diff --git a/.venv/bin/install_cmdstan b/.venv/bin/install_cmdstan new file mode 100755 index 00000000..bb8bdd0f --- /dev/null +++ b/.venv/bin/install_cmdstan @@ -0,0 +1,8 @@ +#!/home/ilgazc/PycharmProjects/TimeSeriesAnalysis/.venv/bin/python3.12 +# -*- coding: utf-8 -*- +import re +import sys +from cmdstanpy.install_cmdstan import __main__ +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(__main__()) diff --git a/.venv/bin/install_cxx_toolchain b/.venv/bin/install_cxx_toolchain new file mode 100755 index 00000000..7af0181c --- /dev/null +++ b/.venv/bin/install_cxx_toolchain @@ -0,0 +1,8 @@ +#!/home/ilgazc/PycharmProjects/TimeSeriesAnalysis/.venv/bin/python3.12 +# -*- coding: utf-8 -*- +import re +import sys +from cmdstanpy.install_cxx_toolchain import __main__ +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(__main__()) diff --git a/.venv/bin/tqdm b/.venv/bin/tqdm new file mode 100755 index 00000000..4bc322f1 --- /dev/null +++ b/.venv/bin/tqdm @@ -0,0 +1,8 @@ +#!/home/ilgazc/PycharmProjects/TimeSeriesAnalysis/.venv/bin/python3.12 +# -*- coding: utf-8 -*- +import re +import sys +from tqdm.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/LICENSE.md b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/LICENSE.md new file mode 100644 index 00000000..04a3a9df --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/LICENSE.md @@ -0,0 +1,15 @@ +BSD 3-Clause License + +Copyright (c) 2019, Stan Developers and their Assignees +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/METADATA b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/METADATA new file mode 100644 index 00000000..16131638 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/METADATA @@ -0,0 +1,102 @@ +Metadata-Version: 2.1 +Name: cmdstanpy +Version: 1.2.5 +Summary: Python interface to CmdStan +Author: Stan Dev Team +License: BSD-3-Clause +Project-URL: Homepage, https://github.com/stan-dev/cmdstanpy +Project-URL: Bug Tracker, https://github.com/stan-dev/cmdstanpy/issues +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Science/Research +Classifier: Natural Language :: English +Classifier: Programming Language :: Python +Classifier: Topic :: Scientific/Engineering :: Information Analysis +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +License-File: LICENSE.md +Requires-Dist: pandas +Requires-Dist: numpy>=1.21 +Requires-Dist: tqdm +Requires-Dist: stanio<2.0.0,>=0.4.0 +Provides-Extra: all +Requires-Dist: xarray; extra == "all" +Provides-Extra: test +Requires-Dist: flake8; extra == "test" +Requires-Dist: pylint; extra == "test" +Requires-Dist: pytest; extra == "test" +Requires-Dist: pytest-cov; extra == "test" +Requires-Dist: pytest-order; extra == "test" +Requires-Dist: mypy; extra == "test" +Requires-Dist: xarray; extra == "test" +Provides-Extra: docs +Requires-Dist: sphinx<6,>5; extra == "docs" +Requires-Dist: pydata-sphinx-theme<0.9; extra == "docs" +Requires-Dist: nbsphinx; extra == "docs" +Requires-Dist: ipython; extra == "docs" +Requires-Dist: ipykernel; extra == "docs" +Requires-Dist: ipywidgets; extra == "docs" +Requires-Dist: sphinx-copybutton; extra == "docs" +Requires-Dist: xarray; extra == "docs" +Requires-Dist: matplotlib; extra == "docs" + +# CmdStanPy + +[![codecov](https://codecov.io/gh/stan-dev/cmdstanpy/branch/master/graph/badge.svg)](https://codecov.io/gh/stan-dev/cmdstanpy) + + +CmdStanPy is a lightweight pure-Python interface to CmdStan which provides access to the Stan compiler and all inference algorithms. It supports both development and production workflows. Because model development and testing may require many iterations, the defaults favor development mode and therefore output files are stored on a temporary filesystem. Non-default options allow all aspects of a run to be specified so that scripts can be used to distributed analysis jobs across nodes and machines. + +CmdStanPy is distributed via PyPi: https://pypi.org/project/cmdstanpy/ + +or Conda Forge: https://anaconda.org/conda-forge/cmdstanpy + +### Goals + +- Clean interface to Stan services so that CmdStanPy can keep up with Stan releases. + +- Provide access to all CmdStan inference methods. + +- Easy to install, + + minimal Python library dependencies: numpy, pandas + + Python code doesn't interface directly with c++, only calls compiled executables + +- Modular - CmdStanPy produces a MCMC sample (or point estimate) from the posterior; other packages do analysis and visualization. + +- Low memory overhead - by default, minimal memory used above that required by CmdStanPy; objects run CmdStan programs and track CmdStan input and output files. + + +### Source Repository + +CmdStanPy and CmdStan are available from GitHub: https://github.com/stan-dev/cmdstanpy and https://github.com/stan-dev/cmdstan + + +### Docs + +The latest release documentation is hosted on https://mc-stan.org/cmdstanpy, older release versions are available from readthedocs: https://cmdstanpy.readthedocs.io + +### Licensing + +The CmdStanPy, CmdStan, and the core Stan C++ code are licensed under new BSD. + +### Example + +```python +import os +from cmdstanpy import cmdstan_path, CmdStanModel + +# specify locations of Stan program file and data +stan_file = os.path.join(cmdstan_path(), 'examples', 'bernoulli', 'bernoulli.stan') +data_file = os.path.join(cmdstan_path(), 'examples', 'bernoulli', 'bernoulli.data.json') + +# instantiate a model; compiles the Stan program by default +model = CmdStanModel(stan_file=stan_file) + +# obtain a posterior sample from the model conditioned on the data +fit = model.sample(chains=4, data=data_file) + +# summarize the results (wraps CmdStan `bin/stansummary`): +fit.summary() +``` diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/RECORD b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/RECORD new file mode 100644 index 00000000..83170cf6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/RECORD @@ -0,0 +1,60 @@ +../../../bin/install_cmdstan,sha256=wXQ7YJaxaA94uHRfLPrP1r4l4y3WbOu-Oq8hesC6GRs,284 +../../../bin/install_cxx_toolchain,sha256=OQqGRHSWnIewU1OYztVUdB9b1p71QR_jvOPdIDCi_uA,290 +cmdstanpy-1.2.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +cmdstanpy-1.2.5.dist-info/LICENSE.md,sha256=idyB5B6vvYuD6l6IVtMLDi0q-IUMmhKkS5MnM8XgTvI,1526 +cmdstanpy-1.2.5.dist-info/METADATA,sha256=0ScvA_iMXhi1MwJj_3dH1Dcm2w8unLHbv8K1Y7RtfV4,4050 +cmdstanpy-1.2.5.dist-info/RECORD,, +cmdstanpy-1.2.5.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91 +cmdstanpy-1.2.5.dist-info/entry_points.txt,sha256=jMCL_dUqeodJmm8BtARyRkIvkL2m8AvIwpoduddo01Y,136 +cmdstanpy-1.2.5.dist-info/top_level.txt,sha256=DymymE6zsANoee61D6GcZ9I2c9H2zrrgv12IP1Ob_nA,10 +cmdstanpy/__init__.py,sha256=VA2CIWvIFkE9FXFUi0DXnAlIDpzuDXGn66lMOX13tv4,1290 +cmdstanpy/__pycache__/__init__.cpython-312.pyc,, +cmdstanpy/__pycache__/_version.cpython-312.pyc,, +cmdstanpy/__pycache__/cmdstan_args.cpython-312.pyc,, +cmdstanpy/__pycache__/compilation.cpython-312.pyc,, +cmdstanpy/__pycache__/install_cmdstan.cpython-312.pyc,, +cmdstanpy/__pycache__/install_cxx_toolchain.cpython-312.pyc,, +cmdstanpy/__pycache__/model.cpython-312.pyc,, +cmdstanpy/__pycache__/progress.cpython-312.pyc,, +cmdstanpy/_version.py,sha256=zN4cqI6KhD4VXPuuWSYE-PKGpLSwPmM8qkOM-67JsyQ,42 +cmdstanpy/cmdstan_args.py,sha256=rKpQrym_ltoa3Qa0mUJMR6jI1v4_mhjmtTd-jlX24ig,39752 +cmdstanpy/compilation.py,sha256=rBTbFiTxautFRx_cWWdZN30h8W4iKsaVreBhBp3QYC4,20806 +cmdstanpy/install_cmdstan.py,sha256=61mVVIC7Bggl1oC7EZvi914uc9tJmqfSTPYWUSE0X54,23553 +cmdstanpy/install_cxx_toolchain.py,sha256=xNyxwUeYyM5vJjnxporefK77SsQUvvM78JeZnFQtKdI,11704 +cmdstanpy/model.py,sha256=5HtQvSnmkVYOJVH7aekF9NKZQmUz8VzthqoxJYGkCyY,89664 +cmdstanpy/progress.py,sha256=k5OQgEpUgh8p7VfMNX23uQcaoKuHA_mJ2XGOAKjUJyY,1317 +cmdstanpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +cmdstanpy/stanfit/__init__.py,sha256=WxvdlTPU1XvxGOIqIF5OKR71O538TDGcBFBE_NLrgAg,10356 +cmdstanpy/stanfit/__pycache__/__init__.cpython-312.pyc,, +cmdstanpy/stanfit/__pycache__/gq.cpython-312.pyc,, +cmdstanpy/stanfit/__pycache__/laplace.cpython-312.pyc,, +cmdstanpy/stanfit/__pycache__/mcmc.cpython-312.pyc,, +cmdstanpy/stanfit/__pycache__/metadata.cpython-312.pyc,, +cmdstanpy/stanfit/__pycache__/mle.cpython-312.pyc,, +cmdstanpy/stanfit/__pycache__/pathfinder.cpython-312.pyc,, +cmdstanpy/stanfit/__pycache__/runset.cpython-312.pyc,, +cmdstanpy/stanfit/__pycache__/vb.cpython-312.pyc,, +cmdstanpy/stanfit/gq.py,sha256=ppUEuOqA7bUnxuahKSqvJ80NB52dBoYVdetqIRpeloM,26049 +cmdstanpy/stanfit/laplace.py,sha256=8St71_dKSQTFw7LKCUGxviGufiMAzlb4IZ2jZ1lcQBI,9618 +cmdstanpy/stanfit/mcmc.py,sha256=l2sc4gjLm7cvCZNNgN4EPzMEVbbYc7Gu6vyJ1FtyMqg,31735 +cmdstanpy/stanfit/metadata.py,sha256=kcQ5-shQ_F3RYAbguc5V_SzWP8KWi2pWrObxFLWpPjg,1596 +cmdstanpy/stanfit/mle.py,sha256=aAk7M1cDhRI-6GRbdqqAcsVVReFhKxReUWSEllTADuM,10458 +cmdstanpy/stanfit/pathfinder.py,sha256=Iz-JjZyDkJ8IGbZDr0_Tnjh0iEGlClNiB89sqFRVXn8,8322 +cmdstanpy/stanfit/runset.py,sha256=0nD_Aq5Jyl6cID-MNWHS-ZFJ786osJR9NmJBqs7JcS0,10851 +cmdstanpy/stanfit/vb.py,sha256=kJvjsUqy9O7pKWQoVaS0R4bh7DpBKk-aD1iq_QpSktA,8502 +cmdstanpy/utils/__init__.py,sha256=irzAF4bKE-NNWoAJKKH0VNKPnFjUBsWkylfdzX6YYpo,3740 +cmdstanpy/utils/__pycache__/__init__.cpython-312.pyc,, +cmdstanpy/utils/__pycache__/cmdstan.cpython-312.pyc,, +cmdstanpy/utils/__pycache__/command.cpython-312.pyc,, +cmdstanpy/utils/__pycache__/data_munging.cpython-312.pyc,, +cmdstanpy/utils/__pycache__/filesystem.cpython-312.pyc,, +cmdstanpy/utils/__pycache__/json.cpython-312.pyc,, +cmdstanpy/utils/__pycache__/logging.cpython-312.pyc,, +cmdstanpy/utils/__pycache__/stancsv.cpython-312.pyc,, +cmdstanpy/utils/cmdstan.py,sha256=uRHFVB955k_nFbR02DUpX-q9xVZzYqnKjjmMJD6L9xk,19196 +cmdstanpy/utils/command.py,sha256=1nPeOI8Gn6r-WAb3TAe1mqweK-1K0aJRmMulYwdWxNk,3229 +cmdstanpy/utils/data_munging.py,sha256=Gw764AKLIzWu9LvO-N7CgUjcIzUOnVANX6khkb-m1Gk,1245 +cmdstanpy/utils/filesystem.py,sha256=t4HHG0IESmUVraF_WlSQs8JRzkGBKJUsj2gSCdt4UHQ,7099 +cmdstanpy/utils/json.py,sha256=rFQwxTr4OCTUMhBAuCNLQY4rRrwY5m1c9ufw0081_XM,132 +cmdstanpy/utils/logging.py,sha256=PipH_4YiZdoe5C9bTf5GEPhoI7zPHRx4VPe4AUCbHvw,699 +cmdstanpy/utils/stancsv.py,sha256=oB1V4dvDgCywoADew39wrbTrSZVXZXvoq3xFUvsiOZ4,16455 diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/WHEEL new file mode 100644 index 00000000..ae527e7d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (75.6.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/entry_points.txt b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/entry_points.txt new file mode 100644 index 00000000..5fda0886 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +install_cmdstan = cmdstanpy.install_cmdstan:__main__ +install_cxx_toolchain = cmdstanpy.install_cxx_toolchain:__main__ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/top_level.txt b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/top_level.txt new file mode 100644 index 00000000..242dea1f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy-1.2.5.dist-info/top_level.txt @@ -0,0 +1 @@ +cmdstanpy diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__init__.py b/.venv/lib/python3.12/site-packages/cmdstanpy/__init__.py new file mode 100644 index 00000000..4e3c134e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/__init__.py @@ -0,0 +1,66 @@ +# pylint: disable=wrong-import-position +"""CmdStanPy Module""" + +import atexit +import shutil +import tempfile + +_TMPDIR = tempfile.mkdtemp() +_CMDSTAN_WARMUP = 1000 +_CMDSTAN_SAMPLING = 1000 +_CMDSTAN_THIN = 1 +_CMDSTAN_REFRESH = 100 +_DOT_CMDSTAN = '.cmdstan' + + +def _cleanup_tmpdir() -> None: + """Force deletion of _TMPDIR.""" + shutil.rmtree(_TMPDIR, ignore_errors=True) + + +atexit.register(_cleanup_tmpdir) + + +from ._version import __version__ # noqa +from .compilation import compile_stan_file, format_stan_file +from .install_cmdstan import rebuild_cmdstan +from .model import CmdStanModel +from .stanfit import ( + CmdStanGQ, + CmdStanLaplace, + CmdStanMCMC, + CmdStanMLE, + CmdStanPathfinder, + CmdStanVB, + from_csv, +) +from .utils import ( + cmdstan_path, + cmdstan_version, + install_cmdstan, + set_cmdstan_path, + set_make_env, + show_versions, + write_stan_json, +) + +__all__ = [ + 'set_cmdstan_path', + 'cmdstan_path', + 'set_make_env', + 'install_cmdstan', + 'compile_stan_file', + 'format_stan_file', + 'CmdStanMCMC', + 'CmdStanMLE', + 'CmdStanGQ', + 'CmdStanVB', + 'CmdStanLaplace', + 'CmdStanPathfinder', + 'CmdStanModel', + 'from_csv', + 'write_stan_json', + 'show_versions', + 'rebuild_cmdstan', + 'cmdstan_version', +] diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..9fd8f4db Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/_version.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/_version.cpython-312.pyc new file mode 100644 index 00000000..75f28d2a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/_version.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/cmdstan_args.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/cmdstan_args.cpython-312.pyc new file mode 100644 index 00000000..6a7ca8a4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/cmdstan_args.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/compilation.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/compilation.cpython-312.pyc new file mode 100644 index 00000000..42fa4f8c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/compilation.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/install_cmdstan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/install_cmdstan.cpython-312.pyc new file mode 100644 index 00000000..8ddfcc43 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/install_cmdstan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/install_cxx_toolchain.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/install_cxx_toolchain.cpython-312.pyc new file mode 100644 index 00000000..193140dd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/install_cxx_toolchain.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/model.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/model.cpython-312.pyc new file mode 100644 index 00000000..7d8eeddc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/model.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/progress.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/progress.cpython-312.pyc new file mode 100644 index 00000000..572f1dc4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/__pycache__/progress.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/_version.py b/.venv/lib/python3.12/site-packages/cmdstanpy/_version.py new file mode 100644 index 00000000..11ebb7e0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/_version.py @@ -0,0 +1,3 @@ +"""PyPi Version""" + +__version__ = '1.2.5' diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/cmdstan_args.py b/.venv/lib/python3.12/site-packages/cmdstanpy/cmdstan_args.py new file mode 100644 index 00000000..07040d6d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/cmdstan_args.py @@ -0,0 +1,1005 @@ +""" +CmdStan arguments +""" +import os +from enum import Enum, auto +from time import time +from typing import Any, Dict, List, Mapping, Optional, Union + +import numpy as np +from numpy.random import default_rng + +from cmdstanpy import _TMPDIR +from cmdstanpy.utils import ( + cmdstan_path, + cmdstan_version_before, + create_named_text_file, + get_logger, + read_metric, + write_stan_json, +) + +OptionalPath = Union[str, os.PathLike, None] + + +class Method(Enum): + """Supported CmdStan method names.""" + + SAMPLE = auto() + OPTIMIZE = auto() + GENERATE_QUANTITIES = auto() + VARIATIONAL = auto() + LAPLACE = auto() + PATHFINDER = auto() + + def __repr__(self) -> str: + return '<%s.%s>' % (self.__class__.__name__, self.name) + + +def positive_int(value: Any, name: str) -> None: + if value is not None: + if isinstance(value, (int, np.integer)): + if value <= 0: + raise ValueError(f'{name} must be greater than 0') + else: + raise ValueError(f'{name} must be of type int') + + +def positive_float(value: Any, name: str) -> None: + if value is not None: + if isinstance(value, (int, float, np.floating)): + if value <= 0: + raise ValueError(f'{name} must be greater than 0') + else: + raise ValueError(f'{name} must be of type float') + + +class SamplerArgs: + """Arguments for the NUTS adaptive sampler.""" + + def __init__( + self, + iter_warmup: Optional[int] = None, + iter_sampling: Optional[int] = None, + save_warmup: bool = False, + thin: Optional[int] = None, + max_treedepth: Optional[int] = None, + metric: Union[ + str, Dict[str, Any], List[str], List[Dict[str, Any]], None + ] = None, + step_size: Union[float, List[float], None] = None, + adapt_engaged: bool = True, + adapt_delta: Optional[float] = None, + adapt_init_phase: Optional[int] = None, + adapt_metric_window: Optional[int] = None, + adapt_step_size: Optional[int] = None, + fixed_param: bool = False, + num_chains: int = 1, + ) -> None: + """Initialize object.""" + self.iter_warmup = iter_warmup + self.iter_sampling = iter_sampling + self.save_warmup = save_warmup + self.thin = thin + self.max_treedepth = max_treedepth + self.metric = metric + self.metric_type: Optional[str] = None + self.metric_file: Union[str, List[str], None] = None + self.step_size = step_size + self.adapt_engaged = adapt_engaged + self.adapt_delta = adapt_delta + self.adapt_init_phase = adapt_init_phase + self.adapt_metric_window = adapt_metric_window + self.adapt_step_size = adapt_step_size + self.fixed_param = fixed_param + self.diagnostic_file = None + self.num_chains = num_chains + + def validate(self, chains: Optional[int]) -> None: + """ + Check arguments correctness and consistency. + + * adaptation and warmup args are consistent + * if file(s) for metric are supplied, check contents. + * length of per-chain lists equals specified # of chains + """ + if not isinstance(chains, (int, np.integer)) or chains < 1: + raise ValueError( + 'Sampler expects number of chains to be greater than 0.' + ) + if not ( + self.adapt_delta is None + and self.adapt_init_phase is None + and self.adapt_metric_window is None + and self.adapt_step_size is None + ): + if self.adapt_engaged is False: + msg = 'Conflicting arguments: adapt_engaged: False' + if self.adapt_delta is not None: + msg = '{}, adapt_delta: {}'.format(msg, self.adapt_delta) + if self.adapt_init_phase is not None: + msg = '{}, adapt_init_phase: {}'.format( + msg, self.adapt_init_phase + ) + if self.adapt_metric_window is not None: + msg = '{}, adapt_metric_window: {}'.format( + msg, self.adapt_metric_window + ) + if self.adapt_step_size is not None: + msg = '{}, adapt_step_size: {}'.format( + msg, self.adapt_step_size + ) + raise ValueError(msg) + + if self.iter_warmup is not None: + if self.iter_warmup < 0 or not isinstance( + self.iter_warmup, (int, np.integer) + ): + raise ValueError( + 'Value for iter_warmup must be a non-negative integer,' + ' found {}.'.format(self.iter_warmup) + ) + if self.iter_warmup == 0 and self.adapt_engaged: + raise ValueError( + 'Must specify iter_warmup > 0 when adapt_engaged=True.' + ) + if self.iter_sampling is not None: + if self.iter_sampling < 0 or not isinstance( + self.iter_sampling, (int, np.integer) + ): + raise ValueError( + 'Argument "iter_sampling" must be a non-negative integer,' + ' found {}.'.format(self.iter_sampling) + ) + + positive_int(self.thin, 'thin') + positive_int(self.max_treedepth, 'max_treedepth') + + if self.step_size is not None: + if isinstance( + self.step_size, (float, int, np.integer, np.floating) + ): + if self.step_size <= 0: + raise ValueError( + 'Argument "step_size" must be > 0, ' + 'found {}.'.format(self.step_size) + ) + else: + if len(self.step_size) != chains: + raise ValueError( + 'Expecting {} per-chain step_size specifications, ' + ' found {}.'.format(chains, len(self.step_size)) + ) + for i, step_size in enumerate(self.step_size): + if step_size < 0: + raise ValueError( + 'Argument "step_size" must be > 0, ' + 'chain {}, found {}.'.format(i + 1, step_size) + ) + if self.metric is not None: + if isinstance(self.metric, str): + if self.metric in ['diag', 'diag_e']: + self.metric_type = 'diag_e' + elif self.metric in ['dense', 'dense_e']: + self.metric_type = 'dense_e' + elif self.metric in ['unit', 'unit_e']: + self.metric_type = 'unit_e' + else: + if not os.path.exists(self.metric): + raise ValueError('no such file {}'.format(self.metric)) + dims = read_metric(self.metric) + if len(dims) == 1: + self.metric_type = 'diag_e' + else: + self.metric_type = 'dense_e' + self.metric_file = self.metric + elif isinstance(self.metric, dict): + if 'inv_metric' not in self.metric: + raise ValueError( + 'Entry "inv_metric" not found in metric dict.' + ) + dims = list(np.asarray(self.metric['inv_metric']).shape) + if len(dims) == 1: + self.metric_type = 'diag_e' + else: + self.metric_type = 'dense_e' + dict_file = create_named_text_file( + dir=_TMPDIR, prefix="metric", suffix=".json" + ) + write_stan_json(dict_file, self.metric) + self.metric_file = dict_file + elif isinstance(self.metric, (list, tuple)): + if len(self.metric) != chains: + raise ValueError( + 'Number of metric files must match number of chains,' + ' found {} metric files for {} chains.'.format( + len(self.metric), chains + ) + ) + if all(isinstance(elem, dict) for elem in self.metric): + metric_files: List[str] = [] + for i, metric in enumerate(self.metric): + metric_dict: Dict[str, Any] = metric # type: ignore + if 'inv_metric' not in metric_dict: + raise ValueError( + 'Entry "inv_metric" not found in metric dict ' + 'for chain {}.'.format(i + 1) + ) + if i == 0: + dims = list( + np.asarray(metric_dict['inv_metric']).shape + ) + else: + dims2 = list( + np.asarray(metric_dict['inv_metric']).shape + ) + if dims != dims2: + raise ValueError( + 'Found inconsistent "inv_metric" entry ' + 'for chain {}: entry has dims ' + '{}, expected {}.'.format( + i + 1, dims, dims2 + ) + ) + dict_file = create_named_text_file( + dir=_TMPDIR, prefix="metric", suffix=".json" + ) + write_stan_json(dict_file, metric_dict) + metric_files.append(dict_file) + if len(dims) == 1: + self.metric_type = 'diag_e' + else: + self.metric_type = 'dense_e' + self.metric_file = metric_files + elif all(isinstance(elem, str) for elem in self.metric): + metric_files = [] + for i, metric in enumerate(self.metric): + assert isinstance(metric, str) # typecheck + if not os.path.exists(metric): + raise ValueError('no such file {}'.format(metric)) + if i == 0: + dims = read_metric(metric) + else: + dims2 = read_metric(metric) + if len(dims) != len(dims2): + raise ValueError( + 'Metrics files {}, {},' + ' inconsistent metrics'.format( + self.metric[0], metric + ) + ) + if dims != dims2: + raise ValueError( + 'Metrics files {}, {},' + ' inconsistent metrics'.format( + self.metric[0], metric + ) + ) + metric_files.append(metric) + if len(dims) == 1: + self.metric_type = 'diag_e' + else: + self.metric_type = 'dense_e' + self.metric_file = metric_files + else: + raise ValueError( + 'Argument "metric" must be a list of pathnames or ' + 'Python dicts, found list of {}.'.format( + type(self.metric[0]) + ) + ) + else: + raise ValueError( + 'Invalid metric specified, not a recognized metric type, ' + 'must be either a metric type name, a filepath, dict, ' + 'or list of per-chain filepaths or dicts. Found ' + 'an object of type {}.'.format(type(self.metric)) + ) + + if self.adapt_delta is not None: + if not 0 < self.adapt_delta < 1: + raise ValueError( + 'Argument "adapt_delta" must be between 0 and 1,' + ' found {}'.format(self.adapt_delta) + ) + if self.adapt_init_phase is not None: + if self.adapt_init_phase < 0 or not isinstance( + self.adapt_init_phase, (int, np.integer) + ): + raise ValueError( + 'Argument "adapt_init_phase" must be a non-negative ' + 'integer, found {}'.format(self.adapt_init_phase) + ) + if self.adapt_metric_window is not None: + if self.adapt_metric_window < 0 or not isinstance( + self.adapt_metric_window, (int, np.integer) + ): + raise ValueError( + 'Argument "adapt_metric_window" must be a non-negative ' + ' integer, found {}'.format(self.adapt_metric_window) + ) + if self.adapt_step_size is not None: + if self.adapt_step_size < 0 or not isinstance( + self.adapt_step_size, (int, np.integer) + ): + raise ValueError( + 'Argument "adapt_step_size" must be a non-negative integer,' + 'found {}'.format(self.adapt_step_size) + ) + positive_int(self.num_chains, 'num_chains') + + if self.fixed_param and ( + self.max_treedepth is not None + or self.metric is not None + or self.step_size is not None + or not ( + self.adapt_delta is None + and self.adapt_init_phase is None + and self.adapt_metric_window is None + and self.adapt_step_size is None + ) + ): + raise ValueError( + 'When fixed_param=True, cannot specify adaptation parameters.' + ) + + def compose(self, idx: int, cmd: List[str]) -> List[str]: + """ + Compose CmdStan command for method-specific non-default arguments. + """ + cmd.append('method=sample') + if self.iter_sampling is not None: + cmd.append(f'num_samples={self.iter_sampling}') + if self.iter_warmup is not None: + cmd.append(f'num_warmup={self.iter_warmup}') + if self.save_warmup: + cmd.append('save_warmup=1') + if self.thin is not None: + cmd.append(f'thin={self.thin}') + if self.fixed_param: + cmd.append('algorithm=fixed_param') + return cmd + else: + cmd.append('algorithm=hmc') + if self.max_treedepth is not None: + cmd.append('engine=nuts') + cmd.append(f'max_depth={self.max_treedepth}') + if self.step_size is not None: + if not isinstance(self.step_size, list): + cmd.append(f'stepsize={self.step_size}') + else: + cmd.append(f'stepsize={self.step_size[idx]}') + if self.metric is not None: + cmd.append(f'metric={self.metric_type}') + if self.metric_file is not None: + if not isinstance(self.metric_file, list): + cmd.append(f'metric_file={self.metric_file}') + else: + cmd.append(f'metric_file={self.metric_file[idx]}') + cmd.append('adapt') + if self.adapt_engaged: + cmd.append('engaged=1') + else: + cmd.append('engaged=0') + if self.adapt_delta is not None: + cmd.append(f'delta={self.adapt_delta}') + if self.adapt_init_phase is not None: + cmd.append(f'init_buffer={self.adapt_init_phase}') + if self.adapt_metric_window is not None: + cmd.append(f'window={self.adapt_metric_window}') + if self.adapt_step_size is not None: + cmd.append('term_buffer={}'.format(self.adapt_step_size)) + if self.num_chains > 1: + cmd.append('num_chains={}'.format(self.num_chains)) + + return cmd + + +class OptimizeArgs: + """Container for arguments for the optimizer.""" + + OPTIMIZE_ALGOS = {'BFGS', 'bfgs', 'LBFGS', 'lbfgs', 'Newton', 'newton'} + bfgs_only = { + "init_alpha", + "tol_obj", + "tol_rel_obj", + "tol_grad", + "tol_rel_grad", + "tol_param", + "history_size", + } + + def __init__( + self, + algorithm: Optional[str] = None, + init_alpha: Optional[float] = None, + iter: Optional[int] = None, + save_iterations: bool = False, + tol_obj: Optional[float] = None, + tol_rel_obj: Optional[float] = None, + tol_grad: Optional[float] = None, + tol_rel_grad: Optional[float] = None, + tol_param: Optional[float] = None, + history_size: Optional[int] = None, + jacobian: bool = False, + ) -> None: + self.algorithm = algorithm or "" + self.init_alpha = init_alpha + self.iter = iter + self.save_iterations = save_iterations + self.tol_obj = tol_obj + self.tol_rel_obj = tol_rel_obj + self.tol_grad = tol_grad + self.tol_rel_grad = tol_rel_grad + self.tol_param = tol_param + self.history_size = history_size + self.jacobian = jacobian + + def validate(self, _chains: Optional[int] = None) -> None: + """ + Check arguments correctness and consistency. + """ + if self.algorithm and self.algorithm not in self.OPTIMIZE_ALGOS: + raise ValueError( + 'Please specify optimizer algorithms as one of [{}]'.format( + ', '.join(self.OPTIMIZE_ALGOS) + ) + ) + + if self.algorithm.lower() not in {'bfgs', 'lbfgs'}: + for arg in self.bfgs_only: + if getattr(self, arg) is not None: + raise ValueError( + f'{arg} requires that algorithm be set to bfgs or lbfgs' + ) + if self.algorithm.lower() != 'lbfgs': + if self.history_size is not None: + raise ValueError( + 'history_size requires that algorithm be set to lbfgs' + ) + + positive_float(self.init_alpha, 'init_alpha') + positive_int(self.iter, 'iter') + positive_float(self.tol_obj, 'tol_obj') + positive_float(self.tol_rel_obj, 'tol_rel_obj') + positive_float(self.tol_grad, 'tol_grad') + positive_float(self.tol_rel_grad, 'tol_rel_grad') + positive_float(self.tol_param, 'tol_param') + positive_int(self.history_size, 'history_size') + + def compose(self, _idx: int, cmd: List[str]) -> List[str]: + """compose command string for CmdStan for non-default arg values.""" + cmd.append('method=optimize') + if self.algorithm: + cmd.append(f'algorithm={self.algorithm.lower()}') + if self.init_alpha is not None: + cmd.append(f'init_alpha={self.init_alpha}') + if self.tol_obj is not None: + cmd.append(f'tol_obj={self.tol_obj}') + if self.tol_rel_obj is not None: + cmd.append(f'tol_rel_obj={self.tol_rel_obj}') + if self.tol_grad is not None: + cmd.append(f'tol_grad={self.tol_grad}') + if self.tol_rel_grad is not None: + cmd.append(f'tol_rel_grad={self.tol_rel_grad}') + if self.tol_param is not None: + cmd.append(f'tol_param={self.tol_param}') + if self.history_size is not None: + cmd.append(f'history_size={self.history_size}') + if self.iter is not None: + cmd.append(f'iter={self.iter}') + if self.save_iterations: + cmd.append('save_iterations=1') + if self.jacobian: + cmd.append("jacobian=1") + return cmd + + +class LaplaceArgs: + """Arguments needed for laplace method.""" + + def __init__( + self, mode: str, draws: Optional[int] = None, jacobian: bool = True + ) -> None: + self.mode = mode + self.jacobian = jacobian + self.draws = draws + + def validate(self, _chains: Optional[int] = None) -> None: + """Check arguments correctness and consistency.""" + if not os.path.exists(self.mode): + raise ValueError(f'Invalid path for mode file: {self.mode}') + positive_int(self.draws, 'draws') + + def compose(self, _idx: int, cmd: List[str]) -> List[str]: + """compose command string for CmdStan for non-default arg values.""" + cmd.append('method=laplace') + cmd.append(f'mode={self.mode}') + if self.draws: + cmd.append(f'draws={self.draws}') + if not self.jacobian: + cmd.append("jacobian=0") + return cmd + + +class PathfinderArgs: + """Container for arguments for Pathfinder.""" + + def __init__( + self, + init_alpha: Optional[float] = None, + tol_obj: Optional[float] = None, + tol_rel_obj: Optional[float] = None, + tol_grad: Optional[float] = None, + tol_rel_grad: Optional[float] = None, + tol_param: Optional[float] = None, + history_size: Optional[int] = None, + num_psis_draws: Optional[int] = None, + num_paths: Optional[int] = None, + max_lbfgs_iters: Optional[int] = None, + num_draws: Optional[int] = None, + num_elbo_draws: Optional[int] = None, + save_single_paths: bool = False, + psis_resample: bool = True, + calculate_lp: bool = True, + ) -> None: + self.init_alpha = init_alpha + self.tol_obj = tol_obj + self.tol_rel_obj = tol_rel_obj + self.tol_grad = tol_grad + self.tol_rel_grad = tol_rel_grad + self.tol_param = tol_param + self.history_size = history_size + + self.num_psis_draws = num_psis_draws + self.num_paths = num_paths + self.max_lbfgs_iters = max_lbfgs_iters + self.num_draws = num_draws + self.num_elbo_draws = num_elbo_draws + + self.save_single_paths = save_single_paths + self.psis_resample = psis_resample + self.calculate_lp = calculate_lp + + def validate(self, _chains: Optional[int] = None) -> None: + """ + Check arguments correctness and consistency. + """ + positive_float(self.init_alpha, 'init_alpha') + positive_float(self.tol_obj, 'tol_obj') + positive_float(self.tol_rel_obj, 'tol_rel_obj') + positive_float(self.tol_grad, 'tol_grad') + positive_float(self.tol_rel_grad, 'tol_rel_grad') + positive_float(self.tol_param, 'tol_param') + positive_int(self.history_size, 'history_size') + + positive_int(self.num_psis_draws, 'num_psis_draws') + positive_int(self.num_paths, 'num_paths') + positive_int(self.max_lbfgs_iters, 'max_lbfgs_iters') + positive_int(self.num_draws, 'num_draws') + positive_int(self.num_elbo_draws, 'num_elbo_draws') + + def compose(self, _idx: int, cmd: List[str]) -> List[str]: + """compose command string for CmdStan for non-default arg values.""" + cmd.append('method=pathfinder') + + if self.init_alpha is not None: + cmd.append(f'init_alpha={self.init_alpha}') + if self.tol_obj is not None: + cmd.append(f'tol_obj={self.tol_obj}') + if self.tol_rel_obj is not None: + cmd.append(f'tol_rel_obj={self.tol_rel_obj}') + if self.tol_grad is not None: + cmd.append(f'tol_grad={self.tol_grad}') + if self.tol_rel_grad is not None: + cmd.append(f'tol_rel_grad={self.tol_rel_grad}') + if self.tol_param is not None: + cmd.append(f'tol_param={self.tol_param}') + if self.history_size is not None: + cmd.append(f'history_size={self.history_size}') + + if self.num_psis_draws is not None: + cmd.append(f'num_psis_draws={self.num_psis_draws}') + if self.num_paths is not None: + cmd.append(f'num_paths={self.num_paths}') + if self.max_lbfgs_iters is not None: + cmd.append(f'max_lbfgs_iters={self.max_lbfgs_iters}') + if self.num_draws is not None: + cmd.append(f'num_draws={self.num_draws}') + if self.num_elbo_draws is not None: + cmd.append(f'num_elbo_draws={self.num_elbo_draws}') + + if self.save_single_paths: + cmd.append('save_single_paths=1') + + if not self.psis_resample: + cmd.append('psis_resample=0') + + if not self.calculate_lp: + cmd.append('calculate_lp=0') + + return cmd + + +class GenerateQuantitiesArgs: + """Arguments needed for generate_quantities method.""" + + def __init__(self, csv_files: List[str]) -> None: + """Initialize object.""" + self.sample_csv_files = csv_files + + def validate( + self, chains: Optional[int] = None # pylint: disable=unused-argument + ) -> None: + """ + Check arguments correctness and consistency. + + * check that sample csv files exist + """ + for csv in self.sample_csv_files: + if not os.path.exists(csv): + raise ValueError( + 'Invalid path for sample csv file: {}'.format(csv) + ) + + def compose(self, idx: int, cmd: List[str]) -> List[str]: + """ + Compose CmdStan command for method-specific non-default arguments. + """ + cmd.append('method=generate_quantities') + cmd.append(f'fitted_params={self.sample_csv_files[idx]}') + return cmd + + +class VariationalArgs: + """Arguments needed for variational method.""" + + VARIATIONAL_ALGOS = {'meanfield', 'fullrank'} + + def __init__( + self, + algorithm: Optional[str] = None, + iter: Optional[int] = None, + grad_samples: Optional[int] = None, + elbo_samples: Optional[int] = None, + eta: Optional[float] = None, + adapt_iter: Optional[int] = None, + adapt_engaged: bool = True, + tol_rel_obj: Optional[float] = None, + eval_elbo: Optional[int] = None, + output_samples: Optional[int] = None, + ) -> None: + self.algorithm = algorithm + self.iter = iter + self.grad_samples = grad_samples + self.elbo_samples = elbo_samples + self.eta = eta + self.adapt_iter = adapt_iter + self.adapt_engaged = adapt_engaged + self.tol_rel_obj = tol_rel_obj + self.eval_elbo = eval_elbo + self.output_samples = output_samples + + def validate( + self, chains: Optional[int] = None # pylint: disable=unused-argument + ) -> None: + """ + Check arguments correctness and consistency. + """ + if ( + self.algorithm is not None + and self.algorithm not in self.VARIATIONAL_ALGOS + ): + raise ValueError( + 'Please specify variational algorithms as one of [{}]'.format( + ', '.join(self.VARIATIONAL_ALGOS) + ) + ) + positive_int(self.iter, 'iter') + positive_int(self.grad_samples, 'grad_samples') + positive_int(self.elbo_samples, 'elbo_samples') + positive_float(self.eta, 'eta') + positive_int(self.adapt_iter, 'adapt_iter') + positive_float(self.tol_rel_obj, 'tol_rel_obj') + positive_int(self.eval_elbo, 'eval_elbo') + positive_int(self.output_samples, 'output_samples') + + # pylint: disable=unused-argument + def compose(self, idx: int, cmd: List[str]) -> List[str]: + """ + Compose CmdStan command for method-specific non-default arguments. + """ + cmd.append('method=variational') + if self.algorithm is not None: + cmd.append(f'algorithm={self.algorithm}') + if self.iter is not None: + cmd.append(f'iter={self.iter}') + if self.grad_samples is not None: + cmd.append(f'grad_samples={self.grad_samples}') + if self.elbo_samples is not None: + cmd.append(f'elbo_samples={self.elbo_samples}') + if self.eta is not None: + cmd.append(f'eta={self.eta}') + cmd.append('adapt') + if self.adapt_engaged: + cmd.append('engaged=1') + if self.adapt_iter is not None: + cmd.append(f'iter={self.adapt_iter}') + else: + cmd.append('engaged=0') + if self.tol_rel_obj is not None: + cmd.append(f'tol_rel_obj={self.tol_rel_obj}') + if self.eval_elbo is not None: + cmd.append(f'eval_elbo={self.eval_elbo}') + if self.output_samples is not None: + cmd.append(f'output_samples={self.output_samples}') + return cmd + + +class CmdStanArgs: + """ + Container for CmdStan command line arguments. + Consists of arguments common to all methods and + and an object which contains the method-specific arguments. + """ + + def __init__( + self, + model_name: str, + model_exe: OptionalPath, + chain_ids: Optional[List[int]], + method_args: Union[ + SamplerArgs, + OptimizeArgs, + GenerateQuantitiesArgs, + VariationalArgs, + LaplaceArgs, + PathfinderArgs, + ], + data: Union[Mapping[str, Any], str, None] = None, + seed: Union[int, List[int], None] = None, + inits: Union[int, float, str, List[str], None] = None, + output_dir: OptionalPath = None, + sig_figs: Optional[int] = None, + save_latent_dynamics: bool = False, + save_profile: bool = False, + refresh: Optional[int] = None, + ) -> None: + """Initialize object.""" + self.model_name = model_name + self.model_exe = model_exe + self.chain_ids = chain_ids + self.data = data + self.seed = seed + self.inits = inits + self.output_dir = output_dir + self.sig_figs = sig_figs + self.save_latent_dynamics = save_latent_dynamics + self.save_profile = save_profile + self.refresh = refresh + self.method_args = method_args + if isinstance(method_args, SamplerArgs): + self.method = Method.SAMPLE + elif isinstance(method_args, OptimizeArgs): + self.method = Method.OPTIMIZE + elif isinstance(method_args, GenerateQuantitiesArgs): + self.method = Method.GENERATE_QUANTITIES + elif isinstance(method_args, VariationalArgs): + self.method = Method.VARIATIONAL + elif isinstance(method_args, LaplaceArgs): + self.method = Method.LAPLACE + elif isinstance(method_args, PathfinderArgs): + self.method = Method.PATHFINDER + else: + raise ValueError( + 'Unsupported method args type: {}'.format(type(method_args)) + ) + self.method_args.validate(len(chain_ids) if chain_ids else None) + self.validate() + + def validate(self) -> None: + """ + Check arguments correctness and consistency. + + * input files must exist + * output files must be in a writeable directory + * if no seed specified, set random seed. + * length of per-chain lists equals specified # of chains + """ + if self.model_name is None: + raise ValueError('no stan model specified') + if self.model_exe is None: + raise ValueError('model not compiled') + + if self.chain_ids is not None: + for chain_id in self.chain_ids: + if chain_id < 1: + raise ValueError('invalid chain_id {}'.format(chain_id)) + if self.output_dir is not None: + self.output_dir = os.path.realpath( + os.path.expanduser(self.output_dir) + ) + if not os.path.exists(self.output_dir): + try: + os.makedirs(self.output_dir) + get_logger().info( + 'created output directory: %s', self.output_dir + ) + except (RuntimeError, PermissionError) as exc: + raise ValueError( + 'Invalid path for output files, ' + 'no such dir: {}.'.format(self.output_dir) + ) from exc + if not os.path.isdir(self.output_dir): + raise ValueError( + 'Specified output_dir is not a directory: {}.'.format( + self.output_dir + ) + ) + try: + testpath = os.path.join(self.output_dir, str(time())) + with open(testpath, 'w+'): + pass + os.remove(testpath) # cleanup + except Exception as exc: + raise ValueError( + 'Invalid path for output files,' + ' cannot write to dir: {}.'.format(self.output_dir) + ) from exc + if self.refresh is not None: + if ( + not isinstance(self.refresh, (int, np.integer)) + or self.refresh < 1 + ): + raise ValueError( + 'Argument "refresh" must be a positive integer value, ' + 'found {}.'.format(self.refresh) + ) + + if self.sig_figs is not None: + if ( + not isinstance(self.sig_figs, (int, np.integer)) + or self.sig_figs < 1 + or self.sig_figs > 18 + ): + raise ValueError( + 'Argument "sig_figs" must be an integer between 1 and 18,' + ' found {}'.format(self.sig_figs) + ) + # TODO: remove at some future release + if cmdstan_version_before(2, 25): + self.sig_figs = None + get_logger().warning( + 'Argument "sig_figs" invalid for CmdStan versions < 2.25, ' + 'using version %s in directory %s', + os.path.basename(cmdstan_path()), + os.path.dirname(cmdstan_path()), + ) + + if self.seed is None: + rng = default_rng() + self.seed = rng.integers(low=1, high=99999, size=1).item() + else: + if not isinstance(self.seed, (int, list, np.integer)): + raise ValueError( + 'Argument "seed" must be an integer between ' + '0 and 2**32-1, found {}.'.format(self.seed) + ) + if isinstance(self.seed, (int, np.integer)): + if self.seed < 0 or self.seed > 2**32 - 1: + raise ValueError( + 'Argument "seed" must be an integer between ' + '0 and 2**32-1, found {}.'.format(self.seed) + ) + else: + if self.chain_ids is None: + raise ValueError( + 'List of per-chain seeds cannot be evaluated without ' + 'corresponding list of chain_ids.' + ) + if len(self.seed) != len(self.chain_ids): + raise ValueError( + 'Number of seeds must match number of chains,' + ' found {} seed for {} chains.'.format( + len(self.seed), len(self.chain_ids) + ) + ) + for seed in self.seed: + if seed < 0 or seed > 2**32 - 1: + raise ValueError( + 'Argument "seed" must be an integer value' + ' between 0 and 2**32-1,' + ' found {}'.format(seed) + ) + + if isinstance(self.data, str): + if not os.path.exists(self.data): + raise ValueError('no such file {}'.format(self.data)) + elif self.data is not None and not isinstance(self.data, (str, dict)): + raise ValueError('Argument "data" must be string or dict') + + if self.inits is not None: + if isinstance(self.inits, (float, int, np.floating, np.integer)): + if self.inits < 0: + raise ValueError( + 'Argument "inits" must be > 0, found {}'.format( + self.inits + ) + ) + elif isinstance(self.inits, str): + if not ( + isinstance(self.method_args, SamplerArgs) + and self.method_args.num_chains > 1 + or isinstance(self.method_args, PathfinderArgs) + ): + if not os.path.exists(self.inits): + raise ValueError('no such file {}'.format(self.inits)) + elif isinstance(self.inits, list): + if self.chain_ids is None: + raise ValueError( + 'List of inits files cannot be evaluated without ' + 'corresponding list of chain_ids.' + ) + + if len(self.inits) != len(self.chain_ids): + raise ValueError( + 'Number of inits files must match number of chains,' + ' found {} inits files for {} chains.'.format( + len(self.inits), len(self.chain_ids) + ) + ) + for inits in self.inits: + if not os.path.exists(inits): + raise ValueError('no such file {}'.format(inits)) + + def compose_command( + self, + idx: int, + csv_file: str, + *, + diagnostic_file: Optional[str] = None, + profile_file: Optional[str] = None, + ) -> List[str]: + """ + Compose CmdStan command for non-default arguments. + """ + cmd: List[str] = [] + if idx is not None and self.chain_ids is not None: + if idx < 0 or idx > len(self.chain_ids) - 1: + raise ValueError( + 'index ({}) exceeds number of chains ({})'.format( + idx, len(self.chain_ids) + ) + ) + cmd.append(self.model_exe) # type: ignore # guaranteed by validate + cmd.append(f'id={self.chain_ids[idx]}') + else: + cmd.append(self.model_exe) # type: ignore # guaranteed by validate + + if self.seed is not None: + if not isinstance(self.seed, list): + cmd.append('random') + cmd.append(f'seed={self.seed}') + else: + cmd.append('random') + cmd.append(f'seed={self.seed[idx]}') + if self.data is not None: + cmd.append('data') + cmd.append(f'file={self.data}') + if self.inits is not None: + if not isinstance(self.inits, list): + cmd.append(f'init={self.inits}') + else: + cmd.append(f'init={self.inits[idx]}') + cmd.append('output') + cmd.append(f'file={csv_file}') + if diagnostic_file: + cmd.append(f'diagnostic_file={diagnostic_file}') + if profile_file: + cmd.append(f'profile_file={profile_file}') + if self.refresh is not None: + cmd.append(f'refresh={self.refresh}') + if self.sig_figs is not None: + cmd.append(f'sig_figs={self.sig_figs}') + cmd = self.method_args.compose(idx, cmd) + return cmd diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/compilation.py b/.venv/lib/python3.12/site-packages/cmdstanpy/compilation.py new file mode 100644 index 00000000..4c21585a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/compilation.py @@ -0,0 +1,579 @@ +""" +Makefile options for stanc and C++ compilers +""" + +import io +import json +import os +import platform +import shutil +import subprocess +from copy import copy +from datetime import datetime +from pathlib import Path +from typing import Any, Dict, Iterable, List, Optional, Union + +from cmdstanpy.utils import get_logger +from cmdstanpy.utils.cmdstan import ( + EXTENSION, + cmdstan_path, + cmdstan_version, + cmdstan_version_before, +) +from cmdstanpy.utils.command import do_command +from cmdstanpy.utils.filesystem import SanitizedOrTmpFilePath + +STANC_OPTS = [ + 'O', + 'O0', + 'O1', + 'Oexperimental', + 'allow-undefined', + 'use-opencl', + 'warn-uninitialized', + 'include-paths', + 'name', + 'warn-pedantic', +] + +# TODO(2.0): remove +STANC_DEPRECATED_OPTS = { + 'allow_undefined': 'allow-undefined', + 'include_paths': 'include-paths', +} + +STANC_IGNORE_OPTS = [ + 'debug-lex', + 'debug-parse', + 'debug-ast', + 'debug-decorated-ast', + 'debug-generate-data', + 'debug-mir', + 'debug-mir-pretty', + 'debug-optimized-mir', + 'debug-optimized-mir-pretty', + 'debug-transformed-mir', + 'debug-transformed-mir-pretty', + 'dump-stan-math-signatures', + 'auto-format', + 'print-canonical', + 'print-cpp', + 'o', + 'help', + 'version', +] + +OptionalPath = Union[str, os.PathLike, None] + + +# TODO(2.0): can remove add function and other logic +class CompilerOptions: + """ + User-specified flags for stanc and C++ compiler. + + Attributes: + stanc_options - stanc compiler flags, options + cpp_options - makefile options (NAME=value) + user_header - path to a user .hpp file to include during compilation + """ + + def __init__( + self, + *, + stanc_options: Optional[Dict[str, Any]] = None, + cpp_options: Optional[Dict[str, Any]] = None, + user_header: OptionalPath = None, + ) -> None: + """Initialize object.""" + self._stanc_options = stanc_options if stanc_options is not None else {} + self._cpp_options = cpp_options if cpp_options is not None else {} + self._user_header = str(user_header) if user_header is not None else '' + + def __repr__(self) -> str: + return 'stanc_options={}, cpp_options={}'.format( + self._stanc_options, self._cpp_options + ) + + def __eq__(self, other: Any) -> bool: + """Overrides the default implementation""" + if self.is_empty() and other is None: # equiv w/r/t compiler + return True + if not isinstance(other, CompilerOptions): + return False + return ( + self._stanc_options == other.stanc_options + and self._cpp_options == other.cpp_options + and self._user_header == other.user_header + ) + + def is_empty(self) -> bool: + """True if no options specified.""" + return ( + self._stanc_options == {} + and self._cpp_options == {} + and self._user_header == '' + ) + + @property + def stanc_options(self) -> Dict[str, Union[bool, int, str, Iterable[str]]]: + """Stanc compiler options.""" + return self._stanc_options + + @property + def cpp_options(self) -> Dict[str, Union[bool, int]]: + """C++ compiler options.""" + return self._cpp_options + + @property + def user_header(self) -> str: + """user header.""" + return self._user_header + + def validate(self) -> None: + """ + Check compiler args. + Raise ValueError if invalid options are found. + """ + self.validate_stanc_opts() + self.validate_cpp_opts() + self.validate_user_header() + + def validate_stanc_opts(self) -> None: + """ + Check stanc compiler args and consistency between stanc and C++ options. + Raise ValueError if bad config is found. + """ + # pylint: disable=no-member + if self._stanc_options is None: + return + ignore = [] + paths = None + has_o_flag = False + + for deprecated, replacement in STANC_DEPRECATED_OPTS.items(): + if deprecated in self._stanc_options: + if replacement: + get_logger().warning( + 'compiler option "%s" is deprecated, use "%s" instead', + deprecated, + replacement, + ) + self._stanc_options[replacement] = copy( + self._stanc_options[deprecated] + ) + del self._stanc_options[deprecated] + else: + get_logger().warning( + 'compiler option "%s" is deprecated and ' + 'should not be used', + deprecated, + ) + for key, val in self._stanc_options.items(): + if key in STANC_IGNORE_OPTS: + get_logger().info('ignoring compiler option: %s', key) + ignore.append(key) + elif key not in STANC_OPTS: + raise ValueError(f'unknown stanc compiler option: {key}') + elif key == 'include-paths': + paths = val + if isinstance(val, str): + paths = val.split(',') + elif not isinstance(val, list): + raise ValueError( + 'Invalid include-paths, expecting list or ' + f'string, found type: {type(val)}.' + ) + elif key == 'use-opencl': + if self._cpp_options is None: + self._cpp_options = {'STAN_OPENCL': 'TRUE'} + else: + self._cpp_options['STAN_OPENCL'] = 'TRUE' + elif key.startswith('O'): + if has_o_flag: + get_logger().warning( + 'More than one of (O, O1, O2, Oexperimental)' + 'optimizations passed. Only the last one will' + 'be used' + ) + else: + has_o_flag = True + + for opt in ignore: + del self._stanc_options[opt] + if paths is not None: + bad_paths = [dir for dir in paths if not os.path.exists(dir)] + if any(bad_paths): + raise ValueError( + 'invalid include paths: {}'.format(', '.join(bad_paths)) + ) + + self._stanc_options['include-paths'] = [ + os.path.abspath(os.path.expanduser(path)) for path in paths + ] + + def validate_cpp_opts(self) -> None: + """ + Check cpp compiler args. + Raise ValueError if bad config is found. + """ + if self._cpp_options is None: + return + for key in ['OPENCL_DEVICE_ID', 'OPENCL_PLATFORM_ID']: + if key in self._cpp_options: + self._cpp_options['STAN_OPENCL'] = 'TRUE' + val = self._cpp_options[key] + if not isinstance(val, int) or val < 0: + raise ValueError( + f'{key} must be a non-negative integer value,' + f' found {val}.' + ) + + def validate_user_header(self) -> None: + """ + User header exists. + Raise ValueError if bad config is found. + """ + if self._user_header != "": + if not ( + os.path.exists(self._user_header) + and os.path.isfile(self._user_header) + ): + raise ValueError( + f"User header file {self._user_header} cannot be found" + ) + if self._user_header[-4:] != '.hpp': + raise ValueError( + f"Header file must end in .hpp, got {self._user_header}" + ) + if "allow-undefined" not in self._stanc_options: + self._stanc_options["allow-undefined"] = True + # set full path + self._user_header = os.path.abspath(self._user_header) + + if ' ' in self._user_header: + raise ValueError( + "User header must be in a location with no spaces in path!" + ) + + if ( + 'USER_HEADER' in self._cpp_options + and self._user_header != self._cpp_options['USER_HEADER'] + ): + raise ValueError( + "Disagreement in user_header C++ options found!\n" + f"{self._user_header}, {self._cpp_options['USER_HEADER']}" + ) + + self._cpp_options['USER_HEADER'] = self._user_header + + def add(self, new_opts: "CompilerOptions") -> None: # noqa: disable=Q000 + """Adds options to existing set of compiler options.""" + if new_opts.stanc_options is not None: + if self._stanc_options is None: + self._stanc_options = new_opts.stanc_options + else: + for key, val in new_opts.stanc_options.items(): + if key == 'include-paths': + if isinstance(val, Iterable) and not isinstance( + val, str + ): + for path in val: + self.add_include_path(str(path)) + else: + self.add_include_path(str(val)) + else: + self._stanc_options[key] = val + if new_opts.cpp_options is not None: + for key, val in new_opts.cpp_options.items(): + self._cpp_options[key] = val + if new_opts._user_header != '' and self._user_header == '': + self._user_header = new_opts._user_header + + def add_include_path(self, path: str) -> None: + """Adds include path to existing set of compiler options.""" + path = os.path.abspath(os.path.expanduser(path)) + if 'include-paths' not in self._stanc_options: + self._stanc_options['include-paths'] = [path] + elif path not in self._stanc_options['include-paths']: + self._stanc_options['include-paths'].append(path) + + def compose_stanc(self, filename_in_msg: Optional[str]) -> List[str]: + opts = [] + + if filename_in_msg is not None: + opts.append(f'--filename-in-msg={filename_in_msg}') + + if self._stanc_options is not None and len(self._stanc_options) > 0: + for key, val in self._stanc_options.items(): + if key == 'include-paths': + opts.append( + '--include-paths=' + + ','.join( + ( + Path(p).as_posix() + for p in self._stanc_options['include-paths'] + ) + ) + ) + elif key == 'name': + opts.append(f'--name={val}') + else: + opts.append(f'--{key}') + return opts + + def compose(self, filename_in_msg: Optional[str] = None) -> List[str]: + """ + Format makefile options as list of strings. + + Parameters + ---------- + filename_in_msg : str, optional + filename to be displayed in stanc3 error messages + (if different from actual filename on disk), by default None + """ + opts = [ + 'STANCFLAGS+=' + flag.replace(" ", "\\ ") + for flag in self.compose_stanc(filename_in_msg) + ] + if self._cpp_options is not None and len(self._cpp_options) > 0: + for key, val in self._cpp_options.items(): + opts.append(f'{key}={val}') + return opts + + +def src_info( + stan_file: str, compiler_options: CompilerOptions +) -> Dict[str, Any]: + """ + Get source info for Stan program file. + + This function is used in the implementation of + :meth:`CmdStanModel.src_info`, and should not be called directly. + """ + cmd = ( + [os.path.join(cmdstan_path(), 'bin', 'stanc' + EXTENSION)] + # handle include-paths, allow-undefined etc + + compiler_options.compose_stanc(None) + + ['--info', str(stan_file)] + ) + proc = subprocess.run(cmd, capture_output=True, text=True, check=False) + if proc.returncode: + raise ValueError( + f"Failed to get source info for Stan model " + f"'{stan_file}'. Console:\n{proc.stderr}" + ) + result: Dict[str, Any] = json.loads(proc.stdout) + return result + + +def compile_stan_file( + src: Union[str, Path], + force: bool = False, + stanc_options: Optional[Dict[str, Any]] = None, + cpp_options: Optional[Dict[str, Any]] = None, + user_header: OptionalPath = None, +) -> str: + """ + Compile the given Stan program file. Translates the Stan code to + C++, then calls the C++ compiler. + + By default, this function compares the timestamps on the source and + executable files; if the executable is newer than the source file, it + will not recompile the file, unless argument ``force`` is ``True`` + or unless the compiler options have been changed. + + :param src: Path to Stan program file. + + :param force: When ``True``, always compile, even if the executable file + is newer than the source file. Used for Stan models which have + ``#include`` directives in order to force recompilation when changes + are made to the included files. + + :param stanc_options: Options for stanc compiler. + :param cpp_options: Options for C++ compiler. + :param user_header: A path to a header file to include during C++ + compilation. + """ + + src = Path(src).resolve() + if not src.exists(): + raise ValueError(f'stan file does not exist: {src}') + + compiler_options = CompilerOptions( + stanc_options=stanc_options, + cpp_options=cpp_options, + user_header=user_header, + ) + compiler_options.validate() + + exe_target = src.with_suffix(EXTENSION) + if exe_target.exists(): + exe_time = os.path.getmtime(exe_target) + included_files = [src] + included_files.extend( + src_info(str(src), compiler_options).get('included_files', []) + ) + out_of_date = any( + os.path.getmtime(included_file) > exe_time + for included_file in included_files + ) + if not out_of_date and not force: + get_logger().debug('found newer exe file, not recompiling') + return str(exe_target) + + compilation_failed = False + # if target path has spaces or special characters, use a copy in a + # temporary directory (GNU-Make constraint) + with SanitizedOrTmpFilePath(str(src)) as (stan_file, is_copied): + exe_file = os.path.splitext(stan_file)[0] + EXTENSION + + hpp_file = os.path.splitext(exe_file)[0] + '.hpp' + if os.path.exists(hpp_file): + os.remove(hpp_file) + if os.path.exists(exe_file): + get_logger().debug('Removing %s', exe_file) + os.remove(exe_file) + + get_logger().info( + 'compiling stan file %s to exe file %s', + stan_file, + exe_target, + ) + + make = os.getenv( + 'MAKE', + 'make' if platform.system() != 'Windows' else 'mingw32-make', + ) + cmd = [make] + cmd.extend(compiler_options.compose(filename_in_msg=src.name)) + cmd.append(Path(exe_file).as_posix()) + + sout = io.StringIO() + try: + do_command(cmd=cmd, cwd=cmdstan_path(), fd_out=sout) + except RuntimeError as e: + sout.write(f'\n{str(e)}\n') + compilation_failed = True + finally: + console = sout.getvalue() + + get_logger().debug('Console output:\n%s', console) + if not compilation_failed: + if is_copied: + shutil.copy(exe_file, exe_target) + get_logger().info('compiled model executable: %s', exe_target) + if 'Warning' in console: + lines = console.split('\n') + warnings = [x for x in lines if x.startswith('Warning')] + get_logger().warning( + 'Stan compiler has produced %d warnings:', + len(warnings), + ) + get_logger().warning(console) + if compilation_failed: + if 'PCH' in console or 'precompiled header' in console: + get_logger().warning( + "CmdStan's precompiled header (PCH) files " + "may need to be rebuilt." + "Please run cmdstanpy.rebuild_cmdstan().\n" + "If the issue persists please open a bug report" + ) + raise ValueError( + f"Failed to compile Stan model '{src}'. " f"Console:\n{console}" + ) + return str(exe_target) + + +def format_stan_file( + stan_file: Union[str, os.PathLike], + *, + overwrite_file: bool = False, + canonicalize: Union[bool, str, Iterable[str]] = False, + max_line_length: int = 78, + backup: bool = True, + stanc_options: Optional[Dict[str, Any]] = None, +) -> None: + """ + Run stanc's auto-formatter on the model code. Either saves directly + back to the file or prints for inspection + + :param stan_file: Path to Stan program file. + :param overwrite_file: If True, save the updated code to disk, rather + than printing it. By default False + :param canonicalize: Whether or not the compiler should 'canonicalize' + the Stan model, removing things like deprecated syntax. Default is + False. If True, all canonicalizations are run. If it is a list of + strings, those options are passed to stanc (new in Stan 2.29) + :param max_line_length: Set the wrapping point for the formatter. The + default value is 78, which wraps most lines by the 80th character. + :param backup: If True, create a stanfile.bak backup before + writing to the file. Only disable this if you're sure you have other + copies of the file or are using a version control system like Git. + :param stanc_options: Additional options to pass to the stanc compiler. + """ + stan_file = Path(stan_file).resolve() + + if not stan_file.exists(): + raise ValueError(f'File does not exist: {stan_file}') + + try: + cmd = ( + [os.path.join(cmdstan_path(), 'bin', 'stanc' + EXTENSION)] + # handle include-paths, allow-undefined etc + + CompilerOptions(stanc_options=stanc_options).compose_stanc(None) + + [str(stan_file)] + ) + + if canonicalize: + if cmdstan_version_before(2, 29): + if isinstance(canonicalize, bool): + cmd.append('--print-canonical') + else: + raise ValueError( + "Invalid arguments passed for current CmdStan" + + " version({})\n".format( + cmdstan_version() or "Unknown" + ) + + "--canonicalize requires 2.29 or higher" + ) + else: + if isinstance(canonicalize, str): + cmd.append('--canonicalize=' + canonicalize) + elif isinstance(canonicalize, Iterable): + cmd.append('--canonicalize=' + ','.join(canonicalize)) + else: + cmd.append('--print-canonical') + + # before 2.29, having both --print-canonical + # and --auto-format printed twice + if not (cmdstan_version_before(2, 29) and canonicalize): + cmd.append('--auto-format') + + if not cmdstan_version_before(2, 29): + cmd.append(f'--max-line-length={max_line_length}') + elif max_line_length != 78: + raise ValueError( + "Invalid arguments passed for current CmdStan version" + + " ({})\n".format(cmdstan_version() or "Unknown") + + "--max-line-length requires 2.29 or higher" + ) + + out = subprocess.run(cmd, capture_output=True, text=True, check=True) + if out.stderr: + get_logger().warning(out.stderr) + result = out.stdout + if overwrite_file: + if result: + if backup: + shutil.copyfile( + stan_file, + str(stan_file) + + '.bak-' + + datetime.now().strftime("%Y%m%d%H%M%S"), + ) + stan_file.write_text(result) + else: + print(result) + + except (ValueError, RuntimeError) as e: + raise RuntimeError("Stanc formatting failed") from e diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/install_cmdstan.py b/.venv/lib/python3.12/site-packages/cmdstanpy/install_cmdstan.py new file mode 100644 index 00000000..0ee829e4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/install_cmdstan.py @@ -0,0 +1,711 @@ +#!/usr/bin/env python +""" +Download and install a CmdStan release from GitHub. +Downloads the release tar.gz file to temporary storage. +Retries GitHub requests in order to allow for transient network outages. +Builds CmdStan executables and tests the compiler by building +example model ``bernoulli.stan``. + +Optional command line arguments: + -i, --interactive: flag, when specified ignore other arguments and + ask user for settings on STDIN + -v, --version : version, defaults to latest release version + -d, --dir : install directory, defaults to '$HOME/.cmdstan + --overwrite: flag, when specified re-installs existing version + --progress: flag, when specified show progress bar for CmdStan download + --verbose: flag, when specified prints output from CmdStan build process + --cores: int, number of cores to use when building, defaults to 1 + -c, --compiler : flag, add C++ compiler to path (Windows only) +""" +import argparse +import json +import os +import platform +import re +import shutil +import sys +import tarfile +import urllib.error +import urllib.request +from collections import OrderedDict +from pathlib import Path +from time import sleep +from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Union + +from tqdm.auto import tqdm + +from cmdstanpy import _DOT_CMDSTAN +from cmdstanpy.utils import ( + cmdstan_path, + do_command, + pushd, + validate_dir, + wrap_url_progress_hook, +) +from cmdstanpy.utils.cmdstan import get_download_url + +from . import progress as progbar + +if sys.version_info >= (3, 8) or TYPE_CHECKING: + # mypy only knows about the new built-in cached_property + from functools import cached_property +else: + # on older Python versions, this is the recommended + # way to get the same effect + from functools import lru_cache + + def cached_property(fun): + return property(lru_cache(maxsize=None)(fun)) + + +try: + # on MacOS and Linux, importing this + # improves the UX of the input() function + import readline + + # dummy statement to use import for flake8/pylint + _ = readline.__doc__ +except ImportError: + pass + + +class CmdStanRetrieveError(RuntimeError): + pass + + +class CmdStanInstallError(RuntimeError): + pass + + +def is_windows() -> bool: + return platform.system() == 'Windows' + + +MAKE = os.getenv('MAKE', 'make' if not is_windows() else 'mingw32-make') +EXTENSION = '.exe' if is_windows() else '' + + +def get_headers() -> Dict[str, str]: + """Create headers dictionary.""" + headers = {} + GITHUB_PAT = os.environ.get("GITHUB_PAT") # pylint:disable=invalid-name + if GITHUB_PAT is not None: + headers["Authorization"] = "token {}".format(GITHUB_PAT) + return headers + + +def latest_version() -> str: + """Report latest CmdStan release version.""" + url = 'https://api.github.com/repos/stan-dev/cmdstan/releases/latest' + request = urllib.request.Request(url, headers=get_headers()) + for i in range(6): + try: + response = urllib.request.urlopen(request).read() + break + except urllib.error.URLError as e: + print('Cannot connect to github.') + print(e) + if i < 5: + print('retry ({}/5)'.format(i + 1)) + sleep(1) + continue + raise CmdStanRetrieveError( + 'Cannot connect to CmdStan github repo.' + ) from e + content = json.loads(response.decode('utf-8')) + tag = content['tag_name'] + match = re.search(r'v?(.+)', tag) + if match is not None: + tag = match.group(1) + return tag # type: ignore + + +def home_cmdstan() -> str: + return os.path.expanduser(os.path.join('~', _DOT_CMDSTAN)) + + +# pylint: disable=too-few-public-methods +class InstallationSettings: + """ + A static installation settings object + """ + + def __init__( + self, + *, + version: Optional[str] = None, + dir: Optional[str] = None, + progress: bool = False, + verbose: bool = False, + overwrite: bool = False, + cores: int = 1, + compiler: bool = False, + **kwargs: Any, + ): + self.version = version if version else latest_version() + self.dir = dir if dir else home_cmdstan() + self.progress = progress + self.verbose = verbose + self.overwrite = overwrite + self.cores = cores + self.compiler = compiler and is_windows() + + _ = kwargs # ignore all other inputs. + # Useful if initialized from a dictionary like **dict + + +def yes_no(answer: str, default: bool) -> bool: + answer = answer.lower() + if answer in ('y', 'yes'): + return True + if answer in ('n', 'no'): + return False + return default + + +class InteractiveSettings: + """ + Installation settings provided on-demand in an interactive format. + + This provides the same set of properties as the ``InstallationSettings`` + object, but rather than them being fixed by the constructor the user is + asked for input whenever they are accessed for the first time. + """ + + @cached_property + def version(self) -> str: + latest = latest_version() + print("Which version would you like to install?") + print(f"Default: {latest}") + answer = input("Type version or hit enter to continue: ") + return answer if answer else latest + + @cached_property + def dir(self) -> str: + directory = home_cmdstan() + print("Where would you like to install CmdStan?") + print(f"Default: {directory}") + answer = input("Type full path or hit enter to continue: ") + return os.path.expanduser(answer) if answer else directory + + @cached_property + def progress(self) -> bool: + print("Show installation progress bars?") + print("Default: y") + answer = input("[y/n]: ") + return yes_no(answer, True) + + @cached_property + def verbose(self) -> bool: + print("Show verbose output of the installation process?") + print("Default: n") + answer = input("[y/n]: ") + return yes_no(answer, False) + + @cached_property + def overwrite(self) -> bool: + print("Overwrite existing CmdStan installation?") + print("Default: n") + answer = input("[y/n]: ") + return yes_no(answer, False) + + @cached_property + def compiler(self) -> bool: + if not is_windows(): + return False + print("Would you like to install the RTools40 C++ toolchain?") + print("A C++ toolchain is required for CmdStan.") + print( + "If you are not sure if you need the toolchain or not, " + "the most likely case is you do need it, and should answer 'y'." + ) + print("Default: n") + answer = input("[y/n]: ") + return yes_no(answer, False) + + @cached_property + def cores(self) -> int: + max_cpus = os.cpu_count() or 1 + print( + "How many CPU cores would you like to use for installing " + "and compiling CmdStan?" + ) + print(f"Default: 1, Max: {max_cpus}") + answer = input("Enter a number or hit enter to continue: ") + try: + return min(max_cpus, max(int(answer), 1)) + except ValueError: + return 1 + + +def clean_all(verbose: bool = False) -> None: + """ + Run `make clean-all` in the current directory (must be a cmdstan library). + + :param verbose: Boolean value; when ``True``, show output from make command. + """ + cmd = [MAKE, 'clean-all'] + try: + if verbose: + do_command(cmd) + else: + do_command(cmd, fd_out=None) + + except RuntimeError as e: + # pylint: disable=raise-missing-from + raise CmdStanInstallError(f'Command "make clean-all" failed\n{str(e)}') + + +def build(verbose: bool = False, progress: bool = True, cores: int = 1) -> None: + """ + Run command ``make build`` in the current directory, which must be + the home directory of a CmdStan version (or GitHub repo). + By default, displays a progress bar which tracks make command outputs. + If argument ``verbose=True``, instead of a progress bar, streams + make command outputs to sys.stdout. When both ``verbose`` and ``progress`` + are ``False``, runs silently. + + :param verbose: Boolean value; when ``True``, show output from make command. + Default is ``False``. + :param progress: Boolean value; when ``True`` display progress progress bar. + Default is ``True``. + :param cores: Integer, number of cores to use in the ``make`` command. + Default is 1 core. + """ + cmd = [MAKE, 'build', f'-j{cores}'] + try: + if verbose: + do_command(cmd) + elif progress and progbar.allow_show_progress(): + progress_hook: Any = _wrap_build_progress_hook() + do_command(cmd, fd_out=None, pbar=progress_hook) + else: + do_command(cmd, fd_out=None) + + except RuntimeError as e: + # pylint: disable=raise-missing-from + raise CmdStanInstallError(f'Command "make build" failed\n{str(e)}') + if not os.path.exists(os.path.join('bin', 'stansummary' + EXTENSION)): + raise CmdStanInstallError( + f'bin/stansummary{EXTENSION} not found' + ', please rebuild or report a bug!' + ) + if not os.path.exists(os.path.join('bin', 'diagnose' + EXTENSION)): + raise CmdStanInstallError( + f'bin/stansummary{EXTENSION} not found' + ', please rebuild or report a bug!' + ) + + if is_windows(): + # Add tbb to the $PATH on Windows + libtbb = os.path.join( + os.getcwd(), 'stan', 'lib', 'stan_math', 'lib', 'tbb' + ) + os.environ['PATH'] = ';'.join( + list( + OrderedDict.fromkeys( + [libtbb] + os.environ.get('PATH', '').split(';') + ) + ) + ) + + +@progbar.wrap_callback +def _wrap_build_progress_hook() -> Optional[Callable[[str], None]]: + """Sets up tqdm callback for CmdStan sampler console msgs.""" + pad = ' ' * 20 + msgs_expected = 150 # hack: 2.27 make build send ~140 msgs to console + pbar: tqdm = tqdm( + total=msgs_expected, + bar_format="{desc} ({elapsed}) | {bar} | {postfix[0][value]}", + postfix=[{"value": f'Building CmdStan {pad}'}], + colour='blue', + desc='', + position=0, + ) + + def build_progress_hook(line: str) -> None: + if line.startswith('--- CmdStan'): + pbar.set_description('Done') + pbar.postfix[0]["value"] = line + pbar.update(msgs_expected - pbar.n) + pbar.close() + else: + if line.startswith('--'): + pbar.postfix[0]["value"] = line + else: + pbar.postfix[0]["value"] = f'{line[:8]} ... {line[-20:]}' + pbar.set_description('Compiling') + pbar.update(1) + + return build_progress_hook + + +def compile_example(verbose: bool = False) -> None: + """ + Compile the example model. + The current directory must be a cmdstan installation, i.e., + contains the makefile, Stanc compiler, and all libraries. + + :param verbose: Boolean value; when ``True``, show output from make command. + """ + path = Path('examples', 'bernoulli', 'bernoulli').with_suffix(EXTENSION) + if path.is_file(): + path.unlink() + + cmd = [MAKE, path.as_posix()] + try: + if verbose: + do_command(cmd) + else: + do_command(cmd, fd_out=None) + except RuntimeError as e: + # pylint: disable=raise-missing-from + raise CmdStanInstallError(f'Command "{" ".join(cmd)}" failed:\n{e}') + + if not path.is_file(): + raise CmdStanInstallError("Failed to generate example binary") + + +def rebuild_cmdstan( + verbose: bool = False, progress: bool = True, cores: int = 1 +) -> None: + """ + Rebuilds the existing CmdStan installation. + This assumes CmdStan has already been installed, + though it need not be installed via CmdStanPy for + this function to work. + + :param verbose: Boolean value; when ``True``, show output from make command. + Default is ``False``. + :param progress: Boolean value; when ``True`` display progress progress bar. + Default is ``True``. + :param cores: Integer, number of cores to use in the ``make`` command. + Default is 1 core. + """ + try: + with pushd(cmdstan_path()): + clean_all(verbose) + build(verbose, progress, cores) + compile_example(verbose) + except ValueError as e: + raise CmdStanInstallError( + "Failed to rebuild CmdStan. Are you sure it is installed?" + ) from e + + +def install_version( + cmdstan_version: str, + overwrite: bool = False, + verbose: bool = False, + progress: bool = True, + cores: int = 1, +) -> None: + """ + Build specified CmdStan version by spawning subprocesses to + run the Make utility on the downloaded CmdStan release src files. + Assumes that current working directory is parent of release dir. + + :param cmdstan_version: CmdStan release, corresponds to release dirname. + :param overwrite: when ``True``, run ``make clean-all`` before building. + :param verbose: Boolean value; when ``True``, show output from make command. + """ + with pushd(cmdstan_version): + print( + 'Building version {}, may take several minutes, ' + 'depending on your system.'.format(cmdstan_version) + ) + if overwrite and os.path.exists('.'): + print( + 'Overwrite requested, remove existing build of version ' + '{}'.format(cmdstan_version) + ) + clean_all(verbose) + print('Rebuilding version {}'.format(cmdstan_version)) + build(verbose, progress=progress, cores=cores) + print('Installed {}'.format(cmdstan_version)) + + +def is_version_available(version: str) -> bool: + if 'git:' in version: + return True # no good way in general to check if a git tag exists + + is_available = True + url = get_download_url(version) + for i in range(6): + try: + urllib.request.urlopen(url) + except urllib.error.HTTPError as err: + print(f'Release {version} is unavailable from URL {url}') + print(f'HTTPError: {err.code}') + is_available = False + break + except urllib.error.URLError as e: + if i < 5: + print( + 'checking version {} availability, retry ({}/5)'.format( + version, i + 1 + ) + ) + sleep(1) + continue + print('Release {} is unavailable from URL {}'.format(version, url)) + print('URLError: {}'.format(e.reason)) + is_available = False + return is_available + + +def retrieve_version(version: str, progress: bool = True) -> None: + """Download specified CmdStan version.""" + if version is None or version == '': + raise ValueError('Argument "version" unspecified.') + + if 'git:' in version: + tag = version.split(':')[1] + tag_folder = version.replace(':', '-').replace('/', '_') + print(f"Cloning CmdStan branch '{tag}' from stan-dev/cmdstan on GitHub") + do_command( + [ + 'git', + 'clone', + '--depth', + '1', + '--branch', + tag, + '--recursive', + '--shallow-submodules', + 'https://github.com/stan-dev/cmdstan.git', + f'cmdstan-{tag_folder}', + ] + ) + return + + print('Downloading CmdStan version {}'.format(version)) + url = get_download_url(version) + for i in range(6): # always retry to allow for transient URLErrors + try: + if progress and progbar.allow_show_progress(): + progress_hook: Optional[ + Callable[[int, int, int], None] + ] = wrap_url_progress_hook() + else: + progress_hook = None + file_tmp, _ = urllib.request.urlretrieve( + url, filename=None, reporthook=progress_hook + ) + break + except urllib.error.HTTPError as e: + raise CmdStanRetrieveError( + 'HTTPError: {}\n' + 'Version {} not available from github.com.'.format( + e.code, version + ) + ) from e + except urllib.error.URLError as e: + print( + 'Failed to download CmdStan version {} from github.com'.format( + version + ) + ) + print(e) + if i < 5: + print('retry ({}/5)'.format(i + 1)) + sleep(1) + continue + print('Version {} not available from github.com.'.format(version)) + raise CmdStanRetrieveError( + 'Version {} not available from github.com.'.format(version) + ) from e + print('Download successful, file: {}'.format(file_tmp)) + try: + print('Extracting distribution') + tar = tarfile.open(file_tmp) + first = tar.next() + if first is not None: + top_dir = first.name + else: + top_dir = '' + cmdstan_dir = f'cmdstan-{version}' + if top_dir != cmdstan_dir: + raise CmdStanInstallError( + 'tarfile should contain top-level dir {},' + 'but found dir {} instead.'.format(cmdstan_dir, top_dir) + ) + target = os.getcwd() + if is_windows(): + # fixes long-path limitation on Windows + target = r'\\?\{}'.format(target) + + if progress and progbar.allow_show_progress(): + for member in tqdm( + iterable=tar.getmembers(), + total=len(tar.getmembers()), + colour='blue', + leave=False, + ): + tar.extract(member=member) + else: + tar.extractall() + except Exception as e: # pylint: disable=broad-except + raise CmdStanInstallError( + f'Failed to unpack file {file_tmp}, error:\n\t{str(e)}' + ) from e + finally: + tar.close() + print(f'Unpacked download as {cmdstan_dir}') + + +def run_compiler_install(dir: str, verbose: bool, progress: bool) -> None: + from .install_cxx_toolchain import is_installed as _is_installed_cxx + from .install_cxx_toolchain import run_rtools_install as _main_cxx + from .utils import cxx_toolchain_path + + compiler_found = False + rtools40_home = os.environ.get('RTOOLS40_HOME') + for cxx_loc in ([rtools40_home] if rtools40_home is not None else []) + [ + home_cmdstan(), + os.path.join(os.path.abspath("/"), "RTools40"), + os.path.join(os.path.abspath("/"), "RTools"), + os.path.join(os.path.abspath("/"), "RTools35"), + os.path.join(os.path.abspath("/"), "RBuildTools"), + ]: + for cxx_version in ['40', '35']: + if _is_installed_cxx(cxx_loc, cxx_version): + compiler_found = True + break + if compiler_found: + break + if not compiler_found: + print('Installing RTools40') + # copy argv and clear sys.argv + _main_cxx( + { + 'dir': dir, + 'progress': progress, + 'version': None, + 'verbose': verbose, + } + ) + cxx_version = '40' + # Add toolchain to $PATH + cxx_toolchain_path(cxx_version, dir) + + +def run_install(args: Union[InteractiveSettings, InstallationSettings]) -> None: + """ + Run a (potentially interactive) installation + """ + validate_dir(args.dir) + print('CmdStan install directory: {}'.format(args.dir)) + + # these accesses just 'warm up' the interactive install + _ = args.progress + _ = args.verbose + + if args.compiler: + run_compiler_install(args.dir, args.verbose, args.progress) + + if 'git:' in args.version: + tag = args.version.replace(':', '-').replace('/', '_') + cmdstan_version = f'cmdstan-{tag}' + else: + cmdstan_version = f'cmdstan-{args.version}' + with pushd(args.dir): + already_installed = os.path.exists(cmdstan_version) and os.path.exists( + os.path.join( + cmdstan_version, + 'examples', + 'bernoulli', + 'bernoulli' + EXTENSION, + ) + ) + if not already_installed or args.overwrite: + if is_version_available(args.version): + print('Installing CmdStan version: {}'.format(args.version)) + else: + raise ValueError( + f'Version {args.version} cannot be downloaded. ' + 'Connection to GitHub failed. ' + 'Check firewall settings or ensure this version exists.' + ) + shutil.rmtree(cmdstan_version, ignore_errors=True) + retrieve_version(args.version, args.progress) + install_version( + cmdstan_version=cmdstan_version, + overwrite=already_installed and args.overwrite, + verbose=args.verbose, + progress=args.progress, + cores=args.cores, + ) + else: + print('CmdStan version {} already installed'.format(args.version)) + + with pushd(cmdstan_version): + print('Test model compilation') + compile_example(args.verbose) + + +def parse_cmdline_args() -> Dict[str, Any]: + parser = argparse.ArgumentParser("install_cmdstan") + parser.add_argument( + '--interactive', + '-i', + action='store_true', + help="Ignore other arguments and run the installation in " + + "interactive mode", + ) + parser.add_argument( + '--version', + '-v', + help="version, defaults to latest release version. " + "If git is installed, you can also specify a git tag or branch, " + "e.g. git:develop", + ) + parser.add_argument( + '--dir', '-d', help="install directory, defaults to '$HOME/.cmdstan" + ) + parser.add_argument( + '--overwrite', + action='store_true', + help="flag, when specified re-installs existing version", + ) + parser.add_argument( + '--verbose', + action='store_true', + help="flag, when specified prints output from CmdStan build process", + ) + parser.add_argument( + '--progress', + action='store_true', + help="flag, when specified show progress bar for CmdStan download", + ) + parser.add_argument( + "--cores", + default=1, + type=int, + help="number of cores to use while building", + ) + if is_windows(): + # use compiler installed with install_cxx_toolchain + # Install a new compiler if compiler not found + # Search order is RTools40, RTools35 + parser.add_argument( + '--compiler', + '-c', + dest='compiler', + action='store_true', + help="flag, add C++ compiler to path (Windows only)", + ) + return vars(parser.parse_args(sys.argv[1:])) + + +def __main__() -> None: + args = parse_cmdline_args() + if args.get('interactive', False): + run_install(InteractiveSettings()) + else: + run_install(InstallationSettings(**args)) + + +if __name__ == '__main__': + __main__() diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/install_cxx_toolchain.py b/.venv/lib/python3.12/site-packages/cmdstanpy/install_cxx_toolchain.py new file mode 100644 index 00000000..19d9ca2a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/install_cxx_toolchain.py @@ -0,0 +1,372 @@ +#!/usr/bin/env python +""" +Download and install a C++ toolchain. +Currently implemented platforms (platform.system) + Windows: RTools 3.5, 4.0 (default) + Darwin (macOS): Not implemented + Linux: Not implemented +Optional command line arguments: + -v, --version : version, defaults to latest + -d, --dir : install directory, defaults to '~/.cmdstan + -s (--silent) : install with /VERYSILENT instead of /SILENT for RTools + -m --no-make : don't install mingw32-make (Windows RTools 4.0 only) + --progress : flag, when specified show progress bar for RTools download +""" +import argparse +import os +import platform +import shutil +import subprocess +import sys +import urllib.request +from collections import OrderedDict +from time import sleep +from typing import Any, Dict, List + +from cmdstanpy import _DOT_CMDSTAN +from cmdstanpy.utils import pushd, validate_dir, wrap_url_progress_hook + +EXTENSION = '.exe' if platform.system() == 'Windows' else '' +IS_64BITS = sys.maxsize > 2**32 + + +def usage() -> None: + """Print usage.""" + print( + """Arguments: + -v (--version) :CmdStan version + -d (--dir) : install directory + -s (--silent) : install with /VERYSILENT instead of /SILENT for RTools + -m (--no-make) : don't install mingw32-make (Windows RTools 4.0 only) + --progress : flag, when specified show progress bar for RTools download + -h (--help) : this message + """ + ) + + +def get_config(dir: str, silent: bool) -> List[str]: + """Assemble config info.""" + config = [] + if platform.system() == 'Windows': + _, dir = os.path.splitdrive(os.path.abspath(dir)) + if dir.startswith('\\'): + dir = dir[1:] + config = [ + '/SP-', + '/VERYSILENT' if silent else '/SILENT', + '/SUPPRESSMSGBOXES', + '/CURRENTUSER', + 'LANG="English"', + '/DIR="{}"'.format(dir), + '/NOICONS', + '/NORESTART', + ] + return config + + +def install_version( + installation_dir: str, + installation_file: str, + version: str, + silent: bool, + verbose: bool = False, +) -> None: + """Install specified toolchain version.""" + with pushd('.'): + print( + 'Installing the C++ toolchain: {}'.format( + os.path.splitext(installation_file)[0] + ) + ) + cmd = [installation_file] + cmd.extend(get_config(installation_dir, silent)) + print(' '.join(cmd)) + proc = subprocess.Popen( + cmd, + cwd=None, + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=os.environ, + ) + while proc.poll() is None: + if proc.stdout: + output = proc.stdout.readline().decode('utf-8').strip() + if output and verbose: + print(output, flush=True) + _, stderr = proc.communicate() + if proc.returncode: + print('Installation failed: returncode={}'.format(proc.returncode)) + if stderr: + print(stderr.decode('utf-8').strip()) + if is_installed(installation_dir, version): + print('Installation files found at the installation location.') + sys.exit(3) + # check installation + if is_installed(installation_dir, version): + os.remove(installation_file) + print('Installed {}'.format(os.path.splitext(installation_file)[0])) + + +def install_mingw32_make(toolchain_loc: str, verbose: bool = False) -> None: + """Install mingw32-make for Windows RTools 4.0.""" + os.environ['PATH'] = ';'.join( + list( + OrderedDict.fromkeys( + [ + os.path.join( + toolchain_loc, + 'mingw_64' if IS_64BITS else 'mingw_32', + 'bin', + ), + os.path.join(toolchain_loc, 'usr', 'bin'), + ] + + os.environ.get('PATH', '').split(';') + ) + ) + ) + cmd = [ + 'pacman', + '-Sy', + 'mingw-w64-x86_64-make' if IS_64BITS else 'mingw-w64-i686-make', + '--noconfirm', + ] + with pushd('.'): + print(' '.join(cmd)) + proc = subprocess.Popen( + cmd, + cwd=None, + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=os.environ, + ) + while proc.poll() is None: + if proc.stdout: + output = proc.stdout.readline().decode('utf-8').strip() + if output and verbose: + print(output, flush=True) + _, stderr = proc.communicate() + if proc.returncode: + print( + 'mingw32-make installation failed: returncode={}'.format( + proc.returncode + ) + ) + if stderr: + print(stderr.decode('utf-8').strip()) + sys.exit(3) + print('Installed mingw32-make.exe') + + +def is_installed(toolchain_loc: str, version: str) -> bool: + """Returns True is toolchain is installed.""" + if platform.system() == 'Windows': + if version in ['35', '3.5']: + if not os.path.exists(os.path.join(toolchain_loc, 'bin')): + return False + return os.path.exists( + os.path.join( + toolchain_loc, + 'mingw_64' if IS_64BITS else 'mingw_32', + 'bin', + 'g++' + EXTENSION, + ) + ) + elif version in ['40', '4.0', '4']: + return os.path.exists( + os.path.join( + toolchain_loc, + 'mingw64' if IS_64BITS else 'mingw32', + 'bin', + 'g++' + EXTENSION, + ) + ) + else: + return False + return False + + +def latest_version() -> str: + """Windows version hardcoded to 4.0.""" + if platform.system() == 'Windows': + return '4.0' + return '' + + +def retrieve_toolchain(filename: str, url: str, progress: bool = True) -> None: + """Download toolchain from URL.""" + print('Downloading C++ toolchain: {}'.format(filename)) + for i in range(6): + try: + if progress: + progress_hook = wrap_url_progress_hook() + else: + progress_hook = None + _ = urllib.request.urlretrieve( + url, filename=filename, reporthook=progress_hook + ) + break + except urllib.error.URLError as err: + print('Failed to download C++ toolchain') + print(err) + if i < 5: + print('retry ({}/5)'.format(i + 1)) + sleep(1) + continue + sys.exit(3) + print('Download successful, file: {}'.format(filename)) + + +def normalize_version(version: str) -> str: + """Return maj.min part of version string.""" + if platform.system() == 'Windows': + if version in ['4', '40']: + version = '4.0' + elif version == '35': + version = '3.5' + return version + + +def get_toolchain_name() -> str: + """Return toolchain name.""" + if platform.system() == 'Windows': + return 'RTools' + return '' + + +# TODO(2.0): drop 3.5 support +def get_url(version: str) -> str: + """Return URL for toolchain.""" + url = '' + if platform.system() == 'Windows': + if version == '4.0': + # pylint: disable=line-too-long + if IS_64BITS: + url = 'https://cran.r-project.org/bin/windows/Rtools/rtools40-x86_64.exe' # noqa: disable=E501 + else: + url = 'https://cran.r-project.org/bin/windows/Rtools/rtools40-i686.exe' # noqa: disable=E501 + elif version == '3.5': + url = 'https://cran.r-project.org/bin/windows/Rtools/Rtools35.exe' + return url + + +def get_toolchain_version(name: str, version: str) -> str: + """Toolchain version.""" + toolchain_folder = '' + if platform.system() == 'Windows': + toolchain_folder = '{}{}'.format(name, version.replace('.', '')) + + return toolchain_folder + + +def run_rtools_install(args: Dict[str, Any]) -> None: + """Main.""" + if platform.system() not in {'Windows'}: + raise NotImplementedError( + 'Download for the C++ toolchain ' + 'on the current platform has not ' + f'been implemented: {platform.system()}' + ) + toolchain = get_toolchain_name() + version = args['version'] + if version is None: + version = latest_version() + version = normalize_version(version) + print("C++ toolchain '{}' version: {}".format(toolchain, version)) + + url = get_url(version) + + if 'verbose' in args: + verbose = args['verbose'] + else: + verbose = False + + install_dir = args['dir'] + if install_dir is None: + install_dir = os.path.expanduser(os.path.join('~', _DOT_CMDSTAN)) + validate_dir(install_dir) + print('Install directory: {}'.format(install_dir)) + + if 'progress' in args: + progress = args['progress'] + else: + progress = False + + if platform.system() == 'Windows': + silent = 'silent' in args + # force silent == False for 4.0 version + if 'silent' not in args and version in ('4.0', '4', '40'): + silent = False + else: + silent = False + + toolchain_folder = get_toolchain_version(toolchain, version) + with pushd(install_dir): + if is_installed(toolchain_folder, version): + print('C++ toolchain {} already installed'.format(toolchain_folder)) + else: + if os.path.exists(toolchain_folder): + shutil.rmtree(toolchain_folder, ignore_errors=False) + retrieve_toolchain( + toolchain_folder + EXTENSION, url, progress=progress + ) + install_version( + toolchain_folder, + toolchain_folder + EXTENSION, + version, + silent, + verbose, + ) + if ( + 'no-make' not in args + and (platform.system() == 'Windows') + and (version in ('4.0', '4', '40')) + ): + if os.path.exists( + os.path.join( + toolchain_folder, 'mingw64', 'bin', 'mingw32-make.exe' + ) + ): + print('mingw32-make.exe already installed') + else: + install_mingw32_make(toolchain_folder, verbose) + + +def parse_cmdline_args() -> Dict[str, Any]: + parser = argparse.ArgumentParser() + parser.add_argument('--version', '-v', help="version, defaults to latest") + parser.add_argument( + '--dir', '-d', help="install directory, defaults to '~/.cmdstan" + ) + parser.add_argument( + '--silent', + '-s', + action='store_true', + help="install with /VERYSILENT instead of /SILENT for RTools", + ) + parser.add_argument( + '--no-make', + '-m', + action='store_false', + help="don't install mingw32-make (Windows RTools 4.0 only)", + ) + parser.add_argument( + '--verbose', + action='store_true', + help="flag, when specified prints output from RTools build process", + ) + parser.add_argument( + '--progress', + action='store_true', + help="flag, when specified show progress bar for CmdStan download", + ) + return vars(parser.parse_args(sys.argv[1:])) + + +def __main__() -> None: + run_rtools_install(parse_cmdline_args()) + + +if __name__ == '__main__': + __main__() diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/model.py b/.venv/lib/python3.12/site-packages/cmdstanpy/model.py new file mode 100644 index 00000000..11519886 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/model.py @@ -0,0 +1,2173 @@ +"""CmdStanModel""" + +import os +import platform +import re +import shutil +import subprocess +import sys +import tempfile +import threading +from collections import OrderedDict +from concurrent.futures import ThreadPoolExecutor +from io import StringIO +from multiprocessing import cpu_count +from typing import ( + Any, + Callable, + Dict, + Iterable, + List, + Literal, + Mapping, + Optional, + TypeVar, + Union, +) + +import pandas as pd +from tqdm.auto import tqdm + +from cmdstanpy import ( + _CMDSTAN_REFRESH, + _CMDSTAN_SAMPLING, + _CMDSTAN_WARMUP, + _TMPDIR, + compilation, +) +from cmdstanpy.cmdstan_args import ( + CmdStanArgs, + GenerateQuantitiesArgs, + LaplaceArgs, + Method, + OptimizeArgs, + PathfinderArgs, + SamplerArgs, + VariationalArgs, +) +from cmdstanpy.stanfit import ( + CmdStanGQ, + CmdStanLaplace, + CmdStanMCMC, + CmdStanMLE, + CmdStanPathfinder, + CmdStanVB, + RunSet, + from_csv, +) +from cmdstanpy.utils import ( + cmdstan_path, + cmdstan_version_before, + do_command, + get_logger, + returncode_msg, +) +from cmdstanpy.utils.filesystem import temp_inits, temp_single_json + +from . import progress as progbar + +OptionalPath = Union[str, os.PathLike, None] +Fit = TypeVar('Fit', CmdStanMCMC, CmdStanMLE, CmdStanVB) + + +class CmdStanModel: + # overview, omitted from doc comment in order to improve Sphinx docs. + # A CmdStanModel object encapsulates the Stan program and provides + # methods for compilation and inference. + """ + The constructor method allows model instantiation given either the + Stan program source file or the compiled executable, or both. + This will compile the model if provided a Stan file and no executable, + + :param model_name: Model name, used for output file names. + Optional, default is the base filename of the Stan program file. + Deprecated: In version 2.0.0, model name cannot be + specified and will always be taken from executable. + + :param stan_file: Path to Stan program file. + + :param exe_file: Path to compiled executable file. Optional, unless + no Stan program file is specified. If both the program file and + the compiled executable file are specified, the base filenames + must match, (but different directory locations are allowed). + + :param force_compile: If ``True``, always compile, even if there + is an existing executable file for this model. + + :param stanc_options: Options for stanc compiler, specified as a Python + dictionary containing Stanc3 compiler option name, value pairs. + Optional. + + :param cpp_options: Options for C++ compiler, specified as a Python + dictionary containing C++ compiler option name, value pairs. + Optional. + + :param user_header: A path to a header file to include during C++ + compilation. + Optional. + + :param compile: Whether or not to compile the model. Default is ``True``. + If set to the string ``"force"``, it will always compile even if + an existing executable is found. + Deprecated: Use ``force_compile`` instead. The ability to instantiate + a CmdStanModel without an executable will be removed in version 2.0.0. + + """ + + def __init__( + self, + model_name: Optional[str] = None, + stan_file: OptionalPath = None, + exe_file: OptionalPath = None, + force_compile: bool = False, + stanc_options: Optional[Dict[str, Any]] = None, + cpp_options: Optional[Dict[str, Any]] = None, + user_header: OptionalPath = None, + *, + compile: Union[bool, Literal['force'], None] = None, + ) -> None: + """ + Initialize object given constructor args. + + :param model_name: Deprecated. Model name, used for output file names. + :param stan_file: Path to Stan program file. + :param exe_file: Path to compiled executable file. + :param force_compile: Whether or not to force recompilation if + executable file already exists. + :param stanc_options: Options for stanc compiler. + :param cpp_options: Options for C++ compiler. + :param user_header: A path to a header file to include during C++ + compilation. + :param compile: Deprecated. Whether or not to compile the model. + """ + self._name = '' + self._stan_file = None + self._exe_file = None + self._compiler_options = compilation.CompilerOptions( + stanc_options=stanc_options, + cpp_options=cpp_options, + user_header=user_header, + ) + self._compiler_options.validate() + + self._fixed_param = False + + if compile is None: + compile = True + else: + get_logger().warning( + "CmdStanModel(compile=...) is deprecated and will be " + "removed in the next major version. The constructor will " + "always ensure a model has a compiled executable.\n" + "If you wish to force recompilation, use force_compile=True " + "instead." + ) + + if force_compile: + compile = 'force' + + if model_name is not None: + get_logger().warning( + "CmdStanModel(model_name=...) is deprecated and will be " + "removed in the next major version." + ) + if not model_name.strip(): + raise ValueError( + 'Invalid value for argument model name, found "{}"'.format( + model_name + ) + ) + self._name = model_name.strip() + + if stan_file is None: + if exe_file is None: + raise ValueError( + 'Missing model file arguments, you must specify ' + 'either Stan source or executable program file or both.' + ) + else: + self._stan_file = os.path.realpath(os.path.expanduser(stan_file)) + if not os.path.exists(self._stan_file): + raise ValueError('no such file {}'.format(self._stan_file)) + _, filename = os.path.split(stan_file) + if len(filename) < 6 or not filename.endswith('.stan'): + raise ValueError( + 'invalid stan filename {}'.format(self._stan_file) + ) + if not self._name: + self._name, _ = os.path.splitext(filename) + + # if program has include directives, record path + with open(self._stan_file, 'r') as fd: + program = fd.read() + if '#include' in program: + path, _ = os.path.split(self._stan_file) + self._compiler_options.add_include_path(path) + + # try to detect models w/out parameters, needed for sampler + if (not cmdstan_version_before(2, 27)) and cmdstan_version_before( + 2, 36 + ): + try: + model_info = self.src_info() + if 'parameters' in model_info: + self._fixed_param |= len(model_info['parameters']) == 0 + except ValueError as e: + if compile: + raise + get_logger().debug(e) + + if exe_file is not None: + self._exe_file = os.path.realpath(os.path.expanduser(exe_file)) + if not os.path.exists(self._exe_file): + raise ValueError('no such file {}'.format(self._exe_file)) + _, exename = os.path.split(self._exe_file) + if not self._name: + self._name, _ = os.path.splitext(exename) + else: + if self._name != os.path.splitext(exename)[0]: + raise ValueError( + 'Name mismatch between Stan file and compiled' + ' executable, expecting basename: {}' + ' found: {}.'.format(self._name, exename) + ) + + if platform.system() == 'Windows': + try: + do_command(['where.exe', 'tbb.dll'], fd_out=None) + except RuntimeError: + # Add tbb to the $PATH on Windows + libtbb = os.environ.get('STAN_TBB') + if libtbb is None: + libtbb = os.path.join( + cmdstan_path(), 'stan', 'lib', 'stan_math', 'lib', 'tbb' + ) + get_logger().debug("Adding TBB (%s) to PATH", libtbb) + os.environ['PATH'] = ';'.join( + list( + OrderedDict.fromkeys( + [libtbb] + os.environ.get('PATH', '').split(';') + ) + ) + ) + else: + get_logger().debug("TBB already found in load path") + + if compile and self._exe_file is None: + self.compile(force=str(compile).lower() == 'force', _internal=True) + + def __repr__(self) -> str: + repr = 'CmdStanModel: name={}'.format(self._name) + repr = '{}\n\t stan_file={}'.format(repr, self._stan_file) + repr = '{}\n\t exe_file={}'.format(repr, self._exe_file) + repr = '{}\n\t compiler_options={}'.format(repr, self._compiler_options) + return repr + + @property + def name(self) -> str: + """ + Model name used in output filename templates. Default is basename + of Stan program or exe file, unless specified in call to constructor + via argument ``model_name``. + """ + return self._name + + @property + def stan_file(self) -> OptionalPath: + """Full path to Stan program file.""" + return self._stan_file + + @property + def exe_file(self) -> OptionalPath: + """Full path to Stan exe file.""" + return self._exe_file + + def exe_info(self) -> Dict[str, str]: + """ + Run model with option 'info'. Parse output statements, which all + have form 'key = value' into a Dict. + If exe file compiled with CmdStan < 2.27, option 'info' isn't + available and the method returns an empty dictionary. + """ + result: Dict[str, str] = {} + if self.exe_file is None: + return result + try: + info = StringIO() + do_command(cmd=[str(self.exe_file), 'info'], fd_out=info) + lines = info.getvalue().split('\n') + for line in lines: + kv_pair = [x.strip() for x in line.split('=')] + if len(kv_pair) != 2: + continue + result[kv_pair[0]] = kv_pair[1] + return result + except RuntimeError as e: + get_logger().debug(e) + return result + + def src_info(self) -> Dict[str, Any]: + """ + Run stanc with option '--info'. + + If stanc is older than 2.27 or if the stan + file cannot be found, returns an empty dictionary. + """ + if self.stan_file is None or cmdstan_version_before(2, 27): + return {} + return compilation.src_info(str(self.stan_file), self._compiler_options) + + # TODO(2.0) remove + def format( + self, + overwrite_file: bool = False, + canonicalize: Union[bool, str, Iterable[str]] = False, + max_line_length: int = 78, + *, + backup: bool = True, + ) -> None: + """ + Deprecated: Use :func:`cmdstanpy.format_stan_file()` instead. + + Run stanc's auto-formatter on the model code. Either saves directly + back to the file or prints for inspection + + + :param overwrite_file: If True, save the updated code to disk, rather + than printing it. By default False + :param canonicalize: Whether or not the compiler should 'canonicalize' + the Stan model, removing things like deprecated syntax. Default is + False. If True, all canonicalizations are run. If it is a list of + strings, those options are passed to stanc (new in Stan 2.29) + :param max_line_length: Set the wrapping point for the formatter. The + default value is 78, which wraps most lines by the 80th character. + :param backup: If True, create a stanfile.bak backup before + writing to the file. Only disable this if you're sure you have other + copies of the file or are using a version control system like Git. + """ + + get_logger().warning( + "CmdStanModel.format() is deprecated and will be " + "removed in the next major version.\n" + "Use cmdstanpy.format_stan_file() instead." + ) + + if self.stan_file is None: + raise ValueError("No Stan file found for this module") + + compilation.format_stan_file( + self.stan_file, + overwrite_file=overwrite_file, + max_line_length=max_line_length, + canonicalize=canonicalize, + backup=backup, + stanc_options=self.stanc_options, + ) + + @property + def stanc_options(self) -> Dict[str, Union[bool, int, str]]: + """Options to stanc compilers.""" + return self._compiler_options._stanc_options + + @property + def cpp_options(self) -> Dict[str, Union[bool, int]]: + """Options to C++ compilers.""" + return self._compiler_options._cpp_options + + @property + def user_header(self) -> str: + """The user header file if it exists, otherwise empty""" + return self._compiler_options._user_header + + def code(self) -> Optional[str]: + """Return Stan program as a string.""" + if not self._stan_file: + raise RuntimeError('Please specify source file') + + code = None + try: + with open(self._stan_file, 'r') as fd: + code = fd.read() + except IOError: + get_logger().error( + 'Cannot read file Stan file: %s', self._stan_file + ) + return code + + # TODO(2.0): remove + def compile( + self, + force: bool = False, + stanc_options: Optional[Dict[str, Any]] = None, + cpp_options: Optional[Dict[str, Any]] = None, + user_header: OptionalPath = None, + override_options: bool = False, + *, + _internal: bool = False, + ) -> None: + """ + Deprecated: To compile a model, use the :class:`~cmdstanpy.CmdStanModel` + constructor or :func:`cmdstanpy.compile_stan_file()`. + + Compile the given Stan program file. Translates the Stan code to + C++, then calls the C++ compiler. + + By default, this function compares the timestamps on the source and + executable files; if the executable is newer than the source file, it + will not recompile the file, unless argument ``force`` is ``True`` + or unless the compiler options have been changed. + + :param force: When ``True``, always compile, even if the executable file + is newer than the source file. Used for Stan models which have + ``#include`` directives in order to force recompilation when changes + are made to the included files. + + :param stanc_options: Options for stanc compiler. + :param cpp_options: Options for C++ compiler. + :param user_header: A path to a header file to include during C++ + compilation. + + :param override_options: When ``True``, override existing option. + When ``False``, add/replace existing options. Default is ``False``. + """ + if not _internal: + get_logger().warning( + "CmdStanModel.compile() is deprecated and will be removed in " + "the next major version. To compile a model, use the " + "CmdStanModel() constructor or cmdstanpy.compile_stan_file()." + ) + + if not self._stan_file: + raise RuntimeError('Please specify source file') + + compiler_options = None + if ( + stanc_options is not None + or cpp_options is not None + or user_header is not None + ): + compiler_options = compilation.CompilerOptions( + stanc_options=stanc_options, + cpp_options=cpp_options, + user_header=user_header, + ) + compiler_options.validate() + + if compiler_options != self._compiler_options: + force = True + if self._compiler_options is None: + self._compiler_options = compiler_options + elif override_options: + self._compiler_options = compiler_options + else: + self._compiler_options.add(compiler_options) + + self._exe_file = compilation.compile_stan_file( + str(self.stan_file), + force=force, + stanc_options=self._compiler_options.stanc_options, + cpp_options=self._compiler_options.cpp_options, + user_header=self._compiler_options.user_header, + ) + + def optimize( + self, + data: Union[Mapping[str, Any], str, os.PathLike, None] = None, + seed: Optional[int] = None, + inits: Union[Mapping[str, Any], float, str, os.PathLike, None] = None, + output_dir: OptionalPath = None, + sig_figs: Optional[int] = None, + save_profile: bool = False, + algorithm: Optional[str] = None, + init_alpha: Optional[float] = None, + tol_obj: Optional[float] = None, + tol_rel_obj: Optional[float] = None, + tol_grad: Optional[float] = None, + tol_rel_grad: Optional[float] = None, + tol_param: Optional[float] = None, + history_size: Optional[int] = None, + iter: Optional[int] = None, + save_iterations: bool = False, + require_converged: bool = True, + show_console: bool = False, + refresh: Optional[int] = None, + time_fmt: str = "%Y%m%d%H%M%S", + timeout: Optional[float] = None, + jacobian: bool = False, + # would be nice to move this further up, but that's a breaking change + ) -> CmdStanMLE: + """ + Run the specified CmdStan optimize algorithm to produce a + penalized maximum likelihood estimate of the model parameters. + + This function validates the specified configuration, composes a call to + the CmdStan ``optimize`` method and spawns one subprocess to run the + optimizer and waits for it to run to completion. + Unspecified arguments are not included in the call to CmdStan, i.e., + those arguments will have CmdStan default values. + + The :class:`CmdStanMLE` object records the command, the return code, + and the paths to the optimize method output CSV and console files. + The output files are written either to a specified output directory + or to a temporary directory which is deleted upon session exit. + + Output files are either written to a temporary directory or to the + specified output directory. Output filenames correspond to the template + '--' plus the file suffix which is + either '.csv' for the CmdStan output or '.txt' for + the console messages, e.g. 'bernoulli-201912081451-1.csv'. + Output files written to the temporary directory contain an additional + 8-character random string, e.g. 'bernoulli-201912081451-1-5nm6as7u.csv'. + + :param data: Values for all data variables in the model, specified + either as a dictionary with entries matching the data variables, + or as the path of a data file in JSON or Rdump format. + + :param seed: The seed for random number generator. Must be an integer + between 0 and 2^32 - 1. If unspecified, + :func:`numpy.random.default_rng` is used to generate a seed. + + :param inits: Specifies how the sampler initializes parameter values. + Initialization is either uniform random on a range centered on 0, + exactly 0, or a dictionary or file of initial values for some or + all parameters in the model. The default initialization behavior + will initialize all parameter values on range [-2, 2] on the + *unconstrained* support. If the expected parameter values are + too far from this range, this option may improve estimation. + The following value types are allowed: + + * Single number, n > 0 - initialization range is [-n, n]. + * 0 - all parameters are initialized to 0. + * dictionary - pairs parameter name : initial value. + * string - pathname to a JSON or Rdump data file. + + :param output_dir: Name of the directory to which CmdStan output + files are written. If unspecified, output files will be written + to a temporary directory which is deleted upon session exit. + + :param sig_figs: Numerical precision used for output CSV and text files. + Must be an integer between 1 and 18. If unspecified, the default + precision for the system file I/O is used; the usual value is 6. + Introduced in CmdStan-2.25. + + :param save_profile: Whether or not to profile auto-diff operations in + labelled blocks of code. If ``True``, CSV outputs are written to + file '--profile-'. + Introduced in CmdStan-2.26. + + :param algorithm: Algorithm to use. One of: 'BFGS', 'LBFGS', 'Newton' + + :param init_alpha: Line search step size for first iteration + + :param tol_obj: Convergence tolerance on changes in objective + function value + + :param tol_rel_obj: Convergence tolerance on relative changes + in objective function value + + :param tol_grad: Convergence tolerance on the norm of the gradient + + :param tol_rel_grad: Convergence tolerance on the relative + norm of the gradient + + :param tol_param: Convergence tolerance on changes in parameter value + + :param history_size: Size of the history for LBFGS Hessian + approximation. The value should be less than the dimensionality + of the parameter space. 5-10 usually sufficient + + :param iter: Total number of iterations + + :param save_iterations: When ``True``, save intermediate approximations + to the output CSV file. Default is ``False``. + + :param require_converged: Whether or not to raise an error if Stan + reports that "The algorithm may not have converged". + + :param show_console: If ``True``, stream CmdStan messages sent to + stdout and stderr to the console. Default is ``False``. + + :param refresh: Specify the number of iterations cmdstan will take + between progress messages. Default value is 100. + + :param time_fmt: A format string passed to + :meth:`~datetime.datetime.strftime` to decide the file names for + output CSVs. Defaults to "%Y%m%d%H%M%S" + + :param timeout: Duration at which optimization times out in seconds. + + :param jacobian: Whether or not to use the Jacobian adjustment for + constrained variables in optimization. By default this is false, + meaning optimization yields the Maximum Likehood Estimate (MLE). + Setting it to true yields the Maximum A Posteriori Estimate (MAP). + + :return: CmdStanMLE object + """ + optimize_args = OptimizeArgs( + algorithm=algorithm, + init_alpha=init_alpha, + tol_obj=tol_obj, + tol_rel_obj=tol_rel_obj, + tol_grad=tol_grad, + tol_rel_grad=tol_rel_grad, + tol_param=tol_param, + history_size=history_size, + iter=iter, + save_iterations=save_iterations, + jacobian=jacobian, + ) + + if jacobian and cmdstan_version_before(2, 32, self.exe_info()): + raise ValueError( + "Jacobian adjustment for optimization is only supported " + "in CmdStan 2.32 and above." + ) + + with temp_single_json(data) as _data, temp_inits( + inits, allow_multiple=False + ) as _inits: + args = CmdStanArgs( + self._name, + self._exe_file, + chain_ids=None, + data=_data, + seed=seed, + inits=_inits, + output_dir=output_dir, + sig_figs=sig_figs, + save_profile=save_profile, + method_args=optimize_args, + refresh=refresh, + ) + dummy_chain_id = 0 + runset = RunSet(args=args, chains=1, time_fmt=time_fmt) + self._run_cmdstan( + runset, + dummy_chain_id, + show_console=show_console, + timeout=timeout, + ) + runset.raise_for_timeouts() + + if not runset._check_retcodes(): + msg = "Error during optimization! Command '{}' failed: {}".format( + ' '.join(runset.cmd(0)), runset.get_err_msgs() + ) + if 'Line search failed' in msg and not require_converged: + get_logger().warning(msg) + else: + raise RuntimeError(msg) + mle = CmdStanMLE(runset) + return mle + + # pylint: disable=too-many-arguments + def sample( + self, + data: Union[Mapping[str, Any], str, os.PathLike, None] = None, + chains: Optional[int] = None, + parallel_chains: Optional[int] = None, + threads_per_chain: Optional[int] = None, + seed: Union[int, List[int], None] = None, + chain_ids: Union[int, List[int], None] = None, + inits: Union[ + Mapping[str, Any], + float, + str, + List[str], + List[Mapping[str, Any]], + None, + ] = None, + iter_warmup: Optional[int] = None, + iter_sampling: Optional[int] = None, + save_warmup: bool = False, + thin: Optional[int] = None, + max_treedepth: Optional[int] = None, + metric: Union[ + str, Dict[str, Any], List[str], List[Dict[str, Any]], None + ] = None, + step_size: Union[float, List[float], None] = None, + adapt_engaged: bool = True, + adapt_delta: Optional[float] = None, + adapt_init_phase: Optional[int] = None, + adapt_metric_window: Optional[int] = None, + adapt_step_size: Optional[int] = None, + fixed_param: bool = False, + output_dir: OptionalPath = None, + sig_figs: Optional[int] = None, + save_latent_dynamics: bool = False, + save_profile: bool = False, + show_progress: bool = True, + show_console: bool = False, + refresh: Optional[int] = None, + time_fmt: str = "%Y%m%d%H%M%S", + timeout: Optional[float] = None, + *, + force_one_process_per_chain: Optional[bool] = None, + ) -> CmdStanMCMC: + """ + Run or more chains of the NUTS-HMC sampler to produce a set of draws + from the posterior distribution of a model conditioned on some data. + + This function validates the specified configuration, composes a call to + the CmdStan ``sample`` method and spawns one subprocess per chain to run + the sampler and waits for all chains to run to completion. + Unspecified arguments are not included in the call to CmdStan, i.e., + those arguments will have CmdStan default values. + + For each chain, the :class:`CmdStanMCMC` object records the command, + the return code, the sampler output file paths, and the corresponding + console outputs, if any. The output files are written either to a + specified output directory or to a temporary directory which is deleted + upon session exit. + + Output files are either written to a temporary directory or to the + specified output directory. Ouput filenames correspond to the template + '--' plus the file suffix which is + either '.csv' for the CmdStan output or '.txt' for + the console messages, e.g. 'bernoulli-201912081451-1.csv'. + Output files written to the temporary directory contain an additional + 8-character random string, e.g. 'bernoulli-201912081451-1-5nm6as7u.csv'. + + :param data: Values for all data variables in the model, specified + either as a dictionary with entries matching the data variables, + or as the path of a data file in JSON or Rdump format. + + :param chains: Number of sampler chains, must be a positive integer. + + :param parallel_chains: Number of processes to run in parallel. Must be + a positive integer. Defaults to :func:`multiprocessing.cpu_count`, + i.e., it will only run as many chains in parallel as there are + cores on the machine. Note that CmdStan 2.28 and higher can run + all chains in parallel providing that the model was compiled with + threading support. + + :param threads_per_chain: The number of threads to use in parallelized + sections within an MCMC chain (e.g., when using the Stan functions + ``reduce_sum()`` or ``map_rect()``). This will only have an effect + if the model was compiled with threading support. For such models, + CmdStan version 2.28 and higher will run all chains in parallel + from within a single process. The total number of threads used + will be ``parallel_chains * threads_per_chain``, where the default + value for parallel_chains is the number of cpus, not chains. + + :param seed: The seed for random number generator. Must be an integer + between 0 and 2^32 - 1. If unspecified, + :func:`numpy.random.default_rng` + is used to generate a seed which will be used for all chains. + When the same seed is used across all chains, + the chain-id is used to advance the RNG to avoid dependent samples. + + :param chain_ids: The offset for the random number generator, either + an integer or a list of unique per-chain offsets. If unspecified, + chain ids are numbered sequentially starting from 1. + + :param inits: Specifies how the sampler initializes parameter values. + Initialization is either uniform random on a range centered on 0, + exactly 0, or a dictionary or file of initial values for some or all + parameters in the model. The default initialization behavior will + initialize all parameter values on range [-2, 2] on the + *unconstrained* support. If the expected parameter values are + too far from this range, this option may improve adaptation. + The following value types are allowed: + + * Single number n > 0 - initialization range is [-n, n]. + * 0 - all parameters are initialized to 0. + * dictionary - pairs parameter name : initial value. + * string - pathname to a JSON or Rdump data file. + * list of strings - per-chain pathname to data file. + * list of dictionaries - per-chain initial values. + + :param iter_warmup: Number of warmup iterations for each chain. + + :param iter_sampling: Number of draws from the posterior for each + chain. + + :param save_warmup: When ``True``, sampler saves warmup draws as part of + the Stan CSV output file. + + :param thin: Period between recorded iterations. Default is 1, i.e., + all iterations are recorded. + + :param max_treedepth: Maximum depth of trees evaluated by NUTS sampler + per iteration. + + :param metric: Specification of the mass matrix, either as a + vector consisting of the diagonal elements of the covariance + matrix ('diag' or 'diag_e') or the full covariance matrix + ('dense' or 'dense_e'). + + If the value of the metric argument is a string other than + 'diag', 'diag_e', 'dense', or 'dense_e', it must be + a valid filepath to a JSON or Rdump file which contains an entry + 'inv_metric' whose value is either the diagonal vector or + the full covariance matrix. + + If the value of the metric argument is a list of paths, its + length must match the number of chains and all paths must be + unique. + + If the value of the metric argument is a Python dict object, it + must contain an entry 'inv_metric' which specifies either the + diagnoal or dense matrix. + + If the value of the metric argument is a list of Python dicts, + its length must match the number of chains and all dicts must + containan entry 'inv_metric' and all 'inv_metric' entries must + have the same shape. + + :param step_size: Initial step size for HMC sampler. The value is + either a single number or a list of numbers which will be used + as the global or per-chain initial step size, respectively. + The length of the list of step sizes must match the number of + chains. + + :param adapt_engaged: When ``True``, adapt step size and metric. + + :param adapt_delta: Adaptation target Metropolis acceptance rate. + The default value is 0.8. Increasing this value, which must be + strictly less than 1, causes adaptation to use smaller step sizes + which improves the effective sample size, but may increase the time + per iteration. + + :param adapt_init_phase: Iterations for initial phase of adaptation + during which step size is adjusted so that the chain converges + towards the typical set. + + :param adapt_metric_window: The second phase of adaptation tunes + the metric and step size in a series of intervals. This parameter + specifies the number of iterations used for the first tuning + interval; window size increases for each subsequent interval. + + :param adapt_step_size: Number of iterations given over to adjusting + the step size given the tuned metric during the final phase of + adaptation. + + :param fixed_param: When ``True``, call CmdStan with argument + ``algorithm=fixed_param`` which runs the sampler without + updating the Markov Chain, thus the values of all parameters and + transformed parameters are constant across all draws and + only those values in the generated quantities block that are + produced by RNG functions may change. This provides + a way to use Stan programs to generate simulated data via the + generated quantities block. Default value is ``False``. + + :param output_dir: Name of the directory to which CmdStan output + files are written. If unspecified, output files will be written + to a temporary directory which is deleted upon session exit. + + :param sig_figs: Numerical precision used for output CSV and text files. + Must be an integer between 1 and 18. If unspecified, the default + precision for the system file I/O is used; the usual value is 6. + Introduced in CmdStan-2.25. + + :param save_latent_dynamics: Whether or not to output the position and + momentum information for the model parameters (unconstrained). + If ``True``, CSV outputs are written to an output file + '--diagnostic-', + e.g. 'bernoulli-201912081451-diagnostic-1.csv', see + https://mc-stan.org/docs/cmdstan-guide/stan_csv.html, + section "Diagnostic CSV output file" for details. + + :param save_profile: Whether or not to profile auto-diff operations in + labelled blocks of code. If ``True``, CSV outputs are written to + file '--profile-'. + Introduced in CmdStan-2.26, see + https://mc-stan.org/docs/cmdstan-guide/stan_csv.html, + section "Profiling CSV output file" for details. + + :param show_progress: If ``True``, display progress bar to track + progress for warmup and sampling iterations. Default is ``True``, + unless package tqdm progress bar encounter errors. + + :param show_console: If ``True``, stream CmdStan messages sent to stdout + and stderr to the console. Default is ``False``. + + :param refresh: Specify the number of iterations CmdStan will take + between progress messages. Default value is 100. + + :param time_fmt: A format string passed to + :meth:`~datetime.datetime.strftime` to decide the file names for + output CSVs. Defaults to "%Y%m%d%H%M%S" + + :param force_one_process_per_chain: If ``True``, run multiple chains in + distinct processes regardless of model ability to run parallel + chains (CmdStan 2.28+ feature). If ``False``, always run multiple + chains in one process (does not check that this is valid). + + If None (Default): Check that CmdStan version is >=2.28, and that + model was compiled with STAN_THREADS=True, and utilize the + parallel chain functionality if those conditions are met. + + :param timeout: Duration at which sampling times out in seconds. + + :return: CmdStanMCMC object + """ + if fixed_param is None: + fixed_param = self._fixed_param + + if chains is None: + chains = 4 + if chains < 1: + raise ValueError( + 'Chains must be a positive integer value, found {}.'.format( + chains + ) + ) + + if parallel_chains is None: + parallel_chains = max(min(cpu_count(), chains), 1) + elif parallel_chains > chains: + get_logger().info( + 'Requested %u parallel_chains but only %u required, ' + 'will run all chains in parallel.', + parallel_chains, + chains, + ) + parallel_chains = chains + elif parallel_chains < 1: + raise ValueError( + 'Argument parallel_chains must be a positive integer, ' + 'found {}.'.format(parallel_chains) + ) + if threads_per_chain is None: + threads_per_chain = 1 + if threads_per_chain < 1: + raise ValueError( + 'Argument threads_per_chain must be a positive integer, ' + 'found {}.'.format(threads_per_chain) + ) + + parallel_procs = parallel_chains + num_threads = threads_per_chain + one_process_per_chain = True + info_dict = self.exe_info() + stan_threads = info_dict.get('STAN_THREADS', 'false').lower() + # run multi-chain sampler unless algo is fixed_param or 1 chain + if chains == 1: + force_one_process_per_chain = True + + if ( + force_one_process_per_chain is None + and not cmdstan_version_before(2, 28, info_dict) + and stan_threads == 'true' + ): + one_process_per_chain = False + num_threads = parallel_chains * num_threads + parallel_procs = 1 + if force_one_process_per_chain is False: + if not cmdstan_version_before(2, 28, info_dict): + one_process_per_chain = False + num_threads = parallel_chains * num_threads + parallel_procs = 1 + if stan_threads == 'false': + get_logger().warning( + 'Stan program not compiled for threading, ' + 'process will run chains sequentially. ' + 'For multi-chain parallelization, recompile ' + 'the model with argument ' + '"cpp_options={\'STAN_THREADS\':\'TRUE\'}.' + ) + else: + get_logger().warning( + 'Installed version of CmdStan cannot multi-process ' + 'chains, will run %d processes. ' + 'Run "install_cmdstan" to upgrade to latest version.', + chains, + ) + os.environ['STAN_NUM_THREADS'] = str(num_threads) + + if chain_ids is None: + chain_ids = [i + 1 for i in range(chains)] + else: + if isinstance(chain_ids, int): + if chain_ids < 1: + raise ValueError( + 'Chain_id must be a positive integer value,' + ' found {}.'.format(chain_ids) + ) + chain_ids = [i + chain_ids for i in range(chains)] + else: + if not one_process_per_chain: + for i, j in zip(chain_ids, chain_ids[1:]): + if i != j - 1: + raise ValueError( + 'chain_ids must be sequential list of integers,' + ' found {}.'.format(chain_ids) + ) + if not len(chain_ids) == chains: + raise ValueError( + 'Chain_ids must correspond to number of chains' + ' specified {} chains, found {} chain_ids.'.format( + chains, len(chain_ids) + ) + ) + for chain_id in chain_ids: + if chain_id < 0: + raise ValueError( + 'Chain_id must be a non-negative integer value,' + ' found {}.'.format(chain_id) + ) + + sampler_args = SamplerArgs( + num_chains=1 if one_process_per_chain else chains, + iter_warmup=iter_warmup, + iter_sampling=iter_sampling, + save_warmup=save_warmup, + thin=thin, + max_treedepth=max_treedepth, + metric=metric, + step_size=step_size, + adapt_engaged=adapt_engaged, + adapt_delta=adapt_delta, + adapt_init_phase=adapt_init_phase, + adapt_metric_window=adapt_metric_window, + adapt_step_size=adapt_step_size, + fixed_param=fixed_param, + ) + + with temp_single_json(data) as _data, temp_inits( + inits, id=chain_ids[0] + ) as _inits: + cmdstan_inits: Union[str, List[str], int, float, None] + if one_process_per_chain and isinstance(inits, list): # legacy + cmdstan_inits = [ + f"{_inits[:-5]}_{i}.json" for i in chain_ids # type: ignore + ] + else: + cmdstan_inits = _inits + + args = CmdStanArgs( + self._name, + self._exe_file, + chain_ids=chain_ids, + data=_data, + seed=seed, + inits=cmdstan_inits, + output_dir=output_dir, + sig_figs=sig_figs, + save_latent_dynamics=save_latent_dynamics, + save_profile=save_profile, + method_args=sampler_args, + refresh=refresh, + ) + + if show_console: + show_progress = False + else: + show_progress = show_progress and progbar.allow_show_progress() + get_logger().info('CmdStan start processing') + + progress_hook: Optional[Callable[[str, int], None]] = None + if show_progress: + iter_total = 0 + if iter_warmup is None: + iter_total += _CMDSTAN_WARMUP + else: + iter_total += iter_warmup + if iter_sampling is None: + iter_total += _CMDSTAN_SAMPLING + else: + iter_total += iter_sampling + if refresh is None: + refresh = _CMDSTAN_REFRESH + iter_total = iter_total // refresh + 2 + + progress_hook = self._wrap_sampler_progress_hook( + chain_ids=chain_ids, + total=iter_total, + ) + runset = RunSet( + args=args, + chains=chains, + chain_ids=chain_ids, + time_fmt=time_fmt, + one_process_per_chain=one_process_per_chain, + ) + with ThreadPoolExecutor(max_workers=parallel_procs) as executor: + for i in range(runset.num_procs): + executor.submit( + self._run_cmdstan, + runset=runset, + idx=i, + show_progress=show_progress, + show_console=show_console, + progress_hook=progress_hook, + timeout=timeout, + ) + if show_progress and progress_hook is not None: + progress_hook("Done", -1) # -1 == all chains finished + + # advance terminal window cursor past progress bars + term_size: os.terminal_size = shutil.get_terminal_size( + fallback=(80, 24) + ) + if term_size is not None and term_size[0] > 0: + for i in range(chains): + sys.stdout.write(' ' * term_size[0]) + sys.stdout.flush() + sys.stdout.write('\n') + get_logger().info('CmdStan done processing.') + + runset.raise_for_timeouts() + + get_logger().debug('runset\n%s', repr(runset)) + + # hack needed to parse CSV files if model has no params + # needed if exe is supplied without stan file + with open(runset.stdout_files[0], 'r') as fd: + console_msgs = fd.read() + get_logger().debug('Chain 1 console:\n%s', console_msgs) + if 'running fixed_param sampler' in console_msgs: + get_logger().debug("Detected fixed param model") + sampler_args.fixed_param = True + runset._args.method_args = sampler_args + + errors = runset.get_err_msgs() + if not runset._check_retcodes(): + msg = ( + f'Error during sampling:\n{errors}\n' + f'Command and output files:\n{repr(runset)}' + ) + if not show_console: + msg += ( + '\nConsider re-running with show_console=True if the' + ' above output is unclear!' + ) + raise RuntimeError(msg) + if errors: + msg = f'Non-fatal error during sampling:\n{errors}' + if not show_console: + msg += ( + '\nConsider re-running with show_console=True if the' + ' above output is unclear!' + ) + get_logger().warning(msg) + + mcmc = CmdStanMCMC(runset) + return mcmc + + def generate_quantities( + self, + data: Union[Mapping[str, Any], str, os.PathLike, None] = None, + previous_fit: Union[Fit, List[str], None] = None, + seed: Optional[int] = None, + gq_output_dir: OptionalPath = None, + sig_figs: Optional[int] = None, + show_console: bool = False, + refresh: Optional[int] = None, + time_fmt: str = "%Y%m%d%H%M%S", + timeout: Optional[float] = None, + *, + mcmc_sample: Union[CmdStanMCMC, List[str], None] = None, + ) -> CmdStanGQ[Fit]: + """ + Run CmdStan's generate_quantities method which runs the generated + quantities block of a model given an existing sample. + + This function takes one of the Stan fit objects + :class:`CmdStanMCMC`, :class:`CmdStanMLE`, or :class:`CmdStanVB` + and the data required for the model and calls to the CmdStan + ``generate_quantities`` method to generate additional quantities of + interest. + + The :class:`CmdStanGQ` object records the command, the return code, + and the paths to the generate method output CSV and console files. + The output files are written either to a specified output directory + or to a temporary directory which is deleted upon session exit. + + Output files are either written to a temporary directory or to the + specified output directory. Output filenames correspond to the template + '--' plus the file suffix which is + either '.csv' for the CmdStan output or '.txt' for + the console messages, e.g. 'bernoulli-201912081451-1.csv'. + Output files written to the temporary directory contain an additional + 8-character random string, e.g. 'bernoulli-201912081451-1-5nm6as7u.csv'. + + :param data: Values for all data variables in the model, specified + either as a dictionary with entries matching the data variables, + or as the path of a data file in JSON or Rdump format. + + :param previous_fit: Can be either a :class:`CmdStanMCMC`, + :class:`CmdStanMLE`, or :class:`CmdStanVB` or a list of + stan-csv files generated by fitting the model to the data + using any Stan interface. + + :param seed: The seed for random number generator. Must be an integer + between 0 and 2^32 - 1. If unspecified, + :func:`numpy.random.default_rng` + is used to generate a seed which will be used for all chains. + *NOTE: Specifying the seed will guarantee the same result for + multiple invocations of this method with the same inputs. However + this will not reproduce results from the sample method given + the same inputs because the RNG will be in a different state.* + + :param gq_output_dir: Name of the directory in which the CmdStan output + files are saved. If unspecified, files will be written to a + temporary directory which is deleted upon session exit. + + :param sig_figs: Numerical precision used for output CSV and text files. + Must be an integer between 1 and 18. If unspecified, the default + precision for the system file I/O is used; the usual value is 6. + Introduced in CmdStan-2.25. + + :param show_console: If ``True``, stream CmdStan messages sent to + stdout and stderr to the console. Default is ``False``. + + :param refresh: Specify the number of iterations CmdStan will take + between progress messages. Default value is 100. + + :param time_fmt: A format string passed to + :meth:`~datetime.datetime.strftime` to decide the file names for + output CSVs. Defaults to "%Y%m%d%H%M%S" + + :param timeout: Duration at which generation times out in seconds. + + :return: CmdStanGQ object + """ + # TODO(2.0): remove + if mcmc_sample is not None: + if previous_fit: + raise ValueError( + "Cannot supply both 'previous_fit' and " + "deprecated argument 'mcmc_sample'" + ) + get_logger().warning( + "Argument name `mcmc_sample` is deprecated, please " + "rename to `previous_fit`." + ) + + previous_fit = mcmc_sample # type: ignore + + if isinstance(previous_fit, (CmdStanMCMC, CmdStanMLE, CmdStanVB)): + fit_object = previous_fit + fit_csv_files = previous_fit.runset.csv_files + elif isinstance(previous_fit, list): + if len(previous_fit) < 1: + raise ValueError( + 'Expecting list of Stan CSV files, found empty list' + ) + try: + fit_csv_files = previous_fit + fit_object = from_csv(fit_csv_files) # type: ignore + except ValueError as e: + raise ValueError( + 'Invalid sample from Stan CSV files, error:\n\t{}\n\t' + ' while processing files\n\t{}'.format( + repr(e), '\n\t'.join(previous_fit) + ) + ) from e + else: + raise ValueError( + 'Previous fit must be either CmdStanPy fit object' + ' or list of paths to Stan CSV files.' + ) + if isinstance(fit_object, CmdStanMCMC): + chains = fit_object.chains + chain_ids = fit_object.chain_ids + if fit_object._save_warmup: + get_logger().warning( + 'Sample contains saved warmup draws which will be used ' + 'to generate additional quantities of interest.' + ) + elif isinstance(fit_object, CmdStanMLE): + if cmdstan_version_before(2, 31): + raise RuntimeError( + "Method generate_quantities was not " + "available for non-HMC until CmdStan 2.31" + ) + chains = 1 + chain_ids = [1] + if fit_object._save_iterations: + get_logger().warning( + 'MLE contains saved iterations which will be used ' + 'to generate additional quantities of interest.' + ) + else: # isinstance(fit_object, CmdStanVB) + if cmdstan_version_before(2, 31): + raise RuntimeError( + "Method generate_quantities was not " + "available for non-HMC until CmdStan 2.31" + ) + chains = 1 + chain_ids = [1] + + generate_quantities_args = GenerateQuantitiesArgs( + csv_files=fit_csv_files + ) + generate_quantities_args.validate(chains) + with temp_single_json(data) as _data: + args = CmdStanArgs( + self._name, + self._exe_file, + chain_ids=chain_ids, + data=_data, + seed=seed, + output_dir=gq_output_dir, + sig_figs=sig_figs, + method_args=generate_quantities_args, + refresh=refresh, + ) + runset = RunSet( + args=args, chains=chains, chain_ids=chain_ids, time_fmt=time_fmt + ) + + parallel_chains_avail = cpu_count() + parallel_chains = max(min(parallel_chains_avail - 2, chains), 1) + with ThreadPoolExecutor(max_workers=parallel_chains) as executor: + for i in range(chains): + executor.submit( + self._run_cmdstan, + runset, + i, + show_console=show_console, + timeout=timeout, + ) + + runset.raise_for_timeouts() + errors = runset.get_err_msgs() + if errors: + msg = ( + f'Error during generate_quantities:\n{errors}\n' + f'Command and output files:\n{repr(runset)}' + ) + if not show_console: + msg += ( + '\nConsider re-running with show_console=True if the' + ' above output is unclear!' + ) + raise RuntimeError(msg) + quantities = CmdStanGQ(runset=runset, previous_fit=fit_object) + return quantities + + def variational( + self, + data: Union[Mapping[str, Any], str, os.PathLike, None] = None, + seed: Optional[int] = None, + inits: Optional[float] = None, + output_dir: OptionalPath = None, + sig_figs: Optional[int] = None, + save_latent_dynamics: bool = False, + save_profile: bool = False, + algorithm: Optional[str] = None, + iter: Optional[int] = None, + grad_samples: Optional[int] = None, + elbo_samples: Optional[int] = None, + eta: Optional[float] = None, + adapt_engaged: bool = True, + adapt_iter: Optional[int] = None, + tol_rel_obj: Optional[float] = None, + eval_elbo: Optional[int] = None, + draws: Optional[int] = None, + require_converged: bool = True, + show_console: bool = False, + refresh: Optional[int] = None, + time_fmt: str = "%Y%m%d%H%M%S", + timeout: Optional[float] = None, + *, + output_samples: Optional[int] = None, + ) -> CmdStanVB: + """ + Run CmdStan's variational inference algorithm to approximate + the posterior distribution of the model conditioned on the data. + + This function validates the specified configuration, composes a call to + the CmdStan ``variational`` method and spawns one subprocess to run the + optimizer and waits for it to run to completion. + Unspecified arguments are not included in the call to CmdStan, i.e., + those arguments will have CmdStan default values. + + The :class:`CmdStanVB` object records the command, the return code, + and the paths to the variational method output CSV and console files. + The output files are written either to a specified output directory + or to a temporary directory which is deleted upon session exit. + + Output files are either written to a temporary directory or to the + specified output directory. Output filenames correspond to the template + '--' plus the file suffix which is + either '.csv' for the CmdStan output or '.txt' for + the console messages, e.g. 'bernoulli-201912081451-1.csv'. + Output files written to the temporary directory contain an additional + 8-character random string, e.g. 'bernoulli-201912081451-1-5nm6as7u.csv'. + + :param data: Values for all data variables in the model, specified + either as a dictionary with entries matching the data variables, + or as the path of a data file in JSON or Rdump format. + + :param seed: The seed for random number generator. Must be an integer + between 0 and 2^32 - 1. If unspecified, + :func:`numpy.random.default_rng` + is used to generate a seed which will be used for all chains. + + :param inits: Specifies how the sampler initializes parameter values. + Initialization is uniform random on a range centered on 0 with + default range of 2. Specifying a single number n > 0 changes + the initialization range to [-n, n]. + + :param output_dir: Name of the directory to which CmdStan output + files are written. If unspecified, output files will be written + to a temporary directory which is deleted upon session exit. + + :param sig_figs: Numerical precision used for output CSV and text files. + Must be an integer between 1 and 18. If unspecified, the default + precision for the system file I/O is used; the usual value is 6. + Introduced in CmdStan-2.25. + + :param save_latent_dynamics: Whether or not to save diagnostics. + If ``True``, CSV outputs are written to output file + '--diagnostic-', + e.g. 'bernoulli-201912081451-diagnostic-1.csv'. + + :param save_profile: Whether or not to profile auto-diff operations in + labelled blocks of code. If ``True``, CSV outputs are written to + file '--profile-'. + Introduced in CmdStan-2.26. + + :param algorithm: Algorithm to use. One of: 'meanfield', 'fullrank'. + + :param iter: Maximum number of ADVI iterations. + + :param grad_samples: Number of MC draws for computing the gradient. + Default is 10. If problems arise, try doubling current value. + + :param elbo_samples: Number of MC draws for estimate of ELBO. + + :param eta: Step size scaling parameter. + + :param adapt_engaged: Whether eta adaptation is engaged. + + :param adapt_iter: Number of iterations for eta adaptation. + + :param tol_rel_obj: Relative tolerance parameter for convergence. + + :param eval_elbo: Number of iterations between ELBO evaluations. + + :param draws: Number of approximate posterior output draws + to save. + + :param require_converged: Whether or not to raise an error if Stan + reports that "The algorithm may not have converged". + + :param show_console: If ``True``, stream CmdStan messages sent to + stdout and stderr to the console. Default is ``False``. + + :param refresh: Specify the number of iterations CmdStan will take + between progress messages. Default value is 100. + + :param time_fmt: A format string passed to + :meth:`~datetime.datetime.strftime` to decide the file names for + output CSVs. Defaults to "%Y%m%d%H%M%S" + + :param timeout: Duration at which variational Bayesian inference times + out in seconds. + + :return: CmdStanVB object + """ + # TODO(2.0): remove + if output_samples is not None: + if draws is not None: + raise ValueError( + "Cannot supply both 'draws' and deprecated argument " + "'output_samples'" + ) + get_logger().warning( + "Argument name `output_samples` is deprecated, please " + "rename to `draws`." + ) + + draws = output_samples + + variational_args = VariationalArgs( + algorithm=algorithm, + iter=iter, + grad_samples=grad_samples, + elbo_samples=elbo_samples, + eta=eta, + adapt_engaged=adapt_engaged, + adapt_iter=adapt_iter, + tol_rel_obj=tol_rel_obj, + eval_elbo=eval_elbo, + output_samples=draws, + ) + + with temp_single_json(data) as _data, temp_inits( + inits, allow_multiple=False + ) as _inits: + args = CmdStanArgs( + self._name, + self._exe_file, + chain_ids=None, + data=_data, + seed=seed, + inits=_inits, + output_dir=output_dir, + sig_figs=sig_figs, + save_latent_dynamics=save_latent_dynamics, + save_profile=save_profile, + method_args=variational_args, + refresh=refresh, + ) + + dummy_chain_id = 0 + runset = RunSet(args=args, chains=1, time_fmt=time_fmt) + self._run_cmdstan( + runset, + dummy_chain_id, + show_console=show_console, + timeout=timeout, + ) + runset.raise_for_timeouts() + + # treat failure to converge as failure + transcript_file = runset.stdout_files[dummy_chain_id] + pat = re.compile(r'The algorithm may not have converged.', re.M) + with open(transcript_file, 'r') as transcript: + contents = transcript.read() + if len(re.findall(pat, contents)) > 0: + if require_converged: + raise RuntimeError( + 'The algorithm may not have converged.\n' + 'If you would like to inspect the output, ' + 're-call with require_converged=False' + ) + # else: + get_logger().warning( + '%s\n%s', + 'The algorithm may not have converged.', + 'Proceeding because require_converged is set to False', + ) + if not runset._check_retcodes(): + transcript_file = runset.stdout_files[dummy_chain_id] + with open(transcript_file, 'r') as transcript: + contents = transcript.read() + pat = re.compile( + r'stan::variational::normal_meanfield::calc_grad:', re.M + ) + if len(re.findall(pat, contents)) > 0: + if grad_samples is None: + grad_samples = 10 + msg = ( + 'Variational algorithm gradient calculation failed. ' + 'Double the value of argument "grad_samples", ' + 'current value is {}.'.format(grad_samples) + ) + else: + msg = 'Error during variational inference: {}'.format( + runset.get_err_msgs() + ) + raise RuntimeError(msg) + # pylint: disable=invalid-name + vb = CmdStanVB(runset) + return vb + + def pathfinder( + self, + data: Union[Mapping[str, Any], str, os.PathLike, None] = None, + *, + init_alpha: Optional[float] = None, + tol_obj: Optional[float] = None, + tol_rel_obj: Optional[float] = None, + tol_grad: Optional[float] = None, + tol_rel_grad: Optional[float] = None, + tol_param: Optional[float] = None, + history_size: Optional[int] = None, + num_paths: Optional[int] = None, + max_lbfgs_iters: Optional[int] = None, + draws: Optional[int] = None, + num_single_draws: Optional[int] = None, + num_elbo_draws: Optional[int] = None, + psis_resample: bool = True, + calculate_lp: bool = True, + # arguments standard to all methods + seed: Optional[int] = None, + inits: Union[Dict[str, float], float, str, os.PathLike, None] = None, + output_dir: OptionalPath = None, + sig_figs: Optional[int] = None, + save_profile: bool = False, + show_console: bool = False, + refresh: Optional[int] = None, + time_fmt: str = "%Y%m%d%H%M%S", + timeout: Optional[float] = None, + num_threads: Optional[int] = None, + ) -> CmdStanPathfinder: + """ + Run CmdStan's Pathfinder variational inference algorithm. + + :param data: Values for all data variables in the model, specified + either as a dictionary with entries matching the data variables, + or as the path of a data file in JSON or Rdump format. + + :param num_paths: Number of single-path Pathfinders to run. + Default is 4, when the number of paths is 1 then no importance + sampling is done. + + :param draws: Number of approximate draws to return. + + :param num_single_draws: Number of draws each single-pathfinder will + draw. + If ``num_paths`` is 1, only one of this and ``draws`` should be + used. + + :param max_lbfgs_iters: Maximum number of L-BFGS iterations. + + :param num_elbo_draws: Number of Monte Carlo draws to evaluate ELBO. + + :param psis_resample: Whether or not to use Pareto Smoothed Importance + Sampling on the result of the individual Pathfinders. If False, the + result contains the draws from each path. + + :param calculate_lp: Whether or not to calculate the log probability + for approximate draws. If False, this also implies that + ``psis_resample`` will be set to False. + + :param seed: The seed for random number generator. Must be an integer + between 0 and 2^32 - 1. If unspecified, + :func:`numpy.random.default_rng` is used to generate a seed. + + :param inits: Specifies how the algorithm initializes parameter values. + Initialization is either uniform random on a range centered on 0, + exactly 0, or a dictionary or file of initial values for some or all + parameters in the model. The default initialization behavior will + initialize all parameter values on range [-2, 2] on the + *unconstrained* support. If the expected parameter values are + too far from this range, this option may improve adaptation. + The following value types are allowed: + + * Single number n > 0 - initialization range is [-n, n]. + * 0 - all parameters are initialized to 0. + * dictionary - pairs parameter name : initial value. + * string - pathname to a JSON or Rdump data file. + * list of strings - per-path pathname to data file. + * list of dictionaries - per-path initial values. + + :param init_alpha: For internal L-BFGS: Line search step size for + first iteration + + :param tol_obj: For internal L-BFGS: Convergence tolerance on changes + in objective function value + + :param tol_rel_obj: For internal L-BFGS: Convergence tolerance on + relative changes in objective function value + + :param tol_grad: For internal L-BFGS: Convergence tolerance on the + norm of the gradient + + :param tol_rel_grad: For internal L-BFGS: Convergence tolerance on + the relative norm of the gradient + + :param tol_param: For internal L-BFGS: Convergence tolerance on changes + in parameter value + + :param history_size: For internal L-BFGS: Size of the history for LBFGS + Hessian approximation. The value should be less than the + dimensionality of the parameter space. 5-10 is usually sufficient + + :param output_dir: Name of the directory to which CmdStan output + files are written. If unspecified, output files will be written + to a temporary directory which is deleted upon session exit. + + :param sig_figs: Numerical precision used for output CSV and text files. + Must be an integer between 1 and 18. If unspecified, the default + precision for the system file I/O is used; the usual value is 6. + Introduced in CmdStan-2.25. + + :param save_profile: Whether or not to profile auto-diff operations in + labelled blocks of code. If ``True``, CSV outputs are written to + file '--profile-'. + Introduced in CmdStan-2.26, see + https://mc-stan.org/docs/cmdstan-guide/stan_csv.html, + section "Profiling CSV output file" for details. + + :param show_console: If ``True``, stream CmdStan messages sent to stdout + and stderr to the console. Default is ``False``. + + :param refresh: Specify the number of iterations CmdStan will take + between progress messages. Default value is 100. + + :param time_fmt: A format string passed to + :meth:`~datetime.datetime.strftime` to decide the file names for + output CSVs. Defaults to "%Y%m%d%H%M%S" + + :param timeout: Duration at which Pathfinder times + out in seconds. Defaults to None. + + :param num_threads: Number of threads to request for parallel execution. + A number other than ``1`` requires the model to have been compiled + with STAN_THREADS=True. + + :return: A :class:`CmdStanPathfinder` object + + References + ---------- + + Zhang, L., Carpenter, B., Gelman, A., & Vehtari, A. (2022). Pathfinder: + Parallel quasi-Newton variational inference. Journal of Machine Learning + Research, 23(306), 1–49. Retrieved from + http://jmlr.org/papers/v23/21-0889.html + """ + + exe_info = self.exe_info() + if cmdstan_version_before(2, 33, exe_info): + raise ValueError( + "Method 'pathfinder' not available for CmdStan versions " + "before 2.33" + ) + + if (not psis_resample or not calculate_lp) and cmdstan_version_before( + 2, 34, exe_info + ): + raise ValueError( + "Arguments 'psis_resample' and 'calculate_lp' are only " + "available for CmdStan versions 2.34 and later" + ) + + if num_threads is not None: + if ( + num_threads != 1 + and exe_info.get('STAN_THREADS', '').lower() != 'true' + ): + raise ValueError( + "Model must be compiled with 'STAN_THREADS=true' to use" + " 'num_threads' argument" + ) + os.environ['STAN_NUM_THREADS'] = str(num_threads) + + if num_paths == 1: + if num_single_draws is None: + num_single_draws = draws + if draws is not None and num_single_draws != draws: + raise ValueError( + "Cannot specify both 'draws' and 'num_single_draws'" + " when 'num_paths' is 1" + ) + + pathfinder_args = PathfinderArgs( + init_alpha=init_alpha, + tol_obj=tol_obj, + tol_rel_obj=tol_rel_obj, + tol_grad=tol_grad, + tol_rel_grad=tol_rel_grad, + tol_param=tol_param, + history_size=history_size, + num_psis_draws=draws, + num_paths=num_paths, + max_lbfgs_iters=max_lbfgs_iters, + num_draws=num_single_draws, + num_elbo_draws=num_elbo_draws, + psis_resample=psis_resample, + calculate_lp=calculate_lp, + ) + + with temp_single_json(data) as _data, temp_inits(inits) as _inits: + args = CmdStanArgs( + self._name, + self._exe_file, + chain_ids=None, + data=_data, + seed=seed, + inits=_inits, + output_dir=output_dir, + sig_figs=sig_figs, + save_profile=save_profile, + method_args=pathfinder_args, + refresh=refresh, + ) + dummy_chain_id = 0 + runset = RunSet(args=args, chains=1, time_fmt=time_fmt) + self._run_cmdstan( + runset, + dummy_chain_id, + show_console=show_console, + timeout=timeout, + ) + runset.raise_for_timeouts() + + if not runset._check_retcodes(): + msg = "Error during Pathfinder! Command '{}' failed: {}".format( + ' '.join(runset.cmd(0)), runset.get_err_msgs() + ) + raise RuntimeError(msg) + return CmdStanPathfinder(runset) + + def log_prob( + self, + params: Union[Dict[str, Any], str, os.PathLike], + data: Union[Mapping[str, Any], str, os.PathLike, None] = None, + *, + jacobian: bool = True, + sig_figs: Optional[int] = None, + ) -> pd.DataFrame: + """ + Calculate the log probability and gradient at the given parameter + values. + + .. note:: This function is **NOT** an efficient way to evaluate the log + density of the model. It should be used for diagnostics ONLY. + Please, do not use this for other purposes such as testing new + sampling algorithms! + + :param params: Values for all parameters in the model, specified + either as a dictionary with entries matching the parameter + variables, or as the path of a data file in JSON or Rdump format. + + These should be given on the constrained (natural) scale. + + :param data: Values for all data variables in the model, specified + either as a dictionary with entries matching the data variables, + or as the path of a data file in JSON or Rdump format. + + :param jacobian: Whether or not to enable the Jacobian adjustment + for constrained parameters. Defaults to ``True``. + + :param sig_figs: Numerical precision used for output CSV and text files. + Must be an integer between 1 and 18. If unspecified, the default + precision for the system file I/O is used; the usual value is 6. + + :return: A pandas.DataFrame containing columns "lp__" and additional + columns for the gradient values. These gradients will be for the + unconstrained parameters of the model. + """ + + if cmdstan_version_before(2, 31, self.exe_info()): + raise ValueError( + "Method 'log_prob' not available for CmdStan versions " + "before 2.31" + ) + with temp_single_json(data) as _data, temp_single_json( + params + ) as _params: + cmd = [ + str(self.exe_file), + "log_prob", + f"constrained_params={_params}", + f"jacobian={int(jacobian)}", + ] + if _data is not None: + cmd += ["data", f"file={_data}"] + + output_dir = tempfile.mkdtemp(prefix=self.name, dir=_TMPDIR) + + output = os.path.join(output_dir, "output.csv") + cmd += ["output", f"file={output}"] + if sig_figs is not None: + cmd.append(f"sig_figs={sig_figs}") + + get_logger().debug("Cmd: %s", str(cmd)) + + proc = subprocess.run( + cmd, capture_output=True, check=False, text=True + ) + if proc.returncode: + get_logger().error( + "'log_prob' command failed!\nstdout:%s\nstderr:%s", + proc.stdout, + proc.stderr, + ) + raise RuntimeError( + "Method 'log_prob' failed with return code " + + str(proc.returncode) + ) + + result = pd.read_csv(output, comment="#") + return result + + def laplace_sample( + self, + data: Union[Mapping[str, Any], str, os.PathLike, None] = None, + mode: Union[CmdStanMLE, str, os.PathLike, None] = None, + draws: Optional[int] = None, + *, + jacobian: bool = True, # NB: Different than optimize! + seed: Optional[int] = None, + output_dir: OptionalPath = None, + sig_figs: Optional[int] = None, + save_profile: bool = False, + show_console: bool = False, + refresh: Optional[int] = None, + time_fmt: str = "%Y%m%d%H%M%S", + timeout: Optional[float] = None, + opt_args: Optional[Dict[str, Any]] = None, + ) -> CmdStanLaplace: + """ + Run a Laplace approximation around the posterior mode. + + :param data: Values for all data variables in the model, specified + either as a dictionary with entries matching the data variables, + or as the path of a data file in JSON or Rdump format. + + :param mode: The mode around which to place the approximation, either + + * A :class:`CmdStanMLE` object + * A path to a CSV file containing the output of an optimization run. + * ``None`` - use default optimizer settings and/or any ``opt_args``. + + :param draws: Number of approximate draws to return. + Defaults to 1000 + + :param jacobian: Whether or not to enable the Jacobian adjustment + for constrained parameters. Defaults to ``True``. + Note: This must match the argument used in the creation of + ``mode``, if supplied. + + :param output_dir: Name of the directory to which CmdStan output + files are written. If unspecified, output files will be written + to a temporary directory which is deleted upon session exit. + + :param sig_figs: Numerical precision used for output CSV and text files. + Must be an integer between 1 and 18. If unspecified, the default + precision for the system file I/O is used; the usual value is 6. + Introduced in CmdStan-2.25. + + :param save_profile: Whether or not to profile auto-diff operations in + labelled blocks of code. If ``True``, CSV outputs are written to + file '--profile-'. + Introduced in CmdStan-2.26, see + https://mc-stan.org/docs/cmdstan-guide/stan_csv.html, + section "Profiling CSV output file" for details. + + :param show_console: If ``True``, stream CmdStan messages sent to stdout + and stderr to the console. Default is ``False``. + + :param refresh: Specify the number of iterations CmdStan will take + between progress messages. Default value is 100. + + :param time_fmt: A format string passed to + :meth:`~datetime.datetime.strftime` to decide the file names for + output CSVs. Defaults to "%Y%m%d%H%M%S" + + :param timeout: Duration at which Pathfinder times + out in seconds. Defaults to None. + + :param opt_args: Dictionary of additional arguments + which will be passed to :meth:`~CmdStanModel.optimize` + + :return: A :class:`CmdStanLaplace` object. + """ + if cmdstan_version_before(2, 32, self.exe_info()): + raise ValueError( + "Method 'laplace_sample' not available for CmdStan versions " + "before 2.32" + ) + if opt_args is not None and mode is not None: + raise ValueError( + "Cannot specify both 'opt_args' and 'mode' arguments" + ) + if mode is None: + optimize_args = { + "seed": seed, + "sig_figs": sig_figs, + "jacobian": jacobian, + "save_profile": save_profile, + "show_console": show_console, + "refresh": refresh, + "time_fmt": time_fmt, + "timeout": timeout, + "output_dir": output_dir, + } + optimize_args.update(opt_args or {}) + optimize_args['time_fmt'] = 'opt-' + time_fmt + try: + cmdstan_mode: CmdStanMLE = self.optimize( + data=data, + **optimize_args, # type: ignore + ) + except Exception as e: + raise RuntimeError( + "Failed to run optimizer on model. " + "Consider supplying a mode or additional optimizer args" + ) from e + elif not isinstance(mode, CmdStanMLE): + cmdstan_mode = from_csv(mode) # type: ignore # we check below + else: + cmdstan_mode = mode + + if cmdstan_mode.runset.method != Method.OPTIMIZE: + raise ValueError( + "Mode must be a CmdStanMLE or a path to an optimize CSV" + ) + + mode_jacobian = ( + cmdstan_mode.runset._args.method_args.jacobian # type: ignore + ) + if mode_jacobian != jacobian: + raise ValueError( + "Jacobian argument to optimize and laplace must match!\n" + f"Laplace was run with jacobian={jacobian},\n" + f"but optimize was run with jacobian={mode_jacobian}" + ) + + laplace_args = LaplaceArgs( + cmdstan_mode.runset.csv_files[0], draws, jacobian + ) + + with temp_single_json(data) as _data: + args = CmdStanArgs( + self._name, + self._exe_file, + chain_ids=None, + data=_data, + seed=seed, + output_dir=output_dir, + sig_figs=sig_figs, + save_profile=save_profile, + method_args=laplace_args, + refresh=refresh, + ) + dummy_chain_id = 0 + runset = RunSet(args=args, chains=1, time_fmt=time_fmt) + self._run_cmdstan( + runset, + dummy_chain_id, + show_console=show_console, + timeout=timeout, + ) + runset.raise_for_timeouts() + return CmdStanLaplace(runset, cmdstan_mode) + + def _run_cmdstan( + self, + runset: RunSet, + idx: int, + show_progress: bool = False, + show_console: bool = False, + progress_hook: Optional[Callable[[str, int], None]] = None, + timeout: Optional[float] = None, + ) -> None: + """ + Helper function which encapsulates call to CmdStan. + Uses subprocess POpen object to run the process. + Records stdout, stderr messages, and process returncode. + Args 'show_progress' and 'show_console' allow use of progress bar, + streaming output to console, respectively. + """ + get_logger().debug('idx %d', idx) + get_logger().debug( + 'running CmdStan, num_threads: %s', + str(os.environ.get('STAN_NUM_THREADS')), + ) + + logger_prefix = 'CmdStan' + console_prefix = '' + if runset.one_process_per_chain: + logger_prefix = 'Chain [{}]'.format(runset.chain_ids[idx]) + console_prefix = 'Chain [{}] '.format(runset.chain_ids[idx]) + + cmd = runset.cmd(idx) + get_logger().debug('CmdStan args: %s', cmd) + + if not show_progress: + get_logger().info('%s start processing', logger_prefix) + try: + fd_out = open(runset.stdout_files[idx], 'w') + proc = subprocess.Popen( + cmd, + bufsize=1, + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, # avoid buffer overflow + env=os.environ, + universal_newlines=True, + ) + timer: Optional[threading.Timer] + if timeout: + + def _timer_target() -> None: + # Abort if the process has already terminated. + if proc.poll() is not None: + return + proc.terminate() + runset._set_timeout_flag(idx, True) + + timer = threading.Timer(timeout, _timer_target) + timer.daemon = True + timer.start() + else: + timer = None + while proc.poll() is None: + if proc.stdout is not None: + line = proc.stdout.readline() + fd_out.write(line) + line = line.strip() + if show_console: + print(f'{console_prefix}{line}') + elif progress_hook is not None: + progress_hook(line, idx) + + stdout, _ = proc.communicate() + retcode = proc.returncode + runset._set_retcode(idx, retcode) + if timer: + timer.cancel() + + if stdout: + fd_out.write(stdout) + if show_console: + lines = stdout.split('\n') + for line in lines: + print(f'{console_prefix}{line}') + fd_out.close() + except OSError as e: + msg = 'Failed with error {}\n'.format(str(e)) + raise RuntimeError(msg) from e + finally: + fd_out.close() + + if not show_progress: + get_logger().info('%s done processing', logger_prefix) + + if retcode != 0: + retcode_summary = returncode_msg(retcode) + serror = '' + try: + serror = os.strerror(retcode) + except (ArithmeticError, ValueError): + pass + get_logger().error( + '%s error: %s %s', logger_prefix, retcode_summary, serror + ) + + @staticmethod + @progbar.wrap_callback + def _wrap_sampler_progress_hook( + chain_ids: List[int], + total: int, + ) -> Optional[Callable[[str, int], None]]: + """ + Sets up tqdm callback for CmdStan sampler console msgs. + CmdStan progress messages start with "Iteration", for single chain + process, "Chain [id] Iteration" for multi-chain processing. + For the latter, manage array of pbars, update accordingly. + """ + pat = re.compile(r'Chain \[(\d*)\] (Iteration.*)') + pbars: Dict[int, tqdm] = { + chain_id: tqdm( + total=total, + bar_format="{desc} |{bar}| {elapsed} {postfix[0][value]}", + postfix=[{"value": "Status"}], + desc=f'chain {chain_id}', + colour='yellow', + ) + for chain_id in chain_ids + } + + def progress_hook(line: str, idx: int) -> None: + if line == "Done": + for pbar in pbars.values(): + pbar.postfix[0]["value"] = 'Sampling completed' + pbar.update(total - pbar.n) + pbar.close() + else: + match = pat.match(line) + if match: + idx = int(match.group(1)) + mline = match.group(2).strip() + elif line.startswith("Iteration"): + mline = line + idx = chain_ids[idx] + else: + return + if 'Sampling' in mline: + pbars[idx].colour = 'blue' + pbars[idx].update(1) + pbars[idx].postfix[0]["value"] = mline + + return progress_hook diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/progress.py b/.venv/lib/python3.12/site-packages/cmdstanpy/progress.py new file mode 100644 index 00000000..0f26a88f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/progress.py @@ -0,0 +1,49 @@ +""" +Record tqdm progress bar fail during session +""" +import functools +import logging + +_SHOW_PROGRESS: bool = True + + +def allow_show_progress() -> bool: + """Return False if any progressbar errors have occurred this session""" + return _SHOW_PROGRESS + + +def _disable_progress(e: Exception) -> None: + """Print an exception and disable progress bars for this session""" + # pylint: disable=global-statement + global _SHOW_PROGRESS + if _SHOW_PROGRESS: + _SHOW_PROGRESS = False + logging.getLogger('cmdstanpy').error( + 'Error in progress bar initialization:\n' + '\t%s\n' + 'Disabling progress bars for this session', + str(e), + ) + + +def wrap_callback(func): # type: ignore + """Wrap a callback generator so it fails safely""" + + @functools.wraps(func) + def safe_progress(*args, **kwargs): # type: ignore + # pylint: disable=unused-argument + def callback(*args, **kwargs): # type: ignore + # totally empty callback + return None + + if not allow_show_progress(): + return callback + + try: + return func(*args, **kwargs) + # pylint: disable=broad-except + except Exception as e: + _disable_progress(e) + return callback + + return safe_progress diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/py.typed b/.venv/lib/python3.12/site-packages/cmdstanpy/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__init__.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__init__.py new file mode 100644 index 00000000..50764a30 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__init__.py @@ -0,0 +1,269 @@ +"""Container objects for results of CmdStan run(s).""" + +import glob +import os +from typing import Any, Dict, List, Optional, Union + +from cmdstanpy.cmdstan_args import ( + CmdStanArgs, + LaplaceArgs, + OptimizeArgs, + PathfinderArgs, + SamplerArgs, + VariationalArgs, +) +from cmdstanpy.utils import check_sampler_csv, get_logger, scan_config + +from .gq import CmdStanGQ +from .laplace import CmdStanLaplace +from .mcmc import CmdStanMCMC +from .metadata import InferenceMetadata +from .mle import CmdStanMLE +from .pathfinder import CmdStanPathfinder +from .runset import RunSet +from .vb import CmdStanVB + +__all__ = [ + "RunSet", + "InferenceMetadata", + "CmdStanMCMC", + "CmdStanMLE", + "CmdStanVB", + "CmdStanGQ", + "CmdStanLaplace", + "CmdStanPathfinder", +] + + +def from_csv( + path: Union[str, List[str], os.PathLike, None] = None, + method: Optional[str] = None, +) -> Union[ + CmdStanMCMC, CmdStanMLE, CmdStanVB, CmdStanPathfinder, CmdStanLaplace, None +]: + """ + Instantiate a CmdStan object from a the Stan CSV files from a CmdStan run. + CSV files are specified from either a list of Stan CSV files or a single + filepath which can be either a directory name, a Stan CSV filename, or + a pathname pattern (i.e., a Python glob). The optional argument 'method' + checks that the CSV files were produced by that method. + Stan CSV files from CmdStan methods 'sample', 'optimize', and 'variational' + result in objects of class CmdStanMCMC, CmdStanMLE, and CmdStanVB, + respectively. + + :param path: directory path + :param method: method name (optional) + + :return: either a CmdStanMCMC, CmdStanMLE, or CmdStanVB object + """ + if path is None: + raise ValueError('Must specify path to Stan CSV files.') + if method is not None and method not in [ + 'sample', + 'optimize', + 'variational', + 'laplace', + 'pathfinder', + ]: + raise ValueError( + 'Bad method argument {}, must be one of: ' + '"sample", "optimize", "variational"'.format(method) + ) + + csvfiles = [] + if isinstance(path, list): + csvfiles = path + elif isinstance(path, str) and '*' in path: + splits = os.path.split(path) + if splits[0] is not None: + if not (os.path.exists(splits[0]) and os.path.isdir(splits[0])): + raise ValueError( + 'Invalid path specification, {} ' + ' unknown directory: {}'.format(path, splits[0]) + ) + csvfiles = glob.glob(path) + elif isinstance(path, (str, os.PathLike)): + if os.path.exists(path) and os.path.isdir(path): + for file in os.listdir(path): + if os.path.splitext(file)[1] == ".csv": + csvfiles.append(os.path.join(path, file)) + elif os.path.exists(path): + csvfiles.append(str(path)) + else: + raise ValueError('Invalid path specification: {}'.format(path)) + else: + raise ValueError('Invalid path specification: {}'.format(path)) + + if len(csvfiles) == 0: + raise ValueError('No CSV files found in directory {}'.format(path)) + for file in csvfiles: + if not (os.path.exists(file) and os.path.splitext(file)[1] == ".csv"): + raise ValueError( + 'Bad CSV file path spec,' + ' includes non-csv file: {}'.format(file) + ) + + config_dict: Dict[str, Any] = {} + try: + with open(csvfiles[0], 'r') as fd: + scan_config(fd, config_dict, 0) + except (IOError, OSError, PermissionError) as e: + raise ValueError('Cannot read CSV file: {}'.format(csvfiles[0])) from e + if 'model' not in config_dict or 'method' not in config_dict: + raise ValueError("File {} is not a Stan CSV file.".format(csvfiles[0])) + if method is not None and method != config_dict['method']: + raise ValueError( + 'Expecting Stan CSV output files from method {}, ' + ' found outputs from method {}'.format( + method, config_dict['method'] + ) + ) + try: + if config_dict['method'] == 'sample': + chains = len(csvfiles) + sampler_args = SamplerArgs( + iter_sampling=config_dict['num_samples'], + iter_warmup=config_dict['num_warmup'], + thin=config_dict['thin'], + save_warmup=config_dict['save_warmup'], + ) + # bugfix 425, check for fixed_params output + try: + check_sampler_csv( + csvfiles[0], + iter_sampling=config_dict['num_samples'], + iter_warmup=config_dict['num_warmup'], + thin=config_dict['thin'], + save_warmup=config_dict['save_warmup'], + ) + except ValueError: + try: + check_sampler_csv( + csvfiles[0], + is_fixed_param=True, + iter_sampling=config_dict['num_samples'], + iter_warmup=config_dict['num_warmup'], + thin=config_dict['thin'], + save_warmup=config_dict['save_warmup'], + ) + sampler_args = SamplerArgs( + iter_sampling=config_dict['num_samples'], + iter_warmup=config_dict['num_warmup'], + thin=config_dict['thin'], + save_warmup=config_dict['save_warmup'], + fixed_param=True, + ) + except ValueError as e: + raise ValueError( + 'Invalid or corrupt Stan CSV output file, ' + ) from e + + cmdstan_args = CmdStanArgs( + model_name=config_dict['model'], + model_exe=config_dict['model'], + chain_ids=[x + 1 for x in range(chains)], + method_args=sampler_args, + ) + runset = RunSet(args=cmdstan_args, chains=chains) + runset._csv_files = csvfiles + for i in range(len(runset._retcodes)): + runset._set_retcode(i, 0) + fit = CmdStanMCMC(runset) + fit.draws() + return fit + elif config_dict['method'] == 'optimize': + if 'algorithm' not in config_dict: + raise ValueError( + "Cannot find optimization algorithm" + " in file {}.".format(csvfiles[0]) + ) + optimize_args = OptimizeArgs( + algorithm=config_dict['algorithm'], + save_iterations=config_dict['save_iterations'], + jacobian=config_dict.get('jacobian', 0), + ) + cmdstan_args = CmdStanArgs( + model_name=config_dict['model'], + model_exe=config_dict['model'], + chain_ids=None, + method_args=optimize_args, + ) + runset = RunSet(args=cmdstan_args) + runset._csv_files = csvfiles + for i in range(len(runset._retcodes)): + runset._set_retcode(i, 0) + return CmdStanMLE(runset) + elif config_dict['method'] == 'variational': + if 'algorithm' not in config_dict: + raise ValueError( + "Cannot find variational algorithm" + " in file {}.".format(csvfiles[0]) + ) + variational_args = VariationalArgs( + algorithm=config_dict['algorithm'], + iter=config_dict['iter'], + grad_samples=config_dict['grad_samples'], + elbo_samples=config_dict['elbo_samples'], + eta=config_dict['eta'], + tol_rel_obj=config_dict['tol_rel_obj'], + eval_elbo=config_dict['eval_elbo'], + output_samples=config_dict['output_samples'], + ) + cmdstan_args = CmdStanArgs( + model_name=config_dict['model'], + model_exe=config_dict['model'], + chain_ids=None, + method_args=variational_args, + ) + runset = RunSet(args=cmdstan_args) + runset._csv_files = csvfiles + for i in range(len(runset._retcodes)): + runset._set_retcode(i, 0) + return CmdStanVB(runset) + elif config_dict['method'] == 'laplace': + laplace_args = LaplaceArgs( + mode=config_dict['mode'], + draws=config_dict['draws'], + jacobian=config_dict['jacobian'], + ) + cmdstan_args = CmdStanArgs( + model_name=config_dict['model'], + model_exe=config_dict['model'], + chain_ids=None, + method_args=laplace_args, + ) + runset = RunSet(args=cmdstan_args) + runset._csv_files = csvfiles + for i in range(len(runset._retcodes)): + runset._set_retcode(i, 0) + mode: CmdStanMLE = from_csv( + config_dict['mode'], + method='optimize', + ) # type: ignore + return CmdStanLaplace(runset, mode=mode) + elif config_dict['method'] == 'pathfinder': + pathfinder_args = PathfinderArgs( + num_draws=config_dict['num_draws'], + num_paths=config_dict['num_paths'], + ) + cmdstan_args = CmdStanArgs( + model_name=config_dict['model'], + model_exe=config_dict['model'], + chain_ids=None, + method_args=pathfinder_args, + ) + runset = RunSet(args=cmdstan_args) + runset._csv_files = csvfiles + for i in range(len(runset._retcodes)): + runset._set_retcode(i, 0) + return CmdStanPathfinder(runset) + else: + get_logger().info( + 'Unable to process CSV output files from method %s.', + (config_dict['method']), + ) + return None + except (IOError, OSError, PermissionError) as e: + raise ValueError( + 'An error occurred processing the CSV files:\n\t{}'.format(str(e)) + ) from e diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..f0784027 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/gq.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/gq.cpython-312.pyc new file mode 100644 index 00000000..192a5640 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/gq.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/laplace.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/laplace.cpython-312.pyc new file mode 100644 index 00000000..bcc36999 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/laplace.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/mcmc.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/mcmc.cpython-312.pyc new file mode 100644 index 00000000..bae499e2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/mcmc.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/metadata.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/metadata.cpython-312.pyc new file mode 100644 index 00000000..bc38b752 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/metadata.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/mle.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/mle.cpython-312.pyc new file mode 100644 index 00000000..4f1ffb67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/mle.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/pathfinder.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/pathfinder.cpython-312.pyc new file mode 100644 index 00000000..f17b1958 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/pathfinder.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/runset.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/runset.cpython-312.pyc new file mode 100644 index 00000000..fac56a5c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/runset.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/vb.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/vb.cpython-312.pyc new file mode 100644 index 00000000..3d73a23c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/__pycache__/vb.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/gq.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/gq.py new file mode 100644 index 00000000..6c77ec95 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/gq.py @@ -0,0 +1,734 @@ +""" +Container for the result of running the +generate quantities (GQ) method +""" + +from collections import Counter +from typing import ( + Any, + Dict, + Generic, + Hashable, + List, + MutableMapping, + NoReturn, + Optional, + Tuple, + TypeVar, + Union, + overload, +) + +import numpy as np +import pandas as pd + +try: + import xarray as xr + + XARRAY_INSTALLED = True +except ImportError: + XARRAY_INSTALLED = False + + +from cmdstanpy.cmdstan_args import Method +from cmdstanpy.utils import build_xarray_data, flatten_chains, get_logger +from cmdstanpy.utils.stancsv import scan_generic_csv + +from .mcmc import CmdStanMCMC +from .metadata import InferenceMetadata +from .mle import CmdStanMLE +from .runset import RunSet +from .vb import CmdStanVB + +Fit = TypeVar('Fit', CmdStanMCMC, CmdStanMLE, CmdStanVB) + + +class CmdStanGQ(Generic[Fit]): + """ + Container for outputs from CmdStan generate_quantities run. + Created by :meth:`CmdStanModel.generate_quantities`. + """ + + def __init__( + self, + runset: RunSet, + previous_fit: Fit, + ) -> None: + """Initialize object.""" + if not runset.method == Method.GENERATE_QUANTITIES: + raise ValueError( + 'Wrong runset method, expecting generate_quantities runset, ' + 'found method {}'.format(runset.method) + ) + self.runset = runset + + self.previous_fit: Fit = previous_fit + + self._draws: np.ndarray = np.array(()) + config = self._validate_csv_files() + self._metadata = InferenceMetadata(config) + + def __repr__(self) -> str: + repr = 'CmdStanGQ: model={} chains={}{}'.format( + self.runset.model, + self.chains, + self.runset._args.method_args.compose(0, cmd=[]), + ) + repr = '{}\n csv_files:\n\t{}\n output_files:\n\t{}'.format( + repr, + '\n\t'.join(self.runset.csv_files), + '\n\t'.join(self.runset.stdout_files), + ) + return repr + + def __getattr__(self, attr: str) -> np.ndarray: + """Synonymous with ``fit.stan_variable(attr)""" + if attr.startswith("_"): + raise AttributeError(f"Unknown variable name {attr}") + try: + return self.stan_variable(attr) + except ValueError as e: + # pylint: disable=raise-missing-from + raise AttributeError(*e.args) + + def __getstate__(self) -> dict: + # This function returns the mapping of objects to serialize with pickle. + # See https://docs.python.org/3/library/pickle.html#object.__getstate__ + # for details. We call _assemble_generated_quantities to ensure + # the data are loaded prior to serialization. + self._assemble_generated_quantities() + return self.__dict__ + + def _validate_csv_files(self) -> Dict[str, Any]: + """ + Checks that Stan CSV output files for all chains are consistent + and returns dict containing config and column names. + + Raises exception when inconsistencies detected. + """ + dzero = {} + for i in range(self.chains): + if i == 0: + dzero = scan_generic_csv( + path=self.runset.csv_files[i], + ) + else: + drest = scan_generic_csv( + path=self.runset.csv_files[i], + ) + for key in dzero: + if ( + key + not in [ + 'id', + 'fitted_params', + 'diagnostic_file', + 'metric_file', + 'profile_file', + 'init', + 'seed', + 'start_datetime', + ] + and dzero[key] != drest[key] + ): + raise ValueError( + 'CmdStan config mismatch in Stan CSV file {}: ' + 'arg {} is {}, expected {}'.format( + self.runset.csv_files[i], + key, + dzero[key], + drest[key], + ) + ) + return dzero + + @property + def chains(self) -> int: + """Number of chains.""" + return self.runset.chains + + @property + def chain_ids(self) -> List[int]: + """Chain ids.""" + return self.runset.chain_ids + + @property + def column_names(self) -> Tuple[str, ...]: + """ + Names of generated quantities of interest. + """ + return self._metadata.cmdstan_config['column_names'] # type: ignore + + @property + def metadata(self) -> InferenceMetadata: + """ + Returns object which contains CmdStan configuration as well as + information about the names and structure of the inference method + and model output variables. + """ + return self._metadata + + def draws( + self, + *, + inc_warmup: bool = False, + inc_iterations: bool = False, + concat_chains: bool = False, + inc_sample: bool = False, + ) -> np.ndarray: + """ + Returns a numpy.ndarray over the generated quantities draws from + all chains which is stored column major so that the values + for a parameter are contiguous in memory, likewise all draws from + a chain are contiguous. By default, returns a 3D array arranged + (draws, chains, columns); parameter ``concat_chains=True`` will + return a 2D array where all chains are flattened into a single column, + preserving chain order, so that given M chains of N draws, + the first N draws are from chain 1, ..., and the the last N draws + are from chain M. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + :param concat_chains: When ``True`` return a 2D array flattening all + all draws from all chains. Default value is ``False``. + + :param inc_sample: When ``True`` include all columns in the previous_fit + draws array as well, excepting columns for variables already present + in the generated quantities drawset. Default value is ``False``. + + See Also + -------- + CmdStanGQ.draws_pd + CmdStanGQ.draws_xr + CmdStanMCMC.draws + """ + self._assemble_generated_quantities() + inc_warmup |= inc_iterations + if inc_warmup: + if ( + isinstance(self.previous_fit, CmdStanMCMC) + and not self.previous_fit._save_warmup + ): + get_logger().warning( + "Sample doesn't contain draws from warmup iterations," + ' rerun sampler with "save_warmup=True".' + ) + elif ( + isinstance(self.previous_fit, CmdStanMLE) + and not self.previous_fit._save_iterations + ): + get_logger().warning( + "MLE doesn't contain draws from pre-convergence iterations," + ' rerun optimization with "save_iterations=True".' + ) + elif isinstance(self.previous_fit, CmdStanVB): + get_logger().warning( + "Variational fit doesn't make sense with argument " + '"inc_warmup=True"' + ) + + if inc_sample: + cols_1 = self.previous_fit.column_names + cols_2 = self.column_names + dups = [ + item + for item, count in Counter(cols_1 + cols_2).items() + if count > 1 + ] + drop_cols: List[int] = [] + for dup in dups: + drop_cols.extend( + self.previous_fit._metadata.stan_vars[dup].columns() + ) + + start_idx, _ = self._draws_start(inc_warmup) + previous_draws = self._previous_draws(True) + if concat_chains and inc_sample: + return flatten_chains( + np.dstack( + ( + np.delete(previous_draws, drop_cols, axis=1), + self._draws, + ) + )[start_idx:, :, :] + ) + if concat_chains: + return flatten_chains(self._draws[start_idx:, :, :]) + if inc_sample: + return np.dstack( + ( + np.delete(previous_draws, drop_cols, axis=1), + self._draws, + ) + )[start_idx:, :, :] + return self._draws[start_idx:, :, :] + + def draws_pd( + self, + vars: Union[List[str], str, None] = None, + inc_warmup: bool = False, + inc_sample: bool = False, + ) -> pd.DataFrame: + """ + Returns the generated quantities draws as a pandas DataFrame. + Flattens all chains into single column. Container variables + (array, vector, matrix) will span multiple columns, one column + per element. E.g. variable 'matrix[2,2] foo' spans 4 columns: + 'foo[1,1], ... foo[2,2]'. + + :param vars: optional list of variable names. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + See Also + -------- + CmdStanGQ.draws + CmdStanGQ.draws_xr + CmdStanMCMC.draws_pd + """ + if vars is not None: + if isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + + vars_list = list(dict.fromkeys(vars_list)) + + if inc_warmup: + if ( + isinstance(self.previous_fit, CmdStanMCMC) + and not self.previous_fit._save_warmup + ): + get_logger().warning( + "Sample doesn't contain draws from warmup iterations," + ' rerun sampler with "save_warmup=True".' + ) + elif ( + isinstance(self.previous_fit, CmdStanMLE) + and not self.previous_fit._save_iterations + ): + get_logger().warning( + "MLE doesn't contain draws from pre-convergence iterations," + ' rerun optimization with "save_iterations=True".' + ) + elif isinstance(self.previous_fit, CmdStanVB): + get_logger().warning( + "Variational fit doesn't make sense with argument " + '"inc_warmup=True"' + ) + + self._assemble_generated_quantities() + + all_columns = ['chain__', 'iter__', 'draw__'] + list(self.column_names) + + gq_cols: List[str] = [] + mcmc_vars: List[str] = [] + if vars is not None: + for var in vars_list: + if var in self._metadata.stan_vars: + info = self._metadata.stan_vars[var] + gq_cols.extend( + self.column_names[info.start_idx : info.end_idx] + ) + elif ( + inc_sample and var in self.previous_fit._metadata.stan_vars + ): + info = self.previous_fit._metadata.stan_vars[var] + mcmc_vars.extend( + self.previous_fit.column_names[ + info.start_idx : info.end_idx + ] + ) + elif var in ['chain__', 'iter__', 'draw__']: + gq_cols.append(var) + else: + raise ValueError('Unknown variable: {}'.format(var)) + else: + gq_cols = all_columns + vars_list = gq_cols + + previous_draws_pd = self._previous_draws_pd(mcmc_vars, inc_warmup) + + draws = self.draws(inc_warmup=inc_warmup) + # add long-form columns for chain, iteration, draw + n_draws, n_chains, _ = draws.shape + chains_col = ( + np.repeat(np.arange(1, n_chains + 1), n_draws) + .reshape(1, n_chains, n_draws) + .T + ) + iter_col = ( + np.tile(np.arange(1, n_draws + 1), n_chains) + .reshape(1, n_chains, n_draws) + .T + ) + draw_col = ( + np.arange(1, (n_draws * n_chains) + 1) + .reshape(1, n_chains, n_draws) + .T + ) + draws = np.concatenate([chains_col, iter_col, draw_col, draws], axis=2) + + draws_pd = pd.DataFrame( + data=flatten_chains(draws), + columns=all_columns, + ) + + if inc_sample and mcmc_vars: + if gq_cols: + return pd.concat( + [ + previous_draws_pd, + draws_pd[gq_cols], + ], + axis='columns', + )[vars_list] + else: + return previous_draws_pd + elif inc_sample and vars is None: + cols_1 = list(previous_draws_pd.columns) + cols_2 = list(draws_pd.columns) + dups = [ + item + for item, count in Counter(cols_1 + cols_2).items() + if count > 1 + ] + return pd.concat( + [ + previous_draws_pd.drop(columns=dups).reset_index(drop=True), + draws_pd, + ], + axis=1, + ) + elif gq_cols: + return draws_pd[gq_cols] + + return draws_pd + + @overload + def draws_xr( + self: Union["CmdStanGQ[CmdStanMLE]", "CmdStanGQ[CmdStanVB]"], + vars: Union[str, List[str], None] = None, + inc_warmup: bool = False, + inc_sample: bool = False, + ) -> NoReturn: + ... + + @overload + def draws_xr( + self: "CmdStanGQ[CmdStanMCMC]", + vars: Union[str, List[str], None] = None, + inc_warmup: bool = False, + inc_sample: bool = False, + ) -> "xr.Dataset": + ... + + def draws_xr( + self, + vars: Union[str, List[str], None] = None, + inc_warmup: bool = False, + inc_sample: bool = False, + ) -> "xr.Dataset": + """ + Returns the generated quantities draws as a xarray Dataset. + + This method can only be called when the underlying fit was made + through sampling, it cannot be used on MLE or VB outputs. + + :param vars: optional list of variable names. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the MCMC sample, then the warmup draws are included. + Default value is ``False``. + + See Also + -------- + CmdStanGQ.draws + CmdStanGQ.draws_pd + CmdStanMCMC.draws_xr + """ + if not XARRAY_INSTALLED: + raise RuntimeError( + 'Package "xarray" is not installed, cannot produce draws array.' + ) + if not isinstance(self.previous_fit, CmdStanMCMC): + raise RuntimeError( + 'Method "draws_xr" is only available when ' + 'original fit is done via Sampling.' + ) + mcmc_vars_list = [] + dup_vars = [] + if vars is not None: + if isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + for var in vars_list: + if var not in self._metadata.stan_vars: + if inc_sample and ( + var in self.previous_fit._metadata.stan_vars + ): + mcmc_vars_list.append(var) + dup_vars.append(var) + else: + raise ValueError('Unknown variable: {}'.format(var)) + else: + vars_list = list(self._metadata.stan_vars.keys()) + if inc_sample: + for var in self.previous_fit._metadata.stan_vars.keys(): + if var not in vars_list and var not in mcmc_vars_list: + mcmc_vars_list.append(var) + for var in dup_vars: + vars_list.remove(var) + + self._assemble_generated_quantities() + + num_draws = self.previous_fit.num_draws_sampling + sample_config = self.previous_fit._metadata.cmdstan_config + attrs: MutableMapping[Hashable, Any] = { + "stan_version": f"{sample_config['stan_version_major']}." + f"{sample_config['stan_version_minor']}." + f"{sample_config['stan_version_patch']}", + "model": sample_config["model"], + "num_draws_sampling": num_draws, + } + if inc_warmup and sample_config['save_warmup']: + num_draws += self.previous_fit.num_draws_warmup + attrs["num_draws_warmup"] = self.previous_fit.num_draws_warmup + + data: MutableMapping[Hashable, Any] = {} + coordinates: MutableMapping[Hashable, Any] = { + "chain": self.chain_ids, + "draw": np.arange(num_draws), + } + + for var in vars_list: + build_xarray_data( + data, + self._metadata.stan_vars[var], + self.draws(inc_warmup=inc_warmup), + ) + if inc_sample: + for var in mcmc_vars_list: + build_xarray_data( + data, + self.previous_fit._metadata.stan_vars[var], + self.previous_fit.draws(inc_warmup=inc_warmup), + ) + + return xr.Dataset(data, coords=coordinates, attrs=attrs).transpose( + 'chain', 'draw', ... + ) + + def stan_variable(self, var: str, **kwargs: bool) -> np.ndarray: + """ + Return a numpy.ndarray which contains the set of draws + for the named Stan program variable. Flattens the chains, + leaving the draws in chain order. The first array dimension, + corresponds to number of draws in the sample. + The remaining dimensions correspond to + the shape of the Stan program variable. + + Underlyingly draws are in chain order, i.e., for a sample with + N chains of M draws each, the first M array elements are from chain 1, + the next M are from chain 2, and the last M elements are from chain N. + + * If the variable is a scalar variable, the return array has shape + ( draws * chains, 1). + * If the variable is a vector, the return array has shape + ( draws * chains, len(vector)) + * If the variable is a matrix, the return array has shape + ( draws * chains, size(dim 1), size(dim 2) ) + * If the variable is an array with N dimensions, the return array + has shape ( draws * chains, size(dim 1), ..., size(dim N)) + + For example, if the Stan program variable ``theta`` is a 3x3 matrix, + and the sample consists of 4 chains with 1000 post-warmup draws, + this function will return a numpy.ndarray with shape (4000,3,3). + + This functionaltiy is also available via a shortcut using ``.`` - + writing ``fit.a`` is a synonym for ``fit.stan_variable("a")`` + + :param var: variable name + + :param kwargs: Additional keyword arguments are passed to the underlying + fit's ``stan_variable`` method if the variable is not a generated + quantity. + + See Also + -------- + CmdStanGQ.stan_variables + CmdStanMCMC.stan_variable + CmdStanMLE.stan_variable + CmdStanPathfinder.stan_variable + CmdStanVB.stan_variable + CmdStanLaplace.stan_variable + """ + model_var_names = self.previous_fit._metadata.stan_vars.keys() + gq_var_names = self._metadata.stan_vars.keys() + if not (var in model_var_names or var in gq_var_names): + raise ValueError( + f'Unknown variable name: {var}\n' + 'Available variables are ' + + ", ".join(model_var_names | gq_var_names) + ) + if var not in gq_var_names: + # TODO(2.0) atleast1d may not be needed + return np.atleast_1d( # type: ignore + self.previous_fit.stan_variable(var, **kwargs) + ) + + # is gq variable + self._assemble_generated_quantities() + + draw1, _ = self._draws_start( + inc_warmup=kwargs.get('inc_warmup', False) + or kwargs.get('inc_iterations', False) + ) + draws = flatten_chains(self._draws[draw1:]) + out: np.ndarray = self._metadata.stan_vars[var].extract_reshape(draws) + return out + + def stan_variables(self, **kwargs: bool) -> Dict[str, np.ndarray]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + :param kwargs: Additional keyword arguments are passed to the underlying + fit's ``stan_variable`` method if the variable is not a generated + quantity. + + See Also + -------- + CmdStanGQ.stan_variable + CmdStanMCMC.stan_variables + CmdStanMLE.stan_variables + CmdStanPathfinder.stan_variables + CmdStanVB.stan_variables + CmdStanLaplace.stan_variables + """ + result = {} + sample_var_names = self.previous_fit._metadata.stan_vars.keys() + gq_var_names = self._metadata.stan_vars.keys() + for name in gq_var_names: + result[name] = self.stan_variable(name, **kwargs) + for name in sample_var_names: + if name not in gq_var_names: + result[name] = self.stan_variable(name, **kwargs) + return result + + def _assemble_generated_quantities(self) -> None: + if self._draws.shape != (0,): + return + # use numpy loadtxt + _, num_draws = self._draws_start(inc_warmup=True) + + gq_sample: np.ndarray = np.empty( + (num_draws, self.chains, len(self.column_names)), + dtype=float, + order='F', + ) + for chain in range(self.chains): + with open(self.runset.csv_files[chain], 'r') as fd: + lines = (line for line in fd if not line.startswith('#')) + gq_sample[:, chain, :] = np.loadtxt( + lines, dtype=np.ndarray, ndmin=2, skiprows=1, delimiter=',' + ) + self._draws = gq_sample + + def _draws_start(self, inc_warmup: bool) -> Tuple[int, int]: + draw1 = 0 + p_fit = self.previous_fit + if isinstance(p_fit, CmdStanMCMC): + num_draws = p_fit.num_draws_sampling + if p_fit._save_warmup: + if inc_warmup: + num_draws += p_fit.num_draws_warmup + else: + draw1 = p_fit.num_draws_warmup + + elif isinstance(p_fit, CmdStanMLE): + num_draws = 1 + if p_fit._save_iterations: + opt_iters = len(p_fit.optimized_iterations_np) # type: ignore + if inc_warmup: + num_draws = opt_iters + else: + draw1 = opt_iters - 1 + else: # CmdStanVB: + draw1 = 1 # skip mean + num_draws = p_fit.variational_sample.shape[0] + if inc_warmup: + num_draws += 1 + + return draw1, num_draws + + def _previous_draws(self, inc_warmup: bool) -> np.ndarray: + """ + Extract the draws from self.previous_fit. + Return is always 3-d + """ + p_fit = self.previous_fit + if isinstance(p_fit, CmdStanMCMC): + return p_fit.draws(inc_warmup=inc_warmup) + elif isinstance(p_fit, CmdStanMLE): + if inc_warmup and p_fit._save_iterations: + return p_fit.optimized_iterations_np[:, None] # type: ignore + + return np.atleast_2d( # type: ignore + p_fit.optimized_params_np, + )[:, None] + else: # CmdStanVB: + if inc_warmup: + return np.vstack( + [p_fit.variational_params_np, p_fit.variational_sample] + )[:, None] + return p_fit.variational_sample[:, None] + + def _previous_draws_pd( + self, vars: List[str], inc_warmup: bool + ) -> pd.DataFrame: + if vars: + sel: Union[List[str], slice] = vars + else: + sel = slice(None, None) + + p_fit = self.previous_fit + if isinstance(p_fit, CmdStanMCMC): + return p_fit.draws_pd(vars or None, inc_warmup=inc_warmup) + + elif isinstance(p_fit, CmdStanMLE): + if inc_warmup and p_fit._save_iterations: + return p_fit.optimized_iterations_pd[sel] # type: ignore + else: + return p_fit.optimized_params_pd[sel] + else: # CmdStanVB: + return p_fit.variational_sample_pd[sel] + + def save_csvfiles(self, dir: Optional[str] = None) -> None: + """ + Move output CSV files to specified directory. If files were + written to the temporary session directory, clean filename. + E.g., save 'bernoulli-201912081451-1-5nm6as7u.csv' as + 'bernoulli-201912081451-1.csv'. + + :param dir: directory path + + See Also + -------- + stanfit.RunSet.save_csvfiles + cmdstanpy.from_csv + """ + self.runset.save_csvfiles(dir) + + # TODO(2.0): remove + @property + def mcmc_sample(self) -> Union[CmdStanMCMC, CmdStanMLE, CmdStanVB]: + get_logger().warning( + "Property `mcmc_sample` is deprecated, use `previous_fit` instead" + ) + return self.previous_fit diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/laplace.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/laplace.py new file mode 100644 index 00000000..741593e7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/laplace.py @@ -0,0 +1,304 @@ +""" + Container for the result of running a laplace approximation. +""" + +from typing import ( + Any, + Dict, + Hashable, + List, + MutableMapping, + Optional, + Tuple, + Union, +) + +import numpy as np +import pandas as pd + +try: + import xarray as xr + + XARRAY_INSTALLED = True +except ImportError: + XARRAY_INSTALLED = False + +from cmdstanpy.cmdstan_args import Method +from cmdstanpy.utils.data_munging import build_xarray_data +from cmdstanpy.utils.stancsv import scan_generic_csv + +from .metadata import InferenceMetadata +from .mle import CmdStanMLE +from .runset import RunSet + +# TODO list: +# - docs and example notebook +# - make sure features like standalone GQ are updated/working + + +class CmdStanLaplace: + def __init__(self, runset: RunSet, mode: CmdStanMLE) -> None: + """Initialize object.""" + if not runset.method == Method.LAPLACE: + raise ValueError( + 'Wrong runset method, expecting laplace runset, ' + 'found method {}'.format(runset.method) + ) + self._runset = runset + self._mode = mode + + self._draws: np.ndarray = np.array(()) + + config = scan_generic_csv(runset.csv_files[0]) + self._metadata = InferenceMetadata(config) + + def _assemble_draws(self) -> None: + if self._draws.shape != (0,): + return + + with open(self._runset.csv_files[0], 'r') as fd: + while (fd.readline()).startswith("#"): + pass + self._draws = np.loadtxt( + fd, + dtype=float, + ndmin=2, + delimiter=',', + comments="#", + ) + + def stan_variable(self, var: str) -> np.ndarray: + """ + Return a numpy.ndarray which contains the estimates for the + for the named Stan program variable where the dimensions of the + numpy.ndarray match the shape of the Stan program variable. + + This functionaltiy is also available via a shortcut using ``.`` - + writing ``fit.a`` is a synonym for ``fit.stan_variable("a")`` + + :param var: variable name + + See Also + -------- + CmdStanMLE.stan_variables + CmdStanMCMC.stan_variable + CmdStanPathfinder.stan_variable + CmdStanVB.stan_variable + CmdStanGQ.stan_variable + """ + self._assemble_draws() + try: + out: np.ndarray = self._metadata.stan_vars[var].extract_reshape( + self._draws + ) + return out + except KeyError: + # pylint: disable=raise-missing-from + raise ValueError( + f'Unknown variable name: {var}\n' + 'Available variables are ' + + ", ".join(self._metadata.stan_vars.keys()) + ) + + def stan_variables(self) -> Dict[str, np.ndarray]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the MCMC sample, then the warmup draws are included. + Default value is ``False`` + + See Also + -------- + CmdStanGQ.stan_variable + CmdStanMCMC.stan_variables + CmdStanMLE.stan_variables + CmdStanPathfinder.stan_variables + CmdStanVB.stan_variables + """ + result = {} + for name in self._metadata.stan_vars: + result[name] = self.stan_variable(name) + return result + + def method_variables(self) -> Dict[str, np.ndarray]: + """ + Returns a dictionary of all sampler variables, i.e., all + output column names ending in `__`. Assumes that all variables + are scalar variables where column name is variable name. + Maps each column name to a numpy.ndarray (draws x chains x 1) + containing per-draw diagnostic values. + """ + self._assemble_draws() + return { + name: var.extract_reshape(self._draws) + for name, var in self._metadata.method_vars.items() + } + + def draws(self) -> np.ndarray: + """ + Return a numpy.ndarray containing the draws from the + approximate posterior distribution. This is a 2-D array + of shape (draws, parameters). + """ + self._assemble_draws() + return self._draws + + def draws_pd( + self, + vars: Union[List[str], str, None] = None, + ) -> pd.DataFrame: + if vars is not None: + if isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + + self._assemble_draws() + cols = [] + if vars is not None: + for var in dict.fromkeys(vars_list): + if var in self._metadata.method_vars: + cols.append(var) + elif var in self._metadata.stan_vars: + info = self._metadata.stan_vars[var] + cols.extend( + self.column_names[info.start_idx : info.end_idx] + ) + else: + raise ValueError(f'Unknown variable: {var}') + + else: + cols = list(self.column_names) + + return pd.DataFrame(self._draws, columns=self.column_names)[cols] + + def draws_xr( + self, + vars: Union[str, List[str], None] = None, + ) -> "xr.Dataset": + """ + Returns the sampler draws as a xarray Dataset. + + :param vars: optional list of variable names. + + See Also + -------- + CmdStanMCMC.draws_xr + CmdStanGQ.draws_xr + """ + if not XARRAY_INSTALLED: + raise RuntimeError( + 'Package "xarray" is not installed, cannot produce draws array.' + ) + + if vars is None: + vars_list = list(self._metadata.stan_vars.keys()) + elif isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + + self._assemble_draws() + + meta = self._metadata.cmdstan_config + attrs: MutableMapping[Hashable, Any] = { + "stan_version": f"{meta['stan_version_major']}." + f"{meta['stan_version_minor']}.{meta['stan_version_patch']}", + "model": meta["model"], + } + + data: MutableMapping[Hashable, Any] = {} + coordinates: MutableMapping[Hashable, Any] = { + "draw": np.arange(self._draws.shape[0]), + } + + for var in vars_list: + build_xarray_data( + data, + self._metadata.stan_vars[var], + self._draws[:, np.newaxis, :], + ) + return ( + xr.Dataset(data, coords=coordinates, attrs=attrs) + .transpose('draw', ...) + .squeeze() + ) + + @property + def mode(self) -> CmdStanMLE: + """ + Return the maximum a posteriori estimate (mode) + as a :class:`CmdStanMLE` object. + """ + return self._mode + + @property + def metadata(self) -> InferenceMetadata: + """ + Returns object which contains CmdStan configuration as well as + information about the names and structure of the inference method + and model output variables. + """ + return self._metadata + + def __repr__(self) -> str: + mode = '\n'.join( + ['\t' + line for line in repr(self.mode).splitlines()] + )[1:] + rep = 'CmdStanLaplace: model={} \nmode=({})\n{}'.format( + self._runset.model, + mode, + self._runset._args.method_args.compose(0, cmd=[]), + ) + rep = '{}\n csv_files:\n\t{}\n output_files:\n\t{}'.format( + rep, + '\n\t'.join(self._runset.csv_files), + '\n\t'.join(self._runset.stdout_files), + ) + return rep + + def __getattr__(self, attr: str) -> np.ndarray: + """Synonymous with ``fit.stan_variable(attr)""" + if attr.startswith("_"): + raise AttributeError(f"Unknown variable name {attr}") + try: + return self.stan_variable(attr) + except ValueError as e: + # pylint: disable=raise-missing-from + raise AttributeError(*e.args) + + def __getstate__(self) -> dict: + # This function returns the mapping of objects to serialize with pickle. + # See https://docs.python.org/3/library/pickle.html#object.__getstate__ + # for details. We call _assemble_draws to ensure posterior samples have + # been loaded prior to serialization. + self._assemble_draws() + return self.__dict__ + + @property + def column_names(self) -> Tuple[str, ...]: + """ + Names of all outputs from the sampler, comprising sampler parameters + and all components of all model parameters, transformed parameters, + and quantities of interest. Corresponds to Stan CSV file header row, + with names munged to array notation, e.g. `beta[1]` not `beta.1`. + """ + return self._metadata.cmdstan_config['column_names'] # type: ignore + + def save_csvfiles(self, dir: Optional[str] = None) -> None: + """ + Move output CSV files to specified directory. If files were + written to the temporary session directory, clean filename. + E.g., save 'bernoulli-201912081451-1-5nm6as7u.csv' as + 'bernoulli-201912081451-1.csv'. + + :param dir: directory path + + See Also + -------- + stanfit.RunSet.save_csvfiles + cmdstanpy.from_csv + """ + self._runset.save_csvfiles(dir) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/mcmc.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/mcmc.py new file mode 100644 index 00000000..8c93c8e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/mcmc.py @@ -0,0 +1,826 @@ +""" +Container for the result of running the sample (MCMC) method +""" + +import math +import os +from io import StringIO +from typing import ( + Any, + Dict, + Hashable, + List, + MutableMapping, + Optional, + Sequence, + Tuple, + Union, +) + +import numpy as np +import pandas as pd + +try: + import xarray as xr + + XARRAY_INSTALLED = True +except ImportError: + XARRAY_INSTALLED = False + +from cmdstanpy import _CMDSTAN_SAMPLING, _CMDSTAN_THIN, _CMDSTAN_WARMUP, _TMPDIR +from cmdstanpy.cmdstan_args import Method, SamplerArgs +from cmdstanpy.utils import ( + EXTENSION, + build_xarray_data, + check_sampler_csv, + cmdstan_path, + cmdstan_version_before, + create_named_text_file, + do_command, + flatten_chains, + get_logger, +) + +from .metadata import InferenceMetadata +from .runset import RunSet + + +class CmdStanMCMC: + """ + Container for outputs from CmdStan sampler run. + Provides methods to summarize and diagnose the model fit + and accessor methods to access the entire sample or + individual items. Created by :meth:`CmdStanModel.sample` + + The sample is lazily instantiated on first access of either + the resulting sample or the HMC tuning parameters, i.e., the + step size and metric. + """ + + # pylint: disable=too-many-public-methods + def __init__( + self, + runset: RunSet, + ) -> None: + """Initialize object.""" + if not runset.method == Method.SAMPLE: + raise ValueError( + 'Wrong runset method, expecting sample runset, ' + 'found method {}'.format(runset.method) + ) + self.runset = runset + + # info from runset to be exposed + sampler_args = self.runset._args.method_args + assert isinstance( + sampler_args, SamplerArgs + ) # make the typechecker happy + self._iter_sampling: int = _CMDSTAN_SAMPLING + if sampler_args.iter_sampling is not None: + self._iter_sampling = sampler_args.iter_sampling + self._iter_warmup: int = _CMDSTAN_WARMUP + if sampler_args.iter_warmup is not None: + self._iter_warmup = sampler_args.iter_warmup + self._thin: int = _CMDSTAN_THIN + if sampler_args.thin is not None: + self._thin = sampler_args.thin + self._is_fixed_param = sampler_args.fixed_param + self._save_warmup: bool = sampler_args.save_warmup + self._sig_figs = runset._args.sig_figs + + # info from CSV values, instantiated lazily + self._draws: np.ndarray = np.array(()) + # only valid when not is_fixed_param + self._metric: np.ndarray = np.array(()) + self._step_size: np.ndarray = np.array(()) + self._divergences: np.ndarray = np.zeros(self.runset.chains, dtype=int) + self._max_treedepths: np.ndarray = np.zeros( + self.runset.chains, dtype=int + ) + + # info from CSV initial comments and header + config = self._validate_csv_files() + self._metadata: InferenceMetadata = InferenceMetadata(config) + if not self._is_fixed_param: + self._check_sampler_diagnostics() + + def __repr__(self) -> str: + repr = 'CmdStanMCMC: model={} chains={}{}'.format( + self.runset.model, + self.runset.chains, + self.runset._args.method_args.compose(0, cmd=[]), + ) + repr = '{}\n csv_files:\n\t{}\n output_files:\n\t{}'.format( + repr, + '\n\t'.join(self.runset.csv_files), + '\n\t'.join(self.runset.stdout_files), + ) + # TODO - hamiltonian, profiling files + return repr + + def __getattr__(self, attr: str) -> np.ndarray: + """Synonymous with ``fit.stan_variable(attr)""" + if attr.startswith("_"): + raise AttributeError(f"Unknown variable name {attr}") + try: + return self.stan_variable(attr) + except ValueError as e: + # pylint: disable=raise-missing-from + raise AttributeError(*e.args) + + def __getstate__(self) -> dict: + # This function returns the mapping of objects to serialize with pickle. + # See https://docs.python.org/3/library/pickle.html#object.__getstate__ + # for details. We call _assemble_draws to ensure posterior samples have + # been loaded prior to serialization. + self._assemble_draws() + return self.__dict__ + + @property + def chains(self) -> int: + """Number of chains.""" + return self.runset.chains + + @property + def chain_ids(self) -> List[int]: + """Chain ids.""" + return self.runset.chain_ids + + @property + def num_draws_warmup(self) -> int: + """Number of warmup draws per chain, i.e., thinned warmup iterations.""" + return int(math.ceil((self._iter_warmup) / self._thin)) + + @property + def num_draws_sampling(self) -> int: + """ + Number of sampling (post-warmup) draws per chain, i.e., + thinned sampling iterations. + """ + return int(math.ceil((self._iter_sampling) / self._thin)) + + @property + def metadata(self) -> InferenceMetadata: + """ + Returns object which contains CmdStan configuration as well as + information about the names and structure of the inference method + and model output variables. + """ + return self._metadata + + @property + def column_names(self) -> Tuple[str, ...]: + """ + Names of all outputs from the sampler, comprising sampler parameters + and all components of all model parameters, transformed parameters, + and quantities of interest. Corresponds to Stan CSV file header row, + with names munged to array notation, e.g. `beta[1]` not `beta.1`. + """ + return self._metadata.cmdstan_config['column_names'] # type: ignore + + @property + def metric_type(self) -> Optional[str]: + """ + Metric type used for adaptation, either 'diag_e' or 'dense_e', according + to CmdStan arg 'metric'. + When sampler algorithm 'fixed_param' is specified, metric_type is None. + """ + return ( + self._metadata.cmdstan_config['metric'] + if not self._is_fixed_param + else None + ) + + @property + def metric(self) -> Optional[np.ndarray]: + """ + Metric used by sampler for each chain. + When sampler algorithm 'fixed_param' is specified, metric is None. + """ + if self._is_fixed_param: + return None + if self._metadata.cmdstan_config['metric'] == 'unit_e': + get_logger().info( + 'Unit diagnonal metric, inverse mass matrix size unknown.' + ) + return None + self._assemble_draws() + return self._metric + + @property + def step_size(self) -> Optional[np.ndarray]: + """ + Step size used by sampler for each chain. + When sampler algorithm 'fixed_param' is specified, step size is None. + """ + self._assemble_draws() + return self._step_size if not self._is_fixed_param else None + + @property + def thin(self) -> int: + """ + Period between recorded iterations. (Default is 1). + """ + return self._thin + + @property + def divergences(self) -> Optional[np.ndarray]: + """ + Per-chain total number of post-warmup divergent iterations. + When sampler algorithm 'fixed_param' is specified, returns None. + """ + return self._divergences if not self._is_fixed_param else None + + @property + def max_treedepths(self) -> Optional[np.ndarray]: + """ + Per-chain total number of post-warmup iterations where the NUTS sampler + reached the maximum allowed treedepth. + When sampler algorithm 'fixed_param' is specified, returns None. + """ + return self._max_treedepths if not self._is_fixed_param else None + + def draws( + self, *, inc_warmup: bool = False, concat_chains: bool = False + ) -> np.ndarray: + """ + Returns a numpy.ndarray over all draws from all chains which is + stored column major so that the values for a parameter are contiguous + in memory, likewise all draws from a chain are contiguous. + By default, returns a 3D array arranged (draws, chains, columns); + parameter ``concat_chains=True`` will return a 2D array where all + chains are flattened into a single column, preserving chain order, + so that given M chains of N draws, the first N draws are from chain 1, + up through the last N draws from chain M. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + :param concat_chains: When ``True`` return a 2D array flattening all + all draws from all chains. Default value is ``False``. + + See Also + -------- + CmdStanMCMC.draws_pd + CmdStanMCMC.draws_xr + CmdStanGQ.draws + """ + self._assemble_draws() + + if inc_warmup and not self._save_warmup: + get_logger().warning( + "Sample doesn't contain draws from warmup iterations," + ' rerun sampler with "save_warmup=True".' + ) + + start_idx = 0 + if not inc_warmup and self._save_warmup: + start_idx = self.num_draws_warmup + + if concat_chains: + return flatten_chains(self._draws[start_idx:, :, :]) + return self._draws[start_idx:, :, :] + + def _validate_csv_files(self) -> Dict[str, Any]: + """ + Checks that Stan CSV output files for all chains are consistent + and returns dict containing config and column names. + + Tabulates sampling iters which are divergent or at max treedepth + Raises exception when inconsistencies detected. + """ + dzero = {} + for i in range(self.chains): + if i == 0: + dzero = check_sampler_csv( + path=self.runset.csv_files[i], + is_fixed_param=self._is_fixed_param, + iter_sampling=self._iter_sampling, + iter_warmup=self._iter_warmup, + save_warmup=self._save_warmup, + thin=self._thin, + ) + if not self._is_fixed_param: + self._divergences[i] = dzero['ct_divergences'] + self._max_treedepths[i] = dzero['ct_max_treedepth'] + else: + drest = check_sampler_csv( + path=self.runset.csv_files[i], + is_fixed_param=self._is_fixed_param, + iter_sampling=self._iter_sampling, + iter_warmup=self._iter_warmup, + save_warmup=self._save_warmup, + thin=self._thin, + ) + for key in dzero: + # check args that matter for parsing, plus name, version + if ( + key + in [ + 'stan_version_major', + 'stan_version_minor', + 'stan_version_patch', + 'stanc_version', + 'model', + 'num_samples', + 'num_warmup', + 'save_warmup', + 'thin', + 'refresh', + ] + and dzero[key] != drest[key] + ): + raise ValueError( + 'CmdStan config mismatch in Stan CSV file {}: ' + 'arg {} is {}, expected {}'.format( + self.runset.csv_files[i], + key, + dzero[key], + drest[key], + ) + ) + if not self._is_fixed_param: + self._divergences[i] = drest['ct_divergences'] + self._max_treedepths[i] = drest['ct_max_treedepth'] + return dzero + + def _check_sampler_diagnostics(self) -> None: + """ + Warn if any iterations ended in divergences or hit maxtreedepth. + """ + if np.any(self._divergences) or np.any(self._max_treedepths): + diagnostics = ['Some chains may have failed to converge.'] + ct_iters = self._metadata.cmdstan_config['num_samples'] + for i in range(self.runset._chains): + if self._divergences[i] > 0: + diagnostics.append( + f'Chain {i + 1} had {self._divergences[i]} ' + 'divergent transitions ' + f'({((self._divergences[i]/ct_iters)*100):.1f}%)' + ) + if self._max_treedepths[i] > 0: + diagnostics.append( + f'Chain {i + 1} had {self._max_treedepths[i]} ' + 'iterations at max treedepth ' + f'({((self._max_treedepths[i]/ct_iters)*100):.1f}%)' + ) + diagnostics.append( + 'Use the "diagnose()" method on the CmdStanMCMC object' + ' to see further information.' + ) + get_logger().warning('\n\t'.join(diagnostics)) + + def _assemble_draws(self) -> None: + """ + Allocates and populates the step size, metric, and sample arrays + by parsing the validated stan_csv files. + """ + if self._draws.shape != (0,): + return + num_draws = self.num_draws_sampling + sampling_iter_start = 0 + if self._save_warmup: + num_draws += self.num_draws_warmup + sampling_iter_start = self.num_draws_warmup + self._draws = np.empty( + (num_draws, self.chains, len(self.column_names)), + dtype=float, + order='F', + ) + self._step_size = np.empty(self.chains, dtype=float) + for chain in range(self.chains): + with open(self.runset.csv_files[chain], 'r') as fd: + line = fd.readline().strip() + # read initial comments, CSV header row + while len(line) > 0 and line.startswith('#'): + line = fd.readline().strip() + if not self._is_fixed_param: + # handle warmup draws, if any + if self._save_warmup: + for i in range(self.num_draws_warmup): + line = fd.readline().strip() + xs = line.split(',') + self._draws[i, chain, :] = [float(x) for x in xs] + line = fd.readline().strip() + if line != '# Adaptation terminated': # shouldn't happen? + while line != '# Adaptation terminated': + line = fd.readline().strip() + # step_size, metric (diag_e and dense_e only) + line = fd.readline().strip() + _, step_size = line.split('=') + self._step_size[chain] = float(step_size.strip()) + if self._metadata.cmdstan_config['metric'] != 'unit_e': + line = fd.readline().strip() # metric type + line = fd.readline().lstrip(' #\t').rstrip() + num_unconstrained_params = len(line.split(',')) + if chain == 0: # can't allocate w/o num params + if self.metric_type == 'diag_e': + self._metric = np.empty( + (self.chains, num_unconstrained_params), + dtype=float, + ) + else: + self._metric = np.empty( + ( + self.chains, + num_unconstrained_params, + num_unconstrained_params, + ), + dtype=float, + ) + if line: + if self.metric_type == 'diag_e': + xs = line.split(',') + self._metric[chain, :] = [float(x) for x in xs] + else: + xs = line.strip().split(',') + self._metric[chain, 0, :] = [ + float(x) for x in xs + ] + for i in range(1, num_unconstrained_params): + line = fd.readline().lstrip(' #\t').rstrip() + xs = line.split(',') + self._metric[chain, i, :] = [ + float(x) for x in xs + ] + else: # unit_e changed in 2.34 to have an extra line + pos = fd.tell() + line = fd.readline().strip() + if not line.startswith('#'): + fd.seek(pos) + + # process draws + for i in range(sampling_iter_start, num_draws): + line = fd.readline().strip() + xs = line.split(',') + self._draws[i, chain, :] = [float(x) for x in xs] + assert self._draws is not None + + def summary( + self, + percentiles: Sequence[int] = (5, 50, 95), + sig_figs: int = 6, + ) -> pd.DataFrame: + """ + Run cmdstan/bin/stansummary over all output CSV files, assemble + summary into DataFrame object. The first row contains statistics + for the total joint log probability `lp__`, but is omitted when the + Stan model has no parameters. The remaining rows contain summary + statistics for all parameters, transformed parameters, and generated + quantities variables, in program declaration order. + + :param percentiles: Ordered non-empty sequence of percentiles to report. + Must be integers from (1, 99), inclusive. Defaults to + ``(5, 50, 95)`` + + :param sig_figs: Number of significant figures to report. + Must be an integer between 1 and 18. If unspecified, the default + precision for the system file I/O is used; the usual value is 6. + If precision above 6 is requested, sample must have been produced + by CmdStan version 2.25 or later and sampler output precision + must equal to or greater than the requested summary precision. + + :return: pandas.DataFrame + """ + if len(percentiles) == 0: + raise ValueError( + 'Invalid percentiles argument, must be ordered' + ' non-empty list from (1, 99), inclusive.' + ) + cur_pct = 0 + for pct in percentiles: + if pct > 99 or not pct > cur_pct: + raise ValueError( + 'Invalid percentiles spec, must be ordered' + ' non-empty list from (1, 99), inclusive.' + ) + cur_pct = pct + percentiles_str = ( + f"--percentiles= {','.join(str(x) for x in percentiles)}" + ) + + if not isinstance(sig_figs, int) or sig_figs < 1 or sig_figs > 18: + raise ValueError( + 'Keyword "sig_figs" must be an integer between 1 and 18,' + ' found {}'.format(sig_figs) + ) + csv_sig_figs = self._sig_figs or 6 + if sig_figs > csv_sig_figs: + get_logger().warning( + 'Requesting %d significant digits of output, but CSV files' + ' only have %d digits of precision.', + sig_figs, + csv_sig_figs, + ) + sig_figs_str = f'--sig_figs={sig_figs}' + cmd_path = os.path.join( + cmdstan_path(), 'bin', 'stansummary' + EXTENSION + ) + tmp_csv_file = 'stansummary-{}-'.format(self.runset._args.model_name) + tmp_csv_path = create_named_text_file( + dir=_TMPDIR, prefix=tmp_csv_file, suffix='.csv', name_only=True + ) + csv_str = '--csv_filename={}'.format(tmp_csv_path) + # TODO: remove at some future release + if cmdstan_version_before(2, 24): + csv_str = '--csv_file={}'.format(tmp_csv_path) + cmd = [ + cmd_path, + percentiles_str, + sig_figs_str, + csv_str, + ] + self.runset.csv_files + do_command(cmd, fd_out=None) + with open(tmp_csv_path, 'rb') as fd: + summary_data = pd.read_csv( + fd, + delimiter=',', + header=0, + index_col=0, + comment='#', + float_precision='high', + ) + mask = ( + [not x.endswith('__') for x in summary_data.index] + if self._is_fixed_param + else [ + x == 'lp__' or not x.endswith('__') for x in summary_data.index + ] + ) + summary_data.index.name = None + return summary_data[mask] + + def diagnose(self) -> Optional[str]: + """ + Run cmdstan/bin/diagnose over all output CSV files, + return console output. + + The diagnose utility reads the outputs of all chains + and checks for the following potential problems: + + + Transitions that hit the maximum treedepth + + Divergent transitions + + Low E-BFMI values (sampler transitions HMC potential energy) + + Low effective sample sizes + + High R-hat values + """ + cmd_path = os.path.join(cmdstan_path(), 'bin', 'diagnose' + EXTENSION) + cmd = [cmd_path] + self.runset.csv_files + result = StringIO() + do_command(cmd=cmd, fd_out=result) + return result.getvalue() + + def draws_pd( + self, + vars: Union[List[str], str, None] = None, + inc_warmup: bool = False, + ) -> pd.DataFrame: + """ + Returns the sample draws as a pandas DataFrame. + Flattens all chains into single column. Container variables + (array, vector, matrix) will span multiple columns, one column + per element. E.g. variable 'matrix[2,2] foo' spans 4 columns: + 'foo[1,1], ... foo[2,2]'. + + :param vars: optional list of variable names. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + See Also + -------- + CmdStanMCMC.draws + CmdStanMCMC.draws_xr + CmdStanGQ.draws_pd + """ + if vars is not None: + if isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + + if inc_warmup and not self._save_warmup: + get_logger().warning( + 'Draws from warmup iterations not available,' + ' must run sampler with "save_warmup=True".' + ) + + self._assemble_draws() + cols = [] + if vars is not None: + for var in dict.fromkeys(vars_list): + if var in self._metadata.method_vars: + cols.append(var) + elif var in self._metadata.stan_vars: + info = self._metadata.stan_vars[var] + cols.extend( + self.column_names[info.start_idx : info.end_idx] + ) + elif var in ['chain__', 'iter__', 'draw__']: + cols.append(var) + else: + raise ValueError(f'Unknown variable: {var}') + else: + cols = ['chain__', 'iter__', 'draw__'] + list(self.column_names) + + draws = self.draws(inc_warmup=inc_warmup) + # add long-form columns for chain, iteration, draw + n_draws, n_chains, _ = draws.shape + chains_col = ( + np.repeat(np.arange(1, n_chains + 1), n_draws) + .reshape(1, n_chains, n_draws) + .T + ) + iter_col = ( + np.tile(np.arange(1, n_draws + 1), n_chains) + .reshape(1, n_chains, n_draws) + .T + ) + draw_col = ( + np.arange(1, (n_draws * n_chains) + 1) + .reshape(1, n_chains, n_draws) + .T + ) + draws = np.concatenate([chains_col, iter_col, draw_col, draws], axis=2) + + return pd.DataFrame( + data=flatten_chains(draws), + columns=['chain__', 'iter__', 'draw__'] + list(self.column_names), + )[cols] + + def draws_xr( + self, vars: Union[str, List[str], None] = None, inc_warmup: bool = False + ) -> "xr.Dataset": + """ + Returns the sampler draws as a xarray Dataset. + + :param vars: optional list of variable names. + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + See Also + -------- + CmdStanMCMC.draws + CmdStanMCMC.draws_pd + CmdStanGQ.draws_xr + """ + if not XARRAY_INSTALLED: + raise RuntimeError( + 'Package "xarray" is not installed, cannot produce draws array.' + ) + if inc_warmup and not self._save_warmup: + get_logger().warning( + "Draws from warmup iterations not available," + ' must run sampler with "save_warmup=True".' + ) + if vars is None: + vars_list = list(self._metadata.stan_vars.keys()) + elif isinstance(vars, str): + vars_list = [vars] + else: + vars_list = vars + + self._assemble_draws() + + num_draws = self.num_draws_sampling + meta = self._metadata.cmdstan_config + attrs: MutableMapping[Hashable, Any] = { + "stan_version": f"{meta['stan_version_major']}." + f"{meta['stan_version_minor']}.{meta['stan_version_patch']}", + "model": meta["model"], + "num_draws_sampling": num_draws, + } + if inc_warmup and self._save_warmup: + num_draws += self.num_draws_warmup + attrs["num_draws_warmup"] = self.num_draws_warmup + + data: MutableMapping[Hashable, Any] = {} + coordinates: MutableMapping[Hashable, Any] = { + "chain": self.chain_ids, + "draw": np.arange(num_draws), + } + + for var in vars_list: + build_xarray_data( + data, + self._metadata.stan_vars[var], + self.draws(inc_warmup=inc_warmup), + ) + return xr.Dataset(data, coords=coordinates, attrs=attrs).transpose( + 'chain', 'draw', ... + ) + + def stan_variable( + self, + var: str, + inc_warmup: bool = False, + ) -> np.ndarray: + """ + Return a numpy.ndarray which contains the set of draws + for the named Stan program variable. Flattens the chains, + leaving the draws in chain order. The first array dimension, + corresponds to number of draws or post-warmup draws in the sample, + per argument ``inc_warmup``. The remaining dimensions correspond to + the shape of the Stan program variable. + + Underlyingly draws are in chain order, i.e., for a sample with + N chains of M draws each, the first M array elements are from chain 1, + the next M are from chain 2, and the last M elements are from chain N. + + * If the variable is a scalar variable, the return array has shape + ( draws * chains, 1). + * If the variable is a vector, the return array has shape + ( draws * chains, len(vector)) + * If the variable is a matrix, the return array has shape + ( draws * chains, size(dim 1), size(dim 2) ) + * If the variable is an array with N dimensions, the return array + has shape ( draws * chains, size(dim 1), ..., size(dim N)) + + For example, if the Stan program variable ``theta`` is a 3x3 matrix, + and the sample consists of 4 chains with 1000 post-warmup draws, + this function will return a numpy.ndarray with shape (4000,3,3). + + This functionaltiy is also available via a shortcut using ``.`` - + writing ``fit.a`` is a synonym for ``fit.stan_variable("a")`` + + :param var: variable name + + :param inc_warmup: When ``True`` and the warmup draws are present in + the output, i.e., the sampler was run with ``save_warmup=True``, + then the warmup draws are included. Default value is ``False``. + + See Also + -------- + CmdStanMCMC.stan_variables + CmdStanMLE.stan_variable + CmdStanPathfinder.stan_variable + CmdStanVB.stan_variable + CmdStanGQ.stan_variable + CmdStanLaplace.stan_variable + """ + try: + draws = self.draws(inc_warmup=inc_warmup, concat_chains=True) + out: np.ndarray = self._metadata.stan_vars[var].extract_reshape( + draws + ) + return out + except KeyError: + # pylint: disable=raise-missing-from + raise ValueError( + f'Unknown variable name: {var}\n' + 'Available variables are ' + + ", ".join(self._metadata.stan_vars.keys()) + ) + + def stan_variables(self) -> Dict[str, np.ndarray]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + See Also + -------- + CmdStanMCMC.stan_variable + CmdStanMLE.stan_variables + CmdStanPathfinder.stan_variables + CmdStanVB.stan_variables + CmdStanGQ.stan_variables + CmdStanLaplace.stan_variables + """ + result = {} + for name in self._metadata.stan_vars: + result[name] = self.stan_variable(name) + return result + + def method_variables(self) -> Dict[str, np.ndarray]: + """ + Returns a dictionary of all sampler variables, i.e., all + output column names ending in `__`. Assumes that all variables + are scalar variables where column name is variable name. + Maps each column name to a numpy.ndarray (draws x chains x 1) + containing per-draw diagnostic values. + """ + self._assemble_draws() + return { + name: var.extract_reshape(self._draws) + for name, var in self._metadata.method_vars.items() + } + + def save_csvfiles(self, dir: Optional[str] = None) -> None: + """ + Move output CSV files to specified directory. If files were + written to the temporary session directory, clean filename. + E.g., save 'bernoulli-201912081451-1-5nm6as7u.csv' as + 'bernoulli-201912081451-1.csv'. + + :param dir: directory path + + See Also + -------- + stanfit.RunSet.save_csvfiles + cmdstanpy.from_csv + """ + self.runset.save_csvfiles(dir) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/metadata.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/metadata.py new file mode 100644 index 00000000..4869f2a0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/metadata.py @@ -0,0 +1,53 @@ +"""Container for metadata parsed from the output of a CmdStan run""" + +import copy +from typing import Any, Dict + +import stanio + + +class InferenceMetadata: + """ + CmdStan configuration and contents of output file parsed out of + the Stan CSV file header comments and column headers. + Assumes valid CSV files. + """ + + def __init__(self, config: Dict[str, Any]) -> None: + """Initialize object from CSV headers""" + self._cmdstan_config = config + vars = stanio.parse_header(config['raw_header']) + + self._method_vars = { + k: v for (k, v) in vars.items() if k.endswith('__') + } + self._stan_vars = { + k: v for (k, v) in vars.items() if not k.endswith('__') + } + + def __repr__(self) -> str: + return 'Metadata:\n{}\n'.format(self._cmdstan_config) + + @property + def cmdstan_config(self) -> Dict[str, Any]: + """ + Returns a dictionary containing a set of name, value pairs + parsed out of the Stan CSV file header. These include the + command configuration and the CSV file header row information. + Uses deepcopy for immutability. + """ + return copy.deepcopy(self._cmdstan_config) + + @property + def method_vars(self) -> Dict[str, stanio.Variable]: + """ + Method variable names always end in `__`, e.g. `lp__`. + """ + return self._method_vars + + @property + def stan_vars(self) -> Dict[str, stanio.Variable]: + """ + These are the user-defined variables in the Stan program. + """ + return self._stan_vars diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/mle.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/mle.py new file mode 100644 index 00000000..3a50ba10 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/mle.py @@ -0,0 +1,284 @@ +"""Container for the result of running optimization""" + +from collections import OrderedDict +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import pandas as pd + +from cmdstanpy.cmdstan_args import Method, OptimizeArgs +from cmdstanpy.utils import get_logger, scan_optimize_csv + +from .metadata import InferenceMetadata +from .runset import RunSet + + +class CmdStanMLE: + """ + Container for outputs from CmdStan optimization. + Created by :meth:`CmdStanModel.optimize`. + """ + + def __init__(self, runset: RunSet) -> None: + """Initialize object.""" + if not runset.method == Method.OPTIMIZE: + raise ValueError( + 'Wrong runset method, expecting optimize runset, ' + 'found method {}'.format(runset.method) + ) + self.runset = runset + # info from runset to be exposed + self.converged = runset._check_retcodes() + optimize_args = self.runset._args.method_args + assert isinstance( + optimize_args, OptimizeArgs + ) # make the typechecker happy + self._save_iterations: bool = optimize_args.save_iterations + self._set_mle_attrs(runset.csv_files[0]) + + def __repr__(self) -> str: + repr = 'CmdStanMLE: model={}{}'.format( + self.runset.model, self.runset._args.method_args.compose(0, cmd=[]) + ) + repr = '{}\n csv_file:\n\t{}\n output_file:\n\t{}'.format( + repr, + '\n\t'.join(self.runset.csv_files), + '\n\t'.join(self.runset.stdout_files), + ) + if not self.converged: + repr = '{}\n Warning: invalid estimate, '.format(repr) + repr = '{} optimization failed to converge.'.format(repr) + return repr + + def __getattr__(self, attr: str) -> Union[np.ndarray, float]: + """Synonymous with ``fit.stan_variable(attr)""" + if attr.startswith("_"): + raise AttributeError(f"Unknown variable name {attr}") + try: + return self.stan_variable(attr) + except ValueError as e: + # pylint: disable=raise-missing-from + raise AttributeError(*e.args) + + def _set_mle_attrs(self, sample_csv_0: str) -> None: + meta = scan_optimize_csv(sample_csv_0, self._save_iterations) + self._metadata = InferenceMetadata(meta) + self._column_names: Tuple[str, ...] = meta['column_names'] + self._mle: np.ndarray = meta['mle'] + if self._save_iterations: + self._all_iters: np.ndarray = meta['all_iters'] + + @property + def column_names(self) -> Tuple[str, ...]: + """ + Names of estimated quantities, includes joint log probability, + and all parameters, transformed parameters, and generated quantities. + """ + return self._column_names + + @property + def metadata(self) -> InferenceMetadata: + """ + Returns object which contains CmdStan configuration as well as + information about the names and structure of the inference method + and model output variables. + """ + return self._metadata + + @property + def optimized_params_np(self) -> np.ndarray: + """ + Returns all final estimates from the optimizer as a numpy.ndarray + which contains all optimizer outputs, i.e., the value for `lp__` + as well as all Stan program variables. + """ + if not self.converged: + get_logger().warning( + 'Invalid estimate, optimization failed to converge.' + ) + return self._mle + + @property + def optimized_iterations_np(self) -> Optional[np.ndarray]: + """ + Returns all saved iterations from the optimizer and final estimate + as a numpy.ndarray which contains all optimizer outputs, i.e., + the value for `lp__` as well as all Stan program variables. + + """ + if not self._save_iterations: + get_logger().warning( + 'Intermediate iterations not saved to CSV output file. ' + 'Rerun the optimize method with "save_iterations=True".' + ) + return None + if not self.converged: + get_logger().warning( + 'Invalid estimate, optimization failed to converge.' + ) + return self._all_iters + + @property + def optimized_params_pd(self) -> pd.DataFrame: + """ + Returns all final estimates from the optimizer as a pandas.DataFrame + which contains all optimizer outputs, i.e., the value for `lp__` + as well as all Stan program variables. + """ + if not self.runset._check_retcodes(): + get_logger().warning( + 'Invalid estimate, optimization failed to converge.' + ) + return pd.DataFrame([self._mle], columns=self.column_names) + + @property + def optimized_iterations_pd(self) -> Optional[pd.DataFrame]: + """ + Returns all saved iterations from the optimizer and final estimate + as a pandas.DataFrame which contains all optimizer outputs, i.e., + the value for `lp__` as well as all Stan program variables. + + """ + if not self._save_iterations: + get_logger().warning( + 'Intermediate iterations not saved to CSV output file. ' + 'Rerun the optimize method with "save_iterations=True".' + ) + return None + if not self.converged: + get_logger().warning( + 'Invalid estimate, optimization failed to converge.' + ) + return pd.DataFrame(self._all_iters, columns=self.column_names) + + @property + def optimized_params_dict(self) -> Dict[str, np.float64]: + """ + Returns all estimates from the optimizer, including `lp__` as a + Python Dict. Only returns estimate from final iteration. + """ + if not self.runset._check_retcodes(): + get_logger().warning( + 'Invalid estimate, optimization failed to converge.' + ) + return OrderedDict(zip(self.column_names, self._mle)) + + def stan_variable( + self, + var: str, + *, + inc_iterations: bool = False, + warn: bool = True, + ) -> Union[np.ndarray, float]: + """ + Return a numpy.ndarray which contains the estimates for the + for the named Stan program variable where the dimensions of the + numpy.ndarray match the shape of the Stan program variable. + + This functionaltiy is also available via a shortcut using ``.`` - + writing ``fit.a`` is a synonym for ``fit.stan_variable("a")`` + + :param var: variable name + + :param inc_iterations: When ``True`` and the intermediate estimates + are included in the output, i.e., the optimizer was run with + ``save_iterations=True``, then intermediate estimates are included. + Default value is ``False``. + + See Also + -------- + CmdStanMLE.stan_variables + CmdStanMCMC.stan_variable + CmdStanPathfinder.stan_variable + CmdStanVB.stan_variable + CmdStanGQ.stan_variable + CmdStanLaplace.stan_variable + """ + if var not in self._metadata.stan_vars: + raise ValueError( + f'Unknown variable name: {var}\n' + 'Available variables are ' + ", ".join(self._metadata.stan_vars) + ) + if warn and inc_iterations and not self._save_iterations: + get_logger().warning( + 'Intermediate iterations not saved to CSV output file. ' + 'Rerun the optimize method with "save_iterations=True".' + ) + if warn and not self.runset._check_retcodes(): + get_logger().warning( + 'Invalid estimate, optimization failed to converge.' + ) + if inc_iterations and self._save_iterations: + data = self._all_iters + else: + data = self._mle + + try: + out: np.ndarray = self._metadata.stan_vars[var].extract_reshape( + data + ) + # TODO(2.0) remove + if out.shape == () or out.shape == (1,): + get_logger().warning( + "The default behavior of CmdStanMLE.stan_variable() " + "will change in a future release to always return a " + "numpy.ndarray, even for scalar variables." + ) + return out.item() # type: ignore + return out + except KeyError: + # pylint: disable=raise-missing-from + raise ValueError( + f'Unknown variable name: {var}\n' + 'Available variables are ' + + ", ".join(self._metadata.stan_vars.keys()) + ) + + def stan_variables( + self, inc_iterations: bool = False + ) -> Dict[str, Union[np.ndarray, float]]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + :param inc_iterations: When ``True`` and the intermediate estimates + are included in the output, i.e., the optimizer was run with + ``save_iterations=True``, then intermediate estimates are included. + Default value is ``False``. + + + See Also + -------- + CmdStanMLE.stan_variable + CmdStanMCMC.stan_variables + CmdStanPathfinder.stan_variables + CmdStanVB.stan_variables + CmdStanGQ.stan_variables + CmdStanLaplace.stan_variables + """ + if not self.runset._check_retcodes(): + get_logger().warning( + 'Invalid estimate, optimization failed to converge.' + ) + result = {} + for name in self._metadata.stan_vars: + result[name] = self.stan_variable( + name, inc_iterations=inc_iterations, warn=False + ) + return result + + def save_csvfiles(self, dir: Optional[str] = None) -> None: + """ + Move output CSV files to specified directory. If files were + written to the temporary session directory, clean filename. + E.g., save 'bernoulli-201912081451-1-5nm6as7u.csv' as + 'bernoulli-201912081451-1.csv'. + + :param dir: directory path + + See Also + -------- + stanfit.RunSet.save_csvfiles + cmdstanpy.from_csv + """ + self.runset.save_csvfiles(dir) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/pathfinder.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/pathfinder.py new file mode 100644 index 00000000..8e63f85f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/pathfinder.py @@ -0,0 +1,237 @@ +""" +Container for the result of running Pathfinder. +""" + +from typing import Dict, List, Optional, Tuple, Union + +import numpy as np + +from cmdstanpy.cmdstan_args import Method +from cmdstanpy.stanfit.metadata import InferenceMetadata +from cmdstanpy.stanfit.runset import RunSet +from cmdstanpy.utils.stancsv import scan_generic_csv + + +class CmdStanPathfinder: + """ + Container for outputs from the Pathfinder algorithm. + Created by :meth:`CmdStanModel.pathfinder()`. + """ + + def __init__(self, runset: RunSet): + """Initialize object.""" + if not runset.method == Method.PATHFINDER: + raise ValueError( + 'Wrong runset method, expecting Pathfinder runset, ' + 'found method {}'.format(runset.method) + ) + self._runset = runset + + self._draws: np.ndarray = np.array(()) + + config = scan_generic_csv(runset.csv_files[0]) + self._metadata = InferenceMetadata(config) + + def create_inits( + self, seed: Optional[int] = None, chains: int = 4 + ) -> Union[List[Dict[str, np.ndarray]], Dict[str, np.ndarray]]: + """ + Create initial values for the parameters of the model + by randomly selecting draws from the Pathfinder approximation. + + :param seed: Used for random selection, defaults to None + :param chains: Number of initial values to return, defaults to 4 + :return: The initial values for the parameters of the model. + + If ``chains`` is 1, a dictionary is returned, otherwise a list + of dictionaries is returned, in the format expected for the + ``inits`` argument. of :meth:`CmdStanModel.sample`. + """ + self._assemble_draws() + rng = np.random.default_rng(seed) + idxs = rng.choice(self._draws.shape[0], size=chains, replace=False) + if chains == 1: + draw = self._draws[idxs[0]] + return { + name: var.extract_reshape(draw) + for name, var in self._metadata.stan_vars.items() + } + else: + return [ + { + name: var.extract_reshape(self._draws[idx]) + for name, var in self._metadata.stan_vars.items() + } + for idx in idxs + ] + + def __repr__(self) -> str: + rep = 'CmdStanPathfinder: model={}{}'.format( + self._runset.model, + self._runset._args.method_args.compose(0, cmd=[]), + ) + rep = '{}\n csv_files:\n\t{}\n output_files:\n\t{}'.format( + rep, + '\n\t'.join(self._runset.csv_files), + '\n\t'.join(self._runset.stdout_files), + ) + return rep + + # below this is identical to same functions in Laplace + def _assemble_draws(self) -> None: + if self._draws.shape != (0,): + return + + with open(self._runset.csv_files[0], 'r') as fd: + while (fd.readline()).startswith("#"): + pass + self._draws = np.loadtxt( + fd, + dtype=float, + ndmin=2, + delimiter=',', + comments="#", + ) + + def stan_variable(self, var: str) -> np.ndarray: + """ + Return a numpy.ndarray which contains the estimates for the + for the named Stan program variable where the dimensions of the + numpy.ndarray match the shape of the Stan program variable. + + This functionaltiy is also available via a shortcut using ``.`` - + writing ``fit.a`` is a synonym for ``fit.stan_variable("a")`` + + :param var: variable name + + See Also + -------- + CmdStanPathfinder.stan_variables + CmdStanMLE.stan_variable + CmdStanMCMC.stan_variable + CmdStanVB.stan_variable + CmdStanGQ.stan_variable + CmdStanLaplace.stan_variable + """ + self._assemble_draws() + try: + out: np.ndarray = self._metadata.stan_vars[var].extract_reshape( + self._draws + ) + return out + except KeyError: + # pylint: disable=raise-missing-from + raise ValueError( + f'Unknown variable name: {var}\n' + 'Available variables are ' + + ", ".join(self._metadata.stan_vars.keys()) + ) + + def stan_variables(self) -> Dict[str, np.ndarray]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + See Also + -------- + CmdStanPathfinder.stan_variable + CmdStanMCMC.stan_variables + CmdStanMLE.stan_variables + CmdStanVB.stan_variables + CmdStanGQ.stan_variables + CmdStanLaplace.stan_variables + """ + result = {} + for name in self._metadata.stan_vars: + result[name] = self.stan_variable(name) + return result + + def method_variables(self) -> Dict[str, np.ndarray]: + """ + Returns a dictionary of all sampler variables, i.e., all + output column names ending in `__`. Assumes that all variables + are scalar variables where column name is variable name. + Maps each column name to a numpy.ndarray (draws x chains x 1) + containing per-draw diagnostic values. + """ + self._assemble_draws() + return { + name: var.extract_reshape(self._draws) + for name, var in self._metadata.method_vars.items() + } + + def draws(self) -> np.ndarray: + """ + Return a numpy.ndarray containing the draws from the + approximate posterior distribution. This is a 2-D array + of shape (draws, parameters). + """ + self._assemble_draws() + return self._draws + + def __getattr__(self, attr: str) -> np.ndarray: + """Synonymous with ``fit.stan_variable(attr)""" + if attr.startswith("_"): + raise AttributeError(f"Unknown variable name {attr}") + try: + return self.stan_variable(attr) + except ValueError as e: + # pylint: disable=raise-missing-from + raise AttributeError(*e.args) + + def __getstate__(self) -> dict: + # This function returns the mapping of objects to serialize with pickle. + # See https://docs.python.org/3/library/pickle.html#object.__getstate__ + # for details. We call _assemble_draws to ensure posterior samples have + # been loaded prior to serialization. + self._assemble_draws() + return self.__dict__ + + @property + def metadata(self) -> InferenceMetadata: + """ + Returns object which contains CmdStan configuration as well as + information about the names and structure of the inference method + and model output variables. + """ + return self._metadata + + @property + def column_names(self) -> Tuple[str, ...]: + """ + Names of all outputs from the sampler, comprising sampler parameters + and all components of all model parameters, transformed parameters, + and quantities of interest. Corresponds to Stan CSV file header row, + with names munged to array notation, e.g. `beta[1]` not `beta.1`. + """ + return self._metadata.cmdstan_config['column_names'] # type: ignore + + @property + def is_resampled(self) -> bool: + """ + Returns True if the draws were resampled from several Pathfinder + approximations, False otherwise. + """ + return ( # type: ignore + self._metadata.cmdstan_config.get("num_paths", 4) > 1 + and self._metadata.cmdstan_config.get('psis_resample', 1) + in (1, 'true') + and self._metadata.cmdstan_config.get('calculate_lp', 1) + in (1, 'true') + ) + + def save_csvfiles(self, dir: Optional[str] = None) -> None: + """ + Move output CSV files to specified directory. If files were + written to the temporary session directory, clean filename. + E.g., save 'bernoulli-201912081451-1-5nm6as7u.csv' as + 'bernoulli-201912081451-1.csv'. + + :param dir: directory path + + See Also + -------- + stanfit.RunSet.save_csvfiles + cmdstanpy.from_csv + """ + self._runset.save_csvfiles(dir) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/runset.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/runset.py new file mode 100644 index 00000000..de11a461 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/runset.py @@ -0,0 +1,307 @@ +""" +Container for the information used in a generic CmdStan run, +such as file locations +""" + +import os +import re +import shutil +import tempfile +from datetime import datetime +from time import time +from typing import List, Optional + +from cmdstanpy import _TMPDIR +from cmdstanpy.cmdstan_args import CmdStanArgs, Method +from cmdstanpy.utils import get_logger + + +class RunSet: + """ + Encapsulates the configuration and results of a call to any CmdStan + inference method. Records the method return code and locations of + all console, error, and output files. + + RunSet objects are instantiated by the CmdStanModel class inference methods + which validate all inputs, therefore "__init__" method skips input checks. + """ + + def __init__( + self, + args: CmdStanArgs, + chains: int = 1, + *, + chain_ids: Optional[List[int]] = None, + time_fmt: str = "%Y%m%d%H%M%S", + one_process_per_chain: bool = True, + ) -> None: + """Initialize object (no input arg checks).""" + self._args = args + self._chains = chains + self._one_process_per_chain = one_process_per_chain + if one_process_per_chain: + self._num_procs = chains + else: + self._num_procs = 1 + self._retcodes = [-1 for _ in range(self._num_procs)] + self._timeout_flags = [False for _ in range(self._num_procs)] + if chain_ids is None: + chain_ids = [i + 1 for i in range(chains)] + self._chain_ids = chain_ids + + if args.output_dir is not None: + self._output_dir = args.output_dir + else: + # make a per-run subdirectory of our master temp directory + self._output_dir = tempfile.mkdtemp( + prefix=args.model_name, dir=_TMPDIR + ) + + # output files prefix: ``-_`` + self._base_outfile = ( + f'{args.model_name}-{datetime.now().strftime(time_fmt)}' + ) + # per-process outputs + self._stdout_files = [''] * self._num_procs + self._profile_files = [''] * self._num_procs # optional + if one_process_per_chain: + for i in range(chains): + self._stdout_files[i] = self.file_path("-stdout.txt", id=i) + if args.save_profile: + self._profile_files[i] = self.file_path( + ".csv", extra="-profile", id=chain_ids[i] + ) + else: + self._stdout_files[0] = self.file_path("-stdout.txt") + if args.save_profile: + self._profile_files[0] = self.file_path( + ".csv", extra="-profile" + ) + + # per-chain output files + self._csv_files: List[str] = [''] * chains + self._diagnostic_files = [''] * chains # optional + + if chains == 1: + self._csv_files[0] = self.file_path(".csv") + if args.save_latent_dynamics: + self._diagnostic_files[0] = self.file_path( + ".csv", extra="-diagnostic" + ) + else: + for i in range(chains): + self._csv_files[i] = self.file_path(".csv", id=chain_ids[i]) + if args.save_latent_dynamics: + self._diagnostic_files[i] = self.file_path( + ".csv", extra="-diagnostic", id=chain_ids[i] + ) + + def __repr__(self) -> str: + repr = 'RunSet: chains={}, chain_ids={}, num_processes={}'.format( + self._chains, self._chain_ids, self._num_procs + ) + repr = '{}\n cmd (chain 1):\n\t{}'.format(repr, self.cmd(0)) + repr = '{}\n retcodes={}'.format(repr, self._retcodes) + repr = f'{repr}\n per-chain output files (showing chain 1 only):' + repr = '{}\n csv_file:\n\t{}'.format(repr, self._csv_files[0]) + if self._args.save_latent_dynamics: + repr = '{}\n diagnostics_file:\n\t{}'.format( + repr, self._diagnostic_files[0] + ) + if self._args.save_profile: + repr = '{}\n profile_file:\n\t{}'.format( + repr, self._profile_files[0] + ) + repr = '{}\n console_msgs (if any):\n\t{}'.format( + repr, self._stdout_files[0] + ) + return repr + + @property + def model(self) -> str: + """Stan model name.""" + return self._args.model_name + + @property + def method(self) -> Method: + """CmdStan method used to generate this fit.""" + return self._args.method + + @property + def num_procs(self) -> int: + """Number of processes run.""" + return self._num_procs + + @property + def one_process_per_chain(self) -> bool: + """ + When True, for each chain, call CmdStan in its own subprocess. + When False, use CmdStan's `num_chains` arg to run parallel chains. + Always True if CmdStan < 2.28. + For CmdStan 2.28 and up, `sample` method determines value. + """ + return self._one_process_per_chain + + @property + def chains(self) -> int: + """Number of chains.""" + return self._chains + + @property + def chain_ids(self) -> List[int]: + """Chain ids.""" + return self._chain_ids + + def cmd(self, idx: int) -> List[str]: + """ + Assemble CmdStan invocation. + When running parallel chains from single process (2.28 and up), + specify CmdStan arg `num_chains` and leave chain idx off CSV files. + """ + if self._one_process_per_chain: + return self._args.compose_command( + idx, + csv_file=self.csv_files[idx], + diagnostic_file=self.diagnostic_files[idx] + if self._args.save_latent_dynamics + else None, + profile_file=self.profile_files[idx] + if self._args.save_profile + else None, + ) + else: + return self._args.compose_command( + idx, + csv_file=self.file_path('.csv'), + diagnostic_file=self.file_path(".csv", extra="-diagnostic") + if self._args.save_latent_dynamics + else None, + profile_file=self.file_path(".csv", extra="-profile") + if self._args.save_profile + else None, + ) + + @property + def csv_files(self) -> List[str]: + """List of paths to CmdStan output files.""" + return self._csv_files + + @property + def stdout_files(self) -> List[str]: + """ + List of paths to transcript of CmdStan messages sent to the console. + Transcripts include config information, progress, and error messages. + """ + return self._stdout_files + + def _check_retcodes(self) -> bool: + """Returns ``True`` when all chains have retcode 0.""" + for code in self._retcodes: + if code != 0: + return False + return True + + @property + def diagnostic_files(self) -> List[str]: + """List of paths to CmdStan hamiltonian diagnostic files.""" + return self._diagnostic_files + + @property + def profile_files(self) -> List[str]: + """List of paths to CmdStan profiler files.""" + return self._profile_files + + # pylint: disable=invalid-name + def file_path( + self, suffix: str, *, extra: str = "", id: Optional[int] = None + ) -> str: + if id is not None: + suffix = f"_{id}{suffix}" + file = os.path.join( + self._output_dir, f"{self._base_outfile}{extra}{suffix}" + ) + return file + + def _retcode(self, idx: int) -> int: + """Get retcode for process[idx].""" + return self._retcodes[idx] + + def _set_retcode(self, idx: int, val: int) -> None: + """Set retcode at process[idx] to val.""" + self._retcodes[idx] = val + + def _set_timeout_flag(self, idx: int, val: bool) -> None: + """Set timeout_flag at process[idx] to val.""" + self._timeout_flags[idx] = val + + def get_err_msgs(self) -> str: + """Checks console messages for each CmdStan run.""" + msgs = [] + for i in range(self._num_procs): + if ( + os.path.exists(self._stdout_files[i]) + and os.stat(self._stdout_files[i]).st_size > 0 + ): + if self._args.method == Method.OPTIMIZE: + msgs.append('console log output:\n') + with open(self._stdout_files[0], 'r') as fd: + msgs.append(fd.read()) + else: + with open(self._stdout_files[i], 'r') as fd: + contents = fd.read() + # pattern matches initial "Exception" or "Error" msg + pat = re.compile(r'^E[rx].*$', re.M) + errors = re.findall(pat, contents) + if len(errors) > 0: + msgs.append('\n\t'.join(errors)) + return '\n'.join(msgs) + + def save_csvfiles(self, dir: Optional[str] = None) -> None: + """ + Moves CSV files to specified directory. + + :param dir: directory path + + See Also + -------- + cmdstanpy.from_csv + """ + if dir is None: + dir = os.path.realpath('.') + test_path = os.path.join(dir, str(time())) + try: + os.makedirs(dir, exist_ok=True) + with open(test_path, 'w'): + pass + os.remove(test_path) # cleanup + except (IOError, OSError, PermissionError) as exc: + raise RuntimeError('Cannot save to path: {}'.format(dir)) from exc + + for i in range(self.chains): + if not os.path.exists(self._csv_files[i]): + raise ValueError( + 'Cannot access CSV file {}'.format(self._csv_files[i]) + ) + + to_path = os.path.join(dir, os.path.basename(self._csv_files[i])) + if os.path.exists(to_path): + raise ValueError( + 'File exists, not overwriting: {}'.format(to_path) + ) + try: + get_logger().debug( + 'saving tmpfile: "%s" as: "%s"', self._csv_files[i], to_path + ) + shutil.move(self._csv_files[i], to_path) + self._csv_files[i] = to_path + except (IOError, OSError, PermissionError) as e: + raise ValueError( + 'Cannot save to file: {}'.format(to_path) + ) from e + + def raise_for_timeouts(self) -> None: + if any(self._timeout_flags): + raise TimeoutError( + f"{sum(self._timeout_flags)} of {self.num_procs} processes " + "timed out" + ) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/vb.py b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/vb.py new file mode 100644 index 00000000..102f292c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/stanfit/vb.py @@ -0,0 +1,240 @@ +"""Container for the results of running autodiff variational inference""" + +from collections import OrderedDict +from typing import Dict, Optional, Tuple, Union + +import numpy as np +import pandas as pd + +from cmdstanpy.cmdstan_args import Method +from cmdstanpy.utils import scan_variational_csv +from cmdstanpy.utils.logging import get_logger + +from .metadata import InferenceMetadata +from .runset import RunSet + + +class CmdStanVB: + """ + Container for outputs from CmdStan variational run. + Created by :meth:`CmdStanModel.variational`. + """ + + def __init__(self, runset: RunSet) -> None: + """Initialize object.""" + if not runset.method == Method.VARIATIONAL: + raise ValueError( + 'Wrong runset method, expecting variational inference, ' + 'found method {}'.format(runset.method) + ) + self.runset = runset + self._set_variational_attrs(runset.csv_files[0]) + + def __repr__(self) -> str: + repr = 'CmdStanVB: model={}{}'.format( + self.runset.model, self.runset._args.method_args.compose(0, cmd=[]) + ) + repr = '{}\n csv_file:\n\t{}\n output_file:\n\t{}'.format( + repr, + '\n\t'.join(self.runset.csv_files), + '\n\t'.join(self.runset.stdout_files), + ) + # TODO - diagnostic, profiling files + return repr + + def __getattr__(self, attr: str) -> Union[np.ndarray, float]: + """Synonymous with ``fit.stan_variable(attr)""" + if attr.startswith("_"): + raise AttributeError(f"Unknown variable name {attr}") + try: + return self.stan_variable(attr) + except ValueError as e: + # pylint: disable=raise-missing-from + raise AttributeError(*e.args) + + def _set_variational_attrs(self, sample_csv_0: str) -> None: + meta = scan_variational_csv(sample_csv_0) + self._metadata = InferenceMetadata(meta) + # these three assignments don't grant type information + self._column_names: Tuple[str, ...] = meta['column_names'] + self._eta: float = meta['eta'] + self._variational_mean: np.ndarray = meta['variational_mean'] + self._variational_sample: np.ndarray = meta['variational_sample'] + + @property + def columns(self) -> int: + """ + Total number of information items returned by sampler. + Includes approximation information and names of model parameters + and computed quantities. + """ + return len(self._column_names) + + @property + def column_names(self) -> Tuple[str, ...]: + """ + Names of information items returned by sampler for each draw. + Includes approximation information and names of model parameters + and computed quantities. + """ + return self._column_names + + @property + def eta(self) -> float: + """ + Step size scaling parameter 'eta' + """ + return self._eta + + @property + def variational_params_np(self) -> np.ndarray: + """ + Returns inferred parameter means as numpy array. + """ + return self._variational_mean + + @property + def variational_params_pd(self) -> pd.DataFrame: + """ + Returns inferred parameter means as pandas DataFrame. + """ + return pd.DataFrame([self._variational_mean], columns=self.column_names) + + @property + def variational_params_dict(self) -> Dict[str, np.ndarray]: + """Returns inferred parameter means as Dict.""" + return OrderedDict(zip(self.column_names, self._variational_mean)) + + @property + def metadata(self) -> InferenceMetadata: + """ + Returns object which contains CmdStan configuration as well as + information about the names and structure of the inference method + and model output variables. + """ + return self._metadata + + def stan_variable( + self, var: str, *, mean: Optional[bool] = None + ) -> Union[np.ndarray, float]: + """ + Return a numpy.ndarray which contains the estimates for the + for the named Stan program variable where the dimensions of the + numpy.ndarray match the shape of the Stan program variable, with + a leading axis added for the number of draws from the variational + approximation. + + * If the variable is a scalar variable, the return array has shape + ( draws, ). + * If the variable is a vector, the return array has shape + ( draws, len(vector)) + * If the variable is a matrix, the return array has shape + ( draws, size(dim 1), size(dim 2) ) + * If the variable is an array with N dimensions, the return array + has shape ( draws, size(dim 1), ..., size(dim N)) + + This functionaltiy is also available via a shortcut using ``.`` - + writing ``fit.a`` is a synonym for ``fit.stan_variable("a")`` + + :param var: variable name + + :param mean: if True, return the variational mean. Otherwise, + return the variational sample. The default behavior will + change in a future release to return the variational sample. + + See Also + -------- + CmdStanVB.stan_variables + CmdStanMCMC.stan_variable + CmdStanMLE.stan_variable + CmdStanPathfinder.stan_variable + CmdStanGQ.stan_variable + CmdStanLaplace.stan_variable + """ + # TODO(2.0): remove None case, make default `False` + if mean is None: + get_logger().warning( + "The default behavior of CmdStanVB.stan_variable() " + "will change in a future release to return the " + "variational sample, rather than the mean.\n" + "To maintain the current behavior, pass the argument " + "mean=True" + ) + mean = True + if mean: + draws = self._variational_mean + else: + draws = self._variational_sample + + try: + out: np.ndarray = self._metadata.stan_vars[var].extract_reshape( + draws + ) + # TODO(2.0): remove + if out.shape == () or out.shape == (1,): + if mean: + get_logger().warning( + "The default behavior of " + "CmdStanVB.stan_variable(mean=True) will change in a " + "future release to always return a numpy.ndarray, even " + "for scalar variables." + ) + return out.item() # type: ignore + return out + except KeyError: + # pylint: disable=raise-missing-from + raise ValueError( + f'Unknown variable name: {var}\n' + 'Available variables are ' + + ", ".join(self._metadata.stan_vars.keys()) + ) + + def stan_variables( + self, *, mean: Optional[bool] = None + ) -> Dict[str, Union[np.ndarray, float]]: + """ + Return a dictionary mapping Stan program variables names + to the corresponding numpy.ndarray containing the inferred values. + + See Also + -------- + CmdStanVB.stan_variable + CmdStanMCMC.stan_variables + CmdStanMLE.stan_variables + CmdStanGQ.stan_variables + CmdStanPathfinder.stan_variables + CmdStanLaplace.stan_variables + """ + result = {} + for name in self._metadata.stan_vars: + result[name] = self.stan_variable(name, mean=mean) + return result + + @property + def variational_sample(self) -> np.ndarray: + """Returns the set of approximate posterior output draws.""" + return self._variational_sample + + @property + def variational_sample_pd(self) -> pd.DataFrame: + """ + Returns the set of approximate posterior output draws as + a pandas DataFrame. + """ + return pd.DataFrame(self._variational_sample, columns=self.column_names) + + def save_csvfiles(self, dir: Optional[str] = None) -> None: + """ + Move output CSV files to specified directory. If files were + written to the temporary session directory, clean filename. + E.g., save 'bernoulli-201912081451-1-5nm6as7u.csv' as + 'bernoulli-201912081451-1.csv'. + + :param dir: directory path + + See Also + -------- + stanfit.RunSet.save_csvfiles + cmdstanpy.from_csv + """ + self.runset.save_csvfiles(dir) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__init__.py b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__init__.py new file mode 100644 index 00000000..9b2da413 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__init__.py @@ -0,0 +1,147 @@ +""" +Utility functions +""" +import os +import platform +import sys + +from .cmdstan import ( + EXTENSION, + cmdstan_path, + cmdstan_version, + cmdstan_version_before, + cxx_toolchain_path, + get_latest_cmdstan, + install_cmdstan, + set_cmdstan_path, + set_make_env, + validate_cmdstan_path, + validate_dir, + wrap_url_progress_hook, +) +from .command import do_command, returncode_msg +from .data_munging import build_xarray_data, flatten_chains +from .filesystem import ( + SanitizedOrTmpFilePath, + create_named_text_file, + pushd, + windows_short_path, +) +from .json import write_stan_json +from .logging import get_logger +from .stancsv import ( + check_sampler_csv, + parse_rdump_value, + read_metric, + rload, + scan_column_names, + scan_config, + scan_hmc_params, + scan_optimize_csv, + scan_sampler_csv, + scan_sampling_iters, + scan_variational_csv, + scan_warmup_iters, +) + + +def show_versions(output: bool = True) -> str: + """Prints out system and dependency information for debugging""" + + import importlib + import locale + import struct + + deps_info = [] + try: + (sysname, _, release, _, machine, processor) = platform.uname() + deps_info.extend( + [ + ("python", sys.version), + ("python-bits", struct.calcsize("P") * 8), + ("OS", f"{sysname}"), + ("OS-release", f"{release}"), + ("machine", f"{machine}"), + ("processor", f"{processor}"), + ("byteorder", f"{sys.byteorder}"), + ("LC_ALL", f'{os.environ.get("LC_ALL", "None")}'), + ("LANG", f'{os.environ.get("LANG", "None")}'), + ("LOCALE", f"{locale.getlocale()}"), + ] + ) + # pylint: disable=broad-except + except Exception: + pass + + try: + deps_info.append(('cmdstan_folder', cmdstan_path())) + deps_info.append(('cmdstan', str(cmdstan_version()))) + # pylint: disable=broad-except + except Exception: + deps_info.append(('cmdstan', 'NOT FOUND')) + + deps = ['cmdstanpy', 'pandas', 'xarray', 'tqdm', 'numpy'] + for module in deps: + try: + if module in sys.modules: + mod = sys.modules[module] + else: + mod = importlib.import_module(module) + # pylint: disable=broad-except + except Exception: + deps_info.append((module, None)) + else: + try: + ver = mod.__version__ # type: ignore + deps_info.append((module, ver)) + # pylint: disable=broad-except + except Exception: + deps_info.append((module, "installed")) + + out = 'INSTALLED VERSIONS\n---------------------\n' + for k, info in deps_info: + out += f'{k}: {info}\n' + if output: + print(out) + return " " + else: + return out + + +__all__ = [ + 'EXTENSION', + 'SanitizedOrTmpFilePath', + 'build_xarray_data', + 'check_sampler_csv', + 'cmdstan_path', + 'cmdstan_version', + 'cmdstan_version_before', + 'create_named_text_file', + 'cxx_toolchain_path', + 'do_command', + 'flatten_chains', + 'get_latest_cmdstan', + 'get_logger', + 'install_cmdstan', + 'parse_rdump_value', + 'pushd', + 'read_metric', + 'returncode_msg', + 'rload', + 'scan_column_names', + 'scan_config', + 'scan_hmc_params', + 'scan_optimize_csv', + 'scan_sampler_csv', + 'scan_sampling_iters', + 'scan_variational_csv', + 'scan_warmup_iters', + 'set_cmdstan_path', + 'set_make_env', + 'show_versions', + 'validate_cmdstan_path', + 'validate_dir', + 'windows_short_path', + 'wrap_url_progress_hook', + 'write_stan_json', +] diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..4fc8531a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/cmdstan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/cmdstan.cpython-312.pyc new file mode 100644 index 00000000..0b708936 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/cmdstan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/command.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/command.cpython-312.pyc new file mode 100644 index 00000000..157fae51 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/command.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/data_munging.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/data_munging.cpython-312.pyc new file mode 100644 index 00000000..52219519 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/data_munging.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/filesystem.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/filesystem.cpython-312.pyc new file mode 100644 index 00000000..54afa6a7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/filesystem.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/json.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/json.cpython-312.pyc new file mode 100644 index 00000000..42b2bb45 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/json.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/logging.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/logging.cpython-312.pyc new file mode 100644 index 00000000..783b6adc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/logging.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/stancsv.cpython-312.pyc b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/stancsv.cpython-312.pyc new file mode 100644 index 00000000..d185d03d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/__pycache__/stancsv.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/cmdstan.py b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/cmdstan.py new file mode 100644 index 00000000..2577b352 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/cmdstan.py @@ -0,0 +1,554 @@ +""" +Utilities for finding and installing CmdStan +""" +import os +import platform +import subprocess +import sys +from collections import OrderedDict +from typing import Callable, Dict, Optional, Tuple, Union + +from tqdm.auto import tqdm + +from cmdstanpy import _DOT_CMDSTAN + +from .. import progress as progbar +from .logging import get_logger + +EXTENSION = '.exe' if platform.system() == 'Windows' else '' + + +def determine_linux_arch() -> str: + machine = platform.machine() + arch = "" + if machine == "aarch64": + arch = "arm64" + elif machine == "armv7l": + # Telling armel and armhf apart is nontrivial + # c.f. https://forums.raspberrypi.com/viewtopic.php?t=20873 + readelf = subprocess.run( + ["readelf", "-A", "/proc/self/exe"], + check=True, + stdout=subprocess.PIPE, + text=True, + ) + if "Tag_ABI_VFP_args" in readelf.stdout: + arch = "armel" + else: + arch = "armhf" + elif machine == "mips64": + arch = "mips64el" + elif machine == "ppc64el" or machine == "ppc64le": + arch = "ppc64el" + elif machine == "s390x": + arch = "s390x" + return arch + + +def get_download_url(version: str) -> str: + arch = os.environ.get("CMDSTAN_ARCH", "") + if not arch and platform.system() == "Linux": + arch = determine_linux_arch() + + if arch and arch.lower() != "false": + url_end = f'v{version}/cmdstan-{version}-linux-{arch}.tar.gz' + else: + url_end = f'v{version}/cmdstan-{version}.tar.gz' + + return f'https://github.com/stan-dev/cmdstan/releases/download/{url_end}' + + +def validate_dir(install_dir: str) -> None: + """Check that specified install directory exists, can write.""" + if not os.path.exists(install_dir): + try: + os.makedirs(install_dir) + except (IOError, OSError, PermissionError) as e: + raise ValueError( + 'Cannot create directory: {}'.format(install_dir) + ) from e + else: + if not os.path.isdir(install_dir): + raise ValueError( + 'File exists, should be a directory: {}'.format(install_dir) + ) + try: + with open('tmp_test_w', 'w'): + pass + os.remove('tmp_test_w') # cleanup + except OSError as e: + raise ValueError( + 'Cannot write files to directory {}'.format(install_dir) + ) from e + + +def get_latest_cmdstan(cmdstan_dir: str) -> Optional[str]: + """ + Given a valid directory path, find all installed CmdStan versions + and return highest (i.e., latest) version number. + + Assumes directory consists of CmdStan releases, created by + function `install_cmdstan`, and therefore dirnames have format + "cmdstan-.." or "cmdstan-..-rc", + which is CmdStan release practice as of v 2.24. + """ + versions = [ + name[8:] + for name in os.listdir(cmdstan_dir) + if os.path.isdir(os.path.join(cmdstan_dir, name)) + and name.startswith('cmdstan-') + ] + if len(versions) == 0: + return None + if len(versions) == 1: + return 'cmdstan-' + versions[0] + # we can only compare numeric versions + versions = [v for v in versions if v[0].isdigit() and v.count('.') == 2] + # munge rc for sort, e.g. 2.25.0-rc1 -> 2.25.-99 + for i in range(len(versions)): # # pylint: disable=C0200 + if '-rc' in versions[i]: + comps = versions[i].split('-rc') + mmp = comps[0].split('.') + rc_num = comps[1] + patch = str(int(rc_num) - 100) + versions[i] = '.'.join([mmp[0], mmp[1], patch]) + + versions.sort(key=lambda s: list(map(int, s.split('.')))) + latest = versions[len(versions) - 1] + + # unmunge as needed + mmp = latest.split('.') + if int(mmp[2]) < 0: + rc_num = str(int(mmp[2]) + 100) + mmp[2] = "0-rc" + rc_num + latest = '.'.join(mmp) + + return 'cmdstan-' + latest + + +def validate_cmdstan_path(path: str) -> None: + """ + Validate that CmdStan directory exists and binaries have been built. + Throws exception if specified path is invalid. + """ + if not os.path.isdir(path): + raise ValueError(f'No CmdStan directory, path {path} does not exist.') + if not os.path.exists(os.path.join(path, 'bin', 'stanc' + EXTENSION)): + raise ValueError( + f'CmdStan installataion missing binaries in {path}/bin. ' + 'Re-install cmdstan by running command "install_cmdstan ' + '--overwrite", or Python code "import cmdstanpy; ' + 'cmdstanpy.install_cmdstan(overwrite=True)"' + ) + + +def set_cmdstan_path(path: str) -> None: + """ + Validate, then set CmdStan directory path. + """ + validate_cmdstan_path(path) + os.environ['CMDSTAN'] = path + + +def set_make_env(make: str) -> None: + """ + set MAKE environmental variable. + """ + os.environ['MAKE'] = make + + +def cmdstan_path() -> str: + """ + Validate, then return CmdStan directory path. + """ + cmdstan = '' + if 'CMDSTAN' in os.environ and len(os.environ['CMDSTAN']) > 0: + cmdstan = os.environ['CMDSTAN'] + else: + cmdstan_dir = os.path.expanduser(os.path.join('~', _DOT_CMDSTAN)) + if not os.path.exists(cmdstan_dir): + raise ValueError( + 'No CmdStan installation found, run command "install_cmdstan"' + 'or (re)activate your conda environment!' + ) + latest_cmdstan = get_latest_cmdstan(cmdstan_dir) + if latest_cmdstan is None: + raise ValueError( + 'No CmdStan installation found, run command "install_cmdstan"' + 'or (re)activate your conda environment!' + ) + cmdstan = os.path.join(cmdstan_dir, latest_cmdstan) + os.environ['CMDSTAN'] = cmdstan + validate_cmdstan_path(cmdstan) + return os.path.normpath(cmdstan) + + +def cmdstan_version() -> Optional[Tuple[int, ...]]: + """ + Parses version string out of CmdStan makefile variable CMDSTAN_VERSION, + returns Tuple(Major, minor). + + If CmdStan installation is not found or cannot parse version from makefile + logs warning and returns None. Lenient behavoir required for CI tests, + per comment: + https://github.com/stan-dev/cmdstanpy/pull/321#issuecomment-733817554 + """ + try: + makefile = os.path.join(cmdstan_path(), 'makefile') + except ValueError as e: + get_logger().info('No CmdStan installation found.') + get_logger().debug("%s", e) + return None + + if not os.path.exists(makefile): + get_logger().info( + 'CmdStan installation %s missing makefile, cannot get version.', + cmdstan_path(), + ) + return None + + with open(makefile, 'r') as fd: + contents = fd.read() + + start_idx = contents.find('CMDSTAN_VERSION := ') + if start_idx < 0: + get_logger().info( + 'Cannot parse version from makefile: %s.', + makefile, + ) + return None + + start_idx += len('CMDSTAN_VERSION := ') + end_idx = contents.find('\n', start_idx) + + version = contents[start_idx:end_idx] + splits = version.split('.') + if len(splits) != 3: + get_logger().info( + 'Cannot parse version, expected "..", ' + 'found: "%s".', + version, + ) + return None + return tuple(int(x) for x in splits[0:2]) + + +def cmdstan_version_before( + major: int, minor: int, info: Optional[Dict[str, str]] = None +) -> bool: + """ + Check that CmdStan version is less than Major.minor version. + + :param major: Major version number + :param minor: Minor version number + + :return: True if version at or above major.minor, else False. + """ + cur_version = None + if info is None or 'stan_version_major' not in info: + cur_version = cmdstan_version() + else: + cur_version = ( + int(info['stan_version_major']), + int(info['stan_version_minor']), + ) + if cur_version is None: + get_logger().info( + 'Cannot determine whether version is before %d.%d.', major, minor + ) + return False + if cur_version[0] < major or ( + cur_version[0] == major and cur_version[1] < minor + ): + return True + return False + + +def cxx_toolchain_path( + version: Optional[str] = None, install_dir: Optional[str] = None +) -> Tuple[str, ...]: + """ + Validate, then activate C++ toolchain directory path. + """ + if platform.system() != 'Windows': + raise RuntimeError( + 'Functionality is currently only supported on Windows' + ) + if version is not None and not isinstance(version, str): + raise TypeError('Format version number as a string') + logger = get_logger() + if 'CMDSTAN_TOOLCHAIN' in os.environ: + toolchain_root = os.environ['CMDSTAN_TOOLCHAIN'] + if os.path.exists(os.path.join(toolchain_root, 'mingw64')): + compiler_path = os.path.join( + toolchain_root, + 'mingw64' if (sys.maxsize > 2**32) else 'mingw32', + 'bin', + ) + if os.path.exists(compiler_path): + tool_path = os.path.join(toolchain_root, 'usr', 'bin') + if not os.path.exists(tool_path): + tool_path = '' + compiler_path = '' + logger.warning( + 'Found invalid installion for RTools40 on %s', + toolchain_root, + ) + toolchain_root = '' + else: + compiler_path = '' + logger.warning( + 'Found invalid installion for RTools40 on %s', + toolchain_root, + ) + toolchain_root = '' + + elif os.path.exists(os.path.join(toolchain_root, 'mingw_64')): + compiler_path = os.path.join( + toolchain_root, + 'mingw_64' if (sys.maxsize > 2**32) else 'mingw_32', + 'bin', + ) + if os.path.exists(compiler_path): + tool_path = os.path.join(toolchain_root, 'bin') + if not os.path.exists(tool_path): + tool_path = '' + compiler_path = '' + logger.warning( + 'Found invalid installion for RTools35 on %s', + toolchain_root, + ) + toolchain_root = '' + else: + compiler_path = '' + logger.warning( + 'Found invalid installion for RTools35 on %s', + toolchain_root, + ) + toolchain_root = '' + else: + rtools40_home = os.environ.get('RTOOLS40_HOME') + cmdstan_dir = os.path.expanduser(os.path.join('~', _DOT_CMDSTAN)) + for toolchain_root in ( + ([rtools40_home] if rtools40_home is not None else []) + + ( + [ + os.path.join(install_dir, 'RTools40'), + os.path.join(install_dir, 'RTools35'), + os.path.join(install_dir, 'RTools30'), + os.path.join(install_dir, 'RTools'), + ] + if install_dir is not None + else [] + ) + + [ + os.path.join(cmdstan_dir, 'RTools40'), + os.path.join(os.path.abspath("/"), "RTools40"), + os.path.join(cmdstan_dir, 'RTools35'), + os.path.join(os.path.abspath("/"), "RTools35"), + os.path.join(cmdstan_dir, 'RTools'), + os.path.join(os.path.abspath("/"), "RTools"), + os.path.join(os.path.abspath("/"), "RBuildTools"), + ] + ): + compiler_path = '' + tool_path = '' + + if os.path.exists(toolchain_root): + if version not in ('35', '3.5', '3'): + compiler_path = os.path.join( + toolchain_root, + 'mingw64' if (sys.maxsize > 2**32) else 'mingw32', + 'bin', + ) + if os.path.exists(compiler_path): + tool_path = os.path.join(toolchain_root, 'usr', 'bin') + if not os.path.exists(tool_path): + tool_path = '' + compiler_path = '' + logger.warning( + 'Found invalid installation for RTools40 on %s', + toolchain_root, + ) + toolchain_root = '' + else: + break + else: + compiler_path = '' + logger.warning( + 'Found invalid installation for RTools40 on %s', + toolchain_root, + ) + toolchain_root = '' + else: + compiler_path = os.path.join( + toolchain_root, + 'mingw_64' if (sys.maxsize > 2**32) else 'mingw_32', + 'bin', + ) + if os.path.exists(compiler_path): + tool_path = os.path.join(toolchain_root, 'bin') + if not os.path.exists(tool_path): + tool_path = '' + compiler_path = '' + logger.warning( + 'Found invalid installation for RTools35 on %s', + toolchain_root, + ) + toolchain_root = '' + else: + break + else: + compiler_path = '' + logger.warning( + 'Found invalid installation for RTools35 on %s', + toolchain_root, + ) + toolchain_root = '' + else: + toolchain_root = '' + + if not toolchain_root: + raise ValueError( + 'no RTools toolchain installation found, ' + 'run command line script ' + '"python -m cmdstanpy.install_cxx_toolchain"' + ) + logger.info('Add C++ toolchain to $PATH: %s', toolchain_root) + os.environ['PATH'] = ';'.join( + list( + OrderedDict.fromkeys( + [compiler_path, tool_path] + os.getenv('PATH', '').split(';') + ) + ) + ) + return compiler_path, tool_path + + +def install_cmdstan( + version: Optional[str] = None, + dir: Optional[str] = None, + overwrite: bool = False, + compiler: bool = False, + progress: bool = False, + verbose: bool = False, + cores: int = 1, + *, + interactive: bool = False, +) -> bool: + """ + Download and install a CmdStan release from GitHub. Downloads the release + tar.gz file to temporary storage. Retries GitHub requests in order + to allow for transient network outages. Builds CmdStan executables + and tests the compiler by building example model ``bernoulli.stan``. + + :param version: CmdStan version string, e.g. "2.29.2". + Defaults to latest CmdStan release. + If ``git`` is installed, a git tag or branch of stan-dev/cmdstan + can be specified, e.g. "git:develop". + + :param dir: Path to install directory. Defaults to hidden directory + ``$HOME/.cmdstan``. + If no directory is specified and the above directory does not + exist, directory ``$HOME/.cmdstan`` will be created and populated. + + :param overwrite: Boolean value; when ``True``, will overwrite and + rebuild an existing CmdStan installation. Default is ``False``. + + :param compiler: Boolean value; when ``True`` on WINDOWS ONLY, use the + C++ compiler from the ``install_cxx_toolchain`` command or install + one if none is found. + + :param progress: Boolean value; when ``True``, show a progress bar for + downloading and unpacking CmdStan. Default is ``False``. + + :param verbose: Boolean value; when ``True``, show console output from all + intallation steps, i.e., download, build, and test CmdStan release. + Default is ``False``. + :param cores: Integer, number of cores to use in the ``make`` command. + Default is 1 core. + + :param interactive: Boolean value; if true, ignore all other arguments + to this function and run in an interactive mode, prompting the user + to provide the other information manually through the standard input. + + This flag should only be used in interactive environments, + e.g. on the command line. + + :return: Boolean value; ``True`` for success. + """ + logger = get_logger() + try: + from ..install_cmdstan import ( + InstallationSettings, + InteractiveSettings, + run_install, + ) + + args: Union[InstallationSettings, InteractiveSettings] + + if interactive: + if any( + [ + version, + dir, + overwrite, + compiler, + progress, + verbose, + cores != 1, + ] + ): + logger.warning( + "Interactive installation requested but other arguments" + " were used.\n\tThese values will be ignored!" + ) + args = InteractiveSettings() + else: + args = InstallationSettings( + version=version, + overwrite=overwrite, + verbose=verbose, + compiler=compiler, + progress=progress, + dir=dir, + cores=cores, + ) + run_install(args) + # pylint: disable=broad-except + except Exception as e: + logger.warning('CmdStan installation failed.\n%s', str(e)) + return False + + if 'git:' in args.version: + folder = f"cmdstan-{args.version.replace(':', '-').replace('/', '_')}" + else: + folder = f"cmdstan-{args.version}" + set_cmdstan_path(os.path.join(args.dir, folder)) + + return True + + +@progbar.wrap_callback +def wrap_url_progress_hook() -> Optional[Callable[[int, int, int], None]]: + """Sets up tqdm callback for url downloads.""" + pbar: tqdm = tqdm( + unit='B', + unit_scale=True, + unit_divisor=1024, + colour='blue', + leave=False, + ) + + def download_progress_hook( + count: int, block_size: int, total_size: int + ) -> None: + if pbar.total is None: + pbar.total = total_size + pbar.reset() + downloaded_size = count * block_size + pbar.update(downloaded_size - pbar.n) + if pbar.n >= total_size: + pbar.close() + + return download_progress_hook diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/command.py b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/command.py new file mode 100644 index 00000000..ca95983e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/command.py @@ -0,0 +1,94 @@ +""" +Run commands and handle returncodes +""" +import os +import subprocess +import sys +from typing import Callable, List, Optional, TextIO + +from .filesystem import pushd +from .logging import get_logger + + +def do_command( + cmd: List[str], + cwd: Optional[str] = None, + *, + fd_out: Optional[TextIO] = sys.stdout, + pbar: Optional[Callable[[str], None]] = None, +) -> None: + """ + Run command as subprocess, polls process output pipes and + either streams outputs to supplied output stream or sends + each line (stripped) to the supplied progress bar callback hook. + + Raises ``RuntimeError`` on non-zero return code or execption ``OSError``. + + :param cmd: command and args. + :param cwd: directory in which to run command, if unspecified, + run command in the current working directory. + :param fd_out: when supplied, streams to this output stream, + else writes to sys.stdout. + :param pbar: optional callback hook to tqdm, which takes + single ``str`` arguent, see: + https://github.com/tqdm/tqdm#hooks-and-callbacks. + + """ + get_logger().debug('cmd: %s\ncwd: %s', ' '.join(cmd), cwd) + try: + # NB: Using this rather than cwd arg to Popen due to windows behavior + with pushd(cwd if cwd is not None else '.'): + # TODO: replace with subprocess.run in later Python versions? + proc = subprocess.Popen( + cmd, + bufsize=1, + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, # avoid buffer overflow + env=os.environ, + universal_newlines=True, + ) + while proc.poll() is None: + if proc.stdout is not None: + line = proc.stdout.readline() + if fd_out is not None: + fd_out.write(line) + if pbar is not None: + pbar(line.strip()) + + stdout, _ = proc.communicate() + if stdout: + if len(stdout) > 0: + if fd_out is not None: + fd_out.write(stdout) + if pbar is not None: + pbar(stdout.strip()) + + if proc.returncode != 0: # throw RuntimeError + msg + serror = '' + try: + serror = os.strerror(proc.returncode) + except (ArithmeticError, ValueError): + pass + msg = 'Command {}\n\t{} {}'.format( + cmd, returncode_msg(proc.returncode), serror + ) + raise RuntimeError(msg) + except OSError as e: + msg = 'Command: {}\nfailed with error {}\n'.format(cmd, str(e)) + raise RuntimeError(msg) from e + + +def returncode_msg(retcode: int) -> str: + """interpret retcode""" + if retcode < 0: + sig = -1 * retcode + return f'terminated by signal {sig}' + if retcode <= 125: + return 'error during processing' + if retcode == 126: # shouldn't happen + return '' + if retcode == 127: + return 'program not found' + sig = retcode - 128 + return f'terminated by signal {sig}' diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/data_munging.py b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/data_munging.py new file mode 100644 index 00000000..495d40a5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/data_munging.py @@ -0,0 +1,44 @@ +""" +Common functions for reshaping numpy arrays +""" +from typing import Hashable, MutableMapping, Tuple + +import numpy as np +import stanio + + +def flatten_chains(draws_array: np.ndarray) -> np.ndarray: + """ + Flatten a 3D array of draws X chains X variable into 2D array + where all chains are concatenated into a single column. + + :param draws_array: 3D array of draws + """ + if len(draws_array.shape) != 3: + raise ValueError( + 'Expecting 3D array, found array with {} dims'.format( + len(draws_array.shape) + ) + ) + + num_rows = draws_array.shape[0] * draws_array.shape[1] + num_cols = draws_array.shape[2] + return draws_array.reshape((num_rows, num_cols), order='F') + + +def build_xarray_data( + data: MutableMapping[Hashable, Tuple[Tuple[str, ...], np.ndarray]], + var: stanio.Variable, + drawset: np.ndarray, +) -> None: + """ + Adds Stan variable name, labels, and values to a dictionary + that will be used to construct an xarray DataSet. + """ + var_dims: Tuple[str, ...] = ('draw', 'chain') + var_dims += tuple(f"{var.name}_dim_{i}" for i in range(len(var.dimensions))) + + data[var.name] = ( + var_dims, + var.extract_reshape(drawset), + ) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/filesystem.py b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/filesystem.py new file mode 100644 index 00000000..233898e1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/filesystem.py @@ -0,0 +1,236 @@ +""" +Utilities for interacting with the filesystem on multiple platforms +""" +import contextlib +import os +import platform +import re +import shutil +import tempfile +from typing import Any, Iterator, List, Mapping, Optional, Tuple, Union + +from cmdstanpy import _TMPDIR + +from .json import write_stan_json +from .logging import get_logger + +EXTENSION = '.exe' if platform.system() == 'Windows' else '' + + +def windows_short_path(path: str) -> str: + """ + Gets the short path name of a given long path. + http://stackoverflow.com/a/23598461/200291 + + On non-Windows platforms, returns the path + + If (base)path does not exist, function raises RuntimeError + """ + if platform.system() != 'Windows': + return path + + if os.path.isfile(path) or ( + not os.path.isdir(path) and os.path.splitext(path)[1] != '' + ): + base_path, file_name = os.path.split(path) + else: + base_path, file_name = path, '' + + if not os.path.exists(base_path): + raise RuntimeError( + 'Windows short path function needs a valid directory. ' + 'Base directory does not exist: "{}"'.format(base_path) + ) + + import ctypes + from ctypes import wintypes + + # pylint: disable=invalid-name + _GetShortPathNameW = ( + ctypes.windll.kernel32.GetShortPathNameW # type: ignore + ) + + _GetShortPathNameW.argtypes = [ + wintypes.LPCWSTR, + wintypes.LPWSTR, + wintypes.DWORD, + ] + _GetShortPathNameW.restype = wintypes.DWORD + + output_buf_size = 0 + while True: + output_buf = ctypes.create_unicode_buffer(output_buf_size) + needed = _GetShortPathNameW(base_path, output_buf, output_buf_size) + if output_buf_size >= needed: + short_base_path = output_buf.value + break + else: + output_buf_size = needed + + short_path = ( + os.path.join(short_base_path, file_name) + if file_name + else short_base_path + ) + return short_path + + +def create_named_text_file( + dir: str, prefix: str, suffix: str, name_only: bool = False +) -> str: + """ + Create a named unique file, return filename. + Flag 'name_only' will create then delete the tmp file; + this lets us create filename args for commands which + disallow overwriting existing files (e.g., 'stansummary'). + """ + fd = tempfile.NamedTemporaryFile( + mode='w+', prefix=prefix, suffix=suffix, dir=dir, delete=name_only + ) + path = fd.name + fd.close() + return path + + +@contextlib.contextmanager +def pushd(new_dir: str) -> Iterator[None]: + """Acts like pushd/popd.""" + previous_dir = os.getcwd() + os.chdir(new_dir) + try: + yield + finally: + os.chdir(previous_dir) + + +def _temp_single_json( + data: Union[str, os.PathLike, Mapping[str, Any], None] +) -> Iterator[Optional[str]]: + """Context manager for json files.""" + if data is None: + yield None + return + if isinstance(data, (str, os.PathLike)): + yield str(data) + return + + data_file = create_named_text_file(dir=_TMPDIR, prefix='', suffix='.json') + get_logger().debug('input tempfile: %s', data_file) + write_stan_json(data_file, data) + try: + yield data_file + finally: + with contextlib.suppress(PermissionError): + os.remove(data_file) + + +temp_single_json = contextlib.contextmanager(_temp_single_json) + + +def _temp_multiinput( + input: Union[str, os.PathLike, Mapping[str, Any], List[Any], None], + base: int = 1, +) -> Iterator[Optional[str]]: + if isinstance(input, list): + # most complicated case: list of inits + # for multiple chains, we need to create multiple files + # which look like somename_{i}.json and then pass somename.json + # to CmdStan + + mother_file = create_named_text_file( + dir=_TMPDIR, prefix='', suffix='.json', name_only=True + ) + new_files = [ + os.path.splitext(mother_file)[0] + f'_{i+base}.json' + for i in range(len(input)) + ] + for init, file in zip(input, new_files): + if isinstance(init, dict): + write_stan_json(file, init) + elif isinstance(init, str): + shutil.copy(init, file) + else: + raise ValueError( + 'A list of inits must contain dicts or strings, not' + + str(type(init)) + ) + try: + yield mother_file + finally: + for file in new_files: + with contextlib.suppress(PermissionError): + os.remove(file) + else: + yield from _temp_single_json(input) + + +@contextlib.contextmanager +def temp_inits( + inits: Union[ + str, os.PathLike, Mapping[str, Any], float, int, List[Any], None + ], + *, + allow_multiple: bool = True, + id: int = 1, +) -> Iterator[Union[str, float, int, None]]: + if isinstance(inits, (float, int)): + yield inits + return + if allow_multiple: + yield from _temp_multiinput(inits, base=id) + else: + if isinstance(inits, list): + raise ValueError('Expected single initialization, got list') + yield from _temp_single_json(inits) + + +class SanitizedOrTmpFilePath: + """ + Context manager for tmpfiles, handles special characters in filepath. + """ + + UNIXISH_PATTERN = re.compile(r"[\s~]") + WINDOWS_PATTERN = re.compile(r"\s") + + @classmethod + def _has_special_chars(cls, file_path: str) -> bool: + if platform.system() == "Windows": + return bool(cls.WINDOWS_PATTERN.search(file_path)) + return bool(cls.UNIXISH_PATTERN.search(file_path)) + + def __init__(self, file_path: str): + self._tmpdir = None + + if self._has_special_chars(os.path.abspath(file_path)): + base_path, file_name = os.path.split(os.path.abspath(file_path)) + os.makedirs(base_path, exist_ok=True) + try: + short_base_path = windows_short_path(base_path) + if os.path.exists(short_base_path): + file_path = os.path.join(short_base_path, file_name) + except RuntimeError: + pass + + if self._has_special_chars(os.path.abspath(file_path)): + tmpdir = tempfile.mkdtemp() + if self._has_special_chars(tmpdir): + raise RuntimeError( + 'Unable to generate temporary path without spaces or ' + 'special characters! \n Please move your stan file to a ' + 'location without spaces or special characters.' + ) + + _, path = tempfile.mkstemp(suffix='.stan', dir=tmpdir) + + shutil.copy(file_path, path) + self._path = path + self._tmpdir = tmpdir + else: + self._path = file_path + + def __enter__(self) -> Tuple[str, bool]: + return self._path, self._tmpdir is not None + + def __exit__(self, exc_type, exc_val, exc_tb) -> None: # type: ignore + if self._tmpdir: + shutil.rmtree(self._tmpdir, ignore_errors=True) diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/json.py b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/json.py new file mode 100644 index 00000000..ce1674e6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/json.py @@ -0,0 +1,6 @@ +""" +Delegated to stanio - https://github.com/WardBrian/stanio +""" +from stanio import write_stan_json + +__all__ = ['write_stan_json'] diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/logging.py b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/logging.py new file mode 100644 index 00000000..6f33ec85 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/logging.py @@ -0,0 +1,25 @@ +""" +CmdStanPy logging +""" +import functools +import logging + + +@functools.lru_cache(maxsize=None) +def get_logger() -> logging.Logger: + """cmdstanpy logger""" + logger = logging.getLogger('cmdstanpy') + if len(logger.handlers) == 0: + # send all messages to handlers + logger.setLevel(logging.DEBUG) + # add a default handler to the logger to INFO and higher + handler = logging.StreamHandler() + handler.setLevel(logging.INFO) + handler.setFormatter( + logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s', + "%H:%M:%S", + ) + ) + logger.addHandler(handler) + return logger diff --git a/.venv/lib/python3.12/site-packages/cmdstanpy/utils/stancsv.py b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/stancsv.py new file mode 100644 index 00000000..b7a3b21c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/cmdstanpy/utils/stancsv.py @@ -0,0 +1,486 @@ +""" +Utility functions for reading the Stan CSV format +""" +import json +import math +import re +from typing import Any, Dict, List, MutableMapping, Optional, TextIO, Union + +import numpy as np +import pandas as pd + +from cmdstanpy import _CMDSTAN_SAMPLING, _CMDSTAN_THIN, _CMDSTAN_WARMUP + + +def check_sampler_csv( + path: str, + is_fixed_param: bool = False, + iter_sampling: Optional[int] = None, + iter_warmup: Optional[int] = None, + save_warmup: bool = False, + thin: Optional[int] = None, +) -> Dict[str, Any]: + """Capture essential config, shape from stan_csv file.""" + meta = scan_sampler_csv(path, is_fixed_param) + if thin is None: + thin = _CMDSTAN_THIN + elif thin > _CMDSTAN_THIN: + if 'thin' not in meta: + raise ValueError( + 'bad Stan CSV file {}, ' + 'config error, expected thin = {}'.format(path, thin) + ) + if meta['thin'] != thin: + raise ValueError( + 'bad Stan CSV file {}, ' + 'config error, expected thin = {}, found {}'.format( + path, thin, meta['thin'] + ) + ) + draws_sampling = iter_sampling + if draws_sampling is None: + draws_sampling = _CMDSTAN_SAMPLING + draws_warmup = iter_warmup + if draws_warmup is None: + draws_warmup = _CMDSTAN_WARMUP + draws_warmup = int(math.ceil(draws_warmup / thin)) + draws_sampling = int(math.ceil(draws_sampling / thin)) + if meta['draws_sampling'] != draws_sampling: + raise ValueError( + 'bad Stan CSV file {}, expected {} draws, found {}'.format( + path, draws_sampling, meta['draws_sampling'] + ) + ) + if save_warmup: + if not ('save_warmup' in meta and meta['save_warmup'] in (1, 'true')): + raise ValueError( + 'bad Stan CSV file {}, ' + 'config error, expected save_warmup = 1'.format(path) + ) + if meta['draws_warmup'] != draws_warmup: + raise ValueError( + 'bad Stan CSV file {}, ' + 'expected {} warmup draws, found {}'.format( + path, draws_warmup, meta['draws_warmup'] + ) + ) + return meta + + +def scan_sampler_csv(path: str, is_fixed_param: bool = False) -> Dict[str, Any]: + """Process sampler stan_csv output file line by line.""" + dict: Dict[str, Any] = {} + lineno = 0 + with open(path, 'r') as fd: + try: + lineno = scan_config(fd, dict, lineno) + lineno = scan_column_names(fd, dict, lineno) + if not is_fixed_param: + lineno = scan_warmup_iters(fd, dict, lineno) + lineno = scan_hmc_params(fd, dict, lineno) + lineno = scan_sampling_iters(fd, dict, lineno, is_fixed_param) + except ValueError as e: + raise ValueError("Error in reading csv file: " + path) from e + return dict + + +def scan_optimize_csv(path: str, save_iters: bool = False) -> Dict[str, Any]: + """Process optimizer stan_csv output file line by line.""" + dict: Dict[str, Any] = {} + lineno = 0 + # scan to find config, header, num saved iters + with open(path, 'r') as fd: + lineno = scan_config(fd, dict, lineno) + lineno = scan_column_names(fd, dict, lineno) + iters = 0 + for line in fd: + iters += 1 + if save_iters: + all_iters: np.ndarray = np.empty( + (iters, len(dict['column_names'])), dtype=float, order='F' + ) + # rescan to capture estimates + with open(path, 'r') as fd: + for i in range(lineno): + fd.readline() + for i in range(iters): + line = fd.readline().strip() + if len(line) < 1: + raise ValueError( + 'cannot parse CSV file {}, error at line {}'.format( + path, lineno + i + ) + ) + xs = line.split(',') + if save_iters: + all_iters[i, :] = [float(x) for x in xs] + if i == iters - 1: + mle: np.ndarray = np.array(xs, dtype=float) + # pylint: disable=possibly-used-before-assignment + dict['mle'] = mle + if save_iters: + dict['all_iters'] = all_iters + return dict + + +def scan_generic_csv(path: str) -> Dict[str, Any]: + """Process laplace stan_csv output file line by line.""" + dict: Dict[str, Any] = {} + lineno = 0 + with open(path, 'r') as fd: + lineno = scan_config(fd, dict, lineno) + lineno = scan_column_names(fd, dict, lineno) + return dict + + +def scan_variational_csv(path: str) -> Dict[str, Any]: + """Process advi stan_csv output file line by line.""" + dict: Dict[str, Any] = {} + lineno = 0 + with open(path, 'r') as fd: + lineno = scan_config(fd, dict, lineno) + lineno = scan_column_names(fd, dict, lineno) + line = fd.readline().lstrip(' #\t').rstrip() + lineno += 1 + if line.startswith('Stepsize adaptation complete.'): + line = fd.readline().lstrip(' #\t\n') + lineno += 1 + if not line.startswith('eta'): + raise ValueError( + 'line {}: expecting eta, found:\n\t "{}"'.format( + lineno, line + ) + ) + _, eta = line.split('=') + dict['eta'] = float(eta) + line = fd.readline().lstrip(' #\t\n') + lineno += 1 + xs = line.split(',') + variational_mean = [float(x) for x in xs] + dict['variational_mean'] = np.array(variational_mean) + dict['variational_sample'] = pd.read_csv( + path, + comment='#', + skiprows=lineno, + header=None, + float_precision='high', + ).to_numpy() + return dict + + +def scan_config(fd: TextIO, config_dict: Dict[str, Any], lineno: int) -> int: + """ + Scan initial stan_csv file comments lines and + save non-default configuration information to config_dict. + """ + cur_pos = fd.tell() + line = fd.readline().strip() + while len(line) > 0 and line.startswith('#'): + lineno += 1 + if line.endswith('(Default)'): + line = line.replace('(Default)', '') + line = line.lstrip(' #\t') + key_val = line.split('=') + if len(key_val) == 2: + if key_val[0].strip() == 'file' and not key_val[1].endswith('csv'): + config_dict['data_file'] = key_val[1].strip() + elif key_val[0].strip() != 'file': + raw_val = key_val[1].strip() + val: Union[int, float, str] + try: + val = int(raw_val) + except ValueError: + try: + val = float(raw_val) + except ValueError: + if raw_val == "true": + val = 1 + elif raw_val == "false": + val = 0 + else: + val = raw_val + config_dict[key_val[0].strip()] = val + cur_pos = fd.tell() + line = fd.readline().strip() + fd.seek(cur_pos) + return lineno + + +def scan_warmup_iters( + fd: TextIO, config_dict: Dict[str, Any], lineno: int +) -> int: + """ + Check warmup iterations, if any. + """ + if 'save_warmup' not in config_dict: + return lineno + cur_pos = fd.tell() + line = fd.readline().strip() + draws_found = 0 + while len(line) > 0 and not line.startswith('#'): + lineno += 1 + draws_found += 1 + cur_pos = fd.tell() + line = fd.readline().strip() + fd.seek(cur_pos) + config_dict['draws_warmup'] = draws_found + return lineno + + +def scan_column_names( + fd: TextIO, config_dict: MutableMapping[str, Any], lineno: int +) -> int: + """ + Process columns header, add to config_dict as 'column_names' + """ + line = fd.readline().strip() + lineno += 1 + config_dict['raw_header'] = line.strip() + names = line.split(',') + config_dict['column_names'] = tuple(munge_varnames(names)) + return lineno + + +def munge_varname(name: str) -> str: + if '.' not in name and ':' not in name: + return name + + tuple_parts = name.split(':') + for i, part in enumerate(tuple_parts): + if '.' not in part: + continue + part = part.replace('.', '[', 1) + part = part.replace('.', ',') + part += ']' + tuple_parts[i] = part + + return '.'.join(tuple_parts) + + +def munge_varnames(names: List[str]) -> List[str]: + """ + Change formatting for indices of container var elements + from use of dot separator to array-like notation, e.g., + rewrite label ``y_forecast.2.4`` to ``y_forecast[2,4]``. + """ + if names is None: + raise ValueError('missing argument "names"') + return [munge_varname(name) for name in names] + + +def scan_hmc_params( + fd: TextIO, config_dict: Dict[str, Any], lineno: int +) -> int: + """ + Scan step size, metric from stan_csv file comment lines. + """ + metric = config_dict['metric'] + line = fd.readline().strip() + lineno += 1 + if not line == '# Adaptation terminated': + raise ValueError( + 'line {}: expecting metric, found:\n\t "{}"'.format(lineno, line) + ) + line = fd.readline().strip() + lineno += 1 + label, step_size = line.split('=') + if not label.startswith('# Step size'): + raise ValueError( + 'line {}: expecting step size, ' + 'found:\n\t "{}"'.format(lineno, line) + ) + try: + float(step_size.strip()) + except ValueError as e: + raise ValueError( + 'line {}: invalid step size: {}'.format(lineno, step_size) + ) from e + before_metric = fd.tell() + line = fd.readline().strip() + lineno += 1 + if metric == 'unit_e': + if line.startswith("# No free parameters"): + return lineno + else: + fd.seek(before_metric) + return lineno - 1 + + if not ( + ( + metric == 'diag_e' + and line == '# Diagonal elements of inverse mass matrix:' + ) + or ( + metric == 'dense_e' and line == '# Elements of inverse mass matrix:' + ) + ): + raise ValueError( + 'line {}: invalid or missing mass matrix ' + 'specification'.format(lineno) + ) + line = fd.readline().lstrip(' #\t') + lineno += 1 + num_unconstrained_params = len(line.split(',')) + if metric == 'diag_e': + return lineno + else: + for _ in range(1, num_unconstrained_params): + line = fd.readline().lstrip(' #\t') + lineno += 1 + if len(line.split(',')) != num_unconstrained_params: + raise ValueError( + 'line {}: invalid or missing mass matrix ' + 'specification'.format(lineno) + ) + return lineno + + +def scan_sampling_iters( + fd: TextIO, config_dict: Dict[str, Any], lineno: int, is_fixed_param: bool +) -> int: + """ + Parse sampling iteration, save number of iterations to config_dict. + Also save number of divergences, max_treedepth hits + """ + draws_found = 0 + num_cols = len(config_dict['column_names']) + if not is_fixed_param: + idx_divergent = config_dict['column_names'].index('divergent__') + idx_treedepth = config_dict['column_names'].index('treedepth__') + max_treedepth = config_dict['max_depth'] + ct_divergences = 0 + ct_max_treedepth = 0 + + cur_pos = fd.tell() + line = fd.readline().strip() + while len(line) > 0 and not line.startswith('#'): + lineno += 1 + draws_found += 1 + data = line.split(',') + if len(data) != num_cols: + raise ValueError( + 'line {}: bad draw, expecting {} items, found {}\n'.format( + lineno, num_cols, len(line.split(',')) + ) + + 'This error could be caused by running out of disk space.\n' + 'Try clearing up TEMP or setting output_dir to a path' + ' on another drive.', + ) + cur_pos = fd.tell() + line = fd.readline().strip() + if not is_fixed_param: + ct_divergences += int(data[idx_divergent]) # type: ignore + if int(data[idx_treedepth]) == max_treedepth: # type: ignore + ct_max_treedepth += 1 + + fd.seek(cur_pos) + config_dict['draws_sampling'] = draws_found + if not is_fixed_param: + config_dict['ct_divergences'] = ct_divergences + config_dict['ct_max_treedepth'] = ct_max_treedepth + return lineno + + +def read_metric(path: str) -> List[int]: + """ + Read metric file in JSON or Rdump format. + Return dimensions of entry "inv_metric". + """ + if path.endswith('.json'): + with open(path, 'r') as fd: + metric_dict = json.load(fd) + if 'inv_metric' in metric_dict: + dims_np: np.ndarray = np.asarray(metric_dict['inv_metric']) + return list(dims_np.shape) + else: + raise ValueError( + 'metric file {}, bad or missing' + ' entry "inv_metric"'.format(path) + ) + else: + dims = list(read_rdump_metric(path)) + if dims is None: + raise ValueError( + 'metric file {}, bad or missing' + ' entry "inv_metric"'.format(path) + ) + return dims + + +def read_rdump_metric(path: str) -> List[int]: + """ + Find dimensions of variable named 'inv_metric' in Rdump data file. + """ + metric_dict = rload(path) + if metric_dict is None or not ( + 'inv_metric' in metric_dict + and isinstance(metric_dict['inv_metric'], np.ndarray) + ): + raise ValueError( + 'metric file {}, bad or missing entry "inv_metric"'.format(path) + ) + return list(metric_dict['inv_metric'].shape) + + +def rload(fname: str) -> Optional[Dict[str, Union[int, float, np.ndarray]]]: + """Parse data and parameter variable values from an R dump format file. + This parser only supports the subset of R dump data as described + in the "Dump Data Format" section of the CmdStan manual, i.e., + scalar, vector, matrix, and array data types. + """ + data_dict = {} + with open(fname, 'r') as fd: + lines = fd.readlines() + # Variable data may span multiple lines, parse accordingly + idx = 0 + while idx < len(lines) and '<-' not in lines[idx]: + idx += 1 + if idx == len(lines): + return None + start_idx = idx + idx += 1 + while True: + while idx < len(lines) and '<-' not in lines[idx]: + idx += 1 + next_var = idx + var_data = ''.join(lines[start_idx:next_var]).replace('\n', '') + lhs, rhs = [item.strip() for item in var_data.split('<-')] + lhs = lhs.replace('"', '') # strip optional Jags double quotes + rhs = rhs.replace('L', '') # strip R long int qualifier + data_dict[lhs] = parse_rdump_value(rhs) + if idx == len(lines): + break + start_idx = next_var + idx += 1 + return data_dict + + +def parse_rdump_value(rhs: str) -> Union[int, float, np.ndarray]: + """Process right hand side of Rdump variable assignment statement. + Value is either scalar, vector, or multi-dim structure. + Use regex to capture structure values, dimensions. + """ + pat = re.compile( + r'structure\(\s*c\((?P[^)]*)\)' + r'(,\s*\.Dim\s*=\s*c\s*\((?P[^)]*)\s*\))?\)' + ) + val: Union[int, float, np.ndarray] + try: + if rhs.startswith('structure'): + parse = pat.match(rhs) + if parse is None or parse.group('vals') is None: + raise ValueError(rhs) + vals = [float(v) for v in parse.group('vals').split(',')] + val = np.array(vals, order='F') + if parse.group('dims') is not None: + dims = [int(v) for v in parse.group('dims').split(',')] + val = np.array(vals).reshape(dims, order='F') + elif rhs.startswith('c(') and rhs.endswith(')'): + val = np.array([float(item) for item in rhs[2:-1].split(',')]) + elif '.' in rhs or 'e' in rhs: + val = float(rhs) + else: + val = int(rhs) + except TypeError as e: + raise ValueError('bad value in Rdump file: {}'.format(rhs)) from e + return val diff --git a/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/METADATA b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/METADATA new file mode 100644 index 00000000..86a99a2d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/METADATA @@ -0,0 +1,1815 @@ +Metadata-Version: 2.4 +Name: holidays +Version: 0.77 +Summary: Open World Holidays Framework +Author: Vacanza Team +Maintainer: Arkadii Yakovets, Panpakorn Siripanich, Serhii Murza +License-Expression: MIT +Project-URL: Documentation, https://holidays.readthedocs.io/en/latest/ +Project-URL: Repository, https://github.com/vacanza/holidays/ +Project-URL: Changelog, https://github.com/vacanza/holidays/releases/ +Keywords: holidays,calendar,l10n,worldwide,vacation +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Education +Classifier: Intended Audience :: End Users/Desktop +Classifier: Intended Audience :: Financial and Insurance Industry +Classifier: Intended Audience :: Information Technology +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Topic :: File Formats :: JSON +Classifier: Topic :: Office/Business :: Financial :: Accounting +Classifier: Topic :: Office/Business :: Financial :: Investment +Classifier: Topic :: Office/Business :: Scheduling +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +License-File: CONTRIBUTORS +License-File: LICENSE +Requires-Dist: python-dateutil +Dynamic: license-file + +# Holidays + +A fast, efficient Python library for generating country- and subdivision- (e.g. state or province) +specific sets of government-designated holidays on the fly. It aims to make determining whether a +specific date is a holiday as fast and flexible as possible. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PyPI + PyPI downloads PyPI version PyPI release date +
CI/CD + CI/CD status Documentation status +
Code + License Python supported versions Code style Code coverage +
GitHub + GitHub stars GitHub forks GitHub contributors GitHub last commit +
Citation + Open World Holidays Framework DOI +
Snyk + Open World Holidays Package Health Score +
+ +## Install + +The latest stable version can always be installed or updated via pip: + +``` shell +pip install --upgrade holidays +``` + +The latest development (dev) version can be installed directly from GitHub: + +``` shell +pip install --upgrade https://github.com/vacanza/holidays/tarball/dev +``` + +All new features are always first pushed to dev branch, then released on main branch upon official +version upgrades. + +## Documentation + +The documentation is hosted on [Read the Docs](https://holidays.readthedocs.io/). + +## Quick Start + +``` python +from datetime import date +import holidays + +us_holidays = holidays.US() # this is a dict-like object +# the below is the same, but takes a string: +us_holidays = holidays.country_holidays('US') # this is a dict-like object + +nyse_holidays = holidays.NYSE() # this is a dict-like object +# the below is the same, but takes a string: +nyse_holidays = holidays.financial_holidays('NYSE') # this is a dict-like object + +date(2015, 1, 1) in us_holidays # True +date(2015, 1, 2) in us_holidays # False +us_holidays.get('2014-01-01') # "New Year's Day" +``` + +The HolidayBase dict-like class will also recognize date strings and Unix timestamps: + +``` python +'2014-01-01' in us_holidays # True +'1/1/2014' in us_holidays # True +1388597445 in us_holidays # True +``` + +Some holidays may be only present in parts of a country: + +``` python +us_pr_holidays = holidays.country_holidays('US', subdiv='PR') +'2018-01-06' in us_holidays # False +'2018-01-06' in us_pr_holidays # True +``` + +Please see the [holidays documentation](https://holidays.readthedocs.io/) for additional examples +and detailed information. + +## Available Countries + +We currently support 223 country codes. The standard way to refer to a country is by using its [ISO +3166-1 alpha-2 code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes), the same used +for domain names, and for a subdivision its [ISO 3166-2 +code](https://en.wikipedia.org/wiki/ISO_3166-2). Some countries have common or foreign names or +abbreviations as aliases for their subdivisions. These are defined in the (optional) +`subdivisions_aliases` attribute. Some of the countries support more than one language for holiday +names output. A default language is defined by `default_language` (optional) attribute for each +entity and is used as a fallback when neither user specified language nor user locale language +available. The default language code is a [ISO 639-1 +code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). A list of all languages supported by +country is defined by `supported_languages` (optional) attribute. If there is no designated [ISO +639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) then [ISO 639-2 +code](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) can be used. + +Many countries have other categories of holidays in addition to common (national-wide) holidays: +bank holidays, school holidays, additional (paid or non-paid) holidays, holidays of state or public +employees, religious holidays (valid only for these religions followers). A list of all categories +supported by country is defined by `supported_categories` (optional) attribute. + +The following is a list of supported countries, their subdivisions followed by their aliases (if +any) in brackets, available languages and additional holiday categories. All countries support +**PUBLIC** holidays category by default. All other default values are highlighted with bold: + + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CountryCodeSubdivisionsSupported LanguagesSupported Categories
AfghanistanAFen_US, fa_AF, ps_AF
Aland IslandsAXCan also be loaded as country FI, subdivision 01en_US, fi, sv_FI, th, ukUNOFFICIAL, WORKDAY
AlbaniaALen_US, sq, uk
AlgeriaDZar, en_US, fr
American SamoaASCan also be loaded as country US, subdivision ASen_US, thGOVERNMENT, UNOFFICIAL
AndorraADParishes: 02 (Canillo), 03 (Encamp), 04 (La Massana), 05 (Ordino), 06 (Sant Julià de Lòria), 07 (Andorra la Vella), 08 (Escaldes-Engordany)ca, en_US, ukGOVERNMENT
AngolaAOen_US, pt_AO, uk
AnguillaAIen_AI, en_US
Antigua and BarbudaAG
ArgentinaARProvinces: A (Salta), B (Buenos Aires), C (Ciudad Autónoma de Buenos Aires), D (San Luis), E (Entre Ríos), F (La Rioja), G (Santiago del Estero), H (Chaco), J (San Juan), K (Catamarca), L (La Pampa), M (Mendoza), N (Misiones), P (Formosa), Q (Neuquén), R (Río Negro), S (Santa Fe), T (Tucumán), U (Chubut), V (Tierra del Fuego), W (Corrientes), X (Córdoba), Y (Jujuy), Z (Santa Cruz)en_US, es, ukARMENIAN, BANK, GOVERNMENT, HEBREW, ISLAMIC
ArmeniaAMen_US, hy
ArubaAWen_US, nl, pap_AW, uk
AustraliaAUStates and territories: ACT (Australian Capital Territory), NSW (New South Wales), NT (Northern Territory), QLD (Queensland), SA (South Australia), TAS (Tasmania), VIC (Victoria), WA (Western Australia)en_AU, en_US, thBANK, HALF_DAY
AustriaATStates: 1 (Burgenland, Bgld, B), 2 (Kärnten, Ktn, K), 3 (Niederösterreich, NÖ, N), 4 (Oberösterreich, OÖ, O), 5 (Salzburg, Sbg, S), 6 (Steiermark, Stmk, St), 7 (Tirol, T), 8 (Vorarlberg, Vbg, V), 9 (Wien, W)de, en_US, ukBANK
AzerbaijanAZaz, en_US, ukWORKDAY
BahamasBS
BahrainBHar, en_US
BangladeshBD
BarbadosBB
BelarusBYbe, en_US, ru, thWORKDAY
BelgiumBEde, en_US, fr, nl, ukBANK
BelizeBZ
BeninBJen_US, fr_BJWORKDAY
BermudaBMen_BM, en_US
BoliviaBODepartments: B (El Beni), C (Cochabamba), H (Chuquisaca), L (La Paz), N (Pando), O (Oruro), P (Potosí), S (Santa Cruz), T (Tarija)en_US, es, uk
Bonaire, Sint Eustatius and SabaBQSubdivisions: BON (Bonaire), SAB (Saba), STA (Sint Eustatius)en_BQ, en_US, nl, pap_BQ
Bosnia and HerzegovinaBAEntities and district: BIH (Federacija Bosne i Hercegovine, FBiH), BRC (Brčko distrikt, BD), SRP (Republika Srpska, RS)bs, en_US, sr, uk
BotswanaBW
BrazilBRStates: AC (Acre), AL (Alagoas), AM (Amazonas), AP (Amapá), BA (Bahia), CE (Ceará), DF (Distrito Federal), ES (Espírito Santo), GO (Goiás), MA (Maranhão), MG (Minas Gerais), MS (Mato Grosso do Sul), MT (Mato Grosso), PA (Pará), PB (Paraíba), PE (Pernambuco), PI (Piauí), PR (Paraná), RJ (Rio de Janeiro), RN (Rio Grande do Norte), RO (Rondônia), RR (Roraima), RS (Rio Grande do Sul), SC (Santa Catarina), SE (Sergipe), SP (São Paulo), TO (Tocantins)en_US, pt_BR, ukOPTIONAL
British Virgin IslandsVGen_US, en_VG
BruneiBNen_US, ms, th
BulgariaBGbg, en_US, ukSCHOOL
Burkina FasoBF
BurundiBI
Cabo VerdeCVMunicipalities: BR (Brava), BV (Boa Vista), CA (Santa Catarina), CF (Santa Catarina do Fogo), CR (Santa Cruz), MA (Maio), MO (Mosteiros), PA (Paul), PN (Porto Novo), PR (Praia), RB (Ribeira Brava), RG (Ribeira Grande), RS (Ribeira Grande de Santiago), SD (São Domingos), SF (São Filipe), SL (Sal), SM (São Miguel), SO (São Lourenço dos Órgãos), SS (São Salvador do Mundo), SV (São Vicente), TA (Tarrafal), TS (Tarrafal de São Nicolau)de, en_US, es, fr, pt_CVOPTIONAL
CambodiaKHen_US, km, th
CameroonCM
CanadaCAProvinces and territories: AB (Alberta), BC (British Columbia, Colombie-Britannique), MB (Manitoba), NB (New Brunswick, Nouveau-Brunswick), NL (Newfoundland and Labrador, Terre-Neuve-et-Labrador), NS (Nova Scotia, Nouvelle-Écosse), NT (Northwest Territories, Territoires du Nord-Ouest), NU (Nunavut), ON (Ontario), PE (Prince Edward Island, Île-du-Prince-Édouard), QC (Quebec, Québec), SK (Saskatchewan), YT (Yukon)ar, en_CA, en_US, fr, thGOVERNMENT, OPTIONAL
Cayman IslandsKYen_GB, en_US
Central African RepublicCFen_US, fr
ChadTD
ChileCLRegions: AI (Aisén del General Carlos Ibañez del Campo), AN (Antofagasta), AP (Arica y Parinacota), AR (La Araucanía), AT (Atacama), BI (Biobío), CO (Coquimbo), LI (Libertador General Bernardo O'Higgins), LL (Los Lagos), LR (Los Ríos), MA (Magallanes), ML (Maule), NB (Ñuble), RM (Región Metropolitana de Santiago), TA (Tarapacá), VS (Valparaíso)en_US, es, ukBANK
ChinaCNen_US, th, zh_CN, zh_TWHALF_DAY
Christmas IslandCXen_CX, en_US
Cocos IslandsCCcoa_CC, en_CC, en_US
ColombiaCOen_US, es, uk
CongoCGen_US, fr
Cook IslandsCKen_CK, en_US
Costa RicaCRen_US, es, ukOPTIONAL
CroatiaHRen_US, hr, uk
CubaCUen_US, es, uk
CuracaoCWen_US, nl, pap_CW, ukHALF_DAY
CyprusCYel, en_CY, en_US, ukBANK, OPTIONAL
CzechiaCZcs, en_US, sk, uk
DenmarkDKda, en_US, ukOPTIONAL
DjiboutiDJar, en_US, fr
DominicaDM
Dominican RepublicDOen_US, es, uk
DR CongoCDen_US, fr
EcuadorECen_US, es, uk
EgyptEGar, en_US
El SalvadorSVDepartments: AH (Ahuachapán), CA (Cabañas), CH (Chalatenango), CU (Cuscatlán), LI (La Libertad), MO (Morazán), PA (La Paz), SA (Santa Ana), SM (San Miguel), SO (Sonsonate), SS (San Salvador), SV (San Vicente), UN (La Unión), US (Usulután)en_US, es, uk
Equatorial GuineaGQProvinces: AN (Annobón, Annobon), BN (Bioko Norte, North Bioko), BS (Bioko Sur, South Bioko), CS (Centro Sur, South Center), DJ (Djibloho), KN (Kié-Ntem, Kie-Ntem), LI (Litoral, Coast), WN (Wele-Nzas)en_US, es
EstoniaEEen_US, et, uk
EswatiniSZ
EthiopiaETam, ar, en_ET, en_USWORKDAY
Falkland IslandsFKen_GB, en_USGOVERNMENT, WORKDAY
Faroe IslandsFOda, en_US, fo, is, no, svHALF_DAY
FijiFJWORKDAY
FinlandFIRegions: 01 (Ahvenanmaan maakunta, Landskapet Åland), 02 (Etelä-Karjala, Södra Karelen), 03 (Etelä-Pohjanmaa, Södra Österbotten), 04 (Etelä-Savo, Södra Savolax), 05 (Kainuu, Kajanaland), 06 (Kanta-Häme, Egentliga Tavastland), 07 (Keski-Pohjanmaa, Mellersta Österbotten), 08 (Keski-Suomi, Mellersta Finland), 09 (Kymenlaakso, Kymmenedalen), 10 (Lappi, Lappland), 11 (Pirkanmaa, Birkaland), 12 (Pohjanmaa, Österbotten), 13 (Pohjois-Karjala, Norra Karelen), 14 (Pohjois-Pohjanmaa, Norra Österbotten), 15 (Pohjois-Savo, Norra Savolax), 16 (Päijät-Häme, Päijänne-Tavastland), 17 (Satakunta), 18 (Uusimaa, Nyland), 19 (Varsinais-Suomi, Egentliga Finland)en_US, fi, sv_FI, th, ukUNOFFICIAL, WORKDAY
FranceFRDepartments/European Collectivity/DOM/ROM/TOM: 57 (Moselle), 6AE (Alsace), 971 (GP, GUA, Guadeloupe), 972 (MQ, Martinique), 973 (GY, Guyane), 974 (RE, LRE, La Réunion), 976 (YT, MAY, Mayotte), BL (Saint-Barthélemy), MF (Saint-Martin), NC (Nouvelle-Calédonie), PF (Polynésie Française), PM (Saint-Pierre-et-Miquelon), TF (Terres australes françaises), WF (Wallis-et-Futuna)en_US, fr, th, uk
French GuianaGFCan also be loaded as country FR, subdivision 973en_US, fr, th, uk
French PolynesiaPFCan also be loaded as country FR, subdivision PFen_US, fr, th, uk
French Southern TerritoriesTFCan also be loaded as country FR, subdivision TFen_US, fr, th, uk
GabonGA
GeorgiaGEen_US, ka, ukGOVERNMENT
GermanyDELands: BB (Brandenburg), BE (Berlin), BW (Baden-Württemberg), BY (Bayern), HB (Bremen), HE (Hessen), HH (Hamburg), MV (Mecklenburg-Vorpommern), NI (Niedersachsen), NW (Nordrhein-Westfalen), RP (Rheinland-Pfalz), SH (Schleswig-Holstein), SL (Saarland), SN (Sachsen), ST (Sachsen-Anhalt), TH (Thüringen)de, en_US, th, ukCATHOLIC
GhanaGH
GibraltarGIen_GB, en_US
GreeceGRel, en_US, ukHALF_DAY
GreenlandGLda, en_US, fi, is, kl, no, sv, ukOPTIONAL
GrenadaGDen_GD, en_US
GuadeloupeGPCan also be loaded as country FR, subdivision 971en_US, fr, th, uk
GuamGUCan also be loaded as country US, subdivision GUen_US, thGOVERNMENT, UNOFFICIAL
GuatemalaGTen_US, es
GuernseyGG
GuineaGNen_US, fr
GuyanaGYen_GY, en_US
HaitiHTen_US, es, fr_HT, htOPTIONAL
HondurasHNen_US, es, uk
Hong KongHKen_HK, en_US, th, zh_CN, zh_HKOPTIONAL
HungaryHUen_US, hu, uk
IcelandISen_US, is, ukHALF_DAY
IndiaINStates: AN (Andaman and Nicobar Islands), AP (Andhra Pradesh), AR (Arunachal Pradesh, Arunāchal Pradesh), AS (Assam), BR (Bihar, Bihār), CG (Chhattisgarh, Chhattīsgarh), CH (Chandigarh, Chandīgarh), DH (Dadra and Nagar Haveli and Daman and Diu, Dādra and Nagar Haveli and Damān and Diu), DL (Delhi), GA (Goa), GJ (Gujarat, Gujarāt), HP (Himachal Pradesh, Himāchal Pradesh), HR (Haryana, Haryāna), JH (Jharkhand, Jhārkhand), JK (Jammu and Kashmir, Jammu and Kashmīr), KA (Karnataka, Karnātaka), KL (Kerala), LA (Ladakh, Ladākh), LD (Lakshadweep), MH (Maharashtra, Mahārāshtra), ML (Meghalaya, Meghālaya), MN (Manipur), MP (Madhya Pradesh), MZ (Mizoram), NL (Nagaland, Nāgāland), OD (Odisha), PB (Punjab), PY (Puducherry), RJ (Rajasthan, Rājasthān), SK (Sikkim), TN (Tamil Nadu, Tamil Nādu), TR (Tripura), TS (Telangana, Telangāna), UK (Uttarakhand, Uttarākhand), UP (Uttar Pradesh), WB (West Bengal)en_IN, en_US, hiOPTIONAL
IndonesiaIDen_US, id, th, ukGOVERNMENT
IranIRen_US, fa_IR
IrelandIE
Isle of ManIMen_GB, en_US, th
IsraelILen_US, he, th, ukOPTIONAL, SCHOOL
ItalyITProvinces: AG (Agrigento), AL (Alessandria), AN (Ancona), AO (Aosta), AP (Ascoli Piceno), AQ (L'Aquila), AR (Arezzo), AT (Asti), AV (Avellino), BA (Bari), BG (Bergamo), BI (Biella), BL (Belluno), BN (Benevento), BO (Bologna), BR (Brindisi), BS (Brescia), BT (Barletta-Andria-Trani), BZ (Bolzano), CA (Cagliari), CB (Campobasso), CE (Caserta), CH (Chieti), CL (Caltanissetta), CN (Cuneo), CO (Como), CR (Cremona), CS (Cosenza), CT (Catania), CZ (Catanzaro), EN (Enna), FC (Forli-Cesena, Forlì-Cesena), FE (Ferrara), FG (Foggia), FI (Firenze), FM (Fermo), FR (Frosinone), GE (Genova), GO (Gorizia), GR (Grosseto), IM (Imperia), IS (Isernia), KR (Crotone), LC (Lecco), LE (Lecce), LI (Livorno), LO (Lodi), LT (Latina), LU (Lucca), MB (Monza e Brianza), MC (Macerata), ME (Messina), MI (Milano), MN (Mantova), MO (Modena), MS (Massa-Carrara), MT (Matera), NA (Napoli), NO (Novara), NU (Nuoro), OR (Oristano), PA (Palermo), PC (Piacenza), PD (Padova), PE (Pescara), PG (Perugia), PI (Pisa), PN (Pordenone), PO (Prato), PR (Parma), PT (Pistoia), PU (Pesaro e Urbino), PV (Pavia), PZ (Potenza), RA (Ravenna), RC (Reggio Calabria), RE (Reggio Emilia), RG (Ragusa), RI (Rieti), RM (Roma), RN (Rimini), RO (Rovigo), SA (Salerno), SI (Siena), SO (Sondrio), SP (La Spezia), SR (Siracusa), SS (Sassari), SU (Sud Sardegna), SV (Savona), TA (Taranto), TE (Teramo), TN (Trento), TO (Torino), TP (Trapani), TR (Terni), TS (Trieste), TV (Treviso), UD (Udine), VA (Varese), VB (Verbano-Cusio-Ossola), VC (Vercelli), VE (Venezia), VI (Vicenza), VR (Verona), VT (Viterbo), VV (Vibo Valentia); cities: Andria, Barletta, Cesena, Forli (Forlì), Pesaro, Trani, Urbino
Ivory CoastCIen_CI, en_US, fr
JamaicaJM
JapanJPen_US, ja, thBANK
JerseyJE
JordanJOar, en_US
KazakhstanKZen_US, kk, uk
KenyaKEen_KE, en_US, swHINDU, ISLAMIC
KuwaitKWar, en_US
KyrgyzstanKG
LaosLAen_US, lo, thBANK, SCHOOL, WORKDAY
LatviaLVen_US, lv, uk
LebanonLBar, en_USBANK, GOVERNMENT
LesothoLS
LibyaLYar, en_USWORKDAY
LiechtensteinLIde, en_US, ukBANK
LithuaniaLTen_US, lt, uk
LuxembourgLUde, en_US, fr, lb, uk
MacauMOHistorical municipalities: I (Concelho das Ilhas, 海島市, 海岛市), M (Concelho de Macau, 澳門市, 澳门市)en_MO, en_US, pt_MO, th, zh_CN, zh_MOGOVERNMENT, MANDATORY
MadagascarMGen_US, mg, uk
MalawiMW
MalaysiaMYStates and federal territories: 01 (Johor, JHR), 02 (Kedah, KDH), 03 (Kelantan, KTN), 04 (Melaka, MLK), 05 (Negeri Sembilan, NSN), 06 (Pahang, PHG), 07 (Pulau Pinang, PNG), 08 (Perak, PRK), 09 (Perlis, PLS), 10 (Selangor, SGR), 11 (Terengganu, TRG), 12 (Sabah, SBH), 13 (Sarawak, SWK), 14 (Wilayah Persekutuan Kuala Lumpur, KUL), 15 (Wilayah Persekutuan Labuan, LBN), 16 (Wilayah Persekutuan Putrajaya, PJY)en_US, ms_MY, th
MaldivesMV
MaliMLen_US, fr
MaltaMTen_US, mt
Marshall Islands (the)MH
MartiniqueMQCan also be loaded as country FR, subdivision 972en_US, fr, th, uk
MauritaniaMR
MauritiusMUen_MU, en_US
MayotteYTCan also be loaded as country FR, subdivision 976en_US, fr, th, uk
MexicoMXen_US, es, uk
MicronesiaFMStates: KSA (Kosrae, Kusaie), PNI (Pohnpei, Ponape), TRK (Chuuk, Truk), YAP (Yap)en_FM, en_US
MoldovaMDen_US, ro, uk
MonacoMCen_US, fr, uk
MongoliaMNen_US, mnWORKDAY
MontenegroMEcnr, en_US, ukCATHOLIC, HEBREW, ISLAMIC, ORTHODOX, WORKDAY
MontserratMSen_MS, en_US
MoroccoMAar, en_US, fr
MozambiqueMZen_US, pt_MZ, uk
NamibiaNAen_NA, en_US, uk
NauruNRen_NR, en_US
NepalNPWORKDAY
NetherlandsNLen_US, fy, nl, ukOPTIONAL
New CaledoniaNCCan also be loaded as country FR, subdivision NCen_US, fr, th, uk
New ZealandNZRegions and Special Island Authorities: AUK (Auckland, Tāmaki-Makaurau, AU), BOP (Bay of Plenty, Toi Moana, BP), CAN (Canterbury, Waitaha, CA), CIT (Chatham Islands Territory, Chatham Islands, Wharekauri, CI), GIS (Gisborne, Te Tairāwhiti, GI), HKB (Hawke's Bay, Te Matau-a-Māui, HB), MBH (Marlborough, MA), MWT (Manawatū Whanganui, Manawatū-Whanganui, MW), NSN (Nelson, Whakatū, NE), NTL (Northland, Te Taitokerau, NO), OTA (Otago, Ō Tākou, OT), STL (Southland, Te Taiao Tonga, SO), TAS (Tasman, Te tai o Aorere, TS), TKI (Taranaki, TK), WGN (Greater Wellington, Te Pane Matua Taiao, Wellington, Te Whanganui-a-Tara, WG), WKO (Waikato, WK), WTC (West Coast, Te Tai o Poutini, WC); subregions: South Canterbury
NicaraguaNISubdivisions: AN (Costa Caribe Norte), AS (Costa Caribe Sur), BO (Boaco), CA (Carazo), CI (Chinandega), CO (Chontales), ES (Estelí), GR (Granada), JI (Jinotega), LE (León), MD (Madriz), MN (Managua), MS (Masaya), MT (Matagalpa), NS (Nueva Segovia), RI (Rivas), SJ (Río San Juan)en_US, es, uk
NigerNEen_US, fr_NEOPTIONAL
NigeriaNG
NiueNUen_NU, en_US
Norfolk IslandNFen_NF, en_US
Northern Mariana Islands (the)MPCan also be loaded as country US, subdivision MPen_US, thGOVERNMENT, UNOFFICIAL
North MacedoniaMKen_US, mk, ukALBANIAN, BOSNIAN, CATHOLIC, HEBREW, ISLAMIC, ORTHODOX, ROMA, SERBIAN, TURKISH, VLACH
NorwayNOCounties and Arctic Regions: 03 (Oslo), 11 (Rogaland), 15 (Møre og Romsdal), 18 (Nordland), 21 (Svalbard), 22 (Jan Mayen), 30 (Viken), 34 (Innlandet), 38 (Vestfold og Telemark), 42 (Agder), 46 (Vestland), 50 (Trööndelage, Trøndelag), 54 (Romssa ja Finnmárkku, Troms og Finnmark, Tromssan ja Finmarkun)en_US, no, th, uk
OmanOMar, en_US
PakistanPKen_PK, en_US, ur_PK
PalauPWARMED_FORCES, HALF_DAY
PalestinePSar, en_USCATHOLIC, ORTHODOX
PanamaPAen_US, es, ukBANK
Papua New GuineaPG
ParaguayPYen_US, es, ukGOVERNMENT
PeruPEen_US, es, uk
PhilippinesPHen_PH, en_US, fil, thWORKDAY
PolandPLde, en_US, pl, uk
PortugalPTDistricts: 01 (Aveiro), 02 (Beja), 03 (Braga), 04 (Bragança), 05 (Castelo Branco), 06 (Coimbra), 07 (Évora), 08 (Faro), 09 (Guarda), 10 (Leiria), 11 (Lisboa), 12 (Portalegre), 13 (Porto), 14 (Santarém), 15 (Setúbal), 16 (Viana do Castelo), 17 (Vila Real), 18 (Viseu), 20 (Região Autónoma dos Açores), 30 (Região Autónoma da Madeira)en_US, pt_PT, ukOPTIONAL
Puerto RicoPRCan also be loaded as country US, subdivision PRen_US, thGOVERNMENT, UNOFFICIAL
QatarQAar_QA, en_USBANK
ReunionRECan also be loaded as country FR, subdivision 974en_US, fr, th, uk
RomaniaROen_US, ro, uk
RussiaRUen_US, ru, th
Saint BarthélemyBLCan also be loaded as country FR, subdivision BLen_US, fr, th, uk
Saint Kitts and NevisKNHALF_DAY, WORKDAY
Saint LuciaLCen_LC, en_US
Saint MartinMFCan also be loaded as country FR, subdivision MFen_US, fr, th, uk
Saint Pierre and MiquelonPMCan also be loaded as country FR, subdivision PMen_US, fr, th, uk
Saint Vincent and the GrenadinesVCen_US, en_VC
SamoaWS
San MarinoSMen_US, it, ukBANK
Sao Tome and PrincipeSTDistricts and Autonomous Region: 01 (Água Grande), 02 (Cantagalo), 03 (Caué), 04 (Lembá), 05 (Lobata), 06 (Mé-Zóchi), P (Príncipe)en_US, pt_ST
Saudi ArabiaSAar, en_US
SenegalSNen_US, fr_SN
SerbiaRSen_US, sr
SeychellesSCen_SC, en_US
Sierra LeoneSLen_SL, en_US
SingaporeSGen_SG, en_US, th
Sint MaartenSXen_US, nl
SlovakiaSKen_US, sk, ukWORKDAY
SloveniaSIen_US, sl, ukWORKDAY
Solomon IslandsSBSubdivisions: CE (Central), CH (Choiseul), CT (Capital Territory, Honiara), GU (Guadalcanal), IS (Isabel), MK (Makira-Ulawa), ML (Malaita), RB (Rennell and Bellona), TE (Temotu), WE (Western)
South AfricaZA
South KoreaKRen_US, ko, thBANK
SpainESAutonomous communities: AN (Andalucía), AR (Aragón), AS (Asturias), CB (Cantabria), CE (Ceuta), CL (Castilla y León), CM (Castilla-La Mancha), CN (Canarias), CT (Cataluña, Catalunya), EX (Extremadura), GA (Galicia), IB (Islas Baleares, Illes Balears), MC (Murcia), MD (Madrid), ML (Melilla), NC (Navarra), PV (País Vasco), RI (La Rioja), VC (Valenciana)en_US, es, uk
Sri LankaLKen_US, si_LK, ta_LKBANK, GOVERNMENT, WORKDAY
SurinameSRen_US, nl
Svalbard and Jan MayenSJCan also be loaded as country NO, subdivision 21 and 22en_US, no, th, uk
SwedenSEen_US, sv, th, uk
SwitzerlandCHCantons: AG (Aargau), AI (Appenzell Innerrhoden), AR (Appenzell Ausserrhoden), BE (Bern, Berne), BL (Basel-Landschaft), BS (Basel-Stadt), FR (Freiburg, Fribourg), GE (Genève), GL (Glarus), GR (Graubünden, Grigioni, Grischun), JU (Jura), LU (Luzern), NE (Neuchâtel), NW (Nidwalden), OW (Obwalden), SG (Sankt Gallen), SH (Schaffhausen), SO (Solothurn), SZ (Schwyz), TG (Thurgau), TI (Ticino), UR (Uri), VD (Vaud), VS (Valais, Wallis), ZG (Zug), ZH (Zürich)de, en_US, fr, it, ukHALF_DAY, OPTIONAL
TaiwanTWen_US, th, zh_CN, zh_TWGOVERNMENT, OPTIONAL, SCHOOL, WORKDAY
TanzaniaTZen_US, swBANK
ThailandTHen_US, th, ukARMED_FORCES, BANK, GOVERNMENT, SCHOOL, WORKDAY
Timor LesteTLen_TL, en_US, pt_TL, tet, thGOVERNMENT, WORKDAY
TogoTGen_US, frWORKDAY
TokelauTKen_TK, en_US, tkl
TongaTOen_US, to
Trinidad and TobagoTTen_TT, en_USOPTIONAL
TunisiaTNar, en_US
TurkeyTRen_US, tr, ukHALF_DAY
Turks and Caicos IslandsTCen_TC, en_US
TuvaluTVTown/Island Councils: FUN (Funafuti), NIT (Niutao), NKF (Nukufetau), NKL (Nukulaelae), NMA (Nanumea), NMG (Nanumaga, Nanumanga), NUI (Nui), VAI (Vaitupu)en_GB, en_US, tvl
UkraineUAar, en_US, th, ukWORKDAY
United Arab EmiratesAEar, en_US, thGOVERNMENT, OPTIONAL
United KingdomGBSubdivisions: ENG (England), NIR (Northern Ireland), SCT (Scotland), WLS (Wales)en_GB, en_US, th
United States Minor Outlying IslandsUMCan also be loaded as country US, subdivision UMen_US, thGOVERNMENT, UNOFFICIAL
United States of America (the)USStates and territories: AK (Alaska), AL (Alabama), AR (Arkansas), AS (American Samoa), AZ (Arizona), CA (California), CO (Colorado), CT (Connecticut), DC (District of Columbia), DE (Delaware), FL (Florida), GA (Georgia), GU (Guam), HI (Hawaii), IA (Iowa), ID (Idaho), IL (Illinois), IN (Indiana), KS (Kansas), KY (Kentucky), LA (Louisiana), MA (Massachusetts), MD (Maryland), ME (Maine), MI (Michigan), MN (Minnesota), MO (Missouri), MP (Northern Mariana Islands), MS (Mississippi), MT (Montana), NC (North Carolina), ND (North Dakota), NE (Nebraska), NH (New Hampshire), NJ (New Jersey), NM (New Mexico), NV (Nevada), NY (New York), OH (Ohio), OK (Oklahoma), OR (Oregon), PA (Pennsylvania), PR (Puerto Rico), RI (Rhode Island), SC (South Carolina), SD (South Dakota), TN (Tennessee), TX (Texas), UM (United States Minor Outlying Islands), UT (Utah), VA (Virginia), VI (Virgin Islands, U.S.), VT (Vermont), WA (Washington), WI (Wisconsin), WV (West Virginia), WY (Wyoming)en_US, thGOVERNMENT, UNOFFICIAL
United States Virgin Islands (the)See Virgin Islands (U.S.)GOVERNMENT, UNOFFICIAL
UruguayUYen_US, es, ukBANK
UzbekistanUZen_US, uk, uz
VanuatuVU
Vatican CityVAen_US, it, th
VenezuelaVEen_US, es, uk
VietnamVNen_US, th, vi
Virgin Islands (U.S.)VICan also be loaded as country US, subdivision VIen_US, thGOVERNMENT, UNOFFICIAL
Wallis and FutunaWFCan also be loaded as country FR, subdivision WFen_US, fr, th, uk
YemenYEar, en_USSCHOOL, WORKDAY
ZambiaZM
ZimbabweZW
+ +## Available Financial Markets + +The standard way to refer to a financial market is to use its [ISO 10383 +MIC](https://www.iso20022.org/market-identifier-codes) (Market Identifier Code) as a "market" +code when available. The following financial markets are available: + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EntityCodeInfoSupported Languages
Brasil, Bolsa, BalcãoBVMFBrazil Stock Exchange and Over-the-Counter Market holidays (same as ANBIMA holidays)en_US, pt_BR, uk
European Central BankXECBTrans-European Automated Real-time Gross Settlement (TARGET2)
ICE Futures EuropeIFEUA London-based Investment Exchange holidays
New York Stock ExchangeXNYSNYSE market holidays (used by all other US-exchanges, including NASDAQ, etc.)
+ +## Contributions + +[Issues](https://github.com/vacanza/holidays/issues) and [pull +requests](https://github.com/vacanza/holidays/pulls) are always welcome. Please see +[here](https://github.com/vacanza/holidays/blob/dev/CONTRIBUTING.md) for more information. + +## License + +Code and documentation are available according to the MIT License (see +[LICENSE](https://github.com/vacanza/holidays/blob/dev/LICENSE)). diff --git a/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/RECORD b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/RECORD new file mode 100644 index 00000000..793f6bb7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/RECORD @@ -0,0 +1,1111 @@ +holidays-0.77.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +holidays-0.77.dist-info/METADATA,sha256=MGMAqp9LuoGBzGtXGvB-6Hn7LwRdHH5oJ-pc8ZzjZy4,46448 +holidays-0.77.dist-info/RECORD,, +holidays-0.77.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91 +holidays-0.77.dist-info/licenses/CONTRIBUTORS,sha256=eMbBxUYXFhw9Q6RARcOC82MlZVoWlMTgQrOqaGs3838,2488 +holidays-0.77.dist-info/licenses/LICENSE,sha256=qaRbNMUziFD5hzKfNRApNOyW0rOkRWOZi8zAG9nJ4-k,1246 +holidays-0.77.dist-info/top_level.txt,sha256=VbGrOCSM-V2kztuL_7CoDKLOgzOc85ueFsng7VYerrQ,9 +holidays/__init__.py,sha256=8KEDrEA3kozqL5nvlN5I8kMeYb8mlQ-gtO25UhCB9R4,833 +holidays/__pycache__/__init__.cpython-312.pyc,, +holidays/__pycache__/constants.cpython-312.pyc,, +holidays/__pycache__/helpers.cpython-312.pyc,, +holidays/__pycache__/holiday_base.cpython-312.pyc,, +holidays/__pycache__/ical.cpython-312.pyc,, +holidays/__pycache__/observed_holiday_base.cpython-312.pyc,, +holidays/__pycache__/registry.cpython-312.pyc,, +holidays/__pycache__/utils.cpython-312.pyc,, +holidays/__pycache__/version.cpython-312.pyc,, +holidays/calendars/__init__.py,sha256=QHFZElyJazdO6BGEeCgcFD-0nd2MsZr_g61Ax3AjzZk,1520 +holidays/calendars/__pycache__/__init__.cpython-312.pyc,, +holidays/calendars/__pycache__/balinese_saka.cpython-312.pyc,, +holidays/calendars/__pycache__/buddhist.cpython-312.pyc,, +holidays/calendars/__pycache__/chinese.cpython-312.pyc,, +holidays/calendars/__pycache__/custom.cpython-312.pyc,, +holidays/calendars/__pycache__/gregorian.cpython-312.pyc,, +holidays/calendars/__pycache__/hebrew.cpython-312.pyc,, +holidays/calendars/__pycache__/hindu.cpython-312.pyc,, +holidays/calendars/__pycache__/islamic.cpython-312.pyc,, +holidays/calendars/__pycache__/julian.cpython-312.pyc,, +holidays/calendars/__pycache__/julian_revised.cpython-312.pyc,, +holidays/calendars/__pycache__/mongolian.cpython-312.pyc,, +holidays/calendars/__pycache__/persian.cpython-312.pyc,, +holidays/calendars/__pycache__/sinhala.cpython-312.pyc,, +holidays/calendars/__pycache__/thai.cpython-312.pyc,, +holidays/calendars/balinese_saka.py,sha256=lbax1UM6GMrUtpQZVcbKSPgJN6I2QoYe5p1DxNFwcqY,3306 +holidays/calendars/buddhist.py,sha256=VwBFc_K_aYgZ0XcK_GN0j9c8N0iE_WV5ybLpdUyWlE0,11405 +holidays/calendars/chinese.py,sha256=JwfSM7F4xJ9-33gCEw7Y3qN0P-UuBeBotOuWMnbmnEI,34386 +holidays/calendars/custom.py,sha256=yU_QoNnQ7L079iKz2V-eZIbrkPolGElEfSQ43eKvPbg,1250 +holidays/calendars/gregorian.py,sha256=cofHQ_X6o8cdcX93ZkYXdgPe81WzyTKEehGopTh4WbQ,2833 +holidays/calendars/hebrew.py,sha256=rtIciWVIspS8vfGJsk30MwhU7bV2knnpvepJlThY7Ok,40618 +holidays/calendars/hindu.py,sha256=n-fahybpPhZg-JW8KM4Tepv_kc2qaDM7uC2NdwFjvuo,40384 +holidays/calendars/islamic.py,sha256=ZRcI_xfHunvjwxyuDEfDmHTDpQrBwHPG163ghqB0LMw,102560 +holidays/calendars/julian.py,sha256=iFMLzBHfOzU-37kB_FymCcHd8KKuNDWQQDiAQKBUDuA,568 +holidays/calendars/julian_revised.py,sha256=8FRtk5uX1rVGEbVEC7sfnGtLh63zmrZyCQ-wnj1i6Ik,584 +holidays/calendars/mongolian.py,sha256=3dzvWbazuHO3jjhrna1Y9ab_8p2gbcKUUcn6XG696-o,8985 +holidays/calendars/persian.py,sha256=jvyne940362TvbM68tZfIkUIn55Iz3HXFVv_6r5mQt0,2140 +holidays/calendars/sinhala.py,sha256=_QdHG92Nhbbgp_mG1SbwY-dqpDD8dYEE3v00bAc14hs,11315 +holidays/calendars/thai.py,sha256=BPP35vNC4PBBcXNRmmzwhLqJVHn3XtinkhX0pgk3mE0,24888 +holidays/constants.py,sha256=Hu3fBOVnKuRqail8gY5deciuWbBv5_XC3oKomzVgx-c,1422 +holidays/countries/__init__.py,sha256=wLnCXN9wNQ5O6lnM2_jtb8xfPCDFJr_DzGGm0vT9Vyk,14430 +holidays/countries/__pycache__/__init__.cpython-312.pyc,, +holidays/countries/__pycache__/afghanistan.cpython-312.pyc,, +holidays/countries/__pycache__/aland_islands.cpython-312.pyc,, +holidays/countries/__pycache__/albania.cpython-312.pyc,, +holidays/countries/__pycache__/algeria.cpython-312.pyc,, +holidays/countries/__pycache__/american_samoa.cpython-312.pyc,, +holidays/countries/__pycache__/andorra.cpython-312.pyc,, +holidays/countries/__pycache__/angola.cpython-312.pyc,, +holidays/countries/__pycache__/anguilla.cpython-312.pyc,, +holidays/countries/__pycache__/antigua_and_barbuda.cpython-312.pyc,, +holidays/countries/__pycache__/argentina.cpython-312.pyc,, +holidays/countries/__pycache__/armenia.cpython-312.pyc,, +holidays/countries/__pycache__/aruba.cpython-312.pyc,, +holidays/countries/__pycache__/australia.cpython-312.pyc,, +holidays/countries/__pycache__/austria.cpython-312.pyc,, +holidays/countries/__pycache__/azerbaijan.cpython-312.pyc,, +holidays/countries/__pycache__/bahamas.cpython-312.pyc,, +holidays/countries/__pycache__/bahrain.cpython-312.pyc,, +holidays/countries/__pycache__/bangladesh.cpython-312.pyc,, +holidays/countries/__pycache__/barbados.cpython-312.pyc,, +holidays/countries/__pycache__/belarus.cpython-312.pyc,, +holidays/countries/__pycache__/belgium.cpython-312.pyc,, +holidays/countries/__pycache__/belize.cpython-312.pyc,, +holidays/countries/__pycache__/benin.cpython-312.pyc,, +holidays/countries/__pycache__/bermuda.cpython-312.pyc,, +holidays/countries/__pycache__/bolivia.cpython-312.pyc,, +holidays/countries/__pycache__/bonaire_sint_eustatius_and_saba.cpython-312.pyc,, +holidays/countries/__pycache__/bosnia_and_herzegovina.cpython-312.pyc,, +holidays/countries/__pycache__/botswana.cpython-312.pyc,, +holidays/countries/__pycache__/brazil.cpython-312.pyc,, +holidays/countries/__pycache__/british_virgin_islands.cpython-312.pyc,, +holidays/countries/__pycache__/brunei.cpython-312.pyc,, +holidays/countries/__pycache__/bulgaria.cpython-312.pyc,, +holidays/countries/__pycache__/burkina_faso.cpython-312.pyc,, +holidays/countries/__pycache__/burundi.cpython-312.pyc,, +holidays/countries/__pycache__/cabo_verde.cpython-312.pyc,, +holidays/countries/__pycache__/cambodia.cpython-312.pyc,, +holidays/countries/__pycache__/cameroon.cpython-312.pyc,, +holidays/countries/__pycache__/canada.cpython-312.pyc,, +holidays/countries/__pycache__/cayman_islands.cpython-312.pyc,, +holidays/countries/__pycache__/central_african_republic.cpython-312.pyc,, +holidays/countries/__pycache__/chad.cpython-312.pyc,, +holidays/countries/__pycache__/chile.cpython-312.pyc,, +holidays/countries/__pycache__/china.cpython-312.pyc,, +holidays/countries/__pycache__/christmas_island.cpython-312.pyc,, +holidays/countries/__pycache__/cocos_islands.cpython-312.pyc,, +holidays/countries/__pycache__/colombia.cpython-312.pyc,, +holidays/countries/__pycache__/congo.cpython-312.pyc,, +holidays/countries/__pycache__/cook_islands.cpython-312.pyc,, +holidays/countries/__pycache__/costa_rica.cpython-312.pyc,, +holidays/countries/__pycache__/croatia.cpython-312.pyc,, +holidays/countries/__pycache__/cuba.cpython-312.pyc,, +holidays/countries/__pycache__/curacao.cpython-312.pyc,, +holidays/countries/__pycache__/cyprus.cpython-312.pyc,, +holidays/countries/__pycache__/czechia.cpython-312.pyc,, +holidays/countries/__pycache__/denmark.cpython-312.pyc,, +holidays/countries/__pycache__/djibouti.cpython-312.pyc,, +holidays/countries/__pycache__/dominica.cpython-312.pyc,, +holidays/countries/__pycache__/dominican_republic.cpython-312.pyc,, +holidays/countries/__pycache__/dr_congo.cpython-312.pyc,, +holidays/countries/__pycache__/ecuador.cpython-312.pyc,, +holidays/countries/__pycache__/egypt.cpython-312.pyc,, +holidays/countries/__pycache__/el_salvador.cpython-312.pyc,, +holidays/countries/__pycache__/equatorial_guinea.cpython-312.pyc,, +holidays/countries/__pycache__/estonia.cpython-312.pyc,, +holidays/countries/__pycache__/eswatini.cpython-312.pyc,, +holidays/countries/__pycache__/ethiopia.cpython-312.pyc,, +holidays/countries/__pycache__/falkland_islands.cpython-312.pyc,, +holidays/countries/__pycache__/faroe_islands.cpython-312.pyc,, +holidays/countries/__pycache__/fiji.cpython-312.pyc,, +holidays/countries/__pycache__/finland.cpython-312.pyc,, +holidays/countries/__pycache__/france.cpython-312.pyc,, +holidays/countries/__pycache__/french_guiana.cpython-312.pyc,, +holidays/countries/__pycache__/french_polynesia.cpython-312.pyc,, +holidays/countries/__pycache__/french_southern_territories.cpython-312.pyc,, +holidays/countries/__pycache__/gabon.cpython-312.pyc,, +holidays/countries/__pycache__/georgia.cpython-312.pyc,, +holidays/countries/__pycache__/germany.cpython-312.pyc,, +holidays/countries/__pycache__/ghana.cpython-312.pyc,, +holidays/countries/__pycache__/gibraltar.cpython-312.pyc,, +holidays/countries/__pycache__/greece.cpython-312.pyc,, +holidays/countries/__pycache__/greenland.cpython-312.pyc,, +holidays/countries/__pycache__/grenada.cpython-312.pyc,, +holidays/countries/__pycache__/guadeloupe.cpython-312.pyc,, +holidays/countries/__pycache__/guam.cpython-312.pyc,, +holidays/countries/__pycache__/guatemala.cpython-312.pyc,, +holidays/countries/__pycache__/guernsey.cpython-312.pyc,, +holidays/countries/__pycache__/guinea.cpython-312.pyc,, +holidays/countries/__pycache__/guyana.cpython-312.pyc,, +holidays/countries/__pycache__/haiti.cpython-312.pyc,, +holidays/countries/__pycache__/honduras.cpython-312.pyc,, +holidays/countries/__pycache__/hongkong.cpython-312.pyc,, +holidays/countries/__pycache__/hungary.cpython-312.pyc,, +holidays/countries/__pycache__/iceland.cpython-312.pyc,, +holidays/countries/__pycache__/india.cpython-312.pyc,, +holidays/countries/__pycache__/indonesia.cpython-312.pyc,, +holidays/countries/__pycache__/iran.cpython-312.pyc,, +holidays/countries/__pycache__/ireland.cpython-312.pyc,, +holidays/countries/__pycache__/isle_of_man.cpython-312.pyc,, +holidays/countries/__pycache__/israel.cpython-312.pyc,, +holidays/countries/__pycache__/italy.cpython-312.pyc,, +holidays/countries/__pycache__/ivory_coast.cpython-312.pyc,, +holidays/countries/__pycache__/jamaica.cpython-312.pyc,, +holidays/countries/__pycache__/japan.cpython-312.pyc,, +holidays/countries/__pycache__/jersey.cpython-312.pyc,, +holidays/countries/__pycache__/jordan.cpython-312.pyc,, +holidays/countries/__pycache__/kazakhstan.cpython-312.pyc,, +holidays/countries/__pycache__/kenya.cpython-312.pyc,, +holidays/countries/__pycache__/kuwait.cpython-312.pyc,, +holidays/countries/__pycache__/kyrgyzstan.cpython-312.pyc,, +holidays/countries/__pycache__/laos.cpython-312.pyc,, +holidays/countries/__pycache__/latvia.cpython-312.pyc,, +holidays/countries/__pycache__/lebanon.cpython-312.pyc,, +holidays/countries/__pycache__/lesotho.cpython-312.pyc,, +holidays/countries/__pycache__/libya.cpython-312.pyc,, +holidays/countries/__pycache__/liechtenstein.cpython-312.pyc,, +holidays/countries/__pycache__/lithuania.cpython-312.pyc,, +holidays/countries/__pycache__/luxembourg.cpython-312.pyc,, +holidays/countries/__pycache__/macau.cpython-312.pyc,, +holidays/countries/__pycache__/madagascar.cpython-312.pyc,, +holidays/countries/__pycache__/malawi.cpython-312.pyc,, +holidays/countries/__pycache__/malaysia.cpython-312.pyc,, +holidays/countries/__pycache__/maldives.cpython-312.pyc,, +holidays/countries/__pycache__/mali.cpython-312.pyc,, +holidays/countries/__pycache__/malta.cpython-312.pyc,, +holidays/countries/__pycache__/marshall_islands.cpython-312.pyc,, +holidays/countries/__pycache__/martinique.cpython-312.pyc,, +holidays/countries/__pycache__/mauritania.cpython-312.pyc,, +holidays/countries/__pycache__/mauritius.cpython-312.pyc,, +holidays/countries/__pycache__/mayotte.cpython-312.pyc,, +holidays/countries/__pycache__/mexico.cpython-312.pyc,, +holidays/countries/__pycache__/micronesia.cpython-312.pyc,, +holidays/countries/__pycache__/moldova.cpython-312.pyc,, +holidays/countries/__pycache__/monaco.cpython-312.pyc,, +holidays/countries/__pycache__/mongolia.cpython-312.pyc,, +holidays/countries/__pycache__/montenegro.cpython-312.pyc,, +holidays/countries/__pycache__/montserrat.cpython-312.pyc,, +holidays/countries/__pycache__/morocco.cpython-312.pyc,, +holidays/countries/__pycache__/mozambique.cpython-312.pyc,, +holidays/countries/__pycache__/namibia.cpython-312.pyc,, +holidays/countries/__pycache__/nauru.cpython-312.pyc,, +holidays/countries/__pycache__/nepal.cpython-312.pyc,, +holidays/countries/__pycache__/netherlands.cpython-312.pyc,, +holidays/countries/__pycache__/new_caledonia.cpython-312.pyc,, +holidays/countries/__pycache__/new_zealand.cpython-312.pyc,, +holidays/countries/__pycache__/nicaragua.cpython-312.pyc,, +holidays/countries/__pycache__/niger.cpython-312.pyc,, +holidays/countries/__pycache__/nigeria.cpython-312.pyc,, +holidays/countries/__pycache__/niue.cpython-312.pyc,, +holidays/countries/__pycache__/norfolk_island.cpython-312.pyc,, +holidays/countries/__pycache__/north_macedonia.cpython-312.pyc,, +holidays/countries/__pycache__/northern_mariana_islands.cpython-312.pyc,, +holidays/countries/__pycache__/norway.cpython-312.pyc,, +holidays/countries/__pycache__/oman.cpython-312.pyc,, +holidays/countries/__pycache__/pakistan.cpython-312.pyc,, +holidays/countries/__pycache__/palau.cpython-312.pyc,, +holidays/countries/__pycache__/palestine.cpython-312.pyc,, +holidays/countries/__pycache__/panama.cpython-312.pyc,, +holidays/countries/__pycache__/papua_new_guinea.cpython-312.pyc,, +holidays/countries/__pycache__/paraguay.cpython-312.pyc,, +holidays/countries/__pycache__/peru.cpython-312.pyc,, +holidays/countries/__pycache__/philippines.cpython-312.pyc,, +holidays/countries/__pycache__/poland.cpython-312.pyc,, +holidays/countries/__pycache__/portugal.cpython-312.pyc,, +holidays/countries/__pycache__/puerto_rico.cpython-312.pyc,, +holidays/countries/__pycache__/qatar.cpython-312.pyc,, +holidays/countries/__pycache__/reunion.cpython-312.pyc,, +holidays/countries/__pycache__/romania.cpython-312.pyc,, +holidays/countries/__pycache__/russia.cpython-312.pyc,, +holidays/countries/__pycache__/saint_barthelemy.cpython-312.pyc,, +holidays/countries/__pycache__/saint_kitts_and_nevis.cpython-312.pyc,, +holidays/countries/__pycache__/saint_lucia.cpython-312.pyc,, +holidays/countries/__pycache__/saint_martin.cpython-312.pyc,, +holidays/countries/__pycache__/saint_pierre_and_miquelon.cpython-312.pyc,, +holidays/countries/__pycache__/saint_vincent_and_the_grenadines.cpython-312.pyc,, +holidays/countries/__pycache__/samoa.cpython-312.pyc,, +holidays/countries/__pycache__/san_marino.cpython-312.pyc,, +holidays/countries/__pycache__/sao_tome_and_principe.cpython-312.pyc,, +holidays/countries/__pycache__/saudi_arabia.cpython-312.pyc,, +holidays/countries/__pycache__/senegal.cpython-312.pyc,, +holidays/countries/__pycache__/serbia.cpython-312.pyc,, +holidays/countries/__pycache__/seychelles.cpython-312.pyc,, +holidays/countries/__pycache__/sierra_leone.cpython-312.pyc,, +holidays/countries/__pycache__/singapore.cpython-312.pyc,, +holidays/countries/__pycache__/sint_maarten.cpython-312.pyc,, +holidays/countries/__pycache__/slovakia.cpython-312.pyc,, +holidays/countries/__pycache__/slovenia.cpython-312.pyc,, +holidays/countries/__pycache__/solomon_islands.cpython-312.pyc,, +holidays/countries/__pycache__/south_africa.cpython-312.pyc,, +holidays/countries/__pycache__/south_korea.cpython-312.pyc,, +holidays/countries/__pycache__/spain.cpython-312.pyc,, +holidays/countries/__pycache__/sri_lanka.cpython-312.pyc,, +holidays/countries/__pycache__/suriname.cpython-312.pyc,, +holidays/countries/__pycache__/svalbard_and_jan_mayen.cpython-312.pyc,, +holidays/countries/__pycache__/sweden.cpython-312.pyc,, +holidays/countries/__pycache__/switzerland.cpython-312.pyc,, +holidays/countries/__pycache__/taiwan.cpython-312.pyc,, +holidays/countries/__pycache__/tanzania.cpython-312.pyc,, +holidays/countries/__pycache__/thailand.cpython-312.pyc,, +holidays/countries/__pycache__/timor_leste.cpython-312.pyc,, +holidays/countries/__pycache__/togo.cpython-312.pyc,, +holidays/countries/__pycache__/tokelau.cpython-312.pyc,, +holidays/countries/__pycache__/tonga.cpython-312.pyc,, +holidays/countries/__pycache__/trinidad_and_tobago.cpython-312.pyc,, +holidays/countries/__pycache__/tunisia.cpython-312.pyc,, +holidays/countries/__pycache__/turkey.cpython-312.pyc,, +holidays/countries/__pycache__/turks_and_caicos_islands.cpython-312.pyc,, +holidays/countries/__pycache__/tuvalu.cpython-312.pyc,, +holidays/countries/__pycache__/ukraine.cpython-312.pyc,, +holidays/countries/__pycache__/united_arab_emirates.cpython-312.pyc,, +holidays/countries/__pycache__/united_kingdom.cpython-312.pyc,, +holidays/countries/__pycache__/united_states.cpython-312.pyc,, +holidays/countries/__pycache__/united_states_minor_outlying_islands.cpython-312.pyc,, +holidays/countries/__pycache__/united_states_virgin_islands.cpython-312.pyc,, +holidays/countries/__pycache__/uruguay.cpython-312.pyc,, +holidays/countries/__pycache__/uzbekistan.cpython-312.pyc,, +holidays/countries/__pycache__/vanuatu.cpython-312.pyc,, +holidays/countries/__pycache__/vatican_city.cpython-312.pyc,, +holidays/countries/__pycache__/venezuela.cpython-312.pyc,, +holidays/countries/__pycache__/vietnam.cpython-312.pyc,, +holidays/countries/__pycache__/wallis_and_futuna.cpython-312.pyc,, +holidays/countries/__pycache__/yemen.cpython-312.pyc,, +holidays/countries/__pycache__/zambia.cpython-312.pyc,, +holidays/countries/__pycache__/zimbabwe.cpython-312.pyc,, +holidays/countries/afghanistan.py,sha256=f9JhviqYyu96uHmAhadFUuwexdknfL7c8jitWt0j5vQ,5829 +holidays/countries/aland_islands.py,sha256=YsdE9QrHZXyjE9fPXY3SvT7QfVtVspewlTCW0dILCaM,1349 +holidays/countries/albania.py,sha256=SqU19yIO57uwbpjHx8U9-XYuSD-cBZu46t87Cg6-82A,5752 +holidays/countries/algeria.py,sha256=anRDTYOGjKytIyw2lwwq5lIrYVikr5dFmJ5vIbUsyp8,3749 +holidays/countries/american_samoa.py,sha256=xDGtuVVdqJIAFZHXOEo0X57m1U7j9oNwtDVEqn0mjLo,1160 +holidays/countries/andorra.py,sha256=yp5WKnuLTyp3M4SI8pQlVrMBCQRbjBd3qNJJomKhUjA,11235 +holidays/countries/angola.py,sha256=efv5QKb3eDmY9sAewUGxyYYQIXc-MHk2RTUOCqAV8A0,7399 +holidays/countries/anguilla.py,sha256=3bblKJp2abi_G1m5O4HEBogZmthEGB6kfogIP44J2TY,7519 +holidays/countries/antigua_and_barbuda.py,sha256=izo24Zw6dczz0sTf6So_BQZrsx-7CWESBzJOaYCn1pI,7022 +holidays/countries/argentina.py,sha256=OH61g5Cf8OosTIZO80TyIAh0xQ7RvF3FCL6QjLyIhf4,45513 +holidays/countries/armenia.py,sha256=qCKLdthbrcjDE50hIRR3ONjoAhuiH05G1qG5kv5Qcvo,3810 +holidays/countries/aruba.py,sha256=PDeeK2AYbMtf3Dojo7c4DFztZStIu3uRge8mEqYXfKk,5891 +holidays/countries/australia.py,sha256=edexK1fgYtlTJKN5Jdbc-WzfbcVr8tRf8C-wAc2B3zY,36987 +holidays/countries/austria.py,sha256=PwTsMvpENhUjzHete2W1JZGcfS9AV4hhYt3KcqLOyTc,4928 +holidays/countries/azerbaijan.py,sha256=xB7AvP7mCMKBXzfqpnu7x0KFkcRNUA8qEaI2LZ-8IEI,12872 +holidays/countries/bahamas.py,sha256=IzPmcH31u1-uKGm-tgRyVBNgXaYxw1EbCtqx8Tl0hb0,5686 +holidays/countries/bahrain.py,sha256=y8XUpZDig4lKSoVp4u868lKDd2_KfTsjmkyo3t4pERg,3500 +holidays/countries/bangladesh.py,sha256=x0I7l5ci8hKzUM4a2XtIXTzQgyJhzJ_ddnamNtm7fJA,1995 +holidays/countries/barbados.py,sha256=xwMvS-ZVGB1tnAIBUxJJmS840mYwgdn_McspT0VYq8o,4038 +holidays/countries/belarus.py,sha256=qgbpbPZpfPOYDu06hQ79U3jLsV6ekD8jYwRMsXO2pSQ,10218 +holidays/countries/belgium.py,sha256=4bmltstbqdAClzLNlt0jN1GhflTXOYrKV2Si_v8mwf4,2947 +holidays/countries/belize.py,sha256=QGvl5lxCbGlfTdwONMKaHG9Z-m9hhiNovxdYfE3H-MM,4142 +holidays/countries/benin.py,sha256=jp3ZMGg5icWIXfzqYNaOptzKbSpSbFEE_ZHj-EJ5Hl0,11685 +holidays/countries/bermuda.py,sha256=AgJB2GmcK29aVToLa1p4nJvYUjmVZ4GVR-jbiGcZXzw,6859 +holidays/countries/bolivia.py,sha256=fBF3BKHM_J6ME9dcChrcjMsbfqTOEhI9amB-9uiAJ2w,6390 +holidays/countries/bonaire_sint_eustatius_and_saba.py,sha256=gMoEUi5MUsDtMKy5CYpVAIR8QWL3AMdat223bbUxhSg,4757 +holidays/countries/bosnia_and_herzegovina.py,sha256=r095abK7etRvGFME75JSYOWUb8OtdtjWkrF6hejrhHw,10109 +holidays/countries/botswana.py,sha256=W1AbVuKElpL-rV2X3cTYrY9iL_oNnlnN4Zp8o1R2aMc,3362 +holidays/countries/brazil.py,sha256=TRE4jbALdh4J8djwLoJ8CccnTG-sakaRPnUgRzR5_QY,13674 +holidays/countries/british_virgin_islands.py,sha256=pGMktxs0IPAGYhdk4uxM0rVR-WiNbCoaoLxj1OyRFAA,8080 +holidays/countries/brunei.py,sha256=nDX4ayaACFr2F_pAn6SdJV8s9_cMmHRa74m7gySIyC0,18029 +holidays/countries/bulgaria.py,sha256=3TQEtgCl_Qo6WkUreVNGe1PRZphW5zGyQ11ilCWcWAw,5478 +holidays/countries/burkina_faso.py,sha256=18Hn9PylJc96OYPx01tKv16hWCUUrGhD-Si9Zsvu0k0,4364 +holidays/countries/burundi.py,sha256=WUQZjzclDy4eVb46hk6hOYnP6WstmN1C6SAr7k1M5kU,3457 +holidays/countries/cabo_verde.py,sha256=xzJCT6RDuQD348ze5PltfcHxUZbdIx52va17kNLimLU,11101 +holidays/countries/cambodia.py,sha256=tlKI2k-Lh8n_F15Oc1Bs--pb5Iotj-tY-XDCXJuH36g,15664 +holidays/countries/cameroon.py,sha256=QIU8No-2B1efRj7vresp21F8wSlnt-uWqH1aLjwn4ZQ,5550 +holidays/countries/canada.py,sha256=VAP0f94uO-fOJf_0HIN9pJ6q_eXuzow0XfnEo0hthJU,20029 +holidays/countries/cayman_islands.py,sha256=1L1sAH26L0e3-K14ypw9lTpOD6MwOK2-3b0De3JLDCc,7104 +holidays/countries/central_african_republic.py,sha256=s9xNKqJwzD1FUs0b6fCBvqAZrumlp51eMV9qdHSK5C0,4785 +holidays/countries/chad.py,sha256=FdZjGEPv0TqSVt0-9X1bcgnqT1NP8Rh_MF35TigMAmQ,4165 +holidays/countries/chile.py,sha256=Fs5J65tDIxabsgTqTk_TINNOXfjYkJeYa5jVkmGbagw,10212 +holidays/countries/china.py,sha256=kwaSDM4tiV7MF6wGEtRh1XtqHTHZAzwzishTsBmoziQ,21194 +holidays/countries/christmas_island.py,sha256=G_BJh1j2cesZi5gHsQ5H1B2eYXxE3qIOH6ppLHX36p4,9556 +holidays/countries/cocos_islands.py,sha256=xUpfhzNJD8ljGv7XcT2_VpjFJxSJZ-18F4_v6O5JskY,11645 +holidays/countries/colombia.py,sha256=9jMxBBhuoaqRkgzeCn6czhH2LqmPAIfhdXFynpWzI5Y,4811 +holidays/countries/congo.py,sha256=8GZAsIDudKT13x1cK7ifzUptVCKuvgh5nSv1thLxlVc,2470 +holidays/countries/cook_islands.py,sha256=unv9Nd2TVYwilYh_69RZ8-uchQMAWNHxneLRQX25TMI,6158 +holidays/countries/costa_rica.py,sha256=_psz2o49W1g7x-0cHjw_rGoGEXUKJGm74H_LR_KoNqc,4506 +holidays/countries/croatia.py,sha256=K_ragW28Lj3ABfiUUpfkSm0D8efNvL9E-114GADcB2I,3582 +holidays/countries/cuba.py,sha256=xLCgetuC66Su6iRzH-hdZN9r4SISy0Urcw5tVWWoT2g,4871 +holidays/countries/curacao.py,sha256=-l9sZhyaasiDg7zE34K6_82Arf30H84jKltHukJrNeU,5721 +holidays/countries/cyprus.py,sha256=YvtJtrAHIBd_VmSbuZZdUh7hzaIOS9KBZp5odpjb_xA,3585 +holidays/countries/czechia.py,sha256=ngp3zcxcHl-0k36ko5YRH0gOxg7qu2rsvVFrd7qj6fo,3797 +holidays/countries/denmark.py,sha256=xhbiuc-Fh6gRDDcBIpXlxnT_YZATRNX7GDEZLWWwj78,2853 +holidays/countries/djibouti.py,sha256=ZiW82ZFpaSpAYaEs1OG94bB4jrb1Wj70DjNy-iKn004,2882 +holidays/countries/dominica.py,sha256=YVWFy46P7TmihV_BZBDwRJEqY6zFG1dbKLX1_KE86WE,5321 +holidays/countries/dominican_republic.py,sha256=kHGtj68welSl3mLSTMSA1x8ePJD5iMVRGT3tVyVqOx0,3000 +holidays/countries/dr_congo.py,sha256=xqvtQweO6zxHS2wU5JT65aIsNcME_cKJllnZvacMK_s,5631 +holidays/countries/ecuador.py,sha256=A14R5feLhOktcKSfau3hn22DlbajzeNgZYzTWlF7Sx8,3932 +holidays/countries/egypt.py,sha256=TqqT5wT6Qs7J6AbR7FlsffPvPeNtKoQHG-Nz1TNVpJU,3801 +holidays/countries/el_salvador.py,sha256=pP7luTp-pYMKVNnUQkp22B49FDAGaAcbwd1EUiP0POo,3761 +holidays/countries/equatorial_guinea.py,sha256=BUHTGy5Yr22iaYqspulfLHEnWlp8pugorEkASkBQtTI,6189 +holidays/countries/estonia.py,sha256=5-GeHePVrLvyiXmEVXpnKDUnzTQJFZWUJ7M4rUx5o-w,2229 +holidays/countries/eswatini.py,sha256=MjjoG18BHxb2QT9ebxZqMhaPgwwGD8DB5goayXKVLUI,3293 +holidays/countries/ethiopia.py,sha256=EtHq9TaeWQ04ISymFyiCuXYLV31Pxqnqm0VtPRKHXqM,6237 +holidays/countries/falkland_islands.py,sha256=_AimxxPFsvA6QQ-buOVqu1AzaiJZJCv-iihMZS2LB9I,5717 +holidays/countries/faroe_islands.py,sha256=MACWPrmphuzkCS1_NaWrrNcNvpqgyT2jKnX-lu_0fHk,3516 +holidays/countries/fiji.py,sha256=W1tsJGtN_Eb3SVLjDXkrmKCw2XXbVi_D-1N4x-opmN8,7160 +holidays/countries/finland.py,sha256=h78GKmirSrtXzLS1xFdIiKiBYI7GyZIaJRNWmCBRKT0,13856 +holidays/countries/france.py,sha256=Ssqb_xyvvOU0su1wv2Jvh8WjmbJb_E_lJZBCh_82NuM,14266 +holidays/countries/french_guiana.py,sha256=k0hyogqmcTUtHyB1ykner0Bj963DpZSDvs6fmWkvLqE,1228 +holidays/countries/french_polynesia.py,sha256=mrfnE4sZjavX9xkrOMZfAES90HkdB0U8Q-YnUy24Dqk,1227 +holidays/countries/french_southern_territories.py,sha256=orrzqdAywcrcusFPKqvRC7Zt-V17PLmdLRRFkRPBsPc,1467 +holidays/countries/gabon.py,sha256=Xm-jjaszdCV8g9MKkHSrEJqmW3RRV3qdN5FDFl2Lkp8,4388 +holidays/countries/georgia.py,sha256=xVvcLSZm3bXWbFYJYteNq1rIfJsxBWWkMj_Tn8zvSuE,4566 +holidays/countries/germany.py,sha256=Em3w_a1iBvBUxjh23eOYBYX6k5yw1zoGTL2RR1xYxQo,9498 +holidays/countries/ghana.py,sha256=XkG8LvAGVQ3MorAD66CfbCHswwuTVFCuQ0Wd8m2Il6A,3417 +holidays/countries/gibraltar.py,sha256=57JzRuuMdqEnIBlSAC6_oX4cM9tStAioSmT_ICdi2YY,10524 +holidays/countries/greece.py,sha256=4BSic1B7x27CwI4AQNrLmUE-WxgUlOgAYYhBQCh7PHg,3600 +holidays/countries/greenland.py,sha256=Kn6nrzCxHasdRTCedMxnt4HL5l8UM32lOfEaE7Ecjww,3142 +holidays/countries/grenada.py,sha256=yL2Pi79hKYcrGDLEqU8hQeTbOgzYsWrsjW0LS3Lw9A8,6598 +holidays/countries/guadeloupe.py,sha256=qgkQ1_Gn6Lqy52SHn6zQZCHG5qflBTWIrHKvctnw7sw,1218 +holidays/countries/guam.py,sha256=US2s3JoL6P3qoTPwgnWl5DE-HgkhRqzzJLxP6j18wx4,1138 +holidays/countries/guatemala.py,sha256=RHqEfOMadq--y5g1ksCtdoYRtRrJsx1Od8w1_XR50Y0,3145 +holidays/countries/guernsey.py,sha256=Zp-wTbvfnO5EJQXKtwBrsuLI1Jy7vOkgXQN95nR6nCo,14831 +holidays/countries/guinea.py,sha256=G-xWs-Ox_5PhROL1a8FcZgfe47a8ciY8cs0o7cCFmRk,5998 +holidays/countries/guyana.py,sha256=mqdUP2dCT6VmG6YqtjMKDoeDn_Jf_4VwmHT_lbSk5cw,9908 +holidays/countries/haiti.py,sha256=P1WhurSKFXAB15VLNeEQrmK8ch13RUMa8U632XwcI8c,4264 +holidays/countries/honduras.py,sha256=9J9_DvStkrY1gHEwxDREAA6NyBsGOK_Aj9wxxUiymMk,2789 +holidays/countries/hongkong.py,sha256=BazZC4UJ5gmBoAVY1Ej_KfUTP7Cp8m0rAx1zKhrYCl4,16298 +holidays/countries/hungary.py,sha256=Ub4cbHGk_kKavyUY6RzKbnKk9_43SDdYlDVOZ7X8oWQ,10561 +holidays/countries/iceland.py,sha256=crwo_LD9qc4uAQWSXYZCpN_drpsK11o7lrndeoATSE8,3001 +holidays/countries/india.py,sha256=N_SDn4pIy6metMUxIqSJ3CzB2UHXM1cX5HR1Ns0vF9Y,20426 +holidays/countries/indonesia.py,sha256=_s2v4iH1fMpALxCdXcNmABVwv5j44K4iO9RnSCtCzDc,33112 +holidays/countries/iran.py,sha256=lT0YJKgeN9S5VmREE9yVg7eyRYO2RnIMl7pLlmj_TWs,16092 +holidays/countries/ireland.py,sha256=9ibumJB2bxO4yIRSORlwchTXnW6pJVObodajFs0Xel4,3172 +holidays/countries/isle_of_man.py,sha256=VEZyDqGsQqn8sObZcycxSeTYwkovKDK4tcL2JAE6G-o,2588 +holidays/countries/israel.py,sha256=gprzVFaD2pRib-xxcnNcH1bwifTsBjj86G_bf5bQpzU,5097 +holidays/countries/italy.py,sha256=wz2Agj_HNrQscYwC0wJN8oXzogF8THDwA_v_aYT85go,22232 +holidays/countries/ivory_coast.py,sha256=Hi3tWG3-TiPUKqrujt8UTaNvguSBH66AK1xqnutAH24,6113 +holidays/countries/jamaica.py,sha256=FqI3wVQUVSRf3YDnST-w9Fi-Kq_9PIELnStV5VXkO9Q,2475 +holidays/countries/japan.py,sha256=qmcTkP9XYo38G-776NzOJ5o-x5cZQfU0aTlEnoe25kE,8914 +holidays/countries/jersey.py,sha256=Nurw6_pWFQJVRQogY3Xd5kID8qABtwbKEilNxF0Ri8k,10733 +holidays/countries/jordan.py,sha256=eJT9LTnu12a3-IrhbeGEoh3Mup1jweAftrOI1pQGoc4,3322 +holidays/countries/kazakhstan.py,sha256=K0AACexvn7E1xJ6EO5M2zz0EwHb0VXt_EcVe0p63sW0,12990 +holidays/countries/kenya.py,sha256=PBYjXdbBiIafripI-gcRNeZn-rPJgHOcHgk9vhKmZJM,8910 +holidays/countries/kuwait.py,sha256=PnnPe3Slk7vwmoCxH4FpuaV3MOAuoH2IvJa4EwimJFs,3235 +holidays/countries/kyrgyzstan.py,sha256=RYq5M3DdwshEJKZM957BMWacQ4ghVFIdEDG5bVmOGV8,3024 +holidays/countries/laos.py,sha256=EUIUAFb2NCRGO_OhxMV-CfKNHBdMHwyit8HwmfwBv8s,17678 +holidays/countries/latvia.py,sha256=wm8pkcHuKesA3NYTb9BHHcH31dWAyVXGIiLJgSBRebE,4261 +holidays/countries/lebanon.py,sha256=Xmc4lrEImCK5iUs4U_D-tr1bSX6UlZePVpwl1uAEtVQ,14776 +holidays/countries/lesotho.py,sha256=fTYUWvU2ko-C4GaLjAalYC1TVa4FEODV_7wHNQwAuEk,2781 +holidays/countries/libya.py,sha256=0lyzmAZ_o3p4MSCGl1BORTQ-F7dJ1T8Ass3jPTM91qI,8131 +holidays/countries/liechtenstein.py,sha256=9_EmpnLTJ4NSVEmnRPdObrl308DPH0sFBgFDUmWb4Mk,3282 +holidays/countries/lithuania.py,sha256=jhswyF3C20eHT8LpmXBoBDUNZ7JQ0PCO8nnkJRqkVGc,3188 +holidays/countries/luxembourg.py,sha256=glr76Wyfx27uCDBRWc8yNBMhK6CT-xnXgphlvgFHlr8,2205 +holidays/countries/macau.py,sha256=bdA3z9KCvDMkFP1BV4MlKb37gWqarK3Jod9bnL_5GfM,19802 +holidays/countries/madagascar.py,sha256=tjQWhGplc6xgnsX4GWaUUQeDSrZk0kVgBdAJDW991rY,3167 +holidays/countries/malawi.py,sha256=RYViAPnp9iu6eMC27g6NUILl112KDeME9akkWKrUp3U,2257 +holidays/countries/malaysia.py,sha256=zdyVkOQmT_rZKtm9b9qqP9hTY6YxcGiof4WV1ewlt2A,31433 +holidays/countries/maldives.py,sha256=VmxJsyHUqwy08gAlDsM1XTY9GzUddOVNwo0IieY0KKk,3010 +holidays/countries/mali.py,sha256=fNJ-41SaPvd4c-8SWqELhZv4LtRn94i9P6XZ95-FpJ0,4998 +holidays/countries/malta.py,sha256=u5WORShQHIsNeEiZ20NX5iLTLGoaefNZJrwjuIEqifs,5129 +holidays/countries/marshall_islands.py,sha256=YiC6U7cPXdD3I6QZYv2NnRCNjpWRepRXGKl1SkMECX0,3370 +holidays/countries/martinique.py,sha256=MPLSm1ZtrUTKdvqHSqg6xXWHPgipeAZo85qRakDZbVc,1218 +holidays/countries/mauritania.py,sha256=FtcfQxsW2G5XSsLNC0pJM00in-m3RLpfOm9CvU1weTM,2392 +holidays/countries/mauritius.py,sha256=XVlP5R0GZ2woAJNUGBNEXS2HKbpx2Oxsg_SG7YeMnIs,6971 +holidays/countries/mayotte.py,sha256=h8hcVVgvb3v2dqMnhf6Gu5S-dMP3f4aI3DOMmXMrRBg,1206 +holidays/countries/mexico.py,sha256=Hb64Hz2fz54gQkYT0ilAQhcwSd_ttE5iNqqRQ1Y_EtM,3338 +holidays/countries/micronesia.py,sha256=Y7otcCld8uj_axZ4_aZlICMIBGW7nczdd3_li4TZKrw,9329 +holidays/countries/moldova.py,sha256=Ez0m2am5rRSimDVy0Z5voX2Cu1RSdEM08nvpXD1jFZo,3370 +holidays/countries/monaco.py,sha256=ASHws-sNAXuxJ54ajqqJep5u8SZcz4l7MpDZaTIjE84,3103 +holidays/countries/mongolia.py,sha256=RfM0KY6nVznN1E7QgWflcSOYmGu1MiNoSu8NaufaMXQ,8281 +holidays/countries/montenegro.py,sha256=tGbdDEHfNnW9eU6nCkDzJN05S8Qk_hz5DF5S8vBcX4E,6603 +holidays/countries/montserrat.py,sha256=RM2JfLPKte9noKI75mIBc1CPtTnYvzQGWrUcFqDMw4M,8013 +holidays/countries/morocco.py,sha256=BQwiyXLtnE8RJlwjEj0C4ZqMzrIxO4IU-7Xjm6maUaI,3906 +holidays/countries/mozambique.py,sha256=1WHOPjr3JpzVR0NxpZuwNMgHsIP8N4zAlQ8WpU9uERE,2485 +holidays/countries/namibia.py,sha256=zqIP5ztoM_CBI0xgyjV9hMme_lrAc_MOwoFWJ5q8CXE,7628 +holidays/countries/nauru.py,sha256=i31C6cZJUBBYykGeyvIX7bi6i8hiLILeDFbQMARUOYY,5441 +holidays/countries/nepal.py,sha256=WnYGVsPqaTvr2EpbnHBEpfapJkooW3z8BGUbfEMmvzM,13669 +holidays/countries/netherlands.py,sha256=qhKS2XfnQlOrb0Vm9P2iKY5h9vNiP6rdSMKsSwfFTe4,3332 +holidays/countries/new_caledonia.py,sha256=N5DqUjhAvcO_uKxwoySsy9P-mvJKP9ArcBV28dpd-uo,1216 +holidays/countries/new_zealand.py,sha256=dEM7ZLQCHBb9gfUkPZWOK_FIWc2IubdGBa8xxrDHbHI,11210 +holidays/countries/nicaragua.py,sha256=OEnUBW5C1yJJ1o0CDnpsmAf_cG9P316hSACmFY59nXM,3736 +holidays/countries/niger.py,sha256=hrruaeyeK7_VKt5tXvuqTv4WegC4IE4Rn4rBTzYLo08,9896 +holidays/countries/nigeria.py,sha256=kBCxaMk4iQL9vZQMNc_L7lru0k772wtZrsmHmFcvJ8s,3514 +holidays/countries/niue.py,sha256=xQJCVJtL-gIcDtI9dI-YBIT39wLVbgu_60Q66V-cKl8,4487 +holidays/countries/norfolk_island.py,sha256=o8FbSCOSWLMtL9o-175x8-JYUCFeu4B08SB7u47qf9c,5185 +holidays/countries/north_macedonia.py,sha256=Iz_1N7r-NsRLCPztwUe1fpVLVGmsklW3tOIBKYRbwgc,11997 +holidays/countries/northern_mariana_islands.py,sha256=wCJkJAV1vx4AOp6P-Xw3lCQYTBg2Dd-3iJimxB-Io2I,1176 +holidays/countries/norway.py,sha256=bqkdNtMaySGBtuZ7hdeku2TMvj3tf9blFiaBfMQs3Io,4608 +holidays/countries/oman.py,sha256=ioy5xrmr1xYMhC7Y4uUcrNJsQCVWs2gWWycwDRsucJM,5837 +holidays/countries/pakistan.py,sha256=XfDjvolYQSsd8MJIVUb11oRi4DgpI_iJIxpdc4V--v4,6199 +holidays/countries/palau.py,sha256=KKXUzg4l5en30BzdPeZEJYB0tYea-mdDf94OVyzySpc,5148 +holidays/countries/palestine.py,sha256=igjb3uoHLVGNdm8W5mD3jgkyUkzCjoBot9vCmbzbIWE,6224 +holidays/countries/panama.py,sha256=sqUOszkEdNA3NwczAVXGelLt7kmw-zn6O75J1kC1Wc4,4738 +holidays/countries/papua_new_guinea.py,sha256=WxPOxe9k1WKDqv4uNPudi5BSm1McIq6A0ZKcpZcUMBM,8247 +holidays/countries/paraguay.py,sha256=9-vQdTuhOk2MI6cPsdQpjyn52-h5O7mU8meAnju8KH8,8945 +holidays/countries/peru.py,sha256=g23z-Z0udo67xTuPbeM7gMLDzQ-s1cSpsS2J9aAd0aY,3456 +holidays/countries/philippines.py,sha256=WFhS9HZR34JOy3WB3TfFZkmtZ4JMOb2Mf3nkO6fuZ0k,12117 +holidays/countries/poland.py,sha256=Idf437U3u9SO0w-GnyDjebV40WU9kaWTTzBvx2RQMv8,4666 +holidays/countries/portugal.py,sha256=jJUcKvfJMMYE5YFe_TEQACRChdhwPHt7mEDrdWz6-tg,9958 +holidays/countries/puerto_rico.py,sha256=ov7SNpgEbzkEuPhmifn6twz4j9g0YPIGOgtWO4Afol0,1151 +holidays/countries/qatar.py,sha256=b0Eh9c9OTn1QF39Pw2mcOT6qYNMfHZ-_2Z9liJKTFKs,5248 +holidays/countries/reunion.py,sha256=RJYIu-gkRxl4dNnIOZemCi36OPGV0wpJ03CpnMQBaWs,1211 +holidays/countries/romania.py,sha256=cvCIXRcAD_4h-azPO82DkFIOI29ZBHCkBFs_x5XuUDE,3055 +holidays/countries/russia.py,sha256=5OR4HoeHTa55flXu_aWrtG7jbK5fv9I0ojChng61t3w,19990 +holidays/countries/saint_barthelemy.py,sha256=8Ut9dSIszHoK6oYcHjJd7f7P_2sjDR0owfg0OUoJOCU,1199 +holidays/countries/saint_kitts_and_nevis.py,sha256=1AnDEprkmfrQbJM2j93kudGOhlMtqoNW3u_iALDPNaQ,8984 +holidays/countries/saint_lucia.py,sha256=eQAvIkDulpQe7W_OI-7hdgdMllR9zzEq7YnWWwFD2UU,3222 +holidays/countries/saint_martin.py,sha256=viZYplDJ_hbk3scK_BlaiuwPxTmVj5hMz5ZQjbI_4iw,1201 +holidays/countries/saint_pierre_and_miquelon.py,sha256=ZoGf0gAvdsrNBUHCcGr1eGnpKTzmraS2hc5YnN0QxIc,1217 +holidays/countries/saint_vincent_and_the_grenadines.py,sha256=VLx3fPvVzwQTy2pC4myNm4k7LYTaezUwDsPu0aouRH8,5479 +holidays/countries/samoa.py,sha256=YF0C9pAKahP7QS9Gkq8DEIjdL6KGOHyvfHeoNf1dz5g,2344 +holidays/countries/san_marino.py,sha256=BaWmz3ZgKMFHah5mnx1Mb7go_m-iTRTD4ACntDlhG7U,4067 +holidays/countries/sao_tome_and_principe.py,sha256=CeY2Ijjis0aDHGuxtdp-lFOFJUw0UncOm4A4kvs_uzU,4073 +holidays/countries/saudi_arabia.py,sha256=Cb2K8MpBRMoDcAveVGpUawEHIqfKexAuqZghfFukqPY,5011 +holidays/countries/senegal.py,sha256=MgX5kvdfwFWQnl2kc1qKFYxjUDgEoH93CUXfRD7LMOI,6671 +holidays/countries/serbia.py,sha256=HSerfR91eeFY2IqSaA_JFDOl7iykLcVKk2w9Q9sgYh8,2843 +holidays/countries/seychelles.py,sha256=NJcduAy2p-jwEkNil1hRl5izAZP-TJUPIcffPzHLjks,6883 +holidays/countries/sierra_leone.py,sha256=1rq4cHJ4RW0dnqG_6yXhmQkuLDcF75UeDrkJS41_4Gc,4837 +holidays/countries/singapore.py,sha256=FzKajp4yX2xIn-aYy8yOFZUb4bOerZKVGI7F7Vc88BY,10276 +holidays/countries/sint_maarten.py,sha256=vRAcncQ2lhrPyZ8JlAAy856RoJUquIJEsc8fRA6FaZM,4136 +holidays/countries/slovakia.py,sha256=phzXXMH-tjucNUa5Z_qSQeyCeYgGaEoWi_mYJcPF-pg,4221 +holidays/countries/slovenia.py,sha256=ofhSDvSKQW6DXxCuLCchAAAT24CUp8pkUqjytnzdyes,4837 +holidays/countries/solomon_islands.py,sha256=XXcZfAccPmzaaVoNaWSgKV1gSRDd3kui9va9qaMX4GM,9015 +holidays/countries/south_africa.py,sha256=2gMKcAkPk14uYRq15DOQ-zz8jIV3LpMTppIBRSuu6gg,5933 +holidays/countries/south_korea.py,sha256=Q_imGBe8HIwVZAKbYor84RW9T0FnRHrAEvj_mxcogOk,24512 +holidays/countries/spain.py,sha256=O_zdlqhyz0Svn030NDCfVGD9jHDoe7NLpotkyzbT_tU,29652 +holidays/countries/sri_lanka.py,sha256=ba3v6hncjr9kGaF3sjmtl0JK9opaG6l2eFSjjFV4-XQ,20299 +holidays/countries/suriname.py,sha256=9-UsXe7rnx8MLmSVQG1b6l8HGtaoxzyXj9BcX0uFceA,7488 +holidays/countries/svalbard_and_jan_mayen.py,sha256=Jq0_MoHGXs_NKoJdvv4D_cNZLT8RWo-vy5NedT9GASg,1123 +holidays/countries/sweden.py,sha256=Fo-CB0l3upY6shCL_eiEcvEobcZKxaHjEozoIqnrLY4,4203 +holidays/countries/switzerland.py,sha256=YBfJ0AMZb3scpvnSvOPSmkk4m8RvyeD__WNa79w5m00,17145 +holidays/countries/taiwan.py,sha256=BuRzqId9wHzzQNirz4iUJDSfrzqJuZ244ac3Bb5rmBU,18233 +holidays/countries/tanzania.py,sha256=Sirhpui7iml-aPmySixMt20m4MXFwmPoWVYU2BYLBn4,11363 +holidays/countries/thailand.py,sha256=LWCjZ1r-lRjwvoYZ5LDqrE4ASJv1YoT-W0EMcm-pcJY,60961 +holidays/countries/timor_leste.py,sha256=Kr_YmgDOsAB_YXb0UmugtPglOi1Yt2jsdzG3mazb8IA,24815 +holidays/countries/togo.py,sha256=L6ybYzHYufo_5nJkEoBBsHPq9A9yFU411PIhEgxUvGk,7290 +holidays/countries/tokelau.py,sha256=V3YqIdSgGH_aD-UfO_B8FMxYBSt8npQO02NfZQlkAMg,2078 +holidays/countries/tonga.py,sha256=nCGewL1qk0lf9sWX66q5HDl_JO7b_m6IH5q4Gq9-Hw8,10146 +holidays/countries/trinidad_and_tobago.py,sha256=8BRurz7R7-fBUoKTfFYkxK3dvicT_hL__1v4LBlP4vY,6908 +holidays/countries/tunisia.py,sha256=3MDTgfYmOX1oYk1ynJLRoWZ6fRAVtUsp2vXxeMXILQw,3074 +holidays/countries/turkey.py,sha256=MG2f45QFz8xi9IprYteAilRWxpI9e6AEyKY-svWdz7o,9771 +holidays/countries/turks_and_caicos_islands.py,sha256=jySGlOhdtp7Yl-wWdL3BbQAK_xasERfWkfiGAKtBrLk,5635 +holidays/countries/tuvalu.py,sha256=pBJYGSqPAPyk9euH9NEX5BBNWUcYTiry9A7bEaPQAcQ,6410 +holidays/countries/ukraine.py,sha256=MIy0-5kHq9qnuqXkwC5Huah9B8dLztTVw-CBJZGrBN0,16650 +holidays/countries/united_arab_emirates.py,sha256=KhoJJYm55hgdJU2hli6WRxfbfAA2OPW48TW9xfoKBc8,9736 +holidays/countries/united_kingdom.py,sha256=wGKClKJiordN_enA1VhOS23x7tSTtM5EzsVSGIfRCIw,7673 +holidays/countries/united_states.py,sha256=5CcnFSOziN159ml-fNLMipJHgkszwGnyZPFPwj0jGG8,54853 +holidays/countries/united_states_minor_outlying_islands.py,sha256=rl5UoQRLwcN7npZDcqeRPaB5Y7PshydRI_rjzSMbDec,1228 +holidays/countries/united_states_virgin_islands.py,sha256=u9jBUDZG9XcVBR72EPr5Vkmvsh7PngIFsImijJrQcKY,1192 +holidays/countries/uruguay.py,sha256=4OGQQ4IT-bu0wwwe-_9kBAnX-G4YemD_7w375ShotEM,6535 +holidays/countries/uzbekistan.py,sha256=IAm6Z6KHYPSppKFl3eBFj5jSw4MvHFyJ-LW9YJP8vpE,8450 +holidays/countries/vanuatu.py,sha256=KnXVG-8PhTGrp73jXBSQ3261rku_vu7lOdcJCtKOMrQ,3543 +holidays/countries/vatican_city.py,sha256=4afXzcsJsWjWENHuTgPKqG0-l0A3ah5FkR--Ef9cUEM,8196 +holidays/countries/venezuela.py,sha256=QCCt53734NVUgcAHRyNwtucgPQSB-CBGO_Un6NJA41s,4556 +holidays/countries/vietnam.py,sha256=-PSuQVdgvsWu_iBne2EaeTbE6YcxTsHhU1Nj1HfPk90,6566 +holidays/countries/wallis_and_futuna.py,sha256=ydAcsCxb0ezUZmSaGLkNOgtGNlbUQWuqtKi5GLCqtIE,1208 +holidays/countries/yemen.py,sha256=puKDnXJoT93iM0bdihZBu3JdyiFPsAYLAOrYQlGzSfs,7473 +holidays/countries/zambia.py,sha256=_8FpItIcUR706zpCVWxrUPcNUFEvph6O6jSWBdIVV98,4040 +holidays/countries/zimbabwe.py,sha256=pKtQxJZnZuGlSbhYOmjokbDOFV7EQGivByfqdA_WKeo,2842 +holidays/deprecations/__pycache__/v1_incompatibility.cpython-312.pyc,, +holidays/deprecations/v1_incompatibility.py,sha256=zYekWOcZB_NjQZg6w6tsNIcVTwLPrEPWQJQnjd4bF4o,1853 +holidays/financial/__init__.py,sha256=bQcGJ65bAnBIbiTMCzebHuI_0LsiDtspjBryfJIzCMA,875 +holidays/financial/__pycache__/__init__.cpython-312.pyc,, +holidays/financial/__pycache__/brasil_bolsa_balcao.cpython-312.pyc,, +holidays/financial/__pycache__/european_central_bank.cpython-312.pyc,, +holidays/financial/__pycache__/ice_futures_europe.cpython-312.pyc,, +holidays/financial/__pycache__/ny_stock_exchange.cpython-312.pyc,, +holidays/financial/brasil_bolsa_balcao.py,sha256=K95QMPmsbGSAS-6bDLS_QOxir-P4qFY_LdPf7lhgeYA,4925 +holidays/financial/european_central_bank.py,sha256=2u6zd12t0DHQB3RpPRM_lfZKkG5B3m7ZhQFuXFijXPA,2168 +holidays/financial/ice_futures_europe.py,sha256=aTOVWzjSDu4Y5XLSvGhWfqDBmecTiA0UCVxPqQcWrh4,1861 +holidays/financial/ny_stock_exchange.py,sha256=6hSGW_-pEXIlgb0lOO6DYcCVgb33see2yROWJRbdR0U,10896 +holidays/groups/__init__.py,sha256=7Fuo39UxhtKsWV31gMUZmFkyylJCkeXVtG_ThshKNT8,1379 +holidays/groups/__pycache__/__init__.cpython-312.pyc,, +holidays/groups/__pycache__/balinese_saka.cpython-312.pyc,, +holidays/groups/__pycache__/buddhist.cpython-312.pyc,, +holidays/groups/__pycache__/chinese.cpython-312.pyc,, +holidays/groups/__pycache__/christian.cpython-312.pyc,, +holidays/groups/__pycache__/custom.cpython-312.pyc,, +holidays/groups/__pycache__/eastern.cpython-312.pyc,, +holidays/groups/__pycache__/hebrew.cpython-312.pyc,, +holidays/groups/__pycache__/hindu.cpython-312.pyc,, +holidays/groups/__pycache__/international.cpython-312.pyc,, +holidays/groups/__pycache__/islamic.cpython-312.pyc,, +holidays/groups/__pycache__/mongolian.cpython-312.pyc,, +holidays/groups/__pycache__/persian.cpython-312.pyc,, +holidays/groups/__pycache__/sinhala.cpython-312.pyc,, +holidays/groups/__pycache__/thai.cpython-312.pyc,, +holidays/groups/balinese_saka.py,sha256=1hMUC-o6Aq4OLerPiHnClRoUaDq0iY89J8zZ6hInso4,1550 +holidays/groups/buddhist.py,sha256=qRleoAALM-CYkfgTcjIwfGCi1euVl1Pa8fjbfqvbsYc,2224 +holidays/groups/chinese.py,sha256=WClAZw8Qxi010fdyKXPCYGm8Qzf2UZkQqyEw_qA3SXs,10232 +holidays/groups/christian.py,sha256=Klh5jmD_TQQypOOPAR5MkMR-lwnShu524EWDQOpykxo,17285 +holidays/groups/custom.py,sha256=-J_3aP9fNOaekg0yy0N2hcocu3VCCnt5GhH31anb0uI,1966 +holidays/groups/eastern.py,sha256=-tfMyMdyWBrhigfUNcc9KWUhonCR-4Spy1T-Th9oPq8,1608 +holidays/groups/hebrew.py,sha256=bJBluUDSnw4ypCJ_-ujPhL0v_H5GzTOrbnfbEoRSqLw,5632 +holidays/groups/hindu.py,sha256=qFYx-Pe7mRndzd2eIF3SVGdbPrz5vOmuRxVYZeTgM9c,18346 +holidays/groups/international.py,sha256=JugC7H9meqI8yA61g-AQcJKAjj9Gw8EtyIi90YTJQWU,7932 +holidays/groups/islamic.py,sha256=6B1xmjWR7n7gZDgFZWhhJD96d4cpxiAe9HFTX1EEZDA,16113 +holidays/groups/mongolian.py,sha256=du_O2WVP5PiP7bpKrlnnnxIJy-4meco7mW3h9zuElK0,4119 +holidays/groups/persian.py,sha256=dlV0t6KCieKA5mq0D_SxEGSf5RORzGWpO8JNo9OnYn0,6590 +holidays/groups/sinhala.py,sha256=0amb0O5-6wgrsCjui1K1OQwt2bjZWBwbaz5zhvi9XDQ,7124 +holidays/groups/thai.py,sha256=aJxilGPwDKyoCK_7HjfMlkrstPo17KSBMzP3MEoC6bo,6777 +holidays/helpers.py,sha256=PPCLc-YhNrK2_-2Zdy-K0Ip3F6hzJILLC9GnR8jSPQs,1382 +holidays/holiday_base.py,sha256=gRuetNZhzhQqMbm3fl7JQwJhJ_oAgX4o9tmPHCtWLEw,54869 +holidays/ical.py,sha256=edR0dmrtpio2KhgZhzpna7xuUlhorzFcN2rPyvUut8U,8466 +holidays/locale/am/LC_MESSAGES/ET.mo,sha256=_O7Yyd07dmM-dQVI7x9U7QZeKR43jHm4uFaEDnkzV60,430 +holidays/locale/ar/LC_MESSAGES/AE.mo,sha256=CcSUP5y9rIlctZRrTGkrx-6AchU207UasVT_KY70uzs,428 +holidays/locale/ar/LC_MESSAGES/BH.mo,sha256=CcSUP5y9rIlctZRrTGkrx-6AchU207UasVT_KY70uzs,428 +holidays/locale/ar/LC_MESSAGES/CA.mo,sha256=rxZl40i3RIAzQ6vup1DS-g8U7pFJQqr6ybC9R4uO9Ug,2509 +holidays/locale/ar/LC_MESSAGES/DJ.mo,sha256=a_FlFv27rK-DKcyHQ-nRKWEeLprPx1_bCXgjavaw51o,1301 +holidays/locale/ar/LC_MESSAGES/DZ.mo,sha256=CcSUP5y9rIlctZRrTGkrx-6AchU207UasVT_KY70uzs,428 +holidays/locale/ar/LC_MESSAGES/EG.mo,sha256=CcSUP5y9rIlctZRrTGkrx-6AchU207UasVT_KY70uzs,428 +holidays/locale/ar/LC_MESSAGES/ET.mo,sha256=fIXu2E4ERZ_k7t-Ufrrmswsfp-FpVBu_MHJ-zoGHPA8,1999 +holidays/locale/ar/LC_MESSAGES/JO.mo,sha256=CBOy5tlaQWvVVAb4HyEUV4vz3oewk0tHGr-GMgUSshU,428 +holidays/locale/ar/LC_MESSAGES/KW.mo,sha256=CBOy5tlaQWvVVAb4HyEUV4vz3oewk0tHGr-GMgUSshU,428 +holidays/locale/ar/LC_MESSAGES/LB.mo,sha256=SLAjae00fYJzheDzGPzwzBcYsEUbPouqyS74IGw_krU,415 +holidays/locale/ar/LC_MESSAGES/LY.mo,sha256=nmhnOubL03MO_IoUVLQsQczv9oJBoYlHhuraR7njmh8,415 +holidays/locale/ar/LC_MESSAGES/MA.mo,sha256=CcSUP5y9rIlctZRrTGkrx-6AchU207UasVT_KY70uzs,428 +holidays/locale/ar/LC_MESSAGES/OM.mo,sha256=Eysu-trnqvbMY5jxYNyyYdGQNVdnDiQXnx4X5vxrOHk,427 +holidays/locale/ar/LC_MESSAGES/PS.mo,sha256=Mam67x7_S-SRc0SKB-dWfd5VdMWC-BXCU7VHEO6ebBo,416 +holidays/locale/ar/LC_MESSAGES/SA.mo,sha256=RZlCFlCZMNCgbYSUq8Y-LiYf1d_5ba1qJ_WJL_mdC2w,428 +holidays/locale/ar/LC_MESSAGES/TN.mo,sha256=CcSUP5y9rIlctZRrTGkrx-6AchU207UasVT_KY70uzs,428 +holidays/locale/ar/LC_MESSAGES/UA.mo,sha256=VgbDJ9yaljSrC4humw-hSh-d7njsUkSy94Y2-H0km04,2603 +holidays/locale/ar/LC_MESSAGES/YE.mo,sha256=8AiplqRygeNGgwoo9M0FXBh-xxsgc5dPT9JCDWs_foo,427 +holidays/locale/ar_QA/LC_MESSAGES/QA.mo,sha256=yfZC9CPnD3B7sOjwy7fDKMggPbKRpt_kZwoQn7PetRA,422 +holidays/locale/az/LC_MESSAGES/AZ.mo,sha256=cd7d2bAOPmNuO0g2TXvMA7wSfR9y2TFRcYWE16R_FEM,428 +holidays/locale/be/LC_MESSAGES/BY.mo,sha256=4mOfnAKZLWrEdN5eSsjl0tOznKQ3ecA7OhvwUc_zsns,430 +holidays/locale/bg/LC_MESSAGES/BG.mo,sha256=dNKuKggj_pdeCZfnQBfZqOcJGsbJm6sfTg0FIySEbUY,430 +holidays/locale/bs/LC_MESSAGES/BA.mo,sha256=VohPus2NuXdqkSDhs1gvx6v05Q-n_FKPJjlOj3IxwXQ,433 +holidays/locale/ca/LC_MESSAGES/AD.mo,sha256=5iVdiMIEOCCmDF4WUrloxO0S2yS_OQNxnJZ7Tp3uz-U,427 +holidays/locale/cnr/LC_MESSAGES/ME.mo,sha256=kYP6vXh8xWbFG6atpZuuuRyEPrBMe6e3-tqGmRLVd20,429 +holidays/locale/coa_CC/LC_MESSAGES/CC.mo,sha256=MqgRBvwk1p8H4lCfr0NSv6Gm_qS97tW_5dfEnKGvR8M,1376 +holidays/locale/cs/LC_MESSAGES/CZ.mo,sha256=vQE_f2BgRsDK1NWF2iQLGeJTN4kvEvKOYJ931L5xBwE,428 +holidays/locale/da/LC_MESSAGES/DK.mo,sha256=3v-juxEuZIyWyeLFrkyWc8YJh9bHNy75b4viY9xLgM4,430 +holidays/locale/da/LC_MESSAGES/FO.mo,sha256=iLsox7FLn-utaxN6rYq_hebqMOpbl6keSZJY25CEAE8,1165 +holidays/locale/da/LC_MESSAGES/GL.mo,sha256=VmLNuZNuSLrUSh9w507HG5aoxzaAUaggueqc02jjnfs,1163 +holidays/locale/de/LC_MESSAGES/AT.mo,sha256=VKz21lIRtcqvCt0iiIsfU9wVFANRre4_UMQsGnQZIw0,433 +holidays/locale/de/LC_MESSAGES/BE.mo,sha256=0mq6hUhokL_rIKxVOyuW5_CjIHFhGmtNSDvcYuspUkQ,1126 +holidays/locale/de/LC_MESSAGES/CH.mo,sha256=gNUFen2pMWlXvXN63dJHx94vPXoVTWBxK6zzmpxgTRE,431 +holidays/locale/de/LC_MESSAGES/CV.mo,sha256=m5N1av7GHhfJZzbEG5CYH5tjWckGKGUjBwGTYF4ZofI,3174 +holidays/locale/de/LC_MESSAGES/DE.mo,sha256=2CLfV9wAuKTmoBq0MlC8lHtqjN1Ol4XRTMOkJCnSnzc,433 +holidays/locale/de/LC_MESSAGES/LI.mo,sha256=y03yx4Wv20KEH6-n9Vwp2K9n08FWzMmVJ4UbmWDDiJ8,431 +holidays/locale/de/LC_MESSAGES/LU.mo,sha256=570ATcj399-Fxq3HtJesCXzOT1joP5il8nrHIUTCo_s,944 +holidays/locale/de/LC_MESSAGES/PL.mo,sha256=wTXbkwtEu5OCFQEctHpoOCGd347P2XO13xaq1M0L4YY,1990 +holidays/locale/el/LC_MESSAGES/CY.mo,sha256=yBBdP5XZikLzJ5rqNsr3b5kH20sPH2-I5u_GRTB8WhI,430 +holidays/locale/el/LC_MESSAGES/GR.mo,sha256=W_g6vg-PMpEy5DEYgDeFnchju8uzaAZEsRgUTXDxZps,430 +holidays/locale/en_AI/LC_MESSAGES/AI.mo,sha256=unoEwnlcIwwIthW1LYsvpsNErDVwFVcpCDYSqedAeFU,431 +holidays/locale/en_AU/LC_MESSAGES/AU.mo,sha256=tmRtUEl3D4-U2p-feFjGorTCSoHzHsJ54_QNrFPC_1U,435 +holidays/locale/en_BM/LC_MESSAGES/BM.mo,sha256=5JdgazpI60bhyon1x0lxts4wjQ7UdhjEccv8OivnsEE,421 +holidays/locale/en_BQ/LC_MESSAGES/BQ.mo,sha256=JYQ2BTDQzbXz095NR319IJImH6F_xUO7ru50bI9OWho,1216 +holidays/locale/en_CA/LC_MESSAGES/CA.mo,sha256=VvQth9ZJYWHHq6MSDt7TigOS2tbiWLGDd7FCq1QoPgU,436 +holidays/locale/en_CC/LC_MESSAGES/CC.mo,sha256=AluAUQjiS9nwUFvBVvAGNHsB5ThNuxvFPZ6kf7kc04M,446 +holidays/locale/en_CI/LC_MESSAGES/CI.mo,sha256=SmYxacdPQNa99ZprNA29Vbad-tkYAg2rjPwYmC1tad8,1725 +holidays/locale/en_CK/LC_MESSAGES/CK.mo,sha256=LtFQZ9KtuZzie1w8LOQyiYe2RqeoOUorX5TIL7irKgM,422 +holidays/locale/en_CX/LC_MESSAGES/CX.mo,sha256=Y3C8LbvY2bDTxJ5_ffFlx6q2Dx_8GjKRMg-dW2_0JmE,437 +holidays/locale/en_CY/LC_MESSAGES/CY.mo,sha256=2OZlHWw2poOp21Psj4VHep0ON7Cw28twwARsG8R7MM4,1669 +holidays/locale/en_ET/LC_MESSAGES/ET.mo,sha256=FBQhfHq_V4ea0s-r_XTiOe9LhOz7SYM0h1B1NejYWpo,1734 +holidays/locale/en_FM/LC_MESSAGES/FM.mo,sha256=79m9SrSxO9oB0SlnzstkBOX2IfW7WhKO9z7bUWwBfkk,421 +holidays/locale/en_GB/LC_MESSAGES/FK.mo,sha256=pYMsmaH-UYPTFtI9891LKD8eRZThybiaIcb8vaVxLpE,420 +holidays/locale/en_GB/LC_MESSAGES/GB.mo,sha256=qJAr_3fmg5ZrtLE1h1QbF7wygwfRO49gjj-qC4AXLDs,435 +holidays/locale/en_GB/LC_MESSAGES/GI.mo,sha256=vmRZPWXedFCbX-Ezk8FILwtLbwPApJhD1TALQy2U6Wc,422 +holidays/locale/en_GB/LC_MESSAGES/IM.mo,sha256=7DhOKtNSVM_LbzY2h6YPzFCoqZkBI22QjhUceXD6dvU,435 +holidays/locale/en_GB/LC_MESSAGES/KY.mo,sha256=sTMG1keBzu_Y1yKJ1H-xhax1WpQlLNrg__B-MuJiVnE,420 +holidays/locale/en_GB/LC_MESSAGES/TV.mo,sha256=YS0hvCWlDCvSVaPOeYTxamUu-ljf9fL7rNZ5sL4Zc4k,1494 +holidays/locale/en_GD/LC_MESSAGES/GD.mo,sha256=bHvuzmkf7QHbF1W7Z1tYHn2GOX4C4XkOYaRUss5oqjY,421 +holidays/locale/en_GY/LC_MESSAGES/GY.mo,sha256=6bMMeq8pC9ElG9k6pceLkNOIZxsUea4RW8WZvDbhC0g,421 +holidays/locale/en_HK/LC_MESSAGES/HK.mo,sha256=NX3Uk1kbnpcJMCH1nIrAndBq28z4mKBBoAyrRjhazB4,3464 +holidays/locale/en_IN/LC_MESSAGES/IN.mo,sha256=egpGOzOVAawpzumQh8JUjSrizF0rs-JWPlRpWZIZjuo,450 +holidays/locale/en_KE/LC_MESSAGES/KE.mo,sha256=fR-7LEqVidlv1pkZZ4bBVSbGleqPU-d6WLeyIvRfksU,433 +holidays/locale/en_LC/LC_MESSAGES/LC.mo,sha256=jzpxLYkf9em7TmiGjmLkY20fiohIzPzLRvR8KBC3-gA,431 +holidays/locale/en_MO/LC_MESSAGES/MO.mo,sha256=iRi1XQ06geXQai80-VWWJXg7jVaBtKHBAMGzKwNuAGk,4339 +holidays/locale/en_MS/LC_MESSAGES/MS.mo,sha256=qTddAnK3J_ZNLSyKlGOnIymS_4MW7-bBJJNocCv0JIk,422 +holidays/locale/en_MU/LC_MESSAGES/MU.mo,sha256=3QsHkknWiMl3Y6M5HoaxAxyCndxcEjXopdGpRZl7f2U,421 +holidays/locale/en_NA/LC_MESSAGES/NA.mo,sha256=LBEFnSOjPcXdLTRzUi-2AtmbUO3RpUzoa2-YMP8i5IU,409 +holidays/locale/en_NF/LC_MESSAGES/NF.mo,sha256=Rz4rgBFqnC0TW_3GgJvm4bqvXyIdNnlgKnSKV3Qg74Q,413 +holidays/locale/en_NR/LC_MESSAGES/NR.mo,sha256=J4L2xPOpXp1oRwaXqB5B4vU9ly7nVYYqdYq8Ru9R4fQ,423 +holidays/locale/en_NU/LC_MESSAGES/NU.mo,sha256=vKZo4f6V91fhb_-CMGm5561orhA4fjBKbg62rClZhNU,420 +holidays/locale/en_PH/LC_MESSAGES/PH.mo,sha256=27UwFnI2CSAqOx-2wFaz-YEDx2B8cCiRY28n_NFboKw,435 +holidays/locale/en_PK/LC_MESSAGES/PK.mo,sha256=S6HOEpBi1IWpKLh9RkCCIxhHhcOsoc7z1WatAk3KBm0,446 +holidays/locale/en_SC/LC_MESSAGES/SC.mo,sha256=ph-IFX1NAJ-v5GJ9Y2im9ADXcuMKR4y0fMw4EymtJ0s,438 +holidays/locale/en_SG/LC_MESSAGES/SG.mo,sha256=H3sUZFFFoeVtPGna52kplGdapK6hdkkR6_hgw9IGIRM,435 +holidays/locale/en_SL/LC_MESSAGES/SL.mo,sha256=831W25snQRS_tcDuTC0yz7szN2nraHiVoQwFPs_n6Pk,1162 +holidays/locale/en_TC/LC_MESSAGES/TC.mo,sha256=3HSMqY2oVG1OWZ2La17a0vKpQrPEuny5EguNTisro90,416 +holidays/locale/en_TK/LC_MESSAGES/TK.mo,sha256=aZbdswDHhucQtnkFSTuE2BeXbMxQDwEFgdUGu552lD4,413 +holidays/locale/en_TL/LC_MESSAGES/TL.mo,sha256=ZG52Ql2_oc6vMHiB_RIEGDorPVhO0-YZrMshPm2PvXQ,2987 +holidays/locale/en_TT/LC_MESSAGES/TT.mo,sha256=0ofF67o8iLSdufZyiyyUEnVcTWq8FFO638IqM0qzq4k,423 +holidays/locale/en_US/LC_MESSAGES/AD.mo,sha256=YkREZOSB6Pw_mEhWodJnzKUwsl-Fcice3Yh7reVTNkI,1944 +holidays/locale/en_US/LC_MESSAGES/AE.mo,sha256=6UCl8hemzn6bZEOKAomo87Rpy_tTNX3Rf_jzZfRBBBw,1320 +holidays/locale/en_US/LC_MESSAGES/AF.mo,sha256=lDdJ64OGb1lzsEi7GpdWYB1GHo1TL_R8uYlSqGS7Qzg,1372 +holidays/locale/en_US/LC_MESSAGES/AI.mo,sha256=WG-_8-2ahKQynCbf1aHa7ceulH2K_hHdX1pwzTfsavY,1784 +holidays/locale/en_US/LC_MESSAGES/AL.mo,sha256=PTVY0dlk3gqP5MRHtpMbE0Ew_QafAZdTsxOwXJyuV0s,1572 +holidays/locale/en_US/LC_MESSAGES/AM.mo,sha256=KgUkRTivoW2LwRiq5gjtLyvON6-x2pKFsuWbDzG_fcI,1536 +holidays/locale/en_US/LC_MESSAGES/AO.mo,sha256=o_doGFXD5ap4IYHPII3BHIdK99sc8giXdu9XBaJl7S8,1892 +holidays/locale/en_US/LC_MESSAGES/AR.mo,sha256=U_TOmuNxYM3tVqSZ7fZWtdSjglY7PK1tZmFxD9gTasc,7790 +holidays/locale/en_US/LC_MESSAGES/AS.mo,sha256=atsqriiTEonrf3s5Ikpft5tZb84sxKb9AZum-8gotU8,435 +holidays/locale/en_US/LC_MESSAGES/AT.mo,sha256=PRDYuqHb_4al0ig2jfA9juvgNuHARLmRCePANyp1FhY,1451 +holidays/locale/en_US/LC_MESSAGES/AU.mo,sha256=GTrQqhw1ClPnel7M9VMwjQJ40zBPODwDw0Bu9pJWZjE,2288 +holidays/locale/en_US/LC_MESSAGES/AW.mo,sha256=gwXqq4QKBWIu5FIzBsG9stlZrLWLG4HU0i4O8zhsFtQ,1156 +holidays/locale/en_US/LC_MESSAGES/AX.mo,sha256=PTZYBdfUdfDdmhjOVygvJ-fnRgVoJAaqIp6r0H2FoV8,436 +holidays/locale/en_US/LC_MESSAGES/AZ.mo,sha256=mOSkZIYkm5L5eJQ1Uwu9f2zhoNmSNcejFG5nDeFTFXE,2030 +holidays/locale/en_US/LC_MESSAGES/BA.mo,sha256=sVDOW5fA0_eX2YFLCz0GPvyPjvrxfGhZK-ycdrTkpgc,1721 +holidays/locale/en_US/LC_MESSAGES/BE.mo,sha256=ErBh6R6IeixT8VI-I5i8wOpjlpGxMLjgKi3hAvbk0tE,1118 +holidays/locale/en_US/LC_MESSAGES/BG.mo,sha256=0itpj7NRo8rjZfl91xFWoBRuGwh-9t4H4hnPPgDO6tg,1801 +holidays/locale/en_US/LC_MESSAGES/BH.mo,sha256=0fw5e1mT9YqY1EeN5TMrlt8VKy1Qt64vD_DLpLxkFWc,1090 +holidays/locale/en_US/LC_MESSAGES/BJ.mo,sha256=6kqQ6Xzkp-C38PXtalEl24vV5UGdjgsVhlEbuHPpL6g,1630 +holidays/locale/en_US/LC_MESSAGES/BL.mo,sha256=11h_PNcIOizEJ8ksLIAFm_kSal0oREgNE3bTp_VneQQ,432 +holidays/locale/en_US/LC_MESSAGES/BM.mo,sha256=2Rx_CGi0UhJ5GBL6wdxdaccUTFz0m1goQo6g29-TDCo,1338 +holidays/locale/en_US/LC_MESSAGES/BN.mo,sha256=w5o1vfvn4dHknjWruUrvFj2ue88QYxqW-i4LuW08PeI,1681 +holidays/locale/en_US/LC_MESSAGES/BO.mo,sha256=JwG92nsYXiS3y6-n-zE1TU-wRpbcX1vzrmbbfnJYnZY,1665 +holidays/locale/en_US/LC_MESSAGES/BQ.mo,sha256=3-eZs5KvCgyLlNgqDTAwSXYaTxYtYZmgD1rhQPv3rBw,1215 +holidays/locale/en_US/LC_MESSAGES/BR.mo,sha256=F4ZP3sH8uVAwTAYknG-6IVnPuPhfFFtZpn8onLjPlZY,4213 +holidays/locale/en_US/LC_MESSAGES/BVMF.mo,sha256=63lPldmETG0K1fcnm-w6jhYDxmxwpOoHbPf8iGiqPXE,1142 +holidays/locale/en_US/LC_MESSAGES/BY.mo,sha256=hvWuc-LISZxrqT2d-fuKzROHBMUhJKZwiFHjJdJatGA,2376 +holidays/locale/en_US/LC_MESSAGES/CA.mo,sha256=ne2spS4yehcta6UxP4ocbMnLcP2fdKpWPX5cXSr8M44,2130 +holidays/locale/en_US/LC_MESSAGES/CC.mo,sha256=08t1yXdzRhUPDNjIZqguEXulWbb23gbB24p2_0OUy1E,1364 +holidays/locale/en_US/LC_MESSAGES/CD.mo,sha256=QzfMCe1d7fBPrL4y30ds5mM-S6oXErwBDdqNFUtQm0U,1861 +holidays/locale/en_US/LC_MESSAGES/CF.mo,sha256=IByNuKdtsV141dI1I7_IMMfXfjXvUNu4OfJgTGwoLu4,1141 +holidays/locale/en_US/LC_MESSAGES/CG.mo,sha256=VKeouM5JE8UST1UPkS7Etu8osGurLGClh2_URoMTVRM,892 +holidays/locale/en_US/LC_MESSAGES/CH.mo,sha256=cZqgx5g0JcJ-cqm9zMKFbvHLiE7ZM0bQNapTfOqPGDA,1598 +holidays/locale/en_US/LC_MESSAGES/CI.mo,sha256=Lqf75oUHD7EbSG8kY9CDrV1Noykc3i1goGFmq7c9H9Y,1735 +holidays/locale/en_US/LC_MESSAGES/CK.mo,sha256=X1TYW1XeUV7HQyVqDyCeyAnUHsqLZIUJxVa3-iOaFPM,1615 +holidays/locale/en_US/LC_MESSAGES/CL.mo,sha256=gzkPg-EmWT0GN1Zxz4adjiWYFv2EfPn_jbf83tqMue8,2104 +holidays/locale/en_US/LC_MESSAGES/CN.mo,sha256=nAUthya34IOhT5gxTp_DpIsCYcoj8KlhAbrwxlxA3AM,1431 +holidays/locale/en_US/LC_MESSAGES/CO.mo,sha256=ym6sPVjXstGyR2I0AvFY8wEiVlKhkL3hhs1917vg5-I,1393 +holidays/locale/en_US/LC_MESSAGES/CR.mo,sha256=evi--fr7lSViYhFUQQZb9BibhyGbbWCGUjnElNElajo,1327 +holidays/locale/en_US/LC_MESSAGES/CU.mo,sha256=wu2ZaVWX0hRdpvOfyNN6_kJiEi0sIgAAtHhvxeVRrkc,1060 +holidays/locale/en_US/LC_MESSAGES/CV.mo,sha256=57pwxcpkDJTi5lVwrSfgq2AALYh9a9-KeAjSkFe04Ko,3187 +holidays/locale/en_US/LC_MESSAGES/CW.mo,sha256=qSpJk6wFu8a98Xu8Utu5KnVEJORT89HtmP_q9uEjYnE,1257 +holidays/locale/en_US/LC_MESSAGES/CX.mo,sha256=2uFgt9NbMlL_U-XmH5cwOeyjqDok6RCJN3lFPgLoQ2g,1171 +holidays/locale/en_US/LC_MESSAGES/CY.mo,sha256=a4uTQNX-SIqLpMdyLcHVBDU4BqttIi02pOzCqKV-Qsc,1680 +holidays/locale/en_US/LC_MESSAGES/CZ.mo,sha256=y2n4X2D7EYYr_lFXLhPHyZZJGptjaN8ddx4-n2XuTuQ,1583 +holidays/locale/en_US/LC_MESSAGES/DE.mo,sha256=zwmIojwqNLz1ycc9mRK38fCVPMmfUUJ4ZUKppAFpNws,1897 +holidays/locale/en_US/LC_MESSAGES/DJ.mo,sha256=bZGRU8kIBsHr8jmaryO4RvyDOw6T2urGmsAWxUf2YFE,1162 +holidays/locale/en_US/LC_MESSAGES/DK.mo,sha256=E07r4c-0HC9xsAiP9UNbzoDsKHI_wEc4qYzjF76lzdM,1102 +holidays/locale/en_US/LC_MESSAGES/DO.mo,sha256=NWp309F_-jK6ReSpQmQRIg0IWHa59UudhkQhfYc3u78,1045 +holidays/locale/en_US/LC_MESSAGES/DZ.mo,sha256=pHUTdfHyDvlH9IA15GI-7py_aII9uKc9apTSWDzhlJQ,1170 +holidays/locale/en_US/LC_MESSAGES/EC.mo,sha256=DEpYzQBUQKO6vT-nM6PdOl7mEKPm0jWtEpas31hj6wY,1014 +holidays/locale/en_US/LC_MESSAGES/EE.mo,sha256=cUprlfxmaBjd_BuiBEwL_YpkaJ8PTMnyIhX-Vjyn3_M,1009 +holidays/locale/en_US/LC_MESSAGES/EG.mo,sha256=u7uMTH1PBkm6iZsgpKKBhEqrBer9-0YmlOdhymN_2qU,1592 +holidays/locale/en_US/LC_MESSAGES/ES.mo,sha256=3zW9fRW2lBM90e0XLmP47ah0QS_hl4b3ocfvsiYvnUg,3289 +holidays/locale/en_US/LC_MESSAGES/ET.mo,sha256=LJnkhxo6JPPTtQpTFOQbmosAEEsN8zuT8qWHJQGQ61Y,1722 +holidays/locale/en_US/LC_MESSAGES/FI.mo,sha256=3t1Erb95WZqg1RLeUUsU7IqGhiDXMAON6LgdZQnRg1A,2995 +holidays/locale/en_US/LC_MESSAGES/FK.mo,sha256=gAutD-Fo2kDCZTIycYpYfZloFXWyqdXXC68ry9_OczM,1193 +holidays/locale/en_US/LC_MESSAGES/FM.mo,sha256=KD4H2E1VrEn5-T5ti5AYH3ZTuqbA9fuacNERquZpbDE,1783 +holidays/locale/en_US/LC_MESSAGES/FO.mo,sha256=lp9xy5KI36wFE6PqQc9W6l_LeY5tnfroGLN0XMGTZPg,1219 +holidays/locale/en_US/LC_MESSAGES/FR.mo,sha256=Qiwg7XV1Vk0vo1JAgkGCifxkFeUxEUprHp8SPRE_J24,1735 +holidays/locale/en_US/LC_MESSAGES/GB.mo,sha256=GkdNdDyGg83sFjthkyc5SYbeZb16NiRvzSFfzlfefOQ,1851 +holidays/locale/en_US/LC_MESSAGES/GD.mo,sha256=MfZcQg58H9Ogq7zgFeVtGkC5Cn1vY80nn4u666-pP7E,1218 +holidays/locale/en_US/LC_MESSAGES/GE.mo,sha256=kQXD4Zk6t_xJRjNIBGmssaOx0bJfG0CVkMg_cjx9BR4,1877 +holidays/locale/en_US/LC_MESSAGES/GF.mo,sha256=xdygrw6IOKYHkuqmhu5kGw1DtBXCLXHKxnyP834DLAc,432 +holidays/locale/en_US/LC_MESSAGES/GI.mo,sha256=se6IAAxlyZI6f8tYFwwqCoxU4SyHIr9dw5X8wu7ESIQ,1714 +holidays/locale/en_US/LC_MESSAGES/GL.mo,sha256=5kzm0TTD7yzTL37pp_Oxcw6YXuBiTXvmIKXC1ODhypk,1186 +holidays/locale/en_US/LC_MESSAGES/GN.mo,sha256=PY61TXgPs43L0CfGYbXVLchRUNGtjoiuF0juQ12Lsvs,1383 +holidays/locale/en_US/LC_MESSAGES/GP.mo,sha256=ZCuKXaz_M3_UrtD6myfdtwedYDduhDkmojRh1bOsh-Q,432 +holidays/locale/en_US/LC_MESSAGES/GQ.mo,sha256=QmMM1g7ARKmfdNGJupz-rTu5V1Fzj2WuOfV1edTYmyU,1434 +holidays/locale/en_US/LC_MESSAGES/GR.mo,sha256=BbD9Mn6hshbUJe5jnvT-iz6kTkHlXM8XMmHqaXYBE5Y,1426 +holidays/locale/en_US/LC_MESSAGES/GT.mo,sha256=EBUW5Mb2P4uuUiPp7Ypqk_q_ju54UenCTBfJF8d79rs,958 +holidays/locale/en_US/LC_MESSAGES/GU.mo,sha256=_pf18PewdLZtAijxqYG7fNcCdEUaC9Pva624WCQtHzQ,435 +holidays/locale/en_US/LC_MESSAGES/GY.mo,sha256=eW4O9XGc8G504UJ6R-2qZqh2W-yrx1GaTr44--t15I4,1311 +holidays/locale/en_US/LC_MESSAGES/HK.mo,sha256=c3pL3fJ2qbpcQJctRfESZ1wB2A014U0HgbTbn4_iaPQ,3352 +holidays/locale/en_US/LC_MESSAGES/HN.mo,sha256=4Z7SSA0ouubiQEYotriJrcbWHIlf7QEAzg9PjavBfVo,1000 +holidays/locale/en_US/LC_MESSAGES/HR.mo,sha256=I3w4fHYwQ7AnauSdt5LNdLnmVrpzu2_S7thdDrxFjvA,1392 +holidays/locale/en_US/LC_MESSAGES/HT.mo,sha256=G7IpKCJqDPSjLfTcD-1P3fuWtpk7cWgWYyPWbs0sWLA,1897 +holidays/locale/en_US/LC_MESSAGES/HU.mo,sha256=ldsFGH61mpo_RMAXyRytb6OaBkWrzHRgsXxzWGu2nag,1398 +holidays/locale/en_US/LC_MESSAGES/ID.mo,sha256=rthEf8WBjSOrMDGWa4shj934bGlr0JpOht6cKagnW0w,2881 +holidays/locale/en_US/LC_MESSAGES/IL.mo,sha256=vk92fgJoB4A6npAPHnYoncFl0k3_rFVkUHSWBAfsYpk,1399 +holidays/locale/en_US/LC_MESSAGES/IM.mo,sha256=bmK34YIuWzgUx6eUQQK1sG7j4tXp7LjTspS-QMSyRlQ,673 +holidays/locale/en_US/LC_MESSAGES/IN.mo,sha256=7AKBEIYPOv2bv5y82vuIxaufWDur4aYBT90yFHkbFLg,4110 +holidays/locale/en_US/LC_MESSAGES/IR.mo,sha256=zDo4SA0mM1yZPmtsRfd8RyPc5UjF8FmLrFdGB4-UgQA,2564 +holidays/locale/en_US/LC_MESSAGES/IS.mo,sha256=qdGHBpmJTrigEQI16Hpd9sCwCXofOHW4LN6pacoqFXQ,1250 +holidays/locale/en_US/LC_MESSAGES/JO.mo,sha256=hsZYIhQfxBDsvPa28eFcxXTPO2jCfrrQA5bISzx52E8,1176 +holidays/locale/en_US/LC_MESSAGES/JP.mo,sha256=S4yAfGSkjxtbXwocWxlqw1Sv3vDSmTuxZYbX_gpdR0E,1695 +holidays/locale/en_US/LC_MESSAGES/KE.mo,sha256=4PL7kPq9JmlNMrH1C0X9CUWBIVtrEcnwNSXmCDcmcpk,1796 +holidays/locale/en_US/LC_MESSAGES/KH.mo,sha256=0qzKXmsot4PJ683xC9cGO7RPfQx4iVvM_IxJOwt7gc0,4237 +holidays/locale/en_US/LC_MESSAGES/KR.mo,sha256=CfwnXuOA1c6zsPStl4PhXfKv4uXNbZm-xu988n68TaQ,3607 +holidays/locale/en_US/LC_MESSAGES/KW.mo,sha256=09OIjVK5N0HVCz6HOTPepMUpaxptxG8xgiqmOn_8OqI,1112 +holidays/locale/en_US/LC_MESSAGES/KY.mo,sha256=V4cNEMHzyn2akH0wHFSZnj8cdASX2ZZgZZG72vYnxNI,1563 +holidays/locale/en_US/LC_MESSAGES/KZ.mo,sha256=cWuk_8fZPIdG97WBWuR6W5IDBMAhJtMrTmtfT6URLIQ,1834 +holidays/locale/en_US/LC_MESSAGES/LA.mo,sha256=I1QQVOX0aNropRLA4tsRWZVStNenMSlcuFFFmX2n-H4,4096 +holidays/locale/en_US/LC_MESSAGES/LB.mo,sha256=QdPR_QY7dGUhqRPZ7aFkqzCFeeXnj4OX5bnMT61RtJU,2505 +holidays/locale/en_US/LC_MESSAGES/LC.mo,sha256=mQ8986rXSVplhbQc6WwQ3vY_4cS0kmDErvm6LTL1TWs,1056 +holidays/locale/en_US/LC_MESSAGES/LI.mo,sha256=jpFfNBZXox8rrdA3skU-mSbwNVKr6wtoehNdWJDJyCk,1408 +holidays/locale/en_US/LC_MESSAGES/LK.mo,sha256=MRzu9AqCjVMDZDfV2m-fJnlVFcaEyRJMlDA8HFYrEmQ,4183 +holidays/locale/en_US/LC_MESSAGES/LT.mo,sha256=YuGMVLX4y312SZZJAwe6Mzm4-zk8CdhsbbpyNGF-SIo,1501 +holidays/locale/en_US/LC_MESSAGES/LU.mo,sha256=XgwmhVwO65S5Iatc_glm6k4sSe3zk1PRql2pUwlnWck,935 +holidays/locale/en_US/LC_MESSAGES/LV.mo,sha256=f1CFuVi4XHc8j_KfR_lWWHZnh4E1K6A4vT0hSTh8tUE,1704 +holidays/locale/en_US/LC_MESSAGES/LY.mo,sha256=9U2iUSfnAx4-w7ZCFzGaYJ3zi6i-syXQt9ldoG7MGhQ,2067 +holidays/locale/en_US/LC_MESSAGES/MA.mo,sha256=it0WtkavQzKIC3fpCtuWe18rPVKz_k1G86iiKAWe39g,1375 +holidays/locale/en_US/LC_MESSAGES/MC.mo,sha256=nHT_7bRf3QFhoNJWygWPIsxzL1NaAFGo80b5IR3u7cA,1099 +holidays/locale/en_US/LC_MESSAGES/MD.mo,sha256=BHCu0IxMAjz7QtONrKGWx_GW87wxEpS2iEN6dOLRIlc,1444 +holidays/locale/en_US/LC_MESSAGES/ME.mo,sha256=tQQrDH9bqWgBoed7rsvat-iORYVCnKo9in_wT_S-Se4,1221 +holidays/locale/en_US/LC_MESSAGES/MF.mo,sha256=GcLlbORzLvgAB6QmfajPTYiSIR4MzrsYlUSp8ABqBRs,432 +holidays/locale/en_US/LC_MESSAGES/MG.mo,sha256=guhJAcKJRIVDn0KQcVyOymG2l8X_K_5lYJq1aIhbUVY,1230 +holidays/locale/en_US/LC_MESSAGES/MK.mo,sha256=VEaS5PNPwNxLGMO6-Jc62ekYIujqMrMz1r3Kw7nlmN8,2493 +holidays/locale/en_US/LC_MESSAGES/ML.mo,sha256=ZOvxhrI8LDDEx2t738OT0FBexQP2lM-GP2AYNraAXxg,1214 +holidays/locale/en_US/LC_MESSAGES/MN.mo,sha256=pqv50o2NBC1UOPjsd_pS0Br-ZX6LqSzhuVnwmoME5Z0,2691 +holidays/locale/en_US/LC_MESSAGES/MO.mo,sha256=j2HQE-DcAL8YCh4xQ8zDvCskFelcy4IP58dGIeZGUsg,4213 +holidays/locale/en_US/LC_MESSAGES/MP.mo,sha256=_pf18PewdLZtAijxqYG7fNcCdEUaC9Pva624WCQtHzQ,435 +holidays/locale/en_US/LC_MESSAGES/MQ.mo,sha256=dHrmibDCfRamaixzxjl9X25MCpsRV96WBVPHS4SI_w4,432 +holidays/locale/en_US/LC_MESSAGES/MS.mo,sha256=MVuIkF3s92Idym5UfbPY_ahvFGHrizfoiwQB-wJ04YI,1443 +holidays/locale/en_US/LC_MESSAGES/MT.mo,sha256=MiJDOO-0jM5GXP1UJZif1euvjLcpeBQHyf18mb1m2J0,1221 +holidays/locale/en_US/LC_MESSAGES/MU.mo,sha256=j5YP6dlP5Dm0c_DaPbLYwL3o3bxGOgxovQupjxxcZsU,1343 +holidays/locale/en_US/LC_MESSAGES/MX.mo,sha256=XbR6Qi2IBR_1moJbppE-NLG_-Yd2CNDnyzbSIRIMvGg,883 +holidays/locale/en_US/LC_MESSAGES/MY.mo,sha256=_Oi6sn19vuWulnErooBjDfMWOGVjts2T9ET9819iJXk,4353 +holidays/locale/en_US/LC_MESSAGES/MZ.mo,sha256=4E6puSHjsBhr0Oj5y5A5EBhMnyOxLlX2Va3E8Flv_6A,1053 +holidays/locale/en_US/LC_MESSAGES/NA.mo,sha256=MNSrPoZLqCjwfVf7sMQ1Ao3m4eEaT3MuQSRgyexPgVk,1807 +holidays/locale/en_US/LC_MESSAGES/NC.mo,sha256=dKhqZTEhV69NaOyWmQLkdN1e_vL7v0tq-WtwUloGIYE,432 +holidays/locale/en_US/LC_MESSAGES/NE.mo,sha256=UFQiAIXcMDfdb9HP7QbPf6qsy1oMACvx5m5MqxvUOUY,1586 +holidays/locale/en_US/LC_MESSAGES/NF.mo,sha256=XD6r_04rU55r74ZOgI25KHjOitsL8dboKjC6MhE1gpk,1127 +holidays/locale/en_US/LC_MESSAGES/NI.mo,sha256=9oggz_HgCEKw_Zfn7HIsatRz2GNWEYF92urR8tJ8aqo,1056 +holidays/locale/en_US/LC_MESSAGES/NL.mo,sha256=vLrGIOedvWcHQuBkHoyNg4L2WWg2aurp9PARUnr-5P0,980 +holidays/locale/en_US/LC_MESSAGES/NO.mo,sha256=nt22s-yh6jTnbcNo-fNr2gvxu_rqXfOog_Pc-ptOJNk,1025 +holidays/locale/en_US/LC_MESSAGES/NR.mo,sha256=dWq2CO4cN3kriEmXRWr8whutUsi5Eh1sXBMdu1QgqyI,1255 +holidays/locale/en_US/LC_MESSAGES/NU.mo,sha256=IFg3QheTidgtJx_HJTfafNUVxHsyIyeEB-AdAwDSd3c,1170 +holidays/locale/en_US/LC_MESSAGES/OM.mo,sha256=9ZxlrwceA52VDMbbDswmzRrBfp7ocT6ofFFfQ9Y4RwI,947 +holidays/locale/en_US/LC_MESSAGES/PA.mo,sha256=GqLFvgzUJuHZFm4CNPZZTcZcuUyML34LhrptPz9ZyL4,1361 +holidays/locale/en_US/LC_MESSAGES/PE.mo,sha256=nHu0lg4o7CnSzildmjI-24f5KGJ53wKt9u4STPrRlLs,1399 +holidays/locale/en_US/LC_MESSAGES/PF.mo,sha256=GDWfdB42SXViCtDmAzS_Rgh4es2GHj8V7iSmZos9hBQ,432 +holidays/locale/en_US/LC_MESSAGES/PH.mo,sha256=xsdw69UUh2-jL7Eke_NR3Kh3JVR3UbWbae25rE_BPDE,1810 +holidays/locale/en_US/LC_MESSAGES/PK.mo,sha256=vYUUT9IhJatuQrGiZtWwCAC2HmzPAG5-9hGqfXPaCuY,978 +holidays/locale/en_US/LC_MESSAGES/PL.mo,sha256=INio_XpGaI2CDdVvrtgnU6Vnokrh2wTFaaL4uH0ktlI,1949 +holidays/locale/en_US/LC_MESSAGES/PM.mo,sha256=F5xLQ4XkDNd47IdPBAh_38pt7KuuAxCJ6q369LZNEUQ,432 +holidays/locale/en_US/LC_MESSAGES/PR.mo,sha256=_pf18PewdLZtAijxqYG7fNcCdEUaC9Pva624WCQtHzQ,435 +holidays/locale/en_US/LC_MESSAGES/PS.mo,sha256=YuY_x2z0unA61EgY2K9oVD71SY9liepZaw6cRU_C5LI,1742 +holidays/locale/en_US/LC_MESSAGES/PT.mo,sha256=Npd3OeSi51Nl_AbxVX1eKy4ILsomA_5rH5pjDOE-T00,2906 +holidays/locale/en_US/LC_MESSAGES/PY.mo,sha256=Df69jSAaN5sHim4P0JhhP9HdM2AaGOENsHcm2JeDvWI,1296 +holidays/locale/en_US/LC_MESSAGES/QA.mo,sha256=fjwJvrZ_ijthjK-h0PYPyq0YN_qNiC5O9q1OhV-LZxs,919 +holidays/locale/en_US/LC_MESSAGES/RE.mo,sha256=LwsyAs-9oVCmbPW7OxMYPatQO5taavQFWetYUcAvZ9o,432 +holidays/locale/en_US/LC_MESSAGES/RO.mo,sha256=lKCdUWkHG4O2fEzXMlak1VZQYWASt93mRfPHyeMBnVc,1058 +holidays/locale/en_US/LC_MESSAGES/RS.mo,sha256=1FCraKtBFYKNT_ElVhRLgHR0Rkx3cS35zV3KHORv3Xg,1022 +holidays/locale/en_US/LC_MESSAGES/RU.mo,sha256=M1etTeJiQfxrFYLizEJ1MX6FK0Cx9x9oFhsmrDkVwtI,1846 +holidays/locale/en_US/LC_MESSAGES/SA.mo,sha256=QxyIZTwhBVh-Ge3BX9cJPhfGQYNJQdNSy_nm2hcufs4,946 +holidays/locale/en_US/LC_MESSAGES/SC.mo,sha256=yqPgYoQTczv-FFQmEvqMQEyUL4X0H5FnEbwRiESZ4lY,1642 +holidays/locale/en_US/LC_MESSAGES/SE.mo,sha256=1i-vS-pFwPU0B3bGtzb2hzhlM9tUUFnJG1eDg-phDEg,1297 +holidays/locale/en_US/LC_MESSAGES/SG.mo,sha256=Jy9DbI-gH8d9QMfFpEy0CSrUUO2H5sxX3GrUxf8VuFw,1191 +holidays/locale/en_US/LC_MESSAGES/SI.mo,sha256=AOC36ih_K7z4e42CFavZ1FhhUVxhITioo21Zz_NQxaM,1817 +holidays/locale/en_US/LC_MESSAGES/SJ.mo,sha256=tTpllb_O3r7DhR2R5f9w_bg28s5skb0lf0NKMUtoW6c,432 +holidays/locale/en_US/LC_MESSAGES/SK.mo,sha256=A1ZxWxYHtljylQcaNJBx2YbJMwkbNN474pgmGbAyn28,1821 +holidays/locale/en_US/LC_MESSAGES/SL.mo,sha256=uZF0xSK0198fpNHfuPJS16C3H5Bs1Pxn4qa84x_iXTA,1145 +holidays/locale/en_US/LC_MESSAGES/SM.mo,sha256=v9kxCJObMZra9gwb4Bh1U1T10MVryXi7zMZbf3LB_Vk,1647 +holidays/locale/en_US/LC_MESSAGES/SN.mo,sha256=W1-7UbvnEiiy69VKBZzKceS3Q_94bJri-kXCWpOc3qc,1393 +holidays/locale/en_US/LC_MESSAGES/SR.mo,sha256=TuqUiTJ_o-ibeXVoutG6uaXCXPQ_czsQnBXhwYvy2IA,1398 +holidays/locale/en_US/LC_MESSAGES/ST.mo,sha256=IfAavfWzo7uv80Z3w6UHYXMMP7E-BQSMMQWGKU-fY4g,1137 +holidays/locale/en_US/LC_MESSAGES/SV.mo,sha256=rnz4yxqmyq24lIOJS8LEPe3GOcfoIE_nAEADGme5-ww,1033 +holidays/locale/en_US/LC_MESSAGES/SX.mo,sha256=e3OKJzdlZP4F-KAk6XWvYerGcla3PsM2QN1R96__SOE,1157 +holidays/locale/en_US/LC_MESSAGES/TC.mo,sha256=2Q1NfXJV9yhcRiyYilntVFI_TzEWr1gV7MOpky1i2ko,1192 +holidays/locale/en_US/LC_MESSAGES/TF.mo,sha256=SGSpSxIDCIL7uYruzO3Mn-YvtTxBJyBJzf2cLpE6J20,433 +holidays/locale/en_US/LC_MESSAGES/TG.mo,sha256=lFggbBu3Xo61r8MpSeLO-mHIp1o980J9xj_0osO61xE,1239 +holidays/locale/en_US/LC_MESSAGES/TH.mo,sha256=PaN2uThN6IPNqfpM_ctaOWB6qcYIQxOGmjn73KJC3LY,10651 +holidays/locale/en_US/LC_MESSAGES/TK.mo,sha256=Ydmnz3moNtcRFtT97ILp2wGKVQNw2JNGNuk1GaK8dq0,667 +holidays/locale/en_US/LC_MESSAGES/TL.mo,sha256=XsBAtZiBbAyzt2taVxNK4qmYrd4tTiZypG5WqF35hfE,3020 +holidays/locale/en_US/LC_MESSAGES/TN.mo,sha256=8O76Wn55Zjs393R1SfiRb3yMUhzAnk1YM6S7NhODUGM,1335 +holidays/locale/en_US/LC_MESSAGES/TO.mo,sha256=Rryl72Y7q5CGVamnbpx2btzQ90yBoRP6Hz4i7n7ISqQ,1584 +holidays/locale/en_US/LC_MESSAGES/TR.mo,sha256=vkXXBCox_qFYCMxQ4Zfo9S9ApPJ4Pt175EpjYvygUqA,1322 +holidays/locale/en_US/LC_MESSAGES/TT.mo,sha256=xNEET5jq0hd2b8YMFUwwvRFGKl6vjdg24Uc7px1wgB0,1336 +holidays/locale/en_US/LC_MESSAGES/TV.mo,sha256=KfxugDrzWlYCRP3M-gFCKwQQu7fJBNFmQ-goxl2cwoI,1494 +holidays/locale/en_US/LC_MESSAGES/TW.mo,sha256=ujyehru2aARMxODIzMsFME3BJPmnaQRWF8wFdJwqAuQ,2295 +holidays/locale/en_US/LC_MESSAGES/TZ.mo,sha256=O3s1nYgUnh9JbFcN2NPqHkHN4wZPLULaoAY5Z8cXjKc,1796 +holidays/locale/en_US/LC_MESSAGES/UA.mo,sha256=zxtym184p_QppxkAHBvT2rdhAc2MVYTCjtfSedfTkBU,2353 +holidays/locale/en_US/LC_MESSAGES/UM.mo,sha256=sQ0spQ-jfp7BNjbO1k00nJMa1zJ4fVTOSiPjvKzm5wM,435 +holidays/locale/en_US/LC_MESSAGES/US.mo,sha256=yuJY5uVPwn81XjvUljdxHviSsM-YbzcZ3RFwPz5k1nQ,435 +holidays/locale/en_US/LC_MESSAGES/UY.mo,sha256=vtJ1DmAtQcd3Vo7KW7GFWA0hM-YzHUH3fU9Xra4ln8k,1664 +holidays/locale/en_US/LC_MESSAGES/UZ.mo,sha256=Bglgt9liHwqK15LqKOsmGfkrBtYB12m-7iybg-SC8co,1358 +holidays/locale/en_US/LC_MESSAGES/VA.mo,sha256=lbx6krs5kU_HmuKP0LzJ8Z0Zj98RUUyGTn30XepARDs,2264 +holidays/locale/en_US/LC_MESSAGES/VC.mo,sha256=SN5s9zGrlh7KPdGDHAf4e-ehZGI1z2cnirPZyc-EUCQ,1195 +holidays/locale/en_US/LC_MESSAGES/VE.mo,sha256=ZRc3Bam7LRG8uyvkMjar1xydTHCYAECxS0oBjiMp7H8,1324 +holidays/locale/en_US/LC_MESSAGES/VG.mo,sha256=so5_FLOY_o7ysaXiMt7wx955x6iX70xQE-c-wce6KR8,1868 +holidays/locale/en_US/LC_MESSAGES/VI.mo,sha256=sQ0spQ-jfp7BNjbO1k00nJMa1zJ4fVTOSiPjvKzm5wM,435 +holidays/locale/en_US/LC_MESSAGES/VN.mo,sha256=WrhiUY0jiCnD2UaqbmoLhOaRPhO_SFkTdmmUansFYyU,1443 +holidays/locale/en_US/LC_MESSAGES/WF.mo,sha256=7kA_9-Jb-zHKhtrsOlP6HrmHgWHbqIrVpbkQ6gtNdvw,432 +holidays/locale/en_US/LC_MESSAGES/YE.mo,sha256=QbpSYH2ii3AaUNAT-i0pIa84ny9nfdhl56giuEzSAlU,1330 +holidays/locale/en_US/LC_MESSAGES/YT.mo,sha256=oAGjK8prY724rH4e8NC1kZNSBqFHb78P_ZLifnlsQUs,432 +holidays/locale/en_VC/LC_MESSAGES/VC.mo,sha256=CrM8bi_uK5PZ7Dw8saGD96HY3dE_OZUnjsOSLOd0_1I,441 +holidays/locale/en_VG/LC_MESSAGES/VG.mo,sha256=6DzihFTm2ocy2U8MZyX0WUfKmwAUOGX_0qhiN26LoFk,421 +holidays/locale/es/LC_MESSAGES/AR.mo,sha256=Q4Wb2BKePsGsTjYHvnCl3x3OX9pNO8EKJ-ERi5D4RTQ,430 +holidays/locale/es/LC_MESSAGES/BO.mo,sha256=557mjX_06-3DiHGaqX_dEd-gISVy5ovYcLqJLGUMtj0,430 +holidays/locale/es/LC_MESSAGES/CL.mo,sha256=6CfqPXGSDBbpj4h6FH0zLKiE5_Mw59WoqJdyGrLiXco,433 +holidays/locale/es/LC_MESSAGES/CO.mo,sha256=ehMrGTBVkxXDFoTL-eb8AnECX9OAuGhvcChhBLAYvVo,430 +holidays/locale/es/LC_MESSAGES/CR.mo,sha256=rkHI09X8d9lxL1wR5eIBmYiDkf2S_r7ahj4F54kI4jw,431 +holidays/locale/es/LC_MESSAGES/CU.mo,sha256=FWfJ1U3pJD5hr7MtR2-G8-LJcrpiHmN91wWsFq810cE,433 +holidays/locale/es/LC_MESSAGES/CV.mo,sha256=1SEL_SkACEtzDjI7eSfE21RbhD2U-yFxG_Z3lo8ESi8,3400 +holidays/locale/es/LC_MESSAGES/DO.mo,sha256=DzEamFcrrWGxuhGKMT6DDk83ZipzIrvkiG6--Bj3xFU,433 +holidays/locale/es/LC_MESSAGES/EC.mo,sha256=mlvs-b-R1mGthyduAIDzpSWRlJBuIVF6RX3jRoinSfY,433 +holidays/locale/es/LC_MESSAGES/ES.mo,sha256=Q4gTtvbceqkBorXM32ZhKaLvT1rrL9MZ8bVMPNAycro,428 +holidays/locale/es/LC_MESSAGES/GQ.mo,sha256=QkVt9nI5n8Is8b1RkUW6VIUliFivAsZq_3WbhkHwdM8,414 +holidays/locale/es/LC_MESSAGES/GT.mo,sha256=hyoaT-GPyKi1GhlGQwPBOeWqt_NsPVNrXSLIm1HFLqA,437 +holidays/locale/es/LC_MESSAGES/HN.mo,sha256=neOvuZKK1_5k4GWl5FHd8HeXcP7G0MnWq1rRR8-u7-w,433 +holidays/locale/es/LC_MESSAGES/HT.mo,sha256=ZkhHszh2b2ChBrpdIpjN6ubJQqenxqTOm3j-KCK2-OA,1989 +holidays/locale/es/LC_MESSAGES/MX.mo,sha256=DzEamFcrrWGxuhGKMT6DDk83ZipzIrvkiG6--Bj3xFU,433 +holidays/locale/es/LC_MESSAGES/NI.mo,sha256=O_tYcRbUbGNtzQLGJ8o90DDAsMhWE1W8yszI6lauEkc,431 +holidays/locale/es/LC_MESSAGES/PA.mo,sha256=-Q_8gnIzdJHoFO5eDFUn_VvcrBRgnwDoCeL9iO7df8Q,427 +holidays/locale/es/LC_MESSAGES/PE.mo,sha256=WQaC6-xHH1kOTSroV3ktpkrcWQ2e7lzv_Kax84Xu3js,430 +holidays/locale/es/LC_MESSAGES/PY.mo,sha256=I-roDUua7dew7wrwNtAyQMpTF8nWIRxhl5ZrL28oBfs,433 +holidays/locale/es/LC_MESSAGES/SV.mo,sha256=DseSgL2YtiDCGuv5MESAhmV-VFgNNB3s0SqnQwVYPJA,427 +holidays/locale/es/LC_MESSAGES/UY.mo,sha256=Ws7cQuERnlHneFaAOFXCwkRaHSqFJPpkpJgsKxfUvXw,433 +holidays/locale/es/LC_MESSAGES/VE.mo,sha256=h0yWnDju6MUBJcK60OhEXUMWcMkLXL3wzXIruA94_t4,433 +holidays/locale/et/LC_MESSAGES/EE.mo,sha256=GneJe4GHe61pY_6aSR9woCUh3mcX9Fx1Ro8Mp_fWoSw,430 +holidays/locale/fa_AF/LC_MESSAGES/AF.mo,sha256=G0W4qeAFHUIU5PoM9YUw8Y4PceIDS9LMOWiK-or8N4U,430 +holidays/locale/fa_IR/LC_MESSAGES/IR.mo,sha256=_6-fBKH4UJ5UpYrN0U-QvZBsoAzngyyHlVVICsV6qGM,434 +holidays/locale/fi/LC_MESSAGES/AX.mo,sha256=F9x1YjEMOoofYabb8j7orntOxNrLO0yinj4fXdndIik,433 +holidays/locale/fi/LC_MESSAGES/FI.mo,sha256=r3Zk-40b5LseBdax1hkiMCHn03dxGq4ZbQRQJ0jYR8Q,433 +holidays/locale/fi/LC_MESSAGES/GL.mo,sha256=mLq2bjUthlCpEDnLzaOIm_ZlDFN_ASl3TMTImRl2qjA,1222 +holidays/locale/fil/LC_MESSAGES/PH.mo,sha256=ln3G-U914ZsV0vdLWInfb3zCw619difUdIf7IoE0W1I,1960 +holidays/locale/fo/LC_MESSAGES/FO.mo,sha256=lzBc3J7ad-ZZzEdyp8HV7HdR4LZI40Cj6d1iefiFY_A,403 +holidays/locale/fr/LC_MESSAGES/BE.mo,sha256=_gkwmI_1MXudwJI6lVUg2K-Z2eVEkU1bz9_cSWzwPTQ,1129 +holidays/locale/fr/LC_MESSAGES/BL.mo,sha256=SJzno78OVQ-LWvvd1uVU56bekYn5van5_lXcndLPNk4,429 +holidays/locale/fr/LC_MESSAGES/CA.mo,sha256=2hZzjNDDIQ5DxWs4C135h_3_acx2vQSIEhZexHias-Y,2317 +holidays/locale/fr/LC_MESSAGES/CD.mo,sha256=g5yR_bymGPr6uZ68oWN5ty4CY-NKEOjZueuERg1-X40,425 +holidays/locale/fr/LC_MESSAGES/CF.mo,sha256=bAsRhqQPlCsdfKunTpuTwv45i-ELxrQ9V-GVFzvMtko,425 +holidays/locale/fr/LC_MESSAGES/CG.mo,sha256=x4pujjHdGqIh5zhKUWfUbESVyKqciYTe6pSqr1oNB88,429 +holidays/locale/fr/LC_MESSAGES/CH.mo,sha256=x1uysYQ84Aq8o3Qf5T9TCIwhIH3EgHGqXgbutt6f6TQ,1622 +holidays/locale/fr/LC_MESSAGES/CI.mo,sha256=9Cgly1xnpkcKF5tXGm5fN5PUavwQEtG06He9sU56na8,415 +holidays/locale/fr/LC_MESSAGES/CV.mo,sha256=nHV8VaKmQLJlE7xiDo8y10idcCj6Cw59-EHa3-PeqEs,3615 +holidays/locale/fr/LC_MESSAGES/DJ.mo,sha256=-va2hBqCY8QmCBuFLwLP1AOxfUJyJ5jxdy4MNKIlRl4,430 +holidays/locale/fr/LC_MESSAGES/DZ.mo,sha256=74vAJZXIpYxFCKcBoq6YreBmlXXI50ilCJ1XEMzN9XE,1249 +holidays/locale/fr/LC_MESSAGES/FR.mo,sha256=OV8Vn48H1JhXe-RmrEDJo-DoAG8J-4m0Mh4fGQkfULA,430 +holidays/locale/fr/LC_MESSAGES/GF.mo,sha256=rtbfpRitbRI35CtyXe0_Gv0tFJ6hzAk4aQJmc9pZbC8,429 +holidays/locale/fr/LC_MESSAGES/GN.mo,sha256=IvD9_tXx0j9fC2y_eGrZ23puaFGzOOhFJe523E_QDpo,415 +holidays/locale/fr/LC_MESSAGES/GP.mo,sha256=LBMu8QQWLZFCDPdYeziy4W9SvHZ1mHkcs9z0BW0aWuE,429 +holidays/locale/fr/LC_MESSAGES/LU.mo,sha256=uSyiYJ9rIYMlVSyGsYuHTwzXYSxtUNAJIFsaxuFprt4,933 +holidays/locale/fr/LC_MESSAGES/MA.mo,sha256=2Rss1rG2V_IlJkegIyyRtjg_UVbGvZ9aG81bNG9rZSg,1458 +holidays/locale/fr/LC_MESSAGES/MC.mo,sha256=PYo0PwaQ2b6tjel6cnn7SJInfZVOYKdkGbZ31UcXmj8,430 +holidays/locale/fr/LC_MESSAGES/MF.mo,sha256=LC4FnJhzq_kHXhTMkP6uhcvgCZDGi1E5ltQ5liVw-Jc,429 +holidays/locale/fr/LC_MESSAGES/ML.mo,sha256=i81st-37W2r5BelWfAVR_GS-xUTPtxmz2LRzNv5H8wc,415 +holidays/locale/fr/LC_MESSAGES/MQ.mo,sha256=OML8he643iv12ls-JRqTiu2dVaeZbD2cRjafZB6nprg,429 +holidays/locale/fr/LC_MESSAGES/NC.mo,sha256=1aT8IODpA0QHVySV94R3WyJr4c72B7K6rgwhJeSuBJQ,429 +holidays/locale/fr/LC_MESSAGES/PF.mo,sha256=NP8_Q2RIm5sKnhBsqKn5p06FkSQk74vX22yhRgOLJ2A,429 +holidays/locale/fr/LC_MESSAGES/PM.mo,sha256=aCPrxtN0Loheg34NNKyowzowi60zybZuGSseGefKQWw,429 +holidays/locale/fr/LC_MESSAGES/RE.mo,sha256=2pEGEntldzdKUMbigQkfszZimACQHkfLQVkpVVp0UXs,429 +holidays/locale/fr/LC_MESSAGES/TF.mo,sha256=DT5HS-s_bb04Y7mGwXxPHdvycIASB2_2KLaPwX2g0VE,430 +holidays/locale/fr/LC_MESSAGES/TG.mo,sha256=76fQx7L6k4Q1vnx2gp2s4tWAzRrkpq7ZFw6RA5cHG7I,415 +holidays/locale/fr/LC_MESSAGES/WF.mo,sha256=_6vdAZomfC9DOqjo3EH8fkVZ8CTiXuvQMwespoxN-aM,429 +holidays/locale/fr/LC_MESSAGES/YT.mo,sha256=NgkfE6JqGOdoMLUYFP1Raq8SvYDY4p7x6-bfwY9W-D8,429 +holidays/locale/fr_BJ/LC_MESSAGES/BJ.mo,sha256=R4Sgxg_7eChjg8DboyGJ-phKeVNQLOEeEj20U4vVAGw,422 +holidays/locale/fr_HT/LC_MESSAGES/HT.mo,sha256=yupIDXObY8-zL7j7wqgzXFGz76LHVOOCOXF1KcrBAIQ,437 +holidays/locale/fr_NE/LC_MESSAGES/NE.mo,sha256=n6HiZ8iNqznPOVqB9eC9RYOeWNMSJ6e7clwK6Spn8Vo,420 +holidays/locale/fr_SN/LC_MESSAGES/SN.mo,sha256=Ii8v5Y4d3xrPtS59cYkI-TU_tR3-ktI2sU9qKuTlMvY,422 +holidays/locale/fy/LC_MESSAGES/NL.mo,sha256=DNetmRHafdXC693bZHj9wuFDBOgH_TpMlKtjgF98oRw,966 +holidays/locale/he/LC_MESSAGES/IL.mo,sha256=Lcv_LKOC60Di5sbGcRC-VzYJqhjYCP6vg3SJN1hZVag,428 +holidays/locale/hi/LC_MESSAGES/IN.mo,sha256=uOJp03sdgxy0wU7zZvsbR5FHAYUoj0Zm58cyy-dvRv8,5778 +holidays/locale/hr/LC_MESSAGES/HR.mo,sha256=IZKY0I7cG6eILQCHxENpuJ8h09Cwo1FGyfvRB5aQoJ0,428 +holidays/locale/ht/LC_MESSAGES/HT.mo,sha256=vIJNBpbTLFCMJdTkPtOyZ1ntsYpwjfpnV8THbIfOg10,1832 +holidays/locale/hu/LC_MESSAGES/HU.mo,sha256=IrMjkwGu93Q9rYW7zpvUN1LwTdcwf4R-u35rP-fcSIM,430 +holidays/locale/hy/LC_MESSAGES/AM.mo,sha256=IyHwiq8fshCmBWatrIQw8U2ujQfkSbBVr4szRyD-CLY,430 +holidays/locale/id/LC_MESSAGES/ID.mo,sha256=M760m09Eqe5kQElQd3Exf8WeenLDSbBWoWFTaBo3UoM,430 +holidays/locale/is/LC_MESSAGES/FO.mo,sha256=yxBj7ITfGAs0F5c9R5UEY1K28-tNwETGH294dlsPATM,1213 +holidays/locale/is/LC_MESSAGES/GL.mo,sha256=1FHeoJx35aAh_OdSSmbWoGQmG4J4OgJPV5MezZNhtIQ,1206 +holidays/locale/is/LC_MESSAGES/IS.mo,sha256=_mQLGcq7OaaXK_ymscrfC19Kp6vak8wBvRIk1ytC72k,431 +holidays/locale/it/LC_MESSAGES/CH.mo,sha256=lY52erCcDpB4me9Dk03EIl6bPSzxh55H3N5tnLYSGDk,1630 +holidays/locale/it/LC_MESSAGES/SM.mo,sha256=cLeCG3RBuMeXbtNfiBR5ipc8a4JkU7itARQGqoVZEdU,403 +holidays/locale/it/LC_MESSAGES/VA.mo,sha256=HWy3xacsig9e7f2ZjCxDVU4OSdQ7XOMURWcILwNEtoE,429 +holidays/locale/ja/LC_MESSAGES/JP.mo,sha256=w-p9jq4vDrHxNY13v4CfF2fRx1RNlF7YqPXfziC8IdY,430 +holidays/locale/ka/LC_MESSAGES/GE.mo,sha256=mzM8YBdLYkPo0yVbK68rhM-nh0GXO_F6r9ecDrjFDBw,432 +holidays/locale/kk/LC_MESSAGES/KZ.mo,sha256=p6HefOE54FY-IBhKkvBgmWd2XCjR-pgS934Rxr-iG2o,427 +holidays/locale/kl/LC_MESSAGES/GL.mo,sha256=EdoviTRaqtp6a2tlpg4ErHFbZxoqk1hp3yk00pPKONw,427 +holidays/locale/km/LC_MESSAGES/KH.mo,sha256=ohhr4xBIWtbrPha9-y_Kt8wvwNqmbZ3w_99yvvjg_yA,402 +holidays/locale/ko/LC_MESSAGES/KR.mo,sha256=leQRLZmBpFn2bHwLimmtdIE4Q828NafjgbQh0N5IDNg,430 +holidays/locale/lb/LC_MESSAGES/LU.mo,sha256=uetoMxTvtEiu8nbYo1o7LxA_G_YNgCWi3tY_uz79qDY,430 +holidays/locale/lo/LC_MESSAGES/LA.mo,sha256=dKsmPaEvGNiDWAlRCI2ySHPjY0SqTIF6qQh8pyiKfyE,400 +holidays/locale/lt/LC_MESSAGES/LT.mo,sha256=CCKgS6zPT19ouRrQtrs9qtZc7nfWDHXB_wCL0Kr4vEo,430 +holidays/locale/lv/LC_MESSAGES/LV.mo,sha256=7fenXAeWHb4Ke9CIm1IkebTiVlBUV8pVHoYDjZloWH8,430 +holidays/locale/mg/LC_MESSAGES/MG.mo,sha256=nzsqz5VBWTHAz1e_-EZSW3vfCz310qRuGc8X3-ywgCA,433 +holidays/locale/mk/LC_MESSAGES/MK.mo,sha256=cLsVPf4U4lrA3Ey8SXpxPlCF4aRJR4V-ItlqCW4hnMY,427 +holidays/locale/mn/LC_MESSAGES/MN.mo,sha256=G0a-E8iVmQD1Sg7vkmZXLFoldY1qTnGOGAAoj4Ult1A,446 +holidays/locale/ms/LC_MESSAGES/BN.mo,sha256=fbHjLo85gYa_jF0xTsYhIeyb7Rat3viT2jQQqYytxrM,402 +holidays/locale/ms_MY/LC_MESSAGES/MY.mo,sha256=R04vloPvyVojR6YpgcbD3zY9F2kf89VcvCVOqsBELNI,435 +holidays/locale/mt/LC_MESSAGES/MT.mo,sha256=WB9kcNnoMEcHLitg58F3jNwFktboTIPdV4kkngsgfGw,383 +holidays/locale/nl/LC_MESSAGES/AW.mo,sha256=TohmwlaOdS9cdivZGflkCJfvjXouMmyq02hfMuS1zk0,1153 +holidays/locale/nl/LC_MESSAGES/BE.mo,sha256=5wjgBh-PKcqNWjAGPNK944zWw7agroXaeEDqzIXKN6k,430 +holidays/locale/nl/LC_MESSAGES/BQ.mo,sha256=5rSDlwbufEdDULQVcGF25V7UaeorFk8GGThqIS9oYdQ,425 +holidays/locale/nl/LC_MESSAGES/CW.mo,sha256=ORy5cRUpUTZ09JSPUX1vRB_Zv2xutaPQ-7ZNlUT_-Ks,1285 +holidays/locale/nl/LC_MESSAGES/NL.mo,sha256=FwSMsrRTO9vvjG24so4vcgBLl1GMzrNSq0VoW2EyH2g,433 +holidays/locale/nl/LC_MESSAGES/SR.mo,sha256=xpJLB10q8pGxqh9iKVTM5d0_RePGbA-orzyp6XgP5-E,415 +holidays/locale/nl/LC_MESSAGES/SX.mo,sha256=oOvLw6iK5zErKmExFj1eHx0DUMAV82izdh_YVO2HBsg,413 +holidays/locale/no/LC_MESSAGES/FO.mo,sha256=-HNhHXDTcpO44YJVn0e-7kbxcFTc08WlQW1JfjvxUo0,1188 +holidays/locale/no/LC_MESSAGES/GL.mo,sha256=QZd9dKUanRF-lD1EfQ0Q2ksenLmbGB5kBXo4mrluAYI,1192 +holidays/locale/no/LC_MESSAGES/NO.mo,sha256=49zPq-pypIZsJB1S9wgHPW_jZFSPOxnJV8UJ-U4HrdQ,433 +holidays/locale/no/LC_MESSAGES/SJ.mo,sha256=Fzugf8gtFw7hOnulSG31RKkzqDP5ud75L2pmJEoZn5k,429 +holidays/locale/pap_AW/LC_MESSAGES/AW.mo,sha256=zet6M57QbRwwNSbNAwXzQfmfwGQez2lxeP6XQFg6C5o,422 +holidays/locale/pap_BQ/LC_MESSAGES/BQ.mo,sha256=7I-4cQajT52IoAJpt2TmHETDFS272rMbQZSyNem2tF8,1249 +holidays/locale/pap_CW/LC_MESSAGES/CW.mo,sha256=zPvagyIsemjWsFfkRbZUc5n7uQTmTYyPsEudbhn-crk,441 +holidays/locale/pl/LC_MESSAGES/PL.mo,sha256=SDiULczGDlBj-i2PbNVziEA4YDkNkUcigA8GgRnFz5g,428 +holidays/locale/ps_AF/LC_MESSAGES/AF.mo,sha256=iHAfq8CXO1RrjSjzbas9jhLLsYo0_29UIIUxOd-8W8I,1577 +holidays/locale/pt_AO/LC_MESSAGES/AO.mo,sha256=Ti6SErn-BJVf3b9IIdfSnckDZLbnmCPPKu4W2DZEt1U,436 +holidays/locale/pt_BR/LC_MESSAGES/BR.mo,sha256=SEAmkBdKSYyeVmsC13AJTXh4rZ4-NwcIXfKJlZmK4_8,433 +holidays/locale/pt_BR/LC_MESSAGES/BVMF.mo,sha256=2AnW6NKxdZwf65p6zUbkOVZc6QF__0P8kWxbcwEDRWg,433 +holidays/locale/pt_CV/LC_MESSAGES/CV.mo,sha256=KdiHvFmo8zRpFVWPuu8QVVrrvpCqiU9wFyROCJ6WcXs,431 +holidays/locale/pt_MO/LC_MESSAGES/MO.mo,sha256=HkOKarQjPuJVduHGeBTsxXCcQ2BQNmhK70w2y-GtVys,4427 +holidays/locale/pt_MZ/LC_MESSAGES/MZ.mo,sha256=4A9dy00kZfIPExrol-VBlKx7-E8VjUVBhcmqDLWOi-I,436 +holidays/locale/pt_PT/LC_MESSAGES/PT.mo,sha256=tJhFK03Khdbkuejnv577mMx43LXCWoy8THH9tgmECTY,441 +holidays/locale/pt_ST/LC_MESSAGES/ST.mo,sha256=QrLUiGE8Mnr6L4KUCXy9Ezib-p6RD5GxViWkw8gqfk8,422 +holidays/locale/pt_TL/LC_MESSAGES/TL.mo,sha256=SESK-AgIygDjyUxeklqhWiWiZ7NbmkG4-GkDhmOZSGc,436 +holidays/locale/ro/LC_MESSAGES/MD.mo,sha256=WbNGwDkhf-16qUWoOKao1fbZ9XbJZWZH-V1KFQ6H_s0,433 +holidays/locale/ro/LC_MESSAGES/RO.mo,sha256=HemRqDZn281eUiz2eVSN7OWLun4XyCURNNzuWreJTVo,433 +holidays/locale/ru/LC_MESSAGES/BY.mo,sha256=5m3OsRo2hmjj0DABl-CYtSTSGW-bai01iPkhGJ7VP-4,2767 +holidays/locale/ru/LC_MESSAGES/RU.mo,sha256=I8bga_PtzpdHI593sJZSkPoLS-mLe3wZlOai7Fo2ZDI,430 +holidays/locale/si_LK/LC_MESSAGES/LK.mo,sha256=lmHIlnZWgn8_gFDurEMvHhERX4cy_fJD4ESIEaSqFo4,435 +holidays/locale/sk/LC_MESSAGES/CZ.mo,sha256=Hyut-IN5ORknBuyuX92WnEep1MJIrbsz5QCHjq1LjtE,1668 +holidays/locale/sk/LC_MESSAGES/SK.mo,sha256=wtfRnXZaSgE4Yr3UB5D96pgmofnT11EKSC0vpsLYWE4,433 +holidays/locale/sl/LC_MESSAGES/SI.mo,sha256=kypEDpGqFPpJ4mNefm3Tu7BLZa_6l5f31OpZ7bdv9LQ,428 +holidays/locale/sq/LC_MESSAGES/AL.mo,sha256=EH1kt-ja_RXk0wlLYqqRRWQKNor4DfClaLKut-bB0zs,427 +holidays/locale/sr/LC_MESSAGES/BA.mo,sha256=7vJ7Mtn_FidAvaZAkL8X8kec1PW4oquFTfkcsScZbJI,2216 +holidays/locale/sr/LC_MESSAGES/RS.mo,sha256=WdJdzXhYV6xuzYwFfCiDWvKIpiybxRvz0W-YP60pvas,430 +holidays/locale/sv/LC_MESSAGES/FO.mo,sha256=5V2NLv12DNSu3C_Z0rOfj2CVJCedw78DCY6_W6mE3Nw,1179 +holidays/locale/sv/LC_MESSAGES/GL.mo,sha256=3t196kd4N1LUzWuQswkF2uXwuPvLZcb5LGK0PdgDC48,1178 +holidays/locale/sv/LC_MESSAGES/SE.mo,sha256=aZvYXAzjDwLRYLyKYq7o0hLFS1hXnl7r2NuJiAATOc4,433 +holidays/locale/sv_FI/LC_MESSAGES/AX.mo,sha256=4_IjbCy9Iymr0JDCFsXJfYKAOLWmMRmkw5SolLD5Drs,436 +holidays/locale/sv_FI/LC_MESSAGES/FI.mo,sha256=L8ged8pa4_5Tyn-6niWV2TKVl-bJNibuwDGIOx7LLos,2959 +holidays/locale/sw/LC_MESSAGES/KE.mo,sha256=b6_6KHPeXSRbeU2-3XPJwk5xHJB0srGBY0NHjzzxnUE,1897 +holidays/locale/sw/LC_MESSAGES/TZ.mo,sha256=nuO1_C2EdhbHtYaPHrhPGHC7eUqPrQpfWR4Nz0XK1zQ,430 +holidays/locale/ta_LK/LC_MESSAGES/LK.mo,sha256=7Ws9T8e2ZGb_ZwO8KKkapEX4qJtST9BcK-rlc7HkNlc,5686 +holidays/locale/tet/LC_MESSAGES/TL.mo,sha256=m-ruTCJNpFoBV704PLTpVw6RYwcBX60Ge3Ga1ARWtoU,3159 +holidays/locale/th/LC_MESSAGES/AE.mo,sha256=REKr9tqepAfdYft9JR2O0j0cbTgwiVtDB-hlU4WqXdY,1929 +holidays/locale/th/LC_MESSAGES/AS.mo,sha256=lilycJeJVx2B4a31ob49OyK1WJdp4OkLNcEUzzzIQSg,432 +holidays/locale/th/LC_MESSAGES/AU.mo,sha256=EpY5PgRD6vfsY8QehOawMEmcSrcTI52zENewNbrh01w,3860 +holidays/locale/th/LC_MESSAGES/AX.mo,sha256=Dt-PpzGUw31DlHFKp331qnKAkLIdwRlqvGuY97ojL08,433 +holidays/locale/th/LC_MESSAGES/BL.mo,sha256=JffAb1ZO_gpAic3uZgfCppJISCkQnr_Ybyp5hluFsKw,429 +holidays/locale/th/LC_MESSAGES/BN.mo,sha256=O-Etzj0R8eTOcC7les00CUySTPdL07BqY7WEaT93yEM,2664 +holidays/locale/th/LC_MESSAGES/BY.mo,sha256=rCuRuT4jMjYfh2fqeUiw74NmIzJeLUkHCHJaiPxtJwo,3325 +holidays/locale/th/LC_MESSAGES/CA.mo,sha256=hukhQW0bGNy9grkOAptKOFmb5W9KHAf-WlMLiZQCwBw,3566 +holidays/locale/th/LC_MESSAGES/CN.mo,sha256=qtUCCj1WTsL8kuAkUB_4xfeB-YJpMIfHkmTg7qaRjKE,1861 +holidays/locale/th/LC_MESSAGES/DE.mo,sha256=6TBktZ2JMuOSi2A1lCuoHQTZr_2aVObe1JmkSASyHBw,3200 +holidays/locale/th/LC_MESSAGES/FI.mo,sha256=fxXg2F20kr7efjoHLzONoIuv8N9OB5TvR5HegmMMNZg,4815 +holidays/locale/th/LC_MESSAGES/FR.mo,sha256=l4wGNaau9qw8OezFQa0KqQ1ME7u0EgPwgTQJDMBHCB4,2917 +holidays/locale/th/LC_MESSAGES/GB.mo,sha256=jmZ7cIM3RRknhj9hI8KrhyNfzTNSbwsjLMrkxAVzDRw,3636 +holidays/locale/th/LC_MESSAGES/GF.mo,sha256=2UNzGwpgMCya8IApDsImqGUPSlVqG6etTDpu1rYfap0,429 +holidays/locale/th/LC_MESSAGES/GP.mo,sha256=COwS1bkrjplBOjh4c8hazlrZQfdEE_JpVUxzgU4J5vA,429 +holidays/locale/th/LC_MESSAGES/GU.mo,sha256=XKgqBgbjDZ5UlEGZLUpiEButf5x2cmbVHbCkSlFI2tk,432 +holidays/locale/th/LC_MESSAGES/HK.mo,sha256=vktB89H5J2X4UXP3uO72k62LYHeDokwlWld0r-geSWo,5008 +holidays/locale/th/LC_MESSAGES/ID.mo,sha256=UyITHVkUwSvb1oP6o1dfhgrp9PYLxzFFplcc0WQtdMY,4818 +holidays/locale/th/LC_MESSAGES/IL.mo,sha256=HG5904Bx6HbFYmMk3Uuw2L9P_xEupzRzn6phQ124Eqc,2105 +holidays/locale/th/LC_MESSAGES/IM.mo,sha256=Jjx4Oe5ZQx12JcbxdMrQgtLVXF4qmnCVviFTzdkjch4,933 +holidays/locale/th/LC_MESSAGES/JP.mo,sha256=r2qrVowmeFgatVB-8ahXQOw6UOfhaii09U0XMOMAh-0,2794 +holidays/locale/th/LC_MESSAGES/KH.mo,sha256=DlnxVFts2oNIIDouVxTyW1jlMWKFm4YFWjW1MNaMQ_c,5977 +holidays/locale/th/LC_MESSAGES/KR.mo,sha256=P6mvsJpNFRCiUTelF9IXd_h1YeQUpFGyFnGutCCoJzM,5624 +holidays/locale/th/LC_MESSAGES/LA.mo,sha256=wD_AUMsxAYIefMR0uK1m7ZjgraqAmuMUBnSKcMPglFc,5322 +holidays/locale/th/LC_MESSAGES/MF.mo,sha256=6J1mIA4dydr1XVasmZJyn4Pqic-LySRBoIPQs-QsOJI,429 +holidays/locale/th/LC_MESSAGES/MO.mo,sha256=gQrIG5EnsmK__ISzrpnw6KKwPl2204U5sIhfeg9LeYc,6317 +holidays/locale/th/LC_MESSAGES/MP.mo,sha256=XKgqBgbjDZ5UlEGZLUpiEButf5x2cmbVHbCkSlFI2tk,432 +holidays/locale/th/LC_MESSAGES/MQ.mo,sha256=Xt7qaBbhQ0yW05pnzOj5tGn3I_D3NvsHEc552F8IbP0,429 +holidays/locale/th/LC_MESSAGES/MY.mo,sha256=LZEWgoXrIy6G9fi5oV3UcRMym07JU7PJIEhyq7W04Xw,7474 +holidays/locale/th/LC_MESSAGES/NC.mo,sha256=5Mg3i8dG76iDpPAeps7NxRn6-4Gz3W7Mpo9klTWV59M,429 +holidays/locale/th/LC_MESSAGES/NO.mo,sha256=iKO0WjOy39fv-WBDJJnAyP7ZgrfE4et20fTgY098Lp8,1563 +holidays/locale/th/LC_MESSAGES/PF.mo,sha256=kelKmzG_R2MAqyoh-1g4SdLgb65i30r0kz1t78z91ac,429 +holidays/locale/th/LC_MESSAGES/PH.mo,sha256=RjZu7ulUnL3FgJ1AZnTCA2uNeNBcmR1C0yjUlLGzHO0,2788 +holidays/locale/th/LC_MESSAGES/PM.mo,sha256=FWHtbGRLzB-rWhOPbH2vCt75foKn0a-WynMw6-YXzyQ,429 +holidays/locale/th/LC_MESSAGES/PR.mo,sha256=XKgqBgbjDZ5UlEGZLUpiEButf5x2cmbVHbCkSlFI2tk,432 +holidays/locale/th/LC_MESSAGES/RE.mo,sha256=8CndEHUEhQgqwdEiLUw0t7K8egzcKDpibpMzdLEe81I,429 +holidays/locale/th/LC_MESSAGES/RU.mo,sha256=6a7_HgbrFv-y0Mv718kz1fP2fkbTR6p-Tlm2AtMMTBA,2413 +holidays/locale/th/LC_MESSAGES/SE.mo,sha256=JRwQcA2Kr6ozRSUatpHvRcUrCPG8dCftVoQZ9OZ171Q,2082 +holidays/locale/th/LC_MESSAGES/SG.mo,sha256=u1cxM3cpsea4hUDW8mUtXGSDcwLpUI0w63FBdb8sqLY,1743 +holidays/locale/th/LC_MESSAGES/SJ.mo,sha256=7a4h0WmTfjW-qOftT7JyXrlv-vKixD6KziZQOUbzcQQ,429 +holidays/locale/th/LC_MESSAGES/TF.mo,sha256=FWHtbGRLzB-rWhOPbH2vCt75foKn0a-WynMw6-YXzyQ,429 +holidays/locale/th/LC_MESSAGES/TH.mo,sha256=LSevibLyyIFdiUpreWskGbbkFIvDjuxG3W_qyqe61D8,402 +holidays/locale/th/LC_MESSAGES/TL.mo,sha256=Uk04yfXZLIm9u-a7VbrIuHOsGbbnEcR2AdAfqsMjG6s,4531 +holidays/locale/th/LC_MESSAGES/TW.mo,sha256=PVGxGfS5ilx2UKQ6oBTgFD0az_zkHt_UzZqwlQzS1do,3529 +holidays/locale/th/LC_MESSAGES/UA.mo,sha256=8ad7nWyuclPOSYbxofwXoiGxvhG9z0aiiejAgYMCQ_A,3193 +holidays/locale/th/LC_MESSAGES/UM.mo,sha256=KaXXeYLwufedA9USvv4ukJHigapWxZz6SDqXPC3g79A,432 +holidays/locale/th/LC_MESSAGES/US.mo,sha256=BS6O9xnvTGRkL7yVck5EXHs7MYbV2DbT4wykNVrXbZI,10754 +holidays/locale/th/LC_MESSAGES/VA.mo,sha256=4tqksHuZO70KuputOiM7gtQ6Cwe4GKcgLVWzc3jdZgk,3787 +holidays/locale/th/LC_MESSAGES/VI.mo,sha256=KaXXeYLwufedA9USvv4ukJHigapWxZz6SDqXPC3g79A,432 +holidays/locale/th/LC_MESSAGES/VN.mo,sha256=PCd40u5PKh2eukzPJKa1pSo0rUbYh3JWEdAWYYZmCT0,1928 +holidays/locale/th/LC_MESSAGES/WF.mo,sha256=Bf74JR2MM7e9loCW3wVCOXMsW_W6d6oRkHqrLYerb-c,429 +holidays/locale/th/LC_MESSAGES/YT.mo,sha256=WOpw6nt8ewidRLlxkEiLVmoRHEbEkOagJ6ynNYZsTn4,429 +holidays/locale/tkl/LC_MESSAGES/TK.mo,sha256=MzBqjiR__wH63ntBsl82j-kdPghjBm0mlCD9c_4jbqU,691 +holidays/locale/to/LC_MESSAGES/TO.mo,sha256=6wKBpo50DPF8HdbKTH1Qox5LKqRiMJJPEn7z6X3kHYA,430 +holidays/locale/tr/LC_MESSAGES/TR.mo,sha256=K60WU1Ami9_LDW9AfHu8SvBUagkpZfB1gZEFg6LQ13s,400 +holidays/locale/tvl/LC_MESSAGES/TV.mo,sha256=236QRQe8nZCxL7CCHLNe8cuP0zBnOS9ffBjYQ0y2LD0,427 +holidays/locale/uk/LC_MESSAGES/AD.mo,sha256=iKY-PIOTfVDp479asZnwhyoiquvpLyzyXEhGVvIZH3g,2558 +holidays/locale/uk/LC_MESSAGES/AL.mo,sha256=hrfNgqggpblyPrTCznAIm3ywAuB1cUU3XVdhBjyUFd4,1906 +holidays/locale/uk/LC_MESSAGES/AO.mo,sha256=ju4nOEqNcuRQTHg6rCNxK93tgwuszda4Rw6PUZomd5A,2469 +holidays/locale/uk/LC_MESSAGES/AR.mo,sha256=wVchsfeUJxcbAFIjre_RuaNvCwylSCvgMK02axfuof8,9931 +holidays/locale/uk/LC_MESSAGES/AT.mo,sha256=A3cQVDb_JpBQ2eQZ4aw60_IVDk4oYsBHUI1V51hoyHI,1937 +holidays/locale/uk/LC_MESSAGES/AW.mo,sha256=NRaPM6wQdsqt0bDZy0P0BVqJgDQ8KJmVJhcibwPXz9A,1404 +holidays/locale/uk/LC_MESSAGES/AX.mo,sha256=-dojDgMZ7JHKatxy2DG-YZwR7z2tC_Yvblz0iUoNYMc,433 +holidays/locale/uk/LC_MESSAGES/AZ.mo,sha256=HSGv5w2Py8yz-RfkeVM5vw6J8PI78C5WMnwRcHN4SfI,2593 +holidays/locale/uk/LC_MESSAGES/BA.mo,sha256=Oxmp3n0MmV5ym8xFsFKB38cGhi4-EgtIPFvrUsKqm0o,2320 +holidays/locale/uk/LC_MESSAGES/BE.mo,sha256=EYqdY1DrKW6xGxl9j48yfMHxDxzvn5SEDOa9q2DBd6U,1412 +holidays/locale/uk/LC_MESSAGES/BG.mo,sha256=rXepj4hkIxrd-7itpEIHH76K5NmJ3yOEdA7ENqKII94,2251 +holidays/locale/uk/LC_MESSAGES/BL.mo,sha256=gidCoNEc14-uzRUFonnQnjFxFgDdACS5SBrohPD8p0g,429 +holidays/locale/uk/LC_MESSAGES/BO.mo,sha256=J9ZWuxYZiE05u92ONC_g55MAP9ycYsKvy7q5uI-HgA8,2208 +holidays/locale/uk/LC_MESSAGES/BR.mo,sha256=-tM6hiQVU7Fm2o2LDHyT95iUIQphTiHN3ofUm1kcFZg,5766 +holidays/locale/uk/LC_MESSAGES/BVMF.mo,sha256=2cDBRodRGhDuWMwOZLj3yp4nOLANo0u9Ko1wIaaxHwQ,1448 +holidays/locale/uk/LC_MESSAGES/CH.mo,sha256=5lkaSiG4w5YXxcNZ41TlkRzpBjIjFsEwMJVlfQIkGTM,2163 +holidays/locale/uk/LC_MESSAGES/CL.mo,sha256=Tmo4MdWIoNLAD0HZ7j36sAxj93ohElb9JwDTGEEusM4,2726 +holidays/locale/uk/LC_MESSAGES/CO.mo,sha256=q-Bp1t4EPg7-mG-UxWSmKwuD5_6M_ZU4Z5vySchCt3A,1793 +holidays/locale/uk/LC_MESSAGES/CR.mo,sha256=75Lx_IQBlb2PULyhUFOZsdrnxAR5xpBbMIjSS1yqWQU,1543 +holidays/locale/uk/LC_MESSAGES/CU.mo,sha256=-fpnKIz9l4YUFOaKFAAnfwW-cPj28viazMK5jwWNuIM,1257 +holidays/locale/uk/LC_MESSAGES/CW.mo,sha256=ZgHMBp0VprMZPzCjgfqIN3kR3GaHT51368zhg4iyLFg,1512 +holidays/locale/uk/LC_MESSAGES/CY.mo,sha256=5swmh6gWd3wtvw6fFjdOU00dE4lerOzdpMetwSwNWEs,1978 +holidays/locale/uk/LC_MESSAGES/CZ.mo,sha256=qOe0I6bwf1XH6ROHqlZ1IabXNW0p4XHddBXo6KzbPeU,2000 +holidays/locale/uk/LC_MESSAGES/DE.mo,sha256=tThHV28f3ruEEORsBlc8xo6_YhWZAtsv9g5mI_jkQGs,2440 +holidays/locale/uk/LC_MESSAGES/DK.mo,sha256=TrwmOo1Yjnf7zD2WnjR_m9FhTBCvcYo-1uqvWn6AFiQ,1328 +holidays/locale/uk/LC_MESSAGES/DO.mo,sha256=-kBxL-s2QIsArZ0wMWqJt6WPlxSq1WpbbHVxvweofRo,1251 +holidays/locale/uk/LC_MESSAGES/EC.mo,sha256=Do7GY72iJ1wWxEmZeJswaS4roPD2gr-D3EQ9nvDl0vM,1173 +holidays/locale/uk/LC_MESSAGES/EE.mo,sha256=IBY9tMz2lNHgR0SgVbSi7KKK4P9YChxrzVXEXWFhFOc,1177 +holidays/locale/uk/LC_MESSAGES/ES.mo,sha256=dbMxaMhsn64U08qmowxXnMQr6jU-0DwKi9pV7RDpAlw,4258 +holidays/locale/uk/LC_MESSAGES/FI.mo,sha256=YV4vgyj_-I8YMs6ucklwGWvEzuRihpPhw2OXRj6I_SI,3854 +holidays/locale/uk/LC_MESSAGES/FR.mo,sha256=IFbmW8mnqxdtAdQepesJNGcALW9h510sh-G8x0KG03Y,2204 +holidays/locale/uk/LC_MESSAGES/GE.mo,sha256=203m_36BkjkLk3_RP4mfRectYVHQQpGzFyUnJp-xKqk,2213 +holidays/locale/uk/LC_MESSAGES/GF.mo,sha256=knY-FTfZm0cx_w-wzV8EtEVOuBVltcWuj6hFC-e4SZY,429 +holidays/locale/uk/LC_MESSAGES/GL.mo,sha256=t_zeDMqR0snxtXnqImn9C4srv13cV1kDk3IpqrKTCKQ,1418 +holidays/locale/uk/LC_MESSAGES/GP.mo,sha256=DOfNa3czSHGG7YH61zjEIBE3B1Z-86L-5Q4TV2CVf4w,429 +holidays/locale/uk/LC_MESSAGES/GR.mo,sha256=8HZmG6YILQBP7gzwXz31dwi9yjDOB_XdsqJgcMIjkeQ,1670 +holidays/locale/uk/LC_MESSAGES/HN.mo,sha256=UPqumpyYUfMsqKwJIa0YKHlvBFnAmh_SbBq2uWDBk5w,1160 +holidays/locale/uk/LC_MESSAGES/HR.mo,sha256=su8wdlHDUeUMclLmkq1f0-ySkYafQYRZ_sNs_-wuxZM,1826 +holidays/locale/uk/LC_MESSAGES/HU.mo,sha256=s3DLAVOl7qjS2-mrHgicfLmRqlX0cXG5ii4VtLBFnwg,1717 +holidays/locale/uk/LC_MESSAGES/ID.mo,sha256=7o_emFk_jzpQdQE4a7tNy08rehcY7jFqftIz1p3P9xE,4168 +holidays/locale/uk/LC_MESSAGES/IL.mo,sha256=bivkwtdweuyOYf5bgBqOerb6OYOLQuH_kgE8a5EBWdQ,1558 +holidays/locale/uk/LC_MESSAGES/IS.mo,sha256=TvDnL4XXR_VgHJxENaLZf8DTYMzWIc_yDPehnb2jYN4,1477 +holidays/locale/uk/LC_MESSAGES/KZ.mo,sha256=deeKqGKAToC4Bz2Vn2FvwCuD0MicW9uTH-Irkv_EtR8,2187 +holidays/locale/uk/LC_MESSAGES/LI.mo,sha256=kKV6lNlSmheHK3LQr5fFaajgQmWzplWOxrEUVImSeAA,1805 +holidays/locale/uk/LC_MESSAGES/LT.mo,sha256=N-pPV997Fz_uXLmW8sOWwvoBfwS0vwutGUpCd8q-R5I,1860 +holidays/locale/uk/LC_MESSAGES/LU.mo,sha256=Aeq7QRWvLzsVwzKee4OdgvrGJ0Dy3f6HN0HfNqswVjw,1145 +holidays/locale/uk/LC_MESSAGES/LV.mo,sha256=DeNVbMKO-SixrK-mTgDvrMEm0s-FUmajuXTEaiXgpq4,2117 +holidays/locale/uk/LC_MESSAGES/MC.mo,sha256=Y43SbLMwbEpiXHG5mv5upDS9EjD4475buAVuhfCRmVQ,1372 +holidays/locale/uk/LC_MESSAGES/MD.mo,sha256=bVIdxF1Z_qyecZljQmViDvU40pvLHvmIdd30N3HoG4U,1723 +holidays/locale/uk/LC_MESSAGES/ME.mo,sha256=3Y5hSnFzJd8TLoHs6Q2kTEX-kGnMU8aZgGVL1SM4ykA,1473 +holidays/locale/uk/LC_MESSAGES/MF.mo,sha256=2JCgndaPAU4nPGKAN86iRcKn0QDvUWBlh9q1DusSot4,429 +holidays/locale/uk/LC_MESSAGES/MG.mo,sha256=MPpr_Bmj7CssGbHLoai7Vx-1ThTAGSuWoC1eBbH5F90,1474 +holidays/locale/uk/LC_MESSAGES/MK.mo,sha256=v6ofxraWavT2qRirwhvZJ3nRExxDoS71KJC300lDthI,3086 +holidays/locale/uk/LC_MESSAGES/MQ.mo,sha256=le9TDsTIbzVZVr9Jaa4ADTk1MsrS-7Yz3tbJyN4h3Lc,429 +holidays/locale/uk/LC_MESSAGES/MX.mo,sha256=w-jZBY_ak_6aKTp6a4sQYbrZC-8-ggR0xDU1kwZmla8,1016 +holidays/locale/uk/LC_MESSAGES/MZ.mo,sha256=Wlfe6gzi4DQLIJimD7vyk1wNG7SXdRtXkMczzkMcYM0,1306 +holidays/locale/uk/LC_MESSAGES/NA.mo,sha256=p1AoUZJlFv9KAIRzJKjKktrGZFEqKrjUT41DA2IiBQA,2235 +holidays/locale/uk/LC_MESSAGES/NC.mo,sha256=oDOus5AQN6Wk7FqQS0VyOhm1SqI0kpWg9nipJpgDBww,429 +holidays/locale/uk/LC_MESSAGES/NI.mo,sha256=-z57zfOBHrgZEj8yGcaY-1eEC2ylURPydCFT-ifbctE,1253 +holidays/locale/uk/LC_MESSAGES/NL.mo,sha256=CtaF41rcO-9jwOPBoFm1c__rwC3eDp41pAIXmua06Qo,1144 +holidays/locale/uk/LC_MESSAGES/NO.mo,sha256=qVt9pMmjvUc7kNDBWG7CtIEcP8_vtKla55Jsp5-GNvw,1192 +holidays/locale/uk/LC_MESSAGES/PA.mo,sha256=aYlr7eclpzye-310aWrg3GT-YK2RBZQiOaVcbAGXm4E,1739 +holidays/locale/uk/LC_MESSAGES/PE.mo,sha256=_FxAOuRptEQefBSv48J0amUC_8E9gpnhZQZTfkPnZWI,1730 +holidays/locale/uk/LC_MESSAGES/PF.mo,sha256=9QAG5LINjypTY18NJYLZ6I-zjXbzG0EVgVGdmzCC8FY,429 +holidays/locale/uk/LC_MESSAGES/PL.mo,sha256=vKMdR5pP9DdGomlSuworg5aeHETNviyDqRoln7wrPis,2399 +holidays/locale/uk/LC_MESSAGES/PM.mo,sha256=rXFGegMXCHOosqeIp1kAdaHjZROTJVWSm3UZdfRsdIw,429 +holidays/locale/uk/LC_MESSAGES/PT.mo,sha256=TvIYR9ykmMJ6PdbbrscymHtmOrEMk0bj46tiPrgbsHM,3690 +holidays/locale/uk/LC_MESSAGES/PY.mo,sha256=eUQSk6_AerNPP9FNoYsKt0Lv-9R8uBw9f_lH1xw5EzY,1588 +holidays/locale/uk/LC_MESSAGES/RE.mo,sha256=NHeo3BT0A8Chlgz2SfoMN8iX22eVmiZJX6VB5GeAWOg,429 +holidays/locale/uk/LC_MESSAGES/RO.mo,sha256=8rtxnqnu-karor_7vVX41vbHOeuaK_jG-oTKmLAbrv4,1279 +holidays/locale/uk/LC_MESSAGES/SE.mo,sha256=5IJbxFJL7qIrH0ZhwCO3mMSfcCbOl6QRYbF8LRQhgt4,1615 +holidays/locale/uk/LC_MESSAGES/SI.mo,sha256=NaX68n2Xnx0dobDEnQK_zJSFeFlwxMarf2LUxrn9YzI,2305 +holidays/locale/uk/LC_MESSAGES/SJ.mo,sha256=TLd7Cix1BBsvtk6IlM44GjhO48VWVPZhjDpV1l7Rw74,429 +holidays/locale/uk/LC_MESSAGES/SK.mo,sha256=X03JMa65Bn8ozFK-uuZjy0zPGuwrw_UD8OYD-2J57d4,2252 +holidays/locale/uk/LC_MESSAGES/SM.mo,sha256=bBFzb73vtInjjH6dqIRQi9-YeuHjEh6aO9Mh0j43KdM,2040 +holidays/locale/uk/LC_MESSAGES/SV.mo,sha256=Nsm8xdGeX_Ao2UfBTEQX-Hwi8FhTsvuOZO4nRYdCYDc,1205 +holidays/locale/uk/LC_MESSAGES/TF.mo,sha256=1tfKVnb_0-r63OqU0hCgxO6WpQmIhItR2MqL7Gp9OZE,428 +holidays/locale/uk/LC_MESSAGES/TH.mo,sha256=_IexOmRKUl2gRTVAucOYbU8q4RKV_T1KQMcOYIcgr_k,13418 +holidays/locale/uk/LC_MESSAGES/TR.mo,sha256=IpBacAnpzkwbRHSS9IygrGla8FZ5-EGYZgr1Wl83XkM,1645 +holidays/locale/uk/LC_MESSAGES/UA.mo,sha256=cM3bpK1pDc5fvb2opGwvVGopnfnXsm8sqfm2BWh0WV0,430 +holidays/locale/uk/LC_MESSAGES/UY.mo,sha256=aZ6sgtBEjqSDyqVm1P-vsBaLLcuxeaJfzcQXAGDLtos,2070 +holidays/locale/uk/LC_MESSAGES/UZ.mo,sha256=EXkobWjYgSheT84eIR8v5PlE-Q2JqmpeGyYyWBv6UBU,1654 +holidays/locale/uk/LC_MESSAGES/VE.mo,sha256=WiudRYlKH4R131yZ2hCcZjs4_tUvREvWnXjEDQod4jg,1621 +holidays/locale/uk/LC_MESSAGES/WF.mo,sha256=hCkjcYkhnJVFTiTAof7D0biQG6Z20Xkxh0CjAmbiWMo,429 +holidays/locale/uk/LC_MESSAGES/YT.mo,sha256=NoKACGEAlc_z42Hffj2G-6RzupmpgiyWhyrhyfjmcoQ,429 +holidays/locale/ur_PK/LC_MESSAGES/PK.mo,sha256=FPi-WEPKK3mZS7xPLMTwLbYHtVqrsnGUq5OMRIrnhWA,1057 +holidays/locale/uz/LC_MESSAGES/UZ.mo,sha256=vnu7utSRLe-RPwZlWIb1_Hk-l7sI0wNxI0arb5HN3Ac,428 +holidays/locale/vi/LC_MESSAGES/VN.mo,sha256=tqiI9HTxUz-SmYm17Ry35A0iyNe_vIJmTx51tDeF6uY,427 +holidays/locale/zh_CN/LC_MESSAGES/CN.mo,sha256=HUAHpUrjyj23ga2_2OIBcb-wKq7s2shR4LXZaymmP04,438 +holidays/locale/zh_CN/LC_MESSAGES/HK.mo,sha256=IjegtHeJElrqcutE9dfuOyzHw6qGsDS4FsZkjwwHe5w,2870 +holidays/locale/zh_CN/LC_MESSAGES/MO.mo,sha256=F0A20EmBvM162sxtVrO80EvEKBrsq33RajwPX7R7dDg,3543 +holidays/locale/zh_CN/LC_MESSAGES/TW.mo,sha256=Jga9Mfu3gadf58m3WMrsP7zA96da2ooMvvkqT5ARprw,2064 +holidays/locale/zh_HK/LC_MESSAGES/HK.mo,sha256=ET_ZICl1UGrqU5tgi_efO4H9DlZgam97_HCzMVqXMI0,435 +holidays/locale/zh_MO/LC_MESSAGES/MO.mo,sha256=zmmxUFDWqznW21Epl0-3TIVEbLWbi8aHW9zOE_VQE1w,435 +holidays/locale/zh_TW/LC_MESSAGES/CN.mo,sha256=dWq51at-GWXcmuakljTqNKuLAvD5LoIyVXpQ7YVICTo,1282 +holidays/locale/zh_TW/LC_MESSAGES/TW.mo,sha256=mI1ZaElVi0rMMWn5xP4RmP_omKa66HCJIIvmTv_P-co,434 +holidays/mixins/__init__.py,sha256=UjGVnrlUCugVdLqaGkqarBsDFrejuOip8p_TFHBWQ48,737 +holidays/mixins/__pycache__/__init__.cpython-312.pyc,, +holidays/mixins/__pycache__/child_entity.cpython-312.pyc,, +holidays/mixins/__pycache__/preferred_discretionary_holidays.cpython-312.pyc,, +holidays/mixins/child_entity.py,sha256=z3o1IzR2svriGdoCQDTVQx8oA02JYPa9yQMiVt_tswA,1602 +holidays/mixins/preferred_discretionary_holidays.py,sha256=ygaJRga0RSOgbHZMt1Hpw4-DbZOdFtYHTv5Pifka4MI,1113 +holidays/observed_holiday_base.py,sha256=oS1o498KfZPrQGD_0nzqZ_9mbeeP-H38CLmyYKR9Pk8,9321 +holidays/py.typed,sha256=EUaxvGLCfdycmOVEDt64l9fUKWuyPBxOEQWGfnMnrxE,171 +holidays/registry.py,sha256=kU05oPGyvIBVeQ9bUYcERHj4Y1Av-LZNpSt73Ib8ydk,15429 +holidays/utils.py,sha256=WgIHCWnPPE1pizbJHkWt054tObT3uN45_DBf3HAauCM,15587 +holidays/version.py,sha256=Y5BhnWZRYbpO3EYVxuF8T3GrGx8fPs17YhAb_9hNZW0,553 diff --git a/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/WHEEL new file mode 100644 index 00000000..e7fa31b6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (80.9.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/licenses/CONTRIBUTORS b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/licenses/CONTRIBUTORS new file mode 100644 index 00000000..e7037eb1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/licenses/CONTRIBUTORS @@ -0,0 +1,162 @@ +Aaron Picht +Aart Goossens +Abdelkhalek Boukli Hacene +Abheelash Mishra +Akos Furton +Alejandro Antunes +Aleksei Zhuchkov +Alexander Schulze +Alexandre Carvalho +Alexei Mikhailov +Anders Wenhaug +Andrei Klimenko +Andres Marrugo +Ankush Kapoor +Anon Kangpanich +Anthony Rose +Anton Daitche +Arjun Anandkumar +Arkadii Yakovets +Artem Tserekh +Ary Hauffe Neto +Bailey Thompson +Ben Collerson +Ben Letham +Benjamin Lucas Wacha +Bernhard M. Wiedemann +Carlos Rocha +Chanran Kim +Chris McKeague +Chris Turra +Christian Alexander +Colin Watson +Dan Gentry +Daniel Musketa +Daniël Niemeijer +David Hotham +Devaraj K +Diego Rosaperez +Diogo Rosa +Dorian Monnier +Douglas Franklin +Eden Juscelino +Edison Robles +Edward Betts +Eldar Mustafayev +Emmanuel Arias +Eugenio Panadero Maciá +Fabian Affolter +Felix Lee +Filip Bednárik +Firas Kafri +Gabriel L Martinez +Gabriel Trabanco +Giedrius Mauza +Gordon Inggs +Greg Rafferty +Győző Papp +Heikki Orsila +Henrik Sozzi +Hiroki Kawahara +Hugh McNamara +Hugo van Kemenade +Isabelle COWAN-BERGMAN +Jacky Han +Jacob Punter +Jaemin Kim +Jahir Fiquitiva +Jakob M. Kjær +Jan Pipek +Jason Jensen +Jeremy Chrimes +Jerry Agbesi +John Laswell +Joost van Driel +Jorge Cadena Argote +Jose Riha +Joshua Adelman +Joël van Amerongen +Julian Broudou +Jung Dong Ho +Justin Asfour +Kamil Leduchowski +Kate Golovanova +Kelsey Karin Hawley +Koert van der Veer +Koki Nomura +Kriti Birda +Laurent Comparet +Lucca Augusto +Maina Kamau +Malthe Borch +Marek Šuppa +Martin Becker +Martin Thurau +Matheus Oliveira +Maurizio Montel +Max Härtwig +Michael Thessel +Mike Borsetti +Mike Polyakovsky +Miroslav Šedivý +Monde Sinxi +Nalin Gupta +Nataliia Dmytriievska +Nate Harris +Nathan Ell +Nicholas Spagnoletti +Nico Albers +Olivier Iffrig +Ondřej Nový +Osayd Abdu +Oscar Romero +Pablo Merino +Panpakorn Siripanich +Patrick Nicholson +Paulo Orrock +Pavel Sofroniev +Pedro Baptista +Peter Zsak +Pieter van der Westhuizen +Piotr Staniów +Platon Supranovich +Prateekshit Jaiswal +Raphael Borg Ellul Vincenti +Raychel Mattheeuw +Reinaldo Ramos +Robert Frazier +Robert Schmidtke +Robert Tran +Robin Emeršič +Roshan Pradhan +Ryan McCrory +Sam Tregar +Samman Sarkar +Santiago Feliu +Sergi Almacellas Abellana +Sergio Mayoral Martinez +Serhii Murza +Shalom Donga +Shaurya Uppal +Sho Hirose +Shreyansh Pande +Shreyas Smarth +Simon Gurcke +Sindhura Kumbakonam Subramanian +Sugato Ray +Sylvain Pasche +Sylvia van Os +Søren Klintrup +Takeshi Osoekawa +Tasnim Nishat Islam +Tewodros Meshesha +Thomas Bøvith +Tommy Sparber +Tudor Văran +Victor Luna +Victor Miti +Ville Skyttä +Vilmos Prokaj +Vu Nhat Chuong +Wasif Shahzad +Youhei Sakurai diff --git a/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/licenses/LICENSE b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/licenses/LICENSE new file mode 100644 index 00000000..e00f477c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/licenses/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) Vacanza Team and individual contributors (see CONTRIBUTORS file) +Copyright (c) dr-prodigy , 2017-2023 +Copyright (c) ryanss , 2014-2017 + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/top_level.txt b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/top_level.txt new file mode 100644 index 00000000..a41943b6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays-0.77.dist-info/top_level.txt @@ -0,0 +1 @@ +holidays diff --git a/.venv/lib/python3.12/site-packages/holidays/__init__.py b/.venv/lib/python3.12/site-packages/holidays/__init__.py new file mode 100644 index 00000000..d0ffe439 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/__init__.py @@ -0,0 +1,22 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +# ruff: noqa: F403 + +from holidays.constants import * +from holidays.holiday_base import * +from holidays.registry import EntityLoader +from holidays.utils import * +from holidays.version import __version__ # noqa: F401 + +EntityLoader.load("countries", globals()) +EntityLoader.load("financial", globals()) diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..3f61e263 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/constants.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/constants.cpython-312.pyc new file mode 100644 index 00000000..7769b2c9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/constants.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/helpers.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/helpers.cpython-312.pyc new file mode 100644 index 00000000..0e152235 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/helpers.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/holiday_base.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/holiday_base.cpython-312.pyc new file mode 100644 index 00000000..493680f4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/holiday_base.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/ical.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/ical.cpython-312.pyc new file mode 100644 index 00000000..9f0ed3a1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/ical.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/observed_holiday_base.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/observed_holiday_base.cpython-312.pyc new file mode 100644 index 00000000..3163210c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/observed_holiday_base.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/registry.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/registry.cpython-312.pyc new file mode 100644 index 00000000..0c0cf2a0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/registry.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/utils.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/utils.cpython-312.pyc new file mode 100644 index 00000000..6c258278 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/utils.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/__pycache__/version.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/__pycache__/version.cpython-312.pyc new file mode 100644 index 00000000..3dcb3b11 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/__pycache__/version.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__init__.py b/.venv/lib/python3.12/site-packages/holidays/calendars/__init__.py new file mode 100644 index 00000000..66e2c4bd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/__init__.py @@ -0,0 +1,28 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +# ruff: noqa: F401 + +from holidays.calendars.balinese_saka import _BalineseSakaLunar +from holidays.calendars.buddhist import _BuddhistLunisolar, _CustomBuddhistHolidays +from holidays.calendars.chinese import _ChineseLunisolar, _CustomChineseHolidays +from holidays.calendars.custom import _CustomCalendar +from holidays.calendars.gregorian import GREGORIAN_CALENDAR +from holidays.calendars.hebrew import _HebrewLunisolar +from holidays.calendars.hindu import _CustomHinduHolidays, _HinduLunisolar +from holidays.calendars.islamic import _CustomIslamicHolidays, _IslamicLunar +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.calendars.julian_revised import JULIAN_REVISED_CALENDAR +from holidays.calendars.mongolian import _CustomMongolianHolidays, _MongolianLunisolar +from holidays.calendars.persian import _Persian +from holidays.calendars.sinhala import _SinhalaLunar, _CustomSinhalaHolidays +from holidays.calendars.thai import _ThaiLunisolar, KHMER_CALENDAR, THAI_CALENDAR diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..490c75b4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/balinese_saka.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/balinese_saka.cpython-312.pyc new file mode 100644 index 00000000..a90d0cae Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/balinese_saka.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/buddhist.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/buddhist.cpython-312.pyc new file mode 100644 index 00000000..c33bab0d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/buddhist.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/chinese.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/chinese.cpython-312.pyc new file mode 100644 index 00000000..374c797f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/chinese.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/custom.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/custom.cpython-312.pyc new file mode 100644 index 00000000..6428125a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/custom.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/gregorian.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/gregorian.cpython-312.pyc new file mode 100644 index 00000000..86133d76 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/gregorian.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/hebrew.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/hebrew.cpython-312.pyc new file mode 100644 index 00000000..bb98c380 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/hebrew.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/hindu.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/hindu.cpython-312.pyc new file mode 100644 index 00000000..e9d69a25 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/hindu.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/islamic.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/islamic.cpython-312.pyc new file mode 100644 index 00000000..6e4b765f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/islamic.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/julian.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/julian.cpython-312.pyc new file mode 100644 index 00000000..b79ccea0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/julian.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/julian_revised.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/julian_revised.cpython-312.pyc new file mode 100644 index 00000000..1bb12695 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/julian_revised.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/mongolian.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/mongolian.cpython-312.pyc new file mode 100644 index 00000000..c2471878 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/mongolian.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/persian.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/persian.cpython-312.pyc new file mode 100644 index 00000000..404b3433 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/persian.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/sinhala.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/sinhala.cpython-312.pyc new file mode 100644 index 00000000..defef4fa Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/sinhala.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/thai.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/thai.cpython-312.pyc new file mode 100644 index 00000000..6f841cce Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/calendars/__pycache__/thai.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/balinese_saka.py b/.venv/lib/python3.12/site-packages/holidays/calendars/balinese_saka.py new file mode 100644 index 00000000..c8afc5e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/balinese_saka.py @@ -0,0 +1,112 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import MAR, APR + +NYEPI = "NYEPI" + + +class _BalineseSakaLunar: + """ + Balinese Saka lunar calendar. + + The Balinese saka calendar is one of two calendars used on the Indonesian island + of Bali. Unlike the 210-day pawukon calendar, it is based on the phases of the Moon, + and is approximately the same length as the tropical year (solar year, Gregorian year). + https://en.wikipedia.org/wiki/Balinese_saka_calendar + """ + + NYEPI_DATES = { + 1983: (MAR, 15), + 1984: (MAR, 4), + 1985: (MAR, 22), + 1986: (MAR, 12), + 1987: (MAR, 31), + 1988: (MAR, 19), + 1989: (MAR, 9), + 1990: (MAR, 27), + 1991: (MAR, 17), + 1992: (MAR, 5), + 1993: (MAR, 24), + 1994: (MAR, 12), + 1995: (APR, 1), + 1996: (MAR, 21), + 1997: (APR, 9), + 1998: (MAR, 29), + 1999: (MAR, 18), + 2000: (APR, 4), + 2001: (MAR, 25), + 2002: (APR, 13), + 2003: (APR, 2), + 2004: (MAR, 22), + 2005: (MAR, 11), + 2006: (MAR, 30), + 2007: (MAR, 19), + 2008: (MAR, 7), + 2009: (MAR, 26), + 2010: (MAR, 16), + 2011: (MAR, 5), + 2012: (MAR, 23), + 2013: (MAR, 12), + 2014: (MAR, 31), + 2015: (MAR, 21), + 2016: (MAR, 9), + 2017: (MAR, 28), + 2018: (MAR, 17), + 2019: (MAR, 7), + 2020: (MAR, 25), + 2021: (MAR, 14), + 2022: (MAR, 3), + 2023: (MAR, 22), + 2024: (MAR, 11), + 2025: (MAR, 29), + 2026: (MAR, 19), + 2027: (MAR, 8), + 2028: (MAR, 26), + 2029: (MAR, 15), + 2030: (MAR, 5), + 2031: (MAR, 24), + 2032: (MAR, 12), + 2033: (MAR, 31), + 2034: (MAR, 20), + 2035: (MAR, 10), + 2036: (MAR, 28), + 2037: (MAR, 17), + 2038: (MAR, 6), + 2039: (MAR, 25), + 2040: (MAR, 14), + 2041: (MAR, 3), + 2042: (MAR, 22), + 2043: (MAR, 11), + 2044: (MAR, 29), + 2045: (MAR, 19), + 2046: (MAR, 8), + 2047: (MAR, 27), + 2048: (MAR, 15), + 2049: (MAR, 5), + 2050: (MAR, 24), + } + + def _get_holiday(self, holiday: str, year: int) -> Optional[date]: + dt = getattr(self, f"{holiday}_DATES", {}).get(year, ()) + return date(year, *dt) if dt else None + + def nyepi_date(self, year: int) -> Optional[date]: + """ + Data References: + * [1983-2025](https://id.wikipedia.org/wiki/Indonesia_dalam_tahun_1983) + * [2020-2050](https://web.archive.org/web/20240718011857/https://www.balitrips.com/balinese-temples-ceremony) + """ + return self._get_holiday(NYEPI, year) diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/buddhist.py b/.venv/lib/python3.12/site-packages/holidays/calendars/buddhist.py new file mode 100644 index 00000000..62a605a1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/buddhist.py @@ -0,0 +1,444 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.custom import _CustomCalendar +from holidays.calendars.gregorian import MAY, JUN + +VESAK = "VESAK" +VESAK_MAY = "VESAK_MAY" + + +class _BuddhistLunisolar: + VESAK_DATES = { + 1901: (JUN, 1), + 1902: (MAY, 22), + 1903: (MAY, 11), + 1904: (MAY, 29), + 1905: (MAY, 18), + 1906: (MAY, 8), + 1907: (MAY, 26), + 1908: (MAY, 14), + 1909: (JUN, 2), + 1910: (MAY, 23), + 1911: (MAY, 13), + 1912: (MAY, 31), + 1913: (MAY, 20), + 1914: (MAY, 9), + 1915: (MAY, 28), + 1916: (MAY, 16), + 1917: (JUN, 4), + 1918: (MAY, 24), + 1919: (MAY, 14), + 1920: (JUN, 1), + 1921: (MAY, 22), + 1922: (MAY, 11), + 1923: (MAY, 30), + 1924: (MAY, 18), + 1925: (MAY, 7), + 1926: (MAY, 26), + 1927: (MAY, 15), + 1928: (JUN, 2), + 1929: (MAY, 23), + 1930: (MAY, 13), + 1931: (MAY, 31), + 1932: (MAY, 20), + 1933: (MAY, 9), + 1934: (MAY, 27), + 1935: (MAY, 17), + 1936: (JUN, 4), + 1937: (MAY, 24), + 1938: (MAY, 14), + 1939: (JUN, 2), + 1940: (MAY, 21), + 1941: (MAY, 10), + 1942: (MAY, 29), + 1943: (MAY, 18), + 1944: (MAY, 7), + 1945: (MAY, 26), + 1946: (MAY, 15), + 1947: (JUN, 3), + 1948: (MAY, 23), + 1949: (MAY, 12), + 1950: (MAY, 31), + 1951: (MAY, 20), + 1952: (MAY, 8), + 1953: (MAY, 27), + 1954: (MAY, 17), + 1955: (JUN, 5), + 1956: (MAY, 24), + 1957: (MAY, 14), + 1958: (JUN, 2), + 1959: (MAY, 22), + 1960: (MAY, 10), + 1961: (MAY, 29), + 1962: (MAY, 18), + 1963: (MAY, 8), + 1964: (MAY, 26), + 1965: (MAY, 15), + 1966: (JUN, 3), + 1967: (MAY, 23), + 1968: (MAY, 11), + 1969: (MAY, 30), + 1970: (MAY, 19), + 1971: (MAY, 9), + 1972: (MAY, 27), + 1973: (MAY, 17), + 1974: (MAY, 6), + 1975: (MAY, 25), + 1976: (MAY, 13), + 1977: (JUN, 1), + 1978: (MAY, 21), + 1979: (MAY, 10), + 1980: (MAY, 28), + 1981: (MAY, 18), + 1982: (MAY, 8), + 1983: (MAY, 27), + 1984: (MAY, 15), + 1985: (JUN, 3), + 1986: (MAY, 23), + 1987: (MAY, 12), + 1988: (MAY, 30), + 1989: (MAY, 19), + 1990: (MAY, 9), + 1991: (MAY, 28), + 1992: (MAY, 17), + 1993: (JUN, 4), + 1994: (MAY, 25), + 1995: (MAY, 14), + 1996: (MAY, 31), + 1997: (MAY, 21), + 1998: (MAY, 10), + 1999: (MAY, 29), + 2000: (MAY, 18), + 2001: (MAY, 7), + 2002: (MAY, 26), + 2003: (MAY, 15), + 2004: (JUN, 2), + 2005: (MAY, 22), + 2006: (MAY, 12), + 2007: (MAY, 31), + 2008: (MAY, 19), + 2009: (MAY, 9), + 2010: (MAY, 28), + 2011: (MAY, 17), + 2012: (MAY, 5), + 2013: (MAY, 24), + 2014: (MAY, 13), + 2015: (JUN, 1), + 2016: (MAY, 21), + 2017: (MAY, 10), + 2018: (MAY, 29), + 2019: (MAY, 19), + 2020: (MAY, 7), + 2021: (MAY, 26), + 2022: (MAY, 15), + 2023: (JUN, 2), + 2024: (MAY, 22), + 2025: (MAY, 12), + 2026: (MAY, 31), + 2027: (MAY, 20), + 2028: (MAY, 9), + 2029: (MAY, 27), + 2030: (MAY, 16), + 2031: (JUN, 4), + 2032: (MAY, 23), + 2033: (MAY, 13), + 2034: (JUN, 1), + 2035: (MAY, 22), + 2036: (MAY, 10), + 2037: (MAY, 29), + 2038: (MAY, 18), + 2039: (MAY, 7), + 2040: (MAY, 25), + 2041: (MAY, 14), + 2042: (JUN, 2), + 2043: (MAY, 23), + 2044: (MAY, 12), + 2045: (MAY, 31), + 2046: (MAY, 20), + 2047: (MAY, 9), + 2048: (MAY, 27), + 2049: (MAY, 16), + 2050: (JUN, 4), + 2051: (MAY, 24), + 2052: (MAY, 13), + 2053: (JUN, 1), + 2054: (MAY, 22), + 2055: (MAY, 11), + 2056: (MAY, 29), + 2057: (MAY, 18), + 2058: (MAY, 7), + 2059: (MAY, 26), + 2060: (MAY, 14), + 2061: (JUN, 2), + 2062: (MAY, 23), + 2063: (MAY, 12), + 2064: (MAY, 30), + 2065: (MAY, 19), + 2066: (MAY, 8), + 2067: (MAY, 27), + 2068: (MAY, 16), + 2069: (MAY, 5), + 2070: (MAY, 24), + 2071: (MAY, 14), + 2072: (JUN, 1), + 2073: (MAY, 21), + 2074: (MAY, 10), + 2075: (MAY, 29), + 2076: (MAY, 17), + 2077: (MAY, 7), + 2078: (MAY, 26), + 2079: (MAY, 15), + 2080: (JUN, 2), + 2081: (MAY, 23), + 2082: (MAY, 12), + 2083: (MAY, 31), + 2084: (MAY, 19), + 2085: (MAY, 8), + 2086: (MAY, 27), + 2087: (MAY, 17), + 2088: (MAY, 5), + 2089: (MAY, 24), + 2090: (MAY, 14), + 2091: (JUN, 1), + 2092: (MAY, 20), + 2093: (MAY, 10), + 2094: (MAY, 28), + 2095: (MAY, 18), + 2096: (MAY, 7), + 2097: (MAY, 26), + 2098: (MAY, 15), + 2099: (JUN, 3), + 2100: (MAY, 23), + } + + VESAK_MAY_DATES = { + 1901: (MAY, 3), + 1902: (MAY, 22), + 1903: (MAY, 11), + 1904: (MAY, 29), + 1905: (MAY, 18), + 1906: (MAY, 8), + 1907: (MAY, 26), + 1908: (MAY, 14), + 1909: (MAY, 4), + 1910: (MAY, 23), + 1911: (MAY, 13), + 1912: (MAY, 1), + 1913: (MAY, 20), + 1914: (MAY, 9), + 1915: (MAY, 28), + 1916: (MAY, 16), + 1917: (MAY, 5), + 1918: (MAY, 24), + 1919: (MAY, 14), + 1920: (MAY, 3), + 1921: (MAY, 22), + 1922: (MAY, 11), + 1923: (MAY, 30), + 1924: (MAY, 18), + 1925: (MAY, 7), + 1926: (MAY, 26), + 1927: (MAY, 15), + 1928: (MAY, 4), + 1929: (MAY, 23), + 1930: (MAY, 13), + 1931: (MAY, 2), + 1932: (MAY, 20), + 1933: (MAY, 9), + 1934: (MAY, 27), + 1935: (MAY, 17), + 1936: (MAY, 5), + 1937: (MAY, 24), + 1938: (MAY, 14), + 1939: (MAY, 4), + 1940: (MAY, 21), + 1941: (MAY, 10), + 1942: (MAY, 29), + 1943: (MAY, 18), + 1944: (MAY, 7), + 1945: (MAY, 26), + 1946: (MAY, 15), + 1947: (MAY, 5), + 1948: (MAY, 23), + 1949: (MAY, 12), + 1950: (MAY, 1), + 1951: (MAY, 20), + 1952: (MAY, 8), + 1953: (MAY, 27), + 1954: (MAY, 17), + 1955: (MAY, 6), + 1956: (MAY, 24), + 1957: (MAY, 14), + 1958: (MAY, 3), + 1959: (MAY, 22), + 1960: (MAY, 10), + 1961: (MAY, 29), + 1962: (MAY, 18), + 1963: (MAY, 8), + 1964: (MAY, 26), + 1965: (MAY, 15), + 1966: (MAY, 5), + 1967: (MAY, 23), + 1968: (MAY, 11), + 1969: (MAY, 1), + 1970: (MAY, 19), + 1971: (MAY, 9), + 1972: (MAY, 27), + 1973: (MAY, 17), + 1974: (MAY, 6), + 1975: (MAY, 25), + 1976: (MAY, 13), + 1977: (MAY, 2), + 1978: (MAY, 21), + 1979: (MAY, 10), + 1980: (MAY, 28), + 1981: (MAY, 18), + 1982: (MAY, 8), + 1983: (MAY, 27), + 1984: (MAY, 15), + 1985: (MAY, 4), + 1986: (MAY, 23), + 1987: (MAY, 12), + 1988: (MAY, 30), + 1989: (MAY, 19), + 1990: (MAY, 9), + 1991: (MAY, 28), + 1992: (MAY, 17), + 1993: (MAY, 6), + 1994: (MAY, 25), + 1995: (MAY, 14), + 1996: (MAY, 2), + 1997: (MAY, 21), + 1998: (MAY, 10), + 1999: (MAY, 29), + 2000: (MAY, 18), + 2001: (MAY, 7), + 2002: (MAY, 26), + 2003: (MAY, 15), + 2004: (MAY, 3), + 2005: (MAY, 22), + 2006: (MAY, 12), + 2007: (MAY, 1), + 2008: (MAY, 19), + 2009: (MAY, 9), + 2010: (MAY, 28), + 2011: (MAY, 17), + 2012: (MAY, 5), + 2013: (MAY, 24), + 2014: (MAY, 13), + 2015: (MAY, 3), + 2016: (MAY, 21), + 2017: (MAY, 10), + 2018: (MAY, 29), + 2019: (MAY, 19), + 2020: (MAY, 7), + 2021: (MAY, 26), + 2022: (MAY, 15), + 2023: (MAY, 4), + 2024: (MAY, 22), + 2025: (MAY, 12), + 2026: (MAY, 1), + 2027: (MAY, 20), + 2028: (MAY, 9), + 2029: (MAY, 27), + 2030: (MAY, 16), + 2031: (MAY, 6), + 2032: (MAY, 23), + 2033: (MAY, 13), + 2034: (MAY, 3), + 2035: (MAY, 22), + 2036: (MAY, 10), + 2037: (MAY, 29), + 2038: (MAY, 18), + 2039: (MAY, 7), + 2040: (MAY, 25), + 2041: (MAY, 14), + 2042: (MAY, 4), + 2043: (MAY, 23), + 2044: (MAY, 12), + 2045: (MAY, 1), + 2046: (MAY, 20), + 2047: (MAY, 9), + 2048: (MAY, 27), + 2049: (MAY, 16), + 2050: (MAY, 5), + 2051: (MAY, 24), + 2052: (MAY, 13), + 2053: (MAY, 3), + 2054: (MAY, 22), + 2055: (MAY, 11), + 2056: (MAY, 29), + 2057: (MAY, 18), + 2058: (MAY, 7), + 2059: (MAY, 26), + 2060: (MAY, 14), + 2061: (MAY, 4), + 2062: (MAY, 23), + 2063: (MAY, 12), + 2064: (MAY, 1), + 2065: (MAY, 19), + 2066: (MAY, 8), + 2067: (MAY, 27), + 2068: (MAY, 16), + 2069: (MAY, 5), + 2070: (MAY, 24), + 2071: (MAY, 14), + 2072: (MAY, 2), + 2073: (MAY, 21), + 2074: (MAY, 10), + 2075: (MAY, 29), + 2076: (MAY, 17), + 2077: (MAY, 7), + 2078: (MAY, 26), + 2079: (MAY, 15), + 2080: (MAY, 4), + 2081: (MAY, 23), + 2082: (MAY, 12), + 2083: (MAY, 1), + 2084: (MAY, 19), + 2085: (MAY, 8), + 2086: (MAY, 27), + 2087: (MAY, 17), + 2088: (MAY, 5), + 2089: (MAY, 24), + 2090: (MAY, 14), + 2091: (MAY, 3), + 2092: (MAY, 20), + 2093: (MAY, 10), + 2094: (MAY, 28), + 2095: (MAY, 18), + 2096: (MAY, 7), + 2097: (MAY, 26), + 2098: (MAY, 15), + 2099: (MAY, 4), + 2100: (MAY, 23), + } + + def _get_holiday(self, holiday: str, year: int) -> tuple[Optional[date], bool]: + estimated_dates = getattr(self, f"{holiday}_DATES", {}) + exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}) + dt = exact_dates.get(year, estimated_dates.get(year, ())) + return date(year, *dt) if dt else None, year not in exact_dates + + def vesak_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(VESAK, year) + + def vesak_may_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(VESAK_MAY, year) + + +class _CustomBuddhistHolidays(_CustomCalendar, _BuddhistLunisolar): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/chinese.py b/.venv/lib/python3.12/site-packages/holidays/calendars/chinese.py new file mode 100644 index 00000000..0e3205ef --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/chinese.py @@ -0,0 +1,1354 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.custom import _CustomCalendar +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, SEP, OCT, NOV + +CHINESE_CALENDAR = "CHINESE_CALENDAR" +KOREAN_CALENDAR = "KOREAN_CALENDAR" +VIETNAMESE_CALENDAR = "VIETNAMESE_CALENDAR" + +BUDDHA_BIRTHDAY = "BUDDHA_BIRTHDAY" +DOUBLE_NINTH = "DOUBLE_NINTH" +DRAGON_BOAT = "DRAGON_BOAT" +HUNG_KINGS = "HUNG_KINGS" +LUNAR_NEW_YEAR = "LUNAR_NEW_YEAR" +MID_AUTUMN = "MID_AUTUMN" + + +class _ChineseLunisolar: + BUDDHA_BIRTHDAY_DATES = { + 1901: (MAY, 25), + 1902: (MAY, 15), + 1903: (MAY, 4), + 1904: (MAY, 22), + 1905: (MAY, 11), + 1906: (MAY, 1), + 1907: (MAY, 19), + 1908: (MAY, 7), + 1909: (MAY, 26), + 1910: (MAY, 16), + 1911: (MAY, 6), + 1912: (MAY, 24), + 1913: (MAY, 13), + 1914: (MAY, 2), + 1915: (MAY, 21), + 1916: (MAY, 9), + 1917: (MAY, 28), + 1918: (MAY, 17), + 1919: (MAY, 7), + 1920: (MAY, 25), + 1921: (MAY, 15), + 1922: (MAY, 4), + 1923: (MAY, 23), + 1924: (MAY, 11), + 1925: (APR, 30), + 1926: (MAY, 19), + 1927: (MAY, 8), + 1928: (MAY, 26), + 1929: (MAY, 16), + 1930: (MAY, 6), + 1931: (MAY, 24), + 1932: (MAY, 13), + 1933: (MAY, 2), + 1934: (MAY, 20), + 1935: (MAY, 10), + 1936: (MAY, 28), + 1937: (MAY, 17), + 1938: (MAY, 7), + 1939: (MAY, 26), + 1940: (MAY, 14), + 1941: (MAY, 3), + 1942: (MAY, 22), + 1943: (MAY, 11), + 1944: (APR, 30), + 1945: (MAY, 19), + 1946: (MAY, 8), + 1947: (MAY, 27), + 1948: (MAY, 16), + 1949: (MAY, 5), + 1950: (MAY, 24), + 1951: (MAY, 13), + 1952: (MAY, 1), + 1953: (MAY, 20), + 1954: (MAY, 10), + 1955: (MAY, 29), + 1956: (MAY, 17), + 1957: (MAY, 7), + 1958: (MAY, 26), + 1959: (MAY, 15), + 1960: (MAY, 3), + 1961: (MAY, 22), + 1962: (MAY, 11), + 1963: (MAY, 1), + 1964: (MAY, 19), + 1965: (MAY, 8), + 1966: (MAY, 27), + 1967: (MAY, 16), + 1968: (MAY, 4), + 1969: (MAY, 23), + 1970: (MAY, 12), + 1971: (MAY, 2), + 1972: (MAY, 20), + 1973: (MAY, 10), + 1974: (APR, 29), + 1975: (MAY, 18), + 1976: (MAY, 6), + 1977: (MAY, 25), + 1978: (MAY, 14), + 1979: (MAY, 3), + 1980: (MAY, 21), + 1981: (MAY, 11), + 1982: (MAY, 1), + 1983: (MAY, 20), + 1984: (MAY, 8), + 1985: (MAY, 27), + 1986: (MAY, 16), + 1987: (MAY, 5), + 1988: (MAY, 23), + 1989: (MAY, 12), + 1990: (MAY, 2), + 1991: (MAY, 21), + 1992: (MAY, 10), + 1993: (MAY, 28), + 1994: (MAY, 18), + 1995: (MAY, 7), + 1996: (MAY, 24), + 1997: (MAY, 14), + 1998: (MAY, 3), + 1999: (MAY, 22), + 2000: (MAY, 11), + 2001: (APR, 30), + 2002: (MAY, 19), + 2003: (MAY, 8), + 2004: (MAY, 26), + 2005: (MAY, 15), + 2006: (MAY, 5), + 2007: (MAY, 24), + 2008: (MAY, 12), + 2009: (MAY, 2), + 2010: (MAY, 21), + 2011: (MAY, 10), + 2012: (APR, 28), + 2013: (MAY, 17), + 2014: (MAY, 6), + 2015: (MAY, 25), + 2016: (MAY, 14), + 2017: (MAY, 3), + 2018: (MAY, 22), + 2019: (MAY, 12), + 2020: (APR, 30), + 2021: (MAY, 19), + 2022: (MAY, 8), + 2023: (MAY, 26), + 2024: (MAY, 15), + 2025: (MAY, 5), + 2026: (MAY, 24), + 2027: (MAY, 13), + 2028: (MAY, 2), + 2029: (MAY, 20), + 2030: (MAY, 9), + 2031: (MAY, 28), + 2032: (MAY, 16), + 2033: (MAY, 6), + 2034: (MAY, 25), + 2035: (MAY, 15), + 2036: (MAY, 3), + 2037: (MAY, 22), + 2038: (MAY, 11), + 2039: (APR, 30), + 2040: (MAY, 18), + 2041: (MAY, 7), + 2042: (MAY, 26), + 2043: (MAY, 16), + 2044: (MAY, 5), + 2045: (MAY, 24), + 2046: (MAY, 13), + 2047: (MAY, 2), + 2048: (MAY, 20), + 2049: (MAY, 9), + 2050: (MAY, 28), + 2051: (MAY, 17), + 2052: (MAY, 6), + 2053: (MAY, 25), + 2054: (MAY, 15), + 2055: (MAY, 4), + 2056: (MAY, 22), + 2057: (MAY, 11), + 2058: (APR, 30), + 2059: (MAY, 19), + 2060: (MAY, 7), + 2061: (MAY, 26), + 2062: (MAY, 16), + 2063: (MAY, 5), + 2064: (MAY, 23), + 2065: (MAY, 12), + 2066: (MAY, 1), + 2067: (MAY, 20), + 2068: (MAY, 9), + 2069: (APR, 28), + 2070: (MAY, 17), + 2071: (MAY, 7), + 2072: (MAY, 25), + 2073: (MAY, 14), + 2074: (MAY, 3), + 2075: (MAY, 22), + 2076: (MAY, 10), + 2077: (APR, 30), + 2078: (MAY, 19), + 2079: (MAY, 8), + 2080: (MAY, 26), + 2081: (MAY, 16), + 2082: (MAY, 5), + 2083: (MAY, 24), + 2084: (MAY, 12), + 2085: (MAY, 1), + 2086: (MAY, 20), + 2087: (MAY, 10), + 2088: (APR, 28), + 2089: (MAY, 17), + 2090: (MAY, 7), + 2091: (MAY, 25), + 2092: (MAY, 13), + 2093: (MAY, 3), + 2094: (MAY, 21), + 2095: (MAY, 11), + 2096: (APR, 30), + 2097: (MAY, 19), + 2098: (MAY, 8), + 2099: (MAY, 27), + 2100: (MAY, 16), + } + + DOUBLE_NINTH_DATES = { + 1901: (OCT, 20), + 1902: (OCT, 10), + 1903: (OCT, 28), + 1904: (OCT, 17), + 1905: (OCT, 7), + 1906: (OCT, 26), + 1907: (OCT, 15), + 1908: (OCT, 3), + 1909: (OCT, 22), + 1910: (OCT, 11), + 1911: (OCT, 30), + 1912: (OCT, 18), + 1913: (OCT, 8), + 1914: (OCT, 27), + 1915: (OCT, 17), + 1916: (OCT, 5), + 1917: (OCT, 24), + 1918: (OCT, 13), + 1919: (NOV, 1), + 1920: (OCT, 20), + 1921: (OCT, 9), + 1922: (OCT, 28), + 1923: (OCT, 18), + 1924: (OCT, 7), + 1925: (OCT, 26), + 1926: (OCT, 15), + 1927: (OCT, 4), + 1928: (OCT, 21), + 1929: (OCT, 11), + 1930: (OCT, 30), + 1931: (OCT, 19), + 1932: (OCT, 8), + 1933: (OCT, 27), + 1934: (OCT, 16), + 1935: (OCT, 6), + 1936: (OCT, 23), + 1937: (OCT, 12), + 1938: (OCT, 31), + 1939: (OCT, 21), + 1940: (OCT, 9), + 1941: (OCT, 28), + 1942: (OCT, 18), + 1943: (OCT, 7), + 1944: (OCT, 25), + 1945: (OCT, 14), + 1946: (OCT, 3), + 1947: (OCT, 22), + 1948: (OCT, 11), + 1949: (OCT, 30), + 1950: (OCT, 19), + 1951: (OCT, 9), + 1952: (OCT, 27), + 1953: (OCT, 16), + 1954: (OCT, 5), + 1955: (OCT, 24), + 1956: (OCT, 12), + 1957: (OCT, 31), + 1958: (OCT, 21), + 1959: (OCT, 10), + 1960: (OCT, 28), + 1961: (OCT, 18), + 1962: (OCT, 7), + 1963: (OCT, 25), + 1964: (OCT, 14), + 1965: (OCT, 3), + 1966: (OCT, 22), + 1967: (OCT, 12), + 1968: (OCT, 30), + 1969: (OCT, 19), + 1970: (OCT, 8), + 1971: (OCT, 27), + 1972: (OCT, 15), + 1973: (OCT, 4), + 1974: (OCT, 23), + 1975: (OCT, 13), + 1976: (OCT, 31), + 1977: (OCT, 21), + 1978: (OCT, 10), + 1979: (OCT, 29), + 1980: (OCT, 17), + 1981: (OCT, 6), + 1982: (OCT, 25), + 1983: (OCT, 14), + 1984: (OCT, 3), + 1985: (OCT, 22), + 1986: (OCT, 12), + 1987: (OCT, 31), + 1988: (OCT, 19), + 1989: (OCT, 8), + 1990: (OCT, 26), + 1991: (OCT, 16), + 1992: (OCT, 4), + 1993: (OCT, 23), + 1994: (OCT, 13), + 1995: (NOV, 1), + 1996: (OCT, 20), + 1997: (OCT, 10), + 1998: (OCT, 28), + 1999: (OCT, 17), + 2000: (OCT, 6), + 2001: (OCT, 25), + 2002: (OCT, 14), + 2003: (OCT, 4), + 2004: (OCT, 22), + 2005: (OCT, 11), + 2006: (OCT, 30), + 2007: (OCT, 19), + 2008: (OCT, 7), + 2009: (OCT, 26), + 2010: (OCT, 16), + 2011: (OCT, 5), + 2012: (OCT, 23), + 2013: (OCT, 13), + 2014: (OCT, 2), + 2015: (OCT, 21), + 2016: (OCT, 9), + 2017: (OCT, 28), + 2018: (OCT, 17), + 2019: (OCT, 7), + 2020: (OCT, 25), + 2021: (OCT, 14), + 2022: (OCT, 4), + 2023: (OCT, 23), + 2024: (OCT, 11), + 2025: (OCT, 29), + 2026: (OCT, 18), + 2027: (OCT, 8), + 2028: (OCT, 26), + 2029: (OCT, 16), + 2030: (OCT, 5), + 2031: (OCT, 24), + 2032: (OCT, 12), + 2033: (OCT, 1), + 2034: (OCT, 20), + 2035: (OCT, 9), + 2036: (OCT, 27), + 2037: (OCT, 17), + 2038: (OCT, 7), + 2039: (OCT, 26), + 2040: (OCT, 14), + 2041: (OCT, 3), + 2042: (OCT, 22), + 2043: (OCT, 11), + 2044: (OCT, 29), + 2045: (OCT, 18), + 2046: (OCT, 8), + 2047: (OCT, 27), + 2048: (OCT, 16), + 2049: (OCT, 5), + 2050: (OCT, 24), + 2051: (OCT, 13), + 2052: (OCT, 30), + 2053: (OCT, 20), + 2054: (OCT, 9), + 2055: (OCT, 28), + 2056: (OCT, 17), + 2057: (OCT, 7), + 2058: (OCT, 25), + 2059: (OCT, 14), + 2060: (OCT, 2), + 2061: (OCT, 21), + 2062: (OCT, 11), + 2063: (OCT, 30), + 2064: (OCT, 18), + 2065: (OCT, 8), + 2066: (OCT, 27), + 2067: (OCT, 16), + 2068: (OCT, 4), + 2069: (OCT, 23), + 2070: (OCT, 12), + 2071: (OCT, 31), + 2072: (OCT, 20), + 2073: (OCT, 9), + 2074: (OCT, 28), + 2075: (OCT, 18), + 2076: (OCT, 6), + 2077: (OCT, 25), + 2078: (OCT, 14), + 2079: (OCT, 3), + 2080: (OCT, 21), + 2081: (OCT, 11), + 2082: (OCT, 30), + 2083: (OCT, 19), + 2084: (OCT, 8), + 2085: (OCT, 27), + 2086: (OCT, 16), + 2087: (OCT, 5), + 2088: (OCT, 22), + 2089: (OCT, 12), + 2090: (OCT, 31), + 2091: (OCT, 21), + 2092: (OCT, 9), + 2093: (OCT, 28), + 2094: (OCT, 17), + 2095: (OCT, 6), + 2096: (OCT, 24), + 2097: (OCT, 13), + 2098: (OCT, 3), + 2099: (OCT, 22), + 2100: (OCT, 12), + } + + DRAGON_BOAT_DATES = { + 1901: (JUN, 20), + 1902: (JUN, 10), + 1903: (MAY, 31), + 1904: (JUN, 18), + 1905: (JUN, 7), + 1906: (JUN, 26), + 1907: (JUN, 15), + 1908: (JUN, 3), + 1909: (JUN, 22), + 1910: (JUN, 11), + 1911: (JUN, 1), + 1912: (JUN, 19), + 1913: (JUN, 9), + 1914: (MAY, 29), + 1915: (JUN, 17), + 1916: (JUN, 5), + 1917: (JUN, 23), + 1918: (JUN, 13), + 1919: (JUN, 2), + 1920: (JUN, 20), + 1921: (JUN, 10), + 1922: (MAY, 31), + 1923: (JUN, 18), + 1924: (JUN, 6), + 1925: (JUN, 25), + 1926: (JUN, 14), + 1927: (JUN, 4), + 1928: (JUN, 22), + 1929: (JUN, 11), + 1930: (JUN, 1), + 1931: (JUN, 20), + 1932: (JUN, 8), + 1933: (MAY, 28), + 1934: (JUN, 16), + 1935: (JUN, 5), + 1936: (JUN, 23), + 1937: (JUN, 13), + 1938: (JUN, 2), + 1939: (JUN, 21), + 1940: (JUN, 10), + 1941: (MAY, 30), + 1942: (JUN, 18), + 1943: (JUN, 7), + 1944: (JUN, 25), + 1945: (JUN, 14), + 1946: (JUN, 4), + 1947: (JUN, 23), + 1948: (JUN, 11), + 1949: (JUN, 1), + 1950: (JUN, 19), + 1951: (JUN, 9), + 1952: (MAY, 28), + 1953: (JUN, 15), + 1954: (JUN, 5), + 1955: (JUN, 24), + 1956: (JUN, 13), + 1957: (JUN, 2), + 1958: (JUN, 21), + 1959: (JUN, 10), + 1960: (MAY, 29), + 1961: (JUN, 17), + 1962: (JUN, 6), + 1963: (JUN, 25), + 1964: (JUN, 14), + 1965: (JUN, 4), + 1966: (JUN, 23), + 1967: (JUN, 12), + 1968: (MAY, 31), + 1969: (JUN, 19), + 1970: (JUN, 8), + 1971: (MAY, 28), + 1972: (JUN, 15), + 1973: (JUN, 5), + 1974: (JUN, 24), + 1975: (JUN, 14), + 1976: (JUN, 2), + 1977: (JUN, 21), + 1978: (JUN, 10), + 1979: (MAY, 30), + 1980: (JUN, 17), + 1981: (JUN, 6), + 1982: (JUN, 25), + 1983: (JUN, 15), + 1984: (JUN, 4), + 1985: (JUN, 22), + 1986: (JUN, 11), + 1987: (MAY, 31), + 1988: (JUN, 18), + 1989: (JUN, 8), + 1990: (MAY, 28), + 1991: (JUN, 16), + 1992: (JUN, 5), + 1993: (JUN, 24), + 1994: (JUN, 13), + 1995: (JUN, 2), + 1996: (JUN, 20), + 1997: (JUN, 9), + 1998: (MAY, 30), + 1999: (JUN, 18), + 2000: (JUN, 6), + 2001: (JUN, 25), + 2002: (JUN, 15), + 2003: (JUN, 4), + 2004: (JUN, 22), + 2005: (JUN, 11), + 2006: (MAY, 31), + 2007: (JUN, 19), + 2008: (JUN, 8), + 2009: (MAY, 28), + 2010: (JUN, 16), + 2011: (JUN, 6), + 2012: (JUN, 23), + 2013: (JUN, 12), + 2014: (JUN, 2), + 2015: (JUN, 20), + 2016: (JUN, 9), + 2017: (MAY, 30), + 2018: (JUN, 18), + 2019: (JUN, 7), + 2020: (JUN, 25), + 2021: (JUN, 14), + 2022: (JUN, 3), + 2023: (JUN, 22), + 2024: (JUN, 10), + 2025: (MAY, 31), + 2026: (JUN, 19), + 2027: (JUN, 9), + 2028: (MAY, 28), + 2029: (JUN, 16), + 2030: (JUN, 5), + 2031: (JUN, 24), + 2032: (JUN, 12), + 2033: (JUN, 1), + 2034: (JUN, 20), + 2035: (JUN, 10), + 2036: (MAY, 30), + 2037: (JUN, 18), + 2038: (JUN, 7), + 2039: (MAY, 27), + 2040: (JUN, 14), + 2041: (JUN, 3), + 2042: (JUN, 22), + 2043: (JUN, 11), + 2044: (MAY, 31), + 2045: (JUN, 19), + 2046: (JUN, 8), + 2047: (MAY, 29), + 2048: (JUN, 15), + 2049: (JUN, 4), + 2050: (JUN, 23), + 2051: (JUN, 13), + 2052: (JUN, 1), + 2053: (JUN, 20), + 2054: (JUN, 10), + 2055: (MAY, 30), + 2056: (JUN, 17), + 2057: (JUN, 6), + 2058: (JUN, 25), + 2059: (JUN, 14), + 2060: (JUN, 3), + 2061: (JUN, 22), + 2062: (JUN, 11), + 2063: (JUN, 1), + 2064: (JUN, 19), + 2065: (JUN, 8), + 2066: (MAY, 28), + 2067: (JUN, 16), + 2068: (JUN, 4), + 2069: (JUN, 23), + 2070: (JUN, 13), + 2071: (JUN, 2), + 2072: (JUN, 20), + 2073: (JUN, 10), + 2074: (MAY, 30), + 2075: (JUN, 17), + 2076: (JUN, 6), + 2077: (JUN, 24), + 2078: (JUN, 14), + 2079: (JUN, 4), + 2080: (JUN, 22), + 2081: (JUN, 11), + 2082: (JUN, 1), + 2083: (JUN, 19), + 2084: (JUN, 7), + 2085: (MAY, 27), + 2086: (JUN, 15), + 2087: (JUN, 5), + 2088: (JUN, 23), + 2089: (JUN, 13), + 2090: (JUN, 2), + 2091: (JUN, 21), + 2092: (JUN, 9), + 2093: (MAY, 29), + 2094: (JUN, 17), + 2095: (JUN, 6), + 2096: (JUN, 24), + 2097: (JUN, 14), + 2098: (JUN, 4), + 2099: (JUN, 23), + 2100: (JUN, 12), + } + + HUNG_KINGS_DATES = { + 1901: (APR, 28), + 1902: (APR, 17), + 1903: (APR, 7), + 1904: (APR, 25), + 1905: (APR, 14), + 1906: (APR, 3), + 1907: (APR, 22), + 1908: (APR, 10), + 1909: (APR, 29), + 1910: (APR, 19), + 1911: (APR, 8), + 1912: (APR, 26), + 1913: (APR, 16), + 1914: (APR, 5), + 1915: (APR, 23), + 1916: (APR, 12), + 1917: (APR, 30), + 1918: (APR, 20), + 1919: (APR, 10), + 1920: (APR, 28), + 1921: (APR, 17), + 1922: (APR, 6), + 1923: (APR, 25), + 1924: (APR, 13), + 1925: (APR, 2), + 1926: (APR, 21), + 1927: (APR, 11), + 1928: (APR, 29), + 1929: (APR, 19), + 1930: (APR, 8), + 1931: (APR, 27), + 1932: (APR, 15), + 1933: (APR, 4), + 1934: (APR, 23), + 1935: (APR, 12), + 1936: (APR, 1), + 1937: (APR, 20), + 1938: (APR, 10), + 1939: (APR, 29), + 1940: (APR, 17), + 1941: (APR, 6), + 1942: (APR, 24), + 1943: (APR, 14), + 1944: (APR, 2), + 1945: (APR, 21), + 1946: (APR, 11), + 1947: (APR, 30), + 1948: (APR, 18), + 1949: (APR, 7), + 1950: (APR, 26), + 1951: (APR, 15), + 1952: (APR, 4), + 1953: (APR, 23), + 1954: (APR, 12), + 1955: (APR, 2), + 1956: (APR, 20), + 1957: (APR, 9), + 1958: (APR, 28), + 1959: (APR, 17), + 1960: (APR, 5), + 1961: (APR, 24), + 1962: (APR, 14), + 1963: (APR, 3), + 1964: (APR, 21), + 1965: (APR, 11), + 1966: (MAR, 31), + 1967: (APR, 19), + 1968: (APR, 7), + 1969: (APR, 26), + 1970: (APR, 15), + 1971: (APR, 5), + 1972: (APR, 23), + 1973: (APR, 12), + 1974: (APR, 2), + 1975: (APR, 21), + 1976: (APR, 9), + 1977: (APR, 27), + 1978: (APR, 16), + 1979: (APR, 6), + 1980: (APR, 24), + 1981: (APR, 14), + 1982: (APR, 3), + 1983: (APR, 22), + 1984: (APR, 10), + 1985: (APR, 29), + 1986: (APR, 18), + 1987: (APR, 7), + 1988: (APR, 25), + 1989: (APR, 15), + 1990: (APR, 5), + 1991: (APR, 24), + 1992: (APR, 12), + 1993: (APR, 1), + 1994: (APR, 20), + 1995: (APR, 9), + 1996: (APR, 27), + 1997: (APR, 16), + 1998: (APR, 6), + 1999: (APR, 25), + 2000: (APR, 14), + 2001: (APR, 3), + 2002: (APR, 22), + 2003: (APR, 11), + 2004: (APR, 28), + 2005: (APR, 18), + 2006: (APR, 7), + 2007: (APR, 26), + 2008: (APR, 15), + 2009: (APR, 5), + 2010: (APR, 23), + 2011: (APR, 12), + 2012: (MAR, 31), + 2013: (APR, 19), + 2014: (APR, 9), + 2015: (APR, 28), + 2016: (APR, 16), + 2017: (APR, 6), + 2018: (APR, 25), + 2019: (APR, 14), + 2020: (APR, 2), + 2021: (APR, 21), + 2022: (APR, 10), + 2023: (APR, 29), + 2024: (APR, 18), + 2025: (APR, 7), + 2026: (APR, 26), + 2027: (APR, 16), + 2028: (APR, 4), + 2029: (APR, 23), + 2030: (APR, 12), + 2031: (APR, 1), + 2032: (APR, 19), + 2033: (APR, 9), + 2034: (APR, 28), + 2035: (APR, 17), + 2036: (APR, 6), + 2037: (APR, 25), + 2038: (APR, 14), + 2039: (APR, 3), + 2040: (APR, 20), + 2041: (APR, 10), + 2042: (APR, 29), + 2043: (APR, 19), + 2044: (APR, 7), + 2045: (APR, 26), + 2046: (APR, 15), + 2047: (APR, 4), + 2048: (APR, 22), + 2049: (APR, 11), + 2050: (APR, 1), + 2051: (APR, 20), + 2052: (APR, 9), + 2053: (APR, 28), + 2054: (APR, 17), + 2055: (APR, 6), + 2056: (APR, 24), + 2057: (APR, 13), + 2058: (APR, 2), + 2059: (APR, 21), + 2060: (APR, 10), + 2061: (MAR, 31), + 2062: (APR, 19), + 2063: (APR, 8), + 2064: (APR, 26), + 2065: (APR, 15), + 2066: (APR, 4), + 2067: (APR, 23), + 2068: (APR, 11), + 2069: (APR, 1), + 2070: (APR, 20), + 2071: (APR, 9), + 2072: (APR, 27), + 2073: (APR, 16), + 2074: (APR, 5), + 2075: (APR, 24), + 2076: (APR, 13), + 2077: (APR, 2), + 2078: (APR, 21), + 2079: (APR, 11), + 2080: (MAR, 30), + 2081: (APR, 18), + 2082: (APR, 7), + 2083: (APR, 26), + 2084: (APR, 14), + 2085: (APR, 4), + 2086: (APR, 23), + 2087: (APR, 12), + 2088: (APR, 1), + 2089: (APR, 20), + 2090: (APR, 9), + 2091: (APR, 28), + 2092: (APR, 16), + 2093: (APR, 5), + 2094: (APR, 24), + 2095: (APR, 14), + 2096: (APR, 2), + 2097: (APR, 21), + 2098: (APR, 11), + 2099: (APR, 29), + 2100: (APR, 19), + } + + LUNAR_NEW_YEAR_DATES = { + 1901: (FEB, 19), + 1902: (FEB, 8), + 1903: (JAN, 29), + 1904: (FEB, 16), + 1905: (FEB, 4), + 1906: (JAN, 25), + 1907: (FEB, 13), + 1908: (FEB, 2), + 1909: (JAN, 22), + 1910: (FEB, 10), + 1911: (JAN, 30), + 1912: (FEB, 18), + 1913: (FEB, 6), + 1914: (JAN, 26), + 1915: (FEB, 14), + 1916: (FEB, 4), + 1917: (JAN, 23), + 1918: (FEB, 11), + 1919: (FEB, 1), + 1920: (FEB, 20), + 1921: (FEB, 8), + 1922: (JAN, 28), + 1923: (FEB, 16), + 1924: (FEB, 5), + 1925: (JAN, 24), + 1926: (FEB, 13), + 1927: (FEB, 2), + 1928: (JAN, 23), + 1929: (FEB, 10), + 1930: (JAN, 30), + 1931: (FEB, 17), + 1932: (FEB, 6), + 1933: (JAN, 26), + 1934: (FEB, 14), + 1935: (FEB, 4), + 1936: (JAN, 24), + 1937: (FEB, 11), + 1938: (JAN, 31), + 1939: (FEB, 19), + 1940: (FEB, 8), + 1941: (JAN, 27), + 1942: (FEB, 15), + 1943: (FEB, 5), + 1944: (JAN, 25), + 1945: (FEB, 13), + 1946: (FEB, 2), + 1947: (JAN, 22), + 1948: (FEB, 10), + 1949: (JAN, 29), + 1950: (FEB, 17), + 1951: (FEB, 6), + 1952: (JAN, 27), + 1953: (FEB, 14), + 1954: (FEB, 3), + 1955: (JAN, 24), + 1956: (FEB, 12), + 1957: (JAN, 31), + 1958: (FEB, 18), + 1959: (FEB, 8), + 1960: (JAN, 28), + 1961: (FEB, 15), + 1962: (FEB, 5), + 1963: (JAN, 25), + 1964: (FEB, 13), + 1965: (FEB, 2), + 1966: (JAN, 21), + 1967: (FEB, 9), + 1968: (JAN, 30), + 1969: (FEB, 17), + 1970: (FEB, 6), + 1971: (JAN, 27), + 1972: (FEB, 15), + 1973: (FEB, 3), + 1974: (JAN, 23), + 1975: (FEB, 11), + 1976: (JAN, 31), + 1977: (FEB, 18), + 1978: (FEB, 7), + 1979: (JAN, 28), + 1980: (FEB, 16), + 1981: (FEB, 5), + 1982: (JAN, 25), + 1983: (FEB, 13), + 1984: (FEB, 2), + 1985: (FEB, 20), + 1986: (FEB, 9), + 1987: (JAN, 29), + 1988: (FEB, 17), + 1989: (FEB, 6), + 1990: (JAN, 27), + 1991: (FEB, 15), + 1992: (FEB, 4), + 1993: (JAN, 23), + 1994: (FEB, 10), + 1995: (JAN, 31), + 1996: (FEB, 19), + 1997: (FEB, 7), + 1998: (JAN, 28), + 1999: (FEB, 16), + 2000: (FEB, 5), + 2001: (JAN, 24), + 2002: (FEB, 12), + 2003: (FEB, 1), + 2004: (JAN, 22), + 2005: (FEB, 9), + 2006: (JAN, 29), + 2007: (FEB, 18), + 2008: (FEB, 7), + 2009: (JAN, 26), + 2010: (FEB, 14), + 2011: (FEB, 3), + 2012: (JAN, 23), + 2013: (FEB, 10), + 2014: (JAN, 31), + 2015: (FEB, 19), + 2016: (FEB, 8), + 2017: (JAN, 28), + 2018: (FEB, 16), + 2019: (FEB, 5), + 2020: (JAN, 25), + 2021: (FEB, 12), + 2022: (FEB, 1), + 2023: (JAN, 22), + 2024: (FEB, 10), + 2025: (JAN, 29), + 2026: (FEB, 17), + 2027: (FEB, 6), + 2028: (JAN, 26), + 2029: (FEB, 13), + 2030: (FEB, 3), + 2031: (JAN, 23), + 2032: (FEB, 11), + 2033: (JAN, 31), + 2034: (FEB, 19), + 2035: (FEB, 8), + 2036: (JAN, 28), + 2037: (FEB, 15), + 2038: (FEB, 4), + 2039: (JAN, 24), + 2040: (FEB, 12), + 2041: (FEB, 1), + 2042: (JAN, 22), + 2043: (FEB, 10), + 2044: (JAN, 30), + 2045: (FEB, 17), + 2046: (FEB, 6), + 2047: (JAN, 26), + 2048: (FEB, 14), + 2049: (FEB, 2), + 2050: (JAN, 23), + 2051: (FEB, 11), + 2052: (FEB, 1), + 2053: (FEB, 19), + 2054: (FEB, 8), + 2055: (JAN, 28), + 2056: (FEB, 15), + 2057: (FEB, 4), + 2058: (JAN, 24), + 2059: (FEB, 12), + 2060: (FEB, 2), + 2061: (JAN, 21), + 2062: (FEB, 9), + 2063: (JAN, 29), + 2064: (FEB, 17), + 2065: (FEB, 5), + 2066: (JAN, 26), + 2067: (FEB, 14), + 2068: (FEB, 3), + 2069: (JAN, 23), + 2070: (FEB, 11), + 2071: (JAN, 31), + 2072: (FEB, 19), + 2073: (FEB, 7), + 2074: (JAN, 27), + 2075: (FEB, 15), + 2076: (FEB, 5), + 2077: (JAN, 24), + 2078: (FEB, 12), + 2079: (FEB, 2), + 2080: (JAN, 22), + 2081: (FEB, 9), + 2082: (JAN, 29), + 2083: (FEB, 17), + 2084: (FEB, 6), + 2085: (JAN, 26), + 2086: (FEB, 14), + 2087: (FEB, 3), + 2088: (JAN, 24), + 2089: (FEB, 10), + 2090: (JAN, 30), + 2091: (FEB, 18), + 2092: (FEB, 7), + 2093: (JAN, 27), + 2094: (FEB, 15), + 2095: (FEB, 5), + 2096: (JAN, 25), + 2097: (FEB, 12), + 2098: (FEB, 1), + 2099: (JAN, 21), + 2100: (FEB, 9), + } + + MID_AUTUMN_DATES = { + 1901: (SEP, 27), + 1902: (SEP, 16), + 1903: (OCT, 5), + 1904: (SEP, 24), + 1905: (SEP, 13), + 1906: (OCT, 2), + 1907: (SEP, 22), + 1908: (SEP, 10), + 1909: (SEP, 28), + 1910: (SEP, 18), + 1911: (OCT, 6), + 1912: (SEP, 25), + 1913: (SEP, 15), + 1914: (OCT, 4), + 1915: (SEP, 23), + 1916: (SEP, 12), + 1917: (SEP, 30), + 1918: (SEP, 19), + 1919: (OCT, 8), + 1920: (SEP, 26), + 1921: (SEP, 16), + 1922: (OCT, 5), + 1923: (SEP, 25), + 1924: (SEP, 13), + 1925: (OCT, 2), + 1926: (SEP, 21), + 1927: (SEP, 10), + 1928: (SEP, 28), + 1929: (SEP, 17), + 1930: (OCT, 6), + 1931: (SEP, 26), + 1932: (SEP, 15), + 1933: (OCT, 4), + 1934: (SEP, 23), + 1935: (SEP, 12), + 1936: (SEP, 30), + 1937: (SEP, 19), + 1938: (OCT, 8), + 1939: (SEP, 27), + 1940: (SEP, 16), + 1941: (OCT, 5), + 1942: (SEP, 24), + 1943: (SEP, 14), + 1944: (OCT, 1), + 1945: (SEP, 20), + 1946: (SEP, 10), + 1947: (SEP, 29), + 1948: (SEP, 17), + 1949: (OCT, 6), + 1950: (SEP, 26), + 1951: (SEP, 15), + 1952: (OCT, 3), + 1953: (SEP, 22), + 1954: (SEP, 11), + 1955: (SEP, 30), + 1956: (SEP, 19), + 1957: (SEP, 8), + 1958: (SEP, 27), + 1959: (SEP, 17), + 1960: (OCT, 5), + 1961: (SEP, 24), + 1962: (SEP, 13), + 1963: (OCT, 2), + 1964: (SEP, 20), + 1965: (SEP, 10), + 1966: (SEP, 29), + 1967: (SEP, 18), + 1968: (OCT, 6), + 1969: (SEP, 26), + 1970: (SEP, 15), + 1971: (OCT, 3), + 1972: (SEP, 22), + 1973: (SEP, 11), + 1974: (SEP, 30), + 1975: (SEP, 20), + 1976: (SEP, 8), + 1977: (SEP, 27), + 1978: (SEP, 17), + 1979: (OCT, 5), + 1980: (SEP, 23), + 1981: (SEP, 12), + 1982: (OCT, 1), + 1983: (SEP, 21), + 1984: (SEP, 10), + 1985: (SEP, 29), + 1986: (SEP, 18), + 1987: (OCT, 7), + 1988: (SEP, 25), + 1989: (SEP, 14), + 1990: (OCT, 3), + 1991: (SEP, 22), + 1992: (SEP, 11), + 1993: (SEP, 30), + 1994: (SEP, 20), + 1995: (SEP, 9), + 1996: (SEP, 27), + 1997: (SEP, 16), + 1998: (OCT, 5), + 1999: (SEP, 24), + 2000: (SEP, 12), + 2001: (OCT, 1), + 2002: (SEP, 21), + 2003: (SEP, 11), + 2004: (SEP, 28), + 2005: (SEP, 18), + 2006: (OCT, 6), + 2007: (SEP, 25), + 2008: (SEP, 14), + 2009: (OCT, 3), + 2010: (SEP, 22), + 2011: (SEP, 12), + 2012: (SEP, 30), + 2013: (SEP, 19), + 2014: (SEP, 8), + 2015: (SEP, 27), + 2016: (SEP, 15), + 2017: (OCT, 4), + 2018: (SEP, 24), + 2019: (SEP, 13), + 2020: (OCT, 1), + 2021: (SEP, 21), + 2022: (SEP, 10), + 2023: (SEP, 29), + 2024: (SEP, 17), + 2025: (OCT, 6), + 2026: (SEP, 25), + 2027: (SEP, 15), + 2028: (OCT, 3), + 2029: (SEP, 22), + 2030: (SEP, 12), + 2031: (OCT, 1), + 2032: (SEP, 19), + 2033: (SEP, 8), + 2034: (SEP, 27), + 2035: (SEP, 16), + 2036: (OCT, 4), + 2037: (SEP, 24), + 2038: (SEP, 13), + 2039: (OCT, 2), + 2040: (SEP, 20), + 2041: (SEP, 10), + 2042: (SEP, 28), + 2043: (SEP, 17), + 2044: (OCT, 5), + 2045: (SEP, 25), + 2046: (SEP, 15), + 2047: (OCT, 4), + 2048: (SEP, 22), + 2049: (SEP, 11), + 2050: (SEP, 30), + 2051: (SEP, 19), + 2052: (SEP, 7), + 2053: (SEP, 26), + 2054: (SEP, 16), + 2055: (OCT, 5), + 2056: (SEP, 24), + 2057: (SEP, 13), + 2058: (OCT, 2), + 2059: (SEP, 21), + 2060: (SEP, 9), + 2061: (SEP, 28), + 2062: (SEP, 17), + 2063: (OCT, 6), + 2064: (SEP, 25), + 2065: (SEP, 15), + 2066: (OCT, 3), + 2067: (SEP, 23), + 2068: (SEP, 11), + 2069: (SEP, 29), + 2070: (SEP, 19), + 2071: (SEP, 8), + 2072: (SEP, 26), + 2073: (SEP, 16), + 2074: (OCT, 5), + 2075: (SEP, 24), + 2076: (SEP, 12), + 2077: (OCT, 1), + 2078: (SEP, 20), + 2079: (SEP, 10), + 2080: (SEP, 28), + 2081: (SEP, 17), + 2082: (OCT, 6), + 2083: (SEP, 26), + 2084: (SEP, 14), + 2085: (OCT, 3), + 2086: (SEP, 22), + 2087: (SEP, 11), + 2088: (SEP, 29), + 2089: (SEP, 18), + 2090: (SEP, 8), + 2091: (SEP, 27), + 2092: (SEP, 16), + 2093: (OCT, 5), + 2094: (SEP, 24), + 2095: (SEP, 13), + 2096: (SEP, 30), + 2097: (SEP, 20), + 2098: (SEP, 9), + 2099: (SEP, 29), + 2100: (SEP, 18), + } + + KOREAN_CALENDAR_BUDDHA_BIRTHDAY_DATES = { + 1905: (MAY, 12), + 1908: (MAY, 8), + 1931: (MAY, 25), + 1968: (MAY, 5), + 2001: (MAY, 1), + 2012: (MAY, 28), + 2023: (MAY, 27), + } + + KOREAN_CALENDAR_LUNAR_NEW_YEAR_DATES = { + 1944: (JAN, 26), + 1954: (FEB, 4), + 1958: (FEB, 19), + 1966: (JAN, 22), + 1988: (FEB, 18), + 1997: (FEB, 8), + 2027: (FEB, 7), + 2028: (JAN, 27), + 2061: (JAN, 22), + 2089: (FEB, 11), + 2092: (FEB, 8), + } + + KOREAN_CALENDAR_MID_AUTUMN_DATES = { + 1909: (SEP, 29), + 1942: (SEP, 25), + 2040: (SEP, 21), + 2089: (SEP, 19), + 2096: (OCT, 1), + 2098: (SEP, 10), + } + + VIETNAMESE_CALENDAR_HUNG_KINGS_DATES = { + 1916: (APR, 11), + 1917: (APR, 1), + 1939: (APR, 28), + 1975: (APR, 20), + 2009: (APR, 4), + 2037: (APR, 24), + 2038: (APR, 13), + 2085: (APR, 3), + 2086: (APR, 22), + 2095: (APR, 13), + 2100: (APR, 18), + } + + VIETNAMESE_CALENDAR_LUNAR_NEW_YEAR_DATES = { + 1903: (JAN, 28), + 1916: (FEB, 3), + 1935: (FEB, 3), + 1965: (FEB, 1), + 1968: (JAN, 29), + 1969: (FEB, 16), + 1985: (JAN, 21), + 2007: (FEB, 17), + 2030: (FEB, 2), + 2053: (FEB, 18), + } + + def __init__(self, calendar: str = CHINESE_CALENDAR) -> None: + self.__verify_calendar(calendar) + self.__calendar = calendar + + @staticmethod + def __verify_calendar(calendar): + """Verify calendar type.""" + + supported_calendars = {CHINESE_CALENDAR, KOREAN_CALENDAR, VIETNAMESE_CALENDAR} + if calendar not in supported_calendars: + raise ValueError( + f"Unknown calendar name: {calendar}. " + f"Supported calendars: {', '.join(sorted(supported_calendars))}" + ) + + def _get_holiday(self, holiday: str, year: int, calendar=None) -> tuple[Optional[date], bool]: + calendar = calendar or self.__calendar + self.__verify_calendar(calendar) + custom_calendar_dates = getattr(self, f"{calendar}_{holiday}_DATES", {}) + estimated_dates = getattr(self, f"{holiday}_DATES", {}) + exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}) + dt = exact_dates.get(year, custom_calendar_dates.get(year, estimated_dates.get(year, ()))) + return date(year, *dt) if dt else None, year not in exact_dates + + def buddha_birthday_date(self, year: int, calendar=None) -> tuple[Optional[date], bool]: + return self._get_holiday(BUDDHA_BIRTHDAY, year, calendar) + + def double_ninth_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(DOUBLE_NINTH, year) + + def dragon_boat_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(DRAGON_BOAT, year) + + def hung_kings_date(self, year: int, calendar=None) -> tuple[Optional[date], bool]: + return self._get_holiday(HUNG_KINGS, year, calendar) + + def lunar_new_year_date(self, year: int, calendar=None) -> tuple[Optional[date], bool]: + return self._get_holiday(LUNAR_NEW_YEAR, year, calendar) + + def mid_autumn_date(self, year: int, calendar=None) -> tuple[Optional[date], bool]: + return self._get_holiday(MID_AUTUMN, year, calendar) + + +class _CustomChineseHolidays(_CustomCalendar, _ChineseLunisolar): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/custom.py b/.venv/lib/python3.12/site-packages/holidays/calendars/custom.py new file mode 100644 index 00000000..004d874e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/custom.py @@ -0,0 +1,34 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + + +class _CustomCalendarType(type): + """Helper class for simple calendar customization. + + Renames child class public attributes keeping the original data under a new + name with a `CUSTOM_ATTR_POSTFIX` postfix. + + Allows for better readability of customized lunisolar calendar dates. + """ + + CUSTOM_ATTR_POSTFIX = "CUSTOM_CALENDAR" + + def __new__(cls, name, bases, namespace): + for attr in (key for key in tuple(namespace.keys()) if key[0] != "_"): + namespace[f"{attr}_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}"] = namespace[attr] + del namespace[attr] + + return super().__new__(cls, name, bases, namespace) + + +class _CustomCalendar(metaclass=_CustomCalendarType): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/gregorian.py b/.venv/lib/python3.12/site-packages/holidays/calendars/gregorian.py new file mode 100644 index 00000000..424dd8fc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/gregorian.py @@ -0,0 +1,95 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date + +GREGORIAN_CALENDAR = "GREGORIAN_CALENDAR" + +MON, TUE, WED, THU, FRI, SAT, SUN = range(7) +WEEKEND = (SAT, SUN) + +JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC = range(1, 13) + +DAYS = {str(d) for d in range(1, 32)} +MONTHS = { + m: i + for i, m in enumerate( + ("jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"), 1 + ) +} +WEEKDAYS = {w: i for i, w in enumerate(("mon", "tue", "wed", "thu", "fri", "sat", "sun"))} + + +# Holiday names. +CHRISTMAS = "christmas" +WINTER_SOLSTICE = "winter_solstice" + + +def _timedelta(dt: date, days: int = 0) -> date: + """ + Return date that is `days` days after (days > 0) or before (days < 0) specified date. + """ + + return date.fromordinal(dt.toordinal() + days) + + +def _get_nth_weekday_from(n: int, weekday: int, from_dt: date) -> date: + """ + Return date of a n-th weekday before a specific date + if n is negative. + Return date of n-th weekday after (including) a specific date + if n is positive. + Examples: 1st Monday, 2nd Saturday, etc). + """ + + return _timedelta( + from_dt, + ( + (n - 1) * 7 + (weekday - from_dt.weekday()) % 7 + if n > 0 + else (n + 1) * 7 - (from_dt.weekday() - weekday) % 7 + ), + ) + + +def _get_nth_weekday_of_month(n: int, weekday: int, month: int, year: int) -> date: + """ + Return date of n-th weekday of month for a specific year + (e.g. 1st Monday of Apr, 2nd Friday of June, etc). + If n is negative the countdown starts at the end of month + (i.e. -1 is last). + """ + + requested_year_month = (year, month) + + if n < 0: + month += 1 + if month > 12: + month = 1 + year += 1 + start_date = _timedelta(date(year, month, 1), -1) + else: + start_date = date(year, month, 1) + + dt = _get_nth_weekday_from(n, weekday, start_date) + dt_year_month = (dt.year, dt.month) + + if dt_year_month != requested_year_month: + raise ValueError(f"{dt_year_month} returned for {requested_year_month}") + + return dt + + +def _get_all_sundays(year): + first_sunday = _get_nth_weekday_of_month(1, SUN, JAN, year) + for n in range(0, (date(year, DEC, 31) - first_sunday).days + 1, 7): + yield _timedelta(first_sunday, n) diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/hebrew.py b/.venv/lib/python3.12/site-packages/holidays/calendars/hebrew.py new file mode 100644 index 00000000..05c9b5f5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/hebrew.py @@ -0,0 +1,1633 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC + +HANUKKAH = "HANUKKAH" +INDEPENDENCE_DAY = "INDEPENDENCE_DAY" +LAG_BAOMER = "LAG_BAOMER" +PASSOVER = "PASSOVER" +PURIM = "PURIM" +ROSH_HASHANAH = "ROSH_HASHANAH" +SHAVUOT = "SHAVUOT" +SUKKOT = "SUKKOT" +TISHA_BAV = "TISHA_BAV" +YOM_KIPPUR = "YOM_KIPPUR" + + +class _HebrewLunisolar: + HANUKKAH_DATES = { + 1947: (DEC, 8), + 1948: (DEC, 27), + 1949: (DEC, 16), + 1950: (DEC, 4), + 1951: (DEC, 24), + 1952: (DEC, 13), + 1953: (DEC, 2), + 1954: (DEC, 20), + 1955: (DEC, 10), + 1956: (NOV, 29), + 1957: (DEC, 18), + 1958: (DEC, 7), + 1959: (DEC, 26), + 1960: (DEC, 14), + 1961: (DEC, 3), + 1962: (DEC, 22), + 1963: (DEC, 11), + 1964: (NOV, 30), + 1965: (DEC, 19), + 1966: (DEC, 8), + 1967: (DEC, 27), + 1968: (DEC, 16), + 1969: (DEC, 5), + 1970: (DEC, 23), + 1971: (DEC, 13), + 1972: (DEC, 1), + 1973: (DEC, 20), + 1974: (DEC, 9), + 1975: (NOV, 29), + 1976: (DEC, 17), + 1977: (DEC, 5), + 1978: (DEC, 25), + 1979: (DEC, 15), + 1980: (DEC, 3), + 1981: (DEC, 21), + 1982: (DEC, 11), + 1983: (DEC, 1), + 1984: (DEC, 19), + 1985: (DEC, 8), + 1986: (DEC, 27), + 1987: (DEC, 16), + 1988: (DEC, 4), + 1989: (DEC, 23), + 1990: (DEC, 12), + 1991: (DEC, 2), + 1992: (DEC, 20), + 1993: (DEC, 9), + 1994: (NOV, 28), + 1995: (DEC, 18), + 1996: (DEC, 6), + 1997: (DEC, 24), + 1998: (DEC, 14), + 1999: (DEC, 4), + 2000: (DEC, 22), + 2001: (DEC, 10), + 2002: (NOV, 30), + 2003: (DEC, 20), + 2004: (DEC, 8), + 2005: (DEC, 26), + 2006: (DEC, 16), + 2007: (DEC, 5), + 2008: (DEC, 22), + 2009: (DEC, 12), + 2010: (DEC, 2), + 2011: (DEC, 21), + 2012: (DEC, 9), + 2013: (NOV, 28), + 2014: (DEC, 17), + 2015: (DEC, 7), + 2016: (DEC, 25), + 2017: (DEC, 13), + 2018: (DEC, 3), + 2019: (DEC, 23), + 2020: (DEC, 11), + 2021: (NOV, 29), + 2022: (DEC, 19), + 2023: (DEC, 8), + 2024: (DEC, 26), + 2025: (DEC, 15), + 2026: (DEC, 5), + 2027: (DEC, 25), + 2028: (DEC, 13), + 2029: (DEC, 2), + 2030: (DEC, 21), + 2031: (DEC, 10), + 2032: (NOV, 28), + 2033: (DEC, 17), + 2034: (DEC, 7), + 2035: (DEC, 26), + 2036: (DEC, 14), + 2037: (DEC, 3), + 2038: (DEC, 22), + 2039: (DEC, 12), + 2040: (NOV, 30), + 2041: (DEC, 18), + 2042: (DEC, 8), + 2043: (DEC, 27), + 2044: (DEC, 15), + 2045: (DEC, 4), + 2046: (DEC, 24), + 2047: (DEC, 13), + 2048: (NOV, 30), + 2049: (DEC, 20), + 2050: (DEC, 10), + 2051: (NOV, 29), + 2052: (DEC, 16), + 2053: (DEC, 6), + 2054: (DEC, 26), + 2055: (DEC, 15), + 2056: (DEC, 3), + 2057: (DEC, 22), + 2058: (DEC, 11), + 2059: (NOV, 30), + 2060: (DEC, 18), + 2061: (DEC, 8), + 2062: (DEC, 27), + 2063: (DEC, 16), + 2064: (DEC, 4), + 2065: (DEC, 23), + 2066: (DEC, 13), + 2067: (DEC, 2), + 2068: (DEC, 19), + 2069: (DEC, 9), + 2070: (NOV, 28), + 2071: (DEC, 17), + 2072: (DEC, 5), + 2073: (DEC, 25), + 2074: (DEC, 14), + 2075: (DEC, 2), + 2076: (DEC, 21), + 2077: (DEC, 11), + 2078: (NOV, 30), + 2079: (DEC, 18), + 2080: (DEC, 7), + 2081: (DEC, 27), + 2082: (DEC, 16), + 2083: (DEC, 5), + 2084: (DEC, 23), + 2085: (DEC, 12), + 2086: (DEC, 1), + 2087: (DEC, 20), + 2088: (DEC, 8), + 2089: (NOV, 28), + 2090: (DEC, 17), + 2091: (DEC, 6), + 2092: (DEC, 24), + 2093: (DEC, 14), + 2094: (DEC, 3), + 2095: (DEC, 21), + 2096: (DEC, 10), + 2097: (NOV, 30), + 2098: (DEC, 19), + 2099: (DEC, 7), + 2100: (DEC, 27), + } + + INDEPENDENCE_DAY_DATES = { + 1947: (APR, 25), + 1948: (MAY, 14), + 1949: (MAY, 4), + 1950: (APR, 22), + 1951: (MAY, 11), + 1952: (APR, 30), + 1953: (APR, 20), + 1954: (MAY, 8), + 1955: (APR, 27), + 1956: (APR, 16), + 1957: (MAY, 6), + 1958: (APR, 25), + 1959: (MAY, 13), + 1960: (MAY, 2), + 1961: (APR, 21), + 1962: (MAY, 9), + 1963: (APR, 29), + 1964: (APR, 17), + 1965: (MAY, 7), + 1966: (APR, 25), + 1967: (MAY, 15), + 1968: (MAY, 3), + 1969: (APR, 23), + 1970: (MAY, 11), + 1971: (APR, 30), + 1972: (APR, 19), + 1973: (MAY, 7), + 1974: (APR, 27), + 1975: (APR, 16), + 1976: (MAY, 5), + 1977: (APR, 23), + 1978: (MAY, 12), + 1979: (MAY, 2), + 1980: (APR, 21), + 1981: (MAY, 9), + 1982: (APR, 28), + 1983: (APR, 18), + 1984: (MAY, 7), + 1985: (APR, 26), + 1986: (MAY, 14), + 1987: (MAY, 4), + 1988: (APR, 22), + 1989: (MAY, 10), + 1990: (APR, 30), + 1991: (APR, 19), + 1992: (MAY, 8), + 1993: (APR, 26), + 1994: (APR, 16), + 1995: (MAY, 5), + 1996: (APR, 24), + 1997: (MAY, 12), + 1998: (MAY, 1), + 1999: (APR, 21), + 2000: (MAY, 10), + 2001: (APR, 28), + 2002: (APR, 17), + 2003: (MAY, 7), + 2004: (APR, 26), + 2005: (MAY, 14), + 2006: (MAY, 3), + 2007: (APR, 23), + 2008: (MAY, 10), + 2009: (APR, 29), + 2010: (APR, 19), + 2011: (MAY, 9), + 2012: (APR, 27), + 2013: (APR, 15), + 2014: (MAY, 5), + 2015: (APR, 24), + 2016: (MAY, 13), + 2017: (MAY, 1), + 2018: (APR, 20), + 2019: (MAY, 10), + 2020: (APR, 29), + 2021: (APR, 17), + 2022: (MAY, 6), + 2023: (APR, 26), + 2024: (MAY, 13), + 2025: (MAY, 3), + 2026: (APR, 22), + 2027: (MAY, 12), + 2028: (MAY, 1), + 2029: (APR, 20), + 2030: (MAY, 8), + 2031: (APR, 28), + 2032: (APR, 16), + 2033: (MAY, 4), + 2034: (APR, 24), + 2035: (MAY, 14), + 2036: (MAY, 2), + 2037: (APR, 20), + 2038: (MAY, 10), + 2039: (APR, 29), + 2040: (APR, 18), + 2041: (MAY, 6), + 2042: (APR, 25), + 2043: (MAY, 15), + 2044: (MAY, 2), + 2045: (APR, 22), + 2046: (MAY, 11), + 2047: (MAY, 1), + 2048: (APR, 18), + 2049: (MAY, 7), + 2050: (APR, 27), + 2051: (APR, 17), + 2052: (MAY, 4), + 2053: (APR, 23), + 2054: (MAY, 13), + 2055: (MAY, 3), + 2056: (APR, 21), + 2057: (MAY, 9), + 2058: (APR, 29), + 2059: (APR, 18), + 2060: (MAY, 5), + 2061: (APR, 25), + 2062: (MAY, 15), + 2063: (MAY, 4), + 2064: (APR, 21), + 2065: (MAY, 11), + 2066: (APR, 30), + 2067: (APR, 20), + 2068: (MAY, 7), + 2069: (APR, 26), + 2070: (APR, 16), + 2071: (MAY, 4), + 2072: (APR, 23), + 2073: (MAY, 12), + 2074: (MAY, 2), + 2075: (APR, 20), + 2076: (MAY, 8), + 2077: (APR, 28), + 2078: (APR, 18), + 2079: (MAY, 6), + 2080: (APR, 24), + 2081: (MAY, 14), + 2082: (MAY, 4), + 2083: (APR, 23), + 2084: (MAY, 10), + 2085: (APR, 30), + 2086: (APR, 19), + 2087: (MAY, 7), + 2088: (APR, 26), + 2089: (APR, 15), + 2090: (MAY, 5), + 2091: (APR, 23), + 2092: (MAY, 12), + 2093: (MAY, 1), + 2094: (APR, 21), + 2095: (MAY, 9), + 2096: (APR, 27), + 2097: (APR, 17), + 2098: (MAY, 7), + 2099: (APR, 25), + 2100: (MAY, 14), + } + + LAG_BAOMER_DATES = { + 1947: (MAY, 8), + 1948: (MAY, 27), + 1949: (MAY, 17), + 1950: (MAY, 5), + 1951: (MAY, 24), + 1952: (MAY, 13), + 1953: (MAY, 3), + 1954: (MAY, 21), + 1955: (MAY, 10), + 1956: (APR, 29), + 1957: (MAY, 19), + 1958: (MAY, 8), + 1959: (MAY, 26), + 1960: (MAY, 15), + 1961: (MAY, 4), + 1962: (MAY, 22), + 1963: (MAY, 12), + 1964: (APR, 30), + 1965: (MAY, 20), + 1966: (MAY, 8), + 1967: (MAY, 28), + 1968: (MAY, 16), + 1969: (MAY, 6), + 1970: (MAY, 24), + 1971: (MAY, 13), + 1972: (MAY, 2), + 1973: (MAY, 20), + 1974: (MAY, 10), + 1975: (APR, 29), + 1976: (MAY, 18), + 1977: (MAY, 6), + 1978: (MAY, 25), + 1979: (MAY, 15), + 1980: (MAY, 4), + 1981: (MAY, 22), + 1982: (MAY, 11), + 1983: (MAY, 1), + 1984: (MAY, 20), + 1985: (MAY, 9), + 1986: (MAY, 27), + 1987: (MAY, 17), + 1988: (MAY, 5), + 1989: (MAY, 23), + 1990: (MAY, 13), + 1991: (MAY, 2), + 1992: (MAY, 21), + 1993: (MAY, 9), + 1994: (APR, 29), + 1995: (MAY, 18), + 1996: (MAY, 7), + 1997: (MAY, 25), + 1998: (MAY, 14), + 1999: (MAY, 4), + 2000: (MAY, 23), + 2001: (MAY, 11), + 2002: (APR, 30), + 2003: (MAY, 20), + 2004: (MAY, 9), + 2005: (MAY, 27), + 2006: (MAY, 16), + 2007: (MAY, 6), + 2008: (MAY, 23), + 2009: (MAY, 12), + 2010: (MAY, 2), + 2011: (MAY, 22), + 2012: (MAY, 10), + 2013: (APR, 28), + 2014: (MAY, 18), + 2015: (MAY, 7), + 2016: (MAY, 26), + 2017: (MAY, 14), + 2018: (MAY, 3), + 2019: (MAY, 23), + 2020: (MAY, 12), + 2021: (APR, 30), + 2022: (MAY, 19), + 2023: (MAY, 9), + 2024: (MAY, 26), + 2025: (MAY, 16), + 2026: (MAY, 5), + 2027: (MAY, 25), + 2028: (MAY, 14), + 2029: (MAY, 3), + 2030: (MAY, 21), + 2031: (MAY, 11), + 2032: (APR, 29), + 2033: (MAY, 17), + 2034: (MAY, 7), + 2035: (MAY, 27), + 2036: (MAY, 15), + 2037: (MAY, 3), + 2038: (MAY, 23), + 2039: (MAY, 12), + 2040: (MAY, 1), + 2041: (MAY, 19), + 2042: (MAY, 8), + 2043: (MAY, 28), + 2044: (MAY, 15), + 2045: (MAY, 5), + 2046: (MAY, 24), + 2047: (MAY, 14), + 2048: (MAY, 1), + 2049: (MAY, 20), + 2050: (MAY, 10), + 2051: (APR, 30), + 2052: (MAY, 17), + 2053: (MAY, 6), + 2054: (MAY, 26), + 2055: (MAY, 16), + 2056: (MAY, 4), + 2057: (MAY, 22), + 2058: (MAY, 12), + 2059: (MAY, 1), + 2060: (MAY, 18), + 2061: (MAY, 8), + 2062: (MAY, 28), + 2063: (MAY, 17), + 2064: (MAY, 4), + 2065: (MAY, 24), + 2066: (MAY, 13), + 2067: (MAY, 3), + 2068: (MAY, 20), + 2069: (MAY, 9), + 2070: (APR, 29), + 2071: (MAY, 17), + 2072: (MAY, 6), + 2073: (MAY, 25), + 2074: (MAY, 15), + 2075: (MAY, 3), + 2076: (MAY, 21), + 2077: (MAY, 11), + 2078: (MAY, 1), + 2079: (MAY, 19), + 2080: (MAY, 7), + 2081: (MAY, 27), + 2082: (MAY, 17), + 2083: (MAY, 6), + 2084: (MAY, 23), + 2085: (MAY, 13), + 2086: (MAY, 2), + 2087: (MAY, 20), + 2088: (MAY, 9), + 2089: (APR, 28), + 2090: (MAY, 18), + 2091: (MAY, 6), + 2092: (MAY, 25), + 2093: (MAY, 14), + 2094: (MAY, 4), + 2095: (MAY, 22), + 2096: (MAY, 10), + 2097: (APR, 30), + 2098: (MAY, 20), + 2099: (MAY, 8), + 2100: (MAY, 27), + } + + PASSOVER_DATES = { + 1947: (APR, 5), + 1948: (APR, 24), + 1949: (APR, 14), + 1950: (APR, 2), + 1951: (APR, 21), + 1952: (APR, 10), + 1953: (MAR, 31), + 1954: (APR, 18), + 1955: (APR, 7), + 1956: (MAR, 27), + 1957: (APR, 16), + 1958: (APR, 5), + 1959: (APR, 23), + 1960: (APR, 12), + 1961: (APR, 1), + 1962: (APR, 19), + 1963: (APR, 9), + 1964: (MAR, 28), + 1965: (APR, 17), + 1966: (APR, 5), + 1967: (APR, 25), + 1968: (APR, 13), + 1969: (APR, 3), + 1970: (APR, 21), + 1971: (APR, 10), + 1972: (MAR, 30), + 1973: (APR, 17), + 1974: (APR, 7), + 1975: (MAR, 27), + 1976: (APR, 15), + 1977: (APR, 3), + 1978: (APR, 22), + 1979: (APR, 12), + 1980: (APR, 1), + 1981: (APR, 19), + 1982: (APR, 8), + 1983: (MAR, 29), + 1984: (APR, 17), + 1985: (APR, 6), + 1986: (APR, 24), + 1987: (APR, 14), + 1988: (APR, 2), + 1989: (APR, 20), + 1990: (APR, 10), + 1991: (MAR, 30), + 1992: (APR, 18), + 1993: (APR, 6), + 1994: (MAR, 27), + 1995: (APR, 15), + 1996: (APR, 4), + 1997: (APR, 22), + 1998: (APR, 11), + 1999: (APR, 1), + 2000: (APR, 20), + 2001: (APR, 8), + 2002: (MAR, 28), + 2003: (APR, 17), + 2004: (APR, 6), + 2005: (APR, 24), + 2006: (APR, 13), + 2007: (APR, 3), + 2008: (APR, 20), + 2009: (APR, 9), + 2010: (MAR, 30), + 2011: (APR, 19), + 2012: (APR, 7), + 2013: (MAR, 26), + 2014: (APR, 15), + 2015: (APR, 4), + 2016: (APR, 23), + 2017: (APR, 11), + 2018: (MAR, 31), + 2019: (APR, 20), + 2020: (APR, 9), + 2021: (MAR, 28), + 2022: (APR, 16), + 2023: (APR, 6), + 2024: (APR, 23), + 2025: (APR, 13), + 2026: (APR, 2), + 2027: (APR, 22), + 2028: (APR, 11), + 2029: (MAR, 31), + 2030: (APR, 18), + 2031: (APR, 8), + 2032: (MAR, 27), + 2033: (APR, 14), + 2034: (APR, 4), + 2035: (APR, 24), + 2036: (APR, 12), + 2037: (MAR, 31), + 2038: (APR, 20), + 2039: (APR, 9), + 2040: (MAR, 29), + 2041: (APR, 16), + 2042: (APR, 5), + 2043: (APR, 25), + 2044: (APR, 12), + 2045: (APR, 2), + 2046: (APR, 21), + 2047: (APR, 11), + 2048: (MAR, 29), + 2049: (APR, 17), + 2050: (APR, 7), + 2051: (MAR, 28), + 2052: (APR, 14), + 2053: (APR, 3), + 2054: (APR, 23), + 2055: (APR, 13), + 2056: (APR, 1), + 2057: (APR, 19), + 2058: (APR, 9), + 2059: (MAR, 29), + 2060: (APR, 15), + 2061: (APR, 5), + 2062: (APR, 25), + 2063: (APR, 14), + 2064: (APR, 1), + 2065: (APR, 21), + 2066: (APR, 10), + 2067: (MAR, 31), + 2068: (APR, 17), + 2069: (APR, 6), + 2070: (MAR, 27), + 2071: (APR, 14), + 2072: (APR, 3), + 2073: (APR, 22), + 2074: (APR, 12), + 2075: (MAR, 31), + 2076: (APR, 18), + 2077: (APR, 8), + 2078: (MAR, 29), + 2079: (APR, 16), + 2080: (APR, 4), + 2081: (APR, 24), + 2082: (APR, 14), + 2083: (APR, 3), + 2084: (APR, 20), + 2085: (APR, 10), + 2086: (MAR, 30), + 2087: (APR, 17), + 2088: (APR, 6), + 2089: (MAR, 26), + 2090: (APR, 15), + 2091: (APR, 3), + 2092: (APR, 22), + 2093: (APR, 11), + 2094: (APR, 1), + 2095: (APR, 19), + 2096: (APR, 7), + 2097: (MAR, 28), + 2098: (APR, 17), + 2099: (APR, 5), + 2100: (APR, 24), + } + + PURIM_DATES = { + 1947: (MAR, 6), + 1948: (MAR, 25), + 1949: (MAR, 15), + 1950: (MAR, 3), + 1951: (MAR, 22), + 1952: (MAR, 11), + 1953: (MAR, 1), + 1954: (MAR, 19), + 1955: (MAR, 8), + 1956: (FEB, 26), + 1957: (MAR, 17), + 1958: (MAR, 6), + 1959: (MAR, 24), + 1960: (MAR, 13), + 1961: (MAR, 2), + 1962: (MAR, 20), + 1963: (MAR, 10), + 1964: (FEB, 27), + 1965: (MAR, 18), + 1966: (MAR, 6), + 1967: (MAR, 26), + 1968: (MAR, 14), + 1969: (MAR, 4), + 1970: (MAR, 22), + 1971: (MAR, 11), + 1972: (FEB, 29), + 1973: (MAR, 18), + 1974: (MAR, 8), + 1975: (FEB, 25), + 1976: (MAR, 16), + 1977: (MAR, 4), + 1978: (MAR, 23), + 1979: (MAR, 13), + 1980: (MAR, 2), + 1981: (MAR, 20), + 1982: (MAR, 9), + 1983: (FEB, 27), + 1984: (MAR, 18), + 1985: (MAR, 7), + 1986: (MAR, 25), + 1987: (MAR, 15), + 1988: (MAR, 3), + 1989: (MAR, 21), + 1990: (MAR, 11), + 1991: (FEB, 28), + 1992: (MAR, 19), + 1993: (MAR, 7), + 1994: (FEB, 25), + 1995: (MAR, 16), + 1996: (MAR, 5), + 1997: (MAR, 23), + 1998: (MAR, 12), + 1999: (MAR, 2), + 2000: (MAR, 21), + 2001: (MAR, 9), + 2002: (FEB, 26), + 2003: (MAR, 18), + 2004: (MAR, 7), + 2005: (MAR, 25), + 2006: (MAR, 14), + 2007: (MAR, 4), + 2008: (MAR, 21), + 2009: (MAR, 10), + 2010: (FEB, 28), + 2011: (MAR, 20), + 2012: (MAR, 8), + 2013: (FEB, 24), + 2014: (MAR, 16), + 2015: (MAR, 5), + 2016: (MAR, 24), + 2017: (MAR, 12), + 2018: (MAR, 1), + 2019: (MAR, 21), + 2020: (MAR, 10), + 2021: (FEB, 26), + 2022: (MAR, 17), + 2023: (MAR, 7), + 2024: (MAR, 24), + 2025: (MAR, 14), + 2026: (MAR, 3), + 2027: (MAR, 23), + 2028: (MAR, 12), + 2029: (MAR, 1), + 2030: (MAR, 19), + 2031: (MAR, 9), + 2032: (FEB, 26), + 2033: (MAR, 15), + 2034: (MAR, 5), + 2035: (MAR, 25), + 2036: (MAR, 13), + 2037: (MAR, 1), + 2038: (MAR, 21), + 2039: (MAR, 10), + 2040: (FEB, 28), + 2041: (MAR, 17), + 2042: (MAR, 6), + 2043: (MAR, 26), + 2044: (MAR, 13), + 2045: (MAR, 3), + 2046: (MAR, 22), + 2047: (MAR, 12), + 2048: (FEB, 28), + 2049: (MAR, 18), + 2050: (MAR, 8), + 2051: (FEB, 26), + 2052: (MAR, 15), + 2053: (MAR, 4), + 2054: (MAR, 24), + 2055: (MAR, 14), + 2056: (MAR, 2), + 2057: (MAR, 20), + 2058: (MAR, 10), + 2059: (FEB, 27), + 2060: (MAR, 16), + 2061: (MAR, 6), + 2062: (MAR, 26), + 2063: (MAR, 15), + 2064: (MAR, 2), + 2065: (MAR, 22), + 2066: (MAR, 11), + 2067: (MAR, 1), + 2068: (MAR, 18), + 2069: (MAR, 7), + 2070: (FEB, 25), + 2071: (MAR, 15), + 2072: (MAR, 4), + 2073: (MAR, 23), + 2074: (MAR, 13), + 2075: (MAR, 1), + 2076: (MAR, 19), + 2077: (MAR, 9), + 2078: (FEB, 27), + 2079: (MAR, 17), + 2080: (MAR, 5), + 2081: (MAR, 25), + 2082: (MAR, 15), + 2083: (MAR, 4), + 2084: (MAR, 21), + 2085: (MAR, 11), + 2086: (FEB, 28), + 2087: (MAR, 18), + 2088: (MAR, 7), + 2089: (FEB, 24), + 2090: (MAR, 16), + 2091: (MAR, 4), + 2092: (MAR, 23), + 2093: (MAR, 12), + 2094: (MAR, 2), + 2095: (MAR, 20), + 2096: (MAR, 8), + 2097: (FEB, 26), + 2098: (MAR, 18), + 2099: (MAR, 6), + 2100: (MAR, 25), + } + + ROSH_HASHANAH_DATES = { + 1947: (SEP, 15), + 1948: (OCT, 4), + 1949: (SEP, 24), + 1950: (SEP, 12), + 1951: (OCT, 1), + 1952: (SEP, 20), + 1953: (SEP, 10), + 1954: (SEP, 28), + 1955: (SEP, 17), + 1956: (SEP, 6), + 1957: (SEP, 26), + 1958: (SEP, 15), + 1959: (OCT, 3), + 1960: (SEP, 22), + 1961: (SEP, 11), + 1962: (SEP, 29), + 1963: (SEP, 19), + 1964: (SEP, 7), + 1965: (SEP, 27), + 1966: (SEP, 15), + 1967: (OCT, 5), + 1968: (SEP, 23), + 1969: (SEP, 13), + 1970: (OCT, 1), + 1971: (SEP, 20), + 1972: (SEP, 9), + 1973: (SEP, 27), + 1974: (SEP, 17), + 1975: (SEP, 6), + 1976: (SEP, 25), + 1977: (SEP, 13), + 1978: (OCT, 2), + 1979: (SEP, 22), + 1980: (SEP, 11), + 1981: (SEP, 29), + 1982: (SEP, 18), + 1983: (SEP, 8), + 1984: (SEP, 27), + 1985: (SEP, 16), + 1986: (OCT, 4), + 1987: (SEP, 24), + 1988: (SEP, 12), + 1989: (SEP, 30), + 1990: (SEP, 20), + 1991: (SEP, 9), + 1992: (SEP, 28), + 1993: (SEP, 16), + 1994: (SEP, 6), + 1995: (SEP, 25), + 1996: (SEP, 14), + 1997: (OCT, 2), + 1998: (SEP, 21), + 1999: (SEP, 11), + 2000: (SEP, 30), + 2001: (SEP, 18), + 2002: (SEP, 7), + 2003: (SEP, 27), + 2004: (SEP, 16), + 2005: (OCT, 4), + 2006: (SEP, 23), + 2007: (SEP, 13), + 2008: (SEP, 30), + 2009: (SEP, 19), + 2010: (SEP, 9), + 2011: (SEP, 29), + 2012: (SEP, 17), + 2013: (SEP, 5), + 2014: (SEP, 25), + 2015: (SEP, 14), + 2016: (OCT, 3), + 2017: (SEP, 21), + 2018: (SEP, 10), + 2019: (SEP, 30), + 2020: (SEP, 19), + 2021: (SEP, 7), + 2022: (SEP, 26), + 2023: (SEP, 16), + 2024: (OCT, 3), + 2025: (SEP, 23), + 2026: (SEP, 12), + 2027: (OCT, 2), + 2028: (SEP, 21), + 2029: (SEP, 10), + 2030: (SEP, 28), + 2031: (SEP, 18), + 2032: (SEP, 6), + 2033: (SEP, 24), + 2034: (SEP, 14), + 2035: (OCT, 4), + 2036: (SEP, 22), + 2037: (SEP, 10), + 2038: (SEP, 30), + 2039: (SEP, 19), + 2040: (SEP, 8), + 2041: (SEP, 26), + 2042: (SEP, 15), + 2043: (OCT, 5), + 2044: (SEP, 22), + 2045: (SEP, 12), + 2046: (OCT, 1), + 2047: (SEP, 21), + 2048: (SEP, 8), + 2049: (SEP, 27), + 2050: (SEP, 17), + 2051: (SEP, 7), + 2052: (SEP, 24), + 2053: (SEP, 13), + 2054: (OCT, 3), + 2055: (SEP, 23), + 2056: (SEP, 11), + 2057: (SEP, 29), + 2058: (SEP, 19), + 2059: (SEP, 8), + 2060: (SEP, 25), + 2061: (SEP, 15), + 2062: (OCT, 5), + 2063: (SEP, 24), + 2064: (SEP, 11), + 2065: (OCT, 1), + 2066: (SEP, 20), + 2067: (SEP, 10), + 2068: (SEP, 27), + 2069: (SEP, 16), + 2070: (SEP, 6), + 2071: (SEP, 24), + 2072: (SEP, 13), + 2073: (OCT, 2), + 2074: (SEP, 22), + 2075: (SEP, 10), + 2076: (SEP, 28), + 2077: (SEP, 18), + 2078: (SEP, 8), + 2079: (SEP, 26), + 2080: (SEP, 14), + 2081: (OCT, 4), + 2082: (SEP, 24), + 2083: (SEP, 13), + 2084: (SEP, 30), + 2085: (SEP, 20), + 2086: (SEP, 9), + 2087: (SEP, 27), + 2088: (SEP, 16), + 2089: (SEP, 5), + 2090: (SEP, 25), + 2091: (SEP, 13), + 2092: (OCT, 2), + 2093: (SEP, 21), + 2094: (SEP, 11), + 2095: (SEP, 29), + 2096: (SEP, 17), + 2097: (SEP, 7), + 2098: (SEP, 27), + 2099: (SEP, 15), + 2100: (OCT, 4), + } + + SHAVUOT_DATES = { + 1947: (MAY, 25), + 1948: (JUN, 13), + 1949: (JUN, 3), + 1950: (MAY, 22), + 1951: (JUN, 10), + 1952: (MAY, 30), + 1953: (MAY, 20), + 1954: (JUN, 7), + 1955: (MAY, 27), + 1956: (MAY, 16), + 1957: (JUN, 5), + 1958: (MAY, 25), + 1959: (JUN, 12), + 1960: (JUN, 1), + 1961: (MAY, 21), + 1962: (JUN, 8), + 1963: (MAY, 29), + 1964: (MAY, 17), + 1965: (JUN, 6), + 1966: (MAY, 25), + 1967: (JUN, 14), + 1968: (JUN, 2), + 1969: (MAY, 23), + 1970: (JUN, 10), + 1971: (MAY, 30), + 1972: (MAY, 19), + 1973: (JUN, 6), + 1974: (MAY, 27), + 1975: (MAY, 16), + 1976: (JUN, 4), + 1977: (MAY, 23), + 1978: (JUN, 11), + 1979: (JUN, 1), + 1980: (MAY, 21), + 1981: (JUN, 8), + 1982: (MAY, 28), + 1983: (MAY, 18), + 1984: (JUN, 6), + 1985: (MAY, 26), + 1986: (JUN, 13), + 1987: (JUN, 3), + 1988: (MAY, 22), + 1989: (JUN, 9), + 1990: (MAY, 30), + 1991: (MAY, 19), + 1992: (JUN, 7), + 1993: (MAY, 26), + 1994: (MAY, 16), + 1995: (JUN, 4), + 1996: (MAY, 24), + 1997: (JUN, 11), + 1998: (MAY, 31), + 1999: (MAY, 21), + 2000: (JUN, 9), + 2001: (MAY, 28), + 2002: (MAY, 17), + 2003: (JUN, 6), + 2004: (MAY, 26), + 2005: (JUN, 13), + 2006: (JUN, 2), + 2007: (MAY, 23), + 2008: (JUN, 9), + 2009: (MAY, 29), + 2010: (MAY, 19), + 2011: (JUN, 8), + 2012: (MAY, 27), + 2013: (MAY, 15), + 2014: (JUN, 4), + 2015: (MAY, 24), + 2016: (JUN, 12), + 2017: (MAY, 31), + 2018: (MAY, 20), + 2019: (JUN, 9), + 2020: (MAY, 29), + 2021: (MAY, 17), + 2022: (JUN, 5), + 2023: (MAY, 26), + 2024: (JUN, 12), + 2025: (JUN, 2), + 2026: (MAY, 22), + 2027: (JUN, 11), + 2028: (MAY, 31), + 2029: (MAY, 20), + 2030: (JUN, 7), + 2031: (MAY, 28), + 2032: (MAY, 16), + 2033: (JUN, 3), + 2034: (MAY, 24), + 2035: (JUN, 13), + 2036: (JUN, 1), + 2037: (MAY, 20), + 2038: (JUN, 9), + 2039: (MAY, 29), + 2040: (MAY, 18), + 2041: (JUN, 5), + 2042: (MAY, 25), + 2043: (JUN, 14), + 2044: (JUN, 1), + 2045: (MAY, 22), + 2046: (JUN, 10), + 2047: (MAY, 31), + 2048: (MAY, 18), + 2049: (JUN, 6), + 2050: (MAY, 27), + 2051: (MAY, 17), + 2052: (JUN, 3), + 2053: (MAY, 23), + 2054: (JUN, 12), + 2055: (JUN, 2), + 2056: (MAY, 21), + 2057: (JUN, 8), + 2058: (MAY, 29), + 2059: (MAY, 18), + 2060: (JUN, 4), + 2061: (MAY, 25), + 2062: (JUN, 14), + 2063: (JUN, 3), + 2064: (MAY, 21), + 2065: (JUN, 10), + 2066: (MAY, 30), + 2067: (MAY, 20), + 2068: (JUN, 6), + 2069: (MAY, 26), + 2070: (MAY, 16), + 2071: (JUN, 3), + 2072: (MAY, 23), + 2073: (JUN, 11), + 2074: (JUN, 1), + 2075: (MAY, 20), + 2076: (JUN, 7), + 2077: (MAY, 28), + 2078: (MAY, 18), + 2079: (JUN, 5), + 2080: (MAY, 24), + 2081: (JUN, 13), + 2082: (JUN, 3), + 2083: (MAY, 23), + 2084: (JUN, 9), + 2085: (MAY, 30), + 2086: (MAY, 19), + 2087: (JUN, 6), + 2088: (MAY, 26), + 2089: (MAY, 15), + 2090: (JUN, 4), + 2091: (MAY, 23), + 2092: (JUN, 11), + 2093: (MAY, 31), + 2094: (MAY, 21), + 2095: (JUN, 8), + 2096: (MAY, 27), + 2097: (MAY, 17), + 2098: (JUN, 6), + 2099: (MAY, 25), + 2100: (JUN, 13), + } + + SUKKOT_DATES = { + 1947: (SEP, 29), + 1948: (OCT, 18), + 1949: (OCT, 8), + 1950: (SEP, 26), + 1951: (OCT, 15), + 1952: (OCT, 4), + 1953: (SEP, 24), + 1954: (OCT, 12), + 1955: (OCT, 1), + 1956: (SEP, 20), + 1957: (OCT, 10), + 1958: (SEP, 29), + 1959: (OCT, 17), + 1960: (OCT, 6), + 1961: (SEP, 25), + 1962: (OCT, 13), + 1963: (OCT, 3), + 1964: (SEP, 21), + 1965: (OCT, 11), + 1966: (SEP, 29), + 1967: (OCT, 19), + 1968: (OCT, 7), + 1969: (SEP, 27), + 1970: (OCT, 15), + 1971: (OCT, 4), + 1972: (SEP, 23), + 1973: (OCT, 11), + 1974: (OCT, 1), + 1975: (SEP, 20), + 1976: (OCT, 9), + 1977: (SEP, 27), + 1978: (OCT, 16), + 1979: (OCT, 6), + 1980: (SEP, 25), + 1981: (OCT, 13), + 1982: (OCT, 2), + 1983: (SEP, 22), + 1984: (OCT, 11), + 1985: (SEP, 30), + 1986: (OCT, 18), + 1987: (OCT, 8), + 1988: (SEP, 26), + 1989: (OCT, 14), + 1990: (OCT, 4), + 1991: (SEP, 23), + 1992: (OCT, 12), + 1993: (SEP, 30), + 1994: (SEP, 20), + 1995: (OCT, 9), + 1996: (SEP, 28), + 1997: (OCT, 16), + 1998: (OCT, 5), + 1999: (SEP, 25), + 2000: (OCT, 14), + 2001: (OCT, 2), + 2002: (SEP, 21), + 2003: (OCT, 11), + 2004: (SEP, 30), + 2005: (OCT, 18), + 2006: (OCT, 7), + 2007: (SEP, 27), + 2008: (OCT, 14), + 2009: (OCT, 3), + 2010: (SEP, 23), + 2011: (OCT, 13), + 2012: (OCT, 1), + 2013: (SEP, 19), + 2014: (OCT, 9), + 2015: (SEP, 28), + 2016: (OCT, 17), + 2017: (OCT, 5), + 2018: (SEP, 24), + 2019: (OCT, 14), + 2020: (OCT, 3), + 2021: (SEP, 21), + 2022: (OCT, 10), + 2023: (SEP, 30), + 2024: (OCT, 17), + 2025: (OCT, 7), + 2026: (SEP, 26), + 2027: (OCT, 16), + 2028: (OCT, 5), + 2029: (SEP, 24), + 2030: (OCT, 12), + 2031: (OCT, 2), + 2032: (SEP, 20), + 2033: (OCT, 8), + 2034: (SEP, 28), + 2035: (OCT, 18), + 2036: (OCT, 6), + 2037: (SEP, 24), + 2038: (OCT, 14), + 2039: (OCT, 3), + 2040: (SEP, 22), + 2041: (OCT, 10), + 2042: (SEP, 29), + 2043: (OCT, 19), + 2044: (OCT, 6), + 2045: (SEP, 26), + 2046: (OCT, 15), + 2047: (OCT, 5), + 2048: (SEP, 22), + 2049: (OCT, 11), + 2050: (OCT, 1), + 2051: (SEP, 21), + 2052: (OCT, 8), + 2053: (SEP, 27), + 2054: (OCT, 17), + 2055: (OCT, 7), + 2056: (SEP, 25), + 2057: (OCT, 13), + 2058: (OCT, 3), + 2059: (SEP, 22), + 2060: (OCT, 9), + 2061: (SEP, 29), + 2062: (OCT, 19), + 2063: (OCT, 8), + 2064: (SEP, 25), + 2065: (OCT, 15), + 2066: (OCT, 4), + 2067: (SEP, 24), + 2068: (OCT, 11), + 2069: (SEP, 30), + 2070: (SEP, 20), + 2071: (OCT, 8), + 2072: (SEP, 27), + 2073: (OCT, 16), + 2074: (OCT, 6), + 2075: (SEP, 24), + 2076: (OCT, 12), + 2077: (OCT, 2), + 2078: (SEP, 22), + 2079: (OCT, 10), + 2080: (SEP, 28), + 2081: (OCT, 18), + 2082: (OCT, 8), + 2083: (SEP, 27), + 2084: (OCT, 14), + 2085: (OCT, 4), + 2086: (SEP, 23), + 2087: (OCT, 11), + 2088: (SEP, 30), + 2089: (SEP, 19), + 2090: (OCT, 9), + 2091: (SEP, 27), + 2092: (OCT, 16), + 2093: (OCT, 5), + 2094: (SEP, 25), + 2095: (OCT, 13), + 2096: (OCT, 1), + 2097: (SEP, 21), + 2098: (OCT, 11), + 2099: (SEP, 29), + 2100: (OCT, 18), + } + + TISHA_BAV_DATES = { + 1947: (JUL, 26), + 1948: (AUG, 14), + 1949: (AUG, 4), + 1950: (JUL, 23), + 1951: (AUG, 11), + 1952: (JUL, 31), + 1953: (JUL, 21), + 1954: (AUG, 8), + 1955: (JUL, 28), + 1956: (JUL, 17), + 1957: (AUG, 6), + 1958: (JUL, 26), + 1959: (AUG, 13), + 1960: (AUG, 2), + 1961: (JUL, 22), + 1962: (AUG, 9), + 1963: (JUL, 30), + 1964: (JUL, 18), + 1965: (AUG, 7), + 1966: (JUL, 26), + 1967: (AUG, 15), + 1968: (AUG, 3), + 1969: (JUL, 24), + 1970: (AUG, 11), + 1971: (JUL, 31), + 1972: (JUL, 20), + 1973: (AUG, 7), + 1974: (JUL, 28), + 1975: (JUL, 17), + 1976: (AUG, 5), + 1977: (JUL, 24), + 1978: (AUG, 12), + 1979: (AUG, 2), + 1980: (JUL, 22), + 1981: (AUG, 9), + 1982: (JUL, 29), + 1983: (JUL, 19), + 1984: (AUG, 7), + 1985: (JUL, 27), + 1986: (AUG, 14), + 1987: (AUG, 4), + 1988: (JUL, 23), + 1989: (AUG, 10), + 1990: (JUL, 31), + 1991: (JUL, 20), + 1992: (AUG, 8), + 1993: (JUL, 27), + 1994: (JUL, 17), + 1995: (AUG, 5), + 1996: (JUL, 25), + 1997: (AUG, 12), + 1998: (AUG, 1), + 1999: (JUL, 22), + 2000: (AUG, 10), + 2001: (JUL, 29), + 2002: (JUL, 18), + 2003: (AUG, 7), + 2004: (JUL, 27), + 2005: (AUG, 14), + 2006: (AUG, 3), + 2007: (JUL, 24), + 2008: (AUG, 10), + 2009: (JUL, 30), + 2010: (JUL, 20), + 2011: (AUG, 9), + 2012: (JUL, 28), + 2013: (JUL, 16), + 2014: (AUG, 5), + 2015: (JUL, 25), + 2016: (AUG, 13), + 2017: (AUG, 1), + 2018: (JUL, 21), + 2019: (AUG, 10), + 2020: (JUL, 30), + 2021: (JUL, 18), + 2022: (AUG, 6), + 2023: (JUL, 27), + 2024: (AUG, 13), + 2025: (AUG, 3), + 2026: (JUL, 23), + 2027: (AUG, 12), + 2028: (AUG, 1), + 2029: (JUL, 21), + 2030: (AUG, 8), + 2031: (JUL, 29), + 2032: (JUL, 17), + 2033: (AUG, 4), + 2034: (JUL, 25), + 2035: (AUG, 14), + 2036: (AUG, 2), + 2037: (JUL, 21), + 2038: (AUG, 10), + 2039: (JUL, 30), + 2040: (JUL, 19), + 2041: (AUG, 6), + 2042: (JUL, 26), + 2043: (AUG, 15), + 2044: (AUG, 2), + 2045: (JUL, 23), + 2046: (AUG, 11), + 2047: (AUG, 1), + 2048: (JUL, 19), + 2049: (AUG, 7), + 2050: (JUL, 28), + 2051: (JUL, 18), + 2052: (AUG, 4), + 2053: (JUL, 24), + 2054: (AUG, 13), + 2055: (AUG, 3), + 2056: (JUL, 22), + 2057: (AUG, 9), + 2058: (JUL, 30), + 2059: (JUL, 19), + 2060: (AUG, 5), + 2061: (JUL, 26), + 2062: (AUG, 15), + 2063: (AUG, 4), + 2064: (JUL, 22), + 2065: (AUG, 11), + 2066: (JUL, 31), + 2067: (JUL, 21), + 2068: (AUG, 7), + 2069: (JUL, 27), + 2070: (JUL, 17), + 2071: (AUG, 4), + 2072: (JUL, 24), + 2073: (AUG, 12), + 2074: (AUG, 2), + 2075: (JUL, 21), + 2076: (AUG, 8), + 2077: (JUL, 29), + 2078: (JUL, 19), + 2079: (AUG, 6), + 2080: (JUL, 25), + 2081: (AUG, 14), + 2082: (AUG, 4), + 2083: (JUL, 24), + 2084: (AUG, 10), + 2085: (JUL, 31), + 2086: (JUL, 20), + 2087: (AUG, 7), + 2088: (JUL, 27), + 2089: (JUL, 16), + 2090: (AUG, 5), + 2091: (JUL, 24), + 2092: (AUG, 12), + 2093: (AUG, 1), + 2094: (JUL, 22), + 2095: (AUG, 9), + 2096: (JUL, 28), + 2097: (JUL, 18), + 2098: (AUG, 7), + 2099: (JUL, 26), + 2100: (AUG, 14), + } + + YOM_KIPPUR_DATES = { + 1947: (SEP, 24), + 1948: (OCT, 13), + 1949: (OCT, 3), + 1950: (SEP, 21), + 1951: (OCT, 10), + 1952: (SEP, 29), + 1953: (SEP, 19), + 1954: (OCT, 7), + 1955: (SEP, 26), + 1956: (SEP, 15), + 1957: (OCT, 5), + 1958: (SEP, 24), + 1959: (OCT, 12), + 1960: (OCT, 1), + 1961: (SEP, 20), + 1962: (OCT, 8), + 1963: (SEP, 28), + 1964: (SEP, 16), + 1965: (OCT, 6), + 1966: (SEP, 24), + 1967: (OCT, 14), + 1968: (OCT, 2), + 1969: (SEP, 22), + 1970: (OCT, 10), + 1971: (SEP, 29), + 1972: (SEP, 18), + 1973: (OCT, 6), + 1974: (SEP, 26), + 1975: (SEP, 15), + 1976: (OCT, 4), + 1977: (SEP, 22), + 1978: (OCT, 11), + 1979: (OCT, 1), + 1980: (SEP, 20), + 1981: (OCT, 8), + 1982: (SEP, 27), + 1983: (SEP, 17), + 1984: (OCT, 6), + 1985: (SEP, 25), + 1986: (OCT, 13), + 1987: (OCT, 3), + 1988: (SEP, 21), + 1989: (OCT, 9), + 1990: (SEP, 29), + 1991: (SEP, 18), + 1992: (OCT, 7), + 1993: (SEP, 25), + 1994: (SEP, 15), + 1995: (OCT, 4), + 1996: (SEP, 23), + 1997: (OCT, 11), + 1998: (SEP, 30), + 1999: (SEP, 20), + 2000: (OCT, 9), + 2001: (SEP, 27), + 2002: (SEP, 16), + 2003: (OCT, 6), + 2004: (SEP, 25), + 2005: (OCT, 13), + 2006: (OCT, 2), + 2007: (SEP, 22), + 2008: (OCT, 9), + 2009: (SEP, 28), + 2010: (SEP, 18), + 2011: (OCT, 8), + 2012: (SEP, 26), + 2013: (SEP, 14), + 2014: (OCT, 4), + 2015: (SEP, 23), + 2016: (OCT, 12), + 2017: (SEP, 30), + 2018: (SEP, 19), + 2019: (OCT, 9), + 2020: (SEP, 28), + 2021: (SEP, 16), + 2022: (OCT, 5), + 2023: (SEP, 25), + 2024: (OCT, 12), + 2025: (OCT, 2), + 2026: (SEP, 21), + 2027: (OCT, 11), + 2028: (SEP, 30), + 2029: (SEP, 19), + 2030: (OCT, 7), + 2031: (SEP, 27), + 2032: (SEP, 15), + 2033: (OCT, 3), + 2034: (SEP, 23), + 2035: (OCT, 13), + 2036: (OCT, 1), + 2037: (SEP, 19), + 2038: (OCT, 9), + 2039: (SEP, 28), + 2040: (SEP, 17), + 2041: (OCT, 5), + 2042: (SEP, 24), + 2043: (OCT, 14), + 2044: (OCT, 1), + 2045: (SEP, 21), + 2046: (OCT, 10), + 2047: (SEP, 30), + 2048: (SEP, 17), + 2049: (OCT, 6), + 2050: (SEP, 26), + 2051: (SEP, 16), + 2052: (OCT, 3), + 2053: (SEP, 22), + 2054: (OCT, 12), + 2055: (OCT, 2), + 2056: (SEP, 20), + 2057: (OCT, 8), + 2058: (SEP, 28), + 2059: (SEP, 17), + 2060: (OCT, 4), + 2061: (SEP, 24), + 2062: (OCT, 14), + 2063: (OCT, 3), + 2064: (SEP, 20), + 2065: (OCT, 10), + 2066: (SEP, 29), + 2067: (SEP, 19), + 2068: (OCT, 6), + 2069: (SEP, 25), + 2070: (SEP, 15), + 2071: (OCT, 3), + 2072: (SEP, 22), + 2073: (OCT, 11), + 2074: (OCT, 1), + 2075: (SEP, 19), + 2076: (OCT, 7), + 2077: (SEP, 27), + 2078: (SEP, 17), + 2079: (OCT, 5), + 2080: (SEP, 23), + 2081: (OCT, 13), + 2082: (OCT, 3), + 2083: (SEP, 22), + 2084: (OCT, 9), + 2085: (SEP, 29), + 2086: (SEP, 18), + 2087: (OCT, 6), + 2088: (SEP, 25), + 2089: (SEP, 14), + 2090: (OCT, 4), + 2091: (SEP, 22), + 2092: (OCT, 11), + 2093: (SEP, 30), + 2094: (SEP, 20), + 2095: (OCT, 8), + 2096: (SEP, 26), + 2097: (SEP, 16), + 2098: (OCT, 6), + 2099: (SEP, 24), + 2100: (OCT, 13), + } + + def _get_holiday(self, holiday: str, year: int) -> Optional[date]: + dt = getattr(self, f"{holiday}_DATES", {}).get(year, ()) + return date(year, *dt) if dt else None + + def hanukkah_date(self, year: int) -> set[Optional[date]]: + return {self._get_holiday(HANUKKAH, y) for y in (year - 1, year)} + + def israel_independence_date(self, year: int) -> Optional[date]: + return self._get_holiday(INDEPENDENCE_DAY, year) + + def lag_baomer_date(self, year: int) -> Optional[date]: + return self._get_holiday(LAG_BAOMER, year) + + def passover_date(self, year: int) -> Optional[date]: + return self._get_holiday(PASSOVER, year) + + def purim_date(self, year: int) -> Optional[date]: + return self._get_holiday(PURIM, year) + + def rosh_hashanah_date(self, year: int) -> Optional[date]: + return self._get_holiday(ROSH_HASHANAH, year) + + def shavuot_date(self, year: int) -> Optional[date]: + return self._get_holiday(SHAVUOT, year) + + def sukkot_date(self, year: int) -> Optional[date]: + return self._get_holiday(SUKKOT, year) + + def tisha_bav_date(self, year: int) -> Optional[date]: + return self._get_holiday(TISHA_BAV, year) + + def yom_kippur_date(self, year: int) -> Optional[date]: + return self._get_holiday(YOM_KIPPUR, year) diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/hindu.py b/.venv/lib/python3.12/site-packages/holidays/calendars/hindu.py new file mode 100644 index 00000000..58b2cb39 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/hindu.py @@ -0,0 +1,1494 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from collections.abc import Iterable +from datetime import date +from typing import Optional + +from holidays.calendars.custom import _CustomCalendar +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, AUG, SEP, OCT, NOV, DEC +from holidays.helpers import _normalize_tuple + +BUDDHA_PURNIMA = "BUDDHA_PURNIMA" +CHHATH_PUJA = "CHHATH_PUJA" +DIWALI = "DIWALI" +DIWALI_INDIA = "DIWALI_INDIA" +DUSSEHRA = "DUSSEHRA" +GANESH_CHATURTHI = "GANESH_CHATURTHI" +GOVARDHAN_PUJA = "GOVARDHAN_PUJA" +GUDI_PADWA = "GUDI_PADWA" +GURU_GOBIND_SINGH_JAYANTI = "GURU_GOBIND_SINGH_JAYANTI" +GURU_NANAK_JAYANTI = "GURU_NANAK_JAYANTI" +GYALPO_LOSAR = "GYALPO_LOSAR" +HOLI = "HOLI" +JANMASHTAMI = "JANMASHTAMI" +MAHA_ASHTAMI = "MAHA_ASHTAMI" +MAHA_NAVAMI = "MAHA_NAVAMI" +MAHA_SHIVARATRI = "MAHA_SHIVARATRI" +MAHAVIR_JAYANTI = "MAHAVIR_JAYANTI" +MAKAR_SANKRANTI = "MAKAR_SANKRANTI" +ONAM = "ONAM" +PONGAL = "PONGAL" +RAKSHA_BANDHAN = "RAKSHA_BANDHAN" +RAM_NAVAMI = "RAM_NAVAMI" +SHARAD_NAVRATRI = "SHARAD_NAVRATRI" +SONAM_LOSAR = "SONAM_LOSAR" +TAMU_LOSAR = "TAMU_LOSAR" +THAIPUSAM = "THAIPUSAM" +VAISAKHI = "VAISAKHI" + + +class _HinduLunisolar: + # https://web.archive.org/web/20240804044401/https://www.timeanddate.com/holidays/india/buddha-purnima + BUDDHA_PURNIMA_DATES = { + 2001: (APR, 30), + 2002: (MAY, 19), + 2003: (MAY, 8), + 2004: (MAY, 26), + 2005: (MAY, 23), + 2006: (MAY, 13), + 2007: (MAY, 2), + 2008: (MAY, 20), + 2009: (MAY, 8), + 2010: (MAY, 27), + 2011: (MAY, 17), + 2012: (MAY, 6), + 2013: (MAY, 25), + 2014: (MAY, 14), + 2015: (MAY, 4), + 2016: (MAY, 21), + 2017: (MAY, 10), + 2018: (APR, 30), + 2019: (MAY, 18), + 2020: (MAY, 7), + 2021: (MAY, 26), + 2022: (MAY, 16), + 2023: (MAY, 5), + 2024: (MAY, 23), + 2025: (MAY, 12), + 2026: (MAY, 1), + 2027: (MAY, 20), + 2028: (MAY, 8), + 2029: (MAY, 27), + 2030: (MAY, 17), + 2031: (MAY, 7), + 2032: (MAY, 25), + 2033: (MAY, 14), + 2034: (MAY, 3), + 2035: (MAY, 22), + } + + # https://web.archive.org/web/20250404174934/https://www.timeanddate.com/holidays/india/chhat-puja + CHHATH_PUJA_DATES = { + 2001: (NOV, 21), + 2002: (NOV, 10), + 2003: (OCT, 30), + 2004: (NOV, 17), + 2005: (NOV, 7), + 2006: (OCT, 28), + 2007: (NOV, 16), + 2008: (NOV, 4), + 2009: (OCT, 24), + 2010: (NOV, 11), + 2011: (NOV, 1), + 2012: (NOV, 19), + 2013: (NOV, 8), + 2014: (OCT, 29), + 2015: (NOV, 17), + 2016: (NOV, 6), + 2017: (OCT, 26), + 2018: (NOV, 13), + 2019: (NOV, 2), + 2020: (NOV, 20), + 2021: (NOV, 10), + 2022: (OCT, 30), + 2023: (NOV, 19), + 2024: (NOV, 7), + 2025: (OCT, 28), + 2026: (NOV, 15), + 2027: (NOV, 4), + 2028: (OCT, 23), + 2029: (NOV, 11), + 2030: (NOV, 1), + 2031: (NOV, 20), + 2032: (NOV, 9), + 2033: (OCT, 29), + 2034: (NOV, 17), + 2035: (NOV, 6), + } + + DIWALI_DATES = { + 1901: (NOV, 9), + 1902: (OCT, 29), + 1903: (NOV, 17), + 1904: (NOV, 5), + 1905: (OCT, 26), + 1906: (NOV, 14), + 1907: (NOV, 4), + 1908: (OCT, 23), + 1909: (NOV, 11), + 1910: (OCT, 31), + 1911: (NOV, 19), + 1912: (NOV, 7), + 1913: (OCT, 27), + 1914: (NOV, 16), + 1915: (NOV, 5), + 1916: (OCT, 25), + 1917: (NOV, 13), + 1918: (NOV, 2), + 1919: (NOV, 20), + 1920: (NOV, 9), + 1921: (OCT, 29), + 1922: (NOV, 17), + 1923: (NOV, 6), + 1924: (OCT, 26), + 1925: (NOV, 14), + 1926: (NOV, 3), + 1927: (OCT, 23), + 1928: (NOV, 10), + 1929: (OCT, 30), + 1930: (NOV, 18), + 1931: (NOV, 8), + 1932: (OCT, 27), + 1933: (NOV, 16), + 1934: (NOV, 5), + 1935: (OCT, 25), + 1936: (NOV, 12), + 1937: (NOV, 1), + 1938: (NOV, 20), + 1939: (NOV, 9), + 1940: (OCT, 29), + 1941: (NOV, 17), + 1942: (NOV, 6), + 1943: (OCT, 27), + 1944: (NOV, 14), + 1945: (NOV, 3), + 1946: (OCT, 23), + 1947: (NOV, 11), + 1948: (OCT, 30), + 1949: (NOV, 18), + 1950: (NOV, 8), + 1951: (OCT, 28), + 1952: (NOV, 15), + 1953: (NOV, 5), + 1954: (OCT, 25), + 1955: (NOV, 12), + 1956: (NOV, 1), + 1957: (NOV, 20), + 1958: (NOV, 9), + 1959: (OCT, 30), + 1960: (NOV, 17), + 1961: (NOV, 6), + 1962: (OCT, 26), + 1963: (NOV, 14), + 1964: (NOV, 2), + 1965: (OCT, 22), + 1966: (NOV, 10), + 1967: (OCT, 31), + 1968: (NOV, 18), + 1969: (NOV, 8), + 1970: (OCT, 28), + 1971: (NOV, 16), + 1972: (NOV, 4), + 1973: (OCT, 24), + 1974: (NOV, 12), + 1975: (NOV, 1), + 1976: (NOV, 19), + 1977: (NOV, 9), + 1978: (OCT, 30), + 1979: (NOV, 18), + 1980: (NOV, 6), + 1981: (OCT, 26), + 1982: (NOV, 13), + 1983: (NOV, 3), + 1984: (OCT, 22), + 1985: (NOV, 10), + 1986: (OCT, 31), + 1987: (NOV, 19), + 1988: (NOV, 7), + 1989: (OCT, 27), + 1990: (NOV, 15), + 1991: (NOV, 4), + 1992: (OCT, 24), + 1993: (NOV, 12), + 1994: (NOV, 1), + 1995: (NOV, 20), + 1996: (NOV, 9), + 1997: (OCT, 29), + 1998: (NOV, 17), + 1999: (NOV, 6), + 2000: (OCT, 25), + 2001: (NOV, 13), + 2002: (NOV, 3), + 2003: (OCT, 23), + 2004: (NOV, 10), + 2005: (OCT, 31), + 2006: (NOV, 19), + 2007: (NOV, 8), + 2008: (OCT, 27), + 2009: (NOV, 15), + 2010: (NOV, 4), + 2011: (OCT, 25), + 2012: (NOV, 12), + 2013: (NOV, 1), + 2014: (NOV, 20), + 2015: (NOV, 10), + 2016: (OCT, 29), + 2017: (NOV, 16), + 2018: (NOV, 6), + 2019: (OCT, 26), + 2020: (NOV, 13), + 2021: (NOV, 3), + 2022: (OCT, 23), + 2023: (NOV, 11), + 2024: (OCT, 30), + 2025: (NOV, 18), + 2026: (NOV, 7), + 2027: (OCT, 27), + 2028: (NOV, 14), + 2029: (NOV, 4), + 2030: (OCT, 25), + 2031: (NOV, 13), + 2032: (NOV, 1), + 2033: (OCT, 21), + 2034: (NOV, 9), + 2035: (OCT, 29), + 2036: (NOV, 16), + 2037: (NOV, 5), + 2038: (OCT, 26), + 2039: (NOV, 14), + 2040: (NOV, 3), + 2041: (OCT, 23), + 2042: (NOV, 11), + 2043: (OCT, 31), + 2044: (NOV, 17), + 2045: (NOV, 7), + 2046: (OCT, 27), + 2047: (NOV, 15), + 2048: (NOV, 4), + 2049: (OCT, 25), + 2050: (NOV, 12), + 2051: (NOV, 1), + 2052: (NOV, 19), + 2053: (NOV, 8), + 2054: (OCT, 29), + 2055: (NOV, 17), + 2056: (NOV, 5), + 2057: (OCT, 26), + 2058: (NOV, 14), + 2059: (NOV, 3), + 2060: (OCT, 22), + 2061: (NOV, 10), + 2062: (OCT, 30), + 2063: (NOV, 18), + 2064: (NOV, 7), + 2065: (OCT, 27), + 2066: (NOV, 15), + 2067: (NOV, 5), + 2068: (OCT, 24), + 2069: (NOV, 12), + 2070: (NOV, 1), + 2071: (NOV, 20), + 2072: (NOV, 8), + 2073: (OCT, 29), + 2074: (NOV, 17), + 2075: (NOV, 6), + 2076: (OCT, 26), + 2077: (NOV, 14), + 2078: (NOV, 3), + 2079: (OCT, 23), + 2080: (NOV, 9), + 2081: (OCT, 30), + 2082: (NOV, 18), + 2083: (NOV, 8), + 2084: (OCT, 27), + 2085: (NOV, 15), + 2086: (NOV, 4), + 2087: (OCT, 24), + 2088: (NOV, 11), + 2089: (OCT, 31), + 2090: (NOV, 19), + 2091: (NOV, 9), + 2092: (OCT, 29), + 2093: (NOV, 17), + 2094: (NOV, 6), + 2095: (OCT, 26), + 2096: (NOV, 13), + 2097: (NOV, 2), + 2098: (OCT, 22), + 2099: (NOV, 10), + 2100: (OCT, 31), + } + + # https://web.archive.org/web/20250118190944/https://www.timeanddate.com/holidays/india/diwali + DIWALI_INDIA_DATES = { + 2001: (NOV, 14), + 2002: (NOV, 4), + 2003: (OCT, 25), + 2004: (NOV, 12), + 2005: (NOV, 1), + 2006: (OCT, 21), + 2007: (NOV, 9), + 2008: (OCT, 28), + 2009: (OCT, 17), + 2010: (NOV, 5), + 2011: (OCT, 26), + 2012: (NOV, 13), + 2013: (NOV, 3), + 2014: (OCT, 23), + 2015: (NOV, 11), + 2016: (OCT, 30), + 2017: (OCT, 19), + 2018: (NOV, 7), + 2019: (OCT, 27), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 24), + 2023: (NOV, 12), + 2024: (OCT, 31), + 2025: (OCT, 20), + 2026: (NOV, 8), + 2027: (OCT, 29), + 2028: (OCT, 17), + 2029: (NOV, 5), + 2030: (OCT, 26), + 2031: (NOV, 14), + 2032: (NOV, 2), + 2033: (OCT, 22), + 2034: (NOV, 10), + 2035: (OCT, 30), + } + + # https://web.archive.org/web/20250118183534/https://www.timeanddate.com/holidays/india/dussehra + DUSSEHRA_DATES = { + 2001: (OCT, 26), + 2002: (OCT, 15), + 2003: (OCT, 5), + 2004: (OCT, 22), + 2005: (OCT, 12), + 2006: (OCT, 2), + 2007: (OCT, 21), + 2008: (OCT, 9), + 2009: (SEP, 28), + 2010: (OCT, 17), + 2011: (OCT, 6), + 2012: (OCT, 24), + 2013: (OCT, 13), + 2014: (OCT, 3), + 2015: (OCT, 22), + 2016: (OCT, 11), + 2017: (SEP, 30), + 2018: (OCT, 19), + 2019: (OCT, 8), + 2020: (OCT, 25), + 2021: (OCT, 15), + 2022: (OCT, 5), + 2023: (OCT, 24), + 2024: (OCT, 12), + 2025: (OCT, 2), + 2026: (OCT, 20), + 2027: (OCT, 9), + 2028: (SEP, 27), + 2029: (OCT, 16), + 2030: (OCT, 6), + 2031: (OCT, 25), + 2032: (OCT, 14), + 2033: (OCT, 3), + 2034: (OCT, 22), + 2035: (OCT, 11), + } + + # https://web.archive.org/web/20250219062212/https://www.timeanddate.com/holidays/india/ganesh-chaturthi + GANESH_CHATURTHI_DATES = { + 2001: (AUG, 22), + 2002: (SEP, 10), + 2003: (AUG, 31), + 2004: (SEP, 18), + 2005: (SEP, 7), + 2006: (AUG, 27), + 2007: (SEP, 15), + 2008: (SEP, 3), + 2009: (AUG, 23), + 2010: (SEP, 11), + 2011: (SEP, 1), + 2012: (SEP, 19), + 2013: (SEP, 9), + 2014: (AUG, 29), + 2015: (SEP, 17), + 2016: (SEP, 5), + 2017: (AUG, 25), + 2018: (SEP, 13), + 2019: (SEP, 2), + 2020: (AUG, 22), + 2021: (SEP, 10), + 2022: (AUG, 31), + 2023: (SEP, 19), + 2024: (SEP, 7), + 2025: (AUG, 27), + 2026: (SEP, 14), + 2027: (SEP, 4), + 2028: (AUG, 23), + 2029: (SEP, 11), + 2030: (SEP, 1), + 2031: (SEP, 20), + 2032: (SEP, 8), + 2033: (AUG, 28), + 2034: (SEP, 16), + 2035: (SEP, 5), + } + + # https://web.archive.org/web/20240917162551/https://www.timeanddate.com/holidays/india/govardhan-puja + GOVARDHAN_PUJA_DATES = { + 2001: (NOV, 15), + 2002: (NOV, 5), + 2003: (OCT, 26), + 2004: (NOV, 13), + 2005: (NOV, 2), + 2006: (OCT, 22), + 2007: (NOV, 10), + 2008: (OCT, 29), + 2009: (OCT, 18), + 2010: (NOV, 6), + 2011: (OCT, 27), + 2012: (NOV, 14), + 2013: (NOV, 4), + 2014: (OCT, 24), + 2015: (NOV, 12), + 2016: (OCT, 31), + 2017: (OCT, 20), + 2018: (NOV, 8), + 2019: (OCT, 28), + 2020: (NOV, 15), + 2021: (NOV, 5), + 2022: (OCT, 25), + 2023: (NOV, 13), + 2024: (NOV, 2), + 2025: (OCT, 22), + 2026: (NOV, 10), + 2027: (OCT, 30), + 2028: (OCT, 18), + 2029: (NOV, 6), + 2030: (OCT, 27), + 2031: (NOV, 15), + 2032: (NOV, 3), + 2033: (OCT, 23), + 2034: (NOV, 11), + 2035: (OCT, 31), + } + + # https://web.archive.org/web/20250331230057/https://www.timeanddate.com/holidays/india/gudi-padwa + GUDI_PADWA_DATES = { + 2001: (MAR, 26), + 2002: (APR, 13), + 2003: (APR, 2), + 2004: (MAR, 21), + 2005: (APR, 9), + 2006: (MAR, 30), + 2007: (MAR, 19), + 2008: (APR, 6), + 2009: (MAR, 27), + 2010: (MAR, 16), + 2011: (APR, 4), + 2012: (MAR, 23), + 2013: (APR, 11), + 2014: (MAR, 31), + 2015: (MAR, 21), + 2016: (APR, 8), + 2017: (MAR, 28), + 2018: (MAR, 18), + 2019: (APR, 6), + 2020: (MAR, 25), + 2021: (APR, 13), + 2022: (APR, 2), + 2023: (MAR, 22), + 2024: (APR, 9), + 2025: (MAR, 30), + 2026: (MAR, 19), + 2027: (APR, 7), + 2028: (MAR, 27), + 2029: (APR, 14), + 2030: (APR, 3), + 2031: (MAR, 24), + 2032: (APR, 11), + 2033: (MAR, 31), + 2034: (MAR, 21), + 2035: (APR, 9), + } + + # https://web.archive.org/web/20241231181629/https://www.timeanddate.com/holidays/india/guru-govind-singh-jayanti + GURU_GOBIND_SINGH_JAYANTI_DATES = { + 2001: (JAN, 2), + 2002: (JAN, 21), + 2003: (DEC, 29), + 2004: (NOV, 20), + 2005: (JAN, 5), + 2006: (JAN, 5), + 2007: (JAN, 5), + 2008: (JAN, 5), + 2009: (JAN, 5), + 2010: (JAN, 5), + 2011: (JAN, 5), + 2012: (JAN, 5), + 2013: (JAN, 18), + 2014: (JAN, 7), + 2015: (JAN, 5), + 2016: (JAN, 16), + 2017: ((JAN, 5), (DEC, 25)), + 2019: (JAN, 13), + 2020: (JAN, 2), + 2021: (JAN, 20), + 2022: ((JAN, 9), (DEC, 29)), + 2024: (JAN, 17), + 2025: ((JAN, 6), (DEC, 27)), + 2027: (JAN, 15), + 2028: (JAN, 4), + 2029: (JAN, 15), + 2030: ((JAN, 10), (DEC, 31)), + 2032: (JAN, 18), + 2033: (JAN, 7), + 2034: (JAN, 17), + 2035: (JAN, 16), + } + + # https://web.archive.org/web/20240521074207/https://www.timeanddate.com/holidays/india/guru-nanak-jayanti + GURU_NANAK_JAYANTI_DATES = { + 2001: (NOV, 30), + 2002: (NOV, 19), + 2003: (NOV, 8), + 2004: (NOV, 26), + 2005: (NOV, 15), + 2006: (NOV, 5), + 2007: (NOV, 24), + 2008: (NOV, 13), + 2009: (NOV, 2), + 2010: (NOV, 21), + 2011: (NOV, 10), + 2012: (NOV, 28), + 2013: (NOV, 17), + 2014: (NOV, 6), + 2015: (NOV, 25), + 2016: (NOV, 14), + 2017: (NOV, 4), + 2018: (NOV, 23), + 2019: (NOV, 12), + 2020: (NOV, 30), + 2021: (NOV, 19), + 2022: (NOV, 8), + 2023: (NOV, 27), + 2024: (NOV, 15), + 2025: (NOV, 5), + 2027: (NOV, 14), + 2028: (NOV, 2), + 2029: (NOV, 21), + 2030: (NOV, 10), + 2031: (NOV, 28), + 2032: (NOV, 17), + 2033: (NOV, 6), + 2034: (NOV, 25), + 2035: (NOV, 15), + } + + # https://web.archive.org/web/20240814073838/https://www.timeanddate.com/holidays/nepal/gyalpo-losar + # https://web.archive.org/web/20250322000610/https://www.ashesh.com.np/nepali-calendar/ + GYALPO_LOSAR_DATES = { + 2010: (FEB, 13), + 2011: (MAR, 5), + 2012: (FEB, 22), + 2013: (MAR, 12), + 2014: (MAR, 2), + 2015: (FEB, 19), + 2016: (MAR, 9), + 2017: (FEB, 27), + 2018: (FEB, 16), + 2019: (MAR, 7), + 2020: (FEB, 24), + 2021: (MAR, 14), + 2022: (MAR, 3), + 2023: (FEB, 21), + 2024: (MAR, 11), + 2025: (FEB, 28), + 2026: (FEB, 18), + 2027: (FEB, 7), + 2028: (FEB, 26), + 2029: (FEB, 14), + 2030: (MAR, 5), + 2031: (FEB, 22), + 2032: (FEB, 12), + 2033: (MAR, 2), + 2034: (FEB, 19), + 2035: (FEB, 9), + } + + # https://web.archive.org/web/20250410002117/https://www.timeanddate.com/holidays/india/holi + HOLI_DATES = { + 2001: (MAR, 10), + 2002: (MAR, 29), + 2003: (MAR, 18), + 2004: (MAR, 7), + 2005: (MAR, 26), + 2006: (MAR, 15), + 2007: (MAR, 4), + 2008: (MAR, 22), + 2009: (MAR, 11), + 2010: (MAR, 1), + 2011: (MAR, 20), + 2012: (MAR, 8), + 2013: (MAR, 27), + 2014: (MAR, 17), + 2015: (MAR, 6), + 2016: (MAR, 24), + 2017: (MAR, 13), + 2018: (MAR, 2), + 2019: (MAR, 21), + 2020: (MAR, 10), + 2021: (MAR, 29), + 2022: (MAR, 18), + 2023: (MAR, 8), + 2024: (MAR, 25), + 2025: (MAR, 14), + 2026: (MAR, 4), + 2027: (MAR, 22), + 2028: (MAR, 11), + 2029: (MAR, 1), + 2030: (MAR, 20), + 2031: (MAR, 9), + 2032: (MAR, 27), + 2033: (MAR, 16), + 2034: (MAR, 5), + 2035: (MAR, 24), + } + + # https://web.archive.org/web/20241205010833/https://www.timeanddate.com/holidays/india/janmashtami + JANMASHTAMI_DATES = { + 2001: (AUG, 12), + 2002: (AUG, 31), + 2003: (AUG, 20), + 2004: (SEP, 7), + 2005: (AUG, 27), + 2006: (AUG, 16), + 2007: (SEP, 4), + 2008: (AUG, 24), + 2009: (AUG, 14), + 2010: (SEP, 2), + 2011: (AUG, 22), + 2012: (AUG, 10), + 2013: (AUG, 28), + 2014: (AUG, 18), + 2015: (SEP, 5), + 2016: (AUG, 25), + 2017: (AUG, 15), + 2018: (SEP, 3), + 2019: (AUG, 24), + 2020: (AUG, 12), + 2021: (AUG, 30), + 2022: (AUG, 19), + 2023: (SEP, 7), + 2024: (AUG, 26), + 2025: (AUG, 16), + 2026: (SEP, 4), + 2027: (AUG, 25), + 2028: (AUG, 13), + 2029: (SEP, 1), + 2030: (AUG, 21), + 2031: (AUG, 10), + 2032: (AUG, 28), + 2033: (AUG, 17), + 2034: (SEP, 6), + 2035: (AUG, 26), + } + + # https://web.archive.org/web/20250113213218/https://www.timeanddate.com/holidays/india/maha-ashtami + MAHA_ASHTAMI_DATES = { + 2001: (OCT, 24), + 2002: (OCT, 13), + 2003: (OCT, 3), + 2004: (OCT, 21), + 2005: (OCT, 11), + 2006: (SEP, 30), + 2007: (OCT, 19), + 2008: (OCT, 7), + 2009: (SEP, 26), + 2010: (OCT, 15), + 2011: (OCT, 4), + 2012: (OCT, 22), + 2013: (OCT, 12), + 2014: (OCT, 2), + 2015: (OCT, 21), + 2016: (OCT, 9), + 2017: (SEP, 28), + 2018: (OCT, 17), + 2019: (OCT, 6), + 2020: (OCT, 23), + 2021: (OCT, 13), + 2022: (OCT, 3), + 2023: (OCT, 22), + 2024: (OCT, 11), + 2025: (SEP, 30), + 2026: (OCT, 19), + 2027: (OCT, 7), + 2028: (SEP, 26), + 2029: (OCT, 14), + 2030: (OCT, 4), + 2031: (OCT, 23), + 2032: (OCT, 12), + 2033: (OCT, 2), + 2034: (OCT, 20), + 2035: (OCT, 9), + } + + # https://web.archive.org/web/20241125173623/https://www.timeanddate.com/holidays/india/maha-navami + MAHA_NAVAMI_DATES = { + 2001: (OCT, 25), + 2002: (OCT, 14), + 2003: (OCT, 3), + 2004: (OCT, 21), + 2005: (OCT, 11), + 2006: (OCT, 1), + 2007: (OCT, 20), + 2008: (OCT, 8), + 2009: (SEP, 27), + 2010: (OCT, 16), + 2011: (OCT, 5), + 2012: (OCT, 23), + 2013: (OCT, 12), + 2014: (OCT, 2), + 2015: (OCT, 21), + 2016: (OCT, 10), + 2017: (SEP, 29), + 2018: (OCT, 17), + 2019: (OCT, 6), + 2020: (OCT, 24), + 2021: (OCT, 14), + 2022: (OCT, 4), + 2023: (OCT, 23), + 2024: (OCT, 11), + 2025: (OCT, 1), + 2026: (OCT, 19), + 2027: (OCT, 8), + 2028: (SEP, 26), + 2029: (OCT, 15), + 2030: (OCT, 5), + 2031: (OCT, 24), + 2032: (OCT, 13), + 2033: (OCT, 2), + 2034: (OCT, 21), + 2035: (OCT, 10), + } + + # https://web.archive.org/web/20250323040914/https://www.timeanddate.com/holidays/india/maha-shivaratri-shivaratri + MAHA_SHIVARATRI_DATES = { + 2001: (FEB, 21), + 2002: (MAR, 12), + 2003: (MAR, 1), + 2004: (FEB, 18), + 2005: (MAR, 8), + 2006: (FEB, 26), + 2007: (FEB, 16), + 2008: (MAR, 6), + 2009: (FEB, 23), + 2010: (FEB, 12), + 2011: (MAR, 2), + 2012: (FEB, 20), + 2013: (MAR, 10), + 2014: (FEB, 27), + 2015: (FEB, 17), + 2016: (MAR, 7), + 2017: (FEB, 24), + 2018: (FEB, 13), + 2019: (MAR, 4), + 2020: (FEB, 21), + 2021: (MAR, 11), + 2022: (MAR, 1), + 2023: (FEB, 18), + 2024: (MAR, 8), + 2025: (FEB, 26), + 2026: (FEB, 15), + 2027: (MAR, 6), + 2028: (FEB, 23), + 2029: (FEB, 11), + 2030: (MAR, 2), + 2031: (FEB, 20), + 2032: (MAR, 10), + 2033: (FEB, 27), + 2034: (FEB, 17), + 2035: (MAR, 8), + } + + # https://web.archive.org/web/20250121194712/https://www.timeanddate.com/holidays/india/mahavir-jayanti + MAHAVIR_JAYANTI_DATES = { + 2001: (APR, 6), + 2002: (APR, 25), + 2003: (APR, 15), + 2004: (APR, 3), + 2005: (APR, 22), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (APR, 18), + 2009: (APR, 7), + 2010: (APR, 28), + 2011: (APR, 16), + 2012: (APR, 5), + 2013: (APR, 24), + 2014: (APR, 13), + 2015: (APR, 2), + 2016: (APR, 20), + 2017: (APR, 9), + 2018: (MAR, 29), + 2019: (APR, 17), + 2020: (APR, 6), + 2021: (APR, 25), + 2022: (APR, 14), + 2023: (APR, 4), + 2024: (APR, 21), + 2025: (APR, 10), + 2026: (MAR, 31), + 2027: (APR, 18), + 2028: (APR, 7), + 2029: (APR, 26), + 2030: (APR, 16), + 2031: (APR, 5), + 2032: (APR, 23), + 2033: (APR, 12), + 2034: (APR, 1), + 2035: (APR, 20), + } + + # https://web.archive.org/web/20250119043432/https://www.timeanddate.com/holidays/india/makar-sankranti + MAKAR_SANKRANTI_DATES = { + 2001: (JAN, 14), + 2002: (JAN, 14), + 2003: (JAN, 14), + 2004: (JAN, 15), + 2005: (JAN, 14), + 2006: (JAN, 14), + 2007: (JAN, 15), + 2008: (JAN, 15), + 2009: (JAN, 14), + 2010: (JAN, 14), + 2011: (JAN, 15), + 2012: (JAN, 15), + 2013: (JAN, 14), + 2014: (JAN, 14), + 2015: (JAN, 15), + 2016: (JAN, 15), + 2017: (JAN, 14), + 2018: (JAN, 14), + 2019: (JAN, 15), + 2020: (JAN, 15), + 2021: (JAN, 14), + 2022: (JAN, 14), + 2023: (JAN, 14), + 2024: (JAN, 14), + 2025: (JAN, 14), + 2026: (JAN, 14), + 2027: (JAN, 15), + 2028: (JAN, 15), + 2029: (JAN, 14), + 2030: (JAN, 14), + 2031: (JAN, 15), + 2032: (JAN, 15), + 2033: (JAN, 14), + 2034: (JAN, 14), + 2035: (JAN, 15), + } + + # https://web.archive.org/web/20241205101551/https://www.timeanddate.com/holidays/india/onam + ONAM_DATES = { + 2001: (AUG, 31), + 2002: (AUG, 21), + 2003: (SEP, 8), + 2004: (AUG, 28), + 2005: (SEP, 15), + 2006: (SEP, 5), + 2007: (AUG, 26), + 2008: (SEP, 12), + 2009: (SEP, 2), + 2010: (AUG, 23), + 2011: (SEP, 9), + 2012: (AUG, 29), + 2013: (AUG, 20), + 2014: (SEP, 6), + 2015: (AUG, 28), + 2016: (SEP, 13), + 2017: (SEP, 4), + 2018: (AUG, 24), + 2019: (SEP, 11), + 2020: (AUG, 31), + 2021: (AUG, 21), + 2022: (SEP, 8), + 2023: (AUG, 29), + 2024: (SEP, 15), + 2025: (SEP, 5), + 2026: (AUG, 26), + 2027: (SEP, 12), + 2028: (SEP, 1), + 2029: (AUG, 22), + 2030: (SEP, 9), + 2031: (AUG, 30), + 2032: (AUG, 20), + 2033: (SEP, 6), + 2034: (AUG, 28), + 2035: (SEP, 14), + } + + PONGAL_DATES = { + 2001: (JAN, 14), + 2002: (JAN, 14), + 2003: (JAN, 15), + 2004: (JAN, 15), + 2005: (JAN, 14), + 2006: (JAN, 14), + 2007: (JAN, 15), + 2008: (JAN, 15), + 2009: (JAN, 14), + 2010: (JAN, 14), + 2011: (JAN, 15), + 2012: (JAN, 15), + 2013: (JAN, 14), + 2014: (JAN, 14), + 2015: (JAN, 15), + 2016: (JAN, 15), + 2017: (JAN, 14), + 2018: (JAN, 14), + 2019: (JAN, 15), + 2020: (JAN, 15), + 2021: (JAN, 14), + 2022: (JAN, 14), + 2023: (JAN, 15), + 2024: (JAN, 15), + 2025: (JAN, 14), + 2026: (JAN, 14), + 2027: (JAN, 15), + 2028: (JAN, 15), + 2029: (JAN, 14), + 2030: (JAN, 14), + 2031: (JAN, 15), + 2032: (JAN, 15), + 2033: (JAN, 14), + 2034: (JAN, 14), + 2035: (JAN, 15), + } + + # https://web.archive.org/web/20240720191148/https://www.timeanddate.com/holidays/india/raksha-bandhan + RAKSHA_BANDHAN_DATES = { + 2001: (AUG, 4), + 2002: (AUG, 22), + 2003: (AUG, 12), + 2004: (AUG, 29), + 2005: (AUG, 19), + 2006: (AUG, 9), + 2007: (AUG, 28), + 2008: (AUG, 16), + 2009: (AUG, 5), + 2010: (AUG, 24), + 2011: (AUG, 13), + 2012: (AUG, 2), + 2013: (AUG, 20), + 2014: (AUG, 10), + 2015: (AUG, 29), + 2016: (AUG, 18), + 2017: (AUG, 7), + 2018: (AUG, 26), + 2019: (AUG, 15), + 2020: (AUG, 3), + 2021: (AUG, 22), + 2022: (AUG, 11), + 2023: (AUG, 30), + 2024: (AUG, 19), + 2025: (AUG, 9), + 2026: (AUG, 28), + 2027: (AUG, 17), + 2028: (AUG, 5), + 2029: (AUG, 23), + 2030: (AUG, 13), + 2031: (AUG, 2), + 2032: (AUG, 20), + 2033: (AUG, 10), + 2034: (AUG, 29), + 2035: (AUG, 18), + } + + # https://web.archive.org/web/20250403054153/https://www.timeanddate.com/holidays/india/rama-navami + RAM_NAVAMI_DATES = { + 2001: (APR, 2), + 2002: (APR, 21), + 2003: (APR, 11), + 2004: (MAR, 30), + 2005: (APR, 18), + 2006: (APR, 6), + 2007: (MAR, 26), + 2008: (APR, 13), + 2009: (APR, 3), + 2010: (MAR, 24), + 2011: (APR, 12), + 2012: (APR, 1), + 2013: (APR, 19), + 2014: (APR, 8), + 2015: (MAR, 28), + 2016: (APR, 15), + 2017: (APR, 4), + 2018: (MAR, 25), + 2019: (APR, 13), + 2020: (APR, 2), + 2021: (APR, 21), + 2022: (APR, 10), + 2023: (MAR, 30), + 2024: (APR, 17), + 2025: (APR, 6), + 2026: (MAR, 26), + 2027: (APR, 15), + 2028: (APR, 3), + 2029: (APR, 22), + 2030: (APR, 12), + 2031: (APR, 1), + 2032: (APR, 19), + 2033: (APR, 7), + 2034: (MAR, 28), + 2035: (APR, 16), + } + + # https://web.archive.org/web/20241202103625/https://www.timeanddate.com/holidays/india/navratri + SHARAD_NAVRATRI_DATES = { + 2001: (OCT, 17), + 2002: (OCT, 7), + 2003: (SEP, 26), + 2004: (OCT, 14), + 2005: (OCT, 4), + 2006: (SEP, 23), + 2007: (OCT, 12), + 2008: (SEP, 30), + 2009: (SEP, 19), + 2010: (OCT, 8), + 2011: (SEP, 28), + 2012: (OCT, 16), + 2013: (OCT, 5), + 2014: (SEP, 25), + 2015: (OCT, 13), + 2016: (OCT, 1), + 2017: (SEP, 21), + 2018: (OCT, 10), + 2019: (SEP, 29), + 2020: (OCT, 17), + 2021: (OCT, 7), + 2022: (SEP, 26), + 2023: (OCT, 15), + 2024: (OCT, 3), + 2025: (SEP, 22), + 2026: (OCT, 11), + 2027: (SEP, 30), + 2028: (SEP, 19), + 2029: (OCT, 8), + 2030: (SEP, 28), + 2031: (OCT, 17), + 2032: (OCT, 5), + 2033: (SEP, 24), + 2034: (OCT, 13), + 2035: (OCT, 2), + } + + # https://web.archive.org/web/20241007171215/https://www.timeanddate.com/holidays/nepal/sonam-losar + # https://web.archive.org/web/20250322000610/https://www.ashesh.com.np/nepali-calendar/ + SONAM_LOSAR_DATES = { + 2010: (JAN, 16), + 2011: (FEB, 4), + 2012: (JAN, 24), + 2013: (FEB, 11), + 2014: (JAN, 31), + 2015: (JAN, 21), + 2016: (FEB, 9), + 2017: (JAN, 28), + 2018: (JAN, 18), + 2019: (FEB, 5), + 2020: (JAN, 25), + 2021: (FEB, 12), + 2022: (FEB, 2), + 2023: (JAN, 22), + 2024: (FEB, 10), + 2025: (JAN, 30), + 2026: (JAN, 19), + 2027: (FEB, 7), + 2028: (FEB, 26), + 2029: (JAN, 15), + 2030: (FEB, 3), + 2031: (JAN, 24), + 2032: (FEB, 12), + 2033: (JAN, 31), + 2034: (JAN, 21), + 2035: (FEB, 9), + } + + # https://web.archive.org/web/20241207045124/https://www.hamropatro.com/posts/articles-Bishesh-Dinharu/articles-Bishesh-Dinharu-english-tamu-lhosar + TAMU_LOSAR_DATES = { + 2010: (DEC, 30), + 2011: (DEC, 30), + 2012: (DEC, 30), + 2013: (DEC, 30), + 2014: (DEC, 30), + 2015: (DEC, 30), + 2016: (DEC, 30), + 2017: (DEC, 30), + 2018: (DEC, 30), + 2019: (DEC, 31), + 2020: (DEC, 30), + 2021: (DEC, 30), + 2022: (DEC, 30), + 2023: (DEC, 31), + 2024: (DEC, 30), + 2025: (DEC, 30), + 2026: (DEC, 30), + 2027: (DEC, 30), + 2028: (DEC, 30), + 2029: (DEC, 30), + 2030: (DEC, 31), + 2031: (DEC, 31), + 2032: (DEC, 30), + } + + THAIPUSAM_DATES = { + 1901: (MAR, 5), + 1902: (FEB, 23), + 1903: (JAN, 14), + 1904: (MAR, 2), + 1905: (FEB, 19), + 1906: (JAN, 10), + 1907: (FEB, 27), + 1908: (FEB, 17), + 1909: (JAN, 7), + 1910: (FEB, 24), + 1911: (JAN, 15), + 1912: (MAR, 4), + 1913: (FEB, 21), + 1914: (JAN, 11), + 1915: (MAR, 1), + 1916: (FEB, 18), + 1917: (JAN, 8), + 1918: (FEB, 26), + 1919: (FEB, 15), + 1920: (MAR, 5), + 1921: (FEB, 23), + 1922: (JAN, 13), + 1923: (MAR, 2), + 1924: (FEB, 19), + 1925: (JAN, 9), + 1926: (FEB, 27), + 1927: (FEB, 17), + 1928: (JAN, 8), + 1929: (FEB, 24), + 1930: (JAN, 15), + 1931: (MAR, 4), + 1932: (FEB, 21), + 1933: (JAN, 11), + 1934: (FEB, 28), + 1935: (FEB, 18), + 1936: (JAN, 9), + 1937: (FEB, 26), + 1938: (FEB, 15), + 1939: (MAR, 6), + 1940: (FEB, 23), + 1941: (JAN, 12), + 1942: (MAR, 2), + 1943: (FEB, 19), + 1944: (JAN, 10), + 1945: (FEB, 27), + 1946: (FEB, 17), + 1947: (JAN, 7), + 1948: (FEB, 25), + 1949: (FEB, 13), + 1950: (MAR, 3), + 1951: (FEB, 21), + 1952: (JAN, 12), + 1953: (FEB, 28), + 1954: (FEB, 18), + 1955: (JAN, 9), + 1956: (FEB, 26), + 1957: (FEB, 15), + 1958: (MAR, 5), + 1959: (FEB, 22), + 1960: (JAN, 13), + 1961: (MAR, 2), + 1962: (FEB, 19), + 1963: (JAN, 10), + 1964: (FEB, 28), + 1965: (FEB, 16), + 1966: (JAN, 6), + 1967: (FEB, 24), + 1968: (FEB, 13), + 1969: (MAR, 3), + 1970: (FEB, 21), + 1971: (JAN, 12), + 1972: (FEB, 29), + 1973: (FEB, 18), + 1974: (JAN, 8), + 1975: (FEB, 26), + 1976: (FEB, 15), + 1977: (MAR, 5), + 1978: (FEB, 22), + 1979: (JAN, 13), + 1980: (MAR, 2), + 1981: (FEB, 19), + 1982: (JAN, 10), + 1983: (FEB, 28), + 1984: (FEB, 17), + 1985: (MAR, 6), + 1986: (FEB, 23), + 1987: (JAN, 14), + 1988: (MAR, 3), + 1989: (FEB, 21), + 1990: (JAN, 12), + 1991: (MAR, 1), + 1992: (FEB, 18), + 1993: (JAN, 8), + 1994: (FEB, 25), + 1995: (FEB, 14), + 1996: (MAR, 4), + 1997: (FEB, 22), + 1998: (JAN, 13), + 1999: (MAR, 3), + 2000: (FEB, 20), + 2001: (JAN, 9), + 2002: (FEB, 27), + 2003: (FEB, 16), + 2004: (JAN, 7), + 2005: (FEB, 23), + 2006: (FEB, 13), + 2007: (MAR, 4), + 2008: (FEB, 22), + 2009: (JAN, 11), + 2010: (MAR, 1), + 2011: (FEB, 18), + 2012: (JAN, 8), + 2013: (FEB, 25), + 2014: (FEB, 14), + 2015: (MAR, 5), + 2016: (FEB, 23), + 2017: (JAN, 13), + 2018: (MAR, 2), + 2019: (FEB, 20), + 2020: (JAN, 10), + 2021: (FEB, 26), + 2022: (FEB, 16), + 2023: (JAN, 7), + 2024: (FEB, 24), + 2025: (JAN, 14), + 2026: (MAR, 4), + 2027: (FEB, 21), + 2028: (JAN, 11), + 2029: (FEB, 28), + 2030: (FEB, 17), + 2031: (JAN, 8), + 2032: (FEB, 26), + 2033: (FEB, 14), + 2034: (MAR, 5), + 2035: (FEB, 23), + 2036: (JAN, 13), + 2037: (MAR, 2), + 2038: (FEB, 19), + 2039: (JAN, 9), + 2040: (FEB, 27), + 2041: (FEB, 15), + 2042: (JAN, 7), + 2043: (FEB, 24), + 2044: (FEB, 14), + 2045: (MAR, 4), + 2046: (FEB, 21), + 2047: (JAN, 11), + 2048: (FEB, 28), + 2049: (FEB, 17), + 2050: (JAN, 8), + 2051: (FEB, 26), + 2052: (FEB, 15), + 2053: (MAR, 5), + 2054: (FEB, 22), + 2055: (JAN, 13), + 2056: (MAR, 1), + 2057: (FEB, 18), + 2058: (JAN, 9), + 2059: (FEB, 27), + 2060: (FEB, 17), + 2061: (JAN, 6), + 2062: (FEB, 24), + 2063: (FEB, 13), + 2064: (MAR, 3), + 2065: (FEB, 20), + 2066: (JAN, 11), + 2067: (FEB, 28), + 2068: (FEB, 18), + 2069: (JAN, 8), + 2070: (FEB, 25), + 2071: (FEB, 15), + 2072: (MAR, 5), + 2073: (FEB, 22), + 2074: (JAN, 12), + 2075: (MAR, 2), + 2076: (FEB, 19), + 2077: (JAN, 9), + 2078: (FEB, 27), + 2079: (FEB, 16), + 2080: (JAN, 7), + 2081: (FEB, 23), + 2082: (FEB, 12), + 2083: (MAR, 3), + 2084: (FEB, 21), + 2085: (JAN, 11), + 2086: (FEB, 28), + 2087: (FEB, 18), + 2088: (JAN, 9), + 2089: (FEB, 25), + 2090: (FEB, 14), + 2091: (MAR, 5), + 2092: (FEB, 22), + 2093: (JAN, 12), + 2094: (MAR, 1), + 2095: (FEB, 19), + 2096: (JAN, 10), + 2097: (FEB, 27), + 2098: (FEB, 16), + 2099: (JAN, 6), + 2100: (FEB, 24), + } + + # https://web.archive.org/web/20250121194712/https://www.timeanddate.com/holidays/india/vaisakhi + VAISAKHI_DATES = { + 2001: (APR, 13), + 2002: (APR, 14), + 2003: (APR, 14), + 2004: (APR, 13), + 2005: (APR, 14), + 2006: (APR, 14), + 2007: (APR, 14), + 2008: (APR, 13), + 2009: (APR, 14), + 2010: (APR, 14), + 2011: (APR, 14), + 2012: (APR, 13), + 2013: (APR, 13), + 2014: (APR, 14), + 2015: (APR, 14), + 2016: (APR, 13), + 2017: (APR, 14), + 2018: (APR, 14), + 2019: (APR, 14), + 2020: (APR, 13), + 2021: (APR, 14), + 2022: (APR, 14), + 2023: (APR, 14), + 2024: (APR, 13), + 2025: (APR, 13), + 2026: (APR, 14), + 2027: (APR, 14), + 2028: (APR, 13), + 2029: (APR, 14), + 2030: (APR, 14), + 2031: (APR, 14), + 2032: (APR, 13), + 2033: (APR, 14), + 2034: (APR, 14), + 2035: (APR, 14), + } + + def _get_holiday(self, holiday: str, year: int) -> tuple[Optional[date], bool]: + estimated_dates = getattr(self, f"{holiday}_DATES", {}) + exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}) + dt = exact_dates.get(year, estimated_dates.get(year, ())) + return date(year, *dt) if dt else None, year not in exact_dates + + def _get_holiday_set(self, holiday: str, year: int) -> Iterable[tuple[date, bool]]: + estimated_dates = getattr(self, f"{holiday}_DATES", {}) + exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}) + for year in (year - 1, year): + for dt in _normalize_tuple(exact_dates.get(year, estimated_dates.get(year, ()))): + yield date(year, *dt), year not in exact_dates + + def buddha_purnima_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(BUDDHA_PURNIMA, year) + + def chhath_puja_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(CHHATH_PUJA, year) + + def diwali_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(DIWALI, year) + + def diwali_india_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(DIWALI_INDIA, year) + + def dussehra_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(DUSSEHRA, year) + + def ganesh_chaturthi_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(GANESH_CHATURTHI, year) + + def govardhan_puja_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(GOVARDHAN_PUJA, year) + + def gudi_padwa_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(GUDI_PADWA, year) + + def guru_gobind_singh_jayanti_date(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday_set(GURU_GOBIND_SINGH_JAYANTI, year) + + def guru_nanak_jayanti_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(GURU_NANAK_JAYANTI, year) + + def gyalpo_losar_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(GYALPO_LOSAR, year) + + def holi_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(HOLI, year) + + def pongal_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(PONGAL, year) + + def janmashtami_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(JANMASHTAMI, year) + + def maha_ashtami_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(MAHA_ASHTAMI, year) + + def maha_navami_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(MAHA_NAVAMI, year) + + def maha_shivaratri_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(MAHA_SHIVARATRI, year) + + def mahavir_jayanti_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(MAHAVIR_JAYANTI, year) + + def makar_sankranti_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(MAKAR_SANKRANTI, year) + + def onam_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(ONAM, year) + + def raksha_bandhan_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(RAKSHA_BANDHAN, year) + + def ram_navami_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(RAM_NAVAMI, year) + + def sharad_navratri_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(SHARAD_NAVRATRI, year) + + def sonam_losar_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(SONAM_LOSAR, year) + + def tamu_losar_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(TAMU_LOSAR, year) + + def thaipusam_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(THAIPUSAM, year) + + def vaisakhi_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(VAISAKHI, year) + + +class _CustomHinduHolidays(_CustomCalendar, _HinduLunisolar): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/islamic.py b/.venv/lib/python3.12/site-packages/holidays/calendars/islamic.py new file mode 100644 index 00000000..807dbd04 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/islamic.py @@ -0,0 +1,4043 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from collections.abc import Iterable +from datetime import date + +from holidays.calendars.custom import _CustomCalendar +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.helpers import _normalize_tuple + +ALI_AL_RIDA_DEATH = "ALI_AL_RIDA_DEATH" +ALI_BIRTHDAY = "ALI_BIRTHDAY" +ALI_DEATH = "ALI_DEATH" +ARBAEEN = "ARBAEEN" +ASHURA = "ASHURA" +EID_AL_ADHA = "EID_AL_ADHA" +EID_AL_FITR = "EID_AL_FITR" +EID_AL_GHADIR = "EID_AL_GHADIR" +FATIMA_DEATH = "FATIMA_DEATH" +GRAND_MAGAL_OF_TOUBA = "GRAND_MAGAL_OF_TOUBA" +HARI_HOL_JOHOR = "HARI_HOL_JOHOR" +HASAN_AL_ASKARI_DEATH = "HASAN_AL_ASKARI_DEATH" +HIJRI_NEW_YEAR = "HIJRI_NEW_YEAR" +IMAM_MAHDI_BIRTHDAY = "IMAM_MAHDI_BIRTHDAY" +ISRA_AND_MIRAJ = "ISRA_AND_MIRAJ" +LAYLAT_AL_QADR = "LAYLAT_AL_QADR" +MALDIVES_EMBRACED_ISLAM_DAY = "MALDIVES_EMBRACED_ISLAM_DAY" +MAWLID = "MAWLID" +NUZUL_AL_QURAN = "NUZUL_AL_QURAN" +PROPHET_DEATH = "PROPHET_DEATH" +QUAMEE_DHUVAS = "QUAMEE_DHUVAS" +RAMADAN_BEGINNING = "RAMADAN_BEGINNING" +SADIQ_BIRTHDAY = "SADIQ_BIRTHDAY" +SADIQ_DEATH = "SADIQ_DEATH" +TASUA = "TASUA" + + +class _IslamicLunar: + ALI_AL_RIDA_DEATH_DATES = { + 1924: (SEP, 28), + 1925: (SEP, 18), + 1926: (SEP, 7), + 1927: (AUG, 27), + 1928: (AUG, 15), + 1929: (AUG, 5), + 1930: (JUL, 25), + 1931: (JUL, 16), + 1932: (JUL, 4), + 1933: (JUN, 23), + 1934: (JUN, 12), + 1935: (JUN, 2), + 1936: (MAY, 21), + 1937: (MAY, 10), + 1938: (APR, 29), + 1939: (APR, 20), + 1940: (APR, 8), + 1941: (MAR, 27), + 1942: (MAR, 17), + 1943: (MAR, 6), + 1944: (FEB, 23), + 1945: (FEB, 12), + 1946: (FEB, 1), + 1947: (JAN, 22), + 1948: ((JAN, 11), (DEC, 30)), + 1949: (DEC, 20), + 1950: (DEC, 10), + 1951: (NOV, 29), + 1952: (NOV, 18), + 1953: (NOV, 7), + 1954: (OCT, 27), + 1955: (OCT, 17), + 1956: (OCT, 5), + 1957: (SEP, 24), + 1958: (SEP, 14), + 1959: (SEP, 3), + 1960: (AUG, 22), + 1961: (AUG, 11), + 1962: (JUL, 31), + 1963: (JUL, 21), + 1964: (JUL, 9), + 1965: (JUN, 28), + 1966: (JUN, 19), + 1967: (JUN, 7), + 1968: (MAY, 27), + 1969: (MAY, 16), + 1970: (MAY, 6), + 1971: (APR, 25), + 1972: (APR, 13), + 1973: (APR, 3), + 1974: (MAR, 23), + 1975: (MAR, 12), + 1976: (FEB, 29), + 1977: (FEB, 18), + 1978: (FEB, 7), + 1979: (JAN, 28), + 1980: (JAN, 18), + 1981: ((JAN, 6), (DEC, 26)), + 1982: (DEC, 15), + 1983: (DEC, 4), + 1984: (NOV, 22), + 1985: (NOV, 12), + 1986: (NOV, 2), + 1987: (OCT, 22), + 1988: (OCT, 10), + 1989: (SEP, 29), + 1990: (SEP, 19), + 1991: (SEP, 8), + 1992: (AUG, 28), + 1993: (AUG, 17), + 1994: (AUG, 7), + 1995: (JUL, 27), + 1996: (JUL, 15), + 1997: (JUL, 4), + 1998: (JUN, 24), + 1999: (JUN, 14), + 2000: (JUN, 2), + 2001: (MAY, 23), + 2002: (MAY, 12), + 2003: (MAY, 1), + 2004: (APR, 19), + 2005: (APR, 9), + 2006: (MAR, 29), + 2007: (MAR, 19), + 2008: (MAR, 8), + 2009: (FEB, 25), + 2010: (FEB, 14), + 2011: (FEB, 3), + 2012: (JAN, 23), + 2013: (JAN, 12), + 2014: ((JAN, 1), (DEC, 22)), + 2015: (DEC, 11), + 2016: (NOV, 29), + 2017: (NOV, 18), + 2018: (NOV, 8), + 2019: (OCT, 28), + 2020: (OCT, 17), + 2021: (OCT, 6), + 2022: (SEP, 26), + 2023: (SEP, 15), + 2024: (SEP, 3), + 2025: (AUG, 23), + 2026: (AUG, 13), + 2027: (AUG, 2), + 2028: (JUL, 22), + 2029: (JUL, 12), + 2030: (JUL, 1), + 2031: (JUN, 20), + 2032: (JUN, 8), + 2033: (MAY, 28), + 2034: (MAY, 18), + 2035: (MAY, 8), + 2036: (APR, 26), + 2037: (APR, 16), + 2038: (APR, 5), + 2039: (MAR, 25), + 2040: (MAR, 13), + 2041: (MAR, 3), + 2042: (FEB, 20), + 2043: (FEB, 10), + 2044: (JAN, 30), + 2045: (JAN, 18), + 2046: ((JAN, 7), (DEC, 27)), + 2047: (DEC, 17), + 2048: (DEC, 6), + 2049: (NOV, 25), + 2050: (NOV, 14), + 2051: (NOV, 4), + 2052: (OCT, 23), + 2053: (OCT, 12), + 2054: (OCT, 1), + 2055: (SEP, 21), + 2056: (SEP, 10), + 2057: (AUG, 30), + 2058: (AUG, 19), + 2059: (AUG, 8), + 2060: (JUL, 27), + 2061: (JUL, 17), + 2062: (JUL, 7), + 2063: (JUN, 26), + 2064: (JUN, 15), + 2065: (JUN, 4), + 2066: (MAY, 24), + 2067: (MAY, 13), + 2068: (MAY, 2), + 2069: (APR, 21), + 2070: (APR, 11), + 2071: (APR, 1), + 2072: (MAR, 20), + 2073: (MAR, 9), + 2074: (FEB, 26), + 2075: (FEB, 15), + 2076: (FEB, 5), + 2077: (JAN, 25), + } + + ALI_BIRTHDAY_DATES = { + 1925: (FEB, 7), + 1926: (JAN, 27), + 1927: (JAN, 17), + 1928: ((JAN, 6), (DEC, 25)), + 1929: (DEC, 14), + 1930: (DEC, 3), + 1931: (NOV, 23), + 1932: (NOV, 12), + 1933: (NOV, 1), + 1934: (OCT, 22), + 1935: (OCT, 11), + 1936: (SEP, 29), + 1937: (SEP, 18), + 1938: (SEP, 7), + 1939: (AUG, 28), + 1940: (AUG, 17), + 1941: (AUG, 5), + 1942: (JUL, 26), + 1943: (JUL, 15), + 1944: (JUL, 3), + 1945: (JUN, 23), + 1946: (JUN, 12), + 1947: (JUN, 2), + 1948: (MAY, 21), + 1949: (MAY, 10), + 1950: (APR, 30), + 1951: (APR, 20), + 1952: (APR, 8), + 1953: (MAR, 29), + 1954: (MAR, 18), + 1955: (MAR, 7), + 1956: (FEB, 25), + 1957: (FEB, 13), + 1958: (FEB, 2), + 1959: (JAN, 23), + 1960: ((JAN, 12), (DEC, 31)), + 1961: (DEC, 21), + 1962: (DEC, 10), + 1963: (NOV, 29), + 1964: (NOV, 17), + 1965: (NOV, 6), + 1966: (OCT, 27), + 1967: (OCT, 16), + 1968: (OCT, 5), + 1969: (SEP, 24), + 1970: (SEP, 14), + 1971: (SEP, 3), + 1972: (AUG, 22), + 1973: (AUG, 11), + 1974: (AUG, 1), + 1975: (JUL, 22), + 1976: (JUL, 10), + 1977: (JUN, 29), + 1978: (JUN, 18), + 1979: (JUN, 8), + 1980: (MAY, 27), + 1981: (MAY, 17), + 1982: (MAY, 6), + 1983: (APR, 26), + 1984: (APR, 14), + 1985: (APR, 3), + 1986: (MAR, 23), + 1987: (MAR, 13), + 1988: (MAR, 1), + 1989: (FEB, 19), + 1990: (FEB, 8), + 1991: (JAN, 28), + 1992: (JAN, 17), + 1993: ((JAN, 6), (DEC, 26)), + 1994: (DEC, 15), + 1995: (DEC, 5), + 1996: (NOV, 24), + 1997: (NOV, 13), + 1998: (NOV, 2), + 1999: (OCT, 22), + 2000: (OCT, 10), + 2001: (SEP, 30), + 2002: (SEP, 20), + 2003: (SEP, 10), + 2004: (AUG, 29), + 2005: (AUG, 18), + 2006: (AUG, 7), + 2007: (JUL, 27), + 2008: (JUL, 16), + 2009: (JUL, 6), + 2010: (JUN, 25), + 2011: (JUN, 15), + 2012: (JUN, 3), + 2013: (MAY, 23), + 2014: (MAY, 12), + 2015: (MAY, 2), + 2016: (APR, 20), + 2017: (APR, 10), + 2018: (MAR, 30), + 2019: (MAR, 20), + 2020: (MAR, 8), + 2021: (FEB, 25), + 2022: (FEB, 14), + 2023: (FEB, 4), + 2024: (JAN, 25), + 2025: (JAN, 13), + 2026: ((JAN, 2), (DEC, 22)), + 2027: (DEC, 11), + 2028: (NOV, 30), + 2029: (NOV, 19), + 2030: (NOV, 9), + 2031: (OCT, 29), + 2032: (OCT, 18), + 2033: (OCT, 7), + 2034: (SEP, 26), + 2035: (SEP, 15), + 2036: (SEP, 4), + 2037: (AUG, 24), + 2038: (AUG, 14), + 2039: (AUG, 3), + 2040: (JUL, 22), + 2041: (JUL, 11), + 2042: (JUL, 1), + 2043: (JUN, 20), + 2044: (JUN, 9), + 2045: (MAY, 30), + 2046: (MAY, 19), + 2047: (MAY, 8), + 2048: (APR, 26), + 2049: (APR, 15), + 2050: (APR, 5), + 2051: (MAR, 26), + 2052: (MAR, 14), + 2053: (MAR, 4), + 2054: (FEB, 21), + 2055: (FEB, 10), + 2056: (JAN, 30), + 2057: (JAN, 18), + 2058: ((JAN, 8), (DEC, 29)), + 2059: (DEC, 18), + 2060: (DEC, 6), + 2061: (NOV, 25), + 2062: (NOV, 15), + 2063: (NOV, 4), + 2064: (OCT, 24), + 2065: (OCT, 13), + 2066: (OCT, 3), + 2067: (SEP, 22), + 2068: (SEP, 10), + 2069: (AUG, 30), + 2070: (AUG, 20), + 2071: (AUG, 9), + 2072: (JUL, 29), + 2073: (JUL, 18), + 2074: (JUL, 8), + 2075: (JUN, 27), + 2076: (JUN, 15), + 2077: (JUN, 4), + } + + ALI_DEATH_DATES = { + 1925: (APR, 16), + 1926: (APR, 4), + 1927: (MAR, 24), + 1928: (MAR, 13), + 1929: (MAR, 2), + 1930: (FEB, 20), + 1931: (FEB, 9), + 1932: (JAN, 29), + 1933: (JAN, 17), + 1934: ((JAN, 7), (DEC, 28)), + 1935: (DEC, 17), + 1936: (DEC, 5), + 1937: (NOV, 25), + 1938: (NOV, 13), + 1939: (NOV, 3), + 1940: (OCT, 23), + 1941: (OCT, 11), + 1942: (OCT, 1), + 1943: (SEP, 20), + 1944: (SEP, 8), + 1945: (AUG, 28), + 1946: (AUG, 18), + 1947: (AUG, 8), + 1948: (JUL, 27), + 1949: (JUL, 16), + 1950: (JUL, 7), + 1951: (JUN, 26), + 1952: (JUN, 14), + 1953: (JUN, 3), + 1954: (MAY, 24), + 1955: (MAY, 14), + 1956: (MAY, 2), + 1957: (APR, 21), + 1958: (APR, 10), + 1959: (MAR, 31), + 1960: (MAR, 19), + 1961: (MAR, 8), + 1962: (FEB, 25), + 1963: (FEB, 15), + 1964: (FEB, 4), + 1965: (JAN, 23), + 1966: (JAN, 12), + 1967: ((JAN, 2), (DEC, 22)), + 1968: (DEC, 11), + 1969: (NOV, 30), + 1970: (NOV, 21), + 1971: (NOV, 9), + 1972: (OCT, 28), + 1973: (OCT, 17), + 1974: (OCT, 7), + 1975: (SEP, 26), + 1976: (SEP, 15), + 1977: (SEP, 4), + 1978: (AUG, 25), + 1979: (AUG, 14), + 1980: (AUG, 2), + 1981: (JUL, 22), + 1982: (JUL, 12), + 1983: (JUL, 2), + 1984: (JUN, 20), + 1985: (JUN, 9), + 1986: (MAY, 29), + 1987: (MAY, 19), + 1988: (MAY, 7), + 1989: (APR, 27), + 1990: (APR, 16), + 1991: (APR, 6), + 1992: (MAR, 25), + 1993: (MAR, 14), + 1994: (MAR, 3), + 1995: (FEB, 20), + 1996: (FEB, 10), + 1997: (JAN, 30), + 1998: (JAN, 19), + 1999: ((JAN, 8), (DEC, 29)), + 2000: (DEC, 17), + 2001: (DEC, 6), + 2002: (NOV, 26), + 2003: (NOV, 15), + 2004: (NOV, 4), + 2005: (OCT, 24), + 2006: (OCT, 14), + 2007: (OCT, 3), + 2008: (SEP, 21), + 2009: (SEP, 11), + 2010: (AUG, 31), + 2011: (AUG, 21), + 2012: (AUG, 9), + 2013: (JUL, 29), + 2014: (JUL, 18), + 2015: (JUL, 8), + 2016: (JUN, 26), + 2017: (JUN, 16), + 2018: (JUN, 5), + 2019: (MAY, 26), + 2020: (MAY, 14), + 2021: (MAY, 3), + 2022: (APR, 22), + 2023: (APR, 12), + 2024: (MAR, 31), + 2025: (MAR, 21), + 2026: (MAR, 10), + 2027: (FEB, 28), + 2028: (FEB, 17), + 2029: (FEB, 5), + 2030: (JAN, 25), + 2031: (JAN, 15), + 2032: ((JAN, 4), (DEC, 24)), + 2033: (DEC, 13), + 2034: (DEC, 2), + 2035: (NOV, 21), + 2036: (NOV, 9), + 2037: (OCT, 30), + 2038: (OCT, 20), + 2039: (OCT, 9), + 2040: (SEP, 27), + 2041: (SEP, 17), + 2042: (SEP, 6), + 2043: (AUG, 26), + 2044: (AUG, 15), + 2045: (AUG, 4), + 2046: (JUL, 25), + 2047: (JUL, 14), + 2048: (JUL, 2), + 2049: (JUN, 22), + 2050: (JUN, 11), + 2051: (MAY, 31), + 2052: (MAY, 20), + 2053: (MAY, 10), + 2054: (APR, 29), + 2055: (APR, 18), + 2056: (APR, 6), + 2057: (MAR, 26), + 2058: (MAR, 16), + 2059: (MAR, 6), + 2060: (FEB, 23), + 2061: (FEB, 12), + 2062: (FEB, 1), + 2063: (JAN, 21), + 2064: ((JAN, 10), (DEC, 29)), + 2065: (DEC, 19), + 2066: (DEC, 9), + 2067: (NOV, 28), + 2068: (NOV, 16), + 2069: (NOV, 5), + 2070: (OCT, 25), + 2071: (OCT, 15), + 2072: (OCT, 3), + 2073: (SEP, 23), + 2074: (SEP, 12), + 2075: (SEP, 2), + 2076: (AUG, 21), + 2077: (AUG, 10), + } + + ARBAEEN_DATES = { + 1924: (SEP, 19), + 1925: (SEP, 9), + 1926: (AUG, 29), + 1927: (AUG, 18), + 1928: (AUG, 6), + 1929: (JUL, 27), + 1930: (JUL, 16), + 1931: (JUL, 6), + 1932: (JUN, 25), + 1933: (JUN, 14), + 1934: (JUN, 3), + 1935: (MAY, 23), + 1936: (MAY, 12), + 1937: (MAY, 1), + 1938: (APR, 20), + 1939: (APR, 10), + 1940: (MAR, 29), + 1941: (MAR, 18), + 1942: (MAR, 8), + 1943: (FEB, 25), + 1944: (FEB, 14), + 1945: (FEB, 3), + 1946: (JAN, 23), + 1947: (JAN, 13), + 1948: ((JAN, 2), (DEC, 21)), + 1949: (DEC, 11), + 1950: (DEC, 1), + 1951: (NOV, 20), + 1952: (NOV, 8), + 1953: (OCT, 28), + 1954: (OCT, 18), + 1955: (OCT, 8), + 1956: (SEP, 25), + 1957: (SEP, 15), + 1958: (SEP, 5), + 1959: (AUG, 24), + 1960: (AUG, 13), + 1961: (AUG, 2), + 1962: (JUL, 22), + 1963: (JUL, 11), + 1964: (JUN, 30), + 1965: (JUN, 19), + 1966: (JUN, 9), + 1967: (MAY, 29), + 1968: (MAY, 17), + 1969: (MAY, 7), + 1970: (APR, 27), + 1971: (APR, 16), + 1972: (APR, 4), + 1973: (MAR, 25), + 1974: (MAR, 14), + 1975: (MAR, 3), + 1976: (FEB, 20), + 1977: (FEB, 8), + 1978: (JAN, 29), + 1979: (JAN, 18), + 1980: ((JAN, 8), (DEC, 27)), + 1981: (DEC, 16), + 1982: (DEC, 5), + 1983: (NOV, 24), + 1984: (NOV, 13), + 1985: (NOV, 3), + 1986: (OCT, 23), + 1987: (OCT, 13), + 1988: (OCT, 1), + 1989: (SEP, 20), + 1990: (SEP, 9), + 1991: (AUG, 30), + 1992: (AUG, 18), + 1993: (AUG, 8), + 1994: (JUL, 28), + 1995: (JUL, 18), + 1996: (JUL, 6), + 1997: (JUN, 25), + 1998: (JUN, 14), + 1999: (JUN, 4), + 2000: (MAY, 24), + 2001: (MAY, 14), + 2002: (MAY, 3), + 2003: (APR, 22), + 2004: (APR, 10), + 2005: (MAR, 30), + 2006: (MAR, 20), + 2007: (MAR, 10), + 2008: (FEB, 27), + 2009: (FEB, 15), + 2010: (FEB, 4), + 2011: (JAN, 24), + 2012: (JAN, 14), + 2013: ((JAN, 2), (DEC, 23)), + 2014: (DEC, 12), + 2015: (DEC, 2), + 2016: (NOV, 20), + 2017: (NOV, 9), + 2018: (OCT, 29), + 2019: (OCT, 19), + 2020: (OCT, 7), + 2021: (SEP, 27), + 2022: (SEP, 16), + 2023: (SEP, 5), + 2024: (AUG, 24), + 2025: (AUG, 14), + 2026: (AUG, 3), + 2027: (JUL, 24), + 2028: (JUL, 13), + 2029: (JUL, 2), + 2030: (JUN, 21), + 2031: (JUN, 10), + 2032: (MAY, 29), + 2033: (MAY, 19), + 2034: (MAY, 9), + 2035: (APR, 28), + 2036: (APR, 17), + 2037: (APR, 6), + 2038: (MAR, 26), + 2039: (MAR, 15), + 2040: (MAR, 4), + 2041: (FEB, 21), + 2042: (FEB, 11), + 2043: (JAN, 31), + 2044: (JAN, 21), + 2045: ((JAN, 9), (DEC, 29)), + 2046: (DEC, 18), + 2047: (DEC, 8), + 2048: (NOV, 26), + 2049: (NOV, 16), + 2050: (NOV, 5), + 2051: (OCT, 25), + 2052: (OCT, 13), + 2053: (OCT, 2), + 2054: (SEP, 22), + 2055: (SEP, 12), + 2056: (AUG, 31), + 2057: (AUG, 20), + 2058: (AUG, 9), + 2059: (JUL, 30), + 2060: (JUL, 18), + 2061: (JUL, 8), + 2062: (JUN, 27), + 2063: (JUN, 17), + 2064: (JUN, 5), + 2065: (MAY, 25), + 2066: (MAY, 14), + 2067: (MAY, 4), + 2068: (APR, 22), + 2069: (APR, 12), + 2070: (APR, 2), + 2071: (MAR, 22), + 2072: (MAR, 10), + 2073: (FEB, 27), + 2074: (FEB, 16), + 2075: (FEB, 6), + 2076: (JAN, 26), + 2077: (JAN, 15), + } + + ASHURA_DATES = { + 1924: (AUG, 10), + 1925: (AUG, 1), + 1926: (JUL, 20), + 1927: (JUL, 10), + 1928: (JUN, 28), + 1929: (JUN, 17), + 1930: (JUN, 6), + 1931: (MAY, 28), + 1932: (MAY, 16), + 1933: (MAY, 5), + 1934: (APR, 24), + 1935: (APR, 14), + 1936: (APR, 2), + 1937: (MAR, 23), + 1938: (MAR, 11), + 1939: (MAR, 1), + 1940: (FEB, 18), + 1941: (FEB, 6), + 1942: (JAN, 27), + 1943: (JAN, 16), + 1944: ((JAN, 5), (DEC, 25)), + 1945: (DEC, 14), + 1946: (DEC, 4), + 1947: (NOV, 23), + 1948: (NOV, 11), + 1949: (NOV, 1), + 1950: (OCT, 22), + 1951: (OCT, 11), + 1952: (SEP, 30), + 1953: (SEP, 19), + 1954: (SEP, 8), + 1955: (AUG, 29), + 1956: (AUG, 17), + 1957: (AUG, 6), + 1958: (JUL, 27), + 1959: (JUL, 16), + 1960: (JUL, 4), + 1961: (JUN, 23), + 1962: (JUN, 12), + 1963: (JUN, 2), + 1964: (MAY, 21), + 1965: (MAY, 10), + 1966: (APR, 30), + 1967: (APR, 20), + 1968: (APR, 8), + 1969: (MAR, 28), + 1970: (MAR, 18), + 1971: (MAR, 7), + 1972: (FEB, 25), + 1973: (FEB, 13), + 1974: (FEB, 2), + 1975: (JAN, 22), + 1976: ((JAN, 11), (DEC, 31)), + 1977: (DEC, 20), + 1978: (DEC, 10), + 1979: (NOV, 29), + 1980: (NOV, 18), + 1981: (NOV, 6), + 1982: (OCT, 27), + 1983: (OCT, 16), + 1984: (OCT, 5), + 1985: (SEP, 24), + 1986: (SEP, 14), + 1987: (SEP, 3), + 1988: (AUG, 22), + 1989: (AUG, 11), + 1990: (AUG, 1), + 1991: (JUL, 21), + 1992: (JUL, 10), + 1993: (JUN, 30), + 1994: (JUN, 19), + 1995: (JUN, 8), + 1996: (MAY, 27), + 1997: (MAY, 16), + 1998: (MAY, 6), + 1999: (APR, 26), + 2000: (APR, 15), + 2001: (APR, 4), + 2002: (MAR, 24), + 2003: (MAR, 13), + 2004: (MAR, 1), + 2005: (FEB, 19), + 2006: (FEB, 9), + 2007: (JAN, 29), + 2008: (JAN, 19), + 2009: ((JAN, 7), (DEC, 27)), + 2010: (DEC, 16), + 2011: (DEC, 5), + 2012: (NOV, 24), + 2013: (NOV, 13), + 2014: (NOV, 3), + 2015: (OCT, 23), + 2016: (OCT, 11), + 2017: (SEP, 30), + 2018: (SEP, 20), + 2019: (SEP, 9), + 2020: (AUG, 29), + 2021: (AUG, 18), + 2022: (AUG, 8), + 2023: (JUL, 28), + 2024: (JUL, 16), + 2025: (JUL, 5), + 2026: (JUN, 25), + 2027: (JUN, 15), + 2028: (JUN, 3), + 2029: (MAY, 23), + 2030: (MAY, 12), + 2031: (MAY, 2), + 2032: (APR, 20), + 2033: (APR, 10), + 2034: (MAR, 30), + 2035: (MAR, 20), + 2036: (MAR, 8), + 2037: (FEB, 25), + 2038: (FEB, 14), + 2039: (FEB, 4), + 2040: (JAN, 24), + 2041: (JAN, 13), + 2042: ((JAN, 2), (DEC, 23)), + 2043: (DEC, 12), + 2044: (NOV, 30), + 2045: (NOV, 19), + 2046: (NOV, 9), + 2047: (OCT, 29), + 2048: (OCT, 18), + 2049: (OCT, 7), + 2050: (SEP, 26), + 2051: (SEP, 15), + 2052: (SEP, 4), + 2053: (AUG, 24), + 2054: (AUG, 14), + 2055: (AUG, 3), + 2056: (JUL, 23), + 2057: (JUL, 12), + 2058: (JUL, 1), + 2059: (JUN, 20), + 2060: (JUN, 9), + 2061: (MAY, 29), + 2062: (MAY, 19), + 2063: (MAY, 9), + 2064: (APR, 27), + 2065: (APR, 16), + 2066: (APR, 5), + 2067: (MAR, 25), + 2068: (MAR, 14), + 2069: (MAR, 4), + 2070: (FEB, 21), + 2071: (FEB, 10), + 2072: (JAN, 30), + 2073: (JAN, 18), + 2074: ((JAN, 8), (DEC, 28)), + 2075: (DEC, 18), + 2076: (DEC, 6), + } + + EID_AL_ADHA_DATES = { + 1925: (JUL, 2), + 1926: (JUN, 21), + 1927: (JUN, 10), + 1928: (MAY, 30), + 1929: (MAY, 19), + 1930: (MAY, 9), + 1931: (APR, 28), + 1932: (APR, 16), + 1933: (APR, 5), + 1934: (MAR, 26), + 1935: (MAR, 15), + 1936: (MAR, 4), + 1937: (FEB, 21), + 1938: (FEB, 10), + 1939: (JAN, 30), + 1940: (JAN, 20), + 1941: ((JAN, 8), (DEC, 28)), + 1942: (DEC, 18), + 1943: (DEC, 7), + 1944: (NOV, 25), + 1945: (NOV, 15), + 1946: (NOV, 4), + 1947: (OCT, 25), + 1948: (OCT, 13), + 1949: (OCT, 2), + 1950: (SEP, 23), + 1951: (SEP, 12), + 1952: (AUG, 31), + 1953: (AUG, 20), + 1954: (AUG, 9), + 1955: (JUL, 30), + 1956: (JUL, 19), + 1957: (JUL, 8), + 1958: (JUN, 27), + 1959: (JUN, 17), + 1960: (JUN, 4), + 1961: (MAY, 25), + 1962: (MAY, 14), + 1963: (MAY, 3), + 1964: (APR, 22), + 1965: (APR, 11), + 1966: (APR, 1), + 1967: (MAR, 21), + 1968: (MAR, 9), + 1969: (FEB, 27), + 1970: (FEB, 16), + 1971: (FEB, 6), + 1972: (JAN, 26), + 1973: (JAN, 14), + 1974: ((JAN, 3), (DEC, 24)), + 1975: (DEC, 13), + 1976: (DEC, 1), + 1977: (NOV, 21), + 1978: (NOV, 10), + 1979: (OCT, 31), + 1980: (OCT, 19), + 1981: (OCT, 8), + 1982: (SEP, 27), + 1983: (SEP, 17), + 1984: (SEP, 5), + 1985: (AUG, 26), + 1986: (AUG, 15), + 1987: (AUG, 4), + 1988: (JUL, 23), + 1989: (JUL, 13), + 1990: (JUL, 2), + 1991: (JUN, 22), + 1992: (JUN, 11), + 1993: (MAY, 31), + 1994: (MAY, 20), + 1995: (MAY, 9), + 1996: (APR, 27), + 1997: (APR, 17), + 1998: (APR, 7), + 1999: (MAR, 27), + 2000: (MAR, 16), + 2001: (MAR, 5), + 2002: (FEB, 22), + 2003: (FEB, 11), + 2004: (FEB, 1), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 27), + 2010: (NOV, 16), + 2011: (NOV, 6), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 23), + 2016: (SEP, 11), + 2017: (SEP, 1), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + 2026: (MAY, 27), + 2027: (MAY, 16), + 2028: (MAY, 5), + 2029: (APR, 24), + 2030: (APR, 13), + 2031: (APR, 2), + 2032: (MAR, 22), + 2033: (MAR, 11), + 2034: (MAR, 1), + 2035: (FEB, 18), + 2036: (FEB, 7), + 2037: (JAN, 26), + 2038: (JAN, 16), + 2039: ((JAN, 5), (DEC, 26)), + 2040: (DEC, 14), + 2041: (DEC, 4), + 2042: (NOV, 23), + 2043: (NOV, 12), + 2044: (OCT, 31), + 2045: (OCT, 21), + 2046: (OCT, 10), + 2047: (SEP, 30), + 2048: (SEP, 19), + 2049: (SEP, 8), + 2050: (AUG, 28), + 2051: (AUG, 17), + 2052: (AUG, 5), + 2053: (JUL, 26), + 2054: (JUL, 15), + 2055: (JUL, 5), + 2056: (JUN, 23), + 2057: (JUN, 12), + 2058: (JUN, 1), + 2059: (MAY, 22), + 2060: (MAY, 10), + 2061: (APR, 30), + 2062: (APR, 20), + 2063: (APR, 9), + 2064: (MAR, 28), + 2065: (MAR, 17), + 2066: (MAR, 6), + 2067: (FEB, 24), + 2068: (FEB, 13), + 2069: (FEB, 2), + 2070: (JAN, 22), + 2071: ((JAN, 11), (DEC, 31)), + 2072: (DEC, 20), + 2073: (DEC, 9), + 2074: (NOV, 29), + 2075: (NOV, 18), + 2076: (NOV, 7), + 2077: (OCT, 27), + } + + EID_AL_FITR_DATES = { + 1925: (APR, 24), + 1926: (APR, 14), + 1927: (APR, 3), + 1928: (MAR, 22), + 1929: (MAR, 12), + 1930: (MAR, 1), + 1931: (FEB, 19), + 1932: (FEB, 8), + 1933: (JAN, 27), + 1934: (JAN, 17), + 1935: ((JAN, 7), (DEC, 27)), + 1936: (DEC, 15), + 1937: (DEC, 4), + 1938: (NOV, 23), + 1939: (NOV, 12), + 1940: (NOV, 1), + 1941: (OCT, 21), + 1942: (OCT, 11), + 1943: (SEP, 30), + 1944: (SEP, 18), + 1945: (SEP, 7), + 1946: (AUG, 28), + 1947: (AUG, 18), + 1948: (AUG, 6), + 1949: (JUL, 26), + 1950: (JUL, 16), + 1951: (JUL, 6), + 1952: (JUN, 23), + 1953: (JUN, 13), + 1954: (JUN, 2), + 1955: (MAY, 23), + 1956: (MAY, 11), + 1957: (MAY, 1), + 1958: (APR, 20), + 1959: (APR, 10), + 1960: (MAR, 28), + 1961: (MAR, 18), + 1962: (MAR, 7), + 1963: (FEB, 24), + 1964: (FEB, 14), + 1965: (FEB, 2), + 1966: (JAN, 22), + 1967: (JAN, 12), + 1968: ((JAN, 1), (DEC, 21)), + 1969: (DEC, 10), + 1970: (NOV, 30), + 1971: (NOV, 19), + 1972: (NOV, 7), + 1973: (OCT, 27), + 1974: (OCT, 16), + 1975: (OCT, 6), + 1976: (SEP, 24), + 1977: (SEP, 14), + 1978: (SEP, 3), + 1979: (AUG, 23), + 1980: (AUG, 12), + 1981: (AUG, 1), + 1982: (JUL, 21), + 1983: (JUL, 11), + 1984: (JUN, 30), + 1985: (JUN, 19), + 1986: (JUN, 8), + 1987: (MAY, 28), + 1988: (MAY, 16), + 1989: (MAY, 6), + 1990: (APR, 26), + 1991: (APR, 15), + 1992: (APR, 4), + 1993: (MAR, 24), + 1994: (MAR, 13), + 1995: (MAR, 2), + 1996: (FEB, 19), + 1997: (FEB, 8), + 1998: (JAN, 29), + 1999: (JAN, 18), + 2000: ((JAN, 8), (DEC, 27)), + 2001: (DEC, 16), + 2002: (DEC, 5), + 2003: (NOV, 25), + 2004: (NOV, 14), + 2005: (NOV, 3), + 2006: (OCT, 23), + 2007: (OCT, 13), + 2008: (OCT, 1), + 2009: (SEP, 20), + 2010: (SEP, 10), + 2011: (AUG, 30), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 6), + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + 2026: (MAR, 20), + 2027: (MAR, 9), + 2028: (FEB, 26), + 2029: (FEB, 14), + 2030: (FEB, 4), + 2031: (JAN, 24), + 2032: (JAN, 14), + 2033: ((JAN, 2), (DEC, 23)), + 2034: (DEC, 12), + 2035: (DEC, 1), + 2036: (NOV, 19), + 2037: (NOV, 8), + 2038: (OCT, 29), + 2039: (OCT, 19), + 2040: (OCT, 7), + 2041: (SEP, 26), + 2042: (SEP, 15), + 2043: (SEP, 4), + 2044: (AUG, 24), + 2045: (AUG, 14), + 2046: (AUG, 3), + 2047: (JUL, 24), + 2048: (JUL, 12), + 2049: (JUL, 1), + 2050: (JUN, 20), + 2051: (JUN, 10), + 2052: (MAY, 29), + 2053: (MAY, 19), + 2054: (MAY, 9), + 2055: (APR, 28), + 2056: (APR, 16), + 2057: (APR, 5), + 2058: (MAR, 25), + 2059: (MAR, 15), + 2060: (MAR, 4), + 2061: (FEB, 21), + 2062: (FEB, 10), + 2063: (JAN, 30), + 2064: (JAN, 20), + 2065: ((JAN, 8), (DEC, 28)), + 2066: (DEC, 18), + 2067: (DEC, 8), + 2068: (NOV, 26), + 2069: (NOV, 15), + 2070: (NOV, 4), + 2071: (OCT, 24), + 2072: (OCT, 13), + 2073: (OCT, 2), + 2074: (SEP, 22), + 2075: (SEP, 11), + 2076: (AUG, 30), + 2077: (AUG, 19), + } + + EID_AL_GHADIR_DATES = { + 1925: (JUL, 10), + 1926: (JUN, 29), + 1927: (JUN, 18), + 1928: (JUN, 7), + 1929: (MAY, 27), + 1930: (MAY, 17), + 1931: (MAY, 6), + 1932: (APR, 24), + 1933: (APR, 13), + 1934: (APR, 3), + 1935: (MAR, 23), + 1936: (MAR, 12), + 1937: (MAR, 1), + 1938: (FEB, 18), + 1939: (FEB, 7), + 1940: (JAN, 28), + 1941: (JAN, 16), + 1942: ((JAN, 5), (DEC, 26)), + 1943: (DEC, 15), + 1944: (DEC, 3), + 1945: (NOV, 23), + 1946: (NOV, 12), + 1947: (NOV, 2), + 1948: (OCT, 21), + 1949: (OCT, 10), + 1950: (OCT, 1), + 1951: (SEP, 20), + 1952: (SEP, 8), + 1953: (AUG, 28), + 1954: (AUG, 17), + 1955: (AUG, 7), + 1956: (JUL, 27), + 1957: (JUL, 16), + 1958: (JUL, 5), + 1959: (JUN, 25), + 1960: (JUN, 12), + 1961: (JUN, 2), + 1962: (MAY, 22), + 1963: (MAY, 11), + 1964: (APR, 30), + 1965: (APR, 19), + 1966: (APR, 9), + 1967: (MAR, 29), + 1968: (MAR, 17), + 1969: (MAR, 7), + 1970: (FEB, 24), + 1971: (FEB, 14), + 1972: (FEB, 3), + 1973: (JAN, 22), + 1974: (JAN, 11), + 1975: ((JAN, 1), (DEC, 21)), + 1976: (DEC, 9), + 1977: (NOV, 29), + 1978: (NOV, 18), + 1979: (NOV, 8), + 1980: (OCT, 27), + 1981: (OCT, 16), + 1982: (OCT, 5), + 1983: (SEP, 25), + 1984: (SEP, 13), + 1985: (SEP, 3), + 1986: (AUG, 23), + 1987: (AUG, 12), + 1988: (JUL, 31), + 1989: (JUL, 21), + 1990: (JUL, 10), + 1991: (JUN, 30), + 1992: (JUN, 19), + 1993: (JUN, 8), + 1994: (MAY, 28), + 1995: (MAY, 17), + 1996: (MAY, 5), + 1997: (APR, 25), + 1998: (APR, 15), + 1999: (APR, 4), + 2000: (MAR, 24), + 2001: (MAR, 13), + 2002: (MAR, 2), + 2003: (FEB, 19), + 2004: (FEB, 9), + 2005: (JAN, 29), + 2006: (JAN, 18), + 2007: ((JAN, 8), (DEC, 28)), + 2008: (DEC, 16), + 2009: (DEC, 5), + 2010: (NOV, 24), + 2011: (NOV, 14), + 2012: (NOV, 3), + 2013: (OCT, 23), + 2014: (OCT, 12), + 2015: (OCT, 1), + 2016: (SEP, 19), + 2017: (SEP, 9), + 2018: (AUG, 29), + 2019: (AUG, 19), + 2020: (AUG, 8), + 2021: (JUL, 28), + 2022: (JUL, 17), + 2023: (JUL, 6), + 2024: (JUN, 24), + 2025: (JUN, 14), + 2026: (JUN, 4), + 2027: (MAY, 24), + 2028: (MAY, 13), + 2029: (MAY, 2), + 2030: (APR, 21), + 2031: (APR, 10), + 2032: (MAR, 30), + 2033: (MAR, 19), + 2034: (MAR, 9), + 2035: (FEB, 26), + 2036: (FEB, 15), + 2037: (FEB, 3), + 2038: (JAN, 24), + 2039: (JAN, 13), + 2040: ((JAN, 3), (DEC, 22)), + 2041: (DEC, 12), + 2042: (DEC, 1), + 2043: (NOV, 20), + 2044: (NOV, 8), + 2045: (OCT, 29), + 2046: (OCT, 18), + 2047: (OCT, 8), + 2048: (SEP, 27), + 2049: (SEP, 16), + 2050: (SEP, 5), + 2051: (AUG, 25), + 2052: (AUG, 13), + 2053: (AUG, 3), + 2054: (JUL, 23), + 2055: (JUL, 13), + 2056: (JUL, 1), + 2057: (JUN, 20), + 2058: (JUN, 9), + 2059: (MAY, 30), + 2060: (MAY, 18), + 2061: (MAY, 8), + 2062: (APR, 28), + 2063: (APR, 17), + 2064: (APR, 5), + 2065: (MAR, 25), + 2066: (MAR, 14), + 2067: (MAR, 4), + 2068: (FEB, 21), + 2069: (FEB, 10), + 2070: (JAN, 30), + 2071: (JAN, 19), + 2072: ((JAN, 8), (DEC, 28)), + 2073: (DEC, 17), + 2074: (DEC, 7), + 2075: (NOV, 26), + 2076: (NOV, 15), + 2077: (NOV, 4), + } + + FATIMA_DEATH_DATES = { + 1924: (DEC, 29), + 1925: (DEC, 19), + 1926: (DEC, 9), + 1927: (NOV, 27), + 1928: (NOV, 15), + 1929: (NOV, 5), + 1930: (OCT, 25), + 1931: (OCT, 15), + 1932: (OCT, 4), + 1933: (SEP, 23), + 1934: (SEP, 12), + 1935: (SEP, 1), + 1936: (AUG, 21), + 1937: (AUG, 10), + 1938: (JUL, 30), + 1939: (JUL, 20), + 1940: (JUL, 9), + 1941: (JUN, 27), + 1942: (JUN, 17), + 1943: (JUN, 6), + 1944: (MAY, 25), + 1945: (MAY, 15), + 1946: (MAY, 4), + 1947: (APR, 24), + 1948: (APR, 12), + 1949: (APR, 1), + 1950: (MAR, 22), + 1951: (MAR, 12), + 1952: (FEB, 28), + 1953: (FEB, 17), + 1954: (FEB, 6), + 1955: (JAN, 27), + 1956: (JAN, 17), + 1957: ((JAN, 4), (DEC, 24)), + 1958: (DEC, 15), + 1959: (DEC, 3), + 1960: (NOV, 22), + 1961: (NOV, 11), + 1962: (OCT, 31), + 1963: (OCT, 21), + 1964: (OCT, 9), + 1965: (SEP, 28), + 1966: (SEP, 18), + 1967: (SEP, 7), + 1968: (AUG, 27), + 1969: (AUG, 16), + 1970: (AUG, 6), + 1971: (JUL, 26), + 1972: (JUL, 14), + 1973: (JUL, 3), + 1974: (JUN, 23), + 1975: (JUN, 12), + 1976: (JUN, 1), + 1977: (MAY, 21), + 1978: (MAY, 10), + 1979: (APR, 29), + 1980: (APR, 18), + 1981: (APR, 7), + 1982: (MAR, 28), + 1983: (MAR, 17), + 1984: (MAR, 5), + 1985: (FEB, 22), + 1986: (FEB, 12), + 1987: (FEB, 1), + 1988: (JAN, 22), + 1989: ((JAN, 10), (DEC, 31)), + 1990: (DEC, 20), + 1991: (DEC, 9), + 1992: (NOV, 27), + 1993: (NOV, 16), + 1994: (NOV, 6), + 1995: (OCT, 27), + 1996: (OCT, 15), + 1997: (OCT, 4), + 1998: (SEP, 23), + 1999: (SEP, 13), + 2000: (SEP, 1), + 2001: (AUG, 22), + 2002: (AUG, 12), + 2003: (AUG, 1), + 2004: (JUL, 20), + 2005: (JUL, 9), + 2006: (JUN, 29), + 2007: (JUN, 18), + 2008: (JUN, 7), + 2009: (MAY, 27), + 2010: (MAY, 17), + 2011: (MAY, 6), + 2012: (APR, 24), + 2013: (APR, 13), + 2014: (APR, 3), + 2015: (MAR, 23), + 2016: (MAR, 12), + 2017: (MAR, 2), + 2018: (FEB, 19), + 2019: (FEB, 8), + 2020: (JAN, 28), + 2021: (JAN, 16), + 2022: ((JAN, 6), (DEC, 27)), + 2023: (DEC, 16), + 2024: (DEC, 4), + 2025: (NOV, 24), + 2026: (NOV, 13), + 2027: (NOV, 2), + 2028: (OCT, 21), + 2029: (OCT, 11), + 2030: (OCT, 1), + 2031: (SEP, 20), + 2032: (SEP, 8), + 2033: (AUG, 28), + 2034: (AUG, 17), + 2035: (AUG, 7), + 2036: (JUL, 26), + 2037: (JUL, 16), + 2038: (JUL, 5), + 2039: (JUN, 25), + 2040: (JUN, 13), + 2041: (JUN, 2), + 2042: (MAY, 22), + 2043: (MAY, 12), + 2044: (MAY, 1), + 2045: (APR, 20), + 2046: (APR, 9), + 2047: (MAR, 29), + 2048: (MAR, 18), + 2049: (MAR, 7), + 2050: (FEB, 25), + 2051: (FEB, 14), + 2052: (FEB, 4), + 2053: (JAN, 23), + 2054: (JAN, 12), + 2055: ((JAN, 1), (DEC, 21)), + 2056: (DEC, 10), + 2057: (NOV, 29), + 2058: (NOV, 19), + 2059: (NOV, 8), + 2060: (OCT, 27), + 2061: (OCT, 17), + 2062: (OCT, 6), + 2063: (SEP, 26), + 2064: (SEP, 14), + 2065: (SEP, 4), + 2066: (AUG, 24), + 2067: (AUG, 13), + 2068: (AUG, 1), + 2069: (JUL, 22), + 2070: (JUL, 11), + 2071: (JUL, 1), + 2072: (JUN, 19), + 2073: (JUN, 9), + 2074: (MAY, 29), + 2075: (MAY, 18), + 2076: (MAY, 6), + 2077: (APR, 26), + } + + GRAND_MAGAL_OF_TOUBA_DATES = { + 1924: (SEP, 17), + 1925: (SEP, 7), + 1926: (AUG, 27), + 1927: (AUG, 16), + 1928: (AUG, 4), + 1929: (JUL, 25), + 1930: (JUL, 14), + 1931: (JUL, 4), + 1932: (JUN, 23), + 1933: (JUN, 12), + 1934: (JUN, 1), + 1935: (MAY, 21), + 1936: (MAY, 10), + 1937: (APR, 29), + 1938: (APR, 18), + 1939: (APR, 8), + 1940: (MAR, 27), + 1941: (MAR, 16), + 1942: (MAR, 6), + 1943: (FEB, 23), + 1944: (FEB, 12), + 1945: (FEB, 1), + 1946: (JAN, 21), + 1947: ((JAN, 11), (DEC, 31)), + 1948: (DEC, 19), + 1949: (DEC, 9), + 1950: (NOV, 29), + 1951: (NOV, 18), + 1952: (NOV, 6), + 1953: (OCT, 26), + 1954: (OCT, 16), + 1955: (OCT, 6), + 1956: (SEP, 23), + 1957: (SEP, 13), + 1958: (SEP, 3), + 1959: (AUG, 22), + 1960: (AUG, 11), + 1961: (JUL, 31), + 1962: (JUL, 20), + 1963: (JUL, 9), + 1964: (JUN, 28), + 1965: (JUN, 17), + 1966: (JUN, 7), + 1967: (MAY, 27), + 1968: (MAY, 15), + 1969: (MAY, 5), + 1970: (APR, 25), + 1971: (APR, 14), + 1972: (APR, 2), + 1973: (MAR, 23), + 1974: (MAR, 12), + 1975: (MAR, 1), + 1976: (FEB, 18), + 1977: (FEB, 6), + 1978: (JAN, 27), + 1979: (JAN, 16), + 1980: ((JAN, 6), (DEC, 25)), + 1981: (DEC, 14), + 1982: (DEC, 3), + 1983: (NOV, 22), + 1984: (NOV, 11), + 1985: (NOV, 1), + 1986: (OCT, 21), + 1987: (OCT, 11), + 1988: (SEP, 29), + 1989: (SEP, 18), + 1990: (SEP, 7), + 1991: (AUG, 28), + 1992: (AUG, 16), + 1993: (AUG, 6), + 1994: (JUL, 26), + 1995: (JUL, 16), + 1996: (JUL, 4), + 1997: (JUN, 23), + 1998: (JUN, 12), + 1999: (JUN, 2), + 2000: (MAY, 22), + 2001: (MAY, 12), + 2002: (MAY, 1), + 2003: (APR, 20), + 2004: (APR, 8), + 2005: (MAR, 28), + 2006: (MAR, 18), + 2007: (MAR, 8), + 2008: (FEB, 25), + 2009: (FEB, 13), + 2010: (FEB, 2), + 2011: (JAN, 22), + 2012: ((JAN, 12), (DEC, 31)), + 2013: (DEC, 21), + 2014: (DEC, 10), + 2015: (NOV, 30), + 2016: (NOV, 18), + 2017: (NOV, 7), + 2018: (OCT, 27), + 2019: (OCT, 17), + 2020: (OCT, 5), + 2021: (SEP, 25), + 2022: (SEP, 14), + 2023: (SEP, 3), + 2024: (AUG, 22), + 2025: (AUG, 12), + 2026: (AUG, 1), + 2027: (JUL, 22), + 2028: (JUL, 11), + 2029: (JUN, 30), + 2030: (JUN, 19), + 2031: (JUN, 8), + 2032: (MAY, 27), + 2033: (MAY, 17), + 2034: (MAY, 7), + 2035: (APR, 26), + 2036: (APR, 15), + 2037: (APR, 4), + 2038: (MAR, 24), + 2039: (MAR, 13), + 2040: (MAR, 2), + 2041: (FEB, 19), + 2042: (FEB, 9), + 2043: (JAN, 29), + 2044: (JAN, 19), + 2045: ((JAN, 7), (DEC, 27)), + 2046: (DEC, 16), + 2047: (DEC, 6), + 2048: (NOV, 24), + 2049: (NOV, 14), + 2050: (NOV, 3), + 2051: (OCT, 23), + 2052: (OCT, 11), + 2053: (SEP, 30), + 2054: (SEP, 20), + 2055: (SEP, 10), + 2056: (AUG, 29), + 2057: (AUG, 18), + 2058: (AUG, 7), + 2059: (JUL, 28), + 2060: (JUL, 16), + 2061: (JUL, 6), + 2062: (JUN, 25), + 2063: (JUN, 15), + 2064: (JUN, 3), + 2065: (MAY, 23), + 2066: (MAY, 12), + 2067: (MAY, 2), + 2068: (APR, 20), + 2069: (APR, 10), + 2070: (MAR, 31), + 2071: (MAR, 20), + 2072: (MAR, 8), + 2073: (FEB, 25), + 2074: (FEB, 14), + 2075: (FEB, 4), + 2076: (JAN, 24), + 2077: (JAN, 13), + } + + HARI_HOL_JOHOR_DATES = { + 1924: (SEP, 5), + 1925: (AUG, 26), + 1926: (AUG, 15), + 1927: (AUG, 4), + 1928: (JUL, 23), + 1929: (JUL, 13), + 1930: (JUL, 2), + 1931: (JUN, 22), + 1932: (JUN, 11), + 1933: (MAY, 31), + 1934: (MAY, 20), + 1935: (MAY, 9), + 1936: (APR, 28), + 1937: (APR, 17), + 1938: (APR, 6), + 1939: (MAR, 27), + 1940: (MAR, 15), + 1941: (MAR, 4), + 1942: (FEB, 22), + 1943: (FEB, 11), + 1944: (JAN, 31), + 1945: (JAN, 20), + 1946: ((JAN, 9), (DEC, 30)), + 1947: (DEC, 19), + 1948: (DEC, 7), + 1949: (NOV, 27), + 1950: (NOV, 17), + 1951: (NOV, 6), + 1952: (OCT, 25), + 1953: (OCT, 14), + 1954: (OCT, 4), + 1955: (SEP, 24), + 1956: (SEP, 11), + 1957: (SEP, 1), + 1958: (AUG, 22), + 1959: (AUG, 10), + 1960: (JUL, 30), + 1961: (JUL, 19), + 1962: (JUL, 8), + 1963: (JUN, 27), + 1964: (JUN, 16), + 1965: (JUN, 5), + 1966: (MAY, 26), + 1967: (MAY, 15), + 1968: (MAY, 3), + 1969: (APR, 23), + 1970: (APR, 13), + 1971: (APR, 2), + 1972: (MAR, 21), + 1973: (MAR, 11), + 1974: (FEB, 28), + 1975: (FEB, 17), + 1976: (FEB, 6), + 1977: (JAN, 25), + 1978: (JAN, 15), + 1979: ((JAN, 4), (DEC, 25)), + 1980: (DEC, 13), + 1981: (DEC, 2), + 1982: (NOV, 21), + 1983: (NOV, 10), + 1984: (OCT, 30), + 1985: (OCT, 20), + 1986: (OCT, 9), + 1987: (SEP, 29), + 1988: (SEP, 17), + 1989: (SEP, 6), + 1990: (AUG, 26), + 1991: (AUG, 16), + 1992: (AUG, 4), + 1993: (JUL, 25), + 1994: (JUL, 14), + 1995: (JUL, 4), + 1996: (JUN, 22), + 1997: (JUN, 11), + 1998: (MAY, 31), + 1999: (MAY, 21), + 2000: (MAY, 10), + 2001: (APR, 30), + 2002: (APR, 19), + 2003: (APR, 8), + 2004: (MAR, 27), + 2005: (MAR, 16), + 2006: (MAR, 6), + 2007: (FEB, 24), + 2008: (FEB, 13), + 2009: (FEB, 1), + 2010: (JAN, 21), + 2011: ((JAN, 10), (DEC, 31)), + 2012: (DEC, 19), + 2013: (DEC, 9), + 2014: (NOV, 28), + 2015: (NOV, 18), + 2016: (NOV, 6), + 2017: (OCT, 26), + 2018: (OCT, 15), + 2019: (OCT, 5), + 2020: (SEP, 23), + 2021: (SEP, 13), + 2022: (SEP, 2), + 2023: (AUG, 22), + 2024: (AUG, 10), + 2025: (JUL, 31), + 2026: (JUL, 20), + 2027: (JUL, 10), + 2028: (JUN, 29), + 2029: (JUN, 18), + 2030: (JUN, 7), + 2031: (MAY, 27), + 2032: (MAY, 15), + 2033: (MAY, 5), + 2034: (APR, 25), + 2035: (APR, 14), + 2036: (APR, 3), + 2037: (MAR, 23), + 2038: (MAR, 12), + 2039: (MAR, 1), + 2040: (FEB, 19), + 2041: (FEB, 7), + 2042: (JAN, 28), + 2043: (JAN, 17), + 2044: ((JAN, 7), (DEC, 26)), + 2045: (DEC, 15), + 2046: (DEC, 4), + 2047: (NOV, 24), + 2048: (NOV, 12), + 2049: (NOV, 2), + 2050: (OCT, 22), + 2051: (OCT, 11), + 2052: (SEP, 29), + 2053: (SEP, 18), + 2054: (SEP, 8), + 2055: (AUG, 29), + 2056: (AUG, 17), + 2057: (AUG, 6), + 2058: (JUL, 26), + 2059: (JUL, 16), + 2060: (JUL, 4), + 2061: (JUN, 24), + 2062: (JUN, 13), + 2063: (JUN, 3), + 2064: (MAY, 22), + 2065: (MAY, 11), + 2066: (APR, 30), + 2067: (APR, 20), + 2068: (APR, 8), + 2069: (MAR, 29), + 2070: (MAR, 19), + 2071: (MAR, 8), + 2072: (FEB, 25), + 2073: (FEB, 13), + 2074: (FEB, 2), + 2075: (JAN, 23), + 2076: (JAN, 12), + 2077: (JAN, 1), + } + + HASAN_AL_ASKARI_DEATH_DATES = { + 1924: (OCT, 6), + 1925: (SEP, 26), + 1926: (SEP, 15), + 1927: (SEP, 4), + 1928: (AUG, 23), + 1929: (AUG, 13), + 1930: (AUG, 2), + 1931: (JUL, 24), + 1932: (JUL, 12), + 1933: (JUL, 1), + 1934: (JUN, 20), + 1935: (JUN, 10), + 1936: (MAY, 29), + 1937: (MAY, 18), + 1938: (MAY, 7), + 1939: (APR, 28), + 1940: (APR, 16), + 1941: (APR, 4), + 1942: (MAR, 25), + 1943: (MAR, 14), + 1944: (MAR, 2), + 1945: (FEB, 20), + 1946: (FEB, 9), + 1947: (JAN, 30), + 1948: (JAN, 19), + 1949: ((JAN, 7), (DEC, 28)), + 1950: (DEC, 18), + 1951: (DEC, 7), + 1952: (NOV, 26), + 1953: (NOV, 15), + 1954: (NOV, 4), + 1955: (OCT, 25), + 1956: (OCT, 13), + 1957: (OCT, 2), + 1958: (SEP, 22), + 1959: (SEP, 11), + 1960: (AUG, 30), + 1961: (AUG, 19), + 1962: (AUG, 8), + 1963: (JUL, 29), + 1964: (JUL, 17), + 1965: (JUL, 6), + 1966: (JUN, 27), + 1967: (JUN, 15), + 1968: (JUN, 4), + 1969: (MAY, 24), + 1970: (MAY, 14), + 1971: (MAY, 3), + 1972: (APR, 21), + 1973: (APR, 11), + 1974: (MAR, 31), + 1975: (MAR, 20), + 1976: (MAR, 8), + 1977: (FEB, 26), + 1978: (FEB, 15), + 1979: (FEB, 5), + 1980: (JAN, 26), + 1981: (JAN, 14), + 1982: ((JAN, 3), (DEC, 23)), + 1983: (DEC, 12), + 1984: (NOV, 30), + 1985: (NOV, 20), + 1986: (NOV, 10), + 1987: (OCT, 30), + 1988: (OCT, 18), + 1989: (OCT, 7), + 1990: (SEP, 27), + 1991: (SEP, 16), + 1992: (SEP, 5), + 1993: (AUG, 25), + 1994: (AUG, 15), + 1995: (AUG, 4), + 1996: (JUL, 23), + 1997: (JUL, 12), + 1998: (JUL, 2), + 1999: (JUN, 22), + 2000: (JUN, 10), + 2001: (MAY, 31), + 2002: (MAY, 20), + 2003: (MAY, 9), + 2004: (APR, 27), + 2005: (APR, 17), + 2006: (APR, 6), + 2007: (MAR, 27), + 2008: (MAR, 16), + 2009: (MAR, 5), + 2010: (FEB, 22), + 2011: (FEB, 11), + 2012: (JAN, 31), + 2013: (JAN, 20), + 2014: ((JAN, 9), (DEC, 30)), + 2015: (DEC, 19), + 2016: (DEC, 7), + 2017: (NOV, 26), + 2018: (NOV, 16), + 2019: (NOV, 5), + 2020: (OCT, 25), + 2021: (OCT, 14), + 2022: (OCT, 4), + 2023: (SEP, 23), + 2024: (SEP, 11), + 2025: (AUG, 31), + 2026: (AUG, 21), + 2027: (AUG, 10), + 2028: (JUL, 30), + 2029: (JUL, 20), + 2030: (JUL, 9), + 2031: (JUN, 28), + 2032: (JUN, 16), + 2033: (JUN, 5), + 2034: (MAY, 26), + 2035: (MAY, 16), + 2036: (MAY, 4), + 2037: (APR, 24), + 2038: (APR, 13), + 2039: (APR, 2), + 2040: (MAR, 21), + 2041: (MAR, 11), + 2042: (FEB, 28), + 2043: (FEB, 18), + 2044: (FEB, 7), + 2045: (JAN, 26), + 2046: (JAN, 15), + 2047: ((JAN, 4), (DEC, 25)), + 2048: (DEC, 14), + 2049: (DEC, 3), + 2050: (NOV, 22), + 2051: (NOV, 12), + 2052: (OCT, 31), + 2053: (OCT, 20), + 2054: (OCT, 9), + 2055: (SEP, 29), + 2056: (SEP, 18), + 2057: (SEP, 7), + 2058: (AUG, 27), + 2059: (AUG, 16), + 2060: (AUG, 4), + 2061: (JUL, 25), + 2062: (JUL, 15), + 2063: (JUL, 4), + 2064: (JUN, 23), + 2065: (JUN, 12), + 2066: (JUN, 1), + 2067: (MAY, 21), + 2068: (MAY, 10), + 2069: (APR, 29), + 2070: (APR, 19), + 2071: (APR, 9), + 2072: (MAR, 28), + 2073: (MAR, 17), + 2074: (MAR, 6), + 2075: (FEB, 23), + 2076: (FEB, 13), + 2077: (FEB, 2), + } + + HIJRI_NEW_YEAR_DATES = { + 1924: (AUG, 1), + 1925: (JUL, 23), + 1926: (JUL, 11), + 1927: (JUL, 1), + 1928: (JUN, 19), + 1929: (JUN, 8), + 1930: (MAY, 28), + 1931: (MAY, 19), + 1932: (MAY, 7), + 1933: (APR, 26), + 1934: (APR, 15), + 1935: (APR, 5), + 1936: (MAR, 24), + 1937: (MAR, 14), + 1938: (MAR, 2), + 1939: (FEB, 20), + 1940: (FEB, 9), + 1941: (JAN, 28), + 1942: (JAN, 18), + 1943: ((JAN, 7), (DEC, 27)), + 1944: (DEC, 16), + 1945: (DEC, 5), + 1946: (NOV, 25), + 1947: (NOV, 14), + 1948: (NOV, 2), + 1949: (OCT, 23), + 1950: (OCT, 13), + 1951: (OCT, 2), + 1952: (SEP, 21), + 1953: (SEP, 10), + 1954: (AUG, 30), + 1955: (AUG, 20), + 1956: (AUG, 8), + 1957: (JUL, 28), + 1958: (JUL, 18), + 1959: (JUL, 7), + 1960: (JUN, 25), + 1961: (JUN, 14), + 1962: (JUN, 3), + 1963: (MAY, 24), + 1964: (MAY, 12), + 1965: (MAY, 1), + 1966: (APR, 21), + 1967: (APR, 11), + 1968: (MAR, 30), + 1969: (MAR, 19), + 1970: (MAR, 9), + 1971: (FEB, 26), + 1972: (FEB, 16), + 1973: (FEB, 4), + 1974: (JAN, 24), + 1975: (JAN, 13), + 1976: ((JAN, 2), (DEC, 22)), + 1977: (DEC, 11), + 1978: (DEC, 1), + 1979: (NOV, 20), + 1980: (NOV, 9), + 1981: (OCT, 28), + 1982: (OCT, 18), + 1983: (OCT, 7), + 1984: (SEP, 26), + 1985: (SEP, 15), + 1986: (SEP, 5), + 1987: (AUG, 25), + 1988: (AUG, 13), + 1989: (AUG, 2), + 1990: (JUL, 23), + 1991: (JUL, 12), + 1992: (JUL, 1), + 1993: (JUN, 21), + 1994: (JUN, 10), + 1995: (MAY, 30), + 1996: (MAY, 18), + 1997: (MAY, 7), + 1998: (APR, 27), + 1999: (APR, 17), + 2000: (APR, 6), + 2001: (MAR, 26), + 2002: (MAR, 15), + 2003: (MAR, 4), + 2004: (FEB, 21), + 2005: (FEB, 10), + 2006: (JAN, 31), + 2007: (JAN, 20), + 2008: ((JAN, 10), (DEC, 29)), + 2009: (DEC, 18), + 2010: (DEC, 7), + 2011: (NOV, 26), + 2012: (NOV, 15), + 2013: (NOV, 4), + 2014: (OCT, 25), + 2015: (OCT, 14), + 2016: (OCT, 2), + 2017: (SEP, 21), + 2018: (SEP, 11), + 2019: (AUG, 31), + 2020: (AUG, 20), + 2021: (AUG, 9), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 7), + 2025: (JUN, 26), + 2026: (JUN, 16), + 2027: (JUN, 6), + 2028: (MAY, 25), + 2029: (MAY, 14), + 2030: (MAY, 3), + 2031: (APR, 23), + 2032: (APR, 11), + 2033: (APR, 1), + 2034: (MAR, 21), + 2035: (MAR, 11), + 2036: (FEB, 28), + 2037: (FEB, 16), + 2038: (FEB, 5), + 2039: (JAN, 26), + 2040: (JAN, 15), + 2041: ((JAN, 4), (DEC, 24)), + 2042: (DEC, 14), + 2043: (DEC, 3), + 2044: (NOV, 21), + 2045: (NOV, 10), + 2046: (OCT, 31), + 2047: (OCT, 20), + 2048: (OCT, 9), + 2049: (SEP, 28), + 2050: (SEP, 17), + 2051: (SEP, 6), + 2052: (AUG, 26), + 2053: (AUG, 15), + 2054: (AUG, 5), + 2055: (JUL, 25), + 2056: (JUL, 14), + 2057: (JUL, 3), + 2058: (JUN, 22), + 2059: (JUN, 11), + 2060: (MAY, 31), + 2061: (MAY, 20), + 2062: (MAY, 10), + 2063: (APR, 30), + 2064: (APR, 18), + 2065: (APR, 7), + 2066: (MAR, 27), + 2067: (MAR, 16), + 2068: (MAR, 5), + 2069: (FEB, 23), + 2070: (FEB, 12), + 2071: (FEB, 1), + 2072: (JAN, 21), + 2073: ((JAN, 9), (DEC, 30)), + 2074: (DEC, 19), + 2075: (DEC, 9), + 2076: (NOV, 27), + } + + IMAM_MAHDI_BIRTHDAY_DATES = { + 1925: (MAR, 11), + 1926: (FEB, 28), + 1927: (FEB, 18), + 1928: (FEB, 7), + 1929: (JAN, 26), + 1930: (JAN, 15), + 1931: ((JAN, 4), (DEC, 25)), + 1932: (DEC, 13), + 1933: (DEC, 3), + 1934: (NOV, 22), + 1935: (NOV, 12), + 1936: (OCT, 31), + 1937: (OCT, 20), + 1938: (OCT, 9), + 1939: (SEP, 29), + 1940: (SEP, 17), + 1941: (SEP, 6), + 1942: (AUG, 27), + 1943: (AUG, 16), + 1944: (AUG, 4), + 1945: (JUL, 25), + 1946: (JUL, 14), + 1947: (JUL, 4), + 1948: (JUN, 22), + 1949: (JUN, 11), + 1950: (JUN, 1), + 1951: (MAY, 22), + 1952: (MAY, 9), + 1953: (APR, 29), + 1954: (APR, 18), + 1955: (APR, 8), + 1956: (MAR, 28), + 1957: (MAR, 17), + 1958: (MAR, 5), + 1959: (FEB, 24), + 1960: (FEB, 12), + 1961: (FEB, 1), + 1962: (JAN, 21), + 1963: ((JAN, 11), (DEC, 31)), + 1964: (DEC, 19), + 1965: (DEC, 8), + 1966: (NOV, 28), + 1967: (NOV, 17), + 1968: (NOV, 6), + 1969: (OCT, 26), + 1970: (OCT, 16), + 1971: (OCT, 5), + 1972: (SEP, 23), + 1973: (SEP, 12), + 1974: (SEP, 2), + 1975: (AUG, 22), + 1976: (AUG, 11), + 1977: (JUL, 31), + 1978: (JUL, 20), + 1979: (JUL, 9), + 1980: (JUN, 28), + 1981: (JUN, 17), + 1982: (JUN, 7), + 1983: (MAY, 27), + 1984: (MAY, 16), + 1985: (MAY, 5), + 1986: (APR, 24), + 1987: (APR, 13), + 1988: (APR, 2), + 1989: (MAR, 22), + 1990: (MAR, 12), + 1991: (MAR, 1), + 1992: (FEB, 18), + 1993: (FEB, 6), + 1994: (JAN, 26), + 1995: (JAN, 16), + 1996: ((JAN, 6), (DEC, 25)), + 1997: (DEC, 15), + 1998: (DEC, 4), + 1999: (NOV, 23), + 2000: (NOV, 11), + 2001: (OCT, 31), + 2002: (OCT, 21), + 2003: (OCT, 11), + 2004: (SEP, 29), + 2005: (SEP, 19), + 2006: (SEP, 8), + 2007: (AUG, 28), + 2008: (AUG, 16), + 2009: (AUG, 6), + 2010: (JUL, 27), + 2011: (JUL, 16), + 2012: (JUL, 5), + 2013: (JUN, 24), + 2014: (JUN, 13), + 2015: (JUN, 2), + 2016: (MAY, 22), + 2017: (MAY, 11), + 2018: (MAY, 1), + 2019: (APR, 20), + 2020: (APR, 8), + 2021: (MAR, 28), + 2022: (MAR, 18), + 2023: (MAR, 7), + 2024: (FEB, 25), + 2025: (FEB, 14), + 2026: (FEB, 3), + 2027: (JAN, 23), + 2028: ((JAN, 12), (DEC, 31)), + 2029: (DEC, 21), + 2030: (DEC, 10), + 2031: (NOV, 30), + 2032: (NOV, 18), + 2033: (NOV, 7), + 2034: (OCT, 27), + 2035: (OCT, 16), + 2036: (OCT, 5), + 2037: (SEP, 25), + 2038: (SEP, 14), + 2039: (SEP, 4), + 2040: (AUG, 23), + 2041: (AUG, 12), + 2042: (AUG, 1), + 2043: (JUL, 22), + 2044: (JUL, 10), + 2045: (JUN, 30), + 2046: (JUN, 19), + 2047: (JUN, 9), + 2048: (MAY, 28), + 2049: (MAY, 17), + 2050: (MAY, 6), + 2051: (APR, 26), + 2052: (APR, 15), + 2053: (APR, 4), + 2054: (MAR, 24), + 2055: (MAR, 13), + 2056: (MAR, 2), + 2057: (FEB, 19), + 2058: (FEB, 8), + 2059: (JAN, 29), + 2060: (JAN, 19), + 2061: ((JAN, 7), (DEC, 27)), + 2062: (DEC, 16), + 2063: (DEC, 6), + 2064: (NOV, 24), + 2065: (NOV, 14), + 2066: (NOV, 3), + 2067: (OCT, 24), + 2068: (OCT, 12), + 2069: (OCT, 1), + 2070: (SEP, 20), + 2071: (SEP, 9), + 2072: (AUG, 29), + 2073: (AUG, 19), + 2074: (AUG, 8), + 2075: (JUL, 28), + 2076: (JUL, 16), + 2077: (JUL, 5), + } + + ISRA_AND_MIRAJ_DATES = { + 1925: (FEB, 21), + 1926: (FEB, 10), + 1927: (JAN, 31), + 1928: (JAN, 20), + 1929: ((JAN, 8), (DEC, 28)), + 1930: (DEC, 17), + 1931: (DEC, 7), + 1932: (NOV, 26), + 1933: (NOV, 15), + 1934: (NOV, 5), + 1935: (OCT, 25), + 1936: (OCT, 13), + 1937: (OCT, 2), + 1938: (SEP, 21), + 1939: (SEP, 11), + 1940: (AUG, 31), + 1941: (AUG, 19), + 1942: (AUG, 9), + 1943: (JUL, 29), + 1944: (JUL, 17), + 1945: (JUL, 7), + 1946: (JUN, 26), + 1947: (JUN, 16), + 1948: (JUN, 4), + 1949: (MAY, 24), + 1950: (MAY, 14), + 1951: (MAY, 4), + 1952: (APR, 22), + 1953: (APR, 12), + 1954: (APR, 1), + 1955: (MAR, 21), + 1956: (MAR, 10), + 1957: (FEB, 27), + 1958: (FEB, 16), + 1959: (FEB, 6), + 1960: (JAN, 26), + 1961: (JAN, 14), + 1962: ((JAN, 4), (DEC, 24)), + 1963: (DEC, 13), + 1964: (DEC, 1), + 1965: (NOV, 20), + 1966: (NOV, 10), + 1967: (OCT, 30), + 1968: (OCT, 19), + 1969: (OCT, 8), + 1970: (SEP, 28), + 1971: (SEP, 17), + 1972: (SEP, 5), + 1973: (AUG, 25), + 1974: (AUG, 15), + 1975: (AUG, 5), + 1976: (JUL, 24), + 1977: (JUL, 13), + 1978: (JUL, 2), + 1979: (JUN, 22), + 1980: (JUN, 10), + 1981: (MAY, 31), + 1982: (MAY, 20), + 1983: (MAY, 10), + 1984: (APR, 28), + 1985: (APR, 17), + 1986: (APR, 6), + 1987: (MAR, 27), + 1988: (MAR, 15), + 1989: (MAR, 5), + 1990: (FEB, 22), + 1991: (FEB, 11), + 1992: (JAN, 31), + 1993: (JAN, 20), + 1994: ((JAN, 9), (DEC, 29)), + 1995: (DEC, 19), + 1996: (DEC, 8), + 1997: (NOV, 27), + 1998: (NOV, 16), + 1999: (NOV, 5), + 2000: (OCT, 24), + 2001: (OCT, 14), + 2002: (OCT, 4), + 2003: (SEP, 24), + 2004: (SEP, 12), + 2005: (SEP, 1), + 2006: (AUG, 21), + 2007: (AUG, 10), + 2008: (JUL, 30), + 2009: (JUL, 20), + 2010: (JUL, 9), + 2011: (JUN, 29), + 2012: (JUN, 17), + 2013: (JUN, 6), + 2014: (MAY, 26), + 2015: (MAY, 16), + 2016: (MAY, 4), + 2017: (APR, 24), + 2018: (APR, 13), + 2019: (APR, 3), + 2020: (MAR, 22), + 2021: (MAR, 11), + 2022: (FEB, 28), + 2023: (FEB, 18), + 2024: (FEB, 8), + 2025: (JAN, 27), + 2026: (JAN, 16), + 2027: ((JAN, 5), (DEC, 25)), + 2028: (DEC, 14), + 2029: (DEC, 3), + 2030: (NOV, 23), + 2031: (NOV, 12), + 2032: (NOV, 1), + 2033: (OCT, 21), + 2034: (OCT, 10), + 2035: (SEP, 29), + 2036: (SEP, 18), + 2037: (SEP, 7), + 2038: (AUG, 28), + 2039: (AUG, 17), + 2040: (AUG, 5), + 2041: (JUL, 25), + 2042: (JUL, 15), + 2043: (JUL, 4), + 2044: (JUN, 23), + 2045: (JUN, 13), + 2046: (JUN, 2), + 2047: (MAY, 22), + 2048: (MAY, 10), + 2049: (APR, 29), + 2050: (APR, 19), + 2051: (APR, 9), + 2052: (MAR, 28), + 2053: (MAR, 18), + 2054: (MAR, 7), + 2055: (FEB, 24), + 2056: (FEB, 13), + 2057: (FEB, 1), + 2058: (JAN, 22), + 2059: (JAN, 12), + 2060: ((JAN, 1), (DEC, 20)), + 2061: (DEC, 9), + 2062: (NOV, 29), + 2063: (NOV, 18), + 2064: (NOV, 7), + 2065: (OCT, 27), + 2066: (OCT, 17), + 2067: (OCT, 6), + 2068: (SEP, 24), + 2069: (SEP, 13), + 2070: (SEP, 3), + 2071: (AUG, 23), + 2072: (AUG, 12), + 2073: (AUG, 1), + 2074: (JUL, 22), + 2075: (JUL, 11), + 2076: (JUN, 29), + 2077: (JUN, 18), + } + + LAYLAT_AL_QADR_DATES = { + 1925: (APR, 22), + 1926: (APR, 10), + 1927: (MAR, 30), + 1928: (MAR, 19), + 1929: (MAR, 8), + 1930: (FEB, 26), + 1931: (FEB, 15), + 1932: (FEB, 4), + 1933: (JAN, 23), + 1934: (JAN, 13), + 1935: ((JAN, 3), (DEC, 23)), + 1936: (DEC, 11), + 1937: (DEC, 1), + 1938: (NOV, 19), + 1939: (NOV, 9), + 1940: (OCT, 29), + 1941: (OCT, 17), + 1942: (OCT, 7), + 1943: (SEP, 26), + 1944: (SEP, 14), + 1945: (SEP, 3), + 1946: (AUG, 24), + 1947: (AUG, 14), + 1948: (AUG, 2), + 1949: (JUL, 22), + 1950: (JUL, 13), + 1951: (JUL, 2), + 1952: (JUN, 20), + 1953: (JUN, 9), + 1954: (MAY, 30), + 1955: (MAY, 20), + 1956: (MAY, 8), + 1957: (APR, 27), + 1958: (APR, 16), + 1959: (APR, 6), + 1960: (MAR, 25), + 1961: (MAR, 14), + 1962: (MAR, 3), + 1963: (FEB, 21), + 1964: (FEB, 10), + 1965: (JAN, 29), + 1966: (JAN, 18), + 1967: ((JAN, 8), (DEC, 28)), + 1968: (DEC, 17), + 1969: (DEC, 6), + 1970: (NOV, 27), + 1971: (NOV, 15), + 1972: (NOV, 3), + 1973: (OCT, 23), + 1974: (OCT, 13), + 1975: (OCT, 2), + 1976: (SEP, 21), + 1977: (SEP, 10), + 1978: (AUG, 31), + 1979: (AUG, 20), + 1980: (AUG, 8), + 1981: (JUL, 28), + 1982: (JUL, 18), + 1983: (JUL, 8), + 1984: (JUN, 26), + 1985: (JUN, 15), + 1986: (JUN, 4), + 1987: (MAY, 25), + 1988: (MAY, 13), + 1989: (MAY, 3), + 1990: (APR, 22), + 1991: (APR, 12), + 1992: (MAR, 31), + 1993: (MAR, 20), + 1994: (MAR, 9), + 1995: (FEB, 26), + 1996: (FEB, 16), + 1997: (FEB, 5), + 1998: (JAN, 25), + 1999: (JAN, 14), + 2000: ((JAN, 4), (DEC, 23)), + 2001: (DEC, 12), + 2002: (DEC, 2), + 2003: (NOV, 21), + 2004: (NOV, 10), + 2005: (OCT, 30), + 2006: (OCT, 20), + 2007: (OCT, 9), + 2008: (SEP, 27), + 2009: (SEP, 17), + 2010: (SEP, 6), + 2011: (AUG, 27), + 2012: (AUG, 15), + 2013: (AUG, 4), + 2014: (JUL, 24), + 2015: (JUL, 14), + 2016: (JUL, 2), + 2017: (JUN, 22), + 2018: (JUN, 11), + 2019: (JUN, 1), + 2020: (MAY, 20), + 2021: (MAY, 9), + 2022: (APR, 28), + 2023: (APR, 18), + 2024: (APR, 6), + 2025: (MAR, 27), + 2026: (MAR, 16), + 2027: (MAR, 6), + 2028: (FEB, 23), + 2029: (FEB, 11), + 2030: (JAN, 31), + 2031: (JAN, 21), + 2032: ((JAN, 10), (DEC, 30)), + 2033: (DEC, 19), + 2034: (DEC, 8), + 2035: (NOV, 27), + 2036: (NOV, 15), + 2037: (NOV, 5), + 2038: (OCT, 26), + 2039: (OCT, 15), + 2040: (OCT, 3), + 2041: (SEP, 23), + 2042: (SEP, 12), + 2043: (SEP, 1), + 2044: (AUG, 21), + 2045: (AUG, 10), + 2046: (JUL, 31), + 2047: (JUL, 20), + 2048: (JUL, 8), + 2049: (JUN, 28), + 2050: (JUN, 17), + 2051: (JUN, 6), + 2052: (MAY, 26), + 2053: (MAY, 16), + 2054: (MAY, 5), + 2055: (APR, 24), + 2056: (APR, 12), + 2057: (APR, 1), + 2058: (MAR, 22), + 2059: (MAR, 12), + 2060: (FEB, 29), + 2061: (FEB, 18), + 2062: (FEB, 7), + 2063: (JAN, 27), + 2064: (JAN, 16), + 2065: ((JAN, 4), (DEC, 25)), + 2066: (DEC, 15), + 2067: (DEC, 4), + 2068: (NOV, 22), + 2069: (NOV, 11), + 2070: (OCT, 31), + 2071: (OCT, 21), + 2072: (OCT, 9), + 2073: (SEP, 29), + 2074: (SEP, 18), + 2075: (SEP, 8), + 2076: (AUG, 27), + 2077: (AUG, 16), + } + + MALDIVES_EMBRACED_ISLAM_DAY_DATES = { + 1924: (OCT, 29), + 1925: (OCT, 19), + 1926: (OCT, 8), + 1927: (SEP, 27), + 1928: (SEP, 15), + 1929: (SEP, 5), + 1930: (AUG, 25), + 1931: (AUG, 15), + 1932: (AUG, 4), + 1933: (JUL, 24), + 1934: (JUL, 13), + 1935: (JUL, 2), + 1936: (JUN, 21), + 1937: (JUN, 10), + 1938: (MAY, 30), + 1939: (MAY, 20), + 1940: (MAY, 9), + 1941: (APR, 27), + 1942: (APR, 17), + 1943: (APR, 6), + 1944: (MAR, 25), + 1945: (MAR, 15), + 1946: (MAR, 4), + 1947: (FEB, 22), + 1948: (FEB, 11), + 1949: (JAN, 30), + 1950: (JAN, 20), + 1951: ((JAN, 10), (DEC, 30)), + 1952: (DEC, 18), + 1953: (DEC, 7), + 1954: (NOV, 27), + 1955: (NOV, 17), + 1956: (NOV, 4), + 1957: (OCT, 24), + 1958: (OCT, 15), + 1959: (OCT, 3), + 1960: (SEP, 22), + 1961: (SEP, 11), + 1962: (AUG, 31), + 1963: (AUG, 20), + 1964: (AUG, 9), + 1965: (JUL, 29), + 1966: (JUL, 19), + 1967: (JUL, 8), + 1968: (JUN, 27), + 1969: (JUN, 16), + 1970: (JUN, 6), + 1971: (MAY, 26), + 1972: (MAY, 14), + 1973: (MAY, 4), + 1974: (APR, 23), + 1975: (APR, 12), + 1976: (MAR, 31), + 1977: (MAR, 20), + 1978: (MAR, 10), + 1979: (FEB, 27), + 1980: (FEB, 17), + 1981: (FEB, 5), + 1982: (JAN, 26), + 1983: (JAN, 15), + 1984: ((JAN, 4), (DEC, 23)), + 1985: (DEC, 13), + 1986: (DEC, 2), + 1987: (NOV, 22), + 1988: (NOV, 10), + 1989: (OCT, 30), + 1990: (OCT, 19), + 1991: (OCT, 8), + 1992: (SEP, 27), + 1993: (SEP, 17), + 1994: (SEP, 6), + 1995: (AUG, 27), + 1996: (AUG, 15), + 1997: (AUG, 4), + 1998: (JUL, 24), + 1999: (JUL, 14), + 2000: (JUL, 3), + 2001: (JUN, 22), + 2002: (JUN, 12), + 2003: (JUN, 1), + 2004: (MAY, 20), + 2005: (MAY, 9), + 2006: (APR, 29), + 2007: (APR, 18), + 2008: (APR, 7), + 2009: (MAR, 28), + 2010: (MAR, 17), + 2011: (MAR, 6), + 2012: (FEB, 23), + 2013: (FEB, 11), + 2014: (FEB, 1), + 2015: (JAN, 21), + 2016: ((JAN, 11), (DEC, 30)), + 2017: (DEC, 19), + 2018: (DEC, 8), + 2019: (NOV, 28), + 2020: (NOV, 16), + 2021: (NOV, 6), + 2022: (OCT, 26), + 2023: (OCT, 16), + 2024: (OCT, 4), + 2025: (SEP, 23), + 2026: (SEP, 12), + 2027: (SEP, 2), + 2028: (AUG, 22), + 2029: (AUG, 11), + 2030: (AUG, 1), + 2031: (JUL, 21), + 2032: (JUL, 9), + 2033: (JUN, 28), + 2034: (JUN, 17), + 2035: (JUN, 7), + 2036: (MAY, 27), + 2037: (MAY, 16), + 2038: (MAY, 5), + 2039: (APR, 24), + 2040: (APR, 13), + 2041: (APR, 2), + 2042: (MAR, 23), + 2043: (MAR, 12), + 2044: (MAR, 1), + 2045: (FEB, 18), + 2046: (FEB, 7), + 2047: (JAN, 27), + 2048: (JAN, 16), + 2049: ((JAN, 5), (DEC, 26)), + 2050: (DEC, 15), + 2051: (DEC, 4), + 2052: (NOV, 22), + 2053: (NOV, 11), + 2054: (NOV, 1), + 2055: (OCT, 21), + 2056: (OCT, 10), + 2057: (SEP, 30), + 2058: (SEP, 19), + 2059: (SEP, 8), + 2060: (AUG, 27), + 2061: (AUG, 16), + 2062: (AUG, 6), + 2063: (JUL, 27), + 2064: (JUL, 15), + 2065: (JUL, 5), + 2066: (JUN, 24), + 2067: (JUN, 13), + 2068: (JUN, 1), + 2069: (MAY, 22), + 2070: (MAY, 11), + 2071: (MAY, 1), + 2072: (APR, 19), + 2073: (APR, 9), + 2074: (MAR, 29), + 2075: (MAR, 18), + 2076: (MAR, 6), + 2077: (FEB, 24), + } + + MAWLID_DATES = { + 1924: (OCT, 10), + 1925: (SEP, 30), + 1926: (SEP, 19), + 1927: (SEP, 8), + 1928: (AUG, 27), + 1929: (AUG, 17), + 1930: (AUG, 6), + 1931: (JUL, 28), + 1932: (JUL, 16), + 1933: (JUL, 5), + 1934: (JUN, 24), + 1935: (JUN, 14), + 1936: (JUN, 2), + 1937: (MAY, 22), + 1938: (MAY, 11), + 1939: (MAY, 2), + 1940: (APR, 20), + 1941: (APR, 8), + 1942: (MAR, 29), + 1943: (MAR, 18), + 1944: (MAR, 6), + 1945: (FEB, 24), + 1946: (FEB, 13), + 1947: (FEB, 3), + 1948: (JAN, 23), + 1949: (JAN, 11), + 1950: ((JAN, 1), (DEC, 22)), + 1951: (DEC, 11), + 1952: (NOV, 30), + 1953: (NOV, 19), + 1954: (NOV, 8), + 1955: (OCT, 29), + 1956: (OCT, 17), + 1957: (OCT, 6), + 1958: (SEP, 26), + 1959: (SEP, 15), + 1960: (SEP, 3), + 1961: (AUG, 23), + 1962: (AUG, 12), + 1963: (AUG, 2), + 1964: (JUL, 21), + 1965: (JUL, 10), + 1966: (JUL, 1), + 1967: (JUN, 19), + 1968: (JUN, 8), + 1969: (MAY, 28), + 1970: (MAY, 18), + 1971: (MAY, 7), + 1972: (APR, 25), + 1973: (APR, 15), + 1974: (APR, 4), + 1975: (MAR, 24), + 1976: (MAR, 12), + 1977: (MAR, 2), + 1978: (FEB, 19), + 1979: (FEB, 9), + 1980: (JAN, 30), + 1981: (JAN, 18), + 1982: ((JAN, 7), (DEC, 27)), + 1983: (DEC, 16), + 1984: (DEC, 4), + 1985: (NOV, 24), + 1986: (NOV, 14), + 1987: (NOV, 3), + 1988: (OCT, 22), + 1989: (OCT, 11), + 1990: (OCT, 1), + 1991: (SEP, 20), + 1992: (SEP, 9), + 1993: (AUG, 29), + 1994: (AUG, 19), + 1995: (AUG, 8), + 1996: (JUL, 27), + 1997: (JUL, 16), + 1998: (JUL, 6), + 1999: (JUN, 26), + 2000: (JUN, 14), + 2001: (JUN, 4), + 2002: (MAY, 24), + 2003: (MAY, 13), + 2004: (MAY, 1), + 2005: (APR, 21), + 2006: (APR, 10), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 15), + 2012: (FEB, 4), + 2013: (JAN, 24), + 2014: (JAN, 13), + 2015: ((JAN, 3), (DEC, 23)), + 2016: (DEC, 11), + 2017: (NOV, 30), + 2018: (NOV, 20), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 15), + 2025: (SEP, 4), + 2026: (AUG, 25), + 2027: (AUG, 14), + 2028: (AUG, 3), + 2029: (JUL, 24), + 2030: (JUL, 13), + 2031: (JUL, 2), + 2032: (JUN, 20), + 2033: (JUN, 9), + 2034: (MAY, 30), + 2035: (MAY, 20), + 2036: (MAY, 8), + 2037: (APR, 28), + 2038: (APR, 17), + 2039: (APR, 6), + 2040: (MAR, 25), + 2041: (MAR, 15), + 2042: (MAR, 4), + 2043: (FEB, 22), + 2044: (FEB, 11), + 2045: (JAN, 30), + 2046: (JAN, 19), + 2047: ((JAN, 8), (DEC, 29)), + 2048: (DEC, 18), + 2049: (DEC, 7), + 2050: (NOV, 26), + 2051: (NOV, 16), + 2052: (NOV, 4), + 2053: (OCT, 24), + 2054: (OCT, 13), + 2055: (OCT, 3), + 2056: (SEP, 22), + 2057: (SEP, 11), + 2058: (AUG, 31), + 2059: (AUG, 20), + 2060: (AUG, 8), + 2061: (JUL, 29), + 2062: (JUL, 19), + 2063: (JUL, 8), + 2064: (JUN, 27), + 2065: (JUN, 16), + 2066: (JUN, 5), + 2067: (MAY, 25), + 2068: (MAY, 14), + 2069: (MAY, 3), + 2070: (APR, 23), + 2071: (APR, 13), + 2072: (APR, 1), + 2073: (MAR, 21), + 2074: (MAR, 10), + 2075: (FEB, 27), + 2076: (FEB, 17), + 2077: (FEB, 6), + } + + NUZUL_AL_QURAN_DATES = { + 1925: (APR, 12), + 1926: (MAR, 31), + 1927: (MAR, 20), + 1928: (MAR, 9), + 1929: (FEB, 26), + 1930: (FEB, 16), + 1931: (FEB, 5), + 1932: (JAN, 25), + 1933: (JAN, 13), + 1934: ((JAN, 3), (DEC, 24)), + 1935: (DEC, 13), + 1936: (DEC, 1), + 1937: (NOV, 21), + 1938: (NOV, 9), + 1939: (OCT, 30), + 1940: (OCT, 19), + 1941: (OCT, 7), + 1942: (SEP, 27), + 1943: (SEP, 16), + 1944: (SEP, 4), + 1945: (AUG, 24), + 1946: (AUG, 14), + 1947: (AUG, 4), + 1948: (JUL, 23), + 1949: (JUL, 12), + 1950: (JUL, 3), + 1951: (JUN, 22), + 1952: (JUN, 10), + 1953: (MAY, 30), + 1954: (MAY, 20), + 1955: (MAY, 10), + 1956: (APR, 28), + 1957: (APR, 17), + 1958: (APR, 6), + 1959: (MAR, 27), + 1960: (MAR, 15), + 1961: (MAR, 4), + 1962: (FEB, 21), + 1963: (FEB, 11), + 1964: (JAN, 31), + 1965: (JAN, 19), + 1966: ((JAN, 8), (DEC, 29)), + 1967: (DEC, 18), + 1968: (DEC, 7), + 1969: (NOV, 26), + 1970: (NOV, 17), + 1971: (NOV, 5), + 1972: (OCT, 24), + 1973: (OCT, 13), + 1974: (OCT, 3), + 1975: (SEP, 22), + 1976: (SEP, 11), + 1977: (AUG, 31), + 1978: (AUG, 21), + 1979: (AUG, 10), + 1980: (JUL, 29), + 1981: (JUL, 18), + 1982: (JUL, 8), + 1983: (JUN, 28), + 1984: (JUN, 16), + 1985: (JUN, 5), + 1986: (MAY, 25), + 1987: (MAY, 15), + 1988: (MAY, 3), + 1989: (APR, 23), + 1990: (APR, 12), + 1991: (APR, 2), + 1992: (MAR, 21), + 1993: (MAR, 10), + 1994: (FEB, 27), + 1995: (FEB, 16), + 1996: (FEB, 6), + 1997: (JAN, 26), + 1998: (JAN, 15), + 1999: ((JAN, 4), (DEC, 25)), + 2000: (DEC, 13), + 2001: (DEC, 2), + 2002: (NOV, 22), + 2003: (NOV, 11), + 2004: (OCT, 31), + 2005: (OCT, 20), + 2006: (OCT, 10), + 2007: (SEP, 29), + 2008: (SEP, 17), + 2009: (SEP, 7), + 2010: (AUG, 27), + 2011: (AUG, 17), + 2012: (AUG, 5), + 2013: (JUL, 25), + 2014: (JUL, 14), + 2015: (JUL, 4), + 2016: (JUN, 22), + 2017: (JUN, 12), + 2018: (JUN, 1), + 2019: (MAY, 22), + 2020: (MAY, 10), + 2021: (APR, 29), + 2022: (APR, 18), + 2023: (APR, 8), + 2024: (MAR, 27), + 2025: (MAR, 17), + 2026: (MAR, 6), + 2027: (FEB, 24), + 2028: (FEB, 13), + 2029: (FEB, 1), + 2030: (JAN, 21), + 2031: ((JAN, 11), (DEC, 31)), + 2032: (DEC, 20), + 2033: (DEC, 9), + 2034: (NOV, 28), + 2035: (NOV, 17), + 2036: (NOV, 5), + 2037: (OCT, 26), + 2038: (OCT, 16), + 2039: (OCT, 5), + 2040: (SEP, 23), + 2041: (SEP, 13), + 2042: (SEP, 2), + 2043: (AUG, 22), + 2044: (AUG, 11), + 2045: (JUL, 31), + 2046: (JUL, 21), + 2047: (JUL, 10), + 2048: (JUN, 28), + 2049: (JUN, 18), + 2050: (JUN, 7), + 2051: (MAY, 27), + 2052: (MAY, 16), + 2053: (MAY, 6), + 2054: (APR, 25), + 2055: (APR, 14), + 2056: (APR, 2), + 2057: (MAR, 22), + 2058: (MAR, 12), + 2059: (MAR, 2), + 2060: (FEB, 19), + 2061: (FEB, 8), + 2062: (JAN, 28), + 2063: (JAN, 17), + 2064: ((JAN, 6), (DEC, 25)), + 2065: (DEC, 15), + 2066: (DEC, 5), + 2067: (NOV, 24), + 2068: (NOV, 12), + 2069: (NOV, 1), + 2070: (OCT, 21), + 2071: (OCT, 11), + 2072: (SEP, 29), + 2073: (SEP, 19), + 2074: (SEP, 8), + 2075: (AUG, 29), + 2076: (AUG, 17), + 2077: (AUG, 6), + } + + PROPHET_DEATH_DATES = { + 1924: (SEP, 27), + 1925: (SEP, 17), + 1926: (SEP, 6), + 1927: (AUG, 26), + 1928: (AUG, 14), + 1929: (AUG, 4), + 1930: (JUL, 24), + 1931: (JUL, 14), + 1932: (JUL, 3), + 1933: (JUN, 22), + 1934: (JUN, 11), + 1935: (MAY, 31), + 1936: (MAY, 20), + 1937: (MAY, 9), + 1938: (APR, 28), + 1939: (APR, 18), + 1940: (APR, 6), + 1941: (MAR, 26), + 1942: (MAR, 16), + 1943: (MAR, 5), + 1944: (FEB, 22), + 1945: (FEB, 11), + 1946: (JAN, 31), + 1947: (JAN, 21), + 1948: ((JAN, 10), (DEC, 29)), + 1949: (DEC, 19), + 1950: (DEC, 9), + 1951: (NOV, 28), + 1952: (NOV, 16), + 1953: (NOV, 5), + 1954: (OCT, 26), + 1955: (OCT, 16), + 1956: (OCT, 3), + 1957: (SEP, 23), + 1958: (SEP, 13), + 1959: (SEP, 1), + 1960: (AUG, 21), + 1961: (AUG, 10), + 1962: (JUL, 30), + 1963: (JUL, 19), + 1964: (JUL, 8), + 1965: (JUN, 27), + 1966: (JUN, 17), + 1967: (JUN, 6), + 1968: (MAY, 25), + 1969: (MAY, 15), + 1970: (MAY, 5), + 1971: (APR, 24), + 1972: (APR, 12), + 1973: (APR, 2), + 1974: (MAR, 22), + 1975: (MAR, 11), + 1976: (FEB, 28), + 1977: (FEB, 16), + 1978: (FEB, 6), + 1979: (JAN, 26), + 1980: (JAN, 16), + 1981: ((JAN, 4), (DEC, 24)), + 1982: (DEC, 13), + 1983: (DEC, 2), + 1984: (NOV, 21), + 1985: (NOV, 11), + 1986: (OCT, 31), + 1987: (OCT, 21), + 1988: (OCT, 9), + 1989: (SEP, 28), + 1990: (SEP, 17), + 1991: (SEP, 7), + 1992: (AUG, 26), + 1993: (AUG, 16), + 1994: (AUG, 5), + 1995: (JUL, 26), + 1996: (JUL, 14), + 1997: (JUL, 3), + 1998: (JUN, 22), + 1999: (JUN, 12), + 2000: (JUN, 1), + 2001: (MAY, 22), + 2002: (MAY, 11), + 2003: (APR, 30), + 2004: (APR, 18), + 2005: (APR, 7), + 2006: (MAR, 28), + 2007: (MAR, 18), + 2008: (MAR, 6), + 2009: (FEB, 23), + 2010: (FEB, 12), + 2011: (FEB, 1), + 2012: (JAN, 22), + 2013: ((JAN, 10), (DEC, 31)), + 2014: (DEC, 20), + 2015: (DEC, 10), + 2016: (NOV, 28), + 2017: (NOV, 17), + 2018: (NOV, 6), + 2019: (OCT, 27), + 2020: (OCT, 15), + 2021: (OCT, 5), + 2022: (SEP, 24), + 2023: (SEP, 13), + 2024: (SEP, 1), + 2025: (AUG, 22), + 2026: (AUG, 11), + 2027: (AUG, 1), + 2028: (JUL, 21), + 2029: (JUL, 10), + 2030: (JUN, 29), + 2031: (JUN, 18), + 2032: (JUN, 6), + 2033: (MAY, 27), + 2034: (MAY, 17), + 2035: (MAY, 6), + 2036: (APR, 25), + 2037: (APR, 14), + 2038: (APR, 3), + 2039: (MAR, 23), + 2040: (MAR, 12), + 2041: (MAR, 1), + 2042: (FEB, 19), + 2043: (FEB, 8), + 2044: (JAN, 29), + 2045: (JAN, 17), + 2046: ((JAN, 6), (DEC, 26)), + 2047: (DEC, 16), + 2048: (DEC, 4), + 2049: (NOV, 24), + 2050: (NOV, 13), + 2051: (NOV, 2), + 2052: (OCT, 21), + 2053: (OCT, 10), + 2054: (SEP, 30), + 2055: (SEP, 20), + 2056: (SEP, 8), + 2057: (AUG, 28), + 2058: (AUG, 17), + 2059: (AUG, 7), + 2060: (JUL, 26), + 2061: (JUL, 16), + 2062: (JUL, 5), + 2063: (JUN, 25), + 2064: (JUN, 13), + 2065: (JUN, 2), + 2066: (MAY, 22), + 2067: (MAY, 12), + 2068: (APR, 30), + 2069: (APR, 20), + 2070: (APR, 10), + 2071: (MAR, 30), + 2072: (MAR, 18), + 2073: (MAR, 7), + 2074: (FEB, 24), + 2075: (FEB, 14), + 2076: (FEB, 3), + 2077: (JAN, 23), + } + + QUAMEE_DHUVAS_DATES = { + 1924: (SEP, 29), + 1925: (SEP, 19), + 1926: (SEP, 8), + 1927: (AUG, 28), + 1928: (AUG, 16), + 1929: (AUG, 6), + 1930: (JUL, 26), + 1931: (JUL, 17), + 1932: (JUL, 5), + 1933: (JUN, 24), + 1934: (JUN, 13), + 1935: (JUN, 3), + 1936: (MAY, 22), + 1937: (MAY, 11), + 1938: (APR, 30), + 1939: (APR, 21), + 1940: (APR, 9), + 1941: (MAR, 28), + 1942: (MAR, 18), + 1943: (MAR, 7), + 1944: (FEB, 24), + 1945: (FEB, 13), + 1946: (FEB, 2), + 1947: (JAN, 23), + 1948: ((JAN, 12), (DEC, 31)), + 1949: (DEC, 21), + 1950: (DEC, 11), + 1951: (NOV, 30), + 1952: (NOV, 19), + 1953: (NOV, 8), + 1954: (OCT, 28), + 1955: (OCT, 18), + 1956: (OCT, 6), + 1957: (SEP, 25), + 1958: (SEP, 15), + 1959: (SEP, 4), + 1960: (AUG, 23), + 1961: (AUG, 12), + 1962: (AUG, 1), + 1963: (JUL, 22), + 1964: (JUL, 10), + 1965: (JUN, 29), + 1966: (JUN, 20), + 1967: (JUN, 8), + 1968: (MAY, 28), + 1969: (MAY, 17), + 1970: (MAY, 7), + 1971: (APR, 26), + 1972: (APR, 14), + 1973: (APR, 4), + 1974: (MAR, 24), + 1975: (MAR, 13), + 1976: (MAR, 1), + 1977: (FEB, 19), + 1978: (FEB, 8), + 1979: (JAN, 29), + 1980: (JAN, 19), + 1981: ((JAN, 7), (DEC, 27)), + 1982: (DEC, 16), + 1983: (DEC, 5), + 1984: (NOV, 23), + 1985: (NOV, 13), + 1986: (NOV, 3), + 1987: (OCT, 23), + 1988: (OCT, 11), + 1989: (SEP, 30), + 1990: (SEP, 20), + 1991: (SEP, 9), + 1992: (AUG, 29), + 1993: (AUG, 18), + 1994: (AUG, 8), + 1995: (JUL, 28), + 1996: (JUL, 16), + 1997: (JUL, 5), + 1998: (JUN, 25), + 1999: (JUN, 15), + 2000: (JUN, 3), + 2001: (MAY, 24), + 2002: (MAY, 13), + 2003: (MAY, 2), + 2004: (APR, 20), + 2005: (APR, 10), + 2006: (MAR, 30), + 2007: (MAR, 20), + 2008: (MAR, 9), + 2009: (FEB, 26), + 2010: (FEB, 15), + 2011: (FEB, 4), + 2012: (JAN, 24), + 2013: (JAN, 13), + 2014: ((JAN, 2), (DEC, 23)), + 2015: (DEC, 12), + 2016: (NOV, 30), + 2017: (NOV, 19), + 2018: (NOV, 9), + 2019: (OCT, 29), + 2020: (OCT, 18), + 2021: (OCT, 7), + 2022: (SEP, 27), + 2023: (SEP, 16), + 2024: (SEP, 4), + 2025: (AUG, 24), + 2026: (AUG, 14), + 2027: (AUG, 3), + 2028: (JUL, 23), + 2029: (JUL, 13), + 2030: (JUL, 2), + 2031: (JUN, 21), + 2032: (JUN, 9), + 2033: (MAY, 29), + 2034: (MAY, 19), + 2035: (MAY, 9), + 2036: (APR, 27), + 2037: (APR, 17), + 2038: (APR, 6), + 2039: (MAR, 26), + 2040: (MAR, 14), + 2041: (MAR, 4), + 2042: (FEB, 21), + 2043: (FEB, 11), + 2044: (JAN, 31), + 2045: (JAN, 19), + 2046: ((JAN, 8), (DEC, 28)), + 2047: (DEC, 18), + 2048: (DEC, 7), + 2049: (NOV, 26), + 2050: (NOV, 15), + 2051: (NOV, 5), + 2052: (OCT, 24), + 2053: (OCT, 13), + 2054: (OCT, 2), + 2055: (SEP, 22), + 2056: (SEP, 11), + 2057: (AUG, 31), + 2058: (AUG, 20), + 2059: (AUG, 9), + 2060: (JUL, 28), + 2061: (JUL, 18), + 2062: (JUL, 8), + 2063: (JUN, 27), + 2064: (JUN, 16), + 2065: (JUN, 5), + 2066: (MAY, 25), + 2067: (MAY, 14), + 2068: (MAY, 3), + 2069: (APR, 22), + 2070: (APR, 12), + 2071: (APR, 2), + 2072: (MAR, 21), + 2073: (MAR, 10), + 2074: (FEB, 27), + 2075: (FEB, 16), + 2076: (FEB, 6), + 2077: (JAN, 26), + } + + RAMADAN_BEGINNING_DATES = { + 1925: (MAR, 27), + 1926: (MAR, 15), + 1927: (MAR, 4), + 1928: (FEB, 22), + 1929: (FEB, 10), + 1930: (JAN, 31), + 1931: (JAN, 20), + 1932: ((JAN, 9), (DEC, 28)), + 1933: (DEC, 18), + 1934: (DEC, 8), + 1935: (NOV, 27), + 1936: (NOV, 15), + 1937: (NOV, 5), + 1938: (OCT, 24), + 1939: (OCT, 14), + 1940: (OCT, 3), + 1941: (SEP, 21), + 1942: (SEP, 11), + 1943: (AUG, 31), + 1944: (AUG, 19), + 1945: (AUG, 8), + 1946: (JUL, 29), + 1947: (JUL, 19), + 1948: (JUL, 7), + 1949: (JUN, 26), + 1950: (JUN, 17), + 1951: (JUN, 6), + 1952: (MAY, 25), + 1953: (MAY, 14), + 1954: (MAY, 4), + 1955: (APR, 24), + 1956: (APR, 12), + 1957: (APR, 1), + 1958: (MAR, 21), + 1959: (MAR, 11), + 1960: (FEB, 28), + 1961: (FEB, 16), + 1962: (FEB, 5), + 1963: (JAN, 26), + 1964: (JAN, 15), + 1965: ((JAN, 3), (DEC, 23)), + 1966: (DEC, 13), + 1967: (DEC, 2), + 1968: (NOV, 21), + 1969: (NOV, 10), + 1970: (NOV, 1), + 1971: (OCT, 20), + 1972: (OCT, 8), + 1973: (SEP, 27), + 1974: (SEP, 17), + 1975: (SEP, 6), + 1976: (AUG, 26), + 1977: (AUG, 15), + 1978: (AUG, 5), + 1979: (JUL, 25), + 1980: (JUL, 13), + 1981: (JUL, 2), + 1982: (JUN, 22), + 1983: (JUN, 12), + 1984: (MAY, 31), + 1985: (MAY, 20), + 1986: (MAY, 9), + 1987: (APR, 29), + 1988: (APR, 17), + 1989: (APR, 7), + 1990: (MAR, 27), + 1991: (MAR, 17), + 1992: (MAR, 5), + 1993: (FEB, 22), + 1994: (FEB, 11), + 1995: (JAN, 31), + 1996: (JAN, 21), + 1997: ((JAN, 10), (DEC, 30)), + 1998: (DEC, 19), + 1999: (DEC, 9), + 2000: (NOV, 27), + 2001: (NOV, 16), + 2002: (NOV, 6), + 2003: (OCT, 26), + 2004: (OCT, 15), + 2005: (OCT, 4), + 2006: (SEP, 24), + 2007: (SEP, 13), + 2008: (SEP, 1), + 2009: (AUG, 22), + 2010: (AUG, 11), + 2011: (AUG, 1), + 2012: (JUL, 20), + 2013: (JUL, 9), + 2014: (JUN, 28), + 2015: (JUN, 18), + 2016: (JUN, 6), + 2017: (MAY, 27), + 2018: (MAY, 16), + 2019: (MAY, 6), + 2020: (APR, 24), + 2021: (APR, 13), + 2022: (APR, 2), + 2023: (MAR, 23), + 2024: (MAR, 11), + 2025: (MAR, 1), + 2026: (FEB, 18), + 2027: (FEB, 8), + 2028: (JAN, 28), + 2029: (JAN, 16), + 2030: ((JAN, 5), (DEC, 26)), + 2031: (DEC, 15), + 2032: (DEC, 4), + 2033: (NOV, 23), + 2034: (NOV, 12), + 2035: (NOV, 1), + 2036: (OCT, 20), + 2037: (OCT, 10), + 2038: (SEP, 30), + 2039: (SEP, 19), + 2040: (SEP, 7), + 2041: (AUG, 28), + 2042: (AUG, 17), + 2043: (AUG, 6), + 2044: (JUL, 26), + 2045: (JUL, 15), + 2046: (JUL, 5), + 2047: (JUN, 24), + 2048: (JUN, 12), + 2049: (JUN, 2), + 2050: (MAY, 22), + 2051: (MAY, 11), + 2052: (APR, 30), + 2053: (APR, 20), + 2054: (APR, 9), + 2055: (MAR, 29), + 2056: (MAR, 17), + 2057: (MAR, 6), + 2058: (FEB, 24), + 2059: (FEB, 14), + 2060: (FEB, 3), + 2061: (JAN, 23), + 2062: (JAN, 12), + 2063: ((JAN, 1), (DEC, 21)), + 2064: (DEC, 9), + 2065: (NOV, 29), + 2066: (NOV, 19), + 2067: (NOV, 8), + 2068: (OCT, 27), + 2069: (OCT, 16), + 2070: (OCT, 5), + 2071: (SEP, 25), + 2072: (SEP, 13), + 2073: (SEP, 3), + 2074: (AUG, 23), + 2075: (AUG, 13), + 2076: (AUG, 1), + 2077: (JUL, 21), + } + + SADIQ_BIRTHDAY_DATES = { + 1924: (OCT, 15), + 1925: (OCT, 5), + 1926: (SEP, 24), + 1927: (SEP, 13), + 1928: (SEP, 1), + 1929: (AUG, 22), + 1930: (AUG, 11), + 1931: (AUG, 2), + 1932: (JUL, 21), + 1933: (JUL, 10), + 1934: (JUN, 29), + 1935: (JUN, 19), + 1936: (JUN, 7), + 1937: (MAY, 27), + 1938: (MAY, 16), + 1939: (MAY, 7), + 1940: (APR, 25), + 1941: (APR, 13), + 1942: (APR, 3), + 1943: (MAR, 23), + 1944: (MAR, 11), + 1945: (MAR, 1), + 1946: (FEB, 18), + 1947: (FEB, 8), + 1948: (JAN, 28), + 1949: (JAN, 16), + 1950: ((JAN, 6), (DEC, 27)), + 1951: (DEC, 16), + 1952: (DEC, 5), + 1953: (NOV, 24), + 1954: (NOV, 13), + 1955: (NOV, 3), + 1956: (OCT, 22), + 1957: (OCT, 11), + 1958: (OCT, 1), + 1959: (SEP, 20), + 1960: (SEP, 8), + 1961: (AUG, 28), + 1962: (AUG, 17), + 1963: (AUG, 7), + 1964: (JUL, 26), + 1965: (JUL, 15), + 1966: (JUL, 6), + 1967: (JUN, 24), + 1968: (JUN, 13), + 1969: (JUN, 2), + 1970: (MAY, 23), + 1971: (MAY, 12), + 1972: (APR, 30), + 1973: (APR, 20), + 1974: (APR, 9), + 1975: (MAR, 29), + 1976: (MAR, 17), + 1977: (MAR, 7), + 1978: (FEB, 24), + 1979: (FEB, 14), + 1980: (FEB, 4), + 1981: (JAN, 23), + 1982: (JAN, 12), + 1983: ((JAN, 1), (DEC, 21)), + 1984: (DEC, 9), + 1985: (NOV, 29), + 1986: (NOV, 19), + 1987: (NOV, 8), + 1988: (OCT, 27), + 1989: (OCT, 16), + 1990: (OCT, 6), + 1991: (SEP, 25), + 1992: (SEP, 14), + 1993: (SEP, 3), + 1994: (AUG, 24), + 1995: (AUG, 13), + 1996: (AUG, 1), + 1997: (JUL, 21), + 1998: (JUL, 11), + 1999: (JUL, 1), + 2000: (JUN, 19), + 2001: (JUN, 9), + 2002: (MAY, 29), + 2003: (MAY, 18), + 2004: (MAY, 6), + 2005: (APR, 26), + 2006: (APR, 15), + 2007: (APR, 5), + 2008: (MAR, 25), + 2009: (MAR, 14), + 2010: (MAR, 3), + 2011: (FEB, 20), + 2012: (FEB, 9), + 2013: (JAN, 29), + 2014: (JAN, 18), + 2015: ((JAN, 8), (DEC, 28)), + 2016: (DEC, 16), + 2017: (DEC, 5), + 2018: (NOV, 25), + 2019: (NOV, 14), + 2020: (NOV, 3), + 2021: (OCT, 23), + 2022: (OCT, 13), + 2023: (OCT, 2), + 2024: (SEP, 20), + 2025: (SEP, 9), + 2026: (AUG, 30), + 2027: (AUG, 19), + 2028: (AUG, 8), + 2029: (JUL, 29), + 2030: (JUL, 18), + 2031: (JUL, 7), + 2032: (JUN, 25), + 2033: (JUN, 14), + 2034: (JUN, 4), + 2035: (MAY, 25), + 2036: (MAY, 13), + 2037: (MAY, 3), + 2038: (APR, 22), + 2039: (APR, 11), + 2040: (MAR, 30), + 2041: (MAR, 20), + 2042: (MAR, 9), + 2043: (FEB, 27), + 2044: (FEB, 16), + 2045: (FEB, 4), + 2046: (JAN, 24), + 2047: (JAN, 13), + 2048: ((JAN, 3), (DEC, 23)), + 2049: (DEC, 12), + 2050: (DEC, 1), + 2051: (NOV, 21), + 2052: (NOV, 9), + 2053: (OCT, 29), + 2054: (OCT, 18), + 2055: (OCT, 8), + 2056: (SEP, 27), + 2057: (SEP, 16), + 2058: (SEP, 5), + 2059: (AUG, 25), + 2060: (AUG, 13), + 2061: (AUG, 3), + 2062: (JUL, 24), + 2063: (JUL, 13), + 2064: (JUL, 2), + 2065: (JUN, 21), + 2066: (JUN, 10), + 2067: (MAY, 30), + 2068: (MAY, 19), + 2069: (MAY, 8), + 2070: (APR, 28), + 2071: (APR, 18), + 2072: (APR, 6), + 2073: (MAR, 26), + 2074: (MAR, 15), + 2075: (MAR, 4), + 2076: (FEB, 22), + 2077: (FEB, 11), + } + + SADIQ_DEATH_DATES = { + 1925: (MAY, 18), + 1926: (MAY, 8), + 1927: (APR, 27), + 1928: (APR, 15), + 1929: (APR, 5), + 1930: (MAR, 25), + 1931: (MAR, 15), + 1932: (MAR, 3), + 1933: (FEB, 20), + 1934: (FEB, 10), + 1935: (JAN, 31), + 1936: (JAN, 20), + 1937: ((JAN, 8), (DEC, 28)), + 1938: (DEC, 17), + 1939: (DEC, 6), + 1940: (NOV, 25), + 1941: (NOV, 14), + 1942: (NOV, 4), + 1943: (OCT, 24), + 1944: (OCT, 12), + 1945: (OCT, 1), + 1946: (SEP, 21), + 1947: (SEP, 11), + 1948: (AUG, 30), + 1949: (AUG, 19), + 1950: (AUG, 9), + 1951: (JUL, 30), + 1952: (JUL, 17), + 1953: (JUL, 7), + 1954: (JUN, 26), + 1955: (JUN, 16), + 1956: (JUN, 4), + 1957: (MAY, 25), + 1958: (MAY, 14), + 1959: (MAY, 4), + 1960: (APR, 21), + 1961: (APR, 11), + 1962: (MAR, 31), + 1963: (MAR, 20), + 1964: (MAR, 9), + 1965: (FEB, 26), + 1966: (FEB, 15), + 1967: (FEB, 5), + 1968: (JAN, 25), + 1969: (JAN, 14), + 1970: ((JAN, 3), (DEC, 24)), + 1971: (DEC, 13), + 1972: (DEC, 1), + 1973: (NOV, 20), + 1974: (NOV, 9), + 1975: (OCT, 30), + 1976: (OCT, 18), + 1977: (OCT, 8), + 1978: (SEP, 27), + 1979: (SEP, 16), + 1980: (SEP, 5), + 1981: (AUG, 25), + 1982: (AUG, 14), + 1983: (AUG, 4), + 1984: (JUL, 24), + 1985: (JUL, 13), + 1986: (JUL, 2), + 1987: (JUN, 21), + 1988: (JUN, 9), + 1989: (MAY, 30), + 1990: (MAY, 20), + 1991: (MAY, 9), + 1992: (APR, 28), + 1993: (APR, 17), + 1994: (APR, 6), + 1995: (MAR, 26), + 1996: (MAR, 14), + 1997: (MAR, 4), + 1998: (FEB, 22), + 1999: (FEB, 11), + 2000: (FEB, 1), + 2001: (JAN, 20), + 2002: ((JAN, 9), (DEC, 29)), + 2003: (DEC, 19), + 2004: (DEC, 8), + 2005: (NOV, 27), + 2006: (NOV, 16), + 2007: (NOV, 6), + 2008: (OCT, 25), + 2009: (OCT, 14), + 2010: (OCT, 4), + 2011: (SEP, 23), + 2012: (SEP, 12), + 2013: (SEP, 1), + 2014: (AUG, 21), + 2015: (AUG, 10), + 2016: (JUL, 30), + 2017: (JUL, 19), + 2018: (JUL, 9), + 2019: (JUN, 28), + 2020: (JUN, 17), + 2021: (JUN, 6), + 2022: (MAY, 26), + 2023: (MAY, 15), + 2024: (MAY, 4), + 2025: (APR, 23), + 2026: (APR, 13), + 2027: (APR, 2), + 2028: (MAR, 21), + 2029: (MAR, 10), + 2030: (FEB, 28), + 2031: (FEB, 17), + 2032: (FEB, 7), + 2033: (JAN, 26), + 2034: (JAN, 16), + 2035: ((JAN, 5), (DEC, 25)), + 2036: (DEC, 13), + 2037: (DEC, 2), + 2038: (NOV, 22), + 2039: (NOV, 12), + 2040: (OCT, 31), + 2041: (OCT, 20), + 2042: (OCT, 9), + 2043: (SEP, 28), + 2044: (SEP, 17), + 2045: (SEP, 7), + 2046: (AUG, 27), + 2047: (AUG, 17), + 2048: (AUG, 5), + 2049: (JUL, 25), + 2050: (JUL, 14), + 2051: (JUL, 4), + 2052: (JUN, 22), + 2053: (JUN, 12), + 2054: (JUN, 2), + 2055: (MAY, 22), + 2056: (MAY, 10), + 2057: (APR, 29), + 2058: (APR, 18), + 2059: (APR, 8), + 2060: (MAR, 28), + 2061: (MAR, 17), + 2062: (MAR, 6), + 2063: (FEB, 23), + 2064: (FEB, 13), + 2065: (FEB, 1), + 2066: (JAN, 21), + 2067: (JAN, 11), + 2068: ((JAN, 1), (DEC, 20)), + 2069: (DEC, 9), + 2070: (NOV, 28), + 2071: (NOV, 17), + 2072: (NOV, 6), + 2073: (OCT, 26), + 2074: (OCT, 16), + 2075: (OCT, 5), + 2076: (SEP, 23), + 2077: (SEP, 12), + } + + TASUA_DATES = { + 1924: (AUG, 9), + 1925: (JUL, 31), + 1926: (JUL, 19), + 1927: (JUL, 9), + 1928: (JUN, 27), + 1929: (JUN, 16), + 1930: (JUN, 5), + 1931: (MAY, 27), + 1932: (MAY, 15), + 1933: (MAY, 4), + 1934: (APR, 23), + 1935: (APR, 13), + 1936: (APR, 1), + 1937: (MAR, 22), + 1938: (MAR, 10), + 1939: (FEB, 28), + 1940: (FEB, 17), + 1941: (FEB, 5), + 1942: (JAN, 26), + 1943: (JAN, 15), + 1944: ((JAN, 4), (DEC, 24)), + 1945: (DEC, 13), + 1946: (DEC, 3), + 1947: (NOV, 22), + 1948: (NOV, 10), + 1949: (OCT, 31), + 1950: (OCT, 21), + 1951: (OCT, 10), + 1952: (SEP, 29), + 1953: (SEP, 18), + 1954: (SEP, 7), + 1955: (AUG, 28), + 1956: (AUG, 16), + 1957: (AUG, 5), + 1958: (JUL, 26), + 1959: (JUL, 15), + 1960: (JUL, 3), + 1961: (JUN, 22), + 1962: (JUN, 11), + 1963: (JUN, 1), + 1964: (MAY, 20), + 1965: (MAY, 9), + 1966: (APR, 29), + 1967: (APR, 19), + 1968: (APR, 7), + 1969: (MAR, 27), + 1970: (MAR, 17), + 1971: (MAR, 6), + 1972: (FEB, 24), + 1973: (FEB, 12), + 1974: (FEB, 1), + 1975: (JAN, 21), + 1976: ((JAN, 10), (DEC, 30)), + 1977: (DEC, 19), + 1978: (DEC, 9), + 1979: (NOV, 28), + 1980: (NOV, 17), + 1981: (NOV, 5), + 1982: (OCT, 26), + 1983: (OCT, 15), + 1984: (OCT, 4), + 1985: (SEP, 23), + 1986: (SEP, 13), + 1987: (SEP, 2), + 1988: (AUG, 21), + 1989: (AUG, 10), + 1990: (JUL, 31), + 1991: (JUL, 20), + 1992: (JUL, 9), + 1993: (JUN, 29), + 1994: (JUN, 18), + 1995: (JUN, 7), + 1996: (MAY, 26), + 1997: (MAY, 15), + 1998: (MAY, 5), + 1999: (APR, 25), + 2000: (APR, 14), + 2001: (APR, 3), + 2002: (MAR, 23), + 2003: (MAR, 12), + 2004: (FEB, 29), + 2005: (FEB, 18), + 2006: (FEB, 8), + 2007: (JAN, 28), + 2008: (JAN, 18), + 2009: ((JAN, 6), (DEC, 26)), + 2010: (DEC, 15), + 2011: (DEC, 4), + 2012: (NOV, 23), + 2013: (NOV, 12), + 2014: (NOV, 2), + 2015: (OCT, 22), + 2016: (OCT, 10), + 2017: (SEP, 29), + 2018: (SEP, 19), + 2019: (SEP, 8), + 2020: (AUG, 28), + 2021: (AUG, 17), + 2022: (AUG, 7), + 2023: (JUL, 27), + 2024: (JUL, 15), + 2025: (JUL, 4), + 2026: (JUN, 24), + 2027: (JUN, 14), + 2028: (JUN, 2), + 2029: (MAY, 22), + 2030: (MAY, 11), + 2031: (MAY, 1), + 2032: (APR, 19), + 2033: (APR, 9), + 2034: (MAR, 29), + 2035: (MAR, 19), + 2036: (MAR, 7), + 2037: (FEB, 24), + 2038: (FEB, 13), + 2039: (FEB, 3), + 2040: (JAN, 23), + 2041: (JAN, 12), + 2042: ((JAN, 1), (DEC, 22)), + 2043: (DEC, 11), + 2044: (NOV, 29), + 2045: (NOV, 18), + 2046: (NOV, 8), + 2047: (OCT, 28), + 2048: (OCT, 17), + 2049: (OCT, 6), + 2050: (SEP, 25), + 2051: (SEP, 14), + 2052: (SEP, 3), + 2053: (AUG, 23), + 2054: (AUG, 13), + 2055: (AUG, 2), + 2056: (JUL, 22), + 2057: (JUL, 11), + 2058: (JUN, 30), + 2059: (JUN, 19), + 2060: (JUN, 8), + 2061: (MAY, 28), + 2062: (MAY, 18), + 2063: (MAY, 8), + 2064: (APR, 26), + 2065: (APR, 15), + 2066: (APR, 4), + 2067: (MAR, 24), + 2068: (MAR, 13), + 2069: (MAR, 3), + 2070: (FEB, 20), + 2071: (FEB, 9), + 2072: (JAN, 29), + 2073: (JAN, 17), + 2074: ((JAN, 7), (DEC, 27)), + 2075: (DEC, 17), + 2076: (DEC, 5), + } + + def _get_holiday(self, holiday: str, year: int) -> Iterable[tuple[date, bool]]: + estimated_dates = getattr(self, f"{holiday}_DATES", {}) + exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}) + for year in (year - 1, year): + for dt in _normalize_tuple(exact_dates.get(year, estimated_dates.get(year, ()))): + yield date(year, *dt), year not in exact_dates + + def ali_al_rida_death_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(ALI_AL_RIDA_DEATH, year) + + def ali_birthday_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(ALI_BIRTHDAY, year) + + def ali_death_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(ALI_DEATH, year) + + def arbaeen_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(ARBAEEN, year) + + def ashura_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(ASHURA, year) + + def eid_al_adha_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(EID_AL_ADHA, year) + + def eid_al_fitr_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(EID_AL_FITR, year) + + def eid_al_ghadir_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(EID_AL_GHADIR, year) + + def fatima_death_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(FATIMA_DEATH, year) + + def grand_magal_of_touba_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(GRAND_MAGAL_OF_TOUBA, year) + + def hari_hol_johor_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(HARI_HOL_JOHOR, year) + + def hasan_al_askari_death_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(HASAN_AL_ASKARI_DEATH, year) + + def hijri_new_year_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(HIJRI_NEW_YEAR, year) + + def imam_mahdi_birthday_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(IMAM_MAHDI_BIRTHDAY, year) + + def isra_and_miraj_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(ISRA_AND_MIRAJ, year) + + def laylat_al_qadr_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(LAYLAT_AL_QADR, year) + + def maldives_embraced_islam_day_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(MALDIVES_EMBRACED_ISLAM_DAY, year) + + def mawlid_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(MAWLID, year) + + def nuzul_al_quran_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(NUZUL_AL_QURAN, year) + + def prophet_death_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(PROPHET_DEATH, year) + + def quamee_dhuvas_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(QUAMEE_DHUVAS, year) + + def ramadan_beginning_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(RAMADAN_BEGINNING, year) + + def sadiq_birthday_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(SADIQ_BIRTHDAY, year) + + def sadiq_death_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(SADIQ_DEATH, year) + + def tasua_dates(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday(TASUA, year) + + +class _CustomIslamicHolidays(_CustomCalendar, _IslamicLunar): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/julian.py b/.venv/lib/python3.12/site-packages/holidays/calendars/julian.py new file mode 100644 index 00000000..5cb5db04 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/julian.py @@ -0,0 +1,13 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +JULIAN_CALENDAR = "JULIAN_CALENDAR" diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/julian_revised.py b/.venv/lib/python3.12/site-packages/holidays/calendars/julian_revised.py new file mode 100644 index 00000000..4df80d46 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/julian_revised.py @@ -0,0 +1,13 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +JULIAN_REVISED_CALENDAR = "JULIAN_REVISED_CALENDAR" diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/mongolian.py b/.venv/lib/python3.12/site-packages/holidays/calendars/mongolian.py new file mode 100644 index 00000000..44b2bdc5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/mongolian.py @@ -0,0 +1,342 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.custom import _CustomCalendar +from holidays.calendars.gregorian import JAN, FEB, MAR, MAY, JUN, OCT, NOV, DEC + +BUDDHA_DAY = "BUDDHA_DAY" +GENGHIS_KHAN_DAY = "GENGHIS_KHAN_DAY" +TSAGAAN_SAR = "TSAGAAN_SAR" + + +class _MongolianLunisolar: + BUDDHA_DAY_DATES = { + 2004: (JUN, 3), + 2005: (MAY, 23), + 2006: (JUN, 11), + 2007: (MAY, 31), + 2008: (MAY, 20), + 2009: (JUN, 7), + 2010: (MAY, 27), + 2011: (MAY, 17), + 2012: (JUN, 4), + 2013: (MAY, 25), + 2014: (JUN, 13), + 2015: (JUN, 2), + 2016: (MAY, 21), + 2017: (JUN, 9), + 2018: (MAY, 29), + 2019: (MAY, 18), + 2020: (JUN, 5), + 2021: (MAY, 26), + 2022: (JUN, 14), + 2023: (JUN, 4), + 2024: (MAY, 23), + 2025: (JUN, 11), + 2026: (MAY, 31), + 2027: (MAY, 20), + 2028: (JUN, 7), + 2029: (MAY, 27), + 2030: (MAY, 17), + 2031: (JUN, 5), + 2032: (MAY, 25), + 2033: (JUN, 12), + 2034: (JUN, 2), + 2035: (MAY, 22), + 2036: (JUN, 8), + 2037: (MAY, 29), + 2038: (MAY, 18), + 2039: (JUN, 6), + 2040: (MAY, 26), + 2041: (JUN, 14), + 2042: (JUN, 3), + 2043: (MAY, 23), + 2044: (JUN, 10), + 2045: (MAY, 30), + 2046: (MAY, 20), + 2047: (JUN, 8), + 2048: (MAY, 27), + 2049: (MAY, 17), + 2050: (JUN, 5), + 2051: (MAY, 25), + 2052: (JUN, 12), + 2053: (JUN, 1), + 2054: (MAY, 21), + 2055: (JUN, 9), + 2056: (MAY, 29), + 2057: (MAY, 18), + 2058: (JUN, 6), + 2059: (MAY, 27), + 2060: (JUN, 14), + 2061: (JUN, 3), + 2062: (MAY, 23), + 2063: (JUN, 11), + 2064: (MAY, 30), + 2065: (MAY, 20), + 2066: (JUN, 8), + 2067: (MAY, 28), + 2068: (JUN, 15), + 2069: (JUN, 4), + 2070: (MAY, 24), + 2071: (JUN, 12), + 2072: (MAY, 31), + 2073: (MAY, 21), + 2074: (JUN, 9), + 2075: (MAY, 30), + 2076: (MAY, 18), + 2077: (JUN, 6), + 2078: (MAY, 26), + 2079: (JUN, 14), + 2080: (JUN, 2), + 2081: (MAY, 22), + 2082: (JUN, 10), + 2083: (MAY, 31), + 2084: (MAY, 20), + 2085: (JUN, 8), + 2086: (MAY, 28), + 2087: (JUN, 16), + 2088: (JUN, 4), + 2089: (MAY, 24), + 2090: (JUN, 12), + 2091: (JUN, 1), + 2092: (MAY, 21), + 2093: (JUN, 9), + 2094: (MAY, 30), + 2095: (MAY, 19), + 2096: (JUN, 6), + 2097: (MAY, 26), + 2098: (JUN, 13), + 2099: (JUN, 3), + 2100: (MAY, 23), + } + + GENGHIS_KHAN_DAY_DATES = { + 2004: (NOV, 13), + 2005: (NOV, 2), + 2006: (NOV, 21), + 2007: (NOV, 10), + 2008: (NOV, 28), + 2009: (NOV, 17), + 2010: (NOV, 7), + 2011: (NOV, 26), + 2012: (NOV, 14), + 2013: (NOV, 4), + 2014: (NOV, 23), + 2015: (NOV, 12), + 2016: (OCT, 31), + 2017: (NOV, 19), + 2018: (NOV, 8), + 2019: (NOV, 27), + 2020: (NOV, 16), + 2021: (NOV, 5), + 2022: (NOV, 24), + 2023: (NOV, 14), + 2024: (NOV, 2), + 2025: (NOV, 21), + 2026: (NOV, 10), + 2027: (NOV, 29), + 2028: (NOV, 17), + 2029: (NOV, 7), + 2030: (NOV, 26), + 2031: (NOV, 15), + 2032: (NOV, 4), + 2033: (NOV, 22), + 2034: (NOV, 11), + 2035: (NOV, 30), + 2036: (NOV, 18), + 2037: (NOV, 8), + 2038: (NOV, 27), + 2039: (NOV, 17), + 2040: (NOV, 5), + 2041: (NOV, 24), + 2042: (NOV, 13), + 2043: (NOV, 2), + 2044: (NOV, 20), + 2045: (NOV, 9), + 2046: (NOV, 28), + 2047: (NOV, 18), + 2048: (NOV, 7), + 2049: (NOV, 26), + 2050: (NOV, 15), + 2051: (NOV, 4), + 2052: (NOV, 22), + 2053: (NOV, 11), + 2054: (NOV, 30), + 2055: (NOV, 19), + 2056: (NOV, 8), + 2057: (NOV, 27), + 2058: (NOV, 17), + 2059: (NOV, 6), + 2060: (NOV, 24), + 2061: (NOV, 13), + 2062: (NOV, 2), + 2063: (NOV, 21), + 2064: (NOV, 9), + 2065: (NOV, 28), + 2066: (NOV, 18), + 2067: (NOV, 7), + 2068: (NOV, 25), + 2069: (NOV, 14), + 2070: (NOV, 3), + 2071: (NOV, 22), + 2072: (NOV, 11), + 2073: (NOV, 30), + 2074: (NOV, 19), + 2075: (NOV, 9), + 2076: (NOV, 27), + 2077: (NOV, 16), + 2078: (NOV, 5), + 2079: (NOV, 24), + 2080: (NOV, 12), + 2081: (NOV, 1), + 2082: (NOV, 21), + 2083: (NOV, 10), + 2084: (NOV, 28), + 2085: (NOV, 18), + 2086: (NOV, 7), + 2087: (NOV, 26), + 2088: (NOV, 14), + 2089: (NOV, 3), + 2090: (NOV, 22), + 2091: (NOV, 12), + 2092: (NOV, 30), + 2093: (NOV, 19), + 2094: (NOV, 9), + 2095: (NOV, 27), + 2096: (NOV, 15), + 2097: (NOV, 5), + 2098: (NOV, 23), + 2099: (NOV, 13), + 2100: (DEC, 2), + } + + TSAGAAN_SAR_DATES = { + 2004: (FEB, 21), + 2005: (FEB, 9), + 2006: (JAN, 30), + 2007: (FEB, 18), + 2008: (FEB, 8), + 2009: (FEB, 25), + 2010: (FEB, 14), + 2011: (FEB, 3), + 2012: (FEB, 22), + 2013: (FEB, 11), + 2014: (JAN, 31), + 2015: (FEB, 19), + 2016: (FEB, 9), + 2017: (FEB, 27), + 2018: (FEB, 16), + 2019: (FEB, 5), + 2020: (FEB, 24), + 2021: (FEB, 12), + 2022: (FEB, 2), + 2023: (FEB, 21), + 2024: (FEB, 10), + 2025: (MAR, 1), + 2026: (FEB, 18), + 2027: (FEB, 7), + 2028: (FEB, 26), + 2029: (FEB, 14), + 2030: (FEB, 3), + 2031: (FEB, 22), + 2032: (FEB, 12), + 2033: (JAN, 31), + 2034: (FEB, 19), + 2035: (FEB, 9), + 2036: (FEB, 28), + 2037: (FEB, 16), + 2038: (FEB, 5), + 2039: (FEB, 24), + 2040: (FEB, 13), + 2041: (FEB, 2), + 2042: (FEB, 21), + 2043: (FEB, 10), + 2044: (FEB, 29), + 2045: (FEB, 17), + 2046: (FEB, 6), + 2047: (FEB, 25), + 2048: (FEB, 14), + 2049: (FEB, 3), + 2050: (FEB, 22), + 2051: (FEB, 12), + 2052: (FEB, 1), + 2053: (FEB, 19), + 2054: (FEB, 8), + 2055: (FEB, 27), + 2056: (FEB, 16), + 2057: (FEB, 4), + 2058: (FEB, 23), + 2059: (FEB, 13), + 2060: (FEB, 3), + 2061: (FEB, 21), + 2062: (FEB, 10), + 2063: (MAR, 1), + 2064: (FEB, 18), + 2065: (FEB, 6), + 2066: (FEB, 25), + 2067: (FEB, 14), + 2068: (FEB, 4), + 2069: (FEB, 22), + 2070: (FEB, 12), + 2071: (FEB, 1), + 2072: (FEB, 19), + 2073: (FEB, 7), + 2074: (FEB, 26), + 2075: (FEB, 16), + 2076: (FEB, 5), + 2077: (FEB, 23), + 2078: (FEB, 13), + 2079: (FEB, 2), + 2080: (FEB, 21), + 2081: (FEB, 9), + 2082: (FEB, 28), + 2083: (FEB, 17), + 2084: (FEB, 7), + 2085: (FEB, 25), + 2086: (FEB, 14), + 2087: (FEB, 4), + 2088: (FEB, 23), + 2089: (FEB, 11), + 2090: (MAR, 2), + 2091: (FEB, 19), + 2092: (FEB, 8), + 2093: (FEB, 26), + 2094: (FEB, 16), + 2095: (FEB, 5), + 2096: (FEB, 24), + 2097: (FEB, 13), + 2098: (FEB, 2), + 2099: (FEB, 21), + 2100: (FEB, 10), + } + + def _get_holiday(self, holiday: str, year: int) -> tuple[Optional[date], bool]: + estimated_dates = getattr(self, f"{holiday}_DATES", {}) + exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}) + dt = exact_dates.get(year, estimated_dates.get(year, ())) + return date(year, *dt) if dt else None, year not in exact_dates + + def buddha_day_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(BUDDHA_DAY, year) + + def genghis_khan_day_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(GENGHIS_KHAN_DAY, year) + + def tsagaan_sar_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(TSAGAAN_SAR, year) + + +class _CustomMongolianHolidays(_CustomCalendar, _MongolianLunisolar): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/persian.py b/.venv/lib/python3.12/site-packages/holidays/calendars/persian.py new file mode 100644 index 00000000..42b21ace --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/persian.py @@ -0,0 +1,64 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import _timedelta + + +class _Persian: + """ + Persian calendar (Solar Hijri) for 1901-2100 years. + + https://en.wikipedia.org/wiki/Solar_Hijri_calendar + """ + + START_YEAR = 1901 + END_YEAR = 2100 + + def is_leap_year(self, year: int) -> bool: + """ + Is Persian year that begins in the specified Gregorian year a leap year. + """ + return (year % 33) in {3, 7, 11, 16, 20, 24, 28, 32} + + def new_year_date(self, year: int) -> Optional[date]: + """ + Return Gregorian date of Persian new year (1 Farvardin) in a given Gregorian year. + """ + if year < _Persian.START_YEAR or year > _Persian.END_YEAR: + return None + + day = 21 + if ( + (year % 4 == 1 and year >= 2029) + or (year % 4 == 2 and year >= 2062) + or (year % 4 == 3 and year >= 2095) + or (year % 4 == 0 and 1996 <= year <= 2096) + ): + day = 20 + elif (year % 4 == 2 and year <= 1926) or (year % 4 == 3 and year <= 1959): + day = 22 + return date(year, 3, day) + + def persian_to_gregorian(self, year: int, j_month: int, j_day: int) -> Optional[date]: + """ + Return Gregorian date of Persian day and month in a given Gregorian year. + """ + start_date = self.new_year_date(year) + if not start_date: + return None + + m = j_month - 1 + delta = (31 * m if m < 6 else 186 + 30 * (m - 6)) + j_day - 1 + return _timedelta(start_date, delta) diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/sinhala.py b/.venv/lib/python3.12/site-packages/holidays/calendars/sinhala.py new file mode 100644 index 00000000..ee0b7484 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/sinhala.py @@ -0,0 +1,414 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from collections.abc import Iterable +from datetime import date +from typing import Optional + +from holidays.calendars.custom import _CustomCalendar +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.helpers import _normalize_tuple + +BAK_POYA = "BAK_POYA" +BINARA_POYA = "BINARA_POYA" +DURUTHU_POYA = "DURUTHU_POYA" +ESALA_POYA = "ESALA_POYA" +IL_POYA = "IL_POYA" +MEDIN_POYA = "MEDIN_POYA" +NAWAM_POYA = "NAWAM_POYA" +NIKINI_POYA = "NIKINI_POYA" +POSON_POYA = "POSON_POYA" +UNDUVAP_POYA = "UNDUVAP_POYA" +VAP_POYA = "VAP_POYA" +VESAK_POYA = "VESAK_POYA" + + +class _SinhalaLunar: + """ + Sinhala Lunar calendar for 2003-2025 years. + + Their Buddhist Uposatha day calculation method is different from Thai LuniSolar + and Buddhist (Mahayana) used in East Asia. + + Due to the fact that Poya (Uposatha) days are calculated astronomically + based on how close a particular day is closest to full moon at noon, and that + an extra month is added every 33 months interval, this is hardcoded for now. + + Adhi month dates are instead hardcoded in Sri Lanka country implementation. + """ + + START_YEAR = 2003 + END_YEAR = 2025 + + BAK_POYA_DATES = { + 2003: (APR, 16), + 2004: (APR, 5), + 2005: (APR, 23), + 2006: (APR, 13), + 2007: (APR, 2), + 2008: (APR, 19), + 2009: (APR, 9), + 2010: (MAR, 29), + 2011: (APR, 17), + 2012: (APR, 6), + 2013: (APR, 25), + 2014: (APR, 14), + 2015: (APR, 3), + 2016: (APR, 21), + 2017: (APR, 10), + 2018: (MAR, 31), + 2019: (APR, 19), + 2020: (APR, 7), + 2021: (APR, 26), + 2022: (APR, 16), + 2023: (APR, 5), + 2024: (APR, 23), + 2025: (APR, 12), + } + + BINARA_POYA_DATES = { + 2003: (SEP, 10), + 2004: (SEP, 28), + 2005: (SEP, 17), + 2006: (SEP, 7), + 2007: (SEP, 26), + 2008: (SEP, 14), + 2009: (SEP, 4), + 2010: (SEP, 22), + 2011: (SEP, 11), + 2012: (SEP, 29), + 2013: (SEP, 19), + 2014: (SEP, 8), + 2015: (SEP, 27), + 2016: (SEP, 16), + 2017: (SEP, 5), + 2018: (SEP, 24), + 2019: (SEP, 13), + 2020: (SEP, 1), + 2021: (SEP, 20), + 2022: (SEP, 10), + 2023: (SEP, 29), + 2024: (SEP, 17), + 2025: (SEP, 7), + } + + DURUTHU_POYA_DATES = { + 2003: (JAN, 17), + 2004: (JAN, 7), + 2005: (JAN, 24), + 2006: (JAN, 13), + 2007: (JAN, 3), + 2008: (JAN, 22), + 2009: ((JAN, 10), (DEC, 31)), + 2011: (JAN, 19), + 2012: (JAN, 8), + 2013: (JAN, 26), + 2014: (JAN, 15), + 2015: (JAN, 4), + 2016: (JAN, 23), + 2017: (JAN, 12), + 2018: (JAN, 1), + 2019: (JAN, 20), + 2020: (JAN, 10), + 2021: (JAN, 28), + 2022: (JAN, 17), + 2023: (JAN, 6), + 2024: (JAN, 25), + 2025: (JAN, 13), + } + + ESALA_POYA_DATES = { + 2003: (JUL, 13), + 2004: (JUL, 2), + 2005: (JUL, 21), + 2006: (JUL, 10), + 2007: (JUL, 29), + 2008: (JUL, 17), + 2009: (JUL, 6), + 2010: (JUL, 25), + 2011: (JUL, 14), + 2012: (JUL, 3), + 2013: (JUL, 22), + 2014: (JUL, 12), + 2015: (JUL, 31), + 2016: (JUL, 19), + 2017: (JUL, 8), + 2018: (JUL, 27), + 2019: (JUL, 16), + 2020: (JUL, 4), + 2021: (JUL, 23), + 2022: (JUL, 13), + 2023: (AUG, 1), + 2024: (JUL, 20), + 2025: (JUL, 10), + } + + IL_POYA_DATES = { + 2003: (NOV, 8), + 2004: (NOV, 26), + 2005: (NOV, 15), + 2006: (NOV, 5), + 2007: (NOV, 24), + 2008: (NOV, 12), + 2009: (NOV, 2), + 2010: (NOV, 21), + 2011: (NOV, 10), + 2012: (NOV, 27), + 2013: (NOV, 17), + 2014: (NOV, 6), + 2015: (NOV, 25), + 2016: (NOV, 14), + 2017: (NOV, 3), + 2018: (NOV, 22), + 2019: (NOV, 12), + 2020: (NOV, 29), + 2021: (NOV, 18), + 2022: (NOV, 7), + 2023: (NOV, 26), + 2024: (NOV, 15), + 2025: (NOV, 5), + } + + MEDIN_POYA_DATES = { + 2003: (MAR, 18), + 2004: (MAR, 6), + 2005: (MAR, 25), + 2006: (MAR, 14), + 2007: (MAR, 3), + 2008: (MAR, 21), + 2009: (MAR, 10), + 2010: (FEB, 28), + 2011: (MAR, 19), + 2012: (MAR, 7), + 2013: (MAR, 26), + 2014: (MAR, 16), + 2015: (MAR, 5), + 2016: (MAR, 22), + 2017: (MAR, 12), + 2018: (MAR, 1), + 2019: (MAR, 20), + 2020: (MAR, 9), + 2021: (MAR, 28), + 2022: (MAR, 17), + 2023: (MAR, 6), + 2024: (MAR, 24), + 2025: (MAR, 13), + } + + NAWAM_POYA_DATES = { + 2003: (FEB, 16), + 2004: (FEB, 5), + 2005: (FEB, 23), + 2006: (FEB, 12), + 2007: (FEB, 1), + 2008: (FEB, 20), + 2009: (FEB, 9), + 2010: (JAN, 29), + 2011: (FEB, 17), + 2012: (FEB, 7), + 2013: (FEB, 25), + 2014: (FEB, 14), + 2015: (FEB, 3), + 2016: (FEB, 22), + 2017: (FEB, 10), + 2018: (JAN, 31), + 2019: (FEB, 19), + 2020: (FEB, 8), + 2021: (FEB, 26), + 2022: (FEB, 16), + 2023: (FEB, 5), + 2024: (FEB, 23), + 2025: (FEB, 12), + } + + NIKINI_POYA_DATES = { + 2003: (AUG, 11), + 2004: (AUG, 29), + 2005: (AUG, 19), + 2006: (AUG, 9), + 2007: (AUG, 28), + 2008: (AUG, 16), + 2009: (AUG, 5), + 2010: (AUG, 24), + 2011: (AUG, 13), + 2012: (AUG, 1), + 2013: (AUG, 20), + 2014: (AUG, 10), + 2015: (AUG, 29), + 2016: (AUG, 17), + 2017: (AUG, 7), + 2018: (AUG, 25), + 2019: (AUG, 14), + 2020: (AUG, 3), + 2021: (AUG, 22), + 2022: (AUG, 11), + 2023: (AUG, 30), + 2024: (AUG, 19), + 2025: (AUG, 8), + } + + POSON_POYA_DATES = { + 2003: (JUN, 14), + 2004: (JUN, 2), + 2005: (JUN, 21), + 2006: (JUN, 11), + 2007: (JUN, 30), + 2008: (JUN, 18), + 2009: (JUN, 7), + 2010: (JUN, 25), + 2011: (JUN, 15), + 2012: (JUN, 4), + 2013: (JUN, 23), + 2014: (JUN, 12), + 2015: (JUN, 2), + 2016: (JUN, 19), + 2017: (JUN, 8), + 2018: (JUN, 27), + 2019: (JUN, 16), + 2020: (JUN, 5), + 2021: (JUN, 24), + 2022: (JUN, 14), + 2023: (JUN, 3), + 2024: (JUN, 21), + 2025: (JUN, 10), + } + + UNDUVAP_POYA_DATES = { + 2003: (DEC, 8), + 2004: (DEC, 26), + 2005: (DEC, 15), + 2006: (DEC, 4), + 2007: (DEC, 23), + 2008: (DEC, 12), + 2009: (DEC, 1), + 2010: (DEC, 20), + 2011: (DEC, 10), + 2012: (DEC, 27), + 2013: (DEC, 16), + 2014: (DEC, 6), + 2015: (DEC, 24), + 2016: (DEC, 13), + 2017: (DEC, 3), + 2018: (DEC, 22), + 2019: (DEC, 11), + 2020: (DEC, 29), + 2021: (DEC, 18), + 2022: (DEC, 7), + 2023: (DEC, 26), + 2024: (DEC, 14), + 2025: (DEC, 4), + } + + VAP_POYA_DATES = { + 2003: (OCT, 9), + 2004: (OCT, 27), + 2005: (OCT, 17), + 2006: (OCT, 6), + 2007: (OCT, 25), + 2008: (OCT, 14), + 2009: (OCT, 3), + 2010: (OCT, 22), + 2011: (OCT, 11), + 2012: (OCT, 29), + 2013: (OCT, 18), + 2014: (OCT, 8), + 2015: (OCT, 27), + 2016: (OCT, 15), + 2017: (OCT, 5), + 2018: (OCT, 24), + 2019: (OCT, 13), + 2020: (OCT, 30), + 2021: (OCT, 20), + 2022: (OCT, 9), + 2023: (OCT, 28), + 2024: (OCT, 17), + 2025: (OCT, 6), + } + + VESAK_POYA_DATES = { + 2003: (MAY, 15), + 2004: (MAY, 4), + 2005: (MAY, 23), + 2006: (MAY, 12), + 2007: (MAY, 1), + 2008: (MAY, 19), + 2009: (MAY, 8), + 2010: (MAY, 27), + 2011: (MAY, 17), + 2012: (MAY, 5), + 2013: (MAY, 24), + 2014: (MAY, 14), + 2015: (MAY, 3), + 2016: (MAY, 21), + 2017: (MAY, 10), + 2018: (APR, 29), + 2019: (MAY, 18), + 2020: (MAY, 7), + 2021: (MAY, 26), + 2022: (MAY, 15), + 2023: (MAY, 5), + 2024: (MAY, 23), + 2025: (MAY, 12), + } + + def _get_holiday(self, holiday: str, year: int) -> tuple[Optional[date], bool]: + estimated_dates = getattr(self, f"{holiday}_DATES", {}) + exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}) + dt = exact_dates.get(year, estimated_dates.get(year, ())) + return date(year, *dt) if dt else None, year not in exact_dates + + def _get_holiday_set(self, holiday: str, year: int) -> Iterable[tuple[date, bool]]: + estimated_dates = getattr(self, f"{holiday}_DATES", {}) + exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}) + for year in (year - 1, year): + for dt in _normalize_tuple(exact_dates.get(year, estimated_dates.get(year, ()))): + yield date(year, *dt), year not in exact_dates + + def bak_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(BAK_POYA, year) + + def binara_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(BINARA_POYA, year) + + def duruthu_poya_date(self, year: int) -> Iterable[tuple[date, bool]]: + return self._get_holiday_set(DURUTHU_POYA, year) + + def esala_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(ESALA_POYA, year) + + def il_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(IL_POYA, year) + + def medin_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(MEDIN_POYA, year) + + def nawam_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(NAWAM_POYA, year) + + def nikini_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(NIKINI_POYA, year) + + def poson_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(POSON_POYA, year) + + def unduvap_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(UNDUVAP_POYA, year) + + def vap_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(VAP_POYA, year) + + def vesak_poya_date(self, year: int) -> tuple[Optional[date], bool]: + return self._get_holiday(VESAK_POYA, year) + + +class _CustomSinhalaHolidays(_CustomCalendar, _SinhalaLunar): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/calendars/thai.py b/.venv/lib/python3.12/site-packages/holidays/calendars/thai.py new file mode 100644 index 00000000..f6855f09 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/calendars/thai.py @@ -0,0 +1,799 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from functools import lru_cache +from typing import Optional + +from holidays.calendars.gregorian import _timedelta + +KHMER_CALENDAR = "KHMER_CALENDAR" +THAI_CALENDAR = "THAI_CALENDAR" + + +class _ThaiLunisolar: + """Thai Lunar Calendar Holidays. + + Works from 1913 (B.E. 2456/2455) onwards until 2157 (B.E. 2700), as we only have + Thai year-type data for cross-checking through that period. + + ## The basics of the Thai Lunar Calendar: + + 3-year types for calendar intercalation: + * Pakatimat (Normal Year): + Consists of 12 months, totaling 354 days. + * Athikawan (Extra-Day Year): + Adds one extra day to the 7th month, totaling 355 days for synodic month correction. + * Athikamat (Extra-Month Year): + Adds one extra 8th month, totaling 384 days for sidereal year correction. + + Months alternate between 30 (even months) and 29 (odd months) days. + + The waxing phase (Full Moon) lasts 15 days, while the waning phase (New Moon) lasts + 14 days for odd months (except Month 7 in Athikawan years), 15 days for even months. + + The second "Month 8" for Athikamat years is called "Month 8.8" + (read as "the latter 8th month"), with all observed holidays + delayed from the usual calendar by 30 days. + + Implemented Thai Lunar Calendar holiday methods: + * Magha Puja / Makha Bucha / Meak Bochea: + 15th Waxing Day (Full Moon) of Month 3 (On Month 4 for Athikamat Years). + `KHMER_CALENDAR` always falls on Month 3. + + * Vesak / Visakha Bucha / Visaka Bochea: + 15th Waxing Day (Full Moon) of Month 6 (On Month 7 for Athikamat Years). + `KHMER_CALENDAR` always falls on Month 6. + + * Cambodian Royal Ploughing Ceremony / Preah Neangkol: + 4th Waning Day of Month 6 (On Month 7 for Athikamat Years). + Defaults to `KHMER_CALENDAR` (its sole user). + + * Buddha's Cremation Day / Atthami Bucha: + 8th Waning Day of Month 6 (On Month 7 for Athikamat Years). + `KHMER_CALENDAR` always falls on Month 6. + + * Asalha Puja / Asarnha Bucha: + 15th Waxing Day (Full Moon) of Month 8 (On Month 8.8 for Athikamat Years). + + * Buddhist Lent Day / Wan Khao Phansa: + 1st Waning Day of Month 8 (On Month 8.8 for Athikamat Years). + + * Boun Haw Khao Padapdin / Boon Khao Padap Din: + 14th Waning Day (New Moon) of Month 9. + + * Boun Haw Khao Salark / Boon Khao Sak: + 15th Waxing Day (Full Moon) of Month 10. + + * Pchum Ben / Prachum Bandar: + 15th Waning Day (New Moon) of Month 10. + + * Ok Boun Suang Huea / Vientiane Boat Racing Festival: + 1st Waning Day (New Moon) of Month 11. + + * Loy Krathong / Boun That Louang / Bon Om Touk: + 15th Waxing Day (Full Moon) of Month 12. + + Other Thai Lunar Calendar holidays: + * Thai Royal Ploughing Ceremony / Raeknakhwan: + Court astrologers choose the auspicious dates based on the Thai Lunar Calendar, + but these dates do not follow a predictable pattern. + See the specific section in `thailand.py` for more details. + + * End of Buddhist Lent Day / Ok Phansa: + 15th Waxing Day (Full Moon) of Month 11 + (Currently calculated based on Asalha Puja / Asarnha Bucha method). + + Notes: + The following code is based on Ninenik Narkdee's PHP implementation, + and we're thankful for his work. + + References: + * + * + + Example: + + >>> from holidays.calendars.thai import _ThaiLunisolar + >>> thls = _ThaiLunisolar() + >>> print(thls.visakha_bucha_date(2010)) + 2010-05-28 + + """ + + # Athikawan (Extra-Day Year) list goes from 1914-2157 C.E. + # Copied off from 1757-2157 (B.E. 2300-2700) Thai Lunar Calendar + ATHIKAWAN_YEARS_GREGORIAN = { + 1914, + 1917, + 1925, + 1929, + 1933, + 1936, + 1945, + 1949, + 1952, + 1957, + 1963, + 1970, + 1973, + 1979, + 1987, + 1990, + 1997, + 2000, + 2006, + 2009, + 2016, + 2020, + 2025, + 2032, + 2035, + 2043, + 2046, + 2052, + 2055, + 2058, + 2067, + 2071, + 2076, + 2083, + 2086, + 2092, + 2097, + 2103, + 2109, + 2111, + 2117, + 2121, + 2126, + 2133, + 2136, + 2142, + 2147, + 2153, + } + + # Athikamat (Extra-Month Year) list goes from 1914-2157 C.E.: + # Copied off from 1757-2157 (B.E. 2300-2700) Thai Lunar Calendar + # Approx formula as follows: (common_era-78)-0.45222)%2.7118886 < 1 + ATHIKAMAT_YEARS_GREGORIAN = { + 1915, + 1918, + 1920, + 1923, + 1926, + 1928, + 1931, + 1934, + 1937, + 1939, + 1942, + 1944, + 1947, + 1950, + 1953, + 1956, + 1958, + 1961, + 1964, + 1966, + 1969, + 1972, + 1975, + 1977, + 1980, + 1983, + 1985, + 1988, + 1991, + 1994, + 1996, + 1999, + 2002, + 2004, + 2007, + 2010, + 2012, + 2015, + 2018, + 2021, + 2023, + 2026, + 2029, + 2031, + 2034, + 2037, + 2040, + 2042, + 2045, + 2048, + 2050, + 2053, + 2056, + 2059, + 2062, + 2064, + 2066, + 2069, + 2072, + 2074, + 2077, + 2080, + 2082, + 2085, + 2088, + 2091, + 2094, + 2096, + 2099, + 2101, + 2104, + 2107, + 2112, + 2114, + 2116, + 2119, + 2122, + 2124, + 2127, + 2130, + 2132, + 2135, + 2138, + 2141, + 2144, + 2146, + 2149, + 2151, + 2154, + 2157, + } + + # While Buddhist Holy Days have been observed since the 1900s + # Thailand's Public Holiday Act wasn't codified until 1914 (B.E. 2457) + # and that our array only goes up to B.E. 2700; We'll thus only populate + # the data for 1914-2157 (B.E. 2457-2700). + # Sources: หนังสือเวียนกรมการปกครอง กระทรวงมหาดไทย มท 0310.1/ว4 5 ก.พ. 2539 + START_DATE = date(1913, 11, 28) + START_YEAR = 1914 + END_YEAR = 2157 + + def __init__(self, calendar=THAI_CALENDAR) -> None: + self.__verify_calendar(calendar) + self.__calendar = calendar + + @staticmethod + def __is_khmer_calendar(calendar) -> bool: + """Check if the given calendar is the Khmer calendar. + + Args: + calendar: + The calendar identifier to check. + + Returns: + True if the calendar is `KHMER_CALENDAR`, False otherwise. + """ + return calendar == KHMER_CALENDAR + + @staticmethod + def __verify_calendar(calendar) -> None: + """Verify calendar type.""" + if calendar not in {KHMER_CALENDAR, THAI_CALENDAR}: + raise ValueError( + f"Unknown calendar name: {calendar}. Use `KHMER_CALENDAR` or `THAI_CALENDAR`." + ) + + @lru_cache + def _get_start_date(self, year: int) -> Optional[date]: + """Calculate the start date of that particular Thai Lunar Calendar Year. + + This usually falls in November or December of the previous Gregorian + year in question. Should the year be outside of working scope + (1914-2157: B.E 2457-2700), this will returns None instead. + + Args: + year: + The Gregorian year. + + Returns: + The start date of Thai Lunar Calendar for a Gregorian year. + """ + if year < _ThaiLunisolar.START_YEAR or year > _ThaiLunisolar.END_YEAR: + return None + + delta_days = 354 * (year - _ThaiLunisolar.START_YEAR) + for iter_year in range(_ThaiLunisolar.START_YEAR, year): + if iter_year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days += 30 + elif iter_year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days += 1 + + return _timedelta(_ThaiLunisolar.START_DATE, delta_days) + + def makha_bucha_date(self, year: int, calendar=None) -> Optional[date]: + """Calculate the estimated Gregorian date of Makha Bucha. + + Also known as "Magha Puja", "Makha Buxha" and "Meak Bochea". + This coincides with the 15th Waxing Day of Month 3 + in Thai Lunar Calendar, or Month 4 in Athikamat years. + + `KHMER_CALENDAR` will always use Month 3 regardless of year type. + + To calculate, we use the following time delta: + + * Athikamat: + 15th Waxing Day of Month 4 or 29[1] + 30[2] + 29[3] + 15[4] -1 = 102 + + * Athikawan: + 15th Waxing Day of Month 3 or 29[1] + 30[2] + 15[3] -1 = 73 + + * Pakatimat: + 15th Waxing Day of Month 3 or 29[1] + 30[2] + 15[3] -1 = 73 + + Args: + year: + The Gregorian year. + + calendar: + Calendar type, this defaults to THAI_CALENDAR. + + Returns: + Estimated Gregorian date of Makha Bucha. + Returns None if the Gregorian year input is invalid. + """ + calendar = calendar or self.__calendar + self.__verify_calendar(calendar) + + start_date = self._get_start_date(year) + if not start_date: + return None + + return _timedelta( + start_date, + +102 + if ( + year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN + and not self.__is_khmer_calendar(calendar) + ) + else +73, + ) + + def visakha_bucha_date(self, year: int, calendar=None) -> Optional[date]: + """Calculate the estimated Gregorian date of Visakha Bucha. + + Also known as "Vesak" and "Buddha Day". This coincides with + the 15th Waxing Day of Month 6 in Thai Lunar Calendar, or Month 7 in Athikamat years. + + `KHMER_CALENDAR` will always use Month 6 regardless of year type. + + To calculate, we use use the following time delta: + + * Athikamat: + 15th Waxing Day of Month 7 or 177[1-6] + 15[7] -1 = 191 + + * Athikawan: + 15th Waxing Day of Month 6 or 147[1-5] + 15[6] -1 = 161 + + * Pakatimat: + 15th Waxing Day of Month 6 or 147[1-5] + 15[6] -1 = 161 + + Args: + year: + The Gregorian year. + + calendar: + Calendar type, this defaults to THAI_CALENDAR. + + Returns: + Estimated Gregorian date of Visakha Bucha. + Returns None if the Gregorian year input is invalid. + """ + calendar = calendar or self.__calendar + self.__verify_calendar(calendar) + + start_date = self._get_start_date(year) + if not start_date: + return None + + return _timedelta( + start_date, + +191 + if ( + year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN + and not self.__is_khmer_calendar(calendar) + ) + else +161, + ) + + def preah_neangkoal_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Preah Neangkoal. + + Also known as "Cambodian Royal Ploughing Ceremony". This always + coincides with the 4th Waning Day of Month 6 in Khmer Lunar Calendar. + + To calculate, we use use the following time delta: + + * Athikamat: + 4th Waning Day of Month 6 (Khmer Lunar Calendar) or 177[1-5] + 19[6] -1 = 165 + + * Athikawan: + 4th Waning Day of Month 6 or 147[1-5] + 19[6] -1 = 165 + + * Pakatimat: + 4th Waning Day of Month 6 or 147[1-5] + 19[6] -1 = 165 + + Or as in simpler terms: "Visakha Bucha" (Khmer Lunar Calendar) +4. + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Preah Neangkoal. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + return _timedelta(start_date, +165) + + def atthami_bucha_date(self, year: int, calendar=None) -> Optional[date]: + """Calculate the estimated Gregorian date of Atthami Bucha. + + Also known as "Buddha's Cremation Day". This coincides with + the 8th Waning Day of Month 6 in Thai Lunar Calendar, or Month 7 in Athikamat years. + + `KHMER_CALENDAR` will always use Month 6 regardless of year type. + + To calculate, we use use the following time delta: + + * Athikamat: + 8th Waning Day of Month 7 or 177[1-6] + 23[7] -1 = 199 + + * Athikawan: + 8th Waning Day of Month 6 or 147[1-5] + 23[6] -1 = 169 + + * Pakatimat: + 8th Waning Day of Month 6 or 147[1-5] + 23[6] -1 = 169 + + Or as in simpler terms: "Visakha Bucha" +8 + + Args: + year: + The Gregorian year. + + calendar: + Calendar type, this defaults to THAI_CALENDAR. + + Returns: + Estimated Gregorian date of Atthami Bucha. + Returns None if the Gregorian year input is invalid. + """ + calendar = calendar or self.__calendar + self.__verify_calendar(calendar) + + start_date = self._get_start_date(year) + if not start_date: + return None + + return _timedelta( + start_date, + +199 + if ( + year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN + and not self.__is_khmer_calendar(calendar) + ) + else +169, + ) + + def asarnha_bucha_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Asarnha Bucha. + + Also known as "Asalha Puja". This coincides with + the 15th Waxing Day of Month 8 in Thai Lunar Calendar, + or Month 8.8 in Athikamat years. + + Lao Start of Buddhist Lent start on this day (1-day earlier than Thai and Khmer ones). + + To calculate, we use the following time delta: + + * Athikamat: + 15th Waxing Day of Month 8/8 or 177[1-6] + 29[7] + 30[8] + 15[8.8] -1 = 250 + + * Athikawan: + 15th Waxing Day of Month 8 or 177[1-6] + 30[7] + 15[8] -1 = 221 + + * Pakatimat: + 15th Waxing Day of Month 8 or 177[1-6] + 29[7] + 15[8] -1 = 220 + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Asarnha Bucha. + Returns None if the Gregorian year input is invalid. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days = +250 + elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days = +221 + else: + delta_days = +220 + return _timedelta(start_date, delta_days) + + def khao_phansa_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Khao Phansa. + + Also known as "(Start of) Buddhist Lent" and "Start of Vassa". + This coincides with the 1st Waning Day of Month 8 + in Thai Lunar Calendar, or Month 8.8 in Athikamat years. + + To calculate, we use use the following time delta: + + * Athikamat: + 1st Waning Day of Month 8.8 or 177[1-6] + 29[7] + 30[8] + 16[8.8] -1 = 251 + + * Athikawan: + 1st Waning Day of Month 8 or 177[1-6] + 30[7] + 16[8] -1 = 222 + + * Pakatimat: + 1st Waning Day of Month 8 or 177[1-6] + 29[7] + 16[8] -1 = 221 + + Or as in simpler terms: "Asarnha Bucha" +1 + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Khao Phansa. + Returns None if the Gregorian year input is invalid. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days = +251 + elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days = +222 + else: + delta_days = +221 + return _timedelta(start_date, delta_days) + + def boun_haw_khao_padapdin_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Boun Haw Khao Padapdin. + + Also known as "Boon Khao Padap Din". + This coincides with the 14th Waning Day of Month 9 in Thai Lunar Calendar. + + To calculate, we use use the following time delta: + + * Athikamat: + 14th Waning Day of Month 9 or 236[1-8] + 30[8.8] + 29[9] -1 = 294 + + * Athikawan: + 14th Waning Day of Month 9 or 236[1-8] + 1[7] + 29[9] -1 = 265 + + * Pakatimat: + 14th Waning Day of Month 9 or 236[1-8] + 29[9] -1 = 264 + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Boun Haw Khao Padapdin. + Returns None if the Gregorian year input is invalid. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days = +294 + elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days = +265 + else: + delta_days = +264 + return _timedelta(start_date, delta_days) + + def boun_haw_khao_salark_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Boun Haw Khao Salark. + + Also known as "Boon Khao Sak". + This coincides with the 15th Waxing Day of Month 10 in Thai Lunar Calendar. + + To calculate, we use use the following time delta: + + * Athikamat: + 15th Waxing Day of Month 10 or 265[1-9] + 30[8.8] + 15[10] -1 = 309 + + * Athikawan: + 15th Waxing Day of Month 10 or 265[1-9] + 1[7] + 15[10] -1 = 280 + + * Pakatimat: + 15th Waxing Day of Month 10 or 265[1-9] + 15[10] -1 = 279 + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Boun Haw Khao Salark. + Returns None if the Gregorian year input is invalid. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days = +309 + elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days = +280 + else: + delta_days = +279 + return _timedelta(start_date, delta_days) + + def pchum_ben_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Pchum Ben. + + Also known as "Prachum Bandar". + This coincides with the 15th Waning Day of Month 10 in Thai Lunar Calendar. + + To calculate, we use use the following time delta: + + * Athikamat: + 15th Waning Day of Month 10 or 265[1-9] + 30[8.8] + 30[10] -1 = 324 + + * Athikawan: + 15th Waning Day of Month 10 or 265[1-9] + 1[7] + 30[10] -1 = 295 + + * Pakatimat: + 15th Waning Day of Month 10 or 265[1-9] + 30[10] -1 = 294 + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Pchum Ben. + Returns None if the Gregorian year input is invalid. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days = +324 + elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days = +295 + else: + delta_days = +294 + return _timedelta(start_date, delta_days) + + def ok_phansa_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Ok Phansa. + + Also known as "End of Buddhist Lent" and "End of Vassa". + This coincides with the 15th Waxing Day of Month 11 in Thai Lunar Calendar. + + To calculate, we use use the following time delta: + + * Athikamat: + 15th Waxing Day of Month 11 or 295[1-10] + 30[8.8] + 15[11] -1 = 339 + + * Athikawan: + 15th Waxing Day of Month 11 or 295[1-10] + 1[7] + 15[11] -1 = 310 + + * Pakatimat: + 15th Waxing Day of Month 11 or 295[1-10] + 15[11] -1 = 309 + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Ok Phansa. + Returns None if the Gregorian year input is invalid. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days = +339 + elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days = +310 + else: + delta_days = +309 + return _timedelta(start_date, delta_days) + + def boun_suang_heua_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Ok Boun Suang Huea. + + Boun Suang Huea Nakhone Luang Prabang, also known as "Vientiane Boat Racing Festival". + This coincides with the 1st Waning Day of Month 11 in Thai Lunar Calendar. + + To calculate, we use use the following time delta: + + * Athikamat: + 1st Waning Day of Month 11 or 295[1-10] + 30[8.8] + 16[11] -1 = 340 + + * Athikawan: + 1st Waning Day of Month 11 or 295[1-10] + 1[7] + 16[11] -1 = 311 + + * Pakatimat: + 1st Waning Day of Month 11 or 295[1-10] + 16[11] -1 = 310 + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Boun Suang Huea. + Returns None if the Gregorian year input is invalid. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days = +340 + elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days = +311 + else: + delta_days = +310 + return _timedelta(start_date, delta_days) + + def loy_krathong_date(self, year: int) -> Optional[date]: + """Calculate the estimated Gregorian date of Loy Krathong. + + Also known as "Boun That Louang" and "Bon Om Touk". + This coincides with the 15th Waxing Day of Month 12 in Thai Lunar Calendar. + + To calculate, we use use the following time delta: + + * Athikamat: + 15th Waxing Day of Month 12 or 324[1-11] + 30[8.8] + 15[11] -1 = 368 + + * Athikawan: + 15th Waxing Day of Month 12 or 324[1-11] + 1[7] + 15[11] -1 = 339 + + * Pakatimat: + 15th Waxing Day of Month 12 or 324[1-11] + 15[11] -1 = 338 + + Args: + year: + The Gregorian year. + + Returns: + Estimated Gregorian date of Loy Krathong. + Returns None if the Gregorian year input is invalid. + """ + start_date = self._get_start_date(year) + if not start_date: + return None + + if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN: + delta_days = +368 + elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN: + delta_days = +339 + else: + delta_days = +338 + return _timedelta(start_date, delta_days) diff --git a/.venv/lib/python3.12/site-packages/holidays/constants.py b/.venv/lib/python3.12/site-packages/holidays/constants.py new file mode 100644 index 00000000..aab5aa58 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/constants.py @@ -0,0 +1,69 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +# ruff: noqa: F401 + +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + MON, + TUE, + WED, + THU, + FRI, + SAT, + SUN, + WEEKEND, +) + +HOLIDAY_NAME_DELIMITER = "; " # Holiday names separator. + +# Supported holiday categories. +ARMED_FORCES = "armed_forces" +BANK = "bank" +GOVERNMENT = "government" +HALF_DAY = "half_day" +MANDATORY = "mandatory" +OPTIONAL = "optional" +PUBLIC = "public" +SCHOOL = "school" +UNOFFICIAL = "unofficial" +WORKDAY = "workday" + +CATHOLIC = "catholic" +CHINESE = "chinese" +CHRISTIAN = "christian" +HEBREW = "hebrew" +HINDU = "hindu" +ISLAMIC = "islamic" +ORTHODOX = "orthodox" + +ALBANIAN = "albanian" +ARMENIAN = "armenian" +BOSNIAN = "bosnian" +ROMA = "roma" +SERBIAN = "serbian" +TURKISH = "turkish" +VLACH = "vlach" + +DEFAULT_START_YEAR = 1901 +DEFAULT_END_YEAR = 2100 diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__init__.py b/.venv/lib/python3.12/site-packages/holidays/countries/__init__.py new file mode 100644 index 00000000..5ff66a62 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/__init__.py @@ -0,0 +1,261 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +# ruff: noqa: F401 + +from holidays.countries.afghanistan import Afghanistan, AF, AFG +from holidays.countries.aland_islands import AlandIslands, AX, ALA, HolidaysAX +from holidays.countries.albania import Albania, AL, ALB +from holidays.countries.algeria import Algeria, DZ, DZA +from holidays.countries.american_samoa import AmericanSamoa, AS, ASM, HolidaysAS +from holidays.countries.andorra import Andorra, AD, AND +from holidays.countries.angola import Angola, AO, AGO +from holidays.countries.anguilla import Anguilla, AI, AIA +from holidays.countries.antigua_and_barbuda import AntiguaAndBarbuda, AG, ATG +from holidays.countries.argentina import Argentina, AR, ARG +from holidays.countries.armenia import Armenia, AM, ARM +from holidays.countries.aruba import Aruba, AW, ABW +from holidays.countries.australia import Australia, AU, AUS +from holidays.countries.austria import Austria, AT, AUT +from holidays.countries.azerbaijan import Azerbaijan, AZ, AZE +from holidays.countries.bahamas import Bahamas, BS, BHS +from holidays.countries.bahrain import Bahrain, BH, BAH +from holidays.countries.bangladesh import Bangladesh, BD, BGD +from holidays.countries.barbados import Barbados, BB, BRB +from holidays.countries.belarus import Belarus, BY, BLR +from holidays.countries.belgium import Belgium, BE, BEL +from holidays.countries.belize import Belize, BZ, BLZ +from holidays.countries.benin import Benin, BJ, BEN +from holidays.countries.bermuda import Bermuda, BM, BMU +from holidays.countries.bolivia import Bolivia, BO, BOL +from holidays.countries.bonaire_sint_eustatius_and_saba import BonaireSintEustatiusAndSaba, BQ, BES +from holidays.countries.bosnia_and_herzegovina import BosniaAndHerzegovina, BA, BIH +from holidays.countries.botswana import Botswana, BW, BWA +from holidays.countries.brazil import Brazil, BR, BRA +from holidays.countries.british_virgin_islands import BritishVirginIslands, VG, VGB +from holidays.countries.brunei import Brunei, BN, BRN +from holidays.countries.bulgaria import Bulgaria, BG, BLG +from holidays.countries.burkina_faso import BurkinaFaso, BF, BFA +from holidays.countries.burundi import Burundi, BI, BDI +from holidays.countries.cabo_verde import CaboVerde, CV, CPV +from holidays.countries.cambodia import Cambodia, KH, KHM +from holidays.countries.cameroon import Cameroon, CM, CMR +from holidays.countries.canada import Canada, CA, CAN +from holidays.countries.cayman_islands import CaymanIslands, KY, CYM +from holidays.countries.central_african_republic import CentralAfricanRepublic, CF, CAF +from holidays.countries.chad import Chad, TD, TCD +from holidays.countries.chile import Chile, CL, CHL +from holidays.countries.china import China, CN, CHN +from holidays.countries.christmas_island import ChristmasIsland, CX, CXR +from holidays.countries.cocos_islands import CocosIslands, CC, CCK +from holidays.countries.colombia import Colombia, CO, COL +from holidays.countries.congo import Congo, CG, COG +from holidays.countries.cook_islands import CookIslands, CK, COK +from holidays.countries.costa_rica import CostaRica, CR, CRI +from holidays.countries.croatia import Croatia, HR, HRV +from holidays.countries.cuba import Cuba, CU, CUB +from holidays.countries.curacao import Curacao, CW, CUW +from holidays.countries.cyprus import Cyprus, CY, CYP +from holidays.countries.czechia import Czechia, CZ, CZE +from holidays.countries.denmark import Denmark, DK, DNK +from holidays.countries.djibouti import Djibouti, DJ, DJI +from holidays.countries.dominica import Dominica, DM, DMA +from holidays.countries.dominican_republic import DominicanRepublic, DO, DOM +from holidays.countries.dr_congo import DRCongo, CD, COD +from holidays.countries.ecuador import Ecuador, EC, ECU +from holidays.countries.egypt import Egypt, EG, EGY +from holidays.countries.el_salvador import ElSalvador, SV, SLV +from holidays.countries.equatorial_guinea import EquatorialGuinea, GQ, GNQ +from holidays.countries.estonia import Estonia, EE, EST +from holidays.countries.eswatini import Eswatini, SZ, SZW, Swaziland +from holidays.countries.ethiopia import Ethiopia, ET, ETH +from holidays.countries.falkland_islands import FalklandIslands, FK, FLK +from holidays.countries.faroe_islands import FaroeIslands, FO, FRO +from holidays.countries.fiji import Fiji, FJ, FJI +from holidays.countries.finland import Finland, FI, FIN +from holidays.countries.france import France, FR, FRA +from holidays.countries.french_guiana import FrenchGuiana, GF, GUF, HolidaysGF +from holidays.countries.french_polynesia import FrenchPolynesia, PF, PYF, HolidaysPF +from holidays.countries.french_southern_territories import ( + FrenchSouthernTerritories, + TF, + ATF, + HolidaysTF, +) +from holidays.countries.gabon import Gabon, GA, GAB +from holidays.countries.georgia import Georgia, GE, GEO +from holidays.countries.germany import Germany, DE, DEU +from holidays.countries.ghana import Ghana, GH, GHA +from holidays.countries.gibraltar import Gibraltar, GI, GIB +from holidays.countries.greece import Greece, GR, GRC +from holidays.countries.greenland import Greenland, GL, GRL +from holidays.countries.grenada import Grenada, GD, GRD +from holidays.countries.guadeloupe import Guadeloupe, GP, GLP, HolidaysGP +from holidays.countries.guam import Guam, GU, GUM, HolidaysGU +from holidays.countries.guatemala import Guatemala, GT, GUA +from holidays.countries.guernsey import Guernsey, GG, GGY +from holidays.countries.guinea import Guinea, GN, GIN +from holidays.countries.guyana import Guyana, GY, GUY +from holidays.countries.haiti import Haiti, HT, HTI +from holidays.countries.honduras import Honduras, HN, HND +from holidays.countries.hongkong import HongKong, HK, HKG +from holidays.countries.hungary import Hungary, HU, HUN +from holidays.countries.iceland import Iceland, IS, ISL +from holidays.countries.india import India, IN, IND +from holidays.countries.indonesia import Indonesia, ID, IDN +from holidays.countries.iran import Iran, IR, IRN +from holidays.countries.ireland import Ireland, IE, IRL +from holidays.countries.isle_of_man import IsleOfMan, IM, IMN +from holidays.countries.israel import Israel, IL, ISR +from holidays.countries.italy import Italy, IT, ITA +from holidays.countries.ivory_coast import IvoryCoast, CI, CIV +from holidays.countries.jamaica import Jamaica, JM, JAM +from holidays.countries.japan import Japan, JP, JPN +from holidays.countries.jersey import Jersey, JE, JEY +from holidays.countries.jordan import Jordan, JO, JOR +from holidays.countries.kazakhstan import Kazakhstan, KZ, KAZ +from holidays.countries.kenya import Kenya, KE, KEN +from holidays.countries.kuwait import Kuwait, KW, KWT +from holidays.countries.kyrgyzstan import Kyrgyzstan, KG, KGZ +from holidays.countries.laos import Laos, LA, LAO +from holidays.countries.latvia import Latvia, LV, LVA +from holidays.countries.lebanon import Lebanon, LB, LBN +from holidays.countries.lesotho import Lesotho, LS, LSO +from holidays.countries.libya import Libya, LY, LBY +from holidays.countries.liechtenstein import Liechtenstein, LI, LIE +from holidays.countries.lithuania import Lithuania, LT, LTU +from holidays.countries.luxembourg import Luxembourg, LU, LUX +from holidays.countries.macau import Macau, MO, MAC +from holidays.countries.madagascar import Madagascar, MG, MDG +from holidays.countries.malawi import Malawi, MW, MWI +from holidays.countries.malaysia import Malaysia, MY, MYS +from holidays.countries.maldives import Maldives, MV, MDV +from holidays.countries.mali import Mali, ML, MLI +from holidays.countries.malta import Malta, MT, MLT +from holidays.countries.marshall_islands import MarshallIslands, MH, MHL, HolidaysMH +from holidays.countries.martinique import Martinique, MQ, MTQ, HolidaysMQ +from holidays.countries.mauritania import Mauritania, MR, MRT +from holidays.countries.mauritius import Mauritius, MU, MUS +from holidays.countries.mayotte import Mayotte, YT, MYT, HolidaysYT +from holidays.countries.mexico import Mexico, MX, MEX +from holidays.countries.micronesia import Micronesia, FM, FSM +from holidays.countries.moldova import Moldova, MD, MDA +from holidays.countries.monaco import Monaco, MC, MCO +from holidays.countries.mongolia import Mongolia, MN, MNG +from holidays.countries.montenegro import Montenegro, ME, MNE +from holidays.countries.montserrat import Montserrat, MS, MSR +from holidays.countries.morocco import Morocco, MA, MOR +from holidays.countries.mozambique import Mozambique, MZ, MOZ +from holidays.countries.namibia import Namibia, NA, NAM +from holidays.countries.nauru import Nauru, NR, NRU +from holidays.countries.nepal import Nepal, NP, NPL +from holidays.countries.netherlands import Netherlands, NL, NLD +from holidays.countries.new_caledonia import NewCaledonia, NC, NCL, HolidaysNC +from holidays.countries.new_zealand import NewZealand, NZ, NZL +from holidays.countries.nicaragua import Nicaragua, NI, NIC +from holidays.countries.niger import Niger, NE, NER +from holidays.countries.nigeria import Nigeria, NG, NGA +from holidays.countries.niue import Niue, NU, NIU +from holidays.countries.norfolk_island import NorfolkIsland, NF, NFK +from holidays.countries.north_macedonia import NorthMacedonia, MK, MKD +from holidays.countries.northern_mariana_islands import NorthernMarianaIslands, MP, MNP, HolidaysMP +from holidays.countries.norway import Norway, NO, NOR +from holidays.countries.oman import Oman, OM, OMN +from holidays.countries.pakistan import Pakistan, PK, PAK +from holidays.countries.palau import Palau, PW, PLW +from holidays.countries.palestine import Palestine, PS, PSE +from holidays.countries.panama import Panama, PA, PAN +from holidays.countries.papua_new_guinea import PapuaNewGuinea, PG, PNG +from holidays.countries.paraguay import Paraguay, PY, PRY +from holidays.countries.peru import Peru, PE, PER +from holidays.countries.philippines import Philippines, PH, PHL +from holidays.countries.poland import Poland, PL, POL +from holidays.countries.portugal import Portugal, PT, PRT +from holidays.countries.puerto_rico import PuertoRico, PR, PRI, HolidaysPR +from holidays.countries.qatar import Qatar, QA, QAT +from holidays.countries.reunion import Reunion, RE, REU, HolidaysRE +from holidays.countries.romania import Romania, RO, ROU +from holidays.countries.russia import Russia, RU, RUS +from holidays.countries.saint_barthelemy import SaintBarthelemy, BL, BLM, HolidaysBL +from holidays.countries.saint_kitts_and_nevis import SaintKittsAndNevis, KN, KNA +from holidays.countries.saint_lucia import SaintLucia, LC, LCA +from holidays.countries.saint_martin import SaintMartin, MF, MAF, HolidaysMF +from holidays.countries.saint_pierre_and_miquelon import ( + SaintPierreAndMiquelon, + PM, + SPM, + HolidaysPM, +) +from holidays.countries.saint_vincent_and_the_grenadines import ( + SaintVincentAndTheGrenadines, + VC, + VCT, +) +from holidays.countries.samoa import Samoa, WS, WSM +from holidays.countries.san_marino import SanMarino, SM, SMR +from holidays.countries.sao_tome_and_principe import SaoTomeAndPrincipe, ST, STP +from holidays.countries.saudi_arabia import SaudiArabia, SA, SAU +from holidays.countries.senegal import Senegal, SN, SEN +from holidays.countries.serbia import Serbia, RS, SRB +from holidays.countries.seychelles import Seychelles, SC, SYC +from holidays.countries.sierra_leone import SierraLeone, SL, SLE +from holidays.countries.singapore import Singapore, SG, SGP +from holidays.countries.sint_maarten import SintMaarten, SX, SXM +from holidays.countries.slovakia import Slovakia, SK, SVK +from holidays.countries.slovenia import Slovenia, SI, SVN +from holidays.countries.solomon_islands import SolomonIslands, SB, SLB +from holidays.countries.south_africa import SouthAfrica, ZA, ZAF +from holidays.countries.south_korea import SouthKorea, KR, KOR, Korea +from holidays.countries.spain import Spain, ES, ESP +from holidays.countries.sri_lanka import SriLanka, LK, LKA +from holidays.countries.suriname import Suriname, SR, SUR +from holidays.countries.svalbard_and_jan_mayen import SvalbardAndJanMayen, SJ, SJM, HolidaysSJ +from holidays.countries.sweden import Sweden, SE, SWE +from holidays.countries.switzerland import Switzerland, CH, CHE +from holidays.countries.taiwan import Taiwan, TW, TWN +from holidays.countries.tanzania import Tanzania, TZ, TZA +from holidays.countries.thailand import Thailand, TH, THA +from holidays.countries.timor_leste import TimorLeste, TL, TLS +from holidays.countries.togo import Togo, TG, TGO +from holidays.countries.tokelau import Tokelau, TK, TKL +from holidays.countries.tonga import Tonga, TO, TON +from holidays.countries.trinidad_and_tobago import TrinidadAndTobago, TT, TTO +from holidays.countries.tunisia import Tunisia, TN, TUN +from holidays.countries.turkey import Turkey, TR, TUR +from holidays.countries.turks_and_caicos_islands import TurksAndCaicosIslands, TC, TCA +from holidays.countries.tuvalu import Tuvalu, TV, TUV +from holidays.countries.ukraine import Ukraine, UA, UKR +from holidays.countries.united_arab_emirates import UnitedArabEmirates, AE, ARE +from holidays.countries.united_kingdom import UnitedKingdom, GB, GBR, UK +from holidays.countries.united_states import UnitedStates, US, USA +from holidays.countries.united_states_minor_outlying_islands import ( + UnitedStatesMinorOutlyingIslands, + UM, + UMI, + HolidaysUM, +) +from holidays.countries.united_states_virgin_islands import ( + UnitedStatesVirginIslands, + VI, + VIR, + HolidaysVI, +) +from holidays.countries.uruguay import Uruguay, UY, URY +from holidays.countries.uzbekistan import Uzbekistan, UZ, UZB +from holidays.countries.vanuatu import Vanuatu, VU, VTU +from holidays.countries.vatican_city import VaticanCity, VA, VAT +from holidays.countries.venezuela import Venezuela, VE, VEN +from holidays.countries.vietnam import Vietnam, VN, VNM +from holidays.countries.wallis_and_futuna import WallisAndFutuna, WF, WLF, HolidaysWF +from holidays.countries.yemen import Yemen, YE, YEM +from holidays.countries.zambia import Zambia, ZM, ZMB +from holidays.countries.zimbabwe import Zimbabwe, ZW, ZWE diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..dbf33955 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/afghanistan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/afghanistan.cpython-312.pyc new file mode 100644 index 00000000..d205102d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/afghanistan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/aland_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/aland_islands.cpython-312.pyc new file mode 100644 index 00000000..b7d5b66d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/aland_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/albania.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/albania.cpython-312.pyc new file mode 100644 index 00000000..51ed31c2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/albania.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/algeria.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/algeria.cpython-312.pyc new file mode 100644 index 00000000..4f072e1a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/algeria.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/american_samoa.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/american_samoa.cpython-312.pyc new file mode 100644 index 00000000..b4791e55 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/american_samoa.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/andorra.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/andorra.cpython-312.pyc new file mode 100644 index 00000000..69b0e67d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/andorra.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/angola.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/angola.cpython-312.pyc new file mode 100644 index 00000000..a8a1c133 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/angola.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/anguilla.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/anguilla.cpython-312.pyc new file mode 100644 index 00000000..086d6925 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/anguilla.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/antigua_and_barbuda.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/antigua_and_barbuda.cpython-312.pyc new file mode 100644 index 00000000..9fc1866b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/antigua_and_barbuda.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/argentina.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/argentina.cpython-312.pyc new file mode 100644 index 00000000..9e40c030 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/argentina.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/armenia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/armenia.cpython-312.pyc new file mode 100644 index 00000000..6e0ca9e2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/armenia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/aruba.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/aruba.cpython-312.pyc new file mode 100644 index 00000000..0cbf8934 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/aruba.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/australia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/australia.cpython-312.pyc new file mode 100644 index 00000000..1803beef Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/australia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/austria.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/austria.cpython-312.pyc new file mode 100644 index 00000000..324e4a5b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/austria.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/azerbaijan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/azerbaijan.cpython-312.pyc new file mode 100644 index 00000000..22912277 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/azerbaijan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bahamas.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bahamas.cpython-312.pyc new file mode 100644 index 00000000..ec7fc5eb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bahamas.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bahrain.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bahrain.cpython-312.pyc new file mode 100644 index 00000000..d6444923 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bahrain.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bangladesh.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bangladesh.cpython-312.pyc new file mode 100644 index 00000000..dbd102e3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bangladesh.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/barbados.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/barbados.cpython-312.pyc new file mode 100644 index 00000000..c6ec7871 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/barbados.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belarus.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belarus.cpython-312.pyc new file mode 100644 index 00000000..be395b41 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belarus.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belgium.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belgium.cpython-312.pyc new file mode 100644 index 00000000..d3d303d6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belgium.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belize.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belize.cpython-312.pyc new file mode 100644 index 00000000..8a9c84c8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/belize.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/benin.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/benin.cpython-312.pyc new file mode 100644 index 00000000..d77db8e6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/benin.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bermuda.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bermuda.cpython-312.pyc new file mode 100644 index 00000000..c2043aa7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bermuda.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bolivia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bolivia.cpython-312.pyc new file mode 100644 index 00000000..a6c5132e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bolivia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bonaire_sint_eustatius_and_saba.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bonaire_sint_eustatius_and_saba.cpython-312.pyc new file mode 100644 index 00000000..94d71e14 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bonaire_sint_eustatius_and_saba.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bosnia_and_herzegovina.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bosnia_and_herzegovina.cpython-312.pyc new file mode 100644 index 00000000..8b5fd5d7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bosnia_and_herzegovina.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/botswana.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/botswana.cpython-312.pyc new file mode 100644 index 00000000..b8356441 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/botswana.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/brazil.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/brazil.cpython-312.pyc new file mode 100644 index 00000000..50785657 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/brazil.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/british_virgin_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/british_virgin_islands.cpython-312.pyc new file mode 100644 index 00000000..53acec87 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/british_virgin_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/brunei.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/brunei.cpython-312.pyc new file mode 100644 index 00000000..23903fb3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/brunei.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bulgaria.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bulgaria.cpython-312.pyc new file mode 100644 index 00000000..a672d94a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/bulgaria.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/burkina_faso.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/burkina_faso.cpython-312.pyc new file mode 100644 index 00000000..47de57b8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/burkina_faso.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/burundi.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/burundi.cpython-312.pyc new file mode 100644 index 00000000..c055e229 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/burundi.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cabo_verde.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cabo_verde.cpython-312.pyc new file mode 100644 index 00000000..3955ead0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cabo_verde.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cambodia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cambodia.cpython-312.pyc new file mode 100644 index 00000000..e1fec7ba Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cambodia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cameroon.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cameroon.cpython-312.pyc new file mode 100644 index 00000000..6f4cc8ab Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cameroon.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/canada.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/canada.cpython-312.pyc new file mode 100644 index 00000000..4db0df00 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/canada.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cayman_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cayman_islands.cpython-312.pyc new file mode 100644 index 00000000..781ed852 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cayman_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/central_african_republic.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/central_african_republic.cpython-312.pyc new file mode 100644 index 00000000..75d9c6e3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/central_african_republic.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/chad.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/chad.cpython-312.pyc new file mode 100644 index 00000000..bda0c4ce Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/chad.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/chile.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/chile.cpython-312.pyc new file mode 100644 index 00000000..0fe37179 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/chile.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/china.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/china.cpython-312.pyc new file mode 100644 index 00000000..beaaaca0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/china.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/christmas_island.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/christmas_island.cpython-312.pyc new file mode 100644 index 00000000..afcb4190 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/christmas_island.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cocos_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cocos_islands.cpython-312.pyc new file mode 100644 index 00000000..db3e1a08 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cocos_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/colombia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/colombia.cpython-312.pyc new file mode 100644 index 00000000..20406920 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/colombia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/congo.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/congo.cpython-312.pyc new file mode 100644 index 00000000..d9f9d4c8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/congo.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cook_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cook_islands.cpython-312.pyc new file mode 100644 index 00000000..61e7a30d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cook_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/costa_rica.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/costa_rica.cpython-312.pyc new file mode 100644 index 00000000..97b3a583 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/costa_rica.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/croatia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/croatia.cpython-312.pyc new file mode 100644 index 00000000..16a02e2e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/croatia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cuba.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cuba.cpython-312.pyc new file mode 100644 index 00000000..8ad470aa Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cuba.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/curacao.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/curacao.cpython-312.pyc new file mode 100644 index 00000000..b500db34 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/curacao.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cyprus.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cyprus.cpython-312.pyc new file mode 100644 index 00000000..1e0b7617 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/cyprus.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/czechia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/czechia.cpython-312.pyc new file mode 100644 index 00000000..40ee902f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/czechia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/denmark.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/denmark.cpython-312.pyc new file mode 100644 index 00000000..4f04727f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/denmark.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/djibouti.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/djibouti.cpython-312.pyc new file mode 100644 index 00000000..f0b8b9ec Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/djibouti.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dominica.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dominica.cpython-312.pyc new file mode 100644 index 00000000..a5c4c679 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dominica.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dominican_republic.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dominican_republic.cpython-312.pyc new file mode 100644 index 00000000..18f7ab81 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dominican_republic.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dr_congo.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dr_congo.cpython-312.pyc new file mode 100644 index 00000000..f1e06faf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/dr_congo.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ecuador.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ecuador.cpython-312.pyc new file mode 100644 index 00000000..53041135 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ecuador.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/egypt.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/egypt.cpython-312.pyc new file mode 100644 index 00000000..c14d9075 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/egypt.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/el_salvador.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/el_salvador.cpython-312.pyc new file mode 100644 index 00000000..74b1ad4b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/el_salvador.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/equatorial_guinea.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/equatorial_guinea.cpython-312.pyc new file mode 100644 index 00000000..6b2fb76d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/equatorial_guinea.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/estonia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/estonia.cpython-312.pyc new file mode 100644 index 00000000..834ddf9c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/estonia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/eswatini.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/eswatini.cpython-312.pyc new file mode 100644 index 00000000..49550e1b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/eswatini.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ethiopia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ethiopia.cpython-312.pyc new file mode 100644 index 00000000..ae4bbd8d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ethiopia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/falkland_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/falkland_islands.cpython-312.pyc new file mode 100644 index 00000000..b0a93fdc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/falkland_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/faroe_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/faroe_islands.cpython-312.pyc new file mode 100644 index 00000000..b30ddb69 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/faroe_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/fiji.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/fiji.cpython-312.pyc new file mode 100644 index 00000000..c4d94554 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/fiji.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/finland.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/finland.cpython-312.pyc new file mode 100644 index 00000000..57eda38e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/finland.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/france.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/france.cpython-312.pyc new file mode 100644 index 00000000..9cf76d8e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/france.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_guiana.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_guiana.cpython-312.pyc new file mode 100644 index 00000000..e9fd9e44 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_guiana.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_polynesia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_polynesia.cpython-312.pyc new file mode 100644 index 00000000..acd223ae Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_polynesia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_southern_territories.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_southern_territories.cpython-312.pyc new file mode 100644 index 00000000..457c8201 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/french_southern_territories.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/gabon.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/gabon.cpython-312.pyc new file mode 100644 index 00000000..1d47c7a4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/gabon.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/georgia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/georgia.cpython-312.pyc new file mode 100644 index 00000000..a3456ef3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/georgia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/germany.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/germany.cpython-312.pyc new file mode 100644 index 00000000..643c9a79 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/germany.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ghana.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ghana.cpython-312.pyc new file mode 100644 index 00000000..e56d3056 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ghana.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/gibraltar.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/gibraltar.cpython-312.pyc new file mode 100644 index 00000000..b8bbce16 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/gibraltar.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/greece.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/greece.cpython-312.pyc new file mode 100644 index 00000000..77603dd9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/greece.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/greenland.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/greenland.cpython-312.pyc new file mode 100644 index 00000000..d94baddf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/greenland.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/grenada.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/grenada.cpython-312.pyc new file mode 100644 index 00000000..26029a8e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/grenada.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guadeloupe.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guadeloupe.cpython-312.pyc new file mode 100644 index 00000000..e016448e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guadeloupe.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guam.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guam.cpython-312.pyc new file mode 100644 index 00000000..e630921b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guam.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guatemala.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guatemala.cpython-312.pyc new file mode 100644 index 00000000..d50939d4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guatemala.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guernsey.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guernsey.cpython-312.pyc new file mode 100644 index 00000000..81f62fe9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guernsey.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guinea.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guinea.cpython-312.pyc new file mode 100644 index 00000000..0dd96956 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guinea.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guyana.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guyana.cpython-312.pyc new file mode 100644 index 00000000..f21b04e3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/guyana.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/haiti.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/haiti.cpython-312.pyc new file mode 100644 index 00000000..33d76f89 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/haiti.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/honduras.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/honduras.cpython-312.pyc new file mode 100644 index 00000000..1bf31e9d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/honduras.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/hongkong.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/hongkong.cpython-312.pyc new file mode 100644 index 00000000..f28f2b73 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/hongkong.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/hungary.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/hungary.cpython-312.pyc new file mode 100644 index 00000000..f6c783b8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/hungary.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/iceland.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/iceland.cpython-312.pyc new file mode 100644 index 00000000..192f5ab3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/iceland.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/india.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/india.cpython-312.pyc new file mode 100644 index 00000000..5476e5b6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/india.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/indonesia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/indonesia.cpython-312.pyc new file mode 100644 index 00000000..8fc23a95 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/indonesia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/iran.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/iran.cpython-312.pyc new file mode 100644 index 00000000..2fdaf74c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/iran.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ireland.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ireland.cpython-312.pyc new file mode 100644 index 00000000..5aa49e93 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ireland.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/isle_of_man.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/isle_of_man.cpython-312.pyc new file mode 100644 index 00000000..40c49ca7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/isle_of_man.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/israel.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/israel.cpython-312.pyc new file mode 100644 index 00000000..1441ecf9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/israel.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/italy.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/italy.cpython-312.pyc new file mode 100644 index 00000000..8705a6ec Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/italy.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ivory_coast.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ivory_coast.cpython-312.pyc new file mode 100644 index 00000000..583a019e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ivory_coast.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jamaica.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jamaica.cpython-312.pyc new file mode 100644 index 00000000..5b36015f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jamaica.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/japan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/japan.cpython-312.pyc new file mode 100644 index 00000000..63c0b511 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/japan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jersey.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jersey.cpython-312.pyc new file mode 100644 index 00000000..8ec9dba7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jersey.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jordan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jordan.cpython-312.pyc new file mode 100644 index 00000000..98c2b78e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/jordan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kazakhstan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kazakhstan.cpython-312.pyc new file mode 100644 index 00000000..2fba3e43 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kazakhstan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kenya.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kenya.cpython-312.pyc new file mode 100644 index 00000000..a01026a8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kenya.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kuwait.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kuwait.cpython-312.pyc new file mode 100644 index 00000000..22b46133 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kuwait.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kyrgyzstan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kyrgyzstan.cpython-312.pyc new file mode 100644 index 00000000..c0bedacd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/kyrgyzstan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/laos.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/laos.cpython-312.pyc new file mode 100644 index 00000000..c680190b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/laos.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/latvia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/latvia.cpython-312.pyc new file mode 100644 index 00000000..4d0b1fb2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/latvia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lebanon.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lebanon.cpython-312.pyc new file mode 100644 index 00000000..f9a8cdbe Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lebanon.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lesotho.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lesotho.cpython-312.pyc new file mode 100644 index 00000000..c8a7e512 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lesotho.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/libya.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/libya.cpython-312.pyc new file mode 100644 index 00000000..874a4ed2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/libya.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/liechtenstein.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/liechtenstein.cpython-312.pyc new file mode 100644 index 00000000..f67654a0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/liechtenstein.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lithuania.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lithuania.cpython-312.pyc new file mode 100644 index 00000000..2cab5a4a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/lithuania.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/luxembourg.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/luxembourg.cpython-312.pyc new file mode 100644 index 00000000..01d26d00 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/luxembourg.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/macau.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/macau.cpython-312.pyc new file mode 100644 index 00000000..680229f4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/macau.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/madagascar.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/madagascar.cpython-312.pyc new file mode 100644 index 00000000..780d793e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/madagascar.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malawi.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malawi.cpython-312.pyc new file mode 100644 index 00000000..4cfde1a8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malawi.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malaysia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malaysia.cpython-312.pyc new file mode 100644 index 00000000..c6233547 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malaysia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/maldives.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/maldives.cpython-312.pyc new file mode 100644 index 00000000..a2c6a05a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/maldives.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mali.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mali.cpython-312.pyc new file mode 100644 index 00000000..20def28e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mali.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malta.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malta.cpython-312.pyc new file mode 100644 index 00000000..9581a6b6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/malta.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/marshall_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/marshall_islands.cpython-312.pyc new file mode 100644 index 00000000..9bc2ea34 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/marshall_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/martinique.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/martinique.cpython-312.pyc new file mode 100644 index 00000000..8336b7d9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/martinique.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mauritania.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mauritania.cpython-312.pyc new file mode 100644 index 00000000..d42af42b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mauritania.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mauritius.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mauritius.cpython-312.pyc new file mode 100644 index 00000000..8c40e1be Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mauritius.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mayotte.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mayotte.cpython-312.pyc new file mode 100644 index 00000000..aa9cb61c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mayotte.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mexico.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mexico.cpython-312.pyc new file mode 100644 index 00000000..23b87c26 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mexico.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/micronesia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/micronesia.cpython-312.pyc new file mode 100644 index 00000000..3396502b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/micronesia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/moldova.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/moldova.cpython-312.pyc new file mode 100644 index 00000000..da618eb9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/moldova.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/monaco.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/monaco.cpython-312.pyc new file mode 100644 index 00000000..1d4646f8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/monaco.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mongolia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mongolia.cpython-312.pyc new file mode 100644 index 00000000..18adc35e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mongolia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/montenegro.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/montenegro.cpython-312.pyc new file mode 100644 index 00000000..d29a3cbe Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/montenegro.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/montserrat.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/montserrat.cpython-312.pyc new file mode 100644 index 00000000..44cb698f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/montserrat.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/morocco.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/morocco.cpython-312.pyc new file mode 100644 index 00000000..b95aec03 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/morocco.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mozambique.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mozambique.cpython-312.pyc new file mode 100644 index 00000000..e98c49eb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/mozambique.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/namibia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/namibia.cpython-312.pyc new file mode 100644 index 00000000..b8dc1d62 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/namibia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nauru.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nauru.cpython-312.pyc new file mode 100644 index 00000000..8c87bac3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nauru.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nepal.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nepal.cpython-312.pyc new file mode 100644 index 00000000..86a92ce7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nepal.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/netherlands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/netherlands.cpython-312.pyc new file mode 100644 index 00000000..c7791598 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/netherlands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/new_caledonia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/new_caledonia.cpython-312.pyc new file mode 100644 index 00000000..85c31bad Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/new_caledonia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/new_zealand.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/new_zealand.cpython-312.pyc new file mode 100644 index 00000000..d3936a06 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/new_zealand.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nicaragua.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nicaragua.cpython-312.pyc new file mode 100644 index 00000000..bf9eb0f0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nicaragua.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/niger.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/niger.cpython-312.pyc new file mode 100644 index 00000000..ca262bb5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/niger.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nigeria.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nigeria.cpython-312.pyc new file mode 100644 index 00000000..77f1bfda Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/nigeria.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/niue.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/niue.cpython-312.pyc new file mode 100644 index 00000000..fc6c4b4d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/niue.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/norfolk_island.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/norfolk_island.cpython-312.pyc new file mode 100644 index 00000000..45473444 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/norfolk_island.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/north_macedonia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/north_macedonia.cpython-312.pyc new file mode 100644 index 00000000..4cb47de0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/north_macedonia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/northern_mariana_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/northern_mariana_islands.cpython-312.pyc new file mode 100644 index 00000000..a6c51717 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/northern_mariana_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/norway.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/norway.cpython-312.pyc new file mode 100644 index 00000000..d94bbcd5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/norway.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/oman.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/oman.cpython-312.pyc new file mode 100644 index 00000000..fd29a8a4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/oman.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/pakistan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/pakistan.cpython-312.pyc new file mode 100644 index 00000000..65be5998 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/pakistan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/palau.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/palau.cpython-312.pyc new file mode 100644 index 00000000..da2d0fa3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/palau.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/palestine.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/palestine.cpython-312.pyc new file mode 100644 index 00000000..6a02e784 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/palestine.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/panama.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/panama.cpython-312.pyc new file mode 100644 index 00000000..f46a21ff Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/panama.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/papua_new_guinea.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/papua_new_guinea.cpython-312.pyc new file mode 100644 index 00000000..f957d8a1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/papua_new_guinea.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/paraguay.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/paraguay.cpython-312.pyc new file mode 100644 index 00000000..cdb66fa7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/paraguay.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/peru.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/peru.cpython-312.pyc new file mode 100644 index 00000000..c2608a4e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/peru.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/philippines.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/philippines.cpython-312.pyc new file mode 100644 index 00000000..e6ec2303 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/philippines.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/poland.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/poland.cpython-312.pyc new file mode 100644 index 00000000..15085e3f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/poland.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/portugal.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/portugal.cpython-312.pyc new file mode 100644 index 00000000..c6707ffd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/portugal.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/puerto_rico.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/puerto_rico.cpython-312.pyc new file mode 100644 index 00000000..ba1e1508 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/puerto_rico.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/qatar.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/qatar.cpython-312.pyc new file mode 100644 index 00000000..ab3ae289 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/qatar.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/reunion.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/reunion.cpython-312.pyc new file mode 100644 index 00000000..14d56a03 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/reunion.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/romania.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/romania.cpython-312.pyc new file mode 100644 index 00000000..a45624f2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/romania.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/russia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/russia.cpython-312.pyc new file mode 100644 index 00000000..10701501 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/russia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_barthelemy.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_barthelemy.cpython-312.pyc new file mode 100644 index 00000000..41ad3941 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_barthelemy.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_kitts_and_nevis.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_kitts_and_nevis.cpython-312.pyc new file mode 100644 index 00000000..22b824d5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_kitts_and_nevis.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_lucia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_lucia.cpython-312.pyc new file mode 100644 index 00000000..613e1b04 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_lucia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_martin.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_martin.cpython-312.pyc new file mode 100644 index 00000000..bb4a01b0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_martin.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_pierre_and_miquelon.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_pierre_and_miquelon.cpython-312.pyc new file mode 100644 index 00000000..0cc51e3b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_pierre_and_miquelon.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_vincent_and_the_grenadines.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_vincent_and_the_grenadines.cpython-312.pyc new file mode 100644 index 00000000..4aec7236 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saint_vincent_and_the_grenadines.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/samoa.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/samoa.cpython-312.pyc new file mode 100644 index 00000000..5cce5a33 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/samoa.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/san_marino.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/san_marino.cpython-312.pyc new file mode 100644 index 00000000..c7810772 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/san_marino.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sao_tome_and_principe.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sao_tome_and_principe.cpython-312.pyc new file mode 100644 index 00000000..5c502b1d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sao_tome_and_principe.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saudi_arabia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saudi_arabia.cpython-312.pyc new file mode 100644 index 00000000..366370ca Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/saudi_arabia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/senegal.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/senegal.cpython-312.pyc new file mode 100644 index 00000000..603b4bba Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/senegal.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/serbia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/serbia.cpython-312.pyc new file mode 100644 index 00000000..b633591a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/serbia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/seychelles.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/seychelles.cpython-312.pyc new file mode 100644 index 00000000..b93decf9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/seychelles.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sierra_leone.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sierra_leone.cpython-312.pyc new file mode 100644 index 00000000..938220a3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sierra_leone.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/singapore.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/singapore.cpython-312.pyc new file mode 100644 index 00000000..ec8244a6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/singapore.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sint_maarten.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sint_maarten.cpython-312.pyc new file mode 100644 index 00000000..cfaaee49 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sint_maarten.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/slovakia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/slovakia.cpython-312.pyc new file mode 100644 index 00000000..d5fea026 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/slovakia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/slovenia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/slovenia.cpython-312.pyc new file mode 100644 index 00000000..b923e2f5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/slovenia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/solomon_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/solomon_islands.cpython-312.pyc new file mode 100644 index 00000000..a621c470 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/solomon_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/south_africa.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/south_africa.cpython-312.pyc new file mode 100644 index 00000000..04ed9e04 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/south_africa.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/south_korea.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/south_korea.cpython-312.pyc new file mode 100644 index 00000000..f5c4e797 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/south_korea.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/spain.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/spain.cpython-312.pyc new file mode 100644 index 00000000..74d12242 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/spain.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sri_lanka.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sri_lanka.cpython-312.pyc new file mode 100644 index 00000000..97a5db4a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sri_lanka.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/suriname.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/suriname.cpython-312.pyc new file mode 100644 index 00000000..3837582a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/suriname.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/svalbard_and_jan_mayen.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/svalbard_and_jan_mayen.cpython-312.pyc new file mode 100644 index 00000000..6af911ef Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/svalbard_and_jan_mayen.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sweden.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sweden.cpython-312.pyc new file mode 100644 index 00000000..3b742efc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/sweden.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/switzerland.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/switzerland.cpython-312.pyc new file mode 100644 index 00000000..0fe7ef47 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/switzerland.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/taiwan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/taiwan.cpython-312.pyc new file mode 100644 index 00000000..6243f27c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/taiwan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tanzania.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tanzania.cpython-312.pyc new file mode 100644 index 00000000..138ea8ff Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tanzania.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/thailand.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/thailand.cpython-312.pyc new file mode 100644 index 00000000..fcad090c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/thailand.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/timor_leste.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/timor_leste.cpython-312.pyc new file mode 100644 index 00000000..d9eb37bf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/timor_leste.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/togo.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/togo.cpython-312.pyc new file mode 100644 index 00000000..7f0dd880 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/togo.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tokelau.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tokelau.cpython-312.pyc new file mode 100644 index 00000000..18ae5155 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tokelau.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tonga.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tonga.cpython-312.pyc new file mode 100644 index 00000000..74a89243 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tonga.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/trinidad_and_tobago.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/trinidad_and_tobago.cpython-312.pyc new file mode 100644 index 00000000..23d96bd4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/trinidad_and_tobago.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tunisia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tunisia.cpython-312.pyc new file mode 100644 index 00000000..99dd00c0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tunisia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/turkey.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/turkey.cpython-312.pyc new file mode 100644 index 00000000..5f971f0c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/turkey.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/turks_and_caicos_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/turks_and_caicos_islands.cpython-312.pyc new file mode 100644 index 00000000..55d26ca5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/turks_and_caicos_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tuvalu.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tuvalu.cpython-312.pyc new file mode 100644 index 00000000..8f112047 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/tuvalu.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ukraine.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ukraine.cpython-312.pyc new file mode 100644 index 00000000..4060e150 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/ukraine.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_arab_emirates.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_arab_emirates.cpython-312.pyc new file mode 100644 index 00000000..4b602659 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_arab_emirates.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_kingdom.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_kingdom.cpython-312.pyc new file mode 100644 index 00000000..51775708 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_kingdom.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states.cpython-312.pyc new file mode 100644 index 00000000..9c9724f5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states_minor_outlying_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states_minor_outlying_islands.cpython-312.pyc new file mode 100644 index 00000000..a4340f31 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states_minor_outlying_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states_virgin_islands.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states_virgin_islands.cpython-312.pyc new file mode 100644 index 00000000..8fe469fc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/united_states_virgin_islands.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/uruguay.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/uruguay.cpython-312.pyc new file mode 100644 index 00000000..cab71810 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/uruguay.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/uzbekistan.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/uzbekistan.cpython-312.pyc new file mode 100644 index 00000000..0656fab8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/uzbekistan.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vanuatu.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vanuatu.cpython-312.pyc new file mode 100644 index 00000000..53b6cca3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vanuatu.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vatican_city.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vatican_city.cpython-312.pyc new file mode 100644 index 00000000..f55a3911 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vatican_city.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/venezuela.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/venezuela.cpython-312.pyc new file mode 100644 index 00000000..2065174a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/venezuela.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vietnam.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vietnam.cpython-312.pyc new file mode 100644 index 00000000..8455b181 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/vietnam.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/wallis_and_futuna.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/wallis_and_futuna.cpython-312.pyc new file mode 100644 index 00000000..fbbf212d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/wallis_and_futuna.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/yemen.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/yemen.cpython-312.pyc new file mode 100644 index 00000000..162bab19 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/yemen.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/zambia.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/zambia.cpython-312.pyc new file mode 100644 index 00000000..4c29cc19 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/zambia.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/zimbabwe.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/zimbabwe.cpython-312.pyc new file mode 100644 index 00000000..bfefd184 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/countries/__pycache__/zimbabwe.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/afghanistan.py b/.venv/lib/python3.12/site-packages/holidays/countries/afghanistan.py new file mode 100644 index 00000000..6af54636 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/afghanistan.py @@ -0,0 +1,202 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + FRI, + SAT, +) +from holidays.groups import InternationalHolidays, IslamicHolidays, PersianCalendarHolidays +from holidays.holiday_base import HolidayBase + + +class Afghanistan(HolidayBase, InternationalHolidays, IslamicHolidays, PersianCalendarHolidays): + """Afghanistan holidays. + + References: + * + * + * + """ + + country = "AF" + default_language = "fa_AF" + # %s (estimated). + estimated_label = tr("%s (برآورد شده)") + supported_languages = ("en_US", "fa_AF", "ps_AF") + # Afghanistan's regaining of full independence from British influence. + start_year = 1919 + weekend = {FRI, SAT} + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=AfghanistanIslamicHolidays, show_estimated=islamic_show_estimated + ) + PersianCalendarHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year >= 1989: + # Liberation Day. + self._add_holiday_feb_15(tr("روز آزادی")) + + # Afghanistan Independence Day. + self._add_holiday_aug_19(tr("روز استقلال افغانستان")) + + if self._year <= 1996 or 2001 <= self._year <= 2020: + # Nowruz. + self._add_nowruz_day(tr("نوروز")) + + if self._year >= 1992: + # Mojahedin's Victory Day. + self._add_holiday_apr_28(tr("روز پیروزی مجاهدین")) + + if 1974 <= self._year <= 1996 or 2002 <= self._year <= 2021: + # International Workers' Day. + self._add_labor_day(tr("روز جهانی کارگر")) + + if 1978 <= self._year <= 1988: + # Soviet Victory Day. + self._add_holiday_may_9(tr("روز پیروزی شوروی")) + + if self._year >= 2022: + # Islamic Emirate Victory Day. + self._add_islamic_emirat_victory_day(tr("روز پیروزی امارت اسلامی")) + + # American Withdrawal Day. + self._add_holiday_aug_31(tr("روز خروج آمریکایی ها")) + + if 2012 <= self._year <= 2020: + # Martyrs' Day. + self._add_holiday_sep_9(tr("روز شهیدان")) + + if self._year <= 2021: + # Ashura. + self._add_ashura_day(tr("عاشورا")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("میلاد پیامبر")) + + # First Day of Ramadan. + self._add_ramadan_beginning_day(tr("اول رمضان")) + + # Eid al-Fitr. + name = tr("عید فطر") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + self._add_eid_al_fitr_day_three(name) + + # Day of Arafah. + self._add_arafah_day(tr("روز عرفه")) + + # Eid al-Adha. + name = tr("عید قربانی") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_eid_al_adha_day_three(name) + + +class AF(Afghanistan): + pass + + +class AFG(Afghanistan): + pass + + +class AfghanistanIslamicHolidays(_CustomIslamicHolidays): + ASHURA_DATES = { + 2014: (NOV, 3), + 2015: (OCT, 24), + 2016: (OCT, 12), + 2017: (OCT, 1), + 2018: (SEP, 21), + 2019: (SEP, 10), + 2020: (AUG, 30), + 2021: (AUG, 19), + } + + EID_AL_ADHA_DATES = { + 2014: (OCT, 5), + 2015: (SEP, 23), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 17), + } + + EID_AL_FITR_DATES = { + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 1), + 2023: (APR, 22), + 2024: (APR, 10), + } + + MAWLID_DATES = { + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 16), + } + + RAMADAN_BEGINNING_DATES = { + 2014: (JUN, 29), + 2015: (JUN, 18), + 2016: (JUN, 7), + 2017: (MAY, 27), + 2018: (MAY, 16), + 2019: (MAY, 6), + 2020: (APR, 24), + 2021: (APR, 13), + 2022: (APR, 2), + 2023: (MAR, 23), + 2024: (MAR, 11), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/aland_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/aland_islands.py new file mode 100644 index 00000000..63e30a9f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/aland_islands.py @@ -0,0 +1,47 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.finland import Finland +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysAX(ChildEntity, Finland): + """Åland Islands holidays. + + Alias of a Finnish subdivision that is also officially assigned + its own country code in ISO 3166-1. + + !!! note "Note" + Åland's Autonomy Day is currently added in Finland's implementation. + + References: + * + * + """ + + country = "AX" + parent_entity = Finland + parent_entity_subdivision_code = "01" + # Åland Islands got its autonomy on May 7th, 1920. + start_year = 1921 + + +class AlandIslands(HolidaysAX): + pass + + +class AX(HolidaysAX): + pass + + +class ALA(HolidaysAX): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/albania.py b/.venv/lib/python3.12/site-packages/holidays/countries/albania.py new file mode 100644 index 00000000..9b9c8b2f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/albania.py @@ -0,0 +1,171 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, MAR, APR, MAY, JUN, JUL, AUG +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class Albania( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Albania holidays. + + References: + * + * [Law No. 7651](https://web.archive.org/web/20250119183539/http://kqk.gov.al/sites/default/files/publikime/ligj_7651_-_per_festat_zyrtare_e_ditet_perkujtimore.pdf) + * [Holidays for 2018-2024](https://web.archive.org/web/20250119183537/https://www.bankofalbania.org/Shtypi/Kalendari_i_festave_zyrtare_2024/) + """ + + country = "AL" + default_language = "sq" + # %s (estimated). + estimated_label = tr("%s (e vlerësuar)") + # %s (observed). + observed_label = tr("%s (ditë pushimi e shtyrë)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (ditë pushimi e shtyrë, e vlerësuar)") + supported_languages = ("en_US", "sq", "uk") + # Law No. 7651 from 21.12.1992. + start_year = 1993 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=AlbaniaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, AlbaniaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + name = tr("Festat e Vitit të Ri") + dts_observed.add(self._add_new_years_day(name)) + dts_observed.add(self._add_new_years_day_two(name)) + + if self._year >= 2004: + # Summer Day. + dts_observed.add(self._add_holiday_mar_14(tr("Dita e Verës"))) + + if self._year >= 1996: + # Nowruz Day. + dts_observed.add(self._add_holiday_mar_22(tr("Dita e Nevruzit"))) + + # Catholic Easter Sunday. + dts_observed.add(self._add_easter_sunday(tr("E diela e Pashkëve Katolike"))) + + dts_observed.add( + # Orthodox Easter Sunday. + self._add_easter_sunday(tr("E diela e Pashkëve Ortodokse"), JULIAN_CALENDAR) + ) + + # International Workers' Day. + dts_observed.add(self._add_labor_day(tr("Dita Ndërkombëtare e Punëtorëve"))) + + if 2004 <= self._year <= 2017: + # Mother Teresa Beatification Day. + dts_observed.add(self._add_holiday_oct_19(tr("Dita e Lumturimit të Shenjt Terezës"))) + elif self._year >= 2018: + # Mother Teresa Canonization Day. + dts_observed.add(self._add_holiday_sep_5(tr("Dita e Shenjtërimit të Shenjt Terezës"))) + + if self._year >= 2024: + # Alphabet Day. + dts_observed.add(self._add_holiday_nov_22(tr("Dita e Alfabetit"))) + + # Flag and Independence Day. + dts_observed.add(self._add_holiday_nov_28(tr("Dita Flamurit dhe e Pavarësisë"))) + + # Liberation Day. + dts_observed.add(self._add_holiday_nov_29(tr("Dita e Çlirimit"))) + + if self._year >= 2009: + # National Youth Day. + dts_observed.add(self._add_holiday_dec_8(tr("Dita Kombëtare e Rinisë"))) + + # Christmas Day. + dts_observed.add(self._add_christmas_day(tr("Krishtlindjet"))) + + # Eid al-Fitr. + dts_observed.update(self._add_eid_al_fitr_day(tr("Dita e Bajramit të Madh"))) + + # Eid al-Adha. + dts_observed.update(self._add_eid_al_adha_day(tr("Dita e Kurban Bajramit"))) + + if self.observed: + self._populate_observed(dts_observed) + + +class AL(Albania): + pass + + +class ALB(Albania): + pass + + +class AlbaniaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + +class AlbaniaStaticHolidays: + # Public Holiday. + public_holiday = tr("Ditë pushimi") + + special_public_holidays = { + 2020: (JAN, 3, public_holiday), + 2022: (MAR, 21, public_holiday), + 2024: (MAR, 15, public_holiday), + } + + special_public_holidays_observed = { + 2007: (JAN, 3, tr("Dita e Kurban Bajramit")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/algeria.py b/.venv/lib/python3.12/site-packages/holidays/countries/algeria.py new file mode 100644 index 00000000..e28069ce --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/algeria.py @@ -0,0 +1,104 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import THU, FRI, SAT, SUN +from holidays.groups import InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Algeria(HolidayBase, InternationalHolidays, IslamicHolidays): + """Algeria holidays. + + References: + * + * + * + """ + + country = "DZ" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + supported_languages = ("ar", "en_US", "fr") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # The resting days are Friday and Saturday since 2009. + # Previously, these were on Thursday and Friday as implemented in 1976. + if self._year >= 2009: + self.weekend = {FRI, SAT} + elif self._year >= 1976: + self.weekend = {THU, FRI} + else: + self.weekend = {SAT, SUN} + + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + # In January 2018, Algeria declared Yennayer a national holiday. + if self._year >= 2018: + # Amazigh New Year. + self._add_holiday_jan_12(tr("رأس السنة الأمازيغية")) + + # Labor Day. + self._add_labor_day(tr("عيد العمال")) + + if self._year >= 1962: + # Independence Day. + self._add_holiday_jul_5(tr("عيد الإستقلال")) + + if self._year >= 1963: + # Revolution Day. + self._add_holiday_nov_1(tr("عيد الثورة")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Ashura. + self._add_ashura_day(tr("عاشورة")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("عيد المولد النبوي")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("عيد الفطر")) + # Eid al-Fitr Holiday. + self._add_eid_al_fitr_day_two(tr("عطلة عيد الفطر")) + if self._year >= 2024: + self._add_eid_al_fitr_day_three(tr("عطلة عيد الفطر")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("عيد الأضحى")) + # Eid al-Adha Holiday. + self._add_eid_al_adha_day_two(tr("عطلة عيد الأضحى")) + if self._year >= 2023: + self._add_eid_al_adha_day_three(tr("عطلة عيد الأضحى")) + + +class DZ(Algeria): + pass + + +class DZA(Algeria): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/american_samoa.py b/.venv/lib/python3.12/site-packages/holidays/countries/american_samoa.py new file mode 100644 index 00000000..a406ce73 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/american_samoa.py @@ -0,0 +1,39 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.united_states import UnitedStates +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysAS(ChildEntity, UnitedStates): + """American Samoa holidays. + + Alias of a US subdivision that is also officially assigned its own country code in ISO 3166-1. + See + """ + + country = "AS" + parent_entity = UnitedStates + # Became a U.S. Territory since April 17th, 1900. + start_year = 1901 + + +class AmericanSamoa(HolidaysAS): + pass + + +class AS(HolidaysAS): + pass + + +class ASM(HolidaysAS): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/andorra.py b/.venv/lib/python3.12/site-packages/holidays/countries/andorra.py new file mode 100644 index 00000000..3648f9ce --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/andorra.py @@ -0,0 +1,229 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import GOVERNMENT, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Andorra(HolidayBase, ChristianHolidays, InternationalHolidays): + """Andorra holidays. + + References: + * + * [Andorra's Constitution](https://web.archive.org/web/20250506145838/https://www.bopa.ad/Legislacio/Detall?doc=7586) + * [Government holidays source](https://web.archive.org/web/20241005040546/https://seu.consellgeneral.ad/calendariPublic/show) + * [2025](https://web.archive.org/web/20250506142149/https://www.bopa.ad/Documents/Detall?doc=GD_2024_10_24_14_36_16) + + Subdivisions holidays: + * Canillo: + * [2020](https://web.archive.org/web/20250506143618/https://www.bopa.ad/Documents/Detall?doc=QCH20191209_09_01_14) + * [2021](https://web.archive.org/web/20250506143707/https://www.bopa.ad/Documents/Detall?doc=QCH20201130_11_52_35) + * [2022](https://web.archive.org/web/20250506143404/https://www.bopa.ad/Documents/Detall?doc=QCD20211126_12_16_57) + * [2023](https://web.archive.org/web/20250506143725/https://www.bopa.ad/Documents/Detall?doc=QCH20221010_11_26_39) + * [2024](https://web.archive.org/web/20250506143740/https://www.bopa.ad/Documents/Detall?doc=QCH_2023_12_06_16_16_52) + * [2025](https://web.archive.org/web/20250506144017/https://www.bopa.ad/Documents/Detall?doc=QCH_2024_10_10_11_42_15) + * Encamp: + * [2024](https://web.archive.org/web/20241201165207/https://www.bopa.ad/Documents/Detall?doc=QEH_2023_12_15_13_03_32) + * [2025](https://web.archive.org/web/20241212121414/https://www.bopa.ad/Documents/Detall?doc=QEH_2024_11_27_10_29_49) + * La Massana: + * [2020](https://web.archive.org/web/20250506144157/https://www.bopa.ad/Documents/Detall?doc=QMH20191209_09_08_10) + * [2021](https://web.archive.org/web/20250506144241/https://www.bopa.ad/Documents/Detall?doc=QMH20201218_11_52_59) + * [2022](https://web.archive.org/web/20250506144526/https://www.bopa.ad/Documents/Detall?doc=QMH20211116_12_23_19) + * [2023](https://web.archive.org/web/20250506144455/https://www.bopa.ad/Documents/Detall?doc=QMH20221216_12_41_13) + * [2024](https://web.archive.org/web/20250506144500/https://www.bopa.ad/Documents/Detall?doc=QMH_2023_12_11_10_54_27) + * [2025](https://web.archive.org/web/20250506144645/https://www.bopa.ad/Documents/Detall?doc=QMH_2024_11_19_09_10_48) + * Ordino: + * [2020](https://web.archive.org/web/20250506144555/https://www.bopa.ad/Documents/Detall?doc=QOH20191127_11_43_45) + * [2021](https://web.archive.org/web/20250506144713/https://www.bopa.ad/Documents/Detall?doc=QOH20201229_12_24_42) + * [2022](https://web.archive.org/web/20250506144715/https://www.bopa.ad/Documents/Detall?doc=QOH20211125_15_57_33) + * [2023](https://web.archive.org/web/20250506144738/https://www.bopa.ad/Documents/Detall?doc=QOH20221228_10_02_52) + * [2024](https://web.archive.org/web/20250506144729/https://www.bopa.ad/Documents/Detall?doc=QOH_2023_12_28_09_52_56) + * [2025](https://web.archive.org/web/20250506144815/https://www.bopa.ad/Documents/Detall?doc=QOH_2024_11_28_13_42_34) + * Sant Julià de Lòria: + * [2020](https://web.archive.org/web/20250506144715/https://www.bopa.ad/Documents/Detall?doc=QSH20191122_11_45_30) + * [2021](https://web.archive.org/web/20250506144827/https://www.bopa.ad/Documents/Detall?doc=QSH20201223_14_47_40) + * [2022](https://web.archive.org/web/20250506144843/https://www.bopa.ad/Documents/Detall?doc=QSH20211217_08_48_18) + * [2023](https://web.archive.org/web/20250506144859/https://www.bopa.ad/Documents/Detall?doc=QSH20221216_10_26_20) + * [2024](https://web.archive.org/web/20250506145411/https://www.bopa.ad/Documents/Detall?doc=QSH_2023_12_07_11_20_16) + * [2025](https://web.archive.org/web/20250506145311/https://www.bopa.ad/Documents/Detall?doc=QSH_2024_12_17_17_06_23) + * Andorra la Vella: + * [2020](https://web.archive.org/web/20250506142322/https://www.bopa.ad/Documents/Detall?doc=QAH20191128_08_58_08) + * [2021](https://web.archive.org/web/20250506142457/https://www.bopa.ad/Documents/Detall?doc=QAH20201210_11_13_19) + * [2022](https://web.archive.org/web/20250506142545/https://www.bopa.ad/Documents/Detall?doc=QAH20211111_16_06_47) + * [2023](https://web.archive.org/web/20250506142748/https://www.bopa.ad/Documents/Detall?doc=QAH20221117_10_31_45) + * [2024](https://web.archive.org/web/20250506142903/https://www.bopa.ad/Documents/Detall?doc=QAH_2023_11_17_12_40_42) + * [2025](https://web.archive.org/web/20250506143036/https://www.bopa.ad/Documents/Detall?doc=QAH_2024_11_21_09_44_47) + * Escaldes-Engordany: + * [Parish foundation](https://web.archive.org/web/20130409081302/http://www.andorra.ad/ca-ES/Andorra/Pagines/comu_escaldes.aspx) + * [2020](https://web.archive.org/web/20250506145337/https://www.bopa.ad/Documents/Detall?doc=QXH20200113_11_32_08) + * [2021](https://web.archive.org/web/20250506145439/https://www.bopa.ad/Documents/Detall?doc=QXH20210127_13_33_13) + * [2022](https://web.archive.org/web/20250506145442/https://www.bopa.ad/Documents/Detall?doc=QXH20220103_09_55_00) + * [2023](https://web.archive.org/web/20250506145436/https://www.bopa.ad/Documents/Detall?doc=QXH20230102_11_21_25) + * [2024](https://web.archive.org/web/20250506145940/https://www.bopa.ad/Documents/Detall?doc=QXH_2024_01_05_14_43_32) + * [2025](https://web.archive.org/web/20250506145955/https://www.bopa.ad/Documents/Detall?doc=QXH_2024_12_23_11_47_04) + """ + + country = "AD" + default_language = "ca" + # The 1933 Revolution in Andorra + start_year = 1934 + subdivisions = ( + "02", # Canillo. + "03", # Encamp. + "04", # La Massana. + "05", # Ordino. + "06", # Sant Julià de Lòria. + "07", # Andorra la Vella. + "08", # Escaldes-Engordany. + ) + subdivisions_aliases = { + "Canillo": "02", + "Encamp": "03", + "La Massana": "04", + "Ordino": "05", + "Sant Julià de Lòria": "06", + "Andorra la Vella": "07", + "Escaldes-Engordany": "08", + } + supported_categories = (GOVERNMENT, PUBLIC) + supported_languages = ("ca", "en_US", "uk") + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self) -> None: + # New Year's Day. + self._add_new_years_day(tr("Cap d'Any")) + + # Epiphany. + self._add_epiphany_day(tr("Reis")) + + # Carnival. + self._add_carnival_monday(tr("Carnaval")) + + if self._year >= 1994: + # Constitution Day. + self._add_holiday_mar_14(tr("Dia de la Constitució")) + + # Good Friday. + self._add_good_friday(tr("Divendres Sant")) + + # Easter Monday. + self._add_easter_monday(tr("Dilluns de Pasqua")) + + # Labor Day. + self._add_labor_day(tr("Festa del treball")) + + # Whit Monday. + self._add_whit_monday(tr("Dilluns de Pentecosta")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assumpció")) + + # Our Lady of Meritxell. + self._add_holiday_sep_8(tr("Nostra Senyora de Meritxell")) + + # All Saints' Day. + self._add_all_saints_day(tr("Tots Sants")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Immaculada Concepció")) + + # Christmas Day. + self._add_christmas_day(tr("Nadal")) + + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Sant Esteve")) + + def _populate_subdiv_02_public_holidays(self): + # Saint Roch's Day. + self._add_holiday_aug_16(tr("Sant Roc")) + + def _populate_subdiv_03_public_holidays(self): + # There are no holidays common to the whole parish. + pass + + def _populate_subdiv_04_public_holidays(self): + # Saint Anthony's Day. + self._add_holiday_jan_17(tr("Sant Antoni")) + + def _populate_subdiv_05_public_holidays(self): + # Saint Peter's Day. + self._add_saints_peter_and_paul_day(tr("Sant Pere")) + + def _populate_subdiv_06_public_holidays(self): + # Saint Julian's Day. + self._add_holiday_jan_7(tr("Sant Julià")) + + # Virgin Mary of Canòlich. + self._add_holiday_last_sat_of_may(tr("Diada de Canòlich")) + + # Sant Julià de Lòria Festival. + name = tr("Festa Major de Sant Julià de Lòria") + self._add_holiday_2_days_past_last_sat_of_jul(name) + self._add_holiday_3_days_past_last_sat_of_jul(name) + + def _populate_subdiv_07_public_holidays(self): + # Andorra la Vella Festival. + name = tr("Festa Major d'Andorra la Vella") + self._add_holiday_1st_sat_of_aug(name) + self._add_holiday_1_day_past_1st_sat_of_aug(name) + self._add_holiday_2_days_past_1st_sat_of_aug(name) + + def _populate_subdiv_08_public_holidays(self): + # The parish of Escaldes-Engordany created on June 14, 1978. + if self._year <= 1978: + return None + + # Saint Michael of Engolasters' Day. + self._add_holiday_may_7(tr("Sant Miquel d'Engolasters")) + + # Parish foundation day. + name = tr("Diada de la creació de la parròquia") + if self._year >= 1997: + self._add_holiday_1st_sun_from_jun_14(name) + else: + self._add_holiday_jun_14(name) + + # Escaldes-Engordany Festival. + name = tr("Festa Major d'Escaldes-Engordany") + self._add_holiday_jul_25(name) + self._add_holiday_jul_26(name) + + def _populate_government_holidays(self): + # %s (from 1pm). + begin_time_label = self.tr("%s (a partir de les 13h)") + + # Epiphany Eve. + self._add_holiday_jan_5(begin_time_label % self.tr("Vigília de Reis")) + + # Maundy Thursday. + self._add_holy_thursday(begin_time_label % self.tr("Dijous Sant")) + + # Christmas Eve. + self._add_christmas_eve(begin_time_label % self.tr("Vigília de Nadal")) + + # New Year's Eve. + self._add_new_years_eve(begin_time_label % self.tr("Vigília de Cap d'Any")) + + +class AD(Andorra): + pass + + +class AND(Andorra): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/angola.py b/.venv/lib/python3.12/site-packages/holidays/countries/angola.py new file mode 100644 index 00000000..92ffd9b3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/angola.py @@ -0,0 +1,187 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr +from typing import Optional + +from holidays.calendars.gregorian import AUG, SEP +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + TUE_TO_PREV_MON, + THU_TO_NEXT_FRI, + SUN_TO_NEXT_MON, +) + + +class Angola(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Angola holidays. + + References: + * + * + * [Decree #5/75](https://web.archive.org/web/20230719141732/https://www.lexlink.eu/FileGet.aspx?FileId=3023486) + * [Decree #92/80](https://web.archive.org/web/20250427180154/https://www.lexlink.eu/FileGet.aspx?FileId=3023473) + * [Decree #7/92](https://web.archive.org/web/20230719141946/https://www.lexlink.eu/FileGet.aspx?FileId=3023485) + * [Law #16/96](https://web.archive.org/web/20230719141332/https://www.lexlink.eu/FileGet.aspx?FileId=3037036) + * [Law #1/01](https://web.archive.org/web/20230719142311/https://www.lexlink.eu/FileGet.aspx?FileId=3029035) + * [Law #7/03](https://web.archive.org/web/20230719142347/https://www.lexlink.eu/FileGet.aspx?FileId=3002131) + * [Law #10/11](https://web.archive.org/web/20250427180133/https://equadros.gov.ao/documents/40468/0/lei_10_11-1+(1).pdf) + * [Law #11/18](https://web.archive.org/web/20250427175641/https://equadros.gov.ao/documents/40468/0/Lei_no_11-18+(1).pdf) + * + * + """ + + country = "AO" + default_language = "pt_AO" + supported_languages = ("en_US", "pt_AO", "uk") + # %s (observed). + observed_label = tr("%s (ponte)") + # Decree #5/75. + start_year = 1975 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=AngolaStaticHolidays) + kwargs.setdefault("observed_rule", TUE_TO_PREV_MON + THU_TO_NEXT_FRI) + super().__init__(*args, **kwargs) + + def _is_observed(self, dt: date) -> bool: + # As per Law # 16/96, from 1996/9/27, when public holiday falls on Sunday, + # it rolls over to the following Monday. + return dt >= date(1996, SEP, 27) + + def _add_observed(self, dt: date, **kwargs) -> tuple[bool, Optional[date]]: + # As per Law # #11/18, from 2018/9/10, when public holiday falls on Tuesday or Thursday, + # the Monday or Friday is also a holiday. + kwargs.setdefault( + "rule", SUN_TO_NEXT_MON if dt < date(2018, SEP, 10) else self._observed_rule + ) + return super()._add_observed(dt, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Dia do Ano Novo") + dt = self._add_new_years_day(name) + if self._year <= 2011 or self._year >= 2018: + self._add_observed(dt) + self._add_observed(self._next_year_new_years_day, name=name) + + # Law #16/96. + if 1997 <= self._year <= 2011: + self._add_observed( + # Martyrs of Colonial Repression Day. + self._add_holiday_jan_4(tr("Dia dos Mártires da Repressão Colonial")) + ) + + self._add_observed( + self._add_holiday_feb_4( + # Beginning of the Armed Struggle for National Liberation Day. + tr("Dia do Início da Luta Armada de Libertação Nacional") + if self._year >= 2012 + # Beginning of the Armed Struggle Day. + else tr("Dia do Início da Luta Armada") + ) + ) + + # Law #16/96. + if self._year >= 1997: + # Carnival Day. + self._add_observed(self._add_carnival_tuesday(tr("Dia do Carnaval"))) + + # International Women's Day. + self._add_observed(self._add_womens_day(tr("Dia Internacional da Mulher"))) + + # Law #11/18. + if self._year >= 2019: + # Southern Africa Liberation Day. + self._add_observed(self._add_holiday_mar_23(tr("Dia da Libertação da África Austral"))) + + # Law #7/03. + if self._year >= 2003: + # Peace and National Reconciliation Day. + self._add_observed(self._add_holiday_apr_4(tr("Dia da Paz e Reconciliação Nacional"))) + + # Law #16/96. + if self._year >= 1997: + # Good Friday. + self._add_good_friday(tr("Sexta-Feira Santa")) + + # International Worker's Day. + self._add_observed(self._add_labor_day(tr("Dia Internacional do Trabalhador"))) + + # Law #1/01. + if 2001 <= self._year <= 2010: + # Africa Day. + self._add_observed(self._add_africa_day(tr("Dia da África"))) + + # Law #16/96. + if 1997 <= self._year <= 2010: + # International Children's Day. + self._add_observed(self._add_childrens_day(tr("Dia Internacional da Criança"))) + + # Decree #92/80. + if self._year >= 1980: + self._add_observed( + # National Heroes' Day. + self._add_holiday_sep_17(tr("Dia do Fundador da Nação e do Herói Nacional")) + ) + + # All Souls' Day. + dt = self._add_all_souls_day(tr("Dia dos Finados")) + if self._year <= 2010 or self._year >= 2018: + self._add_observed(dt) + + self._add_observed( + self._add_holiday_nov_11( + # National Independence Day. + tr("Dia da Independência Nacional") + if self._year >= 1996 + # Independence Day. + else tr("Dia da Independência") + ) + ) + + # Decree # 7/92. + if self._year <= 1991: + # Date of Founding of MPLA - Labor Party. + self._add_holiday_dec_10(tr("Data da Fundacao do MPLA - Partido do Trabalho")) + + dt = self._add_christmas_day( + # Christmas and Family Day. + tr("Dia de Natal e da Família") + if self._year >= 2011 + else ( + tr("Dia do Natal") # Christmas Day. + if self._year >= 1996 + else tr("Dia da Família") # Family Day. + ) + ) + if self._year <= 2010 or self._year >= 2018: + self._add_observed(dt) + + +class AO(Angola): + pass + + +class AGO(Angola): + pass + + +class AngolaStaticHolidays: + special_public_holidays = { + # General Election Day. + 2017: (AUG, 23, tr("Dia de eleições gerais")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/anguilla.py b/.venv/lib/python3.12/site-packages/holidays/countries/anguilla.py new file mode 100644 index 00000000..7256040a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/anguilla.py @@ -0,0 +1,175 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import FEB, APR, JUN, SEP, SUN +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON_TUE, + SAT_SUN_TO_PREV_FRI, +) + + +class Anguilla(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Anguilla holidays. + + References: + - [Public Holidays For 2011](https://web.archive.org/web/20110531155208/https://www.gov.ai/holiday.php) + - [Public Holidays For 2012](https://web.archive.org/web/20120316123834/http://www.gov.ai/holiday.php) + - [Public Holidays For 2013](https://web.archive.org/web/20131113151001/http://www.gov.ai/holiday.php) + - [Public Holidays For 2014](https://web.archive.org/web/20141113163349/http://www.gov.ai/holiday.php) + - [Public Holidays For 2015](https://web.archive.org/web/20151113150558/http://www.gov.ai/holiday.php) + - [Public Holidays For 2016](https://web.archive.org/web/20161021015139/http://www.gov.ai/holiday.php) + - [Public Holidays For 2017](https://web.archive.org/web/20170830143632/http://www.gov.ai/holiday.php) + - [Public Holidays For 2018](https://web.archive.org/web/20181127040220/http://www.gov.ai/holiday.php) + - [Public Holidays For 2019](https://web.archive.org/web/20191021020537/http://www.gov.ai/holiday.php) + - [Public Holidays For 2020](https://web.archive.org/web/20210205021056/http://www.gov.ai/holiday.php) + - [Public Holidays For 2021](https://web.archive.org/web/20210901183726/http://www.gov.ai/holiday.php) + - [Public Holidays For 2022](https://web.archive.org/web/20221011200016/http://www.gov.ai/holiday.php) + - [Public Holidays For 2024](https://web.archive.org/web/20241004074741/https://www.gov.ai/service/public-holidays-for-2024) + - [Public Holidays For 2025](https://web.archive.org/web/20250425025259/https://www.gov.ai/service/public-holidays-for-2025) + - [Public Holidays Regulations R.R.A. P130-1 as of DEC 15, 2000](https://web.archive.org/web/20250611054639/https://laws.gov.ai/storage/pdfs/2000%20AXA%20Revised%20Statutes%20and%20Regulations/PDF%20(Regulations)/P-R.R.A.s/P130-Public%20Holidays%20Regulations.pdf) + - [Public Holidays Regulations R.R.A. P130-1 as of DEC 15, 2010](https://web.archive.org/web/20250611055143/https://laws.gov.ai/storage/pdfs/2010%20AXA%20Revised%20Statutes%20and%20Regulations/PDF%20(Regulations)/P-R.R.A.s/P130-Public%20Holidays%20Regulations.pdf) + """ + + country = "AI" + default_language = "en_AI" + supported_languages = ("en_AI", "en_US") + # %s (observed). + observed_label = tr("%s (observed)") + # Declaration of independence May 30, 1967, + # but the 2000 revision is the earliest comprehensive legal update. + start_year = 2001 + weekend = {SUN} + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=AnguillaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + if self._year >= 2010: + # James Ronald Webster Day. + self._add_observed(self._add_holiday_mar_2(tr("James Ronald Webster Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Labour Day"))) + + # Whit Monday. + whit_monday = self._add_whit_monday(tr("Whit Monday")) + + name = ( + # Queen's Birthday. + tr("Celebration of the Birthday of Her Majesty the Queen") + if self._year <= 2022 + # King's Birthday. + else tr("Celebration of the Birthday of His Majesty the King") + ) + if self._year == 2022: + self._add_holiday_jun_3(name) + elif self._year <= 2021: + self._add_holiday_2nd_mon_of_jun(name) + else: + self._add_holiday_3rd_mon_of_jun(name) + + # Anguilla Day. + name = tr("Anguilla Day") + self._add_observed( + dt := self._add_holiday_may_30(name), + name=name, + rule=MON_TO_NEXT_TUE + if dt == whit_monday + else ( + SAT_SUN_TO_NEXT_TUE + if self._get_observed_date(dt, SAT_SUN_TO_NEXT_MON) == whit_monday + else SAT_SUN_TO_NEXT_MON + ), + ) + + # August Monday. + self._add_holiday_1st_mon_of_aug(tr("August Monday")) + + # August Thursday. + self._add_holiday_3_days_past_1st_mon_of_aug(tr("August Thursday")) + + # Constitution Day. + self._add_holiday_4_days_past_1st_mon_of_aug(tr("Constitution Day")) + + self._add_observed( + self._add_holiday_dec_19( + # National Heroes and Heroines Day. + tr("National Heroes and Heroines Day") + if self._year >= 2011 + # Separation Day. + else tr("Separation Day") + ), + rule=SAT_SUN_TO_PREV_FRI, + ) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + +class AI(Anguilla): + pass + + +class AIA(Anguilla): + pass + + +class AnguillaStaticHolidays: + """Anguilla special holidays. + + References: + - [Government of Anguilla Official Gazette](https://web.archive.org/web/20250304213202/https://gov.ai/document/2025-03-04-123357_2051160063.pdf) + - [Mourning the Death of Her Majesty Queen Elizabeth II](https://web.archive.org/web/20250611052948/https://theanguillian.com/2022/09/mourning-the-death-of-her-majesty-queen-elizabeth-ii/) + """ + + special_public_holidays = { + # Royal Wedding of Prince William & Kate Middleton. + 2011: (APR, 29, tr("Royal Wedding of Prince William & Kate Middleton")), + # Diamond Jubilee Celebration of Her Majesty The Queen. + 2012: (JUN, 4, tr("Diamond Jubilee Celebration of Her Majesty The Queen")), + # Mourning the Death of Her Majesty The Queen Elizabeth II. + 2022: (SEP, 19, tr("Mourning the Death of Her Majesty The Queen Elizabeth II")), + # Special Public Holiday. + 2025: (FEB, 28, tr("Special Public Holiday")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/antigua_and_barbuda.py b/.venv/lib/python3.12/site-packages/holidays/countries/antigua_and_barbuda.py new file mode 100644 index 00000000..a0ac8241 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/antigua_and_barbuda.py @@ -0,0 +1,145 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import JAN, FEB, MAR, AUG +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, + SAT_SUN_TO_NEXT_MON, +) + + +class AntiguaAndBarbuda( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """Antigua and Barbuda holidays. + + References: + * [The Public Holidays Act, 1954](https://web.archive.org/web/20250123110511/https://laws.gov.ag/wp-content/uploads/2018/08/cap-354.pdf) + * [The Public Holidays (Amendment) Act, 2005](https://web.archive.org/web/20250103221834/https://laws.gov.ag/wp-content/uploads/2018/08/a2005-8.pdf) + * [The Public Holidays (Amendment) Act, 2014](https://web.archive.org/web/20250427174435/https://laws.gov.ag/wp-content/uploads/2019/03/Public-Holidays-Amendment-Act.pdf) + * [The Public Holidays (Amendment) Act, 2019](https://web.archive.org/web/20250427174433/https://laws.gov.ag/wp-content/uploads/2020/02/No.-23-of-2019-Public-Holidays-Amendment-Act-2019.pdf) + * [No. 24 of 2006 Proclamation](https://web.archive.org/web/20240620021627/http://laws.gov.ag/wp-content/uploads/2022/06/No.-24-of-2006-Proclamation-dated-29th-November2006-Appointing-the-11th-of-December2006.pdf) + * [No. 40 of 2012 Proclamation](https://web.archive.org/web/20250427174546/https://laws.gov.ag/wp-content/uploads/2021/08/No.-40-of-2012-Proclamation-dated-the-27th-day-of-November-2012-Apponting-the-27th-of-December-2012-as-a-Public-Holiday-throughout-Antigua-and-Barbuda.pdf) + * + + Notes: + In accordance with No. 24 of 2006 Proclamation, National Heroes Day was celebrated on + Dec 11, 2006. In accordance with No. 40 of 2012 Proclamation, National Heroes Day was + celebrated on Dec 10, 2012. + """ + + country = "AG" + observed_label = "%s (observed)" + start_year = 1955 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, AntiguaAndBarbudaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Labour Day. + self._add_holiday_1st_mon_of_may("Labour Day") + + # Whit Monday. + self._add_whit_monday("Whit Monday") + + if self._year <= 2005: + # Caribbean Community (Caricom) Day. + self._add_holiday_1st_mon_of_jul("Caribbean Community (Caricom) Day") + + # Carnival Monday. + self._add_holiday_1st_mon_of_aug("Carnival Monday") + + if self._year >= 2006: + # Carnival Tuesday. + self._add_holiday_1_day_past_1st_mon_of_aug("Carnival Tuesday") + + # Independence Day. + dt = self._add_holiday_nov_1("Independence Day") + if self._year >= 2005: + self._add_observed(dt, rule=SAT_SUN_TO_NEXT_MON) + + if self._year >= 2005: + name = ( + # Sir Vere Cornwall Bird Snr. Day. + "Sir Vere Cornwall Bird Snr. Day" + if self._year >= 2014 + # National Heroes Day. + else "National Heroes Day" + ) + if self._year == 2006: + self._add_holiday_dec_11(name) + elif self._year == 2012: + self._add_holiday_dec_10(name) + else: + dt = self._add_holiday_dec_9(name) + if self._year >= 2020: + self._add_observed(dt, rule=SAT_SUN_TO_NEXT_MON) + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two("Boxing Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + +class AG(AntiguaAndBarbuda): + pass + + +class ATG(AntiguaAndBarbuda): + pass + + +class AntiguaAndBarbudaStaticHolidays: + """Antigua and Barbuda special holidays. + + References: + * [August 3, 1993 Holiday](https://web.archive.org/web/20241215194404/https://laws.gov.ag/wp-content/uploads/2021/08/No.-42-of-1993-Proclamation-dated-the-22nd-day-of-July-1993-appointing-Tuesday-the-3rd-day-of-August-1993-as-a-public-holiday-throughout-Antigua-and-Barbuda..pdf) + * [State Funeral of the late The Honourable Charlesworth T. Samuel](https://web.archive.org/web/20250427174441/https://laws.gov.ag/wp-content/uploads/2022/12/No.-7-of-2008-Proclamation-dated-the-13th-day-of-February-2008-Appointing-Tuesday-19th-February-2008-as-a-Public-Holiday.pdf) + * [State Funeral of the late The Honourable Sir George Herbert Walter](https://web.archive.org/web/20250427174444/https://laws.gov.ag/wp-content/uploads/2022/12/No.-9-of-2008-Proclamation-dated-the-13th-day-of-March-2008-Appointing-Tuesday-18th-March-2008-as-a-Public-Holiday.pdf) + * According to the Public Holidays (Amendment) Act, 2014, the day after the general + election is a holiday. + * [2018 Antiguan general election](https://en.wikipedia.org/wiki/2018_Antiguan_general_election) + * [2023 Antiguan general election](https://en.wikipedia.org/wiki/2023_Antiguan_general_election) + * [The Public Holidays (Amendment) Act, 2014](https://web.archive.org/web/20250427174435/https://laws.gov.ag/wp-content/uploads/2019/03/Public-Holidays-Amendment-Act.pdf) + """ + + # Day after the General Election. + day_after_the_general_election = "Day after the General Election" + + special_public_holidays = { + 1993: (AUG, 3, "Public Holiday"), + 2008: ( + # State Funeral of the late The Honourable Charlesworth T. Samuel. + (FEB, 19, "State Funeral of the late The Honourable Charlesworth T. Samuel"), + # State Funeral of the late The Honourable Sir George Herbert Walter. + (MAR, 18, "State Funeral of the late The Honourable Sir George Herbert Walter"), + ), + 2018: (MAR, 22, day_after_the_general_election), + 2023: (JAN, 19, day_after_the_general_election), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/argentina.py b/.venv/lib/python3.12/site-packages/holidays/countries/argentina.py new file mode 100644 index 00000000..2a5480ee --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/argentina.py @@ -0,0 +1,1000 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import ARMENIAN, BANK, GOVERNMENT, HEBREW, ISLAMIC, PUBLIC +from holidays.groups import ( + ChristianHolidays, + HebrewCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + THU_TO_NEXT_MON, + TUE_WED_TO_PREV_MON, + THU_FRI_TO_NEXT_MON, +) + + +class Argentina( + ObservedHolidayBase, + ChristianHolidays, + HebrewCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Argentina holidays. + + References: + * [Spanish Wikipedia](https://es.wikipedia.org/wiki/Anexo:Días_festivos_en_Argentina) + * [Decree-Law 2446](https://web.archive.org/web/20250421214226/https://www.argentina.gob.ar/normativa/nacional/decreto_ley-2446-1956-161122/texto) + * [Law 21329](https://web.archive.org/web/20250415074830/https://www.argentina.gob.ar/normativa/nacional/ley-21329-65453/texto) + * [Law 22655](https://web.archive.org/web/20240109181150/https://www.argentina.gob.ar/normativa/nacional/ley-22655-140416/texto) + * [Law 22769](https://web.archive.org/web/20240114120630/https://www.argentina.gob.ar/normativa/nacional/ley-22769-65454/texto) + * [Decree 901/1984](https://web.archive.org/web/20240115193220/https://www.argentina.gob.ar/normativa/nacional/decreto-901-1984-65455) + * [Law 23555](https://web.archive.org/web/20250415201749/https://www.argentina.gob.ar/normativa/nacional/ley-23555-20986/texto) + * [Law 24023](https://web.archive.org/web/20250421105240/https://www.argentina.gob.ar/normativa/nacional/ley-24023-422/texto) + * [Law 24160](https://web.archive.org/web/20250419110215/https://www.argentina.gob.ar/normativa/nacional/ley-24160-558/texto) + * [Law 24360](https://web.archive.org/web/20250415204304/https://www.argentina.gob.ar/normativa/nacional/ley-24360-756/texto) + * [Law 24445](https://web.archive.org/web/20250416044658/https://www.argentina.gob.ar/normativa/nacional/ley-24445-782/texto) + * [Law 24571](https://web.archive.org/web/20250414000940/https://www.argentina.gob.ar/normativa/nacional/ley-24571-29129/texto) + * [Law 24757](https://web.archive.org/web/20250414003007/https://www.argentina.gob.ar/normativa/nacional/ley-24757-41168/texto) + * [Law 25370](https://web.archive.org/web/20250415155957/https://www.argentina.gob.ar/normativa/nacional/ley-25370-65442/texto) + * [Law 25442](https://web.archive.org/web/20250417162156/https://www.argentina.gob.ar/normativa/nacional/ley-25442-67888/texto) + * [Decree 1932/2002](https://web.archive.org/web/20240114120622/https://www.argentina.gob.ar/normativa/nacional/decreto-1932-2002-78207/texto) + * [Law 26085](https://web.archive.org/web/20250422065647/https://www.argentina.gob.ar/normativa/nacional/ley-26085-114811/texto) + * [Law 26089](https://web.archive.org/web/20250414041748/https://www.argentina.gob.ar/normativa/nacional/ley-26089-115677/texto) + * [Law 26110](https://web.archive.org/web/20250414182412/https://www.argentina.gob.ar/normativa/nacional/ley-26110-117507/texto) + * [Law 26199](https://web.archive.org/web/20250425020808/https://www.argentina.gob.ar/normativa/nacional/ley-26199-124099/texto) + * [Law 26416](https://web.archive.org/web/20250416115107/https://www.argentina.gob.ar/normativa/nacional/ley-26416-145231/texto) + * [Decree 1584/2010](https://web.archive.org/web/20250415031046/https://www.argentina.gob.ar/normativa/nacional/decreto-1584-2010-174389/texto) + * [Decree 521/2011](https://web.archive.org/web/20250416013752/https://www.argentina.gob.ar/normativa/nacional/decreto-521-2011-181754/texto) + * [Decree 2226/2015](https://web.archive.org/web/20250415163728/https://www.argentina.gob.ar/normativa/nacional/decreto-2226-2015-253971/texto) + * [Law 26876](https://web.archive.org/web/20250415210339/https://www.argentina.gob.ar/normativa/nacional/ley-26876-218152/texto) + * [Law 27258](https://web.archive.org/web/20250416110147/https://www.argentina.gob.ar/normativa/nacional/ley-27258-262574/texto) + * [Decree 52/2017](https://web.archive.org/web/20250415221116/https://www.argentina.gob.ar/normativa/nacional/decreto-52-2017-271094/texto) + * [Decree 80/2017](https://web.archive.org/web/20231214090313/https://www.argentina.gob.ar/normativa/nacional/decreto-80-2017-271382/texto) + * [Law 27399](https://web.archive.org/web/20250424202106/https://www.argentina.gob.ar/normativa/nacional/ley-27399-281835/texto) + * [Decreto 297/2020](https://web.archive.org/web/20250416211712/https://www.argentina.gob.ar/normativa/nacional/decreto-297-2020-335741/texto) + * [Collective Agreement 18/75](https://web.archive.org/web/20250415144525/https://labancaria.org/convenio-colectivo-18-75/) + + Subdivisions Holidays References: + * Catamarca: + * [Law 4553](https://web.archive.org/web/20250427173633/https://www.argentina.gob.ar/normativa/provincial/ley-4553-123456789-0abc-defg-355-4000kvorpyel) + * [Law 5525](https://web.archive.org/web/20250427173109/https://digesto.catamarca.gob.ar/ley/ley_detail/1650) + * Chubut: + * [Law I-85](https://web.archive.org/web/20240926052315/https://digesto.legislaturadelchubut.gob.ar/public/rama/1/ley/85) + * [Law I-547](https://web.archive.org/web/20250422154722/https://www.argentina.gob.ar/normativa/provincial/ley-547-123456789-0abc-defg-745-0001uvorpyel/actualizacion) + * Corrientes: + * [Law 5874](https://web.archive.org/web/20250415160018/https://www.argentina.gob.ar/normativa/provincial/ley-5874-123456789-0abc-defg-478-5000wvorpyel/actualizacion) + * [Law 5884](https://web.archive.org/web/20250415204439/https://www.argentina.gob.ar/normativa/provincial/ley-5884-123456789-0abc-defg-488-5000wvorpyel/actualizacion) + * Entre Ríos: + * [Law 7285/84](https://web.archive.org/web/20241208122634/https://www.entrerios.gov.ar/dgrrhh/normativas/7285%20-%20Feriado%203%20de%20febrero.pdf) + * [Decree 4359/93](https://web.archive.org/web/20240626093740/https://www.entrerios.gov.ar/dgrrhh/normativas/1993%20-%204359%20MGJE%20(San%20Miguel%20Arcangel).pdf) + * [Decree 216/2003](https://web.archive.org/web/20220816033046/https://www.entrerios.gov.ar/dgrrhh/normativas/2003%20-%20216%20GOB%20(Dia%20del%20Empleado%20Publico).pdf) + * [Law 10541](https://web.archive.org/web/20250417063744/https://www.argentina.gob.ar/normativa/provincial/ley-10541-123456789-0abc-defg-145-0100evorpyel/actualizacion) + * Jujuy: + * [Law 4059](https://web.archive.org/web/20250416043711/https://boletinoficial.jujuy.gob.ar/?p=44711) + * [Law 4927](https://web.archive.org/web/20250415213548/https://boletinoficial.jujuy.gob.ar/?p=56587) + * [Law 5005](https://web.archive.org/web/20250414192446/https://boletinoficial.jujuy.gob.ar/?p=51196) + * [Law 6197](https://web.archive.org/web/20250422010737/https://boletinoficial.jujuy.gob.ar/?p=204052) + * La Rioja: + * [Law 6886](https://web.archive.org/web/20250415205303/https://www.argentina.gob.ar/normativa/provincial/ley-6886-123456789-0abc-defg-688-6000fvorpyel/actualizacion) + * [Law 9844](https://web.archive.org/web/20250416124635/https://www.argentina.gob.ar/normativa/provincial/ley-9844-123456789-0abc-defg-448-9000fvorpyel/actualizacion) + * [Law 9955](https://web.archive.org/web/20250414092438/https://www.argentina.gob.ar/normativa/provincial/ley-9955-123456789-0abc-defg-559-9000fvorpyel/actualizacion) + * [Law 10242](https://web.archive.org/web/20250414195737/https://www.argentina.gob.ar/normativa/provincial/ley-10242-123456789-0abc-defg-242-0100fvorpyel/actualizacion) + * [Law 10298](https://web.archive.org/web/20250416014331/https://www.argentina.gob.ar/normativa/provincial/ley-10298-123456789-0abc-defg-892-0100fvorpyel/actualizacion) + * [Law 1035](https://web.archive.org/web/20250415042554/https://www.argentina.gob.ar/normativa/provincial/ley-1035-123456789-0abc-defg-153-0100fvorpyel/actualizacion) + * Mendoza: + * [Law 4081](https://web.archive.org/web/20250418220022/https://www.argentina.gob.ar/normativa/provincial/ley-4081-123456789-0abc-defg-534-0000mvorpyel/actualizacion) + * Salta: + * [Law 5032](https://web.archive.org/web/20250414055533/https://www.argentina.gob.ar/normativa/provincial/ley-5032-123456789-0abc-defg-230-5000avorpyel/actualizacion) + * San Juan: + * [Law 14-P](https://web.archive.org/web/20250427173119/https://www.argentina.gob.ar/normativa/provincial/ley-14-123456789-0abc-defg-410-0061jvorpyel/actualizacion) + * San Luis: + * [Law II-0046-2004](https://web.archive.org/web/20250427173701/https://www.argentina.gob.ar/normativa/provincial/ley-46-123456789-0abc-defg-640-0001dvorpyel/actualizacion) + * Santa Cruz: + * [Law 2882](https://web.archive.org/web/20250427173158/https://www.argentina.gob.ar/normativa/provincial/ley-2882-123456789-0abc-defg-288-2000zvorpyel/actualizacion) + * [Law 3342](https://web.archive.org/web/20250427173122/https://www.argentina.gob.ar/normativa/provincial/ley-3342-123456789-0abc-defg-243-3000zvorpyel/actualizacion) + * [Law 3419](https://web.archive.org/web/20250427173122/https://www.argentina.gob.ar/normativa/provincial/ley-3419-123456789-0abc-defg-914-3000zvorpyel/actualizacion) + * [Law 3668](https://web.archive.org/web/20250427173133/https://www.argentina.gob.ar/normativa/provincial/ley-3668-123456789-0abc-defg-866-3000zvorpyel/actualizacion) + * Tierra del Fuego: + * [Law 7/92](https://web.archive.org/web/20250427173650/https://www.argentina.gob.ar/normativa/provincial/ley-7-123456789-0abc-defg-751-0000vvorpyel/actualizacion) + * [Law 1389/2021](https://web.archive.org/web/20250427173101/https://www.argentina.gob.ar/normativa/provincial/ley-1389-123456789-0abc-defg-588-1000vvorpyel/actualizacion) + * Tucumán: + * [Law 1765](https://web.archive.org/web/20241213162228/https://fet.com.ar/nota/1054/feriado-en-tucuman-24-de-setiembre) + + Other sources: + * + * + * + * + * + + Checked With: + * + * + * + * + * + * + * + * + * + * + * + * [Entre Ríos](https://web.archive.org/web/20241003004359/https://www.entrerios.gov.ar/dgrrhh/index.php?i=7) + * [Tierra del Fuego](https://web.archive.org/web/20240716112344/https://www.justierradelfuego.gov.ar/dias-no-laborables/) + * Jujuy: + * + * + """ + + country = "AR" + default_language = "es" + # %s (observed). + observed_label = tr("%s (observado)") + # Decree-Law 2446. + start_year = 1957 + subdivisions = ( + "A", # Salta. + "B", # Buenos Aires. + "C", # Ciudad Autónoma de Buenos Aires. + "D", # San Luis. + "E", # Entre Ríos. + "F", # La Rioja. + "G", # Santiago del Estero. + "H", # Chaco. + "J", # San Juan. + "K", # Catamarca. + "L", # La Pampa. + "M", # Mendoza. + "N", # Misiones. + "P", # Formosa. + "Q", # Neuquén. + "R", # Río Negro. + "S", # Santa Fe. + "T", # Tucumán. + "U", # Chubut. + "V", # Tierra del Fuego. + "W", # Corrientes. + "X", # Córdoba. + "Y", # Jujuy. + "Z", # Santa Cruz. + ) + subdivisions_aliases = { + "Salta": "A", + "Buenos Aires": "B", + "Ciudad Autónoma de Buenos Aires": "C", + "San Luis": "D", + "Entre Ríos": "E", + "La Rioja": "F", + "Santiago del Estero": "G", + "Chaco": "H", + "San Juan": "J", + "Catamarca": "K", + "La Pampa": "L", + "Mendoza": "M", + "Misiones": "N", + "Formosa": "P", + "Neuquén": "Q", + "Río Negro": "R", + "Santa Fe": "S", + "Tucumán": "T", + "Chubut": "U", + "Tierra del Fuego": "V", + "Corrientes": "W", + "Córdoba": "X", + "Jujuy": "Y", + "Santa Cruz": "Z", + } + supported_languages = ("en_US", "es", "uk") + supported_categories = (ARMENIAN, BANK, GOVERNMENT, HEBREW, ISLAMIC, PUBLIC) + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + HebrewCalendarHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=ArgentinaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, ArgentinaStaticHolidays) + # Law 23555. + kwargs.setdefault("observed_rule", TUE_WED_TO_PREV_MON + THU_FRI_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1988) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Established in 1957 by Decree-Law 2446. + # Abolished in 1977 by Law 21329. + + if self._year <= 1976: + # Epiphany. + self._add_epiphany_day(tr("Día de Reyes")) + + # Established in 1956 by Decree-Law 2446. + # Abolished in 1977 by Law 21329. + # Restored in 2011 by Decree 1584/2010. + + if self._year <= 1976 or self._year >= 2011: + # Carnival Monday. + self._add_carnival_monday(tr("Lunes de Carnaval")) + + # Carnival Tuesday. + self._add_carnival_tuesday(tr("Martes de Carnaval")) + + # Established in 2006 by Law 26085. + + if self._year >= 2006: + self._add_holiday_mar_24( + # National Day of Remembrance for Truth and Justice. + tr("Día Nacional de la Memoria por la Verdad y la Justicia") + ) + + # Established in 1993 by Law 24160. + # Merged in 2001 with "Day of Affirmation of Argentine Rights..." by Law 25370. + # Made fixed in 2007 by Law 26110. + # Got moved temporary in 2020 (Decree 297/2020). + + if self._year >= 1993: + name = ( + # War Veteran's Day. + tr("Día del Veterano de Guerra") + if self._year <= 2000 + # Veteran's Day and the Fallen in the Malvinas War. + else tr("Día del Veterano y de los Caidos en la Guerra de Malvinas") + ) + if self._year == 2020: + self._add_holiday_mar_31(name) + else: + apr_2 = self._add_holiday_apr_2(name) + if self._year <= 2006: + self._move_holiday(apr_2, show_observed_label=False) + + # Established in 1957 by Decree-Law 2446. + # Abolished in 1977 by Law 21329. + # Restored in 2011 by Decree 1584/2010 (as non-working day). + + if self._year <= 1976 or self._year >= 2011: + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Established in 1977 by Law 21329. + + if self._year >= 1977: + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Labor Day. + self._add_labor_day(tr("Día del Trabajo")) + + # May Revolution Day. + self._add_holiday_may_25(tr("Día de la Revolución de Mayo")) + + # Established in 1957 by Decree-Law 2446. + # Abolished in 1976 by Law 21329. + + if self._year <= 1975: + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + # Established in 1983 on April 2 by Law 22769. + # Moved to June 10 by Decree 901/1984. + # Made movable in 1988 by Law 23555. + # Abandoned in 2001 (superseded by "Veterans Day and the Fallen in the Malvinas War"). + + if 1983 <= self._year <= 2000: + # Day of Affirmation of Argentine Rights over the Malvinas, Islands and + # Antarctic Sector. + name = tr( + "Día de la Afirmación de los Derechos Argentinos sobre las Malvinas, " + "Islas y Sector Antártico" + ) + if self._year == 1983: + self._add_holiday_apr_2(name) + else: + self._move_holiday(self._add_holiday_jun_10(name), show_observed_label=False) + + # Established in 2016 by Law 27258. + + if self._year >= 2016: + # If Jun 17 is Friday, then it should move to Mon, Jun 20 + # but Jun 20 is Gen. Belgrano holiday. + self._move_holiday( + self._add_holiday_jun_17( + # Pass to the Immortality of General Don Martín Miguel de Güemes. + tr("Paso a la Inmortalidad del General Don Martín Miguel de Güemes") + ), + rule=TUE_WED_TO_PREV_MON + THU_TO_NEXT_MON, + show_observed_label=False, + ) + + # Established in 1938 as fixed by Law 12361. + # Made movable in 1988 by Law 23555. + # Made fixed in 1992 by Law 24023. + # Set as 3rd MON of JUN in 1995 by Law 24445. + # Made fixed in 2011 by Decree 1584/2010. + # Also called "National Flag Day" (Día de la Bandera Nacional). + + # Pass to the Immortality of General Don Manuel Belgrano. + name = tr("Paso a la Inmortalidad del General Don Manuel Belgrano") + + if 1995 <= self._year <= 2010: + self._add_holiday_3rd_mon_of_jun(name) + else: + jun_20 = self._add_holiday_jun_20(name) + if self._year <= 1991: + self._move_holiday(jun_20, show_observed_label=False) + + # Independence Day. + self._add_holiday_jul_9(tr("Día de la Independencia")) + + # Established in 1957 by Decree-Law 2446. + # Abolished in 1976 by Law 21329. + + # Established in 1938 as fixed by Law 12387. + # Made movable in 1988 by Law 23555. + # Set as 3rd MON of AUG in 1995 by Law 24445. + # Moved to Aug 22 for 2011 (election interfere) by Decree 521/2011. + # Made movable in 2017 by Decree 52/2017. + + # Pass to the Immortality of General Don José de San Martín. + name = tr("Paso a la Inmortalidad del General Don José de San Martín") + if self._year <= 1994 or self._year >= 2017: + self._move_holiday(self._add_holiday_aug_17(name), show_observed_label=False) + elif self._year == 2011: + self._add_holiday_aug_22(name) + else: + self._add_holiday_3rd_mon_of_aug(name) + + # Established in 1957 by Decree-Law 2446. + # Abolished in 1977 by Law 21329. + + if self._year <= 1975: + # Assumption Day. + self._add_assumption_of_mary_day(tr("Día de la Asunción")) + + # Established in 1917. + # Abolished in 1976 by Law 21329. + # Restored in 1982 by Law 22655. + # Made movable in 1988 by Law 23555. + # Observed on Oct 8 in 2001 by Law 25442. + # Observed on Oct 14 in 2002 by Decree 1932/2002. + # Changed moving rule in 2008 by Law 26146 + # 2008-2009 actual dates match the dates by the 2010 rule, so code is simplified. + # Changed name and moving rule in 2010 by Decree 1584/2010. + # Changed moving rule in 2017 by Decree 52/2017. + + if self._year <= 1975 or self._year >= 1982: + name = ( + # Respect for Cultural Diversity Day. + tr("Día del Respeto a la Diversidad Cultural") + if self._year >= 2010 + # Columbus Day. + else tr("Día de la Raza") + ) + if self._year == 2001: + self._add_holiday_oct_8(name) + elif self._year == 2002: + self._add_holiday_oct_14(name) + elif 2008 <= self._year <= 2016: + self._add_holiday_2nd_mon_of_oct(name) + else: + self._move_holiday(self._add_columbus_day(name), show_observed_label=False) + + # Established in 1957 by Decree-Law 2446. + # Abolished in 1977 by Law 21329. + + if self._year <= 1975: + # All Saints' Day. + self._add_all_saints_day(tr("Todos Los Santos")) + + # First observed with no holiday in 1974 by Law 20770. + # Established in 2010 as 4th MON of NOV by Decree 1584/2010. + # Moved to Nov 27 in 2015 by Decree 2226/2015. + # Moved to Nov 28 again for 2016. + + if self._year >= 2010: + # National Sovereignty Day. + name = tr("Día de la Soberanía Nacional") + if self._year >= 2017: + self._move_holiday(self._add_holiday_nov_20(name), show_observed_label=False) + elif self._year == 2016: + self._add_holiday_nov_28(name) + elif self._year == 2015: + self._add_holiday_nov_27(name) + else: + self._add_holiday_4th_mon_of_nov(name) + + # Established in 1957 by Decree-Law 2446. + # Abolished in 1976 by Law 21329. + # Restored in 1995 by Law 24445. + + if self._year <= 1975 or self._year >= 1995: + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Inmaculada Concepción de María")) + + # Christmas Day. + self._add_christmas_day(tr("Navidad")) + + def _populate_subdiv_a_public_holidays(self): + """Salta holidays.""" + + # Law 5032. + if self._year >= 1977: + # Anniversary of the Battle of Salta. + self._add_holiday_feb_20(tr("Aniversario de la Batalla de Salta")) + + self._add_holiday_jun_17( + # Day of Memory of General Don Martín Miguel de Güemes. + tr( + "Dia de la memoria del Guerrero de la Independencia y Gobernador " + "de la Provincia de Salta General Don Martín Miguel de Güemes" + ) + ) + + # Feasts of the Lord and the Virgin of Miracle. + name = tr("Festividades del Señor y de la Virgen del Milagro") + self._add_holiday_sep_13(name) + self._add_holiday_sep_14(name) + self._add_holiday_sep_15(name) + + def _populate_subdiv_d_public_holidays(self): + """San Luis holidays.""" + + # Law II-0046-2004. + if self._year >= 2004: + # Exaltation of the Holy Cross Day. + self._add_holiday_may_3(tr("Día de la Exaltación de la Santa Cruz")) + + # Saint Louis the King of France's Day. + self._add_holiday_aug_25(tr("Día de San Luis Rey de Francia")) + + def _populate_subdiv_e_public_holidays(self): + """Entre Ríos holidays.""" + + # Law 10541. + if self._year >= 2018: + self._add_holiday_mar_24( + # Provincial Day of Remembrance for Truth and Justice. + tr("Día Provincial de la Memoria por la Verdad y la Justicia") + ) + + # Law 7285/84. + if self._year >= 1984: + # Commemoration of the Battle of Caseros. + self._add_holiday_feb_3(tr("Conmemoración de la Batalla de Caseros")) + + # Decree 216/2003. + if self._year >= 2004: + # State Worker's Day. + self._add_holiday_jun_27(tr("Día del Trabajador Estatal")) + + # Decree 4359/93. + if self._year >= 1993: + # Saint Michael the Archangel's Day. + self._add_holiday_sep_29(tr("San Miguel Arcángel")) + + def _populate_subdiv_f_public_holidays(self): + """La Rioja holidays.""" + + # Law 1035. + if self._year >= 2021: + # Day of the Death of Juan Facundo Quiroga. + self._add_holiday_feb_16(tr("Día del fallecimiento de Juan Facundo Quiroga")) + + # Law 10242. + if self._year >= 2020: + # Provincial Autonomy Day. + self._add_holiday_mar_1(tr("Día de la Autonomía Provincial")) + + # Law 9955. + if self._year >= 2017: + # Day of Remembrance for Truth and Justice. + self._add_holiday_mar_24(tr("Día de la Memoria por la Verdad y la Justicia")) + + # Established by Law 9955. + # Abolished by Law 10298. + if 2017 <= self._year <= 2020: + # Malvinas Memorial Day. + self._add_holiday_apr_2(tr("Día de los Caídos en Malvinas")) + + # Law 6886. + if self._year >= 2000: + # La Rioja Foundation Day. + self._add_holiday_may_20(tr("Día de la fundación de La Rioja")) + + # Law 9844. + if self._year >= 2016: + self._add_holiday_aug_4( + # Anniversary of the Death of Enrique Angelelli. + tr("Día del Aniversario del Fallecimiento de Monseñor Enrique Angelelli") + ) + + # Law 10298. + if self._year >= 2020: + self._add_holiday_nov_12( + # Anniversary of the Death of Ángel Vicente Peñaloza. + tr("Día del Aniversario del Fallecimiento de Ángel Vicente Peñaloza") + ) + + # Law 6886. + if self._year >= 2000: + # Tinkunaco Festival. + self._add_holiday_dec_31(tr("Día del Tinkunaco Riojano")) + + def _populate_subdiv_j_public_holidays(self): + """San Juan holidays.""" + + # Law 14-P. + if self._year >= 2015: + # Teacher's Day. + self._add_holiday_sep_11(tr("Día del Maestro")) + + def _populate_subdiv_k_public_holidays(self): + """Catamarca holidays.""" + + # Law 4553. + if self._year >= 1990: + # Birthday of Mamerto Esquiú. + self._add_holiday_may_11(tr("Natalicio de Fray Mamerto Esquiú")) + + # Catamarca Autonomy Day. + self._add_holiday_aug_25(tr("Autonomía de Catamarca")) + + # Law 5525. + if self._year >= 2018: + # Miracle Day. + self._add_holiday_sep_7(tr("Día del Milagro")) + + # Law 4553. + if self._year >= 1989: + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Inmaculada Concepción de María")) + + def _populate_subdiv_m_public_holidays(self): + """Mendoza holidays.""" + + # Law 4081. + if self._year >= 1977: + # Saint James' Day. + self._add_saint_james_day(tr("Día del Apóstol Santiago")) + + def _populate_subdiv_t_public_holidays(self): + """Tucumán holidays.""" + + # Law 1765. + + # Anniversary of the Battle of Tucumán. + self._add_holiday_sep_24(tr("Aniversario de la Batalla de Tucumán")) + + def _populate_subdiv_u_public_holidays(self): + """Chubut holidays.""" + + # Law I-85. + if self._year >= 1984: + # Plebiscite 1902 Trevelin. + self._add_holiday_apr_30(tr("Plebiscito 1902 Trevelin")) + + self._add_holiday_jul_28( + # Anniversary of the arrival of the first Welsh settlers. + tr("Aniversario del arribo de los primeros colonizadores galeses") + ) + + # National Petroleum Day. + self._add_holiday_dec_13(tr("Día del Petróleo Nacional")) + + # Law I-547. + if self._year >= 2015: + self._add_holiday_nov_3( + # Tehuelches and Mapuches declare loyalty to the Argentine flag. + tr("Tehuelches y Mapuches declaran lealtad a la bandera Argentina") + ) + + def _populate_subdiv_v_public_holidays(self): + """Tierra del Fuego holidays.""" + + # Law 7/92. + if self._year >= 1992: + self._add_holiday_jun_1( + # Day of the Province of Tierra del Fuego, Antarctica + # and the South Atlantic Islands. + tr("Día de la Provincia de Tierra del Fuego, Antártida e Islas del Atlántico Sur") + ) + + # Law 1389/2021. + if self._year >= 2021: + # Selk'Nam Genocide Day. + self._add_holiday_nov_25(tr("Día del Genocidio Selk'Nam")) + + def _populate_subdiv_w_public_holidays(self): + """Corrientes holidays.""" + + if self._year >= 2009: + # Law 5884. + self._add_holiday_jun_20( + # Anniversary of the Death of General Manuel Belgrano. + tr( + "Día del Aniversario del Fallecimiento del General Manuel José Joaquín " + "del Corazón de Jesús Belgrano" + ) + ) + + # Law 5874. + self._add_holiday_aug_17( + # Anniversary of the Death of General José Francisco de San Martín. + tr( + "Día del Aniversario del Fallecimiento del General José Francisco " + "de San Martín" + ) + ) + + def _populate_subdiv_y_public_holidays(self): + """Jujuy holidays.""" + + # Law 4059. + if self._year >= 1984: + # Carnival Monday. + self._add_carnival_monday(tr("Lunes de Carnaval")) + + # Carnival Tuesday. + self._add_carnival_tuesday(tr("Martes de Carnaval")) + + # Jujuy Exodus Day. + self._add_holiday_aug_23(tr("Día del Éxodo Jujeño")) + + # Jujuy Political Autonomy Day. + self._add_holiday_nov_18(tr("Autonomía Política de Jujuy")) + + # Law 4927. + if self._year >= 1996: + # Pachamama Day. + self._add_holiday_aug_1(tr("Día de la Pachamama")) + + # Law 5005. + if self._year >= 1997: + # Day of the Virgin of the Rosary of Río Blanco and Paypaya. + self._add_holiday_oct_7(tr("Día de la Virgen del Rosario de Río Blanco y Paypaya")) + + # Law 6197. + if self._year >= 2021: + # Great Day of Jujuy. + self._add_holiday_apr_27(tr("Día Grande de Jujuy")) + + def _populate_subdiv_z_public_holidays(self): + """Santa Cruz holidays.""" + + # Law 2882, Law 3419. + if self._year >= 2007: + # Saint John Bosco's Day. + name = tr("Homenaje al Patrono de la Provincia San Juan Bosco") + if self._year >= 2015: + self._add_holiday_aug_16(name) + else: + self._add_holiday_jan_31(name) + + # Law 3342. + if self._year >= 2014: + self._add_holiday_oct_27( + # Anniversary of the Death of Néstor Carlos Kirchner. + tr( + "Día del Aniversario del Fallecimiento del ex Presidente de la Nación " + "Doctor Néstor Carlos Kirchner" + ) + ) + + # Law 3669. + if self._year >= 2019: + self._add_holiday_dec_7( + # Commemoration of the workers shot in the Patagonian Strikes. + tr("Conmemoración a los obreros fusilados en las Huelgas Patagónicas") + ) + + def _populate_armenian_holidays(self): + # Established in 2007 by Law 26199. + + if self._year >= 2007: + self._add_holiday_apr_24( + # Day of Action for Tolerance and Respect among Peoples. + tr("Día de acción por la tolerancia y el respeto entre los pueblos") + ) + + def _populate_bank_holidays(self): + # Established in 1975 by Collective Agreement 18/75, Art. 50. + + if self._year >= 1975: + # Bankers' Day. + self._add_holiday_nov_6(tr("Día del Bancario")) + + def _populate_government_holidays(self): + # Established in 2014 by Law 26876. + + if self._year >= 2014: + # State Worker's Day. + self._add_holiday_jun_27(tr("Día del Trabajador del Estado")) + + def _populate_hebrew_holidays(self): + # Established in 1996 by Law 24571. + + if self._year >= 1996: + # Rosh Hashanah. + self._add_rosh_hashanah(tr("Año Nuevo Judío (Rosh Hashana)"), range(2)) + + # Yom Kippur. + self._add_yom_kippur(tr("Día del Perdón (Iom Kipur)")) + + # Established in 2007 by Law 26089. + + if self._year >= 2007: + # Pesach. + name = tr("Pascua Judía (Pésaj)") + self._add_passover(name, range(2)) + self._add_passover(name, range(6, 8)) + + def _populate_islamic_holidays(self): + # Established in 1997 by Law 24757. + + if self._year >= 1997: + # Islamic New Year. + self._add_islamic_new_year_day(tr("Año Nuevo Musulmán (Hégira)")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Día posterior a la culminación del ayuno (Id Al-Fitr)")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Día de la Fiesta del Sacrificio (Id Al-Adha)")) + + +class AR(Argentina): + pass + + +class ARG(Argentina): + pass + + +class ArgentinaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 10), + } + + EID_AL_FITR_DATES = { + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + HIJRI_NEW_YEAR_DATES = { + 2019: (AUG, 31), + 2020: (AUG, 20), + 2021: (AUG, 8), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 7), + 2025: (JUN, 26), + } + + +class ArgentinaStaticHolidays: + """Argentina special holidays. + + Special Holidays References: + * [Decree 615/2010](https://web.archive.org/web/20240109181152/https://www.argentina.gob.ar/normativa/nacional/decreto-615-2010-166825/texto) + * [Joint Resolution 1159/2010](https://web.archive.org/web/20231215002151/https://www.argentina.gob.ar/normativa/nacional/resolución-1159-2010-173748/texto) + * [Law 26721](https://web.archive.org/web/20240109181220/https://www.argentina.gob.ar/normativa/nacional/ley-26721-191835/texto) + * [Law 26763](https://web.archive.org/web/20240109181221/https://www.argentina.gob.ar/normativa/nacional/ley-26763-201915/texto) + * [Law 26837](https://web.archive.org/web/20240109181217/https://www.argentina.gob.ar/normativa/nacional/ley-26837-207405/texto) + * [Law 26840](https://web.archive.org/web/20240109181218/https://www.argentina.gob.ar/normativa/nacional/ley-26840-207258/texto) + * [Decree 42/2022](https://web.archive.org/web/20241208143041/https://www.argentina.gob.ar/normativa/nacional/decreto-42-2022-360018/texto) + * [Decree 842/2022](https://web.archive.org/web/20240114151710/https://www.argentina.gob.ar/normativa/nacional/decreto-842-2022-376857/texto) + + Special Bank Holidays References: + * [Release P50962 (2019)](https://web.archive.org/web/20250219192339/https://www.bcra.gob.ar/Pdfs/comytexord/P50962.pdf) + * [Release P50983 (2020)](https://web.archive.org/web/20241203102423/https://www.bcra.gob.ar/Pdfs/comytexord/p50983.pdf) + * [Release P51020 (2021)](https://web.archive.org/web/20240616000609/http://www.bcra.gob.ar/Pdfs/comytexord/P51020.pdf) + * [Release P51155 (2024)](https://web.archive.org/web/20250427172945/https://bcra.gob.ar/Pdfs/comytexord/P51155.pdf) + + Special Subdivision-level Holidays References: + * [2018 G20 Leader Summit Special Holidays for Buenos Aires](https://web.archive.org/web/20220305033755/https://www.perfil.com/noticias/sociedad/30-de-noviembre-feriado-ciudad-de-buenos-aires-cumbre-g20.phtml) + + Special Subdivision-level Holidays References: + * [2018 G20 Leader Summit Special Holidays for Buenos Aires](https://web.archive.org/web/20220305033755/https://www.perfil.com/noticias/sociedad/30-de-noviembre-feriado-ciudad-de-buenos-aires-cumbre-g20.phtml) + + Special Bridge Holidays are given upto 3 days a year as long as it's declared + 50 days before calendar year's end. + There's no Bridge Holidays declared in 2017. + + Bridge Holidays References: + * [Decree 1585/2010 (2011-2013 Bridge Holidays)](https://web.archive.org/web/20240109181210/https://www.argentina.gob.ar/normativa/nacional/decreto-1585-2010-174391/texto) + * [Decree 1768/2013 (2014-2016 Bridge Holidays)](https://web.archive.org/web/20240109181211/https://www.argentina.gob.ar/normativa/nacional/decreto-1768-2013-222021/texto) + * [Decree 923/2017 (2018-2019 Bridge Holidays)](https://web.archive.org/web/20231215115842/https://www.argentina.gob.ar/normativa/nacional/decreto-923-2017-287145) + * [Decree 717/2019 (2020 Bridge Holidays)](https://web.archive.org/web/20241208012315/https://www.argentina.gob.ar/normativa/nacional/decreto-717-2019-330204/texto) + * [Decree 947/2020 (2021 Bridge Holidays)](https://web.archive.org/web/20250424202105/https://www.argentina.gob.ar/normativa/nacional/decreto-947-2020-344620/texto) + * [Decree 789/2021 (2022 Bridge Holidays)](https://web.archive.org/web/20250114061352/https://www.argentina.gob.ar/normativa/nacional/decreto-789-2021-356678/texto) + * [Decree 764/2022 (2023 Bridge Holidays)](https://web.archive.org/web/20250216064929/https://www.argentina.gob.ar/normativa/nacional/decreto-764-2022-375264/texto) + * [Decree 106/2023 (2024 Bridge Holidays)](https://web.archive.org/web/20240930174820/https://www.argentina.gob.ar/normativa/nacional/decreto-106-2023-395689/texto) + * [Decree 1017/2024 (2025 Bridge Holidays)](https://web.archive.org/web/20241227231911/https://www.argentina.gob.ar/normativa/nacional/decreto-1027-2024-406417/texto) + """ + + # Bridge Public Holiday. + arg_bridge_public_holiday = tr("Feriado con fines turísticos") + + # Bicentenary of the May Revolution. + bicentennial_may_revolution = tr("Bicentenario de la Revolución de Mayo") + + # Bicentenary of the creation and first oath of the national flag. + bicentennial_national_flag = tr( + "Bicentenario de la creación y primera jura de la bandera nacional" + ) + + # Bicentenary of the Battle of Tucuman. + bicentennial_battle_tucuman = tr("Bicentenario de la Batalla de Tucumán") + + # Bicentenary of the inaugural session of the National Constituent Assembly of the year 1813. + bicentennial_assembly_1813 = tr( + "Bicentenario de la sesión inaugural de la Asamblea Nacional Constituyente del año 1813" + ) + + # Bicentenary of the Battle of Salta. + bicentennial_battle_salta = tr("Bicentenario de la Batalla de Salta") + + # National Census Day 2010. + national_census_2010 = tr("Censo Nacional 2010") + + # G20 Leaders' Summit. + g20_leaders_summit_holiday = tr("Cumbre de Líderes del Grupo de los 20 (G20)") + + # National Census Day 2022. + national_census_2022 = tr("Censo Nacional 2022") + + # FIFA World Cup 2022 Victory Day. + fifa_world_cup_2022_victory_day = tr("Día de la Victoria de la Copa Mundial de la FIFA 2022") + + # Bank Holiday. + bank_holiday = tr("Asueto bancario") + + special_public_holidays = { + 2010: ( + # Decree 615/2010. + (MAY, 24, bicentennial_may_revolution), + # Joint Resolution 1159/2010. + (OCT, 27, national_census_2010), + ), + 2011: ( + (MAR, 25, arg_bridge_public_holiday), + (DEC, 9, arg_bridge_public_holiday), + ), + 2012: ( + # Law 26721. + (FEB, 27, bicentennial_national_flag), + (APR, 30, arg_bridge_public_holiday), + # Law 26763. + (SEP, 24, bicentennial_battle_tucuman), + (DEC, 24, arg_bridge_public_holiday), + ), + 2013: ( + # Law 26840. + (JAN, 31, bicentennial_assembly_1813), + # Law 26837. + (FEB, 20, bicentennial_battle_salta), + (APR, 1, arg_bridge_public_holiday), + (JUN, 21, arg_bridge_public_holiday), + ), + 2014: ( + (MAY, 2, arg_bridge_public_holiday), + (DEC, 26, arg_bridge_public_holiday), + ), + 2015: ( + (MAR, 23, arg_bridge_public_holiday), + (DEC, 7, arg_bridge_public_holiday), + ), + 2016: ( + (JUL, 8, arg_bridge_public_holiday), + (DEC, 9, arg_bridge_public_holiday), + ), + 2018: ( + (APR, 30, arg_bridge_public_holiday), + (DEC, 24, arg_bridge_public_holiday), + (DEC, 31, arg_bridge_public_holiday), + ), + 2019: ( + (JUL, 8, arg_bridge_public_holiday), + (AUG, 19, arg_bridge_public_holiday), + (OCT, 14, arg_bridge_public_holiday), + ), + 2020: ( + (MAR, 23, arg_bridge_public_holiday), + (JUL, 10, arg_bridge_public_holiday), + (DEC, 7, arg_bridge_public_holiday), + ), + 2021: ( + (MAY, 24, arg_bridge_public_holiday), + (OCT, 8, arg_bridge_public_holiday), + (NOV, 22, arg_bridge_public_holiday), + ), + 2022: ( + # Decree 42/2022. + (MAY, 18, national_census_2022), + (OCT, 7, arg_bridge_public_holiday), + (NOV, 21, arg_bridge_public_holiday), + (DEC, 9, arg_bridge_public_holiday), + # Decree 842/2022. + (DEC, 20, fifa_world_cup_2022_victory_day), + ), + 2023: ( + (MAY, 26, arg_bridge_public_holiday), + (JUN, 19, arg_bridge_public_holiday), + (OCT, 13, arg_bridge_public_holiday), + ), + 2024: ( + (APR, 1, arg_bridge_public_holiday), + (JUN, 21, arg_bridge_public_holiday), + (OCT, 11, arg_bridge_public_holiday), + ), + 2025: ( + (MAY, 2, arg_bridge_public_holiday), + (AUG, 15, arg_bridge_public_holiday), + (NOV, 21, arg_bridge_public_holiday), + ), + } + + special_bank_holidays = { + # Release P50962. + 2019: ( + (DEC, 24, bank_holiday), + (DEC, 31, bank_holiday), + ), + # Release P50983. + 2020: ( + (DEC, 24, bank_holiday), + (DEC, 31, bank_holiday), + ), + # Release P51020. + 2021: ( + (DEC, 24, bank_holiday), + (DEC, 31, bank_holiday), + ), + # Release P51155. + 2024: ( + (DEC, 24, bank_holiday), + (DEC, 31, bank_holiday), + ), + } + + special_b_public_holidays = { + 2018: (NOV, 30, g20_leaders_summit_holiday), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/armenia.py b/.venv/lib/python3.12/site-packages/holidays/countries/armenia.py new file mode 100644 index 00000000..0108d7fa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/armenia.py @@ -0,0 +1,108 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Armenia(HolidayBase, ChristianHolidays, InternationalHolidays): + """Armenia holidays. + + References: + * + * + * + """ + + country = "AM" + default_language = "hy" + supported_languages = ("en_US", "hy") + start_year = 1991 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Նոր տարվա օր") + self._add_new_years_day(name) + self._add_new_years_day_two(name) + + # Christmas. Epiphany Day. + self._add_holiday_jan_6(tr("Սուրբ Ծնունդ եւ Հայտնություն")) + + if 2010 <= self._year <= 2021: + self._add_new_years_day_three(name) + self._add_new_years_day_four(name) + + # Christmas Eve. + self._add_holiday_jan_5(tr("Սուրբ Ծննդյան տոներ")) + + # The Day of Remembrance of the Dead. + self._add_holiday_jan_7(tr("Մեռելոց հիշատակի օր")) + + if self._year >= 2003: + # Army Day. + self._add_holiday_jan_28(tr("Բանակի օր")) + + # Women's Day. + self._add_womens_day(tr("Կանանց տոն")) + + if 1994 <= self._year <= 2001: + # Motherhood and Beauty Day. + self._add_holiday_apr_7(tr("Մայրության և գեղեցկության տոն")) + + # Armenian Genocide Remembrance Day. + self._add_holiday_apr_24(tr("Եղեռնի զոհերի հիշատակի օր")) + + if self._year >= 2001: + self._add_labor_day( + # Labor Day. + tr("Աշխատանքի օր") + if self._year >= 2002 + # International Day of Workers' Solidarity. + else tr("Աշխատավորների համերաշխության միջազգային օր") + ) + + if self._year >= 1995: + self._add_world_war_two_victory_day( + # Victory and Peace Day. + tr("Հաղթանակի և Խաղաղության տոն"), + is_western=False, + ) + + # Republic Day. + self._add_holiday_may_28(tr("Հանրապետության օր")) + + if self._year >= 1996: + # Constitution Day. + self._add_holiday_jul_5(tr("Սահմանադրության օր")) + + if self._year >= 1992: + # Independence Day. + self._add_holiday_sep_21(tr("Անկախության օր")) + + # New Year's Eve. + self._add_new_years_eve(tr("Նոր տարվա գիշեր")) + + +class AM(Armenia): + pass + + +class ARM(Armenia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/aruba.py b/.venv/lib/python3.12/site-packages/holidays/countries/aruba.py new file mode 100644 index 00000000..9885017c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/aruba.py @@ -0,0 +1,159 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SUN_TO_PREV_SAT, + SUN_TO_NEXT_MON, +) + + +class Aruba(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Aruba holidays. + + References: + * [AB 2013 no. 14](https://web.archive.org/web/20250212184919/https://cuatro.sim-cdn.nl/arubaoverheid2858bd/uploads/ab2013no.14_0.pdf?cb=WDbZKYCl) + * [Holidays List (English)]( https://web.archive.org/web/20230808172049/https://www.government.aw/information-public-services/hiring-people_47940/item/holidays_43823.html) + * [Holidays List (Dutch)](https://web.archive.org/web/20231208145916/https://www.overheid.aw/informatie-dienstverlening/ondernemen-en-werken-subthemas_46970/item/feestdagen_37375.html) + * [Holidays List (Papiamento)](https://web.archive.org/web/20231202011228/https://www.gobierno.aw/informacion-tocante-servicio/haci-negoshi-y-traha-sub-topics_47789/item/dia-di-fiesta_41242.html) + * [National Holidays & Celebrations](https://web.archive.org/web/20250210000132/https://www.visitaruba.com/about-aruba/national-holidays-and-celebrations/) + * + * + * + """ + + country = "AW" + default_language = "pap_AW" + supported_languages = ("en_US", "nl", "pap_AW", "uk") + # The Netherlands Antilles was established on December 15th, 1954. + start_year = 1955 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Aña Nobo. + # Status: In-Use. + + # New Year's Day. + self._add_new_years_day(tr("Aña Nobo")) + + # Dia Di Betico. + # Status: In-Use. + # Started in 1989. + + if self._year >= 1989: + # Betico Day. + self._add_holiday_jan_25(tr("Dia di Betico")) + + # Dialuna prome cu diaranson di shinish. + # Status: In-Use. + # Starts as a public holiday from 1956 onwards. + # Event cancelled but remain a holiday in 2021. + # Have its name changed from 2023 onwards. + + if self._year >= 1956: + self._add_ash_monday( + # Carnival Monday. + tr("Dialuna despues di Carnaval Grandi") + if self._year <= 2022 + # Monday before Ash Wednesday. + else tr("Dialuna prome cu diaranson di shinish") + ) + + # Dia di Himno y Bandera. + # Status: In-Use. + # Started in 1976. + + if self._year >= 1976: + # National Anthem and Flag Day. + self._add_holiday_mar_18(tr("Dia di Himno y Bandera")) + + # Bierna Santo. + # Status: In-Use. + + # Good Friday. + self._add_good_friday(tr("Bierna Santo")) + + # Di dos dia di Pasco di Resureccion. + # Status: In-Use. + + # Easter Monday. + self._add_easter_monday(tr("Di dos dia di Pasco di Resureccion")) + + # Dia di Labor/Dia di Obrero. + # Status: In-Use. + # If fall on Sunday, then this will be move to next working day. + # This is placed here before King's/Queen's Day for _move_holiday logic. + + self._move_holiday( + # Labor Day. + self._add_labor_day(tr("Dia di Obrero")), + rule=SUN_TO_NEXT_MON if self._year >= 1980 else MON_TO_NEXT_TUE + SUN_TO_NEXT_MON, + ) + + # Aña di La Reina/Aña di Rey/Dia di Rey. + # Status: In-Use. + # Started under Queen Wilhelmina in 1891. + # Queen Beatrix kept Queen Juliana's Birthday after her coronation. + # Switched to Aña di Rey in 2014 for King Willem-Alexander. + # Have its name changed again to Dia di Rey from 2021 onwards. + + name = ( + # King's Day. + tr("Dia di Rey") + if self._year >= 2021 + else ( + tr("Aña di Rey") # King's Day. + if self._year >= 2014 + else tr("Aña di La Reina") # Queen's Day. + ) + ) + self._move_holiday( + self._add_holiday_apr_27(name) + if self._year >= 2014 + else self._add_holiday_apr_30(name), + rule=SUN_TO_PREV_SAT if self._year >= 1980 else SUN_TO_NEXT_MON, + ) + + # Dia di Asuncion. + # Status: In-Use. + + # Ascension Day. + self._add_ascension_thursday(tr("Dia di Asuncion")) + + # Pasco di Nacemento. + # Status: In-Use. + + # Christmas Day. + self._add_christmas_day(tr("Pasco di Nacemento")) + + # Di dos dia di Pasco di Nacemento. + # Status: In-Use. + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Di dos dia di Pasco di Nacemento")) + + +class AW(Aruba): + pass + + +class ABW(Aruba): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/australia.py b/.venv/lib/python3.12/site-packages/holidays/countries/australia.py new file mode 100644 index 00000000..e958ef55 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/australia.py @@ -0,0 +1,1010 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, APR, JUN, AUG, SEP, OCT, DEC +from holidays.constants import BANK, HALF_DAY, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SUN_TO_NEXT_MON, + SUN_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Australia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Australia holidays. + + References: + * + * [ACT Holidays Act 1958](https://web.archive.org/web/20250322061953/https://www.legislation.act.gov.au/a/1958-19/) + * [ACT 2013-2023](https://web.archive.org/web/20240401072340/https://www.cmtedd.act.gov.au/archived-content/holidays/previous-years) + * [NSW Banks and Bank Holidays Act 1912](https://web.archive.org/web/20241107225523/https://legislation.nsw.gov.au/view/html/repealed/current/act-1912-043) + * [NSW Public Holidays Act 2010](https://web.archive.org/web/20250316173922/https://legislation.nsw.gov.au/view/html/inforce/current/act-2010-115) + * [NT Public Holidays Act 1981](https://web.archive.org/web/20250315072128/https://legislation.nt.gov.au/api/sitecore/Act/PDF?id=12145) + * [QLD Holidays Act 1983](https://web.archive.org/web/20250404230918/https://www.legislation.qld.gov.au/view/html/inforce/current/act-1983-018) + * [QLD 2013-2028](https://web.archive.org/web/20150703042947/http://www.qld.gov.au/recreation/travel/holidays/public/) + * [SA Holidays Act 1910](https://web.archive.org/web/20250420203417/https://www.legislation.sa.gov.au/LZ/C/A/HOLIDAYS%20ACT%201910.aspx) + * [SA Public Holidays Act 2023](https://web.archive.org/web/20250429092113/https://www.legislation.sa.gov.au/lz?path=/C/A/Public%20Holidays%20Act%202023) + * [SA 2023-2024](https://web.archive.org/web/20250404084235/https://www.safework.sa.gov.au/resources/public-holidays) + * [SA 2007-2021](https://web.archive.org/web/20240610084716/https://www.safework.sa.gov.au/__data/assets/pdf_file/0007/235474/Public-Holidays-since-2007.pdf) + * [TAS Statutory Holidays Act 2000](https://web.archive.org/web/20250423095807/https://www.legislation.tas.gov.au/view/html/inforce/current/act-2000-096) + * [VIC Public Holidays Act 1993](https://web.archive.org/web/20250212090816/https://www.legislation.vic.gov.au/in-force/acts/public-holidays-act-1993/027) + * [VIC Minister appointment](https://web.archive.org/web/20240328142238/https://www.gazette.vic.gov.au/gazette/Gazettes2015/GG2015S229.pdf) + * [VIC 2018-2024](https://web.archive.org/web/20250422235530/https://business.vic.gov.au/business-information/public-holidays) + * [WA Public and Bank Holidays Act 1972](https://web.archive.org/web/20241106220940/https://www.legislation.wa.gov.au/legislation/statutes.nsf/law_a639.html) + * [WA 2019-2023](https://web.archive.org/web/20240805123535/https://www.commerce.wa.gov.au/labour-relations/previous-years-public-holiday-dates) + """ + + country = "AU" + default_language = "en_AU" + # %s (observed). + observed_label = tr("%s (observed)") + start_year = 1801 + # fmt: off + subdivisions = ( + "ACT", # Australian Capital Territory. + "NSW", # New South Wales. + "NT", # Northern Territory. + "QLD", # Queensland. + "SA", # South Australia. + "TAS", # Tasmania. + "VIC", # Victoria. + "WA", # Western Australia. + ) + # fmt: on + subdivisions_aliases = { + "Australian Capital Territory": "ACT", + "New South Wales": "NSW", + "Northern Territory": "NT", + "Queensland": "QLD", + "South Australia": "SA", + "Tasmania": "TAS", + "Victoria": "VIC", + "Western Australia": "WA", + } + supported_categories = (BANK, HALF_DAY, PUBLIC) + supported_languages = ("en_AU", "en_US", "th") + + @property + def sovereign_birthday(self) -> str: + """Sovereign's birthday holiday name.""" + return ( + # King's Birthday. + tr("King's Birthday") + if 1902 <= self._year <= 1951 or self._year >= 2023 + # Queen's Birthday. + else tr("Queen's Birthday") + ) + + @property + def australia_day(self) -> str: + """Australia Day holiday name.""" + return ( + # Australia Day. + tr("Australia Day") + if self._year >= 1935 + # Anniversary Day. + else tr("Anniversary Day") + ) + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, AustraliaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Sovereign's Birthday. + if 1902 <= self._year <= 1935: + if self._year >= 1912: + self._add_holiday_jun_3(self.sovereign_birthday) # George V + else: + self._add_holiday_nov_9(self.sovereign_birthday) # Edward VII + + if self.subdiv: + return None + + # Common holidays. + + # New Year's Day. + self._add_new_years_day(tr("New Year's Day")) + + # Australia Day. + if self._year >= 1935: + self._add_holiday_jan_26(self.australia_day) + + if self._year >= 1921: + # ANZAC Day. + self._add_anzac_day(tr("ANZAC Day")) + + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")) + + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")) + + def _populate_subdiv_act_public_holidays(self): + # New Year's Day. + # 1959-1992: SUN - move to MON. + # 1993-2014: SAT, SUN - move to MON. + # from 2015: SAT, SUN - add MON. + + # New Year's Day. + name = tr("New Year's Day") + if self._year >= 2015: + self._add_observed(self._add_new_years_day(name)) + elif self._year >= 1959: + jan_1 = (JAN, 1) + if self._is_sunday(jan_1) or (self._year >= 1993 and self._is_saturday(jan_1)): + self._add_holiday_1st_mon_from_jan_1(name) + else: + self._add_new_years_day(name) + else: + self._add_new_years_day(name) + + # Australia Day. + # 1959-1989: not MON - move to MON. + # from 1990: SAT, SUN - move to MON. + + # Australia Day. + if self._year >= 1888: + if 1959 <= self._year <= 1989 or (self._year >= 1990 and self._is_weekend(JAN, 26)): + self._add_holiday_1st_mon_from_jan_26(self.australia_day) + else: + self._add_holiday_jan_26(self.australia_day) + + if self._year >= 1913: + # Canberra Day. + name = tr("Canberra Day") + if self._year <= 1958 or self._year == 2012: + self._add_holiday_mar_12(name) + elif self._year <= 2007: + self._add_holiday_3rd_mon_of_mar(name) + else: + self._add_holiday_2nd_mon_of_mar(name) + + # Easter Saturday. + self._add_holy_saturday(tr("Easter Saturday")) + + if self._year >= 2016: + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + # ANZAC Day. + # from 1959: SUN - move to MON. + + if self._year >= 1921: + # ANZAC Day. + name = tr("ANZAC Day") + if self._year >= 1959 and self._is_sunday(APR, 25): + self._add_holiday_1st_mon_from_apr_25(name) + else: + self._add_anzac_day(name) + + if self._year >= 2018: + # Reconciliation Day. + self._add_holiday_1st_mon_from_may_27(tr("Reconciliation Day")) + + # Sovereign's Birthday. + if self._year >= 1936: + self._add_holiday_2nd_mon_of_jun(self.sovereign_birthday) + + # Family & Community Day. + # (First Monday of the September/October school holidays; + # moved to the second Monday if this falls on Labour day). + + if 2010 <= self._year <= 2017: + fc_dates = { + 2010: (SEP, 26), + 2011: (OCT, 10), + 2012: (OCT, 8), + 2013: (SEP, 30), + 2014: (SEP, 29), + 2015: (SEP, 28), + 2016: (SEP, 26), + 2017: (SEP, 25), + } + # Family & Community Day. + self._add_holiday(tr("Family & Community Day"), fc_dates[self._year]) + + # Labor Day. + self._add_holiday_1st_mon_of_oct(tr("Labour Day")) + + # Christmas Day. + # 1958-1991: SUN - to MON. + # 1992-2013: SAT, SUN - to MON. + # from 2014: SAT - add MON, SUN - add TUE. + + # Christmas Day. + name = tr("Christmas Day") + if self._year >= 2014: + self._add_observed(self._add_christmas_day(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + elif self._year >= 1958: + dec_25 = (DEC, 25) + if self._is_sunday(dec_25) or (self._year >= 1992 and self._is_saturday(dec_25)): + self._add_holiday_1st_mon_from_dec_25(name) + else: + self._add_christmas_day(name) + else: + self._add_christmas_day(name) + + # Boxing Day. + # 1958-1991: SUN - to MON, MON - to TUE. + # 1992-2013: SAT - to MON, SUN - to TUE, MON - to TUE. + # from 2014: SAT - add MON, SUN - add TUE. + + # Boxing Day. + name = tr("Boxing Day") + if self._year >= 2014: + self._add_observed(self._add_christmas_day_two(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + elif self._year >= 1958: + dec_26 = (DEC, 26) + if self._year >= 1992: + if self._is_saturday(dec_26): + self._add_holiday_1st_mon_from_dec_26(name) + elif self._is_sunday(dec_26) or self._is_monday(dec_26): + self._add_holiday_1st_tue_from_dec_26(name) + else: + self._add_christmas_day_two(name) + else: + if self._is_sunday(dec_26): + self._add_holiday_1st_mon_from_dec_26(name) + elif self._is_monday(dec_26): + self._add_holiday_1st_tue_from_dec_26(name) + else: + self._add_christmas_day_two(name) + else: + self._add_christmas_day_two(name) + + def _populate_subdiv_act_bank_holidays(self): + # Bank Holiday. + self._add_holiday_1st_mon_of_aug(tr("Bank Holiday")) + + def _populate_subdiv_nsw_public_holidays(self): + # New Year's Day. + # 1912-2010: SUN - add MON. + # from 2011: SAT, SUN - add MON. + + self._add_observed( + # New Year's Day. + self._add_new_years_day(tr("New Year's Day")), + rule=SAT_SUN_TO_NEXT_MON if self._year >= 2011 else SUN_TO_NEXT_MON, + ) + + # Australia Day. + # 1912-2010: SUN - add MON. + # from 2011: SAT, SUN - to MON. + + if self._year >= 1888: + name = ( + # Australia Day. + tr("Australia Day") + if self._year >= 1946 + # Anniversary Day. + else tr("Anniversary Day") + ) + if self._year >= 2011: + if self._is_weekend(JAN, 26): + self._add_holiday_1st_mon_from_jan_26(name) + else: + self._add_holiday_jan_26(name) + else: + self._add_observed(self._add_holiday_jan_26(name), rule=SUN_TO_NEXT_MON) + + # Easter Saturday. + self._add_holy_saturday(tr("Easter Saturday")) + + if self._year >= 2011: + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + # ANZAC Day. + # 1912-2010: SUN - add MON. + # from 2011: normal. + + if self._year >= 1921: + # ANZAC Day. + apr_25 = self._add_anzac_day(tr("ANZAC Day")) + if self._year <= 2010: + self._add_observed(apr_25) + + # Labor Day. + self._add_holiday_1st_mon_of_oct(tr("Labour Day")) + + # Sovereign's Birthday. + if self._year >= 1936: + self._add_holiday_2nd_mon_of_jun(self.sovereign_birthday) + + if 1912 <= self._year <= 2010: + # Bank Holiday. + self._add_holiday_1st_mon_of_aug(tr("Bank Holiday")) + + # Christmas Day. + # 1912-2010: SUN - add TUE. + # from 2011: SAT - add MON, SUN - add TUE. + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE if self._year >= 2011 else SUN_TO_NEXT_TUE, + ) + + # Boxing Day. + # 1912-2010: SUN - add MON. + # from 2011: SAT - add MON, SUN - add TUE. + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE if self._year >= 2011 else SUN_TO_NEXT_MON, + ) + + def _populate_subdiv_nsw_bank_holidays(self): + if self._year >= 2011: + # Bank Holiday. + self._add_holiday_1st_mon_of_aug(tr("Bank Holiday")) + + def _populate_subdiv_nt_public_holidays(self): + # New Year's Day. + # 1982-2016: SAT, SUN - move to MON. + # from 2017: SAT, SUN - add MON. + + # New Year's Day. + name = tr("New Year's Day") + if self._year >= 2017: + self._add_observed(self._add_new_years_day(name)) + elif self._year >= 1982 and self._is_weekend(JAN, 1): + self._add_holiday_1st_mon_from_jan_1(name) + else: + self._add_new_years_day(name) + + # Australia Day. + # from 1982: SAT, SUN - move to MON. + + # Australia Day. + if self._year >= 1888: + if self._year >= 1982 and self._is_weekend(JAN, 26): + self._add_holiday_1st_mon_from_jan_26(self.australia_day) + else: + self._add_holiday_jan_26(self.australia_day) + + # Easter Saturday. + self._add_holy_saturday(tr("Easter Saturday")) + + if self._year >= 2024: + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + # ANZAC Day. + # from 1982: SUN - to MON. + + if self._year >= 1921: + # ANZAC Day. + name = tr("ANZAC Day") + if self._year >= 1982 and self._is_sunday(APR, 25): + self._add_holiday_1st_mon_from_apr_25(name) + else: + self._add_anzac_day(name) + + # May Day. + self._add_holiday_1st_mon_of_may(tr("May Day")) + + # Sovereign's Birthday. + if self._year >= 1936: + self._add_holiday_2nd_mon_of_jun(self.sovereign_birthday) + + # Picnic Day. + self._add_holiday_1st_mon_of_aug(tr("Picnic Day")) + + # Christmas Day. + # 1981-2015: SAT, SUN - to MON. + # from 2016: SAT, SUN - add MON. + + # Christmas Day. + name = tr("Christmas Day") + if self._year >= 2016: + self._add_observed(self._add_christmas_day(name)) + elif self._year >= 1981 and self._is_weekend(DEC, 25): + self._add_holiday_1st_mon_from_dec_25(name) + else: + self._add_christmas_day(name) + + # Boxing Day. + # 1981-2022: SAT - to MON, SUN - to TUE, MON - to TUE. + # from 2023: SAT - add MON, SUN - add TUE, MON - add TUE. + + # Boxing Day. + name = tr("Boxing Day") + if self._year >= 2023: + self._add_observed( + self._add_christmas_day_two(name), rule=SAT_SUN_TO_NEXT_MON_TUE + MON_TO_NEXT_TUE + ) + elif self._year >= 1981: + dec_26 = (DEC, 26) + if self._is_saturday(dec_26): + self._add_holiday_1st_mon_from_dec_26(name) + elif self._is_sunday(dec_26) or self._is_monday(dec_26): + self._add_holiday_1st_tue_from_dec_26(name) + else: + self._add_christmas_day_two(name) + else: + self._add_christmas_day_two(name) + + def _populate_subdiv_nt_half_day_holidays(self): + if self._year >= 2016: + # %s (from 7pm). + begin_time_label = self.tr("%s (from 7pm)") + + # Christmas Eve. + self._add_christmas_eve(begin_time_label % self.tr("Christmas Eve")) + + # New Year's Eve. + self._add_new_years_eve(begin_time_label % self.tr("New Year's Eve")) + + def _populate_subdiv_qld_public_holidays(self): + # New Year's Day. + # 1984-2011: SUN - move to MON. + # from 2012: SAT, SUN - add MON. + + # New Year's Day. + name = tr("New Year's Day") + if self._year >= 2012: + self._add_observed(self._add_new_years_day(name)) + elif self._year >= 1984 and self._is_sunday(JAN, 1): + self._add_holiday_1st_mon_from_jan_1(name) + else: + self._add_new_years_day(name) + + # Australia Day. + # 1984-1995: not MON - move to MON. + # from 1996: SAT, SUN - move to MON. + + # Australia Day. + if self._year >= 1888: + if 1984 <= self._year <= 1995 or (self._year >= 1996 and self._is_weekend(JAN, 26)): + self._add_holiday_1st_mon_from_jan_26(self.australia_day) + else: + self._add_holiday_jan_26(self.australia_day) + + # Easter Saturday. + self._add_holy_saturday(tr("Easter Saturday")) + + if self._year >= 2017: + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + # ANZAC Day. + # from 1984: SUN - move to MON. + + if self._year >= 1921: + # ANZAC Day. + name = tr("ANZAC Day") + if self._year >= 1984 and self._is_sunday(APR, 25): + self._add_holiday_1st_mon_from_apr_25(name) + else: + self._add_anzac_day(name) + + # Labor Day. + name = tr("Labour Day") + if 2013 <= self._year <= 2015: + self._add_holiday_1st_mon_of_oct(name) + else: + self._add_holiday_1st_mon_of_may(name) + + # Sovereign's Birthday. + if self._year >= 1936: + if self._year <= 2015 and self._year != 2012: + self._add_holiday_2nd_mon_of_jun(self.sovereign_birthday) + else: + self._add_holiday_1st_mon_of_oct(self.sovereign_birthday) + + # The Royal Queensland Show (Ekka). + # The Show starts on the first Friday of August - providing this is + # not prior to the 5th - in which case it will begin on the second + # Friday. The Wednesday during the show is a public holiday. + ekka_dates = { + 2020: (AUG, 14), + 2021: (OCT, 29), + } + # The Royal Queensland Show. + name = tr("The Royal Queensland Show") + if dt := ekka_dates.get(self._year): + self._add_holiday(name, dt) + else: + # [1st FRI after Aug 5] + 5 days = [1st WED after Aug 10] + self._add_holiday_1st_wed_from_aug_10(name) + + # Christmas Day. + # 1984-2010: SUN - to MON. + # from 2011: SAT - add MON, SUN - add TUE. + + # Christmas Day. + name = tr("Christmas Day") + if self._year >= 2011: + self._add_observed(self._add_christmas_day(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + elif self._year >= 1984 and self._is_sunday(DEC, 25): + self._add_holiday_1st_mon_from_dec_25(name) + else: + self._add_christmas_day(name) + + # Boxing Day. + # 1984-1910: SUN - to MON, MON - to TUE. + # from 2011: SAT - add MON, SUN - add TUE. + + # Boxing Day. + name = tr("Boxing Day") + if self._year >= 2011: + self._add_observed(self._add_christmas_day_two(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + elif self._year >= 1984: + dec_26 = (DEC, 26) + if self._is_sunday(dec_26): + self._add_holiday_1st_mon_from_dec_26(name) + elif self._is_monday(dec_26): + self._add_holiday_1st_tue_from_dec_26(name) + else: + self._add_christmas_day_two(name) + else: + self._add_christmas_day_two(name) + + def _populate_subdiv_sa_public_holidays(self): + # New Year's Day. + # 1984-2003: SAT, SUN - move to MON. + # 2004-2023: SAT - move to MON, SUN - add MON. + # from 2024: SAT, SUN - add MON. + + # New Year's Day. + name = tr("New Year's Day") + jan_1 = (JAN, 1) + if self._year >= 2024: + self._add_observed(self._add_new_years_day(name)) + elif self._year >= 2004: + if self._is_saturday(jan_1): + self._add_holiday_1st_mon_from_jan_1(name) + else: + self._add_observed(self._add_new_years_day(name), rule=SUN_TO_NEXT_MON) + elif self._year >= 1984 and self._is_weekend(jan_1): + self._add_holiday_1st_mon_from_jan_1(name) + else: + self._add_new_years_day(name) + + # Australia Day. + # 1984-1993: not MON - move to MON. + # 1994-2003: SAT, SUN - move to MON. + # 2004-2023: SAT - move to MON, SUN - add MON. + # from 2024: SAT, SUN - move to MON. + + if self._year >= 1935: + # Australia Day. + name = tr("Australia Day") + jan_26 = (JAN, 26) + if 1994 <= self._year <= 2003 or self._year >= 2024: + if self._is_weekend(jan_26): + self._add_holiday_1st_mon_from_jan_26(name) + else: + self._add_holiday_jan_26(name) + elif self._year >= 2004: + if self._is_saturday(jan_26): + self._add_holiday_1st_mon_from_jan_26(name) + else: + self._add_observed(self._add_holiday_jan_26(name), rule=SUN_TO_NEXT_MON) + elif self._year >= 1984: + self._add_holiday_1st_mon_from_jan_26(name) + else: + self._add_holiday_jan_26(name) + + # Adelaide Cup Day. + # First observed as Public Holidays in 1973: https://racingsa.com.au/blog/2020/03/06/2380/a-little-adelaide-cup-history + # 2006-2023: changed each year by SA Government Proclamation from the 3rd Monday in May + # to the 2nd Monday in March. + # from 2024: changed to the 2nd Monday in March officially. + + # Adelaide Cup Day. + name = tr("Adelaide Cup Day") + if self._year >= 2006: + self._add_holiday_2nd_mon_of_mar(name) + elif self._year >= 1973: + self._add_holiday_3rd_mon_of_may(name) + + # Easter Saturday. + self._add_holy_saturday(tr("Easter Saturday")) + + if self._year >= 2024: + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + if self._year >= 1921: + # ANZAC Day. + apr_25 = self._add_anzac_day(tr("ANZAC Day")) + if self._year <= 2023: + self._add_observed(apr_25, rule=SUN_TO_NEXT_MON) + + # Sovereign's Birthday. + if self._year >= 1936: + self._add_holiday_2nd_mon_of_jun(self.sovereign_birthday) + + # Labor Day. + self._add_holiday_1st_mon_of_oct(tr("Labour Day")) + + # Proclamation Day. + # 1984-1992: SAT, SUN - move to MON. + # 1993-2002: SAT - to MON, SUN - to TUE, MON - to TUE. + # 2003-2023: SAT - to MON, SUN - add TUE, MON - add TUE. + # from 2024: SAT - add MON, SUN - add TUE, MON - add TUE. + # (Placed before Christmas Day for proper observed calculation). + + # Proclamation Day. + name = tr("Proclamation Day") + dec_26 = (DEC, 26) + if self._year >= 2024: + self._add_observed( + self._add_christmas_day_two(name), rule=SAT_SUN_TO_NEXT_MON_TUE + MON_TO_NEXT_TUE + ) + elif self._year >= 2003: + if self._is_saturday(dec_26): + self._add_holiday_1st_mon_from_dec_26(name) + else: + self._add_observed( + self._add_christmas_day_two(name), rule=SUN_TO_NEXT_TUE + MON_TO_NEXT_TUE + ) + elif self._year >= 1993: + if self._is_saturday(dec_26): + self._add_holiday_1st_mon_from_dec_26(name) + elif self._is_sunday(dec_26) or self._is_monday(dec_26): + self._add_holiday_1st_tue_from_dec_26(name) + else: + self._add_christmas_day_two(name) + elif self._year >= 1984 and self._is_weekend(dec_26): + self._add_holiday_1st_mon_from_dec_26(name) + else: + self._add_christmas_day_two(name) + + # Christmas Day. + # 1984-2002: SAT, SUN - move to MON. + # 2003-2023: SAT - move to MON, SUN - add MON. + # from 2024: SAT, SUN - add MON. + + # Christmas Day. + name = tr("Christmas Day") + dec_25 = (DEC, 25) + if self._year >= 2024: + self._add_observed(self._add_christmas_day(name)) + elif self._year >= 2003: + if self._is_saturday(dec_25): + self._add_holiday_1st_mon_from_dec_25(name) + else: + self._add_observed(self._add_christmas_day(name), rule=SUN_TO_NEXT_MON) + elif self._year >= 1984 and self._is_weekend(dec_25): + self._add_holiday_1st_mon_from_dec_25(name) + else: + self._add_christmas_day(name) + + def _populate_subdiv_sa_half_day_holidays(self): + if self._year >= 2012: + # %s (from 7pm). + begin_time_label = self.tr("%s (from 7pm)") + + # Christmas Eve. + self._add_christmas_eve(begin_time_label % self.tr("Christmas Eve")) + + # New Year's Eve. + self._add_new_years_eve(begin_time_label % self.tr("New Year's Eve")) + + def _populate_subdiv_tas_public_holidays(self): + # New Year's Day. + # from 2001: SAT, SUN - move to MON. + + # New Year's Day. + name = tr("New Year's Day") + if self._year >= 2001 and self._is_weekend(JAN, 1): + self._add_holiday_1st_mon_from_jan_1(name) + else: + self._add_new_years_day(name) + + # Australia Day. + # from 2001: SAT, SUN - move to MON. + + # Australia Day. + if self._year >= 1888: + if self._year >= 2001 and self._is_weekend(JAN, 26): + self._add_holiday_1st_mon_from_jan_26(self.australia_day) + else: + self._add_holiday_jan_26(self.australia_day) + + # Eight Hours Day. + self._add_holiday_2nd_mon_of_mar(tr("Eight Hours Day")) + + if self._year <= 2010: + # Easter Tuesday. + self._add_easter_tuesday(tr("Easter Tuesday")) + + if self._year >= 1921: + # ANZAC Day. + self._add_anzac_day(tr("ANZAC Day")) + + # Sovereign's Birthday. + if self._year >= 1936: + self._add_holiday_2nd_mon_of_jun(self.sovereign_birthday) + + # Christmas Day. + # 2000-2009: SAT - to MON, SUN - to TUE. + # from 2010: SAT - add MON, SUN - add TUE. + + # Christmas Day. + name = tr("Christmas Day") + if self._year >= 2010: + self._add_observed(self._add_christmas_day(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + elif self._year >= 2000: + dec_25 = (DEC, 25) + if self._is_saturday(dec_25): + self._add_holiday_1st_mon_from_dec_25(name) + elif self._is_sunday(dec_25): + self._add_holiday_1st_tue_from_dec_25(name) + else: + self._add_christmas_day(name) + else: + self._add_christmas_day(name) + + # Boxing Day. + # from 2000: SAT - to MON, SUN - to TUE. + + # Boxing Day. + name = tr("Boxing Day") + if self._year >= 2000: + dec_26 = (DEC, 26) + if self._is_saturday(dec_26): + self._add_holiday_1st_mon_from_dec_26(name) + elif self._is_sunday(dec_26): + self._add_holiday_1st_tue_from_dec_26(name) + else: + self._add_christmas_day_two(name) + else: + self._add_christmas_day_two(name) + + def _populate_subdiv_vic_public_holidays(self): + # New Year's Day. + # 1994-1997: SUN - add MON. + # 1998-2008: SUN - move to MON. + # from 2009: SAT, SUN - add MON. + + # New Year's Day. + name = tr("New Year's Day") + if self._year >= 2009: + self._add_observed(self._add_new_years_day(name)) + elif self._year >= 1998: + if self._is_sunday(JAN, 1): + self._add_holiday_1st_mon_from_jan_1(name) + else: + self._add_new_years_day(name) + elif self._year >= 1994: + self._add_observed(self._add_new_years_day(name), rule=SUN_TO_NEXT_MON) + else: + self._add_new_years_day(name) + + # Australia Day. + # from 2009: SAT, SUN - move to MON. + + # Australia Day. + if self._year >= 1888: + if self._year >= 2009 and self._is_weekend(JAN, 26): + self._add_holiday_1st_mon_from_jan_26(self.australia_day) + else: + self._add_holiday_jan_26(self.australia_day) + + # Labor Day. + self._add_holiday_2nd_mon_of_mar(tr("Labour Day")) + + if self._year >= 2003: + # Easter Saturday. + self._add_holy_saturday(tr("Easter Saturday")) + + if self._year >= 2016: + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + if self._year >= 1921: + # ANZAC Day. + self._add_anzac_day(tr("ANZAC Day")) + + # Sovereign's Birthday. + if self._year >= 1936: + self._add_holiday_2nd_mon_of_jun(self.sovereign_birthday) + + if self._year >= 2015: + grand_final_dates = { + 2015: (OCT, 2), + 2016: (SEP, 30), + # Rescheduled due to COVID-19. + 2020: (OCT, 23), + } + # Grand Final Day. + name = tr("Grand Final Day") + if dt := grand_final_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_1_day_prior_last_sat_of_sep(name) + + if self._year >= 2009: + # Melbourne Cup Day. + self._add_holiday_1st_tue_of_nov(tr("Melbourne Cup Day")) + + # Christmas Day. + # 2008-2018: SAT - to MON, SUN - to TUE. + # from 2019: SAT - add MON, SUN - add TUE. + + # Christmas Day. + name = tr("Christmas Day") + if self._year >= 2019: + self._add_observed(self._add_christmas_day(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + elif self._year >= 2000: + dec_25 = (DEC, 25) + if self._is_saturday(dec_25): + self._add_holiday_1st_mon_from_dec_25(name) + elif self._is_sunday(dec_25): + self._add_holiday_1st_tue_from_dec_25(name) + else: + self._add_christmas_day(name) + else: + self._add_christmas_day(name) + + # Boxing Day. + # 1994-2008: SUN - to MON. + # from 2009: SAT - add MON, SUN - add TUE. + + # Boxing Day. + name = tr("Boxing Day") + if self._year >= 2009: + self._add_observed(self._add_christmas_day_two(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + elif self._year >= 1994 and self._is_sunday(DEC, 26): + self._add_holiday_1st_tue_from_dec_26(name) + else: + self._add_christmas_day_two(name) + + def _populate_subdiv_wa_public_holidays(self): + # New Year's Day. + # from 1973: SAT, SUN - add MON. + + # New Year's Day. + jan_1 = self._add_new_years_day(tr("New Year's Day")) + if self._year >= 1973: + self._add_observed(jan_1) + + # Australia Day. + # 1973-1993: not MON - move to MON. + # from 1994: SAT, SUN - move to MON. + + # Australia Day. + if self._year >= 1888: + if self._year >= 1994: + if self._is_weekend(JAN, 26): + self._add_holiday_1st_mon_from_jan_26(self.australia_day) + else: + self._add_holiday_jan_26(self.australia_day) + elif self._year >= 1973: + self._add_holiday_1st_mon_from_jan_26(self.australia_day) + else: + self._add_holiday_jan_26(self.australia_day) + + # Labor Day. + self._add_holiday_1st_mon_of_mar(tr("Labour Day")) + + if self._year >= 2022: + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + if self._year >= 1921: + # ANZAC Day. + apr_25 = self._add_anzac_day(tr("ANZAC Day")) + if self._year >= 1973: + self._add_observed(apr_25) + + if self._year >= 1833: + self._add_holiday_1st_mon_of_jun( + # Western Australia Day. + tr("Western Australia Day") + if self._year >= 2012 + # Foundation Day. + else tr("Foundation Day") + ) + + # Sovereign's Birthday. + if self._year >= 1936: + if self._year >= 1984: + # Celebration Day for the Anniversary of the Birthday of the Reigning Sovereign + # to be appointed for each year by proclamation published in the Government Gazette + sovereign_birthday_dates = { + 2011: (OCT, 28), + 2012: (OCT, 1), + 2024: (SEP, 23), + } + if dt := sovereign_birthday_dates.get(self._year): + self._add_holiday(self.sovereign_birthday, dt) + else: + self._add_holiday_last_mon_of_sep(self.sovereign_birthday) + else: + self._add_holiday_2nd_mon_of_oct(self.sovereign_birthday) + + # Boxing Day. + # 1972-1975: SAT - add MON, SUN - add TUE. + # from 1976: SAT - add MON, SUN - add TUE, MON - add TUE. + # (Placed before Christmas Day for proper observed calculation). + + # Boxing Day. + dec_26 = self._add_christmas_day_two(tr("Boxing Day")) + if self._year >= 1972: + self._add_observed( + dec_26, + rule=SAT_SUN_TO_NEXT_MON_TUE + MON_TO_NEXT_TUE + if self._year >= 1976 + else SAT_SUN_TO_NEXT_MON_TUE, + ) + + # Christmas Day. + # from 1972: SAT, SUN - add MON. + + # Christmas Day. + dec_25 = self._add_christmas_day(tr("Christmas Day")) + if self._year >= 1972: + self._add_observed(dec_25) + + +class AU(Australia): + pass + + +class AUS(Australia): + pass + + +class AustraliaStaticHolidays: + # Special public holiday. + special_public_holiday = tr("Special public holiday") + + special_public_holidays = { + # National Day of Mourning for Queen Elizabeth II. + 2022: (SEP, 22, tr("National Day of Mourning for Queen Elizabeth II")), + } + + special_act_public_holidays = { + # Declared public holiday. + 2020: (APR, 20, tr("Declared public holiday")), + # Additional public holiday. + 2021: (APR, 25, tr("Additional public holiday")), + } + + special_qld_public_holidays = { + # Queen's Diamond Jubilee. + 2012: (JUN, 11, tr("Queen's Diamond Jubilee")), + } + + special_qld_public_holidays_observed = { + # Christmas Day. + 2010: (DEC, 28, tr("Christmas Day")), + # New Year's Day. + 2011: (JAN, 3, tr("New Year's Day")), + } + + special_wa_public_holidays = { + # In 2011 both ANZAC Day and Easter Monday fell on Monday 25 April. + 2011: (APR, 26, special_public_holiday), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/austria.py b/.venv/lib/python3.12/site-packages/holidays/countries/austria.py new file mode 100644 index 00000000..0cd9a7d4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/austria.py @@ -0,0 +1,171 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import BANK, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Austria(HolidayBase, ChristianHolidays, InternationalHolidays): + """Austria holidays.""" + + country = "AT" + default_language = "de" + subdivisions = ( + "1", # Burgenland. + "2", # Kärnten. + "3", # Niederösterreich. + "4", # Oberösterreich. + "5", # Salzburg. + "6", # Steiermark. + "7", # Tirol. + "8", # Vorarlberg. + "9", # Wien. + ) + subdivisions_aliases = { + "Burgenland": "1", + "Bgld": "1", + "B": "1", + "Kärnten": "2", + "Ktn": "2", + "K": "2", + "Niederösterreich": "3", + "NÖ": "3", + "N": "3", + "Oberösterreich": "4", + "OÖ": "4", + "O": "4", + "Salzburg": "5", + "Sbg": "5", + "S": "5", + "Steiermark": "6", + "Stmk": "6", + "St": "6", + "Tirol": "7", + "T": "7", + "Vorarlberg": "8", + "Vbg": "8", + "V": "8", + "Wien": "9", + "W": "9", + } + supported_categories = (BANK, PUBLIC) + supported_languages = ("de", "en_US", "uk") + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Neujahr")) + + # Epiphany. + self._add_epiphany_day(tr("Heilige Drei Könige")) + + # Easter Monday. + self._add_easter_monday(tr("Ostermontag")) + + # Labor Day. + self._add_labor_day(tr("Staatsfeiertag")) + + # Ascension Day. + self._add_ascension_thursday(tr("Christi Himmelfahrt")) + + # Whit Monday. + self._add_whit_monday(tr("Pfingstmontag")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Fronleichnam")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + # National Day. + national_day = tr("Nationalfeiertag") + if 1919 <= self._year <= 1934: + self._add_holiday_nov_12(national_day) + if self._year >= 1967: + self._add_holiday_oct_26(national_day) + + # All Saints' Day. + self._add_all_saints_day(tr("Allerheiligen")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + # Christmas Day. + self._add_christmas_day(tr("Christtag")) + + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Stefanitag")) + + def _populate_bank_holidays(self): + # Good Friday. + self._add_good_friday(tr("Karfreitag")) + + # Christmas Eve. + self._add_christmas_eve(tr("Heiliger Abend")) + + # New Year's Eve. + self._add_new_years_eve(tr("Silvester")) + + def _populate_subdiv_1_bank_holidays(self): + # Saint Martin's Day. + self._add_holiday_nov_11(tr("Hl. Martin")) + + def _populate_subdiv_2_bank_holidays(self): + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("Hl. Josef")) + + # 1920 Carinthian plebiscite. + self._add_holiday_oct_10(tr("Tag der Volksabstimmung")) + + def _populate_subdiv_3_bank_holidays(self): + # Saint Leopold's Day. + self._add_holiday_nov_15(tr("Hl. Leopold")) + + def _populate_subdiv_4_bank_holidays(self): + if self._year >= 2004: + # Saint Florian's Day. + self._add_holiday_may_4(tr("Hl. Florian")) + + def _populate_subdiv_5_bank_holidays(self): + # Saint Rupert's Day. + self._add_holiday_sep_24(tr("Hl. Rupert")) + + def _populate_subdiv_6_bank_holidays(self): + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("Hl. Josef")) + + def _populate_subdiv_7_bank_holidays(self): + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("Hl. Josef")) + + def _populate_subdiv_8_bank_holidays(self): + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("Hl. Josef")) + + def _populate_subdiv_9_bank_holidays(self): + # Saint Leopold's Day. + self._add_holiday_nov_15(tr("Hl. Leopold")) + + +class AT(Austria): + pass + + +class AUT(Austria): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/azerbaijan.py b/.venv/lib/python3.12/site-packages/holidays/countries/azerbaijan.py new file mode 100644 index 00000000..49d126b2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/azerbaijan.py @@ -0,0 +1,354 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import InternationalHolidays, IslamicHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + WORKDAY_TO_NEXT_WORKDAY, + SAT_SUN_TO_NEXT_WORKDAY, +) + + +class Azerbaijan(ObservedHolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays): + """Azerbaijan holidays. + + References: + * + * + * + """ + + country = "AZ" + default_language = "az" + # %s (estimated). + estimated_label = tr("%s (təxmini)") + # %s (observed). + observed_label = tr("%s (müşahidə olunur)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (müşahidə olunur, təxmini)") + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("az", "en_US", "uk") + start_year = 1990 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=AzerbaijanIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, AzerbaijanStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 2006) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + dts_non_observed = set() + dts_bairami = set() + + # New Year's Day. + name = tr("Yeni il bayramı") + dts_observed.add(self._add_new_years_day(name)) + if self._year >= 2006: + dts_observed.add(self._add_new_years_day_two(name)) + + if self._year >= 2000: + # Martyrs' Day. + dts_non_observed.add(self._add_holiday_jan_20(tr("Ümumxalq hüzn günü"))) + + # Women's Day. + dt = self._add_womens_day(tr("Qadınlar günü")) + if self._year != 2025: + dts_observed.add(dt) + + # Spring Festival. + name = tr("Novruz bayramı") + dts_observed.add(self._add_holiday_mar_20(name)) + dts_observed.add(self._add_holiday_mar_21(name)) + if self._year >= 2007: + dts_observed.add(self._add_holiday_mar_22(name)) + dts_observed.add(self._add_holiday_mar_23(name)) + dts_observed.add(self._add_holiday_mar_24(name)) + + dts_observed.add( + self._add_world_war_two_victory_day( + # Victory over Fascism Day. + tr("Faşizm üzərində qələbə günü"), + is_western=False, + ) + ) + + if self._year >= 1992: + dts_observed.add( + self._add_holiday_may_28( + # Independence Day. + tr("Müstəqillik Günü") + if self._year >= 2021 + # Republic Day. + else tr("Respublika Günü") + ) + ) + + if self._year >= 1997: + dts_observed.add( + # National Liberation Day. + self._add_holiday_jun_15(tr("Azərbaycan xalqının milli qurtuluş günü")) + ) + + if self._year >= 1992: + # Armed Forces Day. + name = tr("Azərbaycan Respublikasının Silahlı Qüvvələri günü") + if self._year <= 1997: + self._add_holiday_oct_9(name) + else: + dts_observed.add(self._add_holiday_jun_26(name)) + + if self._year <= 2005: + # Independence Day. + self._add_holiday_oct_18(tr("Milli Müstəqillik Günü")) + + if self._year >= 2021: + # Victory Day. + dts_observed.add(self._add_holiday_nov_8(tr("Zəfər Günü"))) + + if self._year >= 2010: + dts_observed.add( + # National Flag Day. + self._add_holiday_nov_9(tr("Azərbaycan Respublikasının Dövlət bayrağı günü")) + ) + + if self._year >= 1993: + # International Azerbaijanis Solidarity Day. + name = tr("Dünya azərbaycanlılarının həmrəyliyi günü") + self._add_new_years_eve(name) + self._add_observed(date(self._year - 1, DEC, 31), name) + + if self._year >= 1993: + # Eid al-Fitr. + name = tr("Ramazan bayrami") + dt = self._add_eid_al_fitr_day(name) + if self._year != 2025: + dts_bairami.update(dt) + if self._year >= 2006: + dts_bairami.update(self._add_eid_al_fitr_day_two(name)) + + # Eid al-Adha. + name = tr("Qurban bayrami") + dts_bairami.update(self._add_eid_al_adha_day(name)) + if self._year >= 2007: + dts_bairami.update(self._add_eid_al_adha_day_two(name)) + + # Article 105 of the Labor Code of the Republic of Azerbaijan states: + # 5. If interweekly rest days and holidays that are not considered working days overlap, + # that rest day is immediately transferred to the next working day. + if self.observed and self._year >= 2006: + self._populate_observed(dts_observed.union(dts_bairami)) + + bayrami_names = {self.tr("Ramazan bayrami"), self.tr("Qurban bayrami")} + # 6. If the holidays of Qurban and Ramadan coincide with another holiday + # that is not considered a working day, the next working day is considered a rest day. + for dt_observed in sorted(dts_bairami.difference(dts_non_observed)): + if len(dt_holidays := self.get_list(dt_observed)) == 1: + continue + for name in dt_holidays: + if name in bayrami_names: + self._add_observed(dt_observed, name, WORKDAY_TO_NEXT_WORKDAY) + + def _populate_workday_holidays(self): + if self._year >= 2021: + # Memorial Day. + self._add_holiday_sep_27(tr("Anım Günü")) + + if self._year >= 2006: + self._add_holiday_oct_18( + # Independence Restoration Day. + tr("Müstəqilliyin Bərpası Günü") + if self._year >= 2021 + # Independence Day. + else tr("Milli Müstəqillik Günü") + ) + + if self._year >= 1996: + # Constitution Day. + self._add_holiday_nov_12(tr("Konstitusiya Günü")) + + if self._year >= 1992: + # National Revival Day. + self._add_holiday_nov_17(tr("Milli Dirçəliş Günü")) + + +class AZ(Azerbaijan): + pass + + +class AZE(Azerbaijan): + pass + + +class AzerbaijanIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2002: (FEB, 21), + 2003: (FEB, 11), + 2004: (FEB, 1), + 2005: (JAN, 22), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 27), + 2010: (NOV, 16), + 2011: (NOV, 6), + 2012: (OCT, 25), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 2002: (DEC, 4), + 2003: (NOV, 25), + 2004: (NOV, 14), + 2005: (NOV, 3), + 2006: (OCT, 23), + 2007: (OCT, 12), + 2008: (SEP, 30), + 2009: (SEP, 20), + 2010: (SEP, 9), + 2011: (AUG, 30), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 6), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + +class AzerbaijanStaticHolidays: + """Azerbaijan special holidays. + + Substituted holidays references: + * + * + * + * + * + * + * + * + * + * + + Special holidays references: + * + """ + + eid_al_adha = tr("Qurban bayrami") + + eid_al_fitr = tr("Ramazan bayrami") + + womens_day = tr("Qadınlar günü") + + # Substituted date format. + substituted_date_format = tr("%d.%m.%Y") + # Day off (substituted from %s). + substituted_label = tr("İstirahət günü (%s ilə əvəz edilmişdir)") + + # Presidential elections. + presidential_elections = tr("Prezidenti seçkiləri") + + # Municipal elections. + municipal_elections = tr("Bələdiyyə seçkiləri") + + special_public_holidays = { + 2011: (AUG, 29, AUG, 27), + 2013: ( + (JAN, 3, DEC, 29, 2012), + (JAN, 4, DEC, 30, 2012), + ), + 2014: ( + (JAN, 3, DEC, 28, 2013), + (JAN, 6, DEC, 29, 2013), + ), + 2018: (APR, 11, presidential_elections), + 2019: (DEC, 27, municipal_elections), + 2020: ( + (JAN, 3, DEC, 28, 2019), + (JAN, 6, DEC, 29, 2019), + (MAR, 27, MAR, 29), + (MAY, 27, MAY, 30), + ), + 2021: ( + (MAY, 11, MAY, 8), + (MAY, 12, MAY, 16), + (JUL, 19, JUL, 17), + ), + 2022: ( + (MAR, 7, MAR, 5), + (NOV, 7, NOV, 5), + ), + 2023: ( + (JUN, 27, JUN, 24), + (JUN, 30, JUN, 25), + (NOV, 10, NOV, 4), + ), + 2024: ( + (JAN, 4, DEC, 30, 2023), + (JAN, 5, JAN, 7), + (FEB, 7, presidential_elections), + (APR, 12, APR, 6), + (NOV, 12, NOV, 16), + (NOV, 13, NOV, 23), + (DEC, 30, DEC, 28), + ), + 2025: ( + (JAN, 3, DEC, 29, 2024), + (JAN, 29, municipal_elections), + ), + } + + special_public_holidays_observed = { + 2007: (JAN, 3, eid_al_adha), + 2025: ( + (MAR, 27, womens_day), + (MAR, 28, eid_al_fitr), + ), + 2072: (JAN, 5, eid_al_adha), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/bahamas.py b/.venv/lib/python3.12/site-packages/holidays/countries/bahamas.py new file mode 100644 index 00000000..81b75c5f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/bahamas.py @@ -0,0 +1,142 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import SEP, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + TUE_TO_PREV_MON, + WED_THU_TO_NEXT_FRI, + SAT_SUN_TO_NEXT_MON, + SUN_TO_NEXT_MON, + SUN_TO_NEXT_TUE, +) + + +class Bahamas(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Bahamas holidays. + + References: + * + * + * + * + * + * + + Checked With: + * + * + * + """ + + country = "BS" + observed_label = "%s (observed)" + # Gained Independence on Jul 10, 1973. + start_year = 1974 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, BahamasStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + # Pre-2012 Observance: + # - If TUE, New Year's Day (observed) prev MON. + # - If WED or THU, New Year's Day (observed) next FRI. + # 2012 and beyond Observance: If SUN, New Year's Day (observed) next MON (not for SAT). + self._add_observed( + self._add_new_years_day("New Year's Day"), + rule=SUN_TO_NEXT_MON + if self._year >= 2012 + else SAT_SUN_TO_NEXT_MON + TUE_TO_PREV_MON + WED_THU_TO_NEXT_FRI, + ) + + # Majority Rule Day. + # Officially made a holiday on Oct 11, 2013 under Majority Rule (Public Holiday) Act 2013. + if self._year >= 2014: + self._add_observed(self._add_holiday_jan_10("Majority Rule Day")) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Whit Monday. + self._add_whit_monday("Whit Monday") + + # Randol Fawkes Labour Day. + # This was simply known as "Labour Day" prior to Randol Fawkes Labour Day Act 2013. + self._add_holiday_1st_fri_of_jun( + "Randol Fawkes Labour Day" if self._year >= 2013 else "Labour Day" + ) + + # Independence Day. + self._add_observed(self._add_holiday_jul_10("Independence Day")) + + # Emancipation Day. + self._add_holiday_1st_mon_of_aug("Emancipation Day") + + # National Heroes Day. + # Known as "Discovery Day" prior to 2013, with its date fixed as Oct 12 annually. + # Got its name changed on Oct 11, 2013 under Majority Rule (Public Holiday) Act 2013. + # Pre-2013 Observance: + # - If TUE, Discovery Day (observed) prev MON. + # - If WED or THU, Discovery Day (observed) next FRI. + if self._year >= 2013: + self._add_holiday_2nd_mon_of_oct("National Heroes Day") + else: + self._add_observed( + self._add_columbus_day("Discovery Day"), + rule=SAT_SUN_TO_NEXT_MON + TUE_TO_PREV_MON + WED_THU_TO_NEXT_FRI, + ) + + # Christmas Holidays Exception Rules. + # Observance Exception: + # FRI-SAT -> Boxing Day (observed) next MON. + # SAT-SUN -> Boxing Day (observed) next MON. + # SUN-MON -> Christmas Day (observed) next TUE. + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two("Boxing Day")) + + +class BS(Bahamas): + pass + + +class BHS(Bahamas): + pass + + +class BahamasStaticHolidays: + special_public_holidays = { + # https://web.archive.org/web/20250122110613/https://www.bahamas.gov.bs/wps/portal/public/gov/government/notices/national%20holiday%2019th%20september/ + 2022: (SEP, 19, "State Funeral of Queen Elizabeth II"), + } + + special_public_holidays_observed = { + # New Year's Day observance overflow. + # This only applies to Pre-2012 observance. + 1979: (DEC, 31, "New Year's Day"), + 1984: (DEC, 31, "New Year's Day"), + 1990: (DEC, 31, "New Year's Day"), + 2001: (DEC, 31, "New Year's Day"), + 2007: (DEC, 31, "New Year's Day"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/bahrain.py b/.venv/lib/python3.12/site-packages/holidays/countries/bahrain.py new file mode 100644 index 00000000..1e6be7d9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/bahrain.py @@ -0,0 +1,113 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import FRI, SAT, MAY, JUL, AUG, OCT +from holidays.groups import InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Bahrain(HolidayBase, InternationalHolidays, IslamicHolidays): + """Bahrain holidays. + + References: + * + * + """ + + country = "BH" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + supported_languages = ("ar", "en_US") + weekend = {FRI, SAT} + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=BahrainIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + # Labor Day. + self._add_labor_day(tr("عيد العمال")) + + # Eid al-Fitr. + eid_al_fitr = tr("عيد الفطر") + self._add_eid_al_fitr_day(eid_al_fitr) + self._add_eid_al_fitr_day_two(tr("عطلة عيد الفطر")) + # Eid al-Fitr Holiday. + self._add_eid_al_fitr_day_three(tr("عطلة عيد الفطر")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("عيد الأضحى")) + # Eid al-Adha Holiday. + self._add_eid_al_adha_day_two(tr("عطلة عيد الأضحى")) + self._add_eid_al_adha_day_three(tr("عطلة عيد الأضحى")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Ashura Eve. + self._add_ashura_eve(tr("ليلة عاشورة")) + # Ashura. + self._add_ashura_day(tr("عاشورة")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("عيد المولد النبوي")) + + # National Day. + national_day = tr("اليوم الوطني") + self._add_holiday_dec_16(national_day) + self._add_holiday_dec_17(national_day) + + +class BH(Bahrain): + pass + + +class BAH(Bahrain): + pass + + +class BahrainIslamicHolidays(_CustomIslamicHolidays): + ASHURA_DATES = { + 2022: (AUG, 8), + } + + EID_AL_ADHA = { + 2022: (JUL, 9), + } + + EID_AL_FITR_DATES = { + 2022: (MAY, 2), + } + + HIJRI_NEW_YEAR_DATES = { + 2022: (JUL, 30), + } + + MAWLID_DATES = { + 2022: (OCT, 8), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/bangladesh.py b/.venv/lib/python3.12/site-packages/holidays/countries/bangladesh.py new file mode 100644 index 00000000..e8a8f21a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/bangladesh.py @@ -0,0 +1,61 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import FRI, SAT +from holidays.groups import InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Bangladesh(HolidayBase, InternationalHolidays): + """Bangladesh holidays. + + References: + * + * + """ + + country = "BD" + weekend = {FRI, SAT} + + def __init__(self, *args, **kwargs): + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # International Mother's language Day. + self._add_holiday_feb_21("International Mother's language Day") + + # Sheikh Mujibur Rahman's Birthday and Children's Day. + self._add_holiday_mar_17("Sheikh Mujibur Rahman's Birthday and Children's Day") + + # Independence Day. + self._add_holiday_mar_26("Independence Day") + + # Bengali New Year's Day. + self._add_holiday_apr_14("Bengali New Year's Day") + + # May Day. + self._add_labor_day("May Day") + + # National Mourning Day. + self._add_holiday_aug_15("National Mourning Day") + + # Victory Day. + self._add_holiday_dec_16("Victory Day") + + +class BD(Bangladesh): + pass + + +class BGD(Bangladesh): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/barbados.py b/.venv/lib/python3.12/site-packages/holidays/countries/barbados.py new file mode 100644 index 00000000..58099e47 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/barbados.py @@ -0,0 +1,107 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import JAN, JUL +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SUN_TO_NEXT_MON, + SUN_TO_NEXT_TUE, +) + + +class Barbados(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Barbados holidays. + + References: + * + * + * [Public Holidays Act Cap.352](https://web.archive.org/web/20250427133553/https://barbadosparliament-laws.com/en/showdoc/cs/352) + * + * + * + * + """ + + country = "BB" + observed_label = "%s (observed)" + # Public Holidays Act Cap.352, 1968-12-30 + start_year = 1969 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, BarbadosStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Errol Barrow Day + if self._year >= 1989: + self._add_observed(self._add_holiday_jan_21("Errol Barrow Day")) + + # Good Friday + self._add_good_friday("Good Friday") + + # Easter Monday + self._add_easter_monday("Easter Monday") + + # National Heroes Day + if self._year >= 1998: + self._add_observed(self._add_holiday_apr_28("National Heroes Day")) + + # May Day + self._add_observed(self._add_labor_day("May Day")) + + # Whit Monday + self._add_whit_monday("Whit Monday") + + # Emancipation Day + name = "Emancipation Day" + # If Aug 1 is Kadooment Day (i.e. Monday), observed on Tuesday. + self._add_observed(self._add_holiday_aug_1(name), rule=SUN_TO_NEXT_TUE + MON_TO_NEXT_TUE) + + # Kadooment Day + self._add_holiday_1st_mon_of_aug("Kadooment Day") + + # Independence Day + self._add_observed(self._add_holiday_nov_30("Independence Day")) + + # Christmas + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + + # Boxing Day + self._add_observed(self._add_christmas_day_two("Boxing Day")) + + +class BB(Barbados): + pass + + +class BRB(Barbados): + pass + + +class BarbadosStaticHolidays: + special_public_holidays = { + 2021: ( + (JAN, 4, "Public Holiday"), + (JAN, 5, "Public Holiday"), + ), + # One off 50th Anniversary of CARICOM Holiday. + # See https://web.archive.org/web/20240805050828/https://gisbarbados.gov.bb/blog/one-off-bank-holiday-for-caricoms-50th-anniversary-celebrations/ + 2023: (JUL, 31, "50th Anniversary of CARICOM Holiday"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/belarus.py b/.venv/lib/python3.12/site-packages/holidays/countries/belarus.py new file mode 100644 index 00000000..ef00fc4b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/belarus.py @@ -0,0 +1,303 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import GREGORIAN_CALENDAR, JAN, MAR, APR, MAY, JUN, JUL, NOV, DEC +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Belarus(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Belarus holidays. + + References: + * + * + * + * + * + * + * + + Cross-checked With: + * + """ + + country = "BY" + default_language = "be" + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("be", "en_US", "ru", "th") + # Declaration of State Sovereignty of the BSSR. + start_year = 1991 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, BelarusStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Новы год") + self._add_new_years_day(name) + if self._year >= 2020: + self._add_new_years_day_two(name) + + # Orthodox Christmas Day. + self._add_christmas_day(tr("Нараджэнне Хрыстова (праваслаўнае Раство)")) + + # Women's Day. + self._add_womens_day(tr("Дзень жанчын")) + + if 1995 <= self._year <= 1998: + # Constitution Day. + self._add_holiday_mar_15(tr("Дзень Канстытуцыі")) + + # Labor Day. + self._add_labor_day(tr("Свята працы")) + + # Victory Day. + self._add_world_war_two_victory_day(tr("Дзень Перамогі"), is_western=False) + + # Radunitsa (Day of Rejoicing). + self._add_rejoicing_day(tr("Радаўніца")) + + # Independence Day of the Republic of Belarus (Day of the Republic). + name = tr("Дзень Незалежнасці Рэспублікі Беларусь (Дзень Рэспублікі)") + if self._year >= 1997: + self._add_holiday_jul_3(name) + else: + self._add_holiday_jul_27(name) + + if self._year >= 1995: + # October Revolution Day. + self._add_holiday_nov_7(tr("Дзень Кастрычніцкай рэвалюцыі")) + + # Catholic Christmas Day. + self._add_christmas_day(tr("Нараджэнне Хрыстова (каталіцкае Раство)"), GREGORIAN_CALENDAR) + + if self._year >= 1992: + # Catholic Easter. + name_catholic = tr("Каталiцкi Вялiкдзень") + self._add_easter_sunday(name_catholic, GREGORIAN_CALENDAR) + + # Orthodox Easter. + name_orthodox = tr("Праваслаўны Вялiкдзень") + self._add_easter_sunday(name_orthodox) + + if self._year <= 1997: + self._add_easter_monday(name_catholic, GREGORIAN_CALENDAR) + self._add_easter_monday(name_orthodox) + + # Dzyady (All Souls' Day). + self._add_all_souls_day(tr("Дзень памяці")) + + def _populate_workday_holidays(self): + # Day of the Fatherland's Defenders and the Armed Forces of the Republic of Belarus. + self._add_holiday_feb_23(tr("Дзень абаронцаў Айчыны і Узброеных Сіл Рэспублікі Беларусь")) + + if self._year >= 1999: + # Constitution Day. + self._add_holiday_mar_15(tr("Дзень Канстытуцыі")) + + if self._year >= 1996: + # Day of Unity of the Peoples of Belarus and Russia. + self._add_holiday_apr_2(tr("Дзень яднання народаў Беларусі і Расіі")) + + if self._year >= 1998: + self._add_holiday_2nd_sun_of_may( + # Day of the National Coat of Arms of the Republic of Belarus, + # the National Flag of the Republic of Belarus + # and the National Anthem of the Republic of Belarus. + tr( + "Дзень Дзяржаўнага сцяга, Дзяржаўнага герба і Дзяржаўнага " + "гімна Рэспублікі Беларусь" + ) + ) + + if self._year >= 2021: + # Day of People's Unity. + self._add_holiday_sep_17(tr("Дзень народнага адзінства")) + + if self._year >= 1998: + # Dzyady (All Souls' Day). + self._add_all_souls_day(tr("Дзень памяці")) + + +class BY(Belarus): + pass + + +class BLR(Belarus): + pass + + +class BelarusStaticHolidays: + """Belarus special holidays. + + References: + * + * + """ + + # Date format (see strftime() Format Codes) + substituted_date_format = tr("%d.%m.%Y") + # Day off (substituted from %s). + substituted_label = tr("Выходны (перанесены з %s)") + special_public_holidays = { + 1998: ( + (JAN, 2, JAN, 10), + (APR, 27, APR, 25), + ), + 1999: ( + (JAN, 8, JAN, 16), + (APR, 19, APR, 17), + ), + 2000: ( + (MAY, 8, MAY, 13), + (NOV, 6, NOV, 11), + ), + 2001: ( + (JAN, 2, JAN, 20), + (MAR, 9, MAR, 3), + (APR, 23, APR, 21), + (APR, 30, APR, 28), + (JUL, 2, JUL, 7), + (DEC, 24, DEC, 22), + (DEC, 31, DEC, 29), + ), + 2002: ( + (JAN, 2, JAN, 5), + (MAY, 10, MAY, 18), + (NOV, 8, NOV, 16), + ), + 2003: ( + (JAN, 6, JAN, 4), + (MAY, 5, MAY, 3), + ), + 2004: ( + (JAN, 2, JAN, 10), + (JAN, 5, JAN, 17), + (JAN, 6, JAN, 31), + (APR, 19, APR, 17), + ), + 2005: (MAR, 7, MAR, 12), + 2006: ( + (JAN, 2, JAN, 21), + (MAY, 8, MAY, 6), + (NOV, 6, NOV, 4), + ), + 2007: ( + (JAN, 2, DEC, 30, 2006), + (MAR, 9, MAR, 17), + (APR, 16, APR, 14), + (APR, 30, MAY, 5), + (JUL, 2, JUL, 7), + (DEC, 24, DEC, 22), + (DEC, 31, DEC, 29), + ), + 2008: ( + (JAN, 2, JAN, 12), + (MAY, 5, MAY, 3), + (JUL, 4, JUN, 28), + (DEC, 26, DEC, 20), + ), + 2009: ( + (JAN, 2, JAN, 10), + (APR, 27, APR, 25), + ), + 2010: ( + (JAN, 8, JAN, 23), + (APR, 12, APR, 17), + (MAY, 10, MAY, 15), + ), + 2011: ( + (MAR, 7, MAR, 12), + (MAY, 2, MAY, 14), + ), + 2012: ( + (MAR, 9, MAR, 11), + (APR, 23, APR, 28), + (JUL, 2, JUN, 30), + (DEC, 24, DEC, 22), + (DEC, 31, DEC, 29), + ), + 2013: ( + (JAN, 2, JAN, 5), + (MAY, 10, MAY, 18), + ), + 2014: ( + (JAN, 2, JAN, 4), + (JAN, 6, JAN, 11), + (APR, 30, MAY, 3), + (JUL, 4, JUL, 12), + (DEC, 26, DEC, 20), + ), + 2015: ( + (JAN, 2, JAN, 10), + (APR, 20, APR, 25), + ), + 2016: ( + (JAN, 8, JAN, 16), + (MAR, 7, MAR, 5), + ), + 2017: ( + (JAN, 2, JAN, 21), + (APR, 24, APR, 29), + (MAY, 8, MAY, 6), + (NOV, 6, NOV, 4), + ), + 2018: ( + (JAN, 2, JAN, 20), + (MAR, 9, MAR, 3), + (APR, 16, APR, 14), + (APR, 30, APR, 28), + (JUL, 2, JUL, 7), + (DEC, 24, DEC, 22), + (DEC, 31, DEC, 29), + ), + 2019: ( + (MAY, 6, MAY, 4), + (MAY, 8, MAY, 11), + (NOV, 8, NOV, 16), + ), + 2020: ( + (JAN, 6, JAN, 4), + (APR, 27, APR, 4), + ), + 2021: ( + (JAN, 8, JAN, 16), + (MAY, 10, MAY, 15), + ), + 2022: ( + (MAR, 7, MAR, 12), + (MAY, 2, MAY, 14), + ), + 2023: ( + (APR, 24, APR, 29), + (MAY, 8, MAY, 13), + (NOV, 6, NOV, 11), + ), + 2024: ( + (MAY, 13, MAY, 18), + (NOV, 8, NOV, 16), + ), + 2025: ( + (JAN, 6, JAN, 11), + (APR, 28, APR, 26), + (JUL, 4, JUL, 12), + (DEC, 26, DEC, 20), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/belgium.py b/.venv/lib/python3.12/site-packages/holidays/countries/belgium.py new file mode 100644 index 00000000..c4473459 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/belgium.py @@ -0,0 +1,93 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import BANK, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Belgium(HolidayBase, ChristianHolidays, InternationalHolidays): + """Belgium holidays. + + References: + * + * + * + * + """ + + country = "BE" + default_language = "nl" + supported_categories = (BANK, PUBLIC) + supported_languages = ("de", "en_US", "fr", "nl", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nieuwjaar")) + + # Easter Sunday. + self._add_easter_sunday(tr("Pasen")) + + # Easter Monday. + self._add_easter_monday(tr("Paasmaandag")) + + # Labor Day. + self._add_labor_day(tr("Dag van de Arbeid")) + + # Ascension Day. + self._add_ascension_thursday(tr("O. L. H. Hemelvaart")) + + # Whit Sunday. + self._add_whit_sunday(tr("Pinksteren")) + + # Whit Monday. + self._add_whit_monday(tr("Pinkstermaandag")) + + # National Day. + self._add_holiday_jul_21(tr("Nationale feestdag")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("O. L. V. Hemelvaart")) + + # All Saints' Day. + self._add_all_saints_day(tr("Allerheiligen")) + + # Armistice Day. + self._add_remembrance_day(tr("Wapenstilstand")) + + # Christmas Day. + self._add_christmas_day(tr("Kerstmis")) + + def _populate_bank_holidays(self): + # Good Friday. + self._add_good_friday(tr("Goede Vrijdag")) + + # Friday after Ascension Day. + self._add_holiday_40_days_past_easter(tr("Vrijdag na O. L. H. Hemelvaart")) + + # Bank Holiday. + self._add_christmas_day_two(tr("Banksluitingsdag")) + + +class BE(Belgium): + pass + + +class BEL(Belgium): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/belize.py b/.venv/lib/python3.12/site-packages/holidays/countries/belize.py new file mode 100644 index 00000000..8896be32 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/belize.py @@ -0,0 +1,114 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SUN_TO_NEXT_MON, + TUE_WED_THU_TO_PREV_MON, + FRI_SUN_TO_NEXT_MON, +) + + +class Belize(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Belize holidays. + + References: + * + * + * + * + """ + + country = "BZ" + observed_label = "%s (observed)" + # Belize was granted independence on 21.09.1981. + start_year = 1982 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + # Chapter 289 of the laws of Belize states that if the holiday falls + # on a Sunday or a Friday, the following Monday is observed as public + # holiday; further, if the holiday falls on a Tuesday, Wednesday or + # Thursday, the preceding Monday is observed as public holiday + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._move_holiday(self._add_new_years_day("New Year's Day")) + + if self._year >= 2021: + # George Price Day. + self._move_holiday(self._add_holiday_jan_15("George Price Day")) + + # National Heroes and Benefactors Day. + self._move_holiday( + self._add_holiday_mar_9("National Heroes and Benefactors Day"), + rule=TUE_WED_THU_TO_PREV_MON + FRI_SUN_TO_NEXT_MON, + ) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Holy Saturday. + self._add_holy_saturday("Holy Saturday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Labour Day. + self._move_holiday(self._add_labor_day("Labour Day")) + + if self._year <= 2021: + # Commonwealth Day. + self._move_holiday( + self._add_holiday_may_24("Commonwealth Day"), + rule=TUE_WED_THU_TO_PREV_MON + FRI_SUN_TO_NEXT_MON, + ) + + if self._year >= 2021: + # Emancipation Day. + self._move_holiday( + self._add_holiday_aug_1("Emancipation Day"), + rule=TUE_WED_THU_TO_PREV_MON + FRI_SUN_TO_NEXT_MON, + ) + + # Saint George's Caye Day. + self._move_holiday(self._add_holiday_sep_10("Saint George's Caye Day")) + + # Independence Day. + self._move_holiday(self._add_holiday_sep_21("Independence Day")) + + # Indigenous Peoples' Resistance Day / Pan American Day. + name = "Indigenous Peoples' Resistance Day" if self._year >= 2021 else "Pan American Day" + self._move_holiday( + self._add_columbus_day(name), rule=TUE_WED_THU_TO_PREV_MON + FRI_SUN_TO_NEXT_MON + ) + + # Garifuna Settlement Day. + self._move_holiday(self._add_holiday_nov_19("Garifuna Settlement Day")) + + # Christmas Day. + self._add_christmas_day("Christmas Day") + + # Boxing Day. + self._move_holiday(self._add_christmas_day_two("Boxing Day")) + + +class BZ(Belize): + pass + + +class BLZ(Belize): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/benin.py b/.venv/lib/python3.12/site-packages/holidays/countries/benin.py new file mode 100644 index 00000000..6edc3788 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/benin.py @@ -0,0 +1,199 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Benin(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Benin holidays. + + References: + * + * [Order 71-14](https://web.archive.org/web/20240727075244/https://sgg.gouv.bj/doc/ordonnance-1971-14/) + * [Order 76-35](https://web.archive.org/web/20240726042853/https://sgg.gouv.bj/doc/ordonnance-1976-35/) + * [Order 79-33](https://web.archive.org/web/20240725115717/https://sgg.gouv.bj/doc/ordonnance-1979-33/) + * [Law 90-019](https://web.archive.org/web/20250527021602/https://sgg.gouv.bj/doc/loi-90-019/) + * [Law 97-031](https://web.archive.org/web/20250527022039/https://sgg.gouv.bj/doc/loi-97-031/) + * [Law 2024-32](https://web.archive.org/web/20250321041430/https://sgg.gouv.bj/doc/loi-2024-32/) + + Official dates: + * [2015](https://web.archive.org/web/20211130121041/https://beninconsulate.co.ke/index.php/news-events/7-public-holidays-2015) + * [2017](https://web.archive.org/web/20211130124252/https://beninconsulate.co.ke/index.php/news-events/8-public-holidays-2017) + * [2019](https://web.archive.org/web/20231003144018/https://beninconsulate.co.ke/index.php/news-events) + * [2024](https://web.archive.org/web/20241211032923/https://beninconsulate.co.ke/index.php/news-events) + * [2025](https://web.archive.org/web/20250317141957/https://beninconsulate.co.ke/index.php/news-events?start=1) + + Certain holidays dates: + * 2022: + * [All Saints' Day](https://web.archive.org/web/20241010101230/https://travail.gouv.bj/page/communiques/la-journee-du-mardi-1er-novembre-2022-declaree-feriee-chomee-et-payee) + * [Christmas Day](https://web.archive.org/web/20240814200022/https://travail.gouv.bj/page/communiques/la-journee-du-dimanche-25-decembre-2022-declaree-feriee-chomee-et-payee-a-loccasion-de-la-celebration-de-la-fete-de-noel-lire-le-communique-du-ministre-du-travail-et-de-la-fonction-publique) + * 2023: + * [New Year's Day](https://web.archive.org/web/20240724084416/https://travail.gouv.bj/page/communiques/la-journee-du-dimanche-1er-janvier-2023-declaree-feriee-chomee-et-payee-a-loccasion-de-la-celebration-de-la-fete-du-nouvel-an) + * [Vodoun Festival](https://web.archive.org/web/20240724084406/https://travail.gouv.bj/page/communiques/la-journee-du-mardi-10-janvier-2023-est-declaree-feriee-chomee-et-payee-a-loccasion-de-la-celebration-de-la-fete-annuelle-des-religions-traditionnelles-2301071350-956) + * [Eid al-Fitr](https://web.archive.org/web/20240723004550/https://travail.gouv.bj/page/communiques/celebration-le-vendredi-21-avril-2023-de-la-fete-du-ramadan) + * [Easter Monday](https://web.archive.org/web/20241010103541/https://travail.gouv.bj/page/communiques/la-journee-du-lundi-10-avril-2023-est-declaree-feriee-chomee-et-payee-en-raison-de-la-fete-de-paques) + * [Whit Monday](https://web.archive.org/web/20240911163554/https://travail.gouv.bj/page/communiques/la-fete-de-pentecote) + * [Labor Day](https://web.archive.org/web/20240814205702/https://travail.gouv.bj/page/communiques/la-journee-du-lundi-1er-mai-2023-declaree-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national-a-loccasion-de-la-celebration-de-la-fete-du-travail) + * [Assumption Day](https://web.archive.org/web/20241214182235/https://travail.gouv.bj/page/communiques/la-journee-du-mardi-15-aout-2023-declaree-feriee-chomee-et-payee-en-raison-de-la-fete-de-lassomption) + * [Independence Day](https://web.archive.org/web/20240723004533/https://travail.gouv.bj/page/communiques/la-journee-du-mardi-1er-aout-2023-declaree-feriee-chomee-et-payee-a-l-occasion-de-la-fete-nationale) + * [Eid al-Adha](https://web.archive.org/web/20250422035008/https://travail.gouv.bj/page/communiques/communique-du-ministere-du-travail-et-de-la-fonction-publique-2306262022-744) + * 2024: + * [Vodoun Festival](https://web.archive.org/web/20240723004435/https://travail.gouv.bj/page/communiques/la-journee-du-mercredi-10-janvier-2024-est-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national) + * [Eid al-Fitr](https://web.archive.org/web/20241010114534/https://travail.gouv.bj/page/communiques/la-journee-du-mercredi-10-avril-2024-jour-du-ramadan-est-declaree-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national) + * [Easter Monday](https://web.archive.org/web/20241106004344/https://travail.gouv.bj/page/communiques/la-journee-du-lundi-1er-avril-2024-lundi-de-paques-est-chomee) + * [Assumption Day](https://web.archive.org/web/20250215044724/https://travail.gouv.bj/page/communiques/la-journee-du-dimanche-15-aout-jour-de-lassomption-est-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national) + * [Eid al-Adha](https://web.archive.org/web/20241214200230/https://travail.gouv.bj/page/communiques/jour-de-la-tabaski) + * [Labor Day](https://web.archive.org/web/20250418224409/https://www.travail.gouv.bj/page/communiques/la-journee-du-mercredi-1er-mai-2024-journee-de-la-fete-du-travail-est-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national) + * [Ascension Day](https://web.archive.org/web/20241214204011/https://travail.gouv.bj/page/communiques/le-jeudi-09-mai-2024-jour-de-lascension-est-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national) + * [Whit Monday](https://web.archive.org/web/20241010113401/https://travail.gouv.bj/page/communiques/le-lundi-20-mai-2024-lundi-de-pentecote-est-ferie-chome-et-paye-sur-toute-letendue-du-territoire-national) + * [Prophet's Birthday](https://web.archive.org/web/20250215034616/https://travail.gouv.bj/page/communiques/la-journee-du-dimanche-15-septembre-2024-jour-de-maoloud-est-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national) + * [Christmas Day](https://web.archive.org/web/20250122081816/https://travail.gouv.bj/page/communiques/la-journee-du-mercredi-25-decembre-2024-est-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national) + * 2025: + * [New Year's Day](https://web.archive.org/web/20250422023225/https://travail.gouv.bj/page/communiques/la-journee-du-mercredi-1er-janvier-2025-fete-du-nouvel-an-est-feriee-chomee-et-payee-sur-toute-letendue-du-territoire-national) + * [Vodoun Festival](https://web.archive.org/web/20250422034718/https://travail.gouv.bj/page/communiques/les-journees-du-jeudi-9-janvier-2024-et-vendredi-10-janvier-2024-sont-feriees-chomees-et-payees-sur-toute-letendue-du-territoire-national) + """ + + country = "BJ" + default_language = "fr_BJ" + # %s (estimated). + estimated_label = tr("%s (estimé)") + # Order 76-35 of June 30, 1976. + start_year = 1977 + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("en_US", "fr_BJ") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Fête du Nouvel An")) + + # Established in 1998 by Law 97-031. + # Changed in 2025 by Law 2024-32. + if self._year >= 1998: + # Vodoun Festival. + name = tr("Fête annuelle des religions traditionnelles") + if self._year >= 2025: + self._add_holiday_1_day_prior_2nd_fri_of_jan(name) + self._add_holiday_2nd_fri_of_jan(name) + else: + self._add_holiday_jan_10(name) + + # Established in 1980 by Order 79-33. + # Abolished in 1991 by Law 90-019. + if 1980 <= self._year <= 1990: + # Martyrs' Day. + self._add_holiday_jan_16(tr("Journée des Martyrs")) + + # Youth Day. + self._add_holiday_apr_1(tr("Journée de la Jeunesse Béninoise")) + + # Changed in 1991 by Law 90-019. + if self._year >= 1991: + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + else: + # Easter Sunday. + self._add_easter_sunday(tr("Jour de Pâques")) + + # Labor Day. + self._add_labor_day(tr("Fête du Travail")) + + # Established in 1991 by Law 90-019. + if self._year >= 1991: + # Ascension Day. + self._add_ascension_thursday(tr("Jour de l'Ascension")) + + if self._year >= 1991: + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + else: + # Whit Sunday. + self._add_whit_sunday(tr("Jour de Pentecôte")) + + # Established in 1990 by Law 90-019. + if self._year >= 1990: + # Assumption Day. + self._add_assumption_of_mary_day(tr("Jour de l'Assomption")) + + # Established in 1977 by Order 71-14. + # Abolished in 1990 by Law 90-019. + if self._year <= 1989: + # Armed Forces Day. + self._add_holiday_oct_26(tr("Fête des Forces Armées Populaires du Bénin")) + + # Established in 1990 by Law 90-019. + if self._year >= 1990: + # All Saints' Day. + self._add_all_saints_day(tr("La Toussaint")) + + # National Day. + name = tr("Fête Nationale") + if self._year >= 1991: + self._add_holiday_aug_1(name) + else: + self._add_holiday_nov_30(name) + + # Christmas Day. + self._add_christmas_day(tr("Jour de Noël")) + + # Established in 1977 by Order 71-14. + # Abolished in 1990 by Law 90-019. + if self._year <= 1989: + # Production Day. + self._add_holiday_dec_31(tr("Fête de la Production")) + + # Islamic holidays. + + # Established in 1990 by Law 90-019. + if self._year >= 1990: + # Prophet's Birthday. + self._add_mawlid_day(tr("Journée Maouloud")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Jour du Ramadan")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Jour de la Tabaski")) + + def _populate_workday_holidays(self): + if self._year >= 1990: + # Remembrance Day. + self._add_holiday_jan_16(tr("Journée de Souvenir")) + + # People's Sovereignty Day. + self._add_holiday_feb_28(tr("Journée de la Souveraineté de Peuple")) + + # Women's Day. + self._add_holiday_mar_8(tr("Journée de la Femme")) + + +class BJ(Benin): + pass + + +class BEN(Benin): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/bermuda.py b/.venv/lib/python3.12/site-packages/holidays/countries/bermuda.py new file mode 100644 index 00000000..c2a5b305 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/bermuda.py @@ -0,0 +1,152 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAY, JUN, OCT, NOV +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Bermuda(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Bermuda holidays. + + References: + * [Public Holidays Act 1947](https://web.archive.org/web/20250527163956/https://www.bermudalaws.bm/Laws/Consolidated%20Law/1947/Public%20Holidays%20Act%201947) + * [Public Holidays Amendment Act 1999](https://web.archive.org/web/20250527163749/https://www.bermudalaws.bm/Laws/Annual%20Law/Acts/1999/Public%20Holidays%20Amendment%20Act%201999) + * [Public Holidays Amendment Act 2008](https://web.archive.org/web/20250527163810/https://www.bermudalaws.bm/Laws/Annual%20Law/Acts/2008/Public%20Holidays%20Amendment%20Act%202008) + * [Public Holidays Amendment (No. 2) Act 2009](https://web.archive.org/web/20250527163816/https://www.bermudalaws.bm/Laws/Annual%20Law/Acts/2009/Public%20Holidays%20Amendment%20(No.%202)%20Act%202009) + * [Public Holidays Amendment Act 2017](https://web.archive.org/web/20250527163819/https://www.bermudalaws.bm/Laws/Annual%20Law/Acts/2017/Public%20Holidays%20Amendment%20Act%202017) + * [Public Holidays Amendment Act 2020](https://web.archive.org/web/20250527163836/https://www.bermudalaws.bm/Laws/Annual%20Law/Acts/2020/Public%20Holidays%20Amendment%20Act%202020) + * [Government of Bermuda](https://web.archive.org/web/20250530055854/https://www.gov.bm/public-holidays) + * [Proclamation BR 149 / 2018](https://web.archive.org/web/20250530114331/https://www.bermudalaws.bm/Laws/Annual%20Law/Statutory%20Instruments/2018/Proclamation%20-%20Bermuda%20Day%20Public%20Holiday) + """ + + country = "BM" + default_language = "en_BM" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_BM", "en_US") + start_year = 1948 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, BermudaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Bermuda Day. + name = tr("Bermuda Day") + if self._year <= 2017: + self._add_observed(self._add_holiday_may_24(name)) + elif self._year == 2019: + self._add_holiday_may_24(name) + elif self._year <= 2020: + self._add_holiday_last_fri_of_may(name) + else: + self._add_holiday_3_days_prior_last_mon_of_may(name) + + # Queen's Birthday. + name = tr("Queen's Birthday") + if self._year <= 1999: + self._add_holiday_3rd_mon_of_jun(name) + elif self._year <= 2008: + self._add_holiday_2_days_past_2nd_sat_of_jun(name) + + # National Heroes Day. + name = tr("National Heroes Day") + if self._year == 2008: + self._add_holiday_2nd_mon_of_oct(name) + elif self._year >= 2009: + self._add_holiday_3rd_mon_of_jun(name) + + self._add_holiday_4_days_prior_1st_mon_of_aug( + # Cup Match Day. + tr("Cup Match Day") + if self._year <= 1999 + # Emancipation Day. + else tr("Emancipation Day") + ) + + self._add_holiday_3_days_prior_1st_mon_of_aug( + # Somers Day. + tr("Somers Day") + if self._year <= 2019 + # Mary Prince Day. + else tr("Mary Prince Day") + ) + + # Labor Day. + self._add_holiday_1st_mon_of_sep(tr("Labour Day")) + + # Remembrance Day. + self._add_observed(self._add_remembrance_day(tr("Remembrance Day"))) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + +class BM(Bermuda): + pass + + +class BMU(Bermuda): + pass + + +class BermudaStaticHolidays: + """Bermuda special holidays. + + References: + * [June 5, 2007 Holiday](https://web.archive.org/web/20250530122818/https://www.bermudalaws.bm/Laws/Annual%20Law/Statutory%20Instruments/2007/Proclamation) + * Portuguese Welcome 170th Anniversary + * + * + * Flora Duffy Day + * + * + * The Coronation of His Majesty King Charles III Holiday + * + * + """ + + special_public_holidays = { + # Public Holiday. + 2007: (JUN, 5, tr("Public Holiday")), + # Portuguese Welcome 170th Anniversary. + 2019: (NOV, 4, tr("Portuguese Welcome 170th Anniversary")), + # Flora Duffy Day. + 2021: (OCT, 18, tr("Flora Duffy Day")), + # The Coronation of His Majesty King Charles III. + 2023: (MAY, 8, tr("The Coronation of His Majesty King Charles III")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/bolivia.py b/.venv/lib/python3.12/site-packages/holidays/countries/bolivia.py new file mode 100644 index 00000000..b7db92d4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/bolivia.py @@ -0,0 +1,175 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + TUE_TO_PREV_MON, + THU_TO_NEXT_FRI, + SUN_TO_NEXT_MON, +) + + +class Bolivia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Bolivia holidays. + + References: + * [Supreme Decree #14260](https://web.archive.org/web/20250428205639/https://bolivia.infoleyes.com/norma/1141/decreto-supremo-14260) + * [Supreme Decree #21060](https://web.archive.org/web/20250428210031/https://bolivia.infoleyes.com/norma/1211/decreto-supremo-21060) + * [Supreme Decree #22352](https://web.archive.org/web/20250428210103/https://bolivia.infoleyes.com/norma/1310/decreto-supremo-22352) + * [Supreme Decree #0173](https://web.archive.org/web/20250428210129/https://bolivia.infoleyes.com/norma/829/decreto-supremo-0173) + * [Supreme Decree #0405](https://web.archive.org/web/20250428210132/https://bolivia.infoleyes.com/norma/1252/decreto-supremo-0405) + * [Supreme Decree #1210](https://web.archive.org/web/20250428210105/https://bolivia.infoleyes.com/norma/3756/decreto-supremo-1210) + * [Supreme Decree #2750](https://web.archive.org/web/20250428210116/https://bolivia.infoleyes.com/norma/6023/decreto-supremo-2750) + * + * + """ + + country = "BO" + default_language = "es" + # %s (observed). + observed_label = tr("%s (observado)") + start_year = 1825 + subdivisions = ( + "B", # El Beni. + "C", # Cochabamba. + "H", # Chuquisaca. + "L", # La Paz. + "N", # Pando. + "O", # Oruro. + "P", # Potosí. + "S", # Santa Cruz. + "T", # Tarija. + ) + subdivisions_aliases = { + "El Beni": "B", + "Cochabamba": "C", + "Chuquisaca": "H", + "La Paz": "L", + "Pando": "N", + "Oruro": "O", + "Potosí": "P", + "Santa Cruz": "S", + "Tarija": "T", + } + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + # Supreme Decree #14260. + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1977) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("Año Nuevo"))) + + # Supreme Decree #0405. + if self._year >= 2010: + self._add_observed( + self._add_holiday_jan_22( + # Plurinational State Foundation Day. + tr("Día de la Creación del Estado Plurinacional de Bolivia") + ) + ) + + # Carnival. + name = tr("Carnaval") + self._add_carnival_monday(name) + self._add_carnival_tuesday(name) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Labor Day. + self._add_observed(may_1 := self._add_labor_day(tr("Día del Trabajo"))) + # Supreme Decree #1210. + if 2012 <= self._year <= 2015: + self._add_observed(may_1, rule=TUE_TO_PREV_MON + THU_TO_NEXT_FRI) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + # Supreme Decree #0173. + if self._year >= 2009: + # Aymara New Year. + self._add_observed(self._add_holiday_jun_21(tr("Año Nuevo Aymara Amazónico"))) + + # Independence Day. + self._add_observed(self._add_holiday_aug_6(tr("Día de la Independencia de Bolivia"))) + + if self._year >= 2020: + # National Dignity Day. + self._add_holiday_oct_17(tr("Día de la Dignidad Nacional")) + + # Supreme Decree #21060. + if 1985 <= self._year <= 1988: + # All Saints' Day. + self._add_all_saints_day(tr("Día de Todos los Santos")) + + # Supreme Decree #22352. + if self._year >= 1989: + # All Souls' Day. + nov_2 = self._add_all_souls_day(tr("Día de Todos los Difuntos")) + if self._year <= 2015: + self._add_observed(nov_2) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Navidad"))) + + def _populate_subdiv_b_public_holidays(self): + # Beni Day. + self._add_holiday_nov_18(tr("Día del departamento de Beni")) + + def _populate_subdiv_c_public_holidays(self): + # Cochabamba Day. + self._add_holiday_sep_14(tr("Día del departamento de Cochabamba")) + + def _populate_subdiv_h_public_holidays(self): + # Chuquisaca Day. + self._add_holiday_may_25(tr("Día del departamento de Chuquisaca")) + + def _populate_subdiv_l_public_holidays(self): + # La Paz Day. + self._add_holiday_jul_16(tr("Día del departamento de La Paz")) + + def _populate_subdiv_n_public_holidays(self): + # Pando Day. + self._add_holiday_oct_11(tr("Día del departamento de Pando")) + + def _populate_subdiv_p_public_holidays(self): + # Potosí Day. + self._add_holiday_nov_10(tr("Día del departamento de Potosí")) + + def _populate_subdiv_o_public_holidays(self): + # Carnival in Oruro. + self._add_holiday_51_days_prior_easter(tr("Carnaval de Oruro")) + + def _populate_subdiv_s_public_holidays(self): + # Santa Cruz Day. + self._add_holiday_sep_24(tr("Día del departamento de Santa Cruz")) + + def _populate_subdiv_t_public_holidays(self): + # La Tablada. + self._add_holiday_apr_15(tr("La Tablada")) + + +class BO(Bolivia): + pass + + +class BOL(Bolivia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/bonaire_sint_eustatius_and_saba.py b/.venv/lib/python3.12/site-packages/holidays/countries/bonaire_sint_eustatius_and_saba.py new file mode 100644 index 00000000..45a6e150 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/bonaire_sint_eustatius_and_saba.py @@ -0,0 +1,134 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAY +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_PREV_SAT + + +class BonaireSintEustatiusAndSaba( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """Bonaire, Sint Eustatius and Saba holidays. + + References: + * [Public Holidays 2025 (English)](https://web.archive.org/web/20250620050728/https://english.rijksdienstcn.com/social-affairs-work/employment/official-holidays) + * [Public Holidays 2025 (Dutch)](https://web.archive.org/web/20250323122427/https://www.rijksdienstcn.com/sociale-zaken-werk/arbeid/officiele-feestdagen) + * [Public Holidays 2025 (Papiamento)](https://web.archive.org/web/20250323125431/https://papiamentu.rijksdienstcn.com/asuntunan-sosial-i-labor/labor/dia-di-fiesta-ofisial) + * [Arbeidsregeling 2000](https://web.archive.org/web/20250625203706/https://lokaleregelgeving.overheid.nl/CVDR10375/1) + * [Dia di Rincon 2025](https://web.archive.org/web/20250515183744/https://sunwisebonaire.com/blog/dia-di-rincon-2025-on-bonaire/) + """ + + country = "BQ" + default_language = "nl" + # Became special municipalities of the Netherlands on October 10th, 2010. + start_year = 2011 + subdivisions = ( + "BON", # Bonaire. + "SAB", # Saba. + "STA", # Sint Eustatius. + ) + subdivisions_aliases = { + "Bonaire": "BON", + "Saba": "SAB", + "Sint Eustatius": "STA", + } + supported_languages = ("en_BQ", "en_US", "nl", "pap_BQ") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=BonaireSintEustatiusAndSabaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nieuwjaarsdag")) + + # Good Friday. + self._add_good_friday(tr("Goede Vrijdag")) + + # Easter Sunday. + self._add_easter_sunday(tr("Eerste Paasdag")) + + # Easter Monday. + self._add_easter_monday(tr("Tweede Paasdag")) + + self._move_holiday( + # King's Day. + self._add_holiday_apr_27(tr("Koningsdag")) + if self._year >= 2014 + # Queen's Day. + else self._add_holiday_apr_30(tr("Koninginnedag")), + rule=SUN_TO_PREV_SAT, + ) + + # Labor Day. + self._add_labor_day(tr("Dag van de Arbeid")) + + # Ascension Day. + self._add_ascension_thursday(tr("Hemelvaartsdag")) + + # Whit Sunday. + self._add_whit_sunday(tr("Eerste Pinksterdag")) + + # Christmas Day. + self._add_christmas_day(tr("Eerste Kerstdag")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Tweede Kerstdag")) + + def _populate_subdiv_bon_public_holidays(self): + if self._year >= 2020: + # Rincon Day. + self._add_holiday_apr_30(tr("Rincondag")) + + # Bonaire Day. + self._add_holiday_sep_6(tr("Bonairedag")) + + def _populate_subdiv_sab_public_holidays(self): + # Carnival Monday. + self._add_holiday_last_mon_of_jul(tr("Dag na de carnavalsoptocht")) + + # Saba Day. + self._add_holiday_1st_fri_of_dec(tr("Sabadag")) + + def _populate_subdiv_sta_public_holidays(self): + if self._year >= 2022: + # Emancipation Day. + self._add_holiday_jul_1(tr("Emancipatiedag")) + + # Statia Day. + self._add_holiday_nov_16(tr("Statiadag")) + + +class BQ(BonaireSintEustatiusAndSaba): + pass + + +class BES(BonaireSintEustatiusAndSaba): + pass + + +class BonaireSintEustatiusAndSabaStaticHolidays(StaticHolidays): + """Bonaire, Sint Eustatius and Saba special holidays. + + References: + * [Bonaire May 2nd, 2025](https://web.archive.org/web/20250620052258/https://bonairegov.com/nieuwsoverzicht/artikel/vrijdag-2-mei-2025-aangewezen-als-vrije-dag-voor-ambtenaren) + """ + + special_bon_public_holidays = { + # Bridge Holiday. + 2025: (MAY, 2, tr("Brugdag")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/bosnia_and_herzegovina.py b/.venv/lib/python3.12/site-packages/holidays/countries/bosnia_and_herzegovina.py new file mode 100644 index 00000000..0750069e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/bosnia_and_herzegovina.py @@ -0,0 +1,313 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + GREGORIAN_CALENDAR, + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, +) +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ChristianHolidays, IslamicHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_TO_NEXT_MON, + SUN_TO_NEXT_MON, + SUN_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class BosniaAndHerzegovina( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays +): + """Bosnia and Herzegovina holidays. + + References: + * + * + * + * + + Observed holidays rules: + * BIH: if first day of New Year's Day and Labor Day fall on Sunday, observed on Tuesday. + * BRC: if holiday fall on Sunday, observed on next working day. + * SRP: if second day of New Year's Day and Labor Day fall on Sunday, observed on Monday. + """ + + country = "BA" + default_language = "bs" + # %s (observed). + observed_label = tr("%s (preneseno)") + subdivisions = ( + "BIH", # Federacija Bosne i Hercegovine. + "BRC", # Brčko distrikt. + "SRP", # Republika Srpska. + ) + subdivisions_aliases = { + "Federacija Bosne i Hercegovine": "BIH", + "FBiH": "BIH", + "Brčko distrikt": "BRC", + "BD": "BRC", + "Republika Srpska": "SRP", + "RS": "SRP", + } + supported_languages = ("bs", "en_US", "sr", "uk") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=BosniaAndHerzegovinaIslamicHolidays, show_estimated=islamic_show_estimated + ) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Orthodox Good Friday. + self._add_good_friday(tr("Veliki petak (Pravoslavni)")) + + # Catholic Easter Monday. + self._add_easter_monday(tr("Uskrsni ponedjeljak (Katolički)"), GREGORIAN_CALENDAR) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Ramazanski Bajram")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Kurban Bajram")) + + def _populate_subdiv_holidays(self): + if not self.subdiv: + # New Year's Day. + name = tr("Nova godina") + self._add_new_years_day(name) + self._add_new_years_day_two(name) + + # Orthodox Christmas Day. + self._add_christmas_day(tr("Božić (Pravoslavni)")) + + # International Labor Day. + name = tr("Međunarodni praznik rada") + self._add_labor_day(name) + self._add_labor_day_two(name) + + # Catholic Christmas Day. + self._add_christmas_day(tr("Božić (Katolički)"), GREGORIAN_CALENDAR) + + super()._populate_subdiv_holidays() + + def _populate_subdiv_bih_public_holidays(self): + # New Year's Day. + name = tr("Nova godina") + self._add_observed(self._add_new_years_day(name), rule=SUN_TO_NEXT_TUE) + self._add_new_years_day_two(name) + + # Orthodox Christmas Eve. + self._add_christmas_eve(tr("Badnji dan (Pravoslavni)")) + + # Orthodox Christmas Day. + self._add_christmas_day(tr("Božić (Pravoslavni)")) + + # Independence Day. + self._add_holiday_mar_1(tr("Dan nezavisnosti")) + + # Catholic Good Friday. + self._add_good_friday(tr("Veliki petak (Katolički)"), GREGORIAN_CALENDAR) + + # Catholic Easter Sunday. + self._add_easter_sunday(tr("Uskrs (Katolički)"), GREGORIAN_CALENDAR) + + # Orthodox Easter Sunday. + self._add_easter_sunday(tr("Vaskrs (Pravoslavni)")) + + # Orthodox Easter Monday. + self._add_easter_monday(tr("Uskrsni ponedjeljak (Pravoslavni)")) + + # International Labor Day. + name = tr("Međunarodni praznik rada") + self._add_observed(self._add_labor_day(name), rule=SUN_TO_NEXT_TUE) + self._add_labor_day_two(name) + + # Victory Day. + self._add_world_war_two_victory_day(tr("Dan pobjede nad fašizmom"), is_western=False) + + # Statehood Day. + self._add_holiday_nov_25(tr("Dan državnosti")) + + # Catholic Christmas Eve. + self._add_christmas_eve(tr("Badnji dan (Katolički)"), GREGORIAN_CALENDAR) + + # Catholic Christmas Day. + self._add_christmas_day(tr("Božić (Katolički)"), GREGORIAN_CALENDAR) + + # Eid al-Fitr. + self._add_eid_al_fitr_day_two(tr("Ramazanski Bajram")) + + # Eid al-Adha. + self._add_eid_al_adha_day_two(tr("Kurban Bajram")) + + def _populate_subdiv_brc_public_holidays(self): + # New Year's Day. + name = tr("Nova godina") + self._add_observed(self._add_new_years_day(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + self._add_new_years_day_two(name) + + # Orthodox Christmas Day. + self._add_observed(self._add_christmas_day(tr("Božić (Pravoslavni)"))) + + self._add_observed( + # Day of establishment of Brčko District. + self._add_holiday_mar_8(tr("Dan uspostavljanja Brčko distrikta")) + ) + + # International Labor Day. + name = tr("Međunarodni praznik rada") + self._add_observed(self._add_labor_day(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + self._add_labor_day_two(name) + + self._add_observed( + # Catholic Christmas Day. + self._add_christmas_day(tr("Božić (Katolički)"), GREGORIAN_CALENDAR) + ) + + def _populate_subdiv_srp_public_holidays(self): + # New Year's Day. + name = tr("Nova godina") + self._add_observed(self._add_new_years_day(name), rule=SAT_TO_NEXT_MON) + self._add_new_years_day_two(name) + + # Orthodox Christmas Eve. + self._add_christmas_eve(tr("Badnji dan (Pravoslavni)")) + + # Orthodox Christmas Day. + self._add_christmas_day(tr("Božić (Pravoslavni)")) + + # Orthodox New Year. + self._add_holiday_jan_14(tr("Pravoslavna Nova godina")) + + # Catholic Good Friday. + self._add_good_friday(tr("Veliki petak (Katolički)"), GREGORIAN_CALENDAR) + + # Catholic Easter Sunday. + self._add_easter_sunday(tr("Uskrs (Katolički)"), GREGORIAN_CALENDAR) + + # Orthodox Easter Sunday. + self._add_easter_sunday(tr("Vaskrs (Pravoslavni)")) + + # Orthodox Easter Monday. + self._add_easter_monday(tr("Uskrsni ponedjeljak (Pravoslavni)")) + + # International Labor Day. + name = tr("Međunarodni praznik rada") + self._add_observed(self._add_labor_day(name), rule=SAT_TO_NEXT_MON) + self._add_labor_day_two(name) + + # Victory Day. + self._add_world_war_two_victory_day(tr("Dan pobjede nad fašizmom"), is_western=False) + + self._add_holiday_nov_21( + # Dayton Agreement Day. + tr("Dan uspostave Opšteg okvirnog sporazuma za mir u Bosni i Hercegovini") + ) + + # Catholic Christmas Eve. + self._add_christmas_eve(tr("Badnji dan (Katolički)"), GREGORIAN_CALENDAR) + + # Catholic Christmas Day. + self._add_christmas_day(tr("Božić (Katolički)"), GREGORIAN_CALENDAR) + + # Eid al-Fitr. + self._add_eid_al_fitr_day_two(tr("Ramazanski Bajram")) + + # Eid al-Adha. + self._add_eid_al_adha_day_two(tr("Kurban Bajram")) + + +class BA(BosniaAndHerzegovina): + pass + + +class BIH(BosniaAndHerzegovina): + pass + + +class BosniaAndHerzegovinaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + } + + EID_AL_FITR_DATES = { + 2001: (DEC, 17), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/botswana.py b/.venv/lib/python3.12/site-packages/holidays/countries/botswana.py new file mode 100644 index 00000000..2211f1b3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/botswana.py @@ -0,0 +1,91 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import JUL +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_TO_NEXT_MON, + SUN_TO_NEXT_MON, + SUN_TO_NEXT_TUE, +) + + +class Botswana(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Botswana holidays. + + References: + * + * + * + * + """ + + country = "BW" + observed_label = "%s (observed)" + start_year = 1966 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, BotswanaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1995) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self._add_observed(self._add_new_years_day("New Year's Day"), rule=SUN_TO_NEXT_TUE) + self._add_observed(self._add_new_years_day_two("New Year's Day Holiday")) + + self._add_good_friday("Good Friday") + + self._add_holy_saturday("Holy Saturday") + + self._add_easter_monday("Easter Monday") + + self._add_observed(may_1 := self._add_labor_day("Labour Day")) + if self._year >= 2016: + self._add_observed( + may_1, name="Labour Day Holiday", rule=SAT_TO_NEXT_MON, show_observed_label=False + ) + + self._add_ascension_thursday("Ascension Day") + + self._add_observed(self._add_holiday_jul_1("Sir Seretse Khama Day")) + + self._add_holiday_3rd_mon_of_jul("President's Day") + self._add_holiday_1_day_past_3rd_mon_of_jul("President's Day Holiday") + + self._add_observed(self._add_holiday_sep_30("Botswana Day"), rule=SUN_TO_NEXT_TUE) + self._add_observed(self._add_holiday_oct_1("Botswana Day Holiday")) + + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + self._add_observed(dec_26 := self._add_christmas_day_two("Boxing Day")) + + if self._year >= 2016: + self._add_observed( + dec_26, name="Boxing Day Holiday", rule=SAT_TO_NEXT_MON, show_observed_label=False + ) + + +class BW(Botswana): + pass + + +class BWA(Botswana): + pass + + +class BotswanaStaticHolidays: + special_public_holidays = { + 2019: (JUL, 2, "Public Holiday"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/brazil.py b/.venv/lib/python3.12/site-packages/holidays/countries/brazil.py new file mode 100644 index 00000000..69d02ad3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/brazil.py @@ -0,0 +1,391 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, MAR, SEP, NOV +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, TUE_WED_THU_TO_NEXT_FRI + + +class Brazil(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Brazil holidays. + + References: + * + * [Decreto n. 155-B, de 14.01.1890](https://web.archive.org/web/20241226133739/https://www2.camara.leg.br/legin/fed/decret/1824-1899/decreto-155-b-14-janeiro-1890-517534-publicacaooriginal-1-pe.html) + * [Decreto n. 19.488, de 15.12.1930](https://web.archive.org/web/20241006041503/http://camara.leg.br/legin/fed/decret/1930-1939/decreto-19488-15-dezembro-1930-508040-republicacao-85201-pe.html) + * [Lei n. 662, de 6.04.1949](https://web.archive.org/web/20240913060643/https://www2.camara.leg.br/legin/fed/lei/1940-1949/lei-662-6-abril-1949-347136-publicacaooriginal-1-pl.html) + * [Lei n. 14.759, de 21.12.2023](https://web.archive.org/web/20250402234552/https://www2.camara.leg.br/legin/fed/lei/2023/lei-14759-21-dezembro-2023-795091-publicacaooriginal-170522-pl.html) + """ + + country = "BR" + default_language = "pt_BR" + # Decreto n. 155-B, de 14.01.1890 + start_year = 1890 + subdivisions = ( + "AC", + "AL", + "AM", + "AP", + "BA", + "CE", + "DF", + "ES", + "GO", + "MA", + "MG", + "MS", + "MT", + "PA", + "PB", + "PE", + "PI", + "PR", + "RJ", + "RN", + "RO", + "RR", + "RS", + "SC", + "SE", + "SP", + "TO", + ) + subdivisions_aliases = { + "Acre": "AC", + "Alagoas": "AL", + "Amazonas": "AM", + "Amapá": "AP", + "Bahia": "BA", + "Ceará": "CE", + "Distrito Federal": "DF", + "Espírito Santo": "ES", + "Goiás": "GO", + "Maranhão": "MA", + "Minas Gerais": "MG", + "Mato Grosso do Sul": "MS", + "Mato Grosso": "MT", + "Pará": "PA", + "Paraíba": "PB", + "Pernambuco": "PE", + "Piauí": "PI", + "Paraná": "PR", + "Rio de Janeiro": "RJ", + "Rio Grande do Norte": "RN", + "Rondônia": "RO", + "Roraima": "RR", + "Rio Grande do Sul": "RS", + "Santa Catarina": "SC", + "Sergipe": "SE", + "São Paulo": "SP", + "Tocantins": "TO", + } + supported_categories = (OPTIONAL, PUBLIC) + supported_languages = ("en_US", "pt_BR", "uk") + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Universal Fraternization Day. + self._add_new_years_day(tr("Confraternização Universal")) + + if 1892 <= self._year <= 1930: + # Republic Constitution Day. + self._add_holiday_feb_24(tr("Constituição da Republica")) + + # Good Friday. + self._add_good_friday(tr("Sexta-feira Santa")) + + if self._year not in {1931, 1932}: + # Tiradentes' Day. + self._add_holiday_apr_21(tr("Tiradentes")) + + if self._year >= 1925: + # Worker's Day. + self._add_labor_day(tr("Dia do Trabalhador")) + + if self._year <= 1930 or 1936 <= self._year <= 1948: + # Discovery of Brazil. + self._add_holiday_may_3(tr("Descobrimento do Brasil")) + + if self._year <= 1930: + # Abolition of slavery in Brazil. + self._add_holiday_may_13(tr("Abolição da escravidão no Brasil")) + + # Freedom and Independence of American Peoples. + self._add_holiday_jul_14(tr("Liberdade e Independência dos Povos Americanos")) + + # Independence Day. + self._add_holiday_sep_7(tr("Independência do Brasil")) + + if self._year <= 1930 or 1936 <= self._year <= 1948: + # Discovery of America. + self._add_columbus_day(tr("Descobrimento da América")) + + if self._year >= 1980: + # Our Lady of Aparecida. + self._add_holiday_oct_12(tr("Nossa Senhora Aparecida")) + + # All Souls' Day. + self._add_all_souls_day(tr("Finados")) + + # Republic Proclamation Day. + self._add_holiday_nov_15(tr("Proclamação da República")) + + if self._year >= 2024: + # National Day of Zumbi and Black Awareness. + self._add_holiday_nov_20(tr("Dia Nacional de Zumbi e da Consciência Negra")) + + if self._year >= 1922: + # Christmas Day. + self._add_christmas_day(tr("Natal")) + + def _populate_optional_holidays(self): + # Carnival. + name = tr("Carnaval") + self._add_carnival_monday(name) + self._add_carnival_tuesday(name) + + # Ash Wednesday. + self._add_ash_wednesday(tr("Início da Quaresma")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + # Public Servant's Day. + self._add_holiday_oct_28(tr("Dia do Servidor Público")) + + # Christmas Eve. + self._add_christmas_eve(tr("Véspera de Natal")) + + # New Year's Eve. + self._add_new_years_eve(tr("Véspera de Ano-Novo")) + + def _populate_subdiv_holidays(self): + # Lei n. 9.093, de 12.09.1995 + if self._year >= 1996: + super()._populate_subdiv_holidays() + + def _populate_subdiv_ac_public_holidays(self): + def get_movable_acre(*args) -> date: + dt = date(self._year, *args) + return ( + dt_observed + if self._year >= 2009 + and (dt_observed := self._get_observed_date(dt, TUE_WED_THU_TO_NEXT_FRI)) + else dt + ) + + if self._year >= 2005: + # Evangelical Day. + self._add_holiday(tr("Dia do Evangélico"), get_movable_acre(JAN, 23)) + + if self._year >= 2002: + # International Women's Day. + self._add_holiday(tr("Dia Internacional da Mulher"), get_movable_acre(MAR, 8)) + + # Founding of Acre. + self._add_holiday_jun_15(tr("Aniversário do Acre")) + + if self._year >= 2004: + # Amazonia Day. + self._add_holiday(tr("Dia da Amazônia"), get_movable_acre(SEP, 5)) + + # Signing of the Petropolis Treaty. + self._add_holiday(tr("Assinatura do Tratado de Petrópolis"), get_movable_acre(NOV, 17)) + + def _populate_subdiv_al_public_holidays(self): + # Saint John's Day. + self._add_saint_johns_day(tr("São João")) + + # Saint Peter's Day. + self._add_saints_peter_and_paul_day(tr("São Pedro")) + + # Political Emancipation of Alagoas. + self._add_holiday_sep_16(tr("Emancipação Política de Alagoas")) + + if self._year <= 2023: + # Black Awareness Day. + self._add_holiday_nov_20(tr("Consciência Negra")) + + if self._year >= 2013: + self._add_holiday_nov_30(tr("Dia do Evangélico")) + + def _populate_subdiv_am_public_holidays(self): + # Elevation of Amazonas to province. + self._add_holiday_sep_5(tr("Elevação do Amazonas à categoria de província")) + + if 2010 <= self._year <= 2023: + self._add_holiday_nov_20(tr("Consciência Negra")) + + def _populate_subdiv_ap_public_holidays(self): + if self._year >= 2003: + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("São José")) + + if self._year >= 2012: + # Saint James' Day. + self._add_saint_james_day(tr("São Tiago")) + + # Creation of the Federal Territory. + self._add_holiday_sep_13(tr("Criação do Território Federal")) + + if 2008 <= self._year <= 2023: + self._add_holiday_nov_20(tr("Consciência Negra")) + + def _populate_subdiv_ba_public_holidays(self): + # Bahia Independence Day. + self._add_holiday_jul_2(tr("Independência da Bahia")) + + def _populate_subdiv_ce_public_holidays(self): + self._add_saint_josephs_day(tr("São José")) + + # Abolition of slavery in Ceará. + self._add_holiday_mar_25(tr("Abolição da escravidão no Ceará")) + + if self._year >= 2004: + # Our Lady of Assumption. + self._add_assumption_of_mary_day(tr("Nossa Senhora da Assunção")) + + def _populate_subdiv_df_public_holidays(self): + # Founding of Brasilia. + self._add_holiday_apr_21(tr("Fundação de Brasília")) + + self._add_holiday_nov_30(tr("Dia do Evangélico")) + + def _populate_subdiv_es_public_holidays(self): + if self._year >= 2020: + # Our Lady of Penha. + self._add_holiday_8_days_past_easter(tr("Nossa Senhora da Penha")) + + def _populate_subdiv_go_public_holidays(self): + # Foundation of Goiás city. + self._add_holiday_jul_26(tr("Fundação da cidade de Goiás")) + + # Foundation of Goiânia. + self._add_holiday_oct_24(tr("Pedra fundamental de Goiânia")) + + def _populate_subdiv_ma_public_holidays(self): + # Maranhão joining to independence of Brazil. + self._add_holiday_jul_28(tr("Adesão do Maranhão à independência do Brasil")) + + def _populate_subdiv_mg_public_holidays(self): + # Tiradentes' Execution. + self._add_holiday_apr_21(tr("Execução de Tiradentes")) + + def _populate_subdiv_ms_public_holidays(self): + # State Creation Day. + self._add_holiday_oct_11(tr("Criação do Estado")) + + def _populate_subdiv_mt_public_holidays(self): + if 2003 <= self._year <= 2023: + self._add_holiday_nov_20(tr("Consciência Negra")) + + def _populate_subdiv_pa_public_holidays(self): + # Grão-Pará joining to independence of Brazil. + self._add_holiday_aug_15(tr("Adesão do Grão-Pará à independência do Brasil")) + + def _populate_subdiv_pb_public_holidays(self): + # State Founding Day. + self._add_holiday_aug_5(tr("Fundação do Estado")) + + def _populate_subdiv_pe_public_holidays(self): + if self._year >= 2008: + # Pernambuco Revolution. + self._add_holiday_1st_sun_of_mar(tr("Revolução Pernambucana")) + + def _populate_subdiv_pi_public_holidays(self): + # Piauí Day. + self._add_holiday_oct_19(tr("Dia do Piauí")) + + def _populate_subdiv_pr_public_holidays(self): + # Political Emancipation of Paraná. + self._add_holiday_dec_19(tr("Emancipação do Paraná")) + + def _populate_subdiv_rj_public_holidays(self): + if self._year >= 2008: + # Saint George's Day. + self._add_saint_georges_day(tr("São Jorge")) + + if 2002 <= self._year <= 2023: + self._add_holiday_nov_20(tr("Consciência Negra")) + + def _populate_subdiv_rn_public_holidays(self): + if self._year >= 2000: + # Rio Grande do Norte Day. + self._add_holiday_aug_7(tr("Dia do Rio Grande do Norte")) + + if self._year >= 2007: + # Uruaçu and Cunhaú Martyrs Day. + self._add_holiday_oct_3(tr("Mártires de Cunhaú e Uruaçu")) + + def _populate_subdiv_ro_public_holidays(self): + self._add_holiday_jan_4(tr("Criação do Estado")) + + if self._year >= 2002: + self._add_holiday_jun_18(tr("Dia do Evangélico")) + + def _populate_subdiv_rr_public_holidays(self): + self._add_holiday_oct_5(tr("Criação do Estado")) + + def _populate_subdiv_rs_public_holidays(self): + # Gaucho Day. + self._add_holiday_sep_20(tr("Dia do Gaúcho")) + + def _populate_subdiv_sc_public_holidays(self): + if self._year >= 2004: + # Santa Catarina State Day. + name = tr("Dia do Estado de Santa Catarina") + if self._year >= 2005: + self._add_holiday_1st_sun_from_aug_11(name) + else: + self._add_holiday_aug_11(name) + + # Saint Catherine of Alexandria Day. + name = tr("Dia de Santa Catarina de Alexandria") + if 1999 <= self._year != 2004: + self._add_holiday_1st_sun_from_nov_25(name) + else: + self._add_holiday_nov_25(name) + + def _populate_subdiv_se_public_holidays(self): + # Sergipe Political Emancipation Day. + self._add_holiday_jul_8(tr("Emancipação política de Sergipe")) + + def _populate_subdiv_sp_public_holidays(self): + if self._year >= 1997: + # Constitutionalist Revolution. + self._add_holiday_jul_9(tr("Revolução Constitucionalista")) + + def _populate_subdiv_to_public_holidays(self): + if self._year >= 1998: + # Autonomy Day. + self._add_holiday_mar_18(tr("Dia da Autonomia")) + + # Our Lady of Nativity. + self._add_nativity_of_mary_day(tr("Nossa Senhora da Natividade")) + + self._add_holiday_oct_5(tr("Criação do Estado")) + + +class BR(Brazil): + pass + + +class BRA(Brazil): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/british_virgin_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/british_virgin_islands.py new file mode 100644 index 00000000..09ebb109 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/british_virgin_islands.py @@ -0,0 +1,205 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAY, JUN, OCT, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_TO_PREV_FRI, + SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class BritishVirginIslands( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """British Virgin Islands holidays. + + References: + * + * [Public Holidays (Amendment) Act, 2021](https://web.archive.org/web/20250522154946/https://laws.gov.vg/Laws/public-holidays-amendment-act-2021) + * + * [2015](https://web.archive.org/web/20250317055722/https://www.bvi.gov.vg/media-centre/2015-public-holidays) + * [2016](https://web.archive.org/web/20250323113905/https://www.bvi.gov.vg/media-centre/2016-public-holidays) + * [2017](https://web.archive.org/web/20250515155409/https://bvi.gov.vg/media-centre/2017-public-holidays) + * [2018](https://web.archive.org/web/20250318095807/https://www.bvi.gov.vg/media-centre/2018-public-holidays) + * [2019](https://web.archive.org/web/20250315162108/https://www.bvi.gov.vg/media-centre/2019-public-holidays) + * [2020](https://web.archive.org/web/20250111172241/https://www.bvi.gov.vg/media-centre/2020-public-holidays) + * [2021](https://web.archive.org/web/20250417222246/http://www.bvi.gov.vg/media-centre/2021-public-holidays-revised) + * [2022](https://web.archive.org/web/20250420005523/https://www.bvi.gov.vg/media-centre/revised-2022-public-holidays) + * [2023](https://web.archive.org/web/20250111170511/https://bvi.gov.vg/media-centre/updatedofficialholidays20231) + * [2024](https://web.archive.org/web/20250502194703/https://www.bvi.gov.vg/media-centre/cabinet-approves-2024-public-holidays) + * [2025](https://web.archive.org/web/20250124122752/https://bvi.gov.vg/media-centre/cabinet-approves-2025-holidays) + """ + + country = "VG" + default_language = "en_VG" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_US", "en_VG") + start_year = 1967 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, BritishVirginIslandsStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 2000) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + self._add_holiday_1st_mon_before_mar_7( + # Lavity Stoutt's Birthday. + tr("The Anniversary of the Birth of Hamilton Lavity Stoutt") + ) + + if self._year <= 2020: + # Commonwealth Day. + self._add_holiday_2nd_mon_of_mar(tr("Commonwealth Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Whit Monday. + self._add_whit_monday(tr("Whit Monday")) + + # Sovereign's Birthday. + name = tr("Sovereign's Birthday") + if self._year >= 2019: + sovereign_birthday_dates = { + 2019: (JUN, 7), + 2023: (JUN, 16), + } + if dt := sovereign_birthday_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_2nd_fri_of_jun(name) + else: + self._add_holiday_2nd_sat_of_jun(name) + + name = ( + # Virgin Islands Day. + tr("Virgin Islands Day") + if self._year >= 2021 + # Territory Day. + else tr("Territory Day") + if self._year >= 1978 + # Colony Day. + else tr("Colony Day") + ) + territory_day_dates = { + 2015: (JUN, 29), + 2020: (JUN, 29), + } + if dt := territory_day_dates.get(self._year): + self._add_holiday(name, dt) + else: + if self._year >= 2021: + self._add_holiday_1st_mon_of_jul(name) + else: + self._add_observed( + self._add_holiday_jul_1(name), rule=SAT_TO_PREV_FRI + SUN_TO_NEXT_MON + ) + + self._add_holiday_1st_mon_of_aug( + # Emancipation Monday. + tr("Emancipation Monday") + if self._year >= 2021 + # Festival Monday. + else tr("Festival Monday") + ) + + self._add_holiday_1_day_past_1st_mon_of_aug( + # Emancipation Tuesday. + tr("Emancipation Tuesday") + if self._year >= 2021 + # Festival Tuesday. + else tr("Festival Tuesday") + ) + + self._add_holiday_2_days_past_1st_mon_of_aug( + # Emancipation Wednesday. + tr("Emancipation Wednesday") + if self._year >= 2021 + # Festival Wednesday. + else tr("Festival Wednesday") + ) + + if self._year <= 2020: + # Saint Ursula's Day. + name = tr("Saint Ursula's Day") + saint_ursula_dates = { + 2015: (OCT, 19), + 2020: (OCT, 23), + } + if dt := saint_ursula_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_observed( + self._add_holiday_oct_21(name), rule=SAT_TO_PREV_FRI + SUN_TO_NEXT_MON + ) + + if self._year >= 2021: + # Heroes and Foreparents Day. + self._add_holiday_3rd_mon_of_oct(tr("Heroes and Foreparents Day")) + + # The Great March of 1949 and Restoration Day. + self._add_holiday_4th_mon_of_nov(tr("The Great March of 1949 and Restoration Day")) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + +class VG(BritishVirginIslands): + pass + + +class VGB(BritishVirginIslands): + pass + + +class BritishVirginIslandsStaticHolidays: + """British Virgin Islands special holidays. + + References: + * [2019](https://web.archive.org/web/20250417134346/https://www.bvi.gov.vg/media-centre/public-holiday-be-observed-funeral-late-honourable-ralph-t-o-neal-obe) + * [2022](https://web.archive.org/web/20250315174707/https://www.bvi.gov.vg/media-centre/public-holiday-observe-her-majesty-s-platinum-jubilee) + * [2023](https://web.archive.org/web/20250505073654/https://bvi.gov.vg/media-centre/may-8-and-june-16-declared-public-holidays) + """ + + special_public_holidays = { + # State Funeral of Honourable Ralph T. O'Neal. + 2019: (DEC, 11, tr("State Funeral of Honourable Ralph T. O'Neal")), + # Platinum Jubilee of Elizabeth II. + 2022: (JUN, 3, tr("Queen Elizabeth II's Platinum Jubilee")), + # Coronation of Charles III. + 2023: (MAY, 8, tr("The King's Coronation")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/brunei.py b/.venv/lib/python3.12/site-packages/holidays/countries/brunei.py new file mode 100644 index 00000000..0c1d5e69 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/brunei.py @@ -0,0 +1,509 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + FRI, + SUN, +) +from holidays.groups import ( + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + FRI_TO_NEXT_MON, + FRI_TO_NEXT_SAT, + SUN_TO_NEXT_TUE, + SUN_TO_NEXT_WED, + FRI_SUN_TO_NEXT_SAT_MON, +) + + +class Brunei( + ObservedHolidayBase, + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Brunei holidays. + + References: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + + Checked with: + * + * + * + * [Jubli Emas Sultan Hassanal Bolkiah](https://web.archive.org/web/20241127203518/https://www.brudirect.com/news.php?id=28316) + """ + + country = "BN" + default_language = "ms" + # %s (estimated). + estimated_label = tr("%s (anggaran)") + # %s (observed). + observed_label = tr("%s (diperhatikan)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (diperhatikan, anggaran)") + supported_languages = ("en_US", "ms", "th") + weekend = {FRI, SUN} + # Available post-Independence from 1984 afterwards + start_year = 1984 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChineseCalendarHolidays.__init__(self) + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=BruneiIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=BruneiStaticHolidays) + kwargs.setdefault("observed_rule", FRI_SUN_TO_NEXT_SAT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Awal Tahun Masihi + # Status: In-Use. + + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("Awal Tahun Masihi"))) + + # Tahun Baru Cina + # Status: In-Use. + + # Lunar New Year. + self._add_observed(self._add_chinese_new_years_day(tr("Tahun Baru Cina"))) + + # Hari Kebangsaan + # Status: In-Use. + # Starts in 1984. + + # National Day. + self._add_observed(self._add_holiday_feb_23(tr("Hari Kebangsaan"))) + + # Hari Angkatan Bersenjata Diraja Brunei + # Status: In-Use. + # Starts in 1984. + # Commemorates the formation of Royal Brunei Malay Regiment in 1961. + + self._add_observed( + # Armed Forces Day. + self._add_holiday_may_31(tr("Hari Angkatan Bersenjata Diraja Brunei")) + ) + + # Hari Keputeraan KDYMM Sultan Brunei + # Status: In-Use. + # Started in 1968. + + self._add_observed( + # Sultan Hassanal Bolkiah's Birthday. + self._add_holiday_jul_15(tr("Hari Keputeraan KDYMM Sultan Brunei")) + ) + + # Hari Natal + # Status: In-Use. + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Hari Natal"))) + + # Islamic Holidays are placed after Gregorian holidays to prevent + # the duplication of observed tags. - see #1168 + + # Israk dan Mikraj + # Status: In-Use. + + # Isra' and Mi'raj. + for dt in self._add_isra_and_miraj_day(tr("Israk dan Mikraj")): + self._add_observed(dt) + + # Hari Pertama Berpuasa + # Status: In-Use. + + # First Day of Ramadan. + for dt in self._add_ramadan_beginning_day(tr("Hari Pertama Berpuasa")): + self._add_observed(dt) + + # Hari Nuzul Al-Quran + # Status: In-Use. + + # Anniversary of the revelation of the Quran. + for dt in self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")): + self._add_observed(dt) + + # Hari Raya Aidil Fitri + # Status: In-Use. + # This is celebrate for three days in Brunei. + # 1: If Wed-Thu-Fri -> Sat (3rd Day +1) + # 2: If Thu-Fri-Sat -> Mon (2nd Day +3) + # 3: If Fri-Sat-Sun -> Mon, Tue (1st Day +3, 3rd day +2) + # 4: If Sat-Sun-Mon -> Tue (2nd Day +2) + # 5: If Sun-Mon-Tue -> Wed (1st Day +3) + # Observed as 'Hari Raya Puasa' and only for 2 days prior to 2012. + # 1: If Thu-Fri -> Sat (2nd Day +1) + # 2: If Fri-Sat -> Mon (1nd Day +2) + # 3: If Sat-Sun -> Mon (2nd Day +1) + # 4: If Sun-Mon -> Tue (1st Day +2) + # This was only observed for a single day in 2000. + + # Eid al-Fitr. + name = tr("Hari Raya Aidil Fitri") + if self._year >= 2012: + for dt in self._add_eid_al_fitr_day(name): + self._add_observed(dt, rule=FRI_TO_NEXT_MON + SUN_TO_NEXT_WED) + for dt in self._add_eid_al_fitr_day_two(name): + self._add_observed(dt, rule=FRI_TO_NEXT_MON + SUN_TO_NEXT_TUE) + for dt in self._add_eid_al_fitr_day_three(name): + self._add_observed(dt, rule=FRI_TO_NEXT_SAT + SUN_TO_NEXT_TUE) + elif self._year == 2000: + for dt in self._add_eid_al_fitr_day(name): + self._add_observed(dt) + else: + for dt in self._add_eid_al_fitr_day(name): + self._add_observed(dt, rule=FRI_TO_NEXT_MON + SUN_TO_NEXT_TUE) + for dt in self._add_eid_al_fitr_day_two(name): + self._add_observed(dt) + + # Hari Raya Aidil Adha + # Status: In-Use. + + # Eid al-Adha. + for dt in self._add_eid_al_adha_day(tr("Hari Raya Aidil Adha")): + self._add_observed(dt) + + # Awal Tahun Hijrah + # Status: In-Use. + + # Islamic New Year. + for dt in self._add_islamic_new_year_day(tr("Awal Tahun Hijrah")): + self._add_observed(dt) + + # Maulidur Rasul + # Status: In-Use. + + # Prophet's Birthday. + for dt in self._add_mawlid_day(tr("Maulidur Rasul")): + self._add_observed(dt) + + +class BN(Brunei): + pass + + +class BRN(Brunei): + pass + + +class BruneiIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 1998: (APR, 7), + 1999: (MAR, 28), + 2000: (MAR, 17), + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 11), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 27), + 2010: (NOV, 16), + 2011: (NOV, 6), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 1998: (JAN, 30), + 1999: (JAN, 19), + 2000: ((JAN, 8), (DEC, 27)), + 2001: (DEC, 16), + 2002: (DEC, 6), + 2003: (NOV, 25), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 1), + 2009: (SEP, 20), + 2010: (SEP, 10), + 2011: (AUG, 30), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 6), + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + HIJRI_NEW_YEAR_DATES = { + 1998: (APR, 28), + 1999: (APR, 17), + 2000: (APR, 6), + 2001: (MAR, 26), + 2002: (MAR, 15), + 2003: (MAR, 4), + 2004: (FEB, 22), + 2005: (FEB, 10), + 2006: (JAN, 31), + 2007: (JAN, 20), + 2008: ((JAN, 10), (DEC, 29)), + 2009: (DEC, 18), + 2010: (DEC, 7), + 2011: (NOV, 27), + 2012: (NOV, 15), + 2013: (NOV, 5), + 2014: (OCT, 25), + 2015: (OCT, 14), + 2016: (OCT, 2), + 2017: (SEP, 22), + 2018: (SEP, 11), + 2019: (SEP, 1), + 2020: (AUG, 20), + 2021: (AUG, 10), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 7), + 2025: (JUN, 27), + } + + ISRA_AND_MIRAJ_DATES = { + 1998: (NOV, 17), + 1999: (NOV, 6), + 2000: (OCT, 25), + 2001: (OCT, 15), + 2002: (OCT, 4), + 2003: (SEP, 24), + 2004: (SEP, 12), + 2005: (SEP, 1), + 2006: (AUG, 21), + 2007: (AUG, 11), + 2008: (JUL, 30), + 2009: (JUL, 20), + 2010: (JUL, 10), + 2011: (JUN, 29), + 2012: (JUN, 17), + 2013: (JUN, 6), + 2014: (MAY, 27), + 2015: (MAY, 16), + 2016: (MAY, 5), + 2017: (APR, 24), + 2018: (APR, 14), + 2019: (APR, 3), + 2020: (MAR, 22), + 2021: (MAR, 11), + 2022: (FEB, 28), + 2023: (FEB, 18), + 2024: (FEB, 8), + 2025: (JAN, 27), + } + + MAWLID_DATES = { + 1998: (JUL, 6), + 1999: (JUN, 26), + 2000: (JUN, 15), + 2001: (JUN, 4), + 2002: (MAY, 25), + 2003: (MAY, 14), + 2004: (MAY, 2), + 2005: (APR, 21), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 15), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 20), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 8), + 2023: (SEP, 28), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + NUZUL_AL_QURAN_DATES = { + 1998: (JAN, 16), + 1999: ((JAN, 5), (DEC, 25)), + 2000: (DEC, 13), + 2001: (DEC, 3), + 2002: (NOV, 22), + 2003: (NOV, 12), + 2004: (NOV, 1), + 2005: (OCT, 21), + 2006: (OCT, 10), + 2007: (SEP, 29), + 2008: (SEP, 18), + 2009: (SEP, 7), + 2010: (AUG, 27), + 2011: (AUG, 17), + 2012: (AUG, 6), + 2013: (JUL, 26), + 2014: (JUL, 15), + 2015: (JUL, 4), + 2016: (JUN, 22), + 2017: (JUN, 12), + 2018: (JUN, 2), + 2019: (MAY, 22), + 2020: (MAY, 10), + 2021: (APR, 29), + 2022: (APR, 19), + 2023: (APR, 8), + 2024: (MAR, 28), + 2025: (MAR, 18), + } + + RAMADAN_BEGINNING_DATES = { + 1998: (DEC, 20), + 1999: (DEC, 9), + 2000: (NOV, 27), + 2001: (NOV, 17), + 2002: (NOV, 6), + 2003: (OCT, 27), + 2004: (OCT, 16), + 2005: (OCT, 5), + 2006: (SEP, 24), + 2007: (SEP, 13), + 2008: (SEP, 1), + 2009: (AUG, 22), + 2010: (AUG, 11), + 2011: (AUG, 1), + 2012: (JUL, 21), + 2013: (JUL, 10), + 2014: (JUN, 29), + 2015: (JUN, 18), + 2016: (JUN, 6), + 2017: (MAY, 27), + 2018: (MAY, 17), + 2019: (MAY, 6), + 2020: (APR, 24), + 2021: (APR, 13), + 2022: (APR, 3), + 2023: (MAR, 23), + 2024: (MAR, 12), + 2025: (MAR, 2), + } + + +class BruneiStaticHolidays: + special_public_holidays = { + 1998: ( + AUG, + 10, + # Proclamation Ceremony of Crown Prince Al-Muhtadee Billah of Brunei. + tr("Istiadat Pengisytiharan Duli Pengiran Muda Mahkota Al-Muhtadee Billah"), + ), + # Royal Wedding of Crown Prince Al-Muhtadee Billah and Crown Princess Sarah of Brunei. + 2004: (SEP, 9, tr("Istiadat Perkahwinan Diraja Brunei 2004")), + # Sultan Hassanal Bolkiah's Golden Jubilee celebration. + 2017: (OCT, 5, tr("Jubli Emas Sultan Hassanal Bolkiah")), + } + special_public_holidays_observed = { + # Christmas Day. + 1999: (DEC, 27, tr("Hari Natal")), + # National Day. + 2002: (FEB, 25, tr("Hari Kebangsaan")), + # New Year's Day. + 2007: (JAN, 2, tr("Awal Tahun Masihi")), + # Anniversary of the revelation of the Quran. + 2014: (JUL, 16, tr("Hari Nuzul Al-Quran")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/bulgaria.py b/.venv/lib/python3.12/site-packages/holidays/countries/bulgaria.py new file mode 100644 index 00000000..ce57d37e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/bulgaria.py @@ -0,0 +1,138 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.julian_revised import JULIAN_REVISED_CALENDAR +from holidays.constants import PUBLIC, SCHOOL +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class Bulgaria(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Bulgaria holidays. + + References: + * + * + * + * + + Official holidays in Bulgaria in their current form. This class does not + any return holidays before 1990, as holidays in the People's Republic of + Bulgaria and earlier were different. + + Since 2017, it has been accepted that public holidays in Bulgaria that fall on a Saturday + or Sunday are to be taken on the first working day after them. If there are both Saturday + and Sunday holidays, Monday and Tuesday are rested respectively. + The exceptions are: + 1) the Easter holidays, which are always a consecutive Friday, Saturday, and Sunday; + 2) National Awakening Day which, while an official holiday and a non-attendance day for + schools, is still a working day. + """ + + country = "BG" + default_language = "bg" + # %s (observed). + observed_label = tr("%s (почивен ден)") + supported_categories = (PUBLIC, SCHOOL) + supported_languages = ("bg", "en_US", "uk") + start_year = 1990 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_REVISED_CALENDAR) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 2017) + super().__init__(*args, **kwargs) + + def _populate_observed(self, dts: set[date], excluded_names: set[str]) -> None: + for dt in sorted(dts): + if not self._is_observed(dt): + continue + for name in self.get_list(dt): + if name not in excluded_names: + self._add_observed(dt, name) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("Нова година"))) + + dts_observed.add( + # Liberation Day. + self._add_holiday_mar_3(tr("Ден на Освобождението на България от османско иго")) + ) + + # Good Friday. + self._add_good_friday(tr("Велики петък")) + + # Holy Saturday. + self._add_holy_saturday(tr("Велика събота")) + + # Easter. + name = tr("Великден") + self._add_easter_sunday(name) + self._add_easter_monday(name) + + dts_observed.add( + # International Workers' Day. + self._add_labor_day(tr("Ден на труда и на международната работническа солидарност")) + ) + + dts_observed.add( + # Saint George's Day. + self._add_holiday_may_6(tr("Гергьовден, Ден на храбростта и Българската армия")) + ) + + dts_observed.add( + self._add_holiday_may_24( + # Bulgarian Education and Culture and Slavonic Literature Day. + tr( + "Ден на светите братя Кирил и Методий, на българската азбука, " + "просвета и култура и на славянската книжовност" + ) + ) + ) + + # Unification Day. + dts_observed.add(self._add_holiday_sep_6(tr("Ден на Съединението"))) + + # Independence Day. + dts_observed.add(self._add_holiday_sep_22(tr("Ден на Независимостта на България"))) + + # Christmas Eve. + dts_observed.add(self._add_christmas_eve(tr("Бъдни вечер"))) + + # Christmas Day. + name = tr("Рождество Христово") + dts_observed.add(self._add_christmas_day(name)) + dts_observed.add(self._add_christmas_day_two(name)) + + if self.observed: + self._populate_observed( + dts_observed, excluded_names={self.tr("Велика събота"), self.tr("Великден")} + ) + + def _populate_school_holidays(self): + # National Awakening Day. + self._add_holiday_nov_1(tr("Ден на народните будители")) + + +class BG(Bulgaria): + pass + + +class BLG(Bulgaria): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/burkina_faso.py b/.venv/lib/python3.12/site-packages/holidays/countries/burkina_faso.py new file mode 100644 index 00000000..8faf867f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/burkina_faso.py @@ -0,0 +1,144 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class BurkinaFaso(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Burkina Faso holidays. + + References: + * + """ + + country = "BF" + observed_label = "%s (observed)" + # On 5 August 1960, Burkina Faso (Republic of Upper Volta at that time) + # gained independence from France. + start_year = 1961 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=BurkinaFasoIslamicHolidays, show_estimated=islamic_show_estimated + ) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + if self._year >= 1967: + # Revolution Day. + self._add_observed(self._add_holiday_jan_3("Revolution Day")) + + # International Women's Day. + self._add_observed(self._add_womens_day("International Women's Day")) + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Labour Day. + self._add_observed(self._add_labor_day("Labour Day")) + + # Ascension Day. + self._add_ascension_thursday("Ascension Day") + + # Independence Day. + self._add_observed(self._add_holiday_aug_5("Independence Day")) + + # Assumption Day. + self._add_observed(self._add_assumption_of_mary_day("Assumption Day")) + + if self._year >= 2016: + # Martyrs' Day. + self._add_observed(self._add_holiday_oct_31("Martyrs' Day")) + + # All Saints' Day. + self._add_observed(self._add_all_saints_day("All Saints' Day")) + + self._add_observed( + # Proclamation of Independence Day. + self._add_holiday_dec_11("Proclamation of Independence Day") + ) + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day("Eid al-Fitr") + + # Eid al-Adha. + self._add_eid_al_adha_day("Eid al-Adha") + + # Mawlid. + self._add_mawlid_day("Mawlid") + + +class BF(BurkinaFaso): + pass + + +class BFA(BurkinaFaso): + pass + + +class BurkinaFasoIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + } + + EID_AL_FITR_DATES = { + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + } + + MAWLID_DATES = { + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 9), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/burundi.py b/.venv/lib/python3.12/site-packages/holidays/countries/burundi.py new file mode 100644 index 00000000..1093b258 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/burundi.py @@ -0,0 +1,100 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.groups import ChristianHolidays, IslamicHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Burundi(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Burundi holidays. + + References: + * + + Note that holidays falling on a sunday maybe observed on the following Monday. + This depends on formal announcements by the government, which only happens close + to the date of the holiday. + """ + + country = "BI" + observed_label = "%s (observed)" + start_year = 1962 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Unity Day + if self._year >= 1992: + self._add_observed(self._add_holiday_feb_5("Unity Day")) + + # President Ntaryamira Day + if self._year >= 1995: + self._add_observed(self._add_holiday_apr_6("President Ntaryamira Day")) + + # Labour Day + self._add_observed(self._add_labor_day("Labour Day")) + + # Ascension Day + self._add_ascension_thursday("Ascension Day") + + # President Nkurunziza Day + if self._year >= 2022: + self._add_observed(self._add_holiday_jun_8("President Nkurunziza Day")) + + # Independence Day + self._add_observed(self._add_holiday_jul_1("Independence Day")) + + # Assumption Day + self._add_observed(self._add_assumption_of_mary_day("Assumption Day")) + + # Prince Louis Rwagasore Day + self._add_observed(self._add_holiday_oct_13("Prince Louis Rwagasore Day")) + + # President Ndadaye's Day + if self._year >= 1994: + self._add_observed(self._add_holiday_oct_21("President Ndadaye's Day")) + + # All Saints' Day + self._add_observed(self._add_all_saints_day("All Saints' Day")) + + # Christmas Day + self._add_observed(self._add_christmas_day("Christmas Day")) + + # Eid ul Fitr + for dt in self._add_eid_al_fitr_day("Eid ul Fitr"): + self._add_observed(dt) + + # Eid al Adha + for dt in self._add_eid_al_adha_day("Eid al Adha"): + self._add_observed(dt) + + +class BI(Burundi): + pass + + +class BDI(Burundi): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/cabo_verde.py b/.venv/lib/python3.12/site-packages/holidays/countries/cabo_verde.py new file mode 100644 index 00000000..5ae74823 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/cabo_verde.py @@ -0,0 +1,293 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class CaboVerde(HolidayBase, ChristianHolidays, InternationalHolidays): + """Cabo Verde holidays. + + References: + * [Public holidays in Cape Verde](https://en.wikipedia.org/wiki/Public_holidays_in_Cape_Verde) + * [Legislação Municipal Cabo-Verdiana](https://web.archive.org/web/20180820172827/http://www.interface.gov.cv/index.php?option=com_docman&task=doc_download&gid=12&Itemid=314) + * [Feriados Bancários - Banco de Cabo Verde](https://web.archive.org/web/20250629042854/https://www.bcv.cv/pt/SistemadePagamentos/feriados_bancarios/Paginas/FeriadosBancarios.aspx) + * [Feriados Públicos - Feel Cabo Verde](https://web.archive.org/web/20250419201823/https://feelcaboverde.com/feriados-publicos/) + * [Public Holidays - Feel Cape Verde](https://web.archive.org/web/20250419202739/https://feelcaboverde.com/en/public-holidays-cape-verde/) + * [Democracy Day](https://web.archive.org/web/20250420093850/https://cmsv.cv/dia-da-liberdade-e-democracia-de-cabo-verde/) + """ + + country = "CV" + default_language = "pt_CV" + start_year = 1976 + subdivisions = ( + "BR", # Brava. + "BV", # Boa Vista. + "CA", # Santa Catarina. + "CF", # Santa Catarina do Fogo. + "CR", # Santa Cruz. + "MA", # Maio. + "MO", # Mosteiros. + "PA", # Paul. + "PN", # Porto Novo. + "PR", # Praia. + "RB", # Ribeira Brava + "RG", # Ribeira Grande. + "RS", # Ribeira Grande de Santiago. + "SD", # São Domingos. + "SF", # São Filipe. + "SL", # Sal. + "SM", # São Miguel. + "SO", # São Lourenço dos Órgãos. + "SS", # São Salvador do Mundo. + "SV", # São Vicente. + "TA", # Tarrafal. + "TS", # Tarrafal de São Nicolau. + ) + + subdivisions_aliases = { + "Brava": "BR", + "Boa Vista": "BV", + "Santa Catarina": "CA", + "Santa Catarina do Fogo": "CF", + "Santa Cruz": "CR", + "Maio": "MA", + "Mosteiros": "MO", + "Paul": "PA", + "Porto Novo": "PN", + "Praia": "PR", + "Ribeira Brava": "RB", + "Ribeira Grande": "RG", + "Ribeira Grande de Santiago": "RS", + "São Domingos": "SD", + "São Filipe": "SF", + "Sal": "SL", + "São Miguel": "SM", + "São Lourenço dos Órgãos": "SO", + "São Salvador do Mundo": "SS", + "São Vicente": "SV", + "Tarrafal": "TA", + "Tarrafal de São Nicolau": "TS", + } + supported_categories = (OPTIONAL, PUBLIC) + supported_languages = ("de", "en_US", "es", "fr", "pt_CV") + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Ano Novo")) + + # Law # 95/V/99 of March 22nd. + if self._year >= 2000: + # Democracy and Freedom Day. + self._add_holiday_jan_13(tr("Dia da Liberdade e da Democracia")) + + # National Heroes Day. + self._add_holiday_jan_20(tr("Dia da Nacionalidade e dos Heróis Nacionais")) + + # Ash Wednesday. + self._add_ash_wednesday(tr("Quarta-feira de Cinzas")) + + # Good Friday. + self._add_good_friday(tr("Sexta-feira Santa")) + + # Easter Sunday. + self._add_easter_sunday(tr("Páscoa")) + + # Worker's Day. + self._add_labor_day(tr("Dia do Trabalhador")) + + # Law # 69/VI/2005 of May 31st. + if self._year >= 2005: + # International Children's Day. + self._add_childrens_day(tr("Dia Mundial da Criança")) + + # Independence Day. + self._add_holiday_jul_5(tr("Dia da Independência Nacional")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Dia da Assunção")) + + # All Saints' Day. + self._add_all_saints_day(tr("Dia de Todos os Santos")) + + # Christmas Day. + self._add_christmas_day(tr("Dia do Natal")) + + def _populate_optional_holidays(self): + # Holy Thursday. + self._add_holy_thursday(tr("Quinta-Feira Santa")) + + # Mother's Day. + self._add_holiday_2nd_sun_of_may(tr("Dia das Mães")) + + # Father's Day. + self._add_holiday_3rd_sun_of_jun(tr("Dia dos Pais")) + + def _populate_subdiv_br_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Brava Municipality Day. + self._add_holiday_jun_24(tr("Dia do Município da Brava")) + + def _populate_subdiv_bv_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Boa Vista Municipality Day. + self._add_holiday_jul_4(tr("Dia do Município da Boa Vista")) + + def _populate_subdiv_ca_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1982: + # Santa Catarina de Santiago Municipality Day. + self._add_holiday_nov_25(tr("Dia do Município de Santa Catarina de Santiago")) + + def _populate_subdiv_cf_public_holidays(self): + # Law # 66/VI/2005 of May 9th. + if self._year >= 2005: + # Santa Catarina do Fogo Municipality Day. + self._add_holiday_nov_25(tr("Dia do Município de Santa Catarina do Fogo")) + + def _populate_subdiv_cr_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Santa Cruz Municipality Day. + self._add_holiday_jul_25(tr("Dia do Município de Santa Cruz")) + + def _populate_subdiv_ma_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Maio Municipality Day. + self._add_holiday_sep_8(tr("Dia do Município do Maio")) + + def _populate_subdiv_mo_public_holidays(self): + # Law # 23/IV/91 of December 30th. + if self._year >= 1992: + # Mosteiros Municipality Day. + self._add_holiday_aug_15(tr("Dia do Município dos Mosteiros")) + + def _populate_subdiv_pa_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Santo Antão Island Day. + self._add_holiday_jan_17(tr("Dia da Ilha de Santo Antão")) + + # Paúl Municipality Day. + self._add_holiday_jun_13(tr("Dia do Município do Paúl")) + + def _populate_subdiv_pn_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Santo Antão Island Day. + self._add_holiday_jan_17(tr("Dia da Ilha de Santo Antão")) + + # Porto Novo Municipality Day. + self._add_holiday_sep_2(tr("Dia do Município do Porto Novo")) + + def _populate_subdiv_pr_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Praia Municipality Day. + self._add_holiday_may_19(tr("Dia do Município da Praia")) + + def _populate_subdiv_rb_public_holidays(self): + # Law # 67/VI/2005 of May 9th. + if self._year >= 2005: + # Ribeira Brava Municipality Day. + self._add_holiday_dec_6(tr("Dia do Município de Ribeira Brava")) + + def _populate_subdiv_rg_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Santo Antão Island Day. + self._add_holiday_jan_17(tr("Dia da Ilha de Santo Antão")) + + # Ribeira Grande Municipality Day. + self._add_holiday_may_7(tr("Dia do Município de Ribeira Grande")) + + def _populate_subdiv_rs_public_holidays(self): + # Law # 63/VI/2005 of May 9th. + if self._year >= 2006: + # Ribeira Grande de Santiago Municipality Day. + self._add_holiday_jan_31(tr("Dia do Município de Ribeira Grande de Santiago")) + + def _populate_subdiv_sd_public_holidays(self): + # Law # 96/IV/93 of December 31st. + if self._year >= 1994: + # São Domingos Municipality Day. + self._add_holiday_mar_13(tr("Dia do Município de São Domingos")) + + def _populate_subdiv_sf_public_holidays(self): + # Law # 23/IV/91 of December 30th. + if self._year >= 1992: + # São Filipe Municipality Day. + self._add_holiday_may_1(tr("Dia do Município de São Filipe")) + + def _populate_subdiv_sl_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Sal Municipality Day. + self._add_holiday_sep_15(tr("Dia do Município do Sal")) + + def _populate_subdiv_sm_public_holidays(self): + # Law # 11/V/96 of November 11th. + if self._year >= 1997: + # São Miguel Municipality Day. + self._add_holiday_sep_29(tr("Dia do Município de São Miguel")) + + def _populate_subdiv_so_public_holidays(self): + # Law # 64/VI/2005 of May 9th. + if self._year >= 2005: + # São Lourenço dos Órgãos Municipality Day. + self._add_holiday_may_9(tr("Dia do Município de São Lourenço dos Órgãos")) + + def _populate_subdiv_ss_public_holidays(self): + # Law # 65/VI/2005 of May 9th. + if self._year >= 2005: + # São Salvador do Mundo Municipality Day. + self._add_holiday_jul_19(tr("Dia do Município de São Salvador do Mundo")) + + def _populate_subdiv_sv_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # São Vicente Municipality Day. + self._add_holiday_jan_22(tr("Dia do Município de São Vicente")) + + # Carnival Tuesday. + self._add_carnival_tuesday(tr("Terça-feira de Carnaval")) + + def _populate_subdiv_ta_public_holidays(self): + # Law # 93/82 of November 6th. + if self._year >= 1983: + # Tarrafal de Santiago Municipality Day. + self._add_holiday_jan_15(tr("Dia do Município do Tarrafal de Santiago")) + + def _populate_subdiv_ts_public_holidays(self): + # Law # 67/VI/2005 of May 9th. + if self._year >= 2005: + # Tarrafal de São Nicolau Municipality Day. + self._add_holiday_aug_2(tr("Dia do Município do Tarrafal de São Nicolau")) + + +class CV(CaboVerde): + pass + + +class CPV(CaboVerde): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/cambodia.py b/.venv/lib/python3.12/site-packages/holidays/countries/cambodia.py new file mode 100644 index 00000000..e9df0831 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/cambodia.py @@ -0,0 +1,316 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import APR, MAY, AUG, SEP, _timedelta +from holidays.calendars.thai import KHMER_CALENDAR +from holidays.groups import InternationalHolidays, StaticHolidays, ThaiCalendarHolidays +from holidays.holiday_base import HolidayBase + + +class Cambodia(HolidayBase, InternationalHolidays, StaticHolidays, ThaiCalendarHolidays): + """Cambodia holidays. + + References: + * + * + * + * + + Checked with: + * + * + * + + Limitations: + * Cambodian holidays only works from 1993 onwards. + * Exact Public Holidays as per Cambodia's Official Gazette are only available + from 2015 onwards. + * Cambodian Lunar Calendar Holidays only work from 1941 (B.E. 2485) onwards until 2157 + (B.E. 2701) as we only have Thai year-type data for cross-checking until then. + """ + + country = "KH" + default_language = "km" + supported_languages = ("en_US", "km", "th") + # Available post-Independence from 1993 afterwards + start_year = 1993 + + def __init__(self, *args, **kwargs): + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=CambodiaStaticHolidays) + ThaiCalendarHolidays.__init__(self, KHMER_CALENDAR) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Fixed Holidays + + # ទិវាចូលឆ្នាំសាកល + # Status: In-Use. + + # International New Year Day. + self._add_new_years_day(tr("ទិវាចូលឆ្នាំសាកល")) + + # ទិវាជ័យជម្នះលើរបបប្រល័យពូជសាសន៍ + # Status: In-Use. + # Commemorates the end of the Khmer Rouge regime in 1979 + + # Day of Victory over the Genocidal Regime. + self._add_holiday_jan_7(tr("ទិវាជ័យជម្នះលើរបបប្រល័យពូជសាសន៍")) + + # ទិវាអន្តរជាតិនារី + # Status: In-Use. + + # International Women's Rights Day. + self._add_womens_day(tr("ទិវាអន្តរជាតិនារី")) + + # ពិធីបុណ្យចូលឆ្នាំថ្មីប្រពៃណីជាតិ + # Status: In-Use. + # Usually falls on April 13th except for 2017-2018, 2021-2023, 2025-2027, 2029-2031 + # for years 2001-2050. + + if self._year != 2020: + # Khmer New Year's Day. + sangkranta = tr("ពិធីបុណ្យចូលឆ្នាំថ្មីប្រពៃណីជាតិ") + sangkranta_years_apr_14 = { + 2017, + 2018, + 2021, + 2022, + 2023, + 2025, + 2026, + 2027, + 2029, + 2030, + 2031, + } + dt = ( + self._add_holiday_apr_14(sangkranta) + if self._year in sangkranta_years_apr_14 + else self._add_holiday_apr_13(sangkranta) + ) + self._add_holiday(sangkranta, _timedelta(dt, +1)) + self._add_holiday(sangkranta, _timedelta(dt, +2)) + + # ទិវាពលកម្មអន្តរជាតិ + # Status: In-Use. + + # International Labor Day. + self._add_labor_day(tr("ទិវាពលកម្មអន្តរជាតិ")) + + # ព្រះរាជពិធីបុណ្យចម្រើនព្រះជន្ម ព្រះករុណា ព្រះបាទសម្តេចព្រះបរមនាថ នរោត្តម សីហមុនី + # Status: In-Use. + # Assumed to start in 2005. Was celebrated for 3 days until 2020. + + if self._year >= 2005: + king_sihamoni_bday = tr( + # Birthday of His Majesty Preah Bat Samdech Preah Boromneath + # NORODOM SIHAMONI, King of Cambodia. + "ព្រះរាជពិធីបុណ្យចម្រើនព្រះជន្ម ព្រះករុណា ព្រះបាទសម្តេចព្រះបរមនាថ នរោត្តម សីហមុនី" + ) + self._add_holiday_may_14(king_sihamoni_bday) + if self._year <= 2019: + self._add_holiday_may_13(king_sihamoni_bday) + self._add_holiday_may_15(king_sihamoni_bday) + + # ទិវាជាតិនៃការចងចាំ + # Status: Defunct. + # Active between 2018-2019 as Public Holiday. + # Was ទិវាចងកំហឹង (National Day of Anger) between 1983-2000. + # Its celebration was put onhold by UN administration with + # its name changed to present one in 2001. + + if 2018 <= self._year <= 2019: + # National Day of Remembrance. + self._add_holiday_may_20(tr("ទិវាជាតិនៃការចងចាំ")) + + # ទិវាកុមារអន្តរជាតិ + # Status: Defunct. + # Assumed to start in 1993, defunct from 2020 onwards. + + if self._year <= 2019: + # International Children's Day. + self._add_childrens_day(tr("ទិវាកុមារអន្តរជាតិ")) + + # ព្រះរាជពិធីបុណ្យចម្រើនព្រះជន្ម សម្តេចព្រះមហាក្សត្រី ព្រះវររាជមាតា នរោត្តម មុនិនាថ សីហនុ + # Status: In-Use. + # Assumed to start in 1994. A public holiday since 2015 at least. + + if self._year >= 1994: + self._add_holiday_jun_18( + # Birthday of Her Majesty the Queen-Mother NORODOM MONINEATH SIHANOUK of Cambodia. + tr("ព្រះរាជពិធីបុណ្យចម្រើនព្រះជន្ម សម្តេចព្រះមហាក្សត្រី ព្រះវររាជមាតា នរោត្តម មុនិនាថ សីហនុ") + ) + + # ទិវាប្រកាសរដ្ឋធម្មនុញ្ញ + # Status: In-Use. + # Starts in 1993 + + # Constitution Day. + self._add_holiday_sep_24(tr("ទិវាប្រកាសរដ្ឋធម្មនុញ្ញ")) + + # ទិវាប្រារព្ឋពិធីគោរពព្រះវិញ្ញាណក្ខន្ឋ ព្រះករុណា ព្រះបាទសម្តេចព្រះ នរោត្តម សីហនុ + # ព្រះមហាវីរក្សត្រ ព្រះវររាជបិតាឯករាជ្យ បូរណភាពទឹកដី និងឯកភាពជាតិខ្មែរ ព្រះបរមរតនកោដ្ឋ + # Status: In-Use. + # Starts in 2012. + + if self._year >= 2012: + self._add_holiday_oct_15( + # Mourning Day of the Late King-Father NORODOM SIHANOUK of Cambodia. + tr( + "ទិវាប្រារព្ឋពិធីគោរពព្រះវិញ្ញាណក្ខន្ឋ ព្រះករុណា ព្រះបាទសម្តេចព្រះ នរោត្តម " + "សីហនុ ព្រះមហាវីរក្សត្រ ព្រះវររាជបិតាឯករាជ្យ បូរណភាពទឹកដី និងឯកភាពជាតិខ្មែរ " + "ព្រះបរមរតនកោដ្ឋ" + ) + ) + + # ទិវារំលឹកសន្ធិសញ្ញាសន្តិភាពទីក្រុងប៉ារីស + # Status: Defunct. + # Assumed to start in 1993, defunct from 2020 onwards. + + if self._year <= 2019: + # Paris Peace Agreement's Day. + self._add_holiday_oct_23(tr("ទិវារំលឹកសន្ធិសញ្ញាសន្តិភាពទីក្រុងប៉ារីស")) + + # ព្រះរាជពិធីគ្រងព្រះបរមរាជសម្បត្តិ របស់ ព្រះករុណា + # ព្រះបាទសម្តេចព្រះបរមនាថ នរោត្តម សីហមុនី + # ព្រះមហាក្សត្រនៃព្រះរាជាណាចក្រកម្ពុជា + # Status: In-Use. + # Starts in 2004. + + if self._year >= 2004: + self._add_holiday_oct_29( + # Coronation Day of His Majesty Preah Bat Samdech Preah + # Boromneath NORODOM SIHAMONI, King of Cambodia. + tr( + "ព្រះរាជពិធីគ្រងព្រះបរមរាជសម្បត្តិ របស់ ព្រះករុណា " + "ព្រះបាទសម្តេចព្រះបរមនាថ នរោត្តម សីហមុនី " + "ព្រះមហាក្សត្រនៃព្រះរាជាណាចក្រកម្ពុជា" + ) + ) + + # ពិធីបុណ្យឯករាជ្យជាតិ + # Status: In-Use. + # Starts in 1953 + + # National Independence Day. + self._add_holiday_nov_9(tr("ពិធីបុណ្យឯករាជ្យជាតិ")) + + # ទិវាសិទ្ធិមនុស្សអន្តរជាតិ + # Status: Defunct. + # Assumed to start in 1993, defunct from 2020 onwards. + + if self._year <= 2019: + # International Human Rights Day. + self._add_holiday_dec_10(tr("ទិវាសិទ្ធិមនុស្សអន្តរជាតិ")) + + # Cambodian Lunar Calendar Holidays + # See `_ThaiLunisolar` in holidays/calendars/thai.py for more details. + # Cambodian Lunar Calendar Holidays only work from 1941 to 2157. + + # ពិធីបុណ្យមាឃបូជា + # Status: Defunct. + # 15th Waxing Day of Month 3. + # Defunct from 2020 onwards. + + if self._year <= 2019: + # Meak Bochea Day. + self._add_makha_bucha(tr("ពិធីបុណ្យមាឃបូជា")) + + # ពិធីបុណ្យវិសាខបូជា + # Status: In-Use. + # 15th Waxing Day of Month 6. + # This utilizes Thai calendar as a base, though are calculated to always happen + # in the Traditional Visakhamas month (May). + + # Visaka Bochea Day. + self._add_visakha_bucha(tr("ពិធីបុណ្យវិសាខបូជា")) + + # ព្រះរាជពិធីច្រត់ព្រះនង្គ័ល + # Status: In-Use. + # 4th Waning Day of Month 6. + # Unlike Thai ones, Cambodian Royal Ploughing Ceremony is always fixed. + + # Royal Ploughing Ceremony. + self._add_preah_neangkoal(tr("ព្រះរាជពិធីច្រត់ព្រះនង្គ័ល")) + + # ពិធីបុណ្យភ្ផុំបិណ្ឌ + # Status: In-Use. + # 14th Waning Day of Month 10 - 1st Waxing Day of Month 11. + # The 3rd day is added as a public holiday from 2017 onwards. + + # Pchum Ben Day. + pchum_ben = tr("ពិធីបុណ្យភ្ផុំបិណ្ឌ") + pchum_ben_date = self._add_pchum_ben(pchum_ben) + self._add_holiday(pchum_ben, _timedelta(pchum_ben_date, -1)) + if self._year >= 2017: + self._add_holiday(pchum_ben, _timedelta(pchum_ben_date, +1)) + + # ព្រះរាជពិធីបុណ្យអុំទូក បណ្តែតប្រទីប និងសំពះព្រះខែអកអំបុក + # Status: In-Use. + # 14th Waxing Day of Month 12 - 1st Waning Day of Month 12. + + # Water Festival. + bon_om_touk = tr("ព្រះរាជពិធីបុណ្យអុំទូក បណ្តែតប្រទីប និងសំពះព្រះខែអកអំបុក") + bon_om_touk_date = self._add_loy_krathong(bon_om_touk) + self._add_holiday(bon_om_touk, _timedelta(bon_om_touk_date, -1)) + self._add_holiday(bon_om_touk, _timedelta(bon_om_touk_date, +1)) + + # ទិវាសន្តិភាពនៅកម្ពុជា + # Status: In-Use. + # Dec 29, added from 2024 onwards. + # - https://www.khmertimeskh.com/501424903/24-public-holidays-for-2024-peace-day-now-included/ + # - https://www.khmertimeskh.com/501551204/govt-announces-22-public-holidays-for-next-year/ + + if self._year >= 2024: + # Peace Day in Cambodia. + self._add_holiday_dec_29(tr("ទិវាសន្តិភាពនៅកម្ពុជា")) + + +class KH(Cambodia): + pass + + +class KHM(Cambodia): + pass + + +class CambodiaStaticHolidays: + sangkranta_in_lieu_covid = tr( + # Khmer New Year's Replacement Holiday. + "ថ្ងៃឈប់សម្រាកសងជំនួសឲ្យពិធីបុណ្យចូលឆ្នាំថ្មីប្រពៃណីជាតិ" + ) + # Special Public Holiday. + special_in_lieu_holidays = tr("ថ្ងៃឈប់សម្រាកសងជំនួស") + + # Khmer New Year's Day. + sangkranta = tr("ពិធីបុណ្យចូលឆ្នាំថ្មីប្រពៃណីជាតិ") + + special_public_holidays = { + 2016: ( + (MAY, 2, special_in_lieu_holidays), + (MAY, 16, special_in_lieu_holidays), + ), + 2018: (MAY, 21, special_in_lieu_holidays), + 2019: (SEP, 30, special_in_lieu_holidays), + 2020: ( + (MAY, 11, special_in_lieu_holidays), + (AUG, 17, sangkranta_in_lieu_covid), + (AUG, 18, sangkranta_in_lieu_covid), + (AUG, 19, sangkranta_in_lieu_covid), + (AUG, 20, sangkranta_in_lieu_covid), + (AUG, 21, sangkranta_in_lieu_covid), + ), + 2024: (APR, 16, sangkranta), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/cameroon.py b/.venv/lib/python3.12/site-packages/holidays/countries/cameroon.py new file mode 100644 index 00000000..08e42860 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/cameroon.py @@ -0,0 +1,196 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_WORKDAY + + +class Cameroon( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Cameroon holidays. + + References: + * + * + * + """ + + country = "CM" + observed_label = "%s (observed)" + # On 1 January 1960, French Cameroun gained independence from France. + start_year = 1960 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=CameroonIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=CameroonStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day("New Year's Day")) + + # Youth Day. + if self._year >= 1966: + dts_observed.add(self._add_holiday_feb_11("Youth Day")) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Labour Day. + dts_observed.add(self._add_labor_day("Labour Day")) + + # National Day. + if self._year >= 1972: + dts_observed.add(self._add_holiday_may_20("National Day")) + + # Ascension Day. + self._add_ascension_thursday("Ascension Day") + + # Assumption Day. + dts_observed.add(self._add_assumption_of_mary_day("Assumption Day")) + + # Christmas Day. + dts_observed.add(self._add_christmas_day("Christmas Day")) + + # Eid al-Fitr. + dts_observed.update(self._add_eid_al_fitr_day("Eid al-Fitr")) + + # Eid al-Adha. + dts_observed.update(self._add_eid_al_adha_day("Eid al-Adha")) + + # Mawlid. + dts_observed.update(self._add_mawlid_day("Mawlid")) + + if self.observed: + self._populate_observed(dts_observed) + + +class CM(Cameroon): + pass + + +class CMR(Cameroon): + pass + + +class CameroonIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + } + + EID_AL_FITR_DATES = { + 2001: (DEC, 17), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + } + + MAWLID_DATES = { + 2001: (JUN, 4), + 2002: (MAY, 24), + 2003: (MAY, 14), + 2004: (MAY, 2), + 2005: (APR, 21), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 16), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 8), + } + + +class CameroonStaticHolidays: + special_public_holidays = { + 2021: ( + (MAY, 14, "Public Holiday"), + (JUL, 19, "Public Holiday"), + ), + } + + special_public_holidays_observed = { + 2007: (JAN, 2, "Eid al-Adha"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/canada.py b/.venv/lib/python3.12/site-packages/holidays/countries/canada.py new file mode 100644 index 00000000..1ae2c98c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/canada.py @@ -0,0 +1,565 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr +from typing import Optional + +from holidays.calendars.gregorian import MAR, APR, JUN, JUL, SEP +from holidays.constants import GOVERNMENT, OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + ALL_TO_NEAREST_MON, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, + SUN_TO_NEXT_MON, + SUN_TO_NEXT_TUE, +) + + +class Canada(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Canada holidays. + + References: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + """ + + country = "CA" + default_language = "en_CA" + # %s (observed). + observed_label = tr("%s (observed)") + start_year = 1867 + subdivisions = ( + "AB", # Alberta. + "BC", # British Columbia (Colombie-Britannique). + "MB", # Manitoba. + "NB", # New Brunswick (Nouveau-Brunswick). + "NL", # Newfoundland and Labrador (Terre-Neuve-et-Labrador). + "NS", # Nova Scotia (Nouvelle-Écosse). + "NT", # Northwest Territories (Territoires du Nord-Ouest). + "NU", # Nunavut. + "ON", # Ontario. + "PE", # Prince Edward Island (Île-du-Prince-Édouard). + "QC", # Quebec (Québec). + "SK", # Saskatchewan. + "YT", # Yukon. + ) + subdivisions_aliases = { + "Alberta": "AB", + "British Columbia": "BC", + "Colombie-Britannique": "BC", + "Manitoba": "MB", + "New Brunswick": "NB", + "Nouveau-Brunswick": "NB", + "Newfoundland and Labrador": "NL", + "Terre-Neuve-et-Labrador": "NL", + "Nova Scotia": "NS", + "Nouvelle-Écosse": "NS", + "Northwest Territories": "NT", + "Territoires du Nord-Ouest": "NT", + "Nunavut": "NU", + "Ontario": "ON", + "Prince Edward Island": "PE", + "Île-du-Prince-Édouard": "PE", + "Quebec": "QC", + "Québec": "QC", + "Saskatchewan": "SK", + "Yukon": "YT", + } + supported_categories = (GOVERNMENT, OPTIONAL, PUBLIC) + supported_languages = ("ar", "en_CA", "en_US", "fr", "th") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, CanadaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _get_nearest_monday(self, *args) -> Optional[date]: + return self._get_observed_date(date(self._year, *args), rule=ALL_TO_NEAREST_MON) + + def _add_statutory_holidays(self): + """Nationwide statutory holidays.""" + + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 1879: + self._canada_day = self._add_holiday_jul_1( + # Canada Day. + tr("Canada Day") + if self._year >= 1983 + # Dominion Day. + else tr("Dominion Day") + ) + + if self._year >= 1894: + # Labor Day. + self._add_holiday_1st_mon_of_sep(tr("Labour Day")) + + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")) + + def _populate_public_holidays(self): + self._add_statutory_holidays() + + self._add_observed(self._christmas_day) + + def _populate_government_holidays(self): + """Holidays for federally regulated workplaces.""" + + self._add_statutory_holidays() + + self._add_victoria_day() + + if self._year >= 1879: + self._add_observed(self._canada_day) + + if self._year >= 2021: + self._add_observed( + # National Day for Truth and Reconciliation. + self._add_holiday_sep_30(tr("National Day for Truth and Reconciliation")) + ) + + self._add_thanksgiving_day() + + if self._year >= 1931: + # Remembrance Day. + self._add_observed(self._add_remembrance_day(tr("Remembrance Day"))) + + self._add_observed(self._christmas_day, rule=SAT_SUN_TO_NEXT_MON_TUE) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + def _populate_optional_holidays(self): + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + def _add_thanksgiving_day(self) -> None: + """Adds Thanksgiving Day / Armistice Day. + + In 1921, Thanksgiving Day was moved to "Armistice Day" (1st Monday in the week of Nov 11). + "Remembrance Day" and "Thanksgiving Day" split again in 1931, with Thanksgiving usually on + the 2nd Monday of October — except in 1935, when it was delayed 10 days due to a General + Election. It was finally fixed to the 2nd Monday of October permanently in 1957. + """ + if self._year >= 1931: + # Thanksgiving Day. + name = tr("Thanksgiving Day") + if self._year == 1935: + self._add_holiday_oct_24(name) + else: + self._add_holiday_2nd_mon_of_oct(name) + elif self._year >= 1921: + # Armistice Day. + self._add_holiday_1st_mon_before_nov_12(tr("Armistice Day")) + + def _add_victoria_day(self) -> None: + """Adds Victoria Day. + + After Queen Victoria's death in 1901, an act of the Canadian Parliament established + Victoria Day as a legal holiday, to be celebrated on May 24 (or on May 25 when + May 24 fell on a Sunday). This was later moved to the Monday preceding May 24 in 1952. + """ + # Victoria Day. + name = tr("Victoria Day") + if self._year >= 1953: + self._add_holiday_1st_mon_before_may_24(name) + elif self._year >= 1901: + self._add_observed(self._add_holiday_may_24(name), rule=SUN_TO_NEXT_MON) + + def _populate_subdiv_ab_public_holidays(self): + if self._year >= 1990: + # Family Day. + self._add_holiday_3rd_mon_of_feb(tr("Family Day")) + + self._add_victoria_day() + + if self._year >= 1879: + self._add_observed(self._canada_day, rule=SUN_TO_NEXT_MON) + + self._add_thanksgiving_day() + + if self._year >= 1931: + # Remembrance Day. + self._add_observed(self._add_remembrance_day(tr("Remembrance Day"))) + + def _populate_subdiv_ab_optional_holidays(self): + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # https://en.wikipedia.org/wiki/Civic_Holiday#Alberta + if self._year >= 1974: + # Heritage Day. + self._add_holiday_1st_mon_of_aug(tr("Heritage Day")) + + if self._year >= 2021: + # National Day for Truth and Reconciliation. + self._add_holiday_sep_30(tr("National Day for Truth and Reconciliation")) + + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")) + + def _populate_subdiv_bc_public_holidays(self): + if self._year >= 2013: + # Family Day. + name = tr("Family Day") + if self._year >= 2019: + self._add_holiday_3rd_mon_of_feb(name) + else: + self._add_holiday_2nd_mon_of_feb(name) + + self._add_victoria_day() + + if self._year >= 1879: + self._add_observed(self._canada_day, rule=SUN_TO_NEXT_MON) + + # https://en.wikipedia.org/wiki/Civic_Holiday#British_Columbia + if self._year >= 1974: + # British Columbia Day. + self._add_holiday_1st_mon_of_aug(tr("British Columbia Day")) + + if self._year >= 2023: + # National Day for Truth and Reconciliation. + self._add_holiday_sep_30(tr("National Day for Truth and Reconciliation")) + + self._add_thanksgiving_day() + + if self._year >= 1931: + # Remembrance Day. + self._add_remembrance_day(tr("Remembrance Day")) + + def _populate_subdiv_mb_public_holidays(self): + if self._year >= 2008: + # Louis Riel Day. + self._add_holiday_3rd_mon_of_feb(tr("Louis Riel Day")) + + self._add_victoria_day() + + self._add_thanksgiving_day() + + def _populate_subdiv_mb_optional_holidays(self): + if self._year >= 1900: + self._add_holiday_1st_mon_of_aug( + # Terry Fox Day. + tr("Terry Fox Day") + if self._year >= 2015 + # Civic Holiday. + else tr("Civic Holiday") + ) + + if self._year >= 1931: + # Remembrance Day. + self._add_remembrance_day(tr("Remembrance Day")) + + def _populate_subdiv_nb_public_holidays(self): + if self._year >= 2018: + # Family Day. + self._add_holiday_3rd_mon_of_feb(tr("Family Day")) + + # https://en.wikipedia.org/wiki/Civic_Holiday#New_Brunswick + if self._year >= 1975: + # New Brunswick Day. + self._add_holiday_1st_mon_of_aug(tr("New Brunswick Day")) + + if self._year >= 1931: + # Remembrance Day. + self._add_remembrance_day(tr("Remembrance Day")) + + def _populate_subdiv_nb_optional_holidays(self): + self._add_victoria_day() + + self._add_thanksgiving_day() + + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")) + + def _populate_subdiv_nl_public_holidays(self): + if self._year >= 1917: + # Memorial Day. + self._add_holiday_jul_1(tr("Memorial Day")) + + if self._year >= 1879: + self._add_observed(self._canada_day) + + if self._year >= 1931: + # Remembrance Day. + self._add_observed(self._add_remembrance_day(tr("Remembrance Day"))) + + def _populate_subdiv_nl_optional_holidays(self): + if self._year >= 1900: + # Saint Patrick's Day. + self._add_holiday(tr("Saint Patrick's Day"), self._get_nearest_monday(MAR, 17)) + + if self._year >= 1990: + # Nearest Monday to April 23 + # 4/26 is the Monday closer to 4/23 in 2010 + # but the holiday was observed on 4/19? Crazy Newfies! + dt = date(2010, APR, 19) if self._year == 2010 else self._get_nearest_monday(APR, 23) + # Saint George's Day. + self._add_holiday(tr("Saint George's Day"), dt) + + if self._year >= 1997: + # Discovery Day. + self._add_holiday(tr("Discovery Day"), self._get_nearest_monday(JUN, 24)) + + if self._year >= 1900: + # Orangemen's Day. + self._add_holiday(tr("Orangemen's Day"), self._get_nearest_monday(JUL, 12)) + + self._add_thanksgiving_day() + + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")) + + def _populate_subdiv_ns_public_holidays(self): + # https://web.archive.org/web/20240611215326/https://novascotia.ca/lae/employmentrights/NovaScotiaHeritageDay.asp + if self._year >= 2015: + # Heritage Day. + self._add_holiday_3rd_mon_of_feb(tr("Heritage Day")) + + if self._year >= 1981: + # Remembrance Day. + self._add_observed(self._add_remembrance_day(tr("Remembrance Day"))) + + def _populate_subdiv_ns_optional_holidays(self): + if self._year >= 1996: + # Natal Day. + self._add_holiday_1st_mon_of_aug(tr("Natal Day")) + + def _populate_subdiv_nt_public_holidays(self): + self._add_victoria_day() + + if self._year >= 1996: + # National Aboriginal Day. + self._add_holiday_jun_21(tr("National Aboriginal Day")) + + if self._year >= 1900: + # Civic Holiday. + self._add_holiday_1st_mon_of_aug(tr("Civic Holiday")) + + if self._year >= 2022: + # National Day for Truth and Reconciliation. + self._add_holiday_sep_30(tr("National Day for Truth and Reconciliation")) + + self._add_thanksgiving_day() + + if self._year >= 1931: + # Remembrance Day. + self._add_remembrance_day(tr("Remembrance Day")) + + def _populate_subdiv_nu_public_holidays(self): + self._add_victoria_day() + + if self._year >= 2020: + # Nunavut Day. + self._add_holiday_jul_9(tr("Nunavut Day")) + + if self._year >= 1900: + # Civic Holiday. + self._add_holiday_1st_mon_of_aug(tr("Civic Holiday")) + + if self._year >= 2022: + # National Day for Truth and Reconciliation. + self._add_holiday_sep_30(tr("National Day for Truth and Reconciliation")) + + self._add_thanksgiving_day() + + if self._year >= 1931: + # Remembrance Day. + self._add_remembrance_day(tr("Remembrance Day")) + + def _populate_subdiv_nu_optional_holidays(self): + if 2000 <= self._year <= 2019: + # Nunavut Day. + name = tr("Nunavut Day") + if self._year == 2000: + self._add_holiday_apr_1(name) + else: + self._add_holiday_jul_9(name) + + def _populate_subdiv_on_public_holidays(self): + if self._year >= 2008: + # Family Day. + self._add_holiday_3rd_mon_of_feb(tr("Family Day")) + + self._add_victoria_day() + + self._add_thanksgiving_day() + + # Boxing Day. + self._add_observed(self._add_christmas_day_two(tr("Boxing Day")), rule=SUN_TO_NEXT_TUE) + + def _populate_subdiv_on_optional_holidays(self): + if self._year >= 1900: + # Civic Holiday. + self._add_holiday_1st_mon_of_aug(tr("Civic Holiday")) + + def _populate_subdiv_pe_public_holidays(self): + if self._year >= 2009: + # Islander Day. + name = tr("Islander Day") + if self._year >= 2010: + self._add_holiday_3rd_mon_of_feb(name) + else: + self._add_holiday_2nd_mon_of_feb(name) + + if self._year >= 1879: + self._add_observed(self._canada_day) + + if self._year >= 2022: + # National Day for Truth and Reconciliation. + self._add_holiday_sep_30(tr("National Day for Truth and Reconciliation")) + + if self._year >= 1931: + # Remembrance Day. + self._add_observed(self._add_remembrance_day(tr("Remembrance Day"))) + + def _populate_subdiv_qc_public_holidays(self): + if self._year >= 2003: + # National Patriots' Day. + self._add_holiday_1st_mon_before_may_24(tr("National Patriots' Day")) + + if self._year >= 1925: + self._add_observed( + # Saint John the Baptist Day. + self._add_saint_johns_day(tr("Saint Jean Baptiste Day")), + rule=SUN_TO_NEXT_MON, + ) + + if self._year >= 1879: + self._add_observed(self._canada_day, rule=SUN_TO_NEXT_MON) + + self._add_thanksgiving_day() + + def _populate_subdiv_qc_optional_holidays(self): + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + def _populate_subdiv_sk_public_holidays(self): + if self._year >= 2007: + # Family Day. + self._add_holiday_3rd_mon_of_feb(tr("Family Day")) + + self._add_victoria_day() + + if self._year >= 1879: + self._add_observed(self._canada_day) + + # https://en.wikipedia.org/wiki/Civic_Holiday#Saskatchewan + if self._year >= 1900: + # Saskatchewan Day. + self._add_holiday_1st_mon_of_aug(tr("Saskatchewan Day")) + + self._add_thanksgiving_day() + + if self._year >= 1931: + # Remembrance Day. + self._add_observed(self._add_remembrance_day(tr("Remembrance Day"))) + + def _populate_subdiv_yt_public_holidays(self): + self._add_victoria_day() + + if self._year >= 2017: + # National Aboriginal Day. + self._add_holiday_jun_21(tr("National Aboriginal Day")) + + if self._year >= 1879: + self._add_observed(self._canada_day) + + if self._year >= 1912: + # Discovery Day. + self._add_holiday_3rd_mon_of_aug(tr("Discovery Day")) + + if self._year >= 2023: + # National Day for Truth and Reconciliation. + self._add_holiday_sep_30(tr("National Day for Truth and Reconciliation")) + + self._add_thanksgiving_day() + + if self._year >= 1931: + # Remembrance Day. + self._add_observed(self._add_remembrance_day(tr("Remembrance Day"))) + + def _populate_subdiv_yt_optional_holidays(self): + # Friday before the last Sunday in February + if self._year >= 1976: + # Heritage Day. + self._add_holiday_2_days_prior_last_sun_of_feb(tr("Heritage Day")) + + +class CA(Canada): + pass + + +class CAN(Canada): + pass + + +class CanadaStaticHolidays: + # Funeral of Queen Elizabeth II. + queen_funeral = tr("Funeral of Her Majesty the Queen Elizabeth II") + + special_bc_public_holidays = { + 2022: (SEP, 19, queen_funeral), + } + + special_nb_public_holidays = { + 2022: (SEP, 19, queen_funeral), + } + + special_nl_public_holidays = { + 2022: (SEP, 19, queen_funeral), + } + + special_ns_public_holidays = { + 2022: (SEP, 19, queen_funeral), + } + + special_pe_public_holidays = { + 2022: (SEP, 19, queen_funeral), + } + + special_yt_public_holidays = { + 2022: (SEP, 19, queen_funeral), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/cayman_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/cayman_islands.py new file mode 100644 index 00000000..2c8afda9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/cayman_islands.py @@ -0,0 +1,162 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays import APR, MAY, JUN, JUL, SEP, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class CaymanIslands(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Cayman Islands holidays. + + References: + * + * [Public Holidays Law (2007 Revision)](https://web.archive.org/web/20250227060525/https://legislation.gov.ky/cms/images/LEGISLATION/PRINCIPAL/1964/1964-0140/PublicHolidaysAct_2007%20Revision_g.pdf) + * [Public Holidays Order, 2024](https://web.archive.org/web/20240518181823/https://legislation.gov.ky/cms/images/LEGISLATION/AMENDING/2024/2024-O004/PublicHolidaysOrder2024SL4of2024.pdf) + * [2006-2015](https://web.archive.org/web/20151014061601/http://www.gov.ky/portal/page?_pageid=1142,1592653&_dad=portal&_schema=PORTAL) + * [2016-2018](https://web.archive.org/web/20180330170202/http://www.gov.ky:80/portal/page/portal/cighome/cayman/islands/publicholidays) + * [2021](http://archive.today/2025.07.09-033240/https://www.gov.ky/news/press-release-details/public-holidays-for-2021) + * [2022](http://archive.today/2025.07.09-033515/https://www.gov.ky/news/press-release-details/public-holidays-2022) + * [2024](http://archive.today/2025.01.06-110234/https://www.gov.ky/calendar/public-holidays) + * [2025](http://archive.today/2025.07.09-033853/https://www.gov.ky/calendar/public-holidays) + """ + + country = "KY" + default_language = "en_GB" + # %s observed. + observed_label = tr("%s (observed)") + # Earliest year of holidays with an accessible online record. + start_year = 2006 + supported_languages = ("en_GB", "en_US") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=CaymanIslandsStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # National Heroes Day. + self._add_holiday_4th_mon_of_jan(tr("National Heroes Day")) + + # Ash Wednesday. + self._add_ash_wednesday(tr("Ash Wednesday")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + if self._year >= 2024: + # Emancipation Day. + self._add_holiday_1st_mon_of_may(tr("Emancipation Day")) + + # Discovery Day. + self._add_holiday_3rd_mon_of_may(tr("Discovery Day")) + + if self._year <= 2022: + queens_birthday_dates = { + 2007: (JUN, 18), + 2012: (JUN, 18), + 2013: (JUN, 17), + 2017: (JUN, 19), + 2022: (JUN, 6), + } + # Queen's Birthday. + name = tr("Queen's Birthday") + if dt := queens_birthday_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_2_days_past_2nd_sat_of_jun(name) + else: + # King's Birthday. + self._add_holiday_2_days_past_3rd_sat_of_jun(tr("King's Birthday")) + + # Constitution Day. + self._add_holiday_1st_mon_of_jul(tr("Constitution Day")) + + # Remembrance Day. + self._add_holiday_2nd_mon_of_nov(tr("Remembrance Day")) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + +class KY(CaymanIslands): + pass + + +class CYM(CaymanIslands): + pass + + +class CaymanIslandsStaticHolidays: + """Cayman Islands special holidays. + + References: + * [Public Holidays Order, 2009](https://archive.org/details/public-holidays-order-2009-sl-33-of-2009) + * [Public Holidays Order (No. 2), 2019](https://archive.org/details/public-holidays-no.-2-order-2019-sl-38-of-2019) + * [Public Holidays Order, 2025](https://archive.org/details/public-holidays-order-2025-sl-15-of-2025) + * [Referendum Day 2019](https://web.archive.org/web/20250711121821/https://www.facebook.com/ElectionsOffice/posts/reminder-the-referendum-vote-has-been-postponed-and-will-no-longer-take-place-th/2619995141431734/?_rdc=2&_rdr) + * [UK Royal Wedding](https://en.wikipedia.org/wiki/Wedding_of_Prince_William_and_Catherine_Middleton) + * [Queen Elizabeth II's Diamond Jubilee](https://web.archive.org/web/20210803202236/https://www.caymancompass.com/2012/06/06/queens-diamond-jubilee-feted/) + * [Queen Elizabeth II's Funeral](https://web.archive.org/web/20231226055510/https://www.caymancompass.com/2022/09/12/cayman-declares-public-holiday-for-queens-funeral/) + * [King Charles III's Coronation](https://web.archive.org/web/20250601214328/https://www.radiocayman.gov.ky/news/public-holidays-for-2023-unconfirmed) + """ + + # Referendum Day. + referendum_day_name = tr("Referendum Day") + # General Election Day. + general_election_day_name = tr("General Election Day") + special_public_holidays = { + 2009: ( + # 2009 Cayman Islands Constitution Day. + (NOV, 6, tr("2009 Cayman Islands Constitution Day")), + (MAY, 20, general_election_day_name), + ), + # UK Royal Wedding. + 2011: (APR, 29, tr("UK Royal Wedding")), + 2012: ( + # Queen Elizabeth II's Diamond Jubilee. + (JUN, 4, tr("Queen Elizabeth II's Diamond Jubilee")), + (JUL, 18, referendum_day_name), + ), + 2013: (MAY, 22, general_election_day_name), + 2017: (MAY, 24, general_election_day_name), + 2019: (DEC, 19, referendum_day_name), + 2021: (APR, 14, general_election_day_name), + # Queen Elizabeth II's Funeral. + 2022: (SEP, 19, tr("Queen Elizabeth II's Funeral")), + # King Charles III's Coronation. + 2023: (MAY, 8, tr("Coronation of His Majesty King Charles III")), + 2025: (APR, 30, general_election_day_name), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/central_african_republic.py b/.venv/lib/python3.12/site-packages/holidays/countries/central_african_republic.py new file mode 100644 index 00000000..3bdb2fdb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/central_african_republic.py @@ -0,0 +1,143 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import MAR, APR, MAY, JUN, JUL, AUG, SEP +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class CentralAfricanRepublic( + HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays +): + """Central African Republic holidays. + + References: + * + * [PUBLIC HOLIDAYS](https://web.archive.org/web/20171215122602/http://www.ais-asecna.org/pdf/gen/gen-2-1/04gen2-1-01.pdf) + * + * + * + """ + + country = "CF" + default_language = "fr" + supported_languages = ("en_US", "fr") + # %s (estimated). + estimated_label = tr("%s (estimé)") + # December 1, 1958: Autonomy within the French Community. + start_year = 1959 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=CentralAfricanRepublicIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Jour de l'an")) + + if self._year >= 1960: + # Barthélemy Boganda Day. + self._add_holiday_mar_29(tr("Journée Barthélemy Boganda")) + + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + # Labor Day. + self._add_labor_day(tr("Fête du Travail")) + + # Ascension Day. + self._add_ascension_thursday(tr("Ascension")) + + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + + if self._year >= 2007: + # General Prayer Day. + self._add_holiday_jun_30(tr("Journée de prière générale")) + + if self._year >= 1960: + # Independence Day. + self._add_holiday_aug_13(tr("Jour de l'indépendance")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assomption")) + + # All Saints' Day. + self._add_all_saints_day(tr("Toussaint")) + + # National Day. + name = tr("Fête nationale") + if self._year in {1977, 1978}: + self._add_holiday_dec_4(name) + else: + self._add_holiday_dec_1(name) + + # Christmas Day. + self._add_christmas_day(tr("Jour de Noël")) + + if self._year >= 2015: + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Aïd al-Fitr")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Aïd al-Adha")) + + +class CF(CentralAfricanRepublic): + pass + + +class CAF(CentralAfricanRepublic): + pass + + +class CentralAfricanRepublicIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/chad.py b/.venv/lib/python3.12/site-packages/holidays/countries/chad.py new file mode 100644 index 00000000..05298786 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/chad.py @@ -0,0 +1,143 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Chad( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Chad holidays. + + References: + * + * + """ + + country = "TD" + observed_label = "%s (observed)" + # On 11 August 1960, Chad gained independence from France. + start_year = 1961 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=ChadIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, ChadStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + # International Women's Day. + self._add_observed(self._add_womens_day("International Women's Day")) + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Labour Day. + self._add_observed(self._add_labor_day("Labour Day")) + + # Independence Day. + self._add_observed(self._add_holiday_aug_11("Independence Day")) + + # All Saints' Day. + self._add_all_saints_day("All Saints' Day") + + # Republic Day. + self._add_observed(self._add_holiday_nov_28("Republic Day")) + + if self._year >= 1991: + # Freedom and Democracy Day. + self._add_observed(self._add_holiday_dec_1("Freedom and Democracy Day")) + + # Christmas Day. + self._add_christmas_day("Christmas Day") + + # Eid al-Fitr. + self._add_eid_al_fitr_day("Eid al-Fitr") + + # Eid al-Adha. + self._add_eid_al_adha_day("Eid al-Adha") + + # Mawlid. + self._add_mawlid_day("Mawlid") + + +class TD(Chad): + pass + + +class TCD(Chad): + pass + + +class ChadIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + } + + EID_AL_FITR_DATES = { + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + } + + MAWLID_DATES = { + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + } + + +class ChadStaticHolidays: + special_public_holidays = { + 2021: (APR, 23, "Funeral of Idriss Déby Itno"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/chile.py b/.venv/lib/python3.12/site-packages/holidays/countries/chile.py new file mode 100644 index 00000000..eeb78443 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/chile.py @@ -0,0 +1,268 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JUN, SEP, DEC +from holidays.constants import BANK, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_ONLY, + MON_FRI_ONLY, + TUE_TO_PREV_FRI, + WED_TO_NEXT_FRI, + FRI_ONLY, + WORKDAY_TO_NEAREST_MON, +) + + +class Chile(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Chile holidays. + + References: + * + * [Excellent history of Chile holidays](https://web.archive.org/web/20250124223839/https://www.feriadoschilenos.cl/) + * + * Law 2.977 (established official Chile holidays in its current form) + * Law 20.983 (Day after New Year's Day, if it's a Sunday) + * Law 19.668 (floating Monday holiday) + * Law 19.668 (Corpus Christi) + * Law 2.200, (Labour Day) + * Law 18.018 (Labour Day renamed) + * Law 16.840, Law 18.432 (Saint Peter and Saint Paul) + * Law 20.148 (Day of Virgin of Carmen) + * Law 18.026 (Day of National Liberation) + * Law 19.588, Law 19.793 (Day of National Unity) + * Law 20.983 (National Holiday Friday preceding Independence Day) + * Law 20.215 (National Holiday Monday preceding Independence Day) + * Law 20.215 (National Holiday Friday following Army Day) + * Decree-law 636, Law 8.223 + * Law 3.810 (Columbus Day) + * Law 20.299 (National Day of the Evangelical and Protestant Churches) + * Law 20.663 (Región de Arica y Parinacota) + * Law 20.678 (Región de Ñuble) + * [Law 19.656 (Dec 31, 1999 holiday)](https://web.archive.org/web/20241228005823/https://www.bcn.cl/leychile/navegar?idNorma=149328&idVersion=1999-12-15) + * [Law 12.051 (bank holidays Jun 30 and Dec 31)](https://web.archive.org/web/20241227190026/https://www.bcn.cl/leychile/navegar?idNorma=27013&idVersion=1956-07-12) + * [Decree-law 1.171 (eliminate Jun 30)](https://web.archive.org/web/20241227191010/https://www.bcn.cl/leychile/navegar?idNorma=6507&idVersion=1975-09-05) + * [Law 19.528 (eliminate Dec 31)](https://web.archive.org/web/20241227191452/https://www.bcn.cl/leychile/navegar?idNorma=76630&idVersion=1997-11-04) + * [Law 19.559 (restore Dec 31)](https://web.archive.org/web/20241227195811/https://www.bcn.cl/leychile/navegar?idNorma=97758&idVersion=1998-04-16) + """ + + country = "CL" + default_language = "es" + start_year = 1915 + subdivisions = ( + "AI", # Aisén del General Carlos Ibañez del Campo. + "AN", # Antofagasta. + "AP", # Arica y Parinacota. + "AR", # La Araucanía. + "AT", # Atacama. + "BI", # Biobío. + "CO", # Coquimbo. + "LI", # Libertador General Bernardo O'Higgins. + "LL", # Los Lagos. + "LR", # Los Ríos. + "MA", # Magallanes. + "ML", # Maule. + "NB", # Ñuble. + "RM", # Región Metropolitana de Santiago. + "TA", # Tarapacá. + "VS", # Valparaíso. + ) + subdivisions_aliases = { + "Aisén del General Carlos Ibañez del Campo": "AI", + "Antofagasta": "AN", + "Arica y Parinacota": "AP", + "La Araucanía": "AR", + "Atacama": "AT", + "Biobío": "BI", + "Coquimbo": "CO", + "Libertador General Bernardo O'Higgins": "LI", + "Los Lagos": "LL", + "Los Ríos": "LR", + "Magallanes": "MA", + "Maule": "ML", + "Ñuble": "NB", + "Región Metropolitana de Santiago": "RM", + "Tarapacá": "TA", + "Valparaíso": "VS", + } + supported_categories = (BANK, PUBLIC) + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, ChileStaticHolidays) + kwargs.setdefault("observed_rule", WORKDAY_TO_NEAREST_MON) + kwargs.setdefault("observed_since", 2000) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + if self._year >= 2017: + self._add_observed(self._add_new_years_day_two(tr("Feriado nacional")), rule=MON_ONLY) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Holy Saturday. + self._add_holy_saturday(tr("Sábado Santo")) + + if self._year <= 1967: + # Ascension Day. + self._add_ascension_thursday(tr("Ascensión del Señor")) + + if self._year <= 1967 or 1987 <= self._year <= 2006: + # Corpus Christi. + name = tr("Corpus Christi") + if self._year <= 1999: + self._add_corpus_christi_day(name) + else: + self._add_holiday_57_days_past_easter(name) + + if self._year >= 1932: + # Labor Day. + self._add_labor_day(tr("Día Nacional del Trabajo")) + + # Naval Glories Day. + self._add_holiday_may_21(tr("Día de las Glorias Navales")) + + if self._year >= 2021: + # National Day of Indigenous Peoples. + name = tr("Día Nacional de los Pueblos Indígenas") + if self._year == 2021: + self._add_holiday_jun_21(name) + else: + self._add_holiday(name, self._summer_solstice_date) + + if self._year <= 1967 or self._year >= 1986: + # Saint Peter and Saint Paul's Day. + self._move_holiday(self._add_saints_peter_and_paul_day(tr("San Pedro y San Pablo"))) + + if self._year >= 2007: + # Day of Virgin of Carmen. + self._add_holiday_jul_16(tr("Virgen del Carmen")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Asunción de la Virgen")) + + if 1981 <= self._year <= 1998: + # Day of National Liberation. + self._add_holiday_sep_11(tr("Día de la Liberación Nacional")) + elif 1999 <= self._year <= 2001: + # Day of National Unity. + self._add_holiday_1st_mon_of_sep(tr("Día de la Unidad Nacional")) + + if self._year >= 2007: + self._add_observed( + # National Holiday. + self._add_holiday_sep_17(tr("Fiestas Patrias")), + rule=MON_FRI_ONLY if self._year >= 2017 else MON_ONLY, + ) + + # Independence Day. + self._add_holiday_sep_18(tr("Día de la Independencia")) + + # Army Day. + self._add_holiday_sep_19(tr("Día de las Glorias del Ejército")) + + if self._year >= 2008: + self._add_observed(self._add_holiday_sep_20(tr("Fiestas Patrias")), rule=FRI_ONLY) + + if 1932 <= self._year <= 1944: + self._add_holiday_sep_20(tr("Fiestas Patrias")) + + if self._year >= 1922 and self._year != 1973: + self._move_holiday( + self._add_columbus_day( + # Meeting of Two Worlds' Day. + tr("Día del Encuentro de dos Mundos") + if self._year >= 2000 + # Columbus Day. + else tr("Día de la Raza") + ) + ) + + if self._year >= 2008: + # This holiday is moved to the preceding Friday if it falls on a Tuesday, + # or to the following Friday if it falls on a Wednesday. + self._move_holiday( + self._add_holiday_oct_31( + # National Day of the Evangelical and Protestant Churches. + tr("Día Nacional de las Iglesias Evangélicas y Protestantes") + ), + rule=TUE_TO_PREV_FRI + WED_TO_NEXT_FRI, + ) + + # All Saints' Day. + self._add_all_saints_day(tr("Día de Todos los Santos")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("La Inmaculada Concepción")) + + if 1944 <= self._year <= 1988: + # Christmas Eve. + self._add_christmas_eve(tr("Víspera de Navidad")) + + # Christmas Day. + self._add_christmas_day(tr("Navidad")) + + def _populate_subdiv_ap_public_holidays(self): + if self._year >= 2013: + # Assault and Capture of Cape Arica. + self._add_holiday_jun_7(tr("Asalto y Toma del Morro de Arica")) + + def _populate_subdiv_nb_public_holidays(self): + if self._year >= 2014: + self._add_holiday_aug_20( + # Nativity of Bernardo O'Higgins (Chillán and Chillán Viejo communes) + tr("Nacimiento del Prócer de la Independencia (Chillán y Chillán Viejo)") + ) + + def _populate_bank_holidays(self): + # Bank Holiday. + name = tr("Feriado bancario") + if 1957 <= self._year <= 1975: + self._add_holiday_jun_30(name) + + if self._year >= 1956 and self._year != 1997: + self._add_holiday_dec_31(name) + + @property + def _summer_solstice_date(self) -> tuple[int, int]: + day = 20 + if (self._year % 4 > 1 and self._year <= 2046) or ( + self._year % 4 > 2 and self._year <= 2075 + ): + day = 21 + return JUN, day + + +class CL(Chile): + pass + + +class CHL(Chile): + pass + + +class ChileStaticHolidays: + # National Holiday. + national_holiday = tr("Feriado nacional") + + special_public_holidays = { + 1999: (DEC, 31, national_holiday), + 2022: (SEP, 16, national_holiday), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/china.py b/.venv/lib/python3.12/site-packages/holidays/countries/china.py new file mode 100644 index 00000000..cf51497e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/china.py @@ -0,0 +1,460 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, SEP, OCT, DEC +from holidays.constants import HALF_DAY, PUBLIC +from holidays.groups import ChineseCalendarHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class China(ObservedHolidayBase, ChineseCalendarHolidays, InternationalHolidays, StaticHolidays): + """China holidays. + + References: + * + * [Festivals and Public Holidays](https://zh.wikipedia.org/wiki/中华人民共和国节日与公众假期) + * [2024 changes (Order #795)](https://web.archive.org/web/20250228151847/https://www.gov.cn/zhengce/content/202411/content_6986380.htm) + * [2025](https://web.archive.org/web/20250424041657/https://www.gov.cn/zhengce/content/202411/content_6986382.htm) + * [2024](https://web.archive.org/web/20250227033646/https://www.gov.cn/zhengce/content/202310/content_6911527.htm) + * [2023](https://web.archive.org/web/20250414125053/https://www.gov.cn/gongbao/content/2023/content_5736714.htm) + * [2022](https://web.archive.org/web/20250413071341/http://www.gov.cn/gongbao/content/2021/content_5651728.htm) + * [2021](https://web.archive.org/web/20250424075325/https://www.gov.cn/gongbao/content/2020/content_5567750.htm) + * [2020 Extensions](https://web.archive.org/web/20250427184932/https://www.gov.cn/zhengce/zhengceku/2020-01/27/content_5472352.htm) + * [2020](https://web.archive.org/web/20241222150612/https://www.gov.cn/gongbao/content/2019/content_5459138.htm) + * [2019](https://web.archive.org/web/20241202235023/https://www.gov.cn/gongbao/content/2018/content_5350046.htm) + * [2018](https://web.archive.org/web/20231205013402/https://www.gov.cn/gongbao/content/2017/content_5248221.htm) + * [2017](https://web.archive.org/web/20231205013333/https://www.gov.cn/gongbao/content/2016/content_5148793.htm) + * [2016](https://web.archive.org/web/20231205013233/https://www.gov.cn/gongbao/content/2016/content_2979719.htm) + * [2015](https://web.archive.org/web/20250427025304/https://www.gov.cn/gongbao/content/2015/content_2799019.htm) + * [2014](https://web.archive.org/web/20250426080722/https://www.gov.cn/gongbao/content/2014/content_2561299.htm) + * [2013](https://web.archive.org/web/20240229121946/https://www.gov.cn/gongbao/content/2012/content_2292057.htm) + * [2012](https://web.archive.org/web/20250420220922/https://www.gov.cn/gongbao/content/2011/content_2020918.htm) + * [2011](https://web.archive.org/web/20240812070712/https://www.gov.cn/gongbao/content/2010/content_1765282.htm) + * [2010](https://web.archive.org/web/20101210083603/http://www.gov.cn:80/gongbao/content/2009/content_1487011.htm) + * [2009](https://web.archive.org/web/20230726083438/https://www.gov.cn/gongbao/content/2008/content_1175823.htm) + * [2008](https://web.archive.org/web/20240610103541/https://www.gov.cn/gongbao/content/2008/content_859870.htm) + * [2007](https://web.archive.org/web/20230727050141/https://www.gov.cn/gongbao/content/2007/content_503397.htm) + * [2006](https://web.archive.org/web/20221130214247/https://zh.wikisource.org/wiki/国务院办公厅关于2006年部分节假日安排的通知) + * [2005](https://web.archive.org/web/20210212184000/https://zh.wikisource.org/wiki/国务院办公厅关于2005年部分节假日安排的通知) + * [2004](https://web.archive.org/web/20210212183857/https://zh.wikisource.org/wiki/国务院办公厅关于2004年部分节假日安排的通知) + * [2003](https://web.archive.org/web/20210302090553/https://zh.wikisource.org/wiki/国务院办公厅关于2003年部分节假日休息安排的通知) + * [2002](https://web.archive.org/web/20180122201149/https://zh.wikisource.org/wiki/国务院办公厅关于2002年部分节假日休息安排的通知) + * [2001](https://web.archive.org/web/20180123032517/https://zh.wikisource.org/wiki/国务院办公厅关于2001年春节、“五一”、“十一”放假安排的通知) + + Checked With: + * + * + * + * [2001-2010](https://web.archive.org/web/20250429074341/https://m.wannianli.tianqi.com/fangjiaanpai/2001.html) + + Limitations: + * Only checked with the official General Office of the State Council Notice from 2001 + onwards. + * Due to its complexity, need yearly checks 3-weeks before year's end each year. + """ + + country = "CN" + # %s (observed). + observed_label = tr("%s(观察日)") + supported_categories = (PUBLIC, HALF_DAY) + default_language = "zh_CN" + supported_languages = ("en_US", "th", "zh_CN", "zh_TW") + # Proclamation of the People's Republic of China on Oct 1, 1949. + start_year = 1950 + + def __init__(self, *args, **kwargs): + ChineseCalendarHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=ChinaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 2000) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + + # 元旦 (simp.) / 新年 (trad.) + # Status: In-Use (Statutory). + # Jan 1 in 1949, 1999, 2007, and 2013 revision. + # Consecutive Holidays are available from 2002, except in 2014/2016/2017/2018. + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("元旦"))) + + # 春节 + # Status: In-Use (Statutory). + # Day 1-3 of Chinese New Year in 1949, 1999, 2007, and 2013 revision. + # 2007 revision introduced New Year's Eve (农历除夕) instead of + # New Year's 3rd day; 2013 revision returned it back; + # 2024 revision returned also New Year's Eve. + + # Spring Festival Golden Weekend + # Checked with Official Notice from 2001-2025. + # Consecutive Holidays are available from 2000 (1999 rev.). + + # Chinese New Year (Spring Festival). + chinese_new_year = tr("春节") + # Chinese New Year's Eve. + chinese_new_years_eve = tr("农历除夕") + dts_observed.add(self._add_chinese_new_years_day(chinese_new_year)) + dts_observed.add(self._add_chinese_new_years_day_two(chinese_new_year)) + if 2008 <= self._year <= 2013: + dts_observed.add(self._add_chinese_new_years_eve(chinese_new_years_eve)) + else: + dts_observed.add(self._add_chinese_new_years_day_three(chinese_new_year)) + if self._year >= 2025: + dts_observed.add(self._add_chinese_new_years_eve(chinese_new_years_eve)) + + # 劳动节 + # Status: In-Use (Statutory). + # May 1 in 1949, 1999, 2007, and 2013 revision. + # Additional Holidays (May 2-3) are available from 2000 (1999 rev.) - 2007 (2007 rev.). + # May 2 returned in 2024 revision. + + # Labor Day Golden Weekend + # Checked with Official Notice from 2001-2025. + # Consecutive Holidays are available from 2002, with exception of ????-????. + + # Labor Day. + labor_day = tr("劳动节") + dts_observed.add(self._add_labor_day(labor_day)) + if 2000 <= self._year <= 2007: + dts_observed.add(self._add_labor_day_two(labor_day)) + dts_observed.add(self._add_labor_day_three(labor_day)) + elif self._year >= 2025: + dts_observed.add(self._add_labor_day_two(labor_day)) + + # 国庆节 + # Status: In-Use (Statutory). + # Oct 1-2 in 1949, 1999, 2007, and 2013 revision + # Additional Holiday (Oct 3) is available from Sep 1999 (1999 rev.). + + # National Day Golden Weekend + # Checked with Official Notice from 2001-2023. + + # National Day. + national_day = tr("国庆节") + dts_observed.add(self._add_holiday_oct_1(national_day)) + dts_observed.add(self._add_holiday_oct_2(national_day)) + if self._year >= 1999: + dts_observed.add(self._add_holiday_oct_3(national_day)) + + if self._year >= 2008: + # 清明节 + # Status: In-Use (Statutory). + # Tomb-Sweeping Day in 2007, and 2013 revision. + # Consecutive Holidays are available from 2008, except in 2014/2015/2016/2019. + + # Tomb-Sweeping Day. + dts_observed.add(self._add_qingming_festival(tr("清明节"))) + + # 端午节 + # Status: In-Use (Statutory). + # Dragon Boat Festival in 2007, and 2013 revision. + # Consecutive Holidays are available from 2008, except in 2014/2015/2018/2019/2023. + + # Dragon Boat Festival. + dragon_boat_festival = self._add_dragon_boat_festival(tr("端午节")) + if self._year != 2012: + dts_observed.add(dragon_boat_festival) + + # 中秋节 + # Status: In-Use (Statutory). + # Mid-Autumn Festival in 2007, and 2013 revision. + # Consecutive Holidays are available from 2008, except in 2010/2014/2015/2018/2019. + # Extra Day (Oct 8) is instead added to the National Day Week if overlaps. + + # Mid-Autumn Festival. + mid_autumn_festival = self._add_mid_autumn_festival(tr("中秋节")) + if self._year != 2015: + dts_observed.add(mid_autumn_festival) + + if self.observed: + self._populate_observed(dts_observed, multiple=True) + + def _populate_half_day_holidays(self): + # No in lieus are given for this category. + + # International Women's Day. + self._add_womens_day(tr("国际妇女节")) + + # Youth Day. + self._add_holiday_may_4(tr("五四青年节")) + + # Children's Day. + self._add_childrens_day(tr("六一儿童节")) + + # Army Day. + self._add_holiday_aug_1(tr("建军节")) + + +class CN(China): + pass + + +class CHN(China): + pass + + +class ChinaStaticHolidays: + # Date format (see strftime() Format Codes). + substituted_date_format = tr("%Y-%m-%d") + # Day off (substituted from %s). + substituted_label = tr("休息日(%s日起取代)") + + # Chinese New Year (Spring Festival). + chinese_new_year = tr("春节") + + # Chinese New Year (Spring Festival) Extended Holiday. + chinese_new_year_extended = tr("春节延长假期") + + # Dragon Boat Festival. + dragon_boat_festival = tr("端午节") + + # Mid-Autumn Festival. + mid_autumn_festival = tr("中秋节") + + # 70th Anniversary of the Victory of the Chinese People's War of Resistance against + # Japanese Aggression and the World Anti-Fascist War. + victory_70_anniversary = tr("中国人民抗日战争暨世界反法西斯战争胜利70周年纪念日") + + special_public_holidays = { + 2001: ( + (JAN, 29, JAN, 20), # Spring Festival + (JAN, 30, JAN, 21), # Spring Festival + (MAY, 4, APR, 28), # Labor Day + (MAY, 7, APR, 29), # Labor Day + (OCT, 4, SEP, 29), # National Day + (OCT, 5, SEP, 30), # National Day + ), + 2002: ( + (JAN, 2, DEC, 29, 2001), # New Year's Day + (JAN, 3, DEC, 30, 2001), # New Year's Day + (FEB, 15, FEB, 9), # Spring Festival + (FEB, 18, FEB, 10), # Spring Festival + (MAY, 6, APR, 27), # Labor Day + (MAY, 7, APR, 28), # Labor Day + (OCT, 4, SEP, 28), # National Day + (OCT, 7, SEP, 29), # National Day + ), + 2003: ( + (FEB, 6, FEB, 8), # Spring Festival + (FEB, 7, FEB, 9), # Spring Festival + (MAY, 6, APR, 26), # Labor Day + (MAY, 7, APR, 27), # Labor Day + (OCT, 6, SEP, 27), # National Day + (OCT, 7, SEP, 28), # National Day + ), + 2004: ( + (JAN, 27, JAN, 17), # Spring Festival + (JAN, 28, JAN, 18), # Spring Festival + (MAY, 6, MAY, 8), # Labor Day + (MAY, 7, MAY, 9), # Labor Day + (OCT, 6, OCT, 9), # National Day + (OCT, 7, OCT, 10), # National Day + ), + 2005: ( + (FEB, 14, FEB, 5), # Spring Festival + (FEB, 15, FEB, 6), # Spring Festival + (MAY, 5, APR, 30), # Labor Day + (MAY, 6, MAY, 8), # Labor Day + (OCT, 6, OCT, 8), # National Day + (OCT, 7, OCT, 9), # National Day + ), + 2006: ( + (JAN, 3, DEC, 31, 2005), # New Year's Day + (FEB, 2, JAN, 28), # Spring Festival + (FEB, 3, FEB, 5), # Spring Festival + (MAY, 4, APR, 29), # Labor Day + (MAY, 5, APR, 30), # Labor Day + (OCT, 5, SEP, 30), # National Day + (OCT, 6, OCT, 8), # National Day + ), + 2007: ( + (JAN, 2, DEC, 30, 2006), # New Year's Day + (JAN, 3, DEC, 31, 2006), # New Year's Day + (FEB, 22, FEB, 17), # Spring Festival + (FEB, 23, FEB, 25), # Spring Festival + (MAY, 4, APR, 28), # Labor Day + (MAY, 7, APR, 29), # Labor Day + (OCT, 4, SEP, 29), # National Day + (OCT, 5, SEP, 30), # National Day + (DEC, 31, DEC, 29), # New Year's Day + ), + 2008: ( + (FEB, 11, FEB, 2), # Spring Festival + (FEB, 12, FEB, 3), # Spring Festival + (MAY, 2, MAY, 4), # Labor Day + (SEP, 29, SEP, 27), # National Day + (SEP, 30, SEP, 28), # National Day + ), + 2009: ( + (JAN, 2, JAN, 4), # New Year's Day + (JAN, 29, JAN, 24), # Spring Festival + (JAN, 30, FEB, 1), # Spring Festival + (MAY, 29, MAY, 31), # Dragon Boat Festival + (OCT, 7, SEP, 27), # National Day + (OCT, 8, OCT, 10), # National Day + ), + 2010: ( + (FEB, 18, FEB, 20), # Spring Festival + (FEB, 19, FEB, 21), # Spring Festival + (JUN, 14, JUN, 12), # Dragon Boat Festival + (JUN, 15, JUN, 13), # Dragon Boat Festival + (SEP, 23, SEP, 19), # Mid-Autumn Festival + (SEP, 24, SEP, 25), # Mid-Autumn Festival + (OCT, 6, SEP, 26), # National Day + (OCT, 7, OCT, 9), # National Day + ), + 2011: ( + (FEB, 7, JAN, 30), # Spring Festival + (FEB, 8, FEB, 12), # Spring Festival + (APR, 4, APR, 2), # Tomb-Sweeping Day + (OCT, 6, OCT, 8), # National Day + (OCT, 7, OCT, 9), # National Day + ), + 2012: ( + (JAN, 3, DEC, 31, 2011), # New Year's Day + (JAN, 26, JAN, 21), # Spring Festival + (JAN, 27, JAN, 29), # Spring Festival + (APR, 2, MAR, 31), # Tomb-Sweeping Day + (APR, 3, APR, 1), # Tomb-Sweeping Day + (APR, 30, APR, 28), # Labor Day + (OCT, 5, SEP, 29), # National Day + ), + 2013: ( + (JAN, 2, JAN, 5), # New Year's Day + (JAN, 3, JAN, 6), # New Year's Day + (FEB, 14, FEB, 16), # Spring Festival + (FEB, 15, FEB, 17), # Spring Festival + (APR, 5, APR, 7), # Tomb-Sweeping Day + (APR, 29, APR, 27), # Labor Day + (APR, 30, APR, 28), # Labor Day + (JUN, 10, JUN, 8), # Dragon Boat Festival + (JUN, 11, JUN, 9), # Dragon Boat Festival + (SEP, 20, SEP, 22), # Mid-Autumn Festival + (OCT, 4, SEP, 29), # National Day + (OCT, 7, OCT, 12), # National Day + ), + 2014: ( + (FEB, 5, JAN, 26), # Spring Festival + (FEB, 6, FEB, 8), # Spring Festival + (MAY, 2, MAY, 4), # Labor Day + (OCT, 6, SEP, 28), # National Day + (OCT, 7, OCT, 11), # National Day + ), + 2015: ( + (JAN, 2, JAN, 4), # New Year's Day + (FEB, 18, FEB, 15), # Spring Festival + (FEB, 24, FEB, 28), # Spring Festival + (SEP, 3, victory_70_anniversary), + (SEP, 4, SEP, 6), # 70th Anniversary of the Victory + (OCT, 7, OCT, 10), # National Day + ), + 2016: ( + (FEB, 11, FEB, 6), # Spring Festival + (FEB, 12, FEB, 14), # Spring Festival + (JUN, 10, JUN, 12), # Dragon Boat Festival + (SEP, 16, SEP, 18), # Mid-Autumn Festival + (OCT, 6, OCT, 8), # National Day + (OCT, 7, OCT, 9), # National Day + ), + 2017: ( + (JAN, 27, JAN, 22), # Spring Festival + (FEB, 2, FEB, 4), # Spring Festival + (APR, 3, APR, 1), # Tomb-Sweeping Day + (MAY, 29, MAY, 27), # Dragon Boat Festival + (OCT, 6, SEP, 30), # National Day + ), + 2018: ( + (FEB, 15, FEB, 11), # Spring Festival + (FEB, 21, FEB, 24), # Spring Festival + (APR, 6, APR, 8), # Tomb-Sweeping Day + (APR, 30, APR, 28), # Labor Day + (OCT, 4, SEP, 29), # National Day + (OCT, 5, SEP, 30), # National Day + (DEC, 31, DEC, 29), # New Year's Day + ), + 2019: ( + (FEB, 4, FEB, 2), # Spring Festival + (FEB, 8, FEB, 3), # Spring Festival + (OCT, 4, SEP, 29), # National Day + (OCT, 7, OCT, 12), # National Day + ), + 2020: ( + (JAN, 24, JAN, 19), # Spring Festival + # JAN, 30 in special_public_holidays_observed + (JAN, 31, chinese_new_year_extended), # Spring Festival Extended Holiday + (FEB, 1, chinese_new_year_extended), # Spring Festival Extended Holiday + (FEB, 2, chinese_new_year_extended), # Spring Festival Extended Holiday + (MAY, 4, APR, 26), # Labor Day + (MAY, 5, MAY, 9), # Labor Day + (JUN, 26, JUN, 28), # Dragon Boat Festival + (OCT, 7, SEP, 27), # National Day + (OCT, 8, OCT, 10), # National Day + ), + 2021: ( + (FEB, 11, FEB, 7), # Spring Festival + (FEB, 17, FEB, 20), # Spring Festival + (MAY, 4, APR, 25), # Labor Day + (MAY, 5, MAY, 8), # Labor Day + (SEP, 20, SEP, 18), # Mid-Autumn Festival + (OCT, 6, SEP, 26), # National Day + (OCT, 7, OCT, 9), # National Day + ), + 2022: ( + (JAN, 31, JAN, 29), # Spring Festival + (FEB, 4, JAN, 30), # Spring Festival + (APR, 4, APR, 2), # Tomb-Sweeping Day + (MAY, 3, APR, 24), # Labor Day + (MAY, 4, MAY, 7), # Labor Day + (OCT, 6, OCT, 8), # National Day + (OCT, 7, OCT, 9), # National Day + ), + 2023: ( + (JAN, 26, JAN, 28), # Spring Festival + (JAN, 27, JAN, 29), # Spring Festival + (MAY, 2, APR, 23), # Labor Day + (MAY, 3, MAY, 6), # Labor Day + (JUN, 23, JUN, 25), # Dragon Boat Festival + (OCT, 5, OCT, 7), # National Day + (OCT, 6, OCT, 8), # National Day + ), + 2024: ( + (FEB, 15, FEB, 4), # Spring Festival + (FEB, 16, FEB, 18), # Spring Festival + (APR, 5, APR, 7), # Tomb-Sweeping Day + (MAY, 2, APR, 28), # Labor Day + (MAY, 3, MAY, 11), # Labor Day + (SEP, 16, SEP, 14), # Mid-Autumn Festival + (OCT, 4, SEP, 29), # National Day + (OCT, 7, OCT, 12), # National Day + ), + 2025: ( + (FEB, 3, JAN, 26), # Spring Festival + (FEB, 4, FEB, 8), # Spring Festival + (MAY, 5, APR, 27), # Labor Day + (OCT, 7, SEP, 28), # National Day + (OCT, 8, OCT, 11), # National Day + ), + } + + special_public_holidays_observed = { + 2012: (JUN, 22, dragon_boat_festival), # observed from Jun 23 + 2015: (OCT, 6, mid_autumn_festival), # observed from Sep 27 + 2020: ( + (JAN, 30, chinese_new_year), # Spring Festival (extended due to Covid-19 decree) + (OCT, 6, mid_autumn_festival), # observed from Oct 1, overlap with National Day + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/christmas_island.py b/.venv/lib/python3.12/site-packages/holidays/countries/christmas_island.py new file mode 100644 index 00000000..faaadb50 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/christmas_island.py @@ -0,0 +1,215 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomChineseHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ( + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class ChristmasIsland( + ObservedHolidayBase, + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Christmas Island holidays. + + References: + * + * [2007](https://web.archive.org/web/20250612072036/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2006/01-2006_Public_Holidays_2007_CI.doc) + * [2008](https://web.archive.org/web/20240224131231/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2007/05-2007_Public_Holidays_CI.pdf) + * [2008 Hari Raya Puasa](https://web.archive.org/web/20240331104649/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2008/03_2008_Observance_of_Hari_Raya_Puasa_2008.pdf) + * [2009](https://web.archive.org/web/20231211180406/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2008/02-2008_2009_public_holiday_CI_gazette.pdf) + * [2010](https://web.archive.org/web/20250612051603/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2009/2009-Gazette_5-2009-CI-Proclamation_of_2010_Special_Public_and_Bank_Holidays.pdf) + * [2013](https://web.archive.org/web/20240805060802/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2012/2012-Gazette_7-2012-CI-Proclamation_of_2013_Public_Holidays_for_Christmas_Island.pdf) + * [2014](https://web.archive.org/web/20240718175750/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2013/2013-Gazette_2-2013-Christmas_Island_2014_Public_Holidays.pdf) + * [2016 Hari Raya Puasa](https://web.archive.org/web/20240222235345/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2016/2016-Gazette_4-2016-CI-Proclamation_Special_Public_and_Bank_Holidays_2016.pdf) + * [2017](https://web.archive.org/web/20240226014639/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2016/2016-Gazette_1-2016-CI-Proclamation_Special_Public_and_Bank_Holidays_2017.pdf) + * [2019](https://web.archive.org/web/20250517064053/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_bulletins/2018/files/A37-2018.pdf) + * [2020](https://web.archive.org/web/20240830230128/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_bulletins/2019/files/A52-2019.pdf) + * [2021](https://web.archive.org/web/20240713155232/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_bulletins/2020/files/a40-ci-public-holidays-2021-proclamation.pdf) + * [2022](https://web.archive.org/web/20240626092850/https://www.infrastructure.gov.au/sites/default/files/documents/a32-2021-2022-public-holidays-christmas-island.pdf) + * [2023](https://web.archive.org/web/20250612044842/https://www.infrastructure.gov.au/sites/default/files/documents/A06-2022-notice-proclamation-special-public-bank-holidays-2023-ci.pdf) + * [2023 Hari Raya Haji](https://web.archive.org/web/20240804112114/https://www.infrastructure.gov.au/sites/default/files/documents/a06-2023_community_bulletin_-_change_of_public_holiday_date_for_hari_raya_haji_2023.pdf) + * [2024](https://web.archive.org/web/20240519034837/https://www.infrastructure.gov.au/sites/default/files/documents/a11-2023-2024-public-holidays-christmas-island.pdf) + * [2025](https://web.archive.org/web/20250610185153/https://www.infrastructure.gov.au/sites/default/files/documents/a20-2024-administrator-community-bulletin-ci-public-holidays-2025.pdf) + """ + + country = "CX" + default_language = "en_CX" + # %s (observed). + observed_label = tr("%s (observed)") + # %s (estimated). + estimated_label = tr("%s (estimated)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observed, estimated)") + supported_languages = ("en_CX", "en_US") + start_year = 2007 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + ChineseCalendarHolidays.__init__(self, cls=ChristmasIslandChineseHolidays) + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=ChristmasIslandIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, ChristmasIslandStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Australia Day. + self._add_observed(self._add_holiday_jan_26(tr("Australia Day"))) + + # Chinese New Year. + name = tr("Chinese New Year") + if self._year != 2020: + self._add_observed(self._add_chinese_new_years_day(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + self._add_observed( + self._add_chinese_new_years_day_two(name), rule=SAT_SUN_TO_NEXT_MON_TUE + ) + + # Labor Day. + name = tr("Labour Day") + if self._year in {2009, 2010, 2014, 2021, 2025}: + self._add_holiday_4th_mon_of_mar(name) + else: + self._add_holiday_3rd_mon_of_mar(name) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # ANZAC Day. + self._add_observed(self._add_anzac_day(tr("ANZAC Day"))) + + # Territory Day. + self._add_holiday_1st_mon_of_oct(tr("Territory Day")) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE + MON_TO_NEXT_TUE, + ) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day"))) + + # Eid al-Fitr. + for dt in self._add_eid_al_fitr_day(tr("Hari Raya Puasa")): + self._add_observed(dt) + + # Eid al-Adha. + for dt in self._add_eid_al_adha_day(tr("Hari Raya Haji")): + if self._year not in {2014, 2025}: + self._add_observed(dt) + + +class ChristmasIslandChineseHolidays(_CustomChineseHolidays): + LUNAR_NEW_YEAR_DATES = { + 2007: (FEB, 19), + 2009: (JAN, 27), + 2010: (FEB, 15), + 2023: (JAN, 23), + } + + +class ChristmasIslandIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 30), + 2010: (NOV, 16), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2016: (SEP, 13), + 2017: (SEP, 1), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 2007: (OCT, 15), + 2008: (OCT, 1), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2016: (JUL, 6), + 2017: (JUN, 24), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + +class CX(ChristmasIsland): + pass + + +class CXR(ChristmasIsland): + pass + + +class ChristmasIslandStaticHolidays: + """Christmas Island special holidays. + + References: + * [National Day of Mourning 2022](https://web.archive.org/web/20240712013008/https://www.infrastructure.gov.au/sites/default/files/documents/03-2022-proclamation-ci-day-of-mourning.pdf) + """ + + # Chinese New Year. + chinese_new_year = tr("Chinese New Year") + + # Eid al-Adha. + eid_al_adha = tr("Hari Raya Haji") + + special_public_holidays = { + # National Day of Mourning for Queen Elizabeth II. + 2022: (SEP, 22, tr("National Day of Mourning for Queen Elizabeth II")), + } + + special_public_holidays_observed = { + 2014: (OCT, 7, eid_al_adha), + 2020: ( + (JAN, 28, chinese_new_year), + (JAN, 29, chinese_new_year), + ), + 2025: (JUN, 6, eid_al_adha), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/cocos_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/cocos_islands.py new file mode 100644 index 00000000..f07ba77b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/cocos_islands.py @@ -0,0 +1,260 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class CocosIslands( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Cocos (Keeling) Islands holidays. + + References: + * + * + * + + * [2007](https://web.archive.org/web/20250605022855/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2006/02_2006_Public_Holidays_2007_CKI.doc) + * [2008](https://web.archive.org/web/20240718120923/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2007/06-2007_Public_Holidays_CKI.pdf) + * [2008 Eid al-Fitr](https://web.archive.org/web/20240331104649/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2008/03_2008_Observance_of_Hari_Raya_Puasa_2008.pdf) + * [2009](https://web.archive.org/web/20231208153529/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2008/01-2008-2009-public-holiday-CKI-gazette.pdf) + * [2010](https://archive.org/details/cocos-island-2009-gazette-6-2009-cki-proclamation-of-2010-special-public-bank-holidays) + * [2013](https://web.archive.org/web/20240805055409/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2012/2012-Gazette_8-2012-CKI-Proclamation_of_2013_Public_Holidays_for_Cocos_(Keeling)_Islands.pdf) + * [2014](https://web.archive.org/web/20240718123844/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2013/2013-Gazette_3-2013-Cocos_K_Islands_2014_Public_Holidays.pdf) + * [2016](https://archive.org/details/cocos-island-2015-gazette-4-2015-cki-proclamation-of-2016-special-public-bank-holidays) + * [2016 Eid al-Fitr](https://web.archive.org/web/20231208203746/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2016/2016-Gazette_3-2016-CKI-Proclamation_Special_Public_and_Bank_Holidays_2016.pdf) + * [2017](https://web.archive.org/web/20240303203132/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_gazette/files/2016/2016-Gazette_2-2016-CKI-Proclamation_Special_Public_and_Bank_Holidays_2017.pdf) + * [2019](https://web.archive.org/web/20241123131420/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_bulletins/2018/files/A38-2018.pdf) + * [2019 Act of Self Determination Day](https://web.archive.org/web/20220518200522/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_bulletins/2019/files/A10-2019-bank-holidays.pdf) + * [2020](https://web.archive.org/web/20240521203357/https://www.infrastructure.gov.au/sites/default/files/migrated/territories/indian_ocean/iot_bulletins/2019/files/A53-2019.pdf) + * [2021](https://web.archive.org/web/20250502204052/https://www.infrastructure.gov.au/territories-regions-cities/territories/indian_ocean/iot_bulletins/2020/A041-2020-cki-public-holidays) + * [2022](https://web.archive.org/web/20250429071240/https://www.infrastructure.gov.au/sites/default/files/documents/a33-2021-2022-public-holidays-cocos-keeling-islands.pdf) + * [2022 Eid al-Fitr](https://web.archive.org/web/20220810061351/https://www.infrastructure.gov.au/sites/default/files/documents/Gazette-Change-to-CKI-Hari-Raya-Puasa-2022.pdf) + * [2023](https://web.archive.org/web/20240711221156/https://www.infrastructure.gov.au/sites/default/files/documents/a19-2022-community-bulletin-2023-kings-birthday-cocos-keeling-islands.pdf) + * [2023 Eid al-Fitr](https://web.archive.org/web/20250627103728/https://www.infrastructure.gov.au/sites/default/files/documents/a02-2023-community-bulletin-change-of-public-holiday-date-for-hari-raya-puasa-2023-cocos-keeling-islands.pdf) + * [2023 Eid al-Adha](https://web.archive.org/web/20240804112114/https://www.infrastructure.gov.au/sites/default/files/documents/a06-2023_community_bulletin_-_change_of_public_holiday_date_for_hari_raya_haji_2023.pdf) + * [2024](https://web.archive.org/web/20250207203100/https://www.infrastructure.gov.au/sites/default/files/documents/a12-2023-2024-public-holidays-cocos-k-islands.pdf) + * [2025](https://web.archive.org/web/20250413083314/https://www.infrastructure.gov.au/sites/default/files/documents/a21-2024-administrator-community-bulletin-cki-public-holidays-2025.pdf) + """ + + country = "CC" + default_language = "en_CC" + # %s (observed). + observed_label = tr("%s (observed)") + # %s (estimated). + estimated_label = tr("%s (estimated)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observed, estimated)") + supported_languages = ("coa_CC", "en_CC", "en_US") + # Act of Self Determination 1984. + start_year = 1985 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=CocosIslandsIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, CocosIslandsStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Australia Day. + self._add_observed(self._add_holiday_jan_26(tr("Australia Day"))) + + act_of_self_determination_dates = { + 2007: (APR, 5), + } + # Act of Self Determination Day. + name = tr("Act of Self Determination Day") + if dt := act_of_self_determination_dates.get(self._year): + self._add_holiday(name, dt) + else: + dt = self._add_holiday_apr_6(name) + if self._year != 2019: + self._add_observed(dt) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # ANZAC Day. + self._add_observed(self._add_anzac_day(tr("ANZAC Day"))) + + queens_kings_birthday_dates = { + 2021: (JUN, 7), + 2022: (JUN, 6), + 2023: (JUN, 6), + 2024: (JUN, 6), + } + name = ( + # King's Birthday. + tr("King's Birthday") + if self._year >= 2023 + # Queen's Birthday. + else tr("Queen's Birthday") + ) + if dt := queens_kings_birthday_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_2nd_mon_of_jun(name) + + # Placed before Christmas Day for proper observed calculation. + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE + MON_TO_NEXT_TUE, + ) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day"))) + + # Islamic holidays. + + if self._year <= 2019: + # Islamic New Year. + for dt in self._add_islamic_new_year_day(tr("Islamic New Year")): + self._add_observed(dt) + + # Prophet's Birthday. + for dt in self._add_mawlid_day(tr("Prophet's Birthday")): + self._add_observed(dt) + + # Eid al-Fitr. + for dt in self._add_eid_al_fitr_day(tr("Eid al-Fitr")): + self._add_observed(dt) + + # Eid al-Adha. + for dt in self._add_eid_al_adha_day(tr("Eid al-Adha")): + if self._year != 2025: + self._add_observed(dt) + + +class CocosIslandsIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 30), + 2010: (NOV, 16), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2016: (SEP, 13), + 2017: (SEP, 1), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 2007: (OCT, 15), + 2008: (OCT, 1), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2016: (JUL, 6), + 2017: (JUN, 24), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 3), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + HIJRI_NEW_YEAR_DATES = { + 2007: (JAN, 22), + 2008: (JAN, 10), + 2009: (DEC, 18), + 2010: (DEC, 7), + 2013: (NOV, 4), + 2014: (OCT, 25), + 2016: (OCT, 3), + 2017: (SEP, 22), + 2019: (SEP, 1), + } + + MAWLID_DATES = { + 2007: (APR, 2), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2013: (JAN, 24), + 2014: (JAN, 13), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + +class CC(CocosIslands): + pass + + +class CCK(CocosIslands): + pass + + +class CocosIslandsStaticHolidays: + """Cocos (Keeling) Islands special holidays. + + References: + * [National Day of Mourning 2022](https://web.archive.org/web/20240712213751/https://www.infrastructure.gov.au/sites/default/files/documents/04-2022-proclamation-cki-day-of-mourning.pdf) + """ + + special_public_holidays = { + # National Day of Mourning for Queen Elizabeth II. + 2022: (SEP, 22, tr("National Day of Mourning for Queen Elizabeth II")), + } + + special_public_holidays_observed = { + 2019: (APR, 10, tr("Act of Self Determination Day")), + 2025: (JUN, 6, tr("Eid al-Adha")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/colombia.py b/.venv/lib/python3.12/site-packages/holidays/countries/colombia.py new file mode 100644 index 00000000..3ee60044 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/colombia.py @@ -0,0 +1,120 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, ALL_TO_NEXT_MON + + +class Colombia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Colombia holidays. + + References: + * [Ley 35 de 1939 (DEC 4)](https://web.archive.org/web/20250429071624/https://www.funcionpublica.gov.co/eva/gestornormativo/norma_pdf.php?i=86145) + * [Decreto 2663 de 1950 (AUG 5)](https://web.archive.org/web/20241113003142/https://www.suin-juriscol.gov.co/viewDocument.asp?id=1874133) + * [Decreto 3743 de 1950 (DEC 20)](https://web.archive.org/web/20240725032513/http://suin-juriscol.gov.co/viewDocument.asp?id=1535683) + * [Ley 51 de 1983 (DEC 6)](https://web.archive.org/web/20250423030608/https://www.funcionpublica.gov.co/eva/gestornormativo/norma.php?i=4954) + + A few links below to calendars from the 1980s to demonstrate this law change. + In 1984 some calendars still use the old rules, presumably because they were printed + prior to the declaration of law change: + * [1981](https://web.archive.org/web/20250427173739/https://cloud10.todocoleccion.online/calendarios-antiguos/tc/2018/07/02/19/126899607_96874586.jpg) + * [1982](https://web.archive.org/web/20250427173704/https://cloud10.todocoleccion.online/calendarios-antiguos/tc/2016/08/19/12/58620712_34642074.jpg) + * [1984](https://web.archive.org/web/20250427173707/https://cloud10.todocoleccion.online/calendarios-antiguos/tc/2017/07/12/15/92811790_62818054.jpg) + """ + + country = "CO" + default_language = "es" + # %s (observed). + observed_label = tr("%s (observado)") + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", ALL_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1984) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + if self._year >= 1951: + # Epiphany. + self._move_holiday(self._add_epiphany_day(tr("Día de los Reyes Magos"))) + + # Saint Joseph's Day. + self._move_holiday(self._add_saint_josephs_day(tr("Día de San José"))) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Ascension Day. + self._move_holiday(self._add_ascension_thursday(tr("Ascensión del señor"))) + + # Corpus Christi. + self._move_holiday(self._add_corpus_christi_day(tr("Corpus Christi"))) + + # Labor Day. + self._add_labor_day(tr("Día del Trabajo")) + + if self._year >= 1984: + self._move_holiday( + # Sacred Heart. + self._add_holiday_68_days_past_easter(tr("Sagrado Corazón")) + ) + + if self._year >= 1951: + # Saint Peter and Saint Paul's Day. + self._move_holiday(self._add_saints_peter_and_paul_day(tr("San Pedro y San Pablo"))) + + # Independence Day. + self._add_holiday_jul_20(tr("Día de la Independencia")) + + # Battle of Boyaca. + self._add_holiday_aug_7(tr("Batalla de Boyacá")) + + if self._year >= 1951: + # Assumption Day. + self._move_holiday(self._add_assumption_of_mary_day(tr("La Asunción"))) + + # Columbus Day. + self._move_holiday(self._add_columbus_day(tr("Día de la Raza"))) + + if self._year >= 1951: + # All Saints' Day. + self._move_holiday(self._add_all_saints_day(tr("Día de Todos los Santos"))) + + self._move_holiday( + # Independence of Cartagena. + self._add_holiday_nov_11(tr("Independencia de Cartagena")) + ) + + if self._year >= 1951: + # Immaculate Conception. + self._add_immaculate_conception_day(tr("La Inmaculada Concepción")) + + # Christmas Day. + self._add_christmas_day(tr("Navidad")) + + +class CO(Colombia): + pass + + +class COL(Colombia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/congo.py b/.venv/lib/python3.12/site-packages/holidays/countries/congo.py new file mode 100644 index 00000000..34aeb974 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/congo.py @@ -0,0 +1,79 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Congo(HolidayBase, ChristianHolidays, InternationalHolidays): + """Congo holidays. + + References: + * [Loi N° 2-94](https://web.archive.org/web/20241003070938/http://mokili.free.fr/jours_feries.php) + * [Loi N° 18-2010](https://web.archive.org/web/20250427173832/https://www.finances.gouv.cg/sites/default/files/documents/n¯18-2010%20du%2027%20novembre%202010.PDF) + + Cross-Checked With: + * + """ + + country = "CG" + default_language = "fr" + supported_languages = ("en_US", "fr") + # Loi N° 2-94 of 1 March 1994. + start_year = 1994 + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Jour de l'An")) + + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + # Labor Day. + self._add_labor_day(tr("Fête du Travail")) + + # Ascension Day. + self._add_ascension_thursday(tr("Ascension")) + + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + + # Reconciliation Day. + self._add_holiday_jun_10(tr("Fête de la Réconciliation")) + + # National Day. + self._add_holiday_aug_15(tr("Fête Nationale")) + + # All Saints' Day. + self._add_all_saints_day(tr("Toussaint")) + + if self._year >= 2010: + # Republic Day. + self._add_holiday_nov_28(tr("Jour de la République")) + + # Christmas Day. + self._add_christmas_day(tr("Noël")) + + +class CG(Congo): + pass + + +class COG(Congo): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/cook_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/cook_islands.py new file mode 100644 index 00000000..8c388bfc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/cook_islands.py @@ -0,0 +1,148 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class CookIslands(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Cook Islands holidays. + + References: + * + * [Public Holidays Amendment Act 1970-71](https://web.archive.org/web/20250530101809/https://cookislandslaws.gov.ck/#/Laws-as-Made?id=414&name=Public%20Holidays%20Amendment%20Act%201970-71%20No%2029) + * [Public Holidays Act 1999 (Law as Made)](https://web.archive.org/web/20250530120928/https://cookislandslaws.gov.ck/#/Laws-as-Made?id=1241&name=Public%20Holidays%20Act%201999%20No%2017) + * [Public Holidays (Aitutaki Gospel Day) Order 1989](https://web.archive.org/web/20250530121249/https://parliament.gov.ck/wp-content/uploads/2022/07/Public-Holidays-Aitutaki-Gospel-Day-Order-1990-No.-9.pdf) + * [Public Holidays Act 1999 (Consolidated Law)](https://web.archive.org/web/20250530101809/https://cookislandslaws.gov.ck/#/InternalConsolidatedLaws?legalId=LOCI.PHA99&parent_id=Public%20Holidays%20Act%201999) + * [Gospel Days](https://web.archive.org/web/20110928152006/http://www.cookislands.org.uk/gospelday.html) + * [Public Holidays (Ra o te Ui Ariki) Amendment Act 2011](https://web.archive.org/web/20250530101809/https://cookislandslaws.gov.ck/#/Laws-as-Made?id=1553&name=Public%20Holidays%20(Ra%20o%20te%20Ui%20Ariki)%20Amendment%20Act%202011%20No%204) + * [Public Holidays (Ra o te Ui Ariki) Amendment 2013](https://web.archive.org/web/20250530122050/https://parliament.gov.ck/wp-content/uploads/2020/02/Public-Holidays-Ra-o-te-Ui-Ariki-No.-4.pdf) + * [2004](https://web.archive.org/web/20090326004400/http://www.cook-islands.gov.ck/view_release.php?release_id=429) + * [2008](https://web.archive.org/web/20090326003301/http://www.stats.gov.ck/NewsEvents/PublicHolidays.pdf) + """ + + country = "CK" + default_language = "en_CK" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_CK", "en_US") + # Public Holiday Act 1999. + start_year = 2000 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self._add_observed( + # New Year's Day. + self._add_new_years_day(tr("New Year's Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Day after New Year's Day. + self._add_new_years_day_two(tr("Day after New Year's Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + # Anzac Day. + self._add_anzac_day(tr("Anzac Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Sovereign's Birthday. + self._add_holiday_1st_mon_of_jun(tr("Sovereign's Birthday")) + + if self._year >= 2012: + # Day of the House of Ariki. + name = tr("Ra o te Ui Ariki") + if self._year >= 2013: + self._add_holiday_1st_fri_of_jul(name) + else: + self._add_holiday_jun_6(name) + + # Constitution Day. + self._add_observed(self._add_holiday_aug_4(tr("Constitution Day"))) + + # Cook Islands Gospel Day. + self._add_observed(self._add_holiday_oct_26(tr("Cook Islands Gospel Day"))) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + if self._year <= 2011: + # Penrhyn Gospel Day. + self._add_observed(self._add_holiday_mar_13(tr("Penrhyn Gospel Day"))) + + # Palmerston Gospel Day. + self._add_observed(self._add_holiday_may_25(tr("Palmerston Gospel Day"))) + + # Mangaia Gospel Day. + self._add_observed(self._add_holiday_jun_15(tr("Mangaia Gospel Day"))) + + # Atiu Gospel Day. + self._add_observed(self._add_holiday_jul_20(tr("Atiu Gospel Day"))) + + # Mitiaro Gospel Day. + self._add_observed(self._add_holiday_jul_21(tr("Mitiaro Gospel Day"))) + + self._add_observed( + # Mauke Gospel Day. + self._add_holiday_jul_23(tr("Mauke Gospel Day")), + rule=SAT_TO_NEXT_TUE if self._year in {2005, 2011} else None, + ) + + # Rarotonga Gospel Day. + self._add_observed(self._add_holiday_jul_25(tr("Rarotonga Gospel Day"))) + + # Manihiki Gospel Day. + self._add_observed(self._add_holiday_aug_8(tr("Manihiki Gospel Day"))) + + # Rakahanga Gospel Day. + self._add_observed(self._add_holiday_aug_15(tr("Rakahanga Gospel Day"))) + + # Aitutaki Gospel Day. + self._add_observed(self._add_holiday_oct_27(tr("Aitutaki Gospel Day"))) + + # Pukapuka Gospel Day. + self._add_observed(self._add_holiday_dec_8(tr("Pukapuka Gospel Day"))) + + +class CK(CookIslands): + pass + + +class COK(CookIslands): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/costa_rica.py b/.venv/lib/python3.12/site-packages/holidays/countries/costa_rica.py new file mode 100644 index 00000000..116d1b5a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/costa_rica.py @@ -0,0 +1,128 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + ALL_TO_NEAREST_MON_LATAM, + ALL_TO_NEXT_SUN, + WORKDAY_TO_NEXT_MON, +) + + +class CostaRica(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Costa Rica holidays. + + References: + * + * + * Law #8442 from 19.04.2005 + * Law #8604 from 17.09.2007 + * Law #8753 from 25.07.2009 + * Law #8886 from 01.11.2010 + * Law #9803 from 19.05.2020 + * Law #10050 from 25.10.2021 + """ + + country = "CR" + default_language = "es" + # %s (observed). + observed_label = tr("%s (observado)") + supported_categories = (OPTIONAL, PUBLIC) + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", ALL_TO_NEAREST_MON_LATAM) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Juan Santamaría Day. + apr_11 = self._add_holiday_apr_11(tr("Día de Juan Santamaría")) + if 2006 <= self._year <= 2010: + self._move_holiday(apr_11, rule=WORKDAY_TO_NEXT_MON) + elif self._year in {2023, 2024}: + self._move_holiday(apr_11) + + # International Labor Day. + dt = self._add_labor_day(tr("Día Internacional del Trabajo")) + if self._year == 2021: + self._move_holiday(dt) + + # Annexation of the Party of Nicoya to Costa Rica. + jul_25 = self._add_holiday_jul_25(tr("Anexión del Partido de Nicoya a Costa Rica")) + if 2005 <= self._year <= 2008: + self._move_holiday(jul_25, rule=WORKDAY_TO_NEXT_MON) + elif 2020 <= self._year <= 2024: + self._move_holiday(jul_25) + + # Mother's Day. + dt = self._add_assumption_of_mary_day(tr("Día de la Madre")) + if 2005 <= self._year <= 2007: + self._move_holiday(dt, rule=WORKDAY_TO_NEXT_MON) + elif self._year in {2020, 2023, 2024}: + self._move_holiday(dt) + + # Independence Day. + sep_15 = self._add_holiday_sep_15(tr("Día de la Independencia")) + if self._year in {2020, 2021, 2022}: + self._move_holiday(sep_15) + + if self._year <= 2019: + self._move_holiday( + # Cultures Day. + self._add_columbus_day(tr("Día de las Culturas")), + rule=WORKDAY_TO_NEXT_MON, + ) + + # Christmas Day. + self._add_christmas_day(tr("Navidad")) + + def _populate_optional_holidays(self): + # Feast of Our Lady of the Angels. + self._add_holiday_aug_2(tr("Fiesta de Nuestra Señora de los Ángeles")) + + if self._year >= 2021: + aug_31 = self._add_holiday_aug_31( + # Day of the Black Person and Afro-Costa Rican Culture. + tr("Día de la Persona Negra y la Cultura Afrocostarricense") + ) + if self._year in {2021, 2022, 2023}: + # Move to next Sunday. + self._move_holiday(aug_31, rule=ALL_TO_NEXT_SUN) + + if self._year >= 2020: + # Army Abolition Day. + dec_1 = self._add_holiday_dec_1(tr("Día de la Abolición del Ejército")) + if self._year in {2020, 2021, 2022}: + self._move_holiday(dec_1) + + +class CR(CostaRica): + pass + + +class CRI(CostaRica): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/croatia.py b/.venv/lib/python3.12/site-packages/holidays/countries/croatia.py new file mode 100644 index 00000000..9651bf62 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/croatia.py @@ -0,0 +1,112 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Croatia(HolidayBase, ChristianHolidays, InternationalHolidays): + """Croatia holidays. + + References: + * + * + * + + Updated with act 022-03 / 19-01 / 219 of 14 November 2019 + """ + + country = "HR" + default_language = "hr" + supported_languages = ("en_US", "hr", "uk") + start_year = 1992 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nova godina")) + + if self._year != 2002: + # Epiphany. + self._add_epiphany_day(tr("Bogojavljenje ili Sveta tri kralja")) + + if self._year >= 2009: + # Easter Sunday. + self._add_easter_sunday(tr("Uskrs")) + + # Easter Monday. + self._add_easter_monday(tr("Uskrsni ponedjeljak")) + + if self._year >= 2002: + # Corpus Christi. + self._add_corpus_christi_day(tr("Tijelovo")) + + # Labor Day. + self._add_labor_day(tr("Praznik rada")) + + if self._year >= 1996: + # Statehood Day. + name = tr("Dan državnosti") + if 2002 <= self._year <= 2019: + self._add_holiday_jun_25(name) + else: + self._add_holiday_may_30(name) + + # Anti-Fascist Struggle Day. + self._add_holiday_jun_22(tr("Dan antifašističke borbe")) + + self._add_holiday_aug_5( + # Victory and Homeland Thanksgiving Day and Croatian Veterans Day. + tr("Dan pobjede i domovinske zahvalnosti i Dan hrvatskih branitelja") + if self._year >= 2008 + # Victory and Homeland Thanksgiving Day. + else tr("Dan pobjede i domovinske zahvalnosti") + ) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Velika Gospa")) + + if 2002 <= self._year <= 2019: + # Independence Day. + self._add_holiday_oct_8(tr("Dan neovisnosti")) + + # All Saints' Day. + self._add_all_saints_day(tr("Svi sveti")) + + if self._year >= 2020: + self._add_holiday_nov_18( + # Remembrance Day. + tr( + "Dan sjećanja na žrtve Domovinskog rata i " + "Dan sjećanja na žrtvu Vukovara i Škabrnje" + ) + ) + + # Christmas Day. + self._add_christmas_day(tr("Božić")) + + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Sveti Stjepan")) + + +class HR(Croatia): + pass + + +class HRV(Croatia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/cuba.py b/.venv/lib/python3.12/site-packages/holidays/countries/cuba.py new file mode 100644 index 00000000..893daac0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/cuba.py @@ -0,0 +1,108 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Cuba(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Cuba holidays. + + References: + * + * [1984 (DEC 28)](https://web.archive.org/web/20240726190205/https://files.sld.cu/prevemi/files/2013/03/ley_49_codigo_trabajo_1984.pdf) + * [2007 (NOV 19)](https://web.archive.org/web/20220705173115/https://www.gacetaoficial.gob.cu/sites/default/files/go_x_053_2007.pdf) + * [2013 (DEC 20)](https://web.archive.org/web/20241125112840/http://www.gacetaoficial.gob.cu/es/ley-no-116-codigo-de-trabajo/) + + Certain holidays details: + * Good Friday: + Granted temporarily in 2012 and 2013, permanently granted in 2013 decree for 2014 + and onwards: + * + * + + * Christmas Day: + In 1969, Christmas was cancelled for the sugar harvest but then was cancelled for good: + * + In 1997, Christmas was temporarily back for the Pope's visit: + * + In 1998, Christmas returns for good: + * + * + + For holidays that can be moved to a Monday if they fall on a Sunday, between 1984 + and 2013, the State Committee of Work and Social Security would determine if they + would be moved to the Monday, or if they would stay on the Sunday, presumably + depending on quotas. After 2013, they always move to Monday. I could not find any + records of this, so I implemented this making it always go to the next Monday. + """ + + country = "CU" + default_language = "es" + # %s (observed). + observed_label = tr("%s (observado)") + supported_languages = ("en_US", "es", "uk") + # This calendar only works from 1959 onwards. + start_year = 1959 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Liberation Day. + jan_1 = self._add_holiday_jan_1(tr("Triunfo de la Revolución")) + if self._year <= 2013: + self._add_observed(jan_1) + + if self._year >= 2008: + # Victory Day. + self._add_holiday_jan_2(tr("Día de la Victoria")) + + if self._year >= 2012: + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # International Workers' Day. + self._add_observed(self._add_labor_day(tr("Día Internacional de los Trabajadores"))) + + # Commemoration of the Assault of the Moncada garrison. + self._add_holiday_jul_25(tr("Conmemoración del asalto a Moncada")) + + # Day of the National Rebellion. + self._add_holiday_jul_26(tr("Día de la Rebeldía Nacional")) + + # Commemoration of the Assault of the Moncada garrison. + self._add_holiday_jul_27(tr("Conmemoración del asalto a Moncada")) + + # Independence Day. + self._add_observed(self._add_holiday_oct_10(tr("Inicio de las Guerras de Independencia"))) + + if self._year <= 1968 or self._year >= 1997: + # Christmas Day. + self._add_christmas_day(tr("Día de Navidad")) + + if self._year >= 2007: + # New Year's Eve. + self._add_new_years_eve(tr("Fiesta de Fin de Año")) + + +class CU(Cuba): + pass + + +class CUB(Cuba): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/curacao.py b/.venv/lib/python3.12/site-packages/holidays/countries/curacao.py new file mode 100644 index 00000000..9c4ba69e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/curacao.py @@ -0,0 +1,174 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import HALF_DAY, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SUN_TO_PREV_SAT, + SUN_TO_NEXT_MON, +) + + +class Curacao(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Curaçao holidays. + + References: + * [Arbeidsregeling 2000](https://web.archive.org/web/20250625071823/https://lokaleregelgeving.overheid.nl/CVDR10375) + * [Landbesluit no. 22/2060](https://web.archive.org/web/20240629135453/https://gobiernu.cw/wp-content/uploads/2022/12/123.-GT-Lb.Arebeidsregeling-2000-4.pdf) + * + * + * + """ + + country = "CW" + default_language = "pap_CW" + supported_categories = (HALF_DAY, PUBLIC) + supported_languages = ("en_US", "nl", "pap_CW", "uk") + # The Netherlands Antilles was established on December 15th, 1954. + start_year = 1955 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Aña Nobo. + # Status: In-Use. + + # New Year's Day. + self._add_new_years_day(tr("Aña Nobo")) + + # Dialuna despues di Carnaval Grandi. + # Status: In-Use. + # Started in 1947. + + # Carnival Monday. + self._add_ash_monday(tr("Dialuna despues di Carnaval Grandi")) + + # Bièrnèsantu. + # Status: In-Use. + + # Good Friday. + self._add_good_friday(tr("Bièrnèsantu")) + + # Pasku di Resurekshon. + # Status: In-Use + + # Easter Sunday. + self._add_easter_sunday(tr("Pasku di Resurekshon")) + + # Di dos dia di Pasku di Resurekshon. + # Status: In-Use. + + # Easter Monday. + self._add_easter_monday(tr("Di dos dia di Pasku di Resurekshon")) + + # Dia di Obrero. + # Status: In-Use. + # If fall on Sunday, then this will be move to next working day. + # This is placed here before King's/Queen's Day for _move_holiday logic. + + self._move_holiday( + # Labor Day. + self._add_labor_day(tr("Dia di Obrero")), + rule=SUN_TO_NEXT_MON if self._year >= 1980 else MON_TO_NEXT_TUE + SUN_TO_NEXT_MON, + ) + + # Dia di la Reina/Dia di Rey. + # Status: In-Use. + # Started under Queen Wilhelmina in 1891. + # Queen Beatrix kept Queen Juliana's Birthday after her coronation. + # Switched to Dia di Rey in 2014 for King Willem-Alexander. + + self._move_holiday( + # King's Day. + self._add_holiday_apr_27(tr("Dia di Rey")) + if self._year >= 2014 + # Queen's Day. + else self._add_holiday_apr_30(tr("Dia di la Reina")), + rule=SUN_TO_PREV_SAT if self._year >= 1980 else SUN_TO_NEXT_MON, + ) + + # Dia di Asenshon. + # Status: In-Use. + + # Ascension Day. + self._add_ascension_thursday(tr("Dia di Asenshon")) + + # Domingo di Pentekòstès. + # Status: Removed + # Exists in Labor Regulation 2000. + # Presumed to be removed from 2010 onwards. + + if self._year <= 2009: + # Whit Sunday. + self._add_whit_sunday(tr("Domingo di Pentekòstès")) + + # Dia di Himno i Bandera. + # Status: In-Use. + # Starts in 1984. + + if self._year >= 1984: + # National Anthem and Flag Day. + self._add_holiday_jul_2(tr("Dia di Himno i Bandera")) + + # Dia di Pais Kòrsou / Dia di autonomia. + # Status: In-Use. + # Starts in 2010. + + if self._year >= 2010: + # Curaçao Day. + self._add_holiday_oct_10(tr("Dia di Pais Kòrsou")) + + # Kingdom Day. + # Status: Removed. + # Added on June 3rd, 2008 via P.B. 2008 no. 50. + # Presumed to have been removed in 2010 after Curacao gain its Autonomy. + + if 2008 <= self._year <= 2009: + # Kingdom Day. + self._add_holiday_dec_15(tr("Dia di Reino")) + + # Pasku di Nasementu. + # Status: In-Use. + + # Christmas Day. + self._add_christmas_day(tr("Pasku di Nasementu")) + + # Di dos dia di Pasku di Nasementu. + # Status: In-Use. + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Di dos dia di Pasku di Nasementu")) + + def _populate_half_day_holidays(self): + # New Year's Eve. + # Status: In-Use. + # Presumed to have been added after 2010. + + if self._year >= 2010: + # New Year's Eve. + self._add_new_years_eve(tr("Vispu di Aña Nobo")) + + +class CW(Curacao): + pass + + +class CUW(Curacao): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/cyprus.py b/.venv/lib/python3.12/site-packages/holidays/countries/cyprus.py new file mode 100644 index 00000000..7d48cb68 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/cyprus.py @@ -0,0 +1,104 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.julian_revised import JULIAN_REVISED_CALENDAR +from holidays.constants import BANK, OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Cyprus(HolidayBase, ChristianHolidays, InternationalHolidays): + """Cyprus holidays. + + References: + * + * + """ + + country = "CY" + default_language = "el" + supported_categories = (BANK, OPTIONAL, PUBLIC) + supported_languages = ("el", "en_CY", "en_US", "uk") + start_year = 1961 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_REVISED_CALENDAR) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Πρωτοχρονιά")) + + # Epiphany. + self._add_epiphany_day(tr("Ημέρα των Θεοφανίων")) + + # Green Monday. + self._add_ash_monday(tr("Καθαρά Δευτέρα")) + + # Greek Independence Day. + self._add_holiday_mar_25(tr("Ημέρα της Ελληνικής Ανεξαρτησίας")) + + # Cyprus National Day. + self._add_holiday_apr_1(tr("Εθνική Ημέρα Κύπρου")) + + # Good Friday. + self._add_good_friday(tr("Μεγάλη Παρασκευή")) + + # Easter Sunday. + self._add_easter_sunday(tr("Κυριακή του Πάσχα")) + + # Easter Monday. + self._add_easter_monday(tr("Δευτέρα της Διακαινησίμου")) + + # Labor Day. + self._add_labor_day(tr("Πρωτομαγιά")) + + # Whit Monday. + self._add_whit_monday(tr("Δευτέρα του Αγίου Πνεύματος")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Κοίμηση της Θεοτόκου")) + + if self._year >= 1979: + # Cyprus Independence Day. + self._add_holiday_oct_1(tr("Ημέρα της Κυπριακής Ανεξαρτησίας")) + + # Ochi Day. + self._add_holiday_oct_28(tr("Ημέρα του Όχι")) + + # Christmas Day. + self._add_christmas_day(tr("Χριστούγεννα")) + + # Day After Christmas. + self._add_christmas_day_two(tr("Επομένη Χριστουγέννων")) + + def _populate_bank_holidays(self): + # Easter Tuesday. + self._add_easter_tuesday(tr("Τρίτη της Διακαινησίμου")) + + def _populate_optional_holidays(self): + # Holy Saturday. + self._add_holy_saturday(tr("Μεγάλο Σάββατο")) + + # Christmas Eve. + self._add_christmas_eve(tr("Παραμονή Χριστουγέννων")) + + +class CY(Cyprus): + pass + + +class CYP(Cyprus): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/czechia.py b/.venv/lib/python3.12/site-packages/holidays/countries/czechia.py new file mode 100644 index 00000000..4ceb3cc6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/czechia.py @@ -0,0 +1,108 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Czechia(HolidayBase, ChristianHolidays, InternationalHolidays): + """Czechia holidays. + + References: + * + * [Law 93/1951](https://web.archive.org/web/20240924164547/https://www.zakonyprolidi.cz/cs/1951-93) + * [Law 204/1990 (Jan Hus Day)](https://web.archive.org/web/20240924164541/https://www.zakonyprolidi.cz/cs/1990-204) + * [Law 245/2000](https://web.archive.org/web/20241215175816/https://www.zakonyprolidi.cz/cs/2000-245) + """ + + country = "CZ" + default_language = "cs" + supported_languages = ("cs", "en_US", "sk", "uk") + # Law 93/1951. + start_year = 1952 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nový rok")) + + if self._year >= 2000: + # Independent Czech State Restoration Day. + self._add_holiday_jan_1(tr("Den obnovy samostatného českého státu")) + + if self._year >= 2016: + # Good Friday. + self._add_good_friday(tr("Velký pátek")) + + # Easter Monday. + self._add_easter_monday(tr("Velikonoční pondělí")) + + # Labor Day. + self._add_labor_day(tr("Svátek práce")) + + if self._year >= 2004: + # Victory Day. + name = tr("Den vítězství") + elif self._year >= 2001: + # Liberation Day. + name = tr("Den osvobození") + else: + # Day of liberation from Fascism. + name = tr("Den osvobození od fašismu") + + self._add_world_war_two_victory_day(name, is_western=(self._year >= 1992)) + + if self._year >= 1990: + # Saints Cyril and Methodius Day. + self._add_holiday_jul_5(tr("Den slovanských věrozvěstů Cyrila a Metoděje")) + + # Jan Hus Day. + self._add_holiday_jul_6(tr("Den upálení mistra Jana Husa")) + + if self._year >= 2000: + # Statehood Day. + self._add_holiday_sep_28(tr("Den české státnosti")) + + # Independent Czechoslovak State Day. + self._add_holiday_oct_28(tr("Den vzniku samostatného československého státu")) + + if self._year >= 1990: + self._add_holiday_nov_17( + # Struggle for Freedom and Democracy Day and International Students' Day. + tr("Den boje za svobodu a demokracii a Mezinárodní den studentstva") + if self._year >= 2019 + # Struggle for Freedom and Democracy Day. + else tr("Den boje za svobodu a demokracii") + ) + + # Christmas Eve. + self._add_christmas_eve(tr("Štědrý den")) + + # Christmas Day. + self._add_christmas_day(tr("1. svátek vánoční")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("2. svátek vánoční")) + + +class CZ(Czechia): + pass + + +class CZE(Czechia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/denmark.py b/.venv/lib/python3.12/site-packages/holidays/countries/denmark.py new file mode 100644 index 00000000..49bc4a45 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/denmark.py @@ -0,0 +1,93 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Denmark(HolidayBase, ChristianHolidays, InternationalHolidays): + """Denmark holidays. + + References: + * + * + * + """ + + country = "DK" + default_language = "da" + supported_categories = (OPTIONAL, PUBLIC) + supported_languages = ("da", "en_US", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nytårsdag")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Skærtorsdag")) + + # Good Friday. + self._add_good_friday(tr("Langfredag")) + + # Easter Sunday. + self._add_easter_sunday(tr("Påskedag")) + + # Easter Monday. + self._add_easter_monday(tr("Anden påskedag")) + + if self._year <= 2023: + # Great Day of Prayers. + self._add_holiday_26_days_past_easter(tr("Store bededag")) + + # Ascension Day. + self._add_ascension_thursday(tr("Kristi himmelfartsdag")) + + # Whit Sunday. + self._add_whit_sunday(tr("Pinsedag")) + + # Whit Monday. + self._add_whit_monday(tr("Anden pinsedag")) + + # Christmas Day. + self._add_christmas_day(tr("Juledag")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Anden juledag")) + + def _populate_optional_holidays(self): + # Workers' Day. + self._add_labor_day(tr("Arbejdernes kampdag")) + + # Constitution Day. + self._add_holiday_jun_5(tr("Grundlovsdag")) + + # Christmas Eve. + self._add_christmas_eve(tr("Juleaftensdag")) + + # New Year's Eve. + self._add_new_years_eve(tr("Nytårsaften")) + + +class DK(Denmark): + pass + + +class DNK(Denmark): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/djibouti.py b/.venv/lib/python3.12/site-packages/holidays/countries/djibouti.py new file mode 100644 index 00000000..bbf12f04 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/djibouti.py @@ -0,0 +1,90 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import FRI, SAT +from holidays.groups import ChristianHolidays, IslamicHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Djibouti(HolidayBase, ChristianHolidays, IslamicHolidays, InternationalHolidays): + """Djibouti holidays.""" + + country = "DJ" + default_language = "fr" + # %s (estimated). + estimated_label = tr("%s (estimé)") + supported_languages = ("ar", "en_US", "fr") + weekend = {FRI, SAT} + # On 27 June 1977, Djibouti gained independence from France. + start_year = 1978 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nouvel an")) + + # Labor Day. + self._add_labor_day(tr("Fête du travail")) + + # Independence Day. + self._add_holiday_jun_27(tr("Fête de l'indépendance")) + + # Independence Day Holiday. + self._add_holiday_jun_28(tr("Fête de l'indépendance deuxième jour")) + + # Christmas Day. + self._add_christmas_day(tr("Noël")) + + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("Al Isra et Al Mirague")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Eid al-Fitr")) + + # Eid al-Fitr Holiday. + self._add_eid_al_fitr_day_two(tr("Eid al-Fitr deuxième jour")) + + # Arafat Day. + self._add_arafah_day(tr("Arafat")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Eid al-Adha")) + + # Eid al-Adha Holiday. + self._add_eid_al_adha_day_two(tr("Eid al-Adha deuxième jour")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("Nouvel an musulman")) + + # Prophet Muhammad's Birthday. + self._add_mawlid_day(tr("Anniversaire du prophète Muhammad")) + + +class DJ(Djibouti): + pass + + +class DJI(Djibouti): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/dominica.py b/.venv/lib/python3.12/site-packages/holidays/countries/dominica.py new file mode 100644 index 00000000..210abb20 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/dominica.py @@ -0,0 +1,129 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import JAN, JUL, SEP +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class Dominica(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Dominica holidays. + + References: + * + * + * + * + + Cross-Checked With: + * [2010](https://web.archive.org/web/20240826101956/https://www.dominica-weekly.com/images/dominica-calendar-2010/1600-1280.jpg) + * [2011-2020](https://web.archive.org/web/20241112201134/https://dominicaconsulategreece.com/dominica/public-holidays/) + * + * [2022-2024](https://web.archive.org/web/20250407175225/https://dominica.gov.dm/about-dominica/public-holidays) + + While Labour Day is listed in the 1990 amendment as May 1st, this has, de facto, been + made 1st Monday of May since at least 2010. + + Where in any year two public holidays fall on the same day, then the next succeeding day + not being itself a public holiday shall be observed as a public holiday. In practice, this + only applies to Holidays which falls on Saturday or Sunday. + """ + + country = "DM" + observed_label = "%s (observed)" + # Public Holidays Act, L.I. 12 of 1990 Amendment. + start_year = 1990 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, DominicaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Carnival Monday. + self._add_carnival_monday("Carnival Monday") + + # Carnival Tuesday. + self._add_carnival_tuesday("Carnival Tuesday") + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Labour Day. + labour_day_name = "Labour Day" + if self._year >= 2010: + self._add_holiday_1st_mon_of_may(labour_day_name) + else: + self._add_observed(self._add_labor_day(labour_day_name)) + + # Whit Monday. + self._add_whit_monday("Whit Monday") + + self._add_holiday_1st_mon_of_aug( + # Emancipation Day. + "Emancipation Day" + if self._year >= 1998 + # First Monday of August. + else "First Monday of August" + ) + + # Independence Day. + self._add_observed(self._add_holiday_nov_3("Independence Day"), rule=SUN_TO_NEXT_TUE) + + # National Day of Community Service . + self._add_observed(self._add_holiday_nov_4("National Day of Community Service")) + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two("Boxing Day")) + + +class DM(Dominica): + pass + + +class DMA(Dominica): + pass + + +class DominicaStaticHolidays: + """Dominica special holidays. + + References: + * + * + * + * + """ + + # Special Public Holidays. + special_public_holiday_name = "Special Public Holiday" + + special_public_holidays = { + 2009: ( + (JUL, 28, special_public_holiday_name), + (SEP, 3, special_public_holiday_name), + ), + 2010: (JAN, 4, special_public_holiday_name), + # Post-Hurricane Maria Thanksgiving Celebrations. + 2019: (SEP, 19, "Post-Hurricane Maria Thanksgiving Celebrations"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/dominican_republic.py b/.venv/lib/python3.12/site-packages/holidays/countries/dominican_republic.py new file mode 100644 index 00000000..f140a4b4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/dominican_republic.py @@ -0,0 +1,92 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + TUE_WED_TO_PREV_MON, + THU_FRI_TO_NEXT_MON, + THU_FRI_SUN_TO_NEXT_MON, +) + + +class DominicanRepublic(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Dominican Republic holidays. + + References: + * + * + """ + + country = "DO" + default_language = "es" + supported_languages = ("en_US", "es", "uk") + # Law No. 139-97 - Holidays Dominican Republic (Jun 27, 1997). + start_year = 1998 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", TUE_WED_TO_PREV_MON + THU_FRI_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Epiphany. + self._move_holiday(self._add_epiphany_day(tr("Día de los Santos Reyes"))) + + # Lady of Altagracia. + self._add_holiday_jan_21(tr("Día de la Altagracia")) + + # Juan Pablo Duarte Day. + self._move_holiday(self._add_holiday_jan_26(tr("Día de Duarte"))) + + # Independence Day. + self._add_holiday_feb_27(tr("Día de Independencia")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + self._move_holiday( + # Labor Day. + self._add_labor_day(tr("Día del Trabajo")), + rule=TUE_WED_TO_PREV_MON + THU_FRI_SUN_TO_NEXT_MON, + ) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + # Restoration Day. + aug_16 = self._add_holiday_aug_16(tr("Día de la Restauración")) + if self._year % 4 != 0: + self._move_holiday(aug_16) + + # Our Lady of Mercedes Day. + self._add_holiday_sep_24(tr("Día de las Mercedes")) + + # Constitution Day. + self._move_holiday(self._add_holiday_nov_6(tr("Día de la Constitución"))) + + # Christmas Day. + self._add_christmas_day(tr("Día de Navidad")) + + +class DO(DominicanRepublic): + pass + + +class DOM(DominicanRepublic): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/dr_congo.py b/.venv/lib/python3.12/site-packages/holidays/countries/dr_congo.py new file mode 100644 index 00000000..4b206ec3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/dr_congo.py @@ -0,0 +1,139 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import SUN +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_PREV_SAT + + +class DRCongo(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Democratic Republic of the Congo holidays. + + References: + * + * [Ordonnance n° 79-154](https://web.archive.org/web/20220329181351/http://www.leganet.cd/Legislation/DroitSocial/O.79.154.23.06.1979.htm) + * [Ordonnance n° 14/010](https://web.archive.org/web/20230419184344/http://leganet.cd/Legislation/Divers/Ordonnance.14.10.14.mai.2014.htm) + * [Ordonnance n° 23-042](https://web.archive.org/web/20250113230411/http://www.droitcongolais.info/files/143.03.23_Ordonnance-du-30-mars-2023_jours-feries.pdf) + * [Loi n° 009-2002](https://web.archive.org/web/20250104233847/https://www.leganet.cd/Legislation/Droit%20administratif/Urbanismevoiries/Div/L.009.05.08.2002.htm) + """ + + country = "CD" + default_language = "fr" + # %s (observed). + observed_label = tr("%s (observé)") + supported_languages = ("en_US", "fr") + # Ordonnance n° 79-154. + start_year = 1980 + weekend = {SUN} + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_PREV_SAT) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Nouvel an") + self._add_new_years_day(name) + self._add_observed(self._next_year_new_years_day, name=name) + + # Established on May 10th, 2014 via Ordonnance n° 14/010. + if self._year >= 2015: + # Martyrs' Day. + self._add_observed(self._add_holiday_jan_4(tr("Martyrs de l'indépendance"))) + + self._add_observed( + # National Hero Laurent Désiré Kabila Day. + self._add_holiday_jan_16(tr("Journée du héros national Laurent Désiré Kabila")) + ) + + self._add_observed( + # National Hero Patrice Emery Lumumba Day. + self._add_holiday_jan_17(tr("Journée du héros national Patrice Emery Lumumba")) + ) + + # Established on March 30th, 2023 via Ordonnance n° 23-042. + if self._year >= 2023: + self._add_observed( + self._add_holiday_apr_6( + # Day of the Struggle of Simon Kimbangu and African Consciousness. + tr("Journée du combat de Simon Kimbangu et de la conscience africaine") + ) + ) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Fête du travail"))) + + # Renamed on May 10th, 2014 via Ordonnance n° 14/010. + if self._year >= 2014: + self._add_observed( + # Revolution and Armed Forces Day. + self._add_holiday_may_17(tr("Journée de la Révolution et des Forces Armées")) + ) + else: + # Armed Forces Day. + self._add_observed(self._add_holiday_nov_17(tr("Fête des Forces armées zaïroises"))) + + # Removed on May 10th, 2014 via Ordonnance n° 14/010. + if self._year <= 2013: + self._add_observed( + self._add_holiday_may_20( + # Anniversary of the Popular Movement of the Revolution. + tr("Anniversaire du Mouvement populaire de la révolution") + ) + ) + + self._add_observed( + self._add_holiday_jun_24( + # Anniversary of the New Revolutionary Constitution. + tr("Anniversaire de la nouvelle Constitution révolutionnaire") + ) + ) + + # Independence Day. + self._add_observed(self._add_holiday_jun_30(tr("Journée de l'indépendance"))) + + # Parents' Day. + self._add_observed(self._add_holiday_aug_1(tr("Fête des parents"))) + + if self._year >= 2024: + self._add_observed( + # Congolese Genocide Memorial Day. + self._add_holiday_aug_2(tr("Journée commémorative du génocide Congolais")) + ) + + # Removed on May 10th, 2014 via Ordonnance n° 14/010. + if self._year <= 2013: + # Youth Day. + self._add_observed(self._add_holiday_oct_14(tr("Journée de la Jeunesse"))) + + self._add_observed( + # Anniversary of the Country's Name Change. + self._add_holiday_oct_27(tr("Anniversaire du changement du nom de notre Pays")) + ) + + # Anniversary of the New Regime. + self._add_observed(self._add_holiday_nov_24(tr("Anniversaire du nouveau régime"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Noël"))) + + +class CD(DRCongo): + pass + + +class COD(DRCongo): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/ecuador.py b/.venv/lib/python3.12/site-packages/holidays/countries/ecuador.py new file mode 100644 index 00000000..b23510aa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/ecuador.py @@ -0,0 +1,109 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + TUE_TO_PREV_MON, + WED_TO_NEXT_FRI, + SAT_TO_PREV_FRI, + SUN_TO_NEXT_MON, + WED_THU_TO_NEXT_FRI, +) + + +class Ecuador(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Ecuador holidays. + + References: + * + * [Código del Trabajo](https://web.archive.org/web/20250428092005/https://biblioteca.defensoria.gob.ec/bitstream/37000/3364/1/Código%20de%20Trabajo%20(04-11-2021).pdf) + """ + + country = "EC" + default_language = "es" + # %s (observed). + observed_label = tr("%s (observado)") + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + # Art. 1 of Law #0 from 20.12.2016 + # When holidays falls on Tuesday, the rest shall be transferred to + # preceding Monday, and if they falls on Wednesday or Thursday, + # the rest shall be transferred to Friday of the same week. + # Exceptions to this provision are January 1, December 25 and + # Shrove Tuesday. + # When holidays falls on Saturday or Sunday, the rest shall be + # transferred, respectively, to the preceding Friday or the + # following Monday. + kwargs.setdefault( + "observed_rule", + TUE_TO_PREV_MON + WED_THU_TO_NEXT_FRI + SAT_TO_PREV_FRI + SUN_TO_NEXT_MON, + ) + kwargs.setdefault("observed_since", 2017) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = self.tr("Año Nuevo") + self._add_observed(self._add_new_years_day(name), rule=SAT_TO_PREV_FRI + SUN_TO_NEXT_MON) + self._add_observed(self._next_year_new_years_day, name=name, rule=SAT_TO_PREV_FRI) + + # Carnival. + name = tr("Carnaval") + self._add_carnival_monday(name) + self._add_carnival_tuesday(name) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Día del Trabajo"))) + + # The Battle of Pichincha. + self._add_observed(self._add_holiday_may_24(tr("Batalla de Pichincha"))) + + # Declaration of Independence of Quito. + self._add_observed(self._add_holiday_aug_10(tr("Primer Grito de Independencia"))) + + # Independence of Guayaquil. + self._add_observed(self._add_holiday_oct_9(tr("Independencia de Guayaquil"))) + + self._add_observed( + # All Souls' Day. + self._add_all_souls_day(tr("Día de los Difuntos")), + rule=TUE_TO_PREV_MON + WED_TO_NEXT_FRI + SAT_TO_PREV_FRI, # Not observed the next day. + ) + + self._add_observed( + # Independence of Cuenca. + self._add_holiday_nov_3(tr("Independencia de Cuenca")), + rule=WED_THU_TO_NEXT_FRI + SUN_TO_NEXT_MON, # Not observed the previous day. + ) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Día de Navidad")), + rule=SAT_TO_PREV_FRI + SUN_TO_NEXT_MON, + ) + + +class EC(Ecuador): + pass + + +class ECU(Ecuador): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/egypt.py b/.venv/lib/python3.12/site-packages/holidays/countries/egypt.py new file mode 100644 index 00000000..3d427bab --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/egypt.py @@ -0,0 +1,108 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import FRI, SAT +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ChristianHolidays, IslamicHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Egypt(HolidayBase, ChristianHolidays, IslamicHolidays, InternationalHolidays): + """Egypt holidays.""" + + country = "EG" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + supported_languages = ("ar", "en_US") + weekend = {FRI, SAT} + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + # Coptic Christmas Day. + self._add_christmas_day(tr("عيد الميلاد المجيد (تقويم قبطي)")) + + if self._year >= 2012: + # January 25th Revolution. + self._add_holiday_jan_25(tr("عيد ثورة 25 يناير")) + elif self._year >= 2009: + # National Police Day. + self._add_holiday_jan_25(tr("عيد الشرطة")) + + # Coptic Easter. + self._add_easter_sunday(tr("عيد الفصح القبطي")) + + # Spring Festival. + self._add_easter_monday(tr("شم النسيم")) + + if self._year > 1982: + # Sinai Liberation Day. + self._add_holiday_apr_25(tr("عيد تحرير سيناء")) + + # Labor Day. + self._add_labor_day(tr("عيد العمال")) + + # Armed Forces Day. + self._add_holiday_oct_6(tr("عيد القوات المسلحة")) + + if self._year >= 2014: + # June 30 Revolution Day. + self._add_holiday_jun_30(tr("عيد ثورة 30 يونيو")) + + if self._year > 1952: + # July 23 Revolution Day. + self._add_holiday_jul_23(tr("عيد ثورة 23 يوليو")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("عيد الفطر")) + # Eid al-Fitr Holiday. + self._add_eid_al_fitr_day_two(tr("عطلة عيد الفطر")) + self._add_eid_al_fitr_day_three(tr("عطلة عيد الفطر")) + + # Arafat Day. + self._add_arafah_day(tr("يوم عرفة")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("عيد الأضحى")) + # Eid al-Adha Holiday. + self._add_eid_al_adha_day_two(tr("عطلة عيد الأضحى")) + self._add_eid_al_adha_day_three(tr("عطلة عيد الأضحى")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("عيد المولد النبوي")) + + +class EG(Egypt): + pass + + +class EGY(Egypt): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/el_salvador.py b/.venv/lib/python3.12/site-packages/holidays/countries/el_salvador.py new file mode 100644 index 00000000..19905433 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/el_salvador.py @@ -0,0 +1,121 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class ElSalvador(HolidayBase, ChristianHolidays, InternationalHolidays): + """El Salvador holidays. + + References: + * [Labor Code 1972](https://web.archive.org/web/20240918054537/http://www.transparencia.gob.sv/institutions/gd-usulutan/documents/192280/download) + * + * + """ + + country = "SV" + default_language = "es" + # Labor Code 1972. + start_year = 1973 + subdivisions = ( + "AH", # Ahuachapán. + "CA", # Cabañas. + "CH", # Chalatenango. + "CU", # Cuscatlán. + "LI", # La Libertad. + "MO", # Morazán. + "PA", # La Paz. + "SA", # Santa Ana. + "SM", # San Miguel. + "SO", # Sonsonate. + "SS", # San Salvador. + "SV", # San Vicente. + "UN", # La Unión. + "US", # Usulután. + ) + subdivisions_aliases = { + "Ahuachapán": "AH", + "Cabañas": "CA", + "Chalatenango": "CH", + "Cuscatlán": "CU", + "La Libertad": "LI", + "Morazán": "MO", + "La Paz": "PA", + "Santa Ana": "SA", + "San Miguel": "SM", + "Sonsonate": "SO", + "San Salvador": "SS", + "San Vicente": "SV", + "La Unión": "UN", + "Usulután": "US", + } + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Holy Saturday. + self._add_holy_saturday(tr("Sábado Santo")) + + # Labor Day. + self._add_labor_day(tr("Día del Trabajo")) + + # Legislative Decree #399 from Apr 14, 2016. + if self._year >= 2016: + # Mother's Day. + self._add_holiday_may_10(tr("Día de la Madre")) + + # Legislative Decree #208 from Jun 17, 2012. + if self._year >= 2013: + # Father's Day. + self._add_holiday_jun_17(tr("Día del Padre")) + + # Celebrations of San Salvador. + self._add_holiday_aug_6(tr("Celebración del Divino Salvador del Mundo")) + + # Independence Day. + self._add_holiday_sep_15(tr("Día de la Independencia")) + + # All Souls' Day. + self._add_all_souls_day(tr("Día de los Difuntos")) + + # Christmas Day. + self._add_christmas_day(tr("Navidad")) + + def _populate_subdiv_ss_public_holidays(self): + # Feast of San Salvador. + name = tr("Fiesta de San Salvador") + self._add_holiday_aug_3(name) + self._add_holiday_aug_5(name) + + +class SV(ElSalvador): + pass + + +class SLV(ElSalvador): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/equatorial_guinea.py b/.venv/lib/python3.12/site-packages/holidays/countries/equatorial_guinea.py new file mode 100644 index 00000000..4ac19c2d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/equatorial_guinea.py @@ -0,0 +1,150 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_MON + + +class EquatorialGuinea( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """Equatorial Guinea holidays. + + References: + * [Decree 9/2007](https://web.archive.org/web/20250518185011/https://boe.gob.gq/files/Decreto%20de%20Fijación%20de%20los%20Días%20Feriados%20en%20Guinea%20Ecuatorial.pdf) + * + * + * + * [2015](https://web.archive.org/web/20250421105147/https://www.guineainfomarket.com/gobierno/2015/01/01/calendario-laboral-de-guinea-ecuatorial-2015/) + * [2016](https://web.archive.org/web/20250212174334/https://www.guineainfomarket.com/libros/2015/12/06/calendario-laboral-de-guinea-ecuatorial-2016/) + * [2018](https://web.archive.org/web/20241005004303/https://www.guineainfomarket.com/economia/2017/12/29/calendario-laboral-guinea-ecuatorial-2018/) + * [2019](https://web.archive.org/web/20220526022213/https://www.guineainfomarket.com/economia/2019/01/01/calendario-laboral-guinea-ecuatorial-2019/) + * [2020](https://web.archive.org/web/20250503044753/https://www.guineainfomarket.com/cultura/2020/01/01/calendario-laboral-de-guinea-ecuatorial-2020/) + * [2021](https://web.archive.org/web/20250503044727/https://www.guineainfomarket.com/cultura/2021/01/29/calendario-laboral-de-guinea-ecuatorial-2021/) + * [2022](https://web.archive.org/web/20250503044746/https://www.guineainfomarket.com/cultura/2021/01/29/calendario-laboral-de-guinea-ecuatorial-2021-2/) + * [2024](https://web.archive.org/web/20250504175804/https://www.guineainfomarket.com/business/2024/03/29/calendario-laboral-de-guinea-ecuatorial-2024/) + """ + + country = "GQ" + default_language = "es" + supported_languages = ("en_US", "es") + # %s observed. + observed_label = tr("%s (observado)") + # Decree 9/2007. + start_year = 2007 + subdivisions = ( + "AN", # Annobón (Annobon). + "BN", # Bioko Norte (North Bioko). + "BS", # Bioko Sur (South Bioko). + "CS", # Centro Sur (South Center). + "DJ", # Djibloho. + "KN", # Kié-Ntem (Kie-Ntem). + "LI", # Litoral (Coast). + "WN", # Wele-Nzas. + ) + subdivisions_aliases = { + "Annobón": "AN", + "Annobon": "AN", + "Bioko Norte": "BN", + "North Bioko": "BN", + "Bioko Sur": "BS", + "South Bioko": "BS", + "Centro Sur": "CS", + "South Center": "CS", + "Djibloho": "DJ", + "Kié-Ntem": "KN", + "Kie-Ntem": "KN", + "Litoral": "LI", + "Coast": "LI", + "Wele-Nzas": "WN", + } + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=EquatorialGuineaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("Año Nuevo"))) + + # International Women's Day. + self._add_womens_day(tr("Día Internacional de la Mujer")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # International Labor Day. + self._add_observed(self._add_labor_day(tr("Día Internacional del Trabajo"))) + + # African Liberation Day. + self._add_africa_day(tr("Día de la liberación Africana")) + + self._add_observed( + # President's Day. + self._add_holiday_jun_5(tr("Natalicio de Su Excelencia el Presidente de la República")) + ) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + # Armed Forces Day. + self._add_observed(self._add_holiday_aug_3(tr("Día de las Fuerzas Armadas"))) + + # Constitution Day. + self._add_observed(self._add_holiday_aug_15(tr("Día de la Constitución"))) + + # Independence Day. + self._add_observed(self._add_holiday_oct_12(tr("Día de la Independencia Nacional"))) + + self._add_observed( + self._add_immaculate_conception_day( + # Immaculate Conception. + tr("Festividad de la Inmaculada Concepción de María") + ) + ) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Día de Navidad"))) + + def _populate_subdiv_an_public_holidays(self): + # Patron Saint Festival of Annobón. + self._add_holiday_jun_13(tr("Fiesta Patronal de Annobón")) + + +class GQ(EquatorialGuinea): + pass + + +class GNQ(EquatorialGuinea): + pass + + +class EquatorialGuineaStaticHolidays: + """Equatorial Guinea special holidays. + + References: + * [AFCON Victory Holiday](https://web.archive.org/web/20240124021813/https://www.monitor.co.ug/uganda/sports/soccer/equatorial-guinea-president-awards-team-1-million-for-afcon-victory-4500644) + """ + + special_public_holidays = { + # AFCON Victory Against Ivory Coast. + 2024: (JAN, 23, tr("Victoria de la AFCON contra Costa de Marfil")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/estonia.py b/.venv/lib/python3.12/site-packages/holidays/countries/estonia.py new file mode 100644 index 00000000..c1637af9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/estonia.py @@ -0,0 +1,76 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Estonia(HolidayBase, ChristianHolidays, InternationalHolidays): + """Estonia holidays.""" + + country = "EE" + default_language = "et" + supported_languages = ("en_US", "et", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("uusaasta")) + + # Independence Day. + self._add_holiday_feb_24(tr("iseseisvuspäev")) + + # Good Friday. + self._add_good_friday(tr("suur reede")) + + # Easter Sunday. + self._add_easter_sunday(tr("ülestõusmispühade 1. püha")) + + # Spring Day. + self._add_holiday_may_1(tr("kevadpüha")) + + # Whit Sunday. + self._add_whit_sunday(tr("nelipühade 1. püha")) + + # Victory Day. + self._add_holiday_jun_23(tr("võidupüha")) + + # Midsummer Day. + self._add_saint_johns_day(tr("jaanipäev")) + + if self._year >= 1998: + # Independence Restoration Day. + self._add_holiday_aug_20(tr("taasiseseisvumispäev")) + + if self._year >= 2005: + # Christmas Eve. + self._add_christmas_eve(tr("jõululaupäev")) + + # Christmas Day. + self._add_christmas_day(tr("esimene jõulupüha")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("teine jõulupüha")) + + +class EE(Estonia): + pass + + +class EST(Estonia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/eswatini.py b/.venv/lib/python3.12/site-packages/holidays/countries/eswatini.py new file mode 100644 index 00000000..e19cbfdb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/eswatini.py @@ -0,0 +1,93 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +import warnings + +from holidays.calendars.gregorian import JAN, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class Eswatini(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Eswatini holidays. + + References: + * + * + """ + + country = "SZ" + observed_label = "%s (observed)" + start_year = 1939 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=EswatiniStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 2021) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self._add_observed(self._add_new_years_day("New Year's Day")) + + self._add_good_friday("Good Friday") + + self._add_easter_monday("Easter Monday") + + self._add_ascension_thursday("Ascension Day") + + if self._year >= 1987: + self._add_observed( + apr_19 := self._add_holiday_apr_19("King's Birthday"), + rule=SUN_TO_NEXT_TUE if apr_19 == self._easter_sunday else SUN_TO_NEXT_MON, + ) + + if self._year >= 1969: + self._add_observed( + apr_25 := self._add_holiday_apr_25("National Flag Day"), + rule=SUN_TO_NEXT_TUE if apr_25 == self._easter_sunday else SUN_TO_NEXT_MON, + ) + + self._add_observed(self._add_labor_day("Worker's Day")) + + if self._year >= 1983: + self._add_observed(self._add_holiday_jul_22("Birthday of Late King Sobhuza")) + + self._add_observed(self._add_holiday_sep_6("Independence Day")) + + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + + self._add_observed(self._add_christmas_day_two("Boxing Day")) + + +class Swaziland(Eswatini): + def __init__(self, *args, **kwargs) -> None: + warnings.warn("Swaziland is deprecated, use Eswatini instead.", DeprecationWarning) + + super().__init__(*args, **kwargs) + + +class SZ(Eswatini): + pass + + +class SZW(Eswatini): + pass + + +class EswatiniStaticHolidays: + special_public_holidays = { + # https://web.archive.org/web/20250413193906/https://mg.co.za/article/1999-12-09-swaziland-declares-bank-holidays/ + 1999: (DEC, 31, "Y2K changeover"), + 2000: (JAN, 3, "Y2K changeover"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/ethiopia.py b/.venv/lib/python3.12/site-packages/holidays/countries/ethiopia.py new file mode 100644 index 00000000..29d30fa6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/ethiopia.py @@ -0,0 +1,171 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from calendar import isleap +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Ethiopia(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Ethiopia holidays. + + References: + * [Proclamation No. 29/1996](https://web.archive.org/web/20240918183943/https://lawethiopia.com/images/federal_proclamation/proclamations_by_number/29.pdf) + * [Proclamation No. 1334/2024](https://web.archive.org/web/20240823080839/https://lawethiopiacomment.wordpress.com/wp-content/uploads/2024/08/public-holiday-stamped.pdf) + * + * + * + * + """ + + country = "ET" + default_language = "am" + # %s (estimated). + estimated_label = tr("%s (ግምት)") + # Negarit Gazeta Proclamation No. 16/1975. + start_year = 1976 + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("am", "ar", "en_ET", "en_US") + + def _is_leap_year(self) -> bool: + """Determine if the Ethiopian calendar year is a leap year. + + Ethiopian leap years generally align with Gregorian leap years until + February 2100. However, the Ethiopian calendar starts earlier (on September 11), + which affects holidays between September 11 and January 1. + + To account for this shift, the method checks whether next year is a leap year + in the Gregorian calendar. + + Returns: + `True` if the Ethiopian year is a leap year, `False` otherwise. + """ + + return isleap(self._year + 1) + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=EthiopiaIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Christmas Day. + self._add_christmas_day(tr("የገና ወይም የልደት በዓል")) + + # Epiphany. + self._add_holiday(tr("የጥምቀት በዓል"), JAN, 20 if super()._is_leap_year() else 19) + + if self._year >= 1996: + # Adwa Victory Day. + self._add_holiday_mar_2(tr("የአድዋ ድል በዓል")) + + # Good Friday. + self._add_good_friday(tr("የስቅለት በዓል")) + + # Easter Sunday. + self._add_easter_sunday(tr("የትንሳኤ(ፋሲካ) በዓል")) + + # International Workers' Day. + self._add_labor_day(tr("የዓለም የሠራተኞች (የላብአደሮች) ቀን")) + + # Ethiopian Patriots' Victory Day. + self._add_holiday_may_5(tr("የአርበኞች (የድል) ቀን በዓል")) + + if self._year >= 1992: + # Downfall of the Dergue Regime Day. + self._add_holiday_may_28(tr("ደርግ የወደቀበት ቀን")) + + # Ethiopian New Year. + self._add_holiday(tr("የዘመን መለወጫ (እንቁጣጣሽ) በዓል"), SEP, 12 if self._is_leap_year() else 11) + + # Finding of True Cross. + self._add_holiday(tr("የመስቀል በዓል"), SEP, 28 if self._is_leap_year() else 27) + + if self._year <= 1990: + # Popular Revolution Commemoration Day. + self._add_holiday(tr("የአብዮት ቀን"), SEP, 13 if self._is_leap_year() else 12) + + # October Revolution Day. + self._add_holiday_nov_7(tr("የጥቅምት አብዮት ቀን")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("የኢድ አልፈጥር")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("የኢድ አልአድሃ (አረፋ)")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("የመውሊድ በዓል")) + + def _populate_workday_holidays(self): + # Ethiopian Martyrs' Day. + self._add_holiday_feb_20(tr("የሰማዕታት ቀን")) + + if self._year >= 2006: + # Nations, Nationalities and Peoples Day. + self._add_holiday_dec_9(tr("የብሔር ብሔረሰቦች ቀን")) + + +class ET(Ethiopia): + pass + + +class ETH(Ethiopia): + pass + + +class EthiopiaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + } + + EID_AL_FITR_DATES = { + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + MAWLID_DATES = { + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 15), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/falkland_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/falkland_islands.py new file mode 100644 index 00000000..855ebf1f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/falkland_islands.py @@ -0,0 +1,141 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAY, SEP +from holidays.constants import GOVERNMENT, PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_TO_NEXT_MON, + SAT_TO_NEXT_TUE, + SUN_TO_NEXT_TUE, + SUN_TO_NEXT_WED, + SAT_SUN_TO_NEXT_MON, +) + + +class FalklandIslands( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """Falkland Islands holidays. + + References: + * + * [January 31st, 2023 Amendment](https://web.archive.org/web/20250704040815/https://www.falklands.gov.fk/legalservices/statute-law-commissioner/gazettes-supplements/2023/supplements-2023?task=download.send&id=140) + * + * [Falkland Day](https://web.archive.org/web/20250325025508/https://www.daysoftheyear.com/days/falklands-day/) + * [Peat Cutting Day](https://en.wikipedia.org/wiki/Peat_Cutting_Monday) + * [HM The King's Birthday](https://web.archive.org/web/20230329063159/https://en.mercopress.com/2022/11/03/falklands-appoints-14-november-as-a-public-holiday-to-celebrate-birthday-of-king-charles-iii) + * [Governor's Office Stanley](https://web.archive.org/web/20250704040807/https://www.gov.uk/world/organisations/governors-office-stanley/office/governors-office-stanley) + * [2020-2023](https://web.archive.org/web/20220805134148/http://www.falklands.gov.fk/policy/jdownloads/Reports%20&%20Publications/Public%20Health,%20Social%20and%20Community%20Publications/Falkland%20Islands%20Public%20Holidays%202020-2023.pdf) + * [2023-2026](https://web.archive.org/web/20250402143330/https://www.falklands.gov.fk/policy/downloads?task=download.send&id=186:falkland-islands-public-holidays-2023-2026&catid=12) + """ + + country = "FK" + default_language = "en_GB" + # %s observed. + observed_label = tr("%s (observed)") + # Falkland War's Conclusion. + start_year = 1983 + supported_categories = (GOVERNMENT, PUBLIC, WORKDAY) + supported_languages = ("en_GB", "en_US") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=FalklandIslandsStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year <= 2022: + # Queen's Birthday. + self._add_observed(self._add_holiday_apr_21(tr("HM The Queen's Birthday"))) + + # Liberation Day. + self._add_observed(self._add_holiday_jun_14(tr("Liberation Day"))) + + if self._year <= 2001: + # Falkland Day. + self._add_observed(self._add_holiday_aug_14(tr("Falkland Day"))) + else: + # Peat Cutting Day. + self._add_holiday_1st_mon_of_oct(tr("Peat Cutting Day")) + + if self._year >= 2022: + # King's Birthday. + self._add_observed(self._add_holiday_nov_14(tr("HM The King's Birthday"))) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_TO_NEXT_TUE + SUN_TO_NEXT_WED, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_TO_NEXT_MON + SUN_TO_NEXT_WED, + ) + + self._add_observed( + # Christmas Holiday. + self._add_christmas_day_three(tr("Christmas Holiday")), + rule=SAT_TO_NEXT_MON + SUN_TO_NEXT_TUE, + ) + + def _populate_government_holidays(self): + # Government Holiday. + name = tr("Government Holiday") + last_workday = self._add_holiday( + name, self._get_next_workday(self._next_year_new_years_day, -1) + ) + self._add_holiday(name, self._get_next_workday(last_workday, -1)) + + def _populate_workday_holidays(self): + # Margaret Thatcher Day. + self._add_holiday_jan_10(tr("Margaret Thatcher Day")) + + if self._year >= 2002: + # Falkland Day. + self._add_holiday_aug_14(tr("Falkland Day")) + + +class FK(FalklandIslands): + pass + + +class FLK(FalklandIslands): + pass + + +class FalklandIslandsStaticHolidays: + """Falkland Islands special holidays. + + References: + * + """ + + special_public_holidays = { + # Queen Elizabeth II's Funeral. + 2022: (SEP, 19, tr("Queen Elizabeth II's Funeral")), + # King Charles III's Coronation. + 2023: (MAY, 8, tr("HM The King's Coronation")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/faroe_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/faroe_islands.py new file mode 100644 index 00000000..611d81ea --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/faroe_islands.py @@ -0,0 +1,102 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import HALF_DAY, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class FaroeIslands(HolidayBase, ChristianHolidays, InternationalHolidays): + """Faroe Islands holidays. + + References: + * + * [Decree no. 52 of 23 April 2003](https://web.archive.org/web/20241204233745/https://logir.fo/Kunngerd/52-fra-23-04-2003-um-flagging-fra-landsins-bygningum) + * [2007](https://web.archive.org/web/20250125193236/https://www.framtak.com/info/holidays.html)) + * [2024](https://web.archive.org/web/20250615193008/https://visitfaroeislands.com/en/plan-your-stay/get-ready-for-your-trip/general-facts/public-holidays) + * [2025](https://web.archive.org/web/20250615193215/https://guidetofaroeislands.fo/travel-information/faroe-islands-holiday/) + """ + + country = "FO" + default_language = "fo" + # Denmark granted home rule to the Faroe Islands on 30 March 1948. + start_year = 1949 + supported_categories = (HALF_DAY, PUBLIC) + supported_languages = ("da", "en_US", "fo", "is", "no", "sv") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nýggjársdagur")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Skírhósdagur")) + + # Good Friday. + self._add_good_friday(tr("Langifríggjadagur")) + + # Easter Sunday. + self._add_easter_sunday(tr("Páskadagur")) + + # Easter Monday. + self._add_easter_monday(tr("Annar páskadagur")) + + # Great Prayer Day. + self._add_holiday_26_days_past_easter(tr("Dýri biðidagur")) + + # Ascension Day. + self._add_ascension_thursday(tr("Kristi himmalsferðardagur")) + + # Whit Sunday. + self._add_whit_sunday(tr("Hvítusunnudagur")) + + # Whit Monday. + self._add_whit_monday(tr("Annar hvítusunnudagur")) + + # Saint Olaf's Day. + self._add_holiday_jul_29(tr("Ólavsøkudagur")) + + # Christmas Eve. + self._add_christmas_eve(tr("Jólaaftan")) + + # Christmas Day. + self._add_christmas_day(tr("Jóladagur")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Annar jóladagur")) + + # New Year's Eve. + self._add_new_years_eve(tr("Nýggjársaftan")) + + def _populate_half_day_holidays(self): + # National Flag Day. + self._add_holiday_apr_25(tr("Flaggdagur")) + + # Constitution Day. + self._add_holiday_jun_5(tr("Grundlógardagur")) + + # Saint Olaf's Eve. + self._add_holiday_jul_28(tr("Ólavsøkuaftan")) + + +class FO(FaroeIslands): + pass + + +class FRO(FaroeIslands): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/fiji.py b/.venv/lib/python3.12/site-packages/holidays/countries/fiji.py new file mode 100644 index 00000000..80f47153 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/fiji.py @@ -0,0 +1,183 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars import _CustomHinduHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import SEP, OCT, NOV, DEC +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ( + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, + ALL_TO_NEAREST_MON, +) + + +class Fiji( + ObservedHolidayBase, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, +): + """Fiji holidays. + + References: + * + * + * + * + * + * + * + * + * + + Official Fiji Public Holidays Calendar: + * [2016](https://web.archive.org/web/20160520212352/http://www.fiji.gov.fj:80/Media-Center/Press-Releases/GOVERNMENT-APPROVES-2016-PUBLIC-HOLIDAYS.aspx?) + * [2017](https://web.archive.org/web/20250319202817/https://www.fiji.gov.fj/Media-Centre/News/GOVERNMENT-APPROVES-2017-PUBLIC-HOLIDAYS) + * [2018](https://web.archive.org/web/20180727205733/http://www.employment.gov.fj/images/Laws/Press%20Release%20-%20Government%20Approves%202018%20Public%20Holidays.pdf) + * [2019](https://web.archive.org/web/20191018023027/https://www.fiji.gov.fj/About-Fiji/Public-Holidays) + * [2020](https://web.archive.org/web/20210103183942/https://www.fiji.gov.fj/About-Fiji/Public-Holidays) + * [2021-2022](https://web.archive.org/web/20221223004409/https://www.fiji.gov.fj/About-Fiji/Public-Holidays) + * [2023](https://web.archive.org/web/20231129154609/https://www.fiji.gov.fj/About-Fiji/Public-Holidays) + * [2024](https://web.archive.org/web/20250121185434/https://www.fiji.gov.fj/About-Fiji/Public-Holidays) + * [2025](https://web.archive.org/web/20250318092311/https://www.fiji.gov.fj/About-Fiji/Public-Holidays) + """ + + country = "FJ" + supported_categories = (PUBLIC, WORKDAY) + # %s (estimated). + estimated_label = "%s (estimated)" + # %s (observed). + observed_label = "%s (observed)" + # %s (observed, estimated). + observed_estimated_label = "%s (observed, estimated)" + # Act No. 13 of 2015 + start_year = 2016 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=FijiHinduHolidays, show_estimated=True) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=FijiIslamicHolidays, show_estimated=islamic_show_estimated + ) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Saturday. + self._add_holy_saturday("Easter Saturday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # National Sports Day. + if self._year <= 2018: + self._add_holiday_last_fri_of_jun("National Sports Day") + + if self._year <= 2022: + # Constitution Day. + self._add_observed(self._add_holiday_sep_7("Constitution Day")) + + if self._year >= 2023: + # Girmit Day. + self._move_holiday( + self._add_holiday_may_14("Girmit Day"), + rule=ALL_TO_NEAREST_MON, + show_observed_label=False, + ) + + # Ratu Sir Lala Sukuna Day. + name = "Ratu Sir Lala Sukuna Day" + if self._year == 2023: + self._add_holiday_last_mon_of_may(name) + elif self._year >= 2024: + self._add_holiday_last_fri_of_may(name) + + # Fiji Day. + self._add_holiday_oct_10("Fiji Day") + + # Diwali. + self._add_observed(self._add_diwali_india("Diwali")) + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two("Boxing Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + # Prophet Mohammed's Birthday. + for dt in self._add_mawlid_day("Prophet Mohammed's Birthday"): + self._add_observed(dt) + + def _populate_workday_holidays(self): + if self._year >= 2023: + # Constitution Day. + self._add_holiday_sep_7("Constitution Day") + + +class FJ(Fiji): + pass + + +class FJI(Fiji): + pass + + +class FijiHinduHolidays(_CustomHinduHolidays): + # https://web.archive.org/web/20250413132828/https://web.archive.org/web/20240724121605/https://www.timeanddate.com/holidays/fiji/diwali + DIWALI_INDIA_DATES = { + 2016: (OCT, 31), + 2017: (OCT, 19), + 2018: (NOV, 7), + 2019: (OCT, 28), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 25), + 2023: (NOV, 13), + 2024: (NOV, 1), + 2025: (OCT, 21), + } + + +class FijiIslamicHolidays(_CustomIslamicHolidays): + MAWLID_DATES = { + 2016: (DEC, 12), + 2017: (DEC, 2), + 2018: (NOV, 19), + 2019: (NOV, 9), + 2020: (OCT, 31), + 2021: (OCT, 18), + 2022: (OCT, 7), # looks like observed on FRI + 2023: (SEP, 30), + 2024: (SEP, 16), + 2025: (SEP, 6), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/finland.py b/.venv/lib/python3.12/site-packages/holidays/countries/finland.py new file mode 100644 index 00000000..ad98660f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/finland.py @@ -0,0 +1,356 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import _timedelta +from holidays.constants import PUBLIC, UNOFFICIAL, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Finland(HolidayBase, ChristianHolidays, InternationalHolidays): + """Finland holidays. + + Official Flag Days are included in the `WORKDAY` category, while Customary Flag Days + are included in `UNOFFICIAL` category. + + References: + * + * [Bank holidays (Finnish)](https://web.archive.org/web/20250416185850/https://www.suomenpankki.fi/fi/raha-ja-maksaminen/pankkivapaapaivat/) + * [Bank holidays (English)](https://web.archive.org/web/20250327200736/https://www.suomenpankki.fi/en/money-and-payments/bank-holidays/) + * [Bank holidays (Swedish)](https://web.archive.org/web/20250217014536/https://www.suomenpankki.fi/sv/pengar-och-betalningar/bankfria-dagar-i-finland/) + * + * + * + * + * + * + * + * + * + * + """ + + country = "FI" + default_language = "fi" + supported_languages = ("en_US", "fi", "sv_FI", "th", "uk") + supported_categories = (PUBLIC, UNOFFICIAL, WORKDAY) + subdivisions: tuple[str, ...] = ( + "01", # Ahvenanmaan maakunta (Landskapet Åland). + "02", # Etelä-Karjala (Södra Karelen). + "03", # Etelä-Pohjanmaa (Södra Österbotten). + "04", # Etelä-Savo (Södra Savolax). + "05", # Kainuu (Kajanaland). + "06", # Kanta-Häme (Egentliga Tavastland). + "07", # Keski-Pohjanmaa (Mellersta Österbotten). + "08", # Keski-Suomi (Mellersta Finland). + "09", # Kymenlaakso (Kymmenedalen). + "10", # Lappi (Lappland). + "11", # Pirkanmaa (Birkaland). + "12", # Pohjanmaa (Österbotten). + "13", # Pohjois-Karjala (Norra Karelen). + "14", # Pohjois-Pohjanmaa (Norra Österbotten). + "15", # Pohjois-Savo (Norra Savolax). + "16", # Päijät-Häme (Päijänne-Tavastland). + "17", # Satakunta. + "18", # Uusimaa (Nyland). + "19", # Varsinais-Suomi (Egentliga Finland). + ) + subdivisions_aliases = { + "Ahvenanmaan maakunta": "01", + "Landskapet Åland": "01", + "Etelä-Karjala": "02", + "Södra Karelen": "02", + "Etelä-Pohjanmaa": "03", + "Södra Österbotten": "03", + "Etelä-Savo": "04", + "Södra Savolax": "04", + "Kainuu": "05", + "Kajanaland": "05", + "Kanta-Häme": "06", + "Egentliga Tavastland": "06", + "Keski-Pohjanmaa": "07", + "Mellersta Österbotten": "07", + "Keski-Suomi": "08", + "Mellersta Finland": "08", + "Kymenlaakso": "09", + "Kymmenedalen": "09", + "Lappi": "10", + "Lappland": "10", + "Pirkanmaa": "11", + "Birkaland": "11", + "Pohjanmaa": "12", + "Österbotten": "12", + "Pohjois-Karjala": "13", + "Norra Karelen": "13", + "Pohjois-Pohjanmaa": "14", + "Norra Österbotten": "14", + "Pohjois-Savo": "15", + "Norra Savolax": "15", + "Päijät-Häme": "16", + "Päijänne-Tavastland": "16", + "Satakunta": "17", + "Uusimaa": "18", + "Nyland": "18", + "Varsinais-Suomi": "19", + "Egentliga Finland": "19", + } + start_year = 1853 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Uudenvuodenpäivä")) + + # Epiphany. + name = tr("Loppiainen") + if 1973 <= self._year <= 1990: + self._add_holiday_1st_sat_from_jan_6(name) + else: + self._add_epiphany_day(name) + + # Good Friday. + self._add_good_friday(tr("Pitkäperjantai")) + + # Easter Sunday. + self._add_easter_sunday(tr("Pääsiäispäivä")) + + # Easter Monday. + self._add_easter_monday(tr("Toinen pääsiäispäivä")) + + if self._year >= 1944: + # May Day. + self._add_holiday_may_1(tr("Vappu")) + + # Ascension Day. + name = tr("Helatorstai") + if 1973 <= self._year <= 1990: + self._add_holiday_34_days_past_easter(name) + else: + self._add_ascension_thursday(name) + + # Whit Sunday. + self._add_whit_sunday(tr("Helluntaipäivä")) + + # Midsummer Eve. + name = tr("Juhannusaatto") + if self._year >= 1955: + dt = self._add_holiday_1st_fri_from_jun_19(name) + else: + dt = self._add_holiday_jun_23(name) + + # Midsummer Day. + self._add_holiday(tr("Juhannuspäivä"), _timedelta(dt, +1)) + + # All Saints' Day. + name = tr("Pyhäinpäivä") + if self._year >= 1955: + self._add_holiday_1st_sat_from_oct_31(name) + else: + self._add_holiday_nov_1(name) + + # Designated as Public Holiday on NOV 20th, 1919. + if self._year >= 1919: + # Independence Day. + self._add_holiday_dec_6(tr("Itsenäisyyspäivä")) + + # Christmas Eve. + self._add_christmas_eve(tr("Jouluaatto")) + + # Christmas Day. + self._add_christmas_day(tr("Joulupäivä")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Tapaninpäivä")) + + def _populate_unofficial_holidays(self): + # Customary Flag Days. + + # Unofficial observance starts in 1854. + # Starting in 1929, become a name day of J.L. Runeberg. + # Added to the Almanac in 1950 as J.L. Runeberg's Day. + # Become a Flag Day in 1976. + if self._year >= 1976: + # Runeberg Day. + self._add_holiday_feb_5(tr("Runebergin päivä")) + + # Petition for Flag Day status starts in 2003. + # Become a Flag Day in 2007. + if self._year >= 2007: + # Minna Canth Day, Day of Equality. + self._add_holiday_mar_19(tr("Minna Canthin päivä, tasa-arvon päivä")) + + # Added to the Almanac in 1960 as Mikael Agricola Day. + # Also considered the "Day of Finnish Language" from 1980 onwards. + # Become a Flag Day in 1980. + if self._year >= 1980: + # Mikael Agricola Day, Day of the Finnish Language. + self._add_holiday_apr_9(tr("Mikael Agricolan päivä, suomen kielen päivä")) + + # Become a Flag Day in 1987. + if self._year >= 1987: + # National War Veterans' Day. + self._add_holiday_apr_27(tr("Kansallinen veteraanipäivä")) + + # Become a Flag Day in 2019. + if self._year >= 2019: + # Europe Day. + self._add_europe_day(tr("Eurooppa-päivä")) + + # Petition for Flag Day status starts in the 1920s. + # Become a Flag Day in 1952. + # Also considered the "Day of Finnish Heritage" from 1978 onward. + if self._year >= 1952: + name = ( + # J. V. Snellman Day, Day of Finnish Heritage. + tr("J.V. Snellmanin päivä, suomalaisuuden päivä") + if self._year >= 1978 + # J. V. Snellman Day. + else tr("J.V. Snellmanin päivä") + ) + self._add_holiday_may_12(name) + + # Become a Flag Day in 1977. + if self._year >= 1977: + # Remembrance Day. + self._add_holiday_3rd_sun_of_may(tr("Kaatuneitten muistopäivä")) + + # Become a Flag Day in 1998. + if self._year >= 1998: + # Eino Leino Day, Day of Summer and Poetry. + self._add_holiday_jul_6(tr("Eino Leinon päivä, runon ja suven päivä")) + + # Added to the Almanac in 2020. + # Become a Flag Day in 2023. + if self._year >= 2023: + # Finland's Nature Day. + self._add_holiday_last_sat_of_aug(tr("Suomen luonnon päivä")) + + # Become a Flag Day in 2016. + if self._year >= 2016: + # Miina Sillanpää Day, Day of Civic Participation. + self._add_holiday_oct_1(tr("Miina Sillanpään ja kansalaisvaikuttamisen päivä")) + + # Become a Flag Day in 1950. + # Also considered the "Day of Finnish Literature" from 1978 onward. + if self._year >= 1950: + name = ( + # Aleksis Kivi Day, Day of Finnish Literature. + tr("Aleksis Kiven päivä, suomalaisen kirjallisuuden päivä") + if self._year >= 1978 + # Aleksis Kivi Day. + else tr("Aleksis Kiven päivä") + ) + self._add_holiday_oct_10(name) + + # Become a Flag Day in 1987. + if self._year >= 1987: + # United Nations Day. + self._add_united_nations_day(tr("YK:n päivä")) + + # Become a Flag Day in 1979. + if self._year >= 1979: + # Finnish Swedish Heritage Day, svenska dagen. + self._add_holiday_nov_6(tr("Ruotsalaisuuden päivä, Kustaa Aadolfin päivä")) + + # Become a Customary Flag Day in 1987. + # Become an Official Flag Day in 2019. + if 1987 <= self._year <= 2018: + # Father's Day. + self._add_holiday_2nd_sun_of_nov(tr("Isänpäivä")) + + # Become a Flag Day in 2020. + if self._year >= 2020: + # Day of Children's Rights. + self._add_holiday_nov_20(tr("Lapsen oikeuksien päivä")) + + # First recommendation starts in 2005. + # Become a Flag Day in 2011. + if self._year >= 2011: + # Jean Sibelius Day, Day of Finnish Music. + self._add_holiday_dec_8(tr("Jean Sibeliuksen päivä, suomalaisen musiikin päivä")) + + def _populate_workday_holidays(self): + # Official Flag Days. + + # First general observance starts in 1885. + # Become a Flag Day in 1920. + # Added to the Almanac in 1950, confirmed by a decree in 1978. + if self._year >= 1920: + # Kalevala Day, Day of Finnish Culture. + self._add_holiday_feb_28(tr("Kalevalan päivä, suomalaisen kulttuurin päivä")) + + # While May Day is already a Public Holiday since 1944, it gains Flag Day status in 1978, + # although actual observance starts in 1979. + if self._year >= 1979: + # May Day. + self._add_holiday_may_1(tr("Vappu")) + + # First observed in parts of Finland in 1918. + # Moved from 3rd to 2nd Sunday of May in 1927. + # Become Flag Day in 1947. + if self._year >= 1947: + # Mother's Day. + self._add_holiday_2nd_sun_of_may(tr("Äitienpäivä")) + + # Become a Flag Day in 1942. + # Got its current name in 1950. + if self._year >= 1942: + name = ( + # Flag Day of the Finnish Defense Forces. + tr("Puolustusvoimain lippujuhlan päivä") + if self._year >= 1950 + # Birthday of the Marshal of Finland. + else tr("Suomen marsalkan syntymäpäivä") + ) + self._add_holiday_jun_6(name) + + # Day of the Finnish Flag was first created in 1934. + # This coincides with Midsummer Day. + + # Day of the Finnish Flag. + name = tr("Suomen lipun päivä") + if self._year >= 1955: + self._add_holiday_1st_sat_from_jun_20(name) + elif self._year >= 1934: + self._add_holiday_jun_24(name) + + # Become a Customary Flag Day in 1987. + # Become an Official Flag Day in 2019. + if self._year >= 2019: + # Father's Day. + self._add_holiday_2nd_sun_of_nov(tr("Isänpäivä")) + + # Flag Day status assumed to start in 1919. + if self._year >= 1919: + # Independence Day. + self._add_holiday_dec_6(tr("Itsenäisyyspäivä")) + + def _populate_subdiv_01_public_holidays(self): + # Celebrated since 1993 when the 70th anniversary of the Autonomy Act of 1920 was + # first formally recognized as a flag day. + if self._year >= 1993: + # Åland's Autonomy Day. + self._add_holiday_jun_9(tr("Ahvenanmaan itsehallintopäivä")) + + +class FI(Finland): + pass + + +class FIN(Finland): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/france.py b/.venv/lib/python3.12/site-packages/holidays/countries/france.py new file mode 100644 index 00000000..e7633597 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/france.py @@ -0,0 +1,342 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class France(HolidayBase, ChristianHolidays, InternationalHolidays): + """France holidays. + + References: + * + * + * [Arrêté du 29 germinal an X](https://web.archive.org/web/20250327095254/https://journals.openedition.org/rdr/439) + * [Loi du 6 juillet 1880](https://archive.org/details/jorf-18800707-185) + * [Loi du 8 mars 1886](https://archive.org/details/jorf-18860309-67) + * [Loi du 9 décembre 1905](https://web.archive.org/web/20250617084843/https://mjp.univ-perp.fr/france/1905laicite.htm) + * [Loi du 24 octobre 1922](https://web.archive.org/web/20250618030815/https://archives.defense.gouv.fr/content/download/102094/992430/Loi%20du%2024%20octobre%201922%20fixant%20la%20journée%20commémorative%20du%2011%20novembre.pdf) + * [Loi n°46-828 du 26 avril 1946](https://archive.org/details/jorf-19460428-100) + * [Loi n°46-934 du 7 mai 1946](https://archive.org/details/jorf-19460508-107) + * [Loi n°47-778 du 30 avril 1947 ](https://archive.org/details/jorf-19470501-104) + * [Loi n°48-746 du 29 avril 1948](https://archive.org/details/jorf-19480430-104) + * [Loi n°53-225 du 20 mars 1953](https://archive.org/details/jorf-19530321-69) + * [Décret n°59-533 du 11 avril 1959](https://archive.org/details/jorf-19590415-88) + * [Loi n° 61-814 du 29 juillet 1961](https://web.archive.org/web/20240715174837/https://www.legifrance.gouv.fr/loda/id/JORFTEXT000000684031) + * [Loi n°81-893 du 2 octobre 1981](https://archive.org/details/jorf-19811003-232) + * [Loi n° 83-550 du 30 juin 1983](https://archive.org/details/jorf-19830701-151) + * [Décret n°83-1003 du 23 novembre 1983](https://archive.org/details/jorf-19831124-272_202506) + * [Loi n° 2004-626 du 30 juin 2004](https://web.archive.org/web/20220830045136/https://www.legifrance.gouv.fr/loda/id/JORFTEXT000000622485/) + * [Loi n° 2008-351 du 16 avril 2008](https://web.archive.org/web/20220602124233/https://www.legifrance.gouv.fr/loda/id/JORFTEXT000018656009/) + * [Décret n° 2012-553 du 23 avril 2012](https://web.archive.org/web/20231104120733/https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000025743756) + * + * + * + * + * + + Some provinces have specific holidays, only those are included in the + PROVINCES, because these provinces have different administrative status, + which makes it difficult to enumerate. + """ + + country = "FR" + default_language = "fr" + # Arrêté du 29 germinal an X (April 19th, 1802), + # Reaffirmed by Article 42 de la loi du 9 décembre 1905. + start_year = 1803 + # fmt: off + subdivisions: tuple[str, ...] = ( + "57", # Moselle. + "6AE", # Alsace. + "971", # Guadeloupe. + "972", # Martinique. + "973", # Guyane. + "974", # La Réunion. + "976", # Mayotte. + "BL", # Saint-Barthélemy. + "MF", # Saint-Martin. + "NC", # Nouvelle-Calédonie, + "PF", # Polynésie Française. + "PM", # Saint-Pierre-et-Miquelon. + "TF", # Terres australes françaises. + "WF", # Wallis-et-Futuna. + ) + # fmt: on + subdivisions_aliases = { + "Moselle": "57", + "Alsace": "6AE", + "GP": "971", + "GUA": "971", + "Guadeloupe": "971", + "MQ": "972", + "Martinique": "972", + "GY": "973", + "Guyane": "973", + "RE": "974", + "LRE": "974", + "La Réunion": "974", + "YT": "976", + "MAY": "976", + "Mayotte": "976", + "Saint-Barthélemy": "BL", + "Saint-Martin": "MF", + "Nouvelle-Calédonie": "NC", + "Polynésie Française": "PF", + "Saint-Pierre-et-Miquelon": "PM", + "Terres australes françaises": "TF", + "Wallis-et-Futuna": "WF", + } + supported_languages = ("en_US", "fr", "th", "uk") + _deprecated_subdivisions = ( + "Alsace-Moselle", + "GES", + "Métropole", + "Saint-Barthélémy", + ) + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Established on March 28th, 1810. + if self._year >= 1811: + # New Year's Day. + self._add_new_years_day(tr("Jour de l'an")) + + # Established on March 8th, 1886. + if self._year >= 1886: + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + # Removed on June 30th, 2004. + # Readded on April 16th, 2008. + if self._year not in {2005, 2006, 2007}: + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + + # Made unofficial public holiday with no name on April 23rd, 1919. + # Included in official list by Vichy France with new name on April 24th, 1941. + # Confirmed for 1946 with no name on April 26th, 1946. + # Added annually from 1947 onwards with no name on April 30th, 1947. + # Got its current name on April 29th, 1948. + if self._year >= 1919: + if self._year >= 1948: + # Labor Day. + name = tr("Fête du Travail") + elif 1941 <= self._year <= 1945: + # Labor and Social Concord Day. + name = tr("Fête du Travail et de la Concorde sociale") + else: + # May Day. + name = tr("1er mai") + self._add_labor_day(name) + + # Commemorated on May 7th, 1946 as 1st Sunday after May 7th. + # Upgraded to Public Holiday on May 8th directly on March 20th, 1953. + # Removed from 1960 onwards per April 11th, 1959 decree. + # Readded on October 2nd, 1981. + if 1953 <= self._year <= 1959 or self._year >= 1982: + # Victory Day. + self._add_world_war_two_victory_day(tr("Fête de la Victoire")) + + # Ascension Day. + self._add_ascension_thursday(tr("Ascension")) + + # Established on July 6th, 1880. + if self._year >= 1880: + # National Day. + self._add_holiday_jul_14(tr("Fête nationale")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assomption")) + + # All Saints' Day. + self._add_all_saints_day(tr("Toussaint")) + + # Established on October 24th, 1922. + if self._year >= 1922: + # Armistice Day. + self._add_remembrance_day(tr("Armistice")) + + # Christmas Day. + self._add_christmas_day(tr("Noël")) + + if self.subdiv == "Alsace-Moselle": + self._populate_subdiv_6ae_public_holidays() + elif self.subdiv == "Saint-Barthélémy": + self._populate_subdiv_bl_public_holidays() + + # Moselle. + def _populate_subdiv_57_public_holidays(self): + # Established on August 16th, 1892. + if self._year >= 1893: + # Good Friday. + self._add_good_friday(tr("Vendredi saint")) + + # Established on August 16th, 1892. + if self._year >= 1892: + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Saint Étienne")) + + # Alsace. + def _populate_subdiv_6ae_public_holidays(self): + # Established on August 16th, 1892. + if self._year >= 1893: + # Good Friday. + self._add_good_friday(tr("Vendredi saint")) + + # Established on August 16th, 1892. + if self._year >= 1892: + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Saint Étienne")) + + # Guadeloupe. + def _populate_subdiv_971_public_holidays(self): + # Good Friday. + self._add_good_friday(tr("Vendredi saint")) + + # Mi-Careme. + self._add_holiday_24_days_prior_easter(tr("Mi-Carême")) + + # Provision for Public Holidays decreed on June 30th, 1983. + # Date for each DOM declared on November 23rd, 1983. + # Victor Schoelcher Day is based on June 30th, 1983 provision. + if self._year >= 1984: + # Abolition of Slavery. + self._add_holiday_may_27(tr("Abolition de l'esclavage")) + + # Victor Schoelcher Day. + self._add_holiday_jul_21(tr("Fête de Victor Schoelcher")) + + # Martinique. + def _populate_subdiv_972_public_holidays(self): + # Good Friday. + self._add_good_friday(tr("Vendredi saint")) + + # Provision for Public Holidays decreed on June 30th, 1983. + # Date for each DOM declared on November 23rd, 1983. + # Victor Schoelcher Day is based on June 30th, 1983 provision. + if self._year >= 1984: + # Abolition of Slavery. + self._add_holiday_may_22(tr("Abolition de l'esclavage")) + + # Victor Schoelcher Day. + self._add_holiday_jul_21(tr("Fête de Victor Schoelcher")) + + # Guyane. + def _populate_subdiv_973_public_holidays(self): + # Provision for Public Holidays decreed on June 30th, 1983. + # Date for each DOM declared on November 23rd, 1983. + if self._year >= 1984: + # Abolition of Slavery. + self._add_holiday_jun_10(tr("Abolition de l'esclavage")) + + # Reunion. + def _populate_subdiv_974_public_holidays(self): + # Provision for Public Holidays decreed on June 30th, 1983. + # Date for each DOM declared on November 23rd, 1983. + if self._year >= 1983: + # Abolition of Slavery. + self._add_holiday_dec_20(tr("Abolition de l'esclavage")) + + # Mayotte. + def _populate_subdiv_976_public_holidays(self): + # Provision for Public Holidays decreed on June 30th, 1983. + # Date for each DOM declared on November 23rd, 1983. + if self._year >= 1984: + # Abolition of Slavery. + self._add_holiday_apr_27(tr("Abolition de l'esclavage")) + + # Saint Barthelemy. + def _populate_subdiv_bl_public_holidays(self): + # Provision for Public Holidays decreed on June 30th, 1983. + # Date for each DOM declared on November 23rd, 1983. + # Amended to include Saint-Barthélemy and Saint-Martin subdivision on April 23rd, 2012. + if self._year >= 2012: + # Abolition of Slavery. + self._add_holiday_oct_9(tr("Abolition de l'esclavage")) + + # Saint Martin. + def _populate_subdiv_mf_public_holidays(self): + # Provision for Public Holidays decreed on June 30th, 1983. + # Date for each DOM declared on November 23rd, 1983. + # Amended to include Saint-Barthélemy and Saint-Martin subdivision on April 23rd, 2012. + # Victor Schoelcher Day is based on June 30th, 1983 provision. + if self._year >= 2012: + # Abolition of Slavery. + self._add_holiday_may_28(tr("Abolition de l'esclavage")) + + # Victor Schoelcher Day. + self._add_holiday_jul_21(tr("Fête de Victor Schoelcher")) + + # New Caledonia. + def _populate_subdiv_nc_public_holidays(self): + # First observed in 1953. + # Renamed in 2004. + if self._year >= 1953: + self._add_holiday_sep_24( + # Citizenship Day. + tr("Fête de la Citoyenneté") + if self._year >= 2004 + # Annexation Day. + else tr("Fête de la prise de possession") + ) + + # French Polynesia. + def _populate_subdiv_pf_public_holidays(self): + # Good Friday. + self._add_good_friday(tr("Vendredi saint")) + + # Established on February 1st, 1978. + if self._year >= 1978: + # Missionary Day. + self._add_holiday_mar_5(tr("Arrivée de l'Évangile")) + + # Established on May 30th, 1985. + # Replaced by Matāri'i on April 30th, 2024. + if 1985 <= self._year <= 2024: + # Internal Autonomy Day. + self._add_holiday_jun_29(tr("Fête de l'autonomie")) + + # Established on April 30th, 2024. + if self._year >= 2025: + # Matāri'i. + self._add_holiday_nov_20(tr("Matāri'i")) + + # Wallis and Futuna. + def _populate_subdiv_wf_public_holidays(self): + # While it's not clear when these holidays were added, + # they're likely added after local autonomy was granted on July 29th, 1961. + if self._year >= 1962: + # Feast of Saint Peter Chanel. + self._add_holiday_apr_28(tr("Saint Pierre Chanel")) + + # Saints Peter and Paul Day. + self._add_saints_peter_and_paul_day(tr("Saints Pierre et Paul")) + + # Territory Day. + self._add_holiday_jul_29(tr("Fête du Territoire")) + + +class FR(France): + """FR is also used by dateutil (Friday), so be careful with this one.""" + + pass + + +class FRA(France): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/french_guiana.py b/.venv/lib/python3.12/site-packages/holidays/countries/french_guiana.py new file mode 100644 index 00000000..feb4369c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/french_guiana.py @@ -0,0 +1,44 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysGF(ChildEntity, France): + """French Guiana holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "GF" + parent_entity = France + parent_entity_subdivision_code = "973" + # Cession from Portugal on May 30th, 1814. + start_year = 1815 + + +class FrenchGuiana(HolidaysGF): + pass + + +class GF(HolidaysGF): + pass + + +class GUF(HolidaysGF): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/french_polynesia.py b/.venv/lib/python3.12/site-packages/holidays/countries/french_polynesia.py new file mode 100644 index 00000000..fccd00c5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/french_polynesia.py @@ -0,0 +1,43 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysPF(ChildEntity, France): + """French Polynesia holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "PF" + parent_entity = France + # Pōmare V abdicated and Tahiti became a French Colony on June 29th, 1880. + start_year = 1881 + + +class FrenchPolynesia(HolidaysPF): + pass + + +class PF(HolidaysPF): + pass + + +class PYF(HolidaysPF): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/french_southern_territories.py b/.venv/lib/python3.12/site-packages/holidays/countries/french_southern_territories.py new file mode 100644 index 00000000..59624d86 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/french_southern_territories.py @@ -0,0 +1,48 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysTF(ChildEntity, France): + """French Southern Territories holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + !!! note "Note" + Since most islands doesn't have a permanent population, + the holidays are just the public ones from France. + + References: + * + * + * + """ + + country = "TF" + parent_entity = France + # This overseas territory was separated in 1955. + start_year = 1956 + + +class FrenchSouthernTerritories(HolidaysTF): + pass + + +class TF(HolidaysTF): + pass + + +class ATF(HolidaysTF): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/gabon.py b/.venv/lib/python3.12/site-packages/holidays/countries/gabon.py new file mode 100644 index 00000000..039097ea --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/gabon.py @@ -0,0 +1,147 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Gabon(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Gabon holidays. + + References: + * + * + * + * + """ + + country = "GA" + # On 17 August 1960, Gabon gained independence from France. + start_year = 1961 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=GabonIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day("New Year's Day") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Women's Rights Day. + if self._year >= 2015: + self._add_holiday_apr_17("Women's Rights Day") + + # Labour Day. + self._add_labor_day("Labour Day") + + # Ascension Day. + self._add_ascension_thursday("Ascension Day") + + # Whit Monday. + self._add_whit_monday("Whit Monday") + + # Assumption Day. + self._add_assumption_of_mary_day("Assumption Day") + + # Independence Day. + self._add_holiday_aug_16("Independence Day") + self._add_holiday_aug_17("Independence Day Holiday") + + # All Saints' Day. + self._add_all_saints_day("All Saints' Day") + + # Christmas Day. + self._add_christmas_day("Christmas Day") + + # Eid al-Fitr. + self._add_eid_al_fitr_day("Eid al-Fitr") + + # Eid al-Adha. + self._add_eid_al_adha_day("Eid al-Adha") + + +class GA(Gabon): + pass + + +class GAB(Gabon): + pass + + +class GabonIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + } + + EID_AL_FITR_DATES = { + 2001: (DEC, 17), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/georgia.py b/.venv/lib/python3.12/site-packages/holidays/countries/georgia.py new file mode 100644 index 00000000..ad43bd40 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/georgia.py @@ -0,0 +1,118 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAY +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.constants import GOVERNMENT, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Georgia(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Georgia holidays. + + References: + * + * [Labour Code of Georgia](https://web.archive.org/web/20250121212149/https://matsne.gov.ge/en/document/view/1155567?publication=24) + * [Organic Law 4455-XVIმს-Xმპ](https://web.archive.org/web/20250421162538/https://matsne.gov.ge/ka/document/view/6283937?publication=0) + """ + + country = "GE" + supported_categories = (GOVERNMENT, PUBLIC) + default_language = "ka" + supported_languages = ("en_US", "ka", "uk") + start_year = 1991 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, GeorgiaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("ახალი წელი") + self._add_new_years_day(name) + self._add_new_years_day_two(name) + + # Christmas Day. + self._add_christmas_day(tr("ქრისტეშობა")) + + # Epiphany. + self._add_epiphany_day(tr("ნათლისღება")) + + # Mother's Day. + self._add_holiday_mar_3(tr("დედის დღე")) + + # International Women's Day. + self._add_womens_day(tr("ქალთა საერთაშორისო დღე")) + + # National Unity Day. + self._add_holiday_apr_9(tr("ეროვნული ერთიანობის დღე")) + + # Good Friday. + self._add_good_friday(tr("წითელი პარასკევი")) + + # Holy Saturday. + self._add_holy_saturday(tr("დიდი შაბათი")) + + # Easter Sunday. + self._add_easter_sunday(tr("აღდგომა")) + + # Easter Monday. + self._add_easter_monday(tr("შავი ორშაბათი")) + + # Day of Victory over Fascism. + self._add_world_war_two_victory_day(tr("ფაშიზმზე გამარჯვების დღე"), is_western=False) + + # Saint Andrew's Day. + self._add_holiday_may_12(tr("წმინდა ანდრია პირველწოდებულის დღე")) + + # Established by Organic Law 4455-XVIმს-Xმპ. + if self._year >= 2025: + # Day of Family Sanctity and Respect for Parents. + self._add_holiday_may_17(tr("ოჯახის სიწმინდისა და მშობლების პატივისცემის დღე")) + + # Independence Day. + self._add_holiday_may_26(tr("დამოუკიდებლობის დღე")) + + # Dormition of the Mother of God. + self._add_assumption_of_mary_day(tr("მარიამობა")) + + # Holiday of Svetitskhovloba, Robe of Jesus. + self._add_holiday_oct_14(tr("მცხეთობის")) + + # Saint George's Day. + self._add_holiday_nov_23(tr("გიორგობა")) + + +class GE(Georgia): + pass + + +class GEO(Georgia): + pass + + +class GeorgiaStaticHolidays: + """Georgia special holidays. + + References: + * + """ + + special_government_holidays = { + # Day of Family Sanctity and Respect for Parents. + 2024: (MAY, 17, tr("ოჯახის სიწმინდისა და მშობლების პატივისცემის დღე")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/germany.py b/.venv/lib/python3.12/site-packages/holidays/countries/germany.py new file mode 100644 index 00000000..ce1eaa34 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/germany.py @@ -0,0 +1,277 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAY, JUN, OCT +from holidays.constants import CATHOLIC, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Germany(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Germany holidays. + + This class doesn't return any holidays before 1990-10-03. + + Before that date the current Germany was separated into the "German Democratic + Republic" and the "Federal Republic of Germany" which both had somewhat + different holidays. Since this class is called "Germany" it doesn't really + make sense to include the days from the two former countries. + + "Mariä Himmelfahrt" is only a holiday in Bavaria (BY) and "Fronleichnam" + in Saxony (SN) and Thuringia (TH) if municipality is mostly catholic which + in term depends on census data. It's listed in "CATHOLIC" category for these provinces. + """ + + country = "DE" + default_language = "de" + start_year = 1990 + subdivisions = ( + "BB", # Brandenburg. + "BE", # Berlin. + "BW", # Baden-Württemberg. + "BY", # Bayern. + "HB", # Bremen. + "HE", # Hessen. + "HH", # Hamburg. + "MV", # Mecklenburg-Vorpommern. + "NI", # Niedersachsen. + "NW", # Nordrhein-Westfalen. + "RP", # Rheinland-Pfalz. + "SH", # Schleswig-Holstein. + "SL", # Saarland. + "SN", # Sachsen. + "ST", # Sachsen-Anhalt. + "TH", # Thüringen. + ) + subdivisions_aliases = { + "Brandenburg": "BB", + "Berlin": "BE", + "Baden-Württemberg": "BW", + "Bayern": "BY", + "Bremen": "HB", + "Hessen": "HE", + "Hamburg": "HH", + "Mecklenburg-Vorpommern": "MV", + "Niedersachsen": "NI", + "Nordrhein-Westfalen": "NW", + "Rheinland-Pfalz": "RP", + "Schleswig-Holstein": "SH", + "Saarland": "SL", + "Sachsen": "SN", + "Sachsen-Anhalt": "ST", + "Thüringen": "TH", + } + supported_categories = (CATHOLIC, PUBLIC) + supported_languages = ("de", "en_US", "th", "uk") + _deprecated_subdivisions = ("BYP",) + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, GermanyStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year >= 1991: + # New Year's Day. + self._add_new_years_day(tr("Neujahr")) + + # Good Friday. + self._add_good_friday(tr("Karfreitag")) + + # Easter Monday. + self._add_easter_monday(tr("Ostermontag")) + + # Labor Day. + self._add_labor_day(tr("Erster Mai")) + + # Ascension Day. + self._add_ascension_thursday(tr("Christi Himmelfahrt")) + + # Whit Monday. + self._add_whit_monday(tr("Pfingstmontag")) + + # German Unity Day. + self._add_holiday_oct_3(tr("Tag der Deutschen Einheit")) + + if self._year <= 1994: + # Repentance and Prayer Day. + self._add_holiday_1st_wed_before_nov_22(tr("Buß- und Bettag")) + + # Christmas Day. + self._add_christmas_day(tr("Erster Weihnachtstag")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Zweiter Weihnachtstag")) + + if self.subdiv == "BYP": + self._populate_subdiv_by_public_holidays() + + def _populate_subdiv_bb_public_holidays(self): + if self._year >= 1991: + # Easter Sunday. + self._add_easter_sunday(tr("Ostersonntag")) + + # Whit Sunday. + self._add_whit_sunday(tr("Pfingstsonntag")) + + # Reformation Day. + self._add_holiday_oct_31(tr("Reformationstag")) + + def _populate_subdiv_be_public_holidays(self): + if self._year >= 2019: + # International Women's Day. + self._add_womens_day(tr("Internationaler Frauentag")) + + def _populate_subdiv_bw_public_holidays(self): + if self._year >= 1991: + # Epiphany. + self._add_epiphany_day(tr("Heilige Drei Könige")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Fronleichnam")) + + # All Saints' Day. + self._add_all_saints_day(tr("Allerheiligen")) + + def _populate_subdiv_by_public_holidays(self): + if self._year >= 1991: + self._add_epiphany_day(tr("Heilige Drei Könige")) + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_all_saints_day(tr("Allerheiligen")) + + def _populate_subdiv_by_catholic_holidays(self): + if self._year >= 1991: + # Assumption Day. + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + def _populate_subdiv_hb_public_holidays(self): + if self._year >= 2018: + self._add_holiday_oct_31(tr("Reformationstag")) + + def _populate_subdiv_he_public_holidays(self): + if self._year >= 1991: + self._add_corpus_christi_day(tr("Fronleichnam")) + + def _populate_subdiv_hh_public_holidays(self): + if self._year >= 2018: + self._add_holiday_oct_31(tr("Reformationstag")) + + def _populate_subdiv_mv_public_holidays(self): + if self._year >= 2023: + self._add_womens_day(tr("Internationaler Frauentag")) + + self._add_holiday_oct_31(tr("Reformationstag")) + + def _populate_subdiv_ni_public_holidays(self): + if self._year >= 2018: + self._add_holiday_oct_31(tr("Reformationstag")) + + def _populate_subdiv_nw_public_holidays(self): + if self._year >= 1991: + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_all_saints_day(tr("Allerheiligen")) + + def _populate_subdiv_rp_public_holidays(self): + if self._year >= 1991: + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_all_saints_day(tr("Allerheiligen")) + + def _populate_subdiv_sh_public_holidays(self): + if self._year >= 2018: + self._add_holiday_oct_31(tr("Reformationstag")) + + def _populate_subdiv_sl_public_holidays(self): + if self._year >= 1991: + self._add_corpus_christi_day(tr("Fronleichnam")) + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + def _populate_subdiv_sn_public_holidays(self): + self._add_holiday_oct_31(tr("Reformationstag")) + + if self._year >= 1995: + self._add_holiday_1st_wed_before_nov_22(tr("Buß- und Bettag")) + + def _populate_subdiv_sn_catholic_holidays(self): + if self._year >= 1991: + self._add_corpus_christi_day(tr("Fronleichnam")) + + def _populate_subdiv_st_public_holidays(self): + if self._year >= 1991: + self._add_epiphany_day(tr("Heilige Drei Könige")) + + self._add_holiday_oct_31(tr("Reformationstag")) + + def _populate_subdiv_th_public_holidays(self): + if self._year >= 2019: + # World Children's Day. + self._add_holiday_sep_20(tr("Weltkindertag")) + + self._add_holiday_oct_31(tr("Reformationstag")) + + def _populate_subdiv_th_catholic_holidays(self): + if self._year >= 1991: + self._add_corpus_christi_day(tr("Fronleichnam")) + + +class DE(Germany): + pass + + +class DEU(Germany): + pass + + +class GermanyStaticHolidays: + """Germany special holidays. + + References: + * + * + * + """ + + special_public_holidays = { + 2017: (OCT, 31, tr("Reformationstag")), + } + + special_be_public_holidays = { + 2020: ( + MAY, + 8, + # 75th anniversary of the liberation from Nazism and + # the end of the Second World War in Europe. + tr( + "75. Jahrestag der Befreiung vom Nationalsozialismus " + "und der Beendigung des Zweiten Weltkriegs in Europa" + ), + ), + 2025: ( + MAY, + 8, + # 80th anniversary of the liberation from Nazism and + # the end of the Second World War in Europe. + tr( + "80. Jahrestag der Befreiung vom Nationalsozialismus " + "und der Beendigung des Zweiten Weltkriegs in Europa" + ), + ), + # 75th anniversary of the East German uprising of 1953. + 2028: (JUN, 17, tr("75. Jahrestag des Aufstandes vom 17. Juni 1953")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/ghana.py b/.venv/lib/python3.12/site-packages/holidays/countries/ghana.py new file mode 100644 index 00000000..e2008ff8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/ghana.py @@ -0,0 +1,103 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Ghana(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Ghana holidays. + + References: + * + * + """ + + country = "GH" + estimated_label = "%s (estimated)" + observed_label = "%s (observed)" + observed_estimated_label = "%s (observed, estimated)" + start_year = 1957 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Constitution Day + if self._year >= 2019: + self._add_observed(self._add_holiday_jan_7("Constitution Day")) + + # Independence Day + self._add_observed(self._add_holiday_mar_6("Independence Day")) + + # Good Friday + self._add_good_friday("Good Friday") + + # Easter Monday + self._add_easter_monday("Easter Monday") + + # May Day(Workers' Day) + self._add_observed(self._add_labor_day("May Day")) + + # Eid al-Fitr + for dt in self._add_eid_al_fitr_day("Eid ul-Fitr"): + self._add_observed(dt) + + # Eid al-Adha + for dt in self._add_eid_al_adha_day("Eid ul-Adha"): + self._add_observed(dt) + + # Founders' Day + if self._year >= 2019: + self._add_observed(self._add_holiday_aug_4("Founders' Day")) + + # Kwame Nkrumah Memorial Day / Founder's Day + if self._year >= 2009: + self._add_observed( + self._add_holiday_sep_21( + "Kwame Nkrumah Memorial Day" if self._year >= 2019 else "Founder's Day" + ) + ) + + # Farmer's Day + self._add_holiday_1st_fri_of_dec("Farmer's Day") + + # Christmas Day + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + # Boxing Day + self._add_observed(self._add_christmas_day_two("Boxing Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + +class GH(Ghana): + pass + + +class GHA(Ghana): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/gibraltar.py b/.venv/lib/python3.12/site-packages/holidays/countries/gibraltar.py new file mode 100644 index 00000000..33ea5586 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/gibraltar.py @@ -0,0 +1,219 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, FEB, APR, MAY, JUN, AUG, SEP +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Gibraltar(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Gibraltar holidays. + + References: + * + * [2000](https://web.archive.org/web/20250714134510/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/1999s073.pdf) + * [2001](https://web.archive.org/web/20250714134609/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2000s041.pdf) + * [2003](https://web.archive.org/web/20250713064759/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2002s094.pdf) + * [2004](https://web.archive.org/web/20250713065008/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2003s105.pdf) + * [2005](https://web.archive.org/web/20250713071914/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2004s069.pdf) + * [2006](https://web.archive.org/web/20250713072021/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2005s111.pdf) + * [2007](https://web.archive.org/web/20250713072021/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2006s122.pdf) + * [2008](https://web.archive.org/web/20250713072026/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2007s113.pdf) + * [2009](https://web.archive.org/web/20250713072221/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2008s073.pdf) + * [2010](https://web.archive.org/web/20250713072222/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2009s049.pdf) + * [2011](https://web.archive.org/web/20250713072228/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2010s149.pdf) + * [2012](https://web.archive.org/web/20250713073334/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2011s189.pdf) + * [2013](https://web.archive.org/web/20250713162959/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2012s146.pdf) + * [2014](https://web.archive.org/web/20250713103345/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2013s149.pdf) + * [2015](https://web.archive.org/web/20250713163521/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2014s203.pdf) + * [2016](https://web.archive.org/web/20250713164519/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2015s196.pdf) + * [2017](https://web.archive.org/web/20250713073752/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2016s217.pdf) + * [2018](https://web.archive.org/web/20250714135250/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2017s224.pdf) + * [2019](https://web.archive.org/web/20250713071343/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2018s229.pdf) + * [2020](https://web.archive.org/web/20250714135425/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2019s217.pdf) + * [2021](https://web.archive.org/web/20250421063152/https://www.gibraltarlaws.gov.gi/legislations/bank-and-public-holidays-order-2020-5593/download) + * [2022](https://web.archive.org/web/20250414134257/https://www.gibraltarlaws.gov.gi/legislations/bank-and-public-holidays-order-2021-6286/version/21-10-2021/download) + * [2023](https://web.archive.org/web/20240831014104/https://www.gibraltarlaws.gov.gi/legislations/bank-and-public-holidays-order-2022-6735/version/22-02-2023/download) + * [2024](https://web.archive.org/web/20250502030403/https://www.gibraltarlaws.gov.gi/legislations/bank-and-public-holidays-order-2023-7215/version/06-11-2023/download) + * [2025](https://web.archive.org/web/20250714135600/https://www.gibraltarlaws.gov.gi/legislations/bank-and-public-holidays-order-2024-7456/download) + """ + + country = "GI" + default_language = "en_GB" + # %s (observed). + observed_label = tr("%s (observed)") + # First holiday info available from 2000. + start_year = 2000 + supported_languages = ("en_GB", "en_US") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, GibraltarStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + name = ( + # Winter Midterm Bank Holiday. + tr("Winter Midterm Bank Holiday") + if self._year >= 2023 + # Commonwealth Day. + else tr("Commonwealth Day") + ) + winter_midterm_dts = { + 2024: (FEB, 12), + } + if dt := winter_midterm_dts.get(self._year): + self._add_holiday(name, dt) + elif self._year >= 2021: + self._add_holiday_3rd_mon_of_feb(name) + else: + self._add_holiday_2nd_mon_of_mar(name) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + if self._year >= 2013: + # Workers' Memorial Day. + name = tr("Workers' Memorial Day") + workers_memorial_dts = { + 2013: (APR, 26), + 2015: (APR, 27), + } + if dt := workers_memorial_dts.get(self._year): + self._add_holiday(name, dt) + else: + self._add_observed(self._add_holiday_apr_28(name)) + + # May Day. + name = tr("May Day") + may_day_dts = { + 2007: (MAY, 7), + 2008: (MAY, 5), + 2009: (MAY, 4), + } + if dt := may_day_dts.get(self._year): + self._add_holiday(name, dt) + else: + self._add_observed(self._add_holiday_may_1(name)) + + # Spring Bank Holiday. + name = tr("Spring Bank Holiday") + spring_bank_dts = { + 2012: (JUN, 4), + 2022: (JUN, 2), + } + if dt := spring_bank_dts.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_last_mon_of_may(name) + + name = ( + # King's Birthday. + tr("King's Birthday") + if self._year >= 2023 + # Queen's Birthday. + else tr("Queen's Birthday") + ) + sovereign_birthday_dts = { + 2000: (JUN, 19), + 2001: (JUN, 18), + 2006: (JUN, 19), + 2007: (JUN, 18), + 2012: (JUN, 18), + 2013: (JUN, 17), + 2017: (JUN, 19), + 2019: (JUN, 17), + 2023: (JUN, 19), + 2024: (JUN, 17), + } + if dt := sovereign_birthday_dts.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_2_days_past_2nd_sat_of_jun(name) + + self._add_holiday_last_mon_of_aug( + # Summer Bank Holiday. + tr("Summer Bank Holiday") + if 2002 <= self._year <= 2007 + # Late Summer Bank Holiday. + else tr("Late Summer Bank Holiday") + ) + + # Gibraltar National Day. + name = tr("Gibraltar National Day") + national_day_dts = { + 2016: (SEP, 5), + 2017: (SEP, 4), + } + if dt := national_day_dts.get(self._year): + self._add_holiday(name, dt) + else: + self._add_observed(self._add_holiday_sep_10(name)) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + +class GI(Gibraltar): + pass + + +class GIB(Gibraltar): + pass + + +class GibraltarStaticHolidays(StaticHolidays): + """Gibraltar special holidays. + + References: + * [Evacuation Commemoration Day, 2015](https://web.archive.org/web/20250714174537/https://www.gibraltarlaws.gov.gi/uploads/legislations/banking-and-financial-dealings/B&P%20Holidays/2015s112.pdf) + """ + + special_public_holidays = { + # Tercentenary Holiday. + 2004: (AUG, 4, tr("Tercentenary Holiday")), + # Bank Holiday. + 2009: (JAN, 12, tr("Bank Holiday")), + # Queen's Diamond Jubilee. + 2012: (JUN, 5, tr("Queen's Diamond Jubilee")), + # Evacuation Commemoration Day. + 2015: (SEP, 7, tr("Evacuation Commemoration Day")), + # 75th Anniversary of VE Day. + 2020: (MAY, 8, tr("75th Anniversary of VE Day")), + # Queen's Platinum Jubilee. + 2022: (JUN, 3, tr("Platinum Jubilee")), + # Special King’s Coronation Bank Holiday. + 2023: (MAY, 8, tr("Special King's Coronation Bank Holiday")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/greece.py b/.venv/lib/python3.12/site-packages/holidays/countries/greece.py new file mode 100644 index 00000000..968d049c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/greece.py @@ -0,0 +1,104 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.julian_revised import JULIAN_REVISED_CALENDAR +from holidays.constants import HALF_DAY, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_WORKDAY, +) + + +class Greece(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Greece holidays. + + References: + * + * [2024 Labor Day transfer](https://web.archive.org/web/20240813221449/https://www.et.gr/api/DownloadFeksApi/?fek_pdf=20240201406) + """ + + country = "GR" + default_language = "el" + # %s (observed). + observed_label = tr("%s (παρατηρήθηκε)") + supported_categories = (HALF_DAY, PUBLIC) + supported_languages = ("el", "en_US", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_REVISED_CALENDAR) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 2017) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Πρωτοχρονιά")) + + # Epiphany. + self._add_epiphany_day(tr("Θεοφάνεια")) + + # Green Monday. + self._add_ash_monday(tr("Καθαρά Δευτέρα")) + + # Independence Day. + self._add_holiday_mar_25(tr("Εικοστή Πέμπτη Μαρτίου")) + + # Good Friday. + self._add_good_friday(tr("Μεγάλη Παρασκευή")) + + # Easter Monday. + easter_monday = self._add_easter_monday(tr("Δευτέρα του Πάσχα")) + + # Whit Monday. + self._add_whit_monday(tr("Δευτέρα του Αγίου Πνεύματος")) + + # Labor Day. + name = tr("Εργατική Πρωτομαγιά") + if self._year == 2024: + self._add_holiday_may_7(name) + else: + self._add_observed( + may_1 := self._add_labor_day(name), + rule=MON_TO_NEXT_TUE if may_1 == easter_monday else SAT_SUN_TO_NEXT_WORKDAY, + ) + + # Dormition of the Mother of God. + self._add_assumption_of_mary_day(tr("Κοίμηση της Θεοτόκου")) + + # Ochi Day. + self._add_holiday_oct_28(tr("Ημέρα του Όχι")) + + # Christmas Day. + self._add_christmas_day(tr("Χριστούγεννα")) + + # Glorifying of the Mother of God. + self._add_christmas_day_two(tr("Σύναξη της Υπεραγίας Θεοτόκου")) + + def _populate_half_day_holidays(self): + # Christmas Eve. + self._add_christmas_eve(tr("Παραμονή Χριστουγέννων")) + + # New Year's Eve. + self._add_new_years_eve(tr("Παραμονή Πρωτοχρονιάς")) + + +class GR(Greece): + pass + + +class GRC(Greece): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/greenland.py b/.venv/lib/python3.12/site-packages/holidays/countries/greenland.py new file mode 100644 index 00000000..a25d71b2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/greenland.py @@ -0,0 +1,98 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Greenland(HolidayBase, ChristianHolidays, InternationalHolidays): + """Greenland holidays. + + References: + * + * [Greenlandic names source](https://web.archive.org/web/20241214072442/https://nalunaarutit.gl/groenlandsk-lovgivning/2008/bkg-26-2008?sc_lang=kl-GL) + * [Translation source](https://web.archive.org/web/20250422014548/https://www.norden.org/en/info-norden/public-holidays-greenland) + """ + + country = "GL" + default_language = "kl" + supported_categories = (OPTIONAL, PUBLIC) + supported_languages = ("da", "en_US", "fi", "is", "kl", "no", "sv", "uk") + # Greenland Home Rule Act 1978. + start_year = 1979 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Ukiortaaq")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Sisamanngortoq illernartoq")) + + # Good Friday. + self._add_good_friday(tr("Tallimanngorneq tannaartoq")) + + # Easter Sunday. + self._add_easter_sunday(tr("Poorskip ullua")) + + # Easter Monday. + self._add_easter_monday(tr("Poorskip-aappaa")) + + # Great Prayer Day. + self._add_holiday_26_days_past_easter(tr("Ulloq qinuffiusoq")) + + # Ascension Day. + self._add_ascension_thursday(tr("Qilaliarfik")) + + # Whit Sunday. + self._add_whit_sunday(tr("Piinsip ullua")) + + # Whit Monday. + self._add_whit_monday(tr("Piinsip-aappaa")) + + # Christmas Day. + self._add_christmas_day(tr("Juullip ullua")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Juullip-aappaa")) + + def _populate_optional_holidays(self): + # Epiphany. + self._add_epiphany_day(tr("Kunngit pingasut ulluat")) + + # International Workers' Day. + self._add_labor_day(tr("Sulisartut ulluat")) + + if self._year >= 1983: + # National Day. + self._add_holiday_jun_21(tr("Ullortuneq")) + + # Christmas Eve. + self._add_christmas_eve(tr("Juulliaraq")) + + # New Year's Eve. + self._add_new_years_eve(tr("Ukiortaami")) + + +class GL(Greenland): + pass + + +class GRL(Greenland): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/grenada.py b/.venv/lib/python3.12/site-packages/holidays/countries/grenada.py new file mode 100644 index 00000000..f210a62a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/grenada.py @@ -0,0 +1,143 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import FEB, MAR, JUN, JUL, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Grenada(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Grenada holidays. + + References: + * + * [Bank Holidays Act](https://web.archive.org/web/20250504095840/https://laws.gov.gd/index.php/chapters/b-23-39/1042-cap25-bank-holidays-act-2/viewdocument/1042) + * + * [National Heroes' Day](https://web.archive.org/web/20250504095924/https://www.gov.gd/component/edocman/grenadas-first-national-heroes-day-and-october-19th-commemoration-events/viewdocument/576) + * [Emancipation Day](https://web.archive.org/web/20250504100015/https://nowgrenada.com/2025/01/gnrc-chairman-supports-1-august-as-national-holiday/) + + Checked With: + * [2010](https://web.archive.org/web/20100108053101/http://www.gov.gd/holiday_events.html) + * [2011](https://web.archive.org/web/20111007094915/http://www.gov.gd/holiday_events.html) + * [2012](https://web.archive.org/web/20120623100105/http://www.gov.gd/holiday_events.html) + * [2013](https://web.archive.org/web/20130805181426/http://www.gov.gd/holiday_events.html) + * [2014](https://web.archive.org/web/20140424191452/http://www.gov.gd/holiday_events.html) + * [2015](https://web.archive.org/web/20150701045051/http://www.gov.gd/holiday_events.html) + * [2016](https://web.archive.org/web/20160518030722/http://www.gov.gd/holiday_events.html) + * [2017](https://web.archive.org/web/20170505034606/http://www.gov.gd/holiday_events.html) + * [2018](https://web.archive.org/web/20180424025139/http://www.gov.gd/holiday_events.html) + * [2023](https://web.archive.org/web/20230329094946/https://www.gov.gd/pdf/Public%20Holidays%202023.pdf) + * [2025](https://web.archive.org/web/20250130143152/https://www.gov.gd/component/edocman/grenadas-public-holidays-2025/viewdocument/1386) + """ + + country = "GD" + default_language = "en_GD" + # %s (observed). + observed_label = tr("%s (observed)") + # First available revision of Bank Holidays Act. + start_year = 2000 + supported_languages = ("en_GD", "en_US") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, GrenadaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Independence Day. + self._add_observed(self._add_holiday_feb_7(tr("Independence Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Labour Day"))) + + # Whit Monday. + self._add_whit_monday(tr("Whit Monday")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + # Emancipation Day. + name = tr("Emancipation Day") + if self._year >= 2025: + self._add_observed(self._add_holiday_aug_1(name)) + else: + self._add_holiday_1st_mon_of_aug(name) + + # Carnival Monday. + self._add_holiday_2nd_mon_of_aug(tr("Carnival Monday")) + + # Carnival Tuesday. + self._add_holiday_1_day_past_2nd_mon_of_aug(tr("Carnival Tuesday")) + + if self._year >= 2023: + # National Heroes' Day. + self._add_observed(self._add_holiday_oct_19(tr("National Heroes' Day"))) + + # Thanksgiving Day. + self._add_observed(self._add_holiday_oct_25(tr("Thanksgiving Day"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day"))) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two(tr("Boxing Day"))) + + +class GD(Grenada): + pass + + +class GRD(Grenada): + pass + + +class GrenadaStaticHolidays: + """Grenada special holidays. + + References: + * [2011](https://web.archive.org/web/20250504100149/https://laws.gov.gd/index.php/s-r-o/37-sr-o-35-of-2011-bank-holiday/viewdocument/37) + * [2013](https://web.archive.org/web/20250504100219/https://laws.gov.gd/index.php/s-r-o/93-sro-6-of-2013-bank-holiday/viewdocument/93) + * [2016](https://web.archive.org/web/20250504100408/https://laws.gov.gd/index.php/s-r-o/289-sr-o-61-of-2016-bank-holiday/viewdocument/289) + * [2018](https://web.archive.org/web/20250504100436/https://laws.gov.gd/index.php/s-r-o/348-sr-o-10-of-2018-bank-holiday-proclamation/viewdocument/348) + * [24 June 2022](https://web.archive.org/web/20250504100516/https://laws.gov.gd/index.php/s-r-o/576-sr-o-33-of-2022-bank-holiday-proclamation-2022/viewdocument/576) + * [27 December 2022](https://web.archive.org/web/20250504100538/https://laws.gov.gd/index.php/s-r-o/586-sr-o-43-of-2022-bank-holiday-proclamation-2022/viewdocument/586) + * [CARICOM's 50th Anniversary 2023](https://web.archive.org/web/20250504100603/https://laws.gov.gd/index.php/s-r-o/612-sr-o-22-of-2023-bank-holiday-proclamation-2023/viewdocument/612) + """ + + # Bank Holiday. + bank_holiday = tr("Bank Holiday") + + special_public_holidays = { + 2011: (DEC, 27, bank_holiday), + 2013: (FEB, 22, bank_holiday), + 2016: (DEC, 27, bank_holiday), + 2018: (MAR, 14, bank_holiday), + 2022: ( + (JUN, 24, bank_holiday), + (DEC, 27, bank_holiday), + ), + # CARICOM's 50th Anniversary. + 2023: (JUL, 4, tr("CARICOM's 50th Anniversary")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/guadeloupe.py b/.venv/lib/python3.12/site-packages/holidays/countries/guadeloupe.py new file mode 100644 index 00000000..0bc9a1d3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/guadeloupe.py @@ -0,0 +1,44 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysGP(ChildEntity, France): + """Guadeloupe holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "GP" + parent_entity = France + parent_entity_subdivision_code = "971" + # Cession from Sweden on May 30th, 1814. + start_year = 1815 + + +class Guadeloupe(HolidaysGP): + pass + + +class GP(HolidaysGP): + pass + + +class GLP(HolidaysGP): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/guam.py b/.venv/lib/python3.12/site-packages/holidays/countries/guam.py new file mode 100644 index 00000000..ca5c74b9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/guam.py @@ -0,0 +1,39 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.united_states import UnitedStates +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysGU(ChildEntity, UnitedStates): + """Guam holidays. + + Alias of a US subdivision that is also officially assigned its own country code in ISO 3166-1. + See + """ + + country = "GU" + parent_entity = UnitedStates + # Became a U.S. Territory on April 11th, 1899. + start_year = 1900 + + +class Guam(HolidaysGU): + pass + + +class GU(HolidaysGU): + pass + + +class GUM(HolidaysGU): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/guatemala.py b/.venv/lib/python3.12/site-packages/holidays/countries/guatemala.py new file mode 100644 index 00000000..ebfa590b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/guatemala.py @@ -0,0 +1,90 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import OCT +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, ALL_TO_NEAREST_MON_LATAM + + +class Guatemala(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Guatemala holidays. + + References: + * + * + + Moving holidays: + * [Decree 19-2018 start 18 oct 2018](https://web.archive.org/web/20250426043930/https://www.minfin.gob.gt/images/downloads/leyes_acuerdos/decretocong19_101018.pdf) + * [Case 5536-2018 (CC) start 17 abr 2020](https://web.archive.org/web/20240625093244/https://leyes.infile.com/index.php?id=182&id_publicacion=81055) + """ + + country = "GT" + default_language = "es" + supported_languages = ("en_US", "es") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", ALL_TO_NEAREST_MON_LATAM) + super().__init__(*args, **kwargs) + + def _is_observed(self, dt: date) -> bool: + return dt >= date(2018, OCT, 18) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Holy Saturday. + self._add_holy_saturday(tr("Sábado Santo")) + + # Labor Day. + dt = self._add_labor_day(tr("Día del Trabajo")) + if self._year == 2019: + self._move_holiday(dt) + + # Army Day. + self._move_holiday(self._add_holiday_jun_30(tr("Día del Ejército"))) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Día de la Asunción")) + + # Independence Day. + self._add_holiday_sep_15(tr("Día de la Independencia")) + + # Revolution Day. + dt = self._add_holiday_oct_20(tr("Día de la Revolución")) + if self._year in {2018, 2019}: + self._move_holiday(dt) + + # All Saints' Day. + self._add_all_saints_day(tr("Día de Todos los Santos")) + + # Christmas Day. + self._add_christmas_day(tr("Día de Navidad")) + + +class GT(Guatemala): + pass + + +class GUA(Guatemala): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/guernsey.py b/.venv/lib/python3.12/site-packages/holidays/countries/guernsey.py new file mode 100644 index 00000000..01e8d6a2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/guernsey.py @@ -0,0 +1,331 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import JAN, APR, MAY, JUN, JUL, SEP, OCT, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_WORKDAY, + SUN_TO_NEXT_WORKDAY, +) + + +class Guernsey(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Guernsey holidays. + + References: + * + * + * + + Checked with: + * + + His/Her Majesty's Birthday pre-1946 is cross-checked with The London Gazette's Record, + Specifically as "Home Station" entry under King's Birthday declaration lists. + + Since 1955, if a bank holiday is on a sunday, a substitute weekday becomes a bank holiday, + normally the following Monday. From 2009 onwards this also applies to saturday as well. + """ + + country = "GG" + observed_label = "%s (substitute day)" + # Ordonnance relative aux Jours Fériés, 1909. + start_year = 1909 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, GuernseyStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 1955) + ObservedHolidayBase.__init__(self, *args, **kwargs) + + def _add_observed(self, dt: date, **kwargs) -> tuple[bool, Optional[date]]: + # Prior to 2009, in-lieu are only given for Sundays. + # https://web.archive.org/web/20230930101652/https://guernseylegalresources.gg/CHttpHandler.ashx?documentid=55179 + kwargs.setdefault( + "rule", SUN_TO_NEXT_WORKDAY if dt < date(2009, DEC, 15) else self._observed_rule + ) + return super()._add_observed(dt, **kwargs) + + def _populate_public_holidays(self) -> None: + # New Year's Day + # Le jour de l'An + + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Good Friday + # Vendredi Saint + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Monday + # Le Lundi de Pâques + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # May Day + # (No official Guernésiais translation available) + # Started in 1980 for Guernsey. + # Moved to May 8 specifically for 1995 and 2020. + + if self._year >= 1980: + # May Day Bank Holiday + name = "May Day Bank Holiday" + if self._year in {1995, 2020}: + self._add_holiday_may_8(name) + else: + self._add_holiday_1st_mon_of_may(name) + + # Spring bank holiday + # (No official Guernésiais translation available) + # Replaced Whit Monday in 1967, 1970, 1973, 1974, 1975, 1976. + # No observance in 1977-1978. Properly established from 1979 onwards. + # Moved for Queen Elizabeth II's Jubilee Dates in 2002, 2012, and 2022. + + if self._year in {1967, 1970} or 1973 <= self._year <= 1976 or self._year >= 1979: + spring_bank_dates = { + 2002: (JUN, 4), + 2012: (JUN, 4), + 2022: (JUN, 2), + } + # Spring Bank Holiday + name = "Spring Bank Holiday" + if dt := spring_bank_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_last_mon_of_may(name) + + # Whit Monday + # Le lundi de Pentecôte + # Replaced by Spring Bank Holiday in 1967, 1970, 1973, 1974, 1975, 1976. + # Fully Removed in 1977. + + if self._year <= 1966 or self._year in {1968, 1969, 1971, 1972}: + # Whit Monday. + self._add_whit_monday("Whit Monday") + + # His/Her Majesty's Birthday + # La jour fixé pour la célébration du jour de naissanee de Sa Majesté + # Special Non-Observance Decree was issued in 1940. + # This was fully replaced by Liberation Day in 1947. + + if self._year <= 1946: + his_majesty_birth_dates = { + # Edward VII (MAY/JUN observance). + 1909: (JUN, 25), # (NOV, 9) for overseas. + # George V. + 1910: (JUN, 24), # (NOV, 9) for overseas; No decree cancelled Edward VII ones. + 1911: (MAY, 27), # (JUN, 3) for overseas. + 1912: (JUN, 14), # (JUN, 3) for overseas. + 1913: (JUN, 3), + 1914: (JUN, 24), # Specifically held on the 24th on Guernsey, is 22nd elsewhere. + # Not observed in 1915-1918 due to WW1. + 1919: (JUN, 3), + 1920: (JUN, 5), # (JUN, 3) for overseas. + 1921: (JUN, 4), # (JUN, 3) for overseas. + 1922: (JUN, 3), + 1923: (JUN, 2), + 1924: (JUN, 3), + 1925: (JUN, 3), + 1926: (JUN, 5), + 1927: (JUN, 3), + 1928: (JUN, 4), + 1929: (JUN, 3), + 1930: (JUN, 3), + 1931: (JUN, 3), + 1932: (JUN, 3), + 1933: (JUN, 3), + 1934: (JUN, 4), + 1935: (JUN, 3), + # Edward VIII. + 1936: (JUN, 23), + # George VI. + 1937: (JUN, 9), + 1938: (JUN, 9), + 1939: (JUN, 8), + # Not observed in 1940-1941 due to WW2. + # Although this was only de jure cancelled in 1940 for Guernsey. + 1942: (JUN, 11), + 1943: (JUN, 2), + 1944: (JUN, 8), + 1945: (JUN, 14), + 1946: (JUN, 13), + } + if dt := his_majesty_birth_dates.get(self._year): + # His Majesty's Birthday. + self._add_holiday("His Majesty's Birthday", dt) + + # Summer Bank Holiday + # Le premier Lundi du mois d'Août + # Current Pattern started in 1965. Was initially on first Monday of August for Guernsey. + # Briefly as first Monday of September between 1968-1969 and no observance for 1977-1978. + + # Summer Bank Holiday. + summer_bank_holiday = "Summer Bank Holiday" + if self._year <= 1976 or self._year >= 1979: + if 1968 <= self._year <= 1969: + self._add_holiday_1st_mon_of_sep(summer_bank_holiday) + elif self._year >= 1965: + self._add_holiday_last_mon_of_aug(summer_bank_holiday) + else: + self._add_holiday_1st_mon_of_aug(summer_bank_holiday) + + # Christmas Day + # Le jour de Noël + + # Christmas Day + christmas_day = self._add_christmas_day("Christmas Day") + + # Boxing Day + # Le premier jour ouvrier après le jour de Noël + + # Boxing Day + boxing_day = self._add_christmas_day_two("Boxing Day") + + self._add_observed(christmas_day) + self._add_observed(boxing_day) + + # Guernsey exclusive holidays + + # Liberation Day + # Le jour fixé par les Etats pour la célébration de la Libération de cette Ile + # de l'occupation allemande par les Forces Britannique + # Started in 1946 for Guernsey. Fully replaced HM Birthdays in 1947. This has no in-lieus. + # Specifically moved to May 10 in 2010. + # Unlike Jersey this wasn't moved in 2021. + + if self._year >= 1946: + liberation_dates = { + 2010: (MAY, 10), + } + # Liberation Day. + name = "Liberation Day" + if dt := liberation_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_may_9(name) + + +class GG(Guernsey): + pass + + +class GGY(Guernsey): + pass + + +class GuernseyStaticHolidays: + """Guernsey special holidays. + + References: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + + All "jour de relâche" entries are translated as special day off instead. + + While there's no source for Queen Elizabeth II's Silver Jubilee being observed + by Guernsey - it's safe to assume such holiday was declared. + """ + + # Special Day Off. + special_day_off = "Special Day Off" + + # The visit of Her Majesty Queen Elizabeth II. + elizabeth_2_royal_visit = "The visit of Her Majesty Queen Elizabeth II" + + # Millenium Celebrations. + millenium_celebrations = "Millennium Celebrations" + + # New Year's Day. + new_years_day_in_lieu = "New Year's Day" + + # Christmas Day. + christmas_day_in_lieu = "Christmas Day" + + # Boxing Day. + boxing_day_in_lieu = "Boxing Day" + + special_public_holidays = { + 1930: (OCT, 10, special_day_off), + 1935: (MAY, 6, "Silver Jubilee of King George V"), + 1937: (MAY, 12, "The Coronation of King George VI and Queen Elizabeth"), + 1939: (SEP, 4, special_day_off), + 1949: (SEP, 19, special_day_off), + 1953: (JUN, 2, "The Coronation of Queen Elizabeth II"), + 1957: (JUL, 26, elizabeth_2_royal_visit), + 1977: (JUN, 7, "Silver Jubilee of Elizabeth II"), + 1978: (JUN, 28, elizabeth_2_royal_visit), + 1981: (JUL, 29, "Wedding of Charles and Diana"), + 1989: (MAY, 23, elizabeth_2_royal_visit), + 1999: ( + (DEC, 28, millenium_celebrations), + (DEC, 31, millenium_celebrations), + ), + 2000: (JAN, 3, millenium_celebrations), + 2001: (JUL, 12, elizabeth_2_royal_visit), + 2002: (JUN, 3, "Golden Jubilee of Elizabeth II"), + 2011: (APR, 29, "Wedding of William and Catherine"), + 2012: (JUN, 5, "Diamond Jubilee of Elizabeth II"), + 2022: ( + (JUN, 3, "Queen's Platinum Jubilee Bank Holiday"), + (SEP, 19, "State Funeral of Queen Elizabeth II"), + ), + 2023: (MAY, 8, "Extra Public Holiday for the Coronation of King Charles III"), + 2024: (JUL, 16, "The visit of His Majesty King Charles III and Queen Camilla"), + } + special_public_holidays_observed = { + 1932: (DEC, 27, christmas_day_in_lieu), + 1933: (JAN, 2, new_years_day_in_lieu), + 1938: (DEC, 27, christmas_day_in_lieu), + 1939: (JAN, 2, new_years_day_in_lieu), + 1981: (DEC, 28, boxing_day_in_lieu), + 1982: (DEC, 28, christmas_day_in_lieu), + 1983: (JAN, 3, new_years_day_in_lieu), + 1987: (DEC, 28, boxing_day_in_lieu), + 1993: (DEC, 28, christmas_day_in_lieu), + 1994: (JAN, 3, new_years_day_in_lieu), + 2004: (DEC, 28, christmas_day_in_lieu), + 2005: (JAN, 3, new_years_day_in_lieu), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/guinea.py b/.venv/lib/python3.12/site-packages/holidays/countries/guinea.py new file mode 100644 index 00000000..389862ca --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/guinea.py @@ -0,0 +1,182 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Guinea(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Guinea holidays. + + References: + * [Decree No. 2022-0526](https://archive.org/details/d-2022-0526-prg-cnrd-221103-131021) + * + * + * + * + * + + According to Decree No. 2022-0526 of 2 November 2022: + * Eid al-Adha became a two-day holiday (Article 1). + * If New Year's Day, Independence Day or Eid al-Fitr fall on a non-working day, + the next working day is also a holiday (Article 2). + """ + + country = "GN" + default_language = "fr" + # %s (estimated). + estimated_label = tr("%s (estimé)") + # Day after the %s. + observed_label = tr("Lendemain de la %s") + # Day after the %s (estimated). + observed_estimated_label = tr("Lendemain de la %s (estimé)") + supported_languages = ("en_US", "fr") + + # Guinea gained independence from France on October 2, 1958. + start_year = 1959 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=GuineaIslamicHolidays, show_estimated=islamic_show_estimated + ) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + dt = self._add_new_years_day(tr("Fête du Nouvel an")) + if self._year >= 2023: + self._add_observed(dt) + + if 1985 <= self._year <= 2021: + # Second Republic Day. + self._add_holiday_apr_3(tr("Jour de la Deuxième République")) + + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + # Labor Day. + self._add_labor_day(tr("Fête du Travail")) + + # Africa Day. + self._add_africa_day(tr("Anniversaire de l'Union Africaine")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assomption")) + + # Independence Day. + dt = self._add_holiday_oct_2(tr("Fête anniversaire de l'indépendance de la Guinée")) + if self._year >= 2023: + self._add_observed(dt) + + if self._year <= 2021: + # All Saints' Day. + self._add_all_saints_day(tr("Toussaint")) + + # Christmas Day. + self._add_christmas_day(tr("Fête de Noël")) + + # Day after Prophet's Birthday. + self._add_mawlid_day(tr("Lendemain de la nuit du Maoloud")) + + # Day after Night of Power. + self._add_laylat_al_qadr_day(tr("Lendemain de la nuit Lailatoul Qadr")) + + # Eid al-Fitr. + for dt in self._add_eid_al_fitr_day(tr("Jour de l'Aïd el-Fitr")): + if self._year >= 2023: + self._add_observed(dt) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Jour de la Tabaski")) + + if self._year >= 2023: + # Day after Eid al-Adha. + self._add_eid_al_adha_day_two(tr("Lendemain de la Tabaski")) + + +class GN(Guinea): + pass + + +class GIN(Guinea): + pass + + +class GuineaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 10), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + MAWLID_DATES = { + 2015: (DEC, 24), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 20), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 15), + 2025: (SEP, 5), + } + + LAYLAT_AL_QADR_DATES = { + 2015: (JUL, 14), + 2016: (JUL, 3), + 2017: (JUN, 22), + 2018: (JUN, 12), + 2019: (JUN, 1), + 2020: (MAY, 20), + 2021: (MAY, 9), + 2022: (APR, 29), + 2023: (APR, 18), + 2024: (APR, 6), + 2025: (MAR, 27), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/guyana.py b/.venv/lib/python3.12/site-packages/holidays/countries/guyana.py new file mode 100644 index 00000000..4e294e60 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/guyana.py @@ -0,0 +1,279 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomHinduHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ( + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, + SUN_TO_NEXT_MON, +) + + +class Guyana( + ObservedHolidayBase, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Guyana holidays. + + References: + * [Public Holidays Amendment Act 1967](https://web.archive.org/web/20241125073357/https://parliament.gov.gy/documents/bills/11264-bill_6_of_1967_public_holidays.pdf) + * [Public Holidays Amendment Act 1969](https://web.archive.org/web/20250424211718/https://parliament.gov.gy/documents/bills/11891-bill_26_of_1969_1.pdf) + * [Public Holidays Act Consolidated as of 2012](https://web.archive.org/web/20250608202320/https://mola.gov.gy/laws/Volume%206%20Cap.%2018.01%20-%2023.011696968337.pdf) + * [2021-2025](https://web.archive.org/web/20250614200338/https://moha.gov.gy/public-holidays/) + + The holidays below are not part of the latest Public Holidays Act but have been notified + every year as a holiday by Gazette notifications for many years. The earliest and latest + available notifications for each are linked below. + + * Independence Day: + * [Extraordinary Gazette 14 May 2016](https://web.archive.org/web/20250210091920/https://officialgazette.gov.gy/images/gazettes-files/Extraordinary-gazette_14may161.pdf) + * [Extraordinary Gazette 10 May 2025](https://web.archive.org/web/20250611200312/https://officialgazette.gov.gy/images/gazette2025/may/Extra_10MAY2025NotiPHA.pdf) + * CARICOM Day: + * [Extraordinary Gazette 29 June 2016](https://web.archive.org/web/20250209205727/https://officialgazette.gov.gy/images/gazettes-files/Extraordinary-gazette_29jun16.pdf) + * [Extraordinary Gazette 22 June 2024](https://web.archive.org/web/20250209154128/https://officialgazette.gov.gy/images/gazette2024/jun/Extra_22JUNE2024NotiPHA.pdf) + * Arrival Day: + * [Extraordinary Gazette 16 April 2019](https://web.archive.org/web/20221118182239/https://officialgazette.gov.gy/images/gazette2019/apr/Extra_20APRIL2019NotPubHol.pdf) + * [Extraordinary Gazette 26 April 2025](https://web.archive.org/web/20250611200310/https://officialgazette.gov.gy/images/gazette2025/apr/Extra_26APRIL2025PHA.pdf) + * Commonwealth Day / Emancipation Day: + * No amendment act removing Commonwealth Day and adding Emancipation Day it has been that + way in annual Gazette notifications for years. + * [Extraordinary Gazette 21 July 2016](https://web.archive.org/web/20250211095036/https://officialgazette.gov.gy/images/gazettes-files/Extraordinary-gazette_21jul16.pdf) + * [Extraordinary Gazette 16 July 2022](https://web.archive.org/web/20231214011437/https://officialgazette.gov.gy/images/gazette2022/jul/Extra_16JULY2022NotificPHA.pdf) + """ + + country = "GY" + default_language = "en_GY" + # %s (estimated). + estimated_label = tr("%s (estimated)") + # %s (observed). + observed_label = tr("%s (observed)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observed, estimated)") + start_year = 1968 + supported_languages = ("en_GY", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=GuyanaHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=GuyanaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=GuyanaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day")), rule=SAT_SUN_TO_NEXT_MON) + + if self._year <= 1969 or self._year >= 2016: + # Independence Day. + self._add_holiday_may_26(tr("Independence Day")) + + if self._year >= 1970: + # Republic Day. + self._add_holiday_feb_23(tr("Republic Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Labour Day"))) + + if self._year >= 2019: + # Arrival Day. + self._add_observed(self._add_holiday_may_5(tr("Arrival Day"))) + + if self._year >= 2016: + # CARICOM Day. + self._add_holiday_1st_mon_of_jul(tr("CARICOM Day")) + + if self._year >= 2016: + # Emancipation Day. + self._add_observed(self._add_holiday_aug_1(tr("Emancipation Day"))) + else: + # Commonwealth Day. + self._add_holiday_1st_mon_of_aug(tr("Commonwealth Day")) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Day after Christmas. + self._add_christmas_day_two(tr("Day after Christmas")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + # Holi. + self._add_observed(self._add_holi(tr("Phagwah"))) + + # Diwali. + self._add_observed(self._add_diwali_india(tr("Deepavali"))) + + # Prophet's Birthday. + for dt in self._add_mawlid_day(tr("Youman Nabi")): + self._add_observed(dt) + + # Eid al-Adha. + for dt in self._add_eid_al_adha_day(tr("Eid-Ul-Azha")): + self._add_observed(dt) + + +class GY(Guyana): + pass + + +class GUY(Guyana): + pass + + +class GuyanaHinduHolidays(_CustomHinduHolidays): + # https://web.archive.org/web/20250428060218/https://www.timeanddate.com/holidays/guyana/deepavali + DIWALI_INDIA_DATES = { + 2016: (OCT, 30), + 2017: (OCT, 19), + 2018: (NOV, 7), + 2019: (OCT, 27), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 24), + 2023: (NOV, 12), + 2024: (OCT, 31), + 2025: (OCT, 20), + } + + # https://web.archive.org/web/20250324205940/https://www.timeanddate.com/holidays/guyana/phagwah + HOLI_DATES = { + 2005: (MAR, 26), + 2006: (MAR, 15), + 2007: (MAR, 4), + 2008: (MAR, 22), + 2009: (MAR, 11), + 2010: (MAR, 1), + 2011: (MAR, 20), + 2012: (MAR, 8), + 2013: (MAR, 27), + 2014: (MAR, 17), + 2015: (MAR, 6), + 2016: (MAR, 23), + 2017: (MAR, 12), + 2018: (MAR, 2), + 2019: (MAR, 21), + 2020: (MAR, 10), + 2021: (MAR, 28), + 2022: (MAR, 18), + 2023: (MAR, 7), + 2024: (MAR, 25), + 2025: (MAR, 14), + 2026: (MAR, 3), + } + + +class GuyanaIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20250424074512/https://www.timeanddate.com/holidays/guyana/eid-al-adha + EID_AL_ADHA_DATES = { + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 21), + 2022: (JUL, 9), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + # https://web.archive.org/web/20241006104125/https://www.timeanddate.com/holidays/guyana/prophet-birthday + MAWLID_DATES = { + 2001: (JUN, 4), + 2002: (MAY, 24), + 2003: (MAY, 14), + 2004: (MAY, 2), + 2005: (APR, 21), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 16), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 9), + 2023: (SEP, 28), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + +class GuyanaStaticHolidays(StaticHolidays): + """Guyana special holidays. + + References: + * [Public Holiday](https://web.archive.org/web/20250207012131/https://officialgazette.gov.gy/images/gazette2020/feb/Extra_27FEBRUARY2020NotPholA.pdf) + """ + + special_public_holidays = { + # Public Holiday. + 2020: (MAR, 2, tr("Public Holiday")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/haiti.py b/.venv/lib/python3.12/site-packages/holidays/countries/haiti.py new file mode 100644 index 00000000..b19bedee --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/haiti.py @@ -0,0 +1,129 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Haiti(HolidayBase, ChristianHolidays, InternationalHolidays): + """Haiti holidays. + + References: + * + * + * + """ + + country = "HT" + supported_categories = (OPTIONAL, PUBLIC) + default_language = "fr_HT" + supported_languages = ("en_US", "es", "fr_HT", "ht") + # 1987 Constitution. + start_year = 1987 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # ARTICLE 275.1 : National Holidays. + # Both Battle of Vertieres Day and Armed Forces Day are on Nov 18, declared discretely. + + # National Independence Day. + self._add_holiday_jan_1(tr("Fête de l'Indépendance Nationale")) + + # Ancestry Day. + self._add_holiday_jan_2(tr("Jour des Aïeux")) + + # Agriculture and Labor Day. + self._add_labor_day(tr("Fête de l'Agriculture et du Travail")) + + # Flag Day and University Day. + self._add_holiday_may_18(tr("Fête du Drapeau et de l'Université")) + + # Commemoration of the Battle of Vertieres. + self._add_holiday_nov_18(tr("Commémoration de la Bataille de Vertières")) + + # Armed Forces Day. + self._add_holiday_nov_18(tr("Jour des Forces Armées")) + + # Other Common Holidays. + + # New Year's Day. + self._add_new_years_day(tr("Nouvel An")) + + # Carnival. + self._add_carnival_sunday(tr("Carnaval")) + + # Shrove Monday. + self._add_carnival_monday(tr("Lundi Gras")) + + # Fat Tuesday. + self._add_carnival_tuesday(tr("Mardi Gras")) + + # Good Friday. + self._add_good_friday(tr("Vendredi Saint")) + + # Easter Sunday. + self._add_easter_sunday(tr("Pâques")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Fête-Dieu")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assomption de Marie")) + + # Death of Dessalines. + self._add_holiday_oct_17(tr("Mort de Dessalines")) + + # All Saints' Day. + self._add_all_saints_day(tr("La Toussaint")) + + # Day of the Dead. + self._add_all_souls_day(tr("Fête des Morts")) + + # Christmas Day. + self._add_christmas_day(tr("Noël")) + + def _populate_optional_holidays(self): + # Ash Wednesday. + self._add_ash_wednesday(tr("Mercredi des Cendres")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jeudi Saint")) + + # National Sovereignty Day. + self._add_holiday_may_23(tr("Fête de la Souveraineté Nationale")) + + # Feast of Lady of Perpetual Help, Patroness of Haiti. + self._add_holiday_jun_27(tr("Fête de Notre-Dame du Perpétuel Secours, patronne d'Haiti")) + + # Ascension Day. + self._add_ascension_thursday(tr("Ascension")) + + # Birth Anniversary of Jean-Jacques Dessalines. + self._add_holiday_sep_20(tr("Anniversaire de Naissance de Jean-Jacques Dessalines")) + + # Discovery Day. + self._add_holiday_dec_5(tr("Jour de la Découverte")) + + +class HT(Haiti): + pass + + +class HTI(Haiti): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/honduras.py b/.venv/lib/python3.12/site-packages/holidays/countries/honduras.py new file mode 100644 index 00000000..974d5ff8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/honduras.py @@ -0,0 +1,85 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Honduras(HolidayBase, ChristianHolidays, InternationalHolidays): + """Honduras holidays. + + References: + * [Art. 339 of Labor Code](https://web.archive.org/web/20240201202118/http://ilo.org/dyn/natlex/docs/WEBTEXT/29076/64849/S59HND01.htm) + * [Decree 78-2015](https://web.archive.org/web/20250414065149/https://www.tsc.gob.hn/web/leyes/Decreto_78-2015_Traslado_de_Feriados_Octubre.pdf) + """ + + country = "HN" + default_language = "es" + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Holy Saturday. + self._add_holy_saturday(tr("Sábado de Gloria")) + + # Panamerican Day. + self._add_holiday_apr_14(tr("Día de las Américas")) + + # Labor Day. + self._add_labor_day(tr("Día del Trabajo")) + + # Independence Day. + self._add_holiday_sep_15(tr("Día de la Independencia")) + + # Decree 78-2015. + if self._year <= 2014: + # Morazan's Day. + self._add_holiday_oct_3(tr("Día de Morazán")) + + # Columbus Day. + self._add_columbus_day(tr("Día de la Raza")) + + # Army Day. + self._add_holiday_oct_21(tr("Día de las Fuerzas Armadas")) + else: + # Morazan Weekend. + name = tr("Semana Morazánica") + # First Wednesday of October from 12 noon to Saturday 12 noon. + self._add_holiday_1st_wed_of_oct(name) + self._add_holiday_1_day_past_1st_wed_of_oct(name) + self._add_holiday_2_days_past_1st_wed_of_oct(name) + + # Christmas Day. + self._add_christmas_day(tr("Navidad")) + + +class HN(Honduras): + pass + + +class HND(Honduras): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/hongkong.py b/.venv/lib/python3.12/site-packages/holidays/countries/hongkong.py new file mode 100644 index 00000000..b14582c5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/hongkong.py @@ -0,0 +1,431 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import ( + JAN, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + DEC, + SUN, + _timedelta, + CHRISTMAS, + WINTER_SOLSTICE, +) +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ( + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + StaticHolidays, +) +from holidays.mixins.preferred_discretionary_holidays import PreferredDiscretionaryHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_WORKDAY, + SUN_TO_NEXT_WORKDAY, + WORKDAY_TO_NEXT_WORKDAY, +) + + +class HongKong( + ObservedHolidayBase, + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + PreferredDiscretionaryHolidays, + StaticHolidays, +): + """Hong Kong holidays. + + References: + * [English Wikipedia](https://en.wikipedia.org/wiki/Public_holidays_in_Hong_Kong) + * [Chinese Wikipedia](https://zh.wikipedia.org/wiki/香港節日與公眾假期) + + Statutory Holidays: + * [Section 39 of Cap. 57 Employment Ordinance](http://archive.today/2025.04.29-125537/https://www.elegislation.gov.hk/hk/cap57!en-zh-Hant-HK?INDEX_CS=N&xpid=ID_1438403463460_002) + * [Holidays for 2010-2025](https://web.archive.org/web/20250402133857/https://www.labour.gov.hk/eng/news/holidays_list.htm) + + General Holidays: + * [Cap. 149 General Holidays Ordinance](http://archive.today/2025.04.29-125900/https://www.elegislation.gov.hk/hk/cap149!en-zh-Hant-HK?INDEX_CS=N) + * [Holidays for 2007-2025](https://web.archive.org/web/20250116080351/https://www.gov.hk/en/about/abouthk/holiday/index.htm) + """ + + country = "HK" + default_language = "zh_HK" + default_preferred_discretionary_holidays = (CHRISTMAS,) + # %s (observed). + observed_label = tr("%s(慶祝)") + supported_categories = (OPTIONAL, PUBLIC) + supported_languages = ("en_HK", "en_US", "th", "zh_CN", "zh_HK") + weekend = {SUN} + # Current set of holidays actually valid since 1946 + start_year = 1946 + + def __init__(self, *args, **kwargs): + ChineseCalendarHolidays.__init__(self) + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + PreferredDiscretionaryHolidays.__init__( + self, kwargs.pop("preferred_discretionary_holidays", None) + ) + StaticHolidays.__init__(self, HongKongStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _add_mid_autumn(self) -> date: + # Mid-Autumn Festival. + + mid_autumn_date = self._mid_autumn_festival + if self._year >= 1968: + mid_autumn_date = _timedelta(mid_autumn_date, +1) + # The Day following Mid-Autumn Festival. + name = tr("中秋節翌日") + # The Second Day following Mid-Autumn Festival. + second_name = tr("中秋節後第二日") + else: + # Mid-Autumn Festival. + name = tr("中秋節") + # The Day following Mid-Autumn Festival. + second_name = tr("中秋節翌日") + + if self._is_sunday(mid_autumn_date): + if 1983 <= self._year <= 2010: + # Mid-Autumn Festival. + self._add_holiday(tr("中秋節"), _timedelta(mid_autumn_date, -1)) + else: + self._add_holiday(second_name, _timedelta(mid_autumn_date, +1)) + else: + self._add_holiday(name, mid_autumn_date) + return mid_autumn_date + + def _add_lunar_new_year(self, day_three_start_year: int): + # Chinese New Year. + name = tr("農曆年初一") + # Chinese New Year's Eve. + preceding_day_lunar = tr("農曆年初一的前一日") + # The second day of Chinese New Year. + second_day_lunar = tr("農曆年初二") + # The third day of Chinese New Year. + third_day_lunar = tr("農曆年初三") + # The fourth day of Chinese New Year. + fourth_day_lunar = tr("農曆年初四") + dt_lunar_new_year = self._chinese_new_year + if self._year >= 1983: + if ( + self._is_friday(dt_lunar_new_year) + or self._is_saturday(dt_lunar_new_year) + or self._is_sunday(dt_lunar_new_year) + ): + if self._year >= 2012: + self._add_chinese_new_years_day_four(fourth_day_lunar) + else: + self._add_chinese_new_years_eve(preceding_day_lunar) + + if not self._is_sunday(dt_lunar_new_year): + self._add_chinese_new_years_day(name) + + if not self._is_saturday(dt_lunar_new_year): + self._add_chinese_new_years_day_two(second_day_lunar) + + if not self._is_friday(dt_lunar_new_year): + self._add_chinese_new_years_day_three(third_day_lunar) + else: + self._add_chinese_new_years_day(name) + self._add_chinese_new_years_day_two(second_day_lunar) + if self._year >= day_three_start_year: + self._add_chinese_new_years_day_three(third_day_lunar) + + def _populate_public_holidays(self): + # Statutory Holidays. + + # Industrial Employment Ordinance implemented in April 1962. + if self._year <= 1962: + return None + + if self._year >= 1977: + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("一月一日"))) + + self._add_lunar_new_year(day_three_start_year=1977) + + if self._year >= 2028: + # Good Friday. + self._add_good_friday(tr("耶穌受難節")) + + if self._year >= 2030: + # The day following Good Friday. + self._add_holy_saturday(tr("耶穌受難節翌日")) + + if self._year >= 2026: + # Easter Monday. + self._add_easter_monday(tr("復活節星期一")) + + # Tomb-Sweeping Day. + self._add_observed(self._add_qingming_festival(tr("清明節"))) + + if self._year >= 2022: + # The Buddha's Birthday. + self._add_observed(self._add_chinese_birthday_of_buddha(tr("佛誕"))) + + if self._year >= 1999: + # Labor Day. + self._add_observed(self._add_labor_day(tr("勞動節"))) + + # Dragon Boat Festival. + self._add_observed(self._add_dragon_boat_festival(tr("端午節"))) + + if self._year >= 1997: + # Hong Kong S.A.R. Establishment Day. + self._add_observed(self._add_holiday_jul_1(tr("香港特別行政區成立紀念日"))) + + mid_autumn_date = self._add_mid_autumn() + + if self._year >= 1977: + # Double Ninth Festival. + dt_double_ninth = self._add_double_ninth_festival(tr("重陽節")) + self._add_observed(dt_double_ninth) + + if self._year >= 1997: + # National Day. + name = tr("國慶日") + oct_1 = self._add_holiday_oct_1(name) + self._add_observed( + oct_1, + name=name, + rule=WORKDAY_TO_NEXT_WORKDAY + SAT_SUN_TO_NEXT_WORKDAY + if oct_1 == mid_autumn_date or oct_1 == dt_double_ninth + else SUN_TO_NEXT_WORKDAY, + ) + + if WINTER_SOLSTICE in self.preferred_discretionary_holidays: + # Winter Solstice. + self._add_observed(self._add_dongzhi_festival(tr("冬節"))) + + if self._year >= 2024: + # The first weekday after Christmas Day. + self._add_observed(self._add_christmas_day_two(tr("聖誕節後第一個周日"))) + + if CHRISTMAS in self.preferred_discretionary_holidays: + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("聖誕節"))) + + def _populate_optional_holidays(self): + # General Holidays. + + if self._is_sunday(JAN, 1): + # The day following New Year's Day. + self._add_new_years_day_two(tr("一月一日翌日")) + else: + # New Year's Day. + self._add_new_years_day(tr("一月一日")) + + self._add_lunar_new_year(day_three_start_year=1968) + + if self._year >= 1968: + dt_qingming = self._qingming_festival + if self._is_sunday(dt_qingming) or dt_qingming == _timedelta(self._easter_sunday, +1): + # The day following Tomb-Sweeping Day. + self._add_holiday(tr("清明節翌日"), _timedelta(dt_qingming, +1)) + else: + # Tomb-Sweeping Day. + self._add_qingming_festival(tr("清明節")) + + # Good Friday. + self._add_good_friday(tr("耶穌受難節")) + + # The day following Good Friday. + self._add_holy_saturday(tr("耶穌受難節翌日")) + + if self._year >= 1968 and dt_qingming == self._easter_sunday: + # The day following Easter Monday. + self._add_easter_tuesday(tr("復活節星期一翌日")) + else: + # Easter Monday. + self._add_easter_monday(tr("復活節星期一")) + + if self._year >= 1999: + dt_birthday_of_buddha = self._chinese_birthday_of_buddha + if self._is_sunday(dt_birthday_of_buddha): + # The day following the Buddha's Birthday. + self._add_holiday(tr("佛誕翌日"), _timedelta(dt_birthday_of_buddha, +1)) + else: + # The Buddha's Birthday. + self._add_chinese_birthday_of_buddha(tr("佛誕")) + + if self._year >= 1999: + if self._is_sunday(MAY, 1): + # The day following Labor Day. + self._add_labor_day_two(tr("勞動節翌日")) + else: + # Labor Day. + self._add_labor_day(tr("勞動節")) + + if self._year >= 1968: + dt_dragon_boat = self._dragon_boat_festival + if self._is_sunday(dt_dragon_boat): + # The day following Dragon Boat Festival. + self._add_holiday(tr("端午節翌日"), _timedelta(dt_dragon_boat, +1)) + else: + # Dragon Boat Festival. + self._add_dragon_boat_festival(tr("端午節")) + + if self._year >= 1997: + if self._is_sunday(JUL, 1): + # The day following Hong Kong S.A.R. Establishment Day. + self._add_holiday_jul_2(tr("香港特別行政區成立紀念日翌日")) + else: + # Hong Kong S.A.R. Establishment Day. + self._add_holiday_jul_1(tr("香港特別行政區成立紀念日")) + + mid_autumn_date = self._add_mid_autumn() + + if self._year >= 1968: + dt_double_ninth = self._double_ninth_festival + if self._is_sunday(dt_double_ninth): + # The day following Double Ninth Festival. + self._add_holiday(tr("重陽節翌日"), _timedelta(dt_double_ninth, +1)) + else: + # Double Ninth Festival. + self._add_double_ninth_festival(tr("重陽節")) + + if self._year >= 1997: + dt = date(self._year, OCT, 1) + # The day following National Day. + name = tr("國慶日翌日") + if self._is_sunday(dt) or dt == mid_autumn_date or dt == dt_double_ninth: + self._add_holiday(name, self._get_next_workday(dt)) + else: + # National Day. + self._add_holiday_oct_1(tr("國慶日")) + + if self._year <= 1998: + self._add_holiday_oct_2(name) + + # Christmas Day. + name = tr("聖誕節") + # The first weekday after Christmas Day. + first_after_christmas = tr("聖誕節後第一個周日") + # The second weekday after Christmas Day. + second_after_christmas = tr("聖誕節後第二個周日") + dt_christmas = self._christmas_day + if self._is_sunday(dt_christmas): + self._add_christmas_day_two(first_after_christmas) + self._add_christmas_day_three(second_after_christmas) + elif self._is_saturday(dt_christmas): + self._add_christmas_day(name) + self._add_christmas_day_three(first_after_christmas) + else: + self._add_christmas_day(name) + self._add_christmas_day_two(first_after_christmas) + + # Previous holidays. + + if 1952 <= self._year <= 1996: + # Queen's Birthday. + name = tr("英女皇壽辰") + if self._year >= 1983: + self._add_holiday_2nd_sat_of_jun(name) + self._add_holiday_2_days_past_2nd_sat_of_jun(name) + else: + if self._year != 1952: + self._add_holiday_apr_21(name) + else: + self._add_holiday_jun_5(name) + + if self._year <= 1967: + # Monday after Pentecost. + self._add_whit_monday(tr("靈降臨節後星期一")) + + # National Day of the Republic of China. + self._add_holiday_2nd_mon_of_oct(tr("中華民國國慶日")) + + # Monday after Remembrance Day. + self._add_holiday_1_day_past_2nd_sun_of_nov(tr("和平紀念日後星期一")) + + if self._year <= 1996: + # Anniversary of the liberation of Hong Kong. + name = tr("重光紀念日") + if self._year >= 1983: + self._add_holiday_last_mon_of_aug(name) + self._add_holiday_2_days_prior_last_mon_of_aug(name) + elif self._year >= 1968: + self._add_holiday_1st_mon_of_aug(name) + self._add_holiday_last_mon_of_aug(name) + else: + self._add_holiday_aug_30(name) + + +class HK(HongKong): + pass + + +class HKG(HongKong): + pass + + +class HongKongStaticHolidays: + # Wedding of Prince Charles and Diana. + wedding_of_charles_and_diana = tr("英國王儲查理斯王子與戴安娜婚禮") + + # Second day of Queen Elizabeth II and her husband's visit to Hong Kong. + queen_visit_hk = tr("英女王伊利沙伯二世伉儷訪港的第二天") + + # Queen's Birthday. + queen_birthday = tr("英女皇壽辰") + + # The day following Hong Kong S.A.R. Establishment Day. + day_following_hksar_establishment_day = tr("香港特別行政區成立紀念日翌日") + + # 70th Anniversary of the Victory of the Chinese People's War of Resistance against + # Japanese Aggression and the World Anti-Fascist War. + victory_70th_anniversary = tr("中國人民抗日戰爭勝利70周年紀念日") + + # Sino-Japanese War Victory Day. + war_victory_day = tr("抗日戰爭勝利紀念日") + + # The day following National Day. + day_following_national_day = tr("國慶日翌日") + + # Additional public holiday. + additional_public_holiday = tr("額外公眾假期") + + special_public_holidays = { + 1981: (JUL, 29, wedding_of_charles_and_diana), + 1986: (OCT, 22, queen_visit_hk), + 1997: (JUL, 2, day_following_hksar_establishment_day), + 2015: (SEP, 3, victory_70th_anniversary), + } + + special_optional_holidays = { + 1981: (JUL, 29, wedding_of_charles_and_diana), + 1986: (OCT, 22, queen_visit_hk), + 1997: ( + (JUN, 28, queen_birthday), + (JUN, 30, queen_birthday), + (JUL, 2, day_following_hksar_establishment_day), + (AUG, 18, war_victory_day), + (OCT, 2, day_following_national_day), + ), + 1998: ( + (AUG, 17, war_victory_day), + (OCT, 2, day_following_national_day), + ), + 1999: (DEC, 31, additional_public_holiday), + 2015: (SEP, 3, victory_70th_anniversary), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/hungary.py b/.venv/lib/python3.12/site-packages/holidays/countries/hungary.py new file mode 100644 index 00000000..34ed0c61 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/hungary.py @@ -0,0 +1,288 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, MAR, APR, MAY, AUG, OCT, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Hungary(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Hungary holidays. + + References: + * + * + * + """ + + country = "HU" + default_language = "hu" + start_year = 1945 + supported_languages = ("en_US", "hu", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, HungaryStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Újév")) + + if self._year <= 1950 or self._year >= 1989: + # National Day. + self._add_holiday_mar_15(tr("Nemzeti ünnep")) + + if self._year >= 2017: + # Good Friday. + self._add_good_friday(tr("Nagypéntek")) + + # Easter. + self._add_easter_sunday(tr("Húsvét")) + + if self._year != 1955: + # Easter Monday. + self._add_easter_monday(tr("Húsvét Hétfő")) + + # Whit Sunday. + self._add_whit_sunday(tr("Pünkösd")) + + if self._year <= 1952 or self._year >= 1992: + # Whit Monday. + self._add_whit_monday(tr("Pünkösdhétfő")) + + if self._year >= 1946: + # Labor Day. + name = tr("A Munka ünnepe") + self._add_labor_day(name) + if 1950 <= self._year <= 1953: + self._add_labor_day_two(name) + + self._add_holiday_aug_20( + # Bread Day. + tr("A kenyér ünnepe") + if 1950 <= self._year <= 1989 + # State Foundation Day. + else tr("Az államalapítás ünnepe") + ) + + if self._year >= 1991: + # National Day. + self._add_holiday_oct_23(tr("Nemzeti ünnep")) + + if self._year >= 1999: + # All Saints' Day. + self._add_all_saints_day(tr("Mindenszentek")) + + # Christmas Day. + self._add_christmas_day(tr("Karácsony")) + + if self._year != 1955: + # Second Day of Christmas. + self._add_christmas_day_two(tr("Karácsony másnapja")) + + # Soviet era. + if 1950 <= self._year <= 1989: + # Proclamation of Soviet Republic Day. + self._add_holiday_mar_21(tr("A Tanácsköztársaság kikiáltásának ünnepe")) + + # Liberation Day. + self._add_holiday_apr_4(tr("A felszabadulás ünnepe")) + + if self._year not in {1956, 1989}: + # Great October Socialist Revolution Day. + self._add_holiday_nov_7(tr("A nagy októberi szocialista forradalom ünnepe")) + + +class HU(Hungary): + pass + + +class HUN(Hungary): + pass + + +class HungaryStaticHolidays: + """Hungary special holidays. + + References: + * [1991](https://archive.org/details/7-1990-xii-27-mum-rendelet) + * [1992](https://web.archive.org/web/20250526085935/https://jogkodex.hu/jsz/1992_3_mum_rendelet_5937748) + * [1993](https://web.archive.org/web/20250526090343/https://jogkodex.hu/jsz/1992_7_mum_rendelet_7815697) + * [1994](https://web.archive.org/web/20250526090541/https://jogkodex.hu/jsz/1993_3_mum_rendelet_3120363) + * [1997](https://web.archive.org/web/20250526090817/https://jogkodex.hu/jsz/1996_11_mum_rendelet_3554324) + * [1998](https://web.archive.org/web/20250526091318/https://jogkodex.hu/jsz/1997_18_mum_rendelet_7493439) + * [1999](https://web.archive.org/web/20250526093916/https://jogkodex.hu/jsz/1998_3_szcsm_rendelet_7336830) + * [2001](https://archive.org/details/43-2000-xii-18-gm-rendelet) + * [2002](https://web.archive.org/web/20250526071659/https://jogkodex.hu/jsz/2001_25_gm_rendelet_9200619) + * [2003](https://web.archive.org/web/20250526071517/https://jogkodex.hu/jsz/2002_2_fmm_rendelet_1831209) + * [2004](https://web.archive.org/web/20250526071310/https://jogkodex.hu/jsz/2003_9_fmm_rendelet_8666269) + * [2005](https://web.archive.org/web/20250526071135/https://jogkodex.hu/jsz/2004_25_fmm_rendelet_4309634) + * [2007](https://web.archive.org/web/20250526064108/https://jogkodex.hu/jsz/2006_4_szmm_rendelet_8628960) + * [2008](https://web.archive.org/web/20250526051643/https://jogkodex.hu/jsz/2007_27_szmm_rendelet_3904252) + * [2009](https://web.archive.org/web/20250526051816/https://jogkodex.hu/jsz/2008_16_szmm_rendelet_7668376) + * [2010](https://web.archive.org/web/20250428204804/https://njt.hu/jogszabaly/2009-20-20-1X) + * [2011](https://web.archive.org/web/20250428204915/https://njt.hu/jogszabaly/2010-7-20-2X) + * [2012](https://web.archive.org/web/20250428204812/https://njt.hu/jogszabaly/2011-39-20-2X) + * [2012-2013](https://web.archive.org/web/20230719163315/https://njt.hu/jogszabaly/2012-28-20-2X) + * [2014](https://web.archive.org/web/20241104082745/https://njt.hu/jogszabaly/2013-33-20-2X) + * [2015](https://web.archive.org/web/20241104081744/https://njt.hu/jogszabaly/2014-28-20-2X) + * [2016](https://web.archive.org/web/20230719163025/https://njt.hu/jogszabaly/2015-18-20-2X) + * [2018](https://web.archive.org/web/20250429080658/https://njt.hu/jogszabaly/2017-61-B0-15) + * [2019](https://web.archive.org/web/20241211095342/https://njt.hu/jogszabaly/2018-6-20-53) + * [2020](https://web.archive.org/web/20241104072826/https://njt.hu/jogszabaly/2019-7-20-53) + * [2021](https://web.archive.org/web/20241102122816/https://njt.hu/jogszabaly/2020-14-20-7Q) + * [2022](https://web.archive.org/web/20241107133627/https://njt.hu/jogszabaly/2021-23-20-7Q) + * [2024](https://web.archive.org/web/20241105131832/https://njt.hu/jogszabaly/2023-15-20-8P) + * [2025](https://web.archive.org/web/20241219165144/https://njt.hu/jogszabaly/2024-11-20-2X) + * [2026](https://web.archive.org/web/20250526083742/https://jogkodex.hu/jsz/2025_10_ngm_rendelet_5591314) + """ + + # Substituted date format. + substituted_date_format = tr("%Y. %m. %d.") + # Day off (substituted from %s). + substituted_label = tr("Pihenőnap (%s-től helyettesítve)") + special_public_holidays = { + 1991: (AUG, 19, AUG, 17), + 1992: ( + (AUG, 21, AUG, 29), + (DEC, 24, DEC, 19), + ), + 1993: (DEC, 24, DEC, 18), + 1994: (MAR, 14, MAR, 12), + 1997: ( + (MAY, 2, APR, 26), + (OCT, 24, OCT, 18), + (DEC, 24, DEC, 20), + ), + 1998: ( + (JAN, 2, JAN, 10), + (AUG, 21, AUG, 15), + (DEC, 24, DEC, 19), + ), + 1999: (DEC, 24, DEC, 18), + 2001: ( + (MAR, 16, MAR, 10), + (APR, 30, APR, 28), + (OCT, 22, OCT, 20), + (NOV, 2, OCT, 27), + (DEC, 24, DEC, 22), + (DEC, 31, DEC, 29), + ), + 2002: ( + (AUG, 19, AUG, 10), + (DEC, 24, DEC, 28), + ), + 2003: ( + (MAY, 2, APR, 26), + (OCT, 24, OCT, 18), + (DEC, 24, DEC, 13), + ), + 2004: ( + (JAN, 2, JAN, 10), + (DEC, 24, DEC, 18), + ), + 2005: ( + (MAR, 14, MAR, 19), + (OCT, 31, NOV, 5), + ), + 2007: ( + (MAR, 16, MAR, 10), + (APR, 30, APR, 21), + (OCT, 22, OCT, 20), + (NOV, 2, OCT, 27), + (DEC, 24, DEC, 22), + (DEC, 31, DEC, 29), + ), + 2008: ( + (MAY, 2, APR, 26), + (OCT, 24, OCT, 18), + (DEC, 24, DEC, 20), + ), + 2009: ( + (JAN, 2, MAR, 28), + (AUG, 21, AUG, 29), + (DEC, 24, DEC, 19), + ), + 2010: (DEC, 24, DEC, 11), + 2011: ( + (MAR, 14, MAR, 19), + (OCT, 31, NOV, 5), + ), + 2012: ( + (MAR, 16, MAR, 24), + (APR, 30, APR, 21), + (OCT, 22, OCT, 27), + (NOV, 2, NOV, 10), + (DEC, 24, DEC, 15), + (DEC, 31, DEC, 1), + ), + 2013: ( + (AUG, 19, AUG, 24), + (DEC, 24, DEC, 7), + (DEC, 27, DEC, 21), + ), + 2014: ( + (MAY, 2, MAY, 10), + (OCT, 24, OCT, 18), + (DEC, 24, DEC, 13), + ), + 2015: ( + (JAN, 2, JAN, 10), + (AUG, 21, AUG, 8), + (DEC, 24, DEC, 12), + ), + 2016: ( + (MAR, 14, MAR, 5), + (OCT, 31, OCT, 15), + ), + 2018: ( + (MAR, 16, MAR, 10), + (APR, 30, APR, 21), + (OCT, 22, OCT, 13), + (NOV, 2, NOV, 10), + (DEC, 24, DEC, 1), + (DEC, 31, DEC, 15), + ), + 2019: ( + (AUG, 19, AUG, 10), + (DEC, 24, DEC, 7), + (DEC, 27, DEC, 14), + ), + 2020: ( + (AUG, 21, AUG, 29), + (DEC, 24, DEC, 12), + ), + 2021: (DEC, 24, DEC, 11), + 2022: ( + (MAR, 14, MAR, 26), + (OCT, 31, OCT, 15), + ), + 2024: ( + (AUG, 19, AUG, 3), + (DEC, 24, DEC, 7), + (DEC, 27, DEC, 14), + ), + 2025: ( + (MAY, 2, MAY, 17), + (OCT, 24, OCT, 18), + (DEC, 24, DEC, 13), + ), + 2026: ( + (JAN, 2, JAN, 10), + (AUG, 21, AUG, 8), + (DEC, 24, DEC, 12), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/iceland.py b/.venv/lib/python3.12/site-packages/holidays/countries/iceland.py new file mode 100644 index 00000000..1c23fc44 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/iceland.py @@ -0,0 +1,98 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import HALF_DAY, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Iceland(HolidayBase, ChristianHolidays, InternationalHolidays): + """Iceland holidays. + + References: + * + * + """ + + country = "IS" + default_language = "is" + supported_categories = (HALF_DAY, PUBLIC) + supported_languages = ("en_US", "is", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nýársdagur")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Skírdagur")) + + # Good Friday. + self._add_good_friday(tr("Föstudagurinn langi")) + + # Easter Sunday. + self._add_easter_sunday(tr("Páskadagur")) + + # Easter Monday. + self._add_easter_monday(tr("Annar í páskum")) + + # First Day of Summer. + self._add_holiday_1st_thu_from_apr_19(tr("Sumardagurinn fyrsti")) + + # Labor Day. + self._add_labor_day(tr("Verkalýðsdagurinn")) + + # Ascension Day. + self._add_ascension_thursday(tr("Uppstigningardagur")) + + # Whit Sunday. + self._add_whit_sunday(tr("Hvítasunnudagur")) + + # Whit Monday. + self._add_whit_monday(tr("Annar í hvítasunnu")) + + # National Day. + self._add_holiday_jun_17(tr("Þjóðhátíðardagurinn")) + + if self._year >= 1983: + # Commerce Day. + self._add_holiday_1st_mon_of_aug(tr("Frídagur verslunarmanna")) + + # Christmas Day. + self._add_christmas_day(tr("Jóladagur")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Annar í jólum")) + + def _populate_half_day_holidays(self): + # %s (from 1pm). + begin_time_label = self.tr("%s (frá kl. 13.00)") + + # Christmas Eve. + self._add_christmas_eve(begin_time_label % self.tr("Aðfangadagur")) + + # New Year's Eve. + self._add_new_years_eve(begin_time_label % self.tr("Gamlársdagur")) + + +class IS(Iceland): + pass + + +class ISL(Iceland): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/india.py b/.venv/lib/python3.12/site-packages/holidays/countries/india.py new file mode 100644 index 00000000..45875d4c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/india.py @@ -0,0 +1,627 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +import warnings +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ( + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, +) +from holidays.holiday_base import HolidayBase + + +class India( + HolidayBase, ChristianHolidays, HinduCalendarHolidays, InternationalHolidays, IslamicHolidays +): + """India holidays. + + References: + * + * + * + * + * + * + * Tamil Nadu: + * [Tamil Monthly Calendar](https://web.archive.org/web/20231228103352/https://www.tamildailycalendar.com/tamil_monthly_calendar.php) + * [Tamil Calendar](https://web.archive.org/web/20250429125140/https://www.prokerala.com/general/calendar/tamilcalendar.php) + """ + + country = "IN" + default_language = "en_IN" + # %s (estimated). + estimated_label = tr("%s (estimated)") + # India gained independence on August 15, 1947. + start_year = 1948 + subdivisions = ( + "AN", # Andaman and Nicobar Islands. + "AP", # Andhra Pradesh. + "AR", # Arunachal Pradesh (Arunāchal Pradesh). + "AS", # Assam. + "BR", # Bihar (Bihār). + "CG", # Chhattisgarh (Chhattīsgarh). + "CH", # Chandigarh (Chandīgarh). + "DH", # Dadra and Nagar Haveli and Daman and Diu(Dādra and Nagar Haveli and Damān and Diu) + "DL", # Delhi. + "GA", # Goa. + "GJ", # Gujarat (Gujarāt). + "HP", # Himachal Pradesh (Himāchal Pradesh). + "HR", # Haryana (Haryāna). + "JH", # Jharkhand (Jhārkhand). + "JK", # Jammu and Kashmir (Jammu and Kashmīr). + "KA", # Karnataka (Karnātaka). + "KL", # Kerala. + "LA", # Ladakh (Ladākh). + "LD", # Lakshadweep. + "MH", # Maharashtra (Mahārāshtra). + "ML", # Meghalaya (Meghālaya). + "MN", # Manipur. + "MP", # Madhya Pradesh. + "MZ", # Mizoram. + "NL", # Nagaland (Nāgāland). + "OD", # Odisha. + "PB", # Punjab. + "PY", # Puducherry. + "RJ", # Rajasthan (Rājasthān). + "SK", # Sikkim. + "TN", # Tamil Nadu (Tamil Nādu). + "TR", # Tripura. + "TS", # Telangana (Telangāna). + "UK", # Uttarakhand (Uttarākhand). + "UP", # Uttar Pradesh. + "WB", # West Bengal. + ) + subdivisions_aliases = { + "Andaman and Nicobar Islands": "AN", + "Andhra Pradesh": "AP", + "Arunachal Pradesh": "AR", + "Arunāchal Pradesh": "AR", + "Assam": "AS", + "Bihar": "BR", + "Bihār": "BR", + "Chhattisgarh": "CG", + "Chhattīsgarh": "CG", + "Chandigarh": "CH", + "Chandīgarh": "CH", + "Dadra and Nagar Haveli and Daman and Diu": "DH", + "Dādra and Nagar Haveli and Damān and Diu": "DH", + "Delhi": "DL", + "Goa": "GA", + "Gujarat": "GJ", + "Gujarāt": "GJ", + "Himachal Pradesh": "HP", + "Himāchal Pradesh": "HP", + "Haryana": "HR", + "Haryāna": "HR", + "Jharkhand": "JH", + "Jhārkhand": "JH", + "Jammu and Kashmir": "JK", + "Jammu and Kashmīr": "JK", + "Karnataka": "KA", + "Karnātaka": "KA", + "Kerala": "KL", + "Ladakh": "LA", + "Ladākh": "LA", + "Lakshadweep": "LD", + "Maharashtra": "MH", + "Mahārāshtra": "MH", + "Meghalaya": "ML", + "Meghālaya": "ML", + "Manipur": "MN", + "Madhya Pradesh": "MP", + "Mizoram": "MZ", + "Nagaland": "NL", + "Nāgāland": "NL", + "Odisha": "OD", + "Punjab": "PB", + "Puducherry": "PY", + "Rajasthan": "RJ", + "Rājasthān": "RJ", + "Sikkim": "SK", + "Tamil Nadu": "TN", + "Tamil Nādu": "TN", + "Tripura": "TR", + "Telangana": "TS", + "Telangāna": "TS", + "Uttarakhand": "UK", + "Uttarākhand": "UK", + "Uttar Pradesh": "UP", + "West Bengal": "WB", + } + supported_categories = (OPTIONAL, PUBLIC) + supported_languages = ("en_IN", "en_US", "hi") + _deprecated_subdivisions = ( + "DD", # Daman and Diu. + "OR", # Orissa. + ) + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=IndiaIslamicHolidays, show_estimated=islamic_show_estimated + ) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year >= 1950: + # Republic Day. + self._add_holiday_jan_26(tr("Republic Day")) + + # Independence Day. + self._add_holiday_aug_15(tr("Independence Day")) + + # Gandhi Jayanti. + self._add_holiday_oct_2(tr("Gandhi Jayanti")) + + # Hindu Holidays. + if self._year < 2001 or self._year > 2035: + warning_msg = "Requested Holidays are available only from 2001 to 2035." + warnings.warn(warning_msg, Warning) + + # Buddha Purnima. + self._add_buddha_purnima(tr("Buddha Purnima")) + + # Diwali. + self._add_diwali_india(tr("Diwali")) + + # Janmashtami. + self._add_janmashtami(tr("Janmashtami")) + + # Dussehra. + self._add_dussehra(tr("Dussehra")) + + # Mahavir Jayanti. + self._add_mahavir_jayanti(tr("Mahavir Jayanti")) + + # Maha Shivaratri. + self._add_maha_shivaratri(tr("Maha Shivaratri")) + + # Guru Nanak Jayanti. + self._add_guru_nanak_jayanti(tr("Guru Nanak Jayanti")) + + # Islamic holidays. + + # Ashura. + self._add_ashura_day(tr("Muharram")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("Milad-un-Nabi")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Id-ul-Fitr")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Bakrid")) + + # Christian holidays. + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Christmas. + self._add_christmas_day(tr("Christmas")) + + if self.subdiv == "OR": + self._populate_subdiv_od_public_holidays() + + def _populate_optional_holidays(self): + # Hindu holidays. + + # Children's Day. + self._add_holiday_nov_14(tr("Children's Day")) + + # Holi. + self._add_holi(tr("Holi")) + + # Ganesh Chaturthi. + self._add_ganesh_chaturthi(tr("Ganesh Chaturthi")) + + # Govardhan Puja. + self._add_govardhan_puja(tr("Govardhan Puja")) + + # Labor Day. + self._add_labor_day(tr("Labour Day")) + + # Maha Navami. + self._add_maha_navami(tr("Maha Navami")) + + # Makar Sankranti. + self._add_makar_sankranti(tr("Makar Sankranti")) + + # Raksha Bandhan. + self._add_raksha_bandhan(tr("Raksha Bandhan")) + + # Ram Navami. + self._add_ram_navami(tr("Ram Navami")) + + # Navratri / Sharad Navratri. + self._add_sharad_navratri(tr("Navratri / Sharad Navratri")) + + # Christian holidays. + + # Easter Sunday. + self._add_easter_sunday(tr("Easter Sunday")) + + # Palm Sunday. + self._add_palm_sunday(tr("Palm Sunday")) + + # Andaman and Nicobar Islands. + def _populate_subdiv_an_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + + # Andhra Pradesh. + def _populate_subdiv_ap_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Andhra Pradesh Foundation Day. + self._add_holiday_nov_1(tr("Andhra Pradesh Foundation Day")) + + # Assam. + def _populate_subdiv_as_public_holidays(self): + # Magh Bihu. + self._add_makar_sankranti(tr("Magh Bihu")) + # Assam Day. + self._add_holiday_dec_2(tr("Assam Day")) + + # Bihar. + def _populate_subdiv_br_public_holidays(self): + # Chhath Puja. + self._add_chhath_puja(tr("Chhath Puja")) + # Bihar Day. + self._add_holiday_mar_22(tr("Bihar Day")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + + # Chandigarh. + def _populate_subdiv_ch_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + + # Chhattisgarh. + def _populate_subdiv_cg_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Chhattisgarh Foundation Day. + self._add_holiday_nov_1(tr("Chhattisgarh Foundation Day")) + + # Delhi. + def _populate_subdiv_dl_public_holidays(self): + # Chhath Puja. + self._add_chhath_puja(tr("Chhath Puja")) + + # Goa. + def _populate_subdiv_ga_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Goa Liberation Day. + self._add_holiday_dec_19(tr("Goa Liberation Day")) + + # Gujarat. + def _populate_subdiv_gj_public_holidays(self): + # Makar Sankranti. + self._add_makar_sankranti(tr("Uttarayan")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Gujarat Day. + self._add_holiday_may_1(tr("Gujarat Day")) + # Sardar Vallabhbhai Patel Jayanti. + self._add_holiday_oct_31(tr("Sardar Vallabhbhai Patel Jayanti")) + + # Haryana. + def _populate_subdiv_hr_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Haryana Foundation Day. + self._add_holiday_nov_1(tr("Haryana Foundation Day")) + + # Himachal Pradesh. + def _populate_subdiv_hp_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Himachal Day. + self._add_holiday_apr_15(tr("Himachal Day")) + + # Jammu and Kashmir + def _populate_subdiv_jk_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + + # Jharkhand. + def _populate_subdiv_jh_public_holidays(self): + # Chhath Puja. + self._add_chhath_puja(tr("Chhath Puja")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Jharkhand Formation Day. + self._add_holiday_nov_15(tr("Jharkhand Formation Day")) + + # Karnataka. + def _populate_subdiv_ka_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Karnataka Rajyotsav. + self._add_holiday_nov_1(tr("Karnataka Rajyotsava")) + + # Kerala. + def _populate_subdiv_kl_public_holidays(self): + # Onam. + self._add_onam(tr("Onam")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Kerala Foundation Day. + self._add_holiday_nov_1(tr("Kerala Foundation Day")) + + # Ladakh. + def _populate_subdiv_la_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + + # Maharashtra. + def _populate_subdiv_mh_public_holidays(self): + # Gudi Padwa. + self._add_gudi_padwa(tr("Gudi Padwa")) + # Chhatrapati Shivaji Maharaj Jayanti. + self._add_holiday_feb_19(tr("Chhatrapati Shivaji Maharaj Jayanti")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Maharashtra Day. + self._add_holiday_may_1(tr("Maharashtra Day")) + + # Madhya Pradesh. + def _populate_subdiv_mp_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Madhya Pradesh Foundation Day. + self._add_holiday_nov_1(tr("Madhya Pradesh Foundation Day")) + + # Mizoram. + def _populate_subdiv_mz_public_holidays(self): + # Mizoram State Day. + self._add_holiday_feb_20(tr("Mizoram State Day")) + + # Nagaland. + def _populate_subdiv_nl_public_holidays(self): + # Nagaland State Inauguration Day. + self._add_holiday_dec_1(tr("Nagaland State Inauguration Day")) + + # Orissa / Odisha. + def _populate_subdiv_od_public_holidays(self): + # Odisha Day. + self._add_holiday_apr_1(tr("Odisha Day (Utkala Dibasa)")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Maha Vishuva Sankranti. + self._add_holiday_apr_15(tr("Maha Vishuva Sankranti / Pana Sankranti")) + + # Puducherry. + def _populate_subdiv_py_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Puducherry De Jure Transfer Day. + self._add_holiday_aug_16(tr("Puducherry De Jure Transfer Day")) + # Puducherry Liberation Day. + self._add_holiday_nov_1(tr("Puducherry Liberation Day")) + + # Punjab. + def _populate_subdiv_pb_public_holidays(self): + # Guru Gobind Singh Jayanti. + self._add_guru_gobind_singh_jayanti(tr("Guru Gobind Singh Jayanti")) + # Vaisakhi. + self._add_vaisakhi(tr("Vaisakhi")) + # Lohri. + self._add_holiday_jan_13(tr("Lohri")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Punjabi Day. + self._add_holiday_nov_1(tr("Punjab Day")) + + # Rajasthan. + def _populate_subdiv_rj_public_holidays(self): + # Rajasthan Day. + self._add_holiday_mar_30(tr("Rajasthan Day")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Maharana Pratap Jayanti. + self._add_holiday_jun_15(tr("Maharana Pratap Jayanti")) + + # Sikkim. + def _populate_subdiv_sk_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Sikkim State Day. + self._add_holiday_may_16(tr("Sikkim State Day")) + + # Tamil Nadu. + def _populate_subdiv_tn_public_holidays(self): + # Pongal. + self._add_pongal(tr("Pongal")) + # Thiruvalluvar Day / Mattu Pongal. + self._add_thiruvalluvar_day(tr("Thiruvalluvar Day / Mattu Pongal")) + # Uzhavar Thirunal. + self._add_uzhavar_thirunal(tr("Uzhavar Thirunal")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Puthandu. + self._add_holiday_apr_14(tr("Puthandu (Tamil New Year)")) + + # Telangana. + def _populate_subdiv_ts_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Telangana Formation Day. + self._add_holiday_jun_2(tr("Telangana Formation Day")) + # Bathukamma Festival. + self._add_holiday_oct_6(tr("Bathukamma Festival")) + + # Uttarakhand. + def _populate_subdiv_uk_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + + # Uttar Pradesh. + def _populate_subdiv_up_public_holidays(self): + # Chhath Puja. + self._add_chhath_puja(tr("Chhath Puja")) + # UP Formation Day. + self._add_holiday_jan_24(tr("UP Formation Day")) + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + + # West Bengal. + def _populate_subdiv_wb_public_holidays(self): + # Dr. B. R. Ambedkar Jayanti. + self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) + # Pohela Boisakh. + self._add_holiday_apr_15(tr("Pohela Boishakh")) + # Rabindra Jayanti. + self._add_holiday_may_9(tr("Rabindra Jayanti")) + + +class IndiaIslamicHolidays(_CustomIslamicHolidays): + # Muharram / Day of Ashura. + ASHURA_DATES = { + 2001: (APR, 4), + 2002: (MAR, 24), + 2003: (MAR, 14), + 2004: (MAR, 2), + 2005: (FEB, 19), + 2006: (FEB, 9), + 2007: (JAN, 30), + 2008: (JAN, 19), + 2009: ((JAN, 7), (DEC, 28)), + 2010: (DEC, 17), + 2011: (DEC, 6), + 2012: (NOV, 25), + 2013: (NOV, 14), + 2014: (NOV, 4), + 2015: (OCT, 24), + 2016: (OCT, 12), + 2017: (OCT, 1), + 2018: (SEP, 21), + 2019: (SEP, 10), + 2020: (AUG, 30), + 2021: (AUG, 20), + 2022: (AUG, 9), + 2023: (JUL, 29), + 2024: (JUL, 17), + 2025: (JUL, 6), + } + + # Bakrid / Eid-al-Adha. + EID_AL_ADHA_DATES = { + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 11), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 27), + 2013: (OCT, 16), + 2014: (OCT, 6), + 2015: (SEP, 25), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (AUG, 1), + 2021: (JUL, 21), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + # Id-ul-Fitr / Eid-al-Fitr. + EID_AL_FITR_DATES = { + 2001: (DEC, 17), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 3), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 20), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 16), + 2019: (JUN, 5), + 2020: (MAY, 25), + 2021: (MAY, 14), + 2022: (MAY, 3), + 2023: (APR, 22), + 2024: (APR, 11), + 2025: (MAR, 31), + } + + # Milad-un-Nabi / Mawlid. + MAWLID_DATES = { + 2001: (JUN, 5), + 2002: (MAY, 25), + 2003: (MAY, 15), + 2004: (MAY, 3), + 2005: (APR, 22), + 2006: (APR, 11), + 2007: (APR, 1), + 2008: (MAR, 21), + 2009: (MAR, 9), + 2010: (FEB, 27), + 2011: (FEB, 16), + 2012: (FEB, 5), + 2013: (JAN, 25), + 2014: (JAN, 14), + 2015: ((JAN, 4), (DEC, 25)), + 2016: (DEC, 13), + 2017: (DEC, 2), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 30), + 2021: (OCT, 19), + 2022: (OCT, 9), + 2023: (SEP, 28), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + +class IN(India): + pass + + +class IND(India): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/indonesia.py b/.venv/lib/python3.12/site-packages/holidays/countries/indonesia.py new file mode 100644 index 00000000..2b9e556c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/indonesia.py @@ -0,0 +1,885 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import ( + _CustomBuddhistHolidays, + _CustomChineseHolidays, + _CustomIslamicHolidays, +) +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import GOVERNMENT, PUBLIC +from holidays.groups import ( + BalineseSakaCalendarHolidays, + BuddhistCalendarHolidays, + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase + + +class Indonesia( + ObservedHolidayBase, + BalineseSakaCalendarHolidays, + BuddhistCalendarHolidays, + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Indonesia holidays. + + References: + * + * + * + * [1963-2025](https://id.wikipedia.org/wiki/Indonesia_dalam_tahun_1963) + * + """ + + country = "ID" + default_language = "id" + # %s (estimated). + estimated_label = tr("%s (perkiraan)") + # %s (observed). + observed_label = tr("Pegangti %s") + # %s (observed, estimated). + observed_estimated_label = tr("Pegangti %s (perkiraan)") + supported_languages = ("en_US", "id", "th", "uk") + supported_categories = (GOVERNMENT, PUBLIC) + start_year = 1946 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + BalineseSakaCalendarHolidays.__init__(self) + BuddhistCalendarHolidays.__init__(self, cls=IndonesiaBuddhistHolidays, show_estimated=True) + ChineseCalendarHolidays.__init__(self, cls=IndonesiaChineseHolidays, show_estimated=True) + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=IndonesiaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=IndonesiaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Tahun Baru Masehi")) + + # Independence Day. + self._add_holiday_aug_17(tr("Hari Kemerdekaan Republik Indonesia")) + + # Keputusan Presiden no 24 tahun 1953. (1953-01-01; Removed) + if self._year <= 1952: + # Armed Forces Day. + self._add_holiday_oct_5(tr("Hari Angkatan Perang")) + + # Heroes' Day. + self._add_holiday_nov_10(tr("Hari Pahlawan")) + + # Keputusan Presiden no 24 tahun 1953. (1953-01-01; Added Nationally) + if self._year >= 1953: + # Christmas Day. + self._add_christmas_day(tr("Hari Raya Natal")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Hari Raya Idul Fitri")) + + # Eid al-Fitr Second Day. + self._add_eid_al_fitr_day_two(tr("Hari kedua dari Hari Raya Idul Fitri")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Hari Raya Idul Adha")) + + # Keputusan Presiden no 24 tahun 1953. (1953-01-01; Added Nationally) + # Keputusan Presiden no 21 tahun 1963. (1963-10-15; Moved to Denominative-based) + # Keputusan Presiden no 251 tahun 1967. (1967-12-16; Removed) + if 1953 <= self._year <= 1963: + # Easter Monday. + self._add_easter_monday(tr("Hari kedua Paskah")) + + # Whit Monday. + self._add_whit_monday(tr("Hari kedua Pentakosta")) + + # Nuzul Al Quran. + self._add_nuzul_al_quran_day(tr("Nuzululqur'an")) + + # Keputusan Presiden no 24 tahun 1953. (1953-01-01; Added Nationally) + # Keputusan Presiden no 21 tahun 1963. (1963-10-15; Moved to Denominative-based) + # Keputusan Presiden no 251 tahun 1967. (1967-12-16; Added Nationally) + if 1953 <= self._year <= 1962 or self._year >= 1968: + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("Isra Mikraj Nabi Muhammad")) + + # (Same as above, was before 1963 cut-off date) + if 1953 <= self._year <= 1963 or self._year >= 1968: + # Ascension Day. + self._add_ascension_thursday(tr("Kenaikan Yesus Kristus")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("Tahun Baru Islam")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("Maulid Nabi Muhammad")) + + # Keputusan Presiden no 21 tahun 1963. (1963-10-15; Added Denominative-based) + # Keputusan Presiden no 251 tahun 1967. (1967-12-16; Added Nationally) + # Keputusan Presiden no 10 tahun 1971. (1971-03-15; Removed) + if 1968 <= self._year <= 1970: + # Assumption Day. + self._add_assumption_of_mary_day(tr("Mikraj Santa Maria")) + + # Keputusan Presiden no 24 tahun 1953. (1953-01-01; Added Nationally) + # Keputusan Presiden no 21 tahun 1963. (1963-10-15; Moved to Denominative-based) + # Keputusan Presiden no 251 tahun 1967. (1967-12-16; Removed) + # Keputusan Presiden no 10 tahun 1971. (1971-03-15; Added Nationally) + if 1953 <= self._year <= 1963 or self._year >= 1971: + # Good Friday. + self._add_good_friday(tr("Wafat Yesus Kristus")) + + # Keputusan Presiden no 3 tahun 1983. (1983-01-19; Added Nationally) + if self._year >= 1983: + # Day of Silence. + self._add_nyepi(tr("Hari Suci Nyepi")) + + # Vesak Day. + self._add_vesak(tr("Hari Raya Waisak")) + + # Keputusan Presiden no 19 tahun 2002. (2002-04-09; Added Nationally) + if self._year >= 2003: + # Lunar New Year. + self._add_chinese_new_years_day(tr("Tahun Baru Imlek")) + + # Keputusan Presiden no 24 tahun 1953. (1953-01-01; Added Nationally) + # Keputusan Presiden no 148 tahun 1968. (1968-04-18; Removed) + # Keputusan Presiden no 24 tahun 2013. (2013-07-29; Added Nationally) + if 1953 <= self._year <= 1967 or self._year >= 2014: + # International Labor Day. + self._add_labor_day(tr("Hari Buruh Internasional")) + + # Keputusan Presiden no 24 tahun 2016. (2016-06-01; Added Nationally) + if self._year >= 2016: + # Pancasila Day. + self._add_holiday_jun_1(tr("Hari Lahir Pancasila")) + + # Keputusan Presiden no 8 tahun 2024. (2024-01-29; Added Nationally) + # This KEPPRES overwrites all pre-existing ones. + if self._year >= 2024: + # Easter Sunday. + self._add_easter_sunday(tr("Kebangkitan Yesus Kristus")) + + +class ID(Indonesia): + pass + + +class IDN(Indonesia): + pass + + +class IndonesiaBuddhistHolidays(_CustomBuddhistHolidays): + VESAK_DATES = { + 1983: (MAY, 27), + 1984: (MAY, 14), + 1985: (JUN, 3), + 1986: (MAY, 24), + 1987: (MAY, 13), + 1988: (MAY, 31), + 1989: (MAY, 21), + 1990: (MAY, 10), + 1991: (MAY, 28), + 1992: (MAY, 16), + 1993: (MAY, 6), + 1994: (MAY, 25), + 1995: (MAY, 15), + 1996: (JUN, 2), + 1997: (MAY, 22), + 1998: (MAY, 11), + 1999: (MAY, 30), + 2000: (MAY, 18), + 2001: (MAY, 7), + 2002: (MAY, 26), + 2003: (MAY, 16), + 2004: (JUN, 3), + 2005: (MAY, 24), + 2006: (MAY, 13), + 2007: (JUN, 1), + 2008: (MAY, 20), + 2009: (MAY, 9), + 2010: (MAY, 28), + 2011: (MAY, 17), + 2012: (MAY, 6), + 2013: (MAY, 25), + 2014: (MAY, 15), + 2015: (JUN, 2), + 2016: (MAY, 22), + 2017: (MAY, 11), + 2018: (MAY, 29), + 2019: (MAY, 19), + 2020: (MAY, 7), + 2021: (MAY, 26), + 2022: (MAY, 16), + 2023: (JUN, 4), + 2024: (MAY, 23), + 2025: (MAY, 12), + } + + +class IndonesiaChineseHolidays(_CustomChineseHolidays): + LUNAR_NEW_YEAR_DATES = { + 2003: (FEB, 1), + 2004: (JAN, 22), + 2005: (FEB, 9), + 2006: (JAN, 30), + 2007: (FEB, 19), + 2008: (FEB, 7), + 2009: (JAN, 26), + 2010: (FEB, 15), + 2011: (FEB, 3), + 2012: (JAN, 23), + 2013: (FEB, 11), + 2014: (JAN, 31), + 2015: (FEB, 19), + 2016: (FEB, 8), + 2017: (JAN, 28), + 2018: (FEB, 16), + 2019: (FEB, 5), + 2020: (JAN, 25), + 2021: (FEB, 12), + 2022: (FEB, 1), + 2023: (JAN, 22), + 2024: (FEB, 10), + 2025: (JAN, 29), + } + + +class IndonesiaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 1963: (MAY, 4), + 1964: (APR, 23), + 1965: (APR, 12), + 1966: (APR, 2), + 1967: (MAR, 22), + 1968: (MAR, 9), + 1969: (FEB, 27), + 1970: (FEB, 17), + 1971: (FEB, 6), + 1972: (JAN, 27), + 1973: (JAN, 15), + 1974: ((JAN, 4), (DEC, 24)), + 1975: (DEC, 13), + 1976: (DEC, 2), + 1977: (NOV, 21), + 1978: (NOV, 11), + 1979: (OCT, 31), + 1980: (OCT, 19), + 1981: (OCT, 8), + 1982: (SEP, 28), + 1983: (SEP, 17), + 1984: (SEP, 6), + 1985: (AUG, 26), + 1986: (AUG, 16), + 1987: (AUG, 5), + 1988: (JUL, 24), + 1989: (JUL, 13), + 1990: (JUL, 3), + 1991: (JUN, 23), + 1992: (JUN, 11), + 1993: (JUN, 1), + 1994: (MAY, 21), + 1995: (MAY, 10), + 1996: (APR, 28), + 1997: (APR, 18), + 1998: (APR, 7), + 1999: (MAR, 28), + 2000: (MAR, 16), + 2001: (MAR, 5), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 27), + 2010: (NOV, 17), + 2011: (NOV, 6), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 1963: (FEB, 25), + 1964: (FEB, 15), + 1965: (FEB, 3), + 1966: (JAN, 23), + 1967: (JAN, 12), + 1968: ((JAN, 2), (DEC, 21)), + 1969: (DEC, 11), + 1970: (NOV, 30), + 1971: (NOV, 19), + 1972: (NOV, 7), + 1973: (OCT, 27), + 1974: (OCT, 17), + 1975: (OCT, 6), + 1976: (SEP, 25), + 1977: (SEP, 15), + 1978: (SEP, 4), + 1979: (AUG, 24), + 1980: (AUG, 12), + 1981: (AUG, 1), + 1982: (JUL, 22), + 1983: (JUL, 12), + 1984: (JUN, 30), + 1985: (JUN, 20), + 1986: (JUN, 9), + 1987: (MAY, 29), + 1988: (MAY, 17), + 1989: (MAY, 7), + 1990: (APR, 26), + 1991: (APR, 16), + 1992: (APR, 5), + 1993: (MAR, 25), + 1994: (MAR, 14), + 1995: (MAR, 3), + 1996: (FEB, 20), + 1997: (FEB, 9), + 1998: (JAN, 30), + 1999: (JAN, 19), + 2000: ((JAN, 8), (DEC, 27)), + 2001: (DEC, 16), + 2002: (DEC, 6), + 2003: (NOV, 25), + 2004: (NOV, 14), + 2005: (NOV, 3), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 1), + 2009: (SEP, 20), + 2010: (SEP, 10), + 2011: (AUG, 30), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 6), + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + HIJRI_NEW_YEAR_DATES = { + 1968: (MAR, 30), + 1969: (MAR, 19), + 1970: (MAR, 10), + 1971: (FEB, 27), + 1972: (FEB, 16), + 1973: (FEB, 5), + 1974: (JAN, 25), + 1975: (JAN, 14), + 1976: ((JAN, 3), (DEC, 22)), + 1977: (DEC, 12), + 1978: (DEC, 1), + 1979: (NOV, 21), + 1980: (NOV, 9), + 1981: (OCT, 29), + 1982: (OCT, 18), + 1983: (OCT, 8), + 1984: (SEP, 26), + 1985: (SEP, 16), + 1986: (SEP, 5), + 1987: (AUG, 26), + 1988: (AUG, 14), + 1989: (AUG, 3), + 1990: (JUL, 23), + 1991: (JUL, 13), + 1992: (JUL, 2), + 1993: (JUN, 21), + 1994: (JUN, 11), + 1995: (MAY, 31), + 1996: (MAY, 19), + 1997: (MAY, 8), + 1998: (APR, 28), + 1999: (APR, 17), + 2000: (APR, 6), + 2001: (MAR, 26), + 2002: (MAR, 15), + 2003: (MAR, 3), + 2004: (FEB, 23), + 2005: (FEB, 10), + 2006: (JAN, 31), + 2007: (JAN, 20), + 2008: ((JAN, 10), (DEC, 29)), + 2009: (DEC, 18), + 2010: (DEC, 7), + 2011: (NOV, 27), + 2012: (NOV, 15), + 2013: (NOV, 5), + 2014: (OCT, 25), + 2015: (OCT, 14), + 2016: (OCT, 2), + 2017: (SEP, 21), + 2018: (SEP, 11), + 2019: (SEP, 1), + 2020: (AUG, 20), + 2021: (AUG, 11), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 7), + 2025: (JUN, 27), + } + + ISRA_AND_MIRAJ_DATES = { + 1968: (OCT, 20), + 1969: (OCT, 9), + 1970: (SEP, 29), + 1971: (SEP, 17), + 1972: (SEP, 6), + 1973: (AUG, 26), + 1974: (AUG, 16), + 1975: (AUG, 5), + 1976: (JUL, 25), + 1977: (JUL, 14), + 1978: (JUL, 3), + 1979: (JUN, 22), + 1980: (JUN, 11), + 1981: (MAY, 31), + 1982: (MAY, 21), + 1983: (MAY, 10), + 1984: (APR, 29), + 1985: (APR, 18), + 1986: (APR, 7), + 1987: (MAR, 27), + 1988: (MAR, 16), + 1989: (MAR, 5), + 1990: (FEB, 23), + 1991: (FEB, 12), + 1992: (FEB, 1), + 1993: (JAN, 20), + 1994: ((JAN, 10), (DEC, 30)), + 1995: (DEC, 20), + 1996: (DEC, 8), + 1997: (NOV, 28), + 1998: (NOV, 17), + 1999: (NOV, 6), + 2000: (OCT, 25), + 2001: (OCT, 15), + 2002: (OCT, 4), + 2003: (SEP, 22), + 2004: (SEP, 13), + 2005: (SEP, 2), + 2006: (AUG, 21), + 2007: (AUG, 11), + 2008: (JUL, 30), + 2009: (JUL, 20), + 2010: (JUL, 10), + 2011: (JUN, 29), + 2012: (JUN, 17), + 2013: (JUN, 6), + 2014: (MAY, 27), + 2015: (MAY, 16), + 2016: (MAY, 6), + 2017: (APR, 24), + 2018: (APR, 14), + 2019: (APR, 3), + 2020: (MAR, 22), + 2021: (MAR, 11), + 2022: (FEB, 28), + 2023: (FEB, 18), + 2024: (FEB, 8), + 2025: (JAN, 27), + } + + MAWLID_DATES = { + 1968: (JUN, 8), + 1969: (MAY, 28), + 1970: (MAY, 18), + 1971: (MAY, 7), + 1972: (APR, 26), + 1973: (APR, 14), + 1974: (APR, 5), + 1975: (MAR, 25), + 1976: (MAR, 13), + 1977: (MAR, 2), + 1978: (FEB, 20), + 1979: (FEB, 9), + 1980: (JAN, 30), + 1981: (JAN, 18), + 1982: ((JAN, 8), (DEC, 28)), + 1983: (DEC, 17), + 1984: (DEC, 5), + 1985: (NOV, 25), + 1986: (NOV, 14), + 1987: (NOV, 4), + 1988: (OCT, 23), + 1989: (OCT, 12), + 1990: (OCT, 1), + 1991: (SEP, 21), + 1992: (SEP, 9), + 1993: (AUG, 30), + 1994: (AUG, 20), + 1995: (AUG, 9), + 1996: (JUL, 28), + 1997: (JUL, 17), + 1998: (JUL, 6), + 1999: (JUN, 26), + 2000: (JUN, 15), + 2001: (JUN, 4), + 2002: (MAY, 25), + 2003: (MAY, 15), + 2004: (MAY, 3), + 2005: (APR, 22), + 2006: (APR, 10), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 15), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 20), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 20), + 2022: (OCT, 8), + 2023: (SEP, 28), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + +class IndonesiaStaticHolidays: + """Indonesia special holidays. + + References (Election Days): + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + + References (Joint Holidays): + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + """ + + # General Election Day. + general_election_day = tr("Hari Pemilihan Unum") + # Presidential Election Day. + presidential_election_day = tr("Hari Pemilihan Presiden") + # Legislative Election Day. + legislative_election_day = tr("Hari Pemilihan Legislatif") + # Local Election Day. + local_election_day = tr("Hari Pemilihan Kepala Daerah") + + # Eid al-Fitr Joint Holiday. + eid_al_fitr_joint_holiday = tr("Cuti Bersama Hari Raya Idul Fitri") + # Eid al-Adha Joint Holiday. + eid_al_adha_joint_holiday = tr("Cuti Bersama Hari Raya Idul Adha") + # Prophet's Birthday Joint Holiday. + mawlid_joint_holiday = tr("Cuti Bersama Maulid Nabi Muhammad") + # Islamic New Year Joint Holiday. + islamic_new_year_joint_holiday = tr("Cuti Bersama Tahun Baru Islam") + # Ascension Joint Holiday. + ascension_joint_holiday = tr("Cuti Bersama Kenaikan Yesus Kristus") + # Christmas Joint Holiday. + christmas_joint_holiday = tr("Cuti Bersama Hari Raya Natal") + # Lunar New Year Joint Holiday. + lunar_new_year_joint_holiday = tr("Cuti Bersama Tahun Baru Imlek") + # Day of Silence Joint Holiday. + day_of_silence_joint_holiday = tr("Cuti Bersama Hari Suci Nyepi") + # Vesak Joint Holiday. + vesak_joint_holiday = tr("Cuti Bersama Hari Raya Waisak") + # New Year's Joint Holiday. + new_years_joint_holiday = tr("Cuti Bersama Tahun Baru Masehi") + + special_public_holidays = { + 1999: (JUN, 7, legislative_election_day), + 2004: ( + (APR, 5, legislative_election_day), + (JUL, 5, presidential_election_day), + (SEP, 20, presidential_election_day), + ), + 2009: ( + (APR, 9, legislative_election_day), + (JUL, 8, presidential_election_day), + ), + 2014: ( + (APR, 9, legislative_election_day), + (JUL, 9, presidential_election_day), + ), + 2015: (DEC, 9, local_election_day), + 2017: (FEB, 15, local_election_day), + 2018: (JUN, 27, local_election_day), + 2019: (APR, 17, general_election_day), + 2020: (DEC, 9, local_election_day), + 2024: ( + (FEB, 14, general_election_day), + (NOV, 27, local_election_day), + ), + } + special_public_holidays_observed = { + # Eid al-Fitr. + 2004: (NOV, 16, tr("Hari Raya Idul Fitri")), + } + special_government_holidays = { + # Cuti Bersama (Joint Holidays/Collective Leaves). + # This was first implemented in 2002. + 2002: ( + (DEC, 5, eid_al_fitr_joint_holiday), + (DEC, 9, eid_al_fitr_joint_holiday), + (DEC, 10, eid_al_fitr_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2003: ( + (NOV, 24, eid_al_fitr_joint_holiday), + (NOV, 27, eid_al_fitr_joint_holiday), + (NOV, 28, eid_al_fitr_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2004: ( + (NOV, 17, eid_al_fitr_joint_holiday), + (NOV, 18, eid_al_fitr_joint_holiday), + (NOV, 19, eid_al_fitr_joint_holiday), + ), + 2005: ( + (NOV, 2, eid_al_fitr_joint_holiday), + (NOV, 5, eid_al_fitr_joint_holiday), + (NOV, 7, eid_al_fitr_joint_holiday), + (NOV, 8, eid_al_fitr_joint_holiday), + ), + 2006: ( + (MAR, 31, day_of_silence_joint_holiday), + (MAY, 26, ascension_joint_holiday), + # Independence Day Joint Holiday. + (AUG, 18, tr("Cuti Bersama Hari Kemerdekaan Republik Indonesia")), + (OCT, 23, eid_al_fitr_joint_holiday), + (OCT, 26, eid_al_fitr_joint_holiday), + (OCT, 27, eid_al_fitr_joint_holiday), + ), + 2007: ( + (MAY, 18, ascension_joint_holiday), + (OCT, 12, eid_al_fitr_joint_holiday), + (OCT, 15, eid_al_fitr_joint_holiday), + (OCT, 16, eid_al_fitr_joint_holiday), + (OCT, 17, eid_al_fitr_joint_holiday), + (OCT, 18, eid_al_fitr_joint_holiday), + (OCT, 19, eid_al_fitr_joint_holiday), + (DEC, 21, christmas_joint_holiday), + (DEC, 24, christmas_joint_holiday), + (DEC, 26, christmas_joint_holiday), + (DEC, 31, new_years_joint_holiday), + ), + 2008: ( + (JAN, 11, islamic_new_year_joint_holiday), + (SEP, 29, eid_al_fitr_joint_holiday), + (SEP, 30, eid_al_fitr_joint_holiday), + (OCT, 3, eid_al_fitr_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2009: ( + (JAN, 2, new_years_joint_holiday), + (SEP, 18, eid_al_fitr_joint_holiday), + (SEP, 23, eid_al_fitr_joint_holiday), + (DEC, 24, christmas_joint_holiday), + ), + 2010: ( + (SEP, 9, eid_al_fitr_joint_holiday), + (SEP, 13, eid_al_fitr_joint_holiday), + (DEC, 24, christmas_joint_holiday), + ), + 2011: ( + (MAY, 16, vesak_joint_holiday), + (AUG, 29, eid_al_fitr_joint_holiday), + (SEP, 1, eid_al_fitr_joint_holiday), + (SEP, 2, eid_al_fitr_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2012: ( + (MAY, 18, ascension_joint_holiday), + (AUG, 21, eid_al_fitr_joint_holiday), + (AUG, 22, eid_al_fitr_joint_holiday), + (NOV, 16, islamic_new_year_joint_holiday), + (DEC, 24, christmas_joint_holiday), + (DEC, 31, new_years_joint_holiday), + ), + 2013: ( + (AUG, 5, eid_al_fitr_joint_holiday), + (AUG, 6, eid_al_fitr_joint_holiday), + (AUG, 7, eid_al_fitr_joint_holiday), + (OCT, 14, eid_al_adha_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2014: ( + (JUL, 30, eid_al_fitr_joint_holiday), + (JUL, 31, eid_al_fitr_joint_holiday), + (AUG, 1, eid_al_fitr_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2015: ( + (JUL, 16, eid_al_fitr_joint_holiday), + (JUL, 20, eid_al_fitr_joint_holiday), + (JUL, 21, eid_al_fitr_joint_holiday), + ), + 2016: ( + (JUL, 4, eid_al_fitr_joint_holiday), + (JUL, 5, eid_al_fitr_joint_holiday), + (JUL, 8, eid_al_fitr_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2017: ( + (JAN, 2, new_years_joint_holiday), + (JUN, 23, eid_al_fitr_joint_holiday), + (JUN, 27, eid_al_fitr_joint_holiday), + (JUN, 28, eid_al_fitr_joint_holiday), + (JUN, 29, eid_al_fitr_joint_holiday), + (JUN, 30, eid_al_fitr_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2018: ( + (JUN, 11, eid_al_fitr_joint_holiday), + (JUN, 12, eid_al_fitr_joint_holiday), + (JUN, 13, eid_al_fitr_joint_holiday), + (JUN, 14, eid_al_fitr_joint_holiday), + (JUN, 18, eid_al_fitr_joint_holiday), + (JUN, 19, eid_al_fitr_joint_holiday), + (JUN, 20, eid_al_fitr_joint_holiday), + (DEC, 24, christmas_joint_holiday), + ), + 2019: ( + (JUN, 3, eid_al_fitr_joint_holiday), + (JUN, 4, eid_al_fitr_joint_holiday), + (JUN, 7, eid_al_fitr_joint_holiday), + (DEC, 24, christmas_joint_holiday), + ), + 2020: ( + (AUG, 21, islamic_new_year_joint_holiday), + (OCT, 28, mawlid_joint_holiday), + (OCT, 30, mawlid_joint_holiday), + (DEC, 24, christmas_joint_holiday), + ), + 2021: (MAY, 12, eid_al_fitr_joint_holiday), + 2022: ( + (APR, 29, eid_al_fitr_joint_holiday), + (MAY, 4, eid_al_fitr_joint_holiday), + (MAY, 5, eid_al_fitr_joint_holiday), + (MAY, 6, eid_al_fitr_joint_holiday), + ), + 2023: ( + (JAN, 23, lunar_new_year_joint_holiday), + (MAR, 23, day_of_silence_joint_holiday), + (APR, 19, eid_al_fitr_joint_holiday), + (APR, 20, eid_al_fitr_joint_holiday), + (APR, 21, eid_al_fitr_joint_holiday), + (APR, 24, eid_al_fitr_joint_holiday), + (APR, 25, eid_al_fitr_joint_holiday), + (JUN, 2, vesak_joint_holiday), + (JUN, 28, eid_al_adha_joint_holiday), + (JUN, 30, eid_al_adha_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2024: ( + (FEB, 9, lunar_new_year_joint_holiday), + (MAR, 12, day_of_silence_joint_holiday), + (APR, 8, eid_al_fitr_joint_holiday), + (APR, 9, eid_al_fitr_joint_holiday), + (APR, 12, eid_al_fitr_joint_holiday), + (APR, 15, eid_al_fitr_joint_holiday), + (MAY, 10, ascension_joint_holiday), + (MAY, 24, vesak_joint_holiday), + (JUN, 18, eid_al_adha_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + 2025: ( + (JAN, 28, lunar_new_year_joint_holiday), + (MAR, 28, day_of_silence_joint_holiday), + (APR, 2, eid_al_fitr_joint_holiday), + (APR, 3, eid_al_fitr_joint_holiday), + (APR, 4, eid_al_fitr_joint_holiday), + (APR, 7, eid_al_fitr_joint_holiday), + (MAY, 13, vesak_joint_holiday), + (MAY, 30, ascension_joint_holiday), + (JUN, 9, eid_al_adha_joint_holiday), + (DEC, 26, christmas_joint_holiday), + ), + } + special_government_holidays_observed = { + 2020: (DEC, 31, eid_al_fitr_joint_holiday), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/iran.py b/.venv/lib/python3.12/site-packages/holidays/countries/iran.py new file mode 100644 index 00000000..c9ea1b25 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/iran.py @@ -0,0 +1,611 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + FRI, +) +from holidays.groups import IslamicHolidays, PersianCalendarHolidays +from holidays.holiday_base import HolidayBase + + +class Iran(HolidayBase, IslamicHolidays, PersianCalendarHolidays): + """Iran holidays. + + References: + * + * + * + * + * + """ + + country = "IR" + default_language = "fa_IR" + # %s (estimated). + estimated_label = tr("%s (تخمینی)") + supported_languages = ("en_US", "fa_IR") + start_year = 1980 + weekend = {FRI} + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + IslamicHolidays.__init__( + self, cls=IranIslamicHolidays, show_estimated=islamic_show_estimated + ) + PersianCalendarHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Persian calendar holidays. + + # Islamic Revolution Day. + self._add_islamic_revolution_day(tr("پیروزی انقلاب اسلامی")) + + # Iranian Oil Industry Nationalization Day. + self._add_oil_nationalization_day(tr("روز ملی شدن صنعت نفت ایران")) + + # Last Day of Year. + self._add_last_day_of_year(tr("آخرین روز سال")) + + # Nowruz. + self._add_nowruz_day(tr("جشن نوروز")) + + # Nowruz Holiday. + name = tr("عیدنوروز") + self._add_nowruz_day_two(name) + self._add_nowruz_day_three(name) + self._add_nowruz_day_four(name) + + # Islamic Republic Day. + self._add_islamic_republic_day(tr("روز جمهوری اسلامی")) + + # Nature's Day. + self._add_natures_day(tr("روز طبیعت")) + + # Death of Imam Khomeini. + self._add_death_of_khomeini_day(tr("رحلت حضرت امام خمینی")) + + # 15 Khordad Uprising. + self._add_khordad_uprising_day(tr("قیام 15 خرداد")) + + # Islamic holidays. + + # Tasua. + self._add_tasua_day(tr("تاسوعای حسینی")) + + # Ashura. + self._add_ashura_day(tr("عاشورای حسینی")) + + # Arbaeen. + self._add_arbaeen_day(tr("اربعین حسینی")) + + # Death of Prophet Muhammad and Martyrdom of Hasan ibn Ali. + self._add_prophet_death_day(tr("رحلت رسول اکرم؛شهادت امام حسن مجتبی علیه السلام")) + + # Martyrdom of Ali al-Rida. + self._add_ali_al_rida_death_day(tr("شهادت امام رضا علیه السلام")) + + # Martyrdom of Hasan al-Askari. + self._add_hasan_al_askari_death_day(tr("شهادت امام حسن عسکری علیه السلام")) + + # Birthday of Muhammad and Imam Ja'far al-Sadiq. + self._add_sadiq_birthday_day(tr("میلاد رسول اکرم و امام جعفر صادق علیه السلام")) + + # Martyrdom of Fatima. + self._add_fatima_death_day(tr("شهادت حضرت فاطمه زهرا سلام الله علیها")) + + # Birthday of Imam Ali. + self._add_ali_birthday_day(tr("ولادت امام علی علیه السلام و روز پدر")) + + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("مبعث رسول اکرم (ص)")) + + self._add_imam_mahdi_birthday_day( + # Birthday of Mahdi. + tr("ولادت حضرت قائم عجل الله تعالی فرجه و جشن نیمه شعبان") + ) + + # Martyrdom of Imam Ali. + self._add_ali_death_day(tr("شهادت حضرت علی علیه السلام")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("عید سعید فطر")) + + # Eid al-Fitr Holiday. + self._add_eid_al_fitr_day_two(tr("تعطیل به مناسبت عید سعید فطر")) + + # Martyrdom of Imam Ja'far al-Sadiq. + self._add_sadiq_death_day(tr("شهادت امام جعفر صادق علیه السلام")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("عید سعید قربان")) + + # Eid al-Ghadeer. + self._add_eid_al_ghadir_day(tr("عید سعید غدیر خم")) + + +class IR(Iran): + pass + + +class IRN(Iran): + pass + + +class IranIslamicHolidays(_CustomIslamicHolidays): + ALI_AL_RIDA_DEATH_DATES = { + 2001: (MAY, 24), + 2002: (MAY, 13), + 2003: (MAY, 2), + 2004: (APR, 20), + 2005: (APR, 9), + 2006: (MAR, 30), + 2007: (MAR, 20), + 2008: (MAR, 8), + 2009: (FEB, 26), + 2010: (FEB, 15), + 2011: (FEB, 4), + 2012: (JAN, 24), + 2013: (JAN, 12), + 2014: ((JAN, 2), (DEC, 23)), + 2015: (DEC, 12), + 2016: (NOV, 30), + 2017: (NOV, 19), + 2018: (NOV, 8), + 2019: (OCT, 29), + 2020: (OCT, 17), + 2021: (OCT, 7), + 2022: (SEP, 27), + 2023: (SEP, 16), + 2024: (SEP, 4), + 2025: (AUG, 24), + } + + ALI_BIRTHDAY_DATES = { + 2001: (OCT, 1), + 2002: (SEP, 21), + 2003: (SEP, 10), + 2004: (AUG, 30), + 2005: (AUG, 19), + 2006: (AUG, 8), + 2007: (JUL, 28), + 2008: (JUL, 16), + 2009: (JUL, 6), + 2010: (JUN, 26), + 2011: (JUN, 16), + 2012: (JUN, 4), + 2013: (MAY, 24), + 2014: (MAY, 13), + 2015: (MAY, 2), + 2016: (APR, 21), + 2017: (APR, 11), + 2018: (MAR, 31), + 2019: (MAR, 20), + 2020: (MAR, 8), + 2021: (FEB, 25), + 2022: (FEB, 15), + 2023: (FEB, 4), + 2024: (JAN, 25), + 2025: (JAN, 14), + } + + ALI_DEATH_DATES = { + 2001: (DEC, 7), + 2002: (NOV, 27), + 2003: (NOV, 16), + 2004: (NOV, 5), + 2005: (OCT, 25), + 2006: (OCT, 15), + 2007: (OCT, 3), + 2008: (SEP, 22), + 2009: (SEP, 11), + 2010: (SEP, 1), + 2011: (AUG, 21), + 2012: (AUG, 10), + 2013: (JUL, 30), + 2014: (JUL, 19), + 2015: (JUL, 8), + 2016: (JUN, 27), + 2017: (JUN, 16), + 2018: (JUN, 6), + 2019: (MAY, 27), + 2020: (MAY, 15), + 2021: (MAY, 4), + 2022: (APR, 23), + 2023: (APR, 12), + 2024: (APR, 1), + 2025: (MAR, 22), + } + + ARBAEEN_DATES = { + 2001: (MAY, 14), + 2002: (MAY, 3), + 2003: (APR, 23), + 2004: (APR, 11), + 2005: (MAR, 31), + 2006: (MAR, 21), + 2007: (MAR, 10), + 2008: (FEB, 28), + 2009: (FEB, 16), + 2010: (FEB, 5), + 2011: (JAN, 25), + 2012: (JAN, 14), + 2013: ((JAN, 3), (DEC, 23)), + 2014: (DEC, 13), + 2015: (DEC, 2), + 2016: (NOV, 20), + 2017: (NOV, 9), + 2018: (OCT, 30), + 2019: (OCT, 19), + 2020: (OCT, 8), + 2021: (SEP, 27), + 2022: (SEP, 17), + 2023: (SEP, 6), + 2024: (AUG, 25), + 2025: (AUG, 14), + } + + ASHURA_DATES = { + 2001: (APR, 5), + 2002: (MAR, 25), + 2003: (MAR, 14), + 2004: (MAR, 2), + 2005: (FEB, 20), + 2006: (FEB, 9), + 2007: (JAN, 30), + 2008: (JAN, 19), + 2009: ((JAN, 7), (DEC, 27)), + 2010: (DEC, 16), + 2011: (DEC, 6), + 2012: (NOV, 25), + 2013: (NOV, 14), + 2014: (NOV, 4), + 2015: (OCT, 24), + 2016: (OCT, 12), + 2017: (OCT, 1), + 2018: (SEP, 20), + 2019: (SEP, 10), + 2020: (AUG, 30), + 2021: (AUG, 19), + 2022: (AUG, 8), + 2023: (JUL, 28), + 2024: (JUL, 16), + 2025: (JUL, 6), + } + + EID_AL_ADHA_DATES = { + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 11), (DEC, 31)), + 2007: (DEC, 21), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 16), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 21), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 2001: (DEC, 16), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 1), + 2009: (SEP, 20), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 9), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 6), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 3), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + EID_AL_GHADIR_DATES = { + 2001: (MAR, 14), + 2002: (MAR, 3), + 2003: (FEB, 20), + 2004: (FEB, 10), + 2005: (JAN, 29), + 2006: (JAN, 19), + 2007: ((JAN, 8), (DEC, 29)), + 2008: (DEC, 17), + 2009: (DEC, 6), + 2010: (NOV, 25), + 2011: (NOV, 15), + 2012: (NOV, 3), + 2013: (OCT, 24), + 2014: (OCT, 13), + 2015: (OCT, 2), + 2016: (SEP, 20), + 2017: (SEP, 9), + 2018: (AUG, 30), + 2019: (AUG, 20), + 2020: (AUG, 8), + 2021: (JUL, 29), + 2022: (JUL, 18), + 2023: (JUL, 7), + 2024: (JUN, 25), + 2025: (JUN, 14), + } + + FATIMA_DEATH_DATES = { + 2001: (AUG, 23), + 2002: (AUG, 12), + 2003: (AUG, 2), + 2004: (JUL, 21), + 2005: (JUL, 10), + 2006: (JUN, 29), + 2007: (JUN, 18), + 2008: (JUN, 7), + 2009: (MAY, 28), + 2010: (MAY, 17), + 2011: (MAY, 7), + 2012: (APR, 25), + 2013: (APR, 14), + 2014: (APR, 3), + 2015: (MAR, 24), + 2016: (MAR, 13), + 2017: (MAR, 2), + 2018: (FEB, 20), + 2019: (FEB, 9), + 2020: (JAN, 29), + 2021: (JAN, 17), + 2022: ((JAN, 6), (DEC, 27)), + 2023: (DEC, 17), + 2024: (DEC, 5), + 2025: (NOV, 24), + } + + HASAN_AL_ASKARI_DEATH_DATES = { + 2001: (JUN, 1), + 2002: (MAY, 21), + 2003: (MAY, 10), + 2004: (APR, 28), + 2005: (APR, 17), + 2006: (APR, 7), + 2007: (MAR, 28), + 2008: (MAR, 16), + 2009: (MAR, 6), + 2010: (FEB, 23), + 2011: (FEB, 12), + 2012: (FEB, 1), + 2013: (JAN, 20), + 2014: ((JAN, 10), (DEC, 31)), + 2015: (DEC, 20), + 2016: (DEC, 8), + 2017: (NOV, 27), + 2018: (NOV, 16), + 2019: (NOV, 6), + 2020: (OCT, 25), + 2021: (OCT, 15), + 2022: (OCT, 5), + 2023: (SEP, 24), + 2024: (SEP, 12), + 2025: (SEP, 1), + } + + IMAM_MAHDI_BIRTHDAY_DATES = { + 2001: (NOV, 1), + 2002: (OCT, 22), + 2003: (OCT, 12), + 2004: (OCT, 1), + 2005: (SEP, 20), + 2006: (SEP, 9), + 2007: (AUG, 29), + 2008: (AUG, 17), + 2009: (AUG, 7), + 2010: (JUL, 27), + 2011: (JUL, 17), + 2012: (JUL, 5), + 2013: (JUN, 24), + 2014: (JUN, 13), + 2015: (JUN, 3), + 2016: (MAY, 22), + 2017: (MAY, 12), + 2018: (MAY, 2), + 2019: (APR, 21), + 2020: (APR, 9), + 2021: (MAR, 29), + 2022: (MAR, 18), + 2023: (MAR, 8), + 2024: (FEB, 25), + 2025: (FEB, 14), + } + + ISRA_AND_MIRAJ_DATES = { + 2001: (OCT, 15), + 2002: (OCT, 5), + 2003: (SEP, 24), + 2004: (SEP, 13), + 2005: (SEP, 2), + 2006: (AUG, 22), + 2007: (AUG, 11), + 2008: (JUL, 30), + 2009: (JUL, 20), + 2010: (JUL, 10), + 2011: (JUN, 30), + 2012: (JUN, 18), + 2013: (JUN, 7), + 2014: (MAY, 27), + 2015: (MAY, 16), + 2016: (MAY, 5), + 2017: (APR, 25), + 2018: (APR, 14), + 2019: (APR, 3), + 2020: (MAR, 22), + 2021: (MAR, 11), + 2022: (MAR, 1), + 2023: (FEB, 18), + 2024: (FEB, 8), + 2025: (JAN, 28), + } + + PROPHET_DEATH_DATES = { + 2001: (MAY, 22), + 2002: (MAY, 11), + 2003: (MAY, 1), + 2004: (APR, 19), + 2005: (APR, 8), + 2006: (MAR, 29), + 2007: (MAR, 18), + 2008: (MAR, 7), + 2009: (FEB, 24), + 2010: (FEB, 13), + 2011: (FEB, 2), + 2012: (JAN, 22), + 2013: ((JAN, 11), (DEC, 31)), + 2014: (DEC, 21), + 2015: (DEC, 10), + 2016: (NOV, 28), + 2017: (NOV, 17), + 2018: (NOV, 7), + 2019: (OCT, 27), + 2020: (OCT, 16), + 2021: (OCT, 5), + 2022: (SEP, 25), + 2023: (SEP, 14), + 2024: (SEP, 2), + 2025: (AUG, 22), + } + + SADIQ_BIRTHDAY_DATES = { + 2001: (JUN, 10), + 2002: (MAY, 30), + 2003: (MAY, 19), + 2004: (MAY, 7), + 2005: (APR, 26), + 2006: (APR, 16), + 2007: (APR, 6), + 2008: (MAR, 25), + 2009: (MAR, 15), + 2010: (MAR, 4), + 2011: (FEB, 21), + 2012: (FEB, 10), + 2013: (JAN, 29), + 2014: (JAN, 19), + 2015: ((JAN, 9), (DEC, 29)), + 2016: (DEC, 17), + 2017: (DEC, 6), + 2018: (NOV, 25), + 2019: (NOV, 15), + 2020: (NOV, 3), + 2021: (OCT, 24), + 2022: (OCT, 14), + 2023: (OCT, 3), + 2024: (SEP, 21), + 2025: (SEP, 10), + } + + SADIQ_DEATH_DATES = { + 2001: (JAN, 20), + 2002: ((JAN, 9), (DEC, 30)), + 2003: (DEC, 20), + 2004: (DEC, 8), + 2005: (NOV, 28), + 2006: (NOV, 17), + 2007: (NOV, 6), + 2008: (OCT, 25), + 2009: (OCT, 14), + 2010: (OCT, 4), + 2011: (SEP, 24), + 2012: (SEP, 12), + 2013: (SEP, 2), + 2014: (AUG, 22), + 2015: (AUG, 11), + 2016: (JUL, 30), + 2017: (JUL, 20), + 2018: (JUL, 9), + 2019: (JUN, 29), + 2020: (JUN, 17), + 2021: (JUN, 6), + 2022: (MAY, 27), + 2023: (MAY, 16), + 2024: (MAY, 4), + 2025: (APR, 24), + } + + TASUA_DATES = { + 2001: (APR, 4), + 2002: (MAR, 24), + 2003: (MAR, 13), + 2004: (MAR, 1), + 2005: (FEB, 19), + 2006: (FEB, 8), + 2007: (JAN, 29), + 2008: (JAN, 18), + 2009: ((JAN, 6), (DEC, 26)), + 2010: (DEC, 15), + 2011: (DEC, 5), + 2012: (NOV, 24), + 2013: (NOV, 13), + 2014: (NOV, 3), + 2015: (OCT, 23), + 2016: (OCT, 11), + 2017: (SEP, 30), + 2018: (SEP, 19), + 2019: (SEP, 9), + 2020: (AUG, 29), + 2021: (AUG, 18), + 2022: (AUG, 7), + 2023: (JUL, 27), + 2024: (JUL, 15), + 2025: (JUL, 5), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/ireland.py b/.venv/lib/python3.12/site-packages/holidays/countries/ireland.py new file mode 100644 index 00000000..83c9793d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/ireland.py @@ -0,0 +1,97 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import FEB, MAR, SEP, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Ireland(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Ireland holidays. + + References: + * + * + """ + + country = "IE" + start_year = 1872 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, IrelandStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + if self._year >= 1975: + self._add_new_years_day("New Year's Day") + + # Saint Brigid's Day. + if self._year >= 2023: + name = "Saint Brigid's Day" + if self._is_friday(FEB, 1): + self._add_holiday_feb_1(name) + else: + self._add_holiday_1st_mon_from_feb_1(name) + + # Saint Patrick's Day. + if self._year >= 1903: + self._add_holiday_mar_17("Saint Patrick's Day") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # May Day. + if self._year >= 1994: + name = "May Day" + if self._year == 1995: + self._add_holiday_may_8(name) + else: + self._add_holiday_1st_mon_of_may(name) + + if self._year >= 1973: + # June Bank Holiday. + self._add_holiday_1st_mon_of_jun("June Bank Holiday") + else: + # Whit Monday. + self._add_whit_monday("Whit Monday") + + # August Bank Holiday. + self._add_holiday_1st_mon_of_aug("August Bank Holiday") + + # October Bank Holiday. + if self._year >= 1977: + self._add_holiday_last_mon_of_oct("October Bank Holiday") + + # Christmas Day. + self._add_christmas_day("Christmas Day") + + # Saint Stephen's Day. + self._add_christmas_day_two("Saint Stephen's Day") + + +class IE(Ireland): + pass + + +class IRL(Ireland): + pass + + +class IrelandStaticHolidays: + special_public_holidays = { + 1999: (DEC, 31, "Millennium Celebrations"), + 2011: (SEP, 14, "National Day of Mourning"), + 2022: (MAR, 18, "Day of Remembrance and Recognition"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/isle_of_man.py b/.venv/lib/python3.12/site-packages/holidays/countries/isle_of_man.py new file mode 100644 index 00000000..e409e09d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/isle_of_man.py @@ -0,0 +1,69 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.countries.united_kingdom import UnitedKingdom, UnitedKingdomStaticHolidays +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_MON + + +class IsleOfMan(UnitedKingdom): + """Isle Of Man holidays.""" + + country = "IM" + # The Isle of Man (IM) is not a subdivision of the United Kingdom (GB) + # entity, so the `IsleOfMan` class does not inherit from the `ChildEntity` + # mixin. The `parent_entity` is specified below solely to maintain + # consistency in holiday name localization. + parent_entity = UnitedKingdom + subdivisions = () # Override UnitedKingdom subdivisions. + subdivisions_aliases = {} # Override UnitedKingdom subdivisions aliases. + + def __init__(self, *args, **kwargs): # Override UnitedKingdom __init__(). + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, UnitedKingdomStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + ObservedHolidayBase.__init__(self, *args, **kwargs) + + def _populate_public_holidays(self) -> None: + super()._populate_public_holidays() + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + if self._year <= 1970: + # Whit Monday. + self._add_whit_monday(tr("Whit Monday")) + + if self._year >= 1971: + # Late Summer Bank Holiday. + self._add_holiday_last_mon_of_aug(tr("Late Summer Bank Holiday")) + + # Isle of Man exclusive holidays + + # TT Bank Holiday. + self._add_holiday_1st_fri_of_jun(tr("TT Bank Holiday")) + + # Tynwald Day. + jul_5 = self._add_holiday_jul_5(tr("Tynwald Day")) + if self._year >= 1992: + # Move to the next Monday if falls on a weekend. + self._move_holiday(jul_5, show_observed_label=False) + + +class IM(IsleOfMan): + pass + + +class IMN(IsleOfMan): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/israel.py b/.venv/lib/python3.12/site-packages/holidays/countries/israel.py new file mode 100644 index 00000000..43deebca --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/israel.py @@ -0,0 +1,152 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import _timedelta, FRI, SAT +from holidays.constants import OPTIONAL, PUBLIC, SCHOOL +from holidays.groups import HebrewCalendarHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + THU_TO_PREV_WED, + FRI_TO_PREV_WED, + FRI_TO_PREV_THU, + SAT_TO_PREV_THU, + SAT_TO_NEXT_SUN, + SUN_TO_NEXT_MON, +) + + +class Israel(ObservedHolidayBase, HebrewCalendarHolidays): + """Israel holidays. + + References: + * + * + """ + + country = "IL" + default_language = "he" + # %s (observed). + observed_label = tr("%s (נצפה)") + supported_categories = (OPTIONAL, PUBLIC, SCHOOL) + supported_languages = ("en_US", "he", "th", "uk") + weekend = {FRI, SAT} + start_year = 1948 + + def __init__(self, *args, **kwargs): + HebrewCalendarHolidays.__init__(self) + kwargs.setdefault("observed_rule", FRI_TO_PREV_THU + SAT_TO_PREV_THU) + super().__init__(*args, **kwargs) + + def _add_observed(self, dt, name, rule): + is_observed, _ = super()._add_observed(dt, name, rule) + if not is_observed: + self._add_holiday(name, dt) + + def _populate_public_holidays(self): + # Rosh Hashanah (New Year). + self._add_rosh_hashanah(tr("ראש השנה"), range(2)) + + # Yom Kippur (Day of Atonement). + self._add_yom_kippur(tr("יום כיפור")) + + # Sukkot (Feast of Tabernacles). + self._add_sukkot(tr("סוכות")) + # Simchat Torah / Shemini Atzeret. + self._add_sukkot(tr("שמחת תורה/שמיני עצרת"), +7) + + # Pesach (Passover). + self._add_passover(tr("פסח")) + # Shvi'i shel Pesach (Seventh day of Passover) + self._add_passover(tr("שביעי של פסח"), +6) + + rule = FRI_TO_PREV_THU + SAT_TO_PREV_THU + if self._year >= 2004: + rule += MON_TO_NEXT_TUE + self._add_observed( + self._hebrew_calendar.israel_independence_date(self._year), + # Yom Ha-Atzmaut (Independence Day). + tr("יום העצמאות"), + rule, + ) + + # Shavuot. + self._add_shavuot(tr("שבועות")) + + def _populate_optional_holidays(self): + # Chol HaMoed Sukkot (Feast of Tabernacles holiday). + self._add_sukkot(tr("חול המועד סוכות"), range(1, 6)) + + if self._year >= 2008: + # Sigd. + self._add_yom_kippur(tr("סיגד"), +49) + + # Purim. + self._add_purim(tr("פורים")) + + # Chol HaMoed Pesach (Passover holiday). + self._add_passover(tr("חול המועד פסח"), range(1, 6)) + + if self._year >= 1963: + rule = THU_TO_PREV_WED + FRI_TO_PREV_WED + if self._year >= 2004: + rule += SUN_TO_NEXT_MON + self._add_observed( + _timedelta(self._hebrew_calendar.israel_independence_date(self._year), -1), + # Yom Hazikaron (Fallen Soldiers and Victims of Terrorism Remembrance Day). + tr("יום הזיכרון לחללי מערכות ישראל ונפגעי פעולות האיבה"), + rule, + ) + + if self._year >= 1998: + # Yom Yerushalayim (Jerusalem Day). + self._add_lag_baomer(tr("יום ירושלים"), +10) + + self._add_observed( + self._hebrew_calendar.tisha_bav_date(self._year), + # Tisha B'Av (Tisha B'Av, fast). + tr("תשעה באב"), + SAT_TO_NEXT_SUN, + ) + + def _populate_school_holidays(self): + # Chol HaMoed Sukkot (Feast of Tabernacles holiday). + self._add_sukkot(tr("חול המועד סוכות"), range(1, 6)) + + # Hanukkah. + self._add_hanukkah(tr("חנוכה"), range(8)) + + self._add_observed( + _timedelta(self._hebrew_calendar.purim_date(self._year), -1), + # Ta`anit Ester (Fast of Esther). + tr("תענית אסתר"), + SAT_TO_PREV_THU, + ) + + # Purim. + self._add_purim(tr("פורים")) + + # Chol HaMoed Pesach (Passover holiday). + self._add_passover(tr("חול המועד פסח"), range(1, 6)) + + # Lag Ba'omer (Lag BaOmer). + self._add_lag_baomer(tr('ל"ג בעומר')) + + +class IL(Israel): + pass + + +class ISR(Israel): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/italy.py b/.venv/lib/python3.12/site-packages/holidays/countries/italy.py new file mode 100644 index 00000000..8a134985 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/italy.py @@ -0,0 +1,695 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import MAR +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Italy(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Italy holidays. + + References: + * + * [Provinces holidays](https://it.wikipedia.org/wiki/Santi_patroni_cattolici_delle_città_capoluogo_di_provincia_italiane) + """ + + country = "IT" + subdivisions = ( + # Provinces. + "AG", # Agrigento. + "AL", # Alessandria. + "AN", # Ancona. + "AO", # Aosta (deprecated). + "AP", # Ascoli Piceno. + "AQ", # L'Aquila. + "AR", # Arezzo. + "AT", # Asti. + "AV", # Avellino. + "BA", # Bari. + "BG", # Bergamo. + "BI", # Biella. + "BL", # Belluno. + "BN", # Benevento. + "BO", # Bologna. + "BR", # Brindisi. + "BS", # Brescia. + "BT", # Barletta-Andria-Trani. + "BZ", # Bolzano. + "CA", # Cagliari. + "CB", # Campobasso. + "CE", # Caserta. + "CH", # Chieti. + "CL", # Caltanissetta. + "CN", # Cuneo. + "CO", # Como. + "CR", # Cremona. + "CS", # Cosenza. + "CT", # Catania. + "CZ", # Catanzaro. + "EN", # Enna. + "FC", # Forlì-Cesena. + "FE", # Ferrara. + "FG", # Foggia. + "FI", # Firenze. + "FM", # Fermo. + "FR", # Frosinone. + "GE", # Genova. + "GO", # Gorizia. + "GR", # Grosseto. + "IM", # Imperia. + "IS", # Isernia. + "KR", # Crotone. + "LC", # Lecco. + "LE", # Lecce. + "LI", # Livorno. + "LO", # Lodi. + "LT", # Latina. + "LU", # Lucca. + "MB", # Monza e Brianza. + "MC", # Macerata. + "ME", # Messina. + "MI", # Milano. + "MN", # Mantova. + "MO", # Modena. + "MS", # Massa-Carrara. + "MT", # Matera. + "NA", # Napoli. + "NO", # Novara. + "NU", # Nuoro. + "OR", # Oristano. + "PA", # Palermo. + "PC", # Piacenza. + "PD", # Padova. + "PE", # Pescara. + "PG", # Perugia. + "PI", # Pisa. + "PN", # Pordenone. + "PO", # Prato. + "PR", # Parma. + "PT", # Pistoia. + "PU", # Pesaro e Urbino. + "PV", # Pavia. + "PZ", # Potenza. + "RA", # Ravenna. + "RC", # Reggio Calabria. + "RE", # Reggio Emilia. + "RG", # Ragusa. + "RI", # Rieti. + "RM", # Roma. + "RN", # Rimini. + "RO", # Rovigo. + "SA", # Salerno. + "SI", # Siena. + "SO", # Sondrio. + "SP", # La Spezia. + "SR", # Siracusa. + "SS", # Sassari. + "SU", # Sud Sardegna. + "SV", # Savona. + "TA", # Taranto. + "TE", # Teramo. + "TN", # Trento. + "TO", # Torino. + "TP", # Trapani. + "TR", # Terni. + "TS", # Trieste. + "TV", # Treviso. + "UD", # Udine. + "VA", # Varese. + "VB", # Verbano-Cusio-Ossola. + "VC", # Vercelli. + "VE", # Venezia. + "VI", # Vicenza. + "VR", # Verona. + "VT", # Viterbo. + "VV", # Vibo Valentia. + # Cities. + "Andria", + "Barletta", + "Cesena", + "Forli", + "Pesaro", + "Trani", + "Urbino", + ) + subdivisions_aliases = { + # Provinces. + "Agrigento": "AG", + "Alessandria": "AL", + "Ancona": "AN", + "Aosta": "AO", + "Ascoli Piceno": "AP", + "L'Aquila": "AQ", + "Arezzo": "AR", + "Asti": "AT", + "Avellino": "AV", + "Bari": "BA", + "Bergamo": "BG", + "Biella": "BI", + "Belluno": "BL", + "Benevento": "BN", + "Bologna": "BO", + "Brindisi": "BR", + "Brescia": "BS", + "Barletta-Andria-Trani": "BT", + "Bolzano": "BZ", + "Cagliari": "CA", + "Campobasso": "CB", + "Caserta": "CE", + "Chieti": "CH", + "Caltanissetta": "CL", + "Cuneo": "CN", + "Como": "CO", + "Cremona": "CR", + "Cosenza": "CS", + "Catania": "CT", + "Catanzaro": "CZ", + "Enna": "EN", + "Forli-Cesena": "FC", + "Forlì-Cesena": "FC", + "Ferrara": "FE", + "Foggia": "FG", + "Firenze": "FI", + "Fermo": "FM", + "Frosinone": "FR", + "Genova": "GE", + "Gorizia": "GO", + "Grosseto": "GR", + "Imperia": "IM", + "Isernia": "IS", + "Crotone": "KR", + "Lecco": "LC", + "Lecce": "LE", + "Livorno": "LI", + "Lodi": "LO", + "Latina": "LT", + "Lucca": "LU", + "Monza e Brianza": "MB", + "Macerata": "MC", + "Messina": "ME", + "Milano": "MI", + "Mantova": "MN", + "Modena": "MO", + "Massa-Carrara": "MS", + "Matera": "MT", + "Napoli": "NA", + "Novara": "NO", + "Nuoro": "NU", + "Oristano": "OR", + "Palermo": "PA", + "Piacenza": "PC", + "Padova": "PD", + "Pescara": "PE", + "Perugia": "PG", + "Pisa": "PI", + "Pordenone": "PN", + "Prato": "PO", + "Parma": "PR", + "Pistoia": "PT", + "Pesaro e Urbino": "PU", + "Pavia": "PV", + "Potenza": "PZ", + "Ravenna": "RA", + "Reggio Calabria": "RC", + "Reggio Emilia": "RE", + "Ragusa": "RG", + "Rieti": "RI", + "Roma": "RM", + "Rimini": "RN", + "Rovigo": "RO", + "Salerno": "SA", + "Siena": "SI", + "Sondrio": "SO", + "La Spezia": "SP", + "Siracusa": "SR", + "Sassari": "SS", + "Sud Sardegna": "SU", + "Savona": "SV", + "Taranto": "TA", + "Teramo": "TE", + "Trento": "TN", + "Torino": "TO", + "Trapani": "TP", + "Terni": "TR", + "Trieste": "TS", + "Treviso": "TV", + "Udine": "UD", + "Varese": "VA", + "Verbano-Cusio-Ossola": "VB", + "Vercelli": "VC", + "Venezia": "VE", + "Vicenza": "VI", + "Verona": "VR", + "Viterbo": "VT", + "Vibo Valentia": "VV", + # Cities. + "Forlì": "Forli", + } + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=ItalyStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day("Capodanno") + + # Epiphany. + self._add_epiphany_day("Epifania del Signore") + + if self._year <= 1976: + # Saint Joseph's Day. + self._add_saint_josephs_day("San Giuseppe") + + # Easter Sunday. + self._add_easter_sunday("Pasqua di Resurrezione") + + # Easter Monday. + self._add_easter_monday("Lunedì dell'Angelo") + + if self._year >= 1946: + # Liberation Day. + self._add_holiday_apr_25("Festa della Liberazione") + + # Labor Day. + self._add_labor_day("Festa dei Lavoratori") + + if self._year >= 1948: + # Republic Day. + self._add_holiday_jun_2("Festa della Repubblica") + + if self._year <= 1976: + # Ascension Day. + self._add_ascension_thursday("Ascensione Nostro Signore") + + # Saints Peter and Paul. + self._add_saints_peter_and_paul_day("Santi Pietro e Paolo") + + # Corpus Christi. + self._add_corpus_christi_day("Corpus Domini") + + # Assumption Of Mary Day. + self._add_assumption_of_mary_day("Assunzione della Vergine") + + # All Saints' Day. + self._add_all_saints_day("Tutti i Santi") + + if self._year <= 1976: + # National Unity and Armed Forces Day. + self._add_holiday_nov_4("Giornata dell'Unità Nazionale e delle Forze Armate") + + # Immaculate Conception. + self._add_immaculate_conception_day("Immacolata Concezione") + + # Christmas Day. + self._add_christmas_day("Natale") + + if self._year >= 1947: + # Saint Stephen's Day. + self._add_christmas_day_two("Santo Stefano") + + def _populate_subdiv_ag_public_holidays(self): + self._add_holiday_feb_25("San Gerlando") + + def _populate_subdiv_al_public_holidays(self): + self._add_holiday_nov_10("San Baudolino") + + def _populate_subdiv_an_public_holidays(self): + self._add_holiday_may_4("San Ciriaco") + + def _populate_subdiv_ao_public_holidays(self): + self._add_holiday_sep_7("San Grato") + + def _populate_subdiv_ap_public_holidays(self): + self._add_holiday_aug_5("Sant'Emidio") + + def _populate_subdiv_aq_public_holidays(self): + self._add_holiday_jun_10("San Massimo D'Aveia") + + def _populate_subdiv_ar_public_holidays(self): + self._add_holiday_aug_7("San Donato D'Arezzo") + + def _populate_subdiv_at_public_holidays(self): + self._add_holiday_1st_tue_of_may("San Secondo di Asti") + + def _populate_subdiv_av_public_holidays(self): + self._add_holiday_feb_14("San Modestino") + + def _populate_subdiv_ba_public_holidays(self): + self._add_holiday_dec_6("San Nicola") + + def _populate_subdiv_bg_public_holidays(self): + self._add_holiday_aug_26("Sant'Alessandro di Bergamo") + + def _populate_subdiv_bi_public_holidays(self): + self._add_christmas_day_two("Santo Stefano") + + def _populate_subdiv_bl_public_holidays(self): + self._add_holiday_nov_11("San Martino") + + def _populate_subdiv_bn_public_holidays(self): + self._add_holiday_aug_24("San Bartolomeo apostolo") + + def _populate_subdiv_bo_public_holidays(self): + self._add_holiday_oct_4("San Petronio") + + def _populate_subdiv_br_public_holidays(self): + self._add_holiday_1st_sun_of_sep("San Lorenzo da Brindisi") + + def _populate_subdiv_bs_public_holidays(self): + self._add_holiday_feb_15("Santi Faustino e Giovita") + + # Barletta-Andria-Trani + def _populate_subdiv_bt_public_holidays(self): + self._add_holiday_may_3("San Nicola Pellegrino") + self._add_holiday_3rd_sun_of_sep("San Riccardo di Andria") + self._add_holiday_dec_30("San Ruggero") + + def _populate_subdiv_bz_public_holidays(self): + self._add_whit_monday("Lunedì di Pentecoste") + self._add_assumption_of_mary_day("Maria Santissima Assunta") + + def _populate_subdiv_ca_public_holidays(self): + self._add_holiday_oct_30("San Saturnino di Cagliari") + + def _populate_subdiv_cb_public_holidays(self): + self._add_saint_georges_day("San Giorgio") + + def _populate_subdiv_ce_public_holidays(self): + self._add_holiday_jan_20("San Sebastiano") + + def _populate_subdiv_ch_public_holidays(self): + self._add_holiday_may_11("San Giustino di Chieti") + + def _populate_subdiv_cl_public_holidays(self): + self._add_holiday_sep_29("San Michele Arcangelo") + + def _populate_subdiv_cn_public_holidays(self): + self._add_holiday_sep_29("San Michele Arcangelo") + + def _populate_subdiv_co_public_holidays(self): + self._add_holiday_aug_31("Sant'Abbondio") + + def _populate_subdiv_cr_public_holidays(self): + self._add_holiday_nov_13("Sant'Omobono") + + def _populate_subdiv_cs_public_holidays(self): + self._add_holiday_feb_12("Madonna del Pilerio") + + def _populate_subdiv_ct_public_holidays(self): + self._add_holiday_feb_5("Sant'Agata") + + def _populate_subdiv_cz_public_holidays(self): + self._add_holiday_jul_16("San Vitaliano") + + def _populate_subdiv_en_public_holidays(self): + self._add_holiday_jul_2("Madonna della Visitazione") + + # Forlì-Cesena + def _populate_subdiv_fc_public_holidays(self): + self._add_holiday_feb_4("Madonna del Fuoco") + self._add_saint_johns_day("San Giovanni Battista") + + def _populate_subdiv_fe_public_holidays(self): + self._add_saint_georges_day("San Giorgio") + + def _populate_subdiv_fg_public_holidays(self): + self._add_holiday_mar_22("Madonna dei Sette Veli") + + def _populate_subdiv_fi_public_holidays(self): + self._add_saint_johns_day("San Giovanni Battista") + + def _populate_subdiv_fm_public_holidays(self): + self._add_assumption_of_mary_day("Maria Santissima Assunta") + self._add_holiday_aug_16("Maria Santissima Assunta") + + def _populate_subdiv_fr_public_holidays(self): + self._add_holiday_jun_20("San Silverio") + + def _populate_subdiv_ge_public_holidays(self): + self._add_saint_johns_day("San Giovanni Battista") + + def _populate_subdiv_go_public_holidays(self): + self._add_holiday_mar_16("Santi Ilario e Taziano") + + def _populate_subdiv_gr_public_holidays(self): + self._add_holiday_aug_10("San Lorenzo") + + def _populate_subdiv_im_public_holidays(self): + self._add_holiday_nov_26("San Leonardo da Porto Maurizio") + + def _populate_subdiv_is_public_holidays(self): + self._add_holiday_may_19("San Pietro Celestino") + + def _populate_subdiv_kr_public_holidays(self): + self._add_holiday_oct_9("San Dionigi") + + def _populate_subdiv_lc_public_holidays(self): + self._add_holiday_dec_6("San Nicola") + + def _populate_subdiv_le_public_holidays(self): + self._add_holiday_aug_26("Sant'Oronzo") + + def _populate_subdiv_li_public_holidays(self): + self._add_holiday_may_22("Santa Giulia") + + def _populate_subdiv_lo_public_holidays(self): + self._add_holiday_jan_19("San Bassiano") + + def _populate_subdiv_lt_public_holidays(self): + self._add_holiday_apr_25("San Marco Evangelista") + self._add_holiday_jul_6("Santa Maria Goretti") + + def _populate_subdiv_lu_public_holidays(self): + self._add_holiday_jul_12("San Paolino di Lucca") + + def _populate_subdiv_mb_public_holidays(self): + self._add_saint_johns_day("San Giovanni Battista") + + def _populate_subdiv_mc_public_holidays(self): + self._add_holiday_aug_31("San Giuliano l'ospitaliere") + + def _populate_subdiv_me_public_holidays(self): + self._add_holiday_jun_3("Madonna della Lettera") + + def _populate_subdiv_mi_public_holidays(self): + self._add_holiday_dec_7("Sant'Ambrogio") + + def _populate_subdiv_mn_public_holidays(self): + self._add_holiday_mar_18("Sant'Anselmo da Baggio") + + def _populate_subdiv_mo_public_holidays(self): + self._add_holiday_jan_31("San Geminiano") + + def _populate_subdiv_ms_public_holidays(self): + self._add_holiday_oct_4("San Francesco d'Assisi") + + def _populate_subdiv_mt_public_holidays(self): + self._add_holiday_jul_2("Madonna della Bruna") + + def _populate_subdiv_na_public_holidays(self): + self._add_holiday_sep_19("San Gennaro") + + def _populate_subdiv_no_public_holidays(self): + self._add_holiday_jan_22("San Gaudenzio") + + def _populate_subdiv_nu_public_holidays(self): + self._add_holiday_aug_5("Nostra Signora della Neve") + + def _populate_subdiv_or_public_holidays(self): + self._add_holiday_feb_13("Sant'Archelao") + + def _populate_subdiv_pa_public_holidays(self): + self._add_holiday_jul_15("Santa Rosalia") + + def _populate_subdiv_pc_public_holidays(self): + self._add_holiday_jul_4("Sant'Antonino di Piacenza") + + def _populate_subdiv_pd_public_holidays(self): + self._add_holiday_jun_13("Sant'Antonio di Padova") + + def _populate_subdiv_pe_public_holidays(self): + self._add_holiday_oct_10("San Cetteo") + + def _populate_subdiv_pg_public_holidays(self): + self._add_holiday_aug_11("Santa Chiara d'Assisi") + self._add_holiday_oct_4("San Francesco d'Assisi") + + def _populate_subdiv_pi_public_holidays(self): + self._add_holiday_jun_17("San Ranieri") + + def _populate_subdiv_pn_public_holidays(self): + self._add_holiday_apr_25("San Marco Evangelista") + self._add_nativity_of_mary_day("Madonna delle Grazie") + + def _populate_subdiv_po_public_holidays(self): + self._add_christmas_day_two("Santo Stefano") + + def _populate_subdiv_pr_public_holidays(self): + self._add_holiday_jan_13("Sant'Ilario di Poitiers") + + def _populate_subdiv_pt_public_holidays(self): + self._add_saint_james_day("San Jacopo") + + # Pesaro e Urbino + def _populate_subdiv_pu_public_holidays(self): + self._add_holiday_jun_1("San Crescentino") + self._add_holiday_sep_24("San Terenzio di Pesaro") + + def _populate_subdiv_pv_public_holidays(self): + self._add_holiday_dec_9("San Siro") + + def _populate_subdiv_pz_public_holidays(self): + self._add_holiday_may_30("San Gerardo di Potenza") + + def _populate_subdiv_ra_public_holidays(self): + self._add_holiday_jul_23("Sant'Apollinare") + + def _populate_subdiv_rc_public_holidays(self): + self._add_saint_georges_day("San Giorgio") + + def _populate_subdiv_re_public_holidays(self): + self._add_holiday_nov_24("San Prospero Vescovo") + + def _populate_subdiv_rg_public_holidays(self): + self._add_saint_georges_day("San Giorgio Martire") + self._add_holiday_aug_29("San Giovanni Battista") + + def _populate_subdiv_ri_public_holidays(self): + self._add_holiday_dec_4("Santa Barbara") + + def _populate_subdiv_rm_public_holidays(self): + self._add_saints_peter_and_paul_day("Santi Pietro e Paolo") + + def _populate_subdiv_rn_public_holidays(self): + self._add_holiday_oct_14("San Gaudenzio") + + def _populate_subdiv_ro_public_holidays(self): + self._add_holiday_nov_26("San Bellino") + + def _populate_subdiv_sa_public_holidays(self): + self._add_holiday_sep_21("San Matteo Evangelista") + + def _populate_subdiv_si_public_holidays(self): + self._add_holiday_dec_1("Sant'Ansano") + + def _populate_subdiv_so_public_holidays(self): + self._add_holiday_jun_19("San Gervasio e San Protasio") + + def _populate_subdiv_sp_public_holidays(self): + self._add_saint_josephs_day("San Giuseppe") + + def _populate_subdiv_sr_public_holidays(self): + self._add_holiday_dec_13("Santa Lucia") + + def _populate_subdiv_ss_public_holidays(self): + self._add_holiday_dec_6("San Nicola") + + def _populate_subdiv_su_public_holidays(self): + # Carbonia. + self._add_holiday_4_days_past_2nd_sun_of_may("San Ponziano") + + def _populate_subdiv_sv_public_holidays(self): + self._add_holiday_mar_18("Nostra Signora della Misericordia") + + def _populate_subdiv_ta_public_holidays(self): + self._add_holiday_may_10("San Cataldo") + + def _populate_subdiv_te_public_holidays(self): + self._add_holiday_dec_19("San Berardo da Pagliara") + + def _populate_subdiv_tn_public_holidays(self): + self._add_holiday_jun_26("San Vigilio") + + def _populate_subdiv_to_public_holidays(self): + self._add_saint_johns_day("San Giovanni Battista") + + def _populate_subdiv_tp_public_holidays(self): + self._add_holiday_aug_7("Sant'Alberto degli Abati") + + def _populate_subdiv_tr_public_holidays(self): + self._add_holiday_feb_14("San Valentino") + + def _populate_subdiv_ts_public_holidays(self): + self._add_holiday_nov_3("San Giusto") + + def _populate_subdiv_tv_public_holidays(self): + self._add_holiday_apr_27("San Liberale") + + def _populate_subdiv_ud_public_holidays(self): + self._add_holiday_jul_12("Santi Ermacora e Fortunato") + + def _populate_subdiv_va_public_holidays(self): + self._add_holiday_may_8("San Vittore il Moro") + + def _populate_subdiv_vb_public_holidays(self): + self._add_holiday_may_8("San Vittore il Moro") + + def _populate_subdiv_vc_public_holidays(self): + self._add_holiday_aug_1("Sant'Eusebio di Vercelli") + + def _populate_subdiv_ve_public_holidays(self): + self._add_holiday_apr_25("San Marco Evangelista") + self._add_holiday_nov_21("Madonna della Salute") + + def _populate_subdiv_vi_public_holidays(self): + self._add_nativity_of_mary_day("Madonna di Monte Berico") + + def _populate_subdiv_vr_public_holidays(self): + self._add_holiday_may_21("San Zeno") + + def _populate_subdiv_vt_public_holidays(self): + self._add_holiday_sep_4("Santa Rosa da Viterbo") + + def _populate_subdiv_vv_public_holidays(self): + self._add_holiday_mar_1("San Leoluca") + + def _populate_subdiv_andria_public_holidays(self): + self._add_holiday_3rd_sun_of_sep("San Riccardo di Andria") + + def _populate_subdiv_barletta_public_holidays(self): + self._add_holiday_dec_30("San Ruggero") + + def _populate_subdiv_cesena_public_holidays(self): + self._add_saint_johns_day("San Giovanni Battista") + + def _populate_subdiv_forli_public_holidays(self): + self._add_holiday_feb_4("Madonna del Fuoco") + + def _populate_subdiv_pesaro_public_holidays(self): + self._add_holiday_sep_24("San Terenzio di Pesaro") + + def _populate_subdiv_trani_public_holidays(self): + self._add_holiday_may_3("San Nicola Pellegrino") + + def _populate_subdiv_urbino_public_holidays(self): + self._add_holiday_jun_1("San Crescentino") + + +class IT(Italy): + pass + + +class ITA(Italy): + pass + + +class ItalyStaticHolidays: + # Anniversary of the Unification of Italy. + anniversary_of_unification = "Anniversario dell'Unità d'Italia" + special_public_holidays = { + 1961: (MAR, 17, anniversary_of_unification), + 2011: (MAR, 17, anniversary_of_unification), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/ivory_coast.py b/.venv/lib/python3.12/site-packages/holidays/countries/ivory_coast.py new file mode 100644 index 00000000..e3d6d09d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/ivory_coast.py @@ -0,0 +1,156 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import FEB, OCT +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class IvoryCoast( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Ivory Coast holidays. + + References: + * [Decree No. 96-205](https://web.archive.org/web/20240701120937/http://www.droit-afrique.com/uploads/RCI-Decret-1996-205-jours-feries.pdf) + * Decree No. 2011-371: + * [page 1](https://web.archive.org/web/20180617165811/http://www.cgeci.org/cgeci/docs/documents/Doc-ferie-1.pdf) + * [page 2](https://web.archive.org/web/20180826205106/http://www.cgeci.org/cgeci/docs/documents/Doc-ferie-2.pdf) + * + * + * + * [National Peace Day](https://en.wikipedia.org/wiki/Ivory_Coast#Independence) + + Note: + The oldest decree available online that underpins the public holidays defined here + for the Ivory Coast is Decree no. 96-205 of March 7, 1996. + + In Islamic calendar, days begin at sunset. The naming convention "day after" refers + to the daylight hours following the night of the celebration, which is technically + the same Gregorian calendar day. + + According to Decree no. 2011-371 of 4 November 2011, if Eid al-Fitr, Eid al-Adha + or Christmas Day falls on a Sunday, the following Monday is also a holiday. + """ + + country = "CI" + default_language = "fr" + # %s (estimated). + estimated_label = tr("%s (estimé)") + # Day after the %s. + observed_label = tr("Lendemain de la %s") + # Day after the %s (estimated). + observed_estimated_label = tr("Lendemain de la %s (estimé)") + start_year = 1997 + supported_languages = ("en_CI", "en_US", "fr") + + def __init__(self, *args, islamic_show_estimated: bool = False, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + # The observed dates for the Ivory Coast's islamic holidays have been verified against + # local references (COSIM) and align with the default Umm al-Qura calculations. + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, IvoryCoastStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("1er janvier")) + + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Fête du travail"))) + + # Ascension Day. + self._add_ascension_thursday(tr("Jour de l'Ascension")) + + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + + # Independence Day. + self._add_observed(self._add_holiday_aug_7(tr("Fête Nationale"))) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Fête de l'Assomption")) + + # National Peace Day. + self._add_holiday_nov_15(tr("Journée Nationale de la Paix")) + + # All Saints' Day. + self._add_all_saints_day(tr("Fête de la Toussaint")) + + if self._year <= 2000: + self._add_holiday_dec_7( + # Anniversary of death of President Felix Houphouet-Boigny. + tr("Anniversaire du décès du Président Felix Houphouet-Boigny") + ) + + # Christmas Day. + dt = self._add_christmas_day(tr("Fête de Noël")) + if self._year >= 2011: + self._add_observed(dt) + + # Day after Prophet's Birthday. + self._add_mawlid_day(tr("Lendemain de l'Anniversaire de la Naissance du Prophète Mahomet")) + + # Day after Night of Power. + self._add_laylat_al_qadr_day(tr("Lendemain de la Nuit du Destin")) + + # Eid al-Fitr. + for dt in self._add_eid_al_fitr_day(tr("Fête de fin du Ramadan")): + if self._year >= 2012: + self._add_observed(dt) + + # Eid al-Adha. + for dt in self._add_eid_al_adha_day(tr("Fête de la Tabaski")): + if self._year >= 2012: + self._add_observed(dt) + + +class CI(IvoryCoast): + pass + + +class CIV(IvoryCoast): + pass + + +class IvoryCoastStaticHolidays: + """Ivory Coast special holidays. + + References: + * [2010 Presidential Election](https://web.archive.org/web/20250427185110/https://www.gouv.ci/_actualite-article.php?d=4.&recordID=1255&p=366) + * [2024 AFCON](https://web.archive.org/web/20250429075000/https://apanews.net/public-holiday-as-cote-divoire-wins-afcon-trophy/) + """ + + special_public_holidays = { + # Public holiday for Presidential election preparation. + 2010: (OCT, 29, tr("Jour férié pour la préparation de l'élection présidentielle")), + # 2024 African Cup of Nations Victory. + 2024: (FEB, 12, tr("Victoire à la Coupe d'Afrique des Nations 2024")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/jamaica.py b/.venv/lib/python3.12/site-packages/holidays/countries/jamaica.py new file mode 100644 index 00000000..c12fea8f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/jamaica.py @@ -0,0 +1,79 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SUN_TO_NEXT_MON, + SUN_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON, +) + + +class Jamaica(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Jamaica holidays. + + References: + * + * + """ + + country = "JM" + observed_label = "%s (observed)" + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Ash Wednesday + self._add_ash_wednesday("Ash Wednesday") + + # Good Friday + self._add_good_friday("Good Friday") + + # Easter Monday + self._add_easter_monday("Easter Monday") + + # National Labour Day + self._add_observed( + self._add_holiday_may_23("National Labour Day"), rule=SAT_SUN_TO_NEXT_MON + ) + + # Emancipation Day + if self._year >= 1998: + self._add_observed(self._add_holiday_aug_1("Emancipation Day")) + + # Independence Day + self._add_observed(self._add_holiday_aug_6("Independence Day")) + + # National Heroes Day + self._add_holiday_3rd_mon_of_oct("National Heroes Day") + + # Christmas Day + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + + # Boxing Day + self._add_observed(self._add_christmas_day_two("Boxing Day")) + + +class JM(Jamaica): + pass + + +class JAM(Jamaica): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/japan.py b/.venv/lib/python3.12/site-packages/holidays/countries/japan.py new file mode 100644 index 00000000..56ce1689 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/japan.py @@ -0,0 +1,261 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import ( + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + _timedelta, +) +from holidays.constants import BANK, PUBLIC +from holidays.groups import InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_WORKDAY + + +class Japan(ObservedHolidayBase, InternationalHolidays, StaticHolidays): + """Japan holidays. + + References: + * + * + """ + + country = "JP" + default_language = "ja" + supported_categories = (BANK, PUBLIC) + supported_languages = ("en_US", "ja", "th") + start_year = 1949 + end_year = 2099 + + def __init__(self, *args, **kwargs) -> None: + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=JapanStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _is_observed(self, dt: date) -> bool: + return dt >= date(1973, APR, 12) + + def _populate_observed(self, dts: set[date]) -> None: + # When a national holiday falls on Sunday, next working day + # shall become a public holiday (振替休日) - substitute holiday. + for dt in sorted(dts): + # Substitute Holiday. + self._add_observed(dt, name=tr("振替休日"), show_observed_label=False) + + # A weekday between national holidays becomes a holiday too (国民の休日) - + # national holiday. + # In 1986-2006 it was only May 4 (between Constitution Day and Children's Day). + # Since 2006, it may be only the day between Respect for the Aged Day and + # Autumnal Equinox Day (in September). + if self._year <= 1985: + return None + if self._year <= 2006: + may_4 = (MAY, 4) + if not self._is_monday(may_4) and not self._is_sunday(may_4): + # National Holiday. + self._add_holiday(tr("国民の休日"), may_4) + else: + for dt in dts: + if dt.month == SEP and _timedelta(dt, +2) in dts: + # National Holiday. + self._add_holiday(tr("国民の休日"), _timedelta(dt, +1)) + break + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("元日"))) + + # Coming of Age Day. + name = tr("成人の日") + dts_observed.add( + self._add_holiday_jan_15(name) + if self._year <= 1999 + else self._add_holiday_2nd_mon_of_jan(name) + ) + + if self._year >= 1967: + # Foundation Day. + dts_observed.add(self._add_holiday_feb_11(tr("建国記念の日"))) + + if self._year >= 2020: + # Emperor's Birthday. + dts_observed.add(self._add_holiday_feb_23(tr("天皇誕生日"))) + + # Vernal Equinox Day. + dts_observed.add(self._add_holiday(tr("春分の日"), self._vernal_equinox_date)) + + # Showa Emperor's Birthday, Greenery Day or Showa Day. + if self._year <= 1988: + name = tr("天皇誕生日") + elif self._year <= 2006: + # Greenery Day. + name = tr("みどりの日") + else: + # Showa Day. + name = tr("昭和の日") + dts_observed.add(self._add_holiday_apr_29(name)) + + # Constitution Day. + dts_observed.add(self._add_holiday_may_3(tr("憲法記念日"))) + + # Greenery Day. + if self._year >= 2007: + dts_observed.add(self._add_holiday_may_4(tr("みどりの日"))) + + # Children's Day. + dts_observed.add(self._add_holiday_may_5(tr("こどもの日"))) + + if self._year >= 1996: + # Marine Day. + name = tr("海の日") + if self._year <= 2002: + dts_observed.add(self._add_holiday_jul_20(name)) + else: + dates = { + 2020: (JUL, 23), + 2021: (JUL, 22), + } + dts_observed.add(self._add_holiday(name, dt)) if ( + dt := dates.get(self._year) + ) else dts_observed.add(self._add_holiday_3rd_mon_of_jul(name)) + + if self._year >= 2016: + dates = { + 2020: (AUG, 10), + 2021: (AUG, 8), + } + # Mountain Day. + name = tr("山の日") + dts_observed.add(self._add_holiday(name, dates.get(self._year, (AUG, 11)))) + + if self._year >= 1966: + # Respect for the Aged Day. + name = tr("敬老の日") + dts_observed.add( + self._add_holiday_3rd_mon_of_sep(name) + if self._year >= 2003 + else self._add_holiday_sep_15(name) + ) + + # Autumnal Equinox Day. + dts_observed.add(self._add_holiday(tr("秋分の日"), self._autumnal_equinox_date)) + + # Physical Education and Sports Day. + if self._year >= 1966: + name = ( + # Sports Day. + tr("スポーツの日") + if self._year >= 2020 + # Physical Education Day. + else tr("体育の日") + ) + if self._year >= 2000: + dates = { + 2020: (JUL, 24), + 2021: (JUL, 23), + } + dts_observed.add(self._add_holiday(name, dt)) if ( + dt := dates.get(self._year) + ) else dts_observed.add(self._add_holiday_2nd_mon_of_oct(name)) + else: + dts_observed.add(self._add_holiday_oct_10(name)) + + # Culture Day. + dts_observed.add(self._add_holiday_nov_3(tr("文化の日"))) + + # Labor Thanksgiving Day. + dts_observed.add(self._add_holiday_nov_23(tr("勤労感謝の日"))) + + # Regarding the Emperor of Heisei. + if 1989 <= self._year <= 2018: + dts_observed.add(self._add_holiday_dec_23(tr("天皇誕生日"))) + + if self.observed: + self._populate_observed(dts_observed) + + def _populate_bank_holidays(self): + # Bank Holiday. + name = tr("銀行休業日") + self._add_new_years_day(name) + self._add_new_years_day_two(name) + self._add_new_years_day_three(name) + self._add_new_years_eve(name) + + @property + def _vernal_equinox_date(self) -> tuple[int, int]: + day = 20 + if ( + (self._year % 4 == 0 and self._year <= 1956) + or (self._year % 4 == 1 and self._year <= 1989) + or (self._year % 4 == 2 and self._year <= 2022) + or (self._year % 4 == 3 and self._year <= 2055) + ): + day = 21 + elif self._year % 4 == 0 and self._year >= 2092: + day = 19 + return MAR, day + + @property + def _autumnal_equinox_date(self) -> tuple[int, int]: + day = 23 + if self._year % 4 == 3 and self._year <= 1979: + day = 24 + elif ( + (self._year % 4 == 0 and self._year >= 2012) + or (self._year % 4 == 1 and self._year >= 2045) + or (self._year % 4 == 2 and self._year >= 2078) + ): + day = 22 + return SEP, day + + +class JP(Japan): + pass + + +class JPN(Japan): + pass + + +class JapanStaticHolidays: + national_holiday = tr("国民の休日") + + special_public_holidays = { + 1959: (APR, 10, tr("結婚の儀")), # The Crown Prince marriage ceremony. + 1989: (FEB, 24, tr("大喪の礼")), # State Funeral of Emperor Shōwa. + 1990: (NOV, 12, tr("即位礼正殿の儀")), # Enthronement ceremony. + 1993: (JUN, 9, tr("結婚の儀")), # The Crown Prince marriage ceremony. + 2019: ( + (MAY, 1, tr("天皇の即位の日")), # Enthronement day. + (OCT, 22, tr("即位礼正殿の儀が行われる日")), # Enthronement ceremony. + ), + } + + special_public_holidays_observed = { + 2019: ( + (APR, 30, national_holiday), + (MAY, 2, national_holiday), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/jersey.py b/.venv/lib/python3.12/site-packages/holidays/countries/jersey.py new file mode 100644 index 00000000..816d7223 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/jersey.py @@ -0,0 +1,240 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import JAN, APR, MAY, JUN, JUL, SEP, OCT, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_WORKDAY, + SUN_TO_NEXT_WORKDAY, + SAT_TO_NONE, + SUN_TO_NONE, +) + + +class Jersey(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Jersey holidays. + + References: + * + * [2010 Revision](https://web.archive.org/web/20250403173914/https://www.jerseylaw.je/laws/current/Pages/15.560.20.aspx) + * [1952 Revision](https://web.archive.org/web/20250427181051/https://www.jerseylaw.je/laws/superseded/Pages/2006/15.560.20.aspx) + * [1952 as enacted](https://web.archive.org/web/20241224061844/http://www.jerseylaw.je/laws/enacted/Pages/RO-3038.aspx) + * [Bank Holidays](https://web.archive.org/web/20250427181011/https://www.jerseylaw.je/laws/enacted/Pages/Jersey%20RO%205331.aspx) + * [May Bank Holiday](https://web.archive.org/web/20250427181126/https://www.jerseylaw.je/laws/enacted/Pages/Jersey%20RO%206795.aspx) + + Checked with: + * [From 2010 onwards](https://web.archive.org/web/20241013001943/https://www.gov.je/Leisure/Events/WhatsOn/Pages/BankHolidayDates.aspx) + + This has only been cross-checked with the official source from 2010 onwards. + + Jersey has the same public holidays as the United Kingdom (England Subdivision) + - plus an extra day on 9 May, to mark Liberation Day (ignoring special holidays + like the Corn Riots Anniversary in 2021). + + If a bank holiday is on a sunday, a substitute weekday becomes a bank holiday, + normally the following Monday. From 2004 onwards this also applies to saturday. + """ + + country = "JE" + observed_label = "%s (substitute day)" + # Earliest available piece of law available is from 1952. + start_year = 1952 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, JerseyStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + ObservedHolidayBase.__init__(self, *args, **kwargs) + + def _add_observed(self, dt: date, **kwargs) -> tuple[bool, Optional[date]]: + # Prior to 2004, in-lieu are only given for Sundays. + # https://web.archive.org/web/20250414072718/https://www.jerseylaw.je/laws/enacted/Pages/RO-123-2004.aspx + kwargs.setdefault( + "rule", SUN_TO_NEXT_WORKDAY if dt < date(2004, OCT, 12) else self._observed_rule + ) + return super()._add_observed(dt, **kwargs) + + def _populate_public_holidays(self) -> None: + # New Year's Day. + # Available online source shown that this was celebrated since at least 1952. + # Was briefly removed in 1983 only to be added back again before that came to effect. + + # New Year's Day + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Good Friday + self._add_good_friday("Good Friday") + + # Easter Monday + self._add_easter_monday("Easter Monday") + + # Early May Bank Holiday + # This only starts in 1980 (instead of 1978) for Jersey. + # The date is not moved in 2020 (unlike in the UK) as there's already VE Day Celebrations. + # In 2024 this was called "May Bank Holiday" instead. + + # Early May bank holiday (first Monday in May) + if self._year >= 1980: + name = "May Bank Holiday" if self._year == 2024 else "Early May Bank Holiday" + if self._year == 1995: + self._add_holiday_may_8(name) + else: + self._add_holiday_1st_mon_of_may(name) + + # Spring bank holiday + # Current Pattern started in 1970 for Jersey. + + # Spring bank holiday (last Monday in May) + if self._year >= 1970: + spring_bank_dates = { + 2002: (JUN, 4), + 2012: (JUN, 4), + 2022: (JUN, 2), + } + name = "Spring Bank Holiday" + if dt := spring_bank_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_last_mon_of_may(name) + + # Whit Monday. + # Was in-use prior to Spring bank holiday adoption. + + if self._year <= 1969: + # Whit Monday. + self._add_whit_monday("Whit Monday") + + # Summer Bank Holiday + # Current Pattern started in 1970. Was previously first Monday of September for Jersey. + + # Summer bank holiday (last Monday in August) + summer_bank_holiday = "Summer Bank Holiday" + if self._year >= 1970: + self._add_holiday_last_mon_of_aug(summer_bank_holiday) + else: + self._add_holiday_1st_mon_of_sep(summer_bank_holiday) + + # Christmas Day + christmas_day = self._add_christmas_day("Christmas Day") + + # Boxing Day + boxing_day = self._add_christmas_day_two("Boxing Day") + + self._add_observed(christmas_day) + self._add_observed(boxing_day) + + # Jersey exclusive holidays + + # Liberation Day. + # Started in 1952. This has no in-lieus. + # Counts as Public Holiday when fall on the weekdays, also on Saturday from 2010 onwards. + + self._add_observed( + # Liberation Day + self._add_holiday_may_9("Liberation Day"), + rule=SAT_TO_NONE + SUN_TO_NONE if self._year <= 2010 else SUN_TO_NONE, + ) + + +class JE(Jersey): + pass + + +class JEY(Jersey): + pass + + +class JerseyStaticHolidays: + """Jersey special holidays. + + References: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + """ + + # Mostly a direct copy of UnitedKingdomStaticHolidays. + + # Jersey Specifics: + # - Queen Elizabeth II's Royal Visit (1957, 1978, 1989, 2001)* + # *2004 one falls on existing Liberation Day. + # - 75th VE Day Anniversary (2020) + # - 250th Corn Riots/Code of 1771 Anniversary (2021). + + # Jersey-specific Special Observance + # - New Year's Day (1977, 1983, 1994, 2000) + # - Boxing Day (1976, 1981, 1982, 1987, 1992, 1993, 1994, 1998, 1999, 2009) + + # New Year's Day + new_years_day_in_lieu = "New Year's Day" + + # Boxing Day + boxing_day_in_lieu = "Boxing Day" + + # The visit of Her Majesty Queen Elizabeth II. + elizabeth_2_royal_visit = "The visit of Her Majesty Queen Elizabeth II" + + special_public_holidays = { + 1957: (JUL, 26, elizabeth_2_royal_visit), + 1977: (JUN, 7, "Queen's Silver Jubilee"), + 1978: (JUN, 27, elizabeth_2_royal_visit), + 1981: (JUL, 29, "Wedding of Charles and Diana"), + 1989: (MAY, 25, elizabeth_2_royal_visit), + 1999: (DEC, 31, "Millennium Celebrations"), + 2001: (JUL, 13, elizabeth_2_royal_visit), + 2002: (JUN, 3, "Queen's Golden Jubilee"), + # Specially held in 2010 on Sunday for the 65th Anniversary. + 2010: (MAY, 9, "Liberation Day"), + 2011: (APR, 29, "Wedding of William and Catherine"), + 2012: (JUN, 5, "Queen's Diamond Jubilee"), + 2020: (MAY, 8, "75th Anniversary of VE Day"), + 2021: (SEP, 27, "Corn Riots Anniversary"), + 2022: ( + (JUN, 3, "Queen's Platinum Jubilee"), + (SEP, 19, "Funeral of Her Majesty Queen Elizabeth II"), + ), + 2023: (MAY, 8, "Coronation of His Majesty King Charles III"), + 2024: (JUL, 15, "The visit of His Majesty King Charles III and Queen Camilla"), + } + special_public_holidays_observed = { + 1976: (DEC, 28, boxing_day_in_lieu), + 1977: (JAN, 3, new_years_day_in_lieu), + 1981: (DEC, 28, boxing_day_in_lieu), + 1982: (DEC, 28, boxing_day_in_lieu), + 1983: (JAN, 3, new_years_day_in_lieu), + 1987: (DEC, 28, boxing_day_in_lieu), + 1992: (DEC, 28, boxing_day_in_lieu), + 1993: (DEC, 28, boxing_day_in_lieu), + 1994: (JAN, 3, new_years_day_in_lieu), + 1998: (DEC, 28, boxing_day_in_lieu), + 1999: (DEC, 28, boxing_day_in_lieu), + 2000: (JAN, 3, new_years_day_in_lieu), + 2009: (DEC, 28, boxing_day_in_lieu), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/jordan.py b/.venv/lib/python3.12/site-packages/holidays/countries/jordan.py new file mode 100644 index 00000000..d536a78c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/jordan.py @@ -0,0 +1,93 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import THU, FRI, SAT +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Jordan(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Jordan holidays. + + References: + * + * + """ + + country = "JO" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # The resting days are Friday and Saturday since Jan 6, 2000. + # https://web.archive.org/web/20241226195649/http://archive.wfn.org/2000/01/msg00078.html + self.weekend = {THU, FRI} if self._year <= 1999 else {FRI, SAT} + + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + # Labor Day. + self._add_labor_day(tr("عيد العمال")) + + # Independence Day. + self._add_holiday_may_25(tr("عيد الإستقلال")) + + # Christmas Day. + self._add_christmas_day(tr("عيد الميلاد المجيد")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("عيد المولد النبوي")) + + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("ليلة المعراج")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("عيد الفطر")) + # Eid al-Fitr Holiday. + self._add_eid_al_fitr_day_two(tr("عطلة عيد الفطر")) + self._add_eid_al_fitr_day_three(tr("عطلة عيد الفطر")) + + # Arafat Day. + self._add_arafah_day(tr("يوم عرفة")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("عيد الأضحى")) + # Eid al-Adha Holiday. + self._add_eid_al_adha_day_two(tr("عطلة عيد الأضحى")) + self._add_eid_al_adha_day_three(tr("عطلة عيد الأضحى")) + + +class JO(Jordan): + pass + + +class JOR(Jordan): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/kazakhstan.py b/.venv/lib/python3.12/site-packages/holidays/countries/kazakhstan.py new file mode 100644 index 00000000..1b771fcd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/kazakhstan.py @@ -0,0 +1,318 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class Kazakhstan( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Kazakhstan holidays. + + References: + * + * + * + * + + Islamic holidays: + * [2025](https://web.archive.org/web/20250429084936/https://qazinform.com/news/first-day-of-ramadan-to-fall-on-march-1-2025-ca393f) + """ + + country = "KZ" + default_language = "kk" + # %s (estimated). + estimated_label = tr("%s (бағаланған)") + # %s (observed). + observed_label = tr("%s (қайта белгіленген демалыс)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (қайта белгіленген демалыс, бағаланған)") + supported_languages = ("en_US", "kk", "uk") + # Kazakhstan declared its sovereignty on 25 October 1990. + start_year = 1991 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=KazakhstanIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, KazakhstanStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 2002) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + name = tr("Жаңа жыл") + dts_observed.add(self._add_new_years_day(name)) + dts_observed.add(self._add_new_years_day_two(name)) + + if self._year >= 2006: + # Orthodox Christmas. + self._add_christmas_day(tr("Православиелік Рождество")) + + # International Women's Day. + dts_observed.add(self._add_womens_day(tr("Халықаралық әйелдер күні"))) + + if self._year >= 2002: + # Nowruz Holiday. + name = tr("Наурыз мейрамы") + dts_observed.add(self._add_holiday_mar_22(name)) + if self._year >= 2010: + dts_observed.add(self._add_holiday_mar_21(name)) + dts_observed.add(self._add_holiday_mar_23(name)) + + # Kazakhstan's People Solidarity Holiday. + dts_observed.add(self._add_labor_day(tr("Қазақстан халқының бірлігі мерекесі"))) + + if self._year >= 2013: + # Defender of the Fatherland Day. + dts_observed.add(self._add_holiday_may_7(tr("Отан Қорғаушы күні"))) + + # Victory Day. + dt = self._add_world_war_two_victory_day(tr("Жеңіс күні"), is_western=False) + if self._year != 2020: + dts_observed.add(dt) + + if self._year >= 2009: + # Capital Day. + dts_observed.add(self._add_holiday_jul_6(tr("Астана күні"))) + + if self._year >= 1996: + dts_observed.add( + # Constitution Day. + self._add_holiday_aug_30(tr("Қазақстан Республикасының Конституциясы күні")) + ) + + if 1994 <= self._year <= 2008 or self._year >= 2022: + # Republic Day. + dts_observed.add(self._add_holiday_oct_25(tr("Республика күні"))) + + if 2012 <= self._year <= 2021: + dts_observed.add( + # First President Day. + self._add_holiday_dec_1(tr("Қазақстан Республикасының Тұңғыш Президенті күні")) + ) + + # Independence Day. + name = tr("Тəуелсіздік күні") + dts_observed.add(self._add_holiday_dec_16(name)) + if 2002 <= self._year <= 2021: + dts_observed.add(self._add_holiday_dec_17(name)) + + if self.observed: + self._populate_observed(dts_observed) + + if self._year >= 2006: + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Құрбан айт")) + + +class KZ(Kazakhstan): + pass + + +class KAZ(Kazakhstan): + pass + + +class KazakhstanIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2006: (JAN, 10), + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 27), + 2010: (NOV, 16), + 2011: (NOV, 6), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + } + + +class KazakhstanStaticHolidays: + """Kazakhstan special holidays. + + References: + * [2000](https://web.archive.org/web/20250428203427/https://adilet.zan.kz/kaz/docs/P000000642_) + * 2001: + * + * + * + * [2002](https://web.archive.org/web/20250428203447/https://adilet.zan.kz/kaz/docs/P020000466_) + * 2003: + * + * + * 2005: + * + * + * + * 2006: + * + * + * 2007: + * + * + * + * + * + * [2008](https://web.archive.org/web/20250428204634/https://adilet.zan.kz/kaz/docs/P080000364_) + * [2009](https://web.archive.org/web/20250428204627/https://adilet.zan.kz/kaz/docs/P090001936_) + * 2010: + * + * + * 2011: + * + * + * 2012: + * + * + * + * 2013: + * + * + * + * [2014](https://web.archive.org/web/20200715173002/http://adilet.zan.kz/kaz/docs/P1400000365) + * [2016](https://web.archive.org/web/20200225220136/http://adilet.zan.kz/kaz/docs/P1600000067) + * [2017](https://web.archive.org/web/20200203183402/http://adilet.zan.kz/kaz/docs/P1700000005) + * [2018](https://web.archive.org/web/20200226012057/http://adilet.zan.kz/kaz/docs/P1700000864) + * [2019](https://web.archive.org/web/20200630083024/http://adilet.zan.kz/kaz/docs/P1800000888) + * [2020](https://web.archive.org/web/20221023205506/https://adilet.zan.kz/kaz/docs/P1900000820) + * [2021](https://web.archive.org/web/20250428204757/https://adilet.zan.kz/kaz/docs/P2000000930) + * [2022](https://web.archive.org/web/20250428204753/https://adilet.zan.kz/kaz/docs/P2200000796) + * [2023](https://web.archive.org/web/20230928205344/https://adilet.zan.kz/kaz/docs/P2300000326) + * [2024](https://web.archive.org/web/20250108222408/https://adilet.zan.kz/kaz/docs/G24G0000109) + * [2025](https://web.archive.org/web/20250428203311/https://adilet.zan.kz/kaz/docs/G24G0000436) + """ + + # Substituted date format. + substituted_date_format = tr("%d.%m.%Y") + # Day off (substituted from %s). + substituted_label = tr("Демалыс күні (%s бастап ауыстырылды)") + + special_public_holidays = { + 2000: (MAY, 8, MAY, 6), + 2001: ( + (MAR, 9, MAR, 11), + (MAR, 23, MAR, 25), + (APR, 30, APR, 28), + (DEC, 31, DEC, 29), + ), + 2002: (MAY, 10, MAY, 12), + 2003: ( + (MAY, 2, MAY, 4), + (DEC, 15, DEC, 13), + ), + 2005: ( + (MAR, 7, MAR, 5), + (MAR, 21, MAR, 19), + (AUG, 29, AUG, 27), + (OCT, 24, OCT, 22), + ), + 2006: ( + (JAN, 11, JAN, 14), + (MAY, 8, MAY, 6), + ), + 2007: ( + (MAR, 9, MAR, 11), + (MAR, 23, MAR, 25), + (AUG, 31, SEP, 2), + (OCT, 26, OCT, 28), + (DEC, 31, DEC, 29), + ), + 2008: (MAY, 2, MAY, 4), + 2009: (DEC, 18, DEC, 20), + 2010: ( + (JAN, 8, JAN, 10), + (JUL, 5, JUL, 3), + ), + 2011: ( + (MAR, 7, MAR, 5), + (AUG, 29, AUG, 27), + ), + 2012: ( + (MAR, 9, MAR, 11), + (APR, 30, APR, 28), + (DEC, 31, DEC, 29), + ), + 2013: ( + (MAY, 10, MAY, 4), + (OCT, 14, OCT, 12), + ), + 2014: ( + (JAN, 3, DEC, 28, 2013), + (MAY, 2, MAY, 4), + (MAY, 8, MAY, 11), + ), + 2016: (MAR, 7, MAR, 5), + 2017: ( + (MAR, 20, MAR, 18), + (JUL, 7, JUL, 1), + ), + 2018: ( + (MAR, 9, MAR, 3), + (APR, 30, APR, 28), + (MAY, 8, MAY, 5), + (AUG, 31, AUG, 25), + (DEC, 31, DEC, 29), + ), + 2019: (MAY, 10, MAY, 4), + 2020: ( + (JAN, 3, JAN, 5), + (DEC, 18, DEC, 20), + ), + 2021: (JUL, 5, JUL, 3), + 2022: ( + (MAR, 7, MAR, 5), + (AUG, 29, AUG, 27), + (OCT, 24, OCT, 22), + ), + 2023: (JUL, 7, JUL, 1), + 2024: (MAY, 8, MAY, 4), + 2025: (JAN, 3, JAN, 5), + } + + special_public_holidays_observed = { + # Victory Day. + 2020: (MAY, 8, tr("Жеңіс күні")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/kenya.py b/.venv/lib/python3.12/site-packages/holidays/countries/kenya.py new file mode 100644 index 00000000..ad1aa44a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/kenya.py @@ -0,0 +1,259 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomHinduHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import FEB, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV +from holidays.constants import HINDU, ISLAMIC, PUBLIC +from holidays.groups import ( + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_WORKDAY + + +class Kenya( + ObservedHolidayBase, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Kenya holidays. + + References: + * + * [Public Holidays Act Cap. 110](https://web.archive.org/web/20250118013422/https://new.kenyalaw.org/akn/ke/act/1912/21/eng@2024-04-26) + * [Constitution of Kenya (Art. 9)](https://web.archive.org/web/20250417082347/https://new.kenyalaw.org/akn/ke/act/2010/constitution/eng@2010-09-03) + """ + + country = "KE" + default_language = "en_KE" + # %s (estimated). + estimated_label = tr("%s (estimated)") + # %s (observed). + observed_label = tr("%s (observed)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observed, estimated)") + supported_categories = (HINDU, ISLAMIC, PUBLIC) + supported_languages = ("en_KE", "en_US", "sw") + # Kenya gained independence on December 12, 1963. + start_year = 1964 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=KenyaHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=KenyaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=KenyaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 1985) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("New Year's Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Labor Day. + dts_observed.add(self._add_labor_day(tr("Labour Day"))) + + if self._year >= 2011: + # Madaraka Day. + dts_observed.add(self._add_holiday_jun_1(tr("Madaraka Day"))) + + if 1990 <= self._year <= 2009 or self._year >= 2018: + if self._year >= 2025: + # Mazingira Day. + name = tr("Mazingira Day") + elif self._year >= 2021: + # Utamaduni Day. + name = tr("Utamaduni Day") + else: + # Moi Day. + name = tr("Moi Day") + dts_observed.add(self._add_holiday_oct_10(name)) + + dts_observed.add( + self._add_holiday_oct_20( + # Mashujaa Day. + tr("Mashujaa Day") + if self._year >= 2011 + # Kenyatta Day. + else tr("Kenyatta Day") + ) + ) + + dts_observed.add( + self._add_holiday_dec_12( + # Jamhuri Day. + tr("Jamhuri Day") + if self._year >= 2011 + # Independence Day. + else tr("Independence Day") + ) + ) + + # Christmas Day. + dts_observed.add(self._add_christmas_day(tr("Christmas Day"))) + + # Boxing Day. + dts_observed.add(self._add_christmas_day_two(tr("Boxing Day"))) + + # Eid-al-Fitr. + dts_observed.update(self._add_eid_al_fitr_day(tr("Idd-ul-Fitr"))) + + if self.observed: + self._populate_observed(dts_observed) + + def _populate_hindu_holidays(self): + """Additional Hindu public holidays.""" + + if self._year >= 1984: + # Diwali. + self._add_diwali(tr("Diwali")) + + def _populate_islamic_holidays(self): + """Additional Islamic public holidays.""" + + # Eid-al-Adha. + self._add_eid_al_adha_day(tr("Idd-ul-Azha")) + + +class KE(Kenya): + pass + + +class KEN(Kenya): + pass + + +class KenyaHinduHolidays(_CustomHinduHolidays): + DIWALI_DATES = { + 2014: (OCT, 22), + 2015: (NOV, 10), + 2016: (OCT, 29), + 2017: (OCT, 18), + 2018: (NOV, 6), + 2019: (OCT, 28), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 24), + 2023: (NOV, 12), + 2024: (OCT, 31), + } + + +class KenyaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2014: (OCT, 6), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 21), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 11), + 2023: (JUN, 28), + 2024: (JUN, 17), + } + + EID_AL_FITR_DATES = { + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 25), + 2021: (MAY, 14), + 2022: (MAY, 3), + 2023: (APR, 21), + 2024: (APR, 10), + } + + +class KenyaStaticHolidays: + """Kenya special holidays. + + References: + * + * + * + * + * + * + * + * + * + * + """ + + # Election Day. + election_day = tr("Election Day") + + # Inauguration Day. + inauguration_day = tr("Inauguration Day") + + # Day of Mourning for Queen Elizabeth II. + mourning_for_queen_elizabeth = tr("Day of Mourning for Queen Elizabeth II") + + # National Tree Growing Day. + national_tree_growing_day = tr("National Tree Growing Day") + + special_public_holidays = { + # Visit of Pope Francis to Kenya. + 2015: (NOV, 26, tr("Visit of Pope Francis to Kenya")), + 2017: ( + (AUG, 8, election_day), + (OCT, 25, election_day), + (OCT, 26, election_day), + (NOV, 28, inauguration_day), + ), + # President Moi Memorial Day. + 2020: (FEB, 11, tr("President Moi Memorial Day")), + 2022: ( + # State Funeral for Former President Mwai Kibaki. + (APR, 29, tr("State Funeral for Former President Mwai Kibaki")), + (AUG, 9, election_day), + (SEP, 10, mourning_for_queen_elizabeth), + (SEP, 11, mourning_for_queen_elizabeth), + (SEP, 12, mourning_for_queen_elizabeth), + (SEP, 13, inauguration_day), + ), + 2023: (NOV, 13, national_tree_growing_day), + 2024: ( + (MAY, 10, national_tree_growing_day), + (NOV, 1, inauguration_day), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/kuwait.py b/.venv/lib/python3.12/site-packages/holidays/countries/kuwait.py new file mode 100644 index 00000000..a30aef11 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/kuwait.py @@ -0,0 +1,90 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import THU, FRI, SAT +from holidays.groups import InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Kuwait(HolidayBase, InternationalHolidays, IslamicHolidays): + """Kuwait holidays. + + References: + * + * + * + """ + + country = "KW" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # The resting days are Friday and Saturday since Sep 1, 2007. + # https://web.archive.org/web/20250414072729/https://www.arabnews.com/node/298933 + self.weekend = {THU, FRI} if self._year <= 2006 else {FRI, SAT} + + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + # National Day. + self._add_holiday_feb_25(tr("اليوم الوطني")) + + # Liberation Day. + self._add_holiday_feb_26(tr("يوم التحرير")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("عيد المولد النبوي")) + + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("ليلة المعراج")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("عيد الفطر")) + # Eid al-Fitr Holiday. + self._add_eid_al_fitr_day_two(tr("عطلة عيد الفطر")) + self._add_eid_al_fitr_day_three(tr("عطلة عيد الفطر")) + + # Arafat Day. + self._add_arafah_day(tr("يوم عرفة")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("عيد الأضحى")) + # Eid al-Adha Holiday. + self._add_eid_al_adha_day_two(tr("عطلة عيد الأضحى")) + self._add_eid_al_adha_day_three(tr("عطلة عيد الأضحى")) + + +class KW(Kuwait): + pass + + +class KWT(Kuwait): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/kyrgyzstan.py b/.venv/lib/python3.12/site-packages/holidays/countries/kyrgyzstan.py new file mode 100644 index 00000000..87bc5604 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/kyrgyzstan.py @@ -0,0 +1,94 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ChristianHolidays, IslamicHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Kyrgyzstan(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Kyrgyzstan holidays. + + References: + * + """ + + country = "KG" + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day("New Year's Day") + + # Orthodox Christmas. + self._add_christmas_day("Christmas Day") + + # Feb. 23 Fatherland Defender's Day. + self._add_holiday_feb_23("Fatherland Defender's Day") + + # International Women's Day. + self._add_womens_day("International Women's Day") + + # Nooruz Mairamy. + self._add_holiday_mar_21("Nooruz Mairamy") + + if self._year >= 2016: + # Day of the People's April Revolution. + self._add_holiday_apr_7("Day of the People's April Revolution") + + # International Workers' Day. + self._add_labor_day("International Workers' Day") + + # Constitution Day. + self._add_holiday_may_5("Constitution Day") + + # Victory Day. + self._add_world_war_two_victory_day("Victory Day", is_western=False) + + # Independence Day. + self._add_holiday_aug_31("Independence Day") + + # Days History and Commemoration of Ancestors. + name = "Days of History and Commemoration of Ancestors" + self._add_holiday_nov_7(name) + self._add_holiday_nov_8(name) + + # New Year's Eve. + self._add_new_years_eve("New Year's Eve") + + # Islamic Holidays. + # Orozo Ait. + name = "Orozo Ait" + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + + # Kurman Ait. + self._add_eid_al_adha_day("Kurman Ait") + + +class KG(Kyrgyzstan): + pass + + +class KGZ(Kyrgyzstan): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/laos.py b/.venv/lib/python3.12/site-packages/holidays/countries/laos.py new file mode 100644 index 00000000..767e2d22 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/laos.py @@ -0,0 +1,388 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, APR, JUL +from holidays.calendars.thai import KHMER_CALENDAR +from holidays.constants import BANK, PUBLIC, SCHOOL, WORKDAY +from holidays.groups import InternationalHolidays, ThaiCalendarHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class Laos(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiCalendarHolidays): + """Laos holidays. + + References: + * + * [Decree on Holidays No. 386 / Rev. 15.12.2017](https://web.archive.org/web/20250427180756/https://juristact.weebly.com/uploads/1/0/9/9/109947087/d17_386.pdf) + + Checked with: + * + * + * + * + * + * + * (from 2011 onwards) + + !!! note "If Public Holiday falls on weekends, (in lieu) on workday" + Despite the wording, this usually only applies to Monday only for holidays, + consecutive holidays all have their own special in lieu declared separately. + + As featured in Decree on Holidays No. 386: + - Saturdays and Sundays shall be restdays each week. + - In-Lieu holidays shall be given if it fall on the weekends. + + Although in-lieus has been de facto observed since at least 2012. + + Limitations: + - Laotian holidays only works from 1976 onwards, and are only 100% accurate from 2018 + onwards. + - Laotian Lunar Calendar Holidays only work from 1941 (B.E. 2485) onwards until 2157 + (B.E. 2701) as we only have Thai year-type data for cross-checking until then. + """ + + country = "LA" + supported_categories = (BANK, PUBLIC, SCHOOL, WORKDAY) + default_language = "lo" + # %s (in lieu). + observed_label = tr("ພັກຊົດເຊີຍ%s") + supported_languages = ("en_US", "lo", "th") + # Available post-Lao PDR proclamation on Dec 2, 1975. + start_year = 1976 + + def __init__(self, *args, **kwargs): + InternationalHolidays.__init__(self) + ThaiCalendarHolidays.__init__(self, KHMER_CALENDAR) + StaticHolidays.__init__(self, cls=LaosStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 2012) + super().__init__(*args, **kwargs) + + def _populate_bank_holidays(self): + # Based on both LSX and BCEL calendar. + + # ວັນສ້າງຕັ້ງທະນາຄານແຫ່ງ ສປປ ລາວ + # Status: In-Use. + # Celebrated the creation of the Bank of the Lao PDR on Oct 7, 1968. + # In-Lieus are available in LSX calendar. + + # Establishment Day of the BOL. + self._add_observed(self._add_holiday_oct_7(tr("ວັນສ້າງຕັ້ງທະນາຄານແຫ່ງ ສປປ ລາວ"))) + + # ສາມວັນລັດຖະການສຸດທ້າຍຂອງທຸກໆປີ + # Status: In-Use. + # Financial Institution in Laos are closed on last 3 weekdays of the year. + # Assume [WEEKDAY] is Dec 31: + # - CASE MON: (THU)-(FRI)-MON + # - CASE TUE: (FRI)-MON-TUE + # - CASE WED: MON-TUE-WED + # - CASE THU: TUE-WED-THU + # - CASE FRI/SAT/SUN: WED-THU-FRI + + # Lao Year-End Bank Holiday. + name = tr("ສາມວັນລັດຖະການສຸດທ້າຍຂອງທຸກໆປີ") + + last_workday = self._add_holiday( + name, self._get_next_workday(self._next_year_new_years_day, -1) + ) + second_to_last_workday = self._add_holiday(name, self._get_next_workday(last_workday, -1)) + self._add_holiday(name, self._get_next_workday(second_to_last_workday, -1)) + + def _populate_public_holidays(self): + # ວັນປີໃໝ່ສາກົນ + # Status: In-Use. + + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("ວັນປີໃໝ່ສາກົນ"))) + + # ວັນແມ່ຍິງສາກົນ + # Status: In-Use. + # Only acts as day off for Women. + # No in-lieus are observed in 2014. + + # International Women's Rights Day. + womens_day = self._add_womens_day(tr("ວັນແມ່ຍິງສາກົນ")) + if self._year != 2014: + self._add_observed(womens_day) + + # ບຸນປີໃໝ່ລາວ + # Status: In-Use. + # Celebrated for 3 days from 14-16 April annualy. + # Observed dates prior to 2018 are assigned manually. + + # Lao New Year's Day. + name = tr("ບຸນປີໃໝ່ລາວ") + songkran_years_apr_13_15 = {2012, 2017} + songkran_years_apr_13_16 = {2016, 2020, 2024} + dts_observed = set() + if self._year in songkran_years_apr_13_15.union(songkran_years_apr_13_16): + dts_observed.add(self._add_holiday_apr_13(name)) + dts_observed.add(self._add_holiday_apr_14(name)) + dts_observed.add(self._add_holiday_apr_15(name)) + if self._year not in songkran_years_apr_13_15: + dts_observed.add(self._add_holiday_apr_16(name)) + for dt in dts_observed: + self._add_observed(dt) + + # ວັນກຳມະກອນສາກົນ + # Status: In-Use. + + # International Labor Day. + self._add_observed(self._add_labor_day(tr("ວັນກຳມະກອນສາກົນ"))) + + # ວັນເດັກສາກົນ (`PUBLIC`) + # Status: Defunct, Still Observed. + # Starts as public holiday after Lao PDR joined UN Convention on the + # Rights of the Child in 1989 (de-facto start as holiday in 1990). + # Became defunct from 2018 onwards. Still accessible in `WORKDAY` category. + + if 1990 <= self._year <= 2017: + # International Children's Day. + self._add_childrens_day(tr("ວັນເດັກສາກົນ")) + + # ວັນຊາດ + # Status: In-Use. + # Celebrated the establishment of Lao PDR on Dec 2, 1975. + + # Lao National Day. + self._add_observed(self._add_holiday_dec_2(tr("ວັນຊາດ"))) + + def _populate_school_holidays(self): + # Laotian Lunar Calendar Holidays + # See `_ThaiLunisolar` in holidays/utils.py for more details. + # Unofficial, but observed by schools and most business holidays; + # As such, no in lieu observance are in place for these holidays. + + # Laotian Lunar Calendar Holidays only work from 1941 to 2157. + + # ວັນບຸນມາຂະບູຊາ + # Status: In-Use. + # 15th Waxing Day of Month 3. + # Also denoted as festival days for Sikhottabong Stupa Festival and + # Wat Phou Champasack Festival in BCEL calendar. + + # Makha Bousa Festival. + self._add_makha_bucha(tr("ວັນບຸນມາຂະບູຊາ")) + + # ວັນບຸນວິສາຂະບູຊາ + # Status: In-Use. + # 15th Waxing Day of Month 6. + # This utilizes Thai calendar as a base, though are calculated to always happen + # in the Traditional Visakhamas month (May). + # In Laos Calendar, the day after marks the traditional Buddhist Calendar Year change. + + # Visakha Bousa Festival. + self._add_visakha_bucha(tr("ວັນບຸນວິສາຂະບູຊາ")) + + # ວັນບຸນເຂົ້າພັນສາ + # Status: In-Use. + # 15th Waxing Day of Month 8 (Asarnha Bucha for Thailand and Cambodia). + + # Boun Khao Phansa (Begin of Buddhist Lent). + self._add_asarnha_bucha(tr("ວັນບຸນເຂົ້າພັນສາ")) + + # ວັນບຸນຫໍ່ເຂົ້າປະດັບດິນ + # Status: In-Use. + # 14th Waning Day of Month 9. + + # Boun Haw Khao Padapdin (Rice Growing Festival). + self._add_boun_haw_khao_padapdin(tr("ວັນບຸນຫໍ່ເຂົ້າປະດັບດິນ")) + + # ວັນບຸນຫໍ່ເຂົ້າສະຫຼາກ + # Status: In-Use. + # 15th Waxing Day of Month 10. + + # Boun Haw Khao Salark (Ancestor Festival). + self._add_boun_haw_khao_salark(tr("ວັນບຸນຫໍ່ເຂົ້າສະຫຼາກ")) + + # ວັນບຸນອອກພັນສາ + # Status: In-Use. + # 15th Waxing Day of Month 11. + + # Boun Awk Phansa (End of Buddhist Lent). + self._add_ok_phansa(tr("ວັນບຸນອອກພັນສາ")) + + # ວັນບຸນຊ່ວງເຮືອ ນະຄອນຫຼວງວຽງຈັນ + # Status: In-Use. + # 1st Waning Day of Month 11. + + # Boun Suang Heua (Vientiane Boat Racing Festival). + self._add_boun_suang_heua(tr("ວັນບຸນຊ່ວງເຮືອ ນະຄອນຫຼວງວຽງຈັນ")) + + # ວັນບຸນທາດຫລວງ + # Status: In-Use. + # 15th Waxing Day of Month 12. + + # Boun That Luang Festival. + self._add_loy_krathong(tr("ວັນບຸນທາດຫລວງ")) + + # ວັນຄູແຫ່ງຊາດ + # Status: In-Use. + # In recognition of First Lao Teacher, Kham, as started in Oct 7, 1994. + + if self._year >= 1994: + # National Teacher Day. + self._add_holiday_oct_7(tr("ວັນຄູແຫ່ງຊາດ")) + + def _populate_workday_holidays(self): + # No Public Holidays are issued, though still observed by the government. + + # ວັນສ້າງຕັ້ງກອງທັບປະຊາຊົນລາວ + # Status: In-Use. + # Celebrated the creation of the independent Lao army on Jan 20, 1949. + + # Lao People's Armed Force Day. + self._add_holiday_jan_20(tr("ວັນສ້າງຕັ້ງກອງທັບປະຊາຊົນລາວ")) + + # ວັນສ້າງຕັ້ງສະຫະພັນກໍາມະບານລາວ + # Status: In-Use. + # Celebrated the creation of Lao Federation of Trade Unions on Feb 1, 1966. + + # Lao Federation of Trade Union's Day. + self._add_holiday_feb_1(tr("ວັນສ້າງຕັ້ງສະຫະພັນກໍາມະບານລາວ")) + + # ວັນສ້າງຕັ້ງພັກປະຊາຊົນປະຕິວັດລາວ + # Status: In-Use. + # Celebrated the creation of the Lao People's Revolutionary Party on Mar 22, 1955. + + # Establishment Day of the Lao People's Revolutionary Party. + self._add_holiday_mar_22(tr("ວັນສ້າງຕັ້ງພັກປະຊາຊົນປະຕິວັດລາວ")) + + # ວັນສ້າງຕັ້ງສູນກາງຊາວໜຸ່ມປະຊາຊົນປະຕິວັດລາວ + # Status: In-Use. + # Celebrated the creation of the Lao People's Revolutionary Youth Union on Apr 14, 1955. + + # Lao People's Revolutionary Youth Union Day. + self._add_holiday_apr_14(tr("ວັນສ້າງຕັ້ງສູນກາງຊາວໜຸ່ມປະຊາຊົນປະຕິວັດລາວ")) + + # ວັນເດັກສາກົນ (`WORKDAY`) + # Status: Defunct, Still Observed. + # Starts as public holiday after Lao PDR joined UN Convention on the + # Rights of the Child in 1989 (de-facto start as holiday in 1990). + # Became defunct from 2018 onwards. Still accessible in `WORKDAY` category. + + if self._year >= 2018: + # International Children's Day. + self._add_childrens_day(tr("ວັນເດັກສາກົນ")) + + # ວັນປູກຕົ້ນໄມ້ແຫ່ງຊາດ + # Status: In-Use. + # Assumed to first observed in 1989 following the National Forestry Conference in May. + + if self._year >= 1989: + # National Arbor Day. + self._add_holiday_jun_1(tr("ວັນປູກຕົ້ນໄມ້ແຫ່ງຊາດ")) + + # ວັນຄ້າຍວັນເກີດ ທ່ານ ປະທານ ສຸພານຸວົງ + # Status: In-Use. + # Celebrated President Souphanouvong's Birthday Anniversary on Jul 13, 1909. + + # President Souphanouvong's Birthday. + self._add_holiday_jul_13(tr("ວັນຄ້າຍວັນເກີດ ທ່ານ ປະທານ ສຸພານຸວົງ")) + + # ວັນປ່ອຍປາ ແລະ ວັນອະນຸລັກສັດນ້ຳ-ສັດປ່າແຫ່ງຊາດ + # Status: In-Use. + # First designated in 1997 to concide with Souphanouvong's Birthday anniversary. + + if self._year >= 1997: + # The National Day for Wildlife and Aquatic Animal Conservation. + self._add_holiday_jul_13(tr("ວັນປ່ອຍປາ ແລະ ວັນອະນຸລັກສັດນ້ຳ-ສັດປ່າແຫ່ງຊາດ")) + + # ວັນສ້າງຕັ້ງສະຫະພັນແມ່ຍິງລາວ + # Status: In-Use. + # Celebrated the creation of Lao Women's Union on Jul 20, 1955. + + # Establishment Day of the Lao Women's Union. + self._add_holiday_jul_20(tr("ວັນສ້າງຕັ້ງສະຫະພັນແມ່ຍິງລາວ")) + + # ວັນສື່ມວນຊົນແຫ່ງຊາດ ແລະ ວັນພິມຈໍາໜ່າຍ + # Status: In-Use. + # Celebrated the creation of LPRP's Party Newspaper on Aug 13, 1950. + + # Lao National Mass Media and Publishing Day. + self._add_holiday_aug_13(tr("ວັນສື່ມວນຊົນແຫ່ງຊາດ ແລະ ວັນພິມຈໍາໜ່າຍ")) + + # ວັນລັດຖະທໍາມະນູນແຫ່ງຊາດ + # Status: In-Use. + # Celebrated the adoption of the 1991 Constitution on Aug 15, 1991. + + if self._year >= 1991: + # Lao National Constitution Day. + self._add_holiday_aug_15(tr("ວັນລັດຖະທໍາມະນູນແຫ່ງຊາດ")) + + # ວັນຍຶດອຳນາດທົ່ວປະເທດ + # Status: In-Use. + # Celebrated the Liberation of Vientiane by Pathet Lao forces on Aug 23, 1975. + + # National Uprising Day. + self._add_holiday_aug_23(tr("ວັນຍຶດອຳນາດທົ່ວປະເທດ")) + + # ວັນປະກາດເອກະລາດ + # Status: In-Use. + # Celebrated the Declaration of Independence on Oct 12, 1945. + + # Indepedence Declaration Day. + self._add_holiday_oct_12(tr("ວັນປະກາດເອກະລາດ")) + + # ວັນຄ້າຍວັນເກີດ ທ່ານ ປະທານ ໄກສອນ ພົມວິຫານ + # Status: In-Use. + # Celebrated President Kaysone Phomvihane's Birthday Anniversary on Dec 13, 1920. + + if self._year >= 1991: + # President Kaysone Phomvihane's Birthday. + self._add_holiday_dec_13(tr("ວັນຄ້າຍວັນເກີດ ທ່ານ ປະທານ ໄກສອນ ພົມວິຫານ")) + + +class LA(Laos): + pass + + +class LAO(Laos): + pass + + +class LaosStaticHolidays: + # Special Cases. + + # Special Bank Holiday. + special_bank_day_off = tr("ມື້ປິດການໃຫ້ບໍລິການຂອງທະນາຄານຕົວແທນ") + + # International Women's Rights Day. + international_womens_rights_day = tr("ວັນແມ່ຍິງສາກົນ") + + # Lao New Year's Day. + lao_new_year = tr("ບຸນປີໃໝ່ລາວ") + + # Lao New Year's Day (Special). + lao_new_year_special = tr("ພັກບຸນປີໃໝ່ລາວ") + + # Establishment Day of the Lao Women's Union. + lao_womens_union = tr("ວັນສ້າງຕັ້ງສະຫະພັນແມ່ຍິງລາວ") + + special_bank_holidays = { + 2015: (JAN, 2, special_bank_day_off), + } + + special_public_holidays = { + 2015: (APR, 17, lao_new_year_special), + } + + special_public_holidays_observed = { + 2011: (APR, 13, lao_new_year), + 2020: (APR, 17, lao_new_year), + } + + special_workday_holidays_observed = { + 2019: (JUL, 22, lao_womens_union), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/latvia.py b/.venv/lib/python3.12/site-packages/holidays/countries/latvia.py new file mode 100644 index 00000000..99309f94 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/latvia.py @@ -0,0 +1,124 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAY, JUL, SEP +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_MON + + +class Latvia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Latvia holidays. + + References: + * + * + * + """ + + country = "LV" + default_language = "lv" + # %s (observed). + observed_label = tr("%s (brīvdiena)") + supported_languages = ("en_US", "lv", "uk") + start_year = 1990 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, LatviaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Jaunais Gads")) + + # Good Friday. + self._add_good_friday(tr("Lielā Piektdiena")) + + # Easter Sunday. + self._add_easter_sunday(tr("Lieldienas")) + + # Easter Monday. + self._add_easter_monday(tr("Otrās Lieldienas")) + + # Labor Day. + self._add_labor_day(tr("Darba svētki")) + + if self._year >= 2002: + # Restoration of Independence Day. + dt = self._add_holiday_may_4(tr("Latvijas Republikas Neatkarības atjaunošanas diena")) + if self._year >= 2008: + self._add_observed(dt) + + # Mother's Day. + self._add_holiday_2nd_sun_of_may(tr("Mātes diena")) + + # Midsummer Eve. + self._add_holiday_jun_23(tr("Līgo diena")) + + # Midsummer Day. + self._add_saint_johns_day(tr("Jāņu diena")) + + # Republic of Latvia Proclamation Day. + dt = self._add_holiday_nov_18(tr("Latvijas Republikas proklamēšanas diena")) + if self._year >= 2007: + self._add_observed(dt) + + if self._year >= 2007: + # Christmas Eve. + self._add_christmas_eve(tr("Ziemassvētku vakars")) + + # Christmas Day. + self._add_christmas_day(tr("Ziemassvētki")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Otrie Ziemassvētki")) + + # New Year's Eve. + self._add_new_years_eve(tr("Vecgada vakars")) + + +class LV(Latvia): + pass + + +class LVA(Latvia): + pass + + +class LatviaStaticHolidays: + # General Latvian Song and Dance Festival closing day. + song_and_dance_festival_closing_day = tr( + "Vispārējo latviešu Dziesmu un deju svētku noslēguma dienu" + ) + # Day of His Holiness Pope Francis' pastoral visit to Latvia. + pope_francis_pastoral_visit_day = tr( + "Viņa Svētības pāvesta Franciska pastorālās vizītes Latvijā diena" + ) + # Day the Latvian hockey team won the bronze medal at the 2023 World Ice Hockey Championship. + hockey_team_win_bronze_medal_day = tr( + "Diena, kad Latvijas hokeja komanda ieguva bronzas medaļu 2023. gada " + "Pasaules hokeja čempionātā" + ) + special_public_holidays = { + 2018: ( + (JUL, 9, song_and_dance_festival_closing_day), + (SEP, 24, pope_francis_pastoral_visit_day), + ), + 2023: ( + (MAY, 29, hockey_team_win_bronze_medal_day), + (JUL, 10, song_and_dance_festival_closing_day), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/lebanon.py b/.venv/lib/python3.12/site-packages/holidays/countries/lebanon.py new file mode 100644 index 00000000..0fab16d1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/lebanon.py @@ -0,0 +1,448 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.constants import BANK, GOVERNMENT, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Lebanon(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Lebanon holidays. + + References: + * [Decree No. 35 of 1977](https://web.archive.org/web/20250704170408/http://legiliban.ul.edu.lb/LawArticles.aspx?LawTreeSectionID=204659&LawID=202420&language=ar) + * [Decree No. 2512 of 1985](https://web.archive.org/web/20250704170328/http://legiliban.ul.edu.lb/LawArticles.aspx?LawTreeSectionID=186992&LawID=184753&language=ar) + * [Decree No. 5112 of 1994](https://web.archive.org/web/20250704170257/http://legiliban.ul.edu.lb/LawArticles.aspx?LawTreeSectionID=173902&LawID=171663&language=ar) + * [Decree No. 15215 of 2005](https://web.archive.org/web/20250704170428/http://legiliban.ul.edu.lb/LawArticles.aspx?LawTreeSectionID=213954&LawID=211715&language=ar) + * [Decree No. 16237 of 2006](https://web.archive.org/web/20250704170424/http://legiliban.ul.edu.lb/LawArticles.aspx?LawTreeSectionID=215180&LawID=212941&language=ar) + * [Decree No. 3369 of 2010](https://web.archive.org/web/20250704170437/http://legiliban.ul.edu.lb/LawArticles.aspx?LawTreeSectionID=227216&LawID=224978&language=ar) + * + """ + + country = "LB" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + # %s (observed). + observed_label = tr("%s (يُحتفل به)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (يُحتفل به، المقدرة)") + start_year = 1978 + supported_categories = (BANK, GOVERNMENT, PUBLIC) + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=LebanonIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + if self._year >= 1995: + # Armenian Orthodox Christmas Day. + self._add_holiday_jan_6(tr("عيد الميلاد عند الطوائف الارمنية الارثوذكسية")) + + # Saint Maron's Day. + self._add_holiday_feb_9(tr("عيد مار مارون")) + + if 1995 <= self._year <= 2005 or self._year >= 2010: + # Feast of the Annunciation. + self._add_holiday_mar_25(tr("عيد بشارة السيدة مريم العذراء")) + + # Catholic Good Friday. + catholic_good_friday = self._add_good_friday(tr("الجمعة العظيمة عند الطوائف الكاثوليكية")) + + orthodox_good_friday = self._add_good_friday( + # Orthodox Good Friday. + tr("الجمعة العظيمة عند الطوائف الأرثوذكسية"), + calendar=JULIAN_CALENDAR, + ) + + if orthodox_good_friday == catholic_good_friday: + # Orthodox Holy Saturday. + self._add_holy_saturday(tr("سبت النور للطائفة الأرثوذكسية")) + + if 1986 <= self._year <= 1994: + catholic_easter_monday = self._add_easter_monday( + # Catholic Easter Monday. + tr("اثنين الفصح عند الطوائف الكاثوليكية") + ) + + orthodox_easter_monday = self._add_easter_monday( + # Orthodox Easter Monday. + tr("اثنين الفصح عند الطوائف الأرثوذكسية"), + calendar=JULIAN_CALENDAR, + ) + + if catholic_easter_monday == orthodox_easter_monday: + # Orthodox Easter Tuesday. + self._add_easter_tuesday(tr("ثلاثاء الفصح للطوائف الأرثوذكسية")) + + # Labor Day. + dt = self._add_labor_day(tr("عيد العمل")) + if self._year >= 1995: + self._add_observed(dt, rule=SUN_TO_NEXT_MON) + + # Martyrs' Day. + name = tr("عيد الشهداء") + if self._year <= 1993: + self._add_holiday_1st_sun_from_may_6(name) + elif self._year >= 2006: + self._add_holiday_1st_sun_of_may(name) + + if self._year >= 2006: + # Resistance and Liberation Day. + self._add_holiday_2nd_sun_of_may(tr("عيد المقاومة والتحرير")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("عيد انتقال العذراء")) + + if 1985 <= self._year <= 1993: + # All Saints' Day. + self._add_all_saints_day(tr("عيد جميع القديسين")) + + # Independence Day. + self._add_holiday_nov_22(tr("ذكرى الاستقلال")) + + # Christmas Day. + self._add_christmas_day(tr("عيد الميلاد")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("عيد رأس السنة الهجرية")) + + # Ashura. + self._add_ashura_day(tr("عاشوراء")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("ذكرى المولد النبوي الشريف")) + + # Eid al-Fitr. + name = tr("عيد الفطر") + self._add_eid_al_fitr_day(name) + if self._year >= 1986: + self._add_eid_al_fitr_day_two(name) + if self._year <= 1994: + self._add_eid_al_fitr_day_three(name) + + # Eid al-Adha. + name = tr("عيد الأضحى") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + if 1986 <= self._year <= 1993: + self._add_eid_al_adha_day_three(name) + + def _populate_bank_holidays(self): + if self._year >= 2020: + # Rafik Hariri Memorial Day. + self._add_holiday_feb_14(tr("يوم ذكرى رفيق الحريري")) + + # Catholic Easter Monday. + self._add_easter_monday(tr("اثنين الفصح عند الطوائف الكاثوليكية")) + + self._add_easter_monday( + # Orthodox Easter Monday. + tr("اثنين الفصح عند الطوائف الأرثوذكسية"), + calendar=JULIAN_CALENDAR, + ) + + def _populate_government_holidays(self): + if self._year >= 2020: + # Rafik Hariri Memorial Day. + self._add_holiday_feb_14(tr("يوم ذكرى رفيق الحريري")) + + if self._year >= 2021: + # Anniversary of the tragedy of Beirut port explosion. + self._add_holiday_aug_4(tr("ذكرى مأساة انفجار مرفأ بيروت")) + + +class LB(Lebanon): + pass + + +class LBN(Lebanon): + pass + + +class LebanonIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20250426220233/https://www.timeanddate.com/holidays/lebanon/first-day-ashura + ASHURA_DATES = { + 1978: (DEC, 11), + 1979: (NOV, 30), + 1980: (NOV, 18), + 1981: (NOV, 8), + 1982: (OCT, 28), + 1983: (OCT, 17), + 1984: (OCT, 6), + 1985: (SEP, 25), + 1986: (SEP, 15), + 1987: (SEP, 4), + 1988: (AUG, 23), + 1989: (AUG, 13), + 1990: (AUG, 2), + 1991: (JUL, 22), + 1992: (JUL, 11), + 1993: (JUN, 30), + 1994: (JUN, 19), + 1995: (JUN, 9), + 1996: (MAY, 28), + 1997: (MAY, 18), + 1998: (MAY, 7), + 1999: (APR, 26), + 2000: (APR, 15), + 2001: (APR, 4), + 2002: (MAR, 24), + 2003: (MAR, 14), + 2004: (MAR, 2), + 2005: (FEB, 19), + 2006: (FEB, 9), + 2007: (JAN, 29), + 2008: (JAN, 19), + 2009: ((JAN, 7), (DEC, 27)), + 2010: (DEC, 17), + 2011: (DEC, 6), + 2012: (NOV, 24), + 2013: (NOV, 14), + 2014: (NOV, 3), + 2015: (OCT, 24), + 2016: (OCT, 12), + 2017: (OCT, 1), + 2018: (SEP, 21), + 2019: (SEP, 10), + 2020: (AUG, 30), + 2021: (AUG, 19), + 2022: (AUG, 9), + 2023: (JUL, 28), + 2024: (JUL, 16), + } + + # https://web.archive.org/web/20250316072400/https://www.timeanddate.com/holidays/lebanon/eid-al-adha + EID_AL_ADHA_DATES = { + 1978: (NOV, 11), + 1979: (NOV, 1), + 1980: (OCT, 20), + 1981: (OCT, 9), + 1982: (SEP, 29), + 1983: (SEP, 18), + 1984: (SEP, 6), + 1985: (AUG, 27), + 1986: (AUG, 16), + 1987: (AUG, 6), + 1988: (JUL, 25), + 1989: (JUL, 14), + 1990: (JUL, 4), + 1991: (JUN, 23), + 1992: (JUN, 11), + 1993: (JUN, 1), + 1994: (MAY, 21), + 1995: (MAY, 10), + 1996: (APR, 29), + 1997: (APR, 18), + 1998: (APR, 8), + 1999: (MAR, 28), + 2000: (MAR, 16), + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + } + + # https://web.archive.org/web/20250216042303/https://www.timeanddate.com/holidays/lebanon/eid-al-fitr + EID_AL_FITR_DATES = { + 1978: (SEP, 4), + 1979: (AUG, 25), + 1980: (AUG, 13), + 1981: (AUG, 2), + 1982: (JUL, 23), + 1983: (JUL, 12), + 1984: (JUN, 30), + 1985: (JUN, 20), + 1986: (JUN, 9), + 1987: (MAY, 30), + 1988: (MAY, 18), + 1989: (MAY, 7), + 1990: (APR, 27), + 1991: (APR, 16), + 1992: (APR, 4), + 1993: (MAR, 25), + 1994: (MAR, 14), + 1995: (MAR, 3), + 1996: (FEB, 21), + 1997: (FEB, 9), + 1998: (JAN, 30), + 1999: (JAN, 19), + 2000: ((JAN, 8), (DEC, 28)), + 2001: (DEC, 17), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 17), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + # https://web.archive.org/web/20250428034326/https://www.timeanddate.com/holidays/lebanon/muharram + HIJRI_NEW_YEAR_DATES = { + 1978: (DEC, 2), + 1979: (NOV, 21), + 1980: (NOV, 9), + 1981: (OCT, 30), + 1982: (OCT, 19), + 1983: (OCT, 8), + 1984: (SEP, 27), + 1985: (SEP, 16), + 1986: (SEP, 6), + 1987: (AUG, 26), + 1988: (AUG, 14), + 1989: (AUG, 4), + 1990: (JUL, 24), + 1991: (JUL, 13), + 1992: (JUL, 2), + 1993: (JUN, 21), + 1994: (JUN, 10), + 1995: (MAY, 31), + 1996: (MAY, 19), + 1997: (MAY, 9), + 1998: (APR, 28), + 1999: (APR, 17), + 2000: (APR, 6), + 2001: (MAR, 26), + 2002: (MAR, 15), + 2003: (MAR, 5), + 2004: (FEB, 22), + 2005: (FEB, 10), + 2006: (JAN, 31), + 2007: (JAN, 20), + 2008: ((JAN, 10), (DEC, 29)), + 2009: (DEC, 18), + 2010: (DEC, 8), + 2011: (NOV, 27), + 2012: (NOV, 15), + 2013: (NOV, 5), + 2014: (OCT, 25), + 2015: (OCT, 14), + 2016: (OCT, 3), + 2017: (SEP, 22), + 2018: (SEP, 11), + 2019: (AUG, 31), + 2020: (AUG, 20), + 2021: (AUG, 9), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 7), + 2025: (JUN, 26), + } + + # https://web.archive.org/web/20240908071444/https://www.timeanddate.com/holidays/lebanon/prophet-birthday + MAWLID_DATES = { + 1978: (FEB, 20), + 1979: (FEB, 10), + 1980: (JAN, 30), + 1981: (JAN, 18), + 1982: ((JAN, 8), (DEC, 28)), + 1983: (DEC, 17), + 1984: (DEC, 6), + 1985: (NOV, 25), + 1986: (NOV, 15), + 1987: (NOV, 4), + 1988: (OCT, 23), + 1989: (OCT, 13), + 1990: (OCT, 2), + 1991: (SEP, 21), + 1992: (SEP, 10), + 1993: (AUG, 30), + 1994: (AUG, 19), + 1995: (AUG, 9), + 1996: (JUL, 28), + 1997: (JUL, 18), + 1998: (JUL, 7), + 1999: (JUN, 26), + 2000: (JUN, 15), + 2001: (JUN, 4), + 2002: (MAY, 24), + 2003: (MAY, 14), + 2004: (MAY, 2), + 2005: (APR, 21), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 16), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 20), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 15), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/lesotho.py b/.venv/lib/python3.12/site-packages/holidays/countries/lesotho.py new file mode 100644 index 00000000..d0eb3de4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/lesotho.py @@ -0,0 +1,92 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import MAY +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Lesotho(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Lesotho holidays. + + References: + * + * + * + """ + + country = "LS" + start_year = 1996 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, LesothoStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day("New Year's Day") + + # Moshoeshoe's Day. + self._add_holiday_mar_11("Moshoeshoe's Day") + + if self._year <= 2002: + # Heroes Day. + self._add_holiday_apr_4("Heroes Day") + + if self._year >= 2003: + # Africa/Heroes Day. + self._add_africa_day("Africa/Heroes Day") + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Workers' Day. + self._add_labor_day("Workers' Day") + + # Ascension Day. + self._add_ascension_thursday("Ascension Day") + + # https://en.wikipedia.org/wiki/Letsie_III + # King's Birthday. + name = "King's Birthday" + if self._year >= 1998: + self._add_holiday_jul_17(name) + else: + self._add_holiday_may_2(name) + + # Independence Day. + self._add_holiday_oct_4("Independence Day") + + # Christmas Day. + self._add_christmas_day("Christmas Day") + + # Boxing Day. + self._add_christmas_day_two("Boxing Day") + + +class LS(Lesotho): + pass + + +class LSO(Lesotho): + pass + + +class LesothoStaticHolidays: + special_public_holidays = { + 2002: (MAY, 25, "Africa Day"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/libya.py b/.venv/lib/python3.12/site-packages/holidays/countries/libya.py new file mode 100644 index 00000000..d9b398a0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/libya.py @@ -0,0 +1,227 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import InternationalHolidays, IslamicHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Libya(HolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays): + """Libya holidays. + + References: + * [Law No. 4 of 1987](https://web.archive.org/web/20250629084625/https://lawsociety.ly/legislation/قانون-رقم-4-لسنة-1987-م-بشأن-العطلات-الرسمية/) + * [Law No. 5 of 2012](https://web.archive.org/web/20250629084558/https://lawsociety.ly/legislation/القانون-رقم-5-لسنة-2012-م-بشأن-العطلات-الرسم/) + * [National Environmental Sanitation Day](https://web.archive.org/web/20250629084547/https://lawsociety.ly/legislation/قرار-رقم-414-لسنة-2021-م-باعتبار-يوم-14-أغسطس-يو/) + """ + + country = "LY" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + start_year = 1988 + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=LibyaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=LibyaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year <= 2011: + # People's Authority Day. + self._add_holiday_mar_2(tr("عید إعلان سلطة الشعب")) + + # American Forces Evacuation Day. + self._add_holiday_jun_11(tr("عيد إجلاء القوات الأمريكية")) + + # Glorious July Revolution Day. + self._add_holiday_jul_23(tr("عيد ثورة يوليو المجيدة")) + + # Great Al-Fateh Revolution Day. + self._add_holiday_sep_1(tr("عيد الفاتح العظيم")) + else: + # Anniversary of the February 17 Revolution. + self._add_holiday_feb_17(tr("ثورة 17 فبراير")) + + # Labor Day. + self._add_labor_day(tr("عيد العمال")) + + if self._year >= 2022: + # National Environmental Sanitation Day. + self._add_holiday_aug_14(tr("يوم وطني للإصحاح البيئي")) + + # Martyrs' Day. + self._add_holiday_sep_16(tr("يوم الشهيد")) + + # Liberation Day. + self._add_holiday_oct_23(tr("يوم التحرير")) + + # Independence Day. + self._add_holiday_dec_24(tr("عيد الاستقلال")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("عيد رأس السنة الهجرية")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("ذكرى المولد النبوي الشريف")) + + # Eid al-Fitr. + name = tr("عيد الفطر") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + self._add_eid_al_fitr_day_three(name) + + # Day of Arafah. + self._add_arafah_day(tr("يوم عرفة")) + + # Eid al-Adha. + name = tr("عيد الأضحى") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_eid_al_adha_day_three(name) + + def _populate_workday_holidays(self): + if self._year <= 2011: + # Syrian Revolution Day. + self._add_holiday_mar_8(tr("عيد ثورة سوريا")) + + # Anniversary of the Arab League. + self._add_holiday_mar_22(tr("ذكرى إنشاء الجامعة العربية")) + + # British Forces Evacuation Day. + self._add_holiday_mar_28(tr("عيد إجلاء القوات البريطانية")) + + # Italian Forces Evacuation Day. + self._add_holiday_oct_7(tr("عيد إجلاء الطليان")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("عيد رأس السنة الهجرية")) + + # Ashura. + self._add_ashura_day(tr("عاشوراء")) + + # Isra and Mi'raj. + self._add_isra_and_miraj_day(tr("ذكرى الإسراء والمعراج")) + + # Night of Forgiveness. + self._add_imam_mahdi_birthday_day(tr("ليلة النصف من شعبان")) + + +class LY(Libya): + pass + + +class LBY(Libya): + pass + + +class LibyaIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20240908234803/https://www.timeanddate.com/holidays/libya/eid-al-adha + # https://web.archive.org/web/20250629084537/https://lawsociety.ly/legislation/قرار-رقم-773-لسنة-2017-م-بشأن-تحديد-عطلة-عيد-ال/ + EID_AL_ADHA_DATES = { + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 23), + 2016: (SEP, 11), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + } + + # https://web.archive.org/web/20241012125707/https://www.timeanddate.com/holidays/libya/eid-al-fitr + EID_AL_FITR_DATES = { + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + # https://web.archive.org/web/20250418094505/https://www.timeanddate.com/holidays/libya/muharram-new-year + HIJRI_NEW_YEAR_DATES = { + 2012: (NOV, 15), + 2013: (NOV, 5), + 2014: (OCT, 25), + 2015: (OCT, 15), + 2016: (OCT, 3), + 2017: (SEP, 22), + 2018: (SEP, 12), + 2019: (AUG, 31), + 2020: (AUG, 20), + 2021: (AUG, 10), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 7), + 2025: (JUN, 26), + } + + # https://web.archive.org/web/20241213175353/https://www.timeanddate.com/holidays/libya/prophet-birthday + # https://web.archive.org/web/20250629084607/https://lawsociety.ly/legislation/قرار-رقم-1299-لسنة-2019-م-بشأن-عطلة-ذكرى-المولد/ + MAWLID_DATES = { + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 23)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 15), + } + + +class LibyaStaticHolidays: + """Libya special holidays. + + References: + * + """ + + special_public_holidays = { + # Public Holiday. + 2023: (DEC, 10, tr("عطلة رسمية")) + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/liechtenstein.py b/.venv/lib/python3.12/site-packages/holidays/countries/liechtenstein.py new file mode 100644 index 00000000..f2856dd5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/liechtenstein.py @@ -0,0 +1,112 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import BANK, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Liechtenstein(HolidayBase, ChristianHolidays, InternationalHolidays): + """Liechtenstein holidays. + + References: + * + * + """ + + country = "LI" + default_language = "de" + supported_categories = (BANK, PUBLIC) + supported_languages = ("de", "en_US", "uk") + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Neujahr")) + + # Epiphany. + self._add_epiphany_day(tr("Heilige Drei Könige")) + + # Candlemas. + self._add_candlemas(tr("Mariä Lichtmess")) + + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("Josefstag")) + + # Easter Sunday. + self._add_easter_sunday(tr("Ostersonntag")) + + # Easter Monday. + self._add_easter_monday(tr("Ostermontag")) + + # Labor Day. + self._add_labor_day(tr("Tag der Arbeit")) + + # Ascension Day. + self._add_ascension_thursday(tr("Auffahrt")) + + # Whit Sunday. + self._add_whit_sunday(tr("Pfingstsonntag")) + + # Whit Monday. + self._add_whit_monday(tr("Pfingstmontag")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Fronleichnam")) + + # National Day. + self._add_assumption_of_mary_day(tr("Staatsfeiertag")) + + # Nativity of Mary. + self._add_nativity_of_mary_day(tr("Mariä Geburt")) + + # All Saints' Day. + self._add_all_saints_day(tr("Allerheiligen")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + # Christmas Day. + self._add_christmas_day(tr("Weihnachten")) + + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_bank_holidays(self): + # Saint Berchtold's Day. + self._add_new_years_day_two(tr("Berchtoldstag")) + + # Shrove Tuesday. + self._add_carnival_tuesday(tr("Fasnachtsdienstag")) + + # Good Friday. + self._add_good_friday(tr("Karfreitag")) + + # Christmas Eve. + self._add_christmas_eve(tr("Heiligabend")) + + # New Year's Eve. + self._add_new_years_eve(tr("Silvester")) + + +class LI(Liechtenstein): + pass + + +class LIE(Liechtenstein): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/lithuania.py b/.venv/lib/python3.12/site-packages/holidays/countries/lithuania.py new file mode 100644 index 00000000..6ac4aec1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/lithuania.py @@ -0,0 +1,97 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Lithuania(HolidayBase, ChristianHolidays, InternationalHolidays): + """Lithuania holidays. + + References: + * + * + """ + + country = "LT" + default_language = "lt" + supported_languages = ("en_US", "lt", "uk") + start_year = 1990 + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self) -> None: + # New Year's Day. + self._add_new_years_day(tr("Naujųjų metų diena")) + + # Day of Restoration of the State of Lithuania. + self._add_holiday_feb_16(tr("Lietuvos valstybės atkūrimo diena")) + + # Day of Restoration of Independence of Lithuania. + self._add_holiday_mar_11(tr("Lietuvos nepriklausomybės atkūrimo diena")) + + # Easter Sunday. + self._add_easter_sunday(tr("Šv. Velykos")) + + # Easter Monday. + self._add_easter_monday(tr("Antroji šv. Velykų diena")) + + # International Workers' Day. + self._add_labor_day(tr("Tarptautinė darbo diena")) + + # Mother's Day. + self._add_holiday_1st_sun_of_may(tr("Motinos diena")) + + # Father's Day. + self._add_holiday_1st_sun_of_jun(tr("Tėvo diena")) + + if self._year >= 2003: + # Day of Dew and Saint John. + self._add_saint_johns_day(tr("Rasos ir Joninių diena")) + + if self._year >= 1991: + self._add_holiday_jul_6( + # Statehood Day. + tr("Valstybės (Lietuvos karaliaus Mindaugo karūnavimo) ir Tautiškos giesmės diena") + ) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Žolinė (Švč. Mergelės Marijos ėmimo į dangų diena)")) + + # All Saints' Day. + self._add_all_saints_day(tr("Visų Šventųjų diena")) + + if self._year >= 2020: + # All Souls' Day. + self._add_all_souls_day(tr("Mirusiųjų atminimo (Vėlinių) diena")) + + # Christmas Eve. + self._add_christmas_eve(tr("Kūčių diena")) + + # Christmas Day. + self._add_christmas_day(tr("Šv. Kalėdų pirma diena")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Šv. Kalėdų antra diena")) + + +class LT(Lithuania): + pass + + +class LTU(Lithuania): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/luxembourg.py b/.venv/lib/python3.12/site-packages/holidays/countries/luxembourg.py new file mode 100644 index 00000000..b77da52e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/luxembourg.py @@ -0,0 +1,76 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Luxembourg(HolidayBase, ChristianHolidays, InternationalHolidays): + """Luxembourg holidays. + + References: + * + """ + + country = "LU" + default_language = "lb" + supported_languages = ("de", "en_US", "fr", "lb", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Neijoerschdag")) + + # Easter Monday. + self._add_easter_monday(tr("Ouschterméindeg")) + + # Labor Day. + self._add_labor_day(tr("Dag vun der Aarbecht")) + + if self._year >= 2019: + # Europe Day. + self._add_europe_day(tr("Europadag")) + + # Ascension Day. + self._add_ascension_thursday(tr("Christi Himmelfaart")) + + # Whit Monday. + self._add_whit_monday(tr("Péngschtméindeg")) + + # National Day. + self._add_holiday_jun_23(tr("Nationalfeierdag")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Léiffrawëschdag")) + + # All Saints' Day. + self._add_all_saints_day(tr("Allerhellgen")) + + # Christmas Day. + self._add_christmas_day(tr("Chrëschtdag")) + + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Stiefesdag")) + + +class LU(Luxembourg): + pass + + +class LUX(Luxembourg): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/macau.py b/.venv/lib/python3.12/site-packages/holidays/countries/macau.py new file mode 100644 index 00000000..1745c7d1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/macau.py @@ -0,0 +1,480 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import FEB, SEP, OCT, DEC +from holidays.constants import GOVERNMENT, MANDATORY, PUBLIC +from holidays.groups import ( + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SUN_TO_NEXT_WORKDAY, + SAT_SUN_TO_NEXT_WORKDAY, +) + + +class Macau( + ObservedHolidayBase, + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + StaticHolidays, +): + """Macau holidays. + + References: + * [Decreto-Lei n.º 4/82/M](https://web.archive.org/web/20250422171106/https://bo.io.gov.mo/bo/i/82/04/declei04.asp) + * [Decreto-Lei n.º 38/87/M](https://web.archive.org/web/20250421204103/https://bo.io.gov.mo/bo/i/87/25/declei38.asp) + * [Decreto-Lei n.º 15/93/M](https://web.archive.org/web/20250421233338/https://bo.io.gov.mo/bo/i/93/17/declei15.asp) + * [Decreto-Lei n.º 7/97/M](https://web.archive.org/web/20250421102457/https://bo.io.gov.mo/bo/i/97/11/declei07.asp) + * [Portaria n.º 85/97/M](https://web.archive.org/web/20250421075645/https://bo.io.gov.mo/bo/i/97/15/port85.asp) + * [Portaria n.º 242/98/M](https://web.archive.org/web/20250421194357/https://bo.io.gov.mo/bo/i/98/48/port242.asp) + * [Regulamento Administrativo n.º 4/1999](https://web.archive.org/web/20250421071204/https://bo.io.gov.mo/bo/i/1999/01/regadm04.asp) + * [Regulamento Administrativo n.º 5/1999](https://web.archive.org/web/20240529183711/https://bo.io.gov.mo/bo/i/1999/01/regadm05.asp) + * [Ordem Executiva n.º 60/2000](https://web.archive.org/web/20250421064911/https://bo.io.gov.mo/bo/i/2000/40/ordem60.asp) + * [Lei n.º 27/2024](https://web.archive.org/web/20250404201226/https://bo.io.gov.mo/bo/i/2025/01/lei27.asp) + + Mandatory Holidays References: + * [Decreto-Lei n.º 101/84/M](https://web.archive.org/web/20240518230957/https://bo.io.gov.mo/bo/i/84/35/declei101.asp) + * [Decreto-Lei n.º 24/89/M](https://web.archive.org/web/20241215223116/https://bo.io.gov.mo/bo/i/89/14/declei24.asp) + * [Lei n.º 8/2000](https://web.archive.org/web/20240303230903/https://bo.io.gov.mo/bo/i/2000/19/lei08.asp) + * [Lei n.º 7/2008](https://web.archive.org/web/20250403121227/https://bo.io.gov.mo/bo/i/2008/33/lei07.asp) + + Cross-Checking: + * [Public Holidays for 2017-2025](https://web.archive.org/web/20210509143637/https://www.gov.mo/en/public-holidays/year-2017/) + * [Public Holidays for 2005-2018](https://web.archive.org/web/20171207162948/http://portal.gov.mo/web/guest/info_detail?infoid=1887061) + * [Mandatory Holidays for 2009-2029](https://web.archive.org/web/20250421090753/https://www.dsal.gov.mo/pt/standard/holiday_table.html) + """ + + country = "MO" + default_language = "zh_MO" + # Decreto-Lei n.º 4/82/M. + start_year = 1982 + subdivisions = ( + "I", # Ilhas. + "M", # Macau. + ) + subdivisions_aliases = { + # Municipalities. + "Concelho das Ilhas": "I", + "海島市": "I", + "海岛市": "I", + "Concelho de Macau": "M", + "澳門市": "M", + "澳门市": "M", + } + supported_categories = (GOVERNMENT, MANDATORY, PUBLIC) + supported_languages = ("en_MO", "en_US", "pt_MO", "th", "zh_CN", "zh_MO") + + def __init__(self, *args, **kwargs): + ChineseCalendarHolidays.__init__(self) + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, MacauStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + # Systemic in-lieus starts in 2011. + kwargs.setdefault("observed_since", 2011) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("元旦")) + + # Chinese New Year's Day. + self._add_chinese_new_years_day(tr("農曆正月初一")) + + # The second day of Chinese New Year. + self._add_chinese_new_years_day_two(tr("農曆正月初二")) + + # The third day of Chinese New Year. + self._add_chinese_new_years_day_three(tr("農曆正月初三")) + + # Tomb-Sweeping Day. + self._add_qingming_festival(tr("清明節")) + + # Regulamento Administrativo n.º 4/1999 - Name changed in Chinese for Good Friday. + name = ( + # Good Friday. + tr("耶穌受難日") + if self._year >= 2000 + # Good Friday. + else tr("聖周星期五") + ) + self._add_good_friday(name) + + # Regulamento Administrativo n.º 4/1999 - Name changed to The Day before Easter. + name = ( + # The Day before Easter. + tr("復活節前日") + if self._year >= 2000 + # Holy Saturday. + else tr("聖周星期六") + ) + self._add_holy_saturday(name) + + # Labor Day. + self._add_labor_day(tr("勞動節")) + + # Dragon Boat Festival. + self._add_dragon_boat_festival(tr("端午節")) + + # Double Ninth Festival. + self._add_double_ninth_festival(tr("重陽節")) + + # The Day following Mid-Autumn Festival. + self._add_mid_autumn_festival_day_two(tr("中秋節翌日")) + + # National Day of the People's Republic of China. + self._add_holiday_oct_1(tr("中華人民共和國國慶日")) + + # All Soul's Day. + self._add_all_souls_day(tr("追思節")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("聖母無原罪瞻禮")) + + # Regulamento Administrativo n.º 4/1999 - Moved from DEC 22 to DEC 21. + # Ordem Executiva n.º 60/2000 - Switched to Movable. + + # Winter Solstice. + name = tr("冬至") + if self._year >= 2001: + self._add_dongzhi_festival(name) + elif self._year == 2000: + self._add_holiday_dec_21(name) + else: + self._add_holiday_dec_22(name) + + # Portaria n.º 242/98/M - Name changed in Chinese for Christmas Eve. + # Regulamento Administrativo n.º 4/1999 - Further Chinese name standardization. + if self._year >= 2000: + # Christmas Eve. + name = tr("聖誕節前日") + elif self._year == 1999: + # Christmas Eve. + name = tr("聖誕節前夕") + else: + # Christmas Eve. + name = tr("聖誕前夕") + self._add_christmas_eve(name) + + # Portaria n.º 242/98/M - Name changed in Chinese for Christmas Day. + name = ( + # Christmas Day. + tr("聖誕節") + if self._year >= 1999 + # Christmas Day. + else tr("聖誕") + ) + self._add_christmas_day(name) + + # Decreto-Lei n.º 38/87/M - Removed Assumption Day and All Saints' Day as Public Holiday. + if self._year <= 1986: + # Assumption Day. + self._add_assumption_of_mary_day(tr("聖母升天")) + + # All Saints' Day. + self._add_all_saints_day(tr("諸聖節")) + + # Decreto-Lei n.º 38/87/M - Removed Corpus Christi as Public Holiday. + if self._year <= 1987: + # Corpus Christi. + self._add_corpus_christi_day(tr("基督聖體聖血節")) + + # Portaria n.º 242/98/M - De Facto adds Macao S.A.R. Establishment Day on DEC 20 for 1999. + # Regulamento Administrativo n.º 5/1999 - Special Name for 1999 (see StaticHolidays). + # Ordem Executiva n.º 60/2000 - Removed all Portugal-derived holidays. + # - Adds The Buddha's Birthday. + # - Adds The day following National Day of the PRC on OCT 2. + # - Adds "Anniversary of " to Macao S.A.R. holiday in Chinese. + if self._year <= 1999: + # Freedom Day. + self._add_holiday_apr_25(tr("自由日")) + + # Day of Portugal, Camões, and the Portuguese Communities. + self._add_holiday_jun_10(tr("葡國日、賈梅士日暨葡僑日")) + + # Republic Day. + self._add_holiday_oct_5(tr("葡萄牙共和國國慶日")) + + # Restoration of Independence Day. + self._add_holiday_dec_1(tr("恢復獨立紀念日")) + else: + # The Buddha's Birthday. + self._add_chinese_birthday_of_buddha(tr("佛誕節")) + + # The day following National Day of the People's Republic of China. + self._add_holiday_oct_2(tr("中華人民共和國國慶日翌日")) + + # Macao S.A.R. Establishment Day. + self._add_holiday_dec_20(tr("澳門特別行政區成立紀念日")) + + def _populate_mandatory_holidays(self): + """ + Decreto-Lei n.º 101/84/M - Earliest Available Version Online. + Decreto-Lei n.º 24/89/M - Added Ching Ming Festival. + Lei n.º 8/2000 - Removed Day of Portugal + - Added Macao S.A.R. Establishment Day. + - Moved Mid-Autumn to Day following Mid-Autumn to match Public Holidays. + Lei n.º 7/2008 - Consolidated with other laws, reaffirming 2000 Amendment list. + """ + if self._year <= 1984: + return None + + # New Year's Day. + self._add_new_years_day(tr("元旦")) + + # Chinese New Year's Day. + self._add_chinese_new_years_day(tr("農曆正月初一")) + + # The second day of Chinese New Year. + self._add_chinese_new_years_day_two(tr("農曆正月初二")) + + # The third day of Chinese New Year. + self._add_chinese_new_years_day_three(tr("農曆正月初三")) + + # Labor Day. + self._add_labor_day(tr("勞動節")) + + # Double Ninth Festival. + self._add_double_ninth_festival(tr("重陽節")) + + # National Day of the People's Republic of China. + self._add_holiday_oct_1(tr("中華人民共和國國慶日")) + + # Decreto-Lei n.º 24/89/M - Adds Ching Ming as a Mandatory Holiday. + if self._year >= 1989: + # Tomb-Sweeping Day. + self._add_qingming_festival(tr("清明節")) + + # Lei n.º 8/2000 - Removed Day of Portugal as a Mandatory Holiday. + # - Changed observance from Mid-Autumn to the following day. + # - Adds Macao S.A.R. Establishment Day as a Mandatory Holiday. + if self._year <= 1999: + # Day of Portugal, Camões, and the Portuguese Communities. + self._add_holiday_jun_10(tr("葡國日、賈梅士日暨葡僑日")) + + # Mid-Autumn Festival. + self._add_mid_autumn_festival(tr("中秋節")) + + else: + # The Day following Mid-Autumn Festival. + self._add_mid_autumn_festival_day_two(tr("中秋節翌日")) + + # Macao S.A.R. Establishment Day. + self._add_holiday_dec_20(tr("澳門特別行政區成立紀念日")) + + def _populate_government_holidays(self): + # While Cross-Checking References are available for from 2005-2025, + # SUN in-lieus starts in 2011; SAT-SUN in-lieus starts in 2012. + if self._year <= 2004: + return None + + dts_observed = set() + + # %s (Afternoon). + begin_time_label = self.tr("%s(下午)") + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("元旦"))) + + if self._year not in {2006, 2007, 2009, 2010, 2012, 2013, 2016, 2023}: + # Chinese New Year's Eve. + self._add_chinese_new_years_eve(begin_time_label % self.tr("農曆除夕")) + + if self._year in {2006, 2007, 2010, 2013, 2014, 2017, 2018}: + # The fourth day of Chinese New Year. + self._add_chinese_new_years_day_four(tr("農曆正月初四")) + + if self._year in {2014, 2015, 2017, 2018}: + # The fifth day of Chinese New Year. + self._add_chinese_new_years_day_five(tr("農曆正月初五")) + + if self._year >= 2019: + # Chinese New Year's Day. + dts_observed.add(self._add_chinese_new_years_day(tr("農曆正月初一"))) + + # The second day of Chinese New Year. + dts_observed.add(self._add_chinese_new_years_day_two(tr("農曆正月初二"))) + + # The third day of Chinese New Year. + dts_observed.add(self._add_chinese_new_years_day_three(tr("農曆正月初三"))) + + # The Day before Easter. + dts_observed.add(self._add_holy_saturday(tr("復活節前日"))) + + # Tomb-Sweeping Day. + dts_observed.add(self._add_qingming_festival(tr("清明節"))) + + # Labor Day. + dts_observed.add(self._add_labor_day(tr("勞動節"))) + + # The Buddha's Birthday. + dts_observed.add(self._add_chinese_birthday_of_buddha(tr("佛誕節"))) + + # Dragon Boat Festival. + dts_observed.add(self._add_dragon_boat_festival(tr("端午節"))) + + # The Day following Mid-Autumn Festival. + dts_observed.add(self._add_mid_autumn_festival_day_two(tr("中秋節翌日"))) + + # Double Ninth Festival. + dts_observed.add(self._add_double_ninth_festival(tr("重陽節"))) + + # National Day of the People's Republic of China. + dts_observed.add(self._add_holiday_oct_1(tr("中華人民共和國國慶日"))) + + # The day following National Day of the People's Republic of China. + dts_observed.add(self._add_holiday_oct_2(tr("中華人民共和國國慶日翌日"))) + + # All Soul's Day. + dts_observed.add(self._add_all_souls_day(tr("追思節"))) + + # Immaculate Conception. + dts_observed.add(self._add_immaculate_conception_day(tr("聖母無原罪瞻禮"))) + + # Macao S.A.R. Establishment Day. + dts_observed.add(self._add_holiday_dec_20(tr("澳門特別行政區成立紀念日"))) + + # Winter Solstice. + dts_observed.add(self._add_dongzhi_festival(tr("冬至"))) + + # Christmas Eve. + dts_observed.add(self._add_christmas_eve(tr("聖誕節前日"))) + + # Christmas Day. + dts_observed.add(self._add_christmas_day(tr("聖誕節"))) + + # 2012's Full-Day New Year's Eve is declared discretely. + if self._year >= 2007 and self._year not in {2011, 2012, 2016, 2017, 2022, 2023}: + # New Year's Eve. + self._add_new_years_eve(begin_time_label % self.tr("除夕")) + + if self.observed: + self.observed_label = ( + # Compensatory rest day for %s. + self.tr("%s的補假") + if self._year >= 2020 + # The first working day after %s. + else self.tr("%s後首個工作日") + ) + # Prior to 2012, in-lieus are only given for holidays which falls on Sunday. + self._observed_rule = ( + SUN_TO_NEXT_WORKDAY if self._year <= 2011 else SAT_SUN_TO_NEXT_WORKDAY + ) + self._populate_observed(dts_observed, multiple=True) + + def _populate_subdiv_i_public_holidays(self): + # Decreto-Lei n.º 15/93/M - Moved Day of the Municipality of Ilhas from JUL 13 to NOV 30. + # Regulamento Administrativo n.º 4/1999 - Removed as a Public Holiday. + if self._year <= 1999: + # Day of the Municipality of Ilhas. + name = tr("海島市日") + if self._year <= 1992: + self._add_holiday_nov_30(name) + else: + self._add_holiday_jul_13(name) + + def _populate_subdiv_m_public_holidays(self): + # Regulamento Administrativo n.º 4/1999 - Removed Macau City Day as a Public Holiday. + if self._year <= 1999: + # Macau City Day. + self._add_holiday_jun_24(tr("澳門市日")) + + +class MO(Macau): + pass + + +class MAC(Macau): + pass + + +class MacauStaticHolidays: + """Macau special holidays. + + Special Public and Government Holidays: + * + + Special Mandatory Holidays: + * + + Cross-Checking: + * [Public Holidays for 2017-2025](https://web.archive.org/web/20210509143637/https://www.gov.mo/en/public-holidays/year-2017/) + * [Public Holidays for 2005-2018](https://web.archive.org/web/20171207162948/http://portal.gov.mo/web/guest/info_detail?infoid=1887061) + """ + + # Additional Public Holiday. + name_fullday = tr("額外公眾假期") + + # Additional Half-Day Public Holiday. + name_halfday = tr("額外公眾半日假") + + # 70th Anniversary of the Victory of the Chinese People's War of Resistance against + # Japanese Aggression and the World Anti-Fascist War. + name_70th_war_of_resistance = tr("中國人民抗日戰爭暨世界反法西斯戰爭勝利七十周年紀念日") + + # Overlapping of the Day following National Day of the People's Republic of China + # and the Day following Mid-Autumn Festival. + name_mid_autumn_festival_day_2_national_day_2_overlap = tr( + "中華人民共和國國慶日翌日及中秋節翌日重疊" + ) + + # Overlapping of the Day following National Day of the People's Republic of China + # and the Double Ninth Festival. + name_double_ninth_festival_national_day_2_overlap = tr("中華人民共和國國慶日翌日及重陽節重疊") + + # Overlapping of the National Day of the People's Republic of China + # and the Day following Mid-Autumn Festival. + name_mid_autumn_festival_day_2_national_day_overlap = tr( + "中華人民共和國國慶日及中秋節翌日重疊" + ) + + # New Year's Eve. + name_new_years_eve = tr("除夕") + + special_government_holidays = { + # Additional Government Holiday. + 2008: (DEC, 22, tr("額外政府假期")), + 2012: ( + (OCT, 3, name_mid_autumn_festival_day_2_national_day_overlap), + (DEC, 31, name_new_years_eve), + ), + 2014: (OCT, 3, name_double_ninth_festival_national_day_2_overlap), + 2020: (OCT, 5, name_mid_autumn_festival_day_2_national_day_2_overlap), + } + special_mandatory_holidays = { + 2015: (SEP, 3, name_70th_war_of_resistance), + } + special_public_holidays = { + 1998: ( + (DEC, 23, name_fullday), + (DEC, 31, name_halfday), + ), + 1999: ( + (FEB, 15, name_fullday), + # The Handover of Macau to China and the Establishment of the Macau + # Special Administrative Region of the People's Republic of China. + (DEC, 20, tr("澳門回歸祖國暨中華人民共和國澳門特別行政區成立日")), + # The day following the Handover of Macau to China and the Establishment of the Macau + # Special Administrative Region of the People's Republic of China. + (DEC, 21, tr("澳門回歸祖國暨中華人民共和國澳門特別行政區成立日翌日")), + (DEC, 31, name_halfday), + ), + 2000: (FEB, 4, name_halfday), + 2015: (SEP, 3, name_70th_war_of_resistance), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/madagascar.py b/.venv/lib/python3.12/site-packages/holidays/countries/madagascar.py new file mode 100644 index 00000000..9e24582a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/madagascar.py @@ -0,0 +1,99 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAY, SUN, _timedelta, _get_nth_weekday_of_month +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Madagascar(HolidayBase, ChristianHolidays, InternationalHolidays): + """Madagascar holidays. + + References: + * + * + """ + + country = "MG" + default_language = "mg" + supported_languages = ("en_US", "mg", "uk") + start_year = 1947 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Taom-baovao")) + + # Women's Day. + self._add_womens_day(tr("Fetin'ny vehivavy")) + + # Martyrs' Day. + self._add_holiday_mar_29(tr("Fetin'ny mahery fo")) + + # Easter Sunday. + self._add_easter_sunday(tr("Fetin'ny paska")) + + # Easter Monday. + self._add_easter_monday(tr("Alatsinain'ny paska")) + + # Labor Day. + self._add_labor_day(tr("Fetin'ny asa")) + + # Ascension Day. + self._add_ascension_thursday(tr("Fiakaran'ny Jesosy kristy tany an-danitra")) + + # Whit Sunday. + whit_sunday = self._add_whit_sunday(tr("Pentekosta")) + + # Whit Monday. + self._add_whit_monday(tr("Alatsinain'ny pentekosta")) + + last_sun_of_may = _get_nth_weekday_of_month(-1, SUN, MAY, self._year) + self._add_holiday( + # Mother's Day. + tr("Fetin'ny reny"), + _timedelta(last_sun_of_may, +7) if last_sun_of_may == whit_sunday else last_sun_of_may, + ) + + # Father's Day. + self._add_holiday_3rd_sun_of_jun(tr("Fetin'ny ray")) + + if self._year >= 1960: + # Independence Day. + self._add_holiday_jun_26(tr("Fetin'ny fahaleovantena")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Fiakaran'ny Masina Maria tany an-danitra")) + + # All Saints' Day. + self._add_all_saints_day(tr("Fetin'ny olo-masina")) + + if self._year >= 2011: + # Republic Day. + self._add_holiday_dec_11(tr("Fetin'ny Repoblika")) + + # Christmas Day. + self._add_christmas_day(tr("Fetin'ny noely")) + + +class MG(Madagascar): + pass + + +class MDG(Madagascar): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/malawi.py b/.venv/lib/python3.12/site-packages/holidays/countries/malawi.py new file mode 100644 index 00000000..ba24e9a5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/malawi.py @@ -0,0 +1,68 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Malawi(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Malawi holidays. + + References: + * + * + """ + + country = "MW" + observed_label = "%s (observed)" + start_year = 2000 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self._add_observed(self._add_new_years_day("New Year's Day")) + + self._add_observed(self._add_holiday_jan_15("John Chilembwe Day")) + + self._add_observed(self._add_holiday_mar_3("Martyrs Day")) + + self._add_good_friday("Good Friday") + + self._add_easter_monday("Easter Monday") + + self._add_observed(self._add_labor_day("Labour Day")) + + self._add_observed(self._add_holiday_may_14("Kamuzu Day")) + + self._add_observed(self._add_holiday_jul_6("Independence Day")) + + self._add_observed(self._add_holiday_oct_15("Mother's Day")) + + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + self._add_observed(self._add_christmas_day_two("Boxing Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + +class MW(Malawi): + pass + + +class MWI(Malawi): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/malaysia.py b/.venv/lib/python3.12/site-packages/holidays/countries/malaysia.py new file mode 100644 index 00000000..8d2d196b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/malaysia.py @@ -0,0 +1,1029 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import ( + _CustomBuddhistHolidays, + _CustomChineseHolidays, + _CustomHinduHolidays, + _CustomIslamicHolidays, +) +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + FRI, + SAT, + SUN, +) +from holidays.groups import ( + BuddhistCalendarHolidays, + ChineseCalendarHolidays, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + FRI_TO_NEXT_WORKDAY, + SAT_TO_NEXT_WORKDAY, + SUN_TO_NEXT_WORKDAY, +) + + +class Malaysia( + ObservedHolidayBase, + BuddhistCalendarHolidays, + ChineseCalendarHolidays, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Malaysia holidays. + + References: + * [Holidays Act 1951](https://web.archive.org/web/20241202103403/https://www.kabinet.gov.my/bkpp/pdf/akta_warta/1951_12_31_act369.pdf) + * [Holidays Ordinance (Sabah Cap. 56)](https://web.archive.org/web/20201028045259/https://sagc.sabah.gov.my/sites/default/files/law/HolidaysOrdinance.pdf) + * [Public Holidays Ordinance (Sarawak Cap. 8)](https://web.archive.org/web/20221208142318/https://www.kabinet.gov.my/bkpp/pdf/akta_warta/sarawak_public_holidays_ord_chapter8.pdf) + * [Wikipedia](https://en.wikipedia.org/wiki/Public_holidays_in_Malaysia) + * + * + + Section 3 of Holidays Act 1951: + > If any day specified in the Schedule falls on Sunday then the day following shall be + > a public holiday and if such day is already a public holiday, then the day following + > shall be a public holiday". + + In Johor (until 1994 and in 2014-2024) and Kedah it's Friday to Sunday, + in Kelantan and Terengganu - Saturday to Sunday. + """ + + country = "MY" + default_language = "ms_MY" + # %s (estimated). + estimated_label = tr("%s (anggaran)") + # %s (in lieu). + observed_label = tr("Cuti %s") + # %s (observed, estimated). + observed_estimated_label = tr("Cuti %s (anggaran)") + start_year = 1952 + subdivisions = ( + "01", # Johor. + "02", # Kedah. + "03", # Kelantan. + "04", # Melaka. + "05", # Negeri Sembilan. + "06", # Pahang. + "07", # Pulau Pinang. + "08", # Perak. + "09", # Perlis. + "10", # Selangor. + "11", # Terengganu. + "12", # Sabah. + "13", # Sarawak. + "14", # Wilayah Persekutuan Kuala Lumpur. + "15", # Wilayah Persekutuan Labuan. + "16", # Wilayah Persekutuan Putrajaya. + ) + subdivisions_aliases = { + "Johor": "01", + "JHR": "01", + "Kedah": "02", + "KDH": "02", + "Kelantan": "03", + "KTN": "03", + "Melaka": "04", + "MLK": "04", + "Negeri Sembilan": "05", + "NSN": "05", + "Pahang": "06", + "PHG": "06", + "Pulau Pinang": "07", + "PNG": "07", + "Perak": "08", + "PRK": "08", + "Perlis": "09", + "PLS": "09", + "Selangor": "10", + "SGR": "10", + "Terengganu": "11", + "TRG": "11", + "Sabah": "12", + "SBH": "12", + "Sarawak": "13", + "SWK": "13", + "Wilayah Persekutuan Kuala Lumpur": "14", + "KUL": "14", + "Wilayah Persekutuan Labuan": "15", + "LBN": "15", + "Wilayah Persekutuan Putrajaya": "16", + "PJY": "16", + } + supported_languages = ("en_US", "ms_MY", "th") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + BuddhistCalendarHolidays.__init__(self, cls=MalaysiaBuddhistHolidays, show_estimated=True) + ChineseCalendarHolidays.__init__(self, cls=MalaysiaChineseHolidays, show_estimated=True) + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=MalaysiaHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=MalaysiaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=MalaysiaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self.dts_observed = set() + + # Chinese New Year. + self.dts_observed.add(self._add_chinese_new_years_day(tr("Tahun Baharu Cina"))) + + self.dts_observed.add( + # Chinese New Year (Second Day). + self._add_chinese_new_years_day_two(tr("Tahun Baharu Cina (Hari Kedua)")) + ) + + # Vesak Day. + self.dts_observed.add(self._add_vesak_may(tr("Hari Wesak"))) + + if self._year >= 1973: + # Labor Day. + self.dts_observed.add(self._add_labor_day(tr("Hari Pekerja"))) + + # Birthday of HM Yang di-Pertuan Agong. + name = tr("Hari Keputeraan Rasmi Seri Paduka Baginda Yang di-Pertuan Agong") + if self._year <= 2016: + self.dts_observed.add(self._add_holiday_1st_sat_of_jun(name)) + elif self._year <= 2019: + self.dts_observed.add(self._add_holiday_sep_9(name)) + elif self._year == 2020: + self.dts_observed.add(self._add_holiday_jun_8(name)) + else: + self.dts_observed.add(self._add_holiday_1st_mon_of_jun(name)) + + # National Day. + self.dts_observed.add(self._add_holiday_aug_31(tr("Hari Kebangsaan"))) + + if self._year >= 2010: + # Malaysia Day. + self.dts_observed.add(self._add_holiday_sep_16(tr("Hari Malaysia"))) + + # Christmas Day. + self.dts_observed.add(self._add_christmas_day(tr("Hari Krismas"))) + + if self._year >= 1995: + # Islamic New Year. + self._add_islamic_new_year_day(tr("Awal Muharam")) + + # Prophet Muhammad's Birthday. + self.dts_observed.update(self._add_mawlid_day(tr("Hari Keputeraan Nabi Muhammad S.A.W."))) + + # Eid al-Fitr. + self.dts_observed.update(self._add_eid_al_fitr_day(tr("Hari Raya Puasa"))) + + # Eid al-Fitr (Second Day). + self.dts_observed.update(self._add_eid_al_fitr_day_two(tr("Hari Raya Puasa (Hari Kedua)"))) + + # Eid al-Adha. + self.dts_observed.update(self._add_eid_al_adha_day(tr("Hari Raya Qurban"))) + + def _populate_subdiv_holidays(self): + if self.subdiv and self.subdiv not in {"13", "15"}: + # Deepavali. + self.dts_observed.add(self._add_diwali(tr("Hari Deepavali"))) + + super()._populate_subdiv_holidays() + + if ( + self.subdiv == "01" and (self._year <= 1994 or 2014 <= self._year <= 2024) + ) or self.subdiv == "02": + self._observed_rule = FRI_TO_NEXT_WORKDAY + self.weekend = {FRI, SAT} + elif self.subdiv in {"03", "11"}: + self._observed_rule = SAT_TO_NEXT_WORKDAY + self.weekend = {FRI, SAT} + else: + self._observed_rule = SUN_TO_NEXT_WORKDAY + self.weekend = {SAT, SUN} + + if self.observed: + self._populate_observed(self.dts_observed) + + def _populate_subdiv_01_public_holidays(self): + # Thaipusam. + self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam"))) + + if self._year >= 2015: + # Birthday of the Sultan of Johor. + self._add_holiday_mar_23(tr("Hari Keputeraan Sultan Johor")) + + if self._year >= 2011: + # The Sultan of Johor Hol. + self._add_hari_hol_johor(tr("Hari Hol Almarhum Sultan Iskandar")) + + # Beginning of Ramadan. + self.dts_observed.update(self._add_ramadan_beginning_day(tr("Awal Ramadan"))) + + def _populate_subdiv_02_public_holidays(self): + if self._year >= 2022: + # Thaipusam. + self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam"))) + + if self._year >= 2018: + # Birthday of The Sultan of Kedah. + name = tr("Hari Keputeraan Sultan Kedah") + if self._year == 2024: + self._add_holiday_jun_30(name) + else: + self._add_holiday_3rd_sun_of_jun(name) + + # Isra' and Mi'raj. + self.dts_observed.update(self._add_isra_and_miraj_day(tr("Israk dan Mikraj"))) + + # Beginning of Ramadan. + self.dts_observed.update(self._add_ramadan_beginning_day(tr("Awal Ramadan"))) + + # Eid al-Adha (Second Day). + self.dts_observed.update( + self._add_eid_al_adha_day_two(tr("Hari Raya Qurban (Hari Kedua)")) + ) + + def _populate_subdiv_03_public_holidays(self): + if self._year >= 2010: + # Birthday of the Sultan of Kelantan. + name = tr("Hari Keputeraan Sultan Kelantan") + if self._year >= 2023: + self._add_holiday_sep_29(name) + self._add_holiday_sep_30(name) + elif self._year >= 2012: + self._add_holiday_nov_11(name) + self._add_holiday_nov_12(name) + else: + self._add_holiday_mar_30(name) + self._add_holiday_mar_31(name) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + if self._year >= 2023: + # Arafat Day. + self.dts_observed.update(self._add_arafah_day(tr("Hari Arafah"))) + + # Eid al-Adha (Second Day). + self.dts_observed.update( + self._add_eid_al_adha_day_two(tr("Hari Raya Qurban (Hari Kedua)")) + ) + + def _populate_subdiv_04_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + if self._year >= 2024: + self.dts_observed.add( + # Declaration of Independence Day. + self._add_holiday_feb_20(tr("Hari Pengisytiharan Tarikh Kemerdekaan")) + ) + elif self._year >= 1989: + self.dts_observed.add( + self._add_holiday_apr_15( + # Declaration of Malacca as a Historical City. + tr("Hari Perisytiharan Melaka Sebagai Bandaraya Bersejarah") + ) + ) + + # Birthday of the Governor of Malacca. + name = tr("Hari Jadi Yang di-Pertua Negeri Melaka") + self.dts_observed.add( + self._add_holiday_aug_24(name) + if self._year >= 2020 + else self._add_holiday_2nd_fri_of_oct(name) + ) + + if self._year >= 2025: + self.dts_observed.update( + # Eid al-Fitr (Third Day). + self._add_eid_al_fitr_day_three(tr("Hari Raya Puasa (Hari Ketiga)")) + ) + else: + # Beginning of Ramadan. + self.dts_observed.update(self._add_ramadan_beginning_day(tr("Awal Ramadan"))) + + def _populate_subdiv_05_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + # Thaipusam. + self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam"))) + + if self._year >= 2009: + self.dts_observed.add( + self._add_holiday_jan_14( + # Birthday of the Sultan of Negeri Sembilan. + tr("Hari Keputeraan Yang di-Pertuan Besar Negeri Sembilan") + ) + ) + + # Isra' and Mi'raj. + self.dts_observed.update(self._add_isra_and_miraj_day(tr("Israk dan Mikraj"))) + + def _populate_subdiv_06_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + if self._year >= 1975: + # The Sultan of Pahang Hol. + name = tr("Hari Hol Sultan Pahang") + self.dts_observed.add( + self._add_holiday_may_22(name) + if self._year >= 2020 + else self._add_holiday_may_7(name) + ) + + # Birthday of the Sultan of Pahang. + name = tr("Hari Keputeraan Sultan Pahang") + self.dts_observed.add( + self._add_holiday_jul_30(name) + if self._year >= 2019 + else self._add_holiday_oct_24(name) + ) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + def _populate_subdiv_07_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + # Thaipusam. + self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam"))) + + if self._year >= 2009: + self.dts_observed.add( + # George Town Heritage Day. + self._add_holiday_jul_7(tr("Hari Ulang Tahun Perisytiharan Tapak Warisan Dunia")) + ) + + self.dts_observed.add( + # Birthday of the Governor of Penang. + self._add_holiday_2nd_sat_of_jul(tr("Hari Jadi Yang di-Pertua Negeri Pulau Pinang")) + ) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + def _populate_subdiv_08_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + # Thaipusam. + self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam"))) + + # Birthday of the Sultan of Perak. + name = tr("Hari Keputeraan Sultan Perak") + if self._year >= 2018: + self._add_holiday_1st_fri_of_nov(name) + else: + self._add_holiday_nov_27(name) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + def _populate_subdiv_09_public_holidays(self): + if self._year >= 2000: + # Birthday of the Raja of Perlis. + name = tr("Hari Ulang Tahun Keputeraan Raja Perlis") + self.dts_observed.add( + self._add_holiday_jul_17(name) + if 2018 <= self._year <= 2021 + else self._add_holiday_may_17(name) + ) + + # Isra' and Mi'raj. + self.dts_observed.update(self._add_isra_and_miraj_day(tr("Israk dan Mikraj"))) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + # Eid al-Adha (Second Day). + self.dts_observed.update( + self._add_eid_al_adha_day_two(tr("Hari Raya Qurban (Hari Kedua)")) + ) + + def _populate_subdiv_10_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + # Thaipusam. + self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam"))) + + # Birthday of The Sultan of Selangor. + self.dts_observed.add(self._add_holiday_dec_11(tr("Hari Keputeraan Sultan Selangor"))) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + def _populate_subdiv_11_public_holidays(self): + if self._year >= 2000: + self.dts_observed.add( + self._add_holiday_mar_4( + # Anniversary of the Installation of the Sultan of Terengganu. + tr("Hari Ulang Tahun Pertabalan Sultan Terengganu") + ) + ) + + self.dts_observed.add( + # Birthday of the Sultan of Terengganu. + self._add_holiday_apr_26(tr("Hari Keputeraan Sultan Terengganu")) + ) + + if self._year >= 2020: + # Isra' and Mi'raj. + self.dts_observed.update(self._add_isra_and_miraj_day(tr("Israk dan Mikraj"))) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + # Arafat Day. + self.dts_observed.update(self._add_arafah_day(tr("Hari Arafah"))) + + self.dts_observed.update( + # Eid al-Adha (Second Day). + self._add_eid_al_adha_day_two(tr("Hari Raya Qurban (Hari Kedua)")) + ) + + def _populate_subdiv_12_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Pesta Kaamatan. + name = tr("Pesta Kaamatan") + self._add_holiday_may_30(name) + self._add_holiday_may_31(name) + + # Birthday of the Governor of Sabah. + self._add_holiday_1st_sat_of_oct(tr("Hari Jadi Yang di-Pertua Negeri Sabah")) + + if self._year >= 2019: + # Christmas Eve. + self._add_christmas_eve(tr("Christmas Eve")) + + def _populate_subdiv_13_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 1965: + # Dayak Festival Day. + name = tr("Perayaan Hari Gawai Dayak") + self.dts_observed.add(self._add_holiday_jun_1(name)) + self.dts_observed.add(self._add_holiday_jun_2(name)) + + # Birthday of the Governor of Sarawak. + self._add_holiday_2nd_sat_of_oct(tr("Hari Jadi Yang di-Pertua Negeri Sarawak")) + + if self._year >= 2017: + # Sarawak Independence Day. + self.dts_observed.add(self._add_holiday_jul_22(tr("Hari Kemerdekaan Sarawak"))) + + def _populate_subdiv_14_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + # Thaipusam. + self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam"))) + + if self._year >= 1974: + # Federal Territory Day. + self.dts_observed.add(self._add_holiday_feb_1(tr("Hari Wilayah Persekutuan"))) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + def _populate_subdiv_15_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + if self._year >= 1974: + # Federal Territory Day. + self.dts_observed.add(self._add_holiday_feb_1(tr("Hari Wilayah Persekutuan"))) + + # Pesta Kaamatan. + name = tr("Pesta Kaamatan") + self._add_holiday_may_30(name) + self._add_holiday_may_31(name) + + if self._year >= 2014: + # Deepavali. + self.dts_observed.add(self._add_diwali(tr("Hari Deepavali"))) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + def _populate_subdiv_16_public_holidays(self): + # New Year's Day. + self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu"))) + + # Thaipusam. + self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam"))) + + if self._year >= 1974: + # Federal Territory Day. + self.dts_observed.add(self._add_holiday_feb_1(tr("Hari Wilayah Persekutuan"))) + + # Nuzul Al-Quran Day. + self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran"))) + + +class MY(Malaysia): + pass + + +class MYS(Malaysia): + pass + + +class MalaysiaBuddhistHolidays(_CustomBuddhistHolidays): + VESAK_MAY_DATES = { + 2001: (MAY, 7), + 2002: (MAY, 27), + 2003: (MAY, 15), + 2004: (MAY, 3), + 2005: (MAY, 22), + 2006: (MAY, 12), + 2007: (MAY, 1), + 2008: (MAY, 19), + 2009: (MAY, 9), + 2010: (MAY, 28), + 2011: (MAY, 17), + 2012: (MAY, 5), + 2013: (MAY, 24), + 2014: (MAY, 13), + 2015: (MAY, 3), + 2016: (MAY, 21), + 2017: (MAY, 10), + 2018: (MAY, 29), + 2019: (MAY, 19), + 2020: (MAY, 7), + 2021: (MAY, 26), + 2022: (MAY, 15), + 2023: (MAY, 4), + 2024: (MAY, 22), + 2025: (MAY, 12), + } + + +class MalaysiaChineseHolidays(_CustomChineseHolidays): + LUNAR_NEW_YEAR_DATES = { + 2001: (JAN, 24), + 2002: (FEB, 12), + 2003: (FEB, 1), + 2004: (JAN, 22), + 2005: (FEB, 9), + 2006: (JAN, 29), + 2007: (FEB, 18), + 2008: (FEB, 7), + 2009: (JAN, 26), + 2010: (FEB, 14), + 2011: (FEB, 3), + 2012: (JAN, 23), + 2013: (FEB, 10), + 2014: (JAN, 31), + 2015: (FEB, 19), + 2016: (FEB, 8), + 2017: (JAN, 28), + 2018: (FEB, 16), + 2019: (FEB, 5), + 2020: (JAN, 25), + 2021: (FEB, 12), + 2022: (FEB, 1), + 2023: (JAN, 22), + 2024: (FEB, 10), + 2025: (JAN, 29), + } + + +class MalaysiaHinduHolidays(_CustomHinduHolidays): + DIWALI_DATES = { + 2001: (NOV, 14), + 2002: (NOV, 3), + 2003: (OCT, 23), + 2004: (NOV, 11), + 2005: (NOV, 1), + 2006: (OCT, 21), + 2007: (NOV, 8), + 2008: (OCT, 27), + 2009: (OCT, 17), + 2010: (NOV, 5), + 2011: (OCT, 26), + 2012: (NOV, 13), + 2013: (NOV, 2), + 2014: (OCT, 22), + 2015: (NOV, 10), + 2016: (OCT, 29), + 2017: (OCT, 18), + 2018: (NOV, 6), + 2019: (OCT, 27), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 24), + 2023: (NOV, 12), + 2024: (OCT, 31), + 2025: (OCT, 20), + } + + THAIPUSAM_DATES = { + 2018: (JAN, 31), + 2019: (JAN, 21), + 2020: (FEB, 8), + 2021: (JAN, 28), + 2022: (JAN, 18), + 2023: (FEB, 5), + 2024: (JAN, 25), + 2025: (FEB, 11), + 2026: (FEB, 1), + 2027: (JAN, 22), + } + + +class MalaysiaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 2001: (DEC, 17), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 3), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 1), + 2009: (SEP, 20), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 6), + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + HARI_HOL_JOHOR_DATES = { + 2011: (JAN, 12), + 2012: (DEC, 20), + 2013: (DEC, 10), + 2014: (NOV, 29), + 2015: (NOV, 19), + 2016: (NOV, 7), + 2017: (OCT, 27), + 2018: (OCT, 15), + 2019: (OCT, 5), + 2020: (SEP, 24), + 2021: (SEP, 13), + 2022: (SEP, 3), + 2023: (AUG, 23), + 2024: (AUG, 11), + 2025: (JUL, 31), + } + + HIJRI_NEW_YEAR_DATES = { + 2001: (MAR, 26), + 2002: (MAR, 15), + 2003: (MAR, 5), + 2004: (FEB, 22), + 2005: (FEB, 10), + 2006: (JAN, 31), + 2007: (JAN, 20), + 2008: ((JAN, 10), (DEC, 29)), + 2009: (DEC, 18), + 2010: (DEC, 8), + 2011: (NOV, 27), + 2012: (NOV, 15), + 2013: (NOV, 5), + 2014: (OCT, 25), + 2015: (OCT, 14), + 2016: (OCT, 2), + 2017: (SEP, 22), + 2018: (SEP, 11), + 2019: (SEP, 1), + 2020: (AUG, 20), + 2021: (AUG, 10), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 7), + 2025: (JUN, 27), + } + + ISRA_AND_MIRAJ_DATES = { + 2001: (OCT, 15), + 2002: (OCT, 4), + 2003: (SEP, 24), + 2004: (SEP, 12), + 2005: (SEP, 1), + 2006: (AUG, 22), + 2007: (AUG, 11), + 2008: (JUL, 31), + 2009: (JUL, 20), + 2010: (JUL, 9), + 2011: (JUN, 29), + 2012: (JUN, 17), + 2013: (JUN, 6), + 2014: (MAY, 27), + 2015: (MAY, 16), + 2016: (MAY, 5), + 2017: (APR, 24), + 2018: (APR, 14), + 2019: (APR, 3), + 2020: (MAR, 22), + 2021: (MAR, 11), + 2022: (MAR, 1), + 2023: (FEB, 18), + 2024: (FEB, 8), + 2025: (JAN, 27), + } + + MAWLID_DATES = { + 2001: (JUN, 4), + 2002: (MAY, 24), + 2003: (MAY, 14), + 2004: (MAY, 2), + 2005: (APR, 21), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 16), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 20), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 10), + 2023: (SEP, 28), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + NUZUL_AL_QURAN_DATES = { + 2001: (DEC, 3), + 2002: (NOV, 22), + 2003: (NOV, 12), + 2004: (NOV, 1), + 2005: (OCT, 21), + 2006: (OCT, 10), + 2007: (SEP, 29), + 2008: (SEP, 18), + 2009: (SEP, 7), + 2010: (AUG, 27), + 2011: (AUG, 17), + 2012: (AUG, 5), + 2013: (JUL, 25), + 2014: (JUL, 15), + 2015: (JUL, 4), + 2016: (JUN, 22), + 2017: (JUN, 12), + 2018: (JUN, 2), + 2019: (MAY, 22), + 2020: (MAY, 10), + 2021: (APR, 29), + 2022: (APR, 19), + 2023: (APR, 8), + 2024: (MAR, 28), + 2025: (MAR, 18), + } + + RAMADAN_BEGINNING_DATES = { + 2001: (NOV, 17), + 2002: (NOV, 6), + 2003: (OCT, 27), + 2004: (OCT, 16), + 2005: (OCT, 5), + 2006: (SEP, 24), + 2007: (SEP, 13), + 2008: (SEP, 2), + 2009: (AUG, 22), + 2010: (AUG, 11), + 2011: (AUG, 1), + 2012: (JUL, 20), + 2013: (JUL, 9), + 2014: (JUN, 29), + 2015: (JUN, 18), + 2016: (JUN, 7), + 2017: (MAY, 27), + 2018: (MAY, 17), + 2019: (MAY, 6), + 2020: (APR, 24), + 2021: (APR, 13), + 2022: (APR, 3), + 2023: (MAR, 23), + 2024: (MAR, 12), + 2025: (MAR, 2), + } + + +class MalaysiaStaticHolidays: + # General election additional holiday. + election_polling_day = tr("Cuti Peristiwa (pilihan raya umum)") + + # Additional holiday. + election_additional_holiday = "Cuti Peristiwa" + + # Eid al-Adha. + eid_al_adha = tr("Hari Raya Qurban") + + # Labor Day. + labor_day = tr("Hari Pekerja") + + # Malaysia Cup Holiday. + malaysia_cup_holiday = tr("Cuti Piala Malaysia") + + # Day of Installation of the 15th Yang di-Pertuan Agong. + yang_di_pertuan_agong_15_installation = tr("Hari Pertabalan Yang di-Pertuan Agong ke-15") + + # Day of Installation of the 16th Yang di-Pertuan Agong. + yang_di_pertuan_agong_16_installation = tr("Hari Pertabalan Yang di-Pertuan Agong ke-16") + + # Eid al-Fitr (additional holiday). + eid_al_fitr_additional_holiday = tr("Hari Raya Puasa (pergantian hari)") + + # Arafat Day. + arafat_day = tr("Hari Arafah") + + # Additional holiday in commemoration of the 2017 SEA Games. + additional_holiday_2017_sea_games = tr("Cuti tambahan sempena memperingati SAT 2017") + + special_public_holidays = { + 1999: (NOV, 29, election_polling_day), + 2017: ( + (APR, 24, yang_di_pertuan_agong_15_installation), + (SEP, 4, additional_holiday_2017_sea_games), + ), + 2018: (MAY, 9, election_polling_day), + 2019: (JUL, 30, yang_di_pertuan_agong_16_installation), + 2022: ( + (NOV, 18, election_polling_day), + (NOV, 19, election_polling_day), + (NOV, 28, election_additional_holiday), + ), + 2023: (APR, 21, eid_al_fitr_additional_holiday), + } + + special_14_public_holidays = { + 2021: (DEC, 3, malaysia_cup_holiday), + } + + special_15_public_holidays = { + 2021: (DEC, 3, malaysia_cup_holiday), + } + + special_16_public_holidays = { + 2021: (DEC, 3, malaysia_cup_holiday), + } + + special_13_public_holidays = { + 2018: ( + (MAY, 17, election_additional_holiday), + (MAY, 18, election_additional_holiday), + ), + } + + special_01_public_holidays_observed = { + 2022: (MAY, 4, labor_day), + } + + special_02_public_holidays_observed = { + 2022: (MAY, 4, labor_day), + } + + special_03_public_holidays_observed = { + 2022: (MAY, 4, labor_day), + } + + special_14_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_15_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_04_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_05_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_06_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_16_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_09_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_07_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_08_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_12_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_10_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_13_public_holidays_observed = { + 2007: (JAN, 2, eid_al_adha), + } + + special_11_public_holidays_observed = { + 2007: (JAN, 2, arafat_day), + 2022: (MAY, 4, labor_day), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/maldives.py b/.venv/lib/python3.12/site-packages/holidays/countries/maldives.py new file mode 100644 index 00000000..6b31a08a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/maldives.py @@ -0,0 +1,93 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import FRI, SAT +from holidays.groups import InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Maldives(HolidayBase, InternationalHolidays, IslamicHolidays): + """Maldives holidays. + + References: + * + * + * + """ + + country = "MV" + weekend = {FRI, SAT} + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day("New Year's Day") + + # Labor Day. + self._add_labor_day("Labor Day") + + # Independence Day. + self._add_holiday_jul_26("Independence Day") + + # Victory Day. + self._add_holiday_nov_3("Victory Day") + + # Republic Day. + self._add_holiday_nov_11("Republic Day") + + # Islamic holidays. + # Start of Ramadan. + self._add_ramadan_beginning_day("Beginning of Ramadan") + + # Eid al-Fitr. + self._add_eid_al_fitr_day("Eid al-Fitr") + self._add_eid_al_fitr_day_two("Eid al-Fitr") + self._add_eid_al_fitr_day_three("Eid al-Fitr") + + # Hajj Day. + self._add_arafah_day("Hajj Day") + + # Eid al-Adha. + self._add_eid_al_adha_day("Eid al-Adha") + self._add_eid_al_adha_day_two("Eid al-Adha") + self._add_eid_al_adha_day_three("Eid al-Adha") + self._add_eid_al_adha_day_four("Eid al-Adha") + + # Muharram/Islamic New Year. + self._add_islamic_new_year_day("Islamic New Year") + + # National Day. + self._add_quamee_dhuvas_day("National Day") + + # Prophet Muhammad's Birthday. + self._add_mawlid_day("Mawlid al-Nabi") + + # The Day Maldives Embraced Islam. + self._add_maldives_embraced_islam_day("The Day Maldives Embraced Islam") + + +class MV(Maldives): + pass + + +class MDV(Maldives): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/mali.py b/.venv/lib/python3.12/site-packages/holidays/countries/mali.py new file mode 100644 index 00000000..f281a9a4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/mali.py @@ -0,0 +1,151 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Mali(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Mali holidays. + + References: + * [Ordinance no. 54 of 1960](https://web.archive.org/web/20250619193041/https://sgg-mali.ml/JO/1960/mali-jo-1960-71.pdf) + * [Law No. 28 of 1964](https://web.archive.org/web/20250619190638/https://sgg-mali.ml/JO/1964/mali-jo-1964-183.pdf) + * [Ordinance no. 16 of 1992](https://web.archive.org/web/20250611221453/https://sgg-mali.ml/JO/1992/mali-jo-1992-08.pdf) + * [Law No. 40 of 2005](https://web.archive.org/web/20250603120027/https://sgg-mali.ml/JO/2005/mali-jo-2005-25.pdf) + """ + + country = "ML" + default_language = "fr" + # %s (estimated). + estimated_label = tr("%s (estimé)") + start_year = 1961 + supported_languages = ("en_US", "fr") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=MaliIslamicHolidays, show_estimated=islamic_show_estimated + ) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Jour de l'An")) + + if self._year >= 1965: + # Armed Forces Day. + self._add_holiday_jan_20(tr("Journée de l'Armée")) + + if self._year >= 1992: + # Martyrs' Day. + self._add_holiday_mar_26(tr("Journée du 26 mars")) + + if self._year >= 2006: + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + # Labor Day. + self._add_labor_day(tr("Fête du Travail")) + + if self._year >= 1965: + # Africa Day. + self._add_africa_day(tr("Journée de l'Afrique")) + + # National Day of the Republic of Mali. + self._add_holiday_sep_22(tr("Fête Nationale de la République du Mali")) + + # Christmas Day. + self._add_christmas_day(tr("Fête de Noël")) + + self._add_mawlid_day( + # Prophet's Birthday. + tr("Journée du Maouloud (Naissance du Prophète)") + if self._year >= 2006 + # Prophet's Birthday. + else tr("Journée du Mawloud") + ) + + if self._year >= 2006: + # Prophet's Baptism. + self._add_prophet_baptism_day(tr("Journée du Maouloud (Baptême du Prophète)")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Journée de la Fête du Ramadan")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Journée de la Tabaski")) + + +class ML(Mali): + pass + + +class MLI(Mali): + pass + + +class MaliIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20250619042440/https://www.timeanddate.com/holidays/mali/eid-al-adha + EID_AL_ADHA_DATES = { + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 21), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + # https://web.archive.org/web/20250318001443/https://www.timeanddate.com/holidays/mali/eid-al-fitr + EID_AL_FITR_DATES = { + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 3), + 2020: (MAY, 23), + 2021: (MAY, 12), + 2022: (MAY, 1), + 2023: (APR, 21), + 2024: (APR, 9), + 2025: (MAR, 30), + } + + # https://web.archive.org/web/20240424165412/https://www.timeanddate.com/holidays/mali/prophet-birthday + MAWLID_DATES = { + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 9), + 2023: (SEP, 28), + 2024: (SEP, 16), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/malta.py b/.venv/lib/python3.12/site-packages/holidays/countries/malta.py new file mode 100644 index 00000000..63830df0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/malta.py @@ -0,0 +1,151 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Malta(HolidayBase, ChristianHolidays, InternationalHolidays): + """Malta holidays. + + References: + * + * [Att 10 tal-1980 (Oldest Maltese Holidays Law available online in full)](https://web.archive.org/web/20250427184411/https://legislation.mt/eli/act/1980/10/mlt) + * [A.L. 40 tal-1987 (Additional Holidays added)](https://web.archive.org/web/20250427184605/https://legislation.mt/eli/ln/1987/8/mlt) + * [Att 8 tal-1989 (Additional Holidays added)](https://web.archive.org/web/20250427184429/https://legislation.mt/eli/act/1989/8) + * [Att 2 tal-2005 (If fall on weekends then not observed in terms of vacation leave)](https://web.archive.org/web/20250427184434/https://legislation.mt/eli/act/2005/2/eng) + * [Att 4 tal-2021 (Revert Act II of 2005 changes for vacation leave)](https://web.archive.org/web/20240716035452/https://legislation.mt/eli/cap/252/20210212/mlt) + """ + + country = "MT" + default_language = "mt" + supported_languages = ("en_US", "mt") + # Earliest available source is 1980. + start_year = 1980 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # L-Ewwel tas-Sena + # Status: In-Use. + + # New Year's Day. + self._add_new_years_day(tr("L-Ewwel tas-Sena")) + + # Il-Festa tan-Nawfraġju ta' San Pawl + # Status: In-Use. + # Started in 1987 via Act LX of 1987. + + if self._year >= 1987: + # Feast of Saint Paul's Shipwreck. + self._add_holiday_feb_10(tr("Il-Festa tan-Nawfraġju ta' San Pawl")) + + # Il-Festa ta' San Ġużepp + # Status: In-Use. + # Started in 1987 via Act LX of 1987. + + if self._year >= 1987: + # Feast of Saint Joseph. + self._add_saint_josephs_day(tr("Il-Festa ta' San Ġużepp")) + + # Jum il-Ħelsien + # Status: In-Use. + # Started in 1980 Act X of 1980. + # Not presented in 1987-1988 + + if self._year <= 1986 or self._year >= 1989: + # Freedom Day. + self._add_holiday_mar_31(tr("Jum il-Ħelsien")) + + # Il-Ġimgħa l-Kbira + # Status: In-Use. + + # Good Friday. + self._add_good_friday(tr("Il-Ġimgħa l-Kbira")) + + # Jum il-Ħaddiem + # Status: In-Use. + + # Worker's Day. + self._add_labor_day(tr("Jum il-Ħaddiem")) + + # Sette Giugno + # Status: In-Use. + # Start in 1989 via Act VIII of 1989. + + if self._year >= 1989: + # Sette Giugno. + self._add_holiday_jun_7(tr("Sette Giugno")) + + # Il-Festa ta' San Pietru u San Pawl + # Status: In-Use. + # Started in 1987 via Act LX of 1987. + + if self._year >= 1987: + # Feast of Saint Peter and Saint Paul. + self._add_saints_peter_and_paul_day(tr("Il-Festa ta' San Pietru u San Pawl")) + + # Il-Festa ta' Santa Marija + # Status: In-Use. + + # Feast of the Assumption. + self._add_assumption_of_mary_day(tr("Il-Festa ta' Santa Marija")) + + # Jum il-Vitorja + # Status: In-Use. + # Started in 1987 via Act LX of 1987. + # While this concides with Nativity Of Mary Day, the two are considered separate. + + if self._year >= 1987: + # Feast of Our Lady of Victories. + self._add_holiday_sep_8(tr("Jum il-Vitorja")) + + # Jum l-Indipendenza + # Status: In-Use. + # Started in 1987 via Act LX of 1987. + + if self._year >= 1987: + # Independence Day. + self._add_holiday_sep_21(tr("Jum l-Indipendenza")) + + # Il-Festa tal-Immakulata Kunċizzjoni + # Status: In-Use. + # Started in 1987 via Act LX of 1987. + + if self._year >= 1987: + # Feast of the Immaculate Conception + self._add_immaculate_conception_day(tr("Il-Festa tal-Immakulata Kunċizzjoni")) + + # Jum ir-Repubblika + # Status: In-Use. + + # Republic Day. + self._add_holiday_dec_13(tr("Jum ir-Repubblika")) + + # Il-Milied + # Status: In-Use. + + # Christmas Day. + self._add_christmas_day(tr("Il-Milied")) + + +class MT(Malta): + pass + + +class MLT(Malta): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/marshall_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/marshall_islands.py new file mode 100644 index 00000000..e5f291ce --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/marshall_islands.py @@ -0,0 +1,105 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +import warnings + +from holidays.calendars.gregorian import NOV +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class HolidaysMH(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Marshall Islands holidays. + + References: + * + * + """ + + country = "MH" + observed_label = "%s Holiday" + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, MarshalIslandsStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year <= 2019: + warnings.warn( + "Years before 2020 are not available for the Marshall Islands (MH).", Warning + ) + + # New Year's Day + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Nuclear Victims Remembrance Day + self._add_observed(self._add_holiday_mar_1("Nuclear Victims Remembrance Day")) + + # Good Friday + self._add_good_friday("Good Friday") + + # Constitution Day + self._add_observed(self._add_holiday_may_1("Constitution Day")) + + # Fisherman's Day + self._add_holiday_1st_fri_of_jul("Fisherman's Day") + + # Dri-jerbal Day + self._add_holiday_1st_fri_of_sep("Dri-jerbal Day") + + # Manit Day + self._add_holiday_last_fri_of_sep("Manit Day") + + # President's Day + self._add_observed(self._add_holiday_nov_17("President's Day")) + + # Gospel Day + self._add_holiday_1st_fri_of_dec("Gospel Day") + + # Christmas Day + name = "Christmas Day" + if self._year == 2021: + # special case + self._add_holiday_dec_24(name) + else: + self._add_observed(self._add_christmas_day(name)) + + +class MH(HolidaysMH): + pass + + +class MHL(HolidaysMH): + pass + + +class MarshallIslands(HolidaysMH): + pass + + +class MarshalIslandsStaticHolidays: + # General Election Day + election_day = "General Election Day" + + special_public_holidays = { + 1995: (NOV, 20, election_day), + 1999: (NOV, 22, election_day), + 2003: (NOV, 17, election_day), + 2007: (NOV, 19, election_day), + 2011: (NOV, 21, election_day), + 2015: (NOV, 16, election_day), + 2019: (NOV, 18, election_day), + 2023: (NOV, 20, election_day), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/martinique.py b/.venv/lib/python3.12/site-packages/holidays/countries/martinique.py new file mode 100644 index 00000000..a0415a6a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/martinique.py @@ -0,0 +1,44 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysMQ(ChildEntity, France): + """Martinique holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "MQ" + parent_entity = France + parent_entity_subdivision_code = "972" + # Cession from the UK on May 30th, 1814. + start_year = 1815 + + +class Martinique(HolidaysMQ): + pass + + +class MQ(HolidaysMQ): + pass + + +class MTQ(HolidaysMQ): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/mauritania.py b/.venv/lib/python3.12/site-packages/holidays/countries/mauritania.py new file mode 100644 index 00000000..fdc76bc5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/mauritania.py @@ -0,0 +1,77 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import FRI, SAT +from holidays.groups import InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Mauritania(HolidayBase, InternationalHolidays, IslamicHolidays): + """Mauritania holidays. + + References: + * + * + """ + + country = "MR" + weekend = {FRI, SAT} + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate(self, year): + super()._populate(year) + + # New Year's Day. + self._add_new_years_day("New Year's Day") + + # Labor Day. + self._add_labor_day("Labor Day") + + # Africa Day. + self._add_africa_day("Africa Day") + + # Independence Day. + if year >= 1960: + self._add_holiday_nov_28("Independence Day") + + # Islamic holidays. + # Eid al-Fitr. + self._add_eid_al_fitr_day("Eid al-Fitr") + self._add_eid_al_fitr_day_two("Eid al-Fitr") + + # Eid al-Adha. + self._add_eid_al_adha_day("Eid al-Adha") + self._add_eid_al_adha_day_two("Eid al-Adha") + + # Muharram/Islamic New Year. + self._add_islamic_new_year_day("Islamic New Year") + + # Prophet Muhammad's Birthday. + self._add_mawlid_day("Mawlid al-Nabi") + + +class MR(Mauritania): + pass + + +class MRT(Mauritania): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/mauritius.py b/.venv/lib/python3.12/site-packages/holidays/countries/mauritius.py new file mode 100644 index 00000000..b40b221b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/mauritius.py @@ -0,0 +1,197 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomHinduHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, APR, MAY, JUN, JUL, AUG, SEP +from holidays.groups import ( + ChineseCalendarHolidays, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.holiday_base import HolidayBase + + +class Mauritius( + HolidayBase, + ChineseCalendarHolidays, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Mauritius holidays. + + References: + * [Public Holidays Act Consolidated 1991](https://web.archive.org/web/20250618211720/https://natlex.ilo.org/dyn/natlex2/natlex2/files/download/101480/MUS101480.pdf) + * [The Public Holidays (Amendment) Act 2015](https://web.archive.org/web/20240805131941/http://mauritiusassembly.govmu.org/mauritiusassembly/wp-content/uploads/2023/03/act2815.pdf) + * Mauritius became independent in 1968, but the earliest accessible version of the Public + Holidays Act is the one consolidated in 1991. The most recent update to the holiday + schedule reflected in that version dates back to 1987. Therefore, 1988 is being used + as the starting year. + * [Ougadi](https://en.wikipedia.org/wiki/Ugadi) is another name for the Telugu holiday, + Ugadi, which is celebrated on the same day as Gudi Padwa. Therefore, reusing Gudi Padwa + for adding Ougadi. + * [2021](https://web.archive.org/web/20210926053030/https://mauritius-paris.govmu.org/Pages/About%20Us/Public-Holidays-in-Mauritius-for-Year-2021.aspx) + * [2022](https://web.archive.org/web/20240703234017/https://mauritius-kualalumpur.govmu.org/Documents/Public%20Holiday/Public%20holidays%20-%202022.pdf) + * [2024](https://web.archive.org/web/20240703233951/https://mauritius-paris.govmu.org/Documents/Public%20Holidays/Notice%20-%20Final%20Public%20holidays%20-%202024.pdf) + * [2025](https://web.archive.org/web/20250113100149/https://pmo.govmu.org/Communique/Notice-Public_Holidays_2025.pdf) + """ + + country = "MU" + default_language = "en_MU" + # %s (estimated). + estimated_label = tr("%s (estimated)") + start_year = 1988 + supported_languages = ("en_MU", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChineseCalendarHolidays.__init__(self) + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=MauritiusHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=MauritiusIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=MauritiusStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("New Year's Day")) + + # Day after New Year's Day. + self._add_new_years_day_two(tr("Day after New Year's Day")) + + # Abolition of Slavery. + self._add_holiday_feb_1(tr("Abolition of Slavery")) + + # Independence and Republic Day. + self._add_holiday_mar_12(tr("Independence and Republic Day")) + + # Labor Day. + self._add_labor_day(tr("Labour Day")) + + if self._year >= 2016 and self._year % 2 == 0: + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assumption of the Blessed Virgin Mary")) + + if self._year <= 2015 or self._year % 2 != 0: + # All Saints' Day. + self._add_all_saints_day(tr("All Saints' Day")) + + # Arrival of Indentured Laborers. + self._add_holiday_nov_2(tr("Arrival of Indentured Labourers")) + + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")) + + # Chinese Spring Festival. + self._add_chinese_new_years_day(tr("Chinese Spring Festival")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Eid-ul-Fitr")) + + # Thaipusam. + self._add_thaipusam(tr("Thaipoosam Cavadee")) + + # Maha Shivaratri. + self._add_maha_shivaratri(tr("Maha Shivaratree")) + + # Ugadi. + self._add_gudi_padwa(tr("Ougadi")) + + # Ganesh Chaturthi. + self._add_ganesh_chaturthi(tr("Ganesh Chaturthi")) + + # Diwali. + self._add_diwali_india(tr("Divali")) + + +class MU(Mauritius): + pass + + +class MUS(Mauritius): + pass + + +class MauritiusHinduHolidays(_CustomHinduHolidays): + # https://web.archive.org/web/20241208154454/https://www.timeanddate.com/holidays/mauritius/ganesh-chaturthi + GANESH_CHATURTHI_DATES = { + 2015: (SEP, 18), + 2016: (SEP, 6), + 2017: (AUG, 25), + 2018: (SEP, 14), + 2019: (SEP, 3), + 2020: (AUG, 23), + 2021: (SEP, 11), + 2022: (SEP, 1), + 2023: (SEP, 20), + 2024: (SEP, 8), + 2025: (AUG, 28), + } + + # https://web.archive.org/web/20240910225221/https://www.timeanddate.com/holidays/mauritius/thaipoosam-cavadee + THAIPUSAM_DATES = { + 2020: (FEB, 8), + 2021: (JAN, 28), + 2022: (JAN, 18), + 2023: (FEB, 4), + 2024: (JAN, 25), + 2025: (FEB, 11), + } + + +class MauritiusIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20250420201326/https://www.timeanddate.com/holidays/mauritius/eid-al-fitr + EID_AL_FITR_DATES = { + 2016: (JUL, 6), + 2017: (JUN, 26), + 2018: (JUN, 16), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 14), + 2022: (MAY, 3), + 2023: (APR, 22), + 2024: (APR, 11), + 2025: (APR, 1), + } + + +class MauritiusStaticHolidays(StaticHolidays): + """Mauritius special holidays. + + References: + * [July 29, 2019 and September 9, 2019](https://web.archive.org/web/20250618211631/https://mauritiuslii.org/akn/mu/officialGazette/government-gazette/2019-07-27/78/eng@2019-07-27) + """ + + # Public Holiday. + public_holiday = tr("Public Holiday") + + special_public_holidays = { + 2019: ( + (JUL, 29, public_holiday), + (SEP, 9, public_holiday), + ) + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/mayotte.py b/.venv/lib/python3.12/site-packages/holidays/countries/mayotte.py new file mode 100644 index 00000000..32b3ce9f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/mayotte.py @@ -0,0 +1,44 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysYT(ChildEntity, France): + """Mayotte holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "YT" + parent_entity = France + parent_entity_subdivision_code = "976" + # Sold to France on April 25th, 1841. + start_year = 1842 + + +class Mayotte(HolidaysYT): + pass + + +class YT(HolidaysYT): + pass + + +class MYT(HolidaysYT): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/mexico.py b/.venv/lib/python3.12/site-packages/holidays/countries/mexico.py new file mode 100644 index 00000000..a8bbe76d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/mexico.py @@ -0,0 +1,93 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Mexico(HolidayBase, ChristianHolidays, InternationalHolidays): + """Mexico holidays. + + References: + * + * + * + * + * + """ + + country = "MX" + default_language = "es" + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + if self._year >= 1917: + # Constitution Day. + name = tr("Día de la Constitución") + if self._year >= 2006: + self._add_holiday_1st_mon_of_feb(name) + else: + self._add_holiday_feb_5(name) + + if self._year >= 1917: + # Benito Juárez's birthday. + name = tr("Natalicio de Benito Juárez") + # no 2006 due to celebration of the 200th anniversary + # of Benito Juárez in 2006 + if self._year >= 2007: + self._add_holiday_3rd_mon_of_mar(name) + else: + self._add_holiday_mar_21(name) + + if self._year >= 1923: + # Labor Day. + self._add_labor_day(tr("Día del Trabajo")) + + # Independence Day. + self._add_holiday_sep_16(tr("Día de la Independencia")) + + if self._year >= 1917: + # Revolution Day. + name = tr("Día de la Revolución") + if self._year >= 2006: + self._add_holiday_3rd_mon_of_nov(name) + else: + self._add_holiday_nov_20(name) + + if self._year >= 1970 and (self._year - 1970) % 6 == 0: + # Change of Federal Government. + name = tr("Transmisión del Poder Ejecutivo Federal") + if self._year >= 2024: + self._add_holiday_oct_1(name) + else: + self._add_holiday_dec_1(name) + + # Christmas Day. + self._add_christmas_day(tr("Navidad")) + + +class MX(Mexico): + pass + + +class MEX(Mexico): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/micronesia.py b/.venv/lib/python3.12/site-packages/holidays/countries/micronesia.py new file mode 100644 index 00000000..5842463e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/micronesia.py @@ -0,0 +1,205 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_TO_PREV_FRI, SUN_TO_NEXT_MON + + +class Micronesia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Micronesia holidays. + + References: + * + * + * [2014 FSM Code](https://web.archive.org/web/20241213112548/http://www.fsmlaw.org/fsm/code/PDF/FSMCA2014Tit01.pdf) + * [Section 601, 602, 603](https://web.archive.org/web/20020731194201/http://fsmlaw.org/fsm/code/title01/t01ch06.htm) + * [United Nations Day](https://web.archive.org/web/20241213120703/http://www.fsmlaw.org/fsm/code/PDF/CODE%201/PL%207-20.pdf) + * [FSM Veterans of Foreign Wars Day](https://web.archive.org/web/20241213120631/http://www.fsmlaw.org/fsm/code/PDF/CODE%201/PL%2013-38.pdf) + * [Micronesian Culture and Tradition Day](https://web.archive.org/web/20241213114748/http://fsmlaw.org/fsm/code/PDF/CODE%201/PL%2016-27.pdf) + * [Presidents Day](https://web.archive.org/web/20241213120719/http://www.fsmlaw.org/fsm/code/PDF/CODE%201/PL%2021-209.pdf) + + Subdivisions Holidays References: + * Chuuk: + * [Chuuk State Code, T. 1, Chap. 3](https://web.archive.org/web/20250214151354/http://fsmlaw.org/chuuk/code/title01/T01_Ch03.htm) + * [State Charter Day](https://web.archive.org/web/20241213113932/http://fsmlaw.org/chuuk/pdf/tsl_a/TSL%203-10%20EV.pdf) + * [Chuuk State Constitution Day](https://web.archive.org/web/20241213113821/http://fsmlaw.org/chuuk/pdf/csl_a/CSL%20190-03%20EV.pdf) + * Kosrae: + * [Kosrae State Code, Section 2.501](https://web.archive.org/web/20250211055635/http://fsmlaw.org/kosrae/code/title02/t02c05.htm) + * [Seventh Korsae State Legislature](https://web.archive.org/web/20241213115951/https://fsmlaw.org/kosrae/Law/pdf/123.pdf) + * [Fourth Kosrae State Legislature](https://web.archive.org/web/20241213115949/https://fsmlaw.org/kosrae/Law/pdf/Kosrae%20State%20Law%201989-90.pdf) + * [State Law 4-32](https://web.archive.org/web/20250211151328/https://www.kosraestatelegislature.com/4th-ksl-state-laws) + * [State Law 7-76](https://web.archive.org/web/20250211151710/https://www.kosraestatelegislature.com/7th-ksl-state-laws) + * [State Law 9-50](https://web.archive.org/web/20250430191523/https://www.kosraestatelegislature.com/9th-ksl-state-laws) + * [State Law 13-79](https://web.archive.org/web/20241211232231/https://www.kosraestatelegislature.com/_files/ugd/f1e94d_cc244ef15bea4c74ba81cb1a4621c30f.pdf) + * Pohnpei: + * [State Code 2012](https://web.archive.org/web/20250209195119/https://fsmlaw.org/pohnpei/code/pdf/pohnpei%20state%202012%20code.pdf) + * [2025](https://web.archive.org/web/20250124225740/https://pohnpeistate.gov.fm/fy-2025-holiday-schedule/) + * [Women's Day](https://web.archive.org/web/20250403093235/https://pohnpeistate.gov.fm/2022/02/22/congratulations-pohnpei-womens-council-and-all-who-supported-this-important-undertaking/) + * [Yap](https://web.archive.org/web/20250223222339/http://fsmlaw.org/yap/code/title01/T01_Ch08.htm) + + According to Section 602: + + > All holidays set forth in section 601 shall, if they occur on a Saturday, + > be observed on the preceding Friday, and shall, if they occur on a Sunday, + > be observed on the following Monday. + + According to Kosrae State Legislature State Laws: + + * 4-32: Government Holidays were amended. + * 4-135: September 8 was declared a public holiday. + * 7-27: Good Friday was declared a public holiday. + * 7-76: Gospel Day was declared a public holiday. + * 9-50: Thanksgiving Day was declared a public holiday. + * 13-79: Kosrae Disability Day was declared a public holiday. + + According to Pohnpei State Code 2012 Section 7-101: + + * Pohnpei Constitution Day is a public holiday. + * Liberation Day is a public holiday. + * Pohnpei Cultural Day is a public holiday. + * Good Friday is a public holiday. + """ + + country = "FM" + default_language = "en_FM" + # %s (observed). + observed_label = tr("%s (observed)") + # Federated States of Micronesia gained independence on November 3, 1986. + start_year = 1987 + subdivisions = ( + "KSA", # Kosrae. + "PNI", # Pohnpei. + "TRK", # Chuuk. + "YAP", # Yap. + ) + subdivisions_aliases = { + "Kosrae": "KSA", + "Kusaie": "KSA", + "Pohnpei": "PNI", + "Ponape": "PNI", + "Chuuk": "TRK", + "Truk": "TRK", + "Yap": "YAP", + } + supported_languages = ("en_FM", "en_US") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_TO_PREV_FRI + SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("New Year's Day") + self._add_observed(self._add_new_years_day(name)) + self._add_observed(self._next_year_new_years_day, name=name, rule=SAT_TO_PREV_FRI) + + if self._year >= 2011: + self._add_observed( + # Micronesian Culture and Tradition Day. + self._add_holiday_mar_31(tr("Micronesian Culture and Tradition Day")) + ) + + # Federated States of Micronesia Day. + self._add_observed(self._add_holiday_may_10(tr("Federated States of Micronesia Day"))) + + if self._year >= 1991: + # United Nations Day. + self._add_observed(self._add_united_nations_day(tr("United Nations Day"))) + + # Independence Day. + self._add_observed(self._add_holiday_nov_3(tr("Independence Day"))) + + if self._year >= 2004: + # FSM Veterans of Foreign Wars Day. + self._add_observed(self._add_remembrance_day(tr("FSM Veterans of Foreign Wars Day"))) + + if self._year >= 2021: + # Presidents Day. + self._add_observed(self._add_holiday_nov_23(tr("Presidents Day"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day"))) + + # Kosrae. + def _populate_subdiv_ksa_public_holidays(self): + if self._year >= 1991: + # Kosrae State Constitution Day. + self._add_observed(self._add_holiday_jan_11(tr("Kosrae State Constitution Day"))) + + if self._year >= 2000: + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Gospel Day. + self._add_observed(self._add_holiday_aug_21(tr("Gospel Day"))) + + if self._year >= 1991: + # Kosrae Liberation Day. + self._add_observed(self._add_holiday_sep_8(tr("Kosrae Liberation Day"))) + + # Self Government Day. + self._add_observed(self._add_holiday_nov_3(tr("Self Government Day"))) + + if self._year >= 2011: + # Thanksgiving Day. + self._add_holiday_4th_thu_of_nov(tr("Thanksgiving Day")) + + if self._year >= 2024: + # Kosrae Disability Day. + self._add_observed(self._add_holiday_dec_3(tr("Kosrae Disability Day"))) + + # Pohnpei. + def _populate_subdiv_pni_public_holidays(self): + if self._year >= 2022: + # Women's Day. + self._add_observed(self._add_womens_day(tr("Women's Day"))) + + # Pohnpei Cultural Day. + self._add_observed(self._add_holiday_mar_31(tr("Pohnpei Cultural Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Liberation Day. + self._add_observed(self._add_holiday_sep_11(tr("Liberation Day"))) + + # Pohnpei Constitution Day. + self._add_observed(self._add_holiday_nov_8(tr("Pohnpei Constitution Day"))) + + # Chuuk. + def _populate_subdiv_trk_public_holidays(self): + # State Charter Day. + self._add_observed(self._add_holiday_sep_26(tr("State Charter Day"))) + + if self._year >= 1990: + # Chuuk State Constitution Day. + self._add_observed(self._add_holiday_oct_1(tr("Chuuk State Constitution Day"))) + + # Yap. + def _populate_subdiv_yap_public_holidays(self): + # Yap Day. + self._add_observed(self._add_holiday_mar_1(tr("Yap Day"))) + + # Yap State Constitution Day. + self._add_observed(self._add_holiday_dec_24(tr("Yap State Constitution Day"))) + + +class FM(Micronesia): + pass + + +class FSM(Micronesia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/moldova.py b/.venv/lib/python3.12/site-packages/holidays/countries/moldova.py new file mode 100644 index 00000000..67381318 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/moldova.py @@ -0,0 +1,101 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import GREGORIAN_CALENDAR +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Moldova(HolidayBase, ChristianHolidays, InternationalHolidays): + """Moldova holidays. + + References: + * + * + """ + + country = "MD" + default_language = "ro" + supported_languages = ("en_US", "ro", "uk") + start_year = 1991 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Anul Nou")) + + name = ( + # Christmas Day (by old style). + tr("Nașterea lui Iisus Hristos (Crăciunul pe stil vechi)") + if self._year >= 2014 + # Christmas Day. + else tr("Nașterea lui Iisus Hristos (Crăciunul)") + ) + self._add_christmas_day(name) + self._add_christmas_day_two(name) + + # International Women's Day. + self._add_womens_day(tr("Ziua internatională a femeii")) + + # Easter. + name = tr("Paștele") + self._add_easter_sunday(name) + self._add_easter_monday(name) + + # Day of Rejoicing. + self._add_holiday_8_days_past_easter(tr("Paștele blajinilor")) + + # International Workers' Solidarity Day. + self._add_labor_day(tr("Ziua internaţională a solidarităţii oamenilor muncii")) + + self._add_world_war_two_victory_day( + # Victory Day and Commemoration of the heroes fallen for + # Independence of Fatherland. + tr("Ziua Victoriei și a comemorării eroilor căzuţi pentru Independenţa Patriei"), + is_western=False, + ) + + if self._year >= 2017: + # Europe Day. + self._add_europe_day(tr("Ziua Europei")) + + if self._year >= 2016: + # International Children's Day. + self._add_childrens_day(tr("Ziua Ocrotirii Copilului")) + + # Republic of Moldova Independence Day. + self._add_holiday_aug_27(tr("Ziua independenţei Republicii Moldova")) + + # National Language Day. + self._add_holiday_aug_31(tr("Limba noastră")) + + if self._year >= 2013: + self._add_christmas_day( + # Christmas Day (by new style). + tr("Nașterea lui Iisus Hristos (Crăciunul pe stil nou)"), + GREGORIAN_CALENDAR, + ) + + +class MD(Moldova): + pass + + +class MDA(Moldova): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/monaco.py b/.venv/lib/python3.12/site-packages/holidays/countries/monaco.py new file mode 100644 index 00000000..2a51c46b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/monaco.py @@ -0,0 +1,93 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Monaco(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Monaco holidays. + + References: + * + * + """ + + country = "MC" + default_language = "fr" + # %s (observed). + observed_label = tr("%s (observé)") + supported_languages = ("en_US", "fr", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, MonacoStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("Le jour de l'An"))) + + # Saint Devote's Day. + self._add_holiday_jan_27(tr("La Sainte Dévote")) + + # Easter Monday. + self._add_easter_monday(tr("Le lundi de Pâques")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Fête de la Travaille"))) + + # Ascension Day. + self._add_ascension_thursday(tr("L'Ascension")) + + # Whit Monday. + self._add_whit_monday(tr("Le lundi de Pentecôte")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("La Fête Dieu")) + + # Assumption Day. + self._add_observed(self._add_assumption_of_mary_day(tr("L'Assomption de Marie"))) + + # All Saints' Day. + self._add_observed(self._add_all_saints_day(tr("La Toussaint"))) + + # Prince's Day. + self._add_observed(self._add_holiday_nov_19(tr("La Fête du Prince"))) + + # Immaculate Conception. + dec_8 = self._add_immaculate_conception_day(tr("L'Immaculée Conception")) + if self._year >= 2019: + self._move_holiday(dec_8, show_observed_label=False) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Noël"))) + + +class MC(Monaco): + pass + + +class MCO(Monaco): + pass + + +class MonacoStaticHolidays: + special_public_holidays = { + # Public holiday. + 2015: (JAN, 7, tr("Jour férié")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/mongolia.py b/.venv/lib/python3.12/site-packages/holidays/countries/mongolia.py new file mode 100644 index 00000000..f1115b09 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/mongolia.py @@ -0,0 +1,202 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import _timedelta +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import InternationalHolidays, MongolianCalendarHolidays +from holidays.holiday_base import HolidayBase + + +class Mongolia(HolidayBase, InternationalHolidays, MongolianCalendarHolidays): + """Mongolia holidays. + + References: + * [Law on Public holidays and days of observation](https://web.archive.org/web/20250327062440/https://legalinfo.mn/mn/detail/399) + * [Labor Law](https://web.archive.org/web/20250421093230/https://legalinfo.mn/mn/detail?lawId=16230709635751) + * + * [Mongolian lunar calendar](https://web.archive.org/web/20230412171012/https://www.math.mcgill.ca/gantumur/cal/index_mn.html) + * + * + """ + + country = "MN" + default_language = "mn" + start_year = 2004 + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("en_US", "mn") + + def __init__(self, *args, **kwargs): + InternationalHolidays.__init__(self) + MongolianCalendarHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Шинэ жил")) + + # Lunar New Year. + name = tr("Цагаан сар") + self._add_tsagaan_sar(name) + self._add_tsagaan_sar_day_2(name) + # Expanded on November 28th, 2013. + if self._year >= 2014: + self._add_tsagaan_sar_day_3(name) + + # International Women's Day. + self._add_womens_day(tr("Олон улсын эмэгтэйчүүдийн өдөр")) + + # Children's Day. + self._add_childrens_day(tr("Хүүхдийн баяр")) + + # Established on December 20th, 2019. + if self._year >= 2020: + # The Buddha's Birthday. + self._add_buddha_day(tr("Бурхан багшийн Их дүйчин өдөр")) + + # National Festival and People's Revolution Anniversary. + name = tr("Үндэсний их баяр наадам, Ардын хувьсгалын ойн баяр") + # Expanded to July 10 on July 7th, 2023. + if self._year >= 2023: + self._add_holiday_jul_10(name) + self._add_holiday_jul_11(name) + self._add_holiday_jul_12(name) + self._add_holiday_jul_13(name) + # Expanded to July 14-15 on July 1st, 2014. + if self._year >= 2014: + self._add_holiday_jul_14(name) + self._add_holiday_jul_15(name) + + # Established on November 8th, 2012. + if self._year >= 2012: + # Genghis Khan's Birthday. + self._add_genghis_khan_day(tr("Их Эзэн Чингис хааны өдөр")) + + # Repealed on November 8th, 2012. + # Re-established again on November 18th, 2016. + if self._year <= 2011 or self._year >= 2016: + self._add_holiday_nov_26( + # Republic Day. + tr("Бүгд Найрамдах Улс тунхагласан өдөр") + if self._year >= 2016 + # Republic Holiday. + else tr("Бүгд Найрамдах Улс тунхагласны баяр") + ) + + # Established on August 16th, 2007. + # Renamed and considered a Public Holiday on December 23rd, 2011. + if self._year >= 2011: + self._add_holiday_dec_29( + # National Freedom and Independence Day. + tr("Үндэсний эрх чөлөө, тусгаар тогтнолоо сэргээсний баярын өдөр") + ) + + def _populate_workday_holidays(self): + """ + NOTE: + The following observances are currently unimplemented + due to unclear week-based scheduling rules: + + 1. National Literary, Cultural and Book Days (Үндэсний бичиг соёл, номын өдрүүд): + - Observed on Saturday and Sunday of the 3rd week of May and September. + - Officially added on July 2nd, 2021. + + 2. Environmental Protection Days (Байгаль орчныг хамгаалах өдрүүд): + - Observed during the 4th week of September. + + These are defined using "week of the month" logic, but it is unclear whether weeks start + from the 1st of the month or the first full week. We previously contacted + contact@mecc.gov.mn for clarification but received no response. + + See: + https://github.com/vacanza/holidays/issues/2672 + """ + + # Constitution Day. + self._add_holiday_jan_13(tr("Монгол Улсын Үндсэн хуулийн өдөр")) + + # Established on December 9th, 2004. + if self._year >= 2005: + # Patriots' Day. + self._add_holiday_mar_1(tr("Эх орончдын өдөр")) + + # Renamed on February 9th, 2011. + self._add_holiday_mar_18( + # Military Day. + tr("Монгол цэргийн өдөр") + if self._year >= 2011 + # Armed Forces Day. + else tr("Зэвсэгт хүчний өдөр") + ) + + # Health Protection Day. + self._add_holiday_apr_7(tr("Эрүүл мэндийг хамгаалах өдөр")) + + # Intellectual Property Protection Day. + self._add_holiday_apr_26(tr("Оюуны өмчийг хамгаалах өдөр")) + + # Family Day. + self._add_holiday_may_15(tr("Гэр бүлийн өдөр")) + + # Established on June 11th, 2009. + if self._year >= 2009: + # National Flag Day. + self._add_holiday_jul_10(tr("Монгол Улсын төрийн далбааны өдөр")) + + # Youth Day. + self._add_holiday_aug_25(tr("Залуучуудын өдөр")) + + if self._year >= 2007: + # New Harvest Days. + name = tr("Шинэ ургацын өдрүүд") + dt = self._add_holiday_sep_5(name) + for delta in range(1, 46): + self._add_holiday(name, _timedelta(dt, delta)) + + # Memorial Day of Political Victims. + self._add_holiday_sep_10(tr("Улс төрийн хэлмэгдэгсдийн дурсгалын өдөр")) + + # Elders' Day. + self._add_holiday_oct_1(tr("Ахмадын өдөр")) + + # Renamed on July 7th, 2021. + self._add_holiday_oct_29( + # Capital City Day. + tr("Монгол Улсын нийслэл хотын өдөр") + if self._year >= 2021 + # Capital Day. + else tr("Монгол Улсын Нийслэлийн өдөр") + ) + + # Established on November 8th, 2012 after the old one was repealed. + # Made a Public Holiday again on November 8th, 2016. + if 2012 <= self._year <= 2015: + # Republic Day. + self._add_holiday_nov_26(tr("Бүгд Найрамдах Улс тунхагласан өдөр")) + + # Democracy and Human Rights Day. + self._add_holiday_dec_10(tr("Ардчилал, хүний эрхийн өдөр")) + + # Established on August 16th, 2007. + # Renamed and considered a Public Holiday on December 23rd, 2011. + if 2007 <= self._year <= 2010: + # National Freedom Day. + self._add_holiday_dec_29(tr("Үндэсний эрх чөлөөний өдөр")) + + +class MN(Mongolia): + pass + + +class MNG(Mongolia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/montenegro.py b/.venv/lib/python3.12/site-packages/holidays/countries/montenegro.py new file mode 100644 index 00000000..251135b2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/montenegro.py @@ -0,0 +1,203 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import GREGORIAN_CALENDAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.constants import CATHOLIC, HEBREW, ISLAMIC, ORTHODOX, PUBLIC, WORKDAY +from holidays.groups import ( + ChristianHolidays, + HebrewCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class Montenegro( + ObservedHolidayBase, + ChristianHolidays, + HebrewCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Montenegro holidays. + + References: + * + * [Zakon o državnim i drugim praznicima](https://web.archive.org/web/20241227132503/https://wapi.gov.me/download-preview/927f23a3-db4e-4f65-9f29-ce3c9dde0c90?version=1.0) + * [Zakon o svetkovanju vjerskih praznika](https://web.archive.org/web/20250427181807/https://wapi.gov.me/download-preview/4f0b05a4-c85b-4eb2-bc29-0ad8363a9ba3?version=1.0) + """ + + country = "ME" + default_language = "cnr" + # %s (estimated). + estimated_label = tr("%s (procijenjeno)") + # %s (observed). + observed_label = tr("%s (neradni dan)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (neradni dan, procijenjeno)") + supported_languages = ("cnr", "en_US", "uk") + supported_categories = (CATHOLIC, ISLAMIC, HEBREW, ORTHODOX, PUBLIC, WORKDAY) + start_year = 2007 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self, calendar=JULIAN_CALENDAR) + HebrewCalendarHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=MontenegroIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=MontenegroStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Nova godina") + self._add_observed(self._add_new_years_day(name), rule=SUN_TO_NEXT_TUE) + self._add_observed(self._add_new_years_day_two(name)) + + # Labor Day. + name = tr("Praznik rada") + self._add_observed(self._add_labor_day(name), rule=SUN_TO_NEXT_TUE) + self._add_observed(self._add_labor_day_two(name)) + + # Independence Day. + name = tr("Dan nezavisnosti") + self._add_observed(self._add_holiday_may_21(name), rule=SUN_TO_NEXT_TUE) + self._add_observed(self._add_holiday_may_22(name)) + + # Statehood Day. + name = tr("Dan državnosti") + self._add_observed(self._add_holiday_jul_13(name), rule=SUN_TO_NEXT_TUE) + self._add_observed(self._add_holiday_jul_14(name)) + + if self._year >= 2022: + # Njegos Day. + self._add_observed(self._add_holiday_nov_13(tr("Njegošev dan"))) + + def _populate_catholic_holidays(self): + # Good Friday. + self._add_good_friday(tr("Veliki petak"), GREGORIAN_CALENDAR) + + # Easter. + self._add_easter_monday(tr("Uskrs"), GREGORIAN_CALENDAR) + + # All Saints' Day. + self._add_all_saints_day(tr("Svi Sveti")) + + # Christmas Eve. + self._add_christmas_eve(tr("Badnji dan"), GREGORIAN_CALENDAR) + + # Christmas. + name = tr("Božić") + self._add_christmas_day(name, GREGORIAN_CALENDAR) + self._add_christmas_day_two(name, GREGORIAN_CALENDAR) + + def _populate_hebrew_holidays(self): + # Pesach. + self._add_passover(tr("Pasha"), range(2)) + + # Yom Kippur. + self._add_yom_kippur(tr("Jom Kipur"), range(2)) + + def _populate_islamic_holidays(self): + # Eid al-Fitr. + name = tr("Ramazanski bajram") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + self._add_eid_al_fitr_day_three(name) + + # Eid al-Adha. + name = tr("Kurbanski bajram") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_eid_al_adha_day_three(name) + + def _populate_orthodox_holidays(self): + # Good Friday. + self._add_good_friday(tr("Veliki petak")) + + # Easter. + self._add_easter_monday(tr("Uskrs")) + + # Christmas Eve. + self._add_christmas_eve(tr("Badnji dan")) + + # Christmas. + name = tr("Božić") + self._add_christmas_day(name) + self._add_christmas_day_two(name) + + def _populate_workday_holidays(self): + if self._year >= 2022: + # Ecological State Day. + self._add_holiday_sep_20(tr("Dan Ekološke države")) + + +class ME(Montenegro): + pass + + +class MNE(Montenegro): + pass + + +class MontenegroIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + } + + EID_AL_FITR_DATES = { + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + } + + +class MontenegroStaticHolidays: + special_public_holidays = { + 2024: (NOV, 14, tr("Njegošev dan")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/montserrat.py b/.venv/lib/python3.12/site-packages/holidays/countries/montserrat.py new file mode 100644 index 00000000..ddc2be1a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/montserrat.py @@ -0,0 +1,177 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import APR, MAY, JUN, JUL, SEP, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SAT_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Montserrat(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Montserrat holidays. + + References: + * + * [Public holidays Act, 2017](https://web.archive.org/web/20240619074948/http://agc.gov.ms/wp-content/uploads/2011/10/Act-No.-3-of-2017-Public-Holidays-Amendment-Act-20171.pdf) + * [Public holidays Act, 2019](https://web.archive.org/web/20241025070627/https://www.gov.ms/wp-content/uploads/2020/06/Public-Holidays-Act.pdf) + * [National Day of Prayer and Thanksgiving, 2021](https://web.archive.org/web/20220809144840/https://www.gov.ms/2021/07/16/wednesday-july-21-2021-public-holiday-national-day-of-prayer-thanksgiving/) + * [National Day of Prayer and Thanksgiving, 2022](https://web.archive.org/web/20220816124619/https://www.gov.ms/2022/07/19/public-holiday-for-national-day-of-prayer-and-thanksgiving-to-be-held-on-july-20-2022/) + * [National Day of Prayer and Thanksgiving](https://web.archive.org/web/20240711221313/https://www.gov.ms/wp-content/uploads/2023/05/SRO-No.-15-of-2023-Public-Holidays-Amendment-of-Schedule-Order.pdf) + * [Queen's Platinum Jubilee, 2022](https://web.archive.org/web/20250711160439/https://www.gov.ms/tag/public-holidays/) + * [Montserrat Public holidays, 2022](https://web.archive.org/web/20220809030551/https://www.gov.ms/wp-content/uploads/2021/12/Public-Holidays-2022-1.jpeg) + * [Montserrat Public holidays, 2023](https://web.archive.org/web/20241126232715/https://www.gov.ms/wp-content/uploads/2023/02/Public-Holidays-Montserrat-2023_page-0001.jpg) + * [Montserrat Public holidays, 2024](https://web.archive.org/web/20240421112540/https://www.gov.ms/wp-content/uploads/2023/12/Public-Holidays-Montserrat-2024.docx.pdf) + * [King's Birthday, 2024](https://web.archive.org/web/20250711202228/https://parliament.ms/wp-content/uploads/2024/09/SRO-No.-18-of-2024-PROCOLAMATION-APPOINTING-MONDAY-17-JUNE-2024-AS-A-PUBLIC-HOLIDAY.pdf) + * [Montserrat Public holidays, 2025](https://web.archive.org/web/20250711160324/https://www.gov.ms/wp-content/uploads/2025/01/2025-Public-Holidays-on-Montserrat.pdf) + """ + + country = "MS" + default_language = "en_MS" + # %s (observed). + observed_label = "%s (observed)" + # Public holidays Act, 2017. + start_year = 2017 + supported_languages = ("en_MS", "en_US") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, MontserratStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self._add_observed( + # New Year's Day. + self._add_new_years_day(tr("New Year's Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE + MON_TO_NEXT_TUE, + ) + + # Saint Patrick's Day. + self._add_observed(self._add_holiday_mar_17(tr("Saint Patrick's Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Labor Day. + self._add_holiday_1st_mon_of_may(tr("Labour Day")) + + name = ( + # King's Birthday. + tr("King's Birthday") + if self._year >= 2023 + # Queen's Birthday. + else tr("Queen's Birthday") + ) + sovereign_birthday_dts = { + 2022: (JUN, 2), + 2023: (JUN, 19), + 2024: (JUN, 17), + } + sovereign_birthday_dt = ( + self._add_holiday(name, dt) + if (dt := sovereign_birthday_dts.get(self._year)) + else self._add_holiday_2_days_past_2nd_sat_of_jun(name) + ) + + # Whit Monday. + name = tr("Whit Monday") + whit_monday_dt = self._add_whit_monday(name) + if whit_monday_dt == sovereign_birthday_dt: + self._add_observed(whit_monday_dt, name=name, rule=MON_TO_NEXT_TUE) + + if self._year >= 2021: + day_of_prayer_dts = { + 2021: (JUL, 21), + 2022: (JUL, 20), + } + name = ( + # National Day of Prayer and Thanksgiving. + tr("National Day of Prayer and Thanksgiving") + if self._year <= 2023 + # Day of Prayer and Thanksgiving. + else tr("Day of Prayer and Thanksgiving") + ) + if dt := day_of_prayer_dts.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_2nd_wed_of_jul(name) + + # Emancipation Day. + self._add_holiday_1st_mon_of_aug(tr("Emancipation Day")) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + # Festival Day. + name = tr("Festival Day") + self._add_new_years_eve(name) + self._add_observed((self._year - 1, DEC, 31), name, rule=SAT_TO_NEXT_MON) + + +class MS(Montserrat): + pass + + +class MSR(Montserrat): + pass + + +class MontserratStaticHolidays(StaticHolidays): + """Montserrat special holidays. + + References: + * [September 14th, 2018](https://web.archive.org/web/20220810224300/https://www.gov.ms/wp-content/uploads/2020/11/SRO.-No.-35-of-2018-Proclamation-Declaring-Friday-14-September-2018-as-a-public-holiday.pdf) + * [May 10th, 2019](https://web.archive.org/web/20240626113529/https://parliament.ms/wp-content/uploads/2022/02/SRO-No-13-of-2019-Proclamation-Declaring-Friday-10-May-2019-as-a-publi._.pdf) + * [July 15th, 2020](https://web.archive.org/web/20220810225456/https://www.gov.ms/wp-content/uploads/2020/08/SRO.-No.-40-of-2020-Proclamation-Declaring-Wednesday-15-July-2020-as-a-Public-Holiday.pdf) + * [National Day of Mourning](https://web.archive.org/web/20240617072858/https://www.parliament.ms/wp-content/uploads/2022/09/SRO-No.43-of-2022-Proclamation-Appointing-Monday-19-September-2022-a-Public-Holiday.pdf) + * [Coronation of King Charles III](https://web.archive.org/web/20241126232715/https://www.gov.ms/wp-content/uploads/2023/02/Public-Holidays-Montserrat-2023_page-0001.jpg) + """ + + # Special Public Holiday. + name = tr("Special Public Holiday") + + special_public_holidays = { + 2018: (SEP, 14, name), + 2019: (MAY, 10, name), + 2020: (JUL, 15, name), + 2022: ( + # Platinum Jubilee of Elizabeth II. + (JUN, 3, tr("Platinum Jubilee of Elizabeth II")), + # National Day of Mourning. + (SEP, 19, tr("National Day of Mourning")), + ), + 2023: ( + (APR, 12, name), + # Coronation of King Charles III. + (MAY, 6, tr("Coronation of King Charles III")), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/morocco.py b/.venv/lib/python3.12/site-packages/holidays/countries/morocco.py new file mode 100644 index 00000000..c6ef8fc2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/morocco.py @@ -0,0 +1,115 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import IslamicHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Morocco(HolidayBase, InternationalHolidays, IslamicHolidays): + """Morocco holidays. + + References: + * + * + """ + + country = "MA" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + supported_languages = ("ar", "en_US", "fr") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + if self._year >= 1945: + # Proclamation of Independence Day. + self._add_holiday_jan_11(tr("ذكرى تقديم وثيقة الاستقلال")) + + # In May 2023, Morocco recognized Berber New Year as official holiday. + # https://web.archive.org/web/20230515114330/https://www.diplomatie.ma/en/statement-royal-office-12 + if self._year >= 2024: + # Amazigh New Year. + self._add_holiday_jan_13(tr("رأس السنة الأمازيغية")) + + # Labor Day. + self._add_labor_day(tr("عيد العمال")) + + # Throne day. + name = tr("عيد العرش") + if self._year >= 2001: + self._add_holiday_jul_30(name) + elif self._year >= 1963: + self._add_holiday_mar_3(name) + else: + self._add_holiday_nov_18(name) + + # Oued Ed-Dahab Day. + self._add_holiday_aug_14(tr("ذكرى استرجاع إقليم وادي الذهب")) + + # Revolution Day. + self._add_holiday_aug_20(tr("ذكرى ثورة الملك و الشعب")) + + # Youth Day. + name = tr("عيد الشباب") + if self._year >= 2001: + self._add_holiday_aug_21(name) + else: + self._add_holiday_jul_9(name) + + if self._year >= 1976: + # Green March. + self._add_holiday_nov_6(tr("ذكرى المسيرة الخضراء")) + + if self._year >= 1957: + # Independence Day. + self._add_holiday_nov_18(tr("عيد الإستقلال")) + + # Eid al-Fitr. + name = tr("عيد الفطر") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + + # Eid al-Adha. + name = tr("عيد الأضحى") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Prophet's Birthday. + name = tr("عيد المولد النبوي") + self._add_mawlid_day(name) + self._add_mawlid_day_two(name) + + +class MA(Morocco): + pass + + +class MOR(Morocco): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/mozambique.py b/.venv/lib/python3.12/site-packages/holidays/countries/mozambique.py new file mode 100644 index 00000000..7fe39369 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/mozambique.py @@ -0,0 +1,72 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Mozambique(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Mozambique holidays.""" + + country = "MZ" + default_language = "pt_MZ" + # %s (observed). + observed_label = tr("%s (ponte)") + supported_languages = ("en_US", "pt_MZ", "uk") + start_year = 1975 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # International Fraternalism Day. + self._add_observed(self._add_new_years_day(tr("Dia da Fraternidade universal"))) + + # Heroes' Day. + self._add_observed(self._add_holiday_feb_3(tr("Dia dos Heróis Moçambicanos"))) + + # Women's Day. + self._add_observed(self._add_holiday_apr_7(tr("Dia da Mulher Moçambicana"))) + + # International Workers' Day. + self._add_observed(self._add_labor_day(tr("Dia Internacional dos Trabalhadores"))) + + # Independence Day. + self._add_observed(self._add_holiday_jun_25(tr("Dia da Independência Nacional"))) + + # Victory Day. + self._add_observed(self._add_holiday_sep_7(tr("Dia da Vitória"))) + + self._add_observed( + # Armed Forces Day. + self._add_holiday_sep_25(tr("Dia das Forças Armadas de Libertação Nacional")) + ) + + if self._year >= 1993: + # Peace and Reconciliation Day. + self._add_observed(self._add_holiday_oct_4(tr("Dia da Paz e Reconciliação"))) + + # Family Day. + self._add_observed(self._add_christmas_day(tr("Dia da Família"))) + + +class MZ(Mozambique): + pass + + +class MOZ(Mozambique): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/namibia.py b/.venv/lib/python3.12/site-packages/holidays/countries/namibia.py new file mode 100644 index 00000000..34235e6a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/namibia.py @@ -0,0 +1,161 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, FEB, MAR, SEP, OCT, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Namibia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Namibia holidays. + + References: + * [Public Holidays Act, 1990](https://web.archive.org/web/20250322163344/https://namiblii.org/akn/na/act/1990/26/eng@2004-12-17) + * [Public Holidays Amendment Act, 2004](https://web.archive.org/web/20221015121213/https://namiblii.org/akn/na/act/2004/16/eng@2004-12-17) + * [Genocide Remembrance Day](https://web.archive.org/web/20250126055207/https://namiblii.org/akn/na/officialGazette/government-gazette/2024-05-28/8373/eng@2024-05-28) + + As of 1991/2/1, whenever a public holiday falls on a Sunday, it rolls over to the Monday, + unless that Monday is already a public holiday. + Since the interval from 1991/1/1 to 1991/2/1 includes only New Year's Day, and it's a Tuesday, + we can assume that the beginning is 1991. + """ + + country = "NA" + default_language = "en_NA" + # %s (observed). + observed_label = tr("%s (observed)") + start_year = 1991 + supported_languages = ("en_NA", "en_US", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, NamibiaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Independence Day. + self._add_observed(self._add_holiday_mar_21(tr("Independence Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Workers' Day. + self._add_observed(self._add_labor_day(tr("Workers' Day"))) + + # Cassinga Day. + self._add_observed(self._add_holiday_may_4(tr("Cassinga Day"))) + + # Africa Day. + self._add_observed(self._add_africa_day(tr("Africa Day"))) + + if self._year >= 2025: + # Genocide Remembrance Day. + self._add_holiday_may_28(tr("Genocide Remembrance Day")) + + # Ascension Day. + self._add_ascension_thursday(tr("Ascension Day")) + + # Heroes' Day. + self._add_observed(self._add_holiday_aug_26(tr("Heroes' Day"))) + + self._add_observed( + self._add_holiday_sep_10( + # Day of the Namibian Women and International Human Rights Day. + tr("Day of the Namibian Women and International Human Rights Day") + if self._year >= 2005 + # International Human Rights Day. + else tr("International Human Rights Day") + ) + ) + + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")) + + # Family Day. + self._add_observed(self._add_christmas_day_two(tr("Family Day"))) + + +class NA(Namibia): + pass + + +class NAM(Namibia): + pass + + +class NamibiaStaticHolidays: + """Namibia special holidays. + + References: + * [March 1, 1994](https://web.archive.org/web/20241210145818/https://namiblii.org/akn/na/officialGazette/government-gazette/1994-02-15/797/eng@1994-02-15) + * [December 7, 1994](https://web.archive.org/web/20250613113650/https://namiblii.org/akn/na/officialGazette/government-gazette/1994-11-30/987/eng@1994-11-30) + * [October 24, 1995](https://web.archive.org/web/20250613184422/https://namiblii.org/akn/na/officialGazette/government-gazette/1995-10-20/1178/eng@1995-10-20) + * [September 26, 1997](https://web.archive.org/web/20250613172016/https://namiblii.org/akn/na/officialGazette/government-gazette/1997-09-25/1690/eng@1997-09-25) + * [November 30, 1998](https://web.archive.org/web/20250613184549/https://namiblii.org/akn/na/officialGazette/government-gazette/1998-11-06/1988/eng@1998-11-06) + * [November 30, 1999](https://web.archive.org/web/20241012184236/https://namiblii.org/akn/na/officialGazette/government-gazette/1999-10-08/2202/eng@1999-10-08) + * [Y2K changeover](https://web.archive.org/web/20250613145912/https://namiblii.org/akn/na/officialGazette/government-gazette/1999-11-22/2234/eng@1999-11-22) + * [November 28, 2014](https://web.archive.org/web/20250613184051/https://namiblii.org/akn/na/officialGazette/government-gazette/2014-11-07/5609/eng@2014-11-07) + * [November 27, 2015](https://web.archive.org/web/20250613184258/https://namiblii.org/akn/na/officialGazette/government-gazette/2015-11-26/5885/eng@2015-11-26) + * [November 27, 2019](https://web.archive.org/web/20241112233422/https://namiblii.org/akn/na/officialGazette/government-gazette/2019-09-30/7008/eng@2019-09-30) + * [November 25, 2020](https://web.archive.org/web/20250613112403/https://namiblii.org/akn/na/officialGazette/government-gazette/2020-11-19/7394/eng@2020-11-19) + * [February 25, 2024](https://web.archive.org/web/20241203060851/https://namiblii.org/akn/na/officialGazette/government-gazette/2024-02-20/8312/eng@2024-02-20) + * [November 27, 2024](https://web.archive.org/web/20250514020246/https://namiblii.org/akn/na/officialGazette/government-gazette/2024-09-26/8454/eng@2024-09-26) + * [March 1, 2025](https://web.archive.org/web/20250613172517/https://namiblii.org/akn/na/officialGazette/government-gazette/2025-02-14/8577/eng@2025-02-14) + """ + + # Y2K changeover. + y2k_changeover = tr("Y2K changeover") + + # General Election Day. + general_election_day = tr("General Election Day") + + # Regional Election Day. + regional_election_day = tr("Regional Election Day") + + special_public_holidays = { + 1994: ( + # Walvis Bay Reintegration Day. + (MAR, 1, tr("Walvis Bay Reintegration Day")), + (DEC, 7, general_election_day), + ), + # Public Holiday. + 1995: (OCT, 24, tr("Public Holiday")), + # Day of Mourning for Honourable Moses Garoeb. + 1997: (SEP, 26, tr("Day of Mourning for Honourable Moses Garoeb")), + 1998: (NOV, 30, regional_election_day), + 1999: ( + (NOV, 30, general_election_day), + (DEC, 31, y2k_changeover), + ), + 2000: (JAN, 3, y2k_changeover), + 2014: (NOV, 28, general_election_day), + 2015: (NOV, 27, regional_election_day), + 2019: (NOV, 27, general_election_day), + 2020: (NOV, 25, regional_election_day), + 2024: ( + # Burial ceremony of Dr. Hage Gottfried Geingob. + (FEB, 25, tr("Burial ceremony of Dr. Hage Gottfried Geingob")), + (NOV, 27, general_election_day), + ), + # Burial ceremony of Dr. Sam Shafiishuna Nujoma. + 2025: (MAR, 1, tr("Burial ceremony of Dr. Sam Shafiishuna Nujoma")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/nauru.py b/.venv/lib/python3.12/site-packages/holidays/countries/nauru.py new file mode 100644 index 00000000..b9e3ba87 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/nauru.py @@ -0,0 +1,129 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Nauru(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Nauru holidays. + + References: + * + * [Public Service Act 2016](https://web.archive.org/web/20250613095858/https://ronlaw.gov.nr/assets/docs/acts/2016/Public%20Service%20Act%202016_serv4.pdf) + * [Nauru's Online Legal Database](https://web.archive.org/web/20250501021029/https://ronlaw.gov.nr/) + * + + Gazettes: + * [Public Holidays 2019](https://web.archive.org/web/20250613095031/https://ronlaw.gov.nr/assets/docs/gazettes/2018/11/Gazette%20No.%20175%20(28%20November%202018).pdf) + * [Public Holidays 2021](https://web.archive.org/web/20250613102242/https://ronlaw.gov.nr/assets/docs/gazettes/2020/12/Gazette%20No.%20227%20(21%20December%202020).pdf) + * [Public Holidays 2022](https://web.archive.org/web/20250613102128/https://ronlaw.gov.nr/assets/docs/gazettes/2022/01/Gazette%20No.%207%20(6%20January%202022).pdf) + * [Public Holidays 2023](https://web.archive.org/web/20250613101855/https://ronlaw.gov.nr/assets/docs/gazettes/2022/12/Gazette%20No.%20330%20(30%20December%202022).pdf) + * [Public Holidays 2024](https://web.archive.org/web/20250613094703/https://ronlaw.gov.nr/assets/docs/gazettes/2024/01/Nauru%20Government%20Gazette,%20No.%2014%20(15%20January%202024).pdf) + * [RONPHOS Handover Day 2018](https://web.archive.org/web/20250613095226/https://ronlaw.gov.nr/assets/docs/gazettes/2018/06/Gazette%20No.%20102%20(29%20June%202018).pdf) + * [Ibumin Earoeni Day 2019](https://web.archive.org/web/20250613095413/https://ronlaw.gov.nr/assets/docs/gazettes/2019/08/Gazette%20No.%20139%20(12%20August%202019).pdf) + * [Sir Hammer DeRoburt Day 2020](https://web.archive.org/web/20250614102647/https://ronlaw.gov.nr/assets/docs/gazettes/2020/09/Gazette%20No.%20171%20(10%20September%202020).pdf) + """ + + country = "NR" + default_language = "en_NR" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_NR", "en_US") + # Nauru gained independence on January 31, 1968. + start_year = 1969 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + self._add_observed( + # Independence Day. + self._add_holiday_jan_31(tr("Independence Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Day following Independence Day. + self._add_holiday_feb_1(tr("Day following Independence Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + if self._year >= 2019: + # International Women's Day. + self._add_observed(self._add_womens_day(tr("International Women's Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Easter Tuesday. + self._add_easter_tuesday(tr("Easter Tuesday")) + + # Constitution Day. + self._add_observed(self._add_holiday_may_17(tr("Constitution Day"))) + + if self._year >= 2018: + # RONPHOS Handover. + self._add_observed(self._add_holiday_jul_1(tr("RONPHOS Handover"))) + + if self._year >= 2019: + # Ibumin Earoeni Day. + self._add_observed(self._add_holiday_aug_19(tr("Ibumin Earoeni Day"))) + + if self._year >= 2001: + self._add_observed( + self._add_holiday_sep_25( + # Sir Hammer DeRoburt Day. + tr("Sir Hammer DeRoburt Day") + if self._year >= 2020 + # National Youth Day. + else tr("National Youth Day") + ) + ) + + # Angam Day. + self._add_observed(self._add_holiday_oct_26(tr("Angam Day"))) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Day following Christmas. + self._add_christmas_day_two(tr("Day following Christmas")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + +class NR(Nauru): + pass + + +class NRU(Nauru): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/nepal.py b/.venv/lib/python3.12/site-packages/holidays/countries/nepal.py new file mode 100644 index 00000000..b56f6812 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/nepal.py @@ -0,0 +1,441 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars import _CustomIslamicHolidays, _CustomHinduHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ( + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.holiday_base import HolidayBase + + +class Nepal( + HolidayBase, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Nepal holidays. + + References: + * + * + * + * + * + * + * + * + * + * + """ + + country = "NP" + # %s (estimated). + estimated_label = "%s (estimated)" + start_year = 2010 + supported_categories = (PUBLIC, WORKDAY) + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=NepalHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=NepalIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=NepalStaticHolidays) + super().__init__(*args, **kwargs) + + def _add_non_continuous_holidays(self, is_workday: bool = False): + """Holidays removed by MoHA between 2019-2020.""" + if (2019 <= self._year <= 2020) == is_workday: + martyrs_day_dates = { + 2010: (JAN, 30), + 2011: (JAN, 30), + 2012: (JAN, 30), + 2013: (JAN, 29), + 2014: (JAN, 30), + 2015: (JAN, 30), + 2016: (JAN, 30), + 2017: (JAN, 29), + 2018: (JAN, 30), + 2019: (JAN, 30), + 2020: (JAN, 30), + 2021: (JAN, 29), + 2022: (JAN, 30), + 2023: (JAN, 30), + 2024: (JAN, 30), + 2025: (JAN, 29), + 2026: (JAN, 29), + 2027: (JAN, 29), + 2028: (JAN, 29), + 2029: (JAN, 29), + 2030: (JAN, 29), + 2031: (JAN, 30), + 2032: (JAN, 30), + 2033: (JAN, 29), + } + if dt := martyrs_day_dates.get(self._year): + # Martyr's Day. + self._add_holiday("Martyr's Day", dt) + + democracy_day_dates = { + 2010: (FEB, 19), + 2011: (FEB, 19), + 2012: (FEB, 19), + 2013: (FEB, 18), + 2014: (FEB, 19), + 2015: (FEB, 19), + 2016: (FEB, 19), + 2017: (FEB, 18), + 2018: (FEB, 19), + 2019: (FEB, 19), + 2020: (FEB, 19), + 2021: (FEB, 19), + 2022: (FEB, 19), + 2023: (FEB, 19), + 2024: (FEB, 19), + 2025: (FEB, 19), + 2026: (FEB, 19), + 2027: (FEB, 19), + 2028: (FEB, 19), + 2029: (FEB, 19), + 2030: (FEB, 19), + 2031: (FEB, 20), + 2032: (FEB, 20), + 2033: (FEB, 19), + } + if dt := democracy_day_dates.get(self._year): + # National Democracy Day. + self._add_holiday("National Democracy Day", dt) + + republic_day_dates = { + 2010: (MAY, 29), + 2011: (MAY, 29), + 2012: (MAY, 28), + 2013: (MAY, 29), + 2014: (MAY, 29), + 2015: (MAY, 29), + 2016: (MAY, 28), + 2017: (MAY, 29), + 2018: (MAY, 29), + 2019: (MAY, 29), + 2020: (MAY, 28), + 2021: (MAY, 29), + 2022: (MAY, 29), + 2023: (MAY, 29), + 2024: (MAY, 28), + 2025: (MAY, 28), + 2026: (MAY, 29), + 2027: (MAY, 29), + 2028: (MAY, 28), + 2029: (MAY, 28), + 2030: (MAY, 29), + 2031: (MAY, 29), + 2032: (MAY, 28), + } + if dt := republic_day_dates.get(self._year): + # Established in 2009. + # Republic Day. + self._add_holiday("Republic Day", dt) + + # Hindu Holidays. + + # Ram Navami. + self._add_ram_navami("Ram Navami") + + # Janai Poornima. + self._add_raksha_bandhan("Janai Poornima") + + # Shree Krishna Janmashtami. + self._add_janmashtami("Shree Krishna Janmashtami") + + # Ghatasthapana. + self._add_sharad_navratri("Ghatasthapana") + + # Duwadashi (Dashain). + self._add_papankusha_duwadashi("Duwadashi (Dashain)") + + def _populate_public_holidays(self): + if self._year >= 2023: + # Prithvi Jayanti. + self._add_holiday_jan_11("Prithvi Jayanti") + + # International Women's Day. + self._add_womens_day("International Women's Day") + + # Nepal New Year. + self._add_vaisakhi("Nepali New Year") + + # International Labour Day. + self._add_labor_day("International Labour Day") + + constitution_day_dates = { + 2016: (SEP, 19), + 2017: (SEP, 19), + 2018: (SEP, 19), + 2019: (SEP, 20), + 2020: (SEP, 19), + 2021: (SEP, 19), + 2022: (SEP, 19), + 2023: (SEP, 20), + 2024: (SEP, 19), + 2025: (SEP, 19), + 2026: (SEP, 19), + 2027: (SEP, 19), + 2028: (SEP, 18), + 2029: (SEP, 19), + 2030: (SEP, 19), + 2031: (SEP, 19), + 2032: (SEP, 19), + } + if dt := constitution_day_dates.get(self._year): + # Constitution Day. + self._add_holiday("Constitution Day", dt) + + # Christmas Day. + self._add_christmas_day("Christmas Day") + + # Hindu holidays. + + # Maghe Sankranti. + self._add_makar_sankranti("Maghe Sankranti") + + # Sonam Lhochhar. + self._add_sonam_losar("Sonam Lhochhar") + + # Maha Shivaratri. + self._add_maha_shivaratri("Maha Shivaratri") + + # Gyalpo Lhosar. + self._add_gyalpo_losar("Gyalpo Lhosar") + + # Fagu Poornima. + self._add_nepal_holi("Fagu Poornima") + + # Fagu Poornima (Terai). + self._add_holi("Fagu Poornima (Terai)") + + # Buddha Jayanti. + self._add_buddha_purnima("Buddha Jayanti") + + # Fulpati. + self._add_maha_saptami("Fulpati") + + # Maha Ashtami. + self._add_maha_ashtami("Maha Ashtami") + + # Maha Navami. + self._add_maha_navami("Maha Navami") + + # Bijaya Dashami. + self._add_dussehra("Bijaya Dashami") + + # Ekadashi (Dashain). + self._add_papankusha_ekadashi("Ekadashi (Dashain)") + + # Laxmi Pooja. + self._add_diwali_india("Laxmi Pooja") + + # Gai Tihar. + self._add_gau_krida("Gai Tihar") + + # Gobardhan Pooja. + self._add_govardhan_puja("Gobardhan Pooja") + + # Mha Pooja. + self._add_govardhan_puja("Mha Pooja") + + # Bhai Tika. + self._add_bhai_dooj("Bhai Tika") + + # Chhath Parva. + self._add_chhath_puja("Chhath Parva") + + # Tamu Lhochhar. + self._add_tamu_losar("Tamu Lhochhar") + + # Islamic holidays. + + # Eid al-Fitr. + self._add_eid_al_fitr_day("Id-ul-Fitr") + + # Eid al-Adha. + self._add_eid_al_adha_day("Bakrid") + + # Removed by MoHA between 2019-2020. + self._add_non_continuous_holidays() + + def _populate_workday_holidays(self): + self._add_non_continuous_holidays(is_workday=True) + + +class NepalIslamicHolidays(_CustomIslamicHolidays): + # Bakrid / Eid-al-Adha. + EID_AL_ADHA_DATES = { + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 27), + 2013: (OCT, 16), + 2014: (OCT, 6), + 2015: (SEP, 25), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (AUG, 1), + 2021: (JUL, 21), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + # Id-ul-Fitr / Eid-al-Fitr. + EID_AL_FITR_DATES = { + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 20), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 16), + 2019: (JUN, 5), + 2020: (MAY, 25), + 2021: (MAY, 14), + 2022: (MAY, 3), + 2023: (APR, 22), + 2024: (APR, 11), + 2025: (MAR, 31), + } + + +class NepalHinduHolidays(_CustomHinduHolidays): + # Maghe Sankranti. + MAKAR_SANKRANTI_DATES = { + 2022: (JAN, 15), + 2023: (JAN, 15), + 2024: (JAN, 15), + 2026: (JAN, 15), + } + + # Fagu Poornima (Terai). + HOLI_DATES = { + 2023: (MAR, 7), + 2026: (MAR, 3), + } + + # Ram Navami. + RAM_NAVAMI_DATES = { + 2026: (MAR, 27), + } + + # Nepal New Year. + VAISAKHI_DATES = { + 2025: (APR, 14), + } + + # Janai Punima. + RAKSHA_BANDHAN_DATES = { + 2022: (AUG, 12), + 2023: (AUG, 31), + } + + # Shree Krishna Janmashtami. + JANMASHTAMI_DATES = { + 2023: (SEP, 6), + } + + # Maha Ashtami. + MAHA_ASHTAMI_DATES = { + 2020: (OCT, 24), + } + + # Maha Navami. + MAHA_NAVAMI_DATES = { + 2020: (OCT, 25), + } + + # Bijaya Dashami. + DUSSEHRA_DATES = { + 2020: (OCT, 26), + } + + # Gobardhan Pooja. + GOVARDHAN_PUJA_DATES = { + 2020: (NOV, 16), + 2022: (OCT, 26), + 2023: (NOV, 14), + } + + # Chhath Parva. + CHHATH_PUJA_DATES = { + 2025: (OCT, 27), + } + + +class NP(Nepal): + pass + + +class NPL(Nepal): + pass + + +class NepalStaticHolidays: + """Nepal special holidays. + + References: + * [Death of Krishna Prasad Bhattarai](https://web.archive.org/web/20250527164153/https://myrepublica.nagariknetwork.com/news/27618/) + * [Death of Sushil Koirala](https://web.archive.org/web/20250527164210/https://kathmandupost.com/miscellaneous/2016/02/09/cabinet-decision-koirala-to-be-honoured-with-state-funeral) + * [Crash of Yeti Airlines Flight 691](https://web.archive.org/web/20250123204057/https://edition.cnn.com/2023/01/15/asia/nepal-yeti-airlines-crash-intl-hnk/index.html) + * [People's War Day Instituted](https://web.archive.org/web/20241211215602/https://kathmandupost.com/national/2023/02/12/government-announces-public-holiday-on-monday-to-mark-people-s-war-day) + * [People's War Day Annulled](https://web.archive.org/web/20240111230228/https://kathmandupost.com/national/2023/12/29/supreme-court-annuls-public-holiday-on-people-s-war-day) + * [Death of Subas Chandra Nembang](https://web.archive.org/web/20241214193305/https://en.nepalkhabar.com/news/detail/6023/) + """ + + # Day of National Mourning. + name_day_of_national_mourning = "Day of National Mourning" + + # Tihar Holiday. + name_tihar_holiday = "Tihar Holiday" + + special_public_holidays = { + 2011: (MAR, 6, name_day_of_national_mourning), + 2016: (FEB, 10, name_day_of_national_mourning), + 2021: (NOV, 7, name_tihar_holiday), + 2022: (OCT, 28, name_tihar_holiday), + 2023: ( + (JAN, 16, name_day_of_national_mourning), + # People War's Day. + (FEB, 13, "People War's Day"), + (SEP, 14, name_day_of_national_mourning), + (NOV, 16, name_tihar_holiday), + ), + 2024: (NOV, 4, name_tihar_holiday), + 2025: (OCT, 24, name_tihar_holiday), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/netherlands.py b/.venv/lib/python3.12/site-packages/holidays/countries/netherlands.py new file mode 100644 index 00000000..40b58c9d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/netherlands.py @@ -0,0 +1,100 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_PREV_SAT, SUN_TO_NEXT_MON + + +class Netherlands(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Netherlands holidays. + + References: + * + * + * + """ + + country = "NL" + default_language = "nl" + supported_categories = (OPTIONAL, PUBLIC) + supported_languages = ("en_US", "fy", "nl", "uk") + start_year = 1801 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nieuwjaarsdag")) + + # Easter Sunday. + self._add_easter_sunday(tr("Eerste paasdag")) + + # Easter Monday. + self._add_easter_monday(tr("Tweede paasdag")) + + if self._year >= 1891: + name = ( + # King's Day. + tr("Koningsdag") + if self._year >= 2014 + # Queen's Day. + else tr("Koninginnedag") + ) + if self._year >= 2014: + dt = self._add_holiday_apr_27(name) + elif self._year >= 1949: + dt = self._add_holiday_apr_30(name) + else: + dt = self._add_holiday_aug_31(name) + self._move_holiday(dt, rule=SUN_TO_PREV_SAT if self._year >= 1980 else SUN_TO_NEXT_MON) + + if self._year >= 1950 and self._year % 5 == 0: + # Liberation Day. + self._add_holiday_may_5(tr("Bevrijdingsdag")) + + # Ascension Day. + self._add_ascension_thursday(tr("Hemelvaartsdag")) + + # Whit Sunday. + self._add_whit_sunday(tr("Eerste Pinksterdag")) + + # Whit Monday. + self._add_whit_monday(tr("Tweede Pinksterdag")) + + # Christmas Day. + self._add_christmas_day(tr("Eerste Kerstdag")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Tweede Kerstdag")) + + def _populate_optional_holidays(self): + # Good Friday. + self._add_good_friday(tr("Goede Vrijdag")) + + if self._year >= 1990: + # Liberation Day. + self._add_holiday_may_5(tr("Bevrijdingsdag")) + + +class NL(Netherlands): + pass + + +class NLD(Netherlands): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/new_caledonia.py b/.venv/lib/python3.12/site-packages/holidays/countries/new_caledonia.py new file mode 100644 index 00000000..f79794cd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/new_caledonia.py @@ -0,0 +1,43 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysNC(ChildEntity, France): + """New Caledonia holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "NC" + parent_entity = France + # France took formal possession of New Caledonia on September 24th, 1853. + start_year = 1854 + + +class NewCaledonia(HolidaysNC): + pass + + +class NC(HolidaysNC): + pass + + +class NCL(HolidaysNC): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/new_zealand.py b/.venv/lib/python3.12/site-packages/holidays/countries/new_zealand.py new file mode 100644 index 00000000..b6fd381f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/new_zealand.py @@ -0,0 +1,306 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import JAN, FEB, MAR, JUN, JUL, SEP, NOV, DEC, _timedelta +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + ALL_TO_NEAREST_MON, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class NewZealand(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """New Zealand holidays.""" + + country = "NZ" + observed_label = "%s (observed)" + start_year = 1894 + subdivisions = ( + # ISO 3166-2: Regions and Special Island Authorities. + # https://en.wikipedia.org/wiki/ISO_3166-2:NZ + "AUK", # Auckland (Tāmaki-Makaurau). + "BOP", # Bay of Plenty (Toi Moana). + "CAN", # Canterbury (Waitaha). + "CIT", # Chatham Islands Territory (Wharekauri). + "GIS", # Gisborne (Te Tairāwhiti). + "HKB", # Hawke's Bay (Te Matau-a-Māui). + "MBH", # Marlborough (Manawatū-Whanganui). + "MWT", # Manawatū-Whanganui (Manawatū Whanganui). + "NSN", # Nelson (Whakatū). + "NTL", # Northland (Te Taitokerau). + "OTA", # Otago (Ō Tākou). + "STL", # Southland (Te Taiao Tonga). + "TAS", # Tasman (Te tai o Aorere). + "TKI", # Taranaki (Taranaki). + "WGN", # Greater Wellington (Te Pane Matua Taiao). + "WKO", # Waikato (Waikato). + "WTC", # West Coast (Te Tai o Poutini). + # Subregions: + # https://web.archive.org/web/20250415230521/https://www.govt.nz/browse/work/public-holidays-and-work/public-holidays-and-anniversary-dates/ + "South Canterbury", + ) + subdivisions_aliases = { + # Fullnames in English and Maori, as well as HASC. + "Auckland": "AUK", + "Tāmaki-Makaurau": "AUK", + "AU": "AUK", + "Bay of Plenty": "BOP", + "Toi Moana": "BOP", + "BP": "BOP", + "Canterbury": "CAN", + "Waitaha": "CAN", + "CA": "CAN", + "Chatham Islands Territory": "CIT", + "Chatham Islands": "CIT", # 1901-1994, as County + "Wharekauri": "CIT", + "CI": "CIT", + "Gisborne": "GIS", + "Te Tairāwhiti": "GIS", + "GI": "GIS", + "Hawke's Bay": "HKB", + "Te Matau-a-Māui": "HKB", + "HB": "HKB", + "Marlborough": "MBH", + "MA": "MBH", + "Manawatū Whanganui": "MWT", + "Manawatū-Whanganui": "MWT", + "MW": "MWT", + "Nelson": "NSN", + "Whakatū": "NSN", + "NE": "NSN", + "Northland": "NTL", + "Te Taitokerau": "NTL", + "NO": "NTL", + "Otago": "OTA", + "Ō Tākou": "OTA", + "OT": "OTA", + "Southland": "STL", + "Te Taiao Tonga": "STL", + "SO": "STL", + "Tasman": "TAS", + "Te tai o Aorere": "TAS", + "TS": "TAS", + "Taranaki": "TKI", + "TK": "TKI", + "Greater Wellington": "WGN", + "Te Pane Matua Taiao": "WGN", + "Wellington": "WGN", # Prev. ISO code from 2010-2015. + "Te Whanganui-a-Tara": "WGN", # Prev. ISO code from 2010-2015. + "WG": "WGN", + "Waikato": "WKO", + "WK": "WKO", + "West Coast": "WTC", + "Te Tai o Poutini": "WTC", + "WC": "WTC", + } + _deprecated_subdivisions = ( + # Pre-1893 Naming in Previous Implementations. + "New Plymouth", # 1853-1859, Now Taranaki. + "Westland", # 1873-1876, Now West Coast. + # Unofficial Code. + "STC", # For 'South Canterbury' Subregional Holidays. + "WTL", # Westland, Correct code is WTC (for West Coast). + ) + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, NewZelandStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _get_nearest_monday(self, *args) -> Optional[date]: + return self._get_observed_date(date(self._year, *args), rule=ALL_TO_NEAREST_MON) + + def _populate_public_holidays(self): + # Bank Holidays Act 1873 + # The Employment of Females Act 1873 + # Factories Act 1894 + # Industrial Conciliation and Arbitration Act 1894 + # Labour Day Act 1899 + # Anzac Day Act 1920, 1949, 1956 + # New Zealand Day Act 1973 + # Waitangi Day Act 1960, 1976 + # Sovereign's Birthday Observance Act 1937, 1952 + # Holidays Act 1981, 2003 + + # New Year's Day + self._add_observed(self._add_new_years_day("New Year's Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + self._add_observed( + self._add_new_years_day_two("Day after New Year's Day"), rule=SAT_SUN_TO_NEXT_MON_TUE + ) + + # Waitangi Day + if self._year >= 1974: + name = "Waitangi Day" if self._year >= 1977 else "New Zealand Day" + feb_6 = self._add_holiday_feb_6(name) + if self._year >= 2014: + self._add_observed(feb_6) + + # Anzac Day + if self._year >= 1921: + apr_25 = self._add_anzac_day("Anzac Day") + if self._year >= 2014: + self._add_observed(apr_25) + + # Easter + self._add_good_friday("Good Friday") + self._add_easter_monday("Easter Monday") + + # Sovereign's Birthday + if self._year >= 1902: + name = "Queen's Birthday" if 1952 <= self._year <= 2022 else "King's Birthday" + if self._year == 1952: + self._add_holiday_jun_2(name) # Elizabeth II + elif self._year >= 1938: + self._add_holiday_1st_mon_of_jun(name) # EII & GVI + elif self._year == 1937: + self._add_holiday_jun_9(name) # George VI + elif self._year == 1936: + self._add_holiday_jun_23(name) # Edward VIII + elif self._year >= 1912: + self._add_holiday_jun_3(name) # George V + else: + # https://web.archive.org/web/20250427125629/https://paperspast.natlib.govt.nz/cgi-bin/paperspast?a=d&d=NZH19091110.2.67 + self._add_holiday_nov_9(name) # Edward VII + + # Matariki + dates_obs = { + 2022: (JUN, 24), + 2023: (JUL, 14), + 2024: (JUN, 28), + 2025: (JUN, 20), + 2026: (JUL, 10), + 2027: (JUN, 25), + 2028: (JUL, 14), + 2029: (JUL, 6), + 2030: (JUN, 21), + 2031: (JUL, 11), + 2032: (JUL, 2), + 2033: (JUN, 24), + 2034: (JUL, 7), + 2035: (JUN, 29), + 2036: (JUL, 18), + 2037: (JUL, 10), + 2038: (JUN, 25), + 2039: (JUL, 15), + 2040: (JUL, 6), + 2041: (JUL, 19), + 2042: (JUL, 11), + 2043: (JUL, 3), + 2044: (JUN, 24), + 2045: (JUL, 7), + 2046: (JUN, 29), + 2047: (JUL, 19), + 2048: (JUL, 3), + 2049: (JUN, 25), + 2050: (JUL, 15), + 2051: (JUN, 30), + 2052: (JUN, 21), + } + if dt := dates_obs.get(self._year): + self._add_holiday("Matariki", dt) + + # Labour Day + if self._year >= 1900: + name = "Labour Day" + if self._year >= 1910: + self._add_holiday_4th_mon_of_oct(name) + else: + self._add_holiday_2nd_wed_of_oct(name) + + # Christmas Day + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + # Boxing Day + self._add_observed(self._add_christmas_day_two("Boxing Day"), rule=SAT_SUN_TO_NEXT_MON_TUE) + + if self.subdiv == "New Plymouth": + self._populate_subdiv_tki_public_holidays() + elif self.subdiv == "South Canterbury": + self._populate_subdiv_stc_public_holidays() + elif self.subdiv in {"WTL", "Westland"}: + self._populate_subdiv_wtc_public_holidays() + + def _populate_subdiv_auk_public_holidays(self): + self._add_holiday("Auckland Anniversary Day", self._get_nearest_monday(JAN, 29)) + + def _populate_subdiv_can_public_holidays(self): + self._add_holiday_10_days_past_1st_tue_of_nov("Canterbury Anniversary Day") + + def _populate_subdiv_cit_public_holidays(self): + self._add_holiday("Chatham Islands Anniversary Day", self._get_nearest_monday(NOV, 30)) + + def _populate_subdiv_hkb_public_holidays(self): + self._add_holiday_3_days_prior_4th_mon_of_oct("Hawke's Bay Anniversary Day") + + def _populate_subdiv_mbh_public_holidays(self): + self._add_holiday_7_days_past_4th_mon_of_oct("Marlborough Anniversary Day") + + def _populate_subdiv_nsn_public_holidays(self): + self._add_holiday("Nelson Anniversary Day", self._get_nearest_monday(FEB, 1)) + + def _populate_subdiv_ntl_public_holidays(self): + if 1964 <= self._year <= 1973: + self._add_holiday("Waitangi Day", self._get_nearest_monday(FEB, 6)) + else: + self._add_holiday("Auckland Anniversary Day", self._get_nearest_monday(JAN, 29)) + + def _populate_subdiv_ota_public_holidays(self): + # there is no easily determined single day of local observance?!?! + dt = self._get_nearest_monday(MAR, 23) + if dt == _timedelta(self._easter_sunday, +1): # Avoid Easter Monday + dt = _timedelta(dt, +1) + self._add_holiday("Otago Anniversary Day", dt) + + def _populate_subdiv_stc_public_holidays(self): + self._add_holiday_4th_mon_of_sep("South Canterbury Anniversary Day") + + def _populate_subdiv_stl_public_holidays(self): + name = "Southland Anniversary Day" + if self._year >= 2012: + self._add_easter_tuesday(name) + else: + self._add_holiday(name, self._get_nearest_monday(JAN, 17)) + + def _populate_subdiv_tki_public_holidays(self): + self._add_holiday_2nd_mon_of_mar("Taranaki Anniversary Day") + + def _populate_subdiv_wgn_public_holidays(self): + self._add_holiday("Wellington Anniversary Day", self._get_nearest_monday(JAN, 22)) + + def _populate_subdiv_wtc_public_holidays(self): + dt = ( + date(self._year, DEC, 5) + if self._year == 2005 # special case?!?! + else self._get_nearest_monday(DEC, 1) + ) + self._add_holiday("West Coast Anniversary Day", dt) + + +class NZ(NewZealand): + pass + + +class NZL(NewZealand): + pass + + +class NewZelandStaticHolidays: + special_public_holidays = { + 2022: (SEP, 26, "Queen Elizabeth II Memorial Day"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/nicaragua.py b/.venv/lib/python3.12/site-packages/holidays/countries/nicaragua.py new file mode 100644 index 00000000..dd098957 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/nicaragua.py @@ -0,0 +1,121 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Nicaragua(HolidayBase, ChristianHolidays, InternationalHolidays): + """Nicaragua holidays. + + References: + * + * + * + """ + + country = "NI" + default_language = "es" + subdivisions = ( + "AN", # Costa Caribe Norte. + "AS", # Costa Caribe Sur. + "BO", # Boaco. + "CA", # Carazo. + "CI", # Chinandega. + "CO", # Chontales. + "ES", # Estelí. + "GR", # Granada. + "JI", # Jinotega. + "LE", # León. + "MD", # Madriz. + "MN", # Managua. + "MS", # Masaya. + "MT", # Matagalpa. + "NS", # Nueva Segovia. + "RI", # Rivas. + "SJ", # Río San Juan. + ) + subdivisions_aliases = { + "Costa Caribe Norte": "AN", + "Costa Caribe Sur": "AS", + "Boaco": "BO", + "Carazo": "CA", + "Chinandega": "CI", + "Chontales": "CO", + "Estelí": "ES", + "Granada": "GR", + "Jinotega": "JI", + "León": "LE", + "Madriz": "MD", + "Managua": "MN", + "Masaya": "MS", + "Matagalpa": "MT", + "Nueva Segovia": "NS", + "Rivas": "RI", + "Río San Juan": "SJ", + } + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Labor Day. + self._add_labor_day(tr("Día del Trabajo")) + + if self._year >= 2022: + # Mother's Day. + self._add_holiday_may_30(tr("Día de la Madre")) + + if self._year >= 1979: + # Revolution Day. + self._add_holiday_jul_19(tr("Día de la Revolución")) + + # Battle of San Jacinto Day. + self._add_holiday_sep_14(tr("Batalla de San Jacinto")) + + # Independence Day. + self._add_holiday_sep_15(tr("Día de la Independencia")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Concepción de María")) + + # Christmas Day. + self._add_christmas_day(tr("Navidad")) + + def _populate_subdiv_mn_public_holidays(self): + # Descent of Saint Dominic. + self._add_holiday_aug_1(tr("Bajada de Santo Domingo")) + + # Ascent of Saint Dominic. + self._add_holiday_aug_10(tr("Subida de Santo Domingo")) + + +class NI(Nicaragua): + pass + + +class NIC(Nicaragua): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/niger.py b/.venv/lib/python3.12/site-packages/holidays/countries/niger.py new file mode 100644 index 00000000..46db78bb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/niger.py @@ -0,0 +1,320 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays import OPTIONAL, PUBLIC +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + SUN, +) +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Niger(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Niger holidays. + + References: + * [Law No. 59-22 of December 24, 1959](https://web.archive.org/web/20241106023958/https://www.impots.gouv.ne/media/loi/1960.pdf) + * + * + * + * + * + * [Eid al-Adha](https://web.archive.org/web/20250117013558/https://www.timeanddate.com/holidays/niger/eid-al-adha) + * [Eid al-Fitr](https://web.archive.org/web/20250114130118/https://www.timeanddate.com/holidays/niger/eid-al-fitr) + * [Laylat al-Qadr](https://web.archive.org/web/20250531033137/https://www.timeanddate.com/holidays/niger/laylat-al-qadr) + * [Islamic New Year](https://web.archive.org/web/20240723135601/https://www.timeanddate.com/holidays/niger/muharram-new-year) + * [Prophet's Birthday](https://web.archive.org/web/20250124122731/https://www.timeanddate.com/holidays/niger/prophet-birthday) + + Notes: + After Law No. 97-020 of June 20, 1997 establishing public holidays came into + effect, holidays that fell on the mandatory weekly rest day (Sunday) were + observed on the next Monday. + """ + + country = "NE" + default_language = "fr_NE" + supported_languages = ("en_US", "fr_NE") + supported_categories = (OPTIONAL, PUBLIC) + # %s (observed). + observed_label = tr("%s (observé)") + # %s (estimated). + estimated_label = tr("%s (estimé)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observé, estimé)") + # Law No. 59-22. + start_year = 1960 + weekend = {SUN} + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=NigerIslamicHolidays, show_estimated=islamic_show_estimated + ) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1998) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("Jour de l'An"))) + + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + if self._year >= 1995: + # National Concord Day. + self._add_observed(self._add_holiday_apr_24(tr("Fête nationale de la Concorde"))) + + # International Labor Day. + self._add_observed(self._add_labor_day(tr("Journée internationale du travail"))) + + if self._year >= 2024: + # Anniversary of the CNSP Coup. + self._add_observed(self._add_holiday_jul_26(tr("Anniversaire du coup d'État du CNSP"))) + + self._add_observed( + self._add_holiday_aug_3( + # Anniversary of the Proclamation of Independence. + tr("L'anniversaire de la proclamation de l'indépendance") + if self._year >= 1961 + # Independence Day. + else tr("Jour de l'indépendance") + ) + ) + + # National Day. + self._add_observed(self._add_holiday_dec_18(tr("Fête nationale"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Noël"))) + + # Islamic New Year. + for dt in self._add_islamic_new_year_day(tr("Jour de l'An musulman")): + self._add_observed(dt) + + # Prophet's Birthday. + for dt in self._add_mawlid_day(tr("Mouloud")): + self._add_observed(dt) + + # Laylat al-Qadr. + for dt in self._add_laylat_al_qadr_day(tr("Laylat al-Qadr")): + self._add_observed(dt) + + # Eid al-Fitr. + for dt in self._add_eid_al_fitr_day(tr("Korité")): + self._add_observed(dt) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Tabaski")) + + # Day after Eid al-Adha. + for dt in self._add_eid_al_adha_day_two(tr("Lendemain de la Tabaski")): + self._add_observed(dt) + + def _populate_optional_holidays(self): + # Ascension Day. + self._add_ascension_thursday(tr("Ascension")) + + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + + # Assumption Day. + self._add_observed(self._add_assumption_of_mary_day(tr("Assomption"))) + + # All Saints' Day. + self._add_observed(self._add_all_saints_day(tr("Toussaint"))) + + +class NigerIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 1998: (APR, 8), + 1999: (MAR, 28), + 2000: (MAR, 16), + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 10), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 1998: (JAN, 30), + 1999: (JAN, 19), + 2000: ((JAN, 8), (DEC, 28)), + 2001: (DEC, 17), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 23), + 2021: (MAY, 12), + 2022: (MAY, 1), + 2023: (APR, 21), + 2024: (APR, 9), + 2025: (MAR, 30), + } + + HIJRI_NEW_YEAR_DATES = { + 1998: (APR, 28), + 1999: (APR, 17), + 2000: (APR, 6), + 2001: (MAR, 26), + 2002: (MAR, 15), + 2003: (MAR, 5), + 2004: (FEB, 22), + 2005: (FEB, 10), + 2006: (JAN, 31), + 2007: (JAN, 20), + 2008: ((JAN, 10), (DEC, 29)), + 2009: (DEC, 18), + 2010: (DEC, 8), + 2011: (NOV, 27), + 2012: (NOV, 15), + 2013: (NOV, 5), + 2014: (OCT, 25), + 2015: (OCT, 15), + 2016: (OCT, 3), + 2017: (SEP, 22), + 2018: (SEP, 12), + 2019: (AUG, 31), + 2020: (AUG, 21), + 2021: (AUG, 10), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 6), + 2025: (JUN, 27), + } + + LAYLAT_AL_QADR_DATES = { + 1998: (JAN, 26), + 1999: (JAN, 15), + 2000: ((JAN, 4), (DEC, 24)), + 2001: (DEC, 13), + 2002: (DEC, 2), + 2003: (NOV, 22), + 2004: (NOV, 11), + 2005: (OCT, 31), + 2006: (OCT, 20), + 2007: (OCT, 9), + 2008: (SEP, 28), + 2009: (SEP, 17), + 2010: (SEP, 6), + 2011: (AUG, 27), + 2012: (AUG, 15), + 2013: (AUG, 4), + 2014: (JUL, 25), + 2015: (JUL, 14), + 2016: (JUL, 2), + 2017: (JUN, 22), + 2018: (JUN, 11), + 2019: (JUN, 1), + 2020: (MAY, 20), + 2021: (MAY, 9), + 2022: (APR, 28), + 2023: (APR, 18), + 2024: (APR, 6), + 2025: (MAR, 27), + } + + MAWLID_DATES = { + 1998: (JUL, 7), + 1999: (JUN, 26), + 2000: (JUN, 15), + 2001: (JUN, 4), + 2002: (MAY, 24), + 2003: (MAY, 14), + 2004: (MAY, 2), + 2005: (APR, 21), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 16), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + +class NE(Niger): + pass + + +class NER(Niger): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/nigeria.py b/.venv/lib/python3.12/site-packages/holidays/countries/nigeria.py new file mode 100644 index 00000000..4541a872 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/nigeria.py @@ -0,0 +1,111 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import FEB, MAY +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class Nigeria( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Nigeria holidays. + + References: + * + """ + + country = "NG" + observed_label = "%s (observed)" + start_year = 1979 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + StaticHolidays.__init__(self, NigeriaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 2016) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day("New Year's Day")) + + self._add_good_friday("Good Friday") + self._add_easter_monday("Easter Monday") + + # Worker's day. + if self._year >= 1981: + dts_observed.add(self._add_labor_day("Workers' Day")) + + # Democracy Day. + if self._year >= 2000: + name = "Democracy Day" + dts_observed.add( + self._add_holiday_jun_12(name) + if self._year >= 2019 + else self._add_holiday_may_29(name) + ) + + # Independence Day. + dts_observed.add(self._add_holiday_oct_1("Independence Day")) + + # Christmas day. + dts_observed.add(self._add_christmas_day("Christmas Day")) + + # Boxing day. + dts_observed.add(self._add_christmas_day_two("Boxing Day")) + + # Eid al-Fitr. + dts_observed.update(self._add_eid_al_fitr_day("Eid-el-Fitr")) + dts_observed.update(self._add_eid_al_fitr_day_two("Eid-el-Fitr Holiday")) + + # Eid al-Adha. + dts_observed.update(self._add_eid_al_adha_day("Eid-el-Kabir")) + dts_observed.update(self._add_eid_al_adha_day_two("Eid-el-Kabir Holiday")) + + # Birthday of Prophet Muhammad. + dts_observed.update(self._add_mawlid_day("Eid-el-Mawlid")) + + if self.observed: + self._populate_observed(dts_observed) + + +class NG(Nigeria): + pass + + +class NGA(Nigeria): + pass + + +class NigeriaStaticHolidays: + special_public_holidays = { + 2019: ( + (FEB, 22, "Public Holiday for Elections"), + (MAY, 29, "Presidential Inauguration Day"), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/niue.py b/.venv/lib/python3.12/site-packages/holidays/countries/niue.py new file mode 100644 index 00000000..6a92e55c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/niue.py @@ -0,0 +1,115 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import SEP +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Niue(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Niue holidays. + + References: + * + * + * [Public Holidays Ordinance 1961](https://web.archive.org/web/20250102100637/http://www.paclii.org/nu/legis/num_act/nipho1961314.pdf) + * + * [2021/2022 Public Holidays](https://web.archive.org/web/20250509105501/https://www.gov.nu/media/pages/information/1018c58017-1725838374/4nov2021-circular.pdf) + * [2025 Good Friday & Easter Monday and Anzac Day](https://web.archive.org/web/20250719195126/https://www.gov.nu/media/pages/gazette/3e02b3aa84-1746400484/official-psc-circular-easter-anzac-holiday.pdf) + * [2025 King's Birthday](https://web.archive.org/web/20250719195301/https://www.gov.nu/media/pages/public-service-circulars/3b9f44b6a0-1748573974/king-s-birthday-public-holiday-2025-circular.pdf) + * + """ + + country = "NU" + default_language = "en_NU" + # %s observed. + observed_label = tr("%s (observed)") + # Public Holidays Ordinance 1961. + start_year = 1962 + supported_languages = ("en_NU", "en_US") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=NiueStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON_TUE) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Takai Commission Holiday. + self._add_observed(self._add_new_years_day_two(tr("Takai Commission Holiday"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # ANZAC Day. + self._add_observed(self._add_anzac_day(tr("ANZAC Day")), rule=SAT_SUN_TO_NEXT_MON) + + self._add_holiday_1st_mon_of_jun( + # King's Birthday. + tr("King's Birthday") + if self._year >= 2023 + # Queen's Birthday. + else tr("Queen's Birthday") + ) + + if self._year >= 1974: + # Constitution Day. + self._add_observed(self._add_holiday_oct_19(tr("Constitution Day"))) + + # Constitution Day Holiday. + self._add_observed(self._add_holiday_oct_20(tr("Constitution Day Holiday"))) + else: + # Annexation Day. + self._add_holiday_3rd_mon_of_oct(tr("Annexation Day")) + + # Peniamina Gospel Day. + self._add_holiday_4th_mon_of_oct(tr("Peniamina Gospel Day")) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day"))) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two(tr("Boxing Day"))) + + +class NU(Niue): + pass + + +class NIU(Niue): + pass + + +class NiueStaticHolidays: + """Niue special holidays. + + References: + * [Queen Elizabeth II's Funeral](https://web.archive.org/web/20250617174022/https://tvniue.com/2022/09/premier-will-attend-hm-the-queens-funeral-while-monday-19th-is-declared-one-off-public-holiday/) + """ + + special_public_holidays = { + # Queen Elizabeth II's Funeral. + 2022: (SEP, 19, tr("Queen Elizabeth II's Funeral")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/norfolk_island.py b/.venv/lib/python3.12/site-packages/holidays/countries/norfolk_island.py new file mode 100644 index 00000000..0f56e1ea --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/norfolk_island.py @@ -0,0 +1,129 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + + +from gettext import gettext as tr + +from holidays.calendars.gregorian import SEP +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, + SUN_TO_NEXT_MON, +) + + +class NorfolkIsland(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Norfolk Island holidays. + + References: + * + * + * [2020](https://web.archive.org/web/20220704121150/http://norfolkislander.com/images/2019_08_30_Gazette_No._38.pdf) + * [2021](https://web.archive.org/web/20250710234146/http://www.norfolkislander.com/images/2020_07_31_Gazette_No._35.pdf) + * [2022](https://web.archive.org/web/20250328071352/https://www.nirc.gov.au/files/assets/public/v/1/your-council/documents/nirc-gazettes/2021_07_09_gazette_no_29.pdf) + * [2023](https://web.archive.org/web/20250328071155/https://www.nirc.gov.au/files/assets/public/v/1/your-council/documents/nirc-gazettes/2022_07_21_gazette_no_29.pdf) + * [2024](https://web.archive.org/web/20250328070948/https://www.nirc.gov.au/files/assets/public/v/1/your-council/documents/nirc-gazettes/2023_07_13_gazette_no_40.pdf) + * [2025](https://web.archive.org/web/20250711000525/https://www.nirc.gov.au/files/assets/public/v/1/your-council/documents/nirc-gazettes/2024_07_05_gazette_no_25.pdf) + * [2026](https://web.archive.org/web/20250713192750/https://www.nirc.gov.au/files/assets/public/v/1/your-council/documents/nirc-gazettes/2025/2025-07-11-gazette-no-26.pdf) + """ + + country = "NF" + default_language = "en_NF" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_NF", "en_US") + start_year = 2016 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, NorfolkIslandStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Australia Day. + self._add_observed(self._add_holiday_jan_26(tr("Australia Day"))) + + # Foundation Day. + self._add_observed(self._add_holiday_mar_6(tr("Foundation Day")), rule=SUN_TO_NEXT_MON) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # ANZAC Day. + self._add_anzac_day(tr("ANZAC Day")) + + # Bounty Day. + self._add_observed(bounty_day := self._add_holiday_jun_8(tr("Bounty Day"))) + + # Sovereign's Birthday. + name = ( + # King's Birthday. + tr("King's Birthday") + if self._year >= 2023 + # Queen's Birthday. + else tr("Queen's Birthday") + ) + # If Sovereign's Birthday falls on the same day as Bounty Day (observed), + # it is moved to the next Monday. + if self._is_saturday(bounty_day): + self._add_holiday_2_days_past_3rd_sat_of_jun(name) + else: + self._add_holiday_2_days_past_2nd_sat_of_jun(name) + + # Show Day. + self._add_holiday_2nd_mon_of_oct(tr("Show Day")) + + # Thanksgiving Day. + self._add_holiday_last_wed_of_nov(tr("Thanksgiving Day")) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + +class NF(NorfolkIsland): + pass + + +class NFK(NorfolkIsland): + pass + + +class NorfolkIslandStaticHolidays: + """Norfolk Island special holidays. + + References: + * [National Day of Mourning 2022](https://web.archive.org/web/20250711012623/https://www.infrastructure.gov.au/territories-regions-cities/territories/norfolk-island/media-releases/national-day-of-mourning-for-her-majesty-the-queen) + """ + + special_public_holidays = { + # National Day of Mourning for Queen Elizabeth II. + 2022: (SEP, 22, tr("National Day of Mourning for Queen Elizabeth II")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/north_macedonia.py b/.venv/lib/python3.12/site-packages/holidays/countries/north_macedonia.py new file mode 100644 index 00000000..7956cca9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/north_macedonia.py @@ -0,0 +1,320 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + GREGORIAN_CALENDAR, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, +) +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.constants import ( + ALBANIAN, + BOSNIAN, + CATHOLIC, + HEBREW, + ISLAMIC, + ORTHODOX, + PUBLIC, + ROMA, + SERBIAN, + TURKISH, + VLACH, +) +from holidays.groups import ( + ChristianHolidays, + HebrewCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class NorthMacedonia( + ObservedHolidayBase, + ChristianHolidays, + HebrewCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """North Macedonia holidays. + + References: + * + * [Law on Holidays 21/98](https://web.archive.org/web/20250404064336/https://www.mtsp.gov.mk/content/pdf/dokumenti/Zakon_Praznici_na_RM%20(2_2).pdf) + * [Law Amending Law on Holidays 18/2007](https://web.archive.org/web/20250505061325/https://www.mtsp.gov.mk/content/pdf/dokumenti/Zakon_Izmenuvanje_Praznici_na_RM%20(2_2).pdf) + + Checked With: + * [Non-working days program](https://web.archive.org/web/20250420034141/https://mtsp.gov.mk/programa-za-nerabotni-denovi.nspx) + * [2010](https://web.archive.org/web/20250430235227/https://www.mtsp.gov.mk/WBStorage/Files/programadeseta.doc) + * [2011](https://web.archive.org/web/20250501104555/https://www.mtsp.gov.mk/WBStorage/Files/programaedinaeseta.doc) + * [2012](https://web.archive.org/web/20250501001337/https://www.mtsp.gov.mk/WBStorage/Files/programadvanaeseta.doc) + * [2013](https://web.archive.org/web/20250430234446/https://www.mtsp.gov.mk/WBStorage/Files/programa_trinaeseta_nova.doc) + * [2014](https://web.archive.org/web/20241206035550/https://www.mtsp.gov.mk/WBStorage/Files/programa_nerabotni_denovi_2014.pdf) + * [2015](https://web.archive.org/web/20240304070837/https://www.mtsp.gov.mk/content/pdf/Programa_nerabotni_denovi_2015.pdf) + * [2016](https://web.archive.org/web/20241206052140/https://www.mtsp.gov.mk/content/pdf/Programa_nerabotni_2016.pdf) + * [2017](https://web.archive.org/web/20240629115141/https://www.mtsp.gov.mk/content/pdf/19.10._Програма%20на%20неработни%20денови%20за%202017%20година.pdf) + * [2018](https://web.archive.org/web/20240630201651/https://www.mtsp.gov.mk/content/pdf/programi/Програма%20на%20неработни%20денови%20за%202018%20година.pdf) + * [2019](https://web.archive.org/web/20240629172352/https://www.mtsp.gov.mk/content/pdf/programi/Programa_na_nerabotni_denovi_za_2019_godina..pdf) + * [2020](https://web.archive.org/web/20240629104945/https://www.mtsp.gov.mk/content/pdf/dokumenti/2019/Програма%20на%20неработни%20денови%20за%202020%20година%201.pdf) + * [2021](https://web.archive.org/web/20250502065435/https://www.mtsp.gov.mk/content/Програма%20на%20неработни%20денови%20за%202021%20година%20PDF.pdf) + * [2022](https://web.archive.org/web/20250420054039/https://www.mtsp.gov.mk/content/word/2021/nerabotni/2022_programa_praznici_nerabotni_2.doc) + * [2023](https://web.archive.org/web/20250420050919/https://mtsp.gov.mk/content/word/programi/2022/programa_nerabotni_2023.doc) + * [2024](https://web.archive.org/web/20250420060645/https://www.mtsp.gov.mk/content/word/programi/2023/programa_nerabotni_2024_mkd.doc) + * [2025](https://web.archive.org/web/20250421022811/https://www.mtsp.gov.mk/content/word/2024/programa_nerabotni_2025.docx) + """ + + country = "MK" + default_language = "mk" + # %s (estimated). + estimated_label = tr("%s (проценето)") + # %s (observed). + observed_label = tr("%s (неработен ден)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (неработен ден, проценето)") + start_year = 1999 + supported_categories = ( + ALBANIAN, + BOSNIAN, + CATHOLIC, + HEBREW, + ISLAMIC, + ORTHODOX, + PUBLIC, + ROMA, + SERBIAN, + TURKISH, + VLACH, + ) + supported_languages = ("en_US", "mk", "uk") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + HebrewCalendarHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=NorthMacedoniaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, NorthMacedoniaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Нова Година") + self._add_observed(self._add_new_years_day(name)) + if self._year <= 2007: + self._add_observed(self._add_new_years_day_two(name)) + + if self._year >= 2008: + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Божиќ"))) + + if self._year >= 2007: + # Easter Monday. + self._add_easter_monday(tr("Велигден")) + + # Labor Day. + name = tr("Ден на трудот") + self._add_observed(self._add_labor_day(name)) + if self._year <= 2006: + self._add_observed(self._add_labor_day_two(name)) + + if self._year >= 2007: + self._add_observed( + self._add_holiday_may_24( + # Saints Cyril and Methodius Day. + tr("Светите Кирил и Методиј - Ден на сесловенските просветители") + ) + ) + + # Republic Day. + self._add_observed(self._add_holiday_aug_2(tr("Ден на Републиката"))) + + # Independence Day. + self._add_observed(self._add_holiday_sep_8(tr("Ден на независноста"))) + + # National Uprising Day. + self._add_observed(self._add_holiday_oct_11(tr("Ден на народното востание"))) + + if self._year >= 2007: + self._add_observed( + # Macedonian Revolutionary Struggle Day. + self._add_holiday_oct_23(tr("Ден на македонската револуционерна борба")) + ) + + # Saint Clement of Ohrid Day. + self._add_observed(self._add_holiday_dec_8(tr("Свети Климент Охридски"))) + + if self._year >= 2007: + # Eid al-Fitr. + for dt in self._add_eid_al_fitr_day(tr("Рамазан Бајрам")): + self._add_observed(dt) + + def _populate_albanian_holidays(self): + if self._year >= 2007: + # Albanian Alphabet Day. + self._add_holiday_nov_22(tr("Ден на Албанската азбука")) + + def _populate_bosnian_holidays(self): + if self._year >= 2007: + # International Bosniaks Day. + self._add_holiday_sep_28(tr("Меѓународен ден на Бошњаците")) + + def _populate_catholic_holidays(self): + # Easter Monday. + self._add_easter_monday(tr("Велигден"), GREGORIAN_CALENDAR) + + if self._year >= 2007: + # All Saints' Day. + self._add_all_saints_day(tr("Сите Светци")) + + # Christmas Day. + self._add_christmas_day(tr("Божиќ"), GREGORIAN_CALENDAR) + + def _populate_hebrew_holidays(self): + # Yom Kippur. + self._add_yom_kippur(tr("Јом Кипур")) + + def _populate_islamic_holidays(self): + if self._year >= 2007: + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Курбан Бајрам")) + + def _populate_orthodox_holidays(self): + if self._year <= 2007: + # Christmas Day. + self._add_christmas_day(tr("Божиќ")) + + if self._year <= 2006: + # Easter Monday. + self._add_easter_monday(tr("Велигден")) + + if self._year >= 2007: + # Christmas Eve. + self._add_christmas_eve(tr("Бадник")) + + # Epiphany. + self._add_epiphany_day(tr("Богојавление")) + + # Good Friday. + self._add_good_friday(tr("Велики Петок")) + + # Dormition of the Mother of God. + self._add_assumption_of_mary_day(tr("Успение на Пресвета Богородица")) + + # Pentecost. + self._add_holiday_47_days_past_easter(tr("Духовден")) + + def _populate_roma_holidays(self): + if self._year >= 2007: + # International Romani Day. + self._add_holiday_apr_8(tr("Меѓународен ден на Ромите")) + + def _populate_serbian_holidays(self): + if self._year >= 2008: + # Saint Sava's Day. + self._add_holiday_jan_27(tr("Свети Сава")) + + def _populate_turkish_holidays(self): + if self._year >= 2007: + # Turkish Language Teaching Day. + self._add_holiday_dec_21(tr("Ден на настава на турски јазик")) + + def _populate_vlach_holidays(self): + if self._year >= 2007: + # Vlachs National Day. + self._add_holiday_may_23(tr("Национален ден на Власите")) + + +class MK(NorthMacedonia): + pass + + +class MKD(NorthMacedonia): + pass + + +class NorthMacedoniaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2010: (NOV, 16), + 2011: (NOV, 6), + 2012: (OCT, 25), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 2010: (SEP, 9), + 2011: (AUG, 30), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 5), + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + +class NorthMacedoniaStaticHolidays: + """North Macedonia special holidays. + + References: + * + """ + + # Election Day. + election_day = tr("Ден на изборите") + + special_public_holidays = { + # Election Day. + 2024: ( + (APR, 24, election_day), + (MAY, 8, election_day), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/northern_mariana_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/northern_mariana_islands.py new file mode 100644 index 00000000..2c3a5dab --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/northern_mariana_islands.py @@ -0,0 +1,39 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.united_states import UnitedStates +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysMP(ChildEntity, UnitedStates): + """Northern Mariana Islands (the) holidays. + + Alias of a US subdivision that is also officially assigned its own country code in ISO 3166-1. + See + """ + + country = "MP" + parent_entity = UnitedStates + # UNSC Resolution 21 on April 2nd, 1947. + start_year = 1948 + + +class NorthernMarianaIslands(HolidaysMP): + pass + + +class MP(HolidaysMP): + pass + + +class MNP(HolidaysMP): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/norway.py b/.venv/lib/python3.12/site-packages/holidays/countries/norway.py new file mode 100644 index 00000000..131e38a4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/norway.py @@ -0,0 +1,138 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import _get_all_sundays +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Norway(HolidayBase, ChristianHolidays, InternationalHolidays): + """Norway holidays. + + References: + * + * + * + + Note that holidays falling on a sunday is "lost", it will not be moved + to another day to make up for the collision. + + In Norway, ALL sundays are considered a holiday (https://web.archive.org/web/20250202193959/https://snl.no/helligdag). + Initialize this class with `include_sundays=False` to not include sundays as a holiday. + """ + + country = "NO" + default_language = "no" + subdivisions: tuple[str, ...] = ( + "03", # Oslo. + "11", # Rogaland. + "15", # Møre og Romsdal. + "18", # Nordland. + "21", # Svalbard. + "22", # Jan Mayen. + "30", # Viken. + "34", # Innlandet. + "38", # Vestfold og Telemark. + "42", # Agder. + "46", # Vestland. + "50", # Trøndelag (Trööndelage). + "54", # Troms og Finnmark (Romssa ja Finnmárkku, Tromssan ja Finmarkun). + ) + subdivisions_aliases = { + "Oslo": "03", + "Rogaland": "11", + "Møre og Romsdal": "15", + "Nordland": "18", + "Svalbard": "21", + "Jan Mayen": "22", + "Viken": "30", + "Innlandet": "34", + "Vestfold og Telemark": "38", + "Agder": "42", + "Vestland": "46", + "Trööndelage": "50", + "Trøndelag": "50", + "Romssa ja Finnmárkku": "54", + "Troms og Finnmark": "54", + "Tromssan ja Finmarkun": "54", + } + supported_languages = ("en_US", "no", "th", "uk") + + def __init__(self, include_sundays: bool = False, *args, **kwargs): + """ + Args: + include_sundays: + Whether to consider sundays as a holiday (which they are in Norway) + """ + self.include_sundays = include_sundays + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Første nyttårsdag")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Skjærtorsdag")) + + # Good Friday. + self._add_good_friday(tr("Langfredag")) + + # Easter Sunday. + self._add_easter_sunday(tr("Første påskedag")) + + # Easter Monday. + self._add_easter_monday(tr("Andre påskedag")) + + # Source: https://web.archive.org/web/20250102052441/https://lovdata.no/dokument/NL/lov/1947-04-26-1 + if self._year >= 1947: + # Labor Day. + self._add_labor_day(tr("Arbeidernes dag")) + + # Constitution Day. + self._add_holiday_may_17(tr("Grunnlovsdag")) + + # Ascension Day. + self._add_ascension_thursday(tr("Kristi himmelfartsdag")) + + # Whit Sunday. + self._add_whit_sunday(tr("Første pinsedag")) + + # Whit Monday. + self._add_whit_monday(tr("Andre pinsedag")) + + # According to https://no.wikipedia.org/wiki/Første_juledag, + # these dates are only valid from year > 1700 + # Wikipedia has no source for the statement, so leaving this be for now + + # Christmas Day. + self._add_christmas_day(tr("Første juledag")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Andre juledag")) + + if self.include_sundays: + # Optionally add all Sundays of the year. + for dt in _get_all_sundays(self._year): + # Sunday. + self._add_holiday(tr("Søndag"), dt) + + +class NO(Norway): + pass + + +class NOR(Norway): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/oman.py b/.venv/lib/python3.12/site-packages/holidays/countries/oman.py new file mode 100644 index 00000000..88a6bc2e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/oman.py @@ -0,0 +1,185 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + THU, + FRI, + SAT, + _timedelta, +) +from holidays.groups import IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Oman(HolidayBase, IslamicHolidays): + """Oman holidays. + + References: + * + * [Independence](https://web.archive.org/web/20250211055127/https://omaninfo.om/pages/175/show/572) + * [Weekend](https://web.archive.org/web/20250213121638/https://abnnews.com/the-sultanate-of-oman-changes-weekend-days-from-01-may-2013/) + * [Decree 56/2020](https://web.archive.org/web/20240522150742/https://decree.om/2020/rd20200056/) + * [Decree 88/2022](https://web.archive.org/web/20221207194900/https://decree.om/2022/rd20220088/) + * [Decree 15/2025 (National day is moved)](https://web.archive.org/web/20250121132446/https://decree.om/2025/rd20250015/) + """ + + country = "OM" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + start_year = 1970 + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + IslamicHolidays.__init__( + self, cls=OmanIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Oman switches from THU-FRI to FRI-SAT on May 1, 2013. + self.weekend = {THU, FRI} if self._year <= 2013 else {FRI, SAT} + + if self._year >= 2020: + # Sultan's Accession Day. + self._add_holiday_jan_11(tr("اليوم الوطني لتولي السلطان")) + + if self._year <= 2019: + # Renaissance Day. + self._add_holiday_jul_23(tr("يوم النهضة")) + + if self._year >= 2020: + # National Day. + name = tr("يوم وطني") + if self._year <= 2024: + self._add_holiday_nov_18(name) + self._add_holiday_nov_19(name) + else: + self._add_holiday_nov_20(name) + self._add_holiday_nov_21(name) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("مولد النبي")) + + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("الإسراء والمعراج")) + + # Eid al-Fitr. + name = tr("عيد الفطر") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + self._add_eid_al_fitr_day_three(name) + for dt in self._add_holiday_29_ramadan(name): + if _timedelta(dt, +1) not in self: + self._add_eid_al_fitr_eve(name) + + # Eid al-Adha. + name = tr("عيد الأضحى") + self._add_arafah_day(name) + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_eid_al_adha_day_three(name) + + +class OM(Oman): + pass + + +class OMN(Oman): + pass + + +class OmanIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20240911084650/https://www.timeanddate.com/holidays/oman/muharram-new-year + HIJRI_NEW_YEAR_DATES = { + 2018: (SEP, 11), + 2019: (SEP, 1), + 2020: (AUG, 21), + 2021: (AUG, 10), + 2022: (JUL, 30), + 2023: (JUL, 20), + 2024: (JUL, 7), + } + + # https://web.archive.org/web/20240810230306/https://www.timeanddate.com/holidays/oman/prophet-birthday + MAWLID_DATES = { + 2018: (NOV, 20), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 9), + 2023: (SEP, 28), + 2024: (SEP, 15), + } + + # https://web.archive.org/web/20241231191036/https://www.timeanddate.com/holidays/oman/isra-miraj + ISRA_AND_MIRAJ_DATES = { + 2018: (APR, 13), + 2019: (APR, 3), + 2020: (MAR, 22), + 2021: (MAR, 11), + 2022: (MAR, 1), + 2023: (FEB, 19), + 2024: (FEB, 8), + 2025: (JAN, 27), + } + + # https://web.archive.org/web/20240913230603/https://www.timeanddate.com/holidays/oman/eid-al-adha + EID_AL_ADHA_DATES = { + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 17), + } + + # https://web.archive.org/web/20241231191036/https://www.timeanddate.com/holidays/oman/eid-al-fitr + EID_AL_FITR_DATES = { + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + # https://web.archive.org/web/20240814104839/https://www.timeanddate.com/holidays/oman/ramadan-begins + RAMADAN_BEGINNING_DATES = { + 2023: (MAR, 23), + 2024: (MAR, 12), + 2025: (MAR, 1), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/pakistan.py b/.venv/lib/python3.12/site-packages/holidays/countries/pakistan.py new file mode 100644 index 00000000..554bf722 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/pakistan.py @@ -0,0 +1,204 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Pakistan(HolidayBase, InternationalHolidays, IslamicHolidays): + """Pakistan holidays. + + References: + * + * + * [Public and optional holidays](https://web.archive.org/web/20250118105814/https://cabinet.gov.pk/Detail/OTE2ODBiYmItZmI0MS00NDAwLWE5NGUtYmE1MGVjYzllMzAz) + * [No.10-01/2024-Min-II](https://web.archive.org/web/20241103080918/https://cabinet.gov.pk/SiteImage/Misc/files/Holidays/28-5-24.pdf) + """ + + country = "PK" + default_language = "en_PK" + # %s (estimated). + estimated_label = tr("%s (estimated)") + start_year = 1948 + supported_languages = ("en_PK", "en_US", "ur_PK") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=PakistanIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year >= 1990: + # Kashmir Solidarity Day. + self._add_holiday_feb_5(tr("Kashmir Solidarity Day")) + + if self._year >= 1956: + # Pakistan Day. + self._add_holiday_mar_23(tr("Pakistan Day")) + + if self._year >= 1972: + # Labor Day. + self._add_labor_day(tr("Labour Day")) + + if self._year >= 2024: + # Youm-e-Takbeer. + self._add_holiday_may_28(tr("Youm-e-Takbeer")) + + # Independence Day. + self._add_holiday_aug_14(tr("Independence Day")) + + if self._year <= 2014 or self._year >= 2022: + # Iqbal Day. + self._add_holiday_nov_9(tr("Iqbal Day")) + + # Quaid-e-Azam Day. + self._add_holiday_dec_25(tr("Quaid-e-Azam Day")) + + # Eid al-Fitr. + name = tr("Eid-ul-Fitr") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + self._add_eid_al_fitr_day_three(name) + + # Eid al-Adha. + name = tr("Eid-ul-Adha") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_eid_al_adha_day_three(name) + + # Prophet's Birthday. + self._add_mawlid_day(tr("Eid Milad-un-Nabi")) + + # Ashura. + name = tr("Ashura") + self._add_ashura_eve(name) + self._add_ashura_day(name) + + +class PK(Pakistan): + pass + + +class PAK(Pakistan): + pass + + +class PakistanIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20241123192805/https://www.timeanddate.com/holidays/pakistan/first-day-ashura + + ASHURA_DATES = { + 2005: (FEB, 18), + 2006: (FEB, 8), + 2007: (JAN, 28), + 2008: (JAN, 18), + 2009: ((JAN, 6), (DEC, 26)), + 2010: (DEC, 16), + 2011: (DEC, 5), + 2012: (NOV, 23), + 2013: (NOV, 13), + 2014: (NOV, 3), + 2015: (OCT, 23), + 2016: (OCT, 11), + 2017: (SEP, 30), + 2018: (SEP, 21), + 2019: (SEP, 9), + 2020: (AUG, 29), + 2021: (AUG, 18), + 2022: (AUG, 9), + 2023: (JUL, 28), + 2024: (JUL, 16), + } + + # https://web.archive.org/web/20250424085932/https://www.timeanddate.com/holidays/pakistan/eid-ul-azha + EID_AL_ADHA_DATES = { + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 6), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 21), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + } + + # https://web.archive.org/web/20250414111814/https://www.timeanddate.com/holidays/pakistan/eid-ul-fitr-1 + EID_AL_FITR_DATES = { + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 17), + 2016: (JUL, 6), + 2017: (JUN, 26), + 2018: (JUN, 16), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 3), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + # https://web.archive.org/web/20240529050144/https://www.timeanddate.com/holidays/pakistan/eid-milad-un-nabi + MAWLID_DATES = { + 2005: (APR, 22), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (MAR, 21), + 2009: (MAR, 9), + 2010: (MAR, 1), + 2011: (FEB, 17), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: (JAN, 4), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 30), + 2021: (OCT, 19), + 2022: (OCT, 9), + 2023: (SEP, 29), + 2024: (SEP, 17), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/palau.py b/.venv/lib/python3.12/site-packages/holidays/countries/palau.py new file mode 100644 index 00000000..5bc638e2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/palau.py @@ -0,0 +1,127 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import SEP, NOV +from holidays.constants import ARMED_FORCES, HALF_DAY, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_TO_PREV_FRI, SUN_TO_NEXT_MON + + +class Palau(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Palau holidays. + + References: + * [Chapter 7, Holidays](https://web.archive.org/web/20250130144425/http://www.paclii.org/pw/legis/consol_act/gpt1262/) + * + * [EO336 Memorial Day repealed](https://web.archive.org/web/20250429131246/https://www.facebook.com/plugins/post.php?href=https://www.facebook.com/PalauPresident/posts/195883107230463) + * [Earliest source for President's Day](https://web.archive.org/web/20250429075658/https://www.taiwanembassy.org/pal_en/post/792.html) + + If any of the holidays enumerated in section 701 of this chapter falls on Sunday, the + following Monday shall be observed as a holiday. If any of the holidays enumerated in + section 701 of this chapter falls on Saturday, the preceding Friday shall be observed + as a holiday. + + As there's no record of President's Day (Jun 1) and Independence Day (Oct 1) being + legal holiday before 2017, as seen in RPRL 10-15, they shall be assumed to start in 2018 + for our current implementation. + """ + + country = "PW" + supported_categories = (ARMED_FORCES, HALF_DAY, PUBLIC) + observed_label = "%s (observed)" + # Republic of Palau Public Law No. 2-15. + # The legislation was first adopted by the 2nd Olbiil Era Kelulau (1984-1988), + # but since we cannot find any info on its actual adoption date, we may as + # well use the formation date of the country as the placeholder cut-off date. + start_year = 1981 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, PalauStaticHolidays) + kwargs.setdefault("observed_rule", SAT_TO_PREV_FRI + SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Fixed Date Public Holidays. + + # New Year's Day. + name = "New Year's Day" + self._add_observed(self._add_new_years_day(name)) + self._add_observed(self._next_year_new_years_day, name=name, rule=SAT_TO_PREV_FRI) + + # Youth Day. + self._add_observed(self._add_holiday_mar_15("Youth Day")) + + # Senior Citizens Day. + self._add_observed(self._add_holiday_may_5("Senior Citizens Day")) + + if self._year in {2011, 2012}: + # Memorial Day. + self._add_holiday_last_mon_of_may("Memorial Day") + + if self._year >= 2018: + # President's Day. + self._add_observed(self._add_holiday_jun_1("President's Day")) + + # Constitution Day. + self._add_observed(self._add_holiday_jul_9("Constitution Day")) + + # Labor Day. + self._add_holiday_1st_mon_of_sep("Labor Day") + + if self._year >= 2018: + # Independence Day. + self._add_observed(self._add_holiday_oct_1("Independence Day")) + + # United Nations Day. + self._add_observed(self._add_united_nations_day("United Nations Day")) + + # Thanksgiving Day. + self._add_holiday_4th_thu_of_nov("Thanksgiving Day") + + if self._year >= 2017: + # Family Day. + self._add_holiday_4th_fri_of_nov("Family Day") + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day")) + + +class PW(Palau): + pass + + +class PLW(Palau): + pass + + +class PalauStaticHolidays: + """Palau special holidays. + + References: + * + * + * + """ + + special_armed_forces_holidays = { + 2020: (NOV, 11, "Veterans Day"), + } + + special_half_day_holidays = { + 2019: (SEP, 30, "Preparation for the 25th Independence Day of the Republic of Palau"), + } + + special_public_holidays = { + 2020: (NOV, 3, "National Day of Democracy"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/palestine.py b/.venv/lib/python3.12/site-packages/holidays/countries/palestine.py new file mode 100644 index 00000000..3b89eaca --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/palestine.py @@ -0,0 +1,177 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import GREGORIAN_CALENDAR, SEP +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.constants import CATHOLIC, ORTHODOX, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Palestine(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Palestine holidays. + + References: + * + * + * [Declaration of Palestine independence](https://en.wikipedia.org/wiki/Palestine#Uprising,_declaration_and_peace_treaty) + """ + + country = "PS" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + # State of Palestine declared in November 1988. + start_year = 1989 + supported_categories = (CATHOLIC, ORTHODOX, PUBLIC) + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = False, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self, calendar=JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=PalestineIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادي")) + + # Orthodox Christmas Day. + self._add_christmas_day(tr("عيد الميلاد المجيد الشرقي")) + + # International Women's Day. + self._add_womens_day(tr("يوم المراة العالمي")) + + # Easter. + self._add_easter_sunday(tr("عيد الفصح المجيد"), GREGORIAN_CALENDAR) + + # Easter. + self._add_easter_sunday(tr("عيد الفصح المجيد")) + + # Labor Day. + self._add_labor_day(tr("عيد العمال")) + + # Independence Day. + self._add_holiday_nov_15(tr("عيد الإستقلال")) + + # Catholic Christmas Day. + self._add_christmas_day(tr("عيد الميلاد المجيد الغربي"), GREGORIAN_CALENDAR) + + # Hijri New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("ذكرى المولد النبوي الشريف")) + + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("ذكرى الإسراء والمعراج")) + + # Eid al-Fitr. + name = tr("عيد الفطر السعيد") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + self._add_eid_al_fitr_day_three(name) + + # Eid al-Adha. + name = tr("عيد الأضحى المبارك") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_eid_al_adha_day_three(name) + self._add_eid_al_adha_day_four(name) + + def _populate_catholic_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادي")) + + # Epiphany. + self._add_epiphany_day(tr("عيد الغطاس"), GREGORIAN_CALENDAR) + + # Palm Sunday. + self._add_palm_sunday(tr("أحد الشعانين"), GREGORIAN_CALENDAR) + + # Holy Thursday. + self._add_holy_thursday(tr("خميس الغسل"), GREGORIAN_CALENDAR) + + # Good Friday. + self._add_good_friday(tr("الجمعة العظيمة"), GREGORIAN_CALENDAR) + + # Holy Saturday. + self._add_holy_saturday(tr("سبت النور"), GREGORIAN_CALENDAR) + + # Easter. + self._add_easter_monday(tr("عيد الفصح المجيد"), GREGORIAN_CALENDAR) + + # Ascension Day. + self._add_ascension_thursday(tr("خميس الصعود"), GREGORIAN_CALENDAR) + + # Pentecost. + self._add_whit_sunday(tr("أحد العنصرة"), GREGORIAN_CALENDAR) + + # Catholic Christmas Day. + self._add_christmas_day_two(tr("عيد الميلاد المجيد الغربي"), GREGORIAN_CALENDAR) + + def _populate_orthodox_holidays(self): + # Orthodox New Year's Day. + self._add_holiday_jan_14(tr("عيد رأس السنة الشرقي")) + + # Orthodox Christmas Day. + self._add_christmas_day_two(tr("عيد الميلاد المجيد الشرقي")) + + # Epiphany. + self._add_epiphany_day(tr("عيد الغطاس")) + + # Palm Sunday. + self._add_palm_sunday(tr("أحد الشعانين")) + + # Holy Thursday. + self._add_holy_thursday(tr("خميس الغسل")) + + # Good Friday. + self._add_good_friday(tr("الجمعة العظيمة")) + + # Holy Saturday. + self._add_holy_saturday(tr("سبت النور")) + + # Easter. + self._add_easter_monday(tr("عيد الفصح المجيد")) + + # Ascension Day. + self._add_ascension_thursday(tr("خميس الصعود")) + + # Pentecost. + self._add_whit_sunday(tr("أحد العنصرة")) + + +class PS(Palestine): + pass + + +class PSE(Palestine): + pass + + +class PalestineIslamicHolidays(_CustomIslamicHolidays): + # All other dates follow Umm al-Qura calendar. + MAWLID_DATES = { + 2023: (SEP, 27), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/panama.py b/.venv/lib/python3.12/site-packages/holidays/countries/panama.py new file mode 100644 index 00000000..04915d6e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/panama.py @@ -0,0 +1,119 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JUL +from holidays.constants import BANK, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Panama(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Panama holidays. + + References: + * + * [Labor Code 1947](https://web.archive.org/web/20250429081529/https://docs.panama.justia.com/federales/leyes/67-de-1947-nov-26-1947.pdf) + * [Cabinet Decree #347 of 1969](https://web.archive.org/web/20250429081519/https://docs.panama.justia.com/federales/decretos-de-gabinete/decreto-de-gabinete-347-de-1969-nov-14-1969.pdf) + * [Labor Code 1971](https://web.archive.org/web/20240420050417/https://www.mitradel.gob.pa/wp-content/uploads/2016/12/código-detrabajo.pdf) + * [Law #4 of Jun 25, 1990](https://web.archive.org/web/20250429081538/https://s3-legispan.asamblea.gob.pa/legispan/NORMAS/1990/1990/LEY/Administrador%20Legispan_21570_1990_7_2_ASAMBLEA%20LEGISLATIVA_4.pdf) + * [Law #55 of Nov 7, 2001](https://web.archive.org/web/20230401210617/https://docs.panama.justia.com/federales/leyes/55-de-2001-nov-14-2001.pdf) + """ + + country = "PA" + default_language = "es" + # %s (observed). + observed_label = tr("%s (puente)") + supported_categories = (BANK, PUBLIC) + supported_languages = ("en_US", "es", "uk") + start_year = 1948 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, PanamaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1972) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year >= 1972: + # Martyrs' Day. + self._add_observed(self._add_holiday_jan_9(tr("Día de los Mártires"))) + + if self._year <= 1971: + # Constitution Day. + self._add_holiday_mar_1(tr("Día de la Constitución")) + + # Carnival Tuesday. + self._add_carnival_tuesday(tr("Martes de Carnaval")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Día del Trabajo"))) + + # Separation Day. + self._add_observed(self._add_holiday_nov_3(tr("Separación de Panamá de Colombia"))) + + # Law #55 of Nov 7, 2001. + if self._year >= 2002: + # Colon Day. + self._add_observed(self._add_holiday_nov_5(tr("Día de Colón"))) + + # Cabinet Decree #347 of 1969. + if self._year >= 1969: + # Los Santos Uprising Day. + self._add_observed(self._add_holiday_nov_10(tr("Primer Grito de Independencia"))) + + # Independence Day. + self._add_observed(self._add_holiday_nov_28(tr("Independencia de Panamá de España"))) + + # Mother's Day. + self._add_observed(self._add_holiday_dec_8(tr("Día de la Madre"))) + + if self._year >= 2022: + # National Mourning Day. + self._add_observed(self._add_holiday_dec_20(tr("Día de Duelo Nacional"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Navidad"))) + + def _populate_bank_holidays(self): + # Carnival Monday. + self._add_carnival_monday(tr("Lunes de Carnaval")) + + # National Symbols Day. + self._add_holiday_nov_4(tr("Día de los Símbolos Patrios")) + + +class PA(Panama): + pass + + +class PAN(Panama): + pass + + +class PanamaStaticHolidays: + # Presidential Inauguration Day. + presidential_inauguration_day = tr("Toma posesión del Presidente de la república") + special_public_holidays = { + 2014: (JUL, 1, presidential_inauguration_day), + 2019: (JUL, 1, presidential_inauguration_day), + 2024: (JUL, 1, presidential_inauguration_day), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/papua_new_guinea.py b/.venv/lib/python3.12/site-packages/holidays/countries/papua_new_guinea.py new file mode 100644 index 00000000..0fb6df1e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/papua_new_guinea.py @@ -0,0 +1,179 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, JUN, SEP, NOV +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class PapuaNewGuinea( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """Papua New Guinea holidays. + + References: + * [Public Holidays Act 1953](https://web.archive.org/web/20250406104407/http://www.paclii.org/pg/legis/consol_act/pha1953163.pdf) + * + * + + Checked With: + * + * + * [2019](https://web.archive.org/web/20250429081247/https://www.scribd.com/document/465334129/PNG-2019-Gazetted-Public-Holidays-pdf) + * [2020](https://web.archive.org/web/20250429081229/https://publicholidays.asia/wp-content/uploads/2020/01/PNG_PublicHolidays_2020.png) + * [2021](https://web.archive.org/web/20240625200332/https://publicholidays.asia/wp-content/uploads/2020/12/PNG_PublicHolidays_2021.pdf) + * [2022](https://web.archive.org/web/20230530042019/https://publicholidays.asia/wp-content/uploads/2022/01/PNG_PublicHolidays_2022.pdf) + * [2023](https://web.archive.org/web/20240413053729/https://publicholidays.asia/wp-content/uploads/2022/12/PNG_PublicHolidays_2023.pdf) + + Should a holiday listed, other than the Christmas Day, fall on a Sunday the next Monday + shall, unless the Head of State, acting on advice, declares otherwise, be observed as a + public holiday throughout the country. + + When Christmas Day falls on a Sunday, the following Tuesday shall also be observed as a + public holiday. + """ + + country = "PG" + observed_label = "%s (observed)" + # Public Holidays Law 1953 (No. 38 of 1953). + start_year = 1953 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, PapuaNewGuineaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Section 1: Public Holidays. + # - Easter Saturday is currently not gazetted as a Public Holiday in 2024. + # - While Easter Sunday itself is not listed, this is de facto always a day-off. + + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + # Good Friday. + self._add_good_friday("Good Friday") + + if self._year <= 2023: + # Easter Saturday. + self._add_holy_saturday("Easter Saturday") + + # Easter Sunday. + self._add_easter_sunday("Easter Sunday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Papua New Guinea Remembrance Day. + self._add_observed(self._add_holiday_jul_23("Papua New Guinea Remembrance Day")) + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two("Boxing Day")) + + # Section 2: Independence Day or Days. + + # Independence Day + # Commemorates the attainment of Independent Sovereign Statehood on Sep 16, 1975. + + if self._year >= 1975: + # Independence Day. + self._add_observed(self._add_holiday_sep_16("Independence Day")) + + # Section 3: Anniversary of Birthday of the Queen/King. + # In Papua New Guinea, it is usually celebrated on the second Monday of June every year. + # From 2023, the date changed to Jun 17 (Special Observed for 2023 on Jun 16). + + if self._year <= 2022: + # Queen's Birthday. + self._add_holiday_2nd_mon_of_jun("Queen's Birthday") + else: + # King's Birthday. + self._add_holiday_jun_17("King's Birthday") + + # Section 5: Additional Public Holidays. + + # Grand Chief Sir Michael Somare Remembrance Day. + # First observed on Feb 26, 2022. + # As of 2024, all previous observances so far are done on an ad hoc basis. + + if self._year >= 2022: + # Grand Chief Sir Michael Somare Remembrance Day. + self._add_holiday_feb_26("Grand Chief Sir Michael Somare Remembrance Day") + + # National Repentance Day. + # Enacted Aug 15, 2011, celebrated by "prayer ceremonies" across the country. + # First observed on Aug 26, 2011, held annually since then on that date. + + if self._year >= 2011: + # The National Repentance Day. + self._add_observed(self._add_holiday_aug_26("National Repentance Day")) + + +class PG(PapuaNewGuinea): + pass + + +class PNG(PapuaNewGuinea): + pass + + +class PapuaNewGuineaStaticHolidays: + """Papua New Guinea special holidays. + + References: + * [2018 APEC Public Holiday](https://web.archive.org/web/20220813203130/https://www.rnz.co.nz/international/pacific-news/369989/papua-new-guinea-declares-apec-holiday) + * [2021 Sir Mekere Morauta's Funeral](https://web.archive.org/web/20241206065336/https://pnghausbung.com/friday-8th-declared-a-nation-wide-public-holiday-to-honour-late-sir-mekere/) + * [2021 Sir Michael Somare's Day of Mourning](https://web.archive.org/web/20241207121149/https://pnghausbung.com/2-weeks-mourning-period-for-late-sir-micheal-to-start-with-public-holiday-on-monday-pm/) + * [2022 QE2's Funeral](https://web.archive.org/web/20220914111729/https://www.thenational.com.pg/column-1-553/) + * [2023 Sir Rabbie Namaliu's Funeral](https://web.archive.org/web/20241109201443/https://pnghausbung.com/breaking-public-holiday-tomorrow-in-respect-of-late-sir-rabbies-state-funeral/) + + Nov 15, 2018 is an APEC Holiday too, but for Port Moresby-only: + + + Starting from 2021 afterwards all state funerals are given special public holidays, though only + some are day-off nationwide. + """ + + # National Day of Mourning for Sir Michael Somare. + sir_michael_somare_mourning_day = "National Day of Mourning for Sir Michael Somare" + + # Grand Chief Sir Michael Somare Remembrance Day + sir_michael_somare_remembrance_day = "Grand Chief Sir Michael Somare Remembrance Day" + + special_public_holidays = { + # APEC Leaders' Summit Public Holiday. + 2018: (NOV, 16, "APEC Leaders' Summit Public Holiday"), + 2021: ( + # State Funeral of Sir Mekere Morauta. + (JAN, 8, "State Funeral of Sir Mekere Morauta"), + (MAR, 1, sir_michael_somare_mourning_day), + (MAR, 12, sir_michael_somare_mourning_day), + ), + # State Funeral of Queen Elizabeth II. + 2022: (SEP, 19, "State Funeral of Queen Elizabeth II"), + # State Funeral of Sir Rabbie Namaliu. + 2023: (APR, 18, "State Funeral of Sir Rabbie Namaliu"), + } + + special_public_holidays_observed = { + 2022: (FEB, 28, sir_michael_somare_remembrance_day), + 2023: ( + (FEB, 24, sir_michael_somare_remembrance_day), + (JUN, 16, "King's Birthday"), + (SEP, 15, "Independence Day"), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/paraguay.py b/.venv/lib/python3.12/site-packages/holidays/countries/paraguay.py new file mode 100644 index 00000000..a7a11c22 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/paraguay.py @@ -0,0 +1,224 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, DEC +from holidays.constants import GOVERNMENT, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Paraguay(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Paraguay holidays. + + References: + * [Ley 8/1990](https://web.archive.org/web/20250427173904/https://www.bacn.gov.py/leyes-paraguayas/2358/ley-n-8--por-la-cual-se-determinan-los-feriados-de-la-republica) + * [Ley 715/1995](https://web.archive.org/web/20250427174040/https://www.bacn.gov.py/leyes-paraguayas/792/ley-n-715--amplia-la-ley-no-0890-) + * [Ley 1.601/2000](https://web.archive.org/web/20250427173847/https://www.bacn.gov.py/leyes-paraguayas/1677/ley-n-1601--modifica-el-articulo-1-de-la-ley-no-71595-que-amplia-la-ley-n-0890-por-la-cual-se-determinan-los-feriados-de-la-republica) + * [Ley 1.723/2001](https://web.archive.org/web/20250427173914/https://www.bacn.gov.py/leyes-paraguayas/634/ley-n-1723--autoriza-al-poder-ejecutivo-a-trasladar-los-feriados-nacionales-al-dia-lunes) + * [Ley 4.531/2011](https://web.archive.org/web/20250420210317/https://www.bacn.gov.py/leyes-paraguayas/3831/ley-n-4531-restablece-el-dia-14-de-mayo-de-cada-ano-como-feriado-nacional) + * + * + """ + + country = "PY" + default_language = "es" + supported_categories = (GOVERNMENT, PUBLIC) + supported_languages = ("en_US", "es", "uk") + # Ley 8/1990. + start_year = 1991 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, ParaguayStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + dates_obs = { + 2013: (MAR, 4), + 2016: (FEB, 29), + 2018: (FEB, 26), + 2019: (MAR, 4), + 2022: (FEB, 28), + 2023: (FEB, 27), + } + self._add_holiday( + # Patriots Day. + tr("Día de los Héroes de la Patria"), + dates_obs.get(self._year, (MAR, 1)), + ) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Easter Sunday. + self._add_easter_sunday(tr("Domingo de Resurrección")) + + # Workers' Day. + self._add_labor_day(tr("Día de los Trabajadores")) + + if self._year >= 2012: + # National Holiday. + self._add_holiday_may_14(tr("Feriado Nacional")) + + # Independence Day. + self._add_holiday_may_15(tr("Día de la Independencia Nacional")) + + dates_obs = { + 2014: (JUN, 16), + 2018: (JUN, 11), + 2019: (JUN, 17), + 2024: (JUN, 10), + } + # Chaco Armistice Day. + self._add_holiday(tr("Día de la Paz del Chaco"), dates_obs.get(self._year, (JUN, 12))) + + # Asuncion Foundation's Day. + self._add_holiday_aug_15(tr("Día de la Fundación de Asunción")) + + # Ley 715/1995, 1.601/2000. + if self._year >= 1995: + dates_obs = { + 2015: (SEP, 28), + 2016: (OCT, 3), + 2017: (OCT, 2), + 2021: (SEP, 27), + 2022: (OCT, 3), + 2024: (SEP, 30), + } + self._add_holiday( + # Boqueron Battle Day. + tr("Día de la Batalla de Boquerón"), + dates_obs.get(self._year, (SEP, 29)), + ) + + # Caacupe Virgin Day. + self._add_holiday_dec_8(tr("Día de la Virgen de Caacupé")) + + # Christmas Day. + self._add_christmas_day(tr("Día de la Navidad")) + + +class PY(Paraguay): + pass + + +class PRY(Paraguay): + pass + + +class ParaguayStaticHolidays: + # Public holiday. + public_holiday = tr("Asueto adicionale") + # Public sector holiday. + public_sector_holiday = tr("Asueto de la Administración Pública") + + special_public_holidays = { + # public holiday for business purposes, in view of the recently increased risk + # of Dengue fever. + 2007: (JAN, 29, public_holiday), + # public sector holiday to celebrate Paraguay's football team's qualification + # for the 2010 World Cup. + 2009: (SEP, 10, public_holiday), + # public holiday to coincide with the Paraguay-Italy game of the current World Cup. + 2010: (JUN, 14, public_holiday), + 2011: ( + # public holiday to coincide with the current anti-Dengue drive. + (APR, 19, public_holiday), + # public holidays to commemorate the Bicentennial of Paraguay's independence. + (MAY, 14, public_holiday), + (MAY, 16, public_holiday), + ), + # date of the inauguration of President-elect Horacio Cartes. + 2013: (AUG, 14, public_holiday), + 2015: ( + # public holidays in Paraguay on account of the upcoming visit of Pope Francis + # in Paraguay. + (JUL, 10, public_holiday), + (JUL, 11, public_holiday), + ), + } + + special_government_holidays = { + 2010: ( + # 2 year-end public sector holidays. + (DEC, 24, public_sector_holiday), + (DEC, 31, public_sector_holiday), + ), + 2011: ( + # public sector holiday to let civil servants begin their Holy Week earlier. + (APR, 20, public_sector_holiday), + # 2 year-end public sector holidays. + (DEC, 23, public_sector_holiday), + (DEC, 30, public_sector_holiday), + ), + 2012: ( + # public sector holiday to let civil servants begin their Holy Week earlier. + (APR, 4, public_sector_holiday), + # 2 year-end public sector holidays. + (DEC, 24, public_sector_holiday), + (DEC, 31, public_sector_holiday), + ), + # public sector holiday to let civil servants begin their Holy Week earlier. + 2013: (MAR, 27, public_sector_holiday), + 2014: ( + # public sector holiday to let civil servants begin their Holy Week earlier. + (APR, 16, public_sector_holiday), + # 2 year-end public sector holidays. + (DEC, 24, public_sector_holiday), + (DEC, 31, public_sector_holiday), + ), + 2015: ( + # public sector holiday to let civil servants begin their Holy Week earlier. + (APR, 1, public_sector_holiday), + # 2 year-end public sector holidays. + (DEC, 24, public_sector_holiday), + (DEC, 31, public_sector_holiday), + ), + # public sector holiday to let civil servants begin their Holy Week earlier. + 2016: (MAR, 23, public_sector_holiday), + # public sector holiday to let civil servants begin their Holy Week earlier. + 2017: (MAR, 28, public_sector_holiday), + 2018: ( + # 2 year-end public sector holidays. + (DEC, 24, public_sector_holiday), + (DEC, 31, public_sector_holiday), + ), + 2019: ( + # public sector holiday to let civil servants begin their Holy Week earlier. + (APR, 17, public_sector_holiday), + # 2 year-end public sector holidays. + (DEC, 24, public_sector_holiday), + (DEC, 31, public_sector_holiday), + ), + # public sector holiday to let civil servants begin their Holy Week earlier. + 2020: (APR, 8, public_sector_holiday), + 2021: ( + # 2 year-end public sector holidays. + (DEC, 24, public_sector_holiday), + (DEC, 31, public_sector_holiday), + ), + 2022: ( + # public sector holiday to let civil servants begin their Holy Week earlier. + (APR, 13, public_sector_holiday), + # public sector holiday due to the annual May 1st public holiday falling on a Sunday. + (MAY, 2, public_sector_holiday), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/peru.py b/.venv/lib/python3.12/site-packages/holidays/countries/peru.py new file mode 100644 index 00000000..9cf0d832 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/peru.py @@ -0,0 +1,102 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Peru(HolidayBase, ChristianHolidays, InternationalHolidays): + """Peru holidays. + + References: + * + * + * [Ley N° 31788](https://web.archive.org/web/20250716164223/https://img.lpderecho.pe/wp-content/uploads/2023/06/Ley-31788-LPDerecho.pdf) + * [Ley N° 31822](https://web.archive.org/web/20250716164455/https://img.lpderecho.pe/wp-content/uploads/2023/07/Ley-31822-LPDerecho.pdf) + """ + + country = "PE" + default_language = "es" + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Easter Sunday. + self._add_easter_sunday(tr("Domingo de Resurrección")) + + # Labor Day. + self._add_labor_day(tr("Día del Trabajo")) + + # Added via Ley N° 31788 on June 15th, 2023. + if self._year >= 2024: + # Battle of Arica and Flag Day. + self._add_holiday_jun_7(tr("Batalla de Arica y Día de la Bandera")) + + # Saint Peter and Saint Paul's Day. + self._add_saints_peter_and_paul_day(tr("San Pedro y San Pablo")) + + # Added via Ley N° 31822 on July 8th, 2023. + if self._year >= 2023: + # Peruvian Air Force Day. + self._add_holiday_jul_23(tr("Día de la Fuerza Aérea del Perú")) + + # Independence Day. + self._add_holiday_jul_28(tr("Día de la Independencia")) + + # Great Military Parade Day. + self._add_holiday_jul_29(tr("Día de la Gran Parada Militar")) + + if self._year >= 2022: + # Battle of Junín. + self._add_holiday_aug_6(tr("Batalla de Junín")) + + # Rose of Lima Day. + self._add_holiday_aug_30(tr("Santa Rosa de Lima")) + + # Battle of Angamos. + self._add_holiday_oct_8(tr("Combate de Angamos")) + + # All Saints' Day. + self._add_all_saints_day(tr("Todos Los Santos")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Inmaculada Concepción")) + + if self._year >= 2022: + # Battle of Ayacucho. + self._add_holiday_dec_9(tr("Batalla de Ayacucho")) + + # Christmas Day. + self._add_christmas_day(tr("Navidad del Señor")) + + +class PE(Peru): + pass + + +class PER(Peru): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/philippines.py b/.venv/lib/python3.12/site-packages/holidays/countries/philippines.py new file mode 100644 index 00000000..eb5097a5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/philippines.py @@ -0,0 +1,345 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomChineseHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ( + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.holiday_base import HolidayBase + + +class Philippines( + HolidayBase, + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Philippines holidays. + + References: + * + * [Revised Administrative Code of 1987](https://web.archive.org/web/20241203234427/https://www.officialgazette.gov.ph/1987/07/25/executive-order-no-292-book-ichapter-7-regular-holidays-and-nationwide-special-days/) + * [Republic Act No. 9177](https://web.archive.org/web/20230930164310/https://www.officialgazette.gov.ph/2002/11/13/republic-act-no-9177/) + * [Republic Act No. 9256](https://web.archive.org/web/20240706140401/https://www.officialgazette.gov.ph/2004/02/25/republic-act-no-9256/) + * [Republic Act No. 9492](https://web.archive.org/web/20250413180041/http://www.officialgazette.gov.ph/2007/07/24/republic-act-no-9492/) + * [Republic Act No. 9645](https://web.archive.org/web/20231014172648/https://www.officialgazette.gov.ph/2009/06/12/republic-act-no-9645/) + * [Republic Act No. 9849](https://web.archive.org/web/20250424053703/http://officialgazette.gov.ph/2009/12/11/republic-act-no-9849/) + * [Republic Act No. 10966](https://web.archive.org/web/20250419183417/http://www.officialgazette.gov.ph/2017/12/28/republic-act-no-10966/) + * [Proclamation No. 944/2020](https://web.archive.org/web/20250428055016/https://www.officialgazette.gov.ph/2020/05/19/proclamation-no-944-s-2020/) + * [Proclamation No. 985/2020](https://web.archive.org/web/20230901112559/https://www.officialgazette.gov.ph/2020/07/29/proclamation-no-985-s-2020/) + * [Proclamation No. 90/2022](https://web.archive.org/web/20231026052921/https://www.officialgazette.gov.ph/2022/11/09/proclamation-no-90-s-2022/) + * [Proclamation No. 665/2024](https://archive.org/details/20241015-proc-665-frm) + * [Proclamation No. 729/2024](https://archive.org/details/20241030-proc-729-frm) + * [Nationwide holidays 2018-2025](https://web.archive.org/web/20240515022447/https://www.officialgazette.gov.ph/nationwide-holidays/2018/) + * [Proclamation No. 839/2025](https://archive.org/details/20250320-proc-839-frm_202506) + * [Proclamation No. 878/2025](https://archive.org/details/20250506-proc-878-frm_202506) + * [Proclamation No. 911/2025](https://archive.org/details/20250521-proc-911-frm_20250606_1800) + """ + + country = "PH" + supported_categories = (PUBLIC, WORKDAY) + default_language = "en_PH" + # %s (estimated). + estimated_label = tr("%s (estimated)") + supported_languages = ("en_PH", "en_US", "fil", "th") + start_year = 1988 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChineseCalendarHolidays.__init__(self, cls=PhilippinesChineseHolidays) + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=PhilippinesIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=PhilippinesStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("New Year's Day")) + + if self._year >= 2012 and self._year != 2023: + # Chinese New Year. + self._add_chinese_new_years_day(tr("Chinese New Year")) + + if 2016 <= self._year <= 2023 and self._year != 2017: + dates_obs = { + 2023: (FEB, 24), + } + self._add_holiday( + # EDSA People Power Revolution Anniversary. + tr("EDSA People Power Revolution Anniversary"), + dates_obs.get(self._year, (FEB, 25)), + ) + + # Maundy Thursday. + self._add_holy_thursday(tr("Maundy Thursday")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 2013: + # Black Saturday. + self._add_holy_saturday(tr("Black Saturday")) + + dates_obs = { + 2008: (APR, 7), + 2009: (APR, 6), + 2023: (APR, 10), + } + # Day of Valor. + self._add_holiday(tr("Araw ng Kagitingan"), dates_obs.get(self._year, (APR, 9))) + + # Labor Day. + self._add_labor_day(tr("Labor Day")) + + dates_obs = { + 2007: (JUN, 11), + 2008: (JUN, 9), + 2010: (JUN, 14), + } + # Independence Day. + self._add_holiday(tr("Independence Day"), dates_obs.get(self._year, (JUN, 12))) + + if self._year >= 2004: + dates_obs = { + 2007: (AUG, 20), + 2008: (AUG, 18), + 2010: (AUG, 23), + 2024: (AUG, 23), + } + # Ninoy Aquino Day. + self._add_holiday(tr("Ninoy Aquino Day"), dates_obs.get(self._year, (AUG, 21))) + + # National Heroes Day. + name = tr("National Heroes Day") + if self._year >= 2007: + self._add_holiday_last_mon_of_aug(name) + else: + self._add_holiday_last_sun_of_aug(name) + + # All Saints' Day. + self._add_all_saints_day(tr("All Saints' Day")) + + dates_obs = { + 2008: (DEC, 1), + 2010: (NOV, 29), + 2023: (NOV, 27), + } + # Bonifacio Day. + self._add_holiday(tr("Bonifacio Day"), dates_obs.get(self._year, (NOV, 30))) + + if self._year >= 2019: + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Feast of the Immaculate Conception of Mary")) + + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")) + + dates_obs = { + 2010: (DEC, 27), + } + # Rizal Day. + self._add_holiday(tr("Rizal Day"), dates_obs.get(self._year, (DEC, 30))) + + if self._year not in {2021, 2022}: + # New Year's Eve. + self._add_new_years_eve(tr("Last Day of the Year")) + + if self._year >= 2002: + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Eid'l Fitr")) + + if self._year >= 2010: + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Eid'l Adha")) + + def _populate_workday_holidays(self): + # Added in 2009, get special non-working day status in 2025: + if self._year >= 2009 and self._year != 2025: + # Founding Anniversary of Iglesia ni Cristo. + self._add_holiday_jul_27(tr("Founding Anniversary of Iglesia ni Cristo")) + + # Added from 2025 onwards as first decreed in + # https://web.archive.org/web/20250326064645/https://www.officialgazette.gov.ph/downloads/2024/10oct/20241030-PROC-727-FRM.pdf + if self._year >= 2025: + # EDSA People Power Revolution Anniversary. + self._add_holiday_feb_25(tr("EDSA People Power Revolution Anniversary")) + + +class PH(Philippines): + pass + + +class PHL(Philippines): + pass + + +class PhilippinesChineseHolidays(_CustomChineseHolidays): + LUNAR_NEW_YEAR_DATES = { + 2012: (JAN, 23), + 2013: (FEB, 10), + 2014: (JAN, 31), + 2015: (FEB, 19), + 2016: (FEB, 8), + 2017: (JAN, 28), + 2018: (FEB, 16), + 2019: (FEB, 5), + 2020: (JAN, 25), + 2021: (FEB, 12), + 2022: (FEB, 1), + 2023: (JAN, 22), + 2024: (FEB, 10), + 2025: (JAN, 29), + } + + +class PhilippinesIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 6), + 2015: (SEP, 25), + 2016: (SEP, 10), + 2017: (SEP, 2), + 2018: (AUG, 21), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 17), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 12), + 2008: (OCT, 1), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 30), + 2012: (AUG, 20), + 2013: (AUG, 9), + 2014: (JUL, 29), + 2015: (JUL, 17), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 25), + 2021: (MAY, 13), + 2022: (MAY, 3), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (APR, 1), + } + + +class PhilippinesStaticHolidays: + # Additional special (non-working) day. + additional_special = tr("Additional special (non-working) day") + # Elections special (non-working) day. + election_special = tr("Elections special (non-working) day") + + special_public_holidays = { + 2008: ( + (DEC, 26, additional_special), + (DEC, 29, additional_special), + ), + 2009: ( + (NOV, 2, additional_special), + (DEC, 24, additional_special), + ), + 2010: (DEC, 24, additional_special), + 2012: (NOV, 2, additional_special), + 2013: ( + (NOV, 2, additional_special), + (DEC, 24, additional_special), + ), + 2014: ( + (DEC, 24, additional_special), + (DEC, 26, additional_special), + ), + 2015: ( + (JAN, 2, additional_special), + (DEC, 24, additional_special), + ), + 2016: ( + (JAN, 2, additional_special), + (OCT, 31, additional_special), + (DEC, 24, additional_special), + ), + 2017: ( + (JAN, 2, additional_special), + (OCT, 31, additional_special), + ), + 2018: ( + (MAY, 14, election_special), + (NOV, 2, additional_special), + (DEC, 24, additional_special), + ), + 2019: ( + (MAY, 13, election_special), + (NOV, 2, additional_special), + (DEC, 24, additional_special), + ), + 2020: ( + (NOV, 2, additional_special), + (DEC, 24, additional_special), + ), + 2022: ( + (MAY, 9, election_special), + (OCT, 31, additional_special), + ), + 2023: ( + (JAN, 2, additional_special), + (OCT, 30, election_special), + (NOV, 2, additional_special), + (DEC, 26, additional_special), + ), + 2024: ( + (FEB, 9, additional_special), + (NOV, 2, additional_special), + (DEC, 24, additional_special), + ), + 2025: ( + (MAY, 12, election_special), + (JUL, 27, additional_special), + # All Saints' Day Eve. + (OCT, 31, tr("All Saints' Day Eve")), + # Christmas Eve. + (DEC, 24, tr("Christmas Eve")), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/poland.py b/.venv/lib/python3.12/site-packages/holidays/countries/poland.py new file mode 100644 index 00000000..ca3acaa1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/poland.py @@ -0,0 +1,134 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import NOV +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Poland(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Poland holidays. + + References: + * + * + * + """ + + country = "PL" + default_language = "pl" + supported_languages = ("de", "en_US", "pl", "uk") + start_year = 1925 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, PolandStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nowy Rok")) + + if self._year <= 1960 or self._year >= 2011: + # Epiphany. + self._add_epiphany_day(tr("Święto Trzech Króli")) + + if self._year <= 1950: + # Candlemas. + self._add_candlemas(tr("Oczyszczenie Najświętszej Marii Panny")) + + # Easter Sunday. + self._add_easter_sunday(tr("Niedziela Wielkanocna")) + + # Easter Monday. + self._add_easter_monday(tr("Poniedziałek Wielkanocny")) + + if self._year >= 1950: + # National Day. + self._add_holiday_may_1(tr("Święto Państwowe")) + + if self._year <= 1950 or self._year >= 1990: + # National Day of the Third of May. + self._add_holiday_may_3(tr("Święto Narodowe Trzeciego Maja")) + + if 1946 <= self._year <= 1950: + # National Victory and Freedom Day. + self._add_holiday_may_9(tr("Narodowe Święto Zwycięstwa i Wolności")) + + if self._year <= 1950: + # Ascension Day. + self._add_ascension_thursday(tr("Wniebowstąpienie Pańskie")) + + # Pentecost. + self._add_whit_sunday(tr("Zielone Świątki")) + + if self._year <= 1950: + # Whit Monday. + self._add_whit_monday(tr("Drugi dzień Zielonych Świątek")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Dzień Bożego Ciała")) + + if self._year <= 1950: + self._add_saints_peter_and_paul_day( + # Saints Peter and Paul Day. + tr("Uroczystość Świętych Apostołów Piotra i Pawła") + ) + + if 1945 <= self._year <= 1989: + # National Day of Rebirth of Poland. + self._add_holiday_jul_22(tr("Narodowe Święto Odrodzenia Polski")) + + if self._year <= 1960 or self._year >= 1989: + # Assumption Day. + self._add_assumption_of_mary_day(tr("Wniebowzięcie Najświętszej Marii Panny")) + + # All Saints' Day. + self._add_all_saints_day(tr("Uroczystość Wszystkich Świętych")) + + if 1937 <= self._year <= 1944 or self._year >= 1989: + # National Independence Day. + self._add_holiday_nov_11(tr("Narodowe Święto Niepodległości")) + + if self._year <= 1950: + self._add_immaculate_conception_day( + # Immaculate Conception of the Blessed Virgin Mary. + tr("Niepokalane Poczęcie Najświętszej Marii Panny") + ) + + if self._year >= 2025: + # Christmas Eve. + self._add_christmas_eve(tr("Wigilia Bożego Narodzenia")) + + # Christmas Day. + self._add_christmas_day(tr("Boże Narodzenie (pierwszy dzień)")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Boże Narodzenie (drugi dzień)")) + + +class PL(Poland): + pass + + +class POL(Poland): + pass + + +class PolandStaticHolidays: + special_public_holidays = { + # National Independence Day - 100th anniversary. + 2018: (NOV, 12, tr("Narodowe Święto Niepodległości - 100-lecie")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/portugal.py b/.venv/lib/python3.12/site-packages/holidays/countries/portugal.py new file mode 100644 index 00000000..d0a51572 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/portugal.py @@ -0,0 +1,282 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Portugal(HolidayBase, ChristianHolidays, InternationalHolidays): + """Portugal holidays. + + References: + * + * [Labour Day](https://web.archive.org/web/20240502184140/https://www.e-konomista.pt/dia-do-trabalhador/) + * Portugal Day - Decreto 17.171 + * Restoration of Independence Day - Gazeta de Lisboa, 8 de Dezembro + de 1823 (n.º 290), pp. 1789 e 1790 + * Azores: + * + * Madeira: + * + * + * + """ + + country = "PT" + default_language = "pt_PT" + supported_categories = (OPTIONAL, PUBLIC) + start_year = 1801 + subdivisions = ( + "01", # Aveiro. + "02", # Beja. + "03", # Braga. + "04", # Bragança. + "05", # Castelo Branco. + "06", # Coimbra. + "07", # Évora. + "08", # Faro. + "09", # Guarda. + "10", # Leiria. + "11", # Lisboa. + "12", # Portalegre. + "13", # Porto. + "14", # Santarém. + "15", # Setúbal. + "16", # Viana do Castelo. + "17", # Vila Real. + "18", # Viseu. + "20", # Região Autónoma dos Açores. + "30", # Região Autónoma da Madeira. + ) + subdivisions_aliases = { + "Aveiro": "01", + "Beja": "02", + "Braga": "03", + "Bragança": "04", + "Castelo Branco": "05", + "Coimbra": "06", + "Évora": "07", + "Faro": "08", + "Guarda": "09", + "Leiria": "10", + "Lisboa": "11", + "Portalegre": "12", + "Porto": "13", + "Santarém": "14", + "Setúbal": "15", + "Viana do Castelo": "16", + "Vila Real": "17", + "Viseu": "18", + "Região Autónoma dos Açores": "20", + "Região Autónoma da Madeira": "30", + } + supported_languages = ("en_US", "pt_PT", "uk") + _deprecated_subdivisions = ("Ext",) + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Ano Novo")) + + # Carnival is no longer a holiday, but some companies let workers off. + # TODO: recollect the years in which it was a public holiday. + + # Good Friday. + self._add_good_friday(tr("Sexta-feira Santa")) + + # Easter Sunday. + self._add_easter_sunday(tr("Páscoa")) + + # Revoked holidays in 2013-2015. + if self._year <= 2012 or self._year >= 2016: + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpo de Deus")) + + if self._year >= 1910: + # Republic Day. + self._add_holiday_oct_5(tr("Implantação da República")) + + # All Saints' Day. + self._add_all_saints_day(tr("Dia de Todos os Santos")) + + if self._year >= 1823: + # Restoration of Independence Day. + self._add_holiday_dec_1(tr("Restauração da Independência")) + + if self._year >= 1974: + # Freedom Day. + self._add_holiday_apr_25(tr("Dia da Liberdade")) + + # Labor Day. + self._add_labor_day(tr("Dia do Trabalhador")) + + if self._year >= 1911: + if 1933 <= self._year <= 1973: + # Day of Camões, Portugal, and the Portuguese Race. + self._add_holiday_jun_10(tr("Dia de Camões, de Portugal e da Raça")) + elif self._year >= 1978: + self._add_holiday_jun_10( + # Day of Portugal, Camões, and the Portuguese Communities. + tr("Dia de Portugal, de Camões e das Comunidades Portuguesas") + ) + else: + # Portugal Day. + self._add_holiday_jun_10(tr("Dia de Portugal")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assunção de Nossa Senhora")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Imaculada Conceição")) + + # Christmas Day. + self._add_christmas_day(tr("Dia de Natal")) + + def _populate_optional_holidays(self): + """ + Adds extended days that most people have as a bonus from their + companies: + + - Carnival + - the day before and after xmas + - the day before the new year + - Lisbon's city holiday + """ + + # TODO: add bridging days: + # - get Holidays that occur on Tuesday and add Monday (-1 day) + # - get Holidays that occur on Thursday and add Friday (+1 day) + + # Carnival. + self._add_carnival_tuesday(tr("Carnaval")) + + # Saint Anthony's Day. + self._add_holiday_jun_13(tr("Dia de Santo António")) + + # Christmas Eve. + self._add_christmas_eve(tr("Véspera de Natal")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("26 de Dezembro")) + + # New Year's Eve. + self._add_new_years_eve(tr("Véspera de Ano Novo")) + + def _populate_subdiv_holidays(self): + if self._year >= 1911: + super()._populate_subdiv_holidays() + + if self.subdiv == "Ext": + self._populate_optional_holidays() + + def _populate_subdiv_01_public_holidays(self): + # Saint Joanna's Day. + self._add_holiday_may_12(tr("Dia de Santa Joana")) + + def _populate_subdiv_02_public_holidays(self): + # Ascension Day. + self._add_ascension_thursday(tr("Quinta-feira da Ascensão")) + + def _populate_subdiv_03_public_holidays(self): + # Saint John's Day. + self._add_saint_johns_day(tr("Dia de São João")) + + def _populate_subdiv_04_public_holidays(self): + # Feast of Our Lady of Graces. + self._add_holiday_aug_22(tr("Dia de Nossa Senhora das Graças")) + + def _populate_subdiv_05_public_holidays(self): + # Feast of Our Lady of Mércoles. + self._add_holiday_16_days_past_easter(tr("Dia de Nossa Senhora de Mércoles")) + + def _populate_subdiv_06_public_holidays(self): + # Saint Elizabeth's Day. + self._add_holiday_jul_4(tr("Dia de Santa Isabel")) + + def _populate_subdiv_07_public_holidays(self): + # Saint Peter's Day. + self._add_saints_peter_and_paul_day(tr("Dia de São Pedro")) + + def _populate_subdiv_08_public_holidays(self): + # Municipal Holiday of Faro. + self._add_holiday_sep_7(tr("Dia do Município de Faro")) + + def _populate_subdiv_09_public_holidays(self): + # Municipal Holiday of Guarda. + self._add_holiday_nov_27(tr("Dia do Município da Guarda")) + + def _populate_subdiv_10_public_holidays(self): + # Municipal Holiday of Leiria. + self._add_holiday_may_22(tr("Dia do Município de Leiria")) + + def _populate_subdiv_11_public_holidays(self): + self._add_holiday_jun_13(tr("Dia de Santo António")) + + def _populate_subdiv_12_public_holidays(self): + # Municipal Holiday of Portalegre. + self._add_holiday_may_23(tr("Dia do Município de Portalegre")) + + def _populate_subdiv_13_public_holidays(self): + self._add_saint_johns_day(tr("Dia de São João")) + + def _populate_subdiv_14_public_holidays(self): + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("Dia de São José")) + + def _populate_subdiv_15_public_holidays(self): + # Bocage Day. + self._add_holiday_sep_15(tr("Dia de Bocage")) + + def _populate_subdiv_16_public_holidays(self): + # Feast of Our Lady of Sorrows. + self._add_holiday_aug_20(tr("Dia de Nossa Senhora da Agonia")) + + def _populate_subdiv_17_public_holidays(self): + self._add_holiday_jun_13(tr("Dia de Santo António")) + + def _populate_subdiv_18_public_holidays(self): + # Saint Matthew's Day. + self._add_holiday_sep_21(tr("Dia de São Mateus")) + + def _populate_subdiv_20_public_holidays(self): + if self._year >= 1981: + # Day of the Autonomous Region of the Azores. + self._add_whit_monday(tr("Dia da Região Autónoma dos Açores")) + + def _populate_subdiv_30_public_holidays(self): + if self._year >= 1979: + self._add_holiday_jul_1( + # Day of the Autonomous Region of Madeira and the Madeiran Communities. + tr("Dia da Região Autónoma da Madeira e das Comunidades Madeirenses") + if self._year >= 1989 + # Day of the Autonomous Region of Madeira. + else tr("Dia da Região Autónoma da Madeira") + ) + + if self._year >= 2002: + # 1st Octave. + self._add_christmas_day_two(tr("Primeira Oitava")) + + +class PT(Portugal): + pass + + +class PRT(Portugal): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/puerto_rico.py b/.venv/lib/python3.12/site-packages/holidays/countries/puerto_rico.py new file mode 100644 index 00000000..32a624cd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/puerto_rico.py @@ -0,0 +1,39 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.united_states import UnitedStates +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysPR(ChildEntity, UnitedStates): + """Puerto Rico holidays. + + Alias of a US subdivision that is also officially assigned its own country code in ISO 3166-1. + See + """ + + country = "PR" + parent_entity = UnitedStates + # Became a U.S. Territory on April 11th, 1899. + start_year = 1900 + + +class PuertoRico(HolidaysPR): + pass + + +class PR(HolidaysPR): + pass + + +class PRI(HolidaysPR): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/qatar.py b/.venv/lib/python3.12/site-packages/holidays/countries/qatar.py new file mode 100644 index 00000000..d276bff9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/qatar.py @@ -0,0 +1,172 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + THU, + FRI, + SAT, +) +from holidays.constants import BANK, PUBLIC +from holidays.groups import InternationalHolidays, IslamicHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Qatar(HolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays): + """Qatar holidays. + + References: + * + * [National Sports Day](https://web.archive.org/web/20250417141518/https://hukoomi.gov.qa/en/national-sport-day) + * [Qatar National Day](https://web.archive.org/web/20240522081644/https://www.qatar.qa/en/qatar/history-of-qatar-qatar-national-day-committee/) + * [Weekend](https://web.archive.org/web/20240930093123/https://www.arabnews.com/node/234601) + """ + + country = "QA" + default_language = "ar_QA" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + start_year = 1971 + supported_categories = (BANK, PUBLIC) + supported_languages = ("ar_QA", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=QatarIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, QatarStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Qatar switches from THU-FRI to FRI-SAT on Aug 1, 2003. + self.weekend = {THU, FRI} if self._year <= 2003 else {FRI, SAT} + + if self._year >= 2012: + # National Sports Day. + self._add_holiday_2nd_tue_of_feb(tr("اليوم الوطني للرياضة")) + + if self._year >= 2007: + # Qatar National Day. + self._add_holiday_dec_18(tr("اليوم الوطني لقطر")) + + # Eid al-Fitr. + name = tr("عيد الفطر") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + self._add_eid_al_fitr_day_three(name) + + # Eid al-Adha. + name = tr("عيد الأضحى") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_eid_al_adha_day_three(name) + + def _populate_bank_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + if self._year >= 2010: + # March Bank Holiday. + self._add_holiday_1st_sun_of_mar(tr("عطلة البنك")) + + +class QA(Qatar): + pass + + +class QAT(Qatar): + pass + + +class QatarIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20250422212912/https://www.timeanddate.com/holidays/qatar/eid-al-adha + EID_AL_ADHA_DATES = { + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 15), + 2011: (NOV, 6), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 23), + 2016: (SEP, 10), + 2017: (AUG, 31), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + } + + # https://web.archive.org/web/20241207022523/https://www.timeanddate.com/holidays/qatar/eid-al-fitr + EID_AL_FITR_DATES = { + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 18), + 2016: (JUL, 6), + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + +class QatarStaticHolidays: + """Qatar special holidays. + + References: + * [New Year's Holiday](https://web.archive.org/web/20250119073018/https://www.expatica.com/qa/lifestyle/holidays/qatar-public-holidays-74585/) + """ + + # New Year's Holiday. + name = tr("عطلة رأس السنة") + special_public_holidays = { + 2025: (JAN, 2, name), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/reunion.py b/.venv/lib/python3.12/site-packages/holidays/countries/reunion.py new file mode 100644 index 00000000..8d43ae4c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/reunion.py @@ -0,0 +1,44 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysRE(ChildEntity, France): + """Réunion holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "RE" + parent_entity = France + parent_entity_subdivision_code = "974" + # Cession from the UK on May 30th, 1814. + start_year = 1815 + + +class Reunion(HolidaysRE): + pass + + +class RE(HolidaysRE): + pass + + +class REU(HolidaysRE): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/romania.py b/.venv/lib/python3.12/site-packages/holidays/countries/romania.py new file mode 100644 index 00000000..9499d9b2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/romania.py @@ -0,0 +1,98 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.julian_revised import JULIAN_REVISED_CALENDAR +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Romania(HolidayBase, ChristianHolidays, InternationalHolidays): + """Romania holidays. + + References: + * + * + """ + + country = "RO" + default_language = "ro" + supported_languages = ("en_US", "ro", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_REVISED_CALENDAR) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Anul Nou") + self._add_new_years_day(name) + self._add_new_years_day_two(name) + + if self._year >= 2024: + # Epiphany. + self._add_epiphany_day(tr("Bobotează")) + + # Saint John the Baptist. + self._add_holiday_jan_7(tr("Sfântul Ion")) + + if self._year >= 2016: + # Unification of the Romanian Principalities Day. + self._add_holiday_jan_24(tr("Ziua Unirii Principatelor Române")) + + # Easter. + name = tr("Paștele") + if self._year >= 2018: + self._add_good_friday(name) + + self._add_easter_sunday(name) + self._add_easter_monday(name) + + # Labor Day. + self._add_labor_day(tr("Ziua Muncii")) + + if self._year >= 2017: + # Children's Day. + self._add_childrens_day(tr("Ziua Copilului")) + + # Pentecost. + name = tr("Rusaliile") + self._add_whit_sunday(name) + self._add_whit_monday(name) + + # Law #202/2008 + if self._year >= 2009: + # Dormition of the Mother of God. + self._add_assumption_of_mary_day(tr("Adormirea Maicii Domnului")) + + # Law #147/2012 + if self._year >= 2012: + # Saint Andrew's Day. + self._add_holiday_nov_30(tr("Sfantul Apostol Andrei cel Intai chemat")) + + # National Day. + self._add_holiday_dec_1(tr("Ziua Națională a României")) + + # Christmas Day. + name = tr("Crăciunul") + self._add_christmas_day(name) + self._add_christmas_day_two(name) + + +class RO(Romania): + pass + + +class ROU(Romania): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/russia.py b/.venv/lib/python3.12/site-packages/holidays/countries/russia.py new file mode 100644 index 00000000..2348606a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/russia.py @@ -0,0 +1,525 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, NOV, DEC +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase + + +class Russia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Russia holidays. + + References: + * + * + """ + + country = "RU" + default_language = "ru" + supported_languages = ("en_US", "ru", "th") + start_year = 1991 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, RussiaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year <= 2004: + # New Year's Day. + name = tr("Новый год") + self._add_new_years_day(name) + if self._year >= 1993: + self._add_new_years_day_two(name) + else: + # New Year Holidays. + name = tr("Новогодние каникулы") + for day in range(1, 6): + self._add_holiday(name, JAN, day) + if self._year >= 2013: + self._add_holiday_jan_6(name) + self._add_holiday_jan_8(name) + + # Christmas Day. + self._add_christmas_day(tr("Рождество Христово")) + + if self._year >= 2002: + # Defender of the Fatherland Day. + self._add_holiday_feb_23(tr("День защитника Отечества")) + + # International Women's Day. + self._add_womens_day(tr("Международный женский день")) + + name = ( + # Holiday of Spring and Labor. + tr("Праздник Весны и Труда") + if self._year >= 1992 + # International Workers' Solidarity Day. + else tr("День международной солидарности трудящихся") + ) + self._add_labor_day(name) + if self._year <= 2004: + self._add_labor_day_two(name) + + # Victory Day. + self._add_world_war_two_victory_day(tr("День Победы"), is_western=False) + + if self._year >= 1992: + self._add_holiday_jun_12( + # Russia Day. + tr("День России") + if self._year >= 2002 + # Day of the Adoption of the Declaration of Sovereignty of the Russian Federation. + else tr( + "День принятия Декларации о государственном суверенитете Российской Федерации" + ) + ) + + if self._year >= 2005: + # Unity Day. + self._add_holiday_nov_4(tr("День народного единства")) + + if self._year <= 2004: + name = ( + # Day of consent and reconciliation. + tr("День согласия и примирения") + if self._year >= 1996 + # Anniversary of the Great October Socialist Revolution. + else tr("Годовщина Великой Октябрьской социалистической революции") + ) + self._add_holiday_nov_7(name) + if self._year <= 1991: + self._add_holiday_nov_8(name) + + +class RU(Russia): + pass + + +class RUS(Russia): + pass + + +class RussiaStaticHolidays: + # Date format (see strftime() Format Codes). + substituted_date_format = tr("%d.%m.%Y") + # Day off (substituted from %s). + substituted_label = tr("Выходной (перенесено с %s)") + + special_public_holidays = { + # Substituted Holidays 1991 + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1991: ( + (MAY, 3, MAY, 5), + (MAY, 10, MAY, 12), + ), + # Substituted Holidays 1994 + # src: https://web.archive.org/web/20250414071308/https://www.consultant.ru/document/cons_doc_LAW_3235/ + 1994: (MAR, 7, MAR, 5), + # Substituted Holidays 1995 + # src: https://web.archive.org/web/20250414071446/https://www.consultant.ru/document/cons_doc_LAW_6316/ + # https://web.archive.org/web/20250414071453/https://www.consultant.ru/document/cons_doc_LAW_8134/ + # https://web.archive.org/web/20250414071503/https://www.consultant.ru/document/cons_doc_LAW_8499/ + 1995: ( + (MAY, 8, MAY, 6), + (NOV, 6, NOV, 4), + (DEC, 11, DEC, 9), + ), + # Substituted Holidays 1996 + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1996: ( + (MAY, 3, MAY, 5), + (MAY, 10, MAY, 12), + (JUL, 3, DEC, 14), + (NOV, 8, NOV, 10), + (DEC, 13, DEC, 15), + ), + # Substituted Holidays 1997 + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1997: ( + (JAN, 3, JAN, 5), + (JUN, 13, JUN, 15), + ), + # Substituted Holidays 1999 + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1999: (JAN, 8, JAN, 10), + # Substituted Holidays 2000 + # src: https://web.archive.org/web/20250414071351/https://www.consultant.ru/document/cons_doc_LAW_25401/ + 2000: ( + (MAY, 8, MAY, 6), + (NOV, 6, NOV, 4), + (DEC, 11, DEC, 9), + ), + # Substituted Holidays 2001 + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2001: ( + (MAR, 9, MAR, 11), + (APR, 30, APR, 28), + (JUN, 11, JUN, 9), + (DEC, 31, DEC, 29), + ), + # Substituted Holidays 2002 + # src: https://web.archive.org/web/20240919074957/https://www.consultant.ru/document/cons_doc_LAW_33943/ + 2002: ( + (MAY, 3, APR, 27), + (MAY, 10, MAY, 18), + (NOV, 8, NOV, 10), + (DEC, 13, DEC, 15), + ), + # Substituted Holidays 2003 + # src: https://web.archive.org/web/20190220082540/http://www.consultant.ru:80/document/cons_doc_LAW_39997/16abd0212dcc02f64a1daed24286d2ffc2a4a9e9 + 2003: ( + (JAN, 3, JAN, 4), + (JAN, 6, JAN, 5), + (JUN, 13, JUN, 21), + ), + # Substituted Holidays 2005 + # src: https://web.archive.org/web/20250414071549/https://www.consultant.ru/document/cons_doc_LAW_50948/ + # https://ru.wikipedia.org/wiki/Праздники_России + 2005: ( + (MAR, 7, MAR, 5), + (MAY, 10, MAY, 14), + ), + # Substituted Holidays 2006 + # src: https://web.archive.org/web/20250418072310/https://www.consultant.ru/document/cons_doc_LAW_57425/ + 2006: ( + (FEB, 24, FEB, 26), + (MAY, 8, MAY, 6), + ), + # Substituted Holidays 2007 + # src: https://web.archive.org/web/20250414071613/https://www.consultant.ru/document/cons_doc_LAW_63838/ + 2007: ( + (APR, 30, APR, 28), + (JUN, 11, JUN, 9), + (DEC, 31, DEC, 29), + ), + # Substituted Holidays 2008 + # src: https://web.archive.org/web/20250420141031/https://www.consultant.ru/document/cons_doc_LAW_70469/ + 2008: ( + (MAY, 2, MAY, 4), + (JUN, 13, JUN, 7), + (NOV, 3, NOV, 1), + ), + # Substituted Holidays 2009 + # src: https://web.archive.org/web/20250418041918/https://www.consultant.ru/document/cons_doc_LAW_81981/ + 2009: (JAN, 9, JAN, 11), + # Substituted Holidays 2010 + # src: https://web.archive.org/web/20250419192633/https://www.consultant.ru/document/cons_doc_LAW_93374/ + 2010: ( + (FEB, 22, FEB, 27), + (NOV, 5, NOV, 13), + ), + # Substituted Holidays 2011 + # src: https://web.archive.org/web/20250416021056/https://www.consultant.ru/document/cons_doc_LAW_103530/ + 2011: (MAR, 7, MAR, 5), + # Substituted Holidays 2012 + # src: https://web.archive.org/web/20250420053252/https://www.consultant.ru/document/cons_doc_LAW_117190/ + 2012: ( + (MAR, 9, MAR, 11), + (APR, 30, APR, 28), + (MAY, 7, MAY, 5), + (MAY, 8, MAY, 12), + (JUN, 11, JUN, 9), + (DEC, 31, DEC, 29), + ), + # Substituted Holidays 2013 + # src: https://web.archive.org/web/20250422040920/https://www.consultant.ru/document/cons_doc_LAW_136654/ + 2013: ( + (MAY, 2, JAN, 5), + (MAY, 3, JAN, 6), + (MAY, 10, FEB, 25), + ), + # Substituted Holidays 2014 + # src: https://web.archive.org/web/20250415234224/https://www.consultant.ru/document/cons_doc_LAW_146983/ + 2014: ( + (MAY, 2, JAN, 4), + (JUN, 13, JAN, 5), + (NOV, 3, FEB, 24), + ), + # Substituted Holidays 2015 + # src: https://web.archive.org/web/20250415134053/https://www.consultant.ru/document/cons_doc_LAW_167928/ + 2015: ( + (JAN, 9, JAN, 3), + (MAY, 4, JAN, 4), + ), + # Substituted Holidays 2016 + # src: https://web.archive.org/web/20250417021701/https://www.consultant.ru/document/cons_doc_LAW_186505/ + 2016: ( + (MAY, 3, JAN, 2), + (MAR, 7, JAN, 3), + (FEB, 22, FEB, 20), + ), + # Substituted Holidays 2017 + # src: https://web.archive.org/web/20250414184011/https://www.consultant.ru/document/cons_doc_LAW_202871/ + 2017: ( + (FEB, 24, JAN, 1), + (MAY, 8, JAN, 7), + ), + # Substituted Holidays 2018 + # src: https://web.archive.org/web/20250414223644/https://www.consultant.ru/document/cons_doc_LAW_280526/ + 2018: ( + (MAR, 9, JAN, 6), + (MAY, 2, JAN, 7), + (APR, 30, APR, 28), + (JUN, 11, JUN, 9), + (DEC, 31, DEC, 29), + ), + # Substituted Holidays 2019 + # src: https://web.archive.org/web/20250414103842/https://www.consultant.ru/document/cons_doc_LAW_307996/ + 2019: ( + (MAY, 2, JAN, 5), + (MAY, 3, JAN, 6), + (MAY, 10, FEB, 23), + ), + # Substituted Holidays 2020 + # src: https://web.archive.org/web/20250414071714/https://www.consultant.ru/document/cons_doc_law_328918/ + 2020: ( + (MAY, 4, JAN, 4), + (MAY, 5, JAN, 5), + ), + # Substituted Holidays 2021 + # src: https://web.archive.org/web/20250414071843/https://www.consultant.ru/document/cons_doc_law_365179/ + 2021: ( + (NOV, 5, JAN, 2), + (DEC, 31, JAN, 3), + (FEB, 22, FEB, 20), + ), + # Substituted Holidays 2022 + # src: https://web.archive.org/web/20240613213507/https://www.consultant.ru/document/cons_doc_LAW_395538/ + 2022: ( + (MAY, 3, JAN, 1), + (MAY, 10, JAN, 2), + (MAR, 7, MAR, 5), + ), + # Substituted Holidays 2023 + # src: https://web.archive.org/web/20240908190857/https://www.consultant.ru/document/cons_doc_LAW_425407/ + 2023: ( + (FEB, 24, JAN, 1), + (MAY, 8, JAN, 8), + ), + # Substituted Holidays 2024 + # src: https://web.archive.org/web/20250417024116/https://www.consultant.ru/document/cons_doc_LAW_455140/ + 2024: ( + (APR, 29, APR, 27), + (APR, 30, NOV, 2), + (MAY, 10, JAN, 6), + (DEC, 30, DEC, 28), + (DEC, 31, JAN, 7), + ), + # Substituted Holidays 2025 + # src: https://web.archive.org/web/20250414071812/https://www.consultant.ru/document/cons_doc_LAW_481586/ + 2025: ( + (MAY, 2, JAN, 4), + (DEC, 31, JAN, 5), + (MAY, 8, FEB, 23), + (JUN, 13, MAR, 8), + (NOV, 3, NOV, 1), + ), + } + special_public_holidays_observed = { + # These are cases where additional in-lieus are given + # without actually making weekend workdays. + # Substituted Holidays 1992 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1992: ( + (MAY, 4, MAY, 2), + (MAY, 11, MAY, 9), + (NOV, 9, NOV, 7), + ), + # Substituted Holidays 1993 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1993: ( + (JAN, 4, JAN, 2), + (MAY, 3, MAY, 1), + (MAY, 4, MAY, 2), + (MAY, 10, MAY, 9), + (JUN, 14, JUN, 12), + (NOV, 8, NOV, 7), + ), + # Substituted Holidays 1994 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1994: ( + (JAN, 3, JAN, 1), + (JAN, 4, JAN, 2), + (MAY, 3, MAY, 1), + (MAY, 10, MAY, 9), + (JUN, 13, JUN, 12), + ), + # Substituted Holidays 1995 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1995: ( + (JAN, 3, JAN, 1), + (JAN, 9, JAN, 7), + ), + # Substituted Holidays 1996 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1996: (JAN, 8, JAN, 7), + # Substituted Holidays 1997 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1997: (MAR, 10, MAR, 8), + # Substituted Holidays 1998 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1998: ( + (MAR, 9, MAR, 8), + (MAY, 4, MAY, 2), + (MAY, 11, MAY, 9), + (NOV, 9, NOV, 7), + (DEC, 14, DEC, 12), + ), + # Substituted Holidays 1999 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 1999: ( + (JAN, 4, JAN, 2), + (MAY, 3, MAY, 1), + (MAY, 4, MAY, 2), + (MAY, 10, MAY, 9), + (JUN, 14, JUN, 12), + (NOV, 8, NOV, 7), + (DEC, 13, DEC, 12), + ), + # Substituted Holidays 2000 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2000: ( + (JAN, 3, JAN, 1), + (JAN, 4, JAN, 2), + ), + # Substituted Holidays 2001 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2001: (JAN, 8, JAN, 7), + # Substituted Holidays 2002 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2002: (FEB, 25, FEB, 23), + # Substituted Holidays 2003 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2003: ( + (FEB, 24, FEB, 23), + (MAR, 10, MAR, 8), + ), + # Substituted Holidays 2004 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2004: ( + (MAY, 3, MAY, 1), + (MAY, 4, MAY, 2), + (MAY, 10, MAY, 9), + (JUN, 14, JUN, 12), + (NOV, 8, NOV, 7), + (DEC, 13, DEC, 12), + ), + # Substituted Holidays 2005 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2005: ( + (JAN, 6, JAN, 1), + (JAN, 10, JAN, 2), + (MAY, 2, MAY, 1), + (JUN, 13, JUN, 12), + ), + # Substituted Holidays 2006 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2006: ( + (JAN, 6, JAN, 1), + (JAN, 9, JAN, 7), + (NOV, 6, NOV, 4), + ), + # Substituted Holidays 2007 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2007: ( + (JAN, 8, JAN, 7), + (NOV, 5, NOV, 4), + ), + # Substituted Holidays 2008 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2008: ( + (JAN, 8, JAN, 5), + (FEB, 25, FEB, 23), + (MAR, 10, MAR, 8), + ), + # Substituted Holidays 2009 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2009: ( + (JAN, 6, JAN, 3), + (JAN, 8, JAN, 4), + (MAR, 9, MAR, 8), + (MAY, 11, MAY, 9), + ), + # Substituted Holidays 2010 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2010: ( + (JAN, 6, JAN, 2), + (JAN, 8, JAN, 3), + (MAY, 3, MAY, 1), + (MAY, 10, MAY, 9), + (JUN, 14, JUN, 12), + ), + # Substituted Holidays 2011 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2011: ( + (JAN, 6, JAN, 1), + (JAN, 10, JAN, 2), + (MAY, 2, MAY, 1), + (JUN, 13, JUN, 12), + ), + # Substituted Holidays 2012 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2012: ( + (JAN, 6, JAN, 1), + (JAN, 9, JAN, 7), + (NOV, 5, NOV, 4), + ), + # Substituted Holidays 2014 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2014: (MAR, 10, MAR, 8), + # Substituted Holidays 2015 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2015: ( + (MAR, 9, MAR, 8), + (MAY, 11, MAY, 9), + ), + # Substituted Holidays 2016 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2016: ( + (MAY, 2, MAY, 1), + (JUN, 13, JUN, 12), + ), + # Substituted Holidays 2017 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2017: (NOV, 6, NOV, 4), + # Substituted Holidays 2018 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2018: (NOV, 5, NOV, 4), + # Substituted Holidays 2020 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2020: ( + (FEB, 24, FEB, 23), + (MAR, 9, MAR, 8), + (MAY, 11, MAY, 9), + ), + # Substituted Holidays 2021 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2021: ( + (MAY, 3, MAY, 1), + (MAY, 10, MAY, 9), + (JUN, 14, JUN, 12), + ), + # Substituted Holidays 2022 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2022: ( + (MAY, 2, MAY, 1), + (JUN, 13, JUN, 12), + ), + # Substituted Holidays 2023 (observed) + # src: https://ru.wikipedia.org/wiki/Праздники_России + 2023: (NOV, 6, NOV, 4), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/saint_barthelemy.py b/.venv/lib/python3.12/site-packages/holidays/countries/saint_barthelemy.py new file mode 100644 index 00000000..34618753 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/saint_barthelemy.py @@ -0,0 +1,43 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysBL(ChildEntity, France): + """Saint Barthélemy holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "BL" + parent_entity = France + # Cession from Guadeloupe on July 15th, 2007. + start_year = 2008 + + +class SaintBarthelemy(HolidaysBL): + pass + + +class BL(HolidaysBL): + pass + + +class BLM(HolidaysBL): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/saint_kitts_and_nevis.py b/.venv/lib/python3.12/site-packages/holidays/countries/saint_kitts_and_nevis.py new file mode 100644 index 00000000..3029d616 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/saint_kitts_and_nevis.py @@ -0,0 +1,183 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import FEB, MAR, APR, JUL, AUG, SEP, DEC, SUN +from holidays.constants import HALF_DAY, PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class SaintKittsAndNevis( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """Saint Kitts and Nevis holidays. + + References: + * + * + * + + Cross-Checked With: + * + * + + If Sovereign's Birthday, New Year's Day, Independence Day, or National Heroes Day + fall on a Sunday the next following Monday shall be a public holiday. + + Boxing Day—that is the day after Christmas Day, but if Christmas Day falls + on a Saturday, then the next following Monday shall be a public holiday, and if + Christmas Day falls on a Sunday, then the next following Monday and Tuesday + shall be public holidays. + + While Culturama Day (first started in 1974) and Carnival Day are never officially + included in the main Chapter 23.23 document, they're de facto added since at least + 2015 and should be considered as such. + """ + + country = "KN" + supported_categories = (HALF_DAY, PUBLIC, WORKDAY) + # %s (observed). + observed_label = "%s (observed)" + weekend = {SUN} + # Public Holidays Act, Act 7 of 1983 Amendment. + start_year = 1983 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, SaintKittsAndNevisStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Carnival Day. + self._add_observed(self._add_new_years_day("Carnival Day"), rule=SUN_TO_NEXT_TUE) + + # Carnival Day - Last Lap. + self._add_observed(self._add_new_years_day_two("Carnival Day - Last Lap")) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Labour Day. + self._add_holiday_1st_mon_of_may("Labour Day") + + # While Sovereign's Birthday is officially listed in the Public Holidays Act, + # this was de facto never included in any released calendar since at least 2015. + + # Whit Monday. + self._add_whit_monday("Whit Monday") + + self._add_holiday_1st_mon_of_aug( + # Emancipation Day. + "Emancipation Day" + if self._year >= 1998 + # First Monday of August. + else "First Monday of August" + ) + + # Culturama Day - Last Lap. + self._add_holiday_1_day_past_1st_mon_of_aug("Culturama Day - Last Lap") + + if self._year >= 1998: + # National Heroes Day. + self._add_observed(self._add_holiday_sep_16("National Heroes Day")) + + # Independence Day. + self._add_observed(self._add_holiday_sep_19("Independence Day")) + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two("Boxing Day")) + + def _populate_workday_holidays(self): + # August 25 was declared Kim Collins Day by the government of St. Kitts and Nevis + # in honour of one of the track star's most significant accomplishments, the gold + # at the World Championships in Paris, France in 2003. + if self._year >= 2003: + # Kim Collins Day. + self._add_holiday_aug_25("Kim Collins Day") + + +class KN(SaintKittsAndNevis): + pass + + +class KNA(SaintKittsAndNevis): + pass + + +class SaintKittsAndNevisStaticHolidays: + """Saint Kitts and Nevis special holidays. + + References: + * + * + * + * + * + * + * + * + * + * + * + * + * + """ + + # Federal Election Victory Day. + federal_election_victory_day_name = "Federal Election Victory Day" + + # Children's Carnival Day. + childrens_carnival_day_name = "Children's Carnival Day" + + special_public_holidays = { + 2015: (FEB, 18, federal_election_victory_day_name), + 2017: ( + # National Clean Up Day. + (SEP, 20, "National Clean Up Day"), + # Local Election Victory Day. + (DEC, 19, "Local Election Victory Day"), + ), + 2022: (AUG, 8, federal_election_victory_day_name), + # 50th Anniversary of the Establishment of the Caribbean Community (CARICOM). + 2023: ( + JUL, + 4, + "50th Anniversary of the Establishment of the Caribbean Community (CARICOM)", + ), + } + special_half_day_holidays = { + 2017: ( + # The Passing of His Excellency Sir Probyn Inniss. + (MAR, 23, "The Passing of His Excellency Sir Probyn Inniss"), + # The Passing of His Excellency Sir Cuthbert Sebastian. + (APR, 10, "The Passing of His Excellency Sir Cuthbert Sebastian"), + ), + 2018: (DEC, 31, childrens_carnival_day_name), + 2019: (DEC, 31, childrens_carnival_day_name), + # 2022 Gulf Insurance Inter-Primary Schools Championship. + 2022: (APR, 27, "2022 Gulf Insurance Inter-Primary Schools Championship"), + 2023: ( + # The Passing of His Excellency Sir Tapley Seaton. + (JUL, 20, "The Passing of His Excellency Sir Tapley Seaton"), + (DEC, 30, childrens_carnival_day_name), + ), + # Junior Cultural Street Parade. + 2024: (AUG, 1, "Junior Cultural Street Parade"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/saint_lucia.py b/.venv/lib/python3.12/site-packages/holidays/countries/saint_lucia.py new file mode 100644 index 00000000..7dacdd45 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/saint_lucia.py @@ -0,0 +1,89 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class SaintLucia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Saint Lucia holidays. + + References: + * + * + * + * + * + """ + + country = "LC" + default_language = "en_LC" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_LC", "en_US") + start_year = 1979 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day")), rule=SUN_TO_NEXT_TUE) + + # New Year's Holiday. + self._add_observed(self._add_new_years_day_two(tr("New Year's Holiday"))) + + # Independence Day. + self._add_observed(self._add_holiday_feb_22(tr("Independence Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Labour Day"))) + + # Whit Monday. + self._add_whit_monday(tr("Whit Monday")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + # Emancipation Day. + self._add_observed(self._add_holiday_aug_1(tr("Emancipation Day"))) + + # Thanksgiving Day. + self._add_holiday_1st_mon_of_oct(tr("Thanksgiving Day")) + + # National Day. + self._add_observed(self._add_holiday_dec_13(tr("National Day"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day")), rule=SUN_TO_NEXT_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two(tr("Boxing Day"))) + + +class LC(SaintLucia): + pass + + +class LCA(SaintLucia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/saint_martin.py b/.venv/lib/python3.12/site-packages/holidays/countries/saint_martin.py new file mode 100644 index 00000000..1f351a5a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/saint_martin.py @@ -0,0 +1,43 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysMF(ChildEntity, France): + """Saint Martin holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "MF" + parent_entity = France + # Cession from Guadeloupe on July 15th, 2007. + start_year = 2008 + + +class SaintMartin(HolidaysMF): + pass + + +class MF(HolidaysMF): + pass + + +class MAF(HolidaysMF): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/saint_pierre_and_miquelon.py b/.venv/lib/python3.12/site-packages/holidays/countries/saint_pierre_and_miquelon.py new file mode 100644 index 00000000..cd647fae --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/saint_pierre_and_miquelon.py @@ -0,0 +1,43 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysPM(ChildEntity, France): + """Saint Pierre and Miquelon holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "PM" + parent_entity = France + # Cession from the UK on May 30th, 1814. + start_year = 1815 + + +class SaintPierreAndMiquelon(HolidaysPM): + pass + + +class PM(HolidaysPM): + pass + + +class SPM(HolidaysPM): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/saint_vincent_and_the_grenadines.py b/.venv/lib/python3.12/site-packages/holidays/countries/saint_vincent_and_the_grenadines.py new file mode 100644 index 00000000..138d71a3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/saint_vincent_and_the_grenadines.py @@ -0,0 +1,130 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, JUL, AUG, SEP, _timedelta +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class SaintVincentAndTheGrenadines( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """Saint Vincent and the Grenadines holidays. + + References: + * + * [2013](https://web.archive.org/web/20240225145904/https://www.bosvg.com/wp-content/uploads/2021/10/bosvg_calendar2013-9x12_ver2-2.pdf) + * [2014](https://web.archive.org/web/20250610053913/https://www.bosvg.com/wp-content/uploads/2021/10/BOSVG-Calendar-2014-5th-draft.pdf) + * [2015](https://web.archive.org/web/20240225145904/https://www.bosvg.com/wp-content/uploads/2021/10/BOSVG-Bklet-Calendar-2015_21_11-3.pdf) + * [2016](https://web.archive.org/web/20240225145903/https://www.bosvg.com/wp-content/uploads/2021/10/BOSVG-2016_pgs_sm_fin.pdf) + * [2022](https://web.archive.org/web/20230426000952/https://www.bosvg.com/wp-content/uploads/2022/05/Tent-Calendar.pdf) + * [2023](https://web.archive.org/web/20240225145904/https://www.bosvg.com/wp-content/uploads/2023/03/BOSVG-CALENDAR-TENT_F_REPRINT_TENT-EXCLUDED-FINAL.pdf) + * [2019-2025](https://web.archive.org/web/20250214232128/https://pmoffice.gov.vc/pmoffice/index.php/public-holidays) + * [2020 Carnival Monday](https://web.archive.org/web/20250607111242/https://www.stvincenttimes.com/august-3rd-and-4th-2020-declared-public-holidays-in-svg/) + * [2025 National Spiritual Baptist Day](https://web.archive.org/web/20250513011200/https://www.gov.vc/images/pdf_documents/VINCENTIANS-PREPARE-FOR-MAY-21--SPIRITUAL-BAPTIST-LIBERATION-DAY-NATIONAL-HOLIDAY.pdf) + """ + + country = "VC" + default_language = "en_VC" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_US", "en_VC") + start_year = 1979 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=SaintVincentAndTheGrenadinesStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # National Heroes' Day. + self._add_observed(self._add_holiday_mar_14(tr("National Heroes' Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # National Workers' Day. + self._add_observed(self._add_labor_day(tr("National Workers' Day"))) + + if self._year >= 2025: + # National Spiritual Baptist Day. + self._add_holiday_may_21(tr("National Spiritual Baptist Day")) + + # Whit Monday. + self._add_whit_monday(tr("Whit Monday")) + + # Carnival Monday. + name = tr("Carnival Monday") + carnival_monday_dates = { + 2013: (JUL, 8), + 2018: (JUL, 9), + 2019: (JUL, 8), + 2020: (AUG, 3), + 2021: (SEP, 6), + 2023: (JUL, 10), + 2024: (JUL, 8), + } + dt = ( + self._add_holiday(name, dt) + if (dt := carnival_monday_dates.get(self._year)) + else self._add_holiday_1st_mon_of_jul(name) + ) + + # Carnival Tuesday. + self._add_holiday(tr("Carnival Tuesday"), _timedelta(dt, +1)) + + # Emancipation Day. + self._add_observed(self._add_holiday_aug_1(tr("Emancipation Day"))) + + # Independence Day. + self._add_observed(self._add_holiday_oct_27(tr("Independence Day"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day")), rule=SUN_TO_NEXT_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two(tr("Boxing Day"))) + + +class VC(SaintVincentAndTheGrenadines): + pass + + +class VCT(SaintVincentAndTheGrenadines): + pass + + +class SaintVincentAndTheGrenadinesStaticHolidays: + """Saint Vincent and the Grenadines special holidays. + + References: + * [Statutory Rules and Orders 2021 No.1](https://web.archive.org/web/20250613051716/https://pmoffice.gov.vc/pmoffice/images/PDF/Gazettes/No_1_Proclamation_Delcaring_Friday_the_22nd_and_Monday_25th_day_of_January_2021_to_be_Public_Holidays_in_Saint_Vincent_and_the_Grenadines_19th_January_2021.pdf) + """ + + # Public Health Holiday. + name = tr("Public Health Holiday") + special_public_holidays = { + 2021: ( + (JAN, 22, name), + (JAN, 25, name), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/samoa.py b/.venv/lib/python3.12/site-packages/holidays/countries/samoa.py new file mode 100644 index 00000000..9d2ca882 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/samoa.py @@ -0,0 +1,73 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Samoa(HolidayBase, ChristianHolidays, InternationalHolidays): + """Samoa holidays. + + References: + * + * + * + * + """ + + country = "WS" + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + + super().__init__(*args, **kwargs) + + def _populate(self, year): + super()._populate(year) + + # New Year's Day. + self._add_new_years_day("New Year's Day") + self._add_new_years_day_two("The Day After New Year's Day") + + # Good Friday. + self._add_good_friday("Good Friday") + self._add_holy_saturday("Day After Good Friday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Mother's Day. + self._add_holiday_1_day_past_2nd_sun_of_may("Mother's Day") + + # Independence Day. + self._add_holiday_jun_1("Independence Day") + + # Father's Day. + self._add_holiday_1_day_past_2nd_sun_of_aug("Father's Day") + + # White Monday (Lotu a Tamaiti). + self._add_holiday_1_day_past_2nd_sun_of_oct("White Sunday (Lotu a Tamaiti)") + + # Christmas Day. + self._add_christmas_day("Christmas Day") + + # Boxing Day. + self._add_christmas_day_two("Boxing Day") + + +class WS(Samoa): + pass + + +class WSM(Samoa): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/san_marino.py b/.venv/lib/python3.12/site-packages/holidays/countries/san_marino.py new file mode 100644 index 00000000..6d871452 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/san_marino.py @@ -0,0 +1,115 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.constants import BANK, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class SanMarino(HolidayBase, ChristianHolidays, InternationalHolidays): + """San Marino holidays. + + References: + * + * [Bank holiday calendar (Italian)](https://web.archive.org/web/20250627182751/https://www.bcsm.sm/funzioni/funzioni-statutarie/sistema-dei-pagamenti/calendario-festività) + * [Bank holiday calendar (English)](https://web.archive.org/web/20250627182741/https://www.bcsm.sm/en/functions/statutory-functions/payment-system/bank-holiday-calendar) + * [Law No. 7 of Feb. 17, 1961](https://web.archive.org/web/20250122105136/https://www.consigliograndeegenerale.sm/on-line/home/archivio-leggi-decreti-e-regolamenti/documento17018406.html) + """ + + country = "SM" + default_language = "it" + # Law No. 7 of Feb. 17, 1961. + start_year = 1962 + supported_categories = (BANK, PUBLIC) + supported_languages = ("en_US", "it", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self) -> None: + # New Year's Day. + self._add_new_years_day(tr("Capodanno")) + + # Epiphany. + self._add_epiphany_day(tr("Epifania")) + + self._add_holiday_feb_5( + # Anniversary of the Liberation of the Republic and Feast of Saint Agatha. + tr("Anniversario della Liberazione della Repubblica e Festa di Sant'Agata") + ) + + # Anniversary of the Arengo. + self._add_holiday_mar_25(tr("Anniversario dell'Arengo")) + + # Easter Sunday. + self._add_easter_sunday(tr("Pasqua")) + + # Easter Monday. + self._add_easter_monday(tr("Lunedì dell'angelo")) + + # Investiture of Captains Regent. + name = tr("Investitura Capitani Reggenti") + self._add_holiday_apr_1(name) + self._add_holiday_oct_1(name) + + # Workers' Day. + self._add_labor_day(tr("Festa dei lavoratori")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Domini")) + + self._add_holiday_jul_28( + # Anniversary of the Fall of Fascism and Freedom Day. + tr("Anniversario della Caduta del Fascismo e Festa della Libertà") + ) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assunzione della B.V. Maria")) + + self._add_holiday_sep_3( + # Saint Marinus' Day, Anniversary of the Founding of the Republic. + tr("San Marino, Anniversario di Fondazione della Repubblica") + ) + + # All Saints' Day. + self._add_all_saints_day(tr("Tutti i Santi")) + + # Commemoration of the Dead. + self._add_all_souls_day(tr("Commemorazione dei defunti")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Immacolata Concezione")) + + # Christmas Day. + self._add_christmas_day(tr("Natale")) + + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Santo Stefano")) + + def _populate_bank_holidays(self): + # Christmas Eve. + self._add_christmas_eve(tr("Vigilia di Natale")) + + # New Year's Eve. + self._add_new_years_eve(tr("Ultimo dell'anno")) + + +class SM(SanMarino): + pass + + +class SMR(SanMarino): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/sao_tome_and_principe.py b/.venv/lib/python3.12/site-packages/holidays/countries/sao_tome_and_principe.py new file mode 100644 index 00000000..7baa7819 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/sao_tome_and_principe.py @@ -0,0 +1,112 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_TO_PREV_FRI, SUN_TO_NEXT_MON + + +class SaoTomeAndPrincipe(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Sao Tome and Principe holidays. + + References: + * + * + * + * + """ + + country = "ST" + default_language = "pt_ST" + # %s (observed). + observed_label = tr("%s (observado)") + start_year = 2014 + subdivisions = ( + "01", # Água Grande. + "02", # Cantagalo. + "03", # Caué. + "04", # Lembá. + "05", # Lobata. + "06", # Mé-Zóchi. + "P", # Príncipe. + ) + subdivisions_aliases = { + # Districts. + "Água Grande": "01", + "Cantagalo": "02", + "Caué": "03", + "Lembá": "04", + "Lobata": "05", + "Mé-Zóchi": "06", + # Autonomous Region. + "Príncipe": "P", + } + supported_languages = ("en_US", "pt_ST") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON + SAT_TO_PREV_FRI) + # Holidays are observed on the next Monday if on Sunday, or previous Friday if on Saturday. + # Based on common government practices since at least 2020. + kwargs.setdefault("observed_since", 2020) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Ano Novo") + self._add_observed(self._add_new_years_day(name)) + self._add_observed(self._next_year_new_years_day, name=name, rule=SAT_TO_PREV_FRI) + + # Day of King Amador. + self._add_observed(self._add_holiday_jan_4(tr("Dia do Rei Amador"))) + + # Martyrs' Day. + self._add_observed(self._add_holiday_feb_3(tr("Dia dos Mártires"))) + + # Worker's Day. + self._add_observed(self._add_labor_day(tr("Dia do Trabalhador"))) + + # Independence Day. + self._add_observed(self._add_holiday_jul_12(tr("Dia da Independência"))) + + # Armed Forces Day. + self._add_observed(self._add_holiday_sep_6(tr("Dia das Forças Armadas"))) + + # Agricultural Reform Day. + self._add_observed(self._add_holiday_sep_30(tr("Dia da Reforma Agrária"))) + + if self._year >= 2019: + # São Tomé Day. + self._add_observed(self._add_holiday_dec_21(tr("Dia de São Tomé"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Natal"))) + + def _populate_subdiv_p_public_holidays(self): + # Discovery of Príncipe Island. + self._add_observed(self._add_holiday_jan_17(tr("Descobrimento da Ilha do Príncipe"))) + + # Autonomy Day. + self._add_observed(self._add_holiday_apr_29(tr("Dia da Autonomia do Príncipe"))) + + # São Lourenço Day. + self._add_observed(self._add_holiday_aug_15(tr("Dia de São Lourenço"))) + + +class ST(SaoTomeAndPrincipe): + pass + + +class STP(SaoTomeAndPrincipe): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/saudi_arabia.py b/.venv/lib/python3.12/site-packages/holidays/countries/saudi_arabia.py new file mode 100644 index 00000000..1ee17499 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/saudi_arabia.py @@ -0,0 +1,129 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, FEB, SEP, NOV, THU, FRI, SAT, _timedelta +from holidays.groups import IslamicHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + THU_TO_PREV_WED, + FRI_TO_PREV_THU, + FRI_TO_NEXT_SAT, + SAT_TO_NEXT_SUN, + THU_FRI_TO_NEXT_WORKDAY, + FRI_SAT_TO_NEXT_WORKDAY, +) + + +class SaudiArabia(ObservedHolidayBase, IslamicHolidays, StaticHolidays): + """Saudi Arabia holidays. + + References: + * + * + * + """ + + country = "SA" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + # %s (observed). + observed_label = tr("%s (ملاحظة)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (المقدرة، ملاحظة)") + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + StaticHolidays.__init__(self, SaudiArabiaStaticHolidays) + kwargs.setdefault("observed_rule", FRI_TO_PREV_THU + SAT_TO_NEXT_SUN) + super().__init__(*args, **kwargs) + + def _add_islamic_observed(self, dts: set[date]) -> None: + # Observed days are added to make up for any days falling on a weekend. + if not self.observed: + return None + observed_rule = THU_FRI_TO_NEXT_WORKDAY if self._year <= 2012 else FRI_SAT_TO_NEXT_WORKDAY + for dt in dts: + for i in range(4): + self._add_observed(_timedelta(dt, -i), name=self[dt], rule=observed_rule) + + def _populate_public_holidays(self): + # Weekend used to be THU, FRI before June 28th, 2013. + # On that year both Eids were after that date, and Founding day + # holiday started at 2022; so what below works. + self._observed_rule = ( + THU_TO_PREV_WED + FRI_TO_NEXT_SAT + if self._year <= 2012 + else FRI_TO_PREV_THU + SAT_TO_NEXT_SUN + ) + self.weekend = {THU, FRI} if self._year <= 2012 else {FRI, SAT} + + # Eid al-Fitr Holiday + eid_al_fitr_name = tr("عطلة عيد الفطر") + self._add_eid_al_fitr_day(eid_al_fitr_name) + self._add_eid_al_fitr_day_two(eid_al_fitr_name) + self._add_eid_al_fitr_day_three(eid_al_fitr_name) + self._add_islamic_observed(self._add_eid_al_fitr_day_four(eid_al_fitr_name)) + + # Arafat Day + self._add_arafah_day(tr("يوم عرفة")) + # Eid al-Adha Holiday + name = tr("عطلة عيد الأضحى") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_islamic_observed(self._add_eid_al_adha_day_three(name)) + + # If National Day happens within the Eid al-Fitr Holiday or + # Eid al-Adha Holiday, there is no extra holidays given for it. + if self._year >= 2005: + dt = date(self._year, SEP, 23) + if dt not in self: + # National Day Holiday + self._add_observed(self._add_holiday(tr("اليوم الوطني"), dt)) + + # If Founding Day happens within the Eid al-Fitr Holiday or + # Eid al-Adha Holiday, there is no extra holidays given for it. + if self._year >= 2022: + dt = date(self._year, FEB, 22) + if dt not in self: + # Founding Day + self._add_observed(self._add_holiday(tr("يوم التأسيسي"), dt)) + + +class SA(SaudiArabia): + pass + + +class SAU(SaudiArabia): + pass + + +class SaudiArabiaStaticHolidays: + special_public_holidays = { + # Celebrate the country's win against Argentina in the World Cup + 2022: (NOV, 23, tr("يوم وطني")), + } + + special_public_holidays_observed = { + # Eid al-Fitr Holiday + 2001: (JAN, 1, tr("عطلة عيد الفطر")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/senegal.py b/.venv/lib/python3.12/site-packages/holidays/countries/senegal.py new file mode 100644 index 00000000..3c1f2324 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/senegal.py @@ -0,0 +1,193 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, DEC +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Senegal( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Senegal holidays. + References: + * + * [Law 63-51](https://web.archive.org/web/20250604134724/https://www.dri.gouv.sn/sites/default/files/LOI/1963/63_51.pdf) + * [Law 74-52](https://web.archive.org/web/20250608105243/https://www.dri.gouv.sn/sites/default/files/an-documents/LOI%20N1974%2052%20DU%204%20NOVEMBRE%201974.pdf) + * [Law 83-54](https://web.archive.org/web/20250608105419/https://www.dri.gouv.sn/sites/default/files/LOI/1983/comP4%20loi%20decentralisation%20et%20travail/LOI%20N%20198354%20DU%2018%20FEVRIER%201983/LOI%20N%20198354%20DU%2018%20FEVRIER%201983.pdf) + * [Law 2013-06](https://web.archive.org/web/20250604215148/https://natlex.ilo.org/dyn/natlex2/natlex2/files/download/97261/SEN-97261.pdf) + """ + + country = "SN" + default_language = "fr_SN" + # %s (estimated). + estimated_label = tr("%s (estimé)") + # %s (observed). + observed_label = tr("%s (observé)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observé, estimé)") + # First official source with holidays dates (Law 63-51). + start_year = 1964 + supported_languages = ("en_US", "fr_SN") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=SenegalIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, SenegalStaticHolidays) + # Law 74-52. + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1975) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year >= 1983: + # Ashura. + self._add_ashura_day(tr("Tamxarit")) + + if self._year >= 2014: + # Grand Magal of Touba. + self._add_grand_magal_of_touba(tr("Grand Magal de Touba")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("Journée du Maouloud")) + + # Eid al-Fitr. + for dt in self._add_eid_al_fitr_day(tr("Journée de la Korité")): + self._add_observed(dt) + + # Eid al-Adha. + for dt in self._add_eid_al_adha_day(tr("Journée de la Tabaski")): + self._add_observed(dt) + + # New Year's Day. + self._add_new_years_day(tr("Jour de l'an")) + + if 1983 <= self._year <= 1989: + # Senegambia Confederation Day. + self._add_holiday_feb_1(tr("Fête de la Confédération de la Sénégambie")) + + # Independence Day. + name = tr("Fête de l'Indépendance") + if self._year >= 1975: + self._add_holiday_apr_4(name) + else: + self._add_holiday_jul_14(name) + + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + # Labor Day. + self._add_labor_day(tr("Fête du Travail")) + + # Ascension Day. + self._add_ascension_thursday(tr("Jeudi de l'Ascension")) + + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Assomption")) + + # All Saints' Day. + self._add_all_saints_day(tr("Toussaint")) + + # Christmas Day. + self._add_christmas_day(tr("Noël")) + + +class SN(Senegal): + pass + + +class SEN(Senegal): + pass + + +class SenegalIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20250609044648/https://www.timeanddate.com/holidays/senegal/tamkharit + ASHURA_DATES = { + 2020: (AUG, 29), + 2021: (AUG, 18), + 2022: (AUG, 8), + 2023: (JUL, 28), + 2024: (JUL, 17), + } + + # https://web.archive.org/web/20250609061446/https://www.timeanddate.com/holidays/senegal/grand-magal-de-touba + GRAND_MAGAL_OF_TOUBA_DATES = { + 2020: (OCT, 6), + 2021: (SEP, 26), + 2022: (SEP, 15), + 2023: (SEP, 4), + 2024: (AUG, 23), + } + + # https://web.archive.org/web/20250609091559/https://www.timeanddate.com/holidays/senegal/maouloud + MAWLID_DATES = { + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 15), + } + + # https://web.archive.org/web/20250609092813/https://www.timeanddate.com/holidays/senegal/korite + EID_AL_FITR_DATES = { + 2020: (MAY, 24), + 2021: (MAY, 12), + 2022: (MAY, 1), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + # https://web.archive.org/web/20250609102658/https://www.timeanddate.com/holidays/senegal/tabaski + EID_AL_ADHA_DATES = { + 2020: (JUL, 31), + 2021: (JUL, 21), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + } + + +class SenegalStaticHolidays: + """Senegal special holidays. + + References: + * [29th October, 2018 Public holiday](https://web.archive.org/web/20250608105852/https://www.juriafrica.com/lex/decret-2018-1942-26-octobre-2018-48947.htm) + * [26th December, 2022 Public holiday](https://web.archive.org/web/20250608135605/https://primature.sn/publications/conseil-des-ministres/conseil-des-ministres-du-22-decembre-2022) + """ + + # Public holiday. + name = tr("Jour férié") + special_public_holidays = { + 2018: (OCT, 29, name), + 2022: (DEC, 26, name), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/serbia.py b/.venv/lib/python3.12/site-packages/holidays/countries/serbia.py new file mode 100644 index 00000000..b495cd17 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/serbia.py @@ -0,0 +1,80 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class Serbia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Serbia holidays. + + References: + * + """ + + country = "RS" + default_language = "sr" + # %s (observed). + observed_label = tr("%s (слободан дан)") + supported_languages = ("en_US", "sr") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_CALENDAR) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = tr("Нова година") + self._add_observed(self._add_new_years_day(name), rule=SUN_TO_NEXT_TUE) + self._add_observed(self._add_new_years_day_two(name)) + + # Orthodox Christmas Day. + self._add_christmas_day(tr("Божић")) + + # Statehood Day. + name = tr("Дан државности Србије") + self._add_observed(self._add_holiday_feb_15(name), rule=SUN_TO_NEXT_TUE) + self._add_observed(self._add_holiday_feb_16(name)) + + # Labor Day. + name = tr("Празник рада") + self._add_observed(self._add_labor_day(name), rule=SUN_TO_NEXT_TUE) + + self._add_observed( + may_2 := self._add_labor_day_two(name), + rule=SUN_TO_NEXT_TUE if may_2 == self._easter_sunday else SUN_TO_NEXT_MON, + ) + + # Armistice Day. + self._add_observed(self._add_remembrance_day(tr("Дан примирја у Првом светском рату"))) + + # Good Friday. + self._add_good_friday(tr("Велики петак")) + # Holy Saturday. + self._add_holy_saturday(tr("Велика субота")) + # Easter Sunday. + self._add_easter_sunday(tr("Васкрс")) + # Easter Monday. + self._add_easter_monday(tr("Други дан Васкрса")) + + +class RS(Serbia): + pass + + +class SRB(Serbia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/seychelles.py b/.venv/lib/python3.12/site-packages/holidays/countries/seychelles.py new file mode 100644 index 00000000..ee3da460 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/seychelles.py @@ -0,0 +1,169 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, MAR, MAY, SEP, OCT, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Seychelles(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Seychelles holidays. + + References: + * + * + * [Act 19 of 1976, 1994 Amendment (Oldest Seychelles Holidays Law available online in full)](https://web.archive.org/web/20250414175740/https://seylii.org/akn/sc/act/1976/19/eng@2012-06-30) + * [Act 11 of 2014 (Holidays names changed)](https://web.archive.org/web/20240908070851/https://seylii.org/akn/sc/act/2014/11/eng@2014-08-04) + * [Act 3 of 2017 (Added Easter Monday, repealing Liberation Day)](https://web.archive.org/web/20240920163119/https://seylii.org/akn/sc/act/2017/3/eng@2017-04-12) + + Where any public holiday, except Sunday, falls on a Sunday the next following day, + not being itself a public holiday, shall be a public holiday. + """ + + country = "SC" + default_language = "en_SC" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_SC", "en_US") + # Earliest source is the 1994 amendment of Seychelles Public Holidays Act. + start_year = 1994 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, SeychellesStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("New Year's Day")) + + # New Year Holiday. + self._add_observed(self._add_new_years_day_two(tr("New Year Holiday"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Saturday. + self._add_holy_saturday(tr("Easter Saturday")) + + if self._year >= 2017: + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Labor Day. + self._add_observed(self._add_labor_day(tr("Labour Day"))) + + # Corpus Christi. + self._add_corpus_christi_day(tr("The Fete Dieu")) + + if self._year <= 2016: + # Liberation Day. + self._add_observed(self._add_holiday_jun_5(tr("Liberation Day"))) + + self._add_observed( + self._add_holiday_jun_18( + # National Day. + tr("National Day") + if self._year <= 2014 + # Constitution Day. + else tr("Constitution Day") + ) + ) + + self._add_observed( + self._add_holiday_jun_29( + # Independence Day. + tr("Independence Day") + if self._year <= 2014 + # Independence (National) Day. + else tr("Independence (National) Day") + ) + ) + + # Assumption Day. + self._add_observed(self._add_assumption_of_mary_day(tr("Assumption Day"))) + + # All Saints' Day. + self._add_observed(self._add_all_saints_day(tr("All Saints Day"))) + + self._add_observed( + # Immaculate Conception. + self._add_immaculate_conception_day(tr("The Feast of the Immaculate Conception")) + ) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day"))) + + +class SC(Seychelles): + pass + + +class SYC(Seychelles): + pass + + +class SeychellesStaticHolidays: + """Seychelles special holidays. + + References: + * + * + * + * + * + * + * + * + * + * + + All Election Dates usually proceed from the Outer Islands first, then the Inner Islands, and + the main capital, Mahé, on the last day. The current implementation only uses the last day, + as officially decreed in 2007, 2011, 2015, and 2020. + """ + + # Bridge Public Holiday. + bridge_public_holiday = tr("Bridge Public Holiday") + + # Presidential Election Day. + presidential_election_day = tr("Presidential Election Day") + + # Parliamentary Election Day. + parliamentary_election_day = tr("Parliamentary Election Day") + + # General Election Day. + general_election_day = tr("General Election Day") + + special_public_holidays = { + 2007: (MAY, 12, presidential_election_day), + 2011: ( + (MAY, 21, presidential_election_day), + (OCT, 1, parliamentary_election_day), + ), + 2015: ( + (DEC, 5, presidential_election_day), + (DEC, 18, presidential_election_day), + ), + 2016: (SEP, 10, parliamentary_election_day), + # Funeral of the Former President France Albert René. + 2019: (MAR, 7, tr("Funeral of the Former President France Albert René")), + 2020: ( + (JAN, 3, bridge_public_holiday), + (OCT, 24, general_election_day), + (OCT, 26, bridge_public_holiday), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/sierra_leone.py b/.venv/lib/python3.12/site-packages/holidays/countries/sierra_leone.py new file mode 100644 index 00000000..5724fd0a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/sierra_leone.py @@ -0,0 +1,149 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV +from holidays.calendars.islamic import _CustomIslamicHolidays +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class SierraLeone(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Sierra Leone holidays. + + References: + * + * + * + * + """ + + country = "SL" + default_language = "en_SL" + # %s (estimated). + estimated_label = tr("%s (estimated)") + # %s (observed). + observed_label = tr("%s (observed)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observed, estimated)") + supported_languages = ("en_SL", "en_US") + # Sierra Leone gained independence on April 27, 1961. + start_year = 1962 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=SierraLeoneIslamicHolidays, show_estimated=islamic_show_estimated + ) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("New Year's Day"))) + + if self._year >= 2002: + # Armed Forces Day. + dts_observed.add(self._add_holiday_feb_18(tr("Armed Forces Day"))) + + if self._year >= 2018: + # International Women's Day. + dts_observed.add(self._add_womens_day(tr("International Women's Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Independence Day. + dts_observed.add(self._add_holiday_apr_27(tr("Independence Day"))) + + # International Worker's Day. + dts_observed.add(self._add_labor_day(tr("International Worker's Day"))) + + # Christmas Day. + dts_observed.add(self._add_christmas_day(tr("Christmas Day"))) + + # Boxing Day. + dts_observed.add(self._add_christmas_day_two(tr("Boxing Day"))) + + # Prophet's Birthday. + dts_observed.update(self._add_mawlid_day(tr("Prophet's Birthday"))) + + # Eid al-Fitr. + dts_observed.update(self._add_eid_al_fitr_day(tr("Eid al-Fitr"))) + + # Eid al-Adha. + dts_observed.update(self._add_eid_al_adha_day(tr("Eid al-Adha"))) + + if self.observed: + self._populate_observed(dts_observed) + + +class SL(SierraLeone): + pass + + +class SLE(SierraLeone): + pass + + +class SierraLeoneIslamicHolidays(_CustomIslamicHolidays): + """Sierra Leone Islamic holidays exact dates. + + References: + * + """ + + # Prophet's Birthday + MAWLID_DATES = { + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 15), + } + + # Eid al-Fitr + EID_AL_FITR_DATES = { + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + } + + # Eid al-Adha + EID_AL_ADHA_DATES = { + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/singapore.py b/.venv/lib/python3.12/site-packages/holidays/countries/singapore.py new file mode 100644 index 00000000..04098eaa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/singapore.py @@ -0,0 +1,339 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import ( + _CustomBuddhistHolidays, + _CustomChineseHolidays, + _CustomIslamicHolidays, + _CustomHinduHolidays, +) +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import ( + BuddhistCalendarHolidays, + ChineseCalendarHolidays, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_WORKDAY + + +class Singapore( + ObservedHolidayBase, + BuddhistCalendarHolidays, + ChineseCalendarHolidays, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +): + """Singapore holidays. + + References: + * [Wikipedia](https://en.wikipedia.org/wiki/Public_holidays_in_Singapore) + * [Holidays Act 1998](https://web.archive.org/web/20250405061431/https://sso.agc.gov.sg/Act/HA1998) + * [Ministry of Manpower](https://web.archive.org/web/20250616105633/https://mom.gov.sg/employment-practices/public-holidays) + + Limitations: + * Prior to 1969: holidays are estimated. + * Prior to 2000: holidays may not be accurate. + * 2024 and later: the following four moving date holidays (whose exact + date is announced yearly) are estimated, and so denoted: + * Hari Raya Puasa + * Hari Raya Haji + * Vesak Day + * Deepavali + """ + + country = "SG" + default_language = "en_SG" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_SG", "en_US", "th") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + BuddhistCalendarHolidays.__init__(self, cls=SingaporeBuddhistHolidays, show_estimated=True) + ChineseCalendarHolidays.__init__(self, cls=SingaporeChineseHolidays, show_estimated=True) + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=SingaporeHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=SingaporeIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=SingaporeStaticHolidays) + # Implement Section 4(2) of the Holidays Act: + # "if any day specified in the Schedule falls on a Sunday, + # the day next following not being itself a public holiday + # is declared a public holiday in Singapore." + kwargs.setdefault("observed_rule", SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 1998) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self) -> None: + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("New Year's Day"))) + + # Chinese New Year. + name = tr("Chinese New Year") + dts_observed.add(self._add_chinese_new_years_day(name)) # type: ignore[arg-type] + dts_observed.add(self._add_chinese_new_years_day_two(name)) # type: ignore[arg-type] + + # Eid al-Fitr. + dts_observed.update(self._add_eid_al_fitr_day(tr("Hari Raya Puasa"))) + if self._year <= 1968: + # Second Day of Eid al-Fitr. + self._add_eid_al_fitr_day_two(tr("Second Day of Hari Raya Puasa")) + + # Eid al-Adha. + dts_observed.update(self._add_eid_al_adha_day(tr("Hari Raya Haji"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year <= 1968: + # Holy Saturday. + self._add_holy_saturday(tr("Holy Saturday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Labor Day. + dts_observed.add(self._add_labor_day(tr("Labour Day"))) + + # Vesak Day. + dts_observed.add(self._add_vesak(tr("Vesak Day"))) # type: ignore[arg-type] + + # National Day. + dts_observed.add(self._add_holiday_aug_9(tr("National Day"))) + + # Deepavali. + dts_observed.add(self._add_diwali(tr("Deepavali"))) # type: ignore[arg-type] + + # Christmas Day. + dts_observed.add(self._add_christmas_day(tr("Christmas Day"))) + + if self._year <= 1968: + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")) + + if self.observed: + self._populate_observed(dts_observed) + + +class SG(Singapore): + pass + + +class SGP(Singapore): + pass + + +class SingaporeBuddhistHolidays(_CustomBuddhistHolidays): + VESAK_DATES = { + 2001: (MAY, 7), + 2002: (MAY, 26), + 2003: (MAY, 15), + 2004: (JUN, 2), + 2005: (MAY, 22), + 2006: (MAY, 12), + 2007: (MAY, 31), + 2008: (MAY, 19), + 2009: (MAY, 9), + 2010: (MAY, 28), + 2011: (MAY, 17), + 2012: (MAY, 5), + 2013: (MAY, 24), + 2014: (MAY, 13), + 2015: (JUN, 1), + 2016: (MAY, 21), + 2017: (MAY, 10), + 2018: (MAY, 29), + 2019: (MAY, 19), + 2020: (MAY, 7), + 2021: (MAY, 26), + 2022: (MAY, 15), + 2023: (JUN, 2), + 2024: (MAY, 22), + 2025: (MAY, 12), + 2026: (MAY, 31), + } + + +class SingaporeChineseHolidays(_CustomChineseHolidays): + LUNAR_NEW_YEAR_DATES = { + 2001: (JAN, 24), + 2002: (FEB, 12), + 2003: (FEB, 1), + 2004: (JAN, 22), + 2005: (FEB, 9), + 2006: (JAN, 30), + 2007: (FEB, 19), + 2008: (FEB, 7), + 2009: (JAN, 26), + 2010: (FEB, 14), + 2011: (FEB, 3), + 2012: (JAN, 23), + 2013: (FEB, 10), + 2014: (JAN, 31), + 2015: (FEB, 19), + 2016: (FEB, 8), + 2017: (JAN, 28), + 2018: (FEB, 16), + 2019: (FEB, 5), + 2020: (JAN, 25), + 2021: (FEB, 12), + 2022: (FEB, 1), + 2023: (JAN, 22), + 2024: (FEB, 10), + 2025: (JAN, 29), + 2026: (FEB, 17), + } + + +class SingaporeHinduHolidays(_CustomHinduHolidays): + # Deepavali + DIWALI_DATES = { + 2001: (NOV, 14), + 2002: (NOV, 3), + 2003: (OCT, 23), + 2004: (NOV, 11), + 2005: (NOV, 1), + 2006: (OCT, 21), + 2007: (NOV, 8), + 2008: (OCT, 27), + 2009: (NOV, 15), + 2010: (NOV, 5), + 2011: (OCT, 26), + 2012: (NOV, 13), + 2013: (NOV, 2), + 2014: (OCT, 22), + 2015: (NOV, 10), + 2016: (OCT, 29), + 2017: (OCT, 18), + 2018: (NOV, 6), + 2019: (OCT, 27), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 24), + 2023: (NOV, 12), + 2024: (OCT, 31), + 2025: (OCT, 20), + 2026: (NOV, 8), + } + + +class SingaporeIslamicHolidays(_CustomIslamicHolidays): + # Hari Raya Haji + EID_AL_ADHA_DATES = { + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 1), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 27), + 2010: (NOV, 17), + 2011: (NOV, 6), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 7), + 2026: (MAY, 27), + } + + # Hari Raya Puasa + EID_AL_FITR_DATES = { + 2001: (DEC, 16), + 2002: (DEC, 6), + 2003: (NOV, 25), + 2004: (NOV, 14), + 2005: (NOV, 3), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 1), + 2009: (SEP, 20), + 2010: (SEP, 10), + 2011: (AUG, 30), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 6), + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 3), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + 2026: (MAR, 21), + } + + +class SingaporeStaticHolidays: + """Singapore special holidays. + + References: + * + * + * + * + """ + + # Polling Day. + polling_day_name = tr("Polling Day") + + special_public_holidays = { + 2001: (NOV, 3, polling_day_name), + 2006: (MAY, 6, polling_day_name), + 2011: (MAY, 7, polling_day_name), + 2015: ( + # SG50 Public Holiday. + (AUG, 7, tr("SG50 Public Holiday")), + (SEP, 11, polling_day_name), + ), + 2020: (JUL, 10, polling_day_name), + 2023: (SEP, 1, polling_day_name), + 2025: (MAY, 3, polling_day_name), + } + + special_public_holidays_observed = { + # Eid al-Adha. + 2007: (JAN, 2, tr("Hari Raya Haji")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/sint_maarten.py b/.venv/lib/python3.12/site-packages/holidays/countries/sint_maarten.py new file mode 100644 index 00000000..744bfb24 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/sint_maarten.py @@ -0,0 +1,118 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_TO_PREV_FRI, + SUN_TO_PREV_SAT, + SUN_TO_NEXT_MON, + SUN_TO_NEXT_TUE, +) + + +class SintMaarten(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Sint Maarten holidays. + + References: + * + * [AB 2012 no. 19](https://web.archive.org/web/20250615040244/https://www.sintmaartengov.org/Documents/Official%20Publications/AB%2019%20Lvo%20Dag%20van%20Bevrijding.pdf) + * [AB 2015 no. 24](https://web.archive.org/web/20250615035932/https://www.sintmaartengov.org/Documents/Official%20Publications/AB%2024%20Landsverordening%20Constitution%20Day.pdf) + * [2014-2023](https://web.archive.org/web/20230307083630/https://www.sintmaartengov.org/government/VSA/labour/Pages/Public-Holiday-Schedule.aspx) + * [2024-Present](https://web.archive.org/web/20250212071023/https://www.sintmaartengov.org/Pages/Public-Holiday-Schedule.aspx) + """ + + country = "SX" + default_language = "nl" + supported_languages = ("en_US", "nl") + # Sint Maarten became a constituent country on October 10th, 2010. + start_year = 2011 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nieuwjaarsdag")) + + # Good Friday. + self._add_good_friday(tr("Goede Vrijdag")) + + # Easter Sunday. + self._add_easter_sunday(tr("Eerste paasdag")) + + # Easter Monday. + self._add_easter_monday(tr("Tweede paasdag")) + + self._move_holiday( + # King's Day. + self._add_holiday_apr_27(tr("Koningsdag")) + if self._year >= 2014 + # Queen's Day. + else self._add_holiday_apr_30(tr("Koninginnedag")), + rule=SUN_TO_PREV_SAT, + ) + + # Carnival Day. + name = tr("Carnavalsdag") + if self._year >= 2014: + self._move_holiday( + self._add_holiday_apr_30(name), rule=SAT_TO_PREV_FRI + SUN_TO_NEXT_TUE + ) + else: + self._add_holiday_apr_29(name) + + # Labor Day. + self._add_labor_day(tr("Dag van de Arbeid")) + + # Ascension Day. + self._add_ascension_thursday(tr("Hemelvaartsdag")) + + # Whit Sunday. + self._add_whit_sunday(tr("Eerste Pinksterdag")) + + # Established on June 13th, 2012. + if self._year >= 2012: + # Emancipation Day. + self._move_holiday(self._add_holiday_jul_1(tr("Dag van de Bevrijding"))) + + # Established on September 28th, 2015. + if self._year >= 2015: + # Constitution Day. + self._add_holiday_2nd_mon_of_oct(tr("Dag van de Constitutie")) + + # Sint Maarten Day. + self._add_holiday_nov_11(tr("Sint-Maartensdag")) + + # Replaced by Constitution Day on October 2nd, 2015. + if self._year <= 2014: + # Kingdom Day. + self._move_holiday(self._add_holiday_dec_15(tr("Koninkrijksdag"))) + + # Christmas Day. + self._add_christmas_day(tr("Eerste Kerstdag")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Tweede Kerstdag")) + + +class SX(SintMaarten): + pass + + +class SXM(SintMaarten): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/slovakia.py b/.venv/lib/python3.12/site-packages/holidays/countries/slovakia.py new file mode 100644 index 00000000..3797dba3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/slovakia.py @@ -0,0 +1,119 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import OCT +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Slovakia(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Slovakia holidays. + + References: + * + * + * + """ + + country = "SK" + default_language = "sk" + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("en_US", "sk", "uk") + # Independent Slovak Republic established on Jan 01, 1993. + start_year = 1993 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=SlovakiaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Day of the Establishment of the Slovak Republic. + self._add_holiday_jan_1(tr("Deň vzniku Slovenskej republiky")) + + self._add_epiphany_day( + # Epiphany. + tr("Zjavenie Pána (Traja králi a vianočný sviatok pravoslávnych kresťanov)") + ) + + # Good Friday. + self._add_good_friday(tr("Veľký piatok")) + + # Easter Monday. + self._add_easter_monday(tr("Veľkonočný pondelok")) + + # Labor Day. + self._add_labor_day(tr("Sviatok práce")) + + if self._year >= 1997: + # Day of Victory over Fascism. + self._add_world_war_two_victory_day(tr("Deň víťazstva nad fašizmom")) + + # Saints Cyril and Methodius Day. + self._add_holiday_jul_5(tr("Sviatok svätého Cyrila a svätého Metoda")) + + # Slovak National Uprising Anniversary. + self._add_holiday_aug_29(tr("Výročie Slovenského národného povstania")) + + if self._year <= 2023: + # Constitution Day. + self._add_holiday_sep_1(tr("Deň Ústavy Slovenskej republiky")) + + # Day of Our Lady of the Seven Sorrows. + self._add_holiday_sep_15(tr("Sedembolestná Panna Mária")) + + # All Saints' Day. + self._add_all_saints_day(tr("Sviatok Všetkých svätých")) + + if self._year >= 2001: + # Struggle for Freedom and Democracy Day. + self._add_holiday_nov_17(tr("Deň boja za slobodu a demokraciu")) + + # Christmas Eve. + self._add_christmas_eve(tr("Štedrý deň")) + + # Christmas Day. + self._add_christmas_day(tr("Prvý sviatok vianočný")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Druhý sviatok vianočný")) + + def _populate_workday_holidays(self): + # According to Law 241/1993, these state holidays are not non-working days. + + if self._year >= 2024: + # Constitution Day. + self._add_holiday_sep_1(tr("Deň Ústavy Slovenskej republiky")) + + if self._year >= 2021: + # Day of the Establishment of the Independent Czech-Slovak State. + self._add_holiday_oct_28(tr("Deň vzniku samostatného česko-slovenského štátu")) + + +class SK(Slovakia): + pass + + +class SVK(Slovakia): + pass + + +class SlovakiaStaticHolidays: + special_public_holidays = { + # 100th anniversary of the adoption of the Declaration + # of the Slovak Nation. + 2018: (OCT, 30, tr("100. výročie prijatia Deklarácie slovenského národa")) + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/slovenia.py b/.venv/lib/python3.12/site-packages/holidays/countries/slovenia.py new file mode 100644 index 00000000..912a6a56 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/slovenia.py @@ -0,0 +1,140 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import AUG +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Slovenia(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Slovenia holidays. + + References: + * + * + * + * + """ + + country = "SI" + default_language = "sl" + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("en_US", "sl", "uk") + # Act on Holidays and Non-Working Days in the Republic of Slovenia, 1991-11-21. + start_year = 1992 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, SloveniaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Work-free national holidays and other work-free days. + + # New Year's Day. + name = tr("novo leto") + self._add_new_years_day(name) + if self._year <= 2012 or self._year >= 2017: + self._add_new_years_day_two(name) + + # Prešeren's Day, the Slovenian Cultural Holiday. + self._add_holiday_feb_8(tr("Prešernov dan, slovenski kulturni praznik")) + + # Easter Sunday. + self._add_easter_sunday(tr("velikonočna nedelja")) + + # Easter Monday. + self._add_easter_monday(tr("velikonočni ponedeljek")) + + # Day of Uprising Against Occupation. + self._add_holiday_apr_27(tr("dan upora proti okupatorju")) + + # Labor Day. + name = tr("praznik dela") + self._add_labor_day(name) + self._add_labor_day_two(name) + + # Whit Sunday. + self._add_whit_sunday(tr("binkoštna nedelja")) + + # Statehood Day. + self._add_holiday_jun_25(tr("dan državnosti")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Marijino vnebovzetje")) + + # Reformation Day. + self._add_holiday_oct_31(tr("dan reformacije")) + + # Day of Remembrance for the Dead. + self._add_all_saints_day(tr("dan spomina na mrtve")) + + # Christmas Day. + self._add_christmas_day(tr("božič")) + + self._add_holiday_dec_26( + # Independence and Unity Day. + tr("dan samostojnosti in enotnosti") + if self._year >= 2005 + # Independence Day. + else tr("dan samostojnosti") + ) + + def _populate_workday_holidays(self): + # Not work-free national holidays. + + if self._year >= 2011: + # Primož Trubar Day. + self._add_holiday_jun_8(tr("dan Primoža Trubarja")) + + if self._year >= 2006: + # Unification of Prekmurje Slovenes with the Mother Nation. + self._add_holiday_aug_17(tr("združitev prekmurskih Slovencev z matičnim narodom")) + + self._add_holiday_sep_15( + # Integration of Primorska into the Homeland. + tr("priključitev Primorske k matični domovini") + if self._year >= 2025 + # Return of Primorska into the Homeland. + else tr("vrnitev Primorske k matični domovini") + ) + + if self._year >= 2020: + # Slovenian Sport's Day. + self._add_holiday_sep_23(tr("dan slovenskega športa")) + + if self._year >= 2015: + # Sovereignty Day. + self._add_holiday_oct_25(tr("dan suverenosti")) + + if self._year >= 2005: + # Rudolf Maister Day. + self._add_holiday_nov_23(tr("dan Rudolfa Maistra")) + + +class SI(Slovenia): + pass + + +class SVN(Slovenia): + pass + + +class SloveniaStaticHolidays: + special_public_holidays = { + # Solidarity Day. + 2023: (AUG, 14, tr("dan solidarnosti")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/solomon_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/solomon_islands.py new file mode 100644 index 00000000..57390399 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/solomon_islands.py @@ -0,0 +1,220 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import APR, JUN, SEP, NOV +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_TO_PREV_FRI, + SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class SolomonIslands( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """Solomon Islands holidays. + + References: + * [Public Holidays Act](https://web.archive.org/web/20250615054807/https://www.paclii.org/sb/legis/consol_act_1996/pha163.pdf) + * [2016](https://web.archive.org/web/20250530230724/https://mehrd.gov.sb/documents?view=download&format=raw&fileId=4377) + * [2020](https://web.archive.org/web/20240908025223/https://solomons.gov.sb/national-and-provincial-public-holidays-2020/) + * [2021](https://web.archive.org/web/20241004035112/https://solomons.gov.sb/wp-content/uploads/2021/03/Gaz-No.-54-Sup-No.-50-Wednesday-10th-March-2021.pdf) + * [2022](https://web.archive.org/web/20240727185307/https://solomons.gov.sb/wp-content/uploads/2021/10/Gaz-No.-246-Tuesday-19th-October-2021-.pdf) + * [2023](https://web.archive.org/web/20240810050725/https://solomons.gov.sb/wp-content/uploads/2022/12/Gaz-No.-324-Wednesday-21st-December-2022-1.pdf) + * [2024](https://web.archive.org/web/20240727124555/https://solomons.gov.sb/wp-content/uploads/2024/02/Gaz-No.-15-Monday-12th-FEBRUARY-2024.pdf) + * [2025](https://web.archive.org/web/20250615054517/https://solomons.gov.sb/wp-content/uploads/2024/11/Gaz-No.-178-Monday-25th-November-2024.pdf) + + About the day appointed for the celebration of the Anniversary of the Birthday of the + Sovereign: + + * Up to 2022, the Queen's Birthday was typically observed on the second Saturday of + June, with the preceding Friday designated as a public holiday. From 2023 onward, + the King's Birthday has been marked on the Friday before the third Saturday in + June. Although there has been no amendment to the Public Holidays Act to explicitly + state this change, the pattern is evident in the annual government gazettes and + supported by information from the relevant [Wikipedia + entry](https://en.wikipedia.org/wiki/King's_Official_Birthday#Solomon_Islands). + * There are a few exceptions to this rule: + * [Queen's Birthday 2022](https://web.archive.org/web/20240727184251/https://solomons.gov.sb/wp-content/uploads/2022/05/Gaz-No.-171-Friday-27th-May-2022.pdf) + * According to the holidays schedule for 2024, King's Birthday was celebrated on + the 3rd saturday of June (June 15) and the preceding Friday was observed as a + public holiday. + * [King's Birthday 2025](https://web.archive.org/web/20250615054519/https://solomons.gov.sb/wp-content/uploads/2025/04/Gaz-No.-33-Wednesday-9th-April-2025.pdf) + + Province Days are not listed in the Public Holidays Act but are consistently announced + in the official gazette each year. + + While the Public Holidays Act specifies the Sunday to next Monday observance rule, + gazettes dating back to 2016 also follow the Saturday to previous Friday rule for + shifting public holidays. + """ + + country = "SB" + # %s (observed). + observed_label = "%s (observed)" + start_year = 1979 + subdivisions = ( + "CE", # Central. + "CH", # Choiseul. + "CT", # Capital Territory (Honiara). + "GU", # Guadalcanal. + "IS", # Isabel. + "MK", # Makira-Ulawa. + "ML", # Malaita. + "RB", # Rennell and Bellona. + "TE", # Temotu. + "WE", # Western. + ) + subdivisions_aliases = { + "Central": "CE", + "Choiseul": "CH", + "Capital Territory": "CT", + "Honiara": "CT", + "Guadalcanal": "GU", + "Isabel": "IS", + "Makira-Ulawa": "MK", + "Malaita": "ML", + "Rennell and Bellona": "RB", + "Temotu": "TE", + "Western": "WE", + } + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=SolomonIslandsStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON + SAT_TO_PREV_FRI) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = "New Year's Day" + self._add_observed(self._add_new_years_day(name)) + self._add_observed(self._next_year_new_years_day, name=name, rule=SAT_TO_PREV_FRI) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Holy Saturday. + self._add_holy_saturday("Holy Saturday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Whit Monday. + self._add_whit_monday("Whit Monday") + + name = ( + # King's Birthday. + "King's Birthday" + if self._year >= 2023 + # Queen's Birthday. + else "Queen's Birthday" + ) + sovereign_birthday_dates = { + 2022: (JUN, 3), + 2025: (JUN, 13), + } + if dt := sovereign_birthday_dates.get(self._year): + self._add_holiday(name, dt) + elif self._year == 2024: + self._add_observed(self._add_holiday_3rd_sat_of_jun(name)) + elif self._year >= 2023: + self._add_holiday_1_day_prior_3rd_sat_of_jun(name) + else: + self._add_observed(self._add_holiday_2nd_sat_of_jun(name)) + + # Independence Day. + self._add_observed(self._add_holiday_jul_7("Independence Day")) + + self._add_observed( + # Christmas Day. + self._add_christmas_day("Christmas Day"), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # National Day of Thanksgiving. + self._add_christmas_day_two("National Day of Thanksgiving"), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + def _populate_subdiv_ce_public_holidays(self): + # Central Province Day. + self._add_observed(self._add_holiday_jun_29("Central Province Day")) + + def _populate_subdiv_ch_public_holidays(self): + # Choiseul Province Day. + self._add_observed(self._add_holiday_feb_25("Choiseul Province Day")) + + def _populate_subdiv_gu_public_holidays(self): + # Guadalcanal Province Day. + self._add_observed(self._add_holiday_aug_1("Guadalcanal Province Day")) + + def _populate_subdiv_is_public_holidays(self): + # Isabel Province Day. + self._add_observed(self._add_holiday_jun_2("Isabel Province Day")) + + def _populate_subdiv_mk_public_holidays(self): + # Makira-Ulawa Province Day. + self._add_observed(self._add_holiday_aug_3("Makira-Ulawa Province Day")) + + def _populate_subdiv_ml_public_holidays(self): + # Malaita Province Day. + self._add_observed(self._add_holiday_aug_15("Malaita Province Day")) + + def _populate_subdiv_rb_public_holidays(self): + # Rennell and Bellona Province Day. + self._add_observed(self._add_holiday_jul_20("Rennell and Bellona Province Day")) + + def _populate_subdiv_te_public_holidays(self): + # Temotu Province Day. + self._add_observed(self._add_holiday_jun_8("Temotu Province Day")) + + def _populate_subdiv_we_public_holidays(self): + # Western Province Day. + self._add_observed(self._add_holiday_dec_7("Western Province Day")) + + +class SB(SolomonIslands): + pass + + +class SLB(SolomonIslands): + pass + + +class SolomonIslandsStaticHolidays: + """Solomon Islands special holidays. + + References: + * [2024 General Election Holiday](https://web.archive.org/web/20240711032116/https://solomonchamber.com.sb/media/2618/gaz-no-61-monday-8th-april-2024.pdf) + * [2020 By-election Holiday](https://web.archive.org/web/20241011021616/https://solomons.gov.sb/wp-content/uploads/2020/11/GAZ-173-11th-November-2020-1.pdf) + * [Gazette No. 269 of 2022](https://web.archive.org/web/20240727183925/https://solomons.gov.sb/wp-content/uploads/2022/09/Gaz-No.-269-Friday-9th-September-2022.pdf) + """ + + # Public Holiday. + name = "Public Holiday" + special_public_holidays = { + 2022: (SEP, 12, name), + 2024: (APR, 17, name), + } + + special_ch_public_holidays = { + 2020: (NOV, 18, name), + } + + special_gu_public_holidays = { + 2020: (NOV, 18, name), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/south_africa.py b/.venv/lib/python3.12/site-packages/holidays/countries/south_africa.py new file mode 100644 index 00000000..03635031 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/south_africa.py @@ -0,0 +1,157 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import JAN, MAR, APR, MAY, JUN, AUG, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class SouthAfrica(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """South Africa holidays. + + References: + * + * + * + * + """ + + country = "ZA" + observed_label = "%s (observed)" + # Observed since 1910, with a few name changes + start_year = 1910 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, SouthAfricaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1995) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self._add_observed(self._add_new_years_day("New Year's Day")) + + self._add_good_friday("Good Friday") + + self._add_easter_monday("Family Day" if self._year >= 1980 else "Easter Monday") + + if self._year <= 1951: + name = "Dingaan's Day" + elif self._year <= 1979: + name = "Day of the Covenant" + elif self._year <= 1994: + name = "Day of the Vow" + else: + name = "Day of Reconciliation" + self._add_observed(self._add_holiday_dec_16(name)) + + self._add_christmas_day("Christmas Day") + + self._add_observed( + self._add_christmas_day_two("Day of Goodwill" if self._year >= 1980 else "Boxing Day") + ) + + if self._year >= 1995: + self._add_observed(self._add_holiday_mar_21("Human Rights Day")) + + self._add_observed(self._add_holiday_apr_27("Freedom Day")) + + self._add_observed(self._add_labor_day("Workers' Day")) + + self._add_observed(self._add_holiday_jun_16("Youth Day")) + + self._add_observed(self._add_holiday_aug_9("National Women's Day")) + + self._add_observed(self._add_holiday_sep_24("Heritage Day")) + + # Historic public holidays no longer observed + if 1952 <= self._year <= 1973: + self._add_holiday_apr_6("Van Riebeeck's Day") + elif 1980 <= self._year <= 1994: + self._add_holiday_apr_6("Founder's Day") + + if 1987 <= self._year <= 1989: + self._add_holiday_1st_fri_of_may("Workers' Day") + + if self._year <= 1993: + self._add_ascension_thursday("Ascension Day") + + if self._year <= 1951: + self._add_holiday_may_24("Empire Day") + + if self._year <= 1960: + self._add_holiday_may_31("Union Day") + elif self._year <= 1993: + self._add_holiday_may_31("Republic Day") + + if 1952 <= self._year <= 1960: + self._add_holiday_2nd_mon_of_jul("Queen's Birthday") + + if 1961 <= self._year <= 1973: + self._add_holiday_jul_10("Family Day") + + if self._year <= 1951: + self._add_holiday_1st_mon_of_aug("King's Birthday") + + if 1952 <= self._year <= 1979: + self._add_holiday_1st_mon_of_sep("Settlers' Day") + + if 1952 <= self._year <= 1993: + self._add_holiday_oct_10("Kruger Day") + + +class ZA(SouthAfrica): + pass + + +class ZAF(SouthAfrica): + pass + + +class SouthAfricaStaticHolidays: + local_elections = "Local government elections" + municipal_elections = "Municipal elections" + national_and_provincial_elections = "National and provincial government elections" + presidential_decree_holiday = "Public holiday by presidential decree" + y2k_changeover = "Y2K changeover" + special_public_holidays = { + 1999: ( + (JUN, 2, national_and_provincial_elections), + (DEC, 31, y2k_changeover), + ), + 2000: (JAN, 2, y2k_changeover), + 2004: (APR, 14, national_and_provincial_elections), + 2006: (MAR, 1, local_elections), + 2008: (MAY, 2, presidential_decree_holiday), + 2009: (APR, 22, national_and_provincial_elections), + 2011: ( + (MAY, 18, local_elections), + (DEC, 27, presidential_decree_holiday), + ), + 2014: (MAY, 7, national_and_provincial_elections), + 2016: ( + (AUG, 3, local_elections), + (DEC, 27, presidential_decree_holiday), + ), + 2019: (MAY, 8, national_and_provincial_elections), + 2021: (NOV, 1, municipal_elections), + 2022: (DEC, 27, presidential_decree_holiday), + # Winning the 2023 Rugby World Cup + 2023: (DEC, 15, presidential_decree_holiday), + 2024: (MAY, 29, national_and_provincial_elections), + } + + special_public_holidays_observed = { + # https://web.archive.org/web/20120328122217/http://www.info.gov.za/speeches/1999/991028409p1002.htm + 2000: (JAN, 3, y2k_changeover), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/south_korea.py b/.venv/lib/python3.12/site-packages/holidays/countries/south_korea.py new file mode 100644 index 00000000..c089c878 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/south_korea.py @@ -0,0 +1,597 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +import warnings +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.chinese import KOREAN_CALENDAR +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + _timedelta, +) +from holidays.constants import BANK, PUBLIC +from holidays.groups import ( + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_WORKDAY, + SUN_TO_NEXT_WORKDAY, +) + + +class SouthKorea( + ObservedHolidayBase, + ChineseCalendarHolidays, + ChristianHolidays, + InternationalHolidays, + StaticHolidays, +): + """South Korea holidays. + + References: + * + * + * + * + * + * + * + * + * [TH localization 1](https://web.archive.org/web/20241217184803/https://overseas.mofa.go.kr/th-th/wpge/m_3133/contents.do) + * [TH localization 2](https://web.archive.org/web/20200216004120/http://thailand.korean-culture.org:80/th/138/korea/38) + + Checked With: + * + * + + According to (3), the alt holidays in Korea are as follows: + * The alt holiday means next first non holiday after the holiday. + * Independence Movement Day, Liberation Day, National Foundation Day, + Hangul Day, Children's Day, Birthday of the Buddha, Christmas Day have + alt holiday if they fell on Saturday or Sunday. + * Korean New Year's Day, Korean Mid Autumn Day have alt holiday if they + fell on Sunday. + """ + + country = "KR" + supported_categories = (BANK, PUBLIC) + default_language = "ko" + # Alternative holiday for %s. + observed_label = tr("%s 대체 휴일") + supported_languages = ("en_US", "ko", "th") + start_year = 1948 + + def __init__(self, *args, **kwargs): + ChineseCalendarHolidays.__init__(self, calendar=KOREAN_CALENDAR) + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=SouthKoreaStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 2014) + super().__init__(*args, **kwargs) + + def _populate_observed(self, dts: set[date], three_day_holidays: dict[date, str]) -> None: + for dt in sorted(dts.union(three_day_holidays.keys())): + if not self._is_observed(dt): + continue + dt_observed = self._get_observed_date( + dt, SUN_TO_NEXT_WORKDAY if dt in three_day_holidays else SAT_SUN_TO_NEXT_WORKDAY + ) + if dt_observed != dt or len(self.get_list(dt)) > 1: + if dt_observed == dt: + dt_observed = self._get_next_workday(dt) + names = ( + (three_day_holidays[dt],) if dt in three_day_holidays else self.get_list(dt) + ) + for name in names: + self._add_holiday(self.tr(self.observed_label) % self.tr(name), dt_observed) + + def _populate_public_holidays(self): + def append_observed(dt: date, since: int): + if self._year >= since: + dts_observed.add(dt) + + def add_three_day_holiday(dt: date, name: str): + name = self.tr(name) + for dt_alt in ( + # The day preceding %s. + self._add_holiday(self.tr("%s 전날") % name, _timedelta(dt, -1)), + dt, + # The second day of %s. + self._add_holiday(self.tr("%s 다음날") % name, _timedelta(dt, +1)), + ): + three_days_holidays[dt_alt] = name + + dts_observed = set() + three_days_holidays = {} + + # Fixed Date Holidays. + + # New Year's Day. + name = tr("신정연휴") + self._add_new_years_day(name) + if self._year <= 1998: + self._add_new_years_day_two(name) + if self._year <= 1989: + self._add_new_years_day_three(name) + + if self._year >= 1985: + name = ( + # Korean New Year. + tr("설날") + if self._year >= 1989 + # Folk Day. + else tr("민속의 날") + ) + korean_new_year = self._add_chinese_new_years_day(name) + if self._year >= 1989: + add_three_day_holiday(korean_new_year, name) + + # Independence Movement Day. + mar_1 = self._add_holiday_mar_1(tr("삼일절")) + # mar_1 is used later for Presidential Election Day. + append_observed(mar_1, 2022) + + if 1949 <= self._year <= 2005 and self._year != 1960: + # Tree Planting Day. + self._add_holiday_apr_5(tr("식목일")) + + if self._year >= 1975: + name = ( + # Buddha's Birthday. + tr("부처님오신날") + if self._year >= 2017 + # Buddha's Birthday. + else tr("석가탄신일") + ) + append_observed(self._add_chinese_birthday_of_buddha(name), 2023) + + if self._year >= 1975: + # Children's Day. + append_observed(self._add_holiday_may_5(tr("어린이날")), 2015) + + if self._year >= 1956: + # Memorial Day. + jun_6 = self._add_holiday_jun_6(tr("현충일")) + # jun_6 is used later for Local Election Day. + + if self._year <= 2007: + # Constitution Day. + self._add_holiday_jul_17(tr("제헌절")) + + # Liberation Day. + append_observed(self._add_holiday_aug_15(tr("광복절")), 2021) + + if 1976 <= self._year <= 1990: + # Armed Forces Day. + self._add_holiday_oct_1(tr("국군의 날")) + + # National Foundation Day. + append_observed(self._add_holiday_oct_3(tr("개천절")), 2021) + + if self._year <= 1990 or self._year >= 2013: + # Hangul Day. + append_observed(self._add_holiday_oct_9(tr("한글날")), 2021) + + if 1950 <= self._year <= 1975: + # United Nations Day. + self._add_united_nations_day(tr("국제연합일")) + + # Chuseok. + name = tr("추석") + chuseok = self._add_mid_autumn_festival(name) + if 1986 <= self._year <= 1988: + self._add_mid_autumn_festival_day_two(self.tr("%s 다음날") % self.tr(name)) + elif self._year >= 1989: + add_three_day_holiday(chuseok, name) + + # Christmas Day. + append_observed(self._add_christmas_day(tr("기독탄신일")), 2023) + + # Election Days since Sep 2006; excluding the 2017, 2025 Special Presidential Election Day. + + # Based on Article 34 of the Public Official Election Act. + # (1) The election day for each election to be held at the expiration of the term shall + # be as follows: + # 1. The presidential election shall be held on the first Wednesday from the 70th + # day before the expiration of the term of office; + # 2. The election of National Assembly members shall be held on the first Wednesday + # from the 50th day before the expiration of the term of office; + # 3. The election of local council members and the head of each local government + # shall be held on the first Wednesday from the 30th day before the expiration + # of the term of office. + # (2) Where the election day as provided in paragraph (1) falls on a folk festival day or + # legal holiday closely related with the lives of the people or the day preceding or + # following the election day is a legal holiday, the election shall be held on the + # Wednesday of the following week. + + # National Assembly Election Day. + name = tr("국회의원 선거일") + + if self._year == 2020: + self._add_holiday_apr_15(name) + elif self._year >= 2007 and (self._year - 2008) % 4 == 0: + self._add_holiday_2nd_wed_of_apr(name) + + if self._year >= 2007: + # Presidential Election Day. + name = tr("대통령 선거일") + if self._year <= 2024 and (self._year - 2007) % 5 == 0: + if self._year <= 2012: + self._add_holiday_3rd_wed_of_dec(name) + elif self._year >= 2022: + # Moved as per Paragraph 2 of Article 34 due to conflict with + # Independence Movement Day (MAR, 1). + self._add_holiday_2nd_wed_of_mar(name) + elif self._year >= 2030 and (self._year - 2030) % 5 == 0: + self._add_holiday_1st_wed_of_apr(name) + + if self._year >= 2007 and (self._year - 2010) % 4 == 0: + # Local Election Day. + name = tr("지방선거일") + + if self._is_tuesday(jun_6) or self._is_wednesday(jun_6) or self._is_thursday(jun_6): + # Moved as per Paragraph 2 of Article 34 due to conflict with + # Memorial Day (JUN, 6). + self._add_holiday_2nd_wed_of_jun(name) + else: + self._add_holiday_1st_wed_of_jun(name) + + if self.observed: + self._populate_observed(dts_observed, three_days_holidays) + + def _populate_bank_holidays(self): + # Workers' Day. + name = tr("근로자의날") + if self._year >= 1994: + self._add_labor_day(name) + else: + self._add_holiday_mar_10(name) + + +class Korea(SouthKorea): + def __init__(self, *args, **kwargs) -> None: + warnings.warn("Korea is deprecated, use SouthKorea instead.", DeprecationWarning) + + super().__init__(*args, **kwargs) + + +class KR(SouthKorea): + pass + + +class KOR(SouthKorea): + pass + + +class SouthKoreaStaticHolidays: + """South Korea special holidays. + + References: + * * + * ** + * + + 1. Election Dates featured here are the ones prior to the proper recodification to + Article 34 of the Public Official Election Act(September 2006) + 2. Sabang Day (사방의 날) was technically in the Public Holidays Act itself, but since it was + only celebrated in 1960, this is being put here. + """ + + # Common Special Holiday Types. + + # National Assembly Election Day. + national_assembly_election_day = tr("국회의원 선거일") + + # Presidential Election Day. + presidential_election_day = tr("대통령 선거일") + + # Local Election Day. + local_election_day = tr("지방선거일") + + # Temporary Public Holiday. + temporary_public_holiday = tr("임시공휴일") + + # Presidential Inauguration Day. + presidential_inauguration_day = tr("대통령 취임식") + + # National Conference for Unification Election Day. + national_conference_for_unification_election_day = tr("통일주체국민회의 선거일") + + # Yushin Constitution Referendum Day. + yushin_constitution_referendum_day = tr("유신헌법 국민투표일") + + # May 16 Military Coup d'Etat Anniversary. + may_16_coup_anniversary = tr("5.16 군사혁명 기념일") + + # April 19 Revolution Anniversary. + apr_19_revolution_anniversary = tr("4.19 혁명 기념일") + + # President Syngman Rhee's Birthday. + syngman_rhee_birthday = tr("이승만 대통령 탄신일") + + # Armed Forces Day. + armed_forces_day = tr("국군의 날") + + special_public_holidays = { + 1948: ( + # 1st National Assembly Election. + (MAY, 10, national_assembly_election_day), + # 1st Presidential Election. + (JUL, 20, presidential_election_day), + # Republic of Korea's United Nations Recognition Celebrations. + (DEC, 15, tr("국제연합의 대한민국 정부 승인 경축 국민대회")), + ), + 1949: ( + # Anniversary of the 1st National Assembly Election. + (MAY, 10, tr("5.10 제헌의회선거 1주년 기념일")), + # Baekbeom Kim Ku's Funeral Ceremony. + (JUL, 5, tr("백범 김구 선생 국민장 영결식")), + ), + 1950: ( + # 2nd National Assembly Election. + (MAY, 30, national_assembly_election_day), + # Joint Memorial Service for Fallen Soldiers. + (JUN, 21, tr("전몰군인 합동위령제")), + ), + # Vice Presidential Election. + 1951: (MAY, 16, tr("부통령 선거일")), + 1952: ( + # City/Town/Township-level Local Elections. + (APR, 25, local_election_day), + # Provincial-level Local Elections. + (MAY, 10, local_election_day), + # 2nd Presidential Election/3rd Vice President Election. + (AUG, 5, presidential_election_day), + ), + # 3rd National Assembly Election. + 1954: (MAY, 20, national_assembly_election_day), + 1956: ( + # 3rd Presidential Election/4th Vice President Election. + (MAY, 15, presidential_election_day), + # City/Town/Township-level Local Elections. + (AUG, 8, local_election_day), + # Provincial-level Local Elections. + (AUG, 13, local_election_day), + ), + # President Syngman Rhee's Birthday. + 1957: (MAR, 26, syngman_rhee_birthday), + 1958: ( + # 4th National Assembly Election. + (MAY, 2, national_assembly_election_day), + # President Syngman Rhee's Birthday. + (MAR, 26, syngman_rhee_birthday), + ), + # President Syngman Rhee's Birthday. + 1959: (MAR, 26, syngman_rhee_birthday), + 1960: ( + # Sabang Day. + (MAR, 16, tr("사방의 날")), + # President Syngman Rhee's Birthday. + (MAR, 26, syngman_rhee_birthday), + # 4th Presidential Election/5th Vice President Election. + (MAR, 15, presidential_election_day), + # 5th National Assembly Election. + (JUL, 29, national_assembly_election_day), + # 4th Presidential Election. + (AUG, 12, presidential_election_day), + # New Government Celebration Day. + (OCT, 1, tr("신정부 경축의 날")), + # Special City/Provincial-level Councillors Local Elections. + (DEC, 12, local_election_day), + # City/Town/Township-level Councillors Local Elections. + (DEC, 19, local_election_day), + # Special City/Provincial-level Mayors Local Elections. + (DEC, 26, local_election_day), + # City/Town/Township-level Governors Local Elections. + (DEC, 29, local_election_day), + ), + # April 19 Revolution Anniversary. + 1961: (APR, 19, apr_19_revolution_anniversary), + 1962: ( + # April 19 Revolution Anniversary. + (APR, 19, apr_19_revolution_anniversary), + # May 16 Military Coup d'État Anniversary. + (MAY, 16, may_16_coup_anniversary), + ), + 1963: ( + # April 19 Revolution Anniversary. + (APR, 19, apr_19_revolution_anniversary), + # May 16 Military Coup d'État Anniversary. + (MAY, 16, may_16_coup_anniversary), + # 5th Presidential Election. + (OCT, 15, presidential_election_day), + # 6th National Assembly Election. + (NOV, 26, national_assembly_election_day), + # President Park Chung Hee's Inauguration Day. + (DEC, 17, presidential_inauguration_day), + ), + # Armed Forces Day. + 1966: (OCT, 1, armed_forces_day), + 1967: ( + # In-lieu observance for New Year's Day. + (JAN, 4, temporary_public_holiday), + # 6th Presidential Election. + (MAY, 3, presidential_election_day), + # 7th National Assembly Election. + (JUN, 8, national_assembly_election_day), + # President Park Chung Hee's Inauguration Day. + (JUL, 1, presidential_inauguration_day), + ), + 1969: ( + # Commemoration of the Apollo 11 Moon Landing. + (JUL, 21, tr("아폴로 11호 달 착륙 기념")), + # Third-term Constitutional Referendum Day. + (OCT, 17, tr("삼선 헌법 개정 국민투표일")), + ), + 1971: ( + # 7th Presidential Election. + (APR, 27, presidential_election_day), + # 8th National Assembly Election. + (MAY, 25, national_assembly_election_day), + # President Park Chung Hee's Inauguration Day. + (JUL, 1, presidential_inauguration_day), + ), + 1972: ( + # Yushin Constitution Referendum Day. + (NOV, 21, yushin_constitution_referendum_day), + # 1st National Conference for Unification Election Day. + (DEC, 15, national_conference_for_unification_election_day), + # 8th Presidential Election. + (DEC, 23, presidential_election_day), + # President Park Chung Hee's Inauguration Day. + (DEC, 27, presidential_inauguration_day), + ), + # 9th National Assembly Election. + 1973: (FEB, 27, national_assembly_election_day), + # First Lady Yuk Young-soo's Funeral Ceremony. + 1974: (AUG, 19, tr("대통령 영부인 육영수 여사 국민장 영결식")), + # Yushin Constitution Referendum Day. + 1975: (FEB, 12, yushin_constitution_referendum_day), + 1978: ( + # 2nd National Conference for Unification Election Day. + (MAY, 18, national_conference_for_unification_election_day), + # 9th Presidential Election. + (JUL, 6, presidential_election_day), + # 10th National Assembly Election. + (DEC, 12, national_assembly_election_day), + # President Park Chung Hee's Inauguration Day. + (DEC, 27, presidential_inauguration_day), + ), + 1979: ( + # President Park Chung Hee's Funeral Ceremony. + (NOV, 3, tr("박정희 대통령 국장 영결식")), + # 10th Presidential Election. + (DEC, 6, presidential_election_day), + # President Choi Kyu-hah's Inauguration Day. + (DEC, 21, presidential_inauguration_day), + ), + 1980: ( + # 11th Presidential Election. + (AUG, 27, presidential_election_day), + # President Chun Doo-hwan's Inauguration Day. + (SEP, 1, presidential_inauguration_day), + # 5th Republic Constitutional Referendum Day. + (OCT, 22, tr("제5공화국 헌법 개정 국민투표일")), + ), + 1981: ( + # Electoral College Election Day. + (FEB, 11, tr("선거를 위한 선거인단 선일")), + # 12th Presidential Election. + (FEB, 25, presidential_election_day), + # President Chun Doo-hwan's Inauguration Day. + (MAR, 3, presidential_inauguration_day), + # 11th National Assembly Election. + (MAR, 25, national_assembly_election_day), + ), + # Added due to overlaps between Chuseok and Armed Forces Day. + 1982: (OCT, 2, temporary_public_holiday), + # 12th National Assembly Election. + 1985: (FEB, 12, national_assembly_election_day), + 1987: ( + # 13th Presidential Election. + (DEC, 16, presidential_election_day), + # 6th Republic Constitutional Referendum Day. + (OCT, 27, tr("제6공화국 헌법 개정 국민투표일")), + ), + 1988: ( + # President Roh Tae-woo's Inauguration Day. + (FEB, 25, presidential_inauguration_day), + # 13th National Assembly Election. + (APR, 26, national_assembly_election_day), + # 1988 Seoul Olympics Opening Ceremony. + (SEP, 17, tr("1988 서울 올림픽 개막식")), + ), + 1991: ( + # District/City/County-level Local Elections. + (MAR, 26, local_election_day), + # Metropolitan/Provincial-level Local Elections. + (JUN, 20, local_election_day), + ), + 1992: ( + # 14th National Assembly Election. + (MAR, 24, national_assembly_election_day), + # 14th Presidential Election. + (DEC, 18, presidential_election_day), + ), + # 1st Nationwide Local Election. + 1995: (JUN, 27, local_election_day), + # 15th National Assembly Election. + 1996: (APR, 11, national_assembly_election_day), + # 15th Presidential Election. + 1997: (DEC, 18, presidential_election_day), + # 2nd Nationwide Local Election. + 1998: (JUN, 4, local_election_day), + # 16th National Assembly Election. + 2000: (APR, 13, national_assembly_election_day), + 2002: ( + # 3rd Nationwide Local Election. + (JUN, 13, local_election_day), + # 2002 FIFA World Cup National Team Semi-Finals Celebrations. + (JUL, 1, tr("2002년 한일 월드컵 대표팀 4강 진출")), + # 16th Presidential Election. + (DEC, 19, presidential_election_day), + ), + # 17th National Assembly Election. + 2004: (APR, 15, national_assembly_election_day), + # 4th Nationwide Local Election. + 2006: (MAY, 31, local_election_day), + # Added to help cope with MERS Pandemic fatigue. + 2015: (AUG, 14, temporary_public_holiday), + # Added to fill in holiday gaps between Children's Day and Saturday. + 2016: (MAY, 6, temporary_public_holiday), + 2017: ( + # Special Presidential Election due to Park Geun-hye's impeachment. + (MAY, 9, presidential_election_day), + # Added to create a 10-day long holiday period. + (OCT, 2, temporary_public_holiday), + ), + # Added to help cope with Covid-19 Pandemic fatigue. + 2020: (AUG, 17, temporary_public_holiday), + # Added to create a 6-day long holiday period. + 2023: (OCT, 2, temporary_public_holiday), + # 76th Anniversary of the Armed Forces of Korea. + 2024: (OCT, 1, armed_forces_day), + 2025: ( + # Added to create a 6-day long holiday period. + (JAN, 27, temporary_public_holiday), + # Special Presidential Election (21st) due to Yoon Seok-yeol's impeachment. + (JUN, 3, presidential_election_day), + ), + } + # Pre-2014 Alternate Holidays + # https://namu.wiki/w/대체%20휴일%20제도#s-4.2.1 + special_public_holidays_observed = { + 1959: (APR, 6, tr("식목일")), + 1960: ( + (JUL, 18, tr("제헌절")), + (OCT, 10, tr("한글날")), + (DEC, 26, tr("기독탄신일")), + ), + 1989: (OCT, 2, armed_forces_day), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/spain.py b/.venv/lib/python3.12/site-packages/holidays/countries/spain.py new file mode 100644 index 00000000..d78aa5dc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/spain.py @@ -0,0 +1,767 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV +from holidays.groups import ( + ChristianHolidays, + IslamicHolidays, + InternationalHolidays, + StaticHolidays, +) +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Spain( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Spain holidays. + + References: + * + * [2010](https://web.archive.org/web/20250427181827/https://www.boe.es/buscar/doc.php?id=BOE-A-2009-18477) + * [2011](https://web.archive.org/web/20231121065830/https://www.boe.es/buscar/doc.php?id=BOE-A-2010-15722) + * [2012](https://web.archive.org/web/20250427181838/https://www.boe.es/buscar/doc.php?id=BOE-A-2011-16116) + * [2013](https://web.archive.org/web/20220120080053/https://www.boe.es/buscar/doc.php?id=BOE-A-2012-13644) + * [2014](https://web.archive.org/web/20201001232243/https://www.boe.es/buscar/doc.php?id=BOE-A-2013-12147) + * [2015](https://web.archive.org/web/20240915041804/https://www.boe.es/buscar/doc.php?id=BOE-A-2014-10823) + * [2016](https://web.archive.org/web/20240915044403/http://www.boe.es/buscar/doc.php?id=BOE-A-2015-11348) + * [2017](https://web.archive.org/web/20170609094105/http://www.boe.es:80/buscar/doc.php?id=BOE-A-2016-9244) + * [2018](https://web.archive.org/web/20241006073402/https://www.boe.es/buscar/doc.php?id=BOE-A-2017-11639) + * [2019](https://web.archive.org/web/20240329020330/https://boe.es/buscar/doc.php?id=BOE-A-2018-14369) + * [2020](https://web.archive.org/web/20240417060155/https://www.boe.es/buscar/doc.php?id=BOE-A-2019-14552) + * [2021](https://web.archive.org/web/20241114022913/https://www.boe.es/buscar/doc.php?id=BOE-A-2020-13343) + * [2022](https://web.archive.org/web/20240725121311/https://www.boe.es/buscar/doc.php?id=BOE-A-2021-17113) + * [2023](https://web.archive.org/web/20240811035605/https://www.boe.es/buscar/doc.php?id=BOE-A-2022-16755) + * [2024](https://web.archive.org/web/20240401192304/https://www.boe.es/buscar/doc.php?id=BOE-A-2023-22014) + * [2025](https://web.archive.org/web/20241226214918/https://www.boe.es/buscar/doc.php?id=BOE-A-2024-21316) + + Holidays checked with official sources for 2010-2025 only. + """ + + country = "ES" + default_language = "es" + # Monday following %s. + observed_label = tr("Lunes siguiente a %s") + subdivisions = ( + "AN", # Andalucía. + "AR", # Aragón. + "AS", # Asturias. + "CB", # Cantabria. + "CE", # Ceuta. + "CL", # Castilla y León. + "CM", # Castilla-La Mancha. + "CN", # Canarias. + "CT", # Cataluña (Catalunya). + "EX", # Extremadura. + "GA", # Galicia. + "IB", # Islas Baleares (Illes Balears). + "MC", # Murcia. + "MD", # Madrid. + "ML", # Melilla. + "NC", # Navarra. + "PV", # País Vasco. + "RI", # La Rioja. + "VC", # Valenciana. + ) + subdivisions_aliases = { + "Andalucía": "AN", + "Aragón": "AR", + "Asturias": "AS", + "Cantabria": "CB", + "Ceuta": "CE", + "Castilla y León": "CL", + "Castilla-La Mancha": "CM", + "Canarias": "CN", + "Cataluña": "CT", + "Catalunya": "CT", + "Extremadura": "EX", + "Galicia": "GA", + "Islas Baleares": "IB", + "Illes Balears": "IB", + "Murcia": "MC", + "Madrid": "MD", + "Melilla": "ML", + "Navarra": "NC", + "País Vasco": "PV", + "La Rioja": "RI", + "Valenciana": "VC", + } + supported_languages = ("en_US", "es", "uk") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=SpainIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, cls=SpainStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + if self._year not in {2012, 2017, 2023}: + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + if self._year not in {2013, 2019}: + # Epiphany. + self._add_epiphany_day(tr("Epifanía del Señor")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + if self._year not in {2011, 2016, 2022}: + # Labor Day. + self._add_labor_day(tr("Fiesta del Trabajo")) + + if self._year not in {2010, 2021}: + # Assumption Day. + self._add_assumption_of_mary_day(tr("Asunción de la Virgen")) + + if self._year not in {2014, 2025}: + # National Day. + self._add_holiday_oct_12(tr("Fiesta Nacional de España")) + + if self._year not in {2015, 2020}: + # All Saints' Day. + self._add_all_saints_day(tr("Todos los Santos")) + + # Constitution Day. + self._add_holiday_dec_6(tr("Día de la Constitución Española")) + + if self._year not in {2013, 2019, 2024}: + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Inmaculada Concepción")) + + if self._year not in {2011, 2016, 2022}: + # Christmas Day. + self._add_christmas_day(tr("Natividad del Señor")) + + def _populate_subdiv_an_public_holidays(self): + if self._year in {2012, 2017, 2023}: + self._move_holiday(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + # Andalusia Day. + self._move_holiday(self._add_holiday_feb_28(tr("Día de Andalucia"))) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year in {2010, 2021}: + self._move_holiday(self._add_assumption_of_mary_day(tr("Asunción de la Virgen"))) + + if self._year in {2014, 2025}: + self._move_holiday(self._add_holiday_oct_12(tr("Fiesta Nacional de España"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2013, 2019, 2024}: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_ar_public_holidays(self): + if self._year in {2012, 2017, 2023}: + self._move_holiday(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + self._add_holy_thursday(tr("Jueves Santo")) + + # Saint George's Day. + self._move_holiday(self._add_saint_georges_day(tr("Día de San Jorge"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year in {2010, 2021}: + self._move_holiday(self._add_assumption_of_mary_day(tr("Asunción de la Virgen"))) + + if self._year in {2014, 2025}: + self._move_holiday(self._add_holiday_oct_12(tr("Fiesta Nacional de España"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2013, 2019, 2024}: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_as_public_holidays(self): + if self._year in {2012, 2017, 2023}: + self._move_holiday(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year in {2010, 2021}: + self._move_holiday(self._add_assumption_of_mary_day(tr("Asunción de la Virgen"))) + + # Asturia Day. + self._move_holiday(self._add_holiday_sep_8(tr("Día de Asturias"))) + + if self._year in {2014, 2025}: + self._move_holiday(self._add_holiday_oct_12(tr("Fiesta Nacional de España"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2013, 2019, 2024}: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_cb_public_holidays(self): + if self._year == 2013: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + if self._year != 2018: + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year in {2013, 2015, 2019, 2020, 2024}: + # Easter Monday. + self._add_easter_monday(tr("Lunes de Pascua")) + + if self._year == 2011: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year in {2012, 2013, 2014, 2019, 2024}: + # Saint James' Day. + self._add_saint_james_day(tr("Santiago Apóstol")) + + if self._year not in {2012, 2015, 2019, 2024}: + # Cantabria Institutions Day. + self._add_holiday_jul_28(tr("Día de las Instituciones de Cantabria")) + + if self._year not in {2013, 2019, 2024}: + # Our Lady of the Bien Aparecida. + self._add_holiday_sep_15(tr("La Bien Aparecida")) + + if self._year == 2015: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year == 2019: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_ce_public_holidays(self): + if self._year == 2012: + self._move_holiday(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year == 2011: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year >= 2022: + # Santa Maria of Africa. + self._add_holiday_aug_5(tr("Nuestra Señora de África")) + + if self._year not in {2011, 2012, 2015, 2018, 2025}: + # Ceuta Day. + self._add_holiday_sep_2(tr("Día de Ceuta")) + + if self._year == 2014: + self._move_holiday(self._add_holiday_oct_12(tr("Fiesta Nacional de España"))) + + if self._year == 2015: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year == 2013: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2011, 2016}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + # Eid al-Adha. + name = tr("Fiesta del Sacrificio-Eidul Adha") + if self._year == 2011: + self._add_eid_al_adha_day_two(name) + elif self._year in {2012, 2014}: + self._add_eid_al_adha_day_three(name) + elif self._year >= 2010: + self._add_eid_al_adha_day(name) + + def _populate_subdiv_cl_public_holidays(self): + if self._year in {2017, 2023}: + self._move_holiday(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + if self._year in {2010, 2012}: + self._add_saint_josephs_day(tr("San José")) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year != 2023: + # Castile and León Day. + self._move_holiday(self._add_holiday_apr_23(tr("Fiesta de Castilla y León"))) + + if self._year in {2016, 2022}: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year in {2011, 2023}: + self._add_saint_james_day(tr("Santiago Apóstol")) + + if self._year == 2021: + self._move_holiday(self._add_assumption_of_mary_day(tr("Asunción de la Virgen"))) + + if self._year in {2014, 2025}: + self._move_holiday(self._add_holiday_oct_12(tr("Fiesta Nacional de España"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2013, 2019, 2024}: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_cm_public_holidays(self): + if self._year == 2013: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + if self._year in {2010, 2011, 2020}: + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("San José")) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year in {2014, 2015, 2019, 2020}: + self._add_easter_monday(tr("Lunes de Pascua")) + + if self._year not in {2010, 2018}: + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + if self._year not in {2015, 2020}: + # Castilla-La Mancha Day. + self._add_holiday_may_31(tr("Día de Castilla-La Mancha")) + + if self._year == 2015: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_cn_public_holidays(self): + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year == 2016: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year != 2021: + # Day of the Canary Islands. + self._move_holiday(self._add_holiday_may_30(tr("Día de Canarias"))) + + if self._year == 2021: + self._move_holiday(self._add_assumption_of_mary_day(tr("Asunción de la Virgen"))) + + if self._year == 2015: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year == 2020: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2011, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_ct_public_holidays(self): + self._add_easter_monday(tr("Lunes de Pascua")) + + if self._year in {2011, 2016, 2022}: + # Whit Monday. + self._add_whit_monday(tr("Día de la Pascua Granada")) + + if self._year not in {2012, 2018}: + # Saint John the Baptist. + self._add_saint_johns_day(tr("San Juan")) + + if self._year not in {2011, 2022}: + # National Day of Catalonia. + self._add_holiday_sep_11(tr("Fiesta Nacional de Cataluña")) + + if self._year not in {2010, 2021}: + # Saint Stephen's Day. + self._add_christmas_day_two(tr("San Esteban")) + + def _populate_subdiv_ex_public_holidays(self): + if self._year == 2012: + self._move_holiday(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + if self._year in {2023, 2024}: + # Shrove Tuesday. + self._add_carnival_tuesday(tr("Martes de Carnaval")) + + if self._year in {2010, 2017, 2021}: + # Saint Joseph's Day. + self._move_holiday(self._add_saint_josephs_day(tr("San José"))) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year != 2024: + # Extremadura Day. + self._move_holiday(self._add_holiday_sep_8(tr("Día de Extremadura"))) + + if self._year in {2014, 2025}: + self._move_holiday(self._add_holiday_oct_12(tr("Fiesta Nacional de España"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2013, 2019, 2024}: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_ga_public_holidays(self): + if self._year in {2010, 2011} or 2019 <= self._year <= 2021: + self._move_holiday(self._add_saint_josephs_day(tr("San José"))) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year not in {2015, 2020}: + # Galician Literature Day. + self._add_holiday_may_17(tr("Día de las Letras Gallegas")) + + if self._year in {2013, 2016, 2020, 2022}: + self._add_saint_johns_day(tr("San Juan")) + + if self._year != 2021: + # Galician National Day. + self._add_holiday_jul_25(tr("Día Nacional de Galicia")) + + if self._year == 2015: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + def _populate_subdiv_ib_public_holidays(self): + if self._year not in {2015, 2020}: + # Day of the Balearic Islands. + self._add_holiday_mar_1(tr("Día de las Islas Baleares")) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year not in {2014, 2025}: + self._add_easter_monday(tr("Lunes de Pascua")) + + if self._year == 2015: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + if self._year in {2013, 2014, 2019, 2020, 2025}: + self._add_christmas_day_two(tr("San Esteban")) + + def _populate_subdiv_mc_public_holidays(self): + if self._year in {2017, 2023}: + self._move_holiday(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + if (self._year <= 2021 and self._year != 2017) or self._year in {2024, 2025}: + self._move_holiday(self._add_saint_josephs_day(tr("San José"))) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year in {2011, 2022}: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year not in {2013, 2024}: + # Murcia Day. + self._move_holiday(self._add_holiday_jun_9(tr("Día de la Región de Murcia"))) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2013, 2024}: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_md_public_holidays(self): + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + if self._year in {2010, 2012, 2015, 2017, 2021, 2023}: + self._move_holiday(self._add_saint_josephs_day(tr("San José"))) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year != 2010: + # Madrid Day. + self._move_holiday(self._add_holiday_may_2(tr("Fiesta de la Comunidad de Madrid"))) + + if self._year in {2010, 2011, 2014}: + self._add_corpus_christi_day(tr("Corpus Christi")) + + if self._year in {2011, 2016, 2022, 2024, 2025}: + self._add_saint_james_day(tr("Santiago Apóstol")) + + if self._year == 2020: + self._move_holiday(self._add_all_saints_day(tr("Todos los Santos"))) + + if self._year == 2020: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year == 2019: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_ml_public_holidays(self): + if self._year == 2017: + self._move_holiday(self._add_new_years_day(tr("Año Nuevo"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + if self._year in {2020, 2021}: + # Statute of Autonomy of Melilla Day. + self._add_holiday_mar_13(tr("Estatuto de Autonomía de la Ciudad de Melilla")) + + if self._year <= 2016: + self._add_saint_josephs_day(tr("San José")) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2019, 2024}: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + if self._year in {2022, 2023, 2025}: + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Fiesta del Eid Fitr")) + + # Eid al-Adha. + name = tr("Fiesta del Sacrificio-Aid Al Adha") + if self._year in {2011, 2012, 2021}: + self._add_eid_al_adha_day_two(name) + elif self._year == 2022: + self._add_eid_al_adha_day_three(name) + elif self._year >= 2010: + self._add_eid_al_adha_day(name) + + def _populate_subdiv_nc_public_holidays(self): + if self._year in {2013, 2019}: + self._move_holiday(self._add_epiphany_day(tr("Epifanía del Señor"))) + + if self._year in {2010, 2012, 2014, 2015, 2019, 2020, 2021}: + self._add_saint_josephs_day(tr("San José")) + + self._add_holy_thursday(tr("Jueves Santo")) + + self._add_easter_monday(tr("Lunes de Pascua")) + + if self._year in {2011, 2013, 2015, 2016, 2017} or self._year >= 2022: + self._add_saint_james_day(tr("Santiago Apóstol")) + + if self._year == 2020: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2011, 2016, 2022}: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_pv_public_holidays(self): + if self._year in {2010, 2015, 2019, 2020, 2021}: + self._add_saint_josephs_day(tr("San José")) + + self._add_holy_thursday(tr("Jueves Santo")) + + self._add_easter_monday(tr("Lunes de Pascua")) + + if self._year not in {2010, 2012, 2014, 2018, 2021}: + self._add_saint_james_day(tr("Santiago Apóstol")) + + if 2011 <= self._year <= 2014: + # País Vasco Day. + self._add_holiday_oct_25(tr("Día del País Vasco")) + + def _populate_subdiv_ri_public_holidays(self): + if self._year in {2010, 2012}: + self._add_saint_josephs_day(tr("San José")) + + self._add_holy_thursday(tr("Jueves Santo")) + + if self._year not in {2010, 2012, 2018}: + self._add_easter_monday(tr("Lunes de Pascua")) + + # La Rioja Day. + self._move_holiday(self._add_holiday_jun_9(tr("Día de La Rioja"))) + + if self._year in {2011, 2016}: + self._add_saint_james_day(tr("Santiago Apóstol")) + + if self._year in {2015, 2020}: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year in {2013, 2019}: + self._move_holiday(self._add_immaculate_conception_day(tr("Inmaculada Concepción"))) + + if self._year == 2022: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + def _populate_subdiv_vc_public_holidays(self): + if (self._year <= 2022 and self._year != 2017) or self._year in {2024, 2025}: + self._add_saint_josephs_day(tr("San José")) + + if self._year in {2011, 2016, 2017, 2022}: + self._add_holy_thursday(tr("Jueves Santo")) + + self._add_easter_monday(tr("Lunes de Pascua")) + + if self._year == 2011: + self._move_holiday(self._add_labor_day(tr("Fiesta del Trabajo"))) + + if self._year >= 2019: + self._add_saint_johns_day(tr("San Juan")) + + if self._year not in {2011, 2016, 2022}: + # Valencian Community Day. + self._add_holiday_oct_9(tr("Día de la Comunidad Valenciana")) + + if self._year == 2015: + self._move_holiday(self._add_holiday_dec_6(tr("Día de la Constitución Española"))) + + if self._year == 2016: + self._move_holiday(self._add_christmas_day(tr("Natividad del Señor"))) + + +class ES(Spain): + pass + + +class ESP(Spain): + pass + + +class SpainIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2010: (NOV, 17), + 2011: (NOV, 6), + 2012: (OCT, 25), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 25), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 2022: (MAY, 3), + 2023: (APR, 21), + 2025: (MAR, 31), + } + + +class SpainStaticHolidays: + special_ga_public_holidays = { + # Day following Saint Joseph's Day. + 2015: (MAR, 20, tr("Día siguiente a San José")), + } + + special_md_public_holidays = { + # Saint Joseph's Day Transfer. + 2013: (MAR, 18, tr("Traslado de San José")), + } + + special_pv_public_holidays = { + # 80th Anniversary of the first Basque Government. + 2016: (OCT, 7, tr("80 Aniversario del primer Gobierno Vasco")), + # V Centennial of the Circumnavigation of the World. + 2022: (SEP, 6, tr("V Centenario Vuelta al Mundo")), + } + + special_vc_public_holidays = { + # The Fallas. + 2013: (MAR, 18, tr("Lunes de Fallas")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/sri_lanka.py b/.venv/lib/python3.12/site-packages/holidays/countries/sri_lanka.py new file mode 100644 index 00000000..9dd66a31 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/sri_lanka.py @@ -0,0 +1,525 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomHinduHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + _timedelta, +) +from holidays.constants import BANK, GOVERNMENT, PUBLIC, WORKDAY +from holidays.groups import ( + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + SinhalaCalendarHolidays, + StaticHolidays, +) +from holidays.holiday_base import HolidayBase + + +class SriLanka( + HolidayBase, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, + SinhalaCalendarHolidays, + StaticHolidays, +): + """Sri Lanka holidays. + + References: + * [No. 29 of 1971 (Holidays Act)](https://web.archive.org/web/20250315041521/http://www.commonlii.org/lk/legis/num_act/ha29o1971152/) + * [No. 21 of 1991 (Amendment)](https://web.archive.org/web/20200221094206/http://www.commonlii.org:80/lk/legis/num_act/ha21o1991232/) + * + * + * + + Cross-Checked With: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + """ + + country = "LK" + supported_categories = (BANK, GOVERNMENT, PUBLIC, WORKDAY) + default_language = "si_LK" + # %s (estimated). + estimated_label = tr("%s (අනුමානිත)") + supported_languages = ("en_US", "si_LK", "ta_LK") + # Sri Lanka's Holidays Act (No. 29 of 1971) was first proclaimed on SEP 2nd, 1971 + # but the earliest citable calendar online is from 2003. + # As there's no source for future Poya dates, end year is capped at 2025. + start_year = 1972 + end_year = 2025 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, SriLankaHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=SriLankaIslamicHolidays, show_estimated=islamic_show_estimated + ) + SinhalaCalendarHolidays.__init__(self) + StaticHolidays.__init__(self, cls=SriLankaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Non-Sectarian Holidays. + + # Tamil Thai Pongal Day. + name = tr("දෙමළ තෛපොංැලල් දිනය") + thai_pongal_years_jan_14 = { + 2005, + 2006, + 2009, + 2010, + 2013, + 2014, + 2017, + 2018, + 2021, + 2022, + 2025, + } + if self._year in thai_pongal_years_jan_14: + self._add_holiday_jan_14(name) + else: + self._add_holiday_jan_15(name) + + # Independence Day. + self._add_holiday_feb_4(tr("නිදහස් සමරු දිනය")) + + # Sinhala and Tamil New Year. + name = tr("සිංහල හා දෙමළ අලුත් අවුරුදු දිනය") + aluth_avurudda_years_apr_13 = { + 2004, + 2008, + 2012, + # 2016 is on APR, 14. + 2020, + 2024, + } + if self._year in aluth_avurudda_years_apr_13: + dt = self._add_holiday_apr_13(name) + else: + dt = self._add_holiday_apr_14(name) + # Day Before Sinhala and Tamil New Year. + self._add_holiday(tr("සිංහල හා දෙමළ අලුත් අවුරුදු දිනට පෙර දිනය"), _timedelta(dt, -1)) + + # International Workers' Day. + self._add_labor_day(tr("ලොක කම්කරු දිනය")) + + # Hindu Holidays. + + maha_sivarathri_dates = { + # The one used in Sri Lanka isn't an exact match with India, used with caution. + 2003: (MAR, 1), + 2004: (FEB, 18), + 2005: (MAR, 8), + 2006: (FEB, 26), + 2007: (FEB, 16), + 2008: (MAR, 6), + 2009: (FEB, 23), + 2010: (MAR, 13), + 2011: (MAR, 2), + 2012: (FEB, 20), + 2013: (MAR, 10), + 2014: (FEB, 27), + 2015: (FEB, 17), + 2016: (MAR, 7), + 2017: (FEB, 24), + 2018: (FEB, 13), + 2019: (MAR, 4), + 2020: (FEB, 21), + 2021: (MAR, 11), + 2022: (MAR, 1), + 2023: (FEB, 18), + 2024: (MAR, 8), + 2025: (FEB, 26), + } + maha_sivarathri_date = maha_sivarathri_dates.get(self._year) + if maha_sivarathri_date: + # Maha Sivarathri Day. + self._add_holiday(tr("මහ සිවරාත්රි දිනය"), maha_sivarathri_date) + + # Deepavali was a working day in 2003. + if self._year >= 2004: + # Deepavali Festival Day. + self._add_diwali(tr("දීපවාලි උත්සව දිනය")) + + # Christian Holidays. + + # Good Friday. + self._add_good_friday(tr("මහ සිකුරාදා දිනය")) + + # Christmas Day. + self._add_christmas_day(tr("නත්තල් උත්සව දිනය")) + + # Poya Holidays. + # All Adhi Poya Holidays will instead be added in StaticHolidays. + + # Duruthu Full Moon Poya Day. + self._add_duruthu_poya(tr("දුරුතු පුර පසළොස්වක පෝය දිනය")) + + # Nawam Full Moon Poya Day. + self._add_nawam_poya(tr("නවම් පුර පසළොස්වක පෝය දිනය")) + + # Medin Full Moon Poya Day. + self._add_medin_poya(tr("මැදින් පුර පසළොස්වක පෝය දිනය")) + + # Bak Full Moon Poya Day. + self._add_bak_poya(tr("බක් පුර පසළොස්වක පෝය දිනය")) + + # Vesak Full Moon Poya Day. + dt = self._add_vesak_poya(tr("වෙසක් පුර පසළොස්වක පෝය දිනය")) + + if self._year >= 2003: + # Day Following Vesak Full Moon Poya Day. + self._add_holiday(tr("වෙසක් පුර පසළොස්වක පෝය දිනට පසු දිනය"), _timedelta(dt, +1)) + + # Poson Full Moon Poya Day. + self._add_poson_poya(tr("පොසොන් පුර පසළොස්වක පෝය දිනය")) + + # Esala Full Moon Poya Day. + self._add_esala_poya(tr("ඇසල පුර පසළොස්වක පෝය දිනය")) + + # Nikini Full Moon Poya Day. + self._add_nikini_poya(tr("නිකිණි පුර පසළොස්වක පෝය දිනය")) + + # Binara Full Moon Poya Day. + self._add_binara_poya(tr("බිනර පුර පසළොස්වක පෝය දිනය")) + + # Vap Full Moon Poya Day. + self._add_vap_poya(tr("වප් පුර පසළොස්වක පෝය දිනය")) + + # Il Full Moon Poya Day. + self._add_il_poya(tr("ඉල් පුර පසළොස්වක පෝය දිනය")) + + # Unduvap Full Moon Poya Day. + self._add_unduvap_poya(tr("උඳුවප් පුර පසළොස්වක පෝය දිනය")) + + # Islamic Holidays. + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("ඊදුල් ෆීතර්")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("ඊදුල් අල්හා")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("නබි නායකතුමාගේ උපන් දිනය")) + + +class LK(SriLanka): + pass + + +class LKA(SriLanka): + pass + + +class SriLankaHinduHolidays(_CustomHinduHolidays): + DIWALI_DATES = { + 2003: (OCT, 24), + 2004: (NOV, 11), + 2005: (NOV, 1), + 2006: (OCT, 21), + 2007: (NOV, 8), + 2008: (OCT, 27), + 2009: (OCT, 17), + 2010: (NOV, 5), + 2011: (OCT, 26), + 2012: (NOV, 13), + 2013: (NOV, 2), + 2014: (OCT, 22), + 2015: (NOV, 10), + 2016: (OCT, 29), + 2017: (OCT, 18), + 2018: (NOV, 6), + 2019: (OCT, 27), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 24), + 2023: (NOV, 12), + 2024: (OCT, 31), + 2025: (OCT, 20), + } + + +class SriLankaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2003: (FEB, 12), + 2004: (FEB, 1), + 2005: (JAN, 21), + 2006: ((JAN, 11), (DEC, 31)), + 2007: (DEC, 21), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + # https://web.archive.org/web/20111103102902/http://www.adaderana.lk:80/news.php?nid=15606 + 2011: (NOV, 7), + # https://web.archive.org/web/20121029024049/http://www.adaderana.lk:80/news.php?nid=20136 + 2012: (OCT, 27), + 2013: (OCT, 16), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 12), + 2020: (AUG, 1), + 2021: (JUL, 21), + 2022: (JUL, 10), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 1), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 9), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 6), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 25), + 2021: (MAY, 14), + 2022: (MAY, 3), + 2023: (APR, 22), + 2024: (APR, 11), + 2025: (MAR, 31), + } + + MAWLID_DATES = { + 2003: (MAY, 14), + 2004: (MAY, 2), + 2005: (APR, 22), + 2006: (APR, 11), + 2007: (APR, 1), + 2008: (MAR, 20), + 2009: (MAR, 10), + 2010: (FEB, 27), + 2011: (FEB, 16), + 2012: (FEB, 5), + 2013: (JAN, 25), + 2014: (JAN, 14), + # Technically 2015 has both JAN 5 and DEC 24 + # but this is only observed for JAN 4. + 2015: (JAN, 4), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 20), + 2019: (NOV, 10), + 2020: (OCT, 30), + 2021: (OCT, 19), + 2022: (OCT, 9), + 2023: (SEP, 28), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + +class SriLankaStaticHolidays: + """Sri Lanka special holdays. + + References: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + """ + + # Adhi Binara Full Moon Poya Day. + adhi_binara_poya_name = tr("අධි බිනර පුර පසළොස්වක පෝය දිනය") + + # Adhi Esala Full Moon Poya Day. + adhi_esala_poya_name = tr("අධි ඇසල පුර පසළොස්වක පෝය දිනය") + + # Adhi Poson Full Moon Poya Day. + adhi_poson_poya_name = tr("අධි පොසොන් පුර පසළොස්වක පෝය දිනය") + + # Adhi Vap Full Moon Poya Day. + adhi_vap_poya_name = tr("අධි වප් පුර පසළොස්වක පෝය දිනය") + + # Adhi Vesak Full Mon Poya Day. + adhi_vesak_poya_name = tr("අධි වෙසක් පුර පසළොස්වක පෝය දිනය") + + # Half-Day Special Bank Holiday. + half_day_special_bank_holiday_name = tr("දින භාගයක විශේෂ බැංකු නිවාඩු දිනය") + + # Public Sector Holiday. + public_sector_holiday_name = tr("රාජ්ය අංශයේ නිවාඩු දිනය") + + # Special Bank Holiday. + special_bank_holiday_name = tr("විශේෂ බැංකු නිවාඩු දිනය") + + # Special Public Holiday. + special_public_holiday_name = tr("විශේෂ රජයේ නිවාඩු දිනය") + + special_bank_holidays = { + 2005: ( + (MAY, 2, special_bank_holiday_name), + (DEC, 26, special_bank_holiday_name), + ), + 2007: ( + (FEB, 5, special_bank_holiday_name), + (APR, 3, special_bank_holiday_name), + ), + 2008: (APR, 18, special_bank_holiday_name), + 2011: ( + (MAY, 2, special_bank_holiday_name), + (DEC, 26, special_bank_holiday_name), + ), + 2012: ( + (JAN, 16, special_bank_holiday_name), + (FEB, 10, special_bank_holiday_name), + (MAY, 7, special_bank_holiday_name), + ), + 2013: (APR, 15, special_bank_holiday_name), + 2014: (APR, 15, special_bank_holiday_name), + 2015: (JAN, 5, special_bank_holiday_name), + 2016: ( + (MAY, 2, special_bank_holiday_name), + (MAY, 23, special_bank_holiday_name), + (DEC, 26, special_bank_holiday_name), + ), + 2018: ( + (JAN, 15, special_bank_holiday_name), + (FEB, 5, special_bank_holiday_name), + ), + 2019: ( + (APR, 15, special_bank_holiday_name), + # MAY 20 got upgraded to Special Public Holiday. + (NOV, 11, special_bank_holiday_name), + ), + 2020: (APR, 14, special_bank_holiday_name), + 2021: ( + (APR, 30, half_day_special_bank_holiday_name), + (DEC, 24, half_day_special_bank_holiday_name), + ), + 2022: ( + # MAY 2 got upgraded to Special Public Holiday. + (OCT, 10, special_bank_holiday_name), + (DEC, 26, special_bank_holiday_name), + ), + 2023: (JAN, 16, special_bank_holiday_name), + 2025: (APR, 15, special_bank_holiday_name), + } + + special_government_holidays = { + 2020: (JUN, 4, public_sector_holiday_name), + 2022: ( + (JUN, 13, public_sector_holiday_name), + # All Friday between JUN 15, 2022 to AUG 2, 2022. + (JUN, 17, public_sector_holiday_name), + (JUN, 24, public_sector_holiday_name), + (JUL, 1, public_sector_holiday_name), + (JUL, 8, public_sector_holiday_name), + (JUL, 15, public_sector_holiday_name), + (JUL, 22, public_sector_holiday_name), + (JUL, 29, public_sector_holiday_name), + ), + } + + special_public_holidays = { + 2004: (JUL, 31, adhi_esala_poya_name), + 2007: (MAY, 31, adhi_poson_poya_name), + 2010: (APR, 28, adhi_vesak_poya_name), + # 2011, MAY 2 confirmed as not getting upgrade to Special Public Holiday. + 2012: ( + (MAY, 7, special_public_holiday_name), + (AUG, 31, adhi_binara_poya_name), + ), + 2013: (APR, 15, special_public_holiday_name), + 2015: (JUL, 1, adhi_esala_poya_name), + 2016: (APR, 15, special_public_holiday_name), + 2018: (MAY, 29, adhi_poson_poya_name), + 2019: (MAY, 20, special_public_holiday_name), + 2020: ( + (MAR, 16, special_public_holiday_name), + (MAR, 17, special_public_holiday_name), + (MAR, 18, special_public_holiday_name), + (MAR, 19, special_public_holiday_name), + (OCT, 1, adhi_vap_poya_name), + ), + 2022: ( + (APR, 11, special_public_holiday_name), + (APR, 12, special_public_holiday_name), + (MAY, 2, special_public_holiday_name), + ), + 2023: (JUL, 3, adhi_esala_poya_name), + 2024: ( + (APR, 15, special_public_holiday_name), + (SEP, 29, special_public_holiday_name), + ), + } + + special_workday_holidays = { + 2003: (OCT, 24, tr("දීපවාලි උත්සව දිනය")), # Deepavali Festival Day. + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/suriname.py b/.venv/lib/python3.12/site-packages/holidays/countries/suriname.py new file mode 100644 index 00000000..01b4c85b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/suriname.py @@ -0,0 +1,227 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays import HolidayBase +from holidays.calendars import _CustomHinduHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV +from holidays.groups import ( + ChineseCalendarHolidays, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, +) + + +class Suriname( + HolidayBase, + ChineseCalendarHolidays, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, +): + """Suriname holidays. + + References: + * [Besluit Vrije Dagen 1971](https://web.archive.org/web/20250411201210/https://www.sris.sr/wp-content/uploads/2022/10/Besluit-Vrije-dagen-GB-1971-no-78.pdf) + * https://web.archive.org/web/20240416223555/https://gov.sr/wp-content/uploads/2022/09/arbeidswet.pdf + * [S.B. 2007 no. 98](https://web.archive.org/web/20250411204836/https://www.sris.sr/wp-content/uploads/2021/10/SB-2007-no-98-besluit-vrije-dagen.pdf) + * [S.B. 2012 no. 21](https://web.archive.org/web/20250411204754/https://www.sris.sr/wp-content/uploads/2021/10/SB-2012-no-21-besluit-vrije-dagen.pdf) + * [S.B. 2021 no. 27](https://web.archive.org/web/20250411210516/https://www.sris.sr/wp-content/uploads/2021/03/S.B.-2021-no.-27-houdende-nadere-wijziging-van-het-Besluit-Vrije-Dagen-1971.pdf) + * [S.B. 2024 no. 167](https://web.archive.org/web/20250411211129/https://www.sris.sr/wp-content/uploads/2025/01/S.B.-2024-no.-167-Algemene-termijnenwet.pdf) + + Note: + The oldest decree available online that underpins the public holidays defined here + for Suriname is Besluit Vrije Dagen 1971 of April 22, 1971. + + The S.B. 2024 no. 167 law only applies to prolongations of terms specified in contracts + and other similar legal documents, and does not apply to labor agreements (and days off). + """ + + country = "SR" + default_language = "nl" + # %s (estimated). + estimated_label = tr("%s (geschat)") + start_year = 1972 + supported_languages = ("en_US", "nl") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChineseCalendarHolidays.__init__(self) + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=SurinameHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=SurinameIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nieuwjaarsdag")) + + if 1981 <= self._year <= 1992 or 2012 <= self._year <= 2020: + # Day of Liberation and Renewal. + self._add_holiday_feb_25(tr("Dag van Bevrijding en Vernieuwing")) + + # Good Friday. + self._add_good_friday(tr("Goede Vrijdag")) + + # Easter Monday. + self._add_easter_monday(tr("Tweede Paasdag")) + + if self._year <= 1975: + # Birthday of H.M. the Queen. + self._add_holiday_apr_30(tr("Verjaardag van H.M. de Koningin")) + + # Labor Day. + self._add_labor_day(tr("Dag van de Arbeid")) + + self._add_holiday_jul_1( + # Day of Freedoms. + tr("Keti Koti Dey") if 2008 <= self._year <= 2024 else tr("Dag der Vrijheden") + ) + + if self._year >= 2007: + # Indigenous People Day. + self._add_holiday_aug_9(tr("Dag der Inheemsen")) + + if self._year >= 2012: + # Day of the Maroons. + self._add_holiday_oct_10(tr("Dag der Marrons")) + + if self._year >= 1976: + name = ( + # Independence Day. + tr("Onafhankelijkheidsdag") + if self._year >= 2008 + # Republic Day. + else tr("Dag van de Republiek") + ) + self._add_holiday_nov_25(name) + + # Christmas Day. + self._add_christmas_day(tr("Eerste Kerstdag")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Tweede Kerstdag")) + + # Holi. + self._add_holi(tr("Holi-Phagwa")) + + if self._year >= 2012: + # Diwali. + self._add_diwali(tr("Divali")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Ied-Ul-Fitre")) + + if self._year >= 2012: + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Ied-Ul-Adha")) + + if self._year >= 2022: + # Chinese New Year. + self._add_chinese_new_years_day(tr("Chinees Nieuwjaar")) + + +class SurinameHinduHolidays(_CustomHinduHolidays): + # https://web.archive.org/web/20241104221047/https://www.timeanddate.com/holidays/suriname/holi-phagwa + HOLI_DATES = { + 2015: (MAR, 6), + 2016: (MAR, 23), + 2017: (MAR, 12), + 2018: (MAR, 2), + 2019: (MAR, 21), + 2020: (MAR, 9), + 2021: (MAR, 28), + 2022: (MAR, 18), + 2023: (MAR, 7), + 2024: (MAR, 25), + 2025: (MAR, 14), + 2026: (MAR, 3), + 2027: (MAR, 22), + 2028: (MAR, 11), + 2029: (MAR, 28), + 2030: (MAR, 19), + } + + # https://web.archive.org/web/20241105043434/https://www.timeanddate.com/holidays/suriname/diwali + DIWALI_DATES = { + 2014: (OCT, 23), + 2015: (NOV, 11), + 2016: (OCT, 30), + 2017: (OCT, 19), + 2018: (NOV, 7), + 2019: (OCT, 27), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 24), + 2023: (NOV, 12), + 2024: (OCT, 31), + 2025: (OCT, 20), + 2026: (NOV, 8), + 2027: (OCT, 28), + 2028: (OCT, 17), + 2029: (NOV, 5), + 2030: (OCT, 25), + } + + +class SurinameIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20241107062349/https://www.timeanddate.com/holidays/suriname/eid-al-fitr + EID_AL_FITR_DATES = { + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + # https://web.archive.org/web/20241113121535/https://www.timeanddate.com/holidays/suriname/eid-al-adha + EID_AL_ADHA_DATES = { + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 21), + 2019: (AUG, 12), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 29), + 2024: (JUN, 16), + 2025: (JUN, 7), + } + + +class SR(Suriname): + pass + + +class SUR(Suriname): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/svalbard_and_jan_mayen.py b/.venv/lib/python3.12/site-packages/holidays/countries/svalbard_and_jan_mayen.py new file mode 100644 index 00000000..4298899d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/svalbard_and_jan_mayen.py @@ -0,0 +1,41 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.norway import Norway +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysSJ(ChildEntity, Norway): + """Svalbard and Jan Mayen holidays. + + Alias of Norwegian subdivisions that are also officially assigned + its own country code in ISO 3166-1. + + References: + * + """ + + country = "SJ" + parent_entity = Norway + parent_entity_subdivision_code = "21" + + +class SvalbardAndJanMayen(HolidaysSJ): + pass + + +class SJ(HolidaysSJ): + pass + + +class SJM(HolidaysSJ): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/sweden.py b/.venv/lib/python3.12/site-packages/holidays/countries/sweden.py new file mode 100644 index 00000000..6092dc3c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/sweden.py @@ -0,0 +1,130 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import _timedelta, _get_all_sundays +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Sweden(HolidayBase, ChristianHolidays, InternationalHolidays): + """Sweden holidays. + + References: + * + * + * + * + * + + + Note that holidays falling on a sunday is "lost", it will not be moved + to another day to make up for the collision. + + In Sweden, ALL sundays are considered a holiday. + Initialize this class with `include_sundays=False` to not include sundays as a holiday. + """ + + country = "SE" + default_language = "sv" + supported_languages = ("en_US", "sv", "th", "uk") + + def __init__(self, include_sundays: bool = True, *args, **kwargs): + """ + Args: + include_sundays: + Whether to consider sundays as a holiday (which they are in Sweden) + """ + self.include_sundays = include_sundays + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Nyårsdagen")) + + # Epiphany. + self._add_epiphany_day(tr("Trettondedag jul")) + + if self._year <= 1953: + # Feast of the Annunciation. + self._add_holiday_mar_25(tr("Jungfru Marie bebådelsedag")) + + # Good Friday. + self._add_good_friday(tr("Långfredagen")) + + # Easter Sunday. + self._add_easter_sunday(tr("Påskdagen")) + + # Easter Monday. + self._add_easter_monday(tr("Annandag påsk")) + + if self._year >= 1939: + # May Day. + self._add_labor_day(tr("Första maj")) + + # Ascension Day. + self._add_ascension_thursday(tr("Kristi himmelsfärdsdag")) + + if self._year >= 2005: + # National Day of Sweden. + self._add_holiday_jun_6(tr("Sveriges nationaldag")) + + # Whit Sunday. + self._add_whit_sunday(tr("Pingstdagen")) + + if self._year <= 2004: + # Whit Monday. + self._add_whit_monday(tr("Annandag pingst")) + + # Midsummer Eve. + name = tr("Midsommarafton") + dt = ( + self._add_holiday_1st_fri_from_jun_19(name) + if self._year >= 1953 + else self._add_holiday_jun_23(name) + ) + + # Midsummer Day. + self._add_holiday(tr("Midsommardagen"), _timedelta(dt, +1)) + + if self._year >= 1953: + # All Saints' Day. + self._add_holiday_1st_sat_from_oct_31(tr("Alla helgons dag")) + + # Christmas Eve. + self._add_christmas_eve(tr("Julafton")) + + # Christmas Day. + self._add_christmas_day(tr("Juldagen")) + + # Second Day of Christmas. + self._add_christmas_day_two(tr("Annandag jul")) + + # New Year's Eve. + self._add_new_years_eve(tr("Nyårsafton")) + + # Optionally add all Sundays of the year. + if self.include_sundays: + for dt in _get_all_sundays(self._year): + # Sunday. + self._add_holiday(tr("Söndag"), dt) + + +class SE(Sweden): + pass + + +class SWE(Sweden): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/switzerland.py b/.venv/lib/python3.12/site-packages/holidays/countries/switzerland.py new file mode 100644 index 00000000..5558c938 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/switzerland.py @@ -0,0 +1,559 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import APR, THU, _timedelta, _get_nth_weekday_of_month +from holidays.constants import HALF_DAY, OPTIONAL, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, MON_ONLY, TUE_TO_NONE, SAT_TO_NONE + + +class Switzerland(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Switzerland holidays. + + References: + * + * + * + """ + + country = "CH" + default_language = "de" + start_year = 1801 + subdivisions = ( + "AG", # Aargau. + "AI", # Appenzell Innerrhoden. + "AR", # Appenzell Ausserrhoden. + "BE", # Bern (Berne). + "BL", # Basel-Landschaft. + "BS", # Basel-Stadt. + "FR", # Freiburg (Fribourg). + "GE", # Genève. + "GL", # Glarus. + "GR", # Graubünden (Grigioni, Grischun). + "JU", # Jura. + "LU", # Luzern. + "NE", # Neuchâtel. + "NW", # Nidwalden. + "OW", # Obwalden. + "SG", # Sankt Gallen. + "SH", # Schaffhausen. + "SO", # Solothurn. + "SZ", # Schwyz. + "TG", # Thurgau. + "TI", # Ticino. + "UR", # Uri. + "VD", # Vaud. + "VS", # Valais (Wallis). + "ZG", # Zug. + "ZH", # Zürich. + ) + subdivisions_aliases = { + "Aargau": "AG", + "Appenzell Innerrhoden": "AI", + "Appenzell Ausserrhoden": "AR", + "Bern": "BE", + "Berne": "BE", + "Basel-Landschaft": "BL", + "Basel-Stadt": "BS", + "Freiburg": "FR", + "Fribourg": "FR", + "Genève": "GE", + "Glarus": "GL", + "Graubünden": "GR", + "Grigioni": "GR", + "Grischun": "GR", + "Jura": "JU", + "Luzern": "LU", + "Neuchâtel": "NE", + "Nidwalden": "NW", + "Obwalden": "OW", + "Sankt Gallen": "SG", + "Schaffhausen": "SH", + "Solothurn": "SO", + "Schwyz": "SZ", + "Thurgau": "TG", + "Ticino": "TI", + "Uri": "UR", + "Vaud": "VD", + "Valais": "VS", + "Wallis": "VS", + "Zug": "ZG", + "Zürich": "ZH", + } + supported_categories = (HALF_DAY, OPTIONAL, PUBLIC) + supported_languages = ("de", "en_US", "fr", "it", "uk") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Neujahrstag")) + + # Ascension Day. + self._add_ascension_thursday(tr("Auffahrt")) + + # National Day. + self._add_holiday_aug_1(tr("Nationalfeiertag")) + + # Christmas Day. + self._add_christmas_day(tr("Weihnachten")) + + def _populate_subdiv_ag_public_holidays(self): + # Saint Berchtold's Day. + self._add_new_years_day_two(tr("Berchtoldstag")) + + # Good Friday. + self._add_good_friday(tr("Karfreitag")) + + # Easter Monday. + self._add_easter_monday(tr("Ostermontag")) + + # Labor Day. + self._add_labor_day(tr("Tag der Arbeit")) + + # Whit Monday. + self._add_whit_monday(tr("Pfingstmontag")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Fronleichnam")) + + # Assumption Day. + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + # All Saints' Day. + self._add_all_saints_day(tr("Allerheiligen")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_ar_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_observed( + self._add_christmas_day_two(tr("Stephanstag")), rule=TUE_TO_NONE + SAT_TO_NONE + ) + + def _populate_subdiv_ai_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + self._add_observed( + self._add_christmas_day_two(tr("Stephanstag")), rule=TUE_TO_NONE + SAT_TO_NONE + ) + + def _populate_subdiv_bl_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_labor_day(tr("Tag der Arbeit")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_bs_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_labor_day(tr("Tag der Arbeit")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_be_public_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_fr_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + def _populate_subdiv_fr_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_ge_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + # Genevan Fast. + self._add_holiday_4_days_past_1st_sun_of_sep(tr("Genfer Bettag")) + + # Restoration Day. + self._add_holiday_dec_31(tr("Wiederherstellung der Republik")) + + def _populate_subdiv_gl_public_holidays(self): + # Näfelser Fahrt (first Thursday in April but not in Holy Week) + if self._year >= 1835: + dt = _get_nth_weekday_of_month(1, THU, APR, self._year) + self._add_holiday( + # Battle of Naefels Victory Day. + tr("Näfelser Fahrt"), + _timedelta(dt, +7) if dt == _timedelta(self._easter_sunday, -3) else dt, + ) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_gl_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + def _populate_subdiv_gr_public_holidays(self): + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_gr_optional_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + def _populate_subdiv_ju_public_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_labor_day(tr("Tag der Arbeit")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + # Independence Day. + self._add_holiday_jun_23(tr("Fest der Unabhängigkeit")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + def _populate_subdiv_lu_public_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_ne_public_holidays(self): + self._add_observed( + self._add_new_years_day_two(tr("Berchtoldstag")), + rule=MON_ONLY, # Jan 2 is public holiday only when it falls on Monday. + ) + + # Republic Day. + self._add_holiday_mar_1(tr("Jahrestag der Ausrufung der Republik")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_labor_day(tr("Tag der Arbeit")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_observed(self._add_christmas_day_two(tr("Stephanstag")), rule=MON_ONLY) + + def _populate_subdiv_nw_public_holidays(self): + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("Josefstag")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + def _populate_subdiv_nw_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_ow_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + # Saint Nicholas of Flüe. + self._add_holiday_sep_25(tr("Bruder Klaus")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + def _populate_subdiv_ow_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_sg_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_sg_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + def _populate_subdiv_sh_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_labor_day(tr("Tag der Arbeit")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_sh_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + def _populate_subdiv_sz_public_holidays(self): + # Epiphany. + self._add_epiphany_day(tr("Heilige Drei Könige")) + + self._add_saint_josephs_day(tr("Josefstag")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_so_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + def _populate_subdiv_so_half_day_holidays(self): + self._add_labor_day(tr("Tag der Arbeit")) + + def _populate_subdiv_so_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + def _populate_subdiv_tg_public_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_labor_day(tr("Tag der Arbeit")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_ti_public_holidays(self): + self._add_epiphany_day(tr("Heilige Drei Könige")) + + self._add_saint_josephs_day(tr("Josefstag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_labor_day(tr("Tag der Arbeit")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + # Saints Peter and Paul. + self._add_saints_peter_and_paul_day(tr("Peter und Paul")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_ur_public_holidays(self): + self._add_epiphany_day(tr("Heilige Drei Könige")) + + self._add_saint_josephs_day(tr("Josefstag")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + self._add_observed( + self._add_christmas_day_two(tr("Stephanstag")), rule=TUE_TO_NONE + SAT_TO_NONE + ) + + def _populate_subdiv_vd_public_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + # Prayer Monday. + self._add_holiday_1_day_past_3rd_sun_of_sep(tr("Bettagsmontag")) + + def _populate_subdiv_vs_public_holidays(self): + self._add_saint_josephs_day(tr("Josefstag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + def _populate_subdiv_vs_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_zg_public_holidays(self): + self._add_good_friday(tr("Karfreitag")) + + self._add_corpus_christi_day(tr("Fronleichnam")) + + self._add_assumption_of_mary_day(tr("Mariä Himmelfahrt")) + + self._add_all_saints_day(tr("Allerheiligen")) + + self._add_immaculate_conception_day(tr("Mariä Empfängnis")) + + def _populate_subdiv_zg_optional_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + def _populate_subdiv_zh_public_holidays(self): + self._add_new_years_day_two(tr("Berchtoldstag")) + + self._add_good_friday(tr("Karfreitag")) + + self._add_easter_monday(tr("Ostermontag")) + + self._add_labor_day(tr("Tag der Arbeit")) + + self._add_whit_monday(tr("Pfingstmontag")) + + self._add_christmas_day_two(tr("Stephanstag")) + + +class CH(Switzerland): + pass + + +class CHE(Switzerland): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/taiwan.py b/.venv/lib/python3.12/site-packages/holidays/countries/taiwan.py new file mode 100644 index 00000000..bbbcc992 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/taiwan.py @@ -0,0 +1,437 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr +from typing import Optional + +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + SEP, + OCT, + DEC, + MON, + TUE, + WED, + THU, + FRI, + SAT, + SUN, +) +from holidays.constants import GOVERNMENT, OPTIONAL, PUBLIC, SCHOOL, WORKDAY +from holidays.groups import ChineseCalendarHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + ObservedRule, + SAT_TO_PREV_WORKDAY, + SUN_TO_NEXT_WORKDAY, + SAT_SUN_TO_NEXT_WORKDAY, +) + +CHILDRENS_DAY_RULE = ObservedRule({MON: +1, TUE: -1, WED: -1, THU: +1, FRI: -1, SAT: -1, SUN: -2}) + + +class Taiwan(ObservedHolidayBase, ChineseCalendarHolidays, InternationalHolidays, StaticHolidays): + """Taiwan holidays. + + References: + * + * + + Commemorative Day and Day Implementation Method Amendments: + * [Ministry of Interior (87) Order No. 8706459](https://web.archive.org/web/20250501035936/https://zh.wikisource.org/wiki/紀念日及節日實施辦法_(民國87年)) + * [Ministry of Interior (88) Order No. 8897074](https://web.archive.org/web/20250429134107/https://zh.wikisource.org/wiki/紀念日及節日實施辦法_(民國88年)) + * [Ministry of Interior (89) Order No. 8972185](https://web.archive.org/web/20250429134119/https://zh.wikisource.org/wiki/紀念日及節日實施辦法_(民國89年2月)) + * [Ministry of Interior (89) Order No. 8962562](https://web.archive.org/web/20250429134023/https://zh.wikisource.org/wiki/紀念日及節日實施辦法_(民國89年12月)) + * [Ministry of Interior Order No. 0950045320](https://web.archive.org/web/20240916001724/https://law.moj.gov.tw/LawClass/LawOldVer.aspx?pcode=D0020033&lnndate=20060309&lser=001) + * [Ministry of Interior Order No. 0960110433](https://web.archive.org/web/20240915222212/https://law.moj.gov.tw/LawClass/LawOldVer.aspx?pcode=D0020033&lnndate=20070711&lser=001) + * [Ministry of Interior Order No. 0960131407](https://web.archive.org/web/20240915222212/https://law.moj.gov.tw/LawClass/LawOldVer.aspx?pcode=D0020033&lnndate=20070711&lser=001) + * [Ministry of Interior Order No. 0960155673](https://web.archive.org/web/20240916000901/https://law.moj.gov.tw/LawClass/LawOldVer.aspx?pcode=D0020033&lnndate=20071003&lser=001) + * [Ministry of Interior Order No. 0990212117](https://web.archive.org/web/20240916004712/https://law.moj.gov.tw/LawClass/LawOldVer.aspx?pcode=D0020033&lnndate=20101102&lser=001) + * [Ministry of Interior Order No. 1010307327 and 1030128812](https://web.archive.org/web/20240919205138/https://law.moj.gov.tw/LawClass/LawOldVer.aspx?pcode=D0020033&lnndate=20120925&lser=001) + * [Ministry of Interior Order No. 1030182404](https://web.archive.org/web/20250227171607/https://law.moj.gov.tw/LawClass/LawAll.aspx?pcode=D0020033) + * [Decree No. 11400053171](https://web.archive.org/web/20250602210918/https://law.moj.gov.tw/News/newsdetail.aspx?msgid=191745) + + Checked With: + * [DGPA Work Calendar (1998-2025; Chinese)](https://web.archive.org/web/20250307201828/https://www.dgpa.gov.tw/informationlist?uid=30) + * [DGPA Work Calendar (2001-2025; English)](https://web.archive.org/web/20240606012108/http://www.dgpa.gov.tw/en/informationlist?uid=353) + """ + + country = "TW" + # %s (observed). + observed_label = tr("%s(慶祝)") + default_language = "zh_TW" + supported_categories = (GOVERNMENT, OPTIONAL, PUBLIC, SCHOOL, WORKDAY) + supported_languages = ("en_US", "th", "zh_CN", "zh_TW") + # Ministry of Interior (87) Order No. 8706459. + start_year = 1998 + + def __init__(self, *args, **kwargs): + ChineseCalendarHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, TaiwanStaticHolidays) + kwargs.setdefault("observed_rule", SAT_TO_PREV_WORKDAY + SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _populate_observed( + self, dts: set[date], rule: Optional[ObservedRule] = None, since: int = 2015 + ) -> None: + """ + Taiwan's General Observance Rule first started in 2015 as per + decreed in 內政部台內民字第1030182404號令. + + Children's Day Special Observance Rule first started in 2012 as per + decreed in 內政部台內民字第1010307327號令 - as this doesn't affect 2011 ones, + as such the logic is simplified. + """ + if self._year < since: + return None + + # Children's Day. + childrens_day = self.tr("兒童節") + for dt in sorted(dts): + names = self.get_list(dt) + for name in names: + self._add_observed( + dt, + name, + # Children's Day falls on the same day as Tomb-Sweeping Day. + CHILDRENS_DAY_RULE if name == childrens_day and len(names) > 1 else rule, + ) + + def _populate_public_holidays(self): + dts_observed = set() + dts_observed_forward = set() + + # Founding Day of the Republic of China. + name = tr("中華民國開國紀念日") + dts_observed.add(self._add_new_years_day(name)) + if self._year >= 2015: + self._add_observed(self._next_year_new_years_day, name=name) + + # Chinese New Year's Eve. + name = tr("農曆除夕") + if self._year >= 2026: + dts_observed_forward.add(self._add_chinese_day_before_new_years_eve(name)) + dts_observed_forward.add(self._add_chinese_new_years_eve(name)) + + # Chinese New Year. + name = tr("春節") + dts_observed_forward.add(self._add_chinese_new_years_day(name)) + dts_observed_forward.add(self._add_chinese_new_years_day_two(name)) + dts_observed_forward.add(self._add_chinese_new_years_day_three(name)) + + # Peace Memorial Day. + dts_observed.add(self._add_holiday_feb_28(tr("和平紀念日"))) + + if self._year >= 2011: + # Children's Day. + dts_observed.add(self._add_holiday_apr_4(tr("兒童節"))) + + # Tomb-Sweeping Day. + dts_observed.add(self._add_qingming_festival(tr("民族掃墓節"))) + + if self._year >= 2026: + # Labor Day. + self._add_labor_day(tr("勞動節")) + + # Dragon Boat Festival. + dts_observed.add(self._add_dragon_boat_festival(tr("端午節"))) + + # Mid-Autumn Festival. + dts_observed.add(self._add_mid_autumn_festival(tr("中秋節"))) + + if self._year >= 2025: + # Confucius' Birthday. + self._add_holiday_sep_28(tr("孔子誕辰紀念日")) + + # National Day. + dts_observed.add(self._add_holiday_oct_10(tr("國慶日"))) + + if self._year >= 2025: + # Taiwan Restoration and Guningtou Victory Memorial Day. + self._add_holiday_oct_25(tr("臺灣光復暨金門古寧頭大捷紀念日")) + + # Constitution Day. + self._add_holiday_dec_25(tr("行憲紀念日")) + + if self.observed: + self._populate_observed(dts_observed) + # While Chinese New Year special observances rule weren't officially decreed + # until 2015, this was de facto implemented by the DGPA since at least 2003. + self._populate_observed(dts_observed_forward, rule=SAT_SUN_TO_NEXT_WORKDAY, since=2003) + + def _populate_school_holidays(self): + if self._year <= 2000: + # Founding Day of the Republic of China. + self._add_new_years_day_two(tr("中華民國開國紀念日")) + + # Confucius' Birthday. + self._add_holiday_sep_28(tr("孔子誕辰紀念日")) + + # Taiwan Retrocession Day. + self._add_holiday_oct_25(tr("臺灣光復節")) + + # Late President Chiang Kai-shek's Birthday. + self._add_holiday_oct_31(tr("先總統 蔣公誕辰紀念日")) + + # Dr. Sun Yat-sen's Birthday. + self._add_holiday_nov_12(tr("國父誕辰紀念日")) + + # Constitution Day. + self._add_holiday_dec_25(tr("行憲紀念日")) + + def _populate_government_holidays(self): + self._populate_school_holidays() + + if self._year <= 2000: + # Revolutionary Martyrs Memorial Day. + self._add_holiday_mar_29(tr("革命先烈紀念日")) + + def _populate_optional_holidays(self): + if self._year <= 2025: + # Labor Day. + self._add_labor_day(tr("勞動節")) + + # Armed Forces Day. + self._add_holiday_sep_3(tr("軍人節")) + + def _populate_workday_holidays(self): + # Dr. Sun Yat-sen's Memorial Day. + self._add_holiday_mar_12(tr("國父逝世紀念日")) + + # Arbor Day. + self._add_holiday_mar_12(tr("植樹節")) + + # Youth Day. + self._add_holiday_mar_29(tr("青年節")) + + # Teacher's Day. + self._add_holiday_sep_28(tr("教師節")) + + # Chinese Cultural Renaissance Day. + self._add_holiday_nov_12(tr("中華文化復興節")) + + # Women's Day. + self._add_womens_day(tr("婦女節")) + + if self._year <= 2007: + # Late President Chiang Kai-shek's Memorial Day. + self._add_qingming_festival(tr("先總統蔣公逝世紀念日")) + + if self._year <= 2010: + # Children's Day. + self._add_holiday_apr_4(tr("兒童節")) + + if self._year >= 2000: + # The Buddha's Birthday. + self._add_chinese_birthday_of_buddha(tr("佛陀誕辰紀念日")) + + if self._year >= 2001: + # Taoism Day. + self._add_chinese_new_years_day(tr("道教節")) + + # Revolutionary Martyrs Memorial Day. + self._add_holiday_mar_29(tr("革命先烈紀念日")) + + if self._year <= 2024: + # Confucius' Birthday. + self._add_holiday_sep_28(tr("孔子誕辰紀念日")) + + # Taiwan Retrocession Day. + self._add_holiday_oct_25(tr("臺灣光復節")) + + # Dr. Sun Yat-sen's Birthday. + self._add_holiday_nov_12(tr("國父誕辰紀念日")) + + if self._year <= 2024: + # Constitution Day. + self._add_holiday_dec_25(tr("行憲紀念日")) + + if self._year <= 2006: + # Late President Chiang Kai-shek's Birthday. + self._add_holiday_oct_31(tr("先總統 蔣公誕辰紀念日")) + + if self._year >= 2006: + # Anti-Aggression Day. + self._add_holiday_mar_14(tr("反侵略日")) + + if self._year >= 2008: + # Commemoration Day of the Lifting of Martial Law. + self._add_holiday_jul_15(tr("解嚴紀念日")) + + # Taiwan United Nations Day. + self._add_united_nations_day(tr("臺灣聯合國日")) + + +class TW(Taiwan): + pass + + +class TWN(Taiwan): + pass + + +class TaiwanStaticHolidays: + """Taiwan special holidays. + + DGPA, Executive Yuan Work Calendars: + * [1998](https://web.archive.org/web/20240119034602/https://www.dgpa.gov.tw/information?pid=4979&uid=30) + * [1999](https://web.archive.org/web/20240119034606/https://www.dgpa.gov.tw/information?pid=4978&uid=30) + * [2000](https://web.archive.org/web/20231230164623/https://www.dgpa.gov.tw/information?uid=30&pid=4977) + * [2001](https://web.archive.org/web/20220809165413/https://www.dgpa.gov.tw/en/information?uid=353&pid=6199) + * [2002](https://web.archive.org/web/20220809163821/https://www.dgpa.gov.tw/en/information?uid=353&pid=6198) + * [2003](https://web.archive.org/web/20220809161706/https://www.dgpa.gov.tw/en/information?uid=353&pid=6197) + * [2004](https://web.archive.org/web/20220809175339/https://www.dgpa.gov.tw/en/information?uid=353&pid=6196) + * [2005](https://web.archive.org/web/20220809173619/https://www.dgpa.gov.tw/en/information?uid=353&pid=6195) + * [2006](https://web.archive.org/web/20250427175035/https://www.dgpa.gov.tw/en/information?uid=353&pid=6192) + * [2007](https://web.archive.org/web/20250427175157/https://www.dgpa.gov.tw/en/information?uid=353&pid=6194) + * [2008](https://web.archive.org/web/20250427175031/https://www.dgpa.gov.tw/en/information?uid=353&pid=6191) + * [2009](https://web.archive.org/web/20250427175008/https://www.dgpa.gov.tw/en/information?uid=353&pid=6190) + * [2010](https://web.archive.org/web/20240913193941/https://www.dgpa.gov.tw/en/information?pid=6189&uid=353) + * [2011](https://web.archive.org/web/20250427175006/https://www.dgpa.gov.tw/en/information?uid=353&pid=6188) + * [2012](https://web.archive.org/web/20250427175006/https://www.dgpa.gov.tw/en/information?uid=353&pid=6187) + * [2013](https://web.archive.org/web/20250427174956/https://www.dgpa.gov.tw/en/information?uid=353&pid=6186) + * [2014](https://web.archive.org/web/20220809133242/https://www.dgpa.gov.tw/en/information?uid=353&pid=6183) + * [2015](https://web.archive.org/web/20220809133240/https://www.dgpa.gov.tw/en/information?uid=353&pid=6182) + * [2016](https://web.archive.org/web/20220809133238/https://www.dgpa.gov.tw/en/information?uid=353&pid=6180) + * [2017](https://web.archive.org/web/20220809133236/https://www.dgpa.gov.tw/en/information?uid=353&pid=6178) + * [2018](https://web.archive.org/web/20240518122217/https://www.dgpa.gov.tw/en/information?uid=353&pid=7730) + * [2019](https://web.archive.org/web/20240422121421/http://www.dgpa.gov.tw/en/information?uid=353&pid=8178) + * [2020](https://web.archive.org/web/20240914094053/https://www.dgpa.gov.tw/en/information?pid=9724&uid=353) + * [2021](https://web.archive.org/web/20240615041915/https://www.dgpa.gov.tw/en/information?uid=353&pid=10181) + * [2022](https://web.archive.org/web/20220809133226/https://www.dgpa.gov.tw/en/information?uid=353&pid=10659) + * [2023](https://web.archive.org/web/20220809133225/https://www.dgpa.gov.tw/en/information?uid=353&pid=11016) + * [2024](https://web.archive.org/web/20250414165829/https://www.dgpa.gov.tw/en/information?uid=353&pid=11402) + * [2025](https://web.archive.org/web/20250121091032/https://www.dgpa.gov.tw/en/information?uid=353&pid=11979) + """ + + # Date format (see strftime() Format Codes). + substituted_date_format = tr("%Y-%m-%d") + + # Day off (substituted from %s). + substituted_label = tr("休息日(%s日起取代)") + + # Women's Day. + womens_day = tr("婦女節") + + # Children's Day. + childrens_day = tr("兒童節") + + special_public_holidays = { + 2000: (APR, 3, APR, 8), + 2001: (JAN, 22, JAN, 20), + 2005: (FEB, 7, FEB, 5), + 2006: (OCT, 9, OCT, 14), + 2007: ( + (FEB, 23, MAR, 3), + (APR, 6, APR, 14), + (JUN, 18, JUN, 23), + (SEP, 24, SEP, 29), + ), + 2009: ( + (JAN, 2, JAN, 10), + (JAN, 30, JAN, 17), + (MAY, 29, JUN, 6), + ), + 2010: (FEB, 19, FEB, 6), + 2012: ( + (JAN, 27, FEB, 4), + (FEB, 27, MAR, 3), + (DEC, 31, DEC, 22), + ), + 2013: ( + (FEB, 15, FEB, 23), + (SEP, 20, SEP, 14), + ), + 2015: (JAN, 2, DEC, 27, 2014), + 2016: ( + (FEB, 12, JAN, 30), + (JUN, 10, JUN, 4), + (SEP, 16, SEP, 10), + ), + 2017: ( + (FEB, 27, FEB, 18), + (MAY, 29, JUN, 3), + (OCT, 9, SEP, 30), + ), + 2018: ( + (APR, 6, MAR, 31), + (DEC, 31, DEC, 22), + ), + 2019: ( + (FEB, 8, JAN, 19), + (MAR, 1, FEB, 23), + (OCT, 11, OCT, 5), + ), + 2020: ( + (JAN, 23, FEB, 15), + (JUN, 26, JUN, 20), + (OCT, 2, SEP, 26), + ), + 2021: ( + (FEB, 10, FEB, 20), + (SEP, 20, SEP, 11), + ), + 2022: (FEB, 4, JAN, 22), + 2023: ( + (JAN, 20, JAN, 7), + (JAN, 27, FEB, 4), + (FEB, 27, FEB, 18), + (APR, 3, MAR, 25), + (JUN, 23, JUN, 17), + (OCT, 9, SEP, 23), + ), + 2024: (FEB, 8, FEB, 17), + 2025: (JAN, 27, FEB, 8), + } + # Prior to 2001, Women's Day and Children's Day holidays were given on + # the day before the Tomb-Sweeping Day. + special_optional_holidays_observed = { + 1998: ( + (APR, 4, childrens_day), + (APR, 4, womens_day), + ), + 1999: ( + (APR, 4, childrens_day), + (APR, 4, womens_day), + ), + 2000: ( + (APR, 3, childrens_day), + (APR, 3, womens_day), + # Armed Forces Day. + (SEP, 4, tr("軍人節")), + ), + } + # The Buddha's Birthday was observed on 2nd Sunday of May in 2000. + special_public_holidays_observed = { + 1998: ( + # Chinese New Year. + (JAN, 31, tr("春節")), + # Tomb-Sweeping Day. + (APR, 6, tr("民族掃墓節")), + ), + 1999: ( + # Founding Day of the Republic of China. + (JAN, 2, tr("中華民國開國紀念日")), + # Dragon Boat Festival. + (JUN, 19, tr("端午節")), + ), + # The Buddha's Birthday. + 2000: (MAY, 14, tr("佛陀誕辰紀念日")), + 2013: (APR, 5, childrens_day), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/tanzania.py b/.venv/lib/python3.12/site-packages/holidays/countries/tanzania.py new file mode 100644 index 00000000..4d48d911 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/tanzania.py @@ -0,0 +1,310 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import BANK, PUBLIC +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.holiday_base import HolidayBase + + +class Tanzania( + HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Tanzania holidays. + + References: + * [1962](https://old.tanzlii.org/tz/legislation/act/1962/48/) + * [1964](https://web.archive.org/web/20250426030228/http://www.parliament.go.tz/polis/uploads/bills/acts/1565172859-The%20Public%20Holidays%20Ordinance%20(amendment)%20Act,%201964.pdf) + * [1966](https://web.archive.org/web/20241130122429/http://www.parliament.go.tz/polis/uploads/bills/acts/1565692654-The%20Public%20Holidays%20Ordinance%20(Amendment)%20Act,%201966.pdf) + * [1993](https://web.archive.org/web/20250425095011/https://www.parliament.go.tz/polis/uploads/bills/acts/1566639469-The%20Written%20Laws%20(Miscellaneous%20Amendments)%20Act,%201993.pdf) + * [1994](https://web.archive.org/web/20241130115733/http://www.parliament.go.tz/polis/uploads/bills/acts/1566638051-The%20Written%20Laws%20(Miscellaneous%20Amendments)%20(No.%202)%20Act,%201994.pdf) + * [2002](https://web.archive.org/web/20250427172313/http://parliament.go.tz/polis/uploads/bills/acts/1454076376-ActNo-25-2002.pdf) + * + * + * + * + + Checked With: + * [2023](https://web.archive.org/web/20250403094322/https://www.bot.go.tz/webdocs/Other/2023%20public%20holidays.pdf) + * [2022](https://web.archive.org/web/20230123001009/https://www.bot.go.tz/webdocs/Other/PUBLIC%20HOLIDAYS%202022.pdf) + * [2021](https://web.archive.org/web/20210812134750/https://www.bot.go.tz/webdocs/Other/PUBLIC%20HOLIDAYS%202021.pdf) + * [2020](https://web.archive.org/web/20201219014125/https://www.bot.go.tz/webdocs/Other/PUBLIC%20HOLIDAYS%202020.pdf) + * [2018](https://web.archive.org/web/20190528223244/http://issamichuzi.blogspot.com:80/2017/11/sikukuu-za-kitaifa-zenye-mapumziko-kwa.html) + * [from 2013 onwards](https://web.archive.org/web/20250130093727/https://www.timeanddate.com/holidays/tanzania/) + + Limitations: + * Only works from 1994 onwards due to the lack of sources for certain legislation: + * Government Notices No. 79 of 1977 + * Government Notices No. 300 of 1985 + * Government Notices No. 296 of 1994 + * Exact Islamic holidays dates are only available for 2013-2023; the rest are estimates. + """ + + country = "TZ" + supported_categories = (BANK, PUBLIC) + default_language = "sw" + # %s (estimated). + estimated_label = tr("%s (makisio)") + supported_languages = ("en_US", "sw") + # Written Law (Miscellaneous Amendments) (No. 2) Act, 1994. + start_year = 1994 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=TanzaniaIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, TanzaniaStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_bank_holidays(self): + # Sikukuu ya Pasaka. + # Status: In-Use. + # Only observed by financial institutions. + + # Easter Sunday. + self._add_easter_sunday(tr("Sikukuu ya Pasaka")) + + def _populate_public_holidays(self): + # In-lieus ("Badala ya %s") are observed on Monday should it fall on the weekends. + # Abrogated in Public Holidays Ordinance No. 28 of 1966. + # Reinstituted in Written Law (Miscellaneous Amendments) (No. 2) Act, 1994. + # Claimed to be abrogated again on an unspecified date. + + # Fixed Date Holidays. + + # Mwaka Mpya. + # Status: In-Use. + # Abrogated in Public Holidays Ordinance No. 28 of 1966. + # Reinstituted prior to the Written Law (Miscellaneous Amendments) (No. 1) Act, 1993. + + # New Year's Day. + self._add_new_years_day(tr("Mwaka Mpya")) + + # Mapinduzi ya Zanzibar. + # Status: In-Use. + # Commemorates the fall of the Sultanate of Zanzibar on Jan 12, 1964. + + # Zanzibar Revolution Day. + self._add_holiday_jan_12(tr("Mapinduzi ya Zanzibar")) + + # Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali ya Mapinduzi Zanzibar + # Sheikh Abeid Amani Karume. + # Status: In-Use. + # Commemorates the death of Abeid Amani Karume on Apr 7, 1972. + # Assumed to start via Government Notices 79 of 1977. + + self._add_holiday_apr_7( + # The Sheikh Abeid Amani Karume Day. + tr( + "Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali ya Mapinduzi Zanzibar " + "Sheikh Abeid Amani Karume" + ) + ) + + # Muungano wa Tanganyika na Zanzibar. + # Status: In-Use. + # Commemorates the creation of the United Republic of Tanzania on Apr 26, 1964. + + # Union Celebrations. + self._add_holiday_apr_26(tr("Muungano wa Tanganyika na Zanzibar")) + + # Sikukuu ya Wafanyakazi. + # Status: In-Use. + + # Worker's Day. + self._add_labor_day(tr("Sikukuu ya Wafanyakazi")) + + # Sabasaba. + # Status: In-Use. + # Celebrates the formation of Tanganyika African National Union party on Jul 7, 1954. + # First started in the Public Holidays Ordinance No. 57 of 1964. + # Abrogated in 1993 (need official source on this) + # Reinstituted via Government Notices 296 of 1994. + + # International Trade Fair. + self._add_holiday_jul_7(tr("Sabasaba")) + + # Siku ya Wakulima. + # Status: In-Use. + # Also known as Nane Nane. + # Started via Government Notices 296 of 1994 to replace Sabasaba. + + # Peasants Day. + self._add_holiday_aug_8(tr("Siku ya Wakulima")) + + # Kumbukumbu ya Mwalimu Nyerere. + # Status: In-Use. + # Commemorates the death of Julius Kambarage Nyerere on Oct 14, 1999. + # Adopted in Written Law (Miscellaneous Amendments) (No. 3) Act, 2002. + + if self._year >= 2003: + # The Mwalimu Nyerere Day. + self._add_holiday_oct_14(tr("Kumbukumbu ya Mwalimu Nyerere")) + + # Uhuru na Jamhuri. + # Status: In-Use. + # Commemorates the Independence of Tanganyika from the United Kingdom on Dec 9, 1961. + + # Independence and Republic Day. + self._add_holiday_dec_9(tr("Uhuru na Jamhuri")) + + # Kuzaliwa Kristo. + # Status: In-Use. + + # Christmas Day. + self._add_christmas_day(tr("Kuzaliwa Kristo")) + + # Siku ya Kupeana Zawadi. + # Status: In-Use. + # Abrogated in Public Holidays Ordinance No. 28 of 1966. + # Reinstituted in Written Law (Miscellaneous Amendments) (No. 1) Act, 1993. + + # Boxing Day. + self._add_christmas_day_two(tr("Siku ya Kupeana Zawadi")) + + # Christian Calendar Holidays. + + # Ijumaa Kuu. + # Status: In-Use. + + # Good Friday. + self._add_good_friday(tr("Ijumaa Kuu")) + + # Jumatatu ya Pasaka. + # Status: In-Use. + + # Easter Monday. + self._add_easter_monday(tr("Jumatatu ya Pasaka")) + + # Islamic Calendar Holidays. + + # Eid El-Fitry. + # Status: In-Use. + # Used to be celebrated for 2 days in the 1964 and 1966 amendments. + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Eid El-Fitry")) + + # Eid El-Hajj. + # Status: In-Use. + # Used to be celebrated for 2 days in the 1964 amendments. + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Eid El-Hajj")) + + # Maulidi. + # Status: In-Use. + + # Prophet's Birthday. + self._add_mawlid_day(tr("Maulidi")) + + # Defunct Holidays. + + # 5th Day of February ??? (Name Unavailable) + # Status: Defunct. + # Abrogated in Written Law (Miscellaneous Amendments) (No. 1) Act, 1993. + + +class TZ(Tanzania): + pass + + +class TZA(Tanzania): + pass + + +class TanzaniaIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 23), + 2016: (SEP, 16), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 13), + 2020: (JUL, 31), + 2021: (JUL, 21), + 2022: (JUL, 10), + 2023: (JUN, 29), + } + + EID_AL_FITR_DATES = { + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 14), + 2022: (MAY, 3), + 2023: (APR, 22), + 2024: (APR, 10), + } + + MAWLID_DATES = { + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 19), + 2022: (OCT, 9), + 2023: (SEP, 28), + } + + +class TanzaniaStaticHolidays: + # Special Holidays. + + # John Pombe Magufuli Inauguration Day. + john_magufuli_inauguration = tr("Sikukuu ya Kuapishwa kwa John Pombe Magufuli") + + # Tanzania General Election Day. + tz_election_day = tr("Sikukuu ya Uchaguzi Mkuu wa Tanzania") + + # National Population and Housing Census Day. + phc_census_day = tr("Siku ya Sensa ya Kitaifa ya Watu na Makazi") + + # John Pombe Magufuli's Funeral. + john_magufuli_funeral = tr("Mazishi cha John Pombe Magufuli") + + special_public_holidays = { + 2002: (AUG, 25, phc_census_day), + 2015: (NOV, 5, john_magufuli_inauguration), + 2020: (OCT, 28, tz_election_day), + 2021: ( + (MAR, 22, john_magufuli_funeral), + (MAR, 25, john_magufuli_funeral), + ), + 2022: (AUG, 23, phc_census_day), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/thailand.py b/.venv/lib/python3.12/site-packages/holidays/countries/thailand.py new file mode 100644 index 00000000..c8912b0b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/thailand.py @@ -0,0 +1,1126 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + _timedelta, +) +from holidays.constants import ARMED_FORCES, BANK, GOVERNMENT, PUBLIC, SCHOOL, WORKDAY +from holidays.groups import InternationalHolidays, StaticHolidays, ThaiCalendarHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_TO_NEXT_MON, + THU_FRI_TO_NEXT_WORKDAY, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON_TUE, + SAT_SUN_TO_NEXT_WORKDAY, +) + + +class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiCalendarHolidays): + """Thailand holidays. + + References: + * + * [Holidays Act (MAR 1914)](https://web.archive.org/web/20231021231154/https://ratchakitcha.soc.go.th/documents/1044125.pdf) + * [Special Extension for MoJ (In-effect 1915 onwards)](https://web.archive.org/web/20250428123805/https://ratchakitcha.soc.go.th/documents/1046008.pdf) + * [Holidays Act Amendment (MAR 1926)](https://web.archive.org/web/20231021231328/https://ratchakitcha.soc.go.th/documents/1073133.pdf) + * [Ascension of HM King Ananda Mahidol (MAR 1935)](https://web.archive.org/web/20250215164432/https://th.wikisource.org/wiki/ประกาศนายกรัฐมนตรี_ลงวันที่_7_มีนาคม_2477_(รก.)) + * [Holidays Act Amendment (JAN 1938)](https://web.archive.org/web/20240812112232/https://ratchakitcha.soc.go.th/documents/1105432.pdf) + * [Translation Typo Fixed for the JAN 1938 Amendment](https://web.archive.org/web/20250428132201/https://ratchakitcha.soc.go.th/documents/1105491.pdf) + * [Constitution Petition Day renamed National Day (JUL 1938)](https://web.archive.org/web/20241109062813/https://th.wikisource.org/wiki/ประกาศสำนักนายกรัฐมนตรี_ลงวันที่_18_กรกฎาคม_2481) + * [Holidays Act Amendment (MAR 1940)](https://web.archive.org/web/20240813142812/https://ratchakitcha.soc.go.th/documents/1110471.pdf) + * [Holidays Act Amendment (SEP 1940) (In-effect 1941)](https://web.archive.org/web/20231021230955/https://ratchakitcha.soc.go.th/documents/1111954.pdf) + * [Removal of Royal Language for King's Birthday (B.E 2484/1941)](https://web.archive.org/web/20241213001307/https://th.wikisource.org/wiki/ประกาศสำนักนายกรัฐมนตรี_ลงวันที่_19_กันยายน_2484) + * [Holidays Act, Franco-Thai War Armistice Day added (B.E. 2485/1942)](https://web.archive.org/web/20250428123610/https://ratchakitcha.soc.go.th/documents/1114825.pdf) + * [Holidays Act, Franco-Thai War Armistice Day Repealed (B.E. 2487/1944)](https://web.archive.org/web/20250428123653/https://ratchakitcha.soc.go.th/documents/1121365.pdf) + * [Removal of Royal Language for King's Birthday Repealed (B.E 2488/1945)](https://web.archive.org/web/20241210051421/https://th.wikisource.org/wiki/ประกาศสำนักนายกรัฐมนตรี_ลงวันที่_12_มกราคม_2488) + * [Holidays Act Amendment (DEC B.E. 2488/1945)](https://web.archive.org/web/20231022121809/https://ratchakitcha.soc.go.th/documents/1123218.pdf) + * [Holidays Act Amendment (AUG B.E. 2489/1946)](https://web.archive.org/web/20250428132451/https://ratchakitcha.soc.go.th/documents/1124494.pdf) + * [Special Weekend Arrangement for 4 Southern Provinces (4SP)](https://web.archive.org/web/20250428133015/https://ratchakitcha.soc.go.th/documents/1129175.pdf) + * [Holidays Act, B.E. 2491 (1948)](https://web.archive.org/web/20240812124132/https://ratchakitcha.soc.go.th/documents/1130817.pdf) + * [Holidays Act (No. 2), B.E. 2493 (1950)](https://web.archive.org/web/20240812132452/https://ratchakitcha.soc.go.th/documents/1141392.pdf) + * [Holidays Act (No. 3), B.E. 2494 (1951)](https://web.archive.org/web/20250428133136/https://ratchakitcha.soc.go.th/documents/1143601.pdf) + * [HM King Bhumibol Adulyadej Birthday Holidays Adjustment](https://web.archive.org/web/20250428133250/https://ratchakitcha.soc.go.th/documents/1145614.pdf) + * [Holidays Act (No. 4), B.E. 2495 (1952)](https://web.archive.org/web/20250428133326/https://ratchakitcha.soc.go.th/documents/1148403.pdf) + * [Holidays Act (No. 6), B.E. 2497 (1954)](https://web.archive.org/web/20240812201729/https://ratchakitcha.soc.go.th/documents/1159427.pdf) + * [Holidays Act (No. 7), B.E. 2497 (1954); United Nations Day added](https://web.archive.org/web/20250428133416/https://ratchakitcha.soc.go.th/documents/1160256.pdf) + * [Holidays Act (No. 8), B.E. 2499 (1956); Mothers Day, Children's Day added](https://web.archive.org/web/20250428133618/https://ratchakitcha.soc.go.th/documents/1169783.pdf) + * [Holidays Act (No. 9), B.E. 2499 (1956); Weekend is now Buddhist Sabbath-SUN](https://web.archive.org/web/20250428133714/https://ratchakitcha.soc.go.th/documents/1172667.pdf) + * [Holidays Act (No. 10), B.E. 2500 (1957); Weekend Change Reverted](https://web.archive.org/web/20250428133819/https://ratchakitcha.soc.go.th/documents/1179999.pdf) + * [Holidays Act (No. 11), B.E. 2500 (1957)](https://web.archive.org/web/20250428133903/https://ratchakitcha.soc.go.th/documents/1180042.pdf) + * [Holidays Act (No. 12), B.E. 2502 (1959); Weekend is full day SAT-SUN](https://web.archive.org/web/20250428134027/https://ratchakitcha.soc.go.th/documents/1187876.pdf) + * [Holidays Act (No. 13), B.E. 2503 (1960); National Day is now Dec 5](https://web.archive.org/web/20230627092848/https://ratchakitcha.soc.go.th/documents/1196364.pdf) + * [Holidays Act (No. 14), B.E. 2505 (1962); Asarnha Bucha added](https://web.archive.org/web/20250428134121/https://ratchakitcha.soc.go.th/documents/1206407.pdf) + * [Holidays Act (No. 16), B.E. 2506 (1963); 4SP weekend is now SAT-SUN](https://archive.org/details/httpshr.rid.go.thwp-contentuploads20221206-16.pdf) + * [Eid-al-Fitr and Eit al-Adha added for 4SP](https://archive.org/details/httpshr.rid.go.thwp-contentuploads20221205-2517.pdf) + * [Holidays Act (No. 17), B.E. 2525 (1982); Chakri Day Full Name Changed](https://web.archive.org/web/20250428134349/https://ratchakitcha.soc.go.th/documents/1494132.pdf) + * [Holidays Act (No. 19), B.E. 2540 (1997); Songkran Date Changed](https://web.archive.org/web/20250428134426/https://ratchakitcha.soc.go.th/documents/1685580.pdf) + * [Holidays Act (No. 20), B.E. 2555 (2012); CNY in 4SP](https://web.archive.org/web/20250428134504/https://ratchakitcha.soc.go.th/documents/1914282.pdf) + * [Holidays Act (No. 21), B.E. 2556 (2013); Songkhla added to 4SP](https://web.archive.org/web/20250428134536/https://ratchakitcha.soc.go.th/documents/2098813.pdf) + * [Holidays Act (No. 22), B.E. 2560 (2017); Father's Day Date Clarification](https://web.archive.org/web/20230627142834/https://ratchakitcha.soc.go.th/documents/2098828.pdf) + * [Holidays Act (No. 23), B.E. 2560 (2017); Rama X's Birthday added](https://web.archive.org/web/20250428134706/https://ratchakitcha.soc.go.th/documents/2104467.pdf) + * [HM Queen Suthida's Birthday added](https://web.archive.org/web/20250428134748/https://ratchakitcha.soc.go.th/documents/17081602.pdf) + * [Holidays Act, B.E. 2562 (2019)](https://web.archive.org/web/20250428134835/https://ratchakitcha.soc.go.th/documents/17082311.pdf) + + Checked with: + * [Bank of Thailand](https://web.archive.org/web/20230205072056/https://www.bot.or.th/Thai/FinancialInstitutions/FIholiday/Pages/2023.aspx) + + In Lieus: + * [isranews.org](https://web.archive.org/web/20230205073547/https://www.isranews.org/content-page/item/20544-วันหยุดชดเชย-มาจากไหน-sp-863880667.html) + * + * + * + * + * + + Certain holidays references: + * [New Year's Day](https://web.archive.org/web/20230115102900/https://th.wikisource.org/wiki/ประกาศให้ใช้วันที่_1_มกราคม_เป็นวันขึ้นปีใหม่_ลงวันที่_24_ธันวาคม_2483) + * [National Children's Day](https://web.archive.org/web/20230929070232/https://thainews.prd.go.th/banner/th/children'sday/) + * [Chakri Memorial Day](https://web.archive.org/web/20221003075521/https://www.ocac.go.th/news/๖-เมษายน-วันจักรี/v) + * Songkran Festival: + * [museumsiam.org](https://web.archive.org/web/20230205074402/https://m.museumsiam.org/da-detail2.php?MID=3&CID=177&CONID=4033) + * + * [National Labour Day](https://web.archive.org/web/20220629085454/https://www.thairath.co.th/lifestyle/culture/1832869) + * [National Day (24 June: Defunct)](https://web.archive.org/web/20091106202525/http://www.culture.go.th/study.php?&YY=2548&MM=11&DD=2) + * Coronation Day: + * + * + * [HM Queen Suthida's Birthday](https://web.archive.org/web/20241217104142/https://www.thairath.co.th/news/politic/1567418) + * [HM Maha Vajiralongkorn's Birthday](https://web.archive.org/web/20220817223130/https://www.matichon.co.th/politics/news_526200) + * [HM Queen Sirikit the Queen Mother's Birthday](https://web.archive.org/web/20250203002257/https://hilight.kapook.com/view/14164) + * [National Mother's Day](https://web.archive.org/web/20221207161434/https://www.brh.go.th/index.php/2019-02-27-04-11-52/542-12-2564) + * [HM King Bhumibol Adulyadej Memorial Day](https://web.archive.org/web/20220817223130/https://www.matichon.co.th/politics/news_526200) + * HM King Chulalongkorn Memorial Day: + * + * + * HM King Bhumibol Adulyadej's Birthday + * [Ministry of Culture](https://web.archive.org/web/20091106202525/http://www.culture.go.th/study.php?&YY=2548&MM=11&DD=2) + * + * [National Father's Day](https://web.archive.org/web/20230205075650/https://www.brh.go.th/index.php/2019-02-27-04-12-21/594-5-5) + * Constitution Day: + * + * + * [Bank of Thailand](https://web.archive.org/web/20230205072056/https://www.bot.or.th/Thai/FinancialInstitutions/FIholiday/Pages/2023.aspx) + * + * New Year's Eve: + * [Bank of Thailand](https://web.archive.org/web/20230205072056/https://www.bot.or.th/Thai/FinancialInstitutions/FIholiday/Pages/2023.aspx) + * + * + * [Makha Bucha](https://web.archive.org/web/20240908185818/https://www.onab.go.th/th/content/category/detail/id/73/iid/3403) + * [Visakha Bucha](https://web.archive.org/web/20240908190019/https://www.onab.go.th/th/content/category/detail/id/73/iid/3401) + * [Asarnha Bucha](https://web.archive.org/web/20240816131909/https://www.onab.go.th/th/content/category/detail/id/73/iid/3397) + * [Buddhist Lent Day](https://web.archive.org/web/20240908185432/https://www.onab.go.th/th/content/category/detail/id/73/iid/3395) + * Royal Ploughing Ceremony: + * + * + * + * + * + * + * + * [Royal Thai Armed Forces Day](https://th.wikipedia.org/wiki/วันกองทัพไทย) + * [Teacher's Day](https://web.archive.org/web/20250117105542/http://event.sanook.com/day/teacher-day/) + + !!! info "Info" + If Public Holiday falls on weekends, (in lieu) on workday. + + Despite the wording, this usually only applies to Monday only for + holidays, consecutive holidays all have their own special in lieu + declared separately. + + Data from 1992-1994 and 1998-2000 are declared discretely in + special_holidays declarations above. + + Applied Automatically for Monday if on Weekends: 1961-1973 + + !!! note "Note" + No New Year's Eve (in lieu) for this period + + No In Lieu days available: 1974-1988 + + Case-by-Case application for Workday if on Weekends: 1989-1994 + + Applied Automatically for Workday if on Weekends: 1995-1997 + + Case-by-Case application for Workday if on Weekends: 1998-2000 + + Applied Automatically for Workday if on Weekends: 2001-Present + + Limitations: + * This is only 100% accurate for 1997-2025; any future dates are up to the + Royal Thai Government Gazette which updates on a year-by-year basis. + * Thai Lunar Calendar Holidays only work until 2157 (B.E. 2700) as we only + have Thai year-type data for cross-checking until then. + * Royal Ploughing Ceremony Day is date is announced on an annual basis + by the Court Astrologers, thus need an annual update to the library here + """ + + country = "TH" + default_language = "th" + # %s (in lieu). + observed_label = tr("ชดเชย%s") + # First Holiday Decree was promulgated in March 1914. + start_year = 1914 + supported_categories = (ARMED_FORCES, BANK, GOVERNMENT, PUBLIC, SCHOOL, WORKDAY) + supported_languages = ("en_US", "th", "uk") + + def __init__(self, *args, **kwargs): + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, ThailandStaticHolidays) + ThaiCalendarHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _is_observed(self, dt: date) -> bool: + return 1961 <= self._year <= 1973 or 1995 <= self._year <= 1997 or self._year >= 2001 + + def _populate_public_holidays(self): + # Fixed Date Holidays + + # วันขึ้นปีใหม่ + # Status: In-Use. + # Starts in the present form in 1941 (B.E. 2484). + # From 1941-1945 and 1948-1954 JAN 2nd was also observed. + # For pre- observance, see New Year's Eve entry. + + if self._year >= 1941: + # New Year's Day. + name = tr("วันขึ้นปีใหม่") + self._add_observed(self._add_new_years_day(name)) + if self._year <= 1945 or 1948 <= self._year <= 1954: + self._add_new_years_day_two(name) + + # วันเด็กแห่งชาติ + # Status: In-Use. + # Starts in 1955 (B.E. 2498) as the 1st Monday of OCT. + # Its status as a Public Holiday was reaffirmed in 1956. + # No event was held in 1964 due to date changes came into effect too late. + # Moved to 2nd Saturday of JAN since 1965. + # No in-lieus are observed, and still remain a Public Holidays than just Observed. + + if self._year >= 1955 and self._year != 1964: + # National Children's Day. + name = tr("วันเด็กแห่งชาติ") + if self._year <= 1963: + self._add_holiday_1st_mon_of_oct(name) + else: + self._add_holiday_2nd_sat_of_jan(name) + + # วันลงนามในสัญญาพักรบระหว่างประเทศไทยกับประเทศอินโดจีนฝรั่งเศส + # Status: Defunct. + # Started in 1942 (B.E. 2485), abandoned from 1945 onwards. + + if 1942 <= self._year <= 1944: + # Franco-Thai War Armistice Day. + self._add_holiday_jan_28(tr("วันลงนามในสัญญาพักรบระหว่างประเทศไทยกับประเทศอินโดจีนฝรั่งเศส")) + + # วันจักรี + # Status: In-Use. + # Starts in present form in 1926 (B.E. 2469). + + if self._year >= 1926: + if self._year >= 1983: + # Chakri Memorial Day. + name = tr("วันพระบาทสมเด็จพระพุทธยอดฟ้าจุฬาโลกมหาราช และวันที่ระลึกมหาจักรีบรมราชวงศ์") + elif self._year >= 1938: + # Chakri Day. + name = tr("วันจักรี") + else: + # Maha Chakri Memorial Day. + name = tr("วันที่ระลึกมหาจักรี") + self._add_observed(self._add_holiday_apr_6(name)) + + # พระราชพิธีตะรุษะสงกรานต์ แลนักขัตฤกษ์ (1914-1925) + # ตะรุษะสงกรานต์ (1926-1937) + # วันตรุษสงกรานต์ (1938-1939) + # วันตรุษสงกรานต์และขึ้นปีใหม่ (1940) + # วันสงกรานต์ (1941-Present) + # Status: In-Use. + # Started in 1914 (B.E. 2457). + # Earliest form of Songkran public holidays was observed from MAR 28th to APR 15th + # (19 days). Later extended for MoJ staff only upto APR 27th from 1915 (30 days). + # - 1926-1937, celebrated on MAR 31st-APR 3rd. + # - 1938-1940, celebrated on MAR 31st-APR 2nd. + # - 1941-1947, abandoned as a public holiday. + # - 1948-1953, celebrated on APR 13th-15th. + # - 1954-1956, abandoned as a public holiday. + # - 1957-1988, only celebrated on APR 13th. + # - 1989-1997, celebrated on APR 12th-14th. + # - 1998-Present, celebrated on APR 13th-15th. + # (Except for 2020 due to Covid-19 outbreaks) + # This has its own in-lieu trigger. + + if self._year <= 1940 or 1948 <= self._year <= 1953 or 1957 <= self._year != 2020: + # Songkran Festival. + name = tr("วันสงกรานต์") + if 1989 <= self._year <= 1997: + dt = self._add_holiday_apr_12(name) + self._add_holiday_apr_13(name) + self._add_holiday_apr_14(name) + elif 1957 <= self._year <= 1988: + self._add_observed(self._add_holiday_apr_13(name)) + elif 1926 <= self._year <= 1940: + if self._year == 1940: + # Songkran New Year. + name = tr("วันตรุษสงกรานต์และขึ้นปีใหม่") + elif self._year >= 1938: + # Songkran New Year. + name = tr("วันตรุษสงกรานต์") + else: + # Songkran New Year. + name = tr("ตะรุษะสงกรานต์") + self._add_holiday_mar_31(name) + self._add_holiday_apr_1(name) + self._add_holiday_apr_2(name) + if self._year <= 1937: + self._add_holiday_apr_3(name) + elif self._year <= 1925: + # Songkran New Year Holidays. + name = tr("พระราชพิธีตะรุษะสงกรานต์ แลนักขัตฤกษ์") + dt = self._add_holiday_mar_28(name) + for delta in range(1, 19): + self._add_holiday(name, _timedelta(dt, delta)) + else: + dt = self._add_holiday_apr_13(name) + self._add_holiday_apr_14(name) + self._add_holiday_apr_15(name) + + # วันหยุดชดเชยวันสงกรานต์ + # If Songkran happened to be held on the weekends, only one in-lieu + # public holiday is added. + # - CASE 1: THU-FRI-SAT -> 1 in-lieu on MON + # - CASE 2: FRI-SAT-SUN -> 1 in-lieu on MON + # - CASE 3: SAT-SUN-MON -> 1 in-lieu on TUE + # - CASE 4: SUN-MON-TUE -> 1 in-lieu on WED + # See in lieu logic in `_add_observed(dt: date)`. + # Status: In Use. + + if self._year >= 1995: + self._add_observed(dt, rule=THU_FRI_TO_NEXT_WORKDAY + SAT_SUN_TO_NEXT_WORKDAY) + + # วันแรงงานแห่งชาติ + # Status: In-Use. + # Starts in the present form in 1974 (B.E. 2517). + # Does existed officially since 1956 (B.E. 2499), but wasn't a public holiday until then. + # *** NOTE: only observed by financial and private sectors. + + if self._year >= 1974: + # National Labor Day. + self._add_observed(self._add_labor_day(tr("วันแรงงานแห่งชาติ"))) + + # วันขอพระราชทานรัฐธรรมนูญ (1938-1939) + # วันชาติ (1940-Present) + # Status: In-Use. + # Started as Constitution Petition Day in 1938 (B.E. 2481) for JUN 24th. + # Got its current name in 1940 by Plaek Phibunsongkhram. + # This was observed JUN 23th-25th between 1940-1948. + # Moved to Rama IX's birthday in 1960 (B.E. 2503) by Sarit Thanarat. + + if self._year >= 1938: + name = ( + # National Day. + tr("วันชาติ") + if self._year >= 1939 + # Constitution Petition Day. + else tr("วันขอพระราชทานรัฐธรรมนูญ") + ) + self._add_observed( + self._add_holiday_jun_24(name) + if self._year <= 1959 + else self._add_holiday_dec_5(name) + ) + if 1940 <= self._year <= 1948 or 1952 <= self._year <= 1953: + self._add_holiday_jun_23(name) + self._add_holiday_jun_25(name) + + # วันรัฐธรรมนูญชั่วคราว + # Status: Defunct. + # Started in 1938, abandoned in 1940. + + if 1938 <= self._year <= 1939: + # Provisional Constitution Day. + self._add_holiday_jun_27(tr("วันรัฐธรรมนูญชั่วคราว")) + + # ทำบุญพระบรมอัษฐิ และพระราชพิธีฉัตรมงคล (1914-1925) + # พระราชพิธีฉัตรมงคล (1926-1937) + # วันฉัตรมงคล (1958-Present) + # First observed for Rama VI from 1914-1925 from NOV 9th-12th. + # For Rama VII (1926-1935) this was FEB 24th-26th. + # After Rama VII abdicated on MAR 2nd, 1935, there's no recorded + # change in terms of holiday arrangement until 1938, + # thus, a gap in holidays arrangement is assumed. + # Rama VIII passes away without a coronation ceremony. + # Starts in 1958 (B.E. 2501) for Rama IX's Coronation: MAY 5th. + # No celebration in 2017-2019 (B.E. 2560-2562). + # Reestablished with Rama X's Coronation in 2020: MAY 4th. + + if self._year <= 1935 or self._year >= 1958: + # Coronation Day. + name = tr("วันฉัตรมงคล") + if self._year >= 2020: + # Rama X (2020-Present). + self._add_observed(self._add_holiday_may_4(name)) + elif 1958 <= self._year <= 2016: + # Rama IX (1958-2016). + self._add_observed(self._add_holiday_may_5(name)) + elif 1926 <= self._year <= 1935: + # Coronation Day. + name = tr("พระราชพิธีฉัตรมงคล") + # Rama VII (1926-1935). + self._add_holiday_feb_24(name) + self._add_holiday_feb_25(name) + self._add_holiday_feb_26(name) + elif self._year <= 1925: + # Merit-making Ceremony for the Royal Ashes and the Coronation Day. + name = tr("ทำบุญพระบรมอัษฐิ และพระราชพิธีฉัตรมงคล") + # Rama VI (1914-1925). + self._add_holiday_nov_9(name) + self._add_holiday_nov_10(name) + self._add_holiday_nov_11(name) + self._add_holiday_nov_12(name) + + # วันเฉลิมพระชนมพรรษา พระราชินี + # Status: In-Use. + # Starts in 2019 (B.E. 2562). + + if self._year >= 2019: + self._add_observed( + self._add_holiday_jun_3( + # HM Queen Suthida's Birthday. + tr("วันเฉลิมพระชนมพรรษาสมเด็จพระนางเจ้าสุทิดา พัชรสุธาพิมลลักษณ พระบรมราชินี") + ) + ) + + # วันเฉลิมพระชนมพรรษา รัชกาลที่ 10 + # Status: In-Use. + # Started in 2017 (B.E. 2560). + + if self._year >= 2017: + self._add_observed( + self._add_holiday_jul_28( + # HM King Maha Vajiralongkorn's Birthday. + tr( + "วันเฉลิมพระชนมพรรษาพระบาทสมเด็จพระปรเมนทรรามาธิบดี" + "ศรีสินทรมหาวชิราลงกรณ พระวชิรเกล้าเจ้าอยู่หัว" + ) + ) + ) + + # วันเฉลิมพระชนมพรรษา พระบรมราชินีนาถ (1976-2017) + # วันเฉลิมพระชนมพรรษา พระบรมราชชนนีพันปีหลวง (2017-Present) + # Status: In-Use. + # Started in 1976 (B.E. 2519) alongside Mother's Day. + # Initial celebration as HM Queen Sirikit's Birthday. + # Now acts as the Queen Mother from 2017 onwards. + + if self._year >= 1976: + self._add_observed( + self._add_holiday_aug_12( + # HM Queen Sirikit the Queen Mother's Birthday. + tr("วันเฉลิมพระชนมพรรษาสมเด็จพระบรมราชชนนีพันปีหลวง") + if self._year >= 2017 + # HM Queen Sirikit's Birthday. + else tr("วันเฉลิมพระชนมพรรษาสมเด็จพระนางเจ้าสิริกิติ์ พระบรมราชินีนาถ") + ) + ) + + # วันแม่แห่งชาติ + # Status: In-Use. + # Started 1950 (B.E. 2493) initially as APR 15th and cancelled in + # 1958 (B.E. 2501) when the Min. of Culture was abolished. + # Its status as a Public Holiday was reaffirmed in 1956. + # Restarts again in 1976 (B.E. 2519) on Queen Sirikit's Birthday + # (AUG 12th) and stay that way from that point onwards. + + # National Mother's Day. + name = tr("วันแม่แห่งชาติ") + if 1950 <= self._year <= 1957: + self._add_observed(self._add_holiday_apr_15(name)) + elif self._year >= 1976: + self._add_observed(self._add_holiday_aug_12(name)) + + # วันประกาศสันติภาพ + # Status: Defunct. + # Started in 1946 (B.E. 2489), removed in 1948. + + if 1946 <= self._year <= 1947: + # Peace Proclamation Day. + self._add_holiday_aug_16(tr("วันประกาศสันติภาพ")) + + # วันคล้ายวันสวรรคตพระบาทสมเด็จพระปรมินทรมหาภูมิพลอดุลยเดช บรมนาถบพิตร (2017-2018) + # วันคล้ายวันสวรรคตพระบาทสมเด็จพระบรมชนกาธิเบศร มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร (2019-2022) + # วันนวมินทรมหาราช (2023-Present) + # Status: In-Use. + # Started in 2017 (B.E. 2560). + # Got conferred with 'the Great' title in 2019 (B.E. 2562). + + if self._year >= 2017: + if self._year >= 2023: + # HM King Bhumibol Adulyadej Memorial Day. + name = tr("วันนวมินทรมหาราช") + elif self._year >= 2019: + # Anniversary for the Death of King Bhumibol Adulyadej the Great. + name = tr( + "วันคล้ายวันสวรรคตพระบาทสมเด็จพระบรมชนกาธิเบศร มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร" + ) + else: + # Anniversary for the Death of King Bhumibol Adulyadej. + name = tr("วันคล้ายวันสวรรคตพระบาทสมเด็จพระปรมินทรมหาภูมิพลอดุลยเดช บรมนาถบพิตร") + self._add_observed(self._add_holiday_oct_13(name)) + + # ทำบุญพระบรมอัษฐิพระพุทธเจ้าหลวง (1914-1925) + # วันสวรรคตแห่งพระบาทสมเด็จพระพุทธเจ้าหลวง (1926-1937) + # วันปิยมหาราช (1946-Present) + # Status: In-Use. + # Started in 1914 (B.E. 2457). + # Was abandoned between 1938-1945. + + if self._year <= 1937 or self._year >= 1946: + if self._year >= 1946: + # HM King Chulalongkorn Memorial Day. + name = tr("วันปิยมหาราช") + elif self._year >= 1926: + # Anniversary for the Death of HM King Chulalongkorn. + name = tr("วันสวรรคตแห่งพระบาทสมเด็จพระพุทธเจ้าหลวง") + else: + # Merit-making Ceremony for the Royal Ashes of HM King Chulalongkorn. + name = tr("ทำบุญพระบรมอัษฐิพระพุทธเจ้าหลวง") + self._add_observed(self._add_holiday_oct_23(name)) + + # วันสหประชาชาติ + # Status: Defunct. + # Added since 1951 (B.E. 2494), removed in 1957. + # Technically removed in 1954, but was re-added soon after. + + if 1951 <= self._year <= 1956: + # United Nations Day. + self._add_united_nations_day(tr("วันสหประชาชาติ")) + + # เฉลิมพระชนมพรรษา (1914-1925) + # เฉลิมพระชนม์พรรษา (1926-1937) + # วันเฉลิมพระชนม์พรรษา (1938-1940) + # วันเกิดในสมเด็จพระเจ้าอยู่หัว (1941-1944)** + # วันเฉลิมพระชนมพรรษา (1945-1959) + # วันเฉลิมพระชนมพรรษา รัชกาลที่ 9 (1960-2016) + # วันคล้ายวันเฉลิมพระชนมพรรษา รัชกาลที่ 9 (2017-Present) + # Status: In-Use. + # Rama VI's Birthday was observed from DEC 30th-JAN 3rd between 1914-1925. + # Rama VII's Birthday was observed from NOV 7th-9th between 1926-1934. + # After Rama VII abdicated on MAR 2nd, 1935, there's no recorded + # change in terms of holiday arrangement until 1938, + # thus, a gap in holidays arrangement is assumed. + # Rama VIII's Birthday was observed on SEP 20th between 1938-1945. + # Between 1940-1945 the 2nd day (SEP 21st) was also observed as well. + # Rama IX's Birthday was observed from 1946-Present. + # Between 1946-1953 DEC 6th was also observed. From 1948 onwards DEC 4th + # was observed too except in 1951 when it was temporarily moved to DEC 7th. + # Replaced National Day (JUN 26th) in 1960 (B.E. 2503) by Sarit Thanarat. + # Confirmed as still in-use as Rama IX's in 2017. + # Rama IX got conferred with 'the Great' title in 2019 (B.E. 2562). + # For historical purpose, 1926-1940 entry uses the old spelling. + # **Official naming was override by "Birthday Name Decree" between 1941-1944. + + if self._year >= 2019: + # HM King Bhumibol Adulyadej the Great's Birthday Anniversary. + name = tr( + "วันคล้ายวันเฉลิมพระชนมพรรษาพระบาทสมเด็จพระบรมชนกาธิเบศร มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร" + ) + elif self._year >= 2016: + # HM King Bhumibol Adulyadej Birthday Anniversary. + name = tr("วันคล้ายวันเฉลิมพระชนมพรรษาพระบาทสมเด็จพระปรมินทรมหาภูมิพลอดุลยเดช บรมนาถบพิตร") + elif self._year >= 1960: + # HM King Bhumibol Adulyadej Birthday Anniversary. + name = tr("วันเฉลิมพระชนมพรรษาพระบาทสมเด็จพระปรมินทรมหาภูมิพลอดุลยเดช บรมนาถบพิตร") + elif self._year >= 1945: + # The King's Birthday. + name = tr("วันเฉลิมพระชนมพรรษา") + elif self._year >= 1941: + # The King's Birthday. + name = tr("วันเกิดในสมเด็จพระเจ้าอยู่หัว") + elif self._year >= 1938: + # The King's Birthday. + name = tr("วันเฉลิมพระชนม์พรรษา") + elif self._year >= 1926: + # The King's Birthday. + name = tr("เฉลิมพระชนม์พรรษา") + else: + # The King's Birthday. + name = tr("เฉลิมพระชนมพรรษา") + + if self._year >= 1946: + # Rama IX (1946-2016; In Memoriam 2017-Present). + self._add_observed(self._add_holiday_dec_5(name)) + if self._year <= 1953: + self._add_holiday_dec_6(name) + if self._year == 1951: + self._add_holiday_dec_7(name) + elif self._year >= 1948: + self._add_holiday_dec_4(name) + elif self._year >= 1938: + # Rama VIII (1938*-1945). + # *There was no decree confirming his holiday until 1938. + self._add_holiday_sep_20(name) + if self._year >= 1940: + self._add_holiday_sep_21(name) + elif 1926 <= self._year <= 1934: + # Rama VII (1926-1934). + self._add_holiday_nov_7(name) + self._add_holiday_nov_8(name) + self._add_holiday_nov_9(name) + elif self._year <= 1925: + # Rama VI (1914-1925). + if self._year <= 1924: + self._add_holiday_dec_30(name) + self._add_holiday_dec_31(name) + if self._year >= 1915: + self._add_holiday_jan_1(name) + self._add_holiday_jan_2(name) + self._add_holiday_jan_3(name) + + # วันพ่อแห่งชาติ + # Status: In-Use. + # Starts in 1980 (B.E. 2523). + # Technically, a replication of HM King Bhumibol Adulyadej's Birthday + # but it's in the official calendar, so may as well have this here. + + if self._year >= 1980: + # National Father's Day. + self._add_observed(self._add_holiday_dec_5(tr("วันพ่อแห่งชาติ"))) + + # วันรัฐธรรมนูญ + # Status: In-Use. + # Starts in 1938 (B.E. 2481). + # Initially as DEC 9th-11th, got trimmed down to DEC 10th in 1947. + # Readded Pre- and Post- holidays in 1950 before removed again in 1954. + + if self._year >= 1938: + # Constitution Day. + name = tr("วันรัฐธรรมนูญ") + self._add_observed(self._add_holiday_dec_10(name)) + if self._year <= 1947 or 1950 <= self._year <= 1953: + self._add_holiday_dec_9(name) + self._add_holiday_dec_11(name) + + # วันสิ้นปี + # Status: In-Use. + # Started in 1941 (B.E. 2484; as part of New Year Holidays) + # Abandoned in 1957, presumed to restart in 1989. + # This has its own in-lieu trigger. + + if 1941 <= self._year <= 1956 or self._year >= 1989: + # New Year's Eve. + name = tr("วันสิ้นปี") + self._add_new_years_eve(name) + + # วันหยุดชดเชยวันสิ้นปี + # Status: In-Use. + # Added separately from New Year's Eve itself so that it would't + # go over the next year. + # - CASE 1: SAT-SUN -> 1 in-lieu on TUE. + # - CASE 2: SUN-MON -> 1 in-lieu on TUE. + # See in lieu logic in `_add_observed(dt: date)`. + + if self._year >= 1995 and self._year != 2024: + self._add_observed( + date(self._year - 1, DEC, 31), name=name, rule=SAT_SUN_TO_NEXT_TUE + ) + + # Thai Lunar Calendar Holidays + # See `_ThaiLunisolar` in holidays/utils.py for more details. + + # วันมาฆบูชา + # Status: In-Use. + # Started in 1915 (B.E. 2457**), not observed between 1926-1937. + # For historical purpose, pre-1925 entry uses the old spelling. + # **For pre-1941 data, Buddhist Era year starts on APR 1st. + + if 1915 <= self._year <= 1925 or self._year >= 1938: + name = ( + # Makha Bucha. + tr("วันมาฆบูชา") + if self._year >= 1938 + # Makha Bucha, the Fourfold Assembly Day. + else tr("มาฆบูชา จาตุรงฅ์สันนิบาต") + ) + self._add_observed(self._add_makha_bucha(name)) + + # วันวิสาขบูชา + # Status: In-Use. + # Started in 1914 (B.E. 2457) with pre- and post- observance. + # From 1938-1953 only post- is added. + # For historical purpose, pre-1957 entry uses the old spelling. + # Note that the ones during Rama VII era uses ศ instead of ส. + + if self._year >= 1957: + # Visakha Bucha. + name = tr("วันวิสาขบูชา") + elif self._year >= 1938: + # Visakha Bucha. + name = tr("วันวิสาขะบูชา") + elif self._year >= 1926: + # Visakha Bucha. + name = tr("วิศาขะบูชา") + else: + # Visakha Bucha. + name = tr("วิสาขะบูชา") + + dt = self._add_visakha_bucha(name) + if self._year <= 1953: + self._add_holiday(name, _timedelta(dt, +1)) + if self._year <= 1937: + self._add_holiday(name, _timedelta(dt, -1)) + else: + self._add_observed(dt) + + # วันเข้าพรรษา-วันอาสาฬหบูชา + # Status: In-Use. + # - Started in 1914 (B.E. 2457) with Asarnha Bucha and pre-Asarnha Bucha observance. + # - From 1938-1953 only Asarnha Bucha is added. + # - 2nd, 3rd, 4th, and 5th day was also observed pre-1926. + # - Asarnha Bucha was re-added with its own name from 1962 onwards. + # For historical purpose, pre-1938 entry uses the old spelling. + # When used in combo with Asarnha Bucha Day. + # - CASE 1: FRI-SAT -> 1 in-lieu on MON + # - CASE 2: SAT-SUN -> 1 in-lieu on MON + # - CASE 3: SUN-MON -> 1 in-lieu on TUE + + name = ( + # Buddhist Lent Day. + tr("วันเข้าพรรษา") + if self._year >= 1938 + # Buddhist Lent Day. + else tr("เข้าปุริมพรรษา") + ) + dt = self._add_khao_phansa(name) + if self._year <= 1953: + self._add_asarnha_bucha(name) + if self._year <= 1937: + self._add_holiday(name, _timedelta(dt, -2)) + if self._year <= 1925: + self._add_holiday(name, _timedelta(dt, +1)) + self._add_holiday(name, _timedelta(dt, +2)) + self._add_holiday(name, _timedelta(dt, +3)) + self._add_holiday(name, _timedelta(dt, +4)) + else: + self._add_observed(dt, rule=SAT_TO_NEXT_MON) + if self._year >= 1962: + self._add_observed( + # Asarnha Bucha. + self._add_asarnha_bucha(tr("วันอาสาฬหบูชา")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + def _populate_armed_forces_holidays(self): + # วันกองทัพไทย + # Status: In-Use. + # First started in 1959 (B.E. 2502) on the Ministry of Defense Foundation Day (APR 8th). + # Moved to JAN 25th (Supposedly King Naresuan's Decisive Battle) in 1980. + # Corrected to the battle's actual date (JAN 18th) in 2007. + # Only applys to members of the Royal Thai Armed Forces. + + if self._year >= 1959: + # Royal Thai Armed Forces Day. + name = tr("วันกองทัพไทย") + if self._year >= 2007: + self._add_holiday_jan_18(name) + elif self._year >= 1980: + self._add_holiday_jan_25(name) + else: + self._add_holiday_apr_8(name) + + def _populate_bank_holidays(self): + # Bank of Thailand, the ones who decreed this wasn't found until DEC 10th, 1942. + # So it's safe to assume with that as our start date. + if self._year <= 1942: + return None + + # Bank Holidays + + # วันหยุดเพิ่มเติมสำหรับการปิดบัญชีประจำปีของธนาคารเพื่อการเกษตรและสหกรณ์การเกษตร + # Status: Defunct. + # If held on the weekends, no in-lieus. + # Abandoned in 2022. + + if self._year <= 2021: + self._add_holiday_apr_1( + # Additional Closing Day for Bank for Agriculture and Agricultural Cooperatives. + tr("วันหยุดเพิ่มเติมสำหรับการปิดบัญชีประจำปีของธนาคารเพื่อการเกษตรและสหกรณ์การเกษตร") + ) + + # วันหยุดภาคครึ่งปีของสถาบันการเงินและสถาบันการเงินเฉพาะกิจ + # Status: Defunct. + # If held on the weekends, no in-lieus. + # Abandoned in 2019. + + if self._year <= 2018: + # Mid-Year Closing Day. + self._add_holiday_jul_1(tr("วันหยุดภาคครึ่งปีของสถาบันการเงินและสถาบันการเงินเฉพาะกิจ")) + + def _populate_government_holidays(self): + # No Future Fixed Date Holidays + + # วันพืชมงคล + # Restarts in 1947 (B.E. 2490), become holiday again since 1952 + # but since we lacked the exact date records, this will be ignored. + # Become an holiday again until 1960 (B.E. 2503). + # Removed as an holiday in 1999 due to financial crisis, reinstated in 2000. + # No event was held in 2021 due to local Covid-19 situation, though it stays a day off. + # Is dated on an annual basis by the Royal Palace, always on weekdays. + # For historic research, วันเกษตรแห่งชาติ (National Agricultural Day) also concides with + # this from 1966 onwards. For earlier records the date was refered as วันแรกนาขวัญ. + # This isn't even fixed even by the Thai Lunar Calendar besides being in Month 6 + # to concides with the rainy season, but instead by Court Astrologers; All chosen dates + # so far are all in the first three weeks of MAY. + # *** NOTE: only observed by government sectors. + # TODO: Update this annually around Dec of each year. + + # Got only 1 source for 1992 and 1993, might need some recheck later. + raeknakhwan_dates = { + 1960: (MAY, 2), + 1961: (MAY, 11), + 1962: (MAY, 7), + 1963: (MAY, 10), + 1964: (MAY, 8), + 1965: (MAY, 13), + 1966: (MAY, 13), + 1967: (MAY, 11), + 1968: (MAY, 10), + 1969: (MAY, 9), + 1970: (MAY, 8), + 1971: (MAY, 7), + 1972: (MAY, 8), + 1973: (MAY, 7), + 1974: (MAY, 8), + 1975: (MAY, 7), + 1976: (MAY, 10), + 1977: (MAY, 12), + 1978: (MAY, 11), + 1979: (MAY, 7), + 1980: (MAY, 14), + 1981: (MAY, 7), + 1982: (MAY, 19), + 1983: (MAY, 11), + 1984: (MAY, 10), + 1985: (MAY, 9), + 1986: (MAY, 9), + 1987: (MAY, 8), + 1988: (MAY, 11), + 1989: (MAY, 11), + 1990: (MAY, 11), + 1991: (MAY, 10), + 1992: (MAY, 14), + 1993: (MAY, 17), + 1994: (MAY, 11), + 1995: (MAY, 10), + 1996: (MAY, 16), + 1997: (MAY, 9), + 1998: (MAY, 8), + # Not a holiday in 1999 date, was held on MAY, 14. + 2000: (MAY, 15), + 2001: (MAY, 16), + 2002: (MAY, 9), + 2003: (MAY, 8), + 2004: (MAY, 7), + 2005: (MAY, 11), + 2006: (MAY, 11), + 2007: (MAY, 10), + 2008: (MAY, 9), + 2009: (MAY, 11), + 2010: (MAY, 13), + 2011: (MAY, 13), + 2012: (MAY, 9), + 2013: (MAY, 13), + 2014: (MAY, 9), + 2015: (MAY, 13), + 2016: (MAY, 9), + 2017: (MAY, 12), + 2018: (MAY, 14), + 2019: (MAY, 9), + 2020: (MAY, 11), + 2021: (MAY, 10), + 2022: (MAY, 13), + 2023: (MAY, 17), + 2024: (MAY, 10), + 2025: (MAY, 9), + } + if 1960 <= self._year <= 2025 and self._year != 1999: + self._add_observed( + # Royal Ploughing Ceremony. + self._add_holiday(tr("วันพืชมงคล"), raeknakhwan_dates.get(self._year)) + ) + + def _populate_school_holidays(self): + # วันครู + # Status: In-Use. + # Started in 1957. + # Only applies to Ministry of Education (Students, Teachers, etc.), no in-lieus are given. + + if self._year >= 1957: + # Teacher's Day. + self._add_holiday_jan_16(tr("วันครู")) + + def _populate_workday_holidays(self): + # These are classes as "วันสำคัญ" (Date of National Observance) by the government + # but are not holidays. + + if self._year >= 1948: + # วันทหารผ่านศึก + # Status: In-Use. + # Started in 1948. + + # Thai Veterans Day. + self._add_holiday_feb_3(tr("วันทหารผ่านศึก")) + + if self._year >= 1982: + # วันวิทยาศาสตร์แห่งชาติ + # Status: In-Use. + # Started in 1982. + + # National Science Day. + self._add_holiday_aug_18(tr("วันวิทยาศาสตร์แห่งชาติ")) + + if self._year >= 1985: + # วันศิลปินแห่งชาติ + # Status: In-Use. + # Started in 1985. + + # National Artist Day. + self._add_holiday_feb_26(tr("วันศิลปินแห่งชาติ")) + + if self._year >= 1989: + # วันสตรีสากล + # Status: In-Use. + # Started in 1989. + + # International Women's Day. + self._add_womens_day(tr("วันสตรีสากล")) + + if self._year >= 1990: + # วันอนุรักษ์ทรัพยากรป่าไม้ของชาติ + # Status: In-Use. + # Started in 1990. + + # National Forest Conservation Day. + self._add_holiday_jan_14(tr("วันอนุรักษ์ทรัพยากรป่าไม้ของชาติ")) + + # วันพ่อขุนรามคำแหงมหาราช + # Status: In-Use. + # Started in 1990. + + # HM King Ramkhamhaeng Memorial Day. + self._add_holiday_jan_17(tr("วันพ่อขุนรามคำแหงมหาราช")) + + if self._year >= 1995: + # วันการบินแห่งชาติ + # Status: In-Use. + # Started in 1995. + + # National Aviation Day. + self._add_holiday_jan_13(tr("วันการบินแห่งชาติ")) + + if self._year >= 2017: + # วันพระราชทานธงชาติไทย + # Status: In-Use. + # Started in 2017. + + # Thai National Flag Day. + self._add_holiday_sep_28(tr("วันพระราชทานธงชาติไทย")) + + # วันลอยกระทง + # Status: In-Use. + # Started in 1914. + + # Loy Krathong. + self._add_loy_krathong(tr("วันลอยกระทง")) + + +class TH(Thailand): + pass + + +class THA(Thailand): + pass + + +class ThailandStaticHolidays: + """ + วันหยุดพิเศษ (เพิ่มเติม) - see Bank of Thailand's DB for Cross-Check. + + Special Bank Holidays Pre-1992: + * [HM Queen Rambai Barni's Royal Cremation Ceremony](https://web.archive.org/web/20250428140115/https://ratchakitcha.soc.go.th/documents/1560949.pdf) + """ + + # Special In Lieu Holiday. + thai_special_in_lieu_holidays = tr("วันหยุดชดเชย") + # Thai Election Day. + thai_election = tr("วันเลือกตั้ง") + # Bridge Public Holiday. + thai_bridge_public_holiday = tr("วันหยุดพิเศษ (เพิ่มเติม)") + + # Special Cases. + + # HM King Bhumibol Adulyadej's 60th Anniversary of Accession Event. + rama_ix_sixty_accession = tr("พระราชพิธีฉลองสิริราชสมบัติครบ 60 ปี พ.ศ. 2549") + # Emergency Lockdown (Thai Political Unrest). + thai_political_emergency_lockdown = tr("วันหยุดพิเศษ (การเมือง)") + # Emergency Lockdown (2011 Thailand Floods). + thai_flood_2011_emergency_lockdown = tr("วันหยุดพิเศษ (มหาอุทกภัย พ.ศ. 2554)") + # Songkran Festival. + songkran_festival = tr("วันสงกรานต์") + + special_bank_holidays = { + # HM Queen Rambai Barni's Royal Cremation Ceremony. + 1985: (APR, 9, tr("วันพระราชพิธีถวายพระเพลิงพระบรมศพสมเด็จพระนางเจ้ารำไพพรรณี")) + } + special_public_holidays = { + # 1992-1994 (include In Lieus, Checked with Bank of Thailand Data). + # 1995-1997 (Bank of Thailand Data). + # 1998-2000 (include In Lieus, Checked with Bank of Thailand Data). + # From 2001 Onwards (Checked with Bank of Thailand Data). + 1992: ( + (MAY, 18, thai_special_in_lieu_holidays), + (DEC, 7, thai_special_in_lieu_holidays), + ), + 1993: ( + (MAR, 8, thai_special_in_lieu_holidays), + (MAY, 3, thai_special_in_lieu_holidays), + (OCT, 25, thai_special_in_lieu_holidays), + (DEC, 6, thai_special_in_lieu_holidays), + ), + 1994: ( + (JAN, 3, thai_special_in_lieu_holidays), + (MAY, 2, thai_special_in_lieu_holidays), + (JUL, 25, thai_special_in_lieu_holidays), + (OCT, 24, thai_special_in_lieu_holidays), + (DEC, 12, thai_special_in_lieu_holidays), + ), + # HM King Bhumibol Adulyadej's Golden Jubilee. + 1996: (JUN, 10, tr("พระราชพิธีกาญจนาภิเษก พ.ศ. 2539")), + 1998: ( + (MAY, 11, thai_special_in_lieu_holidays), + (DEC, 7, thai_special_in_lieu_holidays), + ), + 1999: ( + (MAY, 3, thai_special_in_lieu_holidays), + (MAY, 31, thai_special_in_lieu_holidays), + (OCT, 25, thai_special_in_lieu_holidays), + (DEC, 6, thai_special_in_lieu_holidays), + ), + 2000: ( + (JAN, 3, thai_special_in_lieu_holidays), + (FEB, 21, thai_special_in_lieu_holidays), + (AUG, 14, thai_special_in_lieu_holidays), + (DEC, 11, thai_special_in_lieu_holidays), + (DEC, 29, thai_election), + ), + 2006: ( + (APR, 19, thai_election), + (JUN, 9, rama_ix_sixty_accession), + (JUN, 12, rama_ix_sixty_accession), + (JUN, 13, rama_ix_sixty_accession), + # Emergency Lockdown (Thai Military Coup d'état). + (SEP, 20, tr("วันหยุดพิเศษ (คมช.)")), + ), + 2009: ( + (JAN, 2, thai_bridge_public_holiday), + (APR, 10, thai_political_emergency_lockdown), + (APR, 16, thai_political_emergency_lockdown), + (APR, 17, thai_political_emergency_lockdown), + (JUL, 6, thai_bridge_public_holiday), + ), + 2010: ( + (MAY, 20, thai_bridge_public_holiday), + (MAY, 21, thai_bridge_public_holiday), + (AUG, 13, thai_bridge_public_holiday), + ), + 2011: ( + (MAY, 16, thai_bridge_public_holiday), + (OCT, 27, thai_flood_2011_emergency_lockdown), + (OCT, 28, thai_flood_2011_emergency_lockdown), + (OCT, 29, thai_flood_2011_emergency_lockdown), + (OCT, 30, thai_flood_2011_emergency_lockdown), + (OCT, 31, thai_flood_2011_emergency_lockdown), + ), + 2012: (APR, 9, thai_bridge_public_holiday), + 2013: (DEC, 30, thai_bridge_public_holiday), + 2014: (AUG, 11, thai_bridge_public_holiday), + 2015: ( + (JAN, 2, thai_bridge_public_holiday), + (MAY, 4, thai_bridge_public_holiday), + ), + 2016: ( + (MAY, 6, thai_bridge_public_holiday), + (JUL, 18, thai_bridge_public_holiday), + # Day of Mourning for HM King Bhumibol Adulyadej. + (OCT, 14, tr("วันหยุดพิเศษ (ร่วมถวายอาลัย ส่งดวงพระวิญญาณพระบรมศพ)")), + ), + # HM King Bhumibol Adulyadej's Royal Cremation Ceremony. + 2017: (OCT, 26, tr("วันพระราชพิธีถวายพระเพลิงพระบรมศพพระบาทสมเด็จพระปรมินทรมหาภูมิพลอดุลยเดช")), + # HM King Maha Vajiralongkorn's Coronation Celebrations. + 2019: (MAY, 6, tr("พระราชพิธีบรมราชาภิเษก พระบาทสมเด็จพระวชิรเกล้าเจ้าอยู่หัว")), + 2020: ( + (NOV, 19, thai_bridge_public_holiday), + (NOV, 20, thai_bridge_public_holiday), + (DEC, 11, thai_bridge_public_holiday), + ), + 2021: ( + (FEB, 12, thai_bridge_public_holiday), + (APR, 12, thai_bridge_public_holiday), + (SEP, 24, thai_bridge_public_holiday), + ), + 2022: ( + (JUL, 15, thai_bridge_public_holiday), + (JUL, 29, thai_bridge_public_holiday), + (OCT, 14, thai_bridge_public_holiday), + (DEC, 30, thai_bridge_public_holiday), + ), + 2023: ( + (MAY, 5, thai_bridge_public_holiday), + (JUL, 31, thai_bridge_public_holiday), + (DEC, 29, thai_bridge_public_holiday), + ), + 2024: ( + (APR, 12, thai_bridge_public_holiday), + (DEC, 30, thai_bridge_public_holiday), + ), + 2025: ( + (JUN, 2, thai_bridge_public_holiday), + (AUG, 11, thai_bridge_public_holiday), + ), + 2026: (JAN, 2, thai_bridge_public_holiday), + } + special_workday_holidays = {1999: (MAY, 14, tr("วันพืชมงคล"))} + + special_public_holidays_observed = { + 2007: (DEC, 24, thai_election), + 2020: ( + (JUL, 27, songkran_festival), + (SEP, 4, songkran_festival), + (SEP, 7, songkran_festival), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/timor_leste.py b/.venv/lib/python3.12/site-packages/holidays/countries/timor_leste.py new file mode 100644 index 00000000..618b4d93 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/timor_leste.py @@ -0,0 +1,509 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import GOVERNMENT, PUBLIC, WORKDAY +from holidays.groups import ( + ChristianHolidays, + InternationalHolidays, + IslamicHolidays, + StaticHolidays, +) +from holidays.holiday_base import HolidayBase + + +class TimorLeste( + HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays +): + """Timor Leste holidays. + + References: + * [2005 Law](https://web.archive.org/web/20240813193212/https://mj.gov.tl/jornal/lawsTL/RDTL-Law/RDTL-Laws/Law-2005-10.pdf) + * [2016 Amendment](https://web.archive.org/web/20250414152148/https://timor-leste.gov.tl/?p=14494&lang=en) + * [2022](https://web.archive.org/web/20240802065911/https://timor-leste.gov.tl/?p=30266&lang=en) + * [2023 (en_US)](https://web.archive.org/web/20250414071435/https://timor-leste.gov.tl/?lang=en&p=31750) + * [2023 (pt_PT)](https://web.archive.org/web/20250416013718/https://timor-leste.gov.tl/?lang=pt&p=31750) + * [2023 (tet)](https://web.archive.org/web/20250415232148/https://timor-leste.gov.tl/?p=31750&lang=tp) + * [2024](https://web.archive.org/web/20250421164147/https://timor-leste.gov.tl/?p=35833&lang=en) + * [2025](https://web.archive.org/web/20250416022640/https://timor-leste.gov.tl/?lang=en&p=41492) + + Limitations: + * Exact Islamic holidays dates are only available for 2011-2025; the rest are estimates. + """ + + country = "TL" + supported_categories = (GOVERNMENT, PUBLIC, WORKDAY) + default_language = "pt_TL" + # %s (estimated). + estimated_label = tr("%s (aproximada)") + supported_languages = ("en_TL", "en_US", "pt_TL", "tet", "th") + # Law No. 10/2005 Of 10 August, Public Holidays and Official Commemorative Dates. + start_year = 2006 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=TimorLesteIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, TimorLesteStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Fixed Date Public Holidays. + + # New Year's Day. + self._add_new_years_day(tr("Dia de Ano Novo")) + + # Dia dos Veteranos. + # First appeared in 2017. + + if self._year >= 2017: + # Veteran's Day. + self._add_holiday_mar_3(tr("Dia dos Veteranos")) + + # International Worker's Day. + self._add_labor_day(tr("Dia Mundial do Trabalhador")) + + # Restoration of Independence Day. + self._add_holiday_may_20(tr("Dia da Restauração da Independência")) + + # Popular Consultation Day. + self._add_holiday_aug_30(tr("Dia da Consulta Popular")) + + # All Saints' Day. + self._add_all_saints_day(tr("Dia de Todos os Santos")) + + # All Souls' Day. + self._add_all_souls_day(tr("Dia de Todos os Fiéis Defuntos")) + + # Dia Nacional da Mulher. + # Originally classed as "Commemorative Date" only, reclassified in 2023. + + if self._year >= 2023: + # National Women's Day. + self._add_holiday_nov_3(tr("Dia Nacional da Mulher")) + + # National Youth Day. + self._add_holiday_nov_12(tr("Dia Nacional da Juventude")) + + # Proclamation of Independence Day. + self._add_holiday_nov_28(tr("Dia da Proclamação da Independência")) + + # Dia da Memória + # Created to replaced the original National Heroes Day in 2017. + + if self._year >= 2017: + # Memorial Day. + self._add_holiday_dec_7(tr("Dia da Memória")) + + self._add_immaculate_conception_day( + # Day of Our Lady of Immaculate Conception and Timor-Leste Patroness. + tr("Dia de Nossa Senhora da Imaculada Conceição, padroeira de Timor-Leste") + ) + + # Christmas Day. + self._add_christmas_day(tr("Dia de Natal")) + + # Dia dos Heróis Nacionais. + # Moved to Dec 31 in 2017. + + # National Heroes Day. + name = tr("Dia dos Heróis Nacionais") + if self._year >= 2017: + self._add_holiday_dec_31(name) + else: + self._add_holiday_dec_7(name) + + # Variable Date Public Holidays. + + # Holy Friday. + self._add_good_friday(tr("Sexta-Feira Santa")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("Idul Fitri")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Festa do Corpo de Deus")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Idul Adha")) + + def _populate_workday_holidays(self): + # Fixed Date Government Holidays. + + # International Children's Day. + self._add_childrens_day(tr("Dia Mundial da Criança")) + + self._add_holiday_aug_20( + # Day of the Armed Forces for the National Liberation of Timor-Leste (FALINTIL). + tr("Dia das Forças Armadas de Libertação Nacional de Timor-Leste (FALINTIL)") + ) + + # Dia Nacional da Mulher. + # Originally classed as "Commemorative Date" only, reclassified in 2023. + # Prior to reclassification, this is usually only observed as half-day holiday. i.e. + # 2010: + # https://web.archive.org/web/20250427130447/https://timor-leste.gov.tl/?p=4183&lang=en + # 2011: + # https://web.archive.org/web/20250414065353/https://timor-leste.gov.tl/?p=5979&lang=en + if self._year <= 2022: + # National Women's Day. + self._add_holiday_nov_3(tr("Dia Nacional da Mulher")) + + # International Human Rights Day. + self._add_holiday_dec_10(tr("Dia Mundial dos Direitos Humanos")) + + # Variable Date Government Holidays. + + # Ash Wednesday. + self._add_ash_wednesday(tr("Quarta-Feira de Cinzas")) + + # Holy Thursday. + self._add_holy_thursday(tr("Quinta-Feira Santa")) + + # The Day of Ascension of Jesus Christ into Heaven. + self._add_ascension_thursday(tr("Dia da Ascensão de Jesus Cristo ao Céu")) + + +class TL(TimorLeste): + pass + + +class TLS(TimorLeste): + pass + + +class TimorLesteIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 24), + 2016: (SEP, 18), + 2017: (SEP, 1), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 19), + 2022: (JUL, 9), + 2023: (JUN, 29), + 2024: (JUN, 17), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 2011: (AUG, 31), + 2012: (AUG, 20), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 6), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } + + +class TimorLesteStaticHolidays: + # Special Holidays. + + # National Holidays (Special). + special_national_holidays = tr("Feriados Nacionais (Especiais)") + + # Presidential Election Day. + presidential_election = tr("Dia da Eleição Presidencial") + + # Parliamentary Election Day. + parliamentary_election = tr("Dia de Eleições Parlamentares") + + # Local Election Day. + local_election = tr("Dia de eleições locais") + + # Centenary of the Revolt of Dom Boaventura. + dom_boaventura_centenary = tr("Centenário da Revolta de Dom Boaventura") + + # Funeral Ceremonies of Fernando 'La Sama' de Araújo. + la_sama_funeral = tr("Cerimónias Fúnebres de Fernando 'La Sama' de Araújo") + + # 20th Anniversary Celebrations of the Popular Consultation. + popular_consultation_20th = tr("Celebrações do 20.º Aniversário da Consulta Popular") + + # 25th Anniversary Celebrations of the Popular Consultation. + popular_consultation_25th = tr("Celebrações do 25.º Aniversário da Consulta Popular") + + # Visit of His Holiness Pope Francis to Timor-Leste. + pope_francis_visit = tr("Visita de Sua Santidade o Papa Francisco a Timor-Leste") + + special_government_holidays = { + 2010: ( + # https://web.archive.org/web/20250427130447/https://timor-leste.gov.tl/?p=4183&lang=en + (NOV, 3, special_national_holidays), + # https://web.archive.org/web/20250414065444/https://timor-leste.gov.tl/?p=4437&lang=en + (DEC, 24, special_national_holidays), + (DEC, 31, special_national_holidays), + ), + 2011: ( + # https://web.archive.org/web/20250414065414/https://timor-leste.gov.tl/?p=5496&lang=en + (AUG, 15, special_national_holidays), + # https://web.archive.org/web/20250414065353/https://timor-leste.gov.tl/?p=5979&lang=en + (NOV, 3, special_national_holidays), + # https://web.archive.org/web/20250427130448/https://timor-leste.gov.tl/?p=6264&lang=en + (DEC, 26, special_national_holidays), + ), + 2012: ( + # https://web.archive.org/web/20250427130448/https://timor-leste.gov.tl/?p=6264&lang=en + (JAN, 2, special_national_holidays), + # https://web.archive.org/web/20250414065422/https://timor-leste.gov.tl/?p=6347&lang=en + (JAN, 23, special_national_holidays), + # https://web.archive.org/web/20250414065452/https://timor-leste.gov.tl/?p=6471&lang=en + (FEB, 22, special_national_holidays), + # https://web.archive.org/web/20250427130503/https://timor-leste.gov.tl/?p=6621&lang=en + (MAR, 16, presidential_election), + # https://web.archive.org/web/20250414065432/https://timor-leste.gov.tl/?p=6760&lang=en + (APR, 16, presidential_election), + (APR, 17, presidential_election), + # https://web.archive.org/web/20250427130515/https://timor-leste.gov.tl/?p=7035&lang=en + (JUL, 6, parliamentary_election), + # https://web.archive.org/web/20250427130516/https://timor-leste.gov.tl/?p=7046&lang=en + (JUL, 9, parliamentary_election), + # https://web.archive.org/web/20250414065639/https://timor-leste.gov.tl/?p=7474&lang=en + (NOV, 27, dom_boaventura_centenary), + (NOV, 29, dom_boaventura_centenary), + # https://web.archive.org/web/20250414065642/http://timor-leste.gov.tl/?p=7550&lang=en + (DEC, 24, special_national_holidays), + (DEC, 26, special_national_holidays), + (DEC, 31, special_national_holidays), + ), + 2013: ( + # https://web.archive.org/web/20250427130528/https://timor-leste.gov.tl/?p=7715&lang=en + (FEB, 13, special_national_holidays), + # https://web.archive.org/web/20250427130538/https://timor-leste.gov.tl/?p=7918&lang=en + (MAR, 28, special_national_holidays), + (APR, 1, special_national_holidays), + # https://web.archive.org/web/20250414065612/https://timor-leste.gov.tl/?p=8664&lang=en + (AUG, 20, special_national_holidays), + # https://web.archive.org/web/20250414065748/https://timor-leste.gov.tl/?p=9392&lang=en + (NOV, 29, special_national_holidays), + # https://web.archive.org/web/20250414065744/http://timor-leste.gov.tl/?p=9475&lang=en + (DEC, 24, special_national_holidays), + (DEC, 26, special_national_holidays), + (DEC, 31, special_national_holidays), + ), + 2014: ( + # https://web.archive.org/web/20250427130548/https://timor-leste.gov.tl/?p=9759&lang=en + (MAR, 5, special_national_holidays), + # https://web.archive.org/web/20210826174115/http://timor-leste.gov.tl/?p=9964&lang=en + (APR, 17, special_national_holidays), + (APR, 21, special_national_holidays), + # https://web.archive.org/web/20250427130153/http://timor-leste.gov.tl/?p=10294&lang=en + (JUL, 22, special_national_holidays), + (JUL, 23, special_national_holidays), + # https://web.archive.org/web/20250414065707/https://timor-leste.gov.tl/?p=10524&lang=en + (AUG, 15, special_national_holidays), + (AUG, 20, special_national_holidays), + # https://web.archive.org/web/20250427130202/https://timor-leste.gov.tl/?p=11036&lang=en + (DEC, 24, special_national_holidays), + (DEC, 26, special_national_holidays), + (DEC, 31, special_national_holidays), + ), + 2015: ( + # https://web.archive.org/web/20250427130202/https://timor-leste.gov.tl/?p=11036&lang=en + (JAN, 2, special_national_holidays), + # https://web.archive.org/web/20250414065729/https://timor-leste.gov.tl/?p=11247&lang=en + (FEB, 18, special_national_holidays), + # https://web.archive.org/web/20250414065741/https://timor-leste.gov.tl/?p=11544&lang=en + (APR, 2, special_national_holidays), + # https://web.archive.org/web/20250414065752/https://timor-leste.gov.tl/?p=11966&lang=en + (MAY, 13, special_national_holidays), + # https://web.archive.org/web/20230624130431/http://timor-leste.gov.tl/?p=12246&lang=en + (JUN, 5, la_sama_funeral), + # https://web.archive.org/web/20250414065950/https://timor-leste.gov.tl/?p=13105&lang=en + (AUG, 20, special_national_holidays), + # https://web.archive.org/web/20250414065829/https://timor-leste.gov.tl/?p=14271&lang=en + (DEC, 24, special_national_holidays), + (DEC, 31, special_national_holidays), + ), + 2016: ( + # https://web.archive.org/web/20240816060741/https://timor-leste.gov.tl/?p=14482&lang=en + (FEB, 10, special_national_holidays), + # https://web.archive.org/web/20250414070020/https://timor-leste.gov.tl/?p=14827&lang=en + (MAR, 24, special_national_holidays), + # https://web.archive.org/web/20250414065859/https://timor-leste.gov.tl/?p=15740&lang=en + (JUL, 6, special_national_holidays), + # https://web.archive.org/web/20250414070052/https://timor-leste.gov.tl/?p=16626&lang=en + (NOV, 3, special_national_holidays), + # https://web.archive.org/web/20250427130231/https://timor-leste.gov.tl/?p=16998&lang=en + (DEC, 26, special_national_holidays), + ), + 2017: ( + # https://web.archive.org/web/20250427130231/https://timor-leste.gov.tl/?p=16998&lang=en + (JAN, 2, special_national_holidays), + # https://web.archive.org/web/20250427130238/https://timor-leste.gov.tl/?p=17428&lang=en + (MAR, 1, special_national_holidays), + # https://web.archive.org/web/20250427130247/https://timor-leste.gov.tl/?p=17548&lang=en + (MAR, 20, presidential_election), + (MAR, 21, presidential_election), + # https://web.archive.org/web/20250414070116/https://timor-leste.gov.tl/?p=17698&lang=en + (APR, 13, special_national_holidays), + # https://web.archive.org/web/20250427130254/https://timor-leste.gov.tl/?p=19189&lang=en + (DEC, 26, special_national_holidays), + ), + 2018: ( + # https://web.archive.org/web/20250427130254/https://timor-leste.gov.tl/?p=19189&lang=en + (JAN, 2, special_national_holidays), + # https://web.archive.org/web/20240813145627/https://timor-leste.gov.tl/?p=19411&lang=en + (FEB, 14, special_national_holidays), + # https://web.archive.org/web/20250414070149/https://timor-leste.gov.tl/?p=19452&lang=en + (FEB, 16, special_national_holidays), + # https://web.archive.org/web/20240813145438/https://timor-leste.gov.tl/?p=19693&lang=en + (MAR, 29, special_national_holidays), + # https://web.archive.org/web/20250414070232/https://timor-leste.gov.tl/?p=20199&lang=en + (AUG, 22, special_national_holidays), + ), + 2019: ( + # https://web.archive.org/web/20250414070216/https://timor-leste.gov.tl/?p=21116&lang=en + (FEB, 5, special_national_holidays), + # https://web.archive.org/web/20250414070241/https://timor-leste.gov.tl/?p=21207&lang=en + (MAR, 6, special_national_holidays), + # https://web.archive.org/web/20240812151629/https://timor-leste.gov.tl/?p=21607&lang=en + (APR, 18, special_national_holidays), + # https://web.archive.org/web/20250427130325/https://timor-leste.gov.tl/?p=22642&lang=en + (AUG, 12, special_national_holidays), + # https://web.archive.org/web/20250414070318/https://timor-leste.gov.tl/?p=22681&lang=en + (AUG, 20, special_national_holidays), + # https://web.archive.org/web/20240812044011/https://timor-leste.gov.tl/?p=22701&lang=en + (AUG, 26, popular_consultation_20th), + (AUG, 27, popular_consultation_20th), + (AUG, 28, popular_consultation_20th), + (AUG, 29, popular_consultation_20th), + # https://web.archive.org/web/20250414070227/https://timor-leste.gov.tl/?p=23277&lang=en + (OCT, 31, special_national_holidays), + # https://web.archive.org/web/20250414070409/https://timor-leste.gov.tl/?p=23417&lang=en + (DEC, 24, special_national_holidays), + (DEC, 26, special_national_holidays), + (DEC, 30, special_national_holidays), + ), + 2020: ( + # https://web.archive.org/web/20250414070409/https://timor-leste.gov.tl/?p=23417&lang=en + (JAN, 2, special_national_holidays), + # https://web.archive.org/web/20250427130330/https://timor-leste.gov.tl/?p=23607&lang=en + (FEB, 26, special_national_holidays), + # https://web.archive.org/web/20250427130347/https://timor-leste.gov.tl/?p=25455&lang=en + (AUG, 20, special_national_holidays), + # https://web.archive.org/web/20250414070335/https://timor-leste.gov.tl/?p=25502&lang=en + (AUG, 31, special_national_holidays), + # https://web.archive.org/web/20250414070433/https://timor-leste.gov.tl/?p=26030&lang=en + (NOV, 3, special_national_holidays), + # https://web.archive.org/web/20250427130521/https://timor-leste.gov.tl/?p=26365&lang=en + (DEC, 24, special_national_holidays), + ), + 2021: ( + # https://web.archive.org/web/20250414070431/https://timor-leste.gov.tl/?p=26865&lang=en + (FEB, 12, special_national_holidays), + # https://web.archive.org/web/20250414070435/https://timor-leste.gov.tl/?p=26896&lang=en + (FEB, 17, special_national_holidays), + # https://web.archive.org/web/20250414070527/https://timor-leste.gov.tl/?p=29682&lang=en + (NOV, 3, special_national_holidays), + ), + 2022: ( + # https://web.archive.org/web/20250414070535/https://timor-leste.gov.tl/?p=30029&lang=en + (FEB, 1, special_national_holidays), + # https://web.archive.org/web/20250414070533/https://timor-leste.gov.tl/?p=30194&lang=en + (MAR, 2, special_national_holidays), + # https://web.archive.org/web/20250414070535/https://timor-leste.gov.tl/?p=30254&lang=en + (MAR, 18, presidential_election), + # https://web.archive.org/web/20250414070614/https://timor-leste.gov.tl/?p=30429&lang=en + (APR, 14, special_national_holidays), + (APR, 18, presidential_election), + (APR, 19, presidential_election), + (APR, 20, presidential_election), + # https://web.archive.org/web/20250414070557/https://timor-leste.gov.tl/?p=31107&lang=en + (AUG, 29, special_national_holidays), + # https://web.archive.org/web/20250414070537/https://timor-leste.gov.tl/?p=31152&lang=en + (SEP, 6, special_national_holidays), + # https://web.archive.org/web/20250414070629/https://timor-leste.gov.tl/?p=31404&lang=en + (OCT, 31, special_national_holidays), + # https://web.archive.org/web/20250427130438/https://timor-leste.gov.tl/?p=31574&lang=en + (DEC, 9, special_national_holidays), + # https://web.archive.org/web/20250414070644/https://timor-leste.gov.tl/?p=31633&lang=en + (DEC, 26, special_national_holidays), + ), + 2023: ( + # https://web.archive.org/web/20250414070658/https://timor-leste.gov.tl/?p=31641&lang=en + (JAN, 2, special_national_holidays), + # https://web.archive.org/web/20250414070652/https://timor-leste.gov.tl/?p=31798&lang=en + (JAN, 23, special_national_holidays), + # https://web.archive.org/web/20250414070730/https://timor-leste.gov.tl/?p=32191&lang=en + (FEB, 22, special_national_holidays), + # https://web.archive.org/web/20250414070922/https://timor-leste.gov.tl/?p=32561&lang=en + (APR, 6, special_national_holidays), + (APR, 10, special_national_holidays), + # https://web.archive.org/web/20250414070723/https://timor-leste.gov.tl/?p=32590&lang=en + (APR, 20, special_national_holidays), + (APR, 21, special_national_holidays), + # https://web.archive.org/web/20250414070814/https://timor-leste.gov.tl/?p=32617&lang=en + (MAY, 19, parliamentary_election), + (MAY, 22, parliamentary_election), + # https://web.archive.org/web/20250414035027/https://timor-leste.gov.tl/?p=34792&lang=en + (OCT, 27, local_election), + # https://web.archive.org/web/20250414070835/https://timor-leste.gov.tl/?p=35060&lang=en + (NOV, 13, local_election), + # https://web.archive.org/web/20250429134659/https://timor-leste.gov.tl/?p=35627&lang=en& + (DEC, 26, special_national_holidays), + ), + 2024: ( + # https://web.archive.org/web/20250417085916/https://timor-leste.gov.tl/?p=35627&lang=en + (JAN, 2, special_national_holidays), + # https://web.archive.org/web/20250414070914/https://timor-leste.gov.tl/?p=36002&lang=en + (FEB, 14, special_national_holidays), + # https://web.archive.org/web/20250420193703/https://timor-leste.gov.tl/?p=36859&lang=en + (MAR, 28, special_national_holidays), + # https://web.archive.org/web/20250414121144/https://timor-leste.gov.tl/?p=39062&lang=en + (AUG, 28, popular_consultation_25th), + (AUG, 29, popular_consultation_25th), + # https://web.archive.org/web/20250414070900/https://timor-leste.gov.tl/?p=39068&lang=en + (SEP, 9, pope_francis_visit), + (SEP, 10, pope_francis_visit), + (SEP, 11, pope_francis_visit), + # https://web.archive.org/web/20250421064400/https://timor-leste.gov.tl/?p=40592&lang=en + (OCT, 31, special_national_holidays), + # https://web.archive.org/web/20250414071012/https://timor-leste.gov.tl/?p=40955&lang=en + (NOV, 29, special_national_holidays), + # https://web.archive.org/web/20250414071025/https://timor-leste.gov.tl/?p=41325&lang=en + (DEC, 24, special_national_holidays), + ), + 2025: ( + # https://web.archive.org/web/20250414070915/https://timor-leste.gov.tl/?p=41361&lang=en + (JAN, 2, special_national_holidays), + # https://web.archive.org/web/20250414070923/https://timor-leste.gov.tl/?p=41592&lang=en + (JAN, 29, special_national_holidays), + # https://web.archive.org/web/20250414070934/https://timor-leste.gov.tl/?p=42076&lang=en + (MAR, 5, special_national_holidays), + ), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/togo.py b/.venv/lib/python3.12/site-packages/holidays/countries/togo.py new file mode 100644 index 00000000..466d2c22 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/togo.py @@ -0,0 +1,182 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Togo(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Togo holidays. + + References: + * + * + * + * + * + * + * + * + * + + Ramadan start dates: + * [2015](https://web.archive.org/web/20150825071241/https://www.republicoftogo.com/toutes-les-rubriques/societe/le-mois-du-jeune-debute-le-18-juin) + * [2016](https://web.archive.org/web/20250507125256/https://www.republicoftogo.com/toutes-les-rubriques/societe/le-ramadan-debute-le-6-juin) + * [2017](https://web.archive.org/web/20250507125353/https://www.tf1info.fr/societe/le-ramadan-2017-1438-commence-le-samedi-27-mai-comment-la-date-du-debut-du-jeune-est-elle-fixee-1512235.html) + * [2018](https://web.archive.org/web/20250507125622/https://www.republicoftogo.com/toutes-les-rubriques/societe/debut-du-ramadan-demain) + * [2019](https://web.archive.org/web/20250507130404/https://www.republiquetogolaise.com/social/0605-3100-la-communaute-musulmane-du-togo-entame-ce-lundi-le-jeune-du-mois-de-ramadan) + * [2020](https://web.archive.org/web/20250507125837/https://www.republiquetogolaise.com/culture/2404-4278-debut-du-mois-de-ramadan) + * [2021](https://web.archive.org/web/20250507130643/https://www.republiquetogolaise.com/culture/1304-5393-debut-du-mois-de-ramadan) + * [2022](https://web.archive.org/web/20250507130847/https://www.republiquetogolaise.com/culture/0304-6745-debut-du-mois-de-ramadan) + * [2023](https://web.archive.org/web/20250507131022/https://www.republiquetogolaise.com/culture/2303-7864-debut-du-mois-de-ramadan) + * [2024](https://web.archive.org/web/20250507131215/https://www.republiquetogolaise.com/culture/1103-9017-debut-du-mois-de-ramadan) + * [2025](https://web.archive.org/web/20250507131439/https://www.republiquetogolaise.com/culture/2802-10360-le-jeune-de-ramadan-debute-le-1er-mars) + """ + + country = "TG" + default_language = "fr" + supported_categories = (PUBLIC, WORKDAY) + # %s (estimated). + estimated_label = tr("%s (estimé)") + supported_languages = ("en_US", "fr") + # Togo gained independence on April 27, 1960. + start_year = 1961 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=TogoIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Jour de l'an")) + + if 1967 <= self._year <= 2013: + # Liberation Day. + self._add_holiday_jan_13(tr("Fête de la libération nationale")) + + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + # Independence Day. + self._add_holiday_apr_27(tr("Fête de l'indépendance")) + + # Labor Day. + self._add_holiday_may_1(tr("Fête du travail")) + + # Ascension Day. + self._add_ascension_thursday(tr("Fête de l'Ascension")) + + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + + # Martyrs' Day. + self._add_holiday_jun_21(tr("Fête des Martyrs")) + + # Assumption Day. + self._add_holiday_aug_15(tr("Assomption")) + + # All Saints' Day. + self._add_all_saints_day(tr("Toussaint")) + + # Christmas Day. + self._add_christmas_day(tr("Noël")) + + # First Day of Ramadan. + self._add_ramadan_beginning_day(tr("Ramadan")) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("l'Aïd El-Fitr")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Tabaski")) + + def _populate_workday_holidays(self): + if self._year >= 1987: + # Anniversary of the Failed Attack on Lomé. + self._add_holiday_sep_24(tr("Anniversaire de l'attentat manqué contre Lomé")) + + +class TG(Togo): + pass + + +class TGO(Togo): + pass + + +class TogoIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2015: (SEP, 24), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + RAMADAN_BEGINNING_DATES = { + 2015: (JUN, 18), + 2016: (JUN, 6), + 2017: (MAY, 27), + 2018: (MAY, 17), + 2019: (MAY, 6), + 2020: (APR, 24), + 2021: (APR, 13), + 2022: (APR, 2), + 2023: (MAR, 23), + 2024: (MAR, 11), + 2025: (MAR, 1), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/tokelau.py b/.venv/lib/python3.12/site-packages/holidays/countries/tokelau.py new file mode 100644 index 00000000..2bef7614 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/tokelau.py @@ -0,0 +1,66 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import SUN +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Tokelau(HolidayBase, ChristianHolidays, InternationalHolidays): + """Tokelau holidays. + + References: + * + * + * [Interpretation Rules 2003](https://web.archive.org/web/20250715065528/https://paclii.org/tk/legis/consol_act_2016/ir2003240.pdf) + """ + + country = "TK" + default_language = "en_TK" + supported_languages = ("en_TK", "en_US", "tkl") + # Interpretation Rules 2003. + start_year = 2003 + weekend = {SUN} + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("New Year's Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Tokehega Day. + self._add_holiday_sep_3(tr("Tokehega Day")) + + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")) + + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")) + + +class TK(Tokelau): + pass + + +class TKL(Tokelau): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/tonga.py b/.venv/lib/python3.12/site-packages/holidays/countries/tonga.py new file mode 100644 index 00000000..7e0718ba --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/tonga.py @@ -0,0 +1,231 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import SEP, NOV, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + ALL_TO_NEAREST_MON_LATAM, + MON_TO_NEXT_TUE, + SUN_TO_NEXT_MON, +) + + +class Tonga(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Tonga holidays. + + References: + * [1988 Rev. (to)](https://archive.org/details/laokihengaahi-aho-malolo-faka-puleanga-3x/LaokihengaahiAhoMaloloFaka-Puleanga_1x.pdf) + * [1988 Rev.](https://archive.org/details/tonga-public-holidays-act-1) + * [Act 10 of 2010](https://web.archive.org/web/20241217174606/http://www.paclii.org/to/legis/num_act/pha2010243/) + * [Act 5 of 2013](https://web.archive.org/web/20250128143333/http://www.paclii.org/to/legis/num_act/pha2013243/) + * [2016 Rev.](https://web.archive.org/web/20250329175511/https://ago.gov.to/cms/images/LEGISLATION/PRINCIPAL/1919/1919-0008/PublicHolidaysAct_2.pdf) + * [2020 Rev. (to)](https://archive.org/details/laokihengaahi-aho-malolo-faka-puleanga-3x/LaokihengaahiAhoMaloloFaka-Puleanga_3x.pdf) + * [2020 Rev.](https://web.archive.org/web/20240531232255/https://ago.gov.to/cms/images/LEGISLATION/PRINCIPAL/1919/1919-0008/PublicHolidaysAct_3.pdf) + + Checked With: + * [2017](https://web.archive.org/web/20240224051858/https://www.officeholidays.com/countries/tonga/2017) + * [2018](https://web.archive.org/web/20220713062330/https://www.gov.to/press-release/tonga-public-holidays-for-2018/) + * [2019](https://www.gov.to/press-release/tonga-public-holidays-for-2019-2/) + * [2020](https://web.archive.org/web/20211207144655/https://www.gov.to/press-release/tonga-public-holidays-for-2020/) + * [2021](https://web.archive.org/web/20201101134029/https://www.gov.to/press-release/tonga-public-holidays-for-2021/) + * [2022](https://web.archive.org/web/20211216154631/https://www.gov.to/press-release/tonga-public-holidays-for-2022/) + * [2023](https://web.archive.org/web/20221116225808/https://www.gov.to/press-release/tonga-public-holidays-for-2023/) + * [2024](https://www.gov.to/press-release/tonga-public-holidays-for-2024/) + + 1988 Revision Observance Rule: + + Provided always that when any of the days specified falls upon a Sunday, + the next following Monday shall be a public holiday and that whenever + the twenty-sixth day of December falls upon a Monday the day following + shall be a public holiday. (Amended by Act 11 of 1970.) + + 2016 and 2020 Revision Observance Rule: + + Provided that when any public holidays specified, except Christmas Day, the + day immediately succeeding Christmas Day, New Years Day, Good Friday, + Easter Monday, ANZAC Day, Birthday of the reigning Sovereign of Tonga + and Birthday of the Heir to the Crown of Tonga, falls upon a Thursday, + Friday, Saturday or Sunday, that public holiday shall be celebrated on the next + following Monday; and if it falls on a Tuesday or Wednesday, that public + holiday shall be celebrated on the Monday before the actual public holiday. + (Amended by Act 10 of 2010: May 18, 2010.) + "Birthday of the reigning Sovereign of Tonga and Birthday of the Heir to + the Crown of Tonga" is add to the exempted list as seen above. + (Amended by Act 5 of 2013: Jun 28, 2013.) + + Further provided that the Birthday of the reigning Sovereign of Tonga and the + Birthday of the Heir to the Crown of Tonga shall be celebrated on the day it + falls, unless it falls on a Sunday in which case it would be celebrated on the + next following Monday. + (Inserted by Act 5 of 2013: Jun 28, 2013.) + """ + + country = "TO" + default_language = "to" + # %s (observed). + observed_label = tr("%s (fakatokanga'i)") + supported_languages = ("en_US", "to") + # Public Holidays Act, 1988 Revision. + start_year = 1989 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=TongaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _add_observed(self, dt: date, **kwargs): + if self._year >= 2010: + kwargs["rule"] = kwargs["rule"] or ALL_TO_NEAREST_MON_LATAM + return super()._add_observed(dt, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + jan_1 = self._add_new_years_day(tr("'Uluaki 'Aho 'o e Ta'u Fo'ou")) + if self._year <= 2016: + self._add_observed(jan_1, rule=SUN_TO_NEXT_MON) + + # Birthday of the King/Queen of Tonga. + # Topou VI: Jul 12 (2012-Present)* + # George Tupou V: May 4 (2007-2011) + # Tāufa'āhau Tupou IV: Jul 4: (1965-2006) + # * By Cabinet Decision of Jul 6, 2012 this date was declared to be Jul 4, + # thus not celebrated in 2012. + + # Birthday of the Reigning Sovereign of Tonga. + name = tr("'Aho 'Alo'i 'o 'Ene 'Afio ko e Tu'i 'o Tonga 'oku lolotonga Pule") + + if self._year == 2011: + self._move_holiday(self._add_holiday_may_4(name)) + elif 2007 <= self._year <= 2010: + self._add_observed(self._add_holiday_may_4(name), rule=SUN_TO_NEXT_MON) + elif self._year != 2012: + self._add_observed(self._add_holiday_jul_4(name), rule=SUN_TO_NEXT_MON) + + # Birthday of the Crown Prince/Princess of Tonga. + # Tupouto'a 'Ulukalala: Sep 17 (2012-Present) + # Topou VI: Jul 12 (2007-2011) + # George Tupou V: May 4 (1968-2006) + + # Birthday of the Heir to the Crown of Tonga. + name = tr("'Aho 'Alo'i 'o e 'Ea ki he Kalauni 'o Tonga") + + if self._year >= 2012: + self._add_observed(self._add_holiday_sep_17(name), rule=SUN_TO_NEXT_MON) + elif self._year >= 2010: + self._move_holiday(self._add_holiday_jul_12(name)) + elif self._year >= 2007: + self._add_observed(self._add_holiday_jul_12(name)) + else: + self._add_observed(self._add_holiday_may_4(name)) + + # Good Friday. + self._add_good_friday(tr("Falaite Lelei")) + + # Easter Monday. + self._add_easter_monday(tr("Monite 'o e Toetu'u")) + + # Anzac Day. + apr_25 = self._add_anzac_day(tr("'Aho Anzac")) + if self._year <= 2016: + self._add_observed(apr_25, rule=SUN_TO_NEXT_MON) + + # Emancipation Day. + jun_4 = self._add_holiday_jun_4(tr("'Aho Tau'ataina")) + if self._year >= 2010: + self._move_holiday(jun_4) + else: + self._add_observed(jun_4) + + # Coronation Date of Tongan Monarchy since 1970.* + # Topou VI: Jul 4 (2015-Present)** + # George Tupou V: Aug 1 (2008-2011) + # Tāufa'āhau Tupou IV: Jul 4: (1967-2006)** + # * No celebration for in-between years i.e. 2007, 2012-2014. + # ** Has de facto merged with King's Birthday. + + if 2008 <= self._year <= 2011: + name = tr( + # Anniversary of the Coronation Day of the reigning Sovereign of Tonga. + "Fakamanatu 'o e 'Aho Hilifaki Kalauni 'o 'Ene 'Afio ko e Tu'i 'o Tonga " + "'a ia 'oku lolotonga Pule" + ) + if self._year >= 2010: + self._move_holiday(self._add_holiday_aug_1(name)) + else: + self._add_observed(self._add_holiday_aug_1(name)) + + # Constitution Day. + nov_4 = self._add_holiday_nov_4(tr("'Aho Konisitutone")) + if self._year >= 2010: + self._move_holiday(nov_4) + else: + self._add_observed(nov_4) + + dec_4 = self._add_holiday_dec_4( + # Anniversary of the Coronation of HM King George Tupou I. + tr("'Aho Fakamanatu 'o e Hilifaki Kalauni 'o 'Ene 'Afio ko Siaosi Tupou I") + ) + if self._year >= 2010: + self._move_holiday(dec_4) + else: + self._add_observed(dec_4) + + # Christmas Day. + self._add_christmas_day(tr("'Aho Kilisimasi")) + + # Boxing Day. + dec_26 = self._add_christmas_day_two(tr("'Aho 2 'o e Kilisimasi")) + if self._year <= 2009: + self._add_observed(dec_26, rule=MON_TO_NEXT_TUE) + + +class TO(Tonga): + pass + + +class TON(Tonga): + pass + + +class TongaStaticHolidays: + """Tonga special holidays. + + References: + * + * + * + """ + + # Special Cases. + + # Tonga Rugby Public Holiday. + rugby_special_holidays = tr("'Aho malolo 'akapulu 'a Tonga") + + special_public_holidays = { + 2017: (NOV, 29, rugby_special_holidays), + 2019: ( + # State Funeral of 'Akilisi Pohiva. + (SEP, 19, tr("Me'afaka'eiki 'o e Siteiti 'Akilisi Pohiva")), + (NOV, 15, rugby_special_holidays), + ), + } + # Special Case for 2021 + special_public_holidays_observed = { + # Boxing Day. + 2021: (DEC, 27, tr("'Aho 2 'o e Kilisimasi")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/trinidad_and_tobago.py b/.venv/lib/python3.12/site-packages/holidays/countries/trinidad_and_tobago.py new file mode 100644 index 00000000..026b8987 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/trinidad_and_tobago.py @@ -0,0 +1,197 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars import _CustomHinduHolidays, _CustomIslamicHolidays +from holidays.calendars.gregorian import MAR, APR, MAY, JUN, JUL, AUG, OCT, NOV +from holidays.constants import OPTIONAL, PUBLIC +from holidays.groups import ( + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, +) +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SUN_TO_NEXT_WORKDAY, + SAT_SUN_TO_NEXT_WORKDAY, + WORKDAY_TO_NEXT_WORKDAY, +) + + +class TrinidadAndTobago( + ObservedHolidayBase, + ChristianHolidays, + HinduCalendarHolidays, + InternationalHolidays, + IslamicHolidays, +): + """Trinidad and Tobago holidays. + + References: + * + * + * + * + * + * + * + * + * + * + * + * + """ + + country = "TT" + default_language = "en_TT" + supported_categories = (OPTIONAL, PUBLIC) + # %s (estimated). + estimated_label = tr("%s (estimated)") + # %s (observed). + observed_label = tr("%s (observed)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observed, estimated)") + supported_languages = ("en_TT", "en_US") + # Trinidad and Tobago gained independence on August 31, 1962. + start_year = 1963 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + HinduCalendarHolidays.__init__(self, cls=TrinidadAndTobagoHinduHolidays) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=TrinidadAndTobagoIslamicHolidays, show_estimated=islamic_show_estimated + ) + super().__init__(*args, **kwargs) + + def _populate_observed(self, dts: set[date], multiple: bool = False) -> None: + for dt in sorted(dts): + self._add_observed( + dt, + rule=WORKDAY_TO_NEXT_WORKDAY + SAT_SUN_TO_NEXT_WORKDAY + if len(self.get_list(dt)) > 1 + else SUN_TO_NEXT_WORKDAY, + ) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("New Year's Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + if self._year >= 1996: + # Spiritual Baptist Liberation Day. + dts_observed.add(self._add_holiday_mar_30(tr("Spiritual Baptist Liberation Day"))) + + # Indian Arrival Day. + dts_observed.add(self._add_holiday_may_30(tr("Indian Arrival Day"))) + + # Corpus Christi. + dts_observed.add(self._add_corpus_christi_day(tr("Corpus Christi"))) + + if self._year >= 1973: + # Labor Day. + dts_observed.add(self._add_holiday_jun_19(tr("Labour Day"))) + + if self._year >= 1985: + # African Emancipation Day. + dts_observed.add(self._add_holiday_aug_1(tr("African Emancipation Day"))) + + # Independence Day. + dts_observed.add(self._add_holiday_aug_31(tr("Independence Day"))) + + if self._year >= 1976: + # Republic Day. + dts_observed.add(self._add_holiday_sep_24(tr("Republic Day"))) + + # Diwali. + dts_observed.add(self._add_diwali(tr("Divali"))) + + # Christmas Day. + dts_observed.add(self._add_christmas_day(tr("Christmas Day"))) + + # Boxing Day. + dts_observed.add(self._add_christmas_day_two(tr("Boxing Day"))) + + # Eid al-Fitr. + dts_observed.update(self._add_eid_al_fitr_day(tr("Eid-Ul-Fitr"))) + + if self.observed: + self._populate_observed(dts_observed) + + def _populate_optional_holidays(self): + # Carnival Monday. + self._add_carnival_monday(tr("Carnival Monday")) + + # Carnival Tuesday. + self._add_carnival_tuesday(tr("Carnival Tuesday")) + + +class TT(TrinidadAndTobago): + pass + + +class TTO(TrinidadAndTobago): + pass + + +class TrinidadAndTobagoHinduHolidays(_CustomHinduHolidays): + DIWALI_DATES = { + 2012: (NOV, 13), + 2013: (NOV, 4), + 2014: (OCT, 23), + 2015: (NOV, 11), + 2016: (OCT, 29), + 2017: (OCT, 19), + 2018: (NOV, 7), + 2019: (OCT, 27), + 2020: (NOV, 14), + 2021: (NOV, 4), + 2022: (OCT, 24), + 2023: (NOV, 12), + 2024: (OCT, 31), + 2025: (OCT, 20), + } + + +class TrinidadAndTobagoIslamicHolidays(_CustomIslamicHolidays): + EID_AL_FITR_DATES = { + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 6), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 22), + 2024: (APR, 10), + 2025: (MAR, 31), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/tunisia.py b/.venv/lib/python3.12/site-packages/holidays/countries/tunisia.py new file mode 100644 index 00000000..0f9cbdfd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/tunisia.py @@ -0,0 +1,93 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import InternationalHolidays, IslamicHolidays +from holidays.holiday_base import HolidayBase + + +class Tunisia(HolidayBase, InternationalHolidays, IslamicHolidays): + """Tunisia holidays.""" + + country = "TN" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + # Revolution and Youth Day - January 14 + self._add_holiday_jan_14(tr("عيد الثورة والشباب")) + + # Independence Day. + self._add_holiday_mar_20(tr("عيد الإستقلال")) + + # Martyrs' Day. + self._add_holiday_apr_9(tr("عيد الشهداء")) + + # Labor Day. + self._add_labor_day(tr("عيد العمال")) + + # Republic Day. + self._add_holiday_jul_25(tr("عيد الجمهورية")) + + # Women's Day. + self._add_holiday_aug_13(tr("عيد المرأة")) + + # Evacuation Day. + self._add_holiday_oct_15(tr("عيد الجلاء")) + + # Eid al-Fitr. + name = tr("عيد الفطر") + self._add_eid_al_fitr_day(name) + # Eid al-Fitr Holiday. + self._add_eid_al_fitr_day_two(tr("عطلة عيد الفطر")) + self._add_eid_al_fitr_day_three(tr("عطلة عيد الفطر")) + + # Arafat Day. + self._add_arafah_day(tr("يوم عرفة")) + + # Eid al-Adha. + name = tr("عيد الأضحى") + self._add_eid_al_adha_day(name) + # Eid al-Adha Holiday. + self._add_eid_al_adha_day_two(tr("عطلة عيد الأضحى")) + self._add_eid_al_adha_day_three(tr("عطلة عيد الأضحى")) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("عيد المولد النبوي")) + + +class TN(Tunisia): + pass + + +class TUN(Tunisia): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/turkey.py b/.venv/lib/python3.12/site-packages/holidays/countries/turkey.py new file mode 100644 index 00000000..b9b9a043 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/turkey.py @@ -0,0 +1,337 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.constants import HALF_DAY, PUBLIC +from holidays.groups import InternationalHolidays, IslamicHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class Turkey(HolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays): + """Turkey holidays. + + References: + * + * [Law 2739](https://web.archive.org/web/20250102114014/https://www5.tbmm.gov.tr/tutanaklar/KANUNLAR_KARARLAR/kanuntbmmc015/kanuntbmmc015/kanuntbmmc01502739.pdf) + * [Law 2429](https://web.archive.org/web/20250121111504/http://www.mevzuat.gov.tr/MevzuatMetin/1.5.2429.pdf) + * [Hijri calendar holidays](https://web.archive.org/web/20250415045516/https://vakithesaplama.diyanet.gov.tr/hicriden_miladiye.php) + """ + + country = "TR" + default_language = "tr" + # %s (estimated). + estimated_label = tr("%s (tahmini)") + supported_categories = (HALF_DAY, PUBLIC) + supported_languages = ("en_US", "tr", "uk") + # Law 2739 of 27 May 1935. + start_year = 1936 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=TurkeyIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, TurkeyStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Yılbaşı")) + + self._add_holiday_apr_23( + # National Sovereignty and Children's Day. + tr("Ulusal Egemenlik ve Çocuk Bayramı") + if self._year >= 1981 + # National Sovereignty Day. + else tr("Ulusal Egemenlik Bayramı") + ) + + if self._year >= 2009: + # Labour and Solidarity Day. + self._add_labor_day(tr("Emek ve Dayanışma Günü")) + + self._add_holiday_may_19( + # Commemoration of Atatürk, Youth and Sports Day. + tr("Atatürk'ü Anma, Gençlik ve Spor Bayramı") + if self._year >= 1981 + # Youth and Sports Day. + else tr("Gençlik ve Spor Bayramı") + ) + + if 1963 <= self._year <= 1980: + # Freedom and Constitution Day. + self._add_holiday_may_27(tr("Hürriyet ve Anayasa Bayramı")) + + if self._year >= 2017: + # Democracy and National Unity Day. + self._add_holiday_jul_15(tr("Demokrasi ve Millî Birlik Günü")) + + # Victory Day. + self._add_holiday_aug_30(tr("Zafer Bayramı")) + + # Republic Day. + name = tr("Cumhuriyet Bayramı") + self._add_holiday_oct_29(name) + if self._year <= 1980: + self._add_holiday_oct_30(name) + + # Eid al-Fitr. + name = tr("Ramazan Bayramı") + self._add_eid_al_fitr_day(name) + self._add_eid_al_fitr_day_two(name) + self._add_eid_al_fitr_day_three(name) + + # Eid al-Adha. + name = tr("Kurban Bayramı") + self._add_eid_al_adha_day(name) + self._add_eid_al_adha_day_two(name) + self._add_eid_al_adha_day_three(name) + self._add_eid_al_adha_day_four(name) + + def _populate_half_day_holidays(self): + # %s (from 1pm). + begin_time_label = self.tr("%s (saat 13.00'ten)") + + # Republic Day. + self._add_holiday_oct_28(begin_time_label % self.tr("Cumhuriyet Bayramı")) + + # Eid al-Fitr. + self._add_eid_al_fitr_eve(begin_time_label % self.tr("Ramazan Bayramı")) + + # Eid al-Adha. + self._add_arafah_day(begin_time_label % self.tr("Kurban Bayramı")) + + +class TR(Turkey): + pass + + +class TUR(Turkey): + pass + + +class TurkeyIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 1936: (MAR, 4), + 1937: (FEB, 22), + 1938: (FEB, 11), + 1939: (JAN, 31), + 1940: (JAN, 20), + 1941: ((JAN, 8), (DEC, 29)), + 1942: (DEC, 18), + 1943: (DEC, 8), + 1944: (NOV, 26), + 1945: (NOV, 15), + 1946: (NOV, 4), + 1947: (OCT, 25), + 1948: (OCT, 13), + 1949: (OCT, 3), + 1950: (SEP, 23), + 1951: (SEP, 12), + 1952: (AUG, 31), + 1953: (AUG, 20), + 1954: (AUG, 9), + 1955: (JUL, 30), + 1956: (JUL, 19), + 1957: (JUL, 8), + 1958: (JUN, 28), + 1959: (JUN, 17), + 1960: (JUN, 5), + 1961: (MAY, 25), + 1962: (MAY, 14), + 1963: (MAY, 4), + 1964: (APR, 23), + 1965: (APR, 12), + 1966: (APR, 1), + 1967: (MAR, 21), + 1968: (MAR, 10), + 1969: (FEB, 27), + 1970: (FEB, 17), + 1971: (FEB, 6), + 1972: (JAN, 27), + 1973: (JAN, 15), + 1974: ((JAN, 4), (DEC, 24)), + 1975: (DEC, 13), + 1976: (DEC, 2), + 1977: (NOV, 22), + 1978: (NOV, 11), + 1979: (OCT, 31), + 1980: (OCT, 19), + 1981: (OCT, 8), + 1982: (SEP, 27), + 1983: (SEP, 17), + 1984: (SEP, 6), + 1985: (AUG, 26), + 1986: (AUG, 16), + 1987: (AUG, 5), + 1988: (JUL, 24), + 1989: (JUL, 13), + 1990: (JUL, 3), + 1991: (JUN, 23), + 1992: (JUN, 11), + 1993: (JUN, 1), + 1994: (MAY, 21), + 1995: (MAY, 10), + 1996: (APR, 28), + 1997: (APR, 18), + 1998: (APR, 7), + 1999: (MAR, 28), + 2000: (MAR, 16), + 2001: (MAR, 5), + 2002: (FEB, 22), + 2003: (FEB, 11), + 2004: (FEB, 1), + 2005: (JAN, 20), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 8), + 2009: (NOV, 27), + 2010: (NOV, 16), + 2011: (NOV, 6), + 2012: (OCT, 25), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + 2026: (MAY, 27), + 2027: (MAY, 16), + 2028: (MAY, 5), + 2029: (APR, 24), + 2030: (APR, 13), + 2031: (APR, 2), + 2032: (MAR, 22), + } + + EID_AL_FITR_DATES = { + 1936: (DEC, 15), + 1937: (DEC, 4), + 1938: (NOV, 23), + 1939: (NOV, 13), + 1940: (NOV, 1), + 1941: (OCT, 22), + 1942: (OCT, 12), + 1943: (OCT, 1), + 1944: (SEP, 19), + 1945: (SEP, 8), + 1946: (AUG, 29), + 1947: (AUG, 18), + 1948: (AUG, 6), + 1949: (JUL, 27), + 1950: (JUL, 16), + 1951: (JUL, 6), + 1952: (JUN, 24), + 1953: (JUN, 13), + 1954: (JUN, 2), + 1955: (MAY, 23), + 1956: (MAY, 12), + 1957: (MAY, 1), + 1958: (APR, 20), + 1959: (APR, 9), + 1960: (MAR, 29), + 1961: (MAR, 18), + 1962: (MAR, 8), + 1963: (FEB, 25), + 1964: (FEB, 15), + 1965: (FEB, 3), + 1966: (JAN, 23), + 1967: (JAN, 12), + 1968: ((JAN, 1), (DEC, 21)), + 1969: (DEC, 11), + 1970: (DEC, 1), + 1971: (NOV, 20), + 1972: (NOV, 8), + 1973: (OCT, 28), + 1974: (OCT, 17), + 1975: (OCT, 6), + 1976: (SEP, 25), + 1977: (SEP, 15), + 1978: (SEP, 4), + 1979: (AUG, 24), + 1980: (AUG, 12), + 1981: (AUG, 1), + 1982: (JUL, 22), + 1983: (JUL, 12), + 1984: (JUN, 30), + 1985: (JUN, 20), + 1986: (JUN, 9), + 1987: (MAY, 29), + 1988: (MAY, 17), + 1989: (MAY, 6), + 1990: (APR, 26), + 1991: (APR, 16), + 1992: (APR, 4), + 1993: (MAR, 24), + 1994: (MAR, 13), + 1995: (MAR, 3), + 1996: (FEB, 20), + 1997: (FEB, 9), + 1998: (JAN, 29), + 1999: (JAN, 19), + 2000: ((JAN, 8), (DEC, 27)), + 2001: (DEC, 16), + 2002: (DEC, 5), + 2003: (NOV, 25), + 2004: (NOV, 14), + 2005: (NOV, 3), + 2006: (OCT, 23), + 2007: (OCT, 12), + 2008: (SEP, 30), + 2009: (SEP, 20), + 2010: (SEP, 9), + 2011: (AUG, 30), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 28), + 2015: (JUL, 17), + 2016: (JUL, 5), + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + 2026: (MAR, 20), + 2027: (MAR, 9), + 2028: (FEB, 26), + 2029: (FEB, 14), + 2030: (FEB, 4), + 2031: (JAN, 24), + 2032: (JAN, 14), + } + + +class TurkeyStaticHolidays: + special_public_holidays = { + # Public holiday. + 1999: (DEC, 31, tr("Genel tati̇l")) + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/turks_and_caicos_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/turks_and_caicos_islands.py new file mode 100644 index 00000000..3e4b714f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/turks_and_caicos_islands.py @@ -0,0 +1,134 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars.gregorian import JUN +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class TurksAndCaicosIslands(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Turks and Caicos Islands holidays. + + References: + * [Wikipedia](https://en.wikipedia.org/wiki/Public_holidays_in_the_Turks_and_Caicos_Islands) + * [Public Holidays Ordinance, rev. 2014](https://web.archive.org/web/20250210082429/https://gov.tc/agc/component/edocman/21-02-public-holidays-ordinance-2/viewdocument/599?Itemid=) + * [Ordinance 5 of 2020](https://web.archive.org/web/20250429025117/https://www.gov.tc/agc/component/edocman/05-of-2020-public-holidays-amendment-ordinance/viewdocument/1419?Itemid=) + * [Public Holidays Ordinance, rev. 2021](https://web.archive.org/web/20250429025602/https://www.gov.tc/agc/component/edocman/21-02-public-holidays-ordinance-2/viewdocument/2027?Itemid=) + * [2017](https://web.archive.org/web/20250608202444/https://www.facebook.com/photo/?fbid=1137860329642985&set=a.349345645161128) + * [2018](https://web.archive.org/web/20180126185141/https://gov.tc/pressoffice/999-listing-of-special-days-public-holidays-for-2018) + * [2019](https://web.archive.org/web/20250608202446/https://www.facebook.com/photo/?fbid=2514587681970236&set=a.349345645161128) + * [2020](https://web.archive.org/web/20250608202458/https://www.facebook.com/pressofficetcig/photos/a.349345645161128/2572825079479829/?type=3) + * [2021](https://www.facebook.com/pressofficetcig/photos/a.349345645161128/3511371698958491/?type=3) + * [2022](https://www.facebook.com/pressofficetcig/photos/a.349345645161128/4515540038541647/?type=3) + * [2023](https://web.archive.org/web/20250608202452/https://www.facebook.com/photo/?fbid=557741379734203&set=a.363028765872133) + * [2025](https://web.archive.org/web/20250608202433/https://www.facebook.com/photo/?fbid=1019082573584944&set=a.353200576839817) + * [Destination TCI](https://web.archive.org/web/20250429024708/https://destinationtci.tc/turks-and-caicos-islands-public-holidays/) + * [Time and Date](https://web.archive.org/web/20250429024853/https://www.timeanddate.com/holidays/turks-and-caicos-islands/) + """ + + country = "TC" + default_language = "en_TC" + # %s (observed). + observed_label = "%s (observed)" + # Separated from Jamaica in 1962. + start_year = 1963 + supported_languages = ("en_TC", "en_US") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + # Public Holidays Act 1980 established weekend-to-Monday rule. + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1980) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + # Commonwealth Day. + self._add_holiday_2nd_mon_of_mar(tr("Commonwealth Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + self._add_holiday_last_mon_of_may( + # JAGS McCartney Day. + tr("JAGS McCartney Day") + if self._year >= 2020 + # National Heroes Day. + else tr("National Heroes Day") + ) + + name = ( + # King's Birthday. + tr("King's Birthday") + if self._year >= 2023 + # Queen's Birthday. + else tr("Queen's Birthday") + ) + dates_obs = { + 2022: (JUN, 3), + 2023: (JUN, 19), + 2024: (JUN, 17), + 2025: (JUN, 23), + } + if dt := dates_obs.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_2nd_mon_of_jun(name) + + # Emancipation Day. + self._add_observed(self._add_holiday_aug_1(tr("Emancipation Day"))) + + # National Youth Day. + self._add_holiday_last_fri_of_sep(tr("National Youth Day")) + + self._add_holiday_2nd_mon_of_oct( + # National Heritage Day. + tr("National Heritage Day") + if self._year >= 2014 + # Columbus Day. + else tr("Columbus Day") + ) + + # National Day of Thanksgiving. + self._add_holiday_4th_fri_of_nov(tr("National Day of Thanksgiving")) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + +class TC(TurksAndCaicosIslands): + pass + + +class TCA(TurksAndCaicosIslands): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/tuvalu.py b/.venv/lib/python3.12/site-packages/holidays/countries/tuvalu.py new file mode 100644 index 00000000..2d5bc51a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/tuvalu.py @@ -0,0 +1,175 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class Tuvalu(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Tuvalu holidays. + + References: + * [Public holidays in Tuvalu](https://en.wikipedia.org/wiki/Public_holidays_in_Tuvalu) + * [Today's and Upcoming Holidays in Tuvalu](https://web.archive.org/web/20250310164727/https://www.timeanddate.com/holidays/tuvalu/) + * [Public Holidays (Amendment) Act 1990](https://web.archive.org/web/20250429073846/https://www.paclii.org/cgi-bin/sinodisp/tv/legis/num_act/pha1990243/pha1990243.html) + * [Public Holidays Act 1](https://archive.org/details/tuvalu-public-holidays-act-revised-2008) + * [Public Holidays (Amendment) Act 2018](https://archive.org/details/tuvalu-public-holidays-amendment-act-2018) + * [Public Holidays (Amendment) Act 2020](https://archive.org/details/tuvalu-public-holidays-amendment-act-2020) + * [Public Holidays Act 2](https://archive.org/details/tuvalu-public-holidays-act-revised-2022) + * [Codes for the representation of names of countries and their subdivisions](https://www.iso.org/obp/ui/#iso:code:3166:TV) + * [TUVALU-NEWS.TV](https://web.archive.org/web/20140915180104/http://www.tuvalu-news.tv/archives/2007/01/island_special_public_holidays.html) + """ + + country = "TV" + default_language = "tvl" + # %s (observed). + observed_label = tr("%s (fakamatakuga)") + # Tuvalu became fully independent of the United Kingdom on October 1, 1978 + # Tuvalu's PUBLIC HOLIDAYS (AMENDMENT) ACT 1990 (Act 2 of 1990) + # It was first proclaimed on FEB 7th, 1990 + start_year = 1990 + subdivisions = ( + "FUN", # Funafuti. + "NIT", # Niutao. + "NKF", # Nukufetau. + "NKL", # Nukulaelae. + "NMA", # Nanumea. + "NMG", # Nanumaga. + "NUI", # Nui. + "VAI", # Vaitupu. + ) + subdivisions_aliases = { + # Town/Island Councils. + "Funafuti": "FUN", + "Niutao": "NIT", + "Nukufetau": "NKF", + "Nukulaelae": "NKL", + "Nanumea": "NMA", + "Nanumaga": "NMG", + "Nanumanga": "NMG", # Ex-ISO code alias + "Nui": "NUI", + "Vaitupu": "VAI", + } + supported_languages = ("en_GB", "en_US", "tvl") + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("Tausaga Fou"))) + + if self._year <= 2020: + # Commonwealth Day. + self._add_holiday_2nd_mon_of_mar(tr("Aso Atefenua")) + + # Good Friday. + self._add_good_friday(tr("Aso toe tu")) + + # Easter Monday. + self._add_easter_monday(tr("Toe Tu aso gafua")) + + # Gospel Day. + self._add_holiday_1_day_past_2nd_sun_of_may(tr("Te Aso o te Tala Lei")) + + self._add_holiday_2nd_sat_of_jun( + # King's Birthday. + tr("Asofanau Tupu") + if self._year >= 2023 + # Queen's Birthday. + else tr("Asofanau Fafine") + ) + + # National Children's Day. + name = tr("Aso Tamaliki") + if self._year >= 2019: + # National Youth Day. + self._add_holiday_1st_mon_of_aug(tr("Aso tupulaga")) + + # National Children's Day. + self._add_holiday_1_day_past_2nd_sun_of_oct(name) + else: + # National Children's Day. + self._add_holiday_1st_mon_of_aug(name) + + # Tuvalu Day. + name = tr("Tutokotasi") + self._add_observed(self._add_holiday_oct_1(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + self._add_observed(self._add_holiday_oct_2(name), rule=SAT_SUN_TO_NEXT_MON_TUE) + + # https://en.wikipedia.org/wiki/King's_Official_Birthday#Tuvalu + if self._year <= 2022: + # Heir to the Throne's Birthday. + self._add_holiday_2nd_mon_of_nov(tr("Aso fanau o te sui ote Tupu")) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Kilisimasi")), rule=SAT_SUN_TO_NEXT_MON_TUE) + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Aso Faipele")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + def _populate_subdiv_fun_public_holidays(self): + # The Day of the Bombing. + self._add_holiday_apr_23(tr("Te Aso o te Paula")) + + # Cyclone Day. + self._add_holiday_oct_21(tr("Aso o te matagi")) + + def _populate_subdiv_nit_public_holidays(self): + # Niutao Day. + self._add_holiday_sep_17(tr("Te Aso o te Setema")) + + def _populate_subdiv_nkf_public_holidays(self): + # Nukufetau Day. + self._add_holiday_feb_11(tr("Te Aso O Tutasi")) + + def _populate_subdiv_nkl_public_holidays(self): + # Gospel Day. + self._add_holiday_may_10(tr("Te Aso o te Tala Lei")) + + def _populate_subdiv_nma_public_holidays(self): + # Golden Jubilee. + self._add_holiday_jan_8(tr("Te Po o Tefolaha")) + + # Big Day. + self._add_holiday_feb_3(tr("Po Lahi")) + + def _populate_subdiv_nmg_public_holidays(self): + # Nanumaga Day. + self._add_holiday_apr_15(tr("Aho o te Fakavae")) + + def _populate_subdiv_nui_public_holidays(self): + # Day of the Flood. + self._add_holiday_feb_16(tr("Bogin te Ieka")) + + def _populate_subdiv_vai_public_holidays(self): + # Happy Day. + self._add_holiday_nov_25(tr("Te Aso Fiafia")) + + +class TV(Tuvalu): + pass + + +class TUV(Tuvalu): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/ukraine.py b/.venv/lib/python3.12/site-packages/holidays/countries/ukraine.py new file mode 100644 index 00000000..96ff2c86 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/ukraine.py @@ -0,0 +1,382 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.calendars.julian_revised import JULIAN_REVISED_CALENDAR +from holidays.constants import PUBLIC, WORKDAY +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class Ukraine(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Ukraine holidays. + + References: + * [Labor Code of Ukraine, Art. 73](https://web.archive.org/web/20240607021920/https://zakon1.rada.gov.ua/laws/show/322-08/paran454) + * + """ + + country = "UA" + default_language = "uk" + # %s (observed). + observed_label = tr("%s (вихідний)") + supported_categories = (PUBLIC, WORKDAY) + supported_languages = ("ar", "en_US", "th", "uk") + # The current set of holidays came into force in 1991. + start_year = 1991 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self, JULIAN_REVISED_CALENDAR) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, UkraineStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _is_observed(self, dt: date) -> bool: + # 27.01.1995: holiday on weekend move to next workday + # https://web.archive.org/web/20230731064358/https://zakon.rada.gov.ua/laws/show/35/95-вр#Text + # 10.01.1998: cancelled + # https://web.archive.org/web/20250121184919/https://zakon.rada.gov.ua/laws/show/785/97-вр + # 23.04.1999: holiday on weekend move to next workday + # https://web.archive.org/web/20240315074159/http://zakon.rada.gov.ua/laws/show/576-14 + return date(1995, JAN, 27) <= dt <= date(1998, JAN, 9) or dt >= date(1999, APR, 23) + + def _populate_common(self, is_martial_law: bool = False): + # There is no public holidays in Ukraine during the period of martial law + # https://web.archive.org/web/20250418204733/https://zakon.rada.gov.ua/laws/show/2136-20 + # law is in force from March 15, 2022 + dts_observed = set() + + if (self._year >= 2023) == is_martial_law: + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("Новий рік"))) + + if self._year <= 2023: + # Christmas Day. + dts_observed.add(self._add_christmas_day(tr("Різдво Христове"), JULIAN_CALENDAR)) + + # International Women's Day. + dts_observed.add(self._add_womens_day(tr("Міжнародний жіночий день"))) + + if (self._year >= 2022) is is_martial_law: + # Easter Sunday (Pascha). + dts_observed.add(self._add_easter_sunday(tr("Великдень (Пасха)"))) + + # Holy Trinity Day. + dts_observed.add(self._add_whit_sunday(tr("Трійця"))) + + name = ( + # Labor Day. + tr("День праці") + if self._year >= 2018 + # International Workers' Solidarity Day. + else tr("День міжнародної солідарності трудящих") + ) + dts_observed.add(self._add_labor_day(name)) + if self._year <= 2017: + dts_observed.add(self._add_labor_day_two(name)) + + name = ( + # Day of Remembrance and Victory over Nazism in World War II 1939-1945. + tr("День памʼяті та перемоги над нацизмом у Другій світовій війні 1939-1945 років") + if self._year >= 2024 + # Day of Victory over Nazism in World War II (Victory Day). + else tr("День перемоги над нацизмом у Другій світовій війні (День перемоги)") + if self._year >= 2016 + # Victory Day. + else tr("День Перемоги") + ) + dts_observed.add( + self._add_world_war_two_victory_day(name, is_western=(self._year >= 2024)) + ) + + if self._year >= 1997: + # Day of the Constitution of Ukraine. + dts_observed.add(self._add_holiday_jun_28(tr("День Конституції України"))) + + if self._year >= 2022: + # Ukrainian Statehood Day. + name = tr("День Української Державності") + dts_observed.add( + self._add_holiday_jul_15(name) + if self._year >= 2024 + else self._add_holiday_jul_28(name) + ) + + # Independence Day. + name = tr("День незалежності України") + if self._year >= 1992: + dts_observed.add(self._add_holiday_aug_24(name)) + else: + self._add_holiday_jul_16(name) + + if self._year >= 2015: + name = ( + # Day of defenders of Ukraine. + tr("День захисників і захисниць України") + if self._year >= 2021 + # Defender of Ukraine Day. + else tr("День захисника України") + ) + dts_observed.add( + self._add_holiday_oct_1(name) + if self._year >= 2023 + else self._add_holiday_oct_14(name) + ) + + if self._year <= 1999: + # Anniversary of the Great October Socialist Revolution. + name = tr("Річниця Великої Жовтневої соціалістичної революції") + dts_observed.add(self._add_holiday_nov_7(name)) + dts_observed.add(self._add_holiday_nov_8(name)) + + if self._year >= 2017: + # Christmas Day. + dts_observed.add(self._add_christmas_day(tr("Різдво Христове"))) + + if self.observed and not is_martial_law: + self._populate_observed(dts_observed) + + def _populate_public_holidays(self): + self._populate_common() + + def _populate_workday_holidays(self): + self._populate_common(is_martial_law=True) + + +class UA(Ukraine): + pass + + +class UKR(Ukraine): + pass + + +class UkraineStaticHolidays: + """Ukraine special holidays. + + Substituted holidays References: + * [1991](https://web.archive.org/web/20220830105426/https://zakon.rada.gov.ua/laws/show/60-91-п) + * [1992 [1]](https://web.archive.org/web/20220816132241/https://zakon.rada.gov.ua/laws/show/202-92-п) + * [1992 [2]](https://web.archive.org/web/20220514124422/https://zakon.rada.gov.ua/laws/show/377-91-п) + * [1993 [1]](https://web.archive.org/web/20220429231922/https://zakon.rada.gov.ua/laws/show/563-93-п/) + * [1993 [2]](https://web.archive.org/web/20220501192004/https://zakon.rada.gov.ua/laws/show/725-92-п/) + * [1994](https://web.archive.org/web/20220423134711/https://zakon.rada.gov.ua/laws/show/98-94-п) + * [1995 [1]](https://web.archive.org/web/20220416193351/https://zakon.rada.gov.ua/laws/show/852-95-п/) + * [1995 [2]](https://web.archive.org/web/20220727233924/https://zakon.rada.gov.ua/laws/show/634-95-п) + * [1995 [3]](https://web.archive.org/web/20220404230852/https://zakon.rada.gov.ua/laws/show/266-95-п) + * [1996](https://web.archive.org/web/20220703182454/https://zakon.rada.gov.ua/laws/show/424-96-п) + * [1997 [1]](https://web.archive.org/web/20220710133208/https://zakon.rada.gov.ua/laws/show/326-97-п) + * [1997 [2]](https://web.archive.org/web/20240707083032/https://zakon.rada.gov.ua/laws/show/1547-96-п) + * [1998](https://web.archive.org/web/20220516171244/https://zakon.rada.gov.ua/laws/show/1404-97-п>) + * [1999 [1]](https://web.archive.org/web/20220721004702/https://zakon.rada.gov.ua/laws/show/1433-99-п>) + * [1999 [2]](https://web.archive.org/web/20220701225902/https://zakon.rada.gov.ua/laws/show/558-99-п>) + * [1999 [3]](https://web.archive.org/web/20220703131420/https://zakon.rada.gov.ua/laws/show/2070-98-п) + * [2000 [1]](https://web.archive.org/web/20220416193413/https://zakon.rada.gov.ua/laws/show/1251-2000-п/) + * [2000 [2]](https://web.archive.org/web/20220404231224/https://zakon.rada.gov.ua/laws/show/717-2000-п) + * [2001 [1]](https://web.archive.org/web/20220312201133/https://zakon.rada.gov.ua/laws/show/138-2001-р/) + * [2001 [2]](https://web.archive.org/web/20220404230657/https://zakon.rada.gov.ua/laws/show/210-2001-п) + * [2002](https://web.archive.org/web/20220521085829/https://zakon.rada.gov.ua/laws/show/202-2002-р) + * [2002 - 2003](https://web.archive.org/web/20220312195735/https://zakon.rada.gov.ua/laws/show/705-2002-р) + * [2004](https://web.archive.org/web/20220404105708/https://zakon.rada.gov.ua/laws/show/773-2003-р) + * [2005 [1]](https://web.archive.org/web/20220521235321/https://zakon.rada.gov.ua/laws/show/936-2004-р) + * [2005 [2]](https://web.archive.org/web/20220611030516/https://zakon.rada.gov.ua/laws/show/133-2005-р) + * [2006 [1]](https://web.archive.org/web/20240822140051/https://zakon.rada.gov.ua/laws/show/490-2005-р) + * [2006 [2]](https://web.archive.org/web/20220312195751/https://zakon.rada.gov.ua/laws/show/562-2005-р/) + * [2007](https://web.archive.org/web/20240823064327/https://zakon.rada.gov.ua/laws/show/612-2006-р) + * [2008 [1]](https://web.archive.org/web/20240823064327/https://zakon.rada.gov.ua/laws/show/1059-2007-р) + * [2008 [2]](https://web.archive.org/web/20240901160821/https://zakon.rada.gov.ua/laws/show/538-2008-р) + * [2009](https://web.archive.org/web/20220312195619/https://zakon.rada.gov.ua/laws/show/1458-2008-р/) + * [2010](https://web.archive.org/web/20240826001002/https://zakon.rada.gov.ua/laws/show/1412-2009-р) + * [2011](https://web.archive.org/web/20220312200622/https://zakon.rada.gov.ua/laws/show/2130-2010-р/) + * [2012](https://web.archive.org/web/20250119122439/https://zakon.rada.gov.ua/laws/show/1210-2011-р) + * [2013](https://web.archive.org/web/20250119201324/https://zakon.rada.gov.ua/laws/show/1043-2012-р) + * [2014](https://web.archive.org/web/20250421100048/https://zakon.rada.gov.ua/laws/show/920-2013-р) + * [2015](https://web.archive.org/web/20240801225558/https://zakon.rada.gov.ua/laws/show/1084-2014-р) + * [2016](https://web.archive.org/web/20221210054440/https://zakon.rada.gov.ua/laws/show/1155-2015-р) + * [2017](https://web.archive.org/web/20240609025258/https://zakon.rada.gov.ua/laws/show/850-2016-р) + * [2018](https://web.archive.org/web/20221210060148/https://zakon.rada.gov.ua/laws/show/1-2018-р) + * [2019](https://web.archive.org/web/20220316200919/https://zakon.rada.gov.ua/laws/show/7-2019-р) + * [2020](https://web.archive.org/web/20250423064733/https://zakon.rada.gov.ua/laws/show/995-2019-р) + * [2021](https://web.archive.org/web/20250402142530/https://zakon.rada.gov.ua/laws/show/1191-2020-р) + * [2022](https://web.archive.org/web/20250404010912/https://zakon.rada.gov.ua/laws/show/1004-2021-р) + + Special holidays References: + * [1995](https://web.archive.org/web/20220713111605/https://zakon.rada.gov.ua/laws/show/13/95) + """ + + # Date format (see strftime() Format Codes) + substituted_date_format = tr("%d.%m.%Y") + # Day off (substituted from %s). + substituted_label = tr("Вихідний день (перенесено з %s)") + special_public_holidays = { + 1991: ( + (MAY, 3, MAY, 5), + (MAY, 10, MAY, 12), + (JUL, 15, JUL, 13), + ), + 1992: ( + (JAN, 6, JAN, 4), + (APR, 27, MAY, 16), + ), + 1993: ( + (JAN, 8, JAN, 10), + (AUG, 23, AUG, 21), + ), + 1994: (MAR, 7, MAR, 5), + 1995: ( + # Presidential decree holiday. + (JAN, 9, tr("Вихідний згідно указу Президента")), + (MAY, 8, MAY, 6), + (AUG, 25, AUG, 27), + (NOV, 6, NOV, 4), + ), + 1996: ( + (MAY, 3, MAY, 5), + (MAY, 10, MAY, 12), + ), + 1997: ( + (JAN, 2, DEC, 28, 1996), + (JAN, 6, JAN, 4), + (JAN, 8, JAN, 11), + (APR, 29, APR, 19), + (APR, 30, MAY, 17), + ), + 1998: (JAN, 2, JAN, 4), + 1999: ( + (JAN, 8, JAN, 10), + (APR, 12, APR, 24), + (AUG, 23, AUG, 21), + ), + 2000: ( + (MAY, 8, MAY, 6), + (AUG, 25, AUG, 27), + ), + 2001: ( + (MAR, 9, MAR, 11), + (APR, 30, APR, 28), + (MAY, 10, MAY, 5), + (MAY, 11, MAY, 6), + (JUN, 29, JUN, 23), + (DEC, 31, DEC, 29), + ), + 2002: ( + (MAY, 3, MAY, 11), + (DEC, 30, DEC, 28), + (DEC, 31, DEC, 29), + ), + 2003: (JAN, 6, JAN, 4), + 2004: ( + (JAN, 2, JAN, 10), + (JAN, 5, JAN, 17), + (JAN, 6, JAN, 31), + (AUG, 23, AUG, 21), + ), + 2005: ( + (MAR, 7, MAR, 5), + (MAY, 10, MAY, 14), + (JUN, 27, JUN, 25), + ), + 2006: ( + (JAN, 3, JAN, 21), + (JAN, 4, FEB, 4), + (JAN, 5, FEB, 18), + (JAN, 6, MAR, 11), + (MAY, 8, MAY, 6), + (AUG, 25, SEP, 9), + ), + 2007: ( + (JAN, 2, JAN, 20), + (JAN, 3, JAN, 27), + (JAN, 4, FEB, 10), + (JAN, 5, FEB, 24), + (MAR, 9, MAR, 3), + (APR, 30, APR, 28), + (JUN, 29, JUN, 16), + (DEC, 31, DEC, 29), + ), + 2008: ( + (JAN, 2, JAN, 12), + (JAN, 3, JAN, 26), + (JAN, 4, FEB, 9), + (APR, 29, MAY, 17), + (APR, 30, MAY, 31), + ), + 2009: ( + (JAN, 2, JAN, 10), + (JAN, 5, JAN, 24), + (JAN, 6, FEB, 7), + ), + 2010: ( + (JAN, 4, JAN, 30), + (JAN, 5, FEB, 13), + (JAN, 6, FEB, 27), + (JAN, 8, MAR, 13), + (AUG, 23, AUG, 21), + ), + 2011: ( + (MAR, 7, MAR, 12), + (JUN, 27, JUN, 25), + ), + 2012: ( + (MAR, 9, MAR, 3), + (APR, 30, APR, 28), + (JUN, 29, JUL, 7), + (DEC, 31, DEC, 29), + ), + 2013: ( + (MAY, 3, MAY, 18), + (MAY, 10, JUN, 1), + ), + 2014: ( + (JAN, 2, JAN, 11), + (JAN, 3, JAN, 25), + (JAN, 6, FEB, 8), + ), + 2015: ( + (JAN, 2, JAN, 17), + (JAN, 8, JAN, 31), + (JAN, 9, FEB, 14), + ), + 2016: ( + (JAN, 8, JAN, 16), + (MAR, 7, MAR, 12), + (JUN, 27, JUL, 2), + ), + 2017: ( + (MAY, 8, MAY, 13), + (AUG, 25, AUG, 19), + ), + 2018: ( + (MAR, 9, MAR, 3), + (APR, 30, MAY, 5), + (JUN, 29, JUN, 23), + (DEC, 24, DEC, 22), + (DEC, 31, DEC, 29), + ), + 2019: ( + (APR, 30, MAY, 11), + (DEC, 30, DEC, 21), + (DEC, 31, DEC, 28), + ), + 2020: (JAN, 6, JAN, 11), + 2021: ( + (JAN, 8, JAN, 16), + (AUG, 23, AUG, 28), + (OCT, 15, OCT, 23), + ), + 2022: (MAR, 7, MAR, 12), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/united_arab_emirates.py b/.venv/lib/python3.12/site-packages/holidays/countries/united_arab_emirates.py new file mode 100644 index 00000000..23d2702d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/united_arab_emirates.py @@ -0,0 +1,247 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + FRI, + SAT, + SUN, +) +from holidays.constants import GOVERNMENT, OPTIONAL, PUBLIC +from holidays.groups import InternationalHolidays, IslamicHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class UnitedArabEmirates(HolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays): + """United Arab Emirates holidays. + + References: + * [2017](https://web.archive.org/web/20230209125034/https://www.khaleejtimes.com/nation/uae-official-public-holidays-list-2017) + * [2018](https://web.archive.org/web/20201111212817/https://www.khaleejtimes.com/nation/Here-are-the-holidays-remaining-in-2018-in-UAE) + * [2019](https://web.archive.org/web/20240513133929/https://www.thenational.ae/uae/government/uae-public-holidays-for-2019-and-2020-announced-by-cabinet-1.833425) + * [2020](https://web.archive.org/web/20250424164934/https://u.ae/en/information-and-services/public-holidays-and-religious-affairs/public-holidays) + * [2021](https://web.archive.org/web/20210928140451/http://wam.ae/en/details/1395302957696) + * [2022](https://web.archive.org/web/20250207171255/https://www.khaleejtimes.com/ramadan/eid-al-fitr-holiday-announced-in-uae-3) + * 2023: + * + * + * [2024](https://web.archive.org/web/20241001104607/https://www.timeoutdubai.com/news/uae-public-holidays-in-2024) + * [2025](https://web.archive.org/web/20250415131512/https://www.timeoutdubai.com/news/uae-public-holidays-2025) + + Holidays are regulated by the Article 74 of [Federal Law No. + 08](https://web.archive.org/web/20250304004437/https://www.ilo.org/dyn/natlex/docs/ELECTRONIC/11956/69376/F417089305/ARE11956.pdf) + for the year 1980. + + However the law is not applied literally, and was amended often in the past few years. + """ + + country = "AE" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + supported_categories = (GOVERNMENT, OPTIONAL, PUBLIC) + supported_languages = ("ar", "en_US", "th") + # Founded on DEC 2, 1971. + start_year = 1972 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=UnitedArabEmiratesIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, UnitedArabEmiratesStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # The resting days are Saturday and Sunday since Jan 1, 2022. + # https://web.archive.org/web/20250216144205/https://time.com/6126260/uae-working-days-weekend/ + self.weekend = {FRI, SAT} if self._year <= 2021 else {SAT, SUN} + + # New Year's Day. + self._add_new_years_day(tr("رأس السنة الميلادية")) + + if 2015 <= self._year <= 2023: + # Commemoration Day. + name = tr("يوم الشهيد") + if self._year >= 2019: + self._add_holiday_dec_1(name) + else: + self._add_holiday_nov_30(name) + + # National Day. + national_day = tr("اليوم الوطني") + self._add_holiday_dec_2(national_day) + self._add_holiday_dec_3(national_day) + + # Eid al-Fitr. + self._add_eid_al_fitr_day(tr("عيد الفطر")) + + # Eid al-Fitr Holiday. + eid_al_fitr_holiday = tr("عطلة عيد الفطر") + self._add_eid_al_fitr_day_two(eid_al_fitr_holiday) + self._add_eid_al_fitr_day_three(eid_al_fitr_holiday) + if 2019 <= self._year <= 2024: + # Ramadan 30 not confirmed yet for 2025 onwards. + self._add_eid_al_fitr_eve(eid_al_fitr_holiday) + + # Arafat Day. + self._add_arafah_day(tr("وقفة عرفة")) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("عيد الأضحى")) + + # Eid al-Adha Holiday. + eid_al_adha_holiday = tr("عطلة عيد الأضحى") + self._add_eid_al_adha_day_two(eid_al_adha_holiday) + self._add_eid_al_adha_day_three(eid_al_adha_holiday) + + # Islamic New Year. + self._add_islamic_new_year_day(tr("رأس السنة الهجرية")) + + if self._year <= 2018: + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("ليلة المعراج")) + + # Prophet's Birthday. + self._add_mawlid_day(tr("عيد المولد النبوي")) + + +class AE(UnitedArabEmirates): + pass + + +class ARE(UnitedArabEmirates): + pass + + +class UnitedArabEmiratesIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2017: (SEP, 1), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 4), + } + + EID_AL_FITR_DATES = { + 2017: (JUN, 25), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + HIJRI_NEW_YEAR_DATES = { + 2017: (SEP, 22), + 2018: (SEP, 11), + 2019: (AUG, 31), + 2020: (AUG, 23), + 2021: (AUG, 12), + 2022: (JUL, 30), + 2023: (JUL, 21), + 2024: (JUL, 7), + 2025: (JUN, 26), + } + + ISRA_AND_MIRAJ_DATES = { + 2017: (APR, 23), + 2018: (APR, 14), + } + + MAWLID_DATES = { + 2017: (NOV, 30), + 2018: (NOV, 18), + 2019: (NOV, 9), + 2020: (OCT, 29), + 2021: (OCT, 21), + 2022: (OCT, 8), + 2023: (SEP, 29), + 2024: (SEP, 15), + 2025: (SEP, 5), + } + + +class UnitedArabEmiratesStaticHolidays: + """United Arab Emirates special holidays. + + Special Eid al-Fitr entries for Ramadan 29 from 2020 onwards: + * [2019](https://web.archive.org/web/20250429081745/https://www.mohre.gov.ae/en/media-centre/news/30/1/2019/عطلة-رسمية-يوم-زيارة-البابا-للمشاركين-في-فعالياته-من-القطاع-الخاص.aspx?DisableResponsive=1) + * [2020](https://web.archive.org/web/20210804023600/https://gulfbusiness.com/revealed-uae-private-sector-holidays-for-eid-al-fitr-2020/) + * [2021](https://web.archive.org/web/20220508191126/https://www.timeoutdubai.com/news/466278-eid-al-fitr-holiday-2021-dubai) + * 2022: + * + * + * [2023](https://web.archive.org/web/20240301231911/https://hrme.economictimes.indiatimes.com/news/industry/uae-cabinet-announces-national-day-holiday-for-federal-government-from-2-to-4-december/105455071) + * [2024](https://web.archive.org/web/20240720085937/http://www.timeoutdubai.com/news/eid-al-fitr-2024-expected-dates-ramadan) + * [2025](https://web.archive.org/web/20250415131512/https://www.timeoutdubai.com/news/uae-public-holidays-2025) + + Cross-Checked With: + * + """ + + # Eid al-Fitr Holiday. + eid_al_fitr_holiday = tr("عطلة عيد الفطر") + # Death of Sheikh Khalifa bin Zayed Al Nahyan. + sheikh_khalifa_bin_zayed_death = tr("وفاة الشيخ خليفة بن زايد آل نهيان") + + special_government_holidays = { + 2022: ( + (MAY, 5, eid_al_fitr_holiday), + (MAY, 6, eid_al_fitr_holiday), + (MAY, 7, eid_al_fitr_holiday), + (MAY, 8, eid_al_fitr_holiday), + ), + # National Day. + 2023: (DEC, 4, tr("اليوم الوطني")), + } + special_optional_holidays = { + # Pope Francis' Visit Day. + 2019: (FEB, 5, tr("يوم زيارة البابا فرنسيس")), + } + special_public_holidays = { + 2020: (MAY, 22, eid_al_fitr_holiday), + 2021: (MAY, 11, eid_al_fitr_holiday), + 2022: ( + (APR, 30, eid_al_fitr_holiday), + (MAY, 14, sheikh_khalifa_bin_zayed_death), + (MAY, 15, sheikh_khalifa_bin_zayed_death), + (MAY, 16, sheikh_khalifa_bin_zayed_death), + ), + 2024: (APR, 8, eid_al_fitr_holiday), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/united_kingdom.py b/.venv/lib/python3.12/site-packages/holidays/countries/united_kingdom.py new file mode 100644 index 00000000..891ada52 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/united_kingdom.py @@ -0,0 +1,225 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr +from typing import Union + +from holidays.calendars.gregorian import APR, MAY, JUN, JUL, SEP, DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + MON_TO_NEXT_TUE, + SAT_SUN_TO_NEXT_MON, + SAT_SUN_TO_NEXT_MON_TUE, +) + + +class UnitedKingdom(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """United Kingdom holidays. + + References: + * + * + * + * + + The Anniversary of the Battle of the Boyne bank holiday is proclaimed annually by the + Secretary of State for Northern Ireland. + + In-Lieu observance was first provided in the Bank Holidays Extension Act 1875. + """ + + country = "GB" + default_language = "en_GB" + # %s (observed). + observed_label = tr("%s (observed)") + subdivisions: Union[tuple[()], tuple[str, ...]] = ( + "ENG", # England + "NIR", # Northern Ireland + "SCT", # Scotland + "WLS", # Wales + ) + subdivisions_aliases = { + "England": "ENG", + "Northern Ireland": "NIR", + "Scotland": "SCT", + "Wales": "WLS", + } + supported_languages = ("en_GB", "en_US", "th") + _deprecated_subdivisions = ("UK",) + # Bank Holidays Act 1871 + start_year = 1872 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, UnitedKingdomStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_MON) + # Bank Holidays Extension Act 1875 + kwargs.setdefault("observed_since", 1875) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self) -> None: + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 1978: + # May Day. + name = tr("May Day") + if self._year in {1995, 2020}: + self._add_holiday_may_8(name) + else: + self._add_holiday_1st_mon_of_may(name) + + if self._year >= 1971: + spring_bank_dates = { + 2002: (JUN, 4), + 2012: (JUN, 4), + 2022: (JUN, 2), + } + # Spring Bank Holiday. + name = tr("Spring Bank Holiday") + if dt := spring_bank_dates.get(self._year): + self._add_holiday(name, dt) + else: + self._add_holiday_last_mon_of_may(name) + + def _populate_subdiv_holidays(self): + if self.subdiv != "SCT": + if self._year >= 1975: + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("New Year's Day"))) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + super()._populate_subdiv_holidays() + + def _populate_subdiv_eng_public_holidays(self): + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + if self._year <= 1970: + # Whit Monday. + self._add_whit_monday(tr("Whit Monday")) + + if self._year >= 1971: + # Late Summer Bank Holiday. + self._add_holiday_last_mon_of_aug(tr("Late Summer Bank Holiday")) + + def _populate_subdiv_nir_public_holidays(self): + if self._year >= 1903: + # Saint Patrick's Day. + self._add_observed(self._add_holiday_mar_17(tr("Saint Patrick's Day"))) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + if self._year <= 1970: + # Whit Monday. + self._add_whit_monday(tr("Whit Monday")) + + # Battle of the Boyne. + self._add_observed(self._add_holiday_jul_12(tr("Battle of the Boyne"))) + + if self._year >= 1971: + # Late Summer Bank Holiday. + self._add_holiday_last_mon_of_aug(tr("Late Summer Bank Holiday")) + + def _populate_subdiv_sct_public_holidays(self): + # New Year's Day. + jan_1 = self._add_new_years_day(tr("New Year's Day")) + + self._add_observed( + # New Year Holiday. + self._add_new_years_day_two(tr("New Year Holiday")), + rule=SAT_SUN_TO_NEXT_MON_TUE + MON_TO_NEXT_TUE, + ) + self._add_observed(jan_1) + + # Summer Bank Holiday. + self._add_holiday_1st_mon_of_aug(tr("Summer Bank Holiday")) + + if self._year >= 2006: + # Saint Andrew's Day. + self._add_observed(self._add_holiday_nov_30(tr("Saint Andrew's Day"))) + + self._add_observed( + # Christmas Day. + self._add_christmas_day(tr("Christmas Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE if self._year >= 1974 else SAT_SUN_TO_NEXT_MON, + ) + + if self._year >= 1974: + self._add_observed( + # Boxing Day. + self._add_christmas_day_two(tr("Boxing Day")), + rule=SAT_SUN_TO_NEXT_MON_TUE, + ) + + def _populate_subdiv_wls_public_holidays(self): + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + if self._year <= 1970: + # Whit Monday. + self._add_whit_monday(tr("Whit Monday")) + + if self._year >= 1971: + # Late Summer Bank Holiday. + self._add_holiday_last_mon_of_aug(tr("Late Summer Bank Holiday")) + + +class UK(UnitedKingdom): + pass + + +class GB(UnitedKingdom): + pass + + +class GBR(UnitedKingdom): + pass + + +class UnitedKingdomStaticHolidays: + special_public_holidays = { + # Silver Jubilee of Elizabeth II. + 1977: (JUN, 7, tr("Silver Jubilee of Elizabeth II")), + # Wedding of Charles and Diana. + 1981: (JUL, 29, tr("Wedding of Charles and Diana")), + # Millennium Celebrations. + 1999: (DEC, 31, tr("Millennium Celebrations")), + # Golden Jubilee of Elizabeth II. + 2002: (JUN, 3, tr("Golden Jubilee of Elizabeth II")), + # Wedding of William and Catherine. + 2011: (APR, 29, tr("Wedding of William and Catherine")), + # Diamond Jubilee of Elizabeth II. + 2012: (JUN, 5, tr("Diamond Jubilee of Elizabeth II")), + 2022: ( + # Platinum Jubilee of Elizabeth II. + (JUN, 3, tr("Platinum Jubilee of Elizabeth II")), + # State Funeral of Queen Elizabeth II. + (SEP, 19, tr("State Funeral of Queen Elizabeth II")), + ), + # Coronation of Charles III. + 2023: (MAY, 8, tr("Coronation of Charles III")), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/united_states.py b/.venv/lib/python3.12/site-packages/holidays/countries/united_states.py new file mode 100644 index 00000000..223b916d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/united_states.py @@ -0,0 +1,1426 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr +from typing import Union + +from holidays.calendars.gregorian import ( + FEB, + MAR, + APR, + MAY, + SEP, + NOV, + DEC, + MON, + TUE, + WED, + THU, + FRI, + SAT, + SUN, +) +from holidays.constants import GOVERNMENT, PUBLIC, UNOFFICIAL +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + ObservedRule, + MON_TO_NEXT_TUE, + FRI_TO_PREV_THU, + SAT_TO_PREV_FRI, + SUN_TO_NEXT_MON, + SAT_SUN_TO_PREV_FRI, + SAT_SUN_TO_NEXT_MON, +) + +GA_IN_WASHINGTON_BIRTHDAY = ObservedRule( + {MON: +1, TUE: -1, WED: -1, THU: +1, FRI: -1, SAT: -2, SUN: -2} +) + + +class UnitedStates(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """United States of America (the) holidays. + + References: + * + * + * [Federal holidays](https://web.archive.org/web/20250426120914/https://opm.gov/policy-data-oversight/pay-leave/federal-holidays/) + * [Federal holidays history](https://web.archive.org/web/20250626042129/https://www.congress.gov/crs_external_products/R/PDF/R41990/R41990.11.pdf) + * [16 Stat. 168](https://web.archive.org/web/20240602080239/https://memory.loc.gov/cgi-bin/ampage?collId=llsl&fileName=016/llsl016.db&recNum=203) + * [Thanksgiving Day Proclamations 1789-Present](https://web.archive.org/web/20240621142029/https://www.whatsoproudlywehail.org/curriculum/the-american-calendar/thanksgiving-day-proclamations-1789-present/) + * [H.J. RES. 41](https://web.archive.org/web/20250222190611/https://www.archives.gov/global-pages/larger-image.html?i=/legislative/features/thanksgiving/images/joint-res-l.jpg&c=/legislative/features/thanksgiving/images/joint-res.caption.html) + * [H.J. RES. 41 December 9th, 1941 Amendment](https://web.archive.org/web/20250523062313/https://www.archives.gov/global-pages/larger-image.html?i=/legislative/features/thanksgiving/images/amendment-l.jpg&c=/legislative/features/thanksgiving/images/amendment.caption.html) + * [B-112525 February 27th, 1953 32 COMP. GEN. 378](https://web.archive.org/web/20201001081239/https://www.gao.gov/products/b-112525#mt=e-report) + * [Public Law 89-554](https://web.archive.org/web/20250512204449/https://www.govinfo.gov/content/pkg/STATUTE-80/pdf/STATUTE-80-Pg378.pdf) + * [E.O. 11582 of February 11th, 1971](https://web.archive.org/web/20250326234305/https://www.archives.gov/federal-register/codification/executive-order/11582.html) + * Washington's Birthday: + * [AK](https://web.archive.org/web/20250306070343/https://doa.alaska.gov/calendar/) + * [AL](https://web.archive.org/web/20250125202410/https://admincode.legislature.state.al.us/administrative-code/670-X-12-.01) + * [AR](https://web.archive.org/web/20250213100442/https://arkleg.state.ar.us/Home/FTPDocument?path=/ACTS/2001/Public/ACT304.pdf) + * [AZ](https://web.archive.org/web/20250323052619/https://www.azleg.gov/ars/1/00301.htm) + * [CA](https://web.archive.org/web/20250414210521/http://www.sos.ca.gov/state-holidays/) + * [CO](https://web.archive.org/web/20250409020643/https://leg.colorado.gov/sites/default/files/images/olls/crs2023-title-24.pdf) + * [GA](https://web.archive.org/web/20250204223228/https://www.gasupreme.us/court-information/holidays-2/) + * [HI](https://web.archive.org/web/20250313033818/https://www.capitol.hawaii.gov/hrscurrent/Vol01_Ch0001-0042F/HRS0008/HRS_0008-0001.htm) + * [ID](https://web.archive.org/web/20250328091357/https://idaho.gov/government/state-holidays/) + * IN: + * + * + * [MD](https://web.archive.org/web/20250310030503/https://msa.maryland.gov/msa/mdmanual/01glance/html/holidayl.html) + * [MI](https://web.archive.org/web/20250328094534/https://www.michigan.gov/som/government/state-holidays) + * [MN](https://web.archive.org/web/20250322174508/https://www.revisor.mn.gov/statutes/cite/645.44) + * [MT](https://web.archive.org/web/20250408030903/https://archive.legmt.gov/bills/mca/title_0010/chapter_0010/part_0020/section_0160/0010-0010-0020-0160.html) + * [NJ](https://web.archive.org/web/20250409164919/https://nj.gov/nj/about/facts/holidays/) + * [OH](https://web.archive.org/web/20250307080858/https://codes.ohio.gov/ohio-revised-code/section-1.14) + * [OK](https://web.archive.org/web/20250424191658/https://oklahoma.gov/omes/divisions/human-capital-management/employee-benefits/leave-holidays/holidays.html) + * [OR](https://web.archive.org/web/20250209222310/https://www.oregonlegislature.gov/bills_laws/ors/ors187.html) + * [PA](https://web.archive.org/web/20241226003617/https://www.legis.state.pa.us/WU01/LI/LI/US/PDF/1893/0/0138..PDF) + * [PR](https://en.wikipedia.org/wiki/Public_holidays_in_Puerto_Rico) + * [SC](https://web.archive.org/web/20250212044252/https://www.scstatehouse.gov/code/t53c005.php) + * [TN](https://web.archive.org/web/20250404130210/https://www.tn.gov/about-tn/state-holidays.html) + * [TX](https://web.archive.org/web/20250314100137/http://www.tsl.texas.gov/ref/abouttx/holidays) + * [UT](https://web.archive.org/web/20250312095206/https://le.utah.gov/xcode/Title63G/Chapter1/63G-1-S301.html) + * [VA](https://web.archive.org/web/20250309075526/https://law.lis.virginia.gov/vacode/title2.2/chapter33/section2.2-3300/) + * [VT](https://web.archive.org/web/20250415013508/https://legislature.vermont.gov/statutes/section/01/007/00371) + * [WA](https://web.archive.org/web/20250414010238/https://app.leg.wa.gov/RCW/default.aspx?cite=1.16.050) + * [WV](https://web.archive.org/web/20250328050144/http://code.wvlegislature.gov/2-2-1/) + * [WY](https://web.archive.org/web/20250405094801/https://ai.wyo.gov/about-us/state-holidays-and-office-closures) + * Columbus Day / Indigenous Peoples' Day history: + * + * + * + * + * + * [Frances Xavier Cabrini Day](https://web.archive.org/web/20250405014031/https://leg.colorado.gov/sites/default/files/2020a_1031_signed.pdf) + * Northern Mariana Islands (subdivision MP): + * + * + * American Samoa: + * + """ + + country = "US" + default_language = "en_US" + # %s (observed). + observed_label = tr("%s (observed)") + supported_languages = ("en_US", "th") + # Independence Declared on July 4th, 1776. + start_year = 1777 + subdivisions: Union[tuple[()], tuple[str, ...]] = ( + "AK", # Alaska. + "AL", # Alabama. + "AR", # Arkansas. + "AS", # American Samoa. + "AZ", # Arizona. + "CA", # California. + "CO", # Colorado. + "CT", # Connecticut. + "DC", # District of Columbia. + "DE", # Delaware. + "FL", # Florida. + "GA", # Georgia. + "GU", # Guam. + "HI", # Hawaii. + "IA", # Iowa. + "ID", # Idaho. + "IL", # Illinois. + "IN", # Indiana. + "KS", # Kansas. + "KY", # Kentucky. + "LA", # Louisiana. + "MA", # Massachusetts. + "MD", # Maryland. + "ME", # Maine. + "MI", # Michigan. + "MN", # Minnesota. + "MO", # Missouri. + "MP", # Northern Mariana Islands. + "MS", # Mississippi. + "MT", # Montana. + "NC", # North Carolina. + "ND", # North Dakota. + "NE", # Nebraska. + "NH", # New Hampshire. + "NJ", # New Jersey. + "NM", # New Mexico. + "NV", # Nevada. + "NY", # New York. + "OH", # Ohio. + "OK", # Oklahoma. + "OR", # Oregon. + "PA", # Pennsylvania. + "PR", # Puerto Rico. + "RI", # Rhode Island. + "SC", # South Carolina. + "SD", # South Dakota. + "TN", # Tennessee. + "TX", # Texas. + "UM", # United States Minor Outlying Islands. + "UT", # Utah. + "VA", # Virginia. + "VI", # Virgin Islands, U.S.. + "VT", # Vermont. + "WA", # Washington. + "WI", # Wisconsin. + "WV", # West Virginia. + "WY", # Wyoming. + ) + subdivisions_aliases = { + "Alaska": "AK", + "Alabama": "AL", + "Arkansas": "AR", + "American Samoa": "AS", + "Arizona": "AZ", + "California": "CA", + "Colorado": "CO", + "Connecticut": "CT", + "District of Columbia": "DC", + "Delaware": "DE", + "Florida": "FL", + "Georgia": "GA", + "Guam": "GU", + "Hawaii": "HI", + "Iowa": "IA", + "Idaho": "ID", + "Illinois": "IL", + "Indiana": "IN", + "Kansas": "KS", + "Kentucky": "KY", + "Louisiana": "LA", + "Massachusetts": "MA", + "Maryland": "MD", + "Maine": "ME", + "Michigan": "MI", + "Minnesota": "MN", + "Missouri": "MO", + "Northern Mariana Islands": "MP", + "Mississippi": "MS", + "Montana": "MT", + "North Carolina": "NC", + "North Dakota": "ND", + "Nebraska": "NE", + "New Hampshire": "NH", + "New Jersey": "NJ", + "New Mexico": "NM", + "Nevada": "NV", + "New York": "NY", + "Ohio": "OH", + "Oklahoma": "OK", + "Oregon": "OR", + "Pennsylvania": "PA", + "Puerto Rico": "PR", + "Rhode Island": "RI", + "South Carolina": "SC", + "South Dakota": "SD", + "Tennessee": "TN", + "Texas": "TX", + "United States Minor Outlying Islands": "UM", + "Utah": "UT", + "Virginia": "VA", + "Virgin Islands, U.S.": "VI", + "Vermont": "VT", + "Washington": "WA", + "Wisconsin": "WI", + "West Virginia": "WV", + "Wyoming": "WY", + } + supported_categories = (GOVERNMENT, PUBLIC, UNOFFICIAL) + _deprecated_subdivisions = ( + "FM", + "MH", + "PW", + ) + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=UnitedStatesStaticHolidays) + kwargs.setdefault("observed_rule", SAT_TO_PREV_FRI + SUN_TO_NEXT_MON) + # B-11252 February 27th, 1953 32 COMP. GEN. 378. + kwargs.setdefault("observed_since", 1953) + super().__init__(*args, **kwargs) + + def _populate_common(self, include_federal: bool = False): + """ + Populates common US holidays. + + Federal Holidays were first codified on June 28th, 1870 + via 16 Stat. 168. + + First regulation on holidays in-lieu observance is from B-112525 + February 27th, 1953 32 COMP. GEN. 378 document which shifts + from SUN to next MON only. + + It wouldn't be until Public Law 89-554 from September 6th, 1966 + that SAT to previous MON is listed as well. + + This would be finally consolidated as part of E.O. 11582 of + February 11th, 1971 later. + + :param include_federal: + Whether to include federal-specific holidays. + """ + self._observed_rule = ( + SAT_TO_PREV_FRI + SUN_TO_NEXT_MON if self._year >= 1966 else SUN_TO_NEXT_MON + ) + + if self._year >= 1871: + # New Year's Day. + name = tr("New Year's Day") + self._add_observed(self._add_new_years_day(name)) + # Public Law 89-554 of September 6th, 1966. + if self._year >= 1967: + self._add_observed(self._next_year_new_years_day, name=name) + + if include_federal: + if self._year >= 1986: + # Birthday of Martin Luther King, Jr.. + self._add_holiday_3rd_mon_of_jan(tr("Birthday of Martin Luther King, Jr.")) + + if self._year >= 1879: + # Washington's Birthday. + name = tr("Washington's Birthday") + if self._year >= 1971: + self._add_holiday_3rd_mon_of_feb(name) + else: + dt = self._add_holiday_feb_22(name) + # B-112525 February 27th, 1953 32 COMP. GEN. 378. + if self._year >= 1954: + self._add_observed(dt) + + if self._year >= 1971: + # Memorial Day. + self._add_holiday_last_mon_of_may(tr("Memorial Day")) + + if self._year >= 2021: + self._add_observed( + # Juneteenth National Independence Day. + self._add_holiday_jun_19(tr("Juneteenth National Independence Day")) + ) + + if self._year >= 1870: + # Independence Day. + self._add_observed(self._add_holiday_jul_4(tr("Independence Day"))) + + if self._year >= 1894: + # Labor Day. + self._add_holiday_1st_mon_of_sep(tr("Labor Day")) + + if include_federal and self._year >= 1971: + # Columbus Day. + self._add_holiday_2nd_mon_of_oct(tr("Columbus Day")) + + if self._year >= 1938: + name = ( + # Veterans Day. + tr("Veterans Day") + if self._year >= 1954 + # Armistice Day. + else tr("Armistice Day") + ) + if 1971 <= self._year <= 1977: + self._add_holiday_4th_mon_of_oct(name) + else: + self._add_observed(self._add_remembrance_day(name)) + + # Thanksgiving Day. + # Began to be declared annually in 1862 by Abraham Lincoln. + # First declared as last THU of NOV in 1863. + # Briefly moved to 3rd THU of NOV by Franklin Delano Roosevelt from 1939 to 1941. + # First codified as last THU of NOV on October 6th, 1941 via H.J. RES. 41. + # Become 4th THU of NOV from 1942 onwards via a Senate Amendment on December 9th, 1941. + # For Pre-1862 observances, see UnitedStatesStaticHolidays. + + if self._year >= 1862: + thanksgiving_day_dates = { + 1862: (APR, 10), + 1865: (DEC, 7), + 1869: (NOV, 18), + 1939: (NOV, 23), + 1940: (NOV, 21), + 1941: (NOV, 20), + } + # Thanksgiving Day. + name = tr("Thanksgiving Day") + if dt := thanksgiving_day_dates.get(self._year): + self._add_holiday(name, dt) + elif self._year >= 1942: + self._add_holiday_4th_thu_of_nov(name) + else: + self._add_holiday_last_thu_of_nov(name) + + if self._year >= 1870: + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Christmas Day"))) + + def _populate_public_holidays(self): + self._populate_common() + + if 1888 <= self._year <= 1970: + # Memorial Day. + self._add_holiday_may_30(tr("Memorial Day")) + + def _add_christmas_eve_holiday(self): + # If on Friday, observed on Thursday. + # If on Saturday or Sunday, observed on Friday. + + # Christmas Eve. + name = tr("Christmas Eve") + self._add_observed( + self._add_christmas_eve(name), name=name, rule=FRI_TO_PREV_THU + SAT_SUN_TO_PREV_FRI + ) + + def _populate_subdiv_holidays(self): + if PUBLIC not in self.categories: + return None + + if self._year >= 1986 and self.subdiv not in {"AL", "AR", "AZ", "GA", "ID", "MS", "NH"}: + # Martin Luther King Jr. Day. + self._add_holiday_3rd_mon_of_jan(tr("Martin Luther King Jr. Day")) + + if self._year >= 1879 and self.subdiv not in { + "AK", + "AL", + "AR", + "AZ", + "CA", + "CO", + "DE", + "FL", + "GA", + "HI", + "ID", + "IN", + "MD", + "MN", + "MT", + "NJ", + "NM", + "OH", + "OK", + "OR", + "PA", + "PR", + "SC", + "TN", + "TX", + "UT", + "VA", + "VI", + "VT", + "WA", + "WV", + "WY", + }: + # Washington's Birthday. + name = tr("Washington's Birthday") + if self._year >= 1971: + self._add_holiday_3rd_mon_of_feb(name) + else: + self._add_holiday_feb_22(name) + + if self._year >= 1937 and ( + self.subdiv is None + or self.subdiv + in { + "AS", + "AZ", + "CT", + "GA", + "ID", + "IL", + "IN", + "MA", + "MD", + "MO", + "MT", + "NJ", + "NY", + "OH", + "PA", + "UT", + "WV", + } + ): + # Columbus Day. + name = tr("Columbus Day") + if self._year >= 1971: + self._add_holiday_2nd_mon_of_oct(name) + else: + self._add_columbus_day(name) + + super()._populate_subdiv_holidays() + + def _populate_subdiv_ak_public_holidays(self): + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + # No observance in 1921: https://web.archive.org/web/20230208015211/https://chroniclingamerica.loc.gov/lccn/sn86072239/1922-03-29/ed-1/seq-8/ + if self._year >= 1918 and self._year != 1921: + # Seward's Day. + name = tr("Seward's Day") + if self._year >= 1955: + self._add_holiday_last_mon_of_mar(name) + else: + self._add_holiday_mar_30(name) + + if self._year >= 1971: + self._add_holiday_2nd_mon_of_oct( + # Indigenous Peoples' Day. + tr("Indigenous Peoples' Day") + if self._year >= 2015 + # Columbus Day. + else tr("Columbus Day") + ) + + # https://web.archive.org/web/20120502232826/http://www.alaskadispatch.com/article/happy-alaska-day-great-land + if self._year >= 1917: + # Alaska Day. + self._add_observed(self._add_holiday_oct_18(tr("Alaska Day"))) + + def _populate_subdiv_al_public_holidays(self): + if self._year >= 1986: + self._add_holiday_3rd_mon_of_jan( + # Martin Luther King, Jr & Robert E. Lee's Birthday. + tr("Martin Luther King, Jr & Robert E. Lee's Birthday") + ) + + if self._year >= 1879: + # George Washington & Thomas Jefferson's Birthday. + name = tr("George Washington & Thomas Jefferson's Birthday") + if self._year >= 1971: + self._add_holiday_3rd_mon_of_feb(name) + else: + self._add_holiday_feb_22(name) + + if self._year >= 1866: + # Confederate Memorial Day. + self._add_holiday_4th_mon_of_apr(tr("Confederate Memorial Day")) + + if self._year >= 1890: + # Jefferson Davis Birthday. + self._add_holiday_1st_mon_of_jun(tr("Jefferson Davis Birthday")) + + if self._year >= 1971: + self._add_holiday_2nd_mon_of_oct( + # Columbus Day / American Indian Heritage Day / Fraternal Day. + tr("Columbus Day / American Indian Heritage Day / Fraternal Day") + if self._year >= 2000 + # Columbus Day / Fraternal Day. + else tr("Columbus Day / Fraternal Day") + ) + + def _populate_subdiv_ar_public_holidays(self): + if self._year >= 1986: + self._add_holiday_3rd_mon_of_jan( + # Martin Luther King Jr. Day. + tr("Martin Luther King Jr. Day") + if self._year >= 2018 + # Dr. Martin Luther King Jr. and Robert E. Lee's Birthdays. + else tr("Dr. Martin Luther King Jr. and Robert E. Lee's Birthdays") + ) + + if self._year >= 1879: + # George Washington's Birthday and Daisy Gatson Bates Day. + name = tr("George Washington's Birthday and Daisy Gatson Bates Day") + if self._year >= 1971: + self._add_holiday_3rd_mon_of_feb(name) + else: + self._add_holiday_feb_22(name) + + def _populate_subdiv_as_public_holidays(self): + if self._year >= 1901: + # American Samoa Flag Day. + self._add_observed(self._add_holiday_apr_17(tr("American Samoa Flag Day"))) + + if self._year >= 1983: + # Manu'a Islands Cession Day. + self._add_observed(self._add_holiday_jul_16(tr("Manu'a Islands Cession Day"))) + + # White Sunday. + self._add_holiday_2nd_sun_of_oct(tr("White Sunday")) + + def _populate_subdiv_az_public_holidays(self): + if self._year >= 1986: + # Dr. Martin Luther King Jr. / Civil Rights Day. + self._add_holiday_3rd_mon_of_jan(tr("Dr. Martin Luther King Jr. / Civil Rights Day")) + + if self._year >= 1971: + # Lincoln/Washington Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Lincoln/Washington Presidents' Day")) + + def _populate_subdiv_ca_public_holidays(self): + if 1971 <= self._year <= 2009: + # Lincoln's Birthday. + self._add_observed(self._add_holiday_feb_12(tr("Lincoln's Birthday"))) + + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + if self._year >= 2014: + # Susan B. Anthony Day. + self._add_holiday_feb_15(tr("Susan B. Anthony Day")) + + if self._year >= 1995: + self._add_observed( + # Cesar Chavez Day. + self._add_holiday_mar_31(tr("Cesar Chavez Day")), + rule=SUN_TO_NEXT_MON, + ) + + if 1971 <= self._year <= 2008: + # Columbus Day. + self._add_holiday_2nd_mon_of_oct(tr("Columbus Day")) + + if self._year >= 1975: + # Day After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Day After Thanksgiving")) + + def _populate_subdiv_co_public_holidays(self): + if self._year >= 1971: + # Washington-Lincoln Day. + self._add_holiday_3rd_mon_of_feb(tr("Washington-Lincoln Day")) + + if self._year >= 2001: + # Cesar Chavez Day. + self._add_holiday_mar_31(tr("Cesar Chavez Day")) + + if self._year >= 2020: + # Frances Xavier Cabrini Day. + self._add_holiday_1st_mon_of_oct(tr("Frances Xavier Cabrini Day")) + + def _populate_subdiv_ct_public_holidays(self): + if self._year >= 1971: + # Lincoln's Birthday. + self._add_observed(self._add_holiday_feb_12(tr("Lincoln's Birthday"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + def _populate_subdiv_dc_public_holidays(self): + if self._year >= 1789 and (self._year - 1789) % 4 == 0: + # Inauguration Day. + name = tr("Inauguration Day") + self._add_observed( + self._add_holiday_jan_20(name) + if self._year >= 1937 + else self._add_holiday_mar_4(name), + rule=SUN_TO_NEXT_MON, + ) + + if self._year >= 2005: + # Emancipation Day. + self._add_observed(self._add_holiday_apr_16(tr("Emancipation Day"))) + + if self._year >= 1971: + self._add_holiday_2nd_mon_of_oct( + # Indigenous Peoples' Day. + tr("Indigenous Peoples' Day") + if self._year >= 2019 + # Columbus Day. + else tr("Columbus Day") + ) + + def _populate_subdiv_de_public_holidays(self): + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + if self._year >= 1975: + # Day After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Day After Thanksgiving")) + + def _populate_subdiv_fl_public_holidays(self): + if self._year >= 2011: + # Susan B. Anthony Day. + self._add_holiday_feb_15(tr("Susan B. Anthony Day")) + + if self._year >= 1975: + # Friday After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Friday After Thanksgiving")) + + def _populate_subdiv_ga_public_holidays(self): + if self._year >= 1986: + self._add_holiday_3rd_mon_of_jan( + # Martin Luther King Jr. Day. + tr("Martin Luther King Jr. Day") + if self._year >= 2012 + # Robert E. Lee's Birthday. + else tr("Robert E. Lee's Birthday") + ) + + if self._year >= 1866: + name = ( + # State Holiday. + tr("State Holiday") + if self._year >= 2016 + # Confederate Memorial Day. + else tr("Confederate Memorial Day") + ) + if self._year == 2020: + self._add_holiday_apr_10(name) + else: + self._add_holiday_4th_mon_of_apr(name) + + if self._year >= 1986: + self._add_holiday_1_day_past_4th_thu_of_nov( + # State Holiday. + tr("State Holiday") + if self._year >= 2016 + # Robert E. Lee's Birthday. + else tr("Robert E. Lee's Birthday") + ) + + if self._year >= 1879: + self._add_holiday( + # Washington's Birthday. + tr("Washington's Birthday"), + self._get_observed_date(self._christmas_day, rule=GA_IN_WASHINGTON_BIRTHDAY), + ) + + def _populate_subdiv_gu_public_holidays(self): + if self._year >= 1970: + # Guam Discovery Day. + self._add_holiday_1st_mon_of_mar(tr("Guam Discovery Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 1945: + # Liberation Day (Guam). + self._add_holiday_jul_21(tr("Liberation Day (Guam)")) + + # All Souls' Day. + self._add_all_souls_day(tr("All Souls' Day")) + + # Lady of Camarin Day. + self._add_immaculate_conception_day(tr("Lady of Camarin Day")) + + def _populate_subdiv_hi_public_holidays(self): + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + if self._year >= 1949: + # Prince Jonah Kuhio Kalanianaole Day. + self._add_observed(self._add_holiday_mar_26(tr("Prince Jonah Kuhio Kalanianaole Day"))) + + if self._year >= 1872: + # Kamehameha Day. + jun_11 = self._add_holiday_jun_11(tr("Kamehameha Day")) + if self._year >= 2011: + self._add_observed(jun_11) + + if self._year >= 1959: + # Statehood Day. + self._add_holiday_3rd_fri_of_aug(tr("Statehood Day")) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + def _populate_subdiv_ia_public_holidays(self): + if self._year >= 1971: + # Lincoln's Birthday. + self._add_observed(self._add_holiday_feb_12(tr("Lincoln's Birthday"))) + + def _populate_subdiv_id_public_holidays(self): + if self._year >= 1986: + self._add_holiday_3rd_mon_of_jan( + # Martin Luther King Jr. / Idaho Human Rights Day. + tr("Martin Luther King Jr. / Idaho Human Rights Day") + if self._year >= 2006 + # Martin Luther King Jr. Day. + else tr("Martin Luther King Jr. Day") + ) + + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + def _populate_subdiv_il_public_holidays(self): + if self._year >= 1971: + # Lincoln's Birthday. + self._add_observed(self._add_holiday_feb_12(tr("Lincoln's Birthday"))) + + if self._year >= 1978: + # Casimir Pulaski Day. + self._add_holiday_1st_mon_of_mar(tr("Casimir Pulaski Day")) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + def _populate_subdiv_in_public_holidays(self): + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 2015 or (self._year >= 2006 and self._year % 2 == 0): + # Primary Election Day. + self._add_holiday_1_day_past_1st_mon_of_may(tr("Primary Election Day")) + + if self._year >= 2015 or (self._year >= 2008 and self._year % 2 == 0): + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + if self._year >= 2010: + # Lincoln's Birthday. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Lincoln's Birthday")) + + if self._year >= 1879: + self._add_holiday( + # Washington's Birthday. + tr("Washington's Birthday"), + self._get_observed_date(self._christmas_day, rule=GA_IN_WASHINGTON_BIRTHDAY), + ) + + def _populate_subdiv_ks_public_holidays(self): + if self._year >= 2013: + # Christmas Eve. + self._add_christmas_eve_holiday() + + def _populate_subdiv_ky_public_holidays(self): + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 2013: + # New Year's Eve. + self._add_observed(self._add_new_years_eve(tr("New Year's Eve"))) + + def _populate_subdiv_la_public_holidays(self): + if self._year >= 1857: + # Mardi Gras. + self._add_carnival_tuesday(tr("Mardi Gras")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + def _populate_subdiv_ma_public_holidays(self): + if self._year >= 1901: + self._add_observed( + # Evacuation Day. + self._add_holiday_mar_17(tr("Evacuation Day")), + rule=SAT_SUN_TO_NEXT_MON, + ) + + if self._year >= 1894: + # Patriots' Day. + name = tr("Patriots' Day") + if self._year >= 1969: + self._add_holiday_3rd_mon_of_apr(name) + else: + self._add_holiday_apr_19(name) + + def _populate_subdiv_md_public_holidays(self): + if self._year >= 1789 and (self._year - 1789) % 4 == 0: + # Inauguration Day. + name = tr("Inauguration Day") + self._add_observed( + self._add_holiday_jan_20(name) + if self._year >= 1937 + else self._add_holiday_mar_4(name), + rule=SUN_TO_NEXT_MON, + ) + + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + if self._year >= 2008: + # American Indian Heritage Day. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("American Indian Heritage Day")) + + def _populate_subdiv_me_public_holidays(self): + if self._year >= 1894: + # Patriots' Day. + name = tr("Patriots' Day") + if self._year >= 1969: + self._add_holiday_3rd_mon_of_apr(tr("Patriots' Day")) + else: + self._add_holiday_apr_19(name) + + if self._year >= 1971: + self._add_holiday_2nd_mon_of_oct( + # Indigenous Peoples' Day. + tr("Indigenous Peoples' Day") + if self._year >= 2019 + # Columbus Day. + else tr("Columbus Day") + ) + + def _populate_subdiv_mi_public_holidays(self): + if self._year >= 2013: + # Christmas Eve. + self._add_christmas_eve_holiday() + + # New Year's Eve. + self._add_observed(self._add_new_years_eve(tr("New Year's Eve"))) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + if self._year >= 2017: + # Day After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Day After Thanksgiving")) + + def _populate_subdiv_mn_public_holidays(self): + if self._year >= 1971: + # Washington's and Lincoln's Birthday. + self._add_holiday_3rd_mon_of_feb(tr("Washington's and Lincoln's Birthday")) + + def _populate_subdiv_mo_public_holidays(self): + if self._year >= 1949: + # Truman Day. + self._add_observed(self._add_holiday_may_8(tr("Truman Day"))) + + def _populate_subdiv_mp_public_holidays(self): + # Commonwealth Covenant Day. + self._add_observed(self._add_holiday_mar_24(tr("Commonwealth Covenant Day"))) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Commonwealth Cultural Day. + self._add_holiday_2nd_mon_of_oct(tr("Commonwealth Cultural Day")) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + # Citizenship Day. + self._add_observed(self._add_holiday_nov_4(tr("Citizenship Day"))) + + # Constitution Day. + self._add_observed(self._add_holiday_dec_8(tr("Constitution Day"))) + + def _populate_subdiv_ms_public_holidays(self): + if self._year >= 1986: + self._add_holiday_3rd_mon_of_jan( + # Dr. Martin Luther King Jr. and Robert E. Lee's Birthdays. + tr("Dr. Martin Luther King Jr. and Robert E. Lee's Birthdays") + ) + + if self._year >= 1866: + # Confederate Memorial Day. + self._add_holiday_last_mon_of_apr(tr("Confederate Memorial Day")) + + def _populate_subdiv_mt_public_holidays(self): + if self._year >= 1971: + # Lincoln's and Washington's Birthdays. + self._add_holiday_3rd_mon_of_feb(tr("Lincoln's and Washington's Birthdays")) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + def _populate_subdiv_nc_public_holidays(self): + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 1975: + # Day After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Day After Thanksgiving")) + + if self._year >= 2013: + # Christmas Eve. + self._add_christmas_eve_holiday() + + # If on Saturday or Sunday, observed on Monday + # If on Monday, observed on Tuesday + if self._year >= 2013: + # Day After Christmas. + name = tr("Day After Christmas") + self._add_observed( + self._add_christmas_day_two(name), + name=name, + rule=MON_TO_NEXT_TUE + SAT_SUN_TO_NEXT_MON, + ) + + def _populate_subdiv_nd_public_holidays(self): + pass + + def _populate_subdiv_ne_public_holidays(self): + if self._year >= 1875: + # Arbor Day. + name = tr("Arbor Day") + if self._year >= 1989: + self._add_holiday_last_fri_of_apr(name) + else: + self._add_holiday_apr_22(name) + + if self._year >= 1971: + self._add_holiday_2nd_mon_of_oct( + # Indigenous Peoples' Day. + tr("Indigenous Peoples' Day") + if self._year >= 2020 + # Columbus Day. + else tr("Columbus Day") + ) + + def _populate_subdiv_nh_public_holidays(self): + if self._year >= 1986: + # Dr. Martin Luther King Jr. / Civil Rights Day. + self._add_holiday_3rd_mon_of_jan(tr("Dr. Martin Luther King Jr. / Civil Rights Day")) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + if self._year >= 1975: + # Day After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Day After Thanksgiving")) + + def _populate_subdiv_nj_public_holidays(self): + if self._year >= 1971: + # Lincoln's Birthday. + self._add_observed(self._add_holiday_feb_12(tr("Lincoln's Birthday"))) + + # Presidents Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + def _populate_subdiv_nm_public_holidays(self): + if self._year >= 1971: + self._add_holiday_2nd_mon_of_oct( + # Indigenous Peoples' Day. + tr("Indigenous Peoples' Day") + if self._year >= 2019 + # Columbus Day. + else tr("Columbus Day") + ) + + # Presidents' Day. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Presidents' Day")) + + def _populate_subdiv_nv_public_holidays(self): + if self._year >= 1933: + # Nevada Day. + name = tr("Nevada Day") + self._add_observed( + self._add_holiday_last_fri_of_oct(name) + if self._year >= 2000 + else self._add_holiday_oct_31(name) + ) + + # Family Day. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Family Day")) + + def _populate_subdiv_ny_public_holidays(self): + if self._year >= 1971: + # Lincoln's Birthday. + self._add_observed(self._add_holiday_feb_12(tr("Lincoln's Birthday"))) + + if self._year >= 2004: + # Susan B. Anthony Day. + self._add_holiday_feb_15(tr("Susan B. Anthony Day")) + + if self._year >= 2015 or (self._year >= 2008 and self._year % 2 == 0): + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + def _populate_subdiv_oh_public_holidays(self): + if self._year >= 1971: + # Washington-Lincoln Day. + self._add_holiday_3rd_mon_of_feb(tr("Washington-Lincoln Day")) + + def _populate_subdiv_ok_public_holidays(self): + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + if self._year >= 1975: + # Day After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Day After Thanksgiving")) + + def _populate_subdiv_or_public_holidays(self): + if self._year >= 1971: + # Presidents Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents Day")) + + def _populate_subdiv_pa_public_holidays(self): + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + # Day After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Day After Thanksgiving")) + + def _populate_subdiv_pr_public_holidays(self): + # Epiphany. + self._add_epiphany_day(tr("Epiphany")) + + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + # Emancipation Day. + self._add_observed(self._add_holiday_mar_22(tr("Emancipation Day")), rule=SUN_TO_NEXT_MON) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Constitution Day. + self._add_observed(self._add_holiday_jul_25(tr("Constitution Day")), rule=SUN_TO_NEXT_MON) + + # Discovery Day. + self._add_observed(self._add_holiday_nov_19(tr("Discovery Day")), rule=SUN_TO_NEXT_MON) + + def _populate_subdiv_ri_public_holidays(self): + if self._year >= 1948: + # Victory Day. + self._add_holiday_2nd_mon_of_aug(tr("Victory Day")) + + if self._year >= 1971: + self._add_holiday_2nd_mon_of_oct( + # Indigenous Peoples' Day / Columbus Day. + tr("Indigenous Peoples' Day / Columbus Day") + if self._year >= 2022 + # Columbus Day. + else tr("Columbus Day") + ) + + def _populate_subdiv_sc_public_holidays(self): + if self._year >= 1971: + # President's Day. + self._add_holiday_3rd_mon_of_feb(tr("President's Day")) + + if self._year >= 1866: + # Confederate Memorial Day. + self._add_holiday_4th_mon_of_apr(tr("Confederate Memorial Day")) + + def _populate_subdiv_sd_public_holidays(self): + if self._year >= 1937: + name = ( + # Native Americans' Day. + tr("Native Americans' Day") + if self._year >= 1990 + # Columbus Day. + else tr("Columbus Day") + ) + if self._year >= 1970: + self._add_holiday_2nd_mon_of_oct(name) + else: + self._add_columbus_day(name) + + def _populate_subdiv_tn_public_holidays(self): + if self._year >= 1971: + # President's Day. + self._add_holiday_3rd_mon_of_feb(tr("President's Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + def _populate_subdiv_tx_public_holidays(self): + if self._year >= 1931: + # Confederate Memorial Day. + self._add_holiday_jan_19(tr("Confederate Memorial Day")) + + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + if self._year >= 1874: + # Texas Independence Day. + self._add_holiday_mar_2(tr("Texas Independence Day")) + + if self._year >= 2000: + # Cesar Chavez Day. + self._add_holiday_mar_31(tr("Cesar Chavez Day")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + if self._year >= 1875: + # San Jacinto Day. + self._add_holiday_apr_21(tr("San Jacinto Day")) + + if self._year >= 1980: + # Emancipation Day In Texas. + self._add_holiday_jun_19(tr("Emancipation Day In Texas")) + + if self._year >= 1973: + # Lyndon Baines Johnson Day. + self._add_holiday_aug_27(tr("Lyndon Baines Johnson Day")) + + if self._year >= 1975: + # Friday After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Friday After Thanksgiving")) + + if self._year >= 1981: + # Christmas Eve. + self._add_christmas_eve_holiday() + + # Day After Christmas. + self._add_christmas_day_two(tr("Day After Christmas")) + + def _populate_subdiv_um_public_holidays(self): + pass + + def _populate_subdiv_ut_public_holidays(self): + if self._year >= 1971: + # Washington and Lincoln Day. + self._add_holiday_3rd_mon_of_feb(tr("Washington and Lincoln Day")) + + if self._year >= 1849: + # Pioneer Day. + self._add_observed(self._add_holiday_jul_24(tr("Pioneer Day"))) + + def _populate_subdiv_va_public_holidays(self): + if 1889 <= self._year <= 2020: + # Lee Jackson Day. + name = tr("Lee Jackson Day") + if self._year >= 2000: + self._add_holiday_3_days_prior_3rd_mon_of_jan(name) + elif self._year >= 1983: + self._add_holiday_3rd_mon_of_jan(name) + else: + self._add_holiday_jan_19(name) + + if self._year >= 1789 and (self._year - 1789) % 4 == 0: + # Inauguration Day. + name = tr("Inauguration Day") + self._add_observed( + self._add_holiday_jan_20(name) + if self._year >= 1937 + else self._add_holiday_mar_4(name), + rule=SUN_TO_NEXT_MON, + ) + + if self._year >= 1971: + # George Washington Day. + self._add_holiday_3rd_mon_of_feb(tr("George Washington Day")) + + self._add_holiday_2nd_mon_of_oct( + # Indigenous Peoples' Day. + tr("Indigenous Peoples' Day") + if self._year >= 2020 + # Columbus Day. + else tr("Columbus Day") + ) + + def _populate_subdiv_vi_public_holidays(self): + # Three Kings Day. + self._add_epiphany_day(tr("Three Kings Day")) + + if self._year >= 1879: + # Presidents' Day. + name = tr("Presidents' Day") + if self._year >= 1971: + self._add_holiday_3rd_mon_of_feb(name) + else: + self._add_holiday_feb_22(name) + + # Transfer Day. + self._add_holiday_mar_31(tr("Transfer Day")) + + # Holy Thursday. + self._add_holy_thursday(tr("Holy Thursday")) + + # Good Friday. + self._add_good_friday(tr("Good Friday")) + + # Easter Monday. + self._add_easter_monday(tr("Easter Monday")) + + # Emancipation Day. + self._add_holiday_jul_3(tr("Emancipation Day")) + + if self._year >= 1937: + # Columbus Day and Puerto Rico Friendship Day. + name = tr("Columbus Day and Puerto Rico Friendship Day") + if self._year >= 1970: + self._add_holiday_2nd_mon_of_oct(name) + else: + self._add_columbus_day(name) + + # Liberty Day. + self._add_holiday_nov_1(tr("Liberty Day")) + + # Christmas Second Day. + self._add_christmas_day_two(tr("Christmas Second Day")) + + def _populate_subdiv_vt_public_holidays(self): + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + if self._year >= 1800: + # Town Meeting Day. + self._add_holiday_1st_tue_of_mar(tr("Town Meeting Day")) + + if self._year >= 1778: + # Bennington Battle Day. + self._add_observed(self._add_holiday_aug_16(tr("Bennington Battle Day"))) + + def _populate_subdiv_wa_public_holidays(self): + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + def _populate_subdiv_wi_public_holidays(self): + if self._year >= 1976: + # Susan B. Anthony Day. + self._add_holiday_feb_15(tr("Susan B. Anthony Day")) + + if self._year >= 2012: + # Christmas Eve. + self._add_christmas_eve_holiday() + + # New Year's Eve. + self._add_observed(self._add_new_years_eve(tr("New Year's Eve"))) + + def _populate_subdiv_wv_public_holidays(self): + if self._year >= 1971: + # Presidents' Day. + self._add_holiday_3rd_mon_of_feb(tr("Presidents' Day")) + + if self._year >= 1927: + # West Virginia Day. + self._add_observed(self._add_holiday_jun_20(tr("West Virginia Day"))) + + if self._year >= 2008 and self._year % 2 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + if self._year >= 1975: + # Day After Thanksgiving. + self._add_holiday_1_day_past_4th_thu_of_nov(tr("Day After Thanksgiving")) + + def _populate_subdiv_wy_public_holidays(self): + if self._year >= 1971: + # President's Day. + self._add_holiday_3rd_mon_of_feb(tr("President's Day")) + + def _populate_government_holidays(self): + # Added by 16 Stat. 168, effectdive date June 28th, 1870. + # New Year's Day check for 1871 is included. + if self._year >= 1870: + # Federal holidays in the United States. + self._populate_common(include_federal=True) + + def _populate_unofficial_holidays(self): + # Very common celebrated cultural days, but no official observance. + # Due to its nature, no in-lieus are observed. + + # Valentine's Day. + # While the modern iteration of Valentine's Day has started in the UK in 1797, + # it wasn't until 1847 in the US that this started to be observed here. + + if self._year >= 1847: + # Valentine's Day. + self._add_holiday_feb_14(tr("Valentine's Day")) + + # Saint Patrick's Day. + # Started in Boston in 1737 for the US. + + # Saint Patrick's Day. + self._add_holiday_mar_17(tr("Saint Patrick's Day")) + + # Halloween. + # Halloween began in the US sometime around the 19th century. + + # Halloween. + self._add_holiday_oct_31(tr("Halloween")) + + # Continental US non-Public dates + + if self.subdiv not in {"AS", "GU", "MP", "PR", "UM", "VI"}: + # Groundhog Day + # First observed on Feb 2 in 1886 in Continental US + Hawaii. + + if self._year >= 1886: + # Groundhog Day. + self._add_holiday_feb_2(tr("Groundhog Day")) + + # Election Day + # May be duplicates for certain states which has this as their actual public holiday. + # The current US Presidential Election date pattern was codified in 1848 nationwide. + + if self._year >= 1848 and self._year % 4 == 0: + # Election Day. + self._add_holiday_1_day_past_1st_mon_of_nov(tr("Election Day")) + + +class US(UnitedStates): + pass + + +class USA(UnitedStates): + pass + + +class UnitedStatesStaticHolidays(StaticHolidays): + """United States special holidays. + + Thanksgiving Proclamation References: + * [1777](https://web.archive.org/web/20240621142028/https://pilgrimhall.org/pdf/TG_First_National_Thanksgiving_Proclamation_1777.pdf) + * [1782](https://web.archive.org/web/20240621142030/https://www.loc.gov/exhibits/religion/vc006491.jpg) + * [1789](https://web.archive.org/web/20240621142029/https://www.whatsoproudlywehail.org/curriculum/the-american-calendar/thanksgiving-proclamation-1789-2) + * [1795](https://web.archive.org/web/20240621142029/https://founders.archives.gov/documents/Washington/05-17-02-0239) + * [1798](https://web.archive.org/web/20240621142029/https://founders.archives.gov/documents/Adams/99-02-02-2386) + * [1799](https://web.archive.org/web/20240621142029/https://founders.archives.gov/documents/Adams/99-02-02-3372) + * [1813](https://web.archive.org/web/20240621142030/https://founders.archives.gov/documents/Madison/03-06-02-0434) + * [1815](https://web.archive.org/web/20240621142030/https://founders.archives.gov/documents/Madison/03-09-02-0066) + + Pre-1971 Inauguration Day observances has been moved here. + """ + + # Fasting and Humiliation Day. + fasting_and_humiliation_day_name = tr("Fasting and Humiliation Day") + # Public Humiliation and Prayer Day. + public_humiliation_and_prayer_day_name = tr("Public Humiliation and Prayer Day") + # Public Thanksgiving and Prayer Day. + public_thanksgiving_and_prayer_day_name = tr("Public Thanksgiving and Prayer Day") + + # Inauguration Day. + inauguration_day_name = tr("Inauguration Day") + + special_public_holidays = { + 1777: (DEC, 18, public_thanksgiving_and_prayer_day_name), + 1782: (NOV, 28, public_thanksgiving_and_prayer_day_name), + 1789: (NOV, 26, public_thanksgiving_and_prayer_day_name), + 1795: (FEB, 19, public_thanksgiving_and_prayer_day_name), + 1798: (MAY, 9, fasting_and_humiliation_day_name), + 1799: (APR, 25, fasting_and_humiliation_day_name), + 1813: (SEP, 9, public_humiliation_and_prayer_day_name), + 1815: (APR, 13, public_humiliation_and_prayer_day_name), + } + + # Pre-1953 Inauguration Day observances. + special_dc_public_holidays_observed = { + 1877: (MAR, 5, inauguration_day_name), + 1917: (MAR, 5, inauguration_day_name), + } + special_md_public_holidays_observed = { + 1877: (MAR, 5, inauguration_day_name), + 1917: (MAR, 5, inauguration_day_name), + } + special_va_public_holidays_observed = { + 1877: (MAR, 5, inauguration_day_name), + 1917: (MAR, 5, inauguration_day_name), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/united_states_minor_outlying_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/united_states_minor_outlying_islands.py new file mode 100644 index 00000000..abb1c4e1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/united_states_minor_outlying_islands.py @@ -0,0 +1,39 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.united_states import UnitedStates +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysUM(ChildEntity, UnitedStates): + """United States Minor Outlying Islands holidays. + + Alias of a US subdivision that is also officially assigned its own country code in ISO 3166-1. + See + """ + + country = "UM" + parent_entity = UnitedStates + # The first islands were claimed via Guano Islands Act on August 18th, 1856. + start_year = 1857 + + +class UnitedStatesMinorOutlyingIslands(HolidaysUM): + pass + + +class UM(HolidaysUM): + pass + + +class UMI(HolidaysUM): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/united_states_virgin_islands.py b/.venv/lib/python3.12/site-packages/holidays/countries/united_states_virgin_islands.py new file mode 100644 index 00000000..cd48cebd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/united_states_virgin_islands.py @@ -0,0 +1,39 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.united_states import UnitedStates +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysVI(ChildEntity, UnitedStates): + """United States Virgin Islands (the) holidays. + + Alias of a US subdivision that is also officially assigned its own country code in ISO 3166-1. + See + """ + + country = "VI" + parent_entity = UnitedStates + # Became a U.S. Territory since March 31st, 1917. + start_year = 1918 + + +class UnitedStatesVirginIslands(HolidaysVI): + pass + + +class VI(HolidaysVI): + pass + + +class VIR(HolidaysVI): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/uruguay.py b/.venv/lib/python3.12/site-packages/holidays/countries/uruguay.py new file mode 100644 index 00000000..5adc42aa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/uruguay.py @@ -0,0 +1,175 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.gregorian import MAR +from holidays.constants import BANK, PUBLIC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + TUE_WED_TO_PREV_MON, + THU_FRI_TO_NEXT_MON, +) + + +class Uruguay(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Uruguay holidays. + + References: + * + * [Law #6997](https://web.archive.org/web/20250419214344/http://www.impo.com.uy/diariooficial/1919/10/25/2) + * [Decree Law #9000](https://web.archive.org/web/20231029150729/https://www.impo.com.uy/bases/decretos-ley/9000-1933) + * [Decree Law #14977](https://web.archive.org/web/20231013033006/https://www.impo.com.uy/bases/decretos-ley/14977-1979) + * [Decree Law #15535](https://web.archive.org/web/20210519002815/https://www.impo.com.uy/bases/decretos-ley/15535-1984/) + * [Law #16805](https://web.archive.org/web/20241121064154/https://parlamento.gub.uy/documentosyleyes/leyes/ley/16805) + * [Law #17414](https://web.archive.org/web/20241121064131/https://parlamento.gub.uy/documentosyleyes/leyes/ley/17414) + """ + + country = "UY" + default_language = "es" + supported_categories = (BANK, PUBLIC) + supported_languages = ("en_US", "es", "uk") + # Law # 6997. + start_year = 1920 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, cls=UruguayStaticHolidays) + # Decree Law #14977, # 15535, #16805. + kwargs.setdefault("observed_rule", TUE_WED_TO_PREV_MON + THU_FRI_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _is_observed(self, dt: date) -> bool: + return 1980 <= self._year <= 1983 or self._year >= 1997 + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + if self._year <= 1933: + # Cry of Asencio. + self._add_holiday_feb_28(tr("Grito de Asencio")) + + # Workers' Day. + dt = self._add_labor_day(tr("Día de los Trabajadores")) + if self._year <= 1983: + self._move_holiday(dt) + + if self._year <= 1932: + # Spain Day. + self._add_holiday_may_2(tr("Día de España")) + + # America Day. + self._add_holiday_may_25(tr("Día de América")) + + # Democracy Day. + self._add_holiday_jul_4(tr("Día de la Democracia")) + + # Humanity Day. + self._add_holiday_jul_14(tr("Día de la Humanidad")) + + # Constitution Day. + self._add_holiday_jul_18(tr("Jura de la Constitución")) + + # Independence Day. + self._add_holiday_aug_25(tr("Declaratoria de la Independencia")) + + if self._year <= 1932: + # Italy Day. + self._add_holiday_sep_20(tr("Día de Italia")) + + # Open Town Hall. + self._add_holiday_sep_21(tr("Cabildo Abierto")) + + if self._year <= 1932 or 1936 <= self._year <= 1979: + # Beaches Day. + self._add_holiday_dec_8(tr("Día de las Playas")) + + # Day of the Family. + self._add_christmas_day(tr("Día de la Familia")) + + def _populate_bank_holidays(self): + # These holidays are generally observed by schools, public sector offices, banks, + # and a few private companies. + + # Children's Day. + self._add_holiday_jan_6(tr("Día de los Niños")) + + # Carnival. + name = tr("Carnaval") + self._add_carnival_monday(name) + self._add_carnival_tuesday(name) + + if self._year <= 1933 or self._year >= 1949: + # Landing of the 33 Patriots. + self._move_holiday(self._add_holiday_apr_19(tr("Desembarco de los 33 Orientales"))) + + # Tourism Week. + name = tr("Semana de Turismo") + self._add_holiday_6_days_prior_easter(name) + self._add_holiday_5_days_prior_easter(name) + self._add_holiday_4_days_prior_easter(name) + self._add_holy_thursday(name) + self._add_good_friday(name) + + if self._year <= 1932 or self._year >= 1942: + # Battle of Las Piedras. + self._move_holiday(self._add_holiday_may_18(tr("Batalla de Las Piedras"))) + + if self._year <= 1932 or self._year >= 1940: + # Birthday of Artigas. + dt = self._add_holiday_jun_19(tr("Natalicio de Artigas")) + if self._year <= 2001: + self._move_holiday(dt) + + if self._year <= 1932 or self._year >= 1937: + self._move_holiday( + self._add_columbus_day( + # Cultural Diversity Day. + tr("Día de la Diversidad Cultural") + if self._year >= 2014 + # Columbus Day. + else tr("Día de la Raza") + ) + ) + + if self._year <= 1932 or self._year >= 1938: + # All Souls' Day. + dt = self._add_all_souls_day(tr("Día de los Difuntos")) + if self._year <= 2001: + self._move_holiday(dt) + + +class UY(Uruguay): + pass + + +class URY(Uruguay): + pass + + +class UruguayStaticHolidays: + # Presidential Inauguration Day. + presidential_inauguration_day = tr("Inauguración del Presidente de la República") + special_public_holidays = { + 1985: (MAR, 1, presidential_inauguration_day), + 1990: (MAR, 1, presidential_inauguration_day), + 1995: (MAR, 1, presidential_inauguration_day), + 2000: (MAR, 1, presidential_inauguration_day), + 2005: (MAR, 1, presidential_inauguration_day), + 2010: (MAR, 1, presidential_inauguration_day), + 2015: (MAR, 1, presidential_inauguration_day), + 2020: (MAR, 1, presidential_inauguration_day), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/uzbekistan.py b/.venv/lib/python3.12/site-packages/holidays/countries/uzbekistan.py new file mode 100644 index 00000000..4e97619d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/uzbekistan.py @@ -0,0 +1,252 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import JAN, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC +from holidays.groups import InternationalHolidays, IslamicHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY + + +class Uzbekistan(ObservedHolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays): + """Uzbekistan holidays. + + References: + * + * [Labor Code 21.12.1995](https://web.archive.org/web/20250422170827/https://lex.uz/docs/-142859) + * [Labor Code 28.10.2022](https://web.archive.org/web/20250424164306/https://lex.uz/docs/-6257288) + """ + + country = "UZ" + default_language = "uz" + # %s (estimated). + estimated_label = tr("%s (taxminiy)") + # %s (observed). + observed_label = tr("%s (ko‘chirilgan)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (ko‘chirilgan, taxminiy)") + supported_languages = ("en_US", "uk", "uz") + start_year = 1992 + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=UzbekistanIslamicHolidays, show_estimated=islamic_show_estimated + ) + StaticHolidays.__init__(self, UzbekistanStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _is_observed(self, dt: date) -> bool: + # Commencement of the new Labor Code. + return dt >= date(2023, APR, 30) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("Yangi yil"))) + + # Women's Day. + dts_observed.add(self._add_womens_day(tr("Xotin-qizlar kuni"))) + + # Nowruz. + dts_observed.add(self._add_holiday_mar_21(tr("Navro‘z bayrami"))) + + dts_observed.add( + self._add_world_war_two_victory_day( + # Day of Memory and Honor. + tr("Xotira va qadrlash kuni") + if self._year >= 1999 + # Victory Day. + else tr("G‘alaba kuni"), + is_western=False, + ) + ) + + # Independence Day. + dts_observed.add(self._add_holiday_sep_1(tr("Mustaqillik kuni"))) + + if self._year >= 1997: + # Teachers and Instructors Day. + dts_observed.add(self._add_holiday_oct_1(tr("O‘qituvchi va murabbiylar kuni"))) + + if self._year >= 1993: + dts_observed.add( + # Constitution Day. + self._add_holiday_dec_8(tr("O‘zbekiston Respublikasi Konstitutsiyasi kuni")) + ) + + # Eid al-Fitr. + dts_observed.update(self._add_eid_al_fitr_day(tr("Ro‘za hayit"))) + + # Eid al-Adha. + dts_observed.update(self._add_eid_al_adha_day(tr("Qurbon hayit"))) + + if self.observed and self._year >= 2023: + self._populate_observed(dts_observed) + + +class UZ(Uzbekistan): + pass + + +class UZB(Uzbekistan): + pass + + +class UzbekistanIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 2006: ((JAN, 10), (DEC, 30)), + 2007: (DEC, 19), + 2008: (DEC, 8), + 2009: (NOV, 27), + 2010: (NOV, 16), + 2011: (NOV, 6), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 4), + 2015: (SEP, 24), + 2016: (SEP, 12), + 2017: (SEP, 1), + 2018: (AUG, 21), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 6), + } + + EID_AL_FITR_DATES = { + 2006: (OCT, 23), + 2007: (OCT, 13), + 2008: (OCT, 1), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 9), + 2014: (JUL, 28), + 2015: (JUL, 18), + 2016: (JUL, 6), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 5), + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + +class UzbekistanStaticHolidays: + """Uzbekistan special holidays. + + References: + * [2018](https://web.archive.org/web/20250610012705/https://lex.uz/ru/docs/3479237) + * [2019](https://web.archive.org/web/20250521124231/https://lex.uz/docs/-4054698) + * [2020](https://web.archive.org/web/20250522053834/https://lex.uz/docs/-4595638) + * [2021](https://web.archive.org/web/20250522053822/https://lex.uz/docs/-5137156) + * [2022](https://web.archive.org/web/20250522053831/https://lex.uz/docs/-5784917) + * [2023](https://web.archive.org/web/20250522053822/https://lex.uz/docs/-6324664) + * [2024](https://web.archive.org/web/20250522053835/https://lex.uz/docs/-6704048) + * [2025](https://web.archive.org/web/20250422135040/https://lex.uz/docs/-7275687) + """ + + # Date format (see strftime() Format Codes) + substituted_date_format = tr("%d/%m %Y") + # Day off (substituted from %s). + substituted_label = tr("Dam olish kuni (%s dan ko‘chirilgan)") + + # Additional day off by Presidential decree. + additional_day_off = tr("Prezidentining farmoni bilan qo‘shimcha dam olish kuni") + special_public_holidays = { + 2018: ( + (JAN, 2, additional_day_off), + (JAN, 3, JAN, 6), + (MAR, 19, MAR, 17), + (MAR, 22, MAR, 24), + (MAR, 20, additional_day_off), + (AUG, 23, AUG, 25), + (AUG, 24, AUG, 26), + (AUG, 31, additional_day_off), + (SEP, 3, SEP, 8), + (SEP, 4, SEP, 15), + (DEC, 31, DEC, 29), + ), + 2019: ( + (JAN, 2, additional_day_off), + (JAN, 3, JAN, 5), + (MAR, 22, additional_day_off), + (JUN, 6, JUN, 1), + (SEP, 2, additional_day_off), + (SEP, 3, SEP, 7), + (DEC, 31, DEC, 28), + ), + 2020: ( + (JAN, 2, JAN, 4), + (MAR, 23, additional_day_off), + (AUG, 31, AUG, 29), + ), + 2021: ( + (MAR, 22, MAR, 27), + (MAY, 14, additional_day_off), + (JUL, 21, JUL, 17), + (JUL, 22, JUL, 24), + (SEP, 2, additional_day_off), + (SEP, 3, additional_day_off), + (DEC, 31, additional_day_off), + ), + 2022: ( + (JAN, 3, additional_day_off), + (JAN, 4, JAN, 8), + (MAR, 22, additional_day_off), + (MAR, 23, additional_day_off), + (MAY, 3, additional_day_off), + (MAY, 4, MAY, 7), + (JUL, 11, additional_day_off), + (JUL, 12, JUL, 16), + (SEP, 2, additional_day_off), + ), + 2023: ( + (JAN, 2, additional_day_off), + (JAN, 3, JAN, 7), + (MAR, 20, MAR, 11), + (MAR, 22, MAR, 25), + (APR, 24, additional_day_off), + (JUN, 29, additional_day_off), + (JUN, 30, additional_day_off), + ), + 2024: ( + (JAN, 2, JAN, 6), + (MAR, 22, additional_day_off), + (APR, 11, additional_day_off), + (APR, 12, APR, 13), + (JUN, 18, additional_day_off), + (SEP, 3, additional_day_off), + (DEC, 30, DEC, 14), + (DEC, 31, additional_day_off), + ), + 2025: (JAN, 2, JAN, 4), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/vanuatu.py b/.venv/lib/python3.12/site-packages/holidays/countries/vanuatu.py new file mode 100644 index 00000000..c4b8a83f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/vanuatu.py @@ -0,0 +1,106 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import JUL, OCT +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, MON_TO_NEXT_TUE + + +class Vanuatu(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Vanuatu holidays. + + References: + * + * + * + """ + + country = "VU" + observed_label = "%s (observed)" + # On 30 July 1980, Vanuatu gained independence from Britain and France. + start_year = 1981 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, VanuatuStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Years Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + if self._year >= 1999: + # Father Lini Day. + self._add_observed(self._add_holiday_feb_21("Father Lini Day")) + + # Custom Chief's Day. + self._add_observed(self._add_holiday_mar_5("Custom Chief's Day")) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + # Labour Day. + self._add_observed(self._add_labor_day("Labour Day")) + + # Ascension Day. + self._add_ascension_thursday("Ascension Day") + + # Children's Day. + self._add_observed(self._add_holiday_jul_24("Children's Day")) + + # Independence Day. + self._add_observed(self._add_holiday_jul_30("Independence Day")) + + # Assumption Day. + self._add_observed(self._add_assumption_of_mary_day("Assumption Day")) + + # Constitution Day. + self._add_observed(self._add_holiday_oct_5("Constitution Day")) + + # Unity Day. + self._add_observed(self._add_holiday_nov_29("Unity Day")) + + # Christmas Day. + self._add_christmas_day("Christmas Day") + + # Family Day. + self._add_observed( + self._add_christmas_day_two("Family Day"), rule=SUN_TO_NEXT_MON + MON_TO_NEXT_TUE + ) + + +class VU(Vanuatu): + pass + + +class VTU(Vanuatu): + pass + + +class VanuatuStaticHolidays: + independence_anniversary = "40th Independence Anniversary" + + special_public_holidays = { + 2020: ( + (JUL, 23, independence_anniversary), + (JUL, 27, independence_anniversary), + (JUL, 28, independence_anniversary), + (JUL, 29, independence_anniversary), + (JUL, 31, independence_anniversary), + ), + 2022: (OCT, 13, "Election Day"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/vatican_city.py b/.venv/lib/python3.12/site-packages/holidays/countries/vatican_city.py new file mode 100644 index 00000000..b8904f6c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/vatican_city.py @@ -0,0 +1,199 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class VaticanCity(HolidayBase, ChristianHolidays, InternationalHolidays): + """Vatican City holidays. + + References: + * + * + * + * + * + * + * + + Cross-checked With: + * + * + * + * + * + * + """ + + country = "VA" + default_language = "it" + supported_languages = ("en_US", "it", "th") + # Lateran Treaty, FEB 11, 2029. + start_year = 1929 + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self) -> None: + # This is supposedly the same as International New Year. + # Modern adoption across the entire Latin Church in 1931 though this + # was already celebrated in Rome as the Octave day of Christmas. + + # Solemnity of Mary, Mother of God. + self._add_holiday_jan_1(tr("Solennità di Maria Santissima Madre di Dio")) + + # Epiphany. + self._add_epiphany_day(tr("Epifania del Signore")) + + self._add_holiday_feb_11( + # Anniversary of the Foundation of Vatican City. + tr("Anniversario della istituzione dello Stato della Città del Vaticano") + ) + + # Name Day of the Holy Father. + name_day = tr("Onomastico del Santo Padre") + + if self._year >= 2025: + # Pope Leo XIV (Robert Francis Prevost). + # Name Day: Saint Robert Bellarmine Day (SEP 17). + self._add_holiday_sep_17(name_day) + + if self._year == 2025: + # Pope Francis (cont.). + self._add_saint_georges_day(name_day) + elif self._year >= 2013: + # Pope Francis (Jorge Mario Bergoglio). + # Name Day: Saint George's Day (APR 23). + self._add_saint_georges_day(name_day) + elif self._year >= 2006: + # Pope Benedict XVI (Josef Aloisius Ratzinger). + # Name Day: Saint Joseph's Day (MAR 19). + self._add_saint_josephs_day(name_day) + elif 1978 <= self._year <= 2004: + # Pope John Paul II (Karol Józef Wojtyła). + # Name Day: Saint Charles Borromeo Day (NOV 4). + self._add_holiday_nov_4(name_day) + + # Anniversary of the Election of the Holy Father. + name_election = tr("Anniversario dell'Elezione del Santo Padre") + + if self._year >= 2026: + # Pope Leo XIV (Robert Francis Prevost). + self._add_holiday_may_8(name_election) + elif self._year >= 2014: + # Pope Francis (Jorge Mario Bergoglio). + self._add_holiday_mar_13(name_election) + elif 2006 <= self._year <= 2012: + # Pope Benedict XVI (Josef Aloisius Ratzinger). + self._add_holiday_apr_19(name_election) + elif 1979 <= self._year <= 2004: + # Pope John Paul II (Karol Józef Wojtyła). + self._add_holiday_oct_16(name_election) + elif 1964 <= self._year <= 1978: + # Pope Paul VI (Giovanni Battista Enrico Antonio Maria Montini). + self._add_holiday_jun_21(name_election) + elif 1959 <= self._year <= 1962: + # Pope John XXIII (Angelo Giuseppe Roncalli). + self._add_holiday_oct_28(name_election) + elif 1940 <= self._year <= 1958: + # Pope Pius XII (Eugenio Maria Giuseppe Giovanni Pacelli). + self._add_holiday_mar_2(name_election) + elif self._year <= 1939: + # Pope Pius XI (Achille Ambrogio Damiano Ratti). + self._add_holiday_feb_6(name_election) + + # Saint Joseph's Day. + self._add_saint_josephs_day(tr("San Giuseppe")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Giovedì Santo")) + + # Good Friday. + self._add_good_friday(tr("Venerdì Santo")) + + # Holy Saturday. + self._add_holy_saturday(tr("Sabato Santo")) + + # Easter Sunday. + self._add_easter_sunday(tr("Pasqua di Resurrezione")) + + # Easter Monday. + self._add_easter_monday(tr("Lunedì dell'Angelo")) + + # Easter Tuesday. + self._add_easter_tuesday(tr("Martedì in Albis")) + + # Created in response to May Day holidays by Pope Pius XII in 1955. + if self._year >= 1955: + # Saint Joseph the Worker. + self._add_holiday_may_1(tr("San Giuseppe Artigiano")) + + # Solemnity of Pentecost. + self._add_whit_sunday(tr("Solennità della Pentecoste")) + + # Solemnity of Holy Trinity. + self._add_trinity_sunday(tr("Solennità della Santissima Trinità")) + + # Ascension Day. + self._add_ascension_thursday(tr("Ascensione del Signore")) + + # Corpus Domini. + self._add_corpus_christi_day(tr("Corpus Domini")) + + # Saints Peter and Paul's Day. + self._add_saints_peter_and_paul_day(tr("Santi Pietro e Paolo")) + + # Day Before Assumption of Mary. + self._add_holiday_aug_14(tr("Vigilia dell'Assunzione di Maria Santissima")) + + # Assumption of Mary Day. + self._add_assumption_of_mary_day(tr("Assunzione di Maria Santissima")) + + # Day After Assumption of Mary. + self._add_holiday_aug_16(tr("Giorno Successivo all'Assunzione di Maria Santissima")) + + # All Saints' Day. + self._add_all_saints_day(tr("Tutti i Santi")) + + # All Souls' Day. + self._add_all_souls_day(tr("Tutti i Fedeli Defunti")) + + # Immaculate Conception. + self._add_immaculate_conception_day(tr("Immacolata Concezione")) + + # Christmas Eve. + self._add_christmas_eve(tr("Vigilia di Natale")) + + # Christmas Day. + self._add_christmas_day(tr("Natale")) + + # Saint Stephen's Day. + self._add_christmas_day_two(tr("Santo Stefano")) + + # Saint John the Evangelist's Day. + self._add_christmas_day_three(tr("San Giovanni")) + + # Last Day of the Year. + self._add_new_years_eve(tr("Ultimo giorno dell'anno")) + + +class VA(VaticanCity): + pass + + +class VAT(VaticanCity): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/venezuela.py b/.venv/lib/python3.12/site-packages/holidays/countries/venezuela.py new file mode 100644 index 00000000..c3f2a295 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/venezuela.py @@ -0,0 +1,112 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class Venezuela(HolidayBase, ChristianHolidays, InternationalHolidays): + """Venezuela holidays. + + References: + * + * [1909 Aug 5](https://web.archive.org/web/20241012151721/https://www.guao.org/sites/default/files/efemerides/69.Ley%20fiestas%20nacionales%201909.pdf) + * [1918 May 19](https://web.archive.org/web/20250429081541/https://www.guao.org/sites/default/files/efemerides/70.%20Ley%20de%20fiestas%20nacionales%201918.pdf) + * [1921 Jun 11](https://web.archive.org/web/20241012160001/https://www.guao.org/sites/default/files/efemerides/37.LEYES_Y_DECRETOS_1921_Día_de_la_raza.PDF) + * [1971 Jun 22](https://web.archive.org/web/20240802055637/https://www.ilo.org/dyn/travail/docs/2030/Law%20No.29.541.pdf) + * [2002 Oct 10](https://web.archive.org/web/20250214140239/https://www.acnur.org/fileadmin/Documentos/BDL/2008/6635.pdf) + * [2012 May 7](https://web.archive.org/web/20250418204844/https://oig.cepal.org/sites/default/files/2012_leyorgtrabajo_ven.pdf) + """ + + country = "VE" + default_language = "es" + supported_languages = ("en_US", "es", "uk") + start_year = 1801 + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_new_years_day(tr("Año Nuevo")) + + # Monday of Carnival. + self._add_carnival_monday(tr("Lunes de Carnaval")) + + # Tuesday of Carnival. + self._add_carnival_tuesday(tr("Martes de Carnaval")) + + # Maundy Thursday. + self._add_holy_thursday(tr("Jueves Santo")) + + # Good Friday. + self._add_good_friday(tr("Viernes Santo")) + + # Note: not sure about the start year, but this event happened in 1811 + if self._year >= 1811: + # Declaration of Independence. + self._add_holiday_apr_19(tr("Declaración de la Independencia")) + + # https://web.archive.org/web/20250428122616/https://venezuelaenretrospectiva.wordpress.com/2016/05/01/1o-de-mayo-dia-del-trabajador-venezolano/ + if self._year >= 1946: + # International Worker's Day. + self._add_labor_day(tr("Dia Mundial del Trabajador")) + + # Note: not sure about the start year, but this event happened in 1824 + if self._year >= 1971 or 1824 <= self._year <= 1917: + # Battle of Carabobo. + self._add_holiday_jun_24(tr("Batalla de Carabobo")) + + # Note: not sure about the start year, but this event happened in 1811 + if self._year >= 1811: + # Independence Day. + self._add_holiday_jul_5(tr("Día de la Independencia")) + + if self._year >= 1918: + # Birthday of Simon Bolivar. + self._add_holiday_jul_24(tr("Natalicio de Simón Bolívar")) + + if self._year >= 1921: + self._add_columbus_day( + # Day of Indigenous Resistance. + tr("Día de la Resistencia Indígena") + if self._year >= 2002 + # Columbus Day. + else tr("Día de la Raza") + ) + + # Note: not sure about the start year nor the reason this was + # Note: celebrated; the historical records are unclear + if 1909 <= self._year <= 1917: + # Unknown Holiday. + self._add_holiday_oct_28(tr("Día Festivo Desconocido")) + + # Christmas Eve. + self._add_christmas_eve(tr("Nochebuena")) + + # Christmas Day. + self._add_christmas_day(tr("Día de Navidad")) + + # New Year's Eve. + self._add_new_years_eve(tr("Fiesta de Fin de Año")) + + +class VE(Venezuela): + pass + + +class VEN(Venezuela): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/vietnam.py b/.venv/lib/python3.12/site-packages/holidays/countries/vietnam.py new file mode 100644 index 00000000..23d914a3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/vietnam.py @@ -0,0 +1,180 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from gettext import gettext as tr + +from holidays.calendars.chinese import VIETNAMESE_CALENDAR +from holidays.calendars.gregorian import ( + JAN, + FEB, + APR, + MAY, + SEP, + DEC, + MON, + TUE, + WED, + THU, + FRI, + SAT, + SUN, + _timedelta, +) +from holidays.groups import ChineseCalendarHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ( + ObservedHolidayBase, + ObservedRule, + SAT_TO_PREV_WORKDAY, + SUN_TO_NEXT_WORKDAY, + SAT_SUN_TO_NEXT_WORKDAY, +) + +NATIONAL_DAY_RULE = ObservedRule({MON: +1, TUE: -1, WED: -1, THU: +1, FRI: -1, SAT: -1, SUN: +1}) + + +class Vietnam(ObservedHolidayBase, ChineseCalendarHolidays, InternationalHolidays, StaticHolidays): + """Vietnam holidays. + + References: + * [Labor Code 1994 (Art. 73) (en)](https://web.archive.org/web/20160630110506/http://vbpl.vn/TW/Pages/vbpqen-toanvan.aspx?ItemID=2835) + * [Labor Code 2012 (Art. 115) (en)](https://web.archive.org/web/20240706232343/http://vbpl.vn/TW/Pages/vbpqen-toanvan.aspx?ItemID=11013) + * [Labor Code 2012 (Art. 115) (vi)](https://web.archive.org/web/20240917113133/https://vbpl.vn/TW/Pages/vbpq-toanvan.aspx?ItemID=27615) + * [Labor Code 2019 (Art. 112) (en)](https://web.archive.org/web/20250108181808/https://vbpl.vn/TW/pages/vbpqen-toanvan.aspx?ItemID=11135) + * [Labor Code 2019 (Art. 112) (vi)](https://web.archive.org/web/20250221171552/https://vbpl.vn/TW/Pages/vbpq-van-ban-goc.aspx?ItemID=139264) + """ + + country = "VN" + # %s (observed). + observed_label = tr("%s (nghỉ bù)") + default_language = "vi" + supported_languages = ("en_US", "th", "vi") + + def __init__(self, *args, **kwargs): + ChineseCalendarHolidays.__init__(self, calendar=VIETNAMESE_CALENDAR) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, VietnamStaticHolidays) + kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY) + kwargs.setdefault("observed_since", 1995) + super().__init__(*args, **kwargs) + + def _add_lunar_new_year_observed(self, dt_lny: date) -> None: + if self._year <= 1994: + return None + + day_names = { + # 29 of Lunar New Year. + -2: tr("29 Tết"), + # Fourth Day of Lunar New Year. + 3: tr("Mùng bốn Tết Nguyên Đán"), + # Fifth Day of Lunar New Year. + 4: tr("Mùng năm Tết Nguyên Đán"), + # Sixth Day of Lunar New Year. + 5: tr("Mùng sáu Tết Nguyên Đán"), + } + for delta in range(-1, 4 if self._year >= 2013 else 3): + dt = _timedelta(dt_lny, delta) + dt_observed = self._get_observed_date( + dt, + rule=( + SAT_TO_PREV_WORKDAY + SUN_TO_NEXT_WORKDAY + if self._year >= 2014 + else SAT_SUN_TO_NEXT_WORKDAY + ), + ) + if dt_observed != dt: + self._add_holiday( + day_names[(dt_observed - dt_lny).days], # type: ignore[operator] + dt_observed, + ) + + def _populate_public_holidays(self): + dts_observed = set() + + # New Year's Day. + dts_observed.add(self._add_new_years_day(tr("Tết Dương lịch"))) + + # Lunar New Year's Eve. + self._add_chinese_new_years_eve(tr("Giao thừa Tết Nguyên Đán")) + + # Lunar New Year. + lny = self._add_chinese_new_years_day(tr("Tết Nguyên Đán")) + + # Second Day of Lunar New Year. + self._add_chinese_new_years_day_two(tr("Mùng hai Tết Nguyên Đán")) + + # Third Day of Lunar New Year. + self._add_chinese_new_years_day_three(tr("Mùng ba Tết Nguyên Đán")) + + if self._year >= 2013: + # Fourth Day of Lunar New Year. + self._add_chinese_new_years_day_four(tr("Mùng bốn Tết Nguyên Đán")) + + if self._year >= 2007: + # Hung Kings' Commemoration Day. + dts_observed.add(self._add_hung_kings_day(tr("Ngày Giỗ Tổ Hùng Vương"))) + + # Liberation Day/Reunification Day. + dts_observed.add(self._add_holiday_apr_30(tr("Ngày Chiến thắng"))) + + # International Labor Day. + dts_observed.add(self._add_labor_day(tr("Ngày Quốc tế Lao động"))) + + # National Day. + name = tr("Quốc khánh") + dts_observed.add(sep_2 := self._add_holiday_sep_2(name)) + if self._year >= 2021: + self._add_holiday(name, self._get_observed_date(sep_2, NATIONAL_DAY_RULE)) + + if self.observed: + self._add_lunar_new_year_observed(lny) + self._populate_observed(dts_observed) + + +class VN(Vietnam): + pass + + +class VNM(Vietnam): + pass + + +class VietnamStaticHolidays: + """Vietnam special holidays. + + References: + * [2018-2019](https://web.archive.org/web/20250427182343/https://thuvienphapluat.vn/cong-van/EN/Lao-dong-Tien-luong/Official-Dispatch-6519-VPCP-KGVX-2018-national-holidays-for-public-sector-employees/387625/tieng-anh.aspx) + * [2024](https://web.archive.org/web/20241002165957/https://thuvienphapluat.vn/cong-van/EN/Lao-dong-Tien-luong/Official-Dispatch-2450-VPCP-KGVX-2024-swap-of-working-days-during-the-Reunification-Day/606458/tieng-anh.aspx) + """ + + # Date format (see strftime() Format Codes). + substituted_date_format = tr("%d/%m/%Y") + # Day off (substituted from %s). + substituted_label = tr("Ngày nghỉ (thay cho ngày %s)") + + special_public_holidays = { + 2010: (FEB, 19, FEB, 27), + 2012: (JAN, 27, FEB, 4), + 2013: (APR, 29, MAY, 4), + 2014: ( + (MAY, 2, APR, 26), + (SEP, 1, SEP, 6), + ), + 2015: ( + (JAN, 2, DEC, 27, 2014), + (FEB, 16, FEB, 14), + (APR, 29, APR, 25), + ), + 2018: (DEC, 31, JAN, 5, 2019), + 2019: (APR, 29, MAY, 4), + 2024: (APR, 29, MAY, 4), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/wallis_and_futuna.py b/.venv/lib/python3.12/site-packages/holidays/countries/wallis_and_futuna.py new file mode 100644 index 00000000..24dd1c62 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/wallis_and_futuna.py @@ -0,0 +1,43 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.countries.france import France +from holidays.mixins.child_entity import ChildEntity + + +class HolidaysWF(ChildEntity, France): + """Wallis and Futuna holidays. + + Alias of a French subdivision that is also officially assigned + its own country code in ISO 3166-1. + + References: + * + * + """ + + country = "WF" + parent_entity = France + # Separation from French Caledonia on July 29th, 1961. + start_year = 1962 + + +class WallisAndFutuna(HolidaysWF): + pass + + +class WF(HolidaysWF): + pass + + +class WLF(HolidaysWF): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/yemen.py b/.venv/lib/python3.12/site-packages/holidays/countries/yemen.py new file mode 100644 index 00000000..ed71e01b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/yemen.py @@ -0,0 +1,207 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + THU, + FRI, + SAT, + _timedelta, +) +from holidays.constants import PUBLIC, SCHOOL, WORKDAY +from holidays.groups import InternationalHolidays, IslamicHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, FRI_TO_NEXT_WORKDAY + + +class Yemen(ObservedHolidayBase, InternationalHolidays, IslamicHolidays): + """Yemen holidays. + + References: + * [Presidential Decree Law No. (8) of 1996](https://web.archive.org/web/20230905142654/http://yemen-nic.info/db/laws_ye/detail.php?ID=11476) + * [Presidential Decree Law No. (2) of 2000](https://web.archive.org/web/20140714152707/http://www.presidentsaleh.gov.ye/showlaws.php?_lwbkno=3&_lwptno=2&_lwnmid=4) + * + * + * + * + * + * + """ + + country = "YE" + default_language = "ar" + # %s (estimated). + estimated_label = tr("%s (المقدرة)") + # %s (observed). + observed_label = tr("%s (ملاحظة)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (المقدرة، ملاحظة)") + # The Republic of Yemen was declared on 22 May 1990. + start_year = 1991 + supported_categories = (PUBLIC, SCHOOL, WORKDAY) + supported_languages = ("ar", "en_US") + + def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=YemenIslamicHolidays, show_estimated=islamic_show_estimated + ) + kwargs.setdefault("observed_rule", FRI_TO_NEXT_WORKDAY) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + dts_observed = set() + + # Yemen switches from THU-FRI to FRI-SAT on Aug 15, 2013 + self.weekend = {THU, FRI} if self._year <= 2012 else {FRI, SAT} + + # Hijri New Year. + dts_observed.update(self._add_islamic_new_year_day(tr("عيد رأس السنة الهجرية"))) + + if self._year <= 1999: + # Prophet's Birthday. + dts_observed.update(self._add_mawlid_day(tr("المولد النبوي"))) + + # Eid al-Fitr. + name = tr("عيد الفطر") + dts_observed.update(self._add_eid_al_fitr_day(name)) + dts_observed.update(self._add_eid_al_fitr_day_two(name)) + dts_observed.update(self._add_eid_al_fitr_day_three(name)) + ramadan_29_holidays = self._add_holiday_29_ramadan(name) + dts_observed.update(ramadan_29_holidays) + for dt in ramadan_29_holidays: + if _timedelta(dt, +1) not in self: + dts_observed.update(self._add_eid_al_fitr_eve(name)) + + # Eid al-Adha. + name = tr("عيد الأضحى") + dts_observed.update(self._add_arafah_day(name)) + dts_observed.update(self._add_eid_al_adha_day(name)) + dts_observed.update(self._add_eid_al_adha_day_two(name)) + dts_observed.update(self._add_eid_al_adha_day_three(name)) + dts_observed.update(self._add_eid_al_adha_day_four(name)) + + # Labor Day. + dts_observed.add(self._add_labor_day(tr("عيد العمال"))) + + # Unity Day. + dts_observed.add(self._add_holiday_may_22(tr("اليوم الوطني للجمهورية اليمنية"))) + + if self._year <= 1999: + # Victory Day. + dts_observed.add(self._add_holiday_jul_7(tr("ذكرى 7 يوليو"))) + + # Revolution Day. + dts_observed.add(self._add_holiday_sep_26(tr("ثورة 26 سبتمبر المجيدة"))) + + # Liberation Day. + dts_observed.add(self._add_holiday_oct_14(tr("ثورة 14 أكتوبر المجيدة"))) + + # Independence Day. + dts_observed.add(self._add_holiday_nov_30(tr("عيد الجلاء"))) + + if self.observed: + self._populate_observed(dts_observed) + + def _populate_school_holidays(self): + if self._year >= 2013: + # Teacher's Day. + self._add_holiday_may_5(tr("عيد المعلم")) + + def _populate_workday_holidays(self): + if self._year >= 2000: + # Prophet's Birthday. + self._add_mawlid_day(tr("المولد النبوي")) + + # Isra' and Mi'raj. + self._add_isra_and_miraj_day(tr("ذكرى الإسراء والمعراج")) + + # Victory Day. + self._add_holiday_jul_7(tr("ذكرى 7 يوليو")) + + +class YE(Yemen): + pass + + +class YEM(Yemen): + pass + + +class YemenIslamicHolidays(_CustomIslamicHolidays): + # https://web.archive.org/web/20250115070635/https://www.timeanddate.com/holidays/yemen/eid-al-adha-first-day + EID_AL_ADHA_DATES = { + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 9), + 2023: (JUN, 28), + 2024: (JUN, 16), + } + + # https://web.archive.org/web/20250218061345/https://www.timeanddate.com/holidays/yemen/eid-al-fitr-first-day + EID_AL_FITR_DATES = { + 2020: (MAY, 24), + 2021: (MAY, 13), + 2022: (MAY, 2), + 2023: (APR, 21), + 2024: (APR, 10), + 2025: (MAR, 30), + } + + # https://web.archive.org/web/20241011200213/https://www.timeanddate.com/holidays/yemen/muharram-new-year + HIJRI_NEW_YEAR_DATES = { + 2020: (AUG, 20), + 2021: (AUG, 10), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 7), + } + + # https://web.archive.org/web/20241010083000/https://www.timeanddate.com/holidays/yemen/isra-miraj + ISRA_AND_MIRAJ_DATES = { + 2023: (FEB, 18), + 2024: (FEB, 8), + 2025: (JAN, 27), + } + + # https://web.archive.org/web/20241010222331/https://www.timeanddate.com/holidays/yemen/prophet-birthday + MAWLID_DATES = { + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 15), + } + + # https://web.archive.org/web/20250119111122/https://www.timeanddate.com/holidays/yemen/ramadan-begins + RAMADAN_BEGINNING_DATES = { + 2023: (MAR, 23), + 2024: (MAR, 11), + 2025: (MAR, 1), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/zambia.py b/.venv/lib/python3.12/site-packages/holidays/countries/zambia.py new file mode 100644 index 00000000..70f8b22f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/zambia.py @@ -0,0 +1,117 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import MAR, JUL, AUG, SEP +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Zambia(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays): + """Zambia holidays. + + References: + * + * + * + * + """ + + country = "ZM" + observed_label = "%s (observed)" + start_year = 1965 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, ZambiaStaticHolidays) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + if self._year >= 1991: + self._add_observed( + # International Women's Day. + self._add_womens_day("International Women's Day") + ) + + # Youth Day. + self._add_observed(self._add_holiday_mar_12("Youth Day")) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Holy Saturday. + self._add_holy_saturday("Holy Saturday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + if self._year >= 2022: + # Kenneth Kaunda Day. + self._add_observed(self._add_holiday_apr_28("Kenneth Kaunda Day")) + + # Labour Day. + self._add_observed(self._add_labor_day("Labour Day")) + + # Africa Freedom Day. + self._add_observed(self._add_africa_day("Africa Freedom Day")) + + # Heroes' Day. + self._add_holiday_1st_mon_of_jul("Heroes' Day") + + # Unity Day. + self._add_holiday_1_day_past_1st_mon_of_jul("Unity Day") + + # Farmers' Day. + self._add_holiday_1st_mon_of_aug("Farmers' Day") + + if self._year >= 2015: + # National Prayer Day. + self._add_observed(self._add_holiday_oct_18("National Prayer Day")) + + # Independence Day. + self._add_observed(self._add_holiday_oct_24("Independence Day")) + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day")) + + +class ZM(Zambia): + pass + + +class ZMB(Zambia): + pass + + +class ZambiaStaticHolidays: + special_public_holidays = { + 2016: ( + (AUG, 11, "General elections and referendum"), + (SEP, 13, "Inauguration ceremony of President-elect and Vice President-elect"), + ), + 2018: ( + (MAR, 9, "Public holiday"), + (JUL, 26, "Lusaka mayoral and other local government elections"), + ), + 2021: ( + (JUL, 2, "Memorial service for Kenneth Kaunda"), + (JUL, 7, "Funeral of Kenneth Kaunda"), + (AUG, 12, "General elections"), + (AUG, 13, "Counting in general elections"), + (AUG, 24, "Presidential inauguration"), + ), + 2022: (MAR, 18, "Funeral of Rupiah Banda"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/countries/zimbabwe.py b/.venv/lib/python3.12/site-packages/holidays/countries/zimbabwe.py new file mode 100644 index 00000000..d0c96f6c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/countries/zimbabwe.py @@ -0,0 +1,87 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON, SUN_TO_NEXT_TUE + + +class Zimbabwe(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """Zimbabwe holidays. + + References: + * + * + """ + + country = "ZW" + observed_label = "%s (observed)" + start_year = 1988 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day("New Year's Day")) + + if self._year >= 2018: + self._add_observed( + # Robert Gabriel Mugabe National Youth Day. + self._add_holiday_feb_21("Robert Gabriel Mugabe National Youth Day") + ) + + # Good Friday. + self._add_good_friday("Good Friday") + + # Easter Saturday. + self._add_holy_saturday("Easter Saturday") + + # Easter Monday. + self._add_easter_monday("Easter Monday") + + self._add_observed( + # Independence Day. + apr_18 := self._add_holiday_apr_18("Independence Day"), + rule=SUN_TO_NEXT_TUE if apr_18 == self._easter_sunday else SUN_TO_NEXT_MON, + ) + + # Workers' Day. + self._add_observed(self._add_labor_day("Workers' Day")) + + # Africa Day. + self._add_observed(self._add_africa_day("Africa Day")) + + # Zimbabwe Heroes' Day. + self._add_holiday_2nd_mon_of_aug("Zimbabwe Heroes' Day") + + # Defense Forces Day. + self._add_holiday_1_day_past_2nd_mon_of_aug("Defense Forces Day") + + # Unity Day. + self._add_observed(self._add_holiday_dec_22("Unity Day")) + + # Christmas Day. + self._add_observed(self._add_christmas_day("Christmas Day"), rule=SUN_TO_NEXT_TUE) + + # Boxing Day. + self._add_observed(self._add_christmas_day_two("Boxing Day")) + + +class ZW(Zimbabwe): + pass + + +class ZWE(Zimbabwe): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/deprecations/__pycache__/v1_incompatibility.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/deprecations/__pycache__/v1_incompatibility.cpython-312.pyc new file mode 100644 index 00000000..5597c75d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/deprecations/__pycache__/v1_incompatibility.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/deprecations/v1_incompatibility.py b/.venv/lib/python3.12/site-packages/holidays/deprecations/v1_incompatibility.py new file mode 100644 index 00000000..53aafa08 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/deprecations/v1_incompatibility.py @@ -0,0 +1,43 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +import warnings + +from holidays.version import __version__ + +FUTURE_INCOMPATIBILITY_WARNING_TEMPLATE = """ + +This is a future version incompatibility warning from Holidays v{version} +to inform you about an upcoming change in our API versioning strategy that may affect your +project's dependencies. Starting from version 1.0 onwards, we will be following a loose form of +Semantic Versioning (SemVer, https://semver.org/) to provide clearer communication regarding any +potential breaking changes. + +This means that while we strive to maintain backward compatibility, there might be occasional +updates that introduce breaking changes to our API. To ensure the stability of your projects, +we highly recommend pinning the version of our API that you rely on. You can pin your current +holidays v0.x dependency (e.g., holidays=={version}) or limit it (e.g., holidays<1.0) in order to +avoid potentially unwanted upgrade to the version 1.0 when it's released (ETA 2025Q1-Q2). + +If you have any questions or concerns regarding this change, please don't hesitate to reach out +to us via https://github.com/vacanza/holidays/discussions/1800. +""" + + +class FutureIncompatibilityWarning(DeprecationWarning): + pass + + +warnings.warn( + FUTURE_INCOMPATIBILITY_WARNING_TEMPLATE.format(version=__version__), + FutureIncompatibilityWarning, +) diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/__init__.py b/.venv/lib/python3.12/site-packages/holidays/financial/__init__.py new file mode 100644 index 00000000..e918721d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/financial/__init__.py @@ -0,0 +1,18 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +# ruff: noqa: F401 + +from holidays.financial.brasil_bolsa_balcao import BrasilBolsaBalcao, BVMF, B3 +from holidays.financial.european_central_bank import EuropeanCentralBank, XECB, ECB, TAR +from holidays.financial.ice_futures_europe import ICEFuturesEurope, IFEU +from holidays.financial.ny_stock_exchange import NewYorkStockExchange, XNYS, NYSE diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..3a6064d9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/brasil_bolsa_balcao.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/brasil_bolsa_balcao.cpython-312.pyc new file mode 100644 index 00000000..ac63dde5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/brasil_bolsa_balcao.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/european_central_bank.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/european_central_bank.cpython-312.pyc new file mode 100644 index 00000000..3c0d9530 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/european_central_bank.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/ice_futures_europe.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/ice_futures_europe.cpython-312.pyc new file mode 100644 index 00000000..97c3cacd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/ice_futures_europe.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/ny_stock_exchange.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/ny_stock_exchange.cpython-312.pyc new file mode 100644 index 00000000..f28ac125 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/financial/__pycache__/ny_stock_exchange.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/brasil_bolsa_balcao.py b/.venv/lib/python3.12/site-packages/holidays/financial/brasil_bolsa_balcao.py new file mode 100644 index 00000000..7fcc8706 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/financial/brasil_bolsa_balcao.py @@ -0,0 +1,109 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.holiday_base import HolidayBase + + +class BrasilBolsaBalcao(HolidayBase, ChristianHolidays, InternationalHolidays): + """Brasil, Bolsa, Balcão holidays. + + References: + * [Decreto n. 155-B, de 14.01.1890](https://web.archive.org/web/20241226133739/https://www2.camara.leg.br/legin/fed/decret/1824-1899/decreto-155-b-14-janeiro-1890-517534-publicacaooriginal-1-pe.html) + * [Decreto n. 19.488, de 15.12.1930](https://web.archive.org/web/20241006041503/http://camara.leg.br/legin/fed/decret/1930-1939/decreto-19488-15-dezembro-1930-508040-republicacao-85201-pe.html) + * [Decreto n. 22.647, de 17.04.1933](https://web.archive.org/web/20220414202918/https://www2.camara.leg.br/legin/fed/decret/1930-1939/decreto-22647-17-abril-1933-558774-publicacaooriginal-80337-pe.html) + * [Lei n. 662, de 6.04.1949](https://web.archive.org/web/20240913060643/https://www2.camara.leg.br/legin/fed/lei/1940-1949/lei-662-6-abril-1949-347136-publicacaooriginal-1-pl.html) + * [Lei n. 6.802, de 30.06.1980](https://web.archive.org/web/20250206215621/http://www.planalto.gov.br/ccivil_03/leis/L6802.htm) + * [Resolução n. 2.516, de 29.06.1998](https://web.archive.org/web/20250428203302/https://www.bcb.gov.br/pre/normativos/res/1998/pdf/res_2516_v2_P.pdf) + * [Lei n. 14.759, de 21.12.2023](https://web.archive.org/web/20250402234552/https://www2.camara.leg.br/legin/fed/lei/2023/lei-14759-21-dezembro-2023-795091-publicacaooriginal-170522-pl.html) + + Historical data: + * [Feriados ANBIMA 2001-2099](https://web.archive.org/web/20241209033536/https://www.anbima.com.br/feriados/) + * [Calendario de negociação B3](https://web.archive.org/web/20250126154858/https://www.b3.com.br/pt_br/solucoes/plataformas/puma-trading-system/para-participantes-e-traders/calendario-de-negociacao/feriados/) + """ + + market = "BVMF" + default_language = "pt_BR" + supported_languages = ("en_US", "pt_BR", "uk") + # Decreto n. 155-B, de 14.01.1890 + # Curiously enough, 1890 is also the year of foundation of the + # São Paulo Stock Exchange, which would later become the B3. + start_year = 1890 + + def __init__(self, *args, **kwargs) -> None: + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # Universal Fraternization Day. + self._add_new_years_day(tr("Confraternização Universal")) + + # Carnival. + carnival_name = tr("Carnaval") + self._add_carnival_monday(carnival_name) + self._add_carnival_tuesday(carnival_name) + + # Resolução n. 2.516, de 29.06.1998 + if self._year <= 1999: + # Holy Thursday. + self._add_holy_thursday(tr("Quinta-feira Santa")) + + # Good Friday. + self._add_good_friday(tr("Sexta-feira Santa")) + + # Tiradentes' Day was revoked by president Getúlio Vargas in + # december of 1930, through Decreto n. 19.488, but reinstated + # by the same president in 1933, through Decreto n. 22.647. + if self._year not in {1931, 1932}: + # Tiradentes' Day. + self._add_holiday_apr_21(tr("Tiradentes")) + + if self._year >= 1925: + # Worker's Day. + self._add_labor_day(tr("Dia do Trabalhador")) + + # Corpus Christi. + self._add_corpus_christi_day(tr("Corpus Christi")) + + # Independence Day. + self._add_holiday_sep_7(tr("Independência do Brasil")) + + # Lei n. 6.802, de 30.06.1980 + if self._year >= 1980: + # Our Lady of Aparecida. + self._add_holiday_oct_12(tr("Nossa Senhora Aparecida")) + + # All Souls' Day. + self._add_all_souls_day(tr("Finados")) + + # Republic Proclamation Day. + self._add_holiday_nov_15(tr("Proclamação da República")) + + # Lei n. 14.759, de 21.12.2023 + if self._year >= 2024: + # National Day of Zumbi and Black Awareness. + self._add_holiday_nov_20(tr("Dia Nacional de Zumbi e da Consciência Negra")) + + if self._year >= 1922: + # Christmas Day. + self._add_christmas_day(tr("Natal")) + + +class BVMF(BrasilBolsaBalcao): + pass + + +class B3(BrasilBolsaBalcao): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/european_central_bank.py b/.venv/lib/python3.12/site-packages/holidays/financial/european_central_bank.py new file mode 100644 index 00000000..2ea20ebe --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/financial/european_central_bank.py @@ -0,0 +1,66 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.calendars.gregorian import DEC +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.holiday_base import HolidayBase + + +class EuropeanCentralBank(HolidayBase, ChristianHolidays, InternationalHolidays): + """European Central Bank holidays. + + References: + * + * + * + * + """ + + market = "XECB" + start_year = 2000 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, EuropeanCentralBankStaticHolidays) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self._add_new_years_day("New Year's Day") + + self._add_good_friday("Good Friday") + + self._add_easter_monday("Easter Monday") + + self._add_labor_day("Labour Day") + + self._add_christmas_day("Christmas Day") + + self._add_christmas_day_two("Christmas Holiday") + + +class XECB(EuropeanCentralBank): + pass + + +class ECB(EuropeanCentralBank): + pass + + +class TAR(EuropeanCentralBank): + pass + + +class EuropeanCentralBankStaticHolidays: + special_public_holidays = { + 2000: (DEC, 31, "Additional closing day"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/ice_futures_europe.py b/.venv/lib/python3.12/site-packages/holidays/financial/ice_futures_europe.py new file mode 100644 index 00000000..efaceace --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/financial/ice_futures_europe.py @@ -0,0 +1,45 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from holidays.groups import ChristianHolidays, InternationalHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_TO_NONE, SUN_TO_NEXT_MON + + +class ICEFuturesEurope(ObservedHolidayBase, ChristianHolidays, InternationalHolidays): + """ICE Futures Europe holidays. + + References: + * + * + * + * + """ + + market = "IFEU" + start_year = 2014 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + kwargs.setdefault("observed_rule", SAT_TO_NONE + SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + self._move_holiday(self._add_new_years_day("New Year's Day")) + + self._add_good_friday("Good Friday") + + self._move_holiday(self._add_christmas_day("Christmas Day")) + + +class IFEU(ICEFuturesEurope): + pass diff --git a/.venv/lib/python3.12/site-packages/holidays/financial/ny_stock_exchange.py b/.venv/lib/python3.12/site-packages/holidays/financial/ny_stock_exchange.py new file mode 100644 index 00000000..89b268a8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/financial/ny_stock_exchange.py @@ -0,0 +1,287 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date + +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + _timedelta, +) +from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SAT_TO_PREV_FRI, SUN_TO_NEXT_MON + + +class NewYorkStockExchange( + ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays +): + """New York Stock Exchange holidays. + + References: + * + + Historical data: + * + * + """ + + market = "XNYS" + observed_label = "%s (observed)" + start_year = 1863 + + def __init__(self, *args, **kwargs): + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + StaticHolidays.__init__(self, NewYorkStockExchangeStaticHolidays) + kwargs.setdefault("observed_rule", SAT_TO_PREV_FRI + SUN_TO_NEXT_MON) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + name = "New Year's Day" + self._move_holiday(self._add_new_years_day(name)) + + # MLK, 3rd Monday of January. + if self._year >= 1998: + self._add_holiday_3rd_mon_of_jan("Martin Luther King Jr. Day") + + # LINCOLN BIRTHDAY: observed 1896 - 1953 and 1968, Feb 12 (observed) + if 1896 <= self._year <= 1953 or self._year == 1968: + self._move_holiday(self._add_holiday_feb_12("Lincoln's Birthday")) + + # WASHINGTON'S BIRTHDAY: Feb 22 (obs) until 1971, then 3rd Mon of Feb + name = "Washington's Birthday" + if self._year <= 1970: + self._move_holiday(self._add_holiday_feb_22(name)) + else: + self._add_holiday_3rd_mon_of_feb(name) + + # GOOD FRIDAY - closed every year except 1898, 1906, and 1907 + if self._year not in {1898, 1906, 1907}: + self._add_good_friday("Good Friday") + + # MEM DAY (May 30) - closed every year since 1873 + # last Mon in May since 1971 + if self._year >= 1873: + name = "Memorial Day" + if self._year <= 1970: + self._move_holiday(self._add_holiday_may_30(name)) + else: + self._add_holiday_last_mon_of_may(name) + + # FLAG DAY: June 14th 1916 - 1953 + if 1916 <= self._year <= 1953: + self._move_holiday(self._add_holiday_jun_14("Flag Day")) + + # JUNETEENTH: since 2022 + if self._year >= 2022: + self._move_holiday(self._add_holiday_jun_19("Juneteenth National Independence Day")) + + # INDEPENDENCE DAY (July 4) - history suggests closed every year + self._move_holiday(self._add_holiday_jul_4("Independence Day")) + + # LABOR DAY - first mon in Sept, since 1887 + if self._year >= 1887: + self._add_holiday_1st_mon_of_sep("Labor Day") + + # COLUMBUS DAY/INDIGENOUS PPL DAY: Oct 12 - closed 1909-1953 + if 1909 <= self._year <= 1953: + self._move_holiday(self._add_columbus_day("Columbus Day")) + + # ELECTION DAY: Tuesday after first Monday in November (2 U.S. Code §7) + # closed until 1969, then closed pres years 1972-80 + if self._year <= 1968 or self._year in {1972, 1976, 1980}: + self._add_holiday_1_day_past_1st_mon_of_nov("Election Day") + + # VETERAN'S DAY: Nov 11 - closed 1918, 1921, 1934-1953 + if self._year in {1918, 1921} or 1934 <= self._year <= 1953: + self._move_holiday(self._add_remembrance_day("Veteran's Day")) + + # THXGIVING DAY: 4th Thurs in Nov - closed every year + self._add_holiday_4th_thu_of_nov("Thanksgiving Day") + + # XMAS DAY: Dec 25th - every year + self._move_holiday(self._add_christmas_day("Christmas Day")) + + # Special holidays. + if self._year == 1914: + # Beginning of WWI. + begin = date(self._year, JUL, 31) + end = date(self._year, NOV, 27) + for dt in (_timedelta(begin, n) for n in range((end - begin).days + 1)): + if self._is_weekend(dt) or dt in self: + continue + self._add_holiday("World War I", dt) + elif self._year == 1968: + begin = date(self._year, JUN, 12) + end = date(self._year, DEC, 24) + # Wednesday special holiday. + for dt in (_timedelta(begin, n) for n in range(0, (end - begin).days + 1, 7)): + self._add_holiday("Paper Crisis", dt) + + +class XNYS(NewYorkStockExchange): + pass + + +class NYSE(NewYorkStockExchange): + pass + + +class NewYorkStockExchangeStaticHolidays: + """New York Stock Exchange special holidays. + + References: + * + * + """ + + # Blizzard of 1888. + name_blizard_1888 = "Blizzard of 1888" + + # Centennial of George Washington's Inauguration. + name_george_washington_centennial = "Centennial of George Washington's Inauguration" + + # Columbian Celebration. + name_columbian_celebration = "Columbian Celebration" + + # Heatless Day. + name_heatless_day = "Heatless Day" + + # Catch Up Day. + name_catch_up_day = "Catch Up Day" + + # Special Bank Holiday. + name_special_bank_holiday = "Special Bank Holiday" + + # V-J Day (WWII). + name_vj_day_wwii = "V-J Day (WWII)" + + # Christmas Eve. + name_christmas_eve = "Christmas Eve" + + # Closed for Sept 11, 2001 Attacks. + name_sept11_attacks = "Closed for Sept 11, 2001 Attacks" + + # Hurricane Sandy. + name_hurricane_sandy = "Hurricane Sandy" + + special_public_holidays = { + 1888: ( + (MAR, 12, name_blizard_1888), + (MAR, 13, name_blizard_1888), + (NOV, 30, "Thanksgiving Friday 1888"), + ), + 1889: ( + (APR, 29, name_george_washington_centennial), + (APR, 30, name_george_washington_centennial), + (MAY, 1, name_george_washington_centennial), + ), + 1892: ( + (OCT, 12, name_columbian_celebration), + (OCT, 21, name_columbian_celebration), + ), + 1893: (APR, 27, name_columbian_celebration), + 1897: (APR, 27, "Grant's Birthday"), + 1898: (MAY, 4, "Charter Day"), + 1899: ( + (MAY, 29, "Monday before Decoration Day"), + (JUL, 3, "Monday before Independence Day"), + (SEP, 29, "Admiral Dewey Celebration"), + ), + 1900: (DEC, 24, name_christmas_eve), + 1901: ( + (JUL, 5, "Friday after Independence Day"), + (SEP, 19, "National Day of Mourning for President WIlliam McKinley"), + ), + 1903: (APR, 22, "Opening of new NYSE building"), + 1917: (JUN, 5, "Draft Registration Day"), + 1918: ( + (JAN, 28, name_heatless_day), + (FEB, 4, name_heatless_day), + (FEB, 11, name_heatless_day), + (SEP, 12, "Draft Registration Day"), + (NOV, 11, "Armistice Day"), + ), + 1919: ( + (MAR, 25, "Homecoming Day for 27th Division"), + (MAY, 6, "Parade Day for 77th Division"), + (SEP, 10, "Return of General Pershing"), + ), + 1923: ( + (AUG, 3, "Death of President Warren G. Harding"), + (AUG, 10, "National Day of Mourning for President Warren G. Harding"), + ), + 1927: (JUN, 13, "Parade for Colonel Charles Lindbergh"), + 1929: ( + (NOV, 1, name_catch_up_day), + (NOV, 29, name_catch_up_day), + ), + 1933: ( + (MAR, 6, name_special_bank_holiday), + (MAR, 7, name_special_bank_holiday), + (MAR, 8, name_special_bank_holiday), + (MAR, 9, name_special_bank_holiday), + (MAR, 10, name_special_bank_holiday), + (MAR, 13, name_special_bank_holiday), + (MAR, 14, name_special_bank_holiday), + ), + 1945: ( + (AUG, 15, name_vj_day_wwii), + (AUG, 16, name_vj_day_wwii), + (DEC, 24, name_christmas_eve), + ), + 1954: (DEC, 24, name_christmas_eve), + 1956: (DEC, 24, name_christmas_eve), + 1958: (DEC, 26, "Day after Christmas"), + 1961: (MAY, 29, "Day before Decoration Day"), + 1963: (NOV, 25, "National Day of Mourning for President John F. Kennedy"), + 1965: (DEC, 24, name_christmas_eve), + 1968: ( + (APR, 9, "National Day of Mourning for Martin Luther King Jr."), + (JUL, 5, "Day after Independence Day"), + ), + 1969: ( + (FEB, 10, "Heavy Snow"), + (MAR, 31, "National Day of Mourning for former President Dwight D. Eisenhower"), + (JUL, 21, "National Participation in Lunar Exploration"), + ), + 1972: (DEC, 28, "National Day of Mourning for former President Harry S. Truman"), + 1973: (JAN, 25, "National Day of Mourning for former President Lyndon B. Johnson"), + 1977: (JUL, 14, "Blackout in New York City"), + 1985: (SEP, 27, "Hurricane Gloria"), + 1994: (APR, 27, "National Day of Mourning for former President Richard M. Nixon"), + 2001: ( + (SEP, 11, name_sept11_attacks), + (SEP, 12, name_sept11_attacks), + (SEP, 13, name_sept11_attacks), + (SEP, 14, name_sept11_attacks), + ), + 2004: (JUN, 11, "National Day of Mourning for former President Ronald Reagan"), + 2007: (JAN, 2, "National Day of Mourning for former President Gerald R. Ford"), + 2012: ( + (OCT, 29, name_hurricane_sandy), + (OCT, 30, name_hurricane_sandy), + ), + 2018: (DEC, 5, "National Day of Mourning for former President George H. W. Bush"), + 2025: (JAN, 9, "National Day of Mourning for former President Jimmy Carter"), + } diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__init__.py b/.venv/lib/python3.12/site-packages/holidays/groups/__init__.py new file mode 100644 index 00000000..3ebb83b2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/__init__.py @@ -0,0 +1,28 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +# ruff: noqa: F401 + +from holidays.groups.balinese_saka import BalineseSakaCalendarHolidays +from holidays.groups.buddhist import BuddhistCalendarHolidays +from holidays.groups.chinese import ChineseCalendarHolidays +from holidays.groups.christian import ChristianHolidays +from holidays.groups.custom import StaticHolidays +from holidays.groups.eastern import EasternCalendarHolidays +from holidays.groups.hebrew import HebrewCalendarHolidays +from holidays.groups.hindu import HinduCalendarHolidays +from holidays.groups.international import InternationalHolidays +from holidays.groups.islamic import IslamicHolidays +from holidays.groups.mongolian import MongolianCalendarHolidays +from holidays.groups.persian import PersianCalendarHolidays +from holidays.groups.sinhala import SinhalaCalendarHolidays +from holidays.groups.thai import ThaiCalendarHolidays diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..348c35a5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/balinese_saka.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/balinese_saka.cpython-312.pyc new file mode 100644 index 00000000..1da451ae Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/balinese_saka.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/buddhist.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/buddhist.cpython-312.pyc new file mode 100644 index 00000000..f69b7de1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/buddhist.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/chinese.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/chinese.cpython-312.pyc new file mode 100644 index 00000000..a4b69c2e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/chinese.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/christian.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/christian.cpython-312.pyc new file mode 100644 index 00000000..1224ca3d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/christian.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/custom.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/custom.cpython-312.pyc new file mode 100644 index 00000000..c67a8765 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/custom.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/eastern.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/eastern.cpython-312.pyc new file mode 100644 index 00000000..2ff89eab Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/eastern.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/hebrew.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/hebrew.cpython-312.pyc new file mode 100644 index 00000000..9c79dbc4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/hebrew.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/hindu.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/hindu.cpython-312.pyc new file mode 100644 index 00000000..a91ac692 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/hindu.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/international.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/international.cpython-312.pyc new file mode 100644 index 00000000..09d275b6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/international.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/islamic.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/islamic.cpython-312.pyc new file mode 100644 index 00000000..d8a213ac Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/islamic.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/mongolian.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/mongolian.cpython-312.pyc new file mode 100644 index 00000000..01341246 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/mongolian.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/persian.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/persian.cpython-312.pyc new file mode 100644 index 00000000..6614409c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/persian.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/sinhala.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/sinhala.cpython-312.pyc new file mode 100644 index 00000000..cd0f9a2d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/sinhala.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/thai.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/thai.cpython-312.pyc new file mode 100644 index 00000000..4d67d091 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/groups/__pycache__/thai.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/balinese_saka.py b/.venv/lib/python3.12/site-packages/holidays/groups/balinese_saka.py new file mode 100644 index 00000000..ea865f1b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/balinese_saka.py @@ -0,0 +1,45 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars import _BalineseSakaLunar + + +class BalineseSakaCalendarHolidays: + """ + Balinese Saka lunar calendar holidays. + """ + + def __init__(self) -> None: + self._balinese_saka_calendar = _BalineseSakaLunar() + + def _add_balinese_saka_calendar_holiday(self, name: str, dt: Optional[date]) -> Optional[date]: + """ + Add Balinese Saka calendar holiday. + """ + if dt is None: + return None + return self._add_holiday(name, dt) + + def _add_nyepi(self, name) -> Optional[date]: + """ + Add Nyepi (Day following the 9th of Dark Moon (Tilem)). + + Nyepi is a Balinese "Day of Silence" that is commemorated every + Isakawarsa (Saka new year) according to the Balinese calendar. + https://en.wikipedia.org/wiki/Nyepi + """ + return self._add_balinese_saka_calendar_holiday( + name, self._balinese_saka_calendar.nyepi_date(self._year) + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/buddhist.py b/.venv/lib/python3.12/site-packages/holidays/groups/buddhist.py new file mode 100644 index 00000000..868ba1bf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/buddhist.py @@ -0,0 +1,63 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars import _BuddhistLunisolar +from holidays.groups.eastern import EasternCalendarHolidays + + +class BuddhistCalendarHolidays(EasternCalendarHolidays): + """ + Buddhist lunisolar calendar holidays. + """ + + def __init__(self, cls=None, show_estimated=False) -> None: + self._buddhist_calendar = cls() if cls else _BuddhistLunisolar() + self._buddhist_calendar_show_estimated = show_estimated + + def _add_buddhist_calendar_holiday( + self, name: str, dt_estimated: tuple[Optional[date], bool] + ) -> Optional[date]: + """ + Add Buddhist calendar holiday. + + Adds customizable estimation label to holiday name if holiday date + is an estimation. + """ + return self._add_eastern_calendar_holiday( + name, dt_estimated, self._buddhist_calendar_show_estimated + ) + + def _add_vesak(self, name) -> Optional[date]: + """ + Add Vesak (15th day of the 4th lunar month). + + Vesak for Thailand, Laos, Singapore and Indonesia. + https://en.wikipedia.org/wiki/Vesak + """ + return self._add_buddhist_calendar_holiday( + name, self._buddhist_calendar.vesak_date(self._year) + ) + + def _add_vesak_may(self, name) -> Optional[date]: + """ + Add Vesak (on the day of the first full moon in May + in the Gregorian calendar). + + Vesak for Sri Lanka, Nepal, India, Bangladesh and Malaysia. + https://en.wikipedia.org/wiki/Vesak + """ + return self._add_buddhist_calendar_holiday( + name, self._buddhist_calendar.vesak_may_date(self._year) + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/chinese.py b/.venv/lib/python3.12/site-packages/holidays/groups/chinese.py new file mode 100644 index 00000000..8b830e71 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/chinese.py @@ -0,0 +1,277 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.chinese import _ChineseLunisolar, CHINESE_CALENDAR +from holidays.calendars.gregorian import APR, DEC +from holidays.groups.eastern import EasternCalendarHolidays + + +class ChineseCalendarHolidays(EasternCalendarHolidays): + """ + Chinese lunisolar calendar holidays. + """ + + def __init__(self, cls=None, show_estimated=False, calendar=CHINESE_CALENDAR) -> None: + self._chinese_calendar = ( + cls(calendar=calendar) if cls else _ChineseLunisolar(calendar=calendar) + ) + self._chinese_calendar_show_estimated = show_estimated + + @property + def _chinese_new_year(self): + """ + Return Chinese New Year date. + """ + return self._chinese_calendar.lunar_new_year_date(self._year)[0] + + @property + def _qingming_festival(self): + """ + Return Qingming Festival (15th day after the Spring Equinox) date. + """ + day = 5 + if (self._year % 4 < 1) or (self._year % 4 < 2 and self._year >= 2009): + day = 4 + return date(self._year, APR, day) + + @property + def _mid_autumn_festival(self): + """ + Return Mid Autumn Festival (15th day of the 8th lunar month) date. + """ + return self._chinese_calendar.mid_autumn_date(self._year)[0] + + @property + def _chinese_birthday_of_buddha(self): + """ + Return Add Birthday of the Buddha by Chinese lunar calendar (8th day of the + 4th lunar month). + """ + return self._chinese_calendar.buddha_birthday_date(self._year)[0] + + @property + def _dragon_boat_festival(self): + """ + Return Dragon Boat Festival (5th day of 5th lunar month) date. + """ + return self._chinese_calendar.dragon_boat_date(self._year)[0] + + @property + def _double_ninth_festival(self): + """ + Return Double Ninth Festival (9th day of 9th lunar month) date. + """ + return self._chinese_calendar.double_ninth_date(self._year)[0] + + @property + def _dongzhi_festival(self): + """ + Return Dongzhi Festival (Chinese Winter Solstice) date. + + This approximation is reliable for 1952-2099 years. + """ + # + if ( + (self._year % 4 == 0 and self._year >= 1988) + or (self._year % 4 == 1 and self._year >= 2021) + or (self._year % 4 == 2 and self._year >= 2058) + or (self._year % 4 == 3 and self._year >= 2091) + ): + day = 21 + else: + day = 22 + return date(self._year, DEC, day) + + def _add_chinese_calendar_holiday( + self, name: str, dt_estimated: tuple[Optional[date], bool], days_delta: int = 0 + ) -> Optional[date]: + """ + Add Chinese calendar holiday. + + Adds customizable estimation label to holiday name if holiday date + is an estimation. + """ + return self._add_eastern_calendar_holiday( + name, dt_estimated, self._chinese_calendar_show_estimated, days_delta + ) + + def _add_chinese_birthday_of_buddha(self, name) -> Optional[date]: + """ + Add Birthday of the Buddha by Chinese lunar calendar (8th day of the + 4th lunar month). + + Birthday of the Buddha is a Buddhist festival that is celebrated in + most of East Asia and South Asia commemorating the birth of Gautama + Buddha, who was the founder of Buddhism. + https://en.wikipedia.org/wiki/Buddha's_Birthday + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.buddha_birthday_date(self._year) + ) + + def _add_chinese_day_before_new_years_eve(self, name) -> Optional[date]: + """ + Add day before Chinese New Year's Eve (second to last day of 12th lunar month). + + Chinese New Year's Eve is the day before the Chinese New Year. + https://en.wikipedia.org/wiki/Chinese_New_Year's_Eve + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=-2 + ) + + def _add_chinese_new_years_eve(self, name) -> Optional[date]: + """ + Add Chinese New Year's Eve (last day of 12th lunar month). + + Chinese New Year's Eve is the day before the Chinese New Year. + https://en.wikipedia.org/wiki/Chinese_New_Year's_Eve + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=-1 + ) + + def _add_chinese_new_years_day(self, name) -> Optional[date]: + """ + Add Chinese New Year's Day (first day of the first lunar month). + + Chinese New Year is the festival that celebrates the beginning of + a new year on the traditional lunisolar and solar Chinese calendar. + https://en.wikipedia.org/wiki/Chinese_New_Year + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.lunar_new_year_date(self._year) + ) + + def _add_chinese_new_years_day_two(self, name) -> Optional[date]: + """ + Add Chinese New Year's Day Two. + + https://en.wikipedia.org/wiki/Chinese_New_Year + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=+1 + ) + + def _add_chinese_new_years_day_three(self, name) -> Optional[date]: + """ + Add Chinese New Year's Day Three. + + https://en.wikipedia.org/wiki/Chinese_New_Year + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=+2 + ) + + def _add_chinese_new_years_day_four(self, name) -> Optional[date]: + """ + Add Chinese New Year's Day Four. + + https://en.wikipedia.org/wiki/Chinese_New_Year + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=+3 + ) + + def _add_chinese_new_years_day_five(self, name) -> Optional[date]: + """ + Add Chinese New Year's Day Five. + + https://en.wikipedia.org/wiki/Chinese_New_Year + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=+4 + ) + + def _add_dongzhi_festival(self, name) -> Optional[date]: + """ + Add Dongzhi Festival (Chinese Winter Solstice). + + The Dongzhi Festival or Winter Solstice Festival is a traditional + Chinese festival celebrated during the Dongzhi solar term + (winter solstice), which falls between December 21 and 23. + https://en.wikipedia.org/wiki/Dongzhi_Festival + """ + return self._add_holiday(name, self._dongzhi_festival) + + def _add_qingming_festival(self, name) -> date: + """ + Add Qingming Festival (15th day after the Spring Equinox). + + The Qingming festival or Ching Ming Festival, also known as + Tomb-Sweeping Day in English, is a traditional Chinese festival. + https://en.wikipedia.org/wiki/Qingming_Festival + """ + return self._add_holiday(name, self._qingming_festival) + + def _add_double_ninth_festival(self, name) -> Optional[date]: + """ + Add Double Ninth Festival (9th day of 9th lunar month). + + The Double Ninth Festival (Chongyang Festival in Mainland China + and Taiwan or Chung Yeung Festival in Hong Kong and Macau). + https://en.wikipedia.org/wiki/Double_Ninth_Festival + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.double_ninth_date(self._year) + ) + + def _add_dragon_boat_festival(self, name) -> Optional[date]: + """ + Add Dragon Boat Festival (5th day of 5th lunar month). + + The Dragon Boat Festival is a traditional Chinese holiday which occurs + on the fifth day of the fifth month of the Chinese calendar. + https://en.wikipedia.org/wiki/Dragon_Boat_Festival + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.dragon_boat_date(self._year) + ) + + def _add_hung_kings_day(self, name) -> Optional[date]: + """ + Add Hùng Kings' Temple Festival (10th day of the 3rd lunar month). + + Vietnamese festival held annually from the 8th to the 11th day of the + 3rd lunar month in honour of the Hùng Kings. + https://en.wikipedia.org/wiki/Hùng_Kings'_Festival + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.hung_kings_date(self._year) + ) + + def _add_mid_autumn_festival(self, name) -> Optional[date]: + """ + Add Mid Autumn Festival (15th day of the 8th lunar month). + + The Mid-Autumn Festival, also known as the Moon Festival or + Mooncake Festival. + https://en.wikipedia.org/wiki/Mid-Autumn_Festival + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.mid_autumn_date(self._year) + ) + + def _add_mid_autumn_festival_day_two(self, name) -> Optional[date]: + """ + Add Mid Autumn Festival Day Two (16th day of the 8th lunar month). + + The Mid-Autumn Festival, also known as the Moon Festival or + Mooncake Festival. + https://en.wikipedia.org/wiki/Mid-Autumn_Festival + """ + return self._add_chinese_calendar_holiday( + name, self._chinese_calendar.mid_autumn_date(self._year), days_delta=+1 + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/christian.py b/.venv/lib/python3.12/site-packages/holidays/groups/christian.py new file mode 100644 index 00000000..e091c2f3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/christian.py @@ -0,0 +1,463 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date + +from dateutil.easter import EASTER_ORTHODOX, EASTER_WESTERN, easter + +from holidays.calendars.gregorian import GREGORIAN_CALENDAR, JAN, DEC, _timedelta +from holidays.calendars.julian import JULIAN_CALENDAR +from holidays.calendars.julian_revised import JULIAN_REVISED_CALENDAR + + +class ChristianHolidays: + """ + Christian holidays. + """ + + def __init__(self, calendar=GREGORIAN_CALENDAR) -> None: + self.__verify_calendar(calendar) + self.__calendar = calendar + + def __get_christmas_day(self, calendar=None): + """ + Get Christmas Day date. + """ + calendar = calendar or self.__calendar + self.__verify_calendar(calendar) + + return ( + date(self._year, JAN, 7) + if self.__is_julian_calendar(calendar) + else date(self._year, DEC, 25) + ) + + def __get_easter_sunday(self, calendar=None): + """ + Get Easter Sunday date. + """ + calendar = calendar or self.__calendar + self.__verify_calendar(calendar) + + return easter( + self._year, + method=EASTER_WESTERN if self.__is_gregorian_calendar(calendar) else EASTER_ORTHODOX, + ) + + @staticmethod + def __is_gregorian_calendar(calendar): + """ + Return True if `calendar` is Gregorian calendar. + Return False otherwise. + """ + return calendar == GREGORIAN_CALENDAR + + @staticmethod + def __is_julian_calendar(calendar): + """ + Return True if `calendar` is Julian calendar. + Return False otherwise. + """ + return calendar == JULIAN_CALENDAR + + @staticmethod + def __verify_calendar(calendar): + """ + Verify calendar type. + """ + if calendar not in {GREGORIAN_CALENDAR, JULIAN_CALENDAR, JULIAN_REVISED_CALENDAR}: + raise ValueError( + f"Unknown calendar name: {calendar}. " + f"Use `{GREGORIAN_CALENDAR}`, `{JULIAN_CALENDAR}` or `{JULIAN_REVISED_CALENDAR}`." + ) + + @property + def _christmas_day(self): + """ + Return Christmas Day date. + """ + return self.__get_christmas_day() + + @property + def _easter_sunday(self): + """ + Return Easter Sunday date. + """ + return self.__get_easter_sunday() + + def _add_all_saints_day(self, name) -> date: + """ + Add All Saints' Day (November 1st). + + Also known as All Hallows' Day, the Feast of All Saints, + the Feast of All Hallows, the Solemnity of All Saints, and Hallowmas. + https://en.wikipedia.org/wiki/All_Saints'_Day + """ + return self._add_holiday_nov_1(name) + + def _add_all_souls_day(self, name) -> date: + """ + Add All Souls' Day (November 2nd). + + All Souls' Day is a day of prayer and remembrance for the faithful + departed, observed by certain Christian denominations on 2 November. + In Belarussian tradition it is called Dziady. + https://en.wikipedia.org/wiki/All_Souls'_Day + https://en.wikipedia.org/wiki/Dziady + """ + return self._add_holiday_nov_2(name) + + def _add_ascension_thursday(self, name, calendar=None) -> date: + """ + Add Ascension Thursday (39 days after the Easter Sunday). + + The Solemnity of the Ascension of Jesus Christ, also called Ascension + Day, or sometimes Holy Thursday. + https://en.wikipedia.org/wiki/Feast_of_the_Ascension + """ + return self._add_holiday(name, _timedelta(self.__get_easter_sunday(calendar), +39)) + + def _add_ash_monday(self, name) -> date: + """ + Add Ash Monday (48 days before Easter Sunday). + + The Clean Monday, also known as Pure Monday, Monday of Lent + or Green Monday. The first day of Great Lent. + https://en.wikipedia.org/wiki/Clean_Monday + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, -48)) + + def _add_ash_wednesday(self, name) -> date: + """ + Add Ash Wednesday (46 days before Easter Sunday). + + A holy day of prayer and fasting. It marks the beginning of Lent. + https://en.wikipedia.org/wiki/Ash_Wednesday + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, -46)) + + def _add_assumption_of_mary_day(self, name, calendar=None) -> date: + """ + Add Assumption Of Mary (August 15th). + + The Feast of the Assumption of Mary, or simply The Assumption marks the + occasion of the Virgin Mary's bodily ascent to heaven at the end of + her life. + https://en.wikipedia.org/wiki/Assumption_of_Mary + """ + calendar = calendar or self.__calendar + self.__verify_calendar(calendar) + + return ( + self._add_holiday_aug_28(name) + if self.__is_julian_calendar(calendar) + else self._add_holiday_aug_15(name) + ) + + def _add_candlemas(self, name) -> date: + """ + Add Candlemas (February 2nd). + + Also known as the Feast of the Presentation of Jesus Christ, + the Feast of the Purification of the Blessed Virgin Mary, or the Feast + of the Holy Encounter, is a Christian holiday commemorating the + presentation of Jesus at the Temple. + https://en.wikipedia.org/wiki/Candlemas + """ + return self._add_holiday_feb_2(name) + + def _add_carnival_sunday(self, name) -> date: + """ + Add Carnival Sunday (49 days before Easter Sunday). + + Carnival is a Catholic Christian festive season that occurs before + the liturgical season of Lent. + https://en.wikipedia.org/wiki/Carnival + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, -49)) + + def _add_carnival_monday(self, name) -> date: + """ + Add Carnival Monday (48 days before Easter Sunday). + + Carnival is a Catholic Christian festive season that occurs before + the liturgical season of Lent. + https://en.wikipedia.org/wiki/Carnival + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, -48)) + + def _add_carnival_tuesday(self, name) -> date: + """ + Add Carnival Tuesday (47 days before Easter Sunday). + + Carnival is a Catholic Christian festive season that occurs before + the liturgical season of Lent. + https://en.wikipedia.org/wiki/Carnival + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, -47)) + + def _add_christmas_day(self, name, calendar=None) -> date: + """ + Add Christmas Day. + + Christmas is an annual festival commemorating the birth of + Jesus Christ. + https://en.wikipedia.org/wiki/Christmas + """ + return self._add_holiday(name, self.__get_christmas_day(calendar)) + + def _add_christmas_day_two(self, name, calendar=None) -> date: + """ + Add Christmas Day 2. + + A holiday celebrated after Christmas Day, also known as Boxing Day. + https://en.wikipedia.org/wiki/Boxing_Day + https://en.wikipedia.org/wiki/Christmas + """ + return self._add_holiday(name, _timedelta(self.__get_christmas_day(calendar), +1)) + + def _add_christmas_day_three(self, name, calendar=None) -> date: + """ + Add Christmas Day 3. + + A holiday celebrated 2 days after Christmas Day (in some countries). + https://en.wikipedia.org/wiki/Christmas + """ + return self._add_holiday(name, _timedelta(self.__get_christmas_day(calendar), +2)) + + def _add_christmas_eve(self, name, calendar=None) -> date: + """ + Add Christmas Eve. + + Christmas Eve is the evening or entire day before Christmas Day, + the festival commemorating the birth of Jesus Christ. + https://en.wikipedia.org/wiki/Christmas_Eve + """ + return self._add_holiday(name, _timedelta(self.__get_christmas_day(calendar), -1)) + + def _add_corpus_christi_day(self, name) -> date: + """ + Add Feast Of Corpus Christi (60 days after Easter Sunday). + + The Feast of Corpus Christi, also known as the Solemnity of the Most + Holy Body and Blood of Christ, is a Christian liturgical solemnity + celebrating the Real Presence of the Body and Blood, Soul and Divinity + of Jesus Christ in the elements of the Eucharist. + https://en.wikipedia.org/wiki/Feast_of_Corpus_Christi + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, +60)) + + def _add_easter_monday(self, name, calendar=None) -> date: + """ + Add Easter Monday (1 day after Easter Sunday). + + Easter Monday refers to the day after Easter Sunday in either the + Eastern or Western Christian traditions. It is a public holiday in + some countries. + https://en.wikipedia.org/wiki/Easter_Monday + """ + return self._add_holiday(name, _timedelta(self.__get_easter_sunday(calendar), +1)) + + def _add_easter_sunday(self, name, calendar=None) -> date: + """ + Add Easter Sunday. + + Easter, also called Pascha or Resurrection Sunday is a Christian + festival and cultural holiday commemorating the resurrection of Jesus + from the dead. + https://en.wikipedia.org/wiki/Easter + """ + return self._add_holiday(name, self.__get_easter_sunday(calendar)) + + def _add_easter_tuesday(self, name, calendar=None) -> date: + """ + Add Easter Tuesday (2 day after Easter Sunday). + + Easter Tuesday is the third day of Eastertide and is a holiday in some areas. + https://en.wikipedia.org/wiki/Easter_Tuesday + """ + return self._add_holiday(name, _timedelta(self.__get_easter_sunday(calendar), +2)) + + def _add_epiphany_day(self, name, calendar=None) -> date: + """ + Add Epiphany Day. + + Epiphany, also known as Theophany in Eastern Christian traditions, + is a Christian feast day that celebrates the revelation of God + incarnate as Jesus Christ. + https://en.wikipedia.org/wiki/Epiphany_(holiday) + """ + calendar = calendar or self.__calendar + self.__verify_calendar(calendar) + + return ( + self._add_holiday_jan_19(name) + if self.__is_julian_calendar(calendar) + else self._add_holiday_jan_6(name) + ) + + def _add_good_friday(self, name, calendar=None) -> date: + """ + Add Good Friday (2 days before Easter Sunday). + + Good Friday is a Christian holiday commemorating the crucifixion of + Jesus and his death at Calvary. It is also known as Holy Friday, + Great Friday, Great and Holy Friday. + https://en.wikipedia.org/wiki/Good_Friday + """ + return self._add_holiday(name, _timedelta(self.__get_easter_sunday(calendar), -2)) + + def _add_holy_saturday(self, name, calendar=None) -> date: + """ + Add Holy Saturday (1 day before Easter Sunday). + + Great and Holy Saturday is a day between Good Friday and Easter Sunday. + https://en.wikipedia.org/wiki/Holy_Saturday + """ + return self._add_holiday(name, _timedelta(self.__get_easter_sunday(calendar), -1)) + + def _add_holy_thursday(self, name, calendar=None) -> date: + """ + Add Holy Thursday (3 days before Easter Sunday). + + Holy Thursday or Maundy Thursday is the day during Holy Week that + commemorates the Washing of the Feet (Maundy) and Last Supper of + Jesus Christ with the Apostles, as described in the canonical gospels. + https://en.wikipedia.org/wiki/Maundy_Thursday + """ + return self._add_holiday(name, _timedelta(self.__get_easter_sunday(calendar), -3)) + + def _add_immaculate_conception_day(self, name) -> date: + """ + Add Immaculate Conception Day (December 8th). + + https://en.wikipedia.org/wiki/Immaculate_Conception + """ + return self._add_holiday_dec_8(name) + + def _add_nativity_of_mary_day(self, name) -> date: + """ + Add Nativity Of Mary Day (September 8th). + + The Nativity of the Blessed Virgin Mary, the Nativity of Mary, + the Marymas or the Birth of the Virgin Mary, refers to a Christian + feast day celebrating the birth of Mary, mother of Jesus. + https://en.wikipedia.org/wiki/Nativity_of_Mary + """ + return self._add_holiday_sep_8(name) + + def _add_palm_sunday(self, name, calendar=None) -> date: + """ + Add Palm Sunday (7 days before Easter Sunday). + + Palm Sunday is a Christian moveable feast that falls on the Sunday + before Easter. The feast commemorates Christ's triumphal entry into + Jerusalem, an event mentioned in each of the four canonical Gospels. + Palm Sunday marks the first day of Holy Week. + https://en.wikipedia.org/wiki/Palm_Sunday + """ + return self._add_holiday(name, _timedelta(self.__get_easter_sunday(calendar), -7)) + + def _add_rejoicing_day(self, name) -> date: + """ + Add Day Of Rejoicing (9 days after Easter Sunday). + + Add Day Of Rejoicing ("Radonitsa"), in the Russian Orthodox Church is + a commemoration of the departed observed on the second Tuesday of + Pascha (Easter). In Ukrainian tradition it is called Provody. + https://en.wikipedia.org/wiki/Radonitsa + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, +9)) + + def _add_saint_georges_day(self, name) -> date: + """ + Add Saint George's Day (April 23th). + + Saint George's Day is celebrated on 23 April, the traditionally + accepted date of the saint's death. + https://en.wikipedia.org/wiki/Saint_George's_Day + """ + return self._add_holiday_apr_23(name) + + def _add_saint_james_day(self, name) -> date: + """ + Add Saint James' Day (July 25th). + + James the Great was one of the Twelve Apostles of Jesus. + https://en.wikipedia.org/wiki/James_the_Great#Feast + """ + return self._add_holiday_jul_25(name) + + def _add_saint_johns_day(self, name) -> date: + """ + Add Saint John's Day (June 24th). + + The Nativity of John the Baptist is a Christian feast day celebrating + the birth of John the Baptist. + https://en.wikipedia.org/wiki/Nativity_of_John_the_Baptist + """ + return self._add_holiday_jun_24(name) + + def _add_saint_josephs_day(self, name) -> date: + """ + Add Saint Joseph's Day (March 19th). + + Saint Joseph's Day, also called the Feast of Saint Joseph or the + Solemnity of Saint Joseph, is in Western Christianity the principal + feast day of Saint Joseph, husband of the Virgin Mary and legal father + of Jesus Christ. + https://en.wikipedia.org/wiki/Saint_Joseph's_Day + """ + return self._add_holiday_mar_19(name) + + def _add_saints_peter_and_paul_day(self, name) -> date: + """ + Add Feast of Saints Peter and Paul (June 29th). + + A liturgical feast in honor of the martyrdom in Rome of the apostles + Saint Peter and Saint Paul, which is observed on 29 June. + https://en.wikipedia.org/wiki/Feast_of_Saints_Peter_and_Paul + """ + return self._add_holiday_jun_29(name) + + def _add_whit_monday(self, name) -> date: + """ + Add Whit Monday (50 days after Easter Sunday). + + Whit Monday or Pentecost Monday, also known as Monday of the + Holy Spirit, is the holiday celebrated the day after Pentecost. + https://en.wikipedia.org/wiki/Pentecost + https://en.wikipedia.org/wiki/Whit_Monday + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, +50)) + + def _add_whit_sunday(self, name, calendar=None) -> date: + """ + Add Whit Sunday (49 days after Easter Sunday). + + Whit Sunday, also called Pentecost, is a holiday which commemorates + the descent of the Holy Spirit upon the Apostles and other followers + of Jesus Christ while they were in Jerusalem celebrating the + Feast of Weeks. + https://en.wikipedia.org/wiki/Pentecost + """ + return self._add_holiday(name, _timedelta(self.__get_easter_sunday(calendar), +49)) + + def _add_trinity_sunday(self, name) -> date: + """ + Add Trinity Sunday (56 days after Easter Sunday). + + Trinity Sunday, also called Solemnity of Holy Trinity, is the first Sunday + after Pentecost in the Western Christian liturgical calendar, and the Sunday + of Pentecost in Eastern Christianity. + """ + return self._add_holiday(name, _timedelta(self._easter_sunday, +56)) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/custom.py b/.venv/lib/python3.12/site-packages/holidays/groups/custom.py new file mode 100644 index 00000000..bf264645 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/custom.py @@ -0,0 +1,47 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date + +from holidays.helpers import _normalize_tuple + + +class StaticHolidays: + """Helper class for special and substituted holidays support. + + Populates special and substituted holidays related data from + an external class. + """ + + def __init__(self, cls) -> None: + for attribute_name in cls.__dict__.keys(): + # Special holidays. + if attribute_name.startswith("special_") and ( + value := getattr(cls, attribute_name, None) + ): + setattr(self, attribute_name, value) + self.has_special_holidays = True + + # Substituted holidays. + elif attribute_name.startswith("substituted_") and ( + value := getattr(cls, attribute_name, None) + ): + setattr(self, attribute_name, value) + self.has_substituted_holidays = True + + # Populate substituted holidays from adjacent years. + self.weekend_workdays = set() + for special_public_holidays in getattr(self, "special_public_holidays", {}).values(): + for special_public_holiday in _normalize_tuple(special_public_holidays): + if len(special_public_holiday) == 5: # The fifth element is the year. + _, _, from_month, from_day, from_year = special_public_holiday + self.weekend_workdays.add(date(from_year, from_month, from_day)) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/eastern.py b/.venv/lib/python3.12/site-packages/holidays/groups/eastern.py new file mode 100644 index 00000000..a177a865 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/eastern.py @@ -0,0 +1,51 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import _timedelta + + +class EasternCalendarHolidays: + """ + Eastern calendar holidays base class. + """ + + def _add_eastern_calendar_holiday( + self, + name: str, + dt_estimated: tuple[Optional[date], bool], + show_estimated: bool = True, + days_delta: int = 0, + ) -> Optional[date]: + """ + Add Eastern (Buddhist, Chinese, Hindu, Islamic, Mongolian) calendar holiday. + + Adds customizable estimation label to holiday name if holiday date is an estimation. + """ + estimated_label = getattr(self, "estimated_label", "%s (estimated)") + dt, is_estimated = dt_estimated + + if days_delta and dt: + dt = _timedelta(dt, days_delta) + + return ( + self._add_holiday( + self.tr(estimated_label) % self.tr(name) + if is_estimated and show_estimated + else name, + dt, + ) + if dt + else None + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/hebrew.py b/.venv/lib/python3.12/site-packages/holidays/groups/hebrew.py new file mode 100644 index 00000000..bd7b68ae --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/hebrew.py @@ -0,0 +1,151 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from collections.abc import Iterable +from datetime import date +from typing import Optional, Union + +from holidays.calendars import _HebrewLunisolar +from holidays.calendars.gregorian import _timedelta + + +class HebrewCalendarHolidays: + """ + Hebrew lunisolar calendar holidays. + """ + + def __init__(self) -> None: + self._hebrew_calendar = _HebrewLunisolar() + + def _add_hebrew_calendar_holiday( + self, name: str, holiday_date: date, days_delta: Union[int, Iterable[int]] = 0 + ) -> set[date]: + added_dates = set() + for delta in (days_delta,) if isinstance(days_delta, int) else days_delta: + if dt := self._add_holiday(name, _timedelta(holiday_date, delta)): + added_dates.add(dt) + return added_dates + + def _add_hanukkah( + self, name: str, days_delta: Union[int, Iterable[int]] = 0 + ) -> set[Optional[date]]: + """ + Add Hanukkah. + In some Gregorian years, there may be two Hanukkah dates. + + Hanukkah is a Jewish festival commemorating the recovery of Jerusalem + and subsequent rededication of the Second Temple. + https://en.wikipedia.org/wiki/Hanukkah + """ + dts = self._hebrew_calendar.hanukkah_date(self._year) + for dt in dts: + self._add_hebrew_calendar_holiday(name, dt, days_delta) # type: ignore[arg-type] + return dts + + def _add_lag_baomer(self, name: str, days_delta: Union[int, Iterable[int]] = 0) -> set[date]: + """ + Add Lag BaOmer. + + Lag BaOmer, also Lag B'Omer or Lag LaOmer, is a Jewish religious holiday celebrated + on the 33rd day of the Counting of the Omer, which occurs on the 18th day of + the Hebrew month of Iyar. + https://en.wikipedia.org/wiki/Lag_BaOmer + """ + return self._add_hebrew_calendar_holiday( + name, + self._hebrew_calendar.lag_baomer_date(self._year), # type: ignore[arg-type] + days_delta, + ) + + def _add_passover(self, name: str, days_delta: Union[int, Iterable[int]] = 0) -> set[date]: + """ + Add Passover. + + Passover, also called Pesach, is a major Jewish holiday and one of the Three Pilgrimage + Festivals. It celebrates the Exodus of the Israelites from slavery in Egypt. + https://en.wikipedia.org/wiki/Passover + """ + return self._add_hebrew_calendar_holiday( + name, + self._hebrew_calendar.passover_date(self._year), # type: ignore[arg-type] + days_delta, + ) + + def _add_purim(self, name: str) -> set[date]: + """ + Add Purim. + + Purim is a Jewish holiday that commemorates the saving of the Jewish people + from annihilation at the hands of an official of the Achaemenid Empire named Haman, + as it is recounted in the Book of Esther. + https://en.wikipedia.org/wiki/Purim + """ + return self._add_hebrew_calendar_holiday( + name, + self._hebrew_calendar.purim_date(self._year), # type: ignore[arg-type] + ) + + def _add_rosh_hashanah( + self, name: str, days_delta: Union[int, Iterable[int]] = 0 + ) -> set[date]: + """ + Add Rosh Hashanah. + + Rosh Hashanah is the New Year in Judaism. + https://en.wikipedia.org/wiki/Rosh_Hashanah + """ + return self._add_hebrew_calendar_holiday( + name, + self._hebrew_calendar.rosh_hashanah_date(self._year), # type: ignore[arg-type] + days_delta, + ) + + def _add_shavuot(self, name: str) -> set[date]: + """ + Add Shavuot. + + Shavuot, or Shvues, is a Jewish holiday, one of the biblically ordained + Three Pilgrimage Festivals. It occurs on the sixth day of the Hebrew month of Sivan. + https://en.wikipedia.org/wiki/Shavuot + """ + return self._add_hebrew_calendar_holiday( + name, + self._hebrew_calendar.shavuot_date(self._year), # type: ignore[arg-type] + ) + + def _add_sukkot(self, name: str, days_delta: Union[int, Iterable[int]] = 0) -> set[date]: + """ + Add Sukkot. + + Sukkot, also known as the Feast of Tabernacles or Feast of Booths, is a Torah-commanded + holiday celebrated for seven days, beginning on the 15th day of the month of Tishrei. + https://en.wikipedia.org/wiki/Sukkot + """ + return self._add_hebrew_calendar_holiday( + name, + self._hebrew_calendar.sukkot_date(self._year), # type: ignore[arg-type] + days_delta, + ) + + def _add_yom_kippur(self, name: str, days_delta: Union[int, Iterable[int]] = 0) -> set[date]: + """ + Add Yom Kippur. + + Yom Kippur (Day of Atonement) is the holiest day of the year in Judaism. + It occurs annually on the 10th of Tishrei. + https://en.wikipedia.org/wiki/Yom_Kippur + """ + return self._add_hebrew_calendar_holiday( + name, + self._hebrew_calendar.yom_kippur_date(self._year), # type: ignore[arg-type] + days_delta, + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/hindu.py b/.venv/lib/python3.12/site-packages/holidays/groups/hindu.py new file mode 100644 index 00000000..f158dcd8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/hindu.py @@ -0,0 +1,481 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from collections.abc import Iterable +from datetime import date +from typing import Optional + +from holidays.calendars import _HinduLunisolar +from holidays.groups.eastern import EasternCalendarHolidays + + +class HinduCalendarHolidays(EasternCalendarHolidays): + """ + Hindu lunisolar calendar holidays. + """ + + def __init__(self, cls=None, show_estimated=False) -> None: + self._hindu_calendar = cls() if cls else _HinduLunisolar() + self._hindu_calendar_show_estimated = show_estimated + + def _add_hindu_calendar_holiday( + self, name: str, dt_estimated: tuple[Optional[date], bool], days_delta: int = 0 + ) -> Optional[date]: + """ + Add Hindu calendar holiday. + + Adds customizable estimation label to holiday name if holiday date + is an estimation. + """ + + return self._add_eastern_calendar_holiday( + name, dt_estimated, self._hindu_calendar_show_estimated, days_delta + ) + + def _add_hindu_calendar_holiday_set( + self, name: str, dts_estimated: Iterable[tuple[date, bool]], days_delta: int = 0 + ) -> set[date]: + """ + Add Hindu calendar holidays. + + Adds customizable estimation label to holiday name if holiday date + is an estimation. + """ + added_dates = set() + for dt_estimated in dts_estimated: + if dt := self._add_eastern_calendar_holiday( + name, dt_estimated, self._hindu_calendar_show_estimated, days_delta=days_delta + ): + added_dates.add(dt) + + return added_dates + + def _add_bhai_dooj(self, name) -> Optional[date]: + """ + Add Bhai Dooj. + + Bhai Dooj, also known as Bhai Tika or Bhaiya Dooj, is a Hindu festival celebrating the bond + between brothers and sisters. It is observed two days after Diwali on the second lunar day + of the Shukla Paksha in the Hindu month of Kartika. + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.govardhan_puja_date(self._year), days_delta=+1 + ) + + def _add_buddha_purnima(self, name) -> Optional[date]: + """ + Add Buddha Purnima. + + Buddha Purnima, also known as Vesak, commemorates the birth, enlightenment, + and passing of Gautama Buddha. It falls on the full moon day of the + Hindu month of Vaisakha (April-May). + https://en.wikipedia.org/wiki/Vesak + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.buddha_purnima_date(self._year) + ) + + def _add_chhath_puja(self, name) -> Optional[date]: + """ + Add Chhath Puja. + + Chhath Puja is a Hindu festival dedicated to the Sun God (Surya). + It is observed six days after Diwali in the month of Kartika (October-November). + https://en.wikipedia.org/wiki/Chhath + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.chhath_puja_date(self._year) + ) + + def _add_diwali(self, name) -> Optional[date]: + """ + Add Diwali Festival. + + Diwali (Deepavali, Festival of Lights) is one of the most important + festivals in Indian religions. It is celebrated during the Hindu + lunisolar months of Ashvin and Kartika (between mid-October and + mid-November). + https://en.wikipedia.org/wiki/Diwali + """ + return self._add_hindu_calendar_holiday(name, self._hindu_calendar.diwali_date(self._year)) + + def _add_diwali_india(self, name) -> Optional[date]: + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.diwali_india_date(self._year) + ) + + def _add_dussehra(self, name) -> Optional[date]: + """ + Add Dussehra Festival. + + Dussehra (Vijayadashami) is a major Hindu festival that marks the end + of Navratri. It is celebrated on the 10th day of the Hindu lunisolar + month of Ashvin (September-October). + https://en.wikipedia.org/wiki/Vijayadashami + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.dussehra_date(self._year) + ) + + def _add_ganesh_chaturthi(self, name) -> Optional[date]: + """ + Add Ganesh Chaturthi. + + Ganesh Chaturthi is a Hindu festival celebrating the birth of Lord Ganesha. + It falls on the fourth day of the Hindu month of Bhadrapada (August/September). + https://en.wikipedia.org/wiki/Ganesh_Chaturthi + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.ganesh_chaturthi_date(self._year) + ) + + def _add_gau_krida(self, name) -> Optional[date]: + """ + Add Gau Krida. + + Gau Krida, is celebrated the day after Diwali to honor cows. + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.govardhan_puja_date(self._year), days_delta=-1 + ) + + def _add_govardhan_puja(self, name) -> Optional[date]: + """ + Add Govardhan Puja. + + Govardhan Puja, also known as Annakut, is celebrated after Diwali + to honor Lord Krishna. It falls on the first lunar day of the Hindu month of Kartika. + https://en.wikipedia.org/wiki/Govardhan_Puja + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.govardhan_puja_date(self._year) + ) + + def _add_gudi_padwa(self, name) -> Optional[date]: + """ + Add Gudi Padwa. + + Gudi Padwa is the traditional New Year festival for Maharashtrians. + It falls on the first day of Chaitra (March-April). + https://en.wikipedia.org/wiki/Gudi_Padwa + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.gudi_padwa_date(self._year) + ) + + def _add_guru_gobind_singh_jayanti(self, name) -> set[date]: + """ + Add Guru Gobind Singh Jayanti. + + Guru Gobind Singh Jayanti commemorates the birth anniversary of + Guru Gobind Singh, the tenth Sikh Guru. It follows the Nanakshahi calendar. + https://en.wikipedia.org/wiki/Guru_Gobind_Singh + """ + return self._add_hindu_calendar_holiday_set( + name, self._hindu_calendar.guru_gobind_singh_jayanti_date(self._year) + ) + + def _add_guru_nanak_jayanti(self, name) -> Optional[date]: + """ + Add Guru Nanak Jayanti. + + Guru Nanak Jayanti celebrates the birth anniversary of Guru Nanak, + the founder of Sikhism. It is observed on the full moon day of + Kartik (October-November). + https://en.wikipedia.org/wiki/Guru_Nanak_Gurpurab + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.guru_nanak_jayanti_date(self._year) + ) + + def _add_gyalpo_losar(self, name) -> Optional[date]: + """ + Add Gyalpo Losar. + + Gyalpo Losar marks the Tibetan New Year and is widely celebrated by the + Tibetan and Sherpa communities in Nepal. It falls on the first day of the + Tibetan lunar calendar, typically in February or March. + https://en.wikipedia.org/wiki/Gyalpo_Losar + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.gyalpo_losar_date(self._year) + ) + + def _add_nepal_holi(self, name) -> Optional[date]: + """ + Add Holi Festival for Nepal (Mountain & Hilly). + + Holi, known as the Festival of Colors, is a Hindu festival that marks + the arrival of spring. It is celebrated on the full moon day of the + Hindu month of Phalguna (February/March). + https://en.wikipedia.org/wiki/Holi + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.holi_date(self._year), days_delta=-1 + ) + + def _add_holi(self, name) -> Optional[date]: + """ + Add Holi Festival. + + Holi, known as the Festival of Colors, is a Hindu festival that marks + the arrival of spring. It is celebrated on the full moon day of the + Hindu month of Phalguna (February/March). + https://en.wikipedia.org/wiki/Holi + """ + return self._add_hindu_calendar_holiday(name, self._hindu_calendar.holi_date(self._year)) + + def _add_janmashtami(self, name) -> Optional[date]: + """ + Add Janmashtami. + + Janmashtami is a Hindu festival that celebrates the birth of Lord Krishna. + It falls on the eighth day of the Hindu month of Bhadrapada (August/September). + https://en.wikipedia.org/wiki/Krishna_Janmashtami + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.janmashtami_date(self._year) + ) + + def _add_maha_saptami(self, name) -> Optional[date]: + """ + Add Maha Saptami. + + Maha Saptami is the seventh day of Navratri, dedicated to Goddess Durga. + It is observed in Ashvin (September-October). + https://en.wikipedia.org/wiki/Navaratri + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.maha_ashtami_date(self._year), days_delta=-1 + ) + + def _add_maha_ashtami(self, name) -> Optional[date]: + """ + Add Maha Ashtami. + + Maha Ashtami is the eighth day of Navratri, dedicated to Goddess Durga. + It is observed in Ashvin (September-October). + https://en.wikipedia.org/wiki/Navaratri + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.maha_ashtami_date(self._year) + ) + + def _add_maha_navami(self, name) -> Optional[date]: + """ + Add Maha Navami. + + Maha Navami is the ninth day of Navratri, dedicated to Goddess Durga. + It is observed in Ashvin (September-October). + https://en.wikipedia.org/wiki/Navaratri + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.maha_navami_date(self._year) + ) + + def _add_maha_shivaratri(self, name) -> Optional[date]: + """ + Add Maha Shivaratri. + + Maha Shivaratri is a Hindu festival dedicated to Lord Shiva. It is celebrated + on the 14th night of the Hindu month of Phalguna (February/March). + https://en.wikipedia.org/wiki/Maha_Shivaratri + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.maha_shivaratri_date(self._year) + ) + + def _add_mahavir_jayanti(self, name) -> Optional[date]: + """ + Add Mahavir Jayanti. + + Mahavir Jayanti celebrates the birth of Lord Mahavira, the 24th + Tirthankara of Jainism. It falls on the 13th day of Chaitra (March-April). + https://en.wikipedia.org/wiki/Mahavir_Jayanti + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.mahavir_jayanti_date(self._year) + ) + + def _add_makar_sankranti(self, name) -> Optional[date]: + """ + Add Makar Sankranti. + + Makar Sankranti is a Hindu festival that marks the transition of the Sun + into Capricorn (Makar). It is celebrated on January 14th or 15th every year. + https://en.wikipedia.org/wiki/Makar_Sankranti + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.makar_sankranti_date(self._year) + ) + + def _add_onam(self, name) -> Optional[date]: + """ + Add Onam. + + Onam is a major festival in Kerala, celebrating the homecoming of + King Mahabali. It falls in the month of Chingam (August-September). + https://en.wikipedia.org/wiki/Onam + """ + return self._add_hindu_calendar_holiday(name, self._hindu_calendar.onam_date(self._year)) + + def _add_papankusha_ekadashi(self, name) -> Optional[date]: + """ + Add Papankusha Ekadashi. + + Papankusha Ekadashi is a Hindu festival which occurs on eleventh day on month of + Ashwin (September-October). + https://en.wikipedia.org/wiki/Ekadashi + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.dussehra_date(self._year), days_delta=+1 + ) + + def _add_papankusha_duwadashi(self, name) -> Optional[date]: + """ + Add Papankusha Duwadashi. + + Papankusha Duwadashi is a Hindu festival which occurs next day of Papankusha Ekadashi. + https://en.wikipedia.org/wiki/Ekadashi + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.dussehra_date(self._year), days_delta=+2 + ) + + def _add_pongal(self, name) -> Optional[date]: + """ + Add Pongal. + + Pongal is a major harvest festival celebrated in Tamil Nadu, India, marking the + beginning of the sun's northward journey (Uttarayana). It is usually observed + on January 14th or 15th every year, coinciding with the Tamil month of Thai. + The festival is dedicated to the Sun God and marks a season of prosperity and abundance. + https://en.wikipedia.org/wiki/Pongal_(festival) + """ + return self._add_hindu_calendar_holiday(name, self._hindu_calendar.pongal_date(self._year)) + + def _add_raksha_bandhan(self, name) -> Optional[date]: + """ + Add Raksha Bandhan. + + Raksha Bandhan is a Hindu festival that celebrates the bond between + brothers and sisters. It falls on the full moon day of the Hindu month + of Shravana (July/August). + https://en.wikipedia.org/wiki/Raksha_Bandhan + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.raksha_bandhan_date(self._year) + ) + + def _add_ram_navami(self, name) -> Optional[date]: + """ + Add Ram Navami. + + Ram Navami is a Hindu festival celebrating the birth of Lord Rama. + It is observed on the ninth day of the Hindu month of Chaitra (March/April). + https://en.wikipedia.org/wiki/Rama_Navami + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.ram_navami_date(self._year) + ) + + def _add_sharad_navratri(self, name) -> Optional[date]: + """ + Add Navratri / Sharad Navratri. + + Navratri is a Hindu festival dedicated to the worship of Goddess Durga. + It is celebrated over nine nights and occurs in the lunar month of Ashvin + (September/October). + https://en.wikipedia.org/wiki/Navratri + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.sharad_navratri_date(self._year) + ) + + def _add_sonam_losar(self, name) -> Optional[date]: + """ + Add Sonam Losar. + + Sonam Losar is the New Year festival celebrated by the Tamang community + in Nepal. It follows the Tibetan lunar calendar and usually falls in + January or February. + https://en.wikipedia.org/wiki/Sonam_Lhosar + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.sonam_losar_date(self._year) + ) + + def _add_tamu_losar(self, name) -> Optional[date]: + """ + Add Tamu Losar. + + Tamu Losar marks the New Year festival of the Gurung community in Nepal. + It is traditionally celebrated on December 30th each year. + https://en.wikipedia.org/wiki/Tamu_Lhosar + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.tamu_losar_date(self._year) + ) + + def _add_thaipusam(self, name) -> Optional[date]: + """ + Add Thaipusam. + + Thaipusam is a Tamil Hindu festival celebrated on the full moon + of the Tamil month of Thai (January/February). + https://en.wikipedia.org/wiki/Thaipusam + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.thaipusam_date(self._year) + ) + + def _add_thiruvalluvar_day(self, name) -> Optional[date]: + """ + Add Thiruvalluvar Day and Mattu Pongal. + + Thiruvalluvar Day and Mattu Pongal are celebrated in Tamil Nadu, India, as part + of the Pongal festival. Thiruvalluvar Day honors the classical Tamil poet and + philosopher Thiruvalluvar, while Mattu Pongal is dedicated to cattle, recognizing + their importance in agriculture. Both events usually fall on January 15th or 16th + each year during the Tamil month of Thai. + https://en.wikipedia.org/wiki/Thiruvalluvar_Day + https://en.wikipedia.org/wiki/Pongal_(festival)#Mattu_Pongal + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.pongal_date(self._year), days_delta=+1 + ) + + def _add_uzhavar_thirunal(self, name) -> Optional[date]: + """ + Add Uzhavar Thirunal. + + Uzhavar Thirunal is a harvest festival celebrated in Tamil Nadu, India, + as part of the Pongal festivities. It is dedicated to honoring farmers + (uzhavar) and their contribution to agriculture. Uzhavar Thirunal usually + falls on January 16th or 17th each year. + https://en.wikipedia.org/wiki/Pongal_(festival)#Uzhavar_Thirunal + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.pongal_date(self._year), days_delta=+2 + ) + + def _add_vaisakhi(self, name) -> Optional[date]: + """ + Add Vaisakhi. + + Vaisakhi is a major Sikh festival marking the Sikh New Year and the + founding of the Khalsa. It falls on April 13 or 14. + https://en.wikipedia.org/wiki/Vaisakhi + """ + return self._add_hindu_calendar_holiday( + name, self._hindu_calendar.vaisakhi_date(self._year) + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/international.py b/.venv/lib/python3.12/site-packages/holidays/groups/international.py new file mode 100644 index 00000000..78d7611f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/international.py @@ -0,0 +1,220 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date + +from holidays.calendars.gregorian import JAN + + +class InternationalHolidays: + """ + International holidays. + """ + + @property + def _next_year_new_years_day(self): + """ + Return New Year's Day of next year. + """ + return date(self._year + 1, JAN, 1) + + def _add_africa_day(self, name): + """ + Add Africa Day (May 25th) + + Africa Day (formerly African Freedom Day and African Liberation Day) + is the annual commemoration of the foundation of the Organisation + of African Unity on 25 May 1963. + https://en.wikipedia.org/wiki/Africa_Day + """ + return self._add_holiday_may_25(name) + + def _add_anzac_day(self, name): + """ + Add Anzac Day (April 25th) + + Anzac Day is a national day of remembrance in Australia and New Zealand + that broadly commemorates all Australians and New Zealanders "who + served and died in all wars, conflicts, and peacekeeping operations" + and "the contribution and suffering of all those who have served". + + Anzac Day is a public holiday in Australia, New Zealand, and Tonga; it + used to be a public holiday in Samoa up until 2008. + https://en.wikipedia.org/wiki/Anzac_Day + """ + return self._add_holiday_apr_25(name) + + def _add_childrens_day(self, name, variation="JUN"): + """ + Add International Children's Day (June 1). + + In 1925, International Children's Day was first proclaimed in Geneva + during the World Conference on Child Welfare. Since 1950, it is + celebrated on June 1 in many countries. + + As such, this entry currently defaults to June 1, though this also + supports another internationally adopted variant, November 20th. + https://en.wikipedia.org/wiki/Children's_Day + """ + if variation == "JUN": + return self._add_holiday_jun_1(name) + elif variation == "NOV": + return self._add_holiday_nov_20(name) + else: + raise ValueError( + f"Unknown variation name: {variation}. " + "This entry currently supports `JUN` and `NOV` variation only." + ) + + def _add_columbus_day(self, name): + """ + Add Columbus Day (October 12th) + + Columbus Day is a national holiday which officially celebrates the + anniversary of Christopher Columbus's arrival in the Americas. + https://en.wikipedia.org/wiki/Columbus_Day + """ + return self._add_holiday_oct_12(name) + + def _add_europe_day(self, name): + """ + Add Europe Day (May 9th) + + Europe Day is a day celebrating "peace and unity in Europe" + celebrated on 5 May by the Council of Europe + and on 9 May by the European Union. + https://en.wikipedia.org/wiki/Europe_Day + """ + return self._add_holiday_may_9(name) + + def _add_labor_day(self, name): + """ + Add International Workers' Day (May 1st) + + International Workers' Day, also known as Labour Day, is a celebration + of labourers and the working classes that is promoted by the + international labour movement. + https://en.wikipedia.org/wiki/International_Workers'_Day + """ + return self._add_holiday_may_1(name) + + def _add_labor_day_two(self, name): + """ + Add International Workers' Day Two (May 2nd) + + https://en.wikipedia.org/wiki/International_Workers'_Day + """ + return self._add_holiday_may_2(name) + + def _add_labor_day_three(self, name): + """ + Add International Workers' Day Three (May 3rd) + + https://en.wikipedia.org/wiki/International_Workers'_Day + """ + return self._add_holiday_may_3(name) + + def _add_new_years_day(self, name) -> date: + """ + Add New Year's Day (January 1st). + + New Year's Day is a festival observed in most of the world on + 1 January, the first day of the year in the modern Gregorian calendar. + https://en.wikipedia.org/wiki/New_Year's_Day + """ + return self._add_holiday_jan_1(name) + + def _add_new_years_day_two(self, name) -> date: + """ + Add New Year's Day Two (January 2nd). + + New Year's Day is a festival observed in most of the world on + 1 January, the first day of the year in the modern Gregorian calendar. + https://en.wikipedia.org/wiki/New_Year's_Day + """ + return self._add_holiday_jan_2(name) + + def _add_new_years_day_three(self, name) -> date: + """ + Add New Year's Day Three (January 3rd). + + New Year's Day is a festival observed in most of the world on + 1 January, the first day of the year in the modern Gregorian calendar. + https://en.wikipedia.org/wiki/New_Year's_Day + """ + return self._add_holiday_jan_3(name) + + def _add_new_years_day_four(self, name) -> date: + """ + Add New Year's Day Four (January 4th). + + New Year's Day is a festival observed in most of the world on + 1 January, the first day of the year in the modern Gregorian calendar. + https://en.wikipedia.org/wiki/New_Year's_Day + """ + return self._add_holiday_jan_4(name) + + def _add_remembrance_day(self, name): + """ + Add Remembrance Day / Armistice Day (Nov 11th) + + It's a memorial day since the end of the First World War in 1919 + to honour armed forces members who have died in the line of duty. + https://en.wikipedia.org/wiki/Remembrance_Day + """ + return self._add_holiday_nov_11(name) + + def _add_new_years_eve(self, name) -> date: + """ + Add New Year's Eve (December 31st). + + In the Gregorian calendar, New Year's Eve, also known as Old Year's + Day or Saint Sylvester's Day in many countries, is the evening or the + entire day of the last day of the year, on 31 December. + https://en.wikipedia.org/wiki/New_Year's_Eve + """ + return self._add_holiday_dec_31(name) + + def _add_womens_day(self, name): + """ + Add International Women's Day (March 8th). + + International Women's Day is a global holiday celebrated as a focal + point in the women's rights movement, bringing attention to issues + such as gender equality, reproductive rights, and violence and abuse + against women. + https://en.wikipedia.org/wiki/International_Women's_Day + """ + return self._add_holiday_mar_8(name) + + def _add_world_war_two_victory_day(self, name, is_western=True): + """ + Add Day of Victory in World War II in Europe (May 8). + https://en.wikipedia.org/wiki/Victory_in_Europe_Day + + Some Eastern European countries celebrate Victory Day on May 9. + https://en.wikipedia.org/wiki/Victory_Day_(9_May) + """ + if is_western: + return self._add_holiday_may_8(name) + else: + return self._add_holiday_may_9(name) + + def _add_united_nations_day(self, name): + """ + Add United Nations Day (Oct 24th) + + United Nations Day is an annual commemorative day, reflecting the + official creation of the United Nations on 24 October 1945. + https://en.wikipedia.org/wiki/United_Nations_Day + """ + return self._add_holiday_oct_24(name) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/islamic.py b/.venv/lib/python3.12/site-packages/holidays/groups/islamic.py new file mode 100644 index 00000000..db965f43 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/islamic.py @@ -0,0 +1,453 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from collections.abc import Iterable +from datetime import date + +from holidays.calendars import _IslamicLunar +from holidays.groups.eastern import EasternCalendarHolidays + + +class IslamicHolidays(EasternCalendarHolidays): + """ + Islamic holidays. + + The Hijri calendar also known as Islamic calendar, is a lunar + calendar consisting of 12 lunar months in a year of 354 or 355 days. + """ + + def __init__(self, cls=None, show_estimated=True) -> None: + self._islamic_calendar = cls() if cls else _IslamicLunar() + self._islamic_calendar_show_estimated = show_estimated + + def _add_ali_al_rida_death_day(self, name) -> set[date]: + """ + Add death of Ali al-Rida day (last (29th or 30th) day of 2nd month). + + https://en.wikipedia.org/wiki/Ali_al-Rida + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.ali_al_rida_death_dates(self._year) + ) + + def _add_ali_birthday_day(self, name) -> set[date]: + """ + Add birthday of Ali ibn Abu Talib day (13th day of 7th month). + + https://en.wikipedia.org/wiki/Ali + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.ali_birthday_dates(self._year) + ) + + def _add_ali_death_day(self, name) -> set[date]: + """ + Add death of Ali ibn Abu Talib day (21st day of 9th month). + + https://en.wikipedia.org/wiki/Ali + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.ali_death_dates(self._year) + ) + + def _add_arbaeen_day(self, name) -> set[date]: + """ + Add Arbaeen day (20th day of 2nd month). + + https://en.wikipedia.org/wiki/Arbaeen + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.arbaeen_dates(self._year) + ) + + def _add_arafah_day(self, name) -> set[date]: + """ + Add Day of Arafah (9th day of 12th month). + + At dawn of this day, Muslim pilgrims will make their way from Mina + to a nearby hillside and plain called Mount Arafat and the Plain of + Arafat. + https://en.wikipedia.org/wiki/Day_of_Arafah + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_adha_dates(self._year), days_delta=-1 + ) + + def _add_ashura_day(self, name) -> set[date]: + """ + Add Ashura Day (10th day of 1st month). + + Ashura is a day of commemoration in Islam. It occurs annually on the + 10th of Muharram, the first month of the Islamic calendar. + https://en.wikipedia.org/wiki/Ashura + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.ashura_dates(self._year) + ) + + def _add_ashura_eve(self, name) -> set[date]: + """ + Add Ashura Eve (Day before the 10th day of 1st month). + + Ashura is a day of commemoration in Islam. It occurs annually on the + 10th of Muharram, the first month of the Islamic calendar. + https://en.wikipedia.org/wiki/Ashura + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.ashura_dates(self._year), days_delta=-1 + ) + + def _add_eid_al_adha_day(self, name) -> set[date]: + """ + Add Eid al-Adha Day (10th day of the 12th month of Islamic calendar). + + Feast of the Sacrifice. It honours the willingness of Ibrahim + (Abraham) to sacrifice his son Ismail (Ishmael) as an act of obedience + to Allah's command. + https://en.wikipedia.org/wiki/Eid_al-Adha + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_adha_dates(self._year) + ) + + def _add_eid_al_adha_day_two(self, name) -> set[date]: + """ + Add Eid al-Adha Day Two. + + https://en.wikipedia.org/wiki/Eid_al-Adha + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_adha_dates(self._year), days_delta=+1 + ) + + def _add_eid_al_adha_day_three(self, name) -> set[date]: + """ + Add Eid al-Adha Day Three. + + https://en.wikipedia.org/wiki/Eid_al-Adha + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_adha_dates(self._year), days_delta=+2 + ) + + def _add_eid_al_adha_day_four(self, name) -> set[date]: + """ + Add Eid al-Adha Day Four. + + https://en.wikipedia.org/wiki/Eid_al-Adha + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_adha_dates(self._year), days_delta=+3 + ) + + def _add_eid_al_fitr_day(self, name) -> set[date]: + """ + Add Eid al-Fitr Day (1st day of 10th month of Islamic calendar). + + Holiday of Breaking the Fast. The religious holiday is celebrated + by Muslims worldwide because it marks the end of the month-long + dawn-to-sunset fasting of Ramadan. + https://en.wikipedia.org/wiki/Eid_al-Fitr + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_fitr_dates(self._year) + ) + + def _add_eid_al_fitr_day_two(self, name) -> set[date]: + """ + Add Eid al-Fitr Day Two. + + https://en.wikipedia.org/wiki/Eid_al-Fitr + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_fitr_dates(self._year), days_delta=+1 + ) + + def _add_eid_al_fitr_day_three(self, name) -> set[date]: + """ + Add Eid al-Fitr Day Three. + + https://en.wikipedia.org/wiki/Eid_al-Fitr + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_fitr_dates(self._year), days_delta=+2 + ) + + def _add_eid_al_fitr_day_four(self, name) -> set[date]: + """ + Add Eid al-Fitr Day Four. + + https://en.wikipedia.org/wiki/Eid_al-Fitr + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_fitr_dates(self._year), days_delta=+3 + ) + + def _add_eid_al_fitr_eve(self, name) -> set[date]: + """ + Add Eid al-Fitr Eve (last day of 9th month of Islamic calendar). + + https://en.wikipedia.org/wiki/Eid_al-Fitr + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_fitr_dates(self._year), days_delta=-1 + ) + + def _add_eid_al_ghadir_day(self, name) -> set[date]: + """ + Add Eid al-Ghadir Day (18th day of 12th month). + + https://en.wikipedia.org/wiki/Eid_al-Ghadeer + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.eid_al_ghadir_dates(self._year) + ) + + def _add_fatima_death_day(self, name) -> set[date]: + """ + Add death of Fatima day (3rd day of 6th month). + + https://en.wikipedia.org/wiki/Fatima + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.fatima_death_dates(self._year) + ) + + def _add_grand_magal_of_touba(self, name) -> set[date]: + """ + Annual religious pilgrimage of Senegalese Mouride brotherhood. + + https://en.wikipedia.org/wiki/Grand_Magal_of_Touba + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.grand_magal_of_touba_dates(self._year) + ) + + def _add_hari_hol_johor(self, name) -> set[date]: + """ + Hari Hol Johor. + + https://web.archive.org/web/20241202170507/https://publicholidays.com.my/hari-hol-almarhum-sultan-iskandar/ + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.hari_hol_johor_dates(self._year) + ) + + def _add_hasan_al_askari_death_day(self, name) -> set[date]: + """ + Add death of Hasan_al-Askari day (8th day of 3rd month). + + https://en.wikipedia.org/wiki/Hasan_al-Askari + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.hasan_al_askari_death_dates(self._year) + ) + + def _add_holiday_29_ramadan(self, name) -> set[date]: + """ + Add 29th Ramadan holiday. + + https://web.archive.org/web/20250323065556/https://decree.om/2022/rd20220088/ + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.ramadan_beginning_dates(self._year), days_delta=+28 + ) + + def _add_imam_mahdi_birthday_day(self, name) -> set[date]: + """ + Add birthday of Muhammad al-Mahdi day (15th day of 8th month). + + https://en.wikipedia.org/wiki/Muhammad_al-Mahdi + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.imam_mahdi_birthday_dates(self._year) + ) + + def _add_islamic_calendar_holiday( + self, name: str, dates: Iterable[tuple[date, bool]], days_delta: int = 0 + ) -> set[date]: + """ + Add lunar calendar holiday. + + Appends customizable estimation label at the end of holiday name if + holiday date is an estimation. + """ + added_dates = set() + for dts in dates: + if dt := self._add_eastern_calendar_holiday( + name, dts, self._islamic_calendar_show_estimated, days_delta + ): + added_dates.add(dt) + + return added_dates + + def _add_islamic_new_year_day(self, name) -> set[date]: + """ + Add Islamic New Year Day (last day of Dhu al-Hijjah). + + The Islamic New Year, also called the Hijri New Year, is the day that + marks the beginning of a new lunar Hijri year, and is the day on which + the year count is incremented. The first day of the Islamic year is + observed by most Muslims on the first day of the month of Muharram. + https://en.wikipedia.org/wiki/Islamic_New_Year + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.hijri_new_year_dates(self._year) + ) + + def _add_isra_and_miraj_day(self, name): + """ + Add Isra' and Mi'raj Day (27th day of 7th month). + + The Prophet's Ascension. + https://en.wikipedia.org/wiki/Isra'_and_Mi'raj + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.isra_and_miraj_dates(self._year) + ) + + def _add_laylat_al_qadr_day(self, name): + """ + Add Laylat al-Qadr Day (27th day of 9th month). + + The Night of Power. + https://en.wikipedia.org/wiki/Night_of_Power + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.laylat_al_qadr_dates(self._year) + ) + + def _add_maldives_embraced_islam_day(self, name) -> set[date]: + """ + Add Maldives Embraced Islam Day (1st day of 4th month). + + https://en.wikipedia.org/wiki/Islam_in_Maldives + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.maldives_embraced_islam_day_dates(self._year) + ) + + def _add_mawlid_day(self, name) -> set[date]: + """ + Add Mawlid Day (12th day of 3rd month). + + Mawlid is the observance of the birthday of the Islamic prophet + Muhammad. + https://en.wikipedia.org/wiki/Mawlid + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.mawlid_dates(self._year) + ) + + def _add_mawlid_day_two(self, name) -> set[date]: + """ + Add Mawlid Day Two. + + Mawlid is the observance of the birthday of the Islamic prophet + Muhammad. + https://en.wikipedia.org/wiki/Mawlid + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.mawlid_dates(self._year), days_delta=+1 + ) + + def _add_nuzul_al_quran_day(self, name) -> set[date]: + """ + Add Nuzul Al Quran (17th day of 9th month). + + Nuzul Al Quran is a Muslim festival to remember the day when Prophet + Muhammad received his first revelation of Islam's sacred book, + the holy Quran. + https://web.archive.org/web/20241012115752/https://zamzam.com/blog/nuzul-al-quran/ + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.nuzul_al_quran_dates(self._year) + ) + + def _add_prophet_baptism_day(self, name) -> set[date]: + """ + Add Prophet's Baptism. + + Celebrated one week after the Prophet Mohammed's Birthday, this + marks the traditional Islamic birth rites that take place seven + days after birth. While it is not recognized in mainstream Islam, + Mali celebrates it as a cultural-religious public holiday that + reflects the local interpretation and honor of the Prophet Muhammad. + The term "baptism" is symbolic and not literal - there's no Islamic + ritual akin to Christian baptism. + https://www.officeholidays.com/holidays/mali/prophets-baptism + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.mawlid_dates(self._year), days_delta=+7 + ) + + def _add_prophet_death_day(self, name) -> set[date]: + """ + Add death of Prophet Muhammad and Hasan ibn Ali day (28th day of 2nd month). + + https://en.wikipedia.org/wiki/Hasan_ibn_Ali + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.prophet_death_dates(self._year) + ) + + def _add_quamee_dhuvas_day(self, name) -> set[date]: + """ + Add Quamee Dhuvas (1st day of 3rd month). + + https://en.wikipedia.org/wiki/Qaumee_Dhuvas_(Maldives_National_Day) + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.quamee_dhuvas_dates(self._year) + ) + + def _add_ramadan_beginning_day(self, name) -> set[date]: + """ + Add First Day of Ramadan (1st day of 9th month). + + Ramadan is the ninth month of the Islamic calendar, observed by Muslims + worldwide as a month of fasting, prayer, reflection, and community + https://en.wikipedia.org/wiki/Ramadan + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.ramadan_beginning_dates(self._year) + ) + + def _add_sadiq_birthday_day(self, name) -> set[date]: + """ + Add birthday of Prophet Muhammad and Ja'far al-Sadiq day (17th day of 3rd month). + + https://en.wikipedia.org/wiki/Ja'far_al-Sadiq + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.sadiq_birthday_dates(self._year) + ) + + def _add_sadiq_death_day(self, name) -> set[date]: + """ + Add death of Ja'far al-Sadiq day (25th day of 10th month). + + https://en.wikipedia.org/wiki/Ja'far_al-Sadiq + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.sadiq_death_dates(self._year) + ) + + def _add_tasua_day(self, name) -> set[date]: + """ + Add Tasua day (9th day of 1st month). + + https://en.wikipedia.org/wiki/Tasua + """ + return self._add_islamic_calendar_holiday( + name, self._islamic_calendar.tasua_dates(self._year) + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/mongolian.py b/.venv/lib/python3.12/site-packages/holidays/groups/mongolian.py new file mode 100644 index 00000000..1a536fea --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/mongolian.py @@ -0,0 +1,103 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars import _MongolianLunisolar +from holidays.groups.eastern import EasternCalendarHolidays + + +class MongolianCalendarHolidays(EasternCalendarHolidays): + """ + Mongolian lunisolar calendar holidays. + """ + + def __init__(self, cls=None, show_estimated=False) -> None: + self._mongolian_calendar = cls() if cls else _MongolianLunisolar() + self._mongolian_calendar_show_estimated = show_estimated + + def _add_mongolian_calendar_holiday( + self, name: str, dt_estimated: tuple[Optional[date], bool], days_delta: int = 0 + ) -> Optional[date]: + """ + Add Mongolian calendar holiday. + + Adds customizable estimation label to holiday name if holiday date + is an estimation. + """ + + return self._add_eastern_calendar_holiday( + name, dt_estimated, self._mongolian_calendar_show_estimated, days_delta + ) + + def _add_buddha_day(self, name) -> Optional[date]: + """ + Add Buddha Day. + + Buddha Day is celebrated on the 15th day of the early summer month + in the Mongolian lunisolar calendar. + This holiday honors the birth, enlightenment, and death of Buddha. + https://en.wikipedia.org/wiki/Vesak (general Buddhist context) + """ + return self._add_mongolian_calendar_holiday( + name, self._mongolian_calendar.buddha_day_date(self._year) + ) + + def _add_genghis_khan_day(self, name) -> Optional[date]: + """ + Add Genghis Khan's Birthday. + + Genghis Khan's Birthday is observed on the 1st day of the early winter month + according to the Mongolian lunisolar calendar. + It commemorates the birth of the founder of the Mongol Empire. + https://en.wikipedia.org/wiki/Genghis_Khan + """ + return self._add_mongolian_calendar_holiday( + name, self._mongolian_calendar.genghis_khan_day_date(self._year) + ) + + def _add_tsagaan_sar(self, name) -> Optional[date]: + """ + Add Tsagaan Sar (Mongolian Lunar New Year). + + Tsagaan Sar, or White Moon Festival, marks the beginning of the Mongolian Lunar New Year. + It usually falls on the first day of the first month of the Mongolian lunisolar calendar. + https://en.wikipedia.org/wiki/Tsagaan_Sar + """ + return self._add_mongolian_calendar_holiday( + name, self._mongolian_calendar.tsagaan_sar_date(self._year) + ) + + def _add_tsagaan_sar_day_2(self, name) -> Optional[date]: + """ + Add Tsagaan Sar Day 2 (Mongolian Lunar New Year). + + Tsagaan Sar, or White Moon Festival, marks the beginning of the Mongolian Lunar New Year. + It usually falls on the first day of the first month of the Mongolian lunisolar calendar. + https://en.wikipedia.org/wiki/Tsagaan_Sar + """ + return self._add_mongolian_calendar_holiday( + name, self._mongolian_calendar.tsagaan_sar_date(self._year), days_delta=+1 + ) + + def _add_tsagaan_sar_day_3(self, name) -> Optional[date]: + """ + Add Tsagaan Sar Day 3 (Mongolian Lunar New Year). + + Tsagaan Sar, or White Moon Festival, marks the beginning of the Mongolian Lunar New Year. + It usually falls on the first day of the first month of the Mongolian lunisolar calendar. + https://en.wikipedia.org/wiki/Tsagaan_Sar + """ + return self._add_mongolian_calendar_holiday( + name, self._mongolian_calendar.tsagaan_sar_date(self._year), days_delta=+2 + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/persian.py b/.venv/lib/python3.12/site-packages/holidays/groups/persian.py new file mode 100644 index 00000000..7d6380e1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/persian.py @@ -0,0 +1,169 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import _timedelta +from holidays.calendars.persian import _Persian + + +class PersianCalendarHolidays: + """ + Persian (Solar Hijri) calendar holidays. + """ + + def __init__(self) -> None: + self._persian_calendar = _Persian() + + def _add_death_of_khomeini_day(self, name: str) -> Optional[date]: + """ + Add Death of Ruhollah Khomeini Day (14th day of the 3rd month). + + Ayatollah Ruhollah Khomeini was an Iranian revolutionary, politician and religious leader. + https://en.wikipedia.org/wiki/Ruhollah_Khomeini + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.persian_to_gregorian(self._year, 3, 14) + ) + + def _add_islamic_emirat_victory_day(self, name: str) -> Optional[date]: + """ + Add Islamic Emirate Victory Day (24th day of the 5th month). + + Anniversary of the Taliban forces arrival in Kabul. + https://en.wikipedia.org/wiki/Fall_of_Kabul_(2021) + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.persian_to_gregorian(self._year, 5, 24) + ) + + def _add_islamic_republic_day(self, name: str) -> Optional[date]: + """ + Add Islamic Republic Day (12th day of the 1st month). + + Iranian Islamic Republic Day is a national and a public holiday in Iran. It marks the day + that the results of the March 1979 Iranian Islamic Republic referendum were announced. + https://en.wikipedia.org/wiki/Islamic_Republic_Day + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.persian_to_gregorian(self._year, 1, 12) + ) + + def _add_islamic_revolution_day(self, name: str) -> Optional[date]: + """ + Add Islamic Revolution Day (22nd day of the 11th month). + + The anniversary of the Iranian Revolution commemorates the protests that led to + the downfall of the Pahlavi dynasty and the installation of the Islamic Revolutionary + which is headed by Imam Khomeini. + https://en.wikipedia.org/wiki/Anniversary_of_Islamic_Revolution + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.persian_to_gregorian(self._year - 1, 11, 22) + ) + + def _add_khordad_uprising_day(self, name: str) -> Optional[date]: + """ + Add 15 Khordad uprising Day (15th day of the 3rd month). + + The demonstrations of June 5 and 6, also called the events of June 1963 or (using + the Iranian calendar) the 15 Khordad uprising were protests in Iran against the arrest + of Ayatollah Ruhollah Khomeini. + https://en.wikipedia.org/wiki/June_5,_1963_demonstrations_in_Iran + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.persian_to_gregorian(self._year, 3, 15) + ) + + def _add_last_day_of_year(self, name: str) -> Optional[date]: + """ + If previous year is a leap year, its 12th month (Esfand) has 30 days, + and this 30th day is a holiday. + """ + if self._persian_calendar.is_leap_year(self._year - 1): + return self._add_persian_calendar_holiday( + name, self._persian_calendar.new_year_date(self._year), days_delta=-1 + ) + else: + return None + + def _add_natures_day(self, name: str) -> Optional[date]: + """ + Add Nature's Day, or Sizdah Bedar (13th day of the 1st month). + + Nature's Day is an Iranian festival, during which people spend time picnicking outdoors. + https://en.wikipedia.org/wiki/Sizdah_Be-dar + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.persian_to_gregorian(self._year, 1, 13) + ) + + def _add_nowruz_day(self, name: str) -> Optional[date]: + """ + Add Nowruz Day (1st day of the 1st month). + + Nowruz (Iranian or Persian New Year) is a festival based on the Iranian Solar Hijri + calendar, on the spring equinox. + https://en.wikipedia.org/wiki/Nowruz + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.new_year_date(self._year) + ) + + def _add_nowruz_day_two(self, name: str) -> Optional[date]: + """ + Add Nowruz Day Two. + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.new_year_date(self._year), days_delta=+1 + ) + + def _add_nowruz_day_three(self, name: str) -> Optional[date]: + """ + Add Nowruz Day Three. + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.new_year_date(self._year), days_delta=+2 + ) + + def _add_nowruz_day_four(self, name: str) -> Optional[date]: + """ + Add Nowruz Day Four. + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.new_year_date(self._year), days_delta=+3 + ) + + def _add_oil_nationalization_day(self, name: str) -> Optional[date]: + """ + Add Iranian Oil Industry Nationalization Day (29th day of the 12th month). + + The nationalization of the Iranian oil industry resulted from a movement in the Iranian + parliament (Majlis) to seize control of Iran's oil industry. + https://en.wikipedia.org/wiki/Nationalization_of_the_Iranian_oil_industry + """ + return self._add_persian_calendar_holiday( + name, self._persian_calendar.persian_to_gregorian(self._year - 1, 12, 29) + ) + + def _add_persian_calendar_holiday( + self, name: str, dt: Optional[date], days_delta: int = 0 + ) -> Optional[date]: + """ + Add Persian calendar holiday. + """ + if dt is None: + return None + if days_delta != 0: + dt = _timedelta(dt, days_delta) + return self._add_holiday(name, dt) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/sinhala.py b/.venv/lib/python3.12/site-packages/holidays/groups/sinhala.py new file mode 100644 index 00000000..ea957030 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/sinhala.py @@ -0,0 +1,192 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from collections.abc import Iterable +from datetime import date +from typing import Optional + +from holidays.calendars import _SinhalaLunar +from holidays.groups.eastern import EasternCalendarHolidays + + +class SinhalaCalendarHolidays(EasternCalendarHolidays): + """ + Sinhala holidays. + + Sinhala Buddhist Uposatha day calculation method is different from Thai LuniSolar + and Buddhist (Mahayana) used in East Asia. + + Due to the fact that Poya (Uposatha) days are calculated astronomically + based on how close a particular day is closest to full moon at noon, and that + an extra month is added every 33 months interval, this is hardcoded for now. + + Adhi month dates are instead hardcoded in Sri Lanka country implementation. + """ + + def __init__(self, cls=None, show_estimated=False) -> None: + self._sinhala_calendar = cls() if cls else _SinhalaLunar() + self._sinhala_calendar_show_estimated = show_estimated + + def _add_sinhala_calendar_holiday( + self, name: str, dt_estimated: tuple[Optional[date], bool] + ) -> Optional[date]: + """ + Add Sinhala calendar holiday. + + Adds customizable estimation label to holiday name if holiday date + is an estimation. + """ + return self._add_eastern_calendar_holiday( + name, dt_estimated, self._sinhala_calendar_show_estimated + ) + + def _add_sinhala_calendar_holiday_set( + self, name: str, dts_estimated: Iterable[tuple[date, bool]], days_delta: int = 0 + ) -> set[date]: + """ + Add Sinhala calendar holidays. + + Adds customizable estimation label to holiday name if holiday date + is an estimation. + """ + added_dates = set() + for dt_estimated in dts_estimated: + if dt := self._add_eastern_calendar_holiday( + name, dt_estimated, self._sinhala_calendar_show_estimated, days_delta=days_delta + ): + added_dates.add(dt) + + return added_dates + + def _add_bak_poya(self, name) -> Optional[date]: + """ + Add Bak Poya (first full moon day of the 5th lunar month). + + https://web.archive.org/web/20250417183100/https://us.lakpura.com/pages/bak-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.bak_poya_date(self._year) + ) + + def _add_binara_poya(self, name) -> Optional[date]: + """ + Add Binara Poya (first full moon day of the 10th lunar month). + + https://web.archive.org/web/20250415144613/https://us.lakpura.com/pages/binara-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.binara_poya_date(self._year) + ) + + def _add_duruthu_poya(self, name) -> set[date]: + """ + Add Duruthu Poya (first full moon day of the 2nd lunar month). + + https://web.archive.org/web/20250417123343/https://us.lakpura.com/pages/duruthu-poya + """ + return self._add_sinhala_calendar_holiday_set( + name, self._sinhala_calendar.duruthu_poya_date(self._year) + ) + + def _add_esala_poya(self, name) -> Optional[date]: + """ + Add Esala Poya (first full moon day of the 8th lunar month). + + https://web.archive.org/web/20250415231927/https://us.lakpura.com/pages/esala-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.esala_poya_date(self._year) + ) + + def _add_il_poya(self, name) -> Optional[date]: + """ + Add Il Poya (first full moon day of the 12th lunar month). + + Also known as "Ill Poya" + https://web.archive.org/web/20250415054940/https://us.lakpura.com/pages/il-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.il_poya_date(self._year) + ) + + def _add_medin_poya(self, name) -> Optional[date]: + """ + Add Medin Poya (first full moon day of the 4th lunar month). + + https://web.archive.org/web/20250415154545/https://us.lakpura.com/pages/medin-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.medin_poya_date(self._year) + ) + + def _add_nawam_poya(self, name) -> Optional[date]: + """ + Add Nawam Poya (first full moon day of the 3rd lunar month). + + Also known as "Navam Poya" and "Magha Puja". + https://web.archive.org/web/20250416122014/https://us.lakpura.com/pages/navam-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.nawam_poya_date(self._year) + ) + + def _add_nikini_poya(self, name) -> Optional[date]: + """ + Add Nikini Poya (first full moon day of the 9th lunar month). + + https://web.archive.org/web/20241204065104/https://us.lakpura.com/pages/nikini-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.nikini_poya_date(self._year) + ) + + def _add_poson_poya(self, name) -> Optional[date]: + """ + Add Poson Poya (first full moon day of the 7th lunar month). + + https://web.archive.org/web/20250416105848/https://us.lakpura.com/pages/poson + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.poson_poya_date(self._year) + ) + + def _add_unduvap_poya(self, name) -> Optional[date]: + """ + Add Unduvap Poya (first full moon day of the 1st lunar month). + + Also known as "Undawap Poya". + https://web.archive.org/web/20250413191847/https://us.lakpura.com/pages/unduvap-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.unduvap_poya_date(self._year) + ) + + def _add_vap_poya(self, name) -> Optional[date]: + """ + Add Vap Poya (first full moon day of the 11th lunar month). + + https://web.archive.org/web/20250418083429/https://us.lakpura.com/pages/vap-poya + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.vap_poya_date(self._year) + ) + + def _add_vesak_poya(self, name) -> Optional[date]: + """ + Add Vesak Poya (first full moon day of the 6th lunar month). + + Also known as "Wesak Poya". + https://web.archive.org/web/20250419054525/https://us.lakpura.com/pages/vesak + """ + return self._add_sinhala_calendar_holiday( + name, self._sinhala_calendar.vesak_poya_date(self._year) + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/groups/thai.py b/.venv/lib/python3.12/site-packages/holidays/groups/thai.py new file mode 100644 index 00000000..46151ff5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/groups/thai.py @@ -0,0 +1,206 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.thai import THAI_CALENDAR, _ThaiLunisolar + + +class ThaiCalendarHolidays: + """ + Thai lunisolar calendar holidays. + + For more info, see class `_ThaiLunisolar`. + Calendar-type checking are done by `_ThaiLunisolar`. + """ + + def __init__(self, calendar=THAI_CALENDAR) -> None: + self.__calendar = calendar + self._thai_calendar = _ThaiLunisolar(calendar) + + def _add_asarnha_bucha(self, name) -> Optional[date]: + """ + Add Asarnha Bucha. + + Asalha Pūjā (also written as Asarnha Bucha Day) is a Buddhist festival + celebrated on the 15th Waxing Day (Full Moon) of Month 8. + + https://en.wikipedia.org/wiki/Asalha_Puja + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.asarnha_bucha_date(self._year) + ) + + def _add_boun_haw_khao_padapdin(self, name) -> Optional[date]: + """ + Add Boun Haw Khao Padapdin. + + Boun Haw Khao Padapdin (also known as Rice Growing Festival) + is a Buddhist festival celebrated on the 14th Waning Day of Month 9. + + https://web.archive.org/web/20250415072547/https://www.timsthailand.com/boon-khao-pradap-din/ + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.boun_haw_khao_padapdin_date(self._year) + ) + + def _add_boun_haw_khao_salark(self, name) -> Optional[date]: + """ + Add Boun Haw Khao Salark. + + Boun Haw Khao Salark (also known as Ancestor Festival) + is a Buddhist festival celebrated on the 15th Waxing Day of Month 10. + + https://web.archive.org/web/20250414145714/https://www.timsthailand.com/boon-khao-sak/ + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.boun_haw_khao_salark_date(self._year) + ) + + def _add_boun_suang_heua(self, name) -> Optional[date]: + """ + Add Boun Suang Huea. + + Boun Suang Huea Nakhone Luang Prabang (also known as Vientiane Boat Racing Festival) + is a Buddhist festival celebrated on the 1st Waning Day of Month 11. + + https://web.archive.org/web/20250413191357/https://sonasia-holiday.com/sonabee/laos-boat-racing-festival + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.boun_suang_heua_date(self._year) + ) + + def _add_khao_phansa(self, name) -> Optional[date]: + """ + Add Khao Phansa. + + Start of Buddhist Lent (also written as Khao Phansa Day) is a Buddhist + festival celebrated on the 1st Waning Day of Month 8. + + https://en.wikipedia.org/wiki/Vassa + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.khao_phansa_date(self._year) + ) + + def _add_loy_krathong(self, name) -> Optional[date]: + """ + Add Loy Krathong. + + Also known as "Boun That Louang" and "Bon Om Touk". + This concides with the 15th Waxing Day (Full Moon) of Month 12 + in Thai Lunar Calendar. + + https://en.wikipedia.org/wiki/Loy_Krathong + https://en.wikipedia.org/wiki/Bon_Om_Touk + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.loy_krathong_date(self._year) + ) + + def _add_makha_bucha(self, name, calendar=None) -> Optional[date]: + """ + Add Makha Bucha. + + Māgha Pūjā (also written as Makha Bousa and Meak Bochea Day) is a Buddhist + festival celebrated on the 15th Waxing Day (Full Moon) of Month 3. + + Khmer variant: always fall on Month 3. + Thai variant: will use Month 4 instead for Athikamat years. + + https://en.wikipedia.org/wiki/Māgha_Pūjā + """ + calendar = calendar or self.__calendar + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.makha_bucha_date(self._year, calendar) + ) + + def _add_ok_phansa(self, name) -> Optional[date]: + """ + Add Ok Phansa. + + End of Buddhist Lent (also written as Ok Phansa Day) is a Buddhist + festival celebrated on the 15th Waxing Day of Month 11. + + https://en.wikipedia.org/wiki/Pavarana + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.ok_phansa_date(self._year) + ) + + def _add_pchum_ben(self, name) -> Optional[date]: + """ + Add Pchum Ben. + + Also known as "Prachum Bandar". + This concides with the 15th Waning Day (New Moon) of Month 10 in + Thai Lunar Calendar. + + https://en.wikipedia.org/wiki/Pchum_Ben + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.pchum_ben_date(self._year) + ) + + def _add_preah_neangkoal(self, name) -> Optional[date]: + """ + Add Preah Reach Pithi Chrat Preah Neangkoal. + + Also known as "Cambodian Royal Ploughing Ceremony". This always + concides with the 4th Waning Day of Month 6 in Khmer Lunar Calendar. + + https://en.wikipedia.org/wiki/Royal_Ploughing_Ceremony + """ + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.preah_neangkoal_date(self._year) + ) + + def _add_thai_calendar_holiday(self, name, dt) -> Optional[date]: + """ + Add Thai calendar holiday. + + If the result from `_ThaiLunisolar` is none then no holidays added. + """ + if dt is None: + return None + + return self._add_holiday(name, dt) + + def _add_visakha_bucha(self, name, calendar=None) -> Optional[date]: + """ + Add Visakha Bucha. + + Vesak (also written as Visakha Bousa Day and Visaka Bochea Day) is a + Buddhist festival celebrated on the 15th Waxing Day (Full Moon) + of Month 6. + + Khmer variant: always fall on Month 6. + Thai variant: will use Month 7 instead for Athikamat years. + + https://en.wikipedia.org/wiki/Vesak + """ + calendar = calendar or self.__calendar + + return self._add_thai_calendar_holiday( + name, self._thai_calendar.visakha_bucha_date(self._year, calendar) + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/helpers.py b/.venv/lib/python3.12/site-packages/holidays/helpers.py new file mode 100644 index 00000000..49cad8e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/helpers.py @@ -0,0 +1,49 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + + +def _normalize_arguments(cls, value): + """Normalize arguments. + + :param cls: + A type of arguments to normalize. + + :param value: + Either a single item or an iterable of `cls` type. + + :return: + A set created from `value` argument. + + """ + if value is None: + return set() + + if isinstance(value, str): + return {cls(value)} + + try: + return {cls(v) for v in value} + except TypeError: # non-iterable + return {cls(value)} + + +def _normalize_tuple(value): + """Normalize tuple. + + :param data: + Either a tuple or a tuple of tuples. + + :return: + An unchanged object for tuple of tuples, e.g., ((JAN, 10), (DEC, 31)). + An object put into a tuple otherwise, e.g., ((JAN, 10),). + """ + return value if not value or isinstance(value[0], tuple) else (value,) diff --git a/.venv/lib/python3.12/site-packages/holidays/holiday_base.py b/.venv/lib/python3.12/site-packages/holidays/holiday_base.py new file mode 100644 index 00000000..0449b6b4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/holiday_base.py @@ -0,0 +1,1421 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +__all__ = ("DateLike", "HolidayBase", "HolidaySum") + +import copy +import warnings +from bisect import bisect_left, bisect_right +from calendar import isleap +from collections.abc import Iterable +from datetime import date, datetime, timedelta, timezone +from functools import cached_property +from gettext import gettext, translation +from pathlib import Path +from typing import Any, Literal, Optional, Union, cast + +from dateutil.parser import parse + +from holidays.calendars.gregorian import ( + MON, + TUE, + WED, + THU, + FRI, + SAT, + SUN, + _timedelta, + _get_nth_weekday_from, + _get_nth_weekday_of_month, + DAYS, + MONTHS, + WEEKDAYS, +) +from holidays.constants import HOLIDAY_NAME_DELIMITER, PUBLIC, DEFAULT_START_YEAR, DEFAULT_END_YEAR +from holidays.helpers import _normalize_arguments, _normalize_tuple + +CategoryArg = Union[str, Iterable[str]] +DateArg = Union[date, tuple[int, int], tuple[int, int, int]] +DateLike = Union[date, datetime, str, float, int] +SpecialHoliday = Union[tuple[int, int, str], tuple[tuple[int, int, str], ...]] +SubstitutedHoliday = Union[ + Union[tuple[int, int, int, int], tuple[int, int, int, int, int]], + tuple[Union[tuple[int, int, int, int], tuple[int, int, int, int, int]], ...], +] +YearArg = Union[int, Iterable[int]] + + +class HolidayBase(dict[date, str]): + """ + A `dict`-like object containing the holidays for a specific country (and + province or state if so initiated); inherits the `dict` class (so behaves + similarly to a `dict`). Dates without a key in the Holiday object are not + holidays. + + The key of the object is the date of the holiday and the value is the name + of the holiday itself. When passing the date as a key, the date can be + expressed as one of the following formats: + + * `datetime.datetime` type; + * `datetime.date` types; + * a `float` representing a Unix timestamp; + * or a string of any format (recognized by `dateutil.parser.parse()`). + + The key is always returned as a `datetime.date` object. + + To maximize speed, the list of holidays is built as needed on the fly, one + calendar year at a time. When you instantiate the object, it is empty, but + the moment a key is accessed it will build that entire year's list of + holidays. To pre-populate holidays, instantiate the class with the years + argument: + + us_holidays = holidays.US(years=2020) + + It is generally instantiated using the + [country_holidays()][holidays.utils.country_holidays] function. + + The key of the `dict`-like `HolidayBase` object is the + `date` of the holiday, and the value is the name of the holiday itself. + Dates where a key is not present are not public holidays (or, if + **observed** is False, days when a public holiday is observed). + + When passing the `date` as a key, the `date` can be expressed in one of the + following types: + + * `datetime.date`, + * `datetime.datetime`, + * a `str` of any format recognized by `dateutil.parser.parse()`, + * or a `float` or `int` representing a POSIX timestamp. + + The key is always returned as a `datetime.date` object. + + To maximize speed, the list of public holidays is built on the fly as + needed, one calendar year at a time. When the object is instantiated + without a **years** parameter, it is empty, but, unless **expand** is set + to False, as soon as a key is accessed the class will calculate that entire + year's list of holidays and set the keys with them. + + If you need to list the holidays as opposed to querying individual dates, + instantiate the class with the **years** parameter. + + Example usage: + + >>> from holidays import country_holidays + >>> us_holidays = country_holidays('US') + # For a specific subdivisions (e.g. state or province): + >>> california_holidays = country_holidays('US', subdiv='CA') + + The below will cause 2015 holidays to be calculated on the fly: + + >>> from datetime import date + >>> assert date(2015, 1, 1) in us_holidays + + This will be faster because 2015 holidays are already calculated: + + >>> assert date(2015, 1, 2) not in us_holidays + + The `HolidayBase` class also recognizes strings of many formats + and numbers representing a POSIX timestamp: + + >>> assert '2014-01-01' in us_holidays + >>> assert '1/1/2014' in us_holidays + >>> assert 1388597445 in us_holidays + + Show the holiday's name: + + >>> us_holidays.get('2014-01-01') + "New Year's Day" + + Check a range: + + >>> us_holidays['2014-01-01': '2014-01-03'] + [datetime.date(2014, 1, 1)] + + List all 2020 holidays: + + >>> us_holidays = country_holidays('US', years=2020) + >>> for day in sorted(us_holidays.items()): + ... print(day) + (datetime.date(2020, 1, 1), "New Year's Day") + (datetime.date(2020, 1, 20), 'Martin Luther King Jr. Day') + (datetime.date(2020, 2, 17), "Washington's Birthday") + (datetime.date(2020, 5, 25), 'Memorial Day') + (datetime.date(2020, 7, 3), 'Independence Day (observed)') + (datetime.date(2020, 7, 4), 'Independence Day') + (datetime.date(2020, 9, 7), 'Labor Day') + (datetime.date(2020, 10, 12), 'Columbus Day') + (datetime.date(2020, 11, 11), 'Veterans Day') + (datetime.date(2020, 11, 26), 'Thanksgiving Day') + (datetime.date(2020, 12, 25), 'Christmas Day') + + Some holidays are only present in parts of a country: + + >>> us_pr_holidays = country_holidays('US', subdiv='PR') + >>> assert '2018-01-06' not in us_holidays + >>> assert '2018-01-06' in us_pr_holidays + + Append custom holiday dates by passing one of: + + * a `dict` with date/name key/value pairs (e.g. + `{'2010-07-10': 'My birthday!'}`), + * a list of dates (as a `datetime.date`, `datetime.datetime`, + `str`, `int`, or `float`); `'Holiday'` will be used as a description, + * or a single date item (of one of the types above); `'Holiday'` will be + used as a description: + + ```python + >>> custom_holidays = country_holidays('US', years=2015) + >>> custom_holidays.update({'2015-01-01': "New Year's Day"}) + >>> custom_holidays.update(['2015-07-01', '07/04/2015']) + >>> custom_holidays.update(date(2015, 12, 25)) + >>> assert date(2015, 1, 1) in custom_holidays + >>> assert date(2015, 1, 2) not in custom_holidays + >>> assert '12/25/2015' in custom_holidays + ``` + + For special (one-off) country-wide holidays handling use + `special_public_holidays`: + + special_public_holidays = { + 1977: ((JUN, 7, "Silver Jubilee of Elizabeth II"),), + 1981: ((JUL, 29, "Wedding of Charles and Diana"),), + 1999: ((DEC, 31, "Millennium Celebrations"),), + 2002: ((JUN, 3, "Golden Jubilee of Elizabeth II"),), + 2011: ((APR, 29, "Wedding of William and Catherine"),), + 2012: ((JUN, 5, "Diamond Jubilee of Elizabeth II"),), + 2022: ( + (JUN, 3, "Platinum Jubilee of Elizabeth II"), + (SEP, 19, "State Funeral of Queen Elizabeth II"), + ), + } + + def _populate(self, year): + super()._populate(year) + + ... + + For more complex logic, like 4th Monday of January, you can inherit the + [HolidayBase][holidays.holiday_base.HolidayBase] class and define your own `_populate()` + method. + See documentation for examples. + """ + + country: str + """The country's ISO 3166-1 alpha-2 code.""" + market: str + """The market's ISO 3166-1 alpha-2 code.""" + subdivisions: tuple[str, ...] = () + """The subdivisions supported for this country (see documentation).""" + subdivisions_aliases: dict[str, str] = {} + """Aliases for the ISO 3166-2 subdivision codes with the key as alias and + the value the ISO 3166-2 subdivision code.""" + years: set[int] + """The years calculated.""" + expand: bool + """Whether the entire year is calculated when one date from that year + is requested.""" + observed: bool + """Whether dates when public holiday are observed are included.""" + subdiv: Optional[str] = None + """The subdiv requested as ISO 3166-2 code or one of the aliases.""" + special_holidays: dict[int, Union[SpecialHoliday, SubstitutedHoliday]] = {} + """A list of the country-wide special (as opposite to regular) holidays for + a specific year.""" + _deprecated_subdivisions: tuple[str, ...] = () + """Other subdivisions whose names are deprecated or aliases of the official + ones.""" + weekend: set[int] = {SAT, SUN} + """Country weekend days.""" + weekend_workdays: set[date] + """Working days moved to weekends.""" + default_category: str = PUBLIC + """The entity category used by default.""" + default_language: Optional[str] = None + """The entity language used by default.""" + categories: set[str] = set() + """Requested holiday categories.""" + supported_categories: tuple[str, ...] = (PUBLIC,) + """All holiday categories supported by this entity.""" + supported_languages: tuple[str, ...] = () + """All languages supported by this entity.""" + start_year: int = DEFAULT_START_YEAR + """Start year of holidays presence for this entity.""" + end_year: int = DEFAULT_END_YEAR + """End year of holidays presence for this entity.""" + parent_entity: Optional[type["HolidayBase"]] = None + """Optional parent entity to reference as a base.""" + + def __init__( + self, + years: Optional[YearArg] = None, + expand: bool = True, + observed: bool = True, + subdiv: Optional[str] = None, + prov: Optional[str] = None, # Deprecated. + state: Optional[str] = None, # Deprecated. + language: Optional[str] = None, + categories: Optional[CategoryArg] = None, + ) -> None: + """ + Args: + years: + The year(s) to pre-calculate public holidays for at instantiation. + + expand: + Whether the entire year is calculated when one date from that year + is requested. + + observed: + Whether to include the dates when public holiday are observed + (e.g. a holiday falling on a Sunday being observed the + following Monday). This doesn't work for all countries. + + subdiv: + The subdivision (e.g. state or province) as a ISO 3166-2 code + or its alias; not implemented for all countries (see documentation). + + prov: + *deprecated* use `subdiv` instead. + + state: + *deprecated* use `subdiv` instead. + + language: + Specifies the language in which holiday names are returned. + + Accepts either: + + * A two-letter ISO 639-1 language code (e.g., 'en' for English, 'fr' for French), + or + * A language and entity combination using an underscore (e.g., 'en_US' for U.S. + English, 'pt_BR' for Brazilian Portuguese). + + !!! warning + The provided language or locale code must be supported by the holiday + entity. Unsupported values will result in names being shown in the entity's + original language. + + If not explicitly set (`language=None`), the system attempts to infer the + language from the environment's locale settings. The following environment + variables are checked, in order of precedence: LANGUAGE, LC_ALL, LC_MESSAGES, LANG. + + If none of these are set or they are empty, holiday names will default to the + original language of the entity's holiday implementation. + + !!! warning + This fallback mechanism may yield inconsistent results across environments + (e.g., between a terminal session and a Jupyter notebook). + + To ensure consistent behavior, it is recommended to set the language parameter + explicitly. If the specified language is not supported, holiday names will remain + in the original language of the entity's holiday implementation. + + This behavior will be updated and formalized in v1. + + categories: + Requested holiday categories. + + Returns: + A `HolidayBase` object matching the **country** or **market**. + """ + super().__init__() + + # Categories validation. + if self.default_category and self.default_category not in self.supported_categories: + raise ValueError("The default category must be listed in supported categories.") + + if not self.default_category and not categories: + raise ValueError("Categories cannot be empty if `default_category` is not set.") + + categories = _normalize_arguments(str, categories) or {self.default_category} + if unknown_categories := categories.difference( # type: ignore[union-attr] + self.supported_categories + ): + raise ValueError(f"Category is not supported: {', '.join(unknown_categories)}.") + + # Subdivision validation. + if subdiv := subdiv or prov or state: + # Handle subdivisions passed as integers. + if isinstance(subdiv, int): + subdiv = str(subdiv) + + subdivision_aliases = tuple(self.subdivisions_aliases) + supported_subdivisions = set( + self.subdivisions + + subdivision_aliases + + self._deprecated_subdivisions + + (self.parent_entity.subdivisions if self.parent_entity else ()) + ) + + # Unsupported subdivisions. + if not isinstance(self, HolidaySum) and subdiv not in supported_subdivisions: + raise NotImplementedError( + f"Entity `{self._entity_code}` does not have subdivision {subdiv}" + ) + + # Deprecated arguments. + if prov_state := prov or state: + warnings.warn( + f"Arguments prov and state are deprecated, use subdiv='{prov_state}' instead.", + DeprecationWarning, + ) + + # Deprecated subdivisions. + if subdiv in self._deprecated_subdivisions: + warnings.warn( + "This subdivision is deprecated and will be removed after " + "Dec, 1 2023. The list of supported subdivisions: " + f"{', '.join(sorted(self.subdivisions))}; " + "the list of supported subdivisions aliases: " + f"{', '.join(sorted(subdivision_aliases))}.", + DeprecationWarning, + ) + + # Special holidays validation. + if (has_substituted_holidays := getattr(self, "has_substituted_holidays", False)) and ( + not getattr(self, "substituted_label", None) + or not getattr(self, "substituted_date_format", None) + ): + raise ValueError( + f"Entity `{self._entity_code}` class must have `substituted_label` " + "and `substituted_date_format` attributes set." + ) + + self.categories = categories + self.expand = expand + self.has_special_holidays = getattr(self, "has_special_holidays", False) + self.has_substituted_holidays = has_substituted_holidays + self.language = language + self.observed = observed + self.subdiv = subdiv + self.weekend_workdays = getattr(self, "weekend_workdays", set()) + self.years = _normalize_arguments(int, years) + + # Configure l10n related attributes. + self._init_translation() + + # Populate holidays. + for year in self.years: + self._populate(year) + + def __add__(self, other: Union[int, "HolidayBase", "HolidaySum"]) -> "HolidayBase": + """Add another dictionary of public holidays creating a + [HolidaySum][holidays.holiday_base.HolidaySum] object. + + Args: + other: + The dictionary of public holiday to be added. + + Returns: + A `HolidayBase` object unless the other object cannot be added, then `self`. + """ + if isinstance(other, int) and other == 0: + # Required to sum() list of holidays + # sum([h1, h2]) is equivalent to (0 + h1 + h2). + return self + + if not isinstance(other, (HolidayBase, HolidaySum)): + raise TypeError("Holiday objects can only be added with other Holiday objects") + + return HolidaySum(self, other) + + def __bool__(self) -> bool: + return len(self) > 0 + + def __contains__(self, key: object) -> bool: + """Check if a given date is a holiday. + + The method supports the following input types: + + * `datetime.date`, + * `datetime.datetime`, + * a `str` of any format recognized by `dateutil.parser.parse()`, + * or a `float` or `int` representing a POSIX timestamp. + + Args: + key: + The date to check. + + Returns: + `True` if the date is a holiday, `False` otherwise. + """ + + if not isinstance(key, (date, datetime, float, int, str)): + raise TypeError(f"Cannot convert type '{type(key)}' to date.") + + return dict.__contains__(cast("dict[Any, Any]", self), self.__keytransform__(key)) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, HolidayBase): + return False + + for attribute_name in self.__attribute_names: + if getattr(self, attribute_name, None) != getattr(other, attribute_name, None): + return False + + return dict.__eq__(cast("dict[Any, Any]", self), other) + + def __getattr__(self, name): + try: + return self.__getattribute__(name) + except AttributeError as e: + # This part is responsible for _add_holiday_* syntactic sugar support. + add_holiday_prefix = "_add_holiday_" + # Raise early if prefix doesn't match to avoid patterns checks. + if name[: len(add_holiday_prefix)] != add_holiday_prefix: + raise e + + tokens = name.split("_") + + # Handle patterns (e.g., _add_holiday_jun_15()). + if len(tokens) == 5: + *_, month, day = tokens + if month in MONTHS and day in DAYS: + return lambda name: self._add_holiday( + name, date(self._year, MONTHS[month], int(day)) + ) + + elif len(tokens) == 7: + # Handle of patterns (e.g., + # _add_holiday_last_mon_of_aug() or _add_holiday_3rd_fri_of_aug()). + *_, number, weekday, of, month = tokens + if ( + of == "of" + and (number == "last" or number[0].isdigit()) + and month in MONTHS + and weekday in WEEKDAYS + ): + return lambda name: self._add_holiday( + name, + _get_nth_weekday_of_month( + -1 if number == "last" else int(number[0]), + WEEKDAYS[weekday], + MONTHS[month], + self._year, + ), + ) + + # Handle days easter patterns (e.g., + # _add_holiday_8_days_past_easter() or + # _add_holiday_5_days_prior_easter()). + *_, days, unit, delta_direction, easter = tokens + if ( + unit in {"day", "days"} + and delta_direction in {"past", "prior"} + and easter == "easter" + and len(days) < 3 + and days.isdigit() + ): + return lambda name: self._add_holiday( + name, + _timedelta( + self._easter_sunday, + +int(days) if delta_direction == "past" else -int(days), + ), + ) + + # Handle day(s) of patterns (e.g., + # _add_holiday_1_day_past_1st_fri_of_aug() or + # _add_holiday_5_days_prior_last_fri_of_aug()). + elif len(tokens) == 10: + *_, days, unit, delta_direction, number, weekday, of, month = tokens + if ( + unit in {"day", "days"} + and delta_direction in {"past", "prior"} + and of == "of" + and len(days) < 3 + and days.isdigit() + and (number == "last" or number[0].isdigit()) + and month in MONTHS + and weekday in WEEKDAYS + ): + return lambda name: self._add_holiday( + name, + _timedelta( + _get_nth_weekday_of_month( + -1 if number == "last" else int(number[0]), + WEEKDAYS[weekday], + MONTHS[month], + self._year, + ), + +int(days) if delta_direction == "past" else -int(days), + ), + ) + + # Handle patterns (e.g., + # _add_holiday_1st_mon_before_jun_15() or _add_holiday_1st_mon_from_jun_15()). + elif len(tokens) == 8: + *_, number, weekday, date_direction, month, day = tokens + if ( + date_direction in {"before", "from"} + and number[0].isdigit() + and month in MONTHS + and weekday in WEEKDAYS + and day in DAYS + ): + return lambda name: self._add_holiday( + name, + _get_nth_weekday_from( + -int(number[0]) if date_direction == "before" else +int(number[0]), + WEEKDAYS[weekday], + date(self._year, MONTHS[month], int(day)), + ), + ) + + raise e # No match. + + def __getitem__(self, key: DateLike) -> Any: + if isinstance(key, slice): + if not key.start or not key.stop: + raise ValueError("Both start and stop must be given.") + + start = self.__keytransform__(key.start) + stop = self.__keytransform__(key.stop) + + if key.step is None: + step = 1 + elif isinstance(key.step, timedelta): + step = key.step.days + elif isinstance(key.step, int): + step = key.step + else: + raise TypeError(f"Cannot convert type '{type(key.step)}' to int.") + + if step == 0: + raise ValueError("Step value must not be zero.") + + date_diff = stop - start + if date_diff.days < 0 <= step or date_diff.days >= 0 > step: + step *= -1 + + days_in_range = [] + for delta_days in range(0, date_diff.days, step): + day = _timedelta(start, delta_days) + if day in self: + days_in_range.append(day) + + return days_in_range + + return dict.__getitem__(self, self.__keytransform__(key)) + + def __getstate__(self) -> dict[str, Any]: + """Return the object's state for serialization.""" + state = self.__dict__.copy() + state.pop("tr", None) + return state + + def __keytransform__(self, key: DateLike) -> date: + """Convert various date-like formats to `datetime.date`. + + The method supports the following input types: + * `datetime.date`, + * `datetime.datetime`, + * a `str` of any format recognized by `dateutil.parser.parse()`, + * or a `float` or `int` representing a POSIX timestamp + + Args: + key: + The date-like object to convert. + + Returns: + The corresponding `datetime.date` representation. + """ + + dt: Optional[date] = None + # Try to catch `date` and `str` type keys first. + # Using type() here to skip date subclasses. + # Key is `date`. + if type(key) is date: + dt = key + + # Key is `str` instance. + elif isinstance(key, str): + # key possibly contains a date in YYYY-MM-DD or YYYYMMDD format. + if len(key) in {8, 10}: + try: + dt = date.fromisoformat(key) + except ValueError: + pass + if dt is None: + try: + dt = parse(key).date() + except (OverflowError, ValueError): + raise ValueError(f"Cannot parse date from string '{key}'") + + # Key is `datetime` instance. + elif isinstance(key, datetime): + dt = key.date() + + # Must go after the `isinstance(key, datetime)` check as datetime is `date` subclass. + elif isinstance(key, date): + dt = key + + # Key is `float` or `int` instance. + elif isinstance(key, (float, int)): + dt = datetime.fromtimestamp(key, timezone.utc).date() + + # Key is not supported. + else: + raise TypeError(f"Cannot convert type '{type(key)}' to date.") + + # Automatically expand for `expand=True` cases. + if self.expand and dt.year not in self.years: + self.years.add(dt.year) + self._populate(dt.year) + + return dt + + def __ne__(self, other: object) -> bool: + if not isinstance(other, HolidayBase): + return True + + for attribute_name in self.__attribute_names: + if getattr(self, attribute_name, None) != getattr(other, attribute_name, None): + return True + + return dict.__ne__(self, other) + + def __radd__(self, other: Any) -> "HolidayBase": + return self.__add__(other) + + def __reduce__(self) -> Union[str, tuple[Any, ...]]: + return super().__reduce__() + + def __repr__(self) -> str: + if self: + return super().__repr__() + + parts = [] + if hasattr(self, "market"): + parts.append(f"holidays.financial_holidays({self.market!r}") + parts.append(")") + elif hasattr(self, "country"): + parts.append(f"holidays.country_holidays({self.country!r}") + if self.subdiv: + parts.append(f", subdiv={self.subdiv!r}") + parts.append(")") + else: + parts.append("holidays.HolidayBase()") + + return "".join(parts) + + def __setattr__(self, key: str, value: Any) -> None: + dict.__setattr__(self, key, value) + + if self and key in {"categories", "observed"}: + self.clear() + for year in self.years: # Re-populate holidays for each year. + self._populate(year) + + def __setitem__(self, key: DateLike, value: str) -> None: + if key in self: + # If there are multiple holidays on the same date + # order their names alphabetically. + holiday_names = set(self[key].split(HOLIDAY_NAME_DELIMITER)) + holiday_names.update(value.split(HOLIDAY_NAME_DELIMITER)) + value = HOLIDAY_NAME_DELIMITER.join(sorted(holiday_names)) + + dict.__setitem__(self, self.__keytransform__(key), value) + + def __setstate__(self, state: dict[str, Any]) -> None: + """Restore the object's state after deserialization.""" + self.__dict__.update(state) + self._init_translation() + + def __str__(self) -> str: + if self: + return super().__str__() + + parts = ( + f"'{attribute_name}': {getattr(self, attribute_name, None)}" + for attribute_name in self.__attribute_names + ) + + return f"{{{', '.join(parts)}}}" + + @property + def __attribute_names(self): + return ("country", "expand", "language", "market", "observed", "subdiv", "years") + + @cached_property + def _entity_code(self): + return getattr(self, "country", getattr(self, "market", None)) + + @cached_property + def _normalized_subdiv(self): + return ( + self.subdivisions_aliases.get(self.subdiv, self.subdiv) + .translate( + str.maketrans( + { + "-": "_", + " ": "_", + } + ) + ) + .lower() + ) + + @property + def _sorted_categories(self): + return ( + [self.default_category] + sorted(self.categories - {self.default_category}) + if self.default_category in self.categories + else sorted(self.categories) + ) + + @classmethod + def get_subdivision_aliases(cls) -> dict[str, list]: + """Get subdivision aliases. + + Returns: + A dictionary mapping subdivision aliases to their official ISO 3166-2 codes. + """ + subdivision_aliases: dict[str, list[str]] = {s: [] for s in cls.subdivisions} + for alias, subdivision in cls.subdivisions_aliases.items(): + subdivision_aliases[subdivision].append(alias) + + return subdivision_aliases + + def _init_translation(self) -> None: + """Initialize translation function based on language settings.""" + supported_languages = set(self.supported_languages) + if self._entity_code is not None: + fallback = self.language not in supported_languages + languages = [self.language] if self.language in supported_languages else None + locale_directory = str(Path(__file__).with_name("locale")) + + # Add entity native content translations. + entity_translation = translation( + self._entity_code, + fallback=fallback, + languages=languages, + localedir=locale_directory, + ) + # Add a fallback if entity has parent translations. + if parent_entity := self.parent_entity: + entity_translation.add_fallback( + translation( + parent_entity.country or parent_entity.market, + fallback=fallback, + languages=languages, + localedir=locale_directory, + ) + ) + self.tr = entity_translation.gettext + else: + self.tr = gettext + + def _is_leap_year(self) -> bool: + """ + Returns True if the year is leap. Returns False otherwise. + """ + return isleap(self._year) + + def _add_holiday(self, name: str, *args) -> Optional[date]: + """Add a holiday.""" + if not args: + raise TypeError("Incorrect number of arguments.") + + dt = args if len(args) > 1 else args[0] + dt = dt if isinstance(dt, date) else date(self._year, *dt) + + if dt.year != self._year: + return None + + self[dt] = self.tr(name) + return dt + + def _add_special_holidays(self, mapping_names, observed=False): + """Add special holidays.""" + for mapping_name in mapping_names: + for data in _normalize_tuple(getattr(self, mapping_name, {}).get(self._year, ())): + if len(data) == 3: # Special holidays. + month, day, name = data + self._add_holiday( + self.tr(self.observed_label) % self.tr(name) + if observed + else self.tr(name), + month, + day, + ) + else: # Substituted holidays. + to_month, to_day, from_month, from_day, *optional = data + from_date = date(optional[0] if optional else self._year, from_month, from_day) + self._add_holiday( + self.tr(self.substituted_label) + % from_date.strftime(self.tr(self.substituted_date_format)), + to_month, + to_day, + ) + self.weekend_workdays.add(from_date) + + def _check_weekday(self, weekday: int, *args) -> bool: + """ + Returns True if `weekday` equals to the date's week day. + Returns False otherwise. + """ + dt = args if len(args) > 1 else args[0] + dt = dt if isinstance(dt, date) else date(self._year, *dt) + return dt.weekday() == weekday + + def _is_monday(self, *args) -> bool: + return self._check_weekday(MON, *args) + + def _is_tuesday(self, *args) -> bool: + return self._check_weekday(TUE, *args) + + def _is_wednesday(self, *args) -> bool: + return self._check_weekday(WED, *args) + + def _is_thursday(self, *args) -> bool: + return self._check_weekday(THU, *args) + + def _is_friday(self, *args) -> bool: + return self._check_weekday(FRI, *args) + + def _is_saturday(self, *args) -> bool: + return self._check_weekday(SAT, *args) + + def _is_sunday(self, *args) -> bool: + return self._check_weekday(SUN, *args) + + def _is_weekend(self, *args): + """ + Returns True if date's week day is a weekend day. + Returns False otherwise. + """ + dt = args if len(args) > 1 else args[0] + dt = dt if isinstance(dt, date) else date(self._year, *dt) + return dt.weekday() in self.weekend + + def _populate(self, year: int) -> None: + """This is a private class that populates (generates and adds) holidays + for a given year. To keep things fast, it assumes that no holidays for + the year have already been populated. It is required to be called + internally by any country populate() method, while should not be called + directly from outside. + To add holidays to an object, use the update() method. + + Args: + year: The year to populate with holidays. + + >>> from holidays import country_holidays + >>> us_holidays = country_holidays('US', years=2020) + # to add new holidays to the object: + >>> us_holidays.update(country_holidays('US', years=2021)) + """ + + if year < self.start_year or year > self.end_year: + return None + + self._year = year + self._populate_common_holidays() + self._populate_subdiv_holidays() + + def _populate_common_holidays(self): + """Populate entity common holidays.""" + for category in self._sorted_categories: + if pch_method := getattr(self, f"_populate_{category.lower()}_holidays", None): + pch_method() + + if self.has_special_holidays: + self._add_special_holidays( + f"special_{category}_holidays" for category in self._sorted_categories + ) + + def _populate_subdiv_holidays(self): + """Populate entity subdivision holidays.""" + if self.subdiv is None: + return None + + for category in self._sorted_categories: + if asch_method := getattr( + self, + f"_populate_subdiv_{self._normalized_subdiv}_{category.lower()}_holidays", + None, + ): + asch_method() + + if self.has_special_holidays: + self._add_special_holidays( + f"special_{self._normalized_subdiv}_{category.lower()}_holidays" + for category in self._sorted_categories + ) + + def append(self, *args: Union[dict[DateLike, str], list[DateLike], DateLike]) -> None: + """Alias for [update()][holidays.holiday_base.HolidayBase.update] to mimic list type. + + Args: + args: + Holiday data to add. Can be: + + * A dictionary mapping dates to holiday names. + * A list of dates (without names). + * A single date. + """ + return self.update(*args) + + def copy(self): + """Return a copy of the object.""" + return copy.copy(self) + + def get(self, key: DateLike, default: Union[str, Any] = None) -> Union[str, Any]: + """Retrieve the holiday name(s) for a given date. + + If the date is a holiday, returns the holiday name as a string. + If multiple holidays fall on the same date, their names are joined by a semicolon (`;`). + If the date is not a holiday, returns the provided `default` value (defaults to `None`). + + Args: + key: + The date expressed in one of the following types: + + * `datetime.date`, + * `datetime.datetime`, + * a `str` of any format recognized by `dateutil.parser.parse()`, + * or a `float` or `int` representing a POSIX timestamp. + + default: + The default value to return if no value is found. + + Returns: + The holiday name(s) as a string if the date is a holiday, + or the `default` value otherwise. + """ + return dict.get(self, self.__keytransform__(key), default) + + def get_list(self, key: DateLike) -> list[str]: + """Retrieve all holiday names for a given date. + + Args: + key: + The date expressed in one of the following types: + + * `datetime.date`, + * `datetime.datetime`, + * a `str` of any format recognized by `dateutil.parser.parse()`, + * or a `float` or `int` representing a POSIX timestamp. + + Returns: + A list of holiday names if the date is a holiday, otherwise an empty list. + """ + return [name for name in self.get(key, "").split(HOLIDAY_NAME_DELIMITER) if name] + + def get_named( + self, holiday_name: str, lookup: str = "icontains", split_multiple_names: bool = True + ) -> list[date]: + """Find all holiday dates matching a given name. + + The search by default is case-insensitive and includes partial matches. + + Args: + holiday_name: + The holiday's name to try to match. + + lookup: + The holiday name lookup type: + + * contains - case sensitive contains match; + * exact - case sensitive exact match; + * startswith - case sensitive starts with match; + * icontains - case insensitive contains match; + * iexact - case insensitive exact match; + * istartswith - case insensitive starts with match; + + split_multiple_names: + Either use the exact name for each date or split it by holiday + name delimiter. + + Returns: + A list of all holiday dates matching the provided holiday name. + """ + holiday_name_dates = ( + ((k, name) for k, v in self.items() for name in v.split(HOLIDAY_NAME_DELIMITER)) + if split_multiple_names + else ((k, v) for k, v in self.items()) + ) + + if lookup == "icontains": + holiday_name_lower = holiday_name.lower() + return [dt for dt, name in holiday_name_dates if holiday_name_lower in name.lower()] + elif lookup == "exact": + return [dt for dt, name in holiday_name_dates if holiday_name == name] + elif lookup == "contains": + return [dt for dt, name in holiday_name_dates if holiday_name in name] + elif lookup == "startswith": + return [ + dt for dt, name in holiday_name_dates if holiday_name == name[: len(holiday_name)] + ] + elif lookup == "iexact": + holiday_name_lower = holiday_name.lower() + return [dt for dt, name in holiday_name_dates if holiday_name_lower == name.lower()] + elif lookup == "istartswith": + holiday_name_lower = holiday_name.lower() + return [ + dt + for dt, name in holiday_name_dates + if holiday_name_lower == name[: len(holiday_name)].lower() + ] + + raise AttributeError(f"Unknown lookup type: {lookup}") + + def get_closest_holiday( + self, + target_date: Optional[DateLike] = None, + direction: Literal["forward", "backward"] = "forward", + ) -> Optional[tuple[date, str]]: + """Find the closest holiday relative to a given date. + + If `direction` is "forward", returns the next holiday after `target_date`. + If `direction` is "backward", returns the previous holiday before `target_date`. + If `target_date` is not provided, the current date is used. + + Args: + target_date: + The reference date. If None, defaults to today. + + direction: + Search direction, either "forward" (next holiday) or + "backward" (previous holiday). + + Returns: + A tuple containing the holiday date and its name, or None if no holiday is found. + """ + if direction not in {"backward", "forward"}: + raise AttributeError(f"Unknown direction: {direction}") + + dt = self.__keytransform__(target_date or datetime.now().date()) + if direction == "forward" and (next_year := dt.year + 1) not in self.years: + self._populate(next_year) + elif direction == "backward" and (previous_year := dt.year - 1) not in self.years: + self._populate(previous_year) + + sorted_dates = sorted(self.keys()) + position = ( + bisect_right(sorted_dates, dt) + if direction == "forward" + else bisect_left(sorted_dates, dt) - 1 + ) + if 0 <= position < len(sorted_dates): + dt = sorted_dates[position] + return dt, self[dt] + + return None + + def get_nth_working_day(self, key: DateLike, n: int) -> date: + """Find the n-th working day from a given date. + + Moves forward if n is positive, or backward if n is negative. + + Args: + key: + The starting date. + + n: + The number of working days to move. Positive values move forward, + negative values move backward. + + Returns: + The calculated working day after shifting by n working days. + """ + direction = +1 if n > 0 else -1 + dt = self.__keytransform__(key) + for _ in range(abs(n)): + dt = _timedelta(dt, direction) + while not self.is_working_day(dt): + dt = _timedelta(dt, direction) + return dt + + def get_working_days_count(self, start: DateLike, end: DateLike) -> int: + """Calculate the number of working days between two dates. + + The date range works in a closed interval fashion [start, end] so both + endpoints are included. + + Args: + start: + The range start date. + + end: + The range end date. + + Returns: + The total count of working days between the given dates. + """ + dt1 = self.__keytransform__(start) + dt2 = self.__keytransform__(end) + if dt1 > dt2: + dt1, dt2 = dt2, dt1 + days = (dt2 - dt1).days + 1 + return sum(self.is_working_day(_timedelta(dt1, n)) for n in range(days)) + + def is_working_day(self, key: DateLike) -> bool: + """Check if the given date is considered a working day. + + Args: + key: + The date to check. + + Returns: + True if the date is a working day, False if it is a holiday or weekend. + """ + dt = self.__keytransform__(key) + return dt in self.weekend_workdays if self._is_weekend(dt) else dt not in self + + def pop(self, key: DateLike, default: Union[str, Any] = None) -> Union[str, Any]: + """Remove a holiday for a given date and return its name. + + If the specified date is a holiday, it will be removed, and its name will + be returned. If the date is not a holiday, the provided `default` value + will be returned instead. + + Args: + key: + The date expressed in one of the following types: + + * `datetime.date`, + * `datetime.datetime`, + * a `str` of any format recognized by `dateutil.parser.parse()`, + * or a `float` or `int` representing a POSIX timestamp. + + default: + The default value to return if no match is found. + + Returns: + The name of the removed holiday if the date was a holiday, otherwise + the provided `default` value. + + Raises: + KeyError: if date is not a holiday and default is not given. + """ + if default is None: + return dict.pop(self, self.__keytransform__(key)) + + return dict.pop(self, self.__keytransform__(key), default) + + def pop_named(self, holiday_name: str, lookup: str = "icontains") -> list[date]: + """Remove all holidays matching the given name. + + This method removes all dates associated with a holiday name, so they are + no longer considered holidays. The search by default is case-insensitive and + includes partial matches. + + Args: + holiday_name: + The holiday's name to try to match. + + lookup: + The holiday name lookup type: + + * contains - case sensitive contains match; + * exact - case sensitive exact match; + * startswith - case sensitive starts with match; + * icontains - case insensitive contains match; + * iexact - case insensitive exact match; + * istartswith - case insensitive starts with match; + + Returns: + A list of dates removed. + + Raises: + KeyError: if date is not a holiday. + """ + use_exact_name = HOLIDAY_NAME_DELIMITER in holiday_name + if not ( + dts := self.get_named( + holiday_name, lookup=lookup, split_multiple_names=not use_exact_name + ) + ): + raise KeyError(holiday_name) + + popped = [] + for dt in dts: + holiday_names = self[dt].split(HOLIDAY_NAME_DELIMITER) + self.pop(dt) + popped.append(dt) + + # Keep the rest of holidays falling on the same date. + if use_exact_name: + continue + if lookup == "icontains": + holiday_name_lower = holiday_name.lower() + holiday_names = [ + name for name in holiday_names if holiday_name_lower not in name.lower() + ] + elif lookup == "iexact": + holiday_name_lower = holiday_name.lower() + holiday_names = [ + name for name in holiday_names if holiday_name_lower != name.lower() + ] + elif lookup == "istartswith": + holiday_name_lower = holiday_name.lower() + holiday_names = [ + name + for name in holiday_names + if holiday_name_lower != name[: len(holiday_name)].lower() + ] + elif lookup == "contains": + holiday_names = [name for name in holiday_names if holiday_name not in name] + elif lookup == "exact": + holiday_names = [name for name in holiday_names if holiday_name != name] + else: # startswith + holiday_names = [ + name for name in holiday_names if holiday_name != name[: len(holiday_name)] + ] + if holiday_names: + self[dt] = HOLIDAY_NAME_DELIMITER.join(holiday_names) + + return popped + + def update( # type: ignore[override] + self, *args: Union[dict[DateLike, str], list[DateLike], DateLike] + ) -> None: + """Update the object, overwriting existing dates. + + Args: + args: + Either another dictionary object where keys are dates and values + are holiday names, or a single date (or a list of dates) for which + the value will be set to "Holiday". + + Dates can be expressed in one or more of the following types: + + * `datetime.date`, + * `datetime.datetime`, + * a `str` of any format recognized by `dateutil.parser.parse()`, + * or a `float` or `int` representing a POSIX timestamp. + """ + for arg in args: + if isinstance(arg, dict): + for key, value in arg.items(): + self[key] = value + elif isinstance(arg, list): + for item in arg: + self[item] = "Holiday" + else: + self[arg] = "Holiday" + + +class HolidaySum(HolidayBase): + """ + Returns a `dict`-like object resulting from the addition of two or + more individual dictionaries of public holidays. The original dictionaries + are available as a `list` in the attribute `holidays,` and + `country` and `subdiv` attributes are added + together and could become `list` s. Holiday names, when different, + are merged. All years are calculated (expanded) for all operands. + """ + + country: Union[str, list[str]] # type: ignore[assignment] + """Countries included in the addition.""" + market: Union[str, list[str]] # type: ignore[assignment] + """Markets included in the addition.""" + subdiv: Optional[Union[str, list[str]]] # type: ignore[assignment] + """Subdivisions included in the addition.""" + holidays: list[HolidayBase] + """The original HolidayBase objects included in the addition.""" + years: set[int] + """The years calculated.""" + + def __init__( + self, h1: Union[HolidayBase, "HolidaySum"], h2: Union[HolidayBase, "HolidaySum"] + ) -> None: + """ + Args: + h1: + The first HolidayBase object to add. + + h2: + The other HolidayBase object to add. + + Example: + + >>> from holidays import country_holidays + >>> nafta_holidays = country_holidays('US', years=2020) + \ + country_holidays('CA') + country_holidays('MX') + >>> dates = sorted(nafta_holidays.items(), key=lambda x: x[0]) + >>> from pprint import pprint + >>> pprint(dates[:10], width=72) + [(datetime.date(2020, 1, 1), "Año Nuevo; New Year's Day"), + (datetime.date(2020, 1, 20), 'Martin Luther King Jr. Day'), + (datetime.date(2020, 2, 3), 'Día de la Constitución'), + (datetime.date(2020, 2, 17), "Washington's Birthday"), + (datetime.date(2020, 3, 16), 'Natalicio de Benito Juárez'), + (datetime.date(2020, 4, 10), 'Good Friday'), + (datetime.date(2020, 5, 1), 'Día del Trabajo'), + (datetime.date(2020, 5, 25), 'Memorial Day'), + (datetime.date(2020, 7, 1), 'Canada Day'), + (datetime.date(2020, 7, 3), 'Independence Day (observed)')] + """ + # Store originals in the holidays attribute. + self.holidays = [] + for operand in (h1, h2): + if isinstance(operand, HolidaySum): + self.holidays.extend(operand.holidays) + else: + self.holidays.append(operand) + + kwargs: dict[str, Any] = {} + # Join years, expand and observed. + kwargs["years"] = h1.years | h2.years + kwargs["expand"] = h1.expand or h2.expand + kwargs["observed"] = h1.observed or h2.observed + # Join country and subdivisions data. + # TODO: this way makes no sense: joining Italy Catania (IT, CA) with + # USA Mississippi (US, MS) and USA Michigan (US, MI) yields + # country=["IT", "US"] and subdiv=["CA", "MS", "MI"], which could very + # well be California and Messina and Milano, or Catania, Mississippi + # and Milano, or ... you get the picture. + # Same goes when countries and markets are being mixed (working, yet + # still nonsensical). + for attr in ("country", "market", "subdiv"): + if ( + getattr(h1, attr, None) + and getattr(h2, attr, None) + and getattr(h1, attr) != getattr(h2, attr) + ): + a1 = ( + getattr(h1, attr) + if isinstance(getattr(h1, attr), list) + else [getattr(h1, attr)] + ) + a2 = ( + getattr(h2, attr) + if isinstance(getattr(h2, attr), list) + else [getattr(h2, attr)] + ) + value = a1 + a2 + else: + value = getattr(h1, attr, None) or getattr(h2, attr, None) + + if attr == "subdiv": + kwargs[attr] = value + else: + setattr(self, attr, value) + + # Retain language if they match and are strings. + # If language wasn't assigned, default_language acts as fallback. + h1_language = h1.language or h1.default_language + h2_language = h2.language or h2.default_language + if isinstance(h1_language, str) and h1_language == h2_language: + kwargs["language"] = h1_language + + HolidayBase.__init__(self, **kwargs) + + # supported_languages is used for iCalExporter language check as well. + self.supported_languages = (h1_language,) if h1_language else () + + def _populate(self, year): + for operand in self.holidays: + operand._populate(year) + self.update(cast("dict[DateLike, str]", operand)) diff --git a/.venv/lib/python3.12/site-packages/holidays/ical.py b/.venv/lib/python3.12/site-packages/holidays/ical.py new file mode 100644 index 00000000..350bb451 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/ical.py @@ -0,0 +1,228 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +import re +import uuid +from datetime import date, datetime, timedelta, timezone +from typing import Union + +from holidays.holiday_base import HolidayBase +from holidays.version import __version__ + +# iCal-specific constants +CONTENT_LINE_MAX_LENGTH = 75 +CONTENT_LINE_DELIMITER = "\r\n" +CONTENT_LINE_DELIMITER_WRAP = f"{CONTENT_LINE_DELIMITER} " + + +class ICalExporter: + def __init__(self, instance: HolidayBase, show_language: bool = False) -> None: + """Initialize iCalendar exporter. + + Args: + show_language: + Determines whether to include the `;LANGUAGE=` attribute in the + `SUMMARY` field. Defaults to `False`. + + If the `HolidaysBase` object has a `language` attribute, it will + be used. Otherwise, `default_language` will be used if available. + + If neither attribute exists and `show_language=True`, an + exception will be raised. + + instance: + `HolidaysBase` object containing holiday data. + """ + self.holidays = instance + self.show_language = show_language + self.ical_timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ") + self.holidays_version = __version__ + language = getattr(self.holidays, "language", None) or getattr( + self.holidays, "default_language", None + ) + self.language = ( + self._validate_language(language) + if isinstance(language, str) + and language in getattr(self.holidays, "supported_languages", []) + else None + ) + + if self.show_language and self.language is None: + raise ValueError("LANGUAGE cannot be included because the language code is missing.") + + def _validate_language(self, language: str) -> str: + """Validate the language code to ensure it complies with RFC 5646. + + In the current implementation, all languages must comply with + either ISO 639-1 or ISO 639-2 if specified (part of RFC 5646). + + Args: + language: + The language code to validate. + + Returns: + Validated language code. + """ + # Remove whitespace (if any), transforms HolidaysBase default to RFC 5646 compliant + # i.e. `en_US` to `en-US`. + language = language.strip().replace("_", "-") + + # ISO 639-1 and ISO 639-2 patterns, in compliance with RFC 5646. + iso639_pattern = re.compile(r"^[a-z]{2,3}(?:-[A-Z]{2})?$") + + if not iso639_pattern.fullmatch(language): + raise ValueError( + f"Invalid language tag: '{language}'. Expected format follows " + "ISO 639-1 or ISO 639-2, e.g., 'en', 'en-US'. For more details, " + "refer to: https://www.loc.gov/standards/iso639-2/php/code_list.php." + ) + return language + + def _fold_line(self, line: str) -> str: + """Fold long lines according to RFC 5545. + + Content lines SHOULD NOT exceed 75 octets. If a line is too long, + it must be split into multiple lines, with each continuation line + starting with a space. + + Args: + line: + The content line to be folded. + + Returns: + The folded content line. + """ + if line.isascii(): + # Simple split for ASCII: every (CONTENT_LINE_MAX_LENGTH - 1) chars, + # as first char of the next line is space + if len(line) > CONTENT_LINE_MAX_LENGTH: + return CONTENT_LINE_DELIMITER_WRAP.join( + line[i : i + CONTENT_LINE_MAX_LENGTH - 1] + for i in range(0, len(line), CONTENT_LINE_MAX_LENGTH - 1) + ) + + elif len(line.encode()) > CONTENT_LINE_MAX_LENGTH: + # Handle non-ASCII text while respecting byte length + parts = [] + part_start = 0 + part_len = 0 + for i, char in enumerate(line): + char_byte_len = len(char.encode()) + part_len += char_byte_len + + if part_len > CONTENT_LINE_MAX_LENGTH: + parts.append(line[part_start:i]) + part_start = i + part_len = char_byte_len + 1 # line start with space + + parts.append(line[part_start:]) + return CONTENT_LINE_DELIMITER_WRAP.join(parts) + + # Return as-is if it doesn't exceed the limit + return line + + def _generate_event(self, dt: date, holiday_name: str, holiday_length: int = 1) -> list[str]: + """Generate a single holiday event. + + Args: + dt: + Holiday date. + + holiday_name: + Holiday name. + + holiday_length: + Holiday length in days, default to 1. + + Returns: + List of iCalendar format event lines. + """ + # Escape special characters per RFC 5545. + # SEMICOLON is used as a delimiter in HolidayBase (HOLIDAY_NAME_DELIMITER = "; "), + # so a name with a semicolon gets split into two separate `VEVENT`s. + sanitized_holiday_name = ( + holiday_name.replace("\\", "\\\\").replace(",", "\\,").replace(":", "\\:") + ) + event_uid = f"{uuid.uuid4()}@{self.holidays_version}.holidays.local" + language_tag = f";LANGUAGE={self.language}" if self.show_language else "" + + return [ + "BEGIN:VEVENT", + f"DTSTAMP:{self.ical_timestamp}", + f"UID:{event_uid}", + self._fold_line(f"SUMMARY{language_tag}:{sanitized_holiday_name}"), + f"DTSTART;VALUE=DATE:{dt:%Y%m%d}", + f"DURATION:P{holiday_length}D", + "END:VEVENT", + ] + + def generate(self, return_bytes: bool = False) -> Union[str, bytes]: + """Generate iCalendar data. + + Args: + return_bytes: + If True, return bytes instead of string. + + Returns: + The complete iCalendar data + (string or UTF-8 bytes depending on return_bytes). + """ + lines = [ + "BEGIN:VCALENDAR", + f"PRODID:-//Vacanza//Open World Holidays Framework v{self.holidays_version}//EN", + "VERSION:2.0", + "CALSCALE:GREGORIAN", + ] + + sorted_dates = sorted(self.holidays.keys()) + # Merged continuous holiday with the same name and use `DURATION` instead. + i = 0 + while i < len(sorted_dates): + dt = sorted_dates[i] + names = self.holidays.get_list(dt) + + for name in names: + days = 1 + while ( + i + days < len(sorted_dates) + and sorted_dates[i + days] == sorted_dates[i] + timedelta(days=days) + and name in self.holidays.get_list(sorted_dates[i + days]) + ): + days += 1 + + lines.extend(self._generate_event(dt, name, days)) + + i += days + + lines.append("END:VCALENDAR") + lines.append("") + + output = CONTENT_LINE_DELIMITER.join(lines) + return output.encode() if return_bytes else output + + def save_ics(self, file_path: str) -> None: + """Export the calendar data to a .ics file. + + While RFC 5545 does not specifically forbid filenames for .ics files, but it's advisable + to follow general filesystem conventions and avoid using problematic characters. + + Args: + file_path: + Path to save the .ics file, including the filename (with extension). + """ + # Generate and write out content (always in bytes for .ics) + content = self.generate(return_bytes=True) + if not content: + raise ValueError("Generated content is empty or invalid.") + + with open(file_path, "wb") as file: + file.write(content) # type: ignore # this is always bytes, ignoring mypy error. diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/am/LC_MESSAGES/ET.mo b/.venv/lib/python3.12/site-packages/holidays/locale/am/LC_MESSAGES/ET.mo new file mode 100644 index 00000000..af961492 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/am/LC_MESSAGES/ET.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/AE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/AE.mo new file mode 100644 index 00000000..8c62cd67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/AE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/BH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/BH.mo new file mode 100644 index 00000000..8c62cd67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/BH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/CA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/CA.mo new file mode 100644 index 00000000..f5fe4482 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/CA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/DJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/DJ.mo new file mode 100644 index 00000000..875a23bd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/DJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/DZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/DZ.mo new file mode 100644 index 00000000..8c62cd67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/DZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/EG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/EG.mo new file mode 100644 index 00000000..8c62cd67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/EG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/ET.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/ET.mo new file mode 100644 index 00000000..f66644ed Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/ET.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/JO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/JO.mo new file mode 100644 index 00000000..77d3b3b9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/JO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/KW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/KW.mo new file mode 100644 index 00000000..77d3b3b9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/KW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/LB.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/LB.mo new file mode 100644 index 00000000..fd339f6d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/LB.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/LY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/LY.mo new file mode 100644 index 00000000..c35712ae Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/LY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/MA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/MA.mo new file mode 100644 index 00000000..8c62cd67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/MA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/OM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/OM.mo new file mode 100644 index 00000000..615b723c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/OM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/PS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/PS.mo new file mode 100644 index 00000000..1219428c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/PS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/SA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/SA.mo new file mode 100644 index 00000000..149c9116 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/SA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/TN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/TN.mo new file mode 100644 index 00000000..8c62cd67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/TN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/UA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/UA.mo new file mode 100644 index 00000000..7e41625c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/UA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/YE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/YE.mo new file mode 100644 index 00000000..6a848cde Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar/LC_MESSAGES/YE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ar_QA/LC_MESSAGES/QA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ar_QA/LC_MESSAGES/QA.mo new file mode 100644 index 00000000..6209b667 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ar_QA/LC_MESSAGES/QA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/az/LC_MESSAGES/AZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/az/LC_MESSAGES/AZ.mo new file mode 100644 index 00000000..84bad262 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/az/LC_MESSAGES/AZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/be/LC_MESSAGES/BY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/be/LC_MESSAGES/BY.mo new file mode 100644 index 00000000..3a1242d2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/be/LC_MESSAGES/BY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/bg/LC_MESSAGES/BG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/bg/LC_MESSAGES/BG.mo new file mode 100644 index 00000000..19e58ded Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/bg/LC_MESSAGES/BG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/bs/LC_MESSAGES/BA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/bs/LC_MESSAGES/BA.mo new file mode 100644 index 00000000..76b38e4b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/bs/LC_MESSAGES/BA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ca/LC_MESSAGES/AD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ca/LC_MESSAGES/AD.mo new file mode 100644 index 00000000..673c934f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ca/LC_MESSAGES/AD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/cnr/LC_MESSAGES/ME.mo b/.venv/lib/python3.12/site-packages/holidays/locale/cnr/LC_MESSAGES/ME.mo new file mode 100644 index 00000000..03a014a2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/cnr/LC_MESSAGES/ME.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/coa_CC/LC_MESSAGES/CC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/coa_CC/LC_MESSAGES/CC.mo new file mode 100644 index 00000000..b89afac4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/coa_CC/LC_MESSAGES/CC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/cs/LC_MESSAGES/CZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/cs/LC_MESSAGES/CZ.mo new file mode 100644 index 00000000..bc5f62ad Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/cs/LC_MESSAGES/CZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/DK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/DK.mo new file mode 100644 index 00000000..707afb72 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/DK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/FO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/FO.mo new file mode 100644 index 00000000..0c98be60 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/FO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/GL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/GL.mo new file mode 100644 index 00000000..3ced90d5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/da/LC_MESSAGES/GL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/AT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/AT.mo new file mode 100644 index 00000000..01c8bb64 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/AT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/BE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/BE.mo new file mode 100644 index 00000000..19eb622a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/BE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/CH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/CH.mo new file mode 100644 index 00000000..a6f59adf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/CH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/CV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/CV.mo new file mode 100644 index 00000000..a2e2add7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/CV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/DE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/DE.mo new file mode 100644 index 00000000..d4f624f2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/DE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/LI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/LI.mo new file mode 100644 index 00000000..4c1550bf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/LI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/LU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/LU.mo new file mode 100644 index 00000000..972ec18e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/LU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/PL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/PL.mo new file mode 100644 index 00000000..52d35854 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/de/LC_MESSAGES/PL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/el/LC_MESSAGES/CY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/el/LC_MESSAGES/CY.mo new file mode 100644 index 00000000..e479ca70 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/el/LC_MESSAGES/CY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/el/LC_MESSAGES/GR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/el/LC_MESSAGES/GR.mo new file mode 100644 index 00000000..f19b6c1b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/el/LC_MESSAGES/GR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_AI/LC_MESSAGES/AI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_AI/LC_MESSAGES/AI.mo new file mode 100644 index 00000000..d85b0cf6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_AI/LC_MESSAGES/AI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_AU/LC_MESSAGES/AU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_AU/LC_MESSAGES/AU.mo new file mode 100644 index 00000000..b83a126e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_AU/LC_MESSAGES/AU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_BM/LC_MESSAGES/BM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_BM/LC_MESSAGES/BM.mo new file mode 100644 index 00000000..30852d93 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_BM/LC_MESSAGES/BM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_BQ/LC_MESSAGES/BQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_BQ/LC_MESSAGES/BQ.mo new file mode 100644 index 00000000..7a8ccd18 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_BQ/LC_MESSAGES/BQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_CA/LC_MESSAGES/CA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_CA/LC_MESSAGES/CA.mo new file mode 100644 index 00000000..ea208a2e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_CA/LC_MESSAGES/CA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_CC/LC_MESSAGES/CC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_CC/LC_MESSAGES/CC.mo new file mode 100644 index 00000000..263c9136 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_CC/LC_MESSAGES/CC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_CI/LC_MESSAGES/CI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_CI/LC_MESSAGES/CI.mo new file mode 100644 index 00000000..9bf34132 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_CI/LC_MESSAGES/CI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_CK/LC_MESSAGES/CK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_CK/LC_MESSAGES/CK.mo new file mode 100644 index 00000000..29055658 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_CK/LC_MESSAGES/CK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_CX/LC_MESSAGES/CX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_CX/LC_MESSAGES/CX.mo new file mode 100644 index 00000000..e8faeb5d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_CX/LC_MESSAGES/CX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_CY/LC_MESSAGES/CY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_CY/LC_MESSAGES/CY.mo new file mode 100644 index 00000000..19890d30 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_CY/LC_MESSAGES/CY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_ET/LC_MESSAGES/ET.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_ET/LC_MESSAGES/ET.mo new file mode 100644 index 00000000..5dede2cc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_ET/LC_MESSAGES/ET.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_FM/LC_MESSAGES/FM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_FM/LC_MESSAGES/FM.mo new file mode 100644 index 00000000..a7f8799e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_FM/LC_MESSAGES/FM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/FK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/FK.mo new file mode 100644 index 00000000..9fff7e57 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/FK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/GB.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/GB.mo new file mode 100644 index 00000000..41df1b0a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/GB.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/GI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/GI.mo new file mode 100644 index 00000000..009663fb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/GI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/IM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/IM.mo new file mode 100644 index 00000000..0cdd0e80 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/IM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/KY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/KY.mo new file mode 100644 index 00000000..87223e1c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/KY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/TV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/TV.mo new file mode 100644 index 00000000..dc27342d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_GB/LC_MESSAGES/TV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_GD/LC_MESSAGES/GD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_GD/LC_MESSAGES/GD.mo new file mode 100644 index 00000000..3aee334a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_GD/LC_MESSAGES/GD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_GY/LC_MESSAGES/GY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_GY/LC_MESSAGES/GY.mo new file mode 100644 index 00000000..8f22d58b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_GY/LC_MESSAGES/GY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_HK/LC_MESSAGES/HK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_HK/LC_MESSAGES/HK.mo new file mode 100644 index 00000000..94cbd96e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_HK/LC_MESSAGES/HK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_IN/LC_MESSAGES/IN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_IN/LC_MESSAGES/IN.mo new file mode 100644 index 00000000..6180450e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_IN/LC_MESSAGES/IN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_KE/LC_MESSAGES/KE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_KE/LC_MESSAGES/KE.mo new file mode 100644 index 00000000..3f08b110 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_KE/LC_MESSAGES/KE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_LC/LC_MESSAGES/LC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_LC/LC_MESSAGES/LC.mo new file mode 100644 index 00000000..5091791a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_LC/LC_MESSAGES/LC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_MO/LC_MESSAGES/MO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_MO/LC_MESSAGES/MO.mo new file mode 100644 index 00000000..7d9d85b4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_MO/LC_MESSAGES/MO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_MS/LC_MESSAGES/MS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_MS/LC_MESSAGES/MS.mo new file mode 100644 index 00000000..22323170 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_MS/LC_MESSAGES/MS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_MU/LC_MESSAGES/MU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_MU/LC_MESSAGES/MU.mo new file mode 100644 index 00000000..070d0470 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_MU/LC_MESSAGES/MU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_NA/LC_MESSAGES/NA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_NA/LC_MESSAGES/NA.mo new file mode 100644 index 00000000..6b33ae54 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_NA/LC_MESSAGES/NA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_NF/LC_MESSAGES/NF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_NF/LC_MESSAGES/NF.mo new file mode 100644 index 00000000..9eeaad09 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_NF/LC_MESSAGES/NF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_NR/LC_MESSAGES/NR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_NR/LC_MESSAGES/NR.mo new file mode 100644 index 00000000..c49a09c6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_NR/LC_MESSAGES/NR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_NU/LC_MESSAGES/NU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_NU/LC_MESSAGES/NU.mo new file mode 100644 index 00000000..3c92f1a0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_NU/LC_MESSAGES/NU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_PH/LC_MESSAGES/PH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_PH/LC_MESSAGES/PH.mo new file mode 100644 index 00000000..37f21bb5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_PH/LC_MESSAGES/PH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_PK/LC_MESSAGES/PK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_PK/LC_MESSAGES/PK.mo new file mode 100644 index 00000000..1f4bc64a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_PK/LC_MESSAGES/PK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_SC/LC_MESSAGES/SC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_SC/LC_MESSAGES/SC.mo new file mode 100644 index 00000000..3e4586ab Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_SC/LC_MESSAGES/SC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_SG/LC_MESSAGES/SG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_SG/LC_MESSAGES/SG.mo new file mode 100644 index 00000000..364d29cb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_SG/LC_MESSAGES/SG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_SL/LC_MESSAGES/SL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_SL/LC_MESSAGES/SL.mo new file mode 100644 index 00000000..1c9a603c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_SL/LC_MESSAGES/SL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_TC/LC_MESSAGES/TC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_TC/LC_MESSAGES/TC.mo new file mode 100644 index 00000000..bba49589 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_TC/LC_MESSAGES/TC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_TK/LC_MESSAGES/TK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_TK/LC_MESSAGES/TK.mo new file mode 100644 index 00000000..60926715 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_TK/LC_MESSAGES/TK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_TL/LC_MESSAGES/TL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_TL/LC_MESSAGES/TL.mo new file mode 100644 index 00000000..90b94501 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_TL/LC_MESSAGES/TL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_TT/LC_MESSAGES/TT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_TT/LC_MESSAGES/TT.mo new file mode 100644 index 00000000..689ba4b2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_TT/LC_MESSAGES/TT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AD.mo new file mode 100644 index 00000000..d03a01eb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AE.mo new file mode 100644 index 00000000..599f7977 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AF.mo new file mode 100644 index 00000000..0e6461df Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AI.mo new file mode 100644 index 00000000..13068e52 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AL.mo new file mode 100644 index 00000000..a6ae3b7f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AM.mo new file mode 100644 index 00000000..d9f0e8dc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AO.mo new file mode 100644 index 00000000..4b3d394f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AR.mo new file mode 100644 index 00000000..137f88a0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AS.mo new file mode 100644 index 00000000..4f14717a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AT.mo new file mode 100644 index 00000000..c1ebc36f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AU.mo new file mode 100644 index 00000000..80b6b021 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AW.mo new file mode 100644 index 00000000..ee0a912f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AX.mo new file mode 100644 index 00000000..9ac17831 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AZ.mo new file mode 100644 index 00000000..87347fc1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/AZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BA.mo new file mode 100644 index 00000000..5d07aed7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BE.mo new file mode 100644 index 00000000..50fc200d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BG.mo new file mode 100644 index 00000000..8e9d613e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BH.mo new file mode 100644 index 00000000..7278d9f7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BJ.mo new file mode 100644 index 00000000..563e1a3c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BL.mo new file mode 100644 index 00000000..8846c525 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BM.mo new file mode 100644 index 00000000..88126a9a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BN.mo new file mode 100644 index 00000000..774f113c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BO.mo new file mode 100644 index 00000000..87a14372 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BQ.mo new file mode 100644 index 00000000..1daaf12e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BR.mo new file mode 100644 index 00000000..6c381095 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BVMF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BVMF.mo new file mode 100644 index 00000000..344d2936 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BVMF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BY.mo new file mode 100644 index 00000000..4a5d6ea2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/BY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CA.mo new file mode 100644 index 00000000..da903bd4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CC.mo new file mode 100644 index 00000000..c10c95d8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CD.mo new file mode 100644 index 00000000..e2fe1385 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CF.mo new file mode 100644 index 00000000..740d0cc8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CG.mo new file mode 100644 index 00000000..404f2836 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CH.mo new file mode 100644 index 00000000..a90e327b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CI.mo new file mode 100644 index 00000000..6158761d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CK.mo new file mode 100644 index 00000000..62d4ce93 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CL.mo new file mode 100644 index 00000000..2e8c6c1c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CN.mo new file mode 100644 index 00000000..8f114473 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CO.mo new file mode 100644 index 00000000..80feb55d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CR.mo new file mode 100644 index 00000000..8ea81627 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CU.mo new file mode 100644 index 00000000..cc5e138f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CV.mo new file mode 100644 index 00000000..3cda5ee5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CW.mo new file mode 100644 index 00000000..3b52776c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CX.mo new file mode 100644 index 00000000..4f006346 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CY.mo new file mode 100644 index 00000000..5eede041 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CZ.mo new file mode 100644 index 00000000..e43e8a64 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/CZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DE.mo new file mode 100644 index 00000000..199d921c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DJ.mo new file mode 100644 index 00000000..83c8bacd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DK.mo new file mode 100644 index 00000000..86ddc461 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DO.mo new file mode 100644 index 00000000..70e32a17 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DZ.mo new file mode 100644 index 00000000..f4f817a1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/DZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EC.mo new file mode 100644 index 00000000..027bbdae Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EE.mo new file mode 100644 index 00000000..53ff9c1a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EG.mo new file mode 100644 index 00000000..3186f2ee Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/EG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ES.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ES.mo new file mode 100644 index 00000000..a8196247 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ES.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ET.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ET.mo new file mode 100644 index 00000000..ccd01375 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ET.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FI.mo new file mode 100644 index 00000000..b2382292 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FK.mo new file mode 100644 index 00000000..4b351ca5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FM.mo new file mode 100644 index 00000000..4b097c27 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FO.mo new file mode 100644 index 00000000..af677bb2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FR.mo new file mode 100644 index 00000000..04ccd395 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/FR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GB.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GB.mo new file mode 100644 index 00000000..f4c178bb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GB.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GD.mo new file mode 100644 index 00000000..26e2b76c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GE.mo new file mode 100644 index 00000000..90619cd9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GF.mo new file mode 100644 index 00000000..5d8bc112 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GI.mo new file mode 100644 index 00000000..73e2e3e8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GL.mo new file mode 100644 index 00000000..48cefe6d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GN.mo new file mode 100644 index 00000000..97a03b6e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GP.mo new file mode 100644 index 00000000..d7c13891 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GQ.mo new file mode 100644 index 00000000..7cc64f91 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GR.mo new file mode 100644 index 00000000..a7529ce8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GT.mo new file mode 100644 index 00000000..ff19b270 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GU.mo new file mode 100644 index 00000000..a17e7ea7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GY.mo new file mode 100644 index 00000000..ae963acf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/GY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HK.mo new file mode 100644 index 00000000..ce9f1099 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HN.mo new file mode 100644 index 00000000..a4165213 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HR.mo new file mode 100644 index 00000000..eb8b1a0e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HT.mo new file mode 100644 index 00000000..78388d02 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HU.mo new file mode 100644 index 00000000..24ad0b67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/HU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ID.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ID.mo new file mode 100644 index 00000000..7cbbf874 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ID.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IL.mo new file mode 100644 index 00000000..30371fe3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IM.mo new file mode 100644 index 00000000..81707614 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IN.mo new file mode 100644 index 00000000..3b22cf10 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IR.mo new file mode 100644 index 00000000..cc99e4dd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IS.mo new file mode 100644 index 00000000..0fe624e5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/IS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/JO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/JO.mo new file mode 100644 index 00000000..925c027d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/JO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/JP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/JP.mo new file mode 100644 index 00000000..02a56855 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/JP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KE.mo new file mode 100644 index 00000000..e5a91caf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KH.mo new file mode 100644 index 00000000..52ccf17a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KR.mo new file mode 100644 index 00000000..95a0f7f5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KW.mo new file mode 100644 index 00000000..80deaa74 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KY.mo new file mode 100644 index 00000000..2d638c45 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KZ.mo new file mode 100644 index 00000000..e0658818 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/KZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LA.mo new file mode 100644 index 00000000..486ace38 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LB.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LB.mo new file mode 100644 index 00000000..645de87b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LB.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LC.mo new file mode 100644 index 00000000..7ceb0597 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LI.mo new file mode 100644 index 00000000..5ce1d1e5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LK.mo new file mode 100644 index 00000000..8fc6418f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LT.mo new file mode 100644 index 00000000..ba6890b9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LU.mo new file mode 100644 index 00000000..f775f60f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LV.mo new file mode 100644 index 00000000..307c33c0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LY.mo new file mode 100644 index 00000000..fc4df1f2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/LY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MA.mo new file mode 100644 index 00000000..07313d54 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MC.mo new file mode 100644 index 00000000..49e668fc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MD.mo new file mode 100644 index 00000000..b78587cd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ME.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ME.mo new file mode 100644 index 00000000..a7cf7500 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ME.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MF.mo new file mode 100644 index 00000000..7eed58ea Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MG.mo new file mode 100644 index 00000000..02eded4f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MK.mo new file mode 100644 index 00000000..c6cae589 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ML.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ML.mo new file mode 100644 index 00000000..c408a7eb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ML.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MN.mo new file mode 100644 index 00000000..4447969e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MO.mo new file mode 100644 index 00000000..8ea2a172 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MP.mo new file mode 100644 index 00000000..a17e7ea7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MQ.mo new file mode 100644 index 00000000..9eb2e991 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MS.mo new file mode 100644 index 00000000..82d969dc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MT.mo new file mode 100644 index 00000000..9e9430a8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MU.mo new file mode 100644 index 00000000..185bd836 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MX.mo new file mode 100644 index 00000000..e8fc1bc2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MY.mo new file mode 100644 index 00000000..e862f128 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MZ.mo new file mode 100644 index 00000000..f8c9f4f8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/MZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NA.mo new file mode 100644 index 00000000..b8014723 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NC.mo new file mode 100644 index 00000000..1fee0b9c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NE.mo new file mode 100644 index 00000000..1dddafb1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NF.mo new file mode 100644 index 00000000..22fdf3ee Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NI.mo new file mode 100644 index 00000000..ea37a8ce Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NL.mo new file mode 100644 index 00000000..d9bf5efe Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NO.mo new file mode 100644 index 00000000..dc0ce3a7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NR.mo new file mode 100644 index 00000000..d75eb1ef Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NU.mo new file mode 100644 index 00000000..8788a719 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/NU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/OM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/OM.mo new file mode 100644 index 00000000..f3236a22 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/OM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PA.mo new file mode 100644 index 00000000..6101538f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PE.mo new file mode 100644 index 00000000..489e35c0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PF.mo new file mode 100644 index 00000000..542e2575 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PH.mo new file mode 100644 index 00000000..f97d4148 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PK.mo new file mode 100644 index 00000000..4e5e8ea8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PL.mo new file mode 100644 index 00000000..423a7568 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PM.mo new file mode 100644 index 00000000..40be296d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PR.mo new file mode 100644 index 00000000..a17e7ea7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PS.mo new file mode 100644 index 00000000..53d7f8fc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PT.mo new file mode 100644 index 00000000..e3818ffe Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PY.mo new file mode 100644 index 00000000..3499fabc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/PY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/QA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/QA.mo new file mode 100644 index 00000000..4e4743bb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/QA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RE.mo new file mode 100644 index 00000000..e8ed9524 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RO.mo new file mode 100644 index 00000000..e6ac5141 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RS.mo new file mode 100644 index 00000000..d80b3c08 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RU.mo new file mode 100644 index 00000000..475744f8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/RU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SA.mo new file mode 100644 index 00000000..87197460 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SC.mo new file mode 100644 index 00000000..e16c7903 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SE.mo new file mode 100644 index 00000000..37a0804a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SG.mo new file mode 100644 index 00000000..552b6854 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SI.mo new file mode 100644 index 00000000..8b86c8f4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SJ.mo new file mode 100644 index 00000000..fa6ac72e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SK.mo new file mode 100644 index 00000000..6d730262 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SL.mo new file mode 100644 index 00000000..70d9fa45 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SM.mo new file mode 100644 index 00000000..b02598a7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SN.mo new file mode 100644 index 00000000..75447471 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SR.mo new file mode 100644 index 00000000..eb7229ae Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ST.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ST.mo new file mode 100644 index 00000000..8a0dff00 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/ST.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SV.mo new file mode 100644 index 00000000..a02b4d5e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SX.mo new file mode 100644 index 00000000..ea0a3fe5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/SX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TC.mo new file mode 100644 index 00000000..5865c33f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TF.mo new file mode 100644 index 00000000..f9ce08ed Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TG.mo new file mode 100644 index 00000000..d3b40534 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TH.mo new file mode 100644 index 00000000..6984a55c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TK.mo new file mode 100644 index 00000000..3debe071 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TL.mo new file mode 100644 index 00000000..12cb0729 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TN.mo new file mode 100644 index 00000000..0318f49c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TO.mo new file mode 100644 index 00000000..5e854f5c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TR.mo new file mode 100644 index 00000000..d6c34ff1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TT.mo new file mode 100644 index 00000000..fb0e43af Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TV.mo new file mode 100644 index 00000000..88af38c6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TW.mo new file mode 100644 index 00000000..3b0eef54 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TZ.mo new file mode 100644 index 00000000..6329a311 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/TZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UA.mo new file mode 100644 index 00000000..76f50a5c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UM.mo new file mode 100644 index 00000000..63925ad8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/US.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/US.mo new file mode 100644 index 00000000..5d530069 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/US.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UY.mo new file mode 100644 index 00000000..c59a2636 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UZ.mo new file mode 100644 index 00000000..45deb01f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/UZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VA.mo new file mode 100644 index 00000000..f8377912 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VC.mo new file mode 100644 index 00000000..90d0f723 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VE.mo new file mode 100644 index 00000000..fdba7d8c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VG.mo new file mode 100644 index 00000000..47f59cb9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VI.mo new file mode 100644 index 00000000..63925ad8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VN.mo new file mode 100644 index 00000000..a0ad6883 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/VN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/WF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/WF.mo new file mode 100644 index 00000000..bb8310a9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/WF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/YE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/YE.mo new file mode 100644 index 00000000..03383d52 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/YE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/YT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/YT.mo new file mode 100644 index 00000000..fb962859 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_US/LC_MESSAGES/YT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_VC/LC_MESSAGES/VC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_VC/LC_MESSAGES/VC.mo new file mode 100644 index 00000000..8f80bfe3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_VC/LC_MESSAGES/VC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/en_VG/LC_MESSAGES/VG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/en_VG/LC_MESSAGES/VG.mo new file mode 100644 index 00000000..9b63ba4d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/en_VG/LC_MESSAGES/VG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/AR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/AR.mo new file mode 100644 index 00000000..f95b81a4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/AR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/BO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/BO.mo new file mode 100644 index 00000000..b225de29 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/BO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CL.mo new file mode 100644 index 00000000..365e37bb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CO.mo new file mode 100644 index 00000000..ecbdcd10 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CR.mo new file mode 100644 index 00000000..c074e8a3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CU.mo new file mode 100644 index 00000000..9f1b9772 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CV.mo new file mode 100644 index 00000000..c58f3058 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/CV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/DO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/DO.mo new file mode 100644 index 00000000..c667797c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/DO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/EC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/EC.mo new file mode 100644 index 00000000..ef680c32 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/EC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/ES.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/ES.mo new file mode 100644 index 00000000..3727c70b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/ES.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/GQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/GQ.mo new file mode 100644 index 00000000..83d00190 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/GQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/GT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/GT.mo new file mode 100644 index 00000000..8c50d442 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/GT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/HN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/HN.mo new file mode 100644 index 00000000..0cc64e64 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/HN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/HT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/HT.mo new file mode 100644 index 00000000..8a40647d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/HT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/MX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/MX.mo new file mode 100644 index 00000000..c667797c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/MX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/NI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/NI.mo new file mode 100644 index 00000000..065390a7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/NI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PA.mo new file mode 100644 index 00000000..7a69c886 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PE.mo new file mode 100644 index 00000000..39062b22 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PY.mo new file mode 100644 index 00000000..5b6cf0d1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/PY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/SV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/SV.mo new file mode 100644 index 00000000..098a5990 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/SV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/UY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/UY.mo new file mode 100644 index 00000000..bd2c9a90 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/UY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/VE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/VE.mo new file mode 100644 index 00000000..e79a44fc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/es/LC_MESSAGES/VE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/et/LC_MESSAGES/EE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/et/LC_MESSAGES/EE.mo new file mode 100644 index 00000000..f7bc76f6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/et/LC_MESSAGES/EE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fa_AF/LC_MESSAGES/AF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fa_AF/LC_MESSAGES/AF.mo new file mode 100644 index 00000000..b384a26e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fa_AF/LC_MESSAGES/AF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fa_IR/LC_MESSAGES/IR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fa_IR/LC_MESSAGES/IR.mo new file mode 100644 index 00000000..177fd589 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fa_IR/LC_MESSAGES/IR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/AX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/AX.mo new file mode 100644 index 00000000..63e34a9f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/AX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/FI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/FI.mo new file mode 100644 index 00000000..7842b9c3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/FI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/GL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/GL.mo new file mode 100644 index 00000000..af22d309 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fi/LC_MESSAGES/GL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fil/LC_MESSAGES/PH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fil/LC_MESSAGES/PH.mo new file mode 100644 index 00000000..de495fb3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fil/LC_MESSAGES/PH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fo/LC_MESSAGES/FO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fo/LC_MESSAGES/FO.mo new file mode 100644 index 00000000..fd231333 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fo/LC_MESSAGES/FO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/BE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/BE.mo new file mode 100644 index 00000000..404c6595 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/BE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/BL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/BL.mo new file mode 100644 index 00000000..bbd1057a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/BL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CA.mo new file mode 100644 index 00000000..671015b4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CD.mo new file mode 100644 index 00000000..517671b7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CF.mo new file mode 100644 index 00000000..79437cf1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CG.mo new file mode 100644 index 00000000..8e6bec88 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CH.mo new file mode 100644 index 00000000..68b384d0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CI.mo new file mode 100644 index 00000000..80d37adf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CV.mo new file mode 100644 index 00000000..4a406a46 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/CV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/DJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/DJ.mo new file mode 100644 index 00000000..74996ea4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/DJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/DZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/DZ.mo new file mode 100644 index 00000000..77494f47 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/DZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/FR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/FR.mo new file mode 100644 index 00000000..81aa1c1d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/FR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GF.mo new file mode 100644 index 00000000..2a988f62 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GN.mo new file mode 100644 index 00000000..2faa2204 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GP.mo new file mode 100644 index 00000000..9bb9a401 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/GP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/LU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/LU.mo new file mode 100644 index 00000000..3ef4779a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/LU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MA.mo new file mode 100644 index 00000000..f65c47f8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MC.mo new file mode 100644 index 00000000..17b943db Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MF.mo new file mode 100644 index 00000000..e88f35cb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/ML.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/ML.mo new file mode 100644 index 00000000..a89a8322 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/ML.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MQ.mo new file mode 100644 index 00000000..f84438a7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/MQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/NC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/NC.mo new file mode 100644 index 00000000..c095c6b0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/NC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/PF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/PF.mo new file mode 100644 index 00000000..c261b88e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/PF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/PM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/PM.mo new file mode 100644 index 00000000..c145cc6c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/PM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/RE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/RE.mo new file mode 100644 index 00000000..1a7fbe77 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/RE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/TF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/TF.mo new file mode 100644 index 00000000..5c6fae6b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/TF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/TG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/TG.mo new file mode 100644 index 00000000..6a978feb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/TG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/WF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/WF.mo new file mode 100644 index 00000000..7e2185b8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/WF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/YT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/YT.mo new file mode 100644 index 00000000..b03b26c6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr/LC_MESSAGES/YT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr_BJ/LC_MESSAGES/BJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr_BJ/LC_MESSAGES/BJ.mo new file mode 100644 index 00000000..e1b69296 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr_BJ/LC_MESSAGES/BJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr_HT/LC_MESSAGES/HT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr_HT/LC_MESSAGES/HT.mo new file mode 100644 index 00000000..705ef2ab Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr_HT/LC_MESSAGES/HT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr_NE/LC_MESSAGES/NE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr_NE/LC_MESSAGES/NE.mo new file mode 100644 index 00000000..8f1322ce Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr_NE/LC_MESSAGES/NE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fr_SN/LC_MESSAGES/SN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fr_SN/LC_MESSAGES/SN.mo new file mode 100644 index 00000000..9a4cfa22 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fr_SN/LC_MESSAGES/SN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/fy/LC_MESSAGES/NL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/fy/LC_MESSAGES/NL.mo new file mode 100644 index 00000000..a07a1830 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/fy/LC_MESSAGES/NL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/he/LC_MESSAGES/IL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/he/LC_MESSAGES/IL.mo new file mode 100644 index 00000000..c926454d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/he/LC_MESSAGES/IL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/hi/LC_MESSAGES/IN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/hi/LC_MESSAGES/IN.mo new file mode 100644 index 00000000..e0cf3397 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/hi/LC_MESSAGES/IN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/hr/LC_MESSAGES/HR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/hr/LC_MESSAGES/HR.mo new file mode 100644 index 00000000..0f32e7f5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/hr/LC_MESSAGES/HR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ht/LC_MESSAGES/HT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ht/LC_MESSAGES/HT.mo new file mode 100644 index 00000000..fa8e7389 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ht/LC_MESSAGES/HT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/hu/LC_MESSAGES/HU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/hu/LC_MESSAGES/HU.mo new file mode 100644 index 00000000..35c4e148 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/hu/LC_MESSAGES/HU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/hy/LC_MESSAGES/AM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/hy/LC_MESSAGES/AM.mo new file mode 100644 index 00000000..5c08446d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/hy/LC_MESSAGES/AM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/id/LC_MESSAGES/ID.mo b/.venv/lib/python3.12/site-packages/holidays/locale/id/LC_MESSAGES/ID.mo new file mode 100644 index 00000000..f458c07e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/id/LC_MESSAGES/ID.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/FO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/FO.mo new file mode 100644 index 00000000..d242d112 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/FO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/GL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/GL.mo new file mode 100644 index 00000000..8a79253f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/GL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/IS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/IS.mo new file mode 100644 index 00000000..6e762f27 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/is/LC_MESSAGES/IS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/CH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/CH.mo new file mode 100644 index 00000000..64266711 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/CH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/SM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/SM.mo new file mode 100644 index 00000000..d6f6e66d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/SM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/VA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/VA.mo new file mode 100644 index 00000000..fa599c98 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/it/LC_MESSAGES/VA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ja/LC_MESSAGES/JP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ja/LC_MESSAGES/JP.mo new file mode 100644 index 00000000..cf467b67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ja/LC_MESSAGES/JP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ka/LC_MESSAGES/GE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ka/LC_MESSAGES/GE.mo new file mode 100644 index 00000000..22ad1d9f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ka/LC_MESSAGES/GE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/kk/LC_MESSAGES/KZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/kk/LC_MESSAGES/KZ.mo new file mode 100644 index 00000000..d05ca424 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/kk/LC_MESSAGES/KZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/kl/LC_MESSAGES/GL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/kl/LC_MESSAGES/GL.mo new file mode 100644 index 00000000..6fc67084 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/kl/LC_MESSAGES/GL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/km/LC_MESSAGES/KH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/km/LC_MESSAGES/KH.mo new file mode 100644 index 00000000..04852272 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/km/LC_MESSAGES/KH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ko/LC_MESSAGES/KR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ko/LC_MESSAGES/KR.mo new file mode 100644 index 00000000..07fe33dc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ko/LC_MESSAGES/KR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/lb/LC_MESSAGES/LU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/lb/LC_MESSAGES/LU.mo new file mode 100644 index 00000000..54d17d26 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/lb/LC_MESSAGES/LU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/lo/LC_MESSAGES/LA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/lo/LC_MESSAGES/LA.mo new file mode 100644 index 00000000..40b250fd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/lo/LC_MESSAGES/LA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/lt/LC_MESSAGES/LT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/lt/LC_MESSAGES/LT.mo new file mode 100644 index 00000000..802c6368 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/lt/LC_MESSAGES/LT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/lv/LC_MESSAGES/LV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/lv/LC_MESSAGES/LV.mo new file mode 100644 index 00000000..5b491780 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/lv/LC_MESSAGES/LV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/mg/LC_MESSAGES/MG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/mg/LC_MESSAGES/MG.mo new file mode 100644 index 00000000..605a662a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/mg/LC_MESSAGES/MG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/mk/LC_MESSAGES/MK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/mk/LC_MESSAGES/MK.mo new file mode 100644 index 00000000..1ff01e7c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/mk/LC_MESSAGES/MK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/mn/LC_MESSAGES/MN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/mn/LC_MESSAGES/MN.mo new file mode 100644 index 00000000..cfd37fd4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/mn/LC_MESSAGES/MN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ms/LC_MESSAGES/BN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ms/LC_MESSAGES/BN.mo new file mode 100644 index 00000000..ff1589ea Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ms/LC_MESSAGES/BN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ms_MY/LC_MESSAGES/MY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ms_MY/LC_MESSAGES/MY.mo new file mode 100644 index 00000000..d54311a6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ms_MY/LC_MESSAGES/MY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/mt/LC_MESSAGES/MT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/mt/LC_MESSAGES/MT.mo new file mode 100644 index 00000000..35cadc98 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/mt/LC_MESSAGES/MT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/AW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/AW.mo new file mode 100644 index 00000000..6a4fec0c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/AW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/BE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/BE.mo new file mode 100644 index 00000000..95ceaabd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/BE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/BQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/BQ.mo new file mode 100644 index 00000000..e7b71c96 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/BQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/CW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/CW.mo new file mode 100644 index 00000000..d0016954 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/CW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/NL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/NL.mo new file mode 100644 index 00000000..07ac28d3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/NL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/SR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/SR.mo new file mode 100644 index 00000000..81e2e64f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/SR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/SX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/SX.mo new file mode 100644 index 00000000..b12d1a08 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/nl/LC_MESSAGES/SX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/FO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/FO.mo new file mode 100644 index 00000000..df23d6d3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/FO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/GL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/GL.mo new file mode 100644 index 00000000..0cd30a1c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/GL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/NO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/NO.mo new file mode 100644 index 00000000..1ac62df8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/NO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/SJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/SJ.mo new file mode 100644 index 00000000..26dcddee Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/no/LC_MESSAGES/SJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pap_AW/LC_MESSAGES/AW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pap_AW/LC_MESSAGES/AW.mo new file mode 100644 index 00000000..aac68b04 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pap_AW/LC_MESSAGES/AW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pap_BQ/LC_MESSAGES/BQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pap_BQ/LC_MESSAGES/BQ.mo new file mode 100644 index 00000000..66cd3cce Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pap_BQ/LC_MESSAGES/BQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pap_CW/LC_MESSAGES/CW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pap_CW/LC_MESSAGES/CW.mo new file mode 100644 index 00000000..0a7abe65 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pap_CW/LC_MESSAGES/CW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pl/LC_MESSAGES/PL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pl/LC_MESSAGES/PL.mo new file mode 100644 index 00000000..8acc0c81 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pl/LC_MESSAGES/PL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ps_AF/LC_MESSAGES/AF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ps_AF/LC_MESSAGES/AF.mo new file mode 100644 index 00000000..7f687265 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ps_AF/LC_MESSAGES/AF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_AO/LC_MESSAGES/AO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_AO/LC_MESSAGES/AO.mo new file mode 100644 index 00000000..44949664 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_AO/LC_MESSAGES/AO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_BR/LC_MESSAGES/BR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_BR/LC_MESSAGES/BR.mo new file mode 100644 index 00000000..c1807a36 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_BR/LC_MESSAGES/BR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_BR/LC_MESSAGES/BVMF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_BR/LC_MESSAGES/BVMF.mo new file mode 100644 index 00000000..20788e3e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_BR/LC_MESSAGES/BVMF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_CV/LC_MESSAGES/CV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_CV/LC_MESSAGES/CV.mo new file mode 100644 index 00000000..20444394 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_CV/LC_MESSAGES/CV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_MO/LC_MESSAGES/MO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_MO/LC_MESSAGES/MO.mo new file mode 100644 index 00000000..a32c82d8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_MO/LC_MESSAGES/MO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_MZ/LC_MESSAGES/MZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_MZ/LC_MESSAGES/MZ.mo new file mode 100644 index 00000000..a34b0694 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_MZ/LC_MESSAGES/MZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_PT/LC_MESSAGES/PT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_PT/LC_MESSAGES/PT.mo new file mode 100644 index 00000000..ad1ca348 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_PT/LC_MESSAGES/PT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_ST/LC_MESSAGES/ST.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_ST/LC_MESSAGES/ST.mo new file mode 100644 index 00000000..a825b4eb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_ST/LC_MESSAGES/ST.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/pt_TL/LC_MESSAGES/TL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/pt_TL/LC_MESSAGES/TL.mo new file mode 100644 index 00000000..19c529f4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/pt_TL/LC_MESSAGES/TL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ro/LC_MESSAGES/MD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ro/LC_MESSAGES/MD.mo new file mode 100644 index 00000000..4364539a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ro/LC_MESSAGES/MD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ro/LC_MESSAGES/RO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ro/LC_MESSAGES/RO.mo new file mode 100644 index 00000000..02dedbd0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ro/LC_MESSAGES/RO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ru/LC_MESSAGES/BY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ru/LC_MESSAGES/BY.mo new file mode 100644 index 00000000..c27999cd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ru/LC_MESSAGES/BY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ru/LC_MESSAGES/RU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ru/LC_MESSAGES/RU.mo new file mode 100644 index 00000000..1049e2b4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ru/LC_MESSAGES/RU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/si_LK/LC_MESSAGES/LK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/si_LK/LC_MESSAGES/LK.mo new file mode 100644 index 00000000..2b472598 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/si_LK/LC_MESSAGES/LK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sk/LC_MESSAGES/CZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sk/LC_MESSAGES/CZ.mo new file mode 100644 index 00000000..c53745c8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sk/LC_MESSAGES/CZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sk/LC_MESSAGES/SK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sk/LC_MESSAGES/SK.mo new file mode 100644 index 00000000..8195b086 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sk/LC_MESSAGES/SK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sl/LC_MESSAGES/SI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sl/LC_MESSAGES/SI.mo new file mode 100644 index 00000000..4e0666f4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sl/LC_MESSAGES/SI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sq/LC_MESSAGES/AL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sq/LC_MESSAGES/AL.mo new file mode 100644 index 00000000..66a51c42 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sq/LC_MESSAGES/AL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sr/LC_MESSAGES/BA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sr/LC_MESSAGES/BA.mo new file mode 100644 index 00000000..6a4215c8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sr/LC_MESSAGES/BA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sr/LC_MESSAGES/RS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sr/LC_MESSAGES/RS.mo new file mode 100644 index 00000000..0f5bbaac Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sr/LC_MESSAGES/RS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/FO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/FO.mo new file mode 100644 index 00000000..99362f68 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/FO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/GL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/GL.mo new file mode 100644 index 00000000..09384bf5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/GL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/SE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/SE.mo new file mode 100644 index 00000000..312030ca Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sv/LC_MESSAGES/SE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sv_FI/LC_MESSAGES/AX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sv_FI/LC_MESSAGES/AX.mo new file mode 100644 index 00000000..1c4e859c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sv_FI/LC_MESSAGES/AX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sv_FI/LC_MESSAGES/FI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sv_FI/LC_MESSAGES/FI.mo new file mode 100644 index 00000000..3fb3db03 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sv_FI/LC_MESSAGES/FI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sw/LC_MESSAGES/KE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sw/LC_MESSAGES/KE.mo new file mode 100644 index 00000000..dd7ebb10 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sw/LC_MESSAGES/KE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/sw/LC_MESSAGES/TZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/sw/LC_MESSAGES/TZ.mo new file mode 100644 index 00000000..ac207c75 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/sw/LC_MESSAGES/TZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ta_LK/LC_MESSAGES/LK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ta_LK/LC_MESSAGES/LK.mo new file mode 100644 index 00000000..97ffd989 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ta_LK/LC_MESSAGES/LK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/tet/LC_MESSAGES/TL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/tet/LC_MESSAGES/TL.mo new file mode 100644 index 00000000..448b304a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/tet/LC_MESSAGES/TL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AE.mo new file mode 100644 index 00000000..21cce10d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AS.mo new file mode 100644 index 00000000..d5c7b4db Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AU.mo new file mode 100644 index 00000000..c18d18b5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AX.mo new file mode 100644 index 00000000..0c4ccb93 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/AX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BL.mo new file mode 100644 index 00000000..bd9e7d86 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BN.mo new file mode 100644 index 00000000..3c82099b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BY.mo new file mode 100644 index 00000000..1817fab4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/BY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/CA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/CA.mo new file mode 100644 index 00000000..c9e55780 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/CA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/CN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/CN.mo new file mode 100644 index 00000000..c4f44e4b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/CN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/DE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/DE.mo new file mode 100644 index 00000000..8f34f92e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/DE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/FI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/FI.mo new file mode 100644 index 00000000..60f67ee3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/FI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/FR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/FR.mo new file mode 100644 index 00000000..0e1d451d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/FR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GB.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GB.mo new file mode 100644 index 00000000..fdbd4775 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GB.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GF.mo new file mode 100644 index 00000000..3234d314 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GP.mo new file mode 100644 index 00000000..8a4be7fa Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GU.mo new file mode 100644 index 00000000..d2209504 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/GU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/HK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/HK.mo new file mode 100644 index 00000000..a99855d9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/HK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/ID.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/ID.mo new file mode 100644 index 00000000..2df9857a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/ID.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/IL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/IL.mo new file mode 100644 index 00000000..7e1505ca Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/IL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/IM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/IM.mo new file mode 100644 index 00000000..e098736c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/IM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/JP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/JP.mo new file mode 100644 index 00000000..6a019263 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/JP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/KH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/KH.mo new file mode 100644 index 00000000..bd057d63 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/KH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/KR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/KR.mo new file mode 100644 index 00000000..d42ba235 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/KR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/LA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/LA.mo new file mode 100644 index 00000000..8eefde84 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/LA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MF.mo new file mode 100644 index 00000000..89469b57 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MO.mo new file mode 100644 index 00000000..22aaedbb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MP.mo new file mode 100644 index 00000000..d2209504 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MQ.mo new file mode 100644 index 00000000..2c46b72a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MY.mo new file mode 100644 index 00000000..fe5b7f86 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/MY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/NC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/NC.mo new file mode 100644 index 00000000..f870a789 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/NC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/NO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/NO.mo new file mode 100644 index 00000000..11af6843 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/NO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PF.mo new file mode 100644 index 00000000..3742afb8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PH.mo new file mode 100644 index 00000000..713442a0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PM.mo new file mode 100644 index 00000000..b3c33b2c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PR.mo new file mode 100644 index 00000000..d2209504 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/PR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/RE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/RE.mo new file mode 100644 index 00000000..9ea5dc33 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/RE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/RU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/RU.mo new file mode 100644 index 00000000..caf362fa Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/RU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SE.mo new file mode 100644 index 00000000..3f5a0a22 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SG.mo new file mode 100644 index 00000000..daee0531 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SJ.mo new file mode 100644 index 00000000..c4dd9261 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/SJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TF.mo new file mode 100644 index 00000000..b3c33b2c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TH.mo new file mode 100644 index 00000000..343d1435 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TL.mo new file mode 100644 index 00000000..6bae2eaf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TW.mo new file mode 100644 index 00000000..3603b477 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/TW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/UA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/UA.mo new file mode 100644 index 00000000..9feb9a51 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/UA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/UM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/UM.mo new file mode 100644 index 00000000..1c8faa60 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/UM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/US.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/US.mo new file mode 100644 index 00000000..eb70bff4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/US.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VA.mo new file mode 100644 index 00000000..b7762050 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VI.mo new file mode 100644 index 00000000..1c8faa60 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VN.mo new file mode 100644 index 00000000..e3595a96 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/VN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/WF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/WF.mo new file mode 100644 index 00000000..e00d1b0e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/WF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/YT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/YT.mo new file mode 100644 index 00000000..a8c631f7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/th/LC_MESSAGES/YT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/tkl/LC_MESSAGES/TK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/tkl/LC_MESSAGES/TK.mo new file mode 100644 index 00000000..31e9d196 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/tkl/LC_MESSAGES/TK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/to/LC_MESSAGES/TO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/to/LC_MESSAGES/TO.mo new file mode 100644 index 00000000..51e852d9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/to/LC_MESSAGES/TO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/tr/LC_MESSAGES/TR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/tr/LC_MESSAGES/TR.mo new file mode 100644 index 00000000..dd88f920 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/tr/LC_MESSAGES/TR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/tvl/LC_MESSAGES/TV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/tvl/LC_MESSAGES/TV.mo new file mode 100644 index 00000000..5035bbed Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/tvl/LC_MESSAGES/TV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AD.mo new file mode 100644 index 00000000..d746965c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AL.mo new file mode 100644 index 00000000..0eef6501 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AO.mo new file mode 100644 index 00000000..7c8c63e2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AR.mo new file mode 100644 index 00000000..7a15590d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AT.mo new file mode 100644 index 00000000..bcee0117 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AW.mo new file mode 100644 index 00000000..a929f670 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AX.mo new file mode 100644 index 00000000..9077eb2f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AZ.mo new file mode 100644 index 00000000..248bed48 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/AZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BA.mo new file mode 100644 index 00000000..c7a675d8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BE.mo new file mode 100644 index 00000000..e031554c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BG.mo new file mode 100644 index 00000000..819fac54 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BL.mo new file mode 100644 index 00000000..ca97e792 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BO.mo new file mode 100644 index 00000000..32602595 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BR.mo new file mode 100644 index 00000000..2349ab84 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BVMF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BVMF.mo new file mode 100644 index 00000000..414199ec Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/BVMF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CH.mo new file mode 100644 index 00000000..c6ab8ae7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CL.mo new file mode 100644 index 00000000..850aec02 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CO.mo new file mode 100644 index 00000000..d5dbbb9e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CR.mo new file mode 100644 index 00000000..08d43ca8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CU.mo new file mode 100644 index 00000000..d5e7aacf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CW.mo new file mode 100644 index 00000000..c6345f30 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CY.mo new file mode 100644 index 00000000..7c2c7880 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CZ.mo new file mode 100644 index 00000000..cdcc0ee1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/CZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DE.mo new file mode 100644 index 00000000..ec48c62e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DK.mo new file mode 100644 index 00000000..978abf69 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DO.mo new file mode 100644 index 00000000..f00880a5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/DO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/EC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/EC.mo new file mode 100644 index 00000000..da611ca8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/EC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/EE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/EE.mo new file mode 100644 index 00000000..6c2286a9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/EE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ES.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ES.mo new file mode 100644 index 00000000..ed8599f2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ES.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/FI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/FI.mo new file mode 100644 index 00000000..52254e5d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/FI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/FR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/FR.mo new file mode 100644 index 00000000..52a30bbe Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/FR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GE.mo new file mode 100644 index 00000000..2912309f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GF.mo new file mode 100644 index 00000000..9d50f6c5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GL.mo new file mode 100644 index 00000000..a59af73e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GP.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GP.mo new file mode 100644 index 00000000..070e9e47 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GP.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GR.mo new file mode 100644 index 00000000..99ba6c2b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/GR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HN.mo new file mode 100644 index 00000000..60eda842 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HR.mo new file mode 100644 index 00000000..60d39919 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HU.mo new file mode 100644 index 00000000..2e733062 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/HU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ID.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ID.mo new file mode 100644 index 00000000..19533652 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ID.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/IL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/IL.mo new file mode 100644 index 00000000..4412e0cd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/IL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/IS.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/IS.mo new file mode 100644 index 00000000..982f71da Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/IS.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/KZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/KZ.mo new file mode 100644 index 00000000..ea99038b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/KZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LI.mo new file mode 100644 index 00000000..af367be8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LT.mo new file mode 100644 index 00000000..4881aa59 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LU.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LU.mo new file mode 100644 index 00000000..72a2c569 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LU.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LV.mo new file mode 100644 index 00000000..2449cd11 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/LV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MC.mo new file mode 100644 index 00000000..517c6cbf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MD.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MD.mo new file mode 100644 index 00000000..7a08f846 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MD.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ME.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ME.mo new file mode 100644 index 00000000..3c68fbc2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/ME.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MF.mo new file mode 100644 index 00000000..bfbecd1d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MG.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MG.mo new file mode 100644 index 00000000..a76a15a1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MG.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MK.mo new file mode 100644 index 00000000..a24ae32b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MQ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MQ.mo new file mode 100644 index 00000000..91483229 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MQ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MX.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MX.mo new file mode 100644 index 00000000..c245ec32 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MX.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MZ.mo new file mode 100644 index 00000000..6e457990 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/MZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NA.mo new file mode 100644 index 00000000..734dd18f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NC.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NC.mo new file mode 100644 index 00000000..cc3af841 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NC.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NI.mo new file mode 100644 index 00000000..d432e1f2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NL.mo new file mode 100644 index 00000000..865f1877 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NO.mo new file mode 100644 index 00000000..27142a52 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/NO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PA.mo new file mode 100644 index 00000000..63869981 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PE.mo new file mode 100644 index 00000000..2b8aa997 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PF.mo new file mode 100644 index 00000000..f4ca40c7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PL.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PL.mo new file mode 100644 index 00000000..ff8c0bbc Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PL.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PM.mo new file mode 100644 index 00000000..be0a2d6f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PT.mo new file mode 100644 index 00000000..052ea260 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PY.mo new file mode 100644 index 00000000..ed90ea20 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/PY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/RE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/RE.mo new file mode 100644 index 00000000..6843ecaa Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/RE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/RO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/RO.mo new file mode 100644 index 00000000..b5a74760 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/RO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SE.mo new file mode 100644 index 00000000..7bea517b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SI.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SI.mo new file mode 100644 index 00000000..79bf7d0f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SI.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SJ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SJ.mo new file mode 100644 index 00000000..b029008c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SJ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SK.mo new file mode 100644 index 00000000..6d0aeb69 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SM.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SM.mo new file mode 100644 index 00000000..3e094dac Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SM.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SV.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SV.mo new file mode 100644 index 00000000..3c62b31f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/SV.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TF.mo new file mode 100644 index 00000000..ba39b00f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TH.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TH.mo new file mode 100644 index 00000000..6acf0ea5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TH.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TR.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TR.mo new file mode 100644 index 00000000..c560bd84 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/TR.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UA.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UA.mo new file mode 100644 index 00000000..82cfa1b5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UA.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UY.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UY.mo new file mode 100644 index 00000000..37734d33 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UY.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UZ.mo new file mode 100644 index 00000000..4624a9ed Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/UZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/VE.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/VE.mo new file mode 100644 index 00000000..00e557d9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/VE.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/WF.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/WF.mo new file mode 100644 index 00000000..b4e5928c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/WF.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/YT.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/YT.mo new file mode 100644 index 00000000..ab213cfe Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uk/LC_MESSAGES/YT.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/ur_PK/LC_MESSAGES/PK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/ur_PK/LC_MESSAGES/PK.mo new file mode 100644 index 00000000..cac9632b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/ur_PK/LC_MESSAGES/PK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/uz/LC_MESSAGES/UZ.mo b/.venv/lib/python3.12/site-packages/holidays/locale/uz/LC_MESSAGES/UZ.mo new file mode 100644 index 00000000..07f503d2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/uz/LC_MESSAGES/UZ.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/vi/LC_MESSAGES/VN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/vi/LC_MESSAGES/VN.mo new file mode 100644 index 00000000..220cc7ae Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/vi/LC_MESSAGES/VN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/CN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/CN.mo new file mode 100644 index 00000000..3a22b626 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/CN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/HK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/HK.mo new file mode 100644 index 00000000..50149c48 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/HK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/MO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/MO.mo new file mode 100644 index 00000000..734a10d4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/MO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/TW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/TW.mo new file mode 100644 index 00000000..a712314d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/zh_CN/LC_MESSAGES/TW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/zh_HK/LC_MESSAGES/HK.mo b/.venv/lib/python3.12/site-packages/holidays/locale/zh_HK/LC_MESSAGES/HK.mo new file mode 100644 index 00000000..33a75ba3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/zh_HK/LC_MESSAGES/HK.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/zh_MO/LC_MESSAGES/MO.mo b/.venv/lib/python3.12/site-packages/holidays/locale/zh_MO/LC_MESSAGES/MO.mo new file mode 100644 index 00000000..68c4ce2b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/zh_MO/LC_MESSAGES/MO.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/zh_TW/LC_MESSAGES/CN.mo b/.venv/lib/python3.12/site-packages/holidays/locale/zh_TW/LC_MESSAGES/CN.mo new file mode 100644 index 00000000..34236fef Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/zh_TW/LC_MESSAGES/CN.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/locale/zh_TW/LC_MESSAGES/TW.mo b/.venv/lib/python3.12/site-packages/holidays/locale/zh_TW/LC_MESSAGES/TW.mo new file mode 100644 index 00000000..687e0eef Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/locale/zh_TW/LC_MESSAGES/TW.mo differ diff --git a/.venv/lib/python3.12/site-packages/holidays/mixins/__init__.py b/.venv/lib/python3.12/site-packages/holidays/mixins/__init__.py new file mode 100644 index 00000000..e86bf258 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/mixins/__init__.py @@ -0,0 +1,18 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +# ruff: noqa: F401 + +"""Mixins for the holidays package.""" + +from holidays.mixins.child_entity import ChildEntity +from holidays.mixins.preferred_discretionary_holidays import PreferredDiscretionaryHolidays diff --git a/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..b9361aec Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/child_entity.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/child_entity.cpython-312.pyc new file mode 100644 index 00000000..833642a5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/child_entity.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/preferred_discretionary_holidays.cpython-312.pyc b/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/preferred_discretionary_holidays.cpython-312.pyc new file mode 100644 index 00000000..e55577a4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/holidays/mixins/__pycache__/preferred_discretionary_holidays.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/holidays/mixins/child_entity.py b/.venv/lib/python3.12/site-packages/holidays/mixins/child_entity.py new file mode 100644 index 00000000..7298e6ec --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/mixins/child_entity.py @@ -0,0 +1,43 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + + +from typing import Optional + +from holidays.holiday_base import HolidayBase + + +class ChildEntity: + """A mixin for child entities that inherit from a parent entity.""" + + parent_entity: type[HolidayBase] + """The parent entity class.""" + + parent_entity_subdivision_code: Optional[str] = None + """The parent entity's corresponding ISO 3166-2 subdivision code.""" + + subdivisions: tuple[str, ...] = () + """Override parent subdivisions.""" + + subdivisions_aliases: dict[str, str] = {} + """Override parent subdivisions aliases.""" + + def __init__(self, *args, **kwargs): + """Initialize the child entity using its country code. + + A child entity always has its own country code that is different from + the parent entity's country code but (in majority of cases) is a + subdivision of the parent entity. For setting specific subdivision code + value use `parent_entity_subdivision_code`. + """ + kwargs["subdiv"] = self.parent_entity_subdivision_code or self.country + super().__init__(*args, **kwargs) diff --git a/.venv/lib/python3.12/site-packages/holidays/mixins/preferred_discretionary_holidays.py b/.venv/lib/python3.12/site-packages/holidays/mixins/preferred_discretionary_holidays.py new file mode 100644 index 00000000..2a8f206b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/mixins/preferred_discretionary_holidays.py @@ -0,0 +1,28 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + + +class PreferredDiscretionaryHolidays: + """A mixin for setting preferred discretionary holidays. + + See [HongKong][holidays.countries.hongkong.HongKong] for an example. + """ + + default_preferred_discretionary_holidays: tuple[str, ...] = () + """Preferred discretionary holidays defaults.""" + + def __init__(self, preferred_discretionary_holidays): + self.preferred_discretionary_holidays = set( + preferred_discretionary_holidays + if preferred_discretionary_holidays + else self.default_preferred_discretionary_holidays + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/observed_holiday_base.py b/.venv/lib/python3.12/site-packages/holidays/observed_holiday_base.py new file mode 100644 index 00000000..b4b76c7d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/observed_holiday_base.py @@ -0,0 +1,246 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from datetime import date +from typing import Optional + +from holidays.calendars.gregorian import MON, TUE, WED, THU, FRI, SAT, SUN, _timedelta +from holidays.holiday_base import DateArg, HolidayBase + + +class ObservedRule(dict[int, Optional[int]]): + __slots__ = () + + def __add__(self, other): + return ObservedRule({**self, **other}) + + +# Observance calculation rules: +7 - next workday, -7 - previous workday. +# Single days. +MON_TO_NEXT_TUE = ObservedRule({MON: +1}) +MON_ONLY = ObservedRule({TUE: None, WED: None, THU: None, FRI: None, SAT: None, SUN: None}) + +TUE_TO_PREV_MON = ObservedRule({TUE: -1}) +TUE_TO_PREV_FRI = ObservedRule({TUE: -4}) +TUE_TO_NONE = ObservedRule({TUE: None}) + +WED_TO_PREV_MON = ObservedRule({WED: -2}) +WED_TO_NEXT_FRI = ObservedRule({WED: +2}) + +THU_TO_PREV_MON = ObservedRule({THU: -3}) +THU_TO_PREV_WED = ObservedRule({THU: -1}) +THU_TO_NEXT_MON = ObservedRule({THU: +4}) +THU_TO_NEXT_FRI = ObservedRule({THU: +1}) + +FRI_TO_PREV_WED = ObservedRule({FRI: -2}) +FRI_TO_PREV_THU = ObservedRule({FRI: -1}) +FRI_TO_NEXT_MON = ObservedRule({FRI: +3}) +FRI_TO_NEXT_TUE = ObservedRule({FRI: +4}) +FRI_TO_NEXT_SAT = ObservedRule({FRI: +1}) +FRI_TO_NEXT_WORKDAY = ObservedRule({FRI: +7}) +FRI_ONLY = ObservedRule({MON: None, TUE: None, WED: None, THU: None, SAT: None, SUN: None}) + +SAT_TO_PREV_THU = ObservedRule({SAT: -2}) +SAT_TO_PREV_FRI = ObservedRule({SAT: -1}) +SAT_TO_PREV_WORKDAY = ObservedRule({SAT: -7}) +SAT_TO_NEXT_MON = ObservedRule({SAT: +2}) +SAT_TO_NEXT_TUE = ObservedRule({SAT: +3}) +SAT_TO_NEXT_SUN = ObservedRule({SAT: +1}) +SAT_TO_NEXT_WORKDAY = ObservedRule({SAT: +7}) +SAT_TO_NONE = ObservedRule({SAT: None}) + +SUN_TO_PREV_SAT = ObservedRule({SUN: -1}) +SUN_TO_NEXT_MON = ObservedRule({SUN: +1}) +SUN_TO_NEXT_TUE = ObservedRule({SUN: +2}) +SUN_TO_NEXT_WED = ObservedRule({SUN: +3}) +SUN_TO_NEXT_WORKDAY = ObservedRule({SUN: +7}) +SUN_TO_NONE = ObservedRule({SUN: None}) + +# Multiple days. +ALL_TO_NEAREST_MON = ObservedRule({TUE: -1, WED: -2, THU: -3, FRI: +3, SAT: +2, SUN: +1}) +ALL_TO_NEAREST_MON_LATAM = ObservedRule({TUE: -1, WED: -2, THU: 4, FRI: +3, SAT: +2, SUN: +1}) +ALL_TO_NEXT_MON = ObservedRule({TUE: +6, WED: +5, THU: +4, FRI: +3, SAT: +2, SUN: +1}) +ALL_TO_NEXT_SUN = ObservedRule({MON: +6, TUE: +5, WED: +4, THU: +3, FRI: +2, SAT: +1}) + +WORKDAY_TO_NEAREST_MON = ObservedRule({TUE: -1, WED: -2, THU: -3, FRI: +3}) +WORKDAY_TO_NEXT_MON = ObservedRule({TUE: +6, WED: +5, THU: +4, FRI: +3}) +WORKDAY_TO_NEXT_WORKDAY = ObservedRule({MON: +7, TUE: +7, WED: +7, THU: +7, FRI: +7}) + +MON_FRI_ONLY = ObservedRule({TUE: None, WED: None, THU: None, SAT: None, SUN: None}) + +TUE_WED_TO_PREV_MON = ObservedRule({TUE: -1, WED: -2}) +TUE_WED_THU_TO_PREV_MON = ObservedRule({TUE: -1, WED: -2, THU: -3}) +TUE_WED_THU_TO_NEXT_FRI = ObservedRule({TUE: +3, WED: +2, THU: +1}) + +WED_THU_TO_NEXT_FRI = ObservedRule({WED: +2, THU: +1}) + +THU_FRI_TO_NEXT_MON = ObservedRule({THU: +4, FRI: +3}) +THU_FRI_TO_NEXT_WORKDAY = ObservedRule({THU: +7, FRI: +7}) +THU_FRI_SUN_TO_NEXT_MON = ObservedRule({THU: +4, FRI: +3, SUN: +1}) + +FRI_SAT_TO_NEXT_WORKDAY = ObservedRule({FRI: +7, SAT: +7}) +FRI_SUN_TO_NEXT_MON = ObservedRule({FRI: +3, SUN: +1}) +FRI_SUN_TO_NEXT_SAT_MON = ObservedRule({FRI: +1, SUN: +1}) + +SAT_SUN_TO_PREV_FRI = ObservedRule({SAT: -1, SUN: -2}) +SAT_SUN_TO_NEXT_MON = ObservedRule({SAT: +2, SUN: +1}) +SAT_SUN_TO_NEXT_TUE = ObservedRule({SAT: +3, SUN: +2}) +SAT_SUN_TO_NEXT_WED = ObservedRule({SAT: +4, SUN: +3}) +SAT_SUN_TO_NEXT_MON_TUE = ObservedRule({SAT: +2, SUN: +2}) +SAT_SUN_TO_NEXT_WORKDAY = ObservedRule({SAT: +7, SUN: +7}) + + +class ObservedHolidayBase(HolidayBase): + """Observed holidays implementation.""" + + observed_label = "%s" + + def __init__( + self, + observed_rule: Optional[ObservedRule] = None, + observed_since: Optional[int] = None, + *args, + **kwargs, + ): + self._observed_rule = observed_rule or ObservedRule() + self._observed_since = observed_since + super().__init__(*args, **kwargs) + + def _is_observed(self, *args, **kwargs) -> bool: + return self._observed_since is None or self._year >= self._observed_since + + def _get_next_workday(self, dt: date, delta: int = +1) -> date: + dt_work = _timedelta(dt, delta) + while dt_work.year == self._year: + if dt_work in self or self._is_weekend(dt_work): # type: ignore[operator] + dt_work = _timedelta(dt_work, delta) + else: + return dt_work + return dt + + def _get_observed_date(self, dt: date, rule: ObservedRule) -> Optional[date]: + delta = rule.get(dt.weekday(), 0) + if delta: + return ( + self._get_next_workday(dt, delta // 7) + if abs(delta) == 7 + else _timedelta(dt, delta) + ) + # Goes after `if delta` case as a less probable. + elif delta is None: + return None + + return dt + + def _add_observed( + self, + dt: Optional[DateArg] = None, + name: Optional[str] = None, + rule: Optional[ObservedRule] = None, + show_observed_label: bool = True, + ) -> tuple[bool, Optional[date]]: + if dt is None: + return False, None + + # Use as is if already a date. + # Convert to date: (m, d) → use self._year; (y, m, d) → use directly. + dt = dt if isinstance(dt, date) else date(self._year, *dt) if len(dt) == 2 else date(*dt) + + if not self.observed or not self._is_observed(dt): + return False, dt + + dt_observed = self._get_observed_date(dt, rule or self._observed_rule) + if dt_observed == dt: + return False, dt + + # SAT_TO_NONE and similar cases. + if dt_observed is None: + self.pop(dt) + return False, None + + if show_observed_label: + estimated_label = self.tr(getattr(self, "estimated_label", "")) + observed_label = self.tr( + getattr( + self, + "observed_label_before" if dt_observed < dt else "observed_label", + self.observed_label, + ) + ) + + estimated_label_text = estimated_label.strip("%s ()") + # Use observed_estimated_label instead of observed_label for estimated dates. + for name in (name,) if name else self.get_list(dt): + holiday_name = self.tr(name) + observed_estimated_label = None + if estimated_label_text and estimated_label_text in holiday_name: + holiday_name = holiday_name.replace(f"({estimated_label_text})", "").strip() + observed_estimated_label = self.tr(getattr(self, "observed_estimated_label")) + + super()._add_holiday( + (observed_estimated_label or observed_label) % holiday_name, dt_observed + ) + else: + for name in (name,) if name else self.get_list(dt): + super()._add_holiday(name, dt_observed) + + return True, dt_observed + + def _move_holiday( + self, dt: date, rule: Optional[ObservedRule] = None, show_observed_label: bool = True + ) -> tuple[bool, Optional[date]]: + is_observed, dt_observed = self._add_observed( + dt, rule=rule, show_observed_label=show_observed_label + ) + if is_observed: + self.pop(dt) + return is_observed, dt_observed if is_observed else dt + + def _populate_observed(self, dts: set[date], multiple: bool = False) -> None: + """ + When multiple is True, each holiday from a given date has its own observed date. + """ + for dt in sorted(dts): + if not self._is_observed(dt): + continue + if multiple: + for name in self.get_list(dt): + self._add_observed(dt, name) + else: + self._add_observed(dt) + + def _populate_common_holidays(self): + """Populate entity common holidays.""" + super()._populate_common_holidays() + + if not self.observed or not self.has_special_holidays: + return None + + self._add_special_holidays( + (f"special_{category}_holidays_observed" for category in self._sorted_categories), + observed=True, + ) + + def _populate_subdiv_holidays(self): + """Populate entity subdivision holidays.""" + super()._populate_subdiv_holidays() + + if not self.subdiv or not self.observed or not self.has_special_holidays: + return None + + self._add_special_holidays( + ( + f"special_{self._normalized_subdiv}_{category}_holidays_observed" + for category in self._sorted_categories + ), + observed=True, + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/py.typed b/.venv/lib/python3.12/site-packages/holidays/py.typed new file mode 100644 index 00000000..471e51a6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/py.typed @@ -0,0 +1,3 @@ +# Required by PEP 561 to show that we have static types +# See https://www.python.org/dev/peps/pep-0561/#packaging-type-information. +# Enables mypy to discover type hints. diff --git a/.venv/lib/python3.12/site-packages/holidays/registry.py b/.venv/lib/python3.12/site-packages/holidays/registry.py new file mode 100644 index 00000000..53c361b3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/registry.py @@ -0,0 +1,360 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +import importlib +from collections.abc import Iterable +from threading import RLock +from typing import Any, Optional, Union + +from holidays.holiday_base import HolidayBase + +RegistryDict = dict[str, tuple[str, ...]] + +COUNTRIES: RegistryDict = { + "afghanistan": ("Afghanistan", "AF", "AFG"), + "aland_islands": ("AlandIslands", "AX", "ALA", "HolidaysAX"), + "albania": ("Albania", "AL", "ALB"), + "algeria": ("Algeria", "DZ", "DZA"), + "american_samoa": ("AmericanSamoa", "AS", "ASM", "HolidaysAS"), + "andorra": ("Andorra", "AD", "AND"), + "angola": ("Angola", "AO", "AGO"), + "anguilla": ("Anguilla", "AI", "AIA"), + "antigua_and_barbuda": ("AntiguaAndBarbuda", "AG", "ATG"), + "argentina": ("Argentina", "AR", "ARG"), + "armenia": ("Armenia", "AM", "ARM"), + "aruba": ("Aruba", "AW", "ABW"), + "australia": ("Australia", "AU", "AUS"), + "austria": ("Austria", "AT", "AUT"), + "azerbaijan": ("Azerbaijan", "AZ", "AZE"), + "bahamas": ("Bahamas", "BS", "BHS"), + "bahrain": ("Bahrain", "BH", "BAH"), + "bangladesh": ("Bangladesh", "BD", "BGD"), + "barbados": ("Barbados", "BB", "BRB"), + "belarus": ("Belarus", "BY", "BLR"), + "belgium": ("Belgium", "BE", "BEL"), + "belize": ("Belize", "BZ", "BLZ"), + "benin": ("Benin", "BJ", "BEN"), + "bermuda": ("Bermuda", "BM", "BMU"), + "bolivia": ("Bolivia", "BO", "BOL"), + "bonaire_sint_eustatius_and_saba": ("BonaireSintEustatiusAndSaba", "BQ", "BES"), + "bosnia_and_herzegovina": ("BosniaAndHerzegovina", "BA", "BIH"), + "botswana": ("Botswana", "BW", "BWA"), + "brazil": ("Brazil", "BR", "BRA"), + "british_virgin_islands": ("BritishVirginIslands", "VG", "VGB"), + "brunei": ("Brunei", "BN", "BRN"), + "bulgaria": ("Bulgaria", "BG", "BLG"), + "burkina_faso": ("BurkinaFaso", "BF", "BFA"), + "burundi": ("Burundi", "BI", "BDI"), + "cabo_verde": ("CaboVerde", "CV", "CPV"), + "cambodia": ("Cambodia", "KH", "KHM"), + "cameroon": ("Cameroon", "CM", "CMR"), + "canada": ("Canada", "CA", "CAN"), + "cayman_islands": ("CaymanIslands", "KY", "CYM"), + "central_african_republic": ("CentralAfricanRepublic", "CF", "CAF"), + "chad": ("Chad", "TD", "TCD"), + "chile": ("Chile", "CL", "CHL"), + "china": ("China", "CN", "CHN"), + "christmas_island": ("ChristmasIsland", "CX", "CXR"), + "cocos_islands": ("CocosIslands", "CC", "CCK"), + "colombia": ("Colombia", "CO", "COL"), + "congo": ("Congo", "CG", "COG"), + "cook_islands": ("CookIslands", "CK", "COK"), + "costa_rica": ("CostaRica", "CR", "CRI"), + "croatia": ("Croatia", "HR", "HRV"), + "cuba": ("Cuba", "CU", "CUB"), + "curacao": ("Curacao", "CW", "CUW"), + "cyprus": ("Cyprus", "CY", "CYP"), + "czechia": ("Czechia", "CZ", "CZE"), + "denmark": ("Denmark", "DK", "DNK"), + "djibouti": ("Djibouti", "DJ", "DJI"), + "dominica": ("Dominica", "DM", "DMA"), + "dominican_republic": ("DominicanRepublic", "DO", "DOM"), + "dr_congo": ("DRCongo", "CD", "COD"), + "ecuador": ("Ecuador", "EC", "ECU"), + "egypt": ("Egypt", "EG", "EGY"), + "jordan": ("Jordan", "JO", "JOR"), + "el_salvador": ("ElSalvador", "SV", "SLV"), + "equatorial_guinea": ("EquatorialGuinea", "GQ", "GNQ"), + "estonia": ("Estonia", "EE", "EST"), + "eswatini": ("Eswatini", "SZ", "SZW", "Swaziland"), + "ethiopia": ("Ethiopia", "ET", "ETH"), + "falkland_islands": ("FalklandIslands", "FK", "FLK"), + "faroe_islands": ("FaroeIslands", "FO", "FRO"), + "fiji": ("Fiji", "FJ", "FJI"), + "finland": ("Finland", "FI", "FIN"), + "france": ("France", "FR", "FRA"), + "french_guiana": ("FrenchGuiana", "GF", "GUF", "HolidaysGF"), + "french_polynesia": ("FrenchPolynesia", "PF", "PYF", "HolidaysPF"), + "french_southern_territories": ("FrenchSouthernTerritories", "TF", "ATF", "HolidaysTF"), + "gabon": ("Gabon", "GA", "GAB"), + "georgia": ("Georgia", "GE", "GEO"), + "germany": ("Germany", "DE", "DEU"), + "ghana": ("Ghana", "GH", "GHA"), + "gibraltar": ("Gibraltar", "GI", "GIB"), + "greece": ("Greece", "GR", "GRC"), + "greenland": ("Greenland", "GL", "GRL"), + "grenada": ("Grenada", "GD", "GRD"), + "guadeloupe": ("Guadeloupe", "GP", "GLP", "HolidaysGP"), + "guam": ("Guam", "GU", "GUM", "HolidaysGU"), + "guatemala": ("Guatemala", "GT", "GUA"), + "guernsey": ("Guernsey", "GG", "GGY"), + "guinea": ("Guinea", "GN", "GIN"), + "guyana": ("Guyana", "GY", "GUY"), + "haiti": ("Haiti", "HT", "HTI"), + "honduras": ("Honduras", "HN", "HND"), + "hongkong": ("HongKong", "HK", "HKG"), + "hungary": ("Hungary", "HU", "HUN"), + "iceland": ("Iceland", "IS", "ISL"), + "india": ("India", "IN", "IND"), + "indonesia": ("Indonesia", "ID", "IDN"), + "iran": ("Iran", "IR", "IRN"), + "ireland": ("Ireland", "IE", "IRL"), + "isle_of_man": ("IsleOfMan", "IM", "IMN"), + "israel": ("Israel", "IL", "ISR"), + "italy": ("Italy", "IT", "ITA"), + "ivory_coast": ("IvoryCoast", "CI", "CIV"), + "jamaica": ("Jamaica", "JM", "JAM"), + "japan": ("Japan", "JP", "JPN"), + "jersey": ("Jersey", "JE", "JEY"), + "kazakhstan": ("Kazakhstan", "KZ", "KAZ"), + "kenya": ("Kenya", "KE", "KEN"), + "kuwait": ("Kuwait", "KW", "KWT"), + "kyrgyzstan": ("Kyrgyzstan", "KG", "KGZ"), + "laos": ("Laos", "LA", "LAO"), + "latvia": ("Latvia", "LV", "LVA"), + "lebanon": ("Lebanon", "LB", "LBN"), + "lesotho": ("Lesotho", "LS", "LSO"), + "libya": ("Libya", "LY", "LBY"), + "liechtenstein": ("Liechtenstein", "LI", "LIE"), + "lithuania": ("Lithuania", "LT", "LTU"), + "luxembourg": ("Luxembourg", "LU", "LUX"), + "macau": ("Macau", "MO", "MAC"), + "madagascar": ("Madagascar", "MG", "MDG"), + "malawi": ("Malawi", "MW", "MWI"), + "malaysia": ("Malaysia", "MY", "MYS"), + "maldives": ("Maldives", "MV", "MDV"), + "mali": ("Mali", "ML", "MLI"), + "malta": ("Malta", "MT", "MLT"), + "marshall_islands": ("MarshallIslands", "MH", "MHL", "HolidaysMH"), + "martinique": ("Martinique", "MQ", "MTQ", "HolidaysMQ"), + "mauritania": ("Mauritania", "MR", "MRT"), + "mauritius": ("Mauritius", "MU", "MUS"), + "mayotte": ("Mayotte", "YT", "MYT", "HolidaysYT"), + "mexico": ("Mexico", "MX", "MEX"), + "micronesia": ("Micronesia", "FM", "FSM"), + "moldova": ("Moldova", "MD", "MDA"), + "monaco": ("Monaco", "MC", "MCO"), + "mongolia": ("Mongolia", "MN", "MNG"), + "montenegro": ("Montenegro", "ME", "MNE"), + "montserrat": ("Montserrat", "MS", "MSR"), + "morocco": ("Morocco", "MA", "MOR"), + "mozambique": ("Mozambique", "MZ", "MOZ"), + "namibia": ("Namibia", "NA", "NAM"), + "nauru": ("Nauru", "NR", "NRU"), + "nepal": ("Nepal", "NP", "NPL"), + "netherlands": ("Netherlands", "NL", "NLD"), + "new_caledonia": ("NewCaledonia", "NC", "NCL", "HolidaysNC"), + "new_zealand": ("NewZealand", "NZ", "NZL"), + "nicaragua": ("Nicaragua", "NI", "NIC"), + "niger": ("Niger", "NE", "NER"), + "nigeria": ("Nigeria", "NG", "NGA"), + "niue": ("Niue", "NU", "NIU"), + "norfolk_island": ("NorfolkIsland", "NF", "NFK"), + "north_macedonia": ("NorthMacedonia", "MK", "MKD"), + "northern_mariana_islands": ("NorthernMarianaIslands", "MP", "MNP", "HolidaysMP"), + "norway": ("Norway", "NO", "NOR"), + "oman": ("Oman", "OM", "OMN"), + "pakistan": ("Pakistan", "PK", "PAK"), + "palau": ("Palau", "PW", "PLW"), + "palestine": ("Palestine", "PS", "PSE"), + "panama": ("Panama", "PA", "PAN"), + "papua_new_guinea": ("PapuaNewGuinea", "PG", "PNG"), + "paraguay": ("Paraguay", "PY", "PRY"), + "peru": ("Peru", "PE", "PER"), + "philippines": ("Philippines", "PH", "PHL"), + "poland": ("Poland", "PL", "POL"), + "portugal": ("Portugal", "PT", "PRT"), + "puerto_rico": ("PuertoRico", "PR", "PRI", "HolidaysPR"), + "qatar": ("Qatar", "QA", "QAT"), + "reunion": ("Reunion", "RE", "REU", "HolidaysRE"), + "romania": ("Romania", "RO", "ROU"), + "russia": ("Russia", "RU", "RUS"), + "saint_barthelemy": ("SaintBarthelemy", "BL", "BLM", "HolidaysBL"), + "saint_kitts_and_nevis": ("SaintKittsAndNevis", "KN", "KNA"), + "saint_lucia": ("SaintLucia", "LC", "LCA"), + "saint_martin": ("SaintMartin", "MF", "MAF", "HolidaysMF"), + "saint_pierre_and_miquelon": ("SaintPierreAndMiquelon", "PM", "SPM", "HolidaysPM"), + "saint_vincent_and_the_grenadines": ("SaintVincentAndTheGrenadines", "VC", "VCT"), + "samoa": ("Samoa", "WS", "WSM"), + "san_marino": ("SanMarino", "SM", "SMR"), + "sao_tome_and_principe": ("SaoTomeAndPrincipe", "ST", "STP"), + "saudi_arabia": ("SaudiArabia", "SA", "SAU"), + "senegal": ("Senegal", "SN", "SEN"), + "serbia": ("Serbia", "RS", "SRB"), + "seychelles": ("Seychelles", "SC", "SYC"), + "sierra_leone": ("SierraLeone", "SL", "SLE"), + "singapore": ("Singapore", "SG", "SGP"), + "sint_maarten": ("SintMaarten", "SX", "SXM"), + "slovakia": ("Slovakia", "SK", "SVK"), + "slovenia": ("Slovenia", "SI", "SVN"), + "solomon_islands": ("SolomonIslands", "SB", "SLB"), + "south_africa": ("SouthAfrica", "ZA", "ZAF"), + "south_korea": ("SouthKorea", "KR", "KOR", "Korea"), + "spain": ("Spain", "ES", "ESP"), + "sri_lanka": ("SriLanka", "LK", "LKA"), + "suriname": ("Suriname", "SR", "SUR"), + "svalbard_and_jan_mayen": ("SvalbardAndJanMayen", "SJ", "SJM", "HolidaysSJ"), + "sweden": ("Sweden", "SE", "SWE"), + "switzerland": ("Switzerland", "CH", "CHE"), + "taiwan": ("Taiwan", "TW", "TWN"), + "tanzania": ("Tanzania", "TZ", "TZA"), + "thailand": ("Thailand", "TH", "THA"), + "timor_leste": ("TimorLeste", "TL", "TLS"), + "togo": ("Togo", "TG", "TGO"), + "tokelau": ("Tokelau", "TK", "TKL"), + "tonga": ("Tonga", "TO", "TON"), + "trinidad_and_tobago": ("TrinidadAndTobago", "TT", "TTO"), + "tunisia": ("Tunisia", "TN", "TUN"), + "turkey": ("Turkey", "TR", "TUR"), + "turks_and_caicos_islands": ("TurksAndCaicosIslands", "TC", "TCA"), + "tuvalu": ("Tuvalu", "TV", "TUV"), + "ukraine": ("Ukraine", "UA", "UKR"), + "united_arab_emirates": ("UnitedArabEmirates", "AE", "ARE"), + "united_kingdom": ("UnitedKingdom", "GB", "GBR", "UK"), + "united_states_minor_outlying_islands": ( + "UnitedStatesMinorOutlyingIslands", + "UM", + "UMI", + "HolidaysUM", + ), + "united_states_virgin_islands": ("UnitedStatesVirginIslands", "VI", "VIR", "HolidaysVI"), + "united_states": ("UnitedStates", "US", "USA"), + "uruguay": ("Uruguay", "UY", "URY"), + "uzbekistan": ("Uzbekistan", "UZ", "UZB"), + "vanuatu": ("Vanuatu", "VU", "VTU"), + "vatican_city": ("VaticanCity", "VA", "VAT"), + "venezuela": ("Venezuela", "VE", "VEN"), + "vietnam": ("Vietnam", "VN", "VNM"), + "wallis_and_futuna": ("WallisAndFutuna", "WF", "WLF", "HolidaysWF"), + "yemen": ("Yemen", "YE", "YEM"), + "zambia": ("Zambia", "ZM", "ZMB"), + "zimbabwe": ("Zimbabwe", "ZW", "ZWE"), +} + +FINANCIAL: RegistryDict = { + "european_central_bank": ("EuropeanCentralBank", "XECB", "ECB", "TAR"), + "ice_futures_europe": ("ICEFuturesEurope", "IFEU"), + "ny_stock_exchange": ("NewYorkStockExchange", "XNYS", "NYSE"), + "brasil_bolsa_balcao": ("BrasilBolsaBalcao", "BVMF", "B3"), +} + +# A re-entrant lock. Once a thread has acquired a re-entrant lock, +# the same thread may acquire it again without blocking. +# https://docs.python.org/3/library/threading.html#rlock-objects +IMPORT_LOCK = RLock() + + +class EntityLoader: + """Country and financial holidays entities lazy loader.""" + + __slots__ = ("entity", "entity_name", "module_name") + + def __init__(self, path: str, *args, **kwargs) -> None: + """Set up a lazy loader.""" + if args: + raise TypeError( + "This is a holidays entity loader class. " + "For entity inheritance purposes please import a class you " + "want to derive from directly: e.g., " + "`from holidays.countries import Entity` or " + "`from holidays.financial import Entity`." + ) + + entity_path = path.split(".") + + self.entity = None + self.entity_name = entity_path[-1] + self.module_name = ".".join(entity_path[0:-1]) + + super().__init__(*args, **kwargs) + + def __call__(self, *args, **kwargs) -> HolidayBase: + """Create a new instance of a lazy-loaded entity.""" + cls = self.get_entity() + return cls(*args, **kwargs) # type: ignore[misc, operator] + + def __getattr__(self, name: str) -> Optional[Any]: + """Return attribute of a lazy-loaded entity.""" + cls = self.get_entity() + return getattr(cls, name) + + def __str__(self) -> str: + """Return lazy loader object string representation.""" + return ( + f"A lazy loader for {self.get_entity()}. For inheritance please " + f"use the '{self.module_name}.{self.entity_name}' class directly." + ) + + def get_entity(self) -> Optional[HolidayBase]: + """Return lazy-loaded entity.""" + if self.entity is None: + # Avoid deadlock due to importlib.import_module not being thread-safe by caching all + # the first imports in a dedicated thread. + with IMPORT_LOCK: + self.entity = getattr(importlib.import_module(self.module_name), self.entity_name) + + return self.entity + + @staticmethod + def _get_entity_codes( + container: RegistryDict, + entity_length: Union[int, Iterable[int]], + include_aliases: bool = True, + ) -> Iterable[str]: + entity_length = {entity_length} if isinstance(entity_length, int) else set(entity_length) + for entities in container.values(): + for entity in entities: + if len(entity) in entity_length: + yield entity + # Assuming that the alpha-2 code goes first. + if not include_aliases: + break + + @staticmethod + def get_country_codes(include_aliases: bool = True) -> Iterable[str]: + """Get supported country codes. + + :param include_aliases: + Whether to include entity aliases (e.g. UK for GB). + """ + return EntityLoader._get_entity_codes(COUNTRIES, 2, include_aliases) + + @staticmethod + def get_financial_codes(include_aliases: bool = True) -> Iterable[str]: + """Get supported financial codes. + + :param include_aliases: + Whether to include entity aliases(e.g. TAR for ECB, XNYS for NYSE). + """ + return EntityLoader._get_entity_codes(FINANCIAL, (3, 4), include_aliases) + + @staticmethod + def load(prefix: str, scope: dict) -> None: + """Load country or financial entities.""" + entity_mapping = COUNTRIES if prefix == "countries" else FINANCIAL + for module, entities in entity_mapping.items(): + scope.update( + { + entity: EntityLoader(f"holidays.{prefix}.{module}.{entity}") + for entity in entities + } + ) diff --git a/.venv/lib/python3.12/site-packages/holidays/utils.py b/.venv/lib/python3.12/site-packages/holidays/utils.py new file mode 100644 index 00000000..9671329c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/utils.py @@ -0,0 +1,437 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +__all__ = ( + "country_holidays", + "CountryHoliday", + "financial_holidays", + "list_localized_countries", + "list_localized_financial", + "list_supported_countries", + "list_supported_financial", +) + +import warnings +from collections.abc import Iterable +from functools import lru_cache +from typing import Optional, Union + +from holidays.holiday_base import CategoryArg, HolidayBase +from holidays.registry import EntityLoader + + +def country_holidays( + country: str, + subdiv: Optional[str] = None, + years: Optional[Union[int, Iterable[int]]] = None, + expand: bool = True, + observed: bool = True, + prov: Optional[str] = None, + state: Optional[str] = None, + language: Optional[str] = None, + categories: Optional[CategoryArg] = None, +) -> HolidayBase: + """ + Returns a new dictionary-like `HolidayBase` object for the public + holidays of the country matching **country** and other keyword arguments. + + Args: + country: + An ISO 3166-1 Alpha-2 country code. + + subdiv: + The subdivision (e.g. state or province) as a ISO 3166-2 code + or its alias; not implemented for all countries (see documentation). + + years: + The year(s) to pre-calculate public holidays for at instantiation. + + expand: + Whether the entire year is calculated when one date from that year + is requested. + + observed: + Whether to include the dates of when public holiday are observed + (e.g. a holiday falling on a Sunday being observed the following + Monday). False may not work for all countries. + + prov: + *deprecated* use `subdiv` instead. + + state: + *deprecated* use `subdiv` instead. + + language: + Specifies the language in which holiday names are returned. + + Accepts either: + + * A two-letter ISO 639-1 language code (e.g., 'en' for English, 'fr' for French), + or + * A language and entity combination using an underscore (e.g., 'en_US' for U.S. + English, 'pt_BR' for Brazilian Portuguese). + + !!! warning + The provided language or locale code must be supported by the holiday + entity. Unsupported values will result in names being shown in the entity's + original language. + + If not explicitly set (`language=None`), the system attempts to infer the + language from the environment's locale settings. The following environment + variables are checked, in order of precedence: LANGUAGE, LC_ALL, LC_MESSAGES, LANG. + + If none of these are set or they are empty, holiday names will default to the + original language of the entity's holiday implementation. + + !!! warning + This fallback mechanism may yield inconsistent results across environments + (e.g., between a terminal session and a Jupyter notebook). + + To ensure consistent behavior, it is recommended to set the language parameter + explicitly. If the specified language is not supported, holiday names will remain + in the original language of the entity's holiday implementation. + + This behavior will be updated and formalized in v1. + + categories: + Requested holiday categories. + + Returns: + A `HolidayBase` object matching the **country**. + + The key of the `dict`-like `HolidayBase` object is the + `date` of the holiday, and the value is the name of the holiday itself. + Dates where a key is not present are not public holidays (or, if + **observed** is False, days when a public holiday is observed). + + When passing the `date` as a key, the `date` can be expressed in one of the + following types: + + * `datetime.date`, + * `datetime.datetime`, + * a `str` of any format recognized by `dateutil.parser.parse()`, + * or a `float` or `int` representing a POSIX timestamp. + + The key is always returned as a `datetime.date` object. + + To maximize speed, the list of public holidays is built on the fly as + needed, one calendar year at a time. When the object is instantiated + without a **years** parameter, it is empty, but, unless **expand** is set + to False, as soon as a key is accessed the class will calculate that entire + year's list of holidays and set the keys with them. + + If you need to list the holidays as opposed to querying individual dates, + instantiate the class with the **years** parameter. + + Example usage: + + >>> from holidays import country_holidays + >>> us_holidays = country_holidays('US') + # For a specific subdivision (e.g. state or province): + >>> calif_holidays = country_holidays('US', subdiv='CA') + + The below will cause 2015 holidays to be calculated on the fly: + + >>> from datetime import date + >>> assert date(2015, 1, 1) in us_holidays + + This will be faster because 2015 holidays are already calculated: + + >>> assert date(2015, 1, 2) not in us_holidays + + The `HolidayBase` class also recognizes strings of many formats + and numbers representing a POSIX timestamp: + + >>> assert '2014-01-01' in us_holidays + >>> assert '1/1/2014' in us_holidays + >>> assert 1388597445 in us_holidays + + Show the holiday's name: + + >>> us_holidays.get('2014-01-01') + "New Year's Day" + + Check a range: + + >>> us_holidays['2014-01-01': '2014-01-03'] + [datetime.date(2014, 1, 1)] + + List all 2020 holidays: + + >>> us_holidays = country_holidays('US', years=2020) + >>> for day in sorted(us_holidays.items()): + ... print(day) + (datetime.date(2020, 1, 1), "New Year's Day") + (datetime.date(2020, 1, 20), 'Martin Luther King Jr. Day') + (datetime.date(2020, 2, 17), "Washington's Birthday") + (datetime.date(2020, 5, 25), 'Memorial Day') + (datetime.date(2020, 7, 3), 'Independence Day (observed)') + (datetime.date(2020, 7, 4), 'Independence Day') + (datetime.date(2020, 9, 7), 'Labor Day') + (datetime.date(2020, 10, 12), 'Columbus Day') + (datetime.date(2020, 11, 11), 'Veterans Day') + (datetime.date(2020, 11, 26), 'Thanksgiving Day') + (datetime.date(2020, 12, 25), 'Christmas Day') + + Some holidays are only present in parts of a country: + + >>> us_pr_holidays = country_holidays('US', subdiv='PR') + >>> assert '2018-01-06' not in us_holidays + >>> assert '2018-01-06' in us_pr_holidays + + Append custom holiday dates by passing one of: + + * a `dict` with date/name key/value pairs (e.g. + `{'2010-07-10': 'My birthday!'}`), + * a list of dates (as a `datetime.date`, `datetime.datetime`, + `str`, `int`, or `float`); "Holiday" will be used as a description, + * or a single date item (of one of the types above); "Holiday" will be + used as a description: + + ```python + >>> custom_holidays = country_holidays('US', years=2015) + >>> custom_holidays.update({'2015-01-01': "New Year's Day"}) + >>> custom_holidays.update(['2015-07-01', '07/04/2015']) + >>> custom_holidays.update(date(2015, 12, 25)) + >>> assert date(2015, 1, 1) in custom_holidays + >>> assert date(2015, 1, 2) not in custom_holidays + >>> assert '12/25/2015' in custom_holidays + ``` + + For more complex logic, like 4th Monday of January, you can inherit the + `HolidayBase` class and define your own `_populate` method. + See documentation for examples. + """ + import holidays + + try: + return getattr(holidays, country)( + years=years, + subdiv=subdiv, + expand=expand, + observed=observed, + prov=prov, + state=state, + language=language, + categories=categories, + ) + except AttributeError: + raise NotImplementedError(f"Country {country} not available") + + +def financial_holidays( + market: str, + subdiv: Optional[str] = None, + years: Optional[Union[int, Iterable[int]]] = None, + expand: bool = True, + observed: bool = True, + language: Optional[str] = None, +) -> HolidayBase: + """ + Returns a new dictionary-like :py:class:`HolidayBase` object for the public + holidays of the financial market matching **market** and other keyword + arguments. + + Args: + market: + An ISO 3166-1 Alpha-2 market code. + + subdiv: + Currently not implemented for markets (see documentation). + + years: + The year(s) to pre-calculate public holidays for at instantiation. + + expand: + Whether the entire year is calculated when one date from that year + is requested. + + observed: + Whether to include the dates of when public holiday are observed + (e.g. a holiday falling on a Sunday being observed the following + Monday). False may not work for all countries. + + language: + Specifies the language in which holiday names are returned. + + Accepts either: + + * A two-letter ISO 639-1 language code (e.g., 'en' for English, 'fr' for French), + or + * A language and entity combination using an underscore (e.g., 'en_US' for U.S. + English, 'pt_BR' for Brazilian Portuguese). + + !!! warning + The provided language or locale code must be supported by the holiday + entity. Unsupported values will result in names being shown in the entity's + original language. + + If not explicitly set (`language=None`), the system attempts to infer the + language from the environment's locale settings. The following environment + variables are checked, in order of precedence: LANGUAGE, LC_ALL, LC_MESSAGES, LANG. + + If none of these are set or they are empty, holiday names will default to the + original language of the entity's holiday implementation. + + !!! warning + This fallback mechanism may yield inconsistent results across environments + (e.g., between a terminal session and a Jupyter notebook). + + To ensure consistent behavior, it is recommended to set the language parameter + explicitly. If the specified language is not supported, holiday names will remain + in the original language of the entity's holiday implementation. + + This behavior will be updated and formalized in v1. + + Returns: + A `HolidayBase` object matching the **market**. + + Example usage: + + >>> from holidays import financial_holidays + >>> nyse_holidays = financial_holidays('XNYS') + + See [country_holidays()][holidays.utils.country_holidays] documentation for further + details and examples. + """ + import holidays + + try: + return getattr(holidays, market)( + years=years, subdiv=subdiv, expand=expand, observed=observed, language=language + ) + except AttributeError: + raise NotImplementedError(f"Financial market {market} not available") + + +def CountryHoliday( # noqa: N802 + country: str, + subdiv: Optional[str] = None, + years: Optional[Union[int, Iterable[int]]] = None, + expand: bool = True, + observed: bool = True, + prov: Optional[str] = None, + state: Optional[str] = None, +) -> HolidayBase: + """ + Note: + Deprecated name for `country_holidays()`. + """ + + warnings.warn( + "CountryHoliday is deprecated, use country_holidays instead.", DeprecationWarning + ) + return country_holidays(country, subdiv, years, expand, observed, prov, state) + + +def _list_localized_entities(entity_codes: Iterable[str]) -> dict[str, list[str]]: + """Get all localized entities and languages they support. + + Args: + entity_codes: + A list of entity codes. + + Returns: + A dictionary where key is an entity code and value is a list of supported + languages (either ISO 639-1 or a combination of ISO 639-1 and ISO 3166-1 codes joined + with "_"). + """ + import holidays + + localized_countries = {} + for entity_code in entity_codes: + languages = getattr(holidays, entity_code).supported_languages + if not languages: + continue + localized_countries[entity_code] = sorted(languages) + + return localized_countries + + +@lru_cache +def list_localized_countries(include_aliases: bool = True) -> dict[str, list[str]]: + """Get all localized countries and languages they support. + + Args: + include_aliases: + Whether to include entity aliases (e.g. UK for GB). + + Returns: + A dictionary where key is an ISO 3166-1 alpha-2 country code and value is a + list of supported languages (either ISO 639-1 or a combination of ISO 639-1 + and ISO 3166-1 codes joined with "_"). + """ + return _list_localized_entities(EntityLoader.get_country_codes(include_aliases)) + + +@lru_cache +def list_localized_financial(include_aliases: bool = True) -> dict[str, list[str]]: + """Get all localized financial markets and languages they support. + + Args: + include_aliases: + Whether to include entity aliases (e.g. TAR for ECB, XNYS for NYSE). + + Returns: + A dictionary where key is a market code and value is a list of supported + subdivision codes. + """ + return _list_localized_entities(EntityLoader.get_financial_codes(include_aliases)) + + +def _list_supported_entities(entity_codes: Iterable[str]) -> dict[str, list[str]]: + """Get all supported entities and their subdivisions. + + Args: + entity_codes: + A list of entity codes. + + Returns: + A dictionary where key is an entity code and value is a list of supported + subdivision codes. + """ + import holidays + + return { + country_code: list(getattr(holidays, country_code).subdivisions) + for country_code in entity_codes + } + + +@lru_cache +def list_supported_countries(include_aliases: bool = True) -> dict[str, list[str]]: + """Get all supported countries and their subdivisions. + + Args: + include_aliases: + Whether to include entity aliases (e.g. UK for GB). + + Returns: + A dictionary where key is an ISO 3166-1 alpha-2 country code and value + is a list of supported subdivision codes. + """ + return _list_supported_entities(EntityLoader.get_country_codes(include_aliases)) + + +@lru_cache +def list_supported_financial(include_aliases: bool = True) -> dict[str, list[str]]: + """Get all supported financial markets and their subdivisions. + + Args: + include_aliases: + Whether to include entity aliases (e.g. TAR for ECB, XNYS for NYSE). + + Returns: + A dictionary where key is a market code and value is a list of supported + subdivision codes. + """ + return _list_supported_entities(EntityLoader.get_financial_codes(include_aliases)) diff --git a/.venv/lib/python3.12/site-packages/holidays/version.py b/.venv/lib/python3.12/site-packages/holidays/version.py new file mode 100644 index 00000000..90f93729 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/holidays/version.py @@ -0,0 +1,13 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +__version__ = "0.77" diff --git a/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/LICENSE b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/METADATA b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/METADATA new file mode 100644 index 00000000..474de805 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: importlib_resources +Version: 6.5.2 +Summary: Read resources from Python packages +Author-email: Barry Warsaw +Maintainer-email: "Jason R. Coombs" +Project-URL: Source, https://github.com/python/importlib_resources +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Requires-Python: >=3.9 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: zipp>=3.1.0; python_version < "3.10" +Provides-Extra: test +Requires-Dist: pytest!=8.1.*,>=6; extra == "test" +Requires-Dist: zipp>=3.17; extra == "test" +Requires-Dist: jaraco.test>=5.4; extra == "test" +Provides-Extra: doc +Requires-Dist: sphinx>=3.5; extra == "doc" +Requires-Dist: jaraco.packaging>=9.3; extra == "doc" +Requires-Dist: rst.linker>=1.9; extra == "doc" +Requires-Dist: furo; extra == "doc" +Requires-Dist: sphinx-lint; extra == "doc" +Requires-Dist: jaraco.tidelift>=1.4; extra == "doc" +Provides-Extra: check +Requires-Dist: pytest-checkdocs>=2.4; extra == "check" +Requires-Dist: pytest-ruff>=0.2.1; sys_platform != "cygwin" and extra == "check" +Provides-Extra: cover +Requires-Dist: pytest-cov; extra == "cover" +Provides-Extra: enabler +Requires-Dist: pytest-enabler>=2.2; extra == "enabler" +Provides-Extra: type +Requires-Dist: pytest-mypy; extra == "type" + +.. image:: https://img.shields.io/pypi/v/importlib_resources.svg + :target: https://pypi.org/project/importlib_resources + +.. image:: https://img.shields.io/pypi/pyversions/importlib_resources.svg + +.. image:: https://github.com/python/importlib_resources/actions/workflows/main.yml/badge.svg + :target: https://github.com/python/importlib_resources/actions?query=workflow%3A%22tests%22 + :alt: tests + +.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json + :target: https://github.com/astral-sh/ruff + :alt: Ruff + +.. image:: https://readthedocs.org/projects/importlib-resources/badge/?version=latest + :target: https://importlib-resources.readthedocs.io/en/latest/?badge=latest + +.. image:: https://img.shields.io/badge/skeleton-2025-informational + :target: https://blog.jaraco.com/skeleton + +.. image:: https://tidelift.com/badges/package/pypi/importlib-resources + :target: https://tidelift.com/subscription/pkg/pypi-importlib-resources?utm_source=pypi-importlib-resources&utm_medium=readme + +``importlib_resources`` is a backport of Python standard library +`importlib.resources +`_ +module for older Pythons. + +The key goal of this module is to replace parts of `pkg_resources +`_ with a +solution in Python's stdlib that relies on well-defined APIs. This makes +reading resources included in packages easier, with more stable and consistent +semantics. + +Compatibility +============= + +New features are introduced in this third-party library and later merged +into CPython. The following table indicates which versions of this library +were contributed to different versions in the standard library: + +.. list-table:: + :header-rows: 1 + + * - importlib_resources + - stdlib + * - 6.0 + - 3.13 + * - 5.12 + - 3.12 + * - 5.7 + - 3.11 + * - 5.0 + - 3.10 + * - 1.3 + - 3.9 + * - 0.5 (?) + - 3.7 + +For Enterprise +============== + +Available as part of the Tidelift Subscription. + +This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. + +`Learn more `_. diff --git a/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/RECORD b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/RECORD new file mode 100644 index 00000000..6e207562 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/RECORD @@ -0,0 +1,67 @@ +importlib_resources-6.5.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +importlib_resources-6.5.2.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358 +importlib_resources-6.5.2.dist-info/METADATA,sha256=yglT_7S_PsrSQaVTgZKQYfomaUlD-pV74f_9Ld0RjoY,3947 +importlib_resources-6.5.2.dist-info/RECORD,, +importlib_resources-6.5.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91 +importlib_resources-6.5.2.dist-info/top_level.txt,sha256=fHIjHU1GZwAjvcydpmUnUrTnbvdiWjG4OEVZK8by0TQ,20 +importlib_resources/__init__.py,sha256=F6SOMZILiez96lK3h9duE_c5kRTEydzHvI6D7TRcOJE,700 +importlib_resources/__pycache__/__init__.cpython-312.pyc,, +importlib_resources/__pycache__/_adapters.cpython-312.pyc,, +importlib_resources/__pycache__/_common.cpython-312.pyc,, +importlib_resources/__pycache__/_functional.cpython-312.pyc,, +importlib_resources/__pycache__/_itertools.cpython-312.pyc,, +importlib_resources/__pycache__/abc.cpython-312.pyc,, +importlib_resources/__pycache__/readers.cpython-312.pyc,, +importlib_resources/__pycache__/simple.cpython-312.pyc,, +importlib_resources/_adapters.py,sha256=vprJGbUeHbajX6XCuMP6J3lMrqCi-P_MTlziJUR7jfk,4482 +importlib_resources/_common.py,sha256=Vfmmdk5ICrZ8odgfWEuUHG-P7ZbJ-5x3pRLCVwVk8Tg,5624 +importlib_resources/_functional.py,sha256=nMop9Zc7g1Yhiyk5oqr9ukvfJcOx4vnvqD7nh24hV7Y,2743 +importlib_resources/_itertools.py,sha256=eDisV6RqiNZOogLSXf6LOGHOYc79FGgPrKNLzFLmCrU,1277 +importlib_resources/abc.py,sha256=inhYsYj6LrYHn4kCraZq8zqXFQnDX4stNnLTruhf6NU,5549 +importlib_resources/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +importlib_resources/compat/__pycache__/__init__.cpython-312.pyc,, +importlib_resources/compat/__pycache__/py39.cpython-312.pyc,, +importlib_resources/compat/py39.py,sha256=gx5NE25XH1pQrTRJDY7QJUngZpD7OotsK9F6pZy5KjM,151 +importlib_resources/future/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +importlib_resources/future/__pycache__/__init__.cpython-312.pyc,, +importlib_resources/future/__pycache__/adapters.cpython-312.pyc,, +importlib_resources/future/adapters.py,sha256=UFIMxEuLo4PqcVbtoV3e_k9BcxCS-mmG22f8U2Vtkx4,3285 +importlib_resources/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +importlib_resources/readers.py,sha256=uHf9X-smA3CtxdB9IHWH0z-O53379wlcEMmzA2UXzqE,6250 +importlib_resources/simple.py,sha256=wJm2qGZ9EMPFhRLiJBa9Em5tVKbD7Q8ibWtt4ZNgWBU,2590 +importlib_resources/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +importlib_resources/tests/__pycache__/__init__.cpython-312.pyc,, +importlib_resources/tests/__pycache__/_path.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_contents.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_custom.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_files.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_functional.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_open.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_path.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_read.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_reader.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_resource.cpython-312.pyc,, +importlib_resources/tests/__pycache__/test_util.cpython-312.pyc,, +importlib_resources/tests/__pycache__/util.cpython-312.pyc,, +importlib_resources/tests/__pycache__/zip.cpython-312.pyc,, +importlib_resources/tests/_path.py,sha256=IK3o6J_4UaN-4DPuwKr0lOb2KWpoUjwIyQkOtGqZWzs,2250 +importlib_resources/tests/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +importlib_resources/tests/compat/__pycache__/__init__.cpython-312.pyc,, +importlib_resources/tests/compat/__pycache__/py312.cpython-312.pyc,, +importlib_resources/tests/compat/__pycache__/py39.cpython-312.pyc,, +importlib_resources/tests/compat/py312.py,sha256=qcWjpZhQo2oEsdwIlRRQHrsMGDltkFTnETeG7fLdUS8,364 +importlib_resources/tests/compat/py39.py,sha256=nOjut4CZDtRgZEblX9hWhupo9vli_CA1270_JwdQzRo,441 +importlib_resources/tests/test_compatibilty_files.py,sha256=cOLwa5kU6ucxNfiNsAQSpLHCE8asuqAHui6Aw9mxKX8,3313 +importlib_resources/tests/test_contents.py,sha256=r8kVH1k7DHrco2JVTUMCbsWK0JvvjKt0zgrmH56c4Vg,838 +importlib_resources/tests/test_custom.py,sha256=ep5mGT6uT6O1gPdM-b3mXo9HWDnCLD90uc4H1bU68oI,1222 +importlib_resources/tests/test_files.py,sha256=u4vMrXPpaWGJY8DyFJBkgg78lr_l9sfjzatP_7mkn88,5741 +importlib_resources/tests/test_functional.py,sha256=B3cFWFztSkMh4Y58MyOex_lcEooIPR-ezTaA9xzI6Y4,9070 +importlib_resources/tests/test_open.py,sha256=dT-cZmJoGbMMIVVWkNXt8KUxWcQn9Cd0emb85U4CiBA,2682 +importlib_resources/tests/test_path.py,sha256=orETYbmGyYNgXA8Dslj9MM3XjGUDRW8u4dJhIBy0qdU,1986 +importlib_resources/tests/test_read.py,sha256=o3uXJCUTYmUZeaFoQyXeRxTPpwhbjgRz-aALAg_btz8,3046 +importlib_resources/tests/test_reader.py,sha256=1RFB-rJs1hCDSy6qgv2z3LDm42gbQmj2n718CCdn1JY,4655 +importlib_resources/tests/test_resource.py,sha256=ZgpXCuYs4GZpSCElJyhZlMkb8oOfMZX1cnPLoinzis0,7687 +importlib_resources/tests/test_util.py,sha256=VotLNbngOyFg03FKVTzIZKd4Gz4UO-dMEr0G-vHMiuI,1105 +importlib_resources/tests/util.py,sha256=PKybGEyCo53mMu7A-5vC6n0e3nc9R8DS2NtvO-JCyxY,9804 +importlib_resources/tests/zip.py,sha256=nG9D6u_4nu67NrEUFfMt7vzba0qO_-QPyAAWc6W4gP4,577 diff --git a/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/WHEEL new file mode 100644 index 00000000..ae527e7d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (75.6.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/top_level.txt b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/top_level.txt new file mode 100644 index 00000000..58ad1bd3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources-6.5.2.dist-info/top_level.txt @@ -0,0 +1 @@ +importlib_resources diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__init__.py b/.venv/lib/python3.12/site-packages/importlib_resources/__init__.py new file mode 100644 index 00000000..27d6c7f8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/__init__.py @@ -0,0 +1,40 @@ +""" +Read resources contained within a package. + +This codebase is shared between importlib.resources in the stdlib +and importlib_resources in PyPI. See +https://github.com/python/importlib_metadata/wiki/Development-Methodology +for more detail. +""" + +from ._common import ( + Anchor, + Package, + as_file, + files, +) +from ._functional import ( + contents, + is_resource, + open_binary, + open_text, + path, + read_binary, + read_text, +) +from .abc import ResourceReader + +__all__ = [ + 'Package', + 'Anchor', + 'ResourceReader', + 'as_file', + 'files', + 'contents', + 'is_resource', + 'open_binary', + 'open_text', + 'path', + 'read_binary', + 'read_text', +] diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..82780874 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_adapters.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_adapters.cpython-312.pyc new file mode 100644 index 00000000..d136b3d0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_adapters.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_common.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_common.cpython-312.pyc new file mode 100644 index 00000000..e094e56d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_common.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_functional.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_functional.cpython-312.pyc new file mode 100644 index 00000000..1baf7360 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_functional.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_itertools.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_itertools.cpython-312.pyc new file mode 100644 index 00000000..2cd3e24f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/_itertools.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/abc.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/abc.cpython-312.pyc new file mode 100644 index 00000000..df6cd82f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/abc.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/readers.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/readers.cpython-312.pyc new file mode 100644 index 00000000..d7d34b27 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/readers.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/simple.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/simple.cpython-312.pyc new file mode 100644 index 00000000..f101144f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/__pycache__/simple.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/_adapters.py b/.venv/lib/python3.12/site-packages/importlib_resources/_adapters.py new file mode 100644 index 00000000..50688fbb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/_adapters.py @@ -0,0 +1,168 @@ +from contextlib import suppress +from io import TextIOWrapper + +from . import abc + + +class SpecLoaderAdapter: + """ + Adapt a package spec to adapt the underlying loader. + """ + + def __init__(self, spec, adapter=lambda spec: spec.loader): + self.spec = spec + self.loader = adapter(spec) + + def __getattr__(self, name): + return getattr(self.spec, name) + + +class TraversableResourcesLoader: + """ + Adapt a loader to provide TraversableResources. + """ + + def __init__(self, spec): + self.spec = spec + + def get_resource_reader(self, name): + return CompatibilityFiles(self.spec)._native() + + +def _io_wrapper(file, mode='r', *args, **kwargs): + if mode == 'r': + return TextIOWrapper(file, *args, **kwargs) + elif mode == 'rb': + return file + raise ValueError(f"Invalid mode value '{mode}', only 'r' and 'rb' are supported") + + +class CompatibilityFiles: + """ + Adapter for an existing or non-existent resource reader + to provide a compatibility .files(). + """ + + class SpecPath(abc.Traversable): + """ + Path tied to a module spec. + Can be read and exposes the resource reader children. + """ + + def __init__(self, spec, reader): + self._spec = spec + self._reader = reader + + def iterdir(self): + if not self._reader: + return iter(()) + return iter( + CompatibilityFiles.ChildPath(self._reader, path) + for path in self._reader.contents() + ) + + def is_file(self): + return False + + is_dir = is_file + + def joinpath(self, other): + if not self._reader: + return CompatibilityFiles.OrphanPath(other) + return CompatibilityFiles.ChildPath(self._reader, other) + + @property + def name(self): + return self._spec.name + + def open(self, mode='r', *args, **kwargs): + return _io_wrapper(self._reader.open_resource(None), mode, *args, **kwargs) + + class ChildPath(abc.Traversable): + """ + Path tied to a resource reader child. + Can be read but doesn't expose any meaningful children. + """ + + def __init__(self, reader, name): + self._reader = reader + self._name = name + + def iterdir(self): + return iter(()) + + def is_file(self): + return self._reader.is_resource(self.name) + + def is_dir(self): + return not self.is_file() + + def joinpath(self, other): + return CompatibilityFiles.OrphanPath(self.name, other) + + @property + def name(self): + return self._name + + def open(self, mode='r', *args, **kwargs): + return _io_wrapper( + self._reader.open_resource(self.name), mode, *args, **kwargs + ) + + class OrphanPath(abc.Traversable): + """ + Orphan path, not tied to a module spec or resource reader. + Can't be read and doesn't expose any meaningful children. + """ + + def __init__(self, *path_parts): + if len(path_parts) < 1: + raise ValueError('Need at least one path part to construct a path') + self._path = path_parts + + def iterdir(self): + return iter(()) + + def is_file(self): + return False + + is_dir = is_file + + def joinpath(self, other): + return CompatibilityFiles.OrphanPath(*self._path, other) + + @property + def name(self): + return self._path[-1] + + def open(self, mode='r', *args, **kwargs): + raise FileNotFoundError("Can't open orphan path") + + def __init__(self, spec): + self.spec = spec + + @property + def _reader(self): + with suppress(AttributeError): + return self.spec.loader.get_resource_reader(self.spec.name) + + def _native(self): + """ + Return the native reader if it supports files(). + """ + reader = self._reader + return reader if hasattr(reader, 'files') else self + + def __getattr__(self, attr): + return getattr(self._reader, attr) + + def files(self): + return CompatibilityFiles.SpecPath(self.spec, self._reader) + + +def wrap_spec(package): + """ + Construct a package spec with traversable compatibility + on the spec/loader/reader. + """ + return SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/_common.py b/.venv/lib/python3.12/site-packages/importlib_resources/_common.py new file mode 100644 index 00000000..5f41c265 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/_common.py @@ -0,0 +1,211 @@ +import contextlib +import functools +import importlib +import inspect +import itertools +import os +import pathlib +import tempfile +import types +import warnings +from typing import Optional, Union, cast + +from .abc import ResourceReader, Traversable + +Package = Union[types.ModuleType, str] +Anchor = Package + + +def package_to_anchor(func): + """ + Replace 'package' parameter as 'anchor' and warn about the change. + + Other errors should fall through. + + >>> files('a', 'b') + Traceback (most recent call last): + TypeError: files() takes from 0 to 1 positional arguments but 2 were given + + Remove this compatibility in Python 3.14. + """ + undefined = object() + + @functools.wraps(func) + def wrapper(anchor=undefined, package=undefined): + if package is not undefined: + if anchor is not undefined: + return func(anchor, package) + warnings.warn( + "First parameter to files is renamed to 'anchor'", + DeprecationWarning, + stacklevel=2, + ) + return func(package) + elif anchor is undefined: + return func() + return func(anchor) + + return wrapper + + +@package_to_anchor +def files(anchor: Optional[Anchor] = None) -> Traversable: + """ + Get a Traversable resource for an anchor. + """ + return from_package(resolve(anchor)) + + +def get_resource_reader(package: types.ModuleType) -> Optional[ResourceReader]: + """ + Return the package's loader if it's a ResourceReader. + """ + # We can't use + # a issubclass() check here because apparently abc.'s __subclasscheck__() + # hook wants to create a weak reference to the object, but + # zipimport.zipimporter does not support weak references, resulting in a + # TypeError. That seems terrible. + spec = package.__spec__ + reader = getattr(spec.loader, 'get_resource_reader', None) # type: ignore[union-attr] + if reader is None: + return None + return reader(spec.name) # type: ignore[union-attr] + + +@functools.singledispatch +def resolve(cand: Optional[Anchor]) -> types.ModuleType: + return cast(types.ModuleType, cand) + + +@resolve.register +def _(cand: str) -> types.ModuleType: + return importlib.import_module(cand) + + +@resolve.register +def _(cand: None) -> types.ModuleType: + return resolve(_infer_caller().f_globals['__name__']) + + +def _infer_caller(): + """ + Walk the stack and find the frame of the first caller not in this module. + """ + + def is_this_file(frame_info): + return frame_info.filename == stack[0].filename + + def is_wrapper(frame_info): + return frame_info.function == 'wrapper' + + stack = inspect.stack() + not_this_file = itertools.filterfalse(is_this_file, stack) + # also exclude 'wrapper' due to singledispatch in the call stack + callers = itertools.filterfalse(is_wrapper, not_this_file) + return next(callers).frame + + +def from_package(package: types.ModuleType): + """ + Return a Traversable object for the given package. + + """ + # deferred for performance (python/cpython#109829) + from .future.adapters import wrap_spec + + spec = wrap_spec(package) + reader = spec.loader.get_resource_reader(spec.name) + return reader.files() + + +@contextlib.contextmanager +def _tempfile( + reader, + suffix='', + # gh-93353: Keep a reference to call os.remove() in late Python + # finalization. + *, + _os_remove=os.remove, +): + # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try' + # blocks due to the need to close the temporary file to work on Windows + # properly. + fd, raw_path = tempfile.mkstemp(suffix=suffix) + try: + try: + os.write(fd, reader()) + finally: + os.close(fd) + del reader + yield pathlib.Path(raw_path) + finally: + try: + _os_remove(raw_path) + except FileNotFoundError: + pass + + +def _temp_file(path): + return _tempfile(path.read_bytes, suffix=path.name) + + +def _is_present_dir(path: Traversable) -> bool: + """ + Some Traversables implement ``is_dir()`` to raise an + exception (i.e. ``FileNotFoundError``) when the + directory doesn't exist. This function wraps that call + to always return a boolean and only return True + if there's a dir and it exists. + """ + with contextlib.suppress(FileNotFoundError): + return path.is_dir() + return False + + +@functools.singledispatch +def as_file(path): + """ + Given a Traversable object, return that object as a + path on the local file system in a context manager. + """ + return _temp_dir(path) if _is_present_dir(path) else _temp_file(path) + + +@as_file.register(pathlib.Path) +@contextlib.contextmanager +def _(path): + """ + Degenerate behavior for pathlib.Path objects. + """ + yield path + + +@contextlib.contextmanager +def _temp_path(dir: tempfile.TemporaryDirectory): + """ + Wrap tempfile.TemporaryDirectory to return a pathlib object. + """ + with dir as result: + yield pathlib.Path(result) + + +@contextlib.contextmanager +def _temp_dir(path): + """ + Given a traversable dir, recursively replicate the whole tree + to the file system in a context manager. + """ + assert path.is_dir() + with _temp_path(tempfile.TemporaryDirectory()) as temp_dir: + yield _write_contents(temp_dir, path) + + +def _write_contents(target, source): + child = target.joinpath(source.name) + if source.is_dir(): + child.mkdir() + for item in source.iterdir(): + _write_contents(child, item) + else: + child.write_bytes(source.read_bytes()) + return child diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/_functional.py b/.venv/lib/python3.12/site-packages/importlib_resources/_functional.py new file mode 100644 index 00000000..b08a5c6e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/_functional.py @@ -0,0 +1,84 @@ +"""Simplified function-based API for importlib.resources""" + +import warnings + +from ._common import as_file, files +from .abc import TraversalError + +_MISSING = object() + + +def open_binary(anchor, *path_names): + """Open for binary reading the *resource* within *package*.""" + return _get_resource(anchor, path_names).open('rb') + + +def open_text(anchor, *path_names, encoding=_MISSING, errors='strict'): + """Open for text reading the *resource* within *package*.""" + encoding = _get_encoding_arg(path_names, encoding) + resource = _get_resource(anchor, path_names) + return resource.open('r', encoding=encoding, errors=errors) + + +def read_binary(anchor, *path_names): + """Read and return contents of *resource* within *package* as bytes.""" + return _get_resource(anchor, path_names).read_bytes() + + +def read_text(anchor, *path_names, encoding=_MISSING, errors='strict'): + """Read and return contents of *resource* within *package* as str.""" + encoding = _get_encoding_arg(path_names, encoding) + resource = _get_resource(anchor, path_names) + return resource.read_text(encoding=encoding, errors=errors) + + +def path(anchor, *path_names): + """Return the path to the *resource* as an actual file system path.""" + return as_file(_get_resource(anchor, path_names)) + + +def is_resource(anchor, *path_names): + """Return ``True`` if there is a resource named *name* in the package, + + Otherwise returns ``False``. + """ + try: + return _get_resource(anchor, path_names).is_file() + except TraversalError: + return False + + +def contents(anchor, *path_names): + """Return an iterable over the named resources within the package. + + The iterable returns :class:`str` resources (e.g. files). + The iterable does not recurse into subdirectories. + """ + warnings.warn( + "importlib.resources.contents is deprecated. " + "Use files(anchor).iterdir() instead.", + DeprecationWarning, + stacklevel=1, + ) + return (resource.name for resource in _get_resource(anchor, path_names).iterdir()) + + +def _get_encoding_arg(path_names, encoding): + # For compatibility with versions where *encoding* was a positional + # argument, it needs to be given explicitly when there are multiple + # *path_names*. + # This limitation can be removed in Python 3.15. + if encoding is _MISSING: + if len(path_names) > 1: + raise TypeError( + "'encoding' argument required with multiple path names", + ) + else: + return 'utf-8' + return encoding + + +def _get_resource(anchor, path_names): + if anchor is None: + raise TypeError("anchor must be module or string, got None") + return files(anchor).joinpath(*path_names) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/_itertools.py b/.venv/lib/python3.12/site-packages/importlib_resources/_itertools.py new file mode 100644 index 00000000..7b775ef5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/_itertools.py @@ -0,0 +1,38 @@ +# from more_itertools 9.0 +def only(iterable, default=None, too_long=None): + """If *iterable* has only one item, return it. + If it has zero items, return *default*. + If it has more than one item, raise the exception given by *too_long*, + which is ``ValueError`` by default. + >>> only([], default='missing') + 'missing' + >>> only([1]) + 1 + >>> only([1, 2]) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + ValueError: Expected exactly one item in iterable, but got 1, 2, + and perhaps more.' + >>> only([1, 2], too_long=TypeError) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + TypeError + Note that :func:`only` attempts to advance *iterable* twice to ensure there + is only one item. See :func:`spy` or :func:`peekable` to check + iterable contents less destructively. + """ + it = iter(iterable) + first_value = next(it, default) + + try: + second_value = next(it) + except StopIteration: + pass + else: + msg = ( + 'Expected exactly one item in iterable, but got {!r}, {!r}, ' + 'and perhaps more.'.format(first_value, second_value) + ) + raise too_long or ValueError(msg) + + return first_value diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/abc.py b/.venv/lib/python3.12/site-packages/importlib_resources/abc.py new file mode 100644 index 00000000..883d3328 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/abc.py @@ -0,0 +1,193 @@ +import abc +import itertools +import os +import pathlib +from typing import ( + Any, + BinaryIO, + Iterable, + Iterator, + NoReturn, + Literal, + Optional, + Protocol, + Text, + TextIO, + Union, + overload, + runtime_checkable, +) + +StrPath = Union[str, os.PathLike[str]] + +__all__ = ["ResourceReader", "Traversable", "TraversableResources"] + + +class ResourceReader(metaclass=abc.ABCMeta): + """Abstract base class for loaders to provide resource reading support.""" + + @abc.abstractmethod + def open_resource(self, resource: Text) -> BinaryIO: + """Return an opened, file-like object for binary reading. + + The 'resource' argument is expected to represent only a file name. + If the resource cannot be found, FileNotFoundError is raised. + """ + # This deliberately raises FileNotFoundError instead of + # NotImplementedError so that if this method is accidentally called, + # it'll still do the right thing. + raise FileNotFoundError + + @abc.abstractmethod + def resource_path(self, resource: Text) -> Text: + """Return the file system path to the specified resource. + + The 'resource' argument is expected to represent only a file name. + If the resource does not exist on the file system, raise + FileNotFoundError. + """ + # This deliberately raises FileNotFoundError instead of + # NotImplementedError so that if this method is accidentally called, + # it'll still do the right thing. + raise FileNotFoundError + + @abc.abstractmethod + def is_resource(self, path: Text) -> bool: + """Return True if the named 'path' is a resource. + + Files are resources, directories are not. + """ + raise FileNotFoundError + + @abc.abstractmethod + def contents(self) -> Iterable[str]: + """Return an iterable of entries in `package`.""" + raise FileNotFoundError + + +class TraversalError(Exception): + pass + + +@runtime_checkable +class Traversable(Protocol): + """ + An object with a subset of pathlib.Path methods suitable for + traversing directories and opening files. + + Any exceptions that occur when accessing the backing resource + may propagate unaltered. + """ + + @abc.abstractmethod + def iterdir(self) -> Iterator["Traversable"]: + """ + Yield Traversable objects in self + """ + + def read_bytes(self) -> bytes: + """ + Read contents of self as bytes + """ + with self.open('rb') as strm: + return strm.read() + + def read_text( + self, encoding: Optional[str] = None, errors: Optional[str] = None + ) -> str: + """ + Read contents of self as text + """ + with self.open(encoding=encoding, errors=errors) as strm: + return strm.read() + + @abc.abstractmethod + def is_dir(self) -> bool: + """ + Return True if self is a directory + """ + + @abc.abstractmethod + def is_file(self) -> bool: + """ + Return True if self is a file + """ + + def joinpath(self, *descendants: StrPath) -> "Traversable": + """ + Return Traversable resolved with any descendants applied. + + Each descendant should be a path segment relative to self + and each may contain multiple levels separated by + ``posixpath.sep`` (``/``). + """ + if not descendants: + return self + names = itertools.chain.from_iterable( + path.parts for path in map(pathlib.PurePosixPath, descendants) + ) + target = next(names) + matches = ( + traversable for traversable in self.iterdir() if traversable.name == target + ) + try: + match = next(matches) + except StopIteration: + raise TraversalError( + "Target not found during traversal.", target, list(names) + ) + return match.joinpath(*names) + + def __truediv__(self, child: StrPath) -> "Traversable": + """ + Return Traversable child in self + """ + return self.joinpath(child) + + @overload + def open(self, mode: Literal['r'] = 'r', *args: Any, **kwargs: Any) -> TextIO: ... + + @overload + def open(self, mode: Literal['rb'], *args: Any, **kwargs: Any) -> BinaryIO: ... + + @abc.abstractmethod + def open( + self, mode: str = 'r', *args: Any, **kwargs: Any + ) -> Union[TextIO, BinaryIO]: + """ + mode may be 'r' or 'rb' to open as text or binary. Return a handle + suitable for reading (same as pathlib.Path.open). + + When opening as text, accepts encoding parameters such as those + accepted by io.TextIOWrapper. + """ + + @property + @abc.abstractmethod + def name(self) -> str: + """ + The base name of this object without any parent references. + """ + + +class TraversableResources(ResourceReader): + """ + The required interface for providing traversable + resources. + """ + + @abc.abstractmethod + def files(self) -> "Traversable": + """Return a Traversable object for the loaded package.""" + + def open_resource(self, resource: StrPath) -> BinaryIO: + return self.files().joinpath(resource).open('rb') + + def resource_path(self, resource: Any) -> NoReturn: + raise FileNotFoundError(resource) + + def is_resource(self, path: StrPath) -> bool: + return self.files().joinpath(path).is_file() + + def contents(self) -> Iterator[str]: + return (item.name for item in self.files().iterdir()) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/compat/__init__.py b/.venv/lib/python3.12/site-packages/importlib_resources/compat/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/compat/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/compat/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..814fc1db Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/compat/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/compat/__pycache__/py39.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/compat/__pycache__/py39.cpython-312.pyc new file mode 100644 index 00000000..08488f5a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/compat/__pycache__/py39.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/compat/py39.py b/.venv/lib/python3.12/site-packages/importlib_resources/compat/py39.py new file mode 100644 index 00000000..684d3c63 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/compat/py39.py @@ -0,0 +1,9 @@ +import sys + +__all__ = ['ZipPath'] + + +if sys.version_info >= (3, 10): + from zipfile import Path as ZipPath +else: + from zipp import Path as ZipPath diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/future/__init__.py b/.venv/lib/python3.12/site-packages/importlib_resources/future/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/future/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/future/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..8a49faf3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/future/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/future/__pycache__/adapters.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/future/__pycache__/adapters.cpython-312.pyc new file mode 100644 index 00000000..ec6f5f1c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/future/__pycache__/adapters.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/future/adapters.py b/.venv/lib/python3.12/site-packages/importlib_resources/future/adapters.py new file mode 100644 index 00000000..239e52b7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/future/adapters.py @@ -0,0 +1,102 @@ +import functools +import pathlib +from contextlib import suppress +from types import SimpleNamespace + +from .. import _adapters, readers + + +def _block_standard(reader_getter): + """ + Wrap _adapters.TraversableResourcesLoader.get_resource_reader + and intercept any standard library readers. + """ + + @functools.wraps(reader_getter) + def wrapper(*args, **kwargs): + """ + If the reader is from the standard library, return None to allow + allow likely newer implementations in this library to take precedence. + """ + try: + reader = reader_getter(*args, **kwargs) + except NotADirectoryError: + # MultiplexedPath may fail on zip subdirectory + return + except ValueError as exc: + # NamespaceReader in stdlib may fail for editable installs + # (python/importlib_resources#311, python/importlib_resources#318) + # Remove after bugfix applied to Python 3.13. + if "not enough values to unpack" not in str(exc): + raise + return + # Python 3.10+ + mod_name = reader.__class__.__module__ + if mod_name.startswith('importlib.') and mod_name.endswith('readers'): + return + # Python 3.8, 3.9 + if isinstance(reader, _adapters.CompatibilityFiles) and ( + reader.spec.loader.__class__.__module__.startswith('zipimport') + or reader.spec.loader.__class__.__module__.startswith( + '_frozen_importlib_external' + ) + ): + return + return reader + + return wrapper + + +def _skip_degenerate(reader): + """ + Mask any degenerate reader. Ref #298. + """ + is_degenerate = ( + isinstance(reader, _adapters.CompatibilityFiles) and not reader._reader + ) + return reader if not is_degenerate else None + + +class TraversableResourcesLoader(_adapters.TraversableResourcesLoader): + """ + Adapt loaders to provide TraversableResources and other + compatibility. + + Ensures the readers from importlib_resources are preferred + over stdlib readers. + """ + + def get_resource_reader(self, name): + return ( + _skip_degenerate(_block_standard(super().get_resource_reader)(name)) + or self._standard_reader() + or super().get_resource_reader(name) + ) + + def _standard_reader(self): + return self._zip_reader() or self._namespace_reader() or self._file_reader() + + def _zip_reader(self): + with suppress(AttributeError): + return readers.ZipReader(self.spec.loader, self.spec.name) + + def _namespace_reader(self): + with suppress(AttributeError, ValueError): + return readers.NamespaceReader(self.spec.submodule_search_locations) + + def _file_reader(self): + try: + path = pathlib.Path(self.spec.origin) + except TypeError: + return None + if path.exists(): + return readers.FileReader(SimpleNamespace(path=path)) + + +def wrap_spec(package): + """ + Override _adapters.wrap_spec to use TraversableResourcesLoader + from above. Ensures that future behavior is always available on older + Pythons. + """ + return _adapters.SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/py.typed b/.venv/lib/python3.12/site-packages/importlib_resources/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/readers.py b/.venv/lib/python3.12/site-packages/importlib_resources/readers.py new file mode 100644 index 00000000..99884b6a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/readers.py @@ -0,0 +1,202 @@ +from __future__ import annotations + +import collections +import contextlib +import itertools +import operator +import pathlib +import re +import warnings +from collections.abc import Iterator + +from . import abc +from ._itertools import only +from .compat.py39 import ZipPath + + +def remove_duplicates(items): + return iter(collections.OrderedDict.fromkeys(items)) + + +class FileReader(abc.TraversableResources): + def __init__(self, loader): + self.path = pathlib.Path(loader.path).parent + + def resource_path(self, resource): + """ + Return the file system path to prevent + `resources.path()` from creating a temporary + copy. + """ + return str(self.path.joinpath(resource)) + + def files(self): + return self.path + + +class ZipReader(abc.TraversableResources): + def __init__(self, loader, module): + self.prefix = loader.prefix.replace('\\', '/') + if loader.is_package(module): + _, _, name = module.rpartition('.') + self.prefix += name + '/' + self.archive = loader.archive + + def open_resource(self, resource): + try: + return super().open_resource(resource) + except KeyError as exc: + raise FileNotFoundError(exc.args[0]) + + def is_resource(self, path): + """ + Workaround for `zipfile.Path.is_file` returning true + for non-existent paths. + """ + target = self.files().joinpath(path) + return target.is_file() and target.exists() + + def files(self): + return ZipPath(self.archive, self.prefix) + + +class MultiplexedPath(abc.Traversable): + """ + Given a series of Traversable objects, implement a merged + version of the interface across all objects. Useful for + namespace packages which may be multihomed at a single + name. + """ + + def __init__(self, *paths): + self._paths = list(map(_ensure_traversable, remove_duplicates(paths))) + if not self._paths: + message = 'MultiplexedPath must contain at least one path' + raise FileNotFoundError(message) + if not all(path.is_dir() for path in self._paths): + raise NotADirectoryError('MultiplexedPath only supports directories') + + def iterdir(self): + children = (child for path in self._paths for child in path.iterdir()) + by_name = operator.attrgetter('name') + groups = itertools.groupby(sorted(children, key=by_name), key=by_name) + return map(self._follow, (locs for name, locs in groups)) + + def read_bytes(self): + raise FileNotFoundError(f'{self} is not a file') + + def read_text(self, *args, **kwargs): + raise FileNotFoundError(f'{self} is not a file') + + def is_dir(self): + return True + + def is_file(self): + return False + + def joinpath(self, *descendants): + try: + return super().joinpath(*descendants) + except abc.TraversalError: + # One of the paths did not resolve (a directory does not exist). + # Just return something that will not exist. + return self._paths[0].joinpath(*descendants) + + @classmethod + def _follow(cls, children): + """ + Construct a MultiplexedPath if needed. + + If children contains a sole element, return it. + Otherwise, return a MultiplexedPath of the items. + Unless one of the items is not a Directory, then return the first. + """ + subdirs, one_dir, one_file = itertools.tee(children, 3) + + try: + return only(one_dir) + except ValueError: + try: + return cls(*subdirs) + except NotADirectoryError: + return next(one_file) + + def open(self, *args, **kwargs): + raise FileNotFoundError(f'{self} is not a file') + + @property + def name(self): + return self._paths[0].name + + def __repr__(self): + paths = ', '.join(f"'{path}'" for path in self._paths) + return f'MultiplexedPath({paths})' + + +class NamespaceReader(abc.TraversableResources): + def __init__(self, namespace_path): + if 'NamespacePath' not in str(namespace_path): + raise ValueError('Invalid path') + self.path = MultiplexedPath(*filter(bool, map(self._resolve, namespace_path))) + + @classmethod + def _resolve(cls, path_str) -> abc.Traversable | None: + r""" + Given an item from a namespace path, resolve it to a Traversable. + + path_str might be a directory on the filesystem or a path to a + zipfile plus the path within the zipfile, e.g. ``/foo/bar`` or + ``/foo/baz.zip/inner_dir`` or ``foo\baz.zip\inner_dir\sub``. + + path_str might also be a sentinel used by editable packages to + trigger other behaviors (see python/importlib_resources#311). + In that case, return None. + """ + dirs = (cand for cand in cls._candidate_paths(path_str) if cand.is_dir()) + return next(dirs, None) + + @classmethod + def _candidate_paths(cls, path_str: str) -> Iterator[abc.Traversable]: + yield pathlib.Path(path_str) + yield from cls._resolve_zip_path(path_str) + + @staticmethod + def _resolve_zip_path(path_str: str): + for match in reversed(list(re.finditer(r'[\\/]', path_str))): + with contextlib.suppress( + FileNotFoundError, + IsADirectoryError, + NotADirectoryError, + PermissionError, + ): + inner = path_str[match.end() :].replace('\\', '/') + '/' + yield ZipPath(path_str[: match.start()], inner.lstrip('/')) + + def resource_path(self, resource): + """ + Return the file system path to prevent + `resources.path()` from creating a temporary + copy. + """ + return str(self.path.joinpath(resource)) + + def files(self): + return self.path + + +def _ensure_traversable(path): + """ + Convert deprecated string arguments to traversables (pathlib.Path). + + Remove with Python 3.15. + """ + if not isinstance(path, str): + return path + + warnings.warn( + "String arguments are deprecated. Pass a Traversable instead.", + DeprecationWarning, + stacklevel=3, + ) + + return pathlib.Path(path) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/simple.py b/.venv/lib/python3.12/site-packages/importlib_resources/simple.py new file mode 100644 index 00000000..2e75299b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/simple.py @@ -0,0 +1,106 @@ +""" +Interface adapters for low-level readers. +""" + +import abc +import io +import itertools +from typing import BinaryIO, List + +from .abc import Traversable, TraversableResources + + +class SimpleReader(abc.ABC): + """ + The minimum, low-level interface required from a resource + provider. + """ + + @property + @abc.abstractmethod + def package(self) -> str: + """ + The name of the package for which this reader loads resources. + """ + + @abc.abstractmethod + def children(self) -> List['SimpleReader']: + """ + Obtain an iterable of SimpleReader for available + child containers (e.g. directories). + """ + + @abc.abstractmethod + def resources(self) -> List[str]: + """ + Obtain available named resources for this virtual package. + """ + + @abc.abstractmethod + def open_binary(self, resource: str) -> BinaryIO: + """ + Obtain a File-like for a named resource. + """ + + @property + def name(self): + return self.package.split('.')[-1] + + +class ResourceContainer(Traversable): + """ + Traversable container for a package's resources via its reader. + """ + + def __init__(self, reader: SimpleReader): + self.reader = reader + + def is_dir(self): + return True + + def is_file(self): + return False + + def iterdir(self): + files = (ResourceHandle(self, name) for name in self.reader.resources) + dirs = map(ResourceContainer, self.reader.children()) + return itertools.chain(files, dirs) + + def open(self, *args, **kwargs): + raise IsADirectoryError() + + +class ResourceHandle(Traversable): + """ + Handle to a named resource in a ResourceReader. + """ + + def __init__(self, parent: ResourceContainer, name: str): + self.parent = parent + self.name = name # type: ignore[misc] + + def is_file(self): + return True + + def is_dir(self): + return False + + def open(self, mode='r', *args, **kwargs): + stream = self.parent.reader.open_binary(self.name) + if 'b' not in mode: + stream = io.TextIOWrapper(stream, *args, **kwargs) + return stream + + def joinpath(self, name): + raise RuntimeError("Cannot traverse into a resource") + + +class TraversableReader(TraversableResources, SimpleReader): + """ + A TraversableResources based on SimpleReader. Resource providers + may derive from this class to provide the TraversableResources + interface by supplying the SimpleReader interface. + """ + + def files(self): + return ResourceContainer(self) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__init__.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..a19a08d8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/_path.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/_path.cpython-312.pyc new file mode 100644 index 00000000..0c0a7486 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/_path.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-312.pyc new file mode 100644 index 00000000..ed194a95 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_compatibilty_files.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_contents.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_contents.cpython-312.pyc new file mode 100644 index 00000000..3a018018 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_contents.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_custom.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_custom.cpython-312.pyc new file mode 100644 index 00000000..c3f2aa82 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_custom.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_files.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_files.cpython-312.pyc new file mode 100644 index 00000000..c549a5d2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_files.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_functional.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_functional.cpython-312.pyc new file mode 100644 index 00000000..fad3fcfe Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_functional.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_open.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_open.cpython-312.pyc new file mode 100644 index 00000000..8d9083e5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_open.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_path.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_path.cpython-312.pyc new file mode 100644 index 00000000..ec3af8fb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_path.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_read.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_read.cpython-312.pyc new file mode 100644 index 00000000..d3d97585 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_read.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_reader.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_reader.cpython-312.pyc new file mode 100644 index 00000000..14879a73 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_reader.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_resource.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_resource.cpython-312.pyc new file mode 100644 index 00000000..500948a3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_resource.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_util.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_util.cpython-312.pyc new file mode 100644 index 00000000..abea4fd5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/test_util.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/util.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/util.cpython-312.pyc new file mode 100644 index 00000000..c7fe8089 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/util.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/zip.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/zip.cpython-312.pyc new file mode 100644 index 00000000..c87d57d3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/__pycache__/zip.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/_path.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/_path.py new file mode 100644 index 00000000..0033983d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/_path.py @@ -0,0 +1,90 @@ +import functools +import pathlib +from typing import Dict, Protocol, Union, runtime_checkable + +#### +# from jaraco.path 3.7.1 + + +class Symlink(str): + """ + A string indicating the target of a symlink. + """ + + +FilesSpec = Dict[str, Union[str, bytes, Symlink, 'FilesSpec']] + + +@runtime_checkable +class TreeMaker(Protocol): + def __truediv__(self, *args, **kwargs): ... # pragma: no cover + + def mkdir(self, **kwargs): ... # pragma: no cover + + def write_text(self, content, **kwargs): ... # pragma: no cover + + def write_bytes(self, content): ... # pragma: no cover + + def symlink_to(self, target): ... # pragma: no cover + + +def _ensure_tree_maker(obj: Union[str, TreeMaker]) -> TreeMaker: + return obj if isinstance(obj, TreeMaker) else pathlib.Path(obj) # type: ignore[return-value] + + +def build( + spec: FilesSpec, + prefix: Union[str, TreeMaker] = pathlib.Path(), # type: ignore[assignment] +): + """ + Build a set of files/directories, as described by the spec. + + Each key represents a pathname, and the value represents + the content. Content may be a nested directory. + + >>> spec = { + ... 'README.txt': "A README file", + ... "foo": { + ... "__init__.py": "", + ... "bar": { + ... "__init__.py": "", + ... }, + ... "baz.py": "# Some code", + ... "bar.py": Symlink("baz.py"), + ... }, + ... "bing": Symlink("foo"), + ... } + >>> target = getfixture('tmp_path') + >>> build(spec, target) + >>> target.joinpath('foo/baz.py').read_text(encoding='utf-8') + '# Some code' + >>> target.joinpath('bing/bar.py').read_text(encoding='utf-8') + '# Some code' + """ + for name, contents in spec.items(): + create(contents, _ensure_tree_maker(prefix) / name) + + +@functools.singledispatch +def create(content: Union[str, bytes, FilesSpec], path): + path.mkdir(exist_ok=True) + build(content, prefix=path) # type: ignore[arg-type] + + +@create.register +def _(content: bytes, path): + path.write_bytes(content) + + +@create.register +def _(content: str, path): + path.write_text(content, encoding='utf-8') + + +@create.register +def _(content: Symlink, path): + path.symlink_to(content) + + +# end from jaraco.path +#### diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__init__.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..f0aae0ce Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/py312.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/py312.cpython-312.pyc new file mode 100644 index 00000000..f97da029 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/py312.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/py39.cpython-312.pyc b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/py39.cpython-312.pyc new file mode 100644 index 00000000..08d8b762 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/__pycache__/py39.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/py312.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/py312.py new file mode 100644 index 00000000..ea9a58ba --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/py312.py @@ -0,0 +1,18 @@ +import contextlib + +from .py39 import import_helper + + +@contextlib.contextmanager +def isolated_modules(): + """ + Save modules on entry and cleanup on exit. + """ + (saved,) = import_helper.modules_setup() + try: + yield + finally: + import_helper.modules_cleanup(saved) + + +vars(import_helper).setdefault('isolated_modules', isolated_modules) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/py39.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/py39.py new file mode 100644 index 00000000..e01d276b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/compat/py39.py @@ -0,0 +1,13 @@ +""" +Backward-compatability shims to support Python 3.9 and earlier. +""" + +from jaraco.test.cpython import from_test_support, try_import + +import_helper = try_import('import_helper') or from_test_support( + 'modules_setup', 'modules_cleanup', 'DirsOnSysPath' +) +os_helper = try_import('os_helper') or from_test_support('temp_dir') +warnings_helper = try_import('warnings_helper') or from_test_support( + 'ignore_warnings', 'check_warnings' +) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_compatibilty_files.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_compatibilty_files.py new file mode 100644 index 00000000..e8aac284 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_compatibilty_files.py @@ -0,0 +1,103 @@ +import io +import unittest + +import importlib_resources as resources +from importlib_resources._adapters import ( + CompatibilityFiles, + wrap_spec, +) + +from . import util + + +class CompatibilityFilesTests(unittest.TestCase): + @property + def package(self): + bytes_data = io.BytesIO(b'Hello, world!') + return util.create_package( + file=bytes_data, + path='some_path', + contents=('a', 'b', 'c'), + ) + + @property + def files(self): + return resources.files(self.package) + + def test_spec_path_iter(self): + self.assertEqual( + sorted(path.name for path in self.files.iterdir()), + ['a', 'b', 'c'], + ) + + def test_child_path_iter(self): + self.assertEqual(list((self.files / 'a').iterdir()), []) + + def test_orphan_path_iter(self): + self.assertEqual(list((self.files / 'a' / 'a').iterdir()), []) + self.assertEqual(list((self.files / 'a' / 'a' / 'a').iterdir()), []) + + def test_spec_path_is(self): + self.assertFalse(self.files.is_file()) + self.assertFalse(self.files.is_dir()) + + def test_child_path_is(self): + self.assertTrue((self.files / 'a').is_file()) + self.assertFalse((self.files / 'a').is_dir()) + + def test_orphan_path_is(self): + self.assertFalse((self.files / 'a' / 'a').is_file()) + self.assertFalse((self.files / 'a' / 'a').is_dir()) + self.assertFalse((self.files / 'a' / 'a' / 'a').is_file()) + self.assertFalse((self.files / 'a' / 'a' / 'a').is_dir()) + + def test_spec_path_name(self): + self.assertEqual(self.files.name, 'testingpackage') + + def test_child_path_name(self): + self.assertEqual((self.files / 'a').name, 'a') + + def test_orphan_path_name(self): + self.assertEqual((self.files / 'a' / 'b').name, 'b') + self.assertEqual((self.files / 'a' / 'b' / 'c').name, 'c') + + def test_spec_path_open(self): + self.assertEqual(self.files.read_bytes(), b'Hello, world!') + self.assertEqual(self.files.read_text(encoding='utf-8'), 'Hello, world!') + + def test_child_path_open(self): + self.assertEqual((self.files / 'a').read_bytes(), b'Hello, world!') + self.assertEqual( + (self.files / 'a').read_text(encoding='utf-8'), 'Hello, world!' + ) + + def test_orphan_path_open(self): + with self.assertRaises(FileNotFoundError): + (self.files / 'a' / 'b').read_bytes() + with self.assertRaises(FileNotFoundError): + (self.files / 'a' / 'b' / 'c').read_bytes() + + def test_open_invalid_mode(self): + with self.assertRaises(ValueError): + self.files.open('0') + + def test_orphan_path_invalid(self): + with self.assertRaises(ValueError): + CompatibilityFiles.OrphanPath() + + def test_wrap_spec(self): + spec = wrap_spec(self.package) + self.assertIsInstance(spec.loader.get_resource_reader(None), CompatibilityFiles) + + +class CompatibilityFilesNoReaderTests(unittest.TestCase): + @property + def package(self): + return util.create_package_from_loader(None) + + @property + def files(self): + return resources.files(self.package) + + def test_spec_path_joinpath(self): + self.assertIsInstance(self.files / 'a', CompatibilityFiles.OrphanPath) diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_contents.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_contents.py new file mode 100644 index 00000000..dcb872ec --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_contents.py @@ -0,0 +1,39 @@ +import unittest + +import importlib_resources as resources + +from . import util + + +class ContentsTests: + expected = { + '__init__.py', + 'binary.file', + 'subdirectory', + 'utf-16.file', + 'utf-8.file', + } + + def test_contents(self): + contents = {path.name for path in resources.files(self.data).iterdir()} + assert self.expected <= contents + + +class ContentsDiskTests(ContentsTests, util.DiskSetup, unittest.TestCase): + pass + + +class ContentsZipTests(ContentsTests, util.ZipSetup, unittest.TestCase): + pass + + +class ContentsNamespaceTests(ContentsTests, util.DiskSetup, unittest.TestCase): + MODULE = 'namespacedata01' + + expected = { + # no __init__ because of namespace design + 'binary.file', + 'subdirectory', + 'utf-16.file', + 'utf-8.file', + } diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_custom.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_custom.py new file mode 100644 index 00000000..25ae0e75 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_custom.py @@ -0,0 +1,48 @@ +import contextlib +import pathlib +import unittest + +import importlib_resources as resources + +from .. import abc +from ..abc import ResourceReader, TraversableResources +from . import util +from .compat.py39 import os_helper + + +class SimpleLoader: + """ + A simple loader that only implements a resource reader. + """ + + def __init__(self, reader: ResourceReader): + self.reader = reader + + def get_resource_reader(self, package): + return self.reader + + +class MagicResources(TraversableResources): + """ + Magically returns the resources at path. + """ + + def __init__(self, path: pathlib.Path): + self.path = path + + def files(self): + return self.path + + +class CustomTraversableResourcesTests(unittest.TestCase): + def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + + def test_custom_loader(self): + temp_dir = pathlib.Path(self.fixtures.enter_context(os_helper.temp_dir())) + loader = SimpleLoader(MagicResources(temp_dir)) + pkg = util.create_package_from_loader(loader) + files = resources.files(pkg) + assert isinstance(files, abc.Traversable) + assert list(files.iterdir()) == [] diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_files.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_files.py new file mode 100644 index 00000000..be206603 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_files.py @@ -0,0 +1,194 @@ +import contextlib +import importlib +import pathlib +import py_compile +import textwrap +import unittest +import warnings + +import importlib_resources as resources + +from ..abc import Traversable +from . import util +from .compat.py39 import import_helper, os_helper + + +@contextlib.contextmanager +def suppress_known_deprecation(): + with warnings.catch_warnings(record=True) as ctx: + warnings.simplefilter('default', category=DeprecationWarning) + yield ctx + + +class FilesTests: + def test_read_bytes(self): + files = resources.files(self.data) + actual = files.joinpath('utf-8.file').read_bytes() + assert actual == b'Hello, UTF-8 world!\n' + + def test_read_text(self): + files = resources.files(self.data) + actual = files.joinpath('utf-8.file').read_text(encoding='utf-8') + assert actual == 'Hello, UTF-8 world!\n' + + def test_traversable(self): + assert isinstance(resources.files(self.data), Traversable) + + def test_joinpath_with_multiple_args(self): + files = resources.files(self.data) + binfile = files.joinpath('subdirectory', 'binary.file') + self.assertTrue(binfile.is_file()) + + def test_old_parameter(self): + """ + Files used to take a 'package' parameter. Make sure anyone + passing by name is still supported. + """ + with suppress_known_deprecation(): + resources.files(package=self.data) + + +class OpenDiskTests(FilesTests, util.DiskSetup, unittest.TestCase): + pass + + +class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase): + pass + + +class OpenNamespaceTests(FilesTests, util.DiskSetup, unittest.TestCase): + MODULE = 'namespacedata01' + + def test_non_paths_in_dunder_path(self): + """ + Non-path items in a namespace package's ``__path__`` are ignored. + + As reported in python/importlib_resources#311, some tools + like Setuptools, when creating editable packages, will inject + non-paths into a namespace package's ``__path__``, a + sentinel like + ``__editable__.sample_namespace-1.0.finder.__path_hook__`` + to cause the ``PathEntryFinder`` to be called when searching + for packages. In that case, resources should still be loadable. + """ + import namespacedata01 # type: ignore[import-not-found] + + namespacedata01.__path__.append( + '__editable__.sample_namespace-1.0.finder.__path_hook__' + ) + + resources.files(namespacedata01) + + +class OpenNamespaceZipTests(FilesTests, util.ZipSetup, unittest.TestCase): + ZIP_MODULE = 'namespacedata01' + + +class DirectSpec: + """ + Override behavior of ModuleSetup to write a full spec directly. + """ + + MODULE = 'unused' + + def load_fixture(self, name): + self.tree_on_path(self.spec) + + +class ModulesFiles: + spec = { + 'mod.py': '', + 'res.txt': 'resources are the best', + } + + def test_module_resources(self): + """ + A module can have resources found adjacent to the module. + """ + import mod # type: ignore[import-not-found] + + actual = resources.files(mod).joinpath('res.txt').read_text(encoding='utf-8') + assert actual == self.spec['res.txt'] + + +class ModuleFilesDiskTests(DirectSpec, util.DiskSetup, ModulesFiles, unittest.TestCase): + pass + + +class ModuleFilesZipTests(DirectSpec, util.ZipSetup, ModulesFiles, unittest.TestCase): + pass + + +class ImplicitContextFiles: + set_val = textwrap.dedent( + f""" + import {resources.__name__} as res + val = res.files().joinpath('res.txt').read_text(encoding='utf-8') + """ + ) + spec = { + 'somepkg': { + '__init__.py': set_val, + 'submod.py': set_val, + 'res.txt': 'resources are the best', + }, + 'frozenpkg': { + '__init__.py': set_val.replace(resources.__name__, 'c_resources'), + 'res.txt': 'resources are the best', + }, + } + + def test_implicit_files_package(self): + """ + Without any parameter, files() will infer the location as the caller. + """ + assert importlib.import_module('somepkg').val == 'resources are the best' + + def test_implicit_files_submodule(self): + """ + Without any parameter, files() will infer the location as the caller. + """ + assert importlib.import_module('somepkg.submod').val == 'resources are the best' + + def _compile_importlib(self): + """ + Make a compiled-only copy of the importlib resources package. + + Currently only code is copied, as importlib resources doesn't itself + have any resources. + """ + bin_site = self.fixtures.enter_context(os_helper.temp_dir()) + c_resources = pathlib.Path(bin_site, 'c_resources') + sources = pathlib.Path(resources.__file__).parent + + for source_path in sources.glob('**/*.py'): + c_path = c_resources.joinpath(source_path.relative_to(sources)).with_suffix( + '.pyc' + ) + py_compile.compile(source_path, c_path) + self.fixtures.enter_context(import_helper.DirsOnSysPath(bin_site)) + + def test_implicit_files_with_compiled_importlib(self): + """ + Caller detection works for compiled-only resources module. + + python/cpython#123085 + """ + self._compile_importlib() + assert importlib.import_module('frozenpkg').val == 'resources are the best' + + +class ImplicitContextFilesDiskTests( + DirectSpec, util.DiskSetup, ImplicitContextFiles, unittest.TestCase +): + pass + + +class ImplicitContextFilesZipTests( + DirectSpec, util.ZipSetup, ImplicitContextFiles, unittest.TestCase +): + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_functional.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_functional.py new file mode 100644 index 00000000..9eb2d815 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_functional.py @@ -0,0 +1,267 @@ +import importlib +import os +import unittest + +import importlib_resources as resources + +from . import util +from .compat.py39 import warnings_helper + + +class StringAnchorMixin: + anchor01 = 'data01' + anchor02 = 'data02' + + +class ModuleAnchorMixin: + @property + def anchor01(self): + return importlib.import_module('data01') + + @property + def anchor02(self): + return importlib.import_module('data02') + + +class FunctionalAPIBase: + def setUp(self): + super().setUp() + self.load_fixture('data02') + + def _gen_resourcetxt_path_parts(self): + """Yield various names of a text file in anchor02, each in a subTest""" + for path_parts in ( + ('subdirectory', 'subsubdir', 'resource.txt'), + ('subdirectory/subsubdir/resource.txt',), + ('subdirectory/subsubdir', 'resource.txt'), + ): + with self.subTest(path_parts=path_parts): + yield path_parts + + def assertEndsWith(self, string, suffix): + """Assert that `string` ends with `suffix`. + + Used to ignore an architecture-specific UTF-16 byte-order mark.""" + self.assertEqual(string[-len(suffix) :], suffix) + + def test_read_text(self): + self.assertEqual( + resources.read_text(self.anchor01, 'utf-8.file'), + 'Hello, UTF-8 world!\n', + ) + self.assertEqual( + resources.read_text( + self.anchor02, + 'subdirectory', + 'subsubdir', + 'resource.txt', + encoding='utf-8', + ), + 'a resource', + ) + for path_parts in self._gen_resourcetxt_path_parts(): + self.assertEqual( + resources.read_text( + self.anchor02, + *path_parts, + encoding='utf-8', + ), + 'a resource', + ) + # Use generic OSError, since e.g. attempting to read a directory can + # fail with PermissionError rather than IsADirectoryError + with self.assertRaises(OSError): + resources.read_text(self.anchor01) + with self.assertRaises((OSError, resources.abc.TraversalError)): + resources.read_text(self.anchor01, 'no-such-file') + with self.assertRaises(UnicodeDecodeError): + resources.read_text(self.anchor01, 'utf-16.file') + self.assertEqual( + resources.read_text( + self.anchor01, + 'binary.file', + encoding='latin1', + ), + '\x00\x01\x02\x03', + ) + self.assertEndsWith( # ignore the BOM + resources.read_text( + self.anchor01, + 'utf-16.file', + errors='backslashreplace', + ), + 'Hello, UTF-16 world!\n'.encode('utf-16-le').decode( + errors='backslashreplace', + ), + ) + + def test_read_binary(self): + self.assertEqual( + resources.read_binary(self.anchor01, 'utf-8.file'), + b'Hello, UTF-8 world!\n', + ) + for path_parts in self._gen_resourcetxt_path_parts(): + self.assertEqual( + resources.read_binary(self.anchor02, *path_parts), + b'a resource', + ) + + def test_open_text(self): + with resources.open_text(self.anchor01, 'utf-8.file') as f: + self.assertEqual(f.read(), 'Hello, UTF-8 world!\n') + for path_parts in self._gen_resourcetxt_path_parts(): + with resources.open_text( + self.anchor02, + *path_parts, + encoding='utf-8', + ) as f: + self.assertEqual(f.read(), 'a resource') + # Use generic OSError, since e.g. attempting to read a directory can + # fail with PermissionError rather than IsADirectoryError + with self.assertRaises(OSError): + resources.open_text(self.anchor01) + with self.assertRaises((OSError, resources.abc.TraversalError)): + resources.open_text(self.anchor01, 'no-such-file') + with resources.open_text(self.anchor01, 'utf-16.file') as f: + with self.assertRaises(UnicodeDecodeError): + f.read() + with resources.open_text( + self.anchor01, + 'binary.file', + encoding='latin1', + ) as f: + self.assertEqual(f.read(), '\x00\x01\x02\x03') + with resources.open_text( + self.anchor01, + 'utf-16.file', + errors='backslashreplace', + ) as f: + self.assertEndsWith( # ignore the BOM + f.read(), + 'Hello, UTF-16 world!\n'.encode('utf-16-le').decode( + errors='backslashreplace', + ), + ) + + def test_open_binary(self): + with resources.open_binary(self.anchor01, 'utf-8.file') as f: + self.assertEqual(f.read(), b'Hello, UTF-8 world!\n') + for path_parts in self._gen_resourcetxt_path_parts(): + with resources.open_binary( + self.anchor02, + *path_parts, + ) as f: + self.assertEqual(f.read(), b'a resource') + + def test_path(self): + with resources.path(self.anchor01, 'utf-8.file') as path: + with open(str(path), encoding='utf-8') as f: + self.assertEqual(f.read(), 'Hello, UTF-8 world!\n') + with resources.path(self.anchor01) as path: + with open(os.path.join(path, 'utf-8.file'), encoding='utf-8') as f: + self.assertEqual(f.read(), 'Hello, UTF-8 world!\n') + + def test_is_resource(self): + is_resource = resources.is_resource + self.assertTrue(is_resource(self.anchor01, 'utf-8.file')) + self.assertFalse(is_resource(self.anchor01, 'no_such_file')) + self.assertFalse(is_resource(self.anchor01)) + self.assertFalse(is_resource(self.anchor01, 'subdirectory')) + for path_parts in self._gen_resourcetxt_path_parts(): + self.assertTrue(is_resource(self.anchor02, *path_parts)) + + def test_contents(self): + with warnings_helper.check_warnings((".*contents.*", DeprecationWarning)): + c = resources.contents(self.anchor01) + self.assertGreaterEqual( + set(c), + {'utf-8.file', 'utf-16.file', 'binary.file', 'subdirectory'}, + ) + with ( + self.assertRaises(OSError), + warnings_helper.check_warnings(( + ".*contents.*", + DeprecationWarning, + )), + ): + list(resources.contents(self.anchor01, 'utf-8.file')) + + for path_parts in self._gen_resourcetxt_path_parts(): + with ( + self.assertRaises((OSError, resources.abc.TraversalError)), + warnings_helper.check_warnings(( + ".*contents.*", + DeprecationWarning, + )), + ): + list(resources.contents(self.anchor01, *path_parts)) + with warnings_helper.check_warnings((".*contents.*", DeprecationWarning)): + c = resources.contents(self.anchor01, 'subdirectory') + self.assertGreaterEqual( + set(c), + {'binary.file'}, + ) + + @warnings_helper.ignore_warnings(category=DeprecationWarning) + def test_common_errors(self): + for func in ( + resources.read_text, + resources.read_binary, + resources.open_text, + resources.open_binary, + resources.path, + resources.is_resource, + resources.contents, + ): + with self.subTest(func=func): + # Rejecting None anchor + with self.assertRaises(TypeError): + func(None) + # Rejecting invalid anchor type + with self.assertRaises((TypeError, AttributeError)): + func(1234) + # Unknown module + with self.assertRaises(ModuleNotFoundError): + func('$missing module$') + + def test_text_errors(self): + for func in ( + resources.read_text, + resources.open_text, + ): + with self.subTest(func=func): + # Multiple path arguments need explicit encoding argument. + with self.assertRaises(TypeError): + func( + self.anchor02, + 'subdirectory', + 'subsubdir', + 'resource.txt', + ) + + +class FunctionalAPITest_StringAnchor_Disk( + StringAnchorMixin, + FunctionalAPIBase, + util.DiskSetup, + unittest.TestCase, +): + pass + + +class FunctionalAPITest_ModuleAnchor_Disk( + ModuleAnchorMixin, + FunctionalAPIBase, + util.DiskSetup, + unittest.TestCase, +): + pass + + +class FunctionalAPITest_StringAnchor_Memory( + StringAnchorMixin, + FunctionalAPIBase, + util.MemorySetup, + unittest.TestCase, +): + pass diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_open.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_open.py new file mode 100644 index 00000000..8a4b68e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_open.py @@ -0,0 +1,85 @@ +import unittest + +import importlib_resources as resources + +from . import util + + +class CommonBinaryTests(util.CommonTests, unittest.TestCase): + def execute(self, package, path): + target = resources.files(package).joinpath(path) + with target.open('rb'): + pass + + +class CommonTextTests(util.CommonTests, unittest.TestCase): + def execute(self, package, path): + target = resources.files(package).joinpath(path) + with target.open(encoding='utf-8'): + pass + + +class OpenTests: + def test_open_binary(self): + target = resources.files(self.data) / 'binary.file' + with target.open('rb') as fp: + result = fp.read() + self.assertEqual(result, bytes(range(4))) + + def test_open_text_default_encoding(self): + target = resources.files(self.data) / 'utf-8.file' + with target.open(encoding='utf-8') as fp: + result = fp.read() + self.assertEqual(result, 'Hello, UTF-8 world!\n') + + def test_open_text_given_encoding(self): + target = resources.files(self.data) / 'utf-16.file' + with target.open(encoding='utf-16', errors='strict') as fp: + result = fp.read() + self.assertEqual(result, 'Hello, UTF-16 world!\n') + + def test_open_text_with_errors(self): + """ + Raises UnicodeError without the 'errors' argument. + """ + target = resources.files(self.data) / 'utf-16.file' + with target.open(encoding='utf-8', errors='strict') as fp: + self.assertRaises(UnicodeError, fp.read) + with target.open(encoding='utf-8', errors='ignore') as fp: + result = fp.read() + self.assertEqual( + result, + 'H\x00e\x00l\x00l\x00o\x00,\x00 ' + '\x00U\x00T\x00F\x00-\x001\x006\x00 ' + '\x00w\x00o\x00r\x00l\x00d\x00!\x00\n\x00', + ) + + def test_open_binary_FileNotFoundError(self): + target = resources.files(self.data) / 'does-not-exist' + with self.assertRaises(FileNotFoundError): + target.open('rb') + + def test_open_text_FileNotFoundError(self): + target = resources.files(self.data) / 'does-not-exist' + with self.assertRaises(FileNotFoundError): + target.open(encoding='utf-8') + + +class OpenDiskTests(OpenTests, util.DiskSetup, unittest.TestCase): + pass + + +class OpenDiskNamespaceTests(OpenTests, util.DiskSetup, unittest.TestCase): + MODULE = 'namespacedata01' + + +class OpenZipTests(OpenTests, util.ZipSetup, unittest.TestCase): + pass + + +class OpenNamespaceZipTests(OpenTests, util.ZipSetup, unittest.TestCase): + MODULE = 'namespacedata01' + + +if __name__ == '__main__': + unittest.main() diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_path.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_path.py new file mode 100644 index 00000000..0be673d2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_path.py @@ -0,0 +1,63 @@ +import io +import pathlib +import unittest + +import importlib_resources as resources + +from . import util + + +class CommonTests(util.CommonTests, unittest.TestCase): + def execute(self, package, path): + with resources.as_file(resources.files(package).joinpath(path)): + pass + + +class PathTests: + def test_reading(self): + """ + Path should be readable and a pathlib.Path instance. + """ + target = resources.files(self.data) / 'utf-8.file' + with resources.as_file(target) as path: + self.assertIsInstance(path, pathlib.Path) + self.assertTrue(path.name.endswith("utf-8.file"), repr(path)) + self.assertEqual('Hello, UTF-8 world!\n', path.read_text(encoding='utf-8')) + + +class PathDiskTests(PathTests, util.DiskSetup, unittest.TestCase): + def test_natural_path(self): + """ + Guarantee the internal implementation detail that + file-system-backed resources do not get the tempdir + treatment. + """ + target = resources.files(self.data) / 'utf-8.file' + with resources.as_file(target) as path: + assert 'data' in str(path) + + +class PathMemoryTests(PathTests, unittest.TestCase): + def setUp(self): + file = io.BytesIO(b'Hello, UTF-8 world!\n') + self.addCleanup(file.close) + self.data = util.create_package( + file=file, path=FileNotFoundError("package exists only in memory") + ) + self.data.__spec__.origin = None + self.data.__spec__.has_location = False + + +class PathZipTests(PathTests, util.ZipSetup, unittest.TestCase): + def test_remove_in_context_manager(self): + """ + It is not an error if the file that was temporarily stashed on the + file system is removed inside the `with` stanza. + """ + target = resources.files(self.data) / 'utf-8.file' + with resources.as_file(target) as path: + path.unlink() + + +if __name__ == '__main__': + unittest.main() diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_read.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_read.py new file mode 100644 index 00000000..216c8feb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_read.py @@ -0,0 +1,94 @@ +import unittest +from importlib import import_module + +import importlib_resources as resources + +from . import util + + +class CommonBinaryTests(util.CommonTests, unittest.TestCase): + def execute(self, package, path): + resources.files(package).joinpath(path).read_bytes() + + +class CommonTextTests(util.CommonTests, unittest.TestCase): + def execute(self, package, path): + resources.files(package).joinpath(path).read_text(encoding='utf-8') + + +class ReadTests: + def test_read_bytes(self): + result = resources.files(self.data).joinpath('binary.file').read_bytes() + self.assertEqual(result, bytes(range(4))) + + def test_read_text_default_encoding(self): + result = ( + resources.files(self.data) + .joinpath('utf-8.file') + .read_text(encoding='utf-8') + ) + self.assertEqual(result, 'Hello, UTF-8 world!\n') + + def test_read_text_given_encoding(self): + result = ( + resources.files(self.data) + .joinpath('utf-16.file') + .read_text(encoding='utf-16') + ) + self.assertEqual(result, 'Hello, UTF-16 world!\n') + + def test_read_text_with_errors(self): + """ + Raises UnicodeError without the 'errors' argument. + """ + target = resources.files(self.data) / 'utf-16.file' + self.assertRaises(UnicodeError, target.read_text, encoding='utf-8') + result = target.read_text(encoding='utf-8', errors='ignore') + self.assertEqual( + result, + 'H\x00e\x00l\x00l\x00o\x00,\x00 ' + '\x00U\x00T\x00F\x00-\x001\x006\x00 ' + '\x00w\x00o\x00r\x00l\x00d\x00!\x00\n\x00', + ) + + +class ReadDiskTests(ReadTests, util.DiskSetup, unittest.TestCase): + pass + + +class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase): + def test_read_submodule_resource(self): + submodule = import_module('data01.subdirectory') + result = resources.files(submodule).joinpath('binary.file').read_bytes() + self.assertEqual(result, bytes(range(4, 8))) + + def test_read_submodule_resource_by_name(self): + result = ( + resources.files('data01.subdirectory').joinpath('binary.file').read_bytes() + ) + self.assertEqual(result, bytes(range(4, 8))) + + +class ReadNamespaceTests(ReadTests, util.DiskSetup, unittest.TestCase): + MODULE = 'namespacedata01' + + +class ReadNamespaceZipTests(ReadTests, util.ZipSetup, unittest.TestCase): + MODULE = 'namespacedata01' + + def test_read_submodule_resource(self): + submodule = import_module('namespacedata01.subdirectory') + result = resources.files(submodule).joinpath('binary.file').read_bytes() + self.assertEqual(result, bytes(range(12, 16))) + + def test_read_submodule_resource_by_name(self): + result = ( + resources.files('namespacedata01.subdirectory') + .joinpath('binary.file') + .read_bytes() + ) + self.assertEqual(result, bytes(range(12, 16))) + + +if __name__ == '__main__': + unittest.main() diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_reader.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_reader.py new file mode 100644 index 00000000..f8cfd8de --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_reader.py @@ -0,0 +1,137 @@ +import os.path +import pathlib +import unittest +from importlib import import_module + +from importlib_resources.readers import MultiplexedPath, NamespaceReader + +from . import util + + +class MultiplexedPathTest(util.DiskSetup, unittest.TestCase): + MODULE = 'namespacedata01' + + def setUp(self): + super().setUp() + self.folder = pathlib.Path(self.data.__path__[0]) + self.data01 = pathlib.Path(self.load_fixture('data01').__file__).parent + self.data02 = pathlib.Path(self.load_fixture('data02').__file__).parent + + def test_init_no_paths(self): + with self.assertRaises(FileNotFoundError): + MultiplexedPath() + + def test_init_file(self): + with self.assertRaises(NotADirectoryError): + MultiplexedPath(self.folder / 'binary.file') + + def test_iterdir(self): + contents = {path.name for path in MultiplexedPath(self.folder).iterdir()} + try: + contents.remove('__pycache__') + except (KeyError, ValueError): + pass + self.assertEqual( + contents, {'subdirectory', 'binary.file', 'utf-16.file', 'utf-8.file'} + ) + + def test_iterdir_duplicate(self): + contents = { + path.name for path in MultiplexedPath(self.folder, self.data01).iterdir() + } + for remove in ('__pycache__', '__init__.pyc'): + try: + contents.remove(remove) + except (KeyError, ValueError): + pass + self.assertEqual( + contents, + {'__init__.py', 'binary.file', 'subdirectory', 'utf-16.file', 'utf-8.file'}, + ) + + def test_is_dir(self): + self.assertEqual(MultiplexedPath(self.folder).is_dir(), True) + + def test_is_file(self): + self.assertEqual(MultiplexedPath(self.folder).is_file(), False) + + def test_open_file(self): + path = MultiplexedPath(self.folder) + with self.assertRaises(FileNotFoundError): + path.read_bytes() + with self.assertRaises(FileNotFoundError): + path.read_text() + with self.assertRaises(FileNotFoundError): + path.open() + + def test_join_path(self): + prefix = str(self.folder.parent) + path = MultiplexedPath(self.folder, self.data01) + self.assertEqual( + str(path.joinpath('binary.file'))[len(prefix) + 1 :], + os.path.join('namespacedata01', 'binary.file'), + ) + sub = path.joinpath('subdirectory') + assert isinstance(sub, MultiplexedPath) + assert 'namespacedata01' in str(sub) + assert 'data01' in str(sub) + self.assertEqual( + str(path.joinpath('imaginary'))[len(prefix) + 1 :], + os.path.join('namespacedata01', 'imaginary'), + ) + self.assertEqual(path.joinpath(), path) + + def test_join_path_compound(self): + path = MultiplexedPath(self.folder) + assert not path.joinpath('imaginary/foo.py').exists() + + def test_join_path_common_subdir(self): + prefix = str(self.data02.parent) + path = MultiplexedPath(self.data01, self.data02) + self.assertIsInstance(path.joinpath('subdirectory'), MultiplexedPath) + self.assertEqual( + str(path.joinpath('subdirectory', 'subsubdir'))[len(prefix) + 1 :], + os.path.join('data02', 'subdirectory', 'subsubdir'), + ) + + def test_repr(self): + self.assertEqual( + repr(MultiplexedPath(self.folder)), + f"MultiplexedPath('{self.folder}')", + ) + + def test_name(self): + self.assertEqual( + MultiplexedPath(self.folder).name, + os.path.basename(self.folder), + ) + + +class NamespaceReaderTest(util.DiskSetup, unittest.TestCase): + MODULE = 'namespacedata01' + + def test_init_error(self): + with self.assertRaises(ValueError): + NamespaceReader(['path1', 'path2']) + + def test_resource_path(self): + namespacedata01 = import_module('namespacedata01') + reader = NamespaceReader(namespacedata01.__spec__.submodule_search_locations) + + root = self.data.__path__[0] + self.assertEqual( + reader.resource_path('binary.file'), os.path.join(root, 'binary.file') + ) + self.assertEqual( + reader.resource_path('imaginary'), os.path.join(root, 'imaginary') + ) + + def test_files(self): + reader = NamespaceReader(self.data.__spec__.submodule_search_locations) + root = self.data.__path__[0] + self.assertIsInstance(reader.files(), MultiplexedPath) + self.assertEqual(repr(reader.files()), f"MultiplexedPath('{root}')") + + +if __name__ == '__main__': + unittest.main() diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_resource.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_resource.py new file mode 100644 index 00000000..c80afdc7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_resource.py @@ -0,0 +1,238 @@ +import unittest +from importlib import import_module + +import importlib_resources as resources + +from . import util + + +class ResourceTests: + # Subclasses are expected to set the `data` attribute. + + def test_is_file_exists(self): + target = resources.files(self.data) / 'binary.file' + self.assertTrue(target.is_file()) + + def test_is_file_missing(self): + target = resources.files(self.data) / 'not-a-file' + self.assertFalse(target.is_file()) + + def test_is_dir(self): + target = resources.files(self.data) / 'subdirectory' + self.assertFalse(target.is_file()) + self.assertTrue(target.is_dir()) + + +class ResourceDiskTests(ResourceTests, util.DiskSetup, unittest.TestCase): + pass + + +class ResourceZipTests(ResourceTests, util.ZipSetup, unittest.TestCase): + pass + + +def names(traversable): + return {item.name for item in traversable.iterdir()} + + +class ResourceLoaderTests(util.DiskSetup, unittest.TestCase): + def test_resource_contents(self): + package = util.create_package( + file=self.data, path=self.data.__file__, contents=['A', 'B', 'C'] + ) + self.assertEqual(names(resources.files(package)), {'A', 'B', 'C'}) + + def test_is_file(self): + package = util.create_package( + file=self.data, + path=self.data.__file__, + contents=['A', 'B', 'C', 'D/E', 'D/F'], + ) + self.assertTrue(resources.files(package).joinpath('B').is_file()) + + def test_is_dir(self): + package = util.create_package( + file=self.data, + path=self.data.__file__, + contents=['A', 'B', 'C', 'D/E', 'D/F'], + ) + self.assertTrue(resources.files(package).joinpath('D').is_dir()) + + def test_resource_missing(self): + package = util.create_package( + file=self.data, + path=self.data.__file__, + contents=['A', 'B', 'C', 'D/E', 'D/F'], + ) + self.assertFalse(resources.files(package).joinpath('Z').is_file()) + + +class ResourceCornerCaseTests(util.DiskSetup, unittest.TestCase): + def test_package_has_no_reader_fallback(self): + """ + Test odd ball packages which: + # 1. Do not have a ResourceReader as a loader + # 2. Are not on the file system + # 3. Are not in a zip file + """ + module = util.create_package( + file=self.data, path=self.data.__file__, contents=['A', 'B', 'C'] + ) + # Give the module a dummy loader. + module.__loader__ = object() + # Give the module a dummy origin. + module.__file__ = '/path/which/shall/not/be/named' + module.__spec__.loader = module.__loader__ + module.__spec__.origin = module.__file__ + self.assertFalse(resources.files(module).joinpath('A').is_file()) + + +class ResourceFromZipsTest01(util.ZipSetup, unittest.TestCase): + def test_is_submodule_resource(self): + submodule = import_module('data01.subdirectory') + self.assertTrue(resources.files(submodule).joinpath('binary.file').is_file()) + + def test_read_submodule_resource_by_name(self): + self.assertTrue( + resources.files('data01.subdirectory').joinpath('binary.file').is_file() + ) + + def test_submodule_contents(self): + submodule = import_module('data01.subdirectory') + self.assertEqual( + names(resources.files(submodule)), {'__init__.py', 'binary.file'} + ) + + def test_submodule_contents_by_name(self): + self.assertEqual( + names(resources.files('data01.subdirectory')), + {'__init__.py', 'binary.file'}, + ) + + def test_as_file_directory(self): + with resources.as_file(resources.files('data01')) as data: + assert data.name == 'data01' + assert data.is_dir() + assert data.joinpath('subdirectory').is_dir() + assert len(list(data.iterdir())) + assert not data.parent.exists() + + +class ResourceFromZipsTest02(util.ZipSetup, unittest.TestCase): + MODULE = 'data02' + + def test_unrelated_contents(self): + """ + Test thata zip with two unrelated subpackages return + distinct resources. Ref python/importlib_resources#44. + """ + self.assertEqual( + names(resources.files('data02.one')), + {'__init__.py', 'resource1.txt'}, + ) + self.assertEqual( + names(resources.files('data02.two')), + {'__init__.py', 'resource2.txt'}, + ) + + +class DeletingZipsTest(util.ZipSetup, unittest.TestCase): + """Having accessed resources in a zip file should not keep an open + reference to the zip. + """ + + def test_iterdir_does_not_keep_open(self): + [item.name for item in resources.files('data01').iterdir()] + + def test_is_file_does_not_keep_open(self): + resources.files('data01').joinpath('binary.file').is_file() + + def test_is_file_failure_does_not_keep_open(self): + resources.files('data01').joinpath('not-present').is_file() + + @unittest.skip("Desired but not supported.") + def test_as_file_does_not_keep_open(self): # pragma: no cover + resources.as_file(resources.files('data01') / 'binary.file') + + def test_entered_path_does_not_keep_open(self): + """ + Mimic what certifi does on import to make its bundle + available for the process duration. + """ + resources.as_file(resources.files('data01') / 'binary.file').__enter__() + + def test_read_binary_does_not_keep_open(self): + resources.files('data01').joinpath('binary.file').read_bytes() + + def test_read_text_does_not_keep_open(self): + resources.files('data01').joinpath('utf-8.file').read_text(encoding='utf-8') + + +class ResourceFromNamespaceTests: + def test_is_submodule_resource(self): + self.assertTrue( + resources.files(import_module('namespacedata01')) + .joinpath('binary.file') + .is_file() + ) + + def test_read_submodule_resource_by_name(self): + self.assertTrue( + resources.files('namespacedata01').joinpath('binary.file').is_file() + ) + + def test_submodule_contents(self): + contents = names(resources.files(import_module('namespacedata01'))) + try: + contents.remove('__pycache__') + except KeyError: + pass + self.assertEqual( + contents, {'subdirectory', 'binary.file', 'utf-8.file', 'utf-16.file'} + ) + + def test_submodule_contents_by_name(self): + contents = names(resources.files('namespacedata01')) + try: + contents.remove('__pycache__') + except KeyError: + pass + self.assertEqual( + contents, {'subdirectory', 'binary.file', 'utf-8.file', 'utf-16.file'} + ) + + def test_submodule_sub_contents(self): + contents = names(resources.files(import_module('namespacedata01.subdirectory'))) + try: + contents.remove('__pycache__') + except KeyError: + pass + self.assertEqual(contents, {'binary.file'}) + + def test_submodule_sub_contents_by_name(self): + contents = names(resources.files('namespacedata01.subdirectory')) + try: + contents.remove('__pycache__') + except KeyError: + pass + self.assertEqual(contents, {'binary.file'}) + + +class ResourceFromNamespaceDiskTests( + util.DiskSetup, + ResourceFromNamespaceTests, + unittest.TestCase, +): + MODULE = 'namespacedata01' + + +class ResourceFromNamespaceZipTests( + util.ZipSetup, + ResourceFromNamespaceTests, + unittest.TestCase, +): + MODULE = 'namespacedata01' + + +if __name__ == '__main__': + unittest.main() diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_util.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_util.py new file mode 100644 index 00000000..de304b6f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/test_util.py @@ -0,0 +1,29 @@ +import unittest + +from .util import MemorySetup, Traversable + + +class TestMemoryTraversableImplementation(unittest.TestCase): + def test_concrete_methods_are_not_overridden(self): + """`MemoryTraversable` must not override `Traversable` concrete methods. + + This test is not an attempt to enforce a particular `Traversable` protocol; + it merely catches changes in the `Traversable` abstract/concrete methods + that have not been mirrored in the `MemoryTraversable` subclass. + """ + + traversable_concrete_methods = { + method + for method, value in Traversable.__dict__.items() + if callable(value) and method not in Traversable.__abstractmethods__ + } + memory_traversable_concrete_methods = { + method + for method, value in MemorySetup.MemoryTraversable.__dict__.items() + if callable(value) and not method.startswith("__") + } + overridden_methods = ( + memory_traversable_concrete_methods & traversable_concrete_methods + ) + + assert not overridden_methods diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/util.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/util.py new file mode 100644 index 00000000..0340c150 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/util.py @@ -0,0 +1,308 @@ +import abc +import contextlib +import functools +import importlib +import io +import pathlib +import sys +import types +from importlib.machinery import ModuleSpec + +from ..abc import ResourceReader, Traversable, TraversableResources +from . import _path +from . import zip as zip_ +from .compat.py39 import import_helper, os_helper + + +class Reader(ResourceReader): + def __init__(self, **kwargs): + vars(self).update(kwargs) + + def get_resource_reader(self, package): + return self + + def open_resource(self, path): + self._path = path + if isinstance(self.file, Exception): + raise self.file + return self.file + + def resource_path(self, path_): + self._path = path_ + if isinstance(self.path, Exception): + raise self.path + return self.path + + def is_resource(self, path_): + self._path = path_ + if isinstance(self.path, Exception): + raise self.path + + def part(entry): + return entry.split('/') + + return any( + len(parts) == 1 and parts[0] == path_ for parts in map(part, self._contents) + ) + + def contents(self): + if isinstance(self.path, Exception): + raise self.path + yield from self._contents + + +def create_package_from_loader(loader, is_package=True): + name = 'testingpackage' + module = types.ModuleType(name) + spec = ModuleSpec(name, loader, origin='does-not-exist', is_package=is_package) + module.__spec__ = spec + module.__loader__ = loader + return module + + +def create_package(file=None, path=None, is_package=True, contents=()): + return create_package_from_loader( + Reader(file=file, path=path, _contents=contents), + is_package, + ) + + +class CommonTestsBase(metaclass=abc.ABCMeta): + """ + Tests shared by test_open, test_path, and test_read. + """ + + @abc.abstractmethod + def execute(self, package, path): + """ + Call the pertinent legacy API function (e.g. open_text, path) + on package and path. + """ + + def test_package_name(self): + """ + Passing in the package name should succeed. + """ + self.execute(self.data.__name__, 'utf-8.file') + + def test_package_object(self): + """ + Passing in the package itself should succeed. + """ + self.execute(self.data, 'utf-8.file') + + def test_string_path(self): + """ + Passing in a string for the path should succeed. + """ + path = 'utf-8.file' + self.execute(self.data, path) + + def test_pathlib_path(self): + """ + Passing in a pathlib.PurePath object for the path should succeed. + """ + path = pathlib.PurePath('utf-8.file') + self.execute(self.data, path) + + def test_importing_module_as_side_effect(self): + """ + The anchor package can already be imported. + """ + del sys.modules[self.data.__name__] + self.execute(self.data.__name__, 'utf-8.file') + + def test_missing_path(self): + """ + Attempting to open or read or request the path for a + non-existent path should succeed if open_resource + can return a viable data stream. + """ + bytes_data = io.BytesIO(b'Hello, world!') + package = create_package(file=bytes_data, path=FileNotFoundError()) + self.execute(package, 'utf-8.file') + self.assertEqual(package.__loader__._path, 'utf-8.file') + + def test_extant_path(self): + # Attempting to open or read or request the path when the + # path does exist should still succeed. Does not assert + # anything about the result. + bytes_data = io.BytesIO(b'Hello, world!') + # any path that exists + path = __file__ + package = create_package(file=bytes_data, path=path) + self.execute(package, 'utf-8.file') + self.assertEqual(package.__loader__._path, 'utf-8.file') + + def test_useless_loader(self): + package = create_package(file=FileNotFoundError(), path=FileNotFoundError()) + with self.assertRaises(FileNotFoundError): + self.execute(package, 'utf-8.file') + + +fixtures = dict( + data01={ + '__init__.py': '', + 'binary.file': bytes(range(4)), + 'utf-16.file': '\ufeffHello, UTF-16 world!\n'.encode('utf-16-le'), + 'utf-8.file': 'Hello, UTF-8 world!\n'.encode('utf-8'), + 'subdirectory': { + '__init__.py': '', + 'binary.file': bytes(range(4, 8)), + }, + }, + data02={ + '__init__.py': '', + 'one': {'__init__.py': '', 'resource1.txt': 'one resource'}, + 'two': {'__init__.py': '', 'resource2.txt': 'two resource'}, + 'subdirectory': {'subsubdir': {'resource.txt': 'a resource'}}, + }, + namespacedata01={ + 'binary.file': bytes(range(4)), + 'utf-16.file': '\ufeffHello, UTF-16 world!\n'.encode('utf-16-le'), + 'utf-8.file': 'Hello, UTF-8 world!\n'.encode('utf-8'), + 'subdirectory': { + 'binary.file': bytes(range(12, 16)), + }, + }, +) + + +class ModuleSetup: + def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + + self.fixtures.enter_context(import_helper.isolated_modules()) + self.data = self.load_fixture(self.MODULE) + + def load_fixture(self, module): + self.tree_on_path({module: fixtures[module]}) + return importlib.import_module(module) + + +class ZipSetup(ModuleSetup): + MODULE = 'data01' + + def tree_on_path(self, spec): + temp_dir = self.fixtures.enter_context(os_helper.temp_dir()) + modules = pathlib.Path(temp_dir) / 'zipped modules.zip' + self.fixtures.enter_context( + import_helper.DirsOnSysPath(str(zip_.make_zip_file(spec, modules))) + ) + + +class DiskSetup(ModuleSetup): + MODULE = 'data01' + + def tree_on_path(self, spec): + temp_dir = self.fixtures.enter_context(os_helper.temp_dir()) + _path.build(spec, pathlib.Path(temp_dir)) + self.fixtures.enter_context(import_helper.DirsOnSysPath(temp_dir)) + + +class MemorySetup(ModuleSetup): + """Support loading a module in memory.""" + + MODULE = 'data01' + + def load_fixture(self, module): + self.fixtures.enter_context(self.augment_sys_metapath(module)) + return importlib.import_module(module) + + @contextlib.contextmanager + def augment_sys_metapath(self, module): + finder_instance = self.MemoryFinder(module) + sys.meta_path.append(finder_instance) + yield + sys.meta_path.remove(finder_instance) + + class MemoryFinder(importlib.abc.MetaPathFinder): + def __init__(self, module): + self._module = module + + def find_spec(self, fullname, path, target=None): + if fullname != self._module: + return None + + return importlib.machinery.ModuleSpec( + name=fullname, + loader=MemorySetup.MemoryLoader(self._module), + is_package=True, + ) + + class MemoryLoader(importlib.abc.Loader): + def __init__(self, module): + self._module = module + + def exec_module(self, module): + pass + + def get_resource_reader(self, fullname): + return MemorySetup.MemoryTraversableResources(self._module, fullname) + + class MemoryTraversableResources(TraversableResources): + def __init__(self, module, fullname): + self._module = module + self._fullname = fullname + + def files(self): + return MemorySetup.MemoryTraversable(self._module, self._fullname) + + class MemoryTraversable(Traversable): + """Implement only the abstract methods of `Traversable`. + + Besides `.__init__()`, no other methods may be implemented or overridden. + This is critical for validating the concrete `Traversable` implementations. + """ + + def __init__(self, module, fullname): + self._module = module + self._fullname = fullname + + def _resolve(self): + """ + Fully traverse the `fixtures` dictionary. + + This should be wrapped in a `try/except KeyError` + but it is not currently needed and lowers the code coverage numbers. + """ + path = pathlib.PurePosixPath(self._fullname) + return functools.reduce(lambda d, p: d[p], path.parts, fixtures) + + def iterdir(self): + directory = self._resolve() + if not isinstance(directory, dict): + # Filesystem openers raise OSError, and that exception is mirrored here. + raise OSError(f"{self._fullname} is not a directory") + for path in directory: + yield MemorySetup.MemoryTraversable( + self._module, f"{self._fullname}/{path}" + ) + + def is_dir(self) -> bool: + return isinstance(self._resolve(), dict) + + def is_file(self) -> bool: + return not self.is_dir() + + def open(self, mode='r', encoding=None, errors=None, *_, **__): + contents = self._resolve() + if isinstance(contents, dict): + # Filesystem openers raise OSError when attempting to open a directory, + # and that exception is mirrored here. + raise OSError(f"{self._fullname} is a directory") + if isinstance(contents, str): + contents = contents.encode("utf-8") + result = io.BytesIO(contents) + if "b" in mode: + return result + return io.TextIOWrapper(result, encoding=encoding, errors=errors) + + @property + def name(self): + return pathlib.PurePosixPath(self._fullname).name + + +class CommonTests(DiskSetup, CommonTestsBase): + pass diff --git a/.venv/lib/python3.12/site-packages/importlib_resources/tests/zip.py b/.venv/lib/python3.12/site-packages/importlib_resources/tests/zip.py new file mode 100644 index 00000000..51ee5648 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/importlib_resources/tests/zip.py @@ -0,0 +1,26 @@ +""" +Generate zip test data files. +""" + +import zipfile + +import zipp + + +def make_zip_file(tree, dst): + """ + Zip the files in tree into a new zipfile at dst. + """ + with zipfile.ZipFile(dst, 'w') as zf: + for name, contents in walk(tree): + zf.writestr(name, contents) + zipp.CompleteDirs.inject(zf) + return dst + + +def walk(tree, prefix=''): + for name, contents in tree.items(): + if isinstance(contents, dict): + yield from walk(contents, prefix=f'{prefix}{name}/') + else: + yield f'{prefix}{name}', contents diff --git a/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/METADATA b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/METADATA new file mode 100644 index 00000000..a0d2a6b8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/METADATA @@ -0,0 +1,82 @@ +Metadata-Version: 2.4 +Name: prophet +Version: 1.1.7 +Summary: Automatic Forecasting Procedure +Author-email: "Sean J. Taylor" , Ben Letham +Maintainer-email: Cuong Duong +License: MIT +Project-URL: Homepage, https://facebook.github.io/prophet/ +Project-URL: Documentation, https://facebook.github.io/prophet/ +Project-URL: Repository, https://github.com/facebook/prophet +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: cmdstanpy>=1.0.4 +Requires-Dist: numpy>=1.15.4 +Requires-Dist: matplotlib>=2.0.0 +Requires-Dist: pandas>=1.0.4 +Requires-Dist: holidays<1,>=0.25 +Requires-Dist: tqdm>=4.36.1 +Requires-Dist: importlib_resources +Provides-Extra: dev +Requires-Dist: setuptools>=64; extra == "dev" +Requires-Dist: wheel; extra == "dev" +Requires-Dist: pytest; extra == "dev" +Requires-Dist: jupyterlab; extra == "dev" +Requires-Dist: nbconvert; extra == "dev" +Requires-Dist: plotly; extra == "dev" +Provides-Extra: parallel +Requires-Dist: dask[dataframe]; extra == "parallel" +Requires-Dist: distributed; extra == "parallel" +Dynamic: license-file + +# Prophet: Automatic Forecasting Procedure + +Prophet is a procedure for forecasting time series data based on an additive model where non-linear trends are fit with yearly, weekly, and daily seasonality, plus holiday effects. It works best with time series that have strong seasonal effects and several seasons of historical data. Prophet is robust to missing data and shifts in the trend, and typically handles outliers well. + +Prophet is [open source software](https://code.facebook.com/projects/>) released by [Facebook's Core Data Science team ](https://research.fb.com/category/data-science/). + +Full documentation and examples available at the homepage: https://facebook.github.io/prophet/ + +## Important links + +- HTML documentation: https://facebook.github.io/prophet/docs/quick_start.html +- Issue tracker: https://github.com/facebook/prophet/issues +- Source code repository: https://github.com/facebook/prophet +- Implementation of Prophet in R: https://cran.r-project.org/package=prophet + +## Other forecasting packages + +- Rob Hyndman's [forecast package](http://robjhyndman.com/software/forecast/) +- [Statsmodels](http://statsmodels.sourceforge.net/) + +## Installation - PyPI release + +See [Installation in Python - PyPI release](https://github.com/facebook/prophet#installation-in-python---pypi-release) + +## Installation - Development version + +See [Installation in Python - Development version](https://github.com/facebook/prophet#installation-in-python---development-version) + +### Installation using Docker and docker-compose (via Makefile) + +Simply type `make build` and if everything is fine you should be able to `make shell` or alternative jump directly to `make py-shell`. + +To run the tests, inside the container `cd python/prophet` and then `python -m pytest prophet/tests/` + +### Example usage + +```python + >>> from prophet import Prophet + >>> m = Prophet() + >>> m.fit(df) # df is a pandas.DataFrame with 'y' and 'ds' columns + >>> future = m.make_future_dataframe(periods=365) + >>> m.predict(future) +``` diff --git a/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/RECORD b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/RECORD new file mode 100644 index 00000000..44e4b195 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/RECORD @@ -0,0 +1,783 @@ +prophet-1.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +prophet-1.1.7.dist-info/METADATA,sha256=DuvOpuaF1xCkUMCDlv-I3BDdvmnfygNhuFrrNgCvlsc,3495 +prophet-1.1.7.dist-info/RECORD,, +prophet-1.1.7.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +prophet-1.1.7.dist-info/WHEEL,sha256=fFhbKX-dUaoAkV6fMdPsBXB59ktXVc2nZ3V5h4Y98LM,145 +prophet-1.1.7.dist-info/licenses/LICENSE,sha256=UkEte8fOQVfqYou6rLiCngqcs8WPV_mRdhJryM8r_IU,1086 +prophet-1.1.7.dist-info/top_level.txt,sha256=VjCzuVgaPL8q6jJnMQFtNyQBChuMcpMw3b-dloq_esI,8 +prophet.libs/libtbb-ff323302.so.2,sha256=GhTtpfz5UnfzT4j4oYOvg8J0TqqPakcZ6w19DHrHBhU,3678161 +prophet.libs/libtbbmalloc-4dcb68e3.so.2,sha256=UV_toaFwQnjJ_OMRvz4Q8uHoLVqxhdy6AKOqopV9lSM,1010017 +prophet/__init__.py,sha256=GWmjzHPDVJuUNn-Fv3f2acZ3ZIPMPGR6U4qlJA2suL4,517 +prophet/__pycache__/__init__.cpython-312.pyc,, +prophet/__pycache__/__version__.cpython-312.pyc,, +prophet/__pycache__/diagnostics.cpython-312.pyc,, +prophet/__pycache__/forecaster.cpython-312.pyc,, +prophet/__pycache__/make_holidays.cpython-312.pyc,, +prophet/__pycache__/models.cpython-312.pyc,, +prophet/__pycache__/plot.cpython-312.pyc,, +prophet/__pycache__/serialize.cpython-312.pyc,, +prophet/__pycache__/utilities.cpython-312.pyc,, +prophet/__version__.py,sha256=p2qAfdU7zHOShJi2f1FW-_7Tbm0-KCPE7CI7284QiHg,22 +prophet/diagnostics.py,sha256=1KQvC6avKQE-7qvuxAhru9vQv3P2AVWqhd7I7y3-Eyw,23754 +prophet/forecaster.py,sha256=jY2QfhoXB26SW6j26qkW-4tfiejpGBFCBtFrplO626s,79089 +prophet/make_holidays.py,sha256=8FNRl3T_mO9G1qe54OS3ELRDiXvSGK4eh7ZdETArsOw,2091 +prophet/models.py,sha256=EucMEmEvTlG4XETM_nTaDeTbjkwAwWF80laKZ01iwdY,8991 +prophet/plot.py,sha256=fs72_9eCxkT-7yW-ukKtzAkJ9aLSXpdxf0ZzUMUYj50,36919 +prophet/serialize.py,sha256=mNBfz3cU8a1J8GmPpHAF4Vm4F_iW-bXOe7FQv3oLosc,7443 +prophet/stan_model/cmdstan-2.33.1/bin/diagnose,sha256=Ayf8wdcmgI2TRFHaT2pZoiL9S4pMeLfzSjx8s2LgFLw,401448 +prophet/stan_model/cmdstan-2.33.1/bin/print,sha256=ePh1Px6wD9Rty4AaAzyeSk2Z5Er9VEmiqVphoHYbGXU,406592 +prophet/stan_model/cmdstan-2.33.1/bin/stanc,sha256=FPr-Up-OPU7_VS3O_773iIVadvp44Xc-1HXeKwj7rvQ,14393232 +prophet/stan_model/cmdstan-2.33.1/bin/stansummary,sha256=28KdWVozcrY8UxoQNjQ8Ryk0RmI-etLjSI_h_9q3PgI,686384 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/arena.d,sha256=FLkhkEve2psMesDqP9w0e0uX2k9MfxPbiWqIdP8CxFc,3410 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/arena.o,sha256=LLq1mLVFrA5NCf4GZ0cgzybEQ-8jc7QbOzCmfwZe3Tc,840888 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backend.d,sha256=QeAqB06Y07nX_4zqTXf2i9qwojff_nxEXnLYZTj6iv8,1644 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backend.o,sha256=fddgi61-yi9RJSvqQ-rjvPwcJIIZDtQ4mDqVPF6CXxw,537304 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backref.d,sha256=JHICW8o6oP-8SiBOnuTSBzLlBCDviGYP8c_dJDIh2CU,1601 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backref.o,sha256=5wWTTAb6ExPgK1C-iobErMjwh6tlM7K0DQGUlO7KVeg,144704 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/cache_aligned_allocator.d,sha256=GLDS5HDRww_xJSEe9nwnuXz7KXFcNRxPgsscLBF4oF8,1146 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/cache_aligned_allocator.o,sha256=LdXDh7vScfpqYs4ozSGRQe4GGsen5A-41VZyCud_u5Y,81696 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_hash_map.d,sha256=YnAAwepTkP9NUmhfAreNqOb5tghT8JMU5i-P7ZWjYUg,1603 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_hash_map.o,sha256=IKvk6YTcrNjkOxxXF37uGBR5KDXZbZXjCNEeLJ9XJdI,43968 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_monitor.d,sha256=54oNrL-RZfTV644vxrDR8iobDFkrBDT1QEHOapkwWOw,1354 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_monitor.o,sha256=1RplYWR76eTUTJK_lD1bas1toMSDt8gVDbMQZrXZIdc,187784 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue.d,sha256=I2l9anPZNUHV_udtjLhK38QLTxmYO6BeuwSViW82W8o,2444 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue.o,sha256=qPJ6ZHRemisg2MeECEeVWeSshgfBU4a0WxAywHuFvjw,552104 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue_v2.d,sha256=HkJMxphv7Ca12PtRfDOg6LUPaRAgCjSTesoGHR-hU-0,1240 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue_v2.o,sha256=usu-7wJG_AERKivIbTHEf6KJf-AueD1FMvpYQuAQiGA,237576 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector.d,sha256=C-FzqZcKJiX3LHXCIZsuYKt_fT-PNd5cb3M631Vq_s8,1627 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector.o,sha256=OEEywJBk-FbxNjt6U9F6vwZIxNCe8uv8fObUwCo5DIA,842536 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector_v2.d,sha256=d0X_YQqhweCWTaZCt6n-bLwQQqtlxoU2HgHQosRm2C4,1321 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector_v2.o,sha256=iAhmb4x8xNfvYRbw5kvrDPJk16uFA2x_owFtNPuv4jA,234328 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/condition_variable.d,sha256=RSIuGrc8kdz_JnsUOzKWQxeDcwlhRhgx8eC0HT-Wnu4,2269 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/condition_variable.o,sha256=3JhTgbOVITUAm75TFT0C_6f_YZzziDVpLckjNEa7Tsk,32320 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/critical_section.d,sha256=Mrpzc_16m9hWzgxaKfx1SaDPQcevyN2713LLN0SVvKQ,1312 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/critical_section.o,sha256=J26JX17ezhyCkdq_yVEa9zf9V4Kf9oqybATEdgTUASU,36104 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/dynamic_link.d,sha256=O4K_Gm6coRC7vQcecwLAs8rW_pJ6jRrNMvuKbiE0jO4,934 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/dynamic_link.o,sha256=tX2oKAs39THP1hkfOhCLY4AdJ_UgXRkS_WXf7REjqOg,107600 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/frontend.d,sha256=4lMlwWPl8cRDsQKZxB9ddqdXSoo5J5At2m9BMMwuOsU,1781 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/frontend.o,sha256=EHryODx98TLRbpXLLC1uQdfY_-dDXXhqkDhoI78whZs,671136 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/governor.d,sha256=PDFszZcOE5qY0dfPNfEem3imNGEDkdbrToUMNxHQ7_M,3085 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/governor.o,sha256=BFwmC-TYAii_SiZiJ4sXLMwPWyCUm3j22I2sQLE8rT8,258440 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify.d,sha256=MwwWQ22fCN4BclvDJea1mKIcNjFlB-Xm6DoCgXRYwMc,644 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify.o,sha256=TkeQ8-oGzfbl5KL_BtF7CGxSQJDf5v55F03__HfBUAM,294328 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify_malloc.d,sha256=wPJ28uD3nQSHp9-8TE5i3nf-V8JdW0CwWpJ0tLwGn7w,651 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify_malloc.o,sha256=RrAEosJbgd5hWP9VZTgeQFWpdotBS6sIReUrQCQbceo,294504 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/large_objects.d,sha256=GDNSGMHCezmKG0L-CGLzcqrIMRZ-ktpTJZ9b_m4clcc,1656 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/large_objects.o,sha256=HGPTJDpDQiNIRac9zfSZSM-oehCmGJS_0eRnttEhhBU,530560 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbb.so,sha256=N7UHzvJrR7fRwr7vyR7B4w1hsOlAc768p4CsaHCmKHg,20 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbb.so.2,sha256=_zIzAk7LOGzXyauk7QcRQX566K5uZm8U6ymoc-gez8Y,3592920 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc.so,sha256=RItjPMRisvozEBVGUshTcVsK5tnxa64EsIBqjnvUK9s,26 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc.so.2,sha256=Tcto49ArkyxPUUiC7KYaKkkpFrVqogYz_46t4UCYP4s,1001488 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc_proxy.so,sha256=cpmhtMB3D1m1X04aEWPXISsHvQFgquoeHm_6QWi29bk,32 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc_proxy.so.2,sha256=rJDC1hZ0ZhgzE6TThjwYd_xOkmpJ6F-pJt9b_QC4uLw,75577 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/market.d,sha256=Fz8avz3qlBoUJ5v1gcrjFO69xoCZ6dZ1IfFvKEV12W8,3093 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/market.o,sha256=T9K3xrSjxYMnyWXlBYh7zcwLQ5Pn-O-FJt8gWKLMdAE,411256 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/mutex.d,sha256=a_yPwodVH2AOaGbIwAoOfY0zgdS3wTt3K-o47Raeg0o,1491 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/mutex.o,sha256=YJC0dqB6bc9-fuXcs9y5W5tEFpu5EjDInnFEV81MMr4,38680 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/observer_proxy.d,sha256=gfCO2HH-QCZGMUL4AspHbYjkj1UAVuMCFG_Uj6yd3ls,3063 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/observer_proxy.o,sha256=HX2Ds_k7yTQZCS5e-vJsFYEhdu4fv229jvlBLVom0Gw,283568 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/pipeline.d,sha256=ahrNJa2NBBbU_33QuNayg0U6YIwJCW7OViJEl8n8tNk,1496 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/pipeline.o,sha256=-0ADUzXB2Vrg6NAIYwwiHBHcfiBUhoFgbxftDlYMHLw,307856 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/private_server.d,sha256=Gzr54J5ouFsacuDbgtgJW69tkX-mXfX37f8z0JQHzvg,1996 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/private_server.o,sha256=8rjCDUetA0rypEoC72B-NiyqyVISR9a4VdpXlwnPyXk,354632 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/proxy.d,sha256=goh995u4XHJXX6ENKlXnAtsc6pZq1roUQW2etNfUQBg,549 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/proxy.o,sha256=_tF4fekHwSGoawQ-WKbhaeLIdyB_hxtksbkF_jyhE1g,101632 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_mutex.d,sha256=b73ackSrRD-iXvAxdrsodWVsNDO4ohJtwexwa-cVZSU,1213 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_mutex.o,sha256=NDzPfdIvvbU1gbQOnx8dVTDN1i9M8yfZnzVg7BFm3q8,55216 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_rw_mutex.d,sha256=a9Zktk0z-m9o1d-2TPsI8dsUY4uB7S4y-Ed-l4Ey1LY,1118 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_rw_mutex.o,sha256=GrHSFwxbxqaDD2GQIsex6T7TjRD52j90rY2wM4vUTrU,257208 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/reader_writer_lock.d,sha256=TjrvqHK8ajNupHt_DV9s8QGJMSWR7WxYhLqX2jaZ69o,1263 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/reader_writer_lock.o,sha256=vEATHLSIyjY_CRlwimbTPva4GtrO0TDOzrYBw-13-4U,279048 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/recursive_mutex.d,sha256=Wn14LyLJx4gg3658DZTPlVSSuhEGOvX2l7oNwmK3ZTU,1114 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/recursive_mutex.o,sha256=F6VMSiZPb98KwLStRo7UxBBuoUGqiwiQM9a_cYKVHnY,32888 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/rml_tbb.d,sha256=LoOMHbFR5sK0eaAMC-O7ZHO4EzE2PwTwJgfrGuZB_3E,371 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/rml_tbb.o,sha256=q2EloYf6EkHGSs073TnT2m-sNEIwozYsepmDb1pzL6I,24928 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/scheduler.d,sha256=uqBghU7GLStytFTvRJifVrC9AFVHnPkAP8fJAhauMOE,3066 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/scheduler.o,sha256=WixDA-T4Nzjzu7Ykr3wZZLnXSRE4reT2SheSyN0-RyU,944544 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/semaphore.d,sha256=dH1bJckcRvPZKsVRWJoxeTWqS6RItObZf4deaOAxu-k,810 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/semaphore.o,sha256=jTOqCme-fA_sjU4g7xvno7ZGKRUXKTjQKOX0cUALhPw,19824 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_mutex.d,sha256=dNX_8urTD8n9Dv8TIt0qjoeJWApm6eYNsR3P8sCKU80,1371 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_mutex.o,sha256=gv6wpQF0QmyH-bm4HFGFJsPwcMZ79_59J-KR2JNtUpM,33144 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex.d,sha256=WcjlvAW6bWpBcKlzjjavvJKRr2lyEC7myqPgAe4pIyg,1485 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex.o,sha256=07GJyHBvC68kL_oqHX-_FWZzU9FrIsPaDX3gBxepsKY,59016 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex_v2.d,sha256=92Ls9auEB487yY8Op_Ohca_OWypi1JGFLulUPTl2sVM,1037 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex_v2.o,sha256=iYtdu_Eux0D4JkMfKVw7OS9EQzpwcflBb7eHmD54fpk,60848 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task.d,sha256=Dv_TFgqXf0p2fZqQoBwiGSqZaskSchr9qBKomCLDX88,3010 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task.o,sha256=TLATufqI_GG_FSci3gc5FqBRvVpzmpmaSda41boyCgM,207784 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_group_context.d,sha256=GE0Fe-PcoLLpv_cdpUnHEKDOUo79gKZ_xam5Hq5P1vc,2995 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_group_context.o,sha256=Pml__lCybeueG7JQmPh_iQ9AZleB0XUaUOsqFpT47yk,373312 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_v2.d,sha256=VwKuRsxv1mD-AzPYHww6yGUN9AbIIwZeuz3ZpSnNgf4,864 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_v2.o,sha256=Y16npbXSgvlP88V133-zHy86IDmtkK98fblVIZVoshA,25000 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb-make-check,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb.def,sha256=EzDxyY9kJML0-juczowdEQ4uDsUOguVZrvS3KkFAsuw,15679 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_function_replacement.d,sha256=XF0XEpILjqwKMjMRAOzIe0BlU4wBMpa55ixqRirNZb8,130 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_function_replacement.o,sha256=ASY4UU39U3YQs4aC_Cz_ryjaDIC28PpxXWu-Q6do0Uc,2840 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_main.d,sha256=f8nCJK4bkK86iygyqEYTJd0AAvRHKcY7miC5n-_SoNM,2525 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_main.o,sha256=dCSflX-mWc9YvGx4XkTH9EDCMI2F8IB9aNjZl8CLkdc,273456 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc.d,sha256=QbwsWyRrRBW1vYhyp6Zc1WRgSXnoVRTn2nOi6cX_Uwg,1074 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc.o,sha256=1J3Zscp28RHquqPYtxbbq50pL8pllJKT9PgkZiYXNhA,107032 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc_ex.d,sha256=oItod0RqDo-2GLJ4yuzwmB2JLCBWzxAzVenZG_Or0gY,929 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc_ex.o,sha256=DrG3ChM1EUg3FQ5xvaCLgIxv5X09CP5-DBcB2nL2qkw,94024 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_statistics.d,sha256=4YeVFHDUhwxW0Akk0d0wVUMxumUDBS96nq-RZ4N28gA,185 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_statistics.o,sha256=XwmnM2-TVipTTTqQqcxjraxoZIWJZiQ6dSZ2HhBvdLs,16256 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_thread.d,sha256=48ThZaULLb-bmm-4nU3srHRHfBEMql8DJ5PDZiI_L98,1423 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_thread.o,sha256=uC2g5gNEey3khL5Q27WZwCsQnuC3CTSvK--sa1J7z0A,58184 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.d,sha256=YGpuRFVf9btnNcrzIjH7WFK6KthLq1GP2uiq9kJkPoU,1427 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.def,sha256=ON9NfNcqDzAQeTKo4Cnn8-Qtp29rKWLK9Im_JnuA1cQ,1641 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.o,sha256=cATtQiQy_iVRgOXAXm3p3UvEkLeU0N72BWm9BCRyB84,34376 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmallocproxy.def,sha256=1L6rH4pd51e46VaozFb7eWgtB0WF1rBKqAPI7q3m8SU,820 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbvars.csh,sha256=ubmsLxbGdkeKE-_ijFq1dkCt5ByjUkDuValpU171Omc,689 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbvars.sh,sha256=ijz13zO8LQI3fLS5StMczWTXGQRPAd1bkqmlgzEpBCc,689 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/version_string.ver,sha256=O9WBO5NHb1OdXx7xvIvVfn_Cfiilgzr6CG0w0t5Go9g,873 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/version_tbb_2020.3,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/x86_rtm_rw_mutex.d,sha256=4SnKDbviQ3BYQiBfBvSMQCUQgfWCC77BRg8kQC325xE,1823 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/x86_rtm_rw_mutex.o,sha256=a3T8gLfk6BfVkt_ra2E231-WzqK9EZTQvNtb2cdDIg8,82872 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/.gitattributes,sha256=tYmLU1iB21mHP_L1xgQhUnHt6vbr-ja0iby79uRGNgQ,790 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/.gitignore,sha256=F_Fs1iUsZ8_1XtCozBwoTWGSwEdixSvNKX9KQZt55BE,1098 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/CHANGES,sha256=SQnEb8BC0xEYVvUJU_nmEaD-og8ahnMarDN5U8b2-mM,115456 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/Doxyfile,sha256=bVo276OvPi8rIoEWdwp6qHvPObwwnPIEeDrffmZX67Q,55698 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/Makefile,sha256=Y4Y5OGE5BuDCktYLHj2IA3qy2tOH7_2eqvYyM4WN_6E,2570 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/README,sha256=H4W9JRbOfhs0s0aNjJeaMo5sRtAhGxNhGts8gQbDOkQ,353 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/README.md,sha256=z2xwqjTLuV9EdvbA1vJZQAu2YnD8q6cPxS5rkXGOIZg,1921 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/STAN_CHANGES,sha256=IxeUlNKrT3n72TjcuU3IIpbgrgwg5uk24gx--VNMEdI,289 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/AIX.gcc.inc,sha256=llwUQf2aJc1aFJqPiq_3v8pmq90kc-7DuFR7wZBtig4,2155 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/AIX.inc,sha256=yJ_2Zdo6PQvKup8iI9zJpEd806i44LTLAaacPqGdtAg,1700 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/BSD.clang.inc,sha256=W2DVI8kA7pTCVM99P12L_beLGdvkyTsEt_s3Xd-TrWU,2984 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/BSD.inc,sha256=YM5pQd9gKNCK4uckrFmpMRYmW696rE5Kisi0RRVaGcQ,1988 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.clang.inc,sha256=Jr4h8uTuccscGDnK5FTDPpZf6JK9nQ0wieDgnuRI5vk,645 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.gcc.inc,sha256=iMQe_wbMbfFi5631F2ihND7qTOYHHr8Pt4NKqRGSMr4,2757 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.inc,sha256=JIGbGGxLTg-oNbYFRSgFmnv4J4M9_DArsJ0OofdYVIs,625 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.rml,sha256=k5T2zFZHJMB19te9WiZK-bTXy_wiu-t-4DMv99Dzz64,6971 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbb,sha256=3mWCEtXkRBl9iyQvWQZ2qKwM-znFXlwOOjdO9w9NFb4,3614 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbbind,sha256=RVg7g1iSdMZK-sT_KHIIS2wRx_bYlNSC3FEimUqMrAo,2382 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbmalloc,sha256=Nshy8XQKOPmu8CLTcpu2VQa8vGwoEq5BB2PVlwUwY_w,11654 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbproxy,sha256=LheQosNcp1UKxfbWY5CZ-5QmLv8xYgJNjNyg_bLvT3M,3903 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.test,sha256=gP2II6huWoqegns3OknGqxs4__8MF1vPND68Hyx6LDk,13751 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/OpenBSD.clang.inc,sha256=f53sRIIzhBu0tPEuBiU46mYAwvRrcWxmnjaAy1QypuQ,631 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/OpenBSD.inc,sha256=JIGbGGxLTg-oNbYFRSgFmnv4J4M9_DArsJ0OofdYVIs,625 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.gcc.inc,sha256=VRPHl83gzGeQka-Y7hHRz4MIUB0dwveYlrgmhqoEt7o,2672 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.inc,sha256=8oNmomSKv2gYfDAo4wO0WgEZTbH5tqoz72sj1LMuU0w,2255 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.suncc.inc,sha256=Bw8zfhWTukXVPWabxRp8J8g0KSQoZAH1ChDZ-LR8ynI,3166 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/__pycache__/build.cpython-312.pyc,, +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.clang.inc,sha256=D8eUoAbdfAEz07wcPZF8ppjmVLELdZ9e9UkWeAk1YSE,4059 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.gcc.inc,sha256=31jcUh_pdoXdg8uSPwMpOtqOYi03KAAm6V3MtFHpFYQ,3508 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.icc.inc,sha256=yaInz1EOGGRRLEnQgWI_8B3sJlJpfveKzb6PeeDMFic,3529 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.inc,sha256=oiOFt1BPc-ryzlos8hhoQjCIrlwko69Wh4QcJqC87Y0,2052 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.linux.inc,sha256=VAi7FS_ulO582-eUjc0X4hpAal0Pd0yiI7r8wj1FF38,2153 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.linux.launcher.sh,sha256=EzTFG710_t9VibQYcCReHtQpbaYT4MzJeetlmTzgSLE,6480 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.macos.inc,sha256=7BBCxFGrzLZ1B0ktu3BrjyO2gp6PPbYAfIzBAsjObCQ,2252 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.windows.inc,sha256=sD-fTeQpv1MSjbjpnd4wA86DrpCT8JkLWpdNHc8hzdE,2402 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/big_iron.inc,sha256=4zPP775XFWJIU6UDlROmYK5s2EmFrFYKU3uzwk_kcxg,2600 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/build.py,sha256=5RJJspQu8wNlpR_fgmmTH4uQl_0zaJxZMEQVu8JXTPY,9412 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/codecov.txt,sha256=2TktLS4lhtHpvsnY8Wz4AxSAsfEwiSzXnqHujETXT8s,94 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/common.inc,sha256=ySceriX1p2kH73LOkLk2O6VGgSle6paTZOtqJQBpj34,5692 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/common_rules.inc,sha256=dPlUva17wbOPb2z5Ka3SlSOn1vVTor1eA5m9Fw7B5q0,5646 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/detect.js,sha256=LAfX8_HKs3gw1qi4ikQuAbbkaDbTKacJjM4sCuH85Pw,7823 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/generate_tbbvars.bat,sha256=C0BwAF4sCvbWtac-_6BLXqcm9HLxxjfvBywjTKUenBQ,2594 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/generate_tbbvars.sh,sha256=ebL8ujZmXKj5jhjT9waUZT4BSy16XQi8NIzrd2H3rmc,2084 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/index.html,sha256=sLhFD6ADgA4_LnwsEmElgrLTFlVgad6E5pI50kJQxFk,16024 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/ios.clang.inc,sha256=_yOSQGaSTYCmqM4BZkK55qhf693b0vhB_V5utMp5D04,633 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/ios.macos.inc,sha256=wlQ5zjedHorqrCK8Kmptmb8EcYWcSmTt8NT8_-65IPQ,1349 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.clang.inc,sha256=I43mk3Di5jg4ddk3KwrmNcR5HaATd6xGoFbmrWA7NgU,3280 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.gcc.inc,sha256=oy6FlaxtIX_u5ullWPMAJucxqQ03xKQipY7v0oryIpw,5055 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.icc.inc,sha256=BCbE0saQMhZcJ_ZUKkPpzrfZmrKSSyEJxY0aHaAe15k,3793 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.inc,sha256=BBwa5Yd6P4RMIqMUlv8N65exuTGtOKwtRYcER-DJWNw,4544 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.pathcc.inc,sha256=VVb2ztbGfYlvWIhEQNepM7wvrCUGsV_0mueaOS7BAQg,2663 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.xl.inc,sha256=dHEOTq7RuVkecJO9yu3pSdch11PI8Os6mXKXftM9EA8,3323 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.clang.inc,sha256=wxvibiCf4UWFEvn9GZnb4YAWBek6XKQDcjdXx-tPgW0,4091 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.gcc.inc,sha256=q1t_SX2okClVZ4EYLRHgpyyRfbBIdd5MDzeoKce-7Ko,3838 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.icc.inc,sha256=QXgmckmKQ_HBu3AWEj2OGWVnyp1-DDYvw-kGwn-9taM,3211 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.inc,sha256=QdXflf5Np4gl7GRgFFACVnWpYMxeN_Tr93fniR22Q9k,3064 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.icc.inc,sha256=26ipwzivdWW11W6WeLboLcrYT_SaGEMhMMcA_yuGtMM,2268 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.linux.inc,sha256=cttkwjo9j74Ic9e43HfR0MiVLFxb4zQQXXwQpG6MwyU,1308 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.linux.launcher.sh,sha256=-qMnCVbGDvAE-Uea_V4NmEkMrVXx4LiRTNCu7Q-on-o,6293 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.offload.inc,sha256=WUEtEHKMkYyP56lkk5AYYIO2w3Io9wwwjwdcZTe68Fw,4778 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/suncc.map.pause,sha256=eSiDifuMK6-jkSB-A9xrSt-fIISlDnr-EUN1OxEjfAs,19 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/test_launcher.bat,sha256=Fzg_JJwYtyuhFT2AVLTtSm2EyK5tVR6V1I71PeTBrjI,2250 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/test_launcher.sh,sha256=kNTYaP5fX0ar_bwOlokrQMptvn2G8UGcJnKwwHhL1MU,3697 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_aix.sh,sha256=zs7_BqX7ljB5u3Z5N2kvet0UNPK9TVYMA0bsTIOBt-0,1556 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_android.sh,sha256=1RJTKwKxXkwJA25MGca25cQX3Ggg8hCAgIbi_BObw1o,1489 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_linux.sh,sha256=zs7_BqX7ljB5u3Z5N2kvet0UNPK9TVYMA0bsTIOBt-0,1556 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_macos.sh,sha256=Kyyse2MguRQKMmazLsh2EjrVrg5xg5ZcBJxxIoqntoo,1300 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_sunos.sh,sha256=DtOgvMzMs3KPss9US5b-cCUFif00ot1u2KDyO8USYac,1161 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_windows.js,sha256=KZSGloet1hQOwFFz_ZyfMXWzsXM5enC9-aRxg-tkgvw,3279 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/index.html,sha256=Kqcmrm5fviHUA3EO9j6ayuoh1DcGArsnctOXNyfHCf8,880 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/makefile.sln,sha256=UN8BhOjCKzRhuxe52m61hh_PLa353if4KjjvOmkc_uo,5190 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbb.vcxproj,sha256=TkZVmTcqeCS0nZc3uaAh9UcJBvB1IKSCUYEGGo6CnAw,55165 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbbmalloc.vcxproj,sha256=04yzaBDIr8RkdF-3ot5ai-C2jZGRnBJqEowbJGIKth8,43556 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbbmalloc_proxy.vcxproj,sha256=UZ2d21evaDvjb3AVg7dlHxx2OqBei8IkiCwH6uber3Q,28308 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/version_string.ver,sha256=8W7eA7h3NwsXgS0IitmzmmzpFPZfrcYrw6LoH5Ad2LE,41 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.cl.inc,sha256=NqmlffbD7exCegaZm4AR5teYu-rZ736lbnKK1t8XY3A,5346 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.gcc.inc,sha256=Z0GadnftV9-iXBOfZ1PLNEF1h3Hba09HJRfGkVkxTnM,4352 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.icl.inc,sha256=cFYYWjKroZUdCBQf5sb4GrkQBB8hDShuogp1n257Y6A,6265 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.inc,sha256=ROnL2Z-u1HUd39UU6gglJ5m8kSqTHZhY6w8Q0l5EKbU,3764 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/README.rst,sha256=FLz-hrz3rpGEAMJQp_V14cJ4Wz83XBGHK95VliW7B4g,20718 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBBuild.cmake,sha256=4tdEpHQHpB0QyYjCTvkO6wBKBIObiqFdxOVmp2JoAcw,7820 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBGet.cmake,sha256=915jz8N0tmefsKRop13oZtGXVnbx_AGHSrttcj3Ue0A,11059 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBInstallConfig.cmake,sha256=eF2s9sgJW20O5QWB5iT8dCJ6ZAbRBjeMxBmGUpjOmlY,5191 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBMakeConfig.cmake,sha256=yMs0zOrQtN6PMqwjeR25pEdpvSuEoA7qomsVhTIFb6I,6756 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/tbb_config_generator.cmake,sha256=mAEXboIkpqBBmMsjs-c8fbPAbql-YEQ2VwQD-JhJ_9o,1492 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/tbb_config_installer.cmake,sha256=BYHzQpOLRduIoqR5RDZBNZfyu07odWpy5T51GybqEtI,1957 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfig.cmake.in,sha256=Tm8SUFBx1tMDcrO-8kg2W_UcE2lplkHgSPnuXe0Y774,4293 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfigInternal.cmake.in,sha256=I4Kaxv7Glp39lkudY5XBUGeL1I2XgbOw8RWxqRNspi4,4128 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfigVersion.cmake.in,sha256=fHqqKBlyPxlfCrHX3uf108WHv10J6QnYiDXHW8tO7lE,912 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/doc/Release_Notes.txt,sha256=G4Mp9yvkyNuDuruZdJMi8Aiiy4bR7V5Lt5PRUJgP-BI,4671 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/doc/copyright_brand_disclaimer_doxygen.txt,sha256=wiNXX5aUIL7w6Z7eNZLTiuijKHSHLQjee6iqCfHANbM,347 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/index.html,sha256=gtQkrUQ1Ur-vfBuxJYskMKxl7Vmpop8ignhOY0zMm9M,713 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/serial/tbb/parallel_for.h,sha256=-L9rKTjbFW7E_CNvXkPu6CNMdCEmsm0ow_6Tt6ox1ag,9861 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/serial/tbb/tbb_annotate.h,sha256=uq0dk-VcAis4k3_YcQDeg0VPSlO5kQDIDCoV8bBiN28,1062 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/aggregator.h,sha256=lPv-nZM0imvAbwYVUqTqP3GsfnC7VqT_XGJUVe34whU,8329 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/aligned_space.h,sha256=LP3f3MRJk5R0U6RK41CWwxq51_MkzVHEExr0JKaqTyc,2171 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/atomic.h,sha256=_7Ch83R36sAuRzzggxXHd0NYbClH6J4s7Q_OL0-SpUQ,23219 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range.h,sha256=LeeOzZ0oZSFiRrCDB4kg7xstGn1aNwnyIyYW5E4LdLA,6609 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range2d.h,sha256=OJb9Wu9lsMOi634hexEyQ_OIW5RdixFrMOsoN6hxCjI,3237 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range3d.h,sha256=EGpduFuoWYhENDAzHDdgqTQzpucwOtTYERLX8sXdLPg,4317 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_rangeNd.h,sha256=LP7ujD7Si7r6DaqCAaBBb51Na7LkXERczbDx3dnrWDQ,5735 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/cache_aligned_allocator.h,sha256=JasEHh-cHOYMoQYy5kISIDGvA4pC24oLku5Q6gKefOQ,7714 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/combinable.h,sha256=9twPiSzDFMpuQDTWCluU9hibSoz26b5s2M923FD74t0,2598 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/condition_variable,sha256=QX9l3HFvs1Xn9QUZ8OMExF59VAJwDcg9YHppbvJlin8,16485 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/ppl.h,sha256=AMCUkL45bGG-HzqSS1tfMgbHcYq44uKbrBu5VSaZHgw,2302 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/thread,sha256=LN98s5uV21TxNntYDf6zRutxGyZJT0S0OuXpQw8KdXg,2179 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/tuple,sha256=SHP64OaScfnbWyJsON7YMMqCF3JholAGa3jrlqWzuxY,18714 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_hash_map.h,sha256=slY9CZ5-km3endhWP1t9S_M4o_GgMowHX9Zo2Q9khw8,71603 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_lru_cache.h,sha256=ZTwCr2k573hA-BjOhk1_5tlc8pP2wnVpSveao9R8eF0,12948 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_map.h,sha256=lMxyrjcxVkahgNicWGii4UMNmqf8W_NjcwEjDbG6u3s,14461 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_priority_queue.h,sha256=s20HeQTijEYubxwGI8XQXvbeNgrHOAMIt2szyWXJAWo,21987 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_queue.h,sha256=npNheXcDNHwh2uvAgDIF2Zfrac3v5MUNbyuPcibGqdo,16885 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_set.h,sha256=pX7Zsd29pMd-KycGdA2OTCPrNcnxfXEUg018jNDM7RA,11391 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_unordered_map.h,sha256=0tO5ujRyA2NyJo4ylfHBWS9QUe-iiav86XAaWSLAliA,19594 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_unordered_set.h,sha256=GoittPFxsy8eGbZCY7ISm19qUsrBL5OMTxA46TVgjgc,18079 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_vector.h,sha256=QASGfWzlP4WDHiALzRrTejBBWw-nvTdI4_rjwBBJSFg,60518 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/critical_section.h,sha256=Y7WUhwKZXO7WWQYYDaWM9-RIURqeWpwHv392KxXDVPo,4479 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/enumerable_thread_specific.h,sha256=_u0_5jtijGxFRd5q0_tHV6dn-aRs-LVRHfjZAfwwgmE,49420 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph.h,sha256=s0WJA7PWH_TpfnireSyCU7-ayhg4F3SHdoqNTptWoWw,184201 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph_abstractions.h,sha256=v3O8E4a7zEGlxOK_SLIDr4UXDY1M93G2s7cQAeiDZe4,1525 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph_opencl_node.h,sha256=TA0uuA1LGDdSOxUOiUoNFsf835gbQhmbNcEzPYuY6RQ,58883 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/global_control.h,sha256=247EAj6-rlEJQ7_OtceSc63F0e0TdDnv9llbxu4RsaY,2495 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/index.html,sha256=_8Ja0f-08oJShHfs5OGO6fQUvCwMyYxDmdQaQBnKRIc,901 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/info.h,sha256=YkDDd08NHvx2gL94Y5rWBslb0yKOCJ9aYK_4cdGFJLw,1553 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_aggregator_impl.h,sha256=HIEMKGHSdTcLekxpCDjiXd6Xx-MsLhG1rx-2GVS5j8Y,7779 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_allocator_traits.h,sha256=BqCYXDbbXYlSPX6Z8Opns3s2M6aP4sp2NRx9bUuJLyw,5951 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_queue_impl.h,sha256=fuZcLB5YvmS9Wpmg0r2LU6kIWK-4v0wDwc161nq1_nI,37403 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_skip_list_impl.h,sha256=Vhsh1eTgjHDTxyy9i1xSYhp4Pw-70us3e9yEMode-IY,37684 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_unordered_impl.h,sha256=zFeaVlKLSNINERJTgBVrThWLuCjaBGTOovmKD0SifSg,62700 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h,sha256=WKtFwFGyl0xjE59WMJGRHEPdhwJudg5E4AScncpJ8Wc,3174 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_async_msg_impl.h,sha256=XdFdokZOxlY93CTnnu1sq72781cLjYQ-DmZXbV3_ykU,4690 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_body_impl.h,sha256=J_MwX0jfhr3ojhvMJ746NNrdKktfBOzT0QKrngFriuo,17185 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_cache_impl.h,sha256=7KuV4WAvAzl5q8lPnu2B1M3Re8AnbEO7N0jJmPnQ610,17994 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_impl.h,sha256=uclNtfh02Daa-1XC9vmYgroR7cl5tcPsot1hIfL62bI,18482 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_indexer_impl.h,sha256=h_LV7yDD2vQowOoeua3B4K5eHxcraWyeoh1cLxbGFXo,22282 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_item_buffer_impl.h,sha256=-Tk1_7na4MxqDeqdkwDmgHajT5xGPfDiAgo0by0PuNY,11223 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_join_impl.h,sha256=1x69fqvBKMB1RWrHjcl8bO3NEWj_JiWRKepADzoLgm0,97677 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_node_impl.h,sha256=0jETXBYCN7G3jRgELTIOejaw_Zxleot083gBR21HG58,39290 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_node_set_impl.h,sha256=E1I3QLYtU22VY31kgDAyWLZnY4lyBKr61qSYp7fXpA0,10476 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_nodes_deduction.h,sha256=y31_8_PmJCBKjOnYtcgb9m6k_mkfA41IMH9MMbHIpEA,10767 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_streaming_node.h,sha256=gZTs_3HmdsCWibMTgzwMKz3N43PO0LDFflz-5-q9160,31272 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_tagged_buffer_impl.h,sha256=y2Z1R4rtftcpoI2Gsv7ejb59BgZoxtjuFQstBEAXhIs,9978 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_trace_impl.h,sha256=6e8ZJrcc-pH8UkpTkToyTepfnJVlFMqNPhWYoav13ZA,16122 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_types_impl.h,sha256=Hd_AYT_lmc908MzT6JhRraiTHBw254dEl9eNX1g66oE,34056 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_mutex_padding.h,sha256=b8JXK1LvkY9ULWjcGYyP-cdl1XMKWrBJCpzxy8Jzoe0,3829 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_node_handle_impl.h,sha256=ldje-wT2lzR8G-y-EDqIqTxWCHRrW8P8zvlPkiQ3iOI,5237 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_range_iterator.h,sha256=Aj549-4LdwlYSZDfQ69TU4EyHQl3VfJ8ewb0-qIgypA,2292 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_hash_compare_impl.h,sha256=mXLo1KASbfhXyWRaEyN-W-RwsIZwPxN1Cb9hpqWD-UU,3389 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_strings.h,sha256=dcSzkKTRDqfOa5N7I2ipRU9Ed7nCTO0NAI2RWSiLn5Y,4139 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_trace_impl.h,sha256=vzy99MZWCSivNTDV09wl1VdWzPQzddoWRbc-AKtF0XM,2144 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_windef.h,sha256=ckzEosfsrOe59VKcc_2NCUp7rUiT5gYw8Fz5WTejF6Q,2377 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_template_helpers.h,sha256=2yNT5Odh6wLQsn2TNgz4TPaJ2ocVJanB2uSuUWnNCNk,12576 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h,sha256=C6-Zjkjkw1fVaJ1j5FJQK8YX0jmx8cfH8E61gejztr4,869 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h,sha256=TjkZV0u-NCfIG4CdJuu-7eXI1-WYy9z3XV1etYQMtMw,1053 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h,sha256=r8Ze6UC6j7InYwOh6XVROQNdtE0p64IM1JaQaTEjMS4,4474 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h,sha256=7V7sXC2UstJI8Js4pxyINO83ldmuSrO1qQTl2mYUZvg,8328 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/iterators.h,sha256=ITsigt74NCPAqCzOpmbuHVefHl1Zf_r6xb2We9vdyzk,12453 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_arm.h,sha256=Ke1Vikc42CYzYZjweZR-aZROx5YCESD6XAwSAYvHWLI,6876 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_generic.h,sha256=C5OO8mwhvosadKIVk5jPYeXgjazpLcWb80HeRiyjXiA,9860 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_ia32_common.h,sha256=0eoKFv39XDOsen-SaZt1cLIKJfC7Z51FVaGCexcOSuE,3789 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_itsx.h,sha256=Y7CJtd2hmrF72HBHPzjC6GTX6RfdH8IktZYs0FKBYMM,4041 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/ibm_aix51.h,sha256=kQclvrA7HXPax1jDD0SIATcHT1dl4xR2CDKET6kKJJM,2769 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/icc_generic.h,sha256=T8gM7xddlX1HLli1uavVeA91faxn9V2g6tV5SqNfeuo,10373 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_common.h,sha256=OyYxc4d8EDQA_yi0bzD-NGt5_Zpm-BRxPxotw8MTcFg,2975 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_ia32.h,sha256=gZ7MOTpiRGbLVmbjG9YEbwknuhjqqfg7pC1PCCxDqzY,9761 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_ia64.h,sha256=aXrqEv_50RTqEIc_4baiU0s8cGrewCvKQapF0JZDY80,9590 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_intel64.h,sha256=qF2RaYz0ryxw_Pyl_QT64mr1SjsC4rT5U2oPpOUbZzk,5010 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/mac_ppc.h,sha256=B3V9WFcKB-pSYMUOOWlXz5EZV--DeKN73YcA7CaQFk4,17198 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/macos_common.h,sha256=VvPKMkGKczR2DTqn_LnhNz9xH7WTtQ4ePOLPoOOiFIA,4657 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/mic_common.h,sha256=Jo_JMXmaqkxJNCCg-oPmkWi8fgHbK0_VWwomQMoJbz0,1898 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/msvc_armv7.h,sha256=enX2Q2JZlkRv0YewMOimJwtdRXanweRbUI0ZneUfOl4,6023 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/msvc_ia32_common.h,sha256=3L3ORjxRngrZAf-1jgU7UpnY0GQYZJYNXqacpbyMFyE,10536 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/sunos_sparc.h,sha256=U-JWSsUEC7XczVbbl6TSYYg8Z_zqCFCYo_-4gG1QLV4,8677 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_api.h,sha256=KNF_OYz58Ebi5nkqqVXUyMimJUbGryXPeWQOipReAE8,2593 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_ia32.h,sha256=1o4dJ-AVYDhIOj6gla5Y19J2yEIZfOBuvWOvJad4yQo,3540 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_intel64.h,sha256=QwgqG34B8JDxM5qNhi9I9UQO776BUyPRA36A2t3kZzE,3164 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/memory_pool.h,sha256=sDqChdhk9EATvZHGLYYrGOu6a6lRn3GKed5lhSxTx7U,10576 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/mutex.h,sha256=IEm89En0EumNDxy1rwv_Owg1qqUFrJ_X8JCP_Jox_a0,6850 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/null_mutex.h,sha256=O3FCn8sZgpDQ0h6wo0pPqjgOxBdeT9EGx0r2Tm73ktY,1440 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/null_rw_mutex.h,sha256=ug7nmxlFl1yITtClKhMp6QrbXE9AXtAXHCsZ6DXLSgE,1640 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_do.h,sha256=RK4T5RUvjhNNBNcnHfEEztHN5CO2FAR4kb1hF4KSV-A,20089 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_for.h,sha256=xQTjUfykeS82QNhqtIrFrIW_K5JkMVSwDyT1IhEULwg,21162 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_for_each.h,sha256=gB0gAFmMM5jk3oTMDCQgqYZc9_Px_2FPXT5VT_nPn1I,5062 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_invoke.h,sha256=wS4Jj6z9KQN04SepMG-hzIUdgFFqg_j31Netm-sK9Lc,18211 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_reduce.h,sha256=bxIH5LwjFOPBwtuddGBQD9NGz9_pf_QuaI3_AYIZg6A,33041 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_scan.h,sha256=JolXmtEdDl1lLmmAFamJU4FQsQndAvX58Z5UpOmSYfE,16625 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_sort.h,sha256=oSTSjqpTS_n63M6TMlyrWqtDIfUWcE03rbF93cvNxXY,9341 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_while.h,sha256=cEl4TMRnV6FB7XKnQGmPyEDW2eA3LHRw1YXvpinTjnA,6195 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/partitioner.h,sha256=yfUebS8bOw05RbMYzOhRP99c1dzgDxlnGGGrTHOkero,28751 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/pipeline.h,sha256=-0aKBqysfVLwDs6lXm2iP4rx9_7eRzz4PjOieGNlpxM,24828 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/queuing_mutex.h,sha256=ub4q_KxbP_1_vx0DoK2ZAz1v37FBWTInm8Dl6WzFaZ0,3355 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/queuing_rw_mutex.h,sha256=oHFDX6EVESs4DPZIziSpfekF6xn1Zj-3ZgFEvMruHiY,4842 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/reader_writer_lock.h,sha256=Ui3uY76AqtpOjZJeRjYAXZAtdQSFA2zGaFB3uGzuTic,9069 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/recursive_mutex.h,sha256=JUytAPNoKPpVNwCViYCMpGAP74cBjEbvr2Hq4oJuFzc,7408 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/runtime_loader.h,sha256=J4XbCs0N--tSXN4-sVP4nmjdcKvKCM5okLs2gbKE0DI,6796 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/scalable_allocator.h,sha256=coSqEgAfLmn28oXAQhaSaQwo15sDr-lGSA8eaxG1OnM,12970 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/spin_mutex.h,sha256=YArc5svcdiXIheqRXFOTHzRqtHXOTt1v06dAKKLjgcw,6941 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/spin_rw_mutex.h,sha256=Ciw3WKFqH_R5LZpI9jfUODE_aZItYlRFlqCMDv4gsAQ,8929 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task.h,sha256=lGA8uZrX8xTTqeOxj-NOvwCJnOa0yaof-QqmTTg5ycI,47287 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_arena.h,sha256=EAoww9U9jWki9VU_cIOH8aWF8YyYNyHbqGjjRnjGPJ4,18443 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_group.h,sha256=MUFRpswBCVBR3m0NiiQj1e7lN7RWY-orKx5lN7Tk09w,11109 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_scheduler_init.h,sha256=Gm90ZKI_Kkm9B0wtchA3NeBN1G09AAUTOcd90cLOkMI,7855 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_scheduler_observer.h,sha256=PyNave33C2hMboIILsgxyR_ogYcWpLStPdbg92XDSHQ,6603 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb.h,sha256=-ix-4Svntc6HNE2vvNYj9-C3aDXQIA62yCPBCCnsTrA,3068 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_allocator.h,sha256=I2kf5BAP4XwO8jyRPlDKLxPr_E3iBwcTk814IC-CBrg,7592 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_config.h,sha256=sOVIsZQWNoFCkgG-b7sC5Lby92OhbKb6XjNdI9sMVnE,47893 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_disable_exceptions.h,sha256=RIvSemO6_fBKbWD_5ryeVaqLMGzm_XnIhO-EhASeCXk,1126 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_exception.h,sha256=RxnUySIaG2m-i2luzJWwLPuJFBVXjVmLBVfy2SaGG7U,13485 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_machine.h,sha256=aw7z2X-RYrGind2gswIi_2hlyX-S-4AkvTM5RvQ1dZI,40860 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_profiling.h,sha256=zE0i1hvCg-kAId20gOEnQmMY8ZZRffcn9plN1SbuT0E,16316 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_stddef.h,sha256=DsWWNZUGbFFgRJIiWwDA2QWHSU3_3WSReLgNXZPv6VU,20550 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_thread.h,sha256=r1RVCx-xodRNEsEBahzvyWj1D2W_V0Pz1Jg5yfHZd1E,13344 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbbmalloc_proxy.h,sha256=upOf5SaW_idDVw0-sSEPn_D7GBZ-KiA-G9Fy0DBRmAE,1900 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tick_count.h,sha256=fCyI7o-5cOiqMqrq-ANFFp-MQB5CbYGED3Hn936SPvI,4496 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/index.html,sha256=Nj0KgxIYluvSkBDBOli7jPPaZ_aQ9Obhh-cIfAjAyKA,1811 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/jni/Android.mk,sha256=W4p9b9a96xAwpSyymM-k4voGY1tOT5lI7oirt0lx1s4,2375 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/jni/Application.mk,sha256=lG1mm5_oCc51ZpySQmS37jdMXk_JA4t5Agc9WileZyo,1655 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/Makefile,sha256=8n0T2H-z_kB2D0YJECqwEI0-X4zkgFf3EpiJ84hSPrY,1413 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/TBB.py,sha256=_DgAYYOzHnby5xpSWsYQsWmqPygVrsYAqw5NkYY-yts,758 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/__pycache__/TBB.cpython-312.pyc,, +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/__pycache__/setup.cpython-312.pyc,, +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/index.html,sha256=kzFuVU7l8CwPTGwgWhi0a7BDRGRFuIKA-Spmih9rgyk,3875 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/Makefile,sha256=-TYD-vvM2umSKbcLTC-nsk8yYME_om3fuEFPSSjl9Pw,5629 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_server.cpp,sha256=nMyybn5F16pA3AQluDG6WNd2dIrdu-eOIbR4IaXrnUE,37756 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_utils.cpp,sha256=LvVnCcPnHoOSPwRW0JDU6Tl0vITwbdgUAA4AVH864zE,3433 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_utils.h,sha256=1cWwV8G_5xPgxdwmo-7vHH6ipDC5R0twXNt4KAr-KtA,875 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/setup.py,sha256=ustO7xZCQnSnB2GVGeSeHsNty81Yyn7j9JUJgRasmgk,5107 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__init__.py,sha256=eOJ8YIOEESu-4RABj2xlsTebqLiaOqPXXYP0cfPYqyo,12835 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__main__.py,sha256=66yzDNhpvBDb34svdEDetNESgU48KWu3d4GkX7Sqlgo,671 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__pycache__/__init__.cpython-312.pyc,, +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__pycache__/__main__.cpython-312.pyc,, +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__pycache__/pool.cpython-312.pyc,, +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__pycache__/test.cpython-312.pyc,, +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/api.i,sha256=7PgntNskUhBpdcpajMuMue5NyHLkZ7RBf3m4TEYoHvU,5501 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/pool.py,sha256=rBQGrpGbbCUUop04auf6qnVGQHqFQ_FHJnHhZrOPQ4Q,25155 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/test.py,sha256=ezEsIBMmGciwbOr8yaaV8jIXUHIr6jGR7JxNFg9HZT0,6482 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/Makefile,sha256=n6UaRSomQ0BzrYyr-TFS3CaR_2n6Pa_iDGo3eVaVa3o,11755 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/index.html,sha256=EW9sCx6rI6ioXKANI-jbZo4zqx0lSeLyv1ECSZJtcUo,4119 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_queue_v2.cpp,sha256=0WqiPC0XoEwwBWkxj_pZhl9LAlt9AOlIyx5DzhfPXAs,12263 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_queue_v2.h,sha256=iz3N7ZMfsHKthfPdGUezm7ISbe1Rw6NzbrwJRZ4IzKM,10609 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_vector_v2.cpp,sha256=LKYZ8TtumoZ1-JPZrIbz-lETqVh5kY0svvVD-T2aoYE,10002 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_vector_v2.h,sha256=UaaoT7Wuqsdy6ViW6w3fINtWMJBX8SNZKijE5D8Gnyw,19105 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/spin_rw_mutex_v2.cpp,sha256=USSY_n2_D8owcnXLz_bIN7dIBAUCDEsYY_ZjadluIZI,6401 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/spin_rw_mutex_v2.h,sha256=0rJtr0Z3UZ9q-o-ZJx8a1-4hK5SlaF-ltk-tvTdirwU,6134 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/task_v2.cpp,sha256=TKnBPTdO7h2LacmERw2n-YCDQGXD_n5m5DggXzexCnY,1158 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_concurrent_queue_v2.cpp,sha256=frrsRHuYY6aqjcIuDV0VmMN4x4q-LUQbAH_vv_LAhjk,11326 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_concurrent_vector_v2.cpp,sha256=Ozq5pBChGDcjGqpdXBJVowApA3Xb_Y5f3_lLtufe4Ec,19083 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_mutex_v2.cpp,sha256=HeIkbysDinu2sqZPg-Kk6Qt6h8S2ZEvplJ12yex4hp0,8606 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_task_scheduler_observer_v3.cpp,sha256=MEANvh5U_Ci5-nfp-tbpTr8YmGkNJqzbOY7ra7QJ0c4,3220 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/coarse_grained_raii_lru_cache.h,sha256=Wu1CZwtsS-l5y2951b0BBhQ7gZDMqL7ZOgattzOaOWA,6472 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/cpq_pdes.cpp,sha256=v-91YRO0KVNp3WBhuZ6_tsFmsq6ys67r39B87oepcVc,6743 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/fibonacci_impl_tbb.cpp,sha256=9xPbOje2cf3Vu9RLVI8nE1CcpJWQ7dvmGAf220pOLuA,1946 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/harness_perf.h,sha256=zqPCGETBvVauMHqqd_lKDU8Oj3-4mOwnvje5o4vL1kU,1245 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf.cpp,sha256=r5bY83cMBqNKd2zQo60f6EZaH3y4xhxq3T3FYhuX8sI,34077 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf.h,sha256=JHUK3vLdkSqZzQmA2oz51CCP06kVUwp5HlZUw6ytI7s,8979 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf_sched.cpp,sha256=ymcftuYq-9n5cYBs-FgfH5QtHMal5j3jQRlwPRmB5wM,14676 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/run_statistics.sh,sha256=_0QncjMsSU6j_RSzEE45mgTa1ElDRGSz6oas0Jy4pEc,1096 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics.cpp,sha256=kNBrh8zb0tM9KcSOCtgC8JezL3g-q8BIVPy4XDOZQjM,20611 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics.h,sha256=WwqLRtqCjhKGruTZyoZf5eL-oCWe3VlbCKA7xmDOzxQ,7210 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics_xml.h,sha256=2slwzAB9QNaEEMUCdhrI6dbRo9wziBsL9uPuVXwJExk,7351 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_async_return.cpp,sha256=NH3OnXDzF7gKipBJmMh4NoOPvQ0aWTdIu5Z34H609O8,8761 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_cpq_throughput_test.cpp,sha256=CCOWLHAvrKlAy52gI2S7dPOACHO5nqXJvV5GvkwRFkA,9533 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_fibonacci_cutoff.cpp,sha256=JKC3FpXDwHCk5EC83LVZ539Y1-hxpsOBGh91X0hYufw,3732 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_framework.h,sha256=S5FqsccH8WacfX0RQtE6Yqm6p3Nvcit9o5UXJIruBiQ,11318 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map.cpp,sha256=XINic3r24ou2bGcbWYiPy2qfcqmF_nz7JAhxNuSldv0,8382 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map_fill.cpp,sha256=cJR2JDPkgzdE-zzMmsfQ87ilAvbhhY6DwtKE49SDq2Q,5958 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map_fill.html,sha256=1lJQMrOZIR1fmHLRHz1tToA2x0Res8uzh9-lfmUX11Q,4511 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_locked_work.cpp,sha256=7haQ2rQ5m1ZjCn8yU1oKhPbvuR1_PpKEsr6IsYoXYNE,5435 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_lru_cache_throughput.cpp,sha256=J7UrxZ8AKT9aY4I5vEAZ3eF9FINziaoQ4AkrAitp3KM,9068 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_parallel_for_each.cpp,sha256=S1FHFrTo8SSNXzcWRM-Fxwe7U6drLUt10TXhparHJg4,2114 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_resumable_tasks.cpp,sha256=3FXjAnn7po5GeIbNQ-0g3C0RZA0ccsFccg3kDT1CfsI,12278 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_sandbox.h,sha256=eovMJX6bg-SaK1SJvs9oViOYru5pmlMvGpJpEK_POuM,3730 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_split_node.cpp,sha256=JnbJGwB2wyXzjdTF11gd5D0_p9OP1m79jorrz8bana8,3750 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_vector.cpp,sha256=2WDH_JFWbgh-N9JZ8S0ut4_QQz4CaIYc_se8vu73sow,11354 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/index.html,sha256=R-LD8UW-acA4VnNba8bBmqbU3A5kZo3xOgZ6ONmeqYQ,1426 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/library_assert.h,sha256=JilXNb5yzrtucKcYVza9DqjUMDfCYgvPrAg-_z7xXR8,933 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/omp_dynamic_link.cpp,sha256=2nikZC1N2gRsSoaqJV-NpdrNiI-GcuFoC0meuqoYiY0,743 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/omp_dynamic_link.h,sha256=rR-HtH5M59V04aiMdwf339usNkAEhNA8aQ1fF3ZnLM0,903 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_factory.h,sha256=6XhEATet7zHkKXV0c4lbOjmAuY7nfybnsdYzLpMYrS8,3388 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_omp.cpp,sha256=wZR-o5lWr79q3RMBRuwxHxyfkPsT4NfNe5O_-sQmU9I,1348 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_tbb.cpp,sha256=70z3wzAH0SOgnX_ip3mzkFJQwUKt5tBmCiYIKPCnmfY,1453 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/index.html,sha256=Ay_LlRuR-3tjBEifr33Ffq7P6JCDbMP7kQQ-jGra1J4,745 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_base.h,sha256=5Qml5LymuYgeJf8Y2l8JvYdWjXzKHryJTIsMucdXVSM,6670 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_omp.h,sha256=rfMCkDmdi8eIG05e3qrEGgjFNXKPm28RfG0dwEJAmfE,4762 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_tbb.h,sha256=Ep_fp2zSUhxJeDncE4yx7ZVpxeBB2zTD5K18Y6YSegg,3386 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/index.html,sha256=1A5h1H3vVUGjZbTySFbiCkIl19W1tHeMEUKru5HdZ9s,887 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/omp_nested.cpp,sha256=uPsfEUTuoycdMSqAzjfd3mkuFDtk8d8cVZJR2NG173M,3725 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/omp_simple.cpp,sha256=RRjWcs0d9uBIF_v9BrY5rsEvyF_51S1NIxJskawuloo,4305 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/tbb_multi_omp.cpp,sha256=Nwk964YQSRaHciwp5b1Z9CTNhPzZC1H7iFu2VDcr28s,4899 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/tbb_simple.cpp,sha256=MPCGZN3-ZNohT52Pqceu1GccHtc5bLeyE0bmcgWAu20,5001 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/thread_level.h,sha256=GY80PDxe2DswGX-2w98oWQ8AIHGQbeHgM-Lwzq5euZ4,3886 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/index.html,sha256=O8PJuenwtvATcBySneNj1Jsjq24Nv8yyQM1jX6062mI,449 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/irml.rc,sha256=6uT7nS9TZEkKT6wALCGJYXOoD13tKvN8agfPZ9lh5JI,3329 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/job_automaton.h,sha256=jxkl-lI95DovCZ_OlabTu4qGAMSNGQ2K_iN3vWqSz4Q,4326 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/lin-rml-export.def,sha256=Hi4v8vrCwbV64cH4R9tNgL5McirbnAg88rhfgWo1CCs,787 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/rml_server.cpp,sha256=-Xi9XBebLU2_MNyJCKxKbbLSU14uFtdxQB7Bf8bImHI,127724 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/thread_monitor.h,sha256=IsTcy-dPHVvsJYsurUyNr5Q_ZVzBLUFS-W8ZWqVTtuM,9042 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/wait_counter.h,sha256=SH-FfZhNuSDTSGshfERBLP4YpRdbLsN-yRCHyplPi5w,1914 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/win32-rml-export.def,sha256=ybkqqF88nTX8aYCcGBPQts3JByya7mHcwCfwBdOt_C4,746 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/win64-rml-export.def,sha256=ybkqqF88nTX8aYCcGBPQts3JByya7mHcwCfwBdOt_C4,746 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/rml_omp_stub.cpp,sha256=k1q8rlJZu5a2sQTjZLzz_fi42mniMfQqjLtGt4sO_T0,2476 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_job_automaton.cpp,sha256=K6IwA_Oj2aV4h5ddt0YtNcXjDj7iMY8a7qqk7MSw28A,4074 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_mixed.cpp,sha256=kaz1Yyzt0jShnAG0-6I3InAL8vImw3sMaDUnJRex3Zk,9205 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_omp.cpp,sha256=xKfWCrtR6XB8na2-kS02tQM_ZZI4XKffnUnvfioVx6M,7311 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_omp_c_linkage.c,sha256=fOLNCkzcMpZNDr1JaZPDhVve6BNF5QWxMkAR40usU5k,686 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_tbb.cpp,sha256=tL3oeR5s5t8YMXsO6uKBJ6lxj_pS3rk88pB78Zofyl0,7384 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_server.h,sha256=VcuFXuyO2WayPE7VPy2aaXc6yiHhS45WqiRPDE7Yv40,14980 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_thread_monitor.cpp,sha256=ANu559opdeuMmDP3dIICnbWmhxZZBBjm8zg0pxSBUBA,3751 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/arena.cpp,sha256=5i0Rktjzpg1gAHJlXo6uyWh9bCk60Alc_5kgMLHIfrk,55830 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/arena.h,sha256=ozocloVKlMIHIArzN_o7OZTuHTXdlKiHT2snOxj8pO0,23756 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/cache_aligned_allocator.cpp,sha256=rrg2ixXbd5_7RcpAjBwaZK6tKRzgW0VDpjPGwsBF6v8,8902 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/cilk-tbb-interop.h,sha256=0rf3ujrj3YQJiueRcRPRhP9l-ASR-E-ih_bDuEHl6RQ,4306 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/co_context.h,sha256=5G-pcinsVfXCfCB0SiqvR63JVo_mY99U3aI-euxMWi4,6660 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_hash_map.cpp,sha256=06TBi1e69kGpW8-xYtLAnzoTtTfopzHuh6Rzt7F5RXI,1933 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_monitor.cpp,sha256=VDqPuxHL27H1nlBXnNMIFQK7d8OkM9Cs_Y76S1H32bE,3991 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_monitor.h,sha256=xsldd-HD406libupxF1f-OH0inQFAMb8BWyz1goqDgo,8154 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_queue.cpp,sha256=qdZ_qZjfK0OW2FIfAIYG8fjm9TvKvzj8LbGR6D4noaU,24639 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_vector.cpp,sha256=mh4gK5yhbqrRMB1lJDjB0R-66uaFXPPy3wAKA5dAqB4,28992 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/condition_variable.cpp,sha256=MnzSG0bbi2f8FAYmKO6ZWLvTJngI4k7-zU13CRK6-DU,7704 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/critical_section.cpp,sha256=IQ75a-PzIXuEtDW6Du0s9N-XwhGPI1_XNrgzg677PnI,879 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/custom_scheduler.h,sha256=Jbq_8Ry49IPO3lSlKIHZodBIuTiCjOM0WsvSEeeuwVA,40322 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/dynamic_link.cpp,sha256=RFQenf9ZOUYVdl-aguVe1e6nWM0c4T2vbiE6NkX-4uE,23016 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/dynamic_link.h,sha256=Ct5tM-9FcV7boFkYydoyAHccUVYsXTPkw7eqUv7AugQ,4463 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/governor.cpp,sha256=QZugaRkCDQahlSM8dhxreTgP_S9Ec4ylRyymnoOd-q4,20938 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/governor.h,sha256=2Qj7PkctSxxAZ1gnc9Fpdjftvf_vRa90iQA_KH7m6Kc,6151 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/atomic_support.asm,sha256=45YXBb5m6GwOJS414v4OJmn7wtiZ-sEznxoro5hPcjc,3599 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/itsx.asm,sha256=j_vsYrb_i9nzSAbsofuCHXfa-LMkhd7OcbF_blzrdAk,1877 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/lock_byte.asm,sha256=HZLbtS3OLos0qHqhtYkRgBMSs2Ll7gq2v4O3Rts6xkY,973 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/atomic_support.s,sha256=bo0XdCdRl-9bbCzfOkitc9E7bOKQ0CtHc4KEVahhMDA,15124 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/ia64_misc.s,sha256=lgclORHLBj9MlYe1cBUatPewnHnNS6gUPo6sUgRurFs,2687 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/lock_byte.s,sha256=ndU1ASoAT2LqgtZP8LMDrtZja-ohW5FL7SBtO-Hw5T0,1270 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/log2.s,sha256=wuK9c_cQydSRFs7glqY7-zBVneBVCAX4bH2opJmaJTw,1304 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/pause.s,sha256=kt-NOvczHLdqwvQSAK-v1u7zlLgkk2EI2I286uol1hw,940 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ibm_aix51/atomic_support.c,sha256=v4ssXqGIOlaSran7HCLzklzMfsohqEOl2QAKE37AyKo,1670 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/index.html,sha256=qBE5FDtrGMolk7yTF-KVs9juAQpqTXDrsIIAaaMG27o,955 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/atomic_support.asm,sha256=IVGb_u1u9wIONpAWRg2bnRHpjnD2eIFfW4rvEChQKAw,1472 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/intel64_misc.asm,sha256=Mk7faZtZldZvcSNrCqW3b7usWvszI7zFyp4ERHLB7SA,817 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/itsx.asm,sha256=yo9-m9KNrFxKAFRMi-4S7xqQcINCYOEvIZUQMalLxHA,1829 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intrusive_list.h,sha256=FFbzgX6Me0Fc8e83PKMXVnZ75cOWymxhO-RD-B1XCRk,8756 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/itt_notify.cpp,sha256=pOadrTQWRDvMNiGX-mJrpU5yG8dgfcuJjuNbhdalGe8,2985 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/itt_notify.h,sha256=O2M97EAC_L3E_nSpUSHWSvx2WrPQMWueg43c-JOqIno,4471 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbb-export.def,sha256=JYoeFO_QLIhH2Y8r8UQs-Nk2Losun1BKuzPj6EPn624,1048 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbb-export.lst,sha256=fyxVO4fWlZWNkvR5iQ8KzWsrGvbtJEZjl9FpBX5DjGw,22137 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbbbind-export.def,sha256=9uCQzDVGSnj7DXbOyFGRGvOCsiMwtWYDA5tr4ahs8ds,739 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbb-export.def,sha256=ycgSLt7eNjzZV8PTBKTTaE3scKbRGIM7DO0Xhexsu3w,907 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbb-export.lst,sha256=LwtYcqI5gxbuHd724TUCIqvu0gvTvFwy4BQSitu9HpA,21266 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbbbind-export.def,sha256=9uCQzDVGSnj7DXbOyFGRGvOCsiMwtWYDA5tr4ahs8ds,739 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64ipf-tbb-export.def,sha256=bIyh74N05j6pGKIdybWO57_jWdo70HV3ckDJfE6uNWc,929 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64ipf-tbb-export.lst,sha256=Nb12ZCYl5IU9yi3YHKEgSOJcs725wW54bd7ZYjoc8Ek,22576 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac32-tbb-export.def,sha256=6RgDG06CCIsu_m260EedWLeXUebI7FCU_zFt1YNXwGo,682 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac32-tbb-export.lst,sha256=orn6JIlUdb0lbjhLQkH2b04aK9K5HOhFUrdeXRS2PVM,22187 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac64-tbb-export.def,sha256=GYjtS40UKapsYwirtfqLkhlhH8hNYRbm_BEgxB5ux5c,682 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac64-tbb-export.lst,sha256=frtxfdUl0qlxFbvWOyKM1RLRjvYNRiLjkJs_NCxFQg8,22067 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mailbox.h,sha256=vP1-IBEA87GsYe2FI7caiExI7tdQ4tBkbsAH4YZ0St4,9215 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/market.cpp,sha256=76GppNfvUWqkJYsNR6CylRqV0I6KZxWAtwkQM8N7iLM,34737 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/market.h,sha256=l5PG8AegbVfXKAl5ivOJeHyV817f_cY9meV7lpe-syM,15228 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mutex.cpp,sha256=pfdr5H69acCI6ShrvczleMPaYzicXAiRYHVZ4ZaUpaw,4914 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/observer_proxy.cpp,sha256=zp49R5Y37IYxwhsRwjhTkt5CTbkLr9fZCOFX6JVeLac,14612 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/observer_proxy.h,sha256=Odwb-iRKB-vgk8qUGonuFGaPp9wGuh1iUgo5Leq_KM8,5967 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/pipeline.cpp,sha256=Mue7TtK_Xlctf93TW585HlaekpGvVwPkKuDQuQFwQF8,31359 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/private_server.cpp,sha256=pYO6ZuJj8p0Az5CRxzVobr3edH8MYZXqM_0_nX8SWQI,14677 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/queuing_mutex.cpp,sha256=eSnVtGsqx_De7KtkAktPbRZXYzBAM1MyzXn788neo68,3474 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/queuing_rw_mutex.cpp,sha256=mHvvUPkL0153HUVVOqDtx8dpwHipTRiP09iSW_UsWd8,21286 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/reader_writer_lock.cpp,sha256=MWaxS4VA5133rKoC5tPGAf7LDoquOX6xDVRO7pFw_Nw,12872 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/recursive_mutex.cpp,sha256=gLYJaXc9eOTRRBN1xfm8TjxAT6EJbb1or-j686rfSg4,4439 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler.cpp,sha256=kKslPrBJdPfYOHT2zEX6pWs-S5X9jqfK_FH7UbIN948,67503 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler.h,sha256=eeNethx88CWOg5Y20axH9sRf8PA4xcsf0It3Xz5Rd3c,40186 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler_common.h,sha256=F3GAPx-Su5VxZC9vLaaHsxTi839RLvCabsS2FvtcAnA,17025 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler_utility.h,sha256=EMO7MnJqi-_b36ztwpkxnk7WNi1IW105UHQ-wjd7bDM,4510 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/semaphore.cpp,sha256=dJgmEnACxE5is6DUGrHz3JXg4ojHQ_ndvJFkDbgFJ_o,3207 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/semaphore.h,sha256=mFrTARFjKHvoj307g7uY4MB8RjJby_dB_Knr3YFpvJs,6779 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/spin_mutex.cpp,sha256=_aXJ8vcPVCucD1c60bEZZTbHE9KC-g7j96iCBO7V-_I,1669 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/spin_rw_mutex.cpp,sha256=RHdC0BzztDWKC7dl2P0GAmDY--hKn9xdqKcNqPOdkHo,5982 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task.cpp,sha256=jJhkyoJs9XP08HHi1uDzZxKLxOk9sNhike-cck-zVs4,11702 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_group_context.cpp,sha256=xRqwdmRcIrED00aiCU8Z-WkNTkpaBJBjLZVGv5QT20g,22772 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_stream.h,sha256=cQGcOiEoovw_PxYWHwEA0Yw3d4lmlfTZruWQse3Vq-4,5891 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_stream_extended.h,sha256=rzMriIXgs-vgjZxvZse5sjEFmBYVghEd0pyWxXszlCA,11947 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_assert_impl.h,sha256=IJWzGwBhi0RfHJih8dnfJAXiNo6kft9LBoQmx3G1WiQ,3381 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_bind.cpp,sha256=3uNEQ0HSucOztuGtEV-eY24nqrqTYhu3dO9wWehKPJU,12405 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_environment.h,sha256=dM6tLdMLJnF9KJLbZFJNaqW9qsHCn8l0VNJUSK4QwcE,2541 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_main.cpp,sha256=ivjOMdU2fII493hd2kTQuOQKGBiEbqWVjnU9fUh2OwA,21748 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_main.h,sha256=-kvpNNkfUaAbQde8dDf5aYyug5yWuQSpUa67_yaB0k8,3442 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc.cpp,sha256=Z_myBYIXtK3RZZHwJPpkgyDu9Lqv2kPbA12kmiYd-4Y,11757 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc.h,sha256=_eYW5mtilzqgsBZ0weEp4vrgEnOTjAGbMizkPEm1omY,10348 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc_ex.cpp,sha256=bb2gQkPoqbO34ZrimzSxonRN2bZjRI2SlwSZ4QyDaWE,15809 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_resource.rc,sha256=zjjr7jHwavA6xHCF_bG4KoiS9-Swl0U91MCcSZqYIEI,3310 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_statistics.cpp,sha256=bypalNSEmSnBTdhXcvsdZ8E67W6eVhNlAR1TBXCYvG8,7170 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_statistics.h,sha256=2KMZ1HxWHiaLpV_YNNq-I9h4TS0zUGD2E7FfNcrzY5Y,8828 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_thread.cpp,sha256=Y3FohduZ5trC-gkvM0P-F2_ezkrHvKHMNhBq069vuyk,5863 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_version.h,sha256=pm4AxmT-adx-x1uNdbI0Cdfz7atolfTr3k6gw4K-H0U,4013 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tls.h,sha256=Fhm0J91TVuy2jqreWPsSlqxBxL86CSmpGkWcpk8DrgI,3424 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/disable_warnings.h,sha256=KANauGUai8EqLSmLCC6QUZMYzNmP4I_xIpMxPhcCxrs,1545 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify.h,sha256=lp3A5ICPmEyxdJfa7OI5TJYV8iYh43_Za2zscF33ZWM,173350 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_config.h,sha256=TlH-MZO6MokovWFflB1xjzP5-ts2By83wocculEAiqM,20352 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_static.c,sha256=MuoijxnhvN_it9Yv05STI2aSDkOFo52fo_lMkuUTu9E,46776 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_static.h,sha256=iH19UTy4ro2NB9nAVC4z9IyhuAw0d2ywEJ_R08vHD3c,40114 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_types.h,sha256=7ETlPw5CJV1uuQF3jxLELmPq0uD8C7iGheT9oulApSk,2442 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h,sha256=4mEfabamvJnJNC4J8b220qaBSQUP4Hur5sBzzRqCSFE,37121 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbb-export.def,sha256=8I4xGgJVc1tHJx5GoK3V077zlQIsfwsG8L6eRQJUYgc,722 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbb-export.lst,sha256=uyTIQjoFdCZs5lRvoiGULDio-TlzSGqnneKeJWUUyy0,20388 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbbbind-export.def,sha256=GElxr8Nie_PgVdDCgyJqYC7l4Qchl9U_PYtQxj89pYI,714 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-gcc-tbb-export.def,sha256=oRav6mDsVVNK1tt7DdrFFEtv7VdaEtJ2CHn2PEHMqLc,884 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-gcc-tbb-export.lst,sha256=CS4DvsWNm40orh_lJXZqwGj82fOrgDuZjFPk3JQfXb0,22701 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbb-export.def,sha256=9yAqmFr8JOMqub1pfntC-Jm26WQOyKjf0pHZ6nOqAfY,777 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbb-export.lst,sha256=ENGhdJ4YeI3xNktEbnE3s-fwRMvApEcNlmcvQjN1-yU,20530 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbbbind-export.def,sha256=GElxr8Nie_PgVdDCgyJqYC7l4Qchl9U_PYtQxj89pYI,714 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/winrt-tbb-export.lst,sha256=gfv3VHpdenXbn3LOor1GTbDMCpX7VOVBCovnSge2DOA,17226 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/x86_rtm_rw_mutex.cpp,sha256=FY5J6LBogoTrNWbBnqYCJJbPaXSI5PE_WGSM3UCmAr8,11358 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Customize.h,sha256=mF3oOjUmwH0uVRBCq9zT7D1PX4jY2G42fSPNfRy_98k,4588 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/MapMemory.h,sha256=-m_64GCSh9Z1hPSt9MSSptKx123hFz9gYluBWbakCPw,5621 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Statistics.h,sha256=pTnL8QH6i0tcuwuJSVeV5RD77eOo68_mQwbgkhVuhEw,4463 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Synchronize.h,sha256=whisyEkb4gC1xpQwXGJQQeA28g-w37E0BAXrYwZTkgE,3465 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/TypeDefinitions.h,sha256=t-S_lqvYDgfFW0Jm7uJgFobkScyvAylwstP_kMR5jE4,1802 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backend.cpp,sha256=2vt0-QZaO6nMQBDwfMxkj9RH7xf7qgbrkgXN9hGdk24,55673 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backend.h,sha256=QzP0HK4-gX7LPNdr10jkVRTOQgkKBsKOssEcdKRk7lc,14588 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backref.cpp,sha256=1mktlGu32ZIK-T-Q2Domy5BXQaKYFAWMmxCE09RP6rE,13640 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/frontend.cpp,sha256=nteXGNg_4MPXjsnag2ipBvkp0Y17dE1G80Q1art-lys,113900 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/index.html,sha256=_11PQXpeureVVMb_eZqUWjBbPBSrMrmL6fAHlGQmT_8,2256 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/large_objects.cpp,sha256=O1NVQa1Y4odt1hjJrqof9nXPjAwVtOGYbk9HmjHR7Os,34951 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/large_objects.h,sha256=U4VwFgRze8L0BoRGALL77wx-YJxtT2venRtYAimhMto,14181 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin32-proxy-export.def,sha256=vjgItJTiIaPzx-Zgdki6gBsEEAbFKZX06GdxVAg-Ddc,1091 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin32-tbbmalloc-export.def,sha256=a_rS_EBja4HRFlAN8ezYKHvd00ekWxcdk72oICEweMA,1929 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64-proxy-export.def,sha256=BS-6jUGb0SMRsGLEBBEEmdpFKdzbrtubpvfLtRwIcbw,1092 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64-tbbmalloc-export.def,sha256=Yk1Chc0zOoFELy_MaH3pnuBkpanGTcmvUDN9II2Gwyw,1929 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64ipf-proxy-export.def,sha256=BS-6jUGb0SMRsGLEBBEEmdpFKdzbrtubpvfLtRwIcbw,1092 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64ipf-tbbmalloc-export.def,sha256=2ZYNNwEDrUAbf64UxjmlesAhKTsquUPLyw0UfMhx5ko,2050 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/mac32-tbbmalloc-export.def,sha256=OLxugfVCFpzXr75T7TdWvMnCyQ9JiSYVDl-tb9WqvVA,1544 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/mac64-tbbmalloc-export.def,sha256=OLxugfVCFpzXr75T7TdWvMnCyQ9JiSYVDl-tb9WqvVA,1544 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy.cpp,sha256=snaf8p_wEdmK8eUIAGllfZ4e2N1d9prUd6MQfdyfFCI,31980 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy.h,sha256=4X99efMy64o4sQdDxmE5x_ZO_7zSInEqhUgDzvpz1o4,2374 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy_overload_osx.h,sha256=ly8xeeAX7afJnnBQ2nxix7ReBVmzwxXDzeghXz0P2uA,7144 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/shared_utils.h,sha256=e72O3mCEeND4FsJHlyMejp9KsXii3_amesqVmRFZskk,4528 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbb_function_replacement.cpp,sha256=7vN5ymR_Wp8O6XOI45D6cI9EjoQGYoX8sX57r5neQuU,21627 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbb_function_replacement.h,sha256=SORwRO3g9xwFatdPeqM4HKvZZvZ8xnCZ-KUN3ZJzd98,2801 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc.cpp,sha256=0n7Aj5eSEb7gL2EDXRCSSZMkMn3omxBrIQUVyIWZLUk,3824 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc.rc,sha256=o_fTaR170NfiOQ3xSbM1KKscQ_Q7acK8Club2dLcnbM,3465 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc_internal.h,sha256=UomhvFcTwBiRkK_61fgnwfMDGnHc8GVpyWl5A5N9PaI,22842 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h,sha256=RUhcQMk9pwc9-gHVK0ku9j51f7RKkf_jl8zI7MTKvog,1254 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win32-gcc-tbbmalloc-export.def,sha256=3Swa9ygf4bFR-d1cxeaYfu5noTfWdiqqO0JlCyQSnaQ,1533 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win32-tbbmalloc-export.def,sha256=aD8l7RymWlABO9_J79jufb8m8i5y5CCakxSbbY5i6do,1536 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win64-gcc-tbbmalloc-export.def,sha256=dZjqvf-3gfTx8gMHwYNS2YD7mfRm6eYXhiUQoa2APmE,1533 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win64-tbbmalloc-export.def,sha256=Dd-D2C2CPPKkddZqoqFYAZTZAxWbWlxIzZb2SLzJPiw,1586 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbproxy/tbbproxy-windows.asm,sha256=wQ5c4lVF299hNcV0rOLLg157yA2JwQexRT6Nf9lAK1U,2831 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbproxy/tbbproxy.cpp,sha256=XGVaSc-vDQaPMwG6Ev9vfAePIeN5wfbrg5CZ8n3iy88,22579 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness.h,sha256=aarDx7HaHzQ0MkzyBgj-0cvOHmyS9FgfTclaVMi9f4w,28057 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_allocator.h,sha256=RW8u6T-DArO4DhinBjLXBUUQxtBj0_gp8K7TO0KoZPY,32249 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_allocator_overload.h,sha256=UW2gxkw5kfwF85N3AFMoWwmQ_h4yTZCjAuEPChVOnXk,1731 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_assert.h,sha256=BBm0VoMq7UlUg0XPf-eoj5ceEmRy8a0Al2rSRJWSnz8,1514 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_bad_expr.h,sha256=sWYyWwco_vNcRh6ZmWdZy9JLVKiolhn5fPXGRJmoqps,2944 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_barrier.h,sha256=BAobjviF4H5yE4DrZUX6vFoT_OKB-yfLuXwORFyjQso,5190 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_checktype.h,sha256=XSflcy3vaYtgmqgfIxwzkSiQFovro31-Wpr314_ksRA,2871 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_concurrency.h,sha256=OljRWQ_6X7lhzY8eHYdRSot2iod9JtDky6284_D_H-w,3461 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_concurrency_tracker.h,sha256=81j47yCkjhiWeQ2CaM_Wr-fSc47RbfXqlsySmI0WX28,5878 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_cpu.h,sha256=yTSkx8QstGfayI8WHJeyWeuWAG5tvkeVresWaoVJSr4,4926 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_defs.h,sha256=bSfwmdbLX8mFNAZZUKp_ecVDWkgiGorLAZbPcjRKbh0,10946 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_dynamic_libs.h,sha256=KTjNuSMQh9HE-zDV_hU9mn6HdvkyA9dPMilxkhuvzlM,3135 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_eh.h,sha256=LOJRCoTY39wo9WGb1MkRi0JSBTCc6S0X1MLCgIjjGeI,11203 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_fp.h,sha256=5j-x45kB1Snu2XZoDRdvXeG9-9juvprb2scwpgDqFyk,5441 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_graph.h,sha256=Umv88f-wxn-wqfHRb9OuRZwy1yTCPDBwK7Bgve4cR8g,46464 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_inject_scheduler.h,sha256=usJNxfwvdhbA6LntP5Ht0oQNMoeqyTT5HQ0DwEKRNy0,2497 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_iterator.h,sha256=FV-4JPSk0KgpPyxGvsUklSXMvQNCvgUFwcx7Wg4ddSw,5982 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_m128.h,sha256=rc3msvMxH4sVsegewOkKUe32aI7Dte8zTH8x1c6ZsYo,3968 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_memory.h,sha256=dgGAv-rwBAvaMARdx1kXl5Y1kO8YUUACOFVy1GGv7w8,4725 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_mic.h,sha256=1S0bQtottn7u2SVUdxgGGYOjVV6j2FmScTeuj_kbKL4,1240 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_preload.h,sha256=JSUSVAMU_ThUt28mZAYkeuntlgRjGqZbi6m23Ot5SkQ,1851 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_report.h,sha256=88oCsxY27WpCThpKfqzLNBvRUWlxj3SHZG5O5u5agzU,5521 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_runtime_loader.h,sha256=y3QJR9QmGHTPWW2dLYEgcV7ziIak8REwJmLr8w6zYPo,1228 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_state_trackable.h,sha256=qjSfBAUJxHWXVxvltOHnWiM9ZXLP1Pp5vU9PXLXvUPQ,5936 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_task.h,sha256=peYoNN91wKfiI89iXWcMgiHWCTX7jzED5V6LtrifFD0,1677 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tbb_independence.h,sha256=laXEaL63YJhuiVkso1VVbnaEdaJQE_EnvjGQea6Djrs,2727 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_test_cases_framework.h,sha256=3lTMVyeADkznDCefyCrYTnGsiRV6wWPeGopEj0iuq0I,9589 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tls.h,sha256=0BwF15FsEG3QVJIYLiUgGlzkc5nyZyjwZnRELDnbDJA,2464 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tsx.h,sha256=4kuKhE1LbUXr6LT_bud14JE5EcKTAF4lCy-ZqxatJMo,2238 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ScalableAllocator.cpp,sha256=usvGSSKUJgitRwgnnkhGn3XKUZ9qzmZFq8UVu7XWc9g,8293 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ScalableAllocator_STL.cpp,sha256=Cj0lciVhShLn_E1NaKkMCCAa2yFD1-WHB387g-2Qmzk,1947 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_aggregator.cpp,sha256=JevfMw9i4oaH5WodqRoArPYrpwU1Xe03BQp0p24yqzI,5604 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_aligned_space.cpp,sha256=FF85kA3n9zCsDjoeS0ocpz0EJU2G43SCX8uV-pTw8TI,3656 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_allocator.h,sha256=dZ4O0zHl8esmTFsWNDwheoJYVakX6A7zEDMrgwS82Iw,8899 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_allocator_STL.h,sha256=2Fn-oSJDAi_h6yPUtB1izrIpZouUbcc2tW9cnbrvj_s,5394 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_arena_constraints_hwloc.cpp,sha256=aPsFLNUc3-uX4WcAAbP6IigZm5h7s5Zudef4JkmNE3w,15244 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_arena_constraints_stubs.cpp,sha256=rfSgi76LWbTvpaorWohkiCKlu0EbazRk2jTVkd96rv0,1491 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_assembly.cpp,sha256=yovbOR3Z00vOQrPFUEX7QXjxiXi1EhVPSElHcdFdBlk,5030 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_async_msg.cpp,sha256=iPijsxU4JIp8Di5ARDbv950QGefgLMc7sUQ8dy3YZN4,21248 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_async_node.cpp,sha256=GRHBpVhwFHcg2vd-AdjBhxiDoYSnpJt4iP0saKypfds,29378 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_atomic.cpp,sha256=iAsBUNwlT-S99jShttT_Eplos78GrzA2cMAWaLyF4YI,64086 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range.cpp,sha256=hQAqB1_16zu36OQUFTZfDiOCvA_bxZ4tl_SMMoNk9SA,7295 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range2d.cpp,sha256=4YrbucaanTHu5x7LBrZ82pfZtgf71F1FfLLkt3KCPJA,6550 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range3d.cpp,sha256=vwLFFTyld2Qn0-byBQXJSSOztnmVw0A3EVZiEJdAx0M,9171 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_rangeNd.cpp,sha256=UsDz6MkCTwBOprh8GBWk1hv8CFRwgw2qzl6GT5y_nYg,9789 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_broadcast_node.cpp,sha256=EvQgW92E8M-y9zISoFSF2Tzn-zt-4LGUhMAjRCkUq_c,12692 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_buffer_node.cpp,sha256=-jVadsUhhJZfvBI2UNonC-0n1MAoLsZ6V3JFLuIxeYI,13511 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cache_aligned_allocator.cpp,sha256=ssx1wwlzWTuZmF_B7LAPJZXa62eEF7FzD5ASfTLpJFw,2737 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cache_aligned_allocator_STL.cpp,sha256=spUc-9yv0KpgDeFM5OEiCnSRQT6h5_1BqGi36PSXh5A,1635 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_common.h,sha256=7mXTsef-ivDeZ5DJwZ_kQitOUOUYLOk27fIKwIcb8tg,2377 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_dynamic_load.cpp,sha256=iuBlrbwp0sm6UXZd9kDhgZslut1doiuSPjv57uLWShU,4055 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_interop.cpp,sha256=EPd7eGqnq3K1RhhqsUmxjWVtIzjWVSvMf_NRr2Qya1s,4247 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_combinable.cpp,sha256=WrWCKnc3Q00JpWOyehnJ2a2Qb2RvarR3HK-JKwYjF_0,17445 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_composite_node.cpp,sha256=Rsc1-nQw17m1GLDiCf3VCmZfcU9Q5TAlYJIn7hjIqD4,25940 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_associative_common.h,sha256=MC2_8G8Opb2jLW5soV_SiM2HHJpWKB_Q24KWz7h6afg,66617 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_hash_map.cpp,sha256=O4cg8iC0uYvarNsA3O09wpXyR2M2CsnewJh6O12h4pI,63573 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_lru_cache.cpp,sha256=FT5C-Exk695jqeOtujl-WlQphOUws9Tan8Tf_bRgXCk,20538 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_map.cpp,sha256=JKXmV4bfvB6m_JNLIKOPHhqWdVsx0o_CPoSPuzBw5ow,10558 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_monitor.cpp,sha256=Cx3wDkOgoooAbGP_z4vYjyy9xTcMFD-ypX5u1B0q_-I,11278 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_ordered_common.h,sha256=97aGCalyzajS0Qnt8Vf3kbgzhroEckJYU1xbDlY3YcE,14583 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_priority_queue.cpp,sha256=JDZh1_rxfczMgj0C53nVNPxjondRx7DfDgIBtkbhQc4,46187 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_queue.cpp,sha256=zcd4_PxlSIG7SBl73zKBRZdvDekRN6rD5uchZS6_fMw,60328 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_queue_whitebox.cpp,sha256=oaPtq66aAdSVL9kVOXrCtvQlHWFa0yE2Yz2p1b3jn6I,3009 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_set.cpp,sha256=L5U-WxQoyFpbH-woX6Nqn-6PenwQNmbVuzuoBoIsF0I,9685 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_common.h,sha256=oZeWWR2Ji_sUDwaC0I6gufJxvMIunMKLw6OFQCrsTWw,12232 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_map.cpp,sha256=kwcUPpu3eVe_5_rXOwyGUwIiFFgRUAty3wGD2p2fejY,12172 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_set.cpp,sha256=TkeLuMflSV1qrU0jyQCsDAB4-92x2Pi0DyUOAkhNFus,13241 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_vector.cpp,sha256=Xlc3j0EQKtm5UPh7vWSyzde_TbiB7l8g4Ou5BfqGkqc,78080 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_condition_variable.h,sha256=4JWozx-L8O6s5RtDrY2ALwl7KfWK0Ipf10p-89Irk9A,26410 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_container_move_support.h,sha256=oXe-ArV9XB1uyPm7g1h_Be16VCFOS4bdQfXUXHM3JlU,36611 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_continue_node.cpp,sha256=ell0wOYkfwETEm7q12P62gw7uS461sUyc6-yebD9tyE,21647 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_critical_section.cpp,sha256=cVGA90nF5QQ3b7srnG85Y-mGm0s8ZJCD6ykMfmyOP2Q,7808 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_dynamic_link.cpp,sha256=SbvUwgyqGu9xEK8kdrJdiT9V5XwhwCUVUcoiOcVDsT8,3203 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_algorithms.cpp,sha256=WbGHpGVYzJeEkWbFn5yhxJuDu6ATCkR2Vw2-l1AvuGQ,67005 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_flow_graph.cpp,sha256=RG-xey3GwqvUKX6xCfeCb5IHh4aO_DF1_7jlWRJX3GM,91474 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_tasks.cpp,sha256=dqPeaNr80cQ7gtT0YoCntpdvy7R7v5qHr_AOHDupjtI,30447 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_enumerable_thread_specific.cpp,sha256=_XBWbfeQlYq2OamOy8DdFaTBA7QfKKggeIFg-cdiIY0,53198 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_environment_whitebox.cpp,sha256=jAUav4W-dFTE_uM1o49ubGh-ja28YL4Tj0nLqTrSjcs,8891 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_examples_common_utility.cpp,sha256=ZyapvVtuxoNh7z-kFducMeD7aaUjhqzwsa6k5CZoarQ,23400 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_fast_random.cpp,sha256=GnE76UdkUeOodxbQCp-BpF-B5HybMCm0IHrZDaSz5VE,8611 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph.cpp,sha256=ziR_173Ve4Ds1WmJglHBRfj6QMPOOHbSj2Ip5b2j1L0,11807 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph_priorities.cpp,sha256=SnWE7uSXiNQdF_xKZw7X6EUsSZmCB7a6FO8lxiMzNmk,21931 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph_whitebox.cpp,sha256=KXuabo3kWUWF6y1bSV52FUCaXh3Z5_WHNXy1KKHjD4Q,31495 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_follows_and_precedes_api.h,sha256=jtcR5yKHe99_MRt5YVZTP18bMg7JXrYXTI9FkCz9lP4,10995 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_fp.cpp,sha256=Fxa7B1mXJUdWZ9_CNMxUhcnyXwmSPl2hJhjAHApw2qU,14374 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_function_node.cpp,sha256=uT2HX2MvAwW5XeVfXg8_2Efm5WsnJF88v8hq4ZE2MQQ,27664 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_global_control.cpp,sha256=Pq9Bar3_HTnbpCo5AF9kvTLk5aMR_LoV5xGO8f-AEVA,27536 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_global_control_whitebox.cpp,sha256=m2BhxrxNu00zJEr8tLA0pcFZ7tIVBOoCRsbK7M4mx4M,2406 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_halt.cpp,sha256=XCTWne_NtayyB_CmQtKQf44HgsV_A-xNy-eEhmu0_eg,3333 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_handle_perror.cpp,sha256=5ohGyWohPX0c8GwgLc4oj7D40r2QuEttOUk7Jjwicco,1496 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_hw_concurrency.cpp,sha256=fDG5tdLmZ0OvFMu68smFM14QHF0WZLWaRkBgbbvu8NI,1828 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_indexer_node.cpp,sha256=IBSlspvfxeiBC1AgdKFbXCWNooNFO_DpIr8ADs9qPDM,36672 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_initializer_list.h,sha256=jAR4B7NPhQkQHArx0rktfPe2fgwf5xvwOpWTaZPquY0,10919 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_inits_loop.cpp,sha256=-IP1bjtoF9_1vtU6UyR241Y0KDn_2MQULQdXuhXcapE,2667 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_input_node.cpp,sha256=wnIDlUy2iK-LXDsUoY2CI6_BGKEpwnjYuZ8AbshNw0E,10837 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_intrusive_list.cpp,sha256=0J5TY1rAdaHNbxUKinM0Ik1vM4Q197z1Hvn66y-yl6s,5563 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_iterators.cpp,sha256=q8f1Bte1ar5XJmaTzz_0ihfH6sTT1eARW-5evw-qQro,10288 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ittnotify.cpp,sha256=fQXIxOeNSR67l1hjl7oT2rOpB4NxYUJFHrAOU9dJ3Bo,2519 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node.cpp,sha256=t-kwoM4sMqtJkcfgYGAgx1iy6FpHkcsOSZEwX0KJiT0,7939 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node.h,sha256=UTTOFxypNJtSXO80jnAgVWyaAcJqoFQAEDbN1p1H1YQ,85512 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node_key_matching.cpp,sha256=uThcciKjYjkvEoX72Eu9Mik_P1xCoiTjIPpbhIZOxn4,4135 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node_msg_key_matching.cpp,sha256=MrvpsDeLS8VG8X6W51FHIILJsW9MmasgDGVa1pt8SMw,5118 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_lambda.cpp,sha256=9jEqidxCBNozW5QEwC2f5Ad1uigex0n9wjd-jWwtNzQ,9260 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_limiter_node.cpp,sha256=BezC3Q95g6YBAoV4x7nT6ILbm-VuE783RfSSMu42WXE,24879 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_atexit.cpp,sha256=xAD9SmV0yVMjIkc12QElWQh1q2g4QgEW4zIY9_3Svok,4138 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_compliance.cpp,sha256=eVY0Apzl1f7loguOkZpcSpBUrE5raIREKhiMbYk7eiw,36199 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_init_shutdown.cpp,sha256=K4fiz5qXeH2rmIMB_Q8HyD1VKXI7Lo3TTgQ3KRn1wzg,5386 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_lib_unload.cpp,sha256=2vADfx2pZS0MtOLXCtFdDqqivP-5fRx2-xhqy_bWiQw,6742 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_new_handler.cpp,sha256=oGSmrKpopyYNTBRTMcAvVmuJ2IDK4_mxacb-1XDN12w,2517 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_overload.cpp,sha256=yXZR20LVZMuaKcAxuZVsdBdeaB2msOE9BUTR1Qqi6kI,16254 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_overload_disable.cpp,sha256=RfFXm7HYhceEMDeTC-OU_nLlyB3YV6oVDpa1vkUJYTM,2356 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_pools.cpp,sha256=9gGDzFap1bgwNF1eOER5Q362aQmIM8AGwrStiz5u8ss,27504 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_pure_c.c,sha256=_74IAOAboSQc-9IpkOfYe7tK4Pw2G_uTV2JTCYHM5kk,4089 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_regression.cpp,sha256=g83kXMVByvQBnqwerYOYLEHWWkYv5LjXF5DFZuvEyYo,6360 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_shutdown_hang.cpp,sha256=d3aPM8eGihSW7J9gNDa71o37Yb4MwQfTIhc3Rls9acw,3378 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_used_by_lib.cpp,sha256=rP95ppHfix2nsD4S9oWAeX7WSchtwYJTpgnpGXYxfBI,4426 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_whitebox.cpp,sha256=-ppmksZyo__d7gHLlyWxa93qkPJ9MPupmXl8JWLI88g,62103 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_model_plugin.cpp,sha256=lzoNHRh1KjldraWGF0hIBkokCQRZ32rVI0mlvXOR34Y,5516 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_multifunction_node.cpp,sha256=6XRmGu69_rAGGYfPN5dfYMy7ltiCyOJeQmFQuF6fO_I,33271 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_mutex.cpp,sha256=iXkb44P6buVFaqTmyBepIRlsm7qlFIE7WD8Ps3A5NhA,26363 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_mutex_native_threads.cpp,sha256=YPQfo8lnKb7dP6-UhnJINeWm9nZ6UwSsxwnVjBVEcfk,7029 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_kernel_32.spir,sha256=VeAt5cew6Hb2mY12yWi1m3md0MfSmIOR86ZYr3xQXXI,1440 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_kernel_64.spir,sha256=W7R0WVyckRmIBLjGNZSGS43nT8hQg95BF1-c7eJT04s,1468 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_node.cl,sha256=XP6vmTPyIiDO_e-juqeY69YLjRR69GiergkajWDTsBY,4881 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_node.cpp,sha256=6UUePB9xVVAySaWFVunH53dt4fmY4Lla3msukpcAYOw,37114 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_precompiled_kernel_gpu_32.ir,sha256=RtkKN1HrpJg9GgQ3mO26Kk6L1ksI6Fpb5AVQi19QoNU,4110 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_precompiled_kernel_gpu_64.ir,sha256=9zkBs4QEr1nVQ4i6CDl7PqyBLvzVZaDs57CYRklsxpg,4186 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_openmp.cpp,sha256=2LrBnE8qBvPgK-pJq5HVeiZGFRnBHOr5J-3WYfm_Y50,9163 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_overwrite_node.cpp,sha256=xqZk6PHXD174GWcLqC-GjJmf9eLAgVBuxGuXWIxJJuI,6338 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_do.cpp,sha256=HDUdHlqBRTGPUA36hpnEs4O0JIV-Csrz11bM6-WB4mU,15440 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for.cpp,sha256=2xBz3ZBwnOQAc4HRkhniw61P6B3zDfUfm71z3SRciy8,29519 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for_each.cpp,sha256=00mWVPqRFguSRM6CXi6yLbiuoq_pHQfWr_crkKpE_pM,8510 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for_vectorization.cpp,sha256=sOimYw029l8r0RQfxZWd9_DC45jQLZcs4L7eztIXkNk,2561 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_invoke.cpp,sha256=uDSLyidLf3hlARfSoux0HhAVMLMHfunLDox9vcOHMaA,9937 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_pipeline.cpp,sha256=iBvsLcOQ28LDQNp-qKzV3S4w07em8eX238UGXQlJULI,24485 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_reduce.cpp,sha256=soSYUuaXFH3vGbAsFQy8-wX5aVIurFL4_5_zHwe-1Bg,17734 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_scan.cpp,sha256=HS9Tq9GjPQuM6Hl_4q58gELc2xpWKlrZ6CqrMY1uolw,16538 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_sort.cpp,sha256=sdJYsQ2MNyHT-LKYgB2wwA_RpNGRNfJIxjCJ1sKSi8k,20279 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_while.cpp,sha256=lJHoRoopOGsmF-a86njzFDKb0E0b-eYL-XxiNuMMYVM,4646 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner.h,sha256=hDEUzIjYdYBO7S4upOBUipEOGD4fUq7sauaZon07QLE,27120 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner_whitebox.cpp,sha256=fgoanRm524yzPDbiUCehgLeE4I1Yt4-9y1Uxtc_zTJA,8076 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner_whitebox.h,sha256=2SG1rrKXNiDvySM1AW9GMCR2SuPrVbNjT-Yecz9U7Sg,20655 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_pipeline.cpp,sha256=mrJ0UemWC-eK4Ou3vlfQ7ogxSUML91uZE7UcVki9UjQ,11889 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_pipeline_with_tbf.cpp,sha256=Qf6ZnG0wmNAcNmkwHyE75eYjSIgiovAMdv4gv1u6cN4,20804 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_priority_queue_node.cpp,sha256=CVGW1IJn0EWi9LdFdTpY397b0FRlfx86ZfHiKYY_p30,12282 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_queue_node.cpp,sha256=NfKsQwQsjryl8JVbIXHyIg_lpH-NqPPLBNvR_7SQF64,15178 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_range_based_for.h,sha256=38ghPS33hPeNIxpSgckOLpDECFPucOq-rJNp7pyL6ps,2706 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_reader_writer_lock.cpp,sha256=ZDKg3nrgDsUZBMxSDhpQl-nLbP5iqlQH_CpUH2BL2NY,8127 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_resumable_tasks.cpp,sha256=6892KnwmuqcUH8SghB2lBPRnI2C0bXqfil3FKt_iUBg,13465 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_runtime_loader.cpp,sha256=WDt_llKO55IJZmuDBdICdxD5EZLj-DLSfpAsh-LG4JE,12088 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_rwm_upgrade_downgrade.cpp,sha256=f0JLu2iaH_lQs9e8q6yZkukMNfp_cxVHSEs2nR-oWDc,2127 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_semaphore.cpp,sha256=Z9BURr53-PaPdEWPx6T9UjME2sf0V7FYO9IXcWRmXmw,10601 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_sequencer_node.cpp,sha256=o302WtAqK8XdFLJTAezyeFRXQVP8g7nPHc0NIZf_1gA,13899 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_source_node.cpp,sha256=zrG9RV6A7YcViH96ZZk4f8JtNXBiZjVKOTXBBNXYPP8,16507 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_split_node.cpp,sha256=I1UoQL_cIVGvBnWvVpHF4KzxVGaOsAhqdc36lO_Ltqk,15354 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_static_assert.cpp,sha256=ZUAmuM1UjD9Vb-TJYAV-l3_WbsrEdOt0K_bf3nx3-eE,2623 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_std_thread.cpp,sha256=vFcwMak0U2pS9f7uhPXfwz_iaMtyXIsOWBc6_cvoyzk,1094 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_streaming_node.cpp,sha256=SELHNHqcRgcqpKoUJ4_SFtVtJzfqsPPGhkXEGO4tfiE,28608 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tagged_msg.cpp,sha256=RiMo7UqFm-6B5v7nRmE2n70ShwWsy61ERkKnzu9jRoA,10556 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task.cpp,sha256=jQolomFaWrR4QVG5-YGQLwIN3Mr4FyQsaiHugcbeWNs,51760 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_arena.cpp,sha256=yQeBRaJoPZimEdavWAgEsBduUXydjM6TuL7lsQp1COg,66088 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_assertions.cpp,sha256=dqe9Kb_p1tv6fHSVJTThHA8uS_G9sCAmlqYX-1Pn0AY,3069 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_auto_init.cpp,sha256=q4ZkA45CQsRgA2NrPVMD1VKera8E52fCJyNtMZRT-vY,6878 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_enqueue.cpp,sha256=vDPaveo6lIu0xkMpoq7VhtscGPXGQ_TqN88K_RLVyKM,13704 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_group.cpp,sha256=VBe_yWK3vn0PKqb8FbhPTR0zjDd7kwEzSOoBEw5SPos,37382 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_leaks.cpp,sha256=1EbuA4ouVAMTrfG_TzeD2qnIHgL97j6DHO-ds2C9pJo,10622 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_priority.cpp,sha256=56PF3ZGyW0F6phBTGUC_GGaChVWw1yn6KS5Yf0Ma_Oc,25150 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_scheduler_init.cpp,sha256=4Rl4MSZvaPcjx_fq6tj_ZuWUfDTb2nWB83fnExuU25U,13852 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_scheduler_observer.cpp,sha256=lfy4YwkNjs7t75YYx1kLMTqu0ZXIitj9pJB5zJnbkpE,13448 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_steal_limit.cpp,sha256=-JXTzizi74Bf5AeNu60twB8c3CTJhDPMnKE4LLnfuD0,2333 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_condition_variable.cpp,sha256=ac6XvhuYkKoKURuvKrMkaDnv29vFsk7Epkrs0FCYDkM,824 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_fork.cpp,sha256=AskJXgYBa32FQ1ujvJz-6SVFj0le_DSNq8NTTzf4mmg,10117 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_header.cpp,sha256=K1kLcpjTdTEQUthoCNTyh5MMDMNxhCloYr6KwKrYZdM,17770 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_thread.cpp,sha256=hz7S87pQLbTz9npWcKI5pL5rUtnXw3g844HEtXQbcE8,929 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_version.cpp,sha256=h8KSzKUaUw92BAttWGKXmR8LCQE_u9oSltR1fFPWKFE,11175 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_thread.h,sha256=YjNG5hZF86bdavi5yYBv3Fwq2U56LZnOmiaX5AArFXU,9439 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tick_count.cpp,sha256=iM7GafEp1vzZ8Fr7Q037FPTts4zankOe77isnoMzaus,8465 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tuple.cpp,sha256=rKYS6pRjGkTAo6Yl6URWdaQmks10PKma2vVlDqpB8YU,7894 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_write_once_node.cpp,sha256=1b5dz4pnfKs3wEMULAG7cmkTMF4Zy42aEPA7R3K1W9I,6535 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_yield.cpp,sha256=LihiWuGDX9uBefHm8sHqdgn3J1GM_-FTjtTn4F7PP6U,2157 +prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/third-party-programs.txt,sha256=1xSaraX7WFfeEyYNDscCwOkCnqzVen520pZywoBcuZM,15991 +prophet/stan_model/prophet,sha256=vNCvvo9Byt3CC5SpPdgENvOCBZfmKiwyK0JYFbajxzI,2854448 +prophet/stan_model/prophet.hpp,sha256=bWe5MP12WC58ZVcoU3prdwchMsjCFEWPQI-PHqBl_1U,63770 +prophet/stan_model/prophet.stan,sha256=GsrhEiDwxc7yoQVX26z6A06dleW3etlj5HAE1aL8vZs,3634 +prophet/stan_model/prophet_model.bin,sha256=vNCvvo9Byt3CC5SpPdgENvOCBZfmKiwyK0JYFbajxzI,2854448 +prophet/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +prophet/tests/__pycache__/__init__.cpython-312.pyc,, +prophet/tests/__pycache__/conftest.cpython-312.pyc,, +prophet/tests/__pycache__/test_diagnostics.cpython-312.pyc,, +prophet/tests/__pycache__/test_prophet.cpython-312.pyc,, +prophet/tests/__pycache__/test_serialize.cpython-312.pyc,, +prophet/tests/__pycache__/test_utilities.cpython-312.pyc,, +prophet/tests/conftest.py,sha256=hW_ItwIOTx4SyPVz8bWvOXKUP_qGTu1SUiFTq-QGhCg,1874 +prophet/tests/data.csv,sha256=yy-lUrzs5U8J4hGjGIJMbzQd8wDnHEeGZiCSuHhsYfw,8628 +prophet/tests/data2.csv,sha256=wNhJ0BCNvB5G3zAnKiJgsitiGZe4XoFUlZH_B8KEiwE,21518 +prophet/tests/data3.csv,sha256=J0ynT7U6aF83T1J7vJP6Mpu_zTJB3u89Mf8xQyNTT5Q,1615 +prophet/tests/serialized_model_v0.6.1.dev0.json,sha256=3yQaLQSm9zW3B6zQq_ry2Z_jN2KzpwNsVanjkgyLjQE,7084 +prophet/tests/serialized_model_v0.7.1.json,sha256=sdu7ASiv6xKnILBvQPvrvOiBQKjuslQnnBLEVCmhqK8,7511 +prophet/tests/serialized_model_v1.0.1.json,sha256=GfNFqFGOB1CPkTd4YC3GbbDhC9S40DtG2hAt5p68hAA,7507 +prophet/tests/test_diagnostics.py,sha256=cCzqUHTFAMXZvqKrHU-Mz5VZSLdZOpl_uO_93_6rKeM,16685 +prophet/tests/test_prophet.py,sha256=mUqLDdjl7ZO4GadANsSnZlK-J_OFgMjN9MQSUQhyoyA,41388 +prophet/tests/test_serialize.py,sha256=4eVG6UC03MLym1P63CVFRxi9EunPsBRDYJLNBo-8W9k,5518 +prophet/tests/test_utilities.py,sha256=MOt-69lADocVyv4JRvzzL8oy1NV0sfNmCwZ3cE4F90M,1036 +prophet/utilities.py,sha256=Op25_cv3-I-MudmB7zc2FFdx6uj0aEc3GrMxWVpDPMA,3620 diff --git a/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/REQUESTED b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/REQUESTED new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/WHEEL new file mode 100644 index 00000000..6ceca3dc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: setuptools (80.9.0) +Root-Is-Purelib: false +Tag: py3-none-manylinux_2_17_x86_64 +Tag: py3-none-manylinux2014_x86_64 + diff --git a/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/licenses/LICENSE b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/licenses/LICENSE new file mode 100644 index 00000000..b96dcb04 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Facebook, Inc. and its affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/top_level.txt b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/top_level.txt new file mode 100644 index 00000000..79b46584 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet-1.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +prophet diff --git a/.venv/lib/python3.12/site-packages/prophet.libs/libtbb-ff323302.so.2 b/.venv/lib/python3.12/site-packages/prophet.libs/libtbb-ff323302.so.2 new file mode 100755 index 00000000..8433d9b7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet.libs/libtbb-ff323302.so.2 differ diff --git a/.venv/lib/python3.12/site-packages/prophet.libs/libtbbmalloc-4dcb68e3.so.2 b/.venv/lib/python3.12/site-packages/prophet.libs/libtbbmalloc-4dcb68e3.so.2 new file mode 100755 index 00000000..1f49489e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet.libs/libtbbmalloc-4dcb68e3.so.2 differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__init__.py b/.venv/lib/python3.12/site-packages/prophet/__init__.py new file mode 100644 index 00000000..2de68f31 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/__init__.py @@ -0,0 +1,14 @@ +# Copyright (c) 2017-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. +from prophet.forecaster import Prophet + +from pathlib import Path +about = {} +here = Path(__file__).parent.resolve() +with open(here / "__version__.py", "r") as f: + exec(f.read(), about) +__version__ = about["__version__"] diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..bb94c5a3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/__version__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/__version__.cpython-312.pyc new file mode 100644 index 00000000..958be98d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/__version__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/diagnostics.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/diagnostics.cpython-312.pyc new file mode 100644 index 00000000..6a6998b6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/diagnostics.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/forecaster.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/forecaster.cpython-312.pyc new file mode 100644 index 00000000..88c24811 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/forecaster.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/make_holidays.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/make_holidays.cpython-312.pyc new file mode 100644 index 00000000..891611bf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/make_holidays.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/models.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/models.cpython-312.pyc new file mode 100644 index 00000000..9f54e45d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/models.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/plot.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/plot.cpython-312.pyc new file mode 100644 index 00000000..c6c181d9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/plot.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/serialize.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/serialize.cpython-312.pyc new file mode 100644 index 00000000..2d2c8921 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/serialize.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__pycache__/utilities.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/__pycache__/utilities.cpython-312.pyc new file mode 100644 index 00000000..9b0260bb Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/__pycache__/utilities.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/__version__.py b/.venv/lib/python3.12/site-packages/prophet/__version__.py new file mode 100644 index 00000000..bf788263 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/__version__.py @@ -0,0 +1 @@ +__version__ = "1.1.7" diff --git a/.venv/lib/python3.12/site-packages/prophet/diagnostics.py b/.venv/lib/python3.12/site-packages/prophet/diagnostics.py new file mode 100644 index 00000000..7f6bcc30 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/diagnostics.py @@ -0,0 +1,684 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from __future__ import absolute_import, division, print_function + +import logging +from tqdm.auto import tqdm +from copy import deepcopy +import concurrent.futures + +import numpy as np +import pandas as pd + +logger = logging.getLogger('prophet') + + +def generate_cutoffs(df, horizon, initial, period): + """Generate cutoff dates + + Parameters + ---------- + df: pd.DataFrame with historical data. + horizon: pd.Timedelta forecast horizon. + initial: pd.Timedelta window of the initial forecast period. + period: pd.Timedelta simulated forecasts are done with this period. + + Returns + ------- + list of pd.Timestamp + """ + # Last cutoff is 'latest date in data - horizon' date + cutoff = df['ds'].max() - horizon + if cutoff < df['ds'].min(): + raise ValueError('Less data than horizon.') + result = [cutoff] + while result[-1] >= min(df['ds']) + initial: + cutoff -= period + # If data does not exist in data range (cutoff, cutoff + horizon] + if not (((df['ds'] > cutoff) & (df['ds'] <= cutoff + horizon)).any()): + # Next cutoff point is 'last date before cutoff in data - horizon' + if cutoff > df['ds'].min(): + closest_date = df[df['ds'] <= cutoff].max()['ds'] + cutoff = closest_date - horizon + # else no data left, leave cutoff as is, it will be dropped. + result.append(cutoff) + result = result[:-1] + if len(result) == 0: + raise ValueError( + 'Less data than horizon after initial window. ' + 'Make horizon or initial shorter.' + ) + logger.info('Making {} forecasts with cutoffs between {} and {}'.format( + len(result), result[-1], result[0] + )) + return list(reversed(result)) + + +def cross_validation(model, horizon, period=None, initial=None, parallel=None, cutoffs=None, disable_tqdm=False, extra_output_columns=None): + """Cross-Validation for time series. + + Computes forecasts from historical cutoff points, which user can input. + If not provided, begins from (end - horizon) and works backwards, making + cutoffs with a spacing of period until initial is reached. + + When period is equal to the time interval of the data, this is the + technique described in https://robjhyndman.com/hyndsight/tscv/ . + + Parameters + ---------- + model: Prophet class object. Fitted Prophet model. + horizon: string with pd.Timedelta compatible style, e.g., '5 days', + '3 hours', '10 seconds'. + period: string with pd.Timedelta compatible style. Simulated forecast will + be done at every this period. If not provided, 0.5 * horizon is used. + initial: string with pd.Timedelta compatible style. The first training + period will include at least this much data. If not provided, + 3 * horizon is used. + cutoffs: list of pd.Timestamp specifying cutoffs to be used during + cross validation. If not provided, they are generated as described + above. + parallel: {None, 'processes', 'threads', 'dask', object} + How to parallelize the forecast computation. By default no parallelism + is used. + + * None: No parallelism. + * 'processes': Parallelize with concurrent.futures.ProcessPoolExecutor. + * 'threads': Parallelize with concurrent.futures.ThreadPoolExecutor. + Note that some operations currently hold Python's Global Interpreter + Lock, so parallelizing with threads may be slower than training + sequentially. + * 'dask': Parallelize with Dask. + This requires that a dask.distributed Client be created. + * object: Any instance with a `.map` method. This method will + be called with :func:`single_cutoff_forecast` and a sequence of + iterables where each element is the tuple of arguments to pass to + :func:`single_cutoff_forecast` + + .. code-block:: + + class MyBackend: + def map(self, func, *iterables): + results = [ + func(*args) + for args in zip(*iterables) + ] + return results + + disable_tqdm: if True it disables the progress bar that would otherwise show up when parallel=None + extra_output_columns: A String or List of Strings e.g. 'trend' or ['trend']. + Additional columns to 'yhat' and 'ds' to be returned in output. + + Returns + ------- + A pd.DataFrame with the forecast, actual value and cutoff. + """ + + if model.history is None: + raise Exception('Model has not been fit. Fitting the model provides contextual parameters for cross validation.') + + df = model.history.copy().reset_index(drop=True) + horizon = pd.Timedelta(horizon) + predict_columns = ['ds', 'yhat'] + + if model.uncertainty_samples: + predict_columns.extend(['yhat_lower', 'yhat_upper']) + + if extra_output_columns is not None: + if isinstance(extra_output_columns, str): + extra_output_columns = [extra_output_columns] + predict_columns.extend([c for c in extra_output_columns if c not in predict_columns]) + + # Identify the largest seasonality period + period_max = 0. + for s in model.seasonalities.values(): + period_max = max(period_max, s['period']) + seasonality_dt = pd.Timedelta(str(period_max) + ' days') + + if cutoffs is None: + # Set period + period = 0.5 * horizon if period is None else pd.Timedelta(period) + + # Set initial + initial = ( + max(3 * horizon, seasonality_dt) if initial is None + else pd.Timedelta(initial) + ) + + # Compute Cutoffs + cutoffs = generate_cutoffs(df, horizon, initial, period) + else: + # add validation of the cutoff to make sure that the min cutoff is strictly greater than the min date in the history + if min(cutoffs) <= df['ds'].min(): + raise ValueError("Minimum cutoff value is not strictly greater than min date in history") + # max value of cutoffs is <= (end date minus horizon) + end_date_minus_horizon = df['ds'].max() - horizon + if max(cutoffs) > end_date_minus_horizon: + raise ValueError("Maximum cutoff value is greater than end date minus horizon, no value for cross-validation remaining") + initial = cutoffs[0] - df['ds'].min() + + # Check if the initial window + # (that is, the amount of time between the start of the history and the first cutoff) + # is less than the maximum seasonality period + if initial < seasonality_dt: + msg = 'Seasonality has period of {} days '.format(period_max) + msg += 'which is larger than initial window. ' + msg += 'Consider increasing initial.' + logger.warning(msg) + + if parallel: + valid = {"threads", "processes", "dask"} + + if parallel == "threads": + pool = concurrent.futures.ThreadPoolExecutor() + elif parallel == "processes": + pool = concurrent.futures.ProcessPoolExecutor() + elif parallel == "dask": + try: + from dask.distributed import get_client + except ImportError as e: + raise ImportError("parallel='dask' requires the optional " + "dependency dask.") from e + pool = get_client() + # delay df and model to avoid large objects in task graph. + df, model = pool.scatter([df, model]) + elif hasattr(parallel, "map"): + pool = parallel + else: + msg = ("'parallel' should be one of {} for an instance with a " + "'map' method".format(', '.join(valid))) + raise ValueError(msg) + + iterables = ((df, model, cutoff, horizon, predict_columns) + for cutoff in cutoffs) + iterables = zip(*iterables) + + logger.info("Applying in parallel with %s", pool) + predicts = pool.map(single_cutoff_forecast, *iterables) + if parallel == "dask": + # convert Futures to DataFrames + predicts = pool.gather(predicts) + + else: + predicts = [ + single_cutoff_forecast(df, model, cutoff, horizon, predict_columns) + for cutoff in (tqdm(cutoffs) if not disable_tqdm else cutoffs) + ] + + # Combine all predicted pd.DataFrame into one pd.DataFrame + return pd.concat(predicts, axis=0).reset_index(drop=True) + + +def single_cutoff_forecast(df, model, cutoff, horizon, predict_columns): + """Forecast for single cutoff. Used in cross validation function + when evaluating for multiple cutoffs either sequentially or in parallel. + + Parameters + ---------- + df: pd.DataFrame. + DataFrame with history to be used for single + cutoff forecast. + model: Prophet model object. + cutoff: pd.Timestamp cutoff date. + Simulated Forecast will start from this date. + horizon: pd.Timedelta forecast horizon. + predict_columns: List of strings e.g. ['ds', 'yhat']. + Columns with date and forecast to be returned in output. + + Returns + ------- + A pd.DataFrame with the forecast, actual value and cutoff. + + """ + + # Generate new object with copying fitting options + m = prophet_copy(model, cutoff) + # Train model + history_c = df[df['ds'] <= cutoff] + if history_c.shape[0] < 2: + raise Exception( + 'Less than two datapoints before cutoff. ' + 'Increase initial window.' + ) + m.fit(history_c, **model.fit_kwargs) + # Calculate yhat + index_predicted = (df['ds'] > cutoff) & (df['ds'] <= cutoff + horizon) + # Get the columns for the future dataframe + columns = ['ds'] + if m.growth == 'logistic': + columns.append('cap') + if m.logistic_floor: + columns.append('floor') + columns.extend(m.extra_regressors.keys()) + columns.extend([ + props['condition_name'] + for props in m.seasonalities.values() + if props['condition_name'] is not None]) + yhat = m.predict(df[index_predicted][columns]) + # Merge yhat(predicts), y(df, original data) and cutoff + + m.stan_backend.cleanup() + + return pd.concat([ + yhat[predict_columns], + df[index_predicted][['y']].reset_index(drop=True), + pd.DataFrame({'cutoff': [cutoff] * len(yhat)}) + ], axis=1) + + +def prophet_copy(m, cutoff=None): + """Copy Prophet object + + Parameters + ---------- + m: Prophet model. + cutoff: pd.Timestamp or None, default None. + cutoff Timestamp for changepoints member variable. + changepoints are only retained if 'changepoints <= cutoff' + + Returns + ------- + Prophet class object with the same parameter with model variable + """ + if m.history is None: + raise Exception('This is for copying a fitted Prophet object.') + + if m.specified_changepoints: + changepoints = m.changepoints + if cutoff is not None: + # Filter change points '< cutoff' + last_history_date = max(m.history['ds'][m.history['ds'] <= cutoff]) + changepoints = changepoints[changepoints < last_history_date] + else: + changepoints = None + + # Auto seasonalities are set to False because they are already set in + # m.seasonalities. + m2 = m.__class__( + growth=m.growth, + n_changepoints=m.n_changepoints, + changepoint_range=m.changepoint_range, + changepoints=changepoints, + yearly_seasonality=False, + weekly_seasonality=False, + daily_seasonality=False, + holidays=m.holidays, + holidays_mode=m.holidays_mode, + seasonality_mode=m.seasonality_mode, + seasonality_prior_scale=m.seasonality_prior_scale, + changepoint_prior_scale=m.changepoint_prior_scale, + holidays_prior_scale=m.holidays_prior_scale, + mcmc_samples=m.mcmc_samples, + interval_width=m.interval_width, + uncertainty_samples=m.uncertainty_samples, + stan_backend=( + m.stan_backend.get_type() if m.stan_backend is not None + else None + ), + ) + m2.extra_regressors = deepcopy(m.extra_regressors) + m2.seasonalities = deepcopy(m.seasonalities) + m2.country_holidays = deepcopy(m.country_holidays) + return m2 + + +PERFORMANCE_METRICS=dict() +def register_performance_metric(func): + """Register custom performance metric + + Parameters that your metric should contain + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Registered metric should return following + ------- + Dataframe with columns horizon and metric. + """ + PERFORMANCE_METRICS[func.__name__] = func + return func + + +def performance_metrics(df, metrics=None, rolling_window=0.1, monthly=False): + """Compute performance metrics from cross-validation results. + + Computes a suite of performance metrics on the output of cross-validation. + By default, the following metrics are included: + 'mse': mean squared error + 'rmse': root mean squared error + 'mae': mean absolute error + 'mape': mean absolute percent error + 'mdape': median absolute percent error + 'smape': symmetric mean absolute percentage error + 'coverage': coverage of the upper and lower intervals + + A subset of these can be specified by passing a list of names as the + `metrics` argument. + + Metrics are calculated over a rolling window of cross validation + predictions, after sorting by horizon. Averaging is first done within each + value of horizon, and then across horizons as needed to reach the window + size. The size of that window (number of simulated forecast points) is + determined by the rolling_window argument, which specifies a proportion of + simulated forecast points to include in each window. rolling_window=0 will + compute it separately for each horizon. The default of rolling_window=0.1 + will use 10% of the rows in df in each window. rolling_window=1 will + compute the metric across all simulated forecast points. The results are + set to the right edge of the window. + + If rolling_window < 0, then metrics are computed at each datapoint with no + averaging (i.e., 'mse' will actually be squared error with no mean). + + The output is a dataframe containing column 'horizon' along with columns + for each of the metrics computed. + + Parameters + ---------- + df: The dataframe returned by cross_validation. + metrics: A list of performance metrics to compute. If not provided, will + use ['mse', 'rmse', 'mae', 'mape', 'mdape', 'smape', 'coverage']. + rolling_window: Proportion of data to use in each rolling window for + computing the metrics. Should be in [0, 1] to average. + monthly: monthly=True will compute horizons as numbers of calendar months + from the cutoff date, starting from 0 for the cutoff month. + + Returns + ------- + Dataframe with a column for each metric, and column 'horizon' + """ + valid_metrics = ['mse', 'rmse', 'mae', 'mape', 'mdape', 'smape', 'coverage'] + if metrics is None: + metrics = valid_metrics + if ('yhat_lower' not in df or 'yhat_upper' not in df) and ('coverage' in metrics): + metrics.remove('coverage') + if len(set(metrics)) != len(metrics): + raise ValueError('Input metrics must be a list of unique values') + if not set(metrics).issubset(set(PERFORMANCE_METRICS)): + raise ValueError( + 'Valid values for metrics are: {}'.format(valid_metrics) + ) + df_m = df.copy() + if monthly: + df_m['horizon'] = df_m['ds'].dt.to_period('M').astype(int) - df_m['cutoff'].dt.to_period('M').astype(int) + else: + df_m['horizon'] = df_m['ds'] - df_m['cutoff'] + df_m.sort_values('horizon', inplace=True) + if 'mape' in metrics and df_m['y'].abs().min() < 1e-8: + logger.info('Skipping MAPE because y close to 0') + metrics.remove('mape') + if len(metrics) == 0: + return None + w = int(rolling_window * df_m.shape[0]) + if w >= 0: + w = max(w, 1) + w = min(w, df_m.shape[0]) + # Compute all metrics + dfs = {} + for metric in metrics: + dfs[metric] = PERFORMANCE_METRICS[metric](df_m, w) + res = dfs[metrics[0]] + for i in range(1, len(metrics)): + res_m = dfs[metrics[i]] + assert np.array_equal(res['horizon'].values, res_m['horizon'].values) + res[metrics[i]] = res_m[metrics[i]] + return res + + +def rolling_mean_by_h(x, h, w, name): + """Compute a rolling mean of x, after first aggregating by h. + + Right-aligned. Computes a single mean for each unique value of h. Each + mean is over at least w samples. + + Parameters + ---------- + x: Array. + h: Array of horizon for each value in x. + w: Integer window size (number of elements). + name: Name for metric in result dataframe + + Returns + ------- + Dataframe with columns horizon and name, the rolling mean of x. + """ + # Aggregate over h + df = pd.DataFrame({'x': x, 'h': h}) + df2 = ( + df.groupby('h').agg(['sum', 'count']).reset_index().sort_values('h') + ) + xs = df2['x']['sum'].values + ns = df2['x']['count'].values + hs = df2.h.values + + trailing_i = len(df2) - 1 + x_sum = 0 + n_sum = 0 + # We don't know output size but it is bounded by len(df2) + res_x = np.empty(len(df2)) + + # Start from the right and work backwards + for i in range(len(df2) - 1, -1, -1): + x_sum += xs[i] + n_sum += ns[i] + while n_sum >= w: + # Include points from the previous horizon. All of them if still + # less than w, otherwise weight the mean by the difference + excess_n = n_sum - w + excess_x = excess_n * xs[i] / ns[i] + res_x[trailing_i] = (x_sum - excess_x)/ w + x_sum -= xs[trailing_i] + n_sum -= ns[trailing_i] + trailing_i -= 1 + + res_h = hs[(trailing_i + 1):] + res_x = res_x[(trailing_i + 1):] + + return pd.DataFrame({'horizon': res_h, name: res_x}) + + + +def rolling_median_by_h(x, h, w, name): + """Compute a rolling median of x, after first aggregating by h. + + Right-aligned. Computes a single median for each unique value of h. Each + median is over at least w samples. + + For each h where there are fewer than w samples, we take samples from the previous h, + moving backwards. (In other words, we ~ assume that the x's are shuffled within each h.) + + Parameters + ---------- + x: Array. + h: Array of horizon for each value in x. + w: Integer window size (number of elements). + name: Name for metric in result dataframe + + Returns + ------- + Dataframe with columns horizon and name, the rolling median of x. + """ + # Aggregate over h + df = pd.DataFrame({'x': x, 'h': h}) + grouped = df.groupby('h') + df2 = grouped.size().reset_index().sort_values('h') + hs = df2['h'] + + res_h = [] + res_x = [] + # Start from the right and work backwards + i = len(hs) - 1 + while i >= 0: + h_i = hs[i] + xs = grouped.get_group(h_i).x.tolist() + + # wrap in array so this works if h is pandas Series with custom index or numpy array + next_idx_to_add = np.array(h == h_i).argmax() - 1 + while (len(xs) < w) and (next_idx_to_add >= 0): + # Include points from the previous horizon. All of them if still + # less than w, otherwise just enough to get to w. + xs.append(x[next_idx_to_add]) + next_idx_to_add -= 1 + if len(xs) < w: + # Ran out of points before getting enough. + break + res_h.append(hs[i]) + res_x.append(np.median(xs)) + i -= 1 + res_h.reverse() + res_x.reverse() + return pd.DataFrame({'horizon': res_h, name: res_x}) + + +# The functions below specify performance metrics for cross-validation results. +# Each takes as input the output of cross_validation, and returns the statistic +# as a dataframe, given a window size for rolling aggregation. + + +@register_performance_metric +def mse(df, w): + """Mean squared error + + Parameters + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Returns + ------- + Dataframe with columns horizon and mse. + """ + se = (df['y'] - df['yhat']) ** 2 + if w < 0: + return pd.DataFrame({'horizon': df['horizon'], 'mse': se}) + return rolling_mean_by_h( + x=se.values, h=df['horizon'].values, w=w, name='mse' + ) + + +@register_performance_metric +def rmse(df, w): + """Root mean squared error + + Parameters + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Returns + ------- + Dataframe with columns horizon and rmse. + """ + res = mse(df, w) + res['mse'] = np.sqrt(res['mse']) + res.rename({'mse': 'rmse'}, axis='columns', inplace=True) + return res + + +@register_performance_metric +def mae(df, w): + """Mean absolute error + + Parameters + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Returns + ------- + Dataframe with columns horizon and mae. + """ + ae = np.abs(df['y'] - df['yhat']) + if w < 0: + return pd.DataFrame({'horizon': df['horizon'], 'mae': ae}) + return rolling_mean_by_h( + x=ae.values, h=df['horizon'].values, w=w, name='mae' + ) + + +@register_performance_metric +def mape(df, w): + """Mean absolute percent error + + Parameters + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Returns + ------- + Dataframe with columns horizon and mape. + """ + ape = np.abs((df['y'] - df['yhat']) / df['y']) + if w < 0: + return pd.DataFrame({'horizon': df['horizon'], 'mape': ape}) + return rolling_mean_by_h( + x=ape.values, h=df['horizon'].values, w=w, name='mape' + ) + + +@register_performance_metric +def mdape(df, w): + """Median absolute percent error + + Parameters + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Returns + ------- + Dataframe with columns horizon and mdape. + """ + ape = np.abs((df['y'] - df['yhat']) / df['y']) + if w < 0: + return pd.DataFrame({'horizon': df['horizon'], 'mdape': ape}) + return rolling_median_by_h( + x=ape.values, h=df['horizon'], w=w, name='mdape' + ) + + +@register_performance_metric +def smape(df, w): + """Symmetric mean absolute percentage error + based on Chen and Yang (2004) formula + + Parameters + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Returns + ------- + Dataframe with columns horizon and smape. + """ + sape = np.abs(df['y'] - df['yhat']) / ((np.abs(df['y']) + np.abs(df['yhat'])) / 2) + sape = sape.fillna(0) + if w < 0: + return pd.DataFrame({'horizon': df['horizon'], 'smape': sape}) + return rolling_mean_by_h( + x=sape.values, h=df['horizon'].values, w=w, name='smape' + ) + + +@register_performance_metric +def coverage(df, w): + """Coverage + + Parameters + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Returns + ------- + Dataframe with columns horizon and coverage. + """ + is_covered = (df['y'] >= df['yhat_lower']) & (df['y'] <= df['yhat_upper']) + if w < 0: + return pd.DataFrame({'horizon': df['horizon'], 'coverage': is_covered}) + return rolling_mean_by_h( + x=is_covered.values, h=df['horizon'].values, w=w, name='coverage' + ) diff --git a/.venv/lib/python3.12/site-packages/prophet/forecaster.py b/.venv/lib/python3.12/site-packages/prophet/forecaster.py new file mode 100644 index 00000000..ec728c9f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/forecaster.py @@ -0,0 +1,1939 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from __future__ import absolute_import, division, print_function + +import dataclasses +import logging +from collections import OrderedDict, defaultdict +from copy import deepcopy +from datetime import timedelta +from typing import Dict, List, Union + +import numpy as np +import pandas as pd +from numpy.typing import NDArray + +from prophet.make_holidays import get_holiday_names, make_holidays_df +from prophet.models import StanBackendEnum, ModelInputData, ModelParams, TrendIndicator, IStanBackend +from prophet.plot import (plot, plot_components) + +logger = logging.getLogger('prophet') +logger.setLevel(logging.INFO) +NANOSECONDS_TO_SECONDS = 1000 * 1000 * 1000 + +class Prophet(object): + stan_backend: IStanBackend + + """Prophet forecaster. + + Parameters + ---------- + growth: String 'linear', 'logistic' or 'flat' to specify a linear, logistic or + flat trend. + changepoints: List of dates at which to include potential changepoints. If + not specified, potential changepoints are selected automatically. + n_changepoints: Number of potential changepoints to include. Not used + if input `changepoints` is supplied. If `changepoints` is not supplied, + then n_changepoints potential changepoints are selected uniformly from + the first `changepoint_range` proportion of the history. + changepoint_range: Proportion of history in which trend changepoints will + be estimated. Defaults to 0.8 for the first 80%. Not used if + `changepoints` is specified. + yearly_seasonality: Fit yearly seasonality. + Can be 'auto', True, False, or a number of Fourier terms to generate. + weekly_seasonality: Fit weekly seasonality. + Can be 'auto', True, False, or a number of Fourier terms to generate. + daily_seasonality: Fit daily seasonality. + Can be 'auto', True, False, or a number of Fourier terms to generate. + holidays: pd.DataFrame with columns holiday (string) and ds (date type) + and optionally columns lower_window and upper_window which specify a + range of days around the date to be included as holidays. + lower_window=-2 will include 2 days prior to the date as holidays. Also + optionally can have a column prior_scale specifying the prior scale for + that holiday. + seasonality_mode: 'additive' (default) or 'multiplicative'. + seasonality_prior_scale: Parameter modulating the strength of the + seasonality model. Larger values allow the model to fit larger seasonal + fluctuations, smaller values dampen the seasonality. Can be specified + for individual seasonalities using add_seasonality. + holidays_prior_scale: Parameter modulating the strength of the holiday + components model, unless overridden in the holidays input. + changepoint_prior_scale: Parameter modulating the flexibility of the + automatic changepoint selection. Large values will allow many + changepoints, small values will allow few changepoints. + mcmc_samples: Integer, if greater than 0, will do full Bayesian inference + with the specified number of MCMC samples. If 0, will do MAP + estimation. + interval_width: Float, width of the uncertainty intervals provided + for the forecast. If mcmc_samples=0, this will be only the uncertainty + in the trend using the MAP estimate of the extrapolated generative + model. If mcmc.samples>0, this will be integrated over all model + parameters, which will include uncertainty in seasonality. + uncertainty_samples: Number of simulated draws used to estimate + uncertainty intervals. Settings this value to 0 or False will disable + uncertainty estimation and speed up the calculation. + stan_backend: str as defined in StanBackendEnum default: None - will try to + iterate over all available backends and find the working one. + scaling: 'absmax' (default) or 'minmax'. + holidays_mode: 'additive' or 'multiplicative'. Defaults to seasonality_mode. + """ + + def __init__( + self, + growth='linear', + changepoints=None, + n_changepoints=25, + changepoint_range=0.8, + yearly_seasonality='auto', + weekly_seasonality='auto', + daily_seasonality='auto', + holidays=None, + seasonality_mode='additive', + seasonality_prior_scale=10.0, + holidays_prior_scale=10.0, + changepoint_prior_scale=0.05, + mcmc_samples=0, + interval_width=0.80, + uncertainty_samples=1000, + stan_backend=None, + scaling: str = 'absmax', + holidays_mode=None, + ): + self.growth = growth + + self.changepoints = changepoints + if self.changepoints is not None: + self.changepoints = pd.Series(pd.to_datetime(self.changepoints), name='ds') + self.n_changepoints = len(self.changepoints) + self.specified_changepoints = True + else: + self.n_changepoints = n_changepoints + self.specified_changepoints = False + + self.changepoint_range = changepoint_range + self.yearly_seasonality = yearly_seasonality + self.weekly_seasonality = weekly_seasonality + self.daily_seasonality = daily_seasonality + self.holidays = holidays + + self.seasonality_mode = seasonality_mode + self.holidays_mode = holidays_mode + if holidays_mode is None: + self.holidays_mode = self.seasonality_mode + + self.seasonality_prior_scale = float(seasonality_prior_scale) + self.changepoint_prior_scale = float(changepoint_prior_scale) + self.holidays_prior_scale = float(holidays_prior_scale) + + self.mcmc_samples = mcmc_samples + self.interval_width = interval_width + self.uncertainty_samples = uncertainty_samples + if scaling not in ("absmax", "minmax"): + raise ValueError("scaling must be one of 'absmax' or 'minmax'") + self.scaling = scaling + + # Set during fitting or by other methods + self.start = None + self.y_min = None + self.y_scale = None + self.logistic_floor = False + self.t_scale = None + self.changepoints_t = None + self.seasonalities = OrderedDict({}) + self.extra_regressors = OrderedDict({}) + self.country_holidays = None + self.stan_fit = None + self.params = {} + self.history = None + self.history_dates = None + self.train_component_cols = None + self.component_modes = None + self.train_holiday_names = None + self.fit_kwargs = {} + self.validate_inputs() + self._load_stan_backend(stan_backend) + + def _load_stan_backend(self, stan_backend): + if stan_backend is None: + for i in StanBackendEnum: + try: + logger.debug("Trying to load backend: %s", i.name) + return self._load_stan_backend(i.name) + except Exception as e: + logger.debug("Unable to load backend %s (%s), trying the next one", i.name, e) + else: + self.stan_backend = StanBackendEnum.get_backend_class(stan_backend)() + + logger.debug("Loaded stan backend: %s", self.stan_backend.get_type()) + + def validate_inputs(self): + """Validates the inputs to Prophet.""" + if self.growth not in ('linear', 'logistic', 'flat'): + raise ValueError( + 'Parameter "growth" should be "linear", "logistic" or "flat".') + if not isinstance(self.changepoint_range, (int, float)): + raise ValueError("changepoint_range must be a number in [0, 1]'") + if ((self.changepoint_range < 0) or (self.changepoint_range > 1)): + raise ValueError('Parameter "changepoint_range" must be in [0, 1]') + if self.holidays is not None: + if not ( + isinstance(self.holidays, pd.DataFrame) + and 'ds' in self.holidays # noqa W503 + and 'holiday' in self.holidays # noqa W503 + ): + raise ValueError('holidays must be a DataFrame with "ds" and ' + '"holiday" columns.') + self.holidays['ds'] = pd.to_datetime(self.holidays['ds']) + if ( + self.holidays['ds'].isnull().any() + or self.holidays['holiday'].isnull().any() + ): + raise ValueError('Found a NaN in holidays dataframe.') + has_lower = 'lower_window' in self.holidays + has_upper = 'upper_window' in self.holidays + if has_lower + has_upper == 1: + raise ValueError('Holidays must have both lower_window and ' + + 'upper_window, or neither') + if has_lower: + if self.holidays['lower_window'].max() > 0: + raise ValueError('Holiday lower_window should be <= 0') + if self.holidays['upper_window'].min() < 0: + raise ValueError('Holiday upper_window should be >= 0') + for h in self.holidays['holiday'].unique(): + self.validate_column_name(h, check_holidays=False) + if self.seasonality_mode not in ['additive', 'multiplicative']: + raise ValueError( + 'seasonality_mode must be "additive" or "multiplicative"' + ) + if self.holidays_mode not in ['additive', 'multiplicative']: + raise ValueError( + 'holidays_mode must be "additive" or "multiplicative"' + ) + + def validate_column_name(self, name, check_holidays=True, + check_seasonalities=True, check_regressors=True): + """Validates the name of a seasonality, holiday, or regressor. + + Parameters + ---------- + name: string + check_holidays: bool check if name already used for holiday + check_seasonalities: bool check if name already used for seasonality + check_regressors: bool check if name already used for regressor + """ + if '_delim_' in name: + raise ValueError('Name cannot contain "_delim_"') + reserved_names = [ + 'trend', 'additive_terms', 'daily', 'weekly', 'yearly', + 'holidays', 'zeros', 'extra_regressors_additive', 'yhat', + 'extra_regressors_multiplicative', 'multiplicative_terms', + ] + rn_l = [n + '_lower' for n in reserved_names] + rn_u = [n + '_upper' for n in reserved_names] + reserved_names.extend(rn_l) + reserved_names.extend(rn_u) + reserved_names.extend([ + 'ds', 'y', 'cap', 'floor', 'y_scaled', 'cap_scaled']) + if name in reserved_names: + raise ValueError( + 'Name {name!r} is reserved.'.format(name=name) + ) + if (check_holidays and self.holidays is not None and + name in self.holidays['holiday'].unique()): + raise ValueError( + 'Name {name!r} already used for a holiday.'.format(name=name) + ) + if (check_holidays and self.country_holidays is not None and + name in get_holiday_names(self.country_holidays)): + raise ValueError( + 'Name {name!r} is a holiday name in {country_holidays}.' + .format(name=name, country_holidays=self.country_holidays) + ) + if check_seasonalities and name in self.seasonalities: + raise ValueError( + 'Name {name!r} already used for a seasonality.' + .format(name=name) + ) + if check_regressors and name in self.extra_regressors: + raise ValueError( + 'Name {name!r} already used for an added regressor.' + .format(name=name) + ) + + def setup_dataframe(self, df, initialize_scales=False): + """Prepare dataframe for fitting or predicting. + + Adds a time index and scales y. Creates auxiliary columns 't', 't_ix', + 'y_scaled', and 'cap_scaled'. These columns are used during both + fitting and predicting. + + Parameters + ---------- + df: pd.DataFrame with columns ds, y, and cap if logistic growth. Any + specified additional regressors must also be present. + initialize_scales: Boolean set scaling factors in self from df. + + Returns + ------- + pd.DataFrame prepared for fitting or predicting. + """ + if 'y' in df: # 'y' will be in training data + df['y'] = pd.to_numeric(df['y']) + if np.isinf(df['y'].values).any(): + raise ValueError('Found infinity in column y.') + if df['ds'].dtype == np.int64: + df['ds'] = df['ds'].astype(str) + df['ds'] = pd.to_datetime(df['ds']) + if df['ds'].dt.tz is not None: + raise ValueError( + 'Column ds has timezone specified, which is not supported. ' + 'Remove timezone.' + ) + if df['ds'].isnull().any(): + raise ValueError('Found NaN in column ds.') + for name in self.extra_regressors: + if name not in df: + raise ValueError( + 'Regressor {name!r} missing from dataframe' + .format(name=name) + ) + df[name] = pd.to_numeric(df[name]) + if df[name].isnull().any(): + raise ValueError( + 'Found NaN in column {name!r}'.format(name=name) + ) + for props in self.seasonalities.values(): + condition_name = props['condition_name'] + if condition_name is not None: + if condition_name not in df: + raise ValueError( + 'Condition {condition_name!r} missing from dataframe' + .format(condition_name=condition_name) + ) + if not df[condition_name].isin([True, False]).all(): + raise ValueError( + 'Found non-boolean in column {condition_name!r}' + .format(condition_name=condition_name) + ) + df[condition_name] = df[condition_name].astype('bool') + + if df.index.name == 'ds': + df.index.name = None + df = df.sort_values('ds', kind='mergesort') + df = df.reset_index(drop=True) + + self.initialize_scales(initialize_scales, df) + + if self.logistic_floor: + if 'floor' not in df: + raise ValueError('Expected column "floor".') + else: + if self.scaling == "absmax": + df['floor'] = 0. + elif self.scaling == "minmax": + df['floor'] = self.y_min + if self.growth == 'logistic': + if 'cap' not in df: + raise ValueError( + 'Capacities must be supplied for logistic growth in ' + 'column "cap"' + ) + if (df['cap'] <= df['floor']).any(): + raise ValueError( + 'cap must be greater than floor (which defaults to 0).' + ) + df['cap_scaled'] = (df['cap'] - df['floor']) / self.y_scale + + df['t'] = (df['ds'] - self.start) / self.t_scale + if 'y' in df: + df['y_scaled'] = (df['y'] - df['floor']) / self.y_scale + + for name, props in self.extra_regressors.items(): + df[name] = ((df[name] - props['mu']) / props['std']) + return df + + def initialize_scales(self, initialize_scales, df): + """Initialize model scales. + + Sets model scaling factors using df. + + Parameters + ---------- + initialize_scales: Boolean set the scales or not. + df: pd.DataFrame for setting scales. + """ + if not initialize_scales: + return + + if self.growth == 'logistic' and 'floor' in df: + self.logistic_floor = True + if self.scaling == "absmax": + self.y_min = float((df['y'] - df['floor']).abs().min()) + self.y_scale = float((df['y'] - df['floor']).abs().max()) + elif self.scaling == "minmax": + self.y_min = df['floor'].min() + self.y_scale = float(df['cap'].max() - self.y_min) + else: + if self.scaling == "absmax": + self.y_min = 0. + self.y_scale = float((df['y']).abs().max()) + elif self.scaling == "minmax": + self.y_min = df['y'].min() + self.y_scale = float(df['y'].max() - self.y_min) + if self.y_scale == 0: + self.y_scale = 1.0 + + self.start = df['ds'].min() + self.t_scale = df['ds'].max() - self.start + for name, props in self.extra_regressors.items(): + standardize = props['standardize'] + n_vals = len(df[name].unique()) + if n_vals < 2: + standardize = False + if standardize == 'auto': + if set(df[name].unique()) == {1, 0}: + standardize = False # Don't standardize binary variables. + else: + standardize = True + if standardize: + mu = float(df[name].mean()) + std = float(df[name].std()) + self.extra_regressors[name]['mu'] = mu + self.extra_regressors[name]['std'] = std + + def set_changepoints(self): + """Set changepoints + + Sets m$changepoints to the dates of changepoints. Either: + 1) The changepoints were passed in explicitly. + A) They are empty. + B) They are not empty, and need validation. + 2) We are generating a grid of them. + 3) The user prefers no changepoints be used. + """ + if self.changepoints is not None: + if len(self.changepoints) == 0: + pass + else: + too_low = min(self.changepoints) < self.history['ds'].min() + too_high = max(self.changepoints) > self.history['ds'].max() + if too_low or too_high: + raise ValueError( + 'Changepoints must fall within training data.') + else: + # Place potential changepoints evenly through first + # `changepoint_range` proportion of the history + hist_size = int(np.floor(self.history.shape[0] + * self.changepoint_range)) + if self.n_changepoints + 1 > hist_size: + self.n_changepoints = hist_size - 1 + logger.info( + 'n_changepoints greater than number of observations. ' + 'Using {n_changepoints}.' + .format(n_changepoints=self.n_changepoints) + ) + if self.n_changepoints > 0: + cp_indexes = ( + np.linspace(0, hist_size - 1, self.n_changepoints + 1) + .round() + .astype(int) + ) + self.changepoints = ( + self.history.iloc[cp_indexes]['ds'].tail(-1) + ) + else: + # set empty changepoints + self.changepoints = pd.Series(pd.to_datetime([]), name='ds') + if len(self.changepoints) > 0: + self.changepoints_t = np.sort(np.array( + (self.changepoints - self.start) / self.t_scale)) + else: + self.changepoints_t = np.array([0]) # dummy changepoint + + @staticmethod + def fourier_series( + dates: pd.Series, + period: Union[int, float], + series_order: int, + ) -> NDArray[np.float64]: + """Provides Fourier series components with the specified frequency + and order. + + Parameters + ---------- + dates: pd.Series containing timestamps. + period: Number of days of the period. + series_order: Number of components. + + Returns + ------- + Matrix with seasonality features. + """ + if not (series_order >= 1): + raise ValueError("series_order must be >= 1") + + # convert to days since epoch + t = dates.to_numpy(dtype=np.int64) // NANOSECONDS_TO_SECONDS / (3600 * 24.) + + x_T = t * np.pi * 2 + fourier_components = np.empty((dates.shape[0], 2 * series_order)) + for i in range(series_order): + c = x_T * (i + 1) / period + fourier_components[:, 2 * i] = np.sin(c) + fourier_components[:, (2 * i) + 1] = np.cos(c) + return fourier_components + + @classmethod + def make_seasonality_features(cls, dates, period, series_order, prefix): + """Data frame with seasonality features. + + Parameters + ---------- + cls: Prophet class. + dates: pd.Series containing timestamps. + period: Number of days of the period. + series_order: Number of components. + prefix: Column name prefix. + + Returns + ------- + pd.DataFrame with seasonality features. + """ + features = cls.fourier_series(dates, period, series_order) + columns = [ + '{}_delim_{}'.format(prefix, i + 1) + for i in range(features.shape[1]) + ] + return pd.DataFrame(features, columns=columns) + + def construct_holiday_dataframe(self, dates): + """Construct a dataframe of holiday dates. + + Will combine self.holidays with the built-in country holidays + corresponding to input dates, if self.country_holidays is set. + + Parameters + ---------- + dates: pd.Series containing timestamps used for computing seasonality. + + Returns + ------- + dataframe of holiday dates, in holiday dataframe format used in + initialization. + """ + all_holidays = pd.DataFrame() + if self.holidays is not None: + all_holidays = self.holidays.copy() + if self.country_holidays is not None: + year_list = list({x.year for x in dates}) + country_holidays_df = make_holidays_df( + year_list=year_list, country=self.country_holidays + ) + all_holidays = pd.concat((all_holidays, country_holidays_df), + sort=False) + all_holidays.reset_index(drop=True, inplace=True) + # Drop future holidays not previously seen in training data + if self.train_holiday_names is not None: + # Remove holiday names didn't show up in fit + index_to_drop = all_holidays.index[ + np.logical_not( + all_holidays.holiday.isin(self.train_holiday_names) + ) + ] + all_holidays = all_holidays.drop(index_to_drop) + # Add holiday names in fit but not in predict with ds as NA + holidays_to_add = pd.DataFrame({ + 'holiday': self.train_holiday_names[ + np.logical_not(self.train_holiday_names + .isin(all_holidays.holiday)) + ] + }) + all_holidays = pd.concat((all_holidays, holidays_to_add), + sort=False) + all_holidays.reset_index(drop=True, inplace=True) + return all_holidays + + def make_holiday_features(self, dates, holidays): + """Construct a dataframe of holiday features. + + Parameters + ---------- + dates: pd.Series containing timestamps used for computing seasonality. + holidays: pd.Dataframe containing holidays, as returned by + construct_holiday_dataframe. + + Returns + ------- + holiday_features: pd.DataFrame with a column for each holiday. + prior_scale_list: List of prior scales for each holiday column. + holiday_names: List of names of holidays + """ + # Holds columns of our future matrix. + expanded_holidays = defaultdict(lambda: np.zeros(dates.shape[0])) + prior_scales = {} + # Makes an index so we can perform `get_loc` below. + # Strip to just dates. + row_index = pd.DatetimeIndex(dates.dt.date) + + for row in holidays.itertuples(): + dt = row.ds.date() + try: + lw = int(getattr(row, 'lower_window', 0)) + uw = int(getattr(row, 'upper_window', 0)) + except ValueError: + lw = 0 + uw = 0 + ps = float(getattr(row, 'prior_scale', self.holidays_prior_scale)) + if np.isnan(ps): + ps = float(self.holidays_prior_scale) + if row.holiday in prior_scales and prior_scales[row.holiday] != ps: + raise ValueError( + 'Holiday {holiday!r} does not have consistent prior ' + 'scale specification.'.format(holiday=row.holiday) + ) + if ps <= 0: + raise ValueError('Prior scale must be > 0') + prior_scales[row.holiday] = ps + + for offset in range(lw, uw + 1): + occurrence = pd.to_datetime(dt + timedelta(days=offset)) + try: + loc = row_index.get_loc(occurrence) + except KeyError: + loc = None + key = '{}_delim_{}{}'.format( + row.holiday, + '+' if offset >= 0 else '-', + abs(offset) + ) + if loc is not None: + expanded_holidays[key][loc] = 1. + else: + expanded_holidays[key] # Access key to generate value + holiday_features = pd.DataFrame(expanded_holidays) + # Make sure column order is consistent + holiday_features = holiday_features[sorted(holiday_features.columns + .tolist())] + prior_scale_list = [ + prior_scales[h.split('_delim_')[0]] + for h in holiday_features.columns + ] + holiday_names = list(prior_scales.keys()) + # Store holiday names used in fit + if self.train_holiday_names is None: + self.train_holiday_names = pd.Series(holiday_names) + return holiday_features, prior_scale_list, holiday_names + + def add_regressor(self, name, prior_scale=None, standardize='auto', + mode=None): + """Add an additional regressor to be used for fitting and predicting. + + The dataframe passed to `fit` and `predict` will have a column with the + specified name to be used as a regressor. When standardize='auto', the + regressor will be standardized unless it is binary. The regression + coefficient is given a prior with the specified scale parameter. + Decreasing the prior scale will add additional regularization. If no + prior scale is provided, self.holidays_prior_scale will be used. + Mode can be specified as either 'additive' or 'multiplicative'. If not + specified, self.seasonality_mode will be used. 'additive' means the + effect of the regressor will be added to the trend, 'multiplicative' + means it will multiply the trend. + + Parameters + ---------- + name: string name of the regressor. + prior_scale: optional float scale for the normal prior. If not + provided, self.holidays_prior_scale will be used. + standardize: optional, specify whether this regressor will be + standardized prior to fitting. Can be 'auto' (standardize if not + binary), True, or False. + mode: optional, 'additive' or 'multiplicative'. Defaults to + self.seasonality_mode. + + Returns + ------- + The prophet object. + """ + if self.history is not None: + raise Exception( + "Regressors must be added prior to model fitting.") + self.validate_column_name(name, check_regressors=False) + if prior_scale is None: + prior_scale = float(self.holidays_prior_scale) + if mode is None: + mode = self.seasonality_mode + if prior_scale <= 0: + raise ValueError('Prior scale must be > 0') + if mode not in ['additive', 'multiplicative']: + raise ValueError("mode must be 'additive' or 'multiplicative'") + self.extra_regressors[name] = { + 'prior_scale': prior_scale, + 'standardize': standardize, + 'mu': 0., + 'std': 1., + 'mode': mode, + } + return self + + def add_seasonality(self, name, period, fourier_order, prior_scale=None, + mode=None, condition_name=None): + """Add a seasonal component with specified period, number of Fourier + components, and prior scale. + + Increasing the number of Fourier components allows the seasonality to + change more quickly (at risk of overfitting). Default values for yearly + and weekly seasonalities are 10 and 3 respectively. + + Increasing prior scale will allow this seasonality component more + flexibility, decreasing will dampen it. If not provided, will use the + seasonality_prior_scale provided on Prophet initialization (defaults + to 10). + + Mode can be specified as either 'additive' or 'multiplicative'. If not + specified, self.seasonality_mode will be used (defaults to additive). + Additive means the seasonality will be added to the trend, + multiplicative means it will multiply the trend. + + If condition_name is provided, the dataframe passed to `fit` and + `predict` should have a column with the specified condition_name + containing booleans which decides when to apply seasonality. + + Parameters + ---------- + name: string name of the seasonality component. + period: float number of days in one period. + fourier_order: int number of Fourier components to use. + prior_scale: optional float prior scale for this component. + mode: optional 'additive' or 'multiplicative' + condition_name: string name of the seasonality condition. + + Returns + ------- + The prophet object. + """ + if self.history is not None: + raise Exception( + 'Seasonality must be added prior to model fitting.') + if name not in ['daily', 'weekly', 'yearly']: + # Allow overwriting built-in seasonalities + self.validate_column_name(name, check_seasonalities=False) + if prior_scale is None: + ps = self.seasonality_prior_scale + else: + ps = float(prior_scale) + if ps <= 0: + raise ValueError('Prior scale must be > 0') + if fourier_order <= 0: + raise ValueError('Fourier Order must be > 0') + if mode is None: + mode = self.seasonality_mode + if mode not in ['additive', 'multiplicative']: + raise ValueError('mode must be "additive" or "multiplicative"') + if condition_name is not None: + self.validate_column_name(condition_name) + self.seasonalities[name] = { + 'period': period, + 'fourier_order': fourier_order, + 'prior_scale': ps, + 'mode': mode, + 'condition_name': condition_name, + } + return self + + def add_country_holidays(self, country_name): + """Add in built-in holidays for the specified country. + + These holidays will be included in addition to any specified on model + initialization. + + Holidays will be calculated for arbitrary date ranges in the history + and future. See the online documentation for the list of countries with + built-in holidays. + + Built-in country holidays can only be set for a single country. + + Parameters + ---------- + country_name: Name of the country, like 'UnitedStates' or 'US' + + Returns + ------- + The prophet object. + """ + if self.history is not None: + raise Exception( + "Country holidays must be added prior to model fitting." + ) + # Validate names. + for name in get_holiday_names(country_name): + # Allow merging with existing holidays + self.validate_column_name(name, check_holidays=False) + # Set the holidays. + if self.country_holidays is not None: + logger.warning( + 'Changing country holidays from {country_holidays!r} to ' + '{country_name!r}.' + .format( + country_holidays=self.country_holidays, + country_name=country_name, + ) + ) + self.country_holidays = country_name + return self + + def make_all_seasonality_features(self, df): + """Dataframe with seasonality features. + + Includes seasonality features, holiday features, and added regressors. + + Parameters + ---------- + df: pd.DataFrame with dates for computing seasonality features and any + added regressors. + + Returns + ------- + pd.DataFrame with regression features. + list of prior scales for each column of the features dataframe. + Dataframe with indicators for which regression components correspond to + which columns. + Dictionary with keys 'additive' and 'multiplicative' listing the + component names for each mode of seasonality. + """ + seasonal_features = [] + prior_scales = [] + modes = {'additive': [], 'multiplicative': []} + + # Seasonality features + for name, props in self.seasonalities.items(): + features = self.make_seasonality_features( + df['ds'], + props['period'], + props['fourier_order'], + name, + ) + if props['condition_name'] is not None: + features[~df[props['condition_name']]] = 0 + seasonal_features.append(features) + prior_scales.extend( + [props['prior_scale']] * features.shape[1]) + modes[props['mode']].append(name) + + # Holiday features + holidays = self.construct_holiday_dataframe(df['ds']) + if len(holidays) > 0: + features, holiday_priors, holiday_names = ( + self.make_holiday_features(df['ds'], holidays) + ) + seasonal_features.append(features) + prior_scales.extend(holiday_priors) + modes[self.holidays_mode].extend(holiday_names) + + # Additional regressors + for name, props in self.extra_regressors.items(): + seasonal_features.append(pd.DataFrame(df[name])) + prior_scales.append(props['prior_scale']) + modes[props['mode']].append(name) + + # Dummy to prevent empty X + if len(seasonal_features) == 0: + seasonal_features.append( + pd.DataFrame({'zeros': np.zeros(df.shape[0])})) + prior_scales.append(1.) + + seasonal_features = pd.concat(seasonal_features, axis=1) + component_cols, modes = self.regressor_column_matrix( + seasonal_features, modes + ) + return seasonal_features, prior_scales, component_cols, modes + + def regressor_column_matrix(self, seasonal_features, modes): + """Dataframe indicating which columns of the feature matrix correspond + to which seasonality/regressor components. + + Includes combination components, like 'additive_terms'. These + combination components will be added to the 'modes' input. + + Parameters + ---------- + seasonal_features: Constructed seasonal features dataframe + modes: Dictionary with keys 'additive' and 'multiplicative' listing the + component names for each mode of seasonality. + + Returns + ------- + component_cols: A binary indicator dataframe with columns seasonal + components and rows columns in seasonal_features. Entry is 1 if + that columns is used in that component. + modes: Updated input with combination components. + """ + components = pd.DataFrame({ + 'col': np.arange(seasonal_features.shape[1]), + 'component': [ + x.split('_delim_')[0] for x in seasonal_features.columns + ], + }) + # Add total for holidays + if self.train_holiday_names is not None: + components = self.add_group_component( + components, 'holidays', self.train_holiday_names.unique()) + # Add totals additive and multiplicative components, and regressors + for mode in ['additive', 'multiplicative']: + components = self.add_group_component( + components, mode + '_terms', modes[mode] + ) + regressors_by_mode = [ + r for r, props in self.extra_regressors.items() + if props['mode'] == mode + ] + components = self.add_group_component( + components, 'extra_regressors_' + mode, regressors_by_mode) + # Add combination components to modes + modes[mode].append(mode + '_terms') + modes[mode].append('extra_regressors_' + mode) + # After all of the additive/multiplicative groups have been added, + modes[self.holidays_mode].append('holidays') + # Convert to a binary matrix + component_cols = pd.crosstab( + components['col'], components['component'], + ).sort_index(level='col') + # Add columns for additive and multiplicative terms, if missing + for name in ['additive_terms', 'multiplicative_terms']: + if name not in component_cols: + component_cols[name] = 0 + # Remove the placeholder + component_cols.drop('zeros', axis=1, inplace=True, errors='ignore') + # Validation + if (max(component_cols['additive_terms'] + + component_cols['multiplicative_terms']) > 1): + raise Exception('A bug occurred in seasonal components.') + # Compare to the training, if set. + if self.train_component_cols is not None: + component_cols = component_cols[self.train_component_cols.columns] + if not component_cols.equals(self.train_component_cols): + raise Exception('A bug occurred in constructing regressors.') + return component_cols, modes + + def add_group_component(self, components, name, group): + """Adds a component with given name that contains all of the components + in group. + + Parameters + ---------- + components: Dataframe with components. + name: Name of new group component. + group: List of components that form the group. + + Returns + ------- + Dataframe with components. + """ + new_comp = components[components['component'].isin(set(group))].copy() + group_cols = new_comp['col'].unique() + if len(group_cols) > 0: + new_comp = pd.DataFrame({'col': group_cols, 'component': name}) + components = pd.concat([components, new_comp]) + return components + + def parse_seasonality_args(self, name, arg, auto_disable, default_order): + """Get number of fourier components for built-in seasonalities. + + Parameters + ---------- + name: string name of the seasonality component. + arg: 'auto', True, False, or number of fourier components as provided. + auto_disable: bool if seasonality should be disabled when 'auto'. + default_order: int default fourier order + + Returns + ------- + Number of fourier components, or 0 for disabled. + """ + if arg == 'auto': + fourier_order = 0 + if name in self.seasonalities: + logger.info( + 'Found custom seasonality named {name!r}, disabling ' + 'built-in {name!r} seasonality.'.format(name=name) + ) + elif auto_disable: + logger.info( + 'Disabling {name} seasonality. Run prophet with ' + '{name}_seasonality=True to override this.' + .format(name=name) + ) + else: + fourier_order = default_order + elif arg is True: + fourier_order = default_order + elif arg is False: + fourier_order = 0 + else: + fourier_order = int(arg) + return fourier_order + + def set_auto_seasonalities(self): + """Set seasonalities that were left on auto. + + Turns on yearly seasonality if there is >=2 years of history. + Turns on weekly seasonality if there is >=2 weeks of history, and the + spacing between dates in the history is <7 days. + Turns on daily seasonality if there is >=2 days of history, and the + spacing between dates in the history is <1 day. + """ + first = self.history['ds'].min() + last = self.history['ds'].max() + dt = self.history['ds'].diff() + min_dt = dt.iloc[dt.values.nonzero()[0]].min() + + # Yearly seasonality + yearly_disable = last - first < pd.Timedelta(days=730) + fourier_order = self.parse_seasonality_args( + 'yearly', self.yearly_seasonality, yearly_disable, 10) + if fourier_order > 0: + self.seasonalities['yearly'] = { + 'period': 365.25, + 'fourier_order': fourier_order, + 'prior_scale': self.seasonality_prior_scale, + 'mode': self.seasonality_mode, + 'condition_name': None + } + + # Weekly seasonality + weekly_disable = ((last - first < pd.Timedelta(weeks=2)) or + (min_dt >= pd.Timedelta(weeks=1))) + fourier_order = self.parse_seasonality_args( + 'weekly', self.weekly_seasonality, weekly_disable, 3) + if fourier_order > 0: + self.seasonalities['weekly'] = { + 'period': 7, + 'fourier_order': fourier_order, + 'prior_scale': self.seasonality_prior_scale, + 'mode': self.seasonality_mode, + 'condition_name': None + } + + # Daily seasonality + daily_disable = ((last - first < pd.Timedelta(days=2)) or + (min_dt >= pd.Timedelta(days=1))) + fourier_order = self.parse_seasonality_args( + 'daily', self.daily_seasonality, daily_disable, 4) + if fourier_order > 0: + self.seasonalities['daily'] = { + 'period': 1, + 'fourier_order': fourier_order, + 'prior_scale': self.seasonality_prior_scale, + 'mode': self.seasonality_mode, + 'condition_name': None + } + + @staticmethod + def linear_growth_init(df): + """Initialize linear growth. + + Provides a strong initialization for linear growth by calculating the + growth and offset parameters that pass the function through the first + and last points in the time series. + + Parameters + ---------- + df: pd.DataFrame with columns ds (date), y_scaled (scaled time series), + and t (scaled time). + + Returns + ------- + A tuple (k, m) with the rate (k) and offset (m) of the linear growth + function. + """ + i0, i1 = df['ds'].idxmin(), df['ds'].idxmax() + T = df['t'].iloc[i1] - df['t'].iloc[i0] + k = (df['y_scaled'].iloc[i1] - df['y_scaled'].iloc[i0]) / T + m = df['y_scaled'].iloc[i0] - k * df['t'].iloc[i0] + return (k, m) + + @staticmethod + def logistic_growth_init(df): + """Initialize logistic growth. + + Provides a strong initialization for logistic growth by calculating the + growth and offset parameters that pass the function through the first + and last points in the time series. + + Parameters + ---------- + df: pd.DataFrame with columns ds (date), cap_scaled (scaled capacity), + y_scaled (scaled time series), and t (scaled time). + + Returns + ------- + A tuple (k, m) with the rate (k) and offset (m) of the logistic growth + function. + """ + i0, i1 = df['ds'].idxmin(), df['ds'].idxmax() + T = df['t'].iloc[i1] - df['t'].iloc[i0] + + # Force valid values, in case y > cap or y < 0 + C0 = df['cap_scaled'].iloc[i0] + C1 = df['cap_scaled'].iloc[i1] + y0 = max(0.01 * C0, min(0.99 * C0, df['y_scaled'].iloc[i0])) + y1 = max(0.01 * C1, min(0.99 * C1, df['y_scaled'].iloc[i1])) + + r0 = C0 / y0 + r1 = C1 / y1 + + if abs(r0 - r1) <= 0.01: + r0 = 1.05 * r0 + + L0 = np.log(r0 - 1) + L1 = np.log(r1 - 1) + + # Initialize the offset + m = L0 * T / (L0 - L1) + # And the rate + k = (L0 - L1) / T + return (k, m) + + @staticmethod + def flat_growth_init(df): + """Initialize flat growth. + + Provides a strong initialization for flat growth. Sets the growth to 0 + and offset parameter as mean of history y_scaled values. + + Parameters + ---------- + df: pd.DataFrame with columns ds (date), y_scaled (scaled time series), + and t (scaled time). + + Returns + ------- + A tuple (k, m) with the rate (k) and offset (m) of the linear growth + function. + """ + k = 0 + m = df['y_scaled'].mean() + return k, m + + def preprocess(self, df: pd.DataFrame, **kwargs) -> ModelInputData: + """ + Reformats historical data, standardizes y and extra regressors, sets seasonalities and changepoints. + + Saves the preprocessed data to the instantiated object, and also returns the relevant components + as a ModelInputData object. + """ + if ('ds' not in df) or ('y' not in df): + raise ValueError( + 'Dataframe must have columns "ds" and "y" with the dates and ' + 'values respectively.' + ) + history = df[df['y'].notnull()].copy() + if history.shape[0] < 2: + raise ValueError('Dataframe has less than 2 non-NaN rows.') + self.history_dates = pd.to_datetime(pd.Series(df['ds'].unique(), name='ds')).sort_values() + + self.history = self.setup_dataframe(history, initialize_scales=True) + self.set_auto_seasonalities() + seasonal_features, prior_scales, component_cols, modes = ( + self.make_all_seasonality_features(self.history)) + self.train_component_cols = component_cols + self.component_modes = modes + self.fit_kwargs = deepcopy(kwargs) + + self.set_changepoints() + + if self.growth in ['linear', 'flat']: + cap = np.zeros(self.history.shape[0]) + else: + cap = self.history['cap_scaled'] + + return ModelInputData( + T=self.history.shape[0], + S=len(self.changepoints_t), + K=seasonal_features.shape[1], + tau=self.changepoint_prior_scale, + trend_indicator=TrendIndicator[self.growth.upper()].value, + y=self.history['y_scaled'], + t=self.history['t'], + t_change=self.changepoints_t, + X=seasonal_features, + sigmas=prior_scales, + s_a=component_cols['additive_terms'], + s_m=component_cols['multiplicative_terms'], + cap=cap, + ) + + def calculate_initial_params(self, num_total_regressors: int) -> ModelParams: + """ + Calculates initial parameters for the model based on the preprocessed history. + + Parameters + ---------- + num_total_regressors: the count of seasonality fourier components plus holidays plus extra regressors. + """ + if self.growth == 'linear': + k, m = self.linear_growth_init(self.history) + elif self.growth == 'flat': + k, m = self.flat_growth_init(self.history) + elif self.growth == 'logistic': + k, m = self.logistic_growth_init(self.history) + return ModelParams( + k=k, + m=m, + delta=np.zeros_like(self.changepoints_t), + beta=np.zeros(num_total_regressors), + sigma_obs=1.0, + ) + + def fit(self, df, **kwargs): + """Fit the Prophet model. + + This sets self.params to contain the fitted model parameters. It is a + dictionary parameter names as keys and the following items: + k (Mx1 array): M posterior samples of the initial slope. + m (Mx1 array): The initial intercept. + delta (MxN array): The slope change at each of N changepoints. + beta (MxK matrix): Coefficients for K seasonality features. + sigma_obs (Mx1 array): Noise level. + Note that M=1 if MAP estimation. + + Parameters + ---------- + df: pd.DataFrame containing the history. Must have columns ds (date + type) and y, the time series. If self.growth is 'logistic', then + df must also have a column cap that specifies the capacity at + each ds. + kwargs: Additional arguments passed to the optimizing or sampling + functions in Stan. + + Returns + ------- + The fitted Prophet object. + """ + if self.history is not None: + raise Exception('Prophet object can only be fit once. ' + 'Instantiate a new object.') + + model_inputs = self.preprocess(df, **kwargs) + initial_params = self.calculate_initial_params(model_inputs.K) + + dat = dataclasses.asdict(model_inputs) + stan_init = dataclasses.asdict(initial_params) + + if self.history['y'].min() == self.history['y'].max() and \ + (self.growth == 'linear' or self.growth == 'flat'): + self.params = stan_init + self.params['sigma_obs'] = 1e-9 + for par in self.params: + self.params[par] = np.array([self.params[par]]) + elif self.mcmc_samples > 0: + self.params = self.stan_backend.sampling(stan_init, dat, self.mcmc_samples, **kwargs) + else: + self.params = self.stan_backend.fit(stan_init, dat, **kwargs) + + self.stan_fit = self.stan_backend.stan_fit + # If no changepoints were requested, replace delta with 0s + if len(self.changepoints) == 0: + # Fold delta into the base rate k + self.params['k'] = ( + self.params['k'] + self.params['delta'].reshape(-1) + ) + self.params['delta'] = (np.zeros(self.params['delta'].shape) + .reshape((-1, 1))) + + return self + + def predict(self, df: pd.DataFrame = None, vectorized: bool = True) -> pd.DataFrame: + """Predict using the prophet model. + + Parameters + ---------- + df: pd.DataFrame with dates for predictions (column ds), and capacity + (column cap) if logistic growth. If not provided, predictions are + made on the history. + vectorized: Whether to use a vectorized method to compute uncertainty intervals. Suggest using + True (the default) for much faster runtimes in most cases, + except when (growth = 'logistic' and mcmc_samples > 0). + + Returns + ------- + A pd.DataFrame with the forecast components. + """ + if self.history is None: + raise Exception('Model has not been fit.') + + if df is None: + df = self.history.copy() + else: + if df.shape[0] == 0: + raise ValueError('Dataframe has no rows.') + df = self.setup_dataframe(df.copy()) + + df['trend'] = self.predict_trend(df) + seasonal_components = self.predict_seasonal_components(df) + if self.uncertainty_samples: + intervals = self.predict_uncertainty(df, vectorized) + else: + intervals = None + + # Drop columns except ds, cap, floor, and trend + cols = ['ds', 'trend'] + if 'cap' in df: + cols.append('cap') + if self.logistic_floor: + cols.append('floor') + # Add in forecast components + df2 = pd.concat((df[cols], intervals, seasonal_components), axis=1) + df2['yhat'] = ( + df2['trend'] * (1 + df2['multiplicative_terms']) + + df2['additive_terms'] + ) + return df2 + + @staticmethod + def piecewise_linear(t, deltas, k, m, changepoint_ts): + """Evaluate the piecewise linear function. + + Parameters + ---------- + t: np.array of times on which the function is evaluated. + deltas: np.array of rate changes at each changepoint. + k: Float initial rate. + m: Float initial offset. + changepoint_ts: np.array of changepoint times. + + Returns + ------- + Vector y(t). + """ + deltas_t = (changepoint_ts[None, :] <= t[..., None]) * deltas + k_t = deltas_t.sum(axis=1) + k + m_t = (deltas_t * -changepoint_ts).sum(axis=1) + m + return k_t * t + m_t + + @staticmethod + def piecewise_logistic(t, cap, deltas, k, m, changepoint_ts): + """Evaluate the piecewise logistic function. + + Parameters + ---------- + t: np.array of times on which the function is evaluated. + cap: np.array of capacities at each t. + deltas: np.array of rate changes at each changepoint. + k: Float initial rate. + m: Float initial offset. + changepoint_ts: np.array of changepoint times. + + Returns + ------- + Vector y(t). + """ + # Compute offset changes + k_cum = np.concatenate((np.atleast_1d(k), np.cumsum(deltas) + k)) + gammas = np.zeros(len(changepoint_ts)) + for i, t_s in enumerate(changepoint_ts): + gammas[i] = ( + (t_s - m - np.sum(gammas)) + * (1 - k_cum[i] / k_cum[i + 1]) # noqa W503 + ) + # Get cumulative rate and offset at each t + k_t = k * np.ones_like(t) + m_t = m * np.ones_like(t) + for s, t_s in enumerate(changepoint_ts): + indx = t >= t_s + k_t[indx] += deltas[s] + m_t[indx] += gammas[s] + return cap / (1 + np.exp(-k_t * (t - m_t))) + + @staticmethod + def flat_trend(t, m): + """Evaluate the flat trend function. + + Parameters + ---------- + t: np.array of times on which the function is evaluated. + m: Float initial offset. + + Returns + ------- + Vector y(t). + """ + m_t = m * np.ones_like(t) + return m_t + + def predict_trend(self, df): + """Predict trend using the prophet model. + + Parameters + ---------- + df: Prediction dataframe. + + Returns + ------- + Vector with trend on prediction dates. + """ + k = np.nanmean(self.params['k']) + m = np.nanmean(self.params['m']) + deltas = np.nanmean(self.params['delta'], axis=0) + + t = np.array(df['t']) + if self.growth == 'linear': + trend = self.piecewise_linear(t, deltas, k, m, self.changepoints_t) + elif self.growth == 'logistic': + cap = df['cap_scaled'] + trend = self.piecewise_logistic( + t, cap, deltas, k, m, self.changepoints_t) + elif self.growth == 'flat': + # constant trend + trend = self.flat_trend(t, m) + + return trend * self.y_scale + df['floor'] + + def predict_seasonal_components(self, df): + """Predict seasonality components, holidays, and added regressors. + + Parameters + ---------- + df: Prediction dataframe. + + Returns + ------- + Dataframe with seasonal components. + """ + seasonal_features, _, component_cols, _ = ( + self.make_all_seasonality_features(df) + ) + if self.uncertainty_samples: + lower_p = 100 * (1.0 - self.interval_width) / 2 + upper_p = 100 * (1.0 + self.interval_width) / 2 + + X = seasonal_features.values + data = {} + for component in component_cols.columns: + beta_c = self.params['beta'] * component_cols[component].values + + comp = np.matmul(X, beta_c.transpose()) + if component in self.component_modes['additive']: + comp *= self.y_scale + data[component] = np.nanmean(comp, axis=1) + if self.uncertainty_samples: + data[component + '_lower'] = self.percentile( + comp, lower_p, axis=1, + ) + data[component + '_upper'] = self.percentile( + comp, upper_p, axis=1, + ) + return pd.DataFrame(data) + + def predict_uncertainty(self, df: pd.DataFrame, vectorized: bool) -> pd.DataFrame: + """Prediction intervals for yhat and trend. + + Parameters + ---------- + df: Prediction dataframe. + vectorized: Whether to use a vectorized method for generating future draws. + + Returns + ------- + Dataframe with uncertainty intervals. + """ + sim_values = self.sample_posterior_predictive(df, vectorized) + + lower_p = 100 * (1.0 - self.interval_width) / 2 + upper_p = 100 * (1.0 + self.interval_width) / 2 + + series = {} + for key in ['yhat', 'trend']: + series['{}_lower'.format(key)] = self.percentile( + sim_values[key], lower_p, axis=1) + series['{}_upper'.format(key)] = self.percentile( + sim_values[key], upper_p, axis=1) + + return pd.DataFrame(series) + + def sample_posterior_predictive(self, df: pd.DataFrame, vectorized: bool) -> Dict[str, np.ndarray]: + """Prophet posterior predictive samples. + + Parameters + ---------- + df: Prediction dataframe. + vectorized: Whether to use a vectorized method to generate future draws. + + Returns + ------- + Dictionary with posterior predictive samples for the forecast yhat and + for the trend component. + """ + n_iterations = self.params['k'].shape[0] + samp_per_iter = max(1, int(np.ceil( + self.uncertainty_samples / float(n_iterations) + ))) + # Generate seasonality features once so we can re-use them. + seasonal_features, _, component_cols, _ = ( + self.make_all_seasonality_features(df) + ) + sim_values = {'yhat': [], 'trend': []} + for i in range(n_iterations): + if vectorized: + sims = self.sample_model_vectorized( + df=df, + seasonal_features=seasonal_features, + iteration=i, + s_a=component_cols['additive_terms'], + s_m=component_cols['multiplicative_terms'], + n_samples=samp_per_iter + ) + else: + sims = [ + self.sample_model( + df=df, + seasonal_features=seasonal_features, + iteration=i, + s_a=component_cols['additive_terms'], + s_m=component_cols['multiplicative_terms'], + ) for _ in range(samp_per_iter) + ] + for key in sim_values: + for sim in sims: + sim_values[key].append(sim[key]) + for k, v in sim_values.items(): + sim_values[k] = np.column_stack(v) + return sim_values + + def sample_model(self, df, seasonal_features, iteration, s_a, s_m) -> Dict[str, np.ndarray]: + """Simulate observations from the extrapolated generative model. + + Parameters + ---------- + df: Prediction dataframe. + seasonal_features: pd.DataFrame of seasonal features. + iteration: Int sampling iteration to use parameters from. + s_a: Indicator vector for additive components + s_m: Indicator vector for multiplicative components + + Returns + ------- + Dictionary with `yhat` and `trend`, each like df['t']. + """ + trend = self.sample_predictive_trend(df, iteration) + + beta = self.params['beta'][iteration] + Xb_a = np.matmul(seasonal_features.values, + beta * s_a.values) * self.y_scale + Xb_m = np.matmul(seasonal_features.values, beta * s_m.values) + + sigma = self.params['sigma_obs'][iteration] + noise = np.random.normal(0, sigma, df.shape[0]) * self.y_scale + + return { + 'yhat': trend * (1 + Xb_m) + Xb_a + noise, + 'trend': trend + } + + def sample_model_vectorized( + self, + df: pd.DataFrame, + seasonal_features: pd.DataFrame, + iteration: int, + s_a: np.ndarray, + s_m: np.ndarray, + n_samples: int, + ) -> List[Dict[str, np.ndarray]]: + """Simulate observations from the extrapolated generative model. Vectorized version of sample_model(). + + Parameters + ---------- + df: Prediction dataframe. + seasonal_features: pd.DataFrame of seasonal features. + iteration: Int sampling iteration to use parameters from. + s_a: Indicator vector for additive components. + s_m: Indicator vector for multiplicative components. + n_samples: Number of future paths of the trend to simulate. + + Returns + ------- + List (length n_samples) of dictionaries with arrays for trend and yhat, each ordered like df['t']. + """ + # Get the seasonality and regressor components, which are deterministic per iteration + beta = self.params['beta'][iteration] + Xb_a = np.matmul(seasonal_features.values, + beta * s_a.values) * self.y_scale + Xb_m = np.matmul(seasonal_features.values, beta * s_m.values) + # Get the future trend, which is stochastic per iteration + trends = self.sample_predictive_trend_vectorized(df, n_samples, iteration) # already on the same scale as the actual data + sigma = self.params['sigma_obs'][iteration] + noise_terms = np.random.normal(0, sigma, trends.shape) * self.y_scale + + simulations = [] + for trend, noise in zip(trends, noise_terms): + simulations.append({ + 'yhat': trend * (1 + Xb_m) + Xb_a + noise, + 'trend': trend + }) + return simulations + + def sample_predictive_trend(self, df, iteration): + """Simulate the trend using the extrapolated generative model. + + Parameters + ---------- + df: Prediction dataframe. + iteration: Int sampling iteration to use parameters from. + + Returns + ------- + np.array of simulated trend over df['t']. + """ + k = self.params['k'][iteration] + m = self.params['m'][iteration] + deltas = self.params['delta'][iteration] + + t = np.array(df['t']) + T = t.max() + + # New changepoints from a Poisson process with rate S on [1, T] + if T > 1: + S = len(self.changepoints_t) + n_changes = np.random.poisson(S * (T - 1)) + else: + n_changes = 0 + if n_changes > 0: + changepoint_ts_new = 1 + np.random.rand(n_changes) * (T - 1) + changepoint_ts_new.sort() + else: + changepoint_ts_new = [] + + # Get the empirical scale of the deltas, plus epsilon to avoid NaNs. + lambda_ = np.mean(np.abs(deltas)) + 1e-8 + + # Sample deltas + deltas_new = np.random.laplace(0, lambda_, n_changes) + + # Prepend the times and deltas from the history + changepoint_ts = np.concatenate((self.changepoints_t, + changepoint_ts_new)) + deltas = np.concatenate((deltas, deltas_new)) + + if self.growth == 'linear': + trend = self.piecewise_linear(t, deltas, k, m, changepoint_ts) + elif self.growth == 'logistic': + cap = df['cap_scaled'] + trend = self.piecewise_logistic(t, cap, deltas, k, m, + changepoint_ts) + elif self.growth == 'flat': + trend = self.flat_trend(t, m) + + return trend * self.y_scale + df['floor'] + + def sample_predictive_trend_vectorized(self, df: pd.DataFrame, n_samples: int, iteration: int = 0) -> np.ndarray: + """Sample draws of the future trend values. Vectorized version of sample_predictive_trend(). + + Parameters + ---------- + df: Prediction dataframe. + iteration: Int sampling iteration to use parameters from. + n_samples: Number of future paths of the trend to simulate. + + Returns + ------- + Draws of the trend values with shape (n_samples, len(df)). Values are on the scale of the original data. + """ + deltas = self.params["delta"][iteration] + m = self.params["m"][iteration] + k = self.params["k"][iteration] + if self.growth == "linear": + expected = self.piecewise_linear(df["t"].values, deltas, k, m, self.changepoints_t) + elif self.growth == "logistic": + expected = self.piecewise_logistic( + df["t"].values, df["cap_scaled"].values, deltas, k, m, self.changepoints_t + ) + elif self.growth == "flat": + expected = self.flat_trend(df["t"].values, m) + else: + raise NotImplementedError + uncertainty = self._sample_uncertainty(df, n_samples, iteration) + return ( + (np.tile(expected, (n_samples, 1)) + uncertainty) * self.y_scale + + np.tile(df["floor"].values, (n_samples, 1)) + ) + + def _sample_uncertainty(self, df: pd.DataFrame, n_samples: int, iteration: int = 0) -> np.ndarray: + """Sample draws of future trend changes, vectorizing as much as possible. + + Parameters + ---------- + df: DataFrame with columns `t` (time scaled to the model context), trend, and cap. + n_samples: Number of future paths of the trend to simulate + iteration: The iteration of the parameter set to use. Default 0, the first iteration. + + Returns + ------- + Draws of the trend changes with shape (n_samples, len(df)). Values are standardized. + """ + # handle only historic data + if df["t"].max() <= 1: + # there is no trend uncertainty in historic trends + uncertainties = np.zeros((n_samples, len(df))) + else: + future_df = df.loc[df["t"] > 1] + n_length = len(future_df) + # handle 1 length futures by using history + if n_length > 1: + single_diff = np.diff(future_df["t"]).mean() + else: + single_diff = np.diff(self.history["t"]).mean() + change_likelihood = len(self.changepoints_t) * single_diff + deltas = self.params["delta"][iteration] + m = self.params["m"][iteration] + k = self.params["k"][iteration] + mean_delta = np.mean(np.abs(deltas)) + 1e-8 + if self.growth == "linear": + mat = self._make_trend_shift_matrix(mean_delta, change_likelihood, n_length, n_samples=n_samples) + uncertainties = mat.cumsum(axis=1).cumsum(axis=1) # from slope changes to actual values + uncertainties *= single_diff # scaled by the actual meaning of the slope + elif self.growth == "logistic": + mat = self._make_trend_shift_matrix(mean_delta, change_likelihood, n_length, n_samples=n_samples) + uncertainties = self._logistic_uncertainty( + mat=mat, + deltas=deltas, + k=k, + m=m, + cap=future_df["cap_scaled"].values, + t_time=future_df["t"].values, + n_length=n_length, + single_diff=single_diff, + ) + elif self.growth == "flat": + # no trend uncertainty when there is no growth + uncertainties = np.zeros((n_samples, n_length)) + else: + raise NotImplementedError + # handle past included in dataframe + if df["t"].min() <= 1: + past_uncertainty = np.zeros((n_samples, np.sum(df["t"] <= 1))) + uncertainties = np.concatenate([past_uncertainty, uncertainties], axis=1) + return uncertainties + + @staticmethod + def _make_trend_shift_matrix( + mean_delta: float, likelihood: float, future_length: float, n_samples: int + ) -> np.ndarray: + """ + Creates a matrix of random trend shifts based on historical likelihood and size of shifts. + Can be used for either linear or logistic trend shifts. + Each row represents a different sample of a possible future, and each column is a time step into the future. + """ + # create a bool matrix of where these trend shifts should go + bool_slope_change = np.random.uniform(size=(n_samples, future_length)) < likelihood + shift_values = np.random.laplace(0, mean_delta, size=bool_slope_change.shape) + mat = shift_values * bool_slope_change + n_mat = np.hstack([np.zeros((len(mat), 1)), mat])[:, :-1] + mat = (n_mat + mat) / 2 + return mat + + @staticmethod + def _make_historical_mat_time(deltas, changepoints_t, t_time, n_row=1, single_diff=None): + """ + Creates a matrix of slope-deltas where these changes occured in training data according to the trained prophet obj + """ + if single_diff is None: + single_diff = np.diff(t_time).mean() + prev_time = np.arange(0, 1 + single_diff, single_diff) + idxs = [] + for changepoint in changepoints_t: + idxs.append(np.where(prev_time > changepoint)[0][0]) + prev_deltas = np.zeros(len(prev_time)) + prev_deltas[idxs] = deltas + prev_deltas = np.repeat(prev_deltas.reshape(1, -1), n_row, axis=0) + return prev_deltas, prev_time + + def _logistic_uncertainty( + self, + mat: np.ndarray, + deltas: np.ndarray, + k: float, + m: float, + cap: np.ndarray, + t_time: np.ndarray, + n_length: int, + single_diff: float = None, + ) -> np.ndarray: + """ + Vectorizes prophet's logistic uncertainty by creating a matrix of future possible trends. + + Parameters + ---------- + mat: A trend shift matrix returned by _make_trend_shift_matrix() + deltas: The size of the trend changes at each changepoint, estimated by the model + k: Float initial rate. + m: Float initial offset. + cap: np.array of capacities at each t. + t_time: The values of t in the model context (i.e. scaled so that anything > 1 represents the future) + n_length: For each path, the number of future steps to simulate + single_diff: The difference between each t step in the model context. Default None, inferred + from t_time. + + Returns + ------- + A numpy array with shape (n_samples, n_length), representing the width of the uncertainty interval + (standardized, not on the same scale as the actual data values) around 0. + """ + + def ffill(arr): + mask = arr == 0 + idx = np.where(~mask, np.arange(mask.shape[1]), 0) + np.maximum.accumulate(idx, axis=1, out=idx) + return arr[np.arange(idx.shape[0])[:, None], idx] + + # for logistic growth we need to evaluate the trend all the way from the start of the train item + historical_mat, historical_time = self._make_historical_mat_time(deltas, self.changepoints_t, t_time, len(mat), single_diff) + mat = np.concatenate([historical_mat, mat], axis=1) + full_t_time = np.concatenate([historical_time, t_time]) + + # apply logistic growth logic on the slope changes + k_cum = np.concatenate((np.ones((mat.shape[0], 1)) * k, np.where(mat, np.cumsum(mat, axis=1) + k, 0)), axis=1) + k_cum_b = ffill(k_cum) + gammas = np.zeros_like(mat) + for i in range(mat.shape[1]): + x = full_t_time[i] - m - np.sum(gammas[:, :i], axis=1) + ks = 1 - k_cum_b[:, i] / k_cum_b[:, i + 1] + gammas[:, i] = x * ks + # the data before the -n_length is the historical values, which are not needed, so cut the last n_length + k_t = (mat.cumsum(axis=1) + k)[:, -n_length:] + m_t = (gammas.cumsum(axis=1) + m)[:, -n_length:] + sample_trends = cap / (1 + np.exp(-k_t * (t_time - m_t))) + # remove the mean because we only need width of the uncertainty centered around 0 + # we will add the width to the main forecast - yhat (which is the mean) - later + return sample_trends - sample_trends.mean(axis=0) + + def predictive_samples(self, df: pd.DataFrame, vectorized: bool = True): + """Sample from the posterior predictive distribution. Returns samples + for the main estimate yhat, and for the trend component. The shape of + each output will be (nforecast x nsamples), where nforecast is the + number of points being forecasted (the number of rows in the input + dataframe) and nsamples is the number of posterior samples drawn. + This is the argument `uncertainty_samples` in the Prophet constructor, + which defaults to 1000. + + Parameters + ---------- + df: Dataframe with dates for predictions (column ds), and capacity + (column cap) if logistic growth. + vectorized: Whether to use a vectorized method to compute possible draws. Suggest using + True (the default) for much faster runtimes in most cases, + except when (growth = 'logistic' and mcmc_samples > 0). + + Returns + ------- + Dictionary with keys "trend" and "yhat" containing + posterior predictive samples for that component. + """ + df = self.setup_dataframe(df.copy()) + return self.sample_posterior_predictive(df, vectorized) + + def percentile(self, a, *args, **kwargs): + """ + We rely on np.nanpercentile in the rare instances where there + are a small number of bad samples with MCMC that contain NaNs. + However, since np.nanpercentile is far slower than np.percentile, + we only fall back to it if the array contains NaNs. See + https://github.com/facebook/prophet/issues/1310 for more details. + """ + fn = np.nanpercentile if np.isnan(a).any() else np.percentile + return fn(a, *args, **kwargs) + + def make_future_dataframe(self, periods, freq='D', include_history=True): + """Simulate the trend using the extrapolated generative model. + + Parameters + ---------- + periods: Int number of periods to forecast forward. + freq: Any valid frequency for pd.date_range, such as 'D' or 'M'. + include_history: Boolean to include the historical dates in the data + frame for predictions. + + Returns + ------- + pd.Dataframe that extends forward from the end of self.history for the + requested number of periods. + """ + if self.history_dates is None: + raise Exception('Model has not been fit.') + if freq is None: + # taking the tail makes freq inference more reliable + freq = pd.infer_freq(self.history_dates.tail(5)) + # returns None if inference failed + if freq is None: + raise Exception('Unable to infer `freq`') + last_date = self.history_dates.max() + dates = pd.date_range( + start=last_date, + periods=periods + 1, # An extra in case we include start + freq=freq) + dates = dates[dates > last_date] # Drop start if equals last_date + dates = dates[:periods] # Return correct number of periods + + if include_history: + dates = np.concatenate((np.array(self.history_dates), dates)) + + return pd.DataFrame({'ds': dates}) + + def plot(self, fcst, ax=None, uncertainty=True, plot_cap=True, + xlabel='ds', ylabel='y', figsize=(10, 6), include_legend=False): + """Plot the Prophet forecast. + + Parameters + ---------- + fcst: pd.DataFrame output of self.predict. + ax: Optional matplotlib axes on which to plot. + uncertainty: Optional boolean to plot uncertainty intervals. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + xlabel: Optional label name on X-axis + ylabel: Optional label name on Y-axis + figsize: Optional tuple width, height in inches. + include_legend: Optional boolean to add legend to the plot. + + Returns + ------- + A matplotlib figure. + """ + return plot( + m=self, fcst=fcst, ax=ax, uncertainty=uncertainty, + plot_cap=plot_cap, xlabel=xlabel, ylabel=ylabel, + figsize=figsize, include_legend=include_legend + ) + + def plot_components(self, fcst, uncertainty=True, plot_cap=True, + weekly_start=0, yearly_start=0, figsize=None): + """Plot the Prophet forecast components. + + Will plot whichever are available of: trend, holidays, weekly + seasonality, and yearly seasonality. + + Parameters + ---------- + fcst: pd.DataFrame output of self.predict. + uncertainty: Optional boolean to plot uncertainty intervals. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + weekly_start: Optional int specifying the start day of the weekly + seasonality plot. 0 (default) starts the week on Sunday. 1 shifts + by 1 day to Monday, and so on. + yearly_start: Optional int specifying the start day of the yearly + seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts + by 1 day to Jan 2, and so on. + figsize: Optional tuple width, height in inches. + + Returns + ------- + A matplotlib figure. + """ + return plot_components( + m=self, fcst=fcst, uncertainty=uncertainty, plot_cap=plot_cap, + weekly_start=weekly_start, yearly_start=yearly_start, + figsize=figsize + ) diff --git a/.venv/lib/python3.12/site-packages/prophet/make_holidays.py b/.venv/lib/python3.12/site-packages/prophet/make_holidays.py new file mode 100644 index 00000000..61e0ea40 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/make_holidays.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from __future__ import absolute_import, division, print_function + +import numpy as np +import pandas as pd + +import holidays + + +def get_country_holidays_class(country): + """Get class for a supported country. + + Parameters + ---------- + country: country code + + Returns + ------- + A valid country holidays class + """ + substitutions = { + "TU": "TR", # For compatibility with Turkey as 'TU' cases. + } + + country = substitutions.get(country, country) + if not hasattr(holidays, country): + raise AttributeError(f"Holidays in {country} are not currently supported!") + + return getattr(holidays, country) + + +def get_holiday_names(country): + """Return all possible holiday names of given country + + Parameters + ---------- + country: country name + + Returns + ------- + A set of all possible holiday names of given country + """ + country_holidays = get_country_holidays_class(country) + return set(country_holidays(language="en_US", years=np.arange(1995, 2045)).values()) + + +def make_holidays_df(year_list, country, province=None, state=None): + """Make dataframe of holidays for given years and countries + + Parameters + ---------- + year_list: a list of years + country: country name + province: province name + + Returns + ------- + Dataframe with 'ds' and 'holiday', which can directly feed + to 'holidays' params in Prophet + """ + country_holidays = get_country_holidays_class(country) + holidays = country_holidays(expand=False, language="en_US", subdiv=province, years=year_list) + + holidays_df = pd.DataFrame( + [(date, holidays.get_list(date)) for date in holidays], + columns=["ds", "holiday"], + ) + holidays_df = holidays_df.explode("holiday") + holidays_df.reset_index(inplace=True, drop=True) + holidays_df["ds"] = pd.to_datetime(holidays_df["ds"]) + + return holidays_df diff --git a/.venv/lib/python3.12/site-packages/prophet/models.py b/.venv/lib/python3.12/site-packages/prophet/models.py new file mode 100644 index 00000000..dfeb2b50 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/models.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from __future__ import absolute_import, division, print_function +from abc import abstractmethod, ABC +from dataclasses import dataclass +from typing import Sequence, Tuple +from collections import OrderedDict +from enum import Enum +import importlib_resources +import pathlib +import platform + +import logging +logger = logging.getLogger('prophet.models') + +PLATFORM = "win" if platform.platform().startswith("Win") else "unix" + +class TrendIndicator(Enum): + LINEAR = 0 + LOGISTIC = 1 + FLAT = 2 + +@dataclass +class ModelInputData: + T: int + S: int + K: int + tau: float + trend_indicator: int + y: Sequence[float] # length T + t: Sequence[float] # length T + cap: Sequence[float] # length T + t_change: Sequence[float] # length S + s_a: Sequence[int] # length K + s_m: Sequence[int] # length K + X: Sequence[Sequence[float]] # shape (T, K) + sigmas: Sequence[float] # length K + +@dataclass +class ModelParams: + k: float + m: float + delta: Sequence[float] # length S + beta: Sequence[float] # length K + sigma_obs: float + + +class IStanBackend(ABC): + def __init__(self): + self.model = self.load_model() + self.stan_fit = None + self.newton_fallback = True + + def set_options(self, **kwargs): + """ + Specify model options as kwargs. + * newton_fallback [bool]: whether to fallback to Newton if L-BFGS fails + """ + for k, v in kwargs.items(): + if k == 'newton_fallback': + self.newton_fallback = v + else: + raise ValueError(f'Unknown option {k}') + + def cleanup(self): + """Clean up temporary files created during model fitting.""" + pass + + + @staticmethod + @abstractmethod + def get_type(): + pass + + @abstractmethod + def load_model(self): + pass + + @abstractmethod + def fit(self, stan_init, stan_data, **kwargs) -> dict: + pass + + @abstractmethod + def sampling(self, stan_init, stan_data, samples, **kwargs) -> dict: + pass + + +class CmdStanPyBackend(IStanBackend): + CMDSTAN_VERSION = "2.33.1" + def __init__(self): + import cmdstanpy + # this must be set before super.__init__() for load_model to work on Windows + local_cmdstan = importlib_resources.files("prophet") / "stan_model" / f"cmdstan-{self.CMDSTAN_VERSION}" + if local_cmdstan.exists(): + cmdstanpy.set_cmdstan_path(str(local_cmdstan)) + super().__init__() + + @staticmethod + def get_type(): + return StanBackendEnum.CMDSTANPY.name + + def load_model(self): + import cmdstanpy + model_file = importlib_resources.files("prophet") / "stan_model" / "prophet_model.bin" + return cmdstanpy.CmdStanModel(exe_file=str(model_file)) + + def fit(self, stan_init, stan_data, **kwargs): + if 'inits' not in kwargs and 'init' in kwargs: + stan_init = self.sanitize_custom_inits(stan_init, kwargs['init']) + del kwargs['init'] + + inits_list, data_list = self.prepare_data(stan_init, stan_data) + args = dict( + data=data_list, + inits=inits_list, + algorithm='Newton' if data_list['T'] < 100 else 'LBFGS', + iter=int(1e4), + ) + args.update(kwargs) + + try: + self.stan_fit = self.model.optimize(**args) + except RuntimeError as e: + # Fall back on Newton + if not self.newton_fallback or args['algorithm'] == 'Newton': + raise e + logger.warning('Optimization terminated abnormally. Falling back to Newton.') + args['algorithm'] = 'Newton' + self.stan_fit = self.model.optimize(**args) + params = self.stan_to_dict_numpy( + self.stan_fit.column_names, self.stan_fit.optimized_params_np) + for par in params: + params[par] = params[par].reshape((1, -1)) + return params + + def sampling(self, stan_init, stan_data, samples, **kwargs) -> dict: + if 'inits' not in kwargs and 'init' in kwargs: + stan_init = self.sanitize_custom_inits(stan_init, kwargs['init']) + del kwargs['init'] + + inits_list, data_list = self.prepare_data(stan_init, stan_data) + args = dict( + data=data_list, + inits=inits_list, + ) + if 'chains' not in kwargs: + kwargs['chains'] = 4 + iter_half = samples // 2 + kwargs['iter_sampling'] = iter_half + if 'iter_warmup' not in kwargs: + kwargs['iter_warmup'] = iter_half + args.update(kwargs) + + self.stan_fit = self.model.sample(**args) + res = self.stan_fit.draws() + (samples, c, columns) = res.shape + res = res.reshape((samples * c, columns)) + params = self.stan_to_dict_numpy(self.stan_fit.column_names, res) + + for par in params: + s = params[par].shape + if s[1] == 1: + params[par] = params[par].reshape((s[0],)) + + if par in ['delta', 'beta'] and len(s) < 2: + params[par] = params[par].reshape((-1, 1)) + + return params + + def cleanup(self): + import cmdstanpy + + if hasattr(self, "stan_fit"): + fit_result: cmdstanpy.CmdStanMLE | cmdstanpy.CmdStanMCMC = self.stan_fit + to_remove = ( + fit_result.runset.csv_files + + fit_result.runset.diagnostic_files + + fit_result.runset.stdout_files + + fit_result.runset.profile_files + ) + for fpath in to_remove: + if pathlib.Path(fpath).is_file(): + pathlib.Path(fpath).unlink() + + @staticmethod + def sanitize_custom_inits(default_inits, custom_inits): + """Validate that custom inits have the correct type and shape, otherwise use defaults.""" + sanitized = {} + for param in ['k', 'm', 'sigma_obs']: + try: + sanitized[param] = float(custom_inits.get(param)) + except Exception: + sanitized[param] = default_inits[param] + for param in ['delta', 'beta']: + if default_inits[param].shape == custom_inits[param].shape: + sanitized[param] = custom_inits[param] + else: + sanitized[param] = default_inits[param] + return sanitized + + @staticmethod + def prepare_data(init, data) -> Tuple[dict, dict]: + """Converts np.ndarrays to lists that can be read by cmdstanpy.""" + cmdstanpy_data = { + 'T': data['T'], + 'S': data['S'], + 'K': data['K'], + 'tau': data['tau'], + 'trend_indicator': data['trend_indicator'], + 'y': data['y'].tolist(), + 't': data['t'].tolist(), + 'cap': data['cap'].tolist(), + 't_change': data['t_change'].tolist(), + 's_a': data['s_a'].tolist(), + 's_m': data['s_m'].tolist(), + 'X': data['X'].to_numpy().tolist(), + 'sigmas': data['sigmas'] + } + + cmdstanpy_init = { + 'k': init['k'], + 'm': init['m'], + 'delta': init['delta'].tolist(), + 'beta': init['beta'].tolist(), + 'sigma_obs': init['sigma_obs'] + } + return (cmdstanpy_init, cmdstanpy_data) + + @staticmethod + def stan_to_dict_numpy(column_names: Tuple[str, ...], data: 'np.array'): + import numpy as np + + output = OrderedDict() + + prev = None + + start = 0 + end = 0 + two_dims = len(data.shape) > 1 + for cname in column_names: + parsed = cname.split(".") if "." in cname else cname.split("[") + curr = parsed[0] + if prev is None: + prev = curr + + if curr != prev: + if prev in output: + raise RuntimeError( + "Found repeated column name" + ) + if two_dims: + output[prev] = np.array(data[:, start:end]) + else: + output[prev] = np.array(data[start:end]) + prev = curr + start = end + end += 1 + if prev in output: + raise RuntimeError( + "Found repeated column name" + ) + if two_dims: + output[prev] = np.array(data[:, start:end]) + else: + output[prev] = np.array(data[start:end]) + return output + + + + +class StanBackendEnum(Enum): + CMDSTANPY = CmdStanPyBackend + + @staticmethod + def get_backend_class(name: str) -> IStanBackend: + try: + return StanBackendEnum[name].value + except KeyError as e: + raise ValueError(f"Unknown stan backend: {name}") from e diff --git a/.venv/lib/python3.12/site-packages/prophet/plot.py b/.venv/lib/python3.12/site-packages/prophet/plot.py new file mode 100644 index 00000000..e5ef87b3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/plot.py @@ -0,0 +1,1025 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from __future__ import absolute_import, division, print_function + +import logging + +import numpy as np +import pandas as pd + +# TODO: separate performance_metrics into a different module. there is an implicit circular import between forecaster.py and diagnostics.py +from prophet.diagnostics import performance_metrics + +logger = logging.getLogger('prophet.plot') + + + +try: + from matplotlib import pyplot as plt + from matplotlib.dates import ( + MonthLocator, + num2date, + AutoDateLocator, + AutoDateFormatter, + ) + from matplotlib.ticker import FuncFormatter + + from pandas.plotting import deregister_matplotlib_converters + deregister_matplotlib_converters() +except ImportError: + logger.error('Importing matplotlib failed. Plotting will not work.') + +try: + import plotly.graph_objs as go + from plotly.subplots import make_subplots +except ImportError: + logger.error('Importing plotly failed. Interactive plots will not work.') + + +def plot( + m, fcst, ax=None, uncertainty=True, plot_cap=True, xlabel='ds', ylabel='y', + figsize=(10, 6), include_legend=False +): + """Plot the Prophet forecast. + + Parameters + ---------- + m: Prophet model. + fcst: pd.DataFrame output of m.predict. + ax: Optional matplotlib axes on which to plot. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + xlabel: Optional label name on X-axis + ylabel: Optional label name on Y-axis + figsize: Optional tuple width, height in inches. + include_legend: Optional boolean to add legend to the plot. + + Returns + ------- + A matplotlib figure. + """ + user_provided_ax = False if ax is None else True + if ax is None: + fig = plt.figure(facecolor='w', figsize=figsize) + ax = fig.add_subplot(111) + else: + fig = ax.get_figure() + fcst_t = fcst['ds'] + ax.plot(m.history['ds'], m.history['y'], 'k.', + label='Observed data points') + ax.plot(fcst_t, fcst['yhat'], ls='-', c='#0072B2', label='Forecast') + if 'cap' in fcst and plot_cap: + ax.plot(fcst_t, fcst['cap'], ls='--', c='k', label='Maximum capacity') + if m.logistic_floor and 'floor' in fcst and plot_cap: + ax.plot(fcst_t, fcst['floor'], ls='--', c='k', label='Minimum capacity') + if uncertainty and m.uncertainty_samples: + ax.fill_between(fcst_t, fcst['yhat_lower'], fcst['yhat_upper'], + color='#0072B2', alpha=0.2, label='Uncertainty interval') + # Specify formatting to workaround matplotlib issue #12925 + locator = AutoDateLocator(interval_multiples=False) + formatter = AutoDateFormatter(locator) + ax.xaxis.set_major_locator(locator) + ax.xaxis.set_major_formatter(formatter) + ax.grid(True, which='major', c='gray', ls='-', lw=1, alpha=0.2) + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + if include_legend: + ax.legend() + if not user_provided_ax: + fig.tight_layout() + return fig + + +def plot_components( + m, fcst, uncertainty=True, plot_cap=True, weekly_start=0, yearly_start=0, + figsize=None +): + """Plot the Prophet forecast components. + + Will plot whichever are available of: trend, holidays, weekly + seasonality, yearly seasonality, and additive and multiplicative extra + regressors. + + Parameters + ---------- + m: Prophet model. + fcst: pd.DataFrame output of m.predict. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + weekly_start: Optional int specifying the start day of the weekly + seasonality plot. 0 (default) starts the week on Sunday. 1 shifts + by 1 day to Monday, and so on. + yearly_start: Optional int specifying the start day of the yearly + seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts + by 1 day to Jan 2, and so on. + figsize: Optional tuple width, height in inches. + + Returns + ------- + A matplotlib figure. + """ + # Identify components to be plotted + components = ['trend'] + if m.train_holiday_names is not None and 'holidays' in fcst: + components.append('holidays') + # Plot weekly seasonality, if present + if 'weekly' in m.seasonalities and 'weekly' in fcst: + components.append('weekly') + # Yearly if present + if 'yearly' in m.seasonalities and 'yearly' in fcst: + components.append('yearly') + # Other seasonalities + components.extend([ + name for name in sorted(m.seasonalities) + if name in fcst and name not in ['weekly', 'yearly'] + ]) + regressors = {'additive': False, 'multiplicative': False} + for name, props in m.extra_regressors.items(): + regressors[props['mode']] = True + for mode in ['additive', 'multiplicative']: + if regressors[mode] and 'extra_regressors_{}'.format(mode) in fcst: + components.append('extra_regressors_{}'.format(mode)) + npanel = len(components) + + figsize = figsize if figsize else (9, 3 * npanel) + fig, axes = plt.subplots(npanel, 1, facecolor='w', figsize=figsize) + + if npanel == 1: + axes = [axes] + + multiplicative_axes = [] + + dt = m.history['ds'].diff() + min_dt = dt.iloc[dt.values.nonzero()[0]].min() + + for ax, plot_name in zip(axes, components): + if plot_name == 'trend': + plot_forecast_component( + m=m, fcst=fcst, name='trend', ax=ax, uncertainty=uncertainty, + plot_cap=plot_cap, + ) + elif plot_name in m.seasonalities: + if ( + (plot_name == 'weekly' or m.seasonalities[plot_name]['period'] == 7) + and (min_dt == pd.Timedelta(days=1)) + ): + plot_weekly( + m=m, name=plot_name, ax=ax, uncertainty=uncertainty, weekly_start=weekly_start + ) + elif plot_name == 'yearly' or m.seasonalities[plot_name]['period'] == 365.25: + plot_yearly( + m=m, name=plot_name, ax=ax, uncertainty=uncertainty, yearly_start=yearly_start + ) + else: + plot_seasonality( + m=m, name=plot_name, ax=ax, uncertainty=uncertainty, + ) + elif plot_name in [ + 'holidays', + 'extra_regressors_additive', + 'extra_regressors_multiplicative', + ]: + plot_forecast_component( + m=m, fcst=fcst, name=plot_name, ax=ax, uncertainty=uncertainty, + plot_cap=False, + ) + if plot_name in m.component_modes['multiplicative']: + multiplicative_axes.append(ax) + + fig.tight_layout() + # Reset multiplicative axes labels after tight_layout adjustment + for ax in multiplicative_axes: + ax = set_y_as_percent(ax) + return fig + + +def plot_forecast_component( + m, fcst, name, ax=None, uncertainty=True, plot_cap=False, figsize=(10, 6) +): + """Plot a particular component of the forecast. + + Parameters + ---------- + m: Prophet model. + fcst: pd.DataFrame output of m.predict. + name: Name of the component to plot. + ax: Optional matplotlib Axes to plot on. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + figsize: Optional tuple width, height in inches. + + Returns + ------- + a list of matplotlib artists + """ + artists = [] + if not ax: + fig = plt.figure(facecolor='w', figsize=figsize) + ax = fig.add_subplot(111) + fcst_t = fcst['ds'] + artists += ax.plot(fcst_t, fcst[name], ls='-', c='#0072B2') + if 'cap' in fcst and plot_cap: + artists += ax.plot(fcst_t, fcst['cap'], ls='--', c='k') + if m.logistic_floor and 'floor' in fcst and plot_cap: + ax.plot(fcst_t, fcst['floor'], ls='--', c='k') + if uncertainty and m.uncertainty_samples: + artists += [ax.fill_between( + fcst_t, fcst[name + '_lower'], fcst[name + '_upper'], + color='#0072B2', alpha=0.2)] + # Specify formatting to workaround matplotlib issue #12925 + locator = AutoDateLocator(interval_multiples=False) + formatter = AutoDateFormatter(locator) + ax.xaxis.set_major_locator(locator) + ax.xaxis.set_major_formatter(formatter) + ax.grid(True, which='major', c='gray', ls='-', lw=1, alpha=0.2) + ax.set_xlabel('ds') + ax.set_ylabel(name) + if name in m.component_modes['multiplicative']: + ax = set_y_as_percent(ax) + return artists + + +def seasonality_plot_df(m, ds): + """Prepare dataframe for plotting seasonal components. + + Parameters + ---------- + m: Prophet model. + ds: List of dates for column ds. + + Returns + ------- + A dataframe with seasonal components on ds. + """ + df_dict = {'ds': ds, 'cap': 1., 'floor': 0.} + for name in m.extra_regressors: + df_dict[name] = 0. + # Activate all conditional seasonality columns + for props in m.seasonalities.values(): + if props['condition_name'] is not None: + df_dict[props['condition_name']] = True + df = pd.DataFrame(df_dict) + df = m.setup_dataframe(df) + return df + + +def plot_weekly(m, ax=None, uncertainty=True, weekly_start=0, figsize=(10, 6), name='weekly'): + """Plot the weekly component of the forecast. + + Parameters + ---------- + m: Prophet model. + ax: Optional matplotlib Axes to plot on. One will be created if this + is not provided. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + weekly_start: Optional int specifying the start day of the weekly + seasonality plot. 0 (default) starts the week on Sunday. 1 shifts + by 1 day to Monday, and so on. + figsize: Optional tuple width, height in inches. + name: Name of seasonality component if changed from default 'weekly'. + + Returns + ------- + a list of matplotlib artists + """ + artists = [] + if not ax: + fig = plt.figure(facecolor='w', figsize=figsize) + ax = fig.add_subplot(111) + # Compute weekly seasonality for a Sun-Sat sequence of dates. + days = (pd.date_range(start='2017-01-01', periods=7) + + pd.Timedelta(days=weekly_start)) + df_w = seasonality_plot_df(m, days) + seas = m.predict_seasonal_components(df_w) + days = days.day_name() + artists += ax.plot(range(len(days)), seas[name], ls='-', + c='#0072B2') + if uncertainty and m.uncertainty_samples: + artists += [ax.fill_between(range(len(days)), + seas[name + '_lower'], seas[name + '_upper'], + color='#0072B2', alpha=0.2)] + ax.grid(True, which='major', c='gray', ls='-', lw=1, alpha=0.2) + ax.set_xticks(range(len(days))) + ax.set_xticklabels(days) + ax.set_xlabel('Day of week') + ax.set_ylabel(name) + if m.seasonalities[name]['mode'] == 'multiplicative': + ax = set_y_as_percent(ax) + return artists + + +def plot_yearly(m, ax=None, uncertainty=True, yearly_start=0, figsize=(10, 6), name='yearly'): + """Plot the yearly component of the forecast. + + Parameters + ---------- + m: Prophet model. + ax: Optional matplotlib Axes to plot on. One will be created if + this is not provided. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + yearly_start: Optional int specifying the start day of the yearly + seasonality plot. 0 (default) starts the year on Jan 1. 1 shifts + by 1 day to Jan 2, and so on. + figsize: Optional tuple width, height in inches. + name: Name of seasonality component if previously changed from default 'yearly'. + + Returns + ------- + a list of matplotlib artists + """ + artists = [] + if not ax: + fig = plt.figure(facecolor='w', figsize=figsize) + ax = fig.add_subplot(111) + # Compute yearly seasonality for a Jan 1 - Dec 31 sequence of dates. + days = (pd.date_range(start='2017-01-01', periods=365) + + pd.Timedelta(days=yearly_start)) + df_y = seasonality_plot_df(m, days) + seas = m.predict_seasonal_components(df_y) + artists += ax.plot( + df_y['ds'], seas[name], ls='-', c='#0072B2') + if uncertainty and m.uncertainty_samples: + artists += [ax.fill_between( + df_y['ds'], seas[name + '_lower'], + seas[name + '_upper'], color='#0072B2', alpha=0.2)] + ax.grid(True, which='major', c='gray', ls='-', lw=1, alpha=0.2) + months = MonthLocator(range(1, 13), bymonthday=1, interval=2) + ax.xaxis.set_major_formatter(FuncFormatter( + lambda x, pos=None: '{dt:%B} {dt.day}'.format(dt=num2date(x)))) + ax.xaxis.set_major_locator(months) + ax.set_xlabel('Day of year') + ax.set_ylabel(name) + if m.seasonalities[name]['mode'] == 'multiplicative': + ax = set_y_as_percent(ax) + return artists + + +def plot_seasonality(m, name, ax=None, uncertainty=True, figsize=(10, 6)): + """Plot a custom seasonal component. + + Parameters + ---------- + m: Prophet model. + name: Seasonality name, like 'daily', 'weekly'. + ax: Optional matplotlib Axes to plot on. One will be created if + this is not provided. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + figsize: Optional tuple width, height in inches. + + Returns + ------- + a list of matplotlib artists + """ + artists = [] + if not ax: + fig = plt.figure(facecolor='w', figsize=figsize) + ax = fig.add_subplot(111) + # Compute seasonality from Jan 1 through a single period. + start = pd.to_datetime('2017-01-01 0000') + period = m.seasonalities[name]['period'] + end = start + pd.Timedelta(days=period) + plot_points = 200 + days = pd.to_datetime(np.linspace(start.value, end.value, plot_points)) + df_y = seasonality_plot_df(m, days) + seas = m.predict_seasonal_components(df_y) + artists += ax.plot(df_y['ds'], seas[name], ls='-', + c='#0072B2') + if uncertainty and m.uncertainty_samples: + artists += [ax.fill_between( + df_y['ds'], seas[name + '_lower'], + seas[name + '_upper'], color='#0072B2', alpha=0.2)] + ax.grid(True, which='major', c='gray', ls='-', lw=1, alpha=0.2) + n_ticks = 8 + xticks = pd.to_datetime(np.linspace(start.value, end.value, n_ticks) + ).to_pydatetime() + ax.set_xticks(xticks) + if name == 'yearly': + fmt = FuncFormatter( + lambda x, pos=None: '{dt:%B} {dt.day}'.format(dt=num2date(x))) + ax.set_xlabel('Day of year') + elif name == 'weekly': + fmt = FuncFormatter( + lambda x, pos=None: '{dt:%A}'.format(dt=num2date(x))) + ax.set_xlabel('Day of Week') + elif name == 'daily': + fmt = FuncFormatter( + lambda x, pos=None: '{dt:%T}'.format(dt=num2date(x))) + ax.set_xlabel('Hour of day') + elif period <= 2: + fmt = FuncFormatter( + lambda x, pos=None: '{dt:%T}'.format(dt=num2date(x))) + ax.set_xlabel('Hours') + else: + fmt = FuncFormatter( + lambda x, pos=None: '{:.0f}'.format(pos * period / (n_ticks - 1))) + ax.set_xlabel('Days') + ax.xaxis.set_major_formatter(fmt) + ax.set_ylabel(name) + if m.seasonalities[name]['mode'] == 'multiplicative': + ax = set_y_as_percent(ax) + return artists + + +def set_y_as_percent(ax): + yticks = 100 * ax.get_yticks() + yticklabels = ['{0:.4g}%'.format(y) for y in yticks] + ax.set_yticks(ax.get_yticks().tolist()) + ax.set_yticklabels(yticklabels) + return ax + + +def add_changepoints_to_plot( + ax, m, fcst, threshold=0.01, cp_color='r', cp_linestyle='--', trend=True, +): + """Add markers for significant changepoints to prophet forecast plot. + + Example: + fig = m.plot(forecast) + add_changepoints_to_plot(fig.gca(), m, forecast) + + Parameters + ---------- + ax: axis on which to overlay changepoint markers. + m: Prophet model. + fcst: Forecast output from m.predict. + threshold: Threshold on trend change magnitude for significance. + cp_color: Color of changepoint markers. + cp_linestyle: Linestyle for changepoint markers. + trend: If True, will also overlay the trend. + + Returns + ------- + a list of matplotlib artists + """ + artists = [] + if trend: + artists.append(ax.plot(fcst['ds'], fcst['trend'], c=cp_color)) + signif_changepoints = m.changepoints[ + np.abs(np.nanmean(m.params['delta'], axis=0)) >= threshold + ] if len(m.changepoints) > 0 else [] + for cp in signif_changepoints: + artists.append(ax.axvline(x=cp, c=cp_color, ls=cp_linestyle)) + return artists + + +def plot_cross_validation_metric( + df_cv, metric, rolling_window=0.1, ax=None, figsize=(10, 6), color='b', + point_color='gray' +): + """Plot a performance metric vs. forecast horizon from cross validation. + + Cross validation produces a collection of out-of-sample model predictions + that can be compared to actual values, at a range of different horizons + (distance from the cutoff). This computes a specified performance metric + for each prediction, and aggregated over a rolling window with horizon. + + This uses prophet.diagnostics.performance_metrics to compute the metrics. + Valid values of metric are 'mse', 'rmse', 'mae', 'mape', 'mdape', 'smape', and 'coverage'. + + rolling_window is the proportion of data included in the rolling window of + aggregation. The default value of 0.1 means 10% of data are included in the + aggregation for computing the metric. + + As a concrete example, if metric='mse', then this plot will show the + squared error for each cross validation prediction, along with the MSE + averaged over rolling windows of 10% of the data. + + Parameters + ---------- + df_cv: The output from prophet.diagnostics.cross_validation. + metric: Metric name, one of ['mse', 'rmse', 'mae', 'mape', 'mdape', 'smape', 'coverage']. + rolling_window: Proportion of data to use for rolling average of metric. + In [0, 1]. Defaults to 0.1. + ax: Optional matplotlib axis on which to plot. If not given, a new figure + will be created. + figsize: Optional tuple width, height in inches. + color: Optional color for plot and error points, useful when plotting + multiple model performances on one axis for comparison. + + Returns + ------- + a matplotlib figure. + """ + if ax is None: + fig = plt.figure(facecolor='w', figsize=figsize) + ax = fig.add_subplot(111) + else: + fig = ax.get_figure() + # Get the metric at the level of individual predictions, and with the rolling window. + df_none = performance_metrics(df_cv, metrics=[metric], rolling_window=-1) + df_h = performance_metrics(df_cv, metrics=[metric], rolling_window=rolling_window) + + # Some work because matplotlib does not handle timedelta + # Target ~10 ticks. + tick_w = max(df_none['horizon'].astype('timedelta64[ns]')) / 10. + # Find the largest time resolution that has <1 unit per bin. + dts = ['D', 'h', 'm', 's', 'ms', 'us', 'ns'] + dt_names = [ + 'days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds', + 'nanoseconds' + ] + dt_conversions = [ + 24 * 60 * 60 * 10 ** 9, + 60 * 60 * 10 ** 9, + 60 * 10 ** 9, + 10 ** 9, + 10 ** 6, + 10 ** 3, + 1., + ] + for i, dt in enumerate(dts): + if np.timedelta64(1, dt) < np.timedelta64(tick_w, 'ns'): + break + + x_plt = df_none['horizon'].astype('timedelta64[ns]').view(np.int64) / float(dt_conversions[i]) + x_plt_h = df_h['horizon'].astype('timedelta64[ns]').view(np.int64) / float(dt_conversions[i]) + + ax.plot(x_plt, df_none[metric], '.', alpha=0.1, c=point_color) + ax.plot(x_plt_h, df_h[metric], '-', c=color) + ax.grid(True) + + ax.set_xlabel('Horizon ({})'.format(dt_names[i])) + ax.set_ylabel(metric) + return fig + + +def plot_plotly(m, fcst, uncertainty=True, plot_cap=True, trend=False, changepoints=False, + changepoints_threshold=0.01, xlabel='ds', ylabel='y', figsize=(900, 600)): + """Plot the Prophet forecast with Plotly offline. + + Plotting in Jupyter Notebook requires initializing plotly.offline.init_notebook_mode(): + >>> import plotly.offline as py + >>> py.init_notebook_mode() + Then the figure can be displayed using plotly.offline.iplot(...): + >>> fig = plot_plotly(m, fcst) + >>> py.iplot(fig) + see https://plot.ly/python/offline/ for details + + Parameters + ---------- + m: Prophet model. + fcst: pd.DataFrame output of m.predict. + uncertainty: Optional boolean to plot uncertainty intervals. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + trend: Optional boolean to plot trend + changepoints: Optional boolean to plot changepoints + changepoints_threshold: Threshold on trend change magnitude for significance. + xlabel: Optional label name on X-axis + ylabel: Optional label name on Y-axis + figsize: The plot's size (in px). + + Returns + ------- + A Plotly Figure. + """ + prediction_color = '#0072B2' + error_color = 'rgba(0, 114, 178, 0.2)' # '#0072B2' with 0.2 opacity + actual_color = 'black' + cap_color = 'black' + trend_color = '#B23B00' + line_width = 2 + marker_size = 4 + + data = [] + # Add actual + data.append(go.Scatter( + name='Actual', + x=m.history['ds'], + y=m.history['y'], + marker=dict(color=actual_color, size=marker_size), + mode='markers' + )) + # Add lower bound + if uncertainty and m.uncertainty_samples: + data.append(go.Scatter( + x=fcst['ds'], + y=fcst['yhat_lower'], + mode='lines', + line=dict(width=0), + hoverinfo='skip' + )) + # Add prediction + data.append(go.Scatter( + name='Predicted', + x=fcst['ds'], + y=fcst['yhat'], + mode='lines', + line=dict(color=prediction_color, width=line_width), + fillcolor=error_color, + fill='tonexty' if uncertainty and m.uncertainty_samples else 'none' + )) + # Add upper bound + if uncertainty and m.uncertainty_samples: + data.append(go.Scatter( + x=fcst['ds'], + y=fcst['yhat_upper'], + mode='lines', + line=dict(width=0), + fillcolor=error_color, + fill='tonexty', + hoverinfo='skip' + )) + # Add caps + if 'cap' in fcst and plot_cap: + data.append(go.Scatter( + name='Cap', + x=fcst['ds'], + y=fcst['cap'], + mode='lines', + line=dict(color=cap_color, dash='dash', width=line_width), + )) + if m.logistic_floor and 'floor' in fcst and plot_cap: + data.append(go.Scatter( + name='Floor', + x=fcst['ds'], + y=fcst['floor'], + mode='lines', + line=dict(color=cap_color, dash='dash', width=line_width), + )) + # Add trend + if trend: + data.append(go.Scatter( + name='Trend', + x=fcst['ds'], + y=fcst['trend'], + mode='lines', + line=dict(color=trend_color, width=line_width), + )) + # Add changepoints + if changepoints and len(m.changepoints) > 0: + signif_changepoints = m.changepoints[ + np.abs(np.nanmean(m.params['delta'], axis=0)) >= changepoints_threshold + ] + data.append(go.Scatter( + x=signif_changepoints, + y=fcst.loc[fcst['ds'].isin(signif_changepoints), 'trend'], + marker=dict(size=50, symbol='line-ns-open', color=trend_color, + line=dict(width=line_width)), + mode='markers', + hoverinfo='skip' + )) + + layout = dict( + showlegend=False, + width=figsize[0], + height=figsize[1], + yaxis=dict( + title=ylabel + ), + xaxis=dict( + title=xlabel, + type='date', + rangeselector=dict( + buttons=list([ + dict(count=7, + label='1w', + step='day', + stepmode='backward'), + dict(count=1, + label='1m', + step='month', + stepmode='backward'), + dict(count=6, + label='6m', + step='month', + stepmode='backward'), + dict(count=1, + label='1y', + step='year', + stepmode='backward'), + dict(step='all') + ]) + ), + rangeslider=dict( + visible=True + ), + ), + ) + fig = go.Figure(data=data, layout=layout) + return fig + + +def plot_components_plotly( + m, fcst, uncertainty=True, plot_cap=True, figsize=(900, 200)): + """Plot the Prophet forecast components using Plotly. + See plot_plotly() for Plotly setup instructions + + Will plot whichever are available of: trend, holidays, weekly + seasonality, yearly seasonality, and additive and multiplicative extra + regressors. + + Parameters + ---------- + m: Prophet model. + fcst: pd.DataFrame output of m.predict. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + figsize: Set the size for the subplots (in px). + + Returns + ------- + A Plotly Figure. + """ + + # Identify components to plot and get their Plotly props + components = {} + components['trend'] = get_forecast_component_plotly_props( + m, fcst, 'trend', uncertainty, plot_cap) + if m.train_holiday_names is not None and 'holidays' in fcst: + components['holidays'] = get_forecast_component_plotly_props( + m, fcst, 'holidays', uncertainty) + + regressors = {'additive': False, 'multiplicative': False} + for name, props in m.extra_regressors.items(): + regressors[props['mode']] = True + for mode in ['additive', 'multiplicative']: + if regressors[mode] and 'extra_regressors_{}'.format(mode) in fcst: + components['extra_regressors_{}'.format(mode)] = get_forecast_component_plotly_props( + m, fcst, 'extra_regressors_{}'.format(mode)) + for seasonality in m.seasonalities: + components[seasonality] = get_seasonality_plotly_props(m, seasonality) + + # Create Plotly subplot figure and add the components to it + fig = make_subplots(rows=len(components), cols=1, print_grid=False) + fig['layout'].update(go.Layout( + showlegend=False, + width=figsize[0], + height=figsize[1] * len(components) + )) + for i, name in enumerate(components): + if i == 0: + xaxis = fig['layout']['xaxis'] + yaxis = fig['layout']['yaxis'] + else: + xaxis = fig['layout']['xaxis{}'.format(i + 1)] + yaxis = fig['layout']['yaxis{}'.format(i + 1)] + xaxis.update(components[name]['xaxis']) + yaxis.update(components[name]['yaxis']) + for trace in components[name]['traces']: + fig.append_trace(trace, i + 1, 1) + return fig + + +def plot_forecast_component_plotly(m, fcst, name, uncertainty=True, plot_cap=False, figsize=(900, 300)): + """Plot a particular component of the forecast using Plotly. + See plot_plotly() for Plotly setup instructions + + Parameters + ---------- + m: Prophet model. + fcst: pd.DataFrame output of m.predict. + name: Name of the component to plot. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + figsize: The plot's size (in px). + + Returns + ------- + A Plotly Figure. + """ + props = get_forecast_component_plotly_props(m, fcst, name, uncertainty, plot_cap) + layout = go.Layout( + width=figsize[0], + height=figsize[1], + showlegend=False, + xaxis=props['xaxis'], + yaxis=props['yaxis'] + ) + fig = go.Figure(data=props['traces'], layout=layout) + return fig + + +def plot_seasonality_plotly(m, name, uncertainty=True, figsize=(900, 300)): + """Plot a custom seasonal component using Plotly. + See plot_plotly() for Plotly setup instructions + + Parameters + ---------- + m: Prophet model. + name: Seasonality name, like 'daily', 'weekly'. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + figsize: Set the plot's size (in px). + + Returns + ------- + A Plotly Figure. + """ + props = get_seasonality_plotly_props(m, name, uncertainty) + layout = go.Layout( + width=figsize[0], + height=figsize[1], + showlegend=False, + xaxis=props['xaxis'], + yaxis=props['yaxis'] + ) + fig = go.Figure(data=props['traces'], layout=layout) + return fig + + +def get_forecast_component_plotly_props(m, fcst, name, uncertainty=True, plot_cap=False): + """Prepares a dictionary for plotting the selected forecast component with Plotly + + Parameters + ---------- + m: Prophet model. + fcst: pd.DataFrame output of m.predict. + name: Name of the component to plot. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + plot_cap: Optional boolean indicating if the capacity should be shown + in the figure, if available. + + Returns + ------- + A dictionary with Plotly traces, xaxis and yaxis + """ + prediction_color = '#0072B2' + error_color = 'rgba(0, 114, 178, 0.2)' # '#0072B2' with 0.2 opacity + cap_color = 'black' + zeroline_color = '#AAA' + line_width = 2 + + range_margin = (fcst['ds'].max() - fcst['ds'].min()) * 0.05 + range_x = [fcst['ds'].min() - range_margin, fcst['ds'].max() + range_margin] + + text = None + mode = 'lines' + if name == 'holidays': + + # Combine holidays into one hover text + holidays = m.construct_holiday_dataframe(fcst['ds']) + holiday_features, _, _ = m.make_holiday_features(fcst['ds'], holidays) + holiday_features.columns = holiday_features.columns.str.replace('_delim_', '', regex=False) + holiday_features.columns = holiday_features.columns.str.replace('+0', '', regex=False) + text = pd.Series(data='', index=holiday_features.index) + for holiday_feature, idxs in holiday_features.items(): + text[idxs.astype(bool) & (text != '')] += '
' # Add newline if additional holiday + text[idxs.astype(bool)] += holiday_feature + + traces = [] + traces.append(go.Scatter( + name=name, + x=fcst['ds'], + y=fcst[name], + mode=mode, + line=go.scatter.Line(color=prediction_color, width=line_width), + text=text, + )) + if uncertainty and m.uncertainty_samples and (fcst[name + '_upper'] != fcst[name + '_lower']).any(): + if mode == 'markers': + traces[0].update( + error_y=dict( + type='data', + symmetric=False, + array=fcst[name + '_upper'], + arrayminus=fcst[name + '_lower'], + width=0, + color=error_color + ) + ) + else: + traces.append(go.Scatter( + name=name + '_upper', + x=fcst['ds'], + y=fcst[name + '_upper'], + mode=mode, + line=go.scatter.Line(width=0, color=error_color) + )) + traces.append(go.Scatter( + name=name + '_lower', + x=fcst['ds'], + y=fcst[name + '_lower'], + mode=mode, + line=go.scatter.Line(width=0, color=error_color), + fillcolor=error_color, + fill='tonexty' + )) + if 'cap' in fcst and plot_cap: + traces.append(go.Scatter( + name='Cap', + x=fcst['ds'], + y=fcst['cap'], + mode='lines', + line=go.scatter.Line(color=cap_color, dash='dash', width=line_width), + )) + if m.logistic_floor and 'floor' in fcst and plot_cap: + traces.append(go.Scatter( + name='Floor', + x=fcst['ds'], + y=fcst['floor'], + mode='lines', + line=go.scatter.Line(color=cap_color, dash='dash', width=line_width), + )) + + xaxis = go.layout.XAxis( + type='date', + range=range_x) + yaxis = go.layout.YAxis(rangemode='normal' if name == 'trend' else 'tozero', + title=go.layout.yaxis.Title(text=name), + zerolinecolor=zeroline_color) + if name in m.component_modes['multiplicative']: + yaxis.update(tickformat='%', hoverformat='.2%') + return {'traces': traces, 'xaxis': xaxis, 'yaxis': yaxis} + + +def get_seasonality_plotly_props(m, name, uncertainty=True): + """Prepares a dictionary for plotting the selected seasonality with Plotly + + Parameters + ---------- + m: Prophet model. + name: Name of the component to plot. + uncertainty: Optional boolean to plot uncertainty intervals, which will + only be done if m.uncertainty_samples > 0. + + Returns + ------- + A dictionary with Plotly traces, xaxis and yaxis + """ + prediction_color = '#0072B2' + error_color = 'rgba(0, 114, 178, 0.2)' # '#0072B2' with 0.2 opacity + line_width = 2 + zeroline_color = '#AAA' + + # Compute seasonality from Jan 1 through a single period. + start = pd.to_datetime('2017-01-01 0000') + period = m.seasonalities[name]['period'] + end = start + pd.Timedelta(days=period) + if (m.history['ds'].dt.hour == 0).all(): # Day Precision + plot_points = np.floor(period).astype(int) + elif (m.history['ds'].dt.minute == 0).all(): # Hour Precision + plot_points = np.floor(period * 24).astype(int) + else: # Minute Precision + plot_points = np.floor(period * 24 * 60).astype(int) + days = pd.to_datetime(np.linspace(start.value, end.value, plot_points, endpoint=False)) + df_y = seasonality_plot_df(m, days) + seas = m.predict_seasonal_components(df_y) + + traces = [] + traces.append(go.Scatter( + name=name, + x=df_y['ds'], + y=seas[name], + mode='lines', + line=go.scatter.Line(color=prediction_color, width=line_width) + )) + if uncertainty and m.uncertainty_samples and (seas[name + '_upper'] != seas[name + '_lower']).any(): + traces.append(go.Scatter( + name=name + '_upper', + x=df_y['ds'], + y=seas[name + '_upper'], + mode='lines', + line=go.scatter.Line(width=0, color=error_color) + )) + traces.append(go.Scatter( + name=name + '_lower', + x=df_y['ds'], + y=seas[name + '_lower'], + mode='lines', + line=go.scatter.Line(width=0, color=error_color), + fillcolor=error_color, + fill='tonexty' + )) + + # Set tick formats (examples are based on 2017-01-06 21:15) + if period <= 2: + tickformat = '%H:%M' # "21:15" + elif period < 7: + tickformat = '%A %H:%M' # "Friday 21:15" + elif period < 14: + tickformat = '%A' # "Friday" + else: + tickformat = '%B %e' # "January 6" + + range_margin = (df_y['ds'].max() - df_y['ds'].min()) * 0.05 + xaxis = go.layout.XAxis( + tickformat=tickformat, + type='date', + range=[df_y['ds'].min() - range_margin, df_y['ds'].max() + range_margin] + ) + + yaxis = go.layout.YAxis(title=go.layout.yaxis.Title(text=name), + zerolinecolor=zeroline_color) + if m.seasonalities[name]['mode'] == 'multiplicative': + yaxis.update(tickformat='%', hoverformat='.2%') + + return {'traces': traces, 'xaxis': xaxis, 'yaxis': yaxis} diff --git a/.venv/lib/python3.12/site-packages/prophet/serialize.py b/.venv/lib/python3.12/site-packages/prophet/serialize.py new file mode 100644 index 00000000..02640d27 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/serialize.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from __future__ import absolute_import, division, print_function + +from collections import OrderedDict +from copy import deepcopy +from io import StringIO +import json +from pathlib import Path + +import numpy as np +import pandas as pd + +from prophet.forecaster import Prophet + +about = {} +here = Path(__file__).parent.resolve() +with open(here / "__version__.py", "r") as f: + exec(f.read(), about) + +SIMPLE_ATTRIBUTES = [ + 'growth', 'n_changepoints', 'specified_changepoints', 'changepoint_range', + 'yearly_seasonality', 'weekly_seasonality', 'daily_seasonality', + 'seasonality_mode', 'seasonality_prior_scale', 'changepoint_prior_scale', + 'holidays_prior_scale', 'mcmc_samples', 'interval_width', 'uncertainty_samples', + 'y_scale', 'y_min', 'scaling', 'logistic_floor', 'country_holidays', 'component_modes', + 'holidays_mode' +] + +PD_SERIES = ['changepoints', 'history_dates', 'train_holiday_names'] + +PD_TIMESTAMP = ['start'] + +PD_TIMEDELTA = ['t_scale'] + +PD_DATAFRAME = ['holidays', 'history', 'train_component_cols'] + +NP_ARRAY = ['changepoints_t'] + +ORDEREDDICT = ['seasonalities', 'extra_regressors'] + + +def model_to_dict(model): + """Convert a Prophet model to a dictionary suitable for JSON serialization. + + Model must be fitted. Skips Stan objects that are not needed for predict. + + Can be reversed with model_from_dict. + + Parameters + ---------- + model: Prophet model object. + + Returns + ------- + dict that can be used to serialize a Prophet model as JSON or loaded back + into a Prophet model. + """ + if model.history is None: + raise ValueError( + "This can only be used to serialize models that have already been fit." + ) + + model_dict = { + attribute: getattr(model, attribute) for attribute in SIMPLE_ATTRIBUTES + } + # Handle attributes of non-core types + for attribute in PD_SERIES: + if getattr(model, attribute) is None: + model_dict[attribute] = None + else: + model_dict[attribute] = getattr(model, attribute).to_json( + orient='split', date_format='iso' + ) + for attribute in PD_TIMESTAMP: + model_dict[attribute] = getattr(model, attribute).timestamp() + for attribute in PD_TIMEDELTA: + model_dict[attribute] = getattr(model, attribute).total_seconds() + for attribute in PD_DATAFRAME: + if getattr(model, attribute) is None: + model_dict[attribute] = None + else: + model_dict[attribute] = getattr(model, attribute).to_json(orient='table', index=False) + for attribute in NP_ARRAY: + model_dict[attribute] = getattr(model, attribute).tolist() + for attribute in ORDEREDDICT: + model_dict[attribute] = [ + list(getattr(model, attribute).keys()), + getattr(model, attribute), + ] + # Other attributes with special handling + # fit_kwargs -> Transform any numpy types before serializing. + # They do not need to be transformed back on deserializing. + fit_kwargs = deepcopy(model.fit_kwargs) + if 'init' in fit_kwargs: + for k, v in fit_kwargs['init'].items(): + if isinstance(v, np.ndarray): + fit_kwargs['init'][k] = v.tolist() + elif isinstance(v, np.floating): + fit_kwargs['init'][k] = float(v) + model_dict['fit_kwargs'] = fit_kwargs + + # Params (Dict[str, np.ndarray]) + model_dict['params'] = {k: v.tolist() for k, v in model.params.items()} + # Attributes that are skipped: stan_fit, stan_backend + model_dict['__prophet_version'] = about["__version__"] + return model_dict + + +def model_to_json(model): + """Serialize a Prophet model to json string. + + Model must be fitted. Skips Stan objects that are not needed for predict. + + Can be deserialized with model_from_json. + + Parameters + ---------- + model: Prophet model object. + + Returns + ------- + json string that can be deserialized into a Prophet model. + """ + model_json = model_to_dict(model) + return json.dumps(model_json) + + +def _handle_simple_attributes_backwards_compat(model_dict): + """Handle backwards compatibility for SIMPLE_ATTRIBUTES.""" + # prophet<1.1.5: handle scaling parameters introduced in #2470 + if 'scaling' not in model_dict: + model_dict['scaling'] = 'absmax' + model_dict['y_min'] = 0. + # prophet<1.1.5: handle holidays_mode parameter introduced in #2477 + if 'holidays_mode' not in model_dict: + model_dict['holidays_mode'] = model_dict['seasonality_mode'] + +def model_from_dict(model_dict): + """Recreate a Prophet model from a dictionary. + + Recreates models that were converted with model_to_dict. + + Parameters + ---------- + model_dict: Dictionary containing model, created with model_to_dict. + + Returns + ------- + Prophet model. + """ + model = Prophet() # We will overwrite all attributes set in init anyway + # Simple types + _handle_simple_attributes_backwards_compat(model_dict) + for attribute in SIMPLE_ATTRIBUTES: + setattr(model, attribute, model_dict[attribute]) + for attribute in PD_SERIES: + if model_dict[attribute] is None: + setattr(model, attribute, None) + else: + s = pd.read_json(StringIO(model_dict[attribute]), typ='series', orient='split') + if s.name == 'ds': + if len(s) == 0: + s = pd.to_datetime(s) + s = s.dt.tz_localize(None) + setattr(model, attribute, s) + for attribute in PD_TIMESTAMP: + setattr(model, attribute, pd.Timestamp.utcfromtimestamp(model_dict[attribute]).tz_localize(None)) + for attribute in PD_TIMEDELTA: + setattr(model, attribute, pd.Timedelta(seconds=model_dict[attribute])) + for attribute in PD_DATAFRAME: + if model_dict[attribute] is None: + setattr(model, attribute, None) + else: + df = pd.read_json(StringIO(model_dict[attribute]), typ='frame', orient='table', convert_dates=['ds']) + if attribute == 'train_component_cols': + # Special handling because of named index column + df.columns.name = 'component' + df.index.name = 'col' + setattr(model, attribute, df) + for attribute in NP_ARRAY: + setattr(model, attribute, np.array(model_dict[attribute])) + for attribute in ORDEREDDICT: + key_list, unordered_dict = model_dict[attribute] + od = OrderedDict() + for key in key_list: + od[key] = unordered_dict[key] + setattr(model, attribute, od) + # Other attributes with special handling + # fit_kwargs + model.fit_kwargs = model_dict['fit_kwargs'] + # Params (Dict[str, np.ndarray]) + model.params = {k: np.array(v) for k, v in model_dict['params'].items()} + # Skipped attributes + model.stan_backend = None + model.stan_fit = None + return model + + +def model_from_json(model_json): + """Deserialize a Prophet model from json string. + + Deserializes models that were serialized with model_to_json. + + Parameters + ---------- + model_json: Serialized model string + + Returns + ------- + Prophet model. + """ + model_dict = json.loads(model_json) + return model_from_dict(model_dict) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/diagnose b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/diagnose new file mode 100755 index 00000000..1163a340 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/diagnose differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/print b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/print new file mode 100755 index 00000000..3856feb8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/print differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/stanc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/stanc new file mode 100755 index 00000000..95dcb293 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/stanc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/stansummary b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/stansummary new file mode 100755 index 00000000..afa930e7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/bin/stansummary differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/arena.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/arena.d new file mode 100644 index 00000000..08c2790e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/arena.d @@ -0,0 +1,64 @@ +arena.o: ../tbb_2020.3/src/tbb/arena.cpp \ + ../tbb_2020.3/include/tbb/global_control.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h ../tbb_2020.3/src/tbb/scheduler.h \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/src/tbb/mailbox.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/intrusive_list.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/src/tbb/cilk-tbb-interop.h ../tbb_2020.3/src/tbb/arena.h \ + ../tbb_2020.3/src/tbb/task_stream.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/src/tbb/observer_proxy.h \ + ../tbb_2020.3/include/tbb/task_scheduler_observer.h \ + ../tbb_2020.3/include/tbb/task_arena.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h ../tbb_2020.3/src/tbb/market.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/src/tbb/semaphore.h \ + ../tbb_2020.3/include/tbb/internal/_flow_graph_impl.h \ + ../tbb_2020.3/include/tbb/internal/../task.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/internal/../task_arena.h \ + ../tbb_2020.3/include/tbb/internal/../flow_graph_abstractions.h \ + ../tbb_2020.3/src/tbb/scheduler_utility.h \ + ../tbb_2020.3/include/tbb/task_arena.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/arena.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/arena.o new file mode 100644 index 00000000..c8762c1e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/arena.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backend.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backend.d new file mode 100644 index 00000000..dfc28a5e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backend.d @@ -0,0 +1,32 @@ +backend.o: ../tbb_2020.3/src/tbbmalloc/backend.cpp \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal.h \ + ../tbb_2020.3/src/tbbmalloc/TypeDefinitions.h \ + ../tbb_2020.3/src/tbbmalloc/Customize.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbbmalloc/Synchronize.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbbmalloc/proxy.h \ + ../tbb_2020.3/include/tbb/internal/_aggregator_impl.h \ + ../tbb_2020.3/include/tbb/internal/../atomic.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbbmalloc/shared_utils.h \ + ../tbb_2020.3/include/tbb/scalable_allocator.h \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h \ + ../tbb_2020.3/src/tbbmalloc/Statistics.h \ + ../tbb_2020.3/src/tbbmalloc/large_objects.h \ + ../tbb_2020.3/src/tbbmalloc/backend.h \ + ../tbb_2020.3/src/tbbmalloc/MapMemory.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backend.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backend.o new file mode 100644 index 00000000..2d17d8d1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backend.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backref.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backref.d new file mode 100644 index 00000000..9d09e75c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backref.d @@ -0,0 +1,31 @@ +backref.o: ../tbb_2020.3/src/tbbmalloc/backref.cpp \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal.h \ + ../tbb_2020.3/src/tbbmalloc/TypeDefinitions.h \ + ../tbb_2020.3/src/tbbmalloc/Customize.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbbmalloc/Synchronize.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbbmalloc/proxy.h \ + ../tbb_2020.3/include/tbb/internal/_aggregator_impl.h \ + ../tbb_2020.3/include/tbb/internal/../atomic.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbbmalloc/shared_utils.h \ + ../tbb_2020.3/include/tbb/scalable_allocator.h \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h \ + ../tbb_2020.3/src/tbbmalloc/Statistics.h \ + ../tbb_2020.3/src/tbbmalloc/large_objects.h \ + ../tbb_2020.3/src/tbbmalloc/backend.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backref.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backref.o new file mode 100644 index 00000000..e316c5b8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/backref.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/cache_aligned_allocator.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/cache_aligned_allocator.d new file mode 100644 index 00000000..48c71954 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/cache_aligned_allocator.d @@ -0,0 +1,22 @@ +cache_aligned_allocator.o: \ + ../tbb_2020.3/src/tbb/cache_aligned_allocator.cpp \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/dynamic_link.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/cache_aligned_allocator.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/cache_aligned_allocator.o new file mode 100644 index 00000000..a83fae42 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/cache_aligned_allocator.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_hash_map.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_hash_map.d new file mode 100644 index 00000000..9f7ae3cb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_hash_map.d @@ -0,0 +1,30 @@ +concurrent_hash_map.o: ../tbb_2020.3/src/tbb/concurrent_hash_map.cpp \ + ../tbb_2020.3/include/tbb/concurrent_hash_map.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_hash_compare_impl.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/include/tbb/internal/_allocator_traits.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_hash_map.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_hash_map.o new file mode 100644 index 00000000..cec44026 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_hash_map.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_monitor.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_monitor.d new file mode 100644 index 00000000..f80ae4a0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_monitor.d @@ -0,0 +1,27 @@ +concurrent_monitor.o: ../tbb_2020.3/src/tbb/concurrent_monitor.cpp \ + ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/src/tbb/semaphore.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_monitor.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_monitor.o new file mode 100644 index 00000000..56ec913c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_monitor.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue.d new file mode 100644 index 00000000..db7f8eb1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue.d @@ -0,0 +1,43 @@ +concurrent_queue.o: ../tbb_2020.3/src/tbb/concurrent_queue.cpp \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/internal/_concurrent_queue_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../atomic.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../spin_mutex.h \ + ../tbb_2020.3/include/tbb/internal/../aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/internal/../atomic.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../cache_aligned_allocator.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/src/tbb/semaphore.h ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue.o new file mode 100644 index 00000000..dc79858a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue_v2.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue_v2.d new file mode 100644 index 00000000..0e689fb5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue_v2.d @@ -0,0 +1,24 @@ +concurrent_queue_v2.o: ../tbb_2020.3/src/old/concurrent_queue_v2.cpp \ + ../tbb_2020.3/src/old/concurrent_queue_v2.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/include/tbb/atomic.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue_v2.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue_v2.o new file mode 100644 index 00000000..48cf266b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_queue_v2.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector.d new file mode 100644 index 00000000..97fd3474 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector.d @@ -0,0 +1,31 @@ +concurrent_vector.o: ../tbb_2020.3/src/tbb/concurrent_vector.cpp \ + ../tbb_2020.3/include/tbb/concurrent_vector.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/include/tbb/blocked_range.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/internal/_allocator_traits.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/atomic.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector.o new file mode 100644 index 00000000..e9910fb6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector_v2.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector_v2.d new file mode 100644 index 00000000..87d64baa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector_v2.d @@ -0,0 +1,26 @@ +concurrent_vector_v2.o: ../tbb_2020.3/src/old/concurrent_vector_v2.cpp \ + ../tbb_2020.3/src/old/concurrent_vector_v2.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/include/tbb/blocked_range.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/src/old/../tbb/itt_notify.h \ + ../tbb_2020.3/src/old/../tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/old/../tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector_v2.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector_v2.o new file mode 100644 index 00000000..979f5b5e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/concurrent_vector_v2.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/condition_variable.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/condition_variable.d new file mode 100644 index 00000000..4ff919f5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/condition_variable.d @@ -0,0 +1,37 @@ +condition_variable.o: ../tbb_2020.3/src/tbb/condition_variable.cpp \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/compat/condition_variable \ + ../tbb_2020.3/include/tbb/compat/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/compat/../internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/compat/../internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_config.h \ + ../tbb_2020.3/include/tbb/compat/../mutex.h \ + ../tbb_2020.3/include/tbb/compat/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/compat/../internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/compat/../aligned_space.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/compat/../machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/compat/../machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/compat/../machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/compat/../machine/linux_common.h \ + ../tbb_2020.3/include/tbb/compat/../internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/compat/../internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/compat/../atomic.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_thread.h \ + ../tbb_2020.3/include/tbb/compat/../internal/_tbb_hash_compare_impl.h \ + ../tbb_2020.3/include/tbb/compat/../tick_count.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_exception.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_allocator.h \ + ../tbb_2020.3/include/tbb/compat/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/compat/../internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbb/dynamic_link.h ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/condition_variable.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/condition_variable.o new file mode 100644 index 00000000..fbf20bcf Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/condition_variable.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/critical_section.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/critical_section.d new file mode 100644 index 00000000..ab90bae3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/critical_section.d @@ -0,0 +1,26 @@ +critical_section.o: ../tbb_2020.3/src/tbb/critical_section.cpp \ + ../tbb_2020.3/include/tbb/critical_section.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_thread.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_hash_compare_impl.h \ + ../tbb_2020.3/include/tbb/tick_count.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/critical_section.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/critical_section.o new file mode 100644 index 00000000..0cf30441 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/critical_section.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/dynamic_link.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/dynamic_link.d new file mode 100644 index 00000000..50253097 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/dynamic_link.d @@ -0,0 +1,18 @@ +dynamic_link.o: ../tbb_2020.3/src/tbb/dynamic_link.cpp \ + ../tbb_2020.3/src/tbb/dynamic_link.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_config.h ../tbb_2020.3/src/tbb/tbb_misc.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/info.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/dynamic_link.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/dynamic_link.o new file mode 100644 index 00000000..825431ff Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/dynamic_link.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/frontend.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/frontend.d new file mode 100644 index 00000000..04f76f8d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/frontend.d @@ -0,0 +1,34 @@ +frontend.o: ../tbb_2020.3/src/tbbmalloc/frontend.cpp \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal.h \ + ../tbb_2020.3/src/tbbmalloc/TypeDefinitions.h \ + ../tbb_2020.3/src/tbbmalloc/Customize.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbbmalloc/Synchronize.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbbmalloc/proxy.h \ + ../tbb_2020.3/include/tbb/internal/_aggregator_impl.h \ + ../tbb_2020.3/include/tbb/internal/../atomic.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbbmalloc/shared_utils.h \ + ../tbb_2020.3/include/tbb/scalable_allocator.h \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h \ + ../tbb_2020.3/src/tbbmalloc/Statistics.h \ + ../tbb_2020.3/src/tbbmalloc/large_objects.h \ + ../tbb_2020.3/src/tbbmalloc/backend.h \ + ../tbb_2020.3/src/tbbmalloc/../tbb/tbb_version.h version_string.ver \ + ../tbb_2020.3/src/tbbmalloc/../tbb/tbb_environment.h \ + ../tbb_2020.3/src/tbbmalloc/../tbb/itt_notify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/frontend.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/frontend.o new file mode 100644 index 00000000..4f9e52a3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/frontend.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/governor.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/governor.d new file mode 100644 index 00000000..a0dd0aa3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/governor.d @@ -0,0 +1,57 @@ +governor.o: ../tbb_2020.3/src/tbb/governor.cpp \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/cilk-tbb-interop.h \ + ../tbb_2020.3/src/tbb/tbb_main.h ../tbb_2020.3/src/tbb/tbb_environment.h \ + ../tbb_2020.3/src/tbb/scheduler.h \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/src/tbb/mailbox.h ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/intrusive_list.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/src/tbb/arena.h ../tbb_2020.3/src/tbb/task_stream.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/src/tbb/observer_proxy.h \ + ../tbb_2020.3/include/tbb/task_scheduler_observer.h \ + ../tbb_2020.3/include/tbb/task_arena.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h ../tbb_2020.3/src/tbb/market.h \ + ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/src/tbb/semaphore.h ../tbb_2020.3/src/tbb/dynamic_link.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/governor.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/governor.o new file mode 100644 index 00000000..f94cb6a3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/governor.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify.d new file mode 100644 index 00000000..39c7bc88 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify.d @@ -0,0 +1,13 @@ +itt_notify.o: ../tbb_2020.3/src/tbb/itt_notify.cpp \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify_static.c \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify_config.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify_types.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/disable_warnings.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify_static.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify.o new file mode 100644 index 00000000..615aedd5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify_malloc.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify_malloc.d new file mode 100644 index 00000000..f4301c95 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify_malloc.d @@ -0,0 +1,13 @@ +itt_notify_malloc.o: ../tbb_2020.3/src/tbb/itt_notify.cpp \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify_static.c \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify_config.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify_types.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/disable_warnings.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify_static.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify_malloc.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify_malloc.o new file mode 100644 index 00000000..de8ba2d3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/itt_notify_malloc.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/large_objects.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/large_objects.d new file mode 100644 index 00000000..9fa1ebd3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/large_objects.d @@ -0,0 +1,32 @@ +large_objects.o: ../tbb_2020.3/src/tbbmalloc/large_objects.cpp \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal.h \ + ../tbb_2020.3/src/tbbmalloc/TypeDefinitions.h \ + ../tbb_2020.3/src/tbbmalloc/Customize.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbbmalloc/Synchronize.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbbmalloc/proxy.h \ + ../tbb_2020.3/include/tbb/internal/_aggregator_impl.h \ + ../tbb_2020.3/include/tbb/internal/../atomic.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbbmalloc/shared_utils.h \ + ../tbb_2020.3/include/tbb/scalable_allocator.h \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h \ + ../tbb_2020.3/src/tbbmalloc/Statistics.h \ + ../tbb_2020.3/src/tbbmalloc/large_objects.h \ + ../tbb_2020.3/src/tbbmalloc/backend.h \ + ../tbb_2020.3/src/tbb/tbb_environment.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/large_objects.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/large_objects.o new file mode 100644 index 00000000..190746d4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/large_objects.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbb.so b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbb.so new file mode 100644 index 00000000..43e23674 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbb.so @@ -0,0 +1 @@ +INPUT (libtbb.so.2) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbb.so.2 b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbb.so.2 new file mode 100755 index 00000000..7250a170 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbb.so.2 differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc.so b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc.so new file mode 100644 index 00000000..2ee0cac0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc.so @@ -0,0 +1 @@ +INPUT (libtbbmalloc.so.2) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc.so.2 b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc.so.2 new file mode 100755 index 00000000..62520c49 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc.so.2 differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc_proxy.so b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc_proxy.so new file mode 100644 index 00000000..aa866c28 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc_proxy.so @@ -0,0 +1 @@ +INPUT (libtbbmalloc_proxy.so.2) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc_proxy.so.2 b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc_proxy.so.2 new file mode 100755 index 00000000..0e351e57 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/libtbbmalloc_proxy.so.2 differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/market.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/market.d new file mode 100644 index 00000000..ce7bb118 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/market.d @@ -0,0 +1,59 @@ +market.o: ../tbb_2020.3/src/tbb/market.cpp \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/global_control.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h ../tbb_2020.3/src/tbb/market.h \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/intrusive_list.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/src/tbb/tbb_main.h ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/cilk-tbb-interop.h \ + ../tbb_2020.3/src/tbb/tbb_environment.h \ + ../tbb_2020.3/src/tbb/scheduler.h ../tbb_2020.3/src/tbb/mailbox.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/arena.h ../tbb_2020.3/src/tbb/task_stream.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/src/tbb/observer_proxy.h \ + ../tbb_2020.3/include/tbb/task_scheduler_observer.h \ + ../tbb_2020.3/include/tbb/task_arena.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/src/tbb/semaphore.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/market.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/market.o new file mode 100644 index 00000000..6612bbef Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/market.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/mutex.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/mutex.d new file mode 100644 index 00000000..68e232bf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/mutex.d @@ -0,0 +1,28 @@ +mutex.o: ../tbb_2020.3/src/tbb/mutex.cpp \ + ../tbb_2020.3/include/tbb/mutex.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/atomic.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/cilk-tbb-interop.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/mutex.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/mutex.o new file mode 100644 index 00000000..cf68edcd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/mutex.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/observer_proxy.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/observer_proxy.d new file mode 100644 index 00000000..6688e3df --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/observer_proxy.d @@ -0,0 +1,58 @@ +observer_proxy.o: ../tbb_2020.3/src/tbb/observer_proxy.cpp \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbb/observer_proxy.h \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/include/tbb/task_scheduler_observer.h \ + ../tbb_2020.3/include/tbb/task_arena.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/src/tbb/tbb_main.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/cilk-tbb-interop.h \ + ../tbb_2020.3/src/tbb/tbb_environment.h \ + ../tbb_2020.3/src/tbb/scheduler.h ../tbb_2020.3/src/tbb/mailbox.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/intrusive_list.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/src/tbb/arena.h ../tbb_2020.3/src/tbb/task_stream.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h ../tbb_2020.3/src/tbb/market.h \ + ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/src/tbb/semaphore.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/observer_proxy.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/observer_proxy.o new file mode 100644 index 00000000..d9c7b6ba Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/observer_proxy.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/pipeline.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/pipeline.d new file mode 100644 index 00000000..1029babc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/pipeline.d @@ -0,0 +1,30 @@ +pipeline.o: ../tbb_2020.3/src/tbb/pipeline.cpp \ + ../tbb_2020.3/include/tbb/pipeline.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/semaphore.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/src/tbb/tls.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/pipeline.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/pipeline.o new file mode 100644 index 00000000..7d30b4b7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/pipeline.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/private_server.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/private_server.d new file mode 100644 index 00000000..63f2b1e7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/private_server.d @@ -0,0 +1,39 @@ +private_server.o: ../tbb_2020.3/src/tbb/private_server.cpp \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/../rml/server/thread_monitor.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbb/semaphore.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/cilk-tbb-interop.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/private_server.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/private_server.o new file mode 100644 index 00000000..c0a60691 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/private_server.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/proxy.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/proxy.d new file mode 100644 index 00000000..417125a9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/proxy.d @@ -0,0 +1,12 @@ +proxy.o: ../tbb_2020.3/src/tbbmalloc/proxy.cpp \ + ../tbb_2020.3/src/tbbmalloc/proxy.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbb/tbb_environment.h \ + ../tbb_2020.3/src/tbbmalloc/Synchronize.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/proxy.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/proxy.o new file mode 100644 index 00000000..792bd7b5 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/proxy.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_mutex.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_mutex.d new file mode 100644 index 00000000..8414c1ed --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_mutex.d @@ -0,0 +1,23 @@ +queuing_mutex.o: ../tbb_2020.3/src/tbb/queuing_mutex.cpp \ + ../tbb_2020.3/include/tbb/queuing_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h ../tbb_2020.3/src/tbb/tbb_misc.h \ + ../tbb_2020.3/include/tbb/atomic.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_mutex.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_mutex.o new file mode 100644 index 00000000..bb0814fe Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_mutex.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_rw_mutex.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_rw_mutex.d new file mode 100644 index 00000000..2bc532f7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_rw_mutex.d @@ -0,0 +1,22 @@ +queuing_rw_mutex.o: ../tbb_2020.3/src/tbb/queuing_rw_mutex.cpp \ + ../tbb_2020.3/include/tbb/queuing_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_rw_mutex.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_rw_mutex.o new file mode 100644 index 00000000..6229a64e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/queuing_rw_mutex.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/reader_writer_lock.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/reader_writer_lock.d new file mode 100644 index 00000000..da36b3b9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/reader_writer_lock.d @@ -0,0 +1,25 @@ +reader_writer_lock.o: ../tbb_2020.3/src/tbb/reader_writer_lock.cpp \ + ../tbb_2020.3/include/tbb/reader_writer_lock.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_thread.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_hash_compare_impl.h \ + ../tbb_2020.3/include/tbb/tick_count.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/reader_writer_lock.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/reader_writer_lock.o new file mode 100644 index 00000000..2c3e5885 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/reader_writer_lock.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/recursive_mutex.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/recursive_mutex.d new file mode 100644 index 00000000..c604b1bc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/recursive_mutex.d @@ -0,0 +1,21 @@ +recursive_mutex.o: ../tbb_2020.3/src/tbb/recursive_mutex.cpp \ + ../tbb_2020.3/include/tbb/recursive_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/recursive_mutex.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/recursive_mutex.o new file mode 100644 index 00000000..1ce8f877 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/recursive_mutex.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/rml_tbb.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/rml_tbb.d new file mode 100644 index 00000000..44252aa6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/rml_tbb.d @@ -0,0 +1,8 @@ +rml_tbb.o: ../tbb_2020.3/src/rml/client/rml_tbb.cpp \ + ../tbb_2020.3/src/rml/client/../include/rml_tbb.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/rml/client/../include/rml_base.h \ + ../tbb_2020.3/src/tbb/dynamic_link.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/rml/client/rml_factory.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/rml_tbb.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/rml_tbb.o new file mode 100644 index 00000000..272cd974 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/rml_tbb.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/scheduler.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/scheduler.d new file mode 100644 index 00000000..baae623f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/scheduler.d @@ -0,0 +1,59 @@ +scheduler.o: ../tbb_2020.3/src/tbb/scheduler.cpp \ + ../tbb_2020.3/src/tbb/custom_scheduler.h \ + ../tbb_2020.3/src/tbb/scheduler.h \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/src/tbb/mailbox.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/intrusive_list.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/src/tbb/cilk-tbb-interop.h ../tbb_2020.3/src/tbb/arena.h \ + ../tbb_2020.3/src/tbb/task_stream.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/src/tbb/observer_proxy.h \ + ../tbb_2020.3/include/tbb/task_scheduler_observer.h \ + ../tbb_2020.3/include/tbb/task_arena.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h ../tbb_2020.3/src/tbb/market.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/src/tbb/semaphore.h \ + ../tbb_2020.3/src/tbb/scheduler_utility.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/scheduler.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/scheduler.o new file mode 100644 index 00000000..1152678e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/scheduler.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/semaphore.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/semaphore.d new file mode 100644 index 00000000..67288afa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/semaphore.d @@ -0,0 +1,15 @@ +semaphore.o: ../tbb_2020.3/src/tbb/semaphore.cpp \ + ../tbb_2020.3/src/tbb/semaphore.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/semaphore.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/semaphore.o new file mode 100644 index 00000000..ef0fd721 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/semaphore.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_mutex.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_mutex.d new file mode 100644 index 00000000..4b382a19 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_mutex.d @@ -0,0 +1,27 @@ +spin_mutex.o: ../tbb_2020.3/src/tbb/spin_mutex.cpp \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/info.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_mutex.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_mutex.o new file mode 100644 index 00000000..a3107bd8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_mutex.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex.d new file mode 100644 index 00000000..7f0e65a9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex.d @@ -0,0 +1,28 @@ +spin_rw_mutex.o: ../tbb_2020.3/src/tbb/spin_rw_mutex.cpp \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/atomic.h ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex.o new file mode 100644 index 00000000..a068420e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex_v2.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex_v2.d new file mode 100644 index 00000000..4b00906c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex_v2.d @@ -0,0 +1,20 @@ +spin_rw_mutex_v2.o: ../tbb_2020.3/src/old/spin_rw_mutex_v2.cpp \ + ../tbb_2020.3/src/old/spin_rw_mutex_v2.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/src/old/../tbb/itt_notify.h \ + ../tbb_2020.3/src/old/../tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/old/../tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex_v2.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex_v2.o new file mode 100644 index 00000000..1feaa5be Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/spin_rw_mutex_v2.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task.d new file mode 100644 index 00000000..b868d674 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task.d @@ -0,0 +1,58 @@ +task.o: ../tbb_2020.3/src/tbb/task.cpp \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/info.h ../tbb_2020.3/src/tbb/tls.h \ + ../tbb_2020.3/src/tbb/cilk-tbb-interop.h \ + ../tbb_2020.3/src/tbb/scheduler.h ../tbb_2020.3/src/tbb/mailbox.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/intrusive_list.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/src/tbb/arena.h ../tbb_2020.3/src/tbb/task_stream.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/src/tbb/observer_proxy.h \ + ../tbb_2020.3/include/tbb/task_scheduler_observer.h \ + ../tbb_2020.3/include/tbb/task_arena.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h ../tbb_2020.3/src/tbb/market.h \ + ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/src/tbb/semaphore.h \ + ../tbb_2020.3/include/tbb/partitioner.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task.o new file mode 100644 index 00000000..e627d690 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_group_context.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_group_context.d new file mode 100644 index 00000000..4b2076ec --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_group_context.d @@ -0,0 +1,57 @@ +task_group_context.o: ../tbb_2020.3/src/tbb/task_group_context.cpp \ + ../tbb_2020.3/src/tbb/scheduler.h \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/src/tbb/mailbox.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/intrusive_list.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/src/tbb/cilk-tbb-interop.h ../tbb_2020.3/src/tbb/arena.h \ + ../tbb_2020.3/src/tbb/task_stream.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/src/tbb/observer_proxy.h \ + ../tbb_2020.3/include/tbb/task_scheduler_observer.h \ + ../tbb_2020.3/include/tbb/task_arena.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h ../tbb_2020.3/src/tbb/market.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/concurrent_monitor.h \ + ../tbb_2020.3/src/tbb/semaphore.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_group_context.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_group_context.o new file mode 100644 index 00000000..e1cc81d4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_group_context.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_v2.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_v2.d new file mode 100644 index 00000000..96b8502a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_v2.d @@ -0,0 +1,17 @@ +task_v2.o: ../tbb_2020.3/src/old/task_v2.cpp \ + ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_v2.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_v2.o new file mode 100644 index 00000000..ba014aa9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/task_v2.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb-make-check b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb-make-check new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb.def new file mode 100644 index 00000000..e785c08a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb.def @@ -0,0 +1,405 @@ +# 1 "../tbb_2020.3/src/tbb/lin64-tbb-export.def" +# 1 "/project/python/build/lib.linux-x86_64-cpython-39/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb//" +# 1 "" +# 1 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 1 "" 2 +# 1 "../tbb_2020.3/src/tbb/lin64-tbb-export.def" +# 17 "../tbb_2020.3/src/tbb/lin64-tbb-export.def" +{ +global: + + +# 1 "../tbb_2020.3/src/tbb/lin64-tbb-export.lst" 1 +# 17 "../tbb_2020.3/src/tbb/lin64-tbb-export.lst" +# 1 "../tbb_2020.3/include/tbb/tbb_config.h" 1 +# 18 "../tbb_2020.3/src/tbb/lin64-tbb-export.lst" 2 + + +_ZN3tbb8internal12NFS_AllocateEmmPv; +_ZN3tbb8internal15NFS_GetLineSizeEv; +_ZN3tbb8internal8NFS_FreeEPv; +_ZN3tbb8internal23allocate_via_handler_v3Em; +_ZN3tbb8internal25deallocate_via_handler_v3EPv; +_ZN3tbb8internal17is_malloc_used_v3Ev; + + +_ZN3tbb4task13note_affinityEt; +_ZN3tbb4task22internal_set_ref_countEi; +_ZN3tbb4task28internal_decrement_ref_countEv; +_ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE; +_ZN3tbb4task4selfEv; +_ZN3tbb10interface58internal9task_base7destroyERNS_4taskE; +_ZNK3tbb4task26is_owned_by_current_threadEv; +_ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE; +_ZN3tbb8internal19allocate_root_proxy8allocateEm; +_ZN3tbb8internal28affinity_partitioner_base_v36resizeEj; +_ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE; +_ZNK3tbb8internal20allocate_child_proxy8allocateEm; +_ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE; +_ZNK3tbb8internal27allocate_continuation_proxy8allocateEm; +_ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE; +_ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm; +_ZTIN3tbb4taskE; +_ZTSN3tbb4taskE; +_ZTVN3tbb4taskE; +_ZN3tbb19task_scheduler_init19default_num_threadsEv; +_ZN3tbb19task_scheduler_init10initializeEim; +_ZN3tbb19task_scheduler_init10initializeEi; +_ZN3tbb19task_scheduler_init9terminateEv; +_ZN3tbb19task_scheduler_init27internal_blocking_terminateEb; + +_ZN3tbb8internal26task_scheduler_observer_v37observeEb; + +_ZN3tbb10empty_task7executeEv; +_ZN3tbb10empty_taskD0Ev; +_ZN3tbb10empty_taskD1Ev; +_ZTIN3tbb10empty_taskE; +_ZTSN3tbb10empty_taskE; +_ZTVN3tbb10empty_taskE; + + +_ZN3tbb10interface78internal15task_arena_base19internal_initializeEv; +_ZN3tbb10interface78internal15task_arena_base18internal_terminateEv; +_ZN3tbb10interface78internal15task_arena_base15internal_attachEv; +_ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl; +_ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE; +_ZNK3tbb10interface78internal15task_arena_base13internal_waitEv; +_ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv; +_ZN3tbb10interface78internal15task_arena_base24internal_max_concurrencyEPKNS0_10task_arenaE; + +_ZN3tbb8internal13numa_topology11nodes_countEv; +_ZN3tbb8internal13numa_topology4fillEPi; +_ZN3tbb8internal13numa_topology19default_concurrencyEi; + + +_ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl; + + + + +_ZN3tbb4task7destroyERS0_; + + + + +_ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm; +_ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE; +_ZN3tbb4task12change_groupERNS_18task_group_contextE; +_ZNK3tbb18task_group_context28is_group_execution_cancelledEv; +_ZN3tbb18task_group_context22cancel_group_executionEv; +_ZN3tbb18task_group_context26register_pending_exceptionEv; +_ZN3tbb18task_group_context5resetEv; +_ZN3tbb18task_group_context19capture_fp_settingsEv; +_ZN3tbb18task_group_context4initEv; +_ZN3tbb18task_group_contextD1Ev; +_ZN3tbb18task_group_contextD2Ev; + +_ZN3tbb18task_group_context12set_priorityENS_10priority_tE; +_ZNK3tbb18task_group_context8priorityEv; + +_ZNK3tbb18captured_exception4nameEv; +_ZNK3tbb18captured_exception4whatEv; +_ZN3tbb18captured_exception10throw_selfEv; +_ZN3tbb18captured_exception3setEPKcS2_; +_ZN3tbb18captured_exception4moveEv; +_ZN3tbb18captured_exception5clearEv; +_ZN3tbb18captured_exception7destroyEv; +_ZN3tbb18captured_exception8allocateEPKcS2_; +_ZN3tbb18captured_exceptionD0Ev; +_ZN3tbb18captured_exceptionD1Ev; +_ZN3tbb18captured_exceptionD2Ev; +_ZTIN3tbb18captured_exceptionE; +_ZTSN3tbb18captured_exceptionE; +_ZTVN3tbb18captured_exceptionE; +_ZN3tbb13tbb_exceptionD2Ev; +_ZTIN3tbb13tbb_exceptionE; +_ZTSN3tbb13tbb_exceptionE; +_ZTVN3tbb13tbb_exceptionE; + + + +_ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev; +_ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE; +_ZN3tbb14bad_last_allocD0Ev; +_ZN3tbb14bad_last_allocD1Ev; +_ZNK3tbb14bad_last_alloc4whatEv; +_ZTIN3tbb14bad_last_allocE; +_ZTSN3tbb14bad_last_allocE; +_ZTVN3tbb14bad_last_allocE; +_ZN3tbb12missing_waitD0Ev; +_ZN3tbb12missing_waitD1Ev; +_ZNK3tbb12missing_wait4whatEv; +_ZTIN3tbb12missing_waitE; +_ZTSN3tbb12missing_waitE; +_ZTVN3tbb12missing_waitE; +_ZN3tbb27invalid_multiple_schedulingD0Ev; +_ZN3tbb27invalid_multiple_schedulingD1Ev; +_ZNK3tbb27invalid_multiple_scheduling4whatEv; +_ZTIN3tbb27invalid_multiple_schedulingE; +_ZTSN3tbb27invalid_multiple_schedulingE; +_ZTVN3tbb27invalid_multiple_schedulingE; +_ZN3tbb13improper_lockD0Ev; +_ZN3tbb13improper_lockD1Ev; +_ZNK3tbb13improper_lock4whatEv; +_ZTIN3tbb13improper_lockE; +_ZTSN3tbb13improper_lockE; +_ZTVN3tbb13improper_lockE; +_ZN3tbb10user_abortD0Ev; +_ZN3tbb10user_abortD1Ev; +_ZNK3tbb10user_abort4whatEv; +_ZTIN3tbb10user_abortE; +_ZTSN3tbb10user_abortE; +_ZTVN3tbb10user_abortE; + +_ZN3tbb17assertion_failureEPKciS1_S1_; +_ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E; +_ZN3tbb8internal36get_initial_auto_partitioner_divisorEv; +_ZN3tbb8internal13handle_perrorEiPKc; +_ZN3tbb8internal15runtime_warningEPKcz; +TBB_runtime_interface_version; + + +_ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv; +_ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_; +_ZN3tbb8internal18call_itt_notify_v5EiPv; +_ZN3tbb8internal20itt_set_sync_name_v3EPvPKc; +_ZN3tbb8internal19itt_load_pointer_v3EPKv; +_ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc; +_ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE; +_ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE; +_ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y; +_ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE; +_ZN3tbb8internal19itt_region_begin_v9ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE; +_ZN3tbb8internal17itt_region_end_v9ENS0_15itt_domain_enumEPvy; +_ZN3tbb8internal24itt_metadata_ptr_add_v11ENS0_15itt_domain_enumEPvyNS0_12string_indexES2_; + + +_ZTIN3tbb6filterE; +_ZTSN3tbb6filterE; +_ZTVN3tbb6filterE; +_ZN3tbb6filterD2Ev; +_ZN3tbb8pipeline10add_filterERNS_6filterE; +_ZN3tbb8pipeline12inject_tokenERNS_4taskE; +_ZN3tbb8pipeline13remove_filterERNS_6filterE; +_ZN3tbb8pipeline3runEm; + +_ZN3tbb8pipeline3runEmRNS_18task_group_contextE; + +_ZN3tbb8pipeline5clearEv; +_ZN3tbb19thread_bound_filter12process_itemEv; +_ZN3tbb19thread_bound_filter16try_process_itemEv; +_ZTIN3tbb8pipelineE; +_ZTSN3tbb8pipelineE; +_ZTVN3tbb8pipelineE; +_ZN3tbb8pipelineC1Ev; +_ZN3tbb8pipelineC2Ev; +_ZN3tbb8pipelineD0Ev; +_ZN3tbb8pipelineD1Ev; +_ZN3tbb8pipelineD2Ev; +_ZN3tbb6filter16set_end_of_inputEv; + + +_ZN3tbb16queuing_rw_mutex18internal_constructEv; +_ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv; +_ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv; +_ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b; +_ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv; +_ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b; + + +_ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv; +_ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_; +_ZN3tbb10interface518reader_writer_lock13try_lock_readEv; +_ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv; +_ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_; +_ZN3tbb10interface518reader_writer_lock16internal_destroyEv; +_ZN3tbb10interface518reader_writer_lock18internal_constructEv; +_ZN3tbb10interface518reader_writer_lock4lockEv; +_ZN3tbb10interface518reader_writer_lock6unlockEv; +_ZN3tbb10interface518reader_writer_lock8try_lockEv; +_ZN3tbb10interface518reader_writer_lock9lock_readEv; + + + +_ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_; +_ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_; +_ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_; +_ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_; +_ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_; +_ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_; +_ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_; +_ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_; +_ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_; + + + + +_ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv; +_ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb; +_ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE; +_ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb; +_ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE; +_ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE; +_ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE; + + + +_ZN3tbb16spin_rw_mutex_v318internal_constructEv; +_ZN3tbb16spin_rw_mutex_v316internal_upgradeEv; +_ZN3tbb16spin_rw_mutex_v318internal_downgradeEv; +_ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv; +_ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv; +_ZN3tbb16spin_rw_mutex_v323internal_release_readerEv; +_ZN3tbb16spin_rw_mutex_v323internal_release_writerEv; +_ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv; +_ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv; + + +_ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_; +_ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv; +_ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_; +_ZN3tbb10spin_mutex18internal_constructEv; + + +_ZN3tbb5mutex11scoped_lock16internal_acquireERS0_; +_ZN3tbb5mutex11scoped_lock16internal_releaseEv; +_ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_; +_ZN3tbb5mutex16internal_destroyEv; +_ZN3tbb5mutex18internal_constructEv; + + +_ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_; +_ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv; +_ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_; +_ZN3tbb15recursive_mutex16internal_destroyEv; +_ZN3tbb15recursive_mutex18internal_constructEv; + + +_ZN3tbb13queuing_mutex18internal_constructEv; +_ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_; +_ZN3tbb13queuing_mutex11scoped_lock7releaseEv; +_ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_; + + +_ZN3tbb8internal19critical_section_v418internal_constructEv; + + + +_ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv; + + +_ZN3tbb8internal21concurrent_queue_base12internal_popEPv; +_ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv; +_ZN3tbb8internal21concurrent_queue_base21internal_set_capacityElm; +_ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv; +_ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv; +_ZN3tbb8internal21concurrent_queue_baseC2Em; +_ZN3tbb8internal21concurrent_queue_baseD2Ev; +_ZTIN3tbb8internal21concurrent_queue_baseE; +_ZTSN3tbb8internal21concurrent_queue_baseE; +_ZTVN3tbb8internal21concurrent_queue_baseE; +_ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_; +_ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv; +_ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE; +_ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev; +_ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv; + + + + +_ZN3tbb8internal24concurrent_queue_base_v3C2Em; +_ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E; +_ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em; + +_ZN3tbb8internal24concurrent_queue_base_v3D2Ev; +_ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev; + +_ZTIN3tbb8internal24concurrent_queue_base_v3E; +_ZTSN3tbb8internal24concurrent_queue_base_v3E; + +_ZTVN3tbb8internal24concurrent_queue_base_v3E; + +_ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_; +_ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv; +_ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv; +_ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv; +_ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv; +_ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv; +_ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv; +_ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv; +_ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv; +_ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv; +_ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityElm; +_ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv; +_ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv; +_ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv; +_ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_; +_ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_; + + + +_ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE; +_ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb; +_ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_; +_ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE; +_ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm; +_ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm; +_ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE; +_ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv; + + + +_ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE; +_ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE; +_ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_; +_ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_; +_ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm; +_ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm; +_ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_; +_ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv; +_ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE; +_ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_; +_ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm; +_ZN3tbb8internal25concurrent_vector_base_v3D2Ev; +_ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE; +_ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_; + + +_ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv; +_ZN3tbb8internal13tbb_thread_v36detachEv; +_ZN3tbb8internal16thread_get_id_v3Ev; +_ZN3tbb8internal15free_closure_v3EPv; +_ZN3tbb8internal13tbb_thread_v34joinEv; +_ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_; +_ZN3tbb8internal19allocate_closure_v3Em; +_ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_; +_ZN3tbb8internal15thread_yield_v3Ev; +_ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE; + + +_ZN3tbb10interface914global_control12active_valueEi; +_ZN3tbb10interface914global_control15internal_createEv; +_ZN3tbb10interface914global_control16internal_destroyEv; +# 22 "../tbb_2020.3/src/tbb/lin64-tbb-export.def" 2 + +local: + + +*3tbb*; +*__TBB*; + + +__itt_*; + + +__intel_*; +_intel_*; +get_msg_buf; +get_text_buf; +message_catalog; +print_buf; +irc__get_msg; +irc__print; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_function_replacement.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_function_replacement.d new file mode 100644 index 00000000..88540f46 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_function_replacement.d @@ -0,0 +1,3 @@ +tbb_function_replacement.o: \ + ../tbb_2020.3/src/tbbmalloc/tbb_function_replacement.cpp \ + ../tbb_2020.3/include/tbb/tbb_config.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_function_replacement.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_function_replacement.o new file mode 100644 index 00000000..745320ca Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_function_replacement.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_main.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_main.d new file mode 100644 index 00000000..12c0a133 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_main.d @@ -0,0 +1,47 @@ +tbb_main.o: ../tbb_2020.3/src/tbb/tbb_main.cpp \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/global_control.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h ../tbb_2020.3/src/tbb/tbb_main.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/cilk-tbb-interop.h \ + ../tbb_2020.3/src/tbb/tbb_environment.h ../tbb_2020.3/src/tbb/market.h \ + ../tbb_2020.3/src/tbb/scheduler_common.h \ + ../tbb_2020.3/include/tbb/cache_aligned_allocator.h \ + ../tbb_2020.3/src/tbb/tbb_statistics.h ../tbb_2020.3/include/tbb/task.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/spin_mutex.h \ + ../tbb_2020.3/include/tbb/aligned_space.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/src/tbb/intrusive_list.h \ + ../tbb_2020.3/include/tbb/internal/_template_helpers.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_main.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_main.o new file mode 100644 index 00000000..0c9b466d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_main.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc.d new file mode 100644 index 00000000..0a1ba336 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc.d @@ -0,0 +1,20 @@ +tbb_misc.o: ../tbb_2020.3/src/tbb/tbb_misc.cpp \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbb/tbb_assert_impl.h \ + ../tbb_2020.3/include/tbb/tbb_exception.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h ../tbb_2020.3/include/tbb/info.h \ + ../tbb_2020.3/src/tbb/tbb_version.h version_string.ver diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc.o new file mode 100644 index 00000000..57dca20f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc_ex.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc_ex.d new file mode 100644 index 00000000..36d2cd12 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc_ex.d @@ -0,0 +1,17 @@ +tbb_misc_ex.o: ../tbb_2020.3/src/tbb/tbb_misc_ex.cpp \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/info.h ../tbb_2020.3/src/tbb/dynamic_link.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc_ex.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc_ex.o new file mode 100644 index 00000000..1b2ba063 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_misc_ex.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_statistics.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_statistics.d new file mode 100644 index 00000000..a1d19f15 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_statistics.d @@ -0,0 +1,4 @@ +tbb_statistics.o: ../tbb_2020.3/src/tbb/tbb_statistics.cpp \ + ../tbb_2020.3/src/tbb/tbb_statistics.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_statistics.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_statistics.o new file mode 100644 index 00000000..c9a1f3f1 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_statistics.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_thread.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_thread.d new file mode 100644 index 00000000..394ba3c6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_thread.d @@ -0,0 +1,27 @@ +tbb_thread.o: ../tbb_2020.3/src/tbb/tbb_thread.cpp \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/info.h ../tbb_2020.3/include/tbb/tbb_thread.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_hash_compare_impl.h \ + ../tbb_2020.3/include/tbb/tick_count.h \ + ../tbb_2020.3/include/tbb/tbb_allocator.h \ + ../tbb_2020.3/include/tbb/global_control.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/tls.h ../tbb_2020.3/src/tbb/cilk-tbb-interop.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_thread.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_thread.o new file mode 100644 index 00000000..f9e16a6a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbb_thread.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.d new file mode 100644 index 00000000..24f20e99 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.d @@ -0,0 +1,27 @@ +tbbmalloc.o: ../tbb_2020.3/src/tbbmalloc/tbbmalloc.cpp \ + ../tbb_2020.3/src/tbbmalloc/TypeDefinitions.h \ + ../tbb_2020.3/src/tbbmalloc/Customize.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/src/tbbmalloc/Synchronize.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbbmalloc/proxy.h \ + ../tbb_2020.3/include/tbb/internal/_aggregator_impl.h \ + ../tbb_2020.3/include/tbb/internal/../atomic.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/src/tbbmalloc/shared_utils.h \ + ../tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h \ + ../tbb_2020.3/src/tbbmalloc/../tbb/tbb_assert_impl.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.def new file mode 100644 index 00000000..091ba806 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.def @@ -0,0 +1,65 @@ +# 1 "../tbb_2020.3/src/tbbmalloc/lin64-tbbmalloc-export.def" +# 1 "/project/python/build/lib.linux-x86_64-cpython-39/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb//" +# 1 "" +# 1 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 1 "" 2 +# 1 "../tbb_2020.3/src/tbbmalloc/lin64-tbbmalloc-export.def" +# 17 "../tbb_2020.3/src/tbbmalloc/lin64-tbbmalloc-export.def" +{ +global: + +scalable_calloc; +scalable_free; +scalable_malloc; +scalable_realloc; +scalable_posix_memalign; +scalable_aligned_malloc; +scalable_aligned_realloc; +scalable_aligned_free; +scalable_msize; +scalable_allocation_mode; +scalable_allocation_command; +__TBB_malloc_safer_aligned_msize; +__TBB_malloc_safer_aligned_realloc; +__TBB_malloc_safer_free; +__TBB_malloc_safer_msize; +__TBB_malloc_safer_realloc; + + +_ZN3rml11pool_createElPKNS_13MemPoolPolicyE; +_ZN3rml14pool_create_v1ElPKNS_13MemPoolPolicyEPPNS_10MemoryPoolE; +_ZN3rml10pool_resetEPNS_10MemoryPoolE; +_ZN3rml11pool_mallocEPNS_10MemoryPoolEm; +_ZN3rml12pool_destroyEPNS_10MemoryPoolE; +_ZN3rml9pool_freeEPNS_10MemoryPoolEPv; +_ZN3rml12pool_reallocEPNS_10MemoryPoolEPvm; +_ZN3rml20pool_aligned_reallocEPNS_10MemoryPoolEPvmm; +_ZN3rml19pool_aligned_mallocEPNS_10MemoryPoolEmm; +_ZN3rml13pool_identifyEPv; +_ZN3rml10pool_msizeEPNS_10MemoryPoolEPv; + +local: + + +*3rml*; +*3tbb*; +*__TBB*; +__itt_*; +ITT_DoOneTimeInitialization; +TBB_runtime_interface_version; + + +__intel_*; +_intel_*; +get_memcpy_largest_cachelinesize; +get_memcpy_largest_cache_size; +get_mem_ops_method; +init_mem_ops_method; +irc__get_msg; +irc__print; +override_mem_ops_method; +set_memcpy_largest_cachelinesize; +set_memcpy_largest_cache_size; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.o new file mode 100644 index 00000000..3300c05a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmalloc.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmallocproxy.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmallocproxy.def new file mode 100644 index 00000000..1f7ee8d7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbmallocproxy.def @@ -0,0 +1,47 @@ +# 1 "../tbb_2020.3/src/tbbmalloc/lin64-proxy-export.def" +# 1 "/project/python/build/lib.linux-x86_64-cpython-39/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb//" +# 1 "" +# 1 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 1 "" 2 +# 1 "../tbb_2020.3/src/tbbmalloc/lin64-proxy-export.def" +# 17 "../tbb_2020.3/src/tbbmalloc/lin64-proxy-export.def" +{ +global: +calloc; +free; +malloc; +realloc; +posix_memalign; +memalign; +aligned_alloc; +valloc; +pvalloc; +mallinfo; +mallopt; +malloc_usable_size; +__libc_malloc; +__libc_realloc; +__libc_calloc; +__libc_free; +__libc_memalign; +__libc_pvalloc; +__libc_valloc; +__TBB_malloc_proxy; +_ZdaPv; +_ZdaPvRKSt9nothrow_t; +_ZdlPv; +_ZdlPvRKSt9nothrow_t; +_Znam; +_ZnamRKSt9nothrow_t; +_Znwm; +_ZnwmRKSt9nothrow_t; + +local: + + +*3rml8internal*; +*3tbb*; +*__TBB*; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbvars.csh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbvars.csh new file mode 100644 index 00000000..63136cdc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbvars.csh @@ -0,0 +1,19 @@ +#!/bin/csh +setenv TBBROOT "/project/python/build/lib.linux-x86_64-cpython-39/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3" # +setenv tbb_bin "/project/python/build/lib.linux-x86_64-cpython-39/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb" # +if (! $?CPATH) then # + setenv CPATH "${TBBROOT}/include" # +else # + setenv CPATH "${TBBROOT}/include:$CPATH" # +endif # +if (! $?LIBRARY_PATH) then # + setenv LIBRARY_PATH "${tbb_bin}" # +else # + setenv LIBRARY_PATH "${tbb_bin}:$LIBRARY_PATH" # +endif # +if (! $?LD_LIBRARY_PATH) then # + setenv LD_LIBRARY_PATH "${tbb_bin}" # +else # + setenv LD_LIBRARY_PATH "${tbb_bin}:$LD_LIBRARY_PATH" # +endif # + # diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbvars.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbvars.sh new file mode 100644 index 00000000..fb5d5322 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/tbbvars.sh @@ -0,0 +1,19 @@ +#!/bin/bash +export TBBROOT="/project/python/build/lib.linux-x86_64-cpython-39/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3" # +tbb_bin="/project/python/build/lib.linux-x86_64-cpython-39/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb" # +if [ -z "$CPATH" ]; then # + export CPATH="${TBBROOT}/include" # +else # + export CPATH="${TBBROOT}/include:$CPATH" # +fi # +if [ -z "$LIBRARY_PATH" ]; then # + export LIBRARY_PATH="${tbb_bin}" # +else # + export LIBRARY_PATH="${tbb_bin}:$LIBRARY_PATH" # +fi # +if [ -z "$LD_LIBRARY_PATH" ]; then # + export LD_LIBRARY_PATH="${tbb_bin}" # +else # + export LD_LIBRARY_PATH="${tbb_bin}:$LD_LIBRARY_PATH" # +fi # + # diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/version_string.ver b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/version_string.ver new file mode 100644 index 00000000..3e5a568d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/version_string.ver @@ -0,0 +1,11 @@ +#define __TBB_VERSION_STRINGS(N) \ +#N": BUILD_HOST\t\t2a271dfa64e5 (x86_64)" ENDL \ +#N": BUILD_OS\t\tCentOS Linux release 7.9.2009 (Core)" ENDL \ +#N": BUILD_KERNEL\tLinux 6.11.0-1014-azure #14~24.04.1-Ubuntu SMP Thu Apr 24 17:41:03 UTC 2025" ENDL \ +#N": BUILD_GCC\t\tg++ (GCC) 10.2.1 20210130 (Red Hat 10.2.1-11)" ENDL \ +#N": BUILD_LIBC\t2.17" ENDL \ +#N": BUILD_LD\t\tGNU ld version 2.35-5.el7.4" ENDL \ +#N": BUILD_TARGET\tintel64 on cc10.2.1_libc2.17_kernel6.11.0" ENDL \ +#N": BUILD_COMMAND\tg++ -O2 -g -DDO_ITT_NOTIFY -DUSE_PTHREAD -pthread -m64 -mrtm -Wall -Wextra -Wno-unknown-warning-option -Wno-deprecated-copy -Wno-missing-attributes -Wno-class-memaccess -Wno-sized-deallocation -DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 -std=c++1y -I../tbb_2020.3/src -I../tbb_2020.3/src/rml/include -I../tbb_2020.3/include" ENDL \ + +#define __TBB_DATETIME "Fri May 30 11:38:49 UTC 2025" diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/version_tbb_2020.3 b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/version_tbb_2020.3 new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/x86_rtm_rw_mutex.d b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/x86_rtm_rw_mutex.d new file mode 100644 index 00000000..857e4c67 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/x86_rtm_rw_mutex.d @@ -0,0 +1,35 @@ +x86_rtm_rw_mutex.o: ../tbb_2020.3/src/tbb/x86_rtm_rw_mutex.cpp \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/include/tbb/tbb_config.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/include/tbb/machine/gcc_generic.h \ + ../tbb_2020.3/include/tbb/machine/gcc_ia32_common.h \ + ../tbb_2020.3/include/tbb/machine/gcc_itsx.h \ + ../tbb_2020.3/include/tbb/machine/linux_common.h \ + ../tbb_2020.3/include/tbb/tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_config.h \ + ../tbb_2020.3/include/tbb/internal/_tbb_strings.h \ + ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h \ + ../tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h \ + ../tbb_2020.3/include/tbb/internal/_mutex_padding.h \ + ../tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_stddef.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_machine.h \ + ../tbb_2020.3/include/tbb/internal/../tbb_profiling.h \ + ../tbb_2020.3/include/tbb/internal/../spin_rw_mutex.h \ + ../tbb_2020.3/include/tbb/tbb_machine.h \ + ../tbb_2020.3/src/tbb/itt_notify.h \ + ../tbb_2020.3/include/tbb/tbb_stddef.h \ + ../tbb_2020.3/src/tbb/tools_api/ittnotify.h \ + ../tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h \ + ../tbb_2020.3/src/tbb/governor.h \ + ../tbb_2020.3/include/tbb/task_scheduler_init.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_tbb.h \ + ../tbb_2020.3/src/tbb/../rml/include/rml_base.h \ + ../tbb_2020.3/src/tbb/tbb_misc.h ../tbb_2020.3/include/tbb/atomic.h \ + ../tbb_2020.3/include/tbb/info.h ../tbb_2020.3/src/tbb/tls.h \ + ../tbb_2020.3/src/tbb/cilk-tbb-interop.h diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/x86_rtm_rw_mutex.o b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/x86_rtm_rw_mutex.o new file mode 100644 index 00000000..6351e588 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb/x86_rtm_rw_mutex.o differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/.gitattributes b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/.gitattributes new file mode 100644 index 00000000..039edb3a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/.gitattributes @@ -0,0 +1,45 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.h text +*.cpp text +*.def text +*.rc text +*.i text +*.sh text +*.csh text +*.mk text +*.java text +*.csv text +*.lst text +*.asm text +*.cfg text +*.css text +*.inc text +*.js text +*.rb text +*.strings text +*.txt text +*export.lst text +*.xml text +*.py text +*.md text +*.classpath text +*.cproject text +*.project text +*.properties text +*.java text +*.gradle text + +# Declare files that will always have CRLF line endings on checkout. +*.sln text eol=crlf +*.bat text eol=crlf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.ico binary +*.spir binary diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/.gitignore b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/.gitignore new file mode 100644 index 00000000..864ef977 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/.gitignore @@ -0,0 +1,90 @@ +# Ignore the debug and release directories created with Makefile builds # +######################################################################### +build/*_debug/ +build/*_release/ + +# Compiled source # +################### +*.com +*.class +*.dll +*.lib +*.pdb +*.exe +*.o +*.so +*.so.1 +*.so.2 +*.dylib +*.a +*.obj +*.pyc + +*.orig +*.raw +*.sample +*.slo +*.swp +*.config +*.la +*.lai +*.lo +*.nhdr +*.nii.gz +*.nrrd + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.tgz +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# IDE generated files # +###################### +/.ninja_deps +/.ninja_log +/build.ninja +/rules.ninja +*~ +.emacs.desktop +.tags + +# Build system generated files # +################################ +CMakeCache.txt +CMakeFiles/ +cmake/TBBConfig.cmake +cmake/TBBConfigVersion.cmake + +# Other # +######### +.clang_complete +.idea +.svn +crash* +*.tmp +/.vs diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/CHANGES b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/CHANGES new file mode 100644 index 00000000..e96a9699 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/CHANGES @@ -0,0 +1,2919 @@ +------------------------------------------------------------------------ +The list of most significant changes made over time in +Intel(R) Threading Building Blocks (Intel(R) TBB). + +Intel TBB 2020 Update 3 +TBB_INTERFACE_VERSION == 11103 + +Changes (w.r.t. Intel TBB 2020 Update 2): + +Changes affecting backward compatibility: + +- Changed body type concept of the flow::input_node. + Set TBB_DEPRECATED_INPUT_NODE_BODY to 1 to compile with the previous + concept of the body type. + +Bugs fixed: + +- Fixed compilation errors in C++20 mode due to ambiguity of comparison + operators. Inspired by Barry Revzin + (https://github.com/oneapi-src/oneTBB/pull/251). + +Open-source contributions integrated: + +- Fixed an issue in TBBBuild.cmake that causes the build with no arguments + to fail (https://github.com/oneapi-src/oneTBB/pull/233) by tttapa. +- Added cmake/{TBBConfig,TBBConfigVersion}.cmake to Git ignore list + (https://github.com/oneapi-src/oneTBB/pull/239) by Eisuke Kawashima. + +------------------------------------------------------------------------ +Intel TBB 2020 Update 2 +TBB_INTERFACE_VERSION == 11102 + +Changes (w.r.t. Intel TBB 2020 Update 1): + +- Cross-allocator copying constructor and copy assignment operator for + concurrent_vector are deprecated. +- Added input_node to the flow graph API. It acts like a source_node + except for being inactive by default; source_node is deprecated. +- Allocator template parameter for flow graph nodes is deprecated. Set + TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to 1 to avoid compilation errors. +- Flow graph preview hetero-features are deprecated. + +Bugs fixed: + +- Fixed the task affinity mechanism to prevent unlimited memory + consumption in case the number of threads is explicitly decreased. +- Fixed memory leak related NUMA support functionality in task_arena. + +------------------------------------------------------------------------ +Intel TBB 2020 Update 1 +TBB_INTERFACE_VERSION == 11101 + +Changes (w.r.t. Intel TBB 2020): + +Preview features: + +- The NUMA support library (tbbbind) no more depends on the main + TBB library. + +Bugs fixed: + +- Fixed the issue of task_arena constraints not propagated on + copy construction. +- Fixed TBBGet.cmake script broken by TBB package name changes + (https://github.com/intel/tbb/issues/209). + +------------------------------------------------------------------------ +Intel TBB 2020 +TBB_INTERFACE_VERSION == 11100 + +Changes (w.r.t. Intel TBB 2019 Update 9): + +- Extended task_arena interface to simplify development of NUMA-aware + applications. +- Added warning notifications when the deprecated functionality is used. + +Open-source contributions integrated: + +- Fixed various build warnings + (https://github.com/intel/tbb/pull/179) by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 2019 Update 9 +TBB_INTERFACE_VERSION == 11009 + +Changes (w.r.t. Intel TBB 2019 Update 8): + +- Multiple APIs are deprecated. For details, please see + Deprecated Features appendix in the TBB reference manual. +- Added C++17 deduction guides for flow graph nodes. + +Preview Features: + +- Added isolated_task_group class that allows multiple threads to add + and execute tasks sharing the same isolation. +- Extended the flow graph API to simplify connecting nodes. +- Added erase() by heterogeneous keys for concurrent ordered containers. +- Added a possibility to suspend task execution at a specific point + and resume it later. + +Bugs fixed: + +- Fixed the emplace() method of concurrent unordered containers to + destroy a temporary element that was not inserted. +- Fixed a bug in the merge() method of concurrent unordered + containers. +- Fixed behavior of a continue_node that follows buffering nodes. +- Fixed compilation error caused by missed stdlib.h when CMake + integration is used (https://github.com/intel/tbb/issues/195). + Inspired by Andrew Penkrat. + +Open-source contributions integrated: + +- Added support for move-only types to tbb::parallel_pipeline + (https://github.com/intel/tbb/pull/159) by Raf Schietekat. +- Fixed detection of clang version when CUDA toolkit is installed + (https://github.com/intel/tbb/pull/150) by Guilherme Amadio. + +------------------------------------------------------------------------ +Intel TBB 2019 Update 8 +TBB_INTERFACE_VERSION == 11008 + +Changes (w.r.t. Intel TBB 2019 Update 7): + +Bugs fixed: + +- Fixed a bug in TBB 2019 Update 7 that could lead to incorrect memory + reallocation on Linux (https://github.com/intel/tbb/issues/148). +- Fixed enqueuing tbb::task into tbb::task_arena not to fail on threads + with no task scheduler initialized + (https://github.com/intel/tbb/issues/116). + +------------------------------------------------------------------------ +Intel TBB 2019 Update 7 +TBB_INTERFACE_VERSION == 11007 + +Changes (w.r.t. Intel TBB 2019 Update 6): + +- Added TBBMALLOC_SET_HUGE_SIZE_THRESHOLD parameter to set the lower + bound for allocations that are not released back to OS unless + a cleanup is explicitly requested. +- Added zip_iterator::base() method to get the tuple of underlying + iterators. +- Improved async_node to never block a thread that sends a message + through its gateway. +- Extended decrement port of the tbb::flow::limiter_node to accept + messages of integral types. +- Added support of Windows* to the CMake module TBBInstallConfig. +- Added packaging of CMake configuration files to TBB packages built + using build/build.py script + (https://github.com/intel/tbb/issues/141). + +Changes affecting backward compatibility: + +- Removed the number_of_decrement_predecessors parameter from the + constructor of flow::limiter_node. To allow its usage, set + TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR macro to 1. + +Preview Features: + +- Added ordered associative containers: + concurrent_{map,multimap,set,multiset} (requires C++11). + +Open-source contributions integrated: + +- Fixed makefiles to properly obtain the GCC version for GCC 7 + and later (https://github.com/intel/tbb/pull/147) by Timmmm. + +------------------------------------------------------------------------ +Intel TBB 2019 Update 6 +TBB_INTERFACE_VERSION == 11006 + +Changes (w.r.t. Intel TBB 2019 Update 5): + +- Added support for Microsoft* Visual Studio* 2019. +- Added support for enqueuing tbb::task into tbb::task_arena + (https://github.com/01org/tbb/issues/116). +- Improved support for allocator propagation on concurrent_hash_map + assigning and swapping. +- Improved scalable_allocation_command cleanup operations to release + more memory buffered by the calling thread. +- Separated allocation of small and large objects into distinct memory + regions, which helps to reduce excessive memory caching inside the + TBB allocator. + +Preview Features: + +- Removed template class gfx_factory from the flow graph API. + +------------------------------------------------------------------------ +Intel TBB 2019 Update 5 +TBB_INTERFACE_VERSION == 11005 + +Changes (w.r.t. Intel TBB 2019 Update 4): + +- Associating a task_scheduler_observer with an implicit or explicit + task arena is now a fully supported feature. +- Added a CMake module TBBInstallConfig that allows to generate and + install CMake configuration files for TBB packages. + Inspired by Hans Johnson (https://github.com/01org/tbb/pull/119). +- Added node handles, methods merge() and unsafe_extract() to concurrent + unordered containers. +- Added constructors with Compare argument to concurrent_priority_queue + (https://github.com/01org/tbb/issues/109). +- Controlling the stack size of worker threads is now supported for + Universal Windows Platform. +- Improved tbb::zip_iterator to work with algorithms that swap values + via iterators. +- Improved support for user-specified allocators in concurrent_hash_map, + including construction of allocator-aware data types. +- For ReaderWriterMutex types, upgrades and downgrades now succeed if + the mutex is already in the requested state. + Inspired by Niadb (https://github.com/01org/tbb/pull/122). + +Preview Features: + +- The task_scheduler_observer::may_sleep() method has been removed. + +Bugs fixed: + +- Fixed the issue with a pipeline parallel filter executing serially if + it follows a thread-bound filter. +- Fixed a performance regression observed when multiple parallel + algorithms start simultaneously. + +------------------------------------------------------------------------ +Intel TBB 2019 Update 4 +TBB_INTERFACE_VERSION == 11004 + +Changes (w.r.t. Intel TBB 2019 Update 3): + +- global_control class is now a fully supported feature. +- Added deduction guides for tbb containers: concurrent_hash_map, + concurrent_unordered_map, concurrent_unordered_set. +- Added tbb::scalable_memory_resource function returning + std::pmr::memory_resource interface to the TBB memory allocator. +- Added tbb::cache_aligned_resource class that implements + std::pmr::memory_resource with cache alignment and no false sharing. +- Added rml::pool_msize function returning the usable size of a memory + block allocated from a given memory pool. +- Added default and copy constructors for tbb::counting_iterator + and tbb::zip_iterator. +- Added TBB_malloc_replacement_log function to obtain the status of + dynamic memory allocation replacement (Windows* only). +- CMake configuration file now supports release-only and debug-only + configurations (https://github.com/01org/tbb/issues/113). +- TBBBuild CMake module takes the C++ version from CMAKE_CXX_STANDARD. + +Bugs fixed: + +- Fixed compilation for tbb::concurrent_vector when used with + std::pmr::polymorphic_allocator. + +Open-source contributions integrated: + +- TBB_INTERFACE_VERSION is included into TBB version in CMake + configuration (https://github.com/01org/tbb/pull/100) + by Hans Johnson. +- Fixed detection of C++17 deduction guides for Visual C++* + (https://github.com/01org/tbb/pull/112) by Marian Klymov. + +------------------------------------------------------------------------ +Intel TBB 2019 Update 3 +TBB_INTERFACE_VERSION == 11003 + +Changes (w.r.t. Intel TBB 2019 Update 2): + +- Added tbb::transform_iterator. +- Added new Makefile target 'profile' to flow graph examples enabling + additional support for Intel(R) Parallel Studio XE tools. +- Added TBB_MALLOC_DISABLE_REPLACEMENT environment variable to switch off + dynamic memory allocation replacement on Windows*. Inspired by + a contribution from Edward Lam. + +Preview Features: + +- Extended flow graph API to support relative priorities for functional + nodes, specified as an optional parameter to the node constructors. + +Open-source contributions integrated: + +- Enabled using process-local futex operations + (https://github.com/01org/tbb/pull/58) by Andrey Semashev. + +------------------------------------------------------------------------ +Intel TBB 2019 Update 2 +TBB_INTERFACE_VERSION == 11002 + +Changes (w.r.t. Intel TBB 2019 Update 1): + +- Added overloads for parallel_reduce with default partitioner and + user-supplied context. +- Added deduction guides for tbb containers: concurrent_vector, + concurrent_queue, concurrent_bounded_queue, + concurrent_priority_queue. +- Reallocation of memory objects >1MB now copies and frees memory if + the size is decreased twice or more, trading performance off for + reduced memory usage. +- After a period of sleep, TBB worker threads now prefer returning to + their last used task arena. + +Bugs fixed: + +- Fixed compilation of task_group.h when targeting macOS* 10.11 or + earlier (https://github.com/conda-forge/tbb-feedstock/issues/42). + +Open-source contributions integrated: + +- Added constructors with HashCompare argument to concurrent_hash_map + (https://github.com/01org/tbb/pull/63) by arewedancer. + +------------------------------------------------------------------------ +Intel TBB 2019 Update 1 +TBB_INTERFACE_VERSION == 11001 + +Changes (w.r.t. Intel TBB 2019): + +- Doxygen documentation could be built with 'make doxygen' command now. + +Changes affecting backward compatibility: + +- Enforced 8 byte alignment for tbb::atomic and + tbb::atomic. On IA-32 architecture it may cause layout + changes in structures that use these types. + +Bugs fixed: + +- Fixed an issue with dynamic memory allocation replacement on Windows* + occurred for some versions of ucrtbase.dll. +- Fixed possible deadlock in tbbmalloc cleanup procedure during process + shutdown. Inspired by a contribution from Edward Lam. +- Fixed usage of std::uncaught_exception() deprecated in C++17 + (https://github.com/01org/tbb/issues/67). +- Fixed a crash when a local observer is activated after an arena + observer. +- Fixed compilation of task_group.h by Visual C++* 15.7 with + /permissive- option (https://github.com/01org/tbb/issues/53). +- Fixed tbb4py to avoid dependency on Intel(R) C++ Compiler shared + libraries. +- Fixed compilation for Anaconda environment with GCC 7.3 and higher. + +Open-source contributions integrated: + +- Fix various warnings when building with Visual C++ + (https://github.com/01org/tbb/pull/70) by Edward Lam. + +------------------------------------------------------------------------ +Intel TBB 2019 +TBB_INTERFACE_VERSION == 11000 + +Changes (w.r.t. Intel TBB 2018 Update 5): + +- Lightweight policy for functional nodes in the flow graph is now + a fully supported feature. +- Reservation support in flow::write_once_node and flow::overwrite_node + is now a fully supported feature. +- Support for Flow Graph Analyzer and improvements for + Intel(R) VTune(TM) Amplifier become a regular feature enabled by + TBB_USE_THREADING_TOOLS macro. +- Added support for std::new_handler in the replacement functions for + global operator new. +- Added C++14 constructors to concurrent unordered containers. +- Added tbb::counting_iterator and tbb::zip_iterator. +- Fixed multiple -Wextra warnings in TBB source files. + +Preview Features: + +- Extracting nodes from a flow graph is deprecated and disabled by + default. To enable, use TBB_DEPRECATED_FLOW_NODE_EXTRACTION macro. + +Changes affecting backward compatibility: + +- Due to internal changes in the flow graph classes, recompilation is + recommended for all binaries that use the flow graph. + +Open-source contributions integrated: + +- Added support for OpenBSD by Anthony J. Bentley. + +------------------------------------------------------------------------ +Intel TBB 2018 Update 6 +TBB_INTERFACE_VERSION == 10006 + +Changes (w.r.t. Intel TBB 2018 Update 5): + +Bugs fixed: + +- Fixed an issue with dynamic memory allocation replacement on Windows* + occurred for some versions of ucrtbase.dll. + +------------------------------------------------------------------------ +Intel TBB 2018 Update 5 +TBB_INTERFACE_VERSION == 10005 + +Changes (w.r.t. Intel TBB 2018 Update 4): + +Preview Features: + +- Added user event tracing API for Intel(R) VTune(TM) Amplifier and + Flow Graph Analyzer. + +Bugs fixed: + +- Fixed the memory allocator to properly support transparent huge pages. +- Removed dynamic exception specifications in tbbmalloc_proxy for C++11 + and later (https://github.com/01org/tbb/issues/41). +- Added -flifetime-dse=1 option when building with GCC on macOS* + (https://github.com/01org/tbb/issues/60). + +Open-source contributions integrated: + +- Added ARMv8 support by Siddhesh Poyarekar. +- Avoid GCC warnings for clearing an object of non-trivial type + (https://github.com/01org/tbb/issues/54) by Daniel Arndt. + +------------------------------------------------------------------------ +Intel TBB 2018 Update 4 +TBB_INTERFACE_VERSION == 10004 + +Changes (w.r.t. Intel TBB 2018 Update 3): + +Preview Features: + +- Improved support for Flow Graph Analyzer and Intel(R) VTune(TM) + Amplifier in the task scheduler and generic parallel algorithms. +- Default device set for opencl_node now includes all the devices from + the first available OpenCL* platform. +- Added lightweight policy for functional nodes in the flow graph. It + indicates that the node body has little work and should, if possible, + be executed immediately upon receiving a message, avoiding task + scheduling overhead. + +------------------------------------------------------------------------ +Intel TBB 2018 Update 3 +TBB_INTERFACE_VERSION == 10003 + +Changes (w.r.t. Intel TBB 2018 Update 2): + +Preview Features: + +- Added template class blocked_rangeNd for a generic multi-dimensional + range (requires C++11). Inspired by a contribution from Jeff Hammond. + +Bugs fixed: + +- Fixed a crash with dynamic memory allocation replacement on + Windows* for applications using system() function. +- Fixed parallel_deterministic_reduce to split range correctly when used + with static_partitioner. +- Fixed a synchronization issue in task_group::run_and_wait() which + caused a simultaneous call to task_group::wait() to return + prematurely. + +------------------------------------------------------------------------ +Intel TBB 2018 Update 2 +TBB_INTERFACE_VERSION == 10002 + +Changes (w.r.t. Intel TBB 2018 Update 1): + +- Added support for Android* NDK r16, macOS* 10.13, Fedora* 26. +- Binaries for Universal Windows Driver (vc14_uwd) now link with static + Microsoft* runtime libraries, and are only available in commercial + releases. +- Extended flow graph documentation with more code samples. + +Preview Features: + +- Added a Python* module for multi-processing computations in numeric + Python* libraries. + +Bugs fixed: + +- Fixed constructors of concurrent_hash_map to be exception-safe. +- Fixed auto-initialization in the main thread to be cleaned up at + shutdown. +- Fixed a crash when tbbmalloc_proxy is used together with dbghelp. +- Fixed static_partitioner to assign tasks properly in case of nested + parallelism. + +------------------------------------------------------------------------ +Intel TBB 2018 Update 1 +TBB_INTERFACE_VERSION == 10001 + +Changes (w.r.t. Intel TBB 2018): + +- Added lambda-friendly overloads for parallel_scan. +- Added support of static and simple partitioners in + parallel_deterministic_reduce. + +Preview Features: + +- Added initial support for Flow Graph Analyzer to parallel_for. +- Added reservation support in overwrite_node and write_once_node. + +Bugs fixed: + +- Fixed a potential deadlock scenario in the flow graph that affected + Intel TBB 2018. + +------------------------------------------------------------------------ +Intel TBB 2018 +TBB_INTERFACE_VERSION == 10000 + +Changes (w.r.t. Intel TBB 2017 Update 7): + +- Introduced Parallel STL, an implementation of the C++ standard + library algorithms with support for execution policies. For more + information, see Getting Started with Parallel STL + (https://software.intel.com/en-us/get-started-with-pstl). +- this_task_arena::isolate() function is now a fully supported feature. +- this_task_arena::isolate() function and task_arena::execute() method + were extended to pass on the value returned by the executed functor + (requires C++11). +- task_arena::enqueue() and task_group::run() methods extended to accept + move-only functors. +- A flow graph now spawns all tasks into the same task arena, + and waiting for graph completion also happens in that arena. +- Improved support for Flow Graph Analyzer in async_node, opencl_node, + and composite_node. +- Added support for Android* NDK r15, r15b. +- Added support for Universal Windows Platform. +- Increased minimally supported version of macOS* + (MACOSX_DEPLOYMENT_TARGET) to 10.11. + +Changes affecting backward compatibility: + +- Internal layout changes in some flow graph classes; +- Several undocumented methods are removed from class graph, + including set_active() and is_active(). +- Due to incompatible changes, the namespace version is updated + for the flow graph; recompilation is recommended for all + binaries that use the flow graph classes. + +Preview Features: + +- opencl_node can be used with any graph object; class opencl_graph + is removed. +- graph::wait_for_all() now automatically waits for all not yet consumed + async_msg objects. +- Improved concurrent_lru_cache::handle_object to support C++11 move + semantics, default construction, and conversion to bool. + +Bugs fixed: + +- Fixed a bug preventing use of streaming_node and opencl_node with + Clang; inspired by a contribution from Francisco Facioni. +- Fixed this_task_arena::isolate() function to work correctly with + parallel_invoke and parallel_do algorithms. +- Fixed a memory leak in composite_node. +- Fixed an assertion failure in debug tbbmalloc binaries when + TBBMALLOC_CLEAN_ALL_BUFFERS is used. + +------------------------------------------------------------------------ +Intel TBB 2017 Update 8 +TBB_INTERFACE_VERSION == 9108 + +Changes (w.r.t. Intel TBB 2017 Update 7): + +Bugs fixed: + +- Fixed an assertion failure in debug tbbmalloc binaries when + TBBMALLOC_CLEAN_ALL_BUFFERS is used. + +------------------------------------------------------------------------ +Intel TBB 2017 Update 7 +TBB_INTERFACE_VERSION == 9107 + +Changes (w.r.t. Intel TBB 2017 Update 6): + +- In the huge pages mode, the memory allocator now is also able to use + transparent huge pages. + +Preview Features: + +- Added support for Intel TBB integration into CMake-aware + projects, with valuable guidance and feedback provided by Brad King + (Kitware). + +Bugs fixed: + +- Fixed scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, 0) + to process memory left after exited threads. + +------------------------------------------------------------------------ +Intel TBB 2017 Update 6 +TBB_INTERFACE_VERSION == 9106 + +Changes (w.r.t. Intel TBB 2017 Update 5): + +- Added support for Android* NDK r14. + +Preview Features: + +- Added a blocking terminate extension to the task_scheduler_init class + that allows an object to wait for termination of worker threads. + +Bugs fixed: + +- Fixed compilation and testing issues with MinGW (GCC 6). +- Fixed compilation with /std:c++latest option of VS 2017 + (https://github.com/01org/tbb/issues/13). + +------------------------------------------------------------------------ +Intel TBB 2017 Update 5 +TBB_INTERFACE_VERSION == 9105 + +Changes (w.r.t. Intel TBB 2017 Update 4): + +- Added support for Microsoft* Visual Studio* 2017. +- Added graph/matmult example to demonstrate support for compute offload + to Intel(R) Graphics Technology in the flow graph API. +- The "compiler" build option now allows to specify a full path to the + compiler. + +Changes affecting backward compatibility: + +- Constructors for many classes, including graph nodes, concurrent + containers, thread-local containers, etc., are declared explicit and + cannot be used for implicit conversions anymore. + +Bugs fixed: + +- Added a workaround for bug 16657 in the GNU C Library (glibc) + affecting the debug version of tbb::mutex. +- Fixed a crash in pool_identify() called for an object allocated in + another thread. + +------------------------------------------------------------------------ +Intel TBB 2017 Update 4 +TBB_INTERFACE_VERSION == 9104 + +Changes (w.r.t. Intel TBB 2017 Update 3): + +- Added support for C++11 move semantics in parallel_do. +- Added support for FreeBSD* 11. + +Changes affecting backward compatibility: + +- Minimal compiler versions required for support of C++11 move semantics + raised to GCC 4.5, VS 2012, and Intel(R) C++ Compiler 14.0. + +Bugs fixed: + +- The workaround for crashes in the library compiled with GCC 6 + (-flifetime-dse=1) was extended to Windows*. + +------------------------------------------------------------------------ +Intel TBB 2017 Update 3 +TBB_INTERFACE_VERSION == 9103 + +Changes (w.r.t. Intel TBB 2017 Update 2): + +- Added support for Android* 7.0 and Android* NDK r13, r13b. + +Preview Features: + +- Added template class gfx_factory to the flow graph API. It implements + the Factory concept for streaming_node to offload computations to + Intel(R) processor graphics. + +Bugs fixed: + +- Fixed a possible deadlock caused by missed wakeup signals in + task_arena::execute(). + +Open-source contributions integrated: + +- A build fix for Linux* s390x platform by Jerry J. + +------------------------------------------------------------------------ +Intel TBB 2017 Update 2 +TBB_INTERFACE_VERSION == 9102 + +Changes (w.r.t. Intel TBB 2017 Update 1): + +- Removed the long-outdated support for Xbox* consoles. + +Bugs fixed: + +- Fixed the issue with task_arena::execute() not being processed when + the calling thread cannot join the arena. +- Fixed dynamic memory allocation replacement failure on macOS* 10.12. + +------------------------------------------------------------------------ +Intel TBB 2017 Update 1 +TBB_INTERFACE_VERSION == 9101 + +Changes (w.r.t. Intel TBB 2017): + +Bugs fixed: + +- Fixed dynamic memory allocation replacement failures on Windows* 10 + Anniversary Update. +- Fixed emplace() method of concurrent unordered containers to not + require a copy constructor. + +------------------------------------------------------------------------ +Intel TBB 2017 +TBB_INTERFACE_VERSION == 9100 + +Changes (w.r.t. Intel TBB 4.4 Update 5): + +- static_partitioner class is now a fully supported feature. +- async_node class is now a fully supported feature. +- Improved dynamic memory allocation replacement on Windows* OS to skip + DLLs for which replacement cannot be done, instead of aborting. +- Intel TBB no longer performs dynamic memory allocation replacement + for Microsoft* Visual Studio* 2008. +- For 64-bit platforms, quadrupled the worst-case limit on the amount + of memory the Intel TBB allocator can handle. +- Added TBB_USE_GLIBCXX_VERSION macro to specify the version of GNU + libstdc++ when it cannot be properly recognized, e.g. when used + with Clang on Linux* OS. Inspired by a contribution from David A. +- Added graph/stereo example to demonstrate tbb::flow::async_msg. +- Removed a few cases of excessive user data copying in the flow graph. +- Reworked split_node to eliminate unnecessary overheads. +- Added support for C++11 move semantics to the argument of + tbb::parallel_do_feeder::add() method. +- Added C++11 move constructor and assignment operator to + tbb::combinable template class. +- Added tbb::this_task_arena::max_concurrency() function and + max_concurrency() method of class task_arena returning the maximal + number of threads that can work inside an arena. +- Deprecated tbb::task_arena::current_thread_index() static method; + use tbb::this_task_arena::current_thread_index() function instead. +- All examples for commercial version of library moved online: + https://software.intel.com/en-us/product-code-samples. Examples are + available as a standalone package or as a part of Intel(R) Parallel + Studio XE or Intel(R) System Studio Online Samples packages. + +Changes affecting backward compatibility: + +- Renamed following methods and types in async_node class: + Old New + async_gateway_type => gateway_type + async_gateway() => gateway() + async_try_put() => try_put() + async_reserve() => reserve_wait() + async_commit() => release_wait() +- Internal layout of some flow graph nodes has changed; recompilation + is recommended for all binaries that use the flow graph. + +Preview Features: + +- Added template class streaming_node to the flow graph API. It allows + a flow graph to offload computations to other devices through + streaming or offloading APIs. +- Template class opencl_node reimplemented as a specialization of + streaming_node that works with OpenCL*. +- Added tbb::this_task_arena::isolate() function to isolate execution + of a group of tasks or an algorithm from other tasks submitted + to the scheduler. + +Bugs fixed: + +- Added a workaround for GCC bug #62258 in std::rethrow_exception() + to prevent possible problems in case of exception propagation. +- Fixed parallel_scan to provide correct result if the initial value + of an accumulator is not the operation identity value. +- Fixed a memory corruption in the memory allocator when it meets + internal limits. +- Fixed the memory allocator on 64-bit platforms to align memory + to 16 bytes by default for all allocations bigger than 8 bytes. +- As a workaround for crashes in the Intel TBB library compiled with + GCC 6, added -flifetime-dse=1 to compilation options on Linux* OS. +- Fixed a race in the flow graph implementation. + +Open-source contributions integrated: + +- Enabling use of C++11 'override' keyword by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.4 Update 6 +TBB_INTERFACE_VERSION == 9006 + +Changes (w.r.t. Intel TBB 4.4 Update 5): + +- For 64-bit platforms, quadrupled the worst-case limit on the amount + of memory the Intel TBB allocator can handle. + +Bugs fixed: + +- Fixed a memory corruption in the memory allocator when it meets + internal limits. +- Fixed the memory allocator on 64-bit platforms to align memory + to 16 bytes by default for all allocations bigger than 8 bytes. +- Fixed parallel_scan to provide correct result if the initial value + of an accumulator is not the operation identity value. +- As a workaround for crashes in the Intel TBB library compiled with + GCC 6, added -flifetime-dse=1 to compilation options on Linux* OS. + +------------------------------------------------------------------------ +Intel TBB 4.4 Update 5 +TBB_INTERFACE_VERSION == 9005 + +Changes (w.r.t. Intel TBB 4.4 Update 4): + +- Modified graph/fgbzip2 example to remove unnecessary data queuing. + +Preview Features: + +- Added a Python* module which is able to replace Python's thread pool + class with the implementation based on Intel TBB task scheduler. + +Bugs fixed: + +- Fixed the implementation of 64-bit tbb::atomic for IA-32 architecture + to work correctly with GCC 5.2 in C++11/14 mode. +- Fixed a possible crash when tasks with affinity (e.g. specified via + affinity_partitioner) are used simultaneously with task priority + changes. + +------------------------------------------------------------------------ +Intel TBB 4.4 Update 4 +TBB_INTERFACE_VERSION == 9004 + +Changes (w.r.t. Intel TBB 4.4 Update 3): + +- Removed a few cases of excessive user data copying in the flow graph. +- Improved robustness of concurrent_bounded_queue::abort() in case of + simultaneous push and pop operations. + +Preview Features: + +- Added tbb::flow::async_msg, a special message type to support + communications between the flow graph and external asynchronous + activities. +- async_node modified to support use with C++03 compilers. + +Bugs fixed: + +- Fixed a bug in dynamic memory allocation replacement for Windows* OS. +- Fixed excessive memory consumption on Linux* OS caused by enabling + zero-copy realloc. +- Fixed performance regression on Intel(R) Xeon Phi(tm) coprocessor with + auto_partitioner. + +------------------------------------------------------------------------ +Intel TBB 4.4 Update 3 +TBB_INTERFACE_VERSION == 9003 + +Changes (w.r.t. Intel TBB 4.4 Update 2): + +- Modified parallel_sort to not require a default constructor for values + and to use iter_swap() for value swapping. +- Added support for creating or initializing a task_arena instance that + is connected to the arena currently used by the thread. +- graph/binpack example modified to use multifunction_node. +- For performance analysis, use Intel(R) VTune(TM) Amplifier XE 2015 + and higher; older versions are no longer supported. +- Improved support for compilation with disabled RTTI, by omitting its use + in auxiliary code, such as assertions. However some functionality, + particularly the flow graph, does not work if RTTI is disabled. +- The tachyon example for Android* can be built using Android Studio 1.5 + and higher with experimental Gradle plugin 0.4.0. + +Preview Features: + +- Added class opencl_subbufer that allows using OpenCL* sub-buffer + objects with opencl_node. +- Class global_control supports the value of 1 for + max_allowed_parallelism. + +Bugs fixed: + +- Fixed a race causing "TBB Warning: setaffinity syscall failed" message. +- Fixed a compilation issue on OS X* with Intel(R) C++ Compiler 15.0. +- Fixed a bug in queuing_rw_mutex::downgrade() that could temporarily + block new readers. +- Fixed speculative_spin_rw_mutex to stop using the lazy subscription + technique due to its known flaws. +- Fixed memory leaks in the tool support code. + +------------------------------------------------------------------------ +Intel TBB 4.4 Update 2 +TBB_INTERFACE_VERSION == 9002 + +Changes (w.r.t. Intel TBB 4.4 Update 1): + +- Improved interoperability with Intel(R) OpenMP RTL (libiomp) on Linux: + OpenMP affinity settings do not affect the default number of threads + used in the task scheduler. Intel(R) C++ Compiler 16.0 Update 1 + or later is required. +- Added a new flow graph example with different implementations of the + Cholesky Factorization algorithm. + +Preview Features: + +- Added template class opencl_node to the flow graph API. It allows a + flow graph to offload computations to OpenCL* devices. +- Extended join_node to use type-specified message keys. It simplifies + the API of the node by obtaining message keys via functions + associated with the message type (instead of node ports). +- Added static_partitioner that minimizes overhead of parallel_for and + parallel_reduce for well-balanced workloads. +- Improved template class async_node in the flow graph API to support + user settable concurrency limits. + +Bugs fixed: + +- Fixed a possible crash in the GUI layer for library examples on Linux. + +------------------------------------------------------------------------ +Intel TBB 4.4 Update 1 +TBB_INTERFACE_VERSION == 9001 + +Changes (w.r.t. Intel TBB 4.4): + +- Added support for Microsoft* Visual Studio* 2015. +- Intel TBB no longer performs dynamic replacement of memory allocation + functions for Microsoft Visual Studio 2005 and earlier versions. +- For GCC 4.7 and higher, the intrinsics-based platform isolation layer + uses __atomic_* built-ins instead of the legacy __sync_* ones. + This change is inspired by a contribution from Mathieu Malaterre. +- Improvements in task_arena: + Several application threads may join a task_arena and execute tasks + simultaneously. The amount of concurrency reserved for application + threads at task_arena construction can be set to any value between + 0 and the arena concurrency limit. +- The fractal example was modified to demonstrate class task_arena + and moved to examples/task_arena/fractal. + +Bugs fixed: + +- Fixed a deadlock during destruction of task_scheduler_init objects + when one of destructors is set to wait for worker threads. +- Added a workaround for a possible crash on OS X* when dynamic memory + allocator replacement (libtbbmalloc_proxy) is used and memory is + released during application startup. +- Usage of mutable functors with task_group::run_and_wait() and + task_arena::enqueue() is disabled. An attempt to pass a functor + which operator()() is not const will produce compilation errors. +- Makefiles and environment scripts now properly recognize GCC 5.0 and + higher. + +Open-source contributions integrated: + +- Improved performance of parallel_for_each for inputs allowing random + access, by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.4 +TBB_INTERFACE_VERSION == 9000 + +Changes (w.r.t. Intel TBB 4.3 Update 6): + +- The following features are now fully supported: + tbb::flow::composite_node; + additional policies of tbb::flow::graph_node::reset(). +- Platform abstraction layer for Windows* OS updated to use compiler + intrinsics for most atomic operations. +- The tbb/compat/thread header updated to automatically include + C++11 where available. +- Fixes and refactoring in the task scheduler and class task_arena. +- Added key_matching policy to tbb::flow::join_node, which removes + the restriction on the type that can be compared-against. +- For tag_matching join_node, tag_value is redefined to be 64 bits + wide on all architectures. +- Expanded the documentation for the flow graph with details about + node semantics and behavior. +- Added dynamic replacement of C11 standard function aligned_alloc() + under Linux* OS. +- Added C++11 move constructors and assignment operators to + tbb::enumerable_thread_specific container. +- Added hashing support for tbb::tbb_thread::id. +- On OS X*, binaries that depend on libstdc++ are not provided anymore. + In the makefiles, libc++ is now used by default; for building with + libstdc++, specify stdlib=libstdc++ in the make command line. + +Preview Features: + +- Added a new example, graph/fgbzip2, that shows usage of + tbb::flow::async_node. +- Modification to the low-level API for memory pools: + added a function for finding a memory pool by an object allocated + from that pool. +- tbb::memory_pool now does not request memory till the first allocation + from the pool. + +Changes affecting backward compatibility: + +- Internal layout of flow graph nodes has changed; recompilation is + recommended for all binaries that use the flow graph. +- Resetting a tbb::flow::source_node will immediately activate it, + unless it was created in inactive state. + +Bugs fixed: + +- Failure at creation of a memory pool will not cause process + termination anymore. + +Open-source contributions integrated: + +- Supported building TBB with Clang on AArch64 with use of built-in + intrinsics by David A. + +------------------------------------------------------------------------ +Intel TBB 4.3 Update 6 +TBB_INTERFACE_VERSION == 8006 + +Changes (w.r.t. Intel TBB 4.3 Update 5): + +- Supported zero-copy realloc for objects >1MB under Linux* via + mremap system call. +- C++11 move-aware insert and emplace methods have been added to + concurrent_hash_map container. +- install_name is set to @rpath/ on OS X*. + +Preview Features: + +- Added template class async_node to the flow graph API. It allows a + flow graph to communicate with an external activity managed by + the user or another runtime. +- Improved speed of flow::graph::reset() clearing graph edges. + rf_extract flag has been renamed rf_clear_edges. +- extract() method of graph nodes now takes no arguments. + +Bugs fixed: + +- concurrent_unordered_{set,map} behaves correctly for degenerate + hashes. +- Fixed a race condition in the memory allocator that may lead to + excessive memory consumption under high multithreading load. + +------------------------------------------------------------------------ +Intel TBB 4.3 Update 5 +TBB_INTERFACE_VERSION == 8005 + +Changes (w.r.t. Intel TBB 4.3 Update 4): + +- Added add_ref_count() method of class tbb::task. + +Preview Features: + +- Added class global_control for application-wide control of allowed + parallelism and thread stack size. +- memory_pool_allocator now throws the std::bad_alloc exception on + allocation failure. +- Exceptions thrown for by memory pool constructors changed from + std::bad_alloc to std::invalid_argument and std::runtime_error. + +Bugs fixed: + +- scalable_allocator now throws the std::bad_alloc exception on + allocation failure. +- Fixed a race condition in the memory allocator that may lead to + excessive memory consumption under high multithreading load. +- A new scheduler created right after destruction of the previous one + might be unable to modify the number of worker threads. + +Open-source contributions integrated: + +- (Added but not enabled) push_front() method of class tbb::task_list + by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.3 Update 4 +TBB_INTERFACE_VERSION == 8004 + +Changes (w.r.t. Intel TBB 4.3 Update 3): + +- Added a C++11 variadic constructor for enumerable_thread_specific. + The arguments from this constructor are used to construct + thread-local values. +- Improved exception safety for enumerable_thread_specific. +- Added documentation for tbb::flow::tagged_msg class and + tbb::flow::output_port function. +- Fixed build errors for systems that do not support dynamic linking. +- C++11 move-aware insert and emplace methods have been added to + concurrent unordered containers. + +Preview Features: + +- Interface-breaking change: typedefs changed for node predecessor and + successor lists, affecting copy_predecessors and copy_successors + methods. +- Added template class composite_node to the flow graph API. It packages + a subgraph to represent it as a first-class flow graph node. +- make_edge and remove_edge now accept multiport nodes as arguments, + automatically using the node port with index 0 for an edge. + +Open-source contributions integrated: + +- Draft code for enumerable_thread_specific constructor with multiple + arguments (see above) by Adrien Guinet. +- Fix for GCC invocation on IBM* Blue Gene* + by Jeff Hammond and Raf Schietekat. +- Extended testing with smart pointers for Clang & libc++ + by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.3 Update 3 +TBB_INTERFACE_VERSION == 8003 + +Changes (w.r.t. Intel TBB 4.3 Update 2): + +- Move constructor and assignment operator were added to unique_lock. + +Preview Features: + +- Time overhead for memory pool destruction was reduced. + +Open-source contributions integrated: + +- Build error fix for iOS* by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.3 Update 2 +TBB_INTERFACE_VERSION == 8002 + +Changes (w.r.t. Intel TBB 4.3 Update 1): + +- Binary files for 64-bit Android* applications were added as part of the + Linux* OS package. +- Exact exception propagation is enabled for Intel C++ Compiler on OS X*. +- concurrent_vector::shrink_to_fit was optimized for types that support + C++11 move semantics. + +Bugs fixed: + +- Fixed concurrent unordered containers to insert elements much faster + in debug mode. +- Fixed concurrent priority queue to support types that do not have + copy constructors. +- Fixed enumerable_thread_specific to forbid copying from an instance + with a different value type. + +Open-source contributions integrated: + +- Support for PathScale* EKOPath* Compiler by Erik Lindahl. + +------------------------------------------------------------------------ +Intel TBB 4.3 Update 1 +TBB_INTERFACE_VERSION == 8001 + +Changes (w.r.t. Intel TBB 4.3): + +- The ability to split blocked_ranges in a proportion, used by + affinity_partitioner since version 4.2 Update 4, became a formal + extension of the Range concept. +- More checks for an incorrect address to release added to the debug + version of the memory allocator. +- Different kind of solutions for each TBB example were merged. + +Preview Features: + +- Task priorities are re-enabled in preview binaries. + +Bugs fixed: + +- Fixed a duplicate symbol when TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE is + used in multiple compilation units. +- Fixed a crash in __itt_fini_ittlib seen on Ubuntu 14.04. +- Fixed a crash in memory release after dynamic replacement of the + OS X* memory allocator. +- Fixed incorrect indexing of arrays in seismic example. +- Fixed a data race in lazy initialization of task_arena. + +Open-source contributions integrated: + +- Fix for dumping information about gcc and clang compiler versions + by Misty De Meo. + +------------------------------------------------------------------------ +Intel TBB 4.3 +TBB_INTERFACE_VERSION == 8000 + +Changes (w.r.t. Intel TBB 4.2 Update 5): + +- The following features are now fully supported: flow::indexer_node, + task_arena, speculative_spin_rw_mutex. +- Compatibility with C++11 standard improved for tbb/compat/thread + and tbb::mutex. +- C++11 move constructors have been added to concurrent_queue and + concurrent_bounded_queue. +- C++11 move constructors and assignment operators have been added to + concurrent_vector, concurrent_hash_map, concurrent_priority_queue, + concurrent_unordered_{set,multiset,map,multimap}. +- C++11 move-aware emplace/push/pop methods have been added to + concurrent_vector, concurrent_queue, concurrent_bounded_queue, + concurrent_priority_queue. +- Methods to insert a C++11 initializer list have been added: + concurrent_vector::grow_by(), concurrent_hash_map::insert(), + concurrent_unordered_{set,multiset,map,multimap}::insert(). +- Testing for compatibility of containers with some C++11 standard + library types has been added. +- Dynamic replacement of standard memory allocation routines has been + added for OS X*. +- Microsoft* Visual Studio* projects for Intel TBB examples updated + to VS 2010. +- For open-source packages, debugging information (line numbers) in + precompiled binaries now matches the source code. +- Debug information was added to release builds for OS X*, Solaris*, + FreeBSD* operating systems and MinGW*. +- Various improvements in documentation, debug diagnostics and examples. + +Preview Features: + +- Additional actions on reset of graphs, and extraction of individual + nodes from a graph (TBB_PREVIEW_FLOW_GRAPH_FEATURES). +- Support for an arbitrary number of arguments in parallel_invoke + (TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE). + +Changes affecting backward compatibility: + +- For compatibility with C++11 standard, copy and move constructors and + assignment operators are disabled for all mutex classes. To allow + the old behavior, use TBB_DEPRECATED_MUTEX_COPYING macro. +- flow::sequencer_node rejects messages with repeating sequence numbers. +- Changed internal interface between tbbmalloc and tbbmalloc_proxy. +- Following deprecated functionality has been removed: + old debugging macros TBB_DO_ASSERT & TBB_DO_THREADING_TOOLS; + no-op depth-related methods in class task; + tbb::deprecated::concurrent_queue; + deprecated variants of concurrent_vector methods. +- register_successor() and remove_successor() are deprecated as methods + to add and remove edges in flow::graph; use make_edge() and + remove_edge() instead. + +Bugs fixed: + +- Fixed incorrect scalable_msize() implementation for aligned objects. +- Flow graph buffering nodes now destroy their copy of forwarded items. +- Multiple fixes in task_arena implementation, including for: + inconsistent task scheduler state inside executed functions; + incorrect floating-point settings and exception propagation; + possible stalls in concurrent invocations of execute(). +- Fixed floating-point settings propagation when the same instance of + task_group_context is used in different arenas. +- Fixed compilation error in pipeline.h with Intel Compiler on OS X*. +- Added missed headers for individual components to tbb.h. + +Open-source contributions integrated: + +- Range interface addition to parallel_do, parallel_for_each and + parallel_sort by Stephan Dollberg. +- Variadic template implementation of parallel_invoke + by Kizza George Mbidde (see Preview Features). +- Improvement in Seismic example for MacBook Pro* with Retina* display + by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.2 Update 5 +TBB_INTERFACE_VERSION == 7005 + +Changes (w.r.t. Intel TBB 4.2 Update 4): + +- The second template argument of class aligned_space now is set + to 1 by default. + +Preview Features: + +- Better support for exception safety, task priorities and floating + point settings in class task_arena. +- task_arena::current_slot() has been renamed to + task_arena::current_thread_index(). + +Bugs fixed: + +- Task priority change possibly ignored by a worker thread entering + a nested parallel construct. +- Memory leaks inside the task scheduler when running on + Intel(R) Xeon Phi(tm) coprocessor. + +Open-source contributions integrated: + +- Improved detection of X Window support for Intel TBB examples + and other feedback by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.2 Update 4 +TBB_INTERFACE_VERSION == 7004 + +Changes (w.r.t. Intel TBB 4.2 Update 3): + +- Added possibility to specify floating-point settings at invocation + of most parallel algorithms (including flow::graph) via + task_group_context. +- Added dynamic replacement of malloc_usable_size() under + Linux*/Android* and dlmalloc_usable_size() under Android*. +- Added new methods to concurrent_vector: + grow_by() that appends a sequence between two given iterators; + grow_to_at_least() that initializes new elements with a given value. +- Improved affinity_partitioner for better performance on balanced + workloads. +- Improvements in the task scheduler, including better scalability + when threads search for a task arena, and better diagnostics. +- Improved allocation performance for workloads that do intensive + allocation/releasing of same-size objects larger than ~8KB from + multiple threads. +- Exception support is enabled by default for 32-bit MinGW compilers. +- The tachyon example for Android* can be built for all targets + supported by the installed NDK. +- Added Windows Store* version of the tachyon example. +- GettingStarted/sub_string_finder example ported to offload execution + on Windows* for Intel(R) Many Integrated Core Architecture. + +Preview Features: + +- Removed task_scheduler_observer::on_scheduler_leaving() callback. +- Added task_scheduler_observer::may_sleep() callback. +- The CPF or_node has been renamed indexer_node. The input to + indexer_node is now a list of types. The output of indexer_node is + a tagged_msg type composed of a tag and a value. For indexer_node, + the tag is a size_t. + +Bugs fixed: + +- Fixed data races in preview extensions of task_scheduler_observer. +- Added noexcept(false) for destructor of task_group_base to avoid + crash on cancellation of structured task group in C++11. + +Open-source contributions integrated: + +- Improved concurrency detection for BG/Q, and other improvements + by Raf Schietekat. +- Fix for crashes in enumerable_thread_specific in case if a contained + object is too big to be constructed on the stack by Adrien Guinet. + +------------------------------------------------------------------------ +Intel TBB 4.2 Update 3 +TBB_INTERFACE_VERSION == 7003 + +Changes (w.r.t. Intel TBB 4.2 Update 2): + +- Added support for Microsoft* Visual Studio* 2013. +- Improved Microsoft* PPL-compatible form of parallel_for for better + support of auto-vectorization. +- Added a new example for cancellation and reset in the flow graph: + Kohonen self-organizing map (examples/graph/som). +- Various improvements in source code, tests, and makefiles. + +Bugs fixed: + +- Added dynamic replacement of _aligned_msize() previously missed. +- Fixed task_group::run_and_wait() to throw invalid_multiple_scheduling + exception if the specified task handle is already scheduled. + +Open-source contributions integrated: + +- A fix for ARM* processors by Steve Capper. +- Improvements in std::swap calls by Robert Maynard. + +------------------------------------------------------------------------ +Intel TBB 4.2 Update 2 +TBB_INTERFACE_VERSION == 7002 + +Changes (w.r.t. Intel TBB 4.2 Update 1): + +- Enable C++11 features for Microsoft* Visual Studio* 2013 Preview. +- Added a test for compatibility of TBB containers with C++11 + range-based for loop. + +Changes affecting backward compatibility: + +- Internal layout changed for class tbb::flow::limiter_node. + +Preview Features: + +- Added speculative_spin_rw_mutex, a read-write lock class which uses + Intel(R) Transactional Synchronization Extensions. + +Bugs fixed: + +- When building for Intel(R) Xeon Phi(tm) coprocessor, TBB programs + no longer require explicit linking with librt and libpthread. + +Open-source contributions integrated: + +- Fixes for ARM* processors by Steve Capper, Leif Lindholm + and Steven Noonan. +- Support for Clang on Linux by Raf Schietekat. +- Typo correction in scheduler.cpp by Julien Schueller. + +------------------------------------------------------------------------ +Intel TBB 4.2 Update 1 +TBB_INTERFACE_VERSION == 7001 + +Changes (w.r.t. Intel TBB 4.2): + +- Added project files for Microsoft* Visual Studio* 2010. +- Initial support of Microsoft* Visual Studio* 2013 Preview. +- Enable C++11 features available in Intel(R) C++ Compiler 14.0. +- scalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, ) can be + used to urge releasing memory from tbbmalloc internal buffers when + the given limit is exceeded. + +Preview Features: + +- Class task_arena no longer requires linking with a preview library, + though still remains a community preview feature. +- The method task_arena::wait_until_empty() is removed. +- The method task_arena::current_slot() now returns -1 if + the task scheduler is not initialized in the thread. + +Changes affecting backward compatibility: + +- Because of changes in internal layout of graph nodes, the namespace + interface number of flow::graph has been incremented from 6 to 7. + +Bugs fixed: + +- Fixed a race in lazy initialization of task_arena. +- Fixed flow::graph::reset() to prevent situations where tasks would be + spawned in the process of resetting the graph to its initial state. +- Fixed decrement bug in limiter_node. +- Fixed a race in arc deletion in the flow graph. + +Open-source contributions integrated: + +- Improved support for IBM* Blue Gene* by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.2 +TBB_INTERFACE_VERSION == 7000 + +Changes (w.r.t. Intel TBB 4.1 Update 4): + +- Added speculative_spin_mutex, which uses Intel(R) Transactional + Synchronization Extensions when they are supported by hardware. +- Binary files linked with libc++ (the C++ standard library in Clang) + were added on OS X*. +- For OS X* exact exception propagation is supported with Clang; + it requires use of libc++ and corresponding Intel TBB binaries. +- Support for C++11 initializer lists in constructor and assignment + has been added to concurrent_hash_map, concurrent_unordered_set, + concurrent_unordered_multiset, concurrent_unordered_map, + concurrent_unordered_multimap. +- The memory allocator may now clean its per-thread memory caches + when it cannot get more memory. +- Added the scalable_allocation_command() function for on-demand + cleaning of internal memory caches. +- Reduced the time overhead for freeing memory objects smaller than ~8K. +- Simplified linking with the debug library for applications that use + Intel TBB in code offloaded to Intel(R) Xeon Phi(tm) coprocessors. + See an example in + examples/GettingStarted/sub_string_finder/Makefile. +- Various improvements in source code, scripts and makefiles. + +Changes affecting backward compatibility: + +- tbb::flow::graph has been modified to spawn its tasks; + the old behaviour (task enqueuing) is deprecated. This change may + impact applications that expected a flow graph to make progress + without calling wait_for_all(), which is no longer guaranteed. See + the documentation for more details. +- Changed the return values of the scalable_allocation_mode() function. + +Bugs fixed: + +- Fixed a leak of parallel_reduce body objects when execution is + cancelled or an exception is thrown, as suggested by Darcy Harrison. +- Fixed a race in the task scheduler which can lower the effective + priority despite the existence of higher priority tasks. +- On Linux an error during destruction of the internal thread local + storage no longer results in an exception. + +Open-source contributions integrated: + +- Fixed task_group_context state propagation to unrelated context trees + by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.1 Update 4 +TBB_INTERFACE_VERSION == 6105 + +Changes (w.r.t. Intel TBB 4.1 Update 3): + +- Use /volatile:iso option with VS 2012 to disable extended + semantics for volatile variables. +- Various improvements in affinity_partitioner, scheduler, + tests, examples, makefiles. +- Concurrent_priority_queue class now supports initialization/assignment + via C++11 initializer list feature (std::initializer_list). + +Bugs fixed: + +- Fixed more possible stalls in concurrent invocations of + task_arena::execute(), especially waiting for enqueued tasks. +- Fixed requested number of workers for task_arena(P,0). +- Fixed interoperability with Intel(R) VTune(TM) Amplifier XE in + case of using task_arena::enqueue() from a terminating thread. + +Open-source contributions integrated: + +- Type fixes, cleanups, and code beautification by Raf Schietekat. +- Improvements in atomic operations for big endian platforms + by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 4.1 Update 3 +TBB_INTERFACE_VERSION == 6103 + +Changes (w.r.t. Intel TBB 4.1 Update 2): + +- Binary files for Android* applications were added to the Linux* OS + package. +- Binary files for Windows Store* applications were added to the + Windows* OS package. +- Exact exception propagation (exception_ptr) support on Linux OS is + now turned on by default for GCC 4.4 and higher. +- Stopped implicit use of large memory pages by tbbmalloc (Linux-only). + Now use of large pages must be explicitly enabled with + scalable_allocation_mode() function or TBB_MALLOC_USE_HUGE_PAGES + environment variable. + +Community Preview Features: + +- Extended class task_arena constructor and method initialize() to + allow some concurrency to be reserved strictly for application + threads. +- New methods terminate() and is_active() were added to class + task_arena. + +Bugs fixed: + +- Fixed initialization of hashing helper constant in the hash + containers. +- Fixed possible stalls in concurrent invocations of + task_arena::execute() when no worker thread is available to make + progress. +- Fixed incorrect calculation of hardware concurrency in the presence + of inactive processor groups, particularly on systems running + Windows* 8 and Windows* Server 2012. + +Open-source contributions integrated: + +- The fix for the GUI examples on OS X* systems by Raf Schietekat. +- Moved some power-of-2 calculations to functions to improve readability + by Raf Schietekat. +- C++11/Clang support improvements by arcata. +- ARM* platform isolation layer by Steve Capper, Leif Lindholm, Leo Lara + (ARM). + +------------------------------------------------------------------------ +Intel TBB 4.1 Update 2 +TBB_INTERFACE_VERSION == 6102 + +Changes (w.r.t. Intel TBB 4.1 Update 1): + +- Objects up to 128 MB are now cached by the tbbmalloc. Previously + the threshold was 8MB. Objects larger than 128 MB are still + processed by direct OS calls. +- concurrent_unordered_multiset and concurrent_unordered_multimap + have been added, based on Microsoft* PPL prototype. +- Ability to value-initialize a tbb::atomic variable on construction + in C++11, with const expressions properly supported. + +Community Preview Features: + +- Added a possibility to wait until all worker threads terminate. + This is necessary before calling fork() from an application. + +Bugs fixed: + +- Fixed data race in tbbmalloc that might lead to memory leaks + for large object allocations. +- Fixed task_arena::enqueue() to use task_group_context of target arena. +- Improved implementation of 64 bit atomics on ia32. + +------------------------------------------------------------------------ +Intel TBB 4.1 Update 1 +TBB_INTERFACE_VERSION == 6101 + +Changes (w.r.t. Intel TBB 4.1): + +- concurrent_vector class now supports initialization/assignment + via C++11 initializer list feature (std::initializer_list) +- Added implementation of the platform isolation layer based on + Intel compiler atomic built-ins; it is supposed to work on + any platform supported by compiler version 12.1 and newer. +- Using GetNativeSystemInfo() instead of GetSystemInfo() to support + more than 32 processors for 32-bit applications under WOW64. +- The following form of parallel_for: + parallel_for(first, last, [step,] f[, context]) now accepts an + optional partitioner parameter after the function f. + +Backward-incompatible API changes: + +- The library no longer injects tuple in to namespace std. + In previous releases, tuple was injected into namespace std by + flow_graph.h when std::tuple was not available. In this release, + flow_graph.h now uses tbb::flow::tuple. On platforms where + std::tuple is available, tbb::flow::tuple is typedef'ed to + std::tuple. On all other platforms, tbb::flow::tuple provides + a subset of the functionality defined by std::tuple. Users of + flow_graph.h may need to change their uses of std::tuple to + tbb::flow::tuple to ensure compatibility with non-C++11 compliant + compilers. + +Bugs fixed: + +- Fixed local observer to be able to override propagated CPU state and + to provide correct value of task_arena::current_slot() in callbacks. + +------------------------------------------------------------------------ +Intel TBB 4.1 +TBB_INTERFACE_VERSION == 6100 + +Changes (w.r.t. Intel TBB 4.0 Update 5): + +- _WIN32_WINNT must be set to 0x0501 or greater in order to use TBB + on Microsoft* Windows*. +- parallel_deterministic_reduce template function is fully supported. +- TBB headers can be used with C++0x/C++11 mode (-std=c++0x) of GCC + and Intel(R) Compiler. +- C++11 std::make_exception_ptr is used where available, instead of + std::copy_exception from earlier C++0x implementations. +- Improvements in the TBB allocator to reduce extra memory consumption. +- Partial refactoring of the task scheduler data structures. +- TBB examples allow more flexible specification of the thread number, + including arithmetic and geometric progression. + +Bugs fixed: + +- On Linux & OS X*, pre-built TBB binaries do not yet support exact + exception propagation via C++11 exception_ptr. To prevent run time + errors, by default TBB headers disable exact exception propagation + even if the C++ implementation provides exception_ptr. + +Community Preview Features: + +- Added: class task_arena, for work submission by multiple application + threads with thread-independent control of concurrency level. +- Added: task_scheduler_observer can be created as local to a master + thread, to observe threads that work on behalf of that master. + Local observers may have new on_scheduler_leaving() callback. + +------------------------------------------------------------------------ +Intel TBB 4.0 Update 5 +TBB_INTERFACE_VERSION == 6005 + +Changes (w.r.t. Intel TBB 4.0 Update 4): + +- Parallel pipeline optimization (directly storing small objects in the + interstage data buffers) limited to trivially-copyable types for + C++11 and a short list of types for earlier compilers. +- _VARIADIC_MAX switch is honored for TBB tuple implementation + and flow::graph nodes based on tuple. +- Support of Cocoa framework was added to the GUI examples on OS X* + systems. + +Bugs fixed: + +- Fixed a tv_nsec overflow bug in condition_variable::wait_for. +- Fixed execution order of enqueued tasks with different priorities. +- Fixed a bug with task priority changes causing lack of progress + for fire-and-forget tasks when TBB was initialized to use 1 thread. +- Fixed duplicate symbol problem when linking multiple compilation + units that include flow_graph.h on VC 10. + +------------------------------------------------------------------------ +Intel TBB 4.0 Update 4 +TBB_INTERFACE_VERSION == 6004 + +Changes (w.r.t. Intel TBB 4.0 Update 3): + +- The TBB memory allocator transparently supports large pages on Linux. +- A new flow_graph example, logic_sim, was added. +- Support for DirectX* 9 was added to GUI examples. + +Community Preview Features: + +- Added: aggregator, a new concurrency control mechanism. + +Bugs fixed: + +- The abort operation on concurrent_bounded_queue now leaves the queue + in a reusable state. If a bad_alloc or bad_last_alloc exception is + thrown while the queue is recovering from an abort, that exception + will be reported instead of user_abort on the thread on which it + occurred, and the queue will not be reusable. +- Steal limiting heuristic fixed to avoid premature stealing disabling + when large amount of __thread data is allocated on thread stack. +- Fixed a low-probability leak of arenas in the task scheduler. +- In STL-compatible allocator classes, the method construct() was fixed + to comply with C++11 requirements. +- Fixed a bug that prevented creation of fixed-size memory pools + smaller than 2M. +- Significantly reduced the amount of warnings from various compilers. + +Open-source contributions integrated: + +- Multiple improvements by Raf Schietekat. +- Basic support for Clang on OS X* by Blas Rodriguez Somoza. +- Fixes for warnings and corner-case bugs by Blas Rodriguez Somoza + and Edward Lam. + +------------------------------------------------------------------------ +Intel TBB 4.0 Update 3 +TBB_INTERFACE_VERSION == 6003 + +Changes (w.r.t. Intel TBB 4.0 Update 2): + +- Modifications to the low-level API for memory pools: + added support for aligned allocations; + pool policies reworked to allow backward-compatible extensions; + added a policy to not return memory space till destruction; + pool_reset() does not return memory space anymore. +- Class tbb::flow::graph_iterator added to iterate over all nodes + registered with a graph instance. +- multioutput_function_node has been renamed multifunction_node. + multifunction_node and split_node are now fully-supported features. +- For the tagged join node, the policy for try_put of an item with + already existing tag has been defined: the item will be rejected. +- Matching the behavior on Windows, on other platforms the optional + shared libraries (libtbbmalloc, libirml) now are also searched + only in the directory where libtbb is located. +- The platform isolation layer based on GCC built-ins is extended. + +Backward-incompatible API changes: + +- a graph reference parameter is now required to be passed to the + constructors of the following flow graph nodes: overwrite_node, + write_once_node, broadcast_node, and the CPF or_node. +- the following tbb::flow node methods and typedefs have been renamed: + Old New + join_node and or_node: + inputs() -> input_ports() + input_ports_tuple_type -> input_ports_type + multifunction_node and split_node: + ports_type -> output_ports_type + +Bugs fixed: + +- Not all logical processors were utilized on systems with more than + 64 cores split by Windows into several processor groups. + +------------------------------------------------------------------------ +Intel TBB 4.0 Update 2 commercial-aligned release +TBB_INTERFACE_VERSION == 6002 + +Changes (w.r.t. Intel TBB 4.0 Update 1 commercial-aligned release): + +- concurrent_bounded_queue now has an abort() operation that releases + threads involved in pending push or pop operations. The released + threads will receive a tbb::user_abort exception. +- Added Community Preview Feature: concurrent_lru_cache container, + a concurrent implementation of LRU (least-recently-used) cache. + +Bugs fixed: + +- fixed a race condition in the TBB scalable allocator. +- concurrent_queue counter wraparound bug was fixed, which occurred when + the number of push and pop operations exceeded ~>4 billion on IA32. +- fixed races in the TBB scheduler that could put workers asleep too + early, especially in presence of affinitized tasks. + +------------------------------------------------------------------------ +Intel TBB 4.0 Update 1 commercial-aligned release +TBB_INTERFACE_VERSION == 6000 (forgotten to increment) + +Changes (w.r.t. Intel TBB 4.0 commercial-aligned release): + +- Memory leaks fixed in binpack example. +- Improvements and fixes in the TBB allocator. + +------------------------------------------------------------------------ +Intel TBB 4.0 commercial-aligned release +TBB_INTERFACE_VERSION == 6000 + +Changes (w.r.t. Intel TBB 3.0 Update 8 commercial-aligned release): + +- concurrent_priority_queue is now a fully supported feature. + Capacity control methods were removed. +- Flow graph is now a fully supported feature. +- A new memory backend has been implemented in the TBB allocator. + It can reuse freed memory for both small and large objects, and + returns unused memory blocks to the OS more actively. +- Improved partitioning algorithms for parallel_for and parallel_reduce + to better handle load imbalance. +- The convex_hull example has been refactored for reproducible + performance results. +- The major interface version has changed from 5 to 6. + Deprecated interfaces might be removed in future releases. + +Community Preview Features: + +- Added: serial subset, i.e. sequential implementations of TBB generic + algorithms (currently, only provided for parallel_for). +- Preview of new flow graph nodes: + or_node (accepts multiple inputs, forwards each input separately + to all successors), + split_node (accepts tuples, and forwards each element of a tuple + to a corresponding successor), and + multioutput_function_node (accepts one input, and passes the input + and a tuple of output ports to the function body to support outputs + to multiple successors). +- Added: memory pools for more control on memory source, grouping, + and collective deallocation. + +------------------------------------------------------------------------ +Intel TBB 3.0 Update 8 commercial-aligned release +TBB_INTERFACE_VERSION == 5008 + +Changes (w.r.t. Intel TBB 3.0 Update 7 commercial-aligned release): + +- Task priorities become an official feature of TBB, + not community preview as before. +- Atomics API extended, and implementation refactored. +- Added task::set_parent() method. +- Added concurrent_unordered_set container. + +Open-source contributions integrated: + +- PowerPC support by Raf Schietekat. +- Fix of potential task pool overrun and other improvements + in the task scheduler by Raf Schietekat. +- Fix in parallel_for_each to work with std::set in Visual* C++ 2010. + +Community Preview Features: + +- Graph community preview feature was renamed to flow graph. + Multiple improvements in the implementation. + Binpack example was added for the feature. +- A number of improvements to concurrent_priority_queue. + Shortpath example was added for the feature. +- TBB runtime loaded functionality was added (Windows*-only). + It allows to specify which versions of TBB should be used, + as well as to set directories for the library search. +- parallel_deterministic_reduce template function was added. + +------------------------------------------------------------------------ +Intel TBB 3.0 Update 7 commercial-aligned release +TBB_INTERFACE_VERSION == 5006 (forgotten to increment) + +Changes (w.r.t. Intel TBB 3.0 Update 6 commercial-aligned release): + +- Added implementation of the platform isolation layer based on + GCC atomic built-ins; it is supposed to work on any platform + where GCC has these built-ins. + +Community Preview Features: + +- Graph's dining_philosophers example added. +- A number of improvements to graph and concurrent_priority_queue. + + +------------------------------------------------------------------------ +Intel TBB 3.0 Update 6 commercial-aligned release +TBB_INTERFACE_VERSION == 5006 + +Changes (w.r.t. Intel TBB 3.0 Update 5 commercial-aligned release): + +- Added Community Preview feature: task and task group priority, and + Fractal example demonstrating it. +- parallel_pipeline optimized for data items of small and large sizes. +- Graph's join_node is now parametrized with a tuple of up to 10 types. +- Improved performance of concurrent_priority_queue. + +Open-source contributions integrated: + +- Initial NetBSD support by Aleksej Saushev. + +Bugs fixed: + +- Failure to enable interoperability with Intel(R) Cilk(tm) Plus runtime + library, and a crash caused by invoking the interoperability layer + after one of the libraries was unloaded. +- Data race that could result in concurrent_unordered_map structure + corruption after call to clear() method. +- Stack corruption caused by PIC version of 64-bit CAS compiled by Intel + compiler on Linux. +- Inconsistency of exception propagation mode possible when application + built with Microsoft* Visual Studio* 2008 or earlier uses TBB built + with Microsoft* Visual Studio* 2010. +- Affinitizing master thread to a subset of available CPUs after TBB + scheduler was initialized tied all worker threads to the same CPUs. +- Method is_stolen_task() always returned 'false' for affinitized tasks. +- write_once_node and overwrite_node did not immediately send buffered + items to successors + +------------------------------------------------------------------------ +Intel TBB 3.0 Update 5 commercial-aligned release +TBB_INTERFACE_VERSION == 5005 + +Changes (w.r.t. Intel TBB 3.0 Update 4 commercial-aligned release): + +- Added Community Preview feature: graph. +- Added automatic propagation of master thread FPU settings to + TBB worker threads. +- Added a public function to perform a sequentially consistent full + memory fence: tbb::atomic_fence() in tbb/atomic.h. + +Bugs fixed: + +- Data race that could result in scheduler data structures corruption + when using fire-and-forget tasks. +- Potential referencing of destroyed concurrent_hash_map element after + using erase(accessor&A) method with A acquired as const_accessor. +- Fixed a correctness bug in the convex hull example. + +Open-source contributions integrated: + +- Patch for calls to internal::atomic_do_once() by Andrey Semashev. + +------------------------------------------------------------------------ +Intel TBB 3.0 Update 4 commercial-aligned release +TBB_INTERFACE_VERSION == 5004 + +Changes (w.r.t. Intel TBB 3.0 Update 3 commercial-aligned release): + +- Added Community Preview feature: concurrent_priority_queue. +- Fixed library loading to avoid possibility for remote code execution, + see http://www.microsoft.com/technet/security/advisory/2269637.mspx. +- Added support of more than 64 cores for appropriate Microsoft* + Windows* versions. For more details, see + http://msdn.microsoft.com/en-us/library/dd405503.aspx. +- Default number of worker threads is adjusted in accordance with + process affinity mask. + +Bugs fixed: + +- Calls of scalable_* functions from inside the allocator library + caused issues if the functions were overridden by another module. +- A crash occurred if methods run() and wait() were called concurrently + for an empty tbb::task_group (1736). +- The tachyon example exhibited build problems associated with + bug 554339 on Microsoft* Visual Studio* 2010. Project files were + modified as a partial workaround to overcome the problem. See + http://connect.microsoft.com/VisualStudio/feedback/details/554339. + +------------------------------------------------------------------------ +Intel TBB 3.0 Update 3 commercial-aligned release +TBB_INTERFACE_VERSION == 5003 + +Changes (w.r.t. Intel TBB 3.0 Update 2 commercial-aligned release): + +- cache_aligned_allocator class reworked to use scalable_aligned_malloc. +- Improved performance of count() and equal_range() methods + in concurrent_unordered_map. +- Improved implementation of 64-bit atomic loads and stores on 32-bit + platforms, including compilation with VC 7.1. +- Added implementation of atomic operations on top of OSAtomic API + provided by OS X*. +- Removed gratuitous try/catch blocks surrounding thread function calls + in tbb_thread. +- Xcode* projects were added for sudoku and game_of_life examples. +- Xcode* projects were updated to work without TBB framework. + +Bugs fixed: + +- Fixed a data race in task scheduler destruction that on rare occasion + could result in memory corruption. +- Fixed idle spinning in thread bound filters in tbb::pipeline (1670). + +Open-source contributions integrated: + +- MinGW-64 basic support by brsomoza (partially). +- Patch for atomic.h by Andrey Semashev. +- Support for AIX & GCC on PowerPC by Giannis Papadopoulos. +- Various improvements by Raf Schietekat. + +------------------------------------------------------------------------ +Intel TBB 3.0 Update 2 commercial-aligned release +TBB_INTERFACE_VERSION == 5002 + +Changes (w.r.t. Intel TBB 3.0 Update 1 commercial-aligned release): + +- Destructor of tbb::task_group class throws missing_wait exception + if there are tasks running when it is invoked. +- Interoperability layer with Intel Cilk Plus runtime library added + to protect TBB TLS in case of nested usage with Intel Cilk Plus. +- Compilation fix for dependent template names in concurrent_queue. +- Memory allocator code refactored to ease development and maintenance. + +Bugs fixed: + +- Improved interoperability with other Intel software tools on Linux in + case of dynamic replacement of memory allocator (1700) +- Fixed install issues that prevented installation on + Mac OS* X 10.6.4 (1711). + +------------------------------------------------------------------------ +Intel TBB 3.0 Update 1 commercial-aligned release +TBB_INTERFACE_VERSION == 5000 (forgotten to increment) + +Changes (w.r.t. Intel TBB 3.0 commercial-aligned release): + +- Decreased memory fragmentation by allocations bigger than 8K. +- Lazily allocate worker threads, to avoid creating unnecessary stacks. + +Bugs fixed: + +- TBB allocator used much more memory than malloc (1703) - see above. +- Deadlocks happened in some specific initialization scenarios + of the TBB allocator (1701, 1704). +- Regression in enumerable_thread_specific: excessive requirements + for object constructors. +- A bug in construction of parallel_pipeline filters when body instance + was a temporary object. +- Incorrect usage of memory fences on PowerPC and XBOX360 platforms. +- A subtle issue in task group context binding that could result + in cancellation signal being missed by nested task groups. +- Incorrect construction of concurrent_unordered_map if specified + number of buckets is not power of two. +- Broken count() and equal_range() of concurrent_unordered_map. +- Return type of postfix form of operator++ for hash map's iterators. + +------------------------------------------------------------------------ +Intel TBB 3.0 commercial-aligned release +TBB_INTERFACE_VERSION == 5000 + +Changes (w.r.t. Intel TBB 2.2 Update 3 commercial-aligned release): + +- All open-source-release changes down to TBB 2.2 U3 below + were incorporated into this release. + +------------------------------------------------------------------------ +20100406 open-source release + +Changes (w.r.t. 20100310 open-source release): + +- Added support for Microsoft* Visual Studio* 2010, including binaries. +- Added a PDF file with recommended Design Patterns for TBB. +- Added parallel_pipeline function and companion classes and functions + that provide a strongly typed lambda-friendly pipeline interface. +- Reworked enumerable_thread_specific to use a custom implementation of + hash map that is more efficient for ETS usage models. +- Added example for class task_group; see examples/task_group/sudoku. +- Removed two examples, as they were long outdated and superseded: + pipeline/text_filter (use pipeline/square); + parallel_while/parallel_preorder (use parallel_do/parallel_preorder). +- PDF documentation updated. +- Other fixes and changes in code, tests, and examples. + +Bugs fixed: + +- Eliminated build errors with MinGW32. +- Fixed post-build step and other issues in VS projects for examples. +- Fixed discrepancy between scalable_realloc and scalable_msize that + caused crashes with malloc replacement on Windows. + +------------------------------------------------------------------------ +20100310 open-source release + +Changes (w.r.t. Intel TBB 2.2 Update 3 commercial-aligned release): + +- Version macros changed in anticipation of a future release. +- Directory structure aligned with Intel(R) C++ Compiler; + now TBB binaries reside in //[bin|lib] + (in TBB 2.x, it was [bin|lib]//). +- Visual Studio projects changed for examples: instead of separate set + of files for each VS version, now there is single 'msvs' directory + that contains workspaces for MS C++ compiler (_cl.sln) and + Intel C++ compiler (_icl.sln). Works with VS 2005 and above. +- The name versioning scheme for backward compatibility was improved; + now compatibility-breaking changes are done in a separate namespace. +- Added concurrent_unordered_map implementation based on a prototype + developed in Microsoft for a future version of PPL. +- Added PPL-compatible writer-preference RW lock (reader_writer_lock). +- Added TBB_IMPLEMENT_CPP0X macro to control injection of C++0x names + implemented in TBB into namespace std. +- Added almost-C++0x-compatible std::condition_variable, plus a bunch + of other C++0x classes required by condition_variable. +- With TBB_IMPLEMENT_CPP0X, tbb_thread can be also used as std::thread. +- task.cpp was split into several translation units to structure + TBB scheduler sources layout. Static data layout and library + initialization logic were also updated. +- TBB scheduler reworked to prevent master threads from stealing + work belonging to other masters. +- Class task was extended with enqueue() method, and slightly changed + semantics of methods spawn() and destroy(). For exact semantics, + refer to TBB Reference manual. +- task_group_context now allows for destruction by non-owner threads. +- Added TBB_USE_EXCEPTIONS macro to control use of exceptions in TBB + headers. It turns off (i.e. sets to 0) automatically if specified + compiler options disable exception handling. +- TBB is enabled to run on top of Microsoft's Concurrency Runtime + on Windows* 7 (via our worker dispatcher known as RML). +- Removed old unused busy-waiting code in concurrent_queue. +- Described the advanced build & test options in src/index.html. +- Warning level for GCC raised with -Wextra and a few other options. +- Multiple fixes and improvements in code, tests, examples, and docs. + +Open-source contributions integrated: + +- Xbox support by Roman Lut (Deep Shadows), though further changes are + required to make it working; e.g. post-2.1 entry points are missing. +- "Eventcount" by Dmitry Vyukov evolved into concurrent_monitor, + an internal class used in the implementation of concurrent_queue. + +------------------------------------------------------------------------ +Intel TBB 2.2 Update 3 commercial-aligned release +TBB_INTERFACE_VERSION == 4003 + +Changes (w.r.t. Intel TBB 2.2 Update 2 commercial-aligned release): + +- PDF documentation updated. + +Bugs fixed: + +- concurrent_hash_map compatibility issue exposed on Linux in case + two versions of the container were used by different modules. +- enforce 16 byte stack alignment for consistence with GCC; required + to work correctly with 128-bit variables processed by SSE. +- construct() methods of allocator classes now use global operator new. + +------------------------------------------------------------------------ +Intel TBB 2.2 Update 2 commercial-aligned release +TBB_INTERFACE_VERSION == 4002 + +Changes (w.r.t. Intel TBB 2.2 Update 1 commercial-aligned release): + +- parallel_invoke and parallel_for_each now take function objects + by const reference, not by value. +- Building TBB with /MT is supported, to avoid dependency on particular + versions of Visual C++* runtime DLLs. TBB DLLs built with /MT + are located in vc_mt directory. +- Class critical_section introduced. +- Improvements in exception support: new exception classes introduced, + all exceptions are thrown via an out-of-line internal method. +- Improvements and fixes in the TBB allocator and malloc replacement, + including robust memory identification, and more reliable dynamic + function substitution on Windows*. +- Method swap() added to class tbb_thread. +- Methods rehash() and bucket_count() added to concurrent_hash_map. +- Added support for Visual Studio* 2010 Beta2. No special binaries + provided, but CRT-independent DLLs (vc_mt) should work. +- Other fixes and improvements in code, tests, examples, and docs. + +Open-source contributions integrated: + +- The fix to build 32-bit TBB on Mac OS* X 10.6. +- GCC-based port for SPARC Solaris by Michailo Matijkiw, with use of + earlier work by Raf Schietekat. + +Bugs fixed: + +- 159 - TBB build for PowerPC* running Mac OS* X. +- 160 - IBM* Java segfault if used with TBB allocator. +- crash in concurrent_queue (1616). + +------------------------------------------------------------------------ +Intel TBB 2.2 Update 1 commercial-aligned release +TBB_INTERFACE_VERSION == 4001 + +Changes (w.r.t. Intel TBB 2.2 commercial-aligned release): + +- Incorporates all changes from open-source releases below. +- Documentation was updated. +- TBB scheduler auto-initialization now covers all possible use cases. +- concurrent_queue: made argument types of sizeof used in paddings + consistent with those actually used. +- Memory allocator was improved: supported corner case of user's malloc + calling scalable_malloc (non-Windows), corrected processing of + memory allocation requests during tbb memory allocator startup + (Linux). +- Windows malloc replacement has got better support for static objects. +- In pipeline setups that do not allow actual parallelism, execution + by a single thread is guaranteed, idle spinning eliminated, and + performance improved. +- RML refactoring and clean-up. +- New constructor for concurrent_hash_map allows reserving space for + a number of items. +- Operator delete() added to the TBB exception classes. +- Lambda support was improved in parallel_reduce. +- gcc 4.3 warnings were fixed for concurrent_queue. +- Fixed possible initialization deadlock in modules using TBB entities + during construction of global static objects. +- Copy constructor in concurrent_hash_map was fixed. +- Fixed a couple of rare crashes in the scheduler possible before + in very specific use cases. +- Fixed a rare crash in the TBB allocator running out of memory. +- New tests were implemented, including test_lambda.cpp that checks + support for lambda expressions. +- A few other small changes in code, tests, and documentation. + +------------------------------------------------------------------------ +20090809 open-source release + +Changes (w.r.t. Intel TBB 2.2 commercial-aligned release): + +- Fixed known exception safety issues in concurrent_vector. +- Better concurrency of simultaneous grow requests in concurrent_vector. +- TBB allocator further improves performance of large object allocation. +- Problem with source of text relocations was fixed on Linux +- Fixed bugs related to malloc replacement under Windows +- A few other small changes in code and documentation. + +------------------------------------------------------------------------ +Intel TBB 2.2 commercial-aligned release +TBB_INTERFACE_VERSION == 4000 + +Changes (w.r.t. Intel TBB 2.1 U4 commercial-aligned release): + +- Incorporates all changes from open-source releases below. +- Architecture folders renamed from em64t to intel64 and from itanium + to ia64. +- Major Interface version changed from 3 to 4. Deprecated interfaces + might be removed in future releases. +- Parallel algorithms that use partitioners have switched to use + the auto_partitioner by default. +- Improved memory allocator performance for allocations bigger than 8K. +- Added new thread-bound filters functionality for pipeline. +- New implementation of concurrent_hash_map that improves performance + significantly. +- A few other small changes in code and documentation. + +------------------------------------------------------------------------ +20090511 open-source release + +Changes (w.r.t. previous open-source release): + +- Basic support for MinGW32 development kit. +- Added tbb::zero_allocator class that initializes memory with zeros. + It can be used as an adaptor to any STL-compatible allocator class. +- Added tbb::parallel_for_each template function as alias to parallel_do. +- Added more overloads for tbb::parallel_for. +- Added support for exact exception propagation (can only be used with + compilers that support C++0x std::exception_ptr). +- tbb::atomic template class can be used with enumerations. +- mutex, recursive_mutex, spin_mutex, spin_rw_mutex classes extended + with explicit lock/unlock methods. +- Fixed size() and grow_to_at_least() methods of tbb::concurrent_vector + to provide space allocation guarantees. More methods added for + compatibility with std::vector, including some from C++0x. +- Preview of a lambda-friendly interface for low-level use of tasks. +- scalable_msize function added to the scalable allocator (Windows only). +- Rationalized internal auxiliary functions for spin-waiting and backoff. +- Several tests undergo decent refactoring. + +Changes affecting backward compatibility: + +- Improvements in concurrent_queue, including limited API changes. + The previous version is deprecated; its functionality is accessible + via methods of the new tbb::concurrent_bounded_queue class. +- grow* and push_back methods of concurrent_vector changed to return + iterators; old semantics is deprecated. + +------------------------------------------------------------------------ +Intel TBB 2.1 Update 4 commercial-aligned release +TBB_INTERFACE_VERSION == 3016 + +Changes (w.r.t. Intel TBB 2.1 U3 commercial-aligned release): + +- Added tests for aligned memory allocations and malloc replacement. +- Several improvements for better bundling with Intel(R) C++ Compiler. +- A few other small changes in code and documentation. + +Bugs fixed: + +- 150 - request to build TBB examples with debug info in release mode. +- backward compatibility issue with concurrent_queue on Windows. +- dependency on VS 2005 SP1 runtime libraries removed. +- compilation of GUI examples under Xcode* 3.1 (1577). +- On Windows, TBB allocator classes can be instantiated with const types + for compatibility with MS implementation of STL containers (1566). + +------------------------------------------------------------------------ +20090313 open-source release + +Changes (w.r.t. 20081109 open-source release): + +- Includes all changes introduced in TBB 2.1 Update 2 & Update 3 + commercial-aligned releases (see below for details). +- Added tbb::parallel_invoke template function. It runs up to 10 + user-defined functions in parallel and waits for them to complete. +- Added a special library providing ability to replace the standard + memory allocation routines in Microsoft* C/C++ RTL (malloc/free, + global new/delete, etc.) with the TBB memory allocator. + Usage details are described in include/tbb/tbbmalloc_proxy.h file. +- Task scheduler switched to use new implementation of its core + functionality (deque based task pool, new structure of arena slots). +- Preview of Microsoft* Visual Studio* 2005 project files for + building the library is available in build/vsproject folder. +- Added tests for aligned memory allocations and malloc replacement. +- Added parallel_for/game_of_life.net example (for Windows only) + showing TBB usage in a .NET application. +- A number of other fixes and improvements to code, tests, makefiles, + examples and documents. + +Bugs fixed: + +- The same list as in TBB 2.1 Update 4 right above. + +------------------------------------------------------------------------ +Intel TBB 2.1 Update 3 commercial-aligned release +TBB_INTERFACE_VERSION == 3015 + +Changes (w.r.t. Intel TBB 2.1 U2 commercial-aligned release): + +- Added support for aligned allocations to the TBB memory allocator. +- Added a special library to use with LD_PRELOAD on Linux* in order to + replace the standard memory allocation routines in C/C++ with the + TBB memory allocator. +- Added null_mutex and null_rw_mutex: no-op classes interface-compliant + to other TBB mutexes. +- Improved performance of parallel_sort, to close most of the serial gap + with std::sort, and beat it on 2 and more cores. +- A few other small changes. + +Bugs fixed: + +- the problem where parallel_for hanged after exception throw + if affinity_partitioner was used (1556). +- get rid of VS warnings about mbstowcs deprecation (1560), + as well as some other warnings. +- operator== for concurrent_vector::iterator fixed to work correctly + with different vector instances. + +------------------------------------------------------------------------ +Intel TBB 2.1 Update 2 commercial-aligned release +TBB_INTERFACE_VERSION == 3014 + +Changes (w.r.t. Intel TBB 2.1 U1 commercial-aligned release): + +- Incorporates all open-source-release changes down to TBB 2.1 U1, + except for: + - 20081019 addition of enumerable_thread_specific; +- Warning level for Microsoft* Visual C++* compiler raised to /W4 /Wp64; + warnings found on this level were cleaned or suppressed. +- Added TBB_runtime_interface_version API function. +- Added new example: pipeline/square. +- Added exception handling and cancellation support + for parallel_do and pipeline. +- Added copy constructor and [begin,end) constructor to concurrent_queue. +- Added some support for beta version of Intel(R) Parallel Amplifier. +- Added scripts to set environment for cross-compilation of 32-bit + applications on 64-bit Linux with Intel(R) C++ Compiler. +- Fixed semantics of concurrent_vector::clear() to not deallocate + internal arrays. Fixed compact() to perform such deallocation later. +- Fixed the issue with atomic when T is incomplete type. +- Improved support for PowerPC* Macintosh*, including the fix + for a bug in masked compare-and-swap reported by a customer. +- As usual, a number of other improvements everywhere. + +------------------------------------------------------------------------ +20081109 open-source release + +Changes (w.r.t. previous open-source release): + +- Added new serial out of order filter for tbb::pipeline. +- Fixed the issue with atomic::operator= reported at the forum. +- Fixed the issue with using tbb::task::self() in task destructor + reported at the forum. +- A number of other improvements to code, tests, makefiles, examples + and documents. + +Open-source contributions integrated: +- Changes in the memory allocator were partially integrated. + +------------------------------------------------------------------------ +20081019 open-source release + +Changes (w.r.t. previous open-source release): + +- Introduced enumerable_thread_specific. This new class provides a + wrapper around native thread local storage as well as iterators and + ranges for accessing the thread local copies (1533). +- Improved support for Intel(R) Threading Analysis Tools + on Intel(R) 64 architecture. +- Dependency from Microsoft* CRT was integrated to the libraries using + manifests, to avoid issues if called from code that uses different + version of Visual C++* runtime than the library. +- Introduced new defines TBB_USE_ASSERT, TBB_USE_DEBUG, + TBB_USE_PERFORMANCE_WARNINGS, TBB_USE_THREADING_TOOLS. +- A number of other improvements to code, tests, makefiles, examples + and documents. + +Open-source contributions integrated: + +- linker optimization: /incremental:no . + +------------------------------------------------------------------------ +20080925 open-source release + +Changes (w.r.t. previous open-source release): + +- Same fix for a memory leak in the memory allocator as in TBB 2.1 U1. +- Improved support for lambda functions. +- Fixed more concurrent_queue issues reported at the forum. +- A number of other improvements to code, tests, makefiles, examples + and documents. + +------------------------------------------------------------------------ +Intel TBB 2.1 Update 1 commercial-aligned release +TBB_INTERFACE_VERSION == 3013 + +Changes (w.r.t. Intel TBB 2.1 commercial-aligned release): + +- Fixed small memory leak in the memory allocator. +- Incorporates all open-source-release changes since TBB 2.1, + except for: + - 20080825 changes for parallel_do; + +------------------------------------------------------------------------ +20080825 open-source release + +Changes (w.r.t. previous open-source release): + +- Added exception handling and cancellation support for parallel_do. +- Added default HashCompare template argument for concurrent_hash_map. +- Fixed concurrent_queue.clear() issues due to incorrect assumption + about clear() being private method. +- Added the possibility to use TBB in applications that change + default calling conventions (Windows* only). +- Many improvements to code, tests, examples, makefiles and documents. + +Bugs fixed: + +- 120, 130 - memset declaration missed in concurrent_hash_map.h + +------------------------------------------------------------------------ +20080724 open-source release + +Changes (w.r.t. previous open-source release): + +- Inline assembly for atomic operations improved for gcc 4.3 +- A few more improvements to the code. + +------------------------------------------------------------------------ +20080709 open-source release + +Changes (w.r.t. previous open-source release): + +- operator=() was added to the tbb_thread class according to + the current working draft for std::thread. +- Recognizing SPARC* in makefiles for Linux* and Sun Solaris*. + +Bugs fixed: + +- 127 - concurrent_hash_map::range fixed to split correctly. + +Open-source contributions integrated: + +- fix_set_midpoint.diff by jyasskin +- SPARC* support in makefiles by Raf Schietekat + +------------------------------------------------------------------------ +20080622 open-source release + +Changes (w.r.t. previous open-source release): + +- Fixed a hang that rarely happened on Linux + during deinitialization of the TBB scheduler. +- Improved support for Intel(R) Thread Checker. +- A few more improvements to the code. + +------------------------------------------------------------------------ +Intel TBB 2.1 commercial-aligned release +TBB_INTERFACE_VERSION == 3011 + +Changes (w.r.t. Intel TBB 2.0 U3 commercial-aligned release): + +- All open-source-release changes down to, and including, TBB 2.0 below, + were incorporated into this release. + +------------------------------------------------------------------------ +20080605 open-source release + +Changes (w.r.t. previous open-source release): + +- Explicit control of exported symbols by version scripts added on Linux. +- Interfaces polished for exception handling & algorithm cancellation. +- Cache behavior improvements in the scalable allocator. +- Improvements in text_filter, polygon_overlay, and other examples. +- A lot of other stability improvements in code, tests, and makefiles. +- First release where binary packages include headers/docs/examples, so + binary packages are now self-sufficient for using TBB. + +Open-source contributions integrated: + +- atomics patch (partially). +- tick_count warning patch. + +Bugs fixed: + +- 118 - fix for boost compatibility. +- 123 - fix for tbb_machine.h. + +------------------------------------------------------------------------ +20080512 open-source release + +Changes (w.r.t. previous open-source release): + +- Fixed a problem with backward binary compatibility + of debug Linux builds. +- Sun* Studio* support added. +- soname support added on Linux via linker script. To restore backward + binary compatibility, *.so -> *.so.2 softlinks should be created. +- concurrent_hash_map improvements - added few new forms of insert() + method and fixed precondition and guarantees of erase() methods. + Added runtime warning reporting about bad hash function used for + the container. Various improvements for performance and concurrency. +- Cancellation mechanism reworked so that it does not hurt scalability. +- Algorithm parallel_do reworked. Requirement for Body::argument_type + definition removed, and work item argument type can be arbitrarily + cv-qualified. +- polygon_overlay example added. +- A few more improvements to code, tests, examples and Makefiles. + +Open-source contributions integrated: + +- Soname support patch for Bugzilla #112. + +Bugs fixed: + +- 112 - fix for soname support. + +------------------------------------------------------------------------ +Intel TBB 2.0 U3 commercial-aligned release (package 017, April 20, 2008) + +Corresponds to commercial 019 (for Linux*, 020; for Mac OS* X, 018) +packages. + +Changes (w.r.t. Intel TBB 2.0 U2 commercial-aligned release): + +- Does not contain open-source-release changes below; this release is + only a minor update of TBB 2.0 U2. +- Removed spin-waiting in pipeline and concurrent_queue. +- A few more small bug fixes from open-source releases below. + +------------------------------------------------------------------------ +20080408 open-source release + +Changes (w.r.t. previous open-source release): + +- count_strings example reworked: new word generator implemented, hash + function replaced, and tbb_allocator is used with std::string class. +- Static methods of spin_rw_mutex were replaced by normal member + functions, and the class name was versioned. +- tacheon example was renamed to tachyon. +- Improved support for Intel(R) Thread Checker. +- A few more minor improvements. + +Open-source contributions integrated: + +- Two sets of Sun patches for IA Solaris support. + +------------------------------------------------------------------------ +20080402 open-source release + +Changes (w.r.t. previous open-source release): + +- Exception handling and cancellation support for tasks and algorithms + fully enabled. +- Exception safety guaranties defined and fixed for all concurrent + containers. +- User-defined memory allocator support added to all concurrent + containers. +- Performance improvement of concurrent_hash_map, spin_rw_mutex. +- Critical fix for a rare race condition during scheduler + initialization/de-initialization. +- New methods added for concurrent containers to be closer to STL, + as well as automatic filters removal from pipeline + and __TBB_AtomicAND function. +- The volatile keyword dropped from where it is not really needed. +- A few more minor improvements. + +------------------------------------------------------------------------ +20080319 open-source release + +Changes (w.r.t. previous open-source release): + +- Support for gcc version 4.3 was added. +- tbb_thread class, near compatible with std::thread expected in C++0x, + was added. + +Bugs fixed: + +- 116 - fix for compilation issues with gcc version 4.2.1. +- 120 - fix for compilation issues with gcc version 4.3. + +------------------------------------------------------------------------ +20080311 open-source release + +Changes (w.r.t. previous open-source release): + +- An enumerator added for pipeline filter types (serial vs. parallel). +- New task_scheduler_observer class introduced, to observe when + threads start and finish interacting with the TBB task scheduler. +- task_scheduler_init reverted to not use internal versioned class; + binary compatibility guaranteed with stable releases only. +- Various improvements to code, tests, examples and Makefiles. + +------------------------------------------------------------------------ +20080304 open-source release + +Changes (w.r.t. previous open-source release): + +- Task-to-thread affinity support, previously kept under a macro, + now fully legalized. +- Work-in-progress on cache_aligned_allocator improvements. +- Pipeline really supports parallel input stage; it's no more serialized. +- Various improvements to code, tests, examples and Makefiles. + +Bugs fixed: + +- 119 - fix for scalable_malloc sometimes failing to return a big block. +- TR575 - fixed a deadlock occurring on Windows in startup/shutdown + under some conditions. + +------------------------------------------------------------------------ +20080226 open-source release + +Changes (w.r.t. previous open-source release): + +- Introduced tbb_allocator to select between standard allocator and + tbb::scalable_allocator when available. +- Removed spin-waiting in pipeline and concurrent_queue. +- Improved performance of concurrent_hash_map by using tbb_allocator. +- Improved support for Intel(R) Thread Checker. +- Various improvements to code, tests, examples and Makefiles. + +------------------------------------------------------------------------ +Intel TBB 2.0 U2 commercial-aligned release (package 017, February 14, 2008) + +Corresponds to commercial 017 (for Linux*, 018; for Mac OS* X, 016) +packages. + +Changes (w.r.t. Intel TBB 2.0 U1 commercial-aligned release): + +- Does not contain open-source-release changes below; this release is + only a minor update of TBB 2.0 U1. +- Add support for Microsoft* Visual Studio* 2008, including binary + libraries and VS2008 projects for examples. +- Use SwitchToThread() not Sleep() to yield threads on Windows*. +- Enhancements to Doxygen-readable comments in source code. +- A few more small bug fixes from open-source releases below. + +Bugs fixed: + +- TR569 - Memory leak in concurrent_queue. + +------------------------------------------------------------------------ +20080207 open-source release + +Changes (w.r.t. previous open-source release): + +- Improvements and minor fixes in VS2008 projects for examples. +- Improvements in code for gating worker threads that wait for work, + previously consolidated under #if IMPROVED_GATING, now legalized. +- Cosmetic changes in code, examples, tests. + +Bugs fixed: + +- 113 - Iterators and ranges should be convertible to their const + counterparts. +- TR569 - Memory leak in concurrent_queue. + +------------------------------------------------------------------------ +20080122 open-source release + +Changes (w.r.t. previous open-source release): + +- Updated examples/parallel_for/seismic to improve the visuals and to + use the affinity_partitioner (20071127 and forward) for better + performance. +- Minor improvements to unittests and performance tests. + +------------------------------------------------------------------------ +20080115 open-source release + +Changes (w.r.t. previous open-source release): + +- Cleanup, simplifications and enhancements to the Makefiles for + building the libraries (see build/index.html for high-level + changes) and the examples. +- Use SwitchToThread() not Sleep() to yield threads on Windows*. +- Engineering work-in-progress on exception safety/support. +- Engineering work-in-progress on affinity_partitioner for + parallel_reduce. +- Engineering work-in-progress on improved gating for worker threads + (idle workers now block in the OS instead of spinning). +- Enhancements to Doxygen-readable comments in source code. + +Bugs fixed: + +- 102 - Support for parallel build with gmake -j +- 114 - /Wp64 build warning on Windows*. + +------------------------------------------------------------------------ +20071218 open-source release + +Changes (w.r.t. previous open-source release): + +- Full support for Microsoft* Visual Studio* 2008 in open-source. + Binaries for vc9/ will be available in future stable releases. +- New recursive_mutex class. +- Full support for 32-bit PowerMac including export files for builds. +- Improvements to parallel_do. + +------------------------------------------------------------------------ +20071206 open-source release + +Changes (w.r.t. previous open-source release): + +- Support for Microsoft* Visual Studio* 2008 in building libraries + from source as well as in vc9/ projects for examples. +- Small fixes to the affinity_partitioner first introduced in 20071127. +- Small fixes to the thread-stack size hook first introduced in 20071127. +- Engineering work in progress on concurrent_vector. +- Engineering work in progress on exception behavior. +- Unittest improvements. + +------------------------------------------------------------------------ +20071127 open-source release + +Changes (w.r.t. previous open-source release): + +- Task-to-thread affinity support (affinity partitioner) first appears. +- More work on concurrent_vector. +- New parallel_do algorithm (function-style version of parallel while) + and parallel_do/parallel_preorder example. +- New task_scheduler_init() hooks for getting default_num_threads() and + for setting thread stack size. +- Support for weak memory consistency models in the code base. +- Futex usage in the task scheduler (Linux). +- Started adding 32-bit PowerMac support. +- Intel(R) 9.1 compilers are now the base supported Intel(R) compiler + version. +- TBB libraries added to link line automatically on Microsoft Windows* + systems via #pragma comment linker directives. + +Open-source contributions integrated: + +- FreeBSD platform support patches. +- AIX weak memory model patch. + +Bugs fixed: + +- 108 - Removed broken affinity.h reference. +- 101 - Does not build on Debian Lenny (replaced arch with uname -m). + +------------------------------------------------------------------------ +20071030 open-source release + +Changes (w.r.t. previous open-source release): + +- More work on concurrent_vector. +- Better support for building with -Wall -Werror (or not) as desired. +- A few fixes to eliminate extraneous warnings. +- Begin introduction of versioning hooks so that the internal/API + version is tracked via TBB_INTERFACE_VERSION. The newest binary + libraries should always work with previously-compiled code when- + ever possible. +- Engineering work in progress on using futex inside the mutexes (Linux). +- Engineering work in progress on exception behavior. +- Engineering work in progress on a new parallel_do algorithm. +- Unittest improvements. + +------------------------------------------------------------------------ +20070927 open-source release + +Changes (w.r.t. Intel TBB 2.0 U1 commercial-aligned release): + +- Minor update to TBB 2.0 U1 below. +- Begin introduction of new concurrent_vector interfaces not released + with TBB 2.0 U1. + +------------------------------------------------------------------------ +Intel TBB 2.0 U1 commercial-aligned release (package 014, October 1, 2007) + +Corresponds to commercial 014 (for Linux*, 016) packages. + +Changes (w.r.t. Intel TBB 2.0 commercial-aligned release): + +- All open-source-release changes down to, and including, TBB 2.0 + below, were incorporated into this release. +- Made a number of changes to the officially supported OS list: + Added Linux* OSs: + Asianux* 3, Debian* 4.0, Fedora Core* 6, Fedora* 7, + Turbo Linux* 11, Ubuntu* 7.04; + Dropped Linux* OSs: + Asianux* 2, Fedora Core* 4, Haansoft* Linux 2006 Server, + Mandriva/Mandrake* 10.1, Miracle Linux* 4.0, + Red Flag* DC Server 5.0; + Only Mac OS* X 10.4.9 (and forward) and Xcode* tool suite 2.4.1 (and + forward) are now supported. +- Commercial installers on Linux* fixed to recommend the correct + binaries to use in more cases, with less unnecessary warnings. +- Changes to eliminate spurious build warnings. + +Open-source contributions integrated: + +- Two small header guard macro patches; it also fixed bug #94. +- New blocked_range3d class. + +Bugs fixed: + +- 93 - Removed misleading comments in task.h. +- 94 - See above. + +------------------------------------------------------------------------ +20070815 open-source release + +Changes: + +- Changes to eliminate spurious build warnings. +- Engineering work in progress on concurrent_vector allocator behavior. +- Added hooks to use the Intel(R) compiler code coverage tools. + +Open-source contributions integrated: + +- Mac OS* X build warning patch. + +Bugs fixed: + +- 88 - Fixed TBB compilation errors if both VS2005 and Windows SDK are + installed. + +------------------------------------------------------------------------ +20070719 open-source release + +Changes: + +- Minor update to TBB 2.0 commercial-aligned release below. +- Changes to eliminate spurious build warnings. + +------------------------------------------------------------------------ +Intel TBB 2.0 commercial-aligned release (package 010, July 19, 2007) + +Corresponds to commercial 010 (for Linux*, 012) packages. + +- TBB open-source debut release. + +------------------------------------------------------------------------ +Intel TBB 1.1 commercial release (April 10, 2007) + +Changes (w.r.t. Intel TBB 1.0 commercial release): + +- auto_partitioner which offered an automatic alternative to specifying + a grain size parameter to estimate the best granularity for tasks. +- The release was added to the Intel(R) C++ Compiler 10.0 Pro. + +------------------------------------------------------------------------ +Intel TBB 1.0 Update 2 commercial release + +Changes (w.r.t. Intel TBB 1.0 Update 1 commercial release): + +- Mac OS* X 64-bit support added. +- Source packages for commercial releases introduced. + +------------------------------------------------------------------------ +Intel TBB 1.0 Update 1 commercial-aligned release + +Changes (w.r.t. Intel TBB 1.0 commercial release): + +- Fix for critical package issue on Mac OS* X. + +------------------------------------------------------------------------ +Intel TBB 1.0 commercial release (August 29, 2006) + +Changes (w.r.t. Intel TBB 1.0 beta commercial release): + +- New namespace (and compatibility headers for old namespace). + Namespaces are tbb and tbb::internal and all classes are in the + underscore_style not the WindowsStyle. +- New class: scalable_allocator (and cache_aligned_allocator using that + if it exists). +- Added parallel_for/tacheon example. +- Removed C-style casts from headers for better C++ compliance. +- Bug fixes. +- Documentation improvements. +- Improved performance of the concurrent_hash_map class. +- Upgraded parallel_sort() to support STL-style random-access iterators + instead of just pointers. +- The Windows vs7_1 directories renamed to vs7.1 in examples. +- New class: spin version of reader-writer lock. +- Added push_back() interface to concurrent_vector(). + +------------------------------------------------------------------------ +Intel TBB 1.0 beta commercial release + +Initial release. + +Features / APIs: + +- Concurrent containers: ConcurrentHashTable, ConcurrentVector, + ConcurrentQueue. +- Parallel algorithms: ParallelFor, ParallelReduce, ParallelScan, + ParallelWhile, Pipeline, ParallelSort. +- Support: AlignedSpace, BlockedRange (i.e., 1D), BlockedRange2D +- Task scheduler with multi-master support. +- Atomics: read, write, fetch-and-store, fetch-and-add, compare-and-swap. +- Locks: spin, reader-writer, queuing, OS-wrapper. +- Memory allocation: STL-style memory allocator that avoids false + sharing. +- Timers. + +Tools Support: +- Intel(R) Thread Checker 3.0. +- Intel(R) Thread Profiler 3.0. + +Documentation: +- First Use Documents: README.txt, INSTALL.txt, Release_Notes.txt, + Doc_Index.html, Getting_Started.pdf, Tutorial.pdf, Reference.pdf. +- Class hierarchy HTML pages (Doxygen). +- Tree of index.html pages for navigating the installed package, esp. + for the examples. + +Examples: +- One for each of these TBB features: ConcurrentHashTable, ParallelFor, + ParallelReduce, ParallelWhile, Pipeline, Task. +- Live copies of examples from Getting_Started.pdf. +- TestAll example that exercises every class and header in the package + (i.e., a "liveness test"). +- Compilers: see Release_Notes.txt. +- APIs: OpenMP, WinThreads, Pthreads. + +Packaging: +- Package for Windows installs IA-32 and EM64T bits. +- Package for Linux installs IA-32, EM64T and IPF bits. +- Package for Mac OS* X installs IA-32 bits. +- All packages support Intel(R) software setup assistant (ISSA) and + install-time FLEXlm license checking. +- ISSA support allows license file to be specified directly in case of + no Internet connection or problems with IRC or serial #s. +- Linux installer allows root or non-root, RPM or non-RPM installs. +- FLEXlm license servers (for those who need floating/counted licenses) + are provided separately on Intel(R) Premier. + +------------------------------------------------------------------------ +Intel, the Intel logo, Xeon, Intel Xeon Phi, and Cilk are registered +trademarks or trademarks of Intel Corporation or its subsidiaries in +the United States and other countries. + +* Other names and brands may be claimed as the property of others. diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/Doxyfile b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/Doxyfile new file mode 100644 index 00000000..3c7727f8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/Doxyfile @@ -0,0 +1,1325 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "Intel(R) Threading Building Blocks Doxygen Documentation" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = "version 4.2.3" + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = INTERNAL + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = include/ src/tbb/ + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = NO + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = doc/copyright_brand_disclaimer_doxygen.txt + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = TBB_PREVIEW_FLOW_GRAPH_FEATURES \ + TBB_PREVIEW_FLOW_GRAPH_NODES \ + __TBB_PREVIEW_OPENCL_NODE \ + __TBB_CPP11_RVALUE_REF_PRESENT \ + __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT \ + __TBB_IMPLICIT_MOVE_PRESENT \ + __TBB_EXCEPTION_PTR_PRESENT \ + __TBB_STATIC_ASSERT_PRESENT \ + __TBB_CPP11_TUPLE_PRESENT \ + __TBB_INITIALIZER_LISTS_PRESENT \ + __TBB_CONSTEXPR_PRESENT \ + __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT \ + __TBB_NOEXCEPT_PRESENT \ + __TBB_CPP11_STD_BEGIN_END_PRESENT \ + __TBB_CPP11_AUTO_PRESENT \ + __TBB_CPP11_DECLTYPE_PRESENT \ + __TBB_CPP11_LAMBDAS_PRESENT \ + __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT \ + __TBB_OVERRIDE_PRESENT \ + __TBB_ALIGNAS_PRESENT \ + __TBB_CPP11_TEMPLATE_ALIASES_PRESENT \ + __TBB_FLOW_GRAPH_CPP11_FEATURES \ + __TBB_PREVIEW_STREAMING_NODE + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = svg + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = YES + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 200 + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = YES diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/LICENSE b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/Makefile b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/Makefile new file mode 100644 index 00000000..f0641893 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/Makefile @@ -0,0 +1,75 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +tbb_root?=. +cfg?=release +include $(tbb_root)/build/common.inc +.PHONY: default all tbb tbbmalloc tbbproxy test examples + +#workaround for non-depend targets tbb and tbbmalloc which both depend on version_string.ver +#According to documentation, recursively invoked make commands can process their targets in parallel +.NOTPARALLEL: tbb tbbmalloc tbbproxy + +default: tbb tbbmalloc $(if $(use_proxy),tbbproxy) + +all: tbb tbbmalloc tbbproxy test examples + +tbb: mkdir + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbb cfg=release + +tbbmalloc: mkdir + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=release malloc + +tbbproxy: mkdir + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbproxy cfg=release tbbproxy + +tbbbind: mkdir + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbbind cfg=release tbbbind + +test: tbb tbbmalloc $(if $(use_proxy),tbbproxy) + -$(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=release malloc_test + -$(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.test cfg=release + +rml: mkdir + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.rml cfg=release + +examples: tbb tbbmalloc + $(MAKE) -C examples -r -f Makefile tbb_root=.. release test + +python: tbb + $(MAKE) -C "$(work_dir)_release" -rf $(tbb_root)/python/Makefile install + +doxygen: + doxygen Doxyfile + +.PHONY: clean clean_examples mkdir info + +clean: clean_examples + $(shell $(RM) $(work_dir)_release$(SLASH)*.* >$(NUL) 2>$(NUL)) + $(shell $(RD) $(work_dir)_release >$(NUL) 2>$(NUL)) + @echo clean done + +clean_examples: + $(shell $(MAKE) -s -i -r -C examples -f Makefile tbb_root=.. clean >$(NUL) 2>$(NUL)) + +mkdir: + $(shell $(MD) "$(work_dir)_release" >$(NUL) 2>$(NUL)) + @echo Created the $(work_dir)_release directory + +info: + @echo OS: $(tbb_os) + @echo arch=$(arch) + @echo compiler=$(compiler) + @echo runtime=$(runtime) + @echo tbb_build_prefix=$(tbb_build_prefix) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/README b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/README new file mode 100644 index 00000000..fcc87af0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/README @@ -0,0 +1,11 @@ +Intel(R) Threading Building Blocks - README + +See index.html for directions and documentation. + +If source is present (./Makefile and src/ directories), +type 'gmake' in this directory to build and test. + +See examples/index.html for runnable examples and directions. + +See http://threadingbuildingblocks.org for full documentation +and software information. diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/README.md b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/README.md new file mode 100644 index 00000000..15fc3f5e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/README.md @@ -0,0 +1,33 @@ +# Threading Building Blocks 2020 +[![Stable release](https://img.shields.io/badge/version-2020.3-green.svg)](https://github.com/intel/tbb/releases/tag/v2020.3) +[![Apache License Version 2.0](https://img.shields.io/badge/license-Apache_2.0-green.svg)](LICENSE) + +Threading Building Blocks (TBB) lets you easily write parallel C++ programs that take +full advantage of multicore performance, that are portable, composable and have future-proof scalability. + +## Release Information +Here are the latest [Changes](CHANGES) and [Release Notes](doc/Release_Notes.txt) (contains system requirements and known issues). + +Since [2018 U5](https://github.com/intel/tbb/releases/tag/2018_U5) TBB binary packages include [Parallel STL](https://github.com/intel/parallelstl) as a high-level component. + +## Documentation +* TBB [tutorial](https://software.intel.com/en-us/tbb-tutorial) +* TBB general documentation: [stable](https://software.intel.com/en-us/tbb-documentation). For latest documentation please refer to the [latest](https://github.com/intel/tbb/releases/latest) release assets. + +## Support +Please report issues and suggestions via +[GitHub issues](https://github.com/intel/tbb/issues) or start a topic on the +[TBB forum](http://software.intel.com/en-us/forums/intel-threading-building-blocks/). + +## How to Contribute +To contribute to TBB, please open a GitHub pull request (preferred) or send us a patch by e-mail. +Threading Building Blocks is licensed under [Apache License, Version 2.0](LICENSE). +By its terms, contributions submitted to the project are also done under that license. + +## Engineering team contacts +* [E-mail us.](mailto:inteltbbdevelopers@intel.com) + +------------------------------------------------------------------------ +Intel and the Intel logo are trademarks of Intel Corporation or its subsidiaries in the U.S. and/or other countries. + +\* Other names and brands may be claimed as the property of others. diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/STAN_CHANGES b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/STAN_CHANGES new file mode 100644 index 00000000..8de7574b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/STAN_CHANGES @@ -0,0 +1,4 @@ +This file documents changes done for the stan-math project + +- drop -g flag from makefiles for release mode builds to decrease size of binaries +- Add `tbb::` to line 252 of `task.h` to fix a build failure with gcc 13. This was done upstream in https://github.com/oneapi-src/oneTBB/pull/833 diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/AIX.gcc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/AIX.gcc.inc new file mode 100644 index 00000000..2f45d739 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/AIX.gcc.inc @@ -0,0 +1,71 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +DYLIB_KEY = -shared +LIBDL = -ldl + +CPLUS = g++ +CONLY = gcc +LIB_LINK_FLAGS = -shared +LIBS = -lpthread -ldl +C_FLAGS = $(CPLUS_FLAGS) -x c + +ifeq ($(cfg), release) + CPLUS_FLAGS = -O2 -DUSE_PTHREAD -pthread +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -DTBB_USE_DEBUG -g -O0 -DUSE_PTHREAD -pthread +endif + +ASM= +ASM_FLAGS= + +TBB_ASM.OBJ= + +ifeq (powerpc,$(arch)) + CPLUS_FLAGS += -maix64 -Wl,-G + LIB_LINK_FLAGS += -maix64 -Wl,-b64 -Wl,-brtl -Wl,-G +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ + +ASSEMBLY_SOURCE=ibm_aix51 +ifeq (powerpc,$(arch)) + TBB_ASM.OBJ = atomic_support.o +endif + +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/AIX.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/AIX.inc new file mode 100644 index 00000000..e02a6d31 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/AIX.inc @@ -0,0 +1,62 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifndef arch + arch:=$(shell uname -p) + export arch +endif + +ifndef runtime + gcc_version:=$(shell gcc -dumpfullversion -dumpversion) + os_version:=$(shell uname -r) + os_kernel_version:=$(shell uname -r | sed -e 's/-.*$$//') + export runtime:=cc$(gcc_version)_kernel$(os_kernel_version) +endif + +native_compiler := gcc +export compiler ?= gcc +debugger ?= gdb + +CMD=$(SHELL) -c +CWD=$(shell pwd) +RM?=rm -f +RD?=rmdir +MD?=mkdir -p +NUL= /dev/null +SLASH=/ +MAKE_VERSIONS=sh $(tbb_root)/build/version_info_aix.sh $(VERSION_FLAGS) >version_string.ver +MAKE_TBBVARS=sh $(tbb_root)/build/generate_tbbvars.sh + +ifdef LIBPATH + export LIBPATH := .:$(LIBPATH) +else + export LIBPATH := . +endif + +####### Build settings ######################################################## + +OBJ = o +DLL = so + +TBB.LST = +TBB.DEF = +TBB.DLL = libtbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +TBB.LIB = $(TBB.DLL) +LINK_TBB.LIB = $(TBB.LIB) + +MALLOC.DLL = libtbbmalloc$(DEBUG_SUFFIX).$(DLL) +MALLOC.LIB = $(MALLOC.DLL) +LINK_MALLOC.LIB = $(MALLOC.LIB) + +TEST_LAUNCHER=sh $(tbb_root)/build/test_launcher.sh $(largs) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/BSD.clang.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/BSD.clang.inc new file mode 100644 index 00000000..cfcd139a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/BSD.clang.inc @@ -0,0 +1,106 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +TEST_WARNING_KEY = -Wextra -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor +WARNING_SUPPRESS = -Wno-parentheses -Wno-non-virtual-dtor -Wno-dangling-else +DYLIB_KEY = -shared +EXPORT_KEY = -Wl,--version-script, +LIBDL = + +CPLUS = clang++ +CONLY = clang +LIB_LINK_FLAGS = $(DYLIB_KEY) -Wl,-soname=$(BUILDING_LIBRARY) +LIBS += -lpthread +LINK_FLAGS = -Wl,-rpath-link=. -Wl,-rpath=. -rdynamic +C_FLAGS = $(CPLUS_FLAGS) + +ifeq ($(cfg), release) + CPLUS_FLAGS = $(ITT_NOTIFY) -O2 -DUSE_PTHREAD +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -DTBB_USE_DEBUG $(ITT_NOTIFY) -g -O0 -DUSE_PTHREAD +endif + +ifneq (,$(stdlib)) + CPLUS_FLAGS += -stdlib=$(stdlib) + LIB_LINK_FLAGS += -stdlib=$(stdlib) +endif + +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ifeq (intel64,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m32 -march=pentium4 + LIB_LINK_FLAGS += -m32 +endif + +ifeq (ppc64,$(arch)) + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ppc32,$(arch)) + CPLUS_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +endif + +ifeq (bg,$(arch)) + CPLUS = bgclang++ + CONLY = bgclang +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASM = as +ifeq (intel64,$(arch)) + ASM_FLAGS += --64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += --32 +endif +ifeq ($(cfg),debug) + ASM_FLAGS += -g +endif + +ASSEMBLY_SOURCE=$(arch)-gas +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/BSD.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/BSD.inc new file mode 100644 index 00000000..e5ea784d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/BSD.inc @@ -0,0 +1,70 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifndef arch + ifeq ($(shell uname -m),i386) + export arch:=ia32 + endif + ifeq ($(shell uname -m),ia64) + export arch:=ia64 + endif + ifeq ($(shell uname -m),amd64) + export arch:=intel64 + endif +endif + +ifndef runtime + clang_version:=$(shell clang --version | sed -n "1s/.*version \(.*[0-9]\) .*/\1/p") + os_version:=$(shell uname -r) + os_kernel_version:=$(shell uname -r | sed -e 's/-.*$$//') + export runtime:=cc$(clang_version)_kernel$(os_kernel_version) +endif + +native_compiler := clang +export compiler ?= clang +debugger ?= gdb + +CMD=$(SHELL) -c +CWD=$(shell pwd) +RM?=rm -f +RD?=rmdir +MD?=mkdir -p +NUL= /dev/null +SLASH=/ +MAKE_VERSIONS=sh $(tbb_root)/build/version_info_linux.sh $(VERSION_FLAGS) >version_string.ver +MAKE_TBBVARS=sh $(tbb_root)/build/generate_tbbvars.sh + +ifdef LD_LIBRARY_PATH + export LD_LIBRARY_PATH := .:$(LD_LIBRARY_PATH) +else + export LD_LIBRARY_PATH := . +endif + +####### Build settings ######################################################## + +OBJ = o +DLL = so +LIBEXT=so + +TBB.LST = +TBB.DEF = +TBB.DLL = libtbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +TBB.LIB = $(TBB.DLL) +LINK_TBB.LIB = $(TBB.LIB) + +MALLOC.DLL = libtbbmalloc$(DEBUG_SUFFIX).$(DLL) +MALLOC.LIB = $(MALLOC.DLL) +LINK_MALLOC.LIB = $(MALLOC.LIB) + +TEST_LAUNCHER=sh $(tbb_root)/build/test_launcher.sh $(largs) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.clang.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.clang.inc new file mode 100644 index 00000000..f4cdf128 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.clang.inc @@ -0,0 +1,17 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include $(tbb_root)/build/BSD.clang.inc + +LIBS += -lrt diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.gcc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.gcc.inc new file mode 100644 index 00000000..dbf6542a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.gcc.inc @@ -0,0 +1,89 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +DYLIB_KEY = -shared +WARNING_SUPPRESS = -Wno-parentheses + +CPLUS = g++ +CONLY = gcc +LIB_LINK_FLAGS = -shared +LIBS = -lpthread +C_FLAGS = $(CPLUS_FLAGS) + +# gcc 6.0 and later have -flifetime-dse option that controls +# elimination of stores done outside the object lifetime +ifneq (,$(shell gcc -dumpfullversion -dumpversion | egrep "^([6-9]|1[0-9])")) + # keep pre-contruction stores for zero initialization + DSE_KEY = -flifetime-dse=1 +endif + +ifeq ($(cfg), release) + CPLUS_FLAGS = -O2 -DUSE_PTHREAD +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -DTBB_USE_DEBUG -g -O0 -DUSE_PTHREAD +endif + +ASM= +ASM_FLAGS= + +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ifeq (ia64,$(arch)) +# Position-independent code (PIC) is a must on IA-64 architecture, even for regular (not shared) executables + CPLUS_FLAGS += $(PIC_KEY) +endif + +ifeq (intel64,$(arch)) + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + CPLUS_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASSEMBLY_SOURCE=$(arch)-gas +ifeq (ia64,$(arch)) + ASM=as + TBB_ASM.OBJ = atomic_support.o lock_byte.o log2.o pause.o + MALLOC_ASM.OBJ = atomic_support.o lock_byte.o pause.o +endif +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.inc new file mode 100644 index 00000000..8b85bf02 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/FreeBSD.inc @@ -0,0 +1,15 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include $(tbb_root)/build/BSD.inc diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.rml b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.rml new file mode 100644 index 00000000..fc0cb774 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.rml @@ -0,0 +1,169 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# TODO: investigate why version_string.ver is not complete when $(RML_SERVER.OBJ) is being compiled. +.NOTPARALLEL: + +tbb_root ?= $(TBBROOT) +BUILDING_PHASE=1 +TEST_RESOURCE = $(RML.RES) +include $(tbb_root)/build/common.inc +DEBUG_SUFFIX=$(findstring _debug,_$(cfg)) + +ifeq (android,$(target)) +$(error "RML is not supported on Android") +endif + +# default target +default_rml: rml rml_test + +RML_ROOT ?= $(tbb_root)/src/rml +RML_SERVER_ROOT = $(RML_ROOT)/server + +VPATH = $(tbb_root)/src/tbb $(tbb_root)/src/tbb/$(ASSEMBLY_SOURCE) +VPATH += $(RML_ROOT)/server $(RML_ROOT)/client $(RML_ROOT)/test $(tbb_root)/src/test + +include $(tbb_root)/build/common_rules.inc + +#-------------------------------------------------------------------------- +# Define rules for making the RML server shared library and client objects. +#-------------------------------------------------------------------------- + +# Object files that make up RML server +RML_SERVER.OBJ = rml_server.$(OBJ) + +# Object files that RML clients need +RML_TBB_CLIENT.OBJ ?= rml_tbb.$(OBJ) dynamic_link_rml.$(OBJ) +RML_OMP_CLIENT.OBJ ?= rml_omp.$(OBJ) omp_dynamic_link.$(OBJ) + +RML.OBJ = $(RML_SERVER.OBJ) $(RML_TBB_CLIENT.OBJ) $(RML_OMP_CLIENT.OBJ) +ifeq (windows,$(tbb_os)) +RML_ASM.OBJ = $(if $(findstring intel64,$(arch)),$(TBB_ASM.OBJ)) +endif +ifeq (linux,$(tbb_os)) +RML_ASM.OBJ = $(if $(findstring ia64,$(arch)),$(TBB_ASM.OBJ)) +endif + +RML_TBB_DEP= cache_aligned_allocator_rml.$(OBJ) dynamic_link_rml.$(OBJ) concurrent_vector_rml.$(OBJ) semaphore_rml.$(OBJ) tbb_misc_rml.$(OBJ) tbb_misc_ex_rml.$(OBJ) +TBB_DEP_NON_RML_TEST?= cache_aligned_allocator_rml.$(OBJ) dynamic_link_rml.$(OBJ) $(RML_ASM.OBJ) tbb_misc_rml.$(OBJ) tbb_misc_ex_rml.$(OBJ) +ifeq ($(cfg),debug) +RML_TBB_DEP+= spin_mutex_rml.$(OBJ) +TBB_DEP_RML_TEST?= $(RML_ASM.OBJ) tbb_misc_rml.$(OBJ) + +ifeq (windows icl,$(tbb_os) $(compiler_name)) +# Some versions of ICC link to the wrong version of the vc runtime +# libcpmtd.lib should be used instead of libcpmt.lib +LIB_LINK_FLAGS += /nodefaultlib:libcpmt.lib +endif + +else +TBB_DEP_RML_TEST?= $(RML_ASM.OBJ) +endif +LIBS += $(LIBDL) + +INCLUDES += $(INCLUDE_KEY)$(RML_ROOT)/include $(INCLUDE_KEY). +T_INCLUDES = $(INCLUDES) $(INCLUDE_KEY)$(tbb_root)/src/test $(INCLUDE_KEY)$(RML_SERVER_ROOT) + +ifeq ($(rml_wcrm),1) +CPLUS_FLAGS+=/DRML_USE_WCRM +endif + +# Suppress superfluous warnings for RML compilation +R_CPLUS_FLAGS = $(subst DO_ITT_NOTIFY,DO_ITT_NOTIFY=0,$(CPLUS_FLAGS)) $(WARNING_SUPPRESS) \ + $(DEFINE_KEY)TBB_USE_THREADING_TOOLS=0 $(DEFINE_KEY)__TBB_RML_STATIC=1 $(DEFINE_KEY)__TBB_NO_IMPLICIT_LINKAGE=1 + +%.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(R_CPLUS_FLAGS) $(PIC_KEY) $(DSE_KEY) $(INCLUDES) $< + +ifeq (linux,$(tbb_os)) +omp_dynamic_link.$(OBJ): CPLUS_FLAGS+=-fno-exceptions +endif + +tbb_misc_rml.$(OBJ) $(RML_SERVER.OBJ): version_string.ver + +RML_TEST.OBJ = test_job_automaton.$(OBJ) test_thread_monitor.$(OBJ) test_rml_tbb.$(OBJ) test_rml_omp.$(OBJ) test_rml_mixed.$(OBJ) + +$(RML_TBB_DEP): %_rml.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(OUTPUTOBJ_KEY)$@ $(R_CPLUS_FLAGS) $(PIC_KEY) $(DSE_KEY) $(INCLUDES) $< + +$(RML_TEST.OBJ): %.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(R_CPLUS_FLAGS) $(PIC_KEY) $(T_INCLUDES) $< + +ifneq (,$(RML.DEF)) +rml.def: $(RML.DEF) + $(CPLUS) $(PREPROC_ONLY) $< $(CPLUS_FLAGS) $(INCLUDES) > $@ + +LIB_LINK_FLAGS += $(EXPORT_KEY)rml.def +$(RML.DLL): rml.def +endif + +$(RML.DLL): CPLUS_FLAGS += $(SDL_FLAGS) +$(RML.DLL): BUILDING_LIBRARY = $(RML.DLL) +$(RML.DLL): $(RML_TBB_DEP) $(RML_SERVER.OBJ) $(RML.RES) $(RML_NO_VERSION.DLL) $(RML_ASM.OBJ) + $(LIB_LINK_CMD) $(LIB_OUTPUT_KEY)$(RML.DLL) $(RML_SERVER.OBJ) $(RML_TBB_DEP) $(RML_ASM.OBJ) $(RML.RES) $(LIB_LINK_LIBS) $(LIB_LINK_FLAGS) + +ifneq (,$(RML_NO_VERSION.DLL)) +$(RML_NO_VERSION.DLL): + echo "INPUT ($(RML.DLL))" > $(RML_NO_VERSION.DLL) +endif + +rml: $(RML.DLL) $(RML_TBB_CLIENT.OBJ) $(RML_OMP_CLIENT.OBJ) + +#------------------------------------------------------ +# End of rules for making the RML server shared library +#------------------------------------------------------ + +#------------------------------------------------------ +# Define rules for making the RML unit tests +#------------------------------------------------------ + +add_debug=$(basename $(1))_debug$(suffix $(1)) +cross_suffix=$(if $(crosstest),$(if $(DEBUG_SUFFIX),$(subst _debug,,$(1)),$(call add_debug,$(1))),$(1)) + +RML_TESTS = test_job_automaton.$(TEST_EXT) test_thread_monitor.$(TEST_EXT) +RML_CUSTOM_TESTS = test_rml_tbb.$(TEST_EXT) test_rml_omp.$(TEST_EXT) test_rml_mixed.$(TEST_EXT) test_rml_omp_c_linkage.$(TEST_EXT) + +test_rml_tbb.$(TEST_EXT): test_rml_tbb.$(OBJ) $(RML_TBB_CLIENT.OBJ) $(TBB_DEP_RML_TEST) + $(CPLUS) $(OUTPUT_KEY)$@ $(CPLUS_FLAGS) test_rml_tbb.$(OBJ) $(RML_TBB_CLIENT.OBJ) $(TBB_DEP_RML_TEST) $(LIBS) $(LINK_FLAGS) + +test_rml_omp.$(TEST_EXT): test_rml_omp.$(OBJ) $(RML_OMP_CLIENT.OBJ) $(TBB_DEP_NON_RML_TEST) + $(CPLUS) $(OUTPUT_KEY)$@ $(CPLUS_FLAGS) test_rml_omp.$(OBJ) $(RML_OMP_CLIENT.OBJ) $(TBB_DEP_NON_RML_TEST) $(LIBS) $(LINK_FLAGS) + +test_rml_mixed.$(TEST_EXT): test_rml_mixed.$(OBJ) $(RML_TBB_CLIENT.OBJ) $(RML_OMP_CLIENT.OBJ) $(TBB_DEP_RML_TEST) + $(CPLUS) $(OUTPUT_KEY)$@ $(CPLUS_FLAGS) test_rml_mixed.$(OBJ) $(RML_TBB_CLIENT.OBJ) $(RML_OMP_CLIENT.OBJ) $(TBB_DEP_RML_TEST) $(LIBS) $(LINK_FLAGS) + +rml_omp_stub.$(OBJ): rml_omp_stub.cpp + $(CPLUS) $(COMPILE_ONLY) $(M_CPLUS_FLAGS) $(WARNING_SUPPRESS) $(T_INCLUDES) $(PIC_KEY) $< + +test_rml_omp_c_linkage.$(TEST_EXT): test_rml_omp_c_linkage.$(OBJ) rml_omp_stub.$(OBJ) omp_dynamic_link.$(OBJ) + $(CONLY) $(C_FLAGS) $(OUTPUT_KEY)$@ test_rml_omp_c_linkage.$(OBJ) rml_omp_stub.$(OBJ) omp_dynamic_link.$(OBJ) $(LIBS) $(LINK_FLAGS) + +$(RML_TESTS): %.$(TEST_EXT): %.$(OBJ) $(TBB_DEP_NON_RML_TEST) + $(CPLUS) $(OUTPUT_KEY)$@ $(CPLUS_FLAGS) $< $(TBB_DEP_NON_RML_TEST) $(LIBS) $(LINK_FLAGS) + +### run_cmd is usually empty +rml_test: $(call cross_suffix,$(RML.DLL)) $(TEST_PREREQUISITE) $(RML_TESTS) $(RML_CUSTOM_TESTS) + $(run_cmd) ./test_job_automaton.$(TEST_EXT) $(args) + $(run_cmd) ./test_thread_monitor.$(TEST_EXT) $(args) + $(run_cmd) ./test_rml_tbb.$(TEST_EXT) $(args) + $(run_cmd) ./test_rml_omp.$(TEST_EXT) $(args) + $(run_cmd) ./test_rml_mixed.$(TEST_EXT) $(args) + $(run_cmd) ./test_rml_omp_c_linkage.$(TEST_EXT) $(args) + +#------------------------------------------------------ +# End of rules for making the TBBMalloc unit tests +#------------------------------------------------------ + +# Include automatically generated dependencies +-include *.d diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbb b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbb new file mode 100644 index 00000000..15568998 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbb @@ -0,0 +1,114 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#------------------------------------------------------------------------------ +# Define rules for making the TBB shared library. +#------------------------------------------------------------------------------ + +tbb_root ?= "$(TBBROOT)" +BUILDING_PHASE=1 +include $(tbb_root)/build/common.inc +CPLUS_FLAGS += $(SDL_FLAGS) +DEBUG_SUFFIX=$(findstring _debug,_$(cfg)) + +#------------------------------------------------------------ +# Define static pattern rules dealing with .cpp source files +#------------------------------------------------------------ +$(warning CONFIG: cfg=$(cfg) arch=$(arch) compiler=$(compiler) target=$(target) runtime=$(runtime)) + +default_tbb: $(TBB.DLL) +.PHONY: default_tbb tbbvars clean +.PRECIOUS: %.$(OBJ) + +VPATH = $(tbb_root)/src/tbb/$(ASSEMBLY_SOURCE) $(tbb_root)/src/tbb $(tbb_root)/src/old $(tbb_root)/src/rml/client + +CPLUS_FLAGS += $(PIC_KEY) $(DSE_KEY) $(DEFINE_KEY)__TBB_BUILD=1 + +# Object files (that were compiled from C++ code) that gmake up TBB +TBB_CPLUS.OBJ = concurrent_hash_map.$(OBJ) \ + concurrent_queue.$(OBJ) \ + concurrent_vector.$(OBJ) \ + dynamic_link.$(OBJ) \ + itt_notify.$(OBJ) \ + cache_aligned_allocator.$(OBJ) \ + pipeline.$(OBJ) \ + queuing_mutex.$(OBJ) \ + queuing_rw_mutex.$(OBJ) \ + reader_writer_lock.$(OBJ) \ + spin_rw_mutex.$(OBJ) \ + x86_rtm_rw_mutex.$(OBJ) \ + spin_mutex.$(OBJ) \ + critical_section.$(OBJ) \ + mutex.$(OBJ) \ + recursive_mutex.$(OBJ) \ + condition_variable.$(OBJ) \ + tbb_thread.$(OBJ) \ + concurrent_monitor.$(OBJ) \ + semaphore.$(OBJ) \ + private_server.$(OBJ) \ + rml_tbb.$(OBJ) \ + tbb_misc.$(OBJ) \ + tbb_misc_ex.$(OBJ) \ + task.$(OBJ) \ + task_group_context.$(OBJ) \ + governor.$(OBJ) \ + market.$(OBJ) \ + arena.$(OBJ) \ + scheduler.$(OBJ) \ + observer_proxy.$(OBJ) \ + tbb_statistics.$(OBJ) \ + tbb_main.$(OBJ) + +# OLD/Legacy object files for backward binary compatibility +ifeq (,$(findstring $(DEFINE_KEY)TBB_NO_LEGACY,$(CPLUS_FLAGS))) +TBB_CPLUS_OLD.OBJ = \ + concurrent_vector_v2.$(OBJ) \ + concurrent_queue_v2.$(OBJ) \ + spin_rw_mutex_v2.$(OBJ) \ + task_v2.$(OBJ) +endif + +# Object files that gmake up TBB (TBB_ASM.OBJ is platform-specific) +TBB.OBJ = $(TBB_CPLUS.OBJ) $(TBB_CPLUS_OLD.OBJ) $(TBB_ASM.OBJ) + +# Suppress superfluous warnings for TBB compilation +WARNING_KEY += $(WARNING_SUPPRESS) + +include $(tbb_root)/build/common_rules.inc + +ifneq (,$(TBB.DEF)) +tbb.def: $(TBB.DEF) $(TBB.LST) + $(CPLUS) $(PREPROC_ONLY) $< $(CPLUS_FLAGS) $(INCLUDES) > $@ + +LIB_LINK_FLAGS += $(EXPORT_KEY)tbb.def +$(TBB.DLL): tbb.def +endif + +tbbvars.sh: + $(MAKE_TBBVARS) + +$(TBB.DLL): BUILDING_LIBRARY = $(TBB.DLL) +$(TBB.DLL): $(TBB.OBJ) $(TBB.RES) tbbvars.sh $(TBB_NO_VERSION.DLL) + $(LIB_LINK_CMD) $(LIB_OUTPUT_KEY)$(TBB.DLL) $(TBB.OBJ) $(TBB.RES) $(LIB_LINK_LIBS) $(LIB_LINK_FLAGS) + +ifneq (,$(TBB_NO_VERSION.DLL)) +$(TBB_NO_VERSION.DLL): + echo "INPUT ($(TBB.DLL))" > $(TBB_NO_VERSION.DLL) +endif + +#clean: +# $(RM) *.$(OBJ) *.$(DLL) *.res *.map *.ilk *.pdb *.exp *.manifest *.tmp *.d core core.*[0-9][0-9] *.ver + +# Include automatically generated dependencies +-include *.d diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbbind b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbbind new file mode 100644 index 00000000..821009a3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbbind @@ -0,0 +1,69 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#------------------------------------------------------------------------------ +# Define rules for making the tbbbind shared library. +#------------------------------------------------------------------------------ + +tbb_root ?= "$(TBBROOT)" +BUILDING_PHASE=1 +include $(tbb_root)/build/common.inc +CPLUS_FLAGS += $(SDL_FLAGS) +DEBUG_SUFFIX=$(findstring _debug,_$(cfg)) + +#------------------------------------------------------------ +# Define static pattern rules dealing with .cpp source files +#------------------------------------------------------------ +$(warning CONFIG: cfg=$(cfg) arch=$(arch) compiler=$(compiler) target=$(target) runtime=$(runtime)) + +.PHONY: tbbbind +.PRECIOUS: %.$(OBJ) + +VPATH = $(tbb_root)/src/tbb/$(ASSEMBLY_SOURCE) $(tbb_root)/src/tbb $(tbb_root)/src/old $(tbb_root)/src/rml/client + +CPLUS_FLAGS += $(PIC_KEY) $(DSE_KEY) $(DEFINE_KEY)__TBBBIND_BUILD=1 + +# Suppress superfluous warnings for tbbbind compilation +WARNING_KEY += $(WARNING_SUPPRESS) + +include $(tbb_root)/build/common_rules.inc + +TBBBIND.OBJ = tbb_bind.$(OBJ) + +ifneq (,$(TBBBIND.DEF)) +tbbbind.def: $(TBBBIND.DEF) + $(CPLUS) $(PREPROC_ONLY) $< $(CPLUS_FLAGS) $(INCLUDES) > $@ + +LIB_LINK_FLAGS += $(EXPORT_KEY)tbbbind.def +$(TBBBIND.DLL): tbbbind.def +endif + +ifneq (,$(TBBBIND.DLL)) +$(TBBBIND.DLL): BUILDING_LIBRARY = $(TBBBIND.DLL) +$(TBBBIND.DLL): $(TBBBIND.OBJ) $(TBBBIND_NO_VERSION.DLL) + $(LIB_LINK_CMD) $(LIB_OUTPUT_KEY)$(TBBBIND.DLL) $(TBBBIND.OBJ) $(HWLOC.LIB) $(LIB_LINK_FLAGS) +endif + +ifneq (,$(TBBBIND_NO_VERSION.DLL)) +$(TBBBIND_NO_VERSION.DLL): + echo "INPUT ($(TBBBIND.DLL))" > $(TBBBIND_NO_VERSION.DLL) +endif + +tbbbind: $(TBBBIND.DLL) + +#clean: +# $(RM) *.$(OBJ) *.$(DLL) *.res *.map *.ilk *.pdb *.exp *.manifest *.tmp *.d core core.*[0-9][0-9] *.ver + +# Include automatically generated dependencies +-include *.d diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbmalloc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbmalloc new file mode 100644 index 00000000..4ba504f8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbmalloc @@ -0,0 +1,256 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# default target +default_malloc: malloc malloc_test + +tbb_root ?= $(TBBROOT) +BUILDING_PHASE=1 +TEST_RESOURCE = $(MALLOC.RES) +TESTFILE=tbbmalloc +include $(tbb_root)/build/common.inc +DEBUG_SUFFIX=$(findstring _debug,$(call cross_cfg,_$(cfg))) + +MALLOC_ROOT ?= $(tbb_root)/src/tbbmalloc +MALLOC_SOURCE_ROOT ?= $(MALLOC_ROOT) + +VPATH = $(tbb_root)/src/tbb/$(ASSEMBLY_SOURCE) $(tbb_root)/src/tbb $(tbb_root)/src/test +VPATH += $(MALLOC_ROOT) $(MALLOC_SOURCE_ROOT) + +CPLUS_FLAGS += $(if $(crosstest),$(DEFINE_KEY)__TBBMALLOC_NO_IMPLICIT_LINKAGE=1) + +TEST_SUFFIXES=proxy +TEST_PREREQUISITE+=$(MALLOC.LIB) +LINK_FILES+=$(LINK_MALLOC.LIB) +include $(tbb_root)/build/common_rules.inc + +ORIG_CPLUS_FLAGS:=$(CPLUS_FLAGS) +ORIG_INCLUDES:=$(INCLUDES) +ORIG_LINK_MALLOC.LIB:=$(LINK_MALLOC.LIB) + +#------------------------------------------------------ +# Define rules for making the TBBMalloc shared library. +#------------------------------------------------------ + +# Object files that make up TBBMalloc +MALLOC_CPLUS.OBJ = backend.$(OBJ) large_objects.$(OBJ) backref.$(OBJ) tbbmalloc.$(OBJ) +MALLOC.OBJ := $(MALLOC_CPLUS.OBJ) $(MALLOC_ASM.OBJ) itt_notify_malloc.$(OBJ) frontend.$(OBJ) +PROXY.OBJ := proxy.$(OBJ) tbb_function_replacement.$(OBJ) +M_CPLUS_FLAGS += $(DEFINE_KEY)__TBBMALLOC_BUILD=1 +M_INCLUDES := $(INCLUDES) $(INCLUDE_KEY)$(MALLOC_ROOT) $(INCLUDE_KEY)$(MALLOC_SOURCE_ROOT) + +# Suppress superfluous warnings for TBBMalloc compilation +$(MALLOC.OBJ): M_CPLUS_FLAGS := $(subst $(WARNING_KEY),,$(M_CPLUS_FLAGS)) $(WARNING_SUPPRESS) +# Suppress superfluous warnings for TBBMalloc proxy compilation +$(PROXY.OBJ): CPLUS_FLAGS += $(WARNING_SUPPRESS) + +frontend.$(OBJ): frontend.cpp version_string.ver + $(CPLUS) $(COMPILE_ONLY) $(M_CPLUS_FLAGS) $(PIC_KEY) $(DSE_KEY) $(M_INCLUDES) $(INCLUDE_KEY). $< + +$(PROXY.OBJ): %.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(CPLUS_FLAGS) $(PIC_KEY) $(DSE_KEY) $(DEFINE_KEY)__TBBMALLOC_BUILD=1 $(M_INCLUDES) $< + +$(MALLOC_CPLUS.OBJ): %.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(M_CPLUS_FLAGS) $(PIC_KEY) $(DSE_KEY) $(M_INCLUDES) $< + +itt_notify_malloc.$(OBJ): itt_notify.cpp + $(CPLUS) $(COMPILE_ONLY) $(M_CPLUS_FLAGS) $(PIC_KEY) $(DSE_KEY) $(OUTPUTOBJ_KEY)$@ $(INCLUDES) $< + +MALLOC_LINK_FLAGS = $(LIB_LINK_FLAGS) +PROXY_LINK_FLAGS = $(LIB_LINK_FLAGS) + +ifneq (,$(MALLOC.DEF)) +tbbmalloc.def: $(MALLOC.DEF) + $(CPLUS) $(PREPROC_ONLY) $< $(M_CPLUS_FLAGS) $(WARNING_SUPPRESS) $(INCLUDES) > $@ + +MALLOC_LINK_FLAGS += $(EXPORT_KEY)tbbmalloc.def +$(MALLOC.DLL): tbbmalloc.def +endif + +$(MALLOC.DLL) $(MALLOCPROXY.DLL): CPLUS_FLAGS += $(SDL_FLAGS) +$(MALLOC.DLL) $(MALLOCPROXY.DLL): M_CPLUS_FLAGS += $(SDL_FLAGS) +$(MALLOC.DLL): BUILDING_LIBRARY = $(MALLOC.DLL) +$(MALLOC.DLL): $(MALLOC.OBJ) $(MALLOC.RES) $(MALLOC_NO_VERSION.DLL) + $(subst $(CPLUS),$(CONLY),$(LIB_LINK_CMD)) $(LIB_OUTPUT_KEY)$(MALLOC.DLL) $(MALLOC.OBJ) $(MALLOC.RES) $(LIB_LINK_LIBS) $(MALLOC_LINK_FLAGS) + +ifneq (,$(MALLOCPROXY.DEF)) +tbbmallocproxy.def: $(MALLOCPROXY.DEF) + $(CPLUS) $(PREPROC_ONLY) $< $(CPLUS_FLAGS) $(WARNING_SUPPRESS) $(INCLUDES) > $@ + +PROXY_LINK_FLAGS += $(EXPORT_KEY)tbbmallocproxy.def +$(MALLOCPROXY.DLL): tbbmallocproxy.def +endif + +ifneq (,$(MALLOCPROXY.DLL)) +$(MALLOCPROXY.DLL): BUILDING_LIBRARY = $(MALLOCPROXY.DLL) +$(MALLOCPROXY.DLL): $(PROXY.OBJ) $(MALLOCPROXY_NO_VERSION.DLL) $(MALLOC.DLL) $(MALLOC.RES) + $(LIB_LINK_CMD) $(LIB_OUTPUT_KEY)$(MALLOCPROXY.DLL) $(PROXY.OBJ) $(MALLOC.RES) $(LIB_LINK_LIBS) $(LINK_MALLOC.LIB) $(PROXY_LINK_FLAGS) +endif + +ifneq (,$(MALLOC_NO_VERSION.DLL)) +$(MALLOC_NO_VERSION.DLL): + echo "INPUT ($(MALLOC.DLL))" > $(MALLOC_NO_VERSION.DLL) +endif + +ifneq (,$(MALLOCPROXY_NO_VERSION.DLL)) +$(MALLOCPROXY_NO_VERSION.DLL): + echo "INPUT ($(MALLOCPROXY.DLL))" > $(MALLOCPROXY_NO_VERSION.DLL) +endif + +malloc: $(MALLOC.DLL) $(MALLOCPROXY.DLL) + +malloc_dll: $(MALLOC.DLL) + +malloc_proxy_dll: $(MALLOCPROXY.DLL) + +.PHONY: malloc malloc_dll malloc_proxy_dll + +#------------------------------------------------------ +# End of rules for making the TBBMalloc shared library +#------------------------------------------------------ + +#------------------------------------------------------ +# Define rules for making the TBBMalloc unit tests +#------------------------------------------------------ + +# --------- The list of TBBMalloc unit tests ---------- +MALLOC_TESTS = test_ScalableAllocator.$(TEST_EXT) \ + test_ScalableAllocator_STL.$(TEST_EXT) \ + test_malloc_compliance.$(TEST_EXT) \ + test_malloc_regression.$(TEST_EXT) \ + test_malloc_init_shutdown.$(TEST_EXT) \ + test_malloc_pools.$(TEST_EXT) \ + test_malloc_pure_c.$(TEST_EXT) \ + test_malloc_whitebox.$(TEST_EXT) \ + test_malloc_used_by_lib.$(TEST_EXT) \ + test_malloc_lib_unload.$(TEST_EXT) \ + test_malloc_shutdown_hang.$(TEST_EXT) +ifneq (,$(MALLOCPROXY.DLL)) +MALLOC_TESTS += test_malloc_overload.$(TEST_EXT) \ + test_malloc_overload_proxy.$(TEST_EXT) \ + test_malloc_overload_disable.$(TEST_EXT) \ + test_malloc_atexit.$(TEST_EXT) \ + test_malloc_new_handler.$(TEST_EXT) +endif +# ----------------------------------------------------- + +# ------------ Set test specific variables ------------ +# TODO: implement accurate warning suppression for tests to unify with Makefile.test. +$(MALLOC_TESTS): CPLUS_FLAGS += $(TEST_WARNING_KEY) $(if $(no_exceptions),$(DEFINE_KEY)__TBB_TEST_NO_EXCEPTIONS=1) +$(MALLOC_TESTS): M_CPLUS_FLAGS += $(TEST_WARNING_KEY) $(if $(no_exceptions),$(DEFINE_KEY)__TBB_TEST_NO_EXCEPTIONS=1) +$(MALLOC_TESTS): INCLUDES += $(INCLUDE_TEST_HEADERS) +$(MALLOC_TESTS): M_INCLUDES += $(INCLUDE_TEST_HEADERS) + +ifeq (windows.gcc,$(tbb_os).$(compiler)) +test_malloc_overload.$(TEST_EXT): LIBS += $(MALLOCPROXY.LIB) +endif + +MALLOC_M_CPLUS_TESTS = test_malloc_whitebox.$(TEST_EXT) test_malloc_lib_unload.$(TEST_EXT) \ + test_malloc_used_by_lib.$(TEST_EXT) +MALLOC_NO_LIB_TESTS = test_malloc_whitebox.$(TEST_EXT) test_malloc_lib_unload.$(TEST_EXT) \ + test_malloc_used_by_lib.$(TEST_EXT) test_malloc_overload.$(TEST_EXT) +MALLOC_LINK_PROXY_TESTS = test_malloc_overload_proxy.$(TEST_EXT) test_malloc_new_handler.$(TEST_EXT) +MALLOC_ADD_DLL_TESTS = test_malloc_lib_unload.$(TEST_EXT) test_malloc_used_by_lib.$(TEST_EXT) \ + test_malloc_atexit.$(TEST_EXT) +MALLOC_SUPPRESS_WARNINGS = test_malloc_whitebox.$(TEST_EXT) test_malloc_pure_c.$(TEST_EXT) + +$(MALLOC_SUPPRESS_WARNINGS): WARNING_KEY= +$(MALLOC_SUPPRESS_WARNINGS): TEST_WARNING_KEY= +$(MALLOC_M_CPLUS_TESTS): CPLUS_FLAGS:=$(M_CPLUS_FLAGS) +$(MALLOC_M_CPLUS_TESTS): INCLUDES=$(M_INCLUDES) +$(MALLOC_NO_LIB_TESTS): LINK_MALLOC.LIB= +$(MALLOC_NO_LIB_TESTS): LINK_FLAGS+=$(LIBDL) +$(MALLOC_LINK_PROXY_TESTS): LINK_MALLOC.LIB=$(LINK_MALLOCPROXY.LIB) +ifneq (,$(DYLIB_KEY)) +$(MALLOC_ADD_DLL_TESTS): %.$(TEST_EXT): %_dll.$(DLL) +$(MALLOC_ADD_DLL_TESTS): TEST_LIBS+=$(@:.$(TEST_EXT)=_dll.$(LIBEXT)) +endif + +test_malloc_over%.$(TEST_EXT): CPLUS_FLAGS:=$(subst /MT,/MD,$(M_CPLUS_FLAGS)) +test_malloc_over%.$(TEST_EXT): INCLUDES=$(M_INCLUDES) +test_malloc_overload_proxy.$(TEST_EXT): LINK_FLAGS+=$(LIBDL) + +test_malloc_atexit_dll.$(DLL): CPLUS_FLAGS:=$(subst /MT,/MD,$(M_CPLUS_FLAGS)) +test_malloc_atexit.$(TEST_EXT): CPLUS_FLAGS:=$(subst /MT,/MD,$(M_CPLUS_FLAGS)) +test_malloc_atexit.$(TEST_EXT): LINK_FLAGS+=$(LIBDL) +# on Ubuntu 11.10 linker called with --as-needed, so dependency on libtbbmalloc_proxy +# is not created, and malloc overload via linking with -ltbbmalloc_proxy is not working. +# Overcome with --no-as-needed. +ifeq (linux.gcc,$(tbb_os).$(compiler)) +test_malloc_atexit.$(TEST_EXT): MALLOCPROXY.LIB := -Wl,--no-as-needed $(MALLOCPROXY.LIB) +endif +# The test isn't added to MALLOC_LINK_PROXY_TESTS, because we need both +# tbbmalloc and proxy libs. For platforms other than Android it's enough +# to modify LINK_MALLOC.LIB for TEST_EXT target only. But under Android build +# of DLL and TEST_EXT can be requested independently, so there is no chance +# to set LINK_MALLOC.LIB in TEST_EXT build rule, and affect DLL build. +test_malloc_atexit.$(TEST_EXT): LINK_MALLOC.LIB := $(LINK_MALLOC.LIB) $(LINK_MALLOCPROXY.LIB) +test_malloc_atexit_dll.$(DLL): LINK_MALLOC.LIB := $(LINK_MALLOC.LIB) $(LINK_MALLOCPROXY.LIB) + +test_malloc_whitebox.$(TEST_EXT): $(MALLOC_ASM.OBJ) version_string.ver +test_malloc_whitebox.$(TEST_EXT): INCLUDES+=$(INCLUDE_KEY). +test_malloc_whitebox.$(TEST_EXT): LINK_FILES+=$(MALLOC_ASM.OBJ) + +# Some _dll targets need to restore variables since they are changed by parent +# target-specific rule of its .exe targets +test_malloc_lib_unload_dll.$(DLL): CPLUS_FLAGS=$(ORIG_CPLUS_FLAGS) $(if $(no_exceptions),$(DEFINE_KEY)__TBB_TEST_NO_EXCEPTIONS=1) +test_malloc_lib_unload_dll.$(DLL): INCLUDES=$(ORIG_INCLUDES) $(INCLUDE_TEST_HEADERS) + +test_malloc_used_by_lib_dll.$(DLL): CPLUS_FLAGS:=$(subst /MT,/LD,$(M_CPLUS_FLAGS)) +test_malloc_used_by_lib_dll.$(DLL): LINK_FILES+=$(ORIG_LINK_MALLOC.LIB) +test_malloc_used_by_lib_dll.$(DLL): LIBDL= + +# The test needs both tbb and tbbmalloc. +# For static build LINK_TBB.LIB is resolved in tbb.a static lib name (Linux), which cannot be found (dynamic tbb is used only). +# In order to link properly, have to define LINK_TBB.LIB ourselves except for Windows where linkage with *.lib file expected. +ifdef extra_inc +ifneq ($(tbb_os),windows) +DYNAMIC_TBB_LIB=$(LIBPREF)tbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +endif +endif +test_malloc_shutdown_hang.$(TEST_EXT): LINK_FILES += $(if $(DYNAMIC_TBB_LIB), $(DYNAMIC_TBB_LIB), $(LINK_TBB.LIB)) + +# ----------------------------------------------------- + +# ---- The list of TBBMalloc test running commands ---- +# run_cmd is usually empty +malloc_test: $(MALLOC.DLL) malloc_test_no_depends + +malloc_test_no_depends: $(TEST_PREREQUISITE) $(MALLOC_TESTS) + $(run_cmd) ./test_malloc_pools.$(TEST_EXT) $(args) 1:4 +ifneq (,$(MALLOCPROXY.DLL)) + $(run_cmd) ./test_malloc_atexit.$(TEST_EXT) $(args) + $(run_cmd) $(TEST_LAUNCHER) -l $(MALLOCPROXY.DLL) ./test_malloc_overload.$(TEST_EXT) $(args) + $(run_cmd) $(TEST_LAUNCHER) ./test_malloc_overload_proxy.$(TEST_EXT) $(args) + $(run_cmd) ./test_malloc_overload_disable.$(TEST_EXT) $(args) + $(run_cmd) $(TEST_LAUNCHER) ./test_malloc_new_handler.$(TEST_EXT) $(args) +endif + $(run_cmd) $(TEST_LAUNCHER) ./test_malloc_lib_unload.$(TEST_EXT) $(args) + $(run_cmd) $(TEST_LAUNCHER) ./test_malloc_used_by_lib.$(TEST_EXT) + $(run_cmd) ./test_malloc_whitebox.$(TEST_EXT) $(args) 1:4 + $(run_cmd) $(TEST_LAUNCHER) -u ./test_malloc_compliance.$(TEST_EXT) $(args) 1:4 + $(run_cmd) ./test_ScalableAllocator.$(TEST_EXT) $(args) + $(run_cmd) ./test_ScalableAllocator_STL.$(TEST_EXT) $(args) + $(run_cmd) ./test_malloc_regression.$(TEST_EXT) $(args) + $(run_cmd) ./test_malloc_init_shutdown.$(TEST_EXT) $(args) + $(run_cmd) ./test_malloc_pure_c.$(TEST_EXT) $(args) + $(run_cmd) ./test_malloc_shutdown_hang.$(TEST_EXT) +# ----------------------------------------------------- + +#------------------------------------------------------ +# End of rules for making the TBBMalloc unit tests +#------------------------------------------------------ + +# Include automatically generated dependencies +-include *.d diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbproxy b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbproxy new file mode 100644 index 00000000..54f5e9cd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.tbbproxy @@ -0,0 +1,105 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# default target +default_tbbproxy: tbbproxy tbbproxy_test + +tbb_root ?= $(TBBROOT) +BUILDING_PHASE=1 +include $(tbb_root)/build/common.inc +DEBUG_SUFFIX=$(findstring _debug,_$(cfg)) + +PROXY_ROOT ?= $(tbb_root)/src/tbbproxy +PROXY_SOURCE_ROOT ?= $(PROXY_ROOT) + +VPATH = $(tbb_root)/src/tbb/$(ASSEMBLY_SOURCE) $(tbb_root)/src/tbb $(tbb_root)/src/test +VPATH += $(PROXY_ROOT) $(PROXY_SOURCE_ROOT) + +CPLUS_FLAGS += $(DEFINE_KEY)__TBB_DLL_NAME=$(TBB.DLL) +CPLUS_FLAGS += $(DEFINE_KEY)__TBB_LST=$(TBB.LST) +CPLUS_FLAGS += $(foreach dir,$(VPATH),$(INCLUDE_KEY)$(dir)) +CPLUS_FLAGS += $(PIC_KEY) $(DSE_KEY) + +include $(tbb_root)/build/common_rules.inc + +#------------------------------------------------------ +# Define rules for making the TBB Proxy static library. +#------------------------------------------------------ + +# Object files that make up TBB Proxy +PROXY_CPLUS.OBJ = tbbproxy.$(OBJ) +PROXY_ASM.OBJ = tbbproxy-asm.$(OBJ) +PROXY.OBJ := $(PROXY_CPLUS.OBJ) $(PROXY_ASM.OBJ) + +# Not using intrinsics prevents undesired dependence on ICL libraries (e.g. libirc). +# Not using default libs prevents link issues caused by different CRT versions in tbbproxy and in an app. +$(PROXY.OBJ): CPLUS_FLAGS += $(DEFINE_KEY)ARCH_$(arch) $(DEFINE_KEY)OS_$(tbb_os) $(NOINTRINSIC_KEY) $(NODEFAULTLIB_KEY) + +$(PROXY_CPLUS.OBJ): CPLUS_FLAGS+=$(if $(filter windows.%cl,$(tbb_os).$(compiler)),/Fdtbbproxy$(DEBUG_SUFFIX).pdb) +$(PROXY_CPLUS.OBJ): %.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(CPLUS_FLAGS) $(INCLUDES) $< + +$(PROXY.LIB): $(PROXY.OBJ) + $(AR) $(AR_FLAGS) $(AR_OUTPUT_KEY)$@ $^ + +.PRECIOUS : %.$(ASMEXT) +tbbproxy-asm.$(ASMEXT) : tbbproxy-$(tbb_os).$(ASMEXT) $(TBB.LST) $(TBB-OBJECTS.LST) + $(CPLUS) $(PREPROC_ONLY) $< $(INCLUDES) $(CPLUS_FLAGS) $(DEFINE_KEY)__TBB_BUILD=1 > $@ + +.PHONY: tbbproxy +ifeq (windows,$(tbb_os)) +tbbproxy: $(PROXY.LIB) +else +tbbproxy: +endif + +#------------------------------------------------------ +# End of rules for making the TBB Proxy static library +#------------------------------------------------------ + +#------------------------------------------------------ +# Define rules for making the TBB Proxy unit tests +#------------------------------------------------------ + +add_debug=$(basename $(1))_debug$(suffix $(1)) +cross_suffix=$(if $(crosstest),$(if $(DEBUG_SUFFIX),$(subst _debug,,$(1)),$(call add_debug,$(1))),$(1)) + +PROXY_LIB = $(call cross_suffix,$(PROXY.LIB)) +PROXY_TESTS_SRCS = test_runtime_loader.cpp +PROXY_TESTS_OBJS = $(PROXY_TESTS_SRCS:.cpp=.$(OBJ)) +PROXY_TESTS_EXES = $(PROXY_TESTS_OBJS:.$(OBJ)=.$(TEST_EXT)) + +# Run rules. +.PHONY: tbbproxy_test +ifeq (windows,$(tbb_os)) +tbbproxy_test: $(call cross_suffix,$(PROXY.LIB)) $(TEST_PREREQUISITE) $(PROXY_TESTS_EXES) + $(run_cmd) ./test_runtime_loader.$(TEST_EXT) $(args) +else +tbbproxy_test: +endif + +# Link rules. +$(PROXY_TESTS_EXES): %.$(TEST_EXT): %.$(OBJ) $(PROXY_LIB) + $(CPLUS) $(OUTPUT_KEY)$@ $(CPLUS_FLAGS) $< $(PROXY_LIB) $(LIBS) $(LIBDL) $(LINK_FLAGS) + +# Compilation rules. +$(PROXY_TESTS_OBJS): %.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(CPLUS_FLAGS) $(CXX_ONLY_FLAGS) $(CXX_WARN_SUPPRESS) $(INCLUDES) $(OUTPUT_KEY)$@ $< + +#------------------------------------------------------ +# End of rules for making the TBB Proxy unit tests +#------------------------------------------------------ + +# Include automatically generated dependencies +-include *.d diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.test b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.test new file mode 100644 index 00000000..eb2c7053 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/Makefile.test @@ -0,0 +1,321 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#------------------------------------------------------------------------------ +# Define rules for making the TBB tests. +#------------------------------------------------------------------------------ +.PHONY: default test_tbb_plain test_tbb_openmp test_tbb_cilk test_tbb_old clean + +default: test_tbb_plain test_tbb_openmp test_tbb_cilk test_tbb_old + +tbb_root ?= $(TBBROOT) +BUILDING_PHASE=1 +TEST_RESOURCE = $(TBB.RES) +TESTFILE=test +include $(tbb_root)/build/common.inc +DEBUG_SUFFIX=$(findstring _debug,$(call cross_cfg,_$(cfg))) + +#------------------------------------------------------------ +# Define static pattern rules dealing with .cpp source files +#------------------------------------------------------------ + +VPATH = $(tbb_root)/src/tbb/$(ASSEMBLY_SOURCE) $(tbb_root)/src/tbb $(tbb_root)/src/rml/client $(tbb_root)/src/old $(tbb_root)/src/test $(tbb_root)/src/perf +CPLUS_FLAGS += $(if $(crosstest),$(DEFINE_KEY)__TBB_NO_IMPLICIT_LINKAGE=1) \ + $(if $(no_exceptions),$(DEFINE_KEY)__TBB_TEST_NO_EXCEPTIONS=1) \ + $(if $(LINK_TBB.LIB),$(DEFINE_KEY)TEST_USES_TBB=1) + +TEST_PREREQUISITE+=$(TBB.LIB) +LINK_FILES+=$(LINK_TBB.LIB) + +ifdef use_proxy + USE_PROXY_FLAG = $(DEFINE_KEY)HARNESS_USE_RUNTIME_LOADER + CPLUS_FLAGS += $(USE_PROXY_FLAG) + LINK_TBB.LIB = $(PROXY.LIB) + LIBS += $(LIBDL) +endif + +TEST_SUFFIXES=secondary compiler_builtins pic +include $(tbb_root)/build/common_rules.inc + +# Rules for the tests, which use TBB in a dynamically loadable library +test_model_plugin.$(TEST_EXT): LINK_TBB.LIB = +test_model_plugin.$(TEST_EXT): CPLUS_FLAGS := $(CPLUS_FLAGS:$(USE_PROXY_FLAG)=) +test_model_plugin.$(TEST_EXT): LIBS += $(LIBDL) +ifneq (,$(DYLIB_KEY)) +test_model_plugin.$(TEST_EXT): test_model_plugin_dll.$(DLL) +endif + +# tbb_misc.$(OBJ) has to be specified here (instead of harness_inject_scheduler.h) because it carries dependency on version_string.ver +SCHEDULER_DEPENDENCIES = $(TBB_ASM.OBJ) tbb_misc.$(OBJ) + +# These executables don't depend on the TBB library, but include core .cpp files directly +SCHEDULER_DIRECTLY_INCLUDED = test_task_leaks.$(TEST_EXT) \ + test_task_assertions.$(TEST_EXT) \ + test_fast_random.$(TEST_EXT) \ + test_global_control_whitebox.$(TEST_EXT) \ + test_concurrent_queue_whitebox.$(TEST_EXT) + +# Necessary to locate version_string.ver referenced from directly included tbb_misc.cpp +INCLUDES += $(INCLUDE_KEY). $(INCLUDE_TEST_HEADERS) + +$(SCHEDULER_DIRECTLY_INCLUDED): CPLUS_FLAGS += $(DSE_KEY) +$(SCHEDULER_DIRECTLY_INCLUDED): WARNING_KEY += $(WARNING_SUPPRESS) +$(SCHEDULER_DIRECTLY_INCLUDED): LIBS += $(LIBDL) +#tbb.lib must not be linked to scheduler white box tests in order to not violate ODR +$(SCHEDULER_DIRECTLY_INCLUDED): LINK_TBB.LIB = +$(SCHEDULER_DIRECTLY_INCLUDED): LINK_FILES += $(SCHEDULER_DEPENDENCIES) +$(SCHEDULER_DIRECTLY_INCLUDED): $(SCHEDULER_DEPENDENCIES) + +# test_tbb_header detects "multiple definition" linker error using the test that covers the whole library +TWICE_LINKED_TESTS = test_tbb_header.$(TEST_EXT) \ + test_concurrent_unordered_set.$(TEST_EXT) + +%_secondary.$(OBJ): CPLUS_FLAGS+=$(DEFINE_KEY)__TBB_TEST_SECONDARY=1 + +# Detecting "multiple definition" linker error using the test that covers the whole library +$(TWICE_LINKED_TESTS): %.$(TEST_EXT): %.$(OBJ) %_secondary.$(OBJ) +$(TWICE_LINKED_TESTS): LINK_FILES+=$(@:.$(TEST_EXT)=_secondary.$(OBJ)) + +# Checks that TBB works correctly in position independent code +%_pic.$(OBJ): CPLUS_FLAGS+=$(PIC_KEY) +%_pic.$(OBJ): CPLUS_FLAGS+=$(DEFINE_KEY)__TBB_TEST_PIC=1 + +# Test of generic gcc port and icc intrinsics port +%_compiler_builtins.$(TEST_EXT): LINK_TBB.LIB = +%_compiler_builtins.$(OBJ): CPLUS_FLAGS+=$(DEFINE_KEY)__TBB_TEST_BUILTINS=1 $(DEFINE_KEY)TBB_USE_ASSERT=0 + +# dynamic_link tests don't depend on the TBB library +test_dynamic_link%.$(TEST_EXT): LINK_TBB.LIB = +test_dynamic_link.$(TEST_EXT): LIBS += $(LIBDL) + +# Resolving issue with the number of sections that an object file can contain +ifneq (,$(BIGOBJ_KEY)) +TEST_BIGOBJ = test_opencl_node.$(TEST_EXT) \ + test_atomic.$(TEST_EXT) \ + test_concurrent_hash_map.$(TEST_EXT) \ + test_concurrent_set.$(TEST_EXT) \ + test_concurrent_map.$(TEST_EXT) \ + test_concurrent_unordered_set.$(TEST_EXT) \ + test_concurrent_unordered_map.$(TEST_EXT) \ + test_join_node_key_matching.$(TEST_EXT) \ + test_join_node_msg_key_matching.$(TEST_EXT) \ + test_join_node.$(TEST_EXT) +$(TEST_BIGOBJ): override CXXFLAGS += $(BIGOBJ_KEY) +endif + +# TODO: remove repetition of .$(TEST_EXT) in the list below +# The main list of TBB tests +TEST_TBB_PLAIN.EXE = test_assembly.$(TEST_EXT) \ + test_global_control.$(TEST_EXT) \ + test_tbb_fork.$(TEST_EXT) \ + test_assembly_compiler_builtins.$(TEST_EXT) \ + test_aligned_space.$(TEST_EXT) \ + test_atomic.$(TEST_EXT) \ + test_atomic_pic.$(TEST_EXT) \ + test_atomic_compiler_builtins.$(TEST_EXT) \ + test_blocked_range.$(TEST_EXT) \ + test_blocked_range2d.$(TEST_EXT) \ + test_blocked_range3d.$(TEST_EXT) \ + test_blocked_rangeNd.$(TEST_EXT) \ + test_concurrent_queue.$(TEST_EXT) \ + test_concurrent_vector.$(TEST_EXT) \ + test_concurrent_unordered_set.$(TEST_EXT) \ + test_concurrent_unordered_map.$(TEST_EXT) \ + test_concurrent_hash_map.$(TEST_EXT) \ + test_concurrent_set.$(TEST_EXT) \ + test_concurrent_map.$(TEST_EXT) \ + test_enumerable_thread_specific.$(TEST_EXT) \ + test_handle_perror.$(TEST_EXT) \ + test_halt.$(TEST_EXT) \ + test_model_plugin.$(TEST_EXT) \ + test_mutex.$(TEST_EXT) \ + test_mutex_native_threads.$(TEST_EXT) \ + test_rwm_upgrade_downgrade.$(TEST_EXT) \ + test_cache_aligned_allocator.$(TEST_EXT) \ + test_cache_aligned_allocator_STL.$(TEST_EXT) \ + test_parallel_for.$(TEST_EXT) \ + test_parallel_reduce.$(TEST_EXT) \ + test_parallel_sort.$(TEST_EXT) \ + test_parallel_scan.$(TEST_EXT) \ + test_parallel_while.$(TEST_EXT) \ + test_parallel_do.$(TEST_EXT) \ + test_pipeline.$(TEST_EXT) \ + test_pipeline_with_tbf.$(TEST_EXT) \ + test_parallel_pipeline.$(TEST_EXT) \ + test_lambda.$(TEST_EXT) \ + test_task_scheduler_init.$(TEST_EXT) \ + test_task_scheduler_observer.$(TEST_EXT) \ + test_task.$(TEST_EXT) \ + test_tbb_thread.$(TEST_EXT) \ + test_std_thread.$(TEST_EXT) \ + test_tick_count.$(TEST_EXT) \ + test_inits_loop.$(TEST_EXT) \ + test_yield.$(TEST_EXT) \ + test_eh_tasks.$(TEST_EXT) \ + test_eh_algorithms.$(TEST_EXT) \ + test_eh_flow_graph.$(TEST_EXT) \ + test_parallel_invoke.$(TEST_EXT) \ + test_task_group.$(TEST_EXT) \ + test_ittnotify.$(TEST_EXT) \ + test_parallel_for_each.$(TEST_EXT) \ + test_tbb_header.$(TEST_EXT) \ + test_combinable.$(TEST_EXT) \ + test_task_auto_init.$(TEST_EXT) \ + test_task_arena.$(TEST_EXT) \ + test_concurrent_monitor.$(TEST_EXT) \ + test_semaphore.$(TEST_EXT) \ + test_critical_section.$(TEST_EXT) \ + test_reader_writer_lock.$(TEST_EXT) \ + test_tbb_condition_variable.$(TEST_EXT) \ + test_intrusive_list.$(TEST_EXT) \ + test_concurrent_priority_queue.$(TEST_EXT) \ + test_task_priority.$(TEST_EXT) \ + test_task_enqueue.$(TEST_EXT) \ + test_task_steal_limit.$(TEST_EXT) \ + test_hw_concurrency.$(TEST_EXT) \ + test_fp.$(TEST_EXT) \ + test_tuple.$(TEST_EXT) \ + test_flow_graph.$(TEST_EXT) \ + test_broadcast_node.$(TEST_EXT) \ + test_continue_node.$(TEST_EXT) \ + test_function_node.$(TEST_EXT) \ + test_limiter_node.$(TEST_EXT) \ + test_join_node.$(TEST_EXT) \ + test_join_node_key_matching.$(TEST_EXT) \ + test_join_node_msg_key_matching.$(TEST_EXT) \ + test_buffer_node.$(TEST_EXT) \ + test_queue_node.$(TEST_EXT) \ + test_priority_queue_node.$(TEST_EXT) \ + test_sequencer_node.$(TEST_EXT) \ + test_source_node.$(TEST_EXT) \ + test_input_node.$(TEST_EXT) \ + test_overwrite_node.$(TEST_EXT) \ + test_write_once_node.$(TEST_EXT) \ + test_indexer_node.$(TEST_EXT) \ + test_multifunction_node.$(TEST_EXT) \ + test_split_node.$(TEST_EXT) \ + test_static_assert.$(TEST_EXT) \ + test_aggregator.$(TEST_EXT) \ + test_concurrent_lru_cache.$(TEST_EXT) \ + test_examples_common_utility.$(TEST_EXT) \ + test_dynamic_link.$(TEST_EXT) \ + test_parallel_for_vectorization.$(TEST_EXT) \ + test_tagged_msg.$(TEST_EXT) \ + test_partitioner_whitebox.$(TEST_EXT) \ + test_flow_graph_whitebox.$(TEST_EXT) \ + test_composite_node.$(TEST_EXT) \ + test_async_node.$(TEST_EXT) \ + test_async_msg.$(TEST_EXT) \ + test_resumable_tasks.$(TEST_EXT) \ + test_tbb_version.$(TEST_EXT) # insert new files right above + +# These tests depend on other technologies +TEST_TBB_SPECIAL.EXE = test_openmp.$(TEST_EXT) \ + test_cilk_interop.$(TEST_EXT) \ + test_opencl_node.$(TEST_EXT) + +# skip mode_plugin for now +skip_tests += test_model_plugin + +ifdef OPENMP_FLAG +test_openmp.$(TEST_EXT): CPLUS_FLAGS += $(OPENMP_FLAG) + +test_tbb_openmp: $(TEST_PREREQUISITE) test_openmp.$(TEST_EXT) + $(run_cmd) ./test_openmp.$(TEST_EXT) 1:4 +else +test_tbb_openmp: + @echo "OpenMP is not available" +endif + +ifdef CILK_AVAILABLE +# Workaround on cilkrts linkage known issue (see Intel(R) C++ Composer XE 2011 Release Notes) +# The issue reveals itself if a version of binutils is prior to 2.17 +ifeq (linux_icc,$(tbb_os)_$(compiler)) +test_cilk_interop.$(TEST_EXT): LIBS += -lcilkrts +endif +test_tbb_cilk: test_cilk_interop.$(TEST_EXT) + $(run_cmd) ./test_cilk_interop.$(TEST_EXT) $(args) +else +test_tbb_cilk: + @echo "Intel(R) Cilk(TM) Plus is not available" +endif + +test_opencl_node.$(TEST_EXT): LIBS += $(OPENCL.LIB) + +test_arena_constraints_hwloc.$(TEST_EXT): LIBS += $(HWLOC.LIB) + +$(TEST_TBB_PLAIN.EXE) $(TEST_TBB_SPECIAL.EXE): WARNING_KEY += $(TEST_WARNING_KEY) + +# Run tests that are in SCHEDULER_DIRECTLY_INCLUDED and TEST_TBB_PLAIN.EXE but not in skip_tests (which is specified by user) +TESTS_TO_RUN := $(filter-out $(addsuffix .$(TEST_EXT),$(skip_tests)),$(TEST_TBB_PLAIN.EXE) $(SCHEDULER_DIRECTLY_INCLUDED)) + +# This definition intentionally consists of two blank lines +define eol + + +endef + +# First build the targets, then run them +# Form a list of commands separated with end of line +# Note that usually run_cmd is empty, and tests run directly + +test_tbb_plain: $(TEST_PREREQUISITE) $(TESTS_TO_RUN) + $(foreach test, $(TESTS_TO_RUN), $(run_cmd) ./$(test) $(args) $(eol)) + + +# For deprecated files, we don't mind warnings etc., thus compilation rules are most relaxed +CPLUS_FLAGS_DEPRECATED = $(DEFINE_KEY)__TBB_TEST_DEPRECATED=1 $(subst $(WARNING_KEY),,$(CPLUS_FLAGS)) $(WARNING_SUPPRESS) $(INCLUDE_KEY)$(tbb_root)/src/test +TEST_TBB_OLD.OBJ = test_concurrent_vector_v2.$(OBJ) test_concurrent_queue_v2.$(OBJ) test_mutex_v2.$(OBJ) test_task_scheduler_observer_v3.$(OBJ) + +$(TEST_TBB_OLD.OBJ): CPLUS_FLAGS := $(CPLUS_FLAGS_DEPRECATED) + +TEST_TBB_OLD.EXE = $(subst .$(OBJ),.$(TEST_EXT),$(TEST_TBB_OLD.OBJ)) + +ifeq (,$(NO_LEGACY_TESTS)) +test_tbb_old: $(TEST_PREREQUISITE) $(TEST_TBB_OLD.EXE) + $(run_cmd) ./test_concurrent_vector_v2.$(TEST_EXT) $(args) 1:4 + $(run_cmd) ./test_concurrent_queue_v2.$(TEST_EXT) $(args) 1:4 + $(run_cmd) ./test_mutex_v2.$(TEST_EXT) $(args) 1 + $(run_cmd) ./test_mutex_v2.$(TEST_EXT) $(args) 2 + $(run_cmd) ./test_mutex_v2.$(TEST_EXT) $(args) 4 + $(run_cmd) ./test_task_scheduler_observer_v3.$(TEST_EXT) $(args) 1:4 +else +test_tbb_old: + @echo Legacy tests skipped +endif + +ifneq (,$(codecov)) +codecov_gen: + profmerge + codecov $(if $(findstring -,$(codecov)),$(codecov),) -demang -comp $(tbb_root)/build/codecov.txt +endif + +time_%: time_%.$(TEST_EXT) $(TEST_PREREQUISITE) + $(run_cmd) ./$< $(args) + + +# for some reason, "perf_%.$(TEST_EXT): perf_dll.$(DLL)" does not work TODO: find out how to apply pattern here +perf_sched.$(TEST_EXT): perf_dll.$(DLL) +perf_%.$(TEST_EXT): TEST_LIBS = perf_dll.$(LIBEXT) +perf_%: perf_%.$(TEST_EXT) $(TEST_PREREQUISITE) + $(run_cmd) ./$< $(args) + +clean_%: + $(RM) $*.$(OBJ) $*.exe $*.$(DLL) $*.$(LIBEXT) $*.res $*.map $*.ilk $*.pdb $*.exp $*.*manifest $*.tmp $*.d *.ver + +clean: + $(RM) *.$(OBJ) *.exe *.$(DLL) *.$(LIBEXT) *.res *.map *.ilk *.pdb *.exp *.manifest *.tmp *.d pgopti.* *.dyn core core.*[0-9][0-9] *.ver + +# Include automatically generated dependencies +-include *.d diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/OpenBSD.clang.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/OpenBSD.clang.inc new file mode 100644 index 00000000..0acc5eb2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/OpenBSD.clang.inc @@ -0,0 +1,15 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include $(tbb_root)/build/BSD.clang.inc diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/OpenBSD.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/OpenBSD.inc new file mode 100644 index 00000000..8b85bf02 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/OpenBSD.inc @@ -0,0 +1,15 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include $(tbb_root)/build/BSD.inc diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.gcc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.gcc.inc new file mode 100644 index 00000000..f7749655 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.gcc.inc @@ -0,0 +1,88 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +TEST_WARNING_KEY = -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor -Wextra +WARNING_SUPPRESS = -Wno-parentheses -Wno-non-virtual-dtor +DYLIB_KEY = -shared +LIBDL = -ldl + +CPLUS = g++ +CONLY = gcc +LIB_LINK_FLAGS = -shared +LIBS = -lpthread -lrt -ldl +C_FLAGS = $(CPLUS_FLAGS) -x c + +ifeq ($(cfg), release) + CPLUS_FLAGS = -O2 -DUSE_PTHREAD +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -DTBB_USE_DEBUG -g -O0 -DUSE_PTHREAD +endif + +ASM= +ASM_FLAGS= + +TBB_ASM.OBJ= + +ifeq (ia64,$(arch)) +# Position-independent code (PIC) is a must for IA-64 + CPLUS_FLAGS += $(PIC_KEY) +endif + +ifeq (intel64,$(arch)) + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + CPLUS_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +endif + +# for some gcc versions on Solaris, -m64 may imply V9, but perhaps not everywhere (TODO: verify) +ifeq (sparc,$(arch)) + CPLUS_FLAGS += -mcpu=v9 -m64 + LIB_LINK_FLAGS += -mcpu=v9 -m64 +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASSEMBLY_SOURCE=$(arch)-gas +ifeq (ia64,$(arch)) + ASM=ias + TBB_ASM.OBJ = atomic_support.o lock_byte.o log2.o pause.o +endif +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.inc new file mode 100644 index 00000000..30a2e684 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.inc @@ -0,0 +1,79 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifndef arch + arch:=$(shell uname -p) + ifeq ($(arch),i386) + ifeq ($(shell isainfo -b),64) + arch:=intel64 + else + arch:=ia32 + endif + endif + export arch +# For non-IA systems running Sun OS, 'arch' will contain whatever is printed by uname -p. +# In particular, for SPARC architecture it will contain "sparc". +endif + +ifndef runtime + gcc_version:=$(shell gcc -dumpfullversion -dumpversion) + os_version:=$(shell uname -r) + os_kernel_version:=$(shell uname -r | sed -e 's/-.*$$//') + export runtime:=cc$(gcc_version)_kernel$(os_kernel_version) +endif + +ifeq ($(arch),sparc) + native_compiler := gcc + export compiler ?= gcc +else + native_compiler := suncc + export compiler ?= suncc +endif +# debugger ?= gdb + +CMD=$(SHELL) -c +CWD=$(shell pwd) +RM?=rm -f +RD?=rmdir +MD?=mkdir -p +NUL= /dev/null +SLASH=/ +MAKE_VERSIONS=bash $(tbb_root)/build/version_info_sunos.sh $(VERSION_FLAGS) >version_string.ver +MAKE_TBBVARS=bash $(tbb_root)/build/generate_tbbvars.sh + +ifdef LD_LIBRARY_PATH + export LD_LIBRARY_PATH := .:$(LD_LIBRARY_PATH) +else + export LD_LIBRARY_PATH := . +endif + +####### Build settings ######################################################## + +OBJ = o +DLL = so +LIBEXT=so + +TBB.LST = +TBB.DEF = +TBB.DLL = libtbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +TBB.LIB = $(TBB.DLL) +LINK_TBB.LIB = $(TBB.LIB) + +MALLOC.DLL = libtbbmalloc$(DEBUG_SUFFIX).$(DLL) +MALLOC.LIB = $(MALLOC.DLL) +LINK_MALLOC.LIB = $(MALLOC.LIB) + +MALLOCPROXY.DLL = libtbbmalloc_proxy$(DEBUG_SUFFIX).$(DLL) + +TEST_LAUNCHER=sh $(tbb_root)/build/test_launcher.sh $(largs) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.suncc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.suncc.inc new file mode 100644 index 00000000..b0dfa484 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/SunOS.suncc.inc @@ -0,0 +1,88 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +COMPILE_ONLY = -c -xMMD -errtags +PREPROC_ONLY = -E -xMMD +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -KPIC +DYLIB_KEY = -G +LIBDL = -ldl +# WARNING_AS_ERROR_KEY = -errwarn=%all +WARNING_AS_ERROR_KEY = Warning as error +# Supported Solaris Studio* 12.2 and above, remove ',inlasmpnu' in the line below to build by compiler prior Solaris Studio* 12.2 +WARNING_SUPPRESS = -erroff=unassigned,attrskipunsup,badargtype2w,badbinaryopw,wbadasg,wvarhidemem,inlasmpnu +tbb_strict=0 + +CPLUS = CC +CONLY = cc + +OPENMP_FLAG = -xopenmp +LIB_LINK_FLAGS = -G -R . -M$(tbb_root)/build/suncc.map.pause +LINK_FLAGS += -M$(tbb_root)/build/suncc.map.pause +LIBS = -lpthread -lrt -R . +C_FLAGS = $(CPLUS_FLAGS) + +#TODO: the $(stdlib) instead of hard-wiring STLPort +ifeq ($(cfg), release) + CPLUS_FLAGS = -mt -xO2 -g -library=stlport4 -DUSE_PTHREAD $(WARNING_SUPPRESS) +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -mt -DTBB_USE_DEBUG -g -library=stlport4 -DUSE_PTHREAD $(WARNING_SUPPRESS) +endif + +ASM= +ASM_FLAGS= + +TBB_ASM.OBJ= + +ifeq (intel64,$(arch)) + CPLUS_FLAGS += -m64 + ASM_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + CPLUS_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +endif + +# TODO: verify whether -m64 implies V9 on relevant Sun Studio versions +# (those that handle gcc assembler syntax) +ifeq (sparc,$(arch)) + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +export TBB_CUSTOM_VARS_SH=export CXXFLAGS="-I$${TBBROOT}/include -library=stlport4 $(CXXFLAGS) -M$${TBBROOT}/build/suncc.map.pause" +export TBB_CUSTOM_VARS_CSH=setenv CXXFLAGS "-I$${TBBROOT}/include -library=stlport4 $(CXXFLAGS) -M$${TBBROOT}/build/suncc.map.pause" + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASSEMBLY_SOURCE=$(arch)-fbe +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ +M_INCLUDES = $(INCLUDES) -I$(MALLOC_ROOT) -I$(MALLOC_SOURCE_ROOT) +M_CPLUS_FLAGS = $(CPLUS_FLAGS) +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.clang.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.clang.inc new file mode 100644 index 00000000..6edc48f7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.clang.inc @@ -0,0 +1,126 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +SDL_FLAGS = -fPIE -fPIC -fstack-protector -Wformat -Wformat-security +TEST_WARNING_KEY = -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor -Wextra + +WARNING_SUPPRESS = -Wno-parentheses -Wno-non-virtual-dtor +DYLIB_KEY = -shared +EXPORT_KEY = -Wl,--version-script, +LIBDL = -ldl + +CPLUS = $(TARGET_CXX) +CONLY = $(TARGET_CC) + +# -soname is necessary for proper linkage to TBB prebuilt libraries when building application with Android SDK +LIB_LINK_FLAGS = $(DYLIB_KEY) -Wl,-soname=$(BUILDING_LIBRARY) -z relro -z now + +# pie is necessary for test executables to work and might be removed if newer NDK will add it implicitly +PIE_FLAG = -pie +ifeq ($(APP_PIE), false) + PIE_FLAG= +endif + +LINK_FLAGS = -Wl,-rpath-link=. -rdynamic +C_FLAGS = $(CPLUS_FLAGS) + +ifeq ($(cfg), release) + SDL_FLAGS += -D_FORTIFY_SOURCE=2 + CPLUS_FLAGS = -O2 +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -g -O0 $(DEFINE_KEY)TBB_USE_DEBUG +endif + +CPLUS_FLAGS += $(DEFINE_KEY)USE_PTHREAD $(DEFINE_KEY)_GLIBCXX_HAVE_FENV_H + +ifneq (,$(findstring $(arch),ia32 intel64)) + CPLUS_FLAGS += $(DEFINE_KEY)DO_ITT_NOTIFY +endif + +ifeq (0, $(dynamic_load)) + CPLUS_FLAGS += $(DEFINE_KEY)__TBB_DYNAMIC_LOAD_ENABLED=0 +endif + +# Paths to the NDK prebuilt tools and libraries +ifeq (,$(findstring $(ndk_version), $(foreach v, 7 8 9 10 11 12 13 14 15,r$(v) r$(v)b r$(v)c r$(v)d r$(v)e))) + # Since Android* NDK r16 another sysroot and isystem paths have to be specified + CPLUS_FLAGS += --sysroot=$(NDK_ROOT)/sysroot -isystem $(NDK_ROOT)/sysroot/usr/include/$(TRIPLE) + # Android* version flag required since r16 + CPLUS_FLAGS += -D__ANDROID_API__=$(API_LEVEL) +else + CPLUS_FLAGS += --sysroot=$(SYSROOT) +endif + +# Library sysroot flag +LIB_LINK_FLAGS += --sysroot=$(SYSROOT) +# Flag for test executables +LINK_FLAGS += --sysroot=$(SYSROOT) + +LIBS = -L$(CPLUS_LIB_PATH) -lc++_shared +ifeq (,$(findstring $(ndk_version),$(foreach v, 7 8 9 10 11,r$(v) r$(v)b r$(v)c r$(v)d r$(v)e))) + LIBS += -lc++abi + ifeq (arm,$(arch)) + LIBS += -lunwind + endif +endif + +ifeq (arm,$(arch)) + CPLUS_FLAGS += $(DEFINE_KEY)__TBB_64BIT_ATOMICS=0 +endif + +CPLUS_FLAGS += $(TARGET_CFLAGS) +LIB_LINK_FLAGS += $(TARGET_CFLAGS) $(TARGET_LDFLAGS) -L$(CPLUS_LIB_PATH) + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ASM = $(tbb_tool_prefix)as +ifeq (intel64,$(arch)) + ASM_FLAGS += --64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += --32 +endif +ifeq ($(cfg),debug) + ASM_FLAGS += -g +endif + +ASSEMBLY_SOURCE=$(arch)-gas +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.gcc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.gcc.inc new file mode 100644 index 00000000..980a8cac --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.gcc.inc @@ -0,0 +1,113 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +TEST_WARNING_KEY = -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor -Wextra + +WARNING_SUPPRESS = -Wno-parentheses -Wno-non-virtual-dtor +DYLIB_KEY = -shared +EXPORT_KEY = -Wl,--version-script, +LIBDL = -ldl + +CPLUS = $(tbb_tool_prefix)g++ +CONLY = $(tbb_tool_prefix)gcc + +# -soname is necessary for proper linkage to TBB prebuilt libraries when building application with Android SDK +LIB_LINK_FLAGS = $(DYLIB_KEY) -Wl,-soname=$(BUILDING_LIBRARY) + +# pie is necessary for test executables to work and might be removed if newer NDK will add it implicitly +PIE_FLAG = -pie +ifeq ($(APP_PIE), false) + PIE_FLAG= +endif + +LINK_FLAGS = -Wl,-rpath-link=. -rdynamic +C_FLAGS = $(CPLUS_FLAGS) + +ifeq ($(cfg), release) + CPLUS_FLAGS = -O2 +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -g -O0 $(DEFINE_KEY)TBB_USE_DEBUG +endif + +CPLUS_FLAGS += $(DEFINE_KEY)USE_PTHREAD $(DEFINE_KEY)_GLIBCXX_HAVE_FENV_H + +ifneq (,$(findstring $(arch),ia32 intel64)) + CPLUS_FLAGS += $(DEFINE_KEY)DO_ITT_NOTIFY +endif + +ifeq (0, $(dynamic_load)) + CPLUS_FLAGS += $(DEFINE_KEY)__TBB_DYNAMIC_LOAD_ENABLED=0 +endif + + +# Paths to the NDK prebuilt tools and libraries +CPLUS_FLAGS += --sysroot=$(SYSROOT) +LIB_LINK_FLAGS += --sysroot=$(SYSROOT) +LIBS = -L$(CPLUS_LIB_PATH) -lgnustl_shared + +ifeq (ia32,$(arch)) + # TODO: Determine best setting of -march and add to CPLUS_FLAGS + CPLUS_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +else ifeq (intel64,$(arch)) + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +else ifeq (arm,$(arch)) + CPLUS_FLAGS += -march=armv7-a $(DEFINE_KEY)TBB_USE_GCC_BUILTINS=1 $(DEFINE_KEY)__TBB_64BIT_ATOMICS=0 +else ifeq (arm64,$(arch)) + CPLUS_FLAGS += -march=armv8-a +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ASM = $(tbb_tool_prefix)as +ifeq (intel64,$(arch)) + ASM_FLAGS += --64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += --32 +endif +ifeq ($(cfg),debug) + ASM_FLAGS += -g +endif + +ASSEMBLY_SOURCE=$(arch)-gas +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.icc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.icc.inc new file mode 100644 index 00000000..6ba64d19 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.icc.inc @@ -0,0 +1,116 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = +TEST_WARNING_KEY = -Wshadow -Woverloaded-virtual -Wextra + +WARNING_SUPPRESS = -Wno-parentheses -Wno-non-virtual-dtor +DYLIB_KEY = -shared +EXPORT_KEY = -Wl,--version-script, +LIBDL = -ldl + +CPLUS = icpc +CONLY = icc + +# -soname is necessary for proper linkage to TBB prebuilt libraries when building application with Android SDK +LIB_LINK_FLAGS = $(DYLIB_KEY) -Wl,-soname=$(BUILDING_LIBRARY) + +# pie is necessary for test executables to work and might be removed if newer NDK will add it implicitly +PIE_FLAG = -pie +ifeq ($(APP_PIE), false) + PIE_FLAG= +endif + +LINK_FLAGS = -Wl,-rpath-link=. -rdynamic +C_FLAGS = $(CPLUS_FLAGS) + +ifeq ($(cfg), release) + CPLUS_FLAGS = -O2 +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -g -O0 $(DEFINE_KEY)TBB_USE_DEBUG +endif + +CPLUS_FLAGS += $(DEFINE_KEY)USE_PTHREAD $(DEFINE_KEY)_GLIBCXX_HAVE_FENV_H + +ifneq (,$(findstring $(arch),ia32 intel64)) + CPLUS_FLAGS += $(DEFINE_KEY)DO_ITT_NOTIFY +endif + +ifeq (0, $(dynamic_load)) + CPLUS_FLAGS += $(DEFINE_KEY)__TBB_DYNAMIC_LOAD_ENABLED=0 +endif + + +# Paths to the NDK prebuilt tools and libraries +CPLUS_FLAGS += --sysroot=$(SYSROOT) +LIB_LINK_FLAGS += --sysroot=$(SYSROOT) +# the -static-intel flag is to remove the need to copy Intel-specific libs to the device. +LIBS = -L$(CPLUS_LIB_PATH) -lgnustl_shared -static-intel + +ifeq (ia32,$(arch)) + # TODO: Determine best setting of -march and add to CPLUS_FLAGS + CPLUS_FLAGS += -m32 -march=pentium4 -falign-stack=maintain-16-byte + LIB_LINK_FLAGS += -m32 +else + ifeq (intel64,$(arch)) + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 + endif +endif + +ifeq (arm,$(findstring arm,$(arch))) + $(error "Unsupported architecture $(arch) for icc compiler") +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ASM = $(tbb_tool_prefix)as +ifeq (intel64,$(arch)) + ASM_FLAGS += --64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += --32 +endif +ifeq ($(cfg),debug) + ASM_FLAGS += -g +endif + +ASSEMBLY_SOURCE=$(arch)-gas +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.inc new file mode 100644 index 00000000..3832ee53 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.inc @@ -0,0 +1,59 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Extra gmake command-line parameters for use with Android: +# +# dlopen_workaround: Some OS versions need workaround for dlopen to avoid recursive calls. +# + +####### Detections and Commands ############################################### + +ifeq (android,$(findstring android,$(tbb_os))) + $(error TBB only supports cross-compilation for Android. Specify "target=android" instead.) +endif + +ifndef BUILDING_PHASE + ifneq ("command line","$(origin arch)") + ifeq (icc,$(compiler)) + export COMPILER_VERSION := ICC: $(shell icc -V &1 | grep 'Version') + ifneq (,$(findstring running on IA-32, $(COMPILER_VERSION))) + export arch:=ia32 + else ifneq (,$(findstring running on Intel(R) 64, $(COMPILER_VERSION))) + export arch:=intel64 + else + $(error "No support for Android in $(COMPILER_VERSION)") + endif + + else + ifdef ANDROID_SERIAL + uname_m:=$(shell adb shell uname -m) + ifeq (i686,$(uname_m)) + export arch:=ia32 + else + export arch:=$(uname_m) + endif + endif + endif + endif +endif + +ifeq ("$(arch)","") + $(error "No target architecture specified and \'ANDROID_SERIAL\' environment variable specifying target device not set") +endif + +# Android platform only supported from TBB 4.1 forward +NO_LEGACY_TESTS = 1 + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.linux.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.linux.inc new file mode 100644 index 00000000..a7d2b183 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.linux.inc @@ -0,0 +1,63 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +####### Detections and Commands ############################################### + +# Must set def_prefix according to target architecture detected above +ifeq (ia32,$(arch)) + def_prefix = lin32 +endif +ifeq (arm,$(findstring arm,$(arch))) + def_prefix = lin32 +endif +ifeq (64,$(findstring 64,$(arch))) + def_prefix = lin64 +endif + +ifdef ndk_version + $(warning "NDK version $(ndk_version)") +else + $(warning "NDK version not set in environment, using \'unknown\' instead.") + ndk_version:=unknown +endif + +export runtime:=$(target)_NDK$(ndk_version)_version_$(target_os_version) + +AR = $(tbb_tool_prefix)ar +MAKE_VERSIONS=sh $(tbb_root)/build/version_info_android.sh $(VERSION_FLAGS) >version_string.ver + +####### Build settings ######################################################## + +# No SONAME_SUFFIX for Android allowed in library names +TBB.LST = $(tbb_root)/src/tbb/$(def_prefix)-tbb-export.lst +TBB.DEF = $(TBB.LST:.lst=.def) +TBB.DLL = libtbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +TBB.LIB = $(TBB.DLL) +TBB_NO_VERSION.DLL= +LINK_TBB.LIB = $(TBB.LIB) + +MALLOC.DEF = $(MALLOC_ROOT)/$(def_prefix)-tbbmalloc-export.def +MALLOC.DLL = libtbbmalloc$(DEBUG_SUFFIX).$(DLL) +MALLOC.LIB = $(MALLOC.DLL) +MALLOC_NO_VERSION.DLL= +LINK_MALLOC.LIB = $(MALLOC.LIB) + +MALLOCPROXY.DEF = $(MALLOC_ROOT)/$(def_prefix)-proxy-export.def +MALLOCPROXY.DLL = libtbbmalloc_proxy$(DEBUG_SUFFIX).$(DLL) +MALLOCPROXY_NO_VERSION.DLL= +MALLOCPROXY.LIB = $(MALLOCPROXY.DLL) +LINK_MALLOCPROXY.LIB = $(MALLOCPROXY.LIB) + +TEST_LAUNCHER= +run_cmd ?= -sh $(tbb_root)/build/android.linux.launcher.sh $(largs) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.linux.launcher.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.linux.launcher.sh new file mode 100644 index 00000000..2643d3e0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.linux.launcher.sh @@ -0,0 +1,144 @@ +#!/bin/sh +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Usage: +# android.linux.launcher.sh [-v] [-q] [-s] [-r ] [-u] [-l ] +# where: -v enables verbose output +# where: -q enables quiet mode +# where: -s runs the test in stress mode (until non-zero exit code or ctrl-c pressed) +# where: -r specifies number of times to repeat execution +# where: -u is ignored on Android +# where: -l specifies the library name to be assigned to LD_PRELOAD +# +# Libs and executable necessary for testing should be present in the current directory before running. +# ANDROID_SERIAL must be set to the connected Android target device name for file transfer and test runs. +# ANDROID_TEST_DIRECTORY may be set to the directory used for testing on the Android target device; otherwise, +# the default directory used is "/data/local/tmp/$(basename $PWD)". +# Note: Do not remove the redirections to '/dev/null' in the script, otherwise the nightly test system will fail. + +do_cleanup() # +{ # + adb pull $targetdir/events.txt events.txt > /dev/null 2>&1 # + # Remove target directory on the device + adb shell "rm -r ${targetdir}; mkdir -p ${targetdir}" > /dev/null 2>&1 # +} # +do_trap_cleanup() # +{ # + do_cleanup # + exit -1 # +} # +while getopts "qvsr:ul:" flag # +do case $flag in # + s ) # Stress testing mode + echo Doing stress testing. Press Ctrl-C to terminate + run_env='stressed() { while $*; do :; done; }; ' # + run_prefix="stressed $run_prefix" ;; # + r ) # Repeats test n times + run_env="repeated() { for i in $(seq -s ' ' 1 $OPTARG) ; do echo \$i of $OPTARG:; \$*; done; }; " # + run_prefix="repeated $run_prefix" ;; # + l ) # Additional library + ldpreload="$OPTARG " ;; # + u ) # Stack limit + ;; # + q ) # Quiet mode, removes 'done' but prepends any other output by test name + OUTPUT='2>&1 | sed -e "s/done//;/^[[:space:]]*$/d;s!^!$exename: !"' ;; # + v ) # Verbose mode + SUPPRESS='' # + verbose=1 ;; # +esac done # +shift `expr $OPTIND - 1` # +[ -z "$OUTPUT" ] && OUTPUT='| sed -e "s/\\r$//"' # +[ $verbose ] || SUPPRESS='>/dev/null' # +# Collect the executable name +exename=$(basename $1) # +shift # +# Prepare the target directory on the device +currentdir=$(basename $PWD) # +targetdir=${ANDROID_TEST_DIRECTORY:-/data/local/tmp/$currentdir} # +do_cleanup # +trap do_trap_cleanup INT # if someone hits control-c, cleanup the device +# Collect the list of files to transfer to the target device, starting with executable itself. +fnamelist="$exename" # +# Add the C++ standard library from the NDK, which is required for all tests on Android. +if [ ! -z "${LIB_STL_ANDROID}" ]; then # + fnamelist="$fnamelist ${LIB_STL_ANDROID}" # +else # + fnamelist="$fnamelist libc++_shared.so" # +fi # +# Find the TBB libraries and add them to the list. +# Add TBB libraries from the current directory that contains libtbb* files +files="$(ls libtbb* 2> /dev/null)" # +[ -z "$files" ] || fnamelist="$fnamelist $files" # +# Add any libraries built for specific tests. +exeroot=${exename%\.*} # +files="$(ls ${exeroot}*.so ${exeroot}*.so.* 2> /dev/null)" # +[ -z "$files" ] || fnamelist="$fnamelist $files" # +# TODO: Add extra libraries from the Intel(R) Compiler for certain tests +# found=$(echo $exename | egrep 'test_malloc_atexit\|test_malloc_lib_unload' 2> /dev/null) +# if [ ! -z $found ] ; then +# fnamelist="$fnamelist ${compiler_path_lib}/libimf.so \ +# ${compiler_path_lib}/libsvml.so \ +# ${compiler_path_lib}/libintlc.so.5" +# fi + +# Transfer collected executable and library files to the target device. +transfers_ok=1 # +for fullname in $fnamelist; do { # + if [ -r $fullname ]; then { # + # Transfer the executable and libraries to top-level target directory + [ $verbose ] && echo -n "Pushing $fullname: " # + eval "adb push $fullname ${targetdir}/$(basename $fullname) $SUPPRESS 2>&1" # + }; else { # + echo "Error: required file ${currentdir}/${fullname} for test $exename not available for transfer." # + transfers_ok=0 # + }; fi # +}; done # +if [ "${transfers_ok}" = "0" ]; then { # + do_cleanup # + exit -1 # +}; fi # +# Transfer input files used by example codes by scanning the executable argument list. +for fullname in "$@"; do { # + if [ -r $fullname ]; then { # + directory=$(dirname $fullname) # + filename=$(basename $fullname) # + # strip leading "." from fullname if present + if [ "$directory" = "\." ]; then { # + directory="" # + fullname=$filename # + }; fi # + # Create the target directory to hold input file if necessary + if [ ! -z $directory ]; then { # + eval "adb shell 'mkdir $directory' $SUPPRESS 2>&1" # + }; fi # + # Transfer the input file to corresponding directory on target device + [ $verbose ] && echo -n "Pushing $fullname: " # + eval "adb push $fullname ${targetdir}/$fullname $SUPPRESS 2>&1" # + }; fi # +}; done # +# Set LD_PRELOAD if necessary +[ -z "$ldpreload" ] || run_prefix="LD_PRELOAD='$ldpreload' $run_prefix" # +[ $verbose ] && echo Running $run_prefix ./$exename $* # +run_env="$run_env cd $targetdir; export LD_LIBRARY_PATH=." # +[ -z "$VIRTUAL_MACHINE" ] || run_env="$run_env; export VIRTUAL_MACHINE=$VIRTUAL_MACHINE" # +# The return_code file is the best way found to return the status of the test execution when using adb shell. +eval 'adb shell "$run_env; $run_prefix ./$exename $* || echo -n \$? >error_code"' "${OUTPUT}" # +# Capture the return code string and remove the trailing \r from the return_code file contents +err=`adb shell "cat $targetdir/error_code 2>/dev/null"` # +[ -z $err ] || echo $exename: exited with error $err # +do_cleanup # +# Return the exit code of the test. +exit $err # diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.macos.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.macos.inc new file mode 100644 index 00000000..a48ee32b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.macos.inc @@ -0,0 +1,72 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +####### Detections and Commands ############################################### + +# Must set def_prefix according to target architecture detected above +ifeq (ia32,$(arch)) + def_prefix = lin32 +endif +ifeq (arm,$(findstring arm,$(arch))) + def_prefix = lin32 +endif +ifeq (64,$(findstring 64,$(arch))) + def_prefix = lin64 +endif + +ifdef ndk_version + $(warning "NDK version $(ndk_version)") +else + $(warning "NDK version not set in environment, using \'unknown\' instead.") + ndk_version:=unknown +endif + +export runtime:=$(target)_NDK$(ndk_version)_version_$(target_os_version) + +AR = $(tbb_tool_prefix)ar +MAKE_VERSIONS=sh $(tbb_root)/build/version_info_android.sh $(VERSION_FLAGS) >version_string.ver + +####### Build settings ######################################################## + +# No SONAME_SUFFIX for Android allowed in library names +TBB.LST = $(tbb_root)/src/tbb/$(def_prefix)-tbb-export.lst +TBB.DEF = $(TBB.LST:.lst=.def) +TBB.DLL = libtbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +TBB.LIB = $(TBB.DLL) +TBB_NO_VERSION.DLL= +LINK_TBB.LIB = $(TBB.LIB) + +MALLOC.DEF = $(MALLOC_ROOT)/$(def_prefix)-tbbmalloc-export.def +MALLOC.DLL = libtbbmalloc$(DEBUG_SUFFIX).$(DLL) +MALLOC.LIB = $(MALLOC.DLL) +MALLOC_NO_VERSION.DLL= +LINK_MALLOC.LIB = $(MALLOC.LIB) + +MALLOCPROXY.DEF = $(MALLOC_ROOT)/$(def_prefix)-proxy-export.def +MALLOCPROXY.DLL = libtbbmalloc_proxy$(DEBUG_SUFFIX).$(DLL) +MALLOCPROXY_NO_VERSION.DLL= +MALLOCPROXY.LIB = $(MALLOCPROXY.DLL) +LINK_MALLOCPROXY.LIB = $(MALLOCPROXY.LIB) + +TBB.RES = +MALLOC.RES = +RML.RES = +TBB.MANIFEST = +MALLOC.MANIFEST = +RML.MANIFEST = +OBJ = o +DLL = so + +TEST_LAUNCHER= +run_cmd ?= -sh $(tbb_root)/build/android.linux.launcher.sh $(largs) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.windows.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.windows.inc new file mode 100644 index 00000000..a56f9a98 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/android.windows.inc @@ -0,0 +1,74 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +####### Detections and Commands ############################################### + +# Must set def_prefix according to target architecture detected above +ifeq (ia32,$(arch)) + def_prefix = lin32 +endif +ifeq (arm,$(findstring arm,$(arch))) + def_prefix = lin32 +endif +ifeq (64,$(findstring 64,$(arch))) + def_prefix = lin64 +endif + +ifdef ndk_version + $(warning "NDK version $(ndk_version)") +else + $(warning "NDK version not set in environment, using \'unknown\' instead.") + ndk_version:=unknown +endif + +export runtime:=$(target)_NDK$(ndk_version)_version_$(target_os_version) + +AR = $(tbb_tool_prefix)ar +MAKE_VERSIONS = cmd /C cscript /nologo /E:jscript $(subst \,/,$(tbb_root))/build/version_info_windows.js $(CONLY) $(arch) $(subst \,/,"$(VERSION_FLAGS)") > version_string.ver + +####### Build settings ######################################################## + +# No SONAME_SUFFIX for Android allowed in library names +TBB.LST = $(tbb_root)/src/tbb/$(def_prefix)-tbb-export.lst +TBB.DEF = $(TBB.LST:.lst=.def) +TBB.DLL = libtbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +TBB.LIB = $(TBB.DLL) +TBB_NO_VERSION.DLL= +LINK_TBB.LIB = $(TBB.LIB) + +MALLOC.DEF = $(MALLOC_ROOT)/$(def_prefix)-tbbmalloc-export.def +MALLOC.DLL = libtbbmalloc$(DEBUG_SUFFIX).$(DLL) +MALLOC.LIB = $(MALLOC.DLL) +MALLOC_NO_VERSION.DLL= +LINK_MALLOC.LIB = $(MALLOC.LIB) + +MALLOCPROXY.DEF = $(MALLOC_ROOT)/$(def_prefix)-proxy-export.def +MALLOCPROXY.DLL = libtbbmalloc_proxy$(DEBUG_SUFFIX).$(DLL) +MALLOCPROXY_NO_VERSION.DLL= +MALLOCPROXY.LIB = $(MALLOCPROXY.DLL) + +TBB.RES = +MALLOC.RES = +RML.RES = +TBB.MANIFEST = +MALLOC.MANIFEST = +RML.MANIFEST = +OBJ = o +DLL = so + +TEST_LAUNCHER= +run_cmd ?= -sh $(tbb_root)/build/android.linux.launcher.sh $(largs) +export UNIXMODE = 1 +# Clang for Android* uses the INCLUDE variable (instead of CPATH) +export USE_INCLUDE_ENV = 1 diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/big_iron.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/big_iron.inc new file mode 100644 index 00000000..abe6accc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/big_iron.inc @@ -0,0 +1,72 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#------------------------------------------------------------------------------ +# Defines settings for building the TBB run-time as a static library. +# Use these only on platforms where dynamic linking is impractical. +# +# IF YOU USE TBB AS A STATIC LIBRARY, YOU MUST GUARANTEE THAT ONLY ONE COPY OF +# THE TBB RUN-TIME IS LINKED INTO AN APPLICATION! LINKING IN MULTIPLE COPIES +# OF THE TBB RUN-TIME, DIRECTLY OR INDIRECTLY, MAY CAUSE PROGRAM FAILURE! +#------------------------------------------------------------------------------ + +# Note that ITT_NOTIFY allows to selectively remove the definition of +# DO_ITT_NOTIFY without sabotaging deferred expansion of CPLUS_FLAGS. +# TODO: currently only in linux.{gcc,xl}.inc + +# Note that -pthread with xl gives "1501-210 (W) command option t contains an incorrect subargument"; +# multithreading is instead achieved by using the _r affix in the compiler name. +# TODO: is -lpthread still relevant/needed with XL and _r affix? + +# Note that usage of dynamic (shared) libraries is disabled +# (via -D__TBB_DYNAMIC_LOAD_ENABLED=0 and LIBDL emptied) primarily for performance. + +# OS specific settings => + LIB_LINK_CMD = ar rcs + LIB_LINK_FLAGS = + LIB_LINK_LIBS = + LIB_OUTPUT_KEY = + DYLIB_KEY = + ifeq ($(tbb_os),linux) + ifeq ($(compiler),clang) + LIBS = -pthread -lrt + endif + ifeq ($(compiler),gcc) + LIBS = -pthread -lrt + endif + ifeq ($(compiler),xl) + LIBS = -lpthread -lrt + endif + LINK_FLAGS = + endif + override CXXFLAGS += -D__TBB_DYNAMIC_LOAD_ENABLED=0 -D__TBB_SOURCE_DIRECTLY_INCLUDED=1 + ITT_NOTIFY = + DLL = a + LIBEXT = a + LIBPREF = lib + LIBDL = +# <= OS specific settings + +TBB.DLL = $(LIBPREF)tbb$(DEBUG_SUFFIX).$(LIBEXT) +LINK_TBB.LIB = $(TBB.DLL) +TBB.LST = +TBB.DEF = +TBB_NO_VERSION.DLL = + +MALLOC.DLL = $(LIBPREF)tbbmalloc$(DEBUG_SUFFIX).$(LIBEXT) +LINK_MALLOC.LIB = $(MALLOC.DLL) +MALLOC.DEF = +MALLOC_NO_VERSION.DLL = +MALLOCPROXY.DLL = +MALLOCPROXY.DEF = diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/build.py b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/build.py new file mode 100644 index 00000000..c0ab1519 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/build.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python +# +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Provides unified tool for preparing TBB for packaging + +from __future__ import print_function +import os +import re +import sys +import shutil +import platform +import argparse +from glob import glob +from collections import OrderedDict + +jp = os.path.join +is_win = (platform.system() == 'Windows') +is_lin = (platform.system() == 'Linux') +is_mac = (platform.system() == 'Darwin') + +default_prefix = os.getenv('PREFIX', 'install_prefix') +if is_win: + default_prefix = jp(default_prefix, 'Library') # conda-specific by default on Windows + +parser = argparse.ArgumentParser() +parser.add_argument('--tbbroot', default='.', help='Take Intel TBB from here') +parser.add_argument('--prefix', default=default_prefix, help='Prefix') +parser.add_argument('--prebuilt', default=[], action='append', help='Directories to find prebuilt files') +parser.add_argument('--no-rebuild', default=False, action='store_true', help='do not rebuild') +parser.add_argument('--install', default=False, action='store_true', help='install all') +parser.add_argument('--install-libs', default=False, action='store_true', help='install libs') +parser.add_argument('--install-devel', default=False, action='store_true', help='install devel') +parser.add_argument('--install-docs', default=False, action='store_true', help='install docs') +parser.add_argument('--install-python', default=False, action='store_true', help='install python module') +parser.add_argument('--make-tool', default='make', help='Use different make command instead') +parser.add_argument('--copy-tool', default=None, help='Use this command for copying ($ tool file dest-dir)') +parser.add_argument('--build-args', default="", help='specify extra build args') +parser.add_argument('--build-prefix', default='local', help='build dir prefix') +parser.add_argument('--cmake-dir', help='directory to install CMake configuration files. Default: /lib/cmake/tbb') +if is_win: + parser.add_argument('--msbuild', default=False, action='store_true', help='Use msbuild') + parser.add_argument('--vs', default="2012", help='select VS version for build') + parser.add_argument('--vs-platform', default="x64", help='select VS platform for build') +parser.add_argument('ignore', nargs='?', help="workaround conda-build issue #2512") + +args = parser.parse_args() + +if args.install: + args.install_libs = True + args.install_devel = True + args.install_docs = True + args.install_python= True + +def custom_cp(src, dst): + assert os.system(' '.join([args.copy_tool, src, dst])) == 0 + +if args.copy_tool: + install_cp = custom_cp # e.g. to use install -p -D -m 755 on Linux +else: + install_cp = shutil.copy + +bin_dir = jp(args.prefix, "bin") +lib_dir = jp(args.prefix, "lib") +inc_dir = jp(args.prefix, 'include') +doc_dir = jp(args.prefix, 'share', 'doc', 'tbb') +cmake_dir = jp(args.prefix, "lib", "cmake", "tbb") if args.cmake_dir is None else args.cmake_dir + +if is_win: + os.environ["OS"] = "Windows_NT" # make sure TBB will interpret it correctly + libext = '.dll' + libpref = '' + dll_dir = bin_dir +else: + libext = '.dylib' if is_mac else '.so.2' + libpref = 'lib' + dll_dir = lib_dir + +tbb_names = ["tbb", "tbbmalloc", "tbbmalloc_proxy"] + +############################################################## + +def system(arg): + print('$ ', arg) + return os.system(arg) + +def run_make(arg): + if system('%s -j %s'% (args.make_tool, arg)) != 0: + print("\nBummer. Running serial build in order to recover the log and have a chance to fix the build") + assert system('%s %s'% (args.make_tool, arg)) == 0 + +os.chdir(args.tbbroot) +if args.prebuilt: + release_dirs = sum([glob(d) for d in args.prebuilt], []) + print("Using pre-built files from ", release_dirs) +else: + if is_win and args.msbuild: + preview_release_dir = release_dir = jp(args.tbbroot, 'build', 'vs'+args.vs, args.vs_platform, 'Release') + if not args.no_rebuild or not os.path.isdir(release_dir): + assert os.system('msbuild /m /p:Platform=%s /p:Configuration=Release %s build/vs%s/makefile.sln'% \ + (args.vs_platform, args.build_args, args.vs)) == 0 + preview_debug_dir = debug_dir = jp(args.tbbroot, 'build', 'vs'+args.vs, args.vs_platform, 'Debug') + if not args.no_rebuild or not os.path.isdir(debug_dir): + assert os.system('msbuild /m /p:Platform=%s /p:Configuration=Debug %s build/vs%s/makefile.sln'% \ + (args.vs_platform, args.build_args, args.vs)) == 0 + else: + release_dir = jp(args.tbbroot, 'build', args.build_prefix+'_release') + debug_dir = jp(args.tbbroot, 'build', args.build_prefix+'_debug') + if not args.no_rebuild or not (os.path.isdir(release_dir) and os.path.isdir(debug_dir)): + run_make('tbb_build_prefix=%s %s'% (args.build_prefix, args.build_args)) + preview_release_dir = jp(args.tbbroot, 'build', args.build_prefix+'_preview_release') + preview_debug_dir = jp(args.tbbroot, 'build', args.build_prefix+'_preview_debug') + if not args.no_rebuild or not (os.path.isdir(preview_release_dir) and os.path.isdir(preview_debug_dir)): + run_make('tbb_build_prefix=%s_preview %s tbb_cpf=1 tbb'% (args.build_prefix, args.build_args)) + release_dirs = [release_dir, debug_dir, preview_release_dir, preview_debug_dir] + +filemap = OrderedDict() +def append_files(names, dst, paths=release_dirs): + global filemap + files = sum([glob(jp(d, f)) for d in paths for f in names], []) + filemap.update(dict(zip(files, [dst]*len(files)))) + + +if args.install_libs: + append_files([libpref+f+libext for f in tbb_names], dll_dir) + +if args.install_devel: + dll_files = [libpref+f+'_debug'+libext for f in tbb_names] # adding debug libraries + if not is_win or not args.msbuild: + dll_files += [libpref+"tbb_preview"+libext, libpref+"tbb_preview_debug"+libext] + if is_win: + dll_files += ['tbb*.pdb'] # copying debug info + if is_lin: + dll_files += ['libtbb*.so'] # copying linker scripts + # symlinks .so -> .so.2 should not be created instead + # since linking with -ltbb when using links can result in + # incorrect dependence upon unversioned .so files + append_files(dll_files, dll_dir) + if is_win: + append_files(['*.lib', '*.def'], lib_dir) # copying linker libs and defs + for rootdir, dirnames, filenames in os.walk(jp(args.tbbroot,'include')): + files = [f for f in filenames if not '.html' in f] + append_files(files, jp(inc_dir, rootdir.split('include')[1][1:]), paths=(rootdir,)) + + # Preparing CMake configuration files + cmake_build_dir = jp(args.tbbroot, 'build', args.build_prefix+'_release', 'cmake_configs') + assert system('cmake -DINSTALL_DIR=%s -DSYSTEM_NAME=%s -DTBB_VERSION_FILE=%s -DINC_REL_PATH=%s -DLIB_REL_PATH=%s -DBIN_REL_PATH=%s -P %s' % \ + (cmake_build_dir, + platform.system(), + jp(args.tbbroot, 'include', 'tbb', 'tbb_stddef.h'), + os.path.relpath(inc_dir, cmake_dir), + os.path.relpath(lib_dir, cmake_dir), + os.path.relpath(bin_dir, cmake_dir), + jp(args.tbbroot, 'cmake', 'tbb_config_installer.cmake'))) == 0 + append_files(['TBBConfig.cmake', 'TBBConfigVersion.cmake'], cmake_dir, paths=[cmake_build_dir]) + +if args.install_python: # RML part + irml_dir = jp(args.tbbroot, 'build', args.build_prefix+'_release') + run_make('-C src tbb_build_prefix=%s %s python_rml'% (args.build_prefix, args.build_args)) + if is_lin: + append_files(['libirml.so.1'], dll_dir, paths=[irml_dir]) + +if args.install_docs: + files = [ + 'CHANGES', + 'LICENSE', + 'README', + 'README.md', + 'Release_Notes.txt', + ] + append_files(files, doc_dir, paths=release_dirs+[jp(args.tbbroot, d) for d in ('.', 'doc')]) + +for f in filemap.keys(): + assert os.path.exists(f) + assert os.path.isfile(f) + +if filemap: + print("Copying to prefix =", args.prefix) +for f, dest in filemap.items(): + if not os.path.isdir(dest): + os.makedirs(dest) + print("+ %s to $prefix%s"%(f,dest.replace(args.prefix, ''))) + install_cp(f, dest) + +if args.install_python: # Python part + paths = [os.path.abspath(d) for d in [args.prefix, inc_dir, irml_dir, lib_dir]+release_dirs] + os.environ["TBBROOT"] = paths[0] + # all the paths must be relative to python/ directory or be absolute + assert system('python python/setup.py build -b%s build_ext -I%s -L%s install -f'% \ + (paths[2], paths[1], ':'.join(paths[2:]))) == 0 + +print("done") diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/codecov.txt b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/codecov.txt new file mode 100644 index 00000000..e22f8059 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/codecov.txt @@ -0,0 +1,7 @@ +src/tbb +src/tbbmalloc +include/tbb +src/rml/server +src/rml/client +src/rml/include +source/malloc diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/common.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/common.inc new file mode 100644 index 00000000..815fa682 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/common.inc @@ -0,0 +1,170 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifndef tbb_os + + # Windows sets environment variable OS; for other systems, ask uname + ifeq ($(OS),) + OS:=$(shell uname) + ifeq ($(OS),) + $(error "Cannot detect operating system") + endif + export tbb_os=$(OS) + endif + + ifeq ($(OS), Windows_NT) + export tbb_os=windows + endif + ifeq ($(OS), Linux) + export tbb_os=linux + endif + ifeq ($(OS), Darwin) + export tbb_os=macos + endif + +endif # !tbb_os + +ifeq (1,$(tbb_cpf)) + export CPF_SUFFIX ?=_preview +endif + +ifeq (0,$(exceptions)) +# Inverse the value, for simplicity of use + export no_exceptions=1 +endif + +ifdef cpp0x + $(warning "Warning: deprecated cpp0x=$(cpp0x) is used, stdver must be used instead. Building in stdver=c++0x mode.") + export stdver?=c++0x + override cpp0x= +endif + +# Define C & C++ compilers according to platform defaults or CXX & CC environment variables +ifneq (,$(findstring environment, $(origin CXX))) + CPLUS = $(CXX) +endif +ifneq (,$(findstring environment, $(origin CC))) + CONLY = $(CC) +endif + +ifneq (,$(stdver)) + ifeq (,$(findstring ++, $(stdver))) + $(warning "Warning: unexpected stdver=$(stdver) is used.") + endif + CXX_STD_FLAGS=-std=$(stdver) +endif + +# The requested option is added unconditionally. +# If it is not supported, a compiler warning or error is expected. +# Note that CXX_STD_FLAGS can be changed in ..inc. +CXX_ONLY_FLAGS+=$(CXX_STD_FLAGS) + +ifeq (,$(wildcard $(tbb_root)/build/$(tbb_os).inc)) + $(error "$(tbb_os)" is not supported. Add build/$(tbb_os).inc file with os-specific settings ) +endif + +# detect arch and runtime versions, provide common host-specific definitions +include $(tbb_root)/build/$(tbb_os).inc + +ifeq ($(arch),) + $(error Architecture not detected) +endif +ifeq ($(runtime),) + $(error Runtime version not detected) +endif + +# process target-dependent compilation and testing configurations +ifdef target + # optionally process target-dependent options for compilation and testing + ifneq (,$(wildcard $(tbb_root)/build/$(target).inc)) + include $(tbb_root)/build/$(target).inc + endif + + # optionally process host-dependent environment for target-dependent compilation and testing + ifneq (,$(wildcard $(tbb_root)/build/$(target).$(tbb_os).inc)) + include $(tbb_root)/build/$(target).$(tbb_os).inc + endif + + # insure at least one target-dependent configuration file was found for compilation and testing + ifeq (,$(wildcard $(tbb_root)/build/$(target).inc)$(wildcard $(tbb_root)/build/$(target).$(tbb_os).inc)) + $(error "$(target)" is not supported. Add build/$(target).inc or build/$(target).$(tbb_os).inc file) + endif +endif #target + +# Support for running debug tests to release library and vice versa +flip_cfg=$(subst _flipcfg,_release,$(subst _release,_debug,$(subst _debug,_flipcfg,$(1)))) +cross_cfg = $(if $(crosstest),$(call flip_cfg,$(1)),$(1)) +# Setting default configuration to release +cfg?=release + +compiler_name=$(notdir $(compiler)) +ifdef BUILDING_PHASE + ifndef target + target:=$(tbb_os) + endif + # process host/target compiler-dependent build configuration + ifeq (,$(wildcard $(tbb_root)/build/$(target).$(compiler_name).inc)) + $(error "$(compiler_name)" is not supported on $(target). Add build/$(target).$(compiler_name).inc file with compiler-specific settings. ) + endif + include $(tbb_root)/build/$(target).$(compiler_name).inc +endif + +ifneq ($(BUILDING_PHASE),1) + # definitions for top-level Makefiles + origin_build_dir:=$(origin tbb_build_dir) + tbb_build_dir?=$(tbb_root)$(SLASH)build + export tbb_build_prefix?=$(tbb_os)_$(arch)_$(compiler_name)_$(runtime)$(CPF_SUFFIX) + work_dir=$(tbb_build_dir)$(SLASH)$(tbb_build_prefix) +endif # BUILDING_PHASE != 1 + +ifdef offload + extra_inc=$(offload).offload.inc +endif +ifdef extra_inc + ifneq (,$(wildcard $(tbb_root)/build/$(extra_inc))) + include $(tbb_root)/build/$(extra_inc) + else + $(error specified build file: "build/$(extra_inc)" is not found. ) + endif +endif + +ifndef BUILDING_PHASE + work_dir:=$(work_dir) + # assign new value for tbb_root if path is not absolute (the filter keeps only /* paths) + ifeq ($(filter /% $(SLASH)%, $(subst :, ,$(tbb_root)) ),) + full_tbb_root:=$(CURDIR)/$(tbb_root) + ifeq ($(origin_build_dir),undefined) + #relative path are needed here as a workaround to support whitespaces in path + override tbb_root:=../.. + else + override tbb_root:=$(full_tbb_root) + endif + export tbb_root + endif + endif # !BUILDING_PHASE + +.DELETE_ON_ERROR: # Make will delete target if error occurred when building it. + +# MAKEOVERRIDES contains the command line variable definitions. Resetting it to +# empty allows propagating all exported overridden variables to nested makes. +# NOTEs: +# 1. All variable set in command line are propagated to nested makes. +# 2. All variables declared with the "export" keyword are propagated to +# nested makes. +# 3. "override" allows changing variables set in command line. But it doesn't +# propagate new values to nested makes. For propagation, the "export" keyword +# should be used. +# 4. gmake v3.80 doesn't support exporting of target-specific variables using +# the "export" keyword +MAKEOVERRIDES = diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/common_rules.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/common_rules.inc new file mode 100644 index 00000000..64bd74ab --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/common_rules.inc @@ -0,0 +1,169 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +ifeq ($(tbb_strict),1) + ifeq ($(WARNING_AS_ERROR_KEY),) + $(error WARNING_AS_ERROR_KEY is empty) + endif + # Do not remove line below! + WARNING_KEY += $(WARNING_AS_ERROR_KEY) +endif + +ifneq (,$(findstring s,$(MAKEFLAGS))) + override largs+=-q +endif +ifneq (,$(repeat)) + override largs+=-r $(repeat) +endif +ifneq (,$(largs)$(run_prefix)) + override run_cmd:=$(run_cmd) $(TEST_LAUNCHER) + TEST_LAUNCHER= + ifeq (,$(strip $(run_cmd))) + $(warning Test launcher is not defined for the platform, ignoring launcher arguments) + endif +endif + +ifndef TEST_EXT + TEST_EXT = exe +endif + +INCLUDES += $(INCLUDE_KEY)$(tbb_root)/src $(INCLUDE_KEY)$(tbb_root)/src/rml/include $(INCLUDE_KEY)$(tbb_root)/include + +CPLUS_FLAGS += $(WARNING_KEY) $(CXXFLAGS) + +# Suppress warnings about usage of deprecated content +CPLUS_FLAGS += $(DEFINE_KEY)TBB_SUPPRESS_DEPRECATED_MESSAGES=1 + +ifeq (1,$(tbb_cpf)) +CPLUS_FLAGS += $(DEFINE_KEY)__TBB_CPF_BUILD=1 +endif +ifeq (0,$(exceptions)) +CPLUS_FLAGS += $(DEFINE_KEY)TBB_USE_EXCEPTIONS=0 +endif +LINK_FLAGS += $(LDFLAGS) +LIB_LINK_FLAGS += $(LDFLAGS) + +LIB_LINK_CMD ?= $(CPLUS) $(PIC_KEY) +ifeq ($(origin LIB_OUTPUT_KEY), undefined) + LIB_OUTPUT_KEY = $(OUTPUT_KEY) +endif +ifeq ($(origin LIB_LINK_LIBS), undefined) + LIB_LINK_LIBS = $(LIBDL) $(LIBS) +endif + +# some platforms do not provide separate C-only compiler +CONLY ?= $(CPLUS) + +# The most generic rules +#$(1) - is the target pattern +define make-cxx-obj +$1: %.cpp + $$(CPLUS) $$(OUTPUTOBJ_KEY)$$@ $$(COMPILE_ONLY) $$(CPLUS_FLAGS) $$(CXX_ONLY_FLAGS) $$(CXX_WARN_SUPPRESS) $$(INCLUDES) $$< +endef + +TEST_AFFIXES_OBJS=$(addsuffix .$(OBJ),$(addprefix %_,$(TEST_SUFFIXES)) $(addsuffix _%,$(TEST_PREFIXES))) + +# Make will not process the same recipe for each test pattern (since the dependency on the same %.cpp) +# thus the separated recipes should be provided +$(foreach t,%.$(OBJ) $(TEST_AFFIXES_OBJS),$(eval $(call make-cxx-obj,$(t)))) + +.PRECIOUS: %.$(OBJ) %.$(TEST_EXT) %.res $(TEST_AFFIXES_OBJS) + +# Rules for generating a test DLL +%_dll.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(OUTPUTOBJ_KEY)$@ $(CPLUS_FLAGS) $(PIC_KEY) $(DEFINE_KEY)_USRDLL $(INCLUDES) $< + +#$(1) - is the binary name +#$(2) - is the input obj files and libraries +define make-test-binary + $(CPLUS) $(OUTPUT_KEY)$(strip $1) $(CPLUS_FLAGS) $(2) $(LIBS) $(LINK_FLAGS) +endef + +# LINK_FILES the list of options to link test specific files (libraries and object files) +LINK_FILES+=$(TEST_LIBS) +# Rule for generating executable test +%.$(TEST_EXT): %.$(OBJ) $(TEST_LIBS) $(TEST_PREREQUISITE) $(if $(use_proxy),$(PROXY.LIB)) + $(call make-test-binary,$@,$< $(LINK_FILES) $(PIE_FLAG)) + +# Rules for generating a test DLL +%_dll.$(DLL): LINK_FLAGS += $(PIC_KEY) $(DYLIB_KEY) +%_dll.$(DLL): TEST_LIBS := $(subst %_dll.$(DLL),,$(TEST_LIBS)) +%_dll.$(DLL): %_dll.$(OBJ) + $(call make-test-binary,$@,$< $(LINK_FILES)) +.PRECIOUS: %_dll.$(OBJ) %_dll.$(DLL) + +%.$(OBJ): %.c + $(CONLY) $(COMPILE_ONLY) $(OUTPUTOBJ_KEY)$@ $(C_FLAGS) $(INCLUDES) $< + +%.$(OBJ): %.asm + $(ASM) $(ASM_FLAGS) $< + +%.$(OBJ): %.s + cpp <$< | grep -v '^#' >$*.tmp + $(ASM) $(ASM_FLAGS) -o $@ $*.tmp + +# Rule for generating .E file if needed for visual inspection +# Note that ICL treats an argument after PREPROC_ONLY as a file to open, +# so all uses of PREPROC_ONLY should be immediately followed by a file name +%.E: %.cpp + $(CPLUS) $(CPLUS_FLAGS) $(CXX_ONLY_FLAGS) $(INCLUDES) $(PREPROC_ONLY) $< >$@ + +# TODO Rule for generating .asm file if needed for visual inspection +%.asm: %.cpp + $(CPLUS) /c /FAs /Fa $(CPLUS_FLAGS) $(CXX_ONLY_FLAGS) $(INCLUDES) $< + +# TODO Rule for generating .s file if needed for visual inspection +%.s: %.cpp + $(CPLUS) -S $(CPLUS_FLAGS) $(CXX_ONLY_FLAGS) $(INCLUDES) $< + +# Customizations +$(KNOWN_WARNINGS): %.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(subst $(WARNING_KEY),,$(CPLUS_FLAGS)) $(CXX_ONLY_FLAGS) $(CXX_WARN_SUPPRESS) $(INCLUDES) $< + +tbb_misc.$(OBJ): version_string.ver +tbb_misc.$(OBJ): INCLUDES+=$(INCLUDE_KEY). + +tbb_misc.E: tbb_misc.cpp version_string.ver + $(CPLUS) $(CPLUS_FLAGS) $(CXX_ONLY_FLAGS) $(INCLUDE_KEY). $(INCLUDES) $(PREPROC_ONLY) $< >$@ + +%.res: %.rc version_string.ver $(TBB.MANIFEST) + rc /Fo$@ $(INCLUDES) $(filter /D%,$(CPLUS_FLAGS)) $< + +# TODO: add $(LIB_LINK_LIBS) $(LIB_LINK_FLAGS) (in a separate line?) and remove useless $(INCLUDES) +VERSION_FLAGS=$(CPLUS) $(CPLUS_FLAGS) $(CXX_ONLY_FLAGS) $(INCLUDES) + +ifneq (,$(TBB.MANIFEST)) +$(TBB.MANIFEST): + cmd /C "echo #include ^ >tbbmanifest.c" + cmd /C "echo int main(){return 0;} >>tbbmanifest.c" + cl /nologo $(C_FLAGS) tbbmanifest.c + +version_string.ver: $(TBB.MANIFEST) + $(MAKE_VERSIONS) + cmd /C "echo #define TBB_MANIFEST 1 >> version_string.ver" +# TODO: fix parallel build by writing to a temporary file and rename it when complete +else +# TODO: make version strings directly representative for all the libraries +version_string.ver: + $(MAKE_VERSIONS) +endif + +test_% debug_%: test_%.$(TEST_EXT) $(TEST_PREREQUISITE) + $(run_cmd) ./$< $(args) +ifneq (,$(codecov)) + profmerge + codecov $(if $(findstring -,$(codecov)),$(codecov),) -demang -comp $(tbb_root)/build/codecov.txt +endif + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/detect.js b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/detect.js new file mode 100644 index 00000000..ef8ccc15 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/detect.js @@ -0,0 +1,203 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +function readAllFromFile(fname) { + var fso = new ActiveXObject("Scripting.FileSystemObject"); + var file = null; + try { + file = fso.OpenTextFile(fname, 1, 0); + return (file.readAll()); + } finally { + // Close the file in the finally section to guarantee that it will be closed in any case + // (if the exception is thrown or not). + file.Close(); + } +} + +function doWork() { + var WshShell = WScript.CreateObject("WScript.Shell"); + + var tmpExec = WshShell.Run("cmd /c echo int main(){return 0;} >detect.c", 0, true); + + // The next block deals with GCC (MinGW) + if (WScript.Arguments.Count() > 1) { + var compilerPath = WScript.Arguments(1); + // The RegExp matches everything up to and including the last slash (it uses a greedy approach.) + var compilerName = compilerPath.replace(/^.*[\/\\]/, ""); + if (compilerName.match(/gcc/i) != null) { + if (WScript.Arguments(0) == "/arch") { + // Get predefined macros + tmpExec = WshShell.Run("cmd /C " + compilerPath + " -dM -E detect.c > detect.map", 0, true); + var defs = readAllFromFile("detect.map"); + //detect target architecture + var intel64 = /x86_64|amd64/mgi; + var ia32 = /i386/mgi; + if (defs.match(intel64)) { + WScript.Echo("intel64"); + } else if (defs.match(ia32)) { + WScript.Echo("ia32"); + } else { + WScript.Echo("unknown"); + } + } else { + tmpExec = WshShell.Exec(compilerPath + " -dumpfullversion -dumpversion"); + var gccVersion = tmpExec.StdOut.ReadLine(); + if (WScript.Arguments(0) == "/runtime") { + WScript.Echo("mingw" + gccVersion); + } + else if (WScript.Arguments(0) == "/minversion") { + for (var i = 0; i < 3; i++) { + v1 = parseInt(gccVersion.split('.')[i]); + v2 = parseInt(WScript.Arguments(2).split('.')[i]); + + if (v1 > v2) { + break; + } else if (v1 < v2) { + WScript.Echo("fail"); + return; + } + } + WScript.Echo("ok"); + } + } + return; + } + } + + //Compile binary + tmpExec = WshShell.Exec("cl /MD detect.c /link /MAP"); + while (tmpExec.Status == 0) { + WScript.Sleep(100); + } + //compiler banner that includes version and target arch was printed to stderr + var clVersion = tmpExec.StdErr.ReadAll(); + + if (WScript.Arguments(0) == "/arch") { + //detect target architecture + var intel64 = /AMD64|EM64T|x64/mgi; + var ia32 = /[80|\s]x86/mgi; + var arm = /ARM/mgi; + if (clVersion.match(intel64)) { + WScript.Echo("intel64"); + } else if (clVersion.match(ia32)) { + WScript.Echo("ia32"); + } else if (clVersion.match(arm)) { + WScript.Echo("armv7"); + } else { + WScript.Echo("unknown"); + } + return; + } + + if (WScript.Arguments(0) == "/runtime") { + //read map-file + var mapContext = readAllFromFile("detect.map"); + //detect runtime + var vc71 = /MSVCR71\.DLL/mgi; + var vc80 = /MSVCR80\.DLL/mgi; + var vc90 = /MSVCR90\.DLL/mgi; + var vc100 = /MSVCR100\.DLL/mgi; + var vc110 = /MSVCR110\.DLL/mgi; + var vc120 = /MSVCR120\.DLL/mgi; + var vc140 = /VCRUNTIME140\.DLL/mgi; + var psdk = /MSVCRT\.DLL/mgi; + if (mapContext.match(vc71)) { + WScript.Echo("vc7.1"); + } else if (mapContext.match(vc80)) { + WScript.Echo("vc8"); + } else if (mapContext.match(vc90)) { + WScript.Echo("vc9"); + } else if (mapContext.match(vc100)) { + WScript.Echo("vc10"); + } else if (mapContext.match(vc110)) { + WScript.Echo("vc11"); + } else if (mapContext.match(vc120)) { + WScript.Echo("vc12"); + } else if (mapContext.match(vc140)) { + if (WshShell.ExpandEnvironmentStrings("%VisualStudioVersion%") == "15.0") + WScript.Echo("vc14.1"); + else if (WshShell.ExpandEnvironmentStrings("%VisualStudioVersion%") == "16.0") + WScript.Echo("vc14.2"); + else + WScript.Echo("vc14"); + } else { + WScript.Echo("unknown"); + } + return; + } + + if (WScript.Arguments(0) == "/minversion") { + var compilerVersion; + var compilerUpdate; + if (WScript.Arguments(1) == "cl") { + compilerVersion = clVersion.match(/Compiler Version ([0-9.]+)\s/mi)[1]; + // compilerVersion is in xx.xx.xxxxx.xx format, i.e. a string. + // It will compare well with major.minor versions where major has two digits, + // which is sufficient as the versions of interest start from 13 (for VC7). + } else if (WScript.Arguments(1) == "icl") { + // Get predefined ICL macros + tmpExec = WshShell.Run("cmd /C icl /QdM /E detect.c > detect.map", 0, true); + var defs = readAllFromFile("detect.map"); + // In #define __INTEL_COMPILER XXYY, XX is the major ICL version, YY is minor + compilerVersion = defs.match(/__INTEL_COMPILER[ \t]*([0-9]+).*$/mi)[1] / 100; + compilerUpdate = defs.match(/__INTEL_COMPILER_UPDATE[ \t]*([0-9]+).*$/mi)[1]; + // compiler version is a number; it compares well with another major.minor + // version number, where major has one, two, and perhaps more digits (9.1, 11, etc). + } + var requestedVersion = WScript.Arguments(2); + var requestedUpdate = 0; + if (WScript.Arguments.Count() > 3) + requestedUpdate = WScript.Arguments(3); + if (compilerVersion < requestedVersion) { + WScript.Echo("fail"); + } else if (compilerVersion == requestedVersion && compilerUpdate < requestedUpdate) { + WScript.Echo("fail"); + } else { + WScript.Echo("ok"); + } + return; + } +} + +function doClean() { + var fso = new ActiveXObject("Scripting.FileSystemObject"); + // delete intermediate files + if (fso.FileExists("detect.c")) + fso.DeleteFile("detect.c", false); + if (fso.FileExists("detect.obj")) + fso.DeleteFile("detect.obj", false); + if (fso.FileExists("detect.map")) + fso.DeleteFile("detect.map", false); + if (fso.FileExists("detect.exe")) + fso.DeleteFile("detect.exe", false); + if (fso.FileExists("detect.exe.manifest")) + fso.DeleteFile("detect.exe.manifest", false); +} + +if (WScript.Arguments.Count() > 0) { + + try { + doWork(); + } catch (error) { + WScript.Echo("unknown"); + } + doClean(); + +} else { + WScript.Echo("Supported options:\n" + + "\t/arch [compiler]\n" + + "\t/runtime [compiler]\n" + + "\t/minversion compiler version"); +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/generate_tbbvars.bat b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/generate_tbbvars.bat new file mode 100644 index 00000000..12173280 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/generate_tbbvars.bat @@ -0,0 +1,62 @@ +@echo off +REM +REM Copyright (c) 2005-2020 Intel Corporation +REM +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. +REM +setlocal +for %%D in ("%tbb_root%") do set actual_root=%%~fD +set fslash_root=%actual_root:\=/% +set bin_dir=%CD% +set fslash_bin_dir=%bin_dir:\=/% +set _INCLUDE=INCLUDE& set _LIB=LIB +if not x%UNIXMODE%==x set _INCLUDE=CPATH& set _LIB=LIBRARY_PATH +if not x%USE_INCLUDE_ENV%==x set _INCLUDE=INCLUDE + +echo Generating local tbbvars.bat +echo @echo off>tbbvars.bat +echo SET TBBROOT=%actual_root%>>tbbvars.bat +echo SET TBB_ARCH_PLATFORM=%arch%\%runtime%>>tbbvars.bat +echo SET TBB_TARGET_ARCH=%arch%>>tbbvars.bat +echo SET %_INCLUDE%=%%TBBROOT%%\include;%%%_INCLUDE%%%>>tbbvars.bat +echo SET %_LIB%=%bin_dir%;%%%_LIB%%%>>tbbvars.bat +echo SET PATH=%bin_dir%;%%PATH%%>>tbbvars.bat +if not x%UNIXMODE%==x echo SET LD_LIBRARY_PATH=%bin_dir%;%%LD_LIBRARY_PATH%%>>tbbvars.bat + +echo Generating local tbbvars.sh +echo #!/bin/sh>tbbvars.sh +echo export TBBROOT="%fslash_root%">>tbbvars.sh +echo export TBB_ARCH_PLATFORM="%arch%\%runtime%">>tbbvars.sh +echo export TBB_TARGET_ARCH="%arch%">>tbbvars.sh +echo export %_INCLUDE%="${TBBROOT}/include;$%_INCLUDE%">>tbbvars.sh +echo export %_LIB%="%fslash_bin_dir%;$%_LIB%">>tbbvars.sh +echo export PATH="%fslash_bin_dir%;$PATH">>tbbvars.sh +if not x%UNIXMODE%==x echo export LD_LIBRARY_PATH="%fslash_bin_dir%;$LD_LIBRARY_PATH">>tbbvars.sh + +echo Generating local tbbvars.csh +echo #!/bin/csh>tbbvars.csh +echo setenv TBBROOT "%actual_root%">>tbbvars.csh +echo setenv TBB_ARCH_PLATFORM "%arch%\%runtime%">>tbbvars.csh +echo setenv TBB_TARGET_ARCH "%arch%">>tbbvars.csh +echo setenv %_INCLUDE% "${TBBROOT}\include;$%_INCLUDE%">>tbbvars.csh +echo setenv %_LIB% "%bin_dir%;$%_LIB%">>tbbvars.csh +echo setenv PATH "%bin_dir%;$PATH">>tbbvars.csh +if not x%UNIXMODE%==x echo setenv LD_LIBRARY_PATH "%bin_dir%;$LD_LIBRARY_PATH">>tbbvars.csh + +if not x%LIB_STL_ANDROID%==x ( +REM Workaround for copying Android* specific stl shared library to work folder +copy /Y "%LIB_STL_ANDROID:/=\%" . +) + +endlocal +exit diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/generate_tbbvars.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/generate_tbbvars.sh new file mode 100644 index 00000000..4106ed3f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/generate_tbbvars.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script used to generate tbbvars.[c]sh scripts +bin_dir="$PWD" # +cd "$tbb_root" # keep this comments here +tbb_root="$PWD" # to make it unsensible +cd "$bin_dir" # to EOL encoding +cat >./tbbvars.sh <./tbbvars.csh < + + +

Overview

+This directory contains the internal Makefile infrastructure for Intel® Threading Building Blocks (Intel® TBB). + +

+See below for how to build Intel TBB and how to port Intel TBB +to a new platform, operating system or architecture. +

+ +

Files

+The files here are not intended to be used directly. See below for usage. +
+
Makefile.tbb +
Main Makefile to build the Intel TBB library. + Invoked via 'make tbb' from top-level Makefile. +
Makefile.tbbmalloc +
Main Makefile to build the Intel TBB scalable memory allocator library as well as its tests. + Invoked via 'make tbbmalloc' from top-level Makefile. +
Makefile.tbbbind +
Main Makefile to build the tbbbind library. + Invoked via 'make tbbbind' from top-level Makefile +
Makefile.test +
Main Makefile to build and run the tests for the Intel TBB library. + Invoked via 'make test' from top-level Makefile. +
common.inc +
Main common included Makefile that includes OS-specific and compiler-specific Makefiles. +
<os>.inc +
OS-specific Makefile for a particular <os>. +
<os>.<compiler>.inc +
Compiler-specific Makefile for a particular <os> / <compiler> combination. +
*.sh +
Infrastructure utilities for Linux* OS, macOS*, and UNIX*-related operating systems. +
*.js, *.bat +
Infrastructure utilities for Windows* OS. +
+ +

To Build

+

+To port Intel TBB to a new platform, operating system or architecture, see the porting directions below. +

+ +

Software prerequisites:

+
    +
  1. C++ compiler for the platform, operating system and architecture of interest. + Either the native compiler for your system, or, optionally, the appropriate Intel® C++ Compiler, may be used. +
  2. GNU make utility. On Windows OS, if a UNIX* emulator is used to run GNU make, + it should be able to run Windows OS utilities and commands. On Linux OS, macOS, etc., + shell commands issued by GNU make should execute in a Bourne or BASH compatible shell. + In the following examples, replace make with the correct GNU make command for + your system (for example, gmake). GNU make version 3.80 and more recent are supported. +
+ +

+Intel TBB libraries can be built by performing the following steps. +On systems that support only one ABI (e.g., 32-bit), these steps build the libraries for that ABI. +On systems that support both 64-bit and 32-bit libraries, these steps build the 64-bit libraries +(Linux OS, macOS, and related systems) or whichever ABI is selected in the development environment (Windows OS). +

+
    +
  1. Change to the top-level directory of the installed software. +
  2. If using the Intel® C++ Compiler, make sure the appropriate compiler is available in your PATH + (e.g., by sourcing the appropriate iccvars script for the compiler to be used). +
  3. Invoke GNU make using no arguments, for example, make. +
+ +

+To build Intel TBB libraries for other than the default ABI (e.g., to build 32-bit libraries on Linux OS, macOS, +or related systems that support both 64-bit and 32-bit libraries), perform the following steps: +

+
    +
  1. Change to the top-level directory of the installed software. +
  2. If using the Intel® C++ Compiler, make sure the appropriate compiler is available in your PATH + (e.g., by sourcing the appropriate iccvars script for the compiler to be used). +
  3. Explicitly specify the architecture when invoking GNU make, e.g. make arch=ia32. +
+ +

The default make target will build the release version of the Intel TBB library.

+

Other targets are available in the top-level Makefile. You might find the following targets useful: +

    +
  • make test will build and run Intel TBB unit-tests; +
  • make examples will build and run Intel TBB examples. Available in the open-source version only. +For the commercial version, you can download Intel TBB Samples at the Intel® Software Product Samples and Tutorials website; +
  • make all will do all of the above. Available in the open-source version only. +
+See also the list of other targets below. +

+ +

+By default, the libraries will be built in sub-directories within the build/ directory. +The sub-directories are named according to the operating system, architecture, compiler and software environment used +(the sub-directory names also distinguish release vs. debug libraries). On Linux OS, the software environment comprises +the GCC, libc and kernel version used. On macOS, the software environment comprises the GCC and OS version used. +On Windows OS, the software environment comprises the Microsoft* Visual Studio* version used. +See below for how to change the default build directory. +

+ +

+To perform different build and/or test operations, use the following steps. +

+
    +
  1. Change to the top-level directory of the installed software. +
  2. If using the Intel® C++ Compiler, make sure the appropriate compiler is available in your PATH + (e.g., by sourcing the appropriate iccvars script for the compiler to be used). +
  3. Invoke GNU make by using one or more of the following commands. +
    +
    make +
    Default build. Equivalent to make tbb tbbmalloc. +
    make all +
    Equivalent to make tbb tbbmalloc test examples. Available in the open-source version only. +
    cd src;make release +
    Build and test release libraries only. +
    cd src;make debug +
    Build and test debug libraries only. +
    make tbb +
    Make Intel TBB release libraries. +
    make tbbmalloc +
    Make Intel TBB scalable memory allocator libraries. +
    make tbbbind +
    Make the tbbbind library. +
    make test +
    Compile and run unit-tests +
    make examples +
    Build libraries and run all examples, like doing make clean release from the general example Makefile. + Available in the open-source version only. +
    make python +
    Build, install, and test Python* API for Intel TBB. See details here. +
    make compiler={icl, icc, gcc, clang} [(above options or targets)] +
    Build and run as above, but use specified compilers instead of default, native compilers +
      +
    1. {icl, icc} - to use Intel® compilers (icl on Windows OS, icc on Linux OS or macOS).
    2. +
    3. gcc - to use g++ (e.g. MinGW on Windows OS)
    4. +
    5. clang - to use Clang compiler
    6. +
    +
    make compiler=clang stdlib=libc++ [(above options or targets)] +
    Build and run as above, but use libc++ as a standard c++ library for clang. +
    make stdver={c++11, c++14, ...} [(above options or targets)] +
    Build and run as above, but additionally specify the version of the C++ standard or dialect to be used by + the compiler. The specified value of stdver will be used as a parameter to the appropriate + compiler option (such as -std); the behavior in case of unsupported value is compiler-specific. +
    make target_app={win8ui, uwp, uwd} [target_mode=store] [(above options or targets)] +
    Build and run as above, but use API that is compliant with Universal Windows* applications. Use win8ui option, if you want to use Intel TBB in Windows* 8 Universal application, uwp in case of Windows* 10 Universal Windows application and uwd for the usage inside Universal Windows* driver. + target_mode=store is used to produce binaries that are compliant with Windows Store* application container. In later case they won't work with Intel TBB unit tests but work only with Windows Store* applications. +
    ndk-build target=android [(above options or targets)] +
    Build and run as above, but build libraries for Android* OS by Android NDK that should be installed. Makefiles were tested with revision 8. +
    make arch={ia32, intel64, ia64} [(above options or targets)] +
    Build and run as above, but build libraries for the selected ABI. + Might be useful for cross-compilation; ensure proper environment is set before running this command. +
    make tbb_root={(Intel TBB directory)} [(above options or targets)] +
    Build and run as above; for use when invoking make from a directory other than the top-level directory. +
    make tbb_build_dir={(build directory)} [(above options or targets)] +
    Build and run as above, but place the built libraries in the specified directory, rather than in the default sub-directory within the build/ directory. This command might have troubles with the build in case the sources installed to the directory with spaces in the path. +
    make tbb_build_prefix={(build sub-directory)} [(above options or targets)] +
    Build and run as above, but place the built libraries in the specified sub-directory within the build/ directory, rather than using the default sub-directory name. +
    make tbb_cpf=1 [(above options or targets)] +
    Build and run as above, but build and use libraries with the Community Preview Features enabled, rather than the default libraries. +
    make [(above options)] clean +
    Remove any executables or intermediate files produced by the above commands. + Includes build directories, object files, libraries and test executables. +
    +
+ +

To Port

+

+This section provides information on how to port Intel TBB to a new platform, operating system or architecture. +A subset or a superset of these steps may be required for porting to a given platform. +

+ +

To port the Intel TBB source code:

+
    +
  1. If porting to a new architecture, create a file that describes the architecture-specific details for that architecture. +
      +
    • Create a <os>_<architecture>.h file in the include/tbb/machine directory + that describes these details. +
        +
      • The <os>_<architecture>.h is named after the operating system and architecture as recognized by + include/tbb/tbb_machine.h and the Makefile infrastructure. +
      • This file defines the implementations of synchronization operations, and also the + scheduler yield function, for the operating system and architecture. +
      • Several examples of <os>_<architecture>.h files can be found in the + include/tbb/machine directory. +
          +
        • A minimal implementation defines the 4-byte and 8-byte compare-and-swap operations, + and the scheduler yield function. See include/tbb/machine/mac_ppc.h + for an example of a minimal implementation. +
        • More complex implementation examples can also be found in the + include/tbb/machine directory + that implement all the individual variants of synchronization operations that Intel TBB uses. + Such implementations are more verbose but may achieve better performance on a given architecture. +
        • In a given implementation, any synchronization operation that is not defined is implemented, by default, + in terms of 4-byte or 8-byte compare-and-swap. More operations can thus be added incrementally to increase + the performance of an implementation. +
        • In most cases, synchronization operations are implemented as inline assembly code; examples also exist, + (e.g., for Intel® Itanium® processors) that use out-of-line assembly code in *.s or *.asm files + (see the assembly code sub-directories in the src/tbb directory). +
        +
      +
    • Modify include/tbb/tbb_machine.h, if needed, to invoke the appropriate + <os>_<architecture>.h file in the include/tbb/machine directory. +
    +
  2. Add an implementation of DetectNumberOfWorkers() in src/tbb/tbb_misc.h, + that returns the number of cores found on the system in case it is not supported by the current implementation. + This is used to determine the default number of threads for the Intel TBB task scheduler. +
  3. Either properly define FillDynamicLinks for use in + src/tbb/cache_aligned_allocator.cpp, + or hardcode the allocator to be used. +
  4. Additional types might be required in the union defined in + include/tbb/aligned_space.h + to ensure proper alignment on your platform. +
  5. Changes may be required in include/tbb/tick_count.h + for systems that do not provide gettimeofday. +
+ +

To port the Makefile infrastructure:

+Modify the appropriate files in the Makefile infrastructure to add a new platform, operating system or architecture as needed. +See the Makefile infrastructure files for examples. +
    +
  1. The top-level Makefile includes common.inc to determine the operating system. +
      +
    • To add a new operating system, add the appropriate test to common.inc, and create the needed <os>.inc and <os>.<compiler>.inc files (see below). +
    +
  2. The <os>.inc file makes OS-specific settings for a particular operating systems. +
      +
    • For example, linux.inc makes settings specific to Linux operating systems. +
    • This file performs OS-dependent tests to determine the specific platform and/or architecture, and sets other platform-dependent values. +
    • Add a new <os>.inc file for each new operating system added. +
    +
  3. The <os>.<compiler>.inc file makes compiler-specific settings for a particular + <os> / <compiler> combination. +
      +
    • For example, linux.gcc.inc makes specific settings for using GCC on Linux OS, and linux.icc.inc makes specific settings for using the Intel® C++ compiler on Linux OS. +
    • This file sets particular compiler, assembler and linker options required when using a particular <os> / <compiler> combination. +
    • Add a new <os>.<compiler>.inc file for each new <os> / <compiler> combination added. +
    +
+ +
+Up to parent directory +

+Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +

+Intel, the Intel logo and Itanium are trademarks of Intel Corporation or its subsidiaries in the U.S. and/or other countries. +

+* Other names and brands may be claimed as the property of others. + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/ios.clang.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/ios.clang.inc new file mode 100644 index 00000000..a97aad59 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/ios.clang.inc @@ -0,0 +1,15 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include $(tbb_root)/build/macos.clang.inc diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/ios.macos.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/ios.macos.inc new file mode 100644 index 00000000..04f0c090 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/ios.macos.inc @@ -0,0 +1,34 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifneq ($(arch),$(filter $(arch),ia32 intel64 armv7 armv7s arm64)) + $(error $(arch) is unknown architecture. Known arhitechtures are ia32 intel64 armv7 armv7s arm64) +endif + +# If target is ios but arch is ia32/intel64 then build for 32/64 simulator! +ifeq (,$(SDKROOT)) + ifeq ($(arch),$(filter $(arch),ia32 intel64)) + export SDKROOT:=$(shell xcodebuild -sdk -version | grep -o -E '/.*SDKs/iPhoneSimulator.*' 2>/dev/null) + else + export SDKROOT:=$(shell xcodebuild -sdk -version | grep -o -E '/.*SDKs/iPhoneOS.*' 2>/dev/null) + endif +endif +ifeq (,$(SDKROOT)) + $(error iOS* SDK not found) +endif + +ios_version:=$(shell echo $(SDKROOT) | sed -e "s/.*[a-z,A-Z]\(.*\).sdk/\1/") +runtime:=cc$(clang_version)_ios$(ios_version) + +IPHONEOS_DEPLOYMENT_TARGET ?= 8.0 diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.clang.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.clang.inc new file mode 100644 index 00000000..330e090a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.clang.inc @@ -0,0 +1,115 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CPLUS ?= clang++ +CONLY ?= clang +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall -Wextra +TEST_WARNING_KEY = -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor +WARNING_SUPPRESS = -Wno-parentheses -Wno-non-virtual-dtor -Wno-dangling-else +DYLIB_KEY = -shared +EXPORT_KEY = -Wl,--version-script, +LIBDL = -ldl + +LIB_LINK_FLAGS = $(DYLIB_KEY) -Wl,-soname=$(BUILDING_LIBRARY) +LIBS += -lrt +LINK_FLAGS = -Wl,-rpath-link=. -rdynamic +C_FLAGS = $(CPLUS_FLAGS) + +ifeq ($(cfg), release) + # -g is set intentionally in the release mode. It should not affect performance. + CPLUS_FLAGS = -O2 +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -DTBB_USE_DEBUG -O0 -g +endif + +CPLUS_FLAGS += $(ITT_NOTIFY) -DUSE_PTHREAD -pthread +LIB_LINK_FLAGS += -pthread + +ifneq (,$(stdlib)) + CPLUS_FLAGS += -stdlib=$(stdlib) + LIB_LINK_FLAGS += -stdlib=$(stdlib) +endif + +ifneq (,$(gcc_version)) + # TODO: do not assume that GCC minor and patchlevel versions are always single-digit. + CPLUS_FLAGS += -DTBB_USE_GLIBCXX_VERSION=$(subst .,0,$(gcc_version)) +endif + +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ifeq (intel64,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m32 -march=pentium4 + LIB_LINK_FLAGS += -m32 +endif + +ifeq (ppc64,$(arch)) + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ppc32,$(arch)) + CPLUS_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +endif + +ifeq (bg,$(arch)) + CPLUS = bgclang++ + CONLY = bgclang +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASM = as +ifeq (intel64,$(arch)) + ASM_FLAGS += --64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += --32 +endif +ifeq ($(cfg),debug) + ASM_FLAGS += -g +endif + +ASSEMBLY_SOURCE=$(arch)-gas +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.gcc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.gcc.inc new file mode 100644 index 00000000..d820c15d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.gcc.inc @@ -0,0 +1,156 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CPLUS ?= g++ +CONLY ?= gcc +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +TEST_WARNING_KEY = -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor + +WARNING_SUPPRESS = -Wno-parentheses +DYLIB_KEY = -shared +EXPORT_KEY = -Wl,--version-script, +LIBDL = -ldl + +LIB_LINK_FLAGS = $(DYLIB_KEY) -Wl,-soname=$(BUILDING_LIBRARY) +LIBS += -lrt +LINK_FLAGS = -Wl,-rpath-link=. -rdynamic +C_FLAGS = $(CPLUS_FLAGS) + +# gcc 4.2 and higher support OpenMP +ifneq (,$(shell $(CONLY) -dumpfullversion -dumpversion | egrep "^(4\.[2-9]|[5-9]|1[0-9])")) + OPENMP_FLAG = -fopenmp +endif + +# gcc 4.8 and later support RTM intrinsics, but require command line switch to enable them +ifneq (,$(shell $(CONLY) -dumpfullversion -dumpversion | egrep "^(4\.[8-9]|[5-9]|1[0-9])")) + RTM_KEY = -mrtm +endif + +# gcc 4.0 and later have -Wextra that is used by some our customers. +ifneq (,$(shell $(CONLY) -dumpfullversion -dumpversion | egrep "^([4-9]|1[0-9])")) + WARNING_KEY += -Wextra +endif + +# gcc 5.0 and later have -Wsuggest-override and -Wno-sized-deallocation options +ifneq (,$(shell $(CONLY) -dumpfullversion -dumpversion | egrep "^([5-9]|1[0-9])")) + # enable -Wsuggest-override via a pre-included header in order to limit to C++11 and above + INCLUDE_TEST_HEADERS = -include $(tbb_root)/src/test/harness_preload.h + WARNING_SUPPRESS += -Wno-sized-deallocation +endif + +# gcc 6.0 and later have -flifetime-dse option that controls +# elimination of stores done outside the object lifetime +ifneq (,$(shell $(CONLY) -dumpfullversion -dumpversion | egrep "^([6-9]|1[0-9])")) + # keep pre-contruction stores for zero initialization + DSE_KEY = -flifetime-dse=1 +endif + +ifeq ($(cfg), release) + # -g is set intentionally in the release mode. It should not affect performance. + CPLUS_FLAGS = -O2 -g +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -DTBB_USE_DEBUG -O0 -g +endif + +CPLUS_FLAGS += $(ITT_NOTIFY) -DUSE_PTHREAD -pthread +LIB_LINK_FLAGS += -pthread + +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ifeq (ia64,$(arch)) +# Position-independent code (PIC) is a must on IA-64 architecture, even for regular (not shared) executables + CPLUS_FLAGS += $(PIC_KEY) +endif + +ifeq (intel64,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m64 $(RTM_KEY) + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m32 -march=pentium4 $(RTM_KEY) + LIB_LINK_FLAGS += -m32 +endif + +ifeq (ppc64,$(arch)) + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ppc32,$(arch)) + CPLUS_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +endif + +ifeq (bg,$(arch)) + CPLUS = $(firstword $(notdir $(shell which powerpc{64,32,}-bg{z..a}-linux-g++ 2>/dev/null))) + CONLY = $(firstword $(notdir $(shell which powerpc{64,32,}-bg{z..a}-linux-gcc 2>/dev/null))) +endif + +# for some gcc versions on Solaris, -m64 may imply V9, but perhaps not everywhere (TODO: verify) +ifeq (sparc,$(arch)) + CPLUS_FLAGS += -mcpu=v9 -m64 + LIB_LINK_FLAGS += -mcpu=v9 -m64 +endif + +# automatically generate "IT" instructions when compiling for Thumb ISA +ifeq (armv7,$(arch)) + CPLUS_FLAGS += -Wa,-mimplicit-it=thumb +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASM = as +ifeq (intel64,$(arch)) + ASM_FLAGS += --64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += --32 +endif +ifeq ($(cfg),debug) + ASM_FLAGS += -g +endif + +ASSEMBLY_SOURCE=$(arch)-gas +ifeq (ia64,$(arch)) + ASM_FLAGS += -xexplicit + TBB_ASM.OBJ += atomic_support.o lock_byte.o log2.o pause.o ia64_misc.o + MALLOC_ASM.OBJ += atomic_support.o lock_byte.o pause.o log2.o +endif +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.icc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.icc.inc new file mode 100644 index 00000000..2367623d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.icc.inc @@ -0,0 +1,118 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CPLUS ?= icpc +CONLY ?= icc +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -w1 +DYLIB_KEY = -shared +EXPORT_KEY = -Wl,--version-script, +NOINTRINSIC_KEY = -fno-builtin +LIBDL = -ldl +ifneq (,$(shell icc -dumpversion | egrep "1[2-9]\.")) +SDL_FLAGS = -fstack-protector -Wformat -Wformat-security +endif + +ITT_NOTIFY = -DDO_ITT_NOTIFY +ifeq (release,$(cfg)) +SDL_FLAGS += -D_FORTIFY_SOURCE=2 +# -g is set intentionally in the release mode. It should not affect performance. +CPLUS_FLAGS = -O2 -qno-opt-report-embed +else +CPLUS_FLAGS = -O0 -g -DTBB_USE_DEBUG +endif + +LIB_LINK_FLAGS = -shared -static-intel -Wl,-soname=$(BUILDING_LIBRARY) -z relro -z now +LIBS += -lrt +LINK_FLAGS = -rdynamic +C_FLAGS = $(CPLUS_FLAGS) + +CPLUS_FLAGS += $(ITT_NOTIFY) -DUSE_PTHREAD -pthread +LIB_LINK_FLAGS += -pthread + +ifneq (,$(shell icc -dumpversion | egrep "^1[6-9]\.")) +OPENMP_FLAG = -qopenmp +else +OPENMP_FLAG = -openmp +endif + +# ICC 12.0 and higher provide Intel(R) Cilk(TM) Plus +ifneq (,$(shell icc -dumpversion | egrep "^1[2-9]\.")) + CILK_AVAILABLE = yes +endif + +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ifeq (ia32,$(arch)) + CPLUS_FLAGS += -m32 -falign-stack=maintain-16-byte + LIB_LINK_FLAGS += -m32 +endif + +ifeq (ia64,$(arch)) + ITT_NOTIFY = +# Position-independent code (PIC) is a must on IA-64 architecture, even for regular (not shared) executables +# strict-ansi does not work with on RHEL 4 AS + CPLUS_FLAGS += $(PIC_KEY) $(if $(findstring cc3.,$(runtime)),-ansi,-strict-ansi) +else +# For ICC 16 and older, in std=c++14 mode -strict-ansi does not work with GNU C++ library headers +# egrep returns 0 or 1, compare it in concatenation + CPLUS_FLAGS += $(if $(findstring c++14_1,$(stdver)_$(shell icc -dumpversion| egrep -c "^1[1-6]\.")),-ansi,-strict-ansi) +endif + +ifneq (,$(codecov)) +# no tool support for code coverage, need profile data generation + ITT_NOTIFY = -prof-gen=srcpos +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASM = as +ifeq (intel64,$(arch)) + ASM_FLAGS += --64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += --32 +endif +ifeq ($(cfg),debug) + ASM_FLAGS += -g +endif + +ASSEMBLY_SOURCE=$(arch)-gas +ifeq (ia64,$(arch)) + ASM_FLAGS += -xexplicit + TBB_ASM.OBJ += atomic_support.o lock_byte.o log2.o pause.o ia64_misc.o + MALLOC_ASM.OBJ += atomic_support.o lock_byte.o pause.o log2.o +endif +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.inc new file mode 100644 index 00000000..ad1841cb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.inc @@ -0,0 +1,145 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +####### Detections and Commands ############################################### + +ifeq (icc,$(compiler)) + export COMPILER_VERSION := ICC: $(shell icc -V &1 | grep 'Version') + ifneq (,$(findstring running on IA-32, $(COMPILER_VERSION))) + export arch:=ia32 + else + ifneq (,$(findstring running on Intel(R) 64, $(COMPILER_VERSION))) + export arch:=intel64 + else + ifneq (,$(findstring IA-64, $(COMPILER_VERSION))) + export arch:=ia64 + endif + endif + endif + ifeq (,$(arch)) + $(warning "Unknown Intel compiler") + endif +endif + +ifndef arch + uname_m:=$(shell uname -m) + ifeq ($(uname_m),i686) + export arch:=ia32 + endif + ifeq ($(uname_m),ia64) + export arch:=ia64 + endif + ifeq ($(uname_m),x86_64) + export arch:=intel64 + endif + ifeq ($(uname_m),sparc64) + export arch:=sparc + endif + ifeq ($(uname_m),armv7l) + export arch:=armv7 + endif + ifndef arch + export arch:=$(uname_m) + endif +endif + +ifndef runtime + export gcc_version:=$(shell gcc -dumpfullversion -dumpversion) + os_version:=$(shell uname -r) + os_kernel_version:=$(shell uname -r | sed -e 's/-.*$$//') + export os_glibc_version_full:=$(shell getconf GNU_LIBC_VERSION | grep glibc | sed -e 's/^glibc //') + os_glibc_version:=$(shell echo "$(os_glibc_version_full)" | sed -e '2,$$d' -e 's/-.*$$//') + export runtime:=cc$(gcc_version)_libc$(os_glibc_version)_kernel$(os_kernel_version) +endif + +native_compiler := gcc +export compiler ?= gcc +debugger ?= gdb + +CMD=sh -c +CWD=$(shell pwd) +CP=cp +RM?=rm -f +RD?=rmdir +MD?=mkdir -p +NUL= /dev/null +SLASH=/ +MAKE_VERSIONS=sh $(tbb_root)/build/version_info_linux.sh $(VERSION_FLAGS) >version_string.ver +MAKE_TBBVARS=sh $(tbb_root)/build/generate_tbbvars.sh + +ifdef LD_LIBRARY_PATH + export LD_LIBRARY_PATH := .:$(LD_LIBRARY_PATH) +else + export LD_LIBRARY_PATH := . +endif + +####### Build settings ######################################################## + +OBJ = o +DLL = so +MALLOC_DLL?=$(DLL) +LIBEXT = so +SONAME_SUFFIX =$(shell grep TBB_COMPATIBLE_INTERFACE_VERSION $(tbb_root)/include/tbb/tbb_stddef.h | egrep -o [0-9.]+) + +ifeq ($(arch),ia64) + def_prefix = lin64ipf +endif +ifneq (,$(findstring $(arch),sparc s390x)) + def_prefix = lin64 +endif +ifeq ($(arch),armv7) + def_prefix = lin32 +endif +ifeq (,$(def_prefix)) + ifeq (64,$(findstring 64,$(arch))) + def_prefix = lin64 + else + def_prefix = lin32 + endif +endif +TBB.LST = $(tbb_root)/src/tbb/$(def_prefix)-tbb-export.lst +TBB.DEF = $(TBB.LST:.lst=.def) + +TBB.DLL = $(TBB_NO_VERSION.DLL).$(SONAME_SUFFIX) +TBB.LIB = $(TBB.DLL) +TBB_NO_VERSION.DLL=libtbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +LINK_TBB.LIB = $(TBB_NO_VERSION.DLL) + +TBBBIND_NO_VERSION.DLL = libtbbbind$(DEBUG_SUFFIX).$(DLL) +TBBBIND.DEF = $(tbb_root)/src/tbb/$(def_prefix)-tbbbind-export.def +TBBBIND.DLL = $(TBBBIND_NO_VERSION.DLL).$(SONAME_SUFFIX) +TBBBIND.LIB = $(TBBBIND_NO_VERSION.DLL) +LINK_TBBBIND.LIB = $(TBBBIND.LIB) +HWLOC.LIB = -lhwloc + +MALLOC_NO_VERSION.DLL = libtbbmalloc$(DEBUG_SUFFIX).$(MALLOC_DLL) +MALLOC.DEF = $(MALLOC_ROOT)/$(def_prefix)-tbbmalloc-export.def +MALLOC.DLL = $(MALLOC_NO_VERSION.DLL).$(SONAME_SUFFIX) +MALLOC.LIB = $(MALLOC_NO_VERSION.DLL) +LINK_MALLOC.LIB = $(MALLOC_NO_VERSION.DLL) + +MALLOCPROXY_NO_VERSION.DLL = libtbbmalloc_proxy$(DEBUG_SUFFIX).$(DLL) +MALLOCPROXY.DEF = $(MALLOC_ROOT)/$(def_prefix)-proxy-export.def +MALLOCPROXY.DLL = $(MALLOCPROXY_NO_VERSION.DLL).$(SONAME_SUFFIX) +MALLOCPROXY.LIB = $(MALLOCPROXY_NO_VERSION.DLL) +LINK_MALLOCPROXY.LIB = $(MALLOCPROXY.LIB) + +RML_NO_VERSION.DLL = libirml$(DEBUG_SUFFIX).$(DLL) +RML.DEF = $(RML_SERVER_ROOT)/lin-rml-export.def +RML.DLL = $(RML_NO_VERSION.DLL).1 +RML.LIB = $(RML_NO_VERSION.DLL) + +TEST_LAUNCHER=sh $(tbb_root)/build/test_launcher.sh $(largs) + +OPENCL.LIB = -lOpenCL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.pathcc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.pathcc.inc new file mode 100644 index 00000000..066d285e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.pathcc.inc @@ -0,0 +1,89 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CPLUS ?= pathCC +CONLY ?= pathcc +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +TEST_WARNING_KEY = -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor -Wextra + +WARNING_SUPPRESS = -Wno-parentheses -Wno-non-virtual-dtor +DYLIB_KEY = -shared +EXPORT_KEY = -Wl,--version-script, +LIBDL = -ldl + +LIB_LINK_FLAGS = $(DYLIB_KEY) -Wl,-soname=$(BUILDING_LIBRARY) +LIBS += -lstl -lpthread -lrt +LINK_FLAGS = -Wl,-rpath-link=. -rdynamic +C_FLAGS = $(CPLUS_FLAGS) + +OPENMP_FLAG = -openmp + +ifeq ($(cfg), release) + CPLUS_FLAGS = $(ITT_NOTIFY) -O2 -DUSE_PTHREAD +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -DTBB_USE_DEBUG $(ITT_NOTIFY) -g -O0 -DUSE_PTHREAD +endif + +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +ifeq (intel64,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m32 -march=pentium4 + LIB_LINK_FLAGS += -m32 +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASM = as +ifeq (intel64,$(arch)) + ASM_FLAGS += --64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += --32 +endif +ifeq ($(cfg),debug) + ASM_FLAGS += -g +endif + +ASSEMBLY_SOURCE=$(arch)-gas +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.xl.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.xl.inc new file mode 100644 index 00000000..81dbc6f3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/linux.xl.inc @@ -0,0 +1,100 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +####### Detections and Commands ############################################### + +CPLUS ?= xlc++_r +CONLY ?= xlc_r +COMPILE_ONLY = -c +PREPROC_ONLY = -E -qsourcetype=c +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -qpic +WARNING_AS_ERROR_KEY = -qhalt=w +WARNING_KEY = +TEST_WARNING_KEY = + +WARNING_SUPPRESS = +DYLIB_KEY = -qmkshrobj +EXPORT_KEY = -Wl,--version-script, +LIBDL = -ldl + +LIB_LINK_FLAGS = $(DYLIB_KEY) -Wl,-soname=$(BUILDING_LIBRARY) +LIBS = -lpthread -lrt +C_FLAGS = $(CPLUS_FLAGS) + +ifeq ($(cfg), release) + CPLUS_FLAGS = $(ITT_NOTIFY) -O2 -DUSE_PTHREAD +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -DTBB_USE_DEBUG $(ITT_NOTIFY) -g -O0 -DUSE_PTHREAD +endif + +# Adding directly to CPLUS_FLAGS instead of to WARNING_SUPPRESS because otherwise it would not be used in several tests (why not?). +# Suppress warnings like: +# - "1500-029: (W) WARNING: subprogram [...] could not be inlined into [...]." +# - "1501-201: (W) Maximum number of common component diagnostics, 10 has been exceeded." +# see http://www-01.ibm.com/support/docview.wss?uid=swg1LI72843 +# it seems that the internal compiler error that would ensue has now been avoided, making the condition harmless +# - "1540-0198 (W) The omitted keyword "private" is assumed for base class "no_copy"." +# - "1540-0822 (W) The name "__FUNCTION__" must not be defined as a macro." +CPLUS_FLAGS += -qsuppress=1500-029:1501-201:1540-0198:1540-0822 + +ASM= +ASM_FLAGS= + +TBB_ASM.OBJ= + +ifeq (intel64,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -q64 + LIB_LINK_FLAGS += -q64 +endif + +# TODO: equivalent for -march=pentium4 in CPLUS_FLAGS +ifeq (ia32,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -q32 -qarch=pentium4 + LIB_LINK_FLAGS += -q32 +endif + +ifeq (ppc64,$(arch)) + CPLUS_FLAGS += -q64 + LIB_LINK_FLAGS += -q64 +endif + +ifeq (ppc32,$(arch)) + CPLUS_FLAGS += -q32 + LIB_LINK_FLAGS += -q32 +endif + +ifeq (bg,$(arch)) + CPLUS = bgxlC_r + CONLY = bgxlc_r +endif + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +# Suppress innumerable warnings like "1540-1088 (W) The exception specification is being ignored." +# Suppress warnings like "1540-1090 (I) The destructor of "lock" might not be called." +# TODO: aren't these warnings an indication that -qnoeh might not be appropriate? +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -qnortti -qnoeh -qsuppress=1540-1088:1540-1090 + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.clang.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.clang.inc new file mode 100644 index 00000000..a6b314b9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.clang.inc @@ -0,0 +1,136 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CPLUS ?= clang++ +CONLY ?= clang +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +TEST_WARNING_KEY = -Wextra -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor +WARNING_SUPPRESS = -Wno-non-virtual-dtor -Wno-dangling-else +DYLIB_KEY = -dynamiclib +EXPORT_KEY = -Wl,-exported_symbols_list, +LIBDL = -ldl + +LIBS = -lpthread +LINK_FLAGS = +LIB_LINK_FLAGS = -dynamiclib -install_name @rpath/$(BUILDING_LIBRARY) +C_FLAGS = $(CPLUS_FLAGS) + +ifeq ($(cfg), release) + CPLUS_FLAGS = -O2 +else + CPLUS_FLAGS = -g -O0 -DTBB_USE_DEBUG +endif + +CPLUS_FLAGS += -DUSE_PTHREAD $(ITT_NOTIFY) + +ifeq (1,$(tbb_cpf)) +# For correct ucontext.h structures layout +CPLUS_FLAGS += -D_XOPEN_SOURCE +endif + +# For Clang, we add the option to support RTM intrinsics *iff* xtest is found in +ifneq (,$(shell grep xtest `echo "\#include" | $(CONLY) -E -M - 2>&1 | grep immintrin.h` 2>/dev/null)) + RTM_KEY = -mrtm +endif + +ifneq (,$(stdlib)) + CPLUS_FLAGS += -stdlib=$(stdlib) + LIB_LINK_FLAGS += -stdlib=$(stdlib) +endif + +ifeq (intel64,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m64 $(RTM_KEY) + LINK_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m32 $(RTM_KEY) + LINK_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +endif + +ifeq (ppc64,$(arch)) + CPLUS_FLAGS += -arch ppc64 + LINK_FLAGS += -arch ppc64 + LIB_LINK_FLAGS += -arch ppc64 +endif + +ifeq (ppc32,$(arch)) + CPLUS_FLAGS += -arch ppc + LINK_FLAGS += -arch ppc + LIB_LINK_FLAGS += -arch ppc +endif + +ifeq ($(arch),$(filter $(arch),armv7 armv7s arm64)) + CPLUS_FLAGS += -arch $(arch) + LINK_FLAGS += -arch $(arch) + LIB_LINK_FLAGS += -arch $(arch) +endif + +ifdef SDKROOT + CPLUS_FLAGS += -isysroot $(SDKROOT) + LINK_FLAGS += -L$(SDKROOT)/usr/lib/system -L$(SDKROOT)/usr/lib/ + LIB_LINK_FLAGS += -L$(SDKROOT)/usr/lib/system -L$(SDKROOT)/usr/lib/ +endif + +ifeq (ios,$(target)) + CPLUS_FLAGS += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET) + LINK_FLAGS += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET) + LIB_LINK_FLAGS += -miphoneos-version-min=$(IPHONEOS_DEPLOYMENT_TARGET) +else + CPLUS_FLAGS += -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) + LINK_FLAGS += -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) + LIB_LINK_FLAGS += -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ + +ASM = as +ifeq (intel64,$(arch)) + ASM_FLAGS += -arch x86_64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += -arch i386 +endif +ifeq ($(cfg), debug) + ASM_FLAGS += -g +endif + +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.gcc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.gcc.inc new file mode 100644 index 00000000..00741588 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.gcc.inc @@ -0,0 +1,128 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CPLUS ?= g++ +CONLY ?= gcc +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +TEST_WARNING_KEY = -Wextra -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor +WARNING_SUPPRESS = -Wno-non-virtual-dtor +DYLIB_KEY = -dynamiclib +EXPORT_KEY = -Wl,-exported_symbols_list, +LIBDL = -ldl + +LIBS = -lpthread +LINK_FLAGS = +LIB_LINK_FLAGS = -dynamiclib -install_name @rpath/$(BUILDING_LIBRARY) +C_FLAGS = $(CPLUS_FLAGS) + +# gcc 4.8 and later support RTM intrinsics, but require command line switch to enable them +ifneq (,$(shell $(CONLY) -dumpfullversion -dumpversion | egrep "^(4\.[8-9]|[5-9]|1[0-9])")) + RTM_KEY = -mrtm +endif + +# gcc 5.0 and later have -Wsuggest-override option +# enable it via a pre-included header in order to limit to C++11 and above +ifneq (,$(shell $(CONLY) -dumpfullversion -dumpversion | egrep "^([5-9]|1[0-9])")) + INCLUDE_TEST_HEADERS = -include $(tbb_root)/src/test/harness_preload.h +endif + +# gcc 6.0 and later have -flifetime-dse option that controls +# elimination of stores done outside the object lifetime +ifneq (,$(shell $(CONLY) -dumpfullversion -dumpversion | egrep "^([6-9]|1[0-9])")) + # keep pre-contruction stores for zero initialization + DSE_KEY = -flifetime-dse=1 +endif + +ifeq ($(cfg), release) + CPLUS_FLAGS = -O2 +else + CPLUS_FLAGS = -g -O0 -DTBB_USE_DEBUG +endif + +CPLUS_FLAGS += -DUSE_PTHREAD $(ITT_NOTIFY) + +ifeq (intel64,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m64 + LINK_FLAGS += -m64 + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + ITT_NOTIFY = -DDO_ITT_NOTIFY + CPLUS_FLAGS += -m32 + LINK_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 +endif + +ifeq (ppc64,$(arch)) + CPLUS_FLAGS += -arch ppc64 + LINK_FLAGS += -arch ppc64 + LIB_LINK_FLAGS += -arch ppc64 +endif + +ifeq (ppc32,$(arch)) + CPLUS_FLAGS += -arch ppc + LINK_FLAGS += -arch ppc + LIB_LINK_FLAGS += -arch ppc +endif + +ifeq (armv7,$(arch)) + CPLUS_FLAGS += -arch armv7 + LINK_FLAGS += -arch armv7 + LIB_LINK_FLAGS += -arch armv7 +endif + +ifdef SDKROOT + CPLUS_FLAGS += -isysroot $(SDKROOT) + LIB_LINK_FLAGS += -L$(SDKROOT)/usr/lib/system -L$(SDKROOT)/usr/lib/ +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ + +ASM = as +ifeq (intel64,$(arch)) + ASM_FLAGS += -arch x86_64 +endif +ifeq (ia32,$(arch)) + ASM_FLAGS += -arch i386 +endif +ifeq ($(cfg), debug) + ASM_FLAGS += -g +endif + +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.icc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.icc.inc new file mode 100644 index 00000000..6abc9aae --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.icc.inc @@ -0,0 +1,107 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CPLUS ?= icpc +CONLY ?= icc +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -w1 +ifneq (,$(shell icc -dumpversion | egrep "1[2-9]\.")) +SDL_FLAGS = -fstack-protector -Wformat -Wformat-security +endif + +DYLIB_KEY = -dynamiclib +EXPORT_KEY = -Wl,-exported_symbols_list, +LIBDL = -ldl + +LIBS = -lpthread +LINK_FLAGS = +LIB_LINK_FLAGS = -dynamiclib -static-intel -install_name @rpath/$(BUILDING_LIBRARY) +C_FLAGS = $(CPLUS_FLAGS) + +ifneq (,$(shell icc -dumpversion | egrep "^1[6-9]\.")) +OPENMP_FLAG = -qopenmp +else +OPENMP_FLAG = -openmp +endif + +# ICC 12.0 and higher provide Intel(R) Cilk(TM) Plus +ifneq (,$(shell icc -dumpversion | egrep "^1[2-9]\.")) + CILK_AVAILABLE = yes +endif + +ifeq ($(cfg), release) + SDL_FLAGS += -D_FORTIFY_SOURCE=2 + CPLUS_FLAGS = -O2 -fno-omit-frame-pointer -qno-opt-report-embed +else + CPLUS_FLAGS = -g -O0 -DTBB_USE_DEBUG +endif + +ITT_NOTIFY = -DDO_ITT_NOTIFY +CPLUS_FLAGS += -DUSE_PTHREAD $(ITT_NOTIFY) + +ifeq (1,$(tbb_cpf)) +# For correct ucontext.h structures layout +CPLUS_FLAGS += -D_XOPEN_SOURCE +endif + +ifneq (,$(codecov)) + CPLUS_FLAGS += -prof-gen=srcpos +endif + +# ICC 14.0 and higher support usage of libc++, clang standard library +ifneq (,$(shell icc -dumpversion | egrep "^1[4-9]\.")) +ifneq (,$(stdlib)) + CPLUS_FLAGS += -stdlib=$(stdlib) -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) + LIB_LINK_FLAGS += -stdlib=$(stdlib) -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) +endif +endif + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ + +ASM = as +ifeq (intel64,$(arch)) + ASM_FLAGS += -arch x86_64 +endif +ifeq (ia32,$(arch)) + CPLUS_FLAGS += -m32 + LINK_FLAGS += -m32 + LIB_LINK_FLAGS += -m32 + ASM_FLAGS += -arch i386 +endif +ifeq ($(cfg), debug) + ASM_FLAGS += -g +endif + +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.inc new file mode 100644 index 00000000..d68a7ebe --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/macos.inc @@ -0,0 +1,109 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +####### Detections and Commands ############################################### + +ifeq (icc,$(compiler)) + export COMPILER_VERSION := ICC: $(shell icc -V &1 | grep 'Version') + ifneq (,$(findstring running on IA-32, $(COMPILER_VERSION))) + export arch:=ia32 + else + ifneq (,$(findstring running on Intel(R) 64, $(COMPILER_VERSION))) + export arch:=intel64 + endif + endif + ifeq (,$(arch)) + $(warning "Unknown Intel compiler") + endif +endif + +ifndef arch + ifeq ($(shell /usr/sbin/sysctl -n hw.machine),Power Macintosh) + ifeq ($(shell /usr/sbin/sysctl -n hw.optional.64bitops),1) + export arch:=ppc64 + else + export arch:=ppc32 + endif + else + ifeq ($(shell /usr/sbin/sysctl -n hw.machine),arm64) + export arch:=arm64 + else + ifeq ($(shell /usr/sbin/sysctl -n hw.optional.x86_64 2>/dev/null),1) + export arch:=intel64 + else + export arch:=ia32 + endif + endif + endif +endif + +ifndef runtime + clang_version:=$(shell clang --version | sed -n "1s/.*version \(.*[0-9]\) .*/\1/p") + ifndef os_version + os_version:=$(shell /usr/bin/sw_vers -productVersion) + endif + export runtime:=cc$(clang_version)_os$(os_version) +endif + +native_compiler := clang +export compiler ?= clang +debugger ?= lldb + +export stdlib ?= libc++ + +CMD=$(SHELL) -c +CWD=$(shell pwd) +RM?=rm -f +RD?=rmdir +MD?=mkdir -p +NUL= /dev/null +SLASH=/ +MAKE_VERSIONS=sh $(tbb_root)/build/version_info_macos.sh $(VERSION_FLAGS) >version_string.ver +MAKE_TBBVARS=sh $(tbb_root)/build/generate_tbbvars.sh DY + +ifdef DYLD_LIBRARY_PATH + export DYLD_LIBRARY_PATH := .:$(DYLD_LIBRARY_PATH) +else + export DYLD_LIBRARY_PATH := . +endif + +####### Build settings ######################################################## + +OBJ=o +DLL=dylib +MALLOC_DLL?=$(DLL) +LIBEXT=dylib + +def_prefix = $(if $(findstring 64,$(arch)),mac64,mac32) + +TBB.LST = $(tbb_root)/src/tbb/$(def_prefix)-tbb-export.lst +TBB.DEF = $(TBB.LST:.lst=.def) +TBB.DLL = libtbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +TBB.LIB = $(TBB.DLL) +LINK_TBB.LIB = $(TBB.LIB) + +MALLOC.DEF = $(MALLOC_ROOT)/$(def_prefix)-tbbmalloc-export.def +MALLOC.DLL = libtbbmalloc$(DEBUG_SUFFIX).$(MALLOC_DLL) +MALLOC.LIB = $(MALLOC.DLL) +LINK_MALLOC.LIB = $(MALLOC.LIB) + +MALLOCPROXY.DLL = libtbbmalloc_proxy$(DEBUG_SUFFIX).$(MALLOC_DLL) +MALLOCPROXY.LIB = $(MALLOCPROXY.DLL) +LINK_MALLOCPROXY.LIB = $(MALLOCPROXY.LIB) + +TEST_LAUNCHER=sh $(tbb_root)/build/test_launcher.sh $(largs) + +OPENCL.LIB = -framework OpenCL + +MACOSX_DEPLOYMENT_TARGET ?= 10.11 diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.icc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.icc.inc new file mode 100644 index 00000000..e1d66ad8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.icc.inc @@ -0,0 +1,72 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CPLUS ?= icpc +CONLY ?= icc +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = -fPIC +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -w1 +DYLIB_KEY = -shared -Wl,-soname=$@ +EXPORT_KEY = -Wl,--version-script, +NOINTRINSIC_KEY = -fno-builtin +LIBDL = -ldl +SDL_FLAGS = -fstack-protector -Wformat -Wformat-security + +ifeq (release,$(cfg)) + SDL_FLAGS += -D_FORTIFY_SOURCE=2 + CPLUS_FLAGS = -O2 -DUSE_PTHREAD +else + CPLUS_FLAGS = -O0 -g -DUSE_PTHREAD -DTBB_USE_DEBUG +endif + +ifneq (,$(codecov)) + CPLUS_FLAGS += -prof-gen=srcpos +endif + +ifneq (,$(shell icc -dumpversion | egrep "^1[6-9]\.")) +OPENMP_FLAG = -qopenmp +else +OPENMP_FLAG = -openmp +endif + +LIB_LINK_FLAGS = -shared -static-intel -Wl,-soname=$(BUILDING_LIBRARY) -z relro -z now +LIBS += -lpthread -lrt +C_FLAGS = $(CPLUS_FLAGS) +CILK_AVAILABLE = yes + +TBB_ASM.OBJ= +MALLOC_ASM.OBJ= + +CPLUS_FLAGS += -DHARNESS_INCOMPLETE_SOURCES=1 -D__TBB_MIC_NATIVE -DTBB_USE_EXCEPTIONS=0 -qopt-streaming-stores never +CPLUS += -mmic +CONLY += -mmic +LINK_FLAGS = -Wl,-rpath-link=. -rdynamic +# Tell the icc to not link against libcilk*. Otherwise icc tries to link and emits a warning message. +LIB_LINK_FLAGS += -no-intel-extensions + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.linux.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.linux.inc new file mode 100644 index 00000000..32d5be5b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.linux.inc @@ -0,0 +1,39 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifeq ($(tbb_os),mic) + $(error MIC supports only cross-compilation. Specify "target=mic" instead.) +endif + +ifneq ($(BUILDING_PHASE),1) + # The same build prefix should be used in offload.inc + ifeq (,$(tbb_build_prefix)) + tbb_build_prefix=mic_icc$(CPF_SUFFIX) + endif + # For examples + mic_tbb_build_prefix=$(tbb_build_prefix) +endif + +MAKE_VERSIONS=sh $(tbb_root)/build/version_info_linux.sh $(VERSION_FLAGS) >version_string.ver +MAKE_TBBVARS=sh $(tbb_root)/build/generate_tbbvars.sh MIC_ MIC_ +def_prefix=lin64 + +TEST_LAUNCHER= +run_cmd ?= bash $(tbb_root)/build/mic.linux.launcher.sh $(largs) + +# detects whether examples are being built. +ifeq ($(BUILDING_PHASE),0) + export UI = con + export x64 = 64 +endif # examples diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.linux.launcher.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.linux.launcher.sh new file mode 100644 index 00000000..bb09afc1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.linux.launcher.sh @@ -0,0 +1,157 @@ +#!/bin/bash +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Usage: +# mic.linux.launcher.sh [-v] [-q] [-s] [-r ] [-u] [-l ] +# where: -v enables verbose output +# where: -q enables quiet mode +# where: -s runs the test in stress mode (until non-zero exit code or ctrl-c pressed) +# where: -r specifies number of times to repeat execution +# where: -u limits stack size +# where: -l specifies the library name to be assigned to LD_PRELOAD +# +# Libs and executable necessary for testing should be present in the current directory before running. +# Note: Do not remove the redirections to '/dev/null' in the script, otherwise the nightly test system will fail. +# +trap 'echo Error at line $LINENO while executing "$BASH_COMMAND"' ERR # +trap 'echo -e "\n*** Interrupted ***" && exit 1' SIGINT SIGQUIT # +# Process the optional arguments if present +while getopts "qvsr:ul:" flag # +do case $flag in # + s ) # Stress testing mode + echo Doing stress testing. Press Ctrl-C to terminate + run_env='stressed() { while $*; do :; done; };' # + run_prefix="stressed $run_prefix" ;; # + r ) # Repeats test n times + run_env="repeated() { for i in \$(seq 1 $OPTARG); do echo \$i of $OPTARG:; \$*; done; };" # + run_prefix="repeated $run_prefix" ;; # + l ) # Additional library + ldd_list+="$OPTARG " # + run_prefix+=" LD_PRELOAD=$OPTARG" ;; # + u ) # Set stack limit + run_prefix="ulimit -s 10240; $run_prefix" ;; # + q ) # Quiet mode, removes 'done' but prepends any other output by test name + SUPPRESS='>/dev/null' # + verbose=1 ;; # TODO: implement a better quiet mode + v ) # Verbose mode + verbose=1 ;; # +esac done # +shift `expr $OPTIND - 1` # +[ $verbose ] || SUPPRESS='>/dev/null' # +# +# Collect the executable name +fexename="$1" # +exename=`basename $1` # +shift # +# +: ${MICDEV:=mic0} # +RSH="sudo ssh $MICDEV" # +RCP="sudo scp" # +currentdir=$PWD # +# +# Prepare the target directory on the device +targetdir="`$RSH mktemp -d /tmp/tbbtestXXXXXX 2>/dev/null`" # +# Prepare the temporary directory on the host +hostdir="`mktemp -d /tmp/tbbtestXXXXXX 2>/dev/null`" # +# +function copy_files { # + [ $verbose ] && echo Going to copy $* # + eval "cp $* $hostdir/ $SUPPRESS 2>/dev/null || exit \$?" # + eval "$RCP $hostdir/* $MICDEV:$targetdir/ $SUPPRESS 2>/dev/null || exit \$?" # + eval "rm $hostdir/* $SUPPRESS 2>/dev/null || exit \$?" # +} # copy files +# +function clean_all() { # + eval "$RSH rm -fr $targetdir $SUPPRESS" ||: # + eval "rm -fr $hostdir $SUPPRESS" ||: # +} # clean all temporary files +# +function kill_interrupt() { # + echo -e "\n*** Killing remote $exename ***" && $RSH "killall $exename" # + clean_all # +} # kill target process +# +trap 'clean_all' SIGINT SIGQUIT # trap keyboard interrupt (control-c) +# +# Transfer the test executable file and its auxiliary libraries (named as {test}_dll.so) to the target device. +copy_files $fexename `ls ${exename%\.*}*.so 2>/dev/null ||:` # +# +# Collect all dependencies of the test and its auxiliary libraries to transfer them to the target device. +ldd_list+="libtbbmalloc*.so* libirml*.so* `$RSH ldd $targetdir/\* | grep = | cut -d= -f1 2>/dev/null`" # +fnamelist="" # +# +# Find the libraries and add them to the list. +# For example, go through MIC_LD_LIBRARY_PATH and add TBB libraries from the first +# directory that contains tbb files +mic_dir_list=`echo .:$MIC_LD_LIBRARY_PATH | tr : " "` # +[ $verbose ] && echo Searching libraries in $mic_dir_list +for name in $ldd_list; do # adds the first matched name in specified dirs + found="`find -L $mic_dir_list -name $name -a -readable -print -quit 2>/dev/null` "||: # + [ $verbose ] && echo File $name: $found + fnamelist+=$found +done # +# +# Remove extra spaces. +fnamelist=`echo $fnamelist` # +# Transfer collected executable and library files to the target device. +[ -n "$fnamelist" ] && copy_files $fnamelist +# +# Transfer input files used by example codes by scanning the executable argument list. +argfiles= # +args= # +for arg in "$@"; do # + if [ -r $arg ]; then # + argfiles+="$arg " # + args+="$(basename $arg) " # + else # + args+="$arg " # + fi # +done # +[ -n "$argfiles" ] && copy_files $argfiles # +# +# Get the list of transferred files +testfiles="`$RSH find $targetdir/ -type f | tr '\n' ' ' 2>/dev/null`" # +# +[ $verbose ] && echo Running $run_prefix ./$exename $args # +# Run the test on the target device +trap 'kill_interrupt' SIGINT SIGQUIT # trap keyboard interrupt (control-c) +trap - ERR # +run_env+="cd $targetdir; export LD_LIBRARY_PATH=.:\$LD_LIBRARY_PATH;" # +$RSH "$run_env $run_prefix ./$exename $args" # +# +# Delete the test files and get the list of output files +outfiles=`$RSH rm $testfiles 2>/dev/null; find $targetdir/ -type f 2>/dev/null` ||: # +if [ -n "$outfiles" ]; then # + for outfile in $outfiles; do # + filename=$(basename $outfile) # + subdir=$(dirname $outfile) # + subdir="${subdir#$targetdir}" # + [ -n $subdir ] subdir=$subdir/ # + # Create directories on host + [ ! -d "$hostdir/$subdir" ] && mkdir -p "$hostdir/$subdir" # + [ ! -d "$currentdir/$subdir" ] && mkdir -p "$currentdir/$subdir" # + # Copy the output file to the temporary directory on host + eval "$RCP -r '$MICDEV:${outfile#}' '$hostdir/$subdir$filename' $SUPPRESS 2>&1 || exit \$?" # + # Copy the output file from the temporary directory to the current directory + eval "cp '$hostdir/$subdir$filename' '$currentdir/$subdir$filename' $SUPPRESS 2>&1 || exit \$?" # + done # +fi # +# +# Clean up temporary directories +clean_all +# +# Return the exit code of the test. +exit $? # diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.offload.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.offload.inc new file mode 100644 index 00000000..2428166e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/mic.offload.inc @@ -0,0 +1,114 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifneq (mic,$(offload)) + $(error File mic.offload.inc should not be included directly. Use offload=mic instead.) +endif +ifneq (icc,$(compiler)) + $(error Only Intel(R) Compiler is supported for MIC offload compilation) +endif + +# The same build prefix should be used in mic.linux.inc +mic_tbb_build_prefix=mic_icc$(CPF_SUFFIX) +MIC_OFFLOAD_NATIVE_PATH?=../$(mic_tbb_build_prefix)_$(cfg) + +ifdef BUILDING_PHASE + ifeq ($(BUILDING_PHASE),1) + # Tests + export MIC_OFFLOAD_NATIVE_PATH + LINK_TBB_NATIVE.LIB=$(MIC_OFFLOAD_NATIVE_PATH)/$(TBB.LIB) + LINK_TBB.LIB=-qoffload-option,mic,ld,"$(LINK_TBB_NATIVE.LIB)" $(TBB.LIB) + LINK_MALLOC_NATIVE.LIB=$(MIC_OFFLOAD_NATIVE_PATH)/$(MALLOC.DLL) + LINK_MALLOC.LIB=-qoffload-option,mic,ld,"$(LINK_MALLOC_NATIVE.LIB)" $(MALLOC.LIB) + LINK_MALLOCPROXY_NATIVE.LIB=$(MIC_OFFLOAD_NATIVE_PATH)/$(MALLOCPROXY.DLL) + LINK_MALLOCPROXY.LIB=-qoffload-option,mic,ld,"$(LINK_MALLOCPROXY_NATIVE.LIB)" $(MALLOCPROXY.LIB) + + # Export extensions for test_launcher + export DLL + export TEST_EXT=offload.exe + OBJ=offload.o + + # Do not use -Werror because it is too strict for the early offload compiler. + # Need to set anything because WARNING_AS_ERROR_KEY should not be empty. + # Treat #2426 as a warning. Print errors only. + tbb_strict=0 + WARNING_AS_ERROR_KEY = Warning as error + WARNING_KEY = -diag-warning 2426 -w0 + + CXX_MIC_STUFF = -qoffload-attribute-target=mic -D__TBB_MIC_OFFLOAD=1 -qoffload-option,mic,compiler,"-D__TBB_MIC_OFFLOAD=1 $(CXX_MIC_NATIVE_STUFF)" + CXX_MIC_NATIVE_STUFF = -DHARNESS_INCOMPLETE_SOURCES=1 -D__TBB_MIC_NATIVE -DTBB_USE_EXCEPTIONS=0 + CPLUS_FLAGS += $(CXX_MIC_STUFF) + + # Some tests require that an executable exports its symbols. + LINK_FLAGS += -qoffload-option,mic,ld,"--export-dynamic" + + # libcoi_device.so is needed for COIProcessProxyFlush used in Harness. + LINK_FLAGS += -qoffload-option,mic,ld,"-lcoi_device" + + # DSO-linking semantics forces linking libpthread and librt to a test. + LINK_FLAGS += -qoffload-option,mic,ld,"-lpthread -lrt" + + .PHONY: FORCE + FORCE: + + $(MIC_OFFLOAD_NATIVE_PATH)/%_dll.$(DLL): FORCE + @$(MAKE) --no-print-directory -C "$(MIC_OFFLOAD_NATIVE_PATH)" target=mic offload= -f$(tbb_root)/build/Makefile.$(TESTFILE) $*_dll.$(DLL) + %_dll.$(DLL): $(MIC_OFFLOAD_NATIVE_PATH)/%_dll.$(DLL) FORCE + @$(MAKE) --no-print-directory offload= -f$(tbb_root)/build/Makefile.$(TESTFILE) $*_dll.$(DLL) + + .PRECIOUS: $(MIC_OFFLOAD_NATIVE_PATH)/%_dll.$(DLL) + + %.$(TEST_EXT): LINK_FILES+=-qoffload-option,mic,ld,"$(addprefix $(MIC_OFFLOAD_NATIVE_PATH)/,$(TEST_LIBS))" + + TEST_LAUNCHER=sh $(tbb_root)/build/test_launcher.sh $(largs) + + ifdef MIC_LD_LIBRARY_PATH + export MIC_LD_LIBRARY_PATH := $(MIC_OFFLOAD_NATIVE_PATH):$(MIC_LD_LIBRARY_PATH) + else + export MIC_LD_LIBRARY_PATH := $(MIC_OFFLOAD_NATIVE_PATH) + endif + else + # Examples + export UI = con + export x64 = 64 + endif +else + # Libraries + LIB_TARGETS = tbb tbbmalloc tbbproxy rml + addsuffixes = $(foreach suff,$(1),$(addsuffix $(suff),$(2))) + + .PHONY: $(call addsuffixes, _debug _release _debug_mic _release_mic,$(LIB_TARGETS)) + + # The dependence on *_debug and *_release targets unifies the offload support + # for top-level Makefile and src/Makefile + $(LIB_TARGETS): %: %_release %_debug + + # "override offload=" suppresses the "offload" variable value for nested makes + $(LIB_TARGETS) $(call addsuffixes, _debug _release,$(LIB_TARGETS)): override offload= + # Apply overriding for library builds + export offload + export tbb_build_prefix + # Add the dependency on target libraries + $(call addsuffixes, _debug _release,$(LIB_TARGETS)): %: %_mic + + # tbb_build_prefix should be overridden since we want to restart make in "clear" environment + $(call addsuffixes, _debug_mic _release_mic,$(LIB_TARGETS)): override tbb_build_prefix= + $(call addsuffixes, _debug_mic _release_mic,$(LIB_TARGETS)): %_mic: + @$(MAKE) --no-print-directory -C "$(full_tbb_root)/src" $* target=mic tbb_root=.. + + mic_clean: override tbb_build_prefix= + mic_clean: + @$(MAKE) --no-print-directory -C "$(full_tbb_root)/src" clean offload= target=mic tbb_root=.. + clean: mic_clean +endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/suncc.map.pause b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/suncc.map.pause new file mode 100644 index 00000000..a92d08eb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/suncc.map.pause @@ -0,0 +1 @@ +hwcap_1 = OVERRIDE; \ No newline at end of file diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/test_launcher.bat b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/test_launcher.bat new file mode 100644 index 00000000..83627b12 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/test_launcher.bat @@ -0,0 +1,70 @@ +@echo off +REM +REM Copyright (c) 2005-2020 Intel Corporation +REM +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. +REM + +set cmd_line= +if DEFINED run_prefix set cmd_line=%run_prefix% +:while +if NOT "%1"=="" ( + REM Verbose mode + if "%1"=="-v" ( + set verbose=yes + GOTO continue + ) + REM Silent mode of 'make' requires additional support for associating + REM of test output with the test name. Verbose mode is the simplest way + if "%1"=="-q" ( + set verbose=yes + GOTO continue + ) + REM Run in stress mode + if "%1"=="-s" ( + echo Doing stress testing. Press Ctrl-C to terminate + set stress=yes + GOTO continue + ) + REM Repeat execution specified number of times + if "%1"=="-r" ( + set repeat=%2 + SHIFT + GOTO continue + ) + REM no LD_PRELOAD under Windows + REM but run the test to check "#pragma comment" construction + if "%1"=="-l" ( + REM The command line may specify -l with empty dll name, + REM e.g. "test_launcher.bat -l app.exe". If the dll name is + REM empty then %2 contains the application name and the SHIFT + REM operation is not necessary. + if exist "%3" SHIFT + GOTO continue + ) + REM no need to setup up stack size under Windows + if "%1"=="-u" GOTO continue + set cmd_line=%cmd_line% %1 +:continue + SHIFT + GOTO while +) +set cmd_line=%cmd_line:./=.\% +if DEFINED verbose echo Running %cmd_line% +if DEFINED stress set cmd_line=%cmd_line% ^& IF NOT ERRORLEVEL 1 GOTO stress +:stress +if DEFINED repeat ( + for /L %%i in (1,1,%repeat%) do echo %%i of %repeat%: & %cmd_line% +) else ( + %cmd_line% +) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/test_launcher.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/test_launcher.sh new file mode 100644 index 00000000..224ed507 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/test_launcher.sh @@ -0,0 +1,90 @@ +#!/bin/sh +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Usage: +# test_launcher.sh [-v] [-q] [-s] [-r ] [-u] [-l ] +# where: -v enables verbose output +# where: -q enables quiet mode +# where: -s runs the test in stress mode (until non-zero exit code or ctrl-c pressed) +# where: -r specifies number of times to repeat execution +# where: -u limits stack size +# where: -l specifies the library name to be assigned to LD_PRELOAD + +while getopts "qvsr:ul:" flag # +do case $flag in # + s ) # Stress testing mode + run_prefix="stressed $run_prefix" ;; # + r ) # Repeats test n times + repeat=$OPTARG # + run_prefix="repeated $run_prefix" ;; # + l ) if [ `uname` = 'Linux' ] ; then # + LD_PRELOAD=$OPTARG # + elif [ `uname` = 'Darwin' ] ; then # + DYLD_INSERT_LIBRARIES=$OPTARG # + else # + echo 'skip' # + exit # + fi ;; # + u ) # Set stack limit + ulimit -s 10240 ;; # + q ) # Quiet mode, removes 'done' but prepends any other output by test name + OUTPUT='2>&1 | sed -e "s/done//;/^[[:space:]]*$/d;s!^!$1: !"' ;; # + v ) # Verbose mode + verbose=1 ;; # +esac done # +shift `expr $OPTIND - 1` # +if [ $MIC_OFFLOAD_NATIVE_PATH ] ; then # + LIB_NAME=${1/%.$TEST_EXT/_dll.$DLL} # + if [ -f "$MIC_OFFLOAD_NATIVE_PATH/$LIB_NAME" ]; then # + [ -z "$MIC_CARD" ] && MIC_CARD=mic0 # + TMPDIR_HOST=`mktemp -d /tmp/tbbtestXXXXXX` # + TMPDIR_MIC=`sudo ssh $MIC_CARD mktemp -d /tmp/tbbtestXXXXXX` # + sudo ssh $MIC_CARD "chmod +x $TMPDIR_MIC" # + # Test specific library may depend on libtbbmalloc* + cp "$MIC_OFFLOAD_NATIVE_PATH/$LIB_NAME" "$MIC_OFFLOAD_NATIVE_PATH"/libtbbmalloc* "$TMPDIR_HOST" >/dev/null 2>/dev/null # + sudo scp "$TMPDIR_HOST"/* $MIC_CARD:"$TMPDIR_MIC" >/dev/null 2>/dev/null # + + LD_LIBRARY_PATH=$TMPDIR_MIC:$LD_LIBRARY_PATH # + export LD_LIBRARY_PATH # + fi # +fi # +stressed() { echo Doing stress testing. Press Ctrl-C to terminate # + while :; do $*; done;# +} # +repeated() { # + i=0; while [ "$i" -lt $repeat ]; do i=`expr $i + 1`; echo $i of $repeat:; $*; done # +} # +# DYLD_LIBRARY_PATH can be purged on OS X 10.11, set it again +if [ `uname` = 'Darwin' -a -z "$DYLD_LIBRARY_PATH" ] ; then # + DYLD_LIBRARY_PATH=. # + export DYLD_LIBRARY_PATH # +fi # +# Run the command line passed via parameters +[ $verbose ] && echo Running $run_prefix $* # +if [ -n "$LD_PRELOAD" ] ; then # + export LD_PRELOAD # +elif [ -n "$DYLD_INSERT_LIBRARIES" ] ; then # + export DYLD_INSERT_LIBRARIES # +fi # +exec 4>&1 # extracting exit code of the first command in pipeline needs duplicated stdout +# custom redirection needs eval, otherwise shell cannot parse it +err=`eval '( $run_prefix $* || echo \$? >&3; )' ${OUTPUT} 3>&1 >&4` # +[ -z "$err" ] || echo $1: exited with error $err # +if [ $MIC_OFFLOAD_NATIVE_PATH ] ; then # + sudo ssh $MIC_CARD rm -fr "$TMPDIR_MIC" >/dev/null 2>/dev/null # + rm -fr "$TMPDIR_HOST" >/dev/null 2>/dev/null # +fi # +exit $err # diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_aix.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_aix.sh new file mode 100644 index 00000000..793cad11 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_aix.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script used to generate version info string +echo "#define __TBB_VERSION_STRINGS(N) \\" +echo '#N": BUILD_HOST'"\t\t"`hostname -s`" ("`uname -m`")"'" ENDL \' +# find OS name in *-release and issue* files by filtering blank lines and lsb-release content out +echo '#N": BUILD_OS'"\t\t"`lsb_release -sd 2>/dev/null | grep -ih '[a-z] ' - /etc/*release /etc/issue 2>/dev/null | head -1 | sed -e 's/["\\\\]//g'`'" ENDL \' +echo '#N": BUILD_KERNEL'"\t"`uname -srv`'" ENDL \' +echo '#N": BUILD_GCC'"\t\t"`g++ --version &1 | grep 'g++'`'" ENDL \' +[ -z "$COMPILER_VERSION" ] || echo '#N": BUILD_COMPILER'"\t"$COMPILER_VERSION'" ENDL \' +echo '#N": BUILD_LIBC'"\t"`getconf GNU_LIBC_VERSION | grep glibc | sed -e 's/^glibc //'`'" ENDL \' +echo '#N": BUILD_LD'"\t\t"`ld -v 2>&1 | grep 'version'`'" ENDL \' +echo '#N": BUILD_TARGET'"\t$arch on $runtime"'" ENDL \' +echo '#N": BUILD_COMMAND'"\t"$*'" ENDL \' +echo "" +echo "#define __TBB_DATETIME \""`date -u`"\"" diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_android.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_android.sh new file mode 100644 index 00000000..8d828b84 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_android.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script used to generate version info string +echo "#define __TBB_VERSION_STRINGS(N) \\" +echo '#N": BUILD_HOST'"\t\t"`hostname -s`" ("`uname -m`")"'" ENDL \' +# find OS name in *-release and issue* files by filtering blank lines and lsb-release content out +echo '#N": BUILD_OS'"\t\t"`lsb_release -sd 2>/dev/null | grep -ih '[a-z] ' - /etc/*release /etc/issue 2>/dev/null | head -1 | sed -e 's/["\\\\]//g'`'" ENDL \' +echo '#N": BUILD_TARGET_CXX'"\t"`$TARGET_CXX --version | head -n1`'" ENDL \' +[ -z "$COMPILER_VERSION" ] || echo '#N": BUILD_COMPILER'"\t"$COMPILER_VERSION'" ENDL \' +[ -z "$ndk_version" ] || echo '#N": BUILD_NDK'"\t\t$ndk_version"'" ENDL \' +echo '#N": BUILD_LD'"\t\t"`${tbb_tool_prefix}ld -v 2>&1 | grep 'ld'`'" ENDL \' +echo '#N": BUILD_TARGET'"\t$arch on $runtime"'" ENDL \' +echo '#N": BUILD_COMMAND'"\t"$*'" ENDL \' +echo "" +echo "#define __TBB_DATETIME \""`date -u`"\"" diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_linux.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_linux.sh new file mode 100644 index 00000000..793cad11 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_linux.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script used to generate version info string +echo "#define __TBB_VERSION_STRINGS(N) \\" +echo '#N": BUILD_HOST'"\t\t"`hostname -s`" ("`uname -m`")"'" ENDL \' +# find OS name in *-release and issue* files by filtering blank lines and lsb-release content out +echo '#N": BUILD_OS'"\t\t"`lsb_release -sd 2>/dev/null | grep -ih '[a-z] ' - /etc/*release /etc/issue 2>/dev/null | head -1 | sed -e 's/["\\\\]//g'`'" ENDL \' +echo '#N": BUILD_KERNEL'"\t"`uname -srv`'" ENDL \' +echo '#N": BUILD_GCC'"\t\t"`g++ --version &1 | grep 'g++'`'" ENDL \' +[ -z "$COMPILER_VERSION" ] || echo '#N": BUILD_COMPILER'"\t"$COMPILER_VERSION'" ENDL \' +echo '#N": BUILD_LIBC'"\t"`getconf GNU_LIBC_VERSION | grep glibc | sed -e 's/^glibc //'`'" ENDL \' +echo '#N": BUILD_LD'"\t\t"`ld -v 2>&1 | grep 'version'`'" ENDL \' +echo '#N": BUILD_TARGET'"\t$arch on $runtime"'" ENDL \' +echo '#N": BUILD_COMMAND'"\t"$*'" ENDL \' +echo "" +echo "#define __TBB_DATETIME \""`date -u`"\"" diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_macos.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_macos.sh new file mode 100644 index 00000000..b43c0e6b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_macos.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script used to generate version info string +echo "#define __TBB_VERSION_STRINGS(N) \\" +echo '#N": BUILD_HOST'"\t\t"`hostname -s`" ("`arch`")"'" ENDL \' +echo '#N": BUILD_OS'"\t\t"`sw_vers -productName`" version "`sw_vers -productVersion`'" ENDL \' +echo '#N": BUILD_KERNEL'"\t"`uname -v`'" ENDL \' +echo '#N": BUILD_CLANG'"\t"`clang --version | sed -n "1p"`'" ENDL \' +echo '#N": BUILD_XCODE'"\t"`xcodebuild -version &1 | grep 'Xcode'`'" ENDL \' +[ -z "$COMPILER_VERSION" ] || echo '#N": BUILD_COMPILER'"\t"$COMPILER_VERSION'" ENDL \' +echo '#N": BUILD_TARGET'"\t$arch on $runtime"'" ENDL \' +echo '#N": BUILD_COMMAND'"\t"$*'" ENDL \' +echo "" +echo "#define __TBB_DATETIME \""`date -u`"\"" diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_sunos.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_sunos.sh new file mode 100644 index 00000000..335fb419 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_sunos.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script used to generate version info string +echo "#define __TBB_VERSION_STRINGS(N) \\" +echo '#N": BUILD_HOST'"\t"`hostname`" ("`arch`")"'" ENDL \' +echo '#N": BUILD_OS'"\t\t"`uname`'" ENDL \' +echo '#N": BUILD_KERNEL'"\t"`uname -srv`'" ENDL \' +echo '#N": BUILD_SUNCC'"\t"`CC -V &1 | grep 'C++'`'" ENDL \' +[ -z "$COMPILER_VERSION" ] || echo '#N": BUILD_COMPILER'"\t"$COMPILER_VERSION'" ENDL \' +echo '#N": BUILD_TARGET'"\t$arch on $runtime"'" ENDL \' +echo '#N": BUILD_COMMAND'"\t"$*'" ENDL \' +echo "" +echo "#define __TBB_DATETIME \""`date -u`"\"" diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_windows.js b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_windows.js new file mode 100644 index 00000000..d3f4c0fb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/version_info_windows.js @@ -0,0 +1,91 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var WshShell = WScript.CreateObject("WScript.Shell"); + +var tmpExec; + +WScript.Echo("#define __TBB_VERSION_STRINGS(N) \\"); + +//Getting BUILD_HOST +WScript.echo( "#N \": BUILD_HOST\\t\\t" + + WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") + + "\" ENDL \\" ); + +//Getting BUILD_OS +tmpExec = WshShell.Exec("cmd /c ver"); +while ( tmpExec.Status == 0 ) { + WScript.Sleep(100); +} +tmpExec.StdOut.ReadLine(); + +WScript.echo( "#N \": BUILD_OS\\t\\t" + + tmpExec.StdOut.ReadLine() + + "\" ENDL \\" ); + +if ( WScript.Arguments(0).toLowerCase().match("gcc") ) { + tmpExec = WshShell.Exec(WScript.Arguments(0) + " --version"); + WScript.echo( "#N \": BUILD_GCC\\t\\t" + + tmpExec.StdOut.ReadLine() + + "\" ENDL \\" ); + +} else if ( WScript.Arguments(0).toLowerCase().match("clang") ) { + tmpExec = WshShell.Exec(WScript.Arguments(0) + " --version"); + WScript.echo( "#N \": BUILD_CLANG\\t" + + tmpExec.StdOut.ReadLine() + + "\" ENDL \\" ); + +} else { // MS / Intel compilers + //Getting BUILD_CL + tmpExec = WshShell.Exec("cmd /c echo #define 0 0>empty.cpp"); + tmpExec = WshShell.Exec("cl -c empty.cpp "); + while ( tmpExec.Status == 0 ) { + WScript.Sleep(100); + } + var clVersion = tmpExec.StdErr.ReadLine(); + WScript.echo( "#N \": BUILD_CL\\t\\t" + + clVersion + + "\" ENDL \\" ); + + //Getting BUILD_COMPILER + if ( WScript.Arguments(0).toLowerCase().match("icl") ) { + tmpExec = WshShell.Exec("icl -c empty.cpp "); + while ( tmpExec.Status == 0 ) { + WScript.Sleep(100); + } + WScript.echo( "#N \": BUILD_COMPILER\\t" + + tmpExec.StdErr.ReadLine() + + "\" ENDL \\" ); + } else { + WScript.echo( "#N \": BUILD_COMPILER\\t\\t" + + clVersion + + "\" ENDL \\" ); + } + tmpExec = WshShell.Exec("cmd /c del /F /Q empty.obj empty.cpp"); +} + +//Getting BUILD_TARGET +WScript.echo( "#N \": BUILD_TARGET\\t" + + WScript.Arguments(1) + + "\" ENDL \\" ); + +//Getting BUILD_COMMAND +WScript.echo( "#N \": BUILD_COMMAND\\t" + WScript.Arguments(2) + "\" ENDL" ); + +//Getting __TBB_DATETIME and __TBB_VERSION_YMD +var date = new Date(); +WScript.echo( "#define __TBB_DATETIME \"" + date.toUTCString() + "\"" ); +WScript.echo( "#define __TBB_VERSION_YMD " + date.getUTCFullYear() + ", " + + (date.getUTCMonth() > 8 ? (date.getUTCMonth()+1):("0"+(date.getUTCMonth()+1))) + + (date.getUTCDate() > 9 ? date.getUTCDate():("0"+date.getUTCDate())) ); diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/index.html new file mode 100644 index 00000000..5c584adb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/index.html @@ -0,0 +1,30 @@ + + + +

Overview

+This directory contains the Visual Studio* 2013 solution to build Intel® Threading Building Blocks. + + +

Files

+
+
makefile.sln +
Solution file.
+
tbb.vcxproj +
Library project file.
+
tbbmalloc.vcxproj +
Scalable allocator library project file.
+
tbbmalloc_proxy.vcxproj +
Standard allocator replacement project file.
+
+ +
+Up to parent directory +

+Copyright © 2017-2020 Intel Corporation. All Rights Reserved. +

+Intel and the Intel logo are trademarks of Intel Corporation +or its subsidiaries in the U.S. and/or other countries. +

+* Other names and brands may be claimed as the property of others. + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/makefile.sln b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/makefile.sln new file mode 100644 index 00000000..b913551e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/makefile.sln @@ -0,0 +1,80 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8898CE0B-0BFB-45AE-AA71-83735ED2510D}" + ProjectSection(SolutionItems) = preProject + index.html = index.html + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tbb", "tbb.vcxproj", "{F62787DD-1327-448B-9818-030062BCFAA5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tbbmalloc", "tbbmalloc.vcxproj", "{B15F131E-328A-4D42-ADC2-9FF4CA6306D8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tbbmalloc_proxy", "tbbmalloc_proxy.vcxproj", "{02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Debug-MT|Win32 = Debug-MT|Win32 + Debug-MT|x64 = Debug-MT|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Release-MT|Win32 = Release-MT|Win32 + Release-MT|x64 = Release-MT|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F62787DD-1327-448B-9818-030062BCFAA5}.Debug|Win32.ActiveCfg = Debug|Win32 + {F62787DD-1327-448B-9818-030062BCFAA5}.Debug|Win32.Build.0 = Debug|Win32 + {F62787DD-1327-448B-9818-030062BCFAA5}.Debug|x64.ActiveCfg = Debug|x64 + {F62787DD-1327-448B-9818-030062BCFAA5}.Debug|x64.Build.0 = Debug|x64 + {F62787DD-1327-448B-9818-030062BCFAA5}.Debug-MT|Win32.ActiveCfg = Debug-MT|Win32 + {F62787DD-1327-448B-9818-030062BCFAA5}.Debug-MT|Win32.Build.0 = Debug-MT|Win32 + {F62787DD-1327-448B-9818-030062BCFAA5}.Debug-MT|x64.ActiveCfg = Debug-MT|x64 + {F62787DD-1327-448B-9818-030062BCFAA5}.Debug-MT|x64.Build.0 = Debug-MT|x64 + {F62787DD-1327-448B-9818-030062BCFAA5}.Release|Win32.ActiveCfg = Release|Win32 + {F62787DD-1327-448B-9818-030062BCFAA5}.Release|Win32.Build.0 = Release|Win32 + {F62787DD-1327-448B-9818-030062BCFAA5}.Release|x64.ActiveCfg = Release|x64 + {F62787DD-1327-448B-9818-030062BCFAA5}.Release|x64.Build.0 = Release|x64 + {F62787DD-1327-448B-9818-030062BCFAA5}.Release-MT|Win32.ActiveCfg = Release-MT|Win32 + {F62787DD-1327-448B-9818-030062BCFAA5}.Release-MT|Win32.Build.0 = Release-MT|Win32 + {F62787DD-1327-448B-9818-030062BCFAA5}.Release-MT|x64.ActiveCfg = Release-MT|x64 + {F62787DD-1327-448B-9818-030062BCFAA5}.Release-MT|x64.Build.0 = Release-MT|x64 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Debug|Win32.ActiveCfg = Debug|Win32 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Debug|Win32.Build.0 = Debug|Win32 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Debug|x64.ActiveCfg = Debug|x64 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Debug|x64.Build.0 = Debug|x64 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Debug-MT|Win32.ActiveCfg = Debug-MT|Win32 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Debug-MT|Win32.Build.0 = Debug-MT|Win32 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Debug-MT|x64.ActiveCfg = Debug-MT|x64 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Debug-MT|x64.Build.0 = Debug-MT|x64 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Release|Win32.ActiveCfg = Release|Win32 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Release|Win32.Build.0 = Release|Win32 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Release|x64.ActiveCfg = Release|x64 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Release|x64.Build.0 = Release|x64 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Release-MT|Win32.ActiveCfg = Release-MT|Win32 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Release-MT|Win32.Build.0 = Release-MT|Win32 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Release-MT|x64.ActiveCfg = Release-MT|x64 + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8}.Release-MT|x64.Build.0 = Release-MT|x64 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Debug|Win32.ActiveCfg = Debug|Win32 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Debug|Win32.Build.0 = Debug|Win32 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Debug|x64.ActiveCfg = Debug|x64 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Debug|x64.Build.0 = Debug|x64 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Debug-MT|Win32.ActiveCfg = Debug-MT|Win32 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Debug-MT|Win32.Build.0 = Debug-MT|Win32 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Debug-MT|x64.ActiveCfg = Debug-MT|x64 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Debug-MT|x64.Build.0 = Debug-MT|x64 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Release|Win32.ActiveCfg = Release|Win32 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Release|Win32.Build.0 = Release|Win32 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Release|x64.ActiveCfg = Release|x64 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Release|x64.Build.0 = Release|x64 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Release-MT|Win32.ActiveCfg = Release-MT|Win32 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Release-MT|Win32.Build.0 = Release-MT|Win32 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Release-MT|x64.ActiveCfg = Release-MT|x64 + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7}.Release-MT|x64.Build.0 = Release-MT|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbb.vcxproj b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbb.vcxproj new file mode 100644 index 00000000..e1aa9b54 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbb.vcxproj @@ -0,0 +1,697 @@ + + + + + Debug-MT + Win32 + + + Debug-MT + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release-MT + Win32 + + + Release-MT + x64 + + + Release + Win32 + + + Release + x64 + + + + {F62787DD-1327-448B-9818-030062BCFAA5} + tbb + Win32Proj + + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + $(ProjectName)_debug + $(ProjectName)_debug + $(ProjectName)_debug + $(ProjectName)_debug + + + + /c /MDd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBB_BUILD=1 /W4 /I../../src /I../../src/rml/include /I../../include + Disabled + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + + + /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbb.def" %(AdditionalOptions) + $(OutDir)tbb_debug.dll + true + Windows + false + + + MachineX86 + + + + + X64 + + + /c /MDd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBB_BUILD=1 /W4 /I../../src /I../../src/rml/include /I../../include + Disabled + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Level4 + ProgramDatabase + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbb.def" %(AdditionalOptions) + $(OutDir)tbb_debug.dll + true + Windows + false + + + MachineX64 + false + + + + + /c /MD /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBB_BUILD=1 /W4 /I../../src /I../../src/rml/include /I../../include + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + ProgramDatabase + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbb.def" %(AdditionalOptions) + $(OutDir)tbb.dll + true + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + /c /MD /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBB_BUILD=1 /W4 /I../../src /I../../src/rml/include /I../../include + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + MultiThreadedDLL + Level4 + ProgramDatabase + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbb.def" %(AdditionalOptions) + $(OutDir)tbb.dll + true + Windows + true + true + false + + + MachineX64 + false + + + + + /c /MTd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBB_BUILD=1 /W4 /I../../src /I../../src/rml/include /I../../include + Disabled + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level4 + ProgramDatabase + + + /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbb.def" %(AdditionalOptions) + $(OutDir)tbb_debug.dll + true + Windows + false + + + MachineX86 + + + + + X64 + + + /c /MTd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBB_BUILD=1 /W4 /I../../src /I../../src/rml/include /I../../include + Disabled + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Level4 + ProgramDatabase + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbb.def" %(AdditionalOptions) + $(OutDir)tbb_debug.dll + true + Windows + false + + + MachineX64 + false + + + + + /c /MT /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBB_BUILD=1 /W4 /I../../src /I../../src/rml/include /I../../include + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + MultiThreaded + + + Level4 + ProgramDatabase + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbb.def" %(AdditionalOptions) + $(OutDir)tbb.dll + true + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + /c /MT /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBB_BUILD=1 /W4 /I../../src /I../../src/rml/include /I../../include + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + MultiThreaded + Level4 + ProgramDatabase + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbb.def" %(AdditionalOptions) + $(OutDir)tbb.dll + true + Windows + true + true + false + + + MachineX64 + false + + + + + /coff /Zi + true + true + /coff /Zi + true + true + /coff + true + true + /coff + true + true + + + true + building atomic_support.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DUSE_FRAME_POINTER /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/atomic_support.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building atomic_support.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DUSE_FRAME_POINTER /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/atomic_support.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building atomic_support.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/atomic_support.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building atomic_support.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/atomic_support.asm + $(IntDir)%(FileName).obj;%(Outputs) + + + true + building intel64_misc.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DUSE_FRAME_POINTER /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/intel64_misc.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building intel64_misc.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DUSE_FRAME_POINTER /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/intel64_misc.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building intel64_misc.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/intel64_misc.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building intel64_misc.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/intel64_misc.asm + $(IntDir)%(FileName).obj;%(Outputs) + + + /coff /Zi + true + true + /coff /Zi + true + true + /coff + true + true + /coff + true + true + + + true + building itsx.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DUSE_FRAME_POINTER /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/itsx.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building itsx.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DUSE_FRAME_POINTER /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/itsx.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building itsx.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/itsx.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building itsx.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/itsx.asm + $(IntDir)%(FileName).obj;%(Outputs) + + + /coff /Zi + true + true + /coff /Zi + /coff /Zi + true + true + /coff /Zi + /coff + true + true + /coff + true + true + + + + + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /I../../src /I../../include >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + true + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /I../../src /I../../include >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + true + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /I../../src /I../../include >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + true + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /I../../src /I../../include >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + true + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + + + true + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /I../../src /I../../include >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + true + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /I../../src /I../../include >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + true + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /I../../src /I../../include >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + true + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + generating tbb.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbb-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /I../../src /I../../include >"$(IntDir)tbb.def" + + $(IntDir)tbb.def;%(Outputs) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + + + + + + + \ No newline at end of file diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbbmalloc.vcxproj b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbbmalloc.vcxproj new file mode 100644 index 00000000..b8f21dd5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbbmalloc.vcxproj @@ -0,0 +1,559 @@ + + + + + Debug-MT + Win32 + + + Debug-MT + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release-MT + Win32 + + + Release-MT + x64 + + + Release + Win32 + + + Release + x64 + + + + {B15F131E-328A-4D42-ADC2-9FF4CA6306D8} + tbbmalloc + Win32Proj + + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + $(ProjectName)_debug + $(ProjectName)_debug + $(ProjectName)_debug + $(ProjectName)_debug + + + + /c /MDd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc /I. + Disabled + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + Level4 + ProgramDatabase + false + + + /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbbmalloc.def" %(AdditionalOptions) + $(OutDir)tbbmalloc_debug.dll + true + Windows + false + + + MachineX86 + + + + + X64 + + + /c /MDd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc /I. + Disabled + .;%(AdditionalIncludeDirectories) + false + Default + MultiThreadedDebugDLL + true + Level4 + ProgramDatabase + false + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbbmalloc.def" %(AdditionalOptions) + $(OutDir)tbbmalloc_debug.dll + true + Windows + false + + + MachineX64 + + + + + /c /MD /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc /I. + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + MultiThreadedDLL + Level4 + ProgramDatabase + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbbmalloc.def" %(AdditionalOptions) + $(OutDir)tbbmalloc.dll + true + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + /c /MD /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc /I. + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + MultiThreadedDLL + Level4 + ProgramDatabase + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbbmalloc.def" %(AdditionalOptions) + $(OutDir)tbbmalloc.dll + true + Windows + true + true + false + + + MachineX64 + + + + + /c /MTd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc /I. + Disabled + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + Level4 + ProgramDatabase + false + + + /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbbmalloc.def" %(AdditionalOptions) + $(OutDir)tbbmalloc_debug.dll + true + Windows + false + + + MachineX86 + + + + + X64 + + + /c /MTd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc /I. + Disabled + .;%(AdditionalIncludeDirectories) + false + Default + MultiThreadedDebug + true + Level4 + ProgramDatabase + false + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbbmalloc.def" %(AdditionalOptions) + $(OutDir)tbbmalloc_debug.dll + true + Windows + false + + + MachineX64 + + + + + /c /MT /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc /I. + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + MultiThreaded + Level4 + ProgramDatabase + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbbmalloc.def" %(AdditionalOptions) + $(OutDir)tbbmalloc.dll + true + Windows + true + true + false + MachineX86 + + + + + X64 + + + /c /MT /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc /I. + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + MultiThreaded + Level4 + ProgramDatabase + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DEF:"$(IntDir)tbbmalloc.def" %(AdditionalOptions) + $(OutDir)tbbmalloc.dll + true + Windows + true + true + false + + + MachineX64 + + + + + true + building atomic_support.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DUSE_FRAME_POINTER /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/atomic_support.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building atomic_support.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DUSE_FRAME_POINTER /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/atomic_support.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building atomic_support.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/atomic_support.asm + $(IntDir)%(FileName).obj;%(Outputs) + true + building atomic_support.obj + ml64 /Fo"$(IntDir)%(FileName).obj" /DEM64T=1 /c /Zi ../../src/tbb/intel64-masm/atomic_support.asm + $(IntDir)%(FileName).obj;%(Outputs) + + + + + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win32-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + true + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win32-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win32-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + true + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win32-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win32-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + true + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win32-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + true + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbb/win32-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + + + true + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win64-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + true + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win64-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + true + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win64-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + true + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbb/win64-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + generating tbbmalloc.def file + cl /nologo /TC /EP ../../src/tbbmalloc/win64-tbbmalloc-export.def /DTBB_USE_DEBUG /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBBMALLOC_BUILD=1 >"$(IntDir)tbbmalloc.def" + + $(IntDir)tbbmalloc.def;%(Outputs) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + + + + + {f62787dd-1327-448b-9818-030062bcfaa5} + false + + + + + + + \ No newline at end of file diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbbmalloc_proxy.vcxproj b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbbmalloc_proxy.vcxproj new file mode 100644 index 00000000..23dac2f6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/tbbmalloc_proxy.vcxproj @@ -0,0 +1,425 @@ + + + + + Debug-MT + Win32 + + + Debug-MT + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release-MT + Win32 + + + Release-MT + x64 + + + Release + Win32 + + + Release + x64 + + + + {02F61511-D5B6-46E6-B4BB-DEAA96E6BCC7} + tbbmalloc_proxy + Win32Proj + + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + DynamicLibrary + NotSet + true + v120 + + + DynamicLibrary + NotSet + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(ProjectName)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + $(ProjectName)_debug + $(ProjectName)_debug + $(ProjectName)_debug + $(ProjectName)_debug + + + + /c /MDd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /W4 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc + Disabled + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + Sync + Default + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + + + /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO %(AdditionalOptions) + $(OutDir)tbbmalloc_proxy_debug.dll + true + Windows + false + + + MachineX86 + + + + + X64 + + + /c /MDd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /W4 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc + Disabled + .;%(AdditionalIncludeDirectories) + false + + + Default + MultiThreadedDebugDLL + true + + + Level4 + ProgramDatabase + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO %(AdditionalOptions) + $(OutDir)tbbmalloc_proxy_debug.dll + true + Windows + false + + + MachineX64 + + + + + /c /MD /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /W4 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + MultiThreadedDLL + + + Level4 + ProgramDatabase + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO %(AdditionalOptions) + $(OutDir)tbbmalloc_proxy.dll + true + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + /c /MD /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /W4 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + MultiThreadedDLL + + + Level4 + ProgramDatabase + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO %(AdditionalOptions) + $(OutDir)tbbmalloc_proxy.dll + true + Windows + true + true + false + + + MachineX64 + + + + + /c /MTd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /W4 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc + Disabled + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + true + Sync + Default + MultiThreadedDebug + + + Level4 + ProgramDatabase + + + /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO %(AdditionalOptions) + $(OutDir)tbbmalloc_proxy_debug.dll + true + Windows + false + + + MachineX86 + + + + + X64 + + + /c /MTd /Od /Ob0 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /DTBB_USE_DEBUG /D__TBB_LIB_NAME=tbb_debug.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /W4 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc + Disabled + .;%(AdditionalIncludeDirectories) + false + + + Default + MultiThreadedDebug + true + + + Level4 + ProgramDatabase + false + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO %(AdditionalOptions) + $(OutDir)tbbmalloc_proxy_debug.dll + true + Windows + false + + + MachineX64 + + + + + /c /MT /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /W4 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + MultiThreaded + + + Level4 + ProgramDatabase + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO %(AdditionalOptions) + $(OutDir)tbbmalloc_proxy.dll + true + Windows + true + true + false + + + MachineX86 + + + + + X64 + + + /c /MT /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /DTBB_SUPPRESS_DEPRECATED_MESSAGES=1 /D__TBB_LIB_NAME=tbb.lib /DDO_ITT_NOTIFY /GS /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0502 /W4 /D__TBBMALLOC_BUILD=1 /I../../src /I../../src/rml/include /I../../include /I../../src/tbbmalloc /I../../src/tbbmalloc + .;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + MultiThreaded + + + Level4 + ProgramDatabase + + + /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO %(AdditionalOptions) + $(OutDir)tbbmalloc_proxy.dll + true + Windows + true + true + false + + + MachineX64 + + + + + + + + + + + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + /I../../src /I../../include /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 %(AdditionalOptions) + + + + + + + {b15f131e-328a-4d42-adc2-9ff4ca6306d8} + false + + + + + + + \ No newline at end of file diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/version_string.ver b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/version_string.ver new file mode 100644 index 00000000..5d8f04e5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/vs2013/version_string.ver @@ -0,0 +1 @@ +#define __TBB_VERSION_STRINGS(N) "Empty" diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.cl.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.cl.inc new file mode 100644 index 00000000..732b854f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.cl.inc @@ -0,0 +1,162 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#------------------------------------------------------------------------------ +# Define compiler-specific variables. +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Setting compiler flags. +#------------------------------------------------------------------------------ +CPLUS ?= cl /nologo +LINK_FLAGS = /link /nologo +LIB_LINK_FLAGS=/link /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DYNAMICBASE /NXCOMPAT + +ifneq (,$(stdver)) + CXX_STD_FLAGS = /std:$(stdver) +endif + +ifeq ($(arch), ia32) + LIB_LINK_FLAGS += /SAFESEH +endif + +ifeq ($(runtime), vc_mt) + MS_CRT_KEY = /MT$(if $(findstring debug,$(cfg)),d) +else + MS_CRT_KEY = /MD$(if $(findstring debug,$(cfg)),d) +endif +EH_FLAGS = $(if $(no_exceptions),/EHs-,/EHsc /GR) + +# UWD binaries have to use static CRT linkage +ifeq ($(target_app), uwd) + MS_CRT_KEY = /MT$(if $(findstring debug,$(cfg)),d) +endif + +ifeq ($(cfg), release) + CPLUS_FLAGS = $(MS_CRT_KEY) /O2 /Zi $(EH_FLAGS) /Zc:forScope /Zc:wchar_t /D__TBB_LIB_NAME=$(TBB.LIB) + ASM_FLAGS = +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = $(MS_CRT_KEY) /Od /Ob0 /Zi $(EH_FLAGS) /Zc:forScope /Zc:wchar_t /DTBB_USE_DEBUG /D__TBB_LIB_NAME=$(TBB.LIB) + ASM_FLAGS = /DUSE_FRAME_POINTER +endif + +ZW_KEY = /ZW:nostdlib + +# These flags are general for Windows* universal applications +ifneq (,$(target_app)) + CPLUS_FLAGS += $(ZW_KEY) /D "_UNICODE" /D "UNICODE" /D "WINAPI_FAMILY=WINAPI_FAMILY_APP" +endif + +ifeq ($(target_app), win8ui) + _WIN32_WINNT = 0x0602 +else ifneq (,$(filter $(target_app),uwp uwd)) + _WIN32_WINNT = 0x0A00 + LIB_LINK_FLAGS += /NODEFAULTLIB:kernel32.lib OneCore.lib +else + CPLUS_FLAGS += /DDO_ITT_NOTIFY +endif +ifeq ($(target_mode), store) +# it is necessary to source vcvars with 'store' argument in production + LIB_LINK_FLAGS += /APPCONTAINER +endif + +CPLUS_FLAGS += /GS + +COMPILE_ONLY = /c +PREPROC_ONLY = /TP /EP +INCLUDE_KEY = /I +DEFINE_KEY = /D +OUTPUT_KEY = /Fe +OUTPUTOBJ_KEY = /Fo +WARNING_AS_ERROR_KEY = /WX +WARNING_SUPPRESS = $(if $(no_exceptions),/wd4530 /wd4577) +BIGOBJ_KEY = /bigobj + +ifeq ($(runtime),vc7.1) + WARNING_KEY = /W3 +else + WARNING_KEY = /W4 + OPENMP_FLAG = /openmp +endif + +DYLIB_KEY = /DLL +EXPORT_KEY = /DEF: +NODEFAULTLIB_KEY = /Zl +NOINTRINSIC_KEY = /Oi- + +INCLUDE_TEST_HEADERS = /FI$(tbb_root)/src/test/harness_preload.h + +ifeq ($(runtime),vc8) + WARNING_KEY += /Wp64 + CPLUS_FLAGS += /D_USE_RTM_VERSION +endif + +# Since VS2012, VC++ provides /volatile option to control semantics of volatile variables. +# We want to use strict ISO semantics in the library and tests +ifeq (ok,$(call detect_js,/minversion cl 17)) + CPLUS_FLAGS += /volatile:iso +endif + +# Since VS2013, VC++ uses the same .pdb file for different sources so we need +# to add /FS (Force Synchronous PDB Writes) +ifeq (ok,$(call detect_js,/minversion cl 18)) + CPLUS_FLAGS += /FS +endif + +CPLUS_FLAGS += /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE \ + /D_WIN32_WINNT=$(_WIN32_WINNT) +C_FLAGS = $(subst $(ZW_KEY),,$(subst $(EH_FLAGS),,$(CPLUS_FLAGS))) + +#------------------------------------------------------------------------------ +# End of setting compiler flags. +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASSEMBLY_SOURCE=$(arch)-masm +ifeq (intel64,$(arch)) + ASM=ml64 /nologo + ASM_FLAGS += /DEM64T=1 /c /Zi + TBB_ASM.OBJ = atomic_support.obj intel64_misc.obj itsx.obj + MALLOC_ASM.OBJ = atomic_support.obj +else +ifeq (armv7,$(arch)) + ASM= + TBB_ASM.OBJ= +else + ASM=ml /nologo + ASM_FLAGS += /c /coff /Zi /safeseh + TBB_ASM.OBJ = atomic_support.obj lock_byte.obj itsx.obj +endif +endif +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ +M_CPLUS_FLAGS = $(CPLUS_FLAGS) +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# End of define compiler-specific variables. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.gcc.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.gcc.inc new file mode 100644 index 00000000..dc123eed --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.gcc.inc @@ -0,0 +1,138 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#------------------------------------------------------------------------------ +# Overriding settings from windows.inc +#------------------------------------------------------------------------------ + +SLASH= $(strip \) +OBJ = o +LIBEXT = dll # MinGW allows linking with DLLs directly + +TBB.RES = +MALLOC.RES = +RML.RES = +TBB.MANIFEST = +MALLOC.MANIFEST = +RML.MANIFEST = + +ifeq (ia32,$(arch)) + TBB.LST = $(tbb_root)/src/tbb/lin32-tbb-export.lst +else + TBB.LST = $(tbb_root)/src/tbb/win64-gcc-tbb-export.lst +endif +MALLOC.DEF = $(MALLOC_ROOT)/$(def_prefix)-gcc-tbbmalloc-export.def +RML.DEF = $(RML_SERVER_ROOT)/lin-rml-export.def + +LINK_TBB.LIB = $(TBB.LIB) +# no TBB proxy for the configuration +PROXY.LIB = + +#------------------------------------------------------------------------------ +# End of overridden settings +#------------------------------------------------------------------------------ +# Compiler-specific variables +#------------------------------------------------------------------------------ + +CPLUS ?= g++ +COMPILE_ONLY = -c -MMD +PREPROC_ONLY = -E -x c++ +INCLUDE_KEY = -I +DEFINE_KEY = -D +OUTPUT_KEY = -o # +OUTPUTOBJ_KEY = -o # +PIC_KEY = +WARNING_AS_ERROR_KEY = -Werror +WARNING_KEY = -Wall +TEST_WARNING_KEY = -Wextra -Wshadow -Wcast-qual -Woverloaded-virtual -Wnon-virtual-dtor -Wno-uninitialized +WARNING_SUPPRESS = -Wno-parentheses -Wno-uninitialized -Wno-non-virtual-dtor +DYLIB_KEY = -shared +LIBDL = +EXPORT_KEY = -Wl,--version-script, +LIBS = -lpsapi +BIGOBJ_KEY = -Wa,-mbig-obj + +#------------------------------------------------------------------------------ +# End of compiler-specific variables +#------------------------------------------------------------------------------ +# Command lines +#------------------------------------------------------------------------------ + +LINK_FLAGS = -Wl,--enable-auto-import +LIB_LINK_FLAGS = $(DYLIB_KEY) + +# gcc 4.8 and later support RTM intrinsics, but require command line switch to enable them +ifeq (ok,$(call detect_js,/minversion gcc 4.8)) + RTM_KEY = -mrtm +endif + +# gcc 6.0 and later have -flifetime-dse option that controls +# elimination of stores done outside the object lifetime +ifeq (ok,$(call detect_js,/minversion gcc 6.0)) + # keep pre-contruction stores for zero initialization + DSE_KEY = -flifetime-dse=1 +endif + +ifeq ($(cfg), release) + CPLUS_FLAGS = -O2 +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = -g -O0 -DTBB_USE_DEBUG +endif + +CPLUS_FLAGS += -DUSE_WINTHREAD +CPLUS_FLAGS += -D_WIN32_WINNT=$(_WIN32_WINNT) + +# MinGW specific +CPLUS_FLAGS += -DMINGW_HAS_SECURE_API=1 -D__MSVCRT_VERSION__=0x0700 -msse -mthreads + +CONLY = gcc +debugger = gdb +C_FLAGS = $(CPLUS_FLAGS) + +ifeq (intel64,$(arch)) + CPLUS_FLAGS += -m64 $(RTM_KEY) + LIB_LINK_FLAGS += -m64 +endif + +ifeq (ia32,$(arch)) + CPLUS_FLAGS += -m32 -march=i686 $(RTM_KEY) + LIB_LINK_FLAGS += -m32 +endif + +# For examples +export UNIXMODE = 1 + +#------------------------------------------------------------------------------ +# End of command lines +#------------------------------------------------------------------------------ +# Setting assembler data +#------------------------------------------------------------------------------ + +ASM= +ASM_FLAGS= +TBB_ASM.OBJ= +ASSEMBLY_SOURCE=$(arch)-gas + +#------------------------------------------------------------------------------ +# End of setting assembler data +#------------------------------------------------------------------------------ +# Setting tbbmalloc data +#------------------------------------------------------------------------------ + +M_CPLUS_FLAGS = $(CPLUS_FLAGS) -fno-rtti -fno-exceptions + +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.icl.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.icl.inc new file mode 100644 index 00000000..e3b0c0ff --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.icl.inc @@ -0,0 +1,184 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#------------------------------------------------------------------------------ +# Define compiler-specific variables. +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Setting default configuration to release. +#------------------------------------------------------------------------------ +cfg ?= release +#------------------------------------------------------------------------------ +# End of setting default configuration to release. +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Setting compiler flags. +#------------------------------------------------------------------------------ +CPLUS ?= icl /nologo $(VCCOMPAT_FLAG) +LINK_FLAGS = /link /nologo +LIB_LINK_FLAGS= /link /nologo /DLL /MAP /DEBUG /fixed:no /INCREMENTAL:NO /DYNAMICBASE /NXCOMPAT + +ifeq ($(arch), ia32) + LIB_LINK_FLAGS += /SAFESEH +endif + +ifneq (,$(stdver)) + CXX_STD_FLAGS = /Qstd=$(stdver) +endif + +# ICC 12.0 and higher provide Intel(R) Cilk(TM) Plus +ifeq (ok,$(call detect_js,/minversion icl 12)) + CILK_AVAILABLE = yes +endif + +# ICC 17.0.4 and higher provide support for VS2017 +ifeq (ok,$(call detect_js,/minversion icl 17 4)) + VS2017_SUPPORT = yes +endif + +# ICC 19.0.4 and higher provide support for VS2019 +ifeq (ok,$(call detect_js,/minversion icl 19 4)) + VS2019_SUPPORT = yes +endif + +ifeq ($(runtime), vc_mt) + MS_CRT_KEY = /MT$(if $(findstring debug,$(cfg)),d) +else + MS_CRT_KEY = /MD$(if $(findstring debug,$(cfg)),d) +endif +EH_FLAGS = $(if $(no_exceptions),/EHs-,/EHsc /GR) + +ifeq ($(cfg), release) + CPLUS_FLAGS = $(MS_CRT_KEY) /O2 /Zi /Qopt-report-embed- $(EH_FLAGS) /Zc:forScope /Zc:wchar_t /D__TBB_LIB_NAME=$(TBB.LIB) + ASM_FLAGS = +endif +ifeq ($(cfg), debug) + CPLUS_FLAGS = $(MS_CRT_KEY) /Od /Ob0 /Zi $(EH_FLAGS) /Zc:forScope /Zc:wchar_t /DTBB_USE_DEBUG /D__TBB_LIB_NAME=$(TBB.LIB) + ASM_FLAGS = /DUSE_FRAME_POINTER +endif +CPLUS_FLAGS += /GS + +COMPILE_ONLY = /c /QMMD +# PREPROC_ONLY should really use /TP which applies to all files in the command line. +# But with /TP, ICL does not preprocess *.def files. +PREPROC_ONLY = /EP /Tp +INCLUDE_KEY = /I +DEFINE_KEY = /D +OUTPUT_KEY = /Fe +OUTPUTOBJ_KEY = /Fo +WARNING_AS_ERROR_KEY = /WX +WARNING_KEY = /W3 +WARNING_SUPPRESS = $(if $(no_exceptions),/wd583) +DYLIB_KEY = /DLL +EXPORT_KEY = /DEF: +NODEFAULTLIB_KEY = /Zl +NOINTRINSIC_KEY = /Oi- +BIGOBJ_KEY = /bigobj +INCLUDE_TEST_HEADERS = /FI$(tbb_root)/src/test/harness_preload.h + + +ifneq (,$(codecov)) + CPLUS_FLAGS += /Qprof-genx +else + CPLUS_FLAGS += /DDO_ITT_NOTIFY +endif + +OPENMP_FLAG = /Qopenmp +CPLUS_FLAGS += /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE \ + /D_WIN32_WINNT=$(_WIN32_WINNT) + +ifeq ($(runtime),vc8) + CPLUS_FLAGS += /D_USE_RTM_VERSION +endif + + +C_FLAGS = $(subst $(EH_FLAGS),,$(CPLUS_FLAGS)) + +VCVERSION:=$(runtime) +VCCOMPAT_FLAG ?= $(if $(findstring vc7.1, $(VCVERSION)),/Qvc7.1) +ifeq ($(VCCOMPAT_FLAG),) + VCCOMPAT_FLAG := $(if $(findstring vc8, $(VCVERSION)),/Qvc8) +endif +ifeq ($(VCCOMPAT_FLAG),) + VCCOMPAT_FLAG := $(if $(findstring vc_mt, $(VCVERSION)),/Qvc14) +endif +ifeq ($(VCCOMPAT_FLAG),) + VCCOMPAT_FLAG := $(if $(findstring vc9, $(VCVERSION)),/Qvc9) +endif +ifeq ($(VCCOMPAT_FLAG),) + VCCOMPAT_FLAG := $(if $(findstring vc10, $(VCVERSION)),/Qvc10) +endif +ifeq ($(VCCOMPAT_FLAG),) + VCCOMPAT_FLAG := $(if $(findstring vc11, $(VCVERSION)),/Qvc11) +endif +ifeq ($(VCCOMPAT_FLAG),) + VCCOMPAT_FLAG := $(if $(findstring vc12, $(VCVERSION)),/Qvc12) +endif +ifeq ($(VCCOMPAT_FLAG),) + VCCOMPAT_FLAG := $(if $(findstring vc14, $(VCVERSION)),/Qvc14) + ifeq ($(VS2017_SUPPORT),yes) + ifneq (,$(findstring vc14.1, $(VCVERSION))) + VCCOMPAT_FLAG := /Qvc14.1 + endif + endif + ifeq ($(VS2019_SUPPORT),yes) + ifneq (,$(findstring vc14.2, $(VCVERSION))) + VCCOMPAT_FLAG := /Qvc14.2 + endif + endif +endif +ifeq ($(VCCOMPAT_FLAG),) + $(error VC version not detected correctly: $(VCVERSION) ) +endif +export VCCOMPAT_FLAG + +#------------------------------------------------------------------------------ +# End of setting compiler flags. +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Setting assembler data. +#------------------------------------------------------------------------------ +ASSEMBLY_SOURCE=$(arch)-masm +ifeq (intel64,$(arch)) + ASM=ml64 /nologo + ASM_FLAGS += /DEM64T=1 /c /Zi + TBB_ASM.OBJ = atomic_support.obj intel64_misc.obj itsx.obj + MALLOC_ASM.OBJ = atomic_support.obj +else + ASM=ml /nologo + ASM_FLAGS += /c /coff /Zi /safeseh + TBB_ASM.OBJ = atomic_support.obj lock_byte.obj itsx.obj +endif +#------------------------------------------------------------------------------ +# End of setting assembler data. +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Setting tbbmalloc data. +#------------------------------------------------------------------------------ +M_CPLUS_FLAGS = $(CPLUS_FLAGS) +#------------------------------------------------------------------------------ +# End of setting tbbmalloc data. +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# End of define compiler-specific variables. +#------------------------------------------------------------------------------ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.inc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.inc new file mode 100644 index 00000000..dafd8928 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/build/windows.inc @@ -0,0 +1,118 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +export SHELL = cmd + +ifdef tbb_build_dir + test_dir:=$(tbb_build_dir) +else + test_dir:=. +endif + +# A convenience wrapper for calls to detect.js. +# $(1) is the full command line for the script, e.g. /minversion icl 12 +detect_js = $(shell cmd /C "cscript /nologo /E:jscript $(tbb_root)/build/detect.js $(1)") + +# TODO give an error if archs doesn't match +ifndef arch + export arch:=$(call detect_js, /arch $(compiler)) +endif + +ifndef runtime + export runtime:=$(call detect_js, /runtime $(compiler)) +endif + +native_compiler := cl +export compiler ?= cl +debugger ?= devenv /debugexe + +CMD=cmd /C +CWD=$(shell cmd /C echo %CD%) +RM=cmd /C del /Q /F +RD=cmd /C rmdir +MD=cmd /c mkdir +SLASH=\\ +NUL = nul + +AR=lib +AR_OUTPUT_KEY=/out: +AR_FLAGS=/nologo /nodefaultlib + +OBJ = obj +DLL = dll +LIBEXT = lib +ASMEXT = asm + +def_prefix = $(if $(findstring intel64,$(arch)),win64,win32) + +# Target Windows version. Do not increase beyond 0x0502 without prior discussion! +# Used as the value for macro definition option in windows.cl.inc etc. +# For tests, we need at least Windows XP SP2 for sake of enabling stack backtraces. +ifeq (1,$(tbb_cpf)) +_WIN32_WINNT=0x0600 +else +_WIN32_WINNT=0x0502 +endif + +TBB.LST = $(tbb_root)/src/tbb/$(def_prefix)-tbb-export.lst +TBB.DEF = $(TBB.LST:.lst=.def) +TBB.DLL = tbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(DLL) +TBB.LIB = tbb$(CPF_SUFFIX)$(DEBUG_SUFFIX).$(LIBEXT) +TBB.RES = tbb_resource.res +# On Windows, we use #pragma comment to set the proper TBB lib to link with. +# But for cross-configuration testing, need to link explicitly. +# Tests use this variable to detect dependency on TBB binary, so have to be non-empty. +LINK_TBB.LIB = $(if $(crosstest),$(TBB.LIB),$(DEFINE_KEY)__TBB_IMPLICITLY_LINKED) +TBB.MANIFEST = +ifneq ($(filter vc8 vc9,$(runtime)),) + TBB.MANIFEST = tbbmanifest.exe.manifest +endif + +TBBBIND.DEF = $(tbb_root)/src/tbb/$(def_prefix)-tbbbind-export.def +TBBBIND.DLL = tbbbind$(DEBUG_SUFFIX).$(DLL) +TBBBIND.LIB = tbbbind$(DEBUG_SUFFIX).$(LIBEXT) +TBBBIND.RES = tbbbind.res +LINK_TBBBIND.LIB = $(TBBBIND.LIB) +HWLOC.LIB = libhwloc.$(LIBEXT) + +MALLOC.DEF = $(MALLOC_ROOT)/$(def_prefix)-tbbmalloc-export.def +MALLOC.DLL = tbbmalloc$(DEBUG_SUFFIX).$(DLL) +MALLOC.LIB = tbbmalloc$(DEBUG_SUFFIX).$(LIBEXT) +MALLOC.RES = tbbmalloc.res +MALLOC.MANIFEST = +ifneq ($(filter vc8 vc9,$(runtime)),) +MALLOC.MANIFEST = tbbmanifest.exe.manifest +endif +LINK_MALLOC.LIB = $(MALLOC.LIB) + +MALLOCPROXY.DLL = tbbmalloc_proxy$(DEBUG_SUFFIX).$(DLL) +MALLOCPROXY.LIB = tbbmalloc_proxy$(DEBUG_SUFFIX).$(LIBEXT) +LINK_MALLOCPROXY.LIB = $(MALLOCPROXY.LIB) + +PROXY.LIB = tbbproxy$(DEBUG_SUFFIX).$(LIBEXT) + +RML.DEF = $(RML_SERVER_ROOT)/$(def_prefix)-rml-export.def +RML.DLL = irml$(DEBUG_SUFFIX).$(DLL) +RML.LIB = irml$(DEBUG_SUFFIX).$(LIBEXT) +RML.RES = irml.res +ifneq ($(filter vc8 vc9,$(runtime)),) +RML.MANIFEST = tbbmanifest.exe.manifest +endif + +MAKE_VERSIONS = cmd /C cscript /nologo /E:jscript $(subst \,/,$(tbb_root))/build/version_info_windows.js $(compiler) $(arch) $(subst \,/,"$(VERSION_FLAGS)") > version_string.ver +MAKE_TBBVARS = cmd /C "$(subst /,\,$(tbb_root))\build\generate_tbbvars.bat" + +TEST_LAUNCHER = $(subst /,\,$(tbb_root))\build\test_launcher.bat $(largs) + +OPENCL.LIB = OpenCL.$(LIBEXT) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/README.rst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/README.rst new file mode 100644 index 00000000..6997a437 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/README.rst @@ -0,0 +1,361 @@ +.. contents:: + +Introduction +------------ +Many developers use CMake to manage their development projects, so the Threading Building Blocks (TBB) +team created the set of CMake modules to simplify integration of the TBB library into a CMake project. +The modules are available starting from TBB 2017 U7 in `/cmake `_. + +About TBB +^^^^^^^^^^^^^^^ +TBB is a library that supports scalable parallel programming using standard ISO C++ code. It does not require special languages or compilers. It is designed to promote scalable data parallel programming. Additionally, it fully supports nested parallelism, so you can build larger parallel components from smaller parallel components. To use the library, you specify tasks, not threads, and let the library map tasks onto threads in an efficient manner. + +Many of the library interfaces employ generic programming, in which interfaces are defined by requirements on types and not specific types. The C++ Standard Template Library (STL) is an example of generic programming. Generic programming enables TBB to be flexible yet efficient. The generic interfaces enable you to customize components to your specific needs. + +The net result is that TBB enables you to specify parallelism far more conveniently than using raw threads, and at the same time can improve performance. + +References +^^^^^^^^^^ +* `Official TBB open source site `_ +* `Official GitHub repository `_ + +Engineering team contacts +^^^^^^^^^^^^^^^^^^^^^^^^^ +The TBB team is very interested in convenient integration of the TBB library into customer projects. These CMake modules were created to provide such a possibility for CMake projects using a simple but powerful interface. We hope you will try these modules and we are looking forward to receiving your feedback! + +E-mail us: `inteltbbdevelopers@intel.com `_. + +Visit our `forum `_. + +Release Notes +------------- +* Minimum supported CMake version: ``3.0.0``. +* TBB versioning via `find_package `_ has the following format: ``find_package(TBB . ...)``. + +Use cases of TBB integration into CMake-aware projects +------------------------------------------------------------ +There are two types of TBB packages: + * Binary packages with pre-built binaries for Windows* OS, Linux* OS and macOS*. They are available on the releases page of the Github repository: https://github.com/01org/tbb/releases. The main purpose of the binary package integration is the ability to build TBB header files and binaries into your CMake-aware project. + * A source package is also available to download from the release page via the "Source code" link. In addition, it can be cloned from the repository by ``git clone https://github.com/01org/tbb.git``. The main purpose of the source package integration is to allow you to do a custom build of the TBB library from the source files and then build that into your CMake-aware project. + +There are four types of CMake modules that can be used to integrate TBB: `TBBConfig`, `TBBGet`, `TBBMakeConfig` and `TBBBuild`. See `Technical documentation for CMake modules`_ section for additional details. + +Binary package integration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following use case is valid for packages starting from TBB 2017 U7: + +* Download package manually and make integration. + + Pre-condition: Location of TBBConfig.cmake is available via ``TBB_DIR`` or ``CMAKE_PREFIX_PATH`` contains path to TBB root. + + CMake code for integration: + .. code:: cmake + + find_package(TBB ) + +The following use case is valid for all TBB 2017 packages. + +* Download package using TBBGet_ and make integration. + + Pre-condition: TBB CMake modules are available via . + + CMake code for integration: + .. code:: cmake + + include(/TBBGet.cmake) + tbb_get(TBB_ROOT tbb_root CONFIG_DIR TBB_DIR) + find_package(TBB ) + +Source package integration +^^^^^^^^^^^^^^^^^^^^^^^^^^ +* Build TBB from existing source files using TBBBuild_ and make integration. + + Pre-condition: TBB source code is available via and TBB CMake modules are available via . + + CMake code for integration: + .. code:: cmake + + include(/TBBBuild.cmake) + tbb_build(TBB_ROOT CONFIG_DIR TBB_DIR) + find_package(TBB ) + +* Download TBB source files using TBBGet_, build it using TBBBuild_ and make integration. + + Pre-condition: TBB CMake modules are available via . + + CMake code for integration: + .. code:: cmake + + include(/TBBGet.cmake) + include(/TBBBuild.cmake) + tbb_get(TBB_ROOT tbb_root SOURCE_CODE) + tbb_build(TBB_ROOT ${tbb_root} CONFIG_DIR TBB_DIR) + find_package(TBB ) + +Tutorials: TBB integration using CMake +-------------------------------------------- +Binary TBB integration to the sub_string_finder sample (Windows* OS) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In this example, we will integrate binary TBB package into the sub_string_finder sample on Windows* OS (Microsoft* Visual Studio). +This example is also applicable for other platforms with slight changes. +Place holders and should be replaced with the actual values for the TBB package being used. The example is written for `CMake 3.7.1`. + +Precondition: + * `Microsoft* Visual Studio 11` or higher. + * `CMake 3.0.0` or higher. + +#. Download the latest binary package for Windows from `this page `_ and unpack it to the directory ``C:\demo_tbb_cmake``. +#. In the directory ``C:\demo_tbb_cmake\tbb_oss\examples\GettingStarted\sub_string_finder`` create ``CMakeLists.txt`` file with the following content: + .. code:: cmake + + cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) + + project(sub_string_finder CXX) + add_executable(sub_string_finder sub_string_finder.cpp) + + # find_package will search for available TBBConfig using variables CMAKE_PREFIX_PATH and TBB_DIR. + find_package(TBB REQUIRED tbb) + + # Link TBB imported targets to the executable; + # "TBB::tbb" can be used instead of "${TBB_IMPORTED_TARGETS}". + target_link_libraries(sub_string_finder ${TBB_IMPORTED_TARGETS}) +#. Run CMake GUI and: + * Fill the following fields (you can use the buttons ``Browse Source...`` and ``Browse Build...`` accordingly) + + * Where is the source code: ``C:/demo_tbb_cmake/tbb_oss/examples/GettingStarted/sub_string_finder`` + * Where to build the binaries: ``C:/demo_tbb_cmake/tbb_oss/examples/GettingStarted/sub_string_finder/build`` + + * Add new cache entry using button ``Add Entry`` to let CMake know where to search for TBBConfig: + + * Name: ``CMAKE_PREFIX_PATH`` + * Type: ``PATH`` + * Value: ``C:/demo_tbb_cmake/tbb_oss`` + + * Push the button ``Generate`` and choose a proper generator for your Microsoft* Visual Studio version. +#. Now you can open the generated solution ``C:/demo_tbb_cmake/tbb_oss/examples/GettingStarted/sub_string_finder/build/sub_string_finder.sln`` in your Microsoft* Visual Studio and build it. + +Source code integration of TBB to the sub_string_finder sample (Linux* OS) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In this example, we will build TBB from source code with enabled Community Preview Features and link the sub_string_finder sample with the built library. +This example is also applicable for other platforms with slight changes. + +Precondition: + * `CMake 3.0.0` or higher. + * `Git` (to clone the TBB repository from GitHub) + +#. Create the directory ``~/demo_tbb_cmake``, go to the created directory and clone the TBB repository there: + ``mkdir ~/demo_tbb_cmake ; cd ~/demo_tbb_cmake ; git clone https://github.com/01org/tbb.git`` +#. In the directory ``~/demo_tbb_cmake/tbb/examples/GettingStarted/sub_string_finder`` create ``CMakeLists.txt`` file with following content: + .. code:: cmake + + cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) + + project(sub_string_finder CXX) + add_executable(sub_string_finder sub_string_finder.cpp) + + include(${TBB_ROOT}/cmake/TBBBuild.cmake) + + # Build TBB with enabled Community Preview Features (CPF). + tbb_build(TBB_ROOT ${TBB_ROOT} CONFIG_DIR TBB_DIR MAKE_ARGS tbb_cpf=1) + + find_package(TBB REQUIRED tbb_preview) + + # Link TBB imported targets to the executable; + # "TBB::tbb_preview" can be used instead of "${TBB_IMPORTED_TARGETS}". + target_link_libraries(sub_string_finder ${TBB_IMPORTED_TARGETS}) +#. Create a build directory for the sub_string_finder sample to perform build out of source, go to the created directory + ``mkdir ~/demo_tbb_cmake/tbb/examples/GettingStarted/sub_string_finder/build ; cd ~/demo_tbb_cmake/tbb/examples/GettingStarted/sub_string_finder/build`` +#. Run CMake to prepare Makefile for the sub_string_finder sample and provide TBB location (root) where to perform build: + ``cmake -DTBB_ROOT=${HOME}/demo_tbb_cmake/tbb ..`` +#. Make an executable and run it: + ``make ; ./sub_string_finder`` + +Technical documentation for CMake modules +----------------------------------------- +TBBConfig +^^^^^^^^^ + +Configuration module for TBB library. + +How to use this module in your CMake project: + #. Add location of TBB (root) to `CMAKE_PREFIX_PATH `_ + or specify location of TBBConfig.cmake in ``TBB_DIR``. + #. Use `find_package `_ to configure TBB. + #. Use provided variables and/or imported targets (described below) to work with TBB. + +TBB components can be passed to `find_package `_ +after keyword ``COMPONENTS`` or ``REQUIRED``. +Use basic names of components (``tbb``, ``tbbmalloc``, ``tbb_preview``, etc.). + +If components are not specified then default are used: ``tbb``, ``tbbmalloc`` and ``tbbmalloc_proxy``. + +If ``tbbmalloc_proxy`` is requested, ``tbbmalloc`` component will also be added and set as dependency for ``tbbmalloc_proxy``. + +TBBConfig creates `imported targets `_ as +shared libraries using the following format: ``TBB::`` (for example, ``TBB::tbb``, ``TBB::tbbmalloc``). + +Set ``TBB_FIND_RELEASE_ONLY`` to ``TRUE`` before ``find_package`` call in order to search only for release TBB version. This variable helps to avoid simultaneous linkage of release and debug TBB versions when CMake configuration is `Debug` but a third-party component depends on release TBB version. +Variables set during TBB configuration: + +========================= ================================================ + Variable Description +========================= ================================================ +``TBB_FOUND`` TBB library is found +``TBB__FOUND`` specific TBB component is found +``TBB_IMPORTED_TARGETS`` all created TBB imported targets +``TBB_VERSION`` TBB version (format: ``.``) +``TBB_INTERFACE_VERSION`` TBB interface version (can be empty, see below for details) +========================= ================================================ + +TBBInstallConfig +^^^^^^^^^^^^^^^^ + +Module for generation and installation of TBB CMake configuration files (TBBConfig.cmake and TBBConfigVersion.cmake files) on Linux, macOS and Windows. + +Provides the following functions: + + .. code:: cmake + + tbb_install_config(INSTALL_DIR SYSTEM_NAME Linux|Darwin|Windows + [TBB_VERSION .|TBB_VERSION_FILE ] + [LIB_REL_PATH INC_REL_PATH ] + [LIB_PATH INC_PATH ])`` + +**Note: the module overwrites existing TBBConfig.cmake and TBBConfigVersion.cmake files in .** + +``tbb_config_installer.cmake`` allows to run ``TBBInstallConfig.cmake`` from command line. +It accepts the same parameters as ``tbb_install_config`` function, run ``cmake -P tbb_config_installer.cmake`` to get help. + +Use cases +""""""""" +**Prepare TBB CMake configuration files for custom TBB package.** + +The use case is applicable for package maintainers who create own TBB packages and want to create TBBConfig.cmake and TBBConfigVersion.cmake for these packages. + +=========================================== =========================================================== + Parameter Description +=========================================== =========================================================== +``INSTALL_DIR `` Directory to install CMake configuration files +``SYSTEM_NAME Linux|Darwin|Windows`` OS name to generate config files for +``TBB_VERSION_FILE `` Path to ``tbb_stddef.h`` to parse version from and + write it to TBBConfigVersion.cmake +``TBB_VERSION .`` Directly specified TBB version; alternative to ``TBB_VERSION_FILE`` parameter; + ``TBB_INTERFACE_VERSION`` is set to empty value in this case +``LIB_REL_PATH `` Relative path to TBB binaries (.lib files on Windows), default: ``../../../lib`` +``BIN_REL_PATH `` Relative path to TBB DLLs, default: ``../../../bin`` (applicable for Windows only) +``INC_REL_PATH `` Relative path to TBB headers, default: ``../../../include`` +=========================================== =========================================================== + +*Example* + + Assume your package is installed to the following structure: + + * Binaries go to ``/lib`` + * Headers go to ``/include`` + * CMake configuration files go to ``/lib/cmake/`` + + The package is packed from ``/my/package/content`` directory. + + ``cmake -DINSTALL_DIR=/my/package/content/lib/cmake/TBB -DSYSTEM_NAME=Linux -DTBB_VERSION_FILE=/my/package/content/include/tbb/tbb_stddef.h -P tbb_config_installer.cmake`` (default relative paths will be used) + +**Install TBB CMake configuration files for installed TBB.** + +The use case is applicable for users who have installed TBB, but do not have (or have incorrect) CMake configuration files for this TBB. + +==================================== ============================================== + Parameter Description +==================================== ============================================== +``INSTALL_DIR `` Directory to install CMake configuration files +``SYSTEM_NAME Linux|Darwin|Windows`` OS name to generate config files for +``LIB_PATH `` Path to installed TBB binaries (.lib files on Windows) +``BIN_PATH `` Path to installed TBB DLLs (applicable for Windows only) +``INC_PATH `` Path to installed TBB headers +==================================== ============================================== + +``LIB_PATH`` and ``INC_PATH`` will be converted to relative paths based on ``INSTALL_DIR``. +By default TBB version will be parsed from ``/tbb/tbb_stddef.h``, +but it can be overridden by optional parameters ``TBB_VERSION_FILE`` or ``TBB_VERSION``. + +*Example* + + TBB is installed to ``/usr`` directory. + In order to create TBBConfig.cmake and TBBConfigVersion.cmake in ``/usr/lib/cmake/TBB`` run + + ``cmake -DINSTALL_DIR=/usr/lib/cmake/TBB -DSYSTEM_NAME=Linux -DLIB_PATH=/usr/lib -DINC_PATH=/usr/include -P tbb_config_installer.cmake``. + +TBBGet +^^^^^^ + +Module for getting TBB library from `GitHub `_. + +Provides the following functions: + ``tbb_get(TBB_ROOT [RELEASE_TAG |LATEST] [SAVE_TO ] [SYSTEM_NAME Linux|Windows|Darwin] [CONFIG_DIR | SOURCE_CODE])`` + downloads TBB from GitHub and creates TBBConfig for the downloaded binary package if there is no TBBConfig. + + ==================================== ==================================== + Parameter Description + ==================================== ==================================== + ``TBB_ROOT `` a variable to save TBB root in, ``-NOTFOUND`` will be provided in case ``tbb_get`` is unsuccessful + ``RELEASE_TAG |LATEST`` TBB release tag to be downloaded (for example, ``2017_U6``), ``LATEST`` is used by default + ``SAVE_TO `` path to location at which to unpack downloaded TBB, ``${CMAKE_CURRENT_BINARY_DIR}/tbb_downloaded`` is used by default + ``SYSTEM_NAME Linux|Windows|Darwin`` operating system name to download a binary package for, + value of `CMAKE_SYSTEM_NAME `_ is used by default + ``CONFIG_DIR `` a variable to save location of TBBConfig.cmake and TBBConfigVersion.cmake. Ignored if ``SOURCE_CODE`` specified + ``SOURCE_CODE`` flag to get TBB source code (instead of binary package) + ==================================== ==================================== + +TBBMakeConfig +^^^^^^^^^^^^^ + +Module for making TBBConfig in `official TBB binary packages published on GitHub `_. + +This module is to be used for packages that do not have TBBConfig. + +Provides the following functions: + ``tbb_make_config(TBB_ROOT CONFIG_DIR [SYSTEM_NAME Linux|Windows|Darwin])`` + creates CMake configuration files (TBBConfig.cmake and TBBConfigVersion.cmake) for TBB binary package. + + ==================================== ==================================== + Parameter Description + ==================================== ==================================== + ``TBB_ROOT `` path to TBB root + ``CONFIG_DIR `` a variable to store location of the created configuration files + ``SYSTEM_NAME Linux|Windows|Darwin`` operating system name of the binary TBB package, + value of `CMAKE_SYSTEM_NAME `_ is used by default + ==================================== ==================================== + +TBBBuild +^^^^^^^^ + +Module for building TBB library from the source code. + +Provides the following functions: + ``tbb_build(TBB_ROOT CONFIG_DIR [MAKE_ARGS ])`` + builds TBB from source code using the ``Makefile``, creates and provides the location of the CMake configuration files (TBBConfig.cmake and TBBConfigVersion.cmake) . + + ===================================== ==================================== + Parameter Description + ===================================== ==================================== + ``TBB_ROOT `` path to TBB root + ``CONFIG_DIR `` a variable to store location of the created configuration files, + ``-NOTFOUND`` will be provided in case ``tbb_build`` is unsuccessful + ``MAKE_ARGS `` custom arguments to be passed to ``make`` tool. + + The following arguments are always passed with automatically detected values to + ``make`` tool if they are not redefined in ````: + + - ``compiler=`` + - ``tbb_build_dir=`` + - ``tbb_build_prefix=`` + - ``-j`` + ===================================== ==================================== + + +------------ + +Intel and the Intel logo are trademarks of Intel Corporation or its subsidiaries in the U.S. and/or other countries. + +``*`` Other names and brands may be claimed as the property of others. diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBBuild.cmake b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBBuild.cmake new file mode 100644 index 00000000..e4831d09 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBBuild.cmake @@ -0,0 +1,197 @@ +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Usage: +# include(TBBBuild.cmake) +# tbb_build(TBB_ROOT CONFIG_DIR MAKE_ARGS [... ]) +# find_package(TBB ) +# + +include(CMakeParseArguments) + +# Save the location of Intel TBB CMake modules here, as it will not be possible to do inside functions, +# see for details: https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_LIST_DIR.html +set(_tbb_cmake_module_path ${CMAKE_CURRENT_LIST_DIR}) + +## +# Builds Intel TBB. +# +# Parameters: +# TBB_ROOT - path to Intel TBB root directory (with sources); +# MAKE_ARGS - user-defined arguments to be passed to make-tool; +# CONFIG_DIR - store location of the created TBBConfig if the build was ok, store -NOTFOUND otherwise. +# +function(tbb_build) + # NOTE: internal function are used to hide them from user. + + ## + # Provides arguments for make-command to build Intel TBB. + # + # Following arguments are provided automatically if they are not defined by user: + # compiler= + # tbb_build_dir= + # tbb_build_prefix= + # -j + # + # Parameters: + # USER_DEFINED_ARGS - list of user-defined arguments; + # RESULT - resulting list of 'make' arguments. + # + function(tbb_get_make_args) + set(oneValueArgs RESULT) + set(multiValueArgs USER_DEFINED_ARGS) + cmake_parse_arguments(tbb_GMA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(result "${tbb_GMA_USER_DEFINED_ARGS}") + + if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "compiler=") + # TODO: add other supported compilers. + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(compiler gcc) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + set(compiler icc) + if (CMAKE_SYSTEM_NAME MATCHES "Windows") + set(compiler icl) + endif() + elseif (MSVC) + set(compiler cl) + elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(compiler clang) + endif() + + set(result "compiler=${compiler}" ${result}) + endif() + + if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "stdver=" AND DEFINED CMAKE_CXX_STANDARD) + set(result "stdver=c++${CMAKE_CXX_STANDARD}" ${result}) + endif() + + if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "tbb_build_dir=") + set(result "tbb_build_dir=${CMAKE_CURRENT_BINARY_DIR}/tbb_cmake_build" ${result}) + endif() + + if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "tbb_build_prefix=") + set(result "tbb_build_prefix=tbb_cmake_build_subdir" ${result}) + endif() + + if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "(;|^) *\\-j[0-9]* *(;|$)") + include(ProcessorCount) + ProcessorCount(num_of_cores) + if (NOT num_of_cores EQUAL 0) + set(result "-j${num_of_cores}" ${result}) + endif() + endif() + + if (CMAKE_SYSTEM_NAME MATCHES "Android") + set(result target=android ${result}) + endif() + + set(${tbb_GMA_RESULT} ${result} PARENT_SCOPE) + endfunction() + + ## + # Provides release and debug directories basing on 'make' arguments. + # + # Following 'make' arguments are parsed: tbb_build_dir, tbb_build_prefix + # + # Parameters: + # MAKE_ARGS - 'make' arguments (tbb_build_dir and tbb_build_prefix are required) + # RELEASE_DIR - store normalized (CMake) path to release directory + # DEBUG_DIR - store normalized (CMake) path to debug directory + # + function(tbb_get_build_paths_from_make_args) + set(oneValueArgs RELEASE_DIR DEBUG_DIR) + set(multiValueArgs MAKE_ARGS) + cmake_parse_arguments(tbb_GBPFMA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + foreach(arg ${tbb_GBPFMA_MAKE_ARGS}) + if (arg MATCHES "tbb_build_dir=") + string(REPLACE "tbb_build_dir=" "" tbb_build_dir "${arg}") + elseif (arg MATCHES "tbb_build_prefix=") + string(REPLACE "tbb_build_prefix=" "" tbb_build_prefix "${arg}") + endif() + endforeach() + + set(tbb_release_dir "${tbb_build_dir}/${tbb_build_prefix}_release") + set(tbb_debug_dir "${tbb_build_dir}/${tbb_build_prefix}_debug") + + file(TO_CMAKE_PATH "${tbb_release_dir}" tbb_release_dir) + file(TO_CMAKE_PATH "${tbb_debug_dir}" tbb_debug_dir) + + set(${tbb_GBPFMA_RELEASE_DIR} ${tbb_release_dir} PARENT_SCOPE) + set(${tbb_GBPFMA_DEBUG_DIR} ${tbb_debug_dir} PARENT_SCOPE) + endfunction() + + # -------------------- # + # Function entry point # + # -------------------- # + set(oneValueArgs TBB_ROOT CONFIG_DIR) + set(multiValueArgs MAKE_ARGS) + cmake_parse_arguments(tbb_build "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (NOT EXISTS "${tbb_build_TBB_ROOT}/Makefile" OR NOT EXISTS "${tbb_build_TBB_ROOT}/src") + message(STATUS "Intel TBB can not be built: Makefile or src directory was not found in ${tbb_build_TBB_ROOT}") + set(${tbb_build_CONFIG_DIR} ${tbb_build_CONFIG_DIR}-NOTFOUND PARENT_SCOPE) + return() + endif() + + set(make_tool_name make) + if (CMAKE_SYSTEM_NAME MATCHES "Windows") + set(make_tool_name gmake) + elseif (CMAKE_SYSTEM_NAME MATCHES "Android") + set(make_tool_name ndk-build) + endif() + + find_program(TBB_MAKE_TOOL ${make_tool_name} DOC "Make-tool to build Intel TBB.") + mark_as_advanced(TBB_MAKE_TOOL) + + if (NOT TBB_MAKE_TOOL) + message(STATUS "Intel TBB can not be built: required make-tool (${make_tool_name}) was not found") + set(${tbb_build_CONFIG_DIR} ${tbb_build_CONFIG_DIR}-NOTFOUND PARENT_SCOPE) + return() + endif() + + tbb_get_make_args(USER_DEFINED_ARGS ${tbb_build_MAKE_ARGS} RESULT tbb_make_args) + + set(tbb_build_cmd ${TBB_MAKE_TOOL} ${tbb_make_args}) + + string(REPLACE ";" " " tbb_build_cmd_str "${tbb_build_cmd}") + message(STATUS "Building Intel TBB: ${tbb_build_cmd_str}") + execute_process(COMMAND ${tbb_build_cmd} + WORKING_DIRECTORY ${tbb_build_TBB_ROOT} + RESULT_VARIABLE tbb_build_result + ERROR_VARIABLE tbb_build_error_output + OUTPUT_QUIET) + + if (NOT tbb_build_result EQUAL 0) + message(STATUS "Building is unsuccessful (${tbb_build_result}): ${tbb_build_error_output}") + set(${tbb_build_CONFIG_DIR} ${tbb_build_CONFIG_DIR}-NOTFOUND PARENT_SCOPE) + return() + endif() + + tbb_get_build_paths_from_make_args(MAKE_ARGS ${tbb_make_args} + RELEASE_DIR tbb_release_dir + DEBUG_DIR tbb_debug_dir) + + include(${_tbb_cmake_module_path}/TBBMakeConfig.cmake) + tbb_make_config(TBB_ROOT ${tbb_build_TBB_ROOT} + SYSTEM_NAME ${CMAKE_SYSTEM_NAME} + CONFIG_DIR tbb_config_dir + CONFIG_FOR_SOURCE + TBB_RELEASE_DIR ${tbb_release_dir} + TBB_DEBUG_DIR ${tbb_debug_dir}) + + set(${tbb_build_CONFIG_DIR} ${tbb_config_dir} PARENT_SCOPE) +endfunction() diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBGet.cmake b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBGet.cmake new file mode 100644 index 00000000..230edcab --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBGet.cmake @@ -0,0 +1,294 @@ +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(CMakeParseArguments) + +# Save the location of Intel TBB CMake modules here, as it will not be possible to do inside functions, +# see for details: https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_LIST_DIR.html +set(_tbb_cmake_module_path ${CMAKE_CURRENT_LIST_DIR}) + +## +# Downloads file. +# +# Parameters: +# URL - URL to download data from; +# SAVE_AS - filename there to save downloaded data; +# INFO - text description of content to be downloaded; +# will be printed as message in format is "Downloading : ; +# FORCE - option to delete local file from SAVE_AS if it exists; +# +function(_tbb_download_file) + set(options FORCE) + set(oneValueArgs URL RELEASE SAVE_AS INFO) + cmake_parse_arguments(tbb_df "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (tbb_df_FORCE AND EXISTS "${tbb_df_SAVE_AS}") + file(REMOVE ${tbb_df_SAVE_AS}) + endif() + + if (NOT EXISTS "${tbb_df_SAVE_AS}") + set(_show_progress) + if (TBB_DOWNLOADING_PROGRESS) + set(_show_progress SHOW_PROGRESS) + endif() + + message(STATUS "Downloading ${tbb_df_INFO}: ${tbb_df_URL}") + file(DOWNLOAD ${tbb_df_URL} ${tbb_df_SAVE_AS} ${_show_progress} STATUS download_status) + + list(GET download_status 0 download_status_num) + if (NOT download_status_num EQUAL 0) + message(STATUS "Unsuccessful downloading: ${download_status}") + file(REMOVE ${tbb_df_SAVE_AS}) + return() + endif() + else() + message(STATUS "Needed file was found locally ${tbb_df_SAVE_AS}. Remove it if you still want to download a new one") + endif() +endfunction() + +## +# Checks if specified Intel TBB release is available on GitHub. +# +# tbb_check_git_release( ) +# Parameters: +# - release to be checked; +# - store result (TRUE/FALSE). +# +function(_tbb_check_git_release_tag _tbb_release_tag _tbb_release_tag_avail) + if (_tbb_release_tag STREQUAL LATEST) + set(${_tbb_release_tag_avail} TRUE PARENT_SCOPE) + return() + endif() + + set(tbb_releases_file "${CMAKE_CURRENT_BINARY_DIR}/tbb_releases.json") + + _tbb_download_file(URL "${tbb_github_api}/releases" + SAVE_AS ${tbb_releases_file} + INFO "information from GitHub about Intel TBB releases" + FORCE) + + if (NOT EXISTS "${tbb_releases_file}") + set(${_tbb_release_tag_avail} FALSE PARENT_SCOPE) + return() + endif() + + file(READ ${tbb_releases_file} tbb_releases) + + string(REPLACE "\"" "" tbb_releases ${tbb_releases}) + string(REGEX MATCHALL "tag_name: *([A-Za-z0-9_\\.]+)" tbb_releases ${tbb_releases}) + + set(_release_available FALSE) + foreach(tbb_rel ${tbb_releases}) + string(REGEX REPLACE "tag_name: *" "" tbb_rel_cut ${tbb_rel}) + list(REMOVE_ITEM tbb_releases ${tbb_rel}) + list(APPEND tbb_releases ${tbb_rel_cut}) + if (_tbb_release_tag STREQUAL tbb_rel_cut) + set(_release_available TRUE) + break() + endif() + endforeach() + + if (NOT _release_available) + string(REPLACE ";" ", " tbb_releases_str "${tbb_releases}") + message(STATUS "Requested release tag ${_tbb_release_tag} is not available. Available Intel TBB release tags: ${tbb_releases_str}") + endif() + + set(${_tbb_release_tag_avail} ${_release_available} PARENT_SCOPE) +endfunction() + +## +# Compares two Intel TBB releases and provides result +# TRUE if the first release is less than the second, FALSE otherwise. +# +# tbb_is_release_less( ) +# +function(_tbb_is_release_less rel1 rel2 result) + # Convert release to numeric representation to compare it using "if" with VERSION_LESS. + string(REGEX REPLACE "[A-Za-z]" "" rel1 "${rel1}") + string(REPLACE "_" "." rel1 "${rel1}") + string(REGEX REPLACE "[A-Za-z]" "" rel2 "${rel2}") + string(REPLACE "_" "." rel2 "${rel2}") + + if (${rel1} VERSION_LESS ${rel2}) + set(${result} TRUE PARENT_SCOPE) + return() + endif() + + set(${result} FALSE PARENT_SCOPE) +endfunction() + +## +# Finds exact URL to download Intel TBB basing on provided parameters. +# +# Usage: +# _tbb_get_url(URL RELEASE_TAG OS [SOURCE_CODE]) +# +function(_tbb_get_url) + set(oneValueArgs URL RELEASE_TAG OS) + set(options SOURCE_CODE) + cmake_parse_arguments(tbb_get_url "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(tbb_github_api "https://api.github.com/repos/01org/tbb") + + _tbb_check_git_release_tag(${tbb_get_url_RELEASE_TAG} tbb_release_available) + if (NOT tbb_release_available) + set(${tbb_download_FULL_PATH} ${tbb_download_FULL_PATH}-NOTFOUND PARENT_SCOPE) + return() + endif() + + if (tbb_get_url_RELEASE_TAG STREQUAL LATEST) + set(tbb_rel_info_api_url "${tbb_github_api}/releases/latest") + else() + set(tbb_rel_info_api_url "${tbb_github_api}/releases/tags/${tbb_get_url_RELEASE_TAG}") + endif() + + set(tbb_release_info_file "${CMAKE_CURRENT_BINARY_DIR}/tbb_${tbb_get_url_RELEASE_TAG}_info.json") + + _tbb_download_file(URL ${tbb_rel_info_api_url} + SAVE_AS ${tbb_release_info_file} + INFO "information from GitHub about packages for Intel TBB ${tbb_get_url_RELEASE_TAG}" + FORCE) + + if (NOT EXISTS "${tbb_release_info_file}") + set(${tbb_get_url_URL} ${tbb_get_url_URL}-NOTFOUND PARENT_SCOPE) + return() + endif() + + file(STRINGS ${tbb_release_info_file} tbb_release_info) + + if (tbb_get_url_SOURCE_CODE) + # Find name of the latest release to get link to source archive. + if (tbb_get_url_RELEASE_TAG STREQUAL LATEST) + string(REPLACE "\"" "" tbb_release_info ${tbb_release_info}) + string(REGEX REPLACE ".*tag_name: *([A-Za-z0-9_\\.]+).*" "\\1" tbb_get_url_RELEASE_TAG "${tbb_release_info}") + endif() + + set(${tbb_get_url_URL} "https://github.com/01org/tbb/archive/${tbb_get_url_RELEASE_TAG}.tar.gz" PARENT_SCOPE) + else() + if (tbb_get_url_OS MATCHES "Linux") + set(tbb_lib_archive_suffix lin.tgz) + elseif (tbb_get_url_OS MATCHES "Windows") + set(tbb_lib_archive_suffix win.zip) + elseif (tbb_get_url_OS MATCHES "Darwin") + set(tbb_lib_archive_suffix mac.tgz) + + # Since 2017_U4 release archive for Apple has suffix "mac.tgz" instead of "osx.tgz". + if (NOT tbb_get_url_RELEASE_TAG STREQUAL "LATEST") + _tbb_is_release_less(${tbb_get_url_RELEASE_TAG} 2017_U4 release_less) + if (release_less) + set(tbb_lib_archive_suffix osx.tgz) + endif() + endif() + elseif (tbb_get_url_OS MATCHES "Android") + set(tbb_lib_archive_suffix and.tgz) + else() + message(STATUS "Currently prebuilt Intel TBB is not available for your OS (${tbb_get_url_OS})") + set(${tbb_get_url_URL} ${tbb_get_url_URL}-NOTFOUND PARENT_SCOPE) + return() + endif() + + string(REGEX REPLACE ".*(https.*${tbb_lib_archive_suffix}).*" "\\1" tbb_bin_url "${tbb_release_info}") + + set(${tbb_get_url_URL} ${tbb_bin_url} PARENT_SCOPE) + endif() +endfunction() + +function(tbb_get) + set(oneValueArgs RELEASE_TAG SYSTEM_NAME SAVE_TO TBB_ROOT CONFIG_DIR) + set(options SOURCE_CODE) + cmake_parse_arguments(tbb_get "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(tbb_os ${CMAKE_SYSTEM_NAME}) + if (tbb_get_SYSTEM_NAME) + set(tbb_os ${tbb_get_SYSTEM_NAME}) + endif() + + set(tbb_release_tag LATEST) + if (tbb_get_RELEASE_TAG) + set(tbb_release_tag ${tbb_get_RELEASE_TAG}) + endif() + + set(tbb_save_to ${CMAKE_CURRENT_BINARY_DIR}/tbb_downloaded) + if (tbb_get_SAVE_TO) + set(tbb_save_to ${tbb_get_SAVE_TO}) + endif() + + if (tbb_get_SOURCE_CODE) + _tbb_get_url(URL tbb_url RELEASE_TAG ${tbb_release_tag} OS ${tbb_os} SOURCE_CODE) + else() + _tbb_get_url(URL tbb_url RELEASE_TAG ${tbb_release_tag} OS ${tbb_os}) + endif() + + if (NOT tbb_url) + message(STATUS "URL to download Intel TBB has not been found") + set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE) + return() + endif() + + get_filename_component(filename ${tbb_url} NAME) + set(local_file "${CMAKE_CURRENT_BINARY_DIR}/${filename}") + + _tbb_download_file(URL ${tbb_url} + SAVE_AS ${local_file} + INFO "Intel TBB library") + + if (NOT EXISTS "${local_file}") + set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE) + return() + endif() + + get_filename_component(subdir_name ${filename} NAME_WE) + file(MAKE_DIRECTORY ${tbb_save_to}/${subdir_name}) + if (NOT EXISTS "${tbb_save_to}/${subdir_name}") + message(STATUS "${tbb_save_to}/${subdir_name} can not be created") + set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE) + return() + endif() + + message(STATUS "Unpacking ${local_file} to ${tbb_save_to}/${subdir_name}") + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf ${local_file} + WORKING_DIRECTORY ${tbb_save_to}/${subdir_name} + RESULT_VARIABLE unpacking_result) + + if (NOT unpacking_result EQUAL 0) + message(STATUS "Unsuccessful unpacking: ${unpacking_result}") + set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE) + return() + endif() + + file(GLOB_RECURSE tbb_h ${tbb_save_to}/${subdir_name}/*/include/tbb/tbb.h) + list(GET tbb_h 0 tbb_h) + + if (NOT EXISTS "${tbb_h}") + message(STATUS "tbb/tbb.h has not been found in the downloaded package") + set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE) + return() + endif() + + get_filename_component(tbb_root "${tbb_h}" PATH) + get_filename_component(tbb_root "${tbb_root}" PATH) + get_filename_component(tbb_root "${tbb_root}" PATH) + + if (NOT tbb_get_SOURCE_CODE) + set(tbb_config_dir ${tbb_root}/cmake) + + if (NOT EXISTS "${tbb_config_dir}") + tbb_make_config(TBB_ROOT ${tbb_root} CONFIG_DIR tbb_config_dir) + endif() + + set(${tbb_get_CONFIG_DIR} ${tbb_config_dir} PARENT_SCOPE) + endif() + + set(${tbb_get_TBB_ROOT} ${tbb_root} PARENT_SCOPE) +endfunction() diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBInstallConfig.cmake b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBInstallConfig.cmake new file mode 100644 index 00000000..e846fe3d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBInstallConfig.cmake @@ -0,0 +1,124 @@ +# Copyright (c) 2019-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(CMakeParseArguments) + +# Save the location of Intel TBB CMake modules here, as it will not be possible to do inside functions, +# see for details: https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_LIST_DIR.html +set(_tbb_cmake_module_path ${CMAKE_CURRENT_LIST_DIR}) + +function(tbb_install_config) + set(oneValueArgs INSTALL_DIR + SYSTEM_NAME + LIB_REL_PATH INC_REL_PATH BIN_REL_PATH TBB_VERSION TBB_VERSION_FILE + LIB_PATH BIN_PATH INC_PATH) # If TBB is installed on the system + + cmake_parse_arguments(tbb_IC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + get_filename_component(config_install_dir ${tbb_IC_INSTALL_DIR} ABSOLUTE) + file(MAKE_DIRECTORY ${config_install_dir}) + + # --- TBB_LIB_REL_PATH handling --- + set(TBB_LIB_REL_PATH "../../../lib") + + if (tbb_IC_LIB_REL_PATH) + file(TO_CMAKE_PATH ${tbb_IC_LIB_REL_PATH} TBB_LIB_REL_PATH) + endif() + + if (tbb_IC_LIB_PATH) + get_filename_component(lib_abs_path ${tbb_IC_LIB_PATH} ABSOLUTE) + file(RELATIVE_PATH TBB_LIB_REL_PATH ${config_install_dir} ${lib_abs_path}) + unset(lib_abs_path) + endif() + # ------ + + # --- TBB_BIN_REL_PATH handling --- + set(TBB_BIN_REL_PATH "../../../bin") + + if (tbb_IC_BIN_REL_PATH) + file(TO_CMAKE_PATH ${tbb_IC_BIN_REL_PATH} TBB_BIN_REL_PATH) + endif() + + if (tbb_IC_BIN_PATH) + get_filename_component(bin_abs_path ${tbb_IC_BIN_PATH} ABSOLUTE) + file(RELATIVE_PATH TBB_BIN_REL_PATH ${config_install_dir} ${bin_abs_path}) + unset(bin_abs_path) + endif() + # ------ + + # --- TBB_INC_REL_PATH handling --- + set(TBB_INC_REL_PATH "../../../include") + + if (tbb_IC_INC_REL_PATH) + file(TO_CMAKE_PATH ${tbb_IC_INC_REL_PATH} TBB_INC_REL_PATH) + endif() + + if (tbb_IC_INC_PATH) + get_filename_component(inc_abs_path ${tbb_IC_INC_PATH} ABSOLUTE) + file(RELATIVE_PATH TBB_INC_REL_PATH ${config_install_dir} ${inc_abs_path}) + unset(inc_abs_path) + endif() + # ------ + + # --- TBB_VERSION handling --- + if (tbb_IC_TBB_VERSION) + set(TBB_VERSION ${tbb_IC_TBB_VERSION}) + else() + set(tbb_version_file "${config_install_dir}/${TBB_INC_REL_PATH}/tbb/tbb_stddef.h") + if (tbb_IC_TBB_VERSION_FILE) + set(tbb_version_file ${tbb_IC_TBB_VERSION_FILE}) + endif() + + file(READ ${tbb_version_file} _tbb_stddef) + string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" _tbb_ver_major "${_tbb_stddef}") + string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" _tbb_ver_minor "${_tbb_stddef}") + string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_tbb_stddef}") + set(TBB_VERSION "${_tbb_ver_major}.${_tbb_ver_minor}") + endif() + # ------ + + set(tbb_system_name ${CMAKE_SYSTEM_NAME}) + if (tbb_IC_SYSTEM_NAME) + set(tbb_system_name ${tbb_IC_SYSTEM_NAME}) + endif() + + if (tbb_system_name STREQUAL "Linux") + set(TBB_LIB_PREFIX "lib") + set(TBB_LIB_EXT "so.2") + set(TBB_IMPLIB_RELEASE "") + set(TBB_IMPLIB_DEBUG "") + elseif (tbb_system_name STREQUAL "Darwin") + set(TBB_LIB_PREFIX "lib") + set(TBB_LIB_EXT "dylib") + set(TBB_IMPLIB_RELEASE "") + set(TBB_IMPLIB_DEBUG "") + elseif (tbb_system_name STREQUAL "Windows") + set(TBB_LIB_PREFIX "") + set(TBB_LIB_EXT "dll") + # .lib files installed to TBB_LIB_REL_PATH (e.g. /lib); + # .dll files installed to TBB_BIN_REL_PATH (e.g. /bin); + # Expand TBB_LIB_REL_PATH here in IMPORTED_IMPLIB property and + # redefine it with TBB_BIN_REL_PATH value to properly fill IMPORTED_LOCATION property in TBBConfig.cmake.in template. + set(TBB_IMPLIB_RELEASE " + IMPORTED_IMPLIB_RELEASE \"\${CMAKE_CURRENT_LIST_DIR}/${TBB_LIB_REL_PATH}/\${_tbb_component}.lib\"") + set(TBB_IMPLIB_DEBUG " + IMPORTED_IMPLIB_DEBUG \"\${CMAKE_CURRENT_LIST_DIR}/${TBB_LIB_REL_PATH}/\${_tbb_component}_debug.lib\"") + set(TBB_LIB_REL_PATH ${TBB_BIN_REL_PATH}) + else() + message(FATAL_ERROR "Unsupported OS name: ${tbb_system_name}") + endif() + + configure_file(${_tbb_cmake_module_path}/templates/TBBConfig.cmake.in ${config_install_dir}/TBBConfig.cmake @ONLY) + configure_file(${_tbb_cmake_module_path}/templates/TBBConfigVersion.cmake.in ${config_install_dir}/TBBConfigVersion.cmake @ONLY) +endfunction() diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBMakeConfig.cmake b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBMakeConfig.cmake new file mode 100644 index 00000000..8c2c78be --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/TBBMakeConfig.cmake @@ -0,0 +1,164 @@ +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Usage: +# include(TBBMakeConfig.cmake) +# tbb_make_config(TBB_ROOT SYSTEM_NAME CONFIG_DIR [SAVE_TO] [CONFIG_FOR_SOURCE TBB_RELEASE_DIR TBB_DEBUG_DIR ]) +# + +include(CMakeParseArguments) + +# Save the location of Intel TBB CMake modules here, as it will not be possible to do inside functions, +# see for details: https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_LIST_DIR.html +set(_tbb_cmake_module_path ${CMAKE_CURRENT_LIST_DIR}) + +function(tbb_make_config) + set(oneValueArgs TBB_ROOT SYSTEM_NAME CONFIG_DIR SAVE_TO TBB_RELEASE_DIR TBB_DEBUG_DIR) + set(options CONFIG_FOR_SOURCE) + cmake_parse_arguments(tbb_MK "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(tbb_system_name ${CMAKE_SYSTEM_NAME}) + if (tbb_MK_SYSTEM_NAME) + set(tbb_system_name ${tbb_MK_SYSTEM_NAME}) + endif() + + set(tbb_config_dir ${tbb_MK_TBB_ROOT}/cmake) + if (tbb_MK_SAVE_TO) + set(tbb_config_dir ${tbb_MK_SAVE_TO}) + endif() + + file(MAKE_DIRECTORY ${tbb_config_dir}) + + set(TBB_DEFAULT_COMPONENTS tbb tbbmalloc tbbmalloc_proxy) + + if (tbb_MK_CONFIG_FOR_SOURCE) + set(TBB_RELEASE_DIR ${tbb_MK_TBB_RELEASE_DIR}) + set(TBB_DEBUG_DIR ${tbb_MK_TBB_DEBUG_DIR}) + endif() + + if (tbb_system_name STREQUAL "Linux") + set(TBB_SHARED_LIB_DIR "lib") + set(TBB_X32_SUBDIR "ia32") + set(TBB_X64_SUBDIR "intel64") + set(TBB_LIB_PREFIX "lib") + set(TBB_LIB_EXT "so.2") + + # Note: multiline variable + set(TBB_CHOOSE_COMPILER_SUBDIR "set(_tbb_compiler_subdir gcc4.8) + +# For non-GCC compilers try to find version of system GCC to choose right compiler subdirectory. +if (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" AND NOT CMAKE_C_COMPILER_ID STREQUAL \"GNU\") + find_program(_gcc_executable gcc) + if (NOT _gcc_executable) + message(FATAL_ERROR \"This Intel TBB package is intended to be used only in environment with available 'gcc'\") + endif() + unset(_gcc_executable) +endif()") + + elseif (tbb_system_name STREQUAL "Windows") + set(TBB_SHARED_LIB_DIR "bin") + set(TBB_X32_SUBDIR "ia32") + set(TBB_X64_SUBDIR "intel64") + set(TBB_LIB_PREFIX "") + set(TBB_LIB_EXT "dll") + + # Note: multiline variable + set(TBB_CHOOSE_COMPILER_SUBDIR "if (NOT MSVC) + message(FATAL_ERROR \"This Intel TBB package is intended to be used only in the project with MSVC\") +endif() + +if (MSVC_VERSION VERSION_LESS 1900) + message(FATAL_ERROR \"This Intel TBB package is intended to be used only in the project with MSVC version 1900 (vc14) or higher\") +endif() + +set(_tbb_compiler_subdir vc14) + +if (WINDOWS_STORE) + set(_tbb_compiler_subdir \${_tbb_compiler_subdir}_uwp) +endif()") + + if (tbb_MK_CONFIG_FOR_SOURCE) + set(TBB_IMPLIB_RELEASE " + IMPORTED_IMPLIB_RELEASE \"${tbb_MK_TBB_RELEASE_DIR}/\${_tbb_component}.lib\"") + set(TBB_IMPLIB_DEBUG " + IMPORTED_IMPLIB_DEBUG \"${tbb_MK_TBB_DEBUG_DIR}/\${_tbb_component}_debug.lib\"") + else() + set(TBB_IMPLIB_RELEASE " + IMPORTED_IMPLIB_RELEASE \"\${_tbb_root}/lib/\${_tbb_arch_subdir}/\${_tbb_compiler_subdir}/\${_tbb_component}.lib\"") + set(TBB_IMPLIB_DEBUG " + IMPORTED_IMPLIB_DEBUG \"\${_tbb_root}/lib/\${_tbb_arch_subdir}/\${_tbb_compiler_subdir}/\${_tbb_component}_debug.lib\"") + endif() + + # Note: multiline variable + # tbb/internal/_tbb_windef.h (included via tbb/tbb_stddef.h) does implicit linkage of some .lib files, use a special define to avoid it + set(TBB_COMPILE_DEFINITIONS " + INTERFACE_COMPILE_DEFINITIONS \"__TBB_NO_IMPLICIT_LINKAGE=1\"") + elseif (tbb_system_name STREQUAL "Darwin") + set(TBB_SHARED_LIB_DIR "lib") + set(TBB_X32_SUBDIR ".") + set(TBB_X64_SUBDIR ".") + set(TBB_LIB_PREFIX "lib") + set(TBB_LIB_EXT "dylib") + set(TBB_CHOOSE_COMPILER_SUBDIR "set(_tbb_compiler_subdir .)") + elseif (tbb_system_name STREQUAL "Android") + set(TBB_SHARED_LIB_DIR "lib") + set(TBB_X32_SUBDIR ".") + set(TBB_X64_SUBDIR "x86_64") + set(TBB_LIB_PREFIX "lib") + set(TBB_LIB_EXT "so") + set(TBB_CHOOSE_COMPILER_SUBDIR "set(_tbb_compiler_subdir .)") + else() + message(FATAL_ERROR "Unsupported OS name: ${tbb_system_name}") + endif() + + file(READ "${tbb_MK_TBB_ROOT}/include/tbb/tbb_stddef.h" _tbb_stddef) + string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" _tbb_ver_major "${_tbb_stddef}") + string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" _tbb_ver_minor "${_tbb_stddef}") + string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_tbb_stddef}") + set(TBB_VERSION "${_tbb_ver_major}.${_tbb_ver_minor}") + + if (tbb_MK_CONFIG_FOR_SOURCE) + set(TBB_CHOOSE_ARCH_AND_COMPILER "") + set(TBB_RELEASE_LIB_PATH "${TBB_RELEASE_DIR}") + set(TBB_DEBUG_LIB_PATH "${TBB_DEBUG_DIR}") + set(TBB_UNSET_ADDITIONAL_VARIABLES "") + else() + # Note: multiline variable + set(TBB_CHOOSE_ARCH_AND_COMPILER " +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_tbb_arch_subdir ${TBB_X64_SUBDIR}) +else() + set(_tbb_arch_subdir ${TBB_X32_SUBDIR}) +endif() + +${TBB_CHOOSE_COMPILER_SUBDIR} + +get_filename_component(_tbb_lib_path \"\${_tbb_root}/${TBB_SHARED_LIB_DIR}/\${_tbb_arch_subdir}/\${_tbb_compiler_subdir}\" ABSOLUTE) +") + + set(TBB_RELEASE_LIB_PATH "\${_tbb_lib_path}") + set(TBB_DEBUG_LIB_PATH "\${_tbb_lib_path}") + + # Note: multiline variable + set(TBB_UNSET_ADDITIONAL_VARIABLES " +unset(_tbb_arch_subdir) +unset(_tbb_compiler_subdir)") + endif() + + configure_file(${_tbb_cmake_module_path}/templates/TBBConfigInternal.cmake.in ${tbb_config_dir}/TBBConfig.cmake @ONLY) + configure_file(${_tbb_cmake_module_path}/templates/TBBConfigVersion.cmake.in ${tbb_config_dir}/TBBConfigVersion.cmake @ONLY) + + set(${tbb_MK_CONFIG_DIR} ${tbb_config_dir} PARENT_SCOPE) +endfunction() diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/tbb_config_generator.cmake b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/tbb_config_generator.cmake new file mode 100644 index 00000000..495fc45d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/tbb_config_generator.cmake @@ -0,0 +1,41 @@ +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +function(tbb_conf_gen_print_help) + message("Usage: cmake -DTBB_ROOT= -DTBB_OS=Linux|Windows|Darwin [-DSAVE_TO=] -P tbb_config_generator.cmake") +endfunction() + +if (NOT DEFINED TBB_ROOT) + tbb_conf_gen_print_help() + message(FATAL_ERROR "Required parameter TBB_ROOT is not defined") +endif() + +if (NOT EXISTS "${TBB_ROOT}") + tbb_conf_gen_print_help() + message(FATAL_ERROR "TBB_ROOT=${TBB_ROOT} does not exist") +endif() + +if (NOT DEFINED TBB_OS) + tbb_conf_gen_print_help() + message(FATAL_ERROR "Required parameter TBB_OS is not defined") +endif() + +if (DEFINED SAVE_TO) + set(tbb_conf_gen_save_to_param SAVE_TO ${SAVE_TO}) +endif() + +include(${CMAKE_CURRENT_LIST_DIR}/TBBMakeConfig.cmake) +tbb_make_config(TBB_ROOT ${TBB_ROOT} CONFIG_DIR tbb_config_dir SYSTEM_NAME ${TBB_OS} ${tbb_conf_gen_save_to_param}) + +message(STATUS "TBBConfig files were created in ${tbb_config_dir}") diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/tbb_config_installer.cmake b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/tbb_config_installer.cmake new file mode 100644 index 00000000..b1b2d444 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/tbb_config_installer.cmake @@ -0,0 +1,48 @@ +# Copyright (c) 2019-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +function(tbb_conf_gen_print_help) + message("Usage: cmake -DINSTALL_DIR= -DSYSTEM_NAME=Linux|Darwin|Windows -P tbb_config_generator.cmake + +Parameters: + For custom TBB package: + -DTBB_VERSION_FILE= + -DTBB_VERSION=.. (alternative to TBB_VERSION_FILE) + -DINC_REL_PATH= + -DLIB_REL_PATH= + -DBIN_REL_PATH= (only for Windows) + For installed TBB: + -DINC_PATH= + -DLIB_PATH= + -DBIN_PATH= (only for Windows) +") +endfunction() + +if (NOT DEFINED INSTALL_DIR) + tbb_conf_gen_print_help() + message(FATAL_ERROR "Required parameter INSTALL_DIR is not defined") +endif() + +if (NOT DEFINED SYSTEM_NAME) + tbb_conf_gen_print_help() + message(FATAL_ERROR "Required parameter SYSTEM_NAME is not defined") +endif() + +foreach (arg TBB_VERSION INC_REL_PATH LIB_REL_PATH BIN_REL_PATH TBB_VERSION_FILE INC_PATH LIB_PATH BIN_PATH) + set(optional_args ${optional_args} ${arg} ${${arg}}) +endforeach() + +include(${CMAKE_CURRENT_LIST_DIR}/TBBInstallConfig.cmake) +tbb_install_config(INSTALL_DIR ${INSTALL_DIR} SYSTEM_NAME ${SYSTEM_NAME} ${optional_args}) +message(STATUS "TBBConfig files were created in ${INSTALL_DIR}") diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfig.cmake.in b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfig.cmake.in new file mode 100644 index 00000000..744f1215 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfig.cmake.in @@ -0,0 +1,98 @@ +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# It defines the following variables: +# TBB__FOUND +# TBB_IMPORTED_TARGETS +# +# TBBConfigVersion.cmake defines TBB_VERSION +# +# Initialize to default values +if (NOT TBB_IMPORTED_TARGETS) + set(TBB_IMPORTED_TARGETS "") +endif() + +if (NOT TBB_FIND_COMPONENTS) + set(TBB_FIND_COMPONENTS "tbb;tbbmalloc;tbbmalloc_proxy") + foreach (_tbb_component ${TBB_FIND_COMPONENTS}) + set(TBB_FIND_REQUIRED_${_tbb_component} 1) + endforeach() +endif() + +set(TBB_INTERFACE_VERSION @TBB_INTERFACE_VERSION@) + +# Add components with internal dependencies: tbbmalloc_proxy -> tbbmalloc +list(FIND TBB_FIND_COMPONENTS tbbmalloc_proxy _tbbmalloc_proxy_ix) +if (NOT _tbbmalloc_proxy_ix EQUAL -1) + list(FIND TBB_FIND_COMPONENTS tbbmalloc _tbbmalloc_ix) + if (_tbbmalloc_ix EQUAL -1) + list(APPEND TBB_FIND_COMPONENTS tbbmalloc) + set(TBB_FIND_REQUIRED_tbbmalloc ${TBB_FIND_REQUIRED_tbbmalloc_proxy}) + endif() + unset(_tbbmalloc_ix) +endif() +unset(_tbbmalloc_proxy_ix) + +foreach (_tbb_component ${TBB_FIND_COMPONENTS}) + set(TBB_${_tbb_component}_FOUND 0) + + get_filename_component(_tbb_release_lib "${CMAKE_CURRENT_LIST_DIR}/@TBB_LIB_REL_PATH@/@TBB_LIB_PREFIX@${_tbb_component}.@TBB_LIB_EXT@" ABSOLUTE) + + if (NOT TBB_FIND_RELEASE_ONLY) + get_filename_component(_tbb_debug_lib "${CMAKE_CURRENT_LIST_DIR}/@TBB_LIB_REL_PATH@/@TBB_LIB_PREFIX@${_tbb_component}_debug.@TBB_LIB_EXT@" ABSOLUTE) + endif() + + if (EXISTS "${_tbb_release_lib}" OR EXISTS "${_tbb_debug_lib}") + if (NOT TARGET TBB::${_tbb_component}) + add_library(TBB::${_tbb_component} SHARED IMPORTED) + + get_filename_component(_tbb_current_realpath "${CMAKE_CURRENT_LIST_DIR}" REALPATH) + get_filename_component(_tbb_include_dir "${_tbb_current_realpath}/@TBB_INC_REL_PATH@" ABSOLUTE) + set_target_properties(TBB::${_tbb_component} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_tbb_include_dir}") + unset(_tbb_current_realpath) + unset(_tbb_include_dir) + + if (EXISTS "${_tbb_release_lib}") + set_target_properties(TBB::${_tbb_component} PROPERTIES + IMPORTED_LOCATION_RELEASE "${_tbb_release_lib}"@TBB_IMPLIB_RELEASE@) + set_property(TARGET TBB::${_tbb_component} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + endif() + + if (EXISTS "${_tbb_debug_lib}") + set_target_properties(TBB::${_tbb_component} PROPERTIES + IMPORTED_LOCATION_DEBUG "${_tbb_debug_lib}"@TBB_IMPLIB_DEBUG@) + set_property(TARGET TBB::${_tbb_component} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + endif() + + # Add internal dependencies for imported targets: TBB::tbbmalloc_proxy -> TBB::tbbmalloc + if (_tbb_component STREQUAL tbbmalloc_proxy) + set_target_properties(TBB::tbbmalloc_proxy PROPERTIES INTERFACE_LINK_LIBRARIES TBB::tbbmalloc) + endif() + endif() + list(APPEND TBB_IMPORTED_TARGETS TBB::${_tbb_component}) + set(TBB_${_tbb_component}_FOUND 1) + elseif (TBB_FIND_REQUIRED AND TBB_FIND_REQUIRED_${_tbb_component}) + message(STATUS "Missed required Intel TBB component: ${_tbb_component}") + if (TBB_FIND_RELEASE_ONLY) + message(STATUS " ${_tbb_release_lib} must exist.") + else() + message(STATUS " one or both of:\n ${_tbb_release_lib}\n ${_tbb_debug_lib}\n files must exist.") + endif() + set(TBB_FOUND FALSE) + endif() +endforeach() +list(REMOVE_DUPLICATES TBB_IMPORTED_TARGETS) +unset(_tbb_release_lib) +unset(_tbb_debug_lib) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfigInternal.cmake.in b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfigInternal.cmake.in new file mode 100644 index 00000000..ba161301 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfigInternal.cmake.in @@ -0,0 +1,98 @@ +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# It defines the following variables: +# TBB__FOUND +# TBB_IMPORTED_TARGETS +# +# TBBConfigVersion.cmake defines TBB_VERSION +# +# Initialize to default values +if (NOT TBB_IMPORTED_TARGETS) + set(TBB_IMPORTED_TARGETS "") +endif() + +if (NOT TBB_FIND_COMPONENTS) + set(TBB_FIND_COMPONENTS "@TBB_DEFAULT_COMPONENTS@") + foreach (_tbb_component ${TBB_FIND_COMPONENTS}) + set(TBB_FIND_REQUIRED_${_tbb_component} 1) + endforeach() +endif() + +# Add components with internal dependencies: tbbmalloc_proxy -> tbbmalloc +list(FIND TBB_FIND_COMPONENTS tbbmalloc_proxy _tbbmalloc_proxy_ix) +if (NOT _tbbmalloc_proxy_ix EQUAL -1) + list(FIND TBB_FIND_COMPONENTS tbbmalloc _tbbmalloc_ix) + if (_tbbmalloc_ix EQUAL -1) + list(APPEND TBB_FIND_COMPONENTS tbbmalloc) + set(TBB_FIND_REQUIRED_tbbmalloc ${TBB_FIND_REQUIRED_tbbmalloc_proxy}) + endif() +endif() + +set(TBB_INTERFACE_VERSION @TBB_INTERFACE_VERSION@) + +get_filename_component(_tbb_root "${CMAKE_CURRENT_LIST_FILE}" PATH) +get_filename_component(_tbb_root "${_tbb_root}" PATH) +@TBB_CHOOSE_ARCH_AND_COMPILER@ +foreach (_tbb_component ${TBB_FIND_COMPONENTS}) + set(TBB_${_tbb_component}_FOUND 0) + + set(_tbb_release_lib "@TBB_RELEASE_LIB_PATH@/@TBB_LIB_PREFIX@${_tbb_component}.@TBB_LIB_EXT@") + + if (NOT TBB_FIND_RELEASE_ONLY) + set(_tbb_debug_lib "@TBB_DEBUG_LIB_PATH@/@TBB_LIB_PREFIX@${_tbb_component}_debug.@TBB_LIB_EXT@") + endif() + + if (EXISTS "${_tbb_release_lib}" OR EXISTS "${_tbb_debug_lib}") + if (NOT TARGET TBB::${_tbb_component}) + add_library(TBB::${_tbb_component} SHARED IMPORTED) + set_target_properties(TBB::${_tbb_component} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_tbb_root}/include"@TBB_COMPILE_DEFINITIONS@) + + if (EXISTS "${_tbb_release_lib}") + set_target_properties(TBB::${_tbb_component} PROPERTIES + IMPORTED_LOCATION_RELEASE "${_tbb_release_lib}"@TBB_IMPLIB_RELEASE@) + set_property(TARGET TBB::${_tbb_component} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + endif() + + if (EXISTS "${_tbb_debug_lib}") + set_target_properties(TBB::${_tbb_component} PROPERTIES + IMPORTED_LOCATION_DEBUG "${_tbb_debug_lib}"@TBB_IMPLIB_DEBUG@) + set_property(TARGET TBB::${_tbb_component} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + endif() + + # Add internal dependencies for imported targets: TBB::tbbmalloc_proxy -> TBB::tbbmalloc + if (_tbb_component STREQUAL tbbmalloc_proxy) + set_target_properties(TBB::tbbmalloc_proxy PROPERTIES INTERFACE_LINK_LIBRARIES TBB::tbbmalloc) + endif() + endif() + list(APPEND TBB_IMPORTED_TARGETS TBB::${_tbb_component}) + set(TBB_${_tbb_component}_FOUND 1) + elseif (TBB_FIND_REQUIRED AND TBB_FIND_REQUIRED_${_tbb_component}) + message(STATUS "Missed required Intel TBB component: ${_tbb_component}") + if (TBB_FIND_RELEASE_ONLY) + message(STATUS " ${_tbb_release_lib} must exist.") + else() + message(STATUS " one or both of:\n ${_tbb_release_lib}\n ${_tbb_debug_lib}\n files must exist.") + endif() + set(TBB_FOUND FALSE) + endif() +endforeach() +list(REMOVE_DUPLICATES TBB_IMPORTED_TARGETS) +@TBB_UNSET_ADDITIONAL_VARIABLES@ +unset(_tbbmalloc_proxy_ix) +unset(_tbbmalloc_ix) +unset(_tbb_lib_path) +unset(_tbb_release_lib) +unset(_tbb_debug_lib) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfigVersion.cmake.in b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfigVersion.cmake.in new file mode 100644 index 00000000..c7b107b0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/cmake/templates/TBBConfigVersion.cmake.in @@ -0,0 +1,24 @@ +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(PACKAGE_VERSION @TBB_VERSION@) + +if ("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/doc/Release_Notes.txt b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/doc/Release_Notes.txt new file mode 100644 index 00000000..23b3f815 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/doc/Release_Notes.txt @@ -0,0 +1,132 @@ +------------------------------------------------------------------------ +Intel(R) Threading Building Blocks - Release Notes + Version 2020 +------------------------------------------------------------------------ + +Intel(R) Threading Building Blocks (Intel(R) TBB) is planned to be +improved through renewal and update with latest C++ standards to increase +usability. Evaluation of some Intel(R) TBB features removal will be +conducted in some future releases. Features under consideration are mapped +to updated options as described in the 'TBB Revamp: Background,Changes, +and Modernization' +(see https://software.intel.com/en-us/articles/tbb-revamp). + +System Requirements +------------------- + +Intel(R) Threading Building Blocks is available commercially +(see http://software.intel.com/en-us/intel-tbb) as a binary distribution, +and in open source, in both source and binary forms +(see https://github.com/intel/tbb). + +When built from source, Intel(R) TBB is intended to be highly portable +and so supports a wide variety of operating systems and platforms (see +http://threadingbuildingblocks.org for more details). + +Binary distributions, including commercial distributions, are validated +and officially supported for the hardware, software, operating systems +and compilers listed here. + +Hardware - Recommended + + Microsoft* Windows* Systems + Intel(R) Core(TM) processor family + Intel(R) Xeon(R) processor family + Linux* Systems + Intel(R) Core(TM) processor family + Intel(R) Xeon(R) processor family + macOS* Systems + Intel(R) Core(TM) processor family + Android* Systems + Intel(R) Atom(TM) processor family + +Hardware - Supported + + Intel(R) Pentium(R) processor family + Intel(R) Xeon Phi(TM) processor family + Intel(R) Atom(TM) processor family + Non Intel(R) processors compatible with the above processors + +Software - Minimum Requirements + + Supported operating system (see below) + Supported compiler (see below) + +Software - Recommended + + Intel(R) Parallel Studio XE 2019, 2020 + Intel(R) System Studio 2019, 2020 + +Software - Supported Operating Systems + + Systems with Microsoft* Windows* operating systems + Microsoft* Windows* 10 + Microsoft* Windows* Server 2016 + Microsoft* Windows* Server 2019 + Systems with Linux* operating systems + CentOS* 7.1 + Debian* 9, 10 + Fedora* 30 + Intel(R) Cluster Ready + Red Hat* Enterprise Linux* 7, 8 + SuSE* Linux* Enterprise Server 12,15 + Ubuntu* 16.04 LTS, 18.04 LTS + Ubuntu* 19.04 + WindRiver* Linux 9 + Yocto* 2.3 + Systems with OS X* or macOS* operating systems + macOS* 10.14, 10.15 + Systems with Android* operating systems + Android* 6.x, 7.x, 8.x, 9.x + +Software - Supported Compilers + + Intel(R) C++ Compiler 18, 19 and 19.1 version + Microsoft* Visual C++ 14.1 (Microsoft* Visual Studio* 2017, + Windows* OS only) + Microsoft* Visual C++ 14.2 (Microsoft* Visual Studio* 2019, + Windows* OS only) + Microsoft* Windows* Software Development Kit for Windows* 8.1 + Microsoft* Windows* Software Development Kit for Windows* 10 + For each supported Linux* operating system, the standard gcc + version provided with that operating system is supported + GNU Compilers (gcc) 4.8 - 9.1 + GNU C Library (glibc) version 2.17 - 2.29 + Clang* 3.8 - 8.0 + Xcode* 8.x - 11.x + Android* NDK r10e - r17b + +Software - Supported Performance Analysis Tools + + Intel(R) VTune(TM) Amplifier XE 2019, 2020 + Intel(R) Inspector XE 2019, 2020 + Intel(R) Advisor XE 2019, 2020 + +Known Issues +------------ + +Below is the list of known issues in this release of +Intel(R) Threading Building Blocks (Intel(R) TBB). +See the "Known Issues" appendix in the Intel(R) TBB Developer +Reference for notes applicable to multiple releases of Intel(R) TBB. + +Library Issues + + - If you build Intel(R) TBB from sources with GCC 6 or higher, + specify the -flifetime-dse=1 option to prevent crashes at + runtime, or use Intel(R) TBB makefiles that automatically set + this option. + +------------------------------------------------------------------------ +(C) 2020 Intel Corporation + +Intel, the Intel logo, Intel Core, Intel Atom, Celeron, Xeon, +Intel Xeon Phi and Pentium are trademarks of Intel Corporation +in the U.S. and/or other countries + +* Other names and brands may be claimed as the property of others. + +Third Party and Open Source Licenses + +Content of some examples or binaries may be covered by various open-source +licenses. See the index.html file in each respective folder for details. diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/doc/copyright_brand_disclaimer_doxygen.txt b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/doc/copyright_brand_disclaimer_doxygen.txt new file mode 100644 index 00000000..73780e34 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/doc/copyright_brand_disclaimer_doxygen.txt @@ -0,0 +1,9 @@ +
+

+Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +

+Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are +registered trademarks or trademarks of Intel Corporation or its +subsidiaries in the United States and other countries. +

+* Other names and brands may be claimed as the property of others. diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/index.html new file mode 100644 index 00000000..c8698efb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/index.html @@ -0,0 +1,25 @@ + + + +

Overview

+Include files for Intel® Threading Building Blocks (Intel® TBB). + +

Directories

+
+
tbb +
Include files for Intel TBB classes and functions. +
serial/tbb +
Include files for a sequential implementation of the parallel_for algorithm. +
+ +
+Up to parent directory +

+Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +

+Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +

+* Other names and brands may be claimed as the property of others. + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/serial/tbb/parallel_for.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/serial/tbb/parallel_for.h new file mode 100644 index 00000000..4e6111b7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/serial/tbb/parallel_for.h @@ -0,0 +1,226 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../../tbb/internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_parallel_for_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_parallel_for_H +#pragma message("TBB Warning: serial/tbb/parallel_for.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_SERIAL_parallel_for_H +#define __TBB_SERIAL_parallel_for_H + +#include "tbb_annotate.h" + +#ifndef __TBB_NORMAL_EXECUTION +#include "tbb/blocked_range.h" +#include "tbb/partitioner.h" +#endif + +#if TBB_USE_EXCEPTIONS +#include +#include // required to construct std exception classes +#else +#include +#include +#endif + +namespace tbb { +namespace serial { +namespace interface9 { + +// parallel_for serial annotated implementation + +template< typename Range, typename Body, typename Partitioner > +class start_for : tbb::internal::no_copy { + Range my_range; + const Body my_body; + typename Partitioner::task_partition_type my_partition; + void execute(); + + //! Constructor for root task. + start_for( const Range& range, const Body& body, Partitioner& partitioner ) : + my_range( range ), + my_body( body ), + my_partition( partitioner ) + { + } + + //! Splitting constructor used to generate children. + /** this becomes left child. Newly constructed object is right child. */ + start_for( start_for& parent_, typename Partitioner::split_type& split_obj ) : + my_range( parent_.my_range, split_obj ), + my_body( parent_.my_body ), + my_partition( parent_.my_partition, split_obj ) + { + } + +public: + static void run( const Range& range, const Body& body, Partitioner& partitioner ) { + if( !range.empty() ) { + ANNOTATE_SITE_BEGIN( tbb_parallel_for ); + { + start_for a( range, body, partitioner ); + a.execute(); + } + ANNOTATE_SITE_END( tbb_parallel_for ); + } + } +}; + +template< typename Range, typename Body, typename Partitioner > +void start_for< Range, Body, Partitioner >::execute() { + if( !my_range.is_divisible() || !my_partition.is_divisible() ) { + ANNOTATE_TASK_BEGIN( tbb_parallel_for_range ); + { + my_body( my_range ); + } + ANNOTATE_TASK_END( tbb_parallel_for_range ); + } else { + typename Partitioner::split_type split_obj; + start_for b( *this, split_obj ); + this->execute(); // Execute the left interval first to keep the serial order. + b.execute(); // Execute the right interval then. + } +} + +//! Parallel iteration over range with default partitioner. +/** @ingroup algorithms **/ +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for( const Range& range, const Body& body ) { + serial::interface9::start_for::run(range,body,__TBB_DEFAULT_PARTITIONER()); +} + +//! Parallel iteration over range with simple partitioner. +/** @ingroup algorithms **/ +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) { + serial::interface9::start_for::run(range,body,partitioner); +} + +//! Parallel iteration over range with auto_partitioner. +/** @ingroup algorithms **/ +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) { + serial::interface9::start_for::run(range,body,partitioner); +} + +//! Parallel iteration over range with static_partitioner. +/** @ingroup algorithms **/ +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) { + serial::interface9::start_for::run(range,body,partitioner); +} + +//! Parallel iteration over range with affinity_partitioner. +/** @ingroup algorithms **/ +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner ) { + serial::interface9::start_for::run(range,body,partitioner); +} + +//! Implementation of parallel iteration over stepped range of integers with explicit step and partitioner (ignored) +template +void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& ) { + if (step <= 0 ) { +#if TBB_USE_EXCEPTIONS + throw std::invalid_argument( "nonpositive_step" ); +#else + std::cerr << "nonpositive step in a call to parallel_for" << std::endl; + std::abort(); +#endif + } else if (last > first) { + // Above "else" avoids "potential divide by zero" warning on some platforms + ANNOTATE_SITE_BEGIN( tbb_parallel_for ); + for( Index i = first; i < last; i = i + step ) { + ANNOTATE_TASK_BEGIN( tbb_parallel_for_iteration ); + { f( i ); } + ANNOTATE_TASK_END( tbb_parallel_for_iteration ); + } + ANNOTATE_SITE_END( tbb_parallel_for ); + } +} + +//! Parallel iteration over a range of integers with explicit step and default partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, Index step, const Function& f) { + parallel_for_impl(first, last, step, f, auto_partitioner()); +} +//! Parallel iteration over a range of integers with explicit step and simple partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& p) { + parallel_for_impl(first, last, step, f, p); +} +//! Parallel iteration over a range of integers with explicit step and auto partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& p) { + parallel_for_impl(first, last, step, f, p); +} +//! Parallel iteration over a range of integers with explicit step and static partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& p) { + parallel_for_impl(first, last, step, f, p); +} +//! Parallel iteration over a range of integers with explicit step and affinity partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& p) { + parallel_for_impl(first, last, step, f, p); +} + +//! Parallel iteration over a range of integers with default step and default partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, const Function& f) { + parallel_for_impl(first, last, static_cast(1), f, auto_partitioner()); +} +//! Parallel iteration over a range of integers with default step and simple partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& p) { + parallel_for_impl(first, last, static_cast(1), f, p); +} +//! Parallel iteration over a range of integers with default step and auto partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& p) { + parallel_for_impl(first, last, static_cast(1), f, p); +} +//! Parallel iteration over a range of integers with default step and static partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, const Function& f, const static_partitioner& p) { + parallel_for_impl(first, last, static_cast(1), f, p); +} +//! Parallel iteration over a range of integers with default step and affinity_partitioner +template +__TBB_DEPRECATED_IN_VERBOSE_MODE void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& p) { + parallel_for_impl(first, last, static_cast(1), f, p); +} + +} // namespace interfaceX + +using interface9::parallel_for; + +} // namespace serial + +#ifndef __TBB_NORMAL_EXECUTION +using serial::interface9::parallel_for; +#endif + +} // namespace tbb + +#endif /* __TBB_SERIAL_parallel_for_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/serial/tbb/tbb_annotate.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/serial/tbb/tbb_annotate.h new file mode 100644 index 00000000..3e67e4c4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/serial/tbb/tbb_annotate.h @@ -0,0 +1,32 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_annotate_H +#define __TBB_annotate_H + +// Macros used by the Intel(R) Parallel Advisor. +#ifdef __TBB_NORMAL_EXECUTION + #define ANNOTATE_SITE_BEGIN( site ) + #define ANNOTATE_SITE_END( site ) + #define ANNOTATE_TASK_BEGIN( task ) + #define ANNOTATE_TASK_END( task ) + #define ANNOTATE_LOCK_ACQUIRE( lock ) + #define ANNOTATE_LOCK_RELEASE( lock ) +#else + #include +#endif + +#endif /* __TBB_annotate_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/aggregator.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/aggregator.h new file mode 100644 index 00000000..786c52c8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/aggregator.h @@ -0,0 +1,204 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__aggregator_H +#define __TBB__aggregator_H + +#define __TBB_aggregator_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#if !TBB_PREVIEW_AGGREGATOR +#error Set TBB_PREVIEW_AGGREGATOR before including aggregator.h +#endif + +#include "atomic.h" +#include "tbb_profiling.h" + +namespace tbb { +namespace interface6 { + +using namespace tbb::internal; + +class aggregator_operation { + template friend class aggregator_ext; + uintptr_t status; + aggregator_operation* my_next; +public: + enum aggregator_operation_status { agg_waiting=0, agg_finished }; + aggregator_operation() : status(agg_waiting), my_next(NULL) {} + /// Call start before handling this operation + void start() { call_itt_notify(acquired, &status); } + /// Call finish when done handling this operation + /** The operation will be released to its originating thread, and possibly deleted. */ + void finish() { itt_store_word_with_release(status, uintptr_t(agg_finished)); } + aggregator_operation* next() { return itt_hide_load_word(my_next);} + void set_next(aggregator_operation* n) { itt_hide_store_word(my_next, n); } +}; + +namespace internal { + +class basic_operation_base : public aggregator_operation { + friend class basic_handler; + virtual void apply_body() = 0; +public: + basic_operation_base() : aggregator_operation() {} + virtual ~basic_operation_base() {} +}; + +template +class basic_operation : public basic_operation_base, no_assign { + const Body& my_body; + void apply_body() __TBB_override { my_body(); } +public: + basic_operation(const Body& b) : basic_operation_base(), my_body(b) {} +}; + +class basic_handler { +public: + basic_handler() {} + void operator()(aggregator_operation* op_list) const { + while (op_list) { + // ITT note: &(op_list->status) tag is used to cover accesses to the operation data. + // The executing thread "acquires" the tag (see start()) and then performs + // the associated operation w/o triggering a race condition diagnostics. + // A thread that created the operation is waiting for its status (see execute_impl()), + // so when this thread is done with the operation, it will "release" the tag + // and update the status (see finish()) to give control back to the waiting thread. + basic_operation_base& request = static_cast(*op_list); + // IMPORTANT: need to advance op_list to op_list->next() before calling request.finish() + op_list = op_list->next(); + request.start(); + request.apply_body(); + request.finish(); + } + } +}; + +} // namespace internal + +//! Aggregator base class and expert interface +/** An aggregator for collecting operations coming from multiple sources and executing + them serially on a single thread. */ +template +class aggregator_ext : tbb::internal::no_copy { +public: + aggregator_ext(const handler_type& h) : handler_busy(0), handle_operations(h) { mailbox = NULL; } + + //! EXPERT INTERFACE: Enter a user-made operation into the aggregator's mailbox. + /** Details of user-made operations must be handled by user-provided handler */ + void process(aggregator_operation *op) { execute_impl(*op); } + +protected: + /** Place operation in mailbox, then either handle mailbox or wait for the operation + to be completed by a different thread. */ + void execute_impl(aggregator_operation& op) { + aggregator_operation* res; + + // ITT note: &(op.status) tag is used to cover accesses to this operation. This + // thread has created the operation, and now releases it so that the handler + // thread may handle the associated operation w/o triggering a race condition; + // thus this tag will be acquired just before the operation is handled in the + // handle_operations functor. + call_itt_notify(releasing, &(op.status)); + // insert the operation into the list + do { + // ITT may flag the following line as a race; it is a false positive: + // This is an atomic read; we don't provide itt_hide_load_word for atomics + op.my_next = res = mailbox; // NOT A RACE + } while (mailbox.compare_and_swap(&op, res) != res); + if (!res) { // first in the list; handle the operations + // ITT note: &mailbox tag covers access to the handler_busy flag, which this + // waiting handler thread will try to set before entering handle_operations. + call_itt_notify(acquired, &mailbox); + start_handle_operations(); + __TBB_ASSERT(op.status, NULL); + } + else { // not first; wait for op to be ready + call_itt_notify(prepare, &(op.status)); + spin_wait_while_eq(op.status, uintptr_t(aggregator_operation::agg_waiting)); + itt_load_word_with_acquire(op.status); + } + } + + +private: + //! An atomically updated list (aka mailbox) of aggregator_operations + atomic mailbox; + + //! Controls thread access to handle_operations + /** Behaves as boolean flag where 0=false, 1=true */ + uintptr_t handler_busy; + + handler_type handle_operations; + + //! Trigger the handling of operations when the handler is free + void start_handle_operations() { + aggregator_operation *pending_operations; + + // ITT note: &handler_busy tag covers access to mailbox as it is passed + // between active and waiting handlers. Below, the waiting handler waits until + // the active handler releases, and the waiting handler acquires &handler_busy as + // it becomes the active_handler. The release point is at the end of this + // function, when all operations in mailbox have been handled by the + // owner of this aggregator. + call_itt_notify(prepare, &handler_busy); + // get handler_busy: only one thread can possibly spin here at a time + spin_wait_until_eq(handler_busy, uintptr_t(0)); + call_itt_notify(acquired, &handler_busy); + // acquire fence not necessary here due to causality rule and surrounding atomics + __TBB_store_with_release(handler_busy, uintptr_t(1)); + + // ITT note: &mailbox tag covers access to the handler_busy flag itself. + // Capturing the state of the mailbox signifies that handler_busy has been + // set and a new active handler will now process that list's operations. + call_itt_notify(releasing, &mailbox); + // grab pending_operations + pending_operations = mailbox.fetch_and_store(NULL); + + // handle all the operations + handle_operations(pending_operations); + + // release the handler + itt_store_word_with_release(handler_busy, uintptr_t(0)); + } +}; + +//! Basic aggregator interface +class aggregator : private aggregator_ext { +public: + aggregator() : aggregator_ext(internal::basic_handler()) {} + //! BASIC INTERFACE: Enter a function for exclusive execution by the aggregator. + /** The calling thread stores the function object in a basic_operation and + places the operation in the aggregator's mailbox */ + template + void execute(const Body& b) { + internal::basic_operation op(b); + this->execute_impl(op); + } +}; + +} // namespace interface6 + +using interface6::aggregator; +using interface6::aggregator_ext; +using interface6::aggregator_operation; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_aggregator_H_include_area + +#endif // __TBB__aggregator_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/aligned_space.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/aligned_space.h new file mode 100644 index 00000000..1b047f97 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/aligned_space.h @@ -0,0 +1,60 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_aligned_space_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_aligned_space_H +#pragma message("TBB Warning: tbb/aligned_space.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_aligned_space_H +#define __TBB_aligned_space_H + +#define __TBB_aligned_space_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_stddef.h" +#include "tbb_machine.h" + +namespace tbb { + +//! Block of space aligned sufficiently to construct an array T with N elements. +/** The elements are not constructed or destroyed by this class. + @ingroup memory_allocation */ +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::aligned_space is deprecated, use std::aligned_storage") aligned_space { +private: + typedef __TBB_TypeWithAlignmentAtLeastAsStrict(T) element_type; + element_type array[(sizeof(T)*N+sizeof(element_type)-1)/sizeof(element_type)]; +public: + //! Pointer to beginning of array + T* begin() const {return internal::punned_cast(this);} + + //! Pointer to one past last element in array. + T* end() const {return begin()+N;} +}; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_aligned_space_H_include_area + +#endif /* __TBB_aligned_space_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/atomic.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/atomic.h new file mode 100644 index 00000000..e602306f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/atomic.h @@ -0,0 +1,586 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_atomic_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_atomic_H +#pragma message("TBB Warning: tbb/atomic.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_atomic_H +#define __TBB_atomic_H + +#define __TBB_atomic_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include + +#if _MSC_VER +#define __TBB_LONG_LONG __int64 +#else +#define __TBB_LONG_LONG long long +#endif /* _MSC_VER */ + +#include "tbb_machine.h" + +#if _MSC_VER && !__INTEL_COMPILER + // Suppress overzealous compiler warnings till the end of the file + #pragma warning (push) + #pragma warning (disable: 4244 4267 4512) +#endif + +namespace tbb { + +//! Specifies memory semantics. +enum memory_semantics { + //! Sequential consistency + full_fence, + //! Acquire + acquire, + //! Release + release, + //! No ordering + relaxed +}; + +//! @cond INTERNAL +namespace internal { + +#if __TBB_ALIGNAS_PRESENT + #define __TBB_DECL_ATOMIC_FIELD(t,f,a) alignas(a) t f; +#elif __TBB_ATTRIBUTE_ALIGNED_PRESENT + #define __TBB_DECL_ATOMIC_FIELD(t,f,a) t f __attribute__ ((aligned(a))); +#elif __TBB_DECLSPEC_ALIGN_PRESENT + #define __TBB_DECL_ATOMIC_FIELD(t,f,a) __declspec(align(a)) t f; +#else + #error Do not know syntax for forcing alignment. +#endif + +template +struct atomic_rep; // Primary template declared, but never defined. + +template<> +struct atomic_rep<1> { // Specialization + typedef int8_t word; +}; +template<> +struct atomic_rep<2> { // Specialization + typedef int16_t word; +}; +template<> +struct atomic_rep<4> { // Specialization +#if _MSC_VER && !_WIN64 + // Work-around that avoids spurious /Wp64 warnings + typedef intptr_t word; +#else + typedef int32_t word; +#endif +}; +#if __TBB_64BIT_ATOMICS +template<> +struct atomic_rep<8> { // Specialization + typedef int64_t word; +}; +#endif + +template +struct aligned_storage; + +//the specializations are needed to please MSVC syntax of __declspec(align()) which accept _literal_ constants only +#if __TBB_ATOMIC_CTORS + #define ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(S) \ + template \ + struct aligned_storage { \ + __TBB_DECL_ATOMIC_FIELD(value_type,my_value,S) \ + aligned_storage() = default ; \ + constexpr aligned_storage(value_type value):my_value(value){} \ + }; \ + +#else + #define ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(S) \ + template \ + struct aligned_storage { \ + __TBB_DECL_ATOMIC_FIELD(value_type,my_value,S) \ + }; \ + +#endif + +template +struct aligned_storage { + value_type my_value; +#if __TBB_ATOMIC_CTORS + aligned_storage() = default ; + constexpr aligned_storage(value_type value):my_value(value){} +#endif +}; + +ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(2) +ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(4) +#if __TBB_64BIT_ATOMICS +ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(8) +#endif + +template +struct atomic_traits; // Primary template declared, but not defined. + +#define __TBB_DECL_FENCED_ATOMIC_PRIMITIVES(S,M) \ + template<> struct atomic_traits { \ + typedef atomic_rep::word word; \ + inline static word compare_and_swap( volatile void* location, word new_value, word comparand ) { \ + return __TBB_machine_cmpswp##S##M(location,new_value,comparand); \ + } \ + inline static word fetch_and_add( volatile void* location, word addend ) { \ + return __TBB_machine_fetchadd##S##M(location,addend); \ + } \ + inline static word fetch_and_store( volatile void* location, word value ) { \ + return __TBB_machine_fetchstore##S##M(location,value); \ + } \ + }; + +#define __TBB_DECL_ATOMIC_PRIMITIVES(S) \ + template \ + struct atomic_traits { \ + typedef atomic_rep::word word; \ + inline static word compare_and_swap( volatile void* location, word new_value, word comparand ) { \ + return __TBB_machine_cmpswp##S(location,new_value,comparand); \ + } \ + inline static word fetch_and_add( volatile void* location, word addend ) { \ + return __TBB_machine_fetchadd##S(location,addend); \ + } \ + inline static word fetch_and_store( volatile void* location, word value ) { \ + return __TBB_machine_fetchstore##S(location,value); \ + } \ + }; + +template +struct atomic_load_store_traits; // Primary template declaration + +#define __TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(M) \ + template<> struct atomic_load_store_traits { \ + template \ + inline static T load( const volatile T& location ) { \ + return __TBB_load_##M( location ); \ + } \ + template \ + inline static void store( volatile T& location, T value ) { \ + __TBB_store_##M( location, value ); \ + } \ + } + +#if __TBB_USE_FENCED_ATOMICS +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,full_fence) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,full_fence) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,full_fence) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,acquire) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,acquire) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,acquire) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,release) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,release) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,release) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(1,relaxed) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(2,relaxed) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(4,relaxed) +#if __TBB_64BIT_ATOMICS +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,full_fence) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,acquire) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,release) +__TBB_DECL_FENCED_ATOMIC_PRIMITIVES(8,relaxed) +#endif +#else /* !__TBB_USE_FENCED_ATOMICS */ +__TBB_DECL_ATOMIC_PRIMITIVES(1) +__TBB_DECL_ATOMIC_PRIMITIVES(2) +__TBB_DECL_ATOMIC_PRIMITIVES(4) +#if __TBB_64BIT_ATOMICS +__TBB_DECL_ATOMIC_PRIMITIVES(8) +#endif +#endif /* !__TBB_USE_FENCED_ATOMICS */ + +__TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(full_fence); +__TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(acquire); +__TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(release); +__TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(relaxed); + +//! Additive inverse of 1 for type T. +/** Various compilers issue various warnings if -1 is used with various integer types. + The baroque expression below avoids all the warnings (we hope). */ +#define __TBB_MINUS_ONE(T) (T(T(0)-T(1))) + +//! Base class that provides basic functionality for atomic without fetch_and_add. +/** Works for any type T that has the same size as an integral type, has a trivial constructor/destructor, + and can be copied/compared by memcpy/memcmp. */ +template +struct atomic_impl { +protected: + aligned_storage my_storage; +private: + //TODO: rechecks on recent versions of gcc if union is still the _only_ way to do a conversion without warnings + //! Union type used to convert type T to underlying integral type. + template + union converter { + typedef typename atomic_rep::word bits_type; + converter(){} + converter(value_type a_value) : value(a_value) {} + value_type value; + bits_type bits; + }; + + template + static typename converter::bits_type to_bits(value_t value){ + return converter(value).bits; + } + template + static value_t to_value(typename converter::bits_type bits){ + converter u; + u.bits = bits; + return u.value; + } + + template + union ptr_converter; //Primary template declared, but never defined. + + template + union ptr_converter { + ptr_converter(){} + ptr_converter(value_t* a_value) : value(a_value) {} + value_t* value; + uintptr_t bits; + }; + //TODO: check if making to_bits accepting reference (thus unifying it with to_bits_ref) + //does not hurt performance + template + static typename converter::bits_type & to_bits_ref(value_t& value){ + //TODO: this #ifdef is temporary workaround, as union conversion seems to fail + //on suncc for 64 bit types for 32 bit target + #if !__SUNPRO_CC + return *(typename converter::bits_type*)ptr_converter(&value).bits; + #else + return *(typename converter::bits_type*)(&value); + #endif + } + + +public: + typedef T value_type; + +#if __TBB_ATOMIC_CTORS + atomic_impl() = default ; + constexpr atomic_impl(value_type value):my_storage(value){} +#endif + template + value_type fetch_and_store( value_type value ) { + return to_value( + internal::atomic_traits::fetch_and_store( &my_storage.my_value, to_bits(value) ) + ); + } + + value_type fetch_and_store( value_type value ) { + return fetch_and_store(value); + } + + template + value_type compare_and_swap( value_type value, value_type comparand ) { + return to_value( + internal::atomic_traits::compare_and_swap( &my_storage.my_value, to_bits(value), to_bits(comparand) ) + ); + } + + value_type compare_and_swap( value_type value, value_type comparand ) { + return compare_and_swap(value,comparand); + } + + operator value_type() const volatile { // volatile qualifier here for backwards compatibility + return to_value( + __TBB_load_with_acquire( to_bits_ref(my_storage.my_value) ) + ); + } + + template + value_type load () const { + return to_value( + internal::atomic_load_store_traits::load( to_bits_ref(my_storage.my_value) ) + ); + } + + value_type load () const { + return load(); + } + + template + void store ( value_type value ) { + internal::atomic_load_store_traits::store( to_bits_ref(my_storage.my_value), to_bits(value)); + } + + void store ( value_type value ) { + store( value ); + } + +protected: + value_type store_with_release( value_type rhs ) { + //TODO: unify with store + __TBB_store_with_release( to_bits_ref(my_storage.my_value), to_bits(rhs) ); + return rhs; + } +}; + +//! Base class that provides basic functionality for atomic with fetch_and_add. +/** I is the underlying type. + D is the difference type. + StepType should be char if I is an integral type, and T if I is a T*. */ +template +struct atomic_impl_with_arithmetic: atomic_impl { +public: + typedef I value_type; +#if __TBB_ATOMIC_CTORS + atomic_impl_with_arithmetic() = default ; + constexpr atomic_impl_with_arithmetic(value_type value): atomic_impl(value){} +#endif + template + value_type fetch_and_add( D addend ) { + return value_type(internal::atomic_traits::fetch_and_add( &this->my_storage.my_value, addend*sizeof(StepType) )); + } + + value_type fetch_and_add( D addend ) { + return fetch_and_add(addend); + } + + template + value_type fetch_and_increment() { + return fetch_and_add(1); + } + + value_type fetch_and_increment() { + return fetch_and_add(1); + } + + template + value_type fetch_and_decrement() { + return fetch_and_add(__TBB_MINUS_ONE(D)); + } + + value_type fetch_and_decrement() { + return fetch_and_add(__TBB_MINUS_ONE(D)); + } + +public: + value_type operator+=( D value ) { + return fetch_and_add(value)+value; + } + + value_type operator-=( D value ) { + // Additive inverse of value computed using binary minus, + // instead of unary minus, for sake of avoiding compiler warnings. + return operator+=(D(0)-value); + } + + value_type operator++() { + return fetch_and_add(1)+1; + } + + value_type operator--() { + return fetch_and_add(__TBB_MINUS_ONE(D))-1; + } + + value_type operator++(int) { + return fetch_and_add(1); + } + + value_type operator--(int) { + return fetch_and_add(__TBB_MINUS_ONE(D)); + } +}; + +} /* Internal */ +//! @endcond + +//! Primary template for atomic. +/** See the Reference for details. + @ingroup synchronization */ +template +struct __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::atomic is deprecated, use std::atomic") +atomic: internal::atomic_impl { +#if __TBB_ATOMIC_CTORS + atomic() = default; + constexpr atomic(T arg): internal::atomic_impl(arg) {} + constexpr atomic(const atomic& rhs): internal::atomic_impl(rhs) {} +#endif + T operator=( T rhs ) { + // "this" required here in strict ISO C++ because store_with_release is a dependent name + return this->store_with_release(rhs); + } + atomic& operator=( const atomic& rhs ) {this->store_with_release(rhs); return *this;} +}; + +#if __TBB_ATOMIC_CTORS + #define __TBB_DECL_ATOMIC(T) \ + template<> struct __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::atomic is deprecated, use std::atomic") \ + atomic: internal::atomic_impl_with_arithmetic { \ + atomic() = default; \ + constexpr atomic(T arg): internal::atomic_impl_with_arithmetic(arg) {} \ + constexpr atomic(const atomic& rhs): \ + internal::atomic_impl_with_arithmetic(rhs) {} \ + \ + T operator=( T rhs ) {return store_with_release(rhs);} \ + atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ + }; +#else + #define __TBB_DECL_ATOMIC(T) \ + template<> struct __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::atomic is deprecated, use std::atomic") \ + atomic: internal::atomic_impl_with_arithmetic { \ + T operator=( T rhs ) {return store_with_release(rhs);} \ + atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ + }; +#endif + +#if __TBB_64BIT_ATOMICS +//TODO: consider adding non-default (and atomic) copy constructor for 32bit platform +__TBB_DECL_ATOMIC(__TBB_LONG_LONG) +__TBB_DECL_ATOMIC(unsigned __TBB_LONG_LONG) +#else +// test_atomic will verify that sizeof(long long)==8 +#endif +__TBB_DECL_ATOMIC(long) +__TBB_DECL_ATOMIC(unsigned long) + +#if _MSC_VER && !_WIN64 +#if __TBB_ATOMIC_CTORS +/* Special version of __TBB_DECL_ATOMIC that avoids gratuitous warnings from cl /Wp64 option. + It is identical to __TBB_DECL_ATOMIC(unsigned) except that it replaces operator=(T) + with an operator=(U) that explicitly converts the U to a T. Types T and U should be + type synonyms on the platform. Type U should be the wider variant of T from the + perspective of /Wp64. */ +#define __TBB_DECL_ATOMIC_ALT(T,U) \ + template<> struct __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::atomic is deprecated, use std::atomic") \ + atomic: internal::atomic_impl_with_arithmetic { \ + atomic() = default ; \ + constexpr atomic(T arg): internal::atomic_impl_with_arithmetic(arg) {} \ + constexpr atomic(const atomic& rhs): \ + internal::atomic_impl_with_arithmetic(rhs) {} \ + \ + T operator=( U rhs ) {return store_with_release(T(rhs));} \ + atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ + }; +#else +#define __TBB_DECL_ATOMIC_ALT(T,U) \ + template<> struct __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::atomic is deprecated, use std::atomic") \ + atomic: internal::atomic_impl_with_arithmetic { \ + T operator=( U rhs ) {return store_with_release(T(rhs));} \ + atomic& operator=( const atomic& rhs ) {store_with_release(rhs); return *this;} \ + }; +#endif +__TBB_DECL_ATOMIC_ALT(unsigned,size_t) +__TBB_DECL_ATOMIC_ALT(int,ptrdiff_t) +#else +__TBB_DECL_ATOMIC(unsigned) +__TBB_DECL_ATOMIC(int) +#endif /* _MSC_VER && !_WIN64 */ + +__TBB_DECL_ATOMIC(unsigned short) +__TBB_DECL_ATOMIC(short) +__TBB_DECL_ATOMIC(char) +__TBB_DECL_ATOMIC(signed char) +__TBB_DECL_ATOMIC(unsigned char) + +#if !_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED) +__TBB_DECL_ATOMIC(wchar_t) +#endif /* _MSC_VER||!defined(_NATIVE_WCHAR_T_DEFINED) */ + +//! Specialization for atomic with arithmetic and operator->. +template struct __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::atomic is deprecated, use std::atomic") +atomic: internal::atomic_impl_with_arithmetic { +#if __TBB_ATOMIC_CTORS + atomic() = default ; + constexpr atomic(T* arg): internal::atomic_impl_with_arithmetic(arg) {} + constexpr atomic(const atomic& rhs): internal::atomic_impl_with_arithmetic(rhs) {} +#endif + T* operator=( T* rhs ) { + // "this" required here in strict ISO C++ because store_with_release is a dependent name + return this->store_with_release(rhs); + } + atomic& operator=( const atomic& rhs ) { + this->store_with_release(rhs); return *this; + } + T* operator->() const { + return (*this); + } +}; + +//! Specialization for atomic, for sake of not allowing arithmetic or operator->. +template<> struct __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::atomic is deprecated, use std::atomic") +atomic: internal::atomic_impl { +#if __TBB_ATOMIC_CTORS + atomic() = default ; + constexpr atomic(void* arg): internal::atomic_impl(arg) {} + constexpr atomic(const atomic& rhs): internal::atomic_impl(rhs) {} +#endif + void* operator=( void* rhs ) { + // "this" required here in strict ISO C++ because store_with_release is a dependent name + return this->store_with_release(rhs); + } + atomic& operator=( const atomic& rhs ) { + this->store_with_release(rhs); return *this; + } +}; + +// Helpers to workaround ugly syntax of calling template member function of a +// template class with template argument dependent on template parameters. + +template +T load ( const atomic& a ) { return a.template load(); } + +template +void store ( atomic& a, T value ) { a.template store(value); } + +namespace interface6{ +//! Make an atomic for use in an initialization (list), as an alternative to zero-initialization or normal assignment. +template +atomic make_atomic(T t) { + atomic a; + store(a,t); + return a; +} +} +using interface6::make_atomic; + +namespace internal { +template +void swap(atomic & lhs, atomic & rhs){ + T tmp = load(lhs); + store(lhs,load(rhs)); + store(rhs,tmp); +} + +// only to aid in the gradual conversion of ordinary variables to proper atomics +template +inline atomic& as_atomic( T& t ) { + return (atomic&)t; +} +} // namespace tbb::internal + +} // namespace tbb + +#if _MSC_VER && !__INTEL_COMPILER + #pragma warning (pop) +#endif // warnings are restored + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_atomic_H_include_area + +#endif /* __TBB_atomic_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range.h new file mode 100644 index 00000000..b77e7e0a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range.h @@ -0,0 +1,168 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_blocked_range_H +#define __TBB_blocked_range_H + +#include "tbb_stddef.h" + +namespace tbb { + +namespace internal { + +// blocked_rangeNd_impl forward declaration in tbb::internal namespace to +// name it as a friend for a tbb::blocked_range. +template +class blocked_rangeNd_impl; + +} // namespace internal + +/** \page range_req Requirements on range concept + Class \c R implementing the concept of range must define: + - \code R::R( const R& ); \endcode Copy constructor + - \code R::~R(); \endcode Destructor + - \code bool R::is_divisible() const; \endcode True if range can be partitioned into two subranges + - \code bool R::empty() const; \endcode True if range is empty + - \code R::R( R& r, split ); \endcode Split range \c r into two subranges. +**/ + +//! A range over which to iterate. +/** @ingroup algorithms */ +template +class blocked_range { +public: + //! Type of a value + /** Called a const_iterator for sake of algorithms that need to treat a blocked_range + as an STL container. */ + typedef Value const_iterator; + + //! Type for size of a range + typedef std::size_t size_type; + +#if __TBB_DEPRECATED_BLOCKED_RANGE_DEFAULT_CTOR + //! Construct range with default-constructed values for begin, end, and grainsize. + /** Requires that Value have a default constructor. */ + blocked_range() : my_end(), my_begin(), my_grainsize() {} +#endif + + //! Construct range over half-open interval [begin,end), with the given grainsize. + blocked_range( Value begin_, Value end_, size_type grainsize_=1 ) : + my_end(end_), my_begin(begin_), my_grainsize(grainsize_) + { + __TBB_ASSERT( my_grainsize>0, "grainsize must be positive" ); + } + + //! Beginning of range. + const_iterator begin() const {return my_begin;} + + //! One past last value in range. + const_iterator end() const {return my_end;} + + //! Size of the range + /** Unspecified if end() + friend class blocked_range2d; + + template + friend class blocked_range3d; + + template + friend class internal::blocked_rangeNd_impl; +}; + +} // namespace tbb + +#endif /* __TBB_blocked_range_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range2d.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range2d.h new file mode 100644 index 00000000..2498e046 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range2d.h @@ -0,0 +1,104 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_blocked_range2d_H +#define __TBB_blocked_range2d_H + +#include "tbb_stddef.h" +#include "blocked_range.h" + +namespace tbb { + +//! A 2-dimensional range that models the Range concept. +/** @ingroup algorithms */ +template +class blocked_range2d { +public: + //! Type for size of an iteration range + typedef blocked_range row_range_type; + typedef blocked_range col_range_type; + +private: + row_range_type my_rows; + col_range_type my_cols; + +public: + + blocked_range2d( RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize, + ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) : + my_rows(row_begin,row_end,row_grainsize), + my_cols(col_begin,col_end,col_grainsize) + {} + + blocked_range2d( RowValue row_begin, RowValue row_end, + ColValue col_begin, ColValue col_end ) : + my_rows(row_begin,row_end), + my_cols(col_begin,col_end) + {} + + //! True if range is empty + bool empty() const { + // Range is empty if at least one dimension is empty. + return my_rows.empty() || my_cols.empty(); + } + + //! True if range is divisible into two pieces. + bool is_divisible() const { + return my_rows.is_divisible() || my_cols.is_divisible(); + } + + blocked_range2d( blocked_range2d& r, split ) : + my_rows(r.my_rows), + my_cols(r.my_cols) + { + split split_obj; + do_split(r, split_obj); + } + +#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES + //! Static field to support proportional split + static const bool is_splittable_in_proportion = true; + + blocked_range2d( blocked_range2d& r, proportional_split& proportion ) : + my_rows(r.my_rows), + my_cols(r.my_cols) + { + do_split(r, proportion); + } +#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ + + //! The rows of the iteration space + const row_range_type& rows() const {return my_rows;} + + //! The columns of the iteration space + const col_range_type& cols() const {return my_cols;} + +private: + + template + void do_split( blocked_range2d& r, Split& split_obj ) + { + if( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) { + my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); + } else { + my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj); + } + } +}; + +} // namespace tbb + +#endif /* __TBB_blocked_range2d_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range3d.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range3d.h new file mode 100644 index 00000000..15f93130 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_range3d.h @@ -0,0 +1,123 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_blocked_range3d_H +#define __TBB_blocked_range3d_H + +#include "tbb_stddef.h" +#include "blocked_range.h" + +namespace tbb { + +//! A 3-dimensional range that models the Range concept. +/** @ingroup algorithms */ +template +class blocked_range3d { +public: + //! Type for size of an iteration range + typedef blocked_range page_range_type; + typedef blocked_range row_range_type; + typedef blocked_range col_range_type; + +private: + page_range_type my_pages; + row_range_type my_rows; + col_range_type my_cols; + +public: + + blocked_range3d( PageValue page_begin, PageValue page_end, + RowValue row_begin, RowValue row_end, + ColValue col_begin, ColValue col_end ) : + my_pages(page_begin,page_end), + my_rows(row_begin,row_end), + my_cols(col_begin,col_end) + {} + + blocked_range3d( PageValue page_begin, PageValue page_end, typename page_range_type::size_type page_grainsize, + RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize, + ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) : + my_pages(page_begin,page_end,page_grainsize), + my_rows(row_begin,row_end,row_grainsize), + my_cols(col_begin,col_end,col_grainsize) + {} + + //! True if range is empty + bool empty() const { + // Range is empty if at least one dimension is empty. + return my_pages.empty() || my_rows.empty() || my_cols.empty(); + } + + //! True if range is divisible into two pieces. + bool is_divisible() const { + return my_pages.is_divisible() || my_rows.is_divisible() || my_cols.is_divisible(); + } + + blocked_range3d( blocked_range3d& r, split ) : + my_pages(r.my_pages), + my_rows(r.my_rows), + my_cols(r.my_cols) + { + split split_obj; + do_split(r, split_obj); + } + +#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES + //! Static field to support proportional split + static const bool is_splittable_in_proportion = true; + + blocked_range3d( blocked_range3d& r, proportional_split& proportion ) : + my_pages(r.my_pages), + my_rows(r.my_rows), + my_cols(r.my_cols) + { + do_split(r, proportion); + } +#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ + + //! The pages of the iteration space + const page_range_type& pages() const {return my_pages;} + + //! The rows of the iteration space + const row_range_type& rows() const {return my_rows;} + + //! The columns of the iteration space + const col_range_type& cols() const {return my_cols;} + +private: + + template + void do_split( blocked_range3d& r, Split& split_obj) + { + if ( my_pages.size()*double(my_rows.grainsize()) < my_rows.size()*double(my_pages.grainsize()) ) { + if ( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) { + my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); + } else { + my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj); + } + } else { + if ( my_pages.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_pages.grainsize()) ) { + my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj); + } else { + my_pages.my_begin = page_range_type::do_split(r.my_pages, split_obj); + } + } + } +}; + +} // namespace tbb + +#endif /* __TBB_blocked_range3d_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_rangeNd.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_rangeNd.h new file mode 100644 index 00000000..922c77c6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/blocked_rangeNd.h @@ -0,0 +1,150 @@ +/* + Copyright (c) 2017-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_blocked_rangeNd_H +#define __TBB_blocked_rangeNd_H + +#if ! TBB_PREVIEW_BLOCKED_RANGE_ND + #error Set TBB_PREVIEW_BLOCKED_RANGE_ND to include blocked_rangeNd.h +#endif + +#include "tbb_config.h" + +// tbb::blocked_rangeNd requires C++11 support +#if __TBB_CPP11_PRESENT && __TBB_CPP11_ARRAY_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT + +#include "internal/_template_helpers.h" // index_sequence, make_index_sequence + +#include +#include // std::any_of +#include // std::is_same, std::enable_if + +#include "tbb/blocked_range.h" + +namespace tbb { +namespace internal { + +/* + The blocked_rangeNd_impl uses make_index_sequence to automatically generate a ctor with + exactly N arguments of the type tbb::blocked_range. Such ctor provides an opportunity + to use braced-init-list parameters to initialize each dimension. + Use of parameters, whose representation is a braced-init-list, but they're not + std::initializer_list or a reference to one, produces a non-deduced context + within template argument deduction. + + NOTE: blocked_rangeNd must be exactly a templated alias to the blocked_rangeNd_impl + (and not e.g. a derived class), otherwise it would need to declare its own ctor + facing the same problem that the impl class solves. +*/ + +template> +class blocked_rangeNd_impl; + +template +class blocked_rangeNd_impl> { +public: + //! Type of a value. + using value_type = Value; + +private: + + //! Helper type to construct range with N tbb::blocked_range objects. + template + using dim_type_helper = tbb::blocked_range; + +public: + blocked_rangeNd_impl() = delete; + + //! Constructs N-dimensional range over N half-open intervals each represented as tbb::blocked_range. + blocked_rangeNd_impl(const dim_type_helper&... args) : my_dims{ {args...} } {} + + //! Dimensionality of a range. + static constexpr unsigned int ndims() { return N; } + + //! Range in certain dimension. + const tbb::blocked_range& dim(unsigned int dimension) const { + __TBB_ASSERT(dimension < N, "out of bound"); + return my_dims[dimension]; + } + + //------------------------------------------------------------------------ + // Methods that implement Range concept + //------------------------------------------------------------------------ + + //! True if at least one dimension is empty. + bool empty() const { + return std::any_of(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range& d) { + return d.empty(); + }); + } + + //! True if at least one dimension is divisible. + bool is_divisible() const { + return std::any_of(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range& d) { + return d.is_divisible(); + }); + } + +#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES + //! Static field to support proportional split. + static const bool is_splittable_in_proportion = true; + + blocked_rangeNd_impl(blocked_rangeNd_impl& r, proportional_split proportion) : my_dims(r.my_dims) { + do_split(r, proportion); + } +#endif + + blocked_rangeNd_impl(blocked_rangeNd_impl& r, split proportion) : my_dims(r.my_dims) { + do_split(r, proportion); + } + +private: + __TBB_STATIC_ASSERT(N != 0, "zero dimensional blocked_rangeNd can't be constructed"); + + //! Ranges in each dimension. + std::array, N> my_dims; + + template + void do_split(blocked_rangeNd_impl& r, split_type proportion) { + __TBB_STATIC_ASSERT((is_same_type::value + || is_same_type::value), + "type of split object is incorrect"); + __TBB_ASSERT(r.is_divisible(), "can't split not divisible range"); + + auto my_it = std::max_element(my_dims.begin(), my_dims.end(), [](const tbb::blocked_range& first, const tbb::blocked_range& second) { + return (first.size() * second.grainsize() < second.size() * first.grainsize()); + }); + + auto r_it = r.my_dims.begin() + (my_it - my_dims.begin()); + + my_it->my_begin = tbb::blocked_range::do_split(*r_it, proportion); + + // (!(my_it->my_begin < r_it->my_end) && !(r_it->my_end < my_it->my_begin)) equals to + // (my_it->my_begin == r_it->my_end), but we can't use operator== due to Value concept + __TBB_ASSERT(!(my_it->my_begin < r_it->my_end) && !(r_it->my_end < my_it->my_begin), + "blocked_range has been split incorrectly"); + } +}; + +} // namespace internal + +template +using blocked_rangeNd = internal::blocked_rangeNd_impl; + +} // namespace tbb + +#endif /* __TBB_CPP11_PRESENT && __TBB_CPP11_ARRAY_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT */ +#endif /* __TBB_blocked_rangeNd_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/cache_aligned_allocator.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/cache_aligned_allocator.h new file mode 100644 index 00000000..5b4897c4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/cache_aligned_allocator.h @@ -0,0 +1,209 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_cache_aligned_allocator_H +#define __TBB_cache_aligned_allocator_H + +#include +#include "tbb_stddef.h" +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#include // std::forward +#endif + +#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT +#include +#endif + +namespace tbb { + +//! @cond INTERNAL +namespace internal { + //! Cache/sector line size. + /** @ingroup memory_allocation */ + size_t __TBB_EXPORTED_FUNC NFS_GetLineSize(); + + //! Allocate memory on cache/sector line boundary. + /** @ingroup memory_allocation */ + void* __TBB_EXPORTED_FUNC NFS_Allocate( size_t n_element, size_t element_size, void* hint ); + + //! Free memory allocated by NFS_Allocate. + /** Freeing a NULL pointer is allowed, but has no effect. + @ingroup memory_allocation */ + void __TBB_EXPORTED_FUNC NFS_Free( void* ); +} +//! @endcond + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for erroneous "unreferenced parameter" warning in method destroy. + #pragma warning (push) + #pragma warning (disable: 4100) +#endif + +//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 +/** The members are ordered the same way they are in section 20.4.1 + of the ISO C++ standard. + @ingroup memory_allocation */ +template +class cache_aligned_allocator { +public: + typedef typename internal::allocator_type::value_type value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template struct rebind { + typedef cache_aligned_allocator other; + }; + cache_aligned_allocator() throw() {} + cache_aligned_allocator( const cache_aligned_allocator& ) throw() {} + template cache_aligned_allocator(const cache_aligned_allocator&) throw() {} + + pointer address(reference x) const {return &x;} + const_pointer address(const_reference x) const {return &x;} + + //! Allocate space for n objects, starting on a cache/sector line. + pointer allocate( size_type n, const void* hint=0 ) { + // The "hint" argument is always ignored in NFS_Allocate thus const_cast shouldn't hurt + return pointer(internal::NFS_Allocate( n, sizeof(value_type), const_cast(hint) )); + } + + //! Free block of memory that starts on a cache line + void deallocate( pointer p, size_type ) { + internal::NFS_Free(p); + } + + //! Largest value for which method allocate might succeed. + size_type max_size() const throw() { + return (~size_t(0)-internal::NFS_MaxLineSize)/sizeof(value_type); + } + + //! Copy-construct value at location pointed to by p. +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + template + void construct(U *p, Args&&... args) + { ::new((void *)p) U(std::forward(args)...); } +#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#if __TBB_CPP11_RVALUE_REF_PRESENT + void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));} +#endif + void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} +#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + + //! Destroy value at location pointed to by p. + void destroy( pointer p ) {p->~value_type();} +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warning 4100 is back + +//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 +/** @ingroup memory_allocation */ +template<> +class cache_aligned_allocator { +public: + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + template struct rebind { + typedef cache_aligned_allocator other; + }; +}; + +template +inline bool operator==( const cache_aligned_allocator&, const cache_aligned_allocator& ) {return true;} + +template +inline bool operator!=( const cache_aligned_allocator&, const cache_aligned_allocator& ) {return false;} + +#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT + +//! C++17 memory resource wrapper to ensure cache line size alignment +class cache_aligned_resource : public std::pmr::memory_resource { +public: + cache_aligned_resource() : cache_aligned_resource(std::pmr::get_default_resource()) {} + explicit cache_aligned_resource(std::pmr::memory_resource* upstream) : m_upstream(upstream) {} + + std::pmr::memory_resource* upstream_resource() const { + return m_upstream; + } + +private: + //! We don't know what memory resource set. Use padding to guarantee alignment + void* do_allocate(size_t bytes, size_t alignment) override { + size_t cache_line_alignment = correct_alignment(alignment); + uintptr_t base = (uintptr_t)m_upstream->allocate(correct_size(bytes) + cache_line_alignment); + __TBB_ASSERT(base != 0, "Upstream resource returned NULL."); +#if _MSC_VER && !defined(__INTEL_COMPILER) + // unary minus operator applied to unsigned type, result still unsigned + #pragma warning(push) + #pragma warning(disable: 4146 4706) +#endif + // Round up to the next cache line (align the base address) + uintptr_t result = (base + cache_line_alignment) & -cache_line_alignment; +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + // Record where block actually starts. + ((uintptr_t*)result)[-1] = base; + return (void*)result; + } + + void do_deallocate(void* ptr, size_t bytes, size_t alignment) override { + if (ptr) { + // Recover where block actually starts + uintptr_t base = ((uintptr_t*)ptr)[-1]; + m_upstream->deallocate((void*)base, correct_size(bytes) + correct_alignment(alignment)); + } + } + + bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { + if (this == &other) { return true; } +#if __TBB_USE_OPTIONAL_RTTI + const cache_aligned_resource* other_res = dynamic_cast(&other); + return other_res && (this->upstream_resource() == other_res->upstream_resource()); +#else + return false; +#endif + } + + size_t correct_alignment(size_t alignment) { + __TBB_ASSERT(tbb::internal::is_power_of_two(alignment), "Alignment is not a power of 2"); +#if __TBB_CPP17_HW_INTERFERENCE_SIZE_PRESENT + size_t cache_line_size = std::hardware_destructive_interference_size; +#else + size_t cache_line_size = internal::NFS_GetLineSize(); +#endif + return alignment < cache_line_size ? cache_line_size : alignment; + } + + size_t correct_size(size_t bytes) { + // To handle the case, when small size requested. There could be not + // enough space to store the original pointer. + return bytes < sizeof(uintptr_t) ? sizeof(uintptr_t) : bytes; + } + + std::pmr::memory_resource* m_upstream; +}; + +#endif /* __TBB_CPP17_MEMORY_RESOURCE_PRESENT */ + +} // namespace tbb + +#endif /* __TBB_cache_aligned_allocator_H */ + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/combinable.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/combinable.h new file mode 100644 index 00000000..aa8d24b1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/combinable.h @@ -0,0 +1,88 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_combinable_H +#define __TBB_combinable_H + +#define __TBB_combinable_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "enumerable_thread_specific.h" +#include "cache_aligned_allocator.h" + +namespace tbb { +/** \name combinable + **/ +//@{ +//! Thread-local storage with optional reduction +/** @ingroup containers */ + template + class combinable { + + private: + typedef typename tbb::cache_aligned_allocator my_alloc; + typedef typename tbb::enumerable_thread_specific my_ets_type; + my_ets_type my_ets; + + public: + + combinable() { } + + template + explicit combinable( finit _finit) : my_ets(_finit) { } + + //! destructor + ~combinable() { } + + combinable( const combinable& other) : my_ets(other.my_ets) { } + +#if __TBB_ETS_USE_CPP11 + combinable( combinable&& other) : my_ets( std::move(other.my_ets)) { } +#endif + + combinable & operator=( const combinable & other) { + my_ets = other.my_ets; + return *this; + } + +#if __TBB_ETS_USE_CPP11 + combinable & operator=( combinable && other) { + my_ets=std::move(other.my_ets); + return *this; + } +#endif + + void clear() { my_ets.clear(); } + + T& local() { return my_ets.local(); } + + T& local(bool & exists) { return my_ets.local(exists); } + + // combine_func_t has signature T(T,T) or T(const T&, const T&) + template + T combine(combine_func_t f_combine) { return my_ets.combine(f_combine); } + + // combine_func_t has signature void(T) or void(const T&) + template + void combine_each(combine_func_t f_combine) { my_ets.combine_each(f_combine); } + + }; +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_combinable_H_include_area + +#endif /* __TBB_combinable_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/condition_variable b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/condition_variable new file mode 100644 index 00000000..a6967817 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/condition_variable @@ -0,0 +1,489 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_condition_variable_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_condition_variable_H +#pragma message("TBB Warning: tbb/compat/condition_variable is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_condition_variable_H +#define __TBB_condition_variable_H + +#define __TBB_condition_variable_H_include_area +#include "../internal/_warning_suppress_enable_notice.h" + +#if _WIN32||_WIN64 +#include "../machine/windows_api.h" + +namespace tbb { +namespace interface5 { +namespace internal { +struct condition_variable_using_event +{ + //! Event for blocking waiting threads. + HANDLE event; + //! Protects invariants involving n_waiters, release_count, and epoch. + CRITICAL_SECTION mutex; + //! Number of threads waiting on this condition variable + int n_waiters; + //! Number of threads remaining that should no longer wait on this condition variable. + int release_count; + //! To keep threads from waking up prematurely with earlier signals. + unsigned epoch; +}; +}}} // namespace tbb::interface5::internal + +#ifndef CONDITION_VARIABLE_INIT +typedef void* CONDITION_VARIABLE; +typedef CONDITION_VARIABLE* PCONDITION_VARIABLE; +#endif + +#else /* if not _WIN32||_WIN64 */ +#include // some systems need it for ETIMEDOUT +#include +#if __linux__ +#include +#else /* generic Unix */ +#include +#endif +#endif /* _WIN32||_WIN64 */ + +#include "../tbb_stddef.h" +#include "../mutex.h" +#include "../tbb_thread.h" +#include "../tbb_exception.h" +#include "../tbb_profiling.h" + +namespace tbb { + +namespace interface5 { + +// C++0x standard working draft 30.4.3 +// Lock tag types +struct __TBB_DEPRECATED_IN_VERBOSE_MODE defer_lock_t { }; //! do not acquire ownership of the mutex +struct __TBB_DEPRECATED_IN_VERBOSE_MODE try_to_lock_t { }; //! try to acquire ownership of the mutex without blocking +struct __TBB_DEPRECATED_IN_VERBOSE_MODE adopt_lock_t { }; //! assume the calling thread has already +__TBB_DEPRECATED_IN_VERBOSE_MODE const defer_lock_t defer_lock = {}; +__TBB_DEPRECATED_IN_VERBOSE_MODE const try_to_lock_t try_to_lock = {}; +__TBB_DEPRECATED_IN_VERBOSE_MODE const adopt_lock_t adopt_lock = {}; + +// C++0x standard working draft 30.4.3.1 +//! lock_guard +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE lock_guard : tbb::internal::no_copy { +public: + //! mutex type + typedef M mutex_type; + + //! Constructor + /** precondition: If mutex_type is not a recursive mutex, the calling thread + does not own the mutex m. */ + explicit lock_guard(mutex_type& m) : pm(m) {m.lock();} + + //! Adopt_lock constructor + /** precondition: the calling thread owns the mutex m. */ + lock_guard(mutex_type& m, adopt_lock_t) : pm(m) {} + + //! Destructor + ~lock_guard() { pm.unlock(); } +private: + mutex_type& pm; +}; + +// C++0x standard working draft 30.4.3.2 +//! unique_lock +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE unique_lock : tbb::internal::no_copy { + friend class condition_variable; +public: + typedef M mutex_type; + + // 30.4.3.2.1 construct/copy/destroy + // NB: Without constructors that take an r-value reference to a unique_lock, the following constructor is of little use. + //! Constructor + /** postcondition: pm==0 && owns==false */ + unique_lock() : pm(NULL), owns(false) {} + + //! Constructor + /** precondition: if mutex_type is not a recursive mutex, the calling thread + does not own the mutex m. If the precondition is not met, a deadlock occurs. + postcondition: pm==&m and owns==true */ + explicit unique_lock(mutex_type& m) : pm(&m) {m.lock(); owns=true;} + + //! Defer_lock constructor + /** postcondition: pm==&m and owns==false */ + unique_lock(mutex_type& m, defer_lock_t) : pm(&m), owns(false) {} + + //! Try_to_lock constructor + /** precondition: if mutex_type is not a recursive mutex, the calling thread + does not own the mutex m. If the precondition is not met, a deadlock occurs. + postcondition: pm==&m and owns==res where res is the value returned by + the call to m.try_lock(). */ + unique_lock(mutex_type& m, try_to_lock_t) : pm(&m) {owns = m.try_lock();} + + //! Adopt_lock constructor + /** precondition: the calling thread owns the mutex. If it does not, mutex->unlock() would fail. + postcondition: pm==&m and owns==true */ + unique_lock(mutex_type& m, adopt_lock_t) : pm(&m), owns(true) {} + + //! Timed unique_lock acquisition. + /** To avoid requiring support for namespace chrono, this method deviates from the working draft in that + it uses tbb::tick_count::interval_t to specify the time duration. */ + unique_lock(mutex_type& m, const tick_count::interval_t &i) : pm(&m) {owns = try_lock_for( i );} + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move constructor + /** postconditions: pm == src_p.pm and owns == src_p.owns (where src_p is the state of src just prior to this + construction), src.pm == 0 and src.owns == false. */ + unique_lock(unique_lock && src): pm(NULL), owns(false) {this->swap(src);} + + //! Move assignment + /** effects: If owns calls pm->unlock(). + Postconditions: pm == src_p.pm and owns == src_p.owns (where src_p is the state of src just prior to this + assignment), src.pm == 0 and src.owns == false. */ + unique_lock& operator=(unique_lock && src) { + if (owns) + this->unlock(); + pm = NULL; + this->swap(src); + return *this; + } +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + + //! Destructor + ~unique_lock() { if( owns ) pm->unlock(); } + + // 30.4.3.2.2 locking + //! Lock the mutex and own it. + void lock() { + if( pm ) { + if( !owns ) { + pm->lock(); + owns = true; + } else + throw_exception_v4( tbb::internal::eid_possible_deadlock ); + } else + throw_exception_v4( tbb::internal::eid_operation_not_permitted ); + __TBB_ASSERT( owns, NULL ); + } + + //! Try to lock the mutex. + /** If successful, note that this lock owns it. Otherwise, set it false. */ + bool try_lock() { + if( pm ) { + if( !owns ) + owns = pm->try_lock(); + else + throw_exception_v4( tbb::internal::eid_possible_deadlock ); + } else + throw_exception_v4( tbb::internal::eid_operation_not_permitted ); + return owns; + } + + //! Try to lock the mutex. + bool try_lock_for( const tick_count::interval_t &i ); + + //! Unlock the mutex + /** And note that this lock no longer owns it. */ + void unlock() { + if( owns ) { + pm->unlock(); + owns = false; + } else + throw_exception_v4( tbb::internal::eid_operation_not_permitted ); + __TBB_ASSERT( !owns, NULL ); + } + + // 30.4.3.2.3 modifiers + //! Swap the two unique locks + void swap(unique_lock& u) { + mutex_type* t_pm = u.pm; u.pm = pm; pm = t_pm; + bool t_owns = u.owns; u.owns = owns; owns = t_owns; + } + + //! Release control over the mutex. + mutex_type* release() { + mutex_type* o_pm = pm; + pm = NULL; + owns = false; + return o_pm; + } + + // 30.4.3.2.4 observers + //! Does this lock own the mutex? + bool owns_lock() const { return owns; } + + // TODO: Un-comment 'explicit' when the last non-C++0x compiler support is dropped + //! Does this lock own the mutex? + /*explicit*/ operator bool() const { return owns; } + + //! Return the mutex that this lock currently has. + mutex_type* mutex() const { return pm; } + +private: + mutex_type* pm; + bool owns; +}; + +template +__TBB_DEPRECATED_IN_VERBOSE_MODE bool unique_lock::try_lock_for( const tick_count::interval_t &i) +{ + const int unique_lock_tick = 100; /* microseconds; 0.1 milliseconds */ + // the smallest wait-time is 0.1 milliseconds. + bool res = pm->try_lock(); + int duration_in_micro; + if( !res && (duration_in_micro=int(i.seconds()*1e6))>unique_lock_tick ) { + tick_count::interval_t i_100( double(unique_lock_tick)/1e6 /* seconds */); // 100 microseconds = 0.1*10E-3 + do { + this_tbb_thread::sleep(i_100); // sleep for 100 micro seconds + duration_in_micro -= unique_lock_tick; + res = pm->try_lock(); + } while( !res && duration_in_micro>unique_lock_tick ); + } + return (owns=res); +} + +//! Swap the two unique locks that have the mutexes of same type +template +void swap(unique_lock& x, unique_lock& y) { x.swap( y ); } + +namespace internal { + +#if _WIN32||_WIN64 +union condvar_impl_t { + condition_variable_using_event cv_event; + CONDITION_VARIABLE cv_native; +}; +void __TBB_EXPORTED_FUNC internal_initialize_condition_variable( condvar_impl_t& cv ); +void __TBB_EXPORTED_FUNC internal_destroy_condition_variable( condvar_impl_t& cv ); +void __TBB_EXPORTED_FUNC internal_condition_variable_notify_one( condvar_impl_t& cv ); +void __TBB_EXPORTED_FUNC internal_condition_variable_notify_all( condvar_impl_t& cv ); +bool __TBB_EXPORTED_FUNC internal_condition_variable_wait( condvar_impl_t& cv, mutex* mtx, const tick_count::interval_t* i = NULL ); + +#else /* if !(_WIN32||_WIN64), i.e., POSIX threads */ +typedef pthread_cond_t condvar_impl_t; +#endif + +} // namespace internal + +//! cv_status +/** C++0x standard working draft 30.5 */ +enum cv_status { no_timeout, timeout }; + +//! condition variable +/** C++0x standard working draft 30.5.1 + @ingroup synchronization */ +class __TBB_DEPRECATED_IN_VERBOSE_MODE condition_variable : tbb::internal::no_copy { +public: + //! Constructor + condition_variable() { +#if _WIN32||_WIN64 + internal_initialize_condition_variable( my_cv ); +#else + pthread_cond_init( &my_cv, NULL ); +#endif + } + + //! Destructor + ~condition_variable() { + //precondition: There shall be no thread blocked on *this. +#if _WIN32||_WIN64 + internal_destroy_condition_variable( my_cv ); +#else + pthread_cond_destroy( &my_cv ); +#endif + } + + //! Notify one thread and wake it up + void notify_one() { +#if _WIN32||_WIN64 + internal_condition_variable_notify_one( my_cv ); +#else + pthread_cond_signal( &my_cv ); +#endif + } + + //! Notify all threads + void notify_all() { +#if _WIN32||_WIN64 + internal_condition_variable_notify_all( my_cv ); +#else + pthread_cond_broadcast( &my_cv ); +#endif + } + + //! Release the mutex associated with the lock and wait on this condition variable + void wait(unique_lock& lock); + + //! Wait on this condition variable while pred is false + template + void wait(unique_lock& lock, Predicate pred) { + while( !pred() ) + wait( lock ); + } + + //! Timed version of wait() + cv_status wait_for(unique_lock& lock, const tick_count::interval_t &i ); + + //! Timed version of the predicated wait + /** The loop terminates when pred() returns true or when the time duration specified by rel_time (i) has elapsed. */ + template + bool wait_for(unique_lock& lock, const tick_count::interval_t &i, Predicate pred) + { + while( !pred() ) { + cv_status st = wait_for( lock, i ); + if( st==timeout ) + return pred(); + } + return true; + } + + // C++0x standard working draft. 30.2.3 + typedef internal::condvar_impl_t* native_handle_type; + + native_handle_type native_handle() { return (native_handle_type) &my_cv; } + +private: + internal::condvar_impl_t my_cv; +}; + + +#if _WIN32||_WIN64 +inline void condition_variable::wait( unique_lock& lock ) +{ + __TBB_ASSERT( lock.owns, NULL ); + lock.owns = false; + if( !internal_condition_variable_wait( my_cv, lock.mutex() ) ) { + int ec = GetLastError(); + // on Windows 7, SleepConditionVariableCS() may return ERROR_TIMEOUT while the doc says it returns WAIT_TIMEOUT + __TBB_ASSERT_EX( ec!=WAIT_TIMEOUT&&ec!=ERROR_TIMEOUT, NULL ); + lock.owns = true; + throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); + } + lock.owns = true; +} + +inline cv_status condition_variable::wait_for( unique_lock& lock, const tick_count::interval_t& i ) +{ + cv_status rc = no_timeout; + __TBB_ASSERT( lock.owns, NULL ); + lock.owns = false; + // condvar_wait could be SleepConditionVariableCS (or SleepConditionVariableSRW) or our own pre-vista cond_var_wait() + if( !internal_condition_variable_wait( my_cv, lock.mutex(), &i ) ) { + int ec = GetLastError(); + if( ec==WAIT_TIMEOUT || ec==ERROR_TIMEOUT ) + rc = timeout; + else { + lock.owns = true; + throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); + } + } + lock.owns = true; + return rc; +} + +#else /* !(_WIN32||_WIN64) */ +inline void condition_variable::wait( unique_lock& lock ) +{ + __TBB_ASSERT( lock.owns, NULL ); + lock.owns = false; + if( pthread_cond_wait( &my_cv, lock.mutex()->native_handle() ) ) { + lock.owns = true; + throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); + } + // upon successful return, the mutex has been locked and is owned by the calling thread. + lock.owns = true; +} + +inline cv_status condition_variable::wait_for( unique_lock& lock, const tick_count::interval_t& i ) +{ +#if __linux__ + struct timespec req; + double sec = i.seconds(); + clock_gettime( CLOCK_REALTIME, &req ); + req.tv_sec += static_cast(sec); + req.tv_nsec += static_cast( (sec - static_cast(sec))*1e9 ); +#else /* generic Unix */ + struct timeval tv; + struct timespec req; + double sec = i.seconds(); + int status = gettimeofday(&tv, NULL); + __TBB_ASSERT_EX( status==0, "gettimeofday failed" ); + req.tv_sec = tv.tv_sec + static_cast(sec); + req.tv_nsec = tv.tv_usec*1000 + static_cast( (sec - static_cast(sec))*1e9 ); +#endif /*(choice of OS) */ + if( req.tv_nsec>=1e9 ) { + req.tv_sec += 1; + req.tv_nsec -= static_cast(1e9); + } + __TBB_ASSERT( 0<=req.tv_nsec && req.tv_nsec<1e9, NULL ); + + int ec; + cv_status rc = no_timeout; + __TBB_ASSERT( lock.owns, NULL ); + lock.owns = false; + if( ( ec=pthread_cond_timedwait( &my_cv, lock.mutex()->native_handle(), &req ) ) ) { + if( ec==ETIMEDOUT ) + rc = timeout; + else { + __TBB_ASSERT( lock.try_lock()==false, NULL ); + lock.owns = true; + throw_exception_v4( tbb::internal::eid_condvar_wait_failed ); + } + } + lock.owns = true; + return rc; +} +#endif /* !(_WIN32||_WIN64) */ + +} // namespace interface5 + +__TBB_DEFINE_PROFILING_SET_NAME(interface5::condition_variable) + +} // namespace tbb + +#if TBB_IMPLEMENT_CPP0X + +namespace std { + +using tbb::interface5::defer_lock_t; +using tbb::interface5::try_to_lock_t; +using tbb::interface5::adopt_lock_t; +using tbb::interface5::defer_lock; +using tbb::interface5::try_to_lock; +using tbb::interface5::adopt_lock; +using tbb::interface5::lock_guard; +using tbb::interface5::unique_lock; +using tbb::interface5::swap; /* this is for void std::swap(unique_lock&,unique_lock&) */ +using tbb::interface5::condition_variable; +using tbb::interface5::cv_status; +using tbb::interface5::timeout; +using tbb::interface5::no_timeout; + +} // namespace std + +#endif /* TBB_IMPLEMENT_CPP0X */ + +#include "../internal/_warning_suppress_disable_notice.h" +#undef __TBB_condition_variable_H_include_area + +#endif /* __TBB_condition_variable_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/ppl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/ppl.h new file mode 100644 index 00000000..f441b038 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/ppl.h @@ -0,0 +1,75 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_ppl_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_ppl_H +#pragma message("TBB Warning: tbb/compat/ppl.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_compat_ppl_H +#define __TBB_compat_ppl_H + +#define __TBB_ppl_H_include_area +#include "../internal/_warning_suppress_enable_notice.h" + +#include "../task_group.h" +#include "../parallel_invoke.h" +#include "../parallel_for_each.h" +#include "../parallel_for.h" +#include "../tbb_exception.h" +#include "../critical_section.h" +#include "../reader_writer_lock.h" +#include "../combinable.h" + +namespace Concurrency { + +#if __TBB_TASK_GROUP_CONTEXT + using tbb::task_handle; + using tbb::task_group_status; + using tbb::task_group; + using tbb::structured_task_group; + using tbb::invalid_multiple_scheduling; + using tbb::missing_wait; + using tbb::make_task; + + using tbb::not_complete; + using tbb::complete; + using tbb::canceled; + + using tbb::is_current_task_group_canceling; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + using tbb::parallel_invoke; + using tbb::strict_ppl::parallel_for; + using tbb::parallel_for_each; + using tbb::critical_section; + using tbb::reader_writer_lock; + using tbb::combinable; + + using tbb::improper_lock; + +} // namespace Concurrency + +#include "../internal/_warning_suppress_disable_notice.h" +#undef __TBB_ppl_H_include_area + +#endif /* __TBB_compat_ppl_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/thread b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/thread new file mode 100644 index 00000000..8b8a13d7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/thread @@ -0,0 +1,73 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_thread_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_thread_H +#pragma message("TBB Warning: tbb/compat/thread is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_thread_H +#define __TBB_thread_H + +#define __TBB_thread_H_include_area +#include "../internal/_warning_suppress_enable_notice.h" + +#include "../tbb_config.h" + +#if TBB_IMPLEMENT_CPP0X + +#include "../tbb_thread.h" + +namespace std { + +typedef tbb::tbb_thread thread; + +namespace this_thread { + using tbb::this_tbb_thread::get_id; + using tbb::this_tbb_thread::yield; + + __TBB_DEPRECATED_IN_VERBOSE_MODE inline void sleep_for(const tbb::tick_count::interval_t& rel_time) { + tbb::internal::thread_sleep_v3( rel_time ); + } +} + +} // namespace std + +#else /* TBB_IMPLEMENT_CPP0X */ + +#define __TBB_COMPAT_THREAD_RECURSION_PROTECTOR 1 +#include +#undef __TBB_COMPAT_THREAD_RECURSION_PROTECTOR + +#endif /* TBB_IMPLEMENT_CPP0X */ + +#include "../internal/_warning_suppress_disable_notice.h" +#undef __TBB_thread_H_include_area + +#else /* __TBB_thread_H */ + +#if __TBB_COMPAT_THREAD_RECURSION_PROTECTOR +#error The tbb/compat/thread header attempts to include itself. \ + Please make sure that {TBBROOT}/include/tbb/compat is NOT in include paths. +#endif + +#endif /* __TBB_thread_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/tuple b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/tuple new file mode 100644 index 00000000..c568ef3d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/compat/tuple @@ -0,0 +1,501 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_tuple_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_tuple_H +#pragma message("TBB Warning: tbb/compat/tuple is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_tuple_H +#define __TBB_tuple_H + +#define __TBB_tuple_H_include_area +#include "../internal/_warning_suppress_enable_notice.h" + +#include +#include "../tbb_stddef.h" + +// build preprocessor variables for varying number of arguments +// Need the leading comma so the empty __TBB_T_PACK will not cause a syntax error. +#if __TBB_VARIADIC_MAX <= 5 +#define __TBB_T_PACK +#define __TBB_U_PACK +#define __TBB_TYPENAME_T_PACK +#define __TBB_TYPENAME_U_PACK +#define __TBB_NULL_TYPE_PACK +#define __TBB_REF_T_PARAM_PACK +#define __TBB_CONST_REF_T_PARAM_PACK +#define __TBB_T_PARAM_LIST_PACK +#define __TBB_CONST_NULL_REF_PACK +// +#elif __TBB_VARIADIC_MAX == 6 +#define __TBB_T_PACK ,__T5 +#define __TBB_U_PACK ,__U5 +#define __TBB_TYPENAME_T_PACK , typename __T5 +#define __TBB_TYPENAME_U_PACK , typename __U5 +#define __TBB_NULL_TYPE_PACK , null_type +#define __TBB_REF_T_PARAM_PACK ,__T5& t5 +#define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5 +#define __TBB_T_PARAM_LIST_PACK ,t5 +#define __TBB_CONST_NULL_REF_PACK , const null_type& +// +#elif __TBB_VARIADIC_MAX == 7 +#define __TBB_T_PACK ,__T5, __T6 +#define __TBB_U_PACK ,__U5, __U6 +#define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6 +#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6 +#define __TBB_NULL_TYPE_PACK , null_type, null_type +#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6 +#define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5, const __T6& t6 +#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 +#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type& +// +#elif __TBB_VARIADIC_MAX == 8 +#define __TBB_T_PACK ,__T5, __T6, __T7 +#define __TBB_U_PACK ,__U5, __U6, __U7 +#define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6, typename __T7 +#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6, typename __U7 +#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type +#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7 +#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7 +#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 +#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type& +// +#elif __TBB_VARIADIC_MAX == 9 +#define __TBB_T_PACK ,__T5, __T6, __T7, __T8 +#define __TBB_U_PACK ,__U5, __U6, __U7, __U8 +#define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8 +#define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8 +#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type +#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8 +#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8 +#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 +#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type& +// +#elif __TBB_VARIADIC_MAX >= 10 +#define __TBB_T_PACK ,__T5, __T6, __T7, __T8, __T9 +#define __TBB_U_PACK ,__U5, __U6, __U7, __U8, __U9 +#define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8, typename __T9 +#define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8, typename __U9 +#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type, null_type +#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8, __T9& t9 +#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8, const __T9& t9 +#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 ,t9 +#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type&, const null_type& +#endif + + + +namespace tbb { +namespace interface5 { + +namespace internal { +struct null_type { }; +} +using internal::null_type; + +// tuple forward declaration +template = 6 +, typename __T5=null_type +#if __TBB_VARIADIC_MAX >= 7 +, typename __T6=null_type +#if __TBB_VARIADIC_MAX >= 8 +, typename __T7=null_type +#if __TBB_VARIADIC_MAX >= 9 +, typename __T8=null_type +#if __TBB_VARIADIC_MAX >= 10 +, typename __T9=null_type +#endif +#endif +#endif +#endif +#endif +> +class tuple; + +namespace internal { + +// const null_type temp +inline const null_type cnull() { return null_type(); } + +// cons forward declaration +template struct cons; + +// type of a component of the cons +template +struct component { + typedef typename __T::tail_type next; + typedef typename component<__N-1,next>::type type; +}; + +template +struct component<0,__T> { + typedef typename __T::head_type type; +}; + +template<> +struct component<0,null_type> { + typedef null_type type; +}; + +// const version of component + +template +struct component<__N, const __T> +{ + typedef typename __T::tail_type next; + typedef const typename component<__N-1,next>::type type; +}; + +template +struct component<0, const __T> +{ + typedef const typename __T::head_type type; +}; + + +// helper class for getting components of cons +template< int __N> +struct get_helper { +template +inline static typename component<__N, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) { + return get_helper<__N-1>::get(ti.tail); +} +template +inline static typename component<__N, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) { + return get_helper<__N-1>::get(ti.tail); +} +}; + +template<> +struct get_helper<0> { +template +inline static typename component<0, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) { + return ti.head; +} +template +inline static typename component<0, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) { + return ti.head; +} +}; + +// traits adaptor +template +struct tuple_traits { + typedef cons <__T0, typename tuple_traits<__T1, __T2, __T3, __T4 __TBB_T_PACK , null_type>::U > U; +}; + +template +struct tuple_traits<__T0, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > { + typedef cons<__T0, null_type> U; +}; + +template<> +struct tuple_traits { + typedef null_type U; +}; + + +// core cons defs +template +struct cons{ + + typedef __HT head_type; + typedef __TT tail_type; + + head_type head; + tail_type tail; + + static const int length = 1 + tail_type::length; + + // default constructors + explicit cons() : head(), tail() { } + + // non-default constructors + cons(head_type& h, const tail_type& t) : head(h), tail(t) { } + + template + cons(const __T0& t0, const __T1& t1, const __T2& t2, const __T3& t3, const __T4& t4 __TBB_CONST_REF_T_PARAM_PACK) : + head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK, cnull()) { } + + template + cons(__T0& t0, __T1& t1, __T2& t2, __T3& t3, __T4& t4 __TBB_REF_T_PARAM_PACK) : + head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK , cnull()) { } + + template + cons(const cons<__HT1,__TT1>& other) : head(other.head), tail(other.tail) { } + + cons& operator=(const cons& other) { head = other.head; tail = other.tail; return *this; } + + friend bool operator==(const cons& me, const cons& other) { + return me.head == other.head && me.tail == other.tail; + } + friend bool operator<(const cons& me, const cons& other) { + return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail); + } + friend bool operator>(const cons& me, const cons& other) { return other=(const cons& me, const cons& other) { return !(meother); } + + template + friend bool operator==(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { + return me.head == other.head && me.tail == other.tail; + } + + template + friend bool operator<(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { + return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail); + } + + template + friend bool operator>(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return other + friend bool operator!=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me==other); } + + template + friend bool operator>=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me + friend bool operator<=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me>other); } + + +}; // cons + + +template +struct cons<__HT,null_type> { + + typedef __HT head_type; + typedef null_type tail_type; + + head_type head; + + static const int length = 1; + + // default constructor + cons() : head() { /*std::cout << "default constructor 1\n";*/ } + + cons(const null_type&, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head() { /*std::cout << "default constructor 2\n";*/ } + + // non-default constructor + template + cons(__T1& t1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t1) { /*std::cout << "non-default a1, t1== " << t1 << "\n";*/} + + cons(head_type& h, const null_type& = null_type() ) : head(h) { } + cons(const head_type& t0, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t0) { } + + // converting constructor + template + cons(__HT1 h1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(h1) { } + + // copy constructor + template + cons( const cons<__HT1, null_type>& other) : head(other.head) { } + + // assignment operator + cons& operator=(const cons& other) { head = other.head; return *this; } + + friend bool operator==(const cons& me, const cons& other) { return me.head == other.head; } + friend bool operator<(const cons& me, const cons& other) { return me.head < other.head; } + friend bool operator>(const cons& me, const cons& other) { return otherother); } + friend bool operator>=(const cons& me, const cons& other) {return !(me + friend bool operator==(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { + return me.head == other.head; + } + + template + friend bool operator<(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { + return me.head < other.head; + } + + template + friend bool operator>(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return other + friend bool operator!=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me==other); } + + template + friend bool operator<=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me>other); } + + template + friend bool operator>=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me +struct cons { typedef null_type tail_type; static const int length = 0; }; + +// wrapper for default constructor +template +inline const __T wrap_dcons(__T*) { return __T(); } + +} // namespace internal + +// tuple definition +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE tuple : public internal::tuple_traits<__T0, __T1, __T2, __T3, __T4 __TBB_T_PACK >::U { + // friends + template friend class tuple_size; + template friend struct tuple_element; + + // stl components + typedef tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef size_t size_type; + + typedef typename internal::tuple_traits<__T0,__T1,__T2,__T3, __T4 __TBB_T_PACK >::U my_cons; + +public: + __TBB_DEPRECATED_IN_VERBOSE_MODE tuple(const __T0& t0=internal::wrap_dcons((__T0*)NULL) + ,const __T1& t1=internal::wrap_dcons((__T1*)NULL) + ,const __T2& t2=internal::wrap_dcons((__T2*)NULL) + ,const __T3& t3=internal::wrap_dcons((__T3*)NULL) + ,const __T4& t4=internal::wrap_dcons((__T4*)NULL) +#if __TBB_VARIADIC_MAX >= 6 + ,const __T5& t5=internal::wrap_dcons((__T5*)NULL) +#if __TBB_VARIADIC_MAX >= 7 + ,const __T6& t6=internal::wrap_dcons((__T6*)NULL) +#if __TBB_VARIADIC_MAX >= 8 + ,const __T7& t7=internal::wrap_dcons((__T7*)NULL) +#if __TBB_VARIADIC_MAX >= 9 + ,const __T8& t8=internal::wrap_dcons((__T8*)NULL) +#if __TBB_VARIADIC_MAX >= 10 + ,const __T9& t9=internal::wrap_dcons((__T9*)NULL) +#endif +#endif +#endif +#endif +#endif + ) : + my_cons(t0,t1,t2,t3,t4 __TBB_T_PARAM_LIST_PACK) { } + + template + struct internal_tuple_element { + typedef typename internal::component<__N,my_cons>::type type; + }; + + template + typename internal_tuple_element<__N>::type& get() { return internal::get_helper<__N>::get(*this); } + + template + typename internal_tuple_element<__N>::type const& get() const { return internal::get_helper<__N>::get(*this); } + + template + tuple& operator=(const internal::cons<__U1,__U2>& other) { + my_cons::operator=(other); + return *this; + } + + template + tuple& operator=(const std::pair<__U1,__U2>& other) { + // __TBB_ASSERT(tuple_size::value == 2, "Invalid size for pair to tuple assignment"); + this->head = other.first; + this->tail.head = other.second; + return *this; + } + + friend bool operator==(const tuple& me, const tuple& other) {return static_cast(me)==(other);} + friend bool operator<(const tuple& me, const tuple& other) {return static_cast(me)<(other);} + friend bool operator>(const tuple& me, const tuple& other) {return static_cast(me)>(other);} + friend bool operator!=(const tuple& me, const tuple& other) {return static_cast(me)!=(other);} + friend bool operator>=(const tuple& me, const tuple& other) {return static_cast(me)>=(other);} + friend bool operator<=(const tuple& me, const tuple& other) {return static_cast(me)<=(other);} + +}; // tuple + +// empty tuple +template<> +class __TBB_DEPRECATED_IN_VERBOSE_MODE tuple : public null_type { +}; + +// helper classes + +template < typename __T> +class tuple_size { +public: + static const size_t value = 1 + tuple_size::value; +}; + +template <> +class tuple_size > { +public: + static const size_t value = 0; +}; + +template <> +class tuple_size { +public: + static const size_t value = 0; +}; + +template +struct tuple_element { + typedef typename internal::component<__N, typename __T::my_cons>::type type; +}; + +template +inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type& + get(tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); } + +template +inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type const& + get(const tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); } + +} // interface5 +} // tbb + +#if !__TBB_CPP11_TUPLE_PRESENT +namespace tbb { + namespace flow { + using tbb::interface5::tuple; + using tbb::interface5::tuple_size; + using tbb::interface5::tuple_element; + using tbb::interface5::get; + } +} +#endif + +#undef __TBB_T_PACK +#undef __TBB_U_PACK +#undef __TBB_TYPENAME_T_PACK +#undef __TBB_TYPENAME_U_PACK +#undef __TBB_NULL_TYPE_PACK +#undef __TBB_REF_T_PARAM_PACK +#undef __TBB_CONST_REF_T_PARAM_PACK +#undef __TBB_T_PARAM_LIST_PACK +#undef __TBB_CONST_NULL_REF_PACK + +#include "../internal/_warning_suppress_disable_notice.h" +#undef __TBB_tuple_H_include_area + +#endif /* __TBB_tuple_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_hash_map.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_hash_map.h new file mode 100644 index 00000000..80bad97b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_hash_map.h @@ -0,0 +1,1650 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_hash_map_H +#define __TBB_concurrent_hash_map_H + +#define __TBB_concurrent_hash_map_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_stddef.h" +#include +#include // Need std::pair +#include // Need std::memset +#include __TBB_STD_SWAP_HEADER + +#include "tbb_allocator.h" +#include "spin_rw_mutex.h" +#include "atomic.h" +#include "tbb_exception.h" +#include "tbb_profiling.h" +#include "aligned_space.h" +#include "internal/_tbb_hash_compare_impl.h" +#include "internal/_template_helpers.h" +#include "internal/_allocator_traits.h" +#if __TBB_INITIALIZER_LISTS_PRESENT +#include +#endif +#if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS +#include +#endif +#if __TBB_STATISTICS +#include +#endif +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TUPLE_PRESENT +// Definition of __TBB_CPP11_RVALUE_REF_PRESENT includes __TBB_CPP11_TUPLE_PRESENT +// for most of platforms, tuple present macro was added for logical correctness +#include +#endif + +namespace tbb { + +namespace interface5 { + + template, typename A = tbb_allocator > > + class concurrent_hash_map; + + //! @cond INTERNAL + namespace internal { + using namespace tbb::internal; + + + //! Type of a hash code. + typedef size_t hashcode_t; + //! Node base type + struct hash_map_node_base : tbb::internal::no_copy { + //! Mutex type + typedef spin_rw_mutex mutex_t; + //! Scoped lock type for mutex + typedef mutex_t::scoped_lock scoped_t; + //! Next node in chain + hash_map_node_base *next; + mutex_t mutex; + }; + //! Incompleteness flag value + static hash_map_node_base *const rehash_req = reinterpret_cast(size_t(3)); + //! Rehashed empty bucket flag + static hash_map_node_base *const empty_rehashed = reinterpret_cast(size_t(0)); + //! base class of concurrent_hash_map + class hash_map_base { + public: + //! Size type + typedef size_t size_type; + //! Type of a hash code. + typedef size_t hashcode_t; + //! Segment index type + typedef size_t segment_index_t; + //! Node base type + typedef hash_map_node_base node_base; + //! Bucket type + struct bucket : tbb::internal::no_copy { + //! Mutex type for buckets + typedef spin_rw_mutex mutex_t; + //! Scoped lock type for mutex + typedef mutex_t::scoped_lock scoped_t; + mutex_t mutex; + node_base *node_list; + }; + //! Count of segments in the first block + static size_type const embedded_block = 1; + //! Count of segments in the first block + static size_type const embedded_buckets = 1< my_mask; + //! Segment pointers table. Also prevents false sharing between my_mask and my_size + segments_table_t my_table; + //! Size of container in stored items + atomic my_size; // It must be in separate cache line from my_mask due to performance effects + //! Zero segment + bucket my_embedded_segment[embedded_buckets]; +#if __TBB_STATISTICS + atomic my_info_resizes; // concurrent ones + mutable atomic my_info_restarts; // race collisions + atomic my_info_rehashes; // invocations of rehash_bucket +#endif + //! Constructor + hash_map_base() { + std::memset(my_table, 0, sizeof(my_table)); + my_mask = 0; + my_size = 0; + std::memset(my_embedded_segment, 0, sizeof(my_embedded_segment)); + for( size_type i = 0; i < embedded_block; i++ ) // fill the table + my_table[i] = my_embedded_segment + segment_base(i); + my_mask = embedded_buckets - 1; + __TBB_ASSERT( embedded_block <= first_block, "The first block number must include embedded blocks"); +#if __TBB_STATISTICS + my_info_resizes = 0; // concurrent ones + my_info_restarts = 0; // race collisions + my_info_rehashes = 0; // invocations of rehash_bucket +#endif + } + + //! @return segment index of given index in the array + static segment_index_t segment_index_of( size_type index ) { + return segment_index_t( __TBB_Log2( index|1 ) ); + } + + //! @return the first array index of given segment + static segment_index_t segment_base( segment_index_t k ) { + return (segment_index_t(1)<(ptr) > uintptr_t(63); + } + + //! Initialize buckets + static void init_buckets( segment_ptr_t ptr, size_type sz, bool is_initial ) { + if( is_initial ) std::memset( static_cast(ptr), 0, sz*sizeof(bucket) ); + else for(size_type i = 0; i < sz; i++, ptr++) { + *reinterpret_cast(&ptr->mutex) = 0; + ptr->node_list = rehash_req; + } + } + + //! Add node @arg n to bucket @arg b + static void add_to_bucket( bucket *b, node_base *n ) { + __TBB_ASSERT(b->node_list != rehash_req, NULL); + n->next = b->node_list; + b->node_list = n; // its under lock and flag is set + } + + //! Exception safety helper + struct enable_segment_failsafe : tbb::internal::no_copy { + segment_ptr_t *my_segment_ptr; + enable_segment_failsafe(segments_table_t &table, segment_index_t k) : my_segment_ptr(&table[k]) {} + ~enable_segment_failsafe() { + if( my_segment_ptr ) *my_segment_ptr = 0; // indicate no allocation in progress + } + }; + + //! Enable segment + template + void enable_segment( segment_index_t k, const Allocator& allocator, bool is_initial = false ) { + typedef typename tbb::internal::allocator_rebind::type bucket_allocator_type; + typedef tbb::internal::allocator_traits bucket_allocator_traits; + bucket_allocator_type bucket_allocator(allocator); + __TBB_ASSERT( k, "Zero segment must be embedded" ); + enable_segment_failsafe watchdog( my_table, k ); + size_type sz; + __TBB_ASSERT( !is_valid(my_table[k]), "Wrong concurrent assignment"); + if( k >= first_block ) { + sz = segment_size( k ); + segment_ptr_t ptr = bucket_allocator_traits::allocate(bucket_allocator, sz); + init_buckets( ptr, sz, is_initial ); + itt_hide_store_word( my_table[k], ptr ); + sz <<= 1;// double it to get entire capacity of the container + } else { // the first block + __TBB_ASSERT( k == embedded_block, "Wrong segment index" ); + sz = segment_size( first_block ); + segment_ptr_t ptr = bucket_allocator_traits::allocate(bucket_allocator, sz - embedded_buckets); + init_buckets( ptr, sz - embedded_buckets, is_initial ); + ptr -= segment_base(embedded_block); + for(segment_index_t i = embedded_block; i < first_block; i++) // calc the offsets + itt_hide_store_word( my_table[i], ptr + segment_base(i) ); + } + itt_store_word_with_release( my_mask, sz-1 ); + watchdog.my_segment_ptr = 0; + } + + template + void delete_segment(segment_index_t s, const Allocator& allocator) { + typedef typename tbb::internal::allocator_rebind::type bucket_allocator_type; + typedef tbb::internal::allocator_traits bucket_allocator_traits; + bucket_allocator_type bucket_allocator(allocator); + segment_ptr_t buckets_ptr = my_table[s]; + size_type sz = segment_size( s ? s : 1 ); + + if( s >= first_block) // the first segment or the next + bucket_allocator_traits::deallocate(bucket_allocator, buckets_ptr, sz); + else if( s == embedded_block && embedded_block != first_block ) + bucket_allocator_traits::deallocate(bucket_allocator, buckets_ptr, + segment_size(first_block) - embedded_buckets); + if( s >= embedded_block ) my_table[s] = 0; + } + + //! Get bucket by (masked) hashcode + bucket *get_bucket( hashcode_t h ) const throw() { // TODO: add throw() everywhere? + segment_index_t s = segment_index_of( h ); + h -= segment_base(s); + segment_ptr_t seg = my_table[s]; + __TBB_ASSERT( is_valid(seg), "hashcode must be cut by valid mask for allocated segments" ); + return &seg[h]; + } + + // internal serial rehashing helper + void mark_rehashed_levels( hashcode_t h ) throw () { + segment_index_t s = segment_index_of( h ); + while( segment_ptr_t seg = my_table[++s] ) + if( seg[h].node_list == rehash_req ) { + seg[h].node_list = empty_rehashed; + mark_rehashed_levels( h + ((hashcode_t)1<node_list) != rehash_req ) + { +#if __TBB_STATISTICS + my_info_restarts++; // race collisions +#endif + return true; + } + } + return false; + } + + //! Insert a node and check for load factor. @return segment index to enable. + segment_index_t insert_new_node( bucket *b, node_base *n, hashcode_t mask ) { + size_type sz = ++my_size; // prefix form is to enforce allocation after the first item inserted + add_to_bucket( b, n ); + // check load factor + if( sz >= mask ) { // TODO: add custom load_factor + segment_index_t new_seg = __TBB_Log2( mask+1 ); //optimized segment_index_of + __TBB_ASSERT( is_valid(my_table[new_seg-1]), "new allocations must not publish new mask until segment has allocated"); + static const segment_ptr_t is_allocating = (segment_ptr_t)2; + if( !itt_hide_load_word(my_table[new_seg]) + && as_atomic(my_table[new_seg]).compare_and_swap(is_allocating, NULL) == NULL ) + return new_seg; // The value must be processed + } + return 0; + } + + //! Prepare enough segments for number of buckets + template + void reserve(size_type buckets, const Allocator& allocator) { + if( !buckets-- ) return; + bool is_initial = !my_size; + for( size_type m = my_mask; buckets > m; m = my_mask ) + enable_segment( segment_index_of( m+1 ), allocator, is_initial ); + } + //! Swap hash_map_bases + void internal_swap(hash_map_base &table) { + using std::swap; + swap(this->my_mask, table.my_mask); + swap(this->my_size, table.my_size); + for(size_type i = 0; i < embedded_buckets; i++) + swap(this->my_embedded_segment[i].node_list, table.my_embedded_segment[i].node_list); + for(size_type i = embedded_block; i < pointers_per_table; i++) + swap(this->my_table[i], table.my_table[i]); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + void internal_move(hash_map_base&& other) { + my_mask = other.my_mask; + other.my_mask = embedded_buckets - 1; + my_size = other.my_size; + other.my_size = 0; + + for(size_type i = 0; i < embedded_buckets; ++i) { + my_embedded_segment[i].node_list = other.my_embedded_segment[i].node_list; + other.my_embedded_segment[i].node_list = NULL; + } + + for(size_type i = embedded_block; i < pointers_per_table; ++i) { + my_table[i] = other.my_table[i]; + other.my_table[i] = NULL; + } + } +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + }; + + template + class hash_map_range; + + //! Meets requirements of a forward iterator for STL */ + /** Value is either the T or const T type of the container. + @ingroup containers */ + template + class hash_map_iterator + : public std::iterator + { + typedef Container map_type; + typedef typename Container::node node; + typedef hash_map_base::node_base node_base; + typedef hash_map_base::bucket bucket; + + template + friend bool operator==( const hash_map_iterator& i, const hash_map_iterator& j ); + + template + friend bool operator!=( const hash_map_iterator& i, const hash_map_iterator& j ); + + template + friend ptrdiff_t operator-( const hash_map_iterator& i, const hash_map_iterator& j ); + + template + friend class hash_map_iterator; + + template + friend class hash_map_range; + + void advance_to_next_bucket() { // TODO?: refactor to iterator_base class + size_t k = my_index+1; + __TBB_ASSERT( my_bucket, "advancing an invalid iterator?"); + while( k <= my_map->my_mask ) { + // Following test uses 2's-complement wizardry + if( k&(k-2) ) // not the beginning of a segment + ++my_bucket; + else my_bucket = my_map->get_bucket( k ); + my_node = static_cast( my_bucket->node_list ); + if( hash_map_base::is_valid(my_node) ) { + my_index = k; return; + } + ++k; + } + my_bucket = 0; my_node = 0; my_index = k; // the end + } +#if !defined(_MSC_VER) || defined(__INTEL_COMPILER) + template + friend class interface5::concurrent_hash_map; +#else + public: // workaround +#endif + //! concurrent_hash_map over which we are iterating. + const Container *my_map; + + //! Index in hash table for current item + size_t my_index; + + //! Pointer to bucket + const bucket *my_bucket; + + //! Pointer to node that has current item + node *my_node; + + hash_map_iterator( const Container &map, size_t index, const bucket *b, node_base *n ); + + public: + //! Construct undefined iterator + hash_map_iterator(): my_map(), my_index(), my_bucket(), my_node() {} + hash_map_iterator( const hash_map_iterator &other ) : + my_map(other.my_map), + my_index(other.my_index), + my_bucket(other.my_bucket), + my_node(other.my_node) + {} + + hash_map_iterator& operator=( const hash_map_iterator &other ) { + my_map = other.my_map; + my_index = other.my_index; + my_bucket = other.my_bucket; + my_node = other.my_node; + return *this; + } + Value& operator*() const { + __TBB_ASSERT( hash_map_base::is_valid(my_node), "iterator uninitialized or at end of container?" ); + return my_node->value(); + } + Value* operator->() const {return &operator*();} + hash_map_iterator& operator++(); + + //! Post increment + hash_map_iterator operator++(int) { + hash_map_iterator old(*this); + operator++(); + return old; + } + }; + + template + hash_map_iterator::hash_map_iterator( const Container &map, size_t index, const bucket *b, node_base *n ) : + my_map(&map), + my_index(index), + my_bucket(b), + my_node( static_cast(n) ) + { + if( b && !hash_map_base::is_valid(n) ) + advance_to_next_bucket(); + } + + template + hash_map_iterator& hash_map_iterator::operator++() { + my_node = static_cast( my_node->next ); + if( !my_node ) advance_to_next_bucket(); + return *this; + } + + template + bool operator==( const hash_map_iterator& i, const hash_map_iterator& j ) { + return i.my_node == j.my_node && i.my_map == j.my_map; + } + + template + bool operator!=( const hash_map_iterator& i, const hash_map_iterator& j ) { + return i.my_node != j.my_node || i.my_map != j.my_map; + } + + //! Range class used with concurrent_hash_map + /** @ingroup containers */ + template + class hash_map_range { + typedef typename Iterator::map_type map_type; + Iterator my_begin; + Iterator my_end; + mutable Iterator my_midpoint; + size_t my_grainsize; + //! Set my_midpoint to point approximately half way between my_begin and my_end. + void set_midpoint() const; + template friend class hash_map_range; + public: + //! Type for size of a range + typedef std::size_t size_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::reference reference; + typedef typename Iterator::difference_type difference_type; + typedef Iterator iterator; + + //! True if range is empty. + bool empty() const {return my_begin==my_end;} + + //! True if range can be partitioned into two subranges. + bool is_divisible() const { + return my_midpoint!=my_end; + } + //! Split range. + hash_map_range( hash_map_range& r, split ) : + my_end(r.my_end), + my_grainsize(r.my_grainsize) + { + r.my_end = my_begin = r.my_midpoint; + __TBB_ASSERT( !empty(), "Splitting despite the range is not divisible" ); + __TBB_ASSERT( !r.empty(), "Splitting despite the range is not divisible" ); + set_midpoint(); + r.set_midpoint(); + } + //! type conversion + template + hash_map_range( hash_map_range& r) : + my_begin(r.my_begin), + my_end(r.my_end), + my_midpoint(r.my_midpoint), + my_grainsize(r.my_grainsize) + {} + //! Init range with container and grainsize specified + hash_map_range( const map_type &map, size_type grainsize_ = 1 ) : + my_begin( Iterator( map, 0, map.my_embedded_segment, map.my_embedded_segment->node_list ) ), + my_end( Iterator( map, map.my_mask + 1, 0, 0 ) ), + my_grainsize( grainsize_ ) + { + __TBB_ASSERT( grainsize_>0, "grainsize must be positive" ); + set_midpoint(); + } + const Iterator& begin() const {return my_begin;} + const Iterator& end() const {return my_end;} + //! The grain size for this range. + size_type grainsize() const {return my_grainsize;} + }; + + template + void hash_map_range::set_midpoint() const { + // Split by groups of nodes + size_t m = my_end.my_index-my_begin.my_index; + if( m > my_grainsize ) { + m = my_begin.my_index + m/2u; + hash_map_base::bucket *b = my_begin.my_map->get_bucket(m); + my_midpoint = Iterator(*my_begin.my_map,m,b,b->node_list); + } else { + my_midpoint = my_end; + } + __TBB_ASSERT( my_begin.my_index <= my_midpoint.my_index, + "my_begin is after my_midpoint" ); + __TBB_ASSERT( my_midpoint.my_index <= my_end.my_index, + "my_midpoint is after my_end" ); + __TBB_ASSERT( my_begin != my_midpoint || my_begin == my_end, + "[my_begin, my_midpoint) range should not be empty" ); + } + + } // internal +//! @endcond + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress "conditional expression is constant" warning. + #pragma warning( push ) + #pragma warning( disable: 4127 ) +#endif + +//! Unordered map from Key to T. +/** concurrent_hash_map is associative container with concurrent access. + +@par Compatibility + The class meets all Container Requirements from C++ Standard (See ISO/IEC 14882:2003(E), clause 23.1). + +@par Exception Safety + - Hash function is not permitted to throw an exception. User-defined types Key and T are forbidden from throwing an exception in destructors. + - If exception happens during insert() operations, it has no effect (unless exception raised by HashCompare::hash() function during grow_segment). + - If exception happens during operator=() operation, the container can have a part of source items, and methods size() and empty() can return wrong results. + +@par Changes since TBB 2.1 + - Replaced internal algorithm and data structure. Patent is pending. + - Added buckets number argument for constructor + +@par Changes since TBB 2.0 + - Fixed exception-safety + - Added template argument for allocator + - Added allocator argument in constructors + - Added constructor from a range of iterators + - Added several new overloaded insert() methods + - Added get_allocator() + - Added swap() + - Added count() + - Added overloaded erase(accessor &) and erase(const_accessor&) + - Added equal_range() [const] + - Added [const_]pointer, [const_]reference, and allocator_type types + - Added global functions: operator==(), operator!=(), and swap() + + @ingroup containers */ +template +class concurrent_hash_map : protected internal::hash_map_base { + template + friend class internal::hash_map_iterator; + + template + friend class internal::hash_map_range; + +public: + typedef Key key_type; + typedef T mapped_type; + typedef std::pair value_type; + typedef hash_map_base::size_type size_type; + typedef ptrdiff_t difference_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef internal::hash_map_iterator iterator; + typedef internal::hash_map_iterator const_iterator; + typedef internal::hash_map_range range_type; + typedef internal::hash_map_range const_range_type; + typedef Allocator allocator_type; + +protected: + friend class const_accessor; + class node; + typedef typename tbb::internal::allocator_rebind::type node_allocator_type; + typedef tbb::internal::allocator_traits node_allocator_traits; + node_allocator_type my_allocator; + HashCompare my_hash_compare; + + class node : public node_base { + tbb::aligned_space my_value; + public: + value_type* storage() { return my_value.begin(); } + value_type& value() { return *storage(); } + }; + + void delete_node( node_base *n ) { + node_allocator_traits::destroy(my_allocator, static_cast(n)->storage()); + node_allocator_traits::destroy(my_allocator, static_cast(n)); + node_allocator_traits::deallocate(my_allocator, static_cast(n), 1); + } + + struct node_scoped_guard : tbb::internal::no_copy { + node* my_node; + node_allocator_type& my_alloc; + + node_scoped_guard(node* n, node_allocator_type& alloc) : my_node(n), my_alloc(alloc) {} + ~node_scoped_guard() { + if(my_node) { + node_allocator_traits::destroy(my_alloc, my_node); + node_allocator_traits::deallocate(my_alloc, my_node, 1); + } + } + void dismiss() { my_node = NULL; } + }; + +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template + static node* create_node(node_allocator_type& allocator, Args&&... args) +#else + template + static node* create_node(node_allocator_type& allocator, __TBB_FORWARDING_REF(Arg1) arg1, __TBB_FORWARDING_REF(Arg2) arg2) +#endif + { + node* node_ptr = node_allocator_traits::allocate(allocator, 1); + node_scoped_guard guard(node_ptr, allocator); + node_allocator_traits::construct(allocator, node_ptr); +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + node_allocator_traits::construct(allocator, node_ptr->storage(), std::forward(args)...); +#else + node_allocator_traits::construct(allocator, node_ptr->storage(), tbb::internal::forward(arg1), tbb::internal::forward(arg2)); +#endif + guard.dismiss(); + return node_ptr; + } + + static node* allocate_node_copy_construct(node_allocator_type& allocator, const Key &key, const T * t){ + return create_node(allocator, key, *t); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + static node* allocate_node_move_construct(node_allocator_type& allocator, const Key &key, const T * t){ + return create_node(allocator, key, std::move(*const_cast(t))); + } +#endif + + static node* allocate_node_default_construct(node_allocator_type& allocator, const Key &key, const T * ){ +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TUPLE_PRESENT + // Emplace construct an empty T object inside the pair + return create_node(allocator, std::piecewise_construct, + std::forward_as_tuple(key), std::forward_as_tuple()); +#else + // Use of a temporary object is impossible, because create_node takes a non-const reference. + // copy-initialization is possible because T is already required to be CopyConstructible. + T obj = T(); + return create_node(allocator, key, tbb::internal::move(obj)); +#endif + } + + static node* do_not_allocate_node(node_allocator_type& , const Key &, const T * ){ + __TBB_ASSERT(false,"this dummy function should not be called"); + return NULL; + } + + node *search_bucket( const key_type &key, bucket *b ) const { + node *n = static_cast( b->node_list ); + while( is_valid(n) && !my_hash_compare.equal(key, n->value().first) ) + n = static_cast( n->next ); + __TBB_ASSERT(n != internal::rehash_req, "Search can be executed only for rehashed bucket"); + return n; + } + + //! bucket accessor is to find, rehash, acquire a lock, and access a bucket + class bucket_accessor : public bucket::scoped_t { + bucket *my_b; + public: + bucket_accessor( concurrent_hash_map *base, const hashcode_t h, bool writer = false ) { acquire( base, h, writer ); } + //! find a bucket by masked hashcode, optionally rehash, and acquire the lock + inline void acquire( concurrent_hash_map *base, const hashcode_t h, bool writer = false ) { + my_b = base->get_bucket( h ); + // TODO: actually, notification is unnecessary here, just hiding double-check + if( itt_load_word_with_acquire(my_b->node_list) == internal::rehash_req + && try_acquire( my_b->mutex, /*write=*/true ) ) + { + if( my_b->node_list == internal::rehash_req ) base->rehash_bucket( my_b, h ); //recursive rehashing + } + else bucket::scoped_t::acquire( my_b->mutex, writer ); + __TBB_ASSERT( my_b->node_list != internal::rehash_req, NULL); + } + //! check whether bucket is locked for write + bool is_writer() { return bucket::scoped_t::is_writer; } + //! get bucket pointer + bucket *operator() () { return my_b; } + }; + + // TODO refactor to hash_base + void rehash_bucket( bucket *b_new, const hashcode_t h ) { + __TBB_ASSERT( *(intptr_t*)(&b_new->mutex), "b_new must be locked (for write)"); + __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" ); + __TBB_store_with_release(b_new->node_list, internal::empty_rehashed); // mark rehashed + hashcode_t mask = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit +#if __TBB_STATISTICS + my_info_rehashes++; // invocations of rehash_bucket +#endif + + bucket_accessor b_old( this, h & mask ); + + mask = (mask<<1) | 1; // get full mask for new bucket + __TBB_ASSERT( (mask&(mask+1))==0 && (h & mask) == h, NULL ); + restart: + for( node_base **p = &b_old()->node_list, *n = __TBB_load_with_acquire(*p); is_valid(n); n = *p ) { + hashcode_t c = my_hash_compare.hash( static_cast(n)->value().first ); +#if TBB_USE_ASSERT + hashcode_t bmask = h & (mask>>1); + bmask = bmask==0? 1 : ( 1u<<(__TBB_Log2( bmask )+1 ) ) - 1; // minimal mask of parent bucket + __TBB_ASSERT( (c & bmask) == (h & bmask), "hash() function changed for key in table" ); +#endif + if( (c & mask) == h ) { + if( !b_old.is_writer() ) + if( !b_old.upgrade_to_writer() ) { + goto restart; // node ptr can be invalid due to concurrent erase + } + *p = n->next; // exclude from b_old + add_to_bucket( b_new, n ); + } else p = &n->next; // iterate to next item + } + } + + struct call_clear_on_leave { + concurrent_hash_map* my_ch_map; + call_clear_on_leave( concurrent_hash_map* a_ch_map ) : my_ch_map(a_ch_map) {} + void dismiss() {my_ch_map = 0;} + ~call_clear_on_leave(){ + if (my_ch_map){ + my_ch_map->clear(); + } + } + }; +public: + + class accessor; + //! Combines data access, locking, and garbage collection. + class const_accessor : private node::scoped_t /*which derived from no_copy*/ { + friend class concurrent_hash_map; + friend class accessor; + public: + //! Type of value + typedef const typename concurrent_hash_map::value_type value_type; + + //! True if result is empty. + bool empty() const { return !my_node; } + + //! Set to null + void release() { + if( my_node ) { + node::scoped_t::release(); + my_node = 0; + } + } + + //! Return reference to associated value in hash table. + const_reference operator*() const { + __TBB_ASSERT( my_node, "attempt to dereference empty accessor" ); + return my_node->value(); + } + + //! Return pointer to associated value in hash table. + const_pointer operator->() const { + return &operator*(); + } + + //! Create empty result + const_accessor() : my_node(NULL) {} + + //! Destroy result after releasing the underlying reference. + ~const_accessor() { + my_node = NULL; // scoped lock's release() is called in its destructor + } + protected: + bool is_writer() { return node::scoped_t::is_writer; } + node *my_node; + hashcode_t my_hash; + }; + + //! Allows write access to elements and combines data access, locking, and garbage collection. + class accessor: public const_accessor { + public: + //! Type of value + typedef typename concurrent_hash_map::value_type value_type; + + //! Return reference to associated value in hash table. + reference operator*() const { + __TBB_ASSERT( this->my_node, "attempt to dereference empty accessor" ); + return this->my_node->value(); + } + + //! Return pointer to associated value in hash table. + pointer operator->() const { + return &operator*(); + } + }; + + //! Construct empty table. + explicit concurrent_hash_map( const allocator_type &a = allocator_type() ) + : internal::hash_map_base(), my_allocator(a) + {} + + explicit concurrent_hash_map( const HashCompare& compare, const allocator_type& a = allocator_type() ) + : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare) + {} + + //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level. + concurrent_hash_map( size_type n, const allocator_type &a = allocator_type() ) + : internal::hash_map_base(), my_allocator(a) + { + reserve( n, my_allocator ); + } + + concurrent_hash_map( size_type n, const HashCompare& compare, const allocator_type& a = allocator_type() ) + : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare) + { + reserve( n, my_allocator ); + } + + //! Copy constructor + concurrent_hash_map( const concurrent_hash_map &table ) + : internal::hash_map_base(), + my_allocator(node_allocator_traits::select_on_container_copy_construction(table.get_allocator())) + { + call_clear_on_leave scope_guard(this); + internal_copy(table); + scope_guard.dismiss(); + } + + concurrent_hash_map( const concurrent_hash_map &table, const allocator_type &a) + : internal::hash_map_base(), my_allocator(a) + { + call_clear_on_leave scope_guard(this); + internal_copy(table); + scope_guard.dismiss(); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move constructor + concurrent_hash_map( concurrent_hash_map &&table ) + : internal::hash_map_base(), my_allocator(std::move(table.get_allocator())) + { + internal_move(std::move(table)); + } + + //! Move constructor + concurrent_hash_map( concurrent_hash_map &&table, const allocator_type &a ) + : internal::hash_map_base(), my_allocator(a) + { + if (a == table.get_allocator()){ + internal_move(std::move(table)); + }else{ + call_clear_on_leave scope_guard(this); + internal_copy(std::make_move_iterator(table.begin()), std::make_move_iterator(table.end()), table.size()); + scope_guard.dismiss(); + } + } +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + + //! Construction with copying iteration range and given allocator instance + template + concurrent_hash_map( I first, I last, const allocator_type &a = allocator_type() ) + : internal::hash_map_base(), my_allocator(a) + { + call_clear_on_leave scope_guard(this); + internal_copy(first, last, std::distance(first, last)); + scope_guard.dismiss(); + } + + template + concurrent_hash_map( I first, I last, const HashCompare& compare, const allocator_type& a = allocator_type() ) + : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare) + { + call_clear_on_leave scope_guard(this); + internal_copy(first, last, std::distance(first, last)); + scope_guard.dismiss(); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level. + concurrent_hash_map( std::initializer_list il, const allocator_type &a = allocator_type() ) + : internal::hash_map_base(), my_allocator(a) + { + call_clear_on_leave scope_guard(this); + internal_copy(il.begin(), il.end(), il.size()); + scope_guard.dismiss(); + } + + concurrent_hash_map( std::initializer_list il, const HashCompare& compare, const allocator_type& a = allocator_type() ) + : internal::hash_map_base(), my_allocator(a), my_hash_compare(compare) + { + call_clear_on_leave scope_guard(this); + internal_copy(il.begin(), il.end(), il.size()); + scope_guard.dismiss(); + } + +#endif //__TBB_INITIALIZER_LISTS_PRESENT + + //! Assignment + concurrent_hash_map& operator=( const concurrent_hash_map &table ) { + if( this!=&table ) { + typedef typename node_allocator_traits::propagate_on_container_copy_assignment pocca_type; + clear(); + tbb::internal::allocator_copy_assignment(my_allocator, table.my_allocator, pocca_type()); + internal_copy(table); + } + return *this; + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move Assignment + concurrent_hash_map& operator=( concurrent_hash_map &&table ) { + if(this != &table) { + typedef typename node_allocator_traits::propagate_on_container_move_assignment pocma_type; + internal_move_assign(std::move(table), pocma_type()); + } + return *this; + } +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Assignment + concurrent_hash_map& operator=( std::initializer_list il ) { + clear(); + internal_copy(il.begin(), il.end(), il.size()); + return *this; + } +#endif //__TBB_INITIALIZER_LISTS_PRESENT + + + //! Rehashes and optionally resizes the whole table. + /** Useful to optimize performance before or after concurrent operations. + Also enables using of find() and count() concurrent methods in serial context. */ + void rehash(size_type n = 0); + + //! Clear table + void clear(); + + //! Clear table and destroy it. + ~concurrent_hash_map() { clear(); } + + //------------------------------------------------------------------------ + // Parallel algorithm support + //------------------------------------------------------------------------ + range_type range( size_type grainsize=1 ) { + return range_type( *this, grainsize ); + } + const_range_type range( size_type grainsize=1 ) const { + return const_range_type( *this, grainsize ); + } + + //------------------------------------------------------------------------ + // STL support - not thread-safe methods + //------------------------------------------------------------------------ + iterator begin() { return iterator( *this, 0, my_embedded_segment, my_embedded_segment->node_list ); } + iterator end() { return iterator( *this, 0, 0, 0 ); } + const_iterator begin() const { return const_iterator( *this, 0, my_embedded_segment, my_embedded_segment->node_list ); } + const_iterator end() const { return const_iterator( *this, 0, 0, 0 ); } + std::pair equal_range( const Key& key ) { return internal_equal_range( key, end() ); } + std::pair equal_range( const Key& key ) const { return internal_equal_range( key, end() ); } + + //! Number of items in table. + size_type size() const { return my_size; } + + //! True if size()==0. + bool empty() const { return my_size == 0; } + + //! Upper bound on size. + size_type max_size() const {return (~size_type(0))/sizeof(node);} + + //! Returns the current number of buckets + size_type bucket_count() const { return my_mask+1; } + + //! return allocator object + allocator_type get_allocator() const { return this->my_allocator; } + + //! swap two instances. Iterators are invalidated + void swap( concurrent_hash_map &table ); + + //------------------------------------------------------------------------ + // concurrent map operations + //------------------------------------------------------------------------ + + //! Return count of items (0 or 1) + size_type count( const Key &key ) const { + return const_cast(this)->lookup(/*insert*/false, key, NULL, NULL, /*write=*/false, &do_not_allocate_node ); + } + + //! Find item and acquire a read lock on the item. + /** Return true if item is found, false otherwise. */ + bool find( const_accessor &result, const Key &key ) const { + result.release(); + return const_cast(this)->lookup(/*insert*/false, key, NULL, &result, /*write=*/false, &do_not_allocate_node ); + } + + //! Find item and acquire a write lock on the item. + /** Return true if item is found, false otherwise. */ + bool find( accessor &result, const Key &key ) { + result.release(); + return lookup(/*insert*/false, key, NULL, &result, /*write=*/true, &do_not_allocate_node ); + } + + //! Insert item (if not already present) and acquire a read lock on the item. + /** Returns true if item is new. */ + bool insert( const_accessor &result, const Key &key ) { + result.release(); + return lookup(/*insert*/true, key, NULL, &result, /*write=*/false, &allocate_node_default_construct ); + } + + //! Insert item (if not already present) and acquire a write lock on the item. + /** Returns true if item is new. */ + bool insert( accessor &result, const Key &key ) { + result.release(); + return lookup(/*insert*/true, key, NULL, &result, /*write=*/true, &allocate_node_default_construct ); + } + + //! Insert item by copying if there is no such key present already and acquire a read lock on the item. + /** Returns true if item is new. */ + bool insert( const_accessor &result, const value_type &value ) { + result.release(); + return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/false, &allocate_node_copy_construct ); + } + + //! Insert item by copying if there is no such key present already and acquire a write lock on the item. + /** Returns true if item is new. */ + bool insert( accessor &result, const value_type &value ) { + result.release(); + return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/true, &allocate_node_copy_construct ); + } + + //! Insert item by copying if there is no such key present already + /** Returns true if item is inserted. */ + bool insert( const value_type &value ) { + return lookup(/*insert*/true, value.first, &value.second, NULL, /*write=*/false, &allocate_node_copy_construct ); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Insert item by copying if there is no such key present already and acquire a read lock on the item. + /** Returns true if item is new. */ + bool insert( const_accessor &result, value_type && value ) { + return generic_move_insert(result, std::move(value)); + } + + //! Insert item by copying if there is no such key present already and acquire a write lock on the item. + /** Returns true if item is new. */ + bool insert( accessor &result, value_type && value ) { + return generic_move_insert(result, std::move(value)); + } + + //! Insert item by copying if there is no such key present already + /** Returns true if item is inserted. */ + bool insert( value_type && value ) { + return generic_move_insert(accessor_not_used(), std::move(value)); + } + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + //! Insert item by copying if there is no such key present already and acquire a read lock on the item. + /** Returns true if item is new. */ + template + bool emplace( const_accessor &result, Args&&... args ) { + return generic_emplace(result, std::forward(args)...); + } + + //! Insert item by copying if there is no such key present already and acquire a write lock on the item. + /** Returns true if item is new. */ + template + bool emplace( accessor &result, Args&&... args ) { + return generic_emplace(result, std::forward(args)...); + } + + //! Insert item by copying if there is no such key present already + /** Returns true if item is inserted. */ + template + bool emplace( Args&&... args ) { + return generic_emplace(accessor_not_used(), std::forward(args)...); + } +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + + //! Insert range [first, last) + template + void insert( I first, I last ) { + for ( ; first != last; ++first ) + insert( *first ); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Insert initializer list + void insert( std::initializer_list il ) { + insert( il.begin(), il.end() ); + } +#endif //__TBB_INITIALIZER_LISTS_PRESENT + + //! Erase item. + /** Return true if item was erased by particularly this call. */ + bool erase( const Key& key ); + + //! Erase item by const_accessor. + /** Return true if item was erased by particularly this call. */ + bool erase( const_accessor& item_accessor ) { + return exclude( item_accessor ); + } + + //! Erase item by accessor. + /** Return true if item was erased by particularly this call. */ + bool erase( accessor& item_accessor ) { + return exclude( item_accessor ); + } + +protected: + //! Insert or find item and optionally acquire a lock on the item. + bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node* (*allocate_node)(node_allocator_type& , const Key &, const T * ), node *tmp_n = 0 ) ; + + struct accessor_not_used { void release(){}}; + friend const_accessor* accessor_location( accessor_not_used const& ){ return NULL;} + friend const_accessor* accessor_location( const_accessor & a ) { return &a;} + + friend bool is_write_access_needed( accessor const& ) { return true;} + friend bool is_write_access_needed( const_accessor const& ) { return false;} + friend bool is_write_access_needed( accessor_not_used const& ) { return false;} + +#if __TBB_CPP11_RVALUE_REF_PRESENT + template + bool generic_move_insert( Accessor && result, value_type && value ) { + result.release(); + return lookup(/*insert*/true, value.first, &value.second, accessor_location(result), is_write_access_needed(result), &allocate_node_move_construct ); + } + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template + bool generic_emplace( Accessor && result, Args &&... args ) { + result.release(); + node * node_ptr = create_node(my_allocator, std::forward(args)...); + return lookup(/*insert*/true, node_ptr->value().first, NULL, accessor_location(result), is_write_access_needed(result), &do_not_allocate_node, node_ptr ); + } +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + + //! delete item by accessor + bool exclude( const_accessor &item_accessor ); + + //! Returns an iterator for an item defined by the key, or for the next item after it (if upper==true) + template + std::pair internal_equal_range( const Key& key, I end ) const; + + //! Copy "source" to *this, where *this must start out empty. + void internal_copy( const concurrent_hash_map& source ); + + template + void internal_copy( I first, I last, size_type reserve_size ); + +#if __TBB_CPP11_RVALUE_REF_PRESENT + // A compile-time dispatch to allow move assignment of containers with non-movable value_type if POCMA is true_type + void internal_move_assign(concurrent_hash_map&& other, tbb::internal::traits_true_type) { + tbb::internal::allocator_move_assignment(my_allocator, other.my_allocator, tbb::internal::traits_true_type()); + internal_move(std::move(other)); + } + + void internal_move_assign(concurrent_hash_map&& other, tbb::internal::traits_false_type) { + if (this->my_allocator == other.my_allocator) { + internal_move(std::move(other)); + } else { + //do per element move + internal_copy(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()), other.size()); + } + } +#endif + + //! Fast find when no concurrent erasure is used. For internal use inside TBB only! + /** Return pointer to item with given key, or NULL if no such item exists. + Must not be called concurrently with erasure operations. */ + const_pointer internal_fast_find( const Key& key ) const { + hashcode_t h = my_hash_compare.hash( key ); + hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); + node *n; + restart: + __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); + bucket *b = get_bucket( h & m ); + // TODO: actually, notification is unnecessary here, just hiding double-check + if( itt_load_word_with_acquire(b->node_list) == internal::rehash_req ) + { + bucket::scoped_t lock; + if( lock.try_acquire( b->mutex, /*write=*/true ) ) { + if( b->node_list == internal::rehash_req) + const_cast(this)->rehash_bucket( b, h & m ); //recursive rehashing + } + else lock.acquire( b->mutex, /*write=*/false ); + __TBB_ASSERT(b->node_list!=internal::rehash_req,NULL); + } + n = search_bucket( key, b ); + if( n ) + return n->storage(); + else if( check_mask_race( h, m ) ) + goto restart; + return 0; + } +}; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +namespace internal { +using namespace tbb::internal; + +template typename Map, typename Key, typename T, typename... Args> +using hash_map_t = Map< + Key, T, + std::conditional_t< (sizeof...(Args)>0) && !is_allocator_v< pack_element_t<0, Args...> >, + pack_element_t<0, Args...>, tbb_hash_compare >, + std::conditional_t< (sizeof...(Args)>0) && is_allocator_v< pack_element_t >, + pack_element_t, tbb_allocator > > +>; +} + +// Deduction guide for the constructor from two iterators and hash_compare/ allocator +template +concurrent_hash_map(I, I, Args...) +-> internal::hash_map_t,internal::iterator_mapped_t, Args...>; + +// Deduction guide for the constructor from an initializer_list and hash_compare/ allocator +// Deduction guide for an initializer_list, hash_compare and allocator is implicit +template +concurrent_hash_map(std::initializer_list>, CompareOrAllocator) +-> internal::hash_map_t; + +#endif /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ + +template +bool concurrent_hash_map::lookup( bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node* (*allocate_node)(node_allocator_type& , const Key&, const T*), node *tmp_n ) { + __TBB_ASSERT( !result || !result->my_node, NULL ); + bool return_value; + hashcode_t const h = my_hash_compare.hash( key ); + hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); + segment_index_t grow_segment = 0; + node *n; + restart: + {//lock scope + __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); + return_value = false; + // get bucket + bucket_accessor b( this, h & m ); + + // find a node + n = search_bucket( key, b() ); + if( op_insert ) { + // [opt] insert a key + if( !n ) { + if( !tmp_n ) { + tmp_n = allocate_node(my_allocator, key, t); + } + if( !b.is_writer() && !b.upgrade_to_writer() ) { // TODO: improved insertion + // Rerun search_list, in case another thread inserted the item during the upgrade. + n = search_bucket( key, b() ); + if( is_valid(n) ) { // unfortunately, it did + b.downgrade_to_reader(); + goto exists; + } + } + if( check_mask_race(h, m) ) + goto restart; // b.release() is done in ~b(). + // insert and set flag to grow the container + grow_segment = insert_new_node( b(), n = tmp_n, m ); + tmp_n = 0; + return_value = true; + } + } else { // find or count + if( !n ) { + if( check_mask_race( h, m ) ) + goto restart; // b.release() is done in ~b(). TODO: replace by continue + return false; + } + return_value = true; + } + exists: + if( !result ) goto check_growth; + // TODO: the following seems as generic/regular operation + // acquire the item + if( !result->try_acquire( n->mutex, write ) ) { + for( tbb::internal::atomic_backoff backoff(true);; ) { + if( result->try_acquire( n->mutex, write ) ) break; + if( !backoff.bounded_pause() ) { + // the wait takes really long, restart the operation + b.release(); + __TBB_ASSERT( !op_insert || !return_value, "Can't acquire new item in locked bucket?" ); + __TBB_Yield(); + m = (hashcode_t) itt_load_word_with_acquire( my_mask ); + goto restart; + } + } + } + }//lock scope + result->my_node = n; + result->my_hash = h; +check_growth: + // [opt] grow the container + if( grow_segment ) { +#if __TBB_STATISTICS + my_info_resizes++; // concurrent ones +#endif + enable_segment( grow_segment, my_allocator ); + } + if( tmp_n ) // if op_insert only + delete_node( tmp_n ); + return return_value; +} + +template +template +std::pair concurrent_hash_map::internal_equal_range( const Key& key, I end_ ) const { + hashcode_t h = my_hash_compare.hash( key ); + hashcode_t m = my_mask; + __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); + h &= m; + bucket *b = get_bucket( h ); + while( b->node_list == internal::rehash_req ) { + m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit + b = get_bucket( h &= m ); + } + node *n = search_bucket( key, b ); + if( !n ) + return std::make_pair(end_, end_); + iterator lower(*this, h, b, n), upper(lower); + return std::make_pair(lower, ++upper); +} + +template +bool concurrent_hash_map::exclude( const_accessor &item_accessor ) { + __TBB_ASSERT( item_accessor.my_node, NULL ); + node_base *const n = item_accessor.my_node; + hashcode_t const h = item_accessor.my_hash; + hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); + do { + // get bucket + bucket_accessor b( this, h & m, /*writer=*/true ); + node_base **p = &b()->node_list; + while( *p && *p != n ) + p = &(*p)->next; + if( !*p ) { // someone else was first + if( check_mask_race( h, m ) ) + continue; + item_accessor.release(); + return false; + } + __TBB_ASSERT( *p == n, NULL ); + *p = n->next; // remove from container + my_size--; + break; + } while(true); + if( !item_accessor.is_writer() ) // need to get exclusive lock + item_accessor.upgrade_to_writer(); // return value means nothing here + item_accessor.release(); + delete_node( n ); // Only one thread can delete it + return true; +} + +template +bool concurrent_hash_map::erase( const Key &key ) { + node_base *n; + hashcode_t const h = my_hash_compare.hash( key ); + hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask ); +restart: + {//lock scope + // get bucket + bucket_accessor b( this, h & m ); + search: + node_base **p = &b()->node_list; + n = *p; + while( is_valid(n) && !my_hash_compare.equal(key, static_cast(n)->value().first ) ) { + p = &n->next; + n = *p; + } + if( !n ) { // not found, but mask could be changed + if( check_mask_race( h, m ) ) + goto restart; + return false; + } + else if( !b.is_writer() && !b.upgrade_to_writer() ) { + if( check_mask_race( h, m ) ) // contended upgrade, check mask + goto restart; + goto search; + } + *p = n->next; + my_size--; + } + { + typename node::scoped_t item_locker( n->mutex, /*write=*/true ); + } + // note: there should be no threads pretending to acquire this mutex again, do not try to upgrade const_accessor! + delete_node( n ); // Only one thread can delete it due to write lock on the bucket + return true; +} + +template +void concurrent_hash_map::swap(concurrent_hash_map &table) { + typedef typename node_allocator_traits::propagate_on_container_swap pocs_type; + if (this != &table && (pocs_type::value || my_allocator == table.my_allocator)) { + using std::swap; + tbb::internal::allocator_swap(this->my_allocator, table.my_allocator, pocs_type()); + swap(this->my_hash_compare, table.my_hash_compare); + internal_swap(table); + } +} + +template +void concurrent_hash_map::rehash(size_type sz) { + reserve( sz, my_allocator ); // TODO: add reduction of number of buckets as well + hashcode_t mask = my_mask; + hashcode_t b = (mask+1)>>1; // size or first index of the last segment + __TBB_ASSERT((b&(b-1))==0, NULL); // zero or power of 2 + bucket *bp = get_bucket( b ); // only the last segment should be scanned for rehashing + for(; b <= mask; b++, bp++ ) { + node_base *n = bp->node_list; + __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" ); + __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" ); + if( n == internal::rehash_req ) { // rehash bucket, conditional because rehashing of a previous bucket may affect this one + hashcode_t h = b; bucket *b_old = bp; + do { + __TBB_ASSERT( h > 1, "The lowermost buckets can't be rehashed" ); + hashcode_t m = ( 1u<<__TBB_Log2( h ) ) - 1; // get parent mask from the topmost bit + b_old = get_bucket( h &= m ); + } while( b_old->node_list == internal::rehash_req ); + // now h - is index of the root rehashed bucket b_old + mark_rehashed_levels( h ); // mark all non-rehashed children recursively across all segments + for( node_base **p = &b_old->node_list, *q = *p; is_valid(q); q = *p ) { + hashcode_t c = my_hash_compare.hash( static_cast(q)->value().first ); + if( (c & mask) != h ) { // should be rehashed + *p = q->next; // exclude from b_old + bucket *b_new = get_bucket( c & mask ); + __TBB_ASSERT( b_new->node_list != internal::rehash_req, "hash() function changed for key in table or internal error" ); + add_to_bucket( b_new, q ); + } else p = &q->next; // iterate to next item + } + } + } +#if TBB_USE_PERFORMANCE_WARNINGS + int current_size = int(my_size), buckets = int(mask)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics + static bool reported = false; +#endif +#if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS + for( b = 0; b <= mask; b++ ) {// only last segment should be scanned for rehashing + if( b & (b-2) ) ++bp; // not the beginning of a segment + else bp = get_bucket( b ); + node_base *n = bp->node_list; + __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during rehash() execution" ); + __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed, "Broken internal structure" ); +#if TBB_USE_PERFORMANCE_WARNINGS + if( n == internal::empty_rehashed ) empty_buckets++; + else if( n->next ) overpopulated_buckets++; +#endif +#if TBB_USE_ASSERT + for( ; is_valid(n); n = n->next ) { + hashcode_t h = my_hash_compare.hash( static_cast(n)->value().first ) & mask; + __TBB_ASSERT( h == b, "hash() function changed for key in table or internal error" ); + } +#endif + } +#endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS +#if TBB_USE_PERFORMANCE_WARNINGS + if( buckets > current_size) empty_buckets -= buckets - current_size; + else overpopulated_buckets -= current_size - buckets; // TODO: load_factor? + if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) { + tbb::internal::runtime_warning( + "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d", +#if __TBB_USE_OPTIONAL_RTTI + typeid(*this).name(), +#else + "concurrent_hash_map", +#endif + current_size, empty_buckets, overpopulated_buckets ); + reported = true; + } +#endif +} + +template +void concurrent_hash_map::clear() { + hashcode_t m = my_mask; + __TBB_ASSERT((m&(m+1))==0, "data structure is invalid"); +#if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS +#if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS + int current_size = int(my_size), buckets = int(m)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics + static bool reported = false; +#endif + bucket *bp = 0; + // check consistency + for( segment_index_t b = 0; b <= m; b++ ) { + if( b & (b-2) ) ++bp; // not the beginning of a segment + else bp = get_bucket( b ); + node_base *n = bp->node_list; + __TBB_ASSERT( is_valid(n) || n == internal::empty_rehashed || n == internal::rehash_req, "Broken internal structure" ); + __TBB_ASSERT( *reinterpret_cast(&bp->mutex) == 0, "concurrent or unexpectedly terminated operation during clear() execution" ); +#if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS + if( n == internal::empty_rehashed ) empty_buckets++; + else if( n == internal::rehash_req ) buckets--; + else if( n->next ) overpopulated_buckets++; +#endif +#if __TBB_EXTRA_DEBUG + for(; is_valid(n); n = n->next ) { + hashcode_t h = my_hash_compare.hash( static_cast(n)->value().first ); + h &= m; + __TBB_ASSERT( h == b || get_bucket(h)->node_list == internal::rehash_req, "hash() function changed for key in table or internal error" ); + } +#endif + } +#if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS +#if __TBB_STATISTICS + printf( "items=%d buckets: capacity=%d rehashed=%d empty=%d overpopulated=%d" + " concurrent: resizes=%u rehashes=%u restarts=%u\n", + current_size, int(m+1), buckets, empty_buckets, overpopulated_buckets, + unsigned(my_info_resizes), unsigned(my_info_rehashes), unsigned(my_info_restarts) ); + my_info_resizes = 0; // concurrent ones + my_info_restarts = 0; // race collisions + my_info_rehashes = 0; // invocations of rehash_bucket +#endif + if( buckets > current_size) empty_buckets -= buckets - current_size; + else overpopulated_buckets -= current_size - buckets; // TODO: load_factor? + if( !reported && buckets >= 512 && ( 2*empty_buckets > current_size || 2*overpopulated_buckets > current_size ) ) { + tbb::internal::runtime_warning( + "Performance is not optimal because the hash function produces bad randomness in lower bits in %s.\nSize: %d Empties: %d Overlaps: %d", +#if __TBB_USE_OPTIONAL_RTTI + typeid(*this).name(), +#else + "concurrent_hash_map", +#endif + current_size, empty_buckets, overpopulated_buckets ); + reported = true; + } +#endif +#endif // TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS + my_size = 0; + segment_index_t s = segment_index_of( m ); + __TBB_ASSERT( s+1 == pointers_per_table || !my_table[s+1], "wrong mask or concurrent grow" ); + do { + __TBB_ASSERT( is_valid( my_table[s] ), "wrong mask or concurrent grow" ); + segment_ptr_t buckets_ptr = my_table[s]; + size_type sz = segment_size( s ? s : 1 ); + for( segment_index_t i = 0; i < sz; i++ ) + for( node_base *n = buckets_ptr[i].node_list; is_valid(n); n = buckets_ptr[i].node_list ) { + buckets_ptr[i].node_list = n->next; + delete_node( n ); + } + delete_segment(s, my_allocator); + } while(s-- > 0); + my_mask = embedded_buckets - 1; +} + +template +void concurrent_hash_map::internal_copy( const concurrent_hash_map& source ) { + hashcode_t mask = source.my_mask; + if( my_mask == mask ) { // optimized version + reserve( source.my_size, my_allocator ); // TODO: load_factor? + bucket *dst = 0, *src = 0; + bool rehash_required = false; + for( hashcode_t k = 0; k <= mask; k++ ) { + if( k & (k-2) ) ++dst,src++; // not the beginning of a segment + else { dst = get_bucket( k ); src = source.get_bucket( k ); } + __TBB_ASSERT( dst->node_list != internal::rehash_req, "Invalid bucket in destination table"); + node *n = static_cast( src->node_list ); + if( n == internal::rehash_req ) { // source is not rehashed, items are in previous buckets + rehash_required = true; + dst->node_list = internal::rehash_req; + } else for(; n; n = static_cast( n->next ) ) { + node* node_ptr = create_node(my_allocator, n->value().first, n->value().second); + add_to_bucket( dst, node_ptr); + ++my_size; // TODO: replace by non-atomic op + } + } + if( rehash_required ) rehash(); + } else internal_copy( source.begin(), source.end(), source.my_size ); +} + +template +template +void concurrent_hash_map::internal_copy(I first, I last, size_type reserve_size) { + reserve( reserve_size, my_allocator ); // TODO: load_factor? + hashcode_t m = my_mask; + for(; first != last; ++first) { + hashcode_t h = my_hash_compare.hash( (*first).first ); + bucket *b = get_bucket( h & m ); + __TBB_ASSERT( b->node_list != internal::rehash_req, "Invalid bucket in destination table"); + node* node_ptr = create_node(my_allocator, (*first).first, (*first).second); + add_to_bucket( b, node_ptr ); + ++my_size; // TODO: replace by non-atomic op + } +} + +} // namespace interface5 + +using interface5::concurrent_hash_map; + + +template +inline bool operator==(const concurrent_hash_map &a, const concurrent_hash_map &b) { + if(a.size() != b.size()) return false; + typename concurrent_hash_map::const_iterator i(a.begin()), i_end(a.end()); + typename concurrent_hash_map::const_iterator j, j_end(b.end()); + for(; i != i_end; ++i) { + j = b.equal_range(i->first).first; + if( j == j_end || !(i->second == j->second) ) return false; + } + return true; +} + +template +inline bool operator!=(const concurrent_hash_map &a, const concurrent_hash_map &b) +{ return !(a == b); } + +template +inline void swap(concurrent_hash_map &a, concurrent_hash_map &b) +{ a.swap( b ); } + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning( pop ) +#endif // warning 4127 is back + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_concurrent_hash_map_H_include_area + +#endif /* __TBB_concurrent_hash_map_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_lru_cache.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_lru_cache.h new file mode 100644 index 00000000..a18dbf29 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_lru_cache.h @@ -0,0 +1,290 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_lru_cache_H +#define __TBB_concurrent_lru_cache_H + +#define __TBB_concurrent_lru_cache_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#if ! TBB_PREVIEW_CONCURRENT_LRU_CACHE + #error Set TBB_PREVIEW_CONCURRENT_LRU_CACHE to include concurrent_lru_cache.h +#endif + +#include "tbb_stddef.h" + +#include +#include +#include // std::find +#if __TBB_CPP11_RVALUE_REF_PRESENT +#include // std::move +#endif + +#include "atomic.h" +#include "internal/_aggregator_impl.h" + +namespace tbb{ +namespace interface6 { + + +template +class concurrent_lru_cache : internal::no_assign{ +private: + typedef concurrent_lru_cache self_type; + typedef value_functor_type value_function_type; + typedef std::size_t ref_counter_type; + struct map_value_type; + typedef std::map map_storage_type; + typedef std::list lru_list_type; + struct map_value_type { + value_type my_value; + ref_counter_type my_ref_counter; + typename lru_list_type::iterator my_lru_list_iterator; + bool my_is_ready; + + map_value_type (value_type const& a_value, ref_counter_type a_ref_counter, typename lru_list_type::iterator a_lru_list_iterator, bool a_is_ready) + : my_value(a_value), my_ref_counter(a_ref_counter), my_lru_list_iterator (a_lru_list_iterator), my_is_ready(a_is_ready) + {} + }; + + class handle_object; + + struct aggregator_operation; + typedef aggregator_operation aggregated_operation_type; + typedef tbb::internal::aggregating_functor aggregator_function_type; + friend class tbb::internal::aggregating_functor; + typedef tbb::internal::aggregator aggregator_type; + +private: + value_function_type my_value_function; + std::size_t const my_number_of_lru_history_items; + map_storage_type my_map_storage; + lru_list_type my_lru_list; + aggregator_type my_aggregator; + +public: + typedef handle_object handle; + +public: + concurrent_lru_cache(value_function_type f, std::size_t number_of_lru_history_items) + : my_value_function(f),my_number_of_lru_history_items(number_of_lru_history_items) + { + my_aggregator.initialize_handler(aggregator_function_type(this)); + } + + handle_object operator[](key_type k){ + retrieve_aggregator_operation op(k); + my_aggregator.execute(&op); + if (op.is_new_value_needed()){ + op.result().second.my_value = my_value_function(k); + __TBB_store_with_release(op.result().second.my_is_ready, true); + }else{ + tbb::internal::spin_wait_while_eq(op.result().second.my_is_ready,false); + } + return handle_object(*this,op.result()); + } +private: + void signal_end_of_usage(typename map_storage_type::reference value_ref){ + signal_end_of_usage_aggregator_operation op(value_ref); + my_aggregator.execute(&op); + } + +private: +#if !__TBB_CPP11_RVALUE_REF_PRESENT + struct handle_move_t:no_assign{ + concurrent_lru_cache & my_cache_ref; + typename map_storage_type::reference my_map_record_ref; + handle_move_t(concurrent_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_ref(cache_ref),my_map_record_ref(value_ref) {}; + }; +#endif + class handle_object { + concurrent_lru_cache * my_cache_pointer; + typename map_storage_type::pointer my_map_record_ptr; + public: + handle_object() : my_cache_pointer(), my_map_record_ptr() {} + handle_object(concurrent_lru_cache& cache_ref, typename map_storage_type::reference value_ref) : my_cache_pointer(&cache_ref), my_map_record_ptr(&value_ref) {} + operator bool() const { + return (my_cache_pointer && my_map_record_ptr); + } +#if __TBB_CPP11_RVALUE_REF_PRESENT + // TODO: add check for double moved objects by special dedicated field + handle_object(handle_object&& src) : my_cache_pointer(src.my_cache_pointer), my_map_record_ptr(src.my_map_record_ptr) { + __TBB_ASSERT((src.my_cache_pointer && src.my_map_record_ptr) || (!src.my_cache_pointer && !src.my_map_record_ptr), "invalid state of moving object?"); + src.my_cache_pointer = NULL; + src.my_map_record_ptr = NULL; + } + handle_object& operator=(handle_object&& src) { + __TBB_ASSERT((src.my_cache_pointer && src.my_map_record_ptr) || (!src.my_cache_pointer && !src.my_map_record_ptr), "invalid state of moving object?"); + if (my_cache_pointer) { + my_cache_pointer->signal_end_of_usage(*my_map_record_ptr); + } + my_cache_pointer = src.my_cache_pointer; + my_map_record_ptr = src.my_map_record_ptr; + src.my_cache_pointer = NULL; + src.my_map_record_ptr = NULL; + return *this; + } +#else + handle_object(handle_move_t m) : my_cache_pointer(&m.my_cache_ref), my_map_record_ptr(&m.my_map_record_ref) {} + handle_object& operator=(handle_move_t m) { + if (my_cache_pointer) { + my_cache_pointer->signal_end_of_usage(*my_map_record_ptr); + } + my_cache_pointer = &m.my_cache_ref; + my_map_record_ptr = &m.my_map_record_ref; + return *this; + } + operator handle_move_t(){ + return move(*this); + } +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + value_type& value(){ + __TBB_ASSERT(my_cache_pointer,"get value from already moved object?"); + __TBB_ASSERT(my_map_record_ptr,"get value from an invalid or already moved object?"); + return my_map_record_ptr->second.my_value; + } + ~handle_object(){ + if (my_cache_pointer){ + my_cache_pointer->signal_end_of_usage(*my_map_record_ptr); + } + } + private: +#if __TBB_CPP11_RVALUE_REF_PRESENT + // For source compatibility with C++03 + friend handle_object&& move(handle_object& h){ + return std::move(h); + } +#else + friend handle_move_t move(handle_object& h){ + return handle_object::move(h); + } + // TODO: add check for double moved objects by special dedicated field + static handle_move_t move(handle_object& h){ + __TBB_ASSERT((h.my_cache_pointer && h.my_map_record_ptr) || (!h.my_cache_pointer && !h.my_map_record_ptr), "invalid state of moving object?"); + concurrent_lru_cache * cache_pointer = h.my_cache_pointer; + typename map_storage_type::pointer map_record_ptr = h.my_map_record_ptr; + h.my_cache_pointer = NULL; + h.my_map_record_ptr = NULL; + return handle_move_t(*cache_pointer, *map_record_ptr); + } +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + private: + void operator=(handle_object&); +#if __SUNPRO_CC + // Presumably due to a compiler error, private copy constructor + // breaks expressions like handle h = cache[key]; + public: +#endif + handle_object(handle_object &); + }; +private: + //TODO: looks like aggregator_operation is a perfect match for statically typed variant type + struct aggregator_operation : tbb::internal::aggregated_operation{ + enum e_op_type {op_retive, op_signal_end_of_usage}; + //TODO: try to use pointer to function apply_visitor here + //TODO: try virtual functions and measure the difference + e_op_type my_operation_type; + aggregator_operation(e_op_type operation_type): my_operation_type(operation_type) {} + void cast_and_handle(self_type& container ){ + if (my_operation_type==op_retive){ + static_cast(this)->handle(container); + }else{ + static_cast(this)->handle(container); + } + } + }; + struct retrieve_aggregator_operation : aggregator_operation, private internal::no_assign { + key_type my_key; + typename map_storage_type::pointer my_result_map_record_pointer; + bool my_is_new_value_needed; + retrieve_aggregator_operation(key_type key):aggregator_operation(aggregator_operation::op_retive),my_key(key),my_is_new_value_needed(false){} + void handle(self_type& container ){ + my_result_map_record_pointer = & container.retrieve_serial(my_key,my_is_new_value_needed); + } + typename map_storage_type::reference result(){ return * my_result_map_record_pointer; } + bool is_new_value_needed(){return my_is_new_value_needed;} + }; + struct signal_end_of_usage_aggregator_operation : aggregator_operation, private internal::no_assign { + typename map_storage_type::reference my_map_record_ref; + signal_end_of_usage_aggregator_operation(typename map_storage_type::reference map_record_ref):aggregator_operation(aggregator_operation::op_signal_end_of_usage),my_map_record_ref(map_record_ref){} + void handle(self_type& container ){ + container.signal_end_of_usage_serial(my_map_record_ref); + } + }; + +private: + void handle_operations(aggregator_operation* op_list){ + while(op_list){ + op_list->cast_and_handle(*this); + aggregator_operation* tmp = op_list; + op_list=op_list->next; + tbb::internal::itt_store_word_with_release(tmp->status, uintptr_t(1)); + } + } + +private: + typename map_storage_type::reference retrieve_serial(key_type k, bool& is_new_value_needed){ + typename map_storage_type::iterator it = my_map_storage.find(k); + if (it == my_map_storage.end()){ + it = my_map_storage.insert(it,std::make_pair(k,map_value_type(value_type(),0,my_lru_list.end(),false))); + is_new_value_needed = true; + }else { + typename lru_list_type::iterator list_it = it->second.my_lru_list_iterator; + if (list_it!=my_lru_list.end()) { + __TBB_ASSERT(!it->second.my_ref_counter,"item to be evicted should not have a live references"); + //item is going to be used. Therefore it is not a subject for eviction + //so - remove it from LRU history. + my_lru_list.erase(list_it); + it->second.my_lru_list_iterator= my_lru_list.end(); + } + } + ++(it->second.my_ref_counter); + return *it; + } + + void signal_end_of_usage_serial(typename map_storage_type::reference map_record_ref){ + typename map_storage_type::iterator it = my_map_storage.find(map_record_ref.first); + __TBB_ASSERT(it!=my_map_storage.end(),"cache should not return past-end iterators to outer world"); + __TBB_ASSERT(&(*it) == &map_record_ref,"dangling reference has been returned to outside world? data race ?"); + __TBB_ASSERT( my_lru_list.end()== std::find(my_lru_list.begin(),my_lru_list.end(),it), + "object in use should not be in list of unused objects "); + if (! --(it->second.my_ref_counter)){ + //it was the last reference so put it to the LRU history + if (my_lru_list.size()>=my_number_of_lru_history_items){ + //evict items in order to get a space + size_t number_of_elements_to_evict = 1 + my_lru_list.size() - my_number_of_lru_history_items; + for (size_t i=0; isecond.my_ref_counter,"item to be evicted should not have a live references"); + my_lru_list.pop_back(); + my_map_storage.erase(it_to_evict); + } + } + my_lru_list.push_front(it); + it->second.my_lru_list_iterator = my_lru_list.begin(); + } + } +}; +} // namespace interface6 + +using interface6::concurrent_lru_cache; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_concurrent_lru_cache_H_include_area + +#endif //__TBB_concurrent_lru_cache_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_map.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_map.h new file mode 100644 index 00000000..32fbe684 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_map.h @@ -0,0 +1,389 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_map_H +#define __TBB_concurrent_map_H + +#define __TBB_concurrent_map_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#if !TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#error Set TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS to include concurrent_map.h +#endif + +#include "tbb_config.h" + +// concurrent_map requires C++11 support +#if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT + +#include "internal/_concurrent_skip_list_impl.h" + +namespace tbb { + +namespace interface10 { + +template +class map_traits { +public: + static constexpr size_t MAX_LEVEL = MAX_LEVELS; + using random_level_generator_type = RandomGenerator; + using key_type = Key; + using mapped_type = Value; + using compare_type = KeyCompare; + using value_type = std::pair; + using reference = value_type&; + using const_reference = const value_type&; + using allocator_type = Allocator; + using mutex_type = tbb::spin_mutex; + using node_type = tbb::internal::node_handle, allocator_type>; + + static const bool allow_multimapping = AllowMultimapping; + + class value_compare { + public: + // TODO: these member types are deprecated in C++17, do we need to let them + using result_type = bool; + using first_argument_type = value_type; + using second_argument_type = value_type; + + bool operator()(const value_type& lhs, const value_type& rhs) const { + return comp(lhs.first, rhs.first); + } + + protected: + value_compare(compare_type c) : comp(c) {} + + friend class map_traits; + + compare_type comp; + }; + + static value_compare value_comp(compare_type comp) { return value_compare(comp); } + + static const key_type& get_key(const_reference val) { + return val.first; + } +}; // class map_traits + +template +class concurrent_multimap; + +template , typename Allocator = tbb_allocator>> +class concurrent_map + : public internal::concurrent_skip_list, 64, Allocator, false>> { + using traits_type = map_traits, 64, Allocator, false>; + using base_type = internal::concurrent_skip_list; +#if __TBB_EXTRA_DEBUG +public: +#endif + using base_type::allow_multimapping; +public: + using key_type = Key; + using mapped_type = Value; + using value_type = typename traits_type::value_type; + using size_type = typename base_type::size_type; + using difference_type = typename base_type::difference_type; + using key_compare = Comp; + using value_compare = typename base_type::value_compare; + using allocator_type = Allocator; + + using reference = typename base_type::reference; + using const_reference = typename base_type::const_reference; + using pointer = typename base_type::pointer; + using const_pointer = typename base_type::pointer; + + using iterator = typename base_type::iterator; + using const_iterator = typename base_type::const_iterator; + using reverse_iterator = typename base_type::reverse_iterator; + using const_reverse_iterator = typename base_type::const_reverse_iterator; + + using node_type = typename base_type::node_type; + + using base_type::end; + using base_type::find; + using base_type::emplace; + using base_type::insert; + + concurrent_map() = default; + + explicit concurrent_map(const key_compare& comp, const allocator_type& alloc = allocator_type()) : base_type(comp, alloc) {} + + explicit concurrent_map(const allocator_type& alloc) : base_type(key_compare(), alloc) {} + + template< class InputIt > + concurrent_map(InputIt first, InputIt last, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type()) + : base_type(first, last, comp, alloc) {} + + template< class InputIt > + concurrent_map(InputIt first, InputIt last, const allocator_type& alloc) : base_type(first, last, key_compare(), alloc) {} + + /** Copy constructor */ + concurrent_map(const concurrent_map&) = default; + + concurrent_map(const concurrent_map& other, const allocator_type& alloc) : base_type(other, alloc) {} + + concurrent_map(concurrent_map&&) = default; + + concurrent_map(concurrent_map&& other, const allocator_type& alloc) : base_type(std::move(other), alloc) {} + + concurrent_map(std::initializer_list init, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type()) + : base_type(comp, alloc) { + insert(init); + } + + concurrent_map(std::initializer_list init, const allocator_type& alloc) + : base_type(key_compare(), alloc) { + insert(init); + } + + concurrent_map& operator=(const concurrent_map& other) { + return static_cast(base_type::operator=(other)); + } + + concurrent_map& operator=(concurrent_map&& other) { + return static_cast(base_type::operator=(std::move(other))); + } + + mapped_type& at(const key_type& key) { + iterator it = find(key); + + if (it == end()) { + tbb::internal::throw_exception(tbb::internal::eid_invalid_key); + } + + return it->second; + } + + const mapped_type& at(const key_type& key) const { + const_iterator it = find(key); + + if (it == end()) { + tbb::internal::throw_exception(tbb::internal::eid_invalid_key); + } + + return it->second; + } + + mapped_type& operator[](const key_type& key) { + iterator it = find(key); + + if (it == end()) { + it = emplace(std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>()).first; + } + + return it->second; + } + + mapped_type& operator[](key_type&& key) { + iterator it = find(key); + + if (it == end()) { + it = emplace(std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::tuple<>()).first; + } + + return it->second; + } + + template::value>::type> + std::pair insert(P&& value) { + return emplace(std::forward

(value)); + } + + template::value>::type> + iterator insert(const_iterator hint, P&& value) { + return emplace_hint(hint, std::forward

(value)); + return end(); + } + + template + void merge(concurrent_map& source) { + this->internal_merge(source); + } + + template + void merge(concurrent_map&& source) { + this->internal_merge(std::move(source)); + } + + template + void merge(concurrent_multimap& source) { + this->internal_merge(source); + } + + template + void merge(concurrent_multimap&& source) { + this->internal_merge(std::move(source)); + } +}; // class concurrent_map + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +namespace internal { + +using namespace tbb::internal; + +template typename Map, typename Key, typename T, typename... Args> +using c_map_t = Map 0) && !is_allocator_v >, + pack_element_t<0, Args...>, std::less >, + std::conditional_t< (sizeof...(Args) > 0) && is_allocator_v >, + pack_element_t, tbb_allocator > > >; +} // namespace internal + +template +concurrent_map(It, It, Args...) +-> internal::c_map_t, internal::iterator_mapped_t, Args...>; + +template +concurrent_map(std::initializer_list>, Args...) +-> internal::c_map_t; + +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +template , typename Allocator = tbb_allocator>> +class concurrent_multimap + : public internal::concurrent_skip_list, 64, Allocator, true>> { + using traits_type = map_traits, 64, Allocator, true>; + using base_type = internal::concurrent_skip_list; +#if __TBB_EXTRA_DEBUG +public: +#endif + using base_type::allow_multimapping; +public: + using key_type = Key; + using mapped_type = Value; + using value_type = typename traits_type::value_type; + using size_type = typename base_type::size_type; + using difference_type = typename base_type::difference_type; + using key_compare = Comp; + using value_compare = typename base_type::value_compare; + using allocator_type = Allocator; + + using reference = typename base_type::reference; + using const_reference = typename base_type::const_reference; + using pointer = typename base_type::pointer; + using const_pointer = typename base_type::pointer; + + using iterator = typename base_type::iterator; + using const_iterator = typename base_type::const_iterator; + using reverse_iterator = typename base_type::reverse_iterator; + using const_reverse_iterator = typename base_type::const_reverse_iterator; + + using node_type = typename base_type::node_type; + + using base_type::end; + using base_type::find; + using base_type::emplace; + using base_type::insert; + + concurrent_multimap() = default; + + explicit concurrent_multimap(const key_compare& comp, const allocator_type& alloc = allocator_type()) : base_type(comp, alloc) {} + + explicit concurrent_multimap(const allocator_type& alloc) : base_type(key_compare(), alloc) {} + + template< class InputIt > + concurrent_multimap(InputIt first, InputIt last, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type()) + : base_type(first, last, comp, alloc) {} + + template< class InputIt > + concurrent_multimap(InputIt first, InputIt last, const allocator_type& alloc) : base_type(first, last, key_compare(), alloc) {} + + /** Copy constructor */ + concurrent_multimap(const concurrent_multimap&) = default; + + concurrent_multimap(const concurrent_multimap& other, const allocator_type& alloc) : base_type(other, alloc) {} + + concurrent_multimap(concurrent_multimap&&) = default; + + concurrent_multimap(concurrent_multimap&& other, const allocator_type& alloc) : base_type(std::move(other), alloc) {} + + concurrent_multimap(std::initializer_list init, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type()) + : base_type(comp, alloc) { + insert(init); + } + + concurrent_multimap(std::initializer_list init, const allocator_type& alloc) + : base_type(key_compare(), alloc) { + insert(init); + } + + concurrent_multimap& operator=(const concurrent_multimap& other) { + return static_cast(base_type::operator=(other)); + } + + concurrent_multimap& operator=(concurrent_multimap&& other) { + return static_cast(base_type::operator=(std::move(other))); + } + + template::value>::type> + std::pair insert(P&& value) { + return emplace(std::forward

(value)); + } + + template::value>::type> + iterator insert(const_iterator hint, P&& value) { + return emplace_hint(hint, std::forward

(value)); + return end(); + } + + template + void merge(concurrent_multimap& source) { + this->internal_merge(source); + } + + template + void merge(concurrent_multimap&& source) { + this->internal_merge(std::move(source)); + } + + template + void merge(concurrent_map& source) { + this->internal_merge(source); + } + + template + void merge(concurrent_map&& source) { + this->internal_merge(std::move(source)); + } + +}; // class concurrent_multimap + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +template +concurrent_multimap(It, It, Args...) +-> internal::c_map_t, internal::iterator_mapped_t, Args...>; + +template +concurrent_multimap(std::initializer_list>, Args...) +-> internal::c_map_t; + +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +} // namespace interface10 + +using interface10::concurrent_map; +using interface10::concurrent_multimap; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_concurrent_map_H_include_area + +#endif // __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT +#endif // __TBB_concurrent_map_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_priority_queue.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_priority_queue.h new file mode 100644 index 00000000..9c70098b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_priority_queue.h @@ -0,0 +1,552 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_priority_queue_H +#define __TBB_concurrent_priority_queue_H + +#define __TBB_concurrent_priority_queue_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "atomic.h" +#include "cache_aligned_allocator.h" +#include "tbb_exception.h" +#include "tbb_stddef.h" +#include "tbb_profiling.h" +#include "internal/_aggregator_impl.h" +#include "internal/_template_helpers.h" +#include "internal/_allocator_traits.h" +#include +#include +#include +#include __TBB_STD_SWAP_HEADER + +#if __TBB_INITIALIZER_LISTS_PRESENT + #include +#endif + +#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT + #include +#endif + +namespace tbb { +namespace interface5 { +namespace internal { +#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT + template::value> + struct use_element_copy_constructor { + typedef tbb::internal::true_type type; + }; + template + struct use_element_copy_constructor { + typedef tbb::internal::false_type type; + }; +#else + template + struct use_element_copy_constructor { + typedef tbb::internal::true_type type; + }; +#endif +} // namespace internal + +using namespace tbb::internal; + +//! Concurrent priority queue +template , typename A=cache_aligned_allocator > +class concurrent_priority_queue { + public: + //! Element type in the queue. + typedef T value_type; + + //! Reference type + typedef T& reference; + + //! Const reference type + typedef const T& const_reference; + + //! Integral type for representing size of the queue. + typedef size_t size_type; + + //! Difference type for iterator + typedef ptrdiff_t difference_type; + + //! Allocator type + typedef A allocator_type; + + //! Constructs a new concurrent_priority_queue with default capacity + explicit concurrent_priority_queue(const allocator_type& a = allocator_type()) : mark(0), my_size(0), compare(), data(a) + { + my_aggregator.initialize_handler(my_functor_t(this)); + } + + //! Constructs a new concurrent_priority_queue with default capacity + explicit concurrent_priority_queue(const Compare& c, const allocator_type& a = allocator_type()) : mark(0), my_size(0), compare(c), data(a) + { + my_aggregator.initialize_handler(my_functor_t(this)); + } + + //! Constructs a new concurrent_priority_queue with init_sz capacity + explicit concurrent_priority_queue(size_type init_capacity, const allocator_type& a = allocator_type()) : + mark(0), my_size(0), compare(), data(a) + { + data.reserve(init_capacity); + my_aggregator.initialize_handler(my_functor_t(this)); + } + + //! Constructs a new concurrent_priority_queue with init_sz capacity + explicit concurrent_priority_queue(size_type init_capacity, const Compare& c, const allocator_type& a = allocator_type()) : + mark(0), my_size(0), compare(c), data(a) + { + data.reserve(init_capacity); + my_aggregator.initialize_handler(my_functor_t(this)); + } + + //! [begin,end) constructor + template + concurrent_priority_queue(InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) : + mark(0), compare(), data(begin, end, a) + { + my_aggregator.initialize_handler(my_functor_t(this)); + heapify(); + my_size = data.size(); + } + + //! [begin,end) constructor + template + concurrent_priority_queue(InputIterator begin, InputIterator end, const Compare& c, const allocator_type& a = allocator_type()) : + mark(0), compare(c), data(begin, end, a) + { + my_aggregator.initialize_handler(my_functor_t(this)); + heapify(); + my_size = data.size(); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Constructor from std::initializer_list + concurrent_priority_queue(std::initializer_list init_list, const allocator_type &a = allocator_type()) : + mark(0), compare(), data(init_list.begin(), init_list.end(), a) + { + my_aggregator.initialize_handler(my_functor_t(this)); + heapify(); + my_size = data.size(); + } + + //! Constructor from std::initializer_list + concurrent_priority_queue(std::initializer_list init_list, const Compare& c, const allocator_type &a = allocator_type()) : + mark(0), compare(c), data(init_list.begin(), init_list.end(), a) + { + my_aggregator.initialize_handler(my_functor_t(this)); + heapify(); + my_size = data.size(); + } +#endif //# __TBB_INITIALIZER_LISTS_PRESENT + + //! Copy constructor + /** This operation is unsafe if there are pending concurrent operations on the src queue. */ + concurrent_priority_queue(const concurrent_priority_queue& src) : mark(src.mark), + my_size(src.my_size), data(src.data.begin(), src.data.end(), src.data.get_allocator()) + { + my_aggregator.initialize_handler(my_functor_t(this)); + heapify(); + } + + //! Copy constructor with specific allocator + /** This operation is unsafe if there are pending concurrent operations on the src queue. */ + concurrent_priority_queue(const concurrent_priority_queue& src, const allocator_type& a) : mark(src.mark), + my_size(src.my_size), data(src.data.begin(), src.data.end(), a) + { + my_aggregator.initialize_handler(my_functor_t(this)); + heapify(); + } + + //! Assignment operator + /** This operation is unsafe if there are pending concurrent operations on the src queue. */ + concurrent_priority_queue& operator=(const concurrent_priority_queue& src) { + if (this != &src) { + vector_t(src.data.begin(), src.data.end(), src.data.get_allocator()).swap(data); + mark = src.mark; + my_size = src.my_size; + } + return *this; + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move constructor + /** This operation is unsafe if there are pending concurrent operations on the src queue. */ + concurrent_priority_queue(concurrent_priority_queue&& src) : mark(src.mark), + my_size(src.my_size), data(std::move(src.data)) + { + my_aggregator.initialize_handler(my_functor_t(this)); + } + + //! Move constructor with specific allocator + /** This operation is unsafe if there are pending concurrent operations on the src queue. */ + concurrent_priority_queue(concurrent_priority_queue&& src, const allocator_type& a) : mark(src.mark), + my_size(src.my_size), +#if __TBB_ALLOCATOR_TRAITS_PRESENT + data(std::move(src.data), a) +#else + // Some early version of C++11 STL vector does not have a constructor of vector(vector&& , allocator). + // It seems that the reason is absence of support of allocator_traits (stateful allocators). + data(a) +#endif //__TBB_ALLOCATOR_TRAITS_PRESENT + { + my_aggregator.initialize_handler(my_functor_t(this)); +#if !__TBB_ALLOCATOR_TRAITS_PRESENT + if (a != src.data.get_allocator()){ + data.reserve(src.data.size()); + data.assign(std::make_move_iterator(src.data.begin()), std::make_move_iterator(src.data.end())); + }else{ + data = std::move(src.data); + } +#endif //!__TBB_ALLOCATOR_TRAITS_PRESENT + } + + //! Move assignment operator + /** This operation is unsafe if there are pending concurrent operations on the src queue. */ + concurrent_priority_queue& operator=( concurrent_priority_queue&& src) { + if (this != &src) { + mark = src.mark; + my_size = src.my_size; +#if !__TBB_ALLOCATOR_TRAITS_PRESENT + if (data.get_allocator() != src.data.get_allocator()){ + vector_t(std::make_move_iterator(src.data.begin()), std::make_move_iterator(src.data.end()), data.get_allocator()).swap(data); + }else +#endif //!__TBB_ALLOCATOR_TRAITS_PRESENT + { + data = std::move(src.data); + } + } + return *this; + } +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + + //! Assign the queue from [begin,end) range, not thread-safe + template + void assign(InputIterator begin, InputIterator end) { + vector_t(begin, end, data.get_allocator()).swap(data); + mark = 0; + my_size = data.size(); + heapify(); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Assign the queue from std::initializer_list, not thread-safe + void assign(std::initializer_list il) { this->assign(il.begin(), il.end()); } + + //! Assign from std::initializer_list, not thread-safe + concurrent_priority_queue& operator=(std::initializer_list il) { + this->assign(il.begin(), il.end()); + return *this; + } +#endif //# __TBB_INITIALIZER_LISTS_PRESENT + + //! Returns true if empty, false otherwise + /** Returned value may not reflect results of pending operations. + This operation reads shared data and will trigger a race condition. */ + bool empty() const { return size()==0; } + + //! Returns the current number of elements contained in the queue + /** Returned value may not reflect results of pending operations. + This operation reads shared data and will trigger a race condition. */ + size_type size() const { return __TBB_load_with_acquire(my_size); } + + //! Pushes elem onto the queue, increasing capacity of queue if necessary + /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ + void push(const_reference elem) { +#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT + __TBB_STATIC_ASSERT( std::is_copy_constructible::value, "The type is not copy constructible. Copying push operation is impossible." ); +#endif + cpq_operation op_data(elem, PUSH_OP); + my_aggregator.execute(&op_data); + if (op_data.status == FAILED) // exception thrown + throw_exception(eid_bad_alloc); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Pushes elem onto the queue, increasing capacity of queue if necessary + /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ + void push(value_type &&elem) { + cpq_operation op_data(elem, PUSH_RVALUE_OP); + my_aggregator.execute(&op_data); + if (op_data.status == FAILED) // exception thrown + throw_exception(eid_bad_alloc); + } + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + //! Constructs a new element using args as the arguments for its construction and pushes it onto the queue */ + /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */ + template + void emplace(Args&&... args) { + push(value_type(std::forward(args)...)); + } +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + //! Gets a reference to and removes highest priority element + /** If a highest priority element was found, sets elem and returns true, + otherwise returns false. + This operation can be safely used concurrently with other push, try_pop or emplace operations. */ + bool try_pop(reference elem) { + cpq_operation op_data(POP_OP); + op_data.elem = &elem; + my_aggregator.execute(&op_data); + return op_data.status==SUCCEEDED; + } + + //! Clear the queue; not thread-safe + /** This operation is unsafe if there are pending concurrent operations on the queue. + Resets size, effectively emptying queue; does not free space. + May not clear elements added in pending operations. */ + void clear() { + data.clear(); + mark = 0; + my_size = 0; + } + + //! Swap this queue with another; not thread-safe + /** This operation is unsafe if there are pending concurrent operations on the queue. */ + void swap(concurrent_priority_queue& q) { + using std::swap; + data.swap(q.data); + swap(mark, q.mark); + swap(my_size, q.my_size); + } + + //! Return allocator object + allocator_type get_allocator() const { return data.get_allocator(); } + + private: + enum operation_type {INVALID_OP, PUSH_OP, POP_OP, PUSH_RVALUE_OP}; + enum operation_status { WAIT=0, SUCCEEDED, FAILED }; + + class cpq_operation : public aggregated_operation { + public: + operation_type type; + union { + value_type *elem; + size_type sz; + }; + cpq_operation(const_reference e, operation_type t) : + type(t), elem(const_cast(&e)) {} + cpq_operation(operation_type t) : type(t) {} + }; + + class my_functor_t { + concurrent_priority_queue *cpq; + public: + my_functor_t() {} + my_functor_t(concurrent_priority_queue *cpq_) : cpq(cpq_) {} + void operator()(cpq_operation* op_list) { + cpq->handle_operations(op_list); + } + }; + + typedef tbb::internal::aggregator< my_functor_t, cpq_operation > aggregator_t; + aggregator_t my_aggregator; + //! Padding added to avoid false sharing + char padding1[NFS_MaxLineSize - sizeof(aggregator_t)]; + //! The point at which unsorted elements begin + size_type mark; + __TBB_atomic size_type my_size; + Compare compare; + //! Padding added to avoid false sharing + char padding2[NFS_MaxLineSize - (2*sizeof(size_type)) - sizeof(Compare)]; + //! Storage for the heap of elements in queue, plus unheapified elements + /** data has the following structure: + + binary unheapified + heap elements + ____|_______|____ + | | | + v v v + [_|...|_|_|...|_| |...| ] + 0 ^ ^ ^ + | | |__capacity + | |__my_size + |__mark + + Thus, data stores the binary heap starting at position 0 through + mark-1 (it may be empty). Then there are 0 or more elements + that have not yet been inserted into the heap, in positions + mark through my_size-1. */ + typedef std::vector vector_t; + vector_t data; + + void handle_operations(cpq_operation *op_list) { + cpq_operation *tmp, *pop_list=NULL; + + __TBB_ASSERT(mark == data.size(), NULL); + + // First pass processes all constant (amortized; reallocation may happen) time pushes and pops. + while (op_list) { + // ITT note: &(op_list->status) tag is used to cover accesses to op_list + // node. This thread is going to handle the operation, and so will acquire it + // and perform the associated operation w/o triggering a race condition; the + // thread that created the operation is waiting on the status field, so when + // this thread is done with the operation, it will perform a + // store_with_release to give control back to the waiting thread in + // aggregator::insert_operation. + call_itt_notify(acquired, &(op_list->status)); + __TBB_ASSERT(op_list->type != INVALID_OP, NULL); + tmp = op_list; + op_list = itt_hide_load_word(op_list->next); + if (tmp->type == POP_OP) { + if (mark < data.size() && + compare(data[0], data[data.size()-1])) { + // there are newly pushed elems and the last one + // is higher than top + *(tmp->elem) = tbb::internal::move(data[data.size()-1]); + __TBB_store_with_release(my_size, my_size-1); + itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); + data.pop_back(); + __TBB_ASSERT(mark<=data.size(), NULL); + } + else { // no convenient item to pop; postpone + itt_hide_store_word(tmp->next, pop_list); + pop_list = tmp; + } + } else { // PUSH_OP or PUSH_RVALUE_OP + __TBB_ASSERT(tmp->type == PUSH_OP || tmp->type == PUSH_RVALUE_OP, "Unknown operation" ); + __TBB_TRY{ + if (tmp->type == PUSH_OP) { + push_back_helper(*(tmp->elem), typename internal::use_element_copy_constructor::type()); + } else { + data.push_back(tbb::internal::move(*(tmp->elem))); + } + __TBB_store_with_release(my_size, my_size + 1); + itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); + } __TBB_CATCH(...) { + itt_store_word_with_release(tmp->status, uintptr_t(FAILED)); + } + } + } + + // second pass processes pop operations + while (pop_list) { + tmp = pop_list; + pop_list = itt_hide_load_word(pop_list->next); + __TBB_ASSERT(tmp->type == POP_OP, NULL); + if (data.empty()) { + itt_store_word_with_release(tmp->status, uintptr_t(FAILED)); + } + else { + __TBB_ASSERT(mark<=data.size(), NULL); + if (mark < data.size() && + compare(data[0], data[data.size()-1])) { + // there are newly pushed elems and the last one is + // higher than top + *(tmp->elem) = tbb::internal::move(data[data.size()-1]); + __TBB_store_with_release(my_size, my_size-1); + itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); + data.pop_back(); + } + else { // extract top and push last element down heap + *(tmp->elem) = tbb::internal::move(data[0]); + __TBB_store_with_release(my_size, my_size-1); + itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED)); + reheap(); + } + } + } + + // heapify any leftover pushed elements before doing the next + // batch of operations + if (mark0) mark = 1; + for (; mark>1; + if (!compare(data[parent], to_place)) break; + data[cur_pos] = tbb::internal::move(data[parent]); + cur_pos = parent; + } while( cur_pos ); + data[cur_pos] = tbb::internal::move(to_place); + } + } + + //! Re-heapify after an extraction + /** Re-heapify by pushing last element down the heap from the root. */ + void reheap() { + size_type cur_pos=0, child=1; + + while (child < mark) { + size_type target = child; + if (child+1 < mark && compare(data[child], data[child+1])) + ++target; + // target now has the higher priority child + if (compare(data[target], data[data.size()-1])) break; + data[cur_pos] = tbb::internal::move(data[target]); + cur_pos = target; + child = (cur_pos<<1)+1; + } + if (cur_pos != data.size()-1) + data[cur_pos] = tbb::internal::move(data[data.size()-1]); + data.pop_back(); + if (mark > data.size()) mark = data.size(); + } + + void push_back_helper(const T& t, tbb::internal::true_type) { + data.push_back(t); + } + + void push_back_helper(const T&, tbb::internal::false_type) { + __TBB_ASSERT( false, "The type is not copy constructible. Copying push operation is impossible." ); + } +}; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +namespace internal { + +template +using priority_queue_t = concurrent_priority_queue< + T, + std::conditional_t< (sizeof...(Args)>0) && !is_allocator_v< pack_element_t<0, Args...> >, + pack_element_t<0, Args...>, std::less >, + std::conditional_t< (sizeof...(Args)>0) && is_allocator_v< pack_element_t >, + pack_element_t, cache_aligned_allocator > +>; +} + +// Deduction guide for the constructor from two iterators +template::value_type, + typename... Args +> concurrent_priority_queue(InputIterator, InputIterator, Args...) +-> internal::priority_queue_t; + +template +concurrent_priority_queue(std::initializer_list init_list, CompareOrAllocalor) +-> internal::priority_queue_t; + +#endif /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ +} // namespace interface5 + +using interface5::concurrent_priority_queue; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_concurrent_priority_queue_H_include_area + +#endif /* __TBB_concurrent_priority_queue_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_queue.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_queue.h new file mode 100644 index 00000000..122f98e5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_queue.h @@ -0,0 +1,479 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_queue_H +#define __TBB_concurrent_queue_H + +#define __TBB_concurrent_queue_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "internal/_concurrent_queue_impl.h" +#include "internal/_allocator_traits.h" + +namespace tbb { + +namespace strict_ppl { + +//! A high-performance thread-safe non-blocking concurrent queue. +/** Multiple threads may each push and pop concurrently. + Assignment construction is not allowed. + @ingroup containers */ +template > +class concurrent_queue: public internal::concurrent_queue_base_v3 { + template friend class internal::concurrent_queue_iterator; + + //! Allocator type + typedef typename tbb::internal::allocator_rebind::type page_allocator_type; + page_allocator_type my_allocator; + + //! Allocates a block of size n (bytes) + virtual void *allocate_block( size_t n ) __TBB_override { + void *b = reinterpret_cast(my_allocator.allocate( n )); + if( !b ) + internal::throw_exception(internal::eid_bad_alloc); + return b; + } + + //! Deallocates block created by allocate_block. + virtual void deallocate_block( void *b, size_t n ) __TBB_override { + my_allocator.deallocate( reinterpret_cast(b), n ); + } + + static void copy_construct_item(T* location, const void* src){ + new (location) T(*static_cast(src)); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + static void move_construct_item(T* location, const void* src) { + new (location) T( std::move(*static_cast(const_cast(src))) ); + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +public: + //! Element type in the queue. + typedef T value_type; + + //! Reference type + typedef T& reference; + + //! Const reference type + typedef const T& const_reference; + + //! Integral type for representing size of the queue. + typedef size_t size_type; + + //! Difference type for iterator + typedef ptrdiff_t difference_type; + + //! Allocator type + typedef A allocator_type; + + //! Construct empty queue + explicit concurrent_queue(const allocator_type& a = allocator_type()) : + my_allocator( a ) + { + } + + //! [begin,end) constructor + template + concurrent_queue( InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) : + my_allocator( a ) + { + for( ; begin != end; ++begin ) + this->push(*begin); + } + + //! Copy constructor + concurrent_queue( const concurrent_queue& src, const allocator_type& a = allocator_type()) : + internal::concurrent_queue_base_v3(), my_allocator( a ) + { + this->assign( src, copy_construct_item ); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move constructors + concurrent_queue( concurrent_queue&& src ) : + internal::concurrent_queue_base_v3(), my_allocator( std::move(src.my_allocator) ) + { + this->internal_swap( src ); + } + + concurrent_queue( concurrent_queue&& src, const allocator_type& a ) : + internal::concurrent_queue_base_v3(), my_allocator( a ) + { + // checking that memory allocated by one instance of allocator can be deallocated + // with another + if( my_allocator == src.my_allocator) { + this->internal_swap( src ); + } else { + // allocators are different => performing per-element move + this->assign( src, move_construct_item ); + src.clear(); + } + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + //! Destroy queue + ~concurrent_queue(); + + //! Enqueue an item at tail of queue. + void push( const T& source ) { + this->internal_push( &source, copy_construct_item ); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + void push( T&& source ) { + this->internal_push( &source, move_construct_item ); + } + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template + void emplace( Arguments&&... args ) { + push( T(std::forward( args )...) ); + } +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + //! Attempt to dequeue an item from head of queue. + /** Does not wait for item to become available. + Returns true if successful; false otherwise. */ + bool try_pop( T& result ) { + return this->internal_try_pop( &result ); + } + + //! Return the number of items in the queue; thread unsafe + size_type unsafe_size() const {return this->internal_size();} + + //! Equivalent to size()==0. + bool empty() const {return this->internal_empty();} + + //! Clear the queue. not thread-safe. + void clear() ; + + //! Return allocator object + allocator_type get_allocator() const { return this->my_allocator; } + + typedef internal::concurrent_queue_iterator iterator; + typedef internal::concurrent_queue_iterator const_iterator; + + //------------------------------------------------------------------------ + // The iterators are intended only for debugging. They are slow and not thread safe. + //------------------------------------------------------------------------ + iterator unsafe_begin() {return iterator(*this);} + iterator unsafe_end() {return iterator();} + const_iterator unsafe_begin() const {return const_iterator(*this);} + const_iterator unsafe_end() const {return const_iterator();} +} ; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +// Deduction guide for the constructor from two iterators +template::value_type, + typename A = cache_aligned_allocator +> concurrent_queue(InputIterator, InputIterator, const A& = A()) +-> concurrent_queue; +#endif /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ + +template +concurrent_queue::~concurrent_queue() { + clear(); + this->internal_finish_clear(); +} + +template +void concurrent_queue::clear() { + T value; + while( !empty() ) try_pop(value); +} + +} // namespace strict_ppl + +//! A high-performance thread-safe blocking concurrent bounded queue. +/** This is the pre-PPL TBB concurrent queue which supports boundedness and blocking semantics. + Note that method names agree with the PPL-style concurrent queue. + Multiple threads may each push and pop concurrently. + Assignment construction is not allowed. + @ingroup containers */ +template > +class concurrent_bounded_queue: public internal::concurrent_queue_base_v8 { + template friend class internal::concurrent_queue_iterator; + typedef typename tbb::internal::allocator_rebind::type page_allocator_type; + + //! Allocator type + page_allocator_type my_allocator; + + typedef typename concurrent_queue_base_v3::padded_page padded_page; + typedef typename concurrent_queue_base_v3::copy_specifics copy_specifics; + + //! Class used to ensure exception-safety of method "pop" + class destroyer: internal::no_copy { + T& my_value; + public: + destroyer( T& value ) : my_value(value) {} + ~destroyer() {my_value.~T();} + }; + + T& get_ref( page& p, size_t index ) { + __TBB_ASSERT( index(static_cast(&p))->last)[index]; + } + + virtual void copy_item( page& dst, size_t index, const void* src ) __TBB_override { + new( &get_ref(dst,index) ) T(*static_cast(src)); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + virtual void move_item( page& dst, size_t index, const void* src ) __TBB_override { + new( &get_ref(dst,index) ) T( std::move(*static_cast(const_cast(src))) ); + } +#else + virtual void move_item( page&, size_t, const void* ) __TBB_override { + __TBB_ASSERT( false, "Unreachable code" ); + } +#endif + + virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) __TBB_override { + new( &get_ref(dst,dindex) ) T( get_ref( const_cast(src), sindex ) ); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) __TBB_override { + new( &get_ref(dst,dindex) ) T( std::move(get_ref( const_cast(src), sindex )) ); + } +#else + virtual void move_page_item( page&, size_t, const page&, size_t ) __TBB_override { + __TBB_ASSERT( false, "Unreachable code" ); + } +#endif + + virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) __TBB_override { + T& from = get_ref(src,index); + destroyer d(from); + *static_cast(dst) = tbb::internal::move( from ); + } + + virtual page *allocate_page() __TBB_override { + size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T); + page *p = reinterpret_cast(my_allocator.allocate( n )); + if( !p ) + internal::throw_exception(internal::eid_bad_alloc); + return p; + } + + virtual void deallocate_page( page *p ) __TBB_override { + size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T); + my_allocator.deallocate( reinterpret_cast(p), n ); + } + +public: + //! Element type in the queue. + typedef T value_type; + + //! Allocator type + typedef A allocator_type; + + //! Reference type + typedef T& reference; + + //! Const reference type + typedef const T& const_reference; + + //! Integral type for representing size of the queue. + /** Note that the size_type is a signed integral type. + This is because the size can be negative if there are pending pops without corresponding pushes. */ + typedef std::ptrdiff_t size_type; + + //! Difference type for iterator + typedef std::ptrdiff_t difference_type; + + //! Construct empty queue + explicit concurrent_bounded_queue(const allocator_type& a = allocator_type()) : + concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) + { + } + + //! Copy constructor + concurrent_bounded_queue( const concurrent_bounded_queue& src, const allocator_type& a = allocator_type()) + : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) + { + assign( src ); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move constructors + concurrent_bounded_queue( concurrent_bounded_queue&& src ) + : concurrent_queue_base_v8( sizeof(T) ), my_allocator( std::move(src.my_allocator) ) + { + internal_swap( src ); + } + + concurrent_bounded_queue( concurrent_bounded_queue&& src, const allocator_type& a ) + : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) + { + // checking that memory allocated by one instance of allocator can be deallocated + // with another + if( my_allocator == src.my_allocator) { + this->internal_swap( src ); + } else { + // allocators are different => performing per-element move + this->move_content( src ); + src.clear(); + } + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + //! [begin,end) constructor + template + concurrent_bounded_queue( InputIterator begin, InputIterator end, + const allocator_type& a = allocator_type()) + : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a ) + { + for( ; begin != end; ++begin ) + internal_push_if_not_full(&*begin); + } + + //! Destroy queue + ~concurrent_bounded_queue(); + + //! Enqueue an item at tail of queue. + void push( const T& source ) { + internal_push( &source ); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move an item at tail of queue. + void push( T&& source ) { + internal_push_move( &source ); + } + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template + void emplace( Arguments&&... args ) { + push( T(std::forward( args )...) ); + } +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + //! Dequeue item from head of queue. + /** Block until an item becomes available, and then dequeue it. */ + void pop( T& destination ) { + internal_pop( &destination ); + } + +#if TBB_USE_EXCEPTIONS + //! Abort all pending queue operations + void abort() { + internal_abort(); + } +#endif + + //! Enqueue an item at tail of queue if queue is not already full. + /** Does not wait for queue to become not full. + Returns true if item is pushed; false if queue was already full. */ + bool try_push( const T& source ) { + return internal_push_if_not_full( &source ); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move an item at tail of queue if queue is not already full. + /** Does not wait for queue to become not full. + Returns true if item is pushed; false if queue was already full. */ + bool try_push( T&& source ) { + return internal_push_move_if_not_full( &source ); + } +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template + bool try_emplace( Arguments&&... args ) { + return try_push( T(std::forward( args )...) ); + } +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + //! Attempt to dequeue an item from head of queue. + /** Does not wait for item to become available. + Returns true if successful; false otherwise. */ + bool try_pop( T& destination ) { + return internal_pop_if_present( &destination ); + } + + //! Return number of pushes minus number of pops. + /** Note that the result can be negative if there are pops waiting for the + corresponding pushes. The result can also exceed capacity() if there + are push operations in flight. */ + size_type size() const {return internal_size();} + + //! Equivalent to size()<=0. + bool empty() const {return internal_empty();} + + //! Maximum number of allowed elements + size_type capacity() const { + return my_capacity; + } + + //! Set the capacity + /** Setting the capacity to 0 causes subsequent try_push operations to always fail, + and subsequent push operations to block forever. */ + void set_capacity( size_type new_capacity ) { + internal_set_capacity( new_capacity, sizeof(T) ); + } + + //! return allocator object + allocator_type get_allocator() const { return this->my_allocator; } + + //! clear the queue. not thread-safe. + void clear() ; + + typedef internal::concurrent_queue_iterator iterator; + typedef internal::concurrent_queue_iterator const_iterator; + + //------------------------------------------------------------------------ + // The iterators are intended only for debugging. They are slow and not thread safe. + //------------------------------------------------------------------------ + iterator unsafe_begin() {return iterator(*this);} + iterator unsafe_end() {return iterator();} + const_iterator unsafe_begin() const {return const_iterator(*this);} + const_iterator unsafe_end() const {return const_iterator();} + +}; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +// guide for concurrent_bounded_queue(InputIterator, InputIterator, ...) +template::value_type, + typename A = cache_aligned_allocator +> concurrent_bounded_queue(InputIterator, InputIterator, const A& = A()) +-> concurrent_bounded_queue; +#endif /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ + +template +concurrent_bounded_queue::~concurrent_bounded_queue() { + clear(); + internal_finish_clear(); +} + +template +void concurrent_bounded_queue::clear() { + T value; + while( try_pop(value) ) /*noop*/; +} + +using strict_ppl::concurrent_queue; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_concurrent_queue_H_include_area + +#endif /* __TBB_concurrent_queue_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_set.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_set.h new file mode 100644 index 00000000..ecb21624 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_set.h @@ -0,0 +1,304 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_set_H +#define __TBB_concurrent_set_H + +#define __TBB_concurrent_set_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#if !TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#error Set TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS to include concurrent_set.h +#endif + +#include "tbb/tbb_config.h" + +// concurrent_set requires C++11 support +#if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT + +#include "internal/_concurrent_skip_list_impl.h" + +namespace tbb { +namespace interface10 { + +// TODO: test this class +template +class set_traits { +public: + static constexpr size_t MAX_LEVEL = MAX_LEVELS; + using random_level_generator_type = RandomGenerator; + using key_type = Key; + using value_type = key_type; + using compare_type = KeyCompare; + using value_compare = compare_type; + using reference = value_type & ; + using const_reference = const value_type&; + using allocator_type = Allocator; + using mutex_type = tbb::spin_mutex; + using node_type = tbb::internal::node_handle, allocator_type>; + + static const bool allow_multimapping = AllowMultimapping; + + static const key_type& get_key(const_reference val) { + return val; + } + + static value_compare value_comp(compare_type comp) { return comp; } +}; + +template +class concurrent_multiset; + +template , typename Allocator = tbb_allocator> +class concurrent_set + : public internal::concurrent_skip_list, 64, Allocator, false>> { + using traits_type = set_traits, 64, Allocator, false>; + using base_type = internal::concurrent_skip_list; +#if __TBB_EXTRA_DEBUG +public: +#endif + using base_type::allow_multimapping; +public: + using key_type = Key; + using value_type = typename traits_type::value_type; + using size_type = typename base_type::size_type; + using difference_type = typename base_type::difference_type; + using key_compare = Comp; + using value_compare = typename base_type::value_compare; + using allocator_type = Allocator; + + using reference = typename base_type::reference; + using const_reference = typename base_type::const_reference; + using pointer = typename base_type::pointer; + using const_pointer = typename base_type::pointer; + + using iterator = typename base_type::iterator; + using const_iterator = typename base_type::const_iterator; + using reverse_iterator = typename base_type::reverse_iterator; + using const_reverse_iterator = typename base_type::const_reverse_iterator; + + using node_type = typename base_type::node_type; + + using base_type::insert; + + concurrent_set() = default; + + explicit concurrent_set(const key_compare& comp, const allocator_type& alloc = allocator_type()) : base_type(comp, alloc) {} + + explicit concurrent_set(const allocator_type& alloc) : base_type(key_compare(), alloc) {} + + template< class InputIt > + concurrent_set(InputIt first, InputIt last, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type()) + : base_type(first, last, comp, alloc) {} + + template< class InputIt > + concurrent_set(InputIt first, InputIt last, const allocator_type& alloc) : base_type(first, last, key_compare(), alloc) {} + + /** Copy constructor */ + concurrent_set(const concurrent_set&) = default; + + concurrent_set(const concurrent_set& other, const allocator_type& alloc) : base_type(other, alloc) {} + + concurrent_set(concurrent_set&&) = default; + + concurrent_set(concurrent_set&& other, const allocator_type& alloc) : base_type(std::move(other), alloc) {} + + concurrent_set(std::initializer_list init, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type()) + : base_type(comp, alloc) { + insert(init); + } + + concurrent_set(std::initializer_list init, const allocator_type& alloc) + : base_type(key_compare(), alloc) { + insert(init); + } + + concurrent_set& operator=(const concurrent_set& other) { + return static_cast(base_type::operator=(other)); + } + + concurrent_set& operator=(concurrent_set&& other) { + return static_cast(base_type::operator=(std::move(other))); + } + + template + void merge(concurrent_set& source) { + this->internal_merge(source); + } + + template + void merge(concurrent_set&& source) { + this->internal_merge(std::move(source)); + } + + template + void merge(concurrent_multiset& source) { + this->internal_merge(source); + } + + template + void merge(concurrent_multiset&& source) { + this->internal_merge(std::move(source)); + } +}; // class concurrent_set + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +namespace internal { + +using namespace tbb::internal; + +template typename Set, typename Key, typename... Args> +using c_set_t = Set 0) && !is_allocator_v >, + pack_element_t<0, Args...>, std::less >, + std::conditional_t< (sizeof...(Args) > 0) && is_allocator_v >, + pack_element_t, tbb_allocator > >; +} // namespace internal + +template +concurrent_set(It, It, Args...) +-> internal::c_set_t, Args...>; + +template +concurrent_set(std::initializer_list, Args...) +-> internal::c_set_t; + +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +template , typename Allocator = tbb_allocator> +class concurrent_multiset + : public internal::concurrent_skip_list, 64, Allocator, true>> { + using traits_type = set_traits, 64, Allocator, true>; + using base_type = internal::concurrent_skip_list; +#if __TBB_EXTRA_DEBUG +public: +#endif + using base_type::allow_multimapping; +public: + using key_type = Key; + using value_type = typename traits_type::value_type; + using size_type = typename base_type::size_type; + using difference_type = typename base_type::difference_type; + using key_compare = Comp; + using value_compare = typename base_type::value_compare; + using allocator_type = Allocator; + + using reference = typename base_type::reference; + using const_reference = typename base_type::const_reference; + using pointer = typename base_type::pointer; + using const_pointer = typename base_type::pointer; + + using iterator = typename base_type::iterator; + using const_iterator = typename base_type::const_iterator; + using reverse_iterator = typename base_type::reverse_iterator; + using const_reverse_iterator = typename base_type::const_reverse_iterator; + + using node_type = typename base_type::node_type; + + using base_type::insert; + + concurrent_multiset() = default; + + explicit concurrent_multiset(const key_compare& comp, const allocator_type& alloc = allocator_type()) : base_type(comp, alloc) {} + + explicit concurrent_multiset(const allocator_type& alloc) : base_type(key_compare(), alloc) {} + + template< class InputIt > + concurrent_multiset(InputIt first, InputIt last, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type()) + : base_type(comp, alloc) { + insert(first, last); + } + + template< class InputIt > + concurrent_multiset(InputIt first, InputIt last, const allocator_type& alloc) : base_type(key_compare(), alloc) { + insert(first, last); + } + + /** Copy constructor */ + concurrent_multiset(const concurrent_multiset&) = default; + + concurrent_multiset(const concurrent_multiset& other, const allocator_type& alloc) : base_type(other, alloc) {} + + concurrent_multiset(concurrent_multiset&&) = default; + + concurrent_multiset(concurrent_multiset&& other, const allocator_type& alloc) : base_type(std::move(other), alloc) {} + + concurrent_multiset(std::initializer_list init, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type()) + : base_type(comp, alloc) { + insert(init); + } + + concurrent_multiset(std::initializer_list init, const allocator_type& alloc) + : base_type(key_compare(), alloc) { + insert(init); + } + + concurrent_multiset& operator=(const concurrent_multiset& other) { + return static_cast(base_type::operator=(other)); + } + + concurrent_multiset& operator=(concurrent_multiset&& other) { + return static_cast(base_type::operator=(std::move(other))); + } + + template + void merge(concurrent_set& source) { + this->internal_merge(source); + } + + template + void merge(concurrent_set&& source) { + this->internal_merge(std::move(source)); + } + + template + void merge(concurrent_multiset& source) { + this->internal_merge(source); + } + + template + void merge(concurrent_multiset&& source) { + this->internal_merge(std::move(source)); + } +}; // class concurrent_multiset + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + + +template +concurrent_multiset(It, It, Args...) +-> internal::c_set_t, Args...>; + +template +concurrent_multiset(std::initializer_list, Args...) +-> internal::c_set_t; + +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +} // namespace interface10 + +using interface10::concurrent_set; +using interface10::concurrent_multiset; + +} // namespace tbb + +#endif // __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_concurrent_set_H_include_area + +#endif // __TBB_concurrent_set_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_unordered_map.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_unordered_map.h new file mode 100644 index 00000000..a9d8df8a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_unordered_map.h @@ -0,0 +1,492 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* Container implementations in this header are based on PPL implementations + provided by Microsoft. */ + +#ifndef __TBB_concurrent_unordered_map_H +#define __TBB_concurrent_unordered_map_H + +#define __TBB_concurrent_unordered_map_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "internal/_concurrent_unordered_impl.h" + +namespace tbb +{ + +namespace interface5 { + +// Template class for hash map traits +template +class concurrent_unordered_map_traits +{ +protected: + typedef std::pair value_type; + typedef Key key_type; + typedef Hash_compare hash_compare; + typedef typename tbb::internal::allocator_rebind::type allocator_type; +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + typedef tbb::internal::node_handle::node, + allocator_type> node_type; +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + + enum { allow_multimapping = Allow_multimapping }; + + concurrent_unordered_map_traits() : my_hash_compare() {} + concurrent_unordered_map_traits(const hash_compare& hc) : my_hash_compare(hc) {} + + template + static const Key& get_key(const std::pair& value) { + return (value.first); + } + + hash_compare my_hash_compare; // the comparator predicate for keys +}; + +template +class concurrent_unordered_multimap; + +template , typename Key_equality = std::equal_to, + typename Allocator = tbb::tbb_allocator > > +class concurrent_unordered_map : + public internal::concurrent_unordered_base< concurrent_unordered_map_traits, Allocator, false> > +{ + // Base type definitions + typedef internal::hash_compare hash_compare; + typedef concurrent_unordered_map_traits traits_type; + typedef internal::concurrent_unordered_base< traits_type > base_type; +#if __TBB_EXTRA_DEBUG +public: +#endif + using traits_type::allow_multimapping; +public: + using base_type::end; + using base_type::find; + using base_type::insert; + + // Type definitions + typedef Key key_type; + typedef typename base_type::value_type value_type; + typedef T mapped_type; + typedef Hasher hasher; + typedef Key_equality key_equal; + typedef hash_compare key_compare; + + typedef typename base_type::allocator_type allocator_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + + typedef typename base_type::size_type size_type; + typedef typename base_type::difference_type difference_type; + + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::iterator local_iterator; + typedef typename base_type::const_iterator const_local_iterator; +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + typedef typename base_type::node_type node_type; +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + + // Construction/destruction/copying + explicit concurrent_unordered_map(size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), + const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + {} + + concurrent_unordered_map(size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + {} + + concurrent_unordered_map(size_type n_of_buckets, const hasher& a_hasher, const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + {} + + explicit concurrent_unordered_map(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) + {} + + template + concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), + const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + { + insert(first, last); + } + + template + concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + { + insert(first, last); + } + + template + concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets, const hasher& a_hasher, + const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + { + insert(first, last); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Constructor from initializer_list + concurrent_unordered_map(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), + const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + { + insert(il.begin(),il.end()); + } + + concurrent_unordered_map(std::initializer_list il, size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + { + insert(il.begin(), il.end()); + } + + concurrent_unordered_map(std::initializer_list il, size_type n_of_buckets, const hasher& a_hasher, + const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + { + insert(il.begin(), il.end()); + } + +#endif //# __TBB_INITIALIZER_LISTS_PRESENT + + +#if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT + concurrent_unordered_map(const concurrent_unordered_map& table) + : base_type(table) + {} + + concurrent_unordered_map& operator=(const concurrent_unordered_map& table) + { + return static_cast(base_type::operator=(table)); + } + + concurrent_unordered_map(concurrent_unordered_map&& table) + : base_type(std::move(table)) + {} + + concurrent_unordered_map& operator=(concurrent_unordered_map&& table) + { + return static_cast(base_type::operator=(std::move(table))); + } +#endif //__TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT + +#if __TBB_CPP11_RVALUE_REF_PRESENT + concurrent_unordered_map(concurrent_unordered_map&& table, const Allocator& a) : base_type(std::move(table), a) + {} +#endif /*__TBB_CPP11_RVALUE_REF_PRESENT*/ + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + template + void merge(concurrent_unordered_map& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_map&& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_multimap& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_multimap&& source) + { this->internal_merge(source); } + +#endif //__TBB_UNORDERED_NODE_HANDLE_PRESENT + + concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a) + : base_type(table, a) + {} + + // Observers + mapped_type& operator[](const key_type& key) + { + iterator where = find(key); + + if (where == end()) + { + where = insert(std::pair(key, mapped_type())).first; + } + + return ((*where).second); + } + + mapped_type& at(const key_type& key) + { + iterator where = find(key); + + if (where == end()) + { + tbb::internal::throw_exception(tbb::internal::eid_invalid_key); + } + + return ((*where).second); + } + + const mapped_type& at(const key_type& key) const + { + const_iterator where = find(key); + + if (where == end()) + { + tbb::internal::throw_exception(tbb::internal::eid_invalid_key); + } + + return ((*where).second); + } +}; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +namespace internal { +using namespace tbb::internal; + +template typename Map, typename Key, typename Element, typename... Args> +using cu_map_t = Map< + Key, Element, + std::conditional_t< (sizeof...(Args)>0) && !is_allocator_v< pack_element_t<0, Args...> >, + pack_element_t<0, Args...>, tbb_hash >, + std::conditional_t< (sizeof...(Args)>1) && !is_allocator_v< pack_element_t<1, Args...> >, + pack_element_t<1, Args...>, std::equal_to >, + std::conditional_t< (sizeof...(Args)>0) && is_allocator_v< pack_element_t >, + pack_element_t, tbb_allocator > > +>; +} + +// Deduction guide for the constructor from two iterators +template +concurrent_unordered_map (I, I) +-> internal::cu_map_t, internal::iterator_mapped_t>; + +// Deduction guide for the constructor from two iterators and hasher/equality/allocator +template +concurrent_unordered_map(I, I, size_t, Args...) +-> internal::cu_map_t, internal::iterator_mapped_t, Args...>; + +// Deduction guide for the constructor from an initializer_list +template +concurrent_unordered_map(std::initializer_list>) +-> internal::cu_map_t; + +// Deduction guide for the constructor from an initializer_list and hasher/equality/allocator +template +concurrent_unordered_map(std::initializer_list>, size_t, Args...) +-> internal::cu_map_t; + +#endif /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ + +template < typename Key, typename T, typename Hasher = tbb::tbb_hash, typename Key_equality = std::equal_to, + typename Allocator = tbb::tbb_allocator > > +class concurrent_unordered_multimap : + public internal::concurrent_unordered_base< concurrent_unordered_map_traits< Key, T, + internal::hash_compare, Allocator, true> > +{ + // Base type definitions + typedef internal::hash_compare hash_compare; + typedef concurrent_unordered_map_traits traits_type; + typedef internal::concurrent_unordered_base base_type; +#if __TBB_EXTRA_DEBUG +public: +#endif + using traits_type::allow_multimapping; +public: + using base_type::insert; + + // Type definitions + typedef Key key_type; + typedef typename base_type::value_type value_type; + typedef T mapped_type; + typedef Hasher hasher; + typedef Key_equality key_equal; + typedef hash_compare key_compare; + + typedef typename base_type::allocator_type allocator_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + + typedef typename base_type::size_type size_type; + typedef typename base_type::difference_type difference_type; + + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::iterator local_iterator; + typedef typename base_type::const_iterator const_local_iterator; +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + typedef typename base_type::node_type node_type; +#endif //__TBB_UNORDERED_NODE_HANDLE_PRESENT + + // Construction/destruction/copying + explicit concurrent_unordered_multimap(size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), + const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + {} + + concurrent_unordered_multimap(size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + {} + + concurrent_unordered_multimap(size_type n_of_buckets, const hasher& a_hasher, const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + {} + + explicit concurrent_unordered_multimap(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) + {} + + template + concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), + const allocator_type& a = allocator_type()) + : base_type(n_of_buckets,key_compare(a_hasher,a_keyeq), a) + { + insert(first, last); + } + + template + concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + { + insert(first, last); + } + + template + concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets, const hasher& a_hasher, + const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + { + insert(first, last); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Constructor from initializer_list + concurrent_unordered_multimap(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), + const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + { + insert(il.begin(),il.end()); + } + + concurrent_unordered_multimap(std::initializer_list il, size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + { + insert(il.begin(), il.end()); + } + + concurrent_unordered_multimap(std::initializer_list il, size_type n_of_buckets, const hasher& a_hasher, + const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + { + insert(il.begin(), il.end()); + } + +#endif //# __TBB_INITIALIZER_LISTS_PRESENT + +#if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT + concurrent_unordered_multimap(const concurrent_unordered_multimap& table) + : base_type(table) + {} + + concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table) + { + return static_cast(base_type::operator=(table)); + } + + concurrent_unordered_multimap(concurrent_unordered_multimap&& table) + : base_type(std::move(table)) + {} + + concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& table) + { + return static_cast(base_type::operator=(std::move(table))); + } +#endif //__TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT + +#if __TBB_CPP11_RVALUE_REF_PRESENT + concurrent_unordered_multimap(concurrent_unordered_multimap&& table, const Allocator& a) : base_type(std::move(table), a) + {} +#endif /*__TBB_CPP11_RVALUE_REF_PRESENT*/ + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + template + void merge(concurrent_unordered_map& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_map&& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_multimap& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_multimap&& source) + { this->internal_merge(source); } + +#endif //__TBB_UNORDERED_NODE_HANDLE_PRESENT + + concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a) + : base_type(table, a) + {} +}; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +// Deduction guide for the constructor from two iterators +template +concurrent_unordered_multimap (I, I) +-> internal::cu_map_t, internal::iterator_mapped_t>; + +// Deduction guide for the constructor from two iterators and hasher/equality/allocator +template +concurrent_unordered_multimap(I, I, size_t, Args...) +-> internal::cu_map_t, internal::iterator_mapped_t, Args...>; + +// Deduction guide for the constructor from an initializer_list +template +concurrent_unordered_multimap(std::initializer_list>) +-> internal::cu_map_t; + +// Deduction guide for the constructor from an initializer_list and hasher/equality/allocator +template +concurrent_unordered_multimap(std::initializer_list>, size_t, Args...) +-> internal::cu_map_t; + +#endif /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ +} // namespace interface5 + +using interface5::concurrent_unordered_map; +using interface5::concurrent_unordered_multimap; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_concurrent_unordered_map_H_include_area + +#endif// __TBB_concurrent_unordered_map_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_unordered_set.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_unordered_set.h new file mode 100644 index 00000000..edb02565 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_unordered_set.h @@ -0,0 +1,448 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* Container implementations in this header are based on PPL implementations + provided by Microsoft. */ + +#ifndef __TBB_concurrent_unordered_set_H +#define __TBB_concurrent_unordered_set_H + +#define __TBB_concurrent_unordered_set_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "internal/_concurrent_unordered_impl.h" + +namespace tbb +{ + +namespace interface5 { + +// Template class for hash set traits +template +class concurrent_unordered_set_traits +{ +protected: + typedef Key value_type; + typedef Key key_type; + typedef Hash_compare hash_compare; + typedef typename tbb::internal::allocator_rebind::type allocator_type; +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + typedef tbb::internal::node_handle::node, + allocator_type> node_type; +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + + enum { allow_multimapping = Allow_multimapping }; + + concurrent_unordered_set_traits() : my_hash_compare() {} + concurrent_unordered_set_traits(const hash_compare& hc) : my_hash_compare(hc) {} + + static const Key& get_key(const value_type& value) { + return value; + } + + hash_compare my_hash_compare; // the comparator predicate for keys +}; + +template +class concurrent_unordered_multiset; + +template , typename Key_equality = std::equal_to, typename Allocator = tbb::tbb_allocator > +class concurrent_unordered_set : public internal::concurrent_unordered_base< concurrent_unordered_set_traits, Allocator, false> > +{ + // Base type definitions + typedef internal::hash_compare hash_compare; + typedef concurrent_unordered_set_traits traits_type; + typedef internal::concurrent_unordered_base< traits_type > base_type; +#if __TBB_EXTRA_DEBUG +public: +#endif + using traits_type::allow_multimapping; +public: + using base_type::insert; + + // Type definitions + typedef Key key_type; + typedef typename base_type::value_type value_type; + typedef Key mapped_type; + typedef Hasher hasher; + typedef Key_equality key_equal; + typedef hash_compare key_compare; + + typedef typename base_type::allocator_type allocator_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + + typedef typename base_type::size_type size_type; + typedef typename base_type::difference_type difference_type; + + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::iterator local_iterator; + typedef typename base_type::const_iterator const_local_iterator; +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + typedef typename base_type::node_type node_type; +#endif /*__TBB_UNORDERED_NODE_HANDLE_PRESENT*/ + + // Construction/destruction/copying + explicit concurrent_unordered_set(size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), + const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + {} + + concurrent_unordered_set(size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + {} + + concurrent_unordered_set(size_type n_of_buckets, const hasher& a_hasher, const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + {} + + explicit concurrent_unordered_set(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) + {} + + template + concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + { + insert(first, last); + } + + template + concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + { + insert(first, last); + } + + template + concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets, const hasher& a_hasher, const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + { + insert(first, last); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Constructor from initializer_list + concurrent_unordered_set(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(), + const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + { + insert(il.begin(),il.end()); + } + + concurrent_unordered_set(std::initializer_list il, size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + { + insert(il.begin(), il.end()); + } + + concurrent_unordered_set(std::initializer_list il, size_type n_of_buckets, const hasher& a_hasher, const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + { + insert(il.begin(), il.end()); + } + +#endif //# __TBB_INITIALIZER_LISTS_PRESENT + +#if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT + concurrent_unordered_set(const concurrent_unordered_set& table) + : base_type(table) + {} + + concurrent_unordered_set& operator=(const concurrent_unordered_set& table) + { + return static_cast(base_type::operator=(table)); + } + + concurrent_unordered_set(concurrent_unordered_set&& table) + : base_type(std::move(table)) + {} + + concurrent_unordered_set& operator=(concurrent_unordered_set&& table) + { + return static_cast(base_type::operator=(std::move(table))); + } +#endif //__TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT + +#if __TBB_CPP11_RVALUE_REF_PRESENT + concurrent_unordered_set(concurrent_unordered_set&& table, const Allocator& a) + : base_type(std::move(table), a) + {} +#endif /*__TBB_CPP11_RVALUE_REF_PRESENT*/ + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + template + void merge(concurrent_unordered_set& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_set&& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_multiset& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_multiset&& source) + { this->internal_merge(source); } + +#endif //__TBB_UNORDERED_NODE_HANDLE_PRESENT + + concurrent_unordered_set(const concurrent_unordered_set& table, const Allocator& a) + : base_type(table, a) + {} + +}; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +namespace internal { +using namespace tbb::internal; + +template typename Set, typename T, typename... Args> +using cu_set_t = Set < + T, + std::conditional_t< (sizeof...(Args)>0) && !is_allocator_v< pack_element_t<0, Args...> >, + pack_element_t<0, Args...>, tbb_hash >, + std::conditional_t< (sizeof...(Args)>1) && !is_allocator_v< pack_element_t<1, Args...> >, + pack_element_t<1, Args...>, std::equal_to >, + std::conditional_t< (sizeof...(Args)>0) && is_allocator_v< pack_element_t >, + pack_element_t, tbb_allocator > +>; +} + +// Deduction guide for the constructor from two iterators +template +concurrent_unordered_set(I, I) +-> internal::cu_set_t>; + +// Deduction guide for the constructor from two iterators and hasher/equality/allocator +template +concurrent_unordered_set(I, I, size_t, Args...) +-> internal::cu_set_t, Args...>; + +// Deduction guide for the constructor from an initializer_list +template +concurrent_unordered_set(std::initializer_list) +-> internal::cu_set_t; + +// Deduction guide for the constructor from an initializer_list and hasher/equality/allocator +template +concurrent_unordered_set(std::initializer_list, size_t, Args...) +-> internal::cu_set_t; + +#endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ + +template , typename Key_equality = std::equal_to, + typename Allocator = tbb::tbb_allocator > +class concurrent_unordered_multiset : + public internal::concurrent_unordered_base< concurrent_unordered_set_traits, Allocator, true> > +{ + // Base type definitions + typedef internal::hash_compare hash_compare; + typedef concurrent_unordered_set_traits traits_type; + typedef internal::concurrent_unordered_base< traits_type > base_type; +#if __TBB_EXTRA_DEBUG +public: +#endif + using traits_type::allow_multimapping; +public: + using base_type::insert; + + // Type definitions + typedef Key key_type; + typedef typename base_type::value_type value_type; + typedef Key mapped_type; + typedef Hasher hasher; + typedef Key_equality key_equal; + typedef hash_compare key_compare; + + typedef typename base_type::allocator_type allocator_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::const_pointer const_pointer; + typedef typename base_type::reference reference; + typedef typename base_type::const_reference const_reference; + + typedef typename base_type::size_type size_type; + typedef typename base_type::difference_type difference_type; + + typedef typename base_type::iterator iterator; + typedef typename base_type::const_iterator const_iterator; + typedef typename base_type::iterator local_iterator; + typedef typename base_type::const_iterator const_local_iterator; +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + typedef typename base_type::node_type node_type; +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + + // Construction/destruction/copying + explicit concurrent_unordered_multiset(size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), + const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + {} + + concurrent_unordered_multiset(size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + {} + + concurrent_unordered_multiset(size_type n_of_buckets, const hasher& a_hasher, + const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + {} + + explicit concurrent_unordered_multiset(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a) + {} + + template + concurrent_unordered_multiset(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), + const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + { + insert(first, last); + } + + template + concurrent_unordered_multiset(Iterator first, Iterator last, size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + { + insert(first, last); + } + + template + concurrent_unordered_multiset(Iterator first, Iterator last, size_type n_of_buckets, const hasher& a_hasher, + const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + { + insert(first, last); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Constructor from initializer_list + concurrent_unordered_multiset(std::initializer_list il, size_type n_of_buckets = base_type::initial_bucket_number, + const hasher& a_hasher = hasher(), const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type()) + : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a) + { + insert(il.begin(),il.end()); + } + + concurrent_unordered_multiset(std::initializer_list il, size_type n_of_buckets, const allocator_type& a) + : base_type(n_of_buckets, key_compare(hasher(), key_equal()), a) + { + insert(il.begin(), il.end()); + } + + concurrent_unordered_multiset(std::initializer_list il, size_type n_of_buckets, const hasher& a_hasher, + const allocator_type& a) + : base_type(n_of_buckets, key_compare(a_hasher, key_equal()), a) + { + insert(il.begin(), il.end()); + } + +#endif //# __TBB_INITIALIZER_LISTS_PRESENT + + +#if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT + concurrent_unordered_multiset(const concurrent_unordered_multiset& table) + : base_type(table) + {} + + concurrent_unordered_multiset& operator=(const concurrent_unordered_multiset& table) + { + return static_cast(base_type::operator=(table)); + } + + concurrent_unordered_multiset(concurrent_unordered_multiset&& table) + : base_type(std::move(table)) + {} + + concurrent_unordered_multiset& operator=(concurrent_unordered_multiset&& table) + { + return static_cast(base_type::operator=(std::move(table))); + } +#endif //__TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_MOVE_PRESENT + +#if __TBB_CPP11_RVALUE_REF_PRESENT + concurrent_unordered_multiset(concurrent_unordered_multiset&& table, const Allocator& a) + : base_type(std::move(table), a) + { + } +#endif /*__TBB_CPP11_RVALUE_REF_PRESENT*/ + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + template + void merge(concurrent_unordered_set& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_set&& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_multiset& source) + { this->internal_merge(source); } + + template + void merge(concurrent_unordered_multiset&& source) + { this->internal_merge(source); } + +#endif //__TBB_UNORDERED_NODE_HANDLE_PRESENT + + concurrent_unordered_multiset(const concurrent_unordered_multiset& table, const Allocator& a) + : base_type(table, a) + {} +}; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +// Deduction guide for the constructor from two iterators +template +concurrent_unordered_multiset(I, I) +-> internal::cu_set_t>; + +// Deduction guide for the constructor from two iterators and hasher/equality/allocator +template +concurrent_unordered_multiset(I, I, size_t, Args...) +-> internal::cu_set_t, Args...>; + +// Deduction guide for the constructor from an initializer_list +template +concurrent_unordered_multiset(std::initializer_list) +-> internal::cu_set_t; + +// Deduction guide for the constructor from an initializer_list and hasher/equality/allocator +template +concurrent_unordered_multiset(std::initializer_list, size_t, Args...) +-> internal::cu_set_t; + +#endif /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ +} // namespace interface5 + +using interface5::concurrent_unordered_set; +using interface5::concurrent_unordered_multiset; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_concurrent_unordered_set_H_include_area + +#endif// __TBB_concurrent_unordered_set_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_vector.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_vector.h new file mode 100644 index 00000000..a4988aaa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/concurrent_vector.h @@ -0,0 +1,1396 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_vector_H +#define __TBB_concurrent_vector_H + +#define __TBB_concurrent_vector_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_stddef.h" +#include "tbb_exception.h" +#include "atomic.h" +#include "cache_aligned_allocator.h" +#include "blocked_range.h" +#include "tbb_machine.h" +#include "tbb_profiling.h" +#include +#include // for memset() +#include __TBB_STD_SWAP_HEADER +#include +#include + +#include "internal/_allocator_traits.h" + +#if _MSC_VER==1500 && !__INTEL_COMPILER + // VS2008/VC9 seems to have an issue; limits pull in math.h + #pragma warning( push ) + #pragma warning( disable: 4985 ) +#endif +#include /* std::numeric_limits */ +#if _MSC_VER==1500 && !__INTEL_COMPILER + #pragma warning( pop ) +#endif + +#if __TBB_INITIALIZER_LISTS_PRESENT + #include +#endif + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (push) +#if defined(_Wp64) + #pragma warning (disable: 4267) +#endif + #pragma warning (disable: 4127) //warning C4127: conditional expression is constant +#endif + +namespace tbb { + +template > +class concurrent_vector; + +//! @cond INTERNAL +namespace internal { + + template + class vector_iterator; + + //! Bad allocation marker + static void *const vector_allocation_error_flag = reinterpret_cast(size_t(63)); + + //! Exception helper function + template + void handle_unconstructed_elements(T* array, size_t n_of_elements){ + std::memset( static_cast(array), 0, n_of_elements * sizeof( T ) ); + } + + //! Base class of concurrent vector implementation. + /** @ingroup containers */ + class concurrent_vector_base_v3 { + protected: + + // Basic types declarations + typedef size_t segment_index_t; + typedef size_t size_type; + + // Using enumerations due to Mac linking problems of static const variables + enum { + // Size constants + default_initial_segments = 1, // 2 initial items + //! Number of slots for segment pointers inside the class + pointers_per_short_table = 3, // to fit into 8 words of entire structure + pointers_per_long_table = sizeof(segment_index_t) * 8 // one segment per bit + }; + + struct segment_not_used {}; + struct segment_allocated {}; + struct segment_allocation_failed {}; + + class segment_t; + class segment_value_t { + void* array; + private: + //TODO: More elegant way to grant access to selected functions _only_? + friend class segment_t; + explicit segment_value_t(void* an_array):array(an_array) {} + public: + friend bool operator==(segment_value_t const& lhs, segment_not_used ) { return lhs.array == 0;} + friend bool operator==(segment_value_t const& lhs, segment_allocated) { return lhs.array > internal::vector_allocation_error_flag;} + friend bool operator==(segment_value_t const& lhs, segment_allocation_failed) { return lhs.array == internal::vector_allocation_error_flag;} + template + friend bool operator!=(segment_value_t const& lhs, argument_type arg) { return ! (lhs == arg);} + + template + T* pointer() const { return static_cast(const_cast(array)); } + }; + + friend void enforce_segment_allocated(segment_value_t const& s, internal::exception_id exception = eid_bad_last_alloc){ + if(s != segment_allocated()){ + internal::throw_exception(exception); + } + } + + // Segment pointer. + class segment_t { + atomic array; + public: + segment_t(){ store(segment_not_used());} + //Copy ctor and assignment operator are defined to ease using of stl algorithms. + //These algorithms usually not a synchronization point, so, semantic is + //intentionally relaxed here. + segment_t(segment_t const& rhs ){ array.store(rhs.array.load());} + + void swap(segment_t & rhs ){ + tbb::internal::swap(array, rhs.array); + } + + segment_t& operator=(segment_t const& rhs ){ + array.store(rhs.array.load()); + return *this; + } + + template + segment_value_t load() const { return segment_value_t(array.load());} + + template + void store(segment_not_used) { + array.store(0); + } + + template + void store(segment_allocation_failed) { + __TBB_ASSERT(load() != segment_allocated(),"transition from \"allocated\" to \"allocation failed\" state looks non-logical"); + array.store(internal::vector_allocation_error_flag); + } + + template + void store(void* allocated_segment_pointer) __TBB_NOEXCEPT(true) { + __TBB_ASSERT(segment_value_t(allocated_segment_pointer) == segment_allocated(), + "other overloads of store should be used for marking segment as not_used or allocation_failed" ); + array.store(allocated_segment_pointer); + } + +#if TBB_USE_ASSERT + ~segment_t() { + __TBB_ASSERT(load() != segment_allocated(), "should have been freed by clear" ); + } +#endif /* TBB_USE_ASSERT */ + }; + friend void swap(segment_t & , segment_t & ) __TBB_NOEXCEPT(true); + + // Data fields + + //! allocator function pointer + void* (*vector_allocator_ptr)(concurrent_vector_base_v3 &, size_t); + + //! count of segments in the first block + atomic my_first_block; + + //! Requested size of vector + atomic my_early_size; + + //! Pointer to the segments table + atomic my_segment; + + //! embedded storage of segment pointers + segment_t my_storage[pointers_per_short_table]; + + // Methods + + concurrent_vector_base_v3() { + //Here the semantic is intentionally relaxed. + //The reason this is next: + //Object that is in middle of construction (i.e. its constructor is not yet finished) + //cannot be used concurrently until the construction is finished. + //Thus to flag other threads that construction is finished, some synchronization with + //acquire-release semantic should be done by the (external) code that uses the vector. + //So, no need to do the synchronization inside the vector. + + my_early_size.store(0); + my_first_block.store(0); // here is not default_initial_segments + my_segment.store(my_storage); + } + + __TBB_EXPORTED_METHOD ~concurrent_vector_base_v3(); + + //these helpers methods use the fact that segments are allocated so + //that every segment size is a (increasing) power of 2. + //with one exception 0 segment has size of 2 as well segment 1; + //e.g. size of segment with index of 3 is 2^3=8; + static segment_index_t segment_index_of( size_type index ) { + return segment_index_t( __TBB_Log2( index|1 ) ); + } + + static segment_index_t segment_base( segment_index_t k ) { + return (segment_index_t(1)< + friend class vector_iterator; + + }; + + inline void swap(concurrent_vector_base_v3::segment_t & lhs, concurrent_vector_base_v3::segment_t & rhs) __TBB_NOEXCEPT(true) { + lhs.swap(rhs); + } + + typedef concurrent_vector_base_v3 concurrent_vector_base; + + //! Meets requirements of a forward iterator for STL and a Value for a blocked_range.*/ + /** Value is either the T or const T type of the container. + @ingroup containers */ + template + class vector_iterator + { + //! concurrent_vector over which we are iterating. + Container* my_vector; + + //! Index into the vector + size_t my_index; + + //! Caches my_vector->internal_subscript(my_index) + /** NULL if cached value is not available */ + mutable Value* my_item; + + template + friend vector_iterator operator+( ptrdiff_t offset, const vector_iterator& v ); + + template + friend bool operator==( const vector_iterator& i, const vector_iterator& j ); + + template + friend bool operator<( const vector_iterator& i, const vector_iterator& j ); + + template + friend ptrdiff_t operator-( const vector_iterator& i, const vector_iterator& j ); + + template + friend class internal::vector_iterator; + +#if !__TBB_TEMPLATE_FRIENDS_BROKEN + template + friend class tbb::concurrent_vector; +#else +public: +#endif + + vector_iterator( const Container& vector, size_t index, void *ptr = 0 ) : + my_vector(const_cast(&vector)), + my_index(index), + my_item(static_cast(ptr)) + {} + + public: + //! Default constructor + vector_iterator() : my_vector(NULL), my_index(~size_t(0)), my_item(NULL) {} + + vector_iterator( const vector_iterator& other ) : + my_vector(other.my_vector), + my_index(other.my_index), + my_item(other.my_item) + {} + + vector_iterator& operator=( const vector_iterator& other ) + { + my_vector=other.my_vector; + my_index=other.my_index; + my_item=other.my_item; + return *this; + } + + vector_iterator operator+( ptrdiff_t offset ) const { + return vector_iterator( *my_vector, my_index+offset ); + } + vector_iterator &operator+=( ptrdiff_t offset ) { + my_index+=offset; + my_item = NULL; + return *this; + } + vector_iterator operator-( ptrdiff_t offset ) const { + return vector_iterator( *my_vector, my_index-offset ); + } + vector_iterator &operator-=( ptrdiff_t offset ) { + my_index-=offset; + my_item = NULL; + return *this; + } + Value& operator*() const { + Value* item = my_item; + if( !item ) { + item = my_item = &my_vector->internal_subscript(my_index); + } + __TBB_ASSERT( item==&my_vector->internal_subscript(my_index), "corrupt cache" ); + return *item; + } + Value& operator[]( ptrdiff_t k ) const { + return my_vector->internal_subscript(my_index+k); + } + Value* operator->() const {return &operator*();} + + //! Pre increment + vector_iterator& operator++() { + size_t element_index = ++my_index; + if( my_item ) { + //TODO: consider using of knowledge about "first_block optimization" here as well? + if( concurrent_vector_base::is_first_element_in_segment(element_index)) { + //if the iterator crosses a segment boundary, the pointer become invalid + //as possibly next segment is in another memory location + my_item= NULL; + } else { + ++my_item; + } + } + return *this; + } + + //! Pre decrement + vector_iterator& operator--() { + __TBB_ASSERT( my_index>0, "operator--() applied to iterator already at beginning of concurrent_vector" ); + size_t element_index = my_index--; + if( my_item ) { + if(concurrent_vector_base::is_first_element_in_segment(element_index)) { + //if the iterator crosses a segment boundary, the pointer become invalid + //as possibly next segment is in another memory location + my_item= NULL; + } else { + --my_item; + } + } + return *this; + } + + //! Post increment + vector_iterator operator++(int) { + vector_iterator result = *this; + operator++(); + return result; + } + + //! Post decrement + vector_iterator operator--(int) { + vector_iterator result = *this; + operator--(); + return result; + } + + // STL support + + typedef ptrdiff_t difference_type; + typedef Value value_type; + typedef Value* pointer; + typedef Value& reference; + typedef std::random_access_iterator_tag iterator_category; + }; + + template + vector_iterator operator+( ptrdiff_t offset, const vector_iterator& v ) { + return vector_iterator( *v.my_vector, v.my_index+offset ); + } + + template + bool operator==( const vector_iterator& i, const vector_iterator& j ) { + return i.my_index==j.my_index && i.my_vector == j.my_vector; + } + + template + bool operator!=( const vector_iterator& i, const vector_iterator& j ) { + return !(i==j); + } + + template + bool operator<( const vector_iterator& i, const vector_iterator& j ) { + return i.my_index + bool operator>( const vector_iterator& i, const vector_iterator& j ) { + return j + bool operator>=( const vector_iterator& i, const vector_iterator& j ) { + return !(i + bool operator<=( const vector_iterator& i, const vector_iterator& j ) { + return !(j + ptrdiff_t operator-( const vector_iterator& i, const vector_iterator& j ) { + return ptrdiff_t(i.my_index)-ptrdiff_t(j.my_index); + } + + template + class allocator_base { + public: + typedef typename tbb::internal::allocator_rebind::type allocator_type; + allocator_type my_allocator; + allocator_base(const allocator_type &a = allocator_type() ) : my_allocator(a) {} + }; + +} // namespace internal +//! @endcond + +//! Concurrent vector container +/** concurrent_vector is a container having the following main properties: + - It provides random indexed access to its elements. The index of the first element is 0. + - It ensures safe concurrent growing its size (different threads can safely append new elements). + - Adding new elements does not invalidate existing iterators and does not change indices of existing items. + +@par Compatibility + The class meets all Container Requirements and Reversible Container Requirements from + C++ Standard (See ISO/IEC 14882:2003(E), clause 23.1). But it doesn't meet + Sequence Requirements due to absence of insert() and erase() methods. + +@par Exception Safety + Methods working with memory allocation and/or new elements construction can throw an + exception if allocator fails to allocate memory or element's default constructor throws one. + Concurrent vector's element of type T must conform to the following requirements: + - Throwing an exception is forbidden for destructor of T. + - Default constructor of T must not throw an exception OR its non-virtual destructor must safely work when its object memory is zero-initialized. + . + Otherwise, the program's behavior is undefined. +@par + If an exception happens inside growth or assignment operation, an instance of the vector becomes invalid unless it is stated otherwise in the method documentation. + Invalid state means: + - There are no guarantees that all items were initialized by a constructor. The rest of items is zero-filled, including item where exception happens. + - An invalid vector instance cannot be repaired; it is unable to grow anymore. + - Size and capacity reported by the vector are incorrect, and calculated as if the failed operation were successful. + - Attempt to access not allocated elements using operator[] or iterators results in access violation or segmentation fault exception, and in case of using at() method a C++ exception is thrown. + . + If a concurrent grow operation successfully completes, all the elements it has added to the vector will remain valid and accessible even if one of subsequent grow operations fails. + +@par Fragmentation + Unlike an STL vector, a concurrent_vector does not move existing elements if it needs + to allocate more memory. The container is divided into a series of contiguous arrays of + elements. The first reservation, growth, or assignment operation determines the size of + the first array. Using small number of elements as initial size incurs fragmentation that + may increase element access time. Internal layout can be optimized by method compact() that + merges several smaller arrays into one solid. + +@par Changes since TBB 2.1 + - Fixed guarantees of concurrent_vector::size() and grow_to_at_least() methods to assure elements are allocated. + - Methods end()/rbegin()/back() are partly thread-safe since they use size() to get the end of vector + - Added resize() methods (not thread-safe) + - Added cbegin/cend/crbegin/crend methods + - Changed return type of methods grow* and push_back to iterator + +@par Changes since TBB 2.0 + - Implemented exception-safety guarantees + - Added template argument for allocator + - Added allocator argument in constructors + - Faster index calculation + - First growth call specifies a number of segments to be merged in the first allocation. + - Fixed memory blow up for swarm of vector's instances of small size + - Added grow_by(size_type n, const_reference t) growth using copying constructor to init new items. + - Added STL-like constructors. + - Added operators ==, < and derivatives + - Added at() method, approved for using after an exception was thrown inside the vector + - Added get_allocator() method. + - Added assign() methods + - Added compact() method to defragment first segments + - Added swap() method + - range() defaults on grainsize = 1 supporting auto grainsize algorithms. + + @ingroup containers */ +template +class concurrent_vector: protected internal::allocator_base, + private internal::concurrent_vector_base { +private: + template + class generic_range_type: public blocked_range { + public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef I iterator; + typedef ptrdiff_t difference_type; + generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range(begin_,end_,grainsize_) {} + template + generic_range_type( const generic_range_type& r) : blocked_range(r.begin(),r.end(),r.grainsize()) {} + generic_range_type( generic_range_type& r, split ) : blocked_range(r,split()) {} + }; + + template + friend class internal::vector_iterator; + +public: + //------------------------------------------------------------------------ + // STL compatible types + //------------------------------------------------------------------------ + typedef internal::concurrent_vector_base_v3::size_type size_type; + typedef typename internal::allocator_base::allocator_type allocator_type; + + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef T& reference; + typedef const T& const_reference; + typedef T *pointer; + typedef const T *const_pointer; + + typedef internal::vector_iterator iterator; + typedef internal::vector_iterator const_iterator; + +#if !defined(_MSC_VER) || _CPPLIB_VER>=300 + // Assume ISO standard definition of std::reverse_iterator + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#else + // Use non-standard std::reverse_iterator + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#endif /* defined(_MSC_VER) && (_MSC_VER<1300) */ + + //------------------------------------------------------------------------ + // Parallel algorithm support + //------------------------------------------------------------------------ + typedef generic_range_type range_type; + typedef generic_range_type const_range_type; + + //------------------------------------------------------------------------ + // STL compatible constructors & destructors + //------------------------------------------------------------------------ + + //! Construct empty vector. + explicit concurrent_vector(const allocator_type &a = allocator_type()) + : internal::allocator_base(a), internal::concurrent_vector_base() + { + vector_allocator_ptr = &internal_allocator; + } + + //Constructors are not required to have synchronization + //(for more details see comment in the concurrent_vector_base constructor). +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Constructor from initializer_list + concurrent_vector(std::initializer_list init_list, const allocator_type &a = allocator_type()) + : internal::allocator_base(a), internal::concurrent_vector_base() + { + vector_allocator_ptr = &internal_allocator; + __TBB_TRY { + internal_assign_iterators(init_list.begin(), init_list.end()); + } __TBB_CATCH(...) { + segment_t *table = my_segment.load();; + internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); + __TBB_RETHROW(); + } + + } +#endif //# __TBB_INITIALIZER_LISTS_PRESENT + + //! Copying constructor + concurrent_vector( const concurrent_vector& vector, const allocator_type& a = allocator_type() ) + : internal::allocator_base(a), internal::concurrent_vector_base() + { + vector_allocator_ptr = &internal_allocator; + __TBB_TRY { + internal_copy(vector, sizeof(T), ©_array); + } __TBB_CATCH(...) { + segment_t *table = my_segment.load(); + internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); + __TBB_RETHROW(); + } + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move constructor + //TODO add __TBB_NOEXCEPT(true) and static_assert(std::has_nothrow_move_constructor::value) + concurrent_vector( concurrent_vector&& source) + : internal::allocator_base(std::move(source)), internal::concurrent_vector_base() + { + vector_allocator_ptr = &internal_allocator; + concurrent_vector_base_v3::internal_swap(source); + } + + concurrent_vector( concurrent_vector&& source, const allocator_type& a) + : internal::allocator_base(a), internal::concurrent_vector_base() + { + vector_allocator_ptr = &internal_allocator; + //C++ standard requires instances of an allocator being compared for equality, + //which means that memory allocated by one instance is possible to deallocate with the other one. + if (a == source.my_allocator) { + concurrent_vector_base_v3::internal_swap(source); + } else { + __TBB_TRY { + internal_copy(source, sizeof(T), &move_array); + } __TBB_CATCH(...) { + segment_t *table = my_segment.load(); + internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load()); + __TBB_RETHROW(); + } + } + } + +#endif + + //! Copying constructor for vector with different allocator type + template + __TBB_DEPRECATED concurrent_vector( const concurrent_vector& vector, const allocator_type& a = allocator_type() ) + : internal::allocator_base(a), internal::concurrent_vector_base() + { + vector_allocator_ptr = &internal_allocator; + __TBB_TRY { + internal_copy(vector.internal_vector_base(), sizeof(T), ©_array); + } __TBB_CATCH(...) { + segment_t *table = my_segment.load(); + internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); + __TBB_RETHROW(); + } + } + + //! Construction with initial size specified by argument n + explicit concurrent_vector(size_type n) + { + vector_allocator_ptr = &internal_allocator; + __TBB_TRY { + internal_resize( n, sizeof(T), max_size(), NULL, &destroy_array, &initialize_array ); + } __TBB_CATCH(...) { + segment_t *table = my_segment.load(); + internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); + __TBB_RETHROW(); + } + } + + //! Construction with initial size specified by argument n, initialization by copying of t, and given allocator instance + concurrent_vector(size_type n, const_reference t, const allocator_type& a = allocator_type()) + : internal::allocator_base(a) + { + vector_allocator_ptr = &internal_allocator; + __TBB_TRY { + internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); + } __TBB_CATCH(...) { + segment_t *table = my_segment.load(); + internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); + __TBB_RETHROW(); + } + } + + //! Construction with copying iteration range and given allocator instance + template + concurrent_vector(I first, I last, const allocator_type &a = allocator_type()) + : internal::allocator_base(a) + { + vector_allocator_ptr = &internal_allocator; + __TBB_TRY { + internal_assign_range(first, last, static_cast::is_integer> *>(0) ); + } __TBB_CATCH(...) { + segment_t *table = my_segment.load(); + internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); + __TBB_RETHROW(); + } + } + + //! Assignment + concurrent_vector& operator=( const concurrent_vector& vector ) { + if( this != &vector ) + internal_assign(vector, sizeof(T), &destroy_array, &assign_array, ©_array); + return *this; + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //TODO: add __TBB_NOEXCEPT() + //! Move assignment + concurrent_vector& operator=( concurrent_vector&& other ) { + __TBB_ASSERT(this != &other, "Move assignment to itself is prohibited "); + typedef typename tbb::internal::allocator_traits::propagate_on_container_move_assignment pocma_t; + if(pocma_t::value || this->my_allocator == other.my_allocator) { + concurrent_vector trash (std::move(*this)); + internal_swap(other); + tbb::internal::allocator_move_assignment(this->my_allocator, other.my_allocator, pocma_t()); + } else { + internal_assign(other, sizeof(T), &destroy_array, &move_assign_array, &move_array); + } + return *this; + } +#endif + //TODO: add an template assignment operator? (i.e. with different element type) + + //! Assignment for vector with different allocator type + template + __TBB_DEPRECATED concurrent_vector& operator=( const concurrent_vector& vector ) { + if( static_cast( this ) != static_cast( &vector ) ) + internal_assign(vector.internal_vector_base(), + sizeof(T), &destroy_array, &assign_array, ©_array); + return *this; + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Assignment for initializer_list + concurrent_vector& operator=( std::initializer_list init_list ) { + internal_clear(&destroy_array); + internal_assign_iterators(init_list.begin(), init_list.end()); + return *this; + } +#endif //#if __TBB_INITIALIZER_LISTS_PRESENT + + //------------------------------------------------------------------------ + // Concurrent operations + //------------------------------------------------------------------------ + //! Grow by "delta" elements. + /** Returns iterator pointing to the first new element. */ + iterator grow_by( size_type delta ) { + return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array, NULL ) : my_early_size.load()); + } + + //! Grow by "delta" elements using copying constructor. + /** Returns iterator pointing to the first new element. */ + iterator grow_by( size_type delta, const_reference t ) { + return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array_by, static_cast(&t) ) : my_early_size.load()); + } + + /** Returns iterator pointing to the first new element. */ + template + iterator grow_by( I first, I last ) { + typename std::iterator_traits::difference_type delta = std::distance(first, last); + __TBB_ASSERT( delta >= 0, NULL); + + return iterator(*this, delta ? internal_grow_by(delta, sizeof(T), ©_range, static_cast(&first)) : my_early_size.load()); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + /** Returns iterator pointing to the first new element. */ + iterator grow_by( std::initializer_list init_list ) { + return grow_by( init_list.begin(), init_list.end() ); + } +#endif //#if __TBB_INITIALIZER_LISTS_PRESENT + + //! Append minimal sequence of elements such that size()>=n. + /** The new elements are default constructed. Blocks until all elements in range [0..n) are allocated. + May return while other elements are being constructed by other threads. + Returns iterator that points to beginning of appended sequence. + If no elements were appended, returns iterator pointing to nth element. */ + iterator grow_to_at_least( size_type n ) { + size_type m=0; + if( n ) { + m = internal_grow_to_at_least_with_result( n, sizeof(T), &initialize_array, NULL ); + if( m>n ) m=n; + } + return iterator(*this, m); + }; + + /** Analogous to grow_to_at_least( size_type n ) with exception that the new + elements are initialized by copying of t instead of default construction. */ + iterator grow_to_at_least( size_type n, const_reference t ) { + size_type m=0; + if( n ) { + m = internal_grow_to_at_least_with_result( n, sizeof(T), &initialize_array_by, &t); + if( m>n ) m=n; + } + return iterator(*this, m); + }; + + //! Push item + /** Returns iterator pointing to the new element. */ + iterator push_back( const_reference item ) + { + push_back_helper prolog(*this); + new(prolog.internal_push_back_result()) T(item); + return prolog.return_iterator_and_dismiss(); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Push item, move-aware + /** Returns iterator pointing to the new element. */ + iterator push_back( T&& item ) + { + push_back_helper prolog(*this); + new(prolog.internal_push_back_result()) T(std::move(item)); + return prolog.return_iterator_and_dismiss(); + } +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + //! Push item, create item "in place" with provided arguments + /** Returns iterator pointing to the new element. */ + template + iterator emplace_back( Args&&... args ) + { + push_back_helper prolog(*this); + new(prolog.internal_push_back_result()) T(std::forward(args)...); + return prolog.return_iterator_and_dismiss(); + } +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + //! Get reference to element at given index. + /** This method is thread-safe for concurrent reads, and also while growing the vector, + as long as the calling thread has checked that index < size(). */ + reference operator[]( size_type index ) { + return internal_subscript(index); + } + + //! Get const reference to element at given index. + const_reference operator[]( size_type index ) const { + return internal_subscript(index); + } + + //! Get reference to element at given index. Throws exceptions on errors. + reference at( size_type index ) { + return internal_subscript_with_exceptions(index); + } + + //! Get const reference to element at given index. Throws exceptions on errors. + const_reference at( size_type index ) const { + return internal_subscript_with_exceptions(index); + } + + //! Get range for iterating with parallel algorithms + range_type range( size_t grainsize = 1 ) { + return range_type( begin(), end(), grainsize ); + } + + //! Get const range for iterating with parallel algorithms + const_range_type range( size_t grainsize = 1 ) const { + return const_range_type( begin(), end(), grainsize ); + } + + //------------------------------------------------------------------------ + // Capacity + //------------------------------------------------------------------------ + //! Return size of vector. It may include elements under construction + size_type size() const { + size_type sz = my_early_size, cp = internal_capacity(); + return cp < sz ? cp : sz; + } + + //! Return false if vector is not empty or has elements under construction at least. + bool empty() const {return !my_early_size;} + + //! Maximum size to which array can grow without allocating more memory. Concurrent allocations are not included in the value. + size_type capacity() const {return internal_capacity();} + + //! Allocate enough space to grow to size n without having to allocate more memory later. + /** Like most of the methods provided for STL compatibility, this method is *not* thread safe. + The capacity afterwards may be bigger than the requested reservation. */ + void reserve( size_type n ) { + if( n ) + internal_reserve(n, sizeof(T), max_size()); + } + + //! Resize the vector. Not thread-safe. + void resize( size_type n ) { + internal_resize( n, sizeof(T), max_size(), NULL, &destroy_array, &initialize_array ); + } + + //! Resize the vector, copy t for new elements. Not thread-safe. + void resize( size_type n, const_reference t ) { + internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); + } + + //! Optimize memory usage and fragmentation. + void shrink_to_fit(); + + //! Upper bound on argument to reserve. + size_type max_size() const {return (~size_type(0))/sizeof(T);} + + //------------------------------------------------------------------------ + // STL support + //------------------------------------------------------------------------ + + //! start iterator + iterator begin() {return iterator(*this,0);} + //! end iterator + iterator end() {return iterator(*this,size());} + //! start const iterator + const_iterator begin() const {return const_iterator(*this,0);} + //! end const iterator + const_iterator end() const {return const_iterator(*this,size());} + //! start const iterator + const_iterator cbegin() const {return const_iterator(*this,0);} + //! end const iterator + const_iterator cend() const {return const_iterator(*this,size());} + //! reverse start iterator + reverse_iterator rbegin() {return reverse_iterator(end());} + //! reverse end iterator + reverse_iterator rend() {return reverse_iterator(begin());} + //! reverse start const iterator + const_reverse_iterator rbegin() const {return const_reverse_iterator(end());} + //! reverse end const iterator + const_reverse_iterator rend() const {return const_reverse_iterator(begin());} + //! reverse start const iterator + const_reverse_iterator crbegin() const {return const_reverse_iterator(end());} + //! reverse end const iterator + const_reverse_iterator crend() const {return const_reverse_iterator(begin());} + //! the first item + reference front() { + __TBB_ASSERT( size()>0, NULL); + const segment_value_t& segment_value = my_segment[0].template load(); + return (segment_value.template pointer())[0]; + } + //! the first item const + const_reference front() const { + __TBB_ASSERT( size()>0, NULL); + const segment_value_t& segment_value = my_segment[0].template load(); + return (segment_value.template pointer())[0]; + } + //! the last item + reference back() { + __TBB_ASSERT( size()>0, NULL); + return internal_subscript( size()-1 ); + } + //! the last item const + const_reference back() const { + __TBB_ASSERT( size()>0, NULL); + return internal_subscript( size()-1 ); + } + //! return allocator object + allocator_type get_allocator() const { return this->my_allocator; } + + //! assign n items by copying t item + void assign(size_type n, const_reference t) { + clear(); + internal_resize( n, sizeof(T), max_size(), static_cast(&t), &destroy_array, &initialize_array_by ); + } + + //! assign range [first, last) + template + void assign(I first, I last) { + clear(); internal_assign_range( first, last, static_cast::is_integer> *>(0) ); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! assigns an initializer list + void assign(std::initializer_list init_list) { + clear(); internal_assign_iterators( init_list.begin(), init_list.end()); + } +#endif //# __TBB_INITIALIZER_LISTS_PRESENT + + //! swap two instances + void swap(concurrent_vector &vector) { + typedef typename tbb::internal::allocator_traits::propagate_on_container_swap pocs_t; + if( this != &vector && (this->my_allocator == vector.my_allocator || pocs_t::value) ) { + concurrent_vector_base_v3::internal_swap(static_cast(vector)); + tbb::internal::allocator_swap(this->my_allocator, vector.my_allocator, pocs_t()); + } + } + + //! Clear container while keeping memory allocated. + /** To free up the memory, use in conjunction with method compact(). Not thread safe **/ + void clear() { + internal_clear(&destroy_array); + } + + //! Clear and destroy vector. + ~concurrent_vector() { + segment_t *table = my_segment.load(); + internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load() ); + // base class destructor call should be then + } + + const internal::concurrent_vector_base_v3 &internal_vector_base() const { return *this; } +private: + //! Allocate k items + static void *internal_allocator(internal::concurrent_vector_base_v3 &vb, size_t k) { + return static_cast&>(vb).my_allocator.allocate(k); + } + //! Free k segments from table + void internal_free_segments(segment_t table[], segment_index_t k, segment_index_t first_block); + + //! Get reference to element at given index. + T& internal_subscript( size_type index ) const; + + //! Get reference to element at given index with errors checks + T& internal_subscript_with_exceptions( size_type index ) const; + + //! assign n items by copying t + void internal_assign_n(size_type n, const_pointer p) { + internal_resize( n, sizeof(T), max_size(), static_cast(p), &destroy_array, p? &initialize_array_by : &initialize_array ); + } + + //! True/false function override helper + /* Functions declarations: + * void foo(is_integer_tag*); + * void foo(is_integer_tag*); + * Usage example: + * foo(static_cast::is_integer>*>(0)); + */ + template class is_integer_tag; + + //! assign integer items by copying when arguments are treated as iterators. See C++ Standard 2003 23.1.1p9 + template + void internal_assign_range(I first, I last, is_integer_tag *) { + internal_assign_n(static_cast(first), &static_cast(last)); + } + //! inline proxy assign by iterators + template + void internal_assign_range(I first, I last, is_integer_tag *) { + internal_assign_iterators(first, last); + } + //! assign by iterators + template + void internal_assign_iterators(I first, I last); + + //these functions are marked __TBB_EXPORTED_FUNC as they are called from within the library + + //! Construct n instances of T, starting at "begin". + static void __TBB_EXPORTED_FUNC initialize_array( void* begin, const void*, size_type n ); + + //! Copy-construct n instances of T, starting at "begin". + static void __TBB_EXPORTED_FUNC initialize_array_by( void* begin, const void* src, size_type n ); + + //! Copy-construct n instances of T by copying single element pointed to by src, starting at "dst". + static void __TBB_EXPORTED_FUNC copy_array( void* dst, const void* src, size_type n ); + +#if __TBB_MOVE_IF_NOEXCEPT_PRESENT + //! Either opy or move-construct n instances of T, starting at "dst" by copying according element of src array. + static void __TBB_EXPORTED_FUNC move_array_if_noexcept( void* dst, const void* src, size_type n ); +#endif //__TBB_MOVE_IF_NO_EXCEPT_PRESENT + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! Move-construct n instances of T, starting at "dst" by copying according element of src array. + static void __TBB_EXPORTED_FUNC move_array( void* dst, const void* src, size_type n ); + + //! Move-assign (using operator=) n instances of T, starting at "dst" by assigning according element of src array. + static void __TBB_EXPORTED_FUNC move_assign_array( void* dst, const void* src, size_type n ); +#endif + //! Copy-construct n instances of T, starting at "dst" by iterator range of [p_type_erased_iterator, p_type_erased_iterator+n). + template + static void __TBB_EXPORTED_FUNC copy_range( void* dst, const void* p_type_erased_iterator, size_type n ); + + //! Assign (using operator=) n instances of T, starting at "dst" by assigning according element of src array. + static void __TBB_EXPORTED_FUNC assign_array( void* dst, const void* src, size_type n ); + + //! Destroy n instances of T, starting at "begin". + static void __TBB_EXPORTED_FUNC destroy_array( void* begin, size_type n ); + + //! Exception-aware helper class for filling a segment by exception-danger operators of user class + class internal_loop_guide : internal::no_copy { + public: + const pointer array; + const size_type n; + size_type i; + + static const T* as_const_pointer(const void *ptr) { return static_cast(ptr); } + static T* as_pointer(const void *src) { return static_cast(const_cast(src)); } + + internal_loop_guide(size_type ntrials, void *ptr) + : array(as_pointer(ptr)), n(ntrials), i(0) {} + void init() { for(; i < n; ++i) new( &array[i] ) T(); } + void init(const void *src) { for(; i < n; ++i) new( &array[i] ) T(*as_const_pointer(src)); } + void copy(const void *src) { for(; i < n; ++i) new( &array[i] ) T(as_const_pointer(src)[i]); } + void assign(const void *src) { for(; i < n; ++i) array[i] = as_const_pointer(src)[i]; } +#if __TBB_CPP11_RVALUE_REF_PRESENT + void move_assign(const void *src) { for(; i < n; ++i) array[i] = std::move(as_pointer(src)[i]); } + void move_construct(const void *src) { for(; i < n; ++i) new( &array[i] ) T( std::move(as_pointer(src)[i]) ); } +#endif +#if __TBB_MOVE_IF_NOEXCEPT_PRESENT + void move_construct_if_noexcept(const void *src) { for(; i < n; ++i) new( &array[i] ) T( std::move_if_noexcept(as_pointer(src)[i]) ); } +#endif //__TBB_MOVE_IF_NOEXCEPT_PRESENT + + //TODO: rename to construct_range + template void iterate(I &src) { for(; i < n; ++i, ++src) new( &array[i] ) T( *src ); } + ~internal_loop_guide() { + if(i < n) {// if an exception was raised, fill the rest of items with zeros + internal::handle_unconstructed_elements(array+i, n-i); + } + } + }; + + struct push_back_helper : internal::no_copy{ + struct element_construction_guard : internal::no_copy{ + pointer element; + + element_construction_guard(pointer an_element) : element (an_element){} + void dismiss(){ element = NULL; } + ~element_construction_guard(){ + if (element){ + internal::handle_unconstructed_elements(element, 1); + } + } + }; + + concurrent_vector & v; + size_type k; + element_construction_guard g; + + push_back_helper(concurrent_vector & vector) : + v(vector), + g (static_cast(v.internal_push_back(sizeof(T),k))) + {} + + pointer internal_push_back_result(){ return g.element;} + iterator return_iterator_and_dismiss(){ + pointer ptr = g.element; + g.dismiss(); + return iterator(v, k, ptr); + } + }; +}; + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +// Deduction guide for the constructor from two iterators +template::value_type, + typename A = cache_aligned_allocator +> concurrent_vector(I, I, const A& = A()) +-> concurrent_vector; + +// Deduction guide for the constructor from a vector and allocator +template +concurrent_vector(const concurrent_vector &, const A2 &) +-> concurrent_vector; + +// Deduction guide for the constructor from an initializer_list +template +> concurrent_vector(std::initializer_list, const A& = A()) +-> concurrent_vector; +#endif /* __TBB_CPP17_DEDUCTION_GUIDES_PRESENT */ + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning (push) +#pragma warning (disable: 4701) // potentially uninitialized local variable "old" +#endif +template +void concurrent_vector::shrink_to_fit() { + internal_segments_table old; + __TBB_TRY { + internal_array_op2 copy_or_move_array = +#if __TBB_MOVE_IF_NOEXCEPT_PRESENT + &move_array_if_noexcept +#else + ©_array +#endif + ; + if( internal_compact( sizeof(T), &old, &destroy_array, copy_or_move_array ) ) + internal_free_segments( old.table, pointers_per_long_table, old.first_block ); // free joined and unnecessary segments + } __TBB_CATCH(...) { + if( old.first_block ) // free segment allocated for compacting. Only for support of exceptions in ctor of user T[ype] + internal_free_segments( old.table, 1, old.first_block ); + __TBB_RETHROW(); + } +} +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning (pop) +#endif // warning 4701 is back + +template +void concurrent_vector::internal_free_segments(segment_t table[], segment_index_t k, segment_index_t first_block) { + // Free the arrays + while( k > first_block ) { + --k; + segment_value_t segment_value = table[k].load(); + table[k].store(segment_not_used()); + if( segment_value == segment_allocated() ) // check for correct segment pointer + this->my_allocator.deallocate( (segment_value.pointer()), segment_size(k) ); + } + segment_value_t segment_value = table[0].load(); + if( segment_value == segment_allocated() ) { + __TBB_ASSERT( first_block > 0, NULL ); + while(k > 0) table[--k].store(segment_not_used()); + this->my_allocator.deallocate( (segment_value.pointer()), segment_size(first_block) ); + } +} + +template +T& concurrent_vector::internal_subscript( size_type index ) const { + //TODO: unify both versions of internal_subscript + __TBB_ASSERT( index < my_early_size, "index out of bounds" ); + size_type j = index; + segment_index_t k = segment_base_index_of( j ); + __TBB_ASSERT( my_segment.load() != my_storage || k < pointers_per_short_table, "index is being allocated" ); + //no need in load with acquire (load) since thread works in own space or gets + //the information about added elements via some form of external synchronization + //TODO: why not make a load of my_segment relaxed as well ? + //TODO: add an assertion that my_segment[k] is properly aligned to please ITT + segment_value_t segment_value = my_segment[k].template load(); + __TBB_ASSERT( segment_value != segment_allocation_failed(), "the instance is broken by bad allocation. Use at() instead" ); + __TBB_ASSERT( segment_value != segment_not_used(), "index is being allocated" ); + return (( segment_value.pointer()))[j]; +} + +template +T& concurrent_vector::internal_subscript_with_exceptions( size_type index ) const { + if( index >= my_early_size ) + internal::throw_exception(internal::eid_out_of_range); // throw std::out_of_range + size_type j = index; + segment_index_t k = segment_base_index_of( j ); + //TODO: refactor this condition into separate helper function, e.g. fits_into_small_table + if( my_segment.load() == my_storage && k >= pointers_per_short_table ) + internal::throw_exception(internal::eid_segment_range_error); // throw std::range_error + // no need in load with acquire (load) since thread works in own space or gets + //the information about added elements via some form of external synchronization + //TODO: why not make a load of my_segment relaxed as well ? + //TODO: add an assertion that my_segment[k] is properly aligned to please ITT + segment_value_t segment_value = my_segment[k].template load(); + enforce_segment_allocated(segment_value, internal::eid_index_range_error); + return (segment_value.pointer())[j]; +} + +template template +void concurrent_vector::internal_assign_iterators(I first, I last) { + __TBB_ASSERT(my_early_size == 0, NULL); + size_type n = std::distance(first, last); + if( !n ) return; + internal_reserve(n, sizeof(T), max_size()); + my_early_size = n; + segment_index_t k = 0; + //TODO: unify segment iteration code with concurrent_base_v3::helper + size_type sz = segment_size( my_first_block ); + while( sz < n ) { + internal_loop_guide loop(sz, my_segment[k].template load().template pointer()); + loop.iterate(first); + n -= sz; + if( !k ) k = my_first_block; + else { ++k; sz <<= 1; } + } + internal_loop_guide loop(n, my_segment[k].template load().template pointer()); + loop.iterate(first); +} + +template +void concurrent_vector::initialize_array( void* begin, const void *, size_type n ) { + internal_loop_guide loop(n, begin); loop.init(); +} + +template +void concurrent_vector::initialize_array_by( void* begin, const void *src, size_type n ) { + internal_loop_guide loop(n, begin); loop.init(src); +} + +template +void concurrent_vector::copy_array( void* dst, const void* src, size_type n ) { + internal_loop_guide loop(n, dst); loop.copy(src); +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +template +void concurrent_vector::move_array( void* dst, const void* src, size_type n ) { + internal_loop_guide loop(n, dst); loop.move_construct(src); +} +template +void concurrent_vector::move_assign_array( void* dst, const void* src, size_type n ) { + internal_loop_guide loop(n, dst); loop.move_assign(src); +} +#endif + +#if __TBB_MOVE_IF_NOEXCEPT_PRESENT +template +void concurrent_vector::move_array_if_noexcept( void* dst, const void* src, size_type n ) { + internal_loop_guide loop(n, dst); loop.move_construct_if_noexcept(src); +} +#endif //__TBB_MOVE_IF_NOEXCEPT_PRESENT + +template +template +void concurrent_vector::copy_range( void* dst, const void* p_type_erased_iterator, size_type n ){ + internal_loop_guide loop(n, dst); + loop.iterate( *(static_cast(const_cast(p_type_erased_iterator))) ); +} + +template +void concurrent_vector::assign_array( void* dst, const void* src, size_type n ) { + internal_loop_guide loop(n, dst); loop.assign(src); +} + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warning + #pragma warning (push) + #pragma warning (disable: 4189) +#endif +template +void concurrent_vector::destroy_array( void* begin, size_type n ) { + T* array = static_cast(begin); + for( size_type j=n; j>0; --j ) + array[j-1].~T(); // destructors are supposed to not throw any exceptions +} +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warning 4189 is back + +// concurrent_vector's template functions +template +inline bool operator==(const concurrent_vector &a, const concurrent_vector &b) { + //TODO: call size() only once per vector (in operator==) + // Simply: return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); + if(a.size() != b.size()) return false; + typename concurrent_vector::const_iterator i(a.begin()); + typename concurrent_vector::const_iterator j(b.begin()); + for(; i != a.end(); ++i, ++j) + if( !(*i == *j) ) return false; + return true; +} + +template +inline bool operator!=(const concurrent_vector &a, const concurrent_vector &b) +{ return !(a == b); } + +template +inline bool operator<(const concurrent_vector &a, const concurrent_vector &b) +{ return (std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())); } + +template +inline bool operator>(const concurrent_vector &a, const concurrent_vector &b) +{ return b < a; } + +template +inline bool operator<=(const concurrent_vector &a, const concurrent_vector &b) +{ return !(b < a); } + +template +inline bool operator>=(const concurrent_vector &a, const concurrent_vector &b) +{ return !(a < b); } + +template +inline void swap(concurrent_vector &a, concurrent_vector &b) +{ a.swap( b ); } + +} // namespace tbb + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warning 4267,4127 are back + + +#undef __TBB_concurrent_vector_H_include_area +#include "internal/_warning_suppress_disable_notice.h" + +#endif /* __TBB_concurrent_vector_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/critical_section.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/critical_section.h new file mode 100644 index 00000000..fb3332b2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/critical_section.h @@ -0,0 +1,147 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_critical_section_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_critical_section_H +#pragma message("TBB Warning: tbb/critical_section.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef _TBB_CRITICAL_SECTION_H_ +#define _TBB_CRITICAL_SECTION_H_ + +#define __TBB_critical_section_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#if _WIN32||_WIN64 +#include "machine/windows_api.h" +#else +#include +#include +#endif // _WIN32||WIN64 + +#include "tbb_stddef.h" +#include "tbb_thread.h" +#include "tbb_exception.h" + +#include "tbb_profiling.h" + +namespace tbb { + + namespace internal { +class critical_section_v4 : internal::no_copy { +#if _WIN32||_WIN64 + CRITICAL_SECTION my_impl; +#else + pthread_mutex_t my_impl; +#endif + tbb_thread::id my_tid; +public: + + void __TBB_EXPORTED_METHOD internal_construct(); + + critical_section_v4() { +#if _WIN32||_WIN64 + InitializeCriticalSectionEx( &my_impl, 4000, 0 ); +#else + pthread_mutex_init(&my_impl, NULL); +#endif + internal_construct(); + } + + ~critical_section_v4() { + __TBB_ASSERT(my_tid == tbb_thread::id(), "Destroying a still-held critical section"); +#if _WIN32||_WIN64 + DeleteCriticalSection(&my_impl); +#else + pthread_mutex_destroy(&my_impl); +#endif + } + + class scoped_lock : internal::no_copy { + private: + critical_section_v4 &my_crit; + public: + scoped_lock( critical_section_v4& lock_me) :my_crit(lock_me) { + my_crit.lock(); + } + + ~scoped_lock() { + my_crit.unlock(); + } + }; + + void lock() { + tbb_thread::id local_tid = this_tbb_thread::get_id(); + if(local_tid == my_tid) throw_exception( eid_improper_lock ); +#if _WIN32||_WIN64 + EnterCriticalSection( &my_impl ); +#else + int rval = pthread_mutex_lock(&my_impl); + __TBB_ASSERT_EX(!rval, "critical_section::lock: pthread_mutex_lock failed"); +#endif + __TBB_ASSERT(my_tid == tbb_thread::id(), NULL); + my_tid = local_tid; + } + + bool try_lock() { + bool gotlock; + tbb_thread::id local_tid = this_tbb_thread::get_id(); + if(local_tid == my_tid) return false; +#if _WIN32||_WIN64 + gotlock = TryEnterCriticalSection( &my_impl ) != 0; +#else + int rval = pthread_mutex_trylock(&my_impl); + // valid returns are 0 (locked) and [EBUSY] + __TBB_ASSERT(rval == 0 || rval == EBUSY, "critical_section::trylock: pthread_mutex_trylock failed"); + gotlock = rval == 0; +#endif + if(gotlock) { + my_tid = local_tid; + } + return gotlock; + } + + void unlock() { + __TBB_ASSERT(this_tbb_thread::get_id() == my_tid, "thread unlocking critical_section is not thread that locked it"); + my_tid = tbb_thread::id(); +#if _WIN32||_WIN64 + LeaveCriticalSection( &my_impl ); +#else + int rval = pthread_mutex_unlock(&my_impl); + __TBB_ASSERT_EX(!rval, "critical_section::unlock: pthread_mutex_unlock failed"); +#endif + } + + static const bool is_rw_mutex = false; + static const bool is_recursive_mutex = false; + static const bool is_fair_mutex = true; +}; // critical_section_v4 +} // namespace internal +__TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::critical_section is deprecated, use std::mutex") typedef internal::critical_section_v4 critical_section; + +__TBB_DEFINE_PROFILING_SET_NAME(critical_section) +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_critical_section_H_include_area + +#endif // _TBB_CRITICAL_SECTION_H_ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/enumerable_thread_specific.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/enumerable_thread_specific.h new file mode 100644 index 00000000..248597f2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/enumerable_thread_specific.h @@ -0,0 +1,1173 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_enumerable_thread_specific_H +#define __TBB_enumerable_thread_specific_H + +#define __TBB_enumerable_thread_specific_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "atomic.h" +#include "concurrent_vector.h" +#include "tbb_thread.h" +#include "tbb_allocator.h" +#include "cache_aligned_allocator.h" +#include "aligned_space.h" +#include "internal/_template_helpers.h" +#include "internal/_tbb_hash_compare_impl.h" +#include "tbb_profiling.h" +#include // for memcpy + +#if __TBB_PREVIEW_RESUMABLE_TASKS +#include "task.h" // for task::suspend_point +#endif + +#if _WIN32||_WIN64 +#include "machine/windows_api.h" +#else +#include +#endif + +#define __TBB_ETS_USE_CPP11 \ + (__TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT \ + && __TBB_CPP11_DECLTYPE_PRESENT && __TBB_CPP11_LAMBDAS_PRESENT) + +namespace tbb { + +//! enum for selecting between single key and key-per-instance versions +enum ets_key_usage_type { + ets_key_per_instance + , ets_no_key +#if __TBB_PREVIEW_RESUMABLE_TASKS + , ets_suspend_aware +#endif +}; + +namespace interface6 { + + // Forward declaration to use in internal classes + template + class enumerable_thread_specific; + + //! @cond + namespace internal { + + using namespace tbb::internal; + + template + struct ets_key_selector { + typedef tbb_thread::id key_type; + static key_type current_key() { + return tbb::internal::thread_get_id_v3(); + } + }; + +#if __TBB_PREVIEW_RESUMABLE_TASKS + template <> + struct ets_key_selector { + typedef task::suspend_point key_type; + static key_type current_key() { + return internal_current_suspend_point(); + } + }; + + inline task::suspend_point atomic_compare_and_swap(task::suspend_point& location, + const task::suspend_point& value, const task::suspend_point& comparand) { + return as_atomic(location).compare_and_swap(value, comparand); + } +#endif + + template + class ets_base: tbb::internal::no_copy { + protected: + typedef typename ets_key_selector::key_type key_type; +#if __TBB_PROTECTED_NESTED_CLASS_BROKEN + public: +#endif + struct slot; + + struct array { + array* next; + size_t lg_size; + slot& at( size_t k ) { + return ((slot*)(void*)(this+1))[k]; + } + size_t size() const {return size_t(1)<>(8*sizeof(size_t)-lg_size); + } + }; + struct slot { + key_type key; + void* ptr; + bool empty() const {return key == key_type();} + bool match( key_type k ) const {return key == k;} + bool claim( key_type k ) { + // TODO: maybe claim ptr, because key_type is not guaranteed to fit into word size + return atomic_compare_and_swap(key, k, key_type()) == key_type(); + } + }; +#if __TBB_PROTECTED_NESTED_CLASS_BROKEN + protected: +#endif + + //! Root of linked list of arrays of decreasing size. + /** NULL if and only if my_count==0. + Each array in the list is half the size of its predecessor. */ + atomic my_root; + atomic my_count; + virtual void* create_local() = 0; + virtual void* create_array(size_t _size) = 0; // _size in bytes + virtual void free_array(void* ptr, size_t _size) = 0; // _size in bytes + array* allocate( size_t lg_size ) { + size_t n = size_t(1)<(create_array( sizeof(array)+n*sizeof(slot) )); + a->lg_size = lg_size; + std::memset( a+1, 0, n*sizeof(slot) ); + return a; + } + void free(array* a) { + size_t n = size_t(1)<<(a->lg_size); + free_array( (void *)a, size_t(sizeof(array)+n*sizeof(slot)) ); + } + + ets_base() {my_root=NULL; my_count=0;} + virtual ~ets_base(); // g++ complains if this is not virtual + void* table_lookup( bool& exists ); + void table_clear(); + // The following functions are not used in concurrent context, + // so we don't need synchronization and ITT annotations there. + template + void table_elementwise_copy( const ets_base& other, + void*(*add_element)(ets_base&, void*) ) { + __TBB_ASSERT(!my_root,NULL); + __TBB_ASSERT(!my_count,NULL); + if( !other.my_root ) return; + array* root = my_root = allocate(other.my_root->lg_size); + root->next = NULL; + my_count = other.my_count; + size_t mask = root->mask(); + for( array* r=other.my_root; r; r=r->next ) { + for( size_t i=0; isize(); ++i ) { + slot& s1 = r->at(i); + if( !s1.empty() ) { + for( size_t j = root->start(tbb::tbb_hash()(s1.key)); ; j=(j+1)&mask ) { + slot& s2 = root->at(j); + if( s2.empty() ) { + s2.ptr = add_element(static_cast&>(*this), s1.ptr); + s2.key = s1.key; + break; + } + else if( s2.match(s1.key) ) + break; + } + } + } + } + } + void table_swap( ets_base& other ) { + __TBB_ASSERT(this!=&other, "Don't swap an instance with itself"); + tbb::internal::swap(my_root, other.my_root); + tbb::internal::swap(my_count, other.my_count); + } + }; + + template + ets_base::~ets_base() { + __TBB_ASSERT(!my_root, NULL); + } + + template + void ets_base::table_clear() { + while( array* r = my_root ) { + my_root = r->next; + free(r); + } + my_count = 0; + } + + template + void* ets_base::table_lookup( bool& exists ) { + const key_type k = ets_key_selector::current_key(); + + __TBB_ASSERT(k != key_type(),NULL); + void* found; + size_t h = tbb::tbb_hash()(k); + for( array* r=my_root; r; r=r->next ) { + call_itt_notify(acquired,r); + size_t mask=r->mask(); + for(size_t i = r->start(h); ;i=(i+1)&mask) { + slot& s = r->at(i); + if( s.empty() ) break; + if( s.match(k) ) { + if( r==my_root ) { + // Success at top level + exists = true; + return s.ptr; + } else { + // Success at some other level. Need to insert at top level. + exists = true; + found = s.ptr; + goto insert; + } + } + } + } + // Key does not yet exist. The density of slots in the table does not exceed 0.5, + // for if this will occur a new table is allocated with double the current table + // size, which is swapped in as the new root table. So an empty slot is guaranteed. + exists = false; + found = create_local(); + { + size_t c = ++my_count; + array* r = my_root; + call_itt_notify(acquired,r); + if( !r || c>r->size()/2 ) { + size_t s = r ? r->lg_size : 2; + while( c>size_t(1)<<(s-1) ) ++s; + array* a = allocate(s); + for(;;) { + a->next = r; + call_itt_notify(releasing,a); + array* new_r = my_root.compare_and_swap(a,r); + if( new_r==r ) break; + call_itt_notify(acquired, new_r); + if( new_r->lg_size>=s ) { + // Another thread inserted an equal or bigger array, so our array is superfluous. + free(a); + break; + } + r = new_r; + } + } + } + insert: + // Whether a slot has been found in an older table, or if it has been inserted at this level, + // it has already been accounted for in the total. Guaranteed to be room for it, and it is + // not present, so search for empty slot and use it. + array* ir = my_root; + call_itt_notify(acquired, ir); + size_t mask = ir->mask(); + for(size_t i = ir->start(h);;i=(i+1)&mask) { + slot& s = ir->at(i); + if( s.empty() ) { + if( s.claim(k) ) { + s.ptr = found; + return found; + } + } + } + } + + //! Specialization that exploits native TLS + template <> + class ets_base: public ets_base { + typedef ets_base super; +#if _WIN32||_WIN64 +#if __TBB_WIN8UI_SUPPORT + typedef DWORD tls_key_t; + void create_key() { my_key = FlsAlloc(NULL); } + void destroy_key() { FlsFree(my_key); } + void set_tls(void * value) { FlsSetValue(my_key, (LPVOID)value); } + void* get_tls() { return (void *)FlsGetValue(my_key); } +#else + typedef DWORD tls_key_t; + void create_key() { my_key = TlsAlloc(); } + void destroy_key() { TlsFree(my_key); } + void set_tls(void * value) { TlsSetValue(my_key, (LPVOID)value); } + void* get_tls() { return (void *)TlsGetValue(my_key); } +#endif +#else + typedef pthread_key_t tls_key_t; + void create_key() { pthread_key_create(&my_key, NULL); } + void destroy_key() { pthread_key_delete(my_key); } + void set_tls( void * value ) const { pthread_setspecific(my_key, value); } + void* get_tls() const { return pthread_getspecific(my_key); } +#endif + tls_key_t my_key; + virtual void* create_local() __TBB_override = 0; + virtual void* create_array(size_t _size) __TBB_override = 0; // _size in bytes + virtual void free_array(void* ptr, size_t _size) __TBB_override = 0; // size in bytes + protected: + ets_base() {create_key();} + ~ets_base() {destroy_key();} + void* table_lookup( bool& exists ) { + void* found = get_tls(); + if( found ) { + exists=true; + } else { + found = super::table_lookup(exists); + set_tls(found); + } + return found; + } + void table_clear() { + destroy_key(); + create_key(); + super::table_clear(); + } + void table_swap( ets_base& other ) { + using std::swap; + __TBB_ASSERT(this!=&other, "Don't swap an instance with itself"); + swap(my_key, other.my_key); + super::table_swap(other); + } + }; + + //! Random access iterator for traversing the thread local copies. + template< typename Container, typename Value > + class enumerable_thread_specific_iterator +#if defined(_WIN64) && defined(_MSC_VER) + // Ensure that Microsoft's internal template function _Val_type works correctly. + : public std::iterator +#endif /* defined(_WIN64) && defined(_MSC_VER) */ + { + //! current position in the concurrent_vector + + Container *my_container; + typename Container::size_type my_index; + mutable Value *my_value; + + template + friend enumerable_thread_specific_iterator + operator+( ptrdiff_t offset, const enumerable_thread_specific_iterator& v ); + + template + friend bool operator==( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ); + + template + friend bool operator<( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ); + + template + friend ptrdiff_t operator-( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ); + + template + friend class enumerable_thread_specific_iterator; + + public: + + enumerable_thread_specific_iterator( const Container &container, typename Container::size_type index ) : + my_container(&const_cast(container)), my_index(index), my_value(NULL) {} + + //! Default constructor + enumerable_thread_specific_iterator() : my_container(NULL), my_index(0), my_value(NULL) {} + + template + enumerable_thread_specific_iterator( const enumerable_thread_specific_iterator& other ) : + my_container( other.my_container ), my_index( other.my_index), my_value( const_cast(other.my_value) ) {} + + enumerable_thread_specific_iterator operator+( ptrdiff_t offset ) const { + return enumerable_thread_specific_iterator(*my_container, my_index + offset); + } + + enumerable_thread_specific_iterator &operator+=( ptrdiff_t offset ) { + my_index += offset; + my_value = NULL; + return *this; + } + + enumerable_thread_specific_iterator operator-( ptrdiff_t offset ) const { + return enumerable_thread_specific_iterator( *my_container, my_index-offset ); + } + + enumerable_thread_specific_iterator &operator-=( ptrdiff_t offset ) { + my_index -= offset; + my_value = NULL; + return *this; + } + + Value& operator*() const { + Value* value = my_value; + if( !value ) { + value = my_value = (*my_container)[my_index].value(); + } + __TBB_ASSERT( value==(*my_container)[my_index].value(), "corrupt cache" ); + return *value; + } + + Value& operator[]( ptrdiff_t k ) const { + return (*my_container)[my_index + k].value; + } + + Value* operator->() const {return &operator*();} + + enumerable_thread_specific_iterator& operator++() { + ++my_index; + my_value = NULL; + return *this; + } + + enumerable_thread_specific_iterator& operator--() { + --my_index; + my_value = NULL; + return *this; + } + + //! Post increment + enumerable_thread_specific_iterator operator++(int) { + enumerable_thread_specific_iterator result = *this; + ++my_index; + my_value = NULL; + return result; + } + + //! Post decrement + enumerable_thread_specific_iterator operator--(int) { + enumerable_thread_specific_iterator result = *this; + --my_index; + my_value = NULL; + return result; + } + + // STL support + typedef ptrdiff_t difference_type; + typedef Value value_type; + typedef Value* pointer; + typedef Value& reference; + typedef std::random_access_iterator_tag iterator_category; + }; + + template + enumerable_thread_specific_iterator + operator+( ptrdiff_t offset, const enumerable_thread_specific_iterator& v ) { + return enumerable_thread_specific_iterator( v.my_container, v.my_index + offset ); + } + + template + bool operator==( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ) { + return i.my_index==j.my_index && i.my_container == j.my_container; + } + + template + bool operator!=( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ) { + return !(i==j); + } + + template + bool operator<( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ) { + return i.my_index + bool operator>( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ) { + return j + bool operator>=( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ) { + return !(i + bool operator<=( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ) { + return !(j + ptrdiff_t operator-( const enumerable_thread_specific_iterator& i, + const enumerable_thread_specific_iterator& j ) { + return i.my_index-j.my_index; + } + + template + class segmented_iterator +#if defined(_WIN64) && defined(_MSC_VER) + : public std::iterator +#endif + { + template + friend bool operator==(const segmented_iterator& i, const segmented_iterator& j); + + template + friend bool operator!=(const segmented_iterator& i, const segmented_iterator& j); + + template + friend class segmented_iterator; + + public: + + segmented_iterator() {my_segcont = NULL;} + + segmented_iterator( const SegmentedContainer& _segmented_container ) : + my_segcont(const_cast(&_segmented_container)), + outer_iter(my_segcont->end()) { } + + ~segmented_iterator() {} + + typedef typename SegmentedContainer::iterator outer_iterator; + typedef typename SegmentedContainer::value_type InnerContainer; + typedef typename InnerContainer::iterator inner_iterator; + + // STL support + typedef ptrdiff_t difference_type; + typedef Value value_type; + typedef typename SegmentedContainer::size_type size_type; + typedef Value* pointer; + typedef Value& reference; + typedef std::input_iterator_tag iterator_category; + + // Copy Constructor + template + segmented_iterator(const segmented_iterator& other) : + my_segcont(other.my_segcont), + outer_iter(other.outer_iter), + // can we assign a default-constructed iterator to inner if we're at the end? + inner_iter(other.inner_iter) + {} + + // assignment + template + segmented_iterator& operator=( const segmented_iterator& other) { + if(this != &other) { + my_segcont = other.my_segcont; + outer_iter = other.outer_iter; + if(outer_iter != my_segcont->end()) inner_iter = other.inner_iter; + } + return *this; + } + + // allow assignment of outer iterator to segmented iterator. Once it is + // assigned, move forward until a non-empty inner container is found or + // the end of the outer container is reached. + segmented_iterator& operator=(const outer_iterator& new_outer_iter) { + __TBB_ASSERT(my_segcont != NULL, NULL); + // check that this iterator points to something inside the segmented container + for(outer_iter = new_outer_iter ;outer_iter!=my_segcont->end(); ++outer_iter) { + if( !outer_iter->empty() ) { + inner_iter = outer_iter->begin(); + break; + } + } + return *this; + } + + // pre-increment + segmented_iterator& operator++() { + advance_me(); + return *this; + } + + // post-increment + segmented_iterator operator++(int) { + segmented_iterator tmp = *this; + operator++(); + return tmp; + } + + bool operator==(const outer_iterator& other_outer) const { + __TBB_ASSERT(my_segcont != NULL, NULL); + return (outer_iter == other_outer && + (outer_iter == my_segcont->end() || inner_iter == outer_iter->begin())); + } + + bool operator!=(const outer_iterator& other_outer) const { + return !operator==(other_outer); + + } + + // (i)* RHS + reference operator*() const { + __TBB_ASSERT(my_segcont != NULL, NULL); + __TBB_ASSERT(outer_iter != my_segcont->end(), "Dereferencing a pointer at end of container"); + __TBB_ASSERT(inner_iter != outer_iter->end(), NULL); // should never happen + return *inner_iter; + } + + // i-> + pointer operator->() const { return &operator*();} + + private: + SegmentedContainer* my_segcont; + outer_iterator outer_iter; + inner_iterator inner_iter; + + void advance_me() { + __TBB_ASSERT(my_segcont != NULL, NULL); + __TBB_ASSERT(outer_iter != my_segcont->end(), NULL); // not true if there are no inner containers + __TBB_ASSERT(inner_iter != outer_iter->end(), NULL); // not true if the inner containers are all empty. + ++inner_iter; + while(inner_iter == outer_iter->end() && ++outer_iter != my_segcont->end()) { + inner_iter = outer_iter->begin(); + } + } + }; // segmented_iterator + + template + bool operator==( const segmented_iterator& i, + const segmented_iterator& j ) { + if(i.my_segcont != j.my_segcont) return false; + if(i.my_segcont == NULL) return true; + if(i.outer_iter != j.outer_iter) return false; + if(i.outer_iter == i.my_segcont->end()) return true; + return i.inner_iter == j.inner_iter; + } + + // != + template + bool operator!=( const segmented_iterator& i, + const segmented_iterator& j ) { + return !(i==j); + } + + template + struct construct_by_default: tbb::internal::no_assign { + void construct(void*where) {new(where) T();} // C++ note: the () in T() ensure zero initialization. + construct_by_default( int ) {} + }; + + template + struct construct_by_exemplar: tbb::internal::no_assign { + const T exemplar; + void construct(void*where) {new(where) T(exemplar);} + construct_by_exemplar( const T& t ) : exemplar(t) {} +#if __TBB_ETS_USE_CPP11 + construct_by_exemplar( T&& t ) : exemplar(std::move(t)) {} +#endif + }; + + template + struct construct_by_finit: tbb::internal::no_assign { + Finit f; + void construct(void* where) {new(where) T(f());} + construct_by_finit( const Finit& f_ ) : f(f_) {} +#if __TBB_ETS_USE_CPP11 + construct_by_finit( Finit&& f_ ) : f(std::move(f_)) {} +#endif + }; + +#if __TBB_ETS_USE_CPP11 + template + struct construct_by_args: tbb::internal::no_assign { + internal::stored_pack pack; + void construct(void* where) { + internal::call( [where](const typename strip

::type&... args ){ + new(where) T(args...); + }, pack ); + } + construct_by_args( P&& ... args ) : pack(std::forward

(args)...) {} + }; +#endif + + // storage for initialization function pointer + // TODO: consider removing the template parameter T here and in callback_leaf + template + class callback_base { + public: + // Clone *this + virtual callback_base* clone() const = 0; + // Destruct and free *this + virtual void destroy() = 0; + // Need virtual destructor to satisfy GCC compiler warning + virtual ~callback_base() { } + // Construct T at where + virtual void construct(void* where) = 0; + }; + + template + class callback_leaf: public callback_base, Constructor { +#if __TBB_ETS_USE_CPP11 + template callback_leaf( P&& ... params ) : Constructor(std::forward

(params)...) {} +#else + template callback_leaf( const X& x ) : Constructor(x) {} +#endif + // TODO: make the construction/destruction consistent (use allocator.construct/destroy) + typedef typename tbb::tbb_allocator my_allocator_type; + + callback_base* clone() const __TBB_override { + return make(*this); + } + + void destroy() __TBB_override { + my_allocator_type().destroy(this); + my_allocator_type().deallocate(this,1); + } + + void construct(void* where) __TBB_override { + Constructor::construct(where); + } + public: +#if __TBB_ETS_USE_CPP11 + template + static callback_base* make( P&& ... params ) { + void* where = my_allocator_type().allocate(1); + return new(where) callback_leaf( std::forward

(params)... ); + } +#else + template + static callback_base* make( const X& x ) { + void* where = my_allocator_type().allocate(1); + return new(where) callback_leaf(x); + } +#endif + }; + + //! Template for recording construction of objects in table + /** All maintenance of the space will be done explicitly on push_back, + and all thread local copies must be destroyed before the concurrent + vector is deleted. + + The flag is_built is initialized to false. When the local is + successfully-constructed, set the flag to true or call value_committed(). + If the constructor throws, the flag will be false. + */ + template + struct ets_element { + tbb::aligned_space my_space; + bool is_built; + ets_element() { is_built = false; } // not currently-built + U* value() { return my_space.begin(); } + U* value_committed() { is_built = true; return my_space.begin(); } + ~ets_element() { + if(is_built) { + my_space.begin()->~U(); + is_built = false; + } + } + }; + + // A predicate that can be used for a compile-time compatibility check of ETS instances + // Ideally, it should have been declared inside the ETS class, but unfortunately + // in that case VS2013 does not enable the variadic constructor. + template struct is_compatible_ets { static const bool value = false; }; + template + struct is_compatible_ets< T, enumerable_thread_specific > { static const bool value = internal::is_same_type::value; }; + +#if __TBB_ETS_USE_CPP11 + // A predicate that checks whether, for a variable 'foo' of type T, foo() is a valid expression + template + class is_callable_no_args { + private: + typedef char yes[1]; + typedef char no [2]; + + template static yes& decide( decltype(declval()())* ); + template static no& decide(...); + public: + static const bool value = (sizeof(decide(NULL)) == sizeof(yes)); + }; +#endif + + } // namespace internal + //! @endcond + + //! The enumerable_thread_specific container + /** enumerable_thread_specific has the following properties: + - thread-local copies are lazily created, with default, exemplar or function initialization. + - thread-local copies do not move (during lifetime, and excepting clear()) so the address of a copy is invariant. + - the contained objects need not have operator=() defined if combine is not used. + - enumerable_thread_specific containers may be copy-constructed or assigned. + - thread-local copies can be managed by hash-table, or can be accessed via TLS storage for speed. + - outside of parallel contexts, the contents of all thread-local copies are accessible by iterator or using combine or combine_each methods + + @par Segmented iterator + When the thread-local objects are containers with input_iterators defined, a segmented iterator may + be used to iterate over all the elements of all thread-local copies. + + @par combine and combine_each + - Both methods are defined for enumerable_thread_specific. + - combine() requires the type T have operator=() defined. + - neither method modifies the contents of the object (though there is no guarantee that the applied methods do not modify the object.) + - Both are evaluated in serial context (the methods are assumed to be non-benign.) + + @ingroup containers */ + template , + ets_key_usage_type ETS_key_type=ets_no_key > + class enumerable_thread_specific: internal::ets_base { + + template friend class enumerable_thread_specific; + + typedef internal::padded< internal::ets_element > padded_element; + + //! A generic range, used to create range objects from the iterators + template + class generic_range_type: public blocked_range { + public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef I iterator; + typedef ptrdiff_t difference_type; + generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range(begin_,end_,grainsize_) {} + template + generic_range_type( const generic_range_type& r) : blocked_range(r.begin(),r.end(),r.grainsize()) {} + generic_range_type( generic_range_type& r, split ) : blocked_range(r,split()) {} + }; + + typedef typename Allocator::template rebind< padded_element >::other padded_allocator_type; + typedef tbb::concurrent_vector< padded_element, padded_allocator_type > internal_collection_type; + + internal::callback_base *my_construct_callback; + + internal_collection_type my_locals; + + // TODO: consider unifying the callback mechanism for all create_local* methods below + // (likely non-compatible and requires interface version increase) + void* create_local() __TBB_override { + padded_element& lref = *my_locals.grow_by(1); + my_construct_callback->construct(lref.value()); + return lref.value_committed(); + } + + static void* create_local_by_copy( internal::ets_base& base, void* p ) { + enumerable_thread_specific& ets = static_cast(base); + padded_element& lref = *ets.my_locals.grow_by(1); + new(lref.value()) T(*static_cast(p)); + return lref.value_committed(); + } + +#if __TBB_ETS_USE_CPP11 + static void* create_local_by_move( internal::ets_base& base, void* p ) { + enumerable_thread_specific& ets = static_cast(base); + padded_element& lref = *ets.my_locals.grow_by(1); + new(lref.value()) T(std::move(*static_cast(p))); + return lref.value_committed(); + } +#endif + + typedef typename Allocator::template rebind< uintptr_t >::other array_allocator_type; + + // _size is in bytes + void* create_array(size_t _size) __TBB_override { + size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t); + return array_allocator_type().allocate(nelements); + } + + void free_array( void* _ptr, size_t _size) __TBB_override { + size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t); + array_allocator_type().deallocate( reinterpret_cast(_ptr),nelements); + } + + public: + + //! Basic types + typedef Allocator allocator_type; + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; + typedef typename internal_collection_type::size_type size_type; + typedef typename internal_collection_type::difference_type difference_type; + + // Iterator types + typedef typename internal::enumerable_thread_specific_iterator< internal_collection_type, value_type > iterator; + typedef typename internal::enumerable_thread_specific_iterator< internal_collection_type, const value_type > const_iterator; + + // Parallel range types + typedef generic_range_type< iterator > range_type; + typedef generic_range_type< const_iterator > const_range_type; + + //! Default constructor. Each local instance of T is default constructed. + enumerable_thread_specific() : my_construct_callback( + internal::callback_leaf >::make(/*dummy argument*/0) + ){} + + //! Constructor with initializer functor. Each local instance of T is constructed by T(finit()). + template ::type>::value>::type +#endif + > + explicit enumerable_thread_specific( Finit finit ) : my_construct_callback( + internal::callback_leaf >::make( tbb::internal::move(finit) ) + ){} + + //! Constructor with exemplar. Each local instance of T is copy-constructed from the exemplar. + explicit enumerable_thread_specific( const T& exemplar ) : my_construct_callback( + internal::callback_leaf >::make( exemplar ) + ){} + +#if __TBB_ETS_USE_CPP11 + explicit enumerable_thread_specific( T&& exemplar ) : my_construct_callback( + internal::callback_leaf >::make( std::move(exemplar) ) + ){} + + //! Variadic constructor with initializer arguments. Each local instance of T is constructed by T(args...) + template ::type>::value + && !internal::is_compatible_ets::type>::value + && !internal::is_same_type::type>::value + >::type> + enumerable_thread_specific( P1&& arg1, P&& ... args ) : my_construct_callback( + internal::callback_leaf >::make( std::forward(arg1), std::forward

(args)... ) + ){} +#endif + + //! Destructor + ~enumerable_thread_specific() { + if(my_construct_callback) my_construct_callback->destroy(); + // Deallocate the hash table before overridden free_array() becomes inaccessible + this->internal::ets_base::table_clear(); + } + + //! returns reference to local, discarding exists + reference local() { + bool exists; + return local(exists); + } + + //! Returns reference to calling thread's local copy, creating one if necessary + reference local(bool& exists) { + void* ptr = this->table_lookup(exists); + return *(T*)ptr; + } + + //! Get the number of local copies + size_type size() const { return my_locals.size(); } + + //! true if there have been no local copies created + bool empty() const { return my_locals.empty(); } + + //! begin iterator + iterator begin() { return iterator( my_locals, 0 ); } + //! end iterator + iterator end() { return iterator(my_locals, my_locals.size() ); } + + //! begin const iterator + const_iterator begin() const { return const_iterator(my_locals, 0); } + + //! end const iterator + const_iterator end() const { return const_iterator(my_locals, my_locals.size()); } + + //! Get range for parallel algorithms + range_type range( size_t grainsize=1 ) { return range_type( begin(), end(), grainsize ); } + + //! Get const range for parallel algorithms + const_range_type range( size_t grainsize=1 ) const { return const_range_type( begin(), end(), grainsize ); } + + //! Destroys local copies + void clear() { + my_locals.clear(); + this->table_clear(); + // callback is not destroyed + } + + private: + + template + void internal_copy(const enumerable_thread_specific& other) { +#if __TBB_ETS_USE_CPP11 && TBB_USE_ASSERT + // this tests is_compatible_ets + __TBB_STATIC_ASSERT( (internal::is_compatible_ets::type>::value), "is_compatible_ets fails" ); +#endif + // Initialize my_construct_callback first, so that it is valid even if rest of this routine throws an exception. + my_construct_callback = other.my_construct_callback->clone(); + __TBB_ASSERT(my_locals.size()==0,NULL); + my_locals.reserve(other.size()); + this->table_elementwise_copy( other, create_local_by_copy ); + } + + void internal_swap(enumerable_thread_specific& other) { + using std::swap; + __TBB_ASSERT( this!=&other, NULL ); + swap(my_construct_callback, other.my_construct_callback); + // concurrent_vector::swap() preserves storage space, + // so addresses to the vector kept in ETS hash table remain valid. + swap(my_locals, other.my_locals); + this->internal::ets_base::table_swap(other); + } + +#if __TBB_ETS_USE_CPP11 + template + void internal_move(enumerable_thread_specific&& other) { +#if TBB_USE_ASSERT + // this tests is_compatible_ets + __TBB_STATIC_ASSERT( (internal::is_compatible_ets::type>::value), "is_compatible_ets fails" ); +#endif + my_construct_callback = other.my_construct_callback; + other.my_construct_callback = NULL; + __TBB_ASSERT(my_locals.size()==0,NULL); + my_locals.reserve(other.size()); + this->table_elementwise_copy( other, create_local_by_move ); + } +#endif + + public: + + enumerable_thread_specific( const enumerable_thread_specific& other ) + : internal::ets_base() /* prevents GCC warnings with -Wextra */ + { + internal_copy(other); + } + + template + enumerable_thread_specific( const enumerable_thread_specific& other ) + { + internal_copy(other); + } + +#if __TBB_ETS_USE_CPP11 + enumerable_thread_specific( enumerable_thread_specific&& other ) : my_construct_callback() + { + internal_swap(other); + } + + template + enumerable_thread_specific( enumerable_thread_specific&& other ) : my_construct_callback() + { + internal_move(std::move(other)); + } +#endif + + enumerable_thread_specific& operator=( const enumerable_thread_specific& other ) + { + if( this != &other ) { + this->clear(); + my_construct_callback->destroy(); + internal_copy( other ); + } + return *this; + } + + template + enumerable_thread_specific& operator=( const enumerable_thread_specific& other ) + { + __TBB_ASSERT( static_cast(this)!=static_cast(&other), NULL ); // Objects of different types + this->clear(); + my_construct_callback->destroy(); + internal_copy(other); + return *this; + } + +#if __TBB_ETS_USE_CPP11 + enumerable_thread_specific& operator=( enumerable_thread_specific&& other ) + { + if( this != &other ) + internal_swap(other); + return *this; + } + + template + enumerable_thread_specific& operator=( enumerable_thread_specific&& other ) + { + __TBB_ASSERT( static_cast(this)!=static_cast(&other), NULL ); // Objects of different types + this->clear(); + my_construct_callback->destroy(); + internal_move(std::move(other)); + return *this; + } +#endif + + // combine_func_t has signature T(T,T) or T(const T&, const T&) + template + T combine(combine_func_t f_combine) { + if(begin() == end()) { + internal::ets_element location; + my_construct_callback->construct(location.value()); + return *location.value_committed(); + } + const_iterator ci = begin(); + T my_result = *ci; + while(++ci != end()) + my_result = f_combine( my_result, *ci ); + return my_result; + } + + // combine_func_t takes T by value or by [const] reference, and returns nothing + template + void combine_each(combine_func_t f_combine) { + for(iterator ci = begin(); ci != end(); ++ci) { + f_combine( *ci ); + } + } + + }; // enumerable_thread_specific + + template< typename Container > + class flattened2d { + + // This intermediate typedef is to address issues with VC7.1 compilers + typedef typename Container::value_type conval_type; + + public: + + //! Basic types + typedef typename conval_type::size_type size_type; + typedef typename conval_type::difference_type difference_type; + typedef typename conval_type::allocator_type allocator_type; + typedef typename conval_type::value_type value_type; + typedef typename conval_type::reference reference; + typedef typename conval_type::const_reference const_reference; + typedef typename conval_type::pointer pointer; + typedef typename conval_type::const_pointer const_pointer; + + typedef typename internal::segmented_iterator iterator; + typedef typename internal::segmented_iterator const_iterator; + + flattened2d( const Container &c, typename Container::const_iterator b, typename Container::const_iterator e ) : + my_container(const_cast(&c)), my_begin(b), my_end(e) { } + + explicit flattened2d( const Container &c ) : + my_container(const_cast(&c)), my_begin(c.begin()), my_end(c.end()) { } + + iterator begin() { return iterator(*my_container) = my_begin; } + iterator end() { return iterator(*my_container) = my_end; } + const_iterator begin() const { return const_iterator(*my_container) = my_begin; } + const_iterator end() const { return const_iterator(*my_container) = my_end; } + + size_type size() const { + size_type tot_size = 0; + for(typename Container::const_iterator i = my_begin; i != my_end; ++i) { + tot_size += i->size(); + } + return tot_size; + } + + private: + + Container *my_container; + typename Container::const_iterator my_begin; + typename Container::const_iterator my_end; + + }; + + template + flattened2d flatten2d(const Container &c, const typename Container::const_iterator b, const typename Container::const_iterator e) { + return flattened2d(c, b, e); + } + + template + flattened2d flatten2d(const Container &c) { + return flattened2d(c); + } + +} // interface6 + +namespace internal { +using interface6::internal::segmented_iterator; +} + +using interface6::enumerable_thread_specific; +using interface6::flattened2d; +using interface6::flatten2d; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_enumerable_thread_specific_H_include_area + +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph.h new file mode 100644 index 00000000..03020f79 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph.h @@ -0,0 +1,4743 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_flow_graph_H +#define __TBB_flow_graph_H + +#define __TBB_flow_graph_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_stddef.h" +#include "atomic.h" +#include "spin_mutex.h" +#include "null_mutex.h" +#include "spin_rw_mutex.h" +#include "null_rw_mutex.h" +#include "task.h" +#include "cache_aligned_allocator.h" +#include "tbb_exception.h" +#include "pipeline.h" +#include "internal/_template_helpers.h" +#include "internal/_aggregator_impl.h" +#include "tbb/internal/_allocator_traits.h" +#include "tbb_profiling.h" +#include "task_arena.h" + +#if TBB_USE_THREADING_TOOLS && TBB_PREVIEW_FLOW_GRAPH_TRACE && ( __linux__ || __APPLE__ ) + #if __INTEL_COMPILER + // Disabled warning "routine is both inline and noinline" + #pragma warning (push) + #pragma warning( disable: 2196 ) + #endif + #define __TBB_NOINLINE_SYM __attribute__((noinline)) +#else + #define __TBB_NOINLINE_SYM +#endif + +#if __TBB_PREVIEW_ASYNC_MSG +#include // std::vector in internal::async_storage +#include // std::shared_ptr in async_msg +#endif + +#if __TBB_PREVIEW_STREAMING_NODE +// For streaming_node +#include // std::array +#include // std::unordered_map +#include // std::decay, std::true_type, std::false_type +#endif // __TBB_PREVIEW_STREAMING_NODE + +#if TBB_DEPRECATED_FLOW_ENQUEUE +#define FLOW_SPAWN(a) tbb::task::enqueue((a)) +#else +#define FLOW_SPAWN(a) tbb::task::spawn((a)) +#endif + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +#define __TBB_DEFAULT_NODE_ALLOCATOR(T) cache_aligned_allocator +#else +#define __TBB_DEFAULT_NODE_ALLOCATOR(T) null_type +#endif + +// use the VC10 or gcc version of tuple if it is available. +#if __TBB_CPP11_TUPLE_PRESENT + #include +namespace tbb { + namespace flow { + using std::tuple; + using std::tuple_size; + using std::tuple_element; + using std::get; + } +} +#else + #include "compat/tuple" +#endif + +#include +#include + +/** @file + \brief The graph related classes and functions + + There are some applications that best express dependencies as messages + passed between nodes in a graph. These messages may contain data or + simply act as signals that a predecessors has completed. The graph + class and its associated node classes can be used to express such + applications. +*/ + +namespace tbb { +namespace flow { + +//! An enumeration the provides the two most common concurrency levels: unlimited and serial +enum concurrency { unlimited = 0, serial = 1 }; + +namespace interface11 { + +//! A generic null type +struct null_type {}; + +//! An empty class used for messages that mean "I'm done" +class continue_msg {}; + +//! Forward declaration section +template< typename T > class sender; +template< typename T > class receiver; +class continue_receiver; + +template< typename T, typename U > class limiter_node; // needed for resetting decrementer + +template< typename R, typename B > class run_and_put_task; + +namespace internal { + +template class successor_cache; +template class broadcast_cache; +template class round_robin_cache; +template class predecessor_cache; +template class reservable_predecessor_cache; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +namespace order { +struct following; +struct preceding; +} +template struct node_set; +#endif + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +// Holder of edges both for caches and for those nodes which do not have predecessor caches. +// C == receiver< ... > or sender< ... >, depending. +template +class edge_container { + +public: + typedef std::list > edge_list_type; + + void add_edge(C &s) { + built_edges.push_back(&s); + } + + void delete_edge(C &s) { + for (typename edge_list_type::iterator i = built_edges.begin(); i != built_edges.end(); ++i) { + if (*i == &s) { + (void)built_edges.erase(i); + return; // only remove one predecessor per request + } + } + } + + void copy_edges(edge_list_type &v) { + v = built_edges; + } + + size_t edge_count() { + return (size_t)(built_edges.size()); + } + + void clear() { + built_edges.clear(); + } + + // methods remove the statement from all predecessors/successors liste in the edge + // container. + template< typename S > void sender_extract(S &s); + template< typename R > void receiver_extract(R &r); + +private: + edge_list_type built_edges; +}; // class edge_container +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +} // namespace internal + +} // namespace interfaceX +} // namespace flow +} // namespace tbb + +//! The graph class +#include "internal/_flow_graph_impl.h" + +namespace tbb { +namespace flow { +namespace interface11 { + +// enqueue left task if necessary. Returns the non-enqueued task if there is one. +static inline tbb::task *combine_tasks(graph& g, tbb::task * left, tbb::task * right) { + // if no RHS task, don't change left. + if (right == NULL) return left; + // right != NULL + if (left == NULL) return right; + if (left == SUCCESSFULLY_ENQUEUED) return right; + // left contains a task + if (right != SUCCESSFULLY_ENQUEUED) { + // both are valid tasks + internal::spawn_in_graph_arena(g, *left); + return right; + } + return left; +} + +#if __TBB_PREVIEW_ASYNC_MSG + +template < typename T > class __TBB_DEPRECATED async_msg; + +namespace internal { + +template < typename T > class async_storage; + +template< typename T, typename = void > +struct async_helpers { + typedef async_msg async_type; + typedef T filtered_type; + + static const bool is_async_type = false; + + static const void* to_void_ptr(const T& t) { + return static_cast(&t); + } + + static void* to_void_ptr(T& t) { + return static_cast(&t); + } + + static const T& from_void_ptr(const void* p) { + return *static_cast(p); + } + + static T& from_void_ptr(void* p) { + return *static_cast(p); + } + + static task* try_put_task_wrapper_impl(receiver* const this_recv, const void *p, bool is_async) { + if (is_async) { + // This (T) is NOT async and incoming 'A t' IS async + // Get data from async_msg + const async_msg& msg = async_helpers< async_msg >::from_void_ptr(p); + task* const new_task = msg.my_storage->subscribe(*this_recv, this_recv->graph_reference()); + // finalize() must be called after subscribe() because set() can be called in finalize() + // and 'this_recv' client must be subscribed by this moment + msg.finalize(); + return new_task; + } + else { + // Incoming 't' is NOT async + return this_recv->try_put_task(from_void_ptr(p)); + } + } +}; + +template< typename T > +struct async_helpers< T, typename std::enable_if< std::is_base_of, T>::value >::type > { + typedef T async_type; + typedef typename T::async_msg_data_type filtered_type; + + static const bool is_async_type = true; + + // Receiver-classes use const interfaces + static const void* to_void_ptr(const T& t) { + return static_cast(&static_cast&>(t)); + } + + static void* to_void_ptr(T& t) { + return static_cast(&static_cast&>(t)); + } + + // Sender-classes use non-const interfaces + static const T& from_void_ptr(const void* p) { + return *static_cast(static_cast*>(p)); + } + + static T& from_void_ptr(void* p) { + return *static_cast(static_cast*>(p)); + } + + // Used in receiver class + static task* try_put_task_wrapper_impl(receiver* const this_recv, const void *p, bool is_async) { + if (is_async) { + // Both are async + return this_recv->try_put_task(from_void_ptr(p)); + } + else { + // This (T) is async and incoming 'X t' is NOT async + // Create async_msg for X + const filtered_type& t = async_helpers::from_void_ptr(p); + const T msg(t); + return this_recv->try_put_task(msg); + } + } +}; + +class untyped_receiver; + +class untyped_sender { + template< typename, typename > friend class internal::predecessor_cache; + template< typename, typename > friend class internal::reservable_predecessor_cache; +public: + //! The successor type for this node + typedef untyped_receiver successor_type; + + virtual ~untyped_sender() {} + + // NOTE: Following part of PUBLIC section is copy-paste from original sender class + + // TODO: Prevent untyped successor registration + + //! Add a new successor to this node + virtual bool register_successor( successor_type &r ) = 0; + + //! Removes a successor from this node + virtual bool remove_successor( successor_type &r ) = 0; + + //! Releases the reserved item + virtual bool try_release( ) { return false; } + + //! Consumes the reserved item + virtual bool try_consume( ) { return false; } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + //! interface to record edges for traversal & deletion + typedef internal::edge_container built_successors_type; + typedef built_successors_type::edge_list_type successor_list_type; + virtual built_successors_type &built_successors() = 0; + virtual void internal_add_built_successor( successor_type & ) = 0; + virtual void internal_delete_built_successor( successor_type & ) = 0; + virtual void copy_successors( successor_list_type &) = 0; + virtual size_t successor_count() = 0; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ +protected: + //! Request an item from the sender + template< typename X > + bool try_get( X &t ) { + return try_get_wrapper( internal::async_helpers::to_void_ptr(t), internal::async_helpers::is_async_type ); + } + + //! Reserves an item in the sender + template< typename X > + bool try_reserve( X &t ) { + return try_reserve_wrapper( internal::async_helpers::to_void_ptr(t), internal::async_helpers::is_async_type ); + } + + virtual bool try_get_wrapper( void* p, bool is_async ) = 0; + virtual bool try_reserve_wrapper( void* p, bool is_async ) = 0; +}; + +class untyped_receiver { + template< typename, typename > friend class run_and_put_task; + + template< typename, typename > friend class internal::broadcast_cache; + template< typename, typename > friend class internal::round_robin_cache; + template< typename, typename > friend class internal::successor_cache; + +#if __TBB_PREVIEW_OPENCL_NODE + template< typename, typename > friend class proxy_dependency_receiver; +#endif /* __TBB_PREVIEW_OPENCL_NODE */ +public: + //! The predecessor type for this node + typedef untyped_sender predecessor_type; + + //! Destructor + virtual ~untyped_receiver() {} + + //! Put an item to the receiver + template + bool try_put(const X& t) { + task *res = try_put_task(t); + if (!res) return false; + if (res != SUCCESSFULLY_ENQUEUED) internal::spawn_in_graph_arena(graph_reference(), *res); + return true; + } + + // NOTE: Following part of PUBLIC section is copy-paste from original receiver class + + // TODO: Prevent untyped predecessor registration + + //! Add a predecessor to the node + virtual bool register_predecessor( predecessor_type & ) { return false; } + + //! Remove a predecessor from the node + virtual bool remove_predecessor( predecessor_type & ) { return false; } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef internal::edge_container built_predecessors_type; + typedef built_predecessors_type::edge_list_type predecessor_list_type; + virtual built_predecessors_type &built_predecessors() = 0; + virtual void internal_add_built_predecessor( predecessor_type & ) = 0; + virtual void internal_delete_built_predecessor( predecessor_type & ) = 0; + virtual void copy_predecessors( predecessor_list_type & ) = 0; + virtual size_t predecessor_count() = 0; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ +protected: + template + task *try_put_task(const X& t) { + return try_put_task_wrapper( internal::async_helpers::to_void_ptr(t), internal::async_helpers::is_async_type ); + } + + virtual task* try_put_task_wrapper( const void* p, bool is_async ) = 0; + + virtual graph& graph_reference() const = 0; + + // NOTE: Following part of PROTECTED and PRIVATE sections is copy-paste from original receiver class + + //! put receiver back in initial state + virtual void reset_receiver(reset_flags f = rf_reset_protocol) = 0; + + virtual bool is_continue_receiver() { return false; } +}; + +} // namespace internal + +//! Pure virtual template class that defines a sender of messages of type T +template< typename T > +class sender : public internal::untyped_sender { +public: + //! The output type of this sender + __TBB_DEPRECATED typedef T output_type; + + __TBB_DEPRECATED typedef typename internal::async_helpers::filtered_type filtered_type; + + //! Request an item from the sender + virtual bool try_get( T & ) { return false; } + + //! Reserves an item in the sender + virtual bool try_reserve( T & ) { return false; } + +protected: + virtual bool try_get_wrapper( void* p, bool is_async ) __TBB_override { + // Both async OR both are NOT async + if ( internal::async_helpers::is_async_type == is_async ) { + return try_get( internal::async_helpers::from_void_ptr(p) ); + } + // Else: this (T) is async OR incoming 't' is async + __TBB_ASSERT(false, "async_msg interface does not support 'pull' protocol in try_get()"); + return false; + } + + virtual bool try_reserve_wrapper( void* p, bool is_async ) __TBB_override { + // Both async OR both are NOT async + if ( internal::async_helpers::is_async_type == is_async ) { + return try_reserve( internal::async_helpers::from_void_ptr(p) ); + } + // Else: this (T) is async OR incoming 't' is async + __TBB_ASSERT(false, "async_msg interface does not support 'pull' protocol in try_reserve()"); + return false; + } +}; // class sender + +//! Pure virtual template class that defines a receiver of messages of type T +template< typename T > +class receiver : public internal::untyped_receiver { + template< typename > friend class internal::async_storage; + template< typename, typename > friend struct internal::async_helpers; +public: + //! The input type of this receiver + __TBB_DEPRECATED typedef T input_type; + + __TBB_DEPRECATED typedef typename internal::async_helpers::filtered_type filtered_type; + + //! Put an item to the receiver + bool try_put( const typename internal::async_helpers::filtered_type& t ) { + return internal::untyped_receiver::try_put(t); + } + + bool try_put( const typename internal::async_helpers::async_type& t ) { + return internal::untyped_receiver::try_put(t); + } + +protected: + virtual task* try_put_task_wrapper( const void *p, bool is_async ) __TBB_override { + return internal::async_helpers::try_put_task_wrapper_impl(this, p, is_async); + } + + //! Put item to successor; return task to run the successor if possible. + virtual task *try_put_task(const T& t) = 0; + +}; // class receiver + +#else // __TBB_PREVIEW_ASYNC_MSG + +//! Pure virtual template class that defines a sender of messages of type T +template< typename T > +class sender { +public: + //! The output type of this sender + __TBB_DEPRECATED typedef T output_type; + + //! The successor type for this node + __TBB_DEPRECATED typedef receiver successor_type; + + virtual ~sender() {} + + // NOTE: Following part of PUBLIC section is partly copy-pasted in sender under #if __TBB_PREVIEW_ASYNC_MSG + + //! Add a new successor to this node + __TBB_DEPRECATED virtual bool register_successor( successor_type &r ) = 0; + + //! Removes a successor from this node + __TBB_DEPRECATED virtual bool remove_successor( successor_type &r ) = 0; + + //! Request an item from the sender + virtual bool try_get( T & ) { return false; } + + //! Reserves an item in the sender + virtual bool try_reserve( T & ) { return false; } + + //! Releases the reserved item + virtual bool try_release( ) { return false; } + + //! Consumes the reserved item + virtual bool try_consume( ) { return false; } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + //! interface to record edges for traversal & deletion + __TBB_DEPRECATED typedef typename internal::edge_container built_successors_type; + __TBB_DEPRECATED typedef typename built_successors_type::edge_list_type successor_list_type; + __TBB_DEPRECATED virtual built_successors_type &built_successors() = 0; + __TBB_DEPRECATED virtual void internal_add_built_successor( successor_type & ) = 0; + __TBB_DEPRECATED virtual void internal_delete_built_successor( successor_type & ) = 0; + __TBB_DEPRECATED virtual void copy_successors( successor_list_type &) = 0; + __TBB_DEPRECATED virtual size_t successor_count() = 0; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ +}; // class sender + +//! Pure virtual template class that defines a receiver of messages of type T +template< typename T > +class receiver { +public: + //! The input type of this receiver + __TBB_DEPRECATED typedef T input_type; + + //! The predecessor type for this node + __TBB_DEPRECATED typedef sender predecessor_type; + + //! Destructor + virtual ~receiver() {} + + //! Put an item to the receiver + bool try_put( const T& t ) { + task *res = try_put_task(t); + if (!res) return false; + if (res != SUCCESSFULLY_ENQUEUED) internal::spawn_in_graph_arena(graph_reference(), *res); + return true; + } + + //! put item to successor; return task to run the successor if possible. +protected: + template< typename R, typename B > friend class run_and_put_task; + template< typename X, typename Y > friend class internal::broadcast_cache; + template< typename X, typename Y > friend class internal::round_robin_cache; + virtual task *try_put_task(const T& t) = 0; + virtual graph& graph_reference() const = 0; +public: + // NOTE: Following part of PUBLIC and PROTECTED sections is copy-pasted in receiver under #if __TBB_PREVIEW_ASYNC_MSG + + //! Add a predecessor to the node + __TBB_DEPRECATED virtual bool register_predecessor( predecessor_type & ) { return false; } + + //! Remove a predecessor from the node + __TBB_DEPRECATED virtual bool remove_predecessor( predecessor_type & ) { return false; } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + __TBB_DEPRECATED typedef typename internal::edge_container built_predecessors_type; + __TBB_DEPRECATED typedef typename built_predecessors_type::edge_list_type predecessor_list_type; + __TBB_DEPRECATED virtual built_predecessors_type &built_predecessors() = 0; + __TBB_DEPRECATED virtual void internal_add_built_predecessor( predecessor_type & ) = 0; + __TBB_DEPRECATED virtual void internal_delete_built_predecessor( predecessor_type & ) = 0; + __TBB_DEPRECATED virtual void copy_predecessors( predecessor_list_type & ) = 0; + __TBB_DEPRECATED virtual size_t predecessor_count() = 0; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +protected: + //! put receiver back in initial state + virtual void reset_receiver(reset_flags f = rf_reset_protocol) = 0; + + template friend class internal::successor_cache; + virtual bool is_continue_receiver() { return false; } + +#if __TBB_PREVIEW_OPENCL_NODE + template< typename, typename > friend class proxy_dependency_receiver; +#endif /* __TBB_PREVIEW_OPENCL_NODE */ +}; // class receiver + +#endif // __TBB_PREVIEW_ASYNC_MSG + +//! Base class for receivers of completion messages +/** These receivers automatically reset, but cannot be explicitly waited on */ +class continue_receiver : public receiver< continue_msg > { +public: + + //! The input type + __TBB_DEPRECATED typedef continue_msg input_type; + + //! The predecessor type for this node + __TBB_DEPRECATED typedef receiver::predecessor_type predecessor_type; + + //! Constructor + __TBB_DEPRECATED explicit continue_receiver( + __TBB_FLOW_GRAPH_PRIORITY_ARG1(int number_of_predecessors, node_priority_t priority)) { + my_predecessor_count = my_initial_predecessor_count = number_of_predecessors; + my_current_count = 0; + __TBB_FLOW_GRAPH_PRIORITY_EXPR( my_priority = priority; ) + } + + //! Copy constructor + __TBB_DEPRECATED continue_receiver( const continue_receiver& src ) : receiver() { + my_predecessor_count = my_initial_predecessor_count = src.my_initial_predecessor_count; + my_current_count = 0; + __TBB_FLOW_GRAPH_PRIORITY_EXPR( my_priority = src.my_priority; ) + } + + //! Increments the trigger threshold + __TBB_DEPRECATED bool register_predecessor( predecessor_type & ) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + ++my_predecessor_count; + return true; + } + + //! Decrements the trigger threshold + /** Does not check to see if the removal of the predecessor now makes the current count + exceed the new threshold. So removing a predecessor while the graph is active can cause + unexpected results. */ + __TBB_DEPRECATED bool remove_predecessor( predecessor_type & ) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + --my_predecessor_count; + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + __TBB_DEPRECATED typedef internal::edge_container built_predecessors_type; + __TBB_DEPRECATED typedef built_predecessors_type::edge_list_type predecessor_list_type; + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + + __TBB_DEPRECATED void internal_add_built_predecessor( predecessor_type &s) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + my_built_predecessors.add_edge( s ); + } + + __TBB_DEPRECATED void internal_delete_built_predecessor( predecessor_type &s) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + my_built_predecessors.delete_edge(s); + } + + __TBB_DEPRECATED void copy_predecessors( predecessor_list_type &v) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + my_built_predecessors.copy_edges(v); + } + + __TBB_DEPRECATED size_t predecessor_count() __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + return my_built_predecessors.edge_count(); + } + +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + // execute body is supposed to be too small to create a task for. + task *try_put_task( const input_type & ) __TBB_override { + { + spin_mutex::scoped_lock l(my_mutex); + if ( ++my_current_count < my_predecessor_count ) + return SUCCESSFULLY_ENQUEUED; + else + my_current_count = 0; + } + task * res = execute(); + return res? res : SUCCESSFULLY_ENQUEUED; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + // continue_receiver must contain its own built_predecessors because it does + // not have a node_cache. + built_predecessors_type my_built_predecessors; +#endif + spin_mutex my_mutex; + int my_predecessor_count; + int my_current_count; + int my_initial_predecessor_count; + __TBB_FLOW_GRAPH_PRIORITY_EXPR( node_priority_t my_priority; ) + // the friend declaration in the base class did not eliminate the "protected class" + // error in gcc 4.1.2 + template friend class tbb::flow::interface11::limiter_node; + + void reset_receiver( reset_flags f ) __TBB_override { + my_current_count = 0; + if (f & rf_clear_edges) { +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + my_built_predecessors.clear(); +#endif + my_predecessor_count = my_initial_predecessor_count; + } + } + + //! Does whatever should happen when the threshold is reached + /** This should be very fast or else spawn a task. This is + called while the sender is blocked in the try_put(). */ + virtual task * execute() = 0; + template friend class internal::successor_cache; + bool is_continue_receiver() __TBB_override { return true; } + +}; // class continue_receiver + +} // interfaceX + +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + template + K key_from_message( const T &t ) { + return t.key(); + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + + using interface11::sender; + using interface11::receiver; + using interface11::continue_receiver; +} // flow +} // tbb + +#include "internal/_flow_graph_trace_impl.h" +#include "internal/_tbb_hash_compare_impl.h" + +namespace tbb { +namespace flow { +namespace interface11 { + +#include "internal/_flow_graph_body_impl.h" +#include "internal/_flow_graph_cache_impl.h" +#include "internal/_flow_graph_types_impl.h" +#if __TBB_PREVIEW_ASYNC_MSG +#include "internal/_flow_graph_async_msg_impl.h" +#endif +using namespace internal::graph_policy_namespace; + +template +graph_iterator::graph_iterator(C *g, bool begin) : my_graph(g), current_node(NULL) +{ + if (begin) current_node = my_graph->my_nodes; + //else it is an end iterator by default +} + +template +typename graph_iterator::reference graph_iterator::operator*() const { + __TBB_ASSERT(current_node, "graph_iterator at end"); + return *operator->(); +} + +template +typename graph_iterator::pointer graph_iterator::operator->() const { + return current_node; +} + +template +void graph_iterator::internal_forward() { + if (current_node) current_node = current_node->next; +} + +} // namespace interfaceX + +namespace interface10 { +//! Constructs a graph with isolated task_group_context +inline graph::graph() : my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) { + prepare_task_arena(); + own_context = true; + cancelled = false; + caught_exception = false; + my_context = new task_group_context(tbb::internal::FLOW_TASKS); + my_root_task = (new (task::allocate_root(*my_context)) empty_task); + my_root_task->set_ref_count(1); + tbb::internal::fgt_graph(this); + my_is_active = true; +} + +inline graph::graph(task_group_context& use_this_context) : + my_context(&use_this_context), my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) { + prepare_task_arena(); + own_context = false; + cancelled = false; + caught_exception = false; + my_root_task = (new (task::allocate_root(*my_context)) empty_task); + my_root_task->set_ref_count(1); + tbb::internal::fgt_graph(this); + my_is_active = true; +} + +inline graph::~graph() { + wait_for_all(); + my_root_task->set_ref_count(0); + tbb::task::destroy(*my_root_task); + if (own_context) delete my_context; + delete my_task_arena; +} + +inline void graph::reserve_wait() { + if (my_root_task) { + my_root_task->increment_ref_count(); + tbb::internal::fgt_reserve_wait(this); + } +} + +inline void graph::release_wait() { + if (my_root_task) { + tbb::internal::fgt_release_wait(this); + my_root_task->decrement_ref_count(); + } +} + +inline void graph::register_node(tbb::flow::interface11::graph_node *n) { + n->next = NULL; + { + spin_mutex::scoped_lock lock(nodelist_mutex); + n->prev = my_nodes_last; + if (my_nodes_last) my_nodes_last->next = n; + my_nodes_last = n; + if (!my_nodes) my_nodes = n; + } +} + +inline void graph::remove_node(tbb::flow::interface11::graph_node *n) { + { + spin_mutex::scoped_lock lock(nodelist_mutex); + __TBB_ASSERT(my_nodes && my_nodes_last, "graph::remove_node: Error: no registered nodes"); + if (n->prev) n->prev->next = n->next; + if (n->next) n->next->prev = n->prev; + if (my_nodes_last == n) my_nodes_last = n->prev; + if (my_nodes == n) my_nodes = n->next; + } + n->prev = n->next = NULL; +} + +inline void graph::reset( tbb::flow::interface11::reset_flags f ) { + // reset context + tbb::flow::interface11::internal::deactivate_graph(*this); + + if(my_context) my_context->reset(); + cancelled = false; + caught_exception = false; + // reset all the nodes comprising the graph + for(iterator ii = begin(); ii != end(); ++ii) { + tbb::flow::interface11::graph_node *my_p = &(*ii); + my_p->reset_node(f); + } + // Reattach the arena. Might be useful to run the graph in a particular task_arena + // while not limiting graph lifetime to a single task_arena::execute() call. + prepare_task_arena( /*reinit=*/true ); + tbb::flow::interface11::internal::activate_graph(*this); + // now spawn the tasks necessary to start the graph + for(task_list_type::iterator rti = my_reset_task_list.begin(); rti != my_reset_task_list.end(); ++rti) { + tbb::flow::interface11::internal::spawn_in_graph_arena(*this, *(*rti)); + } + my_reset_task_list.clear(); +} + +inline graph::iterator graph::begin() { return iterator(this, true); } + +inline graph::iterator graph::end() { return iterator(this, false); } + +inline graph::const_iterator graph::begin() const { return const_iterator(this, true); } + +inline graph::const_iterator graph::end() const { return const_iterator(this, false); } + +inline graph::const_iterator graph::cbegin() const { return const_iterator(this, true); } + +inline graph::const_iterator graph::cend() const { return const_iterator(this, false); } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE +inline void graph::set_name(const char *name) { + tbb::internal::fgt_graph_desc(this, name); +} +#endif + +} // namespace interface10 + +namespace interface11 { + +inline graph_node::graph_node(graph& g) : my_graph(g) { + my_graph.register_node(this); +} + +inline graph_node::~graph_node() { + my_graph.remove_node(this); +} + +#include "internal/_flow_graph_node_impl.h" + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +using internal::node_set; +#endif + +//! An executable node that acts as a source, i.e. it has no predecessors +template < typename Output > +class input_node : public graph_node, public sender< Output > { +public: + //! The type of the output message, which is complete + typedef Output output_type; + + //! The type of successors of this node + typedef typename sender::successor_type successor_type; + + //Source node has no input type + typedef null_type input_type; + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename sender::built_successors_type built_successors_type; + typedef typename sender::successor_list_type successor_list_type; +#endif + + //! Constructor for a node with a successor + template< typename Body > + __TBB_NOINLINE_SYM input_node( graph &g, Body body ) + : graph_node(g), my_active(false), + my_body( new internal::input_body_leaf< output_type, Body>(body) ), + my_init_body( new internal::input_body_leaf< output_type, Body>(body) ), + my_reserved(false), my_has_cached_item(false) + { + my_successors.set_owner(this); + tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_SOURCE_NODE, &this->my_graph, + static_cast *>(this), this->my_body ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + input_node( const node_set& successors, Body body ) + : input_node(successors.graph_reference(), body) { + make_edges(*this, successors); + } +#endif + + //! Copy constructor + __TBB_NOINLINE_SYM input_node( const input_node& src ) : + graph_node(src.my_graph), sender(), + my_active(false), + my_body( src.my_init_body->clone() ), my_init_body(src.my_init_body->clone() ), + my_reserved(false), my_has_cached_item(false) + { + my_successors.set_owner(this); + tbb::internal::fgt_node_with_body(CODEPTR(), tbb::internal::FLOW_SOURCE_NODE, &this->my_graph, + static_cast *>(this), this->my_body ); + } + + //! The destructor + ~input_node() { delete my_body; delete my_init_body; } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + + //! Add a new successor to this node + bool register_successor( successor_type &r ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_successors.register_successor(r); + if ( my_active ) + spawn_put(); + return true; + } + + //! Removes a successor from this node + bool remove_successor( successor_type &r ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_successors.remove_successor(r); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + + void internal_add_built_successor( successor_type &r) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_successors.internal_add_built_successor(r); + } + + void internal_delete_built_successor( successor_type &r) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_successors.internal_delete_built_successor(r); + } + + size_t successor_count() __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + return my_successors.successor_count(); + } + + void copy_successors(successor_list_type &v) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + my_successors.copy_successors(v); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + //! Request an item from the node + bool try_get( output_type &v ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + if ( my_reserved ) + return false; + + if ( my_has_cached_item ) { + v = my_cached_item; + my_has_cached_item = false; + return true; + } + // we've been asked to provide an item, but we have none. enqueue a task to + // provide one. + if ( my_active ) + spawn_put(); + return false; + } + + //! Reserves an item. + bool try_reserve( output_type &v ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + if ( my_reserved ) { + return false; + } + + if ( my_has_cached_item ) { + v = my_cached_item; + my_reserved = true; + return true; + } else { + return false; + } + } + + //! Release a reserved item. + /** true = item has been released and so remains in sender, dest must request or reserve future items */ + bool try_release( ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + __TBB_ASSERT( my_reserved && my_has_cached_item, "releasing non-existent reservation" ); + my_reserved = false; + if(!my_successors.empty()) + spawn_put(); + return true; + } + + //! Consumes a reserved item + bool try_consume( ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + __TBB_ASSERT( my_reserved && my_has_cached_item, "consuming non-existent reservation" ); + my_reserved = false; + my_has_cached_item = false; + if ( !my_successors.empty() ) { + spawn_put(); + } + return true; + } + + //! Activates a node that was created in the inactive state + void activate() { + spin_mutex::scoped_lock lock(my_mutex); + my_active = true; + if (!my_successors.empty()) + spawn_put(); + } + + template + Body copy_function_object() { + internal::input_body &body_ref = *this->my_body; + return dynamic_cast< internal::input_body_leaf & >(body_ref).get_body(); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract( ) __TBB_override { + my_successors.built_successors().sender_extract(*this); // removes "my_owner" == this from each successor + my_active = false; + my_reserved = false; + if(my_has_cached_item) my_has_cached_item = false; + } +#endif + +protected: + + //! resets the input_node to its initial state + void reset_node( reset_flags f) __TBB_override { + my_active = false; + my_reserved = false; + my_has_cached_item = false; + + if(f & rf_clear_edges) my_successors.clear(); + if(f & rf_reset_bodies) { + internal::input_body *tmp = my_init_body->clone(); + delete my_body; + my_body = tmp; + } + } + +private: + spin_mutex my_mutex; + bool my_active; + internal::input_body *my_body; + internal::input_body *my_init_body; + internal::broadcast_cache< output_type > my_successors; + bool my_reserved; + bool my_has_cached_item; + output_type my_cached_item; + + // used by apply_body_bypass, can invoke body of node. + bool try_reserve_apply_body(output_type &v) { + spin_mutex::scoped_lock lock(my_mutex); + if ( my_reserved ) { + return false; + } + if ( !my_has_cached_item ) { + tbb::internal::fgt_begin_body( my_body ); + +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool r = (*my_body)(my_cached_item); + if (r) { + my_has_cached_item = true; + } +#else + flow_control control; + my_cached_item = (*my_body)(control); + my_has_cached_item = !control.is_pipeline_stopped; +#endif + tbb::internal::fgt_end_body( my_body ); + } + if ( my_has_cached_item ) { + v = my_cached_item; + my_reserved = true; + return true; + } else { + return false; + } + } + + task* create_put_task() { + return ( new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) + internal:: source_task_bypass < input_node< output_type > >( *this ) ); + } + + //! Spawns a task that applies the body + void spawn_put( ) { + if(internal::is_graph_active(this->my_graph)) { + internal::spawn_in_graph_arena(this->my_graph, *create_put_task()); + } + } + + friend class internal::source_task_bypass< input_node< output_type > >; + //! Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it. + task * apply_body_bypass( ) { + output_type v; + if ( !try_reserve_apply_body(v) ) + return NULL; + + task *last_task = my_successors.try_put_task(v); + if ( last_task ) + try_consume(); + else + try_release(); + return last_task; + } +}; // class input_node + +#if TBB_USE_SOURCE_NODE_AS_ALIAS +template < typename Output > +class source_node : public input_node { +public: + //! Constructor for a node with a successor + template< typename Body > + __TBB_NOINLINE_SYM source_node( graph &g, Body body ) + : input_node(g, body) + { + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + source_node( const node_set& successors, Body body ) + : input_node(successors, body) { + } +#endif +}; +#else // TBB_USE_SOURCE_NODE_AS_ALIAS +//! An executable node that acts as a source, i.e. it has no predecessors +template < typename Output > class +__TBB_DEPRECATED_MSG("TBB Warning: tbb::flow::source_node is deprecated, use tbb::flow::input_node." ) +source_node : public graph_node, public sender< Output > { +public: + //! The type of the output message, which is complete + typedef Output output_type; + + //! The type of successors of this node + typedef typename sender::successor_type successor_type; + + //Source node has no input type + typedef null_type input_type; + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename sender::built_successors_type built_successors_type; + typedef typename sender::successor_list_type successor_list_type; +#endif + + //! Constructor for a node with a successor + template< typename Body > + __TBB_NOINLINE_SYM source_node( graph &g, Body body, bool is_active = true ) + : graph_node(g), my_active(is_active), init_my_active(is_active), + my_body( new internal::source_body_leaf< output_type, Body>(body) ), + my_init_body( new internal::source_body_leaf< output_type, Body>(body) ), + my_reserved(false), my_has_cached_item(false) + { + my_successors.set_owner(this); + tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_SOURCE_NODE, &this->my_graph, + static_cast *>(this), this->my_body ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + source_node( const node_set& successors, Body body, bool is_active = true ) + : source_node(successors.graph_reference(), body, is_active) { + make_edges(*this, successors); + } +#endif + + //! Copy constructor + __TBB_NOINLINE_SYM source_node( const source_node& src ) : + graph_node(src.my_graph), sender(), + my_active(src.init_my_active), + init_my_active(src.init_my_active), my_body( src.my_init_body->clone() ), my_init_body(src.my_init_body->clone() ), + my_reserved(false), my_has_cached_item(false) + { + my_successors.set_owner(this); + tbb::internal::fgt_node_with_body(CODEPTR(), tbb::internal::FLOW_SOURCE_NODE, &this->my_graph, + static_cast *>(this), this->my_body ); + } + + //! The destructor + ~source_node() { delete my_body; delete my_init_body; } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + + //! Add a new successor to this node + bool register_successor( successor_type &r ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_successors.register_successor(r); + if ( my_active ) + spawn_put(); + return true; + } + + //! Removes a successor from this node + bool remove_successor( successor_type &r ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_successors.remove_successor(r); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + + void internal_add_built_successor( successor_type &r) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_successors.internal_add_built_successor(r); + } + + void internal_delete_built_successor( successor_type &r) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_successors.internal_delete_built_successor(r); + } + + size_t successor_count() __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + return my_successors.successor_count(); + } + + void copy_successors(successor_list_type &v) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + my_successors.copy_successors(v); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + //! Request an item from the node + bool try_get( output_type &v ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + if ( my_reserved ) + return false; + + if ( my_has_cached_item ) { + v = my_cached_item; + my_has_cached_item = false; + return true; + } + // we've been asked to provide an item, but we have none. enqueue a task to + // provide one. + spawn_put(); + return false; + } + + //! Reserves an item. + bool try_reserve( output_type &v ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + if ( my_reserved ) { + return false; + } + + if ( my_has_cached_item ) { + v = my_cached_item; + my_reserved = true; + return true; + } else { + return false; + } + } + + //! Release a reserved item. + /** true = item has been released and so remains in sender, dest must request or reserve future items */ + bool try_release( ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + __TBB_ASSERT( my_reserved && my_has_cached_item, "releasing non-existent reservation" ); + my_reserved = false; + if(!my_successors.empty()) + spawn_put(); + return true; + } + + //! Consumes a reserved item + bool try_consume( ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + __TBB_ASSERT( my_reserved && my_has_cached_item, "consuming non-existent reservation" ); + my_reserved = false; + my_has_cached_item = false; + if ( !my_successors.empty() ) { + spawn_put(); + } + return true; + } + + //! Activates a node that was created in the inactive state + void activate() { + spin_mutex::scoped_lock lock(my_mutex); + my_active = true; + if (!my_successors.empty()) + spawn_put(); + } + + template + Body copy_function_object() { + internal::source_body &body_ref = *this->my_body; + return dynamic_cast< internal::source_body_leaf & >(body_ref).get_body(); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract( ) __TBB_override { + my_successors.built_successors().sender_extract(*this); // removes "my_owner" == this from each successor + my_active = init_my_active; + my_reserved = false; + if(my_has_cached_item) my_has_cached_item = false; + } +#endif + +protected: + + //! resets the source_node to its initial state + void reset_node( reset_flags f) __TBB_override { + my_active = init_my_active; + my_reserved =false; + if(my_has_cached_item) { + my_has_cached_item = false; + } + if(f & rf_clear_edges) my_successors.clear(); + if(f & rf_reset_bodies) { + internal::source_body *tmp = my_init_body->clone(); + delete my_body; + my_body = tmp; + } + if(my_active) + internal::add_task_to_graph_reset_list(this->my_graph, create_put_task()); + } + +private: + spin_mutex my_mutex; + bool my_active; + bool init_my_active; + internal::source_body *my_body; + internal::source_body *my_init_body; + internal::broadcast_cache< output_type > my_successors; + bool my_reserved; + bool my_has_cached_item; + output_type my_cached_item; + + // used by apply_body_bypass, can invoke body of node. + bool try_reserve_apply_body(output_type &v) { + spin_mutex::scoped_lock lock(my_mutex); + if ( my_reserved ) { + return false; + } + if ( !my_has_cached_item ) { + tbb::internal::fgt_begin_body( my_body ); + bool r = (*my_body)(my_cached_item); + tbb::internal::fgt_end_body( my_body ); + if (r) { + my_has_cached_item = true; + } + } + if ( my_has_cached_item ) { + v = my_cached_item; + my_reserved = true; + return true; + } else { + return false; + } + } + + // when resetting, and if the source_node was created with my_active == true, then + // when we reset the node we must store a task to run the node, and spawn it only + // after the reset is complete and is_active() is again true. This is why we don't + // test for is_active() here. + task* create_put_task() { + return ( new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) + internal:: source_task_bypass < source_node< output_type > >( *this ) ); + } + + //! Spawns a task that applies the body + void spawn_put( ) { + if(internal::is_graph_active(this->my_graph)) { + internal::spawn_in_graph_arena(this->my_graph, *create_put_task()); + } + } + + friend class internal::source_task_bypass< source_node< output_type > >; + //! Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it. + task * apply_body_bypass( ) { + output_type v; + if ( !try_reserve_apply_body(v) ) + return NULL; + + task *last_task = my_successors.try_put_task(v); + if ( last_task ) + try_consume(); + else + try_release(); + return last_task; + } +}; // class source_node +#endif // TBB_USE_SOURCE_NODE_AS_ALIAS + +//! Implements a function node that supports Input -> Output +template +class function_node + : public graph_node +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + , public internal::function_input< Input, Output, Policy, Allocator > +#else + , public internal::function_input< Input, Output, Policy, cache_aligned_allocator > +#endif + , public internal::function_output { + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + typedef Allocator internals_allocator; +#else + typedef cache_aligned_allocator internals_allocator; + + __TBB_STATIC_ASSERT( + (tbb::internal::is_same_type::value), + "Allocator template parameter for flow graph nodes is deprecated and will be removed. " + "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface." + ); +#endif + +public: + typedef Input input_type; + typedef Output output_type; + typedef internal::function_input input_impl_type; + typedef internal::function_input_queue input_queue_type; + typedef internal::function_output fOutput_type; + typedef typename input_impl_type::predecessor_type predecessor_type; + typedef typename fOutput_type::successor_type successor_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename input_impl_type::predecessor_list_type predecessor_list_type; + typedef typename fOutput_type::successor_list_type successor_list_type; +#endif + using input_impl_type::my_predecessors; + + //! Constructor + // input_queue_type is allocated here, but destroyed in the function_input_base. + // TODO: pass the graph_buffer_policy to the function_input_base so it can all + // be done in one place. This would be an interface-breaking change. + template< typename Body > + __TBB_NOINLINE_SYM function_node( graph &g, size_t concurrency, +#if __TBB_CPP11_PRESENT + Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority )) +#else + __TBB_FLOW_GRAPH_PRIORITY_ARG1( Body body, node_priority_t priority = tbb::flow::internal::no_priority )) +#endif + : graph_node(g), input_impl_type(g, concurrency, __TBB_FLOW_GRAPH_PRIORITY_ARG1(body, priority)), + fOutput_type(g) { + tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_FUNCTION_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(this), this->my_body ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT + template + function_node( graph& g, size_t concurrency, Body body, node_priority_t priority ) + : function_node(g, concurrency, body, Policy(), priority) {} +#endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + function_node( const node_set& nodes, size_t concurrency, Body body, + __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy p = Policy(), node_priority_t priority = tbb::flow::internal::no_priority )) + : function_node(nodes.graph_reference(), concurrency, body, __TBB_FLOW_GRAPH_PRIORITY_ARG1(p, priority)) { + make_edges_in_order(nodes, *this); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + template + function_node( const node_set& nodes, size_t concurrency, Body body, node_priority_t priority ) + : function_node(nodes, concurrency, body, Policy(), priority) {} +#endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + + //! Copy constructor + __TBB_NOINLINE_SYM function_node( const function_node& src ) : + graph_node(src.my_graph), + input_impl_type(src), + fOutput_type(src.my_graph) { + tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_FUNCTION_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(this), this->my_body ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract( ) __TBB_override { + my_predecessors.built_predecessors().receiver_extract(*this); + successors().built_successors().sender_extract(*this); + } +#endif + +protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + using input_impl_type::try_put_task; + + internal::broadcast_cache &successors () __TBB_override { return fOutput_type::my_successors; } + + void reset_node(reset_flags f) __TBB_override { + input_impl_type::reset_function_input(f); + // TODO: use clear() instead. + if(f & rf_clear_edges) { + successors().clear(); + my_predecessors.clear(); + } + __TBB_ASSERT(!(f & rf_clear_edges) || successors().empty(), "function_node successors not empty"); + __TBB_ASSERT(this->my_predecessors.empty(), "function_node predecessors not empty"); + } + +}; // class function_node + +//! implements a function node that supports Input -> (set of outputs) +// Output is a tuple of output types. +template +class multifunction_node : + public graph_node, + public internal::multifunction_input + < + Input, + typename internal::wrap_tuple_elements< + tbb::flow::tuple_size::value, // #elements in tuple + internal::multifunction_output, // wrap this around each element + Output // the tuple providing the types + >::type, + Policy, +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + Allocator +#else + cache_aligned_allocator +#endif + > { +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + typedef Allocator internals_allocator; +#else + typedef cache_aligned_allocator internals_allocator; + + __TBB_STATIC_ASSERT( + (tbb::internal::is_same_type::value), + "Allocator template parameter for flow graph nodes is deprecated and will be removed. " + "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface." + ); +#endif + +protected: + static const int N = tbb::flow::tuple_size::value; +public: + typedef Input input_type; + typedef null_type output_type; + typedef typename internal::wrap_tuple_elements::type output_ports_type; + typedef internal::multifunction_input< + input_type, output_ports_type, Policy, internals_allocator> input_impl_type; + typedef internal::function_input_queue input_queue_type; +private: + using input_impl_type::my_predecessors; +public: + template + __TBB_NOINLINE_SYM multifunction_node( + graph &g, size_t concurrency, +#if __TBB_CPP11_PRESENT + Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority ) +#else + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body body, node_priority_t priority = tbb::flow::internal::no_priority) +#endif + ) : graph_node(g), input_impl_type(g, concurrency, __TBB_FLOW_GRAPH_PRIORITY_ARG1(body, priority)) { + tbb::internal::fgt_multioutput_node_with_body( + CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE, + &this->my_graph, static_cast *>(this), + this->output_ports(), this->my_body + ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT + template + __TBB_NOINLINE_SYM multifunction_node(graph& g, size_t concurrency, Body body, node_priority_t priority) + : multifunction_node(g, concurrency, body, Policy(), priority) {} +#endif // TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + __TBB_NOINLINE_SYM multifunction_node(const node_set& nodes, size_t concurrency, Body body, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy p = Policy(), node_priority_t priority = tbb::flow::internal::no_priority)) + : multifunction_node(nodes.graph_reference(), concurrency, body, __TBB_FLOW_GRAPH_PRIORITY_ARG1(p, priority)) { + make_edges_in_order(nodes, *this); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + template + __TBB_NOINLINE_SYM multifunction_node(const node_set& nodes, size_t concurrency, Body body, node_priority_t priority) + : multifunction_node(nodes, concurrency, body, Policy(), priority) {} +#endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + + __TBB_NOINLINE_SYM multifunction_node( const multifunction_node &other) : + graph_node(other.my_graph), input_impl_type(other) { + tbb::internal::fgt_multioutput_node_with_body( CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE, + &this->my_graph, static_cast *>(this), + this->output_ports(), this->my_body ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_multioutput_node_desc( this, name ); + } +#endif + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract( ) __TBB_override { + my_predecessors.built_predecessors().receiver_extract(*this); + input_impl_type::extract(); + } +#endif + // all the guts are in multifunction_input... +protected: + void reset_node(reset_flags f) __TBB_override { input_impl_type::reset(f); } +}; // multifunction_node + +//! split_node: accepts a tuple as input, forwards each element of the tuple to its +// successors. The node has unlimited concurrency, so it does not reject inputs. +template +class split_node : public graph_node, public receiver { + static const int N = tbb::flow::tuple_size::value; + typedef receiver base_type; +public: + typedef TupleType input_type; +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + typedef Allocator allocator_type; +#else + __TBB_STATIC_ASSERT( + (tbb::internal::is_same_type::value), + "Allocator template parameter for flow graph nodes is deprecated and will be removed. " + "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface." + ); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename base_type::predecessor_type predecessor_type; + typedef typename base_type::predecessor_list_type predecessor_list_type; + typedef internal::predecessor_cache predecessor_cache_type; + typedef typename predecessor_cache_type::built_predecessors_type built_predecessors_type; +#endif + + typedef typename internal::wrap_tuple_elements< + N, // #elements in tuple + internal::multifunction_output, // wrap this around each element + TupleType // the tuple providing the types + >::type output_ports_type; + + __TBB_NOINLINE_SYM explicit split_node(graph &g) + : graph_node(g), + my_output_ports(internal::init_output_ports::call(g, my_output_ports)) + { + tbb::internal::fgt_multioutput_node(CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->my_graph, + static_cast *>(this), this->output_ports()); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + __TBB_NOINLINE_SYM split_node(const node_set& nodes) : split_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + __TBB_NOINLINE_SYM split_node(const split_node& other) + : graph_node(other.my_graph), base_type(other), + my_output_ports(internal::init_output_ports::call(other.my_graph, my_output_ports)) + { + tbb::internal::fgt_multioutput_node(CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->my_graph, + static_cast *>(this), this->output_ports()); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_multioutput_node_desc( this, name ); + } +#endif + + output_ports_type &output_ports() { return my_output_ports; } + +protected: + task *try_put_task(const TupleType& t) __TBB_override { + // Sending split messages in parallel is not justified, as overheads would prevail. + // Also, we do not have successors here. So we just tell the task returned here is successful. + return internal::emit_element::emit_this(this->my_graph, t, output_ports()); + } + void reset_node(reset_flags f) __TBB_override { + if (f & rf_clear_edges) + internal::clear_element::clear_this(my_output_ports); + + __TBB_ASSERT(!(f & rf_clear_edges) || internal::clear_element::this_empty(my_output_ports), "split_node reset failed"); + } + void reset_receiver(reset_flags /*f*/) __TBB_override {} + graph& graph_reference() const __TBB_override { + return my_graph; + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +private: //! split_node doesn't use this "predecessors" functionality; so, we have "dummies" here; + void extract() __TBB_override {} + + //! Adds to list of predecessors added by make_edge + void internal_add_built_predecessor(predecessor_type&) __TBB_override {} + + //! removes from to list of predecessors (used by remove_edge) + void internal_delete_built_predecessor(predecessor_type&) __TBB_override {} + + size_t predecessor_count() __TBB_override { return 0; } + + void copy_predecessors(predecessor_list_type&) __TBB_override {} + + built_predecessors_type &built_predecessors() __TBB_override { return my_predessors; } + + //! dummy member + built_predecessors_type my_predessors; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +private: + output_ports_type my_output_ports; +}; + +//! Implements an executable node that supports continue_msg -> Output +template > +class continue_node : public graph_node, public internal::continue_input, + public internal::function_output { +public: + typedef continue_msg input_type; + typedef Output output_type; + typedef internal::continue_input input_impl_type; + typedef internal::function_output fOutput_type; + typedef typename input_impl_type::predecessor_type predecessor_type; + typedef typename fOutput_type::successor_type successor_type; + + //! Constructor for executable node with continue_msg -> Output + template + __TBB_NOINLINE_SYM continue_node( + graph &g, +#if __TBB_CPP11_PRESENT + Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority ) +#else + __TBB_FLOW_GRAPH_PRIORITY_ARG1( Body body, node_priority_t priority = tbb::flow::internal::no_priority ) +#endif + ) : graph_node(g), input_impl_type( g, __TBB_FLOW_GRAPH_PRIORITY_ARG1(body, priority) ), + fOutput_type(g) { + tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, + + static_cast *>(this), + static_cast *>(this), this->my_body ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT + template + continue_node( graph& g, Body body, node_priority_t priority ) + : continue_node(g, body, Policy(), priority) {} +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + continue_node( const node_set& nodes, Body body, + __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy p = Policy(), node_priority_t priority = tbb::flow::internal::no_priority)) + : continue_node(nodes.graph_reference(), body, __TBB_FLOW_GRAPH_PRIORITY_ARG1(p, priority) ) { + make_edges_in_order(nodes, *this); + } +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + template + continue_node( const node_set& nodes, Body body, node_priority_t priority) + : continue_node(nodes, body, Policy(), priority) {} +#endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + + //! Constructor for executable node with continue_msg -> Output + template + __TBB_NOINLINE_SYM continue_node( + graph &g, int number_of_predecessors, +#if __TBB_CPP11_PRESENT + Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority ) +#else + __TBB_FLOW_GRAPH_PRIORITY_ARG1( Body body, node_priority_t priority = tbb::flow::internal::no_priority ) +#endif + ) : graph_node(g) + , input_impl_type(g, number_of_predecessors, __TBB_FLOW_GRAPH_PRIORITY_ARG1(body, priority)), + fOutput_type(g) { + tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, + static_cast *>(this), + static_cast *>(this), this->my_body ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT + template + continue_node( graph& g, int number_of_predecessors, Body body, node_priority_t priority) + : continue_node(g, number_of_predecessors, body, Policy(), priority) {} +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + continue_node( const node_set& nodes, int number_of_predecessors, + Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy p = Policy(), node_priority_t priority = tbb::flow::internal::no_priority )) + : continue_node(nodes.graph_reference(), number_of_predecessors, body, __TBB_FLOW_GRAPH_PRIORITY_ARG1(p, priority)) { + make_edges_in_order(nodes, *this); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + template + continue_node( const node_set& nodes, int number_of_predecessors, + Body body, node_priority_t priority ) + : continue_node(nodes, number_of_predecessors, body, Policy(), priority) {} +#endif +#endif + + //! Copy constructor + __TBB_NOINLINE_SYM continue_node( const continue_node& src ) : + graph_node(src.my_graph), input_impl_type(src), + internal::function_output(src.my_graph) { + tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph, + static_cast *>(this), + static_cast *>(this), this->my_body ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract() __TBB_override { + input_impl_type::my_built_predecessors.receiver_extract(*this); + successors().built_successors().sender_extract(*this); + } +#endif + +protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + using input_impl_type::try_put_task; + internal::broadcast_cache &successors () __TBB_override { return fOutput_type::my_successors; } + + void reset_node(reset_flags f) __TBB_override { + input_impl_type::reset_receiver(f); + if(f & rf_clear_edges)successors().clear(); + __TBB_ASSERT(!(f & rf_clear_edges) || successors().empty(), "continue_node not reset"); + } +}; // continue_node + +//! Forwards messages of type T to all successors +template +class broadcast_node : public graph_node, public receiver, public sender { +public: + typedef T input_type; + typedef T output_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename receiver::predecessor_list_type predecessor_list_type; + typedef typename sender::successor_list_type successor_list_type; +#endif +private: + internal::broadcast_cache my_successors; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + internal::edge_container my_built_predecessors; + spin_mutex pred_mutex; // serialize accesses on edge_container +#endif +public: + + __TBB_NOINLINE_SYM explicit broadcast_node(graph& g) : graph_node(g) { + my_successors.set_owner( this ); + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + broadcast_node(const node_set& nodes) : broadcast_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM broadcast_node( const broadcast_node& src ) : + graph_node(src.my_graph), receiver(), sender() + { + my_successors.set_owner( this ); + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + + //! Adds a successor + bool register_successor( successor_type &r ) __TBB_override { + my_successors.register_successor( r ); + return true; + } + + //! Removes s as a successor + bool remove_successor( successor_type &r ) __TBB_override { + my_successors.remove_successor( r ); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename sender::built_successors_type built_successors_type; + + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + + void internal_add_built_successor(successor_type &r) __TBB_override { + my_successors.internal_add_built_successor(r); + } + + void internal_delete_built_successor(successor_type &r) __TBB_override { + my_successors.internal_delete_built_successor(r); + } + + size_t successor_count() __TBB_override { + return my_successors.successor_count(); + } + + void copy_successors(successor_list_type &v) __TBB_override { + my_successors.copy_successors(v); + } + + typedef typename receiver::built_predecessors_type built_predecessors_type; + + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + + void internal_add_built_predecessor( predecessor_type &p) __TBB_override { + spin_mutex::scoped_lock l(pred_mutex); + my_built_predecessors.add_edge(p); + } + + void internal_delete_built_predecessor( predecessor_type &p) __TBB_override { + spin_mutex::scoped_lock l(pred_mutex); + my_built_predecessors.delete_edge(p); + } + + size_t predecessor_count() __TBB_override { + spin_mutex::scoped_lock l(pred_mutex); + return my_built_predecessors.edge_count(); + } + + void copy_predecessors(predecessor_list_type &v) __TBB_override { + spin_mutex::scoped_lock l(pred_mutex); + my_built_predecessors.copy_edges(v); + } + + void extract() __TBB_override { + my_built_predecessors.receiver_extract(*this); + my_successors.built_successors().sender_extract(*this); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + //! build a task to run the successor if possible. Default is old behavior. + task *try_put_task(const T& t) __TBB_override { + task *new_task = my_successors.try_put_task(t); + if (!new_task) new_task = SUCCESSFULLY_ENQUEUED; + return new_task; + } + + graph& graph_reference() const __TBB_override { + return my_graph; + } + + void reset_receiver(reset_flags /*f*/) __TBB_override {} + + void reset_node(reset_flags f) __TBB_override { + if (f&rf_clear_edges) { + my_successors.clear(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + my_built_predecessors.clear(); +#endif + } + __TBB_ASSERT(!(f & rf_clear_edges) || my_successors.empty(), "Error resetting broadcast_node"); + } +}; // broadcast_node + +//! Forwards messages in arbitrary order +template +class buffer_node + : public graph_node +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + , public internal::reservable_item_buffer< T, Allocator > +#else + , public internal::reservable_item_buffer< T, cache_aligned_allocator > +#endif + , public receiver, public sender { +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + typedef Allocator internals_allocator; +#else + typedef cache_aligned_allocator internals_allocator; +#endif +public: + typedef T input_type; + typedef T output_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; + typedef buffer_node class_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename receiver::predecessor_list_type predecessor_list_type; + typedef typename sender::successor_list_type successor_list_type; +#endif +#if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + __TBB_STATIC_ASSERT( + (tbb::internal::is_same_type::value), + "Allocator template parameter for flow graph nodes is deprecated and will be removed. " + "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface." + ); +#endif + +protected: + typedef size_t size_type; + internal::round_robin_cache< T, null_rw_mutex > my_successors; + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + internal::edge_container my_built_predecessors; +#endif + + friend class internal::forward_task_bypass< class_type >; + + enum op_type {reg_succ, rem_succ, req_item, res_item, rel_res, con_res, put_item, try_fwd_task +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + , add_blt_succ, del_blt_succ, + add_blt_pred, del_blt_pred, + blt_succ_cnt, blt_pred_cnt, + blt_succ_cpy, blt_pred_cpy // create vector copies of preds and succs +#endif + }; + + // implements the aggregator_operation concept + class buffer_operation : public internal::aggregated_operation< buffer_operation > { + public: + char type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + task * ltask; + union { + input_type *elem; + successor_type *r; + predecessor_type *p; + size_t cnt_val; + successor_list_type *svec; + predecessor_list_type *pvec; + }; +#else + T *elem; + task * ltask; + successor_type *r; +#endif + buffer_operation(const T& e, op_type t) : type(char(t)) + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + , ltask(NULL), elem(const_cast(&e)) +#else + , elem(const_cast(&e)) , ltask(NULL) +#endif + {} + buffer_operation(op_type t) : type(char(t)), ltask(NULL) {} + }; + + bool forwarder_busy; + typedef internal::aggregating_functor handler_type; + friend class internal::aggregating_functor; + internal::aggregator< handler_type, buffer_operation> my_aggregator; + + virtual void handle_operations(buffer_operation *op_list) { + handle_operations_impl(op_list, this); + } + + template + void handle_operations_impl(buffer_operation *op_list, derived_type* derived) { + __TBB_ASSERT(static_cast(derived) == this, "'this' is not a base class for derived"); + + buffer_operation *tmp = NULL; + bool try_forwarding = false; + while (op_list) { + tmp = op_list; + op_list = op_list->next; + switch (tmp->type) { + case reg_succ: internal_reg_succ(tmp); try_forwarding = true; break; + case rem_succ: internal_rem_succ(tmp); break; + case req_item: internal_pop(tmp); break; + case res_item: internal_reserve(tmp); break; + case rel_res: internal_release(tmp); try_forwarding = true; break; + case con_res: internal_consume(tmp); try_forwarding = true; break; + case put_item: try_forwarding = internal_push(tmp); break; + case try_fwd_task: internal_forward_task(tmp); break; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + // edge recording + case add_blt_succ: internal_add_built_succ(tmp); break; + case del_blt_succ: internal_del_built_succ(tmp); break; + case add_blt_pred: internal_add_built_pred(tmp); break; + case del_blt_pred: internal_del_built_pred(tmp); break; + case blt_succ_cnt: internal_succ_cnt(tmp); break; + case blt_pred_cnt: internal_pred_cnt(tmp); break; + case blt_succ_cpy: internal_copy_succs(tmp); break; + case blt_pred_cpy: internal_copy_preds(tmp); break; +#endif + } + } + + derived->order(); + + if (try_forwarding && !forwarder_busy) { + if(internal::is_graph_active(this->my_graph)) { + forwarder_busy = true; + task *new_task = new(task::allocate_additional_child_of(*(this->my_graph.root_task()))) internal:: + forward_task_bypass(*this); + // tmp should point to the last item handled by the aggregator. This is the operation + // the handling thread enqueued. So modifying that record will be okay. + // workaround for icc bug + tbb::task *z = tmp->ltask; + graph &g = this->my_graph; + tmp->ltask = combine_tasks(g, z, new_task); // in case the op generated a task + } + } + } // handle_operations + + inline task *grab_forwarding_task( buffer_operation &op_data) { + return op_data.ltask; + } + + inline bool enqueue_forwarding_task(buffer_operation &op_data) { + task *ft = grab_forwarding_task(op_data); + if(ft) { + internal::spawn_in_graph_arena(graph_reference(), *ft); + return true; + } + return false; + } + + //! This is executed by an enqueued task, the "forwarder" + virtual task *forward_task() { + buffer_operation op_data(try_fwd_task); + task *last_task = NULL; + do { + op_data.status = internal::WAIT; + op_data.ltask = NULL; + my_aggregator.execute(&op_data); + + // workaround for icc bug + tbb::task *xtask = op_data.ltask; + graph& g = this->my_graph; + last_task = combine_tasks(g, last_task, xtask); + } while (op_data.status ==internal::SUCCEEDED); + return last_task; + } + + //! Register successor + virtual void internal_reg_succ(buffer_operation *op) { + my_successors.register_successor(*(op->r)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + //! Remove successor + virtual void internal_rem_succ(buffer_operation *op) { + my_successors.remove_successor(*(op->r)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename sender::built_successors_type built_successors_type; + + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + + virtual void internal_add_built_succ(buffer_operation *op) { + my_successors.internal_add_built_successor(*(op->r)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + virtual void internal_del_built_succ(buffer_operation *op) { + my_successors.internal_delete_built_successor(*(op->r)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + typedef typename receiver::built_predecessors_type built_predecessors_type; + + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + + virtual void internal_add_built_pred(buffer_operation *op) { + my_built_predecessors.add_edge(*(op->p)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + virtual void internal_del_built_pred(buffer_operation *op) { + my_built_predecessors.delete_edge(*(op->p)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + virtual void internal_succ_cnt(buffer_operation *op) { + op->cnt_val = my_successors.successor_count(); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + virtual void internal_pred_cnt(buffer_operation *op) { + op->cnt_val = my_built_predecessors.edge_count(); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + virtual void internal_copy_succs(buffer_operation *op) { + my_successors.copy_successors(*(op->svec)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + virtual void internal_copy_preds(buffer_operation *op) { + my_built_predecessors.copy_edges(*(op->pvec)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +private: + void order() {} + + bool is_item_valid() { + return this->my_item_valid(this->my_tail - 1); + } + + void try_put_and_add_task(task*& last_task) { + task *new_task = my_successors.try_put_task(this->back()); + if (new_task) { + // workaround for icc bug + graph& g = this->my_graph; + last_task = combine_tasks(g, last_task, new_task); + this->destroy_back(); + } + } + +protected: + //! Tries to forward valid items to successors + virtual void internal_forward_task(buffer_operation *op) { + internal_forward_task_impl(op, this); + } + + template + void internal_forward_task_impl(buffer_operation *op, derived_type* derived) { + __TBB_ASSERT(static_cast(derived) == this, "'this' is not a base class for derived"); + + if (this->my_reserved || !derived->is_item_valid()) { + __TBB_store_with_release(op->status, internal::FAILED); + this->forwarder_busy = false; + return; + } + // Try forwarding, giving each successor a chance + task * last_task = NULL; + size_type counter = my_successors.size(); + for (; counter > 0 && derived->is_item_valid(); --counter) + derived->try_put_and_add_task(last_task); + + op->ltask = last_task; // return task + if (last_task && !counter) { + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + else { + __TBB_store_with_release(op->status, internal::FAILED); + forwarder_busy = false; + } + } + + virtual bool internal_push(buffer_operation *op) { + this->push_back(*(op->elem)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + return true; + } + + virtual void internal_pop(buffer_operation *op) { + if(this->pop_back(*(op->elem))) { + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + else { + __TBB_store_with_release(op->status, internal::FAILED); + } + } + + virtual void internal_reserve(buffer_operation *op) { + if(this->reserve_front(*(op->elem))) { + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + else { + __TBB_store_with_release(op->status, internal::FAILED); + } + } + + virtual void internal_consume(buffer_operation *op) { + this->consume_front(); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + + virtual void internal_release(buffer_operation *op) { + this->release_front(); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + +public: + //! Constructor + __TBB_NOINLINE_SYM explicit buffer_node( graph &g ) + : graph_node(g), internal::reservable_item_buffer(), receiver(), + sender(), forwarder_busy(false) + { + my_successors.set_owner(this); + my_aggregator.initialize_handler(handler_type(this)); + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_BUFFER_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + buffer_node(const node_set& nodes) : buffer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + //! Copy constructor + __TBB_NOINLINE_SYM buffer_node( const buffer_node& src ) + : graph_node(src.my_graph), internal::reservable_item_buffer(), + receiver(), sender(), forwarder_busy(false) + { + my_successors.set_owner(this); + my_aggregator.initialize_handler(handler_type(this)); + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_BUFFER_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + + // + // message sender implementation + // + + //! Adds a new successor. + /** Adds successor r to the list of successors; may forward tasks. */ + bool register_successor( successor_type &r ) __TBB_override { + buffer_operation op_data(reg_succ); + op_data.r = &r; + my_aggregator.execute(&op_data); + (void)enqueue_forwarding_task(op_data); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void internal_add_built_successor( successor_type &r) __TBB_override { + buffer_operation op_data(add_blt_succ); + op_data.r = &r; + my_aggregator.execute(&op_data); + } + + void internal_delete_built_successor( successor_type &r) __TBB_override { + buffer_operation op_data(del_blt_succ); + op_data.r = &r; + my_aggregator.execute(&op_data); + } + + void internal_add_built_predecessor( predecessor_type &p) __TBB_override { + buffer_operation op_data(add_blt_pred); + op_data.p = &p; + my_aggregator.execute(&op_data); + } + + void internal_delete_built_predecessor( predecessor_type &p) __TBB_override { + buffer_operation op_data(del_blt_pred); + op_data.p = &p; + my_aggregator.execute(&op_data); + } + + size_t predecessor_count() __TBB_override { + buffer_operation op_data(blt_pred_cnt); + my_aggregator.execute(&op_data); + return op_data.cnt_val; + } + + size_t successor_count() __TBB_override { + buffer_operation op_data(blt_succ_cnt); + my_aggregator.execute(&op_data); + return op_data.cnt_val; + } + + void copy_predecessors( predecessor_list_type &v ) __TBB_override { + buffer_operation op_data(blt_pred_cpy); + op_data.pvec = &v; + my_aggregator.execute(&op_data); + } + + void copy_successors( successor_list_type &v ) __TBB_override { + buffer_operation op_data(blt_succ_cpy); + op_data.svec = &v; + my_aggregator.execute(&op_data); + } + +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + //! Removes a successor. + /** Removes successor r from the list of successors. + It also calls r.remove_predecessor(*this) to remove this node as a predecessor. */ + bool remove_successor( successor_type &r ) __TBB_override { + r.remove_predecessor(*this); + buffer_operation op_data(rem_succ); + op_data.r = &r; + my_aggregator.execute(&op_data); + // even though this operation does not cause a forward, if we are the handler, and + // a forward is scheduled, we may be the first to reach this point after the aggregator, + // and so should check for the task. + (void)enqueue_forwarding_task(op_data); + return true; + } + + //! Request an item from the buffer_node + /** true = v contains the returned item
+ false = no item has been returned */ + bool try_get( T &v ) __TBB_override { + buffer_operation op_data(req_item); + op_data.elem = &v; + my_aggregator.execute(&op_data); + (void)enqueue_forwarding_task(op_data); + return (op_data.status==internal::SUCCEEDED); + } + + //! Reserves an item. + /** false = no item can be reserved
+ true = an item is reserved */ + bool try_reserve( T &v ) __TBB_override { + buffer_operation op_data(res_item); + op_data.elem = &v; + my_aggregator.execute(&op_data); + (void)enqueue_forwarding_task(op_data); + return (op_data.status==internal::SUCCEEDED); + } + + //! Release a reserved item. + /** true = item has been released and so remains in sender */ + bool try_release() __TBB_override { + buffer_operation op_data(rel_res); + my_aggregator.execute(&op_data); + (void)enqueue_forwarding_task(op_data); + return true; + } + + //! Consumes a reserved item. + /** true = item is removed from sender and reservation removed */ + bool try_consume() __TBB_override { + buffer_operation op_data(con_res); + my_aggregator.execute(&op_data); + (void)enqueue_forwarding_task(op_data); + return true; + } + +protected: + + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + //! receive an item, return a task *if possible + task *try_put_task(const T &t) __TBB_override { + buffer_operation op_data(t, put_item); + my_aggregator.execute(&op_data); + task *ft = grab_forwarding_task(op_data); + // sequencer_nodes can return failure (if an item has been previously inserted) + // We have to spawn the returned task if our own operation fails. + + if(ft && op_data.status ==internal::FAILED) { + // we haven't succeeded queueing the item, but for some reason the + // call returned a task (if another request resulted in a successful + // forward this could happen.) Queue the task and reset the pointer. + internal::spawn_in_graph_arena(graph_reference(), *ft); ft = NULL; + } + else if(!ft && op_data.status ==internal::SUCCEEDED) { + ft = SUCCESSFULLY_ENQUEUED; + } + return ft; + } + + graph& graph_reference() const __TBB_override { + return my_graph; + } + + void reset_receiver(reset_flags /*f*/) __TBB_override { } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +public: + void extract() __TBB_override { + my_built_predecessors.receiver_extract(*this); + my_successors.built_successors().sender_extract(*this); + } +#endif + +protected: + void reset_node( reset_flags f) __TBB_override { + internal::reservable_item_buffer::reset(); + // TODO: just clear structures + if (f&rf_clear_edges) { + my_successors.clear(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + my_built_predecessors.clear(); +#endif + } + forwarder_busy = false; + } +}; // buffer_node + +//! Forwards messages in FIFO order +template +class queue_node : public buffer_node { +#if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + __TBB_STATIC_ASSERT( + (tbb::internal::is_same_type::value), + "Allocator template parameter for flow graph nodes is deprecated and will be removed. " + "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface." + ); +#endif +protected: + typedef buffer_node base_type; + typedef typename base_type::size_type size_type; + typedef typename base_type::buffer_operation queue_operation; + typedef queue_node class_type; + +private: + template friend class buffer_node; + + bool is_item_valid() { + return this->my_item_valid(this->my_head); + } + + void try_put_and_add_task(task*& last_task) { + task *new_task = this->my_successors.try_put_task(this->front()); + if (new_task) { + // workaround for icc bug + graph& graph_ref = this->graph_reference(); + last_task = combine_tasks(graph_ref, last_task, new_task); + this->destroy_front(); + } + } + +protected: + void internal_forward_task(queue_operation *op) __TBB_override { + this->internal_forward_task_impl(op, this); + } + + void internal_pop(queue_operation *op) __TBB_override { + if ( this->my_reserved || !this->my_item_valid(this->my_head)){ + __TBB_store_with_release(op->status, internal::FAILED); + } + else { + this->pop_front(*(op->elem)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + } + void internal_reserve(queue_operation *op) __TBB_override { + if (this->my_reserved || !this->my_item_valid(this->my_head)) { + __TBB_store_with_release(op->status, internal::FAILED); + } + else { + this->reserve_front(*(op->elem)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + } + void internal_consume(queue_operation *op) __TBB_override { + this->consume_front(); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + } + +public: + typedef T input_type; + typedef T output_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; + + //! Constructor + __TBB_NOINLINE_SYM explicit queue_node( graph &g ) : base_type(g) { + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph), + static_cast *>(this), + static_cast *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + queue_node( const node_set& nodes) : queue_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + //! Copy constructor + __TBB_NOINLINE_SYM queue_node( const queue_node& src) : base_type(src) { + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph), + static_cast *>(this), + static_cast *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +protected: + void reset_node( reset_flags f) __TBB_override { + base_type::reset_node(f); + } +}; // queue_node + +//! Forwards messages in sequence order +template< typename T, typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T) > +class sequencer_node : public queue_node { + internal::function_body< T, size_t > *my_sequencer; + // my_sequencer should be a benign function and must be callable + // from a parallel context. Does this mean it needn't be reset? +public: +#if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + __TBB_STATIC_ASSERT( + (tbb::internal::is_same_type::value), + "Allocator template parameter for flow graph nodes is deprecated and will be removed. " + "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface." + ); +#endif + typedef T input_type; + typedef T output_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; + + //! Constructor + template< typename Sequencer > + __TBB_NOINLINE_SYM sequencer_node( graph &g, const Sequencer& s ) : queue_node(g), + my_sequencer(new internal::function_body_leaf< T, size_t, Sequencer>(s) ) { + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph), + static_cast *>(this), + static_cast *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + sequencer_node( const node_set& nodes, const Sequencer& s) + : sequencer_node(nodes.graph_reference(), s) { + make_edges_in_order(nodes, *this); + } +#endif + + //! Copy constructor + __TBB_NOINLINE_SYM sequencer_node( const sequencer_node& src ) : queue_node(src), + my_sequencer( src.my_sequencer->clone() ) { + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph), + static_cast *>(this), + static_cast *>(this) ); + } + + //! Destructor + ~sequencer_node() { delete my_sequencer; } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +protected: + typedef typename buffer_node::size_type size_type; + typedef typename buffer_node::buffer_operation sequencer_operation; + +private: + bool internal_push(sequencer_operation *op) __TBB_override { + size_type tag = (*my_sequencer)(*(op->elem)); +#if !TBB_DEPRECATED_SEQUENCER_DUPLICATES + if (tag < this->my_head) { + // have already emitted a message with this tag + __TBB_store_with_release(op->status, internal::FAILED); + return false; + } +#endif + // cannot modify this->my_tail now; the buffer would be inconsistent. + size_t new_tail = (tag+1 > this->my_tail) ? tag+1 : this->my_tail; + + if (this->size(new_tail) > this->capacity()) { + this->grow_my_array(this->size(new_tail)); + } + this->my_tail = new_tail; + + const internal::op_stat res = this->place_item(tag, *(op->elem)) ? internal::SUCCEEDED : internal::FAILED; + __TBB_store_with_release(op->status, res); + return res ==internal::SUCCEEDED; + } +}; // sequencer_node + +//! Forwards messages in priority order +template, typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T)> +class priority_queue_node : public buffer_node { +public: +#if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + __TBB_STATIC_ASSERT( + (tbb::internal::is_same_type::value), + "Allocator template parameter for flow graph nodes is deprecated and will removed in the future. " + "To temporary enable the deprecated interface specify TBB_ENABLE_DEPRECATED_NODE_ALLOCATOR." + ); +#endif + typedef T input_type; + typedef T output_type; + typedef buffer_node base_type; + typedef priority_queue_node class_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; + + //! Constructor + __TBB_NOINLINE_SYM explicit priority_queue_node( graph &g, const Compare& comp = Compare() ) + : buffer_node(g), compare(comp), mark(0) { + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph), + static_cast *>(this), + static_cast *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + priority_queue_node(const node_set& nodes, const Compare& comp = Compare()) + : priority_queue_node(nodes.graph_reference(), comp) { + make_edges_in_order(nodes, *this); + } +#endif + + //! Copy constructor + __TBB_NOINLINE_SYM priority_queue_node( const priority_queue_node &src ) + : buffer_node(src), mark(0) + { + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph), + static_cast *>(this), + static_cast *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +protected: + + void reset_node( reset_flags f) __TBB_override { + mark = 0; + base_type::reset_node(f); + } + + typedef typename buffer_node::size_type size_type; + typedef typename buffer_node::item_type item_type; + typedef typename buffer_node::buffer_operation prio_operation; + + //! Tries to forward valid items to successors + void internal_forward_task(prio_operation *op) __TBB_override { + this->internal_forward_task_impl(op, this); + } + + void handle_operations(prio_operation *op_list) __TBB_override { + this->handle_operations_impl(op_list, this); + } + + bool internal_push(prio_operation *op) __TBB_override { + prio_push(*(op->elem)); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + return true; + } + + void internal_pop(prio_operation *op) __TBB_override { + // if empty or already reserved, don't pop + if ( this->my_reserved == true || this->my_tail == 0 ) { + __TBB_store_with_release(op->status, internal::FAILED); + return; + } + + *(op->elem) = prio(); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + prio_pop(); + + } + + // pops the highest-priority item, saves copy + void internal_reserve(prio_operation *op) __TBB_override { + if (this->my_reserved == true || this->my_tail == 0) { + __TBB_store_with_release(op->status, internal::FAILED); + return; + } + this->my_reserved = true; + *(op->elem) = prio(); + reserved_item = *(op->elem); + __TBB_store_with_release(op->status, internal::SUCCEEDED); + prio_pop(); + } + + void internal_consume(prio_operation *op) __TBB_override { + __TBB_store_with_release(op->status, internal::SUCCEEDED); + this->my_reserved = false; + reserved_item = input_type(); + } + + void internal_release(prio_operation *op) __TBB_override { + __TBB_store_with_release(op->status, internal::SUCCEEDED); + prio_push(reserved_item); + this->my_reserved = false; + reserved_item = input_type(); + } + +private: + template friend class buffer_node; + + void order() { + if (mark < this->my_tail) heapify(); + __TBB_ASSERT(mark == this->my_tail, "mark unequal after heapify"); + } + + bool is_item_valid() { + return this->my_tail > 0; + } + + void try_put_and_add_task(task*& last_task) { + task * new_task = this->my_successors.try_put_task(this->prio()); + if (new_task) { + // workaround for icc bug + graph& graph_ref = this->graph_reference(); + last_task = combine_tasks(graph_ref, last_task, new_task); + prio_pop(); + } + } + +private: + Compare compare; + size_type mark; + + input_type reserved_item; + + // in case a reheap has not been done after a push, check if the mark item is higher than the 0'th item + bool prio_use_tail() { + __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds before test"); + return mark < this->my_tail && compare(this->get_my_item(0), this->get_my_item(this->my_tail - 1)); + } + + // prio_push: checks that the item will fit, expand array if necessary, put at end + void prio_push(const T &src) { + if ( this->my_tail >= this->my_array_size ) + this->grow_my_array( this->my_tail + 1 ); + (void) this->place_item(this->my_tail, src); + ++(this->my_tail); + __TBB_ASSERT(mark < this->my_tail, "mark outside bounds after push"); + } + + // prio_pop: deletes highest priority item from the array, and if it is item + // 0, move last item to 0 and reheap. If end of array, just destroy and decrement tail + // and mark. Assumes the array has already been tested for emptiness; no failure. + void prio_pop() { + if (prio_use_tail()) { + // there are newly pushed elements; last one higher than top + // copy the data + this->destroy_item(this->my_tail-1); + --(this->my_tail); + __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop"); + return; + } + this->destroy_item(0); + if(this->my_tail > 1) { + // push the last element down heap + __TBB_ASSERT(this->my_item_valid(this->my_tail - 1), NULL); + this->move_item(0,this->my_tail - 1); + } + --(this->my_tail); + if(mark > this->my_tail) --mark; + if (this->my_tail > 1) // don't reheap for heap of size 1 + reheap(); + __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop"); + } + + const T& prio() { + return this->get_my_item(prio_use_tail() ? this->my_tail-1 : 0); + } + + // turn array into heap + void heapify() { + if(this->my_tail == 0) { + mark = 0; + return; + } + if (!mark) mark = 1; + for (; markmy_tail; ++mark) { // for each unheaped element + size_type cur_pos = mark; + input_type to_place; + this->fetch_item(mark,to_place); + do { // push to_place up the heap + size_type parent = (cur_pos-1)>>1; + if (!compare(this->get_my_item(parent), to_place)) + break; + this->move_item(cur_pos, parent); + cur_pos = parent; + } while( cur_pos ); + (void) this->place_item(cur_pos, to_place); + } + } + + // otherwise heapified array with new root element; rearrange to heap + void reheap() { + size_type cur_pos=0, child=1; + while (child < mark) { + size_type target = child; + if (child+1get_my_item(child), + this->get_my_item(child+1))) + ++target; + // target now has the higher priority child + if (compare(this->get_my_item(target), + this->get_my_item(cur_pos))) + break; + // swap + this->swap_items(cur_pos, target); + cur_pos = target; + child = (cur_pos<<1)+1; + } + } +}; // priority_queue_node + +} // interfaceX + +namespace interface11 { + +//! Forwards messages only if the threshold has not been reached +/** This node forwards items until its threshold is reached. + It contains no buffering. If the downstream node rejects, the + message is dropped. */ +template< typename T, typename DecrementType=continue_msg > +class limiter_node : public graph_node, public receiver< T >, public sender< T > { +public: + typedef T input_type; + typedef T output_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename receiver::built_predecessors_type built_predecessors_type; + typedef typename sender::built_successors_type built_successors_type; + typedef typename receiver::predecessor_list_type predecessor_list_type; + typedef typename sender::successor_list_type successor_list_type; +#endif + //TODO: There is a lack of predefined types for its controlling "decrementer" port. It should be fixed later. + +private: + size_t my_threshold; + size_t my_count; //number of successful puts + size_t my_tries; //number of active put attempts + internal::reservable_predecessor_cache< T, spin_mutex > my_predecessors; + spin_mutex my_mutex; + internal::broadcast_cache< T > my_successors; + __TBB_DEPRECATED_LIMITER_EXPR( int init_decrement_predecessors; ) + + friend class internal::forward_task_bypass< limiter_node >; + + // Let decrementer call decrement_counter() + friend class internal::decrementer< limiter_node, DecrementType >; + + bool check_conditions() { // always called under lock + return ( my_count + my_tries < my_threshold && !my_predecessors.empty() && !my_successors.empty() ); + } + + // only returns a valid task pointer or NULL, never SUCCESSFULLY_ENQUEUED + task *forward_task() { + input_type v; + task *rval = NULL; + bool reserved = false; + { + spin_mutex::scoped_lock lock(my_mutex); + if ( check_conditions() ) + ++my_tries; + else + return NULL; + } + + //SUCCESS + // if we can reserve and can put, we consume the reservation + // we increment the count and decrement the tries + if ( (my_predecessors.try_reserve(v)) == true ){ + reserved=true; + if ( (rval = my_successors.try_put_task(v)) != NULL ){ + { + spin_mutex::scoped_lock lock(my_mutex); + ++my_count; + --my_tries; + my_predecessors.try_consume(); + if ( check_conditions() ) { + if ( internal::is_graph_active(this->my_graph) ) { + task *rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) + internal::forward_task_bypass< limiter_node >( *this ); + internal::spawn_in_graph_arena(graph_reference(), *rtask); + } + } + } + return rval; + } + } + //FAILURE + //if we can't reserve, we decrement the tries + //if we can reserve but can't put, we decrement the tries and release the reservation + { + spin_mutex::scoped_lock lock(my_mutex); + --my_tries; + if (reserved) my_predecessors.try_release(); + if ( check_conditions() ) { + if ( internal::is_graph_active(this->my_graph) ) { + task *rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) + internal::forward_task_bypass< limiter_node >( *this ); + __TBB_ASSERT(!rval, "Have two tasks to handle"); + return rtask; + } + } + return rval; + } + } + + void forward() { + __TBB_ASSERT(false, "Should never be called"); + return; + } + + task* decrement_counter( long long delta ) { + { + spin_mutex::scoped_lock lock(my_mutex); + if( delta > 0 && size_t(delta) > my_count ) + my_count = 0; + else if( delta < 0 && size_t(delta) > my_threshold - my_count ) + my_count = my_threshold; + else + my_count -= size_t(delta); // absolute value of delta is sufficiently small + } + return forward_task(); + } + + void initialize() { + my_predecessors.set_owner(this); + my_successors.set_owner(this); + decrement.set_owner(this); + tbb::internal::fgt_node( + CODEPTR(), tbb::internal::FLOW_LIMITER_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(&decrement), + static_cast *>(this) + ); + } +public: + //! The internal receiver< DecrementType > that decrements the count + internal::decrementer< limiter_node, DecrementType > decrement; + +#if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR + __TBB_STATIC_ASSERT( (tbb::internal::is_same_type::value), + "Deprecated interface of the limiter node can be used only in conjunction " + "with continue_msg as the type of DecrementType template parameter." ); +#endif // Check for incompatible interface + + //! Constructor + limiter_node(graph &g, + __TBB_DEPRECATED_LIMITER_ARG2(size_t threshold, int num_decrement_predecessors=0)) + : graph_node(g), my_threshold(threshold), my_count(0), + __TBB_DEPRECATED_LIMITER_ARG4( + my_tries(0), decrement(), + init_decrement_predecessors(num_decrement_predecessors), + decrement(num_decrement_predecessors)) { + initialize(); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + limiter_node(const node_set& nodes, size_t threshold) + : limiter_node(nodes.graph_reference(), threshold) { + make_edges_in_order(nodes, *this); + } +#endif + + //! Copy constructor + limiter_node( const limiter_node& src ) : + graph_node(src.my_graph), receiver(), sender(), + my_threshold(src.my_threshold), my_count(0), + __TBB_DEPRECATED_LIMITER_ARG4( + my_tries(0), decrement(), + init_decrement_predecessors(src.init_decrement_predecessors), + decrement(src.init_decrement_predecessors)) { + initialize(); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + + //! Replace the current successor with this new successor + bool register_successor( successor_type &r ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + bool was_empty = my_successors.empty(); + my_successors.register_successor(r); + //spawn a forward task if this is the only successor + if ( was_empty && !my_predecessors.empty() && my_count + my_tries < my_threshold ) { + if ( internal::is_graph_active(this->my_graph) ) { + task* task = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) + internal::forward_task_bypass < limiter_node >( *this ); + internal::spawn_in_graph_arena(graph_reference(), *task); + } + } + return true; + } + + //! Removes a successor from this node + /** r.remove_predecessor(*this) is also called. */ + bool remove_successor( successor_type &r ) __TBB_override { + r.remove_predecessor(*this); + my_successors.remove_successor(r); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + built_predecessors_type &built_predecessors() __TBB_override { return my_predecessors.built_predecessors(); } + + void internal_add_built_successor(successor_type &src) __TBB_override { + my_successors.internal_add_built_successor(src); + } + + void internal_delete_built_successor(successor_type &src) __TBB_override { + my_successors.internal_delete_built_successor(src); + } + + size_t successor_count() __TBB_override { return my_successors.successor_count(); } + + void copy_successors(successor_list_type &v) __TBB_override { + my_successors.copy_successors(v); + } + + void internal_add_built_predecessor(predecessor_type &src) __TBB_override { + my_predecessors.internal_add_built_predecessor(src); + } + + void internal_delete_built_predecessor(predecessor_type &src) __TBB_override { + my_predecessors.internal_delete_built_predecessor(src); + } + + size_t predecessor_count() __TBB_override { return my_predecessors.predecessor_count(); } + + void copy_predecessors(predecessor_list_type &v) __TBB_override { + my_predecessors.copy_predecessors(v); + } + + void extract() __TBB_override { + my_count = 0; + my_successors.built_successors().sender_extract(*this); + my_predecessors.built_predecessors().receiver_extract(*this); + decrement.built_predecessors().receiver_extract(decrement); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + //! Adds src to the list of cached predecessors. + bool register_predecessor( predecessor_type &src ) __TBB_override { + spin_mutex::scoped_lock lock(my_mutex); + my_predecessors.add( src ); + if ( my_count + my_tries < my_threshold && !my_successors.empty() && internal::is_graph_active(this->my_graph) ) { + task* task = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) + internal::forward_task_bypass < limiter_node >( *this ); + internal::spawn_in_graph_arena(graph_reference(), *task); + } + return true; + } + + //! Removes src from the list of cached predecessors. + bool remove_predecessor( predecessor_type &src ) __TBB_override { + my_predecessors.remove( src ); + return true; + } + +protected: + + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + //! Puts an item to this receiver + task *try_put_task( const T &t ) __TBB_override { + { + spin_mutex::scoped_lock lock(my_mutex); + if ( my_count + my_tries >= my_threshold ) + return NULL; + else + ++my_tries; + } + + task * rtask = my_successors.try_put_task(t); + + if ( !rtask ) { // try_put_task failed. + spin_mutex::scoped_lock lock(my_mutex); + --my_tries; + if (check_conditions() && internal::is_graph_active(this->my_graph)) { + rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) ) + internal::forward_task_bypass< limiter_node >( *this ); + } + } + else { + spin_mutex::scoped_lock lock(my_mutex); + ++my_count; + --my_tries; + } + return rtask; + } + + graph& graph_reference() const __TBB_override { return my_graph; } + + void reset_receiver(reset_flags /*f*/) __TBB_override { + __TBB_ASSERT(false,NULL); // should never be called + } + + void reset_node( reset_flags f) __TBB_override { + my_count = 0; + if(f & rf_clear_edges) { + my_predecessors.clear(); + my_successors.clear(); + } + else + { + my_predecessors.reset( ); + } + decrement.reset_receiver(f); + } +}; // limiter_node + +#include "internal/_flow_graph_join_impl.h" + +using internal::reserving_port; +using internal::queueing_port; +using internal::key_matching_port; +using internal::input_port; +using internal::tag_value; + +template class join_node; + +template +class join_node: public internal::unfolded_join_node::value, reserving_port, OutputTuple, reserving> { +private: + static const int N = tbb::flow::tuple_size::value; + typedef typename internal::unfolded_join_node unfolded_type; +public: + typedef OutputTuple output_type; + typedef typename unfolded_type::input_ports_type input_ports_type; + __TBB_NOINLINE_SYM explicit join_node(graph &g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + __TBB_NOINLINE_SYM join_node(const node_set& nodes, reserving = reserving()) : join_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + __TBB_NOINLINE_SYM join_node(const join_node &other) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +}; + +template +class join_node: public internal::unfolded_join_node::value, queueing_port, OutputTuple, queueing> { +private: + static const int N = tbb::flow::tuple_size::value; + typedef typename internal::unfolded_join_node unfolded_type; +public: + typedef OutputTuple output_type; + typedef typename unfolded_type::input_ports_type input_ports_type; + __TBB_NOINLINE_SYM explicit join_node(graph &g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + __TBB_NOINLINE_SYM join_node(const node_set& nodes, queueing = queueing()) : join_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + __TBB_NOINLINE_SYM join_node(const join_node &other) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +}; + +// template for key_matching join_node +// tag_matching join_node is a specialization of key_matching, and is source-compatible. +template +class join_node > : public internal::unfolded_join_node::value, + key_matching_port, OutputTuple, key_matching > { +private: + static const int N = tbb::flow::tuple_size::value; + typedef typename internal::unfolded_join_node > unfolded_type; +public: + typedef OutputTuple output_type; + typedef typename unfolded_type::input_ports_type input_ports_type; + +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + join_node(graph &g) : unfolded_type(g) {} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + join_node(const node_set& nodes, key_matching = key_matching()) + : join_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1) : unfolded_type(g, b0, b1) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2) : unfolded_type(g, b0, b1, b2) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3) : unfolded_type(g, b0, b1, b2, b3) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4) : + unfolded_type(g, b0, b1, b2, b3, b4) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } +#if __TBB_VARIADIC_MAX >= 6 + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5) : + unfolded_type(g, b0, b1, b2, b3, b4, b5) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } +#endif +#if __TBB_VARIADIC_MAX >= 7 + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6) : + unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } +#endif +#if __TBB_VARIADIC_MAX >= 8 + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, + __TBB_B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } +#endif +#if __TBB_VARIADIC_MAX >= 9 + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, + __TBB_B7 b7, __TBB_B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } +#endif +#if __TBB_VARIADIC_MAX >= 10 + template + __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, + __TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + __TBB_NOINLINE_SYM join_node(const node_set& nodes, Bodies... bodies) + : join_node(nodes.graph_reference(), bodies...) { + make_edges_in_order(nodes, *this); + } +#endif + + __TBB_NOINLINE_SYM join_node(const join_node &other) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +}; + +// indexer node +#include "internal/_flow_graph_indexer_impl.h" + +// TODO: Implement interface with variadic template or tuple +template class indexer_node; + +//indexer node specializations +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 1; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; + +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 2; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; + +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 3; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; + +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 4; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; + +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 5; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; + +#if __TBB_VARIADIC_MAX >= 6 +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 6; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; +#endif //variadic max 6 + +#if __TBB_VARIADIC_MAX >= 7 +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 7; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; +#endif //variadic max 7 + +#if __TBB_VARIADIC_MAX >= 8 +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 8; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; +#endif //variadic max 8 + +#if __TBB_VARIADIC_MAX >= 9 +template +class indexer_node : public internal::unfolded_indexer_node > { +private: + static const int N = 9; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; +#endif //variadic max 9 + +#if __TBB_VARIADIC_MAX >= 10 +template +class indexer_node/*default*/ : public internal::unfolded_indexer_node > { +private: + static const int N = 10; +public: + typedef tuple InputTuple; + typedef typename internal::tagged_msg output_type; + typedef typename internal::unfolded_indexer_node unfolded_type; + __TBB_NOINLINE_SYM indexer_node(graph& g) : unfolded_type(g) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + indexer_node(const node_set& nodes) : indexer_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + // Copy constructor + __TBB_NOINLINE_SYM indexer_node( const indexer_node& other ) : unfolded_type(other) { + tbb::internal::fgt_multiinput_node( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph, + this->input_ports(), static_cast< sender< output_type > *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif +}; +#endif //variadic max 10 + +#if __TBB_PREVIEW_ASYNC_MSG +inline void internal_make_edge( internal::untyped_sender &p, internal::untyped_receiver &s ) { +#else +template< typename T > +inline void internal_make_edge( sender &p, receiver &s ) { +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + s.internal_add_built_predecessor(p); + p.internal_add_built_successor(s); +#endif + p.register_successor( s ); + tbb::internal::fgt_make_edge( &p, &s ); +} + +//! Makes an edge between a single predecessor and a single successor +template< typename T > +inline void make_edge( sender &p, receiver &s ) { + internal_make_edge( p, s ); +} + +#if __TBB_PREVIEW_ASYNC_MSG +template< typename TS, typename TR, + typename = typename tbb::internal::enable_if::value + || tbb::internal::is_same_type::value>::type> +inline void make_edge( TS &p, TR &s ) { + internal_make_edge( p, s ); +} + +template< typename T > +inline void make_edge( sender &p, receiver &s ) { + internal_make_edge( p, s ); +} + +template< typename T > +inline void make_edge( sender &p, receiver &s ) { + internal_make_edge( p, s ); +} + +#endif // __TBB_PREVIEW_ASYNC_MSG + +#if __TBB_FLOW_GRAPH_CPP11_FEATURES +//Makes an edge from port 0 of a multi-output predecessor to port 0 of a multi-input successor. +template< typename T, typename V, + typename = typename T::output_ports_type, typename = typename V::input_ports_type > +inline void make_edge( T& output, V& input) { + make_edge(get<0>(output.output_ports()), get<0>(input.input_ports())); +} + +//Makes an edge from port 0 of a multi-output predecessor to a receiver. +template< typename T, typename R, + typename = typename T::output_ports_type > +inline void make_edge( T& output, receiver& input) { + make_edge(get<0>(output.output_ports()), input); +} + +//Makes an edge from a sender to port 0 of a multi-input successor. +template< typename S, typename V, + typename = typename V::input_ports_type > +inline void make_edge( sender& output, V& input) { + make_edge(output, get<0>(input.input_ports())); +} +#endif + +#if __TBB_PREVIEW_ASYNC_MSG +inline void internal_remove_edge( internal::untyped_sender &p, internal::untyped_receiver &s ) { +#else +template< typename T > +inline void internal_remove_edge( sender &p, receiver &s ) { +#endif + p.remove_successor( s ); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + // TODO: should we try to remove p from the predecessor list of s, in case the edge is reversed? + p.internal_delete_built_successor(s); + s.internal_delete_built_predecessor(p); +#endif + tbb::internal::fgt_remove_edge( &p, &s ); +} + +//! Removes an edge between a single predecessor and a single successor +template< typename T > +inline void remove_edge( sender &p, receiver &s ) { + internal_remove_edge( p, s ); +} + +#if __TBB_PREVIEW_ASYNC_MSG +template< typename TS, typename TR, + typename = typename tbb::internal::enable_if::value + || tbb::internal::is_same_type::value>::type> +inline void remove_edge( TS &p, TR &s ) { + internal_remove_edge( p, s ); +} + +template< typename T > +inline void remove_edge( sender &p, receiver &s ) { + internal_remove_edge( p, s ); +} + +template< typename T > +inline void remove_edge( sender &p, receiver &s ) { + internal_remove_edge( p, s ); +} +#endif // __TBB_PREVIEW_ASYNC_MSG + +#if __TBB_FLOW_GRAPH_CPP11_FEATURES +//Removes an edge between port 0 of a multi-output predecessor and port 0 of a multi-input successor. +template< typename T, typename V, + typename = typename T::output_ports_type, typename = typename V::input_ports_type > +inline void remove_edge( T& output, V& input) { + remove_edge(get<0>(output.output_ports()), get<0>(input.input_ports())); +} + +//Removes an edge between port 0 of a multi-output predecessor and a receiver. +template< typename T, typename R, + typename = typename T::output_ports_type > +inline void remove_edge( T& output, receiver& input) { + remove_edge(get<0>(output.output_ports()), input); +} +//Removes an edge between a sender and port 0 of a multi-input successor. +template< typename S, typename V, + typename = typename V::input_ports_type > +inline void remove_edge( sender& output, V& input) { + remove_edge(output, get<0>(input.input_ports())); +} +#endif + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +template +template< typename S > +void internal::edge_container::sender_extract( S &s ) { + edge_list_type e = built_edges; + for ( typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) { + remove_edge(s, **i); + } +} + +template +template< typename R > +void internal::edge_container::receiver_extract( R &r ) { + edge_list_type e = built_edges; + for ( typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) { + remove_edge(**i, r); + } +} +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +//! Returns a copy of the body from a function or continue node +template< typename Body, typename Node > +Body copy_body( Node &n ) { + return n.template copy_function_object(); +} + +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + +//composite_node +template< typename InputTuple, typename OutputTuple > class composite_node; + +template< typename... InputTypes, typename... OutputTypes> +class composite_node , tbb::flow::tuple > : public graph_node{ + +public: + typedef tbb::flow::tuple< receiver&... > input_ports_type; + typedef tbb::flow::tuple< sender&... > output_ports_type; + +private: + std::unique_ptr my_input_ports; + std::unique_ptr my_output_ports; + + static const size_t NUM_INPUTS = sizeof...(InputTypes); + static const size_t NUM_OUTPUTS = sizeof...(OutputTypes); + +protected: + void reset_node(reset_flags) __TBB_override {} + +public: +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + composite_node( graph &g, const char *type_name = "composite_node" ) : graph_node(g) { + tbb::internal::fgt_multiinput_multioutput_node( CODEPTR(), tbb::internal::FLOW_COMPOSITE_NODE, this, &this->my_graph ); + tbb::internal::fgt_multiinput_multioutput_node_desc( this, type_name ); + } +#else + composite_node( graph &g ) : graph_node(g) { + tbb::internal::fgt_multiinput_multioutput_node( CODEPTR(), tbb::internal::FLOW_COMPOSITE_NODE, this, &this->my_graph ); + } +#endif + + template + void set_external_ports(T1&& input_ports_tuple, T2&& output_ports_tuple) { + __TBB_STATIC_ASSERT(NUM_INPUTS == tbb::flow::tuple_size::value, "number of arguments does not match number of input ports"); + __TBB_STATIC_ASSERT(NUM_OUTPUTS == tbb::flow::tuple_size::value, "number of arguments does not match number of output ports"); + my_input_ports = tbb::internal::make_unique(std::forward(input_ports_tuple)); + my_output_ports = tbb::internal::make_unique(std::forward(output_ports_tuple)); + + tbb::internal::fgt_internal_input_alias_helper::alias_port( this, input_ports_tuple); + tbb::internal::fgt_internal_output_alias_helper::alias_port( this, output_ports_tuple); + } + + template< typename... NodeTypes > + void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); } + + template< typename... NodeTypes > + void add_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); + } +#endif + + input_ports_type& input_ports() { + __TBB_ASSERT(my_input_ports, "input ports not set, call set_external_ports to set input ports"); + return *my_input_ports; + } + + output_ports_type& output_ports() { + __TBB_ASSERT(my_output_ports, "output ports not set, call set_external_ports to set output ports"); + return *my_output_ports; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract() __TBB_override { + __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); + } +#endif +}; // class composite_node + +//composite_node with only input ports +template< typename... InputTypes> +class composite_node , tbb::flow::tuple<> > : public graph_node { +public: + typedef tbb::flow::tuple< receiver&... > input_ports_type; + +private: + std::unique_ptr my_input_ports; + static const size_t NUM_INPUTS = sizeof...(InputTypes); + +protected: + void reset_node(reset_flags) __TBB_override {} + +public: +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + composite_node( graph &g, const char *type_name = "composite_node") : graph_node(g) { + tbb::internal::fgt_composite( CODEPTR(), this, &g ); + tbb::internal::fgt_multiinput_multioutput_node_desc( this, type_name ); + } +#else + composite_node( graph &g ) : graph_node(g) { + tbb::internal::fgt_composite( CODEPTR(), this, &g ); + } +#endif + + template + void set_external_ports(T&& input_ports_tuple) { + __TBB_STATIC_ASSERT(NUM_INPUTS == tbb::flow::tuple_size::value, "number of arguments does not match number of input ports"); + + my_input_ports = tbb::internal::make_unique(std::forward(input_ports_tuple)); + + tbb::internal::fgt_internal_input_alias_helper::alias_port( this, std::forward(input_ports_tuple)); + } + + template< typename... NodeTypes > + void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); } + + template< typename... NodeTypes > + void add_nodes( const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); + } +#endif + + input_ports_type& input_ports() { + __TBB_ASSERT(my_input_ports, "input ports not set, call set_external_ports to set input ports"); + return *my_input_ports; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract() __TBB_override { + __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); + } +#endif + +}; // class composite_node + +//composite_nodes with only output_ports +template +class composite_node , tbb::flow::tuple > : public graph_node { +public: + typedef tbb::flow::tuple< sender&... > output_ports_type; + +private: + std::unique_ptr my_output_ports; + static const size_t NUM_OUTPUTS = sizeof...(OutputTypes); + +protected: + void reset_node(reset_flags) __TBB_override {} + +public: +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + __TBB_NOINLINE_SYM composite_node( graph &g, const char *type_name = "composite_node") : graph_node(g) { + tbb::internal::fgt_composite( CODEPTR(), this, &g ); + tbb::internal::fgt_multiinput_multioutput_node_desc( this, type_name ); + } +#else + __TBB_NOINLINE_SYM composite_node( graph &g ) : graph_node(g) { + tbb::internal::fgt_composite( CODEPTR(), this, &g ); + } +#endif + + template + void set_external_ports(T&& output_ports_tuple) { + __TBB_STATIC_ASSERT(NUM_OUTPUTS == tbb::flow::tuple_size::value, "number of arguments does not match number of output ports"); + + my_output_ports = tbb::internal::make_unique(std::forward(output_ports_tuple)); + + tbb::internal::fgt_internal_output_alias_helper::alias_port( this, std::forward(output_ports_tuple)); + } + + template + void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); } + + template + void add_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_multiinput_multioutput_node_desc( this, name ); + } +#endif + + output_ports_type& output_ports() { + __TBB_ASSERT(my_output_ports, "output ports not set, call set_external_ports to set output ports"); + return *my_output_ports; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract() __TBB_override { + __TBB_ASSERT(false, "Current composite_node implementation does not support extract"); + } +#endif + +}; // class composite_node + +#endif // __TBB_FLOW_GRAPH_CPP11_FEATURES + +namespace internal { + +template +class async_body_base: tbb::internal::no_assign { +public: + typedef Gateway gateway_type; + + async_body_base(gateway_type *gateway): my_gateway(gateway) { } + void set_gateway(gateway_type *gateway) { + my_gateway = gateway; + } + +protected: + gateway_type *my_gateway; +}; + +template +class async_body: public async_body_base { +public: + typedef async_body_base base_type; + typedef Gateway gateway_type; + + async_body(const Body &body, gateway_type *gateway) + : base_type(gateway), my_body(body) { } + + void operator()( const Input &v, Ports & ) { + my_body(v, *this->my_gateway); + } + + Body get_body() { return my_body; } + +private: + Body my_body; +}; + +} // namespace internal + +} // namespace interfaceX +namespace interface11 { + +//! Implements async node +template < typename Input, typename Output, + typename Policy = queueing_lightweight, + typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(Input) > +class async_node + : public multifunction_node< Input, tuple< Output >, Policy, Allocator >, public sender< Output > +{ +#if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + __TBB_STATIC_ASSERT( + (tbb::internal::is_same_type::value), + "Allocator template parameter for flow graph nodes is deprecated and will removed in the future. " + "To temporary enable the deprecated interface specify TBB_ENABLE_DEPRECATED_NODE_ALLOCATOR." + ); +#endif + typedef multifunction_node< Input, tuple< Output >, Policy, Allocator > base_type; + typedef typename internal::multifunction_input mfn_input_type; + +public: + typedef Input input_type; + typedef Output output_type; + typedef receiver receiver_type; + typedef typename receiver_type::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; + typedef receiver_gateway gateway_type; + typedef internal::async_body_base async_body_base_type; + typedef typename base_type::output_ports_type output_ports_type; + +private: + struct try_put_functor { + typedef internal::multifunction_output output_port_type; + output_port_type *port; + // TODO: pass value by copy since we do not want to block asynchronous thread. + const Output *value; + bool result; + try_put_functor(output_port_type &p, const Output &v) : port(&p), value(&v), result(false) { } + void operator()() { + result = port->try_put(*value); + } + }; + + class receiver_gateway_impl: public receiver_gateway { + public: + receiver_gateway_impl(async_node* node): my_node(node) {} + void reserve_wait() __TBB_override { + tbb::internal::fgt_async_reserve(static_cast(my_node), &my_node->my_graph); + my_node->my_graph.reserve_wait(); + } + + void release_wait() __TBB_override { + my_node->my_graph.release_wait(); + tbb::internal::fgt_async_commit(static_cast(my_node), &my_node->my_graph); + } + + //! Implements gateway_type::try_put for an external activity to submit a message to FG + bool try_put(const Output &i) __TBB_override { + return my_node->try_put_impl(i); + } + + private: + async_node* my_node; + } my_gateway; + + //The substitute of 'this' for member construction, to prevent compiler warnings + async_node* self() { return this; } + + //! Implements gateway_type::try_put for an external activity to submit a message to FG + bool try_put_impl(const Output &i) { + internal::multifunction_output &port_0 = internal::output_port<0>(*this); + internal::broadcast_cache& port_successors = port_0.successors(); + tbb::internal::fgt_async_try_put_begin(this, &port_0); + task_list tasks; + bool is_at_least_one_put_successful = port_successors.gather_successful_try_puts(i, tasks); + __TBB_ASSERT( is_at_least_one_put_successful || tasks.empty(), + "Return status is inconsistent with the method operation." ); + + while( !tasks.empty() ) { + internal::enqueue_in_graph_arena(this->my_graph, tasks.pop_front()); + } + tbb::internal::fgt_async_try_put_end(this, &port_0); + return is_at_least_one_put_successful; + } + +public: + template + __TBB_NOINLINE_SYM async_node( + graph &g, size_t concurrency, +#if __TBB_CPP11_PRESENT + Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority) +#else + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body body, node_priority_t priority = tbb::flow::internal::no_priority) +#endif + ) : base_type( + g, concurrency, + internal::async_body + (body, &my_gateway) __TBB_FLOW_GRAPH_PRIORITY_ARG0(priority) ), my_gateway(self()) { + tbb::internal::fgt_multioutput_node_with_body<1>( + CODEPTR(), tbb::internal::FLOW_ASYNC_NODE, + &this->my_graph, static_cast *>(this), + this->output_ports(), this->my_body + ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT + template + __TBB_NOINLINE_SYM async_node(graph& g, size_t concurrency, Body body, node_priority_t priority) + : async_node(g, concurrency, body, Policy(), priority) {} +#endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + __TBB_NOINLINE_SYM async_node( + const node_set& nodes, size_t concurrency, Body body, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority) + ) : async_node(nodes.graph_reference(), concurrency, __TBB_FLOW_GRAPH_PRIORITY_ARG1(body, priority)) { + make_edges_in_order(nodes, *this); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + template + __TBB_NOINLINE_SYM async_node(const node_set& nodes, size_t concurrency, Body body, node_priority_t priority) + : async_node(nodes, concurrency, body, Policy(), priority) {} +#endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + + __TBB_NOINLINE_SYM async_node( const async_node &other ) : base_type(other), sender(), my_gateway(self()) { + static_cast(this->my_body->get_body_ptr())->set_gateway(&my_gateway); + static_cast(this->my_init_body->get_body_ptr())->set_gateway(&my_gateway); + + tbb::internal::fgt_multioutput_node_with_body<1>( CODEPTR(), tbb::internal::FLOW_ASYNC_NODE, + &this->my_graph, static_cast *>(this), + this->output_ports(), this->my_body ); + } + + gateway_type& gateway() { + return my_gateway; + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_multioutput_node_desc( this, name ); + } +#endif + + // Define sender< Output > + + //! Add a new successor to this node + bool register_successor( successor_type &r ) __TBB_override { + return internal::output_port<0>(*this).register_successor(r); + } + + //! Removes a successor from this node + bool remove_successor( successor_type &r ) __TBB_override { + return internal::output_port<0>(*this).remove_successor(r); + } + + template + Body copy_function_object() { + typedef internal::multifunction_body mfn_body_type; + typedef internal::async_body async_body_type; + mfn_body_type &body_ref = *this->my_body; + async_body_type ab = *static_cast(dynamic_cast< internal::multifunction_body_leaf & >(body_ref).get_body_ptr()); + return ab.get_body(); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + //! interface to record edges for traversal & deletion + typedef typename internal::edge_container built_successors_type; + typedef typename built_successors_type::edge_list_type successor_list_type; + built_successors_type &built_successors() __TBB_override { + return internal::output_port<0>(*this).built_successors(); + } + + void internal_add_built_successor( successor_type &r ) __TBB_override { + internal::output_port<0>(*this).internal_add_built_successor(r); + } + + void internal_delete_built_successor( successor_type &r ) __TBB_override { + internal::output_port<0>(*this).internal_delete_built_successor(r); + } + + void copy_successors( successor_list_type &l ) __TBB_override { + internal::output_port<0>(*this).copy_successors(l); + } + + size_t successor_count() __TBB_override { + return internal::output_port<0>(*this).successor_count(); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +protected: + + void reset_node( reset_flags f) __TBB_override { + base_type::reset_node(f); + } +}; + +#if __TBB_PREVIEW_STREAMING_NODE +#include "internal/_flow_graph_streaming_node.h" +#endif // __TBB_PREVIEW_STREAMING_NODE + +#include "internal/_flow_graph_node_set_impl.h" + +template< typename T > +class overwrite_node : public graph_node, public receiver, public sender { +public: + typedef T input_type; + typedef T output_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename receiver::built_predecessors_type built_predecessors_type; + typedef typename sender::built_successors_type built_successors_type; + typedef typename receiver::predecessor_list_type predecessor_list_type; + typedef typename sender::successor_list_type successor_list_type; +#endif + + __TBB_NOINLINE_SYM explicit overwrite_node(graph &g) : graph_node(g), my_buffer_is_valid(false) { + my_successors.set_owner( this ); + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + overwrite_node(const node_set& nodes) : overwrite_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + //! Copy constructor; doesn't take anything from src; default won't work + __TBB_NOINLINE_SYM overwrite_node( const overwrite_node& src ) : + graph_node(src.my_graph), receiver(), sender(), my_buffer_is_valid(false) + { + my_successors.set_owner( this ); + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph, + static_cast *>(this), static_cast *>(this) ); + } + + ~overwrite_node() {} + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + + bool register_successor( successor_type &s ) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + if (my_buffer_is_valid && internal::is_graph_active( my_graph )) { + // We have a valid value that must be forwarded immediately. + bool ret = s.try_put( my_buffer ); + if ( ret ) { + // We add the successor that accepted our put + my_successors.register_successor( s ); + } else { + // In case of reservation a race between the moment of reservation and register_successor can appear, + // because failed reserve does not mean that register_successor is not ready to put a message immediately. + // We have some sort of infinite loop: reserving node tries to set pull state for the edge, + // but overwrite_node tries to return push state back. That is why we have to break this loop with task creation. + task *rtask = new ( task::allocate_additional_child_of( *( my_graph.root_task() ) ) ) + register_predecessor_task( *this, s ); + internal::spawn_in_graph_arena( my_graph, *rtask ); + } + } else { + // No valid value yet, just add as successor + my_successors.register_successor( s ); + } + return true; + } + + bool remove_successor( successor_type &s ) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + my_successors.remove_successor(s); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + + void internal_add_built_successor( successor_type &s) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + my_successors.internal_add_built_successor(s); + } + + void internal_delete_built_successor( successor_type &s) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + my_successors.internal_delete_built_successor(s); + } + + size_t successor_count() __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + return my_successors.successor_count(); + } + + void copy_successors(successor_list_type &v) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + my_successors.copy_successors(v); + } + + void internal_add_built_predecessor( predecessor_type &p) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + my_built_predecessors.add_edge(p); + } + + void internal_delete_built_predecessor( predecessor_type &p) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + my_built_predecessors.delete_edge(p); + } + + size_t predecessor_count() __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + return my_built_predecessors.edge_count(); + } + + void copy_predecessors( predecessor_list_type &v ) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + my_built_predecessors.copy_edges(v); + } + + void extract() __TBB_override { + my_buffer_is_valid = false; + built_successors().sender_extract(*this); + built_predecessors().receiver_extract(*this); + } + +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + bool try_get( input_type &v ) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + if ( my_buffer_is_valid ) { + v = my_buffer; + return true; + } + return false; + } + + //! Reserves an item + bool try_reserve( T &v ) __TBB_override { + return try_get(v); + } + + //! Releases the reserved item + bool try_release() __TBB_override { return true; } + + //! Consumes the reserved item + bool try_consume() __TBB_override { return true; } + + bool is_valid() { + spin_mutex::scoped_lock l( my_mutex ); + return my_buffer_is_valid; + } + + void clear() { + spin_mutex::scoped_lock l( my_mutex ); + my_buffer_is_valid = false; + } + +protected: + + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + task * try_put_task( const input_type &v ) __TBB_override { + spin_mutex::scoped_lock l( my_mutex ); + return try_put_task_impl(v); + } + + task * try_put_task_impl(const input_type &v) { + my_buffer = v; + my_buffer_is_valid = true; + task * rtask = my_successors.try_put_task(v); + if (!rtask) rtask = SUCCESSFULLY_ENQUEUED; + return rtask; + } + + graph& graph_reference() const __TBB_override { + return my_graph; + } + + //! Breaks an infinite loop between the node reservation and register_successor call + struct register_predecessor_task : public graph_task { + + register_predecessor_task(predecessor_type& owner, successor_type& succ) : + o(owner), s(succ) {}; + + tbb::task* execute() __TBB_override { + if (!s.register_predecessor(o)) { + o.register_successor(s); + } + return NULL; + } + + predecessor_type& o; + successor_type& s; + }; + + spin_mutex my_mutex; + internal::broadcast_cache< input_type, null_rw_mutex > my_successors; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + internal::edge_container my_built_predecessors; +#endif + input_type my_buffer; + bool my_buffer_is_valid; + void reset_receiver(reset_flags /*f*/) __TBB_override {} + + void reset_node( reset_flags f) __TBB_override { + my_buffer_is_valid = false; + if (f&rf_clear_edges) { + my_successors.clear(); + } + } +}; // overwrite_node + +template< typename T > +class write_once_node : public overwrite_node { +public: + typedef T input_type; + typedef T output_type; + typedef overwrite_node base_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename sender::successor_type successor_type; + + //! Constructor + __TBB_NOINLINE_SYM explicit write_once_node(graph& g) : base_type(g) { + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph), + static_cast *>(this), + static_cast *>(this) ); + } + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + template + write_once_node(const node_set& nodes) : write_once_node(nodes.graph_reference()) { + make_edges_in_order(nodes, *this); + } +#endif + + //! Copy constructor: call base class copy constructor + __TBB_NOINLINE_SYM write_once_node( const write_once_node& src ) : base_type(src) { + tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph), + static_cast *>(this), + static_cast *>(this) ); + } + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name( const char *name ) __TBB_override { + tbb::internal::fgt_node_desc( this, name ); + } +#endif + +protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + task *try_put_task( const T &v ) __TBB_override { + spin_mutex::scoped_lock l( this->my_mutex ); + return this->my_buffer_is_valid ? NULL : this->try_put_task_impl(v); + } +}; + +} // interfaceX + + using interface11::reset_flags; + using interface11::rf_reset_protocol; + using interface11::rf_reset_bodies; + using interface11::rf_clear_edges; + + using interface11::graph; + using interface11::graph_node; + using interface11::continue_msg; + using interface11::source_node; + using interface11::input_node; + using interface11::function_node; + using interface11::multifunction_node; + using interface11::split_node; + using interface11::internal::output_port; + using interface11::indexer_node; + using interface11::internal::tagged_msg; + using interface11::internal::cast_to; + using interface11::internal::is_a; + using interface11::continue_node; + using interface11::overwrite_node; + using interface11::write_once_node; + using interface11::broadcast_node; + using interface11::buffer_node; + using interface11::queue_node; + using interface11::sequencer_node; + using interface11::priority_queue_node; + using interface11::limiter_node; + using namespace interface11::internal::graph_policy_namespace; + using interface11::join_node; + using interface11::input_port; + using interface11::copy_body; + using interface11::make_edge; + using interface11::remove_edge; + using interface11::internal::tag_value; +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + using interface11::composite_node; +#endif + using interface11::async_node; +#if __TBB_PREVIEW_ASYNC_MSG + using interface11::async_msg; +#endif +#if __TBB_PREVIEW_STREAMING_NODE + using interface11::port_ref; + using interface11::streaming_node; +#endif // __TBB_PREVIEW_STREAMING_NODE +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + using internal::node_priority_t; + using internal::no_priority; +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + using interface11::internal::follows; + using interface11::internal::precedes; + using interface11::internal::make_node_set; + using interface11::internal::make_edges; +#endif + +} // flow +} // tbb + +// Include deduction guides for node classes +#include "internal/_flow_graph_nodes_deduction.h" + +#undef __TBB_PFG_RESET_ARG +#undef __TBB_COMMA +#undef __TBB_DEFAULT_NODE_ALLOCATOR + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_flow_graph_H_include_area + +#if TBB_USE_THREADING_TOOLS && TBB_PREVIEW_FLOW_GRAPH_TRACE && ( __linux__ || __APPLE__ ) + #undef __TBB_NOINLINE_SYM +#endif + +#endif // __TBB_flow_graph_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph_abstractions.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph_abstractions.h new file mode 100644 index 00000000..f8ac239c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph_abstractions.h @@ -0,0 +1,53 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_flow_graph_abstractions_H +#define __TBB_flow_graph_abstractions_H + +namespace tbb { +namespace flow { +namespace interface11 { + +//! Pure virtual template classes that define interfaces for async communication +class graph_proxy { +public: + //! Inform a graph that messages may come from outside, to prevent premature graph completion + virtual void reserve_wait() = 0; + + //! Inform a graph that a previous call to reserve_wait is no longer in effect + virtual void release_wait() = 0; + + virtual ~graph_proxy() {} +}; + +template +class receiver_gateway : public graph_proxy { +public: + //! Type of inputing data into FG. + typedef Input input_type; + + //! Submit signal from an asynchronous activity to FG. + virtual bool try_put(const input_type&) = 0; +}; + +} //interfaceX + +using interface11::graph_proxy; +using interface11::receiver_gateway; + +} //flow +} //tbb +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph_opencl_node.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph_opencl_node.h new file mode 100644 index 00000000..e6670db6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/flow_graph_opencl_node.h @@ -0,0 +1,1504 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_flow_graph_opencl_node_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_flow_graph_opencl_node_H +#pragma message("TBB Warning: tbb/flow_graph_opencl_node.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_flow_graph_opencl_node_H +#define __TBB_flow_graph_opencl_node_H + +#define __TBB_flow_graph_opencl_node_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb/tbb_config.h" +#if __TBB_PREVIEW_OPENCL_NODE + +#include "flow_graph.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +namespace tbb { +namespace flow { + +namespace interface11 { + +template +class opencl_factory; + +namespace opencl_info { +class default_opencl_factory; +} + +template +class opencl_program; + +inline void enforce_cl_retcode(cl_int err, std::string msg) { + if (err != CL_SUCCESS) { + std::cerr << msg << "; error code: " << err << std::endl; + throw msg; + } +} + +template +T event_info(cl_event e, cl_event_info i) { + T res; + enforce_cl_retcode(clGetEventInfo(e, i, sizeof(res), &res, NULL), "Failed to get OpenCL event information"); + return res; +} + +template +T device_info(cl_device_id d, cl_device_info i) { + T res; + enforce_cl_retcode(clGetDeviceInfo(d, i, sizeof(res), &res, NULL), "Failed to get OpenCL device information"); + return res; +} + +template <> +inline std::string device_info(cl_device_id d, cl_device_info i) { + size_t required; + enforce_cl_retcode(clGetDeviceInfo(d, i, 0, NULL, &required), "Failed to get OpenCL device information"); + + char *buff = (char*)alloca(required); + enforce_cl_retcode(clGetDeviceInfo(d, i, required, buff, NULL), "Failed to get OpenCL device information"); + + return buff; +} + +template +T platform_info(cl_platform_id p, cl_platform_info i) { + T res; + enforce_cl_retcode(clGetPlatformInfo(p, i, sizeof(res), &res, NULL), "Failed to get OpenCL platform information"); + return res; +} + +template <> +inline std::string platform_info(cl_platform_id p, cl_platform_info i) { + size_t required; + enforce_cl_retcode(clGetPlatformInfo(p, i, 0, NULL, &required), "Failed to get OpenCL platform information"); + + char *buff = (char*)alloca(required); + enforce_cl_retcode(clGetPlatformInfo(p, i, required, buff, NULL), "Failed to get OpenCL platform information"); + + return buff; +} + + +class __TBB_DEPRECATED_IN_VERBOSE_MODE opencl_device { +public: + typedef size_t device_id_type; + enum : device_id_type { + unknown = device_id_type( -2 ), + host = device_id_type( -1 ) + }; + + opencl_device() : my_device_id( unknown ), my_cl_device_id( NULL ), my_cl_command_queue( NULL ) {} + + opencl_device( cl_device_id d_id ) : my_device_id( unknown ), my_cl_device_id( d_id ), my_cl_command_queue( NULL ) {} + + opencl_device( cl_device_id cl_d_id, device_id_type device_id ) : my_device_id( device_id ), my_cl_device_id( cl_d_id ), my_cl_command_queue( NULL ) {} + + std::string platform_profile() const { + return platform_info( platform_id(), CL_PLATFORM_PROFILE ); + } + std::string platform_version() const { + return platform_info( platform_id(), CL_PLATFORM_VERSION ); + } + std::string platform_name() const { + return platform_info( platform_id(), CL_PLATFORM_NAME ); + } + std::string platform_vendor() const { + return platform_info( platform_id(), CL_PLATFORM_VENDOR ); + } + std::string platform_extensions() const { + return platform_info( platform_id(), CL_PLATFORM_EXTENSIONS ); + } + + template + void info( cl_device_info i, T &t ) const { + t = device_info( my_cl_device_id, i ); + } + std::string version() const { + // The version string format: OpenCL + return device_info( my_cl_device_id, CL_DEVICE_VERSION ); + } + int major_version() const { + int major; + std::sscanf( version().c_str(), "OpenCL %d", &major ); + return major; + } + int minor_version() const { + int major, minor; + std::sscanf( version().c_str(), "OpenCL %d.%d", &major, &minor ); + return minor; + } + bool out_of_order_exec_mode_on_host_present() const { +#if CL_VERSION_2_0 + if ( major_version() >= 2 ) + return (device_info( my_cl_device_id, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0; + else +#endif /* CL_VERSION_2_0 */ + return (device_info( my_cl_device_id, CL_DEVICE_QUEUE_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0; + } + bool out_of_order_exec_mode_on_device_present() const { +#if CL_VERSION_2_0 + if ( major_version() >= 2 ) + return (device_info( my_cl_device_id, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES ) & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) != 0; + else +#endif /* CL_VERSION_2_0 */ + return false; + } + std::array max_work_item_sizes() const { + return device_info>( my_cl_device_id, CL_DEVICE_MAX_WORK_ITEM_SIZES ); + } + size_t max_work_group_size() const { + return device_info( my_cl_device_id, CL_DEVICE_MAX_WORK_GROUP_SIZE ); + } + bool built_in_kernel_available( const std::string& k ) const { + const std::string semi = ";"; + // Added semicolumns to force an exact match (to avoid a partial match, e.g. "add" is partly matched with "madd"). + return (semi + built_in_kernels() + semi).find( semi + k + semi ) != std::string::npos; + } + std::string built_in_kernels() const { + return device_info( my_cl_device_id, CL_DEVICE_BUILT_IN_KERNELS ); + } + std::string name() const { + return device_info( my_cl_device_id, CL_DEVICE_NAME ); + } + cl_bool available() const { + return device_info( my_cl_device_id, CL_DEVICE_AVAILABLE ); + } + cl_bool compiler_available() const { + return device_info( my_cl_device_id, CL_DEVICE_COMPILER_AVAILABLE ); + } + cl_bool linker_available() const { + return device_info( my_cl_device_id, CL_DEVICE_LINKER_AVAILABLE ); + } + bool extension_available( const std::string &ext ) const { + const std::string space = " "; + // Added space to force an exact match (to avoid a partial match, e.g. "ext" is partly matched with "ext2"). + return (space + extensions() + space).find( space + ext + space ) != std::string::npos; + } + std::string extensions() const { + return device_info( my_cl_device_id, CL_DEVICE_EXTENSIONS ); + } + + cl_device_type type() const { + return device_info( my_cl_device_id, CL_DEVICE_TYPE ); + } + + std::string vendor() const { + return device_info( my_cl_device_id, CL_DEVICE_VENDOR ); + } + + cl_uint address_bits() const { + return device_info( my_cl_device_id, CL_DEVICE_ADDRESS_BITS ); + } + + cl_device_id device_id() const { + return my_cl_device_id; + } + + cl_command_queue command_queue() const { + return my_cl_command_queue; + } + + void set_command_queue( cl_command_queue cmd_queue ) { + my_cl_command_queue = cmd_queue; + } + + cl_platform_id platform_id() const { + return device_info( my_cl_device_id, CL_DEVICE_PLATFORM ); + } + +private: + + device_id_type my_device_id; + cl_device_id my_cl_device_id; + cl_command_queue my_cl_command_queue; + + friend bool operator==(opencl_device d1, opencl_device d2) { return d1.my_cl_device_id == d2.my_cl_device_id; } + + template + friend class opencl_factory; + template + friend class opencl_memory; + template + friend class opencl_program; + +#if TBB_USE_ASSERT + template + friend class opencl_buffer; +#endif +}; + +class __TBB_DEPRECATED_IN_VERBOSE_MODE opencl_device_list { + typedef std::vector container_type; +public: + typedef container_type::iterator iterator; + typedef container_type::const_iterator const_iterator; + typedef container_type::size_type size_type; + + opencl_device_list() {} + opencl_device_list( std::initializer_list il ) : my_container( il ) {} + + void add( opencl_device d ) { my_container.push_back( d ); } + size_type size() const { return my_container.size(); } + bool empty() const { return my_container.empty(); } + iterator begin() { return my_container.begin(); } + iterator end() { return my_container.end(); } + const_iterator begin() const { return my_container.begin(); } + const_iterator end() const { return my_container.end(); } + const_iterator cbegin() const { return my_container.cbegin(); } + const_iterator cend() const { return my_container.cend(); } + +private: + container_type my_container; +}; + +namespace internal { + +// Retrieve all OpenCL devices from machine +inline opencl_device_list find_available_devices() { + opencl_device_list opencl_devices; + + cl_uint num_platforms; + enforce_cl_retcode(clGetPlatformIDs(0, NULL, &num_platforms), "clGetPlatformIDs failed"); + + std::vector platforms(num_platforms); + enforce_cl_retcode(clGetPlatformIDs(num_platforms, platforms.data(), NULL), "clGetPlatformIDs failed"); + + cl_uint num_devices; + std::vector::iterator platforms_it = platforms.begin(); + cl_uint num_all_devices = 0; + while (platforms_it != platforms.end()) { + cl_int err = clGetDeviceIDs(*platforms_it, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices); + if (err == CL_DEVICE_NOT_FOUND) { + platforms_it = platforms.erase(platforms_it); + } + else { + enforce_cl_retcode(err, "clGetDeviceIDs failed"); + num_all_devices += num_devices; + ++platforms_it; + } + } + + std::vector devices(num_all_devices); + std::vector::iterator devices_it = devices.begin(); + for (auto p = platforms.begin(); p != platforms.end(); ++p) { + enforce_cl_retcode(clGetDeviceIDs((*p), CL_DEVICE_TYPE_ALL, (cl_uint)std::distance(devices_it, devices.end()), &*devices_it, &num_devices), "clGetDeviceIDs failed"); + devices_it += num_devices; + } + + for (auto d = devices.begin(); d != devices.end(); ++d) { + opencl_devices.add(opencl_device((*d))); + } + + return opencl_devices; +} + +} // namespace internal + +// TODO: consider this namespace as public API +namespace opencl_info { + + inline const opencl_device_list& available_devices() { + // Static storage for all available OpenCL devices on machine + static const opencl_device_list my_devices = internal::find_available_devices(); + return my_devices; + } + +} // namespace opencl_info + + +class callback_base : tbb::internal::no_copy { +public: + virtual void call() = 0; + virtual ~callback_base() {} +}; + +template +class callback : public callback_base { + Callback my_callback; + T my_data; +public: + callback( Callback c, const T& t ) : my_callback( c ), my_data( t ) {} + + void call() __TBB_override { + my_callback( my_data ); + } +}; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE opencl_async_msg : public async_msg { +public: + typedef T value_type; + + opencl_async_msg() : my_callback_flag_ptr( std::make_shared< tbb::atomic>() ) { + my_callback_flag_ptr->store(false); + } + + explicit opencl_async_msg( const T& data ) : my_data(data), my_callback_flag_ptr( std::make_shared>() ) { + my_callback_flag_ptr->store(false); + } + + opencl_async_msg( const T& data, cl_event event ) : my_data(data), my_event(event), my_is_event(true), my_callback_flag_ptr( std::make_shared>() ) { + my_callback_flag_ptr->store(false); + enforce_cl_retcode( clRetainEvent( my_event ), "Failed to retain an event" ); + } + + T& data( bool wait = true ) { + if ( my_is_event && wait ) { + enforce_cl_retcode( clWaitForEvents( 1, &my_event ), "Failed to wait for an event" ); + enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); + my_is_event = false; + } + return my_data; + } + + const T& data( bool wait = true ) const { + if ( my_is_event && wait ) { + enforce_cl_retcode( clWaitForEvents( 1, &my_event ), "Failed to wait for an event" ); + enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); + my_is_event = false; + } + return my_data; + } + + opencl_async_msg( const opencl_async_msg &dmsg ) : async_msg(dmsg), + my_data(dmsg.my_data), my_event(dmsg.my_event), my_is_event( dmsg.my_is_event ), + my_callback_flag_ptr(dmsg.my_callback_flag_ptr) + { + if ( my_is_event ) + enforce_cl_retcode( clRetainEvent( my_event ), "Failed to retain an event" ); + } + + opencl_async_msg( opencl_async_msg &&dmsg ) : async_msg(std::move(dmsg)), + my_data(std::move(dmsg.my_data)), my_event(dmsg.my_event), my_is_event(dmsg.my_is_event), + my_callback_flag_ptr( std::move(dmsg.my_callback_flag_ptr) ) + { + dmsg.my_is_event = false; + } + + opencl_async_msg& operator=(const opencl_async_msg &dmsg) { + async_msg::operator =(dmsg); + + // Release original event + if ( my_is_event ) + enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to retain an event" ); + + my_data = dmsg.my_data; + my_event = dmsg.my_event; + my_is_event = dmsg.my_is_event; + + // Retain copied event + if ( my_is_event ) + enforce_cl_retcode( clRetainEvent( my_event ), "Failed to retain an event" ); + + my_callback_flag_ptr = dmsg.my_callback_flag_ptr; + return *this; + } + + ~opencl_async_msg() { + if ( my_is_event ) + enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); + } + + cl_event const * get_event() const { return my_is_event ? &my_event : NULL; } + void set_event( cl_event e ) const { + if ( my_is_event ) { + cl_command_queue cq = event_info( my_event, CL_EVENT_COMMAND_QUEUE ); + if ( cq != event_info( e, CL_EVENT_COMMAND_QUEUE ) ) + enforce_cl_retcode( clFlush( cq ), "Failed to flush an OpenCL command queue" ); + enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); + } + my_is_event = true; + my_event = e; + clRetainEvent( my_event ); + } + + void clear_event() const { + if ( my_is_event ) { + enforce_cl_retcode( clFlush( event_info( my_event, CL_EVENT_COMMAND_QUEUE ) ), "Failed to flush an OpenCL command queue" ); + enforce_cl_retcode( clReleaseEvent( my_event ), "Failed to release an event" ); + } + my_is_event = false; + } + + template + void register_callback( Callback c ) const { + __TBB_ASSERT( my_is_event, "The OpenCL event is not set" ); + enforce_cl_retcode( clSetEventCallback( my_event, CL_COMPLETE, register_callback_func, new callback( c, my_data ) ), "Failed to set an OpenCL callback" ); + } + + operator T&() { return data(); } + operator const T&() const { return data(); } + +protected: + // Overridden in this derived class to inform that + // async calculation chain is over + void finalize() const __TBB_override { + receive_if_memory_object(*this); + if (! my_callback_flag_ptr->fetch_and_store(true)) { + opencl_async_msg a(*this); + if (my_is_event) { + register_callback([a](const T& t) mutable { + a.set(t); + }); + } + else { + a.set(my_data); + } + } + clear_event(); + } + +private: + static void CL_CALLBACK register_callback_func( cl_event, cl_int event_command_exec_status, void *data ) { + tbb::internal::suppress_unused_warning( event_command_exec_status ); + __TBB_ASSERT( event_command_exec_status == CL_COMPLETE, NULL ); + __TBB_ASSERT( data, NULL ); + callback_base *c = static_cast(data); + c->call(); + delete c; + } + + T my_data; + mutable cl_event my_event; + mutable bool my_is_event = false; + + std::shared_ptr< tbb::atomic > my_callback_flag_ptr; +}; + +template +K key_from_message( const opencl_async_msg &dmsg ) { + using tbb::flow::key_from_message; + const T &t = dmsg.data( false ); + __TBB_STATIC_ASSERT( true, "" ); + return key_from_message( t ); +} + +template +class opencl_memory { +public: + opencl_memory() {} + opencl_memory( Factory &f ) : my_host_ptr( NULL ), my_factory( &f ), my_sending_event_present( false ) { + my_curr_device_id = my_factory->devices().begin()->my_device_id; + } + + virtual ~opencl_memory() { + if ( my_sending_event_present ) enforce_cl_retcode( clReleaseEvent( my_sending_event ), "Failed to release an event for the OpenCL buffer" ); + enforce_cl_retcode( clReleaseMemObject( my_cl_mem ), "Failed to release an memory object" ); + } + + cl_mem get_cl_mem() const { + return my_cl_mem; + } + + void* get_host_ptr() { + if ( !my_host_ptr ) { + opencl_async_msg d = receive( NULL ); + d.data(); + __TBB_ASSERT( d.data() == my_host_ptr, NULL ); + } + return my_host_ptr; + } + + Factory *factory() const { return my_factory; } + + opencl_async_msg receive(const cl_event *e) { + opencl_async_msg d; + if (e) { + d = opencl_async_msg(my_host_ptr, *e); + } else { + d = opencl_async_msg(my_host_ptr); + } + + // Concurrent receives are prohibited so we do not worry about synchronization. + if (my_curr_device_id.load() != opencl_device::host) { + map_memory(*my_factory->devices().begin(), d); + my_curr_device_id.store(opencl_device::host); + my_host_ptr = d.data(false); + } + // Release the sending event + if (my_sending_event_present) { + enforce_cl_retcode(clReleaseEvent(my_sending_event), "Failed to release an event"); + my_sending_event_present = false; + } + return d; + } + + opencl_async_msg send(opencl_device device, const cl_event *e) { + opencl_device::device_id_type device_id = device.my_device_id; + if (!my_factory->is_same_context(my_curr_device_id.load(), device_id)) { + { + tbb::spin_mutex::scoped_lock lock(my_sending_lock); + if (!my_factory->is_same_context(my_curr_device_id.load(), device_id)) { + __TBB_ASSERT(my_host_ptr, "The buffer has not been mapped"); + opencl_async_msg d(my_host_ptr); + my_factory->enqueue_unmap_buffer(device, *this, d); + my_sending_event = *d.get_event(); + my_sending_event_present = true; + enforce_cl_retcode(clRetainEvent(my_sending_event), "Failed to retain an event"); + my_host_ptr = NULL; + my_curr_device_id.store(device_id); + } + } + __TBB_ASSERT(my_sending_event_present, NULL); + } + + // !e means that buffer has come from the host + if (!e && my_sending_event_present) e = &my_sending_event; + + __TBB_ASSERT(!my_host_ptr, "The buffer has not been unmapped"); + return e ? opencl_async_msg(NULL, *e) : opencl_async_msg(NULL); + } + + virtual void map_memory( opencl_device, opencl_async_msg & ) = 0; +protected: + cl_mem my_cl_mem; + tbb::atomic my_curr_device_id; + void* my_host_ptr; + Factory *my_factory; + + tbb::spin_mutex my_sending_lock; + bool my_sending_event_present; + cl_event my_sending_event; +}; + +template +class opencl_buffer_impl : public opencl_memory { + size_t my_size; +public: + opencl_buffer_impl( size_t size, Factory& f ) : opencl_memory( f ), my_size( size ) { + cl_int err; + this->my_cl_mem = clCreateBuffer( this->my_factory->context(), CL_MEM_ALLOC_HOST_PTR, size, NULL, &err ); + enforce_cl_retcode( err, "Failed to create an OpenCL buffer" ); + } + + // The constructor for subbuffers. + opencl_buffer_impl( cl_mem m, size_t index, size_t size, Factory& f ) : opencl_memory( f ), my_size( size ) { + cl_int err; + cl_buffer_region region = { index, size }; + this->my_cl_mem = clCreateSubBuffer( m, 0, CL_BUFFER_CREATE_TYPE_REGION, ®ion, &err ); + enforce_cl_retcode( err, "Failed to create an OpenCL subbuffer" ); + } + + size_t size() const { + return my_size; + } + + void map_memory( opencl_device device, opencl_async_msg &dmsg ) __TBB_override { + this->my_factory->enqueue_map_buffer( device, *this, dmsg ); + } + +#if TBB_USE_ASSERT + template + friend class opencl_buffer; +#endif +}; + +enum access_type { + read_write, + write_only, + read_only +}; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE +opencl_subbuffer; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE +opencl_buffer { +public: + typedef cl_mem native_object_type; + typedef opencl_buffer memory_object_type; + typedef Factory opencl_factory_type; + + template using iterator = T*; + + template + iterator
access() const { + T* ptr = (T*)my_impl->get_host_ptr(); + __TBB_ASSERT( ptr, NULL ); + return iterator( ptr ); + } + + T* data() const { return &access()[0]; } + + template + iterator begin() const { return access(); } + + template + iterator end() const { return access()+my_impl->size()/sizeof(T); } + + size_t size() const { return my_impl->size()/sizeof(T); } + + T& operator[] ( ptrdiff_t k ) { return begin()[k]; } + + opencl_buffer() {} + opencl_buffer( size_t size ); + opencl_buffer( Factory &f, size_t size ) : my_impl( std::make_shared( size*sizeof(T), f ) ) {} + + cl_mem native_object() const { + return my_impl->get_cl_mem(); + } + + const opencl_buffer& memory_object() const { + return *this; + } + + void send( opencl_device device, opencl_async_msg &dependency ) const { + __TBB_ASSERT( dependency.data( /*wait = */false ) == *this, NULL ); + opencl_async_msg d = my_impl->send( device, dependency.get_event() ); + const cl_event *e = d.get_event(); + if ( e ) dependency.set_event( *e ); + else dependency.clear_event(); + } + void receive( const opencl_async_msg &dependency ) const { + __TBB_ASSERT( dependency.data( /*wait = */false ) == *this, NULL ); + opencl_async_msg d = my_impl->receive( dependency.get_event() ); + const cl_event *e = d.get_event(); + if ( e ) dependency.set_event( *e ); + else dependency.clear_event(); + } + + opencl_subbuffer subbuffer( size_t index, size_t size ) const; +private: + // The constructor for subbuffers. + opencl_buffer( Factory &f, cl_mem m, size_t index, size_t size ) : my_impl( std::make_shared( m, index*sizeof(T), size*sizeof(T), f ) ) {} + + typedef opencl_buffer_impl impl_type; + + std::shared_ptr my_impl; + + friend bool operator==(const opencl_buffer &lhs, const opencl_buffer &rhs) { + return lhs.my_impl == rhs.my_impl; + } + + template + friend class opencl_factory; + template + friend class opencl_subbuffer; +}; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE +opencl_subbuffer : public opencl_buffer { + opencl_buffer my_owner; +public: + opencl_subbuffer() {} + opencl_subbuffer( const opencl_buffer &owner, size_t index, size_t size ) : + opencl_buffer( *owner.my_impl->factory(), owner.native_object(), index, size ), my_owner( owner ) {} +}; + +template +opencl_subbuffer opencl_buffer::subbuffer( size_t index, size_t size ) const { + return opencl_subbuffer( *this, index, size ); +} + + +#define is_typedef(type) \ + template \ + struct is_##type { \ + template \ + static std::true_type check( typename C::type* ); \ + template \ + static std::false_type check( ... ); \ + \ + static const bool value = decltype(check(0))::value; \ + } + +is_typedef( native_object_type ); +is_typedef( memory_object_type ); + +template +typename std::enable_if::value, typename T::native_object_type>::type get_native_object( const T &t ) { + return t.native_object(); +} + +template +typename std::enable_if::value, T>::type get_native_object( T t ) { + return t; +} + +// send_if_memory_object checks if the T type has memory_object_type and call the send method for the object. +template +typename std::enable_if::value>::type send_if_memory_object( opencl_device device, opencl_async_msg &dmsg ) { + const T &t = dmsg.data( false ); + typedef typename T::memory_object_type mem_obj_t; + mem_obj_t mem_obj = t.memory_object(); + opencl_async_msg d( mem_obj ); + if ( dmsg.get_event() ) d.set_event( *dmsg.get_event() ); + mem_obj.send( device, d ); + if ( d.get_event() ) dmsg.set_event( *d.get_event() ); +} + +template +typename std::enable_if::value>::type send_if_memory_object( opencl_device device, T &t ) { + typedef typename T::memory_object_type mem_obj_t; + mem_obj_t mem_obj = t.memory_object(); + opencl_async_msg dmsg( mem_obj ); + mem_obj.send( device, dmsg ); +} + +template +typename std::enable_if::value>::type send_if_memory_object( opencl_device, T& ) {}; + +// receive_if_memory_object checks if the T type has memory_object_type and call the receive method for the object. +template +typename std::enable_if::value>::type receive_if_memory_object( const opencl_async_msg &dmsg ) { + const T &t = dmsg.data( false ); + typedef typename T::memory_object_type mem_obj_t; + mem_obj_t mem_obj = t.memory_object(); + opencl_async_msg d( mem_obj ); + if ( dmsg.get_event() ) d.set_event( *dmsg.get_event() ); + mem_obj.receive( d ); + if ( d.get_event() ) dmsg.set_event( *d.get_event() ); +} + +template +typename std::enable_if::value>::type receive_if_memory_object( const T& ) {} + +class __TBB_DEPRECATED_IN_VERBOSE_MODE opencl_range { +public: + typedef size_t range_index_type; + typedef std::array nd_range_type; + + template , typename L = std::initializer_list, + typename = typename std::enable_if::type, opencl_range>::value>::type> + opencl_range(G&& global_work = std::initializer_list({ 0 }), L&& local_work = std::initializer_list({ 0, 0, 0 })) { + auto g_it = global_work.begin(); + auto l_it = local_work.begin(); + my_global_work_size = { {size_t(-1), size_t(-1), size_t(-1)} }; + // my_local_work_size is still uninitialized + for (int s = 0; s < 3 && g_it != global_work.end(); ++g_it, ++l_it, ++s) { + __TBB_ASSERT(l_it != local_work.end(), "global_work & local_work must have same size"); + my_global_work_size[s] = *g_it; + my_local_work_size[s] = *l_it; + } + } + + const nd_range_type& global_range() const { return my_global_work_size; } + const nd_range_type& local_range() const { return my_local_work_size; } + +private: + nd_range_type my_global_work_size; + nd_range_type my_local_work_size; +}; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE opencl_factory { +public: + template using async_msg_type = opencl_async_msg>; + typedef opencl_device device_type; + + class kernel : tbb::internal::no_assign { + public: + kernel( const kernel& k ) : my_factory( k.my_factory ) { + // Clone my_cl_kernel via opencl_program + size_t ret_size = 0; + + std::vector kernel_name; + for ( size_t curr_size = 32;; curr_size <<= 1 ) { + kernel_name.resize( curr_size <<= 1 ); + enforce_cl_retcode( clGetKernelInfo( k.my_cl_kernel, CL_KERNEL_FUNCTION_NAME, curr_size, kernel_name.data(), &ret_size ), "Failed to get kernel info" ); + if ( ret_size < curr_size ) break; + } + + cl_program program; + enforce_cl_retcode( clGetKernelInfo( k.my_cl_kernel, CL_KERNEL_PROGRAM, sizeof(program), &program, &ret_size ), "Failed to get kernel info" ); + __TBB_ASSERT( ret_size == sizeof(program), NULL ); + + my_cl_kernel = opencl_program< factory_type >( my_factory, program ).get_cl_kernel( kernel_name.data() ); + } + + ~kernel() { + enforce_cl_retcode( clReleaseKernel( my_cl_kernel ), "Failed to release a kernel" ); + } + + private: + typedef opencl_factory factory_type; + + kernel( const cl_kernel& k, factory_type& f ) : my_cl_kernel( k ), my_factory( f ) {} + + // Data + cl_kernel my_cl_kernel; + factory_type& my_factory; + + template + friend class opencl_factory; + + template + friend class opencl_program; + }; + + typedef kernel kernel_type; + + // 'range_type' enables kernel_executor with range support + // it affects expectations for enqueue_kernel(.....) interface method + typedef opencl_range range_type; + + opencl_factory() {} + ~opencl_factory() { + if ( my_devices.size() ) { + for ( auto d = my_devices.begin(); d != my_devices.end(); ++d ) { + enforce_cl_retcode( clReleaseCommandQueue( (*d).my_cl_command_queue ), "Failed to release a command queue" ); + } + enforce_cl_retcode( clReleaseContext( my_cl_context ), "Failed to release a context" ); + } + } + + bool init( const opencl_device_list &device_list ) { + tbb::spin_mutex::scoped_lock lock( my_devices_mutex ); + if ( !my_devices.size() ) { + my_devices = device_list; + return true; + } + return false; + } + + +private: + template + void enqueue_map_buffer( opencl_device device, opencl_buffer_impl &buffer, opencl_async_msg& dmsg ) { + cl_event const* e1 = dmsg.get_event(); + cl_event e2; + cl_int err; + void *ptr = clEnqueueMapBuffer( device.my_cl_command_queue, buffer.get_cl_mem(), false, CL_MAP_READ | CL_MAP_WRITE, 0, buffer.size(), + e1 == NULL ? 0 : 1, e1, &e2, &err ); + enforce_cl_retcode( err, "Failed to map a buffer" ); + dmsg.data( false ) = ptr; + dmsg.set_event( e2 ); + enforce_cl_retcode( clReleaseEvent( e2 ), "Failed to release an event" ); + } + + + template + void enqueue_unmap_buffer( opencl_device device, opencl_memory &memory, opencl_async_msg& dmsg ) { + cl_event const* e1 = dmsg.get_event(); + cl_event e2; + enforce_cl_retcode( + clEnqueueUnmapMemObject( device.my_cl_command_queue, memory.get_cl_mem(), memory.get_host_ptr(), e1 == NULL ? 0 : 1, e1, &e2 ), + "Failed to unmap a buffer" ); + dmsg.set_event( e2 ); + enforce_cl_retcode( clReleaseEvent( e2 ), "Failed to release an event" ); + } + + // --------- Kernel argument & event list helpers --------- // + template + void process_one_arg( const kernel_type& kernel, std::array&, int&, int& place, const T& t ) { + auto p = get_native_object(t); + enforce_cl_retcode( clSetKernelArg(kernel.my_cl_kernel, place++, sizeof(p), &p), "Failed to set a kernel argument" ); + } + + template + void process_one_arg( const kernel_type& kernel, std::array& events, int& num_events, int& place, const opencl_async_msg& msg ) { + __TBB_ASSERT((static_cast::size_type>(num_events) < events.size()), NULL); + + const cl_event * const e = msg.get_event(); + if (e != NULL) { + events[num_events++] = *e; + } + + process_one_arg( kernel, events, num_events, place, msg.data(false) ); + } + + template + void process_arg_list( const kernel_type& kernel, std::array& events, int& num_events, int& place, const T& t, const Rest&... args ) { + process_one_arg( kernel, events, num_events, place, t ); + process_arg_list( kernel, events, num_events, place, args... ); + } + + template + void process_arg_list( const kernel_type&, std::array&, int&, int& ) {} + // ------------------------------------------- // + template + void update_one_arg( cl_event, T& ) {} + + template + void update_one_arg( cl_event e, opencl_async_msg& msg ) { + msg.set_event( e ); + } + + template + void update_arg_list( cl_event e, T& t, Rest&... args ) { + update_one_arg( e, t ); + update_arg_list( e, args... ); + } + + void update_arg_list( cl_event ) {} + // ------------------------------------------- // +public: + template + void send_kernel( opencl_device device, const kernel_type& kernel, const range_type& work_size, Args&... args ) { + std::array events; + int num_events = 0; + int place = 0; + process_arg_list( kernel, events, num_events, place, args... ); + + const cl_event e = send_kernel_impl( device, kernel.my_cl_kernel, work_size, num_events, events.data() ); + + update_arg_list(e, args...); + + // Release our own reference to cl_event + enforce_cl_retcode( clReleaseEvent(e), "Failed to release an event" ); + } + + // ------------------------------------------- // + template + void send_data(opencl_device device, T& t, Rest&... args) { + send_if_memory_object( device, t ); + send_data( device, args... ); + } + + void send_data(opencl_device) {} + // ------------------------------------------- // + +private: + cl_event send_kernel_impl( opencl_device device, const cl_kernel& kernel, + const range_type& work_size, cl_uint num_events, cl_event* event_list ) { + const typename range_type::nd_range_type g_offset = { { 0, 0, 0 } }; + const typename range_type::nd_range_type& g_size = work_size.global_range(); + const typename range_type::nd_range_type& l_size = work_size.local_range(); + cl_uint s; + for ( s = 1; s < 3 && g_size[s] != size_t(-1); ++s) {} + cl_event event; + enforce_cl_retcode( + clEnqueueNDRangeKernel( device.my_cl_command_queue, kernel, s, + g_offset.data(), g_size.data(), l_size[0] ? l_size.data() : NULL, num_events, num_events ? event_list : NULL, &event ), + "Failed to enqueue a kernel" ); + return event; + } + + // ------------------------------------------- // + template + bool get_event_from_one_arg( cl_event&, const T& ) { + return false; + } + + template + bool get_event_from_one_arg( cl_event& e, const opencl_async_msg& msg) { + cl_event const *e_ptr = msg.get_event(); + + if ( e_ptr != NULL ) { + e = *e_ptr; + return true; + } + + return false; + } + + template + bool get_event_from_args( cl_event& e, const T& t, const Rest&... args ) { + if ( get_event_from_one_arg( e, t ) ) { + return true; + } + + return get_event_from_args( e, args... ); + } + + bool get_event_from_args( cl_event& ) { + return false; + } + // ------------------------------------------- // + + struct finalize_fn : tbb::internal::no_assign { + virtual ~finalize_fn() {} + virtual void operator() () {} + }; + + template + struct finalize_fn_leaf : public finalize_fn { + Fn my_fn; + finalize_fn_leaf(Fn fn) : my_fn(fn) {} + void operator() () __TBB_override { my_fn(); } + }; + + static void CL_CALLBACK finalize_callback(cl_event, cl_int event_command_exec_status, void *data) { + tbb::internal::suppress_unused_warning(event_command_exec_status); + __TBB_ASSERT(event_command_exec_status == CL_COMPLETE, NULL); + + finalize_fn * const fn_ptr = static_cast(data); + __TBB_ASSERT(fn_ptr != NULL, "Invalid finalize function pointer"); + (*fn_ptr)(); + + // Function pointer was created by 'new' & this callback must be called once only + delete fn_ptr; + } +public: + template + void finalize( opencl_device device, FinalizeFn fn, Args&... args ) { + cl_event e; + + if ( get_event_from_args( e, args... ) ) { + enforce_cl_retcode( clSetEventCallback( e, CL_COMPLETE, finalize_callback, + new finalize_fn_leaf(fn) ), "Failed to set a callback" ); + } + + enforce_cl_retcode( clFlush( device.my_cl_command_queue ), "Failed to flush an OpenCL command queue" ); + } + + const opencl_device_list& devices() { + std::call_once( my_once_flag, &opencl_factory::init_once, this ); + return my_devices; + } + +private: + bool is_same_context( opencl_device::device_id_type d1, opencl_device::device_id_type d2 ) { + __TBB_ASSERT( d1 != opencl_device::unknown && d2 != opencl_device::unknown, NULL ); + // Currently, factory supports only one context so if the both devices are not host it means the are in the same context. + if ( d1 != opencl_device::host && d2 != opencl_device::host ) + return true; + return d1 == d2; + } +private: + opencl_factory( const opencl_factory& ); + opencl_factory& operator=(const opencl_factory&); + + cl_context context() { + std::call_once( my_once_flag, &opencl_factory::init_once, this ); + return my_cl_context; + } + + void init_once() { + { + tbb::spin_mutex::scoped_lock lock(my_devices_mutex); + if (!my_devices.size()) + my_devices = DeviceFilter()( opencl_info::available_devices() ); + } + + enforce_cl_retcode(my_devices.size() ? CL_SUCCESS : CL_INVALID_DEVICE, "No devices in the device list"); + cl_platform_id platform_id = my_devices.begin()->platform_id(); + for (opencl_device_list::iterator it = ++my_devices.begin(); it != my_devices.end(); ++it) + enforce_cl_retcode(it->platform_id() == platform_id ? CL_SUCCESS : CL_INVALID_PLATFORM, "All devices should be in the same platform"); + + std::vector cl_device_ids; + for (auto d = my_devices.begin(); d != my_devices.end(); ++d) { + cl_device_ids.push_back((*d).my_cl_device_id); + } + + cl_context_properties context_properties[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, (cl_context_properties)NULL }; + cl_int err; + cl_context ctx = clCreateContext(context_properties, + (cl_uint)cl_device_ids.size(), + cl_device_ids.data(), + NULL, NULL, &err); + enforce_cl_retcode(err, "Failed to create context"); + my_cl_context = ctx; + + size_t device_counter = 0; + for (auto d = my_devices.begin(); d != my_devices.end(); d++) { + (*d).my_device_id = device_counter++; + cl_int err2; + cl_command_queue cq; +#if CL_VERSION_2_0 + if ((*d).major_version() >= 2) { + if ((*d).out_of_order_exec_mode_on_host_present()) { + cl_queue_properties props[] = { CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, 0 }; + cq = clCreateCommandQueueWithProperties(ctx, (*d).my_cl_device_id, props, &err2); + } else { + cl_queue_properties props[] = { 0 }; + cq = clCreateCommandQueueWithProperties(ctx, (*d).my_cl_device_id, props, &err2); + } + } else +#endif + { + cl_command_queue_properties props = (*d).out_of_order_exec_mode_on_host_present() ? CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE : 0; + // Suppress "declared deprecated" warning for the next line. +#if __TBB_GCC_WARNING_SUPPRESSION_PRESENT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#if _MSC_VER || __INTEL_COMPILER +#pragma warning( push ) +#if __INTEL_COMPILER +#pragma warning (disable: 1478) +#else +#pragma warning (disable: 4996) +#endif +#endif + cq = clCreateCommandQueue(ctx, (*d).my_cl_device_id, props, &err2); +#if _MSC_VER || __INTEL_COMPILER +#pragma warning( pop ) +#endif +#if __TBB_GCC_WARNING_SUPPRESSION_PRESENT +#pragma GCC diagnostic pop +#endif + } + enforce_cl_retcode(err2, "Failed to create command queue"); + (*d).my_cl_command_queue = cq; + } + } + + std::once_flag my_once_flag; + opencl_device_list my_devices; + cl_context my_cl_context; + + tbb::spin_mutex my_devices_mutex; + + template + friend class opencl_program; + template + friend class opencl_buffer_impl; + template + friend class opencl_memory; +}; // class opencl_factory + +// TODO: consider this namespace as public API +namespace opencl_info { + +// Default types + +template +struct default_device_selector { + opencl_device operator()(Factory& f) { + __TBB_ASSERT(!f.devices().empty(), "No available devices"); + return *(f.devices().begin()); + } +}; + +struct default_device_filter { + opencl_device_list operator()(const opencl_device_list &devices) { + opencl_device_list dl; + cl_platform_id platform_id = devices.begin()->platform_id(); + for (opencl_device_list::const_iterator it = devices.cbegin(); it != devices.cend(); ++it) { + if (it->platform_id() == platform_id) { + dl.add(*it); + } + } + return dl; + } +}; + +class default_opencl_factory : public opencl_factory < default_device_filter >, tbb::internal::no_copy { +public: + template using async_msg_type = opencl_async_msg; + + friend default_opencl_factory& default_factory(); + +private: + default_opencl_factory() = default; +}; + +inline default_opencl_factory& default_factory() { + static default_opencl_factory default_factory; + return default_factory; +} + +} // namespace opencl_info + +template +opencl_buffer::opencl_buffer( size_t size ) : my_impl( std::make_shared( size*sizeof(T), opencl_info::default_factory() ) ) {} + + +enum class opencl_program_type { + SOURCE, + PRECOMPILED, + SPIR +}; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE opencl_program : tbb::internal::no_assign { +public: + typedef typename Factory::kernel_type kernel_type; + + opencl_program( Factory& factory, opencl_program_type type, const std::string& program_name ) : my_factory( factory ), my_type(type) , my_arg_str( program_name) {} + opencl_program( Factory& factory, const char* program_name ) : opencl_program( factory, std::string( program_name ) ) {} + opencl_program( Factory& factory, const std::string& program_name ) : opencl_program( factory, opencl_program_type::SOURCE, program_name ) {} + + opencl_program( opencl_program_type type, const std::string& program_name ) : opencl_program( opencl_info::default_factory(), type, program_name ) {} + opencl_program( const char* program_name ) : opencl_program( opencl_info::default_factory(), program_name ) {} + opencl_program( const std::string& program_name ) : opencl_program( opencl_info::default_factory(), program_name ) {} + opencl_program( opencl_program_type type ) : opencl_program( opencl_info::default_factory(), type ) {} + + opencl_program( const opencl_program &src ) : my_factory( src.my_factory ), my_type( src.type ), my_arg_str( src.my_arg_str ), my_cl_program( src.my_cl_program ) { + // Set my_do_once_flag to the called state. + std::call_once( my_do_once_flag, [](){} ); + } + + kernel_type get_kernel( const std::string& k ) const { + return kernel_type( get_cl_kernel(k), my_factory ); + } + +private: + opencl_program( Factory& factory, cl_program program ) : my_factory( factory ), my_cl_program( program ) { + // Set my_do_once_flag to the called state. + std::call_once( my_do_once_flag, [](){} ); + } + + cl_kernel get_cl_kernel( const std::string& k ) const { + std::call_once( my_do_once_flag, [this, &k](){ this->init( k ); } ); + cl_int err; + cl_kernel kernel = clCreateKernel( my_cl_program, k.c_str(), &err ); + enforce_cl_retcode( err, std::string( "Failed to create kernel: " ) + k ); + return kernel; + } + + class file_reader { + public: + file_reader( const std::string& filepath ) { + std::ifstream file_descriptor( filepath, std::ifstream::binary ); + if ( !file_descriptor.is_open() ) { + std::string str = std::string( "Could not open file: " ) + filepath; + std::cerr << str << std::endl; + throw str; + } + file_descriptor.seekg( 0, file_descriptor.end ); + size_t length = size_t( file_descriptor.tellg() ); + file_descriptor.seekg( 0, file_descriptor.beg ); + my_content.resize( length ); + char* begin = &*my_content.begin(); + file_descriptor.read( begin, length ); + file_descriptor.close(); + } + const char* content() { return &*my_content.cbegin(); } + size_t length() { return my_content.length(); } + private: + std::string my_content; + }; + + class opencl_program_builder { + public: + typedef void (CL_CALLBACK *cl_callback_type)(cl_program, void*); + opencl_program_builder( Factory& f, const std::string& name, cl_program program, + cl_uint num_devices, cl_device_id* device_list, + const char* options, cl_callback_type callback, + void* user_data ) { + cl_int err = clBuildProgram( program, num_devices, device_list, options, + callback, user_data ); + if( err == CL_SUCCESS ) + return; + std::string str = std::string( "Failed to build program: " ) + name; + if ( err == CL_BUILD_PROGRAM_FAILURE ) { + const opencl_device_list &devices = f.devices(); + for ( auto d = devices.begin(); d != devices.end(); ++d ) { + std::cerr << "Build log for device: " << (*d).name() << std::endl; + size_t log_size; + cl_int query_err = clGetProgramBuildInfo( + program, (*d).my_cl_device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, + &log_size ); + enforce_cl_retcode( query_err, "Failed to get build log size" ); + if( log_size ) { + std::vector output; + output.resize( log_size ); + query_err = clGetProgramBuildInfo( + program, (*d).my_cl_device_id, CL_PROGRAM_BUILD_LOG, + output.size(), output.data(), NULL ); + enforce_cl_retcode( query_err, "Failed to get build output" ); + std::cerr << output.data() << std::endl; + } else { + std::cerr << "No build log available" << std::endl; + } + } + } + enforce_cl_retcode( err, str ); + } + }; + + class opencl_device_filter { + public: + template + opencl_device_filter( cl_uint& num_devices, cl_device_id* device_list, + Filter filter, const char* message ) { + for ( cl_uint i = 0; i < num_devices; ++i ) + if ( filter(device_list[i]) ) { + device_list[i--] = device_list[--num_devices]; + } + if ( !num_devices ) + enforce_cl_retcode( CL_DEVICE_NOT_AVAILABLE, message ); + } + }; + + void init( const std::string& ) const { + cl_uint num_devices; + enforce_cl_retcode( clGetContextInfo( my_factory.context(), CL_CONTEXT_NUM_DEVICES, sizeof( num_devices ), &num_devices, NULL ), + "Failed to get OpenCL context info" ); + if ( !num_devices ) + enforce_cl_retcode( CL_DEVICE_NOT_FOUND, "No supported devices found" ); + cl_device_id *device_list = (cl_device_id *)alloca( num_devices*sizeof( cl_device_id ) ); + enforce_cl_retcode( clGetContextInfo( my_factory.context(), CL_CONTEXT_DEVICES, num_devices*sizeof( cl_device_id ), device_list, NULL ), + "Failed to get OpenCL context info" ); + const char *options = NULL; + switch ( my_type ) { + case opencl_program_type::SOURCE: { + file_reader fr( my_arg_str ); + const char *s[] = { fr.content() }; + const size_t l[] = { fr.length() }; + cl_int err; + my_cl_program = clCreateProgramWithSource( my_factory.context(), 1, s, l, &err ); + enforce_cl_retcode( err, std::string( "Failed to create program: " ) + my_arg_str ); + opencl_device_filter( + num_devices, device_list, + []( const opencl_device& d ) -> bool { + return !d.compiler_available() || !d.linker_available(); + }, "No one device supports building program from sources" ); + opencl_program_builder( + my_factory, my_arg_str, my_cl_program, num_devices, device_list, + options, /*callback*/ NULL, /*user data*/NULL ); + break; + } + case opencl_program_type::SPIR: + options = "-x spir"; + case opencl_program_type::PRECOMPILED: { + file_reader fr( my_arg_str ); + std::vector s( + num_devices, reinterpret_cast(fr.content()) ); + std::vector l( num_devices, fr.length() ); + std::vector bin_statuses( num_devices, -1 ); + cl_int err; + my_cl_program = clCreateProgramWithBinary( my_factory.context(), num_devices, + device_list, l.data(), s.data(), + bin_statuses.data(), &err ); + if( err != CL_SUCCESS ) { + std::string statuses_str; + for (auto st = bin_statuses.begin(); st != bin_statuses.end(); ++st) { + statuses_str += std::to_string((*st)); + } + + enforce_cl_retcode( err, std::string( "Failed to create program, error " + std::to_string( err ) + " : " ) + my_arg_str + + std::string( ", binary_statuses = " ) + statuses_str ); + } + opencl_program_builder( + my_factory, my_arg_str, my_cl_program, num_devices, device_list, + options, /*callback*/ NULL, /*user data*/NULL ); + break; + } + default: + __TBB_ASSERT( false, "Unsupported program type" ); + } + } + + Factory& my_factory; + opencl_program_type my_type; + std::string my_arg_str; + mutable cl_program my_cl_program; + mutable std::once_flag my_do_once_flag; + + template + friend class opencl_factory; + + friend class Factory::kernel; +}; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE opencl_node; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE +opencl_node< tuple, JP, Factory > : public streaming_node< tuple, JP, Factory > { + typedef streaming_node < tuple, JP, Factory > base_type; +public: + typedef typename base_type::kernel_type kernel_type; + + opencl_node( graph &g, const kernel_type& kernel ) + : base_type( g, kernel, opencl_info::default_device_selector< opencl_info::default_opencl_factory >(), opencl_info::default_factory() ) + { + tbb::internal::fgt_multiinput_multioutput_node( CODEPTR(), tbb::internal::FLOW_OPENCL_NODE, this, &this->my_graph ); + } + + opencl_node( graph &g, const kernel_type& kernel, Factory &f ) + : base_type( g, kernel, opencl_info::default_device_selector (), f ) + { + tbb::internal::fgt_multiinput_multioutput_node( CODEPTR(), tbb::internal::FLOW_OPENCL_NODE, this, &this->my_graph ); + } + + template + opencl_node( graph &g, const kernel_type& kernel, DeviceSelector d, Factory &f) + : base_type( g, kernel, d, f) + { + tbb::internal::fgt_multiinput_multioutput_node( CODEPTR(), tbb::internal::FLOW_OPENCL_NODE, this, &this->my_graph ); + } +}; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE +opencl_node< tuple, JP > : public opencl_node < tuple, JP, opencl_info::default_opencl_factory > { + typedef opencl_node < tuple, JP, opencl_info::default_opencl_factory > base_type; +public: + typedef typename base_type::kernel_type kernel_type; + + opencl_node( graph &g, const kernel_type& kernel ) + : base_type( g, kernel, opencl_info::default_device_selector< opencl_info::default_opencl_factory >(), opencl_info::default_factory() ) + {} + + template + opencl_node( graph &g, const kernel_type& kernel, DeviceSelector d ) + : base_type( g, kernel, d, opencl_info::default_factory() ) + {} +}; + +template +class __TBB_DEPRECATED_IN_VERBOSE_MODE +opencl_node< tuple > : public opencl_node < tuple, queueing, opencl_info::default_opencl_factory > { + typedef opencl_node < tuple, queueing, opencl_info::default_opencl_factory > base_type; +public: + typedef typename base_type::kernel_type kernel_type; + + opencl_node( graph &g, const kernel_type& kernel ) + : base_type( g, kernel, opencl_info::default_device_selector< opencl_info::default_opencl_factory >(), opencl_info::default_factory() ) + {} + + template + opencl_node( graph &g, const kernel_type& kernel, DeviceSelector d ) + : base_type( g, kernel, d, opencl_info::default_factory() ) + {} +}; + +} // namespace interfaceX + +using interface11::opencl_node; +using interface11::read_only; +using interface11::read_write; +using interface11::write_only; +using interface11::opencl_buffer; +using interface11::opencl_subbuffer; +using interface11::opencl_device; +using interface11::opencl_device_list; +using interface11::opencl_program; +using interface11::opencl_program_type; +using interface11::opencl_async_msg; +using interface11::opencl_factory; +using interface11::opencl_range; + +} // namespace flow +} // namespace tbb +#endif /* __TBB_PREVIEW_OPENCL_NODE */ + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_flow_graph_opencl_node_H_include_area + +#endif // __TBB_flow_graph_opencl_node_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/global_control.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/global_control.h new file mode 100644 index 00000000..bdcd59a5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/global_control.h @@ -0,0 +1,78 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_global_control_H +#define __TBB_global_control_H + +#include "tbb_stddef.h" + +namespace tbb { +namespace interface9 { + +class global_control { +public: + enum parameter { + max_allowed_parallelism, + thread_stack_size, + parameter_max // insert new parameters above this point + }; + + global_control(parameter p, size_t value) : + my_value(value), my_next(NULL), my_param(p) { + __TBB_ASSERT(my_param < parameter_max, "Invalid parameter"); +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) + // For Windows 8 Store* apps it's impossible to set stack size + if (p==thread_stack_size) + return; +#elif __TBB_x86_64 && (_WIN32 || _WIN64) + if (p==thread_stack_size) + __TBB_ASSERT_RELEASE((unsigned)value == value, "Stack size is limited to unsigned int range"); +#endif + if (my_param==max_allowed_parallelism) + __TBB_ASSERT_RELEASE(my_value>0, "max_allowed_parallelism cannot be 0."); + internal_create(); + } + + ~global_control() { + __TBB_ASSERT(my_param < parameter_max, "Invalid parameter. Probably the object was corrupted."); +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) + // For Windows 8 Store* apps it's impossible to set stack size + if (my_param==thread_stack_size) + return; +#endif + internal_destroy(); + } + + static size_t active_value(parameter p) { + __TBB_ASSERT(p < parameter_max, "Invalid parameter"); + return active_value((int)p); + } +private: + size_t my_value; + global_control *my_next; + parameter my_param; + + void __TBB_EXPORTED_METHOD internal_create(); + void __TBB_EXPORTED_METHOD internal_destroy(); + static size_t __TBB_EXPORTED_FUNC active_value(int param); +}; +} // namespace interface9 + +using interface9::global_control; + +} // tbb + +#endif // __TBB_global_control_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/index.html new file mode 100644 index 00000000..9ead0e24 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/index.html @@ -0,0 +1,29 @@ + + + +

Overview

+Include files for Intel® Threading Building Blocks classes and functions. + +
Click here to see all files in the directory. + +

Directories

+
+
compat +
Include files for source level compatibility with other frameworks. +
internal +
Include files with implementation details; not for direct use. +
machine +
Include files for low-level architecture specific functionality; not for direct use. +
+ +
+Up to parent directory +

+Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +

+Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +

+* Other names and brands may be claimed as the property of others. + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/info.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/info.h new file mode 100644 index 00000000..84b32092 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/info.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_info_H +#define __TBB_info_H + +#include "tbb_config.h" + +#if __TBB_NUMA_SUPPORT + +#include + +namespace tbb { + namespace internal { + namespace numa_topology { + unsigned nodes_count(); + void fill(int* indexes_array); + int default_concurrency(int node_id); + } //namespace numa_topology + } // namespace internal + + typedef int numa_node_id; + + namespace info { + inline std::vector numa_nodes() { + std::vector nodes_indexes(tbb::internal::numa_topology::nodes_count()); + internal::numa_topology::fill(&nodes_indexes.front()); + return nodes_indexes; + } + + inline int default_concurrency(numa_node_id id = -1) { + return internal::numa_topology::default_concurrency(id); + } + } // namespace info +} // namespace tbb + +#endif /*__TBB_NUMA_SUPPORT*/ + +#endif /*__TBB_info_H*/ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_aggregator_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_aggregator_impl.h new file mode 100644 index 00000000..6d89c055 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_aggregator_impl.h @@ -0,0 +1,180 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__aggregator_impl_H +#define __TBB__aggregator_impl_H + +#include "../atomic.h" +#if !__TBBMALLOC_BUILD +#include "../tbb_profiling.h" +#endif + +namespace tbb { +namespace interface6 { +namespace internal { + +using namespace tbb::internal; + +//! aggregated_operation base class +template +class aggregated_operation { + public: + //! Zero value means "wait" status, all other values are "user" specified values and are defined into the scope of a class which uses "status". + uintptr_t status; + + Derived *next; + aggregated_operation() : status(0), next(NULL) {} +}; + +//! Aggregator base class +/** An aggregator for collecting operations coming from multiple sources and executing + them serially on a single thread. operation_type must be derived from + aggregated_operation. The parameter handler_type is a functor that will be passed the + list of operations and is expected to handle each operation appropriately, setting the + status of each operation to non-zero.*/ +template < typename operation_type > +class aggregator_generic { +public: + aggregator_generic() : handler_busy(false) { pending_operations = NULL; } + + //! Execute an operation + /** Places an operation into the waitlist (pending_operations), and either handles the list, + or waits for the operation to complete, or returns. + The long_life_time parameter specifies the life time of the given operation object. + Operations with long_life_time == true may be accessed after execution. + A "short" life time operation (long_life_time == false) can be destroyed + during execution, and so any access to it after it was put into the waitlist, + including status check, is invalid. As a consequence, waiting for completion + of such operation causes undefined behavior. + */ + template < typename handler_type > + void execute(operation_type *op, handler_type &handle_operations, bool long_life_time = true) { + operation_type *res; + // op->status should be read before inserting the operation into the + // aggregator waitlist since it can become invalid after executing a + // handler (if the operation has 'short' life time.) + const uintptr_t status = op->status; + + // ITT note: &(op->status) tag is used to cover accesses to this op node. This + // thread has created the operation, and now releases it so that the handler + // thread may handle the associated operation w/o triggering a race condition; + // thus this tag will be acquired just before the operation is handled in the + // handle_operations functor. + call_itt_notify(releasing, &(op->status)); + // insert the operation in the queue. + do { + // Tools may flag the following line as a race; it is a false positive: + // This is an atomic read; we don't provide itt_hide_load_word for atomics + op->next = res = pending_operations; // NOT A RACE + } while (pending_operations.compare_and_swap(op, res) != res); + if (!res) { // first in the list; handle the operations. + // ITT note: &pending_operations tag covers access to the handler_busy flag, + // which this waiting handler thread will try to set before entering + // handle_operations. + call_itt_notify(acquired, &pending_operations); + start_handle_operations(handle_operations); + // The operation with 'short' life time can already be destroyed. + if (long_life_time) + __TBB_ASSERT(op->status, NULL); + } + // not first; wait for op to be ready. + else if (!status) { // operation is blocking here. + __TBB_ASSERT(long_life_time, "Waiting for an operation object that might be destroyed during processing."); + call_itt_notify(prepare, &(op->status)); + spin_wait_while_eq(op->status, uintptr_t(0)); + itt_load_word_with_acquire(op->status); + } + } + + private: + //! An atomically updated list (aka mailbox) of pending operations + atomic pending_operations; + //! Controls thread access to handle_operations + uintptr_t handler_busy; + + //! Trigger the handling of operations when the handler is free + template < typename handler_type > + void start_handle_operations( handler_type &handle_operations ) { + operation_type *op_list; + + // ITT note: &handler_busy tag covers access to pending_operations as it is passed + // between active and waiting handlers. Below, the waiting handler waits until + // the active handler releases, and the waiting handler acquires &handler_busy as + // it becomes the active_handler. The release point is at the end of this + // function, when all operations in pending_operations have been handled by the + // owner of this aggregator. + call_itt_notify(prepare, &handler_busy); + // get the handler_busy: + // only one thread can possibly spin here at a time + spin_wait_until_eq(handler_busy, uintptr_t(0)); + call_itt_notify(acquired, &handler_busy); + // acquire fence not necessary here due to causality rule and surrounding atomics + __TBB_store_with_release(handler_busy, uintptr_t(1)); + + // ITT note: &pending_operations tag covers access to the handler_busy flag + // itself. Capturing the state of the pending_operations signifies that + // handler_busy has been set and a new active handler will now process that list's + // operations. + call_itt_notify(releasing, &pending_operations); + // grab pending_operations + op_list = pending_operations.fetch_and_store(NULL); + + // handle all the operations + handle_operations(op_list); + + // release the handler + itt_store_word_with_release(handler_busy, uintptr_t(0)); + } +}; + +template < typename handler_type, typename operation_type > +class aggregator : public aggregator_generic { + handler_type handle_operations; +public: + aggregator() {} + explicit aggregator(handler_type h) : handle_operations(h) {} + + void initialize_handler(handler_type h) { handle_operations = h; } + + void execute(operation_type *op) { + aggregator_generic::execute(op, handle_operations); + } +}; + +// the most-compatible friend declaration (vs, gcc, icc) is +// template friend class aggregating_functor; +template +class aggregating_functor { + aggregating_class *fi; +public: + aggregating_functor() : fi() {} + aggregating_functor(aggregating_class *fi_) : fi(fi_) {} + void operator()(operation_list* op_list) { fi->handle_operations(op_list); } +}; + +} // namespace internal +} // namespace interface6 + +namespace internal { + using interface6::internal::aggregated_operation; + using interface6::internal::aggregator_generic; + using interface6::internal::aggregator; + using interface6::internal::aggregating_functor; +} // namespace internal + +} // namespace tbb + +#endif // __TBB__aggregator_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_allocator_traits.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_allocator_traits.h new file mode 100644 index 00000000..eba986b7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_allocator_traits.h @@ -0,0 +1,156 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_allocator_traits_H +#define __TBB_allocator_traits_H + +#include "../tbb_stddef.h" // true/false_type + +#if __TBB_ALLOCATOR_TRAITS_PRESENT +#include // for allocator_traits +#endif + +#if __TBB_CPP11_RVALUE_REF_PRESENT +#include // for std::move +#endif + +// For allocator_swap helper +#include __TBB_STD_SWAP_HEADER + +namespace tbb { +namespace internal { + +//! Internal implementation of allocator traits, propagate_on_* use internal boolean_constant. +//! In order to avoid code duplication, check what implementation of boolean constant will likely be passed. +#if __TBB_ALLOCATOR_TRAITS_PRESENT +typedef std::true_type traits_true_type; +typedef std::false_type traits_false_type; +#else +typedef tbb::internal::true_type traits_true_type; +typedef tbb::internal::false_type traits_false_type; +#endif + +//! Copy assignment implementation for allocator if propagate_on_container_copy_assignment == true_type +//! Noop if pocca == false_type +template +inline void allocator_copy_assignment(MyAlloc& my_allocator, OtherAlloc& other_allocator, traits_true_type) { + my_allocator = other_allocator; +} +template +inline void allocator_copy_assignment(MyAlloc&, OtherAlloc&, traits_false_type) { /* NO COPY */} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +//! Move assignment implementation for allocator if propagate_on_container_move_assignment == true_type. +//! Noop if pocma == false_type. +template +inline void allocator_move_assignment(MyAlloc& my_allocator, OtherAlloc& other_allocator, traits_true_type) { + my_allocator = std::move(other_allocator); +} +template +inline void allocator_move_assignment(MyAlloc&, OtherAlloc&, traits_false_type) { /* NO MOVE */ } +#endif + +//! Swap implementation for allocators if propagate_on_container_swap == true_type. +//! Noop if pocs == false_type. +template +inline void allocator_swap(MyAlloc& my_allocator, OtherAlloc& other_allocator, traits_true_type) { + using std::swap; + swap(my_allocator, other_allocator); +} +template +inline void allocator_swap(MyAlloc&, OtherAlloc&, traits_false_type) { /* NO SWAP */ } + +#if __TBB_ALLOCATOR_TRAITS_PRESENT +using std::allocator_traits; +#else +//! Internal allocator_traits implementation, which relies on C++03 standard +//! [20.1.5] allocator requirements +template +struct allocator_traits { + // C++03 allocator doesn't have to be assignable or swappable, therefore + // define these traits as false_type to do not require additional operations + // that are not supposed to be in. + typedef tbb::internal::false_type propagate_on_container_move_assignment; + typedef tbb::internal::false_type propagate_on_container_copy_assignment; + typedef tbb::internal::false_type propagate_on_container_swap; + + typedef Alloc allocator_type; + typedef typename allocator_type::value_type value_type; + + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename allocator_type::difference_type difference_type; + typedef typename allocator_type::size_type size_type; + + template struct rebind_alloc { + typedef typename Alloc::template rebind::other other; + }; + + static pointer allocate(Alloc& a, size_type n) { + return a.allocate(n); + } + + static void deallocate(Alloc& a, pointer p, size_type n) { + a.deallocate(p, n); + } + + template + static void construct(Alloc&, PT* p) { + ::new (static_cast(p)) PT(); + } + + template + static void construct(Alloc&, PT* p, __TBB_FORWARDING_REF(T1) t1) { + ::new (static_cast(p)) PT(tbb::internal::forward(t1)); + } + + template + static void construct(Alloc&, PT* p, __TBB_FORWARDING_REF(T1) t1, __TBB_FORWARDING_REF(T2) t2) { + ::new (static_cast(p)) PT(tbb::internal::forward(t1), tbb::internal::forward(t2)); + } + + template + static void construct(Alloc&, PT* p, __TBB_FORWARDING_REF(T1) t1, + __TBB_FORWARDING_REF(T2) t2, __TBB_FORWARDING_REF(T3) t3) { + ::new (static_cast(p)) PT(tbb::internal::forward(t1), tbb::internal::forward(t2), + tbb::internal::forward(t3)); + } + + template + static void destroy(Alloc&, T* p) { + p->~T(); + tbb::internal::suppress_unused_warning(p); + } + + static Alloc select_on_container_copy_construction(const Alloc& a) { return a; } +}; +#endif // __TBB_ALLOCATOR_TRAITS_PRESENT + +//! C++03/C++11 compliant rebind helper, even if no std::allocator_traits available +//! or rebind is not defined for allocator type +template +struct allocator_rebind { +#if __TBB_ALLOCATOR_TRAITS_PRESENT + typedef typename allocator_traits::template rebind_alloc type; +#else + typedef typename allocator_traits::template rebind_alloc::other type; +#endif +}; + +}} // namespace tbb::internal + +#endif // __TBB_allocator_traits_H + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_queue_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_queue_impl.h new file mode 100644 index 00000000..e3bef772 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_queue_impl.h @@ -0,0 +1,1081 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__concurrent_queue_impl_H +#define __TBB__concurrent_queue_impl_H + +#ifndef __TBB_concurrent_queue_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#include "../tbb_stddef.h" +#include "../tbb_machine.h" +#include "../atomic.h" +#include "../spin_mutex.h" +#include "../cache_aligned_allocator.h" +#include "../tbb_exception.h" +#include "../tbb_profiling.h" +#include +#include __TBB_STD_SWAP_HEADER +#include + +namespace tbb { + +#if !__TBB_TEMPLATE_FRIENDS_BROKEN + +// forward declaration +namespace strict_ppl { +template class concurrent_queue; +} + +template class concurrent_bounded_queue; + +#endif + +//! For internal use only. +namespace strict_ppl { + +//! @cond INTERNAL +namespace internal { + +using namespace tbb::internal; + +typedef size_t ticket; + +template class micro_queue ; +template class micro_queue_pop_finalizer ; +template class concurrent_queue_base_v3; +template struct concurrent_queue_rep; + +//! parts of concurrent_queue_rep that do not have references to micro_queue +/** + * For internal use only. + */ +struct concurrent_queue_rep_base : no_copy { + template friend class micro_queue; + template friend class concurrent_queue_base_v3; + +protected: + //! Approximately n_queue/golden ratio + static const size_t phi = 3; + +public: + // must be power of 2 + static const size_t n_queue = 8; + + //! Prefix on a page + struct page { + page* next; + uintptr_t mask; + }; + + atomic head_counter; + char pad1[NFS_MaxLineSize-sizeof(atomic)]; + atomic tail_counter; + char pad2[NFS_MaxLineSize-sizeof(atomic)]; + + //! Always a power of 2 + size_t items_per_page; + + //! Size of an item + size_t item_size; + + //! number of invalid entries in the queue + atomic n_invalid_entries; + + char pad3[NFS_MaxLineSize-sizeof(size_t)-sizeof(size_t)-sizeof(atomic)]; +} ; + +inline bool is_valid_page(const concurrent_queue_rep_base::page* p) { + return uintptr_t(p)>1; +} + +//! Abstract class to define interface for page allocation/deallocation +/** + * For internal use only. + */ +class concurrent_queue_page_allocator +{ + template friend class micro_queue ; + template friend class micro_queue_pop_finalizer ; +protected: + virtual ~concurrent_queue_page_allocator() {} +private: + virtual concurrent_queue_rep_base::page* allocate_page() = 0; + virtual void deallocate_page( concurrent_queue_rep_base::page* p ) = 0; +} ; + +#if _MSC_VER && !defined(__INTEL_COMPILER) +// unary minus operator applied to unsigned type, result still unsigned +#pragma warning( push ) +#pragma warning( disable: 4146 ) +#endif + +//! A queue using simple locking. +/** For efficiency, this class has no constructor. + The caller is expected to zero-initialize it. */ +template +class micro_queue : no_copy { +public: + typedef void (*item_constructor_t)(T* location, const void* src); +private: + typedef concurrent_queue_rep_base::page page; + + //! Class used to ensure exception-safety of method "pop" + class destroyer: no_copy { + T& my_value; + public: + destroyer( T& value ) : my_value(value) {} + ~destroyer() {my_value.~T();} + }; + + void copy_item( page& dst, size_t dindex, const void* src, item_constructor_t construct_item ) { + construct_item( &get_ref(dst, dindex), src ); + } + + void copy_item( page& dst, size_t dindex, const page& src, size_t sindex, + item_constructor_t construct_item ) + { + T& src_item = get_ref( const_cast(src), sindex ); + construct_item( &get_ref(dst, dindex), static_cast(&src_item) ); + } + + void assign_and_destroy_item( void* dst, page& src, size_t index ) { + T& from = get_ref(src,index); + destroyer d(from); + *static_cast(dst) = tbb::internal::move( from ); + } + + void spin_wait_until_my_turn( atomic& counter, ticket k, concurrent_queue_rep_base& rb ) const ; + +public: + friend class micro_queue_pop_finalizer; + + struct padded_page: page { + //! Not defined anywhere - exists to quiet warnings. + padded_page(); + //! Not defined anywhere - exists to quiet warnings. + void operator=( const padded_page& ); + //! Must be last field. + T last; + }; + + static T& get_ref( page& p, size_t index ) { + return (&static_cast(static_cast(&p))->last)[index]; + } + + atomic head_page; + atomic head_counter; + + atomic tail_page; + atomic tail_counter; + + spin_mutex page_mutex; + + void push( const void* item, ticket k, concurrent_queue_base_v3& base, + item_constructor_t construct_item ) ; + + bool pop( void* dst, ticket k, concurrent_queue_base_v3& base ) ; + + micro_queue& assign( const micro_queue& src, concurrent_queue_base_v3& base, + item_constructor_t construct_item ) ; + + page* make_copy( concurrent_queue_base_v3& base, const page* src_page, size_t begin_in_page, + size_t end_in_page, ticket& g_index, item_constructor_t construct_item ) ; + + void invalidate_page_and_rethrow( ticket k ) ; +}; + +template +void micro_queue::spin_wait_until_my_turn( atomic& counter, ticket k, concurrent_queue_rep_base& rb ) const { + for( atomic_backoff b(true);;b.pause() ) { + ticket c = counter; + if( c==k ) return; + else if( c&1 ) { + ++rb.n_invalid_entries; + throw_exception( eid_bad_last_alloc ); + } + } +} + +template +void micro_queue::push( const void* item, ticket k, concurrent_queue_base_v3& base, + item_constructor_t construct_item ) +{ + k &= -concurrent_queue_rep_base::n_queue; + page* p = NULL; + size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page); + if( !index ) { + __TBB_TRY { + concurrent_queue_page_allocator& pa = base; + p = pa.allocate_page(); + } __TBB_CATCH (...) { + ++base.my_rep->n_invalid_entries; + invalidate_page_and_rethrow( k ); + } + p->mask = 0; + p->next = NULL; + } + + if( tail_counter != k ) spin_wait_until_my_turn( tail_counter, k, *base.my_rep ); + call_itt_notify(acquired, &tail_counter); + + if( p ) { + spin_mutex::scoped_lock lock( page_mutex ); + page* q = tail_page; + if( is_valid_page(q) ) + q->next = p; + else + head_page = p; + tail_page = p; + } else { + p = tail_page; + } + + __TBB_TRY { + copy_item( *p, index, item, construct_item ); + // If no exception was thrown, mark item as present. + itt_hide_store_word(p->mask, p->mask | uintptr_t(1)<n_invalid_entries; + call_itt_notify(releasing, &tail_counter); + tail_counter += concurrent_queue_rep_base::n_queue; + __TBB_RETHROW(); + } +} + +template +bool micro_queue::pop( void* dst, ticket k, concurrent_queue_base_v3& base ) { + k &= -concurrent_queue_rep_base::n_queue; + if( head_counter!=k ) spin_wait_until_eq( head_counter, k ); + call_itt_notify(acquired, &head_counter); + if( tail_counter==k ) spin_wait_while_eq( tail_counter, k ); + call_itt_notify(acquired, &tail_counter); + page *p = head_page; + __TBB_ASSERT( p, NULL ); + size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); + bool success = false; + { + micro_queue_pop_finalizer finalizer( *this, base, k+concurrent_queue_rep_base::n_queue, index==base.my_rep->items_per_page-1 ? p : NULL ); + if( p->mask & uintptr_t(1)<n_invalid_entries; + } + } + return success; +} + +template +micro_queue& micro_queue::assign( const micro_queue& src, concurrent_queue_base_v3& base, + item_constructor_t construct_item ) +{ + head_counter = src.head_counter; + tail_counter = src.tail_counter; + + const page* srcp = src.head_page; + if( is_valid_page(srcp) ) { + ticket g_index = head_counter; + __TBB_TRY { + size_t n_items = (tail_counter-head_counter)/concurrent_queue_rep_base::n_queue; + size_t index = modulo_power_of_two( head_counter/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); + size_t end_in_first_page = (index+n_itemsitems_per_page)?(index+n_items):base.my_rep->items_per_page; + + head_page = make_copy( base, srcp, index, end_in_first_page, g_index, construct_item ); + page* cur_page = head_page; + + if( srcp != src.tail_page ) { + for( srcp = srcp->next; srcp!=src.tail_page; srcp=srcp->next ) { + cur_page->next = make_copy( base, srcp, 0, base.my_rep->items_per_page, g_index, construct_item ); + cur_page = cur_page->next; + } + + __TBB_ASSERT( srcp==src.tail_page, NULL ); + size_t last_index = modulo_power_of_two( tail_counter/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page ); + if( last_index==0 ) last_index = base.my_rep->items_per_page; + + cur_page->next = make_copy( base, srcp, 0, last_index, g_index, construct_item ); + cur_page = cur_page->next; + } + tail_page = cur_page; + } __TBB_CATCH (...) { + invalidate_page_and_rethrow( g_index ); + } + } else { + head_page = tail_page = NULL; + } + return *this; +} + +template +void micro_queue::invalidate_page_and_rethrow( ticket k ) { + // Append an invalid page at address 1 so that no more pushes are allowed. + page* invalid_page = (page*)uintptr_t(1); + { + spin_mutex::scoped_lock lock( page_mutex ); + itt_store_word_with_release(tail_counter, k+concurrent_queue_rep_base::n_queue+1); + page* q = tail_page; + if( is_valid_page(q) ) + q->next = invalid_page; + else + head_page = invalid_page; + tail_page = invalid_page; + } + __TBB_RETHROW(); +} + +template +concurrent_queue_rep_base::page* micro_queue::make_copy( concurrent_queue_base_v3& base, + const concurrent_queue_rep_base::page* src_page, size_t begin_in_page, size_t end_in_page, + ticket& g_index, item_constructor_t construct_item ) +{ + concurrent_queue_page_allocator& pa = base; + page* new_page = pa.allocate_page(); + new_page->next = NULL; + new_page->mask = src_page->mask; + for( ; begin_in_page!=end_in_page; ++begin_in_page, ++g_index ) + if( new_page->mask & uintptr_t(1)< +class micro_queue_pop_finalizer: no_copy { + typedef concurrent_queue_rep_base::page page; + ticket my_ticket; + micro_queue& my_queue; + page* my_page; + concurrent_queue_page_allocator& allocator; +public: + micro_queue_pop_finalizer( micro_queue& queue, concurrent_queue_base_v3& b, ticket k, page* p ) : + my_ticket(k), my_queue(queue), my_page(p), allocator(b) + {} + ~micro_queue_pop_finalizer() ; +}; + +template +micro_queue_pop_finalizer::~micro_queue_pop_finalizer() { + page* p = my_page; + if( is_valid_page(p) ) { + spin_mutex::scoped_lock lock( my_queue.page_mutex ); + page* q = p->next; + my_queue.head_page = q; + if( !is_valid_page(q) ) { + my_queue.tail_page = NULL; + } + } + itt_store_word_with_release(my_queue.head_counter, my_ticket); + if( is_valid_page(p) ) { + allocator.deallocate_page( p ); + } +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) +#pragma warning( pop ) +#endif // warning 4146 is back + +template class concurrent_queue_iterator_rep ; +template class concurrent_queue_iterator_base_v3; + +//! representation of concurrent_queue_base +/** + * the class inherits from concurrent_queue_rep_base and defines an array of micro_queue's + */ +template +struct concurrent_queue_rep : public concurrent_queue_rep_base { + micro_queue array[n_queue]; + + //! Map ticket to an array index + static size_t index( ticket k ) { + return k*phi%n_queue; + } + + micro_queue& choose( ticket k ) { + // The formula here approximates LRU in a cache-oblivious way. + return array[index(k)]; + } +}; + +//! base class of concurrent_queue +/** + * The class implements the interface defined by concurrent_queue_page_allocator + * and has a pointer to an instance of concurrent_queue_rep. + */ +template +class concurrent_queue_base_v3: public concurrent_queue_page_allocator { +private: + //! Internal representation + concurrent_queue_rep* my_rep; + + friend struct concurrent_queue_rep; + friend class micro_queue; + friend class concurrent_queue_iterator_rep; + friend class concurrent_queue_iterator_base_v3; + +protected: + typedef typename concurrent_queue_rep::page page; + +private: + typedef typename micro_queue::padded_page padded_page; + typedef typename micro_queue::item_constructor_t item_constructor_t; + + virtual page *allocate_page() __TBB_override { + concurrent_queue_rep& r = *my_rep; + size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T); + return reinterpret_cast(allocate_block ( n )); + } + + virtual void deallocate_page( concurrent_queue_rep_base::page *p ) __TBB_override { + concurrent_queue_rep& r = *my_rep; + size_t n = sizeof(padded_page) + (r.items_per_page-1)*sizeof(T); + deallocate_block( reinterpret_cast(p), n ); + } + + //! custom allocator + virtual void *allocate_block( size_t n ) = 0; + + //! custom de-allocator + virtual void deallocate_block( void *p, size_t n ) = 0; + +protected: + concurrent_queue_base_v3(); + + virtual ~concurrent_queue_base_v3() { +#if TBB_USE_ASSERT + size_t nq = my_rep->n_queue; + for( size_t i=0; iarray[i].tail_page==NULL, "pages were not freed properly" ); +#endif /* TBB_USE_ASSERT */ + cache_aligned_allocator >().deallocate(my_rep,1); + } + + //! Enqueue item at tail of queue + void internal_push( const void* src, item_constructor_t construct_item ) { + concurrent_queue_rep& r = *my_rep; + ticket k = r.tail_counter++; + r.choose(k).push( src, k, *this, construct_item ); + } + + //! Attempt to dequeue item from queue. + /** NULL if there was no item to dequeue. */ + bool internal_try_pop( void* dst ) ; + + //! Get size of queue; result may be invalid if queue is modified concurrently + size_t internal_size() const ; + + //! check if the queue is empty; thread safe + bool internal_empty() const ; + + //! free any remaining pages + /* note that the name may be misleading, but it remains so due to a historical accident. */ + void internal_finish_clear() ; + + //! Obsolete + void internal_throw_exception() const { + throw_exception( eid_bad_alloc ); + } + + //! copy or move internal representation + void assign( const concurrent_queue_base_v3& src, item_constructor_t construct_item ) ; + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! swap internal representation + void internal_swap( concurrent_queue_base_v3& src ) { + std::swap( my_rep, src.my_rep ); + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +}; + +template +concurrent_queue_base_v3::concurrent_queue_base_v3() { + const size_t item_size = sizeof(T); + my_rep = cache_aligned_allocator >().allocate(1); + __TBB_ASSERT( (size_t)my_rep % NFS_GetLineSize()==0, "alignment error" ); + __TBB_ASSERT( (size_t)&my_rep->head_counter % NFS_GetLineSize()==0, "alignment error" ); + __TBB_ASSERT( (size_t)&my_rep->tail_counter % NFS_GetLineSize()==0, "alignment error" ); + __TBB_ASSERT( (size_t)&my_rep->array % NFS_GetLineSize()==0, "alignment error" ); + memset(static_cast(my_rep),0,sizeof(concurrent_queue_rep)); + my_rep->item_size = item_size; + my_rep->items_per_page = item_size<= 8 ? 32 : + item_size<= 16 ? 16 : + item_size<= 32 ? 8 : + item_size<= 64 ? 4 : + item_size<=128 ? 2 : + 1; +} + +template +bool concurrent_queue_base_v3::internal_try_pop( void* dst ) { + concurrent_queue_rep& r = *my_rep; + ticket k; + do { + k = r.head_counter; + for(;;) { + if( (ptrdiff_t)(r.tail_counter-k)<=0 ) { + // Queue is empty + return false; + } + // Queue had item with ticket k when we looked. Attempt to get that item. + ticket tk=k; +#if defined(_MSC_VER) && defined(_Wp64) + #pragma warning (push) + #pragma warning (disable: 4267) +#endif + k = r.head_counter.compare_and_swap( tk+1, tk ); +#if defined(_MSC_VER) && defined(_Wp64) + #pragma warning (pop) +#endif + if( k==tk ) + break; + // Another thread snatched the item, retry. + } + } while( !r.choose( k ).pop( dst, k, *this ) ); + return true; +} + +template +size_t concurrent_queue_base_v3::internal_size() const { + concurrent_queue_rep& r = *my_rep; + __TBB_ASSERT( sizeof(ptrdiff_t)<=sizeof(size_t), NULL ); + ticket hc = r.head_counter; + size_t nie = r.n_invalid_entries; + ticket tc = r.tail_counter; + __TBB_ASSERT( hc!=tc || !nie, NULL ); + ptrdiff_t sz = tc-hc-nie; + return sz<0 ? 0 : size_t(sz); +} + +template +bool concurrent_queue_base_v3::internal_empty() const { + concurrent_queue_rep& r = *my_rep; + ticket tc = r.tail_counter; + ticket hc = r.head_counter; + // if tc!=r.tail_counter, the queue was not empty at some point between the two reads. + return tc==r.tail_counter && tc==hc+r.n_invalid_entries ; +} + +template +void concurrent_queue_base_v3::internal_finish_clear() { + concurrent_queue_rep& r = *my_rep; + size_t nq = r.n_queue; + for( size_t i=0; i +void concurrent_queue_base_v3::assign( const concurrent_queue_base_v3& src, + item_constructor_t construct_item ) +{ + concurrent_queue_rep& r = *my_rep; + r.items_per_page = src.my_rep->items_per_page; + + // copy concurrent_queue_rep data + r.head_counter = src.my_rep->head_counter; + r.tail_counter = src.my_rep->tail_counter; + r.n_invalid_entries = src.my_rep->n_invalid_entries; + + // copy or move micro_queues + for( size_t i = 0; i < r.n_queue; ++i ) + r.array[i].assign( src.my_rep->array[i], *this, construct_item); + + __TBB_ASSERT( r.head_counter==src.my_rep->head_counter && r.tail_counter==src.my_rep->tail_counter, + "the source concurrent queue should not be concurrently modified." ); +} + +template class concurrent_queue_iterator; + +template +class concurrent_queue_iterator_rep: no_assign { + typedef typename micro_queue::padded_page padded_page; +public: + ticket head_counter; + const concurrent_queue_base_v3& my_queue; + typename concurrent_queue_base_v3::page* array[concurrent_queue_rep::n_queue]; + concurrent_queue_iterator_rep( const concurrent_queue_base_v3& queue ) : + head_counter(queue.my_rep->head_counter), + my_queue(queue) + { + for( size_t k=0; k::n_queue; ++k ) + array[k] = queue.my_rep->array[k].head_page; + } + + //! Set item to point to kth element. Return true if at end of queue or item is marked valid; false otherwise. + bool get_item( T*& item, size_t k ) ; +}; + +template +bool concurrent_queue_iterator_rep::get_item( T*& item, size_t k ) { + if( k==my_queue.my_rep->tail_counter ) { + item = NULL; + return true; + } else { + typename concurrent_queue_base_v3::page* p = array[concurrent_queue_rep::index(k)]; + __TBB_ASSERT(p,NULL); + size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, my_queue.my_rep->items_per_page ); + item = µ_queue::get_ref(*p,i); + return (p->mask & uintptr_t(1)< +class concurrent_queue_iterator_base_v3 { + //! Represents concurrent_queue over which we are iterating. + /** NULL if one past last element in queue. */ + concurrent_queue_iterator_rep* my_rep; + + template + friend bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); + + template + friend bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); +protected: + //! Pointer to current item + Value* my_item; + + //! Default constructor + concurrent_queue_iterator_base_v3() : my_rep(NULL), my_item(NULL) { +#if __TBB_GCC_OPTIMIZER_ORDERING_BROKEN + __TBB_compiler_fence(); +#endif + } + + //! Copy constructor + concurrent_queue_iterator_base_v3( const concurrent_queue_iterator_base_v3& i ) + : my_rep(NULL), my_item(NULL) { + assign(i); + } + + concurrent_queue_iterator_base_v3& operator=( const concurrent_queue_iterator_base_v3& i ) { + assign(i); + return *this; + } + + //! Construct iterator pointing to head of queue. + concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ) ; + + //! Assignment + void assign( const concurrent_queue_iterator_base_v3& other ) ; + + //! Advance iterator one step towards tail of queue. + void advance() ; + + //! Destructor + ~concurrent_queue_iterator_base_v3() { + cache_aligned_allocator >().deallocate(my_rep, 1); + my_rep = NULL; + } +}; + +template +concurrent_queue_iterator_base_v3::concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ) { + my_rep = cache_aligned_allocator >().allocate(1); + new( my_rep ) concurrent_queue_iterator_rep(queue); + size_t k = my_rep->head_counter; + if( !my_rep->get_item(my_item, k) ) advance(); +} + +template +void concurrent_queue_iterator_base_v3::assign( const concurrent_queue_iterator_base_v3& other ) { + if( my_rep!=other.my_rep ) { + if( my_rep ) { + cache_aligned_allocator >().deallocate(my_rep, 1); + my_rep = NULL; + } + if( other.my_rep ) { + my_rep = cache_aligned_allocator >().allocate(1); + new( my_rep ) concurrent_queue_iterator_rep( *other.my_rep ); + } + } + my_item = other.my_item; +} + +template +void concurrent_queue_iterator_base_v3::advance() { + __TBB_ASSERT( my_item, "attempt to increment iterator past end of queue" ); + size_t k = my_rep->head_counter; + const concurrent_queue_base_v3& queue = my_rep->my_queue; +#if TBB_USE_ASSERT + Value* tmp; + my_rep->get_item(tmp,k); + __TBB_ASSERT( my_item==tmp, NULL ); +#endif /* TBB_USE_ASSERT */ + size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, queue.my_rep->items_per_page ); + if( i==queue.my_rep->items_per_page-1 ) { + typename concurrent_queue_base_v3::page*& root = my_rep->array[concurrent_queue_rep::index(k)]; + root = root->next; + } + // advance k + my_rep->head_counter = ++k; + if( !my_rep->get_item(my_item, k) ) advance(); +} + +//! Similar to C++0x std::remove_cv +/** "tbb_" prefix added to avoid overload confusion with C++0x implementations. */ +template struct tbb_remove_cv {typedef T type;}; +template struct tbb_remove_cv {typedef T type;}; +template struct tbb_remove_cv {typedef T type;}; +template struct tbb_remove_cv {typedef T type;}; + +//! Meets requirements of a forward iterator for STL. +/** Value is either the T or const T type of the container. + @ingroup containers */ +template +class concurrent_queue_iterator: public concurrent_queue_iterator_base_v3::type>, + public std::iterator { +#if !__TBB_TEMPLATE_FRIENDS_BROKEN + template + friend class ::tbb::strict_ppl::concurrent_queue; +#else +public: +#endif + //! Construct iterator pointing to head of queue. + explicit concurrent_queue_iterator( const concurrent_queue_base_v3::type>& queue ) : + concurrent_queue_iterator_base_v3::type>(queue) + { + } + +public: + concurrent_queue_iterator() {} + + /** If Value==Container::value_type, then this routine is the copy constructor. + If Value==const Container::value_type, then this routine is a conversion constructor. */ + concurrent_queue_iterator( const concurrent_queue_iterator& other ) : + concurrent_queue_iterator_base_v3::type>(other) + {} + + //! Iterator assignment + concurrent_queue_iterator& operator=( const concurrent_queue_iterator& other ) { + concurrent_queue_iterator_base_v3::type>::operator=(other); + return *this; + } + + //! Reference to current item + Value& operator*() const { + return *static_cast(this->my_item); + } + + Value* operator->() const {return &operator*();} + + //! Advance to next item in queue + concurrent_queue_iterator& operator++() { + this->advance(); + return *this; + } + + //! Post increment + Value* operator++(int) { + Value* result = &operator*(); + operator++(); + return result; + } +}; // concurrent_queue_iterator + + +template +bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { + return i.my_item==j.my_item; +} + +template +bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { + return i.my_item!=j.my_item; +} + +} // namespace internal + +//! @endcond + +} // namespace strict_ppl + +//! @cond INTERNAL +namespace internal { + +class concurrent_queue_rep; +class concurrent_queue_iterator_rep; +class concurrent_queue_iterator_base_v3; +template class concurrent_queue_iterator; + +//! For internal use only. +/** Type-independent portion of concurrent_queue. + @ingroup containers */ +class concurrent_queue_base_v3: no_copy { +private: + //! Internal representation + concurrent_queue_rep* my_rep; + + friend class concurrent_queue_rep; + friend struct micro_queue; + friend class micro_queue_pop_finalizer; + friend class concurrent_queue_iterator_rep; + friend class concurrent_queue_iterator_base_v3; +protected: + //! Prefix on a page + struct page { + page* next; + uintptr_t mask; + }; + + //! Capacity of the queue + ptrdiff_t my_capacity; + + //! Always a power of 2 + size_t items_per_page; + + //! Size of an item + size_t item_size; + + enum copy_specifics { copy, move }; + +#if __TBB_PROTECTED_NESTED_CLASS_BROKEN +public: +#endif + template + struct padded_page: page { + //! Not defined anywhere - exists to quiet warnings. + padded_page(); + //! Not defined anywhere - exists to quiet warnings. + void operator=( const padded_page& ); + //! Must be last field. + T last; + }; + +private: + virtual void copy_item( page& dst, size_t index, const void* src ) = 0; + virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) = 0; +protected: + __TBB_EXPORTED_METHOD concurrent_queue_base_v3( size_t item_size ); + virtual __TBB_EXPORTED_METHOD ~concurrent_queue_base_v3(); + + //! Enqueue item at tail of queue using copy operation + void __TBB_EXPORTED_METHOD internal_push( const void* src ); + + //! Dequeue item from head of queue + void __TBB_EXPORTED_METHOD internal_pop( void* dst ); + + //! Abort all pending queue operations + void __TBB_EXPORTED_METHOD internal_abort(); + + //! Attempt to enqueue item onto queue using copy operation + bool __TBB_EXPORTED_METHOD internal_push_if_not_full( const void* src ); + + //! Attempt to dequeue item from queue. + /** NULL if there was no item to dequeue. */ + bool __TBB_EXPORTED_METHOD internal_pop_if_present( void* dst ); + + //! Get size of queue + ptrdiff_t __TBB_EXPORTED_METHOD internal_size() const; + + //! Check if the queue is empty + bool __TBB_EXPORTED_METHOD internal_empty() const; + + //! Set the queue capacity + void __TBB_EXPORTED_METHOD internal_set_capacity( ptrdiff_t capacity, size_t element_size ); + + //! custom allocator + virtual page *allocate_page() = 0; + + //! custom de-allocator + virtual void deallocate_page( page *p ) = 0; + + //! free any remaining pages + /* note that the name may be misleading, but it remains so due to a historical accident. */ + void __TBB_EXPORTED_METHOD internal_finish_clear() ; + + //! throw an exception + void __TBB_EXPORTED_METHOD internal_throw_exception() const; + + //! copy internal representation + void __TBB_EXPORTED_METHOD assign( const concurrent_queue_base_v3& src ) ; + +#if __TBB_CPP11_RVALUE_REF_PRESENT + //! swap queues + void internal_swap( concurrent_queue_base_v3& src ) { + std::swap( my_capacity, src.my_capacity ); + std::swap( items_per_page, src.items_per_page ); + std::swap( item_size, src.item_size ); + std::swap( my_rep, src.my_rep ); + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + //! Enqueues item at tail of queue using specified operation (copy or move) + void internal_insert_item( const void* src, copy_specifics op_type ); + + //! Attempts to enqueue at tail of queue using specified operation (copy or move) + bool internal_insert_if_not_full( const void* src, copy_specifics op_type ); + + //! Assigns one queue to another using specified operation (copy or move) + void internal_assign( const concurrent_queue_base_v3& src, copy_specifics op_type ); +private: + virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) = 0; +}; + +//! For internal use only. +/** Backward compatible modification of concurrent_queue_base_v3 + @ingroup containers */ +class concurrent_queue_base_v8: public concurrent_queue_base_v3 { +protected: + concurrent_queue_base_v8( size_t item_sz ) : concurrent_queue_base_v3( item_sz ) {} + + //! move items + void __TBB_EXPORTED_METHOD move_content( concurrent_queue_base_v8& src ) ; + + //! Attempt to enqueue item onto queue using move operation + bool __TBB_EXPORTED_METHOD internal_push_move_if_not_full( const void* src ); + + //! Enqueue item at tail of queue using move operation + void __TBB_EXPORTED_METHOD internal_push_move( const void* src ); +private: + friend struct micro_queue; + virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) = 0; + virtual void move_item( page& dst, size_t index, const void* src ) = 0; +}; + +//! Type-independent portion of concurrent_queue_iterator. +/** @ingroup containers */ +class concurrent_queue_iterator_base_v3 { + //! concurrent_queue over which we are iterating. + /** NULL if one past last element in queue. */ + concurrent_queue_iterator_rep* my_rep; + + template + friend bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); + + template + friend bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); + + void initialize( const concurrent_queue_base_v3& queue, size_t offset_of_data ); +protected: + //! Pointer to current item + void* my_item; + + //! Default constructor + concurrent_queue_iterator_base_v3() : my_rep(NULL), my_item(NULL) {} + + //! Copy constructor + concurrent_queue_iterator_base_v3( const concurrent_queue_iterator_base_v3& i ) : my_rep(NULL), my_item(NULL) { + assign(i); + } + + concurrent_queue_iterator_base_v3& operator=( const concurrent_queue_iterator_base_v3& i ) { + assign(i); + return *this; + } + + //! Obsolete entry point for constructing iterator pointing to head of queue. + /** Does not work correctly for SSE types. */ + __TBB_EXPORTED_METHOD concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue ); + + //! Construct iterator pointing to head of queue. + __TBB_EXPORTED_METHOD concurrent_queue_iterator_base_v3( const concurrent_queue_base_v3& queue, size_t offset_of_data ); + + //! Assignment + void __TBB_EXPORTED_METHOD assign( const concurrent_queue_iterator_base_v3& i ); + + //! Advance iterator one step towards tail of queue. + void __TBB_EXPORTED_METHOD advance(); + + //! Destructor + __TBB_EXPORTED_METHOD ~concurrent_queue_iterator_base_v3(); +}; + +typedef concurrent_queue_iterator_base_v3 concurrent_queue_iterator_base; + +//! Meets requirements of a forward iterator for STL. +/** Value is either the T or const T type of the container. + @ingroup containers */ +template +class concurrent_queue_iterator: public concurrent_queue_iterator_base, + public std::iterator { + +#if !__TBB_TEMPLATE_FRIENDS_BROKEN + template + friend class ::tbb::concurrent_bounded_queue; +#else +public: +#endif + + //! Construct iterator pointing to head of queue. + explicit concurrent_queue_iterator( const concurrent_queue_base_v3& queue ) : + concurrent_queue_iterator_base_v3(queue,__TBB_offsetof(concurrent_queue_base_v3::padded_page,last)) + { + } + +public: + concurrent_queue_iterator() {} + + /** If Value==Container::value_type, then this routine is the copy constructor. + If Value==const Container::value_type, then this routine is a conversion constructor. */ + concurrent_queue_iterator( const concurrent_queue_iterator& other ) : + concurrent_queue_iterator_base_v3(other) + {} + + //! Iterator assignment + concurrent_queue_iterator& operator=( const concurrent_queue_iterator& other ) { + concurrent_queue_iterator_base_v3::operator=(other); + return *this; + } + + //! Reference to current item + Value& operator*() const { + return *static_cast(my_item); + } + + Value* operator->() const {return &operator*();} + + //! Advance to next item in queue + concurrent_queue_iterator& operator++() { + advance(); + return *this; + } + + //! Post increment + Value* operator++(int) { + Value* result = &operator*(); + operator++(); + return result; + } +}; // concurrent_queue_iterator + + +template +bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { + return i.my_item==j.my_item; +} + +template +bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { + return i.my_item!=j.my_item; +} + +} // namespace internal; + +//! @endcond + +} // namespace tbb + +#endif /* __TBB__concurrent_queue_impl_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_skip_list_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_skip_list_impl.h new file mode 100644 index 00000000..8cc1a11d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_skip_list_impl.h @@ -0,0 +1,1085 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_skip_list_H +#define __TBB_concurrent_skip_list_H + +#if !defined(__TBB_concurrent_map_H) && !defined(__TBB_concurrent_set_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#include "../tbb_config.h" +#include "../tbb_stddef.h" +#include "../tbb_allocator.h" +#include "../spin_mutex.h" +#include "../tbb_exception.h" +#include "../enumerable_thread_specific.h" +#include "_allocator_traits.h" +#include "_template_helpers.h" +#include "_node_handle_impl.h" +#include // Need std::pair +#include +#include +#include // Need std::allocator_traits +#include +#include +#include +#include +#include +#include +#include +#include + +#if _MSC_VER +#pragma warning(disable: 4189) // warning 4189 -- local variable is initialized but not referenced +#pragma warning(disable: 4127) // warning 4127 -- while (true) has a constant expression in it +#endif + +namespace tbb { +namespace interface10 { +namespace internal { + +template +class skip_list_node { + +public: + using value_type = Value; + using size_type = std::size_t; + using reference = value_type & ; + using const_reference = const value_type & ; + using pointer = value_type * ; + using const_pointer = const value_type *; + using node_pointer = skip_list_node * ; + using atomic_node_pointer = std::atomic; + + using mutex_type = Mutex; + using lock_type = std::unique_lock; + + skip_list_node(size_type levels) : my_height(levels), my_fullyLinked(false) { + for (size_type lev = 0; lev < my_height; ++lev) + new(&my_next(lev)) atomic_node_pointer(nullptr); + __TBB_ASSERT(height() == levels, "Wrong node height"); + } + + ~skip_list_node() { + for(size_type lev = 0; lev < my_height; ++lev) + my_next(lev).~atomic(); + } + + skip_list_node(const skip_list_node&) = delete; + + skip_list_node(skip_list_node&&) = delete; + + skip_list_node& operator=(const skip_list_node&) = delete; + + pointer storage() { + return reinterpret_cast(&my_val); + } + + reference value() { + return *storage(); + } + + node_pointer next(size_type level) const { + __TBB_ASSERT(level < height(), "Cannot get next on the level greater than height"); + return my_next(level).load(std::memory_order_acquire); + } + + void set_next(size_type level, node_pointer next) { + __TBB_ASSERT(level < height(), "Cannot set next on the level greater than height"); + + my_next(level).store(next, std::memory_order_release); + } + + /** @return number of layers */ + size_type height() const { + return my_height; + } + + bool fully_linked() const { + return my_fullyLinked.load(std::memory_order_acquire); + } + + void mark_linked() { + my_fullyLinked.store(true, std::memory_order_release); + } + + lock_type acquire() { + return lock_type(my_mutex); + } + +private: + using aligned_storage_type = typename std::aligned_storage::type; + + atomic_node_pointer& my_next(size_type level) { + atomic_node_pointer* arr = reinterpret_cast(this + 1); + return arr[level]; + } + + const atomic_node_pointer& my_next(size_type level) const { + const atomic_node_pointer* arr = reinterpret_cast(this + 1); + return arr[level]; + } + + mutex_type my_mutex; + aligned_storage_type my_val; + size_type my_height; + std::atomic_bool my_fullyLinked; +}; + +template +class skip_list_iterator { + using node_type = NodeType; + using node_ptr = node_type*; +public: + using iterator_category = std::forward_iterator_tag; + using value_type = typename node_type::value_type; + using difference_type = std::ptrdiff_t; + using pointer = typename std::conditional::type; + using reference = typename std::conditional::type; + + skip_list_iterator() : my_node_ptr(nullptr) {} + + // TODO: the code above does not compile in VS2015 (seems like a bug) - consider enabling it for all other platforms + // template ::type> + // skip_list_iterator(const skip_list_iterator& other) : my_node_ptr(other.my_node_ptr) {} + + // skip_list_iterator(const skip_list_iterator& other) : my_node_ptr(other.my_node_ptr) {} + + skip_list_iterator(const skip_list_iterator& other) : my_node_ptr(other.my_node_ptr) {} + + skip_list_iterator& operator=(const skip_list_iterator& other) { + my_node_ptr = other.my_node_ptr; + return *this; + } + + template ::type> + skip_list_iterator(const skip_list_iterator& other) : my_node_ptr(other.my_node_ptr) {} + + reference operator*() const { return *(my_node_ptr->storage()); } + pointer operator->() const { return &**this; } + + skip_list_iterator& operator++() { + __TBB_ASSERT(my_node_ptr != nullptr, NULL); + my_node_ptr = my_node_ptr->next(0); + return *this; + } + + skip_list_iterator operator++(int) { + skip_list_iterator tmp = *this; + ++*this; + return tmp; + } + +private: + skip_list_iterator(node_type* n) : my_node_ptr(n) {} + + node_ptr my_node_ptr; + + template + friend class concurrent_skip_list; + + friend class skip_list_iterator; + + friend class const_range; + friend class range; + + template + friend bool operator==(const skip_list_iterator&, const skip_list_iterator&); + + template + friend bool operator!=(const skip_list_iterator&, const skip_list_iterator&); +}; + +template +bool operator==(const skip_list_iterator& lhs, const skip_list_iterator& rhs) { + return lhs.my_node_ptr == rhs.my_node_ptr; +} + +template +bool operator!=(const skip_list_iterator& lhs, const skip_list_iterator& rhs) { + return lhs.my_node_ptr != rhs.my_node_ptr; +} + +template +class concurrent_skip_list { +protected: + using traits_type = Traits; + using allocator_type = typename traits_type::allocator_type; + using allocator_traits_type = std::allocator_traits; + using key_compare = typename traits_type::compare_type; + using value_compare = typename traits_type::value_compare; + using key_type = typename traits_type::key_type; + using value_type = typename traits_type::value_type; + using node_type = typename traits_type::node_type; + using list_node_type = skip_list_node; + + using iterator = skip_list_iterator; + using const_iterator = skip_list_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + using reference = value_type&; + using const_reference = const value_type&; + using pointer = typename allocator_traits_type::pointer; + using const_pointer = typename allocator_traits_type::const_pointer; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using random_level_generator_type = typename traits_type::random_level_generator_type; + using node_allocator_type = typename std::allocator_traits::template rebind_alloc; + using node_allocator_traits = typename std::allocator_traits::template rebind_traits; + using node_ptr = list_node_type*; + + static constexpr size_type MAX_LEVEL = traits_type::MAX_LEVEL; + + using array_type = std::array; + using lock_array = std::array; + +public: + static bool const allow_multimapping = traits_type::allow_multimapping; + + /** + * Default constructor. Construct empty skip list. + */ + concurrent_skip_list() : my_size(0) { + create_dummy_head(); + } + + explicit concurrent_skip_list(const key_compare& comp, const allocator_type& alloc = allocator_type()) + : my_node_allocator(alloc), my_compare(comp), my_size(0) + { + create_dummy_head(); + } + + template + concurrent_skip_list(InputIt first, InputIt last, const key_compare& comp = key_compare(), + const allocator_type& alloc = allocator_type()) + : my_node_allocator(alloc), my_compare(comp), my_size(0) + { + create_dummy_head(); + internal_copy(first, last); + } + + /** Copy constructor */ + concurrent_skip_list(const concurrent_skip_list& other) + : my_node_allocator(node_allocator_traits::select_on_container_copy_construction(other.get_allocator())), + my_compare(other.my_compare), my_rnd_generator(other.my_rnd_generator), my_size(0) + { + create_dummy_head(); + internal_copy(other); + __TBB_ASSERT(my_size == other.my_size, "Wrong size of copy-constructed container"); + } + + concurrent_skip_list(const concurrent_skip_list& other, const allocator_type& alloc) + : my_node_allocator(alloc), my_compare(other.my_compare), + my_rnd_generator(other.my_rnd_generator), my_size(0) + { + create_dummy_head(); + internal_copy(other); + __TBB_ASSERT(my_size == other.my_size, "Wrong size of copy-constructed container"); + } + + concurrent_skip_list(concurrent_skip_list&& other) + : my_node_allocator(std::move(other.my_node_allocator)), my_compare(other.my_compare), + my_rnd_generator(other.my_rnd_generator) + { + internal_move(std::move(other)); + } + + concurrent_skip_list(concurrent_skip_list&& other, const allocator_type& alloc) + : my_node_allocator(alloc), my_compare(other.my_compare), + my_rnd_generator(other.my_rnd_generator) + { + if (alloc == other.get_allocator()) { + internal_move(std::move(other)); + } else { + my_size = 0; + create_dummy_head(); + internal_copy(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end())); + } + } + + ~concurrent_skip_list() { + clear(); + delete_dummy_head(); + } + + concurrent_skip_list& operator=(const concurrent_skip_list& other) { + if (this != &other) { + using pocca_type = typename node_allocator_traits::propagate_on_container_copy_assignment; + clear(); + tbb::internal::allocator_copy_assignment(my_node_allocator, other.my_node_allocator, pocca_type()); + my_compare = other.my_compare; + my_rnd_generator = other.my_rnd_generator; + internal_copy(other); + } + return *this; + } + + concurrent_skip_list& operator=(concurrent_skip_list&& other) { + if (this != &other) { + using pocma_type = typename node_allocator_traits::propagate_on_container_move_assignment; + clear(); + my_compare = other.my_compare; + my_rnd_generator = other.my_rnd_generator; + internal_move_assign(std::move(other), pocma_type()); + } + return *this; + } + + concurrent_skip_list& operator=(std::initializer_list il) + { + clear(); + insert(il.begin(),il.end()); + return *this; + } + + std::pair insert(const value_type& value) { + return internal_insert(value); + } + + std::pair insert(value_type&& value) { + return internal_insert(std::move(value)); + } + + iterator insert(const_iterator, const_reference value) { + // Ignore hint + return insert(value).first; + } + + iterator insert(const_iterator, value_type&& value) { + // Ignore hint + return insert(std::move(value)).first; + } + + template + void insert(InputIterator first, InputIterator last) { + for (InputIterator it = first; it != last; ++it) + insert(*it); + } + + void insert(std::initializer_list init) { + insert(init.begin(), init.end()); + } + + std::pair insert(node_type&& nh) { + if(!nh.empty()) { + std::pair insert_result = internal_insert_node(nh.my_node); + if(insert_result.second) { + nh.deactivate(); + } + return insert_result; + } + return std::pair(end(), false); + } + + iterator insert(const_iterator, node_type&& nh) { + // Ignore hint + return insert(std::move(nh)).first; + } + + template + std::pair emplace(Args&&... args) { + return internal_insert(std::forward(args)...); + } + + template + iterator emplace_hint(const_iterator, Args&&... args) { + // Ignore hint + return emplace(std::forward(args)...).first; + } + + iterator unsafe_erase(iterator pos) { + std::pair extract_result = internal_extract(pos); + if(extract_result.first) { // node was extracted + delete_node(extract_result.first); + return iterator(extract_result.second); + } + return end(); + } + + iterator unsafe_erase(const_iterator pos) { + return unsafe_erase(get_iterator(pos)); + } + + template , + typename = typename std::enable_if::value && + !std::is_convertible::value>::type> + size_type unsafe_erase(const K& key) { + std::pair range = equal_range(key); + size_type sz = std::distance(range.first, range.second); + unsafe_erase(range.first, range.second); + return sz; + } + + iterator unsafe_erase(const_iterator first, const_iterator last) { + while(first != last) { + first = unsafe_erase(get_iterator(first)); + } + return get_iterator(first); + } + + size_type unsafe_erase(const key_type& key) { + std::pair range = equal_range(key); + size_type sz = std::distance(range.first, range.second); + unsafe_erase(range.first, range.second); + return sz; + } + + node_type unsafe_extract(const_iterator pos) { + std::pair extract_result = internal_extract(pos); + return extract_result.first ? node_type(extract_result.first) : node_type(); + } + + node_type unsafe_extract(const key_type& key) { + return unsafe_extract(find(key)); + } + + iterator lower_bound(const key_type& key) { + return internal_get_bound(key, my_compare); + } + + const_iterator lower_bound(const key_type& key) const { + return internal_get_bound(key, my_compare); + } + + template > + iterator lower_bound(const K& key) { + return internal_get_bound(key, my_compare); + } + + template > + const_iterator lower_bound(const K& key) const { + return internal_get_bound(key, my_compare); + } + + iterator upper_bound(const key_type& key) { + return internal_get_bound(key, not_greater_compare(my_compare)); + } + + const_iterator upper_bound(const key_type& key) const { + return internal_get_bound(key, not_greater_compare(my_compare)); + } + + template > + iterator upper_bound(const K& key) { + return internal_get_bound(key, not_greater_compare(my_compare)); + } + + template > + const_iterator upper_bound(const K& key) const { + return internal_get_bound(key, not_greater_compare(my_compare)); + } + + iterator find(const key_type& key) { + return internal_find(key); + } + + const_iterator find(const key_type& key) const { + return internal_find(key); + } + + template > + iterator find(const K& key) { + return internal_find(key); + } + + template > + const_iterator find(const K& key) const { + return internal_find(key); + } + + size_type count( const key_type& key ) const { + return internal_count(key); + } + + template > + size_type count(const K& key) const { + return internal_count(key); + } + + bool contains(const key_type& key) const { + return find(key) != end(); + } + + template > + bool contains(const K& key) const { + return find(key) != end(); + } + + void clear() noexcept { + __TBB_ASSERT(dummy_head->height() > 0, NULL); + + node_ptr current = dummy_head->next(0); + while (current) { + __TBB_ASSERT(current->height() > 0, NULL); + node_ptr next = current->next(0); + delete_node(current); + current = next; + } + + my_size = 0; + for (size_type i = 0; i < dummy_head->height(); ++i) { + dummy_head->set_next(i, nullptr); + } + } + + iterator begin() { + return iterator(dummy_head->next(0)); + } + + const_iterator begin() const { + return const_iterator(dummy_head->next(0)); + } + + const_iterator cbegin() const { + return const_iterator(dummy_head->next(0)); + } + + iterator end() { + return iterator(nullptr); + } + + const_iterator end() const { + return const_iterator(nullptr); + } + + const_iterator cend() const { + return const_iterator(nullptr); + } + + size_type size() const { + return my_size.load(std::memory_order_relaxed); + } + + size_type max_size() const { + return my_node_allocator.max_size(); + } + + bool empty() const { + return 0 == size(); + } + + allocator_type get_allocator() const { + return my_node_allocator; + } + + void swap(concurrent_skip_list& other) { + using std::swap; + using pocs_type = typename node_allocator_traits::propagate_on_container_swap; + tbb::internal::allocator_swap(my_node_allocator, other.my_node_allocator, pocs_type()); + swap(my_compare, other.my_compare); + swap(my_rnd_generator, other.my_rnd_generator); + swap(dummy_head, other.dummy_head); + + size_type tmp = my_size; + my_size.store(other.my_size); + other.my_size.store(tmp); + } + + std::pair equal_range(const key_type& key) { + return std::pair(lower_bound(key), upper_bound(key)); + } + + std::pair equal_range(const key_type& key) const { + return std::pair(lower_bound(key), upper_bound(key)); + } + + template > + std::pair equal_range(const K& key) { + return std::pair(lower_bound(key), upper_bound(key)); + } + + template > + std::pair equal_range(const K& key) const { + return std::pair(lower_bound(key), upper_bound(key)); + } + + key_compare key_comp() const { return my_compare; } + + value_compare value_comp() const { return traits_type::value_comp(my_compare); } + + class const_range_type : tbb::internal::no_assign { + public: + using size_type = typename concurrent_skip_list::size_type; + using value_type = typename concurrent_skip_list::value_type; + using iterator = typename concurrent_skip_list::const_iterator; + private: + const_iterator my_end; + const_iterator my_begin; + size_type my_level; + + public: + + bool empty() const { + return my_begin.my_node_ptr->next(0) == my_end.my_node_ptr; + } + + bool is_divisible() const { + return my_level != 0 ? my_begin.my_node_ptr->next(my_level - 1) != my_end.my_node_ptr : false; + } + + size_type size() const { return std::distance(my_begin, my_end);} + + const_range_type( const_range_type& r, split) + : my_end(r.my_end) { + my_begin = iterator(r.my_begin.my_node_ptr->next(r.my_level - 1)); + my_level = my_begin.my_node_ptr->height(); + r.my_end = my_begin; + } + + const_range_type( const concurrent_skip_list& l) + : my_end(l.end()), my_begin(l.begin()), my_level(my_begin.my_node_ptr->height() ) {} + + iterator begin() const { return my_begin; } + iterator end() const { return my_end; } + size_t grainsize() const { return 1; } + + }; // class const_range_type + + class range_type : public const_range_type { + public: + using iterator = typename concurrent_skip_list::iterator; + + range_type(range_type& r, split) : const_range_type(r, split()) {} + range_type(const concurrent_skip_list& l) : const_range_type(l) {} + + iterator begin() const { + node_ptr node = const_range_type::begin().my_node_ptr; + return iterator(node); + } + + iterator end() const { + node_ptr node = const_range_type::end().my_node_ptr; + return iterator(node); } + }; // class range_type + + range_type range() { return range_type(*this); } + const_range_type range() const { return const_range_type(*this); } + +private: + void internal_move(concurrent_skip_list&& other) { + dummy_head = other.dummy_head; + other.dummy_head = nullptr; + other.create_dummy_head(); + + my_size = other.my_size.load(); + other.my_size = 0; + } + + static const key_type& get_key(node_ptr n) { + __TBB_ASSERT(n, NULL); + return traits_type::get_key(n->value()); + } + + template + iterator internal_find(const K& key) { + iterator it = lower_bound(key); + return (it == end() || my_compare(key, traits_type::get_key(*it))) ? end() : it; + } + + template + const_iterator internal_find(const K& key) const { + const_iterator it = lower_bound(key); + return (it == end() || my_compare(key, traits_type::get_key(*it))) ? end() : it; + } + + template + size_type internal_count( const K& key ) const { + if (allow_multimapping) { + std::pair range = equal_range(key); + return std::distance(range.first, range.second); + } + return (find(key) == end()) ? size_type(0) : size_type(1); + } + + /** + * Finds position on the @param level using @param cmp + * @param level - on which level search prev node + * @param prev - pointer to the start node to search + * @param key - key to search + * @param cmp - callable object to compare two objects + * (my_compare member is default comparator) + * @returns pointer to the node which is not satisfy the comparison with @param key + */ + template + pointer_type internal_find_position( size_type level, pointer_type& prev, const K& key, + const comparator& cmp) const { + __TBB_ASSERT(level < prev->height(), "Wrong level to find position"); + pointer_type curr = prev->next(level); + + while (curr && cmp(get_key(curr), key)) { + prev = curr; + __TBB_ASSERT(level < prev->height(), NULL); + curr = prev->next(level); + } + + return curr; + } + + template + void fill_prev_next_arrays(array_type& prev_nodes, array_type& next_nodes, node_ptr prev, const key_type& key, + const comparator& cmp) { + prev_nodes.fill(dummy_head); + next_nodes.fill(nullptr); + + for (size_type h = prev->height(); h > 0; --h) { + node_ptr next = internal_find_position(h - 1, prev, key, cmp); + prev_nodes[h - 1] = prev; + next_nodes[h - 1] = next; + } + } + + template + void fill_prev_next_by_ptr(array_type& prev_nodes, array_type& next_nodes, const_iterator it, const key_type& key, + const comparator& cmp) { + node_ptr prev = dummy_head; + node_ptr erase_node = it.my_node_ptr; + size_type node_height = erase_node->height(); + + for (size_type h = prev->height(); h >= node_height; --h) { + internal_find_position(h - 1, prev, key, cmp); + } + + for (size_type h = node_height; h > 0; --h) { + node_ptr curr = prev->next(h - 1); + while (const_iterator(curr) != it) { + prev = curr; + curr = prev->next(h - 1); + } + prev_nodes[h - 1] = prev; + } + + std::fill(next_nodes.begin(), next_nodes.begin() + node_height, erase_node); + } + + template + std::pair internal_insert(Args&&... args) { + node_ptr new_node = create_node(std::forward(args)...); + std::pair insert_result = internal_insert_node(new_node); + if(!insert_result.second) { + delete_node(new_node); + } + return insert_result; + } + + std::pair internal_insert_node(node_ptr new_node) { + array_type prev_nodes; + array_type next_nodes; + __TBB_ASSERT(dummy_head->height() >= new_node->height(), "Wrong height for new node"); + + do { + if (allow_multimapping) { + fill_prev_next_arrays(prev_nodes, next_nodes, dummy_head, get_key(new_node), + not_greater_compare(my_compare)); + } else { + fill_prev_next_arrays(prev_nodes, next_nodes, dummy_head, get_key(new_node), my_compare); + } + + node_ptr next = next_nodes[0]; + if (next && !allow_multimapping && !my_compare(get_key(new_node), get_key(next))) { + // TODO: do we really need to wait? + while (!next->fully_linked()) { + // TODO: atomic backoff + } + + return std::pair(iterator(next), false); + } + __TBB_ASSERT(allow_multimapping || !next || my_compare(get_key(new_node), get_key(next)), + "Wrong elements order"); + + } while (!try_insert_node(new_node, prev_nodes, next_nodes)); + + __TBB_ASSERT(new_node, NULL); + return std::pair(iterator(new_node), true); + } + + bool try_insert_node(node_ptr new_node, array_type& prev_nodes, array_type& next_nodes) { + __TBB_ASSERT(dummy_head->height() >= new_node->height(), NULL); + + lock_array locks; + + if (!try_lock_nodes(new_node->height(), prev_nodes, next_nodes, locks)) { + return false; + } + + __TBB_ASSERT(allow_multimapping || + ((prev_nodes[0] == dummy_head || + my_compare(get_key(prev_nodes[0]), get_key(new_node))) && + (next_nodes[0] == nullptr || my_compare(get_key(new_node), get_key(next_nodes[0])))), + "Wrong elements order"); + + for (size_type level = 0; level < new_node->height(); ++level) { + __TBB_ASSERT(prev_nodes[level]->height() > level, NULL); + __TBB_ASSERT(prev_nodes[level]->next(level) == next_nodes[level], NULL); + new_node->set_next(level, next_nodes[level]); + prev_nodes[level]->set_next(level, new_node); + } + new_node->mark_linked(); + + ++my_size; + + return true; + } + + bool try_lock_nodes(size_type height, array_type& prevs, array_type& next_nodes, lock_array& locks) { + for (size_type l = 0; l < height; ++l) { + if (l == 0 || prevs[l] != prevs[l - 1]) + locks[l] = prevs[l]->acquire(); + + node_ptr next = prevs[l]->next(l); + if ( next != next_nodes[l]) return false; + } + + return true; + } + + template + const_iterator internal_get_bound(const K& key, const comparator& cmp) const { + node_ptr prev = dummy_head; + __TBB_ASSERT(dummy_head->height() > 0, NULL); + node_ptr next = nullptr; + + for (size_type h = prev->height(); h > 0; --h) { + next = internal_find_position(h - 1, prev, key, cmp); + } + + return const_iterator(next); + } + + template + iterator internal_get_bound(const K& key, const comparator& cmp){ + node_ptr prev = dummy_head; + __TBB_ASSERT(dummy_head->height() > 0, NULL); + node_ptr next = nullptr; + + for (size_type h = prev->height(); h > 0; --h) { + next = internal_find_position(h - 1, prev, key, cmp); + } + + return iterator(next); + } + + // Returns node_ptr to the extracted node and node_ptr to the next node after the extracted + std::pair internal_extract(const_iterator it) { + if ( it != end() ) { + key_type key = traits_type::get_key(*it); + __TBB_ASSERT(dummy_head->height() > 0, NULL); + + array_type prev_nodes; + array_type next_nodes; + + fill_prev_next_by_ptr(prev_nodes, next_nodes, it, key, my_compare); + + node_ptr erase_node = next_nodes[0]; + __TBB_ASSERT(erase_node != nullptr, NULL); + node_ptr next_node = erase_node->next(0); + + if (!my_compare(key, get_key(erase_node))) { + for(size_type level = 0; level < erase_node->height(); ++level) { + __TBB_ASSERT(prev_nodes[level]->height() > level, NULL); + __TBB_ASSERT(next_nodes[level] == erase_node, NULL); + prev_nodes[level]->set_next(level, erase_node->next(level)); + } + --my_size; + return std::pair(erase_node, next_node); + } + } + return std::pair(nullptr, nullptr); + } + +protected: + template + void internal_merge(SourceType&& source) { + using source_type = typename std::decay::type; + using source_iterator = typename source_type::iterator; + __TBB_STATIC_ASSERT((std::is_same::value), "Incompatible containers cannot be merged"); + + for(source_iterator it = source.begin(); it != source.end();) { + source_iterator where = it++; + if (allow_multimapping || !contains(traits_type::get_key(*where))) { + std::pair extract_result = source.internal_extract(where); + + //If the insertion fails - return the node into source + node_type handle(extract_result.first); + __TBB_ASSERT(!handle.empty(), "Extracted handle in merge is empty"); + + if (!insert(std::move(handle)).second) { + source.insert(std::move(handle)); + } + handle.deactivate(); + } + } + } + +private: + void internal_copy(const concurrent_skip_list& other) { + internal_copy(other.begin(), other.end()); + } + + template + void internal_copy(Iterator first, Iterator last) { + clear(); + try { + for (auto it = first; it != last; ++it) + insert(*it); + } + catch (...) { + clear(); + delete_dummy_head(); + throw; + } + } + + /** Generate random level */ + size_type random_level() { + return my_rnd_generator(); + } + + static size_type calc_node_size(size_type height) { + return sizeof(list_node_type) + height*sizeof(typename list_node_type::atomic_node_pointer); + } + + /** Creates new node */ + template + node_ptr create_node(Args&&... args) { + size_type levels = random_level(); + + size_type sz = calc_node_size(levels); + + node_ptr node = reinterpret_cast(node_allocator_traits::allocate(my_node_allocator, sz)); + + try { + node_allocator_traits::construct(my_node_allocator, node, levels); + + } + catch(...) { + deallocate_node(node, sz); + throw; + } + + try { + node_allocator_traits::construct(my_node_allocator, node->storage(), std::forward(args)...); + } + catch (...) { + node_allocator_traits::destroy(my_node_allocator, node); + deallocate_node(node, sz); + throw; + } + + return node; + } + + void create_dummy_head() { + size_type sz = calc_node_size(MAX_LEVEL); + + dummy_head = reinterpret_cast(node_allocator_traits::allocate(my_node_allocator, sz)); + // TODO: investigate linkage fail in debug without this workaround + auto max_level = MAX_LEVEL; + + try { + node_allocator_traits::construct(my_node_allocator, dummy_head, max_level); + } + catch(...) { + deallocate_node(dummy_head, sz); + throw; + } + } + + template + void delete_node(node_ptr node) { + size_type sz = calc_node_size(node->height()); + // Destroy value + if (!is_dummy) node_allocator_traits::destroy(my_node_allocator, node->storage()); + // Destroy node + node_allocator_traits::destroy(my_node_allocator, node); + // Deallocate memory + deallocate_node(node, sz); + } + + void deallocate_node(node_ptr node, size_type sz) { + node_allocator_traits::deallocate(my_node_allocator, reinterpret_cast(node), sz); + } + + void delete_dummy_head() { + delete_node(dummy_head); + } + + static iterator get_iterator(const_iterator it) { + return iterator(it.my_node_ptr); + } + + void internal_move_assign(concurrent_skip_list&& other, /*POCMA=*/std::true_type) { + delete_dummy_head(); + tbb::internal::allocator_move_assignment(my_node_allocator, other.my_node_allocator, std::true_type()); + internal_move(std::move(other)); + } + + void internal_move_assign(concurrent_skip_list&& other, /*POCMA=*/std::false_type) { + if (my_node_allocator == other.my_node_allocator) { + delete_dummy_head(); + internal_move(std::move(other)); + } else { + internal_copy(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end())); + } + } + + struct not_greater_compare { + const key_compare& my_less_compare; + + not_greater_compare(const key_compare& less_compare) : my_less_compare(less_compare) {} + + template + bool operator()(const K1& first, const K2& second) const { + return !my_less_compare(second, first); + } + }; + + node_allocator_type my_node_allocator; + key_compare my_compare; + random_level_generator_type my_rnd_generator; + node_ptr dummy_head; + + template + friend class concurrent_skip_list; + + std::atomic my_size; +}; // class concurrent_skip_list + +template +class concurrent_geometric_level_generator { +public: + static constexpr size_t max_level = MAX_LEVEL; + + concurrent_geometric_level_generator() : engines(time(NULL)) {} + + size_t operator()() { + return (distribution(engines.local()) % MAX_LEVEL) + 1; + } + +private: + tbb::enumerable_thread_specific engines; + std::geometric_distribution distribution; +}; + +} // namespace internal +} // namespace interface10 +} // namespace tbb + +#endif // __TBB_concurrent_skip_list_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_unordered_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_unordered_impl.h new file mode 100644 index 00000000..b4bbefa5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_concurrent_unordered_impl.h @@ -0,0 +1,1684 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* Container implementations in this header are based on PPL implementations + provided by Microsoft. */ + +#ifndef __TBB__concurrent_unordered_impl_H +#define __TBB__concurrent_unordered_impl_H +#if !defined(__TBB_concurrent_unordered_map_H) && !defined(__TBB_concurrent_unordered_set_H) && !defined(__TBB_concurrent_hash_map_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#include "../tbb_stddef.h" + +#include +#include // Need std::pair +#include // Need std::equal_to (in ../concurrent_unordered_*.h) +#include // For tbb_hasher +#include // Need std::memset +#include __TBB_STD_SWAP_HEADER + +#include "../atomic.h" +#include "../tbb_exception.h" +#include "../tbb_allocator.h" + +#if __TBB_INITIALIZER_LISTS_PRESENT + #include +#endif + +#if __TBB_CPP11_RVALUE_REF_PRESENT && !__TBB_IMPLICIT_COPY_DELETION_BROKEN + #define __TBB_UNORDERED_NODE_HANDLE_PRESENT 1 +#endif + +#include "_allocator_traits.h" +#include "_tbb_hash_compare_impl.h" +#include "_template_helpers.h" + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT +#include "_node_handle_impl.h" +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + +namespace tbb { +namespace interface5 { +//! @cond INTERNAL +namespace internal { + +template +class split_ordered_list; +template +class concurrent_unordered_base; + +// Forward list iterators (without skipping dummy elements) +template +class flist_iterator : public std::iterator +{ + template + friend class split_ordered_list; + template + friend class concurrent_unordered_base; + template + friend class flist_iterator; + + typedef typename Solist::nodeptr_t nodeptr_t; +public: + typedef typename Solist::value_type value_type; + typedef typename Solist::difference_type difference_type; + typedef typename Solist::pointer pointer; + typedef typename Solist::reference reference; + + flist_iterator() : my_node_ptr(0) {} + flist_iterator( const flist_iterator &other ) + : my_node_ptr(other.my_node_ptr) {} + + flist_iterator& operator=( const flist_iterator &other ) { + my_node_ptr = other.my_node_ptr; + return *this; + } + + reference operator*() const { return my_node_ptr->my_element; } + pointer operator->() const { return &**this; } + + flist_iterator& operator++() { + my_node_ptr = my_node_ptr->my_next; + return *this; + } + + flist_iterator operator++(int) { + flist_iterator tmp = *this; + ++*this; + return tmp; + } + +protected: + flist_iterator(nodeptr_t pnode) : my_node_ptr(pnode) {} + nodeptr_t get_node_ptr() const { return my_node_ptr; } + + nodeptr_t my_node_ptr; + + template + friend bool operator==( const flist_iterator &i, const flist_iterator &j ); + template + friend bool operator!=( const flist_iterator& i, const flist_iterator& j ); +}; + +template +bool operator==( const flist_iterator &i, const flist_iterator &j ) { + return i.my_node_ptr == j.my_node_ptr; +} +template +bool operator!=( const flist_iterator& i, const flist_iterator& j ) { + return i.my_node_ptr != j.my_node_ptr; +} + +// Split-order list iterators, needed to skip dummy elements +template +class solist_iterator : public flist_iterator +{ + typedef flist_iterator base_type; + typedef typename Solist::nodeptr_t nodeptr_t; + using base_type::get_node_ptr; + template + friend class split_ordered_list; + template + friend class solist_iterator; + template + friend class concurrent_unordered_base; + template + friend bool operator==( const solist_iterator &i, const solist_iterator &j ); + template + friend bool operator!=( const solist_iterator& i, const solist_iterator& j ); + + const Solist *my_list_ptr; + solist_iterator(nodeptr_t pnode, const Solist *plist) : base_type(pnode), my_list_ptr(plist) {} + +public: + typedef typename Solist::value_type value_type; + typedef typename Solist::difference_type difference_type; + typedef typename Solist::pointer pointer; + typedef typename Solist::reference reference; + + solist_iterator() {} + solist_iterator( const solist_iterator &other ) + : base_type(other), my_list_ptr(other.my_list_ptr) {} + + solist_iterator& operator=( const solist_iterator &other ) { + base_type::my_node_ptr = other.get_node_ptr(); + my_list_ptr = other.my_list_ptr; + return *this; + } + + reference operator*() const { + return this->base_type::operator*(); + } + + pointer operator->() const { + return (&**this); + } + + solist_iterator& operator++() { + do ++(*(base_type *)this); + while (get_node_ptr() != NULL && get_node_ptr()->is_dummy()); + + return (*this); + } + + solist_iterator operator++(int) { + solist_iterator tmp = *this; + do ++*this; + while (get_node_ptr() != NULL && get_node_ptr()->is_dummy()); + + return (tmp); + } +}; + +template +bool operator==( const solist_iterator &i, const solist_iterator &j ) { + return i.my_node_ptr == j.my_node_ptr && i.my_list_ptr == j.my_list_ptr; +} +template +bool operator!=( const solist_iterator& i, const solist_iterator& j ) { + return i.my_node_ptr != j.my_node_ptr || i.my_list_ptr != j.my_list_ptr; +} + +// Forward type and class definitions +typedef size_t sokey_t; + + +// Forward list in which elements are sorted in a split-order +template +class split_ordered_list +{ +public: + typedef split_ordered_list self_type; + + typedef typename tbb::internal::allocator_rebind::type allocator_type; + + struct node; + typedef node *nodeptr_t; + + typedef typename tbb::internal::allocator_traits::value_type value_type; + typedef typename tbb::internal::allocator_traits::size_type size_type; + typedef typename tbb::internal::allocator_traits::difference_type difference_type; + typedef typename tbb::internal::allocator_traits::pointer pointer; + typedef typename tbb::internal::allocator_traits::const_pointer const_pointer; + // No support for reference/const_reference in allocator traits + typedef value_type& reference; + typedef const value_type& const_reference; + + typedef solist_iterator const_iterator; + typedef solist_iterator iterator; + typedef flist_iterator raw_const_iterator; + typedef flist_iterator raw_iterator; + + // Node that holds the element in a split-ordered list + struct node : tbb::internal::no_assign + { + private: + // for compilers that try to generate default constructors though they are not needed. + node(); // VS 2008, 2010, 2012 + public: + // Initialize the node with the given order key + void init(sokey_t order_key) { + my_order_key = order_key; + my_next = NULL; + } + + // Return the order key (needed for hashing) + sokey_t get_order_key() const { // TODO: remove + return my_order_key; + } + + // get() and value() is a common interface for getting access to node`s element (required by node_handle) + value_type* storage() { + return reinterpret_cast(&my_element); + } + + value_type& value() { + return *storage(); + } + + // Inserts the new element in the list in an atomic fashion + nodeptr_t atomic_set_next(nodeptr_t new_node, nodeptr_t current_node) + { + // Try to change the next pointer on the current element to a new element, only if it still points to the cached next + nodeptr_t exchange_node = tbb::internal::as_atomic(my_next).compare_and_swap(new_node, current_node); + + if (exchange_node == current_node) // TODO: why this branch? + { + // Operation succeeded, return the new node + return new_node; + } + else + { + // Operation failed, return the "interfering" node + return exchange_node; + } + } + + // Checks if this element in the list is a dummy, order enforcing node. Dummy nodes are used by buckets + // in the hash table to quickly index into the right subsection of the split-ordered list. + bool is_dummy() const { + return (my_order_key & 0x1) == 0; + } + + + nodeptr_t my_next; // Next element in the list + value_type my_element; // Element storage + sokey_t my_order_key; // Order key for this element + }; + + // Allocate a new node with the given order key; used to allocate dummy nodes + nodeptr_t create_node(sokey_t order_key) { + nodeptr_t pnode = my_node_allocator.allocate(1); + pnode->init(order_key); + return (pnode); + } + + // Allocate a new node with the given order key and value + template + nodeptr_t create_node(sokey_t order_key, __TBB_FORWARDING_REF(Arg) t, + /*AllowCreate=*/tbb::internal::true_type=tbb::internal::true_type()){ + nodeptr_t pnode = my_node_allocator.allocate(1); + + //TODO: use RAII scoped guard instead of explicit catch + __TBB_TRY { + new(static_cast(&pnode->my_element)) T(tbb::internal::forward(t)); + pnode->init(order_key); + } __TBB_CATCH(...) { + my_node_allocator.deallocate(pnode, 1); + __TBB_RETHROW(); + } + + return (pnode); + } + + // A helper to avoid excessive requiremens in internal_insert + template + nodeptr_t create_node(sokey_t, __TBB_FORWARDING_REF(Arg), + /*AllowCreate=*/tbb::internal::false_type){ + __TBB_ASSERT(false, "This compile-time helper should never get called"); + return nodeptr_t(); + } + + // Allocate a new node with the given parameters for constructing value + template + nodeptr_t create_node_v( __TBB_FORWARDING_REF(Args) __TBB_PARAMETER_PACK args){ + nodeptr_t pnode = my_node_allocator.allocate(1); + + //TODO: use RAII scoped guard instead of explicit catch + __TBB_TRY { + new(static_cast(&pnode->my_element)) T(__TBB_PACK_EXPANSION(tbb::internal::forward(args))); + } __TBB_CATCH(...) { + my_node_allocator.deallocate(pnode, 1); + __TBB_RETHROW(); + } + + return (pnode); + } + + split_ordered_list(allocator_type a = allocator_type()) + : my_node_allocator(a), my_element_count(0) + { + // Immediately allocate a dummy node with order key of 0. This node + // will always be the head of the list. + my_head = create_node(sokey_t(0)); + } + + ~split_ordered_list() + { + // Clear the list + clear(); + + // Remove the head element which is not cleared by clear() + nodeptr_t pnode = my_head; + my_head = NULL; + + __TBB_ASSERT(pnode != NULL && pnode->my_next == NULL, "Invalid head list node"); + + destroy_node(pnode); + } + + // Common forward list functions + + allocator_type get_allocator() const { + return (my_node_allocator); + } + + void clear() { + nodeptr_t pnext; + nodeptr_t pnode = my_head; + + __TBB_ASSERT(my_head != NULL, "Invalid head list node"); + pnext = pnode->my_next; + pnode->my_next = NULL; + pnode = pnext; + + while (pnode != NULL) + { + pnext = pnode->my_next; + destroy_node(pnode); + pnode = pnext; + } + + my_element_count = 0; + } + + // Returns a first non-dummy element in the SOL + iterator begin() { + return first_real_iterator(raw_begin()); + } + + // Returns a first non-dummy element in the SOL + const_iterator begin() const { + return first_real_iterator(raw_begin()); + } + + iterator end() { + return (iterator(0, this)); + } + + const_iterator end() const { + return (const_iterator(0, this)); + } + + const_iterator cbegin() const { + return (((const self_type *)this)->begin()); + } + + const_iterator cend() const { + return (((const self_type *)this)->end()); + } + + // Checks if the number of elements (non-dummy) is 0 + bool empty() const { + return (my_element_count == 0); + } + + // Returns the number of non-dummy elements in the list + size_type size() const { + return my_element_count; + } + + // Returns the maximum size of the list, determined by the allocator + size_type max_size() const { + return my_node_allocator.max_size(); + } + + // Swaps 'this' list with the passed in one + void swap(self_type& other) + { + if (this == &other) + { + // Nothing to do + return; + } + + std::swap(my_element_count, other.my_element_count); + std::swap(my_head, other.my_head); + } + + // Split-order list functions + + // Returns a first element in the SOL, which is always a dummy + raw_iterator raw_begin() { + return raw_iterator(my_head); + } + + // Returns a first element in the SOL, which is always a dummy + raw_const_iterator raw_begin() const { + return raw_const_iterator(my_head); + } + + raw_iterator raw_end() { + return raw_iterator(0); + } + + raw_const_iterator raw_end() const { + return raw_const_iterator(0); + } + + static sokey_t get_order_key(const raw_const_iterator& it) { + return it.get_node_ptr()->get_order_key(); + } + + static sokey_t get_safe_order_key(const raw_const_iterator& it) { + if( !it.get_node_ptr() ) return ~sokey_t(0); + return it.get_node_ptr()->get_order_key(); + } + + // Returns a public iterator version of the internal iterator. Public iterator must not + // be a dummy private iterator. + iterator get_iterator(raw_iterator it) { + __TBB_ASSERT(it.get_node_ptr() == NULL || !it.get_node_ptr()->is_dummy(), "Invalid user node (dummy)"); + return iterator(it.get_node_ptr(), this); + } + + // Returns a public iterator version of the internal iterator. Public iterator must not + // be a dummy private iterator. + const_iterator get_iterator(raw_const_iterator it) const { + __TBB_ASSERT(it.get_node_ptr() == NULL || !it.get_node_ptr()->is_dummy(), "Invalid user node (dummy)"); + return const_iterator(it.get_node_ptr(), this); + } + + // Returns a non-const version of the raw_iterator + raw_iterator get_iterator(raw_const_iterator it) { + return raw_iterator(it.get_node_ptr()); + } + + // Returns a non-const version of the iterator + static iterator get_iterator(const_iterator it) { + return iterator(it.my_node_ptr, it.my_list_ptr); + } + + // Returns a public iterator version of a first non-dummy internal iterator at or after + // the passed in internal iterator. + iterator first_real_iterator(raw_iterator it) + { + // Skip all dummy, internal only iterators + while (it != raw_end() && it.get_node_ptr()->is_dummy()) + ++it; + + return iterator(it.get_node_ptr(), this); + } + + // Returns a public iterator version of a first non-dummy internal iterator at or after + // the passed in internal iterator. + const_iterator first_real_iterator(raw_const_iterator it) const + { + // Skip all dummy, internal only iterators + while (it != raw_end() && it.get_node_ptr()->is_dummy()) + ++it; + + return const_iterator(it.get_node_ptr(), this); + } + + // Erase an element using the allocator + void destroy_node(nodeptr_t pnode) { + if (!pnode->is_dummy()) my_node_allocator.destroy(pnode); + my_node_allocator.deallocate(pnode, 1); + } + + // Try to insert a new element in the list. + // If insert fails, return the node that was inserted instead. + static nodeptr_t try_insert_atomic(nodeptr_t previous, nodeptr_t new_node, nodeptr_t current_node) { + new_node->my_next = current_node; + return previous->atomic_set_next(new_node, current_node); + } + + // Insert a new element between passed in iterators + std::pair try_insert(raw_iterator it, raw_iterator next, nodeptr_t pnode, size_type *new_count) + { + nodeptr_t inserted_node = try_insert_atomic(it.get_node_ptr(), pnode, next.get_node_ptr()); + + if (inserted_node == pnode) + { + // If the insert succeeded, check that the order is correct and increment the element count + check_range(it, next); + *new_count = tbb::internal::as_atomic(my_element_count).fetch_and_increment(); + return std::pair(iterator(pnode, this), true); + } + else + { + return std::pair(end(), false); + } + } + + // Insert a new dummy element, starting search at a parent dummy element + raw_iterator insert_dummy(raw_iterator it, sokey_t order_key) + { + raw_iterator last = raw_end(); + raw_iterator where = it; + + __TBB_ASSERT(where != last, "Invalid head node"); + + ++where; + + // Create a dummy element up front, even though it may be discarded (due to concurrent insertion) + nodeptr_t dummy_node = create_node(order_key); + + for (;;) + { + __TBB_ASSERT(it != last, "Invalid head list node"); + + // If the head iterator is at the end of the list, or past the point where this dummy + // node needs to be inserted, then try to insert it. + if (where == last || get_order_key(where) > order_key) + { + __TBB_ASSERT(get_order_key(it) < order_key, "Invalid node order in the list"); + + // Try to insert it in the right place + nodeptr_t inserted_node = try_insert_atomic(it.get_node_ptr(), dummy_node, where.get_node_ptr()); + + if (inserted_node == dummy_node) + { + // Insertion succeeded, check the list for order violations + check_range(it, where); + return raw_iterator(dummy_node); + } + else + { + // Insertion failed: either dummy node was inserted by another thread, or + // a real element was inserted at exactly the same place as dummy node. + // Proceed with the search from the previous location where order key was + // known to be larger (note: this is legal only because there is no safe + // concurrent erase operation supported). + where = it; + ++where; + continue; + } + } + else if (get_order_key(where) == order_key) + { + // Another dummy node with the same value found, discard the new one. + destroy_node(dummy_node); + return where; + } + + // Move the iterator forward + it = where; + ++where; + } + + } + + nodeptr_t erase_node_impl(raw_iterator previous, raw_const_iterator& where) { + nodeptr_t pnode = (where++).get_node_ptr(); + nodeptr_t prevnode = previous.get_node_ptr(); + __TBB_ASSERT(prevnode->my_next == pnode, "Erase must take consecutive iterators"); + prevnode->my_next = pnode->my_next; + return pnode; + } + + // This erase function can handle both real and dummy nodes + void erase_node(raw_iterator previous, raw_const_iterator& where, + /*allow_destroy*/tbb::internal::true_type) + { + nodeptr_t pnode = erase_node_impl(previous, where); + destroy_node(pnode); + } + + void erase_node(raw_iterator previous, raw_const_iterator& where, + /*allow_destroy*/tbb::internal::false_type) + { + erase_node_impl(previous, where); + } + + void erase_node(raw_iterator previous, raw_const_iterator& where) { + erase_node(previous, where, /*allow_destroy*/tbb::internal::true_type()); + } + + // Erase the element (previous node needs to be passed because this is a forward only list) + template + iterator erase_node(raw_iterator previous, const_iterator where, AllowDestroy) + { + raw_const_iterator it = where; + erase_node(previous, it, AllowDestroy()); + my_element_count--; + + return get_iterator(first_real_iterator(it)); + } + + iterator erase_node(raw_iterator previous, const_iterator& where) { + return erase_node(previous, where, /*allow_destroy*/tbb::internal::true_type()); + } + + + + // Move all elements from the passed in split-ordered list to this one + void move_all(self_type& source) + { + raw_const_iterator first = source.raw_begin(); + raw_const_iterator last = source.raw_end(); + + if (first == last) + return; + + nodeptr_t previous_node = my_head; + raw_const_iterator begin_iterator = first++; + + // Move all elements one by one, including dummy ones + for (raw_const_iterator it = first; it != last;) + { + nodeptr_t pnode = it.get_node_ptr(); + + nodeptr_t dummy_node = pnode->is_dummy() ? create_node(pnode->get_order_key()) : create_node(pnode->get_order_key(), pnode->my_element); + previous_node = try_insert_atomic(previous_node, dummy_node, NULL); + __TBB_ASSERT(previous_node != NULL, "Insertion must succeed"); + raw_const_iterator where = it++; + source.erase_node(get_iterator(begin_iterator), where); + } + check_range(); + } + + +private: + //Need to setup private fields of split_ordered_list in move constructor and assignment of concurrent_unordered_base + template + friend class concurrent_unordered_base; + + // Check the list for order violations + void check_range( raw_iterator first, raw_iterator last ) + { +#if TBB_USE_ASSERT + for (raw_iterator it = first; it != last; ++it) + { + raw_iterator next = it; + ++next; + + __TBB_ASSERT(next == raw_end() || get_order_key(next) >= get_order_key(it), "!!! List order inconsistency !!!"); + } +#else + tbb::internal::suppress_unused_warning(first, last); +#endif + } + void check_range() + { +#if TBB_USE_ASSERT + check_range( raw_begin(), raw_end() ); +#endif + } + + typename tbb::internal::allocator_rebind::type my_node_allocator; // allocator object for nodes + size_type my_element_count; // Total item count, not counting dummy nodes + nodeptr_t my_head; // pointer to head node +}; + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(push) +#pragma warning(disable: 4127) // warning C4127: conditional expression is constant +#endif + +template +class concurrent_unordered_base : public Traits +{ +protected: + // Type definitions + typedef concurrent_unordered_base self_type; + typedef typename Traits::value_type value_type; + typedef typename Traits::key_type key_type; + typedef typename Traits::hash_compare hash_compare; + typedef typename Traits::allocator_type allocator_type; + typedef typename hash_compare::hasher hasher; + typedef typename hash_compare::key_equal key_equal; + + typedef typename tbb::internal::allocator_traits::size_type size_type; + typedef typename tbb::internal::allocator_traits::difference_type difference_type; + typedef typename tbb::internal::allocator_traits::pointer pointer; + typedef typename tbb::internal::allocator_traits::const_pointer const_pointer; + // No support for reference/const_reference in allocator + typedef typename allocator_type::value_type& reference; + typedef const typename allocator_type::value_type& const_reference; + + typedef split_ordered_list solist_t; + typedef typename solist_t::nodeptr_t nodeptr_t; + // Iterators that walk the entire split-order list, including dummy nodes + typedef typename solist_t::raw_iterator raw_iterator; + typedef typename solist_t::raw_const_iterator raw_const_iterator; + typedef typename solist_t::iterator iterator; // TODO: restore const iterator for unordered_sets + typedef typename solist_t::const_iterator const_iterator; + typedef iterator local_iterator; + typedef const_iterator const_local_iterator; +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + typedef typename Traits::node_type node_type; +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + using Traits::my_hash_compare; + using Traits::get_key; + using Traits::allow_multimapping; + + static const size_type initial_bucket_number = 8; // Initial number of buckets + +private: + template + friend class concurrent_unordered_base; + + typedef std::pair pairii_t; + typedef std::pair paircc_t; + + static size_type const pointers_per_table = sizeof(size_type) * 8; // One bucket segment per bit + static const size_type initial_bucket_load = 4; // Initial maximum number of elements per bucket + + struct call_internal_clear_on_exit{ + concurrent_unordered_base* my_instance; + call_internal_clear_on_exit(concurrent_unordered_base* instance) : my_instance(instance) {} + void dismiss(){ my_instance = NULL;} + ~call_internal_clear_on_exit(){ + if (my_instance){ + my_instance->internal_clear(); + } + } + }; +protected: + // Constructors/Destructors + concurrent_unordered_base(size_type n_of_buckets = initial_bucket_number, + const hash_compare& hc = hash_compare(), const allocator_type& a = allocator_type()) + : Traits(hc), my_solist(a), + my_allocator(a), my_maximum_bucket_size((float) initial_bucket_load) + { + if( n_of_buckets == 0) ++n_of_buckets; + my_number_of_buckets = size_type(1)<<__TBB_Log2((uintptr_t)n_of_buckets*2-1); // round up to power of 2 + internal_init(); + } + + concurrent_unordered_base(const concurrent_unordered_base& right, const allocator_type& a) + : Traits(right.my_hash_compare), my_solist(a), my_allocator(a) + { + internal_init(); + internal_copy(right); + } + + concurrent_unordered_base(const concurrent_unordered_base& right) + : Traits(right.my_hash_compare), my_solist(right.get_allocator()), my_allocator(right.get_allocator()) + { + //FIXME:exception safety seems to be broken here + internal_init(); + internal_copy(right); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + concurrent_unordered_base(concurrent_unordered_base&& right) + : Traits(right.my_hash_compare), my_solist(right.get_allocator()), my_allocator(right.get_allocator()), + my_maximum_bucket_size(float(initial_bucket_load)) + { + my_number_of_buckets = initial_bucket_number; + internal_init(); + swap(right); + } + + concurrent_unordered_base(concurrent_unordered_base&& right, const allocator_type& a) + : Traits(right.my_hash_compare), my_solist(a), my_allocator(a) + { + call_internal_clear_on_exit clear_buckets_on_exception(this); + + internal_init(); + if (a == right.get_allocator()){ + my_number_of_buckets = initial_bucket_number; + my_maximum_bucket_size = float(initial_bucket_load); + this->swap(right); + }else{ + my_maximum_bucket_size = right.my_maximum_bucket_size; + my_number_of_buckets = right.my_number_of_buckets; + my_solist.my_element_count = right.my_solist.my_element_count; + + if (! right.my_solist.empty()){ + nodeptr_t previous_node = my_solist.my_head; + + // Move all elements one by one, including dummy ones + for (raw_const_iterator it = ++(right.my_solist.raw_begin()), last = right.my_solist.raw_end(); it != last; ++it) + { + const nodeptr_t pnode = it.get_node_ptr(); + nodeptr_t node; + if (pnode->is_dummy()) { + node = my_solist.create_node(pnode->get_order_key()); + size_type bucket = __TBB_ReverseBits(pnode->get_order_key()) % my_number_of_buckets; + set_bucket(bucket, node); + }else{ + node = my_solist.create_node(pnode->get_order_key(), std::move(pnode->my_element)); + } + + previous_node = my_solist.try_insert_atomic(previous_node, node, NULL); + __TBB_ASSERT(previous_node != NULL, "Insertion of node failed. Concurrent inserts in constructor ?"); + } + my_solist.check_range(); + } + } + + clear_buckets_on_exception.dismiss(); + } + +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + + concurrent_unordered_base& operator=(const concurrent_unordered_base& right) { + if (this != &right) + internal_copy(right); + return (*this); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + concurrent_unordered_base& operator=(concurrent_unordered_base&& other) + { + if(this != &other){ + typedef typename tbb::internal::allocator_traits::propagate_on_container_move_assignment pocma_t; + if(pocma_t::value || this->my_allocator == other.my_allocator) { + concurrent_unordered_base trash (std::move(*this)); + swap(other); + if (pocma_t::value) { + using std::swap; + //TODO: swapping allocators here may be a problem, replace with single direction moving + swap(this->my_solist.my_node_allocator, other.my_solist.my_node_allocator); + swap(this->my_allocator, other.my_allocator); + } + } else { + concurrent_unordered_base moved_copy(std::move(other),this->my_allocator); + this->swap(moved_copy); + } + } + return *this; + } + +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! assignment operator from initializer_list + concurrent_unordered_base& operator=(std::initializer_list il) + { + this->clear(); + this->insert(il.begin(),il.end()); + return (*this); + } +#endif // __TBB_INITIALIZER_LISTS_PRESENT + + + ~concurrent_unordered_base() { + // Delete all node segments + internal_clear(); + } + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + template + void internal_merge(SourceType& source) { + typedef typename SourceType::iterator source_iterator; + __TBB_STATIC_ASSERT((tbb::internal::is_same_type::value), + "Incompatible containers cannot be merged"); + + for(source_iterator it = source.begin(); it != source.end();) { + source_iterator where = it++; + if (allow_multimapping || find(get_key(*where)) == end()) { + std::pair extract_result = source.internal_extract(where); + + // Remember the old order key + sokey_t old_order_key = extract_result.first.my_node->get_order_key(); + + // If the insertion fails, it returns ownership of the node to extract_result.first + // extract_result.first remains valid node handle + if (!insert(std::move(extract_result.first)).second) { + raw_iterator next = extract_result.second; + raw_iterator current = next++; + + // Revert order key to old value + extract_result.first.my_node->init(old_order_key); + + __TBB_ASSERT(extract_result.first.my_node->get_order_key() >= current.get_node_ptr()->get_order_key(), + "Wrong nodes order in source container"); + __TBB_ASSERT(next==source.my_solist.raw_end() || + extract_result.first.my_node->get_order_key() <= next.get_node_ptr()->get_order_key(), + "Wrong nodes order in source container"); + + size_t new_count = 0;// To use try_insert() + bool insert_result = + source.my_solist.try_insert(current, next, extract_result.first.my_node, &new_count).second; + __TBB_ASSERT_EX(insert_result, "Return to source must be successful. " + "Changing source container while merging is unsafe."); + } + extract_result.first.deactivate(); + } + } + } +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + +public: + allocator_type get_allocator() const { + return my_solist.get_allocator(); + } + + // Size and capacity function + bool empty() const { + return my_solist.empty(); + } + + size_type size() const { + return my_solist.size(); + } + + size_type max_size() const { + return my_solist.max_size(); + } + + // Iterators + iterator begin() { + return my_solist.begin(); + } + + const_iterator begin() const { + return my_solist.begin(); + } + + iterator end() { + return my_solist.end(); + } + + const_iterator end() const { + return my_solist.end(); + } + + const_iterator cbegin() const { + return my_solist.cbegin(); + } + + const_iterator cend() const { + return my_solist.cend(); + } + + // Parallel traversal support + class const_range_type : tbb::internal::no_assign { + const concurrent_unordered_base &my_table; + raw_const_iterator my_begin_node; + raw_const_iterator my_end_node; + mutable raw_const_iterator my_midpoint_node; + public: + //! Type for size of a range + typedef typename concurrent_unordered_base::size_type size_type; + typedef typename concurrent_unordered_base::value_type value_type; + typedef typename concurrent_unordered_base::reference reference; + typedef typename concurrent_unordered_base::difference_type difference_type; + typedef typename concurrent_unordered_base::const_iterator iterator; + + //! True if range is empty. + bool empty() const {return my_begin_node == my_end_node;} + + //! True if range can be partitioned into two subranges. + bool is_divisible() const { + return my_midpoint_node != my_end_node; + } + //! Split range. + const_range_type( const_range_type &r, split ) : + my_table(r.my_table), my_end_node(r.my_end_node) + { + r.my_end_node = my_begin_node = r.my_midpoint_node; + __TBB_ASSERT( !empty(), "Splitting despite the range is not divisible" ); + __TBB_ASSERT( !r.empty(), "Splitting despite the range is not divisible" ); + set_midpoint(); + r.set_midpoint(); + } + //! Init range with container and grainsize specified + const_range_type( const concurrent_unordered_base &a_table ) : + my_table(a_table), my_begin_node(a_table.my_solist.begin()), + my_end_node(a_table.my_solist.end()) + { + set_midpoint(); + } + iterator begin() const { return my_table.my_solist.get_iterator(my_begin_node); } + iterator end() const { return my_table.my_solist.get_iterator(my_end_node); } + //! The grain size for this range. + size_type grainsize() const { return 1; } + + //! Set my_midpoint_node to point approximately half way between my_begin_node and my_end_node. + void set_midpoint() const { + if( my_begin_node == my_end_node ) // not divisible + my_midpoint_node = my_end_node; + else { + sokey_t begin_key = solist_t::get_safe_order_key(my_begin_node); + sokey_t end_key = solist_t::get_safe_order_key(my_end_node); + size_t mid_bucket = __TBB_ReverseBits( begin_key + (end_key-begin_key)/2 ) % my_table.my_number_of_buckets; + while ( !my_table.is_initialized(mid_bucket) ) mid_bucket = my_table.get_parent(mid_bucket); + if(__TBB_ReverseBits(mid_bucket) > begin_key) { + // found a dummy_node between begin and end + my_midpoint_node = my_table.my_solist.first_real_iterator(my_table.get_bucket( mid_bucket )); + } + else { + // didn't find a dummy node between begin and end. + my_midpoint_node = my_end_node; + } +#if TBB_USE_ASSERT + { + sokey_t mid_key = solist_t::get_safe_order_key(my_midpoint_node); + __TBB_ASSERT( begin_key < mid_key, "my_begin_node is after my_midpoint_node" ); + __TBB_ASSERT( mid_key <= end_key, "my_midpoint_node is after my_end_node" ); + } +#endif // TBB_USE_ASSERT + } + } + }; + + class range_type : public const_range_type { + public: + typedef typename concurrent_unordered_base::iterator iterator; + //! Split range. + range_type( range_type &r, split ) : const_range_type( r, split() ) {} + //! Init range with container and grainsize specified + range_type( const concurrent_unordered_base &a_table ) : const_range_type(a_table) {} + + iterator begin() const { return solist_t::get_iterator( const_range_type::begin() ); } + iterator end() const { return solist_t::get_iterator( const_range_type::end() ); } + }; + + range_type range() { + return range_type( *this ); + } + + const_range_type range() const { + return const_range_type( *this ); + } + + // Modifiers + std::pair insert(const value_type& value) { + return internal_insert(value); + } + + iterator insert(const_iterator, const value_type& value) { + // Ignore hint + return insert(value).first; + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + std::pair insert(value_type&& value) { + return internal_insert(std::move(value)); + } + + iterator insert(const_iterator, value_type&& value) { + // Ignore hint + return insert(std::move(value)).first; + } +#endif /*__TBB_CPP11_RVALUE_REF_PRESENT*/ + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + std::pair insert(node_type&& nh) { + if (!nh.empty()) { + nodeptr_t handled_node = nh.my_node; + std::pair insert_result = + internal_insert + (handled_node->my_element, handled_node); + if (insert_result.second) + nh.deactivate(); + return insert_result; + } + return std::pair(end(), false); + } + + iterator insert(const_iterator, node_type&& nh) { + return insert(std::move(nh)).first; + } +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT + template + std::pair emplace(Args&&... args) { + nodeptr_t pnode = my_solist.create_node_v(tbb::internal::forward(args)...); + + return internal_insert(pnode->my_element, pnode); + } + + template + iterator emplace_hint(const_iterator, Args&&... args) { + // Ignore hint + return emplace(tbb::internal::forward(args)...).first; + } +#endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT + + + template + void insert(Iterator first, Iterator last) { + for (Iterator it = first; it != last; ++it) + insert(*it); + } + +#if __TBB_INITIALIZER_LISTS_PRESENT + //! Insert initializer list + void insert(std::initializer_list il) { + insert(il.begin(), il.end()); + } +#endif + + iterator unsafe_erase(const_iterator where) { + return internal_erase(where); + } + + iterator unsafe_erase(const_iterator first, const_iterator last) { + while (first != last) + unsafe_erase(first++); + return my_solist.get_iterator(first); + } + + size_type unsafe_erase(const key_type& key) { + pairii_t where = equal_range(key); + size_type item_count = internal_distance(where.first, where.second); + unsafe_erase(where.first, where.second); + return item_count; + } + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + node_type unsafe_extract(const_iterator where) { + return internal_extract(where).first; + } + + node_type unsafe_extract(const key_type& key) { + pairii_t where = equal_range(key); + if (where.first == end()) return node_type(); // element was not found + return internal_extract(where.first).first; + } +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + + void swap(concurrent_unordered_base& right) { + if (this != &right) { + std::swap(my_hash_compare, right.my_hash_compare); + my_solist.swap(right.my_solist); + internal_swap_buckets(right); + std::swap(my_number_of_buckets, right.my_number_of_buckets); + std::swap(my_maximum_bucket_size, right.my_maximum_bucket_size); + } + } + + // Observers + hasher hash_function() const { + return my_hash_compare.my_hash_object; + } + + key_equal key_eq() const { + return my_hash_compare.my_key_compare_object; + } + + void clear() { + // Clear list + my_solist.clear(); + + // Clear buckets + internal_clear(); + + // Initialize bucket 0 + __TBB_ASSERT(my_buckets[0] == NULL, NULL); + raw_iterator dummy_node = my_solist.raw_begin(); + set_bucket(0, dummy_node); + } + + // Lookup + iterator find(const key_type& key) { + return internal_find(key); + } + + const_iterator find(const key_type& key) const { + return const_cast(this)->internal_find(key); + } + + size_type count(const key_type& key) const { + if(allow_multimapping) { + paircc_t answer = equal_range(key); + size_type item_count = internal_distance(answer.first, answer.second); + return item_count; + } else { + return const_cast(this)->internal_find(key) == end()?0:1; + } + } + + std::pair equal_range(const key_type& key) { + return internal_equal_range(key); + } + + std::pair equal_range(const key_type& key) const { + return const_cast(this)->internal_equal_range(key); + } + + // Bucket interface - for debugging + size_type unsafe_bucket_count() const { + return my_number_of_buckets; + } + + size_type unsafe_max_bucket_count() const { + return segment_size(pointers_per_table-1); + } + + size_type unsafe_bucket_size(size_type bucket) { + size_type item_count = 0; + if (is_initialized(bucket)) { + raw_iterator it = get_bucket(bucket); + ++it; + for (; it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy(); ++it) + ++item_count; + } + return item_count; + } + + size_type unsafe_bucket(const key_type& key) const { + sokey_t order_key = (sokey_t) my_hash_compare(key); + size_type bucket = order_key % my_number_of_buckets; + return bucket; + } + + // If the bucket is initialized, return a first non-dummy element in it + local_iterator unsafe_begin(size_type bucket) { + if (!is_initialized(bucket)) + return end(); + + raw_iterator it = get_bucket(bucket); + return my_solist.first_real_iterator(it); + } + + // If the bucket is initialized, return a first non-dummy element in it + const_local_iterator unsafe_begin(size_type bucket) const + { + if (!is_initialized(bucket)) + return end(); + + raw_const_iterator it = get_bucket(bucket); + return my_solist.first_real_iterator(it); + } + + // @REVIEW: Takes O(n) + // Returns the iterator after the last non-dummy element in the bucket + local_iterator unsafe_end(size_type bucket) + { + if (!is_initialized(bucket)) + return end(); + + raw_iterator it = get_bucket(bucket); + + // Find the end of the bucket, denoted by the dummy element + do ++it; + while(it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy()); + + // Return the first real element past the end of the bucket + return my_solist.first_real_iterator(it); + } + + // @REVIEW: Takes O(n) + // Returns the iterator after the last non-dummy element in the bucket + const_local_iterator unsafe_end(size_type bucket) const + { + if (!is_initialized(bucket)) + return end(); + + raw_const_iterator it = get_bucket(bucket); + + // Find the end of the bucket, denoted by the dummy element + do ++it; + while(it != my_solist.raw_end() && !it.get_node_ptr()->is_dummy()); + + // Return the first real element past the end of the bucket + return my_solist.first_real_iterator(it); + } + + const_local_iterator unsafe_cbegin(size_type bucket) const { + return ((const self_type *) this)->unsafe_begin(bucket); + } + + const_local_iterator unsafe_cend(size_type bucket) const { + return ((const self_type *) this)->unsafe_end(bucket); + } + + // Hash policy + float load_factor() const { + return (float) size() / (float) unsafe_bucket_count(); + } + + float max_load_factor() const { + return my_maximum_bucket_size; + } + + void max_load_factor(float newmax) { + if (newmax != newmax || newmax < 0) + tbb::internal::throw_exception(tbb::internal::eid_invalid_load_factor); + my_maximum_bucket_size = newmax; + } + + // This function is a noop, because the underlying split-ordered list + // is already sorted, so an increase in the bucket number will be + // reflected next time this bucket is touched. + void rehash(size_type buckets) { + size_type current_buckets = my_number_of_buckets; + if (current_buckets >= buckets) + return; + my_number_of_buckets = size_type(1)<<__TBB_Log2((uintptr_t)buckets*2-1); // round up to power of 2 + } + +private: + + // Initialize the hash and keep the first bucket open + void internal_init() { + // Initialize the array of segment pointers + memset(my_buckets, 0, sizeof(my_buckets)); + + // Initialize bucket 0 + raw_iterator dummy_node = my_solist.raw_begin(); + set_bucket(0, dummy_node); + } + + void internal_clear() { + for (size_type index = 0; index < pointers_per_table; ++index) { + if (my_buckets[index] != NULL) { + size_type sz = segment_size(index); + for (size_type index2 = 0; index2 < sz; ++index2) + my_allocator.destroy(&my_buckets[index][index2]); + my_allocator.deallocate(my_buckets[index], sz); + my_buckets[index] = 0; + } + } + } + + void internal_copy(const self_type& right) { + clear(); + + my_maximum_bucket_size = right.my_maximum_bucket_size; + my_number_of_buckets = right.my_number_of_buckets; + + __TBB_TRY { + insert(right.begin(), right.end()); + my_hash_compare = right.my_hash_compare; + } __TBB_CATCH(...) { + my_solist.clear(); + __TBB_RETHROW(); + } + } + + void internal_swap_buckets(concurrent_unordered_base& right) + { + // Swap all node segments + for (size_type index = 0; index < pointers_per_table; ++index) + { + raw_iterator * iterator_pointer = my_buckets[index]; + my_buckets[index] = right.my_buckets[index]; + right.my_buckets[index] = iterator_pointer; + } + } + + //TODO: why not use std::distance? + // Hash APIs + static size_type internal_distance(const_iterator first, const_iterator last) + { + size_type num = 0; + + for (const_iterator it = first; it != last; ++it) + ++num; + + return num; + } + + // Insert an element in the hash given its value + template + std::pair internal_insert(__TBB_FORWARDING_REF(ValueType) value, nodeptr_t pnode = NULL) + { + const key_type *pkey = &get_key(value); + sokey_t hash_key = (sokey_t) my_hash_compare(*pkey); + size_type new_count = 0; + sokey_t order_key = split_order_key_regular(hash_key); + raw_iterator previous = prepare_bucket(hash_key); + raw_iterator last = my_solist.raw_end(); + __TBB_ASSERT(previous != last, "Invalid head node"); + + if (pnode) { + // Set new order_key to node + pnode->init(order_key); + } + + // First node is a dummy node + for (raw_iterator where = previous;;) + { + ++where; + if (where == last || solist_t::get_order_key(where) > order_key || + // if multimapped, stop at the first item equal to us. + (allow_multimapping && solist_t::get_order_key(where) == order_key && + !my_hash_compare(get_key(*where), *pkey))) // TODO: fix negation + { + if (!pnode) { + pnode = my_solist.create_node(order_key, tbb::internal::forward(value), AllowCreate()); + // If the value was moved, the known reference to key might be invalid + pkey = &get_key(pnode->my_element); + } + + // Try to insert 'pnode' between 'previous' and 'where' + std::pair result = my_solist.try_insert(previous, where, pnode, &new_count); + + if (result.second) + { + // Insertion succeeded, adjust the table size, if needed + adjust_table_size(new_count, my_number_of_buckets); + return result; + } + else + { + // Insertion failed: either the same node was inserted by another thread, or + // another element was inserted at exactly the same place as this node. + // Proceed with the search from the previous location where order key was + // known to be larger (note: this is legal only because there is no safe + // concurrent erase operation supported). + where = previous; + continue; + } + } + else if (!allow_multimapping && solist_t::get_order_key(where) == order_key && + !my_hash_compare(get_key(*where), *pkey)) // TODO: fix negation + { // Element already in the list, return it + if (pnode && AllowDestroy::value) + my_solist.destroy_node(pnode); + return std::pair(my_solist.get_iterator(where), false); + } + // Move the iterator forward + previous = where; + } + } + + // Find the element in the split-ordered list + iterator internal_find(const key_type& key) + { + sokey_t hash_key = (sokey_t) my_hash_compare(key); + sokey_t order_key = split_order_key_regular(hash_key); + raw_iterator last = my_solist.raw_end(); + + for (raw_iterator it = prepare_bucket(hash_key); it != last; ++it) + { + if (solist_t::get_order_key(it) > order_key) + { + // If the order key is smaller than the current order key, the element + // is not in the hash. + return end(); + } + else if (solist_t::get_order_key(it) == order_key) + { + // The fact that order keys match does not mean that the element is found. + // Key function comparison has to be performed to check whether this is the + // right element. If not, keep searching while order key is the same. + if (!my_hash_compare(get_key(*it), key)) // TODO: fix negation + return my_solist.get_iterator(it); + } + } + + return end(); + } + + // Erase an element from the list. This is not a concurrency safe function. + iterator internal_erase(const_iterator it) + { + sokey_t hash_key = (sokey_t) my_hash_compare(get_key(*it)); + raw_iterator previous = prepare_bucket(hash_key); + raw_iterator last = my_solist.raw_end(); + __TBB_ASSERT(previous != last, "Invalid head node"); + + // First node is a dummy node + for (raw_iterator where = previous; where != last; previous = where) { + ++where; + if (my_solist.get_iterator(where) == it) + return my_solist.erase_node(previous, it); + } + return end(); + } + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + std::pair internal_extract(const_iterator it) { + sokey_t hash_key = sokey_t(my_hash_compare(get_key(*it))); + raw_iterator previous = prepare_bucket(hash_key); + raw_iterator last = my_solist.raw_end(); + __TBB_ASSERT(previous != last, "Invalid head node"); + + for(raw_iterator where = previous; where != last; previous = where) { + ++where; + if (my_solist.get_iterator(where) == it) { + const_iterator result = it; + my_solist.erase_node(previous, it, /*allow_destroy*/tbb::internal::false_type()); + return std::pair( node_type(result.get_node_ptr()), + previous); + } + } + return std::pair(node_type(), end()); + } +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT + + // Return the [begin, end) pair of iterators with the same key values. + // This operation makes sense only if mapping is many-to-one. + pairii_t internal_equal_range(const key_type& key) + { + sokey_t hash_key = (sokey_t) my_hash_compare(key); + sokey_t order_key = split_order_key_regular(hash_key); + raw_iterator end_it = my_solist.raw_end(); + + for (raw_iterator it = prepare_bucket(hash_key); it != end_it; ++it) + { + if (solist_t::get_order_key(it) > order_key) + { + // There is no element with the given key + return pairii_t(end(), end()); + } + else if (solist_t::get_order_key(it) == order_key && + !my_hash_compare(get_key(*it), key)) // TODO: fix negation; also below + { + iterator first = my_solist.get_iterator(it); + iterator last = first; + do ++last; while( allow_multimapping && last != end() && !my_hash_compare(get_key(*last), key) ); + return pairii_t(first, last); + } + } + + return pairii_t(end(), end()); + } + + // Bucket APIs + void init_bucket(size_type bucket) + { + // Bucket 0 has no parent. + __TBB_ASSERT( bucket != 0, "The first bucket must always be initialized"); + + size_type parent_bucket = get_parent(bucket); + + // All parent_bucket buckets have to be initialized before this bucket is + if (!is_initialized(parent_bucket)) + init_bucket(parent_bucket); + + raw_iterator parent = get_bucket(parent_bucket); + + // Create a dummy first node in this bucket + raw_iterator dummy_node = my_solist.insert_dummy(parent, split_order_key_dummy(bucket)); + set_bucket(bucket, dummy_node); + } + + void adjust_table_size(size_type total_elements, size_type current_size) + { + // Grow the table by a factor of 2 if possible and needed + if ( ((float) total_elements / (float) current_size) > my_maximum_bucket_size ) + { + // Double the size of the hash only if size has not changed in between loads + my_number_of_buckets.compare_and_swap(2u*current_size, current_size); + //Simple "my_number_of_buckets.compare_and_swap( current_size<<1, current_size );" does not work for VC8 + //due to overzealous compiler warnings in /Wp64 mode + } + } + + size_type get_parent(size_type bucket) const + { + // Unsets bucket's most significant turned-on bit + size_type msb = __TBB_Log2((uintptr_t)bucket); + return bucket & ~(size_type(1) << msb); + } + + + // Dynamic sized array (segments) + //! @return segment index of given index in the array + static size_type segment_index_of( size_type index ) { + return size_type( __TBB_Log2( uintptr_t(index|1) ) ); + } + + //! @return the first array index of given segment + static size_type segment_base( size_type k ) { + return (size_type(1)<(new_segment), 0, sz*sizeof(raw_iterator)); + + if (my_buckets[segment].compare_and_swap( new_segment, NULL) != NULL) + my_allocator.deallocate(new_segment, sz); + } + + my_buckets[segment][bucket] = dummy_head; + } + + bool is_initialized(size_type bucket) const { + size_type segment = segment_index_of(bucket); + bucket -= segment_base(segment); + + if (my_buckets[segment] == NULL) + return false; + + raw_iterator it = my_buckets[segment][bucket]; + return (it.get_node_ptr() != NULL); + } + + // Utilities for keys + + // A regular order key has its original hash value reversed and the last bit set + sokey_t split_order_key_regular(sokey_t order_key) const { + return __TBB_ReverseBits(order_key) | 0x1; + } + + // A dummy order key has its original hash value reversed and the last bit unset + sokey_t split_order_key_dummy(sokey_t order_key) const { + return __TBB_ReverseBits(order_key) & ~sokey_t(0x1); + } + + // Shared variables + atomic my_number_of_buckets; // Current table size + solist_t my_solist; // List where all the elements are kept + typename tbb::internal::allocator_rebind::type my_allocator; // Allocator object for segments + float my_maximum_bucket_size; // Maximum size of the bucket + atomic my_buckets[pointers_per_table]; // The segment table +}; +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(pop) // warning 4127 is back +#endif + +} // namespace internal +//! @endcond +} // namespace interface5 +} // namespace tbb +#endif // __TBB__concurrent_unordered_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h new file mode 100644 index 00000000..fa993572 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_deprecated_header_message_guard.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +#if (!defined(TBB_SUPPRESS_DEPRECATED_MESSAGES) || (TBB_SUPPRESS_DEPRECATED_MESSAGES == 0)) && !defined(__TBB_INTERNAL_INCLUDES_DEPRECATION_MESSAGE) && \ +!defined(__TBB_condition_variable_H_include_area) && \ +!defined(__TBB_ppl_H_include_area) && \ +!defined(__TBB_thread_H_include_area) && \ +!defined(__TBB_tuple_H_include_area) && \ +!defined(__TBB_aggregator_H_include_area) && \ +!defined(__TBB_aligned_space_H_include_area) && \ +!defined(__TBB_atomic_H_include_area) && \ +!defined(__TBB_combinable_H_include_area) && \ +!defined(__TBB_concurrent_hash_map_H_include_area) && \ +!defined(__TBB_concurrent_lru_cache_H_include_area) && \ +!defined(__TBB_concurrent_map_H_include_area) && \ +!defined(__TBB_concurrent_priority_queue_H_include_area) && \ +!defined(__TBB_concurrent_queue_H_include_area) && \ +!defined(__TBB_concurrent_set_H_include_area) && \ +!defined(__TBB_concurrent_unordered_map_H_include_area) && \ +!defined(__TBB_concurrent_unordered_set_H_include_area) && \ +!defined(__TBB_concurrent_vector_H_include_area) && \ +!defined(__TBB_critical_section_H_include_area) && \ +!defined(__TBB_enumerable_thread_specific_H_include_area) && \ +!defined(__TBB_flow_graph_opencl_node_H_include_area) && \ +!defined(__TBB_flow_graph_H_include_area) && \ +!defined(__TBB_mutex_H_include_area) && \ +!defined(__TBB_parallel_do_H_include_area) && \ +!defined(__TBB_parallel_for_H_include_area) && \ +!defined(__TBB_parallel_invoke_H_include_area) && \ +!defined(__TBB_parallel_reduce_H_include_area) && \ +!defined(__TBB_parallel_scan_H_include_area) && \ +!defined(__TBB_parallel_sort_H_include_area) && \ +!defined(__TBB_parallel_while_H_include_area) && \ +!defined(__TBB_partitioner_H_include_area) && \ +!defined(__TBB_pipeline_H_include_area) && \ +!defined(__TBB_queuing_mutex_H_include_area) && \ +!defined(__TBB_queuing_rw_mutex_H_include_area) && \ +!defined(__TBB_reader_writer_lock_H_include_area) && \ +!defined(__TBB_recursive_mutex_H_include_area) && \ +!defined(__TBB_runtime_loader_H_include_area) && \ +!defined(__TBB_task_scheduler_init_H_include_area) && \ +!defined(__TBB_spin_mutex_H_include_area) && \ +!defined(__TBB_task_arena_H_include_area) && \ +!defined(__TBB_task_group_H_include_area) && \ +!defined(__TBB_task_scheduler_observer_H_include_area) && \ +!defined(__TBB_task_H_include_area) && \ +!defined(__TBB_tbb_exception_H_include_area) && \ +!defined(__TBB_tbb_profiling_H_include_area) && \ +!defined(__TBB_tbb_thread_H_include_area) && \ +!defined(__TBB_tbb_H_include_area) + +#define __TBB_show_deprecated_header_message + +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_async_msg_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_async_msg_impl.h new file mode 100644 index 00000000..9f269ffd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_async_msg_impl.h @@ -0,0 +1,153 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__flow_graph_async_msg_impl_H +#define __TBB__flow_graph_async_msg_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +namespace internal { + +template +class async_storage { +public: + typedef receiver async_storage_client; + + async_storage() : my_graph(nullptr) { + my_data_ready.store(false); + } + + ~async_storage() { + // Release reference to the graph if async_storage + // was destructed before set() call + if (my_graph) { + my_graph->release_wait(); + my_graph = nullptr; + } + } + + template + async_storage(C&& data) : my_graph(nullptr), my_data( std::forward(data) ) { + using namespace tbb::internal; + __TBB_STATIC_ASSERT( (is_same_type::type, typename strip::type>::value), "incoming type must be T" ); + + my_data_ready.store(true); + } + + template + bool set(C&& data) { + using namespace tbb::internal; + __TBB_STATIC_ASSERT( (is_same_type::type, typename strip::type>::value), "incoming type must be T" ); + + { + tbb::spin_mutex::scoped_lock locker(my_mutex); + + if (my_data_ready.load()) { + __TBB_ASSERT(false, "double set() call"); + return false; + } + + my_data = std::forward(data); + my_data_ready.store(true); + } + + // Thread sync is on my_data_ready flag + for (typename subscriber_list_type::iterator it = my_clients.begin(); it != my_clients.end(); ++it) { + (*it)->try_put(my_data); + } + + // Data was sent, release reference to the graph + if (my_graph) { + my_graph->release_wait(); + my_graph = nullptr; + } + + return true; + } + + task* subscribe(async_storage_client& client, graph& g) { + if (! my_data_ready.load()) + { + tbb::spin_mutex::scoped_lock locker(my_mutex); + + if (! my_data_ready.load()) { +#if TBB_USE_ASSERT + for (typename subscriber_list_type::iterator it = my_clients.begin(); it != my_clients.end(); ++it) { + __TBB_ASSERT(*it != &client, "unexpected double subscription"); + } +#endif // TBB_USE_ASSERT + + // Increase graph lifetime + my_graph = &g; + my_graph->reserve_wait(); + + // Subscribe + my_clients.push_back(&client); + return SUCCESSFULLY_ENQUEUED; + } + } + + __TBB_ASSERT(my_data_ready.load(), "data is NOT ready"); + return client.try_put_task(my_data); + } + +private: + graph* my_graph; + tbb::spin_mutex my_mutex; + tbb::atomic my_data_ready; + T my_data; + typedef std::vector subscriber_list_type; + subscriber_list_type my_clients; +}; + +} // namespace internal + +template +class __TBB_DEPRECATED async_msg { + template< typename > friend class receiver; + template< typename, typename > friend struct internal::async_helpers; +public: + typedef T async_msg_data_type; + + async_msg() : my_storage(std::make_shared< internal::async_storage >()) {} + + async_msg(const T& t) : my_storage(std::make_shared< internal::async_storage >(t)) {} + + async_msg(T&& t) : my_storage(std::make_shared< internal::async_storage >( std::move(t) )) {} + + virtual ~async_msg() {} + + void set(const T& t) { + my_storage->set(t); + } + + void set(T&& t) { + my_storage->set( std::move(t) ); + } + +protected: + // Can be overridden in derived class to inform that + // async calculation chain is over + virtual void finalize() const {} + +private: + typedef std::shared_ptr< internal::async_storage > async_storage_ptr; + async_storage_ptr my_storage; +}; + +#endif // __TBB__flow_graph_async_msg_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_body_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_body_impl.h new file mode 100644 index 00000000..e75f50da --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_body_impl.h @@ -0,0 +1,507 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__flow_graph_body_impl_H +#define __TBB__flow_graph_body_impl_H + +#include "tbb/internal/_template_helpers.h" + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +// included in namespace tbb::flow::interfaceX (in flow_graph.h) + +namespace internal { + +typedef tbb::internal::uint64_t tag_value; + +using tbb::internal::strip; + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + +template struct Policy {}; + +template struct has_policy; + +template +struct has_policy : + tbb::internal::bool_constant::value || + has_policy::value> {}; + +template +struct has_policy : + tbb::internal::bool_constant::value> {}; + +template +struct has_policy > : has_policy {}; + +#else + +template struct Policy {}; + +template +struct has_policy : tbb::internal::bool_constant::value> {}; + +template +struct has_policy > : has_policy {}; + +template +struct has_policy > : + tbb::internal::bool_constant::value || has_policy::value> {}; + +#endif + +namespace graph_policy_namespace { + + struct rejecting { }; + struct reserving { }; + struct queueing { }; + struct lightweight { }; + + // K == type of field used for key-matching. Each tag-matching port will be provided + // functor that, given an object accepted by the port, will return the + /// field of type K being used for matching. + template::type > > + struct key_matching { + typedef K key_type; + typedef typename strip::type base_key_type; + typedef KHash hash_compare_type; + }; + + // old tag_matching join's new specifier + typedef key_matching tag_matching; + + // Aliases for Policy combinations + typedef interface11::internal::Policy queueing_lightweight; + typedef interface11::internal::Policy rejecting_lightweight; + +} // namespace graph_policy_namespace + +// -------------- function_body containers ---------------------- +//! A functor that takes no input and generates a value of type Output +template< typename Output > +class input_body : tbb::internal::no_assign { +public: + virtual ~input_body() {} + +#if TBB_DEPRECATED_INPUT_NODE_BODY + virtual bool operator()(Output &output) = 0; +#else + virtual Output operator()(flow_control& fc) = 0; +#endif + virtual input_body* clone() = 0; +}; + +template +void check_input_node_body_input_type_impl(Body) { + __TBB_STATIC_ASSERT((tbb::internal::is_same_type::arg_type, flow_control&>::value), + "TBB Warning: input_node body requirements have been changed." + "To temporarily enforce deprecated API specify TBB_DEPRECATED_INPUT_NODE_BODY."); +} + +template +void check_input_node_body_input_type(Body) { + check_input_node_body_input_type_impl(&Body::operator()); +} + +template +void check_input_node_body_input_type(ReturnType(*)(T)) { + __TBB_STATIC_ASSERT((tbb::internal::is_same_type::value), + "TBB Warning: input_node body requirements have been changed." + "To temporarily enforce deprecated API specify TBB_DEPRECATED_INPUT_NODE_BODY."); +} + +//! The leaf for input_body +template< typename Output, typename Body> +class input_body_leaf : public input_body { +public: + input_body_leaf( const Body &_body ) : body(_body) { } + +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(Output &output) __TBB_override { return body( output ); } +#else + Output operator()(flow_control& fc) __TBB_override { + check_input_node_body_input_type(body); + return body(fc); + } +#endif + input_body_leaf* clone() __TBB_override { + return new input_body_leaf< Output, Body >(body); + } + Body get_body() { return body; } +private: + Body body; +}; + +template< typename Output > +class source_body : tbb::internal::no_assign { +public: + virtual ~source_body() {} + virtual bool operator()(Output &output) = 0; + virtual source_body* clone() = 0; +}; + +//! The leaf for source_body +template< typename Output, typename Body> +class source_body_leaf : public source_body { +public: + source_body_leaf( const Body &_body ) : body(_body) { } + + bool operator()(Output &output) __TBB_override { return body( output ); } + + source_body_leaf* clone() __TBB_override { + return new source_body_leaf< Output, Body >(body); + } + + Body get_body() { return body; } +private: + Body body; +}; + +//! A functor that takes an Input and generates an Output +template< typename Input, typename Output > +class function_body : tbb::internal::no_assign { +public: + virtual ~function_body() {} + virtual Output operator()(const Input &input) = 0; + virtual function_body* clone() = 0; +}; + +//! the leaf for function_body +template +class function_body_leaf : public function_body< Input, Output > { +public: + function_body_leaf( const B &_body ) : body(_body) { } + Output operator()(const Input &i) __TBB_override { return body(i); } + B get_body() { return body; } + function_body_leaf* clone() __TBB_override { + return new function_body_leaf< Input, Output, B >(body); + } +private: + B body; +}; + +//! the leaf for function_body specialized for Input and output of continue_msg +template +class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > { +public: + function_body_leaf( const B &_body ) : body(_body) { } + continue_msg operator()( const continue_msg &i ) __TBB_override { + body(i); + return i; + } + B get_body() { return body; } + function_body_leaf* clone() __TBB_override { + return new function_body_leaf< continue_msg, continue_msg, B >(body); + } +private: + B body; +}; + +//! the leaf for function_body specialized for Output of continue_msg +template +class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > { +public: + function_body_leaf( const B &_body ) : body(_body) { } + continue_msg operator()(const Input &i) __TBB_override { + body(i); + return continue_msg(); + } + B get_body() { return body; } + function_body_leaf* clone() __TBB_override { + return new function_body_leaf< Input, continue_msg, B >(body); + } +private: + B body; +}; + +//! the leaf for function_body specialized for Input of continue_msg +template +class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > { +public: + function_body_leaf( const B &_body ) : body(_body) { } + Output operator()(const continue_msg &i) __TBB_override { + return body(i); + } + B get_body() { return body; } + function_body_leaf* clone() __TBB_override { + return new function_body_leaf< continue_msg, Output, B >(body); + } +private: + B body; +}; + +//! function_body that takes an Input and a set of output ports +template +class multifunction_body : tbb::internal::no_assign { +public: + virtual ~multifunction_body () {} + virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0; + virtual multifunction_body* clone() = 0; + virtual void* get_body_ptr() = 0; +}; + +//! leaf for multifunction. OutputSet can be a std::tuple or a vector. +template +class multifunction_body_leaf : public multifunction_body { +public: + multifunction_body_leaf(const B &_body) : body(_body) { } + void operator()(const Input &input, OutputSet &oset) __TBB_override { + body(input, oset); // body may explicitly put() to one or more of oset. + } + void* get_body_ptr() __TBB_override { return &body; } + multifunction_body_leaf* clone() __TBB_override { + return new multifunction_body_leaf(body); + } + +private: + B body; +}; + +// ------ function bodies for hash_buffers and key-matching joins. + +template +class type_to_key_function_body : tbb::internal::no_assign { + public: + virtual ~type_to_key_function_body() {} + virtual Output operator()(const Input &input) = 0; // returns an Output + virtual type_to_key_function_body* clone() = 0; +}; + +// specialization for ref output +template +class type_to_key_function_body : tbb::internal::no_assign { + public: + virtual ~type_to_key_function_body() {} + virtual const Output & operator()(const Input &input) = 0; // returns a const Output& + virtual type_to_key_function_body* clone() = 0; +}; + +template +class type_to_key_function_body_leaf : public type_to_key_function_body { +public: + type_to_key_function_body_leaf( const B &_body ) : body(_body) { } + Output operator()(const Input &i) __TBB_override { return body(i); } + B get_body() { return body; } + type_to_key_function_body_leaf* clone() __TBB_override { + return new type_to_key_function_body_leaf< Input, Output, B>(body); + } +private: + B body; +}; + +template +class type_to_key_function_body_leaf : public type_to_key_function_body< Input, Output&> { +public: + type_to_key_function_body_leaf( const B &_body ) : body(_body) { } + const Output& operator()(const Input &i) __TBB_override { + return body(i); + } + B get_body() { return body; } + type_to_key_function_body_leaf* clone() __TBB_override { + return new type_to_key_function_body_leaf< Input, Output&, B>(body); + } +private: + B body; +}; + +// --------------------------- end of function_body containers ------------------------ + +// --------------------------- node task bodies --------------------------------------- + +//! A task that calls a node's forward_task function +template< typename NodeType > +class forward_task_bypass : public graph_task { + + NodeType &my_node; + +public: + + forward_task_bypass( NodeType &n +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + , node_priority_t node_priority = no_priority + ) : graph_task(node_priority), +#else + ) : +#endif + my_node(n) {} + + task *execute() __TBB_override { + task * new_task = my_node.forward_task(); + if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL; + return new_task; + } +}; + +//! A task that calls a node's apply_body_bypass function, passing in an input of type Input +// return the task* unless it is SUCCESSFULLY_ENQUEUED, in which case return NULL +template< typename NodeType, typename Input > +class apply_body_task_bypass : public graph_task { + + NodeType &my_node; + Input my_input; + +public: + + apply_body_task_bypass( NodeType &n, const Input &i +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + , node_priority_t node_priority = no_priority + ) : graph_task(node_priority), +#else + ) : +#endif + my_node(n), my_input(i) {} + + task *execute() __TBB_override { + task * next_task = my_node.apply_body_bypass( my_input ); + if(next_task == SUCCESSFULLY_ENQUEUED) next_task = NULL; + return next_task; + } +}; + +//! A task that calls a node's apply_body_bypass function with no input +template< typename NodeType > +class source_task_bypass : public graph_task { + + NodeType &my_node; + +public: + + source_task_bypass( NodeType &n ) : my_node(n) {} + + task *execute() __TBB_override { + task *new_task = my_node.apply_body_bypass( ); + if(new_task == SUCCESSFULLY_ENQUEUED) return NULL; + return new_task; + } +}; + +// ------------------------ end of node task bodies ----------------------------------- + +//! An empty functor that takes an Input and returns a default constructed Output +template< typename Input, typename Output > +struct empty_body { + Output operator()( const Input & ) const { return Output(); } +}; + +template +class decrementer; + +template +class decrementer::value, void>::type + > : public receiver, tbb::internal::no_copy { + T* my_node; +protected: + + task* try_put_task( const DecrementType& value ) __TBB_override { + task* result = my_node->decrement_counter( value ); + if( !result ) + result = SUCCESSFULLY_ENQUEUED; + return result; + } + + graph& graph_reference() const __TBB_override { + return my_node->my_graph; + } + + template friend class tbb::flow::interface11::limiter_node; + void reset_receiver( reset_flags f ) __TBB_override { +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + if (f & rf_clear_edges) + my_built_predecessors.clear(); +#else + tbb::internal::suppress_unused_warning( f ); +#endif + } + +public: + // Since decrementer does not make use of possibly unconstructed owner inside its + // constructor, my_node can be directly initialized with 'this' pointer passed from the + // owner, hence making method 'set_owner' needless. + decrementer() : my_node(NULL) {} + void set_owner( T *node ) { my_node = node; } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + spin_mutex my_mutex; + //! The predecessor type for this node + typedef typename receiver::predecessor_type predecessor_type; + + typedef internal::edge_container built_predecessors_type; + typedef typename built_predecessors_type::edge_list_type predecessor_list_type; + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + + void internal_add_built_predecessor( predecessor_type &s) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + my_built_predecessors.add_edge( s ); + } + + void internal_delete_built_predecessor( predecessor_type &s) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + my_built_predecessors.delete_edge(s); + } + + void copy_predecessors( predecessor_list_type &v) __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + my_built_predecessors.copy_edges(v); + } + + size_t predecessor_count() __TBB_override { + spin_mutex::scoped_lock l(my_mutex); + return my_built_predecessors.edge_count(); + } +protected: + built_predecessors_type my_built_predecessors; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ +}; + +template +class decrementer : public continue_receiver, tbb::internal::no_copy { + + T *my_node; + + task *execute() __TBB_override { + return my_node->decrement_counter( 1 ); + } + +protected: + + graph& graph_reference() const __TBB_override { + return my_node->my_graph; + } + +public: + + typedef continue_msg input_type; + typedef continue_msg output_type; + decrementer( int number_of_predecessors = 0 ) + : continue_receiver( + __TBB_FLOW_GRAPH_PRIORITY_ARG1(number_of_predecessors, tbb::flow::internal::no_priority) + ) + // Since decrementer does not make use of possibly unconstructed owner inside its + // constructor, my_node can be directly initialized with 'this' pointer passed from the + // owner, hence making method 'set_owner' needless. + , my_node(NULL) + {} + void set_owner( T *node ) { my_node = node; } +}; + +} // namespace internal + +#endif // __TBB__flow_graph_body_impl_H + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_cache_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_cache_impl.h new file mode 100644 index 00000000..b670ae65 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_cache_impl.h @@ -0,0 +1,592 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__flow_graph_cache_impl_H +#define __TBB__flow_graph_cache_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +// included in namespace tbb::flow::interfaceX (in flow_graph.h) + +namespace internal { + +//! A node_cache maintains a std::queue of elements of type T. Each operation is protected by a lock. +template< typename T, typename M=spin_mutex > +class node_cache { + public: + + typedef size_t size_type; + + bool empty() { + typename mutex_type::scoped_lock lock( my_mutex ); + return internal_empty(); + } + + void add( T &n ) { + typename mutex_type::scoped_lock lock( my_mutex ); + internal_push(n); + } + + void remove( T &n ) { + typename mutex_type::scoped_lock lock( my_mutex ); + for ( size_t i = internal_size(); i != 0; --i ) { + T &s = internal_pop(); + if ( &s == &n ) return; // only remove one predecessor per request + internal_push(s); + } + } + + void clear() { + while( !my_q.empty()) (void)my_q.pop(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + my_built_predecessors.clear(); +#endif + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef edge_container built_predecessors_type; + built_predecessors_type &built_predecessors() { return my_built_predecessors; } + + typedef typename edge_container::edge_list_type predecessor_list_type; + void internal_add_built_predecessor( T &n ) { + typename mutex_type::scoped_lock lock( my_mutex ); + my_built_predecessors.add_edge(n); + } + + void internal_delete_built_predecessor( T &n ) { + typename mutex_type::scoped_lock lock( my_mutex ); + my_built_predecessors.delete_edge(n); + } + + void copy_predecessors( predecessor_list_type &v) { + typename mutex_type::scoped_lock lock( my_mutex ); + my_built_predecessors.copy_edges(v); + } + + size_t predecessor_count() { + typename mutex_type::scoped_lock lock(my_mutex); + return (size_t)(my_built_predecessors.edge_count()); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +protected: + + typedef M mutex_type; + mutex_type my_mutex; + std::queue< T * > my_q; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + built_predecessors_type my_built_predecessors; +#endif + + // Assumes lock is held + inline bool internal_empty( ) { + return my_q.empty(); + } + + // Assumes lock is held + inline size_type internal_size( ) { + return my_q.size(); + } + + // Assumes lock is held + inline void internal_push( T &n ) { + my_q.push(&n); + } + + // Assumes lock is held + inline T &internal_pop() { + T *v = my_q.front(); + my_q.pop(); + return *v; + } + +}; + +//! A cache of predecessors that only supports try_get +template< typename T, typename M=spin_mutex > +#if __TBB_PREVIEW_ASYNC_MSG +// TODO: make predecessor_cache type T-independent when async_msg becomes regular feature +class predecessor_cache : public node_cache< untyped_sender, M > { +#else +class predecessor_cache : public node_cache< sender, M > { +#endif // __TBB_PREVIEW_ASYNC_MSG +public: + typedef M mutex_type; + typedef T output_type; +#if __TBB_PREVIEW_ASYNC_MSG + typedef untyped_sender predecessor_type; + typedef untyped_receiver successor_type; +#else + typedef sender predecessor_type; + typedef receiver successor_type; +#endif // __TBB_PREVIEW_ASYNC_MSG + + predecessor_cache( ) : my_owner( NULL ) { } + + void set_owner( successor_type *owner ) { my_owner = owner; } + + bool get_item( output_type &v ) { + + bool msg = false; + + do { + predecessor_type *src; + { + typename mutex_type::scoped_lock lock(this->my_mutex); + if ( this->internal_empty() ) { + break; + } + src = &this->internal_pop(); + } + + // Try to get from this sender + msg = src->try_get( v ); + + if (msg == false) { + // Relinquish ownership of the edge + if (my_owner) + src->register_successor( *my_owner ); + } else { + // Retain ownership of the edge + this->add(*src); + } + } while ( msg == false ); + return msg; + } + + // If we are removing arcs (rf_clear_edges), call clear() rather than reset(). + void reset() { + if (my_owner) { + for(;;) { + predecessor_type *src; + { + if (this->internal_empty()) break; + src = &this->internal_pop(); + } + src->register_successor( *my_owner ); + } + } + } + +protected: + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + using node_cache< predecessor_type, M >::my_built_predecessors; +#endif + successor_type *my_owner; +}; + +//! An cache of predecessors that supports requests and reservations +// TODO: make reservable_predecessor_cache type T-independent when async_msg becomes regular feature +template< typename T, typename M=spin_mutex > +class reservable_predecessor_cache : public predecessor_cache< T, M > { +public: + typedef M mutex_type; + typedef T output_type; +#if __TBB_PREVIEW_ASYNC_MSG + typedef untyped_sender predecessor_type; + typedef untyped_receiver successor_type; +#else + typedef sender predecessor_type; + typedef receiver successor_type; +#endif // __TBB_PREVIEW_ASYNC_MSG + + reservable_predecessor_cache( ) : reserved_src(NULL) { } + + bool + try_reserve( output_type &v ) { + bool msg = false; + + do { + { + typename mutex_type::scoped_lock lock(this->my_mutex); + if ( reserved_src || this->internal_empty() ) + return false; + + reserved_src = &this->internal_pop(); + } + + // Try to get from this sender + msg = reserved_src->try_reserve( v ); + + if (msg == false) { + typename mutex_type::scoped_lock lock(this->my_mutex); + // Relinquish ownership of the edge + reserved_src->register_successor( *this->my_owner ); + reserved_src = NULL; + } else { + // Retain ownership of the edge + this->add( *reserved_src ); + } + } while ( msg == false ); + + return msg; + } + + bool + try_release( ) { + reserved_src->try_release( ); + reserved_src = NULL; + return true; + } + + bool + try_consume( ) { + reserved_src->try_consume( ); + reserved_src = NULL; + return true; + } + + void reset( ) { + reserved_src = NULL; + predecessor_cache::reset( ); + } + + void clear() { + reserved_src = NULL; + predecessor_cache::clear(); + } + +private: + predecessor_type *reserved_src; +}; + + +//! An abstract cache of successors +// TODO: make successor_cache type T-independent when async_msg becomes regular feature +template +class successor_cache : tbb::internal::no_copy { +protected: + + typedef M mutex_type; + mutex_type my_mutex; + +#if __TBB_PREVIEW_ASYNC_MSG + typedef untyped_receiver successor_type; + typedef untyped_receiver *pointer_type; + typedef untyped_sender owner_type; +#else + typedef receiver successor_type; + typedef receiver *pointer_type; + typedef sender owner_type; +#endif // __TBB_PREVIEW_ASYNC_MSG + typedef std::list< pointer_type > successors_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + edge_container my_built_successors; +#endif + successors_type my_successors; + + owner_type *my_owner; + +public: +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename edge_container::edge_list_type successor_list_type; + + edge_container &built_successors() { return my_built_successors; } + + void internal_add_built_successor( successor_type &r) { + typename mutex_type::scoped_lock l(my_mutex, true); + my_built_successors.add_edge( r ); + } + + void internal_delete_built_successor( successor_type &r) { + typename mutex_type::scoped_lock l(my_mutex, true); + my_built_successors.delete_edge(r); + } + + void copy_successors( successor_list_type &v) { + typename mutex_type::scoped_lock l(my_mutex, false); + my_built_successors.copy_edges(v); + } + + size_t successor_count() { + typename mutex_type::scoped_lock l(my_mutex,false); + return my_built_successors.edge_count(); + } + +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + successor_cache( ) : my_owner(NULL) {} + + void set_owner( owner_type *owner ) { my_owner = owner; } + + virtual ~successor_cache() {} + + void register_successor( successor_type &r ) { + typename mutex_type::scoped_lock l(my_mutex, true); + my_successors.push_back( &r ); + } + + void remove_successor( successor_type &r ) { + typename mutex_type::scoped_lock l(my_mutex, true); + for ( typename successors_type::iterator i = my_successors.begin(); + i != my_successors.end(); ++i ) { + if ( *i == & r ) { + my_successors.erase(i); + break; + } + } + } + + bool empty() { + typename mutex_type::scoped_lock l(my_mutex, false); + return my_successors.empty(); + } + + void clear() { + my_successors.clear(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + my_built_successors.clear(); +#endif + } + +#if !__TBB_PREVIEW_ASYNC_MSG + virtual task * try_put_task( const T &t ) = 0; +#endif // __TBB_PREVIEW_ASYNC_MSG + }; // successor_cache + +//! An abstract cache of successors, specialized to continue_msg +template +class successor_cache< continue_msg, M > : tbb::internal::no_copy { +protected: + + typedef M mutex_type; + mutex_type my_mutex; + +#if __TBB_PREVIEW_ASYNC_MSG + typedef untyped_receiver successor_type; + typedef untyped_receiver *pointer_type; +#else + typedef receiver successor_type; + typedef receiver *pointer_type; +#endif // __TBB_PREVIEW_ASYNC_MSG + typedef std::list< pointer_type > successors_type; + successors_type my_successors; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + edge_container my_built_successors; + typedef edge_container::edge_list_type successor_list_type; +#endif + + sender *my_owner; + +public: + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + + edge_container &built_successors() { return my_built_successors; } + + void internal_add_built_successor( successor_type &r) { + typename mutex_type::scoped_lock l(my_mutex, true); + my_built_successors.add_edge( r ); + } + + void internal_delete_built_successor( successor_type &r) { + typename mutex_type::scoped_lock l(my_mutex, true); + my_built_successors.delete_edge(r); + } + + void copy_successors( successor_list_type &v) { + typename mutex_type::scoped_lock l(my_mutex, false); + my_built_successors.copy_edges(v); + } + + size_t successor_count() { + typename mutex_type::scoped_lock l(my_mutex,false); + return my_built_successors.edge_count(); + } + +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + successor_cache( ) : my_owner(NULL) {} + + void set_owner( sender *owner ) { my_owner = owner; } + + virtual ~successor_cache() {} + + void register_successor( successor_type &r ) { + typename mutex_type::scoped_lock l(my_mutex, true); + my_successors.push_back( &r ); + if ( my_owner && r.is_continue_receiver() ) { + r.register_predecessor( *my_owner ); + } + } + + void remove_successor( successor_type &r ) { + typename mutex_type::scoped_lock l(my_mutex, true); + for ( successors_type::iterator i = my_successors.begin(); + i != my_successors.end(); ++i ) { + if ( *i == & r ) { + // TODO: Check if we need to test for continue_receiver before + // removing from r. + if ( my_owner ) + r.remove_predecessor( *my_owner ); + my_successors.erase(i); + break; + } + } + } + + bool empty() { + typename mutex_type::scoped_lock l(my_mutex, false); + return my_successors.empty(); + } + + void clear() { + my_successors.clear(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + my_built_successors.clear(); +#endif + } + +#if !__TBB_PREVIEW_ASYNC_MSG + virtual task * try_put_task( const continue_msg &t ) = 0; +#endif // __TBB_PREVIEW_ASYNC_MSG + +}; // successor_cache< continue_msg > + +//! A cache of successors that are broadcast to +// TODO: make broadcast_cache type T-independent when async_msg becomes regular feature +template +class broadcast_cache : public successor_cache { + typedef M mutex_type; + typedef typename successor_cache::successors_type successors_type; + +public: + + broadcast_cache( ) {} + + // as above, but call try_put_task instead, and return the last task we received (if any) +#if __TBB_PREVIEW_ASYNC_MSG + template + task * try_put_task( const X &t ) { +#else + task * try_put_task( const T &t ) __TBB_override { +#endif // __TBB_PREVIEW_ASYNC_MSG + task * last_task = NULL; + bool upgraded = true; + typename mutex_type::scoped_lock l(this->my_mutex, upgraded); + typename successors_type::iterator i = this->my_successors.begin(); + while ( i != this->my_successors.end() ) { + task *new_task = (*i)->try_put_task(t); + // workaround for icc bug + graph& graph_ref = (*i)->graph_reference(); + last_task = combine_tasks(graph_ref, last_task, new_task); // enqueue if necessary + if(new_task) { + ++i; + } + else { // failed + if ( (*i)->register_predecessor(*this->my_owner) ) { + if (!upgraded) { + l.upgrade_to_writer(); + upgraded = true; + } + i = this->my_successors.erase(i); + } else { + ++i; + } + } + } + return last_task; + } + + // call try_put_task and return list of received tasks +#if __TBB_PREVIEW_ASYNC_MSG + template + bool gather_successful_try_puts( const X &t, task_list &tasks ) { +#else + bool gather_successful_try_puts( const T &t, task_list &tasks ) { +#endif // __TBB_PREVIEW_ASYNC_MSG + bool upgraded = true; + bool is_at_least_one_put_successful = false; + typename mutex_type::scoped_lock l(this->my_mutex, upgraded); + typename successors_type::iterator i = this->my_successors.begin(); + while ( i != this->my_successors.end() ) { + task * new_task = (*i)->try_put_task(t); + if(new_task) { + ++i; + if(new_task != SUCCESSFULLY_ENQUEUED) { + tasks.push_back(*new_task); + } + is_at_least_one_put_successful = true; + } + else { // failed + if ( (*i)->register_predecessor(*this->my_owner) ) { + if (!upgraded) { + l.upgrade_to_writer(); + upgraded = true; + } + i = this->my_successors.erase(i); + } else { + ++i; + } + } + } + return is_at_least_one_put_successful; + } +}; + +//! A cache of successors that are put in a round-robin fashion +// TODO: make round_robin_cache type T-independent when async_msg becomes regular feature +template +class round_robin_cache : public successor_cache { + typedef size_t size_type; + typedef M mutex_type; + typedef typename successor_cache::successors_type successors_type; + +public: + + round_robin_cache( ) {} + + size_type size() { + typename mutex_type::scoped_lock l(this->my_mutex, false); + return this->my_successors.size(); + } + +#if __TBB_PREVIEW_ASYNC_MSG + template + task * try_put_task( const X &t ) { +#else + task *try_put_task( const T &t ) __TBB_override { +#endif // __TBB_PREVIEW_ASYNC_MSG + bool upgraded = true; + typename mutex_type::scoped_lock l(this->my_mutex, upgraded); + typename successors_type::iterator i = this->my_successors.begin(); + while ( i != this->my_successors.end() ) { + task *new_task = (*i)->try_put_task(t); + if ( new_task ) { + return new_task; + } else { + if ( (*i)->register_predecessor(*this->my_owner) ) { + if (!upgraded) { + l.upgrade_to_writer(); + upgraded = true; + } + i = this->my_successors.erase(i); + } + else { + ++i; + } + } + } + return NULL; + } +}; + +} // namespace internal + +#endif // __TBB__flow_graph_cache_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_impl.h new file mode 100644 index 00000000..7859e944 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_impl.h @@ -0,0 +1,547 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_flow_graph_impl_H +#define __TBB_flow_graph_impl_H + +#include "../tbb_stddef.h" +#include "../task.h" +#include "../task_arena.h" +#include "../flow_graph_abstractions.h" + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#include "../concurrent_priority_queue.h" +#endif + +#include + +#if TBB_DEPRECATED_FLOW_ENQUEUE +#define FLOW_SPAWN(a) tbb::task::enqueue((a)) +#else +#define FLOW_SPAWN(a) tbb::task::spawn((a)) +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#define __TBB_FLOW_GRAPH_PRIORITY_EXPR( expr ) expr +#define __TBB_FLOW_GRAPH_PRIORITY_ARG0( priority ) , priority +#define __TBB_FLOW_GRAPH_PRIORITY_ARG1( arg1, priority ) arg1, priority +#else +#define __TBB_FLOW_GRAPH_PRIORITY_EXPR( expr ) +#define __TBB_FLOW_GRAPH_PRIORITY_ARG0( priority ) +#define __TBB_FLOW_GRAPH_PRIORITY_ARG1( arg1, priority ) arg1 +#endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + +#if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR +#define __TBB_DEPRECATED_LIMITER_EXPR( expr ) expr +#define __TBB_DEPRECATED_LIMITER_ARG2( arg1, arg2 ) arg1, arg2 +#define __TBB_DEPRECATED_LIMITER_ARG4( arg1, arg2, arg3, arg4 ) arg1, arg3, arg4 +#else +#define __TBB_DEPRECATED_LIMITER_EXPR( expr ) +#define __TBB_DEPRECATED_LIMITER_ARG2( arg1, arg2 ) arg1 +#define __TBB_DEPRECATED_LIMITER_ARG4( arg1, arg2, arg3, arg4 ) arg1, arg2 +#endif // TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR + +namespace tbb { +namespace flow { + +namespace internal { +static tbb::task * const SUCCESSFULLY_ENQUEUED = (task *)-1; +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +typedef unsigned int node_priority_t; +static const node_priority_t no_priority = node_priority_t(0); +#endif +} + +namespace interface10 { +class graph; +} + +namespace interface11 { + +using tbb::flow::internal::SUCCESSFULLY_ENQUEUED; + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +using tbb::flow::internal::node_priority_t; +using tbb::flow::internal::no_priority; +//! Base class for tasks generated by graph nodes. +struct graph_task : public task { + graph_task( node_priority_t node_priority = no_priority ) : priority( node_priority ) {} + node_priority_t priority; +}; +#else +typedef task graph_task; +#endif /* __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES */ + +class graph_node; + +template +class graph_iterator { + friend class tbb::flow::interface10::graph; + friend class graph_node; +public: + typedef size_t size_type; + typedef GraphNodeType value_type; + typedef GraphNodeType* pointer; + typedef GraphNodeType& reference; + typedef const GraphNodeType& const_reference; + typedef std::forward_iterator_tag iterator_category; + + //! Default constructor + graph_iterator() : my_graph(NULL), current_node(NULL) {} + + //! Copy constructor + graph_iterator(const graph_iterator& other) : + my_graph(other.my_graph), current_node(other.current_node) + {} + + //! Assignment + graph_iterator& operator=(const graph_iterator& other) { + if (this != &other) { + my_graph = other.my_graph; + current_node = other.current_node; + } + return *this; + } + + //! Dereference + reference operator*() const; + + //! Dereference + pointer operator->() const; + + //! Equality + bool operator==(const graph_iterator& other) const { + return ((my_graph == other.my_graph) && (current_node == other.current_node)); + } + + //! Inequality + bool operator!=(const graph_iterator& other) const { return !(operator==(other)); } + + //! Pre-increment + graph_iterator& operator++() { + internal_forward(); + return *this; + } + + //! Post-increment + graph_iterator operator++(int) { + graph_iterator result = *this; + operator++(); + return result; + } + +private: + // the graph over which we are iterating + GraphContainerType *my_graph; + // pointer into my_graph's my_nodes list + pointer current_node; + + //! Private initializing constructor for begin() and end() iterators + graph_iterator(GraphContainerType *g, bool begin); + void internal_forward(); +}; // class graph_iterator + +// flags to modify the behavior of the graph reset(). Can be combined. +enum reset_flags { + rf_reset_protocol = 0, + rf_reset_bodies = 1 << 0, // delete the current node body, reset to a copy of the initial node body. + rf_clear_edges = 1 << 1 // delete edges +}; + +namespace internal { + +void activate_graph(tbb::flow::interface10::graph& g); +void deactivate_graph(tbb::flow::interface10::graph& g); +bool is_graph_active(tbb::flow::interface10::graph& g); +tbb::task& prioritize_task(tbb::flow::interface10::graph& g, tbb::task& arena_task); +void spawn_in_graph_arena(tbb::flow::interface10::graph& g, tbb::task& arena_task); +void enqueue_in_graph_arena(tbb::flow::interface10::graph &g, tbb::task& arena_task); +void add_task_to_graph_reset_list(tbb::flow::interface10::graph& g, tbb::task *tp); + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +struct graph_task_comparator { + bool operator()(const graph_task* left, const graph_task* right) { + return left->priority < right->priority; + } +}; + +typedef tbb::concurrent_priority_queue graph_task_priority_queue_t; + +class priority_task_selector : public task { +public: + priority_task_selector(graph_task_priority_queue_t& priority_queue) + : my_priority_queue(priority_queue) {} + task* execute() __TBB_override { + graph_task* t = NULL; + bool result = my_priority_queue.try_pop(t); + __TBB_ASSERT_EX( result, "Number of critical tasks for scheduler and tasks" + " in graph's priority queue mismatched" ); + __TBB_ASSERT( t && t != SUCCESSFULLY_ENQUEUED, + "Incorrect task submitted to graph priority queue" ); + __TBB_ASSERT( t->priority != tbb::flow::internal::no_priority, + "Tasks from graph's priority queue must have priority" ); + task* t_next = t->execute(); + task::destroy(*t); + return t_next; + } +private: + graph_task_priority_queue_t& my_priority_queue; +}; +#endif /* __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES */ + +} + +} // namespace interfaceX +namespace interface10 { +//! The graph class +/** This class serves as a handle to the graph */ +class graph : tbb::internal::no_copy, public tbb::flow::graph_proxy { + friend class tbb::flow::interface11::graph_node; + + template< typename Body > + class run_task : public tbb::flow::interface11::graph_task { + public: + run_task(Body& body +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + , tbb::flow::interface11::node_priority_t node_priority = tbb::flow::interface11::no_priority + ) : tbb::flow::interface11::graph_task(node_priority), +#else + ) : +#endif + my_body(body) { } + tbb::task *execute() __TBB_override { + my_body(); + return NULL; + } + private: + Body my_body; + }; + + template< typename Receiver, typename Body > + class run_and_put_task : public tbb::flow::interface11::graph_task { + public: + run_and_put_task(Receiver &r, Body& body) : my_receiver(r), my_body(body) {} + tbb::task *execute() __TBB_override { + tbb::task *res = my_receiver.try_put_task(my_body()); + if (res == tbb::flow::interface11::SUCCESSFULLY_ENQUEUED) res = NULL; + return res; + } + private: + Receiver &my_receiver; + Body my_body; + }; + typedef std::list task_list_type; + + class wait_functor { + tbb::task* graph_root_task; + public: + wait_functor(tbb::task* t) : graph_root_task(t) {} + void operator()() const { graph_root_task->wait_for_all(); } + }; + + //! A functor that spawns a task + class spawn_functor : tbb::internal::no_assign { + tbb::task& spawn_task; + public: + spawn_functor(tbb::task& t) : spawn_task(t) {} + void operator()() const { + FLOW_SPAWN(spawn_task); + } + }; + + void prepare_task_arena(bool reinit = false) { + if (reinit) { + __TBB_ASSERT(my_task_arena, "task arena is NULL"); + my_task_arena->terminate(); + my_task_arena->initialize(tbb::task_arena::attach()); + } + else { + __TBB_ASSERT(my_task_arena == NULL, "task arena is not NULL"); + my_task_arena = new tbb::task_arena(tbb::task_arena::attach()); + } + if (!my_task_arena->is_active()) // failed to attach + my_task_arena->initialize(); // create a new, default-initialized arena + __TBB_ASSERT(my_task_arena->is_active(), "task arena is not active"); + } + +public: + //! Constructs a graph with isolated task_group_context + graph(); + + //! Constructs a graph with use_this_context as context + explicit graph(tbb::task_group_context& use_this_context); + + //! Destroys the graph. + /** Calls wait_for_all, then destroys the root task and context. */ + ~graph(); + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + void set_name(const char *name); +#endif + + __TBB_DEPRECATED void increment_wait_count() { + reserve_wait(); + } + + __TBB_DEPRECATED void decrement_wait_count() { + release_wait(); + } + + //! Used to register that an external entity may still interact with the graph. + /** The graph will not return from wait_for_all until a matching number of decrement_wait_count calls + is made. */ + void reserve_wait() __TBB_override; + + //! Deregisters an external entity that may have interacted with the graph. + /** The graph will not return from wait_for_all until all the number of decrement_wait_count calls + matches the number of increment_wait_count calls. */ + void release_wait() __TBB_override; + + //! Spawns a task that runs a body and puts its output to a specific receiver + /** The task is spawned as a child of the graph. This is useful for running tasks + that need to block a wait_for_all() on the graph. For example a one-off source. */ + template< typename Receiver, typename Body > + __TBB_DEPRECATED void run(Receiver &r, Body body) { + if (tbb::flow::interface11::internal::is_graph_active(*this)) { + task* rtask = new (task::allocate_additional_child_of(*root_task())) + run_and_put_task< Receiver, Body >(r, body); + my_task_arena->execute(spawn_functor(*rtask)); + } + } + + //! Spawns a task that runs a function object + /** The task is spawned as a child of the graph. This is useful for running tasks + that need to block a wait_for_all() on the graph. For example a one-off source. */ + template< typename Body > + __TBB_DEPRECATED void run(Body body) { + if (tbb::flow::interface11::internal::is_graph_active(*this)) { + task* rtask = new (task::allocate_additional_child_of(*root_task())) run_task< Body >(body); + my_task_arena->execute(spawn_functor(*rtask)); + } + } + + //! Wait until graph is idle and decrement_wait_count calls equals increment_wait_count calls. + /** The waiting thread will go off and steal work while it is block in the wait_for_all. */ + void wait_for_all() { + cancelled = false; + caught_exception = false; + if (my_root_task) { +#if TBB_USE_EXCEPTIONS + try { +#endif + my_task_arena->execute(wait_functor(my_root_task)); +#if __TBB_TASK_GROUP_CONTEXT + cancelled = my_context->is_group_execution_cancelled(); +#endif +#if TBB_USE_EXCEPTIONS + } + catch (...) { + my_root_task->set_ref_count(1); + my_context->reset(); + caught_exception = true; + cancelled = true; + throw; + } +#endif +#if __TBB_TASK_GROUP_CONTEXT + // TODO: the "if" condition below is just a work-around to support the concurrent wait + // mode. The cancellation and exception mechanisms are still broken in this mode. + // Consider using task group not to re-implement the same functionality. + if (!(my_context->traits() & tbb::task_group_context::concurrent_wait)) { + my_context->reset(); // consistent with behavior in catch() +#endif + my_root_task->set_ref_count(1); +#if __TBB_TASK_GROUP_CONTEXT + } +#endif + } + } + + //! Returns the root task of the graph + __TBB_DEPRECATED tbb::task * root_task() { + return my_root_task; + } + + // ITERATORS + template + friend class tbb::flow::interface11::graph_iterator; + + // Graph iterator typedefs + typedef tbb::flow::interface11::graph_iterator iterator; + typedef tbb::flow::interface11::graph_iterator const_iterator; + + // Graph iterator constructors + //! start iterator + iterator begin(); + //! end iterator + iterator end(); + //! start const iterator + const_iterator begin() const; + //! end const iterator + const_iterator end() const; + //! start const iterator + const_iterator cbegin() const; + //! end const iterator + const_iterator cend() const; + + //! return status of graph execution + bool is_cancelled() { return cancelled; } + bool exception_thrown() { return caught_exception; } + + // thread-unsafe state reset. + void reset(tbb::flow::interface11::reset_flags f = tbb::flow::interface11::rf_reset_protocol); + +private: + tbb::task *my_root_task; +#if __TBB_TASK_GROUP_CONTEXT + tbb::task_group_context *my_context; +#endif + bool own_context; + bool cancelled; + bool caught_exception; + bool my_is_active; + task_list_type my_reset_task_list; + + tbb::flow::interface11::graph_node *my_nodes, *my_nodes_last; + + tbb::spin_mutex nodelist_mutex; + void register_node(tbb::flow::interface11::graph_node *n); + void remove_node(tbb::flow::interface11::graph_node *n); + + tbb::task_arena* my_task_arena; + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + tbb::flow::interface11::internal::graph_task_priority_queue_t my_priority_queue; +#endif + + friend void tbb::flow::interface11::internal::activate_graph(graph& g); + friend void tbb::flow::interface11::internal::deactivate_graph(graph& g); + friend bool tbb::flow::interface11::internal::is_graph_active(graph& g); + friend tbb::task& tbb::flow::interface11::internal::prioritize_task(graph& g, tbb::task& arena_task); + friend void tbb::flow::interface11::internal::spawn_in_graph_arena(graph& g, tbb::task& arena_task); + friend void tbb::flow::interface11::internal::enqueue_in_graph_arena(graph &g, tbb::task& arena_task); + friend void tbb::flow::interface11::internal::add_task_to_graph_reset_list(graph& g, tbb::task *tp); + + friend class tbb::interface7::internal::task_arena_base; + +}; // class graph +} // namespace interface10 + +namespace interface11 { + +using tbb::flow::interface10::graph; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +namespace internal{ +class get_graph_helper; +} +#endif + +//! The base of all graph nodes. +class graph_node : tbb::internal::no_copy { + friend class graph; + template + friend class graph_iterator; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + friend class internal::get_graph_helper; +#endif + +protected: + graph& my_graph; + graph_node *next, *prev; +public: + explicit graph_node(graph& g); + + virtual ~graph_node(); + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + virtual void set_name(const char *name) = 0; +#endif + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + virtual void extract() = 0; +#endif + +protected: + // performs the reset on an individual node. + virtual void reset_node(reset_flags f = rf_reset_protocol) = 0; +}; // class graph_node + +namespace internal { + +inline void activate_graph(graph& g) { + g.my_is_active = true; +} + +inline void deactivate_graph(graph& g) { + g.my_is_active = false; +} + +inline bool is_graph_active(graph& g) { + return g.my_is_active; +} + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +inline tbb::task& prioritize_task(graph& g, tbb::task& t) { + task* critical_task = &t; + // TODO: change flow graph's interfaces to work with graph_task type instead of tbb::task. + graph_task* gt = static_cast(&t); + if( gt->priority != no_priority ) { + //! Non-preemptive priority pattern. The original task is submitted as a work item to the + //! priority queue, and a new critical task is created to take and execute a work item with + //! the highest known priority. The reference counting responsibility is transferred (via + //! allocate_continuation) to the new task. + critical_task = new( gt->allocate_continuation() ) priority_task_selector(g.my_priority_queue); + tbb::internal::make_critical( *critical_task ); + g.my_priority_queue.push(gt); + } + return *critical_task; +} +#else +inline tbb::task& prioritize_task(graph&, tbb::task& t) { + return t; +} +#endif /* __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES */ + +//! Spawns a task inside graph arena +inline void spawn_in_graph_arena(graph& g, tbb::task& arena_task) { + if (is_graph_active(g)) { + graph::spawn_functor s_fn(prioritize_task(g, arena_task)); + __TBB_ASSERT(g.my_task_arena && g.my_task_arena->is_active(), NULL); + g.my_task_arena->execute(s_fn); + } +} + +//! Enqueues a task inside graph arena +inline void enqueue_in_graph_arena(graph &g, tbb::task& arena_task) { + if (is_graph_active(g)) { + __TBB_ASSERT( g.my_task_arena && g.my_task_arena->is_active(), "Is graph's arena initialized and active?" ); + task::enqueue(prioritize_task(g, arena_task), *g.my_task_arena); + } +} + +inline void add_task_to_graph_reset_list(graph& g, tbb::task *tp) { + g.my_reset_task_list.push_back(tp); +} + +} // namespace internal + +} // namespace interfaceX +} // namespace flow +} // namespace tbb + +#endif // __TBB_flow_graph_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_indexer_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_indexer_impl.h new file mode 100644 index 00000000..2900db91 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_indexer_impl.h @@ -0,0 +1,480 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__flow_graph_indexer_impl_H +#define __TBB__flow_graph_indexer_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#include "_flow_graph_types_impl.h" + +namespace internal { + + // Output of the indexer_node is a tbb::flow::tagged_msg, and will be of + // the form tagged_msg + // where the value of tag will indicate which result was put to the + // successor. + + template + task* do_try_put(const T &v, void *p) { + typename IndexerNodeBaseType::output_type o(K, v); + return reinterpret_cast(p)->try_put_task(&o); + } + + template + struct indexer_helper { + template + static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) { + typedef typename tuple_element::type T; + task *(*indexer_node_put_task)(const T&, void *) = do_try_put; + tbb::flow::get(my_input).set_up(p, indexer_node_put_task, g); + indexer_helper::template set_indexer_node_pointer(my_input, p, g); + } + template + static inline void reset_inputs(InputTuple &my_input, reset_flags f) { + indexer_helper::reset_inputs(my_input, f); + tbb::flow::get(my_input).reset_receiver(f); + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + template + static inline void extract(InputTuple &my_input) { + indexer_helper::extract(my_input); + tbb::flow::get(my_input).extract_receiver(); + } +#endif + }; + + template + struct indexer_helper { + template + static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) { + typedef typename tuple_element<0, TupleTypes>::type T; + task *(*indexer_node_put_task)(const T&, void *) = do_try_put; + tbb::flow::get<0>(my_input).set_up(p, indexer_node_put_task, g); + } + template + static inline void reset_inputs(InputTuple &my_input, reset_flags f) { + tbb::flow::get<0>(my_input).reset_receiver(f); + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + template + static inline void extract(InputTuple &my_input) { + tbb::flow::get<0>(my_input).extract_receiver(); + } +#endif + }; + + template + class indexer_input_port : public receiver { + private: + void* my_indexer_ptr; + typedef task* (* forward_function_ptr)(T const &, void* ); + forward_function_ptr my_try_put_task; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + spin_mutex my_pred_mutex; + typedef typename receiver::built_predecessors_type built_predecessors_type; + built_predecessors_type my_built_predecessors; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + graph* my_graph; + public: +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + indexer_input_port() : my_pred_mutex(), my_graph(NULL) {} + indexer_input_port( const indexer_input_port & other) : receiver(), my_pred_mutex(), my_graph(other.my_graph) { + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + void set_up(void* p, forward_function_ptr f, graph& g) { + my_indexer_ptr = p; + my_try_put_task = f; + my_graph = &g; + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename receiver::predecessor_list_type predecessor_list_type; + typedef typename receiver::predecessor_type predecessor_type; + + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + + size_t predecessor_count() __TBB_override { + spin_mutex::scoped_lock l(my_pred_mutex); + return my_built_predecessors.edge_count(); + } + void internal_add_built_predecessor(predecessor_type &p) __TBB_override { + spin_mutex::scoped_lock l(my_pred_mutex); + my_built_predecessors.add_edge(p); + } + void internal_delete_built_predecessor(predecessor_type &p) __TBB_override { + spin_mutex::scoped_lock l(my_pred_mutex); + my_built_predecessors.delete_edge(p); + } + void copy_predecessors( predecessor_list_type &v) __TBB_override { + spin_mutex::scoped_lock l(my_pred_mutex); + my_built_predecessors.copy_edges(v); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + task *try_put_task(const T &v) __TBB_override { + return my_try_put_task(v, my_indexer_ptr); + } + + graph& graph_reference() const __TBB_override { + return *my_graph; + } + + public: +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void reset_receiver(reset_flags f) __TBB_override { if(f&rf_clear_edges) my_built_predecessors.clear(); } +#else + void reset_receiver(reset_flags /*f*/) __TBB_override { } +#endif + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract_receiver() { my_built_predecessors.receiver_extract(*this); } +#endif + }; + + template + class indexer_node_FE { + public: + static const int N = tbb::flow::tuple_size::value; + typedef OutputType output_type; + typedef InputTuple input_type; + + // Some versions of Intel(R) C++ Compiler fail to generate an implicit constructor for the class which has std::tuple as a member. + indexer_node_FE() : my_inputs() {} + + input_type &input_ports() { return my_inputs; } + protected: + input_type my_inputs; + }; + + //! indexer_node_base + template + class indexer_node_base : public graph_node, public indexer_node_FE, + public sender { + protected: + using graph_node::my_graph; + public: + static const size_t N = tbb::flow::tuple_size::value; + typedef OutputType output_type; + typedef StructTypes tuple_types; + typedef typename sender::successor_type successor_type; + typedef indexer_node_FE input_ports_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename sender::built_successors_type built_successors_type; + typedef typename sender::successor_list_type successor_list_type; +#endif + + private: + // ----------- Aggregator ------------ + enum op_type { reg_succ, rem_succ, try__put_task +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + , add_blt_succ, del_blt_succ, + blt_succ_cnt, blt_succ_cpy +#endif + }; + typedef indexer_node_base class_type; + + class indexer_node_base_operation : public aggregated_operation { + public: + char type; + union { + output_type const *my_arg; + successor_type *my_succ; + task *bypass_t; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + size_t cnt_val; + successor_list_type *succv; +#endif + }; + indexer_node_base_operation(const output_type* e, op_type t) : + type(char(t)), my_arg(e) {} + indexer_node_base_operation(const successor_type &s, op_type t) : type(char(t)), + my_succ(const_cast(&s)) {} + indexer_node_base_operation(op_type t) : type(char(t)) {} + }; + + typedef internal::aggregating_functor handler_type; + friend class internal::aggregating_functor; + aggregator my_aggregator; + + void handle_operations(indexer_node_base_operation* op_list) { + indexer_node_base_operation *current; + while(op_list) { + current = op_list; + op_list = op_list->next; + switch(current->type) { + + case reg_succ: + my_successors.register_successor(*(current->my_succ)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + + case rem_succ: + my_successors.remove_successor(*(current->my_succ)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case try__put_task: { + current->bypass_t = my_successors.try_put_task(*(current->my_arg)); + __TBB_store_with_release(current->status, SUCCEEDED); // return of try_put_task actual return value + } + break; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + case add_blt_succ: + my_successors.internal_add_built_successor(*(current->my_succ)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case del_blt_succ: + my_successors.internal_delete_built_successor(*(current->my_succ)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_succ_cnt: + current->cnt_val = my_successors.successor_count(); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_succ_cpy: + my_successors.copy_successors(*(current->succv)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + } + } + } + // ---------- end aggregator ----------- + public: + indexer_node_base(graph& g) : graph_node(g), input_ports_type() { + indexer_helper::set_indexer_node_pointer(this->my_inputs, this, g); + my_successors.set_owner(this); + my_aggregator.initialize_handler(handler_type(this)); + } + + indexer_node_base(const indexer_node_base& other) : graph_node(other.my_graph), input_ports_type(), sender() { + indexer_helper::set_indexer_node_pointer(this->my_inputs, this, other.my_graph); + my_successors.set_owner(this); + my_aggregator.initialize_handler(handler_type(this)); + } + + bool register_successor(successor_type &r) __TBB_override { + indexer_node_base_operation op_data(r, reg_succ); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + bool remove_successor( successor_type &r) __TBB_override { + indexer_node_base_operation op_data(r, rem_succ); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + task * try_put_task(output_type const *v) { // not a virtual method in this class + indexer_node_base_operation op_data(v, try__put_task); + my_aggregator.execute(&op_data); + return op_data.bypass_t; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + + void internal_add_built_successor( successor_type &r) __TBB_override { + indexer_node_base_operation op_data(r, add_blt_succ); + my_aggregator.execute(&op_data); + } + + void internal_delete_built_successor( successor_type &r) __TBB_override { + indexer_node_base_operation op_data(r, del_blt_succ); + my_aggregator.execute(&op_data); + } + + size_t successor_count() __TBB_override { + indexer_node_base_operation op_data(blt_succ_cnt); + my_aggregator.execute(&op_data); + return op_data.cnt_val; + } + + void copy_successors( successor_list_type &v) __TBB_override { + indexer_node_base_operation op_data(blt_succ_cpy); + op_data.succv = &v; + my_aggregator.execute(&op_data); + } + void extract() __TBB_override { + my_successors.built_successors().sender_extract(*this); + indexer_helper::extract(this->my_inputs); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + protected: + void reset_node(reset_flags f) __TBB_override { + if(f & rf_clear_edges) { + my_successors.clear(); + indexer_helper::reset_inputs(this->my_inputs,f); + } + } + + private: + broadcast_cache my_successors; + }; //indexer_node_base + + + template struct input_types; + + template + struct input_types<1, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename internal::tagged_msg type; + }; + + template + struct input_types<2, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename internal::tagged_msg type; + }; + + template + struct input_types<3, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename tuple_element<2, InputTuple>::type third_type; + typedef typename internal::tagged_msg type; + }; + + template + struct input_types<4, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename tuple_element<2, InputTuple>::type third_type; + typedef typename tuple_element<3, InputTuple>::type fourth_type; + typedef typename internal::tagged_msg type; + }; + + template + struct input_types<5, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename tuple_element<2, InputTuple>::type third_type; + typedef typename tuple_element<3, InputTuple>::type fourth_type; + typedef typename tuple_element<4, InputTuple>::type fifth_type; + typedef typename internal::tagged_msg type; + }; + + template + struct input_types<6, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename tuple_element<2, InputTuple>::type third_type; + typedef typename tuple_element<3, InputTuple>::type fourth_type; + typedef typename tuple_element<4, InputTuple>::type fifth_type; + typedef typename tuple_element<5, InputTuple>::type sixth_type; + typedef typename internal::tagged_msg type; + }; + + template + struct input_types<7, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename tuple_element<2, InputTuple>::type third_type; + typedef typename tuple_element<3, InputTuple>::type fourth_type; + typedef typename tuple_element<4, InputTuple>::type fifth_type; + typedef typename tuple_element<5, InputTuple>::type sixth_type; + typedef typename tuple_element<6, InputTuple>::type seventh_type; + typedef typename internal::tagged_msg type; + }; + + + template + struct input_types<8, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename tuple_element<2, InputTuple>::type third_type; + typedef typename tuple_element<3, InputTuple>::type fourth_type; + typedef typename tuple_element<4, InputTuple>::type fifth_type; + typedef typename tuple_element<5, InputTuple>::type sixth_type; + typedef typename tuple_element<6, InputTuple>::type seventh_type; + typedef typename tuple_element<7, InputTuple>::type eighth_type; + typedef typename internal::tagged_msg type; + }; + + + template + struct input_types<9, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename tuple_element<2, InputTuple>::type third_type; + typedef typename tuple_element<3, InputTuple>::type fourth_type; + typedef typename tuple_element<4, InputTuple>::type fifth_type; + typedef typename tuple_element<5, InputTuple>::type sixth_type; + typedef typename tuple_element<6, InputTuple>::type seventh_type; + typedef typename tuple_element<7, InputTuple>::type eighth_type; + typedef typename tuple_element<8, InputTuple>::type nineth_type; + typedef typename internal::tagged_msg type; + }; + + template + struct input_types<10, InputTuple> { + typedef typename tuple_element<0, InputTuple>::type first_type; + typedef typename tuple_element<1, InputTuple>::type second_type; + typedef typename tuple_element<2, InputTuple>::type third_type; + typedef typename tuple_element<3, InputTuple>::type fourth_type; + typedef typename tuple_element<4, InputTuple>::type fifth_type; + typedef typename tuple_element<5, InputTuple>::type sixth_type; + typedef typename tuple_element<6, InputTuple>::type seventh_type; + typedef typename tuple_element<7, InputTuple>::type eighth_type; + typedef typename tuple_element<8, InputTuple>::type nineth_type; + typedef typename tuple_element<9, InputTuple>::type tenth_type; + typedef typename internal::tagged_msg type; + }; + + // type generators + template + struct indexer_types : public input_types::value, OutputTuple> { + static const int N = tbb::flow::tuple_size::value; + typedef typename input_types::type output_type; + typedef typename wrap_tuple_elements::type input_ports_type; + typedef internal::indexer_node_FE indexer_FE_type; + typedef internal::indexer_node_base indexer_base_type; + }; + + template + class unfolded_indexer_node : public indexer_types::indexer_base_type { + public: + typedef typename indexer_types::input_ports_type input_ports_type; + typedef OutputTuple tuple_types; + typedef typename indexer_types::output_type output_type; + private: + typedef typename indexer_types::indexer_base_type base_type; + public: + unfolded_indexer_node(graph& g) : base_type(g) {} + unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {} + }; + +} /* namespace internal */ + +#endif /* __TBB__flow_graph_indexer_impl_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_item_buffer_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_item_buffer_impl.h new file mode 100644 index 00000000..e5a97d1c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_item_buffer_impl.h @@ -0,0 +1,283 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__flow_graph_item_buffer_impl_H +#define __TBB__flow_graph_item_buffer_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#include "tbb/internal/_flow_graph_types_impl.h" // for aligned_pair + +// in namespace tbb::flow::interfaceX (included in _flow_graph_node_impl.h) + + //! Expandable buffer of items. The possible operations are push, pop, + //* tests for empty and so forth. No mutual exclusion is built in. + //* objects are constructed into and explicitly-destroyed. get_my_item gives + // a read-only reference to the item in the buffer. set_my_item may be called + // with either an empty or occupied slot. + + using internal::aligned_pair; + using internal::alignment_of; + +namespace internal { + + template > + class item_buffer { + public: + typedef T item_type; + enum buffer_item_state { no_item=0, has_item=1, reserved_item=2 }; + protected: + typedef size_t size_type; + typedef typename aligned_pair::type buffer_item_type; + typedef typename tbb::internal::allocator_rebind::type allocator_type; + buffer_item_type *my_array; + size_type my_array_size; + static const size_type initial_buffer_size = 4; + size_type my_head; + size_type my_tail; + + bool buffer_empty() const { return my_head == my_tail; } + + buffer_item_type &item(size_type i) { + __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of::value),NULL); + __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].first))%alignment_of::value), NULL); + return my_array[i & (my_array_size - 1) ]; + } + + const buffer_item_type &item(size_type i) const { + __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of::value), NULL); + __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].first))%alignment_of::value), NULL); + return my_array[i & (my_array_size-1)]; + } + + bool my_item_valid(size_type i) const { return (i < my_tail) && (i >= my_head) && (item(i).second != no_item); } + bool my_item_reserved(size_type i) const { return item(i).second == reserved_item; } + + // object management in buffer + const item_type &get_my_item(size_t i) const { + __TBB_ASSERT(my_item_valid(i),"attempt to get invalid item"); + item_type *itm = (tbb::internal::punned_cast(&(item(i).first))); + return *(const item_type *)itm; + } + + // may be called with an empty slot or a slot that has already been constructed into. + void set_my_item(size_t i, const item_type &o) { + if(item(i).second != no_item) { + destroy_item(i); + } + new(&(item(i).first)) item_type(o); + item(i).second = has_item; + } + + // destructively-fetch an object from the buffer + void fetch_item(size_t i, item_type &o) { + __TBB_ASSERT(my_item_valid(i), "Trying to fetch an empty slot"); + o = get_my_item(i); // could have std::move assign semantics + destroy_item(i); + } + + // move an existing item from one slot to another. The moved-to slot must be unoccupied, + // the moved-from slot must exist and not be reserved. The after, from will be empty, + // to will be occupied but not reserved + void move_item(size_t to, size_t from) { + __TBB_ASSERT(!my_item_valid(to), "Trying to move to a non-empty slot"); + __TBB_ASSERT(my_item_valid(from), "Trying to move from an empty slot"); + set_my_item(to, get_my_item(from)); // could have std::move semantics + destroy_item(from); + + } + + // put an item in an empty slot. Return true if successful, else false + bool place_item(size_t here, const item_type &me) { +#if !TBB_DEPRECATED_SEQUENCER_DUPLICATES + if(my_item_valid(here)) return false; +#endif + set_my_item(here, me); + return true; + } + + // could be implemented with std::move semantics + void swap_items(size_t i, size_t j) { + __TBB_ASSERT(my_item_valid(i) && my_item_valid(j), "attempt to swap invalid item(s)"); + item_type temp = get_my_item(i); + set_my_item(i, get_my_item(j)); + set_my_item(j, temp); + } + + void destroy_item(size_type i) { + __TBB_ASSERT(my_item_valid(i), "destruction of invalid item"); + (tbb::internal::punned_cast(&(item(i).first)))->~item_type(); + item(i).second = no_item; + } + + // returns the front element + const item_type& front() const + { + __TBB_ASSERT(my_item_valid(my_head), "attempt to fetch head non-item"); + return get_my_item(my_head); + } + + // returns the back element + const item_type& back() const + { + __TBB_ASSERT(my_item_valid(my_tail - 1), "attempt to fetch head non-item"); + return get_my_item(my_tail - 1); + } + + // following methods are for reservation of the front of a buffer. + void reserve_item(size_type i) { __TBB_ASSERT(my_item_valid(i) && !my_item_reserved(i), "item cannot be reserved"); item(i).second = reserved_item; } + void release_item(size_type i) { __TBB_ASSERT(my_item_reserved(i), "item is not reserved"); item(i).second = has_item; } + + void destroy_front() { destroy_item(my_head); ++my_head; } + void destroy_back() { destroy_item(my_tail-1); --my_tail; } + + // we have to be able to test against a new tail value without changing my_tail + // grow_array doesn't work if we change my_tail when the old array is too small + size_type size(size_t new_tail = 0) { return (new_tail ? new_tail : my_tail) - my_head; } + size_type capacity() { return my_array_size; } + // sequencer_node does not use this method, so we don't + // need a version that passes in the new_tail value. + bool buffer_full() { return size() >= capacity(); } + + //! Grows the internal array. + void grow_my_array( size_t minimum_size ) { + // test that we haven't made the structure inconsistent. + __TBB_ASSERT(capacity() >= my_tail - my_head, "total items exceed capacity"); + size_type new_size = my_array_size ? 2*my_array_size : initial_buffer_size; + while( new_sizeback(); + destroy_back(); + return true; + } + + bool pop_front(item_type &v) { + if(!my_item_valid(my_head)) { + return false; + } + v = this->front(); + destroy_front(); + return true; + } + + // This is used both for reset and for grow_my_array. In the case of grow_my_array + // we want to retain the values of the head and tail. + void clean_up_buffer(bool reset_pointers) { + if (my_array) { + for( size_type i=my_head; i > + class reservable_item_buffer : public item_buffer { + protected: + using item_buffer::my_item_valid; + using item_buffer::my_head; + + public: + reservable_item_buffer() : item_buffer(), my_reserved(false) {} + void reset() {my_reserved = false; item_buffer::reset(); } + protected: + + bool reserve_front(T &v) { + if(my_reserved || !my_item_valid(this->my_head)) return false; + my_reserved = true; + // reserving the head + v = this->front(); + this->reserve_item(this->my_head); + return true; + } + + void consume_front() { + __TBB_ASSERT(my_reserved, "Attempt to consume a non-reserved item"); + this->destroy_front(); + my_reserved = false; + } + + void release_front() { + __TBB_ASSERT(my_reserved, "Attempt to release a non-reserved item"); + this->release_item(this->my_head); + my_reserved = false; + } + + bool my_reserved; + }; + +} // namespace internal + +#endif // __TBB__flow_graph_item_buffer_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_join_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_join_impl.h new file mode 100644 index 00000000..16837c7a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_join_impl.h @@ -0,0 +1,2002 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__flow_graph_join_impl_H +#define __TBB__flow_graph_join_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +namespace internal { + + struct forwarding_base : tbb::internal::no_assign { + forwarding_base(graph &g) : graph_ref(g) {} + virtual ~forwarding_base() {} + // decrement_port_count may create a forwarding task. If we cannot handle the task + // ourselves, ask decrement_port_count to deal with it. + virtual task * decrement_port_count(bool handle_task) = 0; + virtual void increment_port_count() = 0; + // moved here so input ports can queue tasks + graph& graph_ref; + }; + + // specialization that lets us keep a copy of the current_key for building results. + // KeyType can be a reference type. + template + struct matching_forwarding_base : public forwarding_base { + typedef typename tbb::internal::strip::type current_key_type; + matching_forwarding_base(graph &g) : forwarding_base(g) { } + virtual task * increment_key_count(current_key_type const & /*t*/, bool /*handle_task*/) = 0; // {return NULL;} + current_key_type current_key; // so ports can refer to FE's desired items + }; + + template< int N > + struct join_helper { + + template< typename TupleType, typename PortType > + static inline void set_join_node_pointer(TupleType &my_input, PortType *port) { + tbb::flow::get( my_input ).set_join_node_pointer(port); + join_helper::set_join_node_pointer( my_input, port ); + } + template< typename TupleType > + static inline void consume_reservations( TupleType &my_input ) { + tbb::flow::get( my_input ).consume(); + join_helper::consume_reservations( my_input ); + } + + template< typename TupleType > + static inline void release_my_reservation( TupleType &my_input ) { + tbb::flow::get( my_input ).release(); + } + + template + static inline void release_reservations( TupleType &my_input) { + join_helper::release_reservations(my_input); + release_my_reservation(my_input); + } + + template< typename InputTuple, typename OutputTuple > + static inline bool reserve( InputTuple &my_input, OutputTuple &out) { + if ( !tbb::flow::get( my_input ).reserve( tbb::flow::get( out ) ) ) return false; + if ( !join_helper::reserve( my_input, out ) ) { + release_my_reservation( my_input ); + return false; + } + return true; + } + + template + static inline bool get_my_item( InputTuple &my_input, OutputTuple &out) { + bool res = tbb::flow::get(my_input).get_item(tbb::flow::get(out) ); // may fail + return join_helper::get_my_item(my_input, out) && res; // do get on other inputs before returning + } + + template + static inline bool get_items(InputTuple &my_input, OutputTuple &out) { + return get_my_item(my_input, out); + } + + template + static inline void reset_my_port(InputTuple &my_input) { + join_helper::reset_my_port(my_input); + tbb::flow::get(my_input).reset_port(); + } + + template + static inline void reset_ports(InputTuple& my_input) { + reset_my_port(my_input); + } + + template + static inline void set_key_functors(InputTuple &my_input, KeyFuncTuple &my_key_funcs) { + tbb::flow::get(my_input).set_my_key_func(tbb::flow::get(my_key_funcs)); + tbb::flow::get(my_key_funcs) = NULL; + join_helper::set_key_functors(my_input, my_key_funcs); + } + + template< typename KeyFuncTuple> + static inline void copy_key_functors(KeyFuncTuple &my_inputs, KeyFuncTuple &other_inputs) { + if(tbb::flow::get(other_inputs).get_my_key_func()) { + tbb::flow::get(my_inputs).set_my_key_func(tbb::flow::get(other_inputs).get_my_key_func()->clone()); + } + join_helper::copy_key_functors(my_inputs, other_inputs); + } + + template + static inline void reset_inputs(InputTuple &my_input, reset_flags f) { + join_helper::reset_inputs(my_input, f); + tbb::flow::get(my_input).reset_receiver(f); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + template + static inline void extract_inputs(InputTuple &my_input) { + join_helper::extract_inputs(my_input); + tbb::flow::get(my_input).extract_receiver(); + } +#endif + }; // join_helper + + template< > + struct join_helper<1> { + + template< typename TupleType, typename PortType > + static inline void set_join_node_pointer(TupleType &my_input, PortType *port) { + tbb::flow::get<0>( my_input ).set_join_node_pointer(port); + } + + template< typename TupleType > + static inline void consume_reservations( TupleType &my_input ) { + tbb::flow::get<0>( my_input ).consume(); + } + + template< typename TupleType > + static inline void release_my_reservation( TupleType &my_input ) { + tbb::flow::get<0>( my_input ).release(); + } + + template + static inline void release_reservations( TupleType &my_input) { + release_my_reservation(my_input); + } + + template< typename InputTuple, typename OutputTuple > + static inline bool reserve( InputTuple &my_input, OutputTuple &out) { + return tbb::flow::get<0>( my_input ).reserve( tbb::flow::get<0>( out ) ); + } + + template + static inline bool get_my_item( InputTuple &my_input, OutputTuple &out) { + return tbb::flow::get<0>(my_input).get_item(tbb::flow::get<0>(out)); + } + + template + static inline bool get_items(InputTuple &my_input, OutputTuple &out) { + return get_my_item(my_input, out); + } + + template + static inline void reset_my_port(InputTuple &my_input) { + tbb::flow::get<0>(my_input).reset_port(); + } + + template + static inline void reset_ports(InputTuple& my_input) { + reset_my_port(my_input); + } + + template + static inline void set_key_functors(InputTuple &my_input, KeyFuncTuple &my_key_funcs) { + tbb::flow::get<0>(my_input).set_my_key_func(tbb::flow::get<0>(my_key_funcs)); + tbb::flow::get<0>(my_key_funcs) = NULL; + } + + template< typename KeyFuncTuple> + static inline void copy_key_functors(KeyFuncTuple &my_inputs, KeyFuncTuple &other_inputs) { + if(tbb::flow::get<0>(other_inputs).get_my_key_func()) { + tbb::flow::get<0>(my_inputs).set_my_key_func(tbb::flow::get<0>(other_inputs).get_my_key_func()->clone()); + } + } + template + static inline void reset_inputs(InputTuple &my_input, reset_flags f) { + tbb::flow::get<0>(my_input).reset_receiver(f); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + template + static inline void extract_inputs(InputTuple &my_input) { + tbb::flow::get<0>(my_input).extract_receiver(); + } +#endif + }; // join_helper<1> + + //! The two-phase join port + template< typename T > + class reserving_port : public receiver { + public: + typedef T input_type; + typedef typename receiver::predecessor_type predecessor_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename receiver::predecessor_list_type predecessor_list_type; + typedef typename receiver::built_predecessors_type built_predecessors_type; +#endif + private: + // ----------- Aggregator ------------ + enum op_type { reg_pred, rem_pred, res_item, rel_res, con_res +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy +#endif + }; + typedef reserving_port class_type; + + class reserving_port_operation : public aggregated_operation { + public: + char type; + union { + T *my_arg; + predecessor_type *my_pred; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + size_t cnt_val; + predecessor_list_type *plist; +#endif + }; + reserving_port_operation(const T& e, op_type t) : + type(char(t)), my_arg(const_cast(&e)) {} + reserving_port_operation(const predecessor_type &s, op_type t) : type(char(t)), + my_pred(const_cast(&s)) {} + reserving_port_operation(op_type t) : type(char(t)) {} + }; + + typedef internal::aggregating_functor handler_type; + friend class internal::aggregating_functor; + aggregator my_aggregator; + + void handle_operations(reserving_port_operation* op_list) { + reserving_port_operation *current; + bool no_predecessors; + while(op_list) { + current = op_list; + op_list = op_list->next; + switch(current->type) { + case reg_pred: + no_predecessors = my_predecessors.empty(); + my_predecessors.add(*(current->my_pred)); + if ( no_predecessors ) { + (void) my_join->decrement_port_count(true); // may try to forward + } + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case rem_pred: + my_predecessors.remove(*(current->my_pred)); + if(my_predecessors.empty()) my_join->increment_port_count(); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case res_item: + if ( reserved ) { + __TBB_store_with_release(current->status, FAILED); + } + else if ( my_predecessors.try_reserve( *(current->my_arg) ) ) { + reserved = true; + __TBB_store_with_release(current->status, SUCCEEDED); + } else { + if ( my_predecessors.empty() ) { + my_join->increment_port_count(); + } + __TBB_store_with_release(current->status, FAILED); + } + break; + case rel_res: + reserved = false; + my_predecessors.try_release( ); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case con_res: + reserved = false; + my_predecessors.try_consume( ); + __TBB_store_with_release(current->status, SUCCEEDED); + break; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + case add_blt_pred: + my_predecessors.internal_add_built_predecessor(*(current->my_pred)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case del_blt_pred: + my_predecessors.internal_delete_built_predecessor(*(current->my_pred)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_pred_cnt: + current->cnt_val = my_predecessors.predecessor_count(); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_pred_cpy: + my_predecessors.copy_predecessors(*(current->plist)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + } + } + } + + protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + task *try_put_task( const T & ) __TBB_override { + return NULL; + } + + graph& graph_reference() const __TBB_override { + return my_join->graph_ref; + } + + public: + + //! Constructor + reserving_port() : reserved(false) { + my_join = NULL; + my_predecessors.set_owner( this ); + my_aggregator.initialize_handler(handler_type(this)); + } + + // copy constructor + reserving_port(const reserving_port& /* other */) : receiver() { + reserved = false; + my_join = NULL; + my_predecessors.set_owner( this ); + my_aggregator.initialize_handler(handler_type(this)); + } + + void set_join_node_pointer(forwarding_base *join) { + my_join = join; + } + + //! Add a predecessor + bool register_predecessor( predecessor_type &src ) __TBB_override { + reserving_port_operation op_data(src, reg_pred); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + //! Remove a predecessor + bool remove_predecessor( predecessor_type &src ) __TBB_override { + reserving_port_operation op_data(src, rem_pred); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + //! Reserve an item from the port + bool reserve( T &v ) { + reserving_port_operation op_data(v, res_item); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + //! Release the port + void release( ) { + reserving_port_operation op_data(rel_res); + my_aggregator.execute(&op_data); + } + + //! Complete use of the port + void consume( ) { + reserving_port_operation op_data(con_res); + my_aggregator.execute(&op_data); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + built_predecessors_type &built_predecessors() __TBB_override { return my_predecessors.built_predecessors(); } + void internal_add_built_predecessor(predecessor_type &src) __TBB_override { + reserving_port_operation op_data(src, add_blt_pred); + my_aggregator.execute(&op_data); + } + + void internal_delete_built_predecessor(predecessor_type &src) __TBB_override { + reserving_port_operation op_data(src, del_blt_pred); + my_aggregator.execute(&op_data); + } + + size_t predecessor_count() __TBB_override { + reserving_port_operation op_data(blt_pred_cnt); + my_aggregator.execute(&op_data); + return op_data.cnt_val; + } + + void copy_predecessors(predecessor_list_type &l) __TBB_override { + reserving_port_operation op_data(blt_pred_cpy); + op_data.plist = &l; + my_aggregator.execute(&op_data); + } + + void extract_receiver() { + my_predecessors.built_predecessors().receiver_extract(*this); + } + +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + void reset_receiver( reset_flags f) __TBB_override { + if(f & rf_clear_edges) my_predecessors.clear(); + else + my_predecessors.reset(); + reserved = false; + __TBB_ASSERT(!(f&rf_clear_edges) || my_predecessors.empty(), "port edges not removed"); + } + + private: +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + friend class get_graph_helper; +#endif + + forwarding_base *my_join; + reservable_predecessor_cache< T, null_mutex > my_predecessors; + bool reserved; + }; // reserving_port + + //! queueing join_port + template + class queueing_port : public receiver, public item_buffer { + public: + typedef T input_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef queueing_port class_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename receiver::built_predecessors_type built_predecessors_type; + typedef typename receiver::predecessor_list_type predecessor_list_type; +#endif + + // ----------- Aggregator ------------ + private: + enum op_type { get__item, res_port, try__put_task +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy +#endif + }; + + class queueing_port_operation : public aggregated_operation { + public: + char type; + T my_val; + T *my_arg; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + predecessor_type *pred; + size_t cnt_val; + predecessor_list_type *plist; +#endif + task * bypass_t; + // constructor for value parameter + queueing_port_operation(const T& e, op_type t) : + type(char(t)), my_val(e) + , bypass_t(NULL) + {} + // constructor for pointer parameter + queueing_port_operation(const T* p, op_type t) : + type(char(t)), my_arg(const_cast(p)) + , bypass_t(NULL) + {} + // constructor with no parameter + queueing_port_operation(op_type t) : type(char(t)) + , bypass_t(NULL) + {} + }; + + typedef internal::aggregating_functor handler_type; + friend class internal::aggregating_functor; + aggregator my_aggregator; + + void handle_operations(queueing_port_operation* op_list) { + queueing_port_operation *current; + bool was_empty; + while(op_list) { + current = op_list; + op_list = op_list->next; + switch(current->type) { + case try__put_task: { + task *rtask = NULL; + was_empty = this->buffer_empty(); + this->push_back(current->my_val); + if (was_empty) rtask = my_join->decrement_port_count(false); + else + rtask = SUCCESSFULLY_ENQUEUED; + current->bypass_t = rtask; + __TBB_store_with_release(current->status, SUCCEEDED); + } + break; + case get__item: + if(!this->buffer_empty()) { + *(current->my_arg) = this->front(); + __TBB_store_with_release(current->status, SUCCEEDED); + } + else { + __TBB_store_with_release(current->status, FAILED); + } + break; + case res_port: + __TBB_ASSERT(this->my_item_valid(this->my_head), "No item to reset"); + this->destroy_front(); + if(this->my_item_valid(this->my_head)) { + (void)my_join->decrement_port_count(true); + } + __TBB_store_with_release(current->status, SUCCEEDED); + break; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + case add_blt_pred: + my_built_predecessors.add_edge(*(current->pred)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case del_blt_pred: + my_built_predecessors.delete_edge(*(current->pred)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_pred_cnt: + current->cnt_val = my_built_predecessors.edge_count(); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_pred_cpy: + my_built_predecessors.copy_edges(*(current->plist)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + } + } + } + // ------------ End Aggregator --------------- + + protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + task *try_put_task(const T &v) __TBB_override { + queueing_port_operation op_data(v, try__put_task); + my_aggregator.execute(&op_data); + __TBB_ASSERT(op_data.status == SUCCEEDED || !op_data.bypass_t, "inconsistent return from aggregator"); + if(!op_data.bypass_t) return SUCCESSFULLY_ENQUEUED; + return op_data.bypass_t; + } + + graph& graph_reference() const __TBB_override { + return my_join->graph_ref; + } + + public: + + //! Constructor + queueing_port() : item_buffer() { + my_join = NULL; + my_aggregator.initialize_handler(handler_type(this)); + } + + //! copy constructor + queueing_port(const queueing_port& /* other */) : receiver(), item_buffer() { + my_join = NULL; + my_aggregator.initialize_handler(handler_type(this)); + } + + //! record parent for tallying available items + void set_join_node_pointer(forwarding_base *join) { + my_join = join; + } + + bool get_item( T &v ) { + queueing_port_operation op_data(&v, get__item); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + // reset_port is called when item is accepted by successor, but + // is initiated by join_node. + void reset_port() { + queueing_port_operation op_data(res_port); + my_aggregator.execute(&op_data); + return; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + + void internal_add_built_predecessor(predecessor_type &p) __TBB_override { + queueing_port_operation op_data(add_blt_pred); + op_data.pred = &p; + my_aggregator.execute(&op_data); + } + + void internal_delete_built_predecessor(predecessor_type &p) __TBB_override { + queueing_port_operation op_data(del_blt_pred); + op_data.pred = &p; + my_aggregator.execute(&op_data); + } + + size_t predecessor_count() __TBB_override { + queueing_port_operation op_data(blt_pred_cnt); + my_aggregator.execute(&op_data); + return op_data.cnt_val; + } + + void copy_predecessors(predecessor_list_type &l) __TBB_override { + queueing_port_operation op_data(blt_pred_cpy); + op_data.plist = &l; + my_aggregator.execute(&op_data); + } + + void extract_receiver() { + item_buffer::reset(); + my_built_predecessors.receiver_extract(*this); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + void reset_receiver(reset_flags f) __TBB_override { + tbb::internal::suppress_unused_warning(f); + item_buffer::reset(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + if (f & rf_clear_edges) + my_built_predecessors.clear(); +#endif + } + + private: +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + friend class get_graph_helper; +#endif + + forwarding_base *my_join; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + edge_container my_built_predecessors; +#endif + }; // queueing_port + +#include "_flow_graph_tagged_buffer_impl.h" + + template + struct count_element { + K my_key; + size_t my_value; + }; + + // method to access the key in the counting table + // the ref has already been removed from K + template< typename K > + struct key_to_count_functor { + typedef count_element table_item_type; + const K& operator()(const table_item_type& v) { return v.my_key; } + }; + + // the ports can have only one template parameter. We wrap the types needed in + // a traits type + template< class TraitsType > + class key_matching_port : + public receiver, + public hash_buffer< typename TraitsType::K, typename TraitsType::T, typename TraitsType::TtoK, + typename TraitsType::KHash > { + public: + typedef TraitsType traits; + typedef key_matching_port class_type; + typedef typename TraitsType::T input_type; + typedef typename TraitsType::K key_type; + typedef typename tbb::internal::strip::type noref_key_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef typename TraitsType::TtoK type_to_key_func_type; + typedef typename TraitsType::KHash hash_compare_type; + typedef hash_buffer< key_type, input_type, type_to_key_func_type, hash_compare_type > buffer_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename receiver::built_predecessors_type built_predecessors_type; + typedef typename receiver::predecessor_list_type predecessor_list_type; +#endif + private: +// ----------- Aggregator ------------ + private: + enum op_type { try__put, get__item, res_port +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy +#endif + }; + + class key_matching_port_operation : public aggregated_operation { + public: + char type; + input_type my_val; + input_type *my_arg; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + predecessor_type *pred; + size_t cnt_val; + predecessor_list_type *plist; +#endif + // constructor for value parameter + key_matching_port_operation(const input_type& e, op_type t) : + type(char(t)), my_val(e) {} + // constructor for pointer parameter + key_matching_port_operation(const input_type* p, op_type t) : + type(char(t)), my_arg(const_cast(p)) {} + // constructor with no parameter + key_matching_port_operation(op_type t) : type(char(t)) {} + }; + + typedef internal::aggregating_functor handler_type; + friend class internal::aggregating_functor; + aggregator my_aggregator; + + void handle_operations(key_matching_port_operation* op_list) { + key_matching_port_operation *current; + while(op_list) { + current = op_list; + op_list = op_list->next; + switch(current->type) { + case try__put: { + bool was_inserted = this->insert_with_key(current->my_val); + // return failure if a duplicate insertion occurs + __TBB_store_with_release(current->status, was_inserted ? SUCCEEDED : FAILED); + } + break; + case get__item: + // use current_key from FE for item + if(!this->find_with_key(my_join->current_key, *(current->my_arg))) { + __TBB_ASSERT(false, "Failed to find item corresponding to current_key."); + } + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case res_port: + // use current_key from FE for item + this->delete_with_key(my_join->current_key); + __TBB_store_with_release(current->status, SUCCEEDED); + break; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + case add_blt_pred: + my_built_predecessors.add_edge(*(current->pred)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case del_blt_pred: + my_built_predecessors.delete_edge(*(current->pred)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_pred_cnt: + current->cnt_val = my_built_predecessors.edge_count(); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_pred_cpy: + my_built_predecessors.copy_edges(*(current->plist)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; +#endif + } + } + } +// ------------ End Aggregator --------------- + protected: + template< typename R, typename B > friend class run_and_put_task; + template friend class internal::broadcast_cache; + template friend class internal::round_robin_cache; + task *try_put_task(const input_type& v) __TBB_override { + key_matching_port_operation op_data(v, try__put); + task *rtask = NULL; + my_aggregator.execute(&op_data); + if(op_data.status == SUCCEEDED) { + rtask = my_join->increment_key_count((*(this->get_key_func()))(v), false); // may spawn + // rtask has to reflect the return status of the try_put + if(!rtask) rtask = SUCCESSFULLY_ENQUEUED; + } + return rtask; + } + + graph& graph_reference() const __TBB_override { + return my_join->graph_ref; + } + + public: + + key_matching_port() : receiver(), buffer_type() { + my_join = NULL; + my_aggregator.initialize_handler(handler_type(this)); + } + + // copy constructor + key_matching_port(const key_matching_port& /*other*/) : receiver(), buffer_type() { + my_join = NULL; + my_aggregator.initialize_handler(handler_type(this)); + } + + ~key_matching_port() { } + + void set_join_node_pointer(forwarding_base *join) { + my_join = dynamic_cast*>(join); + } + + void set_my_key_func(type_to_key_func_type *f) { this->set_key_func(f); } + + type_to_key_func_type* get_my_key_func() { return this->get_key_func(); } + + bool get_item( input_type &v ) { + // aggregator uses current_key from FE for Key + key_matching_port_operation op_data(&v, get__item); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; } + + void internal_add_built_predecessor(predecessor_type &p) __TBB_override { + key_matching_port_operation op_data(add_blt_pred); + op_data.pred = &p; + my_aggregator.execute(&op_data); + } + + void internal_delete_built_predecessor(predecessor_type &p) __TBB_override { + key_matching_port_operation op_data(del_blt_pred); + op_data.pred = &p; + my_aggregator.execute(&op_data); + } + + size_t predecessor_count() __TBB_override { + key_matching_port_operation op_data(blt_pred_cnt); + my_aggregator.execute(&op_data); + return op_data.cnt_val; + } + + void copy_predecessors(predecessor_list_type &l) __TBB_override { + key_matching_port_operation op_data(blt_pred_cpy); + op_data.plist = &l; + my_aggregator.execute(&op_data); + } +#endif + + // reset_port is called when item is accepted by successor, but + // is initiated by join_node. + void reset_port() { + key_matching_port_operation op_data(res_port); + my_aggregator.execute(&op_data); + return; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract_receiver() { + buffer_type::reset(); + my_built_predecessors.receiver_extract(*this); + } +#endif + void reset_receiver(reset_flags f ) __TBB_override { + tbb::internal::suppress_unused_warning(f); + buffer_type::reset(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + if (f & rf_clear_edges) + my_built_predecessors.clear(); +#endif + } + + private: + // my_join forwarding base used to count number of inputs that + // received key. + matching_forwarding_base *my_join; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + edge_container my_built_predecessors; +#endif + }; // key_matching_port + + using namespace graph_policy_namespace; + + template + class join_node_base; + + //! join_node_FE : implements input port policy + template + class join_node_FE; + + template + class join_node_FE : public forwarding_base { + public: + static const int N = tbb::flow::tuple_size::value; + typedef OutputTuple output_type; + typedef InputTuple input_type; + typedef join_node_base base_node_type; // for forwarding + + join_node_FE(graph &g) : forwarding_base(g), my_node(NULL) { + ports_with_no_inputs = N; + join_helper::set_join_node_pointer(my_inputs, this); + } + + join_node_FE(const join_node_FE& other) : forwarding_base((other.forwarding_base::graph_ref)), my_node(NULL) { + ports_with_no_inputs = N; + join_helper::set_join_node_pointer(my_inputs, this); + } + + void set_my_node(base_node_type *new_my_node) { my_node = new_my_node; } + + void increment_port_count() __TBB_override { + ++ports_with_no_inputs; + } + + // if all input_ports have predecessors, spawn forward to try and consume tuples + task * decrement_port_count(bool handle_task) __TBB_override { + if(ports_with_no_inputs.fetch_and_decrement() == 1) { + if(internal::is_graph_active(this->graph_ref)) { + task *rtask = new ( task::allocate_additional_child_of( *(this->graph_ref.root_task()) ) ) + forward_task_bypass(*my_node); + if(!handle_task) return rtask; + internal::spawn_in_graph_arena(this->graph_ref, *rtask); + } + } + return NULL; + } + + input_type &input_ports() { return my_inputs; } + + protected: + + void reset( reset_flags f) { + // called outside of parallel contexts + ports_with_no_inputs = N; + join_helper::reset_inputs(my_inputs, f); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract( ) { + // called outside of parallel contexts + ports_with_no_inputs = N; + join_helper::extract_inputs(my_inputs); + } +#endif + + // all methods on input ports should be called under mutual exclusion from join_node_base. + + bool tuple_build_may_succeed() { + return !ports_with_no_inputs; + } + + bool try_to_make_tuple(output_type &out) { + if(ports_with_no_inputs) return false; + return join_helper::reserve(my_inputs, out); + } + + void tuple_accepted() { + join_helper::consume_reservations(my_inputs); + } + void tuple_rejected() { + join_helper::release_reservations(my_inputs); + } + + input_type my_inputs; + base_node_type *my_node; + atomic ports_with_no_inputs; + }; // join_node_FE + + template + class join_node_FE : public forwarding_base { + public: + static const int N = tbb::flow::tuple_size::value; + typedef OutputTuple output_type; + typedef InputTuple input_type; + typedef join_node_base base_node_type; // for forwarding + + join_node_FE(graph &g) : forwarding_base(g), my_node(NULL) { + ports_with_no_items = N; + join_helper::set_join_node_pointer(my_inputs, this); + } + + join_node_FE(const join_node_FE& other) : forwarding_base((other.forwarding_base::graph_ref)), my_node(NULL) { + ports_with_no_items = N; + join_helper::set_join_node_pointer(my_inputs, this); + } + + // needed for forwarding + void set_my_node(base_node_type *new_my_node) { my_node = new_my_node; } + + void reset_port_count() { + ports_with_no_items = N; + } + + // if all input_ports have items, spawn forward to try and consume tuples + task * decrement_port_count(bool handle_task) __TBB_override + { + if(ports_with_no_items.fetch_and_decrement() == 1) { + if(internal::is_graph_active(this->graph_ref)) { + task *rtask = new ( task::allocate_additional_child_of( *(this->graph_ref.root_task()) ) ) + forward_task_bypass (*my_node); + if(!handle_task) return rtask; + internal::spawn_in_graph_arena(this->graph_ref, *rtask); + } + } + return NULL; + } + + void increment_port_count() __TBB_override { __TBB_ASSERT(false, NULL); } // should never be called + + input_type &input_ports() { return my_inputs; } + + protected: + + void reset( reset_flags f) { + reset_port_count(); + join_helper::reset_inputs(my_inputs, f ); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract() { + reset_port_count(); + join_helper::extract_inputs(my_inputs); + } +#endif + // all methods on input ports should be called under mutual exclusion from join_node_base. + + bool tuple_build_may_succeed() { + return !ports_with_no_items; + } + + bool try_to_make_tuple(output_type &out) { + if(ports_with_no_items) return false; + return join_helper::get_items(my_inputs, out); + } + + void tuple_accepted() { + reset_port_count(); + join_helper::reset_ports(my_inputs); + } + void tuple_rejected() { + // nothing to do. + } + + input_type my_inputs; + base_node_type *my_node; + atomic ports_with_no_items; + }; // join_node_FE + + // key_matching join front-end. + template + class join_node_FE, InputTuple, OutputTuple> : public matching_forwarding_base, + // buffer of key value counts + public hash_buffer< // typedefed below to key_to_count_buffer_type + typename tbb::internal::strip::type&, // force ref type on K + count_element::type>, + internal::type_to_key_function_body< + count_element::type>, + typename tbb::internal::strip::type& >, + KHash >, + // buffer of output items + public item_buffer { + public: + static const int N = tbb::flow::tuple_size::value; + typedef OutputTuple output_type; + typedef InputTuple input_type; + typedef K key_type; + typedef typename tbb::internal::strip::type unref_key_type; + typedef KHash key_hash_compare; + // must use K without ref. + typedef count_element count_element_type; + // method that lets us refer to the key of this type. + typedef key_to_count_functor key_to_count_func; + typedef internal::type_to_key_function_body< count_element_type, unref_key_type&> TtoK_function_body_type; + typedef internal::type_to_key_function_body_leaf TtoK_function_body_leaf_type; + // this is the type of the special table that keeps track of the number of discrete + // elements corresponding to each key that we've seen. + typedef hash_buffer< unref_key_type&, count_element_type, TtoK_function_body_type, key_hash_compare > + key_to_count_buffer_type; + typedef item_buffer output_buffer_type; + typedef join_node_base, InputTuple, OutputTuple> base_node_type; // for forwarding + typedef matching_forwarding_base forwarding_base_type; + +// ----------- Aggregator ------------ + // the aggregator is only needed to serialize the access to the hash table. + // and the output_buffer_type base class + private: + enum op_type { res_count, inc_count, may_succeed, try_make }; + typedef join_node_FE, InputTuple, OutputTuple> class_type; + + class key_matching_FE_operation : public aggregated_operation { + public: + char type; + unref_key_type my_val; + output_type* my_output; + task *bypass_t; + bool enqueue_task; + // constructor for value parameter + key_matching_FE_operation(const unref_key_type& e , bool q_task , op_type t) : type(char(t)), my_val(e), + my_output(NULL), bypass_t(NULL), enqueue_task(q_task) {} + key_matching_FE_operation(output_type *p, op_type t) : type(char(t)), my_output(p), bypass_t(NULL), + enqueue_task(true) {} + // constructor with no parameter + key_matching_FE_operation(op_type t) : type(char(t)), my_output(NULL), bypass_t(NULL), enqueue_task(true) {} + }; + + typedef internal::aggregating_functor handler_type; + friend class internal::aggregating_functor; + aggregator my_aggregator; + + // called from aggregator, so serialized + // returns a task pointer if the a task would have been enqueued but we asked that + // it be returned. Otherwise returns NULL. + task * fill_output_buffer(unref_key_type &t, bool should_enqueue, bool handle_task) { + output_type l_out; + task *rtask = NULL; + bool do_fwd = should_enqueue && this->buffer_empty() && internal::is_graph_active(this->graph_ref); + this->current_key = t; + this->delete_with_key(this->current_key); // remove the key + if(join_helper::get_items(my_inputs, l_out)) { // <== call back + this->push_back(l_out); + if(do_fwd) { // we enqueue if receiving an item from predecessor, not if successor asks for item + rtask = new ( task::allocate_additional_child_of( *(this->graph_ref.root_task()) ) ) + forward_task_bypass(*my_node); + if(handle_task) { + internal::spawn_in_graph_arena(this->graph_ref, *rtask); + rtask = NULL; + } + do_fwd = false; + } + // retire the input values + join_helper::reset_ports(my_inputs); // <== call back + } + else { + __TBB_ASSERT(false, "should have had something to push"); + } + return rtask; + } + + void handle_operations(key_matching_FE_operation* op_list) { + key_matching_FE_operation *current; + while(op_list) { + current = op_list; + op_list = op_list->next; + switch(current->type) { + case res_count: // called from BE + { + this->destroy_front(); + __TBB_store_with_release(current->status, SUCCEEDED); + } + break; + case inc_count: { // called from input ports + count_element_type *p = 0; + unref_key_type &t = current->my_val; + bool do_enqueue = current->enqueue_task; + if(!(this->find_ref_with_key(t,p))) { + count_element_type ev; + ev.my_key = t; + ev.my_value = 0; + this->insert_with_key(ev); + if(!(this->find_ref_with_key(t,p))) { + __TBB_ASSERT(false, "should find key after inserting it"); + } + } + if(++(p->my_value) == size_t(N)) { + task *rtask = fill_output_buffer(t, true, do_enqueue); + __TBB_ASSERT(!rtask || !do_enqueue, "task should not be returned"); + current->bypass_t = rtask; + } + } + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case may_succeed: // called from BE + __TBB_store_with_release(current->status, this->buffer_empty() ? FAILED : SUCCEEDED); + break; + case try_make: // called from BE + if(this->buffer_empty()) { + __TBB_store_with_release(current->status, FAILED); + } + else { + *(current->my_output) = this->front(); + __TBB_store_with_release(current->status, SUCCEEDED); + } + break; + } + } + } +// ------------ End Aggregator --------------- + + public: + template + join_node_FE(graph &g, FunctionTuple &TtoK_funcs) : forwarding_base_type(g), my_node(NULL) { + join_helper::set_join_node_pointer(my_inputs, this); + join_helper::set_key_functors(my_inputs, TtoK_funcs); + my_aggregator.initialize_handler(handler_type(this)); + TtoK_function_body_type *cfb = new TtoK_function_body_leaf_type(key_to_count_func()); + this->set_key_func(cfb); + } + + join_node_FE(const join_node_FE& other) : forwarding_base_type((other.forwarding_base_type::graph_ref)), key_to_count_buffer_type(), + output_buffer_type() { + my_node = NULL; + join_helper::set_join_node_pointer(my_inputs, this); + join_helper::copy_key_functors(my_inputs, const_cast(other.my_inputs)); + my_aggregator.initialize_handler(handler_type(this)); + TtoK_function_body_type *cfb = new TtoK_function_body_leaf_type(key_to_count_func()); + this->set_key_func(cfb); + } + + // needed for forwarding + void set_my_node(base_node_type *new_my_node) { my_node = new_my_node; } + + void reset_port_count() { // called from BE + key_matching_FE_operation op_data(res_count); + my_aggregator.execute(&op_data); + return; + } + + // if all input_ports have items, spawn forward to try and consume tuples + // return a task if we are asked and did create one. + task *increment_key_count(unref_key_type const & t, bool handle_task) __TBB_override { // called from input_ports + key_matching_FE_operation op_data(t, handle_task, inc_count); + my_aggregator.execute(&op_data); + return op_data.bypass_t; + } + + task *decrement_port_count(bool /*handle_task*/) __TBB_override { __TBB_ASSERT(false, NULL); return NULL; } + + void increment_port_count() __TBB_override { __TBB_ASSERT(false, NULL); } // should never be called + + input_type &input_ports() { return my_inputs; } + + protected: + + void reset( reset_flags f ) { + // called outside of parallel contexts + join_helper::reset_inputs(my_inputs, f); + + key_to_count_buffer_type::reset(); + output_buffer_type::reset(); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract() { + // called outside of parallel contexts + join_helper::extract_inputs(my_inputs); + key_to_count_buffer_type::reset(); // have to reset the tag counts + output_buffer_type::reset(); // also the queue of outputs + // my_node->current_tag = NO_TAG; + } +#endif + // all methods on input ports should be called under mutual exclusion from join_node_base. + + bool tuple_build_may_succeed() { // called from back-end + key_matching_FE_operation op_data(may_succeed); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + // cannot lock while calling back to input_ports. current_key will only be set + // and reset under the aggregator, so it will remain consistent. + bool try_to_make_tuple(output_type &out) { + key_matching_FE_operation op_data(&out,try_make); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + void tuple_accepted() { + reset_port_count(); // reset current_key after ports reset. + } + + void tuple_rejected() { + // nothing to do. + } + + input_type my_inputs; // input ports + base_node_type *my_node; + }; // join_node_FE, InputTuple, OutputTuple> + + //! join_node_base + template + class join_node_base : public graph_node, public join_node_FE, + public sender { + protected: + using graph_node::my_graph; + public: + typedef OutputTuple output_type; + + typedef typename sender::successor_type successor_type; + typedef join_node_FE input_ports_type; + using input_ports_type::tuple_build_may_succeed; + using input_ports_type::try_to_make_tuple; + using input_ports_type::tuple_accepted; + using input_ports_type::tuple_rejected; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename sender::built_successors_type built_successors_type; + typedef typename sender::successor_list_type successor_list_type; +#endif + + private: + // ----------- Aggregator ------------ + enum op_type { reg_succ, rem_succ, try__get, do_fwrd, do_fwrd_bypass +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + , add_blt_succ, del_blt_succ, blt_succ_cnt, blt_succ_cpy +#endif + }; + typedef join_node_base class_type; + + class join_node_base_operation : public aggregated_operation { + public: + char type; + union { + output_type *my_arg; + successor_type *my_succ; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + size_t cnt_val; + successor_list_type *slist; +#endif + }; + task *bypass_t; + join_node_base_operation(const output_type& e, op_type t) : type(char(t)), + my_arg(const_cast(&e)), bypass_t(NULL) {} + join_node_base_operation(const successor_type &s, op_type t) : type(char(t)), + my_succ(const_cast(&s)), bypass_t(NULL) {} + join_node_base_operation(op_type t) : type(char(t)), bypass_t(NULL) {} + }; + + typedef internal::aggregating_functor handler_type; + friend class internal::aggregating_functor; + bool forwarder_busy; + aggregator my_aggregator; + + void handle_operations(join_node_base_operation* op_list) { + join_node_base_operation *current; + while(op_list) { + current = op_list; + op_list = op_list->next; + switch(current->type) { + case reg_succ: { + my_successors.register_successor(*(current->my_succ)); + if(tuple_build_may_succeed() && !forwarder_busy && internal::is_graph_active(my_graph)) { + task *rtask = new ( task::allocate_additional_child_of(*(my_graph.root_task())) ) + forward_task_bypass + >(*this); + internal::spawn_in_graph_arena(my_graph, *rtask); + forwarder_busy = true; + } + __TBB_store_with_release(current->status, SUCCEEDED); + } + break; + case rem_succ: + my_successors.remove_successor(*(current->my_succ)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case try__get: + if(tuple_build_may_succeed()) { + if(try_to_make_tuple(*(current->my_arg))) { + tuple_accepted(); + __TBB_store_with_release(current->status, SUCCEEDED); + } + else __TBB_store_with_release(current->status, FAILED); + } + else __TBB_store_with_release(current->status, FAILED); + break; + case do_fwrd_bypass: { + bool build_succeeded; + task *last_task = NULL; + output_type out; + if(tuple_build_may_succeed()) { // checks output queue of FE + do { + build_succeeded = try_to_make_tuple(out); // fetch front_end of queue + if(build_succeeded) { + task *new_task = my_successors.try_put_task(out); + last_task = combine_tasks(my_graph, last_task, new_task); + if(new_task) { + tuple_accepted(); + } + else { + tuple_rejected(); + build_succeeded = false; + } + } + } while(build_succeeded); + } + current->bypass_t = last_task; + __TBB_store_with_release(current->status, SUCCEEDED); + forwarder_busy = false; + } + break; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + case add_blt_succ: + my_successors.internal_add_built_successor(*(current->my_succ)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case del_blt_succ: + my_successors.internal_delete_built_successor(*(current->my_succ)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_succ_cnt: + current->cnt_val = my_successors.successor_count(); + __TBB_store_with_release(current->status, SUCCEEDED); + break; + case blt_succ_cpy: + my_successors.copy_successors(*(current->slist)); + __TBB_store_with_release(current->status, SUCCEEDED); + break; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + } + } + } + // ---------- end aggregator ----------- + public: + join_node_base(graph &g) : graph_node(g), input_ports_type(g), forwarder_busy(false) { + my_successors.set_owner(this); + input_ports_type::set_my_node(this); + my_aggregator.initialize_handler(handler_type(this)); + } + + join_node_base(const join_node_base& other) : + graph_node(other.graph_node::my_graph), input_ports_type(other), + sender(), forwarder_busy(false), my_successors() { + my_successors.set_owner(this); + input_ports_type::set_my_node(this); + my_aggregator.initialize_handler(handler_type(this)); + } + + template + join_node_base(graph &g, FunctionTuple f) : graph_node(g), input_ports_type(g, f), forwarder_busy(false) { + my_successors.set_owner(this); + input_ports_type::set_my_node(this); + my_aggregator.initialize_handler(handler_type(this)); + } + + bool register_successor(successor_type &r) __TBB_override { + join_node_base_operation op_data(r, reg_succ); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + bool remove_successor( successor_type &r) __TBB_override { + join_node_base_operation op_data(r, rem_succ); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + + bool try_get( output_type &v) __TBB_override { + join_node_base_operation op_data(v, try__get); + my_aggregator.execute(&op_data); + return op_data.status == SUCCEEDED; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); } + + void internal_add_built_successor( successor_type &r) __TBB_override { + join_node_base_operation op_data(r, add_blt_succ); + my_aggregator.execute(&op_data); + } + + void internal_delete_built_successor( successor_type &r) __TBB_override { + join_node_base_operation op_data(r, del_blt_succ); + my_aggregator.execute(&op_data); + } + + size_t successor_count() __TBB_override { + join_node_base_operation op_data(blt_succ_cnt); + my_aggregator.execute(&op_data); + return op_data.cnt_val; + } + + void copy_successors(successor_list_type &l) __TBB_override { + join_node_base_operation op_data(blt_succ_cpy); + op_data.slist = &l; + my_aggregator.execute(&op_data); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract() __TBB_override { + input_ports_type::extract(); + my_successors.built_successors().sender_extract(*this); + } +#endif + + protected: + + void reset_node(reset_flags f) __TBB_override { + input_ports_type::reset(f); + if(f & rf_clear_edges) my_successors.clear(); + } + + private: + broadcast_cache my_successors; + + friend class forward_task_bypass< join_node_base >; + task *forward_task() { + join_node_base_operation op_data(do_fwrd_bypass); + my_aggregator.execute(&op_data); + return op_data.bypass_t; + } + + }; // join_node_base + + // join base class type generator + template class PT, typename OutputTuple, typename JP> + struct join_base { + typedef typename internal::join_node_base::type, OutputTuple> type; + }; + + template + struct join_base > { + typedef key_matching key_traits_type; + typedef K key_type; + typedef KHash key_hash_compare; + typedef typename internal::join_node_base< key_traits_type, + // ports type + typename wrap_key_tuple_elements::type, + OutputTuple > type; + }; + + //! unfolded_join_node : passes input_ports_type to join_node_base. We build the input port type + // using tuple_element. The class PT is the port type (reserving_port, queueing_port, key_matching_port) + // and should match the typename. + + template class PT, typename OutputTuple, typename JP> + class unfolded_join_node : public join_base::type { + public: + typedef typename wrap_tuple_elements::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base base_type; + public: + unfolded_join_node(graph &g) : base_type(g) {} + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; + +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + template + struct key_from_message_body { + K operator()(const T& t) const { + using tbb::flow::key_from_message; + return key_from_message(t); + } + }; + // Adds const to reference type + template + struct key_from_message_body { + const K& operator()(const T& t) const { + using tbb::flow::key_from_message; + return key_from_message(t); + } + }; +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + // key_matching unfolded_join_node. This must be a separate specialization because the constructors + // differ. + + template + class unfolded_join_node<2,key_matching_port,OutputTuple,key_matching > : public + join_base<2,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + public: + typedef typename wrap_key_tuple_elements<2,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base, input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename tbb::flow::tuple< f0_p, f1_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 2, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; + + template + class unfolded_join_node<3,key_matching_port,OutputTuple,key_matching > : public + join_base<3,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; + public: + typedef typename wrap_key_tuple_elements<3,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base, input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename internal::type_to_key_function_body *f2_p; + typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1), + new internal::type_to_key_function_body_leaf(body2) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 3, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; + + template + class unfolded_join_node<4,key_matching_port,OutputTuple,key_matching > : public + join_base<4,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; + typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; + public: + typedef typename wrap_key_tuple_elements<4,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base, input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename internal::type_to_key_function_body *f2_p; + typedef typename internal::type_to_key_function_body *f3_p; + typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1), + new internal::type_to_key_function_body_leaf(body2), + new internal::type_to_key_function_body_leaf(body3) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 4, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; + + template + class unfolded_join_node<5,key_matching_port,OutputTuple,key_matching > : public + join_base<5,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; + typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; + typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; + public: + typedef typename wrap_key_tuple_elements<5,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base , input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename internal::type_to_key_function_body *f2_p; + typedef typename internal::type_to_key_function_body *f3_p; + typedef typename internal::type_to_key_function_body *f4_p; + typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1), + new internal::type_to_key_function_body_leaf(body2), + new internal::type_to_key_function_body_leaf(body3), + new internal::type_to_key_function_body_leaf(body4) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 5, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; + +#if __TBB_VARIADIC_MAX >= 6 + template + class unfolded_join_node<6,key_matching_port,OutputTuple,key_matching > : public + join_base<6,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; + typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; + typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; + typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; + public: + typedef typename wrap_key_tuple_elements<6,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base , input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename internal::type_to_key_function_body *f2_p; + typedef typename internal::type_to_key_function_body *f3_p; + typedef typename internal::type_to_key_function_body *f4_p; + typedef typename internal::type_to_key_function_body *f5_p; + typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, Body5 body5) + : base_type(g, func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1), + new internal::type_to_key_function_body_leaf(body2), + new internal::type_to_key_function_body_leaf(body3), + new internal::type_to_key_function_body_leaf(body4), + new internal::type_to_key_function_body_leaf(body5) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 6, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; +#endif + +#if __TBB_VARIADIC_MAX >= 7 + template + class unfolded_join_node<7,key_matching_port,OutputTuple,key_matching > : public + join_base<7,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; + typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; + typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; + typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; + typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; + public: + typedef typename wrap_key_tuple_elements<7,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base , input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename internal::type_to_key_function_body *f2_p; + typedef typename internal::type_to_key_function_body *f3_p; + typedef typename internal::type_to_key_function_body *f4_p; + typedef typename internal::type_to_key_function_body *f5_p; + typedef typename internal::type_to_key_function_body *f6_p; + typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, + Body5 body5, Body6 body6) : base_type(g, func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1), + new internal::type_to_key_function_body_leaf(body2), + new internal::type_to_key_function_body_leaf(body3), + new internal::type_to_key_function_body_leaf(body4), + new internal::type_to_key_function_body_leaf(body5), + new internal::type_to_key_function_body_leaf(body6) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 7, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; +#endif + +#if __TBB_VARIADIC_MAX >= 8 + template + class unfolded_join_node<8,key_matching_port,OutputTuple,key_matching > : public + join_base<8,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; + typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; + typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; + typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; + typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; + typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; + public: + typedef typename wrap_key_tuple_elements<8,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base , input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename internal::type_to_key_function_body *f2_p; + typedef typename internal::type_to_key_function_body *f3_p; + typedef typename internal::type_to_key_function_body *f4_p; + typedef typename internal::type_to_key_function_body *f5_p; + typedef typename internal::type_to_key_function_body *f6_p; + typedef typename internal::type_to_key_function_body *f7_p; + typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, + Body5 body5, Body6 body6, Body7 body7) : base_type(g, func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1), + new internal::type_to_key_function_body_leaf(body2), + new internal::type_to_key_function_body_leaf(body3), + new internal::type_to_key_function_body_leaf(body4), + new internal::type_to_key_function_body_leaf(body5), + new internal::type_to_key_function_body_leaf(body6), + new internal::type_to_key_function_body_leaf(body7) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 8, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; +#endif + +#if __TBB_VARIADIC_MAX >= 9 + template + class unfolded_join_node<9,key_matching_port,OutputTuple,key_matching > : public + join_base<9,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; + typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; + typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; + typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; + typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; + typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; + typedef typename tbb::flow::tuple_element<8, OutputTuple>::type T8; + public: + typedef typename wrap_key_tuple_elements<9,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base , input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename internal::type_to_key_function_body *f2_p; + typedef typename internal::type_to_key_function_body *f3_p; + typedef typename internal::type_to_key_function_body *f4_p; + typedef typename internal::type_to_key_function_body *f5_p; + typedef typename internal::type_to_key_function_body *f6_p; + typedef typename internal::type_to_key_function_body *f7_p; + typedef typename internal::type_to_key_function_body *f8_p; + typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, + Body5 body5, Body6 body6, Body7 body7, Body8 body8) : base_type(g, func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1), + new internal::type_to_key_function_body_leaf(body2), + new internal::type_to_key_function_body_leaf(body3), + new internal::type_to_key_function_body_leaf(body4), + new internal::type_to_key_function_body_leaf(body5), + new internal::type_to_key_function_body_leaf(body6), + new internal::type_to_key_function_body_leaf(body7), + new internal::type_to_key_function_body_leaf(body8) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 9, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; +#endif + +#if __TBB_VARIADIC_MAX >= 10 + template + class unfolded_join_node<10,key_matching_port,OutputTuple,key_matching > : public + join_base<10,key_matching_port,OutputTuple,key_matching >::type { + typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0; + typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1; + typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2; + typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3; + typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4; + typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5; + typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6; + typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7; + typedef typename tbb::flow::tuple_element<8, OutputTuple>::type T8; + typedef typename tbb::flow::tuple_element<9, OutputTuple>::type T9; + public: + typedef typename wrap_key_tuple_elements<10,key_matching_port,key_matching,OutputTuple>::type input_ports_type; + typedef OutputTuple output_type; + private: + typedef join_node_base , input_ports_type, output_type > base_type; + typedef typename internal::type_to_key_function_body *f0_p; + typedef typename internal::type_to_key_function_body *f1_p; + typedef typename internal::type_to_key_function_body *f2_p; + typedef typename internal::type_to_key_function_body *f3_p; + typedef typename internal::type_to_key_function_body *f4_p; + typedef typename internal::type_to_key_function_body *f5_p; + typedef typename internal::type_to_key_function_body *f6_p; + typedef typename internal::type_to_key_function_body *f7_p; + typedef typename internal::type_to_key_function_body *f8_p; + typedef typename internal::type_to_key_function_body *f9_p; + typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p, f9_p > func_initializer_type; + public: +#if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING + unfolded_join_node(graph &g) : base_type(g, + func_initializer_type( + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()), + new internal::type_to_key_function_body_leaf >(key_from_message_body()) + ) ) { + } +#endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */ + template + unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, + Body5 body5, Body6 body6, Body7 body7, Body8 body8, Body9 body9) : base_type(g, func_initializer_type( + new internal::type_to_key_function_body_leaf(body0), + new internal::type_to_key_function_body_leaf(body1), + new internal::type_to_key_function_body_leaf(body2), + new internal::type_to_key_function_body_leaf(body3), + new internal::type_to_key_function_body_leaf(body4), + new internal::type_to_key_function_body_leaf(body5), + new internal::type_to_key_function_body_leaf(body6), + new internal::type_to_key_function_body_leaf(body7), + new internal::type_to_key_function_body_leaf(body8), + new internal::type_to_key_function_body_leaf(body9) + ) ) { + __TBB_STATIC_ASSERT(tbb::flow::tuple_size::value == 10, "wrong number of body initializers"); + } + unfolded_join_node(const unfolded_join_node &other) : base_type(other) {} + }; +#endif + + //! templated function to refer to input ports of the join node + template + typename tbb::flow::tuple_element::type &input_port(JNT &jn) { + return tbb::flow::get(jn.input_ports()); + } + +} +#endif // __TBB__flow_graph_join_impl_H + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_node_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_node_impl.h new file mode 100644 index 00000000..dbc56ecd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_node_impl.h @@ -0,0 +1,971 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__flow_graph_node_impl_H +#define __TBB__flow_graph_node_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#include "_flow_graph_item_buffer_impl.h" + +//! @cond INTERNAL +namespace internal { + + using tbb::internal::aggregated_operation; + using tbb::internal::aggregating_functor; + using tbb::internal::aggregator; + + template< typename T, typename A > + class function_input_queue : public item_buffer { + public: + bool empty() const { + return this->buffer_empty(); + } + + const T& front() const { + return this->item_buffer::front(); + } + + bool pop( T& t ) { + return this->pop_front( t ); + } + + void pop() { + this->destroy_front(); + } + + bool push( T& t ) { + return this->push_back( t ); + } + }; + + //! Input and scheduling for a function node that takes a type Input as input + // The only up-ref is apply_body_impl, which should implement the function + // call and any handling of the result. + template< typename Input, typename Policy, typename A, typename ImplType > + class function_input_base : public receiver, tbb::internal::no_assign { + enum op_type {reg_pred, rem_pred, try_fwd, tryput_bypass, app_body_bypass, occupy_concurrency +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + , add_blt_pred, del_blt_pred, + blt_pred_cnt, blt_pred_cpy // create vector copies of preds and succs +#endif + }; + typedef function_input_base class_type; + + public: + + //! The input type of this receiver + typedef Input input_type; + typedef typename receiver::predecessor_type predecessor_type; + typedef predecessor_cache predecessor_cache_type; + typedef function_input_queue input_queue_type; + typedef typename tbb::internal::allocator_rebind::type queue_allocator_type; + __TBB_STATIC_ASSERT(!((internal::has_policy::value) && (internal::has_policy::value)), + "queueing and rejecting policies can't be specified simultaneously"); + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename predecessor_cache_type::built_predecessors_type built_predecessors_type; + typedef typename receiver::predecessor_list_type predecessor_list_type; +#endif + + //! Constructor for function_input_base + function_input_base( + graph &g, __TBB_FLOW_GRAPH_PRIORITY_ARG1(size_t max_concurrency, node_priority_t priority) + ) : my_graph_ref(g), my_max_concurrency(max_concurrency) + , __TBB_FLOW_GRAPH_PRIORITY_ARG1(my_concurrency(0), my_priority(priority)) + , my_queue(!internal::has_policy::value ? new input_queue_type() : NULL) + , forwarder_busy(false) + { + my_predecessors.set_owner(this); + my_aggregator.initialize_handler(handler_type(this)); + } + + //! Copy constructor + function_input_base( const function_input_base& src) + : receiver(), tbb::internal::no_assign() + , my_graph_ref(src.my_graph_ref), my_max_concurrency(src.my_max_concurrency) + , __TBB_FLOW_GRAPH_PRIORITY_ARG1(my_concurrency(0), my_priority(src.my_priority)) + , my_queue(src.my_queue ? new input_queue_type() : NULL), forwarder_busy(false) + { + my_predecessors.set_owner(this); + my_aggregator.initialize_handler(handler_type(this)); + } + + //! Destructor + // The queue is allocated by the constructor for {multi}function_node. + // TODO: pass the graph_buffer_policy to the base so it can allocate the queue instead. + // This would be an interface-breaking change. + virtual ~function_input_base() { + if ( my_queue ) delete my_queue; + } + + task* try_put_task( const input_type& t) __TBB_override { + return try_put_task_impl(t, internal::has_policy()); + } + + //! Adds src to the list of cached predecessors. + bool register_predecessor( predecessor_type &src ) __TBB_override { + operation_type op_data(reg_pred); + op_data.r = &src; + my_aggregator.execute(&op_data); + return true; + } + + //! Removes src from the list of cached predecessors. + bool remove_predecessor( predecessor_type &src ) __TBB_override { + operation_type op_data(rem_pred); + op_data.r = &src; + my_aggregator.execute(&op_data); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + //! Adds to list of predecessors added by make_edge + void internal_add_built_predecessor( predecessor_type &src) __TBB_override { + operation_type op_data(add_blt_pred); + op_data.r = &src; + my_aggregator.execute(&op_data); + } + + //! removes from to list of predecessors (used by remove_edge) + void internal_delete_built_predecessor( predecessor_type &src) __TBB_override { + operation_type op_data(del_blt_pred); + op_data.r = &src; + my_aggregator.execute(&op_data); + } + + size_t predecessor_count() __TBB_override { + operation_type op_data(blt_pred_cnt); + my_aggregator.execute(&op_data); + return op_data.cnt_val; + } + + void copy_predecessors(predecessor_list_type &v) __TBB_override { + operation_type op_data(blt_pred_cpy); + op_data.predv = &v; + my_aggregator.execute(&op_data); + } + + built_predecessors_type &built_predecessors() __TBB_override { + return my_predecessors.built_predecessors(); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + protected: + + void reset_function_input_base( reset_flags f) { + my_concurrency = 0; + if(my_queue) { + my_queue->reset(); + } + reset_receiver(f); + forwarder_busy = false; + } + + graph& my_graph_ref; + const size_t my_max_concurrency; + size_t my_concurrency; + __TBB_FLOW_GRAPH_PRIORITY_EXPR( node_priority_t my_priority; ) + input_queue_type *my_queue; + predecessor_cache my_predecessors; + + void reset_receiver( reset_flags f) __TBB_override { + if( f & rf_clear_edges) my_predecessors.clear(); + else + my_predecessors.reset(); + __TBB_ASSERT(!(f & rf_clear_edges) || my_predecessors.empty(), "function_input_base reset failed"); + } + + graph& graph_reference() const __TBB_override { + return my_graph_ref; + } + + task* try_get_postponed_task(const input_type& i) { + operation_type op_data(i, app_body_bypass); // tries to pop an item or get_item + my_aggregator.execute(&op_data); + return op_data.bypass_t; + } + + private: + + friend class apply_body_task_bypass< class_type, input_type >; + friend class forward_task_bypass< class_type >; + + class operation_type : public aggregated_operation< operation_type > { + public: + char type; + union { + input_type *elem; + predecessor_type *r; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + size_t cnt_val; + predecessor_list_type *predv; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + }; + tbb::task *bypass_t; + operation_type(const input_type& e, op_type t) : + type(char(t)), elem(const_cast(&e)) {} + operation_type(op_type t) : type(char(t)), r(NULL) {} + }; + + bool forwarder_busy; + typedef internal::aggregating_functor handler_type; + friend class internal::aggregating_functor; + aggregator< handler_type, operation_type > my_aggregator; + + task* perform_queued_requests() { + task* new_task = NULL; + if(my_queue) { + if(!my_queue->empty()) { + ++my_concurrency; + new_task = create_body_task(my_queue->front()); + + my_queue->pop(); + } + } + else { + input_type i; + if(my_predecessors.get_item(i)) { + ++my_concurrency; + new_task = create_body_task(i); + } + } + return new_task; + } + void handle_operations(operation_type *op_list) { + operation_type *tmp; + while (op_list) { + tmp = op_list; + op_list = op_list->next; + switch (tmp->type) { + case reg_pred: + my_predecessors.add(*(tmp->r)); + __TBB_store_with_release(tmp->status, SUCCEEDED); + if (!forwarder_busy) { + forwarder_busy = true; + spawn_forward_task(); + } + break; + case rem_pred: + my_predecessors.remove(*(tmp->r)); + __TBB_store_with_release(tmp->status, SUCCEEDED); + break; + case app_body_bypass: { + tmp->bypass_t = NULL; + __TBB_ASSERT(my_max_concurrency != 0, NULL); + --my_concurrency; + if(my_concurrencybypass_t = perform_queued_requests(); + + __TBB_store_with_release(tmp->status, SUCCEEDED); + } + break; + case tryput_bypass: internal_try_put_task(tmp); break; + case try_fwd: internal_forward(tmp); break; + case occupy_concurrency: + if (my_concurrency < my_max_concurrency) { + ++my_concurrency; + __TBB_store_with_release(tmp->status, SUCCEEDED); + } else { + __TBB_store_with_release(tmp->status, FAILED); + } + break; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + case add_blt_pred: { + my_predecessors.internal_add_built_predecessor(*(tmp->r)); + __TBB_store_with_release(tmp->status, SUCCEEDED); + } + break; + case del_blt_pred: + my_predecessors.internal_delete_built_predecessor(*(tmp->r)); + __TBB_store_with_release(tmp->status, SUCCEEDED); + break; + case blt_pred_cnt: + tmp->cnt_val = my_predecessors.predecessor_count(); + __TBB_store_with_release(tmp->status, SUCCEEDED); + break; + case blt_pred_cpy: + my_predecessors.copy_predecessors( *(tmp->predv) ); + __TBB_store_with_release(tmp->status, SUCCEEDED); + break; +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + } + } + } + + //! Put to the node, but return the task instead of enqueueing it + void internal_try_put_task(operation_type *op) { + __TBB_ASSERT(my_max_concurrency != 0, NULL); + if (my_concurrency < my_max_concurrency) { + ++my_concurrency; + task * new_task = create_body_task(*(op->elem)); + op->bypass_t = new_task; + __TBB_store_with_release(op->status, SUCCEEDED); + } else if ( my_queue && my_queue->push(*(op->elem)) ) { + op->bypass_t = SUCCESSFULLY_ENQUEUED; + __TBB_store_with_release(op->status, SUCCEEDED); + } else { + op->bypass_t = NULL; + __TBB_store_with_release(op->status, FAILED); + } + } + + //! Creates tasks for postponed messages if available and if concurrency allows + void internal_forward(operation_type *op) { + op->bypass_t = NULL; + if (my_concurrency < my_max_concurrency || !my_max_concurrency) + op->bypass_t = perform_queued_requests(); + if(op->bypass_t) + __TBB_store_with_release(op->status, SUCCEEDED); + else { + forwarder_busy = false; + __TBB_store_with_release(op->status, FAILED); + } + } + + task* internal_try_put_bypass( const input_type& t ) { + operation_type op_data(t, tryput_bypass); + my_aggregator.execute(&op_data); + if( op_data.status == internal::SUCCEEDED ) { + return op_data.bypass_t; + } + return NULL; + } + + task* try_put_task_impl( const input_type& t, /*lightweight=*/tbb::internal::true_type ) { + if( my_max_concurrency == 0 ) { + return apply_body_bypass(t); + } else { + operation_type check_op(t, occupy_concurrency); + my_aggregator.execute(&check_op); + if( check_op.status == internal::SUCCEEDED ) { + return apply_body_bypass(t); + } + return internal_try_put_bypass(t); + } + } + + task* try_put_task_impl( const input_type& t, /*lightweight=*/tbb::internal::false_type ) { + if( my_max_concurrency == 0 ) { + return create_body_task(t); + } else { + return internal_try_put_bypass(t); + } + } + + //! Applies the body to the provided input + // then decides if more work is available + task * apply_body_bypass( const input_type &i ) { + return static_cast(this)->apply_body_impl_bypass(i); + } + + //! allocates a task to apply a body + inline task * create_body_task( const input_type &input ) { + return (internal::is_graph_active(my_graph_ref)) ? + new( task::allocate_additional_child_of(*(my_graph_ref.root_task())) ) + apply_body_task_bypass < class_type, input_type >( + *this, __TBB_FLOW_GRAPH_PRIORITY_ARG1(input, my_priority)) + : NULL; + } + + //! This is executed by an enqueued task, the "forwarder" + task* forward_task() { + operation_type op_data(try_fwd); + task* rval = NULL; + do { + op_data.status = WAIT; + my_aggregator.execute(&op_data); + if(op_data.status == SUCCEEDED) { + task* ttask = op_data.bypass_t; + __TBB_ASSERT( ttask && ttask != SUCCESSFULLY_ENQUEUED, NULL ); + rval = combine_tasks(my_graph_ref, rval, ttask); + } + } while (op_data.status == SUCCEEDED); + return rval; + } + + inline task *create_forward_task() { + return (internal::is_graph_active(my_graph_ref)) ? + new( task::allocate_additional_child_of(*(my_graph_ref.root_task())) ) + forward_task_bypass< class_type >( __TBB_FLOW_GRAPH_PRIORITY_ARG1(*this, my_priority) ) + : NULL; + } + + //! Spawns a task that calls forward() + inline void spawn_forward_task() { + task* tp = create_forward_task(); + if(tp) { + internal::spawn_in_graph_arena(graph_reference(), *tp); + } + } + }; // function_input_base + + //! Implements methods for a function node that takes a type Input as input and sends + // a type Output to its successors. + template< typename Input, typename Output, typename Policy, typename A> + class function_input : public function_input_base > { + public: + typedef Input input_type; + typedef Output output_type; + typedef function_body function_body_type; + typedef function_input my_class; + typedef function_input_base base_type; + typedef function_input_queue input_queue_type; + + // constructor + template + function_input( + graph &g, size_t max_concurrency, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body& body, node_priority_t priority) + ) : base_type(g, __TBB_FLOW_GRAPH_PRIORITY_ARG1(max_concurrency, priority)) + , my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) + , my_init_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) { + } + + //! Copy constructor + function_input( const function_input& src ) : + base_type(src), + my_body( src.my_init_body->clone() ), + my_init_body(src.my_init_body->clone() ) { + } + + ~function_input() { + delete my_body; + delete my_init_body; + } + + template< typename Body > + Body copy_function_object() { + function_body_type &body_ref = *this->my_body; + return dynamic_cast< internal::function_body_leaf & >(body_ref).get_body(); + } + + output_type apply_body_impl( const input_type& i) { + // There is an extra copied needed to capture the + // body execution without the try_put + tbb::internal::fgt_begin_body( my_body ); + output_type v = (*my_body)(i); + tbb::internal::fgt_end_body( my_body ); + return v; + } + + //TODO: consider moving into the base class + task * apply_body_impl_bypass( const input_type &i) { + output_type v = apply_body_impl(i); +#if TBB_DEPRECATED_MESSAGE_FLOW_ORDER + task* successor_task = successors().try_put_task(v); +#endif + task* postponed_task = NULL; + if( base_type::my_max_concurrency != 0 ) { + postponed_task = base_type::try_get_postponed_task(i); + __TBB_ASSERT( !postponed_task || postponed_task != SUCCESSFULLY_ENQUEUED, NULL ); + } +#if TBB_DEPRECATED_MESSAGE_FLOW_ORDER + graph& g = base_type::my_graph_ref; + return combine_tasks(g, successor_task, postponed_task); +#else + if( postponed_task ) { + // make the task available for other workers since we do not know successors' + // execution policy + internal::spawn_in_graph_arena(base_type::graph_reference(), *postponed_task); + } + task* successor_task = successors().try_put_task(v); +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (push) +#pragma warning (disable: 4127) /* suppress conditional expression is constant */ +#endif + if(internal::has_policy::value) { +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (pop) +#endif + if(!successor_task) { + // Return confirmative status since current + // node's body has been executed anyway + successor_task = SUCCESSFULLY_ENQUEUED; + } + } + return successor_task; +#endif /* TBB_DEPRECATED_MESSAGE_FLOW_ORDER */ + } + + protected: + + void reset_function_input(reset_flags f) { + base_type::reset_function_input_base(f); + if(f & rf_reset_bodies) { + function_body_type *tmp = my_init_body->clone(); + delete my_body; + my_body = tmp; + } + } + + function_body_type *my_body; + function_body_type *my_init_body; + virtual broadcast_cache &successors() = 0; + + }; // function_input + + + // helper templates to clear the successor edges of the output ports of an multifunction_node + template struct clear_element { + template static void clear_this(P &p) { + (void)tbb::flow::get(p).successors().clear(); + clear_element::clear_this(p); + } + template static bool this_empty(P &p) { + if(tbb::flow::get(p).successors().empty()) + return clear_element::this_empty(p); + return false; + } + }; + + template<> struct clear_element<1> { + template static void clear_this(P &p) { + (void)tbb::flow::get<0>(p).successors().clear(); + } + template static bool this_empty(P &p) { + return tbb::flow::get<0>(p).successors().empty(); + } + }; + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + // helper templates to extract the output ports of an multifunction_node from graph + template struct extract_element { + template static void extract_this(P &p) { + (void)tbb::flow::get(p).successors().built_successors().sender_extract(tbb::flow::get(p)); + extract_element::extract_this(p); + } + }; + + template<> struct extract_element<1> { + template static void extract_this(P &p) { + (void)tbb::flow::get<0>(p).successors().built_successors().sender_extract(tbb::flow::get<0>(p)); + } + }; +#endif + + template + struct init_output_ports { +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template + static OutputTuple call(graph& g, const tbb::flow::tuple&) { + return OutputTuple(Args(g)...); + } +#else // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template + static OutputTuple call(graph& g, const tbb::flow::tuple&) { + return OutputTuple(T1(g)); + } + + template + static OutputTuple call(graph& g, const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g)); + } + + template + static OutputTuple call(graph& g, const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g), T3(g)); + } + + template + static OutputTuple call(graph& g, const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g), T3(g), T4(g)); + } + + template + static OutputTuple call(graph& g, const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g), T3(g), T4(g), T5(g)); + } +#if __TBB_VARIADIC_MAX >= 6 + template + static OutputTuple call(graph& g, const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g), T3(g), T4(g), T5(g), T6(g)); + } +#endif +#if __TBB_VARIADIC_MAX >= 7 + template + static OutputTuple call(graph& g, + const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g), T3(g), T4(g), T5(g), T6(g), T7(g)); + } +#endif +#if __TBB_VARIADIC_MAX >= 8 + template + static OutputTuple call(graph& g, + const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g), T3(g), T4(g), T5(g), T6(g), T7(g), T8(g)); + } +#endif +#if __TBB_VARIADIC_MAX >= 9 + template + static OutputTuple call(graph& g, + const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g), T3(g), T4(g), T5(g), T6(g), T7(g), T8(g), T9(g)); + } +#endif +#if __TBB_VARIADIC_MAX >= 9 + template + static OutputTuple call(graph& g, + const tbb::flow::tuple&) { + return OutputTuple(T1(g), T2(g), T3(g), T4(g), T5(g), T6(g), T7(g), T8(g), T9(g), T10(g)); + } +#endif +#endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + }; // struct init_output_ports + + //! Implements methods for a function node that takes a type Input as input + // and has a tuple of output ports specified. + template< typename Input, typename OutputPortSet, typename Policy, typename A> + class multifunction_input : public function_input_base > { + public: + static const int N = tbb::flow::tuple_size::value; + typedef Input input_type; + typedef OutputPortSet output_ports_type; + typedef multifunction_body multifunction_body_type; + typedef multifunction_input my_class; + typedef function_input_base base_type; + typedef function_input_queue input_queue_type; + + // constructor + template + multifunction_input(graph &g, size_t max_concurrency, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body& body, node_priority_t priority) + ) : base_type(g, __TBB_FLOW_GRAPH_PRIORITY_ARG1(max_concurrency, priority)) + , my_body( new internal::multifunction_body_leaf(body) ) + , my_init_body( new internal::multifunction_body_leaf(body) ) + , my_output_ports(init_output_ports::call(g, my_output_ports)){ + } + + //! Copy constructor + multifunction_input( const multifunction_input& src ) : + base_type(src), + my_body( src.my_init_body->clone() ), + my_init_body(src.my_init_body->clone() ), + my_output_ports( init_output_ports::call(src.my_graph_ref, my_output_ports) ) { + } + + ~multifunction_input() { + delete my_body; + delete my_init_body; + } + + template< typename Body > + Body copy_function_object() { + multifunction_body_type &body_ref = *this->my_body; + return *static_cast(dynamic_cast< internal::multifunction_body_leaf & >(body_ref).get_body_ptr()); + } + + // for multifunction nodes we do not have a single successor as such. So we just tell + // the task we were successful. + //TODO: consider moving common parts with implementation in function_input into separate function + task * apply_body_impl_bypass( const input_type &i) { + tbb::internal::fgt_begin_body( my_body ); + (*my_body)(i, my_output_ports); + tbb::internal::fgt_end_body( my_body ); + task* ttask = NULL; + if(base_type::my_max_concurrency != 0) { + ttask = base_type::try_get_postponed_task(i); + } + return ttask ? ttask : SUCCESSFULLY_ENQUEUED; + } + + output_ports_type &output_ports(){ return my_output_ports; } + + protected: +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + void extract() { + extract_element::extract_this(my_output_ports); + } +#endif + + void reset(reset_flags f) { + base_type::reset_function_input_base(f); + if(f & rf_clear_edges)clear_element::clear_this(my_output_ports); + if(f & rf_reset_bodies) { + multifunction_body_type *tmp = my_init_body->clone(); + delete my_body; + my_body = tmp; + } + __TBB_ASSERT(!(f & rf_clear_edges) || clear_element::this_empty(my_output_ports), "multifunction_node reset failed"); + } + + multifunction_body_type *my_body; + multifunction_body_type *my_init_body; + output_ports_type my_output_ports; + + }; // multifunction_input + + // template to refer to an output port of a multifunction_node + template + typename tbb::flow::tuple_element::type &output_port(MOP &op) { + return tbb::flow::get(op.output_ports()); + } + + inline void check_task_and_spawn(graph& g, task* t) { + if (t && t != SUCCESSFULLY_ENQUEUED) { + internal::spawn_in_graph_arena(g, *t); + } + } + + // helper structs for split_node + template + struct emit_element { + template + static task* emit_this(graph& g, const T &t, P &p) { + // TODO: consider to collect all the tasks in task_list and spawn them all at once + task* last_task = tbb::flow::get(p).try_put_task(tbb::flow::get(t)); + check_task_and_spawn(g, last_task); + return emit_element::emit_this(g,t,p); + } + }; + + template<> + struct emit_element<1> { + template + static task* emit_this(graph& g, const T &t, P &p) { + task* last_task = tbb::flow::get<0>(p).try_put_task(tbb::flow::get<0>(t)); + check_task_and_spawn(g, last_task); + return SUCCESSFULLY_ENQUEUED; + } + }; + + //! Implements methods for an executable node that takes continue_msg as input + template< typename Output, typename Policy> + class continue_input : public continue_receiver { + public: + + //! The input type of this receiver + typedef continue_msg input_type; + + //! The output type of this receiver + typedef Output output_type; + typedef function_body function_body_type; + typedef continue_input class_type; + + template< typename Body > + continue_input( graph &g, __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body& body, node_priority_t priority) ) + : continue_receiver(__TBB_FLOW_GRAPH_PRIORITY_ARG1(/*number_of_predecessors=*/0, priority)) + , my_graph_ref(g) + , my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) + , my_init_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) + { } + + template< typename Body > + continue_input( graph &g, int number_of_predecessors, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body& body, node_priority_t priority) + ) : continue_receiver( __TBB_FLOW_GRAPH_PRIORITY_ARG1(number_of_predecessors, priority) ) + , my_graph_ref(g) + , my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) + , my_init_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) + { } + + continue_input( const continue_input& src ) : continue_receiver(src), + my_graph_ref(src.my_graph_ref), + my_body( src.my_init_body->clone() ), + my_init_body( src.my_init_body->clone() ) {} + + ~continue_input() { + delete my_body; + delete my_init_body; + } + + template< typename Body > + Body copy_function_object() { + function_body_type &body_ref = *my_body; + return dynamic_cast< internal::function_body_leaf & >(body_ref).get_body(); + } + + void reset_receiver( reset_flags f) __TBB_override { + continue_receiver::reset_receiver(f); + if(f & rf_reset_bodies) { + function_body_type *tmp = my_init_body->clone(); + delete my_body; + my_body = tmp; + } + } + + protected: + + graph& my_graph_ref; + function_body_type *my_body; + function_body_type *my_init_body; + + virtual broadcast_cache &successors() = 0; + + friend class apply_body_task_bypass< class_type, continue_msg >; + + //! Applies the body to the provided input + task *apply_body_bypass( input_type ) { + // There is an extra copied needed to capture the + // body execution without the try_put + tbb::internal::fgt_begin_body( my_body ); + output_type v = (*my_body)( continue_msg() ); + tbb::internal::fgt_end_body( my_body ); + return successors().try_put_task( v ); + } + + task* execute() __TBB_override { + if(!internal::is_graph_active(my_graph_ref)) { + return NULL; + } +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (push) +#pragma warning (disable: 4127) /* suppress conditional expression is constant */ +#endif + if(internal::has_policy::value) { +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (pop) +#endif + return apply_body_bypass( continue_msg() ); + } + else { + return new ( task::allocate_additional_child_of( *(my_graph_ref.root_task()) ) ) + apply_body_task_bypass< class_type, continue_msg >( + *this, __TBB_FLOW_GRAPH_PRIORITY_ARG1(continue_msg(), my_priority) ); + } + } + + graph& graph_reference() const __TBB_override { + return my_graph_ref; + } + }; // continue_input + + //! Implements methods for both executable and function nodes that puts Output to its successors + template< typename Output > + class function_output : public sender { + public: + + template friend struct clear_element; + typedef Output output_type; + typedef typename sender::successor_type successor_type; + typedef broadcast_cache broadcast_cache_type; +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename sender::built_successors_type built_successors_type; + typedef typename sender::successor_list_type successor_list_type; +#endif + + function_output( graph& g) : my_graph_ref(g) { my_successors.set_owner(this); } + function_output(const function_output & other) : sender(), my_graph_ref(other.my_graph_ref) { + my_successors.set_owner(this); + } + + //! Adds a new successor to this node + bool register_successor( successor_type &r ) __TBB_override { + successors().register_successor( r ); + return true; + } + + //! Removes a successor from this node + bool remove_successor( successor_type &r ) __TBB_override { + successors().remove_successor( r ); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + built_successors_type &built_successors() __TBB_override { return successors().built_successors(); } + + + void internal_add_built_successor( successor_type &r) __TBB_override { + successors().internal_add_built_successor( r ); + } + + void internal_delete_built_successor( successor_type &r) __TBB_override { + successors().internal_delete_built_successor( r ); + } + + size_t successor_count() __TBB_override { + return successors().successor_count(); + } + + void copy_successors( successor_list_type &v) __TBB_override { + successors().copy_successors(v); + } +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + + // for multifunction_node. The function_body that implements + // the node will have an input and an output tuple of ports. To put + // an item to a successor, the body should + // + // get(output_ports).try_put(output_value); + // + // if task pointer is returned will always spawn and return true, else + // return value will be bool returned from successors.try_put. + task *try_put_task(const output_type &i) { // not a virtual method in this class + return my_successors.try_put_task(i); + } + + broadcast_cache_type &successors() { return my_successors; } + + graph& graph_reference() const { return my_graph_ref; } + protected: + broadcast_cache_type my_successors; + graph& my_graph_ref; + }; // function_output + + template< typename Output > + class multifunction_output : public function_output { + public: + typedef Output output_type; + typedef function_output base_type; + using base_type::my_successors; + + multifunction_output(graph& g) : base_type(g) {my_successors.set_owner(this);} + multifunction_output( const multifunction_output& other) : base_type(other.my_graph_ref) { my_successors.set_owner(this); } + + bool try_put(const output_type &i) { + task *res = try_put_task(i); + if(!res) return false; + if(res != SUCCESSFULLY_ENQUEUED) { + FLOW_SPAWN(*res); // TODO: Spawn task inside arena + } + return true; + } + + using base_type::graph_reference; + + protected: + + task* try_put_task(const output_type &i) { + return my_successors.try_put_task(i); + } + + template friend struct emit_element; + + }; // multifunction_output + +//composite_node +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + template + void add_nodes_impl(CompositeType*, bool) {} + + template< typename CompositeType, typename NodeType1, typename... NodeTypes > + void add_nodes_impl(CompositeType *c_node, bool visible, const NodeType1& n1, const NodeTypes&... n) { + void *addr = const_cast(&n1); + + fgt_alias_port(c_node, addr, visible); + add_nodes_impl(c_node, visible, n...); + } +#endif + +} // internal + +#endif // __TBB__flow_graph_node_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_node_set_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_node_set_impl.h new file mode 100644 index 00000000..f5ec6d0e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_node_set_impl.h @@ -0,0 +1,269 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_flow_graph_node_set_impl_H +#define __TBB_flow_graph_node_set_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +// Included in namespace tbb::flow::interfaceX (in flow_graph.h) + +namespace internal { + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +// Visual Studio 2019 reports an error while calling predecessor_selector::get and successor_selector::get +// Seems like the well-formed expression in trailing decltype is treated as ill-formed +// TODO: investigate problems with decltype in trailing return types or find the cross-platform solution +#define __TBB_MSVC_DISABLE_TRAILING_DECLTYPE (_MSC_VER >= 1900) + +namespace order { +struct undefined {}; +struct following {}; +struct preceding {}; +} + +class get_graph_helper { +public: + // TODO: consider making graph_reference() public and consistent interface to get a reference to the graph + // and remove get_graph_helper + template + static graph& get(const T& object) { + return get_impl(object, std::is_base_of()); + } + +private: + // Get graph from the object of type derived from graph_node + template + static graph& get_impl(const T& object, std::true_type) { + return static_cast(&object)->my_graph; + } + + template + static graph& get_impl(const T& object, std::false_type) { + return object.graph_reference(); + } +}; + +template +struct node_set { + typedef Order order_type; + + tbb::flow::tuple nodes; + node_set(Nodes&... ns) : nodes(ns...) {} + + template + node_set(const node_set& set) : nodes(set.nodes) {} + + graph& graph_reference() const { + return get_graph_helper::get(std::get<0>(nodes)); + } +}; + +namespace alias_helpers { +template using output_type = typename T::output_type; +template using output_ports_type = typename T::output_ports_type; +template using input_type = typename T::input_type; +template using input_ports_type = typename T::input_ports_type; +} // namespace alias_helpers + +template +using has_output_type = tbb::internal::supports; + +template +using has_input_type = tbb::internal::supports; + +template +using has_input_ports_type = tbb::internal::supports; + +template +using has_output_ports_type = tbb::internal::supports; + +template +struct is_sender : std::is_base_of, T> {}; + +template +struct is_receiver : std::is_base_of, T> {}; + +template +struct is_async_node : std::false_type {}; + +template +struct is_async_node> : std::true_type {}; + +template +node_set +follows(FirstPredecessor& first_predecessor, Predecessors&... predecessors) { + __TBB_STATIC_ASSERT((tbb::internal::conjunction, + has_output_type...>::value), + "Not all node's predecessors has output_type typedef"); + __TBB_STATIC_ASSERT((tbb::internal::conjunction, is_sender...>::value), + "Not all node's predecessors are senders"); + return node_set(first_predecessor, predecessors...); +} + +template +node_set +follows(node_set& predecessors_set) { + __TBB_STATIC_ASSERT((tbb::internal::conjunction...>::value), + "Not all nodes in the set has output_type typedef"); + __TBB_STATIC_ASSERT((tbb::internal::conjunction...>::value), + "Not all nodes in the set are senders"); + return node_set(predecessors_set); +} + +template +node_set +precedes(FirstSuccessor& first_successor, Successors&... successors) { + __TBB_STATIC_ASSERT((tbb::internal::conjunction, + has_input_type...>::value), + "Not all node's successors has input_type typedef"); + __TBB_STATIC_ASSERT((tbb::internal::conjunction, is_receiver...>::value), + "Not all node's successors are receivers"); + return node_set(first_successor, successors...); +} + +template +node_set +precedes(node_set& successors_set) { + __TBB_STATIC_ASSERT((tbb::internal::conjunction...>::value), + "Not all nodes in the set has input_type typedef"); + __TBB_STATIC_ASSERT((tbb::internal::conjunction...>::value), + "Not all nodes in the set are receivers"); + return node_set(successors_set); +} + +template +node_set +make_node_set(Node& first_node, Nodes&... nodes) { + return node_set(first_node, nodes...); +} + +template +class successor_selector { + template + static auto get_impl(NodeType& node, std::true_type) -> decltype(input_port(node)) { + return input_port(node); + } + + template + static NodeType& get_impl(NodeType& node, std::false_type) { return node; } + +public: + template +#if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE + static auto& get(NodeType& node) +#else + static auto get(NodeType& node) -> decltype(get_impl(node, has_input_ports_type())) +#endif + { + return get_impl(node, has_input_ports_type()); + } +}; + +template +class predecessor_selector { + template + static auto internal_get(NodeType& node, std::true_type) -> decltype(output_port(node)) { + return output_port(node); + } + + template + static NodeType& internal_get(NodeType& node, std::false_type) { return node;} + + template +#if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE + static auto& get_impl(NodeType& node, std::false_type) +#else + static auto get_impl(NodeType& node, std::false_type) -> decltype(internal_get(node, has_output_ports_type())) +#endif + { + return internal_get(node, has_output_ports_type()); + } + + template + static AsyncNode& get_impl(AsyncNode& node, std::true_type) { return node; } + +public: + template +#if __TBB_MSVC_DISABLE_TRAILING_DECLTYPE + static auto& get(NodeType& node) +#else + static auto get(NodeType& node) -> decltype(get_impl(node, is_async_node())) +#endif + { + return get_impl(node, is_async_node()); + } +}; + +template +class make_edges_helper { +public: + template + static void connect_predecessors(PredecessorsTuple& predecessors, NodeType& node) { + make_edge(std::get(predecessors), successor_selector::get(node)); + make_edges_helper::connect_predecessors(predecessors, node); + } + + template + static void connect_successors(NodeType& node, SuccessorsTuple& successors) { + make_edge(predecessor_selector::get(node), std::get(successors)); + make_edges_helper::connect_successors(node, successors); + } +}; + +template<> +struct make_edges_helper<0> { + template + static void connect_predecessors(PredecessorsTuple& predecessors, NodeType& node) { + make_edge(std::get<0>(predecessors), successor_selector<0>::get(node)); + } + + template + static void connect_successors(NodeType& node, SuccessorsTuple& successors) { + make_edge(predecessor_selector<0>::get(node), std::get<0>(successors)); + } +}; + +// TODO: consider adding an overload for making edges between node sets +template +void make_edges(const node_set& s, NodeType& node) { + const std::size_t SetSize = tbb::flow::tuple_size::value; + make_edges_helper::connect_predecessors(s.nodes, node); +} + +template +void make_edges(NodeType& node, const node_set& s) { + const std::size_t SetSize = tbb::flow::tuple_size::value; + make_edges_helper::connect_successors(node, s.nodes); +} + +template +void make_edges_in_order(const node_set& ns, NodeType& node) { + make_edges(ns, node); +} + +template +void make_edges_in_order(const node_set& ns, NodeType& node) { + make_edges(node, ns); +} + +#endif // __TBB_CPP11_PRESENT + +} // namespace internal + +#endif // __TBB_flow_graph_node_set_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_nodes_deduction.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_nodes_deduction.h new file mode 100644 index 00000000..caf2f689 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_nodes_deduction.h @@ -0,0 +1,298 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_flow_graph_nodes_deduction_H +#define __TBB_flow_graph_nodes_deduction_H + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +namespace tbb { +namespace flow { +namespace interface11 { + +template +struct declare_body_types { + using input_type = Input; + using output_type = Output; +}; + +struct NoInputBody {}; + +template +struct declare_body_types { + using output_type = Output; +}; + +template struct body_types; + +template +struct body_types : declare_body_types {}; + +template +struct body_types : declare_body_types {}; + +template +struct body_types : declare_body_types {}; + +template +struct body_types : declare_body_types {}; + +template +struct body_types : declare_body_types {}; + +template +struct body_types : declare_body_types {}; + +template +struct body_types : declare_body_types {}; + +template +struct body_types : declare_body_types {}; + +template +struct body_types : declare_body_types {}; + +template +using input_t = typename body_types::input_type; + +template +using output_t = typename body_types::output_type; + +template +auto decide_on_operator_overload(Output (T::*name)(const Input&) const)->decltype(name); + +template +auto decide_on_operator_overload(Output (T::*name)(const Input&))->decltype(name); + +template +auto decide_on_operator_overload(Output (T::*name)(Input&) const)->decltype(name); + +template +auto decide_on_operator_overload(Output (T::*name)(Input&))->decltype(name); + +template +auto decide_on_operator_overload(Output (*name)(const Input&))->decltype(name); + +template +auto decide_on_operator_overload(Output (*name)(Input&))->decltype(name); + +template +decltype(decide_on_operator_overload(&Body::operator())) decide_on_callable_type(int); + +template +decltype(decide_on_operator_overload(std::declval())) decide_on_callable_type(...); + +// Deduction guides for Flow Graph nodes +#if TBB_USE_SOURCE_NODE_AS_ALIAS +#if TBB_DEPRECATED_INPUT_NODE_BODY +template +source_node(GraphOrSet&&, Body) +->source_node(0))>>; +#else +template +source_node(GraphOrSet&&, Body) +->source_node(0))>>; +#endif // TBB_DEPRECATED_INPUT_NODE_BODY +#else +template +source_node(GraphOrSet&&, Body, bool = true) +->source_node(0))>>; +#endif + +#if TBB_DEPRECATED_INPUT_NODE_BODY +template +input_node(GraphOrSet&&, Body, bool = true) +->input_node(0))>>; +#else +template +input_node(GraphOrSet&&, Body) +->input_node(0))>>; +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +template +struct decide_on_set; + +template +struct decide_on_set> { + using type = typename Node::output_type; +}; + +template +struct decide_on_set> { + using type = typename Node::input_type; +}; + +template +using decide_on_set_t = typename decide_on_set>::type; + +template +broadcast_node(const NodeSet&) +->broadcast_node>; + +template +buffer_node(const NodeSet&) +->buffer_node>; + +template +queue_node(const NodeSet&) +->queue_node>; +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +template +sequencer_node(GraphOrProxy&&, Sequencer) +->sequencer_node(0))>>; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +template +priority_queue_node(const NodeSet&, const Compare&) +->priority_queue_node, Compare>; + +template +priority_queue_node(const NodeSet&) +->priority_queue_node, std::less>>; +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +template +struct join_key { + using type = Key; +}; + +template +struct join_key { + using type = T&; +}; + +template +using join_key_t = typename join_key::type; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +template +join_node(const node_set&, Policy) +->join_node, + Policy>; + +template +join_node(const node_set&, Policy) +->join_node; + +template +join_node(const node_set) +->join_node, + queueing>; + +template +join_node(const node_set) +->join_node; +#endif + +template +join_node(GraphOrProxy&&, Body, Bodies...) +->join_node(0))>, + input_t(0))>...>, + key_matching(0))>>>>; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +template +indexer_node(const node_set&) +->indexer_node; +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +template +limiter_node(const NodeSet&, size_t) +->limiter_node>; + +template +split_node(const node_set&) +->split_node; + +template +split_node(const node_set&) +->split_node>; + +#endif + +template +function_node(GraphOrSet&&, + size_t, Body, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority)) +->function_node(0))>, + output_t(0))>, + Policy>; + +template +function_node(GraphOrSet&&, size_t, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority)) +->function_node(0))>, + output_t(0))>, + queueing>; + +template +struct continue_output { + using type = Output; +}; + +template <> +struct continue_output { + using type = continue_msg; +}; + +template +using continue_output_t = typename continue_output::type; + +template +continue_node(GraphOrSet&&, Body, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority)) +->continue_node>, + Policy>; + +template +continue_node(GraphOrSet&&, + int, Body, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy, node_priority_t = tbb::flow::internal::no_priority)) +->continue_node>, + Policy>; + +template +continue_node(GraphOrSet&&, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority)) +->continue_node>, + internal::Policy>; + +template +continue_node(GraphOrSet&&, int, + __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body, node_priority_t = tbb::flow::internal::no_priority)) +->continue_node>, + internal::Policy>; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +template +overwrite_node(const NodeSet&) +->overwrite_node>; + +template +write_once_node(const NodeSet&) +->write_once_node>; +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +} // namespace interfaceX +} // namespace flow +} // namespace tbb + +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +#endif // __TBB_flow_graph_nodes_deduction_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_streaming_node.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_streaming_node.h new file mode 100644 index 00000000..4ef990bf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_streaming_node.h @@ -0,0 +1,743 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_flow_graph_streaming_H +#define __TBB_flow_graph_streaming_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#if __TBB_PREVIEW_STREAMING_NODE + +// Included in namespace tbb::flow::interfaceX (in flow_graph.h) + +namespace internal { + +template +struct port_ref_impl { + // "+1" since the port_ref range is a closed interval (includes its endpoints). + static const int size = N2 - N1 + 1; +}; + +} // internal + +// The purpose of the port_ref_impl is the pretty syntax: the deduction of a compile-time constant is processed from the return type. +// So it is possible to use this helper without parentheses, e.g. "port_ref<0>". +template +__TBB_DEPRECATED internal::port_ref_impl port_ref() { + return internal::port_ref_impl(); +}; + +namespace internal { + +template +struct num_arguments { + static const int value = 1; +}; + +template +struct num_arguments(*)()> { + static const int value = port_ref_impl::size; +}; + +template +struct num_arguments> { + static const int value = port_ref_impl::size; +}; + +template +void ignore_return_values( Args&&... ) {} + +template +T or_return_values( T&& t ) { return t; } +template +T or_return_values( T&& t, Rest&&... rest ) { + return t | or_return_values( std::forward(rest)... ); +} + +template +struct key_from_policy { + typedef size_t type; + typedef std::false_type is_key_matching; +}; + +template +struct key_from_policy< key_matching > { + typedef Key type; + typedef std::true_type is_key_matching; +}; + +template +struct key_from_policy< key_matching > { + typedef const Key &type; + typedef std::true_type is_key_matching; +}; + +template +class streaming_device_with_key { + Device my_device; + typename std::decay::type my_key; +public: + // TODO: investigate why default constructor is required + streaming_device_with_key() {} + streaming_device_with_key( const Device& d, Key k ) : my_device( d ), my_key( k ) {} + Key key() const { return my_key; } + const Device& device() const { return my_device; } +}; + +// --------- Kernel argument helpers --------- // +template +struct is_port_ref_impl { + typedef std::false_type type; +}; + +template +struct is_port_ref_impl< port_ref_impl > { + typedef std::true_type type; +}; + +template +struct is_port_ref_impl< port_ref_impl( * )() > { + typedef std::true_type type; +}; + +template +struct is_port_ref { + typedef typename is_port_ref_impl< typename tbb::internal::strip::type >::type type; +}; + +template +struct convert_and_call_impl; + +template +struct convert_and_call_impl { + static const size_t my_delta = 1; // Index 0 contains device + + template + static void doit(F& f, Tuple& t, A1& a1, Args1&... args1, Args2&... args2) { + convert_and_call_impl::doit_impl(typename is_port_ref::type(), f, t, a1, args1..., args2...); + } + template + static void doit_impl(std::false_type, F& f, Tuple& t, A1& a1, Args1&... args1, Args2&... args2) { + convert_and_call_impl::doit(f, t, args1..., args2..., a1); + } + template + static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl, Args1&... args1, Args2&... args2) { + convert_and_call_impl, Args1...>::doit_impl(x, f, t, port_ref(), args1..., + args2..., std::get(t)); + } + template + static void doit_impl(std::true_type, F& f, Tuple& t, port_ref_impl, Args1&... args1, Args2&... args2) { + convert_and_call_impl::doit(f, t, args1..., args2..., std::get(t)); + } + + template + static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl(* fn)(), Args1&... args1, Args2&... args2) { + doit_impl(x, f, t, fn(), args1..., args2...); + } + template + static void doit_impl(std::true_type x, F& f, Tuple& t, port_ref_impl(* fn)(), Args1&... args1, Args2&... args2) { + doit_impl(x, f, t, fn(), args1..., args2...); + } +}; + +template <> +struct convert_and_call_impl<> { + template + static void doit(F& f, Tuple&, Args2&... args2) { + f(args2...); + } +}; +// ------------------------------------------- // + +template +struct streaming_node_traits { + // Do not use 'using' instead of 'struct' because Microsoft Visual C++ 12.0 fails to compile. + template + struct async_msg_type { + typedef typename StreamFactory::template async_msg_type type; + }; + + typedef tuple< typename async_msg_type::type... > input_tuple; + typedef input_tuple output_tuple; + typedef tuple< streaming_device_with_key< typename StreamFactory::device_type, typename key_from_policy::type >, + typename async_msg_type::type... > kernel_input_tuple; + + // indexer_node parameters pack expansion workaround for VS2013 for streaming_node + typedef indexer_node< typename async_msg_type::type... > indexer_node_type; +}; + +// Default empty implementation +template +class kernel_executor_helper { + typedef typename StreamFactory::device_type device_type; + typedef typename StreamFactory::kernel_type kernel_type; + typedef KernelInputTuple kernel_input_tuple; +protected: + template + void enqueue_kernel_impl( kernel_input_tuple&, StreamFactory& factory, device_type device, const kernel_type& kernel, Args&... args ) const { + factory.send_kernel( device, kernel, args... ); + } +}; + +// Implementation for StreamFactory supporting range +template +class kernel_executor_helper::type > { + typedef typename StreamFactory::device_type device_type; + typedef typename StreamFactory::kernel_type kernel_type; + typedef KernelInputTuple kernel_input_tuple; + + typedef typename StreamFactory::range_type range_type; + + // Container for randge. It can contain either port references or real range. + struct range_wrapper { + virtual range_type get_range( const kernel_input_tuple &ip ) const = 0; + virtual range_wrapper *clone() const = 0; + virtual ~range_wrapper() {} + }; + + struct range_value : public range_wrapper { + range_value( const range_type& value ) : my_value(value) {} + + range_value( range_type&& value ) : my_value(std::move(value)) {} + + range_type get_range( const kernel_input_tuple & ) const __TBB_override { + return my_value; + } + + range_wrapper *clone() const __TBB_override { + return new range_value(my_value); + } + private: + range_type my_value; + }; + + template + struct range_mapper : public range_wrapper { + range_mapper() {} + + range_type get_range( const kernel_input_tuple &ip ) const __TBB_override { + // "+1" since get<0>(ip) is StreamFactory::device. + return get(ip).data(false); + } + + range_wrapper *clone() const __TBB_override { + return new range_mapper; + } + }; + +protected: + template + void enqueue_kernel_impl( kernel_input_tuple& ip, StreamFactory& factory, device_type device, const kernel_type& kernel, Args&... args ) const { + __TBB_ASSERT(my_range_wrapper, "Range is not set. Call set_range() before running streaming_node."); + factory.send_kernel( device, kernel, my_range_wrapper->get_range(ip), args... ); + } + +public: + kernel_executor_helper() : my_range_wrapper(NULL) {} + + kernel_executor_helper(const kernel_executor_helper& executor) : my_range_wrapper(executor.my_range_wrapper ? executor.my_range_wrapper->clone() : NULL) {} + + kernel_executor_helper(kernel_executor_helper&& executor) : my_range_wrapper(executor.my_range_wrapper) { + // Set moving holder mappers to NULL to prevent double deallocation + executor.my_range_wrapper = NULL; + } + + ~kernel_executor_helper() { + if (my_range_wrapper) delete my_range_wrapper; + } + + void set_range(const range_type& work_size) { + my_range_wrapper = new range_value(work_size); + } + + void set_range(range_type&& work_size) { + my_range_wrapper = new range_value(std::move(work_size)); + } + + template + void set_range(port_ref_impl) { + my_range_wrapper = new range_mapper; + } + + template + void set_range(port_ref_impl(*)()) { + my_range_wrapper = new range_mapper; + } + +private: + range_wrapper* my_range_wrapper; +}; + +} // internal + +/* +/---------------------------------------- streaming_node ------------------------------------\ +| | +| /--------------\ /----------------------\ /-----------\ /----------------------\ | +| | | | (device_with_key) O---O | | | | +| | | | | | | | | | +O---O indexer_node O---O device_selector_node O---O join_node O---O kernel_node O---O +| | | | (multifunction_node) | | | | (multifunction_node) | | +O---O | | O---O | | O---O +| \--------------/ \----------------------/ \-----------/ \----------------------/ | +| | +\--------------------------------------------------------------------------------------------/ +*/ +template +class __TBB_DEPRECATED streaming_node; + +template +class __TBB_DEPRECATED +streaming_node< tuple, JP, StreamFactory > + : public composite_node < typename internal::streaming_node_traits::input_tuple, + typename internal::streaming_node_traits::output_tuple > + , public internal::kernel_executor_helper< StreamFactory, typename internal::streaming_node_traits::kernel_input_tuple > +{ + typedef typename internal::streaming_node_traits::input_tuple input_tuple; + typedef typename internal::streaming_node_traits::output_tuple output_tuple; + typedef typename internal::key_from_policy::type key_type; +protected: + typedef typename StreamFactory::device_type device_type; + typedef typename StreamFactory::kernel_type kernel_type; +private: + typedef internal::streaming_device_with_key device_with_key_type; + typedef composite_node base_type; + static const size_t NUM_INPUTS = tuple_size::value; + static const size_t NUM_OUTPUTS = tuple_size::value; + + typedef typename internal::make_sequence::type input_sequence; + typedef typename internal::make_sequence::type output_sequence; + + typedef typename internal::streaming_node_traits::indexer_node_type indexer_node_type; + typedef typename indexer_node_type::output_type indexer_node_output_type; + typedef typename internal::streaming_node_traits::kernel_input_tuple kernel_input_tuple; + typedef multifunction_node device_selector_node; + typedef multifunction_node kernel_multifunction_node; + + template + typename base_type::input_ports_type get_input_ports( internal::sequence ) { + return std::tie( internal::input_port( my_indexer_node )... ); + } + + template + typename base_type::output_ports_type get_output_ports( internal::sequence ) { + return std::tie( internal::output_port( my_kernel_node )... ); + } + + typename base_type::input_ports_type get_input_ports() { + return get_input_ports( input_sequence() ); + } + + typename base_type::output_ports_type get_output_ports() { + return get_output_ports( output_sequence() ); + } + + template + int make_Nth_edge() { + make_edge( internal::output_port( my_device_selector_node ), internal::input_port( my_join_node ) ); + return 0; + } + + template + void make_edges( internal::sequence ) { + make_edge( my_indexer_node, my_device_selector_node ); + make_edge( my_device_selector_node, my_join_node ); + internal::ignore_return_values( make_Nth_edge()... ); + make_edge( my_join_node, my_kernel_node ); + } + + void make_edges() { + make_edges( input_sequence() ); + } + + class device_selector_base { + public: + virtual void operator()( const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) = 0; + virtual device_selector_base *clone( streaming_node &n ) const = 0; + virtual ~device_selector_base() {} + }; + + template + class device_selector : public device_selector_base, tbb::internal::no_assign { + public: + device_selector( UserFunctor uf, streaming_node &n, StreamFactory &f ) + : my_dispatch_funcs( create_dispatch_funcs( input_sequence() ) ) + , my_user_functor( uf ), my_node(n), my_factory( f ) + { + my_port_epoches.fill( 0 ); + } + + void operator()( const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) __TBB_override { + (this->*my_dispatch_funcs[ v.tag() ])( my_port_epoches[ v.tag() ], v, op ); + __TBB_ASSERT( (tbb::internal::is_same_type::is_key_matching, std::false_type>::value) + || my_port_epoches[v.tag()] == 0, "Epoch is changed when key matching is requested" ); + } + + device_selector_base *clone( streaming_node &n ) const __TBB_override { + return new device_selector( my_user_functor, n, my_factory ); + } + private: + typedef void(device_selector::*send_and_put_fn_type)(size_t &, const indexer_node_output_type &, typename device_selector_node::output_ports_type &); + typedef std::array < send_and_put_fn_type, NUM_INPUTS > dispatch_funcs_type; + + template + static dispatch_funcs_type create_dispatch_funcs( internal::sequence ) { + dispatch_funcs_type dispatch = { { &device_selector::send_and_put_impl... } }; + return dispatch; + } + + template + key_type get_key( std::false_type, const T &, size_t &epoch ) { + __TBB_STATIC_ASSERT( (tbb::internal::is_same_type::value), "" ); + return epoch++; + } + + template + key_type get_key( std::true_type, const T &t, size_t &/*epoch*/ ) { + using tbb::flow::key_from_message; + return key_from_message( t ); + } + + template + void send_and_put_impl( size_t &epoch, const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) { + typedef typename tuple_element::type::output_type elem_type; + elem_type e = internal::cast_to( v ); + device_type device = get_device( get_key( typename internal::key_from_policy::is_key_matching(), e, epoch ), get<0>( op ) ); + my_factory.send_data( device, e ); + get( op ).try_put( e ); + } + + template< typename DevicePort > + device_type get_device( key_type key, DevicePort& dp ) { + typename std::unordered_map::type, epoch_desc>::iterator it = my_devices.find( key ); + if ( it == my_devices.end() ) { + device_type d = my_user_functor( my_factory ); + std::tie( it, std::ignore ) = my_devices.insert( std::make_pair( key, d ) ); + bool res = dp.try_put( device_with_key_type( d, key ) ); + __TBB_ASSERT_EX( res, NULL ); + my_node.notify_new_device( d ); + } + epoch_desc &e = it->second; + device_type d = e.my_device; + if ( ++e.my_request_number == NUM_INPUTS ) my_devices.erase( it ); + return d; + } + + struct epoch_desc { + epoch_desc(device_type d ) : my_device( d ), my_request_number( 0 ) {} + device_type my_device; + size_t my_request_number; + }; + + std::unordered_map::type, epoch_desc> my_devices; + std::array my_port_epoches; + dispatch_funcs_type my_dispatch_funcs; + UserFunctor my_user_functor; + streaming_node &my_node; + StreamFactory &my_factory; + }; + + class device_selector_body { + public: + device_selector_body( device_selector_base *d ) : my_device_selector( d ) {} + + void operator()( const indexer_node_output_type &v, typename device_selector_node::output_ports_type &op ) { + (*my_device_selector)(v, op); + } + private: + device_selector_base *my_device_selector; + }; + + // TODO: investigate why copy-construction is disallowed + class args_storage_base : tbb::internal::no_copy { + public: + typedef typename kernel_multifunction_node::output_ports_type output_ports_type; + + virtual void enqueue( kernel_input_tuple &ip, output_ports_type &op, const streaming_node &n ) = 0; + virtual void send( device_type d ) = 0; + virtual args_storage_base *clone() const = 0; + virtual ~args_storage_base () {} + + protected: + args_storage_base( const kernel_type& kernel, StreamFactory &f ) + : my_kernel( kernel ), my_factory( f ) + {} + + args_storage_base( const args_storage_base &k ) + : tbb::internal::no_copy(), my_kernel( k.my_kernel ), my_factory( k.my_factory ) + {} + + const kernel_type my_kernel; + StreamFactory &my_factory; + }; + + template + class args_storage : public args_storage_base { + typedef typename args_storage_base::output_ports_type output_ports_type; + + // ---------- Update events helpers ---------- // + template + bool do_try_put( const kernel_input_tuple& ip, output_ports_type &op ) const { + const auto& t = get( ip ); + auto &port = get( op ); + return port.try_put( t ); + } + + template + bool do_try_put( const kernel_input_tuple& ip, output_ports_type &op, internal::sequence ) const { + return internal::or_return_values( do_try_put( ip, op )... ); + } + + // ------------------------------------------- // + class run_kernel_func : tbb::internal::no_assign { + public: + run_kernel_func( kernel_input_tuple &ip, const streaming_node &node, const args_storage& storage ) + : my_kernel_func( ip, node, storage, get<0>(ip).device() ) {} + + // It is immpossible to use Args... because a function pointer cannot be casted to a function reference implicitly. + // Allow the compiler to deduce types for function pointers automatically. + template + void operator()( FnArgs&... args ) { + internal::convert_and_call_impl::doit( my_kernel_func, my_kernel_func.my_ip, args... ); + } + private: + struct kernel_func : tbb::internal::no_copy { + kernel_input_tuple &my_ip; + const streaming_node &my_node; + const args_storage& my_storage; + device_type my_device; + + kernel_func( kernel_input_tuple &ip, const streaming_node &node, const args_storage& storage, device_type device ) + : my_ip( ip ), my_node( node ), my_storage( storage ), my_device( device ) + {} + + template + void operator()( FnArgs&... args ) { + my_node.enqueue_kernel( my_ip, my_storage.my_factory, my_device, my_storage.my_kernel, args... ); + } + } my_kernel_func; + }; + + template + class run_finalize_func : tbb::internal::no_assign { + public: + run_finalize_func( kernel_input_tuple &ip, StreamFactory &factory, FinalizeFn fn ) + : my_ip( ip ), my_finalize_func( factory, get<0>(ip).device(), fn ) {} + + // It is immpossible to use Args... because a function pointer cannot be casted to a function reference implicitly. + // Allow the compiler to deduce types for function pointers automatically. + template + void operator()( FnArgs&... args ) { + internal::convert_and_call_impl::doit( my_finalize_func, my_ip, args... ); + } + private: + kernel_input_tuple &my_ip; + + struct finalize_func : tbb::internal::no_assign { + StreamFactory &my_factory; + device_type my_device; + FinalizeFn my_fn; + + finalize_func( StreamFactory &factory, device_type device, FinalizeFn fn ) + : my_factory(factory), my_device(device), my_fn(fn) {} + + template + void operator()( FnArgs&... args ) { + my_factory.finalize( my_device, my_fn, args... ); + } + } my_finalize_func; + }; + + template + static run_finalize_func make_run_finalize_func( kernel_input_tuple &ip, StreamFactory &factory, FinalizeFn fn ) { + return run_finalize_func( ip, factory, fn ); + } + + class send_func : tbb::internal::no_assign { + public: + send_func( StreamFactory &factory, device_type d ) + : my_factory(factory), my_device( d ) {} + + template + void operator()( FnArgs&... args ) { + my_factory.send_data( my_device, args... ); + } + private: + StreamFactory &my_factory; + device_type my_device; + }; + + public: + args_storage( const kernel_type& kernel, StreamFactory &f, Args&&... args ) + : args_storage_base( kernel, f ) + , my_args_pack( std::forward(args)... ) + {} + + args_storage( const args_storage &k ) : args_storage_base( k ), my_args_pack( k.my_args_pack ) {} + + args_storage( const args_storage_base &k, Args&&... args ) : args_storage_base( k ), my_args_pack( std::forward(args)... ) {} + + void enqueue( kernel_input_tuple &ip, output_ports_type &op, const streaming_node &n ) __TBB_override { + // Make const qualified args_pack (from non-const) + const args_pack_type& const_args_pack = my_args_pack; + // factory.enqure_kernel() gets + // - 'ip' tuple elements by reference and updates it (and 'ip') with dependencies + // - arguments (from my_args_pack) by const-reference via const_args_pack + tbb::internal::call( run_kernel_func( ip, n, *this ), const_args_pack ); + + if (! do_try_put( ip, op, input_sequence() ) ) { + graph& g = n.my_graph; + // No one message was passed to successors so set a callback to extend the graph lifetime until the kernel completion. + g.increment_wait_count(); + + // factory.finalize() gets + // - 'ip' tuple elements by reference, so 'ip' might be changed + // - arguments (from my_args_pack) by const-reference via const_args_pack + tbb::internal::call( make_run_finalize_func(ip, this->my_factory, [&g] { + g.decrement_wait_count(); + }), const_args_pack ); + } + } + + void send( device_type d ) __TBB_override { + // factory.send() gets arguments by reference and updates these arguments with dependencies + // (it gets but usually ignores port_ref-s) + tbb::internal::call( send_func( this->my_factory, d ), my_args_pack ); + } + + args_storage_base *clone() const __TBB_override { + // Create new args_storage with copying constructor. + return new args_storage( *this ); + } + + private: + typedef tbb::internal::stored_pack args_pack_type; + args_pack_type my_args_pack; + }; + + // Body for kernel_multifunction_node. + class kernel_body : tbb::internal::no_assign { + public: + kernel_body( const streaming_node &node ) : my_node( node ) {} + + void operator()( kernel_input_tuple ip, typename args_storage_base::output_ports_type &op ) { + __TBB_ASSERT( (my_node.my_args_storage != NULL), "No arguments storage" ); + // 'ip' is passed by value to create local copy for updating inside enqueue_kernel() + my_node.my_args_storage->enqueue( ip, op, my_node ); + } + private: + const streaming_node &my_node; + }; + + template ::type > + struct wrap_to_async { + typedef T type; // Keep port_ref as it is + }; + + template + struct wrap_to_async { + typedef typename StreamFactory::template async_msg_type< typename tbb::internal::strip::type > type; + }; + + template + args_storage_base *make_args_storage(const args_storage_base& storage, Args&&... args) const { + // In this variadic template convert all simple types 'T' into 'async_msg_type' + return new args_storage(storage, std::forward(args)...); + } + + void notify_new_device( device_type d ) { + my_args_storage->send( d ); + } + + template + void enqueue_kernel( kernel_input_tuple& ip, StreamFactory& factory, device_type device, const kernel_type& kernel, Args&... args ) const { + this->enqueue_kernel_impl( ip, factory, device, kernel, args... ); + } + +public: + template + streaming_node( graph &g, const kernel_type& kernel, DeviceSelector d, StreamFactory &f ) + : base_type( g ) + , my_indexer_node( g ) + , my_device_selector( new device_selector( d, *this, f ) ) + , my_device_selector_node( g, serial, device_selector_body( my_device_selector ) ) + , my_join_node( g ) + , my_kernel_node( g, serial, kernel_body( *this ) ) + // By default, streaming_node maps all its ports to the kernel arguments on a one-to-one basis. + , my_args_storage( make_args_storage( args_storage<>(kernel, f), port_ref<0, NUM_INPUTS - 1>() ) ) + { + base_type::set_external_ports( get_input_ports(), get_output_ports() ); + make_edges(); + } + + streaming_node( const streaming_node &node ) + : base_type( node.my_graph ) + , my_indexer_node( node.my_indexer_node ) + , my_device_selector( node.my_device_selector->clone( *this ) ) + , my_device_selector_node( node.my_graph, serial, device_selector_body( my_device_selector ) ) + , my_join_node( node.my_join_node ) + , my_kernel_node( node.my_graph, serial, kernel_body( *this ) ) + , my_args_storage( node.my_args_storage->clone() ) + { + base_type::set_external_ports( get_input_ports(), get_output_ports() ); + make_edges(); + } + + streaming_node( streaming_node &&node ) + : base_type( node.my_graph ) + , my_indexer_node( std::move( node.my_indexer_node ) ) + , my_device_selector( node.my_device_selector->clone(*this) ) + , my_device_selector_node( node.my_graph, serial, device_selector_body( my_device_selector ) ) + , my_join_node( std::move( node.my_join_node ) ) + , my_kernel_node( node.my_graph, serial, kernel_body( *this ) ) + , my_args_storage( node.my_args_storage ) + { + base_type::set_external_ports( get_input_ports(), get_output_ports() ); + make_edges(); + // Set moving node mappers to NULL to prevent double deallocation. + node.my_args_storage = NULL; + } + + ~streaming_node() { + if ( my_args_storage ) delete my_args_storage; + if ( my_device_selector ) delete my_device_selector; + } + + template + void set_args( Args&&... args ) { + // Copy the base class of args_storage and create new storage for "Args...". + args_storage_base * const new_args_storage = make_args_storage( *my_args_storage, typename wrap_to_async::type(std::forward(args))...); + delete my_args_storage; + my_args_storage = new_args_storage; + } + +protected: + void reset_node( reset_flags = rf_reset_protocol ) __TBB_override { __TBB_ASSERT( false, "Not implemented yet" ); } + +private: + indexer_node_type my_indexer_node; + device_selector_base *my_device_selector; + device_selector_node my_device_selector_node; + join_node my_join_node; + kernel_multifunction_node my_kernel_node; + + args_storage_base *my_args_storage; +}; + +#endif // __TBB_PREVIEW_STREAMING_NODE +#endif // __TBB_flow_graph_streaming_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_tagged_buffer_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_tagged_buffer_impl.h new file mode 100644 index 00000000..92291129 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_tagged_buffer_impl.h @@ -0,0 +1,249 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// a hash table buffer that can expand, and can support as many deletions as +// additions, list-based, with elements of list held in array (for destruction +// management), multiplicative hashing (like ets). No synchronization built-in. +// + +#ifndef __TBB__flow_graph_hash_buffer_impl_H +#define __TBB__flow_graph_hash_buffer_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +// included in namespace tbb::flow::interfaceX::internal + +// elements in the table are a simple list; we need pointer to next element to +// traverse the chain +template +struct buffer_element_type { + // the second parameter below is void * because we can't forward-declare the type + // itself, so we just reinterpret_cast below. + typedef typename aligned_pair::type type; +}; + +template + < + typename Key, // type of key within ValueType + typename ValueType, + typename ValueToKey, // abstract method that returns "const Key" or "const Key&" given ValueType + typename HashCompare, // has hash and equal + typename Allocator=tbb::cache_aligned_allocator< typename aligned_pair::type > + > +class hash_buffer : public HashCompare { +public: + static const size_t INITIAL_SIZE = 8; // initial size of the hash pointer table + typedef ValueType value_type; + typedef typename buffer_element_type< value_type >::type element_type; + typedef value_type *pointer_type; + typedef element_type *list_array_type; // array we manage manually + typedef list_array_type *pointer_array_type; + typedef typename Allocator::template rebind::other pointer_array_allocator_type; + typedef typename Allocator::template rebind::other elements_array_allocator; + typedef typename tbb::internal::strip::type Knoref; + +private: + ValueToKey *my_key; + size_t my_size; + size_t nelements; + pointer_array_type pointer_array; // pointer_array[my_size] + list_array_type elements_array; // elements_array[my_size / 2] + element_type* free_list; + + size_t mask() { return my_size - 1; } + + void set_up_free_list( element_type **p_free_list, list_array_type la, size_t sz) { + for(size_t i=0; i < sz - 1; ++i ) { // construct free list + la[i].second = &(la[i+1]); + } + la[sz-1].second = NULL; + *p_free_list = (element_type *)&(la[0]); + } + + // cleanup for exceptions + struct DoCleanup { + pointer_array_type *my_pa; + list_array_type *my_elements; + size_t my_size; + + DoCleanup(pointer_array_type &pa, list_array_type &my_els, size_t sz) : + my_pa(&pa), my_elements(&my_els), my_size(sz) { } + ~DoCleanup() { + if(my_pa) { + size_t dont_care = 0; + internal_free_buffer(*my_pa, *my_elements, my_size, dont_care); + } + } + }; + + // exception-safety requires we do all the potentially-throwing operations first + void grow_array() { + size_t new_size = my_size*2; + size_t new_nelements = nelements; // internal_free_buffer zeroes this + list_array_type new_elements_array = NULL; + pointer_array_type new_pointer_array = NULL; + list_array_type new_free_list = NULL; + { + DoCleanup my_cleanup(new_pointer_array, new_elements_array, new_size); + new_elements_array = elements_array_allocator().allocate(my_size); + new_pointer_array = pointer_array_allocator_type().allocate(new_size); + for(size_t i=0; i < new_size; ++i) new_pointer_array[i] = NULL; + set_up_free_list(&new_free_list, new_elements_array, my_size ); + + for(size_t i=0; i < my_size; ++i) { + for( element_type* op = pointer_array[i]; op; op = (element_type *)(op->second)) { + value_type *ov = reinterpret_cast(&(op->first)); + // could have std::move semantics + internal_insert_with_key(new_pointer_array, new_size, new_free_list, *ov); + } + } + my_cleanup.my_pa = NULL; + my_cleanup.my_elements = NULL; + } + + internal_free_buffer(pointer_array, elements_array, my_size, nelements); + free_list = new_free_list; + pointer_array = new_pointer_array; + elements_array = new_elements_array; + my_size = new_size; + nelements = new_nelements; + } + + // v should have perfect forwarding if std::move implemented. + // we use this method to move elements in grow_array, so can't use class fields + void internal_insert_with_key( element_type **p_pointer_array, size_t p_sz, list_array_type &p_free_list, + const value_type &v) { + size_t l_mask = p_sz-1; + __TBB_ASSERT(my_key, "Error: value-to-key functor not provided"); + size_t h = this->hash((*my_key)(v)) & l_mask; + __TBB_ASSERT(p_free_list, "Error: free list not set up."); + element_type* my_elem = p_free_list; p_free_list = (element_type *)(p_free_list->second); + (void) new(&(my_elem->first)) value_type(v); + my_elem->second = p_pointer_array[h]; + p_pointer_array[h] = my_elem; + } + + void internal_initialize_buffer() { + pointer_array = pointer_array_allocator_type().allocate(my_size); + for(size_t i = 0; i < my_size; ++i) pointer_array[i] = NULL; + elements_array = elements_array_allocator().allocate(my_size / 2); + set_up_free_list(&free_list, elements_array, my_size / 2); + } + + // made static so an enclosed class can use to properly dispose of the internals + static void internal_free_buffer( pointer_array_type &pa, list_array_type &el, size_t &sz, size_t &ne ) { + if(pa) { + for(size_t i = 0; i < sz; ++i ) { + element_type *p_next; + for( element_type *p = pa[i]; p; p = p_next) { + p_next = (element_type *)p->second; + internal::punned_cast(&(p->first))->~value_type(); + } + } + pointer_array_allocator_type().deallocate(pa, sz); + pa = NULL; + } + // Separate test (if allocation of pa throws, el may be allocated. + // but no elements will be constructed.) + if(el) { + elements_array_allocator().deallocate(el, sz / 2); + el = NULL; + } + sz = INITIAL_SIZE; + ne = 0; + } + +public: + hash_buffer() : my_key(NULL), my_size(INITIAL_SIZE), nelements(0) { + internal_initialize_buffer(); + } + + ~hash_buffer() { + internal_free_buffer(pointer_array, elements_array, my_size, nelements); + if(my_key) delete my_key; + } + + void reset() { + internal_free_buffer(pointer_array, elements_array, my_size, nelements); + internal_initialize_buffer(); + } + + // Take ownership of func object allocated with new. + // This method is only used internally, so can't be misused by user. + void set_key_func(ValueToKey *vtk) { my_key = vtk; } + // pointer is used to clone() + ValueToKey* get_key_func() { return my_key; } + + bool insert_with_key(const value_type &v) { + pointer_type p = NULL; + __TBB_ASSERT(my_key, "Error: value-to-key functor not provided"); + if(find_ref_with_key((*my_key)(v), p)) { + p->~value_type(); + (void) new(p) value_type(v); // copy-construct into the space + return false; + } + ++nelements; + if(nelements*2 > my_size) grow_array(); + internal_insert_with_key(pointer_array, my_size, free_list, v); + return true; + } + + // returns true and sets v to array element if found, else returns false. + bool find_ref_with_key(const Knoref& k, pointer_type &v) { + size_t i = this->hash(k) & mask(); + for(element_type* p = pointer_array[i]; p; p = (element_type *)(p->second)) { + pointer_type pv = reinterpret_cast(&(p->first)); + __TBB_ASSERT(my_key, "Error: value-to-key functor not provided"); + if(this->equal((*my_key)(*pv), k)) { + v = pv; + return true; + } + } + return false; + } + + bool find_with_key( const Knoref& k, value_type &v) { + value_type *p; + if(find_ref_with_key(k, p)) { + v = *p; + return true; + } + else + return false; + } + + void delete_with_key(const Knoref& k) { + size_t h = this->hash(k) & mask(); + element_type* prev = NULL; + for(element_type* p = pointer_array[h]; p; prev = p, p = (element_type *)(p->second)) { + value_type *vp = reinterpret_cast(&(p->first)); + __TBB_ASSERT(my_key, "Error: value-to-key functor not provided"); + if(this->equal((*my_key)(*vp), k)) { + vp->~value_type(); + if(prev) prev->second = p->second; + else pointer_array[h] = (element_type *)(p->second); + p->second = free_list; + free_list = p; + --nelements; + return; + } + } + __TBB_ASSERT(false, "key not found for delete"); + } +}; +#endif // __TBB__flow_graph_hash_buffer_impl_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_trace_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_trace_impl.h new file mode 100644 index 00000000..65809c39 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_trace_impl.h @@ -0,0 +1,364 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _FGT_GRAPH_TRACE_IMPL_H +#define _FGT_GRAPH_TRACE_IMPL_H + +#include "../tbb_profiling.h" +#if (_MSC_VER >= 1900) + #include +#endif + +namespace tbb { + namespace internal { + +#if TBB_USE_THREADING_TOOLS + #if TBB_PREVIEW_FLOW_GRAPH_TRACE + #if (_MSC_VER >= 1900) + #define CODEPTR() (_ReturnAddress()) + #elif __TBB_GCC_VERSION >= 40800 + #define CODEPTR() ( __builtin_return_address(0)) + #else + #define CODEPTR() NULL + #endif + #else + #define CODEPTR() NULL + #endif /* TBB_PREVIEW_FLOW_GRAPH_TRACE */ + +static inline void fgt_alias_port(void *node, void *p, bool visible) { + if(visible) + itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_NODE ); + else + itt_relation_add( ITT_DOMAIN_FLOW, p, FLOW_NODE, __itt_relation_is_child_of, node, FLOW_NODE ); +} + +static inline void fgt_composite ( void* codeptr, void *node, void *graph ) { + itt_make_task_group( ITT_DOMAIN_FLOW, node, FLOW_NODE, graph, FLOW_GRAPH, FLOW_COMPOSITE_NODE ); + suppress_unused_warning( codeptr ); +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + if (codeptr != NULL) { + register_node_addr(ITT_DOMAIN_FLOW, node, FLOW_NODE, CODE_ADDRESS, &codeptr); + } +#endif +} + +static inline void fgt_internal_alias_input_port( void *node, void *p, string_index name_index ) { + itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index ); + itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_INPUT_PORT ); +} + +static inline void fgt_internal_alias_output_port( void *node, void *p, string_index name_index ) { + itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index ); + itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_OUTPUT_PORT ); +} + +template +void alias_input_port(void *node, tbb::flow::receiver* port, string_index name_index) { + // TODO: Make fgt_internal_alias_input_port a function template? + fgt_internal_alias_input_port( node, port, name_index); +} + +template < typename PortsTuple, int N > +struct fgt_internal_input_alias_helper { + static void alias_port( void *node, PortsTuple &ports ) { + alias_input_port( node, &(tbb::flow::get(ports)), static_cast(FLOW_INPUT_PORT_0 + N - 1) ); + fgt_internal_input_alias_helper::alias_port( node, ports ); + } +}; + +template < typename PortsTuple > +struct fgt_internal_input_alias_helper { + static void alias_port( void * /* node */, PortsTuple & /* ports */ ) { } +}; + +template +void alias_output_port(void *node, tbb::flow::sender* port, string_index name_index) { + // TODO: Make fgt_internal_alias_output_port a function template? + fgt_internal_alias_output_port( node, static_cast(port), name_index); +} + +template < typename PortsTuple, int N > +struct fgt_internal_output_alias_helper { + static void alias_port( void *node, PortsTuple &ports ) { + alias_output_port( node, &(tbb::flow::get(ports)), static_cast(FLOW_OUTPUT_PORT_0 + N - 1) ); + fgt_internal_output_alias_helper::alias_port( node, ports ); + } +}; + +template < typename PortsTuple > +struct fgt_internal_output_alias_helper { + static void alias_port( void * /*node*/, PortsTuple &/*ports*/ ) { + } +}; + +static inline void fgt_internal_create_input_port( void *node, void *p, string_index name_index ) { + itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index ); +} + +static inline void fgt_internal_create_output_port( void* codeptr, void *node, void *p, string_index name_index ) { + itt_make_task_group(ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index); + suppress_unused_warning( codeptr ); +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + if (codeptr != NULL) { + register_node_addr(ITT_DOMAIN_FLOW, node, FLOW_NODE, CODE_ADDRESS, &codeptr); + } +#endif +} + +template +void register_input_port(void *node, tbb::flow::receiver* port, string_index name_index) { + // TODO: Make fgt_internal_create_input_port a function template? + // In C++03 dependent name lookup from the template definition context + // works only for function declarations with external linkage: + // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#561 + fgt_internal_create_input_port(node, static_cast(port), name_index); +} + +template < typename PortsTuple, int N > +struct fgt_internal_input_helper { + static void register_port( void *node, PortsTuple &ports ) { + register_input_port( node, &(tbb::flow::get(ports)), static_cast(FLOW_INPUT_PORT_0 + N - 1) ); + fgt_internal_input_helper::register_port( node, ports ); + } +}; + +template < typename PortsTuple > +struct fgt_internal_input_helper { + static void register_port( void *node, PortsTuple &ports ) { + register_input_port( node, &(tbb::flow::get<0>(ports)), FLOW_INPUT_PORT_0 ); + } +}; + +template +void register_output_port(void* codeptr, void *node, tbb::flow::sender* port, string_index name_index) { + // TODO: Make fgt_internal_create_output_port a function template? + fgt_internal_create_output_port( codeptr, node, static_cast(port), name_index); +} + +template < typename PortsTuple, int N > +struct fgt_internal_output_helper { + static void register_port( void* codeptr, void *node, PortsTuple &ports ) { + register_output_port( codeptr, node, &(tbb::flow::get(ports)), static_cast(FLOW_OUTPUT_PORT_0 + N - 1) ); + fgt_internal_output_helper::register_port( codeptr, node, ports ); + } +}; + +template < typename PortsTuple > +struct fgt_internal_output_helper { + static void register_port( void* codeptr, void *node, PortsTuple &ports ) { + register_output_port( codeptr, node, &(tbb::flow::get<0>(ports)), FLOW_OUTPUT_PORT_0 ); + } +}; + +template< typename NodeType > +void fgt_multioutput_node_desc( const NodeType *node, const char *desc ) { + void *addr = (void *)( static_cast< tbb::flow::receiver< typename NodeType::input_type > * >(const_cast< NodeType *>(node)) ); + itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); +} + +template< typename NodeType > +void fgt_multiinput_multioutput_node_desc( const NodeType *node, const char *desc ) { + void *addr = const_cast(node); + itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); +} + +template< typename NodeType > +static inline void fgt_node_desc( const NodeType *node, const char *desc ) { + void *addr = (void *)( static_cast< tbb::flow::sender< typename NodeType::output_type > * >(const_cast< NodeType *>(node)) ); + itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); +} + +static inline void fgt_graph_desc( void *g, const char *desc ) { + itt_metadata_str_add( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, FLOW_OBJECT_NAME, desc ); +} + +static inline void fgt_body( void *node, void *body ) { + itt_relation_add( ITT_DOMAIN_FLOW, body, FLOW_BODY, __itt_relation_is_child_of, node, FLOW_NODE ); +} + +template< int N, typename PortsTuple > +static inline void fgt_multioutput_node(void* codeptr, string_index t, void *g, void *input_port, PortsTuple &ports ) { + itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t ); + fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 ); + fgt_internal_output_helper::register_port(codeptr, input_port, ports ); +} + +template< int N, typename PortsTuple > +static inline void fgt_multioutput_node_with_body( void* codeptr, string_index t, void *g, void *input_port, PortsTuple &ports, void *body ) { + itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t ); + fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 ); + fgt_internal_output_helper::register_port( codeptr, input_port, ports ); + fgt_body( input_port, body ); +} + +template< int N, typename PortsTuple > +static inline void fgt_multiinput_node( void* codeptr, string_index t, void *g, PortsTuple &ports, void *output_port) { + itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); + fgt_internal_create_output_port( codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 ); + fgt_internal_input_helper::register_port( output_port, ports ); +} + +static inline void fgt_multiinput_multioutput_node( void* codeptr, string_index t, void *n, void *g ) { + itt_make_task_group( ITT_DOMAIN_FLOW, n, FLOW_NODE, g, FLOW_GRAPH, t ); + suppress_unused_warning( codeptr ); +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + if (codeptr != NULL) { + register_node_addr(ITT_DOMAIN_FLOW, n, FLOW_NODE, CODE_ADDRESS, &codeptr); + } +#endif +} + +static inline void fgt_node( void* codeptr, string_index t, void *g, void *output_port ) { + itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); + fgt_internal_create_output_port( codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 ); +} + +static void fgt_node_with_body( void* codeptr, string_index t, void *g, void *output_port, void *body ) { + itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); + fgt_internal_create_output_port(codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 ); + fgt_body( output_port, body ); +} + +static inline void fgt_node( void* codeptr, string_index t, void *g, void *input_port, void *output_port ) { + fgt_node( codeptr, t, g, output_port ); + fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 ); +} + +static inline void fgt_node_with_body( void* codeptr, string_index t, void *g, void *input_port, void *output_port, void *body ) { + fgt_node_with_body( codeptr, t, g, output_port, body ); + fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 ); +} + + +static inline void fgt_node( void* codeptr, string_index t, void *g, void *input_port, void *decrement_port, void *output_port ) { + fgt_node( codeptr, t, g, input_port, output_port ); + fgt_internal_create_input_port( output_port, decrement_port, FLOW_INPUT_PORT_1 ); +} + +static inline void fgt_make_edge( void *output_port, void *input_port ) { + itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_predecessor_to, input_port, FLOW_INPUT_PORT); +} + +static inline void fgt_remove_edge( void *output_port, void *input_port ) { + itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_sibling_of, input_port, FLOW_INPUT_PORT); +} + +static inline void fgt_graph( void *g ) { + itt_make_task_group( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, NULL, FLOW_NULL, FLOW_GRAPH ); +} + +static inline void fgt_begin_body( void *body ) { + itt_task_begin( ITT_DOMAIN_FLOW, body, FLOW_BODY, NULL, FLOW_NULL, FLOW_BODY ); +} + +static inline void fgt_end_body( void * ) { + itt_task_end( ITT_DOMAIN_FLOW ); +} + +static inline void fgt_async_try_put_begin( void *node, void *port ) { + itt_task_begin( ITT_DOMAIN_FLOW, port, FLOW_OUTPUT_PORT, node, FLOW_NODE, FLOW_OUTPUT_PORT ); +} + +static inline void fgt_async_try_put_end( void *, void * ) { + itt_task_end( ITT_DOMAIN_FLOW ); +} + +static inline void fgt_async_reserve( void *node, void *graph ) { + itt_region_begin( ITT_DOMAIN_FLOW, node, FLOW_NODE, graph, FLOW_GRAPH, FLOW_NULL ); +} + +static inline void fgt_async_commit( void *node, void * /*graph*/) { + itt_region_end( ITT_DOMAIN_FLOW, node, FLOW_NODE ); +} + +static inline void fgt_reserve_wait( void *graph ) { + itt_region_begin( ITT_DOMAIN_FLOW, graph, FLOW_GRAPH, NULL, FLOW_NULL, FLOW_NULL ); +} + +static inline void fgt_release_wait( void *graph ) { + itt_region_end( ITT_DOMAIN_FLOW, graph, FLOW_GRAPH ); +} + +#else // TBB_USE_THREADING_TOOLS + +#define CODEPTR() NULL + +static inline void fgt_alias_port(void * /*node*/, void * /*p*/, bool /*visible*/ ) { } + +static inline void fgt_composite ( void* /*codeptr*/, void * /*node*/, void * /*graph*/ ) { } + +static inline void fgt_graph( void * /*g*/ ) { } + +template< typename NodeType > +static inline void fgt_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { } + +template< typename NodeType > +static inline void fgt_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { } + +static inline void fgt_graph_desc( void * /*g*/, const char * /*desc*/ ) { } + +static inline void fgt_body( void * /*node*/, void * /*body*/ ) { } + +template< int N, typename PortsTuple > +static inline void fgt_multioutput_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/ ) { } + +template< int N, typename PortsTuple > +static inline void fgt_multioutput_node_with_body( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/, void * /*body*/ ) { } + +template< int N, typename PortsTuple > +static inline void fgt_multiinput_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, PortsTuple & /*ports*/, void * /*output_port*/ ) { } + +static inline void fgt_multiinput_multioutput_node( void* /*codeptr*/, string_index /*t*/, void * /*node*/, void * /*graph*/ ) { } + +static inline void fgt_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*output_port*/ ) { } +static inline void fgt_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/ ) { } +static inline void fgt_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*decrement_port*/, void * /*output_port*/ ) { } + +static inline void fgt_node_with_body( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*output_port*/, void * /*body*/ ) { } +static inline void fgt_node_with_body( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/, void * /*body*/ ) { } + +static inline void fgt_make_edge( void * /*output_port*/, void * /*input_port*/ ) { } +static inline void fgt_remove_edge( void * /*output_port*/, void * /*input_port*/ ) { } + +static inline void fgt_begin_body( void * /*body*/ ) { } +static inline void fgt_end_body( void * /*body*/) { } + +static inline void fgt_async_try_put_begin( void * /*node*/, void * /*port*/ ) { } +static inline void fgt_async_try_put_end( void * /*node*/ , void * /*port*/ ) { } +static inline void fgt_async_reserve( void * /*node*/, void * /*graph*/ ) { } +static inline void fgt_async_commit( void * /*node*/, void * /*graph*/ ) { } +static inline void fgt_reserve_wait( void * /*graph*/ ) { } +static inline void fgt_release_wait( void * /*graph*/ ) { } + +template< typename NodeType > +void fgt_multiinput_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { } + +template < typename PortsTuple, int N > +struct fgt_internal_input_alias_helper { + static void alias_port( void * /*node*/, PortsTuple & /*ports*/ ) { } +}; + +template < typename PortsTuple, int N > +struct fgt_internal_output_alias_helper { + static void alias_port( void * /*node*/, PortsTuple & /*ports*/ ) { } +}; + +#endif // TBB_USE_THREADING_TOOLS + + } // namespace internal +} // namespace tbb + +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_types_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_types_impl.h new file mode 100644 index 00000000..f374831b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_flow_graph_types_impl.h @@ -0,0 +1,723 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__flow_graph_types_impl_H +#define __TBB__flow_graph_types_impl_H + +#ifndef __TBB_flow_graph_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +// included in namespace tbb::flow::interfaceX + +namespace internal { + + // the change to key_matching (adding a K and KHash template parameter, making it a class) + // means we have to pass this data to the key_matching_port. All the ports have only one + // template parameter, so we have to wrap the following types in a trait: + // + // . K == key_type + // . KHash == hash and compare for Key + // . TtoK == function_body that given an object of T, returns its K + // . T == type accepted by port, and stored in the hash table + // + // The port will have an additional parameter on node construction, which is a function_body + // that accepts a const T& and returns a K which is the field in T which is its K. + template + struct KeyTrait { + typedef Kp K; + typedef Tp T; + typedef internal::type_to_key_function_body TtoK; + typedef KHashp KHash; + }; + + // wrap each element of a tuple in a template, and make a tuple of the result. + template class PT, typename TypeTuple> + struct wrap_tuple_elements; + + // A wrapper that generates the traits needed for each port of a key-matching join, + // and the type of the tuple of input ports. + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements; + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_VARIADIC_TUPLE_PRESENT + template class PT, typename... Args> + struct wrap_tuple_elements >{ + typedef typename tbb::flow::tuple... > type; + }; + + template class PT, typename KeyTraits, typename... Args> + struct wrap_key_tuple_elements > { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef typename tbb::flow::tuple >... > type; + }; +#else + template class PT, typename TypeTuple> + struct wrap_tuple_elements<1, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<1, PT, KeyTraits, TypeTuple > { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef typename tbb::flow::tuple< PT > type; + }; + + template class PT, typename TypeTuple> + struct wrap_tuple_elements<2, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<2, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef typename tbb::flow::tuple< PT, PT > type; + }; + + template class PT, typename TypeTuple> + struct wrap_tuple_elements<3, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<3, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef KeyTrait::type> KeyTrait2; + typedef typename tbb::flow::tuple< PT, PT, PT > type; + }; + + template class PT, typename TypeTuple> + struct wrap_tuple_elements<4, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type>, + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<4, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef KeyTrait::type> KeyTrait2; + typedef KeyTrait::type> KeyTrait3; + typedef typename tbb::flow::tuple< PT, PT, PT, + PT > type; + }; + + template class PT, typename TypeTuple> + struct wrap_tuple_elements<5, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<5, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef KeyTrait::type> KeyTrait2; + typedef KeyTrait::type> KeyTrait3; + typedef KeyTrait::type> KeyTrait4; + typedef typename tbb::flow::tuple< PT, PT, PT, + PT, PT > type; + }; + +#if __TBB_VARIADIC_MAX >= 6 + template class PT, typename TypeTuple> + struct wrap_tuple_elements<6, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<6, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef KeyTrait::type> KeyTrait2; + typedef KeyTrait::type> KeyTrait3; + typedef KeyTrait::type> KeyTrait4; + typedef KeyTrait::type> KeyTrait5; + typedef typename tbb::flow::tuple< PT, PT, PT, PT, + PT, PT > type; + }; +#endif + +#if __TBB_VARIADIC_MAX >= 7 + template class PT, typename TypeTuple> + struct wrap_tuple_elements<7, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<7, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef KeyTrait::type> KeyTrait2; + typedef KeyTrait::type> KeyTrait3; + typedef KeyTrait::type> KeyTrait4; + typedef KeyTrait::type> KeyTrait5; + typedef KeyTrait::type> KeyTrait6; + typedef typename tbb::flow::tuple< PT, PT, PT, PT, + PT, PT, PT > type; + }; +#endif + +#if __TBB_VARIADIC_MAX >= 8 + template class PT, typename TypeTuple> + struct wrap_tuple_elements<8, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<8, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef KeyTrait::type> KeyTrait2; + typedef KeyTrait::type> KeyTrait3; + typedef KeyTrait::type> KeyTrait4; + typedef KeyTrait::type> KeyTrait5; + typedef KeyTrait::type> KeyTrait6; + typedef KeyTrait::type> KeyTrait7; + typedef typename tbb::flow::tuple< PT, PT, PT, PT, + PT, PT, PT, PT > type; + }; +#endif + +#if __TBB_VARIADIC_MAX >= 9 + template class PT, typename TypeTuple> + struct wrap_tuple_elements<9, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<9, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef KeyTrait::type> KeyTrait2; + typedef KeyTrait::type> KeyTrait3; + typedef KeyTrait::type> KeyTrait4; + typedef KeyTrait::type> KeyTrait5; + typedef KeyTrait::type> KeyTrait6; + typedef KeyTrait::type> KeyTrait7; + typedef KeyTrait::type> KeyTrait8; + typedef typename tbb::flow::tuple< PT, PT, PT, PT, + PT, PT, PT, PT, PT > type; + }; +#endif + +#if __TBB_VARIADIC_MAX >= 10 + template class PT, typename TypeTuple> + struct wrap_tuple_elements<10, PT, TypeTuple> { + typedef typename tbb::flow::tuple< + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type>, + PT::type> > + type; + }; + + template class PT, typename KeyTraits, typename TypeTuple> + struct wrap_key_tuple_elements<10, PT, KeyTraits, TypeTuple> { + typedef typename KeyTraits::key_type K; + typedef typename KeyTraits::hash_compare_type KHash; + typedef KeyTrait::type> KeyTrait0; + typedef KeyTrait::type> KeyTrait1; + typedef KeyTrait::type> KeyTrait2; + typedef KeyTrait::type> KeyTrait3; + typedef KeyTrait::type> KeyTrait4; + typedef KeyTrait::type> KeyTrait5; + typedef KeyTrait::type> KeyTrait6; + typedef KeyTrait::type> KeyTrait7; + typedef KeyTrait::type> KeyTrait8; + typedef KeyTrait::type> KeyTrait9; + typedef typename tbb::flow::tuple< PT, PT, PT, PT, + PT, PT, PT, PT, PT, + PT > type; + }; +#endif +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_VARIADIC_TUPLE_PRESENT */ + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template< int... S > class sequence {}; + + template< int N, int... S > + struct make_sequence : make_sequence < N - 1, N - 1, S... > {}; + + template< int... S > + struct make_sequence < 0, S... > { + typedef sequence type; + }; +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ + +#if __TBB_INITIALIZER_LISTS_PRESENT + // Until C++14 std::initializer_list does not guarantee life time of contained objects. + template + class initializer_list_wrapper { + public: + typedef T value_type; + typedef const T& reference; + typedef const T& const_reference; + typedef size_t size_type; + + typedef T* iterator; + typedef const T* const_iterator; + + initializer_list_wrapper( std::initializer_list il ) __TBB_NOEXCEPT( true ) : my_begin( static_cast(malloc( il.size()*sizeof( T ) )) ) { + iterator dst = my_begin; + for ( typename std::initializer_list::const_iterator src = il.begin(); src != il.end(); ++src ) + new (dst++) T( *src ); + my_end = dst; + } + + initializer_list_wrapper( const initializer_list_wrapper& ilw ) __TBB_NOEXCEPT( true ) : my_begin( static_cast(malloc( ilw.size()*sizeof( T ) )) ) { + iterator dst = my_begin; + for ( typename std::initializer_list::const_iterator src = ilw.begin(); src != ilw.end(); ++src ) + new (dst++) T( *src ); + my_end = dst; + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + initializer_list_wrapper( initializer_list_wrapper&& ilw ) __TBB_NOEXCEPT( true ) : my_begin( ilw.my_begin ), my_end( ilw.my_end ) { + ilw.my_begin = ilw.my_end = NULL; + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + ~initializer_list_wrapper() { + if ( my_begin ) + free( my_begin ); + } + + const_iterator begin() const __TBB_NOEXCEPT(true) { return my_begin; } + const_iterator end() const __TBB_NOEXCEPT(true) { return my_end; } + size_t size() const __TBB_NOEXCEPT(true) { return (size_t)(my_end - my_begin); } + + private: + iterator my_begin; + iterator my_end; + }; +#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ + +//! type mimicking std::pair but with trailing fill to ensure each element of an array +//* will have the correct alignment + template + struct type_plus_align { + char first[sizeof(T1)]; + T2 second; + char fill1[REM]; + }; + + template + struct type_plus_align { + char first[sizeof(T1)]; + T2 second; + }; + + template struct alignment_of { + typedef struct { char t; U padded; } test_alignment; + static const size_t value = sizeof(test_alignment) - sizeof(U); + }; + + // T1, T2 are actual types stored. The space defined for T1 in the type returned + // is a char array of the correct size. Type T2 should be trivially-constructible, + // T1 must be explicitly managed. + template + struct aligned_pair { + static const size_t t1_align = alignment_of::value; + static const size_t t2_align = alignment_of::value; + typedef type_plus_align just_pair; + static const size_t max_align = t1_align < t2_align ? t2_align : t1_align; + static const size_t extra_bytes = sizeof(just_pair) % max_align; + static const size_t remainder = extra_bytes ? max_align - extra_bytes : 0; + public: + typedef type_plus_align type; + }; // aligned_pair + +// support for variant type +// type we use when we're not storing a value +struct default_constructed { }; + +// type which contains another type, tests for what type is contained, and references to it. +// internal::Wrapper +// void CopyTo( void *newSpace) : builds a Wrapper copy of itself in newSpace + +// struct to allow us to copy and test the type of objects +struct WrapperBase { + virtual ~WrapperBase() {} + virtual void CopyTo(void* /*newSpace*/) const { } +}; + +// Wrapper contains a T, with the ability to test what T is. The Wrapper can be +// constructed from a T, can be copy-constructed from another Wrapper, and can be +// examined via value(), but not modified. +template +struct Wrapper: public WrapperBase { + typedef T value_type; + typedef T* pointer_type; +private: + T value_space; +public: + const value_type &value() const { return value_space; } + +private: + Wrapper(); + + // on exception will ensure the Wrapper will contain only a trivially-constructed object + struct _unwind_space { + pointer_type space; + _unwind_space(pointer_type p) : space(p) {} + ~_unwind_space() { + if(space) (void) new (space) Wrapper(default_constructed()); + } + }; +public: + explicit Wrapper( const T& other ) : value_space(other) { } + explicit Wrapper(const Wrapper& other) : value_space(other.value_space) { } + + void CopyTo(void* newSpace) const __TBB_override { + _unwind_space guard((pointer_type)newSpace); + (void) new(newSpace) Wrapper(value_space); + guard.space = NULL; + } + ~Wrapper() { } +}; + +// specialization for array objects +template +struct Wrapper : public WrapperBase { + typedef T value_type; + typedef T* pointer_type; + // space must be untyped. + typedef T ArrayType[N]; +private: + // The space is not of type T[N] because when copy-constructing, it would be + // default-initialized and then copied to in some fashion, resulting in two + // constructions and one destruction per element. If the type is char[ ], we + // placement new into each element, resulting in one construction per element. + static const size_t space_size = sizeof(ArrayType) / sizeof(char); + char value_space[space_size]; + + + // on exception will ensure the already-built objects will be destructed + // (the value_space is a char array, so it is already trivially-destructible.) + struct _unwind_class { + pointer_type space; + int already_built; + _unwind_class(pointer_type p) : space(p), already_built(0) {} + ~_unwind_class() { + if(space) { + for(size_t i = already_built; i > 0 ; --i ) space[i-1].~value_type(); + (void) new(space) Wrapper(default_constructed()); + } + } + }; +public: + const ArrayType &value() const { + char *vp = const_cast(value_space); + return reinterpret_cast(*vp); + } + +private: + Wrapper(); +public: + // have to explicitly construct because other decays to a const value_type* + explicit Wrapper(const ArrayType& other) { + _unwind_class guard((pointer_type)value_space); + pointer_type vp = reinterpret_cast(&value_space); + for(size_t i = 0; i < N; ++i ) { + (void) new(vp++) value_type(other[i]); + ++(guard.already_built); + } + guard.space = NULL; + } + explicit Wrapper(const Wrapper& other) : WrapperBase() { + // we have to do the heavy lifting to copy contents + _unwind_class guard((pointer_type)value_space); + pointer_type dp = reinterpret_cast(value_space); + pointer_type sp = reinterpret_cast(const_cast(other.value_space)); + for(size_t i = 0; i < N; ++i, ++dp, ++sp) { + (void) new(dp) value_type(*sp); + ++(guard.already_built); + } + guard.space = NULL; + } + + void CopyTo(void* newSpace) const __TBB_override { + (void) new(newSpace) Wrapper(*this); // exceptions handled in copy constructor + } + + ~Wrapper() { + // have to destroy explicitly in reverse order + pointer_type vp = reinterpret_cast(&value_space); + for(size_t i = N; i > 0 ; --i ) vp[i-1].~value_type(); + } +}; + +// given a tuple, return the type of the element that has the maximum alignment requirement. +// Given a tuple and that type, return the number of elements of the object with the max +// alignment requirement that is at least as big as the largest object in the tuple. + +template struct pick_one; +template struct pick_one { typedef T1 type; }; +template struct pick_one { typedef T2 type; }; + +template< template class Selector, typename T1, typename T2 > +struct pick_max { + typedef typename pick_one< (Selector::value > Selector::value), T1, T2 >::type type; +}; + +template struct size_of { static const int value = sizeof(T); }; + +template< size_t N, class Tuple, template class Selector > struct pick_tuple_max { + typedef typename pick_tuple_max::type LeftMaxType; + typedef typename tbb::flow::tuple_element::type ThisType; + typedef typename pick_max::type type; +}; + +template< class Tuple, template class Selector > struct pick_tuple_max<0, Tuple, Selector> { + typedef typename tbb::flow::tuple_element<0, Tuple>::type type; +}; + +// is the specified type included in a tuple? +template +struct is_element_of { + typedef typename tbb::flow::tuple_element::type T_i; + static const bool value = tbb::internal::is_same_type::value || is_element_of::value; +}; + +template +struct is_element_of { + typedef typename tbb::flow::tuple_element<0, Tuple>::type T_i; + static const bool value = tbb::internal::is_same_type::value; +}; + +// allow the construction of types that are listed tuple. If a disallowed type +// construction is written, a method involving this type is created. The +// type has no definition, so a syntax error is generated. +template struct ERROR_Type_Not_allowed_In_Tagged_Msg_Not_Member_Of_Tuple; + +template struct do_if; +template +struct do_if { + static void construct(void *mySpace, const T& x) { + (void) new(mySpace) Wrapper(x); + } +}; +template +struct do_if { + static void construct(void * /*mySpace*/, const T& x) { + // This method is instantiated when the type T does not match any of the + // element types in the Tuple in variant. + ERROR_Type_Not_allowed_In_Tagged_Msg_Not_Member_Of_Tuple::bad_type(x); + } +}; + +// Tuple tells us the allowed types that variant can hold. It determines the alignment of the space in +// Wrapper, and how big Wrapper is. +// +// the object can only be tested for type, and a read-only reference can be fetched by cast_to(). + +using tbb::internal::punned_cast; +struct tagged_null_type {}; +template +class tagged_msg { + typedef tbb::flow::tuple= 6 + , T5 + #endif + #if __TBB_VARIADIC_MAX >= 7 + , T6 + #endif + #if __TBB_VARIADIC_MAX >= 8 + , T7 + #endif + #if __TBB_VARIADIC_MAX >= 9 + , T8 + #endif + #if __TBB_VARIADIC_MAX >= 10 + , T9 + #endif + > Tuple; + +private: + class variant { + static const size_t N = tbb::flow::tuple_size::value; + typedef typename pick_tuple_max::type AlignType; + typedef typename pick_tuple_max::type MaxSizeType; + static const size_t MaxNBytes = (sizeof(Wrapper)+sizeof(AlignType)-1); + static const size_t MaxNElements = MaxNBytes/sizeof(AlignType); + typedef typename tbb::aligned_space SpaceType; + SpaceType my_space; + static const size_t MaxSize = sizeof(SpaceType); + + public: + variant() { (void) new(&my_space) Wrapper(default_constructed()); } + + template + variant( const T& x ) { + do_if::value>::construct(&my_space,x); + } + + variant(const variant& other) { + const WrapperBase * h = punned_cast(&(other.my_space)); + h->CopyTo(&my_space); + } + + // assignment must destroy and re-create the Wrapper type, as there is no way + // to create a Wrapper-to-Wrapper assign even if we find they agree in type. + void operator=( const variant& rhs ) { + if(&rhs != this) { + WrapperBase *h = punned_cast(&my_space); + h->~WrapperBase(); + const WrapperBase *ch = punned_cast(&(rhs.my_space)); + ch->CopyTo(&my_space); + } + } + + template + const U& variant_cast_to() const { + const Wrapper *h = dynamic_cast*>(punned_cast(&my_space)); + if(!h) { + tbb::internal::throw_exception(tbb::internal::eid_bad_tagged_msg_cast); + } + return h->value(); + } + template + bool variant_is_a() const { return dynamic_cast*>(punned_cast(&my_space)) != NULL; } + + bool variant_is_default_constructed() const {return variant_is_a();} + + ~variant() { + WrapperBase *h = punned_cast(&my_space); + h->~WrapperBase(); + } + }; //class variant + + TagType my_tag; + variant my_msg; + +public: + tagged_msg(): my_tag(TagType(~0)), my_msg(){} + + template + tagged_msg(T const &index, R const &value) : my_tag(index), my_msg(value) {} + + #if __TBB_CONST_REF_TO_ARRAY_TEMPLATE_PARAM_BROKEN + template + tagged_msg(T const &index, R (&value)[N]) : my_tag(index), my_msg(value) {} + #endif + + void set_tag(TagType const &index) {my_tag = index;} + TagType tag() const {return my_tag;} + + template + const V& cast_to() const {return my_msg.template variant_cast_to();} + + template + bool is_a() const {return my_msg.template variant_is_a();} + + bool is_default_constructed() const {return my_msg.variant_is_default_constructed();} +}; //class tagged_msg + +// template to simplify cast and test for tagged_msg in template contexts +template +const V& cast_to(T const &t) { return t.template cast_to(); } + +template +bool is_a(T const &t) { return t.template is_a(); } + +enum op_stat { WAIT = 0, SUCCEEDED, FAILED }; + +} // namespace internal + +#endif /* __TBB__flow_graph_types_impl_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_mutex_padding.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_mutex_padding.h new file mode 100644 index 00000000..d26f5f48 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_mutex_padding.h @@ -0,0 +1,98 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_mutex_padding_H +#define __TBB_mutex_padding_H + +// wrapper for padding mutexes to be alone on a cache line, without requiring they be allocated +// from a pool. Because we allow them to be defined anywhere they must be two cache lines in size. + + +namespace tbb { +namespace interface7 { +namespace internal { + +static const size_t cache_line_size = 64; + +// Pad a mutex to occupy a number of full cache lines sufficient to avoid false sharing +// with other data; space overhead is up to 2*cache_line_size-1. +template class padded_mutex; + +template +class padded_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { + typedef long pad_type; + pad_type my_pad[((sizeof(Mutex)+cache_line_size-1)/cache_line_size+1)*cache_line_size/sizeof(pad_type)]; + + Mutex *impl() { return (Mutex *)((uintptr_t(this)|(cache_line_size-1))+1);} + +public: + static const bool is_rw_mutex = Mutex::is_rw_mutex; + static const bool is_recursive_mutex = Mutex::is_recursive_mutex; + static const bool is_fair_mutex = Mutex::is_fair_mutex; + + padded_mutex() { new(impl()) Mutex(); } + ~padded_mutex() { impl()->~Mutex(); } + + //! Represents acquisition of a mutex. + class scoped_lock : tbb::internal::no_copy { + typename Mutex::scoped_lock my_scoped_lock; + public: + scoped_lock() : my_scoped_lock() {} + scoped_lock( padded_mutex& m ) : my_scoped_lock(*m.impl()) { } + ~scoped_lock() { } + + void acquire( padded_mutex& m ) { my_scoped_lock.acquire(*m.impl()); } + bool try_acquire( padded_mutex& m ) { return my_scoped_lock.try_acquire(*m.impl()); } + void release() { my_scoped_lock.release(); } + }; +}; + +template +class padded_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { + typedef long pad_type; + pad_type my_pad[((sizeof(Mutex)+cache_line_size-1)/cache_line_size+1)*cache_line_size/sizeof(pad_type)]; + + Mutex *impl() { return (Mutex *)((uintptr_t(this)|(cache_line_size-1))+1);} + +public: + static const bool is_rw_mutex = Mutex::is_rw_mutex; + static const bool is_recursive_mutex = Mutex::is_recursive_mutex; + static const bool is_fair_mutex = Mutex::is_fair_mutex; + + padded_mutex() { new(impl()) Mutex(); } + ~padded_mutex() { impl()->~Mutex(); } + + //! Represents acquisition of a mutex. + class scoped_lock : tbb::internal::no_copy { + typename Mutex::scoped_lock my_scoped_lock; + public: + scoped_lock() : my_scoped_lock() {} + scoped_lock( padded_mutex& m, bool write = true ) : my_scoped_lock(*m.impl(),write) { } + ~scoped_lock() { } + + void acquire( padded_mutex& m, bool write = true ) { my_scoped_lock.acquire(*m.impl(),write); } + bool try_acquire( padded_mutex& m, bool write = true ) { return my_scoped_lock.try_acquire(*m.impl(),write); } + bool upgrade_to_writer() { return my_scoped_lock.upgrade_to_writer(); } + bool downgrade_to_reader() { return my_scoped_lock.downgrade_to_reader(); } + void release() { my_scoped_lock.release(); } + }; +}; + +} // namespace internal +} // namespace interface7 +} // namespace tbb + +#endif /* __TBB_mutex_padding_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_node_handle_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_node_handle_impl.h new file mode 100644 index 00000000..2088aa8b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_node_handle_impl.h @@ -0,0 +1,168 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_node_handle_H +#define __TBB_node_handle_H + +#include "_allocator_traits.h" +#include "../tbb_config.h" + + +namespace tbb { + +// This classes must be declared here for correct friendly relationship +// TODO: Consider creation some internal class to access node_handle private fields without any friendly classes +namespace interface5 { +namespace internal { + template + class split_ordered_list; + template + class concurrent_unordered_base; +} +} + +namespace interface10{ +namespace internal { + template + class concurrent_skip_list; +} +} + +namespace internal { + +template +class node_handle_base { +public: + typedef Allocator allocator_type; +protected: + typedef Node node; + typedef tbb::internal::allocator_traits traits_type; +public: + + node_handle_base() : my_node(NULL), my_allocator() {} + node_handle_base(node_handle_base&& nh) : my_node(nh.my_node), + my_allocator(std::move(nh.my_allocator)) { + nh.my_node = NULL; + } + + bool empty() const { return my_node == NULL; } + explicit operator bool() const { return my_node != NULL; } + + ~node_handle_base() { internal_destroy(); } + + node_handle_base& operator=(node_handle_base&& nh) { + internal_destroy(); + my_node = nh.my_node; + typedef typename traits_type::propagate_on_container_move_assignment pocma_type; + tbb::internal::allocator_move_assignment(my_allocator, nh.my_allocator, pocma_type()); + nh.deactivate(); + return *this; + } + + void swap(node_handle_base& nh) { + std::swap(my_node, nh.my_node); + typedef typename traits_type::propagate_on_container_swap pocs_type; + tbb::internal::allocator_swap(my_allocator, nh.my_allocator, pocs_type()); + } + + allocator_type get_allocator() const { + return my_allocator; + } + +protected: + node_handle_base(node* n) : my_node(n) {} + + void internal_destroy() { + if(my_node) { + traits_type::destroy(my_allocator, my_node->storage()); + typename tbb::internal::allocator_rebind::type node_allocator; + node_allocator.deallocate(my_node, 1); + } + } + + void deactivate() { my_node = NULL; } + + node* my_node; + allocator_type my_allocator; +}; + +// node handle for maps +template +class node_handle : public node_handle_base { + typedef node_handle_base base_type; +public: + typedef Key key_type; + typedef typename Value::second_type mapped_type; + typedef typename base_type::allocator_type allocator_type; + + node_handle() : base_type() {} + + key_type& key() const { + __TBB_ASSERT(!this->empty(), "Cannot get key from the empty node_type object"); + return *const_cast(&(this->my_node->value().first)); + } + + mapped_type& mapped() const { + __TBB_ASSERT(!this->empty(), "Cannot get mapped value from the empty node_type object"); + return this->my_node->value().second; + } + +private: + template + friend class tbb::interface5::internal::split_ordered_list; + + template + friend class tbb::interface5::internal::concurrent_unordered_base; + + template + friend class tbb::interface10::internal::concurrent_skip_list; + + node_handle(typename base_type::node* n) : base_type(n) {} +}; + +// node handle for sets +template +class node_handle : public node_handle_base { + typedef node_handle_base base_type; +public: + typedef Key value_type; + typedef typename base_type::allocator_type allocator_type; + + node_handle() : base_type() {} + + value_type& value() const { + __TBB_ASSERT(!this->empty(), "Cannot get value from the empty node_type object"); + return *const_cast(&(this->my_node->value())); + } + +private: + template + friend class tbb::interface5::internal::split_ordered_list; + + template + friend class tbb::interface5::internal::concurrent_unordered_base; + + template + friend class tbb::interface10::internal::concurrent_skip_list; + + node_handle(typename base_type::node* n) : base_type(n) {} +}; + + +}// namespace internal +}// namespace tbb + +#endif /*__TBB_node_handle_H*/ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_range_iterator.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_range_iterator.h new file mode 100644 index 00000000..df00e88d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_range_iterator.h @@ -0,0 +1,66 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_range_iterator_H +#define __TBB_range_iterator_H + +#include "../tbb_stddef.h" + +#if __TBB_CPP11_STD_BEGIN_END_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT + #include +#endif + +namespace tbb { + // iterators to first and last elements of container + namespace internal { + +#if __TBB_CPP11_STD_BEGIN_END_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT + using std::begin; + using std::end; + template + auto first(Container& c)-> decltype(begin(c)) {return begin(c);} + + template + auto first(const Container& c)-> decltype(begin(c)) {return begin(c);} + + template + auto last(Container& c)-> decltype(begin(c)) {return end(c);} + + template + auto last(const Container& c)-> decltype(begin(c)) {return end(c);} +#else + template + typename Container::iterator first(Container& c) {return c.begin();} + + template + typename Container::const_iterator first(const Container& c) {return c.begin();} + + template + typename Container::iterator last(Container& c) {return c.end();} + + template + typename Container::const_iterator last(const Container& c) {return c.end();} +#endif + + template + T* first(T (&arr) [size]) {return arr;} + + template + T* last(T (&arr) [size]) {return arr + size;} + } //namespace internal +} //namespace tbb + +#endif // __TBB_range_iterator_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_hash_compare_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_hash_compare_impl.h new file mode 100644 index 00000000..82f0df13 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_hash_compare_impl.h @@ -0,0 +1,105 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// must be included outside namespaces. +#ifndef __TBB_tbb_hash_compare_impl_H +#define __TBB_tbb_hash_compare_impl_H + +#include + +namespace tbb { +namespace interface5 { +namespace internal { + +// Template class for hash compare +template +class hash_compare +{ +public: + typedef Hasher hasher; + typedef Key_equality key_equal; + + hash_compare() {} + + hash_compare(Hasher a_hasher) : my_hash_object(a_hasher) {} + + hash_compare(Hasher a_hasher, Key_equality a_keyeq) : my_hash_object(a_hasher), my_key_compare_object(a_keyeq) {} + + size_t operator()(const Key& key) const { + return ((size_t)my_hash_object(key)); + } + + bool operator()(const Key& key1, const Key& key2) const { + // TODO: get rid of the result invertion + return (!my_key_compare_object(key1, key2)); + } + + Hasher my_hash_object; // The hash object + Key_equality my_key_compare_object; // The equality comparator object +}; + +//! Hash multiplier +static const size_t hash_multiplier = tbb::internal::select_size_t_constant<2654435769U, 11400714819323198485ULL>::value; + +} // namespace internal + +//! Hasher functions +template +__TBB_DEPRECATED_MSG("tbb::tbb_hasher is deprecated, use std::hash") inline size_t tbb_hasher( const T& t ) { + return static_cast( t ) * internal::hash_multiplier; +} +template +__TBB_DEPRECATED_MSG("tbb::tbb_hasher is deprecated, use std::hash") inline size_t tbb_hasher( P* ptr ) { + size_t const h = reinterpret_cast( ptr ); + return (h >> 3) ^ h; +} +template +__TBB_DEPRECATED_MSG("tbb::tbb_hasher is deprecated, use std::hash") inline size_t tbb_hasher( const std::basic_string& s ) { + size_t h = 0; + for( const E* c = s.c_str(); *c; ++c ) + h = static_cast(*c) ^ (h * internal::hash_multiplier); + return h; +} +template +__TBB_DEPRECATED_MSG("tbb::tbb_hasher is deprecated, use std::hash") inline size_t tbb_hasher( const std::pair& p ) { + return tbb_hasher(p.first) ^ tbb_hasher(p.second); +} + +} // namespace interface5 +using interface5::tbb_hasher; + +// Template class for hash compare +template +class __TBB_DEPRECATED_MSG("tbb::tbb_hash is deprecated, use std::hash") tbb_hash +{ +public: + tbb_hash() {} + + size_t operator()(const Key& key) const + { + return tbb_hasher(key); + } +}; + +//! hash_compare that is default argument for concurrent_hash_map +template +struct tbb_hash_compare { + static size_t hash( const Key& a ) { return tbb_hasher(a); } + static bool equal( const Key& a, const Key& b ) { return a == b; } +}; + +} // namespace tbb +#endif /* __TBB_tbb_hash_compare_impl_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_strings.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_strings.h new file mode 100644 index 00000000..df443f3f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_strings.h @@ -0,0 +1,79 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +TBB_STRING_RESOURCE(FLOW_BROADCAST_NODE, "broadcast_node") +TBB_STRING_RESOURCE(FLOW_BUFFER_NODE, "buffer_node") +TBB_STRING_RESOURCE(FLOW_CONTINUE_NODE, "continue_node") +TBB_STRING_RESOURCE(FLOW_FUNCTION_NODE, "function_node") +TBB_STRING_RESOURCE(FLOW_JOIN_NODE_QUEUEING, "join_node (queueing)") +TBB_STRING_RESOURCE(FLOW_JOIN_NODE_RESERVING, "join_node (reserving)") +TBB_STRING_RESOURCE(FLOW_JOIN_NODE_TAG_MATCHING, "join_node (tag_matching)") +TBB_STRING_RESOURCE(FLOW_LIMITER_NODE, "limiter_node") +TBB_STRING_RESOURCE(FLOW_MULTIFUNCTION_NODE, "multifunction_node") +TBB_STRING_RESOURCE(FLOW_OR_NODE, "or_node") //no longer in use, kept for backward compatibility +TBB_STRING_RESOURCE(FLOW_OVERWRITE_NODE, "overwrite_node") +TBB_STRING_RESOURCE(FLOW_PRIORITY_QUEUE_NODE, "priority_queue_node") +TBB_STRING_RESOURCE(FLOW_QUEUE_NODE, "queue_node") +TBB_STRING_RESOURCE(FLOW_SEQUENCER_NODE, "sequencer_node") +TBB_STRING_RESOURCE(FLOW_SOURCE_NODE, "source_node") +TBB_STRING_RESOURCE(FLOW_SPLIT_NODE, "split_node") +TBB_STRING_RESOURCE(FLOW_WRITE_ONCE_NODE, "write_once_node") +TBB_STRING_RESOURCE(FLOW_BODY, "body") +TBB_STRING_RESOURCE(FLOW_GRAPH, "graph") +TBB_STRING_RESOURCE(FLOW_NODE, "node") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT, "input_port") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_0, "input_port_0") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_1, "input_port_1") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_2, "input_port_2") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_3, "input_port_3") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_4, "input_port_4") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_5, "input_port_5") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_6, "input_port_6") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_7, "input_port_7") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_8, "input_port_8") +TBB_STRING_RESOURCE(FLOW_INPUT_PORT_9, "input_port_9") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT, "output_port") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_0, "output_port_0") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_1, "output_port_1") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_2, "output_port_2") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_3, "output_port_3") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_4, "output_port_4") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_5, "output_port_5") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_6, "output_port_6") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_7, "output_port_7") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_8, "output_port_8") +TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_9, "output_port_9") +TBB_STRING_RESOURCE(FLOW_OBJECT_NAME, "object_name") +TBB_STRING_RESOURCE(FLOW_NULL, "null") +TBB_STRING_RESOURCE(FLOW_INDEXER_NODE, "indexer_node") +TBB_STRING_RESOURCE(FLOW_COMPOSITE_NODE, "composite_node") +TBB_STRING_RESOURCE(FLOW_ASYNC_NODE, "async_node") +TBB_STRING_RESOURCE(FLOW_OPENCL_NODE, "opencl_node") +TBB_STRING_RESOURCE(ALGORITHM, "tbb_algorithm") +TBB_STRING_RESOURCE(PARALLEL_FOR, "tbb_parallel_for") +TBB_STRING_RESOURCE(PARALLEL_DO, "tbb_parallel_do") +TBB_STRING_RESOURCE(PARALLEL_INVOKE, "tbb_parallel_invoke") +TBB_STRING_RESOURCE(PARALLEL_REDUCE, "tbb_parallel_reduce") +TBB_STRING_RESOURCE(PARALLEL_SCAN, "tbb_parallel_scan") +TBB_STRING_RESOURCE(PARALLEL_SORT, "tbb_parallel_sort") +TBB_STRING_RESOURCE(CUSTOM_CTX, "tbb_custom") +TBB_STRING_RESOURCE(FLOW_TASKS, "tbb_flow_graph") +TBB_STRING_RESOURCE(PARALLEL_FOR_TASK, "tbb_parallel_for_task") +// TODO: Drop following string prefix "fgt_" here and in FGA's collector +TBB_STRING_RESOURCE(USER_EVENT, "fgt_user_event") +#if __TBB_CPF_BUILD || (TBB_PREVIEW_FLOW_GRAPH_TRACE && TBB_USE_THREADING_TOOLS) +TBB_STRING_RESOURCE(CODE_ADDRESS, "code_address") +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_trace_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_trace_impl.h new file mode 100644 index 00000000..38dc68cf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_trace_impl.h @@ -0,0 +1,55 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _FGT_TBB_TRACE_IMPL_H +#define _FGT_TBB_TRACE_IMPL_H + +#include "../tbb_profiling.h" + +namespace tbb { + namespace internal { + +#if TBB_PREVIEW_ALGORITHM_TRACE + static inline void fgt_algorithm( string_index t, void *algorithm, void *parent ) { + itt_make_task_group( ITT_DOMAIN_FLOW, algorithm, ALGORITHM, parent, ALGORITHM, t ); + } + static inline void fgt_begin_algorithm( string_index t, void *algorithm ) { + itt_task_begin( ITT_DOMAIN_FLOW, algorithm, ALGORITHM, NULL, FLOW_NULL, t ); + } + static inline void fgt_end_algorithm( void * ) { + itt_task_end( ITT_DOMAIN_FLOW ); + } + static inline void fgt_alg_begin_body( string_index t, void *body, void *algorithm ) { + itt_task_begin( ITT_DOMAIN_FLOW, body, FLOW_BODY, algorithm, ALGORITHM, t ); + } + static inline void fgt_alg_end_body( void * ) { + itt_task_end( ITT_DOMAIN_FLOW ); + } + +#else // TBB_PREVIEW_ALGORITHM_TRACE + + static inline void fgt_algorithm( string_index /*t*/, void * /*algorithm*/, void * /*parent*/ ) { } + static inline void fgt_begin_algorithm( string_index /*t*/, void * /*algorithm*/ ) { } + static inline void fgt_end_algorithm( void * ) { } + static inline void fgt_alg_begin_body( string_index /*t*/, void * /*body*/, void * /*algorithm*/ ) { } + static inline void fgt_alg_end_body( void * ) { } + +#endif // TBB_PREVIEW_ALGORITHM_TRACEE + + } // namespace internal +} // namespace tbb + +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_windef.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_windef.h new file mode 100644 index 00000000..b2eb9d5d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_tbb_windef.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbb_windef_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif /* __TBB_tbb_windef_H */ + +// Check that the target Windows version has all API calls required for TBB. +// Do not increase the version in condition beyond 0x0500 without prior discussion! +#if defined(_WIN32_WINNT) && _WIN32_WINNT<0x0501 +#error TBB is unable to run on old Windows versions; _WIN32_WINNT must be 0x0501 or greater. +#endif + +#if !defined(_MT) +#error TBB requires linkage with multithreaded C/C++ runtime library. \ + Choose multithreaded DLL runtime in project settings, or use /MD[d] compiler switch. +#endif + +// Workaround for the problem with MVSC headers failing to define namespace std +namespace std { + using ::size_t; using ::ptrdiff_t; +} + +#define __TBB_STRING_AUX(x) #x +#define __TBB_STRING(x) __TBB_STRING_AUX(x) + +// Default setting of TBB_USE_DEBUG +#ifdef TBB_USE_DEBUG +# if TBB_USE_DEBUG +# if !defined(_DEBUG) +# pragma message(__FILE__ "(" __TBB_STRING(__LINE__) ") : Warning: Recommend using /MDd if compiling with TBB_USE_DEBUG!=0") +# endif +# else +# if defined(_DEBUG) +# pragma message(__FILE__ "(" __TBB_STRING(__LINE__) ") : Warning: Recommend using /MD if compiling with TBB_USE_DEBUG==0") +# endif +# endif +#endif + +#if (__TBB_BUILD || __TBBMALLOC_BUILD || __TBBBIND_BUILD) && !defined(__TBB_NO_IMPLICIT_LINKAGE) +#define __TBB_NO_IMPLICIT_LINKAGE 1 +#endif + +#if _MSC_VER + #if !__TBB_NO_IMPLICIT_LINKAGE + #ifdef __TBB_LIB_NAME + #pragma comment(lib, __TBB_STRING(__TBB_LIB_NAME)) + #else + #ifdef _DEBUG + #pragma comment(lib, "tbb_debug.lib") + #else + #pragma comment(lib, "tbb.lib") + #endif + #endif + #endif +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_template_helpers.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_template_helpers.h new file mode 100644 index 00000000..08470430 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_template_helpers.h @@ -0,0 +1,311 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_template_helpers_H +#define __TBB_template_helpers_H + +#include +#include +#include "../tbb_config.h" +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT +#include +#endif +#if __TBB_CPP11_PRESENT +#include +#include // allocator_traits +#endif + +namespace tbb { namespace internal { + +//! Enables one or the other code branches +template struct enable_if {}; +template struct enable_if { typedef T type; }; + +//! Strips its template type argument from cv- and ref-qualifiers +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +//! Specialization for function pointers +template struct strip { typedef T(*type)(); }; +#if __TBB_CPP11_RVALUE_REF_PRESENT +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +template struct strip { typedef T type; }; +#endif +//! Specialization for arrays converts to a corresponding pointer +template struct strip { typedef T* type; }; +template struct strip { typedef const T* type; }; +template struct strip { typedef volatile T* type; }; +template struct strip { typedef const volatile T* type; }; + +//! Detects whether two given types are the same +template struct is_same_type { static const bool value = false; }; +template struct is_same_type { static const bool value = true; }; + +template struct is_ref { static const bool value = false; }; +template struct is_ref { static const bool value = true; }; + +//! Partial support for std::is_integral +template struct is_integral_impl { static const bool value = false; }; +template<> struct is_integral_impl { static const bool value = true; }; +template<> struct is_integral_impl { static const bool value = true; }; +#if __TBB_CPP11_PRESENT +template<> struct is_integral_impl { static const bool value = true; }; +template<> struct is_integral_impl { static const bool value = true; }; +#endif +template<> struct is_integral_impl { static const bool value = true; }; +template<> struct is_integral_impl { static const bool value = true; }; +template<> struct is_integral_impl { static const bool value = true; }; +template<> struct is_integral_impl { static const bool value = true; }; +template<> struct is_integral_impl { static const bool value = true; }; + +template +struct is_integral : is_integral_impl::type> {}; + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +//! std::void_t internal implementation (to avoid GCC < 4.7 "template aliases" absence) +template struct void_t { typedef void type; }; +#endif + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT + +// Generic SFINAE helper for expression checks, based on the idea demonstrated in ISO C++ paper n4502 +template class... Checks> +struct supports_impl { typedef std::false_type type; }; +template class... Checks> +struct supports_impl...>::type, Checks...> { typedef std::true_type type; }; + +template class... Checks> +using supports = typename supports_impl::type; + +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT */ + +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + +//! Allows to store a function parameter pack as a variable and later pass it to another function +template< typename... Types > +struct stored_pack; + +template<> +struct stored_pack<> +{ + typedef stored_pack<> pack_type; + stored_pack() {} + + // Friend front-end functions + template< typename F, typename Pack > friend void call( F&& f, Pack&& p ); + template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p ); + +protected: + // Ideally, ref-qualified non-static methods would be used, + // but that would greatly reduce the set of compilers where it works. + template< typename Ret, typename F, typename... Preceding > + static Ret call( F&& f, const pack_type& /*pack*/, Preceding&&... params ) { + return std::forward(f)( std::forward(params)... ); + } + template< typename Ret, typename F, typename... Preceding > + static Ret call( F&& f, pack_type&& /*pack*/, Preceding&&... params ) { + return std::forward(f)( std::forward(params)... ); + } +}; + +template< typename T, typename... Types > +struct stored_pack : stored_pack +{ + typedef stored_pack pack_type; + typedef stored_pack pack_remainder; + // Since lifetime of original values is out of control, copies should be made. + // Thus references should be stripped away from the deduced type. + typename strip::type leftmost_value; + + // Here rvalue references act in the same way as forwarding references, + // as long as class template parameters were deduced via forwarding references. + stored_pack( T&& t, Types&&... types ) + : pack_remainder(std::forward(types)...), leftmost_value(std::forward(t)) {} + + // Friend front-end functions + template< typename F, typename Pack > friend void call( F&& f, Pack&& p ); + template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p ); + +protected: + template< typename Ret, typename F, typename... Preceding > + static Ret call( F&& f, pack_type& pack, Preceding&&... params ) { + return pack_remainder::template call( + std::forward(f), static_cast(pack), + std::forward(params)... , pack.leftmost_value + ); + } + template< typename Ret, typename F, typename... Preceding > + static Ret call( F&& f, const pack_type& pack, Preceding&&... params ) { + return pack_remainder::template call( + std::forward(f), static_cast(pack), + std::forward(params)... , pack.leftmost_value + ); + } + template< typename Ret, typename F, typename... Preceding > + static Ret call( F&& f, pack_type&& pack, Preceding&&... params ) { + return pack_remainder::template call( + std::forward(f), static_cast(pack), + std::forward(params)... , std::move(pack.leftmost_value) + ); + } +}; + +//! Calls the given function with arguments taken from a stored_pack +template< typename F, typename Pack > +void call( F&& f, Pack&& p ) { + strip::type::template call( std::forward(f), std::forward(p) ); +} + +template< typename Ret, typename F, typename Pack > +Ret call_and_return( F&& f, Pack&& p ) { + return strip::type::template call( std::forward(f), std::forward(p) ); +} + +template< typename... Types > +stored_pack save_pack( Types&&... types ) { + return stored_pack( std::forward(types)... ); +} + +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ + +#if __TBB_CPP14_INTEGER_SEQUENCE_PRESENT + +using std::index_sequence; +using std::make_index_sequence; + +#elif __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT + +template class index_sequence {}; + +template +struct make_index_sequence_impl : make_index_sequence_impl < N - 1, N - 1, S... > {}; + +template +struct make_index_sequence_impl <0, S...> { + using type = index_sequence; +}; + +template +using make_index_sequence = typename tbb::internal::make_index_sequence_impl::type; + +#endif /* __TBB_CPP14_INTEGER_SEQUENCE_PRESENT */ + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +template +struct conjunction; + +template +struct conjunction + : std::conditional, First>::type {}; + +template +struct conjunction : T {}; + +template<> +struct conjunction<> : std::true_type {}; + +#endif + +#if __TBB_CPP11_PRESENT + +template< typename Iter > +using iterator_value_t = typename std::iterator_traits::value_type; + +template< typename Iter > +using iterator_key_t = typename std::remove_const::first_type>::type; + +template< typename Iter > +using iterator_mapped_t = typename iterator_value_t::second_type; + +template< typename A > using value_type = typename A::value_type; +template< typename A > using alloc_ptr_t = typename std::allocator_traits::pointer; +template< typename A > using has_allocate = decltype(std::declval&>() = std::declval().allocate(0)); +template< typename A > using has_deallocate = decltype(std::declval().deallocate(std::declval>(), 0)); + +// value_type should be checked first because it can be used in other checks (via allocator_traits) +template< typename T > +using is_allocator = supports; + +#if __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT + +template< typename T > +static constexpr bool is_allocator_v = is_allocator::value; + +#endif /*__TBB_CPP14_VARIABLE_TEMPLATES */ + +template< std::size_t N, typename... Args > +struct pack_element { + using type = void; +}; + +template< std::size_t N, typename T, typename... Args > +struct pack_element { + using type = typename pack_element::type; +}; + +template< typename T, typename... Args > +struct pack_element<0, T, Args...> { + using type = T; +}; + +template< std::size_t N, typename... Args > +using pack_element_t = typename pack_element::type; + +// Helper alias for heterogeneous lookup functions in containers +// template parameter K and std::conditional are needed to provide immediate context +// and postpone getting is_trasparent from the compare functor until method instantiation. +template +using is_transparent = typename std::conditional::type::is_transparent; + +#endif /* __TBB_CPP11_PRESENT */ + +template +struct body_arg_detector; + +template +struct body_arg_detector { + typedef T arg_type; +}; + +template +struct body_arg_detector { + typedef T arg_type; +}; + +#if __TBB_CPP11_PRESENT +using std::conditional; +#else +template +struct conditional { + typedef U type; +}; + +template +struct conditional { + typedef T type; +}; +#endif + +} } // namespace internal, namespace tbb + +#endif /* __TBB_template_helpers_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h new file mode 100644 index 00000000..1b536463 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_warning_suppress_disable_notice.h @@ -0,0 +1,27 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_SUPPRESS_INTERNAL_DEPRECATED_MESSAGES + +#if __INTEL_COMPILER || _MSC_VER +#pragma warning( pop ) +#elif __GNUC__ +#pragma GCC diagnostic pop +#elif __clang__ +#pragma clang diagnostic pop +#endif + +#endif // __TBB_SUPPRESS_INTERNAL_DEPRECATED_MESSAGES diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h new file mode 100644 index 00000000..3b927231 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_warning_suppress_enable_notice.h @@ -0,0 +1,32 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../tbb_config.h" + +#if __TBB_SUPPRESS_INTERNAL_DEPRECATED_MESSAGES + +#if _MSC_VER || __INTEL_COMPILER +#pragma warning( push ) +#pragma warning( disable: 4996 ) +#elif __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + +#endif // __TBB_SUPPRESS_INTERNAL_DEPRECATED_MESSAGES diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h new file mode 100644 index 00000000..11be329d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_x86_eliding_mutex_impl.h @@ -0,0 +1,144 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__x86_eliding_mutex_impl_H +#define __TBB__x86_eliding_mutex_impl_H + +#ifndef __TBB_spin_mutex_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#if ( __TBB_x86_32 || __TBB_x86_64 ) + +namespace tbb { +namespace interface7 { +namespace internal { + +template +class padded_mutex; + +//! An eliding lock that occupies a single byte. +/** A x86_eliding_mutex is an HLE-enabled spin mutex. It is recommended to + put the mutex on a cache line that is not shared by the data it protects. + It should be used for locking short critical sections where the lock is + contended but the data it protects are not. If zero-initialized, the + mutex is considered unheld. + @ingroup synchronization */ +class x86_eliding_mutex : tbb::internal::mutex_copy_deprecated_and_disabled { + //! 0 if lock is released, 1 if lock is acquired. + __TBB_atomic_flag flag; + + friend class padded_mutex; + +public: + //! Construct unacquired lock. + /** Equivalent to zero-initialization of *this. */ + x86_eliding_mutex() : flag(0) {} + +// bug in gcc 3.x.x causes syntax error in spite of the friend declaration above. +// Make the scoped_lock public in that case. +#if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000 +#else + // by default we will not provide the scoped_lock interface. The user + // should use the padded version of the mutex. scoped_lock is used in + // padded_mutex template. +private: +#endif + // scoped_lock in padded_mutex<> is the interface to use. + //! Represents acquisition of a mutex. + class scoped_lock : tbb::internal::no_copy { + private: + //! Points to currently held mutex, or NULL if no lock is held. + x86_eliding_mutex* my_mutex; + + public: + //! Construct without acquiring a mutex. + scoped_lock() : my_mutex(NULL) {} + + //! Construct and acquire lock on a mutex. + scoped_lock( x86_eliding_mutex& m ) : my_mutex(NULL) { acquire(m); } + + //! Acquire lock. + void acquire( x86_eliding_mutex& m ) { + __TBB_ASSERT( !my_mutex, "already holding a lock" ); + + my_mutex=&m; + my_mutex->lock(); + } + + //! Try acquiring lock (non-blocking) + /** Return true if lock acquired; false otherwise. */ + bool try_acquire( x86_eliding_mutex& m ) { + __TBB_ASSERT( !my_mutex, "already holding a lock" ); + + bool result = m.try_lock(); + if( result ) { + my_mutex = &m; + } + return result; + } + + //! Release lock + void release() { + __TBB_ASSERT( my_mutex, "release on scoped_lock that is not holding a lock" ); + + my_mutex->unlock(); + my_mutex = NULL; + } + + //! Destroy lock. If holding a lock, releases the lock first. + ~scoped_lock() { + if( my_mutex ) { + release(); + } + } + }; +#if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000 +#else +public: +#endif /* __TBB_USE_X86_ELIDING_MUTEX */ + + // Mutex traits + static const bool is_rw_mutex = false; + static const bool is_recursive_mutex = false; + static const bool is_fair_mutex = false; + + // ISO C++0x compatibility methods + + //! Acquire lock + void lock() { + __TBB_LockByteElided(flag); + } + + //! Try acquiring lock (non-blocking) + /** Return true if lock acquired; false otherwise. */ + bool try_lock() { + return __TBB_TryLockByteElided(flag); + } + + //! Release lock + void unlock() { + __TBB_UnlockByteElided( flag ); + } +}; // end of x86_eliding_mutex + +} // namespace internal +} // namespace interface7 +} // namespace tbb + +#endif /* ( __TBB_x86_32 || __TBB_x86_64 ) */ + +#endif /* __TBB__x86_eliding_mutex_impl_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h new file mode 100644 index 00000000..9373aaa0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/internal/_x86_rtm_rw_mutex_impl.h @@ -0,0 +1,223 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB__x86_rtm_rw_mutex_impl_H +#define __TBB__x86_rtm_rw_mutex_impl_H + +#ifndef __TBB_spin_rw_mutex_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#if __TBB_TSX_AVAILABLE + +#include "../tbb_stddef.h" +#include "../tbb_machine.h" +#include "../tbb_profiling.h" +#include "../spin_rw_mutex.h" + +namespace tbb { +namespace interface8 { +namespace internal { + +enum RTM_type { + RTM_not_in_mutex, + RTM_transacting_reader, + RTM_transacting_writer, + RTM_real_reader, + RTM_real_writer +}; + +static const unsigned long speculation_granularity = 64; + +//! Fast, unfair, spinning speculation-enabled reader-writer lock with backoff and +// writer-preference +/** @ingroup synchronization */ +class x86_rtm_rw_mutex: private spin_rw_mutex { +#if __TBB_USE_X86_RTM_RW_MUTEX || __TBB_GCC_VERSION < 40000 +// bug in gcc 3.x.x causes syntax error in spite of the friend declaration below. +// Make the scoped_lock public in that case. +public: +#else +private: +#endif + friend class interface7::internal::padded_mutex; + class scoped_lock; // should be private + friend class scoped_lock; +private: + //! @cond INTERNAL + + //! Internal construct unacquired mutex. + void __TBB_EXPORTED_METHOD internal_construct(); + + //! Internal acquire write lock. + // only_speculate == true if we're doing a try_lock, else false. + void __TBB_EXPORTED_METHOD internal_acquire_writer(x86_rtm_rw_mutex::scoped_lock&, bool only_speculate=false); + + //! Internal acquire read lock. + // only_speculate == true if we're doing a try_lock, else false. + void __TBB_EXPORTED_METHOD internal_acquire_reader(x86_rtm_rw_mutex::scoped_lock&, bool only_speculate=false); + + //! Internal upgrade reader to become a writer. + bool __TBB_EXPORTED_METHOD internal_upgrade( x86_rtm_rw_mutex::scoped_lock& ); + + //! Out of line code for downgrading a writer to a reader. + bool __TBB_EXPORTED_METHOD internal_downgrade( x86_rtm_rw_mutex::scoped_lock& ); + + //! Internal try_acquire write lock. + bool __TBB_EXPORTED_METHOD internal_try_acquire_writer( x86_rtm_rw_mutex::scoped_lock& ); + + //! Internal release lock. + void __TBB_EXPORTED_METHOD internal_release( x86_rtm_rw_mutex::scoped_lock& ); + + static x86_rtm_rw_mutex* internal_get_mutex( const spin_rw_mutex::scoped_lock& lock ) + { + return static_cast( lock.mutex ); + } + static void internal_set_mutex( spin_rw_mutex::scoped_lock& lock, spin_rw_mutex* mtx ) + { + lock.mutex = mtx; + } + //! @endcond +public: + //! Construct unacquired mutex. + x86_rtm_rw_mutex() { + w_flag = false; +#if TBB_USE_THREADING_TOOLS + internal_construct(); +#endif + } + +#if TBB_USE_ASSERT + //! Empty destructor. + ~x86_rtm_rw_mutex() {} +#endif /* TBB_USE_ASSERT */ + + // Mutex traits + static const bool is_rw_mutex = true; + static const bool is_recursive_mutex = false; + static const bool is_fair_mutex = false; + +#if __TBB_USE_X86_RTM_RW_MUTEX || __TBB_GCC_VERSION < 40000 +#else + // by default we will not provide the scoped_lock interface. The user + // should use the padded version of the mutex. scoped_lock is used in + // padded_mutex template. +private: +#endif + //! The scoped locking pattern + /** It helps to avoid the common problem of forgetting to release lock. + It also nicely provides the "node" for queuing locks. */ + // Speculation-enabled scoped lock for spin_rw_mutex + // The idea is to be able to reuse the acquire/release methods of spin_rw_mutex + // and its scoped lock wherever possible. The only way to use a speculative lock is to use + // a scoped_lock. (because transaction_state must be local) + + class scoped_lock : tbb::internal::no_copy { + friend class x86_rtm_rw_mutex; + spin_rw_mutex::scoped_lock my_scoped_lock; + + RTM_type transaction_state; + + public: + //! Construct lock that has not acquired a mutex. + /** Equivalent to zero-initialization of *this. */ + scoped_lock() : my_scoped_lock(), transaction_state(RTM_not_in_mutex) { + } + + //! Acquire lock on given mutex. + scoped_lock( x86_rtm_rw_mutex& m, bool write = true ) : my_scoped_lock(), + transaction_state(RTM_not_in_mutex) { + acquire(m, write); + } + + //! Release lock (if lock is held). + ~scoped_lock() { + if(transaction_state != RTM_not_in_mutex) release(); + } + + //! Acquire lock on given mutex. + void acquire( x86_rtm_rw_mutex& m, bool write = true ) { + if( write ) m.internal_acquire_writer(*this); + else m.internal_acquire_reader(*this); + } + + //! Release lock + void release() { + x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); + __TBB_ASSERT( mutex, "lock is not acquired" ); + __TBB_ASSERT( transaction_state!=RTM_not_in_mutex, "lock is not acquired" ); + return mutex->internal_release(*this); + } + + //! Upgrade reader to become a writer. + /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ + bool upgrade_to_writer() { + x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); + __TBB_ASSERT( mutex, "lock is not acquired" ); + if (transaction_state == RTM_transacting_writer || transaction_state == RTM_real_writer) + return true; // Already a writer + return mutex->internal_upgrade(*this); + } + + //! Downgrade writer to become a reader. + /** Returns whether the downgrade happened without releasing and re-acquiring the lock */ + bool downgrade_to_reader() { + x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); + __TBB_ASSERT( mutex, "lock is not acquired" ); + if (transaction_state == RTM_transacting_reader || transaction_state == RTM_real_reader) + return true; // Already a reader + return mutex->internal_downgrade(*this); + } + + //! Attempt to acquire mutex. + /** returns true if successful. */ + bool try_acquire( x86_rtm_rw_mutex& m, bool write = true ) { +#if TBB_USE_ASSERT + x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock); + __TBB_ASSERT( !mutex, "lock is already acquired" ); +#endif + // have to assign m to our mutex. + // cannot set the mutex, because try_acquire in spin_rw_mutex depends on it being NULL. + if(write) return m.internal_try_acquire_writer(*this); + // speculatively acquire the lock. If this fails, do try_acquire on the spin_rw_mutex. + m.internal_acquire_reader(*this, /*only_speculate=*/true); + if(transaction_state == RTM_transacting_reader) return true; + if( my_scoped_lock.try_acquire(m, false)) { + transaction_state = RTM_real_reader; + return true; + } + return false; + } + + }; // class x86_rtm_rw_mutex::scoped_lock + + // ISO C++0x compatibility methods not provided because we cannot maintain + // state about whether a thread is in a transaction. + +private: + char pad[speculation_granularity-sizeof(spin_rw_mutex)]; // padding + + // If true, writer holds the spin_rw_mutex. + tbb::atomic w_flag; // want this on a separate cache line + +}; // x86_rtm_rw_mutex + +} // namespace internal +} // namespace interface8 +} // namespace tbb + +#endif /* __TBB_TSX_AVAILABLE */ +#endif /* __TBB__x86_rtm_rw_mutex_impl_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/iterators.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/iterators.h new file mode 100644 index 00000000..2d4da9c9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/iterators.h @@ -0,0 +1,326 @@ +/* + Copyright (c) 2017-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_iterators_H +#define __TBB_iterators_H + +#include +#include + +#include "tbb_config.h" +#include "tbb_stddef.h" + +#if __TBB_CPP11_PRESENT + +#include + +namespace tbb { + +template +class counting_iterator { + __TBB_STATIC_ASSERT(std::numeric_limits::is_integer, "Cannot instantiate counting_iterator with a non-integer type"); +public: + typedef typename std::make_signed::type difference_type; + typedef IntType value_type; + typedef const IntType* pointer; + typedef const IntType& reference; + typedef std::random_access_iterator_tag iterator_category; + + counting_iterator() : my_counter() {} + explicit counting_iterator(IntType init) : my_counter(init) {} + + reference operator*() const { return my_counter; } + value_type operator[](difference_type i) const { return *(*this + i); } + + difference_type operator-(const counting_iterator& it) const { return my_counter - it.my_counter; } + + counting_iterator& operator+=(difference_type forward) { my_counter += forward; return *this; } + counting_iterator& operator-=(difference_type backward) { return *this += -backward; } + counting_iterator& operator++() { return *this += 1; } + counting_iterator& operator--() { return *this -= 1; } + + counting_iterator operator++(int) { + counting_iterator it(*this); + ++(*this); + return it; + } + counting_iterator operator--(int) { + counting_iterator it(*this); + --(*this); + return it; + } + + counting_iterator operator-(difference_type backward) const { return counting_iterator(my_counter - backward); } + counting_iterator operator+(difference_type forward) const { return counting_iterator(my_counter + forward); } + friend counting_iterator operator+(difference_type forward, const counting_iterator it) { return it + forward; } + + bool operator==(const counting_iterator& it) const { return *this - it == 0; } + bool operator!=(const counting_iterator& it) const { return !(*this == it); } + bool operator<(const counting_iterator& it) const {return *this - it < 0; } + bool operator>(const counting_iterator& it) const { return it < *this; } + bool operator<=(const counting_iterator& it) const { return !(*this > it); } + bool operator>=(const counting_iterator& it) const { return !(*this < it); } + +private: + IntType my_counter; +}; +} //namespace tbb + + +#include + +#include "internal/_template_helpers.h" // index_sequence, make_index_sequence + +namespace tbb { +namespace internal { + +template +struct tuple_util { + template + static void increment(TupleType& it, DifferenceType forward) { + std::get(it) += forward; + tuple_util::increment(it, forward); + } + template + static bool check_sync(const TupleType& it1, const TupleType& it2, DifferenceType val) { + if(std::get(it1) - std::get(it2) != val) + return false; + return tuple_util::check_sync(it1, it2, val); + } +}; + +template<> +struct tuple_util<0> { + template + static void increment(TupleType&, DifferenceType) {} + template + static bool check_sync(const TupleType&, const TupleType&, DifferenceType) { return true;} +}; + +template +struct make_references { + template + TupleReturnType operator()(const TupleType& t, tbb::internal::index_sequence) { + return std::tie( *std::get(t)... ); + } +}; + +// A simple wrapper over a tuple of references. +// The class is designed to hold a temporary tuple of reference +// after dereferencing a zip_iterator; in particular, it is needed +// to swap these rvalue tuples. Any other usage is not supported. +template +struct tuplewrapper : public std::tuple::value, T&&>::type...> { + // In the context of this class, T is a reference, so T&& is a "forwarding reference" + typedef std::tuple base_type; + // Construct from the result of std::tie + tuplewrapper(const base_type& in) : base_type(in) {} +#if __INTEL_COMPILER + // ICC cannot generate copy ctor & assignment + tuplewrapper(const tuplewrapper& rhs) : base_type(rhs) {} + tuplewrapper& operator=(const tuplewrapper& rhs) { + *this = base_type(rhs); + return *this; + } +#endif + // Assign any tuple convertible to std::tuple: *it = a_tuple; + template + tuplewrapper& operator=(const std::tuple& other) { + base_type::operator=(other); + return *this; + } +#if _LIBCPP_VERSION + // (Necessary for libc++ tuples) Convert to a tuple of values: v = *it; + operator std::tuple::type...>() { return base_type(*this); } +#endif + // Swap rvalue tuples: swap(*it1,*it2); + friend void swap(tuplewrapper&& a, tuplewrapper&& b) { + std::swap(a,b); + } +}; + +} //namespace internal + +template +class zip_iterator { + __TBB_STATIC_ASSERT(sizeof...(Types)>0, "Cannot instantiate zip_iterator with empty template parameter pack"); + static const std::size_t num_types = sizeof...(Types); + typedef std::tuple it_types; +public: + typedef typename std::make_signed::type difference_type; + typedef std::tuple::value_type...> value_type; +#if __INTEL_COMPILER && __INTEL_COMPILER < 1800 && _MSC_VER + typedef std::tuple::reference...> reference; +#else + typedef tbb::internal::tuplewrapper::reference...> reference; +#endif + typedef std::tuple::pointer...> pointer; + typedef std::random_access_iterator_tag iterator_category; + + zip_iterator() : my_it() {} + explicit zip_iterator(Types... args) : my_it(std::make_tuple(args...)) {} + zip_iterator(const zip_iterator& input) : my_it(input.my_it) {} + zip_iterator& operator=(const zip_iterator& input) { + my_it = input.my_it; + return *this; + } + + reference operator*() const { + return tbb::internal::make_references()(my_it, tbb::internal::make_index_sequence()); + } + reference operator[](difference_type i) const { return *(*this + i); } + + difference_type operator-(const zip_iterator& it) const { + __TBB_ASSERT(internal::tuple_util::check_sync(my_it, it.my_it, std::get<0>(my_it) - std::get<0>(it.my_it)), + "Components of zip_iterator are not synchronous"); + return std::get<0>(my_it) - std::get<0>(it.my_it); + } + + zip_iterator& operator+=(difference_type forward) { + internal::tuple_util::increment(my_it, forward); + return *this; + } + zip_iterator& operator-=(difference_type backward) { return *this += -backward; } + zip_iterator& operator++() { return *this += 1; } + zip_iterator& operator--() { return *this -= 1; } + + zip_iterator operator++(int) { + zip_iterator it(*this); + ++(*this); + return it; + } + zip_iterator operator--(int) { + zip_iterator it(*this); + --(*this); + return it; + } + + zip_iterator operator-(difference_type backward) const { + zip_iterator it(*this); + return it -= backward; + } + zip_iterator operator+(difference_type forward) const { + zip_iterator it(*this); + return it += forward; + } + friend zip_iterator operator+(difference_type forward, const zip_iterator& it) { return it + forward; } + + bool operator==(const zip_iterator& it) const { + return *this - it == 0; + } + it_types base() const { return my_it; } + + bool operator!=(const zip_iterator& it) const { return !(*this == it); } + bool operator<(const zip_iterator& it) const { return *this - it < 0; } + bool operator>(const zip_iterator& it) const { return it < *this; } + bool operator<=(const zip_iterator& it) const { return !(*this > it); } + bool operator>=(const zip_iterator& it) const { return !(*this < it); } +private: + it_types my_it; +}; + +template +zip_iterator make_zip_iterator(T... args) { return zip_iterator(args...); } + +template +class transform_iterator { +public: + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; +#if __TBB_CPP17_INVOKE_RESULT_PRESENT + typedef typename std::invoke_result::reference>::type reference; +#else + typedef typename std::result_of::reference)>::type reference; +#endif + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::random_access_iterator_tag iterator_category; + + transform_iterator(Iter it, UnaryFunc unary_func) : my_it(it), my_unary_func(unary_func) { + __TBB_STATIC_ASSERT((std::is_same::iterator_category, + std::random_access_iterator_tag>::value), "Random access iterator required."); + } + transform_iterator(const transform_iterator& input) : my_it(input.my_it), my_unary_func(input.my_unary_func) { } + transform_iterator& operator=(const transform_iterator& input) { + my_it = input.my_it; + return *this; + } + reference operator*() const { + return my_unary_func(*my_it); + } + reference operator[](difference_type i) const { + return *(*this + i); + } + transform_iterator& operator++() { + ++my_it; + return *this; + } + transform_iterator& operator--() { + --my_it; + return *this; + } + transform_iterator operator++(int) { + transform_iterator it(*this); + ++(*this); + return it; + } + transform_iterator operator--(int) { + transform_iterator it(*this); + --(*this); + return it; + } + transform_iterator operator+(difference_type forward) const { + return { my_it + forward, my_unary_func }; + } + transform_iterator operator-(difference_type backward) const { + return { my_it - backward, my_unary_func }; + } + transform_iterator& operator+=(difference_type forward) { + my_it += forward; + return *this; + } + transform_iterator& operator-=(difference_type backward) { + my_it -= backward; + return *this; + } + friend transform_iterator operator+(difference_type forward, const transform_iterator& it) { + return it + forward; + } + difference_type operator-(const transform_iterator& it) const { + return my_it - it.my_it; + } + bool operator==(const transform_iterator& it) const { return *this - it == 0; } + bool operator!=(const transform_iterator& it) const { return !(*this == it); } + bool operator<(const transform_iterator& it) const { return *this - it < 0; } + bool operator>(const transform_iterator& it) const { return it < *this; } + bool operator<=(const transform_iterator& it) const { return !(*this > it); } + bool operator>=(const transform_iterator& it) const { return !(*this < it); } + + Iter base() const { return my_it; } +private: + Iter my_it; + const UnaryFunc my_unary_func; +}; + +template +transform_iterator make_transform_iterator(Iter it, UnaryFunc unary_func) { + return transform_iterator(it, unary_func); +} + +} //namespace tbb + +#endif //__TBB_CPP11_PRESENT + +#endif /* __TBB_iterators_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_arm.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_arm.h new file mode 100644 index 00000000..284a3f9e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_arm.h @@ -0,0 +1,216 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + Platform isolation layer for the ARMv7-a architecture. +*/ + +#ifndef __TBB_machine_H +#error Do not include this file directly; include tbb_machine.h instead +#endif + +#if __ARM_ARCH_7A__ + +#include +#include + +#define __TBB_WORDSIZE 4 + +// Traditionally ARM is little-endian. +// Note that, since only the layout of aligned 32-bit words is of interest, +// any apparent PDP-endianness of 32-bit words at half-word alignment or +// any little-endian ordering of big-endian 32-bit words in 64-bit quantities +// may be disregarded for this setting. +#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG +#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE +#elif defined(__BYTE_ORDER__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED +#else + #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT +#endif + + +#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") +#define __TBB_full_memory_fence() __asm__ __volatile__("dmb ish": : :"memory") +#define __TBB_control_consistency_helper() __TBB_full_memory_fence() +#define __TBB_acquire_consistency_helper() __TBB_full_memory_fence() +#define __TBB_release_consistency_helper() __TBB_full_memory_fence() + +//-------------------------------------------------- +// Compare and swap +//-------------------------------------------------- + +/** + * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr + * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand + * @param value value to assign *ptr to if *ptr==comparand + * @param comparand value to compare with *ptr + * @return value originally in memory at ptr, regardless of success +*/ +static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand ) +{ + int32_t oldval, res; + + __TBB_full_memory_fence(); + + do { + __asm__ __volatile__( + "ldrex %1, [%3]\n" + "mov %0, #0\n" + "cmp %1, %4\n" + "it eq\n" + "strexeq %0, %5, [%3]\n" + : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int32_t*)ptr) + : "r" ((volatile int32_t *)ptr), "Ir" (comparand), "r" (value) + : "cc"); + } while (res); + + __TBB_full_memory_fence(); + + return oldval; +} + +/** + * Atomic CAS for 64 bit values, if *ptr==comparand, then *ptr=value, returns *ptr + * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand + * @param value value to assign *ptr to if *ptr==comparand + * @param comparand value to compare with *ptr + * @return value originally in memory at ptr, regardless of success + */ +static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, int64_t comparand ) +{ + int64_t oldval; + int32_t res; + + __TBB_full_memory_fence(); + + do { + __asm__ __volatile__( + "mov %0, #0\n" + "ldrexd %1, %H1, [%3]\n" + "cmp %1, %4\n" + "it eq\n" + "cmpeq %H1, %H4\n" + "it eq\n" + "strexdeq %0, %5, %H5, [%3]" + : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int64_t*)ptr) + : "r" ((volatile int64_t *)ptr), "r" (comparand), "r" (value) + : "cc"); + } while (res); + + __TBB_full_memory_fence(); + + return oldval; +} + +static inline int32_t __TBB_machine_fetchadd4(volatile void* ptr, int32_t addend) +{ + unsigned long tmp; + int32_t result, tmp2; + + __TBB_full_memory_fence(); + + __asm__ __volatile__( +"1: ldrex %0, [%4]\n" +" add %3, %0, %5\n" +" strex %1, %3, [%4]\n" +" cmp %1, #0\n" +" bne 1b\n" + : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int32_t*)ptr), "=&r"(tmp2) + : "r" ((volatile int32_t *)ptr), "Ir" (addend) + : "cc"); + + __TBB_full_memory_fence(); + + return result; +} + +static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend) +{ + unsigned long tmp; + int64_t result, tmp2; + + __TBB_full_memory_fence(); + + __asm__ __volatile__( +"1: ldrexd %0, %H0, [%4]\n" +" adds %3, %0, %5\n" +" adc %H3, %H0, %H5\n" +" strexd %1, %3, %H3, [%4]\n" +" cmp %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int64_t*)ptr), "=&r"(tmp2) + : "r" ((volatile int64_t *)ptr), "r" (addend) + : "cc"); + + + __TBB_full_memory_fence(); + + return result; +} + +namespace tbb { +namespace internal { + template + struct machine_load_store_relaxed { + static inline T load ( const volatile T& location ) { + const T value = location; + + /* + * An extra memory barrier is required for errata #761319 + * Please see http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a + */ + __TBB_acquire_consistency_helper(); + return value; + } + + static inline void store ( volatile T& location, T value ) { + location = value; + } + }; +}} // namespaces internal, tbb + +// Machine specific atomic operations + +#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) +#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) + +// Use generics for some things +#define __TBB_USE_GENERIC_PART_WORD_CAS 1 +#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 +#define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 1 +#define __TBB_USE_GENERIC_FETCH_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 +#elif defined __aarch64__ +// Generic gcc implementations are fine for ARMv8-a except __TBB_PAUSE. +#include "gcc_generic.h" +#else +#error compilation requires an ARMv7-a or ARMv8-a architecture. +#endif // __ARM_ARCH_7A__ + +inline void __TBB_machine_pause (int32_t delay) +{ + while(delay>0) + { + __asm__ __volatile__("yield" ::: "memory"); + delay--; + } +} +#define __TBB_Pause(V) __TBB_machine_pause(V) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_generic.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_generic.h new file mode 100644 index 00000000..9b157721 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_generic.h @@ -0,0 +1,233 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_generic_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_gcc_generic_H + +#include +#include + +#define __TBB_WORDSIZE __SIZEOF_POINTER__ + +#if __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN + #define __TBB_64BIT_ATOMICS 0 +#endif + +/** FPU control setting not available for non-Intel architectures on Android **/ +#if __ANDROID__ && __TBB_generic_arch + #define __TBB_CPU_CTL_ENV_PRESENT 0 +#endif + +// __BYTE_ORDER__ is used in accordance with http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html, +// but __BIG_ENDIAN__ or __LITTLE_ENDIAN__ may be more commonly found instead. +#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG +#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE +#elif defined(__BYTE_ORDER__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED +#else + #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT +#endif + +#if __TBB_GCC_VERSION < 40700 +// Use __sync_* builtins + +/** As this generic implementation has absolutely no information about underlying + hardware, its performance most likely will be sub-optimal because of full memory + fence usages where a more lightweight synchronization means (or none at all) + could suffice. Thus if you use this header to enable TBB on a new platform, + consider forking it and relaxing below helpers as appropriate. **/ +#define __TBB_acquire_consistency_helper() __sync_synchronize() +#define __TBB_release_consistency_helper() __sync_synchronize() +#define __TBB_full_memory_fence() __sync_synchronize() +#define __TBB_control_consistency_helper() __sync_synchronize() + +#define __TBB_MACHINE_DEFINE_ATOMICS(S,T) \ +inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ + return __sync_val_compare_and_swap(reinterpret_cast(ptr),comparand,value); \ +} \ +inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ + return __sync_fetch_and_add(reinterpret_cast(ptr),value); \ +} + +#define __TBB_USE_GENERIC_FETCH_STORE 1 + +#else +// __TBB_GCC_VERSION >= 40700; use __atomic_* builtins available since gcc 4.7 + +#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") +// Acquire and release fence intrinsics in GCC might miss compiler fence. +// Adding it at both sides of an intrinsic, as we do not know what reordering can be made. +#define __TBB_acquire_consistency_helper() __TBB_compiler_fence(); __atomic_thread_fence(__ATOMIC_ACQUIRE); __TBB_compiler_fence() +#define __TBB_release_consistency_helper() __TBB_compiler_fence(); __atomic_thread_fence(__ATOMIC_RELEASE); __TBB_compiler_fence() +#define __TBB_full_memory_fence() __atomic_thread_fence(__ATOMIC_SEQ_CST) +#define __TBB_control_consistency_helper() __TBB_acquire_consistency_helper() + +#define __TBB_MACHINE_DEFINE_ATOMICS(S,T) \ +inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ + (void)__atomic_compare_exchange_n(reinterpret_cast(ptr), &comparand, value, \ + false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ + return comparand; \ +} \ +inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ + return __atomic_fetch_add(reinterpret_cast(ptr), value, __ATOMIC_SEQ_CST); \ +} \ +inline T __TBB_machine_fetchstore##S( volatile void *ptr, T value ) { \ + return __atomic_exchange_n(reinterpret_cast(ptr), value, __ATOMIC_SEQ_CST); \ +} + +#endif // __TBB_GCC_VERSION < 40700 + +__TBB_MACHINE_DEFINE_ATOMICS(1,int8_t) +__TBB_MACHINE_DEFINE_ATOMICS(2,int16_t) +__TBB_MACHINE_DEFINE_ATOMICS(4,int32_t) +__TBB_MACHINE_DEFINE_ATOMICS(8,int64_t) + +#undef __TBB_MACHINE_DEFINE_ATOMICS + +typedef unsigned char __TBB_Flag; +typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag; + +#if __TBB_GCC_VERSION < 40700 +// Use __sync_* builtins + +// Use generic machine_load_store functions if there are no builtin atomics +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + +static inline void __TBB_machine_or( volatile void *ptr, uintptr_t addend ) { + __sync_fetch_and_or(reinterpret_cast(ptr),addend); +} + +static inline void __TBB_machine_and( volatile void *ptr, uintptr_t addend ) { + __sync_fetch_and_and(reinterpret_cast(ptr),addend); +} + +inline bool __TBB_machine_try_lock_byte( __TBB_atomic_flag &flag ) { + return __sync_lock_test_and_set(&flag,1)==0; +} + +inline void __TBB_machine_unlock_byte( __TBB_atomic_flag &flag ) { + __sync_lock_release(&flag); +} + +#else +// __TBB_GCC_VERSION >= 40700; use __atomic_* builtins available since gcc 4.7 + +static inline void __TBB_machine_or( volatile void *ptr, uintptr_t addend ) { + __atomic_fetch_or(reinterpret_cast(ptr),addend,__ATOMIC_SEQ_CST); +} + +static inline void __TBB_machine_and( volatile void *ptr, uintptr_t addend ) { + __atomic_fetch_and(reinterpret_cast(ptr),addend,__ATOMIC_SEQ_CST); +} + +inline bool __TBB_machine_try_lock_byte( __TBB_atomic_flag &flag ) { + return !__atomic_test_and_set(&flag,__ATOMIC_ACQUIRE); +} + +inline void __TBB_machine_unlock_byte( __TBB_atomic_flag &flag ) { + __atomic_clear(&flag,__ATOMIC_RELEASE); +} + +namespace tbb { namespace internal { + +/** GCC atomic operation intrinsics might miss compiler fence. + Adding it after load-with-acquire, before store-with-release, and + on both sides of sequentially consistent operations is sufficient for correctness. **/ + +template +inline T __TBB_machine_atomic_load( const volatile T& location) { + if (MemOrder == __ATOMIC_SEQ_CST) __TBB_compiler_fence(); + T value = __atomic_load_n(&location, MemOrder); + if (MemOrder != __ATOMIC_RELAXED) __TBB_compiler_fence(); + return value; +} + +template +inline void __TBB_machine_atomic_store( volatile T& location, T value) { + if (MemOrder != __ATOMIC_RELAXED) __TBB_compiler_fence(); + __atomic_store_n(&location, value, MemOrder); + if (MemOrder == __ATOMIC_SEQ_CST) __TBB_compiler_fence(); +} + +template +struct machine_load_store { + static T load_with_acquire ( const volatile T& location ) { + return __TBB_machine_atomic_load(location); + } + static void store_with_release ( volatile T &location, T value ) { + __TBB_machine_atomic_store(location, value); + } +}; + +template +struct machine_load_store_relaxed { + static inline T load ( const volatile T& location ) { + return __TBB_machine_atomic_load(location); + } + static inline void store ( volatile T& location, T value ) { + __TBB_machine_atomic_store(location, value); + } +}; + +template +struct machine_load_store_seq_cst { + static T load ( const volatile T& location ) { + return __TBB_machine_atomic_load(location); + } + static void store ( volatile T &location, T value ) { + __TBB_machine_atomic_store(location, value); + } +}; + +}} // namespace tbb::internal + +#endif // __TBB_GCC_VERSION < 40700 + +// Machine specific atomic operations +#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) +#define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) + +#define __TBB_TryLockByte __TBB_machine_try_lock_byte +#define __TBB_UnlockByte __TBB_machine_unlock_byte + +// __builtin_clz counts the number of leading zeroes +namespace tbb{ namespace internal { namespace gcc_builtins { + inline int clz(unsigned int x){ return __builtin_clz(x); } + inline int clz(unsigned long int x){ return __builtin_clzl(x); } + inline int clz(unsigned long long int x){ return __builtin_clzll(x); } +}}} +// logarithm is the index of the most significant non-zero bit +static inline intptr_t __TBB_machine_lg( uintptr_t x ) { + // If P is a power of 2 and x +static inline intptr_t __TBB_machine_lg( T x ) { + __TBB_ASSERT(x>0, "The logarithm of a non-positive value is undefined."); + uintptr_t j, i = x; + __asm__("bsr %1,%0" : "=r"(j) : "r"(i)); + return j; +} +#define __TBB_Log2(V) __TBB_machine_lg(V) +#endif /* !__TBB_Log2 */ + +#ifndef __TBB_Pause +//TODO: check if raising a ratio of pause instructions to loop control instructions +//(via e.g. loop unrolling) gives any benefit for HT. E.g, the current implementation +//does about 2 CPU-consuming instructions for every pause instruction. Perhaps for +//high pause counts it should use an unrolled loop to raise the ratio, and thus free +//up more integer cycles for the other hyperthread. On the other hand, if the loop is +//unrolled too far, it won't fit in the core's loop cache, and thus take away +//instruction decode slots from the other hyperthread. + +//TODO: check if use of gcc __builtin_ia32_pause intrinsic gives a "some how" better performing code +static inline void __TBB_machine_pause( int32_t delay ) { + for (int32_t i = 0; i < delay; i++) { + __asm__ __volatile__("pause;"); + } + return; +} +#define __TBB_Pause(V) __TBB_machine_pause(V) +#endif /* !__TBB_Pause */ + +namespace tbb { namespace internal { typedef uint64_t machine_tsc_t; } } +static inline tbb::internal::machine_tsc_t __TBB_machine_time_stamp() { +#if __INTEL_COMPILER + return _rdtsc(); +#else + tbb::internal::uint32_t hi, lo; + __asm__ __volatile__("rdtsc" : "=d"(hi), "=a"(lo)); + return (tbb::internal::machine_tsc_t( hi ) << 32) | lo; +#endif +} +#define __TBB_time_stamp() __TBB_machine_time_stamp() + +// API to retrieve/update FPU control setting +#ifndef __TBB_CPU_CTL_ENV_PRESENT +#define __TBB_CPU_CTL_ENV_PRESENT 1 +namespace tbb { +namespace internal { +class cpu_ctl_env { +private: + int mxcsr; + short x87cw; + static const int MXCSR_CONTROL_MASK = ~0x3f; /* all except last six status bits */ +public: + bool operator!=( const cpu_ctl_env& ctl ) const { return mxcsr != ctl.mxcsr || x87cw != ctl.x87cw; } + void get_env() { + #if __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN + cpu_ctl_env loc_ctl; + __asm__ __volatile__ ( + "stmxcsr %0\n\t" + "fstcw %1" + : "=m"(loc_ctl.mxcsr), "=m"(loc_ctl.x87cw) + ); + *this = loc_ctl; + #else + __asm__ __volatile__ ( + "stmxcsr %0\n\t" + "fstcw %1" + : "=m"(mxcsr), "=m"(x87cw) + ); + #endif + mxcsr &= MXCSR_CONTROL_MASK; + } + void set_env() const { + __asm__ __volatile__ ( + "ldmxcsr %0\n\t" + "fldcw %1" + : : "m"(mxcsr), "m"(x87cw) + ); + } +}; +} // namespace internal +} // namespace tbb +#endif /* !__TBB_CPU_CTL_ENV_PRESENT */ + +#include "gcc_itsx.h" + +#endif /* __TBB_machine_gcc_ia32_common_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_itsx.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_itsx.h new file mode 100644 index 00000000..5e93a202 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/gcc_itsx.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_itsx_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_gcc_itsx_H + +#define __TBB_OP_XACQUIRE 0xF2 +#define __TBB_OP_XRELEASE 0xF3 +#define __TBB_OP_LOCK 0xF0 + +#define __TBB_STRINGIZE_INTERNAL(arg) #arg +#define __TBB_STRINGIZE(arg) __TBB_STRINGIZE_INTERNAL(arg) + +#ifdef __TBB_x86_64 +#define __TBB_r_out "=r" +#else +#define __TBB_r_out "=q" +#endif + +inline static uint8_t __TBB_machine_try_lock_elided( volatile uint8_t* lk ) +{ + uint8_t value = 1; + __asm__ volatile (".byte " __TBB_STRINGIZE(__TBB_OP_XACQUIRE)"; lock; xchgb %0, %1;" + : __TBB_r_out(value), "=m"(*lk) : "0"(value), "m"(*lk) : "memory" ); + return uint8_t(value^1); +} + +inline static void __TBB_machine_try_lock_elided_cancel() +{ + // 'pause' instruction aborts HLE/RTM transactions + __asm__ volatile ("pause\n" : : : "memory" ); +} + +inline static void __TBB_machine_unlock_elided( volatile uint8_t* lk ) +{ + __asm__ volatile (".byte " __TBB_STRINGIZE(__TBB_OP_XRELEASE)"; movb $0, %0" + : "=m"(*lk) : "m"(*lk) : "memory" ); +} + +#if __TBB_TSX_INTRINSICS_PRESENT +#include + +#define __TBB_machine_is_in_transaction _xtest +#define __TBB_machine_begin_transaction _xbegin +#define __TBB_machine_end_transaction _xend +#define __TBB_machine_transaction_conflict_abort() _xabort(0xff) + +#else + +/*! + * Check if the instruction is executed in a transaction or not + */ +inline static bool __TBB_machine_is_in_transaction() +{ + int8_t res = 0; +#if __TBB_x86_32 + __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD6;\n" + "setz %0" : "=q"(res) : : "memory" ); +#else + __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD6;\n" + "setz %0" : "=r"(res) : : "memory" ); +#endif + return res==0; +} + +/*! + * Enter speculative execution mode. + * @return -1 on success + * abort cause ( or 0 ) on abort + */ +inline static uint32_t __TBB_machine_begin_transaction() +{ + uint32_t res = ~uint32_t(0); // success value + __asm__ volatile ("1: .byte 0xC7; .byte 0xF8;\n" // XBEGIN + " .long 2f-1b-6\n" // 2f-1b == difference in addresses of start + // of XBEGIN and the MOVL + // 2f - 1b - 6 == that difference minus the size of the + // XBEGIN instruction. This is the abort offset to + // 2: below. + " jmp 3f\n" // success (leave -1 in res) + "2: movl %%eax,%0\n" // store failure code in res + "3:" + :"=r"(res):"0"(res):"memory","%eax"); + return res; +} + +/*! + * Attempt to commit/end transaction + */ +inline static void __TBB_machine_end_transaction() +{ + __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD5" :::"memory"); // XEND +} + +/* + * aborts with code 0xFF (lock already held) + */ +inline static void __TBB_machine_transaction_conflict_abort() +{ + __asm__ volatile (".byte 0xC6; .byte 0xF8; .byte 0xFF" :::"memory"); +} + +#endif /* __TBB_TSX_INTRINSICS_PRESENT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/ibm_aix51.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/ibm_aix51.h new file mode 100644 index 00000000..c8246848 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/ibm_aix51.h @@ -0,0 +1,66 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// TODO: revise by comparing with mac_ppc.h + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_ibm_aix51_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_ibm_aix51_H + +#define __TBB_WORDSIZE 8 +#define __TBB_ENDIANNESS __TBB_ENDIAN_BIG // assumption based on operating system + +#include +#include +#include + +extern "C" { +int32_t __TBB_machine_cas_32 (volatile void* ptr, int32_t value, int32_t comparand); +int64_t __TBB_machine_cas_64 (volatile void* ptr, int64_t value, int64_t comparand); +void __TBB_machine_flush (); +void __TBB_machine_lwsync (); +void __TBB_machine_isync (); +} + +// Mapping of old entry point names retained for the sake of backward binary compatibility +#define __TBB_machine_cmpswp4 __TBB_machine_cas_32 +#define __TBB_machine_cmpswp8 __TBB_machine_cas_64 + +#define __TBB_Yield() sched_yield() + +#define __TBB_USE_GENERIC_PART_WORD_CAS 1 +#define __TBB_USE_GENERIC_FETCH_ADD 1 +#define __TBB_USE_GENERIC_FETCH_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + +#if __GNUC__ + #define __TBB_control_consistency_helper() __asm__ __volatile__( "isync": : :"memory") + #define __TBB_acquire_consistency_helper() __asm__ __volatile__("lwsync": : :"memory") + #define __TBB_release_consistency_helper() __asm__ __volatile__("lwsync": : :"memory") + #define __TBB_full_memory_fence() __asm__ __volatile__( "sync": : :"memory") +#else + // IBM C++ Compiler does not support inline assembly + // TODO: Since XL 9.0 or earlier GCC syntax is supported. Replace with more + // lightweight implementation (like in mac_ppc.h) + #define __TBB_control_consistency_helper() __TBB_machine_isync () + #define __TBB_acquire_consistency_helper() __TBB_machine_lwsync () + #define __TBB_release_consistency_helper() __TBB_machine_lwsync () + #define __TBB_full_memory_fence() __TBB_machine_flush () +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/icc_generic.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/icc_generic.h new file mode 100644 index 00000000..c4675b8e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/icc_generic.h @@ -0,0 +1,258 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_icc_generic_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#if ! __TBB_ICC_BUILTIN_ATOMICS_PRESENT + #error "Intel(R) C++ Compiler of at least 12.0 version is needed to use ICC intrinsics port" +#endif + +#define __TBB_machine_icc_generic_H + +//ICC mimics the "native" target compiler +#if _MSC_VER + #include "msvc_ia32_common.h" +#else + #include "gcc_ia32_common.h" +#endif + +//TODO: Make __TBB_WORDSIZE macro optional for ICC intrinsics port. +//As compiler intrinsics are used for all the operations it is possible to do. + +#if __TBB_x86_32 + #define __TBB_WORDSIZE 4 +#else + #define __TBB_WORDSIZE 8 +#endif +#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE + +//__TBB_compiler_fence() defined just in case, as it seems not to be used on its own anywhere else +#ifndef __TBB_compiler_fence +#if _MSC_VER + //TODO: any way to use same intrinsics on windows and linux? + #pragma intrinsic(_ReadWriteBarrier) + #define __TBB_compiler_fence() _ReadWriteBarrier() +#else + #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") +#endif +#endif + +#ifndef __TBB_full_memory_fence +#if _MSC_VER + //TODO: any way to use same intrinsics on windows and linux? + #pragma intrinsic(_mm_mfence) + #define __TBB_full_memory_fence() _mm_mfence() +#else + #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") +#endif +#endif + +#ifndef __TBB_control_consistency_helper +#define __TBB_control_consistency_helper() __TBB_compiler_fence() +#endif + +namespace tbb { namespace internal { +//TODO: is there any way to reuse definition of memory_order enum from ICC instead of copy paste. +//however it seems unlikely that ICC will silently change exact enum values, as they are defined +//in the ISO exactly like this. +//TODO: add test that exact values of the enum are same as in the ISO C++11 +typedef enum memory_order { + memory_order_relaxed, memory_order_consume, memory_order_acquire, + memory_order_release, memory_order_acq_rel, memory_order_seq_cst +} memory_order; + +namespace icc_intrinsics_port { + template + T convert_argument(T value){ + return value; + } + //The overload below is needed to have explicit conversion of pointer to void* in argument list. + //compiler bug? + //TODO: add according broken macro and recheck with ICC 13.0 if the overload is still needed + template + void* convert_argument(T* value){ + return (void*)value; + } +} +//TODO: code below is a bit repetitive, consider simplifying it +template +struct machine_load_store { + static T load_with_acquire ( const volatile T& location ) { + return __atomic_load_explicit(&location, memory_order_acquire); + } + static void store_with_release ( volatile T &location, T value ) { + __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release); + } +}; + +template +struct machine_load_store_relaxed { + static inline T load ( const T& location ) { + return __atomic_load_explicit(&location, memory_order_relaxed); + } + static inline void store ( T& location, T value ) { + __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed); + } +}; + +template +struct machine_load_store_seq_cst { + static T load ( const volatile T& location ) { + return __atomic_load_explicit(&location, memory_order_seq_cst); + } + + static void store ( volatile T &location, T value ) { + __atomic_store_explicit(&location, value, memory_order_seq_cst); + } +}; + +}} // namespace tbb::internal + +namespace tbb{ namespace internal { namespace icc_intrinsics_port{ + typedef enum memory_order_map { + relaxed = memory_order_relaxed, + acquire = memory_order_acquire, + release = memory_order_release, + full_fence= memory_order_seq_cst + } memory_order_map; +}}}// namespace tbb::internal + +#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,M) \ +inline T __TBB_machine_cmpswp##S##M( volatile void *ptr, T value, T comparand ) { \ + __atomic_compare_exchange_strong_explicit( \ + (T*)ptr \ + ,&comparand \ + ,value \ + , tbb::internal::icc_intrinsics_port::M \ + , tbb::internal::icc_intrinsics_port::M); \ + return comparand; \ +} \ + \ +inline T __TBB_machine_fetchstore##S##M(volatile void *ptr, T value) { \ + return __atomic_exchange_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \ +} \ + \ +inline T __TBB_machine_fetchadd##S##M(volatile void *ptr, T value) { \ + return __atomic_fetch_add_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M); \ +} \ + +__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, full_fence) +__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, acquire) +__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, release) +__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, relaxed) + +__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, full_fence) +__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, acquire) +__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, release) +__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, relaxed) + +__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, full_fence) +__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, acquire) +__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, release) +__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, relaxed) + +__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, full_fence) +__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, acquire) +__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, release) +__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, relaxed) + + +#undef __TBB_MACHINE_DEFINE_ATOMICS + +#define __TBB_USE_FENCED_ATOMICS 1 + +namespace tbb { namespace internal { +#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN +__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(full_fence) +__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(full_fence) + +__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(acquire) +__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(release) + +__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(relaxed) +__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(relaxed) + +template +struct machine_load_store { + static T load_with_acquire ( const volatile T& location ) { + if( tbb::internal::is_aligned(&location,8)) { + return __atomic_load_explicit(&location, memory_order_acquire); + } else { + return __TBB_machine_generic_load8acquire(&location); + } + } + static void store_with_release ( volatile T &location, T value ) { + if( tbb::internal::is_aligned(&location,8)) { + __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release); + } else { + return __TBB_machine_generic_store8release(&location,value); + } + } +}; + +template +struct machine_load_store_relaxed { + static T load( const volatile T& location ) { + if( tbb::internal::is_aligned(&location,8)) { + return __atomic_load_explicit(&location, memory_order_relaxed); + } else { + return __TBB_machine_generic_load8relaxed(&location); + } + } + static void store( volatile T &location, T value ) { + if( tbb::internal::is_aligned(&location,8)) { + __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed); + } else { + return __TBB_machine_generic_store8relaxed(&location,value); + } + } +}; + +template +struct machine_load_store_seq_cst { + static T load ( const volatile T& location ) { + if( tbb::internal::is_aligned(&location,8)) { + return __atomic_load_explicit(&location, memory_order_seq_cst); + } else { + return __TBB_machine_generic_load8full_fence(&location); + } + + } + + static void store ( volatile T &location, T value ) { + if( tbb::internal::is_aligned(&location,8)) { + __atomic_store_explicit(&location, value, memory_order_seq_cst); + } else { + return __TBB_machine_generic_store8full_fence(&location,value); + } + + } +}; + +#endif +}} // namespace tbb::internal +template +inline void __TBB_machine_OR( T *operand, T addend ) { + __atomic_fetch_or_explicit(operand, addend, tbb::internal::memory_order_seq_cst); +} + +template +inline void __TBB_machine_AND( T *operand, T addend ) { + __atomic_fetch_and_explicit(operand, addend, tbb::internal::memory_order_seq_cst); +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_common.h new file mode 100644 index 00000000..9dc6c813 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_common.h @@ -0,0 +1,105 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_machine_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#include +#define __TBB_Yield() sched_yield() + +#include +/* Futex definitions */ +#include + +#if defined(SYS_futex) +/* This header file is included for Linux and some other systems that may support futexes.*/ + +#define __TBB_USE_FUTEX 1 + +#if defined(__has_include) +#define __TBB_has_include __has_include +#else +#define __TBB_has_include(x) 0 +#endif + +/* +If available, use typical headers where futex API is defined. While Linux and OpenBSD +are known to provide such headers, other systems might have them as well. +*/ +#if defined(__linux__) || __TBB_has_include() +#include +#elif defined(__OpenBSD__) || __TBB_has_include() +#include +#endif + +#include +#include + +/* +Some systems might not define the macros or use different names. In such case we expect +the actual parameter values to match Linux: 0 for wait, 1 for wake. +*/ +#if defined(FUTEX_WAIT_PRIVATE) +#define __TBB_FUTEX_WAIT FUTEX_WAIT_PRIVATE +#elif defined(FUTEX_WAIT) +#define __TBB_FUTEX_WAIT FUTEX_WAIT +#else +#define __TBB_FUTEX_WAIT 0 +#endif + +#if defined(FUTEX_WAKE_PRIVATE) +#define __TBB_FUTEX_WAKE FUTEX_WAKE_PRIVATE +#elif defined(FUTEX_WAKE) +#define __TBB_FUTEX_WAKE FUTEX_WAKE +#else +#define __TBB_FUTEX_WAKE 1 +#endif + +#ifndef __TBB_ASSERT +#error machine specific headers must be included after tbb_stddef.h +#endif + +namespace tbb { + +namespace internal { + +inline int futex_wait( void *futex, int comparand ) { + int r = syscall( SYS_futex,futex,__TBB_FUTEX_WAIT,comparand,NULL,NULL,0 ); +#if TBB_USE_ASSERT + int e = errno; + __TBB_ASSERT( r==0||r==EWOULDBLOCK||(r==-1&&(e==EAGAIN||e==EINTR)), "futex_wait failed." ); +#endif /* TBB_USE_ASSERT */ + return r; +} + +inline int futex_wakeup_one( void *futex ) { + int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,1,NULL,NULL,0 ); + __TBB_ASSERT( r==0||r==1, "futex_wakeup_one: more than one thread woken up?" ); + return r; +} + +inline int futex_wakeup_all( void *futex ) { + int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAKE,INT_MAX,NULL,NULL,0 ); + __TBB_ASSERT( r>=0, "futex_wakeup_all: error in waking up threads" ); + return r; +} + +} /* namespace internal */ + +} /* namespace tbb */ + +#endif /* SYS_futex */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_ia32.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_ia32.h new file mode 100644 index 00000000..3942d8bf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_ia32.h @@ -0,0 +1,228 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia32_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_linux_ia32_H + +#include +#include "gcc_ia32_common.h" + +#define __TBB_WORDSIZE 4 +#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE + +#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") +#define __TBB_control_consistency_helper() __TBB_compiler_fence() +#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() +#define __TBB_release_consistency_helper() __TBB_compiler_fence() +#define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") + +#if __TBB_ICC_ASM_VOLATILE_BROKEN +#define __TBB_VOLATILE +#else +#define __TBB_VOLATILE volatile +#endif + +#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,X,R) \ +static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand ) \ +{ \ + T result; \ + \ + __asm__ __volatile__("lock\ncmpxchg" X " %2,%1" \ + : "=a"(result), "=m"(*(__TBB_VOLATILE T*)ptr) \ + : "q"(value), "0"(comparand), "m"(*(__TBB_VOLATILE T*)ptr) \ + : "memory"); \ + return result; \ +} \ + \ +static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend) \ +{ \ + T result; \ + __asm__ __volatile__("lock\nxadd" X " %0,%1" \ + : R (result), "=m"(*(__TBB_VOLATILE T*)ptr) \ + : "0"(addend), "m"(*(__TBB_VOLATILE T*)ptr) \ + : "memory"); \ + return result; \ +} \ + \ +static inline T __TBB_machine_fetchstore##S(volatile void *ptr, T value) \ +{ \ + T result; \ + __asm__ __volatile__("lock\nxchg" X " %0,%1" \ + : R (result), "=m"(*(__TBB_VOLATILE T*)ptr) \ + : "0"(value), "m"(*(__TBB_VOLATILE T*)ptr) \ + : "memory"); \ + return result; \ +} \ + +__TBB_MACHINE_DEFINE_ATOMICS(1,int8_t,"","=q") +__TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"","=r") +__TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"l","=r") + +#if __INTEL_COMPILER +#pragma warning( push ) +// reference to EBX in a function requiring stack alignment +#pragma warning( disable: 998 ) +#endif + +#if __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN +#define __TBB_IA32_CAS8_NOINLINE __attribute__ ((noinline)) +#else +#define __TBB_IA32_CAS8_NOINLINE +#endif + +static inline __TBB_IA32_CAS8_NOINLINE int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) { +//TODO: remove the extra part of condition once __TBB_GCC_BUILTIN_ATOMICS_PRESENT is lowered to gcc version 4.1.2 +#if (__TBB_GCC_BUILTIN_ATOMICS_PRESENT || (__TBB_GCC_VERSION >= 40102)) && !__TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN + return __sync_val_compare_and_swap( reinterpret_cast(ptr), comparand, value ); +#else /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */ + //TODO: look like ICC 13.0 has some issues with this code, investigate it more deeply + int64_t result; + union { + int64_t i64; + int32_t i32[2]; + }; + i64 = value; +#if __PIC__ + /* compiling position-independent code */ + // EBX register preserved for compliance with position-independent code rules on IA32 + int32_t tmp; + __asm__ __volatile__ ( + "movl %%ebx,%2\n\t" + "movl %5,%%ebx\n\t" +#if __GNUC__==3 + "lock\n\t cmpxchg8b %1\n\t" +#else + "lock\n\t cmpxchg8b (%3)\n\t" +#endif + "movl %2,%%ebx" + : "=A"(result) + , "=m"(*(__TBB_VOLATILE int64_t *)ptr) + , "=m"(tmp) +#if __GNUC__==3 + : "m"(*(__TBB_VOLATILE int64_t *)ptr) +#else + : "SD"(ptr) +#endif + , "0"(comparand) + , "m"(i32[0]), "c"(i32[1]) + : "memory" +#if __INTEL_COMPILER + ,"ebx" +#endif + ); +#else /* !__PIC__ */ + __asm__ __volatile__ ( + "lock\n\t cmpxchg8b %1\n\t" + : "=A"(result), "=m"(*(__TBB_VOLATILE int64_t *)ptr) + : "m"(*(__TBB_VOLATILE int64_t *)ptr) + , "0"(comparand) + , "b"(i32[0]), "c"(i32[1]) + : "memory" + ); +#endif /* __PIC__ */ + return result; +#endif /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */ +} + +#undef __TBB_IA32_CAS8_NOINLINE + +#if __INTEL_COMPILER +#pragma warning( pop ) +#endif // warning 998 is back + +static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) { + __asm__ __volatile__("lock\norl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory"); +} + +static inline void __TBB_machine_and( volatile void *ptr, uint32_t addend ) { + __asm__ __volatile__("lock\nandl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory"); +} + +//TODO: Check if it possible and profitable for IA-32 architecture on (Linux* and Windows*) +//to use of 64-bit load/store via floating point registers together with full fence +//for sequentially consistent load/store, instead of CAS. + +#if __clang__ +#define __TBB_fildq "fildll" +#define __TBB_fistpq "fistpll" +#else +#define __TBB_fildq "fildq" +#define __TBB_fistpq "fistpq" +#endif + +static inline int64_t __TBB_machine_aligned_load8 (const volatile void *ptr) { + __TBB_ASSERT(tbb::internal::is_aligned(ptr,8),"__TBB_machine_aligned_load8 should be used with 8 byte aligned locations only \n"); + int64_t result; + __asm__ __volatile__ ( __TBB_fildq " %1\n\t" + __TBB_fistpq " %0" : "=m"(result) : "m"(*(const __TBB_VOLATILE uint64_t*)ptr) : "memory" ); + return result; +} + +static inline void __TBB_machine_aligned_store8 (volatile void *ptr, int64_t value ) { + __TBB_ASSERT(tbb::internal::is_aligned(ptr,8),"__TBB_machine_aligned_store8 should be used with 8 byte aligned locations only \n"); + // Aligned store + __asm__ __volatile__ ( __TBB_fildq " %1\n\t" + __TBB_fistpq " %0" : "=m"(*(__TBB_VOLATILE int64_t*)ptr) : "m"(value) : "memory" ); +} + +static inline int64_t __TBB_machine_load8 (const volatile void *ptr) { +#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN + if( tbb::internal::is_aligned(ptr,8)) { +#endif + return __TBB_machine_aligned_load8(ptr); +#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN + } else { + // Unaligned load + return __TBB_machine_cmpswp8(const_cast(ptr),0,0); + } +#endif +} + +//! Handles misaligned 8-byte store +/** Defined in tbb_misc.cpp */ +extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value ); +extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr ); + +static inline void __TBB_machine_store8(volatile void *ptr, int64_t value) { +#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN + if( tbb::internal::is_aligned(ptr,8)) { +#endif + __TBB_machine_aligned_store8(ptr,value); +#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN + } else { + // Unaligned store +#if TBB_USE_PERFORMANCE_WARNINGS + __TBB_machine_store8_slow_perf_warning(ptr); +#endif /* TBB_USE_PERFORMANCE_WARNINGS */ + __TBB_machine_store8_slow(ptr,value); + } +#endif +} + +// Machine specific atomic operations +#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) +#define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) + +#define __TBB_USE_GENERIC_DWORD_FETCH_ADD 1 +#define __TBB_USE_GENERIC_DWORD_FETCH_STORE 1 +#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_ia64.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_ia64.h new file mode 100644 index 00000000..28b2bc41 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_ia64.h @@ -0,0 +1,177 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia64_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_linux_ia64_H + +#include +#include + +#define __TBB_WORDSIZE 8 +#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE + +#if __INTEL_COMPILER + #define __TBB_compiler_fence() + #define __TBB_control_consistency_helper() __TBB_compiler_fence() + #define __TBB_acquire_consistency_helper() + #define __TBB_release_consistency_helper() + #define __TBB_full_memory_fence() __mf() +#else + #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") + #define __TBB_control_consistency_helper() __TBB_compiler_fence() + // Even though GCC imbues volatile loads with acquire semantics, it sometimes moves + // loads over the acquire fence. The following helpers stop such incorrect code motion. + #define __TBB_acquire_consistency_helper() __TBB_compiler_fence() + #define __TBB_release_consistency_helper() __TBB_compiler_fence() + #define __TBB_full_memory_fence() __asm__ __volatile__("mf": : :"memory") +#endif /* !__INTEL_COMPILER */ + +// Most of the functions will be in a .s file +// TODO: revise dynamic_link, memory pools and etc. if the library dependency is removed. + +extern "C" { + int8_t __TBB_machine_fetchadd1__TBB_full_fence (volatile void *ptr, int8_t addend); + int8_t __TBB_machine_fetchadd1acquire(volatile void *ptr, int8_t addend); + int8_t __TBB_machine_fetchadd1release(volatile void *ptr, int8_t addend); + + int16_t __TBB_machine_fetchadd2__TBB_full_fence (volatile void *ptr, int16_t addend); + int16_t __TBB_machine_fetchadd2acquire(volatile void *ptr, int16_t addend); + int16_t __TBB_machine_fetchadd2release(volatile void *ptr, int16_t addend); + + int32_t __TBB_machine_fetchadd4__TBB_full_fence (volatile void *ptr, int32_t value); + int32_t __TBB_machine_fetchadd4acquire(volatile void *ptr, int32_t addend); + int32_t __TBB_machine_fetchadd4release(volatile void *ptr, int32_t addend); + + int64_t __TBB_machine_fetchadd8__TBB_full_fence (volatile void *ptr, int64_t value); + int64_t __TBB_machine_fetchadd8acquire(volatile void *ptr, int64_t addend); + int64_t __TBB_machine_fetchadd8release(volatile void *ptr, int64_t addend); + + int8_t __TBB_machine_fetchstore1__TBB_full_fence (volatile void *ptr, int8_t value); + int8_t __TBB_machine_fetchstore1acquire(volatile void *ptr, int8_t value); + int8_t __TBB_machine_fetchstore1release(volatile void *ptr, int8_t value); + + int16_t __TBB_machine_fetchstore2__TBB_full_fence (volatile void *ptr, int16_t value); + int16_t __TBB_machine_fetchstore2acquire(volatile void *ptr, int16_t value); + int16_t __TBB_machine_fetchstore2release(volatile void *ptr, int16_t value); + + int32_t __TBB_machine_fetchstore4__TBB_full_fence (volatile void *ptr, int32_t value); + int32_t __TBB_machine_fetchstore4acquire(volatile void *ptr, int32_t value); + int32_t __TBB_machine_fetchstore4release(volatile void *ptr, int32_t value); + + int64_t __TBB_machine_fetchstore8__TBB_full_fence (volatile void *ptr, int64_t value); + int64_t __TBB_machine_fetchstore8acquire(volatile void *ptr, int64_t value); + int64_t __TBB_machine_fetchstore8release(volatile void *ptr, int64_t value); + + int8_t __TBB_machine_cmpswp1__TBB_full_fence (volatile void *ptr, int8_t value, int8_t comparand); + int8_t __TBB_machine_cmpswp1acquire(volatile void *ptr, int8_t value, int8_t comparand); + int8_t __TBB_machine_cmpswp1release(volatile void *ptr, int8_t value, int8_t comparand); + + int16_t __TBB_machine_cmpswp2__TBB_full_fence (volatile void *ptr, int16_t value, int16_t comparand); + int16_t __TBB_machine_cmpswp2acquire(volatile void *ptr, int16_t value, int16_t comparand); + int16_t __TBB_machine_cmpswp2release(volatile void *ptr, int16_t value, int16_t comparand); + + int32_t __TBB_machine_cmpswp4__TBB_full_fence (volatile void *ptr, int32_t value, int32_t comparand); + int32_t __TBB_machine_cmpswp4acquire(volatile void *ptr, int32_t value, int32_t comparand); + int32_t __TBB_machine_cmpswp4release(volatile void *ptr, int32_t value, int32_t comparand); + + int64_t __TBB_machine_cmpswp8__TBB_full_fence (volatile void *ptr, int64_t value, int64_t comparand); + int64_t __TBB_machine_cmpswp8acquire(volatile void *ptr, int64_t value, int64_t comparand); + int64_t __TBB_machine_cmpswp8release(volatile void *ptr, int64_t value, int64_t comparand); + + int64_t __TBB_machine_lg(uint64_t value); + void __TBB_machine_pause(int32_t delay); + bool __TBB_machine_trylockbyte( volatile unsigned char &ptr ); + int64_t __TBB_machine_lockbyte( volatile unsigned char &ptr ); + + //! Retrieves the current RSE backing store pointer. IA64 specific. + void* __TBB_get_bsp(); + + int32_t __TBB_machine_load1_relaxed(const void *ptr); + int32_t __TBB_machine_load2_relaxed(const void *ptr); + int32_t __TBB_machine_load4_relaxed(const void *ptr); + int64_t __TBB_machine_load8_relaxed(const void *ptr); + + void __TBB_machine_store1_relaxed(void *ptr, int32_t value); + void __TBB_machine_store2_relaxed(void *ptr, int32_t value); + void __TBB_machine_store4_relaxed(void *ptr, int32_t value); + void __TBB_machine_store8_relaxed(void *ptr, int64_t value); +} // extern "C" + +// Mapping old entry points to the names corresponding to the new full_fence identifier. +#define __TBB_machine_fetchadd1full_fence __TBB_machine_fetchadd1__TBB_full_fence +#define __TBB_machine_fetchadd2full_fence __TBB_machine_fetchadd2__TBB_full_fence +#define __TBB_machine_fetchadd4full_fence __TBB_machine_fetchadd4__TBB_full_fence +#define __TBB_machine_fetchadd8full_fence __TBB_machine_fetchadd8__TBB_full_fence +#define __TBB_machine_fetchstore1full_fence __TBB_machine_fetchstore1__TBB_full_fence +#define __TBB_machine_fetchstore2full_fence __TBB_machine_fetchstore2__TBB_full_fence +#define __TBB_machine_fetchstore4full_fence __TBB_machine_fetchstore4__TBB_full_fence +#define __TBB_machine_fetchstore8full_fence __TBB_machine_fetchstore8__TBB_full_fence +#define __TBB_machine_cmpswp1full_fence __TBB_machine_cmpswp1__TBB_full_fence +#define __TBB_machine_cmpswp2full_fence __TBB_machine_cmpswp2__TBB_full_fence +#define __TBB_machine_cmpswp4full_fence __TBB_machine_cmpswp4__TBB_full_fence +#define __TBB_machine_cmpswp8full_fence __TBB_machine_cmpswp8__TBB_full_fence + +// Mapping relaxed operations to the entry points implementing them. +/** On IA64 RMW operations implicitly have acquire semantics. Thus one cannot + actually have completely relaxed RMW operation here. **/ +#define __TBB_machine_fetchadd1relaxed __TBB_machine_fetchadd1acquire +#define __TBB_machine_fetchadd2relaxed __TBB_machine_fetchadd2acquire +#define __TBB_machine_fetchadd4relaxed __TBB_machine_fetchadd4acquire +#define __TBB_machine_fetchadd8relaxed __TBB_machine_fetchadd8acquire +#define __TBB_machine_fetchstore1relaxed __TBB_machine_fetchstore1acquire +#define __TBB_machine_fetchstore2relaxed __TBB_machine_fetchstore2acquire +#define __TBB_machine_fetchstore4relaxed __TBB_machine_fetchstore4acquire +#define __TBB_machine_fetchstore8relaxed __TBB_machine_fetchstore8acquire +#define __TBB_machine_cmpswp1relaxed __TBB_machine_cmpswp1acquire +#define __TBB_machine_cmpswp2relaxed __TBB_machine_cmpswp2acquire +#define __TBB_machine_cmpswp4relaxed __TBB_machine_cmpswp4acquire +#define __TBB_machine_cmpswp8relaxed __TBB_machine_cmpswp8acquire + +#define __TBB_MACHINE_DEFINE_ATOMICS(S,V) \ + template \ + struct machine_load_store_relaxed { \ + static inline T load ( const T& location ) { \ + return (T)__TBB_machine_load##S##_relaxed(&location); \ + } \ + static inline void store ( T& location, T value ) { \ + __TBB_machine_store##S##_relaxed(&location, (V)value); \ + } \ + } + +namespace tbb { +namespace internal { + __TBB_MACHINE_DEFINE_ATOMICS(1,int8_t); + __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t); + __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t); + __TBB_MACHINE_DEFINE_ATOMICS(8,int64_t); +}} // namespaces internal, tbb + +#undef __TBB_MACHINE_DEFINE_ATOMICS + +#define __TBB_USE_FENCED_ATOMICS 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + +// Definition of Lock functions +#define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) +#define __TBB_LockByte(P) __TBB_machine_lockbyte(P) + +// Definition of other utility functions +#define __TBB_Pause(V) __TBB_machine_pause(V) +#define __TBB_Log2(V) __TBB_machine_lg(V) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_intel64.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_intel64.h new file mode 100644 index 00000000..907ead52 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/linux_intel64.h @@ -0,0 +1,92 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_intel64_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_linux_intel64_H + +#include +#include "gcc_ia32_common.h" + +#define __TBB_WORDSIZE 8 +#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE + +#define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory") +#define __TBB_control_consistency_helper() __TBB_compiler_fence() +#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() +#define __TBB_release_consistency_helper() __TBB_compiler_fence() + +#ifndef __TBB_full_memory_fence +#define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory") +#endif + +#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,X) \ +static inline T __TBB_machine_cmpswp##S (volatile void *ptr, T value, T comparand ) \ +{ \ + T result; \ + \ + __asm__ __volatile__("lock\ncmpxchg" X " %2,%1" \ + : "=a"(result), "=m"(*(volatile T*)ptr) \ + : "q"(value), "0"(comparand), "m"(*(volatile T*)ptr) \ + : "memory"); \ + return result; \ +} \ + \ +static inline T __TBB_machine_fetchadd##S(volatile void *ptr, T addend) \ +{ \ + T result; \ + __asm__ __volatile__("lock\nxadd" X " %0,%1" \ + : "=r"(result),"=m"(*(volatile T*)ptr) \ + : "0"(addend), "m"(*(volatile T*)ptr) \ + : "memory"); \ + return result; \ +} \ + \ +static inline T __TBB_machine_fetchstore##S(volatile void *ptr, T value) \ +{ \ + T result; \ + __asm__ __volatile__("lock\nxchg" X " %0,%1" \ + : "=r"(result),"=m"(*(volatile T*)ptr) \ + : "0"(value), "m"(*(volatile T*)ptr) \ + : "memory"); \ + return result; \ +} \ + +__TBB_MACHINE_DEFINE_ATOMICS(1,int8_t,"") +__TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"") +__TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"") +__TBB_MACHINE_DEFINE_ATOMICS(8,int64_t,"q") + +#undef __TBB_MACHINE_DEFINE_ATOMICS + +static inline void __TBB_machine_or( volatile void *ptr, uint64_t value ) { + __asm__ __volatile__("lock\norq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(value), "m"(*(volatile uint64_t*)ptr) : "memory"); +} + +static inline void __TBB_machine_and( volatile void *ptr, uint64_t value ) { + __asm__ __volatile__("lock\nandq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(value), "m"(*(volatile uint64_t*)ptr) : "memory"); +} + +#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) +#define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) + +#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/mac_ppc.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/mac_ppc.h new file mode 100644 index 00000000..2eb5ad3a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/mac_ppc.h @@ -0,0 +1,309 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_power_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_gcc_power_H + +#include +#include + +// TODO: rename to gcc_power.h? +// This file is for Power Architecture with compilers supporting GNU inline-assembler syntax (currently GNU g++ and IBM XL). +// Note that XL V9.0 (sometimes?) has trouble dealing with empty input and/or clobber lists, so they should be avoided. + +#if __powerpc64__ || __ppc64__ + // IBM XL documents __powerpc64__ (and __PPC64__). + // Apple documents __ppc64__ (with __ppc__ only on 32-bit). + #define __TBB_WORDSIZE 8 +#else + #define __TBB_WORDSIZE 4 +#endif + +// Traditionally Power Architecture is big-endian. +// Little-endian could be just an address manipulation (compatibility with TBB not verified), +// or normal little-endian (on more recent systems). Embedded PowerPC systems may support +// page-specific endianness, but then one endianness must be hidden from TBB so that it still sees only one. +#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG +#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE +#elif defined(__BYTE_ORDER__) + #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED +#else + #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT +#endif + +// On Power Architecture, (lock-free) 64-bit atomics require 64-bit hardware: +#if __TBB_WORDSIZE==8 + // Do not change the following definition, because TBB itself will use 64-bit atomics in 64-bit builds. + #define __TBB_64BIT_ATOMICS 1 +#elif __bgp__ + // Do not change the following definition, because this is known 32-bit hardware. + #define __TBB_64BIT_ATOMICS 0 +#else + // To enable 64-bit atomics in 32-bit builds, set the value below to 1 instead of 0. + // You must make certain that the program will only use them on actual 64-bit hardware + // (which typically means that the entire program is only executed on such hardware), + // because their implementation involves machine instructions that are illegal elsewhere. + // The setting can be chosen independently per compilation unit, + // which also means that TBB itself does not need to be rebuilt. + // Alternatively (but only for the current architecture and TBB version), + // override the default as a predefined macro when invoking the compiler. + #ifndef __TBB_64BIT_ATOMICS + #define __TBB_64BIT_ATOMICS 0 + #endif +#endif + +inline int32_t __TBB_machine_cmpswp4 (volatile void *ptr, int32_t value, int32_t comparand ) +{ + int32_t result; + + __asm__ __volatile__("sync\n" + "0:\n\t" + "lwarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ + "cmpw %[res],%[cmp]\n\t" /* compare against comparand */ + "bne- 1f\n\t" /* exit if not same */ + "stwcx. %[val],0,%[ptr]\n\t" /* store new value */ + "bne- 0b\n" /* retry if reservation lost */ + "1:\n\t" /* the exit */ + "isync" + : [res]"=&r"(result) + , "+m"(* (int32_t*) ptr) /* redundant with "memory" */ + : [ptr]"r"(ptr) + , [val]"r"(value) + , [cmp]"r"(comparand) + : "memory" /* compiler full fence */ + , "cr0" /* clobbered by cmp and/or stwcx. */ + ); + return result; +} + +#if __TBB_WORDSIZE==8 + +inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) +{ + int64_t result; + __asm__ __volatile__("sync\n" + "0:\n\t" + "ldarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ + "cmpd %[res],%[cmp]\n\t" /* compare against comparand */ + "bne- 1f\n\t" /* exit if not same */ + "stdcx. %[val],0,%[ptr]\n\t" /* store new value */ + "bne- 0b\n" /* retry if reservation lost */ + "1:\n\t" /* the exit */ + "isync" + : [res]"=&r"(result) + , "+m"(* (int64_t*) ptr) /* redundant with "memory" */ + : [ptr]"r"(ptr) + , [val]"r"(value) + , [cmp]"r"(comparand) + : "memory" /* compiler full fence */ + , "cr0" /* clobbered by cmp and/or stdcx. */ + ); + return result; +} + +#elif __TBB_64BIT_ATOMICS /* && __TBB_WORDSIZE==4 */ + +inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand ) +{ + int64_t result; + int64_t value_register, comparand_register, result_register; // dummy variables to allocate registers + __asm__ __volatile__("sync\n\t" + "ld %[val],%[valm]\n\t" + "ld %[cmp],%[cmpm]\n" + "0:\n\t" + "ldarx %[res],0,%[ptr]\n\t" /* load w/ reservation */ + "cmpd %[res],%[cmp]\n\t" /* compare against comparand */ + "bne- 1f\n\t" /* exit if not same */ + "stdcx. %[val],0,%[ptr]\n\t" /* store new value */ + "bne- 0b\n" /* retry if reservation lost */ + "1:\n\t" /* the exit */ + "std %[res],%[resm]\n\t" + "isync" + : [resm]"=m"(result) + , [res] "=&r"( result_register) + , [val] "=&r"( value_register) + , [cmp] "=&r"(comparand_register) + , "+m"(* (int64_t*) ptr) /* redundant with "memory" */ + : [ptr] "r"(ptr) + , [valm]"m"(value) + , [cmpm]"m"(comparand) + : "memory" /* compiler full fence */ + , "cr0" /* clobbered by cmpd and/or stdcx. */ + ); + return result; +} + +#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ + +#define __TBB_MACHINE_DEFINE_LOAD_STORE(S,ldx,stx,cmpx) \ + template \ + struct machine_load_store { \ + static inline T load_with_acquire(const volatile T& location) { \ + T result; \ + __asm__ __volatile__(ldx " %[res],0(%[ptr])\n" \ + "0:\n\t" \ + cmpx " %[res],%[res]\n\t" \ + "bne- 0b\n\t" \ + "isync" \ + : [res]"=r"(result) \ + : [ptr]"b"(&location) /* cannot use register 0 here */ \ + , "m"(location) /* redundant with "memory" */ \ + : "memory" /* compiler acquire fence */ \ + , "cr0" /* clobbered by cmpw/cmpd */); \ + return result; \ + } \ + static inline void store_with_release(volatile T &location, T value) { \ + __asm__ __volatile__("lwsync\n\t" \ + stx " %[val],0(%[ptr])" \ + : "=m"(location) /* redundant with "memory" */ \ + : [ptr]"b"(&location) /* cannot use register 0 here */ \ + , [val]"r"(value) \ + : "memory"/*compiler release fence*/ /*(cr0 not affected)*/); \ + } \ + }; \ + \ + template \ + struct machine_load_store_relaxed { \ + static inline T load (const __TBB_atomic T& location) { \ + T result; \ + __asm__ __volatile__(ldx " %[res],0(%[ptr])" \ + : [res]"=r"(result) \ + : [ptr]"b"(&location) /* cannot use register 0 here */ \ + , "m"(location) \ + ); /*(no compiler fence)*/ /*(cr0 not affected)*/ \ + return result; \ + } \ + static inline void store (__TBB_atomic T &location, T value) { \ + __asm__ __volatile__(stx " %[val],0(%[ptr])" \ + : "=m"(location) \ + : [ptr]"b"(&location) /* cannot use register 0 here */ \ + , [val]"r"(value) \ + ); /*(no compiler fence)*/ /*(cr0 not affected)*/ \ + } \ + }; + +namespace tbb { +namespace internal { + __TBB_MACHINE_DEFINE_LOAD_STORE(1,"lbz","stb","cmpw") + __TBB_MACHINE_DEFINE_LOAD_STORE(2,"lhz","sth","cmpw") + __TBB_MACHINE_DEFINE_LOAD_STORE(4,"lwz","stw","cmpw") + +#if __TBB_WORDSIZE==8 + + __TBB_MACHINE_DEFINE_LOAD_STORE(8,"ld" ,"std","cmpd") + +#elif __TBB_64BIT_ATOMICS /* && __TBB_WORDSIZE==4 */ + + template + struct machine_load_store { + static inline T load_with_acquire(const volatile T& location) { + T result; + T result_register; // dummy variable to allocate a register + __asm__ __volatile__("ld %[res],0(%[ptr])\n\t" + "std %[res],%[resm]\n" + "0:\n\t" + "cmpd %[res],%[res]\n\t" + "bne- 0b\n\t" + "isync" + : [resm]"=m"(result) + , [res]"=&r"(result_register) + : [ptr]"b"(&location) /* cannot use register 0 here */ + , "m"(location) /* redundant with "memory" */ + : "memory" /* compiler acquire fence */ + , "cr0" /* clobbered by cmpd */); + return result; + } + + static inline void store_with_release(volatile T &location, T value) { + T value_register; // dummy variable to allocate a register + __asm__ __volatile__("lwsync\n\t" + "ld %[val],%[valm]\n\t" + "std %[val],0(%[ptr])" + : "=m"(location) /* redundant with "memory" */ + , [val]"=&r"(value_register) + : [ptr]"b"(&location) /* cannot use register 0 here */ + , [valm]"m"(value) + : "memory"/*compiler release fence*/ /*(cr0 not affected)*/); + } + }; + + struct machine_load_store_relaxed { + static inline T load (const volatile T& location) { + T result; + T result_register; // dummy variable to allocate a register + __asm__ __volatile__("ld %[res],0(%[ptr])\n\t" + "std %[res],%[resm]" + : [resm]"=m"(result) + , [res]"=&r"(result_register) + : [ptr]"b"(&location) /* cannot use register 0 here */ + , "m"(location) + ); /*(no compiler fence)*/ /*(cr0 not affected)*/ + return result; + } + + static inline void store (volatile T &location, T value) { + T value_register; // dummy variable to allocate a register + __asm__ __volatile__("ld %[val],%[valm]\n\t" + "std %[val],0(%[ptr])" + : "=m"(location) + , [val]"=&r"(value_register) + : [ptr]"b"(&location) /* cannot use register 0 here */ + , [valm]"m"(value) + ); /*(no compiler fence)*/ /*(cr0 not affected)*/ + } + }; + #define __TBB_machine_load_store_relaxed_8 + +#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ + +}} // namespaces internal, tbb + +#undef __TBB_MACHINE_DEFINE_LOAD_STORE + +#define __TBB_USE_GENERIC_PART_WORD_CAS 1 +#define __TBB_USE_GENERIC_FETCH_ADD 1 +#define __TBB_USE_GENERIC_FETCH_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + +#define __TBB_control_consistency_helper() __asm__ __volatile__("isync": : :"memory") +#define __TBB_full_memory_fence() __asm__ __volatile__( "sync": : :"memory") + +static inline intptr_t __TBB_machine_lg( uintptr_t x ) { + __TBB_ASSERT(x, "__TBB_Log2(0) undefined"); + // cntlzd/cntlzw starts counting at 2^63/2^31 (ignoring any higher-order bits), and does not affect cr0 +#if __TBB_WORDSIZE==8 + __asm__ __volatile__ ("cntlzd %0,%0" : "+r"(x)); + return 63-static_cast(x); +#else + __asm__ __volatile__ ("cntlzw %0,%0" : "+r"(x)); + return 31-static_cast(x); +#endif +} +#define __TBB_Log2(V) __TBB_machine_lg(V) + +// Assumes implicit alignment for any 32-bit value +typedef uint32_t __TBB_Flag; +#define __TBB_Flag __TBB_Flag + +inline bool __TBB_machine_trylockbyte( __TBB_atomic __TBB_Flag &flag ) { + return __TBB_machine_cmpswp4(&flag,1,0)==0; +} +#define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/macos_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/macos_common.h new file mode 100644 index 00000000..87bb5e3e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/macos_common.h @@ -0,0 +1,129 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_macos_common_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_macos_common_H + +#include +#define __TBB_Yield() sched_yield() + +// __TBB_HardwareConcurrency + +#include +#include + +static inline int __TBB_macos_available_cpu() { + int name[2] = {CTL_HW, HW_AVAILCPU}; + int ncpu; + size_t size = sizeof(ncpu); + sysctl( name, 2, &ncpu, &size, NULL, 0 ); + return ncpu; +} + +#define __TBB_HardwareConcurrency() __TBB_macos_available_cpu() + +#ifndef __TBB_full_memory_fence + // TBB has not recognized the architecture (none of the architecture abstraction + // headers was included). + #define __TBB_UnknownArchitecture 1 +#endif + +#if __TBB_UnknownArchitecture +// Implementation of atomic operations based on OS provided primitives +#include + +static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t value, int64_t comparand) +{ + __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for macOS* atomics"); + int64_t* address = (int64_t*)ptr; + while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){ +#if __TBB_WORDSIZE==8 + int64_t snapshot = *address; +#else + int64_t snapshot = OSAtomicAdd64( 0, address ); +#endif + if( snapshot!=comparand ) return snapshot; + } + return comparand; +} + +#define __TBB_machine_cmpswp8 __TBB_machine_cmpswp8_OsX + +#endif /* __TBB_UnknownArchitecture */ + +#if __TBB_UnknownArchitecture + +#ifndef __TBB_WORDSIZE +#define __TBB_WORDSIZE __SIZEOF_POINTER__ +#endif + +#ifdef __TBB_ENDIANNESS + // Already determined based on hardware architecture. +#elif __BIG_ENDIAN__ + #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG +#elif __LITTLE_ENDIAN__ + #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE +#else + #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED +#endif + +/** As this generic implementation has absolutely no information about underlying + hardware, its performance most likely will be sub-optimal because of full memory + fence usages where a more lightweight synchronization means (or none at all) + could suffice. Thus if you use this header to enable TBB on a new platform, + consider forking it and relaxing below helpers as appropriate. **/ +#define __TBB_control_consistency_helper() OSMemoryBarrier() +#define __TBB_acquire_consistency_helper() OSMemoryBarrier() +#define __TBB_release_consistency_helper() OSMemoryBarrier() +#define __TBB_full_memory_fence() OSMemoryBarrier() + +static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand) +{ + __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for macOS atomics"); + int32_t* address = (int32_t*)ptr; + while( !OSAtomicCompareAndSwap32Barrier(comparand, value, address) ){ + int32_t snapshot = *address; + if( snapshot!=comparand ) return snapshot; + } + return comparand; +} + +static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend) +{ + __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for macOS atomics"); + return OSAtomicAdd32Barrier(addend, (int32_t*)ptr) - addend; +} + +static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend) +{ + __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for macOS atomics"); + return OSAtomicAdd64Barrier(addend, (int64_t*)ptr) - addend; +} + +#define __TBB_USE_GENERIC_PART_WORD_CAS 1 +#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 +#define __TBB_USE_GENERIC_FETCH_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 +#if __TBB_WORDSIZE == 4 + #define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 +#endif +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + +#endif /* __TBB_UnknownArchitecture */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/mic_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/mic_common.h new file mode 100644 index 00000000..8c844f1d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/mic_common.h @@ -0,0 +1,53 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_mic_common_H +#define __TBB_mic_common_H + +#ifndef __TBB_machine_H +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#if ! __TBB_DEFINE_MIC + #error mic_common.h should be included only when building for Intel(R) Many Integrated Core Architecture +#endif + +#ifndef __TBB_PREFETCHING +#define __TBB_PREFETCHING 1 +#endif +#if __TBB_PREFETCHING +#include +#define __TBB_cl_prefetch(p) _mm_prefetch((const char*)p, _MM_HINT_T1) +#define __TBB_cl_evict(p) _mm_clevict(p, _MM_HINT_T1) +#endif + +/** Intel(R) Many Integrated Core Architecture does not support mfence and pause instructions **/ +#define __TBB_full_memory_fence() __asm__ __volatile__("lock; addl $0,(%%rsp)":::"memory") +#define __TBB_Pause(x) _mm_delay_32(16*(x)) +#define __TBB_STEALING_PAUSE 1500/16 +#include +#define __TBB_Yield() sched_yield() + +/** Specifics **/ +#define __TBB_STEALING_ABORT_ON_CONTENTION 1 +#define __TBB_YIELD2P 1 +#define __TBB_HOARD_NONLOCAL_TASKS 1 + +#if ! ( __FreeBSD__ || __linux__ ) + #error Intel(R) Many Integrated Core Compiler does not define __FreeBSD__ or __linux__ anymore. Check for the __TBB_XXX_BROKEN defined under __FreeBSD__ or __linux__. +#endif /* ! ( __FreeBSD__ || __linux__ ) */ + +#endif /* __TBB_mic_common_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/msvc_armv7.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/msvc_armv7.h new file mode 100644 index 00000000..e83c077e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/msvc_armv7.h @@ -0,0 +1,167 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_msvc_armv7_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_msvc_armv7_H + +#include +#include + +#define __TBB_WORDSIZE 4 + +#define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED + +#if defined(TBB_WIN32_USE_CL_BUILTINS) +// We can test this on _M_IX86 +#pragma intrinsic(_ReadWriteBarrier) +#pragma intrinsic(_mm_mfence) +#define __TBB_compiler_fence() _ReadWriteBarrier() +#define __TBB_full_memory_fence() _mm_mfence() +#define __TBB_control_consistency_helper() __TBB_compiler_fence() +#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() +#define __TBB_release_consistency_helper() __TBB_compiler_fence() +#else +//Now __dmb(_ARM_BARRIER_SY) is used for both compiler and memory fences +//This might be changed later after testing +#define __TBB_compiler_fence() __dmb(_ARM_BARRIER_SY) +#define __TBB_full_memory_fence() __dmb(_ARM_BARRIER_SY) +#define __TBB_control_consistency_helper() __TBB_compiler_fence() +#define __TBB_acquire_consistency_helper() __TBB_full_memory_fence() +#define __TBB_release_consistency_helper() __TBB_full_memory_fence() +#endif + +//-------------------------------------------------- +// Compare and swap +//-------------------------------------------------- + +/** + * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr + * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand + * @param value value to assign *ptr to if *ptr==comparand + * @param comparand value to compare with *ptr + * @return value originally in memory at ptr, regardless of success +*/ + +#define __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(S,T,F) \ +inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) { \ + return _InterlockedCompareExchange##F(reinterpret_cast(ptr),value,comparand); \ +} \ + +#define __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(S,T,F) \ +inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) { \ + return _InterlockedExchangeAdd##F(reinterpret_cast(ptr),value); \ +} \ + +__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(1,char,8) +__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(2,short,16) +__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(4,long,) +__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(8,__int64,64) +__TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(4,long,) +#if defined(TBB_WIN32_USE_CL_BUILTINS) +// No _InterlockedExchangeAdd64 intrinsic on _M_IX86 +#define __TBB_64BIT_ATOMICS 0 +#else +__TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(8,__int64,64) +#endif + +inline void __TBB_machine_pause (int32_t delay ) +{ + while(delay>0) + { + __TBB_compiler_fence(); + delay--; + } +} + +// API to retrieve/update FPU control setting +#define __TBB_CPU_CTL_ENV_PRESENT 1 + +namespace tbb { +namespace internal { + +template +struct machine_load_store_relaxed { + static inline T load ( const volatile T& location ) { + const T value = location; + + /* + * An extra memory barrier is required for errata #761319 + * Please see http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a + */ + __TBB_acquire_consistency_helper(); + return value; + } + + static inline void store ( volatile T& location, T value ) { + location = value; + } +}; + +class cpu_ctl_env { +private: + unsigned int my_ctl; +public: + bool operator!=( const cpu_ctl_env& ctl ) const { return my_ctl != ctl.my_ctl; } + void get_env() { my_ctl = _control87(0, 0); } + void set_env() const { _control87( my_ctl, ~0U ); } +}; + +} // namespace internal +} // namespaces tbb + +// Machine specific atomic operations +#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C) +#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C) +#define __TBB_Pause(V) __TBB_machine_pause(V) + +// Use generics for some things +#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 +#define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE 1 +#define __TBB_USE_GENERIC_FETCH_STORE 1 +#define __TBB_USE_GENERIC_DWORD_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + +#if defined(TBB_WIN32_USE_CL_BUILTINS) +#if !__TBB_WIN8UI_SUPPORT +extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); +#define __TBB_Yield() SwitchToThread() +#else +#include +#define __TBB_Yield() std::this_thread::yield() +#endif +#else +#define __TBB_Yield() __yield() +#endif + +// Machine specific atomic operations +#define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V) +#define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V) + +template +inline void __TBB_machine_OR( T1 *operand, T2 addend ) { + _InterlockedOr((long volatile *)operand, (long)addend); +} + +template +inline void __TBB_machine_AND( T1 *operand, T2 addend ) { + _InterlockedAnd((long volatile *)operand, (long)addend); +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/msvc_ia32_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/msvc_ia32_common.h new file mode 100644 index 00000000..2e17836d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/msvc_ia32_common.h @@ -0,0 +1,275 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_msvc_ia32_common_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_msvc_ia32_common_H + +#include + +//TODO: consider moving this macro to tbb_config.h and using where MSVC asm is used +#if !_M_X64 || __INTEL_COMPILER + #define __TBB_X86_MSVC_INLINE_ASM_AVAILABLE 1 +#else + //MSVC in x64 mode does not accept inline assembler + #define __TBB_X86_MSVC_INLINE_ASM_AVAILABLE 0 + #define __TBB_NO_X86_MSVC_INLINE_ASM_MSG "The compiler being used is not supported (outdated?)" +#endif + +#if _M_X64 + #define __TBB_r(reg_name) r##reg_name + #define __TBB_W(name) name##64 + namespace tbb { namespace internal { namespace msvc_intrinsics { + typedef __int64 word; + }}} +#else + #define __TBB_r(reg_name) e##reg_name + #define __TBB_W(name) name + namespace tbb { namespace internal { namespace msvc_intrinsics { + typedef long word; + }}} +#endif + +#if __TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT + // S is the operand size in bytes, B is the suffix for intrinsics for that size + #define __TBB_MACHINE_DEFINE_ATOMICS(S,B,T,U) \ + __pragma(intrinsic( _InterlockedCompareExchange##B )) \ + static inline T __TBB_machine_cmpswp##S ( volatile void * ptr, U value, U comparand ) { \ + return _InterlockedCompareExchange##B ( (T*)ptr, value, comparand ); \ + } \ + __pragma(intrinsic( _InterlockedExchangeAdd##B )) \ + static inline T __TBB_machine_fetchadd##S ( volatile void * ptr, U addend ) { \ + return _InterlockedExchangeAdd##B ( (T*)ptr, addend ); \ + } \ + __pragma(intrinsic( _InterlockedExchange##B )) \ + static inline T __TBB_machine_fetchstore##S ( volatile void * ptr, U value ) { \ + return _InterlockedExchange##B ( (T*)ptr, value ); \ + } + + // Atomic intrinsics for 1, 2, and 4 bytes are available for x86 & x64 + __TBB_MACHINE_DEFINE_ATOMICS(1,8,char,__int8) + __TBB_MACHINE_DEFINE_ATOMICS(2,16,short,__int16) + __TBB_MACHINE_DEFINE_ATOMICS(4,,long,__int32) + + #if __TBB_WORDSIZE==8 + __TBB_MACHINE_DEFINE_ATOMICS(8,64,__int64,__int64) + #endif + + #undef __TBB_MACHINE_DEFINE_ATOMICS +#endif /* __TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT */ + +#if _MSC_VER>=1300 || __INTEL_COMPILER>=1100 + #pragma intrinsic(_ReadWriteBarrier) + #pragma intrinsic(_mm_mfence) + #define __TBB_compiler_fence() _ReadWriteBarrier() + #define __TBB_full_memory_fence() _mm_mfence() +#elif __TBB_X86_MSVC_INLINE_ASM_AVAILABLE + #define __TBB_compiler_fence() __asm { __asm nop } + #define __TBB_full_memory_fence() __asm { __asm mfence } +#else + #error Unsupported compiler; define __TBB_{control,acquire,release}_consistency_helper to support it +#endif + +#define __TBB_control_consistency_helper() __TBB_compiler_fence() +#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() +#define __TBB_release_consistency_helper() __TBB_compiler_fence() + +#if (_MSC_VER>=1300) || (__INTEL_COMPILER) + #pragma intrinsic(_mm_pause) + namespace tbb { namespace internal { namespace msvc_intrinsics { + static inline void pause (uintptr_t delay ) { + for (;delay>0; --delay ) + _mm_pause(); + } + }}} + #define __TBB_Pause(V) tbb::internal::msvc_intrinsics::pause(V) + #define __TBB_SINGLE_PAUSE _mm_pause() +#else + #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE + #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG + #endif + namespace tbb { namespace internal { namespace msvc_inline_asm + static inline void pause (uintptr_t delay ) { + _asm + { + mov __TBB_r(ax), delay + __TBB_L1: + pause + add __TBB_r(ax), -1 + jne __TBB_L1 + } + return; + } + }}} + #define __TBB_Pause(V) tbb::internal::msvc_inline_asm::pause(V) + #define __TBB_SINGLE_PAUSE __asm pause +#endif + +#if (_MSC_VER>=1400 && !__INTEL_COMPILER) || (__INTEL_COMPILER>=1200) +// MSVC did not have this intrinsic prior to VC8. +// ICL 11.1 fails to compile a TBB example if __TBB_Log2 uses the intrinsic. + #pragma intrinsic(__TBB_W(_BitScanReverse)) + namespace tbb { namespace internal { namespace msvc_intrinsics { + static inline uintptr_t lg_bsr( uintptr_t i ){ + unsigned long j; + __TBB_W(_BitScanReverse)( &j, i ); + return j; + } + }}} + #define __TBB_Log2(V) tbb::internal::msvc_intrinsics::lg_bsr(V) +#else + #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE + #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG + #endif + namespace tbb { namespace internal { namespace msvc_inline_asm { + static inline uintptr_t lg_bsr( uintptr_t i ){ + uintptr_t j; + __asm + { + bsr __TBB_r(ax), i + mov j, __TBB_r(ax) + } + return j; + } + }}} + #define __TBB_Log2(V) tbb::internal::msvc_inline_asm::lg_bsr(V) +#endif + +#if _MSC_VER>=1400 + #pragma intrinsic(__TBB_W(_InterlockedOr)) + #pragma intrinsic(__TBB_W(_InterlockedAnd)) + namespace tbb { namespace internal { namespace msvc_intrinsics { + static inline void lock_or( volatile void *operand, intptr_t addend ){ + __TBB_W(_InterlockedOr)((volatile word*)operand, addend); + } + static inline void lock_and( volatile void *operand, intptr_t addend ){ + __TBB_W(_InterlockedAnd)((volatile word*)operand, addend); + } + }}} + #define __TBB_AtomicOR(P,V) tbb::internal::msvc_intrinsics::lock_or(P,V) + #define __TBB_AtomicAND(P,V) tbb::internal::msvc_intrinsics::lock_and(P,V) +#else + #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE + #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG + #endif + namespace tbb { namespace internal { namespace msvc_inline_asm { + static inline void lock_or( volatile void *operand, __int32 addend ) { + __asm + { + mov eax, addend + mov edx, [operand] + lock or [edx], eax + } + } + static inline void lock_and( volatile void *operand, __int32 addend ) { + __asm + { + mov eax, addend + mov edx, [operand] + lock and [edx], eax + } + } + }}} + #define __TBB_AtomicOR(P,V) tbb::internal::msvc_inline_asm::lock_or(P,V) + #define __TBB_AtomicAND(P,V) tbb::internal::msvc_inline_asm::lock_and(P,V) +#endif + +#pragma intrinsic(__rdtsc) +namespace tbb { namespace internal { typedef uint64_t machine_tsc_t; } } +static inline tbb::internal::machine_tsc_t __TBB_machine_time_stamp() { + return __rdtsc(); +} +#define __TBB_time_stamp() __TBB_machine_time_stamp() + +// API to retrieve/update FPU control setting +#define __TBB_CPU_CTL_ENV_PRESENT 1 + +namespace tbb { namespace internal { class cpu_ctl_env; } } +#if __TBB_X86_MSVC_INLINE_ASM_AVAILABLE + inline void __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* ctl ) { + __asm { + __asm mov __TBB_r(ax), ctl + __asm stmxcsr [__TBB_r(ax)] + __asm fstcw [__TBB_r(ax)+4] + } + } + inline void __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* ctl ) { + __asm { + __asm mov __TBB_r(ax), ctl + __asm ldmxcsr [__TBB_r(ax)] + __asm fldcw [__TBB_r(ax)+4] + } + } +#else + extern "C" { + void __TBB_EXPORTED_FUNC __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* ); + void __TBB_EXPORTED_FUNC __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* ); + } +#endif + +namespace tbb { +namespace internal { +class cpu_ctl_env { +private: + int mxcsr; + short x87cw; + static const int MXCSR_CONTROL_MASK = ~0x3f; /* all except last six status bits */ +public: + bool operator!=( const cpu_ctl_env& ctl ) const { return mxcsr != ctl.mxcsr || x87cw != ctl.x87cw; } + void get_env() { + __TBB_get_cpu_ctl_env( this ); + mxcsr &= MXCSR_CONTROL_MASK; + } + void set_env() const { __TBB_set_cpu_ctl_env( this ); } +}; +} // namespace internal +} // namespace tbb + +#if !__TBB_WIN8UI_SUPPORT +extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); +#define __TBB_Yield() SwitchToThread() +#else +#include +#define __TBB_Yield() std::this_thread::yield() +#endif + +#undef __TBB_r +#undef __TBB_W +#undef __TBB_word + +extern "C" { + __int8 __TBB_EXPORTED_FUNC __TBB_machine_try_lock_elided (volatile void* ptr); + void __TBB_EXPORTED_FUNC __TBB_machine_unlock_elided (volatile void* ptr); + + // 'pause' instruction aborts HLE/RTM transactions + inline static void __TBB_machine_try_lock_elided_cancel() { __TBB_SINGLE_PAUSE; } + +#if __TBB_TSX_INTRINSICS_PRESENT + #define __TBB_machine_is_in_transaction _xtest + #define __TBB_machine_begin_transaction _xbegin + #define __TBB_machine_end_transaction _xend + // The value (0xFF) below comes from the + // Intel(R) 64 and IA-32 Architectures Optimization Reference Manual 12.4.5 lock not free + #define __TBB_machine_transaction_conflict_abort() _xabort(0xFF) +#else + __int8 __TBB_EXPORTED_FUNC __TBB_machine_is_in_transaction(); + unsigned __int32 __TBB_EXPORTED_FUNC __TBB_machine_begin_transaction(); + void __TBB_EXPORTED_FUNC __TBB_machine_end_transaction(); + void __TBB_EXPORTED_FUNC __TBB_machine_transaction_conflict_abort(); +#endif /* __TBB_TSX_INTRINSICS_PRESENT */ +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/sunos_sparc.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/sunos_sparc.h new file mode 100644 index 00000000..b5864ba7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/sunos_sparc.h @@ -0,0 +1,199 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_sunos_sparc_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_sunos_sparc_H + +#include +#include + +#define __TBB_WORDSIZE 8 +// Big endian is assumed for SPARC. +// While hardware may support page-specific bi-endianness, only big endian pages may be exposed to TBB +#define __TBB_ENDIANNESS __TBB_ENDIAN_BIG + +/** To those working on SPARC hardware. Consider relaxing acquire and release + consistency helpers to no-op (as this port covers TSO mode only). **/ +#define __TBB_compiler_fence() __asm__ __volatile__ ("": : :"memory") +#define __TBB_control_consistency_helper() __TBB_compiler_fence() +#define __TBB_acquire_consistency_helper() __TBB_compiler_fence() +#define __TBB_release_consistency_helper() __TBB_compiler_fence() +#define __TBB_full_memory_fence() __asm__ __volatile__("membar #LoadLoad|#LoadStore|#StoreStore|#StoreLoad": : : "memory") + +//-------------------------------------------------- +// Compare and swap +//-------------------------------------------------- + +/** + * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr + * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand + * @param value value to assign *ptr to if *ptr==comparand + * @param comparand value to compare with *ptr + ( @return value originally in memory at ptr, regardless of success +*/ +static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand ){ + int32_t result; + __asm__ __volatile__( + "cas\t[%5],%4,%1" + : "=m"(*(int32_t *)ptr), "=r"(result) + : "m"(*(int32_t *)ptr), "1"(value), "r"(comparand), "r"(ptr) + : "memory"); + return result; +} + +/** + * Atomic CAS for 64 bit values, if *ptr==comparand, then *ptr=value, returns *ptr + * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand + * @param value value to assign *ptr to if *ptr==comparand + * @param comparand value to compare with *ptr + ( @return value originally in memory at ptr, regardless of success + */ +static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, int64_t comparand ){ + int64_t result; + __asm__ __volatile__( + "casx\t[%5],%4,%1" + : "=m"(*(int64_t *)ptr), "=r"(result) + : "m"(*(int64_t *)ptr), "1"(value), "r"(comparand), "r"(ptr) + : "memory"); + return result; +} + +//--------------------------------------------------- +// Fetch and add +//--------------------------------------------------- + +/** + * Atomic fetch and add for 32 bit values, in this case implemented by continuously checking success of atomicity + * @param ptr pointer to value to add addend to + * @param addened value to add to *ptr + * @return value at ptr before addened was added + */ +static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend){ + int32_t result; + __asm__ __volatile__ ( + "0:\t add\t %3, %4, %0\n" // do addition + "\t cas\t [%2], %3, %0\n" // cas to store result in memory + "\t cmp\t %3, %0\n" // check if value from memory is original + "\t bne,a,pn\t %%icc, 0b\n" // if not try again + "\t mov %0, %3\n" // use branch delay slot to move new value in memory to be added + : "=&r"(result), "=m"(*(int32_t *)ptr) + : "r"(ptr), "r"(*(int32_t *)ptr), "r"(addend), "m"(*(int32_t *)ptr) + : "ccr", "memory"); + return result; +} + +/** + * Atomic fetch and add for 64 bit values, in this case implemented by continuously checking success of atomicity + * @param ptr pointer to value to add addend to + * @param addened value to add to *ptr + * @return value at ptr before addened was added + */ +static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend){ + int64_t result; + __asm__ __volatile__ ( + "0:\t add\t %3, %4, %0\n" // do addition + "\t casx\t [%2], %3, %0\n" // cas to store result in memory + "\t cmp\t %3, %0\n" // check if value from memory is original + "\t bne,a,pn\t %%xcc, 0b\n" // if not try again + "\t mov %0, %3\n" // use branch delay slot to move new value in memory to be added + : "=&r"(result), "=m"(*(int64_t *)ptr) + : "r"(ptr), "r"(*(int64_t *)ptr), "r"(addend), "m"(*(int64_t *)ptr) + : "ccr", "memory"); + return result; +} + +//-------------------------------------------------------- +// Logarithm (base two, integer) +//-------------------------------------------------------- + +static inline int64_t __TBB_machine_lg( uint64_t x ) { + __TBB_ASSERT(x, "__TBB_Log2(0) undefined"); + uint64_t count; + // one hot encode + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + x |= (x >> 32); + // count 1's + __asm__ ("popc %1, %0" : "=r"(count) : "r"(x) ); + return count-1; +} + +//-------------------------------------------------------- + +static inline void __TBB_machine_or( volatile void *ptr, uint64_t value ) { + __asm__ __volatile__ ( + "0:\t or\t %2, %3, %%g1\n" // do operation + "\t casx\t [%1], %2, %%g1\n" // cas to store result in memory + "\t cmp\t %2, %%g1\n" // check if value from memory is original + "\t bne,a,pn\t %%xcc, 0b\n" // if not try again + "\t mov %%g1, %2\n" // use branch delay slot to move new value in memory to be added + : "=m"(*(int64_t *)ptr) + : "r"(ptr), "r"(*(int64_t *)ptr), "r"(value), "m"(*(int64_t *)ptr) + : "ccr", "g1", "memory"); +} + +static inline void __TBB_machine_and( volatile void *ptr, uint64_t value ) { + __asm__ __volatile__ ( + "0:\t and\t %2, %3, %%g1\n" // do operation + "\t casx\t [%1], %2, %%g1\n" // cas to store result in memory + "\t cmp\t %2, %%g1\n" // check if value from memory is original + "\t bne,a,pn\t %%xcc, 0b\n" // if not try again + "\t mov %%g1, %2\n" // use branch delay slot to move new value in memory to be added + : "=m"(*(int64_t *)ptr) + : "r"(ptr), "r"(*(int64_t *)ptr), "r"(value), "m"(*(int64_t *)ptr) + : "ccr", "g1", "memory"); +} + + +static inline void __TBB_machine_pause( int32_t delay ) { + // do nothing, inlined, doesn't matter +} + +// put 0xff in memory location, return memory value, +// generic trylockbyte puts 0x01, however this is fine +// because all that matters is that 0 is unlocked +static inline bool __TBB_machine_trylockbyte(unsigned char &flag){ + unsigned char result; + __asm__ __volatile__ ( + "ldstub\t [%2], %0\n" + : "=r"(result), "=m"(flag) + : "r"(&flag), "m"(flag) + : "memory"); + return result == 0; +} + +#define __TBB_USE_GENERIC_PART_WORD_CAS 1 +#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD 1 +#define __TBB_USE_GENERIC_FETCH_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + +#define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V) +#define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V) + +// Definition of other functions +#define __TBB_Pause(V) __TBB_machine_pause(V) +#define __TBB_Log2(V) __TBB_machine_lg(V) + +#define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_api.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_api.h new file mode 100644 index 00000000..54987915 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_api.h @@ -0,0 +1,65 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_machine_windows_api_H +#define __TBB_machine_windows_api_H + +#if _WIN32 || _WIN64 + +#include + +#if _WIN32_WINNT < 0x0600 +// The following Windows API function is declared explicitly; +// otherwise it fails to compile by VS2005. +#if !defined(WINBASEAPI) || (_WIN32_WINNT < 0x0501 && _MSC_VER == 1400) +#define __TBB_WINBASEAPI extern "C" +#else +#define __TBB_WINBASEAPI WINBASEAPI +#endif +__TBB_WINBASEAPI BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION ); +__TBB_WINBASEAPI BOOL WINAPI InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION, DWORD ); +// Overloading WINBASEAPI macro and using local functions missing in Windows XP/2003 +#define InitializeCriticalSectionEx inlineInitializeCriticalSectionEx +#define CreateSemaphoreEx inlineCreateSemaphoreEx +#define CreateEventEx inlineCreateEventEx +inline BOOL WINAPI inlineInitializeCriticalSectionEx( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD ) +{ + return InitializeCriticalSectionAndSpinCount( lpCriticalSection, dwSpinCount ); +} +inline HANDLE WINAPI inlineCreateSemaphoreEx( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName, DWORD, DWORD ) +{ + return CreateSemaphore( lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName ); +} +inline HANDLE WINAPI inlineCreateEventEx( LPSECURITY_ATTRIBUTES lpEventAttributes, LPCTSTR lpName, DWORD dwFlags, DWORD ) +{ + BOOL manual_reset = dwFlags&0x00000001 ? TRUE : FALSE; // CREATE_EVENT_MANUAL_RESET + BOOL initial_set = dwFlags&0x00000002 ? TRUE : FALSE; // CREATE_EVENT_INITIAL_SET + return CreateEvent( lpEventAttributes, manual_reset, initial_set, lpName ); +} +#endif + +#if defined(RTL_SRWLOCK_INIT) +#ifndef __TBB_USE_SRWLOCK +// TODO: turn it on when bug 1952 will be fixed +#define __TBB_USE_SRWLOCK 0 +#endif +#endif + +#else +#error tbb/machine/windows_api.h should only be used for Windows based platforms +#endif // _WIN32 || _WIN64 + +#endif // __TBB_machine_windows_api_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_ia32.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_ia32.h new file mode 100644 index 00000000..62968226 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_ia32.h @@ -0,0 +1,105 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_ia32_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_windows_ia32_H + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (push) + #pragma warning (disable: 4244 4267) +#endif + +#include "msvc_ia32_common.h" + +#define __TBB_WORDSIZE 4 +#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE + +extern "C" { + __int64 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp8 (volatile void *ptr, __int64 value, __int64 comparand ); + __int64 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd8 (volatile void *ptr, __int64 addend ); + __int64 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore8 (volatile void *ptr, __int64 value ); + void __TBB_EXPORTED_FUNC __TBB_machine_store8 (volatile void *ptr, __int64 value ); + __int64 __TBB_EXPORTED_FUNC __TBB_machine_load8 (const volatile void *ptr); +} + +#if !__TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT + +#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,U,A,C) \ +static inline T __TBB_machine_cmpswp##S ( volatile void * ptr, U value, U comparand ) { \ + T result; \ + volatile T *p = (T *)ptr; \ + __asm \ + { \ + __asm mov edx, p \ + __asm mov C , value \ + __asm mov A , comparand \ + __asm lock cmpxchg [edx], C \ + __asm mov result, A \ + } \ + return result; \ +} \ +\ +static inline T __TBB_machine_fetchadd##S ( volatile void * ptr, U addend ) { \ + T result; \ + volatile T *p = (T *)ptr; \ + __asm \ + { \ + __asm mov edx, p \ + __asm mov A, addend \ + __asm lock xadd [edx], A \ + __asm mov result, A \ + } \ + return result; \ +}\ +\ +static inline T __TBB_machine_fetchstore##S ( volatile void * ptr, U value ) { \ + T result; \ + volatile T *p = (T *)ptr; \ + __asm \ + { \ + __asm mov edx, p \ + __asm mov A, value \ + __asm lock xchg [edx], A \ + __asm mov result, A \ + } \ + return result; \ +} + + +__TBB_MACHINE_DEFINE_ATOMICS(1, __int8, __int8, al, cl) +__TBB_MACHINE_DEFINE_ATOMICS(2, __int16, __int16, ax, cx) +__TBB_MACHINE_DEFINE_ATOMICS(4, ptrdiff_t, ptrdiff_t, eax, ecx) + +#undef __TBB_MACHINE_DEFINE_ATOMICS + +#endif /* __TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT */ + +//TODO: Check if it possible and profitable for IA-32 architecture on (Linux and Windows) +//to use of 64-bit load/store via floating point registers together with full fence +//for sequentially consistent load/store, instead of CAS. +#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 + + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warnings 4244, 4267 are back diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_intel64.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_intel64.h new file mode 100644 index 00000000..6e2a2cc7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/machine/windows_intel64.h @@ -0,0 +1,70 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_intel64_H) +#error Do not #include this internal file directly; use public TBB headers instead. +#endif + +#define __TBB_machine_windows_intel64_H + +#define __TBB_WORDSIZE 8 +#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE + +#include "msvc_ia32_common.h" + +#if !__TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT + +#include +#pragma intrinsic(_InterlockedCompareExchange,_InterlockedExchangeAdd,_InterlockedExchange) +#pragma intrinsic(_InterlockedCompareExchange64,_InterlockedExchangeAdd64,_InterlockedExchange64) + +// ATTENTION: if you ever change argument types in machine-specific primitives, +// please take care of atomic_word<> specializations in tbb/atomic.h +extern "C" { + __int8 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp1 (volatile void *ptr, __int8 value, __int8 comparand ); + __int8 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd1 (volatile void *ptr, __int8 addend ); + __int8 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore1 (volatile void *ptr, __int8 value ); + __int16 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp2 (volatile void *ptr, __int16 value, __int16 comparand ); + __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd2 (volatile void *ptr, __int16 addend ); + __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore2 (volatile void *ptr, __int16 value ); +} + +inline long __TBB_machine_cmpswp4 (volatile void *ptr, __int32 value, __int32 comparand ) { + return _InterlockedCompareExchange( (long*)ptr, value, comparand ); +} +inline long __TBB_machine_fetchadd4 (volatile void *ptr, __int32 addend ) { + return _InterlockedExchangeAdd( (long*)ptr, addend ); +} +inline long __TBB_machine_fetchstore4 (volatile void *ptr, __int32 value ) { + return _InterlockedExchange( (long*)ptr, value ); +} + +inline __int64 __TBB_machine_cmpswp8 (volatile void *ptr, __int64 value, __int64 comparand ) { + return _InterlockedCompareExchange64( (__int64*)ptr, value, comparand ); +} +inline __int64 __TBB_machine_fetchadd8 (volatile void *ptr, __int64 addend ) { + return _InterlockedExchangeAdd64( (__int64*)ptr, addend ); +} +inline __int64 __TBB_machine_fetchstore8 (volatile void *ptr, __int64 value ) { + return _InterlockedExchange64( (__int64*)ptr, value ); +} + +#endif /* __TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT */ + +#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE 1 +#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE 1 +#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1 diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/memory_pool.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/memory_pool.h new file mode 100644 index 00000000..99a31d6a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/memory_pool.h @@ -0,0 +1,275 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_memory_pool_H +#define __TBB_memory_pool_H + +#if !TBB_PREVIEW_MEMORY_POOL +#error Set TBB_PREVIEW_MEMORY_POOL to include memory_pool.h +#endif +/** @file */ + +#include "scalable_allocator.h" +#include // std::bad_alloc +#include // std::runtime_error, std::invalid_argument +// required in C++03 to construct std::runtime_error and std::invalid_argument +#include +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#include // std::forward +#endif + +#if __TBB_EXTRA_DEBUG +#define __TBBMALLOC_ASSERT ASSERT +#else +#define __TBBMALLOC_ASSERT(a,b) ((void)0) +#endif + +namespace tbb { +namespace interface6 { +//! @cond INTERNAL +namespace internal { + +//! Base of thread-safe pool allocator for variable-size requests +class pool_base : tbb::internal::no_copy { + // Pool interface is separate from standard allocator classes because it has + // to maintain internal state, no copy or assignment. Move and swap are possible. +public: + //! Reset pool to reuse its memory (free all objects at once) + void recycle() { rml::pool_reset(my_pool); } + + //! The "malloc" analogue to allocate block of memory of size bytes + void *malloc(size_t size) { return rml::pool_malloc(my_pool, size); } + + //! The "free" analogue to discard a previously allocated piece of memory. + void free(void* ptr) { rml::pool_free(my_pool, ptr); } + + //! The "realloc" analogue complementing pool_malloc. + // Enables some low-level optimization possibilities + void *realloc(void* ptr, size_t size) { + return rml::pool_realloc(my_pool, ptr, size); + } + +protected: + //! destroy pool - must be called in a child class + void destroy() { rml::pool_destroy(my_pool); } + + rml::MemoryPool *my_pool; +}; + +} // namespace internal +//! @endcond + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for erroneous "unreferenced parameter" warning in method destroy. + #pragma warning (push) + #pragma warning (disable: 4100) +#endif + +//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 +/** @ingroup memory_allocation */ +template +class memory_pool_allocator { +protected: + typedef P pool_type; + pool_type *my_pool; + template + friend class memory_pool_allocator; + template + friend bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b); + template + friend bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b); +public: + typedef typename tbb::internal::allocator_type::value_type value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template struct rebind { + typedef memory_pool_allocator other; + }; + + explicit memory_pool_allocator(pool_type &pool) throw() : my_pool(&pool) {} + memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} + template + memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} + + pointer address(reference x) const { return &x; } + const_pointer address(const_reference x) const { return &x; } + + //! Allocate space for n objects. + pointer allocate( size_type n, const void* /*hint*/ = 0) { + pointer p = static_cast( my_pool->malloc( n*sizeof(value_type) ) ); + if (!p) + tbb::internal::throw_exception(std::bad_alloc()); + return p; + } + //! Free previously allocated block of memory. + void deallocate( pointer p, size_type ) { + my_pool->free(p); + } + //! Largest value for which method allocate might succeed. + size_type max_size() const throw() { + size_type max = static_cast(-1) / sizeof (value_type); + return (max > 0 ? max : 1); + } + //! Copy-construct value at location pointed to by p. +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + template + void construct(U *p, Args&&... args) + { ::new((void *)p) U(std::forward(args)...); } +#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#if __TBB_CPP11_RVALUE_REF_PRESENT + void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));} +#endif + void construct( pointer p, const value_type& value ) { ::new((void*)(p)) value_type(value); } +#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + + //! Destroy value at location pointed to by p. + void destroy( pointer p ) { p->~value_type(); } + +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warning 4100 is back + +//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 +/** @ingroup memory_allocation */ +template +class memory_pool_allocator { +public: + typedef P pool_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + template struct rebind { + typedef memory_pool_allocator other; + }; + + explicit memory_pool_allocator( pool_type &pool) throw() : my_pool(&pool) {} + memory_pool_allocator( const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} + template + memory_pool_allocator(const memory_pool_allocator& src) throw() : my_pool(src.my_pool) {} + +protected: + pool_type *my_pool; + template + friend class memory_pool_allocator; + template + friend bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b); + template + friend bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b); +}; + +template +inline bool operator==( const memory_pool_allocator& a, const memory_pool_allocator& b) {return a.my_pool==b.my_pool;} + +template +inline bool operator!=( const memory_pool_allocator& a, const memory_pool_allocator& b) {return a.my_pool!=b.my_pool;} + + +//! Thread-safe growable pool allocator for variable-size requests +template +class memory_pool : public internal::pool_base { + Alloc my_alloc; // TODO: base-class optimization + static void *allocate_request(intptr_t pool_id, size_t & bytes); + static int deallocate_request(intptr_t pool_id, void*, size_t raw_bytes); + +public: + //! construct pool with underlying allocator + explicit memory_pool(const Alloc &src = Alloc()); + + //! destroy pool + ~memory_pool() { destroy(); } // call the callbacks first and destroy my_alloc latter + +}; + +class fixed_pool : public internal::pool_base { + void *my_buffer; + size_t my_size; + inline static void *allocate_request(intptr_t pool_id, size_t & bytes); + +public: + //! construct pool with underlying allocator + inline fixed_pool(void *buf, size_t size); + //! destroy pool + ~fixed_pool() { destroy(); } +}; + +//////////////// Implementation /////////////// + +template +memory_pool::memory_pool(const Alloc &src) : my_alloc(src) { + rml::MemPoolPolicy args(allocate_request, deallocate_request, + sizeof(typename Alloc::value_type)); + rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool); + if (res!=rml::POOL_OK) + tbb::internal::throw_exception(std::runtime_error("Can't create pool")); +} +template +void *memory_pool::allocate_request(intptr_t pool_id, size_t & bytes) { + memory_pool &self = *reinterpret_cast*>(pool_id); + const size_t unit_size = sizeof(typename Alloc::value_type); + __TBBMALLOC_ASSERT( 0 == bytes%unit_size, NULL); + void *ptr; + __TBB_TRY { ptr = self.my_alloc.allocate( bytes/unit_size ); } + __TBB_CATCH(...) { return 0; } + return ptr; +} +#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED + // Workaround for erroneous "unreachable code" warning in the template below. + // Specific for VC++ 17-18 compiler + #pragma warning (push) + #pragma warning (disable: 4702) +#endif +template +int memory_pool::deallocate_request(intptr_t pool_id, void* raw_ptr, size_t raw_bytes) { + memory_pool &self = *reinterpret_cast*>(pool_id); + const size_t unit_size = sizeof(typename Alloc::value_type); + __TBBMALLOC_ASSERT( 0 == raw_bytes%unit_size, NULL); + self.my_alloc.deallocate( static_cast(raw_ptr), raw_bytes/unit_size ); + return 0; +} +#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED + #pragma warning (pop) +#endif +inline fixed_pool::fixed_pool(void *buf, size_t size) : my_buffer(buf), my_size(size) { + if (!buf || !size) + // TODO: improve support for mode with exceptions disabled + tbb::internal::throw_exception(std::invalid_argument("Zero in parameter is invalid")); + rml::MemPoolPolicy args(allocate_request, 0, size, /*fixedPool=*/true); + rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool); + if (res!=rml::POOL_OK) + tbb::internal::throw_exception(std::runtime_error("Can't create pool")); +} +inline void *fixed_pool::allocate_request(intptr_t pool_id, size_t & bytes) { + fixed_pool &self = *reinterpret_cast(pool_id); + __TBBMALLOC_ASSERT(0 != self.my_size, "The buffer must not be used twice."); + bytes = self.my_size; + self.my_size = 0; // remember that buffer has been used + return self.my_buffer; +} + +} //namespace interface6 +using interface6::memory_pool_allocator; +using interface6::memory_pool; +using interface6::fixed_pool; +} //namespace tbb + +#undef __TBBMALLOC_ASSERT +#endif// __TBB_memory_pool_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/mutex.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/mutex.h new file mode 100644 index 00000000..94269f3d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/mutex.h @@ -0,0 +1,246 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_mutex_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_mutex_H +#pragma message("TBB Warning: tbb/mutex.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_mutex_H +#define __TBB_mutex_H + +#define __TBB_mutex_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#if _WIN32||_WIN64 +#include "machine/windows_api.h" +#else +#include +#endif /* _WIN32||_WIN64 */ + +#include +#include "aligned_space.h" +#include "tbb_stddef.h" +#include "tbb_profiling.h" + +namespace tbb { + +//! Wrapper around the platform's native lock. +/** @ingroup synchronization */ +class __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::critical_section is deprecated, use std::mutex") mutex : internal::mutex_copy_deprecated_and_disabled { +public: + //! Construct unacquired mutex. + mutex() { +#if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS + internal_construct(); +#else + #if _WIN32||_WIN64 + InitializeCriticalSectionEx(&impl, 4000, 0); + #else + int error_code = pthread_mutex_init(&impl,NULL); + if( error_code ) + tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed"); + #endif /* _WIN32||_WIN64*/ +#endif /* TBB_USE_ASSERT */ + }; + + ~mutex() { +#if TBB_USE_ASSERT + internal_destroy(); +#else + #if _WIN32||_WIN64 + DeleteCriticalSection(&impl); + #else + pthread_mutex_destroy(&impl); + + #endif /* _WIN32||_WIN64 */ +#endif /* TBB_USE_ASSERT */ + }; + + class scoped_lock; + friend class scoped_lock; + + //! The scoped locking pattern + /** It helps to avoid the common problem of forgetting to release lock. + It also nicely provides the "node" for queuing locks. */ + class scoped_lock : internal::no_copy { + public: + //! Construct lock that has not acquired a mutex. + scoped_lock() : my_mutex(NULL) {}; + + //! Acquire lock on given mutex. + scoped_lock( mutex& mutex ) { + acquire( mutex ); + } + + //! Release lock (if lock is held). + ~scoped_lock() { + if( my_mutex ) + release(); + } + + //! Acquire lock on given mutex. + void acquire( mutex& mutex ) { +#if TBB_USE_ASSERT + internal_acquire(mutex); +#else + mutex.lock(); + my_mutex = &mutex; +#endif /* TBB_USE_ASSERT */ + } + + //! Try acquire lock on given mutex. + bool try_acquire( mutex& mutex ) { +#if TBB_USE_ASSERT + return internal_try_acquire (mutex); +#else + bool result = mutex.try_lock(); + if( result ) + my_mutex = &mutex; + return result; +#endif /* TBB_USE_ASSERT */ + } + + //! Release lock + void release() { +#if TBB_USE_ASSERT + internal_release (); +#else + my_mutex->unlock(); + my_mutex = NULL; +#endif /* TBB_USE_ASSERT */ + } + + private: + //! The pointer to the current mutex to work + mutex* my_mutex; + + //! All checks from acquire using mutex.state were moved here + void __TBB_EXPORTED_METHOD internal_acquire( mutex& m ); + + //! All checks from try_acquire using mutex.state were moved here + bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m ); + + //! All checks from release using mutex.state were moved here + void __TBB_EXPORTED_METHOD internal_release(); + + friend class mutex; + }; + + // Mutex traits + static const bool is_rw_mutex = false; + static const bool is_recursive_mutex = false; + static const bool is_fair_mutex = false; + + // ISO C++0x compatibility methods + + //! Acquire lock + void lock() { +#if TBB_USE_ASSERT + aligned_space tmp; + new(tmp.begin()) scoped_lock(*this); +#else + #if _WIN32||_WIN64 + EnterCriticalSection(&impl); + #else + int error_code = pthread_mutex_lock(&impl); + if( error_code ) + tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_lock failed"); + #endif /* _WIN32||_WIN64 */ +#endif /* TBB_USE_ASSERT */ + } + + //! Try acquiring lock (non-blocking) + /** Return true if lock acquired; false otherwise. */ + bool try_lock() { +#if TBB_USE_ASSERT + aligned_space tmp; + scoped_lock& s = *tmp.begin(); + s.my_mutex = NULL; + return s.internal_try_acquire(*this); +#else + #if _WIN32||_WIN64 + return TryEnterCriticalSection(&impl)!=0; + #else + return pthread_mutex_trylock(&impl)==0; + #endif /* _WIN32||_WIN64 */ +#endif /* TBB_USE_ASSERT */ + } + + //! Release lock + void unlock() { +#if TBB_USE_ASSERT + aligned_space tmp; + scoped_lock& s = *tmp.begin(); + s.my_mutex = this; + s.internal_release(); +#else + #if _WIN32||_WIN64 + LeaveCriticalSection(&impl); + #else + pthread_mutex_unlock(&impl); + #endif /* _WIN32||_WIN64 */ +#endif /* TBB_USE_ASSERT */ + } + + //! Return native_handle + #if _WIN32||_WIN64 + typedef LPCRITICAL_SECTION native_handle_type; + #else + typedef pthread_mutex_t* native_handle_type; + #endif + native_handle_type native_handle() { return (native_handle_type) &impl; } + + enum state_t { + INITIALIZED=0x1234, + DESTROYED=0x789A, + HELD=0x56CD + }; +private: +#if _WIN32||_WIN64 + CRITICAL_SECTION impl; + enum state_t state; +#else + pthread_mutex_t impl; +#endif /* _WIN32||_WIN64 */ + + //! All checks from mutex constructor using mutex.state were moved here + void __TBB_EXPORTED_METHOD internal_construct(); + + //! All checks from mutex destructor using mutex.state were moved here + void __TBB_EXPORTED_METHOD internal_destroy(); + +#if _WIN32||_WIN64 +public: + //! Set the internal state + void set_state( state_t to ) { state = to; } +#endif +}; + +__TBB_DEFINE_PROFILING_SET_NAME(mutex) + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_mutex_H_include_area + +#endif /* __TBB_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/null_mutex.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/null_mutex.h new file mode 100644 index 00000000..3c7bad1a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/null_mutex.h @@ -0,0 +1,50 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_null_mutex_H +#define __TBB_null_mutex_H + +#include "tbb_stddef.h" + +namespace tbb { + +//! A mutex which does nothing +/** A null_mutex does no operation and simulates success. + @ingroup synchronization */ +class null_mutex : internal::mutex_copy_deprecated_and_disabled { +public: + //! Represents acquisition of a mutex. + class scoped_lock : internal::no_copy { + public: + scoped_lock() {} + scoped_lock( null_mutex& ) {} + ~scoped_lock() {} + void acquire( null_mutex& ) {} + bool try_acquire( null_mutex& ) { return true; } + void release() {} + }; + + null_mutex() {} + + // Mutex traits + static const bool is_rw_mutex = false; + static const bool is_recursive_mutex = true; + static const bool is_fair_mutex = true; +}; + +} + +#endif /* __TBB_null_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/null_rw_mutex.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/null_rw_mutex.h new file mode 100644 index 00000000..f1ea4df6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/null_rw_mutex.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_null_rw_mutex_H +#define __TBB_null_rw_mutex_H + +#include "tbb_stddef.h" + +namespace tbb { + +//! A rw mutex which does nothing +/** A null_rw_mutex is a rw mutex that does nothing and simulates successful operation. + @ingroup synchronization */ +class null_rw_mutex : internal::mutex_copy_deprecated_and_disabled { +public: + //! Represents acquisition of a mutex. + class scoped_lock : internal::no_copy { + public: + scoped_lock() {} + scoped_lock( null_rw_mutex& , bool = true ) {} + ~scoped_lock() {} + void acquire( null_rw_mutex& , bool = true ) {} + bool upgrade_to_writer() { return true; } + bool downgrade_to_reader() { return true; } + bool try_acquire( null_rw_mutex& , bool = true ) { return true; } + void release() {} + }; + + null_rw_mutex() {} + + // Mutex traits + static const bool is_rw_mutex = true; + static const bool is_recursive_mutex = true; + static const bool is_fair_mutex = true; +}; + +} + +#endif /* __TBB_null_rw_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_do.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_do.h new file mode 100644 index 00000000..1b63e279 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_do.h @@ -0,0 +1,553 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_parallel_do_H +#define __TBB_parallel_do_H + +#define __TBB_parallel_do_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "internal/_range_iterator.h" +#include "internal/_template_helpers.h" +#include "task.h" +#include "aligned_space.h" +#include + +namespace tbb { +namespace interface9 { +//! @cond INTERNAL +namespace internal { + template class parallel_do_feeder_impl; +} // namespace internal +//! @endcond + +//! Class the user supplied algorithm body uses to add new tasks +/** \param Item Work item type **/ + template + class parallel_do_feeder: ::tbb::internal::no_copy + { + parallel_do_feeder() {} + virtual ~parallel_do_feeder () {} + virtual void internal_add_copy( const Item& item ) = 0; +#if __TBB_CPP11_RVALUE_REF_PRESENT + virtual void internal_add_move( Item&& item ) = 0; +#endif + template friend class internal::parallel_do_feeder_impl; + public: + //! Add a work item to a running parallel_do. + void add( const Item& item ) {internal_add_copy(item);} +#if __TBB_CPP11_RVALUE_REF_PRESENT + void add( Item&& item ) {internal_add_move(std::move(item));} +#endif + }; + +//! @cond INTERNAL +namespace internal { + template class do_group_task; + + //! For internal use only. + /** Selects one of the two possible forms of function call member operator. + @ingroup algorithms **/ + template + class parallel_do_operator_selector + { + typedef parallel_do_feeder Feeder; + template + static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2&, void (Body::*)(CvItem) const ) { + obj(tbb::internal::forward(arg1)); + } + template + static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2& arg2, void (Body::*)(CvItem, parallel_do_feeder&) const ) { + obj(tbb::internal::forward(arg1), arg2); + } + template + static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2&, void (Body::*)(CvItem&) const ) { + obj(arg1); + } + template + static void internal_call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2& arg2, void (Body::*)(CvItem&, parallel_do_feeder&) const ) { + obj(arg1, arg2); + } + public: + template + static void call( const Body& obj, __TBB_FORWARDING_REF(A1) arg1, A2& arg2 ) + { + internal_call( obj, tbb::internal::forward(arg1), arg2, &Body::operator() ); + } + }; + + //! For internal use only. + /** Executes one iteration of a do. + @ingroup algorithms */ + template + class do_iteration_task: public task + { + typedef parallel_do_feeder_impl feeder_type; + + Item my_value; + feeder_type& my_feeder; + + do_iteration_task( const Item& value, feeder_type& feeder ) : + my_value(value), my_feeder(feeder) + {} + +#if __TBB_CPP11_RVALUE_REF_PRESENT + do_iteration_task( Item&& value, feeder_type& feeder ) : + my_value(std::move(value)), my_feeder(feeder) + {} +#endif + + task* execute() __TBB_override + { + parallel_do_operator_selector::call(*my_feeder.my_body, tbb::internal::move(my_value), my_feeder); + return NULL; + } + + template friend class parallel_do_feeder_impl; + }; // class do_iteration_task + + template + class do_iteration_task_iter: public task + { + typedef parallel_do_feeder_impl feeder_type; + + Iterator my_iter; + feeder_type& my_feeder; + + do_iteration_task_iter( const Iterator& iter, feeder_type& feeder ) : + my_iter(iter), my_feeder(feeder) + {} + + task* execute() __TBB_override + { + parallel_do_operator_selector::call(*my_feeder.my_body, *my_iter, my_feeder); + return NULL; + } + + template friend class do_group_task_forward; + template friend class do_group_task_input; + template friend class do_task_iter; + }; // class do_iteration_task_iter + + //! For internal use only. + /** Implements new task adding procedure. + @ingroup algorithms **/ + template + class parallel_do_feeder_impl : public parallel_do_feeder + { +#if __TBB_CPP11_RVALUE_REF_PRESENT + //Avoiding use of copy constructor in a virtual method if the type does not support it + void internal_add_copy_impl(std::true_type, const Item& item) { + typedef do_iteration_task iteration_type; + iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(item, *this); + task::spawn(t); + } + void internal_add_copy_impl(std::false_type, const Item&) { + __TBB_ASSERT(false, "Overloading for r-value reference doesn't work or it's not movable and not copyable object"); + } + void internal_add_copy( const Item& item ) __TBB_override + { +#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT + internal_add_copy_impl(typename std::is_copy_constructible::type(), item); +#else + internal_add_copy_impl(std::true_type(), item); +#endif + } + void internal_add_move( Item&& item ) __TBB_override + { + typedef do_iteration_task iteration_type; + iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(std::move(item), *this); + task::spawn(t); + } +#else /* ! __TBB_CPP11_RVALUE_REF_PRESENT */ + void internal_add_copy(const Item& item) __TBB_override { + typedef do_iteration_task iteration_type; + iteration_type& t = *new (task::allocate_additional_child_of(*my_barrier)) iteration_type(item, *this); + task::spawn(t); + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + public: + const Body* my_body; + empty_task* my_barrier; + + parallel_do_feeder_impl() + { + my_barrier = new( task::allocate_root() ) empty_task(); + __TBB_ASSERT(my_barrier, "root task allocation failed"); + } + +#if __TBB_TASK_GROUP_CONTEXT + parallel_do_feeder_impl(tbb::task_group_context &context) + { + my_barrier = new( task::allocate_root(context) ) empty_task(); + __TBB_ASSERT(my_barrier, "root task allocation failed"); + } +#endif + + ~parallel_do_feeder_impl() + { + my_barrier->destroy(*my_barrier); + } + }; // class parallel_do_feeder_impl + + + //! For internal use only + /** Unpacks a block of iterations. + @ingroup algorithms */ + + template + class do_group_task_forward: public task + { + static const size_t max_arg_size = 4; + + typedef parallel_do_feeder_impl feeder_type; + + feeder_type& my_feeder; + Iterator my_first; + size_t my_size; + + do_group_task_forward( Iterator first, size_t size, feeder_type& feeder ) + : my_feeder(feeder), my_first(first), my_size(size) + {} + + task* execute() __TBB_override + { + typedef do_iteration_task_iter iteration_type; + __TBB_ASSERT( my_size>0, NULL ); + task_list list; + task* t; + size_t k=0; + for(;;) { + t = new( allocate_child() ) iteration_type( my_first, my_feeder ); + ++my_first; + if( ++k==my_size ) break; + list.push_back(*t); + } + set_ref_count(int(k+1)); + spawn(list); + spawn_and_wait_for_all(*t); + return NULL; + } + + template friend class do_task_iter; + }; // class do_group_task_forward + + template + class do_group_task_input: public task + { + static const size_t max_arg_size = 4; + + typedef parallel_do_feeder_impl feeder_type; + + feeder_type& my_feeder; + size_t my_size; + aligned_space my_arg; + + do_group_task_input( feeder_type& feeder ) + : my_feeder(feeder), my_size(0) + {} + + task* execute() __TBB_override + { +#if __TBB_CPP11_RVALUE_REF_PRESENT + typedef std::move_iterator Item_iterator; +#else + typedef Item* Item_iterator; +#endif + typedef do_iteration_task_iter iteration_type; + __TBB_ASSERT( my_size>0, NULL ); + task_list list; + task* t; + size_t k=0; + for(;;) { + t = new( allocate_child() ) iteration_type( Item_iterator(my_arg.begin() + k), my_feeder ); + if( ++k==my_size ) break; + list.push_back(*t); + } + set_ref_count(int(k+1)); + spawn(list); + spawn_and_wait_for_all(*t); + return NULL; + } + + ~do_group_task_input(){ + for( size_t k=0; k~Item(); + } + + template friend class do_task_iter; + }; // class do_group_task_input + + //! For internal use only. + /** Gets block of iterations and packages them into a do_group_task. + @ingroup algorithms */ + template + class do_task_iter: public task + { + typedef parallel_do_feeder_impl feeder_type; + + public: + do_task_iter( Iterator first, Iterator last , feeder_type& feeder ) : + my_first(first), my_last(last), my_feeder(feeder) + {} + + private: + Iterator my_first; + Iterator my_last; + feeder_type& my_feeder; + + /* Do not merge run(xxx) and run_xxx() methods. They are separated in order + to make sure that compilers will eliminate unused argument of type xxx + (that is will not put it on stack). The sole purpose of this argument + is overload resolution. + + An alternative could be using template functions, but explicit specialization + of member function templates is not supported for non specialized class + templates. Besides template functions would always fall back to the least + efficient variant (the one for input iterators) in case of iterators having + custom tags derived from basic ones. */ + task* execute() __TBB_override + { + typedef typename std::iterator_traits::iterator_category iterator_tag; + return run( (iterator_tag*)NULL ); + } + + /** This is the most restricted variant that operates on input iterators or + iterators with unknown tags (tags not derived from the standard ones). **/ + inline task* run( void* ) { return run_for_input_iterator(); } + + task* run_for_input_iterator() { + typedef do_group_task_input block_type; + + block_type& t = *new( allocate_additional_child_of(*my_feeder.my_barrier) ) block_type(my_feeder); + size_t k=0; + while( !(my_first == my_last) ) { + // Move semantics are automatically used when supported by the iterator + new (t.my_arg.begin() + k) Item(*my_first); + ++my_first; + if( ++k==block_type::max_arg_size ) { + if ( !(my_first == my_last) ) + recycle_to_reexecute(); + break; + } + } + if( k==0 ) { + destroy(t); + return NULL; + } else { + t.my_size = k; + return &t; + } + } + + inline task* run( std::forward_iterator_tag* ) { return run_for_forward_iterator(); } + + task* run_for_forward_iterator() { + typedef do_group_task_forward block_type; + + Iterator first = my_first; + size_t k=0; + while( !(my_first==my_last) ) { + ++my_first; + if( ++k==block_type::max_arg_size ) { + if ( !(my_first==my_last) ) + recycle_to_reexecute(); + break; + } + } + return k==0 ? NULL : new( allocate_additional_child_of(*my_feeder.my_barrier) ) block_type(first, k, my_feeder); + } + + inline task* run( std::random_access_iterator_tag* ) { return run_for_random_access_iterator(); } + + task* run_for_random_access_iterator() { + typedef do_group_task_forward block_type; + typedef do_iteration_task_iter iteration_type; + + size_t k = static_cast(my_last-my_first); + if( k > block_type::max_arg_size ) { + Iterator middle = my_first + k/2; + + empty_task& c = *new( allocate_continuation() ) empty_task; + do_task_iter& b = *new( c.allocate_child() ) do_task_iter(middle, my_last, my_feeder); + recycle_as_child_of(c); + + my_last = middle; + c.set_ref_count(2); + c.spawn(b); + return this; + }else if( k != 0 ) { + task_list list; + task* t; + size_t k1=0; + for(;;) { + t = new( allocate_child() ) iteration_type(my_first, my_feeder); + ++my_first; + if( ++k1==k ) break; + list.push_back(*t); + } + set_ref_count(int(k+1)); + spawn(list); + spawn_and_wait_for_all(*t); + } + return NULL; + } + }; // class do_task_iter + + //! For internal use only. + /** Implements parallel iteration over a range. + @ingroup algorithms */ + template + void run_parallel_do( Iterator first, Iterator last, const Body& body +#if __TBB_TASK_GROUP_CONTEXT + , task_group_context& context +#endif + ) + { + typedef do_task_iter root_iteration_task; +#if __TBB_TASK_GROUP_CONTEXT + parallel_do_feeder_impl feeder(context); +#else + parallel_do_feeder_impl feeder; +#endif + feeder.my_body = &body; + + root_iteration_task &t = *new( feeder.my_barrier->allocate_child() ) root_iteration_task(first, last, feeder); + + feeder.my_barrier->set_ref_count(2); + feeder.my_barrier->spawn_and_wait_for_all(t); + } + + //! For internal use only. + /** Detects types of Body's operator function arguments. + @ingroup algorithms **/ + template + void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item) const +#if __TBB_TASK_GROUP_CONTEXT + , task_group_context& context +#endif + ) + { + run_parallel_do::type>( first, last, body +#if __TBB_TASK_GROUP_CONTEXT + , context +#endif + ); + } + + //! For internal use only. + /** Detects types of Body's operator function arguments. + @ingroup algorithms **/ + template + void select_parallel_do( Iterator first, Iterator last, const Body& body, void (Body::*)(Item, parallel_do_feeder<_Item>&) const +#if __TBB_TASK_GROUP_CONTEXT + , task_group_context& context +#endif + ) + { + run_parallel_do::type>( first, last, body +#if __TBB_TASK_GROUP_CONTEXT + , context +#endif + ); + } + +} // namespace internal +} // namespace interface9 +//! @endcond + +/** \page parallel_do_body_req Requirements on parallel_do body + Class \c Body implementing the concept of parallel_do body must define: + - \code + B::operator()( + cv_item_type item, + parallel_do_feeder& feeder + ) const + + OR + + B::operator()( cv_item_type& item ) const + \endcode Process item. + May be invoked concurrently for the same \c this but different \c item. + + - \code item_type( const item_type& ) \endcode + Copy a work item. + - \code ~item_type() \endcode Destroy a work item +**/ + +/** \name parallel_do + See also requirements on \ref parallel_do_body_req "parallel_do Body". **/ +//@{ +//! Parallel iteration over a range, with optional addition of more work. +/** @ingroup algorithms */ +template +void parallel_do( Iterator first, Iterator last, const Body& body ) +{ + if ( first == last ) + return; +#if __TBB_TASK_GROUP_CONTEXT + task_group_context context(internal::PARALLEL_DO); +#endif + interface9::internal::select_parallel_do( first, last, body, &Body::operator() +#if __TBB_TASK_GROUP_CONTEXT + , context +#endif + ); +} + +template +void parallel_do(Range& rng, const Body& body) { + parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body); +} + +template +void parallel_do(const Range& rng, const Body& body) { + parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body); +} + +#if __TBB_TASK_GROUP_CONTEXT +//! Parallel iteration over a range, with optional addition of more work and user-supplied context +/** @ingroup algorithms */ +template +void parallel_do( Iterator first, Iterator last, const Body& body, task_group_context& context ) +{ + if ( first == last ) + return; + interface9::internal::select_parallel_do( first, last, body, &Body::operator(), context ); +} + +template +void parallel_do(Range& rng, const Body& body, task_group_context& context) { + parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body, context); +} + +template +void parallel_do(const Range& rng, const Body& body, task_group_context& context) { + parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body, context); +} + +#endif // __TBB_TASK_GROUP_CONTEXT + +//@} + +using interface9::parallel_do_feeder; + +} // namespace + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_parallel_do_H_include_area + +#endif /* __TBB_parallel_do_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_for.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_for.h new file mode 100644 index 00000000..0b4861f4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_for.h @@ -0,0 +1,425 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_parallel_for_H +#define __TBB_parallel_for_H + +#define __TBB_parallel_for_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include +#include "task.h" +#include "partitioner.h" +#include "blocked_range.h" +#include "tbb_exception.h" +#include "internal/_tbb_trace_impl.h" + +namespace tbb { + +namespace interface9 { +//! @cond INTERNAL +namespace internal { + + //! allocate right task with new parent + void* allocate_sibling(task* start_for_task, size_t bytes); + + //! Task type used in parallel_for + /** @ingroup algorithms */ + template + class start_for: public task { + Range my_range; + const Body my_body; + typename Partitioner::task_partition_type my_partition; + task* execute() __TBB_override; + + //! Update affinity info, if any. + void note_affinity( affinity_id id ) __TBB_override { + my_partition.note_affinity( id ); + } + + public: + //! Constructor for root task. + start_for( const Range& range, const Body& body, Partitioner& partitioner ) : + my_range(range), + my_body(body), + my_partition(partitioner) + { + tbb::internal::fgt_algorithm(tbb::internal::PARALLEL_FOR_TASK, this, NULL); + } + //! Splitting constructor used to generate children. + /** parent_ becomes left child. Newly constructed object is right child. */ + start_for( start_for& parent_, typename Partitioner::split_type& split_obj) : + my_range(parent_.my_range, split_obj), + my_body(parent_.my_body), + my_partition(parent_.my_partition, split_obj) + { + my_partition.set_affinity(*this); + tbb::internal::fgt_algorithm(tbb::internal::PARALLEL_FOR_TASK, this, (void *)&parent_); + } + //! Construct right child from the given range as response to the demand. + /** parent_ remains left child. Newly constructed object is right child. */ + start_for( start_for& parent_, const Range& r, depth_t d ) : + my_range(r), + my_body(parent_.my_body), + my_partition(parent_.my_partition, split()) + { + my_partition.set_affinity(*this); + my_partition.align_depth( d ); + tbb::internal::fgt_algorithm(tbb::internal::PARALLEL_FOR_TASK, this, (void *)&parent_); + } + static void run( const Range& range, const Body& body, Partitioner& partitioner ) { + if( !range.empty() ) { +#if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP + start_for& a = *new(task::allocate_root()) start_for(range,body,partitioner); +#else + // Bound context prevents exceptions from body to affect nesting or sibling algorithms, + // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. + task_group_context context(PARALLEL_FOR); + start_for& a = *new(task::allocate_root(context)) start_for(range,body,partitioner); +#endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ + // REGION BEGIN + fgt_begin_algorithm( tbb::internal::PARALLEL_FOR_TASK, (void*)&context ); + task::spawn_root_and_wait(a); + fgt_end_algorithm( (void*)&context ); + // REGION END + } + } +#if __TBB_TASK_GROUP_CONTEXT + static void run( const Range& range, const Body& body, Partitioner& partitioner, task_group_context& context ) { + if( !range.empty() ) { + start_for& a = *new(task::allocate_root(context)) start_for(range,body,partitioner); + // REGION BEGIN + fgt_begin_algorithm( tbb::internal::PARALLEL_FOR_TASK, (void*)&context ); + task::spawn_root_and_wait(a); + fgt_end_algorithm( (void*)&context ); + // END REGION + } + } +#endif /* __TBB_TASK_GROUP_CONTEXT */ + //! Run body for range, serves as callback for partitioner + void run_body( Range &r ) { + fgt_alg_begin_body( tbb::internal::PARALLEL_FOR_TASK, (void *)const_cast(&(this->my_body)), (void*)this ); + my_body( r ); + fgt_alg_end_body( (void *)const_cast(&(this->my_body)) ); + } + + //! spawn right task, serves as callback for partitioner + void offer_work(typename Partitioner::split_type& split_obj) { + spawn( *new( allocate_sibling(static_cast(this), sizeof(start_for)) ) start_for(*this, split_obj) ); + } + //! spawn right task, serves as callback for partitioner + void offer_work(const Range& r, depth_t d = 0) { + spawn( *new( allocate_sibling(static_cast(this), sizeof(start_for)) ) start_for(*this, r, d) ); + } + }; + + //! allocate right task with new parent + // TODO: 'inline' here is to avoid multiple definition error but for sake of code size this should not be inlined + inline void* allocate_sibling(task* start_for_task, size_t bytes) { + task* parent_ptr = new( start_for_task->allocate_continuation() ) flag_task(); + start_for_task->set_parent(parent_ptr); + parent_ptr->set_ref_count(2); + return &parent_ptr->allocate_child().allocate(bytes); + } + + //! execute task for parallel_for + template + task* start_for::execute() { + my_partition.check_being_stolen( *this ); + my_partition.execute(*this, my_range); + return NULL; + } +} // namespace internal +//! @endcond +} // namespace interfaceX + +//! @cond INTERNAL +namespace internal { + using interface9::internal::start_for; + + //! Calls the function with values from range [begin, end) with a step provided + template + class parallel_for_body : internal::no_assign { + const Function &my_func; + const Index my_begin; + const Index my_step; + public: + parallel_for_body( const Function& _func, Index& _begin, Index& _step ) + : my_func(_func), my_begin(_begin), my_step(_step) {} + + void operator()( const tbb::blocked_range& r ) const { + // A set of local variables to help the compiler with vectorization of the following loop. + Index b = r.begin(); + Index e = r.end(); + Index ms = my_step; + Index k = my_begin + b*ms; + +#if __INTEL_COMPILER +#pragma ivdep +#if __TBB_ASSERT_ON_VECTORIZATION_FAILURE +#pragma vector always assert +#endif +#endif + for ( Index i = b; i < e; ++i, k += ms ) { + my_func( k ); + } + } + }; +} // namespace internal +//! @endcond + +// Requirements on Range concept are documented in blocked_range.h + +/** \page parallel_for_body_req Requirements on parallel_for body + Class \c Body implementing the concept of parallel_for body must define: + - \code Body::Body( const Body& ); \endcode Copy constructor + - \code Body::~Body(); \endcode Destructor + - \code void Body::operator()( Range& r ) const; \endcode Function call operator applying the body to range \c r. +**/ + +/** \name parallel_for + See also requirements on \ref range_req "Range" and \ref parallel_for_body_req "parallel_for Body". **/ +//@{ + +//! Parallel iteration over range with default partitioner. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body ) { + internal::start_for::run(range,body,__TBB_DEFAULT_PARTITIONER()); +} + +//! Parallel iteration over range with simple partitioner. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) { + internal::start_for::run(range,body,partitioner); +} + +//! Parallel iteration over range with auto_partitioner. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) { + internal::start_for::run(range,body,partitioner); +} + +//! Parallel iteration over range with static_partitioner. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) { + internal::start_for::run(range,body,partitioner); +} + +//! Parallel iteration over range with affinity_partitioner. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner ) { + internal::start_for::run(range,body,partitioner); +} + +#if __TBB_TASK_GROUP_CONTEXT +//! Parallel iteration over range with default partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, task_group_context& context ) { + internal::start_for::run(range, body, __TBB_DEFAULT_PARTITIONER(), context); +} + +//! Parallel iteration over range with simple partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner, task_group_context& context ) { + internal::start_for::run(range, body, partitioner, context); +} + +//! Parallel iteration over range with auto_partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner, task_group_context& context ) { + internal::start_for::run(range, body, partitioner, context); +} + +//! Parallel iteration over range with static_partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner, task_group_context& context ) { + internal::start_for::run(range, body, partitioner, context); +} + +//! Parallel iteration over range with affinity_partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner, task_group_context& context ) { + internal::start_for::run(range,body,partitioner, context); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ +//@} + +namespace strict_ppl { + +//@{ +//! Implementation of parallel iteration over stepped range of integers with explicit step and partitioner +template +void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& partitioner) { + if (step <= 0 ) + internal::throw_exception(internal::eid_nonpositive_step); // throws std::invalid_argument + else if (last > first) { + // Above "else" avoids "potential divide by zero" warning on some platforms + Index end = (last - first - Index(1)) / step + Index(1); + tbb::blocked_range range(static_cast(0), end); + internal::parallel_for_body body(f, first, step); + tbb::parallel_for(range, body, partitioner); + } +} + +//! Parallel iteration over a range of integers with a step provided and default partitioner +template +void parallel_for(Index first, Index last, Index step, const Function& f) { + parallel_for_impl(first, last, step, f, auto_partitioner()); +} +//! Parallel iteration over a range of integers with a step provided and simple partitioner +template +void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner) { + parallel_for_impl(first, last, step, f, partitioner); +} +//! Parallel iteration over a range of integers with a step provided and auto partitioner +template +void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner) { + parallel_for_impl(first, last, step, f, partitioner); +} +//! Parallel iteration over a range of integers with a step provided and static partitioner +template +void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& partitioner) { + parallel_for_impl(first, last, step, f, partitioner); +} +//! Parallel iteration over a range of integers with a step provided and affinity partitioner +template +void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner) { + parallel_for_impl(first, last, step, f, partitioner); +} + +//! Parallel iteration over a range of integers with a default step value and default partitioner +template +void parallel_for(Index first, Index last, const Function& f) { + parallel_for_impl(first, last, static_cast(1), f, auto_partitioner()); +} +//! Parallel iteration over a range of integers with a default step value and simple partitioner +template +void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& partitioner) { + parallel_for_impl(first, last, static_cast(1), f, partitioner); +} +//! Parallel iteration over a range of integers with a default step value and auto partitioner +template +void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner) { + parallel_for_impl(first, last, static_cast(1), f, partitioner); +} +//! Parallel iteration over a range of integers with a default step value and static partitioner +template +void parallel_for(Index first, Index last, const Function& f, const static_partitioner& partitioner) { + parallel_for_impl(first, last, static_cast(1), f, partitioner); +} +//! Parallel iteration over a range of integers with a default step value and affinity partitioner +template +void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner) { + parallel_for_impl(first, last, static_cast(1), f, partitioner); +} + +#if __TBB_TASK_GROUP_CONTEXT +//! Implementation of parallel iteration over stepped range of integers with explicit step, task group context, and partitioner +template +void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& partitioner, tbb::task_group_context &context) { + if (step <= 0 ) + internal::throw_exception(internal::eid_nonpositive_step); // throws std::invalid_argument + else if (last > first) { + // Above "else" avoids "potential divide by zero" warning on some platforms + Index end = (last - first - Index(1)) / step + Index(1); + tbb::blocked_range range(static_cast(0), end); + internal::parallel_for_body body(f, first, step); + tbb::parallel_for(range, body, partitioner, context); + } +} + +//! Parallel iteration over a range of integers with explicit step, task group context, and default partitioner +template +void parallel_for(Index first, Index last, Index step, const Function& f, tbb::task_group_context &context) { + parallel_for_impl(first, last, step, f, auto_partitioner(), context); +} +//! Parallel iteration over a range of integers with explicit step, task group context, and simple partitioner + template +void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner, tbb::task_group_context &context) { + parallel_for_impl(first, last, step, f, partitioner, context); +} +//! Parallel iteration over a range of integers with explicit step, task group context, and auto partitioner + template +void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) { + parallel_for_impl(first, last, step, f, partitioner, context); +} +//! Parallel iteration over a range of integers with explicit step, task group context, and static partitioner +template +void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& partitioner, tbb::task_group_context &context) { + parallel_for_impl(first, last, step, f, partitioner, context); +} +//! Parallel iteration over a range of integers with explicit step, task group context, and affinity partitioner + template +void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) { + parallel_for_impl(first, last, step, f, partitioner, context); +} + + +//! Parallel iteration over a range of integers with a default step value, explicit task group context, and default partitioner +template +void parallel_for(Index first, Index last, const Function& f, tbb::task_group_context &context) { + parallel_for_impl(first, last, static_cast(1), f, auto_partitioner(), context); +} +//! Parallel iteration over a range of integers with a default step value, explicit task group context, and simple partitioner + template +void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& partitioner, tbb::task_group_context &context) { + parallel_for_impl(first, last, static_cast(1), f, partitioner, context); +} +//! Parallel iteration over a range of integers with a default step value, explicit task group context, and auto partitioner + template +void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) { + parallel_for_impl(first, last, static_cast(1), f, partitioner, context); +} +//! Parallel iteration over a range of integers with a default step value, explicit task group context, and static partitioner +template +void parallel_for(Index first, Index last, const Function& f, const static_partitioner& partitioner, tbb::task_group_context &context) { + parallel_for_impl(first, last, static_cast(1), f, partitioner, context); +} +//! Parallel iteration over a range of integers with a default step value, explicit task group context, and affinity_partitioner + template +void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) { + parallel_for_impl(first, last, static_cast(1), f, partitioner, context); +} + +#endif /* __TBB_TASK_GROUP_CONTEXT */ +//@} + +} // namespace strict_ppl + +using strict_ppl::parallel_for; + +} // namespace tbb + +#if TBB_PREVIEW_SERIAL_SUBSET +#define __TBB_NORMAL_EXECUTION +#include "../serial/tbb/parallel_for.h" +#undef __TBB_NORMAL_EXECUTION +#endif + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_parallel_for_H_include_area + +#endif /* __TBB_parallel_for_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_for_each.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_for_each.h new file mode 100644 index 00000000..e1da1bbd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_for_each.h @@ -0,0 +1,133 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_parallel_for_each_H +#define __TBB_parallel_for_each_H + +#include "parallel_do.h" +#include "parallel_for.h" + +namespace tbb { + +//! @cond INTERNAL +namespace internal { + // The class calls user function in operator() + template + class parallel_for_each_body_do : internal::no_assign { + const Function &my_func; + public: + parallel_for_each_body_do(const Function &_func) : my_func(_func) {} + + void operator()(typename std::iterator_traits::reference value) const { + my_func(value); + } + }; + + // The class calls user function in operator() + template + class parallel_for_each_body_for : internal::no_assign { + const Function &my_func; + public: + parallel_for_each_body_for(const Function &_func) : my_func(_func) {} + + void operator()(tbb::blocked_range range) const { +#if __INTEL_COMPILER +#pragma ivdep +#endif + for(Iterator it = range.begin(), end = range.end(); it != end; ++it) { + my_func(*it); + } + } + }; + + template + struct parallel_for_each_impl { +#if __TBB_TASK_GROUP_CONTEXT + static void doit(Iterator first, Iterator last, const Function& f, task_group_context &context) { + internal::parallel_for_each_body_do body(f); + tbb::parallel_do(first, last, body, context); + } +#endif + static void doit(Iterator first, Iterator last, const Function& f) { + internal::parallel_for_each_body_do body(f); + tbb::parallel_do(first, last, body); + } + }; + template + struct parallel_for_each_impl { +#if __TBB_TASK_GROUP_CONTEXT + static void doit(Iterator first, Iterator last, const Function& f, task_group_context &context) { + internal::parallel_for_each_body_for body(f); + tbb::parallel_for(tbb::blocked_range(first, last), body, context); + } +#endif + static void doit(Iterator first, Iterator last, const Function& f) { + internal::parallel_for_each_body_for body(f); + tbb::parallel_for(tbb::blocked_range(first, last), body); + } + }; +} // namespace internal +//! @endcond + +/** \name parallel_for_each + **/ +//@{ +//! Calls function f for all items from [first, last) interval using user-supplied context +/** @ingroup algorithms */ +#if __TBB_TASK_GROUP_CONTEXT +template +void parallel_for_each(Iterator first, Iterator last, const Function& f, task_group_context &context) { + internal::parallel_for_each_impl::iterator_category>::doit(first, last, f, context); +} + +//! Calls function f for all items from rng using user-supplied context +/** @ingroup algorithms */ +template +void parallel_for_each(Range& rng, const Function& f, task_group_context& context) { + parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context); +} + +//! Calls function f for all items from const rng user-supplied context +/** @ingroup algorithms */ +template +void parallel_for_each(const Range& rng, const Function& f, task_group_context& context) { + parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +//! Uses default context +template +void parallel_for_each(Iterator first, Iterator last, const Function& f) { + internal::parallel_for_each_impl::iterator_category>::doit(first, last, f); +} + +//! Uses default context +template +void parallel_for_each(Range& rng, const Function& f) { + parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f); +} + +//! Uses default context +template +void parallel_for_each(const Range& rng, const Function& f) { + parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f); +} + +//@} + +} // namespace + +#endif /* __TBB_parallel_for_each_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_invoke.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_invoke.h new file mode 100644 index 00000000..4be4bdb7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_invoke.h @@ -0,0 +1,460 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_parallel_invoke_H +#define __TBB_parallel_invoke_H + +#define __TBB_parallel_invoke_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "task.h" +#include "tbb_profiling.h" + +#if __TBB_VARIADIC_PARALLEL_INVOKE + #include // std::forward +#endif + +namespace tbb { + +#if !__TBB_TASK_GROUP_CONTEXT + /** Dummy to avoid cluttering the bulk of the header with enormous amount of ifdefs. **/ + struct task_group_context { + task_group_context(tbb::internal::string_index){} + }; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +//! @cond INTERNAL +namespace internal { + // Simple task object, executing user method + template + class function_invoker : public task{ + public: + function_invoker(const function& _function) : my_function(_function) {} + private: + const function &my_function; + task* execute() __TBB_override + { + my_function(); + return NULL; + } + }; + + // The class spawns two or three child tasks + template + class spawner : public task { + private: + const function1& my_func1; + const function2& my_func2; + const function3& my_func3; + bool is_recycled; + + task* execute () __TBB_override { + if(is_recycled){ + return NULL; + }else{ + __TBB_ASSERT(N==2 || N==3, "Number of arguments passed to spawner is wrong"); + set_ref_count(N); + recycle_as_safe_continuation(); + internal::function_invoker* invoker2 = new (allocate_child()) internal::function_invoker(my_func2); + __TBB_ASSERT(invoker2, "Child task allocation failed"); + spawn(*invoker2); + size_t n = N; // To prevent compiler warnings + if (n>2) { + internal::function_invoker* invoker3 = new (allocate_child()) internal::function_invoker(my_func3); + __TBB_ASSERT(invoker3, "Child task allocation failed"); + spawn(*invoker3); + } + my_func1(); + is_recycled = true; + return NULL; + } + } // execute + + public: + spawner(const function1& _func1, const function2& _func2, const function3& _func3) : my_func1(_func1), my_func2(_func2), my_func3(_func3), is_recycled(false) {} + }; + + // Creates and spawns child tasks + class parallel_invoke_helper : public empty_task { + public: + // Dummy functor class + class parallel_invoke_noop { + public: + void operator() () const {} + }; + // Creates a helper object with user-defined number of children expected + parallel_invoke_helper(int number_of_children) + { + set_ref_count(number_of_children + 1); + } + +#if __TBB_VARIADIC_PARALLEL_INVOKE + void add_children() {} + void add_children(tbb::task_group_context&) {} + + template + void add_children(function&& _func) + { + internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(std::forward(_func)); + __TBB_ASSERT(invoker, "Child task allocation failed"); + spawn(*invoker); + } + + template + void add_children(function&& _func, tbb::task_group_context&) + { + add_children(std::forward(_func)); + } + + // Adds child(ren) task(s) and spawns them + template + void add_children(function1&& _func1, function2&& _func2, function&&... _func) + { + // The third argument is dummy, it is ignored actually. + parallel_invoke_noop noop; + typedef internal::spawner<2, function1, function2, parallel_invoke_noop> spawner_type; + spawner_type & sub_root = *new(allocate_child()) spawner_type(std::forward(_func1), std::forward(_func2), noop); + spawn(sub_root); + add_children(std::forward(_func)...); + } +#else + // Adds child task and spawns it + template + void add_children (const function &_func) + { + internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(_func); + __TBB_ASSERT(invoker, "Child task allocation failed"); + spawn(*invoker); + } + + // Adds a task with multiple child tasks and spawns it + // two arguments + template + void add_children (const function1& _func1, const function2& _func2) + { + // The third argument is dummy, it is ignored actually. + parallel_invoke_noop noop; + internal::spawner<2, function1, function2, parallel_invoke_noop>& sub_root = *new(allocate_child())internal::spawner<2, function1, function2, parallel_invoke_noop>(_func1, _func2, noop); + spawn(sub_root); + } + // three arguments + template + void add_children (const function1& _func1, const function2& _func2, const function3& _func3) + { + internal::spawner<3, function1, function2, function3>& sub_root = *new(allocate_child())internal::spawner<3, function1, function2, function3>(_func1, _func2, _func3); + spawn(sub_root); + } +#endif // __TBB_VARIADIC_PARALLEL_INVOKE + + // Waits for all child tasks + template + void run_and_finish(const F0& f0) + { + internal::function_invoker* invoker = new (allocate_child()) internal::function_invoker(f0); + __TBB_ASSERT(invoker, "Child task allocation failed"); + spawn_and_wait_for_all(*invoker); + } + }; + // The class destroys root if exception occurred as well as in normal case + class parallel_invoke_cleaner: internal::no_copy { + public: +#if __TBB_TASK_GROUP_CONTEXT + parallel_invoke_cleaner(int number_of_children, tbb::task_group_context& context) + : root(*new(task::allocate_root(context)) internal::parallel_invoke_helper(number_of_children)) +#else + parallel_invoke_cleaner(int number_of_children, tbb::task_group_context&) + : root(*new(task::allocate_root()) internal::parallel_invoke_helper(number_of_children)) +#endif /* !__TBB_TASK_GROUP_CONTEXT */ + {} + + ~parallel_invoke_cleaner(){ + root.destroy(root); + } + internal::parallel_invoke_helper& root; + }; + +#if __TBB_VARIADIC_PARALLEL_INVOKE +// Determine whether the last parameter in a pack is task_group_context + template struct impl_selector; // to workaround a GCC bug + + template struct impl_selector { + typedef typename impl_selector::type type; + }; + + template struct impl_selector { + typedef false_type type; + }; + template<> struct impl_selector { + typedef true_type type; + }; + + // Select task_group_context parameter from the back of a pack + inline task_group_context& get_context( task_group_context& tgc ) { return tgc; } + + template + task_group_context& get_context( T1&& /*ignored*/, T&&... t ) + { return get_context( std::forward(t)... ); } + + // task_group_context is known to be at the back of the parameter pack + template + void parallel_invoke_impl(true_type, F0&& f0, F1&& f1, F&&... f) { + __TBB_STATIC_ASSERT(sizeof...(F)>0, "Variadic parallel_invoke implementation broken?"); + // # of child tasks: f0, f1, and a task for each two elements of the pack except the last + const size_t number_of_children = 2 + sizeof...(F)/2; + parallel_invoke_cleaner cleaner(number_of_children, get_context(std::forward(f)...)); + parallel_invoke_helper& root = cleaner.root; + + root.add_children(std::forward(f)...); + root.add_children(std::forward(f1)); + root.run_and_finish(std::forward(f0)); + } + + // task_group_context is not in the pack, needs to be added + template + void parallel_invoke_impl(false_type, F0&& f0, F1&& f1, F&&... f) { + tbb::task_group_context context(PARALLEL_INVOKE); + // Add context to the arguments, and redirect to the other overload + parallel_invoke_impl(true_type(), std::forward(f0), std::forward(f1), std::forward(f)..., context); + } +#endif +} // namespace internal +//! @endcond + +/** \name parallel_invoke + **/ +//@{ +//! Executes a list of tasks in parallel and waits for all tasks to complete. +/** @ingroup algorithms */ + +#if __TBB_VARIADIC_PARALLEL_INVOKE + +// parallel_invoke for two or more arguments via variadic templates +// presence of task_group_context is defined automatically +template +void parallel_invoke(F0&& f0, F1&& f1, F&&... f) { + typedef typename internal::impl_selector::type selector_type; + internal::parallel_invoke_impl(selector_type(), std::forward(f0), std::forward(f1), std::forward(f)...); +} + +#else + +// parallel_invoke with user-defined context +// two arguments +template +void parallel_invoke(const F0& f0, const F1& f1, tbb::task_group_context& context) { + internal::parallel_invoke_cleaner cleaner(2, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f1); + + root.run_and_finish(f0); +} + +// three arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, tbb::task_group_context& context) { + internal::parallel_invoke_cleaner cleaner(3, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f2); + root.add_children(f1); + + root.run_and_finish(f0); +} + +// four arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, + tbb::task_group_context& context) +{ + internal::parallel_invoke_cleaner cleaner(4, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f3); + root.add_children(f2); + root.add_children(f1); + + root.run_and_finish(f0); +} + +// five arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + tbb::task_group_context& context) +{ + internal::parallel_invoke_cleaner cleaner(3, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f4, f3); + root.add_children(f2, f1); + + root.run_and_finish(f0); +} + +// six arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5, + tbb::task_group_context& context) +{ + internal::parallel_invoke_cleaner cleaner(3, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f5, f4, f3); + root.add_children(f2, f1); + + root.run_and_finish(f0); +} + +// seven arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + const F5& f5, const F6& f6, + tbb::task_group_context& context) +{ + internal::parallel_invoke_cleaner cleaner(3, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f6, f5, f4); + root.add_children(f3, f2, f1); + + root.run_and_finish(f0); +} + +// eight arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + const F5& f5, const F6& f6, const F7& f7, + tbb::task_group_context& context) +{ + internal::parallel_invoke_cleaner cleaner(4, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f7, f6, f5); + root.add_children(f4, f3); + root.add_children(f2, f1); + + root.run_and_finish(f0); +} + +// nine arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + const F5& f5, const F6& f6, const F7& f7, const F8& f8, + tbb::task_group_context& context) +{ + internal::parallel_invoke_cleaner cleaner(4, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f8, f7, f6); + root.add_children(f5, f4, f3); + root.add_children(f2, f1); + + root.run_and_finish(f0); +} + +// ten arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + const F5& f5, const F6& f6, const F7& f7, const F8& f8, const F9& f9, + tbb::task_group_context& context) +{ + internal::parallel_invoke_cleaner cleaner(4, context); + internal::parallel_invoke_helper& root = cleaner.root; + + root.add_children(f9, f8, f7); + root.add_children(f6, f5, f4); + root.add_children(f3, f2, f1); + + root.run_and_finish(f0); +} + +// two arguments +template +void parallel_invoke(const F0& f0, const F1& f1) { + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, context); +} +// three arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2) { + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, f2, context); +} +// four arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3) { + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, f2, f3, context); +} +// five arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4) { + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, f2, f3, f4, context); +} +// six arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, const F5& f5) { + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, f2, f3, f4, f5, context); +} +// seven arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + const F5& f5, const F6& f6) +{ + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, f2, f3, f4, f5, f6, context); +} +// eight arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + const F5& f5, const F6& f6, const F7& f7) +{ + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, context); +} +// nine arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + const F5& f5, const F6& f6, const F7& f7, const F8& f8) +{ + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, f8, context); +} +// ten arguments +template +void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4, + const F5& f5, const F6& f6, const F7& f7, const F8& f8, const F9& f9) +{ + task_group_context context(internal::PARALLEL_INVOKE); + parallel_invoke(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, context); +} +#endif // __TBB_VARIADIC_PARALLEL_INVOKE +//@} + +} // namespace + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_parallel_invoke_H_include_area + +#endif /* __TBB_parallel_invoke_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_reduce.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_reduce.h new file mode 100644 index 00000000..da2e2f8d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_reduce.h @@ -0,0 +1,657 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_parallel_reduce_H +#define __TBB_parallel_reduce_H + +#define __TBB_parallel_reduce_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include +#include "task.h" +#include "aligned_space.h" +#include "partitioner.h" +#include "tbb_profiling.h" + +namespace tbb { + +namespace interface9 { +//! @cond INTERNAL +namespace internal { + + using namespace tbb::internal; + + /** Values for reduction_context. */ + enum { + root_task, left_child, right_child + }; + + /** Represented as a char, not enum, for compactness. */ + typedef char reduction_context; + + //! Task type used to combine the partial results of parallel_reduce. + /** @ingroup algorithms */ + template + class finish_reduce: public flag_task { + //! Pointer to body, or NULL if the left child has not yet finished. + bool has_right_zombie; + const reduction_context my_context; + Body* my_body; + aligned_space zombie_space; + finish_reduce( reduction_context context_ ) : + has_right_zombie(false), // TODO: substitute by flag_task::child_stolen? + my_context(context_), + my_body(NULL) + { + } + ~finish_reduce() { + if( has_right_zombie ) + zombie_space.begin()->~Body(); + } + task* execute() __TBB_override { + if( has_right_zombie ) { + // Right child was stolen. + Body* s = zombie_space.begin(); + my_body->join( *s ); + // Body::join() won't be called if canceled. Defer destruction to destructor + } + if( my_context==left_child ) + itt_store_word_with_release( static_cast(parent())->my_body, my_body ); + return NULL; + } + template + friend class start_reduce; + }; + + //! allocate right task with new parent + void allocate_sibling(task* start_reduce_task, task *tasks[], size_t start_bytes, size_t finish_bytes); + + //! Task type used to split the work of parallel_reduce. + /** @ingroup algorithms */ + template + class start_reduce: public task { + typedef finish_reduce finish_type; + Body* my_body; + Range my_range; + typename Partitioner::task_partition_type my_partition; + reduction_context my_context; + task* execute() __TBB_override; + //! Update affinity info, if any + void note_affinity( affinity_id id ) __TBB_override { + my_partition.note_affinity( id ); + } + template + friend class finish_reduce; + +public: + //! Constructor used for root task + start_reduce( const Range& range, Body* body, Partitioner& partitioner ) : + my_body(body), + my_range(range), + my_partition(partitioner), + my_context(root_task) + { + } + //! Splitting constructor used to generate children. + /** parent_ becomes left child. Newly constructed object is right child. */ + start_reduce( start_reduce& parent_, typename Partitioner::split_type& split_obj ) : + my_body(parent_.my_body), + my_range(parent_.my_range, split_obj), + my_partition(parent_.my_partition, split_obj), + my_context(right_child) + { + my_partition.set_affinity(*this); + parent_.my_context = left_child; + } + //! Construct right child from the given range as response to the demand. + /** parent_ remains left child. Newly constructed object is right child. */ + start_reduce( start_reduce& parent_, const Range& r, depth_t d ) : + my_body(parent_.my_body), + my_range(r), + my_partition(parent_.my_partition, split()), + my_context(right_child) + { + my_partition.set_affinity(*this); + my_partition.align_depth( d ); // TODO: move into constructor of partitioner + parent_.my_context = left_child; + } + static void run( const Range& range, Body& body, Partitioner& partitioner ) { + if( !range.empty() ) { +#if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP + task::spawn_root_and_wait( *new(task::allocate_root()) start_reduce(range,&body,partitioner) ); +#else + // Bound context prevents exceptions from body to affect nesting or sibling algorithms, + // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. + task_group_context context(PARALLEL_REDUCE); + task::spawn_root_and_wait( *new(task::allocate_root(context)) start_reduce(range,&body,partitioner) ); +#endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ + } + } +#if __TBB_TASK_GROUP_CONTEXT + static void run( const Range& range, Body& body, Partitioner& partitioner, task_group_context& context ) { + if( !range.empty() ) + task::spawn_root_and_wait( *new(task::allocate_root(context)) start_reduce(range,&body,partitioner) ); + } +#endif /* __TBB_TASK_GROUP_CONTEXT */ + //! Run body for range + void run_body( Range &r ) { (*my_body)( r ); } + + //! spawn right task, serves as callback for partitioner + // TODO: remove code duplication from 'offer_work' methods + void offer_work(typename Partitioner::split_type& split_obj) { + task *tasks[2]; + allocate_sibling(static_cast(this), tasks, sizeof(start_reduce), sizeof(finish_type)); + new((void*)tasks[0]) finish_type(my_context); + new((void*)tasks[1]) start_reduce(*this, split_obj); + spawn(*tasks[1]); + } + //! spawn right task, serves as callback for partitioner + void offer_work(const Range& r, depth_t d = 0) { + task *tasks[2]; + allocate_sibling(static_cast(this), tasks, sizeof(start_reduce), sizeof(finish_type)); + new((void*)tasks[0]) finish_type(my_context); + new((void*)tasks[1]) start_reduce(*this, r, d); + spawn(*tasks[1]); + } + }; + + //! allocate right task with new parent + // TODO: 'inline' here is to avoid multiple definition error but for sake of code size this should not be inlined + inline void allocate_sibling(task* start_reduce_task, task *tasks[], size_t start_bytes, size_t finish_bytes) { + tasks[0] = &start_reduce_task->allocate_continuation().allocate(finish_bytes); + start_reduce_task->set_parent(tasks[0]); + tasks[0]->set_ref_count(2); + tasks[1] = &tasks[0]->allocate_child().allocate(start_bytes); + } + + template + task* start_reduce::execute() { + my_partition.check_being_stolen( *this ); + if( my_context==right_child ) { + finish_type* parent_ptr = static_cast(parent()); + if( !itt_load_word_with_acquire(parent_ptr->my_body) ) { // TODO: replace by is_stolen_task() or by parent_ptr->ref_count() == 2??? + my_body = new( parent_ptr->zombie_space.begin() ) Body(*my_body,split()); + parent_ptr->has_right_zombie = true; + } + } else __TBB_ASSERT(my_context==root_task,NULL);// because left leaf spawns right leafs without recycling + my_partition.execute(*this, my_range); + if( my_context==left_child ) { + finish_type* parent_ptr = static_cast(parent()); + __TBB_ASSERT(my_body!=parent_ptr->zombie_space.begin(),NULL); + itt_store_word_with_release(parent_ptr->my_body, my_body ); + } + return NULL; + } + + //! Task type used to combine the partial results of parallel_deterministic_reduce. + /** @ingroup algorithms */ + template + class finish_deterministic_reduce: public task { + Body &my_left_body; + Body my_right_body; + + finish_deterministic_reduce( Body &body ) : + my_left_body( body ), + my_right_body( body, split() ) + { + } + task* execute() __TBB_override { + my_left_body.join( my_right_body ); + return NULL; + } + template + friend class start_deterministic_reduce; + }; + + //! Task type used to split the work of parallel_deterministic_reduce. + /** @ingroup algorithms */ + template + class start_deterministic_reduce: public task { + typedef finish_deterministic_reduce finish_type; + Body &my_body; + Range my_range; + typename Partitioner::task_partition_type my_partition; + task* execute() __TBB_override; + + //! Constructor used for root task + start_deterministic_reduce( const Range& range, Body& body, Partitioner& partitioner ) : + my_body( body ), + my_range( range ), + my_partition( partitioner ) + { + } + //! Splitting constructor used to generate children. + /** parent_ becomes left child. Newly constructed object is right child. */ + start_deterministic_reduce( start_deterministic_reduce& parent_, finish_type& c, typename Partitioner::split_type& split_obj ) : + my_body( c.my_right_body ), + my_range( parent_.my_range, split_obj ), + my_partition( parent_.my_partition, split_obj ) + { + } + +public: + static void run( const Range& range, Body& body, Partitioner& partitioner ) { + if( !range.empty() ) { +#if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP + task::spawn_root_and_wait( *new(task::allocate_root()) start_deterministic_reduce(range,&body,partitioner) ); +#else + // Bound context prevents exceptions from body to affect nesting or sibling algorithms, + // and allows users to handle exceptions safely by wrapping parallel_for in the try-block. + task_group_context context(PARALLEL_REDUCE); + task::spawn_root_and_wait( *new(task::allocate_root(context)) start_deterministic_reduce(range,body,partitioner) ); +#endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */ + } + } +#if __TBB_TASK_GROUP_CONTEXT + static void run( const Range& range, Body& body, Partitioner& partitioner, task_group_context& context ) { + if( !range.empty() ) + task::spawn_root_and_wait( *new(task::allocate_root(context)) start_deterministic_reduce(range,body,partitioner) ); + } +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + void offer_work( typename Partitioner::split_type& split_obj) { + task* tasks[2]; + allocate_sibling(static_cast(this), tasks, sizeof(start_deterministic_reduce), sizeof(finish_type)); + new((void*)tasks[0]) finish_type(my_body); + new((void*)tasks[1]) start_deterministic_reduce(*this, *static_cast(tasks[0]), split_obj); + spawn(*tasks[1]); + } + + void run_body( Range &r ) { my_body(r); } + }; + + template + task* start_deterministic_reduce::execute() { + my_partition.execute(*this, my_range); + return NULL; + } +} // namespace internal +//! @endcond +} //namespace interfaceX + +//! @cond INTERNAL +namespace internal { + using interface9::internal::start_reduce; + using interface9::internal::start_deterministic_reduce; + //! Auxiliary class for parallel_reduce; for internal use only. + /** The adaptor class that implements \ref parallel_reduce_body_req "parallel_reduce Body" + using given \ref parallel_reduce_lambda_req "anonymous function objects". + **/ + /** @ingroup algorithms */ + template + class lambda_reduce_body { + +//FIXME: decide if my_real_body, my_reduction, and identity_element should be copied or referenced +// (might require some performance measurements) + + const Value& identity_element; + const RealBody& my_real_body; + const Reduction& my_reduction; + Value my_value; + lambda_reduce_body& operator= ( const lambda_reduce_body& other ); + public: + lambda_reduce_body( const Value& identity, const RealBody& body, const Reduction& reduction ) + : identity_element(identity) + , my_real_body(body) + , my_reduction(reduction) + , my_value(identity) + { } + lambda_reduce_body( const lambda_reduce_body& other ) + : identity_element(other.identity_element) + , my_real_body(other.my_real_body) + , my_reduction(other.my_reduction) + , my_value(other.my_value) + { } + lambda_reduce_body( lambda_reduce_body& other, tbb::split ) + : identity_element(other.identity_element) + , my_real_body(other.my_real_body) + , my_reduction(other.my_reduction) + , my_value(other.identity_element) + { } + void operator()(Range& range) { + my_value = my_real_body(range, const_cast(my_value)); + } + void join( lambda_reduce_body& rhs ) { + my_value = my_reduction(const_cast(my_value), const_cast(rhs.my_value)); + } + Value result() const { + return my_value; + } + }; + +} // namespace internal +//! @endcond + +// Requirements on Range concept are documented in blocked_range.h + +/** \page parallel_reduce_body_req Requirements on parallel_reduce body + Class \c Body implementing the concept of parallel_reduce body must define: + - \code Body::Body( Body&, split ); \endcode Splitting constructor. + Must be able to run concurrently with operator() and method \c join + - \code Body::~Body(); \endcode Destructor + - \code void Body::operator()( Range& r ); \endcode Function call operator applying body to range \c r + and accumulating the result + - \code void Body::join( Body& b ); \endcode Join results. + The result in \c b should be merged into the result of \c this +**/ + +/** \page parallel_reduce_lambda_req Requirements on parallel_reduce anonymous function objects (lambda functions) + TO BE DOCUMENTED +**/ + +/** \name parallel_reduce + See also requirements on \ref range_req "Range" and \ref parallel_reduce_body_req "parallel_reduce Body". **/ +//@{ + +//! Parallel iteration with reduction and default partitioner. +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body ) { + internal::start_reduce::run( range, body, __TBB_DEFAULT_PARTITIONER() ); +} + +//! Parallel iteration with reduction and simple_partitioner +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, const simple_partitioner& partitioner ) { + internal::start_reduce::run( range, body, partitioner ); +} + +//! Parallel iteration with reduction and auto_partitioner +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, const auto_partitioner& partitioner ) { + internal::start_reduce::run( range, body, partitioner ); +} + +//! Parallel iteration with reduction and static_partitioner +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, const static_partitioner& partitioner ) { + internal::start_reduce::run( range, body, partitioner ); +} + +//! Parallel iteration with reduction and affinity_partitioner +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, affinity_partitioner& partitioner ) { + internal::start_reduce::run( range, body, partitioner ); +} + +#if __TBB_TASK_GROUP_CONTEXT +//! Parallel iteration with reduction, default partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, task_group_context& context ) { + internal::start_reduce::run( range, body, __TBB_DEFAULT_PARTITIONER(), context ); +} + +//! Parallel iteration with reduction, simple partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, const simple_partitioner& partitioner, task_group_context& context ) { + internal::start_reduce::run( range, body, partitioner, context ); +} + +//! Parallel iteration with reduction, auto_partitioner and user-supplied context +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, const auto_partitioner& partitioner, task_group_context& context ) { + internal::start_reduce::run( range, body, partitioner, context ); +} + +//! Parallel iteration with reduction, static_partitioner and user-supplied context +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, const static_partitioner& partitioner, task_group_context& context ) { + internal::start_reduce::run( range, body, partitioner, context ); +} + +//! Parallel iteration with reduction, affinity_partitioner and user-supplied context +/** @ingroup algorithms **/ +template +void parallel_reduce( const Range& range, Body& body, affinity_partitioner& partitioner, task_group_context& context ) { + internal::start_reduce::run( range, body, partitioner, context ); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +/** parallel_reduce overloads that work with anonymous function objects + (see also \ref parallel_reduce_lambda_req "requirements on parallel_reduce anonymous function objects"). **/ + +//! Parallel iteration with reduction and default partitioner. +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,const __TBB_DEFAULT_PARTITIONER> + ::run(range, body, __TBB_DEFAULT_PARTITIONER() ); + return body.result(); +} + +//! Parallel iteration with reduction and simple_partitioner. +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + const simple_partitioner& partitioner ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,const simple_partitioner> + ::run(range, body, partitioner ); + return body.result(); +} + +//! Parallel iteration with reduction and auto_partitioner +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + const auto_partitioner& partitioner ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,const auto_partitioner> + ::run( range, body, partitioner ); + return body.result(); +} + +//! Parallel iteration with reduction and static_partitioner +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + const static_partitioner& partitioner ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,const static_partitioner> + ::run( range, body, partitioner ); + return body.result(); +} + +//! Parallel iteration with reduction and affinity_partitioner +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + affinity_partitioner& partitioner ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,affinity_partitioner> + ::run( range, body, partitioner ); + return body.result(); +} + +#if __TBB_TASK_GROUP_CONTEXT +//! Parallel iteration with reduction, default partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + task_group_context& context ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,const __TBB_DEFAULT_PARTITIONER> + ::run( range, body, __TBB_DEFAULT_PARTITIONER(), context ); + return body.result(); +} + +//! Parallel iteration with reduction, simple partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + const simple_partitioner& partitioner, task_group_context& context ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,const simple_partitioner> + ::run( range, body, partitioner, context ); + return body.result(); +} + +//! Parallel iteration with reduction, auto_partitioner and user-supplied context +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + const auto_partitioner& partitioner, task_group_context& context ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,const auto_partitioner> + ::run( range, body, partitioner, context ); + return body.result(); +} + +//! Parallel iteration with reduction, static_partitioner and user-supplied context +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + const static_partitioner& partitioner, task_group_context& context ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,const static_partitioner> + ::run( range, body, partitioner, context ); + return body.result(); +} + +//! Parallel iteration with reduction, affinity_partitioner and user-supplied context +/** @ingroup algorithms **/ +template +Value parallel_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + affinity_partitioner& partitioner, task_group_context& context ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_reduce,affinity_partitioner> + ::run( range, body, partitioner, context ); + return body.result(); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +//! Parallel iteration with deterministic reduction and default simple partitioner. +/** @ingroup algorithms **/ +template +void parallel_deterministic_reduce( const Range& range, Body& body ) { + internal::start_deterministic_reduce::run(range, body, simple_partitioner()); +} + +//! Parallel iteration with deterministic reduction and simple partitioner. +/** @ingroup algorithms **/ +template +void parallel_deterministic_reduce( const Range& range, Body& body, const simple_partitioner& partitioner ) { + internal::start_deterministic_reduce::run(range, body, partitioner); +} + +//! Parallel iteration with deterministic reduction and static partitioner. +/** @ingroup algorithms **/ +template +void parallel_deterministic_reduce( const Range& range, Body& body, const static_partitioner& partitioner ) { + internal::start_deterministic_reduce::run(range, body, partitioner); +} + +#if __TBB_TASK_GROUP_CONTEXT +//! Parallel iteration with deterministic reduction, default simple partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_deterministic_reduce( const Range& range, Body& body, task_group_context& context ) { + internal::start_deterministic_reduce::run( range, body, simple_partitioner(), context ); +} + +//! Parallel iteration with deterministic reduction, simple partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_deterministic_reduce( const Range& range, Body& body, const simple_partitioner& partitioner, task_group_context& context ) { + internal::start_deterministic_reduce::run(range, body, partitioner, context); +} + +//! Parallel iteration with deterministic reduction, static partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +void parallel_deterministic_reduce( const Range& range, Body& body, const static_partitioner& partitioner, task_group_context& context ) { + internal::start_deterministic_reduce::run(range, body, partitioner, context); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +/** parallel_reduce overloads that work with anonymous function objects + (see also \ref parallel_reduce_lambda_req "requirements on parallel_reduce anonymous function objects"). **/ + +//! Parallel iteration with deterministic reduction and default simple partitioner. +// TODO: consider making static_partitioner the default +/** @ingroup algorithms **/ +template +Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction ) { + return parallel_deterministic_reduce(range, identity, real_body, reduction, simple_partitioner()); +} + +//! Parallel iteration with deterministic reduction and simple partitioner. +/** @ingroup algorithms **/ +template +Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, const simple_partitioner& partitioner ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_deterministic_reduce, const simple_partitioner> + ::run(range, body, partitioner); + return body.result(); +} + +//! Parallel iteration with deterministic reduction and static partitioner. +/** @ingroup algorithms **/ +template +Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, const static_partitioner& partitioner ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_deterministic_reduce, const static_partitioner> + ::run(range, body, partitioner); + return body.result(); +} +#if __TBB_TASK_GROUP_CONTEXT +//! Parallel iteration with deterministic reduction, default simple partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + task_group_context& context ) { + return parallel_deterministic_reduce(range, identity, real_body, reduction, simple_partitioner(), context); +} + +//! Parallel iteration with deterministic reduction, simple partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + const simple_partitioner& partitioner, task_group_context& context ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_deterministic_reduce, const simple_partitioner> + ::run(range, body, partitioner, context); + return body.result(); +} + +//! Parallel iteration with deterministic reduction, static partitioner and user-supplied context. +/** @ingroup algorithms **/ +template +Value parallel_deterministic_reduce( const Range& range, const Value& identity, const RealBody& real_body, const Reduction& reduction, + const static_partitioner& partitioner, task_group_context& context ) { + internal::lambda_reduce_body body(identity, real_body, reduction); + internal::start_deterministic_reduce, const static_partitioner> + ::run(range, body, partitioner, context); + return body.result(); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ +//@} + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_parallel_reduce_H_include_area + +#endif /* __TBB_parallel_reduce_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_scan.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_scan.h new file mode 100644 index 00000000..7930b5c4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_scan.h @@ -0,0 +1,416 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_parallel_scan_H +#define __TBB_parallel_scan_H + +#define __TBB_parallel_scan_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "task.h" +#include "aligned_space.h" +#include +#include "partitioner.h" + +namespace tbb { + +//! Used to indicate that the initial scan is being performed. +/** @ingroup algorithms */ +struct pre_scan_tag { + static bool is_final_scan() {return false;} + operator bool() {return is_final_scan();} +}; + +//! Used to indicate that the final scan is being performed. +/** @ingroup algorithms */ +struct final_scan_tag { + static bool is_final_scan() {return true;} + operator bool() {return is_final_scan();} +}; + +//! @cond INTERNAL +namespace internal { + + //! Performs final scan for a leaf + /** @ingroup algorithms */ + template + class final_sum: public task { + public: + Body my_body; + private: + aligned_space my_range; + //! Where to put result of last subrange, or NULL if not last subrange. + Body* my_stuff_last; + public: + final_sum( Body& body_ ) : + my_body(body_,split()) + { + poison_pointer(my_stuff_last); + } + ~final_sum() { + my_range.begin()->~Range(); + } + void finish_construction( const Range& range_, Body* stuff_last_ ) { + new( my_range.begin() ) Range(range_); + my_stuff_last = stuff_last_; + } + private: + task* execute() __TBB_override { + my_body( *my_range.begin(), final_scan_tag() ); + if( my_stuff_last ) + my_stuff_last->assign(my_body); + return NULL; + } + }; + + //! Split work to be done in the scan. + /** @ingroup algorithms */ + template + class sum_node: public task { + typedef final_sum final_sum_type; + public: + final_sum_type *my_incoming; + final_sum_type *my_body; + Body *my_stuff_last; + private: + final_sum_type *my_left_sum; + sum_node *my_left; + sum_node *my_right; + bool my_left_is_final; + Range my_range; + sum_node( const Range range_, bool left_is_final_ ) : + my_stuff_last(NULL), + my_left_sum(NULL), + my_left(NULL), + my_right(NULL), + my_left_is_final(left_is_final_), + my_range(range_) + { + // Poison fields that will be set by second pass. + poison_pointer(my_body); + poison_pointer(my_incoming); + } + task* create_child( const Range& range_, final_sum_type& f, sum_node* n, final_sum_type* incoming_, Body* stuff_last_ ) { + if( !n ) { + f.recycle_as_child_of( *this ); + f.finish_construction( range_, stuff_last_ ); + return &f; + } else { + n->my_body = &f; + n->my_incoming = incoming_; + n->my_stuff_last = stuff_last_; + return n; + } + } + task* execute() __TBB_override { + if( my_body ) { + if( my_incoming ) + my_left_sum->my_body.reverse_join( my_incoming->my_body ); + recycle_as_continuation(); + sum_node& c = *this; + task* b = c.create_child(Range(my_range,split()),*my_left_sum,my_right,my_left_sum,my_stuff_last); + task* a = my_left_is_final ? NULL : c.create_child(my_range,*my_body,my_left,my_incoming,NULL); + set_ref_count( (a!=NULL)+(b!=NULL) ); + my_body = NULL; + if( a ) spawn(*b); + else a = b; + return a; + } else { + return NULL; + } + } + template + friend class start_scan; + + template + friend class finish_scan; + }; + + //! Combine partial results + /** @ingroup algorithms */ + template + class finish_scan: public task { + typedef sum_node sum_node_type; + typedef final_sum final_sum_type; + final_sum_type** const my_sum; + sum_node_type*& my_return_slot; + public: + final_sum_type* my_right_zombie; + sum_node_type& my_result; + + task* execute() __TBB_override { + __TBB_ASSERT( my_result.ref_count()==(my_result.my_left!=NULL)+(my_result.my_right!=NULL), NULL ); + if( my_result.my_left ) + my_result.my_left_is_final = false; + if( my_right_zombie && my_sum ) + ((*my_sum)->my_body).reverse_join(my_result.my_left_sum->my_body); + __TBB_ASSERT( !my_return_slot, NULL ); + if( my_right_zombie || my_result.my_right ) { + my_return_slot = &my_result; + } else { + destroy( my_result ); + } + if( my_right_zombie && !my_sum && !my_result.my_right ) { + destroy(*my_right_zombie); + my_right_zombie = NULL; + } + return NULL; + } + + finish_scan( sum_node_type*& return_slot_, final_sum_type** sum_, sum_node_type& result_ ) : + my_sum(sum_), + my_return_slot(return_slot_), + my_right_zombie(NULL), + my_result(result_) + { + __TBB_ASSERT( !my_return_slot, NULL ); + } + }; + + //! Initial task to split the work + /** @ingroup algorithms */ + template + class start_scan: public task { + typedef sum_node sum_node_type; + typedef final_sum final_sum_type; + final_sum_type* my_body; + /** Non-null if caller is requesting total. */ + final_sum_type** my_sum; + sum_node_type** my_return_slot; + /** Null if computing root. */ + sum_node_type* my_parent_sum; + bool my_is_final; + bool my_is_right_child; + Range my_range; + typename Partitioner::partition_type my_partition; + task* execute() __TBB_override ; + public: + start_scan( sum_node_type*& return_slot_, start_scan& parent_, sum_node_type* parent_sum_ ) : + my_body(parent_.my_body), + my_sum(parent_.my_sum), + my_return_slot(&return_slot_), + my_parent_sum(parent_sum_), + my_is_final(parent_.my_is_final), + my_is_right_child(false), + my_range(parent_.my_range,split()), + my_partition(parent_.my_partition,split()) + { + __TBB_ASSERT( !*my_return_slot, NULL ); + } + + start_scan( sum_node_type*& return_slot_, const Range& range_, final_sum_type& body_, const Partitioner& partitioner_) : + my_body(&body_), + my_sum(NULL), + my_return_slot(&return_slot_), + my_parent_sum(NULL), + my_is_final(true), + my_is_right_child(false), + my_range(range_), + my_partition(partitioner_) + { + __TBB_ASSERT( !*my_return_slot, NULL ); + } + + static void run( const Range& range_, Body& body_, const Partitioner& partitioner_ ) { + if( !range_.empty() ) { + typedef internal::start_scan start_pass1_type; + internal::sum_node* root = NULL; + final_sum_type* temp_body = new(task::allocate_root()) final_sum_type( body_ ); + start_pass1_type& pass1 = *new(task::allocate_root()) start_pass1_type( + /*my_return_slot=*/root, + range_, + *temp_body, + partitioner_ ); + temp_body->my_body.reverse_join(body_); + task::spawn_root_and_wait( pass1 ); + if( root ) { + root->my_body = temp_body; + root->my_incoming = NULL; + root->my_stuff_last = &body_; + task::spawn_root_and_wait( *root ); + } else { + body_.assign(temp_body->my_body); + temp_body->finish_construction( range_, NULL ); + temp_body->destroy(*temp_body); + } + } + } + }; + + template + task* start_scan::execute() { + typedef internal::finish_scan finish_pass1_type; + finish_pass1_type* p = my_parent_sum ? static_cast( parent() ) : NULL; + // Inspecting p->result.left_sum would ordinarily be a race condition. + // But we inspect it only if we are not a stolen task, in which case we + // know that task assigning to p->result.left_sum has completed. + bool treat_as_stolen = my_is_right_child && (is_stolen_task() || my_body!=p->my_result.my_left_sum); + if( treat_as_stolen ) { + // Invocation is for right child that has been really stolen or needs to be virtually stolen + p->my_right_zombie = my_body = new( allocate_root() ) final_sum_type(my_body->my_body); + my_is_final = false; + } + task* next_task = NULL; + if( (my_is_right_child && !treat_as_stolen) || !my_range.is_divisible() || my_partition.should_execute_range(*this) ) { + if( my_is_final ) + (my_body->my_body)( my_range, final_scan_tag() ); + else if( my_sum ) + (my_body->my_body)( my_range, pre_scan_tag() ); + if( my_sum ) + *my_sum = my_body; + __TBB_ASSERT( !*my_return_slot, NULL ); + } else { + sum_node_type* result; + if( my_parent_sum ) + result = new(allocate_additional_child_of(*my_parent_sum)) sum_node_type(my_range,/*my_left_is_final=*/my_is_final); + else + result = new(task::allocate_root()) sum_node_type(my_range,/*my_left_is_final=*/my_is_final); + finish_pass1_type& c = *new( allocate_continuation()) finish_pass1_type(*my_return_slot,my_sum,*result); + // Split off right child + start_scan& b = *new( c.allocate_child() ) start_scan( /*my_return_slot=*/result->my_right, *this, result ); + b.my_is_right_child = true; + // Left child is recycling of *this. Must recycle this before spawning b, + // otherwise b might complete and decrement c.ref_count() to zero, which + // would cause c.execute() to run prematurely. + recycle_as_child_of(c); + c.set_ref_count(2); + c.spawn(b); + my_sum = &result->my_left_sum; + my_return_slot = &result->my_left; + my_is_right_child = false; + next_task = this; + my_parent_sum = result; + __TBB_ASSERT( !*my_return_slot, NULL ); + } + return next_task; + } + + template + class lambda_scan_body : no_assign { + Value my_sum; + const Value& identity_element; + const Scan& my_scan; + const ReverseJoin& my_reverse_join; + public: + lambda_scan_body( const Value& identity, const Scan& scan, const ReverseJoin& rev_join) + : my_sum(identity) + , identity_element(identity) + , my_scan(scan) + , my_reverse_join(rev_join) {} + + lambda_scan_body( lambda_scan_body& b, split ) + : my_sum(b.identity_element) + , identity_element(b.identity_element) + , my_scan(b.my_scan) + , my_reverse_join(b.my_reverse_join) {} + + template + void operator()( const Range& r, Tag tag ) { + my_sum = my_scan(r, my_sum, tag); + } + + void reverse_join( lambda_scan_body& a ) { + my_sum = my_reverse_join(a.my_sum, my_sum); + } + + void assign( lambda_scan_body& b ) { + my_sum = b.my_sum; + } + + Value result() const { + return my_sum; + } + }; +} // namespace internal +//! @endcond + +// Requirements on Range concept are documented in blocked_range.h + +/** \page parallel_scan_body_req Requirements on parallel_scan body + Class \c Body implementing the concept of parallel_scan body must define: + - \code Body::Body( Body&, split ); \endcode Splitting constructor. + Split \c b so that \c this and \c b can accumulate separately + - \code Body::~Body(); \endcode Destructor + - \code void Body::operator()( const Range& r, pre_scan_tag ); \endcode + Preprocess iterations for range \c r + - \code void Body::operator()( const Range& r, final_scan_tag ); \endcode + Do final processing for iterations of range \c r + - \code void Body::reverse_join( Body& a ); \endcode + Merge preprocessing state of \c a into \c this, where \c a was + created earlier from \c b by b's splitting constructor +**/ + +/** \name parallel_scan + See also requirements on \ref range_req "Range" and \ref parallel_scan_body_req "parallel_scan Body". **/ +//@{ + +//! Parallel prefix with default partitioner +/** @ingroup algorithms **/ +template +void parallel_scan( const Range& range, Body& body ) { + internal::start_scan::run(range,body,__TBB_DEFAULT_PARTITIONER()); +} + +//! Parallel prefix with simple_partitioner +/** @ingroup algorithms **/ +template +void parallel_scan( const Range& range, Body& body, const simple_partitioner& partitioner ) { + internal::start_scan::run(range,body,partitioner); +} + +//! Parallel prefix with auto_partitioner +/** @ingroup algorithms **/ +template +void parallel_scan( const Range& range, Body& body, const auto_partitioner& partitioner ) { + internal::start_scan::run(range,body,partitioner); +} + +//! Parallel prefix with default partitioner +/** @ingroup algorithms **/ +template +Value parallel_scan( const Range& range, const Value& identity, const Scan& scan, const ReverseJoin& reverse_join ) { + internal::lambda_scan_body body(identity, scan, reverse_join); + tbb::parallel_scan(range,body,__TBB_DEFAULT_PARTITIONER()); + return body.result(); +} + +//! Parallel prefix with simple_partitioner +/** @ingroup algorithms **/ +template +Value parallel_scan( const Range& range, const Value& identity, const Scan& scan, const ReverseJoin& reverse_join, const simple_partitioner& partitioner ) { + internal::lambda_scan_body body(identity, scan, reverse_join); + tbb::parallel_scan(range,body,partitioner); + return body.result(); +} + +//! Parallel prefix with auto_partitioner +/** @ingroup algorithms **/ +template +Value parallel_scan( const Range& range, const Value& identity, const Scan& scan, const ReverseJoin& reverse_join, const auto_partitioner& partitioner ) { + internal::lambda_scan_body body(identity, scan, reverse_join); + tbb::parallel_scan(range,body,partitioner); + return body.result(); +} + +//@} + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_parallel_scan_H_include_area + +#endif /* __TBB_parallel_scan_H */ + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_sort.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_sort.h new file mode 100644 index 00000000..b865b2ee --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_sort.h @@ -0,0 +1,257 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_parallel_sort_H +#define __TBB_parallel_sort_H + +#define __TBB_parallel_sort_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "parallel_for.h" +#include "blocked_range.h" +#include "internal/_range_iterator.h" +#include +#include +#include +#if __TBB_TASK_GROUP_CONTEXT + #include "tbb_profiling.h" +#endif + +namespace tbb { + +namespace interface9 { +//! @cond INTERNAL +namespace internal { + +using tbb::internal::no_assign; + +//! Range used in quicksort to split elements into subranges based on a value. +/** The split operation selects a splitter and places all elements less than or equal + to the value in the first range and the remaining elements in the second range. + @ingroup algorithms */ +template +class quick_sort_range: private no_assign { + + inline size_t median_of_three(const RandomAccessIterator &array, size_t l, size_t m, size_t r) const { + return comp(array[l], array[m]) ? ( comp(array[m], array[r]) ? m : ( comp( array[l], array[r]) ? r : l ) ) + : ( comp(array[r], array[m]) ? m : ( comp( array[r], array[l] ) ? r : l ) ); + } + + inline size_t pseudo_median_of_nine( const RandomAccessIterator &array, const quick_sort_range &range ) const { + size_t offset = range.size/8u; + return median_of_three(array, + median_of_three(array, 0, offset, offset*2), + median_of_three(array, offset*3, offset*4, offset*5), + median_of_three(array, offset*6, offset*7, range.size - 1) ); + + } + + size_t split_range( quick_sort_range& range ) { + using std::iter_swap; + RandomAccessIterator array = range.begin; + RandomAccessIterator key0 = range.begin; + size_t m = pseudo_median_of_nine(array, range); + if (m) iter_swap ( array, array+m ); + + size_t i=0; + size_t j=range.size; + // Partition interval [i+1,j-1] with key *key0. + for(;;) { + __TBB_ASSERT( i=grainsize;} + + quick_sort_range( quick_sort_range& range, split ) + : comp(range.comp) + , size(split_range(range)) + // +1 accounts for the pivot element, which is at its correct place + // already and, therefore, is not included into subranges. + , begin(range.begin+range.size+1) {} +}; + +#if __TBB_TASK_GROUP_CONTEXT +//! Body class used to test if elements in a range are presorted +/** @ingroup algorithms */ +template +class quick_sort_pretest_body : no_assign { + const Compare ∁ + +public: + quick_sort_pretest_body(const Compare &_comp) : comp(_comp) {} + + void operator()( const blocked_range& range ) const { + task &my_task = task::self(); + RandomAccessIterator my_end = range.end(); + + int i = 0; + for (RandomAccessIterator k = range.begin(); k != my_end; ++k, ++i) { + if ( i%64 == 0 && my_task.is_cancelled() ) break; + + // The k-1 is never out-of-range because the first chunk starts at begin+serial_cutoff+1 + if ( comp( *(k), *(k-1) ) ) { + my_task.cancel_group_execution(); + break; + } + } + } + +}; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +//! Body class used to sort elements in a range that is smaller than the grainsize. +/** @ingroup algorithms */ +template +struct quick_sort_body { + void operator()( const quick_sort_range& range ) const { + //SerialQuickSort( range.begin, range.size, range.comp ); + std::sort( range.begin, range.begin + range.size, range.comp ); + } +}; + +//! Wrapper method to initiate the sort by calling parallel_for. +/** @ingroup algorithms */ +template +void parallel_quick_sort( RandomAccessIterator begin, RandomAccessIterator end, const Compare& comp ) { +#if __TBB_TASK_GROUP_CONTEXT + task_group_context my_context(PARALLEL_SORT); + const int serial_cutoff = 9; + + __TBB_ASSERT( begin + serial_cutoff < end, "min_parallel_size is smaller than serial cutoff?" ); + RandomAccessIterator k = begin; + for ( ; k != begin + serial_cutoff; ++k ) { + if ( comp( *(k+1), *k ) ) { + goto do_parallel_quick_sort; + } + } + + parallel_for( blocked_range(k+1, end), + quick_sort_pretest_body(comp), + auto_partitioner(), + my_context); + + if (my_context.is_group_execution_cancelled()) +do_parallel_quick_sort: +#endif /* __TBB_TASK_GROUP_CONTEXT */ + parallel_for( quick_sort_range(begin, end-begin, comp ), + quick_sort_body(), + auto_partitioner() ); +} + +} // namespace internal +//! @endcond +} // namespace interfaceX + +/** \page parallel_sort_iter_req Requirements on iterators for parallel_sort + Requirements on the iterator type \c It and its value type \c T for \c parallel_sort: + + - \code void iter_swap( It a, It b ) \endcode Swaps the values of the elements the given + iterators \c a and \c b are pointing to. \c It should be a random access iterator. + + - \code bool Compare::operator()( const T& x, const T& y ) \endcode True if x comes before y; +**/ + +/** \name parallel_sort + See also requirements on \ref parallel_sort_iter_req "iterators for parallel_sort". **/ +//@{ + +//! Sorts the data in [begin,end) using the given comparator +/** The compare function object is used for all comparisons between elements during sorting. + The compare object must define a bool operator() function. + @ingroup algorithms **/ +template +void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end, const Compare& comp) { + const int min_parallel_size = 500; + if( end > begin ) { + if (end - begin < min_parallel_size) { + std::sort(begin, end, comp); + } else { + interface9::internal::parallel_quick_sort(begin, end, comp); + } + } +} + +//! Sorts the data in [begin,end) with a default comparator \c std::less +/** @ingroup algorithms **/ +template +inline void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end ) { + parallel_sort( begin, end, std::less< typename std::iterator_traits::value_type >() ); +} + +//! Sorts the data in rng using the given comparator +/** @ingroup algorithms **/ +template +void parallel_sort(Range& rng, const Compare& comp) { + parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng), comp); +} + +//! Sorts the data in rng with a default comparator \c std::less +/** @ingroup algorithms **/ +template +void parallel_sort(Range& rng) { + parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng)); +} + +//! Sorts the data in the range \c [begin,end) with a default comparator \c std::less +/** @ingroup algorithms **/ +template +inline void parallel_sort( T * begin, T * end ) { + parallel_sort( begin, end, std::less< T >() ); +} +//@} + + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_parallel_sort_H_include_area + +#endif + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_while.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_while.h new file mode 100644 index 00000000..65984af5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/parallel_while.h @@ -0,0 +1,188 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_parallel_while +#define __TBB_parallel_while + +#define __TBB_parallel_while_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "task.h" +#include + +namespace tbb { + +template +class parallel_while; + +//! @cond INTERNAL +namespace internal { + + template class while_task; + + //! For internal use only. + /** Executes one iteration of a while. + @ingroup algorithms */ + template + class while_iteration_task: public task { + const Body& my_body; + typename Body::argument_type my_value; + task* execute() __TBB_override { + my_body(my_value); + return NULL; + } + while_iteration_task( const typename Body::argument_type& value, const Body& body ) : + my_body(body), my_value(value) + {} + template friend class while_group_task; + friend class tbb::parallel_while; + }; + + //! For internal use only + /** Unpacks a block of iterations. + @ingroup algorithms */ + template + class while_group_task: public task { + static const size_t max_arg_size = 4; + const Body& my_body; + size_t size; + typename Body::argument_type my_arg[max_arg_size]; + while_group_task( const Body& body ) : my_body(body), size(0) {} + task* execute() __TBB_override { + typedef while_iteration_task iteration_type; + __TBB_ASSERT( size>0, NULL ); + task_list list; + task* t; + size_t k=0; + for(;;) { + t = new( allocate_child() ) iteration_type(my_arg[k],my_body); + if( ++k==size ) break; + list.push_back(*t); + } + set_ref_count(int(k+1)); + spawn(list); + spawn_and_wait_for_all(*t); + return NULL; + } + template friend class while_task; + }; + + //! For internal use only. + /** Gets block of iterations from a stream and packages them into a while_group_task. + @ingroup algorithms */ + template + class while_task: public task { + Stream& my_stream; + const Body& my_body; + empty_task& my_barrier; + task* execute() __TBB_override { + typedef while_group_task block_type; + block_type& t = *new( allocate_additional_child_of(my_barrier) ) block_type(my_body); + size_t k=0; + while( my_stream.pop_if_present(t.my_arg[k]) ) { + if( ++k==block_type::max_arg_size ) { + // There might be more iterations. + recycle_to_reexecute(); + break; + } + } + if( k==0 ) { + destroy(t); + return NULL; + } else { + t.size = k; + return &t; + } + } + while_task( Stream& stream, const Body& body, empty_task& barrier ) : + my_stream(stream), + my_body(body), + my_barrier(barrier) + {} + friend class tbb::parallel_while; + }; + +} // namespace internal +//! @endcond + +//! Parallel iteration over a stream, with optional addition of more work. +/** The Body b has the requirement: \n + "b(v)" \n + "b.argument_type" \n + where v is an argument_type + @ingroup algorithms */ +template +class parallel_while: internal::no_copy { +public: + //! Construct empty non-running parallel while. + parallel_while() : my_body(NULL), my_barrier(NULL) {} + + //! Destructor cleans up data members before returning. + ~parallel_while() { + if( my_barrier ) { + my_barrier->destroy(*my_barrier); + my_barrier = NULL; + } + } + + //! Type of items + typedef typename Body::argument_type value_type; + + //! Apply body.apply to each item in the stream. + /** A Stream s has the requirements \n + "S::value_type" \n + "s.pop_if_present(value) is convertible to bool */ + template + void run( Stream& stream, const Body& body ); + + //! Add a work item while running. + /** Should be executed only by body.apply or a thread spawned therefrom. */ + void add( const value_type& item ); + +private: + const Body* my_body; + empty_task* my_barrier; +}; + +template +template +void parallel_while::run( Stream& stream, const Body& body ) { + using namespace internal; + empty_task& barrier = *new( task::allocate_root() ) empty_task(); + my_body = &body; + my_barrier = &barrier; + my_barrier->set_ref_count(2); + while_task& w = *new( my_barrier->allocate_child() ) while_task( stream, body, barrier ); + my_barrier->spawn_and_wait_for_all(w); + my_barrier->destroy(*my_barrier); + my_barrier = NULL; + my_body = NULL; +} + +template +void parallel_while::add( const value_type& item ) { + __TBB_ASSERT(my_barrier,"attempt to add to parallel_while that is not running"); + typedef internal::while_iteration_task iteration_type; + iteration_type& i = *new( task::allocate_additional_child_of(*my_barrier) ) iteration_type(item,*my_body); + task::self().spawn( i ); +} + +} // namespace + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_parallel_while_H_include_area + +#endif /* __TBB_parallel_while */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/partitioner.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/partitioner.h new file mode 100644 index 00000000..c130d349 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/partitioner.h @@ -0,0 +1,681 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_partitioner_H +#define __TBB_partitioner_H + +#define __TBB_partitioner_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#ifndef __TBB_INITIAL_CHUNKS +// initial task divisions per thread +#define __TBB_INITIAL_CHUNKS 2 +#endif +#ifndef __TBB_RANGE_POOL_CAPACITY +// maximum number of elements in range pool +#define __TBB_RANGE_POOL_CAPACITY 8 +#endif +#ifndef __TBB_INIT_DEPTH +// initial value for depth of range pool +#define __TBB_INIT_DEPTH 5 +#endif +#ifndef __TBB_DEMAND_DEPTH_ADD +// when imbalance is found range splits this value times more +#define __TBB_DEMAND_DEPTH_ADD 1 +#endif +#ifndef __TBB_STATIC_THRESHOLD +// necessary number of clocks for the work to be distributed among all tasks +#define __TBB_STATIC_THRESHOLD 40000 +#endif +#if __TBB_DEFINE_MIC +#define __TBB_NONUNIFORM_TASK_CREATION 1 +#ifdef __TBB_time_stamp +#define __TBB_USE_MACHINE_TIME_STAMPS 1 +#define __TBB_task_duration() __TBB_STATIC_THRESHOLD +#endif // __TBB_machine_time_stamp +#endif // __TBB_DEFINE_MIC + +#include "task.h" +#include "task_arena.h" +#include "aligned_space.h" +#include "atomic.h" +#include "internal/_template_helpers.h" + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + #pragma warning (push) + #pragma warning (disable: 4244) +#endif + +namespace tbb { + +class auto_partitioner; +class simple_partitioner; +class static_partitioner; +class affinity_partitioner; + +namespace interface9 { + namespace internal { + class affinity_partition_type; + } +} + +namespace internal { //< @cond INTERNAL +size_t __TBB_EXPORTED_FUNC get_initial_auto_partitioner_divisor(); + +//! Defines entry point for affinity partitioner into TBB run-time library. +class affinity_partitioner_base_v3: no_copy { + friend class tbb::affinity_partitioner; + friend class tbb::interface9::internal::affinity_partition_type; + //! Array that remembers affinities of tree positions to affinity_id. + /** NULL if my_size==0. */ + affinity_id* my_array; + //! Number of elements in my_array. + size_t my_size; + //! Zeros the fields. + affinity_partitioner_base_v3() : my_array(NULL), my_size(0) {} + //! Deallocates my_array. + ~affinity_partitioner_base_v3() {resize(0);} + //! Resize my_array. + /** Retains values if resulting size is the same. */ + void __TBB_EXPORTED_METHOD resize( unsigned factor ); +}; + +//! Provides backward-compatible methods for partition objects without affinity. +class partition_type_base { +public: + void set_affinity( task & ) {} + void note_affinity( task::affinity_id ) {} + task* continue_after_execute_range() {return NULL;} + bool decide_whether_to_delay() {return false;} + void spawn_or_delay( bool, task& b ) { + task::spawn(b); + } +}; + +template class start_scan; + +} //< namespace internal @endcond + +namespace serial { +namespace interface9 { +template class start_for; +} +} + +namespace interface9 { +//! @cond INTERNAL +namespace internal { +using namespace tbb::internal; +template class start_for; +template class start_reduce; +template class start_deterministic_reduce; + +//! Join task node that contains shared flag for stealing feedback +class flag_task: public task { +public: + tbb::atomic my_child_stolen; + flag_task() { my_child_stolen = false; } + task* execute() __TBB_override { return NULL; } + static void mark_task_stolen(task &t) { + tbb::atomic &flag = static_cast(t.parent())->my_child_stolen; +#if TBB_USE_THREADING_TOOLS + // Threading tools respect lock prefix but report false-positive data-race via plain store + flag.fetch_and_store(true); +#else + flag = true; +#endif //TBB_USE_THREADING_TOOLS + } + static bool is_peer_stolen(task &t) { + return static_cast(t.parent())->my_child_stolen; + } +}; + +//! Depth is a relative depth of recursive division inside a range pool. Relative depth allows +//! infinite absolute depth of the recursion for heavily unbalanced workloads with range represented +//! by a number that cannot fit into machine word. +typedef unsigned char depth_t; + +//! Range pool stores ranges of type T in a circular buffer with MaxCapacity +template +class range_vector { + depth_t my_head; + depth_t my_tail; + depth_t my_size; + depth_t my_depth[MaxCapacity]; // relative depths of stored ranges + tbb::aligned_space my_pool; + +public: + //! initialize via first range in pool + range_vector(const T& elem) : my_head(0), my_tail(0), my_size(1) { + my_depth[0] = 0; + new( static_cast(my_pool.begin()) ) T(elem);//TODO: std::move? + } + ~range_vector() { + while( !empty() ) pop_back(); + } + bool empty() const { return my_size == 0; } + depth_t size() const { return my_size; } + //! Populates range pool via ranges up to max depth or while divisible + //! max_depth starts from 0, e.g. value 2 makes 3 ranges in the pool up to two 1/4 pieces + void split_to_fill(depth_t max_depth) { + while( my_size < MaxCapacity && is_divisible(max_depth) ) { + depth_t prev = my_head; + my_head = (my_head + 1) % MaxCapacity; + new(my_pool.begin()+my_head) T(my_pool.begin()[prev]); // copy TODO: std::move? + my_pool.begin()[prev].~T(); // instead of assignment + new(my_pool.begin()+prev) T(my_pool.begin()[my_head], split()); // do 'inverse' split + my_depth[my_head] = ++my_depth[prev]; + my_size++; + } + } + void pop_back() { + __TBB_ASSERT(my_size > 0, "range_vector::pop_back() with empty size"); + my_pool.begin()[my_head].~T(); + my_size--; + my_head = (my_head + MaxCapacity - 1) % MaxCapacity; + } + void pop_front() { + __TBB_ASSERT(my_size > 0, "range_vector::pop_front() with empty size"); + my_pool.begin()[my_tail].~T(); + my_size--; + my_tail = (my_tail + 1) % MaxCapacity; + } + T& back() { + __TBB_ASSERT(my_size > 0, "range_vector::back() with empty size"); + return my_pool.begin()[my_head]; + } + T& front() { + __TBB_ASSERT(my_size > 0, "range_vector::front() with empty size"); + return my_pool.begin()[my_tail]; + } + //! similarly to front(), returns depth of the first range in the pool + depth_t front_depth() { + __TBB_ASSERT(my_size > 0, "range_vector::front_depth() with empty size"); + return my_depth[my_tail]; + } + depth_t back_depth() { + __TBB_ASSERT(my_size > 0, "range_vector::back_depth() with empty size"); + return my_depth[my_head]; + } + bool is_divisible(depth_t max_depth) { + return back_depth() < max_depth && back().is_divisible(); + } +}; + +//! Provides default methods for partition objects and common algorithm blocks. +template +struct partition_type_base { + typedef split split_type; + // decision makers + void set_affinity( task & ) {} + void note_affinity( task::affinity_id ) {} + bool check_being_stolen(task &) { return false; } // part of old should_execute_range() + bool check_for_demand(task &) { return false; } + bool is_divisible() { return true; } // part of old should_execute_range() + depth_t max_depth() { return 0; } + void align_depth(depth_t) { } + template split_type get_split() { return split(); } + Partition& self() { return *static_cast(this); } // CRTP helper + + template + void work_balance(StartType &start, Range &range) { + start.run_body( range ); // simple partitioner goes always here + } + + template + void execute(StartType &start, Range &range) { + // The algorithm in a few words ([]-denotes calls to decision methods of partitioner): + // [If this task is stolen, adjust depth and divisions if necessary, set flag]. + // If range is divisible { + // Spread the work while [initial divisions left]; + // Create trap task [if necessary]; + // } + // If not divisible or [max depth is reached], execute, else do the range pool part + if ( range.is_divisible() ) { + if ( self().is_divisible() ) { + do { // split until is divisible + typename Partition::split_type split_obj = self().template get_split(); + start.offer_work( split_obj ); + } while ( range.is_divisible() && self().is_divisible() ); + } + } + self().work_balance(start, range); + } +}; + +//! Provides default splitting strategy for partition objects. +template +struct adaptive_mode : partition_type_base { + typedef Partition my_partition; + size_t my_divisor; + // For affinity_partitioner, my_divisor indicates the number of affinity array indices the task reserves. + // A task which has only one index must produce the right split without reserved index in order to avoid + // it to be overwritten in note_affinity() of the created (right) task. + // I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order) + static const unsigned factor = 1; + adaptive_mode() : my_divisor(tbb::internal::get_initial_auto_partitioner_divisor() / 4 * my_partition::factor) {} + adaptive_mode(adaptive_mode &src, split) : my_divisor(do_split(src, split())) {} + /*! Override do_split methods in order to specify splitting strategy */ + size_t do_split(adaptive_mode &src, split) { + return src.my_divisor /= 2u; + } +}; + +//! A helper class to create a proportional_split object for a given type of Range. +/** If the Range has static boolean constant 'is_splittable_in_proportion' set to 'true', + the created object splits a provided value in an implemenation-defined proportion; + otherwise it represents equal-size split. */ +// TODO: check if this helper can be a nested class of proportional_mode. +template +struct proportion_helper { + static proportional_split get_split(size_t) { return proportional_split(1,1); } +}; +template +struct proportion_helper::type> { + static proportional_split get_split(size_t n) { +#if __TBB_NONUNIFORM_TASK_CREATION + size_t right = (n + 2) / 3; +#else + size_t right = n / 2; +#endif + size_t left = n - right; + return proportional_split(left, right); + } +}; + +//! Provides proportional splitting strategy for partition objects +template +struct proportional_mode : adaptive_mode { + typedef Partition my_partition; + using partition_type_base::self; // CRTP helper to get access to derived classes + + proportional_mode() : adaptive_mode() {} + proportional_mode(proportional_mode &src, split) : adaptive_mode(src, split()) {} + proportional_mode(proportional_mode &src, const proportional_split& split_obj) { self().my_divisor = do_split(src, split_obj); } + size_t do_split(proportional_mode &src, const proportional_split& split_obj) { +#if __TBB_ENABLE_RANGE_FEEDBACK + size_t portion = size_t(float(src.my_divisor) * float(split_obj.right()) + / float(split_obj.left() + split_obj.right()) + 0.5f); +#else + size_t portion = split_obj.right() * my_partition::factor; +#endif + portion = (portion + my_partition::factor/2) & (0ul - my_partition::factor); +#if __TBB_ENABLE_RANGE_FEEDBACK + /** Corner case handling */ + if (!portion) + portion = my_partition::factor; + else if (portion == src.my_divisor) + portion = src.my_divisor - my_partition::factor; +#endif + src.my_divisor -= portion; + return portion; + } + bool is_divisible() { // part of old should_execute_range() + return self().my_divisor > my_partition::factor; + } + template + proportional_split get_split() { + // Create a proportion for the number of threads expected to handle "this" subrange + return proportion_helper::get_split( self().my_divisor / my_partition::factor ); + } +}; + +static size_t get_initial_partition_head() { + int current_index = tbb::this_task_arena::current_thread_index(); + if (current_index == tbb::task_arena::not_initialized) + current_index = 0; + return size_t(current_index); +} + +//! Provides default linear indexing of partitioner's sequence +template +struct linear_affinity_mode : proportional_mode { + size_t my_head; + size_t my_max_affinity; + using proportional_mode::self; + linear_affinity_mode() : proportional_mode(), my_head(get_initial_partition_head()), + my_max_affinity(self().my_divisor) {} + linear_affinity_mode(linear_affinity_mode &src, split) : proportional_mode(src, split()) + , my_head((src.my_head + src.my_divisor) % src.my_max_affinity), my_max_affinity(src.my_max_affinity) {} + linear_affinity_mode(linear_affinity_mode &src, const proportional_split& split_obj) : proportional_mode(src, split_obj) + , my_head((src.my_head + src.my_divisor) % src.my_max_affinity), my_max_affinity(src.my_max_affinity) {} + void set_affinity( task &t ) { + if( self().my_divisor ) + t.set_affinity( affinity_id(my_head) + 1 ); + } +}; + +/*! Determine work-balance phase implementing splitting & stealing actions */ +template +struct dynamic_grainsize_mode : Mode { + using Mode::self; +#ifdef __TBB_USE_MACHINE_TIME_STAMPS + tbb::internal::machine_tsc_t my_dst_tsc; +#endif + enum { + begin = 0, + run, + pass + } my_delay; + depth_t my_max_depth; + static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY; + dynamic_grainsize_mode(): Mode() +#ifdef __TBB_USE_MACHINE_TIME_STAMPS + , my_dst_tsc(0) +#endif + , my_delay(begin) + , my_max_depth(__TBB_INIT_DEPTH) {} + dynamic_grainsize_mode(dynamic_grainsize_mode& p, split) + : Mode(p, split()) +#ifdef __TBB_USE_MACHINE_TIME_STAMPS + , my_dst_tsc(0) +#endif + , my_delay(pass) + , my_max_depth(p.my_max_depth) {} + dynamic_grainsize_mode(dynamic_grainsize_mode& p, const proportional_split& split_obj) + : Mode(p, split_obj) +#ifdef __TBB_USE_MACHINE_TIME_STAMPS + , my_dst_tsc(0) +#endif + , my_delay(begin) + , my_max_depth(p.my_max_depth) {} + bool check_being_stolen(task &t) { // part of old should_execute_range() + if( !(self().my_divisor / Mode::my_partition::factor) ) { // if not from the top P tasks of binary tree + self().my_divisor = 1; // TODO: replace by on-stack flag (partition_state's member)? + if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // runs concurrently with the left task +#if __TBB_USE_OPTIONAL_RTTI + // RTTI is available, check whether the cast is valid + __TBB_ASSERT(dynamic_cast(t.parent()), 0); + // correctness of the cast relies on avoiding the root task for which: + // - initial value of my_divisor != 0 (protected by separate assertion) + // - is_stolen_task() always returns false for the root task. +#endif + flag_task::mark_task_stolen(t); + if( !my_max_depth ) my_max_depth++; + my_max_depth += __TBB_DEMAND_DEPTH_ADD; + return true; + } + } + return false; + } + depth_t max_depth() { return my_max_depth; } + void align_depth(depth_t base) { + __TBB_ASSERT(base <= my_max_depth, 0); + my_max_depth -= base; + } + template + void work_balance(StartType &start, Range &range) { + if( !range.is_divisible() || !self().max_depth() ) { + start.run_body( range ); // simple partitioner goes always here + } + else { // do range pool + internal::range_vector range_pool(range); + do { + range_pool.split_to_fill(self().max_depth()); // fill range pool + if( self().check_for_demand( start ) ) { + if( range_pool.size() > 1 ) { + start.offer_work( range_pool.front(), range_pool.front_depth() ); + range_pool.pop_front(); + continue; + } + if( range_pool.is_divisible(self().max_depth()) ) // was not enough depth to fork a task + continue; // note: next split_to_fill() should split range at least once + } + start.run_body( range_pool.back() ); + range_pool.pop_back(); + } while( !range_pool.empty() && !start.is_cancelled() ); + } + } + bool check_for_demand( task &t ) { + if( pass == my_delay ) { + if( self().my_divisor > 1 ) // produce affinitized tasks while they have slot in array + return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more + else if( self().my_divisor && my_max_depth ) { // make balancing task + self().my_divisor = 0; // once for each task; depth will be decreased in align_depth() + return true; + } + else if( flag_task::is_peer_stolen(t) ) { + my_max_depth += __TBB_DEMAND_DEPTH_ADD; + return true; + } + } else if( begin == my_delay ) { +#ifndef __TBB_USE_MACHINE_TIME_STAMPS + my_delay = pass; +#else + my_dst_tsc = __TBB_time_stamp() + __TBB_task_duration(); + my_delay = run; + } else if( run == my_delay ) { + if( __TBB_time_stamp() < my_dst_tsc ) { + __TBB_ASSERT(my_max_depth > 0, NULL); + my_max_depth--; // increase granularity since tasks seem having too small work + return false; + } + my_delay = pass; + return true; +#endif // __TBB_USE_MACHINE_TIME_STAMPS + } + return false; + } +}; + +class auto_partition_type: public dynamic_grainsize_mode > { +public: + auto_partition_type( const auto_partitioner& ) + : dynamic_grainsize_mode >() { + my_divisor *= __TBB_INITIAL_CHUNKS; + } + auto_partition_type( auto_partition_type& src, split) + : dynamic_grainsize_mode >(src, split()) {} + bool is_divisible() { // part of old should_execute_range() + if( my_divisor > 1 ) return true; + if( my_divisor && my_max_depth ) { // can split the task. TODO: on-stack flag instead + // keep same fragmentation while splitting for the local task pool + my_max_depth--; + my_divisor = 0; // decrease max_depth once per task + return true; + } else return false; + } + bool check_for_demand(task &t) { + if( flag_task::is_peer_stolen(t) ) { + my_max_depth += __TBB_DEMAND_DEPTH_ADD; + return true; + } else return false; + } +}; + +class simple_partition_type: public partition_type_base { +public: + simple_partition_type( const simple_partitioner& ) {} + simple_partition_type( const simple_partition_type&, split ) {} + //! simplified algorithm + template + void execute(StartType &start, Range &range) { + split_type split_obj = split(); // start.offer_work accepts split_type as reference + while( range.is_divisible() ) + start.offer_work( split_obj ); + start.run_body( range ); + } +}; + +class static_partition_type : public linear_affinity_mode { +public: + typedef proportional_split split_type; + static_partition_type( const static_partitioner& ) + : linear_affinity_mode() {} + static_partition_type( static_partition_type& p, split ) + : linear_affinity_mode(p, split()) {} + static_partition_type( static_partition_type& p, const proportional_split& split_obj ) + : linear_affinity_mode(p, split_obj) {} +}; + +class affinity_partition_type : public dynamic_grainsize_mode > { + static const unsigned factor_power = 4; // TODO: get a unified formula based on number of computing units + tbb::internal::affinity_id* my_array; +public: + static const unsigned factor = 1 << factor_power; // number of slots in affinity array per task + typedef proportional_split split_type; + affinity_partition_type( tbb::internal::affinity_partitioner_base_v3& ap ) + : dynamic_grainsize_mode >() { + __TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" ); + ap.resize(factor); + my_array = ap.my_array; + my_max_depth = factor_power + 1; + __TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 ); + } + affinity_partition_type(affinity_partition_type& p, split) + : dynamic_grainsize_mode >(p, split()) + , my_array(p.my_array) {} + affinity_partition_type(affinity_partition_type& p, const proportional_split& split_obj) + : dynamic_grainsize_mode >(p, split_obj) + , my_array(p.my_array) {} + void set_affinity( task &t ) { + if( my_divisor ) { + if( !my_array[my_head] ) + // TODO: consider new ideas with my_array for both affinity and static partitioner's, then code reuse + t.set_affinity( affinity_id(my_head / factor + 1) ); + else + t.set_affinity( my_array[my_head] ); + } + } + void note_affinity( task::affinity_id id ) { + if( my_divisor ) + my_array[my_head] = id; + } +}; + +//! Backward-compatible partition for auto and affinity partition objects. +class old_auto_partition_type: public tbb::internal::partition_type_base { + size_t num_chunks; + static const size_t VICTIM_CHUNKS = 4; +public: + bool should_execute_range(const task &t) { + if( num_chunks friend class serial::interface9::start_for; + template friend class interface9::internal::start_for; + template friend class interface9::internal::start_reduce; + template friend class interface9::internal::start_deterministic_reduce; + template friend class internal::start_scan; + // backward compatibility + class partition_type: public internal::partition_type_base { + public: + bool should_execute_range(const task& ) {return false;} + partition_type( const simple_partitioner& ) {} + partition_type( const partition_type&, split ) {} + }; + // new implementation just extends existing interface + typedef interface9::internal::simple_partition_type task_partition_type; + + // TODO: consider to make split_type public + typedef interface9::internal::simple_partition_type::split_type split_type; +}; + +//! An auto partitioner +/** The range is initial divided into several large chunks. + Chunks are further subdivided into smaller pieces if demand detected and they are divisible. + @ingroup algorithms */ +class auto_partitioner { +public: + auto_partitioner() {} + +private: + template friend class serial::interface9::start_for; + template friend class interface9::internal::start_for; + template friend class interface9::internal::start_reduce; + template friend class internal::start_scan; + // backward compatibility + typedef interface9::internal::old_auto_partition_type partition_type; + // new implementation just extends existing interface + typedef interface9::internal::auto_partition_type task_partition_type; + + // TODO: consider to make split_type public + typedef interface9::internal::auto_partition_type::split_type split_type; +}; + +//! A static partitioner +class static_partitioner { +public: + static_partitioner() {} +private: + template friend class serial::interface9::start_for; + template friend class interface9::internal::start_for; + template friend class interface9::internal::start_reduce; + template friend class interface9::internal::start_deterministic_reduce; + template friend class internal::start_scan; + // backward compatibility + typedef interface9::internal::old_auto_partition_type partition_type; + // new implementation just extends existing interface + typedef interface9::internal::static_partition_type task_partition_type; + + // TODO: consider to make split_type public + typedef interface9::internal::static_partition_type::split_type split_type; +}; + +//! An affinity partitioner +class affinity_partitioner: internal::affinity_partitioner_base_v3 { +public: + affinity_partitioner() {} + +private: + template friend class serial::interface9::start_for; + template friend class interface9::internal::start_for; + template friend class interface9::internal::start_reduce; + template friend class internal::start_scan; + // backward compatibility - for parallel_scan only + typedef interface9::internal::old_auto_partition_type partition_type; + // new implementation just extends existing interface + typedef interface9::internal::affinity_partition_type task_partition_type; + + // TODO: consider to make split_type public + typedef interface9::internal::affinity_partition_type::split_type split_type; +}; + +} // namespace tbb + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warning 4244 is back +#undef __TBB_INITIAL_CHUNKS +#undef __TBB_RANGE_POOL_CAPACITY +#undef __TBB_INIT_DEPTH + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_partitioner_H_include_area + +#endif /* __TBB_partitioner_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/pipeline.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/pipeline.h new file mode 100644 index 00000000..b8212ddb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/pipeline.h @@ -0,0 +1,689 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_pipeline_H +#define __TBB_pipeline_H + +#define __TBB_pipeline_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "atomic.h" +#include "task.h" +#include "tbb_allocator.h" +#include + +#if __TBB_CPP11_TYPE_PROPERTIES_PRESENT +#include +#endif + +namespace tbb { + +class pipeline; +class filter; + +//! @cond INTERNAL +namespace internal { + +// The argument for PIPELINE_VERSION should be an integer between 2 and 9 +#define __TBB_PIPELINE_VERSION(x) ((unsigned char)(x-2)<<1) + +typedef unsigned long Token; +typedef long tokendiff_t; +class stage_task; +class input_buffer; +class pipeline_root_task; +class pipeline_cleaner; + +} // namespace internal + +namespace interface6 { + template class filter_t; + + namespace internal { + class pipeline_proxy; + } +} + +//! @endcond + +//! A stage in a pipeline. +/** @ingroup algorithms */ +class filter: internal::no_copy { +private: + //! Value used to mark "not in pipeline" + static filter* not_in_pipeline() { return reinterpret_cast(intptr_t(-1)); } +protected: + //! The lowest bit 0 is for parallel vs. serial + static const unsigned char filter_is_serial = 0x1; + + //! 4th bit distinguishes ordered vs unordered filters. + /** The bit was not set for parallel filters in TBB 2.1 and earlier, + but is_ordered() function always treats parallel filters as out of order. */ + static const unsigned char filter_is_out_of_order = 0x1<<4; + + //! 5th bit distinguishes thread-bound and regular filters. + static const unsigned char filter_is_bound = 0x1<<5; + + //! 6th bit marks input filters emitting small objects + static const unsigned char filter_may_emit_null = 0x1<<6; + + //! 7th bit defines exception propagation mode expected by the application. + static const unsigned char exact_exception_propagation = +#if TBB_USE_CAPTURED_EXCEPTION + 0x0; +#else + 0x1<<7; +#endif /* TBB_USE_CAPTURED_EXCEPTION */ + + static const unsigned char current_version = __TBB_PIPELINE_VERSION(5); + static const unsigned char version_mask = 0x7<<1; // bits 1-3 are for version +public: + enum mode { + //! processes multiple items in parallel and in no particular order + parallel = current_version | filter_is_out_of_order, + //! processes items one at a time; all such filters process items in the same order + serial_in_order = current_version | filter_is_serial, + //! processes items one at a time and in no particular order + serial_out_of_order = current_version | filter_is_serial | filter_is_out_of_order, + //! @deprecated use serial_in_order instead + serial = serial_in_order + }; +protected: + explicit filter( bool is_serial_ ) : + next_filter_in_pipeline(not_in_pipeline()), + my_input_buffer(NULL), + my_filter_mode(static_cast((is_serial_ ? serial : parallel) | exact_exception_propagation)), + prev_filter_in_pipeline(not_in_pipeline()), + my_pipeline(NULL), + next_segment(NULL) + {} + + explicit filter( mode filter_mode ) : + next_filter_in_pipeline(not_in_pipeline()), + my_input_buffer(NULL), + my_filter_mode(static_cast(filter_mode | exact_exception_propagation)), + prev_filter_in_pipeline(not_in_pipeline()), + my_pipeline(NULL), + next_segment(NULL) + {} + + // signal end-of-input for concrete_filters + void __TBB_EXPORTED_METHOD set_end_of_input(); + +public: + //! True if filter is serial. + bool is_serial() const { + return bool( my_filter_mode & filter_is_serial ); + } + + //! True if filter must receive stream in order. + bool is_ordered() const { + return (my_filter_mode & (filter_is_out_of_order|filter_is_serial))==filter_is_serial; + } + + //! True if filter is thread-bound. + bool is_bound() const { + return ( my_filter_mode & filter_is_bound )==filter_is_bound; + } + + //! true if an input filter can emit null + bool object_may_be_null() { + return ( my_filter_mode & filter_may_emit_null ) == filter_may_emit_null; + } + + //! Operate on an item from the input stream, and return item for output stream. + /** Returns NULL if filter is a sink. */ + virtual void* operator()( void* item ) = 0; + + //! Destroy filter. + /** If the filter was added to a pipeline, the pipeline must be destroyed first. */ + virtual __TBB_EXPORTED_METHOD ~filter(); + +#if __TBB_TASK_GROUP_CONTEXT + //! Destroys item if pipeline was cancelled. + /** Required to prevent memory leaks. + Note it can be called concurrently even for serial filters.*/ + virtual void finalize( void* /*item*/ ) {} +#endif + +private: + //! Pointer to next filter in the pipeline. + filter* next_filter_in_pipeline; + + //! has the filter not yet processed all the tokens it will ever see? + // (pipeline has not yet reached end_of_input or this filter has not yet + // seen the last token produced by input_filter) + bool has_more_work(); + + //! Buffer for incoming tokens, or NULL if not required. + /** The buffer is required if the filter is serial or follows a thread-bound one. */ + internal::input_buffer* my_input_buffer; + + friend class internal::stage_task; + friend class internal::pipeline_root_task; + friend class pipeline; + friend class thread_bound_filter; + + //! Storage for filter mode and dynamically checked implementation version. + const unsigned char my_filter_mode; + + //! Pointer to previous filter in the pipeline. + filter* prev_filter_in_pipeline; + + //! Pointer to the pipeline. + pipeline* my_pipeline; + + //! Pointer to the next "segment" of filters, or NULL if not required. + /** In each segment, the first filter is not thread-bound but follows a thread-bound one. */ + filter* next_segment; +}; + +//! A stage in a pipeline served by a user thread. +/** @ingroup algorithms */ +class thread_bound_filter: public filter { +public: + enum result_type { + // item was processed + success, + // item is currently not available + item_not_available, + // there are no more items to process + end_of_stream + }; +protected: + explicit thread_bound_filter(mode filter_mode): + filter(static_cast(filter_mode | filter::filter_is_bound)) + { + __TBB_ASSERT(filter_mode & filter::filter_is_serial, "thread-bound filters must be serial"); + } +public: + //! If a data item is available, invoke operator() on that item. + /** This interface is non-blocking. + Returns 'success' if an item was processed. + Returns 'item_not_available' if no item can be processed now + but more may arrive in the future, or if token limit is reached. + Returns 'end_of_stream' if there are no more items to process. */ + result_type __TBB_EXPORTED_METHOD try_process_item(); + + //! Wait until a data item becomes available, and invoke operator() on that item. + /** This interface is blocking. + Returns 'success' if an item was processed. + Returns 'end_of_stream' if there are no more items to process. + Never returns 'item_not_available', as it blocks until another return condition applies. */ + result_type __TBB_EXPORTED_METHOD process_item(); + +private: + //! Internal routine for item processing + result_type internal_process_item(bool is_blocking); +}; + +//! A processing pipeline that applies filters to items. +/** @ingroup algorithms */ +class __TBB_DEPRECATED_MSG("tbb::pipeline is deprecated, use tbb::parallel_pipeline") pipeline { +public: + //! Construct empty pipeline. + __TBB_EXPORTED_METHOD pipeline(); + + /** Though the current implementation declares the destructor virtual, do not rely on this + detail. The virtualness is deprecated and may disappear in future versions of TBB. */ + virtual __TBB_EXPORTED_METHOD ~pipeline(); + + //! Add filter to end of pipeline. + void __TBB_EXPORTED_METHOD add_filter( filter& filter_ ); + + //! Run the pipeline to completion. + void __TBB_EXPORTED_METHOD run( size_t max_number_of_live_tokens ); + +#if __TBB_TASK_GROUP_CONTEXT + //! Run the pipeline to completion with user-supplied context. + void __TBB_EXPORTED_METHOD run( size_t max_number_of_live_tokens, tbb::task_group_context& context ); +#endif + + //! Remove all filters from the pipeline. + void __TBB_EXPORTED_METHOD clear(); + +private: + friend class internal::stage_task; + friend class internal::pipeline_root_task; + friend class filter; + friend class thread_bound_filter; + friend class internal::pipeline_cleaner; + friend class tbb::interface6::internal::pipeline_proxy; + + //! Pointer to first filter in the pipeline. + filter* filter_list; + + //! Pointer to location where address of next filter to be added should be stored. + filter* filter_end; + + //! task who's reference count is used to determine when all stages are done. + task* end_counter; + + //! Number of idle tokens waiting for input stage. + atomic input_tokens; + + //! Global counter of tokens + atomic token_counter; + + //! False until fetch_input returns NULL. + bool end_of_input; + + //! True if the pipeline contains a thread-bound filter; false otherwise. + bool has_thread_bound_filters; + + //! Remove filter from pipeline. + void remove_filter( filter& filter_ ); + + //! Not used, but retained to satisfy old export files. + void __TBB_EXPORTED_METHOD inject_token( task& self ); + +#if __TBB_TASK_GROUP_CONTEXT + //! Does clean up if pipeline is cancelled or exception occurred + void clear_filters(); +#endif +}; + +//------------------------------------------------------------------------ +// Support for lambda-friendly parallel_pipeline interface +//------------------------------------------------------------------------ + +namespace flow { +namespace interface11 { + template class input_node; +} +} + +namespace interface6 { + +namespace internal { + template class concrete_filter; +} + +//! input_filter control to signal end-of-input for parallel_pipeline +class flow_control { + bool is_pipeline_stopped; + flow_control() { is_pipeline_stopped = false; } + template friend class internal::concrete_filter; + template friend class flow::interface11::input_node; +public: + void stop() { is_pipeline_stopped = true; } +}; + +//! @cond INTERNAL +namespace internal { + +// Emulate std::is_trivially_copyable (false positives not allowed, false negatives suboptimal but safe). +#if __TBB_CPP11_TYPE_PROPERTIES_PRESENT +template struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable::value }; }; +#else +template struct tbb_trivially_copyable { enum { value = false }; }; +template struct tbb_trivially_copyable < T* > { enum { value = true }; }; +template<> struct tbb_trivially_copyable < bool > { enum { value = true }; }; +template<> struct tbb_trivially_copyable < char > { enum { value = true }; }; +template<> struct tbb_trivially_copyable < signed char > { enum { value = true }; }; +template<> struct tbb_trivially_copyable { enum { value = true }; }; +template<> struct tbb_trivially_copyable < short > { enum { value = true }; }; +template<> struct tbb_trivially_copyable { enum { value = true }; }; +template<> struct tbb_trivially_copyable < int > { enum { value = true }; }; +template<> struct tbb_trivially_copyable { enum { value = true }; }; +template<> struct tbb_trivially_copyable < long > { enum { value = true }; }; +template<> struct tbb_trivially_copyable { enum { value = true }; }; +template<> struct tbb_trivially_copyable < long long> { enum { value = true }; }; +template<> struct tbb_trivially_copyable { enum { value = true }; }; +template<> struct tbb_trivially_copyable < float > { enum { value = true }; }; +template<> struct tbb_trivially_copyable < double > { enum { value = true }; }; +template<> struct tbb_trivially_copyable < long double > { enum { value = true }; }; +#if !_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED) +template<> struct tbb_trivially_copyable < wchar_t > { enum { value = true }; }; +#endif /* _MSC_VER||!defined(_NATIVE_WCHAR_T_DEFINED) */ +#endif // tbb_trivially_copyable + +template +struct use_allocator { + enum { value = sizeof(T) > sizeof(void *) || !tbb_trivially_copyable::value }; +}; + +// A helper class to customize how a type is passed between filters. +// Usage: token_helper::value> +template class token_helper; + +// using tbb_allocator +template +class token_helper { +public: + typedef typename tbb::tbb_allocator allocator; + typedef T* pointer; + typedef T value_type; +#if __TBB_CPP11_RVALUE_REF_PRESENT + static pointer create_token(value_type && source) +#else + static pointer create_token(const value_type & source) +#endif + { + pointer output_t = allocator().allocate(1); + return new (output_t) T(tbb::internal::move(source)); + } + static value_type & token(pointer & t) { return *t; } + static void * cast_to_void_ptr(pointer ref) { return (void *) ref; } + static pointer cast_from_void_ptr(void * ref) { return (pointer)ref; } + static void destroy_token(pointer token) { + allocator().destroy(token); + allocator().deallocate(token,1); + } +}; + +// pointer specialization +template +class token_helper { +public: + typedef T* pointer; + typedef T* value_type; + static pointer create_token(const value_type & source) { return source; } + static value_type & token(pointer & t) { return t; } + static void * cast_to_void_ptr(pointer ref) { return (void *)ref; } + static pointer cast_from_void_ptr(void * ref) { return (pointer)ref; } + static void destroy_token( pointer /*token*/) {} +}; + +// converting type to and from void*, passing objects directly +template +class token_helper { + typedef union { + T actual_value; + void * void_overlay; + } type_to_void_ptr_map; +public: + typedef T pointer; // not really a pointer in this case. + typedef T value_type; + static pointer create_token(const value_type & source) { return source; } + static value_type & token(pointer & t) { return t; } + static void * cast_to_void_ptr(pointer ref) { + type_to_void_ptr_map mymap; + mymap.void_overlay = NULL; + mymap.actual_value = ref; + return mymap.void_overlay; + } + static pointer cast_from_void_ptr(void * ref) { + type_to_void_ptr_map mymap; + mymap.void_overlay = ref; + return mymap.actual_value; + } + static void destroy_token( pointer /*token*/) {} +}; + +// intermediate +template +class concrete_filter: public tbb::filter { + const Body& my_body; + typedef token_helper::value> t_helper; + typedef typename t_helper::pointer t_pointer; + typedef token_helper::value> u_helper; + typedef typename u_helper::pointer u_pointer; + + void* operator()(void* input) __TBB_override { + t_pointer temp_input = t_helper::cast_from_void_ptr(input); + u_pointer output_u = u_helper::create_token(my_body(tbb::internal::move(t_helper::token(temp_input)))); + t_helper::destroy_token(temp_input); + return u_helper::cast_to_void_ptr(output_u); + } + + void finalize(void * input) __TBB_override { + t_pointer temp_input = t_helper::cast_from_void_ptr(input); + t_helper::destroy_token(temp_input); + } + +public: + concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} +}; + +// input +template +class concrete_filter: public filter { + const Body& my_body; + typedef token_helper::value> u_helper; + typedef typename u_helper::pointer u_pointer; + + void* operator()(void*) __TBB_override { + flow_control control; + u_pointer output_u = u_helper::create_token(my_body(control)); + if(control.is_pipeline_stopped) { + u_helper::destroy_token(output_u); + set_end_of_input(); + return NULL; + } + return u_helper::cast_to_void_ptr(output_u); + } + +public: + concrete_filter(tbb::filter::mode filter_mode, const Body& body) : + filter(static_cast(filter_mode | filter_may_emit_null)), + my_body(body) + {} +}; + +// output +template +class concrete_filter: public filter { + const Body& my_body; + typedef token_helper::value> t_helper; + typedef typename t_helper::pointer t_pointer; + + void* operator()(void* input) __TBB_override { + t_pointer temp_input = t_helper::cast_from_void_ptr(input); + my_body(tbb::internal::move(t_helper::token(temp_input))); + t_helper::destroy_token(temp_input); + return NULL; + } + void finalize(void* input) __TBB_override { + t_pointer temp_input = t_helper::cast_from_void_ptr(input); + t_helper::destroy_token(temp_input); + } + +public: + concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} +}; + +template +class concrete_filter: public filter { + const Body& my_body; + + void* operator()(void*) __TBB_override { + flow_control control; + my_body(control); + void* output = control.is_pipeline_stopped ? NULL : (void*)(intptr_t)-1; + return output; + } +public: + concrete_filter(filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {} +}; + +//! The class that represents an object of the pipeline for parallel_pipeline(). +/** It primarily serves as RAII class that deletes heap-allocated filter instances. */ +class pipeline_proxy { + tbb::pipeline my_pipe; +public: + pipeline_proxy( const filter_t& filter_chain ); + ~pipeline_proxy() { + while( filter* f = my_pipe.filter_list ) + delete f; // filter destructor removes it from the pipeline + } + tbb::pipeline* operator->() { return &my_pipe; } +}; + +//! Abstract base class that represents a node in a parse tree underlying a filter_t. +/** These nodes are always heap-allocated and can be shared by filter_t objects. */ +class filter_node: tbb::internal::no_copy { + /** Count must be atomic because it is hidden state for user, but might be shared by threads. */ + tbb::atomic ref_count; +protected: + filter_node() { + ref_count = 0; +#ifdef __TBB_TEST_FILTER_NODE_COUNT + ++(__TBB_TEST_FILTER_NODE_COUNT); +#endif + } +public: + //! Add concrete_filter to pipeline + virtual void add_to( pipeline& ) = 0; + //! Increment reference count + void add_ref() { ++ref_count; } + //! Decrement reference count and delete if it becomes zero. + void remove_ref() { + __TBB_ASSERT(ref_count>0,"ref_count underflow"); + if( --ref_count==0 ) + delete this; + } + virtual ~filter_node() { +#ifdef __TBB_TEST_FILTER_NODE_COUNT + --(__TBB_TEST_FILTER_NODE_COUNT); +#endif + } +}; + +//! Node in parse tree representing result of make_filter. +template +class filter_node_leaf: public filter_node { + const tbb::filter::mode mode; + const Body body; + void add_to( pipeline& p ) __TBB_override { + concrete_filter* f = new concrete_filter(mode,body); + p.add_filter( *f ); + } +public: + filter_node_leaf( tbb::filter::mode m, const Body& b ) : mode(m), body(b) {} +}; + +//! Node in parse tree representing join of two filters. +class filter_node_join: public filter_node { + friend class filter_node; // to suppress GCC 3.2 warnings + filter_node& left; + filter_node& right; + ~filter_node_join() { + left.remove_ref(); + right.remove_ref(); + } + void add_to( pipeline& p ) __TBB_override { + left.add_to(p); + right.add_to(p); + } +public: + filter_node_join( filter_node& x, filter_node& y ) : left(x), right(y) { + left.add_ref(); + right.add_ref(); + } +}; + +} // namespace internal +//! @endcond + +//! Create a filter to participate in parallel_pipeline +template +filter_t make_filter(tbb::filter::mode mode, const Body& body) { + return new internal::filter_node_leaf(mode, body); +} + +template +filter_t operator& (const filter_t& left, const filter_t& right) { + __TBB_ASSERT(left.root,"cannot use default-constructed filter_t as left argument of '&'"); + __TBB_ASSERT(right.root,"cannot use default-constructed filter_t as right argument of '&'"); + return new internal::filter_node_join(*left.root,*right.root); +} + +//! Class representing a chain of type-safe pipeline filters +template +class filter_t { + typedef internal::filter_node filter_node; + filter_node* root; + filter_t( filter_node* root_ ) : root(root_) { + root->add_ref(); + } + friend class internal::pipeline_proxy; + template + friend filter_t make_filter(tbb::filter::mode, const Body& ); + template + friend filter_t operator& (const filter_t& , const filter_t& ); +public: + // TODO: add move-constructors, move-assignment, etc. where C++11 is available. + filter_t() : root(NULL) {} + filter_t( const filter_t& rhs ) : root(rhs.root) { + if( root ) root->add_ref(); + } + template + filter_t( tbb::filter::mode mode, const Body& body ) : + root( new internal::filter_node_leaf(mode, body) ) { + root->add_ref(); + } + + void operator=( const filter_t& rhs ) { + // Order of operations below carefully chosen so that reference counts remain correct + // in unlikely event that remove_ref throws exception. + filter_node* old = root; + root = rhs.root; + if( root ) root->add_ref(); + if( old ) old->remove_ref(); + } + ~filter_t() { + if( root ) root->remove_ref(); + } + void clear() { + // Like operator= with filter_t() on right side. + if( root ) { + filter_node* old = root; + root = NULL; + old->remove_ref(); + } + } +}; + +inline internal::pipeline_proxy::pipeline_proxy( const filter_t& filter_chain ) : my_pipe() { + __TBB_ASSERT( filter_chain.root, "cannot apply parallel_pipeline to default-constructed filter_t" ); + filter_chain.root->add_to(my_pipe); +} + +inline void parallel_pipeline(size_t max_number_of_live_tokens, const filter_t& filter_chain +#if __TBB_TASK_GROUP_CONTEXT + , tbb::task_group_context& context +#endif + ) { + internal::pipeline_proxy pipe(filter_chain); + // tbb::pipeline::run() is called via the proxy + pipe->run(max_number_of_live_tokens +#if __TBB_TASK_GROUP_CONTEXT + , context +#endif + ); +} + +#if __TBB_TASK_GROUP_CONTEXT +inline void parallel_pipeline(size_t max_number_of_live_tokens, const filter_t& filter_chain) { + tbb::task_group_context context; + parallel_pipeline(max_number_of_live_tokens, filter_chain, context); +} +#endif // __TBB_TASK_GROUP_CONTEXT + +} // interface6 + +using interface6::flow_control; +using interface6::filter_t; +using interface6::make_filter; +using interface6::parallel_pipeline; + +} // tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_pipeline_H_include_area + +#endif /* __TBB_pipeline_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/queuing_mutex.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/queuing_mutex.h new file mode 100644 index 00000000..c5c64993 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/queuing_mutex.h @@ -0,0 +1,113 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_queuing_mutex_H +#define __TBB_queuing_mutex_H + +#define __TBB_queuing_mutex_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include +#include "atomic.h" +#include "tbb_profiling.h" + +namespace tbb { + +//! Queuing mutex with local-only spinning. +/** @ingroup synchronization */ +class queuing_mutex : internal::mutex_copy_deprecated_and_disabled { +public: + //! Construct unacquired mutex. + queuing_mutex() { + q_tail = NULL; +#if TBB_USE_THREADING_TOOLS + internal_construct(); +#endif + } + + //! The scoped locking pattern + /** It helps to avoid the common problem of forgetting to release lock. + It also nicely provides the "node" for queuing locks. */ + class scoped_lock: internal::no_copy { + //! Initialize fields to mean "no lock held". + void initialize() { + mutex = NULL; + going = 0; +#if TBB_USE_ASSERT + internal::poison_pointer(next); +#endif /* TBB_USE_ASSERT */ + } + + public: + //! Construct lock that has not acquired a mutex. + /** Equivalent to zero-initialization of *this. */ + scoped_lock() {initialize();} + + //! Acquire lock on given mutex. + scoped_lock( queuing_mutex& m ) { + initialize(); + acquire(m); + } + + //! Release lock (if lock is held). + ~scoped_lock() { + if( mutex ) release(); + } + + //! Acquire lock on given mutex. + void __TBB_EXPORTED_METHOD acquire( queuing_mutex& m ); + + //! Acquire lock on given mutex if free (i.e. non-blocking) + bool __TBB_EXPORTED_METHOD try_acquire( queuing_mutex& m ); + + //! Release lock. + void __TBB_EXPORTED_METHOD release(); + + private: + //! The pointer to the mutex owned, or NULL if not holding a mutex. + queuing_mutex* mutex; + + //! The pointer to the next competitor for a mutex + scoped_lock *next; + + //! The local spin-wait variable + /** Inverted (0 - blocked, 1 - acquired the mutex) for the sake of + zero-initialization. Defining it as an entire word instead of + a byte seems to help performance slightly. */ + uintptr_t going; + }; + + void __TBB_EXPORTED_METHOD internal_construct(); + + // Mutex traits + static const bool is_rw_mutex = false; + static const bool is_recursive_mutex = false; + static const bool is_fair_mutex = true; + +private: + //! The last competitor requesting the lock + atomic q_tail; + +}; + +__TBB_DEFINE_PROFILING_SET_NAME(queuing_mutex) + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_queuing_mutex_H_include_area + +#endif /* __TBB_queuing_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/queuing_rw_mutex.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/queuing_rw_mutex.h new file mode 100644 index 00000000..b264141c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/queuing_rw_mutex.h @@ -0,0 +1,154 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_queuing_rw_mutex_H +#define __TBB_queuing_rw_mutex_H + +#define __TBB_queuing_rw_mutex_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include +#include "atomic.h" +#include "tbb_profiling.h" + +namespace tbb { + +//! Queuing reader-writer mutex with local-only spinning. +/** Adapted from Krieger, Stumm, et al. pseudocode at + http://www.eecg.toronto.edu/parallel/pubs_abs.html#Krieger_etal_ICPP93 + @ingroup synchronization */ +class queuing_rw_mutex : internal::mutex_copy_deprecated_and_disabled { +public: + //! Construct unacquired mutex. + queuing_rw_mutex() { + q_tail = NULL; +#if TBB_USE_THREADING_TOOLS + internal_construct(); +#endif + } + + //! Destructor asserts if the mutex is acquired, i.e. q_tail is non-NULL + ~queuing_rw_mutex() { +#if TBB_USE_ASSERT + __TBB_ASSERT( !q_tail, "destruction of an acquired mutex"); +#endif + } + + //! The scoped locking pattern + /** It helps to avoid the common problem of forgetting to release lock. + It also nicely provides the "node" for queuing locks. */ + class scoped_lock: internal::no_copy { + //! Initialize fields to mean "no lock held". + void initialize() { + my_mutex = NULL; + my_internal_lock = 0; + my_going = 0; +#if TBB_USE_ASSERT + my_state = 0xFF; // Set to invalid state + internal::poison_pointer(my_next); + internal::poison_pointer(my_prev); +#endif /* TBB_USE_ASSERT */ + } + + public: + //! Construct lock that has not acquired a mutex. + /** Equivalent to zero-initialization of *this. */ + scoped_lock() {initialize();} + + //! Acquire lock on given mutex. + scoped_lock( queuing_rw_mutex& m, bool write=true ) { + initialize(); + acquire(m,write); + } + + //! Release lock (if lock is held). + ~scoped_lock() { + if( my_mutex ) release(); + } + + //! Acquire lock on given mutex. + void acquire( queuing_rw_mutex& m, bool write=true ); + + //! Acquire lock on given mutex if free (i.e. non-blocking) + bool try_acquire( queuing_rw_mutex& m, bool write=true ); + + //! Release lock. + void release(); + + //! Upgrade reader to become a writer. + /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ + bool upgrade_to_writer(); + + //! Downgrade writer to become a reader. + bool downgrade_to_reader(); + + private: + //! The pointer to the mutex owned, or NULL if not holding a mutex. + queuing_rw_mutex* my_mutex; + + //! The pointer to the previous and next competitors for a mutex + scoped_lock *__TBB_atomic my_prev, *__TBB_atomic my_next; + + typedef unsigned char state_t; + + //! State of the request: reader, writer, active reader, other service states + atomic my_state; + + //! The local spin-wait variable + /** Corresponds to "spin" in the pseudocode but inverted for the sake of zero-initialization */ + unsigned char __TBB_atomic my_going; + + //! A tiny internal lock + unsigned char my_internal_lock; + + //! Acquire the internal lock + void acquire_internal_lock(); + + //! Try to acquire the internal lock + /** Returns true if lock was successfully acquired. */ + bool try_acquire_internal_lock(); + + //! Release the internal lock + void release_internal_lock(); + + //! Wait for internal lock to be released + void wait_for_release_of_internal_lock(); + + //! A helper function + void unblock_or_wait_on_internal_lock( uintptr_t ); + }; + + void __TBB_EXPORTED_METHOD internal_construct(); + + // Mutex traits + static const bool is_rw_mutex = true; + static const bool is_recursive_mutex = false; + static const bool is_fair_mutex = true; + +private: + //! The last competitor requesting the lock + atomic q_tail; + +}; + +__TBB_DEFINE_PROFILING_SET_NAME(queuing_rw_mutex) + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_queuing_rw_mutex_H_include_area + +#endif /* __TBB_queuing_rw_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/reader_writer_lock.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/reader_writer_lock.h new file mode 100644 index 00000000..509ff7b7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/reader_writer_lock.h @@ -0,0 +1,246 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_reader_writer_lock_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_reader_writer_lock_H +#pragma message("TBB Warning: tbb/reader_writer_lock.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_reader_writer_lock_H +#define __TBB_reader_writer_lock_H + +#define __TBB_reader_writer_lock_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_thread.h" +#include "tbb_allocator.h" +#include "atomic.h" + +namespace tbb { +namespace interface5 { +//! Writer-preference reader-writer lock with local-only spinning on readers. +/** Loosely adapted from Mellor-Crummey and Scott pseudocode at + http://www.cs.rochester.edu/research/synchronization/pseudocode/rw.html#s_wp + @ingroup synchronization */ + class __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::reader_writer_lock is deprecated, use std::shared_mutex") + reader_writer_lock : tbb::internal::no_copy { + public: + friend class scoped_lock; + friend class scoped_lock_read; + //! Status type for nodes associated with lock instances + /** waiting_nonblocking: the wait state for nonblocking lock + instances; for writes, these transition straight to active + states; for reads, these are unused. + + waiting: the start and spin state for all lock instances; these will + transition to active state when appropriate. Non-blocking write locks + transition from this state to waiting_nonblocking immediately. + + active: the active state means that the lock instance holds + the lock; it will transition to invalid state during node deletion + + invalid: the end state for all nodes; this is set in the + destructor so if we encounter this state, we are looking at + memory that has already been freed + + The state diagrams below describe the status transitions. + Single arrows indicate that the thread that owns the node is + responsible for the transition; double arrows indicate that + any thread could make the transition. + + State diagram for scoped_lock status: + + waiting ----------> waiting_nonblocking + | _____________/ | + V V V + active -----------------> invalid + + State diagram for scoped_lock_read status: + + waiting + | + V + active ----------------->invalid + + */ + enum status_t { waiting_nonblocking, waiting, active, invalid }; + + //! Constructs a new reader_writer_lock + reader_writer_lock() { + internal_construct(); + } + + //! Destructs a reader_writer_lock object + ~reader_writer_lock() { + internal_destroy(); + } + + //! The scoped lock pattern for write locks + /** Scoped locks help avoid the common problem of forgetting to release the lock. + This type also serves as the node for queuing locks. */ + class scoped_lock : tbb::internal::no_copy { + public: + friend class reader_writer_lock; + + //! Construct with blocking attempt to acquire write lock on the passed-in lock + scoped_lock(reader_writer_lock& lock) { + internal_construct(lock); + } + + //! Destructor, releases the write lock + ~scoped_lock() { + internal_destroy(); + } + + void* operator new(size_t s) { + return tbb::internal::allocate_via_handler_v3(s); + } + void operator delete(void* p) { + tbb::internal::deallocate_via_handler_v3(p); + } + + private: + //! The pointer to the mutex to lock + reader_writer_lock *mutex; + //! The next queued competitor for the mutex + scoped_lock* next; + //! Status flag of the thread associated with this node + atomic status; + + //! Construct scoped_lock that is not holding lock + scoped_lock(); + + void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&); + void __TBB_EXPORTED_METHOD internal_destroy(); + }; + + //! The scoped lock pattern for read locks + class scoped_lock_read : tbb::internal::no_copy { + public: + friend class reader_writer_lock; + + //! Construct with blocking attempt to acquire read lock on the passed-in lock + scoped_lock_read(reader_writer_lock& lock) { + internal_construct(lock); + } + + //! Destructor, releases the read lock + ~scoped_lock_read() { + internal_destroy(); + } + + void* operator new(size_t s) { + return tbb::internal::allocate_via_handler_v3(s); + } + void operator delete(void* p) { + tbb::internal::deallocate_via_handler_v3(p); + } + + private: + //! The pointer to the mutex to lock + reader_writer_lock *mutex; + //! The next queued competitor for the mutex + scoped_lock_read *next; + //! Status flag of the thread associated with this node + atomic status; + + //! Construct scoped_lock_read that is not holding lock + scoped_lock_read(); + + void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&); + void __TBB_EXPORTED_METHOD internal_destroy(); + }; + + //! Acquires the reader_writer_lock for write. + /** If the lock is currently held in write mode by another + context, the writer will block by spinning on a local + variable. Exceptions thrown: improper_lock The context tries + to acquire a reader_writer_lock that it already has write + ownership of.*/ + void __TBB_EXPORTED_METHOD lock(); + + //! Tries to acquire the reader_writer_lock for write. + /** This function does not block. Return Value: True or false, + depending on whether the lock is acquired or not. If the lock + is already held by this acquiring context, try_lock() returns + false. */ + bool __TBB_EXPORTED_METHOD try_lock(); + + //! Acquires the reader_writer_lock for read. + /** If the lock is currently held by a writer, this reader will + block and wait until the writers are done. Exceptions thrown: + improper_lock The context tries to acquire a + reader_writer_lock that it already has write ownership of. */ + void __TBB_EXPORTED_METHOD lock_read(); + + //! Tries to acquire the reader_writer_lock for read. + /** This function does not block. Return Value: True or false, + depending on whether the lock is acquired or not. */ + bool __TBB_EXPORTED_METHOD try_lock_read(); + + //! Releases the reader_writer_lock + void __TBB_EXPORTED_METHOD unlock(); + + private: + void __TBB_EXPORTED_METHOD internal_construct(); + void __TBB_EXPORTED_METHOD internal_destroy(); + + //! Attempts to acquire write lock + /** If unavailable, spins in blocking case, returns false in non-blocking case. */ + bool start_write(scoped_lock *); + //! Sets writer_head to w and attempts to unblock + void set_next_writer(scoped_lock *w); + //! Relinquishes write lock to next waiting writer or group of readers + void end_write(scoped_lock *); + //! Checks if current thread holds write lock + bool is_current_writer(); + + //! Attempts to acquire read lock + /** If unavailable, spins in blocking case, returns false in non-blocking case. */ + void start_read(scoped_lock_read *); + //! Unblocks pending readers + void unblock_readers(); + //! Relinquishes read lock by decrementing counter; last reader wakes pending writer + void end_read(); + + //! The list of pending readers + atomic reader_head; + //! The list of pending writers + atomic writer_head; + //! The last node in the list of pending writers + atomic writer_tail; + //! Writer that owns the mutex; tbb_thread::id() otherwise. + tbb_thread::id my_current_writer; + //! Status of mutex + atomic rdr_count_and_flags; // used with __TBB_AtomicOR, which assumes uintptr_t +}; + +} // namespace interface5 + +using interface5::reader_writer_lock; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_reader_writer_lock_H_include_area + +#endif /* __TBB_reader_writer_lock_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/recursive_mutex.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/recursive_mutex.h new file mode 100644 index 00000000..d5be2c4f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/recursive_mutex.h @@ -0,0 +1,248 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_recursive_mutex_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_recursive_mutex_H +#pragma message("TBB Warning: tbb/recursive_mutex.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_recursive_mutex_H +#define __TBB_recursive_mutex_H + +#define __TBB_recursive_mutex_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#if _WIN32||_WIN64 +#include "machine/windows_api.h" +#else +#include +#endif /* _WIN32||_WIN64 */ + +#include +#include "aligned_space.h" +#include "tbb_stddef.h" +#include "tbb_profiling.h" + +namespace tbb { +//! Mutex that allows recursive mutex acquisition. +/** Mutex that allows recursive mutex acquisition. + @ingroup synchronization */ +class __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::recursive_mutex is deprecated, use std::recursive_mutex") +recursive_mutex : internal::mutex_copy_deprecated_and_disabled { +public: + //! Construct unacquired recursive_mutex. + recursive_mutex() { +#if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS + internal_construct(); +#else + #if _WIN32||_WIN64 + InitializeCriticalSectionEx(&impl, 4000, 0); + #else + pthread_mutexattr_t mtx_attr; + int error_code = pthread_mutexattr_init( &mtx_attr ); + if( error_code ) + tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutexattr_init failed"); + + pthread_mutexattr_settype( &mtx_attr, PTHREAD_MUTEX_RECURSIVE ); + error_code = pthread_mutex_init( &impl, &mtx_attr ); + if( error_code ) + tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_init failed"); + + pthread_mutexattr_destroy( &mtx_attr ); + #endif /* _WIN32||_WIN64*/ +#endif /* TBB_USE_ASSERT */ + }; + + ~recursive_mutex() { +#if TBB_USE_ASSERT + internal_destroy(); +#else + #if _WIN32||_WIN64 + DeleteCriticalSection(&impl); + #else + pthread_mutex_destroy(&impl); + + #endif /* _WIN32||_WIN64 */ +#endif /* TBB_USE_ASSERT */ + }; + + class scoped_lock; + friend class scoped_lock; + + //! The scoped locking pattern + /** It helps to avoid the common problem of forgetting to release lock. + It also nicely provides the "node" for queuing locks. */ + class scoped_lock: internal::no_copy { + public: + //! Construct lock that has not acquired a recursive_mutex. + scoped_lock() : my_mutex(NULL) {}; + + //! Acquire lock on given mutex. + scoped_lock( recursive_mutex& mutex ) { +#if TBB_USE_ASSERT + my_mutex = &mutex; +#endif /* TBB_USE_ASSERT */ + acquire( mutex ); + } + + //! Release lock (if lock is held). + ~scoped_lock() { + if( my_mutex ) + release(); + } + + //! Acquire lock on given mutex. + void acquire( recursive_mutex& mutex ) { +#if TBB_USE_ASSERT + internal_acquire( mutex ); +#else + my_mutex = &mutex; + mutex.lock(); +#endif /* TBB_USE_ASSERT */ + } + + //! Try acquire lock on given recursive_mutex. + bool try_acquire( recursive_mutex& mutex ) { +#if TBB_USE_ASSERT + return internal_try_acquire( mutex ); +#else + bool result = mutex.try_lock(); + if( result ) + my_mutex = &mutex; + return result; +#endif /* TBB_USE_ASSERT */ + } + + //! Release lock + void release() { +#if TBB_USE_ASSERT + internal_release(); +#else + my_mutex->unlock(); + my_mutex = NULL; +#endif /* TBB_USE_ASSERT */ + } + + private: + //! The pointer to the current recursive_mutex to work + recursive_mutex* my_mutex; + + //! All checks from acquire using mutex.state were moved here + void __TBB_EXPORTED_METHOD internal_acquire( recursive_mutex& m ); + + //! All checks from try_acquire using mutex.state were moved here + bool __TBB_EXPORTED_METHOD internal_try_acquire( recursive_mutex& m ); + + //! All checks from release using mutex.state were moved here + void __TBB_EXPORTED_METHOD internal_release(); + + friend class recursive_mutex; + }; + + // Mutex traits + static const bool is_rw_mutex = false; + static const bool is_recursive_mutex = true; + static const bool is_fair_mutex = false; + + // C++0x compatibility interface + + //! Acquire lock + void lock() { +#if TBB_USE_ASSERT + aligned_space tmp; + new(tmp.begin()) scoped_lock(*this); +#else + #if _WIN32||_WIN64 + EnterCriticalSection(&impl); + #else + int error_code = pthread_mutex_lock(&impl); + if( error_code ) + tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_lock failed"); + #endif /* _WIN32||_WIN64 */ +#endif /* TBB_USE_ASSERT */ + } + + //! Try acquiring lock (non-blocking) + /** Return true if lock acquired; false otherwise. */ + bool try_lock() { +#if TBB_USE_ASSERT + aligned_space tmp; + return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this); +#else + #if _WIN32||_WIN64 + return TryEnterCriticalSection(&impl)!=0; + #else + return pthread_mutex_trylock(&impl)==0; + #endif /* _WIN32||_WIN64 */ +#endif /* TBB_USE_ASSERT */ + } + + //! Release lock + void unlock() { +#if TBB_USE_ASSERT + aligned_space tmp; + scoped_lock& s = *tmp.begin(); + s.my_mutex = this; + s.internal_release(); +#else + #if _WIN32||_WIN64 + LeaveCriticalSection(&impl); + #else + pthread_mutex_unlock(&impl); + #endif /* _WIN32||_WIN64 */ +#endif /* TBB_USE_ASSERT */ + } + + //! Return native_handle + #if _WIN32||_WIN64 + typedef LPCRITICAL_SECTION native_handle_type; + #else + typedef pthread_mutex_t* native_handle_type; + #endif + native_handle_type native_handle() { return (native_handle_type) &impl; } + +private: +#if _WIN32||_WIN64 + CRITICAL_SECTION impl; + enum state_t { + INITIALIZED=0x1234, + DESTROYED=0x789A, + } state; +#else + pthread_mutex_t impl; +#endif /* _WIN32||_WIN64 */ + + //! All checks from mutex constructor using mutex.state were moved here + void __TBB_EXPORTED_METHOD internal_construct(); + + //! All checks from mutex destructor using mutex.state were moved here + void __TBB_EXPORTED_METHOD internal_destroy(); +}; + +__TBB_DEFINE_PROFILING_SET_NAME(recursive_mutex) + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_recursive_mutex_H_include_area + +#endif /* __TBB_recursive_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/runtime_loader.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/runtime_loader.h new file mode 100644 index 00000000..9aaeea5b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/runtime_loader.h @@ -0,0 +1,193 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_runtime_loader_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_runtime_loader_H +#pragma message("TBB Warning: tbb/runtime_loader.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_runtime_loader_H +#define __TBB_runtime_loader_H + +#define __TBB_runtime_loader_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#if ! TBB_PREVIEW_RUNTIME_LOADER + #error Set TBB_PREVIEW_RUNTIME_LOADER to include runtime_loader.h +#endif + +#include "tbb_stddef.h" +#include + +#if _MSC_VER + #if ! __TBB_NO_IMPLICIT_LINKAGE + #ifdef _DEBUG + #pragma comment( linker, "/nodefaultlib:tbb_debug.lib" ) + #pragma comment( linker, "/defaultlib:tbbproxy_debug.lib" ) + #else + #pragma comment( linker, "/nodefaultlib:tbb.lib" ) + #pragma comment( linker, "/defaultlib:tbbproxy.lib" ) + #endif + #endif +#endif + +namespace tbb { + +namespace interface6 { + +//! Load TBB at runtime. +/*! + +\b Usage: + +In source code: + +\code +#include "tbb/runtime_loader.h" + +char const * path[] = { "/lib/ia32", NULL }; +tbb::runtime_loader loader( path ); + +// Now use TBB. +\endcode + +Link with \c tbbproxy.lib (or \c libtbbproxy.a) instead of \c tbb.lib (\c libtbb.dylib, +\c libtbb.so). + +TBB library will be loaded at runtime from \c /lib/ia32 directory. + +\b Attention: + +All \c runtime_loader objects (in the same module, i.e. exe or dll) share some global state. +The most noticeable piece of global state is loaded TBB library. +There are some implications: + + - Only one TBB library can be loaded per module. + + - If one object has already loaded TBB library, another object will not load TBB. + If the loaded TBB library is suitable for the second object, both will use TBB + cooperatively, otherwise the second object will report an error. + + - \c runtime_loader objects will not work (correctly) in parallel due to absence of + synchronization. + +*/ + +class __TBB_DEPRECATED_IN_VERBOSE_MODE runtime_loader : tbb::internal::no_copy { + + public: + + //! Error mode constants. + enum error_mode { + em_status, //!< Save status of operation and continue. + em_throw, //!< Throw an exception of tbb::runtime_loader::error_code type. + em_abort //!< Print message to \c stderr and call \c abort(). + }; // error_mode + + //! Error codes. + enum error_code { + ec_ok, //!< No errors. + ec_bad_call, //!< Invalid function call (e. g. load() called when TBB is already loaded). + ec_bad_arg, //!< Invalid argument passed. + ec_bad_lib, //!< Invalid library found (e. g. \c TBB_runtime_version symbol not found). + ec_bad_ver, //!< TBB found but version is not suitable. + ec_no_lib //!< No suitable TBB library found. + }; // error_code + + //! Initialize object but do not load TBB. + runtime_loader( error_mode mode = em_abort ); + + //! Initialize object and load TBB. + /*! + See load() for details. + + If error mode is \c em_status, call status() to check whether TBB was loaded or not. + */ + runtime_loader( + char const * path[], //!< List of directories to search TBB in. + int min_ver = TBB_INTERFACE_VERSION, //!< Minimal suitable version of TBB. + int max_ver = INT_MAX, //!< Maximal suitable version of TBB. + error_mode mode = em_abort //!< Error mode for this object. + ); + + //! Destroy object. + ~runtime_loader(); + + //! Load TBB. + /*! + The method searches the directories specified in \c path[] array for the TBB library. + When the library is found, it is loaded and its version is checked. If the version is + not suitable, the library is unloaded, and the search continues. + + \b Note: + + For security reasons, avoid using relative directory names. For example, never load + TBB from current (\c "."), parent (\c "..") or any other relative directory (like + \c "lib" ). Use only absolute directory names (e. g. "/usr/local/lib"). + + For the same security reasons, avoid using system default directories (\c "") on + Windows. (See http://www.microsoft.com/technet/security/advisory/2269637.mspx for + details.) + + Neglecting these rules may cause your program to execute 3-rd party malicious code. + + \b Errors: + - \c ec_bad_call - TBB already loaded by this object. + - \c ec_bad_arg - \p min_ver and/or \p max_ver negative or zero, + or \p min_ver > \p max_ver. + - \c ec_bad_ver - TBB of unsuitable version already loaded by another object. + - \c ec_no_lib - No suitable library found. + */ + error_code + load( + char const * path[], //!< List of directories to search TBB in. + int min_ver = TBB_INTERFACE_VERSION, //!< Minimal suitable version of TBB. + int max_ver = INT_MAX //!< Maximal suitable version of TBB. + + ); + + + //! Report status. + /*! + If error mode is \c em_status, the function returns status of the last operation. + */ + error_code status(); + + private: + + error_mode const my_mode; + error_code my_status; + bool my_loaded; + +}; // class runtime_loader + +} // namespace interface6 + +using interface6::runtime_loader; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_runtime_loader_H_include_area + +#endif /* __TBB_runtime_loader_H */ + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/scalable_allocator.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/scalable_allocator.h new file mode 100644 index 00000000..f1fc98ed --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/scalable_allocator.h @@ -0,0 +1,388 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_scalable_allocator_H +#define __TBB_scalable_allocator_H +/** @file */ + +#include /* Need ptrdiff_t and size_t from here. */ +#if !_MSC_VER +#include /* Need intptr_t from here. */ +#endif + +#if !defined(__cplusplus) && __ICC==1100 + #pragma warning (push) + #pragma warning (disable: 991) +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if _MSC_VER >= 1400 +#define __TBB_EXPORTED_FUNC __cdecl +#else +#define __TBB_EXPORTED_FUNC +#endif + +/** The "malloc" analogue to allocate block of memory of size bytes. + * @ingroup memory_allocation */ +void * __TBB_EXPORTED_FUNC scalable_malloc (size_t size); + +/** The "free" analogue to discard a previously allocated piece of memory. + @ingroup memory_allocation */ +void __TBB_EXPORTED_FUNC scalable_free (void* ptr); + +/** The "realloc" analogue complementing scalable_malloc. + @ingroup memory_allocation */ +void * __TBB_EXPORTED_FUNC scalable_realloc (void* ptr, size_t size); + +/** The "calloc" analogue complementing scalable_malloc. + @ingroup memory_allocation */ +void * __TBB_EXPORTED_FUNC scalable_calloc (size_t nobj, size_t size); + +/** The "posix_memalign" analogue. + @ingroup memory_allocation */ +int __TBB_EXPORTED_FUNC scalable_posix_memalign (void** memptr, size_t alignment, size_t size); + +/** The "_aligned_malloc" analogue. + @ingroup memory_allocation */ +void * __TBB_EXPORTED_FUNC scalable_aligned_malloc (size_t size, size_t alignment); + +/** The "_aligned_realloc" analogue. + @ingroup memory_allocation */ +void * __TBB_EXPORTED_FUNC scalable_aligned_realloc (void* ptr, size_t size, size_t alignment); + +/** The "_aligned_free" analogue. + @ingroup memory_allocation */ +void __TBB_EXPORTED_FUNC scalable_aligned_free (void* ptr); + +/** The analogue of _msize/malloc_size/malloc_usable_size. + Returns the usable size of a memory block previously allocated by scalable_*, + or 0 (zero) if ptr does not point to such a block. + @ingroup memory_allocation */ +size_t __TBB_EXPORTED_FUNC scalable_msize (void* ptr); + +/* Results for scalable_allocation_* functions */ +typedef enum { + TBBMALLOC_OK, + TBBMALLOC_INVALID_PARAM, + TBBMALLOC_UNSUPPORTED, + TBBMALLOC_NO_MEMORY, + TBBMALLOC_NO_EFFECT +} ScalableAllocationResult; + +/* Setting TBB_MALLOC_USE_HUGE_PAGES environment variable to 1 enables huge pages. + scalable_allocation_mode call has priority over environment variable. */ +typedef enum { + TBBMALLOC_USE_HUGE_PAGES, /* value turns using huge pages on and off */ + /* deprecated, kept for backward compatibility only */ + USE_HUGE_PAGES = TBBMALLOC_USE_HUGE_PAGES, + /* try to limit memory consumption value (Bytes), clean internal buffers + if limit is exceeded, but not prevents from requesting memory from OS */ + TBBMALLOC_SET_SOFT_HEAP_LIMIT, + /* Lower bound for the size (Bytes), that is interpreted as huge + * and not released during regular cleanup operations. */ + TBBMALLOC_SET_HUGE_SIZE_THRESHOLD +} AllocationModeParam; + +/** Set TBB allocator-specific allocation modes. + @ingroup memory_allocation */ +int __TBB_EXPORTED_FUNC scalable_allocation_mode(int param, intptr_t value); + +typedef enum { + /* Clean internal allocator buffers for all threads. + Returns TBBMALLOC_NO_EFFECT if no buffers cleaned, + TBBMALLOC_OK if some memory released from buffers. */ + TBBMALLOC_CLEAN_ALL_BUFFERS, + /* Clean internal allocator buffer for current thread only. + Return values same as for TBBMALLOC_CLEAN_ALL_BUFFERS. */ + TBBMALLOC_CLEAN_THREAD_BUFFERS +} ScalableAllocationCmd; + +/** Call TBB allocator-specific commands. + @ingroup memory_allocation */ +int __TBB_EXPORTED_FUNC scalable_allocation_command(int cmd, void *param); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#ifdef __cplusplus + +//! The namespace rml contains components of low-level memory pool interface. +namespace rml { +class MemoryPool; + +typedef void *(*rawAllocType)(intptr_t pool_id, size_t &bytes); +// returns non-zero in case of error +typedef int (*rawFreeType)(intptr_t pool_id, void* raw_ptr, size_t raw_bytes); + +/* +MemPoolPolicy extension must be compatible with such structure fields layout + +struct MemPoolPolicy { + rawAllocType pAlloc; + rawFreeType pFree; + size_t granularity; // granularity of pAlloc allocations +}; +*/ + +struct MemPoolPolicy { + enum { + TBBMALLOC_POOL_VERSION = 1 + }; + + rawAllocType pAlloc; + rawFreeType pFree; + // granularity of pAlloc allocations. 0 means default used. + size_t granularity; + int version; + // all memory consumed at 1st pAlloc call and never returned, + // no more pAlloc calls after 1st + unsigned fixedPool : 1, + // memory consumed but returned only at pool termination + keepAllMemory : 1, + reserved : 30; + + MemPoolPolicy(rawAllocType pAlloc_, rawFreeType pFree_, + size_t granularity_ = 0, bool fixedPool_ = false, + bool keepAllMemory_ = false) : + pAlloc(pAlloc_), pFree(pFree_), granularity(granularity_), version(TBBMALLOC_POOL_VERSION), + fixedPool(fixedPool_), keepAllMemory(keepAllMemory_), + reserved(0) {} +}; + +// enums have same values as appropriate enums from ScalableAllocationResult +// TODO: use ScalableAllocationResult in pool_create directly +enum MemPoolError { + // pool created successfully + POOL_OK = TBBMALLOC_OK, + // invalid policy parameters found + INVALID_POLICY = TBBMALLOC_INVALID_PARAM, + // requested pool policy is not supported by allocator library + UNSUPPORTED_POLICY = TBBMALLOC_UNSUPPORTED, + // lack of memory during pool creation + NO_MEMORY = TBBMALLOC_NO_MEMORY, + // action takes no effect + NO_EFFECT = TBBMALLOC_NO_EFFECT +}; + +MemPoolError pool_create_v1(intptr_t pool_id, const MemPoolPolicy *policy, + rml::MemoryPool **pool); + +bool pool_destroy(MemoryPool* memPool); +void *pool_malloc(MemoryPool* memPool, size_t size); +void *pool_realloc(MemoryPool* memPool, void *object, size_t size); +void *pool_aligned_malloc(MemoryPool* mPool, size_t size, size_t alignment); +void *pool_aligned_realloc(MemoryPool* mPool, void *ptr, size_t size, size_t alignment); +bool pool_reset(MemoryPool* memPool); +bool pool_free(MemoryPool *memPool, void *object); +MemoryPool *pool_identify(void *object); +size_t pool_msize(MemoryPool *memPool, void *object); + +} // namespace rml + +#include /* To use new with the placement argument */ + +/* Ensure that including this header does not cause implicit linkage with TBB */ +#ifndef __TBB_NO_IMPLICIT_LINKAGE + #define __TBB_NO_IMPLICIT_LINKAGE 1 + #include "tbb_stddef.h" + #undef __TBB_NO_IMPLICIT_LINKAGE +#else + #include "tbb_stddef.h" +#endif + +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#include // std::forward +#endif + +#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT +#include +#endif + +namespace tbb { + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for erroneous "unreferenced parameter" warning in method destroy. + #pragma warning (push) + #pragma warning (disable: 4100) +#endif + +//! @cond INTERNAL +namespace internal { + +#if TBB_USE_EXCEPTIONS +// forward declaration is for inlining prevention +template __TBB_NOINLINE( void throw_exception(const E &e) ); +#endif + +// keep throw in a separate function to prevent code bloat +template +void throw_exception(const E &e) { + __TBB_THROW(e); +} + +} // namespace internal +//! @endcond + +//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 +/** The members are ordered the same way they are in section 20.4.1 + of the ISO C++ standard. + @ingroup memory_allocation */ +template +class scalable_allocator { +public: + typedef typename internal::allocator_type::value_type value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template struct rebind { + typedef scalable_allocator other; + }; + + scalable_allocator() throw() {} + scalable_allocator( const scalable_allocator& ) throw() {} + template scalable_allocator(const scalable_allocator&) throw() {} + + pointer address(reference x) const {return &x;} + const_pointer address(const_reference x) const {return &x;} + + //! Allocate space for n objects. + pointer allocate( size_type n, const void* /*hint*/ =0 ) { + pointer p = static_cast( scalable_malloc( n * sizeof(value_type) ) ); + if (!p) + internal::throw_exception(std::bad_alloc()); + return p; + } + + //! Free previously allocated block of memory + void deallocate( pointer p, size_type ) { + scalable_free( p ); + } + + //! Largest value for which method allocate might succeed. + size_type max_size() const throw() { + size_type absolutemax = static_cast(-1) / sizeof (value_type); + return (absolutemax > 0 ? absolutemax : 1); + } +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + template + void construct(U *p, Args&&... args) + { ::new((void *)p) U(std::forward(args)...); } +#else /* __TBB_ALLOCATOR_CONSTRUCT_VARIADIC */ +#if __TBB_CPP11_RVALUE_REF_PRESENT + void construct( pointer p, value_type&& value ) { ::new((void*)(p)) value_type( std::move( value ) ); } +#endif + void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} +#endif /* __TBB_ALLOCATOR_CONSTRUCT_VARIADIC */ + void destroy( pointer p ) {p->~value_type();} +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif /* warning 4100 is back */ + +//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 +/** @ingroup memory_allocation */ +template<> +class scalable_allocator { +public: + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + template struct rebind { + typedef scalable_allocator other; + }; +}; + +template +inline bool operator==( const scalable_allocator&, const scalable_allocator& ) {return true;} + +template +inline bool operator!=( const scalable_allocator&, const scalable_allocator& ) {return false;} + +#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT + +namespace internal { + +//! C++17 memory resource implementation for scalable allocator +//! ISO C++ Section 23.12.2 +class scalable_resource_impl : public std::pmr::memory_resource { +private: + void* do_allocate(size_t bytes, size_t alignment) override { + void* ptr = scalable_aligned_malloc( bytes, alignment ); + if (!ptr) { + throw_exception(std::bad_alloc()); + } + return ptr; + } + + void do_deallocate(void* ptr, size_t /*bytes*/, size_t /*alignment*/) override { + scalable_free(ptr); + } + + //! Memory allocated by one instance of scalable_resource_impl could be deallocated by any + //! other instance of this class + bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { + return this == &other || +#if __TBB_USE_OPTIONAL_RTTI + dynamic_cast(&other) != NULL; +#else + false; +#endif + } +}; + +} // namespace internal + +//! Global scalable allocator memory resource provider +inline std::pmr::memory_resource* scalable_memory_resource() noexcept { + static tbb::internal::scalable_resource_impl scalable_res; + return &scalable_res; +} + +#endif /* __TBB_CPP17_MEMORY_RESOURCE_PRESENT */ + +} // namespace tbb + +#if _MSC_VER + #if (__TBB_BUILD || __TBBMALLOC_BUILD) && !defined(__TBBMALLOC_NO_IMPLICIT_LINKAGE) + #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1 + #endif + + #if !__TBBMALLOC_NO_IMPLICIT_LINKAGE + #ifdef _DEBUG + #pragma comment(lib, "tbbmalloc_debug.lib") + #else + #pragma comment(lib, "tbbmalloc.lib") + #endif + #endif + + +#endif + +#endif /* __cplusplus */ + +#if !defined(__cplusplus) && __ICC==1100 + #pragma warning (pop) +#endif /* ICC 11.0 warning 991 is back */ + +#endif /* __TBB_scalable_allocator_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/spin_mutex.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/spin_mutex.h new file mode 100644 index 00000000..56348c9d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/spin_mutex.h @@ -0,0 +1,214 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_spin_mutex_H +#define __TBB_spin_mutex_H + +#define __TBB_spin_mutex_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include +#include +#include "aligned_space.h" +#include "tbb_stddef.h" +#include "tbb_machine.h" +#include "tbb_profiling.h" +#include "internal/_mutex_padding.h" + +namespace tbb { + +//! A lock that occupies a single byte. +/** A spin_mutex is a spin mutex that fits in a single byte. + It should be used only for locking short critical sections + (typically less than 20 instructions) when fairness is not an issue. + If zero-initialized, the mutex is considered unheld. + @ingroup synchronization */ +class spin_mutex : internal::mutex_copy_deprecated_and_disabled { + //! 0 if lock is released, 1 if lock is acquired. + __TBB_atomic_flag flag; + +public: + //! Construct unacquired lock. + /** Equivalent to zero-initialization of *this. */ + spin_mutex() : flag(0) { +#if TBB_USE_THREADING_TOOLS + internal_construct(); +#endif + } + + //! Represents acquisition of a mutex. + class scoped_lock : internal::no_copy { + private: + //! Points to currently held mutex, or NULL if no lock is held. + spin_mutex* my_mutex; + + //! Value to store into spin_mutex::flag to unlock the mutex. + /** This variable is no longer used. Instead, 0 and 1 are used to + represent that the lock is free and acquired, respectively. + We keep the member variable here to ensure backward compatibility */ + __TBB_Flag my_unlock_value; + + //! Like acquire, but with ITT instrumentation. + void __TBB_EXPORTED_METHOD internal_acquire( spin_mutex& m ); + + //! Like try_acquire, but with ITT instrumentation. + bool __TBB_EXPORTED_METHOD internal_try_acquire( spin_mutex& m ); + + //! Like release, but with ITT instrumentation. + void __TBB_EXPORTED_METHOD internal_release(); + + friend class spin_mutex; + + public: + //! Construct without acquiring a mutex. + scoped_lock() : my_mutex(NULL), my_unlock_value(0) {} + + //! Construct and acquire lock on a mutex. + scoped_lock( spin_mutex& m ) : my_unlock_value(0) { + internal::suppress_unused_warning(my_unlock_value); +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + my_mutex=NULL; + internal_acquire(m); +#else + my_mutex=&m; + __TBB_LockByte(m.flag); +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ + } + + //! Acquire lock. + void acquire( spin_mutex& m ) { +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + internal_acquire(m); +#else + my_mutex = &m; + __TBB_LockByte(m.flag); +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ + } + + //! Try acquiring lock (non-blocking) + /** Return true if lock acquired; false otherwise. */ + bool try_acquire( spin_mutex& m ) { +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + return internal_try_acquire(m); +#else + bool result = __TBB_TryLockByte(m.flag); + if( result ) + my_mutex = &m; + return result; +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/ + } + + //! Release lock + void release() { +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + internal_release(); +#else + __TBB_UnlockByte(my_mutex->flag); + my_mutex = NULL; +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ + } + + //! Destroy lock. If holding a lock, releases the lock first. + ~scoped_lock() { + if( my_mutex ) { +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + internal_release(); +#else + __TBB_UnlockByte(my_mutex->flag); +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ + } + } + }; + + //! Internal constructor with ITT instrumentation. + void __TBB_EXPORTED_METHOD internal_construct(); + + // Mutex traits + static const bool is_rw_mutex = false; + static const bool is_recursive_mutex = false; + static const bool is_fair_mutex = false; + + // ISO C++0x compatibility methods + + //! Acquire lock + void lock() { +#if TBB_USE_THREADING_TOOLS + aligned_space tmp; + new(tmp.begin()) scoped_lock(*this); +#else + __TBB_LockByte(flag); +#endif /* TBB_USE_THREADING_TOOLS*/ + } + + //! Try acquiring lock (non-blocking) + /** Return true if lock acquired; false otherwise. */ + bool try_lock() { +#if TBB_USE_THREADING_TOOLS + aligned_space tmp; + return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this); +#else + return __TBB_TryLockByte(flag); +#endif /* TBB_USE_THREADING_TOOLS*/ + } + + //! Release lock + void unlock() { +#if TBB_USE_THREADING_TOOLS + aligned_space tmp; + scoped_lock& s = *tmp.begin(); + s.my_mutex = this; + s.internal_release(); +#else + __TBB_UnlockByte(flag); +#endif /* TBB_USE_THREADING_TOOLS */ + } + + friend class scoped_lock; +}; // end of spin_mutex + +__TBB_DEFINE_PROFILING_SET_NAME(spin_mutex) + +} // namespace tbb + +#if ( __TBB_x86_32 || __TBB_x86_64 ) +#include "internal/_x86_eliding_mutex_impl.h" +#endif + +namespace tbb { +//! A cross-platform spin mutex with speculative lock acquisition. +/** On platforms with proper HW support, this lock may speculatively execute + its critical sections, using HW mechanisms to detect real data races and + ensure atomicity of the critical sections. In particular, it uses + Intel(R) Transactional Synchronization Extensions (Intel(R) TSX). + Without such HW support, it behaves like a spin_mutex. + It should be used for locking short critical sections where the lock is + contended but the data it protects are not. If zero-initialized, the + mutex is considered unheld. + @ingroup synchronization */ + +#if ( __TBB_x86_32 || __TBB_x86_64 ) +typedef interface7::internal::padded_mutex speculative_spin_mutex; +#else +typedef interface7::internal::padded_mutex speculative_spin_mutex; +#endif +__TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_mutex) + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_spin_mutex_H_include_area + +#endif /* __TBB_spin_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/spin_rw_mutex.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/spin_rw_mutex.h new file mode 100644 index 00000000..57a4ce2f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/spin_rw_mutex.h @@ -0,0 +1,252 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_spin_rw_mutex_H +#define __TBB_spin_rw_mutex_H + +#include "tbb_stddef.h" +#include "tbb_machine.h" +#include "tbb_profiling.h" +#include "internal/_mutex_padding.h" + +namespace tbb { + +#if __TBB_TSX_AVAILABLE +namespace interface8 { namespace internal { + class x86_rtm_rw_mutex; +}} +#endif + +class spin_rw_mutex_v3; +typedef spin_rw_mutex_v3 spin_rw_mutex; + +//! Fast, unfair, spinning reader-writer lock with backoff and writer-preference +/** @ingroup synchronization */ +class spin_rw_mutex_v3 : internal::mutex_copy_deprecated_and_disabled { + //! @cond INTERNAL + + //! Internal acquire write lock. + bool __TBB_EXPORTED_METHOD internal_acquire_writer(); + + //! Out of line code for releasing a write lock. + /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ + void __TBB_EXPORTED_METHOD internal_release_writer(); + + //! Internal acquire read lock. + void __TBB_EXPORTED_METHOD internal_acquire_reader(); + + //! Internal upgrade reader to become a writer. + bool __TBB_EXPORTED_METHOD internal_upgrade(); + + //! Out of line code for downgrading a writer to a reader. + /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ + void __TBB_EXPORTED_METHOD internal_downgrade(); + + //! Internal release read lock. + void __TBB_EXPORTED_METHOD internal_release_reader(); + + //! Internal try_acquire write lock. + bool __TBB_EXPORTED_METHOD internal_try_acquire_writer(); + + //! Internal try_acquire read lock. + bool __TBB_EXPORTED_METHOD internal_try_acquire_reader(); + + //! @endcond +public: + //! Construct unacquired mutex. + spin_rw_mutex_v3() : state(0) { +#if TBB_USE_THREADING_TOOLS + internal_construct(); +#endif + } + +#if TBB_USE_ASSERT + //! Destructor asserts if the mutex is acquired, i.e. state is zero. + ~spin_rw_mutex_v3() { + __TBB_ASSERT( !state, "destruction of an acquired mutex"); + }; +#endif /* TBB_USE_ASSERT */ + + //! The scoped locking pattern + /** It helps to avoid the common problem of forgetting to release lock. + It also nicely provides the "node" for queuing locks. */ + class scoped_lock : internal::no_copy { +#if __TBB_TSX_AVAILABLE + friend class tbb::interface8::internal::x86_rtm_rw_mutex; +#endif + public: + //! Construct lock that has not acquired a mutex. + /** Equivalent to zero-initialization of *this. */ + scoped_lock() : mutex(NULL), is_writer(false) {} + + //! Acquire lock on given mutex. + scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) { + acquire(m, write); + } + + //! Release lock (if lock is held). + ~scoped_lock() { + if( mutex ) release(); + } + + //! Acquire lock on given mutex. + void acquire( spin_rw_mutex& m, bool write = true ) { + __TBB_ASSERT( !mutex, "holding mutex already" ); + is_writer = write; + mutex = &m; + if( write ) mutex->internal_acquire_writer(); + else mutex->internal_acquire_reader(); + } + + //! Upgrade reader to become a writer. + /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ + bool upgrade_to_writer() { + __TBB_ASSERT( mutex, "mutex is not acquired" ); + if (is_writer) return true; // Already a writer + is_writer = true; + return mutex->internal_upgrade(); + } + + //! Release lock. + void release() { + __TBB_ASSERT( mutex, "mutex is not acquired" ); + spin_rw_mutex *m = mutex; + mutex = NULL; +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + if( is_writer ) m->internal_release_writer(); + else m->internal_release_reader(); +#else + if( is_writer ) __TBB_AtomicAND( &m->state, READERS ); + else __TBB_FetchAndAddWrelease( &m->state, -(intptr_t)ONE_READER); +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ + } + + //! Downgrade writer to become a reader. + bool downgrade_to_reader() { + __TBB_ASSERT( mutex, "mutex is not acquired" ); + if (!is_writer) return true; // Already a reader +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + mutex->internal_downgrade(); +#else + __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER)); +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ + is_writer = false; + return true; + } + + //! Try acquire lock on given mutex. + bool try_acquire( spin_rw_mutex& m, bool write = true ) { + __TBB_ASSERT( !mutex, "holding mutex already" ); + bool result; + is_writer = write; + result = write? m.internal_try_acquire_writer() + : m.internal_try_acquire_reader(); + if( result ) + mutex = &m; + return result; + } + + protected: + + //! The pointer to the current mutex that is held, or NULL if no mutex is held. + spin_rw_mutex* mutex; + + //! If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock. + /** Not defined if not holding a lock. */ + bool is_writer; + }; + + // Mutex traits + static const bool is_rw_mutex = true; + static const bool is_recursive_mutex = false; + static const bool is_fair_mutex = false; + + // ISO C++0x compatibility methods + + //! Acquire writer lock + void lock() {internal_acquire_writer();} + + //! Try acquiring writer lock (non-blocking) + /** Return true if lock acquired; false otherwise. */ + bool try_lock() {return internal_try_acquire_writer();} + + //! Release lock + void unlock() { +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + if( state&WRITER ) internal_release_writer(); + else internal_release_reader(); +#else + if( state&WRITER ) __TBB_AtomicAND( &state, READERS ); + else __TBB_FetchAndAddWrelease( &state, -(intptr_t)ONE_READER); +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ + } + + // Methods for reader locks that resemble ISO C++0x compatibility methods. + + //! Acquire reader lock + void lock_read() {internal_acquire_reader();} + + //! Try acquiring reader lock (non-blocking) + /** Return true if reader lock acquired; false otherwise. */ + bool try_lock_read() {return internal_try_acquire_reader();} + +protected: + typedef intptr_t state_t; + static const state_t WRITER = 1; + static const state_t WRITER_PENDING = 2; + static const state_t READERS = ~(WRITER | WRITER_PENDING); + static const state_t ONE_READER = 4; + static const state_t BUSY = WRITER | READERS; + //! State of lock + /** Bit 0 = writer is holding lock + Bit 1 = request by a writer to acquire lock (hint to readers to wait) + Bit 2..N = number of readers holding lock */ + state_t state; + +private: + void __TBB_EXPORTED_METHOD internal_construct(); +}; + +__TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex) + +} // namespace tbb + +#if __TBB_TSX_AVAILABLE +#include "internal/_x86_rtm_rw_mutex_impl.h" +#endif + +namespace tbb { +namespace interface8 { +//! A cross-platform spin reader/writer mutex with speculative lock acquisition. +/** On platforms with proper HW support, this lock may speculatively execute + its critical sections, using HW mechanisms to detect real data races and + ensure atomicity of the critical sections. In particular, it uses + Intel(R) Transactional Synchronization Extensions (Intel(R) TSX). + Without such HW support, it behaves like a spin_rw_mutex. + It should be used for locking short critical sections where the lock is + contended but the data it protects are not. + @ingroup synchronization */ +#if __TBB_TSX_AVAILABLE +typedef interface7::internal::padded_mutex speculative_spin_rw_mutex; +#else +typedef interface7::internal::padded_mutex speculative_spin_rw_mutex; +#endif +} // namespace interface8 + +using interface8::speculative_spin_rw_mutex; +__TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_rw_mutex) +} // namespace tbb +#endif /* __TBB_spin_rw_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task.h new file mode 100644 index 00000000..b5fb1ac3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task.h @@ -0,0 +1,1189 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_task_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_task_H +#pragma message("TBB Warning: tbb/task.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_task_H +#define __TBB_task_H + +#define __TBB_task_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_stddef.h" +#include "tbb_machine.h" +#include "tbb_profiling.h" +#include + +typedef struct ___itt_caller *__itt_caller; + +namespace tbb { + +class task; +class task_list; +class task_group_context; + +// MSVC does not allow taking the address of a member that was defined +// privately in task_base and made public in class task via a using declaration. +#if _MSC_VER || (__GNUC__==3 && __GNUC_MINOR__<3) +#define __TBB_TASK_BASE_ACCESS public +#else +#define __TBB_TASK_BASE_ACCESS private +#endif + +namespace internal { //< @cond INTERNAL + + class allocate_additional_child_of_proxy: no_assign { + //! No longer used, but retained for binary layout compatibility. Always NULL. + task* self; + task& parent; + public: + explicit allocate_additional_child_of_proxy( task& parent_ ) : self(NULL), parent(parent_) { + suppress_unused_warning( self ); + } + task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; + void __TBB_EXPORTED_METHOD free( task& ) const; + }; + + struct cpu_ctl_env_space { int space[sizeof(internal::uint64_t)/sizeof(int)]; }; +} //< namespace internal @endcond + +namespace interface5 { + namespace internal { + //! Base class for methods that became static in TBB 3.0. + /** TBB's evolution caused the "this" argument for several methods to become obsolete. + However, for backwards binary compatibility, the new methods need distinct names, + otherwise the One Definition Rule would be broken. Hence the new methods are + defined in this private base class, and then exposed in class task via + using declarations. */ + class task_base: tbb::internal::no_copy { + __TBB_TASK_BASE_ACCESS: + friend class tbb::task; + + //! Schedule task for execution when a worker becomes available. + static void spawn( task& t ); + + //! Spawn multiple tasks and clear list. + static void spawn( task_list& list ); + + //! Like allocate_child, except that task's parent becomes "t", not this. + /** Typically used in conjunction with schedule_to_reexecute to implement while loops. + Atomically increments the reference count of t.parent() */ + static tbb::internal::allocate_additional_child_of_proxy allocate_additional_child_of( task& t ) { + return tbb::internal::allocate_additional_child_of_proxy(t); + } + + //! Destroy a task. + /** Usually, calling this method is unnecessary, because a task is + implicitly deleted after its execute() method runs. However, + sometimes a task needs to be explicitly deallocated, such as + when a root task is used as the parent in spawn_and_wait_for_all. */ + static void __TBB_EXPORTED_FUNC destroy( task& victim ); + }; + } // internal +} // interface5 + +//! @cond INTERNAL +namespace internal { + + class scheduler: no_copy { + public: + //! For internal use only + virtual void spawn( task& first, task*& next ) = 0; + + //! For internal use only + virtual void wait_for_all( task& parent, task* child ) = 0; + + //! For internal use only + virtual void spawn_root_and_wait( task& first, task*& next ) = 0; + + //! Pure virtual destructor; + // Have to have it just to shut up overzealous compilation warnings + virtual ~scheduler() = 0; + + //! For internal use only + virtual void enqueue( task& t, void* reserved ) = 0; + }; + + //! A reference count + /** Should always be non-negative. A signed type is used so that underflow can be detected. */ + typedef intptr_t reference_count; + +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! The flag to indicate that the wait task has been abandoned. + static const reference_count abandon_flag = reference_count(1) << (sizeof(reference_count)*CHAR_BIT - 2); +#endif + + //! An id as used for specifying affinity. + typedef unsigned short affinity_id; + +#if __TBB_TASK_ISOLATION + //! A tag for task isolation. + typedef intptr_t isolation_tag; + const isolation_tag no_isolation = 0; +#endif /* __TBB_TASK_ISOLATION */ + +#if __TBB_TASK_GROUP_CONTEXT + class generic_scheduler; + + struct context_list_node_t { + context_list_node_t *my_prev, + *my_next; + }; + + class allocate_root_with_context_proxy: no_assign { + task_group_context& my_context; + public: + allocate_root_with_context_proxy ( task_group_context& ctx ) : my_context(ctx) {} + task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; + void __TBB_EXPORTED_METHOD free( task& ) const; + }; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + class allocate_root_proxy: no_assign { + public: + static task& __TBB_EXPORTED_FUNC allocate( size_t size ); + static void __TBB_EXPORTED_FUNC free( task& ); + }; + + class allocate_continuation_proxy: no_assign { + public: + task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; + void __TBB_EXPORTED_METHOD free( task& ) const; + }; + + class allocate_child_proxy: no_assign { + public: + task& __TBB_EXPORTED_METHOD allocate( size_t size ) const; + void __TBB_EXPORTED_METHOD free( task& ) const; + }; + +#if __TBB_PREVIEW_CRITICAL_TASKS + // TODO: move to class methods when critical task API becomes public + void make_critical( task& t ); + bool is_critical( task& t ); +#endif + + //! Memory prefix to a task object. + /** This class is internal to the library. + Do not reference it directly, except within the library itself. + Fields are ordered in way that preserves backwards compatibility and yields good packing on + typical 32-bit and 64-bit platforms. New fields should be added at the beginning for + backward compatibility with accesses to the task prefix inlined into application code. To + prevent ODR violation, the class shall have the same layout in all application translation + units. If some fields are conditional (e.g. enabled by preview macros) and might get + skipped, use reserved fields to adjust the layout. + + In case task prefix size exceeds 32 or 64 bytes on IA32 and Intel64 architectures + correspondingly, consider dynamic setting of task_alignment and task_prefix_reservation_size + based on the maximal operand size supported by the current CPU. + + @ingroup task_scheduling */ + class task_prefix { + private: + friend class tbb::task; + friend class tbb::interface5::internal::task_base; + friend class tbb::task_list; + friend class internal::scheduler; + friend class internal::allocate_root_proxy; + friend class internal::allocate_child_proxy; + friend class internal::allocate_continuation_proxy; + friend class internal::allocate_additional_child_of_proxy; +#if __TBB_PREVIEW_CRITICAL_TASKS + friend void make_critical( task& ); + friend bool is_critical( task& ); +#endif + +#if __TBB_TASK_ISOLATION + //! The tag used for task isolation. + isolation_tag isolation; +#else + intptr_t reserved_space_for_task_isolation_tag; +#endif /* __TBB_TASK_ISOLATION */ + +#if __TBB_TASK_GROUP_CONTEXT + //! Shared context that is used to communicate asynchronous state changes + /** Currently it is used to broadcast cancellation requests generated both + by users and as the result of unhandled exceptions in the task::execute() + methods. */ + task_group_context *context; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + //! The scheduler that allocated the task, or NULL if the task is big. + /** Small tasks are pooled by the scheduler that allocated the task. + If a scheduler needs to free a small task allocated by another scheduler, + it returns the task to that other scheduler. This policy avoids + memory space blowup issues for memory allocators that allocate from + thread-specific pools. */ + scheduler* origin; + +#if __TBB_TASK_PRIORITY || __TBB_PREVIEW_RESUMABLE_TASKS + union { +#endif /* __TBB_TASK_PRIORITY */ + //! Obsolete. The scheduler that owns the task. + /** Retained only for the sake of backward binary compatibility. + Still used by inline methods in the task.h header. **/ + scheduler* owner; + +#if __TBB_TASK_PRIORITY + //! Pointer to the next offloaded lower priority task. + /** Used to maintain a list of offloaded tasks inside the scheduler. **/ + tbb::task* next_offloaded; +#endif + +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! Pointer to the abandoned scheduler where the current task is waited for. + scheduler* abandoned_scheduler; +#endif +#if __TBB_TASK_PRIORITY || __TBB_PREVIEW_RESUMABLE_TASKS + }; +#endif /* __TBB_TASK_PRIORITY || __TBB_PREVIEW_RESUMABLE_TASKS */ + + //! The task whose reference count includes me. + /** In the "blocking style" of programming, this field points to the parent task. + In the "continuation-passing style" of programming, this field points to the + continuation of the parent. */ + tbb::task* parent; + + //! Reference count used for synchronization. + /** In the "continuation-passing style" of programming, this field is + the difference of the number of allocated children minus the + number of children that have completed. + In the "blocking style" of programming, this field is one more than the difference. */ + __TBB_atomic reference_count ref_count; + + //! Obsolete. Used to be scheduling depth before TBB 2.2 + /** Retained only for the sake of backward binary compatibility. + Not used by TBB anymore. **/ + int depth; + + //! A task::state_type, stored as a byte for compactness. + /** This state is exposed to users via method task::state(). */ + unsigned char state; + + //! Miscellaneous state that is not directly visible to users, stored as a byte for compactness. + /** 0x0 -> version 1.0 task + 0x1 -> version >=2.1 task + 0x10 -> task was enqueued + 0x20 -> task_proxy + 0x40 -> task has live ref_count + 0x80 -> a stolen task */ + unsigned char extra_state; + + affinity_id affinity; + + //! "next" field for list of task + tbb::task* next; + + //! The task corresponding to this task_prefix. + tbb::task& task() {return *reinterpret_cast(this+1);} + }; + +} // namespace internal +//! @endcond + +#if __TBB_TASK_GROUP_CONTEXT + +#if __TBB_TASK_PRIORITY +namespace internal { + static const int priority_stride_v4 = INT_MAX / 4; +#if __TBB_PREVIEW_CRITICAL_TASKS + // TODO: move into priority_t enum when critical tasks become public feature + static const int priority_critical = priority_stride_v4 * 3 + priority_stride_v4 / 3 * 2; +#endif +} + +enum priority_t { + priority_normal = internal::priority_stride_v4 * 2, + priority_low = priority_normal - internal::priority_stride_v4, + priority_high = priority_normal + internal::priority_stride_v4 +}; + +#endif /* __TBB_TASK_PRIORITY */ + +#if TBB_USE_CAPTURED_EXCEPTION + class tbb_exception; +#else + namespace internal { + class tbb_exception_ptr; + } +#endif /* !TBB_USE_CAPTURED_EXCEPTION */ + +class task_scheduler_init; +namespace interface7 { class task_arena; } +using interface7::task_arena; + +//! Used to form groups of tasks +/** @ingroup task_scheduling + The context services explicit cancellation requests from user code, and unhandled + exceptions intercepted during tasks execution. Intercepting an exception results + in generating internal cancellation requests (which is processed in exactly the + same way as external ones). + + The context is associated with one or more root tasks and defines the cancellation + group that includes all the descendants of the corresponding root task(s). Association + is established when a context object is passed as an argument to the task::allocate_root() + method. See task_group_context::task_group_context for more details. + + The context can be bound to another one, and other contexts can be bound to it, + forming a tree-like structure: parent -> this -> children. Arrows here designate + cancellation propagation direction. If a task in a cancellation group is cancelled + all the other tasks in this group and groups bound to it (as children) get cancelled too. + + IMPLEMENTATION NOTE: + When adding new members to task_group_context or changing types of existing ones, + update the size of both padding buffers (_leading_padding and _trailing_padding) + appropriately. See also VERSIONING NOTE at the constructor definition below. **/ +class task_group_context : internal::no_copy { +private: + friend class internal::generic_scheduler; + friend class task_scheduler_init; + friend class task_arena; + +#if TBB_USE_CAPTURED_EXCEPTION + typedef tbb_exception exception_container_type; +#else + typedef internal::tbb_exception_ptr exception_container_type; +#endif + + enum version_traits_word_layout { + traits_offset = 16, + version_mask = 0xFFFF, + traits_mask = 0xFFFFul << traits_offset + }; + +public: + enum kind_type { + isolated, + bound + }; + + enum traits_type { + exact_exception = 0x0001ul << traits_offset, +#if __TBB_FP_CONTEXT + fp_settings = 0x0002ul << traits_offset, +#endif + concurrent_wait = 0x0004ul << traits_offset, +#if TBB_USE_CAPTURED_EXCEPTION + default_traits = 0 +#else + default_traits = exact_exception +#endif /* !TBB_USE_CAPTURED_EXCEPTION */ + }; + +private: + enum state { + may_have_children = 1, + // the following enumerations must be the last, new 2^x values must go above + next_state_value, low_unused_state_bit = (next_state_value-1)*2 + }; + + union { + //! Flavor of this context: bound or isolated. + // TODO: describe asynchronous use, and whether any memory semantics are needed + __TBB_atomic kind_type my_kind; + uintptr_t _my_kind_aligner; + }; + + //! Pointer to the context of the parent cancellation group. NULL for isolated contexts. + task_group_context *my_parent; + + //! Used to form the thread specific list of contexts without additional memory allocation. + /** A context is included into the list of the current thread when its binding to + its parent happens. Any context can be present in the list of one thread only. **/ + internal::context_list_node_t my_node; + + //! Used to set and maintain stack stitching point for Intel Performance Tools. + __itt_caller itt_caller; + + //! Leading padding protecting accesses to frequently used members from false sharing. + /** Read accesses to the field my_cancellation_requested are on the hot path inside + the scheduler. This padding ensures that this field never shares the same cache + line with a local variable that is frequently written to. **/ + char _leading_padding[internal::NFS_MaxLineSize + - 2 * sizeof(uintptr_t)- sizeof(void*) - sizeof(internal::context_list_node_t) + - sizeof(__itt_caller) +#if __TBB_FP_CONTEXT + - sizeof(internal::cpu_ctl_env_space) +#endif + ]; + +#if __TBB_FP_CONTEXT + //! Space for platform-specific FPU settings. + /** Must only be accessed inside TBB binaries, and never directly in user + code or inline methods. */ + internal::cpu_ctl_env_space my_cpu_ctl_env; +#endif + + //! Specifies whether cancellation was requested for this task group. + uintptr_t my_cancellation_requested; + + //! Version for run-time checks and behavioral traits of the context. + /** Version occupies low 16 bits, and traits (zero or more ORed enumerators + from the traits_type enumerations) take the next 16 bits. + Original (zeroth) version of the context did not support any traits. **/ + uintptr_t my_version_and_traits; + + //! Pointer to the container storing exception being propagated across this task group. + exception_container_type *my_exception; + + //! Scheduler instance that registered this context in its thread specific list. + internal::generic_scheduler *my_owner; + + //! Internal state (combination of state flags, currently only may_have_children). + uintptr_t my_state; + +#if __TBB_TASK_PRIORITY + //! Priority level of the task group (in normalized representation) + intptr_t my_priority; +#endif /* __TBB_TASK_PRIORITY */ + + //! Description of algorithm for scheduler based instrumentation. + internal::string_index my_name; + + //! Trailing padding protecting accesses to frequently used members from false sharing + /** \sa _leading_padding **/ + char _trailing_padding[internal::NFS_MaxLineSize - 2 * sizeof(uintptr_t) - 2 * sizeof(void*) +#if __TBB_TASK_PRIORITY + - sizeof(intptr_t) +#endif /* __TBB_TASK_PRIORITY */ + - sizeof(internal::string_index) + ]; + +public: + //! Default & binding constructor. + /** By default a bound context is created. That is this context will be bound + (as child) to the context of the task calling task::allocate_root(this_context) + method. Cancellation requests passed to the parent context are propagated + to all the contexts bound to it. Similarly priority change is propagated + from the parent context to its children. + + If task_group_context::isolated is used as the argument, then the tasks associated + with this context will never be affected by events in any other context. + + Creating isolated contexts involve much less overhead, but they have limited + utility. Normally when an exception occurs in an algorithm that has nested + ones running, it is desirably to have all the nested algorithms cancelled + as well. Such a behavior requires nested algorithms to use bound contexts. + + There is one good place where using isolated algorithms is beneficial. It is + a master thread. That is if a particular algorithm is invoked directly from + the master thread (not from a TBB task), supplying it with explicitly + created isolated context will result in a faster algorithm startup. + + VERSIONING NOTE: + Implementation(s) of task_group_context constructor(s) cannot be made + entirely out-of-line because the run-time version must be set by the user + code. This will become critically important for binary compatibility, if + we ever have to change the size of the context object. + + Boosting the runtime version will also be necessary if new data fields are + introduced in the currently unused padding areas and these fields are updated + by inline methods. **/ + task_group_context ( kind_type relation_with_parent = bound, + uintptr_t t = default_traits ) + : my_kind(relation_with_parent) + , my_version_and_traits(3 | t) + , my_name(internal::CUSTOM_CTX) + { + init(); + } + + // Custom constructor for instrumentation of TBB algorithm + task_group_context ( internal::string_index name ) + : my_kind(bound) + , my_version_and_traits(3 | default_traits) + , my_name(name) + { + init(); + } + + // Do not introduce standalone unbind method since it will break state propagation assumptions + __TBB_EXPORTED_METHOD ~task_group_context (); + + //! Forcefully reinitializes the context after the task tree it was associated with is completed. + /** Because the method assumes that all the tasks that used to be associated with + this context have already finished, calling it while the context is still + in use somewhere in the task hierarchy leads to undefined behavior. + + IMPORTANT: This method is not thread safe! + + The method does not change the context's parent if it is set. **/ + void __TBB_EXPORTED_METHOD reset (); + + //! Initiates cancellation of all tasks in this cancellation group and its subordinate groups. + /** \return false if cancellation has already been requested, true otherwise. + + Note that canceling never fails. When false is returned, it just means that + another thread (or this one) has already sent cancellation request to this + context or to one of its ancestors (if this context is bound). It is guaranteed + that when this method is concurrently called on the same not yet cancelled + context, true will be returned by one and only one invocation. **/ + bool __TBB_EXPORTED_METHOD cancel_group_execution (); + + //! Returns true if the context received cancellation request. + bool __TBB_EXPORTED_METHOD is_group_execution_cancelled () const; + + //! Records the pending exception, and cancels the task group. + /** May be called only from inside a catch-block. If the context is already + cancelled, does nothing. + The method brings the task group associated with this context exactly into + the state it would be in, if one of its tasks threw the currently pending + exception during its execution. In other words, it emulates the actions + of the scheduler's dispatch loop exception handler. **/ + void __TBB_EXPORTED_METHOD register_pending_exception (); + +#if __TBB_FP_CONTEXT + //! Captures the current FPU control settings to the context. + /** Because the method assumes that all the tasks that used to be associated with + this context have already finished, calling it while the context is still + in use somewhere in the task hierarchy leads to undefined behavior. + + IMPORTANT: This method is not thread safe! + + The method does not change the FPU control settings of the context's parent. **/ + void __TBB_EXPORTED_METHOD capture_fp_settings (); +#endif + +#if __TBB_TASK_PRIORITY + //! Changes priority of the task group + __TBB_DEPRECATED_IN_VERBOSE_MODE void set_priority ( priority_t ); + + //! Retrieves current priority of the current task group + __TBB_DEPRECATED_IN_VERBOSE_MODE priority_t priority () const; +#endif /* __TBB_TASK_PRIORITY */ + + //! Returns the context's trait + uintptr_t traits() const { return my_version_and_traits & traits_mask; } + +protected: + //! Out-of-line part of the constructor. + /** Singled out to ensure backward binary compatibility of the future versions. **/ + void __TBB_EXPORTED_METHOD init (); + +private: + friend class task; + friend class internal::allocate_root_with_context_proxy; + + static const kind_type binding_required = bound; + static const kind_type binding_completed = kind_type(bound+1); + static const kind_type detached = kind_type(binding_completed+1); + static const kind_type dying = kind_type(detached+1); + + //! Propagates any state change detected to *this, and as an optimisation possibly also upward along the heritage line. + template + void propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ); + + //! Registers this context with the local scheduler and binds it to its parent context + void bind_to ( internal::generic_scheduler *local_sched ); + + //! Registers this context with the local scheduler + void register_with ( internal::generic_scheduler *local_sched ); + +#if __TBB_FP_CONTEXT + //! Copies FPU control setting from another context + // TODO: Consider adding #else stub in order to omit #if sections in other code + void copy_fp_settings( const task_group_context &src ); +#endif /* __TBB_FP_CONTEXT */ +}; // class task_group_context + +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +//! Base class for user-defined tasks. +/** @ingroup task_scheduling */ +class __TBB_DEPRECATED_IN_VERBOSE_MODE task: __TBB_TASK_BASE_ACCESS interface5::internal::task_base { + + //! Set reference count + void __TBB_EXPORTED_METHOD internal_set_ref_count( int count ); + + //! Decrement reference count and return its new value. + internal::reference_count __TBB_EXPORTED_METHOD internal_decrement_ref_count(); + +protected: + //! Default constructor. + task() {prefix().extra_state=1;} + +public: + //! Destructor. + virtual ~task() {} + + //! Should be overridden by derived classes. + virtual task* execute() = 0; + + //! Enumeration of task states that the scheduler considers. + enum state_type { + //! task is running, and will be destroyed after method execute() completes. + executing, + //! task to be rescheduled. + reexecute, + //! task is in ready pool, or is going to be put there, or was just taken off. + ready, + //! task object is freshly allocated or recycled. + allocated, + //! task object is on free list, or is going to be put there, or was just taken off. + freed, + //! task to be recycled as continuation + recycle +#if __TBB_RECYCLE_TO_ENQUEUE + //! task to be scheduled for starvation-resistant execution + ,to_enqueue +#endif +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! a special task used to resume a scheduler. + ,to_resume +#endif + }; + + //------------------------------------------------------------------------ + // Allocating tasks + //------------------------------------------------------------------------ + + //! Returns proxy for overloaded new that allocates a root task. + static internal::allocate_root_proxy allocate_root() { + return internal::allocate_root_proxy(); + } + +#if __TBB_TASK_GROUP_CONTEXT + //! Returns proxy for overloaded new that allocates a root task associated with user supplied context. + static internal::allocate_root_with_context_proxy allocate_root( task_group_context& ctx ) { + return internal::allocate_root_with_context_proxy(ctx); + } +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + //! Returns proxy for overloaded new that allocates a continuation task of *this. + /** The continuation's parent becomes the parent of *this. */ + internal::allocate_continuation_proxy& allocate_continuation() { + return *reinterpret_cast(this); + } + + //! Returns proxy for overloaded new that allocates a child task of *this. + internal::allocate_child_proxy& allocate_child() { + return *reinterpret_cast(this); + } + + //! Define recommended static form via import from base class. + using task_base::allocate_additional_child_of; + +#if __TBB_DEPRECATED_TASK_INTERFACE + //! Destroy a task. + /** Usually, calling this method is unnecessary, because a task is + implicitly deleted after its execute() method runs. However, + sometimes a task needs to be explicitly deallocated, such as + when a root task is used as the parent in spawn_and_wait_for_all. */ + void __TBB_EXPORTED_METHOD destroy( task& t ); +#else /* !__TBB_DEPRECATED_TASK_INTERFACE */ + //! Define recommended static form via import from base class. + using task_base::destroy; +#endif /* !__TBB_DEPRECATED_TASK_INTERFACE */ + + //------------------------------------------------------------------------ + // Recycling of tasks + //------------------------------------------------------------------------ + + //! Change this to be a continuation of its former self. + /** The caller must guarantee that the task's refcount does not become zero until + after the method execute() returns. Typically, this is done by having + method execute() return a pointer to a child of the task. If the guarantee + cannot be made, use method recycle_as_safe_continuation instead. + + Because of the hazard, this method may be deprecated in the future. */ + void recycle_as_continuation() { + __TBB_ASSERT( prefix().state==executing, "execute not running?" ); + prefix().state = allocated; + } + + //! Recommended to use, safe variant of recycle_as_continuation + /** For safety, it requires additional increment of ref_count. + With no descendants and ref_count of 1, it has the semantics of recycle_to_reexecute. */ + void recycle_as_safe_continuation() { + __TBB_ASSERT( prefix().state==executing, "execute not running?" ); + prefix().state = recycle; + } + + //! Change this to be a child of new_parent. + void recycle_as_child_of( task& new_parent ) { + internal::task_prefix& p = prefix(); + __TBB_ASSERT( prefix().state==executing||prefix().state==allocated, "execute not running, or already recycled" ); + __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled as a child" ); + __TBB_ASSERT( p.parent==NULL, "parent must be null" ); + __TBB_ASSERT( new_parent.prefix().state<=recycle, "corrupt parent's state" ); + __TBB_ASSERT( new_parent.prefix().state!=freed, "parent already freed" ); + p.state = allocated; + p.parent = &new_parent; +#if __TBB_TASK_GROUP_CONTEXT + p.context = new_parent.prefix().context; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + } + + //! Schedule this for reexecution after current execute() returns. + /** Made obsolete by recycle_as_safe_continuation; may become deprecated. */ + void recycle_to_reexecute() { + __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" ); + __TBB_ASSERT( prefix().ref_count==0, "no child tasks allowed when recycled for reexecution" ); + prefix().state = reexecute; + } + +#if __TBB_RECYCLE_TO_ENQUEUE + //! Schedule this to enqueue after descendant tasks complete. + /** Save enqueue/spawn difference, it has the semantics of recycle_as_safe_continuation. */ + void recycle_to_enqueue() { + __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" ); + prefix().state = to_enqueue; + } +#endif /* __TBB_RECYCLE_TO_ENQUEUE */ + + //------------------------------------------------------------------------ + // Spawning and blocking + //------------------------------------------------------------------------ + + //! Set reference count + void set_ref_count( int count ) { +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + internal_set_ref_count(count); +#else + prefix().ref_count = count; +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ + } + + //! Atomically increment reference count. + /** Has acquire semantics */ + void increment_ref_count() { + __TBB_FetchAndIncrementWacquire( &prefix().ref_count ); + } + + //! Atomically adds to reference count and returns its new value. + /** Has release-acquire semantics */ + int add_ref_count( int count ) { + internal::call_itt_notify( internal::releasing, &prefix().ref_count ); + internal::reference_count k = count+__TBB_FetchAndAddW( &prefix().ref_count, count ); + __TBB_ASSERT( k>=0, "task's reference count underflowed" ); + if( k==0 ) + internal::call_itt_notify( internal::acquired, &prefix().ref_count ); + return int(k); + } + + //! Atomically decrement reference count and returns its new value. + /** Has release semantics. */ + int decrement_ref_count() { +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + return int(internal_decrement_ref_count()); +#else + return int(__TBB_FetchAndDecrementWrelease( &prefix().ref_count ))-1; +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ + } + + //! Define recommended static forms via import from base class. + using task_base::spawn; + + //! Similar to spawn followed by wait_for_all, but more efficient. + void spawn_and_wait_for_all( task& child ) { + prefix().owner->wait_for_all( *this, &child ); + } + + //! Similar to spawn followed by wait_for_all, but more efficient. + void __TBB_EXPORTED_METHOD spawn_and_wait_for_all( task_list& list ); + + //! Spawn task allocated by allocate_root, wait for it to complete, and deallocate it. + static void spawn_root_and_wait( task& root ) { + root.prefix().owner->spawn_root_and_wait( root, root.prefix().next ); + } + + //! Spawn root tasks on list and wait for all of them to finish. + /** If there are more tasks than worker threads, the tasks are spawned in + order of front to back. */ + static void spawn_root_and_wait( task_list& root_list ); + + //! Wait for reference count to become one, and set reference count to zero. + /** Works on tasks while waiting. */ + void wait_for_all() { + prefix().owner->wait_for_all( *this, NULL ); + } + + //! Enqueue task for starvation-resistant execution. +#if __TBB_TASK_PRIORITY + /** The task will be enqueued on the normal priority level disregarding the + priority of its task group. + + The rationale of such semantics is that priority of an enqueued task is + statically fixed at the moment of its enqueuing, while task group priority + is dynamic. Thus automatic priority inheritance would be generally a subject + to the race, which may result in unexpected behavior. + + Use enqueue() overload with explicit priority value and task::group_priority() + method to implement such priority inheritance when it is really necessary. **/ +#endif /* __TBB_TASK_PRIORITY */ + static void enqueue( task& t ) { + t.prefix().owner->enqueue( t, NULL ); + } + +#if __TBB_TASK_PRIORITY + //! Enqueue task for starvation-resistant execution on the specified priority level. + static void enqueue( task& t, priority_t p ) { +#if __TBB_PREVIEW_CRITICAL_TASKS + __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high + || p == internal::priority_critical, "Invalid priority level value"); +#else + __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value"); +#endif + t.prefix().owner->enqueue( t, (void*)p ); + } +#endif /* __TBB_TASK_PRIORITY */ + + //! Enqueue task in task_arena + //! The implementation is in task_arena.h +#if __TBB_TASK_PRIORITY + inline static void enqueue( task& t, task_arena& arena, priority_t p = priority_t(0) ); +#else + inline static void enqueue( task& t, task_arena& arena); +#endif + + //! The innermost task being executed or destroyed by the current thread at the moment. + static task& __TBB_EXPORTED_FUNC self(); + + //! task on whose behalf this task is working, or NULL if this is a root. + task* parent() const {return prefix().parent;} + + //! sets parent task pointer to specified value + void set_parent(task* p) { +#if __TBB_TASK_GROUP_CONTEXT + __TBB_ASSERT(!p || prefix().context == p->prefix().context, "The tasks must be in the same context"); +#endif + prefix().parent = p; + } + +#if __TBB_TASK_GROUP_CONTEXT + //! This method is deprecated and will be removed in the future. + /** Use method group() instead. **/ + task_group_context* context() {return prefix().context;} + + //! Pointer to the task group descriptor. + task_group_context* group () { return prefix().context; } +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + //! True if task was stolen from the task pool of another thread. + bool is_stolen_task() const { + return (prefix().extra_state & 0x80)!=0; + } + + //! True if the task was enqueued + bool is_enqueued_task() const { + // es_task_enqueued = 0x10 + return (prefix().extra_state & 0x10)!=0; + } + +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! Type that defines suspension point + typedef void* suspend_point; + + //! Suspend current task execution + template + static void suspend(F f); + + //! Resume specific suspend point + static void resume(suspend_point tag); +#endif + + //------------------------------------------------------------------------ + // Debugging + //------------------------------------------------------------------------ + + //! Current execution state + state_type state() const {return state_type(prefix().state);} + + //! The internal reference count. + int ref_count() const { +#if TBB_USE_ASSERT +#if __TBB_PREVIEW_RESUMABLE_TASKS + internal::reference_count ref_count_ = prefix().ref_count & ~internal::abandon_flag; +#else + internal::reference_count ref_count_ = prefix().ref_count; +#endif + __TBB_ASSERT( ref_count_==int(ref_count_), "integer overflow error"); +#endif +#if __TBB_PREVIEW_RESUMABLE_TASKS + return int(prefix().ref_count & ~internal::abandon_flag); +#else + return int(prefix().ref_count); +#endif + } + + //! Obsolete, and only retained for the sake of backward compatibility. Always returns true. + bool __TBB_EXPORTED_METHOD is_owned_by_current_thread() const; + + //------------------------------------------------------------------------ + // Affinity + //------------------------------------------------------------------------ + + //! An id as used for specifying affinity. + /** Guaranteed to be integral type. Value of 0 means no affinity. */ + typedef internal::affinity_id affinity_id; + + //! Set affinity for this task. + void set_affinity( affinity_id id ) {prefix().affinity = id;} + + //! Current affinity of this task + affinity_id affinity() const {return prefix().affinity;} + + //! Invoked by scheduler to notify task that it ran on unexpected thread. + /** Invoked before method execute() runs, if task is stolen, or task has + affinity but will be executed on another thread. + + The default action does nothing. */ + virtual void __TBB_EXPORTED_METHOD note_affinity( affinity_id id ); + +#if __TBB_TASK_GROUP_CONTEXT + //! Moves this task from its current group into another one. + /** Argument ctx specifies the new group. + + The primary purpose of this method is to associate unique task group context + with a task allocated for subsequent enqueuing. In contrast to spawned tasks + enqueued ones normally outlive the scope where they were created. This makes + traditional usage model where task group context are allocated locally on + the stack inapplicable. Dynamic allocation of context objects is performance + inefficient. Method change_group() allows to make task group context object + a member of the task class, and then associate it with its containing task + object in the latter's constructor. **/ + void __TBB_EXPORTED_METHOD change_group ( task_group_context& ctx ); + + //! Initiates cancellation of all tasks in this cancellation group and its subordinate groups. + /** \return false if cancellation has already been requested, true otherwise. **/ + bool cancel_group_execution () { return prefix().context->cancel_group_execution(); } + + //! Returns true if the context has received cancellation request. + bool is_cancelled () const { return prefix().context->is_group_execution_cancelled(); } +#else + bool is_cancelled () const { return false; } +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#if __TBB_TASK_PRIORITY + //! Changes priority of the task group this task belongs to. + __TBB_DEPRECATED void set_group_priority ( priority_t p ) { prefix().context->set_priority(p); } + + //! Retrieves current priority of the task group this task belongs to. + __TBB_DEPRECATED priority_t group_priority () const { return prefix().context->priority(); } + +#endif /* __TBB_TASK_PRIORITY */ + +private: + friend class interface5::internal::task_base; + friend class task_list; + friend class internal::scheduler; + friend class internal::allocate_root_proxy; +#if __TBB_TASK_GROUP_CONTEXT + friend class internal::allocate_root_with_context_proxy; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + friend class internal::allocate_continuation_proxy; + friend class internal::allocate_child_proxy; + friend class internal::allocate_additional_child_of_proxy; + + //! Get reference to corresponding task_prefix. + /** Version tag prevents loader on Linux from using the wrong symbol in debug builds. **/ + internal::task_prefix& prefix( internal::version_tag* = NULL ) const { + return reinterpret_cast(const_cast(this))[-1]; + } +#if __TBB_PREVIEW_CRITICAL_TASKS + friend void internal::make_critical( task& ); + friend bool internal::is_critical( task& ); +#endif +}; // class task + +#if __TBB_PREVIEW_CRITICAL_TASKS +namespace internal { +inline void make_critical( task& t ) { t.prefix().extra_state |= 0x8; } +inline bool is_critical( task& t ) { return bool((t.prefix().extra_state & 0x8) != 0); } +} // namespace internal +#endif /* __TBB_PREVIEW_CRITICAL_TASKS */ + +#if __TBB_PREVIEW_RESUMABLE_TASKS +namespace internal { + template + static void suspend_callback(void* user_callback, task::suspend_point tag) { + // Copy user function to a new stack to avoid a race when the previous scheduler is resumed. + F user_callback_copy = *static_cast(user_callback); + user_callback_copy(tag); + } + void __TBB_EXPORTED_FUNC internal_suspend(void* suspend_callback, void* user_callback); + void __TBB_EXPORTED_FUNC internal_resume(task::suspend_point); + task::suspend_point __TBB_EXPORTED_FUNC internal_current_suspend_point(); +} + +template +inline void task::suspend(F f) { + internal::internal_suspend((void*)internal::suspend_callback, &f); +} +inline void task::resume(suspend_point tag) { + internal::internal_resume(tag); +} +#endif + +//! task that does nothing. Useful for synchronization. +/** @ingroup task_scheduling */ +class __TBB_DEPRECATED_IN_VERBOSE_MODE empty_task: public task { + task* execute() __TBB_override { + return NULL; + } +}; + +//! @cond INTERNAL +namespace internal { + template + class function_task : public task { +#if __TBB_ALLOW_MUTABLE_FUNCTORS + // TODO: deprecated behavior, remove + F my_func; +#else + const F my_func; +#endif + task* execute() __TBB_override { + my_func(); + return NULL; + } + public: + function_task( const F& f ) : my_func(f) {} +#if __TBB_CPP11_RVALUE_REF_PRESENT + function_task( F&& f ) : my_func( std::move(f) ) {} +#endif + }; +} // namespace internal +//! @endcond + +//! A list of children. +/** Used for method task::spawn_children + @ingroup task_scheduling */ +class __TBB_DEPRECATED_IN_VERBOSE_MODE task_list: internal::no_copy { +private: + task* first; + task** next_ptr; + friend class task; + friend class interface5::internal::task_base; +public: + //! Construct empty list + task_list() : first(NULL), next_ptr(&first) {} + + //! Destroys the list, but does not destroy the task objects. + ~task_list() {} + + //! True if list is empty; false otherwise. + bool empty() const {return !first;} + + //! Push task onto back of list. + void push_back( task& task ) { + task.prefix().next = NULL; + *next_ptr = &task; + next_ptr = &task.prefix().next; + } +#if __TBB_TODO + // TODO: add this method and implement&document the local execution ordering. See more in generic_scheduler::local_spawn + //! Push task onto front of list (FIFO local execution, like individual spawning in the same order). + void push_front( task& task ) { + if( empty() ) { + push_back(task); + } else { + task.prefix().next = first; + first = &task; + } + } +#endif + //! Pop the front task from the list. + task& pop_front() { + __TBB_ASSERT( !empty(), "attempt to pop item from empty task_list" ); + task* result = first; + first = result->prefix().next; + if( !first ) next_ptr = &first; + return *result; + } + + //! Clear the list + void clear() { + first=NULL; + next_ptr=&first; + } +}; + +inline void interface5::internal::task_base::spawn( task& t ) { + t.prefix().owner->spawn( t, t.prefix().next ); +} + +inline void interface5::internal::task_base::spawn( task_list& list ) { + if( task* t = list.first ) { + t->prefix().owner->spawn( *t, *list.next_ptr ); + list.clear(); + } +} + +inline void task::spawn_root_and_wait( task_list& root_list ) { + if( task* t = root_list.first ) { + t->prefix().owner->spawn_root_and_wait( *t, *root_list.next_ptr ); + root_list.clear(); + } +} + +} // namespace tbb + +inline void *operator new( size_t bytes, const tbb::internal::allocate_root_proxy& ) { + return &tbb::internal::allocate_root_proxy::allocate(bytes); +} + +inline void operator delete( void* task, const tbb::internal::allocate_root_proxy& ) { + tbb::internal::allocate_root_proxy::free( *static_cast(task) ); +} + +#if __TBB_TASK_GROUP_CONTEXT +inline void *operator new( size_t bytes, const tbb::internal::allocate_root_with_context_proxy& p ) { + return &p.allocate(bytes); +} + +inline void operator delete( void* task, const tbb::internal::allocate_root_with_context_proxy& p ) { + p.free( *static_cast(task) ); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +inline void *operator new( size_t bytes, const tbb::internal::allocate_continuation_proxy& p ) { + return &p.allocate(bytes); +} + +inline void operator delete( void* task, const tbb::internal::allocate_continuation_proxy& p ) { + p.free( *static_cast(task) ); +} + +inline void *operator new( size_t bytes, const tbb::internal::allocate_child_proxy& p ) { + return &p.allocate(bytes); +} + +inline void operator delete( void* task, const tbb::internal::allocate_child_proxy& p ) { + p.free( *static_cast(task) ); +} + +inline void *operator new( size_t bytes, const tbb::internal::allocate_additional_child_of_proxy& p ) { + return &p.allocate(bytes); +} + +inline void operator delete( void* task, const tbb::internal::allocate_additional_child_of_proxy& p ) { + p.free( *static_cast(task) ); +} + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_task_H_include_area + +#endif /* __TBB_task_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_arena.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_arena.h new file mode 100644 index 00000000..46eb4959 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_arena.h @@ -0,0 +1,511 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_task_arena_H +#define __TBB_task_arena_H + +#define __TBB_task_arena_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "task.h" +#include "tbb_exception.h" +#include "internal/_template_helpers.h" +#if __TBB_NUMA_SUPPORT +#include "info.h" +#endif /*__TBB_NUMA_SUPPORT*/ +#if TBB_USE_THREADING_TOOLS +#include "atomic.h" // for as_atomic +#endif +#include "aligned_space.h" + +namespace tbb { + +namespace this_task_arena { + int max_concurrency(); +} // namespace this_task_arena + +//! @cond INTERNAL +namespace internal { + //! Internal to library. Should not be used by clients. + /** @ingroup task_scheduling */ + class arena; + class task_scheduler_observer_v3; +} // namespace internal +//! @endcond + +namespace interface7 { +class task_arena; + +//! @cond INTERNAL +namespace internal { +using namespace tbb::internal; //e.g. function_task from task.h + +class delegate_base : no_assign { +public: + virtual void operator()() const = 0; + virtual ~delegate_base() {} +}; + +// If decltype is available, the helper detects the return type of functor of specified type, +// otherwise it defines the void type. +template +struct return_type_or_void { +#if __TBB_CPP11_DECLTYPE_PRESENT && !__TBB_CPP11_DECLTYPE_OF_FUNCTION_RETURN_TYPE_BROKEN + typedef decltype(declval()()) type; +#else + typedef void type; +#endif +}; + +template +class delegated_function : public delegate_base { + F &my_func; + tbb::aligned_space my_return_storage; + // The function should be called only once. + void operator()() const __TBB_override { + new (my_return_storage.begin()) R(my_func()); + } +public: + delegated_function(F& f) : my_func(f) {} + // The function can be called only after operator() and only once. + R consume_result() const { + return tbb::internal::move(*(my_return_storage.begin())); + } + ~delegated_function() { + my_return_storage.begin()->~R(); + } +}; + +template +class delegated_function : public delegate_base { + F &my_func; + void operator()() const __TBB_override { + my_func(); + } +public: + delegated_function(F& f) : my_func(f) {} + void consume_result() const {} + + friend class task_arena_base; +}; + +class task_arena_base { +#if __TBB_NUMA_SUPPORT +public: + // TODO: consider version approach to resolve backward compatibility potential issues. + struct constraints { + constraints(numa_node_id id = automatic, int maximal_concurrency = automatic) + : numa_id(id) + , max_concurrency(maximal_concurrency) + {} + numa_node_id numa_id; + int max_concurrency; + }; +#endif /*__TBB_NUMA_SUPPORT*/ +protected: + //! NULL if not currently initialized. + internal::arena* my_arena; + +#if __TBB_TASK_GROUP_CONTEXT + //! default context of the arena + task_group_context *my_context; +#endif + + //! Concurrency level for deferred initialization + int my_max_concurrency; + + //! Reserved master slots + unsigned my_master_slots; + + //! Special settings + intptr_t my_version_and_traits; + + bool my_initialized; + +#if __TBB_NUMA_SUPPORT + //! The NUMA node index to which the arena will be attached + numa_node_id my_numa_id; + + // Do not access my_numa_id without the following runtime check. + // Despite my_numa_id is accesible, it does not exist in task_arena_base on user side + // if TBB_PREVIEW_NUMA_SUPPORT macro is not defined by the user. To be sure that + // my_numa_id exists in task_arena_base layout we check the traits. + // TODO: Consider increasing interface version for task_arena_base instead of this runtime check. + numa_node_id numa_id() { + return (my_version_and_traits & numa_support_flag) == numa_support_flag ? my_numa_id : automatic; + } +#endif + + enum { + default_flags = 0 +#if __TBB_TASK_GROUP_CONTEXT + | (task_group_context::default_traits & task_group_context::exact_exception) // 0 or 1 << 16 + , exact_exception_flag = task_group_context::exact_exception // used to specify flag for context directly +#endif +#if __TBB_NUMA_SUPPORT + , numa_support_flag = 1 +#endif + }; + + task_arena_base(int max_concurrency, unsigned reserved_for_masters) + : my_arena(0) +#if __TBB_TASK_GROUP_CONTEXT + , my_context(0) +#endif + , my_max_concurrency(max_concurrency) + , my_master_slots(reserved_for_masters) +#if __TBB_NUMA_SUPPORT + , my_version_and_traits(default_flags | numa_support_flag) +#else + , my_version_and_traits(default_flags) +#endif + , my_initialized(false) +#if __TBB_NUMA_SUPPORT + , my_numa_id(automatic) +#endif + {} + +#if __TBB_NUMA_SUPPORT + task_arena_base(const constraints& constraints_, unsigned reserved_for_masters) + : my_arena(0) +#if __TBB_TASK_GROUP_CONTEXT + , my_context(0) +#endif + , my_max_concurrency(constraints_.max_concurrency) + , my_master_slots(reserved_for_masters) + , my_version_and_traits(default_flags | numa_support_flag) + , my_initialized(false) + , my_numa_id(constraints_.numa_id ) + {} +#endif /*__TBB_NUMA_SUPPORT*/ + + void __TBB_EXPORTED_METHOD internal_initialize(); + void __TBB_EXPORTED_METHOD internal_terminate(); + void __TBB_EXPORTED_METHOD internal_attach(); + void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const; + void __TBB_EXPORTED_METHOD internal_execute( delegate_base& ) const; + void __TBB_EXPORTED_METHOD internal_wait() const; + static int __TBB_EXPORTED_FUNC internal_current_slot(); + static int __TBB_EXPORTED_FUNC internal_max_concurrency( const task_arena * ); +public: + //! Typedef for number of threads that is automatic. + static const int automatic = -1; + static const int not_initialized = -2; + +}; + +#if __TBB_TASK_ISOLATION +void __TBB_EXPORTED_FUNC isolate_within_arena( delegate_base& d, intptr_t isolation = 0 ); + +template +R isolate_impl(F& f) { + delegated_function d(f); + isolate_within_arena(d); + return d.consume_result(); +} +#endif /* __TBB_TASK_ISOLATION */ +} // namespace internal +//! @endcond + +/** 1-to-1 proxy representation class of scheduler's arena + * Constructors set up settings only, real construction is deferred till the first method invocation + * Destructor only removes one of the references to the inner arena representation. + * Final destruction happens when all the references (and the work) are gone. + */ +class task_arena : public internal::task_arena_base { + friend class tbb::internal::task_scheduler_observer_v3; + friend void task::enqueue(task&, task_arena& +#if __TBB_TASK_PRIORITY + , priority_t +#endif + ); + friend int tbb::this_task_arena::max_concurrency(); + void mark_initialized() { + __TBB_ASSERT( my_arena, "task_arena initialization is incomplete" ); +#if __TBB_TASK_GROUP_CONTEXT + __TBB_ASSERT( my_context, "task_arena initialization is incomplete" ); +#endif +#if TBB_USE_THREADING_TOOLS + // Actual synchronization happens in internal_initialize & internal_attach. + // The race on setting my_initialized is benign, but should be hidden from Intel(R) Inspector + internal::as_atomic(my_initialized).fetch_and_store(true); +#else + my_initialized = true; +#endif + } + + template + void enqueue_impl( __TBB_FORWARDING_REF(F) f +#if __TBB_TASK_PRIORITY + , priority_t p = priority_t(0) +#endif + ) { +#if !__TBB_TASK_PRIORITY + intptr_t p = 0; +#endif + initialize(); +#if __TBB_TASK_GROUP_CONTEXT + internal_enqueue(*new(task::allocate_root(*my_context)) internal::function_task< typename internal::strip::type >(internal::forward(f)), p); +#else + internal_enqueue(*new(task::allocate_root()) internal::function_task< typename internal::strip::type >(internal::forward(f)), p); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + } + + template + R execute_impl(F& f) { + initialize(); + internal::delegated_function d(f); + internal_execute(d); + return d.consume_result(); + } + +public: + //! Creates task_arena with certain concurrency limits + /** Sets up settings only, real construction is deferred till the first method invocation + * @arg max_concurrency specifies total number of slots in arena where threads work + * @arg reserved_for_masters specifies number of slots to be used by master threads only. + * Value of 1 is default and reflects behavior of implicit arenas. + **/ + task_arena(int max_concurrency_ = automatic, unsigned reserved_for_masters = 1) + : task_arena_base(max_concurrency_, reserved_for_masters) + {} + +#if __TBB_NUMA_SUPPORT + //! Creates task arena pinned to certain NUMA node + task_arena(const constraints& constraints_, unsigned reserved_for_masters = 1) + : task_arena_base(constraints_, reserved_for_masters) + {} + + //! Copies settings from another task_arena + task_arena(const task_arena &s) // copy settings but not the reference or instance + : task_arena_base(constraints(s.my_numa_id, s.my_max_concurrency), s.my_master_slots) + {} +#else + //! Copies settings from another task_arena + task_arena(const task_arena &s) // copy settings but not the reference or instance + : task_arena_base(s.my_max_concurrency, s.my_master_slots) + {} +#endif /*__TBB_NUMA_SUPPORT*/ + + //! Tag class used to indicate the "attaching" constructor + struct attach {}; + + //! Creates an instance of task_arena attached to the current arena of the thread + explicit task_arena( attach ) + : task_arena_base(automatic, 1) // use default settings if attach fails + { + internal_attach(); + if( my_arena ) my_initialized = true; + } + + //! Forces allocation of the resources for the task_arena as specified in constructor arguments + inline void initialize() { + if( !my_initialized ) { + internal_initialize(); + mark_initialized(); + } + } + + //! Overrides concurrency level and forces initialization of internal representation + inline void initialize(int max_concurrency_, unsigned reserved_for_masters = 1) { + // TODO: decide if this call must be thread-safe + __TBB_ASSERT(!my_arena, "Impossible to modify settings of an already initialized task_arena"); + if( !my_initialized ) { + my_max_concurrency = max_concurrency_; + my_master_slots = reserved_for_masters; + initialize(); + } + } + +#if __TBB_NUMA_SUPPORT + inline void initialize(constraints constraints_, unsigned reserved_for_masters = 1) { + // TODO: decide if this call must be thread-safe + __TBB_ASSERT(!my_arena, "Impossible to modify settings of an already initialized task_arena"); + if( !my_initialized ) { + my_numa_id = constraints_.numa_id; + my_max_concurrency = constraints_.max_concurrency; + my_master_slots = reserved_for_masters; + initialize(); + } + } +#endif /*__TBB_NUMA_SUPPORT*/ + + //! Attaches this instance to the current arena of the thread + inline void initialize(attach) { + // TODO: decide if this call must be thread-safe + __TBB_ASSERT(!my_arena, "Impossible to modify settings of an already initialized task_arena"); + if( !my_initialized ) { + internal_attach(); + if ( !my_arena ) internal_initialize(); + mark_initialized(); + } + } + + //! Removes the reference to the internal arena representation. + //! Not thread safe wrt concurrent invocations of other methods. + inline void terminate() { + if( my_initialized ) { + internal_terminate(); + my_initialized = false; + } + } + + //! Removes the reference to the internal arena representation, and destroys the external object. + //! Not thread safe wrt concurrent invocations of other methods. + ~task_arena() { + terminate(); + } + + //! Returns true if the arena is active (initialized); false otherwise. + //! The name was chosen to match a task_scheduler_init method with the same semantics. + bool is_active() const { return my_initialized; } + + //! Enqueues a task into the arena to process a functor, and immediately returns. + //! Does not require the calling thread to join the arena + +#if __TBB_CPP11_RVALUE_REF_PRESENT + template + void enqueue( F&& f ) { + enqueue_impl(std::forward(f)); + } +#else + template + void enqueue( const F& f ) { + enqueue_impl(f); + } +#endif + +#if __TBB_TASK_PRIORITY + //! Enqueues a task with priority p into the arena to process a functor f, and immediately returns. + //! Does not require the calling thread to join the arena + template +#if __TBB_CPP11_RVALUE_REF_PRESENT + __TBB_DEPRECATED void enqueue( F&& f, priority_t p ) { +#if __TBB_PREVIEW_CRITICAL_TASKS + __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high + || p == internal::priority_critical, "Invalid priority level value"); +#else + __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value"); +#endif + enqueue_impl(std::forward(f), p); + } +#else + __TBB_DEPRECATED void enqueue( const F& f, priority_t p ) { +#if __TBB_PREVIEW_CRITICAL_TASKS + __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high + || p == internal::priority_critical, "Invalid priority level value"); +#else + __TBB_ASSERT(p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value"); +#endif + enqueue_impl(f,p); + } +#endif +#endif// __TBB_TASK_PRIORITY + + //! Joins the arena and executes a mutable functor, then returns + //! If not possible to join, wraps the functor into a task, enqueues it and waits for task completion + //! Can decrement the arena demand for workers, causing a worker to leave and free a slot to the calling thread + //! Since C++11, the method returns the value returned by functor (prior to C++11 it returns void). + template + typename internal::return_type_or_void::type execute(F& f) { + return execute_impl::type>(f); + } + + //! Joins the arena and executes a constant functor, then returns + //! If not possible to join, wraps the functor into a task, enqueues it and waits for task completion + //! Can decrement the arena demand for workers, causing a worker to leave and free a slot to the calling thread + //! Since C++11, the method returns the value returned by functor (prior to C++11 it returns void). + template + typename internal::return_type_or_void::type execute(const F& f) { + return execute_impl::type>(f); + } + +#if __TBB_EXTRA_DEBUG + //! Wait for all work in the arena to be completed + //! Even submitted by other application threads + //! Joins arena if/when possible (in the same way as execute()) + void debug_wait_until_empty() { + initialize(); + internal_wait(); + } +#endif //__TBB_EXTRA_DEBUG + + //! Returns the index, aka slot number, of the calling thread in its current arena + //! This method is deprecated and replaced with this_task_arena::current_thread_index() + inline static int current_thread_index() { + return internal_current_slot(); + } + + //! Returns the maximal number of threads that can work inside the arena + inline int max_concurrency() const { + // Handle special cases inside the library + return (my_max_concurrency>1) ? my_max_concurrency : internal_max_concurrency(this); + } +}; + +namespace this_task_arena { +#if __TBB_TASK_ISOLATION + //! Executes a mutable functor in isolation within the current task arena. + //! Since C++11, the method returns the value returned by functor (prior to C++11 it returns void). + template + typename internal::return_type_or_void::type isolate(F& f) { + return internal::isolate_impl::type>(f); + } + + //! Executes a constant functor in isolation within the current task arena. + //! Since C++11, the method returns the value returned by functor (prior to C++11 it returns void). + template + typename internal::return_type_or_void::type isolate(const F& f) { + return internal::isolate_impl::type>(f); + } +#endif /* __TBB_TASK_ISOLATION */ +} // namespace this_task_arena +} // namespace interfaceX + +using interface7::task_arena; + +namespace this_task_arena { + using namespace interface7::this_task_arena; + + //! Returns the index, aka slot number, of the calling thread in its current arena + inline int current_thread_index() { + int idx = tbb::task_arena::current_thread_index(); + return idx == -1 ? tbb::task_arena::not_initialized : idx; + } + + //! Returns the maximal number of threads that can work inside the arena + inline int max_concurrency() { + return tbb::task_arena::internal_max_concurrency(NULL); + } +} // namespace this_task_arena + +//! Enqueue task in task_arena +#if __TBB_TASK_PRIORITY +void task::enqueue( task& t, task_arena& arena, priority_t p ) { +#else +void task::enqueue( task& t, task_arena& arena ) { + intptr_t p = 0; +#endif + arena.initialize(); + //! Note: the context of the task may differ from the context instantiated by task_arena + arena.internal_enqueue(t, p); +} +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_task_arena_H_include_area + +#endif /* __TBB_task_arena_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_group.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_group.h new file mode 100644 index 00000000..f090d3a2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_group.h @@ -0,0 +1,366 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_task_group_H +#define __TBB_task_group_H + +#define __TBB_task_group_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "task.h" +#include "tbb_exception.h" +#include "internal/_template_helpers.h" +#if TBB_PREVIEW_ISOLATED_TASK_GROUP && __TBB_TASK_ISOLATION +#include "task_arena.h" +#endif + +#if __TBB_TASK_GROUP_CONTEXT + +namespace tbb { + +namespace internal { + template class task_handle_task; +} + +class task_group; +class structured_task_group; +#if TBB_PREVIEW_ISOLATED_TASK_GROUP && __TBB_TASK_ISOLATION +class isolated_task_group; +#endif + +template +class task_handle : internal::no_assign { + template friend class internal::task_handle_task; + friend class task_group; + friend class structured_task_group; +#if TBB_PREVIEW_ISOLATED_TASK_GROUP && __TBB_TASK_ISOLATION + friend class isolated_task_group; +#endif + + static const intptr_t scheduled = 0x1; + + F my_func; + intptr_t my_state; + + void mark_scheduled () { + // The check here is intentionally lax to avoid the impact of interlocked operation + if ( my_state & scheduled ) + internal::throw_exception( internal::eid_invalid_multiple_scheduling ); + my_state |= scheduled; + } +public: + task_handle( const F& f ) : my_func(f), my_state(0) {} +#if __TBB_CPP11_RVALUE_REF_PRESENT + task_handle( F&& f ) : my_func( std::move(f)), my_state(0) {} +#endif + + void operator() () const { my_func(); } +}; + +enum task_group_status { + not_complete, + complete, + canceled +}; + +namespace internal { + +template +class task_handle_task : public task { + task_handle& my_handle; + task* execute() __TBB_override { + my_handle(); + return NULL; + } +public: + task_handle_task( task_handle& h ) : my_handle(h) { h.mark_scheduled(); } +}; + +class task_group_base : internal::no_copy { + class ref_count_guard : internal::no_copy { + task& my_task; + public: + ref_count_guard(task& t) : my_task(t) { + my_task.increment_ref_count(); + } + ~ref_count_guard() { + my_task.decrement_ref_count(); + } + }; +protected: + empty_task* my_root; + task_group_context my_context; + + template + task_group_status internal_run_and_wait( F& f ) { + __TBB_TRY { + if ( !my_context.is_group_execution_cancelled() ) { + // We need to increase the reference count of the root task to notify waiters that + // this task group has some work in progress. + ref_count_guard guard(*my_root); + f(); + } + } __TBB_CATCH( ... ) { + my_context.register_pending_exception(); + } + return wait(); + } + + template + task* prepare_task( __TBB_FORWARDING_REF(F) f ) { + return new( task::allocate_additional_child_of(*my_root) ) Task( internal::forward(f) ); + } + +public: + task_group_base( uintptr_t traits = 0 ) + : my_context(task_group_context::bound, task_group_context::default_traits | traits) + { + my_root = new( task::allocate_root(my_context) ) empty_task; + my_root->set_ref_count(1); + } + + ~task_group_base() __TBB_NOEXCEPT(false) { + if( my_root->ref_count() > 1 ) { +#if __TBB_CPP17_UNCAUGHT_EXCEPTIONS_PRESENT + bool stack_unwinding_in_progress = std::uncaught_exceptions() > 0; +#else + bool stack_unwinding_in_progress = std::uncaught_exception(); +#endif + // Always attempt to do proper cleanup to avoid inevitable memory corruption + // in case of missing wait (for the sake of better testability & debuggability) + if ( !is_canceling() ) + cancel(); + __TBB_TRY { + my_root->wait_for_all(); + } __TBB_CATCH (...) { + task::destroy(*my_root); + __TBB_RETHROW(); + } + task::destroy(*my_root); + if ( !stack_unwinding_in_progress ) + internal::throw_exception( internal::eid_missing_wait ); + } + else { + task::destroy(*my_root); + } + } + + template + void run( task_handle& h ) { + task::spawn( *prepare_task< internal::task_handle_task >(h) ); + } + + task_group_status wait() { + __TBB_TRY { + my_root->wait_for_all(); + } __TBB_CATCH( ... ) { + my_context.reset(); + __TBB_RETHROW(); + } + if ( my_context.is_group_execution_cancelled() ) { + // TODO: the reset method is not thread-safe. Ensure the correct behavior. + my_context.reset(); + return canceled; + } + return complete; + } + + bool is_canceling() { + return my_context.is_group_execution_cancelled(); + } + + void cancel() { + my_context.cancel_group_execution(); + } +}; // class task_group_base + +} // namespace internal + +class task_group : public internal::task_group_base { +public: + task_group () : task_group_base( task_group_context::concurrent_wait ) {} + +#if __SUNPRO_CC + template + void run( task_handle& h ) { + internal_run< internal::task_handle_task >( h ); + } +#else + using task_group_base::run; +#endif + +#if __TBB_CPP11_RVALUE_REF_PRESENT + template + void run( F&& f ) { + task::spawn( *prepare_task< internal::function_task< typename internal::strip::type > >(std::forward(f)) ); + } +#else + template + void run(const F& f) { + task::spawn( *prepare_task< internal::function_task >(f) ); + } +#endif + + template + task_group_status run_and_wait( const F& f ) { + return internal_run_and_wait( f ); + } + + // TODO: add task_handle rvalues support + template + task_group_status run_and_wait( task_handle& h ) { + h.mark_scheduled(); + return internal_run_and_wait< task_handle >( h ); + } +}; // class task_group + +class __TBB_DEPRECATED structured_task_group : public internal::task_group_base { +public: + // TODO: add task_handle rvalues support + template + task_group_status run_and_wait ( task_handle& h ) { + h.mark_scheduled(); + return internal_run_and_wait< task_handle >( h ); + } + + task_group_status wait() { + task_group_status res = task_group_base::wait(); + my_root->set_ref_count(1); + return res; + } +}; // class structured_task_group + +#if TBB_PREVIEW_ISOLATED_TASK_GROUP && __TBB_TASK_ISOLATION +namespace internal { + using interface7::internal::delegate_base; + using interface7::internal::isolate_within_arena; + + class spawn_delegate : public delegate_base { + task* task_to_spawn; + void operator()() const __TBB_override { + task::spawn(*task_to_spawn); + } + public: + spawn_delegate(task* a_task) : task_to_spawn(a_task) {} + }; + + class wait_delegate : public delegate_base { + void operator()() const __TBB_override { + status = tg.wait(); + } + protected: + task_group& tg; + task_group_status& status; + public: + wait_delegate(task_group& a_group, task_group_status& tgs) + : tg(a_group), status(tgs) {} + }; + + template + class run_wait_delegate : public wait_delegate { + F& func; + void operator()() const __TBB_override { + status = tg.run_and_wait( func ); + } + public: + run_wait_delegate(task_group& a_group, F& a_func, task_group_status& tgs) + : wait_delegate(a_group, tgs), func(a_func) {} + }; +} // namespace internal + +class isolated_task_group : public task_group { + intptr_t this_isolation() { + return reinterpret_cast(this); + } +public: + isolated_task_group () : task_group() {} + +#if __TBB_CPP11_RVALUE_REF_PRESENT + template + void run( F&& f ) { + internal::spawn_delegate sd( + prepare_task< internal::function_task< typename internal::strip::type > >(std::forward(f)) + ); + internal::isolate_within_arena( sd, this_isolation() ); + } +#else + template + void run(const F& f) { + internal::spawn_delegate sd( prepare_task< internal::function_task >(f) ); + internal::isolate_within_arena( sd, this_isolation() ); + } +#endif + + template + task_group_status run_and_wait( const F& f ) { + task_group_status result = not_complete; + internal::run_wait_delegate< const F > rwd( *this, f, result ); + internal::isolate_within_arena( rwd, this_isolation() ); + __TBB_ASSERT( result!=not_complete, "premature exit from wait?" ); + return result; + } + + // TODO: add task_handle rvalues support + template + void run( task_handle& h ) { + internal::spawn_delegate sd( prepare_task< internal::task_handle_task >(h) ); + internal::isolate_within_arena( sd, this_isolation() ); + } + + template + task_group_status run_and_wait ( task_handle& h ) { + task_group_status result = not_complete; + internal::run_wait_delegate< task_handle > rwd( *this, h, result ); + internal::isolate_within_arena( rwd, this_isolation() ); + __TBB_ASSERT( result!=not_complete, "premature exit from wait?" ); + return result; + } + + task_group_status wait() { + task_group_status result = not_complete; + internal::wait_delegate wd( *this, result ); + internal::isolate_within_arena( wd, this_isolation() ); + __TBB_ASSERT( result!=not_complete, "premature exit from wait?" ); + return result; + } +}; // class isolated_task_group +#endif // TBB_PREVIEW_ISOLATED_TASK_GROUP && __TBB_TASK_ISOLATION + +inline +bool is_current_task_group_canceling() { + return task::self().is_cancelled(); +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +template +task_handle< typename internal::strip::type > make_task( F&& f ) { + return task_handle< typename internal::strip::type >( std::forward(f) ); +} +#else +template +task_handle make_task( const F& f ) { + return task_handle( f ); +} +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +} // namespace tbb + +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_task_group_H_include_area + +#endif /* __TBB_task_group_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_scheduler_init.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_scheduler_init.h new file mode 100644 index 00000000..687bba1d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_scheduler_init.h @@ -0,0 +1,174 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_task_scheduler_init_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_task_scheduler_init_H +#pragma message("TBB Warning: tbb/task_scheduler_init.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_task_scheduler_init_H +#define __TBB_task_scheduler_init_H + +#define __TBB_task_scheduler_init_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_stddef.h" +#include "limits.h" +#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE +#include // nothrow_t +#endif + +namespace tbb { + +typedef std::size_t stack_size_type; + +//! @cond INTERNAL +namespace internal { + //! Internal to library. Should not be used by clients. + /** @ingroup task_scheduling */ + class scheduler; +} // namespace internal +//! @endcond + +//! Class delimiting the scope of task scheduler activity. +/** A thread can construct a task_scheduler_init object and keep it alive + while it uses TBB's tasking subsystem (including parallel algorithms). + + This class allows to customize properties of the TBB task pool to some extent. + For example it can limit concurrency level of parallel work initiated by the + given thread. It also can be used to specify stack size of the TBB worker threads, + though this setting is not effective if the thread pool has already been created. + + If a parallel construct is used without task_scheduler_init object previously + created, the scheduler will be initialized automatically with default settings, + and will persist until this thread exits. Default concurrency level is defined + as described in task_scheduler_init::initialize(). + @ingroup task_scheduling */ +class __TBB_DEPRECATED_IN_VERBOSE_MODE task_scheduler_init: internal::no_copy { + enum ExceptionPropagationMode { + propagation_mode_exact = 1u, + propagation_mode_captured = 2u, + propagation_mode_mask = propagation_mode_exact | propagation_mode_captured + }; + + /** NULL if not currently initialized. */ + internal::scheduler* my_scheduler; + + bool internal_terminate( bool blocking ); +#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE + bool __TBB_EXPORTED_METHOD internal_blocking_terminate( bool throwing ); +#endif +public: + + //! Typedef for number of threads that is automatic. + static const int automatic = -1; + + //! Argument to initialize() or constructor that causes initialization to be deferred. + static const int deferred = -2; + + //! Ensure that scheduler exists for this thread + /** A value of -1 lets TBB decide on the number of threads, which is usually + maximal hardware concurrency for this process, that is the number of logical + CPUs on the machine (possibly limited by the processor affinity mask of this + process (Windows) or of this thread (Linux, FreeBSD). It is preferable option + for production code because it helps to avoid nasty surprises when several + TBB based components run side-by-side or in a nested fashion inside the same + process. + + The number_of_threads is ignored if any other task_scheduler_inits + currently exist. A thread may construct multiple task_scheduler_inits. + Doing so does no harm because the underlying scheduler is reference counted. */ + void __TBB_EXPORTED_METHOD initialize( int number_of_threads=automatic ); + + //! The overloaded method with stack size parameter + /** Overloading is necessary to preserve ABI compatibility */ + void __TBB_EXPORTED_METHOD initialize( int number_of_threads, stack_size_type thread_stack_size ); + + //! Inverse of method initialize. + void __TBB_EXPORTED_METHOD terminate(); + +#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE +#if TBB_USE_EXCEPTIONS + //! terminate() that waits for worker threads termination. Throws exception on error. + void blocking_terminate() { + internal_blocking_terminate( /*throwing=*/true ); + } +#endif + //! terminate() that waits for worker threads termination. Returns false on error. + bool blocking_terminate(const std::nothrow_t&) __TBB_NOEXCEPT(true) { + return internal_blocking_terminate( /*throwing=*/false ); + } +#endif // __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE + + //! Shorthand for default constructor followed by call to initialize(number_of_threads). + task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0 ) : my_scheduler(NULL) + { + // Two lowest order bits of the stack size argument may be taken to communicate + // default exception propagation mode of the client to be used when the + // client manually creates tasks in the master thread and does not use + // explicit task group context object. This is necessary because newer + // TBB binaries with exact propagation enabled by default may be used + // by older clients that expect tbb::captured_exception wrapper. + // All zeros mean old client - no preference. + __TBB_ASSERT( !(thread_stack_size & propagation_mode_mask), "Requested stack size is not aligned" ); +#if TBB_USE_EXCEPTIONS + thread_stack_size |= TBB_USE_CAPTURED_EXCEPTION ? propagation_mode_captured : propagation_mode_exact; +#endif /* TBB_USE_EXCEPTIONS */ + initialize( number_of_threads, thread_stack_size ); + } + + //! Destroy scheduler for this thread if thread has no other live task_scheduler_inits. + ~task_scheduler_init() { + if( my_scheduler ) + terminate(); + internal::poison_pointer( my_scheduler ); + } + //! Returns the number of threads TBB scheduler would create if initialized by default. + /** Result returned by this method does not depend on whether the scheduler + has already been initialized. + + Because TBB 2.0 does not support blocking tasks yet, you may use this method + to boost the number of threads in the TBB's internal pool, if your tasks are + doing I/O operations. The optimal number of additional threads depends on how + much time your tasks spend in the blocked state. + + Before TBB 3.0 U4 this method returned the number of logical CPU in the + system. Currently on Windows, Linux and FreeBSD it returns the number of + logical CPUs available to the current process in accordance with its affinity + mask. + + NOTE: The return value of this method never changes after its first invocation. + This means that changes in the process affinity mask that took place after + this method was first invoked will not affect the number of worker threads + in the TBB worker threads pool. */ + static int __TBB_EXPORTED_FUNC default_num_threads (); + + //! Returns true if scheduler is active (initialized); false otherwise + bool is_active() const { return my_scheduler != NULL; } +}; + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_task_scheduler_init_H_include_area + +#endif /* __TBB_task_scheduler_init_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_scheduler_observer.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_scheduler_observer.h new file mode 100644 index 00000000..1bb93636 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/task_scheduler_observer.h @@ -0,0 +1,166 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_task_scheduler_observer_H +#define __TBB_task_scheduler_observer_H + +#define __TBB_task_scheduler_observer_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "atomic.h" +#if __TBB_ARENA_OBSERVER +#include "task_arena.h" +#endif + +#if __TBB_SCHEDULER_OBSERVER + +namespace tbb { +namespace interface6 { +class task_scheduler_observer; +} +namespace internal { + +class observer_proxy; +class observer_list; + +class task_scheduler_observer_v3 { + friend class observer_proxy; + friend class observer_list; + friend class interface6::task_scheduler_observer; + + //! Pointer to the proxy holding this observer. + /** Observers are proxied by the scheduler to maintain persistent lists of them. **/ + observer_proxy* my_proxy; + + //! Counter preventing the observer from being destroyed while in use by the scheduler. + /** Valid only when observation is on. **/ + atomic my_busy_count; + +public: + //! Enable or disable observation + /** For local observers the method can be used only when the current thread + has the task scheduler initialized or is attached to an arena. + + Repeated calls with the same state are no-ops. **/ + void __TBB_EXPORTED_METHOD observe( bool state=true ); + + //! Returns true if observation is enabled, false otherwise. + bool is_observing() const {return my_proxy!=NULL;} + + //! Construct observer with observation disabled. + task_scheduler_observer_v3() : my_proxy(NULL) { my_busy_count.store(0); } + + //! Entry notification + /** Invoked from inside observe(true) call and whenever a worker enters the arena + this observer is associated with. If a thread is already in the arena when + the observer is activated, the entry notification is called before it + executes the first stolen task. + + Obsolete semantics. For global observers it is called by a thread before + the first steal since observation became enabled. **/ + virtual void on_scheduler_entry( bool /*is_worker*/ ) {} + + //! Exit notification + /** Invoked from inside observe(false) call and whenever a worker leaves the + arena this observer is associated with. + + Obsolete semantics. For global observers it is called by a thread before + the first steal since observation became enabled. **/ + virtual void on_scheduler_exit( bool /*is_worker*/ ) {} + + //! Destructor automatically switches observation off if it is enabled. + virtual ~task_scheduler_observer_v3() { if(my_proxy) observe(false);} +}; + +} // namespace internal + +#if __TBB_ARENA_OBSERVER +namespace interface6 { +class task_scheduler_observer : public internal::task_scheduler_observer_v3 { + friend class internal::task_scheduler_observer_v3; + friend class internal::observer_proxy; + friend class internal::observer_list; + + /** Negative numbers with the largest absolute value to minimize probability + of coincidence in case of a bug in busy count usage. **/ + // TODO: take more high bits for version number + static const intptr_t v6_trait = (intptr_t)((~(uintptr_t)0 >> 1) + 1); + + //! contains task_arena pointer or tag indicating local or global semantics of the observer + intptr_t my_context_tag; + enum { global_tag = 0, implicit_tag = 1 }; + +public: + //! Construct local or global observer in inactive state (observation disabled). + /** For a local observer entry/exit notifications are invoked whenever a worker + thread joins/leaves the arena of the observer's owner thread. If a thread is + already in the arena when the observer is activated, the entry notification is + called before it executes the first stolen task. **/ + /** TODO: Obsolete. + Global observer semantics is obsolete as it violates master thread isolation + guarantees and is not composable. Thus the current default behavior of the + constructor is obsolete too and will be changed in one of the future versions + of the library. **/ + explicit task_scheduler_observer( bool local = false ) { +#if __TBB_ARENA_OBSERVER + my_context_tag = local? implicit_tag : global_tag; +#else + __TBB_ASSERT_EX( !local, NULL ); + my_context_tag = global_tag; +#endif + } + +#if __TBB_ARENA_OBSERVER + //! Construct local observer for a given arena in inactive state (observation disabled). + /** entry/exit notifications are invoked whenever a thread joins/leaves arena. + If a thread is already in the arena when the observer is activated, the entry notification + is called before it executes the first stolen task. **/ + explicit task_scheduler_observer( task_arena & a) { + my_context_tag = (intptr_t)&a; + } +#endif /* __TBB_ARENA_OBSERVER */ + + /** Destructor protects instance of the observer from concurrent notification. + It is recommended to disable observation before destructor of a derived class starts, + otherwise it can lead to concurrent notification callback on partly destroyed object **/ + virtual ~task_scheduler_observer() { if(my_proxy) observe(false); } + + //! Enable or disable observation + /** Warning: concurrent invocations of this method are not safe. + Repeated calls with the same state are no-ops. **/ + void observe( bool state=true ) { + if( state && !my_proxy ) { + __TBB_ASSERT( !my_busy_count, "Inconsistent state of task_scheduler_observer instance"); + my_busy_count.store(v6_trait); + } + internal::task_scheduler_observer_v3::observe(state); + } +}; + +} //namespace interface6 +using interface6::task_scheduler_observer; +#else /*__TBB_ARENA_OBSERVER*/ +typedef tbb::internal::task_scheduler_observer_v3 task_scheduler_observer; +#endif /*__TBB_ARENA_OBSERVER*/ + +} // namespace tbb + +#endif /* __TBB_SCHEDULER_OBSERVER */ + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_task_scheduler_observer_H_include_area + +#endif /* __TBB_task_scheduler_observer_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb.h new file mode 100644 index 00000000..f06ec5a3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb.h @@ -0,0 +1,97 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbb_H +#define __TBB_tbb_H + +#if (!defined(TBB_SUPPRESS_DEPRECATED_MESSAGES) || (TBB_SUPPRESS_DEPRECATED_MESSAGES == 0)) && !defined(__TBB_INTERNAL_INCLUDES_DEPRECATION_MESSAGE) +#pragma message("TBB Warning: tbb.h contains deprecated functionality. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#define __TBB_tbb_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +/** + This header bulk-includes declarations or definitions of all the functionality + provided by TBB (save for tbbmalloc and 3rd party dependent headers). + + If you use only a few TBB constructs, consider including specific headers only. + Any header listed below can be included independently of others. +**/ + +#if TBB_PREVIEW_AGGREGATOR +#include "aggregator.h" +#endif +#include "aligned_space.h" +#include "atomic.h" +#include "blocked_range.h" +#include "blocked_range2d.h" +#include "blocked_range3d.h" +#if TBB_PREVIEW_BLOCKED_RANGE_ND +#include "blocked_rangeNd.h" +#endif +#include "cache_aligned_allocator.h" +#include "combinable.h" +#include "concurrent_hash_map.h" +#if TBB_PREVIEW_CONCURRENT_LRU_CACHE +#include "concurrent_lru_cache.h" +#endif +#include "concurrent_priority_queue.h" +#include "concurrent_queue.h" +#include "concurrent_unordered_map.h" +#include "concurrent_unordered_set.h" +#if TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS +#include "concurrent_map.h" +#include "concurrent_set.h" +#endif +#include "concurrent_vector.h" +#include "critical_section.h" +#include "enumerable_thread_specific.h" +#include "flow_graph.h" +#include "global_control.h" +#include "iterators.h" +#include "mutex.h" +#include "null_mutex.h" +#include "null_rw_mutex.h" +#include "parallel_do.h" +#include "parallel_for.h" +#include "parallel_for_each.h" +#include "parallel_invoke.h" +#include "parallel_reduce.h" +#include "parallel_scan.h" +#include "parallel_sort.h" +#include "partitioner.h" +#include "pipeline.h" +#include "queuing_mutex.h" +#include "queuing_rw_mutex.h" +#include "reader_writer_lock.h" +#include "recursive_mutex.h" +#include "spin_mutex.h" +#include "spin_rw_mutex.h" +#include "task.h" +#include "task_arena.h" +#include "task_group.h" +#include "task_scheduler_init.h" +#include "task_scheduler_observer.h" +#include "tbb_allocator.h" +#include "tbb_exception.h" +#include "tbb_thread.h" +#include "tick_count.h" + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_tbb_H_include_area + +#endif /* __TBB_tbb_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_allocator.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_allocator.h new file mode 100644 index 00000000..ac0d1a6b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_allocator.h @@ -0,0 +1,203 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbb_allocator_H +#define __TBB_tbb_allocator_H + +#include "tbb_stddef.h" +#include +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + #include // std::forward +#endif +#include + +namespace tbb { + +//! @cond INTERNAL +namespace internal { + + //! Deallocates memory using FreeHandler + /** The function uses scalable_free if scalable allocator is available and free if not*/ + void __TBB_EXPORTED_FUNC deallocate_via_handler_v3( void *p ); + + //! Allocates memory using MallocHandler + /** The function uses scalable_malloc if scalable allocator is available and malloc if not*/ + void* __TBB_EXPORTED_FUNC allocate_via_handler_v3( size_t n ); + + //! Returns true if standard malloc/free are used to work with memory. + bool __TBB_EXPORTED_FUNC is_malloc_used_v3(); +} +//! @endcond + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for erroneous "unreferenced parameter" warning in method destroy. + #pragma warning (push) + #pragma warning (disable: 4100) +#endif + +//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 +/** The class selects the best memory allocation mechanism available + from scalable_malloc and standard malloc. + The members are ordered the same way they are in section 20.4.1 + of the ISO C++ standard. + @ingroup memory_allocation */ +template +class tbb_allocator { +public: + typedef typename internal::allocator_type::value_type value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template struct rebind { + typedef tbb_allocator other; + }; + + //! Specifies current allocator + enum malloc_type { + scalable, + standard + }; + + tbb_allocator() throw() {} + tbb_allocator( const tbb_allocator& ) throw() {} + template tbb_allocator(const tbb_allocator&) throw() {} + + pointer address(reference x) const {return &x;} + const_pointer address(const_reference x) const {return &x;} + + //! Allocate space for n objects. + pointer allocate( size_type n, const void* /*hint*/ = 0) { + return pointer(internal::allocate_via_handler_v3( n * sizeof(value_type) )); + } + + //! Free previously allocated block of memory. + void deallocate( pointer p, size_type ) { + internal::deallocate_via_handler_v3(p); + } + + //! Largest value for which method allocate might succeed. + size_type max_size() const throw() { + size_type max = static_cast(-1) / sizeof (value_type); + return (max > 0 ? max : 1); + } + + //! Copy-construct value at location pointed to by p. +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + template + void construct(U *p, Args&&... args) + { ::new((void *)p) U(std::forward(args)...); } +#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#if __TBB_CPP11_RVALUE_REF_PRESENT + void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));} +#endif + void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} +#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + + //! Destroy value at location pointed to by p. + void destroy( pointer p ) {p->~value_type();} + + //! Returns current allocator + static malloc_type allocator_type() { + return internal::is_malloc_used_v3() ? standard : scalable; + } +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warning 4100 is back + +//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 +/** @ingroup memory_allocation */ +template<> +class tbb_allocator { +public: + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + template struct rebind { + typedef tbb_allocator other; + }; +}; + +template +inline bool operator==( const tbb_allocator&, const tbb_allocator& ) {return true;} + +template +inline bool operator!=( const tbb_allocator&, const tbb_allocator& ) {return false;} + +//! Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5 +/** The class is an adapter over an actual allocator that fills the allocation + using memset function with template argument C as the value. + The members are ordered the same way they are in section 20.4.1 + of the ISO C++ standard. + @ingroup memory_allocation */ +template class Allocator = tbb_allocator> +class zero_allocator : public Allocator +{ +public: + typedef Allocator base_allocator_type; + typedef typename base_allocator_type::value_type value_type; + typedef typename base_allocator_type::pointer pointer; + typedef typename base_allocator_type::const_pointer const_pointer; + typedef typename base_allocator_type::reference reference; + typedef typename base_allocator_type::const_reference const_reference; + typedef typename base_allocator_type::size_type size_type; + typedef typename base_allocator_type::difference_type difference_type; + template struct rebind { + typedef zero_allocator other; + }; + + zero_allocator() throw() { } + zero_allocator(const zero_allocator &a) throw() : base_allocator_type( a ) { } + template + zero_allocator(const zero_allocator &a) throw() : base_allocator_type( Allocator( a ) ) { } + + pointer allocate(const size_type n, const void *hint = 0 ) { + pointer ptr = base_allocator_type::allocate( n, hint ); + std::memset( static_cast(ptr), 0, n * sizeof(value_type) ); + return ptr; + } +}; + +//! Analogous to std::allocator, as defined in ISO C++ Standard, Section 20.4.1 +/** @ingroup memory_allocation */ +template class Allocator> +class zero_allocator : public Allocator { +public: + typedef Allocator base_allocator_type; + typedef typename base_allocator_type::value_type value_type; + typedef typename base_allocator_type::pointer pointer; + typedef typename base_allocator_type::const_pointer const_pointer; + template struct rebind { + typedef zero_allocator other; + }; +}; + +template class B1, typename T2, template class B2> +inline bool operator==( const zero_allocator &a, const zero_allocator &b) { + return static_cast< B1 >(a) == static_cast< B2 >(b); +} +template class B1, typename T2, template class B2> +inline bool operator!=( const zero_allocator &a, const zero_allocator &b) { + return static_cast< B1 >(a) != static_cast< B2 >(b); +} + +} // namespace tbb + +#endif /* __TBB_tbb_allocator_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_config.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_config.h new file mode 100644 index 00000000..7a8d06a0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_config.h @@ -0,0 +1,873 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbb_config_H +#define __TBB_tbb_config_H + +/** This header is supposed to contain macro definitions and C style comments only. + The macros defined here are intended to control such aspects of TBB build as + - presence of compiler features + - compilation modes + - feature sets + - known compiler/platform issues +**/ + +/* This macro marks incomplete code or comments describing ideas which are considered for the future. + * See also for plain comment with TODO and FIXME marks for small improvement opportunities. + */ +#define __TBB_TODO 0 + +/* Check which standard library we use. */ +/* __TBB_SYMBOL is defined only while processing exported symbols list where C++ is not allowed. */ +#if !defined(__TBB_SYMBOL) && !__TBB_CONFIG_PREPROC_ONLY + #include +#endif + +// Note that when ICC or Clang is in use, __TBB_GCC_VERSION might not fully match +// the actual GCC version on the system. +#define __TBB_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) + +// Prior to GCC 7, GNU libstdc++ did not have a convenient version macro. +// Therefore we use different ways to detect its version. +#if defined(TBB_USE_GLIBCXX_VERSION) && !defined(_GLIBCXX_RELEASE) +// The version is explicitly specified in our public TBB_USE_GLIBCXX_VERSION macro. +// Its format should match the __TBB_GCC_VERSION above, e.g. 70301 for libstdc++ coming with GCC 7.3.1. +#define __TBB_GLIBCXX_VERSION TBB_USE_GLIBCXX_VERSION +#elif _GLIBCXX_RELEASE && _GLIBCXX_RELEASE != __GNUC__ +// Reported versions of GCC and libstdc++ do not match; trust the latter +#define __TBB_GLIBCXX_VERSION (_GLIBCXX_RELEASE*10000) +#elif __GLIBCPP__ || __GLIBCXX__ +// The version macro is not defined or matches the GCC version; use __TBB_GCC_VERSION +#define __TBB_GLIBCXX_VERSION __TBB_GCC_VERSION +#endif + +#if __clang__ + // according to clang documentation, version can be vendor specific + #define __TBB_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif + +/** Target OS is either iOS* or iOS* simulator **/ +#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ + #define __TBB_IOS 1 +#endif + +#if __APPLE__ + #if __INTEL_COMPILER && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1099 \ + && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101000 + // ICC does not correctly set the macro if -mmacosx-min-version is not specified + #define __TBB_MACOS_TARGET_VERSION (100000 + 10*(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ - 1000)) + #else + #define __TBB_MACOS_TARGET_VERSION __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ + #endif +#endif + +/** Preprocessor symbols to determine HW architecture **/ + +#if _WIN32||_WIN64 +# if defined(_M_X64)||defined(__x86_64__) // the latter for MinGW support +# define __TBB_x86_64 1 +# elif defined(_M_IA64) +# define __TBB_ipf 1 +# elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support +# define __TBB_x86_32 1 +# else +# define __TBB_generic_arch 1 +# endif +#else /* Assume generic Unix */ +# if !__linux__ && !__APPLE__ +# define __TBB_generic_os 1 +# endif +# if __TBB_IOS +# define __TBB_generic_arch 1 +# elif __x86_64__ +# define __TBB_x86_64 1 +# elif __ia64__ +# define __TBB_ipf 1 +# elif __i386__||__i386 // __i386 is for Sun OS +# define __TBB_x86_32 1 +# else +# define __TBB_generic_arch 1 +# endif +#endif + +#if __MIC__ || __MIC2__ +#define __TBB_DEFINE_MIC 1 +#endif + +#define __TBB_TSX_AVAILABLE ((__TBB_x86_32 || __TBB_x86_64) && !__TBB_DEFINE_MIC) + +/** Presence of compiler features **/ + +#if __INTEL_COMPILER == 9999 && __INTEL_COMPILER_BUILD_DATE == 20110811 +/* Intel(R) Composer XE 2011 Update 6 incorrectly sets __INTEL_COMPILER. Fix it. */ + #undef __INTEL_COMPILER + #define __INTEL_COMPILER 1210 +#endif + +#if __clang__ && !__INTEL_COMPILER +#define __TBB_USE_OPTIONAL_RTTI __has_feature(cxx_rtti) +#elif defined(_CPPRTTI) +#define __TBB_USE_OPTIONAL_RTTI 1 +#else +#define __TBB_USE_OPTIONAL_RTTI (__GXX_RTTI || __RTTI || __INTEL_RTTI__) +#endif + +#if __TBB_GCC_VERSION >= 40400 && !defined(__INTEL_COMPILER) + /** warning suppression pragmas available in GCC since 4.4 **/ + #define __TBB_GCC_WARNING_SUPPRESSION_PRESENT 1 +#endif + +/* Select particular features of C++11 based on compiler version. + ICC 12.1 (Linux*), GCC 4.3 and higher, clang 2.9 and higher + set __GXX_EXPERIMENTAL_CXX0X__ in c++11 mode. + + Compilers that mimics other compilers (ICC, clang) must be processed before + compilers they mimic (GCC, MSVC). + + TODO: The following conditions should be extended when new compilers/runtimes + support added. + */ + +/** + __TBB_CPP11_PRESENT macro indicates that the compiler supports vast majority of C++11 features. + Depending on the compiler, some features might still be unsupported or work incorrectly. + Use it when enabling C++11 features individually is not practical, and be aware that + some "good enough" compilers might be excluded. **/ +#define __TBB_CPP11_PRESENT (__cplusplus >= 201103L || _MSC_VER >= 1900) + +#define __TBB_CPP17_FALLTHROUGH_PRESENT (__cplusplus >= 201703L) +#define __TBB_FALLTHROUGH_PRESENT (__TBB_GCC_VERSION >= 70000 && !__INTEL_COMPILER) + +/** C++11 mode detection macros for Intel(R) C++ Compiler (enabled by -std=c++XY option): + __INTEL_CXX11_MODE__ for version >=13.0 (not available for ICC 15.0 if -std=c++14 is used), + __STDC_HOSTED__ for version >=12.0 (useful only on Windows), + __GXX_EXPERIMENTAL_CXX0X__ for version >=12.0 on Linux and macOS. **/ +#if __INTEL_COMPILER && !__INTEL_CXX11_MODE__ + // __INTEL_CXX11_MODE__ is not set, try to deduce it + #define __INTEL_CXX11_MODE__ (__GXX_EXPERIMENTAL_CXX0X__ || (_MSC_VER && __STDC_HOSTED__)) +#endif + +#if __INTEL_COMPILER && (!_MSC_VER || __INTEL_CXX11_MODE__) + // On Windows, C++11 features supported by Visual Studio 2010 and higher are enabled by default, + // so in absence of /Qstd= use MSVC branch for feature detection. + // On other platforms, no -std= means C++03. + + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (__INTEL_CXX11_MODE__ && __VARIADIC_TEMPLATES) + // Both r-value reference support in compiler and std::move/std::forward + // presence in C++ standard library is checked. + #define __TBB_CPP11_RVALUE_REF_PRESENT ((_MSC_VER >= 1700 || __GXX_EXPERIMENTAL_CXX0X__ && (__TBB_GLIBCXX_VERSION >= 40500 || _LIBCPP_VERSION)) && __INTEL_COMPILER >= 1400) + #define __TBB_IMPLICIT_MOVE_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 && (_MSC_VER >= 1900 || __TBB_GCC_VERSION >= 40600 || __clang__)) + #if _MSC_VER >= 1600 + #define __TBB_EXCEPTION_PTR_PRESENT ( __INTEL_COMPILER > 1300 \ + /*ICC 12.1 Upd 10 and 13 beta Upd 2 fixed exception_ptr linking issue*/ \ + || (__INTEL_COMPILER == 1300 && __INTEL_COMPILER_BUILD_DATE >= 20120530) \ + || (__INTEL_COMPILER == 1210 && __INTEL_COMPILER_BUILD_DATE >= 20120410) ) + /** libstdc++ that comes with GCC 4.6 use C++11 features not supported by ICC 12.1. + * Because of that ICC 12.1 does not support C++11 mode with gcc 4.6 (or higher), + * and therefore does not define __GXX_EXPERIMENTAL_CXX0X__ macro **/ + #elif __TBB_GLIBCXX_VERSION >= 40404 && __TBB_GLIBCXX_VERSION < 40600 + #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1200) + #elif __TBB_GLIBCXX_VERSION >= 40600 + #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1300) + #elif _LIBCPP_VERSION + #define __TBB_EXCEPTION_PTR_PRESENT __GXX_EXPERIMENTAL_CXX0X__ + #else + #define __TBB_EXCEPTION_PTR_PRESENT 0 + #endif + #define __TBB_STATIC_ASSERT_PRESENT (__INTEL_CXX11_MODE__ || _MSC_VER >= 1600) + #define __TBB_CPP11_TUPLE_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && (__TBB_GLIBCXX_VERSION >= 40300 || _LIBCPP_VERSION)) + #define __TBB_INITIALIZER_LISTS_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 && (_MSC_VER >= 1800 || __TBB_GLIBCXX_VERSION >= 40400 || _LIBCPP_VERSION)) + #define __TBB_CONSTEXPR_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400) + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200) + /** ICC seems to disable support of noexcept event in c++11 when compiling in compatibility mode for gcc <4.6 **/ + #define __TBB_NOEXCEPT_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1300 && (__TBB_GLIBCXX_VERSION >= 40600 || _LIBCPP_VERSION || _MSC_VER)) + #define __TBB_CPP11_STD_BEGIN_END_PRESENT (_MSC_VER >= 1700 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1310 && (__TBB_GLIBCXX_VERSION >= 40600 || _LIBCPP_VERSION)) + #define __TBB_CPP11_AUTO_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) + #define __TBB_CPP11_DECLTYPE_PRESENT (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) + #define __TBB_CPP11_LAMBDAS_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200) + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT (_MSC_VER >= 1800 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210) + #define __TBB_OVERRIDE_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400) + #define __TBB_ALIGNAS_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1500) + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT (__INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1210) + #define __TBB_CPP14_INTEGER_SEQUENCE_PRESENT (__cplusplus >= 201402L) + #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (__cplusplus >= 201402L) + #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (__INTEL_COMPILER > 1910) // a future version + #define __TBB_CPP17_INVOKE_RESULT_PRESENT (__cplusplus >= 201703L) +#elif __clang__ +/** TODO: these options need to be rechecked **/ + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT __has_feature(__cxx_variadic_templates__) + #define __TBB_CPP11_RVALUE_REF_PRESENT (__has_feature(__cxx_rvalue_references__) && (_LIBCPP_VERSION || __TBB_GLIBCXX_VERSION >= 40500)) + #define __TBB_IMPLICIT_MOVE_PRESENT __has_feature(cxx_implicit_moves) +/** TODO: extend exception_ptr related conditions to cover libstdc++ **/ + #define __TBB_EXCEPTION_PTR_PRESENT (__cplusplus >= 201103L && (_LIBCPP_VERSION || __TBB_GLIBCXX_VERSION >= 40600)) + #define __TBB_STATIC_ASSERT_PRESENT __has_feature(__cxx_static_assert__) + #if (__cplusplus >= 201103L && __has_include()) + #define __TBB_CPP11_TUPLE_PRESENT 1 + #endif + #if (__has_feature(__cxx_generalized_initializers__) && __has_include()) + #define __TBB_INITIALIZER_LISTS_PRESENT 1 + #endif + #define __TBB_CONSTEXPR_PRESENT __has_feature(__cxx_constexpr__) + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__has_feature(__cxx_defaulted_functions__) && __has_feature(__cxx_deleted_functions__)) + /**For some unknown reason __has_feature(__cxx_noexcept) does not yield true for all cases. Compiler bug ? **/ + #define __TBB_NOEXCEPT_PRESENT (__cplusplus >= 201103L) + #define __TBB_CPP11_STD_BEGIN_END_PRESENT (__has_feature(__cxx_range_for__) && (_LIBCPP_VERSION || __TBB_GLIBCXX_VERSION >= 40600)) + #define __TBB_CPP11_AUTO_PRESENT __has_feature(__cxx_auto_type__) + #define __TBB_CPP11_DECLTYPE_PRESENT __has_feature(__cxx_decltype__) + #define __TBB_CPP11_LAMBDAS_PRESENT __has_feature(cxx_lambdas) + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT __has_feature(cxx_default_function_template_args) + #define __TBB_OVERRIDE_PRESENT __has_feature(cxx_override_control) + #define __TBB_ALIGNAS_PRESENT __has_feature(cxx_alignas) + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT __has_feature(cxx_alias_templates) + #define __TBB_CPP14_INTEGER_SEQUENCE_PRESENT (__cplusplus >= 201402L) + #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (__has_feature(cxx_variable_templates)) + #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (__has_feature(__cpp_deduction_guides)) + #define __TBB_CPP17_INVOKE_RESULT_PRESENT (__has_feature(__cpp_lib_is_invocable)) +#elif __GNUC__ + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT __GXX_EXPERIMENTAL_CXX0X__ + #define __TBB_CPP11_VARIADIC_FIXED_LENGTH_EXP_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700) + #define __TBB_CPP11_RVALUE_REF_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40500) + #define __TBB_IMPLICIT_MOVE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) + /** __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 here is a substitution for _GLIBCXX_ATOMIC_BUILTINS_4, which is a prerequisite + for exception_ptr but cannot be used in this file because it is defined in a header, not by the compiler. + If the compiler has no atomic intrinsics, the C++ library should not expect those as well. **/ + #define __TBB_EXCEPTION_PTR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40404 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + #define __TBB_STATIC_ASSERT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) + #define __TBB_CPP11_TUPLE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) + #define __TBB_INITIALIZER_LISTS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + /** gcc seems have to support constexpr from 4.4 but tests in (test_atomic) seeming reasonable fail to compile prior 4.6**/ + #define __TBB_CONSTEXPR_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_NOEXCEPT_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) + #define __TBB_CPP11_STD_BEGIN_END_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600) + #define __TBB_CPP11_AUTO_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_CPP11_DECLTYPE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400) + #define __TBB_CPP11_LAMBDAS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40500) + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300) + #define __TBB_OVERRIDE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700) + #define __TBB_ALIGNAS_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40800) + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700) + #define __TBB_CPP14_INTEGER_SEQUENCE_PRESENT (__cplusplus >= 201402L && __TBB_GCC_VERSION >= 50000) + #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (__cplusplus >= 201402L && __TBB_GCC_VERSION >= 50000) + #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (__cpp_deduction_guides >= 201606L) + #define __TBB_CPP17_INVOKE_RESULT_PRESENT (__cplusplus >= 201703L && __TBB_GCC_VERSION >= 70000) +#elif _MSC_VER + // These definitions are also used with Intel C++ Compiler in "default" mode (__INTEL_CXX11_MODE__ == 0); + // see a comment in "__INTEL_COMPILER" section above. + + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT (_MSC_VER >= 1800) + // Contains a workaround for ICC 13 + #define __TBB_CPP11_RVALUE_REF_PRESENT (_MSC_VER >= 1700 && (!__INTEL_COMPILER || __INTEL_COMPILER >= 1400)) + #define __TBB_IMPLICIT_MOVE_PRESENT (_MSC_VER >= 1900) + #define __TBB_EXCEPTION_PTR_PRESENT (_MSC_VER >= 1600) + #define __TBB_STATIC_ASSERT_PRESENT (_MSC_VER >= 1600) + #define __TBB_CPP11_TUPLE_PRESENT (_MSC_VER >= 1600) + #define __TBB_INITIALIZER_LISTS_PRESENT (_MSC_VER >= 1800) + #define __TBB_CONSTEXPR_PRESENT (_MSC_VER >= 1900) + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT (_MSC_VER >= 1800) + #define __TBB_NOEXCEPT_PRESENT (_MSC_VER >= 1900) + #define __TBB_CPP11_STD_BEGIN_END_PRESENT (_MSC_VER >= 1700) + #define __TBB_CPP11_AUTO_PRESENT (_MSC_VER >= 1600) + #define __TBB_CPP11_DECLTYPE_PRESENT (_MSC_VER >= 1600) + #define __TBB_CPP11_LAMBDAS_PRESENT (_MSC_VER >= 1600) + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT (_MSC_VER >= 1800) + #define __TBB_OVERRIDE_PRESENT (_MSC_VER >= 1700) + #define __TBB_ALIGNAS_PRESENT (_MSC_VER >= 1900) + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT (_MSC_VER >= 1800) + #define __TBB_CPP14_INTEGER_SEQUENCE_PRESENT (_MSC_VER >= 1900) + /* Variable templates are supported in VS2015 Update 2 or later */ + #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (_MSC_FULL_VER >= 190023918 && (!__INTEL_COMPILER || __INTEL_COMPILER >= 1700)) + #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (_MSVC_LANG >= 201703L && _MSC_VER >= 1914) + #define __TBB_CPP17_INVOKE_RESULT_PRESENT (_MSVC_LANG >= 201703L && _MSC_VER >= 1911) +#else + #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP11_RVALUE_REF_PRESENT __TBB_CPP11_PRESENT + #define __TBB_IMPLICIT_MOVE_PRESENT __TBB_CPP11_PRESENT + #define __TBB_EXCEPTION_PTR_PRESENT __TBB_CPP11_PRESENT + #define __TBB_STATIC_ASSERT_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP11_TUPLE_PRESENT __TBB_CPP11_PRESENT + #define __TBB_INITIALIZER_LISTS_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CONSTEXPR_PRESENT __TBB_CPP11_PRESENT + #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT __TBB_CPP11_PRESENT + #define __TBB_NOEXCEPT_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP11_STD_BEGIN_END_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP11_AUTO_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP11_DECLTYPE_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP11_LAMBDAS_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT __TBB_CPP11_PRESENT + #define __TBB_OVERRIDE_PRESENT __TBB_CPP11_PRESENT + #define __TBB_ALIGNAS_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP11_TEMPLATE_ALIASES_PRESENT __TBB_CPP11_PRESENT + #define __TBB_CPP14_INTEGER_SEQUENCE_PRESENT (__cplusplus >= 201402L) + #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (__cplusplus >= 201402L) + #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (__cplusplus >= 201703L) + #define __TBB_CPP17_INVOKE_RESULT_PRESENT (__cplusplus >= 201703L) +#endif + +// C++11 standard library features + +#define __TBB_CPP11_ARRAY_PRESENT (_MSC_VER >= 1700 || _LIBCPP_VERSION || __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GLIBCXX_VERSION >= 40300) + +#ifndef __TBB_CPP11_VARIADIC_FIXED_LENGTH_EXP_PRESENT +#define __TBB_CPP11_VARIADIC_FIXED_LENGTH_EXP_PRESENT __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif +#define __TBB_CPP11_VARIADIC_TUPLE_PRESENT (!_MSC_VER || _MSC_VER >= 1800) + +#define __TBB_CPP11_TYPE_PROPERTIES_PRESENT (_LIBCPP_VERSION || _MSC_VER >= 1700 || (__TBB_GLIBCXX_VERSION >= 50000 && __GXX_EXPERIMENTAL_CXX0X__)) +// GCC supported some of type properties since 4.7 +#define __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GLIBCXX_VERSION >= 40700 || __TBB_CPP11_TYPE_PROPERTIES_PRESENT) + +// In GCC, std::move_if_noexcept appeared later than noexcept +#define __TBB_MOVE_IF_NOEXCEPT_PRESENT (__TBB_NOEXCEPT_PRESENT && (__TBB_GLIBCXX_VERSION >= 40700 || _MSC_VER >= 1900 || _LIBCPP_VERSION)) +#define __TBB_ALLOCATOR_TRAITS_PRESENT (__cplusplus >= 201103L && _LIBCPP_VERSION || _MSC_VER >= 1800 || \ + __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GLIBCXX_VERSION >= 40700 && !(__TBB_GLIBCXX_VERSION == 40700 && __TBB_DEFINE_MIC)) +#define __TBB_MAKE_EXCEPTION_PTR_PRESENT (__TBB_EXCEPTION_PTR_PRESENT && (_MSC_VER >= 1700 || __TBB_GLIBCXX_VERSION >= 40600 || _LIBCPP_VERSION || __SUNPRO_CC)) + +// Due to libc++ limitations in C++03 mode, do not pass rvalues to std::make_shared() +#define __TBB_CPP11_SMART_POINTERS_PRESENT ( _MSC_VER >= 1600 || _LIBCPP_VERSION \ + || ((__cplusplus >= 201103L || __GXX_EXPERIMENTAL_CXX0X__) \ + && (__TBB_GLIBCXX_VERSION >= 40500 || __TBB_GLIBCXX_VERSION >= 40400 && __TBB_USE_OPTIONAL_RTTI)) ) + +#define __TBB_CPP11_FUTURE_PRESENT (_MSC_VER >= 1700 || __TBB_GLIBCXX_VERSION >= 40600 && __GXX_EXPERIMENTAL_CXX0X__ || _LIBCPP_VERSION) + +#define __TBB_CPP11_GET_NEW_HANDLER_PRESENT (_MSC_VER >= 1900 || __TBB_GLIBCXX_VERSION >= 40900 && __GXX_EXPERIMENTAL_CXX0X__ || _LIBCPP_VERSION) + +#define __TBB_CPP17_UNCAUGHT_EXCEPTIONS_PRESENT (_MSC_VER >= 1900 || __GLIBCXX__ && __cpp_lib_uncaught_exceptions \ + || _LIBCPP_VERSION >= 3700 && (!__TBB_MACOS_TARGET_VERSION || __TBB_MACOS_TARGET_VERSION >= 101200)) +// TODO: wait when memory_resource will be fully supported in clang and define the right macro +// Currently it is in experimental stage since 6 version. +#define __TBB_CPP17_MEMORY_RESOURCE_PRESENT (_MSC_VER >= 1913 && (_MSVC_LANG > 201402L || __cplusplus > 201402L) || \ + __GLIBCXX__ && __cpp_lib_memory_resource >= 201603) +#define __TBB_CPP17_HW_INTERFERENCE_SIZE_PRESENT (_MSC_VER >= 1911) +// std::swap is in only since C++11, though MSVC had it at least since VS2005 +#if _MSC_VER>=1400 || _LIBCPP_VERSION || __GXX_EXPERIMENTAL_CXX0X__ +#define __TBB_STD_SWAP_HEADER +#else +#define __TBB_STD_SWAP_HEADER +#endif + +//TODO: not clear how exactly this macro affects exception_ptr - investigate +// On linux ICC fails to find existing std::exception_ptr in libstdc++ without this define +#if __INTEL_COMPILER && __GNUC__ && __TBB_EXCEPTION_PTR_PRESENT && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +#endif + +// Work around a bug in MinGW32 +#if __MINGW32__ && __TBB_EXCEPTION_PTR_PRESENT && !defined(_GLIBCXX_ATOMIC_BUILTINS_4) + #define _GLIBCXX_ATOMIC_BUILTINS_4 +#endif + +#if __GNUC__ || __SUNPRO_CC || __IBMCPP__ + /* ICC defines __GNUC__ and so is covered */ + #define __TBB_ATTRIBUTE_ALIGNED_PRESENT 1 +#elif _MSC_VER && (_MSC_VER >= 1300 || __INTEL_COMPILER) + #define __TBB_DECLSPEC_ALIGN_PRESENT 1 +#endif + +/* Actually ICC supports gcc __sync_* intrinsics starting 11.1, + * but 64 bit support for 32 bit target comes in later ones*/ +/* TODO: change the version back to 4.1.2 once macro __TBB_WORD_SIZE become optional */ +/* Assumed that all clang versions have these gcc compatible intrinsics. */ +#if __TBB_GCC_VERSION >= 40306 || __INTEL_COMPILER >= 1200 || __clang__ + /** built-in atomics available in GCC since 4.1.2 **/ + #define __TBB_GCC_BUILTIN_ATOMICS_PRESENT 1 +#endif + +#if __TBB_GCC_VERSION >= 70000 && !__INTEL_COMPILER && !__clang__ + // After GCC7 there was possible reordering problem in generic atomic load/store operations. + // So always using builtins. + #define TBB_USE_GCC_BUILTINS 1 +#endif + +#if __INTEL_COMPILER >= 1200 + /** built-in C++11 style atomics available in ICC since 12.0 **/ + #define __TBB_ICC_BUILTIN_ATOMICS_PRESENT 1 +#endif + +#if _MSC_VER>=1600 && (!__INTEL_COMPILER || __INTEL_COMPILER>=1310) + #define __TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT 1 +#endif + +#define __TBB_TSX_INTRINSICS_PRESENT ((__RTM__ || _MSC_VER>=1700 || __INTEL_COMPILER>=1300) && !__TBB_DEFINE_MIC && !__ANDROID__) + +/** Macro helpers **/ +#define __TBB_CONCAT_AUX(A,B) A##B +// The additional level of indirection is needed to expand macros A and B (not to get the AB macro). +// See [cpp.subst] and [cpp.concat] for more details. +#define __TBB_CONCAT(A,B) __TBB_CONCAT_AUX(A,B) +// The IGNORED argument and comma are needed to always have 2 arguments (even when A is empty). +#define __TBB_IS_MACRO_EMPTY(A,IGNORED) __TBB_CONCAT_AUX(__TBB_MACRO_EMPTY,A) +#define __TBB_MACRO_EMPTY 1 + +/** User controlled TBB features & modes **/ +#ifndef TBB_USE_DEBUG +/* +There are four cases that are supported: + 1. "_DEBUG is undefined" means "no debug"; + 2. "_DEBUG defined to something that is evaluated to 0" (including "garbage", as per [cpp.cond]) means "no debug"; + 3. "_DEBUG defined to something that is evaluated to a non-zero value" means "debug"; + 4. "_DEBUG defined to nothing (empty)" means "debug". +*/ +#ifdef _DEBUG +// Check if _DEBUG is empty. +#define __TBB_IS__DEBUG_EMPTY (__TBB_IS_MACRO_EMPTY(_DEBUG,IGNORED)==__TBB_MACRO_EMPTY) +#if __TBB_IS__DEBUG_EMPTY +#define TBB_USE_DEBUG 1 +#else +#define TBB_USE_DEBUG _DEBUG +#endif /* __TBB_IS__DEBUG_EMPTY */ +#else +#define TBB_USE_DEBUG 0 +#endif +#endif /* TBB_USE_DEBUG */ + +#ifndef TBB_USE_ASSERT +#define TBB_USE_ASSERT TBB_USE_DEBUG +#endif /* TBB_USE_ASSERT */ + +#ifndef TBB_USE_THREADING_TOOLS +#define TBB_USE_THREADING_TOOLS TBB_USE_DEBUG +#endif /* TBB_USE_THREADING_TOOLS */ + +#ifndef TBB_USE_PERFORMANCE_WARNINGS +#ifdef TBB_PERFORMANCE_WARNINGS +#define TBB_USE_PERFORMANCE_WARNINGS TBB_PERFORMANCE_WARNINGS +#else +#define TBB_USE_PERFORMANCE_WARNINGS TBB_USE_DEBUG +#endif /* TBB_PERFORMANCE_WARNINGS */ +#endif /* TBB_USE_PERFORMANCE_WARNINGS */ + +#if __TBB_DEFINE_MIC + #if TBB_USE_EXCEPTIONS + #error The platform does not properly support exception handling. Please do not set TBB_USE_EXCEPTIONS macro or set it to 0. + #elif !defined(TBB_USE_EXCEPTIONS) + #define TBB_USE_EXCEPTIONS 0 + #endif +#elif !(__EXCEPTIONS || defined(_CPPUNWIND) || __SUNPRO_CC) + #if TBB_USE_EXCEPTIONS + #error Compilation settings do not support exception handling. Please do not set TBB_USE_EXCEPTIONS macro or set it to 0. + #elif !defined(TBB_USE_EXCEPTIONS) + #define TBB_USE_EXCEPTIONS 0 + #endif +#elif !defined(TBB_USE_EXCEPTIONS) + #define TBB_USE_EXCEPTIONS 1 +#endif + +#ifndef TBB_IMPLEMENT_CPP0X +/** By default, use C++11 classes if available **/ + #if __clang__ + /* Old versions of Intel C++ Compiler do not have __has_include or cannot use it in #define */ + #if (__INTEL_COMPILER && (__INTEL_COMPILER < 1500 || __INTEL_COMPILER == 1500 && __INTEL_COMPILER_UPDATE <= 1)) + #define TBB_IMPLEMENT_CPP0X (__cplusplus < 201103L || !_LIBCPP_VERSION) + #else + #define TBB_IMPLEMENT_CPP0X (__cplusplus < 201103L || (!__has_include() && !__has_include())) + #endif + #elif __GNUC__ + #define TBB_IMPLEMENT_CPP0X (__TBB_GCC_VERSION < 40400 || !__GXX_EXPERIMENTAL_CXX0X__) + #elif _MSC_VER + #define TBB_IMPLEMENT_CPP0X (_MSC_VER < 1700) + #else + // TODO: Reconsider general approach to be more reliable, e.g. (!(__cplusplus >= 201103L && __ STDC_HOSTED__)) + #define TBB_IMPLEMENT_CPP0X (!__STDCPP_THREADS__) + #endif +#endif /* TBB_IMPLEMENT_CPP0X */ + +/* TBB_USE_CAPTURED_EXCEPTION should be explicitly set to either 0 or 1, as it is used as C++ const */ +#ifndef TBB_USE_CAPTURED_EXCEPTION + /** IA-64 architecture pre-built TBB binaries do not support exception_ptr. **/ + #if __TBB_EXCEPTION_PTR_PRESENT && !defined(__ia64__) + #define TBB_USE_CAPTURED_EXCEPTION 0 + #else + #define TBB_USE_CAPTURED_EXCEPTION 1 + #endif +#else /* defined TBB_USE_CAPTURED_EXCEPTION */ + #if !TBB_USE_CAPTURED_EXCEPTION && !__TBB_EXCEPTION_PTR_PRESENT + #error Current runtime does not support std::exception_ptr. Set TBB_USE_CAPTURED_EXCEPTION and make sure that your code is ready to catch tbb::captured_exception. + #endif +#endif /* defined TBB_USE_CAPTURED_EXCEPTION */ + +/** Check whether the request to use GCC atomics can be satisfied **/ +#if TBB_USE_GCC_BUILTINS && !__TBB_GCC_BUILTIN_ATOMICS_PRESENT + #error "GCC atomic built-ins are not supported." +#endif + +/** Internal TBB features & modes **/ + +/** __TBB_CONCURRENT_ORDERED_CONTAINERS indicates that all conditions of use + * concurrent_map and concurrent_set are met. **/ +// TODO: Add cpp11 random generation macro +#ifndef __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT + #define __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT ( __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT \ + && __TBB_IMPLICIT_MOVE_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_LAMBDAS_PRESENT && __TBB_CPP11_ARRAY_PRESENT \ + && __TBB_INITIALIZER_LISTS_PRESENT ) +#endif + +/** __TBB_WEAK_SYMBOLS_PRESENT denotes that the system supports the weak symbol mechanism **/ +#ifndef __TBB_WEAK_SYMBOLS_PRESENT +#define __TBB_WEAK_SYMBOLS_PRESENT ( !_WIN32 && !__APPLE__ && !__sun && (__TBB_GCC_VERSION >= 40000 || __INTEL_COMPILER ) ) +#endif + +/** __TBB_DYNAMIC_LOAD_ENABLED describes the system possibility to load shared libraries at run time **/ +#ifndef __TBB_DYNAMIC_LOAD_ENABLED + #define __TBB_DYNAMIC_LOAD_ENABLED 1 +#endif + +/** __TBB_SOURCE_DIRECTLY_INCLUDED is a mode used in whitebox testing when + it's necessary to test internal functions not exported from TBB DLLs +**/ +#if (_WIN32||_WIN64) && (__TBB_SOURCE_DIRECTLY_INCLUDED || TBB_USE_PREVIEW_BINARY) + #define __TBB_NO_IMPLICIT_LINKAGE 1 + #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1 +#endif + +#ifndef __TBB_COUNT_TASK_NODES + #define __TBB_COUNT_TASK_NODES TBB_USE_ASSERT +#endif + +#ifndef __TBB_TASK_GROUP_CONTEXT + #define __TBB_TASK_GROUP_CONTEXT 1 +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#ifndef __TBB_SCHEDULER_OBSERVER + #define __TBB_SCHEDULER_OBSERVER 1 +#endif /* __TBB_SCHEDULER_OBSERVER */ + +#ifndef __TBB_FP_CONTEXT + #define __TBB_FP_CONTEXT __TBB_TASK_GROUP_CONTEXT +#endif /* __TBB_FP_CONTEXT */ + +#if __TBB_FP_CONTEXT && !__TBB_TASK_GROUP_CONTEXT + #error __TBB_FP_CONTEXT requires __TBB_TASK_GROUP_CONTEXT to be enabled +#endif + +#define __TBB_RECYCLE_TO_ENQUEUE __TBB_BUILD // keep non-official + +#ifndef __TBB_ARENA_OBSERVER + #define __TBB_ARENA_OBSERVER __TBB_SCHEDULER_OBSERVER +#endif /* __TBB_ARENA_OBSERVER */ + +#ifndef __TBB_TASK_ISOLATION + #define __TBB_TASK_ISOLATION 1 +#endif /* __TBB_TASK_ISOLATION */ + +#if TBB_USE_EXCEPTIONS && !__TBB_TASK_GROUP_CONTEXT + #error TBB_USE_EXCEPTIONS requires __TBB_TASK_GROUP_CONTEXT to be enabled +#endif + +#ifndef __TBB_TASK_PRIORITY + #define __TBB_TASK_PRIORITY (__TBB_TASK_GROUP_CONTEXT) +#endif /* __TBB_TASK_PRIORITY */ + +#if __TBB_TASK_PRIORITY && !__TBB_TASK_GROUP_CONTEXT + #error __TBB_TASK_PRIORITY requires __TBB_TASK_GROUP_CONTEXT to be enabled +#endif + +#if TBB_PREVIEW_NUMA_SUPPORT || __TBB_BUILD + #define __TBB_NUMA_SUPPORT 1 +#endif + +#if TBB_PREVIEW_WAITING_FOR_WORKERS || __TBB_BUILD + #define __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE 1 +#endif + +#ifndef __TBB_ENQUEUE_ENFORCED_CONCURRENCY + #define __TBB_ENQUEUE_ENFORCED_CONCURRENCY 1 +#endif + +#if !defined(__TBB_SURVIVE_THREAD_SWITCH) && \ + (_WIN32 || _WIN64 || __APPLE__ || (__linux__ && !__ANDROID__)) + #define __TBB_SURVIVE_THREAD_SWITCH 1 +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ + +#ifndef __TBB_DEFAULT_PARTITIONER +#define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner +#endif + +#ifndef __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES +#define __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES 1 +#endif + +#ifndef __TBB_ENABLE_RANGE_FEEDBACK +#define __TBB_ENABLE_RANGE_FEEDBACK 0 +#endif + +#ifdef _VARIADIC_MAX + #define __TBB_VARIADIC_MAX _VARIADIC_MAX +#else + #if _MSC_VER == 1700 + #define __TBB_VARIADIC_MAX 5 // VS11 setting, issue resolved in VS12 + #elif _MSC_VER == 1600 + #define __TBB_VARIADIC_MAX 10 // VS10 setting + #else + #define __TBB_VARIADIC_MAX 15 + #endif +#endif + +// Intel C++ Compiler starts analyzing usages of the deprecated content at the template +// instantiation site, which is too late for suppression of the corresponding messages for internal +// stuff. +#if !defined(__INTEL_COMPILER) && (!defined(TBB_SUPPRESS_DEPRECATED_MESSAGES) || (TBB_SUPPRESS_DEPRECATED_MESSAGES == 0)) + #if (__cplusplus >= 201402L) + #define __TBB_DEPRECATED [[deprecated]] + #define __TBB_DEPRECATED_MSG(msg) [[deprecated(msg)]] + #elif _MSC_VER + #define __TBB_DEPRECATED __declspec(deprecated) + #define __TBB_DEPRECATED_MSG(msg) __declspec(deprecated(msg)) + #elif (__GNUC__ && __TBB_GCC_VERSION >= 40805) || __clang__ + #define __TBB_DEPRECATED __attribute__((deprecated)) + #define __TBB_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) + #endif +#endif // !defined(TBB_SUPPRESS_DEPRECATED_MESSAGES) || (TBB_SUPPRESS_DEPRECATED_MESSAGES == 0) + +#if !defined(__TBB_DEPRECATED) + #define __TBB_DEPRECATED + #define __TBB_DEPRECATED_MSG(msg) +#elif !defined(__TBB_SUPPRESS_INTERNAL_DEPRECATED_MESSAGES) + // Suppress deprecated messages from self + #define __TBB_SUPPRESS_INTERNAL_DEPRECATED_MESSAGES 1 +#endif + +#if defined(TBB_SUPPRESS_DEPRECATED_MESSAGES) && (TBB_SUPPRESS_DEPRECATED_MESSAGES == 0) + #define __TBB_DEPRECATED_IN_VERBOSE_MODE __TBB_DEPRECATED + #define __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG(msg) __TBB_DEPRECATED_MSG(msg) +#else + #define __TBB_DEPRECATED_IN_VERBOSE_MODE + #define __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG(msg) +#endif // (TBB_SUPPRESS_DEPRECATED_MESSAGES == 0) + +#if (!defined(TBB_SUPPRESS_DEPRECATED_MESSAGES) || (TBB_SUPPRESS_DEPRECATED_MESSAGES == 0)) && !__TBB_CPP11_PRESENT + #pragma message("TBB Warning: Support for C++98/03 is deprecated. Please use the compiler that supports C++11 features at least.") +#endif + +/** __TBB_WIN8UI_SUPPORT enables support of Windows* Store Apps and limit a possibility to load + shared libraries at run time only from application container **/ +// TODO: Separate this single macro into two for Windows 8 Store* (win8ui mode) and UWP/UWD modes. +#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP + #define __TBB_WIN8UI_SUPPORT 1 +#else + #define __TBB_WIN8UI_SUPPORT 0 +#endif + +/** Macros of the form __TBB_XXX_BROKEN denote known issues that are caused by + the bugs in compilers, standard or OS specific libraries. They should be + removed as soon as the corresponding bugs are fixed or the buggy OS/compiler + versions go out of the support list. +**/ + +#if __SIZEOF_POINTER__ < 8 && __ANDROID__ && __TBB_GCC_VERSION <= 40403 && !__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 + /** Necessary because on Android 8-byte CAS and F&A are not available for some processor architectures, + but no mandatory warning message appears from GCC 4.4.3. Instead, only a linkage error occurs when + these atomic operations are used (such as in unit test test_atomic.exe). **/ + #define __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN 1 +#elif __TBB_x86_32 && __TBB_GCC_VERSION == 40102 && ! __GNUC_RH_RELEASE__ + /** GCC 4.1.2 erroneously emit call to external function for 64 bit sync_ intrinsics. + However these functions are not defined anywhere. It seems that this problem was fixed later on + and RHEL got an updated version of gcc 4.1.2. **/ + #define __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN 1 +#endif + +#if __GNUC__ && __TBB_x86_64 && __INTEL_COMPILER == 1200 + #define __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN 1 +#endif + +#if _MSC_VER && __INTEL_COMPILER && (__INTEL_COMPILER<1110 || __INTEL_COMPILER==1110 && __INTEL_COMPILER_BUILD_DATE < 20091012) + /** Necessary to avoid ICL error (or warning in non-strict mode): + "exception specification for implicitly declared virtual destructor is + incompatible with that of overridden one". **/ + #define __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN 1 +#endif + +#if !__INTEL_COMPILER && (_MSC_VER && _MSC_VER < 1500 || __GNUC__ && __TBB_GCC_VERSION < 40102) + /** gcc 3.4.6 (and earlier) and VS2005 (and earlier) do not allow declaring template class as a friend + of classes defined in other namespaces. **/ + #define __TBB_TEMPLATE_FRIENDS_BROKEN 1 +#endif + +#if __GLIBC__==2 && __GLIBC_MINOR__==3 || (__APPLE__ && ( __INTEL_COMPILER==1200 && !TBB_USE_DEBUG)) + /** Macro controlling EH usages in TBB tests. + Some older versions of glibc crash when exception handling happens concurrently. **/ + #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 1 +#endif + +#if (_WIN32||_WIN64) && __INTEL_COMPILER == 1110 + /** That's a bug in Intel C++ Compiler 11.1.044/IA-32 architecture/Windows* OS, that leads to a worker thread crash on the thread's startup. **/ + #define __TBB_ICL_11_1_CODE_GEN_BROKEN 1 +#endif + +#if __clang__ || (__GNUC__==3 && __GNUC_MINOR__==3 && !defined(__INTEL_COMPILER)) + /** Bugs with access to nested classes declared in protected area */ + #define __TBB_PROTECTED_NESTED_CLASS_BROKEN 1 +#endif + +#if __MINGW32__ && __TBB_GCC_VERSION < 40200 + /** MinGW has a bug with stack alignment for routines invoked from MS RTLs. + Since GCC 4.2, the bug can be worked around via a special attribute. **/ + #define __TBB_SSE_STACK_ALIGNMENT_BROKEN 1 +#endif + +#if __TBB_GCC_VERSION==40300 && !__INTEL_COMPILER && !__clang__ + /* GCC of this version may rashly ignore control dependencies */ + #define __TBB_GCC_OPTIMIZER_ORDERING_BROKEN 1 +#endif + +#if __FreeBSD__ + /** A bug in FreeBSD 8.0 results in kernel panic when there is contention + on a mutex created with this attribute. **/ + #define __TBB_PRIO_INHERIT_BROKEN 1 + + /** A bug in FreeBSD 8.0 results in test hanging when an exception occurs + during (concurrent?) object construction by means of placement new operator. **/ + #define __TBB_PLACEMENT_NEW_EXCEPTION_SAFETY_BROKEN 1 +#endif /* __FreeBSD__ */ + +#if (__linux__ || __APPLE__) && __i386__ && defined(__INTEL_COMPILER) + /** The Intel C++ Compiler for IA-32 architecture (Linux* OS|macOS) crashes or generates + incorrect code when __asm__ arguments have a cast to volatile. **/ + #define __TBB_ICC_ASM_VOLATILE_BROKEN 1 +#endif + +#if !__INTEL_COMPILER && (_MSC_VER && _MSC_VER < 1700 || __GNUC__==3 && __GNUC_MINOR__<=2) + /** Bug in GCC 3.2 and MSVC compilers that sometimes return 0 for __alignof(T) + when T has not yet been instantiated. **/ + #define __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN 1 +#endif + +#if __TBB_DEFINE_MIC + /** Main thread and user's thread have different default thread affinity masks. **/ + #define __TBB_MAIN_THREAD_AFFINITY_BROKEN 1 +#endif + +#if __GXX_EXPERIMENTAL_CXX0X__ && !defined(__EXCEPTIONS) && \ + ((!__INTEL_COMPILER && !__clang__ && (__TBB_GCC_VERSION>=40400 && __TBB_GCC_VERSION<40600)) || \ + (__INTEL_COMPILER<=1400 && (__TBB_GLIBCXX_VERSION>=40400 && __TBB_GLIBCXX_VERSION<=40801))) +/* There is an issue for specific GCC toolchain when C++11 is enabled + and exceptions are disabled: + exceprion_ptr.h/nested_exception.h use throw unconditionally. + GCC can ignore 'throw' since 4.6; but with ICC the issue still exists. + */ + #define __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN 1 +#endif + +#if __INTEL_COMPILER==1300 && __TBB_GLIBCXX_VERSION>=40700 && defined(__GXX_EXPERIMENTAL_CXX0X__) +/* Some C++11 features used inside libstdc++ are not supported by Intel C++ Compiler. */ + #define __TBB_ICC_13_0_CPP11_STDLIB_SUPPORT_BROKEN 1 +#endif + +#if (__GNUC__==4 && __GNUC_MINOR__==4 ) && !defined(__INTEL_COMPILER) && !defined(__clang__) + /** excessive warnings related to strict aliasing rules in GCC 4.4 **/ + #define __TBB_GCC_STRICT_ALIASING_BROKEN 1 + /* topical remedy: #pragma GCC diagnostic ignored "-Wstrict-aliasing" */ + #if !__TBB_GCC_WARNING_SUPPRESSION_PRESENT + #error Warning suppression is not supported, while should. + #endif +#endif + +/* In a PIC mode some versions of GCC 4.1.2 generate incorrect inlined code for 8 byte __sync_val_compare_and_swap intrinsic */ +#if __TBB_GCC_VERSION == 40102 && __PIC__ && !defined(__INTEL_COMPILER) && !defined(__clang__) + #define __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN 1 +#endif + +#if __TBB_x86_32 && ( __INTEL_COMPILER || (__GNUC__==5 && __GNUC_MINOR__>=2 && __GXX_EXPERIMENTAL_CXX0X__) \ + || (__GNUC__==3 && __GNUC_MINOR__==3) || (__MINGW32__ && __GNUC__==4 && __GNUC_MINOR__==5) || __SUNPRO_CC ) + // Some compilers for IA-32 architecture fail to provide 8-byte alignment of objects on the stack, + // even if the object specifies 8-byte alignment. On such platforms, the implementation + // of 64 bit atomics for IA-32 architecture (e.g. atomic) use different tactics + // depending upon whether the object is properly aligned or not. + #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 1 +#else + // Define to 0 explicitly because the macro is used in a compiled code of test_atomic + #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 0 +#endif + +#if __GNUC__ && !__INTEL_COMPILER && !__clang__ && __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && __TBB_GCC_VERSION < 40700 + #define __TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN 1 +#endif + +#if _MSC_VER && _MSC_VER <= 1800 && !__INTEL_COMPILER + // With MSVC, when an array is passed by const reference to a template function, + // constness from the function parameter may get propagated to the template parameter. + #define __TBB_CONST_REF_TO_ARRAY_TEMPLATE_PARAM_BROKEN 1 +#endif + +// A compiler bug: a disabled copy constructor prevents use of the moving constructor +#define __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN (_MSC_VER && (__INTEL_COMPILER >= 1300 && __INTEL_COMPILER <= 1310) && !__INTEL_CXX11_MODE__) + +#define __TBB_CPP11_DECLVAL_BROKEN (_MSC_VER == 1600 || (__GNUC__ && __TBB_GCC_VERSION < 40500) ) +// Intel C++ Compiler has difficulties with copying std::pair with VC11 std::reference_wrapper being a const member +#define __TBB_COPY_FROM_NON_CONST_REF_BROKEN (_MSC_VER == 1700 && __INTEL_COMPILER && __INTEL_COMPILER < 1600) + +// The implicit upcasting of the tuple of a reference of a derived class to a base class fails on icc 13.X if the system's gcc environment is 4.8 +// Also in gcc 4.4 standard library the implementation of the tuple<&> conversion (tuple a = tuple, B is inherited from A) is broken. +#if __GXX_EXPERIMENTAL_CXX0X__ && __GLIBCXX__ && ((__INTEL_COMPILER >=1300 && __INTEL_COMPILER <=1310 && __TBB_GLIBCXX_VERSION>=40700) || (__TBB_GLIBCXX_VERSION < 40500)) +#define __TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN 1 +#endif + +// In some cases decltype of a function adds a reference to a return type. +#define __TBB_CPP11_DECLTYPE_OF_FUNCTION_RETURN_TYPE_BROKEN (_MSC_VER == 1600 && !__INTEL_COMPILER) + +// Visual Studio 2013 does not delete the copy constructor when a user-defined move constructor is provided +#if _MSC_VER && _MSC_VER <= 1800 + #define __TBB_IMPLICIT_COPY_DELETION_BROKEN 1 +#endif + +/** End of __TBB_XXX_BROKEN macro section **/ + +#if defined(_MSC_VER) && _MSC_VER>=1500 && !defined(__INTEL_COMPILER) + // A macro to suppress erroneous or benign "unreachable code" MSVC warning (4702) + #define __TBB_MSVC_UNREACHABLE_CODE_IGNORED 1 +#endif + +#define __TBB_ATOMIC_CTORS (__TBB_CONSTEXPR_PRESENT && __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && (!__TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN)) + +// Many OS versions (Android 4.0.[0-3] for example) need workaround for dlopen to avoid non-recursive loader lock hang +// Setting the workaround for all compile targets ($APP_PLATFORM) below Android 4.4 (android-19) +#if __ANDROID__ +#include +#define __TBB_USE_DLOPEN_REENTRANCY_WORKAROUND (__ANDROID_API__ < 19) +#endif + +#define __TBB_ALLOCATOR_CONSTRUCT_VARIADIC (__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT) + +#define __TBB_VARIADIC_PARALLEL_INVOKE (TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT) +#define __TBB_FLOW_GRAPH_CPP11_FEATURES (__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT \ + && __TBB_CPP11_SMART_POINTERS_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_AUTO_PRESENT) \ + && __TBB_CPP11_VARIADIC_TUPLE_PRESENT && __TBB_CPP11_DEFAULT_FUNC_TEMPLATE_ARGS_PRESENT \ + && !__TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN +#define __TBB_PREVIEW_STREAMING_NODE (__TBB_CPP11_VARIADIC_FIXED_LENGTH_EXP_PRESENT && __TBB_FLOW_GRAPH_CPP11_FEATURES \ + && TBB_PREVIEW_FLOW_GRAPH_NODES && !TBB_IMPLEMENT_CPP0X && !__TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN) +#define __TBB_PREVIEW_OPENCL_NODE (__TBB_PREVIEW_STREAMING_NODE && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT) +#define __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING (TBB_PREVIEW_FLOW_GRAPH_FEATURES || __TBB_PREVIEW_OPENCL_NODE) +#define __TBB_PREVIEW_ASYNC_MSG (TBB_PREVIEW_FLOW_GRAPH_FEATURES && __TBB_FLOW_GRAPH_CPP11_FEATURES) + + +#ifndef __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#define __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES TBB_PREVIEW_FLOW_GRAPH_FEATURES +#endif + +// This feature works only in combination with critical tasks (__TBB_PREVIEW_CRITICAL_TASKS) +#ifndef __TBB_PREVIEW_RESUMABLE_TASKS +#define __TBB_PREVIEW_RESUMABLE_TASKS ((__TBB_CPF_BUILD || TBB_PREVIEW_RESUMABLE_TASKS) && !__TBB_WIN8UI_SUPPORT && !__ANDROID__ && !__TBB_ipf) +#endif + +#ifndef __TBB_PREVIEW_CRITICAL_TASKS +#define __TBB_PREVIEW_CRITICAL_TASKS (__TBB_CPF_BUILD || __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES || __TBB_PREVIEW_RESUMABLE_TASKS) +#endif + +#ifndef __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#define __TBB_PREVIEW_FLOW_GRAPH_NODE_SET (TBB_PREVIEW_FLOW_GRAPH_FEATURES && __TBB_CPP11_PRESENT && __TBB_FLOW_GRAPH_CPP11_FEATURES) +#endif + +#endif /* __TBB_tbb_config_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_disable_exceptions.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_disable_exceptions.h new file mode 100644 index 00000000..69ef5c57 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_disable_exceptions.h @@ -0,0 +1,31 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +//! To disable use of exceptions, include this header before any other header file from the library. + +//! The macro that prevents use of exceptions in the library files +#undef TBB_USE_EXCEPTIONS +#define TBB_USE_EXCEPTIONS 0 + +//! Prevent compilers from issuing exception related warnings. +/** Note that the warnings are suppressed for all the code after this header is included. */ +#if _MSC_VER +#if __INTEL_COMPILER + #pragma warning (disable: 583) +#else + #pragma warning (disable: 4530 4577) +#endif +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_exception.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_exception.h new file mode 100644 index 00000000..3c5fb7dd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_exception.h @@ -0,0 +1,362 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_exception_H +#define __TBB_exception_H + +#define __TBB_tbb_exception_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_stddef.h" +#include +#include // required for bad_alloc definition, operators new +#include // required to construct std exception classes + +namespace tbb { + +//! Exception for concurrent containers +class bad_last_alloc : public std::bad_alloc { +public: + const char* what() const throw() __TBB_override; +#if __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN + ~bad_last_alloc() throw() __TBB_override {} +#endif +}; + +//! Exception for PPL locks +class __TBB_DEPRECATED improper_lock : public std::exception { +public: + const char* what() const throw() __TBB_override; +}; + +//! Exception for user-initiated abort +class user_abort : public std::exception { +public: + const char* what() const throw() __TBB_override; +}; + +//! Exception for missing wait on structured_task_group +class missing_wait : public std::exception { +public: + const char* what() const throw() __TBB_override; +}; + +//! Exception for repeated scheduling of the same task_handle +class invalid_multiple_scheduling : public std::exception { +public: + const char* what() const throw() __TBB_override; +}; + +namespace internal { +//! Obsolete +void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4(); + +enum exception_id { + eid_bad_alloc = 1, + eid_bad_last_alloc, + eid_nonpositive_step, + eid_out_of_range, + eid_segment_range_error, + eid_index_range_error, + eid_missing_wait, + eid_invalid_multiple_scheduling, + eid_improper_lock, + eid_possible_deadlock, + eid_operation_not_permitted, + eid_condvar_wait_failed, + eid_invalid_load_factor, + eid_reserved, // free slot for backward compatibility, can be reused. + eid_invalid_swap, + eid_reservation_length_error, + eid_invalid_key, + eid_user_abort, + eid_reserved1, +#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE + // This id is used only from inside the library and only for support of CPF functionality. + // So, if we drop the functionality, eid_reserved1 can be safely renamed and reused. + eid_blocking_thread_join_impossible = eid_reserved1, +#endif + eid_bad_tagged_msg_cast, + //! The last enumerator tracks the number of defined IDs. It must remain the last one. + /** When adding new IDs, place them immediately _before_ this comment (that is + _after_ all the existing IDs. NEVER insert new IDs between the existing ones. **/ + eid_max +}; + +//! Gathers all throw operators in one place. +/** Its purpose is to minimize code bloat that can be caused by throw operators + scattered in multiple places, especially in templates. **/ +void __TBB_EXPORTED_FUNC throw_exception_v4 ( exception_id ); + +//! Versionless convenience wrapper for throw_exception_v4() +inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); } + +} // namespace internal +} // namespace tbb + +#if __TBB_TASK_GROUP_CONTEXT +#include "tbb_allocator.h" +#include //for typeid + +namespace tbb { + +//! Interface to be implemented by all exceptions TBB recognizes and propagates across the threads. +/** If an unhandled exception of the type derived from tbb::tbb_exception is intercepted + by the TBB scheduler in one of the worker threads, it is delivered to and re-thrown in + the root thread. The root thread is the thread that has started the outermost algorithm + or root task sharing the same task_group_context with the guilty algorithm/task (the one + that threw the exception first). + + Note: when documentation mentions workers with respect to exception handling, + masters are implied as well, because they are completely equivalent in this context. + Consequently a root thread can be master or worker thread. + + NOTE: In case of nested algorithms or complex task hierarchies when the nested + levels share (explicitly or by means of implicit inheritance) the task group + context of the outermost level, the exception may be (re-)thrown multiple times + (ultimately - in each worker on each nesting level) before reaching the root + thread at the outermost level. IMPORTANT: if you intercept an exception derived + from this class on a nested level, you must re-throw it in the catch block by means + of the "throw;" operator. + + TBB provides two implementations of this interface: tbb::captured_exception and + template class tbb::movable_exception. See their declarations for more info. **/ +class __TBB_DEPRECATED tbb_exception : public std::exception +{ + /** No operator new is provided because the TBB usage model assumes dynamic + creation of the TBB exception objects only by means of applying move() + operation on an exception thrown out of TBB scheduler. **/ + void* operator new ( size_t ); + +public: +#if __clang__ + // At -O3 or even -O2 optimization level, Clang may fully throw away an empty destructor + // of tbb_exception from destructors of derived classes. As a result, it does not create + // vtable for tbb_exception, which is a required part of TBB binary interface. + // Making the destructor non-empty (with just a semicolon) prevents that optimization. + ~tbb_exception() throw() { /* keep the semicolon! */ ; } +#endif + + //! Creates and returns pointer to the deep copy of this exception object. + /** Move semantics is allowed. **/ + virtual tbb_exception* move() throw() = 0; + + //! Destroys objects created by the move() method. + /** Frees memory and calls destructor for this exception object. + Can and must be used only on objects created by the move method. **/ + virtual void destroy() throw() = 0; + + //! Throws this exception object. + /** Make sure that if you have several levels of derivation from this interface + you implement or override this method on the most derived level. The implementation + is as simple as "throw *this;". Failure to do this will result in exception + of a base class type being thrown. **/ + virtual void throw_self() = 0; + + //! Returns RTTI name of the originally intercepted exception + virtual const char* name() const throw() = 0; + + //! Returns the result of originally intercepted exception's what() method. + virtual const char* what() const throw() __TBB_override = 0; + + /** Operator delete is provided only to allow using existing smart pointers + with TBB exception objects obtained as the result of applying move() + operation on an exception thrown out of TBB scheduler. + + When overriding method move() make sure to override operator delete as well + if memory is allocated not by TBB's scalable allocator. **/ + void operator delete ( void* p ) { + internal::deallocate_via_handler_v3(p); + } +}; + +//! This class is used by TBB to propagate information about unhandled exceptions into the root thread. +/** Exception of this type is thrown by TBB in the root thread (thread that started a parallel + algorithm ) if an unhandled exception was intercepted during the algorithm execution in one + of the workers. + \sa tbb::tbb_exception **/ +class __TBB_DEPRECATED_IN_VERBOSE_MODE captured_exception : public tbb_exception +{ +public: + captured_exception( const captured_exception& src ) + : tbb_exception(src), my_dynamic(false) + { + set(src.my_exception_name, src.my_exception_info); + } + + captured_exception( const char* name_, const char* info ) + : my_dynamic(false) + { + set(name_, info); + } + + __TBB_EXPORTED_METHOD ~captured_exception() throw(); + + captured_exception& operator= ( const captured_exception& src ) { + if ( this != &src ) { + clear(); + set(src.my_exception_name, src.my_exception_info); + } + return *this; + } + + captured_exception* __TBB_EXPORTED_METHOD move() throw() __TBB_override; + + void __TBB_EXPORTED_METHOD destroy() throw() __TBB_override; + + void throw_self() __TBB_override { __TBB_THROW(*this); } + + const char* __TBB_EXPORTED_METHOD name() const throw() __TBB_override; + + const char* __TBB_EXPORTED_METHOD what() const throw() __TBB_override; + + void __TBB_EXPORTED_METHOD set( const char* name, const char* info ) throw(); + void __TBB_EXPORTED_METHOD clear() throw(); + +private: + //! Used only by method move(). + captured_exception() : my_dynamic(), my_exception_name(), my_exception_info() {} + + //! Functionally equivalent to {captured_exception e(name,info); return e.move();} + static captured_exception* allocate( const char* name, const char* info ); + + bool my_dynamic; + const char* my_exception_name; + const char* my_exception_info; +}; + +//! Template that can be used to implement exception that transfers arbitrary ExceptionData to the root thread +/** Code using TBB can instantiate this template with an arbitrary ExceptionData type + and throw this exception object. Such exceptions are intercepted by the TBB scheduler + and delivered to the root thread (). + \sa tbb::tbb_exception **/ +template +class __TBB_DEPRECATED movable_exception : public tbb_exception +{ + typedef movable_exception self_type; + +public: + movable_exception( const ExceptionData& data_ ) + : my_exception_data(data_) + , my_dynamic(false) + , my_exception_name( +#if TBB_USE_EXCEPTIONS + typeid(self_type).name() +#else /* !TBB_USE_EXCEPTIONS */ + "movable_exception" +#endif /* !TBB_USE_EXCEPTIONS */ + ) + {} + + movable_exception( const movable_exception& src ) throw () + : tbb_exception(src) + , my_exception_data(src.my_exception_data) + , my_dynamic(false) + , my_exception_name(src.my_exception_name) + {} + + ~movable_exception() throw() {} + + const movable_exception& operator= ( const movable_exception& src ) { + if ( this != &src ) { + my_exception_data = src.my_exception_data; + my_exception_name = src.my_exception_name; + } + return *this; + } + + ExceptionData& data() throw() { return my_exception_data; } + + const ExceptionData& data() const throw() { return my_exception_data; } + + const char* name() const throw() __TBB_override { return my_exception_name; } + + const char* what() const throw() __TBB_override { return "tbb::movable_exception"; } + + movable_exception* move() throw() __TBB_override { + void* e = internal::allocate_via_handler_v3(sizeof(movable_exception)); + if ( e ) { + ::new (e) movable_exception(*this); + ((movable_exception*)e)->my_dynamic = true; + } + return (movable_exception*)e; + } + void destroy() throw() __TBB_override { + __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" ); + if ( my_dynamic ) { + this->~movable_exception(); + internal::deallocate_via_handler_v3(this); + } + } + void throw_self() __TBB_override { __TBB_THROW( *this ); } + +protected: + //! User data + ExceptionData my_exception_data; + +private: + //! Flag specifying whether this object has been dynamically allocated (by the move method) + bool my_dynamic; + + //! RTTI name of this class + /** We rely on the fact that RTTI names are static string constants. **/ + const char* my_exception_name; +}; + +#if !TBB_USE_CAPTURED_EXCEPTION +namespace internal { + +//! Exception container that preserves the exact copy of the original exception +/** This class can be used only when the appropriate runtime support (mandated + by C++11) is present **/ +class tbb_exception_ptr { + std::exception_ptr my_ptr; + +public: + static tbb_exception_ptr* allocate(); + static tbb_exception_ptr* allocate( const tbb_exception& tag ); + //! This overload uses move semantics (i.e. it empties src) + static tbb_exception_ptr* allocate( captured_exception& src ); + + //! Destroys this objects + /** Note that objects of this type can be created only by the allocate() method. **/ + void destroy() throw(); + + //! Throws the contained exception . + void throw_self() { std::rethrow_exception(my_ptr); } + +private: + tbb_exception_ptr( const std::exception_ptr& src ) : my_ptr(src) {} + tbb_exception_ptr( const captured_exception& src ) : + #if __TBB_MAKE_EXCEPTION_PTR_PRESENT + my_ptr(std::make_exception_ptr(src)) // the final function name in C++11 + #else + my_ptr(std::copy_exception(src)) // early C++0x drafts name + #endif + {} +}; // class tbb::internal::tbb_exception_ptr + +} // namespace internal +#endif /* !TBB_USE_CAPTURED_EXCEPTION */ + +} // namespace tbb + +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_tbb_exception_H_include_area + +#endif /* __TBB_exception_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_machine.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_machine.h new file mode 100644 index 00000000..9752be58 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_machine.h @@ -0,0 +1,978 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_machine_H +#define __TBB_machine_H + +/** This header provides basic platform abstraction layer by hooking up appropriate + architecture/OS/compiler specific headers from the /include/tbb/machine directory. + If a plug-in header does not implement all the required APIs, it must specify + the missing ones by setting one or more of the following macros: + + __TBB_USE_GENERIC_PART_WORD_CAS + __TBB_USE_GENERIC_PART_WORD_FETCH_ADD + __TBB_USE_GENERIC_PART_WORD_FETCH_STORE + __TBB_USE_GENERIC_FETCH_ADD + __TBB_USE_GENERIC_FETCH_STORE + __TBB_USE_GENERIC_DWORD_FETCH_ADD + __TBB_USE_GENERIC_DWORD_FETCH_STORE + __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE + __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE + __TBB_USE_GENERIC_RELAXED_LOAD_STORE + __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE + + In this case tbb_machine.h will add missing functionality based on a minimal set + of APIs that are required to be implemented by all plug-n headers as described + further. + Note that these generic implementations may be sub-optimal for a particular + architecture, and thus should be relied upon only after careful evaluation + or as the last resort. + + Additionally __TBB_64BIT_ATOMICS can be set to 0 on a 32-bit architecture to + indicate that the port is not going to support double word atomics. It may also + be set to 1 explicitly, though normally this is not necessary as tbb_machine.h + will set it automatically. + + __TBB_ENDIANNESS macro can be defined by the implementation as well. + It is used only if __TBB_USE_GENERIC_PART_WORD_CAS is set (or for testing), + and must specify the layout of aligned 16-bit and 32-bit data anywhere within a process + (while the details of unaligned 16-bit or 32-bit data or of 64-bit data are irrelevant). + The layout must be the same at all relevant memory locations within the current process; + in case of page-specific endianness, one endianness must be kept "out of sight". + Possible settings, reflecting hardware and possibly O.S. convention, are: + - __TBB_ENDIAN_BIG for big-endian data, + - __TBB_ENDIAN_LITTLE for little-endian data, + - __TBB_ENDIAN_DETECT for run-time detection iff exactly one of the above, + - __TBB_ENDIAN_UNSUPPORTED to prevent undefined behavior if none of the above. + + Prerequisites for each architecture port + ---------------------------------------- + The following functions and macros have no generic implementation. Therefore they must be + implemented in each machine architecture specific header either as a conventional + function or as a functional macro. + + __TBB_WORDSIZE + This is the size of machine word in bytes, i.e. for 32 bit systems it + should be defined to 4. + + __TBB_Yield() + Signals OS that the current thread is willing to relinquish the remainder + of its time quantum. + + __TBB_full_memory_fence() + Must prevent all memory operations from being reordered across it (both + by hardware and compiler). All such fences must be totally ordered (or + sequentially consistent). + + __TBB_machine_cmpswp4( volatile void *ptr, int32_t value, int32_t comparand ) + Must be provided if __TBB_USE_FENCED_ATOMICS is not set. + + __TBB_machine_cmpswp8( volatile void *ptr, int32_t value, int64_t comparand ) + Must be provided for 64-bit architectures if __TBB_USE_FENCED_ATOMICS is not set, + and for 32-bit architectures if __TBB_64BIT_ATOMICS is set + + __TBB_machine_(...), where + = {cmpswp, fetchadd, fetchstore} + = {1, 2, 4, 8} + = {full_fence, acquire, release, relaxed} + Must be provided if __TBB_USE_FENCED_ATOMICS is set. + + __TBB_control_consistency_helper() + Bridges the memory-semantics gap between architectures providing only + implicit C++0x "consume" semantics (like Power Architecture) and those + also implicitly obeying control dependencies (like IA-64 architecture). + It must be used only in conditional code where the condition is itself + data-dependent, and will then make subsequent code behave as if the + original data dependency were acquired. + It needs only a compiler fence where implied by the architecture + either specifically (like IA-64 architecture) or because generally stronger + "acquire" semantics are enforced (like x86). + It is always valid, though potentially suboptimal, to replace + control with acquire on the load and then remove the helper. + + __TBB_acquire_consistency_helper(), __TBB_release_consistency_helper() + Must be provided if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE is set. + Enforce acquire and release semantics in generic implementations of fenced + store and load operations. Depending on the particular architecture/compiler + combination they may be a hardware fence, a compiler fence, both or nothing. + **/ + +#include "tbb_stddef.h" + +namespace tbb { +namespace internal { //< @cond INTERNAL + +//////////////////////////////////////////////////////////////////////////////// +// Overridable helpers declarations +// +// A machine/*.h file may choose to define these templates, otherwise it must +// request default implementation by setting appropriate __TBB_USE_GENERIC_XXX macro(s). +// +template +struct machine_load_store; + +template +struct machine_load_store_relaxed; + +template +struct machine_load_store_seq_cst; +// +// End of overridable helpers declarations +//////////////////////////////////////////////////////////////////////////////// + +template struct atomic_selector; + +template<> struct atomic_selector<1> { + typedef int8_t word; + inline static word fetch_store ( volatile void* location, word value ); +}; + +template<> struct atomic_selector<2> { + typedef int16_t word; + inline static word fetch_store ( volatile void* location, word value ); +}; + +template<> struct atomic_selector<4> { +#if _MSC_VER && !_WIN64 + // Work-around that avoids spurious /Wp64 warnings + typedef intptr_t word; +#else + typedef int32_t word; +#endif + inline static word fetch_store ( volatile void* location, word value ); +}; + +template<> struct atomic_selector<8> { + typedef int64_t word; + inline static word fetch_store ( volatile void* location, word value ); +}; + +}} //< namespaces internal @endcond, tbb + +#define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M) \ + inline void __TBB_machine_generic_store8##M(volatile void *ptr, int64_t value) { \ + for(;;) { \ + int64_t result = *(volatile int64_t *)ptr; \ + if( __TBB_machine_cmpswp8##M(ptr,value,result)==result ) break; \ + } \ + } \ + +#define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M) \ + inline int64_t __TBB_machine_generic_load8##M(const volatile void *ptr) { \ + /* Comparand and new value may be anything, they only must be equal, and */ \ + /* the value should have a low probability to be actually found in 'location'.*/ \ + const int64_t anyvalue = 2305843009213693951LL; \ + return __TBB_machine_cmpswp8##M(const_cast(ptr),anyvalue,anyvalue); \ + } \ + +// The set of allowed values for __TBB_ENDIANNESS (see above for details) +#define __TBB_ENDIAN_UNSUPPORTED -1 +#define __TBB_ENDIAN_LITTLE 0 +#define __TBB_ENDIAN_BIG 1 +#define __TBB_ENDIAN_DETECT 2 + +#if _WIN32||_WIN64 + +#ifdef _MANAGED +#pragma managed(push, off) +#endif + + #if __MINGW64__ || __MINGW32__ + extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void ); + #define __TBB_Yield() SwitchToThread() + #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) + #include "machine/gcc_generic.h" + #elif __MINGW64__ + #include "machine/linux_intel64.h" + #elif __MINGW32__ + #include "machine/linux_ia32.h" + #endif + #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) + #include "machine/icc_generic.h" + #elif defined(_M_IX86) && !defined(__TBB_WIN32_USE_CL_BUILTINS) + #include "machine/windows_ia32.h" + #elif defined(_M_X64) + #include "machine/windows_intel64.h" + #elif defined(_M_ARM) || defined(__TBB_WIN32_USE_CL_BUILTINS) + #include "machine/msvc_armv7.h" + #endif + +#ifdef _MANAGED +#pragma managed(pop) +#endif + +#elif __TBB_DEFINE_MIC + + #include "machine/mic_common.h" + #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) + #include "machine/icc_generic.h" + #else + #include "machine/linux_intel64.h" + #endif + +#elif __linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ + + #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT) + #include "machine/gcc_generic.h" + #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) + #include "machine/icc_generic.h" + #elif __i386__ + #include "machine/linux_ia32.h" + #elif __x86_64__ + #include "machine/linux_intel64.h" + #elif __ia64__ + #include "machine/linux_ia64.h" + #elif __powerpc__ + #include "machine/mac_ppc.h" + #elif __ARM_ARCH_7A__ || __aarch64__ + #include "machine/gcc_arm.h" + #elif __TBB_GCC_BUILTIN_ATOMICS_PRESENT + #include "machine/gcc_generic.h" + #endif + #include "machine/linux_common.h" + +#elif __APPLE__ + //TODO: TBB_USE_GCC_BUILTINS is not used for Mac, Sun, Aix + #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT) + #include "machine/icc_generic.h" + #elif __TBB_x86_32 + #include "machine/linux_ia32.h" + #elif __TBB_x86_64 + #include "machine/linux_intel64.h" + #elif __POWERPC__ + #include "machine/mac_ppc.h" + #endif + #include "machine/macos_common.h" + +#elif _AIX + + #include "machine/ibm_aix51.h" + +#elif __sun || __SUNPRO_CC + + #define __asm__ asm + #define __volatile__ volatile + + #if __i386 || __i386__ + #include "machine/linux_ia32.h" + #elif __x86_64__ + #include "machine/linux_intel64.h" + #elif __sparc + #include "machine/sunos_sparc.h" + #endif + #include + + #define __TBB_Yield() sched_yield() + +#endif /* OS selection */ + +#ifndef __TBB_64BIT_ATOMICS + #define __TBB_64BIT_ATOMICS 1 +#endif + +//TODO: replace usage of these functions with usage of tbb::atomic, and then remove them +//TODO: map functions with W suffix to use cast to tbb::atomic and according op, i.e. as_atomic().op() +// Special atomic functions +#if __TBB_USE_FENCED_ATOMICS + #define __TBB_machine_cmpswp1 __TBB_machine_cmpswp1full_fence + #define __TBB_machine_cmpswp2 __TBB_machine_cmpswp2full_fence + #define __TBB_machine_cmpswp4 __TBB_machine_cmpswp4full_fence + #define __TBB_machine_cmpswp8 __TBB_machine_cmpswp8full_fence + + #if __TBB_WORDSIZE==8 + #define __TBB_machine_fetchadd8 __TBB_machine_fetchadd8full_fence + #define __TBB_machine_fetchstore8 __TBB_machine_fetchstore8full_fence + #define __TBB_FetchAndAddWrelease(P,V) __TBB_machine_fetchadd8release(P,V) + #define __TBB_FetchAndIncrementWacquire(P) __TBB_machine_fetchadd8acquire(P,1) + #define __TBB_FetchAndDecrementWrelease(P) __TBB_machine_fetchadd8release(P,(-1)) + #else + #define __TBB_machine_fetchadd4 __TBB_machine_fetchadd4full_fence + #define __TBB_machine_fetchstore4 __TBB_machine_fetchstore4full_fence + #define __TBB_FetchAndAddWrelease(P,V) __TBB_machine_fetchadd4release(P,V) + #define __TBB_FetchAndIncrementWacquire(P) __TBB_machine_fetchadd4acquire(P,1) + #define __TBB_FetchAndDecrementWrelease(P) __TBB_machine_fetchadd4release(P,(-1)) + #endif /* __TBB_WORDSIZE==4 */ +#else /* !__TBB_USE_FENCED_ATOMICS */ + #define __TBB_FetchAndAddWrelease(P,V) __TBB_FetchAndAddW(P,V) + #define __TBB_FetchAndIncrementWacquire(P) __TBB_FetchAndAddW(P,1) + #define __TBB_FetchAndDecrementWrelease(P) __TBB_FetchAndAddW(P,(-1)) +#endif /* !__TBB_USE_FENCED_ATOMICS */ + +#if __TBB_WORDSIZE==4 + #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp4(P,V,C) + #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd4(P,V) + #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore4(P,V) +#elif __TBB_WORDSIZE==8 + #if __TBB_USE_GENERIC_DWORD_LOAD_STORE || __TBB_USE_GENERIC_DWORD_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_STORE + #error These macros should only be used on 32-bit platforms. + #endif + + #define __TBB_CompareAndSwapW(P,V,C) __TBB_machine_cmpswp8(P,V,C) + #define __TBB_FetchAndAddW(P,V) __TBB_machine_fetchadd8(P,V) + #define __TBB_FetchAndStoreW(P,V) __TBB_machine_fetchstore8(P,V) +#else /* __TBB_WORDSIZE != 8 */ + #error Unsupported machine word size. +#endif /* __TBB_WORDSIZE */ + +#ifndef __TBB_Pause + inline void __TBB_Pause(int32_t) { + __TBB_Yield(); + } +#endif + +namespace tbb { + +//! Sequentially consistent full memory fence. +inline void atomic_fence () { __TBB_full_memory_fence(); } + +namespace internal { //< @cond INTERNAL + +//! Class that implements exponential backoff. +/** See implementation of spin_wait_while_eq for an example. */ +class atomic_backoff : no_copy { + //! Time delay, in units of "pause" instructions. + /** Should be equal to approximately the number of "pause" instructions + that take the same time as an context switch. Must be a power of two.*/ + static const int32_t LOOPS_BEFORE_YIELD = 16; + int32_t count; +public: + // In many cases, an object of this type is initialized eagerly on hot path, + // as in for(atomic_backoff b; ; b.pause()) { /*loop body*/ } + // For this reason, the construction cost must be very small! + atomic_backoff() : count(1) {} + // This constructor pauses immediately; do not use on hot paths! + atomic_backoff( bool ) : count(1) { pause(); } + + //! Pause for a while. + void pause() { + if( count<=LOOPS_BEFORE_YIELD ) { + __TBB_Pause(count); + // Pause twice as long the next time. + count*=2; + } else { + // Pause is so long that we might as well yield CPU to scheduler. + __TBB_Yield(); + } + } + + //! Pause for a few times and return false if saturated. + bool bounded_pause() { + __TBB_Pause(count); + if( count +void spin_wait_while_eq( const volatile T& location, U value ) { + atomic_backoff backoff; + while( location==value ) backoff.pause(); +} + +//! Spin UNTIL the value of the variable is equal to a given value +/** T and U should be comparable types. */ +template +void spin_wait_until_eq( const volatile T& location, const U value ) { + atomic_backoff backoff; + while( location!=value ) backoff.pause(); +} + +template +void spin_wait_while(predicate_type condition){ + atomic_backoff backoff; + while( condition() ) backoff.pause(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Generic compare-and-swap applied to only a part of a machine word. +// +#ifndef __TBB_ENDIANNESS +#define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT +#endif + +#if __TBB_USE_GENERIC_PART_WORD_CAS && __TBB_ENDIANNESS==__TBB_ENDIAN_UNSUPPORTED +#error Generic implementation of part-word CAS may not be used with __TBB_ENDIAN_UNSUPPORTED +#endif + +#if __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED +// +// This function is the only use of __TBB_ENDIANNESS. +// The following restrictions/limitations apply for this operation: +// - T must be an integer type of at most 4 bytes for the casts and calculations to work +// - T must also be less than 4 bytes to avoid compiler warnings when computing mask +// (and for the operation to be useful at all, so no workaround is applied) +// - the architecture must consistently use either little-endian or big-endian (same for all locations) +// +// TODO: static_assert for the type requirements stated above +template +inline T __TBB_MaskedCompareAndSwap (volatile T * const ptr, const T value, const T comparand ) { + struct endianness{ static bool is_big_endian(){ + #if __TBB_ENDIANNESS==__TBB_ENDIAN_DETECT + const uint32_t probe = 0x03020100; + return (((const char*)(&probe))[0]==0x03); + #elif __TBB_ENDIANNESS==__TBB_ENDIAN_BIG || __TBB_ENDIANNESS==__TBB_ENDIAN_LITTLE + return __TBB_ENDIANNESS==__TBB_ENDIAN_BIG; + #else + #error Unexpected value of __TBB_ENDIANNESS + #endif + }}; + + const uint32_t byte_offset = (uint32_t) ((uintptr_t)ptr & 0x3); + volatile uint32_t * const aligned_ptr = (uint32_t*)((uintptr_t)ptr - byte_offset ); + + // location of T within uint32_t for a C++ shift operation + const uint32_t bits_to_shift = 8*(endianness::is_big_endian() ? (4 - sizeof(T) - (byte_offset)) : byte_offset); + const uint32_t mask = (((uint32_t)1<<(sizeof(T)*8)) - 1 )<> bits_to_shift); + } + else continue; // CAS failed but the bits of interest were not changed + } +} +#endif // __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED +//////////////////////////////////////////////////////////////////////////////// + +template +inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T comparand ); + +template<> +inline int8_t __TBB_CompareAndSwapGeneric <1,int8_t> (volatile void *ptr, int8_t value, int8_t comparand ) { +#if __TBB_USE_GENERIC_PART_WORD_CAS + return __TBB_MaskedCompareAndSwap((volatile int8_t *)ptr,value,comparand); +#else + return __TBB_machine_cmpswp1(ptr,value,comparand); +#endif +} + +template<> +inline int16_t __TBB_CompareAndSwapGeneric <2,int16_t> (volatile void *ptr, int16_t value, int16_t comparand ) { +#if __TBB_USE_GENERIC_PART_WORD_CAS + return __TBB_MaskedCompareAndSwap((volatile int16_t *)ptr,value,comparand); +#else + return __TBB_machine_cmpswp2(ptr,value,comparand); +#endif +} + +template<> +inline int32_t __TBB_CompareAndSwapGeneric <4,int32_t> (volatile void *ptr, int32_t value, int32_t comparand ) { + // Cast shuts up /Wp64 warning + return (int32_t)__TBB_machine_cmpswp4(ptr,value,comparand); +} + +#if __TBB_64BIT_ATOMICS +template<> +inline int64_t __TBB_CompareAndSwapGeneric <8,int64_t> (volatile void *ptr, int64_t value, int64_t comparand ) { + return __TBB_machine_cmpswp8(ptr,value,comparand); +} +#endif + +template +inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) { + T result; + for( atomic_backoff b;;b.pause() ) { + result = *reinterpret_cast(ptr); + // __TBB_CompareAndSwapGeneric presumed to have full fence. + if( __TBB_CompareAndSwapGeneric ( ptr, result+addend, result )==result ) + break; + } + return result; +} + +template +inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) { + T result; + for( atomic_backoff b;;b.pause() ) { + result = *reinterpret_cast(ptr); + // __TBB_CompareAndSwapGeneric presumed to have full fence. + if( __TBB_CompareAndSwapGeneric ( ptr, value, result )==result ) + break; + } + return result; +} + +#if __TBB_USE_GENERIC_PART_WORD_CAS +#define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1,int8_t> +#define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2,int16_t> +#endif + +#if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_PART_WORD_FETCH_ADD +#define __TBB_machine_fetchadd1 tbb::internal::__TBB_FetchAndAddGeneric<1,int8_t> +#define __TBB_machine_fetchadd2 tbb::internal::__TBB_FetchAndAddGeneric<2,int16_t> +#endif + +#if __TBB_USE_GENERIC_FETCH_ADD +#define __TBB_machine_fetchadd4 tbb::internal::__TBB_FetchAndAddGeneric<4,int32_t> +#endif + +#if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_ADD +#define __TBB_machine_fetchadd8 tbb::internal::__TBB_FetchAndAddGeneric<8,int64_t> +#endif + +#if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_PART_WORD_FETCH_STORE +#define __TBB_machine_fetchstore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,int8_t> +#define __TBB_machine_fetchstore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,int16_t> +#endif + +#if __TBB_USE_GENERIC_FETCH_STORE +#define __TBB_machine_fetchstore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,int32_t> +#endif + +#if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_DWORD_FETCH_STORE +#define __TBB_machine_fetchstore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,int64_t> +#endif + +#if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE +#define __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(S) \ + atomic_selector::word atomic_selector::fetch_store ( volatile void* location, word value ) { \ + return __TBB_machine_fetchstore##S( location, value ); \ + } + +__TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(1) +__TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(2) +__TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(4) +__TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(8) + +#undef __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE +#endif /* __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ + +#if __TBB_USE_GENERIC_DWORD_LOAD_STORE +/*TODO: find a more elegant way to handle function names difference*/ +#if ! __TBB_USE_FENCED_ATOMICS + /* This name forwarding is needed for generic implementation of + * load8/store8 defined below (via macro) to pick the right CAS function*/ + #define __TBB_machine_cmpswp8full_fence __TBB_machine_cmpswp8 +#endif +__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(full_fence) +__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(full_fence) + +#if ! __TBB_USE_FENCED_ATOMICS + #undef __TBB_machine_cmpswp8full_fence +#endif + +#define __TBB_machine_store8 tbb::internal::__TBB_machine_generic_store8full_fence +#define __TBB_machine_load8 tbb::internal::__TBB_machine_generic_load8full_fence +#endif /* __TBB_USE_GENERIC_DWORD_LOAD_STORE */ + +#if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE +/** Fenced operations use volatile qualifier to prevent compiler from optimizing + them out, and on architectures with weak memory ordering to induce compiler + to generate code with appropriate acquire/release semantics. + On architectures like IA32, Intel64 (and likely Sparc TSO) volatile has + no effect on code gen, and consistency helpers serve as a compiler fence (the + latter being true for IA64/gcc as well to fix a bug in some gcc versions). + This code assumes that the generated instructions will operate atomically, + which typically requires a type that can be moved in a single instruction, + cooperation from the compiler for effective use of such an instruction, + and appropriate alignment of the data. **/ +template +struct machine_load_store { + static T load_with_acquire ( const volatile T& location ) { + T to_return = location; + __TBB_acquire_consistency_helper(); + return to_return; + } + static void store_with_release ( volatile T &location, T value ) { + __TBB_release_consistency_helper(); + location = value; + } +}; + +//in general, plain load and store of 32bit compiler is not atomic for 64bit types +#if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS +template +struct machine_load_store { + static T load_with_acquire ( const volatile T& location ) { + return (T)__TBB_machine_load8( (const volatile void*)&location ); + } + static void store_with_release ( volatile T& location, T value ) { + __TBB_machine_store8( (volatile void*)&location, (int64_t)value ); + } +}; +#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ +#endif /* __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE */ + +#if __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE +template +struct machine_load_store_seq_cst { + static T load ( const volatile T& location ) { + __TBB_full_memory_fence(); + return machine_load_store::load_with_acquire( location ); + } +#if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE + static void store ( volatile T &location, T value ) { + atomic_selector::fetch_store( (volatile void*)&location, (typename atomic_selector::word)value ); + } +#else /* !__TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ + static void store ( volatile T &location, T value ) { + machine_load_store::store_with_release( location, value ); + __TBB_full_memory_fence(); + } +#endif /* !__TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */ +}; + +#if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS +/** The implementation does not use functions __TBB_machine_load8/store8 as they + are not required to be sequentially consistent. **/ +template +struct machine_load_store_seq_cst { + static T load ( const volatile T& location ) { + // Comparand and new value may be anything, they only must be equal, and + // the value should have a low probability to be actually found in 'location'. + const int64_t anyvalue = 2305843009213693951LL; + return __TBB_machine_cmpswp8( (volatile void*)const_cast(&location), anyvalue, anyvalue ); + } + static void store ( volatile T &location, T value ) { +#if __TBB_GCC_VERSION >= 40702 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + // An atomic initialization leads to reading of uninitialized memory + int64_t result = (volatile int64_t&)location; +#if __TBB_GCC_VERSION >= 40702 +#pragma GCC diagnostic pop +#endif + while ( __TBB_machine_cmpswp8((volatile void*)&location, (int64_t)value, result) != result ) + result = (volatile int64_t&)location; + } +}; +#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ +#endif /*__TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE */ + +#if __TBB_USE_GENERIC_RELAXED_LOAD_STORE +// Relaxed operations add volatile qualifier to prevent compiler from optimizing them out. +/** Volatile should not incur any additional cost on IA32, Intel64, and Sparc TSO + architectures. However on architectures with weak memory ordering compiler may + generate code with acquire/release semantics for operations on volatile data. **/ +template +struct machine_load_store_relaxed { + static inline T load ( const volatile T& location ) { + return location; + } + static inline void store ( volatile T& location, T value ) { + location = value; + } +}; + +#if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS +template +struct machine_load_store_relaxed { + static inline T load ( const volatile T& location ) { + return (T)__TBB_machine_load8( (const volatile void*)&location ); + } + static inline void store ( volatile T& location, T value ) { + __TBB_machine_store8( (volatile void*)&location, (int64_t)value ); + } +}; +#endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */ +#endif /* __TBB_USE_GENERIC_RELAXED_LOAD_STORE */ + +#undef __TBB_WORDSIZE //this macro is forbidden to use outside of atomic machinery + +template +inline T __TBB_load_with_acquire(const volatile T &location) { + return machine_load_store::load_with_acquire( location ); +} +template +inline void __TBB_store_with_release(volatile T& location, V value) { + machine_load_store::store_with_release( location, T(value) ); +} +//! Overload that exists solely to avoid /Wp64 warnings. +inline void __TBB_store_with_release(volatile size_t& location, size_t value) { + machine_load_store::store_with_release( location, value ); +} + +template +inline T __TBB_load_full_fence(const volatile T &location) { + return machine_load_store_seq_cst::load( location ); +} +template +inline void __TBB_store_full_fence(volatile T& location, V value) { + machine_load_store_seq_cst::store( location, T(value) ); +} +//! Overload that exists solely to avoid /Wp64 warnings. +inline void __TBB_store_full_fence(volatile size_t& location, size_t value) { + machine_load_store_seq_cst::store( location, value ); +} + +template +inline T __TBB_load_relaxed (const volatile T& location) { + return machine_load_store_relaxed::load( const_cast(location) ); +} +template +inline void __TBB_store_relaxed ( volatile T& location, V value ) { + machine_load_store_relaxed::store( const_cast(location), T(value) ); +} +//! Overload that exists solely to avoid /Wp64 warnings. +inline void __TBB_store_relaxed ( volatile size_t& location, size_t value ) { + machine_load_store_relaxed::store( const_cast(location), value ); +} + +// Macro __TBB_TypeWithAlignmentAtLeastAsStrict(T) should be a type with alignment at least as +// strict as type T. The type should have a trivial default constructor and destructor, so that +// arrays of that type can be declared without initializers. +// It is correct (but perhaps a waste of space) if __TBB_TypeWithAlignmentAtLeastAsStrict(T) expands +// to a type bigger than T. +// The default definition here works on machines where integers are naturally aligned and the +// strictest alignment is 64. +#ifndef __TBB_TypeWithAlignmentAtLeastAsStrict + +#if __TBB_ALIGNAS_PRESENT + +// Use C++11 keywords alignas and alignof +#define __TBB_DefineTypeWithAlignment(PowerOf2) \ +struct alignas(PowerOf2) __TBB_machine_type_with_alignment_##PowerOf2 { \ + uint32_t member[PowerOf2/sizeof(uint32_t)]; \ +}; +#define __TBB_alignof(T) alignof(T) + +#elif __TBB_ATTRIBUTE_ALIGNED_PRESENT + +#define __TBB_DefineTypeWithAlignment(PowerOf2) \ +struct __TBB_machine_type_with_alignment_##PowerOf2 { \ + uint32_t member[PowerOf2/sizeof(uint32_t)]; \ +} __attribute__((aligned(PowerOf2))); +#define __TBB_alignof(T) __alignof__(T) + +#elif __TBB_DECLSPEC_ALIGN_PRESENT + +#define __TBB_DefineTypeWithAlignment(PowerOf2) \ +__declspec(align(PowerOf2)) \ +struct __TBB_machine_type_with_alignment_##PowerOf2 { \ + uint32_t member[PowerOf2/sizeof(uint32_t)]; \ +}; +#define __TBB_alignof(T) __alignof(T) + +#else /* A compiler with unknown syntax for data alignment */ +#error Must define __TBB_TypeWithAlignmentAtLeastAsStrict(T) +#endif + +/* Now declare types aligned to useful powers of two */ +__TBB_DefineTypeWithAlignment(8) // i386 ABI says that uint64_t is aligned on 4 bytes +__TBB_DefineTypeWithAlignment(16) +__TBB_DefineTypeWithAlignment(32) +__TBB_DefineTypeWithAlignment(64) + +typedef __TBB_machine_type_with_alignment_64 __TBB_machine_type_with_strictest_alignment; + +// Primary template is a declaration of incomplete type so that it fails with unknown alignments +template struct type_with_alignment; + +// Specializations for allowed alignments +template<> struct type_with_alignment<1> { char member; }; +template<> struct type_with_alignment<2> { uint16_t member; }; +template<> struct type_with_alignment<4> { uint32_t member; }; +template<> struct type_with_alignment<8> { __TBB_machine_type_with_alignment_8 member; }; +template<> struct type_with_alignment<16> {__TBB_machine_type_with_alignment_16 member; }; +template<> struct type_with_alignment<32> {__TBB_machine_type_with_alignment_32 member; }; +template<> struct type_with_alignment<64> {__TBB_machine_type_with_alignment_64 member; }; + +#if __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN +//! Work around for bug in GNU 3.2 and MSVC compilers. +/** Bug is that compiler sometimes returns 0 for __alignof(T) when T has not yet been instantiated. + The work-around forces instantiation by forcing computation of sizeof(T) before __alignof(T). */ +template +struct work_around_alignment_bug { + static const size_t alignment = __TBB_alignof(T); +}; +#define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment::alignment> +#else +#define __TBB_TypeWithAlignmentAtLeastAsStrict(T) tbb::internal::type_with_alignment<__TBB_alignof(T)> +#endif /* __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN */ + +#endif /* __TBB_TypeWithAlignmentAtLeastAsStrict */ + +// Template class here is to avoid instantiation of the static data for modules that don't use it +template +struct reverse { + static const T byte_table[256]; +}; +// An efficient implementation of the reverse function utilizes a 2^8 lookup table holding the bit-reversed +// values of [0..2^8 - 1]. Those values can also be computed on the fly at a slightly higher cost. +template +const T reverse::byte_table[256] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; + +} // namespace internal @endcond +} // namespace tbb + +// Preserving access to legacy APIs +using tbb::internal::__TBB_load_with_acquire; +using tbb::internal::__TBB_store_with_release; + +// Mapping historically used names to the ones expected by atomic_load_store_traits +#define __TBB_load_acquire __TBB_load_with_acquire +#define __TBB_store_release __TBB_store_with_release + +#ifndef __TBB_Log2 +inline intptr_t __TBB_Log2( uintptr_t x ) { + if( x==0 ) return -1; + intptr_t result = 0; + +#if !defined(_M_ARM) + uintptr_t tmp_; + if( sizeof(x)>4 && (tmp_ = ((uint64_t)x)>>32) ) { x=tmp_; result += 32; } +#endif + if( uintptr_t tmp = x>>16 ) { x=tmp; result += 16; } + if( uintptr_t tmp = x>>8 ) { x=tmp; result += 8; } + if( uintptr_t tmp = x>>4 ) { x=tmp; result += 4; } + if( uintptr_t tmp = x>>2 ) { x=tmp; result += 2; } + + return (x&2)? result+1: result; +} +#endif + +#ifndef __TBB_AtomicOR +inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) { + for( tbb::internal::atomic_backoff b;;b.pause() ) { + uintptr_t tmp = *(volatile uintptr_t *)operand; + uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp); + if( result==tmp ) break; + } +} +#endif + +#ifndef __TBB_AtomicAND +inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) { + for( tbb::internal::atomic_backoff b;;b.pause() ) { + uintptr_t tmp = *(volatile uintptr_t *)operand; + uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp); + if( result==tmp ) break; + } +} +#endif + +#if __TBB_PREFETCHING +#ifndef __TBB_cl_prefetch +#error This platform does not define cache management primitives required for __TBB_PREFETCHING +#endif + +#ifndef __TBB_cl_evict +#define __TBB_cl_evict(p) +#endif +#endif + +#ifndef __TBB_Flag +typedef unsigned char __TBB_Flag; +#endif +typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag; + +#ifndef __TBB_TryLockByte +inline bool __TBB_TryLockByte( __TBB_atomic_flag &flag ) { + return __TBB_machine_cmpswp1(&flag,1,0)==0; +} +#endif + +#ifndef __TBB_LockByte +inline __TBB_Flag __TBB_LockByte( __TBB_atomic_flag& flag ) { + tbb::internal::atomic_backoff backoff; + while( !__TBB_TryLockByte(flag) ) backoff.pause(); + return 0; +} +#endif + +#ifndef __TBB_UnlockByte +#define __TBB_UnlockByte(addr) __TBB_store_with_release((addr),0) +#endif + +// lock primitives with Intel(R) Transactional Synchronization Extensions (Intel(R) TSX) +#if ( __TBB_x86_32 || __TBB_x86_64 ) /* only on ia32/intel64 */ +inline void __TBB_TryLockByteElidedCancel() { __TBB_machine_try_lock_elided_cancel(); } + +inline bool __TBB_TryLockByteElided( __TBB_atomic_flag& flag ) { + bool res = __TBB_machine_try_lock_elided( &flag )!=0; + // to avoid the "lemming" effect, we need to abort the transaction + // if __TBB_machine_try_lock_elided returns false (i.e., someone else + // has acquired the mutex non-speculatively). + if( !res ) __TBB_TryLockByteElidedCancel(); + return res; +} + +inline void __TBB_LockByteElided( __TBB_atomic_flag& flag ) +{ + for(;;) { + tbb::internal::spin_wait_while_eq( flag, 1 ); + if( __TBB_machine_try_lock_elided( &flag ) ) + return; + // Another thread acquired the lock "for real". + // To avoid the "lemming" effect, we abort the transaction. + __TBB_TryLockByteElidedCancel(); + } +} + +inline void __TBB_UnlockByteElided( __TBB_atomic_flag& flag ) { + __TBB_machine_unlock_elided( &flag ); +} +#endif + +#ifndef __TBB_ReverseByte +inline unsigned char __TBB_ReverseByte(unsigned char src) { + return tbb::internal::reverse::byte_table[src]; +} +#endif + +template +T __TBB_ReverseBits(T src) { + T dst; + unsigned char *original = (unsigned char *) &src; + unsigned char *reversed = (unsigned char *) &dst; + + for( int i = sizeof(T)-1; i >= 0; i-- ) + reversed[i] = __TBB_ReverseByte( original[sizeof(T)-i-1] ); + + return dst; +} + +#endif /* __TBB_machine_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_profiling.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_profiling.h new file mode 100644 index 00000000..20f8f512 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_profiling.h @@ -0,0 +1,355 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_profiling_H +#define __TBB_profiling_H + +#define __TBB_tbb_profiling_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +namespace tbb { + namespace internal { + + // include list of index names + #define TBB_STRING_RESOURCE(index_name,str) index_name, + enum string_index { + #include "internal/_tbb_strings.h" + NUM_STRINGS + }; + #undef TBB_STRING_RESOURCE + + enum itt_relation + { + __itt_relation_is_unknown = 0, + __itt_relation_is_dependent_on, /**< "A is dependent on B" means that A cannot start until B completes */ + __itt_relation_is_sibling_of, /**< "A is sibling of B" means that A and B were created as a group */ + __itt_relation_is_parent_of, /**< "A is parent of B" means that A created B */ + __itt_relation_is_continuation_of, /**< "A is continuation of B" means that A assumes the dependencies of B */ + __itt_relation_is_child_of, /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */ + __itt_relation_is_continued_by, /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */ + __itt_relation_is_predecessor_to /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */ + }; + + } +} + +// Check if the tools support is enabled +#if (_WIN32||_WIN64||__linux__) && !__MINGW32__ && TBB_USE_THREADING_TOOLS + +#if _WIN32||_WIN64 +#include /* mbstowcs_s */ +#endif +#include "tbb_stddef.h" + +namespace tbb { + namespace internal { + +#if _WIN32||_WIN64 + void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const wchar_t* name ); + inline size_t multibyte_to_widechar( wchar_t* wcs, const char* mbs, size_t bufsize) { +#if _MSC_VER>=1400 + size_t len; + mbstowcs_s( &len, wcs, bufsize, mbs, _TRUNCATE ); + return len; // mbstowcs_s counts null terminator +#else + size_t len = mbstowcs( wcs, mbs, bufsize ); + if(wcs && len!=size_t(-1) ) + wcs[len + inline void itt_store_word_with_release(tbb::atomic& dst, U src) { +#if TBB_USE_THREADING_TOOLS + // This assertion should be replaced with static_assert + __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); + itt_store_pointer_with_release_v3(&dst, (void *)uintptr_t(src)); +#else + dst = src; +#endif // TBB_USE_THREADING_TOOLS + } + + template + inline T itt_load_word_with_acquire(const tbb::atomic& src) { +#if TBB_USE_THREADING_TOOLS + // This assertion should be replaced with static_assert + __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + #pragma warning (push) + #pragma warning (disable: 4311) +#endif + T result = (T)itt_load_pointer_with_acquire_v3(&src); +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif + return result; +#else + return src; +#endif // TBB_USE_THREADING_TOOLS + } + + template + inline void itt_store_word_with_release(T& dst, T src) { +#if TBB_USE_THREADING_TOOLS + // This assertion should be replaced with static_assert + __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); + itt_store_pointer_with_release_v3(&dst, (void *)src); +#else + __TBB_store_with_release(dst, src); +#endif // TBB_USE_THREADING_TOOLS + } + + template + inline T itt_load_word_with_acquire(const T& src) { +#if TBB_USE_THREADING_TOOLS + // This assertion should be replaced with static_assert + __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized"); + return (T)itt_load_pointer_with_acquire_v3(&src); +#else + return __TBB_load_with_acquire(src); +#endif // TBB_USE_THREADING_TOOLS + } + + template + inline void itt_hide_store_word(T& dst, T src) { +#if TBB_USE_THREADING_TOOLS + //TODO: This assertion should be replaced with static_assert + __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized"); + itt_store_pointer_with_release_v3(&dst, (void *)src); +#else + dst = src; +#endif + } + + //TODO: rename to itt_hide_load_word_relaxed + template + inline T itt_hide_load_word(const T& src) { +#if TBB_USE_THREADING_TOOLS + //TODO: This assertion should be replaced with static_assert + __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized."); + return (T)itt_load_pointer_v3(&src); +#else + return src; +#endif + } + +#if TBB_USE_THREADING_TOOLS + inline void call_itt_notify(notify_type t, void *ptr) { + call_itt_notify_v5((int)t, ptr); + } + + inline void itt_make_task_group( itt_domain_enum domain, void *group, unsigned long long group_extra, + void *parent, unsigned long long parent_extra, string_index name_index ) { + itt_make_task_group_v7( domain, group, group_extra, parent, parent_extra, name_index ); + } + + inline void itt_metadata_str_add( itt_domain_enum domain, void *addr, unsigned long long addr_extra, + string_index key, const char *value ) { + itt_metadata_str_add_v7( domain, addr, addr_extra, key, value ); + } + + inline void register_node_addr(itt_domain_enum domain, void *addr, unsigned long long addr_extra, + string_index key, void *value) { + itt_metadata_ptr_add_v11(domain, addr, addr_extra, key, value); + } + + inline void itt_relation_add( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, + itt_relation relation, void *addr1, unsigned long long addr1_extra ) { + itt_relation_add_v7( domain, addr0, addr0_extra, relation, addr1, addr1_extra ); + } + + inline void itt_task_begin( itt_domain_enum domain, void *task, unsigned long long task_extra, + void *parent, unsigned long long parent_extra, string_index name_index ) { + itt_task_begin_v7( domain, task, task_extra, parent, parent_extra, name_index ); + } + + inline void itt_task_end( itt_domain_enum domain ) { + itt_task_end_v7( domain ); + } + + inline void itt_region_begin( itt_domain_enum domain, void *region, unsigned long long region_extra, + void *parent, unsigned long long parent_extra, string_index name_index ) { + itt_region_begin_v9( domain, region, region_extra, parent, parent_extra, name_index ); + } + + inline void itt_region_end( itt_domain_enum domain, void *region, unsigned long long region_extra ) { + itt_region_end_v9( domain, region, region_extra ); + } +#else + inline void register_node_addr( itt_domain_enum /*domain*/, void* /*addr*/, unsigned long long /*addr_extra*/, string_index /*key*/, void* /*value*/ ) {} + inline void call_itt_notify(notify_type /*t*/, void* /*ptr*/) {} + + inline void itt_make_task_group( itt_domain_enum /*domain*/, void* /*group*/, unsigned long long /*group_extra*/, + void* /*parent*/, unsigned long long /*parent_extra*/, string_index /*name_index*/ ) {} + + inline void itt_metadata_str_add( itt_domain_enum /*domain*/, void* /*addr*/, unsigned long long /*addr_extra*/, + string_index /*key*/, const char* /*value*/ ) {} + + inline void itt_relation_add( itt_domain_enum /*domain*/, void* /*addr0*/, unsigned long long /*addr0_extra*/, + itt_relation /*relation*/, void* /*addr1*/, unsigned long long /*addr1_extra*/ ) {} + + inline void itt_task_begin( itt_domain_enum /*domain*/, void* /*task*/, unsigned long long /*task_extra*/, + void* /*parent*/, unsigned long long /*parent_extra*/, string_index /*name_index*/ ) {} + + inline void itt_task_end( itt_domain_enum /*domain*/ ) {} + + inline void itt_region_begin( itt_domain_enum /*domain*/, void* /*region*/, unsigned long long /*region_extra*/, + void* /*parent*/, unsigned long long /*parent_extra*/, string_index /*name_index*/ ) {} + + inline void itt_region_end( itt_domain_enum /*domain*/, void* /*region*/, unsigned long long /*region_extra*/ ) {} +#endif // TBB_USE_THREADING_TOOLS + + } // namespace internal +} // namespace tbb + +#if TBB_PREVIEW_FLOW_GRAPH_TRACE +#include + +namespace tbb { +namespace profiling { +namespace interface10 { + +#if TBB_USE_THREADING_TOOLS && !(TBB_USE_THREADING_TOOLS == 2) +class event { +/** This class supports user event traces through itt. + Common use-case is tagging data flow graph tasks (data-id) + and visualization by Intel Advisor Flow Graph Analyzer (FGA) **/ +// TODO: Replace implementation by itt user event api. + + const std::string my_name; + + static void emit_trace(const std::string &input) { + itt_metadata_str_add( tbb::internal::ITT_DOMAIN_FLOW, NULL, tbb::internal::FLOW_NULL, tbb::internal::USER_EVENT, ( "FGA::DATAID::" + input ).c_str() ); + } + +public: + event(const std::string &input) + : my_name( input ) + { } + + void emit() { + emit_trace(my_name); + } + + static void emit(const std::string &description) { + emit_trace(description); + } + +}; +#else // TBB_USE_THREADING_TOOLS && !(TBB_USE_THREADING_TOOLS == 2) +// Using empty struct if user event tracing is disabled: +struct event { + event(const std::string &) { } + + void emit() { } + + static void emit(const std::string &) { } +}; +#endif // TBB_USE_THREADING_TOOLS && !(TBB_USE_THREADING_TOOLS == 2) + +} // interfaceX +using interface10::event; +} // namespace profiling +} // namespace tbb +#endif // TBB_PREVIEW_FLOW_GRAPH_TRACE + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_tbb_profiling_H_include_area + +#endif /* __TBB_profiling_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_stddef.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_stddef.h new file mode 100644 index 00000000..96743024 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_stddef.h @@ -0,0 +1,565 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbb_stddef_H +#define __TBB_tbb_stddef_H + +// Marketing-driven product version +#define TBB_VERSION_MAJOR 2020 +#define TBB_VERSION_MINOR 3 + +// Engineering-focused interface version +#define TBB_INTERFACE_VERSION 11103 +#define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 + +// The oldest major interface version still supported +// To be used in SONAME, manifests, etc. +#define TBB_COMPATIBLE_INTERFACE_VERSION 2 + +#define __TBB_STRING_AUX(x) #x +#define __TBB_STRING(x) __TBB_STRING_AUX(x) + +// We do not need defines below for resource processing on windows +#if !defined RC_INVOKED + +// Define groups for Doxygen documentation +/** + * @defgroup algorithms Algorithms + * @defgroup containers Containers + * @defgroup memory_allocation Memory Allocation + * @defgroup synchronization Synchronization + * @defgroup timing Timing + * @defgroup task_scheduling Task Scheduling + */ + +// Simple text that is displayed on the main page of Doxygen documentation. +/** + * \mainpage Main Page + * + * Click the tabs above for information about the + * - Modules (groups of functionality) implemented by the library + * - Classes provided by the library + * - Files constituting the library. + * . + * Please note that significant part of TBB functionality is implemented in the form of + * template functions, descriptions of which are not accessible on the Classes + * tab. Use Modules or Namespace/Namespace Members + * tabs to find them. + * + * Additional pieces of information can be found here + * - \subpage concepts + * . + */ + +/** \page concepts TBB concepts + + A concept is a set of requirements to a type, which are necessary and sufficient + for the type to model a particular behavior or a set of behaviors. Some concepts + are specific to a particular algorithm (e.g. algorithm body), while other ones + are common to several algorithms (e.g. range concept). + + All TBB algorithms make use of different classes implementing various concepts. + Implementation classes are supplied by the user as type arguments of template + parameters and/or as objects passed as function call arguments. The library + provides predefined implementations of some concepts (e.g. several kinds of + \ref range_req "ranges"), while other ones must always be implemented by the user. + + TBB defines a set of minimal requirements each concept must conform to. Here is + the list of different concepts hyperlinked to the corresponding requirements specifications: + - \subpage range_req + - \subpage parallel_do_body_req + - \subpage parallel_for_body_req + - \subpage parallel_reduce_body_req + - \subpage parallel_scan_body_req + - \subpage parallel_sort_iter_req +**/ + +// tbb_config.h should be included the first since it contains macro definitions used in other headers +#include "tbb_config.h" + +#if _MSC_VER >=1400 + #define __TBB_EXPORTED_FUNC __cdecl + #define __TBB_EXPORTED_METHOD __thiscall +#else + #define __TBB_EXPORTED_FUNC + #define __TBB_EXPORTED_METHOD +#endif + +#if __INTEL_COMPILER || _MSC_VER +#define __TBB_NOINLINE(decl) __declspec(noinline) decl +#elif __GNUC__ +#define __TBB_NOINLINE(decl) decl __attribute__ ((noinline)) +#else +#define __TBB_NOINLINE(decl) decl +#endif + +#if __TBB_NOEXCEPT_PRESENT +#define __TBB_NOEXCEPT(expression) noexcept(expression) +#else +#define __TBB_NOEXCEPT(expression) +#endif + +#include /* Need size_t and ptrdiff_t */ + +#if _MSC_VER + #define __TBB_tbb_windef_H + #include "internal/_tbb_windef.h" + #undef __TBB_tbb_windef_H +#endif +#if !defined(_MSC_VER) || _MSC_VER>=1600 + #include +#endif + +//! Type for an assertion handler +typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment ); + +#if __TBBMALLOC_BUILD +namespace rml { namespace internal { + #define __TBB_ASSERT_RELEASE(predicate,message) ((predicate)?((void)0) : rml::internal::assertion_failure(__FILE__,__LINE__,#predicate,message)) +#else +namespace tbb { + #define __TBB_ASSERT_RELEASE(predicate,message) ((predicate)?((void)0) : tbb::assertion_failure(__FILE__,__LINE__,#predicate,message)) +#endif + + //! Set assertion handler and return previous value of it. + assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler ); + + //! Process an assertion failure. + /** Normally called from __TBB_ASSERT macro. + If assertion handler is null, print message for assertion failure and abort. + Otherwise call the assertion handler. */ + void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment ); + +#if __TBBMALLOC_BUILD +}} // namespace rml::internal +#else +} // namespace tbb +#endif + +#if TBB_USE_ASSERT + + //! Assert that predicate is true. + /** If predicate is false, print assertion failure message. + If the comment argument is not NULL, it is printed as part of the failure message. + The comment argument has no other effect. */ + #define __TBB_ASSERT(predicate,message) __TBB_ASSERT_RELEASE(predicate,message) + + #define __TBB_ASSERT_EX __TBB_ASSERT + +#else /* !TBB_USE_ASSERT */ + + //! No-op version of __TBB_ASSERT. + #define __TBB_ASSERT(predicate,comment) ((void)0) + //! "Extended" version is useful to suppress warnings if a variable is only used with an assert + #define __TBB_ASSERT_EX(predicate,comment) ((void)(1 && (predicate))) + +#endif /* !TBB_USE_ASSERT */ + +//! The namespace tbb contains all components of the library. +namespace tbb { + + namespace internal { +#if _MSC_VER && _MSC_VER<1600 + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; +#else /* Posix */ + using ::int8_t; + using ::int16_t; + using ::int32_t; + using ::int64_t; + using ::uint8_t; + using ::uint16_t; + using ::uint32_t; + using ::uint64_t; +#endif /* Posix */ + } // namespace internal + + using std::size_t; + using std::ptrdiff_t; + +//! The function returns the interface version of the TBB shared library being used. +/** + * The version it returns is determined at runtime, not at compile/link time. + * So it can be different than the value of TBB_INTERFACE_VERSION obtained at compile time. + */ +extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version(); + +/** + * @cond INTERNAL + * @brief Identifiers declared inside namespace internal should never be used directly by client code. + */ +namespace internal { + +//! Compile-time constant that is upper bound on cache line/sector size. +/** It should be used only in situations where having a compile-time upper + bound is more useful than a run-time exact answer. + @ingroup memory_allocation */ +const size_t NFS_MaxLineSize = 128; + +/** Label for data that may be accessed from different threads, and that may eventually become wrapped + in a formal atomic type. + + Note that no problems have yet been observed relating to the definition currently being empty, + even if at least "volatile" would seem to be in order to avoid data sometimes temporarily hiding + in a register (although "volatile" as a "poor man's atomic" lacks several other features of a proper + atomic, some of which are now provided instead through specialized functions). + + Note that usage is intentionally compatible with a definition as qualifier "volatile", + both as a way to have the compiler help enforce use of the label and to quickly rule out + one potential issue. + + Note however that, with some architecture/compiler combinations, e.g. on IA-64 architecture, "volatile" + also has non-portable memory semantics that are needlessly expensive for "relaxed" operations. + + Note that this must only be applied to data that will not change bit patterns when cast to/from + an integral type of the same length; tbb::atomic must be used instead for, e.g., floating-point types. + + TODO: apply wherever relevant **/ +#define __TBB_atomic // intentionally empty, see above + +#if __TBB_OVERRIDE_PRESENT +#define __TBB_override override +#else +#define __TBB_override // formal comment only +#endif + +#if __TBB_CPP17_FALLTHROUGH_PRESENT +#define __TBB_fallthrough [[fallthrough]] +#elif __TBB_FALLTHROUGH_PRESENT +#define __TBB_fallthrough __attribute__ ((fallthrough)) +#else +#define __TBB_fallthrough +#endif + +template +struct padded_base : T { + char pad[S - R]; +}; +template struct padded_base : T {}; + +//! Pads type T to fill out to a multiple of cache line size. +template +struct padded : padded_base {}; + +//! Extended variant of the standard offsetof macro +/** The standard offsetof macro is not sufficient for TBB as it can be used for + POD-types only. The constant 0x1000 (not NULL) is necessary to appease GCC. **/ +#define __TBB_offsetof(class_name, member_name) \ + ((ptrdiff_t)&(reinterpret_cast(0x1000)->member_name) - 0x1000) + +//! Returns address of the object containing a member with the given name and address +#define __TBB_get_object_ref(class_name, member_name, member_addr) \ + (*reinterpret_cast((char*)member_addr - __TBB_offsetof(class_name, member_name))) + +//! Throws std::runtime_error with what() returning error_code description prefixed with aux_info +void __TBB_EXPORTED_FUNC handle_perror( int error_code, const char* aux_info ); + +#if TBB_USE_EXCEPTIONS + #define __TBB_TRY try + #define __TBB_CATCH(e) catch(e) + #define __TBB_THROW(e) throw e + #define __TBB_RETHROW() throw +#else /* !TBB_USE_EXCEPTIONS */ + inline bool __TBB_false() { return false; } + #define __TBB_TRY + #define __TBB_CATCH(e) if ( tbb::internal::__TBB_false() ) + #define __TBB_THROW(e) tbb::internal::suppress_unused_warning(e) + #define __TBB_RETHROW() ((void)0) +#endif /* !TBB_USE_EXCEPTIONS */ + +//! Report a runtime warning. +void __TBB_EXPORTED_FUNC runtime_warning( const char* format, ... ); + +#if TBB_USE_ASSERT +static void* const poisoned_ptr = reinterpret_cast(-1); + +//! Set p to invalid pointer value. +// Also works for regular (non-__TBB_atomic) pointers. +template +inline void poison_pointer( T* __TBB_atomic & p ) { p = reinterpret_cast(poisoned_ptr); } + +/** Expected to be used in assertions only, thus no empty form is defined. **/ +template +inline bool is_poisoned( T* p ) { return p == reinterpret_cast(poisoned_ptr); } +#else +template +inline void poison_pointer( T* __TBB_atomic & ) {/*do nothing*/} +#endif /* !TBB_USE_ASSERT */ + +//! Cast between unrelated pointer types. +/** This method should be used sparingly as a last resort for dealing with + situations that inherently break strict ISO C++ aliasing rules. */ +// T is a pointer type because it will be explicitly provided by the programmer as a template argument; +// U is a referent type to enable the compiler to check that "ptr" is a pointer, deducing U in the process. +template +inline T punned_cast( U* ptr ) { + uintptr_t x = reinterpret_cast(ptr); + return reinterpret_cast(x); +} + +#if __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT + +//! Base class for types that should not be assigned. +class no_assign { +public: + void operator=( const no_assign& ) = delete; + no_assign( const no_assign& ) = default; + no_assign() = default; +}; + +//! Base class for types that should not be copied or assigned. +class no_copy: no_assign { +public: + no_copy( const no_copy& ) = delete; + no_copy() = default; +}; + +#else /*__TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT*/ + +//! Base class for types that should not be assigned. +class no_assign { + // Deny assignment + void operator=( const no_assign& ); +public: +#if __GNUC__ + //! Explicitly define default construction, because otherwise gcc issues gratuitous warning. + no_assign() {} +#endif /* __GNUC__ */ +}; + +//! Base class for types that should not be copied or assigned. +class no_copy: no_assign { + //! Deny copy construction + no_copy( const no_copy& ); +public: + //! Allow default construction + no_copy() {} +}; + +#endif /*__TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT*/ + +#if TBB_DEPRECATED_MUTEX_COPYING +class mutex_copy_deprecated_and_disabled {}; +#else +// By default various implementations of mutexes are not copy constructible +// and not copy assignable. +class mutex_copy_deprecated_and_disabled : no_copy {}; +#endif + +//! A function to check if passed in pointer is aligned on a specific border +template +inline bool is_aligned(T* pointer, uintptr_t alignment) { + return 0==((uintptr_t)pointer & (alignment-1)); +} + +//! A function to check if passed integer is a power of 2 +template +inline bool is_power_of_two(integer_type arg) { + return arg && (0 == (arg & (arg - 1))); +} + +//! A function to compute arg modulo divisor where divisor is a power of 2. +template +inline argument_integer_type modulo_power_of_two(argument_integer_type arg, divisor_integer_type divisor) { + __TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of two" ); + return (arg & (divisor - 1)); +} + + +//! A function to determine if arg is a power of 2 at least as big as another power of 2. +// i.e. for strictly positive i and j, with j being a power of 2, +// determines whether i==j< +inline bool is_power_of_two_at_least(argument_integer_type arg, power2_integer_type power2) { + __TBB_ASSERT( is_power_of_two(power2), "Divisor should be a power of two" ); + return 0 == (arg & (arg - power2)); +} + +//! Utility template function to prevent "unused" warnings by various compilers. +template void suppress_unused_warning( const T1& ) {} +template void suppress_unused_warning( const T1&, const T2& ) {} +template void suppress_unused_warning( const T1&, const T2&, const T3& ) {} + +// Struct to be used as a version tag for inline functions. +/** Version tag can be necessary to prevent loader on Linux from using the wrong + symbol in debug builds (when inline functions are compiled as out-of-line). **/ +struct version_tag_v3 {}; + +typedef version_tag_v3 version_tag; + +} // internal + +//! Dummy type that distinguishes splitting constructor from copy constructor. +/** + * See description of parallel_for and parallel_reduce for example usages. + * @ingroup algorithms + */ +class split { +}; + +//! Type enables transmission of splitting proportion from partitioners to range objects +/** + * In order to make use of such facility Range objects must implement + * splitting constructor with this type passed and initialize static + * constant boolean field 'is_splittable_in_proportion' with the value + * of 'true' + */ +class proportional_split: internal::no_assign { +public: + proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left), my_right(_right) { } + + size_t left() const { return my_left; } + size_t right() const { return my_right; } + + // used when range does not support proportional split + operator split() const { return split(); } + +#if __TBB_ENABLE_RANGE_FEEDBACK + void set_proportion(size_t _left, size_t _right) { + my_left = _left; + my_right = _right; + } +#endif +private: + size_t my_left, my_right; +}; + +} // tbb + +// Following is a set of classes and functions typically used in compile-time "metaprogramming". +// TODO: move all that to a separate header + +#if __TBB_CPP11_SMART_POINTERS_PRESENT +#include // for unique_ptr +#endif + +#if __TBB_CPP11_RVALUE_REF_PRESENT || __TBB_CPP11_DECLTYPE_PRESENT || _LIBCPP_VERSION +#include // for std::move, std::forward, std::declval +#endif + +namespace tbb { +namespace internal { + +#if __TBB_CPP11_SMART_POINTERS_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + template + std::unique_ptr make_unique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); + } +#endif + +//! Class for determining type of std::allocator::value_type. +template +struct allocator_type { + typedef T value_type; +}; + +#if _MSC_VER +//! Microsoft std::allocator has non-standard extension that strips const from a type. +template +struct allocator_type { + typedef T value_type; +}; +#endif + +// Ad-hoc implementation of true_type & false_type +// Intended strictly for internal use! For public APIs (traits etc), use C++11 analogues. +template +struct bool_constant { + static /*constexpr*/ const bool value = v; +}; +typedef bool_constant true_type; +typedef bool_constant false_type; + +//! A template to select either 32-bit or 64-bit constant as compile time, depending on machine word size. +template +struct select_size_t_constant { + //Explicit cast is needed to avoid compiler warnings about possible truncation. + //The value of the right size, which is selected by ?:, is anyway not truncated or promoted. + static const size_t value = (size_t)((sizeof(size_t)==sizeof(u)) ? u : ull); +}; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +using std::move; +using std::forward; +#elif defined(_LIBCPP_NAMESPACE) +// libc++ defines "pre-C++11 move and forward" similarly to ours; use it to avoid name conflicts in some cases. +using std::_LIBCPP_NAMESPACE::move; +using std::_LIBCPP_NAMESPACE::forward; +#else +// It is assumed that cv qualifiers, if any, are part of the deduced type. +template +T& move( T& x ) { return x; } +template +T& forward( T& x ) { return x; } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +// Helper macros to simplify writing templates working with both C++03 and C++11. +#if __TBB_CPP11_RVALUE_REF_PRESENT +#define __TBB_FORWARDING_REF(A) A&& +#else +// It is assumed that cv qualifiers, if any, are part of a deduced type. +// Thus this macro should not be used in public interfaces. +#define __TBB_FORWARDING_REF(A) A& +#endif +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#define __TBB_PARAMETER_PACK ... +#define __TBB_PACK_EXPANSION(A) A... +#else +#define __TBB_PARAMETER_PACK +#define __TBB_PACK_EXPANSION(A) A +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ + +#if __TBB_CPP11_DECLTYPE_PRESENT +#if __TBB_CPP11_DECLVAL_BROKEN +// Ad-hoc implementation of std::declval +template __TBB_FORWARDING_REF(T) declval() /*noexcept*/; +#else +using std::declval; +#endif +#endif + +template +struct STATIC_ASSERTION_FAILED; + +template <> +struct STATIC_ASSERTION_FAILED { enum {value=1};}; + +template<> +struct STATIC_ASSERTION_FAILED; //intentionally left undefined to cause compile time error + +//! @endcond +}} // namespace tbb::internal + +#if __TBB_STATIC_ASSERT_PRESENT +#define __TBB_STATIC_ASSERT(condition,msg) static_assert(condition,msg) +#else +//please note condition is intentionally inverted to get a bit more understandable error msg +#define __TBB_STATIC_ASSERT_IMPL1(condition,msg,line) \ + enum {static_assert_on_line_##line = tbb::internal::STATIC_ASSERTION_FAILED::value} + +#define __TBB_STATIC_ASSERT_IMPL(condition,msg,line) __TBB_STATIC_ASSERT_IMPL1(condition,msg,line) +//! Verify condition, at compile time +#define __TBB_STATIC_ASSERT(condition,msg) __TBB_STATIC_ASSERT_IMPL(condition,msg,__LINE__) +#endif + +#endif /* RC_INVOKED */ +#endif /* __TBB_tbb_stddef_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_thread.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_thread.h new file mode 100644 index 00000000..48c11711 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbb_thread.h @@ -0,0 +1,345 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "internal/_deprecated_header_message_guard.h" + +#if !defined(__TBB_show_deprecation_message_tbb_thread_H) && defined(__TBB_show_deprecated_header_message) +#define __TBB_show_deprecation_message_tbb_thread_H +#pragma message("TBB Warning: tbb/tbb_thread.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.") +#endif + +#if defined(__TBB_show_deprecated_header_message) +#undef __TBB_show_deprecated_header_message +#endif + +#ifndef __TBB_tbb_thread_H +#define __TBB_tbb_thread_H + +#define __TBB_tbb_thread_H_include_area +#include "internal/_warning_suppress_enable_notice.h" + +#include "tbb_stddef.h" + +#if _WIN32||_WIN64 +#include "machine/windows_api.h" +#define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI +#define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* ) +namespace tbb { namespace internal { +#if __TBB_WIN8UI_SUPPORT + typedef size_t thread_id_type; +#else // __TBB_WIN8UI_SUPPORT + typedef DWORD thread_id_type; +#endif // __TBB_WIN8UI_SUPPORT +}} //namespace tbb::internal +#else +#define __TBB_NATIVE_THREAD_ROUTINE void* +#define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* ) +#include +namespace tbb { namespace internal { + typedef pthread_t thread_id_type; +}} //namespace tbb::internal +#endif // _WIN32||_WIN64 + +#include "atomic.h" +#include "internal/_tbb_hash_compare_impl.h" +#include "tick_count.h" + +#include __TBB_STD_SWAP_HEADER +#include + +namespace tbb { + +namespace internal { + class tbb_thread_v3; +} + +inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true); + +namespace internal { + + //! Allocate a closure + void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size ); + //! Free a closure allocated by allocate_closure_v3 + void __TBB_EXPORTED_FUNC free_closure_v3( void* ); + + struct thread_closure_base { + void* operator new( size_t size ) {return allocate_closure_v3(size);} + void operator delete( void* ptr ) {free_closure_v3(ptr);} + }; + + template struct thread_closure_0: thread_closure_base { + F function; + + static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { + thread_closure_0 *self = static_cast(c); + self->function(); + delete self; + return 0; + } + thread_closure_0( const F& f ) : function(f) {} + }; + //! Structure used to pass user function with 1 argument to thread. + template struct thread_closure_1: thread_closure_base { + F function; + X arg1; + //! Routine passed to Windows's _beginthreadex by thread::internal_start() inside tbb.dll + static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { + thread_closure_1 *self = static_cast(c); + self->function(self->arg1); + delete self; + return 0; + } + thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {} + }; + template struct thread_closure_2: thread_closure_base { + F function; + X arg1; + Y arg2; + //! Routine passed to Windows's _beginthreadex by thread::internal_start() inside tbb.dll + static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { + thread_closure_2 *self = static_cast(c); + self->function(self->arg1, self->arg2); + delete self; + return 0; + } + thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {} + }; + + //! Versioned thread class. + class tbb_thread_v3 { +#if __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN + // Workaround for a compiler bug: declaring the copy constructor as public + // enables use of the moving constructor. + // The definition is not provided in order to prohibit copying. + public: +#endif + tbb_thread_v3(const tbb_thread_v3&); // = delete; // Deny access + public: +#if _WIN32||_WIN64 + typedef HANDLE native_handle_type; +#else + typedef pthread_t native_handle_type; +#endif // _WIN32||_WIN64 + + class id; + //! Constructs a thread object that does not represent a thread of execution. + tbb_thread_v3() __TBB_NOEXCEPT(true) : my_handle(0) +#if _WIN32||_WIN64 + , my_thread_id(0) +#endif // _WIN32||_WIN64 + {} + + //! Constructs an object and executes f() in a new thread + template explicit tbb_thread_v3(F f) { + typedef internal::thread_closure_0 closure_type; + internal_start(closure_type::start_routine, new closure_type(f)); + } + //! Constructs an object and executes f(x) in a new thread + template tbb_thread_v3(F f, X x) { + typedef internal::thread_closure_1 closure_type; + internal_start(closure_type::start_routine, new closure_type(f,x)); + } + //! Constructs an object and executes f(x,y) in a new thread + template tbb_thread_v3(F f, X x, Y y) { + typedef internal::thread_closure_2 closure_type; + internal_start(closure_type::start_routine, new closure_type(f,x,y)); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + tbb_thread_v3(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) + : my_handle(x.my_handle) +#if _WIN32||_WIN64 + , my_thread_id(x.my_thread_id) +#endif + { + x.internal_wipe(); + } + tbb_thread_v3& operator=(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) { + internal_move(x); + return *this; + } + private: + tbb_thread_v3& operator=(const tbb_thread_v3& x); // = delete; + public: +#else // __TBB_CPP11_RVALUE_REF_PRESENT + tbb_thread_v3& operator=(tbb_thread_v3& x) { + internal_move(x); + return *this; + } +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + + void swap( tbb_thread_v3& t ) __TBB_NOEXCEPT(true) {tbb::swap( *this, t );} + bool joinable() const __TBB_NOEXCEPT(true) {return my_handle!=0; } + //! The completion of the thread represented by *this happens before join() returns. + void __TBB_EXPORTED_METHOD join(); + //! When detach() returns, *this no longer represents the possibly continuing thread of execution. + void __TBB_EXPORTED_METHOD detach(); + ~tbb_thread_v3() {if( joinable() ) detach();} + inline id get_id() const __TBB_NOEXCEPT(true); + native_handle_type native_handle() { return my_handle; } + + //! The number of hardware thread contexts. + /** Before TBB 3.0 U4 this methods returned the number of logical CPU in + the system. Currently on Windows, Linux and FreeBSD it returns the + number of logical CPUs available to the current process in accordance + with its affinity mask. + + NOTE: The return value of this method never changes after its first + invocation. This means that changes in the process affinity mask that + took place after this method was first invoked will not affect the + number of worker threads in the TBB worker threads pool. **/ + static unsigned __TBB_EXPORTED_FUNC hardware_concurrency() __TBB_NOEXCEPT(true); + private: + native_handle_type my_handle; +#if _WIN32||_WIN64 + thread_id_type my_thread_id; +#endif // _WIN32||_WIN64 + + void internal_wipe() __TBB_NOEXCEPT(true) { + my_handle = 0; +#if _WIN32||_WIN64 + my_thread_id = 0; +#endif + } + void internal_move(tbb_thread_v3& x) __TBB_NOEXCEPT(true) { + if (joinable()) detach(); + my_handle = x.my_handle; +#if _WIN32||_WIN64 + my_thread_id = x.my_thread_id; +#endif // _WIN32||_WIN64 + x.internal_wipe(); + } + + /** Runs start_routine(closure) on another thread and sets my_handle to the handle of the created thread. */ + void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), + void* closure ); + friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ); + friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true); + }; + + class tbb_thread_v3::id { + thread_id_type my_id; + id( thread_id_type id_ ) : my_id(id_) {} + + friend class tbb_thread_v3; + public: + id() __TBB_NOEXCEPT(true) : my_id(0) {} + + friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); + friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); + friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); + friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); + friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); + friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true); + + template + friend std::basic_ostream& + operator<< (std::basic_ostream &out, + tbb_thread_v3::id id) + { + out << id.my_id; + return out; + } + friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3(); + + friend inline size_t tbb_hasher( const tbb_thread_v3::id& id ) { + __TBB_STATIC_ASSERT(sizeof(id.my_id) <= sizeof(size_t), "Implementation assumes that thread_id_type fits into machine word"); + return tbb::tbb_hasher(id.my_id); + } + + // A workaround for lack of tbb::atomic (which would require id to be POD in C++03). + friend id atomic_compare_and_swap(id& location, const id& value, const id& comparand){ + return as_atomic(location.my_id).compare_and_swap(value.my_id, comparand.my_id); + } + }; // tbb_thread_v3::id + + tbb_thread_v3::id tbb_thread_v3::get_id() const __TBB_NOEXCEPT(true) { +#if _WIN32||_WIN64 + return id(my_thread_id); +#else + return id(my_handle); +#endif // _WIN32||_WIN64 + } + + void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ); + tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3(); + void __TBB_EXPORTED_FUNC thread_yield_v3(); + void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i); + + inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) + { + return x.my_id == y.my_id; + } + inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) + { + return x.my_id != y.my_id; + } + inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) + { + return x.my_id < y.my_id; + } + inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) + { + return x.my_id <= y.my_id; + } + inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) + { + return x.my_id > y.my_id; + } + inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true) + { + return x.my_id >= y.my_id; + } + +} // namespace internal; + +//! Users reference thread class by name tbb_thread +__TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::thread is deprecated, use std::thread") typedef internal::tbb_thread_v3 tbb_thread; + +using internal::operator==; +using internal::operator!=; +using internal::operator<; +using internal::operator>; +using internal::operator<=; +using internal::operator>=; + +inline void move( tbb_thread& t1, tbb_thread& t2 ) { + internal::move_v3(t1, t2); +} + +inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true) { + std::swap(t1.my_handle, t2.my_handle); +#if _WIN32||_WIN64 + std::swap(t1.my_thread_id, t2.my_thread_id); +#endif /* _WIN32||_WIN64 */ +} + +namespace this_tbb_thread { + __TBB_DEPRECATED_IN_VERBOSE_MODE inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); } + //! Offers the operating system the opportunity to schedule another thread. + __TBB_DEPRECATED_IN_VERBOSE_MODE inline void yield() { internal::thread_yield_v3(); } + //! The current thread blocks at least until the time specified. + __TBB_DEPRECATED_IN_VERBOSE_MODE inline void sleep(const tick_count::interval_t &i) { + internal::thread_sleep_v3(i); + } +} // namespace this_tbb_thread + +} // namespace tbb + +#include "internal/_warning_suppress_disable_notice.h" +#undef __TBB_tbb_thread_H_include_area + +#endif /* __TBB_tbb_thread_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbbmalloc_proxy.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbbmalloc_proxy.h new file mode 100644 index 00000000..28f6a405 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tbbmalloc_proxy.h @@ -0,0 +1,65 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* +Replacing the standard memory allocation routines in Microsoft* C/C++ RTL +(malloc/free, global new/delete, etc.) with the TBB memory allocator. + +Include the following header to a source of any binary which is loaded during +application startup + +#include "tbb/tbbmalloc_proxy.h" + +or add following parameters to the linker options for the binary which is +loaded during application startup. It can be either exe-file or dll. + +For win32 +tbbmalloc_proxy.lib /INCLUDE:"___TBB_malloc_proxy" +win64 +tbbmalloc_proxy.lib /INCLUDE:"__TBB_malloc_proxy" +*/ + +#ifndef __TBB_tbbmalloc_proxy_H +#define __TBB_tbbmalloc_proxy_H + +#if _MSC_VER + +#ifdef _DEBUG + #pragma comment(lib, "tbbmalloc_proxy_debug.lib") +#else + #pragma comment(lib, "tbbmalloc_proxy.lib") +#endif + +#if defined(_WIN64) + #pragma comment(linker, "/include:__TBB_malloc_proxy") +#else + #pragma comment(linker, "/include:___TBB_malloc_proxy") +#endif + +#else +/* Primarily to support MinGW */ + +extern "C" void __TBB_malloc_proxy(); +struct __TBB_malloc_proxy_caller { + __TBB_malloc_proxy_caller() { __TBB_malloc_proxy(); } +} volatile __TBB_malloc_proxy_helper_object; + +#endif // _MSC_VER + +/* Public Windows API */ +extern "C" int TBB_malloc_replacement_log(char *** function_replacement_log_ptr); + +#endif //__TBB_tbbmalloc_proxy_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tick_count.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tick_count.h new file mode 100644 index 00000000..bbc92476 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/include/tbb/tick_count.h @@ -0,0 +1,136 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tick_count_H +#define __TBB_tick_count_H + +#include "tbb_stddef.h" + +#if _WIN32||_WIN64 +#include "machine/windows_api.h" +#elif __linux__ +#include +#else /* generic Unix */ +#include +#endif /* (choice of OS) */ + +namespace tbb { + +//! Absolute timestamp +/** @ingroup timing */ +class tick_count { +public: + //! Relative time interval. + class interval_t { + long long value; + explicit interval_t( long long value_ ) : value(value_) {} + public: + //! Construct a time interval representing zero time duration + interval_t() : value(0) {}; + + //! Construct a time interval representing sec seconds time duration + explicit interval_t( double sec ); + + //! Return the length of a time interval in seconds + double seconds() const; + + friend class tbb::tick_count; + + //! Extract the intervals from the tick_counts and subtract them. + friend interval_t operator-( const tick_count& t1, const tick_count& t0 ); + + //! Add two intervals. + friend interval_t operator+( const interval_t& i, const interval_t& j ) { + return interval_t(i.value+j.value); + } + + //! Subtract two intervals. + friend interval_t operator-( const interval_t& i, const interval_t& j ) { + return interval_t(i.value-j.value); + } + + //! Accumulation operator + interval_t& operator+=( const interval_t& i ) {value += i.value; return *this;} + + //! Subtraction operator + interval_t& operator-=( const interval_t& i ) {value -= i.value; return *this;} + private: + static long long ticks_per_second(){ +#if _WIN32||_WIN64 + LARGE_INTEGER qpfreq; + int rval = QueryPerformanceFrequency(&qpfreq); + __TBB_ASSERT_EX(rval, "QueryPerformanceFrequency returned zero"); + return static_cast(qpfreq.QuadPart); +#elif __linux__ + return static_cast(1E9); +#else /* generic Unix */ + return static_cast(1E6); +#endif /* (choice of OS) */ + } + }; + + //! Construct an absolute timestamp initialized to zero. + tick_count() : my_count(0) {}; + + //! Return current time. + static tick_count now(); + + //! Subtract two timestamps to get the time interval between + friend interval_t operator-( const tick_count& t1, const tick_count& t0 ); + + //! Return the resolution of the clock in seconds per tick. + static double resolution() { return 1.0 / interval_t::ticks_per_second(); } + +private: + long long my_count; +}; + +inline tick_count tick_count::now() { + tick_count result; +#if _WIN32||_WIN64 + LARGE_INTEGER qpcnt; + int rval = QueryPerformanceCounter(&qpcnt); + __TBB_ASSERT_EX(rval, "QueryPerformanceCounter failed"); + result.my_count = qpcnt.QuadPart; +#elif __linux__ + struct timespec ts; + int status = clock_gettime( CLOCK_REALTIME, &ts ); + __TBB_ASSERT_EX( status==0, "CLOCK_REALTIME not supported" ); + result.my_count = static_cast(1000000000UL)*static_cast(ts.tv_sec) + static_cast(ts.tv_nsec); +#else /* generic Unix */ + struct timeval tv; + int status = gettimeofday(&tv, NULL); + __TBB_ASSERT_EX( status==0, "gettimeofday failed" ); + result.my_count = static_cast(1000000)*static_cast(tv.tv_sec) + static_cast(tv.tv_usec); +#endif /*(choice of OS) */ + return result; +} + +inline tick_count::interval_t::interval_t( double sec ) { + value = static_cast(sec*interval_t::ticks_per_second()); +} + +inline tick_count::interval_t operator-( const tick_count& t1, const tick_count& t0 ) { + return tick_count::interval_t( t1.my_count-t0.my_count ); +} + +inline double tick_count::interval_t::seconds() const { + return value*tick_count::resolution(); +} + +} // namespace tbb + +#endif /* __TBB_tick_count_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/index.html new file mode 100644 index 00000000..8aee7ae9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/index.html @@ -0,0 +1,48 @@ + + +

Overview

+Top level directory for Intel® Threading Building Blocks (Intel® TBB). +

Common directories

+
+
include +
Include files required for compiling code that uses the library. +
examples +
Examples of how to use the library. +
python +
Python* API for Intel TBB. +
+

Intel TBB source package

+

+To build Intel TBB, use the top-level Makefile; see also the build directions. +To port Intel TBB to a new platform, operating system or architecture, see the porting directions. +

+

Files

+
+
Makefile +
Top-level Makefile for Intel TBB. See also the build directions. +
+

Directories

+
+
src +
Source code for the library. +
build, jni +
Internal Makefile infrastructure for Intel TBB. Do not use directly; see the build directions. +
+

Intel TBB binary package

+

Directories

+
+
bin +
Start-up scripts for sourcing library for Linux* OS and macOS*. For Windows* OS: start-up scripts and dynamic-link libraries. +
lib +
Platform-specific binary files for the library. +
+
+

+Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +

+Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +

+* Other names and brands may be claimed as the property of others. + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/jni/Android.mk b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/jni/Android.mk new file mode 100644 index 00000000..74c5863c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/jni/Android.mk @@ -0,0 +1,62 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +export tbb_root?=$(NDK_PROJECT_PATH) + +ifeq (armeabi-v7a,$(APP_ABI)) + export SYSROOT:=$(NDK_ROOT)/platforms/$(APP_PLATFORM)/arch-arm +else ifeq (arm64-v8a,$(APP_ABI)) + export SYSROOT:=$(NDK_ROOT)/platforms/$(APP_PLATFORM)/arch-arm64 +else + export SYSROOT:=$(NDK_ROOT)/platforms/$(APP_PLATFORM)/arch-$(APP_ABI) +endif + +ifeq (windows,$(tbb_os)) + export CPATH_SEPARATOR :=; +else + export CPATH_SEPARATOR :=: +endif + +export ANDROID_NDK_ROOT:=$(NDK_ROOT) +export ndk_version:=$(lastword $(subst -, ,$(ANDROID_NDK_ROOT))) +ndk_version:= $(firstword $(subst /, ,$(ndk_version))) +ndk_version:= $(firstword $(subst \, ,$(ndk_version))) + +ifeq (clang,$(compiler)) + ifeq (,$(findstring $(ndk_version),ifeq (,$(findstring $(ndk_version),$(foreach v, 7 8 9 10 11 12,r$(v) r$(v)b r$(v)c r$(v)d r$(v)e))))) + TBB_RTL :=llvm-libc++ + else + TBB_RTL :=llvm-libc++/libcxx + endif + TBB_RTL_LIB :=llvm-libc++ + TBB_RTL_FILE :=libc++_shared.so +else + TBB_RTL :=gnu-libstdc++/$(NDK_TOOLCHAIN_VERSION) + TBB_RTL_LIB :=$(TBB_RTL) + TBB_RTL_FILE :=libgnustl_shared.so +endif + +export CPATH := $(SYSROOT)/usr/include$(CPATH_SEPARATOR)$(NDK_ROOT)/sources/cxx-stl/$(TBB_RTL)/include$(CPATH_SEPARATOR)$(NDK_ROOT)/sources/cxx-stl/$(TBB_RTL)/libs/$(APP_ABI)/include$(CPATH_SEPARATOR)$(NDK_ROOT)/sources/android/support/include + +LIB_STL_ANDROID_DIR := $(NDK_ROOT)/sources/cxx-stl/$(TBB_RTL_LIB)/libs/$(APP_ABI) +#LIB_STL_ANDROID is required to be set up for copying Android specific library to a device next to test +export LIB_STL_ANDROID := $(LIB_STL_ANDROID_DIR)/$(TBB_RTL_FILE) +export CPLUS_LIB_PATH := $(SYSROOT)/usr/lib -L$(LIB_STL_ANDROID_DIR) +export target_os_version:=$(APP_PLATFORM) +export tbb_tool_prefix:=$(TOOLCHAIN_PREFIX) +export TARGET_CXX +export TARGET_CC +export TARGET_CFLAGS + +include $(NDK_PROJECT_PATH)/src/Makefile diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/jni/Application.mk b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/jni/Application.mk new file mode 100644 index 00000000..8f711496 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/jni/Application.mk @@ -0,0 +1,67 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ifndef tbb_os + + # Windows sets environment variable OS; for other systems, ask uname + ifeq ($(OS),) + OS:=$(shell uname) + ifeq ($(OS),) + $(error "Cannot detect operating system") + endif + export tbb_os=$(OS) + endif + + ifeq ($(OS), Windows_NT) + export tbb_os=windows + endif + ifeq ($(OS), Linux) + export tbb_os=linux + endif + ifeq ($(OS), Darwin) + export tbb_os=macos + endif + +endif + +export compiler?=clang +export arch?=ia32 +export target?=android + +ifeq (ia32,$(arch)) + APP_ABI:=x86 + export TRIPLE:=i686-linux-android +else ifeq (intel64,$(arch)) + APP_ABI:=x86_64 + export TRIPLE:=x86_64-linux-android +else ifeq (arm,$(arch)) + APP_ABI:=armeabi-v7a + export TRIPLE:=arm-linux-androideabi +else ifeq (arm64,$(arch)) + APP_ABI:=arm64-v8a + export TRIPLE:=aarch64-linux-android +else + APP_ABI:=$(arch) +endif + +api_version?=21 +export API_LEVEL:=$(api_version) +APP_PLATFORM:=android-$(api_version) + +ifeq (clang,$(compiler)) + NDK_TOOLCHAIN_VERSION:=clang + APP_STL:=c++_shared +else + NDK_TOOLCHAIN_VERSION:=4.9 +endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/Makefile b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/Makefile new file mode 100644 index 00000000..2afbca67 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/Makefile @@ -0,0 +1,45 @@ +# Copyright (c) 2016-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +tbb_root?=.. +BUILDING_PHASE:=0 +include $(tbb_root)/build/common.inc +.PHONY: all release test install test-install + +export TBBROOT=$(abspath $(tbb_root)) +SRC=$(tbb_root)/python/*.py $(tbb_root)/python/tbb/* +PY_SETUP=python $(tbb_root)/python/setup.py + +all: install test + +clean: + $(PY_SETUP) clean -b$(work_dir)_release + +release: CC=$(compiler) +release: $(SRC) rml + $(PY_SETUP) build -b$(work_dir)_release -f check + +install: CC=$(compiler) +install: $(SRC) rml + $(PY_SETUP) build -b$(work_dir)_release build_ext -f -I$(tbb_root)/include -L$(work_dir)_release install -f + +test: + python -m tbb test + +rml: +ifeq (linux,$(tbb_os)) + $(MAKE) -C "$(work_dir)_release" -rf $(tbb_root)/python/rml/Makefile cfg=release rml +rml_%: + $(MAKE) -C "$(work_dir)_release" -rf $(tbb_root)/python/rml/Makefile cfg=release $(subst rml_,,$@) +endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/TBB.py b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/TBB.py new file mode 100644 index 00000000..1a5d0e32 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/TBB.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from tbb import * +from tbb import __all__, __doc__ + +if __name__ == "__main__": + from tbb import _main + import sys + sys.exit(_main()) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/index.html new file mode 100644 index 00000000..f5e69276 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/index.html @@ -0,0 +1,84 @@ + + +

Python* API for Intel® Threading Building Blocks (Intel® TBB). +

+ +

Overview

+It is a preview Python* module which unlocks opportunities for additional performance in multi-threaded and multiprocess Python programs by enabling threading composability +between two or more thread-enabled libraries like Numpy, Scipy, Sklearn, Dask, Joblib, and etc. +

+The biggest improvement can be achieved when a task pool like the ThreadPool or Pool from the Python standard library or libraries like Dask or Joblib (used either in multi-threading or multi-processing mode) +execute tasks calling compute-intensive functions of Numpy/Scipy/Sklearn/PyDAAL which in turn are parallelized using Intel® Math Kernel Library or/and Intel® TBB. +

+The module implements Pool class with the standard interface using Intel® TBB which can be used to replace Python's ThreadPool. +Thanks to the monkey-patching technique implemented in class Monkey, no source code change is needed in order to enable threading composability in Python programs. +

+For more information and examples, please refer to online blog. + +

Directories

+
+
rml +
The folder contains sources for building the plugin with cross-process dynamic thread scheduler implementation. +
tbb +
The folder contains Python module sources. +
+ +

Files

+
+
setup.py +
Standard Python setup script. +
Makefile +
Internal Makefile for building, installing, and testing. See below. +
TBB.py +
Alternative entry point for Python module. +
+ +

Build and install (source package only)

+For accessing targets defined in python/Makefile, please use +src/Makefile +instead and build runtime libraries before working with Python. +
+
make -C ../src python_all +
Install and test as described below. +
make -C ../src python_install +
Install module into Python environment. +
make -C ../src python_test +
Test installed Intel® TBB module for Python. +
make -C ../src python_release +
Recompile Python module. Result is located in Intel® TBB build directory. +
make -C ../src python_clean +
Remove any intermediate files produced by the commands above. Does not remove installed module. +
+ +

Command-line interface

+
+
python -m tbb -h +
Print documentation on command-line interface
+
pydoc tbb +
Read built-in documentation for Python interfaces.
+
python-tbb your_script.py +
python -m tbb your_script.py +
Run your_script.py in context of `with tbb.Monkey():` when Intel® TBB is enabled. By default only multi-threading will be covered.
+
python -m tbb --ipc your_script.py +
Run your_script.py in context of `with tbb.Monkey():` when Intel® TBB enabled in both multi-threading and multi-processing modes.
+
+ +

System Requirements

+The Python module was not tested on older versions of Python thus we require at least Python versions 2.7 and 3.5 or higher.
+SWIG must be of version 3.0.6 or higher
+OS versions: +Microsoft* Windows* Server 2012, +Microsoft* Windows* 10, +Ubuntu* 14.04 LTS, +Red Hat* Enterprise Linux* 7. +
+Up to parent directory +

+Copyright © 2016-2020 Intel Corporation. All Rights Reserved. +

+Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +

+* Other names and brands may be claimed as the property of others. + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/Makefile b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/Makefile new file mode 100644 index 00000000..dc3b0bd1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/Makefile @@ -0,0 +1,151 @@ +# Copyright (c) 2017-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +.NOTPARALLEL: + +tbb_root ?= ../.. +BUILDING_PHASE=0 +TEST_RESOURCE = $(RML.RES) +include $(tbb_root)/build/common.inc +DEBUG_SUFFIX=$(findstring _debug,_$(cfg)) + +ifneq (linux,$(target)) +$(error "IPC RML is supported on Linux only") +endif + +.PHONY: default rml test clean + +# default target +default: rml test + +RML_ROOT ?= $(tbb_root)/src/rml +RML_SERVER_ROOT = $(RML_ROOT)/server +# TODO: new API needs to be added for this server, exposing everything +RML.DEF = + +VPATH = $(tbb_root)/src/tbb $(tbb_root)/src/tbb/$(ASSEMBLY_SOURCE) +VPATH += $(tbb_root)/python/rml $(RML_ROOT)/test $(tbb_root)/src/test +VPATH += $(tbb_root)/src/rml/client + +include $(tbb_root)/build/common_rules.inc + +#-------------------------------------------------------------------------- +# Define rules for making the RML server shared library and client objects. +#-------------------------------------------------------------------------- + +# Object files that make up RML server +RML_SERVER.OBJ = ipc_server.$(OBJ) + +# Object files that RML clients need +RML_TBB_CLIENT.OBJ ?= ipc_utils.$(OBJ) +RML.OBJ = $(RML_SERVER.OBJ) $(RML_TBB_CLIENT.OBJ) +ifeq (windows,$(tbb_os)) +RML_ASM.OBJ = $(if $(findstring intel64,$(arch)),$(TBB_ASM.OBJ)) +endif +ifeq (linux,$(tbb_os)) +RML_ASM.OBJ = $(if $(findstring ia64,$(arch)),$(TBB_ASM.OBJ)) +endif + +RML_TBB_DEP= cache_aligned_allocator_rml.$(OBJ) dynamic_link_rml.$(OBJ) tbb_misc_rml.$(OBJ) tbb_misc_ex_rml.$(OBJ) +TBB_DEP_NON_RML_TEST?= cache_aligned_allocator_rml.$(OBJ) dynamic_link_rml.$(OBJ) $(RML_ASM.OBJ) tbb_misc_rml.$(OBJ) tbb_misc_ex_rml.$(OBJ) +ifeq ($(cfg),debug) +RML_TBB_DEP+= spin_mutex_rml.$(OBJ) +TBB_DEP_RML_TEST?= $(RML_ASM.OBJ) tbb_misc_rml.$(OBJ) +else +TBB_DEP_RML_TEST?= $(RML_ASM.OBJ) +endif +LIBS += $(LIBDL) +TBB_DEP_RML_TEST = rml_tbb.$(OBJ) dynamic_link_rml.$(OBJ) + +INCLUDES += $(INCLUDE_KEY)$(RML_ROOT)/include $(INCLUDE_KEY). +T_INCLUDES = $(INCLUDES) $(INCLUDE_KEY)$(tbb_root)/src/test $(INCLUDE_KEY)$(RML_SERVER_ROOT) + +# Suppress superfluous warnings for RML compilation +R_CPLUS_FLAGS = $(subst DO_ITT_NOTIFY,DO_ITT_NOTIFY=0,$(CPLUS_FLAGS)) $(WARNING_SUPPRESS) \ + $(DEFINE_KEY)TBB_USE_THREADING_TOOLS=0 $(DEFINE_KEY)__TBB_RML_STATIC=1 $(DEFINE_KEY)__TBB_NO_IMPLICIT_LINKAGE=1 + +%.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(R_CPLUS_FLAGS) $(PIC_KEY) $(DSE_KEY) $(INCLUDES) $< + +tbb_misc_rml.$(OBJ) $(RML_SERVER.OBJ): version_string.ver + +RML_TEST.OBJ = test_job_automaton.$(OBJ) test_thread_monitor.$(OBJ) test_rml_tbb.$(OBJ) + +$(RML_TBB_DEP): %_rml.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(OUTPUTOBJ_KEY)$@ $(R_CPLUS_FLAGS) $(PIC_KEY) $(DSE_KEY) $(INCLUDES) $< + +$(RML_TEST.OBJ): %.$(OBJ): %.cpp + $(CPLUS) $(COMPILE_ONLY) $(R_CPLUS_FLAGS) $(PIC_KEY) $(T_INCLUDES) $< + +ifneq (,$(RML.DEF)) +rml.def: $(RML.DEF) + $(CPLUS) $(PREPROC_ONLY) $< $(CPLUS_FLAGS) $(INCLUDES) > $@ + +LIB_LINK_FLAGS += $(EXPORT_KEY)rml.def +$(RML.DLL): rml.def +endif + +$(RML.DLL): CPLUS_FLAGS += $(SDL_FLAGS) +$(RML.DLL): BUILDING_LIBRARY = $(RML.DLL) +$(RML.DLL): $(RML_TBB_DEP) $(RML.OBJ) $(RML.RES) $(RML_NO_VERSION.DLL) $(RML_ASM.OBJ) + $(LIB_LINK_CMD) $(LIB_OUTPUT_KEY)$(RML.DLL) $(RML.OBJ) $(RML_TBB_DEP) $(RML_ASM.OBJ) $(RML.RES) $(LIB_LINK_LIBS) $(LIB_LINK_FLAGS) + +ifneq (,$(RML_NO_VERSION.DLL)) +$(RML_NO_VERSION.DLL): + echo "INPUT ($(RML.DLL))" > $(RML_NO_VERSION.DLL) +endif + +rml: rml_dll +rml_dll: $(RML.DLL) + +#------------------------------------------------------ +# End of rules for making the RML server shared library +#------------------------------------------------------ + +#------------------------------------------------------ +# Define rules for making the RML unit tests +#------------------------------------------------------ + +add_debug=$(basename $(1))_debug$(suffix $(1)) +cross_suffix=$(if $(crosstest),$(if $(DEBUG_SUFFIX),$(subst _debug,,$(1)),$(call add_debug,$(1))),$(1)) + +RML_TESTS = test_job_automaton.$(TEST_EXT) test_thread_monitor.$(TEST_EXT) +RML_CUSTOM_TESTS = test_rml_tbb.$(TEST_EXT) + +test_rml_tbb.$(TEST_EXT): test_rml_tbb.$(OBJ) $(RML_TBB_CLIENT.OBJ) $(TBB_DEP_RML_TEST) + $(CPLUS) $(OUTPUT_KEY)$@ $(CPLUS_FLAGS) test_rml_tbb.$(OBJ) $(RML_TBB_CLIENT.OBJ) $(TBB_DEP_RML_TEST) $(LIBS) $(LINK_FLAGS) + +$(RML_TESTS): %.$(TEST_EXT): %.$(OBJ) $(TBB_DEP_NON_RML_TEST) + $(CPLUS) $(OUTPUT_KEY)$@ $(CPLUS_FLAGS) $< $(TBB_DEP_NON_RML_TEST) $(LIBS) $(LINK_FLAGS) + +export IPC_ENABLE=1 +### run_cmd is usually empty +test: $(call cross_suffix,$(RML.DLL)) $(TEST_PREREQUISITE) $(RML_TESTS) $(RML_CUSTOM_TESTS) + $(run_cmd) ./test_job_automaton.$(TEST_EXT) $(args) + $(run_cmd) ./test_thread_monitor.$(TEST_EXT) $(args) +#TODO: $(run_cmd) ./test_rml_tbb.$(TEST_EXT) $(args) +#TODO: IPC_ENABLE=1 LD_PRELOAD=$(abspath libirml.so.1) $(MAKE) -rf $(tbb_root)/src/Makefile cfg=release tbb_test_release + +#------------------------------------------------------ +# End of rules for making the TBBMalloc unit tests +#------------------------------------------------------ + +# Include automatically generated dependencies +-include *.d + +clean: + -rm -rf *.o *.so* *.d *.def version_string.ver + -rm -rf $(work_dir)_release/libirml* + -rm -rf $(work_dir)_debug/libirml* diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_server.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_server.cpp new file mode 100644 index 00000000..1146a160 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_server.cpp @@ -0,0 +1,1115 @@ +/* + Copyright (c) 2017-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "rml_tbb.h" +#include "../server/thread_monitor.h" +#include "tbb/atomic.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/scheduler_common.h" +#include "tbb/governor.h" +#include "tbb/tbb_misc.h" + +#include "ipc_utils.h" + +#include + +namespace rml { +namespace internal { + +static const char* IPC_ENABLE_VAR_NAME = "IPC_ENABLE"; + +typedef versioned_object::version_type version_type; + +extern "C" factory::status_type __RML_open_factory(factory& f, version_type& /*server_version*/, version_type /*client_version*/) { + if( !tbb::internal::rml::get_enable_flag( IPC_ENABLE_VAR_NAME ) ) { + return factory::st_incompatible; + } + + // Hack to keep this library from being closed + static tbb::atomic one_time_flag; + if( one_time_flag.compare_and_swap(true,false)==false ) { + __TBB_ASSERT( (size_t)f.library_handle!=factory::c_dont_unload, NULL ); +#if _WIN32||_WIN64 + f.library_handle = reinterpret_cast(factory::c_dont_unload); +#else + f.library_handle = reinterpret_cast(factory::c_dont_unload); +#endif + } + // End of hack + + return factory::st_success; +} + +extern "C" void __RML_close_factory(factory& /*f*/) { +} + +class ipc_thread_monitor : public thread_monitor { +public: + ipc_thread_monitor() : thread_monitor() {} + +#if USE_WINTHREAD +#elif USE_PTHREAD + static handle_type launch(thread_routine_type thread_routine, void* arg, size_t stack_size); +#endif +}; + +#if USE_WINTHREAD +#elif USE_PTHREAD +inline ipc_thread_monitor::handle_type ipc_thread_monitor::launch(void* (*thread_routine)(void*), void* arg, size_t stack_size) { + pthread_attr_t s; + if( pthread_attr_init( &s ) ) return 0; + if( stack_size>0 ) { + if( pthread_attr_setstacksize( &s, stack_size ) ) return 0; + } + pthread_t handle; + if( pthread_create( &handle, &s, thread_routine, arg ) ) return 0; + if( pthread_attr_destroy( &s ) ) return 0; + return handle; +} +#endif + +}} //rml::internal + +using rml::internal::ipc_thread_monitor; + +namespace tbb { +namespace internal { +namespace rml { + +typedef ipc_thread_monitor::handle_type thread_handle; + +class ipc_server; + +static const char* IPC_MAX_THREADS_VAR_NAME = "MAX_THREADS"; +static const char* IPC_ACTIVE_SEM_PREFIX = "/__IPC_active"; +static const char* IPC_STOP_SEM_PREFIX = "/__IPC_stop"; +static const char* IPC_ACTIVE_SEM_VAR_NAME = "IPC_ACTIVE_SEMAPHORE"; +static const char* IPC_STOP_SEM_VAR_NAME = "IPC_STOP_SEMAPHORE"; +static const mode_t IPC_SEM_MODE = 0660; + +static tbb::atomic my_global_thread_count; + +char* get_active_sem_name() { + char* value = getenv( IPC_ACTIVE_SEM_VAR_NAME ); + if( value!=NULL && strlen( value )>0 ) { + char* sem_name = new char[strlen( value ) + 1]; + __TBB_ASSERT( sem_name!=NULL, NULL ); + strcpy( sem_name, value ); + return sem_name; + } else { + return get_shared_name( IPC_ACTIVE_SEM_PREFIX ); + } +} + +char* get_stop_sem_name() { + char* value = getenv( IPC_STOP_SEM_VAR_NAME ); + if( value!=NULL && strlen( value )>0 ) { + char* sem_name = new char[strlen( value ) + 1]; + __TBB_ASSERT( sem_name!=NULL, NULL ); + strcpy( sem_name, value ); + return sem_name; + } else { + return get_shared_name( IPC_STOP_SEM_PREFIX ); + } +} + +static void release_thread_sem(sem_t* my_sem) { + int old; + do { + old = my_global_thread_count; + if( old<=0 ) return; + } while( my_global_thread_count.compare_and_swap(old-1, old)!=old ); + if( old>0 ) { + sem_post( my_sem ); + } +} + +extern "C" void set_active_sem_name() { + char* templ = new char[strlen( IPC_ACTIVE_SEM_PREFIX ) + strlen( "_XXXXXX" ) + 1]; + __TBB_ASSERT( templ!=NULL, NULL ); + strcpy( templ, IPC_ACTIVE_SEM_PREFIX ); + strcpy( templ + strlen( IPC_ACTIVE_SEM_PREFIX ), "_XXXXXX" ); + char* sem_name = mktemp( templ ); + if( sem_name!=NULL ) { + int status = setenv( IPC_ACTIVE_SEM_VAR_NAME, sem_name, 1 ); + __TBB_ASSERT_EX( status==0, NULL ); + } + delete[] templ; +} + +extern "C" void set_stop_sem_name() { + char* templ = new char[strlen( IPC_STOP_SEM_PREFIX ) + strlen( "_XXXXXX" ) + 1]; + __TBB_ASSERT( templ!=NULL, NULL ); + strcpy( templ, IPC_STOP_SEM_PREFIX ); + strcpy( templ + strlen( IPC_STOP_SEM_PREFIX ), "_XXXXXX" ); + char* sem_name = mktemp( templ ); + if( sem_name!=NULL ) { + int status = setenv( IPC_STOP_SEM_VAR_NAME, sem_name, 1 ); + __TBB_ASSERT_EX( status==0, NULL ); + } + delete[] templ; +} + +extern "C" void release_resources() { + if( my_global_thread_count!=0 ) { + char* active_sem_name = get_active_sem_name(); + sem_t* my_active_sem = sem_open( active_sem_name, O_CREAT ); + __TBB_ASSERT( my_active_sem, "Unable to open active threads semaphore" ); + delete[] active_sem_name; + + do { + release_thread_sem( my_active_sem ); + } while( my_global_thread_count!=0 ); + } +} + +extern "C" void release_semaphores() { + int status = 0; + char* sem_name = NULL; + + sem_name = get_active_sem_name(); + if( sem_name==NULL ) { + runtime_warning("Can not get RML semaphore name"); + return; + } + status = sem_unlink( sem_name ); + if( status!=0 ) { + if( errno==ENOENT ) { + /* There is no semaphore with the given name, nothing to do */ + } else { + runtime_warning("Can not release RML semaphore"); + return; + } + } + delete[] sem_name; + + sem_name = get_stop_sem_name(); + if( sem_name==NULL ) { + runtime_warning( "Can not get RML semaphore name" ); + return; + } + status = sem_unlink( sem_name ); + if( status!=0 ) { + if( errno==ENOENT ) { + /* There is no semaphore with the given name, nothing to do */ + } else { + runtime_warning("Can not release RML semaphore"); + return; + } + } + delete[] sem_name; +} + +class ipc_worker: no_copy { +protected: + //! State in finite-state machine that controls the worker. + /** State diagram: + /----------stop---\ + | ^ | + V | | + init --> starting --> normal | + | | | | + | V | | + \------> quit <-------/<----/ + */ + enum state_t { + //! *this is initialized + st_init, + //! *this has associated thread that is starting up. + st_starting, + //! Associated thread is doing normal life sequence. + st_normal, + //! Associated thread is stopped but can be started again. + st_stop, + //! Associated thread has ended normal life sequence and promises to never touch *this again. + st_quit + }; + atomic my_state; + + //! Associated server + ipc_server& my_server; + + //! Associated client + tbb_client& my_client; + + //! index used for avoiding the 64K aliasing problem + const size_t my_index; + + //! Monitor for sleeping when there is no work to do. + /** The invariant that holds for sleeping workers is: + "my_slack<=0 && my_state==st_normal && I am on server's list of asleep threads" */ + ipc_thread_monitor my_thread_monitor; + + //! Handle of the OS thread associated with this worker + thread_handle my_handle; + + //! Link for list of workers that are sleeping or have no associated thread. + ipc_worker* my_next; + + friend class ipc_server; + + //! Actions executed by the associated thread + void run(); + + //! Wake up associated thread (or launch a thread if there is none) + bool wake_or_launch(); + + //! Called by a thread (usually not the associated thread) to commence termination. + void start_shutdown(bool join); + + //! Called by a thread (usually not the associated thread) to commence stopping. + void start_stopping(bool join); + + static __RML_DECL_THREAD_ROUTINE thread_routine(void* arg); + + static void release_handle(thread_handle my_handle, bool join); + +protected: + ipc_worker(ipc_server& server, tbb_client& client, const size_t i) : + my_server(server), + my_client(client), + my_index(i) + { + my_state = st_init; + } +}; + +static const size_t cache_line_size = tbb::internal::NFS_MaxLineSize; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warnings about uninstantiable class + #pragma warning(push) + #pragma warning(disable:4510 4610) +#endif +class padded_ipc_worker: public ipc_worker { + char pad[cache_line_size - sizeof(ipc_worker)%cache_line_size]; +public: + padded_ipc_worker(ipc_server& server, tbb_client& client, const size_t i) + : ipc_worker( server,client,i ) { suppress_unused_warning(pad); } +}; +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +class ipc_waker : public padded_ipc_worker { +private: + static __RML_DECL_THREAD_ROUTINE thread_routine(void* arg); + void run(); + bool wake_or_launch(); + + friend class ipc_server; + +public: + ipc_waker(ipc_server& server, tbb_client& client, const size_t i) + : padded_ipc_worker( server, client, i ) {} +}; + +class ipc_stopper : public padded_ipc_worker { +private: + static __RML_DECL_THREAD_ROUTINE thread_routine(void* arg); + void run(); + bool wake_or_launch(); + + friend class ipc_server; + +public: + ipc_stopper(ipc_server& server, tbb_client& client, const size_t i) + : padded_ipc_worker( server, client, i ) {} +}; + +class ipc_server: public tbb_server, no_copy { +private: + tbb_client& my_client; + //! Maximum number of threads to be created. + /** Threads are created lazily, so maximum might not actually be reached. */ + tbb_client::size_type my_n_thread; + + //! Stack size for each thread. */ + const size_t my_stack_size; + + //! Number of jobs that could use their associated thread minus number of active threads. + /** If negative, indicates oversubscription. + If positive, indicates that more threads should run. + Can be lowered asynchronously, but must be raised only while holding my_asleep_list_mutex, + because raising it impacts the invariant for sleeping threads. */ + atomic my_slack; + + //! Counter used to determine when to delete this. + atomic my_ref_count; + + padded_ipc_worker* my_thread_array; + + //! List of workers that are asleep or committed to sleeping until notified by another thread. + tbb::atomic my_asleep_list_root; + + //! Protects my_asleep_list_root + typedef scheduler_mutex_type asleep_list_mutex_type; + asleep_list_mutex_type my_asleep_list_mutex; + + //! Should server wait workers while terminate + const bool my_join_workers; + + //! Service thread for waking of workers + ipc_waker* my_waker; + + //! Service thread to stop threads + ipc_stopper* my_stopper; + + //! Semaphore to account active threads + sem_t* my_active_sem; + + //! Semaphore to account stop threads + sem_t* my_stop_sem; + +#if TBB_USE_ASSERT + atomic my_net_slack_requests; +#endif /* TBB_USE_ASSERT */ + + //! Wake up to two sleeping workers, if there are any sleeping. + /** The call is used to propagate a chain reaction where each thread wakes up two threads, + which in turn each wake up two threads, etc. */ + void propagate_chain_reaction() { + // First test of a double-check idiom. Second test is inside wake_some(0). + if( my_slack>0 ) { + int active_threads = 0; + if( try_get_active_thread() ) { + ++active_threads; + if( try_get_active_thread() ) { + ++active_threads; + } + wake_some( 0, active_threads ); + } + } + } + + //! Try to add t to list of sleeping workers + bool try_insert_in_asleep_list(ipc_worker& t); + + //! Try to add t to list of sleeping workers even if there is some work to do + bool try_insert_in_asleep_list_forced(ipc_worker& t); + + //! Equivalent of adding additional_slack to my_slack and waking up to 2 threads if my_slack permits. + void wake_some(int additional_slack, int active_threads); + + //! Equivalent of adding additional_slack to my_slack and waking up to 1 thread if my_slack permits. + void wake_one_forced(int additional_slack); + + //! Stop one thread from asleep list + bool stop_one(); + + //! Wait for active thread + bool wait_active_thread(); + + //! Try to get active thread + bool try_get_active_thread(); + + //! Release active thread + void release_active_thread(); + + //! Wait for thread to stop + bool wait_stop_thread(); + + //! Add thread to stop list + void add_stop_thread(); + + void remove_server_ref() { + if( --my_ref_count==0 ) { + my_client.acknowledge_close_connection(); + this->~ipc_server(); + tbb::cache_aligned_allocator().deallocate( this, 1 ); + } + } + + friend class ipc_worker; + friend class ipc_waker; + friend class ipc_stopper; +public: + ipc_server(tbb_client& client); + virtual ~ipc_server(); + + version_type version() const __TBB_override { + return 0; + } + + void request_close_connection(bool /*exiting*/) __TBB_override { + my_waker->start_shutdown(false); + my_stopper->start_shutdown(false); + for( size_t i=0; i=2 && !__MINGW64__ +// ensure that stack is properly aligned +__attribute__((force_align_arg_pointer)) +#endif +__RML_DECL_THREAD_ROUTINE ipc_worker::thread_routine(void* arg) { + ipc_worker* self = static_cast(arg); + AVOID_64K_ALIASING( self->my_index ); + self->run(); + return 0; +} +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +void ipc_worker::release_handle(thread_handle handle, bool join) { + if( join ) + ipc_thread_monitor::join( handle ); + else + ipc_thread_monitor::detach_thread( handle ); +} + +void ipc_worker::start_shutdown(bool join) { + state_t s; + + do { + s = my_state; + __TBB_ASSERT( s!=st_quit, NULL ); + } while( my_state.compare_and_swap( st_quit, s )!=s ); + if( s==st_normal || s==st_starting ) { + // May have invalidated invariant for sleeping, so wake up the thread. + // Note that the notify() here occurs without maintaining invariants for my_slack. + // It does not matter, because my_state==st_quit overrides checking of my_slack. + my_thread_monitor.notify(); + // Do not need release handle in st_init state, + // because in this case the thread wasn't started yet. + // For st_starting release is done at launch site. + if( s==st_normal ) + release_handle( my_handle, join ); + } +} + +void ipc_worker::start_stopping(bool join) { + state_t s; + + do { + s = my_state; + } while( my_state.compare_and_swap( st_stop, s )!=s ); + if( s==st_normal || s==st_starting ) { + // May have invalidated invariant for sleeping, so wake up the thread. + // Note that the notify() here occurs without maintaining invariants for my_slack. + // It does not matter, because my_state==st_quit overrides checking of my_slack. + my_thread_monitor.notify(); + // Do not need release handle in st_init state, + // because in this case the thread wasn't started yet. + // For st_starting release is done at launch site. + if( s==st_normal ) + release_handle( my_handle, join ); + } +} + +void ipc_worker::run() { + my_server.propagate_chain_reaction(); + + // Transiting to st_normal here would require setting my_handle, + // which would create race with the launching thread and + // complications in handle management on Windows. + + ::rml::job& j = *my_client.create_one_job(); + state_t state = my_state; + while( state!=st_quit && state!=st_stop ) { + if( my_server.my_slack>=0 ) { + my_client.process(j); + } else { + ipc_thread_monitor::cookie c; + // Prepare to wait + my_thread_monitor.prepare_wait(c); + // Check/set the invariant for sleeping + state = my_state; + if( state!=st_quit && state!=st_stop && my_server.try_insert_in_asleep_list(*this) ) { + if( my_server.my_n_thread > 1 ) my_server.release_active_thread(); + my_thread_monitor.commit_wait(c); + my_server.propagate_chain_reaction(); + } else { + // Invariant broken + my_thread_monitor.cancel_wait(); + } + } + state = my_state; + } + my_client.cleanup(j); + + my_server.remove_server_ref(); +} + +inline bool ipc_worker::wake_or_launch() { + if( ( my_state==st_init && my_state.compare_and_swap( st_starting, st_init )==st_init ) || + ( my_state==st_stop && my_state.compare_and_swap( st_starting, st_stop )==st_stop ) ) { + // after this point, remove_server_ref() must be done by created thread +#if USE_WINTHREAD + my_handle = ipc_thread_monitor::launch( thread_routine, this, my_server.my_stack_size, &this->my_index ); +#elif USE_PTHREAD + { + affinity_helper fpa; + fpa.protect_affinity_mask( /*restore_process_mask=*/true ); + my_handle = ipc_thread_monitor::launch( thread_routine, this, my_server.my_stack_size ); + if( my_handle == 0 ) { + // Unable to create new thread for process + // However, this is expected situation for the use cases of this coordination server + state_t s = my_state.compare_and_swap( st_init, st_starting ); + if (st_starting != s) { + // Do shutdown during startup. my_handle can't be released + // by start_shutdown, because my_handle value might be not set yet + // at time of transition from st_starting to st_quit. + __TBB_ASSERT( s==st_quit, NULL ); + release_handle( my_handle, my_server.my_join_workers ); + } + return false; + } else { + my_server.my_ref_count++; + } + // Implicit destruction of fpa resets original affinity mask. + } +#endif /* USE_PTHREAD */ + state_t s = my_state.compare_and_swap( st_normal, st_starting ); + if( st_starting!=s ) { + // Do shutdown during startup. my_handle can't be released + // by start_shutdown, because my_handle value might be not set yet + // at time of transition from st_starting to st_quit. + __TBB_ASSERT( s==st_quit, NULL ); + release_handle( my_handle, my_server.my_join_workers ); + } + } + else { + my_thread_monitor.notify(); + } + + return true; +} + +//------------------------------------------------------------------------ +// Methods of ipc_waker +//------------------------------------------------------------------------ +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warnings about an initialized variable 'sink_for_alloca' not referenced + #pragma warning(push) + #pragma warning(disable:4189) +#endif +#if __MINGW32__ && __GNUC__==4 &&__GNUC_MINOR__>=2 && !__MINGW64__ +// ensure that stack is properly aligned +__attribute__((force_align_arg_pointer)) +#endif +__RML_DECL_THREAD_ROUTINE ipc_waker::thread_routine(void* arg) { + ipc_waker* self = static_cast(arg); + AVOID_64K_ALIASING( self->my_index ); + self->run(); + return 0; +} +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +void ipc_waker::run() { + // Transiting to st_normal here would require setting my_handle, + // which would create race with the launching thread and + // complications in handle management on Windows. + + while( my_state!=st_quit ) { + bool have_to_sleep = false; + if( my_server.my_slack>0 ) { + if( my_server.wait_active_thread() ) { + if( my_server.my_slack>0 ) { + my_server.wake_some( 0, 1 ); + } else { + my_server.release_active_thread(); + have_to_sleep = true; + } + } + } else { + have_to_sleep = true; + } + if( have_to_sleep ) { + ipc_thread_monitor::cookie c; + // Prepare to wait + my_thread_monitor.prepare_wait(c); + // Check/set the invariant for sleeping + if( my_state!=st_quit && my_server.my_slack<0 ) { + my_thread_monitor.commit_wait(c); + } else { + // Invariant broken + my_thread_monitor.cancel_wait(); + } + } + } + + my_server.remove_server_ref(); +} + +inline bool ipc_waker::wake_or_launch() { + if( my_state==st_init && my_state.compare_and_swap( st_starting, st_init )==st_init ) { + // after this point, remove_server_ref() must be done by created thread +#if USE_WINTHREAD + my_handle = ipc_thread_monitor::launch( thread_routine, this, my_server.my_stack_size, &this->my_index ); +#elif USE_PTHREAD + { + affinity_helper fpa; + fpa.protect_affinity_mask( /*restore_process_mask=*/true ); + my_handle = ipc_thread_monitor::launch( thread_routine, this, my_server.my_stack_size ); + if( my_handle == 0 ) { + runtime_warning( "Unable to create new thread for process %d", getpid() ); + state_t s = my_state.compare_and_swap( st_init, st_starting ); + if (st_starting != s) { + // Do shutdown during startup. my_handle can't be released + // by start_shutdown, because my_handle value might be not set yet + // at time of transition from st_starting to st_quit. + __TBB_ASSERT( s==st_quit, NULL ); + release_handle( my_handle, my_server.my_join_workers ); + } + return false; + } else { + my_server.my_ref_count++; + } + // Implicit destruction of fpa resets original affinity mask. + } +#endif /* USE_PTHREAD */ + state_t s = my_state.compare_and_swap( st_normal, st_starting ); + if( st_starting!=s ) { + // Do shutdown during startup. my_handle can't be released + // by start_shutdown, because my_handle value might be not set yet + // at time of transition from st_starting to st_quit. + __TBB_ASSERT( s==st_quit, NULL ); + release_handle( my_handle, my_server.my_join_workers ); + } + } + else { + my_thread_monitor.notify(); + } + + return true; +} + +//------------------------------------------------------------------------ +// Methods of ipc_stopper +//------------------------------------------------------------------------ +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warnings about an initialized variable 'sink_for_alloca' not referenced + #pragma warning(push) + #pragma warning(disable:4189) +#endif +#if __MINGW32__ && __GNUC__==4 &&__GNUC_MINOR__>=2 && !__MINGW64__ +// ensure that stack is properly aligned +__attribute__((force_align_arg_pointer)) +#endif +__RML_DECL_THREAD_ROUTINE ipc_stopper::thread_routine(void* arg) { + ipc_stopper* self = static_cast(arg); + AVOID_64K_ALIASING( self->my_index ); + self->run(); + return 0; +} +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +void ipc_stopper::run() { + // Transiting to st_normal here would require setting my_handle, + // which would create race with the launching thread and + // complications in handle management on Windows. + + while( my_state!=st_quit ) { + if( my_server.wait_stop_thread() ) { + if( my_state!=st_quit ) { + if( !my_server.stop_one() ) { + my_server.add_stop_thread(); + prolonged_pause(); + } + } + } + } + + my_server.remove_server_ref(); +} + +inline bool ipc_stopper::wake_or_launch() { + if( my_state==st_init && my_state.compare_and_swap( st_starting, st_init )==st_init ) { + // after this point, remove_server_ref() must be done by created thread +#if USE_WINTHREAD + my_handle = ipc_thread_monitor::launch( thread_routine, this, my_server.my_stack_size, &this->my_index ); +#elif USE_PTHREAD + { + affinity_helper fpa; + fpa.protect_affinity_mask( /*restore_process_mask=*/true ); + my_handle = ipc_thread_monitor::launch( thread_routine, this, my_server.my_stack_size ); + if( my_handle == 0 ) { + runtime_warning( "Unable to create new thread for process %d", getpid() ); + state_t s = my_state.compare_and_swap( st_init, st_starting ); + if (st_starting != s) { + // Do shutdown during startup. my_handle can't be released + // by start_shutdown, because my_handle value might be not set yet + // at time of transition from st_starting to st_quit. + __TBB_ASSERT( s==st_quit, NULL ); + release_handle( my_handle, my_server.my_join_workers ); + } + return false; + } else { + my_server.my_ref_count++; + } + // Implicit destruction of fpa resets original affinity mask. + } +#endif /* USE_PTHREAD */ + state_t s = my_state.compare_and_swap( st_normal, st_starting ); + if( st_starting!=s ) { + // Do shutdown during startup. my_handle can't be released + // by start_shutdown, because my_handle value might be not set yet + // at time of transition from st_starting to st_quit. + __TBB_ASSERT( s==st_quit, NULL ); + release_handle( my_handle, my_server.my_join_workers ); + } + } + else { + my_thread_monitor.notify(); + } + + return true; +} + +//------------------------------------------------------------------------ +// Methods of ipc_server +//------------------------------------------------------------------------ +ipc_server::ipc_server(tbb_client& client) : + my_client( client ), + my_stack_size( client.min_stack_size() ), + my_thread_array(NULL), + my_join_workers(false), + my_waker(NULL), + my_stopper(NULL) +{ + my_ref_count = 1; + my_slack = 0; +#if TBB_USE_ASSERT + my_net_slack_requests = 0; +#endif /* TBB_USE_ASSERT */ + my_n_thread = get_num_threads(IPC_MAX_THREADS_VAR_NAME); + if( my_n_thread==0 ) { + my_n_thread = AvailableHwConcurrency(); + __TBB_ASSERT( my_n_thread>0, NULL ); + } + + my_asleep_list_root = NULL; + my_thread_array = tbb::cache_aligned_allocator().allocate( my_n_thread ); + memset( my_thread_array, 0, sizeof(padded_ipc_worker)*my_n_thread ); + for( size_t i=0; imy_next = my_asleep_list_root; + my_asleep_list_root = t; + } + + my_waker = tbb::cache_aligned_allocator().allocate(1); + memset( my_waker, 0, sizeof(ipc_waker) ); + new( my_waker ) ipc_waker( *this, client, my_n_thread ); + + my_stopper = tbb::cache_aligned_allocator().allocate(1); + memset( my_stopper, 0, sizeof(ipc_stopper) ); + new( my_stopper ) ipc_stopper( *this, client, my_n_thread + 1 ); + + char* active_sem_name = get_active_sem_name(); + my_active_sem = sem_open( active_sem_name, O_CREAT, IPC_SEM_MODE, my_n_thread - 1 ); + __TBB_ASSERT( my_active_sem, "Unable to open active threads semaphore" ); + delete[] active_sem_name; + + char* stop_sem_name = get_stop_sem_name(); + my_stop_sem = sem_open( stop_sem_name, O_CREAT, IPC_SEM_MODE, 0 ); + __TBB_ASSERT( my_stop_sem, "Unable to open stop threads semaphore" ); + delete[] stop_sem_name; +} + +ipc_server::~ipc_server() { + __TBB_ASSERT( my_net_slack_requests==0, NULL ); + + for( size_t i=my_n_thread; i--; ) + my_thread_array[i].~padded_ipc_worker(); + tbb::cache_aligned_allocator().deallocate( my_thread_array, my_n_thread ); + tbb::internal::poison_pointer( my_thread_array ); + + my_waker->~ipc_waker(); + tbb::cache_aligned_allocator().deallocate( my_waker, 1 ); + tbb::internal::poison_pointer( my_waker ); + + my_stopper->~ipc_stopper(); + tbb::cache_aligned_allocator().deallocate( my_stopper, 1 ); + tbb::internal::poison_pointer( my_stopper ); + + sem_close( my_active_sem ); + sem_close( my_stop_sem ); +} + +inline bool ipc_server::try_insert_in_asleep_list(ipc_worker& t) { + asleep_list_mutex_type::scoped_lock lock; + if( !lock.try_acquire( my_asleep_list_mutex ) ) + return false; + // Contribute to slack under lock so that if another takes that unit of slack, + // it sees us sleeping on the list and wakes us up. + int k = ++my_slack; + if( k<=0 ) { + t.my_next = my_asleep_list_root; + my_asleep_list_root = &t; + return true; + } else { + --my_slack; + return false; + } +} + +inline bool ipc_server::try_insert_in_asleep_list_forced(ipc_worker& t) { + asleep_list_mutex_type::scoped_lock lock; + if( !lock.try_acquire( my_asleep_list_mutex ) ) + return false; + // Contribute to slack under lock so that if another takes that unit of slack, + // it sees us sleeping on the list and wakes us up. + ++my_slack; + t.my_next = my_asleep_list_root; + my_asleep_list_root = &t; + return true; +} + +inline bool ipc_server::wait_active_thread() { + if( sem_wait( my_active_sem ) == 0 ) { + ++my_global_thread_count; + return true; + } + return false; +} + +inline bool ipc_server::try_get_active_thread() { + if( sem_trywait( my_active_sem ) == 0 ) { + ++my_global_thread_count; + return true; + } + return false; +} + +inline void ipc_server::release_active_thread() { + release_thread_sem( my_active_sem ); +} + +inline bool ipc_server::wait_stop_thread() { + struct timespec ts; + if( clock_gettime( CLOCK_REALTIME, &ts )==0 ) { + ts.tv_sec++; + if( sem_timedwait( my_stop_sem, &ts )==0 ) { + return true; + } + } + return false; +} + +inline void ipc_server::add_stop_thread() { + sem_post( my_stop_sem ); +} + +void ipc_server::wake_some( int additional_slack, int active_threads ) { + __TBB_ASSERT( additional_slack>=0, NULL ); + ipc_worker* wakee[2]; + ipc_worker **w = wakee; + { + asleep_list_mutex_type::scoped_lock lock(my_asleep_list_mutex); + while( active_threads>0 && my_asleep_list_root && w0 ) { + if( additional_slack+my_slack<=0 ) // additional demand does not exceed surplus supply + break; + --additional_slack; + } else { + // Chain reaction; Try to claim unit of slack + int old; + do { + old = my_slack; + if( old<=0 ) goto done; + } while( my_slack.compare_and_swap( old-1, old )!=old ); + } + // Pop sleeping worker to combine with claimed unit of slack + my_asleep_list_root = (*w++ = my_asleep_list_root)->my_next; + --active_threads; + } + if( additional_slack ) { + // Contribute our unused slack to my_slack. + my_slack += additional_slack; + } + } +done: + while( w>wakee ) { + if( !(*--w)->wake_or_launch() ) { + add_stop_thread(); + do { + } while( !try_insert_in_asleep_list_forced(**w) ); + release_active_thread(); + } + } + while( active_threads ) { + release_active_thread(); + --active_threads; + } +} + +void ipc_server::wake_one_forced( int additional_slack ) { + __TBB_ASSERT( additional_slack>=0, NULL ); + ipc_worker* wakee[1]; + ipc_worker **w = wakee; + { + asleep_list_mutex_type::scoped_lock lock(my_asleep_list_mutex); + while( my_asleep_list_root && w0 ) { + if( additional_slack+my_slack<=0 ) // additional demand does not exceed surplus supply + break; + --additional_slack; + } else { + // Chain reaction; Try to claim unit of slack + int old; + do { + old = my_slack; + if( old<=0 ) goto done; + } while( my_slack.compare_and_swap( old-1, old )!=old ); + } + // Pop sleeping worker to combine with claimed unit of slack + my_asleep_list_root = (*w++ = my_asleep_list_root)->my_next; + } + if( additional_slack ) { + // Contribute our unused slack to my_slack. + my_slack += additional_slack; + } + } +done: + while( w>wakee ) { + if( !(*--w)->wake_or_launch() ) { + add_stop_thread(); + do { + } while( !try_insert_in_asleep_list_forced(**w) ); + } + } +} + +bool ipc_server::stop_one() { + ipc_worker* current = NULL; + ipc_worker* next = NULL; + { + asleep_list_mutex_type::scoped_lock lock(my_asleep_list_mutex); + if( my_asleep_list_root ) { + current = my_asleep_list_root; + if( current->my_state==ipc_worker::st_normal ) { + next = current->my_next; + while( next!= NULL && next->my_state==ipc_worker::st_normal ) { + current = next; + next = current->my_next; + } + current->start_stopping( my_join_workers ); + return true; + } + } + } + return false; +} + +void ipc_server::adjust_job_count_estimate( int delta ) { +#if TBB_USE_ASSERT + my_net_slack_requests+=delta; +#endif /* TBB_USE_ASSERT */ + if( my_n_thread > 1 ) { + if( delta<0 ) { + my_slack+=delta; + } else if( delta>0 ) { + int active_threads = 0; + if( try_get_active_thread() ) { + ++active_threads; + if( try_get_active_thread() ) { + ++active_threads; + } + } + wake_some( delta, active_threads ); + + if( !my_waker->wake_or_launch() ) { + add_stop_thread(); + } + if( !my_stopper->wake_or_launch() ) { + add_stop_thread(); + } + } + } else { // Corner case when RML shouldn't provide any worker thread but client has to have at least one + if( delta<0 ) { + my_slack += delta; + } else { + wake_one_forced( delta ); + } + } +} + +//------------------------------------------------------------------------ +// RML factory methods +//------------------------------------------------------------------------ + +#if USE_PTHREAD + +static tbb_client* my_global_client = NULL; +static tbb_server* my_global_server = NULL; + +void rml_atexit() { + release_resources(); +} + +void rml_atfork_child() { + if( my_global_server!=NULL && my_global_client!=NULL ) { + ipc_server* server = static_cast( my_global_server ); + server->~ipc_server(); + memset( server, 0, sizeof(ipc_server) ); + new( server ) ipc_server( *my_global_client ); + pthread_atfork( NULL, NULL, rml_atfork_child ); + atexit( rml_atexit ); + } +} + +#endif /* USE_PTHREAD */ + +extern "C" tbb_factory::status_type __TBB_make_rml_server(tbb_factory& /*f*/, tbb_server*& server, tbb_client& client) { + server = new( tbb::cache_aligned_allocator().allocate(1) ) ipc_server(client); +#if USE_PTHREAD + my_global_client = &client; + my_global_server = server; + pthread_atfork( NULL, NULL, rml_atfork_child ); + atexit( rml_atexit ); +#endif /* USE_PTHREAD */ + if( getenv( "RML_DEBUG" ) ) { + runtime_warning("IPC server is started"); + } + return tbb_factory::st_success; +} + +extern "C" void __TBB_call_with_my_server_info(::rml::server_info_callback_t /*cb*/, void* /*arg*/) { +} + +} // namespace rml +} // namespace internal + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_utils.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_utils.cpp new file mode 100644 index 00000000..8bb5e160 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_utils.cpp @@ -0,0 +1,140 @@ +/* + Copyright (c) 2017-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ipc_utils.h" + +#include +#include +#include +#include +#include + +namespace tbb { +namespace internal { +namespace rml { + +#define MAX_STR_LEN 255 +#define STARTTIME_ITEM_ID 21 + +static char* get_stat_item(char* line, int item_id) { + int id = 0, i = 0; + + while( id!=item_id ) { + while( line[i]!='(' && line[i]!=' ' && line[i]!='\0' ) { + ++i; + } + if( line[i]==' ' ) { + ++id; + ++i; + } else if( line[i]=='(' ) { + while( line[i]!=')' && line[i]!='\0' ) { + ++i; + } + if( line[i]==')' ) { + ++i; + } else { + return NULL; + } + } else { + return NULL; + } + } + + return line + i; +} + +unsigned long long get_start_time(int pid) { + const char* stat_file_path_template = "/proc/%d/stat"; + char stat_file_path[MAX_STR_LEN + 1]; + sprintf( stat_file_path, stat_file_path_template, pid ); + + FILE* stat_file = fopen( stat_file_path, "rt" ); + if( stat_file==NULL ) { + return 0; + } + + char stat_line[MAX_STR_LEN + 1]; + char* line = fgets( stat_line, MAX_STR_LEN, stat_file ); + if( line==NULL ) { + return 0; + } + + char* starttime_str = get_stat_item( stat_line, STARTTIME_ITEM_ID ); + if( starttime_str==NULL ) { + return 0; + } + + unsigned long long starttime = strtoull( starttime_str, NULL, 10 ); + if( starttime==ULLONG_MAX ) { + return 0; + } + + return starttime; +} + +char* get_shared_name(const char* prefix, int pid, unsigned long long time) { + const char* name_template = "%s_%d_%llu"; + const int digits_in_int = 10; + const int digits_in_long = 20; + + int len = strlen( name_template ) + strlen( prefix ) + digits_in_int + digits_in_long + 1; + char* name = new char[len]; + sprintf( name, name_template, prefix, pid, time ); + + return name; +} + +char* get_shared_name(const char* prefix) { + int pid = getpgrp(); + unsigned long long time = get_start_time( pid ); + return get_shared_name( prefix, pid, time ); +} + +int get_num_threads(const char* env_var) { + if( env_var==NULL ) { + return 0; + } + + char* value = getenv( env_var ); + if( value==NULL ) { + return 0; + } + + int num_threads = (int)strtol( value, NULL, 10 ); + return num_threads; +} + +bool get_enable_flag(const char* env_var) { + if( env_var==NULL ) { + return false; + } + + char* value = getenv( env_var ); + if( value==NULL ) { + return false; + } + + if( strcmp( value, "0" ) == 0 || + strcmp( value, "false" ) == 0 || + strcmp( value, "False" ) == 0 || + strcmp( value, "FALSE" ) == 0 ) { + return false; + } + + return true; +} + +}}} //tbb::internal::rml diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_utils.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_utils.h new file mode 100644 index 00000000..171c89bc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/rml/ipc_utils.h @@ -0,0 +1,30 @@ +/* + Copyright (c) 2017-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __IPC_UTILS_H +#define __IPC_UTILS_H + +namespace tbb { +namespace internal { +namespace rml { + +char* get_shared_name(const char* prefix); +int get_num_threads(const char* env_var); +bool get_enable_flag(const char* env_var); + +}}} //tbb::internal::rml + +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/setup.py b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/setup.py new file mode 100644 index 00000000..8e93355c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/setup.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# System imports +from __future__ import print_function +from glob import glob +import platform +import os + +from distutils.core import * +from distutils.command.build import build + +rundir = os.getcwd() +os.chdir(os.path.abspath(os.path.dirname(__file__))) + +if any(i in os.environ for i in ["CC", "CXX"]): + if "CC" not in os.environ: + os.environ['CC'] = os.environ['CXX'] + if "CXX" not in os.environ: + os.environ['CXX'] = os.environ['CC'] + if platform.system() == 'Linux': + os.environ['LDSHARED'] = os.environ['CXX'] + " -shared" + print("Environment specifies CC=%s CXX=%s"%(os.environ['CC'], os.environ['CXX'])) + +intel_compiler = os.getenv('CC', '') in ['icl', 'icpc', 'icc'] +try: + tbb_root = os.environ['TBBROOT'] + print("Using TBBROOT=", tbb_root) +except: + tbb_root = '..' + if not intel_compiler: + print("Warning: TBBROOT env var is not set and Intel's compiler is not used. It might lead\n" + " !!!: to compile/link problems. Source tbbvars.sh/.csh file to set environment") +use_compiler_tbb = intel_compiler and tbb_root == '..' +if use_compiler_tbb: + print("Using Intel TBB from Intel's compiler") +if platform.system() == 'Windows': + if intel_compiler: + os.environ['DISTUTILS_USE_SDK'] = '1' # Enable environment settings in distutils + os.environ['MSSdk'] = '1' + print("Using compiler settings from environment") + tbb_flag = ['/Qtbb'] if use_compiler_tbb else [] + tbb_flag += ['/EHsc'] # for Python 2 + compile_flags = ['/Qstd=c++11'] if intel_compiler else [] +else: + tbb_flag = ['-tbb'] if use_compiler_tbb else [] + compile_flags = ['-std=c++11', '-Wno-unused-variable'] + +_tbb = Extension("tbb._api", ["tbb/api.i"], + include_dirs=[os.path.join(tbb_root, 'include')] if not use_compiler_tbb else [], + swig_opts =['-c++', '-O', '-threads'] + ( # add '-builtin' later + ['-I' + os.path.join(tbb_root, 'include')] if not use_compiler_tbb else []), + extra_compile_args=compile_flags + tbb_flag, + extra_link_args=tbb_flag, + libraries =(['tbb'] if not use_compiler_tbb else []) + + (['irml'] if platform.system() == "Linux" else []), # TODO: why do we need this? + library_dirs=[ rundir, # for custom-builds + os.path.join(tbb_root, 'lib', 'intel64', 'gcc4.8'), # for Linux + os.path.join(tbb_root, 'lib'), # for MacOS + os.path.join(tbb_root, 'lib', 'intel64', 'vc_mt'), # for Windows + ] if not use_compiler_tbb else [], + language ='c++', + ) + + +class TBBBuild(build): + sub_commands = [ # define build order + ('build_ext', build.has_ext_modules), + ('build_py', build.has_pure_modules), + ] + + +setup( name ="TBB", + description ="Python API for Intel TBB", + long_description="Python API to Intel(R) Threading Building Blocks library (Intel(R) TBB) " + "extended with standard Pool implementation and monkey-patching", + url ="https://software.intel.com/en-us/intel-tbb", + author ="Intel Corporation", + author_email="inteltbbdevelopers@intel.com", + license ="Dual license: Apache or Proprietary", + version ="0.1", + classifiers =[ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'Intended Audience :: Other Audience', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'Programming Language :: C++', + 'Topic :: System :: Hardware :: Symmetric Multi-processing', + 'Topic :: Software Development :: Libraries', + ], + keywords='TBB multiprocessing multithreading composable parallelism', + ext_modules=[_tbb], + packages=['tbb'], + py_modules=['TBB'], + cmdclass={'build': TBBBuild} +) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__init__.py b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__init__.py new file mode 100644 index 00000000..508ad1ef --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__init__.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from __future__ import print_function + +import multiprocessing.pool +import ctypes +import atexit +import sys +import os + +from .api import * +from .api import __all__ as api__all +from .pool import * +from .pool import __all__ as pool__all + +__all__ = ["Monkey", "is_active"] + api__all + pool__all + +__doc__ = """ +Python API for Intel(R) Threading Building Blocks (Intel(R) TBB) +extended with standard Python's pools implementation and monkey-patching. + +Command-line interface example: +$ python -m tbb $your_script.py +Runs your_script.py in context of tbb.Monkey +""" + +is_active = False +""" Indicates whether TBB context is activated """ + +ipc_enabled = False +""" Indicates whether IPC mode is enabled """ + +libirml = "libirml.so.1" + + +def _test(arg=None): + """Some tests""" + import platform + if platform.system() == "Linux": + ctypes.CDLL(libirml) + assert 256 == os.system("ldd "+_api.__file__+"| grep -E 'libimf|libsvml|libintlc'") + from .test import test + test(arg) + print("done") + + +def tbb_process_pool_worker27(inqueue, outqueue, initializer=None, initargs=(), + maxtasks=None): + from multiprocessing.pool import worker + worker(inqueue, outqueue, initializer, initargs, maxtasks) + if ipc_enabled: + try: + librml = ctypes.CDLL(libirml) + librml.release_resources() + except: + print("Warning: Can not load ", libirml, file=sys.stderr) + + +class TBBProcessPool27(multiprocessing.pool.Pool): + def _repopulate_pool(self): + """Bring the number of pool processes up to the specified number, + for use after reaping workers which have exited. + """ + from multiprocessing.util import debug + + for i in range(self._processes - len(self._pool)): + w = self.Process(target=tbb_process_pool_worker27, + args=(self._inqueue, self._outqueue, + self._initializer, + self._initargs, self._maxtasksperchild) + ) + self._pool.append(w) + w.name = w.name.replace('Process', 'PoolWorker') + w.daemon = True + w.start() + debug('added worker') + + def __del__(self): + self.close() + for p in self._pool: + p.join() + + def __exit__(self, *args): + self.close() + for p in self._pool: + p.join() + + +def tbb_process_pool_worker3(inqueue, outqueue, initializer=None, initargs=(), + maxtasks=None, wrap_exception=False): + from multiprocessing.pool import worker + worker(inqueue, outqueue, initializer, initargs, maxtasks, wrap_exception) + if ipc_enabled: + try: + librml = ctypes.CDLL(libirml) + librml.release_resources() + except: + print("Warning: Can not load ", libirml, file=sys.stderr) + + +class TBBProcessPool3(multiprocessing.pool.Pool): + def _repopulate_pool(self): + """Bring the number of pool processes up to the specified number, + for use after reaping workers which have exited. + """ + from multiprocessing.util import debug + + for i in range(self._processes - len(self._pool)): + w = self.Process(target=tbb_process_pool_worker3, + args=(self._inqueue, self._outqueue, + self._initializer, + self._initargs, self._maxtasksperchild, + self._wrap_exception) + ) + self._pool.append(w) + w.name = w.name.replace('Process', 'PoolWorker') + w.daemon = True + w.start() + debug('added worker') + + def __del__(self): + self.close() + for p in self._pool: + p.join() + + def __exit__(self, *args): + self.close() + for p in self._pool: + p.join() + + +class Monkey: + """ + Context manager which replaces standard multiprocessing.pool + implementations with tbb.pool using monkey-patching. It also enables TBB + threading for Intel(R) Math Kernel Library (Intel(R) MKL). For example: + + with tbb.Monkey(): + run_my_numpy_code() + + It allows multiple parallel tasks to be executed on the same thread pool + and coordinate number of threads across multiple processes thus avoiding + overheads from oversubscription. + """ + _items = {} + _modules = {} + + def __init__(self, max_num_threads=None, benchmark=False): + """ + Create context manager for running under TBB scheduler. + :param max_num_threads: if specified, limits maximal number of threads + :param benchmark: if specified, blocks in initialization until requested number of threads are ready + """ + if max_num_threads: + self.ctl = global_control(global_control.max_allowed_parallelism, int(max_num_threads)) + if benchmark: + if not max_num_threads: + max_num_threads = default_num_threads() + from .api import _concurrency_barrier + _concurrency_barrier(int(max_num_threads)) + + def _patch(self, class_name, module_name, obj): + m = self._modules[class_name] = __import__(module_name, globals(), + locals(), [class_name]) + if m == None: + return + oldattr = getattr(m, class_name, None) + if oldattr == None: + self._modules[class_name] = None + return + self._items[class_name] = oldattr + setattr(m, class_name, obj) + + def __enter__(self): + global is_active + assert is_active == False, "tbb.Monkey does not support nesting yet" + is_active = True + self.env_mkl = os.getenv('MKL_THREADING_LAYER') + os.environ['MKL_THREADING_LAYER'] = 'TBB' + self.env_numba = os.getenv('NUMBA_THREADING_LAYER') + os.environ['NUMBA_THREADING_LAYER'] = 'TBB' + + if ipc_enabled: + if sys.version_info.major == 2 and sys.version_info.minor >= 7: + self._patch("Pool", "multiprocessing.pool", TBBProcessPool27) + elif sys.version_info.major == 3 and sys.version_info.minor >= 5: + self._patch("Pool", "multiprocessing.pool", TBBProcessPool3) + self._patch("ThreadPool", "multiprocessing.pool", Pool) + return self + + def __exit__(self, exc_type, exc_value, traceback): + global is_active + assert is_active == True, "modified?" + is_active = False + if self.env_mkl is None: + del os.environ['MKL_THREADING_LAYER'] + else: + os.environ['MKL_THREADING_LAYER'] = self.env_mkl + if self.env_numba is None: + del os.environ['NUMBA_THREADING_LAYER'] + else: + os.environ['NUMBA_THREADING_LAYER'] = self.env_numba + for name in self._items.keys(): + setattr(self._modules[name], name, self._items[name]) + + +def init_sem_name(): + try: + librml = ctypes.CDLL(libirml) + librml.set_active_sem_name() + librml.set_stop_sem_name() + except Exception as e: + print("Warning: Can not initialize name of shared semaphores:", e, + file=sys.stderr) + + +def tbb_atexit(): + if ipc_enabled: + try: + librml = ctypes.CDLL(libirml) + librml.release_semaphores() + except: + print("Warning: Can not release shared semaphores", + file=sys.stderr) + + +def _main(): + # Run the module specified as the next command line argument + # python -m TBB user_app.py + global ipc_enabled + + import platform + import argparse + parser = argparse.ArgumentParser(prog="python -m tbb", description=""" + Run your Python script in context of tbb.Monkey, which + replaces standard Python pools and threading layer of + Intel(R) Math Kernel Library by implementation based on + Intel(R) Threading Building Blocks. It enables multiple parallel + tasks to be executed on the same thread pool and coordinate + number of threads across multiple processes thus avoiding + overheads from oversubscription. + """, formatter_class=argparse.ArgumentDefaultsHelpFormatter) + if platform.system() == "Linux": + parser.add_argument('--ipc', action='store_true', + help="Enable inter-process (IPC) coordination between Intel TBB schedulers") + parser.add_argument('-a', '--allocator', action='store_true', + help="Enable Intel TBB scalable allocator as a replacement for standard memory allocator") + parser.add_argument('--allocator-huge-pages', action='store_true', + help="Enable huge pages for Intel TBB allocator (implies: -a)") + parser.add_argument('-p', '--max-num-threads', default=default_num_threads(), type=int, + help="Initialize Intel TBB with P max number of threads per process", metavar='P') + parser.add_argument('-b', '--benchmark', action='store_true', + help="Block Intel TBB initialization until all the threads are created before continue the script. " + "This is necessary for performance benchmarks that want to exclude lazy scheduler initialization effects from the measurements") + parser.add_argument('-v', '--verbose', action='store_true', + help="Request verbose and version information") + parser.add_argument('-m', action='store_true', dest='module', + help="Executes following as a module") + parser.add_argument('name', help="Script or module name") + parser.add_argument('args', nargs=argparse.REMAINDER, + help="Command line arguments") + args = parser.parse_args() + + if args.verbose: + os.environ["TBB_VERSION"] = "1" + if platform.system() == "Linux": + if args.allocator_huge_pages: + args.allocator = True + if args.allocator and not os.environ.get("_TBB_MALLOC_PRELOAD"): + libtbbmalloc_lib = 'libtbbmalloc_proxy.so.2' + ld_preload = 'LD_PRELOAD' + os.environ["_TBB_MALLOC_PRELOAD"] = "1" + preload_list = filter(None, os.environ.get(ld_preload, "").split(':')) + if libtbbmalloc_lib in preload_list: + print('Info:', ld_preload, "contains", libtbbmalloc_lib, "already\n") + else: + os.environ[ld_preload] = ':'.join([libtbbmalloc_lib] + list(preload_list)) + + if args.allocator_huge_pages: + assert platform.system() == "Linux" + try: + with open('/proc/sys/vm/nr_hugepages', 'r') as f: + pages = int(f.read()) + if pages == 0: + print("TBB: Pre-allocated huge pages are not currently reserved in the system. To reserve, run e.g.:\n" + "\tsudo sh -c 'echo 2000 > /proc/sys/vm/nr_hugepages'") + os.environ["TBB_MALLOC_USE_HUGE_PAGES"] = "1" + except: + print("TBB: Failed to read number of pages from /proc/sys/vm/nr_hugepages\n" + "\tIs the Linux kernel configured with the huge pages feature?") + sys.exit(1) + + os.execl(sys.executable, sys.executable, '-m', 'tbb', *sys.argv[1:]) + assert False, "Re-execution failed" + + sys.argv = [args.name] + args.args + ipc_enabled = platform.system() == "Linux" and args.ipc + os.environ["IPC_ENABLE"] = "1" if ipc_enabled else "0" + if ipc_enabled: + atexit.register(tbb_atexit) + init_sem_name() + if not os.environ.get("KMP_BLOCKTIME"): # TODO move + os.environ["KMP_BLOCKTIME"] = "0" + if '_' + args.name in globals(): + return globals()['_' + args.name](*args.args) + else: + import runpy + runf = runpy.run_module if args.module else runpy.run_path + with Monkey(max_num_threads=args.max_num_threads, benchmark=args.benchmark): + runf(args.name, run_name='__main__') diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__main__.py b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__main__.py new file mode 100644 index 00000000..34873625 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/__main__.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from . import _main +from sys import exit +exit(_main()) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/api.i b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/api.i new file mode 100644 index 00000000..7a07eb3c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/api.i @@ -0,0 +1,175 @@ +%pythonbegin %{ +# +# Copyright (c) 2016-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +__all__ = ["task_arena", "task_group", "task_scheduler_init", "global_control", "default_num_threads"] +%} +%begin %{ +/* Defines Python wrappers for Intel(R) Threading Building Blocks (Intel TBB).*/ +%} +%module api + +#if SWIG_VERSION < 0x030001 +#error SWIG version 3.0.6 or newer is required for correct functioning +#endif + +%{ +#define TBB_PREVIEW_WAITING_FOR_WORKERS 1 +#include +#include +#if TBB_IMPLEMENT_CPP0X +namespace std { using tbb::mutex; } +#define unique_ptr auto_ptr +#else +#include +#include +#include +#endif +using namespace tbb; + +class PyCaller : public swig::SwigPtr_PyObject { +public: + // icpc 2013 does not support simple using SwigPtr_PyObject::SwigPtr_PyObject; + PyCaller(const PyCaller& s) : SwigPtr_PyObject(s) {} + PyCaller(PyObject *p, bool initial = true) : SwigPtr_PyObject(p, initial) {} + + void operator()() const { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyObject* r = PyObject_CallFunctionObjArgs((PyObject*)*this, NULL); + if(r) Py_DECREF(r); + SWIG_PYTHON_THREAD_END_BLOCK; + } +}; + +struct ArenaPyCaller { + task_arena *my_arena; + PyObject *my_callable; + ArenaPyCaller(task_arena *a, PyObject *c) : my_arena(a), my_callable(c) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + Py_XINCREF(c); + SWIG_PYTHON_THREAD_END_BLOCK; + } + void operator()() const { + my_arena->execute(PyCaller(my_callable, false)); + } +}; + +struct barrier_data { + std::condition_variable event; + std::mutex m; + int worker_threads, full_threads; +}; + +class barrier_task : public tbb::task { + barrier_data &b; +public: + barrier_task(barrier_data &d) : b(d) {} + /*override*/ tbb::task *execute() { + std::unique_lock lock(b.m); + if(++b.worker_threads >= b.full_threads) + b.event.notify_all(); + else while(b.worker_threads < b.full_threads) + b.event.wait(lock); + return NULL; + } +}; + +void _concurrency_barrier(int threads = tbb::task_scheduler_init::automatic) { + if(threads == task_scheduler_init::automatic) + threads = task_scheduler_init::default_num_threads(); + if(threads < 2) + return; + std::unique_ptr g( + (global_control::active_value(global_control::max_allowed_parallelism) < unsigned(threads))? + new global_control(global_control::max_allowed_parallelism, threads) : NULL); + barrier_data b; + b.worker_threads = 0; + b.full_threads = threads-1; + for(int i = 0; i < b.full_threads; i++) + tbb::task::enqueue( *new( tbb::task::allocate_root() ) barrier_task(b) ); + std::unique_lock lock(b.m); + b.event.wait(lock); +}; + +%} + +void _concurrency_barrier(int threads = tbb::task_scheduler_init::automatic); + +namespace tbb { + class task_scheduler_init { + public: + //! Typedef for number of threads that is automatic. + static const int automatic = -1; + //! Argument to initialize() or constructor that causes initialization to be deferred. + static const int deferred = -2; + task_scheduler_init( int max_threads=automatic, + size_t thread_stack_size=0 ); + ~task_scheduler_init(); + void initialize( int max_threads=automatic ); + void terminate(); + static int default_num_threads(); + bool is_active() const; + void blocking_terminate(); + }; + + class task_arena { + public: + static const int automatic = -1; + static int current_thread_index(); + task_arena(int max_concurrency = automatic, unsigned reserved_for_masters = 1); + task_arena(const task_arena &s); + ~task_arena(); + void initialize(); + void initialize(int max_concurrency, unsigned reserved_for_masters = 1); + void terminate(); + bool is_active(); + %extend { + void enqueue( PyObject *c ) { $self->enqueue(PyCaller(c)); } + void execute( PyObject *c ) { $self->execute(PyCaller(c)); } + }; + }; + + class task_group { + public: + task_group(); + ~task_group(); + void wait(); + bool is_canceling(); + void cancel(); + %extend { + void run( PyObject *c ) { $self->run(PyCaller(c)); } + void run( PyObject *c, task_arena *a ) { $self->run(ArenaPyCaller(a, c)); } + }; + }; + + class global_control { + public: + enum parameter { + max_allowed_parallelism, + thread_stack_size, + parameter_max // insert new parameters above this point + }; + global_control(parameter param, size_t value); + ~global_control(); + static size_t active_value(parameter param); + }; + +} // tbb + +// Additional definitions for Python part of the module +%pythoncode %{ +default_num_threads = task_scheduler_init_default_num_threads +%} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/pool.py b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/pool.py new file mode 100644 index 00000000..56b6c319 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/pool.py @@ -0,0 +1,631 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Based on the software developed by: +# Copyright (c) 2008,2016 david decotigny (Pool of threads) +# Copyright (c) 2006-2008, R Oudkerk (multiprocessing.Pool) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of author nor the names of any contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# @brief Python Pool implementation based on TBB with monkey-patching +# +# See http://docs.python.org/dev/library/multiprocessing.html +# Differences: added imap_async and imap_unordered_async, and terminate() +# has to be called explicitly (it's not registered by atexit). +# +# The general idea is that we submit works to a workqueue, either as +# single Jobs (one function to call), or JobSequences (batch of +# Jobs). Each Job is associated with an ApplyResult object which has 2 +# states: waiting for the Job to complete, or Ready. Instead of +# waiting for the jobs to finish, we wait for their ApplyResult object +# to become ready: an event mechanism is used for that. +# When we apply a function to several arguments in "parallel", we need +# a way to wait for all/part of the Jobs to be processed: that's what +# "collectors" are for; they group and wait for a set of ApplyResult +# objects. Once a collector is ready to be used, we can use a +# CollectorIterator to iterate over the result values it's collecting. +# +# The methods of a Pool object use all these concepts and expose +# them to their caller in a very simple way. + +import sys +import threading +import traceback +from .api import * + +__all__ = ["Pool", "TimeoutError"] +__doc__ = """ +Standard Python Pool implementation based on Python API +for Intel(R) Threading Building Blocks library (Intel(R) TBB) +""" + + +class TimeoutError(Exception): + """Raised when a result is not available within the given timeout""" + pass + + +class Pool(object): + """ + The Pool class provides standard multiprocessing.Pool interface + which is mapped onto Intel(R) TBB tasks executing in its thread pool + """ + + def __init__(self, nworkers=0, name="Pool"): + """ + \param nworkers (integer) number of worker threads to start + \param name (string) prefix for the worker threads' name + """ + self._closed = False + self._tasks = task_group() + self._pool = [None,]*default_num_threads() # Dask asks for len(_pool) + + def apply(self, func, args=(), kwds=dict()): + """Equivalent of the apply() builtin function. It blocks till + the result is ready.""" + return self.apply_async(func, args, kwds).get() + + def map(self, func, iterable, chunksize=None): + """A parallel equivalent of the map() builtin function. It + blocks till the result is ready. + + This method chops the iterable into a number of chunks which + it submits to the process pool as separate tasks. The + (approximate) size of these chunks can be specified by setting + chunksize to a positive integer.""" + return self.map_async(func, iterable, chunksize).get() + + def imap(self, func, iterable, chunksize=1): + """ + An equivalent of itertools.imap(). + + The chunksize argument is the same as the one used by the + map() method. For very long iterables using a large value for + chunksize can make the job complete much faster than + using the default value of 1. + + Also if chunksize is 1 then the next() method of the iterator + returned by the imap() method has an optional timeout + parameter: next(timeout) will raise processing.TimeoutError if + the result cannot be returned within timeout seconds. + """ + collector = OrderedResultCollector(as_iterator=True) + self._create_sequences(func, iterable, chunksize, collector) + return iter(collector) + + def imap_unordered(self, func, iterable, chunksize=1): + """The same as imap() except that the ordering of the results + from the returned iterator should be considered + arbitrary. (Only when there is only one worker process is the + order guaranteed to be "correct".)""" + collector = UnorderedResultCollector() + self._create_sequences(func, iterable, chunksize, collector) + return iter(collector) + + def apply_async(self, func, args=(), kwds=dict(), callback=None): + """A variant of the apply() method which returns an + ApplyResult object. + + If callback is specified then it should be a callable which + accepts a single argument. When the result becomes ready, + callback is applied to it (unless the call failed). callback + should complete immediately since otherwise the thread which + handles the results will get blocked.""" + assert not self._closed # No lock here. We assume it's atomic... + apply_result = ApplyResult(callback=callback) + job = Job(func, args, kwds, apply_result) + self._tasks.run(job) + return apply_result + + def map_async(self, func, iterable, chunksize=None, callback=None): + """A variant of the map() method which returns a ApplyResult + object. + + If callback is specified then it should be a callable which + accepts a single argument. When the result becomes ready + callback is applied to it (unless the call failed). callback + should complete immediately since otherwise the thread which + handles the results will get blocked.""" + apply_result = ApplyResult(callback=callback) + collector = OrderedResultCollector(apply_result, as_iterator=False) + if not self._create_sequences(func, iterable, chunksize, collector): + apply_result._set_value([]) + return apply_result + + def imap_async(self, func, iterable, chunksize=None, callback=None): + """A variant of the imap() method which returns an ApplyResult + object that provides an iterator (next method(timeout) + available). + + If callback is specified then it should be a callable which + accepts a single argument. When the resulting iterator becomes + ready, callback is applied to it (unless the call + failed). callback should complete immediately since otherwise + the thread which handles the results will get blocked.""" + apply_result = ApplyResult(callback=callback) + collector = OrderedResultCollector(apply_result, as_iterator=True) + if not self._create_sequences(func, iterable, chunksize, collector): + apply_result._set_value(iter([])) + return apply_result + + def imap_unordered_async(self, func, iterable, chunksize=None, + callback=None): + """A variant of the imap_unordered() method which returns an + ApplyResult object that provides an iterator (next + method(timeout) available). + + If callback is specified then it should be a callable which + accepts a single argument. When the resulting iterator becomes + ready, callback is applied to it (unless the call + failed). callback should complete immediately since otherwise + the thread which handles the results will get blocked.""" + apply_result = ApplyResult(callback=callback) + collector = UnorderedResultCollector(apply_result) + if not self._create_sequences(func, iterable, chunksize, collector): + apply_result._set_value(iter([])) + return apply_result + + def close(self): + """Prevents any more tasks from being submitted to the + pool. Once all the tasks have been completed the worker + processes will exit.""" + # No lock here. We assume it's sufficiently atomic... + self._closed = True + + def terminate(self): + """Stops the worker processes immediately without completing + outstanding work. When the pool object is garbage collected + terminate() will be called immediately.""" + self.close() + self._tasks.cancel() + + def join(self): + """Wait for the worker processes to exit. One must call + close() or terminate() before using join().""" + self._tasks.wait() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.join() + + def __del__(self): + self.terminate() + self.join() + + def _create_sequences(self, func, iterable, chunksize, collector): + """ + Create callable objects to process and pushes them on the + work queue. Each work unit is meant to process a slice of + iterable of size chunksize. If collector is specified, then + the ApplyResult objects associated with the jobs will notify + collector when their result becomes ready. + + \return the list callable objects (basically: JobSequences) + pushed onto the work queue + """ + assert not self._closed # No lock here. We assume it's atomic... + it_ = iter(iterable) + exit_loop = False + sequences = [] + while not exit_loop: + seq = [] + for _ in range(chunksize or 1): + try: + arg = next(it_) + except StopIteration: + exit_loop = True + break + apply_result = ApplyResult(collector) + job = Job(func, (arg,), {}, apply_result) + seq.append(job) + if seq: + sequences.append(JobSequence(seq)) + for t in sequences: + self._tasks.run(t) + return sequences + + +class Job: + """A work unit that corresponds to the execution of a single function""" + + def __init__(self, func, args, kwds, apply_result): + """ + \param func/args/kwds used to call the function + \param apply_result ApplyResult object that holds the result + of the function call + """ + self._func = func + self._args = args + self._kwds = kwds + self._result = apply_result + + def __call__(self): + """ + Call the function with the args/kwds and tell the ApplyResult + that its result is ready. Correctly handles the exceptions + happening during the execution of the function + """ + try: + result = self._func(*self._args, **self._kwds) + except: + self._result._set_exception() + else: + self._result._set_value(result) + + +class JobSequence: + """A work unit that corresponds to the processing of a continuous + sequence of Job objects""" + + def __init__(self, jobs): + self._jobs = jobs + + def __call__(self): + """ + Call all the Job objects that have been specified + """ + for job in self._jobs: + job() + + +class ApplyResult(object): + """An object associated with a Job object that holds its result: + it's available during the whole life the Job and after, even when + the Job didn't process yet. It's possible to use this object to + wait for the result/exception of the job to be available. + + The result objects returns by the Pool::*_async() methods are of + this type""" + + def __init__(self, collector=None, callback=None): + """ + \param collector when not None, the notify_ready() method of + the collector will be called when the result from the Job is + ready + \param callback when not None, function to call when the + result becomes available (this is the parameter passed to the + Pool::*_async() methods. + """ + self._success = False + self._event = threading.Event() + self._data = None + self._collector = None + self._callback = callback + + if collector is not None: + collector.register_result(self) + self._collector = collector + + def get(self, timeout=None): + """ + Returns the result when it arrives. If timeout is not None and + the result does not arrive within timeout seconds then + TimeoutError is raised. If the remote call raised an exception + then that exception will be reraised by get(). + """ + if not self.wait(timeout): + raise TimeoutError("Result not available within %fs" % timeout) + if self._success: + return self._data + if sys.version_info[0] == 3: + raise self._data[0](self._data[1]).with_traceback(self._data[2]) + else: + exec("raise self._data[0], self._data[1], self._data[2]") + + def wait(self, timeout=None): + """Waits until the result is available or until timeout + seconds pass.""" + self._event.wait(timeout) + return self._event.isSet() + + def ready(self): + """Returns whether the call has completed.""" + return self._event.isSet() + + def successful(self): + """Returns whether the call completed without raising an + exception. Will raise AssertionError if the result is not + ready.""" + assert self.ready() + return self._success + + def _set_value(self, value): + """Called by a Job object to tell the result is ready, and + provides the value of this result. The object will become + ready and successful. The collector's notify_ready() method + will be called, and the callback method too""" + assert not self.ready() + self._data = value + self._success = True + self._event.set() + if self._collector is not None: + self._collector.notify_ready(self) + if self._callback is not None: + try: + self._callback(value) + except: + traceback.print_exc() + + def _set_exception(self): + """Called by a Job object to tell that an exception occurred + during the processing of the function. The object will become + ready but not successful. The collector's notify_ready() + method will be called, but NOT the callback method""" + # traceback.print_exc() + assert not self.ready() + self._data = sys.exc_info() + self._success = False + self._event.set() + if self._collector is not None: + self._collector.notify_ready(self) + + +class AbstractResultCollector(object): + """ABC to define the interface of a ResultCollector object. It is + basically an object which knows whuich results it's waiting for, + and which is able to get notify when they get available. It is + also able to provide an iterator over the results when they are + available""" + + def __init__(self, to_notify): + """ + \param to_notify ApplyResult object to notify when all the + results we're waiting for become available. Can be None. + """ + self._to_notify = to_notify + + def register_result(self, apply_result): + """Used to identify which results we're waiting for. Will + always be called BEFORE the Jobs get submitted to the work + queue, and BEFORE the __iter__ and _get_result() methods can + be called + \param apply_result ApplyResult object to add in our collection + """ + raise NotImplementedError("Children classes must implement it") + + def notify_ready(self, apply_result): + """Called by the ApplyResult object (already registered via + register_result()) that it is now ready (ie. the Job's result + is available or an exception has been raised). + \param apply_result ApplyResult object telling us that the job + has been processed + """ + raise NotImplementedError("Children classes must implement it") + + def _get_result(self, idx, timeout=None): + """Called by the CollectorIterator object to retrieve the + result's values one after another (order defined by the + implementation) + \param idx The index of the result we want, wrt collector's order + \param timeout integer telling how long to wait (in seconds) + for the result at index idx to be available, or None (wait + forever) + """ + raise NotImplementedError("Children classes must implement it") + + def __iter__(self): + """Return a new CollectorIterator object for this collector""" + return CollectorIterator(self) + + +class CollectorIterator(object): + """An iterator that allows to iterate over the result values + available in the given collector object. Equipped with an extended + next() method accepting a timeout argument. Created by the + AbstractResultCollector::__iter__() method""" + + def __init__(self, collector): + """\param AbstractResultCollector instance""" + self._collector = collector + self._idx = 0 + + def __iter__(self): + return self + + def next(self, timeout=None): + """Return the next result value in the sequence. Raise + StopIteration at the end. Can raise the exception raised by + the Job""" + try: + apply_result = self._collector._get_result(self._idx, timeout) + except IndexError: + # Reset for next time + self._idx = 0 + raise StopIteration + except: + self._idx = 0 + raise + self._idx += 1 + assert apply_result.ready() + return apply_result.get(0) + + def __next__(self): + return self.next() + + +class UnorderedResultCollector(AbstractResultCollector): + """An AbstractResultCollector implementation that collects the + values of the ApplyResult objects in the order they become ready. The + CollectorIterator object returned by __iter__() will iterate over + them in the order they become ready""" + + def __init__(self, to_notify=None): + """ + \param to_notify ApplyResult object to notify when all the + results we're waiting for become available. Can be None. + """ + AbstractResultCollector.__init__(self, to_notify) + self._cond = threading.Condition() + self._collection = [] + self._expected = 0 + + def register_result(self, apply_result): + """Used to identify which results we're waiting for. Will + always be called BEFORE the Jobs get submitted to the work + queue, and BEFORE the __iter__ and _get_result() methods can + be called + \param apply_result ApplyResult object to add in our collection + """ + self._expected += 1 + + def _get_result(self, idx, timeout=None): + """Called by the CollectorIterator object to retrieve the + result's values one after another, in the order the results have + become available. + \param idx The index of the result we want, wrt collector's order + \param timeout integer telling how long to wait (in seconds) + for the result at index idx to be available, or None (wait + forever) + """ + self._cond.acquire() + try: + if idx >= self._expected: + raise IndexError + elif idx < len(self._collection): + return self._collection[idx] + elif idx != len(self._collection): + # Violation of the sequence protocol + raise IndexError() + else: + self._cond.wait(timeout=timeout) + try: + return self._collection[idx] + except IndexError: + # Still not added ! + raise TimeoutError("Timeout while waiting for results") + finally: + self._cond.release() + + def notify_ready(self, apply_result=None): + """Called by the ApplyResult object (already registered via + register_result()) that it is now ready (ie. the Job's result + is available or an exception has been raised). + \param apply_result ApplyResult object telling us that the job + has been processed + """ + first_item = False + self._cond.acquire() + try: + self._collection.append(apply_result) + first_item = (len(self._collection) == 1) + + self._cond.notifyAll() + finally: + self._cond.release() + + if first_item and self._to_notify is not None: + self._to_notify._set_value(iter(self)) + + +class OrderedResultCollector(AbstractResultCollector): + """An AbstractResultCollector implementation that collects the + values of the ApplyResult objects in the order they have been + submitted. The CollectorIterator object returned by __iter__() + will iterate over them in the order they have been submitted""" + + def __init__(self, to_notify=None, as_iterator=True): + """ + \param to_notify ApplyResult object to notify when all the + results we're waiting for become available. Can be None. + \param as_iterator boolean telling whether the result value + set on to_notify should be an iterator (available as soon as 1 + result arrived) or a list (available only after the last + result arrived) + """ + AbstractResultCollector.__init__(self, to_notify) + self._results = [] + self._lock = threading.Lock() + self._remaining = 0 + self._as_iterator = as_iterator + + def register_result(self, apply_result): + """Used to identify which results we're waiting for. Will + always be called BEFORE the Jobs get submitted to the work + queue, and BEFORE the __iter__ and _get_result() methods can + be called + \param apply_result ApplyResult object to add in our collection + """ + self._results.append(apply_result) + self._remaining += 1 + + def _get_result(self, idx, timeout=None): + """Called by the CollectorIterator object to retrieve the + result's values one after another (order defined by the + implementation) + \param idx The index of the result we want, wrt collector's order + \param timeout integer telling how long to wait (in seconds) + for the result at index idx to be available, or None (wait + forever) + """ + res = self._results[idx] + res.wait(timeout) + return res + + def notify_ready(self, apply_result): + """Called by the ApplyResult object (already registered via + register_result()) that it is now ready (ie. the Job's result + is available or an exception has been raised). + \param apply_result ApplyResult object telling us that the job + has been processed + """ + got_first = False + got_last = False + self._lock.acquire() + try: + assert self._remaining > 0 + got_first = (len(self._results) == self._remaining) + self._remaining -= 1 + got_last = (self._remaining == 0) + finally: + self._lock.release() + + if self._to_notify is not None: + if self._as_iterator and got_first: + self._to_notify._set_value(iter(self)) + elif not self._as_iterator and got_last: + try: + lst = [r.get(0) for r in self._results] + except: + self._to_notify._set_exception() + else: + self._to_notify._set_value(lst) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/test.py b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/test.py new file mode 100644 index 00000000..2f2885ef --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/python/tbb/test.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Based on the software developed by: +# Copyright (c) 2008,2016 david decotigny (Pool of threads) +# Copyright (c) 2006-2008, R Oudkerk (multiprocessing.Pool) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of author nor the names of any contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +from __future__ import print_function +import time +import threading + +from .api import * +from .pool import * + + +def test(arg=None): + if arg == "-v": + def say(*x): + print(*x) + else: + def say(*x): + pass + say("Start Pool testing") + + get_tid = lambda: threading.current_thread().ident + + def return42(): + return 42 + + def f(x): + return x * x + + def work(mseconds): + res = str(mseconds) + if mseconds < 0: + mseconds = -mseconds + say("[%d] Start to work for %fms..." % (get_tid(), mseconds*10)) + time.sleep(mseconds/100.) + say("[%d] Work done (%fms)." % (get_tid(), mseconds*10)) + return res + + ### Test copy/pasted from multiprocessing + pool = Pool(4) # start worker threads + + # edge cases + assert pool.map(return42, []) == [] + assert pool.apply_async(return42, []).get() == 42 + assert pool.apply(return42, []) == 42 + assert list(pool.imap(return42, iter([]))) == [] + assert list(pool.imap_unordered(return42, iter([]))) == [] + assert pool.map_async(return42, []).get() == [] + assert list(pool.imap_async(return42, iter([])).get()) == [] + assert list(pool.imap_unordered_async(return42, iter([])).get()) == [] + + # basic tests + result = pool.apply_async(f, (10,)) # evaluate "f(10)" asynchronously + assert result.get(timeout=1) == 100 # ... unless slow computer + assert list(pool.map(f, range(10))) == list(map(f, range(10))) + it = pool.imap(f, range(10)) + assert next(it) == 0 + assert next(it) == 1 + assert next(it) == 4 + + # Test apply_sync exceptions + result = pool.apply_async(time.sleep, (3,)) + try: + say(result.get(timeout=1)) # raises `TimeoutError` + except TimeoutError: + say("Good. Got expected timeout exception.") + else: + assert False, "Expected exception !" + assert result.get() is None # sleep() returns None + + def cb(s): + say("Result ready: %s" % s) + + # Test imap() + assert list(pool.imap(work, range(10, 3, -1), chunksize=4)) == list(map( + str, range(10, 3, -1))) + + # Test imap_unordered() + assert sorted(pool.imap_unordered(work, range(10, 3, -1))) == sorted(map( + str, range(10, 3, -1))) + + # Test map_async() + result = pool.map_async(work, range(10), callback=cb) + try: + result.get(timeout=0.01) # raises `TimeoutError` + except TimeoutError: + say("Good. Got expected timeout exception.") + else: + assert False, "Expected exception !" + say(result.get()) + + # Test imap_async() + result = pool.imap_async(work, range(3, 10), callback=cb) + try: + result.get(timeout=0.01) # raises `TimeoutError` + except TimeoutError: + say("Good. Got expected timeout exception.") + else: + assert False, "Expected exception !" + for i in result.get(): + say("Item:", i) + say("### Loop again:") + for i in result.get(): + say("Item2:", i) + + # Test imap_unordered_async() + result = pool.imap_unordered_async(work, range(10, 3, -1), callback=cb) + try: + say(result.get(timeout=0.01)) # raises `TimeoutError` + except TimeoutError: + say("Good. Got expected timeout exception.") + else: + assert False, "Expected exception !" + for i in result.get(): + say("Item1:", i) + for i in result.get(): + say("Item2:", i) + r = result.get() + for i in r: + say("Item3:", i) + for i in r: + say("Item4:", i) + for i in r: + say("Item5:", i) + + # + # The case for the exceptions + # + + # Exceptions in imap_unordered_async() + result = pool.imap_unordered_async(work, range(2, -10, -1), callback=cb) + time.sleep(3) + try: + for i in result.get(): + say("Got item:", i) + except (IOError, ValueError): + say("Good. Got expected exception") + + # Exceptions in imap_async() + result = pool.imap_async(work, range(2, -10, -1), callback=cb) + time.sleep(3) + try: + for i in result.get(): + say("Got item:", i) + except (IOError, ValueError): + say("Good. Got expected exception") + + # Stop the test: need to stop the pool !!! + pool.terminate() + pool.join() + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/Makefile b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/Makefile new file mode 100644 index 00000000..57234fe7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/Makefile @@ -0,0 +1,276 @@ +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +tbb_root?=.. +examples_root:=$(tbb_root)/examples +include $(tbb_root)/build/common.inc + +#workaround for non-depend targets tbb and tbbmalloc which both depend on version_string.ver +#According to documentation, recursively invoked make commands can process their targets in parallel +.NOTPARALLEL: + +.PHONY: all tbb tbbmalloc tbbbind tbbproxy test test_no_depends release debug examples clean mkdir + +all: release examples + +tbb: tbb_release tbb_debug + +tbbmalloc: tbbmalloc_release tbbmalloc_debug + +tbbbind: tbbbind_release + +tbbproxy: tbbproxy_release + +rml: rml_release + +test: tbbmalloc_test_release $(if $(use_proxy),tbbproxy_test_release) tbb_test_release tbbmalloc_test_debug $(if $(use_proxy),tbbproxy_test_debug) tbb_test_debug +ifeq (,$(findstring skip,$(target:android=skip) $(offload:mic=skip))) +test: rml_test_debug rml_test_release +endif + +test_no_depends: tbbmalloc_test_release_no_depends $(if $(use_proxy),tbbproxy_test_release_no_depends) tbb_test_release_no_depends tbbmalloc_test_debug_no_depends $(if $(use_proxy),tbbproxy_test_debug_no_depends) tbb_test_debug_no_depends + @echo done + +release: tbb_release tbbmalloc_release $(if $(use_proxy),tbbproxy_release) +release: $(call cross_cfg,tbbmalloc_test_release) $(call cross_cfg,test_release) + +debug: tbb_debug tbbmalloc_debug $(if $(use_proxy),tbbproxy_debug) +debug: $(call cross_cfg,tbbmalloc_test_debug) $(call cross_cfg, test_debug) + +examples: tbb tbbmalloc examples_debug clean_examples examples_release + +examples_no_depends: examples_release_no_depends examples_debug_no_depends + +clean: clean_release clean_debug clean_examples + @echo clean done + +mkdir: mkdir_debug mkdir_release + +.PHONY: full +full: + $(MAKE) -sir --no-print-directory -f Makefile tbb_root=.. clean all +ifeq ($(tbb_os),windows) + $(MAKE) -sir --no-print-directory -f Makefile tbb_root=.. compiler=icl clean all native_examples +else + $(MAKE) -sir --no-print-directory -f Makefile tbb_root=.. compiler=icc clean all native_examples +endif +ifeq ($(arch),intel64) + $(MAKE) -sir --no-print-directory -f Makefile tbb_root=.. arch=ia32 clean all +endif +# it doesn't test compiler=icc arch=ia32 on intel64 systems due to environment settings of icc + +native_examples: tbb tbbmalloc + $(MAKE) -C $(examples_root) -r -f Makefile tbb_root=.. compiler=$(native_compiler) debug test + $(MAKE) -C $(examples_root) -r -f Makefile tbb_root=.. compiler=$(native_compiler) clean release test + +../examples/% examples/%:: + $(MAKE) -C $(examples_root) -r -f Makefile tbb_root=.. $(subst examples/,,$(subst ../,,$@)) + +debug_%:: cfg:=$(if $(findstring file,$(origin cfg)),debug,$(cfg)) +debug_%:: export run_cmd=$(debugger) +debug_malloc_% test_malloc_% debug_ScalableAlloc% test_ScalableAlloc%:: TESTFILE=tbbmalloc +debug_rml_% test_rml_%:: TESTFILE=rml +debug_runtime_load% test_runtime_load%:: TESTFILE=tbbproxy +debug_% test_% stress_% time_% perf_%:: TESTFILE?=test +debug_% test_% stress_% time_% perf_%:: + $(MAKE) -C "$(work_dir)_$(cfg)" -r -f $(tbb_root)/build/Makefile.$(TESTFILE) cfg=$(cfg) $(subst .cpp,,$@) + +clean_%:: +ifeq ($(origin cfg),file) + @$(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.test cfg=release $@ + @$(MAKE) -C "$(work_dir)_debug" -r -f $(tbb_root)/build/Makefile.test cfg=debug $@ +else + @$(MAKE) -C "$(work_dir)_$(cfg)" -r -f $(tbb_root)/build/Makefile.test $@ +endif + +python_%: mkdir_release + $(MAKE) -C "$(work_dir)_release" -rf $(tbb_root)/python/Makefile $(subst python_,,$@) + +.PHONY: test_release test_debug test_release_no_depends test_debug_no_depends +.PHONY: tbb_release tbb_debug tbb_test_release tbb_test_debug tbb_test_release_no_depends tbb_test_debug_no_depends +.PHONY: tbbbind_release tbbbind_debug +# do not delete double-space after -C option +tbb_release: mkdir_release + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbb cfg=release + +tbb_debug: mkdir_debug + $(MAKE) -C "$(work_dir)_debug" -r -f $(tbb_root)/build/Makefile.tbb cfg=debug + +tbb_test: tbb_test_release tbb_test_debug + +tbb_test_release: $(call cross_cfg,tbb_release) $(if $(use_proxy),$(call cross_cfg,tbbproxy_release)) tbb_test_release_no_depends +tbb_test_release_no_depends:$(call cross_cfg,mkdir_release) + $(MAKE) -C "$(call cross_cfg,$(work_dir)_release)" -r -f $(tbb_root)/build/Makefile.test cfg=release + +tbb_test_debug: $(call cross_cfg,tbb_debug) $(if $(use_proxy),$(call cross_cfg,tbbproxy_debug)) tbb_test_debug_no_depends +tbb_test_debug_no_depends:$(call cross_cfg,mkdir_debug) + $(MAKE) -C "$(call cross_cfg,$(work_dir)_debug)" -r -f $(tbb_root)/build/Makefile.test cfg=debug +# backward compatibility +test_release: tbb_test_release +test_debug: tbb_test_debug +test_release_no_depends: tbb_test_release_no_depends +test_debug_no_depends: tbb_test_debug_no_depends + +tbbbind_release: mkdir_release + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbbind cfg=release tbbbind + +tbbbind_debug: mkdir_debug + $(MAKE) -C "$(work_dir)_debug" -r -f $(tbb_root)/build/Makefile.tbbbind cfg=debug tbbbind + +.PHONY: tbbmalloc_release tbbmalloc_debug +.PHONY: tbbmalloc_dll_release tbbmalloc_dll_debug tbbmalloc_proxy_dll_release tbbmalloc_proxy_dll_debug +.PHONY: tbbmalloc_test tbbmalloc_test_release tbbmalloc_test_debug tbbmalloc_test_release_no_depends tbbmalloc_test_debug_no_depends + +tbbmalloc_release: mkdir_release + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=release malloc + +tbbmalloc_debug: mkdir_debug + $(MAKE) -C "$(work_dir)_debug" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=debug malloc + +tbbmalloc_dll_release: mkdir_release + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=release malloc_dll + +tbbmalloc_proxy_dll_release: mkdir_release + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=release malloc_proxy_dll + +tbbmalloc_dll_debug: mkdir_debug + $(MAKE) -C "$(work_dir)_debug" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=debug malloc_dll + +tbbmalloc_proxy_dll_debug: mkdir_debug + $(MAKE) -C "$(work_dir)_debug" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=debug malloc_proxy_dll + +tbbmalloc_test: tbbmalloc_test_release tbbmalloc_test_debug + +tbbmalloc_test_release: $(call cross_cfg,tbbmalloc_release) tbbmalloc_test_release_no_depends +tbbmalloc_test_release_no_depends: $(call cross_cfg,mkdir_release) + $(MAKE) -C "$(call cross_cfg,$(work_dir)_release)" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=release malloc_test_no_depends + +tbbmalloc_test_debug: $(call cross_cfg,tbbmalloc_debug) tbbmalloc_test_debug_no_depends +tbbmalloc_test_debug_no_depends: $(call cross_cfg,mkdir_debug) + $(MAKE) -C "$(call cross_cfg,$(work_dir)_debug)" -r -f $(tbb_root)/build/Makefile.tbbmalloc cfg=debug malloc_test_no_depends + +.PHONY: tbbproxy_release tbbproxy_debug +.PHONY: tbbproxy_test tbbproxy_test_release tbbproxy_test_debug tbbproxy_test_release_no_depends tbbproxy_test_debug_no_depends + +tbbproxy_release: mkdir_release tbb_release + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.tbbproxy cfg=release tbbproxy + +tbbproxy_debug: mkdir_debug tbb_debug + $(MAKE) -C "$(work_dir)_debug" -r -f $(tbb_root)/build/Makefile.tbbproxy cfg=debug tbbproxy + +tbbproxy_test: tbbproxy_test_release tbbproxy_test_debug + +tbbproxy_test_release: $(call cross_cfg,tbb_release) $(call cross_cfg,tbbproxy_release) tbbproxy_test_release_no_depends +tbbproxy_test_release_no_depends:$(call cross_cfg,mkdir_release) + $(MAKE) -C "$(call cross_cfg,$(work_dir)_release)" -r -f $(tbb_root)/build/Makefile.tbbproxy cfg=release tbbproxy_test + +tbbproxy_test_debug: $(call cross_cfg,tbb_debug) $(call cross_cfg,tbbproxy_debug) tbbproxy_test_debug_no_depends +tbbproxy_test_debug_no_depends: $(call cross_cfg,mkdir_debug) + $(MAKE) -C "$(call cross_cfg,$(work_dir)_debug)" -r -f $(tbb_root)/build/Makefile.tbbproxy cfg=debug tbbproxy_test + +.PHONY: rml_release rml_debug rml_test_release rml_test_debug +.PHONY: rml_test_release_no_depends rml_test_debug_no_depends + +rml_release: mkdir_release + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.rml cfg=release rml + +rml_debug: mkdir_debug + $(MAKE) -C "$(work_dir)_debug" -r -f $(tbb_root)/build/Makefile.rml cfg=debug rml + +rml_test: rml_test_release rml_test_debug + +rml_test_release: $(call cross_cfg,rml_release) rml_test_release_no_depends +rml_test_release_no_depends: $(call cross_cfg,mkdir_release) + $(MAKE) -C "$(call cross_cfg,$(work_dir)_release)" -r -f $(tbb_root)/build/Makefile.rml cfg=release rml_test + +rml_test_debug: $(call cross_cfg,rml_debug) rml_test_debug_no_depends +rml_test_debug_no_depends: $(call cross_cfg,mkdir_debug) + $(MAKE) -C "$(call cross_cfg,$(work_dir)_debug)" -r -f $(tbb_root)/build/Makefile.rml cfg=debug rml_test + +.PHONY: examples_release examples_debug examples_release_no_depends examples_debug_no_depends + +examples_release: tbb_release tbbmalloc_release examples_release_no_depends +examples_release_no_depends: + $(MAKE) -C $(examples_root) -r -f Makefile tbb_root=.. release test UI=con + +examples_debug: tbb_debug tbbmalloc_debug examples_debug_no_depends +examples_debug_no_depends: + $(MAKE) -C $(examples_root) -r -f Makefile tbb_root=.. debug test UI=con + +.PHONY: clean_release clean_debug clean_examples + +clean_release: + $(shell $(RM) $(work_dir)_release$(SLASH)*.* >$(NUL) 2>$(NUL)) + $(shell $(RD) $(work_dir)_release >$(NUL) 2>$(NUL)) + +clean_debug: + $(shell $(RM) $(work_dir)_debug$(SLASH)*.* >$(NUL) 2>$(NUL)) + $(shell $(RD) $(work_dir)_debug >$(NUL) 2>$(NUL)) + +clean_examples: + $(shell $(MAKE) -s -i -r -C $(examples_root) -f Makefile tbb_root=.. clean >$(NUL) 2>$(NUL)) + +.PHONY: mkdir_release mkdir_debug codecov do_codecov info tbbvars shell + +mkdir_release: + $(shell $(MD) "$(work_dir)_release" >$(NUL) 2>$(NUL)) + @echo Created $(work_dir)_release directory + +mkdir_debug: + $(shell $(MD) "$(work_dir)_debug" >$(NUL) 2>$(NUL)) + @echo Created $(work_dir)_debug directory + +ifeq ($(compiler),$(if $(findstring windows,$(tbb_os)),icl,icc)) +codecov: codecov=yes +codecov: do_codecov + $(MAKE) -C "$(work_dir)_release" -r -f $(tbb_root)/build/Makefile.test cfg=release codecov_gen +else +codecov: + $(error Only Intel(R) C++ Compiler is supported for code coverage) +endif + +export codecov + +do_codecov: tbb_root=.. +do_codecov: + $(MAKE) RML=yes tbbmalloc_test_release test_release + $(MAKE) clean_test_* cfg=release + $(MAKE) RML=yes crosstest=yes tbbmalloc_test_debug test_debug + $(MAKE) clean_test_* cfg=release + $(MAKE) rml_test_release + $(MAKE) clean_test_* cfg=release + $(MAKE) crosstest=yes rml_test_debug + +info: + @echo OS: $(tbb_os) + @echo arch=$(arch) + @echo compiler=$(compiler) + @echo runtime=$(runtime) + @echo tbb_build_prefix=$(tbb_build_prefix) + @echo work_dir=$(abspath $(tbb_build_dir)$(SLASH)$(tbb_build_prefix)_$(cfg)) + +# [usage]$ source `make tbbvars`.sh +tbbvars: + @echo $(tbb_build_dir)$(SLASH)$(tbb_build_prefix)_$(cfg)$(SLASH)tbbvars + +symbols: args=$(if $(findstring cl,$(compiler)), dumpbin /section:.text *.obj|findstr COMDAT , nm -Pg *.o|grep ' T '|cut -f1 -d' ') +symbols: shell + +shell: +ifdef BUILDING_PHASE + -$(run_cmd) $(shell_cmd) +else + @$(MAKE) -C "$(work_dir)_$(cfg)" -rf $(tbb_root)/src/Makefile BUILDING_PHASE=1 shell shell_cmd="$(if $(args),$(args),$(SHELL))" +endif + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/index.html new file mode 100644 index 00000000..ddb823b0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/index.html @@ -0,0 +1,76 @@ + + + +

Overview

+This directory contains the source code and unit tests for Intel® Threading Building Blocks. + +

Directories

+
+
tbb +
Source code of the TBB library core. +
tbbmalloc +
Source code of the TBB scalable memory allocator. +
test +
Source code of the TBB unit tests. +
rml +
Source code of the Resource Management Layer (RML). +
perf +
Source code of microbenchmarks. +
old +
Source code of deprecated TBB entities that are still shipped as part of the TBB library for the sake of backward compatibility. +
+ +

Files

+
+
Makefile +
Advanced Makefile for developing and debugging of TBB. See the basic build directions. Additional targets and options: +
make test_{name} time_{name} +
Make and run individual test or benchmark. +
make stress_{name} +
Equivalent to 'make test_{name}' but runs until a failure detected or terminated by user. +
make run_cmd="{command}" [(above options or targets)] +
Command prefix for tests execution. Also, "run_cmd=-" will ignore test execution failures. See also -k and -i options of the GNU make for more options to keep building and testing despite of failures. +
make debug_{name} +
Equivalent to 'make test_{name}' but compiles in debug mode and runs under debugger ("run_cmd=$(debugger)"). +
make args="{command-line arguments}" [(above options or targets)] +
Additional arguments for the run. +
make repeat="{N}" [(above options or targets)] +
Repeats execution N times. +
make clean_{filename} +
Removes executable, object, and other intermediate files with specified filename ('*' also works). +
make cfg={debug|release} [(above options or targets)] +
Specifies a build mode or corresponding directory to work in. +
make tbb_strict=1 [(above options or targets)] +
Enables warnings as errors. +
make examples/{target} +
Invokes examples/Makefile with specified target. Available in the open-source version only. + For the commercial version, you can download Intel TBB Samples at the Intel® Software Product Samples and Tutorials website. +
make python_{target} [compiler={icl, icc}] +
Invokes Makefile with the specified target in python directory. E.g. 'python_install' target builds and installs the module into Python. +
make clean_release clean_debug clean_examples +
Removes release or debug build directories, or cleans all examples. The target clean_examples is available in the open-source version only. +
make test_no_depends +
Equivalent to 'make test' but does not check for libraries updates. +
make info +
Output information about build configuration and directories. +
make cpp0x=1 [(above options or targets)] +
Enables C++0x extensions like lambdas for compilers that implement them as experimental features. +
make CXXFLAGS={Flags} [(above options or targets)] +
Specifies additional options for compiler. +
make target={name} [(above options or targets)] +
Includes additional build/{name}.inc file after OS-specific one. +
make extra_inc={filename} [(above options or targets)] +
Includes additional makefile. +
+ +
+Up to parent directory +

+Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +

+Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +

+* Other names and brands may be claimed as the property of others. + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_queue_v2.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_queue_v2.cpp new file mode 100644 index 00000000..43a20feb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_queue_v2.cpp @@ -0,0 +1,361 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "concurrent_queue_v2.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/spin_mutex.h" +#include "tbb/atomic.h" +#include +#include + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4267) +#endif + +#define RECORD_EVENTS 0 + +namespace tbb { + +namespace internal { + +class concurrent_queue_rep; + +//! A queue using simple locking. +/** For efficiency, this class has no constructor. + The caller is expected to zero-initialize it. */ +struct micro_queue { + typedef concurrent_queue_base::page page; + typedef size_t ticket; + + atomic head_page; + atomic head_counter; + + atomic tail_page; + atomic tail_counter; + + spin_mutex page_mutex; + + class push_finalizer: no_copy { + ticket my_ticket; + micro_queue& my_queue; + public: + push_finalizer( micro_queue& queue, ticket k ) : + my_ticket(k), my_queue(queue) + {} + ~push_finalizer() { + my_queue.tail_counter = my_ticket; + } + }; + + void push( const void* item, ticket k, concurrent_queue_base& base ); + + class pop_finalizer: no_copy { + ticket my_ticket; + micro_queue& my_queue; + page* my_page; + public: + pop_finalizer( micro_queue& queue, ticket k, page* p ) : + my_ticket(k), my_queue(queue), my_page(p) + {} + ~pop_finalizer() { + page* p = my_page; + if( p ) { + spin_mutex::scoped_lock lock( my_queue.page_mutex ); + page* q = p->next; + my_queue.head_page = q; + if( !q ) { + my_queue.tail_page = NULL; + } + } + my_queue.head_counter = my_ticket; + if( p ) + operator delete(p); + } + }; + + bool pop( void* dst, ticket k, concurrent_queue_base& base ); +}; + +//! Internal representation of a ConcurrentQueue. +/** For efficiency, this class has no constructor. + The caller is expected to zero-initialize it. */ +class concurrent_queue_rep { +public: + typedef size_t ticket; + +private: + friend struct micro_queue; + + //! Approximately n_queue/golden ratio + static const size_t phi = 3; + +public: + //! Must be power of 2 + static const size_t n_queue = 8; + + //! Map ticket to an array index + static size_t index( ticket k ) { + return k*phi%n_queue; + } + + atomic head_counter; + char pad1[NFS_MaxLineSize-sizeof(atomic)]; + + atomic tail_counter; + char pad2[NFS_MaxLineSize-sizeof(atomic)]; + micro_queue array[n_queue]; + + micro_queue& choose( ticket k ) { + // The formula here approximates LRU in a cache-oblivious way. + return array[index(k)]; + } + + //! Value for effective_capacity that denotes unbounded queue. + static const ptrdiff_t infinite_capacity = ptrdiff_t(~size_t(0)/2); +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // unary minus operator applied to unsigned type, result still unsigned + #pragma warning( push ) + #pragma warning( disable: 4146 ) +#endif + +//------------------------------------------------------------------------ +// micro_queue +//------------------------------------------------------------------------ +void micro_queue::push( const void* item, ticket k, concurrent_queue_base& base ) { + k &= -concurrent_queue_rep::n_queue; + page* p = NULL; + size_t index = modulo_power_of_two( k/concurrent_queue_rep::n_queue, base.items_per_page ); + if( !index ) { + size_t n = sizeof(page) + base.items_per_page*base.item_size; + p = static_cast(operator new( n )); + p->mask = 0; + p->next = NULL; + } + { + push_finalizer finalizer( *this, k+concurrent_queue_rep::n_queue ); + spin_wait_until_eq( tail_counter, k ); + if( p ) { + spin_mutex::scoped_lock lock( page_mutex ); + if( page* q = tail_page ) + q->next = p; + else + head_page = p; + tail_page = p; + } else { + p = tail_page; + } + base.copy_item( *p, index, item ); + // If no exception was thrown, mark item as present. + p->mask |= uintptr_t(1)<mask & uintptr_t(1)<1 ? item_sz : 2); + my_rep = cache_aligned_allocator().allocate(1); + __TBB_ASSERT( (size_t)my_rep % NFS_GetLineSize()==0, "alignment error" ); + __TBB_ASSERT( (size_t)&my_rep->head_counter % NFS_GetLineSize()==0, "alignment error" ); + __TBB_ASSERT( (size_t)&my_rep->tail_counter % NFS_GetLineSize()==0, "alignment error" ); + __TBB_ASSERT( (size_t)&my_rep->array % NFS_GetLineSize()==0, "alignment error" ); + std::memset(static_cast(my_rep),0,sizeof(concurrent_queue_rep)); + this->item_size = item_sz; +} + +concurrent_queue_base::~concurrent_queue_base() { + size_t nq = my_rep->n_queue; + for( size_t i=0; iarray[i].tail_page; + __TBB_ASSERT( my_rep->array[i].head_page==tp, "at most one page should remain" ); + if( tp!=NULL ) + delete tp; + } + cache_aligned_allocator().deallocate(my_rep,1); +} + +void concurrent_queue_base::internal_push( const void* src ) { + concurrent_queue_rep& r = *my_rep; + concurrent_queue_rep::ticket k = r.tail_counter++; + if( my_capacity=const_cast(my_capacity) ) + backoff.pause(); + } + r.choose(k).push(src,k,*this); +} + +void concurrent_queue_base::internal_pop( void* dst ) { + concurrent_queue_rep& r = *my_rep; + concurrent_queue_rep::ticket k; + do { + k = r.head_counter++; + } while( !r.choose(k).pop(dst,k,*this) ); +} + +bool concurrent_queue_base::internal_pop_if_present( void* dst ) { + concurrent_queue_rep& r = *my_rep; + concurrent_queue_rep::ticket k; + do { + for( atomic_backoff b;;b.pause() ) { + k = r.head_counter; + if( r.tail_counter<=k ) { + // Queue is empty + return false; + } + // Queue had item with ticket k when we looked. Attempt to get that item. + if( r.head_counter.compare_and_swap(k+1,k)==k ) { + break; + } + // Another thread snatched the item, so pause and retry. + } + } while( !r.choose(k).pop(dst,k,*this) ); + return true; +} + +bool concurrent_queue_base::internal_push_if_not_full( const void* src ) { + concurrent_queue_rep& r = *my_rep; + concurrent_queue_rep::ticket k; + for( atomic_backoff b;;b.pause() ) { + k = r.tail_counter; + if( (ptrdiff_t)(k-r.head_counter)>=my_capacity ) { + // Queue is full + return false; + } + // Queue had empty slot with ticket k when we looked. Attempt to claim that slot. + if( r.tail_counter.compare_and_swap(k+1,k)==k ) + break; + // Another thread claimed the slot, so pause and retry. + } + r.choose(k).push(src,k,*this); + return true; +} + +ptrdiff_t concurrent_queue_base::internal_size() const { + __TBB_ASSERT( sizeof(ptrdiff_t)<=sizeof(size_t), NULL ); + return ptrdiff_t(my_rep->tail_counter-my_rep->head_counter); +} + +void concurrent_queue_base::internal_set_capacity( ptrdiff_t capacity, size_t /*item_sz*/ ) { + my_capacity = capacity<0 ? concurrent_queue_rep::infinite_capacity : capacity; +} + +//------------------------------------------------------------------------ +// concurrent_queue_iterator_rep +//------------------------------------------------------------------------ +class concurrent_queue_iterator_rep: no_assign { +public: + typedef concurrent_queue_rep::ticket ticket; + ticket head_counter; + const concurrent_queue_base& my_queue; + concurrent_queue_base::page* array[concurrent_queue_rep::n_queue]; + concurrent_queue_iterator_rep( const concurrent_queue_base& queue ) : + head_counter(queue.my_rep->head_counter), + my_queue(queue) + { + const concurrent_queue_rep& rep = *queue.my_rep; + for( size_t k=0; ktail_counter ) + return NULL; + else { + concurrent_queue_base::page* p = array[concurrent_queue_rep::index(k)]; + __TBB_ASSERT(p,NULL); + size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, my_queue.items_per_page ); + return static_cast(static_cast(p+1)) + my_queue.item_size*i; + } + } +}; + +//------------------------------------------------------------------------ +// concurrent_queue_iterator_base +//------------------------------------------------------------------------ +concurrent_queue_iterator_base::concurrent_queue_iterator_base( const concurrent_queue_base& queue ) { + my_rep = new concurrent_queue_iterator_rep(queue); + my_item = my_rep->choose(my_rep->head_counter); +} + +void concurrent_queue_iterator_base::assign( const concurrent_queue_iterator_base& other ) { + if( my_rep!=other.my_rep ) { + if( my_rep ) { + delete my_rep; + my_rep = NULL; + } + if( other.my_rep ) { + my_rep = new concurrent_queue_iterator_rep( *other.my_rep ); + } + } + my_item = other.my_item; +} + +void concurrent_queue_iterator_base::advance() { + __TBB_ASSERT( my_item, "attempt to increment iterator past end of queue" ); + size_t k = my_rep->head_counter; + const concurrent_queue_base& queue = my_rep->my_queue; + __TBB_ASSERT( my_item==my_rep->choose(k), NULL ); + size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, queue.items_per_page ); + if( i==queue.items_per_page-1 ) { + concurrent_queue_base::page*& root = my_rep->array[concurrent_queue_rep::index(k)]; + root = root->next; + } + my_rep->head_counter = k+1; + my_item = my_rep->choose(k+1); +} + +concurrent_queue_iterator_base::~concurrent_queue_iterator_base() { + delete my_rep; + my_rep = NULL; +} + +} // namespace internal + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_queue_v2.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_queue_v2.h new file mode 100644 index 00000000..3f8bef0e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_queue_v2.h @@ -0,0 +1,320 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_queue_H +#define __TBB_concurrent_queue_H + +#include "tbb/tbb_stddef.h" +#include + +namespace tbb { + +template class concurrent_queue; + +//! @cond INTERNAL +namespace internal { + +class concurrent_queue_rep; +class concurrent_queue_iterator_rep; +template class concurrent_queue_iterator; + +//! For internal use only. +/** Type-independent portion of concurrent_queue. + @ingroup containers */ +class concurrent_queue_base: no_copy { + //! Internal representation + concurrent_queue_rep* my_rep; + + friend class concurrent_queue_rep; + friend struct micro_queue; + friend class concurrent_queue_iterator_rep; + friend class concurrent_queue_iterator_base; + + // In C++ 1998/2003 (but quite likely not beyond), friend micro_queue's rights + // do not apply to the declaration of micro_queue::pop_finalizer::my_page, + // as a member of a class nested within that friend class, so... +public: + //! Prefix on a page + struct page { + page* next; + uintptr_t mask; + }; + +protected: + //! Capacity of the queue + ptrdiff_t my_capacity; + + //! Always a power of 2 + size_t items_per_page; + + //! Size of an item + size_t item_size; +private: + virtual void copy_item( page& dst, size_t index, const void* src ) = 0; + virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) = 0; +protected: + __TBB_EXPORTED_METHOD concurrent_queue_base( size_t item_size ); + virtual __TBB_EXPORTED_METHOD ~concurrent_queue_base(); + + //! Enqueue item at tail of queue + void __TBB_EXPORTED_METHOD internal_push( const void* src ); + + //! Dequeue item from head of queue + void __TBB_EXPORTED_METHOD internal_pop( void* dst ); + + //! Attempt to enqueue item onto queue. + bool __TBB_EXPORTED_METHOD internal_push_if_not_full( const void* src ); + + //! Attempt to dequeue item from queue. + /** NULL if there was no item to dequeue. */ + bool __TBB_EXPORTED_METHOD internal_pop_if_present( void* dst ); + + //! Get size of queue + ptrdiff_t __TBB_EXPORTED_METHOD internal_size() const; + + void __TBB_EXPORTED_METHOD internal_set_capacity( ptrdiff_t capacity, size_t element_size ); +}; + +//! Type-independent portion of concurrent_queue_iterator. +/** @ingroup containers */ +class concurrent_queue_iterator_base : no_assign { + //! concurrent_queue over which we are iterating. + /** NULL if one past last element in queue. */ + concurrent_queue_iterator_rep* my_rep; + + template + friend bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); + + template + friend bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ); +protected: + //! Pointer to current item + mutable void* my_item; + + //! Default constructor + __TBB_EXPORTED_METHOD concurrent_queue_iterator_base() : no_assign(), my_rep(NULL), my_item(NULL) {} + + //! Copy constructor + concurrent_queue_iterator_base( const concurrent_queue_iterator_base& i ) : no_assign(), my_rep(NULL), my_item(NULL) { + assign(i); + } + + //! Construct iterator pointing to head of queue. + concurrent_queue_iterator_base( const concurrent_queue_base& queue ); + + //! Assignment + void __TBB_EXPORTED_METHOD assign( const concurrent_queue_iterator_base& i ); + + //! Advance iterator one step towards tail of queue. + void __TBB_EXPORTED_METHOD advance(); + + //! Destructor + __TBB_EXPORTED_METHOD ~concurrent_queue_iterator_base(); +}; + +//! Meets requirements of a forward iterator for STL. +/** Value is either the T or const T type of the container. + @ingroup containers */ +template +class concurrent_queue_iterator: public concurrent_queue_iterator_base { +#if !defined(_MSC_VER) || defined(__INTEL_COMPILER) + template + friend class ::tbb::concurrent_queue; +#else +public: // workaround for MSVC +#endif + //! Construct iterator pointing to head of queue. + concurrent_queue_iterator( const concurrent_queue_base& queue ) : + concurrent_queue_iterator_base(queue) + { + } +public: + concurrent_queue_iterator() {} + + /** If Value==Container::value_type, then this routine is the copy constructor. + If Value==const Container::value_type, then this routine is a conversion constructor. */ + concurrent_queue_iterator( const concurrent_queue_iterator& other ) : + concurrent_queue_iterator_base(other) + {} + + //! Iterator assignment + concurrent_queue_iterator& operator=( const concurrent_queue_iterator& other ) { + assign(other); + return *this; + } + + //! Reference to current item + Value& operator*() const { + return *static_cast(my_item); + } + + Value* operator->() const {return &operator*();} + + //! Advance to next item in queue + concurrent_queue_iterator& operator++() { + advance(); + return *this; + } + + //! Post increment + Value* operator++(int) { + Value* result = &operator*(); + operator++(); + return result; + } +}; // concurrent_queue_iterator + +template +bool operator==( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { + return i.my_item==j.my_item; +} + +template +bool operator!=( const concurrent_queue_iterator& i, const concurrent_queue_iterator& j ) { + return i.my_item!=j.my_item; +} + +} // namespace internal; +//! @endcond + +//! A high-performance thread-safe queue. +/** Multiple threads may each push and pop concurrently. + Assignment and copy construction are not allowed. + @ingroup containers */ +template +class concurrent_queue: public internal::concurrent_queue_base { + template friend class internal::concurrent_queue_iterator; + + //! Class used to ensure exception-safety of method "pop" + class destroyer { + T& my_value; + public: + destroyer( T& value ) : my_value(value) {} + ~destroyer() {my_value.~T();} + }; + + T& get_ref( page& pg, size_t index ) { + __TBB_ASSERT( index(static_cast(&pg+1))[index]; + } + + virtual void copy_item( page& dst, size_t index, const void* src ) __TBB_override { + new( &get_ref(dst,index) ) T(*static_cast(src)); + } + + virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) __TBB_override { + T& from = get_ref(src,index); + destroyer d(from); + *static_cast(dst) = from; + } + +public: + //! Element type in the queue. + typedef T value_type; + + //! Reference type + typedef T& reference; + + //! Const reference type + typedef const T& const_reference; + + //! Integral type for representing size of the queue. + /** Note that the size_type is a signed integral type. + This is because the size can be negative if there are pending pops without corresponding pushes. */ + typedef std::ptrdiff_t size_type; + + //! Difference type for iterator + typedef std::ptrdiff_t difference_type; + + //! Construct empty queue + concurrent_queue() : + concurrent_queue_base( sizeof(T) ) + { + } + + //! Destroy queue + ~concurrent_queue(); + + //! Enqueue an item at tail of queue. + void push( const T& source ) { + internal_push( &source ); + } + + //! Dequeue item from head of queue. + /** Block until an item becomes available, and then dequeue it. */ + void pop( T& destination ) { + internal_pop( &destination ); + } + + //! Enqueue an item at tail of queue if queue is not already full. + /** Does not wait for queue to become not full. + Returns true if item is pushed; false if queue was already full. */ + bool push_if_not_full( const T& source ) { + return internal_push_if_not_full( &source ); + } + + //! Attempt to dequeue an item from head of queue. + /** Does not wait for item to become available. + Returns true if successful; false otherwise. */ + bool pop_if_present( T& destination ) { + return internal_pop_if_present( &destination ); + } + + //! Return number of pushes minus number of pops. + /** Note that the result can be negative if there are pops waiting for the + corresponding pushes. The result can also exceed capacity() if there + are push operations in flight. */ + size_type size() const {return internal_size();} + + //! Equivalent to size()<=0. + bool empty() const {return size()<=0;} + + //! Maximum number of allowed elements + size_type capacity() const { + return my_capacity; + } + + //! Set the capacity + /** Setting the capacity to 0 causes subsequent push_if_not_full operations to always fail, + and subsequent push operations to block forever. */ + void set_capacity( size_type new_capacity ) { + internal_set_capacity( new_capacity, sizeof(T) ); + } + + typedef internal::concurrent_queue_iterator iterator; + typedef internal::concurrent_queue_iterator const_iterator; + + //------------------------------------------------------------------------ + // The iterators are intended only for debugging. They are slow and not thread safe. + //------------------------------------------------------------------------ + iterator begin() {return iterator(*this);} + iterator end() {return iterator();} + const_iterator begin() const {return const_iterator(*this);} + const_iterator end() const {return const_iterator();} + +}; + +template +concurrent_queue::~concurrent_queue() { + while( !empty() ) { + T value; + internal_pop(&value); + } +} + +} // namespace tbb + +#endif /* __TBB_concurrent_queue_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_vector_v2.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_vector_v2.cpp new file mode 100644 index 00000000..0f96b755 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_vector_v2.cpp @@ -0,0 +1,252 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "concurrent_vector_v2.h" +#include "tbb/tbb_machine.h" +#include "../tbb/itt_notify.h" +#include "tbb/task.h" + +#include // std::length_error +#include + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4267) +#endif + +namespace tbb { + +namespace internal { + +void concurrent_vector_base::internal_grow_to_at_least( size_type new_size, size_type element_size, internal_array_op1 init ) { + size_type e = my_early_size; + while( e=pointers_per_short_segment && v.my_segment==v.my_storage ) { + extend_segment(v); + } + } +}; + +void concurrent_vector_base::helper::extend_segment( concurrent_vector_base& v ) { + const size_t pointers_per_long_segment = sizeof(void*)==4 ? 32 : 64; + segment_t* s = (segment_t*)NFS_Allocate( pointers_per_long_segment, sizeof(segment_t), NULL ); + std::memset( static_cast(s), 0, pointers_per_long_segment*sizeof(segment_t) ); + // If other threads are trying to set pointers in the short segment, wait for them to finish their + // assignments before we copy the short segment to the long segment. + atomic_backoff backoff; + while( !v.my_storage[0].array || !v.my_storage[1].array ) backoff.pause(); + s[0] = v.my_storage[0]; + s[1] = v.my_storage[1]; + if( v.my_segment.compare_and_swap( s, v.my_storage )!=v.my_storage ) + NFS_Free(s); +} + +concurrent_vector_base::size_type concurrent_vector_base::internal_capacity() const { + return segment_base( helper::find_segment_end(*this) ); +} + +void concurrent_vector_base::internal_reserve( size_type n, size_type element_size, size_type max_size ) { + if( n>max_size ) { + __TBB_THROW( std::length_error("argument to concurrent_vector::reserve exceeds concurrent_vector::max_size()") ); + } + for( segment_index_t k = helper::find_segment_end(*this); segment_base(k)n-b ) m = n-b; + copy( my_segment[k].array, src.my_segment[k].array, m ); + } + } +} + +void concurrent_vector_base::internal_assign( const concurrent_vector_base& src, size_type element_size, internal_array_op1 destroy, internal_array_op2 assign, internal_array_op2 copy ) { + size_type n = src.my_early_size; + while( my_early_size>n ) { + segment_index_t k = segment_index_of( my_early_size-1 ); + size_type b=segment_base(k); + size_type new_end = b>=n ? b : n; + __TBB_ASSERT( my_early_size>new_end, NULL ); + destroy( (char*)my_segment[k].array+element_size*(new_end-b), my_early_size-new_end ); + my_early_size = new_end; + } + size_type dst_initialized_size = my_early_size; + my_early_size = n; + size_type b; + for( segment_index_t k=0; (b=segment_base(k))n-b ) m = n-b; + size_type a = 0; + if( dst_initialized_size>b ) { + a = dst_initialized_size-b; + if( a>m ) a = m; + assign( my_segment[k].array, src.my_segment[k].array, a ); + m -= a; + a *= element_size; + } + if( m>0 ) + copy( (char*)my_segment[k].array+a, (char*)src.my_segment[k].array+a, m ); + } + __TBB_ASSERT( src.my_early_size==n, "detected use of concurrent_vector::operator= with right side that was concurrently modified" ); +} + +void* concurrent_vector_base::internal_push_back( size_type element_size, size_type& index ) { + __TBB_ASSERT( sizeof(my_early_size)==sizeof(reference_count), NULL ); + //size_t tmp = __TBB_FetchAndIncrementWacquire(*(tbb::internal::reference_count*)&my_early_size); + size_t tmp = __TBB_FetchAndIncrementWacquire((tbb::internal::reference_count*)&my_early_size); + index = tmp; + segment_index_t k_old = segment_index_of( tmp ); + size_type base = segment_base(k_old); + helper::extend_segment_if_necessary(*this,k_old); + segment_t& s = my_segment[k_old]; + void* array = s.array; + if( !array ) { + // FIXME - consider factoring this out and share with internal_grow_by + if( base==tmp ) { + __TBB_ASSERT( !s.array, NULL ); + size_t n = segment_size(k_old); + array = NFS_Allocate( n, element_size, NULL ); + ITT_NOTIFY( sync_releasing, &s.array ); + s.array = array; + } else { + ITT_NOTIFY(sync_prepare, &s.array); + spin_wait_while_eq( s.array, (void*)0 ); + ITT_NOTIFY(sync_acquired, &s.array); + array = s.array; + } + } + size_type j_begin = tmp-base; + return (void*)((char*)array+element_size*j_begin); +} + +concurrent_vector_base::size_type concurrent_vector_base::internal_grow_by( size_type delta, size_type element_size, internal_array_op1 init ) { + size_type result = my_early_size.fetch_and_add(delta); + internal_grow( result, result+delta, element_size, init ); + return result; +} + +void concurrent_vector_base::internal_grow( const size_type start, size_type finish, size_type element_size, internal_array_op1 init ) { + __TBB_ASSERT( start finish-base ? finish-base : n; + (*init)( (void*)((char*)array+element_size*j_begin), j_end-j_begin ); + tmp = base+j_end; + } while( tmp0 ) { + segment_index_t k_old = segment_index_of(finish-1); + segment_t& s = my_segment[k_old]; + __TBB_ASSERT( s.array, NULL ); + size_type base = segment_base(k_old); + size_type j_end = finish-base; + __TBB_ASSERT( j_end, NULL ); + (*destroy)( s.array, j_end ); + finish = base; + } + + // Free the arrays + if( reclaim_storage ) { + size_t k = helper::find_segment_end(*this); + while( k>0 ) { + --k; + segment_t& s = my_segment[k]; + void* array = s.array; + s.array = NULL; + NFS_Free( array ); + } + // Clear short segment. + my_storage[0].array = NULL; + my_storage[1].array = NULL; + segment_t* s = my_segment; + if( s!=my_storage ) { + my_segment = my_storage; + NFS_Free( s ); + } + } +} + +} // namespace internal + +} // tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_vector_v2.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_vector_v2.h new file mode 100644 index 00000000..1cb482eb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/concurrent_vector_v2.h @@ -0,0 +1,508 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_vector_H +#define __TBB_concurrent_vector_H + +#include "tbb/tbb_stddef.h" +#include "tbb/atomic.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/blocked_range.h" +#include "tbb/tbb_machine.h" +#include +#include + +namespace tbb { + +template +class concurrent_vector; + +//! @cond INTERNAL +namespace internal { + + //! Base class of concurrent vector implementation. + /** @ingroup containers */ + class concurrent_vector_base { + protected: + + // Basic types declarations + typedef unsigned long segment_index_t; + typedef size_t size_type; + + //! Log2 of "min_segment_size". + static const int lg_min_segment_size = 4; + + //! Minimum size (in physical items) of a segment. + static const int min_segment_size = segment_index_t(1)<>1< my_early_size; + + /** Can be zero-initialized. */ + struct segment_t { + /** Declared volatile because in weak memory model, must have ld.acq/st.rel */ + void* volatile array; +#if TBB_USE_ASSERT + ~segment_t() { + __TBB_ASSERT( !array, "should have been set to NULL by clear" ); + } +#endif /* TBB_USE_ASSERT */ + }; + + // Data fields + + //! Pointer to the segments table + atomic my_segment; + + //! embedded storage of segment pointers + segment_t my_storage[2]; + + // Methods + + concurrent_vector_base() { + my_early_size = 0; + my_storage[0].array = NULL; + my_storage[1].array = NULL; + my_segment = my_storage; + } + + //! An operation on an n-element array starting at begin. + typedef void(__TBB_EXPORTED_FUNC *internal_array_op1)(void* begin, size_type n ); + + //! An operation on n-element destination array and n-element source array. + typedef void(__TBB_EXPORTED_FUNC *internal_array_op2)(void* dst, const void* src, size_type n ); + + void __TBB_EXPORTED_METHOD internal_grow_to_at_least( size_type new_size, size_type element_size, internal_array_op1 init ); + void internal_grow( size_type start, size_type finish, size_type element_size, internal_array_op1 init ); + size_type __TBB_EXPORTED_METHOD internal_grow_by( size_type delta, size_type element_size, internal_array_op1 init ); + void* __TBB_EXPORTED_METHOD internal_push_back( size_type element_size, size_type& index ); + void __TBB_EXPORTED_METHOD internal_clear( internal_array_op1 destroy, bool reclaim_storage ); + void __TBB_EXPORTED_METHOD internal_copy( const concurrent_vector_base& src, size_type element_size, internal_array_op2 copy ); + void __TBB_EXPORTED_METHOD internal_assign( const concurrent_vector_base& src, size_type element_size, + internal_array_op1 destroy, internal_array_op2 assign, internal_array_op2 copy ); +private: + //! Private functionality that does not cross DLL boundary. + class helper; + friend class helper; + }; + + //! Meets requirements of a forward iterator for STL and a Value for a blocked_range.*/ + /** Value is either the T or const T type of the container. + @ingroup containers */ + template + class vector_iterator +#if defined(_WIN64) && defined(_MSC_VER) + // Ensure that Microsoft's internal template function _Val_type works correctly. + : public std::iterator +#endif /* defined(_WIN64) && defined(_MSC_VER) */ + { + //! concurrent_vector over which we are iterating. + Container* my_vector; + + //! Index into the vector + size_t my_index; + + //! Caches my_vector->internal_subscript(my_index) + /** NULL if cached value is not available */ + mutable Value* my_item; + + template + friend bool operator==( const vector_iterator& i, const vector_iterator& j ); + + template + friend bool operator<( const vector_iterator& i, const vector_iterator& j ); + + template + friend ptrdiff_t operator-( const vector_iterator& i, const vector_iterator& j ); + + template + friend class internal::vector_iterator; + +#if !defined(_MSC_VER) || defined(__INTEL_COMPILER) + template + friend class tbb::concurrent_vector; +#else +public: // workaround for MSVC +#endif + + vector_iterator( const Container& vector, size_t index ) : + my_vector(const_cast(&vector)), + my_index(index), + my_item(NULL) + {} + + public: + //! Default constructor + vector_iterator() : my_vector(NULL), my_index(~size_t(0)), my_item(NULL) {} + + vector_iterator( const vector_iterator& other ) : + my_vector(other.my_vector), + my_index(other.my_index), + my_item(other.my_item) + {} + + vector_iterator operator+( ptrdiff_t offset ) const { + return vector_iterator( *my_vector, my_index+offset ); + } + friend vector_iterator operator+( ptrdiff_t offset, const vector_iterator& v ) { + return vector_iterator( *v.my_vector, v.my_index+offset ); + } + vector_iterator operator+=( ptrdiff_t offset ) { + my_index+=offset; + my_item = NULL; + return *this; + } + vector_iterator operator-( ptrdiff_t offset ) const { + return vector_iterator( *my_vector, my_index-offset ); + } + vector_iterator operator-=( ptrdiff_t offset ) { + my_index-=offset; + my_item = NULL; + return *this; + } + Value& operator*() const { + Value* item = my_item; + if( !item ) { + item = my_item = &my_vector->internal_subscript(my_index); + } + __TBB_ASSERT( item==&my_vector->internal_subscript(my_index), "corrupt cache" ); + return *item; + } + Value& operator[]( ptrdiff_t k ) const { + return my_vector->internal_subscript(my_index+k); + } + Value* operator->() const {return &operator*();} + + //! Pre increment + vector_iterator& operator++() { + size_t k = ++my_index; + if( my_item ) { + // Following test uses 2's-complement wizardry and fact that + // min_segment_size is a power of 2. + if( (k& k-concurrent_vector::min_segment_size)==0 ) { + // k is a power of two that is at least k-min_segment_size + my_item= NULL; + } else { + ++my_item; + } + } + return *this; + } + + //! Pre decrement + vector_iterator& operator--() { + __TBB_ASSERT( my_index>0, "operator--() applied to iterator already at beginning of concurrent_vector" ); + size_t k = my_index--; + if( my_item ) { + // Following test uses 2's-complement wizardry and fact that + // min_segment_size is a power of 2. + if( (k& k-concurrent_vector::min_segment_size)==0 ) { + // k is a power of two that is at least k-min_segment_size + my_item= NULL; + } else { + --my_item; + } + } + return *this; + } + + //! Post increment + vector_iterator operator++(int) { + vector_iterator result = *this; + operator++(); + return result; + } + + //! Post decrement + vector_iterator operator--(int) { + vector_iterator result = *this; + operator--(); + return result; + } + + // STL support + + typedef ptrdiff_t difference_type; + typedef Value value_type; + typedef Value* pointer; + typedef Value& reference; + typedef std::random_access_iterator_tag iterator_category; + }; + + template + bool operator==( const vector_iterator& i, const vector_iterator& j ) { + return i.my_index==j.my_index; + } + + template + bool operator!=( const vector_iterator& i, const vector_iterator& j ) { + return !(i==j); + } + + template + bool operator<( const vector_iterator& i, const vector_iterator& j ) { + return i.my_index + bool operator>( const vector_iterator& i, const vector_iterator& j ) { + return j + bool operator>=( const vector_iterator& i, const vector_iterator& j ) { + return !(i + bool operator<=( const vector_iterator& i, const vector_iterator& j ) { + return !(j + ptrdiff_t operator-( const vector_iterator& i, const vector_iterator& j ) { + return ptrdiff_t(i.my_index)-ptrdiff_t(j.my_index); + } + +} // namespace internal +//! @endcond + +//! Concurrent vector +/** @ingroup containers */ +template +class concurrent_vector: private internal::concurrent_vector_base { +public: + using internal::concurrent_vector_base::size_type; +private: + template + class generic_range_type: public blocked_range { + public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef I iterator; + typedef ptrdiff_t difference_type; + generic_range_type( I begin_, I end_, size_t grainsize_ ) : blocked_range(begin_,end_,grainsize_) {} + generic_range_type( generic_range_type& r, split ) : blocked_range(r,split()) {} + }; + + template + friend class internal::vector_iterator; +public: + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; + typedef ptrdiff_t difference_type; + + //! Construct empty vector. + concurrent_vector() {} + + //! Copy a vector. + concurrent_vector( const concurrent_vector& vector ) : internal::concurrent_vector_base() + { internal_copy(vector,sizeof(T),©_array); } + + //! Assignment + concurrent_vector& operator=( const concurrent_vector& vector ) { + if( this!=&vector ) + internal_assign(vector,sizeof(T),&destroy_array,&assign_array,©_array); + return *this; + } + + //! Clear and destroy vector. + ~concurrent_vector() {internal_clear(&destroy_array,/*reclaim_storage=*/true);} + + //------------------------------------------------------------------------ + // Concurrent operations + //------------------------------------------------------------------------ + //! Grow by "delta" elements. + /** Returns old size. */ + size_type grow_by( size_type delta ) { + return delta ? internal_grow_by( delta, sizeof(T), &initialize_array ) : my_early_size.load(); + } + + //! Grow array until it has at least n elements. + void grow_to_at_least( size_type n ) { + if( my_early_size iterator; + typedef internal::vector_iterator const_iterator; + +#if !defined(_MSC_VER) || _CPPLIB_VER>=300 + // Assume ISO standard definition of std::reverse_iterator + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#else + // Use non-standard std::reverse_iterator + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#endif /* defined(_MSC_VER) && (_MSC_VER<1300) */ + + // Forward sequence + iterator begin() {return iterator(*this,0);} + iterator end() {return iterator(*this,size());} + const_iterator begin() const {return const_iterator(*this,0);} + const_iterator end() const {return const_iterator(*this,size());} + + // Reverse sequence + reverse_iterator rbegin() {return reverse_iterator(end());} + reverse_iterator rend() {return reverse_iterator(begin());} + const_reverse_iterator rbegin() const {return const_reverse_iterator(end());} + const_reverse_iterator rend() const {return const_reverse_iterator(begin());} + + //------------------------------------------------------------------------ + // Support for TBB algorithms (ranges) + //------------------------------------------------------------------------ + typedef generic_range_type range_type; + typedef generic_range_type const_range_type; + + //! Get range to use with parallel algorithms + range_type range( size_t grainsize = 1 ) { + return range_type( begin(), end(), grainsize ); + } + + //! Get const range for iterating with parallel algorithms + const_range_type range( size_t grainsize = 1 ) const { + return const_range_type( begin(), end(), grainsize ); + } + + //------------------------------------------------------------------------ + // Size and capacity + //------------------------------------------------------------------------ + //! Return size of vector. + size_type size() const {return my_early_size;} + + //! Return false if vector is not empty. + bool empty() const {return !my_early_size;} + + //! Maximum size to which array can grow without allocating more memory. + size_type capacity() const {return internal_capacity();} + + //! Allocate enough space to grow to size n without having to allocate more memory later. + /** Like most of the methods provided for STL compatibility, this method is *not* thread safe. + The capacity afterwards may be bigger than the requested reservation. */ + void reserve( size_type n ) { + if( n ) + internal_reserve(n, sizeof(T), max_size()); + } + + //! Upper bound on argument to reserve. + size_type max_size() const {return (~size_t(0))/sizeof(T);} + + //! Not thread safe + /** Does not change capacity. */ + void clear() {internal_clear(&destroy_array,/*reclaim_storage=*/false);} +private: + //! Get reference to element at given index. + T& internal_subscript( size_type index ) const; + + //! Construct n instances of T, starting at "begin". + static void __TBB_EXPORTED_FUNC initialize_array( void* begin, size_type n ); + + //! Construct n instances of T, starting at "begin". + static void __TBB_EXPORTED_FUNC copy_array( void* dst, const void* src, size_type n ); + + //! Assign n instances of T, starting at "begin". + static void __TBB_EXPORTED_FUNC assign_array( void* dst, const void* src, size_type n ); + + //! Destroy n instances of T, starting at "begin". + static void __TBB_EXPORTED_FUNC destroy_array( void* begin, size_type n ); +}; + +template +T& concurrent_vector::internal_subscript( size_type index ) const { + __TBB_ASSERT( index(my_segment[k].array)[j]; +} + +template +void concurrent_vector::initialize_array( void* begin, size_type n ) { + T* array = static_cast(begin); + for( size_type j=0; j +void concurrent_vector::copy_array( void* dst, const void* src, size_type n ) { + T* d = static_cast(dst); + const T* s = static_cast(src); + for( size_type j=0; j +void concurrent_vector::assign_array( void* dst, const void* src, size_type n ) { + T* d = static_cast(dst); + const T* s = static_cast(src); + for( size_type j=0; j +void concurrent_vector::destroy_array( void* begin, size_type n ) { + T* array = static_cast(begin); + for( size_type j=n; j>0; --j ) + array[j-1].~T(); +} + +} // namespace tbb + +#endif /* __TBB_concurrent_vector_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/spin_rw_mutex_v2.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/spin_rw_mutex_v2.cpp new file mode 100644 index 00000000..79b667d8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/spin_rw_mutex_v2.cpp @@ -0,0 +1,152 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "spin_rw_mutex_v2.h" +#include "tbb/tbb_machine.h" +#include "../tbb/itt_notify.h" +#include "tbb/atomic.h" + +namespace tbb { + +using namespace internal; + +static inline bool CAS(volatile uintptr_t &addr, uintptr_t newv, uintptr_t oldv) { + return as_atomic(addr).compare_and_swap(newv, oldv) == oldv; +} + +//! Signal that write lock is released +void spin_rw_mutex::internal_itt_releasing(spin_rw_mutex *mutex) { + __TBB_ASSERT_EX(mutex, NULL); // To prevent compiler warnings + ITT_NOTIFY(sync_releasing, mutex); +} + +//! Acquire write (exclusive) lock on the given mutex. +bool spin_rw_mutex::internal_acquire_writer(spin_rw_mutex *mutex) +{ + ITT_NOTIFY(sync_prepare, mutex); + for( atomic_backoff backoff;;backoff.pause() ) { + state_t s = mutex->state; + if( !(s & BUSY) ) { // no readers, no writers + if( CAS(mutex->state, WRITER, s) ) + break; // successfully stored writer flag + backoff.reset(); // we could be very close to complete op. + } else if( !(s & WRITER_PENDING) ) { // no pending writers + __TBB_AtomicOR(&mutex->state, WRITER_PENDING); + } + } + ITT_NOTIFY(sync_acquired, mutex); + __TBB_ASSERT( (mutex->state & BUSY)==WRITER, "invalid state of a write lock" ); + return false; +} + +//! Release write lock on the given mutex +void spin_rw_mutex::internal_release_writer(spin_rw_mutex *mutex) { + __TBB_ASSERT( (mutex->state & BUSY)==WRITER, "invalid state of a write lock" ); + ITT_NOTIFY(sync_releasing, mutex); + mutex->state = 0; +} + +//! Acquire read (shared) lock on the given mutex. +void spin_rw_mutex::internal_acquire_reader(spin_rw_mutex *mutex) { + ITT_NOTIFY(sync_prepare, mutex); + for( atomic_backoff backoff;;backoff.pause() ) { + state_t s = mutex->state; + if( !(s & (WRITER|WRITER_PENDING)) ) { // no writer or write requests + if( CAS(mutex->state, s+ONE_READER, s) ) + break; // successfully stored increased number of readers + backoff.reset(); // we could be very close to complete op. + } + } + ITT_NOTIFY(sync_acquired, mutex); + __TBB_ASSERT( mutex->state & READERS, "invalid state of a read lock: no readers" ); + __TBB_ASSERT( !(mutex->state & WRITER), "invalid state of a read lock: active writer" ); +} + +//! Upgrade reader to become a writer. +/** Returns whether the upgrade happened without releasing and re-acquiring the lock */ +bool spin_rw_mutex::internal_upgrade(spin_rw_mutex *mutex) { + state_t s = mutex->state; + __TBB_ASSERT( s & READERS, "invalid state before upgrade: no readers " ); + __TBB_ASSERT( !(s & WRITER), "invalid state before upgrade: active writer " ); + // check and set writer-pending flag + // required conditions: either no pending writers, or we are the only reader + // (with multiple readers and pending writer, another upgrade could have been requested) + while( (s & READERS)==ONE_READER || !(s & WRITER_PENDING) ) { + if( CAS(mutex->state, s | WRITER_PENDING, s) ) + { + ITT_NOTIFY(sync_prepare, mutex); + atomic_backoff backoff; + while( (mutex->state & READERS) != ONE_READER ) backoff.pause(); + __TBB_ASSERT(mutex->state == (ONE_READER | WRITER_PENDING),"invalid state when upgrading to writer"); + // both new readers and writers are blocked at this time + mutex->state = WRITER; + ITT_NOTIFY(sync_acquired, mutex); + __TBB_ASSERT( (mutex->state & BUSY) == WRITER, "invalid state after upgrade" ); + return true; // successfully upgraded + } else { + s = mutex->state; // re-read + } + } + // slow reacquire + internal_release_reader(mutex); + return internal_acquire_writer(mutex); // always returns false +} + +//! Downgrade writer to a reader +void spin_rw_mutex::internal_downgrade(spin_rw_mutex *mutex) { + __TBB_ASSERT( (mutex->state & BUSY) == WRITER, "invalid state before downgrade" ); + ITT_NOTIFY(sync_releasing, mutex); + mutex->state = ONE_READER; + __TBB_ASSERT( mutex->state & READERS, "invalid state after downgrade: no readers" ); + __TBB_ASSERT( !(mutex->state & WRITER), "invalid state after downgrade: active writer" ); +} + +//! Release read lock on the given mutex +void spin_rw_mutex::internal_release_reader(spin_rw_mutex *mutex) +{ + __TBB_ASSERT( mutex->state & READERS, "invalid state of a read lock: no readers" ); + __TBB_ASSERT( !(mutex->state & WRITER), "invalid state of a read lock: active writer" ); + ITT_NOTIFY(sync_releasing, mutex); // release reader + __TBB_FetchAndAddWrelease((volatile void *)&(mutex->state),-(intptr_t)ONE_READER); +} + +//! Try to acquire write lock on the given mutex +bool spin_rw_mutex::internal_try_acquire_writer( spin_rw_mutex * mutex ) +{ + // for a writer: only possible to acquire if no active readers or writers + state_t s = mutex->state; // on IA-64 architecture, this volatile load has acquire semantic + if( !(s & BUSY) ) // no readers, no writers; mask is 1..1101 + if( CAS(mutex->state, WRITER, s) ) { + ITT_NOTIFY(sync_acquired, mutex); + return true; // successfully stored writer flag + } + return false; +} + +//! Try to acquire read lock on the given mutex +bool spin_rw_mutex::internal_try_acquire_reader( spin_rw_mutex * mutex ) +{ + // for a reader: acquire if no active or waiting writers + state_t s = mutex->state; // on IA-64 architecture, a load of volatile variable has acquire semantic + while( !(s & (WRITER|WRITER_PENDING)) ) // no writers + if( CAS(mutex->state, s+ONE_READER, s) ) { + ITT_NOTIFY(sync_acquired, mutex); + return true; // successfully stored increased number of readers + } + return false; +} + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/spin_rw_mutex_v2.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/spin_rw_mutex_v2.h new file mode 100644 index 00000000..a49cc58b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/spin_rw_mutex_v2.h @@ -0,0 +1,171 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_spin_rw_mutex_H +#define __TBB_spin_rw_mutex_H + +#include "tbb/tbb_stddef.h" + +namespace tbb { + +//! Fast, unfair, spinning reader-writer lock with backoff and writer-preference +/** @ingroup synchronization */ +class spin_rw_mutex { + //! @cond INTERNAL + + //! Present so that 1.0 headers work with 1.1 dynamic library. + static void __TBB_EXPORTED_FUNC internal_itt_releasing(spin_rw_mutex *); + + //! Internal acquire write lock. + static bool __TBB_EXPORTED_FUNC internal_acquire_writer(spin_rw_mutex *); + + //! Out of line code for releasing a write lock. + /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ + static void __TBB_EXPORTED_FUNC internal_release_writer(spin_rw_mutex *); + + //! Internal acquire read lock. + static void __TBB_EXPORTED_FUNC internal_acquire_reader(spin_rw_mutex *); + + //! Internal upgrade reader to become a writer. + static bool __TBB_EXPORTED_FUNC internal_upgrade(spin_rw_mutex *); + + //! Out of line code for downgrading a writer to a reader. + /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */ + static void __TBB_EXPORTED_FUNC internal_downgrade(spin_rw_mutex *); + + //! Internal release read lock. + static void __TBB_EXPORTED_FUNC internal_release_reader(spin_rw_mutex *); + + //! Internal try_acquire write lock. + static bool __TBB_EXPORTED_FUNC internal_try_acquire_writer(spin_rw_mutex *); + + //! Internal try_acquire read lock. + static bool __TBB_EXPORTED_FUNC internal_try_acquire_reader(spin_rw_mutex *); + + //! @endcond +public: + //! Construct unacquired mutex. + spin_rw_mutex() : state(0) {} + +#if TBB_USE_ASSERT + //! Destructor asserts if the mutex is acquired, i.e. state is zero. + ~spin_rw_mutex() { + __TBB_ASSERT( !state, "destruction of an acquired mutex"); + }; +#endif /* TBB_USE_ASSERT */ + + //! The scoped locking pattern + /** It helps to avoid the common problem of forgetting to release lock. + It also nicely provides the "node" for queuing locks. */ + class scoped_lock : internal::no_copy { + public: + //! Construct lock that has not acquired a mutex. + /** Equivalent to zero-initialization of *this. */ + scoped_lock() : mutex(NULL) {} + + //! Construct and acquire lock on given mutex. + scoped_lock( spin_rw_mutex& m, bool write = true ) : mutex(NULL) { + acquire(m, write); + } + + //! Release lock (if lock is held). + ~scoped_lock() { + if( mutex ) release(); + } + + //! Acquire lock on given mutex. + void acquire( spin_rw_mutex& m, bool write = true ) { + __TBB_ASSERT( !mutex, "holding mutex already" ); + mutex = &m; + is_writer = write; + if( write ) internal_acquire_writer(mutex); + else internal_acquire_reader(mutex); + } + + //! Upgrade reader to become a writer. + /** Returns whether the upgrade happened without releasing and re-acquiring the lock */ + bool upgrade_to_writer() { + __TBB_ASSERT( mutex, "lock is not acquired" ); + __TBB_ASSERT( !is_writer, "not a reader" ); + is_writer = true; + return internal_upgrade(mutex); + } + + //! Release lock. + void release() { + __TBB_ASSERT( mutex, "lock is not acquired" ); + spin_rw_mutex *m = mutex; + mutex = NULL; + if( is_writer ) { +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + internal_release_writer(m); +#else + m->state = 0; +#endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */ + } else { + internal_release_reader(m); + } + }; + + //! Downgrade writer to become a reader. + bool downgrade_to_reader() { + __TBB_ASSERT( mutex, "lock is not acquired" ); + __TBB_ASSERT( is_writer, "not a writer" ); +#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT + internal_downgrade(mutex); +#else + mutex->state = 4; // Bit 2 - reader, 00..00100 +#endif + is_writer = false; + return true; + } + + //! Try acquire lock on given mutex. + bool try_acquire( spin_rw_mutex& m, bool write = true ) { + __TBB_ASSERT( !mutex, "holding mutex already" ); + bool result; + is_writer = write; + result = write? internal_try_acquire_writer(&m) + : internal_try_acquire_reader(&m); + if( result ) mutex = &m; + return result; + } + + private: + //! The pointer to the current mutex that is held, or NULL if no mutex is held. + spin_rw_mutex* mutex; + + //! If mutex!=NULL, then is_writer is true if holding a writer lock, false if holding a reader lock. + /** Not defined if not holding a lock. */ + bool is_writer; + }; + +private: + typedef uintptr_t state_t; + static const state_t WRITER = 1; + static const state_t WRITER_PENDING = 2; + static const state_t READERS = ~(WRITER | WRITER_PENDING); + static const state_t ONE_READER = 4; + static const state_t BUSY = WRITER | READERS; + /** Bit 0 = writer is holding lock + Bit 1 = request by a writer to acquire lock (hint to readers to wait) + Bit 2..N = number of readers holding lock */ + volatile state_t state; +}; + +} // namespace tbb + +#endif /* __TBB_spin_rw_mutex_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/task_v2.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/task_v2.cpp new file mode 100644 index 00000000..e49635db --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/task_v2.cpp @@ -0,0 +1,34 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* This compilation unit provides definition of task::destroy( task& ) + that is binary compatible with TBB 2.x. In TBB 3.0, the method became + static, and its name decoration changed, though the definition remained. + + The macro switch should be set prior to including task.h + or any TBB file that might bring task.h up. +*/ +#define __TBB_DEPRECATED_TASK_INTERFACE 1 +#include "tbb/task.h" + +namespace tbb { + +void task::destroy( task& victim ) { + // Forward to static version + task_base::destroy( victim ); +} + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_concurrent_queue_v2.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_concurrent_queue_v2.cpp new file mode 100644 index 00000000..74112757 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_concurrent_queue_v2.cpp @@ -0,0 +1,344 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "old/concurrent_queue_v2.h" +#include "tbb/atomic.h" +#include "tbb/tick_count.h" + +#include "../test/harness_assert.h" +#include "../test/harness.h" + +static tbb::atomic FooConstructed; +static tbb::atomic FooDestroyed; + +enum state_t{ + LIVE=0x1234, + DEAD=0xDEAD +}; + +class Foo { + state_t state; +public: + int thread_id; + int serial; + Foo() : state(LIVE) { + ++FooConstructed; + } + Foo( const Foo& item ) : state(LIVE) { + ASSERT( item.state==LIVE, NULL ); + ++FooConstructed; + thread_id = item.thread_id; + serial = item.serial; + } + ~Foo() { + ASSERT( state==LIVE, NULL ); + ++FooDestroyed; + state=DEAD; + thread_id=DEAD; + serial=DEAD; + } + void operator=( Foo& item ) { + ASSERT( item.state==LIVE, NULL ); + ASSERT( state==LIVE, NULL ); + thread_id = item.thread_id; + serial = item.serial; + } + bool is_const() {return false;} + bool is_const() const {return true;} +}; + +const size_t MAXTHREAD = 256; + +static int Sum[MAXTHREAD]; + +//! Count of various pop operations +/** [0] = pop_if_present that failed + [1] = pop_if_present that succeeded + [2] = pop */ +static tbb::atomic PopKind[3]; + +const int M = 10000; + +struct Body: NoAssign { + tbb::concurrent_queue* queue; + const int nthread; + Body( int nthread_ ) : nthread(nthread_) {} + void operator()( long thread_id ) const { + long pop_kind[3] = {0,0,0}; + int serial[MAXTHREAD+1]; + memset( serial, 0, nthread*sizeof(unsigned) ); + ASSERT( thread_idpop_if_present(f); + ++pop_kind[prepopped]; + } + Foo g; + g.thread_id = thread_id; + g.serial = j+1; + queue->push( g ); + if( !prepopped ) { + queue->pop(f); + ++pop_kind[2]; + } + ASSERT( f.thread_id<=nthread, NULL ); + ASSERT( f.thread_id==nthread || serial[f.thread_id]0, "nthread must be positive" ); + if( prefill+1>=capacity ) + return; + bool success = false; + for( int k=0; k<3; ++k ) + PopKind[k] = 0; + for( int trial=0; !success; ++trial ) { + FooConstructed = 0; + FooDestroyed = 0; + Body body(nthread); + tbb::concurrent_queue queue; + queue.set_capacity( capacity ); + body.queue = &queue; + for( int i=0; i=0; ) { + ASSERT( !queue.empty(), NULL ); + Foo f; + queue.pop(f); + ASSERT( queue.size()==i, NULL ); + sum += f.serial-1; + } + ASSERT( queue.empty(), NULL ); + ASSERT( queue.size()==0, NULL ); + if( sum!=expected ) + printf("sum=%d expected=%d\n",sum,expected); + ASSERT( FooConstructed==FooDestroyed, NULL ); + + success = true; + if( nthread>1 && prefill==0 ) { + // Check that pop_if_present got sufficient exercise + for( int k=0; k<2; ++k ) { +#if (_WIN32||_WIN64) + // The TBB library on Windows seems to have a tough time generating + // the desired interleavings for pop_if_present, so the code tries longer, and settles + // for fewer desired interleavings. + const int max_trial = 100; + const int min_requirement = 20; +#else + const int min_requirement = 100; + const int max_trial = 20; +#endif /* _WIN32||_WIN64 */ + if( PopKind[k]=max_trial ) { + if( Verbose ) + printf("Warning: %d threads had only %ld pop_if_present operations %s after %d trials (expected at least %d). " + "This problem may merely be unlucky scheduling. " + "Investigate only if it happens repeatedly.\n", + nthread, long(PopKind[k]), k==0?"failed":"succeeded", max_trial, min_requirement); + else + printf("Warning: the number of %s pop_if_present operations is less than expected for %d threads. Investigate if it happens repeatedly.\n", + k==0?"failed":"succeeded", nthread ); + } else { + success = false; + } + } + } + } + } +} + +template +void TestIteratorAux( Iterator1 i, Iterator2 j, int size ) { + Iterator1 old_i; // assigned at first iteration below + for( int k=0; k" + ASSERT( k+1==i->serial, NULL ); + if( k&1 ) { + // Test post-increment + Foo f = *old_i++; + ASSERT( k+1==f.serial, NULL ); + // Test assignment + i = old_i; + } else { + // Test pre-increment + if( k +void TestIteratorAssignment( Iterator2 j ) { + Iterator1 i(j); + ASSERT( i==j, NULL ); + ASSERT( !(i!=j), NULL ); + Iterator1 k; + k = j; + ASSERT( k==j, NULL ); + ASSERT( !(k!=j), NULL ); +} + +//! Test the iterators for concurrent_queue +void TestIterator() { + tbb::concurrent_queue queue; + tbb::concurrent_queue& const_queue = queue; + for( int j=0; j<500; ++j ) { + TestIteratorAux( queue.begin(), queue.end(), j ); + TestIteratorAux( const_queue.begin(), const_queue.end(), j ); + TestIteratorAux( const_queue.begin(), queue.end(), j ); + TestIteratorAux( queue.begin(), const_queue.end(), j ); + Foo f; + f.serial = j+1; + queue.push(f); + } + TestIteratorAssignment::const_iterator>( const_queue.begin() ); + TestIteratorAssignment::const_iterator>( queue.begin() ); + TestIteratorAssignment:: iterator>( queue.begin() ); +} + +void TestConcurrentQueueType() { + AssertSameType( tbb::concurrent_queue::value_type(), Foo() ); + Foo f; + const Foo g; + tbb::concurrent_queue::reference r = f; + ASSERT( &r==&f, NULL ); + ASSERT( !r.is_const(), NULL ); + tbb::concurrent_queue::const_reference cr = g; + ASSERT( &cr==&g, NULL ); + ASSERT( cr.is_const(), NULL ); +} + +template +void TestEmptyQueue() { + const tbb::concurrent_queue queue; + ASSERT( queue.size()==0, NULL ); + ASSERT( queue.capacity()>0, NULL ); + ASSERT( size_t(queue.capacity())>=size_t(-1)/(sizeof(void*)+sizeof(T)), NULL ); +} + +void TestFullQueue() { + for( int n=0; n<10; ++n ) { + FooConstructed = 0; + FooDestroyed = 0; + tbb::concurrent_queue queue; + queue.set_capacity(n); + for( int i=0; i<=n; ++i ) { + Foo f; + f.serial = i; + bool result = queue.push_if_not_full( f ); + ASSERT( result==(i +struct TestNegativeQueueBody: NoAssign { + tbb::concurrent_queue& queue; + const int nthread; + TestNegativeQueueBody( tbb::concurrent_queue& q, int n ) : queue(q), nthread(n) {} + void operator()( int k ) const { + if( k==0 ) { + int number_of_pops = nthread-1; + // Wait for all pops to pend. + while( queue.size()>-number_of_pops ) { + __TBB_Yield(); + } + for( int i=0; ; ++i ) { + ASSERT( queue.size()==i-number_of_pops, NULL ); + ASSERT( queue.empty()==(queue.size()<=0), NULL ); + if( i==number_of_pops ) break; + // Satisfy another pop + queue.push( T() ); + } + } else { + // Pop item from queue + T item; + queue.pop(item); + } + } +}; + +//! Test a queue with a negative size. +template +void TestNegativeQueue( int nthread ) { + tbb::concurrent_queue queue; + NativeParallelFor( nthread, TestNegativeQueueBody(queue,nthread) ); +} + +int TestMain () { + TestEmptyQueue(); + TestEmptyQueue(); + TestFullQueue(); + TestConcurrentQueueType(); + TestIterator(); + + // Test concurrent operations + for( int nthread=MinThread; nthread<=MaxThread; ++nthread ) { + TestNegativeQueue(nthread); + for( int prefill=0; prefill<64; prefill+=(1+prefill/3) ) { + TestPushPop(prefill,ptrdiff_t(-1),nthread); + TestPushPop(prefill,ptrdiff_t(1),nthread); + TestPushPop(prefill,ptrdiff_t(2),nthread); + TestPushPop(prefill,ptrdiff_t(10),nthread); + TestPushPop(prefill,ptrdiff_t(100),nthread); + } + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_concurrent_vector_v2.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_concurrent_vector_v2.cpp new file mode 100644 index 00000000..02b8dc75 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_concurrent_vector_v2.cpp @@ -0,0 +1,554 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "concurrent_vector_v2.h" +#include +#include +#include "../test/harness_assert.h" + +tbb::atomic FooCount; + +//! Problem size +const size_t N = 500000; + +struct Foo { + int my_bar; +public: + enum State { + DefaultInitialized=0x1234, + CopyInitialized=0x89ab, + Destroyed=0x5678 + } state; + int& bar() { + ASSERT( state==DefaultInitialized||state==CopyInitialized, NULL ); + return my_bar; + } + int bar() const { + ASSERT( state==DefaultInitialized||state==CopyInitialized, NULL ); + return my_bar; + } + static const int initial_value_of_bar = 42; + Foo() { + state = DefaultInitialized; + ++FooCount; + my_bar = initial_value_of_bar; + } + Foo( const Foo& foo ) { + state = CopyInitialized; + ++FooCount; + my_bar = foo.my_bar; + } + ~Foo() { + ASSERT( state==DefaultInitialized||state==CopyInitialized, NULL ); + state = Destroyed; + my_bar = ~initial_value_of_bar; + --FooCount; + } + bool is_const() const {return true;} + bool is_const() {return false;} +}; + +class FooWithAssign: public Foo { +public: + void operator=( const FooWithAssign& x ) { + ASSERT( x.state==DefaultInitialized||x.state==CopyInitialized, NULL ); + ASSERT( state==DefaultInitialized||state==CopyInitialized, NULL ); + my_bar = x.my_bar; + } +}; + +inline void NextSize( int& s ) { + if( s<=32 ) ++s; + else s += s/10; +} + +static void CheckVector( const tbb::concurrent_vector& cv, size_t expected_size, size_t old_size ) { + ASSERT( cv.size()==expected_size, NULL ); + ASSERT( cv.empty()==(expected_size==0), NULL ); + for( int j=0; j vector_t; + for( int old_size=0; old_size<=128; NextSize( old_size ) ) { + for( int new_size=old_size; new_size<=128; NextSize( new_size ) ) { + long count = FooCount; + vector_t v; + ASSERT( count==FooCount, NULL ); + v.grow_by(old_size); + ASSERT( count+old_size==FooCount, NULL ); + for( int j=0; j vector_t; + vector_t v; + v.reserve( old_size ); + ASSERT( v.capacity()>=old_size, NULL ); + v.reserve( new_size ); + ASSERT( v.capacity()>=old_size, NULL ); + ASSERT( v.capacity()>=new_size, NULL ); + for( size_t i=0; i<2*new_size; ++i ) { + ASSERT( size_t(FooCount)==count+i, NULL ); + size_t j = v.grow_by(1); + ASSERT( j==i, NULL ); + } + } + ASSERT( FooCount==count, NULL ); + } + } +} + +struct AssignElement { + typedef tbb::concurrent_vector::range_type::iterator iterator; + iterator base; + void operator()( const tbb::concurrent_vector::range_type& range ) const { + for( iterator i=range.begin(); i!=range.end(); ++i ) { + if( *i!=0 ) + std::printf("ERROR for v[%ld]\n", long(i-base)); + *i = int(i-base); + } + } + AssignElement( iterator base_ ) : base(base_) {} +}; + +struct CheckElement { + typedef tbb::concurrent_vector::const_range_type::iterator iterator; + iterator base; + void operator()( const tbb::concurrent_vector::const_range_type& range ) const { + for( iterator i=range.begin(); i!=range.end(); ++i ) + if( *i != int(i-base) ) + std::printf("ERROR for v[%ld]\n", long(i-base)); + } + CheckElement( iterator base_ ) : base(base_) {} +}; + +#include "tbb/tick_count.h" +#include "tbb/parallel_for.h" +#include "../test/harness.h" + +//! Test parallel access by iterators +void TestParallelFor( int nthread ) { + typedef tbb::concurrent_vector vector_t; + vector_t v; + v.grow_to_at_least(N); + tbb::tick_count t0 = tbb::tick_count::now(); + if( Verbose ) + std::printf("Calling parallel_for.h with %ld threads\n",long(nthread)); + tbb::parallel_for( v.range(10000), AssignElement(v.begin()) ); + tbb::tick_count t1 = tbb::tick_count::now(); + const vector_t& u = v; + tbb::parallel_for( u.range(10000), CheckElement(u.begin()) ); + tbb::tick_count t2 = tbb::tick_count::now(); + if( Verbose ) + std::printf("Time for parallel_for.h: assign time = %8.5f, check time = %8.5f\n", + (t1-t0).seconds(),(t2-t1).seconds()); + for( long i=0; size_t(i) +void TestIteratorAssignment( Iterator2 j ) { + Iterator1 i(j); + ASSERT( i==j, NULL ); + ASSERT( !(i!=j), NULL ); + Iterator1 k; + k = j; + ASSERT( k==j, NULL ); + ASSERT( !(k!=j), NULL ); +} + +template +void TestIteratorTraits() { + AssertSameType( static_cast(0), static_cast(0) ); + AssertSameType( static_cast(0), static_cast(0) ); + AssertSameType( static_cast(0), static_cast(0) ); + AssertSameType( static_cast(0), static_cast(0) ); + T x; + typename Iterator::reference xr = x; + typename Iterator::pointer xp = &x; + ASSERT( &xr==xp, NULL ); +} + +template +void CheckConstIterator( const Vector& u, int i, const Iterator& cp ) { + typename Vector::const_reference pref = *cp; + if( pref.bar()!=i ) + std::printf("ERROR for u[%ld] using const_iterator\n", long(i)); + typename Vector::difference_type delta = cp-u.begin(); + ASSERT( delta==i, NULL ); + if( u[i].bar()!=i ) + std::printf("ERROR for u[%ld] using subscripting\n", long(i)); + ASSERT( u.begin()[i].bar()==i, NULL ); +} + +template +void CheckIteratorComparison( V& u ) { + Iterator1 i = u.begin(); + for( int i_count=0; i_count<100; ++i_count ) { + Iterator2 j = u.begin(); + for( int j_count=0; j_count<100; ++j_count ) { + ASSERT( (i==j)==(i_count==j_count), NULL ); + ASSERT( (i!=j)==(i_count!=j_count), NULL ); + ASSERT( (i-j)==(i_count-j_count), NULL ); + ASSERT( (ij)==(i_count>j_count), NULL ); + ASSERT( (i<=j)==(i_count<=j_count), NULL ); + ASSERT( (i>=j)==(i_count>=j_count), NULL ); + ++j; + } + ++i; + } +} + +//! Test sequential iterators for vector type V. +/** Also does timing. */ +template +void TestSequentialFor() { + V v; + v.grow_by(N); + + // Check iterator + tbb::tick_count t0 = tbb::tick_count::now(); + typename V::iterator p = v.begin(); + ASSERT( !(*p).is_const(), NULL ); + ASSERT( !p->is_const(), NULL ); + for( int i=0; size_t(i)is_const(), NULL ); + for( int i=0; size_t(i)0; ) { + --i; + --cp; + if( i>0 ) { + typename V::const_iterator cp_old = cp--; + int here = (*cp_old).bar(); + ASSERT( here==u[i].bar(), NULL ); + typename V::const_iterator cp_new = cp++; + int prev = (*cp_new).bar(); + ASSERT( prev==u[i-1].bar(), NULL ); + } + CheckConstIterator(u,i,cp); + } + + // Now go forwards and backwards + cp = u.begin(); + ptrdiff_t k = 0; + for( size_t i=0; i(v); + CheckIteratorComparison(v); + CheckIteratorComparison(v); + CheckIteratorComparison(v); + + TestIteratorAssignment( u.begin() ); + TestIteratorAssignment( v.begin() ); + TestIteratorAssignment( v.begin() ); + + // Check reverse_iterator + typename V::reverse_iterator rp = v.rbegin(); + for( size_t i=v.size(); i>0; --i, ++rp ) { + typename V::reference pref = *rp; + ASSERT( size_t(pref.bar())==i-1, NULL ); + ASSERT( rp!=v.rend(), NULL ); + } + ASSERT( rp==v.rend(), NULL ); + + // Check const_reverse_iterator + typename V::const_reverse_iterator crp = u.rbegin(); + for( size_t i=v.size(); i>0; --i, ++crp ) { + typename V::const_reference cpref = *crp; + ASSERT( size_t(cpref.bar())==i-1, NULL ); + ASSERT( crp!=u.rend(), NULL ); + } + ASSERT( crp==u.rend(), NULL ); + + TestIteratorAssignment( u.rbegin() ); + TestIteratorAssignment( v.rbegin() ); +} + +static const size_t Modulus = 7; + +typedef tbb::concurrent_vector MyVector; + +class GrowToAtLeast { + MyVector& my_vector; +public: + void operator()( const tbb::blocked_range& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + size_t n = my_vector.size(); + size_t k = n==0 ? 0 : i % (2*n+1); + my_vector.grow_to_at_least(k+1); + ASSERT( my_vector.size()>=k+1, NULL ); + } + } + GrowToAtLeast( MyVector& vector ) : my_vector(vector) {} +}; + +void TestConcurrentGrowToAtLeast() { + MyVector v; + for( size_t s=1; s<1000; s*=10 ) { + tbb::parallel_for( tbb::blocked_range(0,1000000,100), GrowToAtLeast(v) ); + } +} + +//! Test concurrent invocations of method concurrent_vector::grow_by +class GrowBy { + MyVector& my_vector; +public: + void operator()( const tbb::blocked_range& range ) const { + for( int i=range.begin(); i!=range.end(); ++i ) { + if( i%3 ) { + Foo& element = my_vector[my_vector.grow_by(1)]; + element.bar() = i; + } else { + Foo f; + f.bar() = i; + size_t k = my_vector.push_back( f ); + ASSERT( my_vector[k].bar()==i, NULL ); + } + } + } + GrowBy( MyVector& vector ) : my_vector(vector) {} +}; + +//! Test concurrent invocations of method concurrent_vector::grow_by +void TestConcurrentGrowBy( int nthread ) { + int m = 100000; + MyVector v; + tbb::parallel_for( tbb::blocked_range(0,m,1000), GrowBy(v) ); + ASSERT( v.size()==size_t(m), NULL ); + + // Verify that v is a permutation of 0..m + int inversions = 0; + bool* found = new bool[m]; + memset( found, 0, m ); + for( int i=0; i0 ) + inversions += v[i].bar()1 || v[i].bar()==i, "sequential execution is wrong" ); + } + delete[] found; + if( nthread>1 && inversions vector_t; + for( int dst_size=1; dst_size<=128; NextSize( dst_size ) ) { + for( int src_size=2; src_size<=128; NextSize( src_size ) ) { + vector_t u; + u.grow_to_at_least(src_size); + for( int i=0; i + +typedef unsigned long Number; + +static tbb::concurrent_vector Primes; + +class FindPrimes { + bool is_prime( Number val ) const { + int limit, factor = 3; + if( val<5u ) + return val==2; + else { + limit = long(sqrtf(float(val))+0.5f); + while( factor<=limit && val % factor ) + ++factor; + return factor>limit; + } + } +public: + void operator()( const tbb::blocked_range& r ) const { + for( Number i=r.begin(); i!=r.end(); ++i ) { + if( i%2 && is_prime(i) ) { + Primes[Primes.grow_by(1)] = i; + } + } + } +}; + +static double TimeFindPrimes( int nthread ) { + Primes.clear(); + tbb::task_scheduler_init init(nthread); + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for( tbb::blocked_range(0,1000000,500), FindPrimes() ); + tbb::tick_count t1 = tbb::tick_count::now(); + return (t1-t0).seconds(); +} + +static void TestFindPrimes() { + // Time fully subscribed run. + double t2 = TimeFindPrimes( tbb::task_scheduler_init::automatic ); + + // Time parallel run that is very likely oversubscribed. + double t128 = TimeFindPrimes(128); + + if( Verbose ) + std::printf("TestFindPrimes: t2==%g t128=%g\n", t2, t128 ); + + // We allow the 128-thread run a little extra time to allow for thread overhead. + // Theoretically, following test will fail on machine with >128 processors. + // But that situation is not going to come up in the near future, + // and the generalization to fix the issue is not worth the trouble. + if( t128>1.10*t2 ) { + std::printf("Warning: grow_by is pathetically slow: t2==%g t128=%g\n", t2, t128); + } +} + +//------------------------------------------------------------------------ +// Test compatibility with STL sort. +//------------------------------------------------------------------------ + +#include + +void TestSort() { + for( int n=1; n<100; n*=3 ) { + tbb::concurrent_vector array; + array.grow_by( n ); + for( int i=0; i::iterator,Foo>(); + TestIteratorTraits::const_iterator,const Foo>(); + TestSequentialFor > (); + TestResizeAndCopy(); + TestAssign(); + TestCapacity(); + for( int nthread=MinThread; nthread<=MaxThread; ++nthread ) { + tbb::task_scheduler_init init( nthread ); + TestParallelFor( nthread ); + TestConcurrentGrowToAtLeast(); + TestConcurrentGrowBy( nthread ); + } + TestFindPrimes(); + TestSort(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_mutex_v2.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_mutex_v2.cpp new file mode 100644 index 00000000..b550d302 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_mutex_v2.cpp @@ -0,0 +1,238 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 1 +#define HARNESS_DEFAULT_MAX_THREADS 3 + +//------------------------------------------------------------------------ +// Test TBB mutexes when used with parallel_for.h +// +// Usage: test_Mutex.exe [-v] nthread +// +// The -v option causes timing information to be printed. +// +// Compile with _OPENMP and -openmp +//------------------------------------------------------------------------ +#include "../test/harness_defs.h" +#include "tbb/atomic.h" +#include "tbb/blocked_range.h" +#include "tbb/parallel_for.h" +#include "tbb/tick_count.h" +#include "../test/harness.h" +#include "spin_rw_mutex_v2.h" +#include +#include + +// This test deliberately avoids a "using tbb" statement, +// so that the error of putting types in the wrong namespace will be caught. + +template +struct Counter { + typedef M mutex_type; + M mutex; + volatile long value; +}; + +//! Function object for use with parallel_for.h. +template +struct AddOne: NoAssign { + C& counter; + /** Increments counter once for each iteration in the iteration space. */ + void operator()( tbb::blocked_range& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + if( i&1 ) { + // Try implicit acquire and explicit release + typename C::mutex_type::scoped_lock lock(counter.mutex); + counter.value = counter.value+1; + lock.release(); + } else { + // Try explicit acquire and implicit release + typename C::mutex_type::scoped_lock lock; + lock.acquire(counter.mutex); + counter.value = counter.value+1; + } + } + } + AddOne( C& counter_ ) : counter(counter_) {} +}; + +//! Generic test of a TBB mutex type M. +/** Does not test features specific to reader-writer locks. */ +template +void Test( const char * name ) { + if( Verbose ) { + printf("%s time = ",name); + fflush(stdout); + } + Counter counter; + counter.value = 0; + const int n = 100000; + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for(tbb::blocked_range(0,n,n/10),AddOne >(counter)); + tbb::tick_count t1 = tbb::tick_count::now(); + if( Verbose ) + printf("%g usec\n",(t1-t0).seconds()); + if( counter.value!=n ) + printf("ERROR for %s: counter.value=%ld\n",name,counter.value); +} + +template +struct Invariant { + typedef M mutex_type; + M mutex; + const char* mutex_name; + volatile long value[N]; + Invariant( const char* mutex_name_ ) : + mutex_name(mutex_name_) + { + for( size_t k=0; k +struct TwiddleInvariant: NoAssign { + I& invariant; + TwiddleInvariant( I& invariant_ ) : invariant(invariant_) {} + + /** Increments counter once for each iteration in the iteration space. */ + void operator()( tbb::blocked_range& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + //! Every 8th access is a write access + const bool write = (i%8)==7; + bool okay = true; + bool lock_kept = true; + if( (i/8)&1 ) { + // Try implicit acquire and explicit release + typename I::mutex_type::scoped_lock lock(invariant.mutex,write); + execute_aux(lock, i, write, okay, lock_kept); + lock.release(); + } else { + // Try explicit acquire and implicit release + typename I::mutex_type::scoped_lock lock; + lock.acquire(invariant.mutex,write); + execute_aux(lock, i, write, okay, lock_kept); + } + if( !okay ) { + printf( "ERROR for %s at %ld: %s %s %s %s\n",invariant.mutex_name, long(i), + write ? "write," : "read,", + write ? (i%16==7?"downgrade,":"") : (i%8==3?"upgrade,":""), + lock_kept ? "lock kept," : "lock not kept,", // TODO: only if downgrade/upgrade + (i/8)&1 ? "impl/expl" : "expl/impl" ); + } + } + } +private: + void execute_aux(typename I::mutex_type::scoped_lock & lock, const size_t i, const bool write, bool & okay, bool & lock_kept) const { + if( write ) { + long my_value = invariant.value[0]; + invariant.update(); + if( i%16==7 ) { + lock_kept = lock.downgrade_to_reader(); + if( !lock_kept ) + my_value = invariant.value[0] - 1; + okay = invariant.value_is(my_value+1); + } + } else { + okay = invariant.is_okay(); + if( i%8==3 ) { + long my_value = invariant.value[0]; + lock_kept = lock.upgrade_to_writer(); + if( !lock_kept ) + my_value = invariant.value[0]; + invariant.update(); + okay = invariant.value_is(my_value+1); + } + } + } +}; + +/** This test is generic so that we can test any other kinds of ReaderWriter locks we write later. */ +template +void TestReaderWriterLock( const char * mutex_name ) { + if( Verbose ) { + printf("%s readers & writers time = ",mutex_name); + fflush(stdout); + } + Invariant invariant(mutex_name); + const size_t n = 500000; + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for(tbb::blocked_range(0,n,n/100),TwiddleInvariant >(invariant)); + tbb::tick_count t1 = tbb::tick_count::now(); + // There is either a writer or a reader upgraded to a writer for each 4th iteration + long expected_value = n/4; + if( !invariant.value_is(expected_value) ) + printf("ERROR for %s: final invariant value is wrong\n",mutex_name); + if( Verbose ) + printf("%g usec\n", (t1-t0).seconds()); +} + +/** Test try_acquire functionality of a non-reenterable mutex */ +template +void TestTryAcquire_OneThread( const char * mutex_name ) { + M tested_mutex; + typename M::scoped_lock lock1; + if( lock1.try_acquire(tested_mutex) ) + lock1.release(); + else + printf("ERROR for %s: try_acquire failed though it should not\n", mutex_name); + { + typename M::scoped_lock lock2(tested_mutex); + if( lock1.try_acquire(tested_mutex) ) + printf("ERROR for %s: try_acquire succeeded though it should not\n", mutex_name); + } + if( lock1.try_acquire(tested_mutex) ) + lock1.release(); + else + printf("ERROR for %s: try_acquire failed though it should not\n", mutex_name); +} + +#include "tbb/task_scheduler_init.h" + +int TestMain () { + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init( p ); + if( Verbose ) + printf( "testing with %d workers\n", static_cast(p) ); + const int n = 3; + // Run each test several times. + for( int i=0; i( "Spin RW Mutex" ); + TestTryAcquire_OneThread("Spin RW Mutex"); // only tests try_acquire for writers + TestReaderWriterLock( "Spin RW Mutex" ); + } + if( Verbose ) + printf( "calling destructor for task_scheduler_init\n" ); + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_task_scheduler_observer_v3.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_task_scheduler_observer_v3.cpp new file mode 100644 index 00000000..732e4b7e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/old/test_task_scheduler_observer_v3.cpp @@ -0,0 +1,117 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define __TBB_ARENA_OBSERVER 0 +#include "tbb/task_scheduler_observer.h" + +typedef uintptr_t FlagType; +const int MaxFlagIndex = sizeof(FlagType)*8-1; + +class MyObserver: public tbb::task_scheduler_observer { + FlagType flags; + void on_scheduler_entry( bool is_worker ) __TBB_override; + void on_scheduler_exit( bool is_worker ) __TBB_override; +public: + MyObserver( FlagType flags_ ) : flags(flags_) { + observe(true); + } +}; + +#include "harness_assert.h" +#include "tbb/atomic.h" + +tbb::atomic EntryCount; +tbb::atomic ExitCount; + +struct State { + FlagType MyFlags; + bool IsMaster; + State() : MyFlags(), IsMaster() {} +}; + +#include "../tbb/tls.h" +tbb::internal::tls LocalState; + +void MyObserver::on_scheduler_entry( bool is_worker ) { + State& state = *LocalState; + ASSERT( is_worker==!state.IsMaster, NULL ); + ++EntryCount; + state.MyFlags |= flags; +} + +void MyObserver::on_scheduler_exit( bool is_worker ) { + State& state = *LocalState; + ASSERT( is_worker==!state.IsMaster, NULL ); + ++ExitCount; + state.MyFlags &= ~flags; +} + +#include "tbb/task.h" + +class FibTask: public tbb::task { + const int n; + FlagType flags; +public: + FibTask( int n_, FlagType flags_ ) : n(n_), flags(flags_) {} + tbb::task* execute() __TBB_override { + ASSERT( !(~LocalState->MyFlags & flags), NULL ); + if( n>=2 ) { + set_ref_count(3); + spawn(*new( allocate_child() ) FibTask(n-1,flags)); + spawn_and_wait_for_all(*new( allocate_child() ) FibTask(n-2,flags)); + } + return NULL; + } +}; + +void DoFib( FlagType flags ) { + tbb::task* t = new( tbb::task::allocate_root() ) FibTask(10,flags); + tbb::task::spawn_root_and_wait(*t); +} + +#include "tbb/task_scheduler_init.h" +#include "harness.h" + +class DoTest { + int nthread; +public: + DoTest( int n ) : nthread(n) {} + void operator()( int i ) const { + LocalState->IsMaster = true; + if( i==0 ) { + tbb::task_scheduler_init init(nthread); + DoFib(0); + } else { + FlagType f = i<=MaxFlagIndex? 1<0, "on_scheduler_entry not exercised" ); + ASSERT( ExitCount>0, "on_scheduler_exit not exercised" ); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/coarse_grained_raii_lru_cache.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/coarse_grained_raii_lru_cache.h new file mode 100644 index 00000000..019a6da0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/coarse_grained_raii_lru_cache.h @@ -0,0 +1,143 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef coarse_grained_raii_lru_cache_H +#define coarse_grained_raii_lru_cache_H + +#include +#include +#include +#include + +#include "tbb/spin_mutex.h" +#include "tbb/tbb_stddef.h" +template +class coarse_grained_raii_lru_cache : tbb::internal::no_assign{ + typedef value_functor_type value_function_type; + + typedef std::size_t ref_counter_type; + struct map_value_type; + typedef std::map map_storage_type; + typedef std::list lru_list_type; + struct map_value_type { + value_type my_value; + ref_counter_type my_ref_counter; + typename lru_list_type::iterator my_lru_list_iterator; + bool my_is_ready; + + map_value_type (value_type const& a_value, ref_counter_type a_ref_counter, typename lru_list_type::iterator a_lru_list_iterator, bool a_is_ready) + : my_value(a_value), my_ref_counter(a_ref_counter), my_lru_list_iterator (a_lru_list_iterator) + ,my_is_ready(a_is_ready) + {} + }; + + class handle_object; +public: + typedef handle_object handle; + + coarse_grained_raii_lru_cache(value_function_type f, std::size_t number_of_lru_history_items): my_value_function(f),my_number_of_lru_history_items(number_of_lru_history_items){} + handle_object operator[](key_type k){ + tbb::spin_mutex::scoped_lock lock(my_mutex); + bool is_new_value_needed = false; + typename map_storage_type::iterator it = my_map_storage.find(k); + if (it == my_map_storage.end()){ + it = my_map_storage.insert(it,std::make_pair(k,map_value_type(value_type(),0,my_lru_list.end(),false))); + is_new_value_needed = true; + }else { + typename lru_list_type::iterator list_it = it->second.my_lru_list_iterator; + if (list_it!=my_lru_list.end()) { + my_lru_list.erase(list_it); + it->second.my_lru_list_iterator= my_lru_list.end(); + } + } + typename map_storage_type::reference value_ref = *it; + //increase ref count + ++(value_ref.second.my_ref_counter); + if (is_new_value_needed){ + lock.release(); + value_ref.second.my_value = my_value_function(k); + __TBB_store_with_release(value_ref.second.my_is_ready, true); + + }else{ + if (!value_ref.second.my_is_ready){ + lock.release(); + tbb::internal::spin_wait_while_eq(value_ref.second.my_is_ready,false); + } + } + return handle_object(*this,(value_ref)); + } +private: + void signal_end_of_usage(typename map_storage_type::reference value_ref){ + tbb::spin_mutex::scoped_lock lock(my_mutex); + typename map_storage_type::iterator it = my_map_storage.find(value_ref.first); + __TBB_ASSERT(it!=my_map_storage.end(),"cache should not return past-end iterators to outer world"); + __TBB_ASSERT(&(*it) == &value_ref,"dangling reference has been returned to outside world? data race ?"); + __TBB_ASSERT( my_lru_list.end()== std::find(my_lru_list.begin(),my_lru_list.end(),it), + "object in use should not be in list of unused objects "); + if (! --(it->second.my_ref_counter)){ //decrease ref count, and check if it was the last reference + if (my_lru_list.size()>=my_number_of_lru_history_items){ + size_t number_of_elements_to_evict = 1 + my_lru_list.size() - my_number_of_lru_history_items; + for (size_t i=0; isecond.my_lru_list_iterator = my_lru_list.begin(); + } + } +private: + value_function_type my_value_function; + std::size_t const my_number_of_lru_history_items; + map_storage_type my_map_storage; + lru_list_type my_lru_list; + tbb::spin_mutex my_mutex; +private: + struct handle_move_t:tbb::internal::no_assign{ + coarse_grained_raii_lru_cache & my_cache_ref; + typename map_storage_type::reference my_value_ref; + handle_move_t(coarse_grained_raii_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_ref(cache_ref),my_value_ref(value_ref) {}; + }; + class handle_object { + coarse_grained_raii_lru_cache * my_cache_pointer; + typename map_storage_type::reference my_value_ref; + public: + handle_object(coarse_grained_raii_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_pointer(&cache_ref), my_value_ref(value_ref) {} + handle_object(handle_move_t m):my_cache_pointer(&m.my_cache_ref), my_value_ref(m.my_value_ref){} + operator handle_move_t(){ return move(*this);} + value_type& value(){return my_value_ref.second.my_value;} + ~handle_object(){ + if (my_cache_pointer){ + my_cache_pointer->signal_end_of_usage(my_value_ref); + } + } + private: + friend handle_move_t move(handle_object& h){ + return handle_object::move(h); + } + static handle_move_t move(handle_object& h){ + __TBB_ASSERT(h.my_cache_pointer,"move from the same object twice ?"); + coarse_grained_raii_lru_cache * cache_pointer = NULL; + std::swap(cache_pointer,h.my_cache_pointer); + return handle_move_t(*cache_pointer,h.my_value_ref); + } + private: + void operator=(handle_object&); + handle_object(handle_object &); + }; +}; +#endif //coarse_grained_raii_lru_cache_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/cpq_pdes.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/cpq_pdes.cpp new file mode 100644 index 00000000..56645129 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/cpq_pdes.cpp @@ -0,0 +1,226 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include +#include +#include +#include "tbb/tbb_stddef.h" +#include "tbb/spin_mutex.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/tick_count.h" +#include "tbb/blocked_range.h" +#include "../test/harness.h" +#include "tbb/concurrent_priority_queue.h" + +#pragma warning(disable: 4996) + +#define IMPL_STL 0 +#define IMPL_CPQ 1 + +using namespace tbb; + +//const int contention = 75; // degree contention. 100 = 0 us busy_wait, 50 = 50*contention_unit us +const double contention_unit = 0.025; // in microseconds (us) +const double throughput_window = 30; // in seconds +const int num_initial_events = 10000; // number of initial events in the queue +const int min_elapse = 20; // min contention_units to elapse between event spawns +const int max_elapse = 40; // max contention_units to elapse between event spawns +const int min_spawn = 0; // min number of events to spawn +const int max_spawn = 2; // max number of events to spawn + +tbb::atomic operation_count; +tbb::tick_count start; +bool done; + +class event { +public: + int timestamp; + int elapse; + int spawn; +}; + +class timestamp_compare { +public: + bool operator()(event e1, event e2) { + return e2.timestamp, timestamp_compare > *stl_cpq; +concurrent_priority_queue *lfc_pq; + +unsigned int one_us_iters = 429; // default value + +// if user wants to calibrate to microseconds on particular machine, call this at beginning of program +// sets one_us_iters to number of iters to busy_wait for approx. 1 us +void calibrate_busy_wait() { + const unsigned niter = 1000000; + tbb::tick_count t0 = tbb::tick_count::now(); + for (volatile unsigned int i=0; ipush(elem); + } + else { + tbb::spin_mutex::scoped_lock myLock(*my_mutex); + stl_cpq->push(elem); + } + } + else { + lfc_pq->push(elem); + } +} + +bool do_pop(event& elem, int nThr, int impl) { + if (impl == IMPL_STL) { + if (nThr == 1) { + if (!stl_cpq->empty()) { + elem = stl_cpq->top(); + stl_cpq->pop(); + return true; + } + } + else { + tbb::spin_mutex::scoped_lock myLock(*my_mutex); + if (!stl_cpq->empty()) { + elem = stl_cpq->top(); + stl_cpq->pop(); + return true; + } + } + } + else { + if (lfc_pq->try_pop(elem)) { + return true; + } + } + return false; +} + +struct TestPDESloadBody : NoAssign { + int nThread; + int implementation; + + TestPDESloadBody(int nThread_, int implementation_) : + nThread(nThread_), implementation(implementation_) {} + + void operator()(const int threadID) const { + if (threadID == nThread) { + sleep(throughput_window); + done = true; + } + else { + event e, tmp; + unsigned int num_operations = 0; + for (;;) { + // pop an event + if (do_pop(e, nThread, implementation)) { + num_operations++; + // do the event + busy_wait(e.elapse*contention_unit); + while (e.spawn > 0) { + tmp.spawn = ((e.spawn+1-min_spawn) % ((max_spawn-min_spawn)+1))+min_spawn; + tmp.timestamp = e.timestamp + e.elapse; + e.timestamp = tmp.timestamp; + e.elapse = ((e.elapse+1-min_elapse) % ((max_elapse-min_elapse)+1))+min_elapse; + tmp.elapse = e.elapse; + do_push(tmp, nThread, implementation); + num_operations++; + e.spawn--; + busy_wait(e.elapse*contention_unit); + if (done) break; + } + } + if (done) break; + } + operation_count += num_operations; + } + } +}; + +void preload_queue(int nThr, int impl) { + event an_event; + for (int i=0; i, timestamp_compare >; + preload_queue(nThreads, IMPL_STL); + TestPDESloadBody my_stl_test(nThreads, IMPL_STL); + start = tbb::tick_count::now(); + NativeParallelFor(nThreads+1, my_stl_test); + delete stl_cpq; + + REPORT(" %10d", operation_count/throughput_window); + + operation_count = 0; + done = false; + lfc_pq = new concurrent_priority_queue; + preload_queue(nThreads, IMPL_CPQ); + TestPDESloadBody my_cpq_test(nThreads, IMPL_CPQ); + start = tbb::tick_count::now(); + NativeParallelFor(nThreads+1, my_cpq_test); + delete lfc_pq; + + REPORT(" %10d\n", operation_count/throughput_window); +} + +int TestMain() { + srand(42); + if (MinThread < 1) + MinThread = 1; + //calibrate_busy_wait(); + cache_aligned_allocator my_mutex_allocator; + my_mutex = (spin_mutex *)my_mutex_allocator.allocate(1); + + REPORT("#Thr "); + REPORT("STL "); +#ifdef LINEARIZABLE + REPORT("CPQ_L\n"); +#else + REPORT("CPQ_N\n"); +#endif + for (int p = MinThread; p <= MaxThread; ++p) { + TestPDESload(p); + } + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/fibonacci_impl_tbb.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/fibonacci_impl_tbb.cpp new file mode 100644 index 00000000..0c54d0cd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/fibonacci_impl_tbb.cpp @@ -0,0 +1,74 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include +#include + +#include "tbb/task_scheduler_init.h" +#include "tbb/task.h" +#include "tbb/tick_count.h" + +extern long CutOff; + +long SerialFib( const long n ) { + if( n<2 ) + return n; + else + return SerialFib(n-1)+SerialFib(n-2); +} + +struct FibContinuation: public tbb::task { + long* const sum; + long x, y; + FibContinuation( long* sum_ ) : sum(sum_) {} + tbb::task* execute() { + *sum = x+y; + return NULL; + } +}; + +struct FibTask: public tbb::task { + long n; + long * sum; + FibTask( const long n_, long * const sum_ ) : + n(n_), sum(sum_) + {} + tbb::task* execute() { + if( n +#include + +namespace harness_perf { + +template +typename InputIterator::value_type median(InputIterator first, InputIterator last) { + std::sort(first, last); + typename InputIterator::difference_type distance = std::distance(first, last); + std::advance(first, distance / 2 - 1); + if (distance % 2 == 0) + return typename InputIterator::value_type((*first + *(++first)) / 2); + else + return typename InputIterator::value_type(*first); +} + +} // namespace harness_perf + +#endif // !__TBB_HARNESS_PERF + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf.cpp new file mode 100644 index 00000000..b7925770 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf.cpp @@ -0,0 +1,856 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "perf.h" + +#include +#include +#include +#include +#include + +#include "tbb/tick_count.h" + +#define HARNESS_CUSTOM_MAIN 1 +#include "../src/test/harness.h" +#include "../src/test/harness_barrier.h" + +#include "tbb/task_scheduler_init.h" +#include "tbb/task.h" +#include "tbb/atomic.h" + +#if __linux__ || __APPLE__ || __FreeBSD__ || __NetBSD__ + #include +#endif + +__TBB_PERF_API int NumCpus = tbb::task_scheduler_init::default_num_threads(), + NumThreads, + MaxConcurrency; + +namespace Perf { + +SessionSettings theSettings; + +namespace internal { + + typedef std::vector durations_t; + + static uintptr_t NumRuns = 7; + static duration_t RunDuration = 0.01; + + static const int RateFieldLen = 10; + static const int OvhdFieldLen = 12; + + const char* TestNameColumnTitle = "Test name"; + const char* WorkloadNameColumnTitle = "Workload"; + + size_t TitleFieldLen = 0; + size_t WorkloadFieldLen = 0; + + int TotalConfigs = 0; + int MaxTbbMasters = 1; + + //! Defines the mapping between threads and cores in the undersubscription mode + /** When adding new enumerator, insert it before amLast, and do not specify + its value explicitly. **/ + enum AffinitizationMode { + amFirst = 0, + amDense = amFirst, + amSparse, + //! Used to track the number of supported affinitization modes + amLast + }; + + static const int NumAffinitizationModes = amLast - amFirst; + + const char* AffinitizationModeNames[] = { "dense", "sparse" }; + + int NumActiveAffModes = 1; + + //! Settings of a test run configuration + struct RunConfig { + int my_maxConcurrency; + int my_numThreads; // For task scheduler tests this is number of workers + 1 + int my_numMasters; // Used for task scheduler tests only + int my_affinityMode; // Used for task scheduler tests only + int my_workloadID; + + int NumMasters () const { + return theSettings.my_opts & UseTaskScheduler ? my_numMasters : my_numThreads; + } + }; + + double StandardDeviation ( double avg, const durations_t& d ) { + double std_dev = 0; + for ( uintptr_t i = 0; i < d.size(); ++i ) { + double dev = fabs(d[i] - avg); + std_dev += dev * dev; + } + std_dev = sqrt(std_dev / d.size()); + return std_dev / avg * 100; + } + + void Statistics ( const durations_t& d, + duration_t& avgTime, double& stdDev, + duration_t& minTime, duration_t& maxTime ) + { + minTime = maxTime = avgTime = d[0]; + for ( size_t i = 1; i < d.size(); ++i ) { + avgTime += d[i]; + if ( minTime > d[i] ) + minTime = d[i]; + else if ( maxTime < d[i] ) + maxTime = d[i]; + } + avgTime = avgTime / d.size(); + stdDev = StandardDeviation( avgTime, d ); + } + + //! Timing data for the series of repeated runs and results of their statistical processing + struct TimingSeries { + //! Statistical timing series + durations_t my_durations; + + //! Average time obtained from my_durations data + duration_t my_avgTime; + + //! Minimal time obtained from my_durations data + duration_t my_minTime; + + //! Minimal time obtained from my_durations data + duration_t my_maxTime; + + //! Standard deviation of my_avgTime value (per cent) + double my_stdDev; + + TimingSeries ( uintptr_t nruns = NumRuns ) + : my_durations(nruns), my_avgTime(0), my_minTime(0), my_maxTime(0) + {} + + void CalculateStatistics () { + Statistics( my_durations, my_avgTime, my_stdDev, my_minTime, my_maxTime ); + } + }; // struct TimingSeries + + //! Settings and timing results for a test run configuration + struct RunResults { + //! Run configuration settings + RunConfig my_config; + + //! Timing results for this run configuration + TimingSeries my_timing; + }; + + typedef std::vector names_t; + typedef std::vector timings_t; + typedef std::vector test_results_t; + + enum TestMethods { + idRunSerial = 0x01, + idOnStart = 0x02, + idOnFinish = 0x04, + idPrePostProcess = idOnStart | idOnFinish + }; + + //! Set of flags identifying methods not overridden by the currently active test + /** Used as a scratch var. **/ + uintptr_t g_absentMethods; + + //! Test object and timing results for all of its configurations + struct TestResults { + //! Pointer to the test object interface + Test* my_test; + + //! Set of flags identifying optional methods overridden by my_test + /** A set of ORed TestMethods flags **/ + uintptr_t my_availableMethods; + + //! Vector of serial times for each workload supported by this test + /** Element index in the vector serves as a zero based workload ID. **/ + timings_t my_serialBaselines; + + //! Common baselines for both parallel and serial variants + /** Element index in the vector serves as a zero based workload ID. **/ + timings_t my_baselines; + + //! Strings identifying workloads to be used in output + names_t my_workloadNames; + + //! Vector of timings for all run configurations of my_test + test_results_t my_results; + + const char* my_testName; + + mutable bool my_hasOwnership; + + TestResults ( Test* t, const char* className, bool takeOwnership ) + : my_test(t), my_availableMethods(0), my_testName(className), my_hasOwnership(takeOwnership) + {} + + TestResults ( const TestResults& tr ) + : my_test(tr.my_test) + , my_availableMethods(0) + , my_testName(tr.my_testName) + , my_hasOwnership(tr.my_hasOwnership) + { + tr.my_hasOwnership = false; + } + + ~TestResults () { + for ( size_t i = 0; i < my_workloadNames.size(); ++i ) + delete my_workloadNames[i]; + if ( my_hasOwnership ) + delete my_test; + } + }; // struct TestResults + + typedef std::vector session_t; + + session_t theSession; + + TimingSeries CalibrationTiming; + + const uintptr_t CacheSize = 8*1024*1024; + volatile intptr_t W[CacheSize]; + + struct WiperBody { + void operator()( int ) const { + volatile intptr_t sink = 0; + for ( uintptr_t i = 0; i < CacheSize; ++i ) + sink += W[i]; + } + }; + + void TraceHistogram ( const durations_t& t, const char* histogramFileName ) { + FILE* f = histogramFileName ? fopen(histogramFileName, "wt") : stdout; + uintptr_t n = t.size(); + const uintptr_t num_buckets = 100; + double min_val = *std::min_element(t.begin(), t.end()), + max_val = *std::max_element(t.begin(), t.end()), + bucket_size = (max_val - min_val) / num_buckets; + std::vector hist(num_buckets + 1, 0); + for ( uintptr_t i = 0; i < n; ++i ) + ++hist[uintptr_t((t[i]-min_val)/bucket_size)]; + ASSERT (hist[num_buckets] == 1, ""); + ++hist[num_buckets - 1]; + hist.resize(num_buckets); + fprintf (f, "Histogram: nvals = %u, min = %g, max = %g, nbuckets = %u\n", (unsigned)n, min_val, max_val, (unsigned)num_buckets); + double bucket = min_val; + for ( uintptr_t i = 0; i < num_buckets; ++i, bucket+=bucket_size ) + fprintf (f, "%12g\t%u\n", bucket, (unsigned)hist[i]); + fclose(f); + } + +#if _MSC_VER + typedef DWORD_PTR cpu_set_t; + + class AffinityHelper { + static const unsigned MaxAffinitySetSize = sizeof(cpu_set_t) * 8; + static unsigned AffinitySetSize; + + //! Mapping from a CPU index to a valid affinity cpu_mask + /** The first element is not used. **/ + static cpu_set_t m_affinities[MaxAffinitySetSize + 1]; + + static cpu_set_t m_processMask; + + class Initializer { + public: + Initializer () { + SYSTEM_INFO si; + GetNativeSystemInfo(&si); + ASSERT( si.dwNumberOfProcessors <= MaxAffinitySetSize, "Too many CPUs" ); + AffinitySetSize = min (si.dwNumberOfProcessors, MaxAffinitySetSize); + cpu_set_t systemMask = 0; + GetProcessAffinityMask( GetCurrentProcess(), &m_processMask, &systemMask ); + cpu_set_t cpu_mask = 1; + for ( DWORD i = 0; i < AffinitySetSize; ++i ) { + while ( !(cpu_mask & m_processMask) && cpu_mask ) + cpu_mask <<= 1; + ASSERT( cpu_mask != 0, "Process affinity set is culled?" ); + m_affinities[i] = cpu_mask; + cpu_mask <<= 1; + } + } + }; // class AffinityHelper::Initializer + + static Initializer m_initializer; + + public: + static cpu_set_t CpuAffinity ( int cpuIndex ) { + return m_affinities[cpuIndex % AffinitySetSize]; + } + + static const cpu_set_t& ProcessMask () { return m_processMask; } + }; // class AffinityHelper + + unsigned AffinityHelper::AffinitySetSize = 0; + cpu_set_t AffinityHelper::m_affinities[AffinityHelper::MaxAffinitySetSize + 1] = {0}; + cpu_set_t AffinityHelper::m_processMask = 0; + AffinityHelper::Initializer AffinityHelper::m_initializer; + + #define CPU_ZERO(cpu_mask) (*cpu_mask = 0) + #define CPU_SET(cpu_idx, cpu_mask) (*cpu_mask |= AffinityHelper::CpuAffinity(cpu_idx)) + #define CPU_CLR(cpu_idx, cpu_mask) (*cpu_mask &= ~AffinityHelper::CpuAffinity(cpu_idx)) + #define CPU_ISSET(cpu_idx, cpu_mask) ((*cpu_mask & AffinityHelper::CpuAffinity(cpu_idx)) != 0) + +#elif __linux__ /* end of _MSC_VER */ + + #include + #include + #include + + pid_t gettid() { return (pid_t)syscall(__NR_gettid); } + + #define GET_MASK(cpu_set) (*(unsigned*)(void*)&cpu_set) + #define RES_STAT(res) (res != 0 ? "failed" : "ok") + + class AffinityHelper { + static cpu_set_t m_processMask; + + class Initializer { + public: + Initializer () { + CPU_ZERO (&m_processMask); + int res = sched_getaffinity( getpid(), sizeof(cpu_set_t), &m_processMask ); + ASSERT ( res == 0, "sched_getaffinity failed" ); + } + }; // class AffinityHelper::Initializer + + static Initializer m_initializer; + + public: + static const cpu_set_t& ProcessMask () { return m_processMask; } + }; // class AffinityHelper + + cpu_set_t AffinityHelper::m_processMask; + AffinityHelper::Initializer AffinityHelper::m_initializer; +#endif /* __linux__ */ + + bool PinTheThread ( int cpu_idx, tbb::atomic& nThreads ) { + #if _MSC_VER || __linux__ + cpu_set_t orig_mask, target_mask; + CPU_ZERO( &target_mask ); + CPU_SET( cpu_idx, &target_mask ); + ASSERT ( CPU_ISSET(cpu_idx, &target_mask), "CPU_SET failed" ); + #endif + #if _MSC_VER + orig_mask = SetThreadAffinityMask( GetCurrentThread(), target_mask ); + if ( !orig_mask ) + return false; + #elif __linux__ + CPU_ZERO( &orig_mask ); + int res = sched_getaffinity( gettid(), sizeof(cpu_set_t), &orig_mask ); + ASSERT ( res == 0, "sched_getaffinity failed" ); + res = sched_setaffinity( gettid(), sizeof(cpu_set_t), &target_mask ); + ASSERT ( res == 0, "sched_setaffinity failed" ); + #endif /* _MSC_VER */ + --nThreads; + while ( nThreads ) + __TBB_Yield(); + #if _MSC_VER + SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_HIGHEST); + #endif + return true; + } + + class AffinitySetterTask : tbb::task { + static bool m_result; + static tbb::atomic m_nThreads; + int m_idx; + + tbb::task* execute () { + //TestAffinityOps(); + m_result = PinTheThread( m_idx, m_nThreads ); + return NULL; + } + + public: + AffinitySetterTask ( int idx ) : m_idx(idx) {} + + friend bool AffinitizeTBB ( int, int /*mode*/ ); + }; + + bool AffinitySetterTask::m_result = true; + tbb::atomic AffinitySetterTask::m_nThreads; + + bool AffinitizeTBB ( int p, int affMode ) { + #if _MSC_VER + SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_HIGHEST); + SetPriorityClass (GetCurrentProcess(), HIGH_PRIORITY_CLASS); + #endif + AffinitySetterTask::m_result = true; + AffinitySetterTask::m_nThreads = p; + tbb::task_list tl; + for ( int i = 0; i < p; ++i ) { + tbb::task &t = *new( tbb::task::allocate_root() ) AffinitySetterTask( affMode == amSparse ? i * NumCpus / p : i ); + t.set_affinity( tbb::task::affinity_id(i + 1) ); + tl.push_back( t ); + } + tbb::task::spawn_root_and_wait(tl); + return AffinitySetterTask::m_result; + } + + inline + void Affinitize ( int p, int affMode ) { + if ( !AffinitizeTBB (p, affMode) ) + REPORT("Warning: Failed to set affinity for %d TBB threads\n", p); + } + + class TbbWorkersTrapper { + tbb::atomic my_refcount; + tbb::task *my_root; + tbb::task_group_context my_context; + Harness::SpinBarrier my_barrier; + + friend class TrapperTask; + + class TrapperTask : public tbb::task { + TbbWorkersTrapper& my_owner; + + tbb::task* execute () { + my_owner.my_barrier.wait(); + my_owner.my_root->wait_for_all(); + my_owner.my_barrier.wait(); + return NULL; + } + public: + TrapperTask ( TbbWorkersTrapper& owner ) : my_owner(owner) {} + }; + + public: + TbbWorkersTrapper () + : my_context(tbb::task_group_context::bound, + tbb::task_group_context::default_traits | tbb::task_group_context::concurrent_wait) + { + my_root = new ( tbb::task::allocate_root(my_context) ) tbb::empty_task; + my_root->set_ref_count(2); + my_barrier.initialize(NumThreads); + for ( int i = 1; i < NumThreads; ++i ) + tbb::task::spawn( *new(tbb::task::allocate_root()) TrapperTask(*this) ); + my_barrier.wait(); // Wait util all workers are ready + } + + ~TbbWorkersTrapper () { + my_root->decrement_ref_count(); + my_barrier.wait(); // Make sure no tasks are referencing us + tbb::task::destroy(*my_root); + } + }; // TbbWorkersTrapper + + +#if __TBB_STATISTICS + static bool StatisticsMode = true; +#else + static bool StatisticsMode = false; +#endif + +//! Suppresses silly warning +inline bool __TBB_bool( bool b ) { return b; } + +#define START_WORKERS(needScheduler, p, a, setWorkersAffinity, trapWorkers) \ + tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred); \ + TbbWorkersTrapper *trapper = NULL; \ + if ( theSettings.my_opts & UseTaskScheduler \ + && (needScheduler) && ((setWorkersAffinity) || (trapWorkers)) ) \ + { \ + init.initialize( p ); \ + if ( __TBB_bool(setWorkersAffinity) ) \ + Affinitize( p, a ); \ + if ( __TBB_bool(trapWorkers) ) \ + trapper = new TbbWorkersTrapper; \ + } + +#define STOP_WORKERS() \ + if ( theSettings.my_opts & UseTaskScheduler && init.is_active() ) { \ + if ( trapper ) \ + delete trapper; \ + init.terminate(); \ + /* Give asynchronous deinitialization time to complete */ \ + Harness::Sleep(50); \ + } + + typedef void (Test::*RunMemFnPtr)( Test::ThreadInfo& ); + + TimingSeries *TlsTimings; + Harness::SpinBarrier multipleMastersBarrier; + + class TimingFunctor { + Test* my_test; + RunConfig *my_cfg; + RunMemFnPtr my_fnRun; + size_t my_numRuns; + size_t my_numRepeats; + uintptr_t my_availableMethods; + + duration_t TimeSingleRun ( Test::ThreadInfo& ti ) const { + if ( my_availableMethods & idOnStart ) + my_test->OnStart(ti); + // Warming run + (my_test->*my_fnRun)(ti); + multipleMastersBarrier.wait(); + tbb::tick_count t0 = tbb::tick_count::now(); + (my_test->*my_fnRun)(ti); + duration_t t = (tbb::tick_count::now() - t0).seconds(); + if ( my_availableMethods & idOnFinish ) + my_test->OnFinish(ti); + return t; + } + + public: + TimingFunctor ( Test* test, RunConfig *cfg, RunMemFnPtr fnRun, + size_t numRuns, size_t nRepeats, uintptr_t availableMethods ) + : my_test(test), my_cfg(cfg), my_fnRun(fnRun) + , my_numRuns(numRuns), my_numRepeats(nRepeats), my_availableMethods(availableMethods) + {} + + void operator()( int tid ) const { + Test::ThreadInfo ti = { tid, NULL }; + durations_t &d = TlsTimings[tid].my_durations; + bool singleMaster = my_cfg->my_numMasters == 1; + START_WORKERS( (!singleMaster || (singleMaster && StatisticsMode)) && my_fnRun != &Test::RunSerial, + my_cfg->my_numThreads, my_cfg->my_affinityMode, singleMaster, singleMaster ); + for ( uintptr_t k = 0; k < my_numRuns; ++k ) { + if ( my_numRepeats > 1 ) { + d[k] = 0; + if ( my_availableMethods & idPrePostProcess ) { + for ( uintptr_t i = 0; i < my_numRepeats; ++i ) + d[k] += TimeSingleRun(ti); + } + else { + multipleMastersBarrier.wait(); + tbb::tick_count t0 = tbb::tick_count::now(); + for ( uintptr_t i = 0; i < my_numRepeats; ++i ) + (my_test->*my_fnRun)(ti); + d[k] = (tbb::tick_count::now() - t0).seconds(); + } + d[k] /= my_numRepeats; + } + else + d[k] = TimeSingleRun(ti); + } + STOP_WORKERS(); + TlsTimings[tid].CalculateStatistics(); + } + }; // class TimingFunctor + + void DoTiming ( TestResults& tr, RunConfig &cfg, RunMemFnPtr fnRun, size_t nRepeats, TimingSeries& ts ) { + int numThreads = cfg.NumMasters(); + size_t numRuns = ts.my_durations.size() / numThreads; + TimingFunctor body( tr.my_test, &cfg, fnRun, numRuns, nRepeats, tr.my_availableMethods ); + multipleMastersBarrier.initialize(numThreads); + tr.my_test->SetWorkload(cfg.my_workloadID); + if ( numThreads == 1 ) { + TimingSeries *t = TlsTimings; + TlsTimings = &ts; + body(0); + TlsTimings = t; + } + else { + ts.my_durations.resize(numThreads * numRuns); + NativeParallelFor( numThreads, body ); + for ( int i = 0, j = 0; i < numThreads; ++i ) { + durations_t &d = TlsTimings[i].my_durations; + for ( size_t k = 0; k < numRuns; ++k, ++j ) + ts.my_durations[j] = d[k]; + } + ts.CalculateStatistics(); + } + } + + //! Runs the test function, does statistical processing, and, if title is nonzero, prints results. + /** If histogramFileName is a string, the histogram of individual runs is generated and stored + in a file with the given name. If it is NULL then the histogram is printed on the console. + By default no histogram is generated. + The histogram format is: "rate bucket start" "number of tests in this bucket". **/ + void RunTestImpl ( TestResults& tr, RunConfig &cfg, RunMemFnPtr pfnTest, TimingSeries& ts ) { + // nRepeats is a number of repeated calls to the test function made as + // part of the same run. It is determined experimentally by the following + // calibration process so that the total run time was approx. RunDuration. + // This is helpful to increase the measurement precision in case of very + // short tests. + size_t nRepeats = 1; + // A minimal stats is enough when doing calibration + CalibrationTiming.my_durations.resize( (NumRuns < 4 ? NumRuns : 3) * cfg.NumMasters() ); + // There's no need to be too precise when calculating nRepeats. And reasonably + // far extrapolation can speed up the process significantly. + for (;;) { + DoTiming( tr, cfg, pfnTest, nRepeats, CalibrationTiming ); + if ( CalibrationTiming.my_avgTime * nRepeats > 1e-4 ) + break; + nRepeats *= 2; + } + nRepeats *= (uintptr_t)ceil( RunDuration / (CalibrationTiming.my_avgTime * nRepeats) ); + + DoTiming(tr, cfg, pfnTest, nRepeats, ts); + + // No histogram for baseline measurements + if ( pfnTest != &Test::RunSerial && pfnTest != &Test::Baseline ) { + const char* histogramName = theSettings.my_histogramName; + if ( histogramName != NoHistogram && tr.my_test->HistogramName() != DefaultHistogram ) + histogramName = tr.my_test->HistogramName(); + if ( histogramName != NoHistogram ) + TraceHistogram( ts.my_durations, histogramName ); + } + } // RunTestImpl + + typedef void (*TestActionFn) ( TestResults&, int mastersRange, int w, int p, int m, int a, int& numTests ); + + int TestResultIndex ( int mastersRange, int w, int p, int m, int a ) { + return ((w * (MaxThread - MinThread + 1) + (p - MinThread)) * mastersRange + m) * NumActiveAffModes + a; + } + + void RunTest ( TestResults& tr, int mastersRange, int w, int p, int m, int a, int& numTests ) { + size_t r = TestResultIndex(mastersRange, w, p, m, a); + ASSERT( r < tr.my_results.size(), NULL ); + RunConfig &rc = tr.my_results[r].my_config; + rc.my_maxConcurrency = MaxConcurrency; + rc.my_numThreads = p; + rc.my_numMasters = m + tr.my_test->MinNumMasters(); + rc.my_affinityMode = a; + rc.my_workloadID = w; + RunTestImpl( tr, rc, &Test::Run, tr.my_results[r].my_timing ); + printf( "Running tests: %04.1f%%\r", ++numTests * 100. / TotalConfigs ); fflush(stdout); + } + + void WalkTests ( TestActionFn fn, int& numTests, bool setAffinity, bool trapWorkers, bool multipleMasters ) { + for ( int p = MinThread; p <= MaxThread; ++p ) { + NumThreads = p; + MaxConcurrency = p < NumCpus ? p : NumCpus; + for ( int a = 0; a < NumActiveAffModes; ++a ) { + START_WORKERS( multipleMasters || !StatisticsMode, p, a, setAffinity, trapWorkers ); + for ( size_t i = 0; i < theSession.size(); ++i ) { + TestResults &tr = theSession[i]; + Test *t = tr.my_test; + int mastersRange = t->MaxNumMasters() - t->MinNumMasters() + 1; + int numWorkloads = theSettings.my_opts & UseSmallestWorkloadOnly ? 1 : t->NumWorkloads(); + for ( int w = 0; w < numWorkloads; ++w ) { + if ( multipleMasters ) + for ( int m = 1; m < mastersRange; ++m ) + fn( tr, mastersRange, w, p, m, a, numTests ); + else + fn( tr, mastersRange, w, p, 0, a, numTests ); + } + } + STOP_WORKERS(); + } + } + } + + void RunTests () { + int numTests = 0; + WalkTests( &RunTest, numTests, !StatisticsMode, !StatisticsMode, false ); + if ( MaxTbbMasters > 1 ) + WalkTests( &RunTest, numTests, true, false, true ); + } + + void InitTestData ( TestResults& tr, int mastersRange, int w, int p, int m, int a, int& ) { + size_t r = TestResultIndex(mastersRange, w, p, m, a); + ASSERT( r < tr.my_results.size(), NULL ); + tr.my_results[r].my_timing.my_durations.resize( + (theSettings.my_opts & UseTaskScheduler ? tr.my_test->MinNumMasters() + m : p) * NumRuns ); + } + + char WorkloadName[MaxWorkloadNameLen + 1]; + + void PrepareTests () { + printf( "Initializing...\r" ); + NumActiveAffModes = theSettings.my_opts & UseAffinityModes ? NumAffinitizationModes : 1; + TotalConfigs = 0; + TitleFieldLen = strlen( TestNameColumnTitle ); + WorkloadFieldLen = strlen( WorkloadNameColumnTitle ); + int numThreads = MaxThread - MinThread + 1; + int numConfigsBase = numThreads * NumActiveAffModes; + int totalWorkloads = 0; + for ( size_t i = 0; i < theSession.size(); ++i ) { + TestResults &tr = theSession[i]; + Test &t = *tr.my_test; + int numWorkloads = theSettings.my_opts & UseSmallestWorkloadOnly ? 1 : t.NumWorkloads(); + int numConfigs = numConfigsBase * numWorkloads; + if ( t.MaxNumMasters() > 1 ) { + ASSERT( theSettings.my_opts & UseTaskScheduler, "Multiple masters mode is only valid for task scheduler tests" ); + if ( MaxTbbMasters < t.MaxNumMasters() ) + MaxTbbMasters = t.MaxNumMasters(); + numConfigs *= t.MaxNumMasters() - t.MinNumMasters() + 1; + } + totalWorkloads += numWorkloads; + TotalConfigs += numConfigs; + + const char* testName = t.Name(); + if ( testName ) + tr.my_testName = testName; + ASSERT( tr.my_testName, "Neither Test::Name() is implemented, nor RTTI is enabled" ); + TitleFieldLen = max( TitleFieldLen, strlen(tr.my_testName) ); + + tr.my_results.resize( numConfigs ); + tr.my_serialBaselines.resize( numWorkloads ); + tr.my_baselines.resize( numWorkloads ); + tr.my_workloadNames.resize( numWorkloads ); + } + TimingSeries tmpTiming; + TlsTimings = &tmpTiming; // All measurements are serial here + int n = 0; + for ( size_t i = 0; i < theSession.size(); ++i ) { + TestResults &tr = theSession[i]; + Test &t = *tr.my_test; + // Detect which methods are overridden by the test implementation + g_absentMethods = 0; + Test::ThreadInfo ti = { 0 }; + t.SetWorkload(0); + t.OnStart(ti); + t.RunSerial(ti); + t.OnFinish(ti); + if ( theSettings.my_opts & UseSerialBaseline && !(g_absentMethods & idRunSerial) ) + tr.my_availableMethods |= idRunSerial; + if ( !(g_absentMethods & idOnStart) ) + tr.my_availableMethods |= idOnStart; + + RunConfig rc = { 1, 1, 1, 0, 0 }; + int numWorkloads = theSettings.my_opts & UseSmallestWorkloadOnly ? 1 : t.NumWorkloads(); + for ( int w = 0; w < numWorkloads; ++w ) { + WorkloadName[0] = 0; + t.SetWorkload(w); + if ( !WorkloadName[0] ) + sprintf( WorkloadName, "%d", w ); + size_t len = strlen(WorkloadName); + tr.my_workloadNames[w] = new char[len + 1]; + strcpy ( (char*)tr.my_workloadNames[w], WorkloadName ); + WorkloadFieldLen = max( WorkloadFieldLen, len ); + + rc.my_workloadID = w; + if ( theSettings.my_opts & UseBaseline ) + RunTestImpl( tr, rc, &Test::Baseline, tr.my_baselines[w] ); + if ( tr.my_availableMethods & idRunSerial ) + RunTestImpl( tr, rc, &Test::RunSerial, tr.my_serialBaselines[w] ); + printf( "Measuring baselines: %04.1f%%\r", ++n * 100. / totalWorkloads ); fflush(stdout); + } + } + TlsTimings = new TimingSeries[MaxThread + MaxTbbMasters - 1]; + if ( theSettings.my_opts & UseTaskScheduler ? MaxTbbMasters : MaxThread ) + WalkTests( &InitTestData, n, false, false, theSettings.my_opts & UseTaskScheduler ? true : false ); + CalibrationTiming.my_durations.reserve( MaxTbbMasters * 3 ); + printf( " \r"); + } + + FILE* ResFile = NULL; + + void Report ( char const* fmt, ... ) { + va_list args; + if ( ResFile ) { + va_start( args, fmt ); + vfprintf( ResFile, fmt, args ); + va_end( args ); + } + va_start( args, fmt ); + vprintf( fmt, args ); + va_end( args ); + } + + void PrintResults () { + if ( theSettings.my_resFile ) + ResFile = fopen( theSettings.my_resFile, "w" ); + Report( "%-*s %-*s %s", TitleFieldLen, "Test-name", WorkloadFieldLen, "Workload", + MaxTbbMasters > 1 ? "W M " : "T " ); + if ( theSettings.my_opts & UseAffinityModes ) + Report( "Aff " ); + Report( "%-*s SD,%% %-*s %-*s %-*s ", + RateFieldLen, "Avg.time", OvhdFieldLen, "Par.ovhd,%", + RateFieldLen, "Min.time", RateFieldLen, "Max.time" ); + Report( " | Repeats = %lu, CPUs %d\n", (unsigned long)NumRuns, NumCpus ); + for ( size_t i = 0; i < theSession.size(); ++i ) { + TestResults &tr = theSession[i]; + for ( size_t j = 0; j < tr.my_results.size(); ++j ) { + RunResults &rr = tr.my_results[j]; + RunConfig &rc = rr.my_config; + int w = rc.my_workloadID; + TimingSeries &ts = rr.my_timing; + duration_t baselineTime = tr.my_baselines[w].my_avgTime, + cleanTime = ts.my_avgTime - baselineTime; + Report( "%-*s %-*s ", TitleFieldLen, tr.my_testName, WorkloadFieldLen, tr.my_workloadNames[w] ); + if ( MaxTbbMasters > 1 ) + Report( "%-4d %-4d ", rc.my_numThreads - 1, rc.my_numMasters ); + else + Report( "%-4d ", rc.my_numThreads ); + if ( theSettings.my_opts & UseAffinityModes ) + Report( "%%-8s ", AffinitizationModeNames[rc.my_affinityMode] ); + Report( "%-*.2e %-6.1f ", RateFieldLen, cleanTime, ts.my_stdDev); + if ( tr.my_availableMethods & idRunSerial ) { + duration_t serialTime = (tr.my_serialBaselines[w].my_avgTime - baselineTime) / rc.my_maxConcurrency; + Report( "%-*.1f ", OvhdFieldLen, 100*(cleanTime - serialTime)/serialTime ); + } + else + Report( "%*s%*s ", OvhdFieldLen/2, "-", OvhdFieldLen - OvhdFieldLen/2, "" ); + Report( "%-*.2e %-*.2e ", RateFieldLen, ts.my_minTime - baselineTime, RateFieldLen, ts.my_maxTime - baselineTime); + Report( "\n" ); + } + } + delete [] TlsTimings; + if ( ResFile ) + fclose(ResFile); + } + + __TBB_PERF_API void RegisterTest ( Test* t, const char* className, bool takeOwnership ) { + // Just collect test objects at this stage + theSession.push_back( TestResults(t, className, takeOwnership) ); + } + +} // namespace internal + +__TBB_PERF_API void Test::Baseline ( ThreadInfo& ) {} + +__TBB_PERF_API void Test::RunSerial ( ThreadInfo& ) { internal::g_absentMethods |= internal::idRunSerial; } + +__TBB_PERF_API void Test::OnStart ( ThreadInfo& ) { internal::g_absentMethods |= internal::idOnStart; } + +__TBB_PERF_API void Test::OnFinish ( ThreadInfo& ) { internal::g_absentMethods |= internal::idOnFinish; } + +__TBB_PERF_API void WipeCaches () { NativeParallelFor( NumCpus, internal::WiperBody() ); } + +__TBB_PERF_API void EmptyFunc () {} +__TBB_PERF_API void AnchorFunc ( void* ) {} +__TBB_PERF_API void AnchorFunc2 ( void*, void* ) {} + +__TBB_PERF_API void SetWorkloadName( const char* format, ... ) { + internal::WorkloadName[MaxWorkloadNameLen] = 0; + va_list args; + va_start(args, format); + vsnprintf( internal::WorkloadName, MaxWorkloadNameLen, format, args ); + va_end(args); +} + + +__TBB_PERF_API int TestMain( int argc, char* argv[], const SessionSettings* defaultSettings ) { +#if _MSC_VER + HANDLE hMutex = CreateMutex( NULL, FALSE, "Global\\TBB_OMP_PerfSession" ); + WaitForSingleObject( hMutex, INFINITE ); +#endif + MinThread = MaxThread = NumCpus; + if ( defaultSettings ) + theSettings = *defaultSettings; + ParseCommandLine( argc, argv ); // May override data in theSettings + + internal::PrepareTests (); + internal::RunTests (); + internal::PrintResults(); + REPORT("\n"); +#if _MSC_VER + ReleaseMutex( hMutex ); + CloseHandle( hMutex ); +#endif + return 0; +} + +} // namespace Perf diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf.h new file mode 100644 index 00000000..4ea267fb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf.h @@ -0,0 +1,253 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __tbb_perf_h__ +#define __tbb_perf_h__ + +#ifndef TBB_PERF_TYPEINFO +#define TBB_PERF_TYPEINFO 1 +#endif + +#if TBB_PERF_TYPEINFO + #include + #define __TBB_PERF_TEST_CLASS_NAME(T) typeid(T).name() +#else /* !TBB_PERF_TYPEINFO */ + #define __TBB_PERF_TEST_CLASS_NAME(T) NULL +#endif /* !TBB_PERF_TYPEINFO */ + + +#include "tbb/tick_count.h" + +// TODO: Fix build scripts to provide more reliable build phase identification means +#ifndef __TBB_PERF_API +#if _USRDLL + #if _MSC_VER + #define __TBB_PERF_API __declspec(dllexport) + #else /* !_MSC_VER */ + #define __TBB_PERF_API + #endif /* !_MSC_VER */ +#else /* !_USRDLL */ + #if _MSC_VER + #define __TBB_PERF_API __declspec(dllimport) + #else /* !_MSC_VER */ + #define __TBB_PERF_API + #endif /* !_MSC_VER */ +#endif /* !_USRDLL */ +#endif /* !__TBB_PERF_API */ + +#if _WIN32||_WIN64 + +namespace Perf { + typedef unsigned __int64 tick_t; + #if defined(_M_X64) + inline tick_t rdtsc () { return __rdtsc(); } + #elif _M_IX86 + inline tick_t rdtsc () { __asm { rdtsc } } + #else + #error Unsupported ISA + #endif +} // namespace Perf + +#elif __linux__ || __APPLE__ + +#include + +namespace Perf { + typedef uint64_t tick_t; + #if __x86_64__ || __i386__ || __i386 + inline tick_t rdtsc () { + uint32_t lo, hi; + __asm__ __volatile__ ( "rdtsc" : "=a" (lo), "=d" (hi) ); + return (tick_t)lo | ((tick_t)hi) << 32; + } + #else + #error Unsupported ISA + #endif +} // namespace Perf + +#else + #error Unsupported OS +#endif /* OS */ + +__TBB_PERF_API extern int NumThreads, + MaxConcurrency, + NumCpus; + +// Functions and global variables provided by the benchmarking framework +namespace Perf { + +typedef double duration_t; + +static const int MaxWorkloadNameLen = 64; + +static const char* NoHistogram = (char*)-1; +static const char* DefaultHistogram = (char*)-2; + +__TBB_PERF_API void AnchorFunc ( void* ); +__TBB_PERF_API void AnchorFunc2 ( void*, void* ); + +//! Helper that can be used in the preprocess handler to clean caches +/** Cleaning caches is necessary to obtain reproducible results when a test + accesses significant ranges of memory. **/ +__TBB_PERF_API void WipeCaches (); + +//! Specifies the name to be used to designate the current workload in output +/** Should be used from Test::SetWorkload(). If necessary workload name will be + truncated to MaxWorkloadNameLen characters. **/ +__TBB_PERF_API void SetWorkloadName( const char* format, ... ); + +class __TBB_PERF_API Test { +public: + virtual ~Test () {} + + //! Struct used by tests running in multiple masters mode + struct ThreadInfo { + //! Zero based thread ID + int tid; + //! Pointer to test specific data + /** If used by the test, should be initialized by OnStartLocal(), and + finalized by OnFinishLocal(). **/ + void* data; + }; + + //////////////////////////////////////////////////////////////////////////////// + // Mandatory methods + + //! Returns the number of workloads supported + virtual int NumWorkloads () = 0; + + //! Set workload info for the subsequent calls to Run() and RunSerial() + /** This method can use global helper function Perf::SetWorkloadName() in order + to specify the name of the current workload, which will be used in output + to designate the workload. If SetWorkloadName is not called, workloadIndex + will be used for this purpose. + + When testing task scheduler, make sure that this method does not trigger + its automatic initialization. **/ + virtual void SetWorkload ( int workloadIndex ) = 0; + + //! Test implementation + /** Called by the timing framework several times in a loop to achieve approx. + RunDuration time, and this loop is timed NumRuns times to collect statistics. + Argument ti specifies information about the master thread calling this method. **/ + virtual void Run ( ThreadInfo& ti ) = 0; + + //////////////////////////////////////////////////////////////////////////////// + // Optional methods + + //! Returns short title string to be used in the regular output to identify the test + /** Should uniquely identify the test among other ones in the given benchmark suite. + If not implemented, the test implementation class' RTTI name is used. **/ + virtual const char* Name () { return NULL; }; + + //! Returns minimal number of master threads + /** Used for task scheduler tests only (when UseTbbScheduler option is specified + in session settings). **/ + virtual int MinNumMasters () { return 1; } + + //! Returns maximal number of master threads + /** Used for task scheduler tests only (when UseTbbScheduler option is specified + in session settings). **/ + virtual int MaxNumMasters () { return 1; } + + //! Executes serial workload equivalent to the one processed by Run() + /** Called by the timing framework several times in a loop to collect statistics. **/ + virtual void RunSerial ( ThreadInfo& ti ); + + //! Invoked before each call to Run() + /** Can be used to preinitialize data necessary for the test, clean up + caches (see Perf::WipeCaches), etc. + In multiple masters mode this method is called on each thread. **/ + virtual void OnStart ( ThreadInfo& ti ); + + //! Invoked after each call to Run() + /** Can be used to free resources allocated by OnStart(). + Note that this method must work correctly independently of whether Run(), + RunSerial() or nothing is called between OnStart() and OnFinish(). + In multiple masters mode this method is called on each thread. **/ + virtual void OnFinish ( ThreadInfo& ti ); + + //! Functionality, the cost of which has to be factored out from timing results + /** Applies to both parallel and serial versions. **/ + virtual void Baseline ( ThreadInfo& ); + + //! Returns description string to be used in the benchmark info/summary output + virtual const char* Description () { return NULL; } + + //! Specifies if the histogram of individual run times in a series + /** If the method is not overridden, histogramName argument of TestMain is used. **/ + virtual const char* HistogramName () { return DefaultHistogram; } +}; // class Test + +namespace internal { + __TBB_PERF_API void RegisterTest ( Test*, const char* testClassName, bool takeOwnership ); +} + +template +void RegisterTest() { internal::RegisterTest( new T, __TBB_PERF_TEST_CLASS_NAME(T), true ); } + +template +void RegisterTest( T& t ) { internal::RegisterTest( &t, __TBB_PERF_TEST_CLASS_NAME(T), false ); } + +enum SessionOptions { + //! Use Test::RunSerial if present + UseBaseline = 0x01, + UseSerialBaseline = 0x02, + UseBaselines = UseBaseline | UseSerialBaseline, + UseTaskScheduler = 0x10, + UseAffinityModes = 0x20, + UseSmallestWorkloadOnly = 0x40 +}; + +struct SessionSettings { + //! A combination of SessionOptions flags + uintptr_t my_opts; + + //! Name of a file to store performance results + /** These results are duplicates of what is printed on the console. **/ + const char* my_resFile; + + //! Output destination for the histogram of individual run times in a series + /** If it is a string, the histogram is stored in a file with such name. + If it is NULL, the histogram is printed on the console. By default histograms + are suppressed. + + The histogram is formatted as two column table: + "time bucket start" "number of tests in this bucket" + + When this setting enables histogram generation, an individual test + can override it by implementing HistogramName method. **/ + const char* my_histogramName; + + SessionSettings ( uintptr_t opts = 0, const char* resFile = NULL, const char* histogram = NoHistogram ) + : my_opts(opts) + , my_resFile(resFile) + , my_histogramName(histogram) + {} +}; // struct SessionSettings + +//! Benchmarking session entry point +/** Executes all the individual tests registered previously by means of + RegisterTest **/ +__TBB_PERF_API int TestMain( int argc, char* argv[], + const SessionSettings* defaultSettings = NULL ); + + +} // namespace Perf + +#endif /* __tbb_perf_h__ */ + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf_sched.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf_sched.cpp new file mode 100644 index 00000000..43331c3c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/perf_sched.cpp @@ -0,0 +1,452 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "perf.h" + +#include + +#include "tbb/blocked_range.h" +#include "tbb/parallel_for.h" +#include "tbb/parallel_reduce.h" + +#define NUM_CHILD_TASKS 2096 +#define NUM_ROOT_TASKS 256 + +#define N 100000000 +#define FINEST_GRAIN 10 +#define FINE_GRAIN 50 +#define MED_GRAIN 200 +#define COARSE_GRAIN 1000 + + +typedef int count_t; + +const count_t N_finest = (count_t)(N/log((double)N)/10); +const count_t N_fine = N_finest * 20; +const count_t N_med = N_fine * (count_t)log((double)N) / 5; + +class StaticTaskHolder { +public: + tbb::task *my_leafTaskPtr; + StaticTaskHolder (); +}; + +static StaticTaskHolder s_tasks; + +static count_t NumIterations; +static count_t NumLeafTasks; +static count_t NumRootTasks; + +class LeafTaskBase : public tbb::task { +public: + count_t my_ID; + + LeafTaskBase () {} + LeafTaskBase ( count_t id ) : my_ID(id) {} +}; + +class SimpleLeafTask : public LeafTaskBase { + task* execute () { + volatile count_t anchor = 0; + for ( count_t i=0; i < NumIterations; ++i ) + anchor += i; + return NULL; + } +public: + SimpleLeafTask ( count_t ) {} +}; + +StaticTaskHolder::StaticTaskHolder () { + static SimpleLeafTask s_t1(0); + my_leafTaskPtr = &s_t1; +} + +class Test_SPMC : public Perf::Test { +protected: + static const int numWorkloads = 4; + static const count_t workloads[numWorkloads]; + + LeafTaskBase* my_leafTaskPtr; + + const char* Name () { return "SPMC"; } + + int NumWorkloads () { return numWorkloads; } + + void SetWorkload ( int idx ) { + NumRootTasks = 1; + NumIterations = workloads[idx]; + NumLeafTasks = NUM_CHILD_TASKS * NUM_ROOT_TASKS / (NumIterations > 1000 ? 32 : 8); + Perf::SetWorkloadName( "%dx%d", NumLeafTasks, NumIterations ); + } + + void Run ( ThreadInfo& ) { + tbb::empty_task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + r.set_ref_count( NumLeafTasks + 1 ); + for ( count_t i = 0; i < NumLeafTasks; ++i ) + r.spawn( *new(r.allocate_child()) SimpleLeafTask(0) ); + r.wait_for_all(); + tbb::task::destroy(r); + } + + void RunSerial ( ThreadInfo& ) { + const count_t n = NumLeafTasks * NumRootTasks; + for ( count_t i=0; i < n; ++i ) { + my_leafTaskPtr->my_ID = i; + my_leafTaskPtr->execute(); + } + } + +public: + Test_SPMC ( LeafTaskBase* leafTaskPtr = NULL ) { + static SimpleLeafTask t(0); + my_leafTaskPtr = leafTaskPtr ? leafTaskPtr : &t; + } +}; // class Test_SPMC + +const count_t Test_SPMC::workloads[Test_SPMC::numWorkloads] = { 1, 50, 500, 5000 }; + +template +class LeavesLauncherTask : public tbb::task { + count_t my_groupId; + + task* execute () { + count_t base = my_groupId * NumLeafTasks; + set_ref_count(NumLeafTasks + 1); + for ( count_t i = 0; i < NumLeafTasks; ++i ) + spawn( *new(allocate_child()) LeafTask(base + i) ); + wait_for_all(); + return NULL; + } +public: + LeavesLauncherTask ( count_t groupId ) : my_groupId(groupId) {} +}; + +template +void RunShallowTree () { + tbb::empty_task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + r.set_ref_count( NumRootTasks + 1 ); + for ( count_t i = 0; i < NumRootTasks; ++i ) + r.spawn( *new(r.allocate_child()) LeavesLauncherTask(i) ); + r.wait_for_all(); + tbb::task::destroy(r); +} + +class Test_ShallowTree : public Test_SPMC { + const char* Name () { return "ShallowTree"; } + + void SetWorkload ( int idx ) { + NumRootTasks = NUM_ROOT_TASKS; + NumIterations = workloads[idx]; + NumLeafTasks = NumIterations > 200 ? NUM_CHILD_TASKS / 10 : + (NumIterations > 50 ? NUM_CHILD_TASKS / 2 : NUM_CHILD_TASKS * 2); + Perf::SetWorkloadName( "%dx%d", NumRootTasks * NumLeafTasks, NumIterations ); + } + + void Run ( ThreadInfo& ) { + RunShallowTree(); + } +}; // class Test_ShallowTree + +class LeafTaskSkewed : public LeafTaskBase { + task* execute () { + volatile count_t anchor = 0; + double K = (double)NumRootTasks * NumLeafTasks; + count_t n = count_t(sqrt(double(my_ID)) * double(my_ID) * my_ID / (4 * K * K)); + for ( count_t i = 0; i < n; ++i ) + anchor += i; + return NULL; + } +public: + LeafTaskSkewed ( count_t id ) : LeafTaskBase(id) {} +}; + +class Test_ShallowTree_Skewed : public Test_SPMC { + static LeafTaskSkewed SerialTaskBody; + + const char* Name () { return "ShallowTree_Skewed"; } + + int NumWorkloads () { return 1; } + + void SetWorkload ( int ) { + NumRootTasks = NUM_ROOT_TASKS; + NumLeafTasks = NUM_CHILD_TASKS; + Perf::SetWorkloadName( "%d", NumRootTasks * NumLeafTasks ); + } + + void Run ( ThreadInfo& ) { + RunShallowTree(); + } + +public: + Test_ShallowTree_Skewed () : Test_SPMC(&SerialTaskBody) {} +}; // class Test_ShallowTree_Skewed + +LeafTaskSkewed Test_ShallowTree_Skewed::SerialTaskBody(0); + +typedef tbb::blocked_range range_t; + +static count_t IterRange = N, + IterGrain = 1; + +enum PartitionerType { + SimplePartitioner = 0, + AutoPartitioner = 1 +}; + +class Test_Algs : public Perf::Test { +protected: + static const int numWorkloads = 4; + static const count_t algRanges[numWorkloads]; + static const count_t algGrains[numWorkloads]; + + tbb::simple_partitioner my_simplePartitioner; + tbb::auto_partitioner my_autoPartitioner; + PartitionerType my_partitionerType; + + bool UseAutoPartitioner () const { return my_partitionerType == AutoPartitioner; } + + int NumWorkloads () { return UseAutoPartitioner() ? 3 : numWorkloads; } + + void SetWorkload ( int idx ) { + if ( UseAutoPartitioner() ) { + IterRange = algRanges[idx ? numWorkloads - 1 : 0]; + IterGrain = idx > 1 ? algGrains[numWorkloads - 1] : 1; + } + else { + IterRange = algRanges[idx]; + IterGrain = algGrains[idx]; + } + Perf::SetWorkloadName( "%d/%d", IterRange, IterGrain ); + } +public: + Test_Algs ( PartitionerType pt = SimplePartitioner ) : my_partitionerType(pt) {} +}; // class Test_Algs + +const count_t Test_Algs::algRanges[] = {N_finest, N_fine, N_med, N}; +const count_t Test_Algs::algGrains[] = {1, FINE_GRAIN, MED_GRAIN, COARSE_GRAIN}; + +template +class Test_PFor : public Test_Algs { +protected: + void Run ( ThreadInfo& ) { + if ( UseAutoPartitioner() ) + tbb::parallel_for( range_t(0, IterRange, IterGrain), Body(), my_autoPartitioner ); + else + tbb::parallel_for( range_t(0, IterRange, IterGrain), Body(), my_simplePartitioner ); + } + + void RunSerial ( ThreadInfo& ) { + Body body; + body( range_t(0, IterRange, IterGrain) ); + } +public: + Test_PFor ( PartitionerType pt = SimplePartitioner ) : Test_Algs(pt) {} +}; // class Test_PFor + +class SimpleForBody { +public: + void operator()( const range_t& r ) const { + count_t end = r.end(); + volatile count_t anchor = 0; + for( count_t i = r.begin(); i < end; ++i ) + anchor += i; + } +}; // class SimpleForBody + +class Test_PFor_Simple : public Test_PFor { +protected: + const char* Name () { return UseAutoPartitioner() ? "PFor-AP" : "PFor"; } +public: + Test_PFor_Simple ( PartitionerType pt = SimplePartitioner ) : Test_PFor(pt) {} +}; // class Test_PFor_Simple + +class SkewedForBody { +public: + void operator()( const range_t& r ) const { + count_t end = (r.end() + 1) * (r.end() + 1); + volatile count_t anchor = 0; + for( count_t i = r.begin() * r.begin(); i < end; ++i ) + anchor += i; + } +}; // class SkewedForBody + +class Test_PFor_Skewed : public Test_PFor { + typedef Test_PFor base_type; +protected: + const char* Name () { return UseAutoPartitioner() ? "PFor-Skewed-AP" : "PFor-Skewed"; } + + void SetWorkload ( int idx ) { + base_type::SetWorkload(idx); + IterRange = (count_t)(sqrt((double)IterRange) * sqrt(sqrt((double)N / IterRange))); + Perf::SetWorkloadName( "%d", IterRange ); + } + +public: + Test_PFor_Skewed ( PartitionerType pt = SimplePartitioner ) : base_type(pt) {} +}; // class Test_PFor_Skewed + +PartitionerType gPartitionerType; +count_t NestingRange; +count_t NestingGrain; + +class NestingForBody { + count_t my_depth; + tbb::simple_partitioner my_simplePartitioner; + tbb::auto_partitioner my_autoPartitioner; + + template + void run ( const range_t& r, Partitioner& p ) const { + count_t end = r.end(); + if ( my_depth > 1 ) + for ( count_t i = r.begin(); i < end; ++i ) + tbb::parallel_for( range_t(0, IterRange, IterGrain), NestingForBody(my_depth - 1), p ); + else + for ( count_t i = r.begin(); i < end; ++i ) + tbb::parallel_for( range_t(0, IterRange, IterGrain), SimpleForBody(), p ); + } +public: + void operator()( const range_t& r ) const { + if ( gPartitionerType == AutoPartitioner ) + run( r, my_autoPartitioner ); + else + run( r, my_simplePartitioner ); + } + NestingForBody ( count_t depth = 1 ) : my_depth(depth) {} +}; // class NestingForBody + +enum NestingType { + HollowNesting, + ShallowNesting, + DeepNesting +}; + +class Test_PFor_Nested : public Test_Algs { + typedef Test_Algs base_type; + + NestingType my_nestingType; + count_t my_nestingDepth; + +protected: + const char* Name () { + static const char* names[] = { "PFor-HollowNested", "PFor-HollowNested-AP", + "PFor-ShallowNested", "PFor-ShallowNested-AP", + "PFor-DeeplyNested", "PFor-DeeplyNested-AP" }; + return names[my_nestingType * 2 + my_partitionerType]; + } + + int NumWorkloads () { return my_nestingType == ShallowNesting ? (UseAutoPartitioner() ? 3 : 2) : 1; } + + void SetWorkload ( int idx ) { + gPartitionerType = my_partitionerType; + if ( my_nestingType == DeepNesting ) { + NestingRange = 1024; + IterGrain = NestingGrain = 1; + IterRange = 4; + my_nestingDepth = 4; + } + else if ( my_nestingType == ShallowNesting ) { + int i = idx ? numWorkloads - 1 : 0; + count_t baseRange = algRanges[i]; + count_t baseGrain = !UseAutoPartitioner() || idx > 1 ? algGrains[i] : 1; + NestingRange = IterRange = (count_t)sqrt((double)baseRange); + NestingGrain = IterGrain = (count_t)sqrt((double)baseGrain); + } + else { + NestingRange = N / 100; + NestingGrain = COARSE_GRAIN / 10; + IterRange = 2; + IterGrain = 1; + } + Perf::SetWorkloadName( "%d/%d", NestingRange, NestingGrain ); + } + + void Run ( ThreadInfo& ) { + if ( UseAutoPartitioner() ) + tbb::parallel_for( range_t(0, NestingRange, NestingGrain), NestingForBody(my_nestingDepth), my_autoPartitioner ); + else + tbb::parallel_for( range_t(0, NestingRange, NestingGrain), NestingForBody(my_nestingDepth), my_simplePartitioner ); + } + + void RunSerial ( ThreadInfo& ) { + for ( int i = 0; i < NestingRange; ++i ) { + SimpleForBody body; + body( range_t(0, IterRange, IterGrain) ); + } + } +public: + Test_PFor_Nested ( NestingType nt, PartitionerType pt ) : base_type(pt), my_nestingType(nt), my_nestingDepth(1) {} +}; // class Test_PFor_Nested + +class SimpleReduceBody { +public: + count_t my_sum; + SimpleReduceBody () : my_sum(0) {} + SimpleReduceBody ( SimpleReduceBody&, tbb::split ) : my_sum(0) {} + void join( SimpleReduceBody& rhs ) { my_sum += rhs.my_sum;} + void operator()( const range_t& r ) { + count_t end = r.end(); + volatile count_t anchor = 0; + for( count_t i = r.begin(); i < end; ++i ) + anchor += i; + my_sum = anchor; + } +}; // class SimpleReduceBody + +class Test_PReduce : public Test_Algs { +protected: + const char* Name () { return UseAutoPartitioner() ? "PReduce-AP" : "PReduce"; } + + void Run ( ThreadInfo& ) { + SimpleReduceBody body; + if ( UseAutoPartitioner() ) + tbb::parallel_reduce( range_t(0, IterRange, IterGrain), body, my_autoPartitioner ); + else + tbb::parallel_reduce( range_t(0, IterRange, IterGrain), body, my_simplePartitioner ); + } + + void RunSerial ( ThreadInfo& ) { + SimpleReduceBody body; + body( range_t(0, IterRange, IterGrain) ); + } +public: + Test_PReduce ( PartitionerType pt = SimplePartitioner ) : Test_Algs(pt) {} +}; // class Test_PReduce + +int main( int argc, char* argv[] ) { + Perf::SessionSettings opts (Perf::UseTaskScheduler | Perf::UseSerialBaseline, "perf_sched.txt"); // Perf::UseBaseline, Perf::UseSmallestWorkloadOnly + Perf::RegisterTest(); + Perf::RegisterTest(); + Perf::RegisterTest(); + Test_PFor_Simple pf_sp(SimplePartitioner), pf_ap(AutoPartitioner); + Perf::RegisterTest(pf_sp); + Perf::RegisterTest(pf_ap); + Test_PReduce pr_sp(SimplePartitioner), pr_ap(AutoPartitioner); + Perf::RegisterTest(pr_sp); + Perf::RegisterTest(pr_ap); + Test_PFor_Skewed pf_s_sp(SimplePartitioner), pf_s_ap(AutoPartitioner); + Perf::RegisterTest(pf_s_sp); + Perf::RegisterTest(pf_s_ap); + Test_PFor_Nested pf_hn_sp(HollowNesting, SimplePartitioner), pf_hn_ap(HollowNesting, AutoPartitioner), + pf_sn_sp(ShallowNesting, SimplePartitioner), pf_sn_ap(ShallowNesting, AutoPartitioner), + pf_dn_sp(DeepNesting, SimplePartitioner), pf_dn_ap(DeepNesting, AutoPartitioner); + Perf::RegisterTest(pf_hn_sp); + Perf::RegisterTest(pf_hn_ap); + Perf::RegisterTest(pf_sn_sp); + Perf::RegisterTest(pf_sn_ap); + Perf::RegisterTest(pf_dn_sp); + Perf::RegisterTest(pf_dn_ap); + return Perf::TestMain(argc, argv, &opts); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/run_statistics.sh b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/run_statistics.sh new file mode 100644 index 00000000..232d5084 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/run_statistics.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Copyright (c) 2005-2020 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH +#setting output format .csv, 'pivot' - is pivot table mode, ++ means append +export STAT_FORMAT=pivot-csv++ +#check existing files because of append mode +ls *.csv +rm -i *.csv +#setting a delimiter in txt or csv file +#export STAT_DELIMITER=, +export STAT_RUNINFO1=Host=`hostname -s` +#append a suffix after the filename +#export STAT_SUFFIX=$STAT_RUNINFO1 +for ((i=1;i<=${repeat:=100};++i)); do echo $i of $repeat: && STAT_RUNINFO2=Run=$i $* || break; done diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics.cpp new file mode 100644 index 00000000..4825cf98 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics.cpp @@ -0,0 +1,440 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "statistics.h" +#include "statistics_xml.h" + +#define COUNT_PARAMETERS 3 + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +void GetTime(char* buff,int size_buff) +{ + tm *newtime; + time_t timer; + time(&timer); + newtime=localtime(&timer); + strftime(buff,size_buff,"%H:%M:%S",newtime); +} + +void GetDate(char* buff,int size_buff) +{ + tm *newtime; + time_t timer; + time(&timer); + newtime=localtime(&timer); + strftime(buff,size_buff,"%Y-%m-%d",newtime); +} + + +StatisticsCollector::TestCase StatisticsCollector::SetTestCase(const char *name, const char *mode, int threads) +{ + string KeyName(name); + switch (SortMode) + { + case ByThreads: KeyName += Format("_%02d_%s", threads, mode); break; + default: + case ByAlg: KeyName += Format("_%s_%02d", mode, threads); break; + } + CurrentKey = Statistics[KeyName]; + if(!CurrentKey) { + CurrentKey = new StatisticResults; + CurrentKey->Mode = mode; + CurrentKey->Name = name; + CurrentKey->Threads = threads; + CurrentKey->Results.reserve(RoundTitles.size()); + Statistics[KeyName] = CurrentKey; + } + return TestCase(CurrentKey); +} + +StatisticsCollector::~StatisticsCollector() +{ + for(Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + delete i->second; +} + +void StatisticsCollector::ReserveRounds(size_t index) +{ + size_t i = RoundTitles.size(); + if (i > index) return; + char buf[16]; + RoundTitles.resize(index+1); + for(; i <= index; i++) { + snprintf( buf, 15, "%u", unsigned(i+1) ); + RoundTitles[i] = buf; + } + for(Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) { + if(!i->second) printf("!!!'%s' = NULL\n", i->first.c_str()); + else i->second->Results.reserve(index+1); + } +} + +void StatisticsCollector::AddRoundResult(const TestCase &key, value_t v) +{ + ReserveRounds(key.access->Results.size()); + key.access->Results.push_back(v); +} + +void StatisticsCollector::SetRoundTitle(size_t index, const char *fmt, ...) +{ + vargf2buff(buff, 128, fmt); + ReserveRounds(index); + RoundTitles[index] = buff; +} + +void StatisticsCollector::AddStatisticValue(const TestCase &key, const char *type, const char *fmt, ...) +{ + vargf2buff(buff, 128, fmt); + AnalysisTitles.insert(type); + key.access->Analysis[type] = buff; +} + +void StatisticsCollector::AddStatisticValue(const char *type, const char *fmt, ...) +{ + vargf2buff(buff, 128, fmt); + AnalysisTitles.insert(type); + CurrentKey->Analysis[type] = buff; +} + +void StatisticsCollector::SetRunInfo(const char *title, const char *fmt, ...) +{ + vargf2buff(buff, 256, fmt); + RunInfo.push_back(make_pair(title, buff)); +} + +void StatisticsCollector::SetStatisticFormula(const char *name, const char *formula) +{ + Formulas[name] = formula; +} + +void StatisticsCollector::SetTitle(const char *fmt, ...) +{ + vargf2buff(buff, 256, fmt); + Title = buff; +} + +string ExcelFormula(const string &fmt, size_t place, size_t rounds, bool is_horizontal) +{ + char buff[16]; + if(is_horizontal) + snprintf(buff, 15, "RC[%u]:RC[%u]", unsigned(place), unsigned(place+rounds-1)); + else + snprintf(buff, 15, "R[%u]C:R[%u]C", unsigned(place+1), unsigned(place+rounds)); + string result(fmt); size_t pos = 0; + while ( (pos = result.find("ROUNDS", pos, 6)) != string::npos ) + result.replace(pos, 6, buff); + return result; +} + +void StatisticsCollector::Print(int dataOutput, const char *ModeName) +{ + FILE *OutputFile; + const char *file_suffix = getenv("STAT_SUFFIX"); + if( !file_suffix ) file_suffix = ""; + const char *file_format = getenv("STAT_FORMAT"); + if( file_format ) { + dataOutput = 0; + if( strstr(file_format, "con")||strstr(file_format, "std") ) dataOutput |= StatisticsCollector::Stdout; + if( strstr(file_format, "txt")||strstr(file_format, "csv") ) dataOutput |= StatisticsCollector::TextFile; + if( strstr(file_format, "excel")||strstr(file_format, "xml") ) dataOutput |= StatisticsCollector::ExcelXML; + if( strstr(file_format, "htm") ) dataOutput |= StatisticsCollector::HTMLFile; + if( strstr(file_format, "pivot") ) dataOutput |= StatisticsCollector::PivotMode; + } + for(int i = 1; i < 10; i++) { + string env = Format("STAT_RUNINFO%d", i); + const char *info = getenv(env.c_str()); + if( info ) { + string title(info); + size_t pos = title.find('='); + if( pos != string::npos ) { + env = title.substr(pos+1); + title.resize(pos); + } else env = title; + RunInfo.push_back(make_pair(title, env)); + } + } + + if (dataOutput & StatisticsCollector::Stdout) + { + printf("\n-=# %s #=-\n", Title.c_str()); + if(SortMode == ByThreads) + printf(" Name | # | %s ", ModeName); + else + printf(" Name | %s | # ", ModeName); + for (AnalysisTitles_t::iterator i = AnalysisTitles.begin(); i != AnalysisTitles.end(); i++) + printf("|%s", i->c_str()+1); + + for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + { + if(SortMode == ByThreads) + printf("\n%12s|% 5d|%6s", i->second->Name.c_str(), i->second->Threads, i->second->Mode.c_str()); + else + printf("\n%12s|%6s|% 5d", i->second->Name.c_str(), i->second->Mode.c_str(), i->second->Threads); + Analysis_t &analisis = i->second->Analysis; + AnalysisTitles_t::iterator t = AnalysisTitles.begin(); + for (Analysis_t::iterator a = analisis.begin(); a != analisis.end(); t++) + { + char fmt[8]; snprintf(fmt, 7, "|%% %us", unsigned(max(size_t(3), t->size()))); + if(*t != a->first) + printf(fmt, ""); + else { + printf(fmt, a->second.c_str()); a++; + } + } + } + printf("\n"); + } + if (dataOutput & StatisticsCollector::TextFile) + { + bool append = false; + const char *file_ext = ".txt"; + if( file_format && strstr(file_format, "++") ) append = true; + if( file_format && strstr(file_format, "csv") ) file_ext = ".csv"; + if ((OutputFile = fopen((Name+file_suffix+file_ext).c_str(), append?"at":"wt")) == NULL) { + printf("Can't open .txt file\n"); + } else { + const char *delim = getenv("STAT_DELIMITER"); + if( !delim || !delim[0] ) { + if( file_format && strstr(file_format, "csv") ) delim = ","; + else delim = "\t"; + } + if( !append || !ftell(OutputFile) ) { // header needed + append = false; + if(SortMode == ByThreads) fprintf(OutputFile, "Name%s#%s%s", delim, delim, ModeName); + else fprintf(OutputFile, "Name%s%s%s#", delim, ModeName, delim); + for( size_t k = 0; k < RunInfo.size(); k++ ) + fprintf(OutputFile, "%s%s", delim, RunInfo[k].first.c_str()); + } + if(dataOutput & StatisticsCollector::PivotMode) { + if( !append) fprintf(OutputFile, "%sColumn%sValue", delim, delim); + for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + { + string RowHead; + if(SortMode == ByThreads) + RowHead = Format("\n%s%s%d%s%s%s", i->second->Name.c_str(), delim, i->second->Threads, delim, i->second->Mode.c_str(), delim); + else + RowHead = Format("\n%s%s%s%s%d%s", i->second->Name.c_str(), delim, i->second->Mode.c_str(), delim, i->second->Threads, delim); + for( size_t k = 0; k < RunInfo.size(); k++ ) + RowHead.append(RunInfo[k].second + delim); + Analysis_t &analisis = i->second->Analysis; + for (Analysis_t::iterator a = analisis.begin(); a != analisis.end(); ++a) + fprintf(OutputFile, "%s%s%s%s", RowHead.c_str(), a->first.c_str(), delim, a->second.c_str()); + Results_t &r = i->second->Results; + for (size_t k = 0; k < r.size(); k++) { + fprintf(OutputFile, "%s%s%s", RowHead.c_str(), RoundTitles[k].c_str(), delim); + fprintf(OutputFile, ResultsFmt, r[k]); + } + } + } else { + if( !append ) { + for( size_t k = 0; k < RunInfo.size(); k++ ) + fprintf(OutputFile, "%s%s", delim, RunInfo[k].first.c_str()); + for (AnalysisTitles_t::iterator i = AnalysisTitles.begin(); i != AnalysisTitles.end(); i++) + fprintf(OutputFile, "%s%s", delim, i->c_str()+1); + for (size_t i = 0; i < RoundTitles.size(); i++) + fprintf(OutputFile, "%s%s", delim, RoundTitles[i].c_str()); + } + for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + { + if(SortMode == ByThreads) + fprintf(OutputFile, "\n%s%s%d%s%s", i->second->Name.c_str(), delim, i->second->Threads, delim, i->second->Mode.c_str()); + else + fprintf(OutputFile, "\n%s%s%s%s%d", i->second->Name.c_str(), delim, i->second->Mode.c_str(), delim, i->second->Threads); + for( size_t k = 0; k < RunInfo.size(); k++ ) + fprintf(OutputFile, "%s%s", delim, RunInfo[k].second.c_str()); + Analysis_t &analisis = i->second->Analysis; + AnalysisTitles_t::iterator t = AnalysisTitles.begin(); + for (Analysis_t::iterator a = analisis.begin(); a != analisis.end(); ++t) { + fprintf(OutputFile, "%s", delim); + if(*t == a->first) { + fprintf(OutputFile, "%s", a->second.c_str()); ++a; + } + } + //data + Results_t &r = i->second->Results; + for (size_t k = 0; k < r.size(); k++) + { + fprintf(OutputFile, "%s", delim); + fprintf(OutputFile, ResultsFmt, r[k]); + } + } + } + fprintf(OutputFile, "\n"); + fclose(OutputFile); + } + } + if (dataOutput & StatisticsCollector::HTMLFile) + { + if ((OutputFile = fopen((Name+file_suffix+".html").c_str(), "w+t")) == NULL) { + printf("Can't open .html file\n"); + } else { + char TimerBuff[100], DateBuff[100]; + GetTime(TimerBuff,sizeof(TimerBuff)); + GetDate(DateBuff,sizeof(DateBuff)); + fprintf(OutputFile, "\n%s\n\n", Title.c_str()); + //----------------------- + fprintf(OutputFile, "\n"); + fprintf(OutputFile, "" + "\n", ModeName); + for (AnalysisTitles_t::iterator i = AnalysisTitles.begin(); i != AnalysisTitles.end(); i++) + fprintf(OutputFile, "", i->c_str()+1); + for (size_t i = 0; i < RoundTitles.size(); i++) + fprintf(OutputFile, "", RoundTitles[i].c_str()); + for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + { + fprintf(OutputFile, "\n", + i->second->Name.c_str(), i->second->Threads, i->second->Mode.c_str()); + //statistics + AnalysisTitles_t::iterator t = AnalysisTitles.begin(); + for (Analysis_t::iterator j = i->second->Analysis.begin(); j != i->second->Analysis.end(); t++) + { + fprintf(OutputFile, "", (*t != j->first)?" ":(i->second->Analysis[j->first]).c_str()); + if(*t == j->first) j++; + } + //data + Results_t &r = i->second->Results; + for (size_t k = 0; k < r.size(); k++) + { + fprintf(OutputFile, ""); + } + } + fprintf(OutputFile, "\n
Flip[H]%s%s%s", + DateBuff, TimerBuff, unsigned(AnalysisTitles.size() + RoundTitles.size()), Title.c_str()); + for( size_t k = 0; k < RunInfo.size(); k++ ) + fprintf(OutputFile, "; %s: %s", RunInfo[k].first.c_str(), RunInfo[k].second.c_str()); + fprintf(OutputFile, "
NameThreads%s%s%s
%s%d%4s%s"); + fprintf(OutputFile, ResultsFmt, r[k]); + fprintf(OutputFile, "
\n"); + ////////////////////////////////////////////////////// + fprintf(OutputFile, "\n"); + fprintf(OutputFile, "\n" + "", + DateBuff, TimerBuff, unsigned(max(Statistics.size()-2,size_t(1))), Title.c_str()); + + fprintf(OutputFile, "\n"); + for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + fprintf(OutputFile, "", i->second->Name.c_str()); + fprintf(OutputFile, "\n"); + for (Statistics_t::iterator n = Statistics.begin(); n != Statistics.end(); n++) + fprintf(OutputFile, "", n->second->Threads); + fprintf(OutputFile, "\n", ModeName); + for (Statistics_t::iterator m = Statistics.begin(); m != Statistics.end(); m++) + fprintf(OutputFile, "", m->second->Mode.c_str()); + + for (AnalysisTitles_t::iterator t = AnalysisTitles.begin(); t != AnalysisTitles.end(); t++) + { + fprintf(OutputFile, "\n", t->c_str()+1); + for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + fprintf(OutputFile, "", i->second->Analysis.count(*t)?i->second->Analysis[*t].c_str():" "); + } + + for (size_t r = 0; r < RoundTitles.size(); r++) + { + fprintf(OutputFile, "\n", RoundTitles[r].c_str()); + for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + { + Results_t &result = i->second->Results; + fprintf(OutputFile, ""); + } + } + fprintf(OutputFile, "\n
Flip[V]%s%s%s
Name%s
Threads%d
%s%s
%s%s
%s"); + if(result.size() > r) + fprintf(OutputFile, ResultsFmt, result[r]); + fprintf(OutputFile, "
\n\n"); + fclose(OutputFile); + } + } + if (dataOutput & StatisticsCollector::ExcelXML) + { + if ((OutputFile = fopen((Name+file_suffix+".xml").c_str(), "w+t")) == NULL) { + printf("Can't open .xml file\n"); + } else { + // TODO:PivotMode + char UserName[100]; + char TimerBuff[100], DateBuff[100]; +#if _WIN32 || _WIN64 + strcpy(UserName,getenv("USERNAME")); +#else + strcpy(UserName,getenv("USER")); +#endif + //-------------------------------- + GetTime(TimerBuff,sizeof(TimerBuff)); + GetDate(DateBuff,sizeof(DateBuff)); + //-------------------------- + fprintf(OutputFile, XMLHead, UserName, TimerBuff); + fprintf(OutputFile, XMLStyles); + fprintf(OutputFile, XMLBeginSheet, "Horizontal"); + fprintf(OutputFile, XMLNames,1,1,1,int(AnalysisTitles.size()+Formulas.size()+COUNT_PARAMETERS)); + fprintf(OutputFile, XMLBeginTable, int(RoundTitles.size()+Formulas.size()+AnalysisTitles.size()+COUNT_PARAMETERS+1/*title*/), int(Statistics.size()+1)); + fprintf(OutputFile, XMLBRow); + fprintf(OutputFile, XMLCellTopName); + fprintf(OutputFile, XMLCellTopThread); + fprintf(OutputFile, XMLCellTopMode, ModeName); + for (AnalysisTitles_t::iterator j = AnalysisTitles.begin(); j != AnalysisTitles.end(); j++) + fprintf(OutputFile, XMLAnalysisTitle, j->c_str()+1); + for (Formulas_t::iterator j = Formulas.begin(); j != Formulas.end(); j++) + fprintf(OutputFile, XMLAnalysisTitle, j->first.c_str()+1); + for (RoundTitles_t::iterator j = RoundTitles.begin(); j != RoundTitles.end(); j++) + fprintf(OutputFile, XMLAnalysisTitle, j->c_str()); + string Info = Title; + for( size_t k = 0; k < RunInfo.size(); k++ ) + Info.append("; " + RunInfo[k].first + "=" + RunInfo[k].second); + fprintf(OutputFile, XMLCellEmptyWhite, Info.c_str()); + fprintf(OutputFile, XMLERow); + //------------------------ + for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) + { + fprintf(OutputFile, XMLBRow); + fprintf(OutputFile, XMLCellName, i->second->Name.c_str()); + fprintf(OutputFile, XMLCellThread,i->second->Threads); + fprintf(OutputFile, XMLCellMode, i->second->Mode.c_str()); + //statistics + AnalysisTitles_t::iterator at = AnalysisTitles.begin(); + for (Analysis_t::iterator j = i->second->Analysis.begin(); j != i->second->Analysis.end(); at++) + { + fprintf(OutputFile, XMLCellAnalysis, (*at != j->first)?"":(i->second->Analysis[j->first]).c_str()); + if(*at == j->first) j++; + } + //formulas + size_t place = 0; + Results_t &v = i->second->Results; + for (Formulas_t::iterator f = Formulas.begin(); f != Formulas.end(); f++, place++) + fprintf(OutputFile, XMLCellFormula, ExcelFormula(f->second, Formulas.size()-place, v.size(), true).c_str()); + //data + for (size_t k = 0; k < v.size(); k++) + { + fprintf(OutputFile, XMLCellData, v[k]); + } + if(v.size() < RoundTitles.size()) + fprintf(OutputFile, XMLMergeRow, int(RoundTitles.size() - v.size())); + fprintf(OutputFile, XMLERow); + } + //------------------------ + fprintf(OutputFile, XMLEndTable); + fprintf(OutputFile, XMLWorkSheetProperties,1,1,3,3,int(RoundTitles.size()+AnalysisTitles.size()+Formulas.size()+COUNT_PARAMETERS)); + fprintf(OutputFile, XMLAutoFilter,1,1,1,int(AnalysisTitles.size()+Formulas.size()+COUNT_PARAMETERS)); + fprintf(OutputFile, XMLEndWorkSheet); + //---------------------------------------- + fprintf(OutputFile, XMLEndWorkbook); + fclose(OutputFile); + } + } +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics.h new file mode 100644 index 00000000..8f9a3816 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics.h @@ -0,0 +1,187 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Internal Intel tool + +#ifndef __STATISTICS_H__ +#define __STATISTICS_H__ + +#define _CRT_SECURE_NO_DEPRECATE 1 + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +typedef double value_t; + +/* + Statistical collector class. + + Resulting table output: + +---------------------------------------------------------------------------+ + | [Date] ... | + +----------+----v----+--v---+----------------+------------+-..-+------------+ + | TestName | Threads | Mode | Rounds results | Stat_type1 | .. | Stat_typeN | + +----------+---------+------+-+-+-+-..-+-+-+-+------------+-..-+------------+ + | | | | | | | .. | | | | | | | + .. ... ... .................. ...... .. + | | | | | | | .. | | | | | | | + +----------+---------+------+-+-+-+-..-+-+-+-+------------+-..-+------------+ + + Iterating table output: + +---------------------------------------------------------------------------+ + | [Date] <TestName>, Threads: <N>, Mode: <M>; for <Title>... | + +----------+----v----+--v---+----------------+------------+-..-+------------+ + +*/ + +class StatisticsCollector +{ +public: + typedef map<string, string> Analysis_t; + typedef vector<value_t> Results_t; + +protected: + StatisticsCollector(const StatisticsCollector &); + + struct StatisticResults + { + string Name; + string Mode; + int Threads; + Results_t Results; + Analysis_t Analysis; + }; + + // internal members + //bool OpenFile; + StatisticResults *CurrentKey; + string Title; + const char /**Name,*/ *ResultsFmt; + string Name; + //! Data + typedef map<string, StatisticResults*> Statistics_t; + Statistics_t Statistics; + typedef vector<string> RoundTitles_t; + RoundTitles_t RoundTitles; + //TODO: merge those into one structure + typedef map<string, string> Formulas_t; + Formulas_t Formulas; + typedef set<string> AnalysisTitles_t; + AnalysisTitles_t AnalysisTitles; + typedef vector<pair<string, string> > RunInfo_t; + RunInfo_t RunInfo; + +public: + struct TestCase { + StatisticResults *access; + TestCase() : access(0) {} + TestCase(StatisticResults *link) : access(link) {} + const char *getName() const { return access->Name.c_str(); } + const char *getMode() const { return access->Mode.c_str(); } + int getThreads() const { return access->Threads; } + const Results_t &getResults() const { return access->Results; } + const Analysis_t &getAnalysis() const { return access->Analysis; } + }; + + enum Sorting { + ByThreads, ByAlg + }; + + //! Data and output types + enum DataOutput { + // Verbosity level enumeration + Statistic = 1, //< Analytical data - computed after all iterations and rounds passed + Result = 2, //< Testing data - collected after all iterations passed + Iteration = 3, //< Verbose data - collected at each iteration (for each size - in case of containers) + // ExtraVerbose is not applicabe yet :) be happy, but flexibility is always welcome + + // Next constants are bit-fields + Stdout = 1<<8, //< Output to the console + TextFile = 1<<9, //< Output to plain text file "name.txt" (delimiter is TAB by default) + ExcelXML = 1<<10, //< Output to Excel-readable XML-file "name.xml" + HTMLFile = 1<<11, //< Output to HTML file "name.html" + PivotMode= 1<<15 //< Puts all the rounds into one columt to better fit for pivot table in Excel + }; + + //! Constructor. Specify tests set name which used as name of output files + StatisticsCollector(const char *name, Sorting mode = ByThreads, const char *fmt = "%g") + : CurrentKey(NULL), ResultsFmt(fmt), Name(name), SortMode(mode) {} + + ~StatisticsCollector(); + + //! Set tests set title, supporting printf-like arguments + void SetTitle(const char *fmt, ...); + + //! Specify next test key + TestCase SetTestCase(const char *name, const char *mode, int threads); + //! Specify next test key + void SetTestCase(const TestCase &t) { SetTestCase(t.getName(), t.getMode(), t.getThreads()); } + //! Reserve specified number of rounds. Use for efficiency. Used mostly internally + void ReserveRounds(size_t index); + //! Add result of the measure + void AddRoundResult(const TestCase &, value_t v); + //! Add result of the current measure + void AddRoundResult(value_t v) { if(CurrentKey) AddRoundResult(TestCase(CurrentKey), v); } + //! Add title of round + void SetRoundTitle(size_t index, const char *fmt, ...); + //! Add numbered title of round + void SetRoundTitle(size_t index, int num) { SetRoundTitle(index, "%d", num); } + //! Get number of rounds + size_t GetRoundsCount() const { return RoundTitles.size(); } + // Set statistic value for the test + void AddStatisticValue(const TestCase &, const char *type, const char *fmt, ...); + // Set statistic value for the current test + void AddStatisticValue(const char *type, const char *fmt, ...); + //! Add Excel-processing formulas. @arg formula can contain more than one instances of + //! ROUNDS template which transforms into the range of cells with result values + //TODO://! #1 .. #n templates represent data cells from the first to the last + //TODO: merge with Analisis + void SetStatisticFormula(const char *name, const char *formula); + //! Add information about run or compile parameters + void SetRunInfo(const char *title, const char *fmt, ...); + void SetRunInfo(const char *title, int num) { SetRunInfo(title, "%d", num); } + + //! Data output + void Print(int dataOutput, const char *ModeName = "Mode"); + +private: + Sorting SortMode; +}; + +//! using: Func(const char *fmt, ...) { vargf2buff(buff, 128, fmt);... +#define vargf2buff(name, size, fmt) \ + char name[size]; memset(name, 0, size); \ + va_list args; va_start(args, fmt); \ + vsnprintf(name, size-1, fmt, args); \ + va_end(args); + + +inline std::string Format(const char *fmt, ...) { + vargf2buff(buf, 1024, fmt); // from statistics.h + return std::string(buf); +} + +#ifdef STATISTICS_INLINE +#include "statistics.cpp" +#endif +#endif //__STATISTICS_H__ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics_xml.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics_xml.h new file mode 100644 index 00000000..3a31ce10 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/statistics_xml.h @@ -0,0 +1,196 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const char XMLBRow[]= +" <Row>\n"; + +const char XMLERow[]= +" </Row>\n"; + +const char XMLHead[]= +"<?xml version=\"1.0\"?>\n" +"<?mso-application progid=\"Excel.Sheet\"?>\n\ +<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\n\ + xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n\ + xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n\ + xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"\n\ + xmlns:html=\"http://www.w3.org/TR/REC-html40\">\n\ + <DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\">\n\ + <Author>%s</Author>\n\ + <Created>%s</Created>\n\ + <Company>Intel Corporation</Company>\n\ + </DocumentProperties>\n\ + <ExcelWorkbook xmlns=\"urn:schemas-microsoft-com:office:excel\">\n\ + <RefModeR1C1/>\n\ + </ExcelWorkbook>\n"; + + const char XMLStyles[]= + " <Styles>\n\ + <Style ss:ID=\"Default\" ss:Name=\"Normal\">\n\ + <Alignment ss:Vertical=\"Bottom\" ss:Horizontal=\"Left\" ss:WrapText=\"0\"/>\n\ + </Style>\n\ + <Style ss:ID=\"s26\">\n\ + <Alignment ss:Vertical=\"Top\" ss:Horizontal=\"Left\" ss:WrapText=\"0\"/>\n\ + <Borders>\n\ + <Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + </Borders>\n\ + <Interior ss:Color=\"#FFFF99\" ss:Pattern=\"Solid\"/>\n\ + </Style>\n\ + <Style ss:ID=\"s25\">\n\ + <Alignment ss:Vertical=\"Top\" ss:Horizontal=\"Left\" ss:WrapText=\"0\"/>\n\ + <Borders>\n\ + <Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + </Borders>\n\ + <Interior ss:Color=\"#CCFFFF\" ss:Pattern=\"Solid\"/>\n\ + </Style>\n\ + <Style ss:ID=\"s24\">\n\ + <Alignment ss:Vertical=\"Top\" ss:Horizontal=\"Left\" ss:WrapText=\"0\"/>\n\ + <Borders>\n\ + <Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + </Borders>\n\ + <Interior ss:Color=\"#CCFFCC\" ss:Pattern=\"Solid\"/>\n\ + </Style>\n\ + <Style ss:ID=\"s23\">\n\ + <Alignment ss:Vertical=\"Top\" ss:Horizontal=\"Left\" ss:WrapText=\"0\"/>\n\ + <Borders>\n\ + <Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + <Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\"/>\n\ + </Borders>\n\ + </Style>\n\ + </Styles>\n"; + +const char XMLBeginSheet[]= +" <Worksheet ss:Name=\"%s\">\n"; + +const char XMLNames[]= +" <Names>\n\ + <NamedRange ss:Name=\"_FilterDatabase\" ss:RefersTo=\"R%dC%d:R%dC%d\" ss:Hidden=\"1\"/>\n\ + </Names>\n"; + +const char XMLBeginTable[]= +" <Table ss:ExpandedColumnCount=\"%d\" ss:ExpandedRowCount=\"%d\" x:FullColumns=\"1\"\n\ + x:FullRows=\"1\">\n"; + +const char XMLColumsHorizontalTable[]= +" <Column ss:Index=\"1\" ss:Width=\"108.75\"/>\n\ + <Column ss:Index=\"%d\" ss:Width=\"77.25\" ss:Span=\"%d\"/>\n"; + +const char XMLColumsVerticalTable[]= +" <Column ss:Index=\"1\" ss:Width=\"77.25\" ss:Span=\"%d\"/>\n"; + +const char XMLNameAndTime[]= +" <Cell><Data ss:Type=\"String\">%s</Data></Cell>\n\ + <Cell><Data ss:Type=\"String\">%s</Data></Cell>\n\ + <Cell><Data ss:Type=\"String\">%s</Data></Cell>\n"; + +const char XMLTableParamAndTitle[]= +" <Cell><Data ss:Type=\"Number\">%d</Data></Cell>\n\ + <Cell><Data ss:Type=\"Number\">%d</Data></Cell>\n\ + <Cell><Data ss:Type=\"Number\">%d</Data></Cell>\n\ + <Cell><Data ss:Type=\"String\">%s</Data></Cell>\n"; + +//-------------- +const char XMLCellTopName[]= +" <Cell ss:StyleID=\"s25\"><Data ss:Type=\"String\">Name</Data></Cell>\n"; +const char XMLCellTopThread[]= +" <Cell ss:StyleID=\"s25\"><Data ss:Type=\"String\">Threads</Data></Cell>\n"; +const char XMLCellTopMode[]= +" <Cell ss:StyleID=\"s25\"><Data ss:Type=\"String\">%s</Data></Cell>\n"; +//--------------------- +const char XMLAnalysisTitle[]= +" <Cell ss:StyleID=\"s25\"><Data ss:Type=\"String\">%s</Data></Cell>\n"; + +const char XMLCellName[]= +" <Cell ss:StyleID=\"s24\"><Data ss:Type=\"String\">%s</Data></Cell>\n"; + +const char XMLCellThread[]= +" <Cell ss:StyleID=\"s24\"><Data ss:Type=\"Number\">%d</Data></Cell>\n"; + +const char XMLCellMode[]= +" <Cell ss:StyleID=\"s24\"><Data ss:Type=\"String\">%s</Data></Cell>\n"; + +const char XMLCellAnalysis[]= +" <Cell ss:StyleID=\"s26\"><Data ss:Type=\"String\">%s</Data></Cell>\n"; + +const char XMLCellFormula[]= +" <Cell ss:StyleID=\"s26\" ss:Formula=\"%s\"><Data ss:Type=\"Number\"></Data></Cell>\n"; + +const char XMLCellData[]= +" <Cell ss:StyleID=\"s23\"><Data ss:Type=\"Number\">%g</Data></Cell>\n"; + +const char XMLMergeRow[]= +" <Cell ss:StyleID=\"s23\" ss:MergeAcross=\"%d\" ><Data ss:Type=\"String\"></Data></Cell>\n"; + +const char XMLCellEmptyWhite[]= +" <Cell><Data ss:Type=\"String\">%s</Data></Cell>\n"; + +const char XMLCellEmptyTitle[]= +" <Cell ss:StyleID=\"s25\"><Data ss:Type=\"String\"></Data></Cell>\n"; + +const char XMLEndTable[]= +" </Table>\n"; + +const char XMLAutoFilter[]= +" <AutoFilter x:Range=\"R%dC%d:R%dC%d\" xmlns=\"urn:schemas-microsoft-com:office:excel\">\n\ + </AutoFilter>\n"; + +const char XMLEndWorkSheet[]= + " </Worksheet>\n"; + +const char XMLWorkSheetProperties[]= +" <WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">\n\ + <Unsynced/>\n\ + <Selected/>\n\ + <FreezePanes/>\n\ + <FrozenNoSplit/>\n\ + <SplitHorizontal>%d</SplitHorizontal>\n\ + <TopRowBottomPane>%d</TopRowBottomPane>\n\ + <SplitVertical>%d</SplitVertical>\n\ + <LeftColumnRightPane>%d</LeftColumnRightPane>\n\ + <ActivePane>0</ActivePane>\n\ + <Panes>\n\ + <Pane>\n\ + <Number>3</Number>\n\ + </Pane>\n\ + <Pane>\n\ + <Number>1</Number>\n\ + </Pane>\n\ + <Pane>\n\ + <Number>2</Number>\n\ + </Pane>\n\ + <Pane>\n\ + <Number>0</Number>\n\ + <ActiveRow>0</ActiveRow>\n\ + <ActiveCol>%d</ActiveCol>\n\ + </Pane>\n\ + </Panes>\n\ + <ProtectObjects>False</ProtectObjects>\n\ + <ProtectScenarios>False</ProtectScenarios>\n\ + </WorksheetOptions>\n"; + +const char XMLEndWorkbook[]= + "</Workbook>\n"; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_async_return.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_async_return.cpp new file mode 100644 index 00000000..59272556 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_async_return.cpp @@ -0,0 +1,222 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + This microbenchmark measures prioritization of the tasks that were spawned to execute async_node + successor's body. The idea of the prioritization is to have TBB worker threads react eagerly on + the work, which was returned back to the graph through async_node's gateway interface while + being occupied by CPU work generated by function_node with nested parallelism. Worker threads + should prefer async_node task instead of next parallel_for task. The result of correct work + prioritization is the interleaving of CPU and ASYNC work: + + ASYNC task=1 started, thread_idx=0 + CPU task=1 started, thread_idx=0 + CPU task=1, nested pfor task=0, thread_idx=0 + CPU task=1, nested pfor task=4, thread_idx=1 + ASYNC task=1 finished, thread_idx=0 + ASYNC task=2 started, thread_idx=0 + CPU task=1, nested pfor task=1, thread_idx=0 + CPU task=1, nested pfor task=5, thread_idx=1 + ASYNC task=2 finished, thread_idx=0 + ASYNC task=3 started, thread_idx=0 + CPU task=1, nested pfor task=2, thread_idx=0 + CPU task=1, nested pfor task=6, thread_idx=1 + ASYNC task=3 finished, thread_idx=0 + ASYNC task=4 started, thread_idx=0 + CPU task=1, nested pfor task=3, thread_idx=0 + CPU task=1, nested pfor task=7, thread_idx=1 + ASYNC task=4 finished, thread_idx=0 + ASYNC task=5 started, thread_idx=0 + CPU task=1 finished, thread_idx=0 + CPU task=2 started, thread_idx=0 + CPU task=2, nested pfor task=0, thread_idx=0 + CPU task=2, nested pfor task=4, thread_idx=1 + CPU task=2, nested pfor task=5, thread_idx=1 + ASYNC task=5 finished, thread_idx=0 + ASYNC task=6 started, thread_idx=0 + CPU task=2, nested pfor task=1, thread_idx=0 + ASYNC task=6 finished, thread_idx=1 + CPU task=2, nested pfor task=2, thread_idx=0 + ASYNC task=7 started, thread_idx=1 + CPU task=2, nested pfor task=6, thread_idx=1 + ASYNC task=7 finished, thread_idx=0 + ASYNC task=8 started, thread_idx=0 + CPU task=2, nested pfor task=7, thread_idx=1 + CPU task=2, nested pfor task=3, thread_idx=0 + CPU task=2 finished, thread_idx=0 + ASYNC task=8 finished, thread_idx=1 + Elapsed time: 8.002 + + The parameters are chosen so that CPU and ASYNC work take approximately the same time. +*/ + +#define TBB_PREVIEW_FLOW_GRAPH_FEATURES __TBB_CPF_BUILD + +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/concurrent_queue.h" +#include "tbb/tick_count.h" +#include "tbb/tbb_thread.h" +#include "tbb/flow_graph.h" +#include "tbb/task_arena.h" +#include <vector> +#include <cstdio> + +const int NUM_THREADS = 2; // number of threads TBB is initialized with +const int CPU_LIMIT = 2; // number of repetitions of sub-graph with function_node +const double CPU_SPIN = 1.; // execution time of every parallel_for task +const int NESTED_CPU_TASKS_COUNT = 4 * NUM_THREADS; // number of parallel_for tasks +const int ASYNC_LIMIT = 8; // number of repetitions of sub-graph with async_node +const double ASYNC_SPIN = 0.5; // execution time of every async_node work + +void spin(double s) { + tbb::tick_count start = tbb::tick_count::now(); + while ((tbb::tick_count::now() - start).seconds() < s); +} + +typedef int data_type; +typedef tbb::flow::async_node<data_type, data_type> async_node_type; +typedef tbb::flow::multifunction_node<data_type, + tbb::flow::tuple<data_type, data_type> > decider_node_type; + +struct AsyncActivity { + typedef async_node_type::gateway_type gateway_type; + + struct work_type { + data_type input; + gateway_type* gateway; + }; + bool done; + bool end_of_work() { return done; } + tbb::concurrent_queue<work_type> my_queue; + tbb::tbb_thread my_service_thread; + + struct ServiceThreadFunc { + void operator()(AsyncActivity* activity) { + while (!activity->end_of_work()) { + work_type work; + while (activity->my_queue.try_pop(work)) { + spin(ASYNC_SPIN); // do work + work.gateway->try_put(work.input); + work.gateway->release_wait(); + } + } + } + }; + + void stop_and_wait() { + done = true; + my_service_thread.join(); + } + + void submit(data_type input, gateway_type* gateway) { + work_type work = { input, gateway }; + gateway->reserve_wait(); + my_queue.push(work); + } + + AsyncActivity() : done(false), my_service_thread(ServiceThreadFunc(), this) {} +}; + +struct StartBody { + bool has_run; + bool operator()(data_type& input) { + if (has_run) return false; + else { + input = 1; + has_run = true; + return true; + } + } + StartBody() : has_run(false) {} +}; + +struct ParallelForBody { + const data_type& my_input; + ParallelForBody(const data_type& input) : my_input(input) {} + void operator()(const data_type& p) const { + std::printf(" CPU task=%d, nested pfor task=%d, thread_idx=%d\n", my_input, p, + tbb::this_task_arena::current_thread_index()); + spin(CPU_SPIN); + } +}; + +struct CpuWorkBody { + const int parallel_for_tasks_count; + data_type operator()(const data_type& input) { + std::printf("CPU task=%d started, thread_idx=%d\n", input, + tbb::this_task_arena::current_thread_index()); + tbb::parallel_for(0, parallel_for_tasks_count, ParallelForBody(input)); + return input; + } + CpuWorkBody() : parallel_for_tasks_count(NESTED_CPU_TASKS_COUNT) {} +}; + +struct DeciderBody { + const int& my_limit; + DeciderBody( const int& limit ) : my_limit( limit ) {} + void operator()(data_type input, decider_node_type::output_ports_type& ports) { + const char* work_type = my_limit == ASYNC_LIMIT ? "ASYNC" : "CPU"; + std::printf("%s task=%d finished, thread_idx=%d\n", work_type, input, + tbb::this_task_arena::current_thread_index()); + if (input < my_limit) + tbb::flow::get<0>(ports).try_put(input + 1); + else + tbb::flow::get<1>(ports).try_put(input + 1); + } +}; + +struct AsyncSubmissionBody { + AsyncActivity* my_activity; + void operator()(data_type input, async_node_type::gateway_type& gateway) { + my_activity->submit(input, &gateway); + std::printf("ASYNC task=%d started, thread_idx=%d\n", input, + tbb::this_task_arena::current_thread_index()); + } + AsyncSubmissionBody(AsyncActivity* activity) : my_activity(activity) {} +}; + +int main() { + tbb::task_scheduler_init init(NUM_THREADS); + AsyncActivity activity; + tbb::flow::graph g; + + tbb::flow::source_node<data_type> starter_node(g, StartBody(), false); + tbb::flow::function_node<data_type, data_type> cpu_work_node(g, tbb::flow::unlimited, CpuWorkBody()); + decider_node_type cpu_restarter_node(g, tbb::flow::unlimited, DeciderBody(CPU_LIMIT)); + async_node_type async_node(g, tbb::flow::unlimited, AsyncSubmissionBody(&activity)); + decider_node_type async_restarter_node(g, tbb::flow::unlimited, DeciderBody(ASYNC_LIMIT) +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + , /*priority=*/1 +#endif + ); + + tbb::flow::make_edge(starter_node, cpu_work_node); + tbb::flow::make_edge(cpu_work_node, cpu_restarter_node); + tbb::flow::make_edge(tbb::flow::output_port<0>(cpu_restarter_node), cpu_work_node); + + tbb::flow::make_edge(starter_node, async_node); + tbb::flow::make_edge(async_node, async_restarter_node); + tbb::flow::make_edge(tbb::flow::output_port<0>(async_restarter_node), async_node); + + tbb::tick_count start_time = tbb::tick_count::now(); + starter_node.activate(); + g.wait_for_all(); + activity.stop_and_wait(); + std::printf("Elapsed time: %lf seconds\n", (tbb::tick_count::now() - start_time).seconds()); + + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_cpq_throughput_test.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_cpq_throughput_test.cpp new file mode 100644 index 00000000..04f6cc11 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_cpq_throughput_test.cpp @@ -0,0 +1,290 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_CUSTOM_MAIN 1 +#define HARNESS_NO_PARSE_COMMAND_LINE 1 + +#include <cstdlib> +#include <cmath> +#include <queue> +#include "tbb/tbb_stddef.h" +#include "tbb/spin_mutex.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/concurrent_priority_queue.h" +#include "../test/harness.h" +#include "../examples/common/utility/utility.h" +#if _MSC_VER +#pragma warning(disable: 4996) +#endif + +#define IMPL_SERIAL 0 +#define IMPL_STL 1 +#define IMPL_CPQ 2 + +using namespace tbb; + +// test parameters & defaults +int impl = IMPL_CPQ; // which implementation to test +int contention = 1; // busywork between operations in us +int preload = 0; // # elements to pre-load queue with +double throughput_window = 30.0; // in seconds +int ops_per_iteration = 20; // minimum: 2 (1 push, 1 pop) +const int sample_operations = 1000; // for timing checks + +// global data & types +int pushes_per_iter; +int pops_per_iter; +tbb::atomic<unsigned int> operation_count; +tbb::tick_count start; + +// a non-trivial data element to use in the priority queue +const int padding_size = 15; // change to get cache line size for test machine +class padding_type { +public: + int p[padding_size]; + padding_type& operator=(const padding_type& other) { + if (this != &other) { + for (int i=0; i<padding_size; ++i) { + p[i] = other.p[i]; + } + } + return *this; + } +}; + +class my_data_type { +public: + int priority; + padding_type padding; + my_data_type() : priority(0) {} +}; + +class my_less { +public: + bool operator()(my_data_type d1, my_data_type d2) { + return d1.priority<d2.priority; + } +}; + +// arrays to get/put data from/to to generate non-trivial accesses during busywork +my_data_type *input_data; +my_data_type *output_data; +size_t arrsz; + +// Serial priority queue +std::priority_queue<my_data_type, std::vector<my_data_type>, my_less > *serial_cpq; + +// Coarse-locked priority queue +spin_mutex *my_mutex; +std::priority_queue<my_data_type, std::vector<my_data_type>, my_less > *stl_cpq; + +// TBB concurrent_priority_queue +concurrent_priority_queue<my_data_type, my_less > *agg_cpq; + +// Busy work and calibration helpers +unsigned int one_us_iters = 345; // default value + +// if user wants to calibrate to microseconds on particular machine, call +// this at beginning of program; sets one_us_iters to number of iters to +// busy_wait for approx. 1 us +void calibrate_busy_wait() { + const unsigned niter = 1000000; + tbb::tick_count t0 = tbb::tick_count::now(); + for (volatile unsigned int i=0; i<niter; ++i) continue; + tbb::tick_count t1 = tbb::tick_count::now(); + + one_us_iters = (unsigned int)(niter/(t1-t0).seconds())*1e-6; + printf("one_us_iters: %d\n", one_us_iters); +} + +void busy_wait(int us) +{ + unsigned int iter = us*one_us_iters; + for (volatile unsigned int i=0; i<iter; ++i) continue; +} + +// Push to priority queue, depending on implementation +void do_push(my_data_type elem, int nThr, int impl) { + if (impl == IMPL_SERIAL) { + serial_cpq->push(elem); + } + else if (impl == IMPL_STL) { + tbb::spin_mutex::scoped_lock myLock(*my_mutex); + stl_cpq->push(elem); + } + else if (impl == IMPL_CPQ) { + agg_cpq->push(elem); + } +} + +// Pop from priority queue, depending on implementation +my_data_type do_pop(int nThr, int impl) { + my_data_type elem; + if (impl == IMPL_SERIAL) { + if (!serial_cpq->empty()) { + elem = serial_cpq->top(); + serial_cpq->pop(); + return elem; + } + } + else if (impl == IMPL_STL) { + tbb::spin_mutex::scoped_lock myLock(*my_mutex); + if (!stl_cpq->empty()) { + elem = stl_cpq->top(); + stl_cpq->pop(); + return elem; + } + } + else if (impl == IMPL_CPQ) { + if (agg_cpq->try_pop(elem)) { + return elem; + } + } + return elem; +} + + +struct TestThroughputBody : NoAssign { + int nThread; + int implementation; + + TestThroughputBody(int nThread_, int implementation_) : + nThread(nThread_), implementation(implementation_) {} + + void operator()(const int threadID) const { + tbb::tick_count now; + size_t pos_in = threadID, pos_out = threadID; + my_data_type elem; + while (1) { + for (int i=0; i<sample_operations; i+=ops_per_iteration) { + // do pushes + for (int j=0; j<pushes_per_iter; ++j) { + elem = input_data[pos_in]; + do_push(elem, nThread, implementation); + busy_wait(contention); + pos_in += nThread; + if (pos_in >= arrsz) pos_in = pos_in % arrsz; + } + // do pops + for (int j=0; j<pops_per_iter; ++j) { + output_data[pos_out] = do_pop(nThread, implementation); + busy_wait(contention); + pos_out += nThread; + if (pos_out >= arrsz) pos_out = pos_out % arrsz; + } + } + now = tbb::tick_count::now(); + operation_count += sample_operations; + if ((now-start).seconds() >= throughput_window) break; + } + } +}; + +void TestSerialThroughput() { + tbb::tick_count now; + + serial_cpq = new std::priority_queue<my_data_type, std::vector<my_data_type>, my_less >; + for (int i=0; i<preload; ++i) do_push(input_data[i], 1, IMPL_SERIAL); + + TestThroughputBody my_serial_test(1, IMPL_SERIAL); + start = tbb::tick_count::now(); + NativeParallelFor(1, my_serial_test); + now = tbb::tick_count::now(); + delete serial_cpq; + + printf("SERIAL 1 %10d\n", int(operation_count/(now-start).seconds())); +} + +void TestThroughputCpqOnNThreads(int nThreads) { + tbb::tick_count now; + + if (impl == IMPL_STL) { + stl_cpq = new std::priority_queue<my_data_type, std::vector<my_data_type>, my_less >; + for (int i=0; i<preload; ++i) do_push(input_data[i], nThreads, IMPL_STL); + + TestThroughputBody my_stl_test(nThreads, IMPL_STL); + start = tbb::tick_count::now(); + NativeParallelFor(nThreads, my_stl_test); + now = tbb::tick_count::now(); + delete stl_cpq; + + printf("STL %3d %10d\n", nThreads, int(operation_count/(now-start).seconds())); + } + else if (impl == IMPL_CPQ) { + agg_cpq = new concurrent_priority_queue<my_data_type, my_less >; + for (int i=0; i<preload; ++i) do_push(input_data[i], nThreads, IMPL_CPQ); + + TestThroughputBody my_cpq_test(nThreads, IMPL_CPQ); + start = tbb::tick_count::now(); + NativeParallelFor(nThreads, my_cpq_test); + now = tbb::tick_count::now(); + delete agg_cpq; + + printf("CPQ %3d %10d\n", nThreads, int(operation_count/(now-start).seconds())); + } +} + + +int main(int argc, char *argv[]) { + utility::thread_number_range threads(tbb::task_scheduler_init::default_num_threads); + struct select_impl{ + static bool validate(const int & impl){ + return ((impl == IMPL_SERIAL) || (impl == IMPL_STL) || (impl == IMPL_CPQ)); + } + }; + utility::parse_cli_arguments(argc,argv,utility::cli_argument_pack() + .positional_arg(threads,"n-of-threads",utility::thread_number_range_desc) + .positional_arg(contention,"contention"," busywork between operations, in us") + .positional_arg(impl,"queue_type", "which implementation to test. One of 0(SERIAL), 1(STL), 2(CPQ) ", select_impl::validate) + .positional_arg(preload,"preload","number of elements to pre-load queue with") + .positional_arg(ops_per_iteration, "batch size" ,"minimum: 2 (1 push, 1 pop)") + .positional_arg(throughput_window, "duration", "in seconds") + ); + + std::cout<< "Priority queue performance test "<<impl<<" will run with "<<contention<<"us contention " + "using "<<threads<<" threads, "<<ops_per_iteration<<" batch size, "<<preload<<" pre-loaded elements," + " for "<<throughput_window<<" seconds.\n" + <<std::flush + ; + + srand(42); + arrsz = 100000; + input_data = new my_data_type[arrsz]; + output_data = new my_data_type[arrsz]; + for (size_t i=0; i<arrsz; ++i) { + input_data[i].priority = rand()%100; + } + //calibrate_busy_wait(); + pushes_per_iter = ops_per_iteration/2; + pops_per_iter = ops_per_iteration/2; + operation_count = 0; + + // Initialize mutex for Coarse-locked priority_queue + cache_aligned_allocator<spin_mutex> my_mutex_allocator; + my_mutex = (spin_mutex *)my_mutex_allocator.allocate(1); + + if (impl == IMPL_SERIAL) { + TestSerialThroughput(); + } + else { + for( int p=threads.first; p<=threads.last; p = threads.step(p) ) { + TestThroughputCpqOnNThreads(p); + } + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_fibonacci_cutoff.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_fibonacci_cutoff.cpp new file mode 100644 index 00000000..4e0b2a58 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_fibonacci_cutoff.cpp @@ -0,0 +1,126 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <cstdio> +#include <cstdlib> + +#include "tbb/task_scheduler_init.h" +#include "tbb/task.h" +#include "tbb/tick_count.h" +#include "fibonacci_impl_tbb.cpp" + +long CutOff = 1; + +long SerialFib( const long n ); + +long ParallelFib( const long n ); + +inline void dump_title() { + printf(" Mode, P, repeat, N, =fib value, cutoff, time, speedup\n"); +} + +inline void output(int P, long n, long c, int T, double serial_elapsed, double elapsed, long result) { + printf("%s,%4d,%7d,%3ld,%11ld,%7ld,%9.3g,%8.3g\n", ( (P == 0) ? " Serial" : "Parallel" ), + P, T, n, result, c, elapsed, serial_elapsed / elapsed); +} + +#define MOVE_BY_FOURTHS 1 +inline long calculate_new_cutoff(const long lo, const long hi) { +#if MOVE_BY_FOURTHS + return lo + (3 + hi - lo ) / 4; +#else + return (hi + lo)/2; +#endif +} + +void find_cutoff(const int P, const long n, const int T, const double serial_elapsed) { + long lo = 1, hi = n; + double elapsed = 0, lo_elapsed = 0, hi_elapsed = 0; + long final_cutoff = -1; + + tbb::task_scheduler_init init(P); + + while(true) { + CutOff = calculate_new_cutoff(lo, hi); + long result = 0; + tbb::tick_count t0; + for (int t = -1; t < T; ++t) { + if (t == 0) t0 = tbb::tick_count::now(); + result += ParallelFib(n); + } + elapsed = (tbb::tick_count::now() - t0).seconds(); + output(P,n,CutOff,T,serial_elapsed,elapsed,result); + + if (serial_elapsed / elapsed >= P/2.0) { + final_cutoff = CutOff; + if (hi == CutOff) { + if (hi == lo) { + // we have had this value at both above and below 50% + lo = 1; lo_elapsed = 0; + } else { + break; + } + } + hi = CutOff; + hi_elapsed = elapsed; + } else { + if (lo == CutOff) break; + lo = CutOff; + lo_elapsed = elapsed; + } + } + + double interpolated_cutoff = lo + ( P/2.0 - serial_elapsed/lo_elapsed ) * ( (hi - lo) / ( serial_elapsed/hi_elapsed - serial_elapsed/lo_elapsed )); + + if (final_cutoff != -1) { + printf("50%% efficiency cutoff is %ld ( linearly interpolated cutoff is %g )\n", final_cutoff, interpolated_cutoff); + } else { + printf("Cannot achieve 50%% efficiency\n"); + } + + return; +} + +int main(int argc, char *argv[]) { + if (argc < 4) { + printf("Usage: %s threads n repetitions\nWhere n make sense in range [25; 45]\n",argv[0]); + return 1; + } + + int P = atoi(argv[1]); + volatile long n = atol(argv[2]); + int T = atoi(argv[3]); + + // warmup parallel engine + ParallelFib(n); + + dump_title(); + + // collect serial time + long serial_result = 0; + tbb::tick_count t0; + for (int t = -1; t < T; ++t) { + if (t == 0) t0 = tbb::tick_count::now(); + serial_result += SerialFib(n); + } + double serial_elapsed = (tbb::tick_count::now() - t0).seconds(); + output(0,n,0,T,serial_elapsed,serial_elapsed,serial_result); + + // perform search + find_cutoff(P,n,T,serial_elapsed); + + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_framework.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_framework.h new file mode 100644 index 00000000..d670e831 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_framework.h @@ -0,0 +1,347 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TIME_FRAMEWORK_H__ +#define __TIME_FRAMEWORK_H__ + +#include <cstdlib> +#include <math.h> +#include <vector> +#include <string> +#include <sstream> +#include "tbb/tbb_stddef.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" +#define HARNESS_CUSTOM_MAIN 1 +#include "../test/harness.h" +#include "../test/harness_barrier.h" +#define STATISTICS_INLINE +#include "statistics.h" + +#ifndef ARG_TYPE +typedef intptr_t arg_t; +#else +typedef ARG_TYPE arg_t; +#endif + +class Timer { + tbb::tick_count tick; +public: + Timer() { tick = tbb::tick_count::now(); } + double get_time() { return (tbb::tick_count::now() - tick).seconds(); } + double diff_time(const Timer &newer) { return (newer.tick - tick).seconds(); } + double mark_time() { tbb::tick_count t1(tbb::tick_count::now()), t2(tick); tick = t1; return (t1 - t2).seconds(); } + double mark_time(const Timer &newer) { tbb::tick_count t(tick); tick = newer.tick; return (tick - t).seconds(); } +}; + +class TesterBase /*: public tbb::internal::no_copy*/ { +protected: + friend class TestProcessor; + friend class TestRunner; + + //! it is barrier for synchronizing between threads + Harness::SpinBarrier *barrier; + + //! number of tests per this tester + const int tests_count; + + //! number of threads to operate + int threads_count; + + //! some value for tester + arg_t value; + + //! tester name + const char *tester_name; + + // avoid false sharing + char pad[128 - sizeof(arg_t) - sizeof(int)*2 - sizeof(void*)*2 ]; + +public: + //! init tester base. @arg ntests is number of embedded tests in this tester. + TesterBase(int ntests) + : barrier(NULL), tests_count(ntests) + {} + virtual ~TesterBase() {} + + //! internal function + void base_init(arg_t v, int t, Harness::SpinBarrier &b) { + threads_count = t; + barrier = &b; + value = v; + init(); + } + + //! optionally override to init after value and threads count were set. + virtual void init() { } + + //! Override to provide your names + virtual std::string get_name(int testn) { + return Format("test %d", testn); + } + + //! optionally override to init test mode just before execution for a given thread number. + virtual void test_prefix(int testn, int threadn) { } + + //! Override to provide main test's entry function returns a value to record + virtual value_t test(int testn, int threadn) = 0; + + //! Type of aggregation from results of threads + enum result_t { + SUM, AVG, MIN, MAX + }; + + //! Override to change result type for the test. Return postfix for test name or 0 if result type is not needed. + virtual const char *get_result_type(int /*testn*/, result_t type) const { + return type == AVG ? "" : 0; // only average result by default + } +}; + +/***** +a user's tester concept: + +class tester: public TesterBase { +public: + //! init tester with known amount of work + tester() : TesterBase(<user-specified tests count>) { ... } + + //! run a test with sequental number @arg test_number for @arg thread. + / *override* / value_t test(int test_number, int thread); +}; + +******/ + +template<typename Tester, int scale = 1> +class TimeTest : public Tester { + /*override*/ value_t test(int testn, int threadn) { + Timer timer; + Tester::test(testn, threadn); + return timer.get_time() * double(scale); + } +}; + +template<typename Tester> +class NanosecPerValue : public Tester { + /*override*/ value_t test(int testn, int threadn) { + Timer timer; + Tester::test(testn, threadn); + // return time (ns) per value + return timer.get_time()*1e+9/double(Tester::value); + } +}; + +template<typename Tester, int scale = 1> +class ValuePerSecond : public Tester { + /*override*/ value_t test(int testn, int threadn) { + Timer timer; + Tester::test(testn, threadn); + // return value per seconds/scale + return double(Tester::value)/(timer.get_time()*scale); + } +}; + +template<typename Tester, int scale = 1> +class NumberPerSecond : public Tester { + /*override*/ value_t test(int testn, int threadn) { + Timer timer; + Tester::test(testn, threadn); + // return a scale per seconds + return double(scale)/timer.get_time(); + } +}; + +// operate with single tester +class TestRunner { + friend class TestProcessor; + friend struct RunArgsBody; + TestRunner(const TestRunner &); // don't copy + + const char *tester_name; + StatisticsCollector *stat; + std::vector<std::vector<StatisticsCollector::TestCase> > keys; + +public: + TesterBase &tester; + + template<typename Test> + TestRunner(const char *name, Test *test) + : tester_name(name), tester(*static_cast<TesterBase*>(test)) + { + test->tester_name = name; + } + + ~TestRunner() { delete &tester; } + + void init(arg_t value, int threads, Harness::SpinBarrier &barrier, StatisticsCollector *s) { + tester.base_init(value, threads, barrier); + stat = s; + keys.resize(tester.tests_count); + for(int testn = 0; testn < tester.tests_count; testn++) { + keys[testn].resize(threads); + std::string test_name(tester.get_name(testn)); + for(int threadn = 0; threadn < threads; threadn++) + keys[testn][threadn] = stat->SetTestCase(tester_name, test_name.c_str(), threadn); + } + } + + void run_test(int threadn) { + for(int testn = 0; testn < tester.tests_count; testn++) { + tester.test_prefix(testn, threadn); + tester.barrier->wait(); // <<<<<<<<<<<<<<<<< Barrier before running test mode + value_t result = tester.test(testn, threadn); + stat->AddRoundResult(keys[testn][threadn], result); + } + } + + void post_process(StatisticsCollector &report) { + const int threads = tester.threads_count; + for(int testn = 0; testn < tester.tests_count; testn++) { + size_t coln = keys[testn][0].getResults().size()-1; + value_t rsum = keys[testn][0].getResults()[coln]; + value_t rmin = rsum, rmax = rsum; + for(int threadn = 1; threadn < threads; threadn++) { + value_t result = keys[testn][threadn].getResults()[coln]; + rsum += result; // for both SUM or AVG + if(rmin > result) rmin = result; + if(rmax < result) rmax = result; + } + std::string test_name(tester.get_name(testn)); + const char *rname = tester.get_result_type(testn, TesterBase::SUM); + if( rname ) { + report.SetTestCase(tester_name, (test_name+rname).c_str(), threads); + report.AddRoundResult(rsum); + } + rname = tester.get_result_type(testn, TesterBase::MIN); + if( rname ) { + report.SetTestCase(tester_name, (test_name+rname).c_str(), threads); + report.AddRoundResult(rmin); + } + rname = tester.get_result_type(testn, TesterBase::AVG); + if( rname ) { + report.SetTestCase(tester_name, (test_name+rname).c_str(), threads); + report.AddRoundResult(rsum / threads); + } + rname = tester.get_result_type(testn, TesterBase::MAX); + if( rname ) { + report.SetTestCase(tester_name, (test_name+rname).c_str(), threads); + report.AddRoundResult(rmax); + } + } + } +}; + +struct RunArgsBody { + const vector<TestRunner*> &run_list; + RunArgsBody(const vector<TestRunner*> &a) : run_list(a) { } +#ifndef __TBB_parallel_for_H + void operator()(int thread) const { +#else + void operator()(const tbb::blocked_range<int> &r) const { + ASSERT( r.begin() + 1 == r.end(), 0); + int thread = r.begin(); +#endif + for(size_t i = 0; i < run_list.size(); i++) + run_list[i]->run_test(thread); + } +}; + +//! Main test processor. +/** Override or use like this: + class MyTestCollection : public TestProcessor { + void factory(arg_t value, int threads) { + process( value, threads, + run("my1", new tester<my1>() ), + run("my2", new tester<my2>() ), + end ); + if(value == threads) + stat->Print(); + } +}; +*/ + +class TestProcessor { + friend class TesterBase; + + // <threads, collector> + typedef std::map<int, StatisticsCollector *> statistics_collection; + statistics_collection stat_by_threads; + +protected: + // Members + const char *collection_name; + // current stat + StatisticsCollector *stat; + // token + size_t end; + +public: + StatisticsCollector report; + + // token of tests list + template<typename Test> + TestRunner *run(const char *name, Test *test) { + return new TestRunner(name, test); + } + + // iteration processing + void process(arg_t value, int threads, ...) { + // prepare items + stat = stat_by_threads[threads]; + if(!stat) { + stat_by_threads[threads] = stat = new StatisticsCollector((collection_name + Format("@%d", threads)).c_str(), StatisticsCollector::ByAlg); + stat->SetTitle("Detailed log of %s running with %d threads.", collection_name, threads); + } + Harness::SpinBarrier barrier(threads); + // init args + va_list args; va_start(args, threads); + vector<TestRunner*> run_list; run_list.reserve(16); + while(true) { + TestRunner *item = va_arg(args, TestRunner*); + if( !item ) break; + item->init(value, threads, barrier, stat); + run_list.push_back(item); + } + va_end(args); + std::ostringstream buf; + buf << value; + const size_t round_number = stat->GetRoundsCount(); + stat->SetRoundTitle(round_number, buf.str().c_str()); + report.SetRoundTitle(round_number, buf.str().c_str()); + // run them +#ifndef __TBB_parallel_for_H + NativeParallelFor(threads, RunArgsBody(run_list)); +#else + tbb::parallel_for(tbb::blocked_range<int>(0,threads,1), RunArgsBody(run_list)); +#endif + // destroy args + for(size_t i = 0; i < run_list.size(); i++) { + run_list[i]->post_process(report); + delete run_list[i]; + } + } + +public: + TestProcessor(const char *name, StatisticsCollector::Sorting sort_by = StatisticsCollector::ByAlg) + : collection_name(name), stat(NULL), end(0), report(collection_name, sort_by) + { } + + ~TestProcessor() { + for(statistics_collection::iterator i = stat_by_threads.begin(); i != stat_by_threads.end(); i++) + delete i->second; + } +}; + +#endif// __TIME_FRAMEWORK_H__ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map.cpp new file mode 100644 index 00000000..2d87ef25 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map.cpp @@ -0,0 +1,257 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// configuration: +#define TBB_USE_THREADING_TOOLS 0 + +//! enable/disable std::map tests +#define STDTABLE 0 + +//! enable/disable old implementation tests (correct include file also) +#define OLDTABLE 0 +#define OLDTABLEHEADER "tbb/concurrent_hash_map-5468.h"//-4329 + +//! enable/disable experimental implementation tests (correct include file also) +#define TESTTABLE 0 +#define TESTTABLEHEADER "tbb/concurrent_unordered_map.h" + +//! avoid erase() +#define TEST_ERASE 1 + +////////////////////////////////////////////////////////////////////////////////// + +#include <cstdlib> +#include <math.h> +#include "tbb/tbb_stddef.h" +#include <vector> +#include <map> +// needed by hash_maps +#include <stdexcept> +#include <iterator> +#include <algorithm> // Need std::swap +#include <utility> // Need std::pair +#include "tbb/cache_aligned_allocator.h" +#include "tbb/tbb_allocator.h" +#include "tbb/spin_rw_mutex.h" +#include "tbb/aligned_space.h" +#include "tbb/atomic.h" +#define __TBB_concurrent_unordered_set_H +#include "tbb/internal/_concurrent_unordered_impl.h" +#undef __TBB_concurrent_unordered_set_H +// for test +#include "tbb/spin_mutex.h" +#include "time_framework.h" + + +using namespace tbb; +using namespace tbb::internal; + +struct IntHashCompare { + size_t operator() ( int x ) const { return x; } + bool operator() ( int x, int y ) const { return x==y; } + static long hash( int x ) { return x; } + bool equal( int x, int y ) const { return x==y; } +}; + +namespace version_current { + namespace tbb { using namespace ::tbb; namespace internal { using namespace ::tbb::internal; } } + namespace tbb { namespace interface5 { using namespace ::tbb::interface5; namespace internal { using namespace ::tbb::interface5::internal; } } } + #include "tbb/concurrent_hash_map.h" +} +typedef version_current::tbb::concurrent_hash_map<int,int> IntTable; + +#if OLDTABLE +#undef __TBB_concurrent_hash_map_H +namespace version_base { + namespace tbb { using namespace ::tbb; namespace internal { using namespace ::tbb::internal; } } + namespace tbb { namespace interface5 { using namespace ::tbb::interface5; namespace internal { using namespace ::tbb::interface5::internal; } } } + #include OLDTABLEHEADER +} +typedef version_base::tbb::concurrent_hash_map<int,int> OldTable; +#endif + +#if TESTTABLE +#undef __TBB_concurrent_hash_map_H +namespace version_new { + namespace tbb { using namespace ::tbb; namespace internal { using namespace ::tbb::internal; } } + namespace tbb { namespace interface5 { using namespace ::tbb::interface5; namespace internal { using namespace ::tbb::interface5::internal; } } } + #include TESTTABLEHEADER +} +typedef version_new::tbb::concurrent_unordered_map<int,int> TestTable; +#define TESTTABLE 1 +#endif + +/////////////////////////////////////// + +static const char *map_testnames[] = { + "1.insert", "2.count1st", "3.count2nd", "4.insert-exists", "5.erase " +}; + +template<typename TableType> +struct TestTBBMap : TesterBase { + TableType Table; + int n_items; + + TestTBBMap() : TesterBase(4+TEST_ERASE), Table(MaxThread*4) {} + void init() { n_items = value/threads_count; } + + std::string get_name(int testn) { + return std::string(map_testnames[testn]); + } + + double test(int test, int t) + { + switch(test) { + case 0: // fill + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + Table.insert( std::make_pair(i,i) ); + } + break; + case 1: // work1 + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + size_t c = Table.count( i ); + ASSERT( c == 1, NULL); + } + break; + case 2: // work2 + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + Table.count( i ); + } + break; + case 3: // work3 + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + Table.insert( std::make_pair(i,i) ); + } + break; +#if TEST_ERASE + case 4: // clean + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + ASSERT( Table.erase( i ), NULL); + } +#endif + } + return 0; + } +}; + +template<typename M> +struct TestSTLMap : TesterBase { + std::map<int, int> Table; + M mutex; + + int n_items; + TestSTLMap() : TesterBase(4+TEST_ERASE) {} + void init() { n_items = value/threads_count; } + + std::string get_name(int testn) { + return std::string(map_testnames[testn]); + } + + double test(int test, int t) + { + switch(test) { + case 0: // fill + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + typename M::scoped_lock with(mutex); + Table[i] = 0; + } + break; + case 1: // work1 + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + typename M::scoped_lock with(mutex); + size_t c = Table.count(i); + ASSERT( c == 1, NULL); + } + break; + case 2: // work2 + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + typename M::scoped_lock with(mutex); + Table.count(i); + } + break; + case 3: // work3 + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + typename M::scoped_lock with(mutex); + Table.insert(std::make_pair(i,i)); + } + break; + case 4: // clean + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + typename M::scoped_lock with(mutex); + Table.erase(i); + } + } + return 0; + } +}; + +class fake_mutex { +public: + class scoped_lock { + fake_mutex *p; + + public: + scoped_lock() {} + scoped_lock( fake_mutex &m ) { p = &m; } + ~scoped_lock() { } + void acquire( fake_mutex &m ) { p = &m; } + void release() { } + }; +}; + +class test_hash_map : public TestProcessor { +public: + test_hash_map() : TestProcessor("time_hash_map") {} + void factory(int value, int threads) { + if(Verbose) printf("Processing with %d threads: %d...\n", threads, value); + process( value, threads, +#if STDTABLE + run("std::map ", new NanosecPerValue<TestSTLMap<spin_mutex> >() ), +#endif +#if OLDTABLE + run("old::hmap", new NanosecPerValue<TestTBBMap<OldTable> >() ), +#endif + run("tbb::hmap", new NanosecPerValue<TestTBBMap<IntTable> >() ), +#if TESTTABLE + run("new::hmap", new NanosecPerValue<TestTBBMap<TestTable> >() ), +#endif + end ); + //stat->Print(StatisticsCollector::Stdout); + //if(value >= 2097152) stat->Print(StatisticsCollector::HTMLFile); + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +int main(int argc, char* argv[]) { + if(argc>1) Verbose = true; + //if(argc>2) ExtraVerbose = true; + MinThread = 1; MaxThread = task_scheduler_init::default_num_threads(); + ParseCommandLine( argc, argv ); + + ASSERT(tbb_allocator<int>::allocator_type() == tbb_allocator<int>::scalable, "expecting scalable allocator library to be loaded. Please build it by:\n\t\tmake tbbmalloc"); + + { + test_hash_map the_test; + for( int t=MinThread; t <= MaxThread; t++) + for( int o=/*2048*/(1<<8)*8; o<2200000; o*=2 ) + the_test.factory(o, t); + the_test.report.SetTitle("Nanoseconds per operation of (Mode) for N items in container (Name)"); + the_test.report.SetStatisticFormula("1AVG per size", "=AVERAGE(ROUNDS)"); + the_test.report.Print(StatisticsCollector::HTMLFile|StatisticsCollector::ExcelXML); + } + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map_fill.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map_fill.cpp new file mode 100644 index 00000000..7e3ca942 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map_fill.cpp @@ -0,0 +1,163 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// configuration: + +// Size of final table (must be multiple of STEP_*) +int MAX_TABLE_SIZE = 2000000; + +// Specify list of unique percents (5-30,100) to test against. Max 10 values +#define UNIQUE_PERCENTS PERCENT(5); PERCENT(10); PERCENT(20); PERCENT(30); PERCENT(100) + +#define SECONDS_RATIO 1000000 // microseconds + +// enable/disable tests for: +#define BOX1 "CHMap" +#define BOX1TEST ValuePerSecond<Uniques<tbb::concurrent_hash_map<int,int> >, SECONDS_RATIO> +#define BOX1HEADER "tbb/concurrent_hash_map.h" + +// enable/disable tests for: +#define BOX2 "CUMap" +#define BOX2TEST ValuePerSecond<Uniques<tbb::concurrent_unordered_map<int,int> >, SECONDS_RATIO> +#define BOX2HEADER "tbb/concurrent_unordered_map.h" + +// enable/disable tests for: +//#define BOX3 "OLD" +#define BOX3TEST ValuePerSecond<Uniques<tbb::concurrent_hash_map<int,int> >, SECONDS_RATIO> +#define BOX3HEADER "tbb/concurrent_hash_map-5468.h" + +#define TBB_USE_THREADING_TOOLS 0 +////////////////////////////////////////////////////////////////////////////////// + +#include <cstdlib> +#include <math.h> +#include "tbb/tbb_stddef.h" +#include <vector> +#include <map> +// needed by hash_maps +#include <stdexcept> +#include <iterator> +#include <algorithm> // Need std::swap +#include <utility> // Need std::pair +#include <cstring> // Need std::memset +#include <typeinfo> +#include "tbb/cache_aligned_allocator.h" +#include "tbb/tbb_allocator.h" +#include "tbb/spin_rw_mutex.h" +#include "tbb/aligned_space.h" +#include "tbb/atomic.h" +#define __TBB_concurrent_unordered_set_H +#include "tbb/internal/_concurrent_unordered_impl.h" +#undef __TBB_concurrent_unordered_set_H +// for test +#include "tbb/spin_mutex.h" +#include "time_framework.h" + + +using namespace tbb; +using namespace tbb::internal; + +///////////////////////////////////////////////////////////////////////////////////////// +// Input data built for test +int *Data; + +// Main test class used to run the timing tests. All overridden methods are called by the framework +template<typename TableType> +struct Uniques : TesterBase { + TableType Table; + int n_items; + + // Initializes base class with number of test modes + Uniques() : TesterBase(2), Table(MaxThread*16) { + //Table->max_load_factor(1); // add stub into hash_map to uncomment it + } + ~Uniques() {} + + // Returns name of test mode specified by number + /*override*/ std::string get_name(int testn) { + if(testn == 1) return "find"; + return "insert"; + } + + // Informs the class that value and threads number become known + /*override*/ void init() { + n_items = value/threads_count; // operations + } + + // Informs the class that the test mode for specified thread is about to start + /*override*/ void test_prefix(int testn, int t) { + barrier->wait(); + if(Verbose && !t && testn) printf("%s: inserted %u, %g%% of operations\n", tester_name, unsigned(Table.size()), 100.0*Table.size()/(value*testn)); + } + + // Executes test mode for a given thread. Return value is ignored when used with timing wrappers. + /*override*/ double test(int testn, int t) + { + if( testn == 0 ) { // do insertions + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + Table.insert( std::make_pair(Data[i],t) ); + } + } else { // do last finds + for(int i = t*n_items, e = (t+1)*n_items; i < e; i++) { + size_t c = + Table.count( Data[i] ); + ASSERT( c == 1, NULL ); // must exist + } + } + return 0; + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// +#undef max +#include <limits> + +// Using BOX declarations from configuration +#include "time_sandbox.h" + +int rounds = 0; +// Prepares the input data for given unique percent +void execute_percent(test_sandbox &the_test, int p) { + int input_size = MAX_TABLE_SIZE*100/p; + Data = new int[input_size]; + int uniques = p==100?std::numeric_limits<int>::max() : MAX_TABLE_SIZE; + ASSERT(p==100 || p <= 30, "Function is broken for %% > 30 except for 100%%"); + for(int i = 0; i < input_size; i++) + Data[i] = (rand()*rand())%uniques; + for(int t = MinThread; t <= MaxThread; t++) + the_test.factory(input_size, t); // executes the tests specified in BOX-es for given 'value' and threads + the_test.report.SetRoundTitle(rounds++, "%d%%", p); +} +#define PERCENT(x) execute_percent(the_test, x) + +int main(int argc, char* argv[]) { + if(argc>1) Verbose = true; + //if(argc>2) ExtraVerbose = true; + MinThread = 1; MaxThread = task_scheduler_init::default_num_threads(); + ParseCommandLine( argc, argv ); + if(getenv("TABLE_SIZE")) + MAX_TABLE_SIZE = atoi(getenv("TABLE_SIZE")); + + ASSERT(tbb_allocator<int>::allocator_type() == tbb_allocator<int>::scalable, "expecting scalable allocator library to be loaded. Please build it by:\n\t\tmake tbbmalloc"); + // Declares test processor + test_sandbox the_test("time_hash_map_fill"/*, StatisticsCollector::ByThreads*/); + srand(10101); + UNIQUE_PERCENTS; // test the percents + the_test.report.SetTitle("Operations per microsecond"); + the_test.report.SetRunInfo("Items", MAX_TABLE_SIZE); + the_test.report.Print(StatisticsCollector::HTMLFile|StatisticsCollector::ExcelXML); // Write files + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map_fill.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map_fill.html new file mode 100644 index 00000000..b038ab48 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_hash_map_fill.html @@ -0,0 +1,122 @@ +<HTML><BODY> +<H2>time_hash_map_fill</H2> +<P><a href=time_hash_map_fill.cpp>time_hash_map_fill.cpp</a> is a micro-benchmark specifically designed to highlight aspects of concurrent resizing algorithm of the hash tables. +It was derived from the Count Strings example that counts the number of unique words. But to exclude synchronization on the counters from the picture, +it was simplified to build just a set of unique numbers from an input array. The array is filled evenly by using a pseudo-random number generator from the standard C library for various proportions of unique numbers. +For example, for 5% of unique numbers, the same number is repeated 20 times on average. Together, it gives 5% of actual insertions and 95% are just lookups. However, in the beginning, there are more new keys occur than in the end. +In addition, a size of the source array correlates with input rates in order to produce the same number of unique keys at the end, and so exclude cache effects from the equation. +</P> +<H2>Diagram</H2><img src="time_hash_map_fill.gif"/> +<H3>Prepare results</H3> +<P>This benchmark outputs results in Excel* and html file formats by default. To generate text (CSV) file instead, specify STAT_FORMAT=pivot-csv environment variable. To change the default table size, set TABLE_SIZE. +<code><b><pre>src$ make time_hash_map_fill args=-v STAT_FORMAT=pivot-csv TABLE_SIZE=250000</pre></b></code>Or to get statistics from different runs: +<code><b><pre>src$ make time_hash_map_fill TABLE_SIZE=50000 run_cmd="bash ../../src/perf/<a href=run_statistics.sh>run_statistics.sh</a>"</pre></b></code> +</P> +<H3>Build diagram</H3>You can use <a href="http://ploticus.sourceforge.net/">Ploticus</a> to build diagram from the prepared data using this html file as a script. But first, the input data file should be sorted to join lines from different runs together, e.g.: +<code><b><pre>src$ sort -t , -k 1dr,2 -k 3n,4 -k 7n,7 ../build/<i>{scrambled_path}</i>/time_hash_map_fill.csv -o perf/time_hash_map_fill.csv</pre></b></code>Here, field 7 is "Column" field that contains input rates because run_statistics.sh adds hostname and number of the run as 5 and 6 fields. Now, to build gif diagram, run: +<code><b><pre>perf$ pl -maxrows 200000 -maxfields 1500000 -maxvector 1200000 -gif -scale 1.8 time_hash_map_fill.html</pre></b></code> +<H3>Script body</H3> +<hr/><pre> + +#setifnotgiven NAMES = $makelist("1.CHMap 2.CUMap 3.OLD") +#setifnotgiven LABLESIZE = 0.06 + +#proc settings + encodenames: yes + units: cm + +#proc getdata + file: time_hash_map_fill.csv + fieldnameheader: yes + delim: comma + showdata: no + select: @@Mode = insert + pf_fieldnames: Name Mode Threads Value + filter: + ##print @@Name,"@@Items on @@Column",@@3,@@Value + +#endproc + +#proc page + pagesize: 70 50 + tightcrop: yes +#endproc + +#proc processdata + action: summary + fields: Name Mode Threads + valfield: Value + fieldnames: Name Mode Threads Average sd sem n_obs Min Max + showdata: no + +#proc categories + axis: x + datafield: Mode + +#proc areadef + title: Throughput on Insert operation + titledetails: size=14 align=C + areaname: slide + xscaletype: categories + xautorange: datafield=Mode + xaxis.stubs: usecategories + xaxis.label: Threads across table sizes and % of input rates +// yrange: 0 70 + yautorange: datafield=Max,Min + yaxis.stubs: inc + yaxis.label: ops/ns +// yaxis.stubformat: %3.1f + autowidth: 1.1 + autoheight: 0.07 + frame: yes + +#for LABEL in @NAMES +#set NLABEL = $arithl(@NLABEL+1) +#set COLOR = $icolor( @NLABEL ) +#proc legendentry + label: @LABEL + sampletype: color + details: @COLOR + +#procdef catlines + select: @Name = @LABEL + catfield: Mode + subcatfield: Threads + subcats: auto + plotwidth: 0.8 + #saveas C + +#proc catlines + #clone C + dpsymbol: shape=square radius=@LABLESIZE style=solid color=@COLOR + valfield: Average + errfield: sd + +#proc catlines + #clone C + valfield: Max + dpsymbol: shape=triangle radius=@LABLESIZE style=solid color=@COLOR + +#proc catlines + #clone C + valfield: Min + dpsymbol: shape=downtriangle radius=@LABLESIZE style=solid color=@COLOR + +#endloop + +#proc legend + location: 3.2 max + seglen: 0.2 +#endproc +</pre> +<HR/> +<A HREF="../index.html">Up to parent directory</A> +<p></p> +Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +<P></P> +Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +<p></p> +* Other names and brands may be claimed as the property of others. +</BODY> +</HTML> diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_locked_work.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_locked_work.cpp new file mode 100644 index 00000000..2a7f0bb9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_locked_work.cpp @@ -0,0 +1,162 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +////// Test configuration //////////////////////////////////////////////////// +#define SECONDS_RATIO 1000000 // microseconds + +#ifndef REPEAT_K +#define REPEAT_K 50 // repeat coefficient +#endif + +int outer_work[] = {/*256,*/ 64, 16, 4, 0}; +int inner_work[] = {32, 8, 0 }; + +// keep it to calibrate the time of work without synchronization +#define BOX1 "baseline" +#define BOX1TEST TimeTest< TBB_Mutex<tbb::null_mutex>, SECONDS_RATIO > + +// enable/disable tests for: +#define BOX2 "spin_mutex" +#define BOX2TEST TimeTest< TBB_Mutex<tbb::spin_mutex>, SECONDS_RATIO > + +// enable/disable tests for: +#define BOX3 "spin_rw_mutex" +#define BOX3TEST TimeTest< TBB_Mutex<tbb::spin_rw_mutex>, SECONDS_RATIO > + +// enable/disable tests for: +#define BOX4 "queuing_mutex" +#define BOX4TEST TimeTest< TBB_Mutex<tbb::queuing_mutex>, SECONDS_RATIO > + +// enable/disable tests for: +//#define BOX5 "queuing_rw_mutex" +#define BOX5TEST TimeTest< TBB_Mutex<tbb::queuing_rw_mutex>, SECONDS_RATIO > + +////////////////////////////////////////////////////////////////////////////// + +#include <cstdlib> +#include <math.h> +#include <algorithm> // Need std::swap +#include <utility> // Need std::pair +#include <sstream> +#include "tbb/tbb_stddef.h" +#include "tbb/null_mutex.h" +#include "tbb/spin_rw_mutex.h" +#include "tbb/spin_mutex.h" +#include "tbb/queuing_mutex.h" +#include "tbb/queuing_rw_mutex.h" +#include "tbb/mutex.h" + +#if INTEL_TRIAL==2 +#include "tbb/parallel_for.h" // enable threading by TBB scheduler +#include "tbb/task_scheduler_init.h" +#include "tbb/blocked_range.h" +#endif +// for test +#include "time_framework.h" + +using namespace tbb; +using namespace tbb::internal; + +///////////////////////////////////////////////////////////////////////////////////////// + +//! base class for tests family +struct TestLocks : TesterBase { + // Inherits "value", "threads_count", and other variables + TestLocks() : TesterBase(/*number of modes*/sizeof(outer_work)/sizeof(int)) {} + //! returns name of test part/mode + /*override*/std::string get_name(int testn) { + std::ostringstream buf; + buf.width(4); buf.fill('0'); + buf << outer_work[testn]; // mode number + return buf.str(); + } + //! enables results types and returns theirs suffixes + /*override*/const char *get_result_type(int, result_t type) const { + switch(type) { + case MIN: return " min"; + case MAX: return " max"; + default: return 0; + } + } + //! repeats count + int repeat_until(int /*test_n*/) const { + return REPEAT_K*100;//TODO: suggest better? + } + //! fake work + void do_work(int work) volatile { + for(int i = 0; i < work; i++) { + volatile int x = i; + __TBB_Pause(0); // just to call inline assembler + x *= work/threads_count; + } + } +}; + +//! template test unit for any of TBB mutexes +template<typename M> +struct TBB_Mutex : TestLocks { + M mutex; + + double test(int testn, int /*threadn*/) + { + for(int r = 0; r < repeat_until(testn); ++r) { + do_work(outer_work[testn]); + { + typename M::scoped_lock with(mutex); + do_work(/*inner work*/value); + } + } + return 0; + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +//Using BOX declarations +#include "time_sandbox.h" + +// run tests for each of inner work value +void RunLoops(test_sandbox &the_test, int thread) { + for( unsigned i=0; i<sizeof(inner_work)/sizeof(int); ++i ) + the_test.factory(inner_work[i], thread); +} + +int main(int argc, char* argv[]) { + if(argc>1) Verbose = true; + int DefThread = task_scheduler_init::default_num_threads(); + MinThread = 1; MaxThread = DefThread+1; + ParseCommandLine( argc, argv ); + ASSERT(MinThread <= MaxThread, 0); +#if INTEL_TRIAL && defined(__TBB_parallel_for_H) + task_scheduler_init me(MaxThread); +#endif + { + test_sandbox the_test("time_locked_work", StatisticsCollector::ByThreads); + //TODO: refactor this out as RunThreads(test&) + for( int t = MinThread; t < DefThread && t <= MaxThread; t *= 2) + RunLoops( the_test, t ); // execute undersubscribed threads + if( DefThread > MinThread && DefThread <= MaxThread ) + RunLoops( the_test, DefThread ); // execute on all hw threads + if( DefThread < MaxThread) + RunLoops( the_test, MaxThread ); // execute requested oversubscribed threads + + the_test.report.SetTitle("Time of lock/unlock for mutex Name with Outer and Inner work"); + //the_test.report.SetStatisticFormula("1AVG per size", "=AVERAGE(ROUNDS)"); + the_test.report.Print(StatisticsCollector::HTMLFile|StatisticsCollector::ExcelXML, /*ModeName*/ "Outer work"); + } + return 0; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_lru_cache_throughput.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_lru_cache_throughput.cpp new file mode 100644 index 00000000..f7673fb1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_lru_cache_throughput.cpp @@ -0,0 +1,213 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../examples/common/utility/utility.h" +#include "tbb/tick_count.h" +//#include <tbb/parallel_for.h> +#include "tbb/task_scheduler_init.h" //for number of threads +#include <functional> + +#include "coarse_grained_raii_lru_cache.h" +#define TBB_PREVIEW_CONCURRENT_LRU_CACHE 1 +#include "tbb/concurrent_lru_cache.h" + +#define HARNESS_CUSTOM_MAIN 1 +#define HARNESS_NO_PARSE_COMMAND_LINE 1 + +#include "../src/test/harness.h" +#include "../src/test/harness_barrier.h" + +#include <vector> +#include <algorithm> +#include "tbb/mutex.h" + +//TODO: probably move this to separate header utility file +namespace micro_benchmarking{ +namespace utils{ + template <typename type> + void disable_elimination(type const& v){ + volatile type dummy = v; + (void) dummy; + } + //Busy work and calibration helpers + unsigned int one_us_iters = 345; // default value + + //TODO: add a CLI parameter for calibration run + // if user wants to calibrate to microseconds on particular machine, call + // this at beginning of program; sets one_us_iters to number of iters to + // busy_wait for approx. 1 us + void calibrate_busy_wait() { + const unsigned niter = 1000000; + tbb::tick_count t0 = tbb::tick_count::now(); + for (volatile unsigned int i=0; i<niter; ++i) continue; + tbb::tick_count t1 = tbb::tick_count::now(); + + one_us_iters = (unsigned int)(niter/(t1-t0).seconds())*1e-6; + } + + void busy_wait(int us) + { + unsigned int iter = us*one_us_iters; + for (volatile unsigned int i=0; i<iter; ++i) continue; + } +} +} + +struct parameter_pack{ + size_t time_window_sec; + size_t time_check_granularity_ops; + size_t cache_lru_history_size; + size_t time_of_item_use_usec; + size_t cache_miss_percent; + int threads_number; + size_t weight_of_initiation_call_usec; + bool use_serial_initiation_function; + parameter_pack( + size_t a_time_window_sec + ,size_t a_time_check_granularity_ops + ,size_t a_cache_lru_history_size + ,size_t a_time_of_item_use_usec, size_t a_cache_miss_percent + , int a_threads_number ,size_t a_weight_of_initiation_call_usec + , bool a_use_serial_initiation_function + ) : + time_window_sec(a_time_window_sec) + ,time_check_granularity_ops(a_time_check_granularity_ops) + ,cache_lru_history_size(a_cache_lru_history_size) + ,time_of_item_use_usec(a_time_of_item_use_usec) + ,cache_miss_percent(a_cache_miss_percent) + ,threads_number(a_threads_number) + ,weight_of_initiation_call_usec(a_weight_of_initiation_call_usec) + ,use_serial_initiation_function(a_use_serial_initiation_function) + {} +}; + +struct return_size_t { + size_t m_weight_of_initiation_call_usec; + bool use_serial_initiation_function; + return_size_t(size_t a_weight_of_initiation_call_usec, bool a_use_serial_initiation_function) + :m_weight_of_initiation_call_usec(a_weight_of_initiation_call_usec), use_serial_initiation_function(a_use_serial_initiation_function) + {} + size_t operator()(size_t key){ + static tbb::mutex mtx; + if (use_serial_initiation_function){ + mtx.lock(); + } + micro_benchmarking::utils::busy_wait(m_weight_of_initiation_call_usec); + if (use_serial_initiation_function){ + mtx.unlock(); + } + + return key; + } +}; + +template< typename a_cache_type> +struct throughput { + typedef throughput self_type; + typedef a_cache_type cache_type; + + parameter_pack m_parameter_pack; + + + const size_t per_thread_sample_size ; + typedef std::vector<size_t> access_sequence_type; + access_sequence_type m_access_sequence; + cache_type m_cache; + Harness::SpinBarrier m_barrier; + tbb::atomic<size_t> loops_count; + + throughput(parameter_pack a_parameter_pack) + :m_parameter_pack(a_parameter_pack) + ,per_thread_sample_size(m_parameter_pack.cache_lru_history_size *(1 + m_parameter_pack.cache_miss_percent/100)) + ,m_access_sequence(m_parameter_pack.threads_number * per_thread_sample_size ) + ,m_cache(return_size_t(m_parameter_pack.weight_of_initiation_call_usec,m_parameter_pack.use_serial_initiation_function),m_parameter_pack.cache_lru_history_size) + + { + loops_count=0; + //TODO: check if changing from generating longer sequence to generating indexes in a specified range (i.e. making per_thread_sample_size fixed) give any change + std::generate(m_access_sequence.begin(),m_access_sequence.end(),std::rand); + } + + size_t operator()(){ + struct _{ static void retrieve_from_cache(self_type* _this, size_t thread_index){ + parameter_pack& p = _this->m_parameter_pack; + access_sequence_type::iterator const begin_it =_this->m_access_sequence.begin()+ thread_index * _this->per_thread_sample_size; + access_sequence_type::iterator const end_it = begin_it + _this->per_thread_sample_size; + + _this->m_barrier.wait(); + tbb::tick_count start = tbb::tick_count::now(); + + size_t local_loops_count =0; + do { + size_t part_of_the_sample_so_far = (local_loops_count * p.time_check_granularity_ops) % _this->per_thread_sample_size; + access_sequence_type::iterator const iteration_begin_it = begin_it + part_of_the_sample_so_far; + access_sequence_type::iterator const iteration_end_it = iteration_begin_it + + (std::min)(p.time_check_granularity_ops, _this->per_thread_sample_size - part_of_the_sample_so_far); + + for (access_sequence_type::iterator it = iteration_begin_it; it < iteration_end_it; ++it){ + typename cache_type::handle h = _this->m_cache[*it]; + micro_benchmarking::utils::busy_wait(p.time_of_item_use_usec); + micro_benchmarking::utils::disable_elimination(h.value()); + } + ++local_loops_count; + }while((tbb::tick_count::now()-start).seconds() < p.time_window_sec); + _this->loops_count+=local_loops_count; + }}; + m_barrier.initialize(m_parameter_pack.threads_number); + + NativeParallelFor(m_parameter_pack.threads_number,std::bind1st(std::ptr_fun(&_::retrieve_from_cache),this)); + + return loops_count * m_parameter_pack.time_check_granularity_ops; + } +}; + +int main(int argc,const char** args ){ + + size_t time_window_sec = 10; + size_t cache_lru_history_size = 1000; + size_t time_check_granularity_ops = 200; + size_t time_of_item_use_usec = 100; + size_t cache_miss_percent = 5; + int threads_number =tbb::task_scheduler_init::default_num_threads(); + size_t weight_of_initiation_call_usec =1000; + bool use_serial_initiation_function = false; + bool use_coarse_grained_locked_cache = false; + + parameter_pack p(time_window_sec, time_check_granularity_ops, cache_lru_history_size,time_of_item_use_usec,cache_miss_percent,threads_number,weight_of_initiation_call_usec,use_serial_initiation_function); + + utility::parse_cli_arguments(argc,args,utility::cli_argument_pack() + .arg(p.cache_lru_history_size,"cache-lru-history-size","") + .arg(p.time_window_sec,"time-window","time frame for measuring, in seconds") + .arg(p.threads_number,"n-of-threads","number of threads to run on") + .arg(p.time_of_item_use_usec,"time-of-item-use","time between consequent requests to the cache, in microseconds") + .arg(p.cache_miss_percent,"cache-miss-percent","cache miss percent ") + .arg(p.weight_of_initiation_call_usec,"initiation-call-weight","time occupied by a single call to initiation function, in microseconds") + .arg(p.use_serial_initiation_function,"use-serial-initiation-function","limit lock-based serial initiation function") + .arg(use_coarse_grained_locked_cache,"use-locked-version","use stl coarse grained lock based version") + ); + + typedef tbb::concurrent_lru_cache<size_t,size_t,return_size_t> tbb_cache; + typedef coarse_grained_raii_lru_cache<size_t,size_t,return_size_t> coarse_grained_locked_cache; + + size_t operations =0; + if (!use_coarse_grained_locked_cache){ + operations = throughput<tbb_cache>(p)(); + }else{ + operations = throughput<coarse_grained_locked_cache>(p)(); + } + std::cout<<"operations: "<<operations<<std::endl; + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_parallel_for_each.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_parallel_for_each.cpp new file mode 100644 index 00000000..65904fdb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_parallel_for_each.cpp @@ -0,0 +1,66 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <vector> +#include <list> +#include <iostream> +#include <cstdlib> +#include <algorithm> +#include <string> + +#include "tbb/parallel_for_each.h" +#include "tbb/tick_count.h" + +template <typename Type> +void foo( Type &f ) { + f += 1.0f; +} + +template <typename Container> +void test( std::string testName, const int N, const int numRepeats ) { + typedef typename Container::value_type Type; + Container v; + + for ( int i = 0; i < N; ++i ) { + v.push_back( static_cast<Type>(std::rand()) ); + } + + std::vector<double> times; + times.reserve( numRepeats ); + + for ( int i = 0; i < numRepeats; ++i ) { + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for_each( v.begin(), v.end(), foo<Type> ); + tbb::tick_count t1 = tbb::tick_count::now(); + times.push_back( (t1 - t0).seconds()*1e+3 ); + } + + std::sort( times.begin(), times.end() ); + std::cout << "Test " << testName << std::endl + << "min " << times[times.size() / 20] << " ms " << std::endl + << "med " << times[times.size() / 2] << " ms " << std::endl + << "max " << times[times.size() - times.size() / 20 - 1] << " ms " << std::endl; +} + +int main( int argc, char* argv[] ) { + const int N = argc > 1 ? std::atoi( argv[1] ) : 10 * 1000; + const int numRepeats = argc > 2 ? std::atoi( argv[2] ) : 10; + + test< std::vector<float> >( "std::vector<float>", N, numRepeats ); + test< std::list<float> >( "std::list<float>", N / 100, numRepeats ); + + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_resumable_tasks.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_resumable_tasks.cpp new file mode 100644 index 00000000..bcfb824f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_resumable_tasks.cpp @@ -0,0 +1,323 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_PREVIEW_RESUMABLE_TASKS 1 +#include "tbb/tbb_config.h" + +#include "tbb/task.h" +#include "tbb/task_group.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" + +#include "tbb/parallel_for.h" + +#include <vector> +#include <stack> +#include <functional> +#include <numeric> +#include <algorithm> + +/************************************************************************/ +/* SETTINGS */ +/************************************************************************/ + +const int DEF_BENCH_RUNS = 1000; + +/************************************************************************/ +/* HELPERS */ +/************************************************************************/ + +#include "harness_perf.h" // harness_perf::median + +template<typename T> +T get_median(std::vector<T>& times) { + return harness_perf::median(times.begin(), times.end()); +} + +/************************************************************************/ +/* SERIAL BENCHMARKS */ +/************************************************************************/ + +//! Allocate COROUTINES_NUM fibers in a row (suspend) in a recursive manner +//! and then swith back (resume) unwinding the ctx_stack. +void BenchCoroutinesAllocation() { + tbb::task_scheduler_init init(1); + + const int COROUTINES_NUM = 100; + std::stack<tbb::task::suspend_point> ctx_stack; + tbb::task_group tg; + + std::function<void(int)> recursive_f; + recursive_f = [=, &ctx_stack, &tg, &recursive_f](int i) { + if (i < COROUTINES_NUM) { + tg.run([&recursive_f, i]() { + recursive_f(i + 1); + }); + tbb::task::suspend([&ctx_stack](tbb::task::suspend_point ctx) { + ctx_stack.push(ctx); + }); + } + if (ctx_stack.size() != 0) { + tbb::task::suspend_point ctx = ctx_stack.top(); ctx_stack.pop(); + tbb::task::resume(ctx); + } + }; + tg.run([=, &recursive_f]() { + std::vector<double> times; + for (int i = 0; i < DEF_BENCH_RUNS; i++) { + tbb::tick_count tick = tbb::tick_count::now(); + recursive_f(1); + double interval = (tbb::tick_count::now() - tick).seconds() * 1e6; + times.push_back(interval); + } + // COROUTINES_NUM suspend and resume operations in each run + double median = get_median(times) / double(COROUTINES_NUM); + printf("Test 1 (Coroutines alloc/dealloc): Median time (microseconds): %.4f\n", median); + }); + tg.wait(); +} + +//! Create a task, which suspends and resumes intself, thus reusing once created coroutine +void BenchReusage() { + tbb::task_scheduler_init init(1); + tbb::task_group tg; + + std::vector<double> times; + tg.run([×]() { + for (int i = 0; i < DEF_BENCH_RUNS * 10; i++) { + tbb::tick_count tick = tbb::tick_count::now(); + tbb::task::suspend([](tbb::task::suspend_point ctx) { + tbb::task::resume(ctx); + }); + double diff = (tbb::tick_count::now() - tick).seconds() * 1e6; + times.push_back(diff); + } + }); + tg.wait(); + double median = get_median(times); + printf("Test 2 (Coroutine reusage): Median time (microseconds): %.4f\n", median); +} + +//! Create two tasks and switch between them (suspend current and resume previously suspended coroutine) +//! Measure an average time of the context switch +void BenchContextSwitch() { + tbb::task_scheduler_init init(1); + tbb::task_group tg; + const int N = 10000; // number of switches + const int tasks_num = 2; + + std::vector<double> times; + for (int i = 0; i < 100; ++i) { + int switch_counter = N; + tbb::task::suspend_point current_ctx = NULL; + + tbb::tick_count tick = tbb::tick_count::now(); + for (int j = 0; j < tasks_num; ++j) { + tg.run([=, &switch_counter, ¤t_ctx]() { + while (switch_counter-- > 0) { + tbb::task::suspend([=, &switch_counter, ¤t_ctx](tbb::task::suspend_point ctx) { + if (switch_counter == N - 1) { + current_ctx = ctx; + } else { + tbb::task::suspend_point ctx_to_resume = current_ctx; + current_ctx = ctx; + tbb::task::resume(ctx_to_resume); + } + }); + } + if (switch_counter == -1) { + tbb::task::resume(current_ctx); + } + }); + } + tg.wait(); + // To get an average context switch time divide the bench time by the number of context switches + double diff = ((tbb::tick_count::now() - tick).seconds() / double(N)) * 1e6; + times.push_back(diff); + } + printf("Test 3 (Context Switch): Median time (microseconds): %.4f\n", get_median(times)); +} + +/************************************************************************/ +/* PARALLEL BENCHMARKS */ +/************************************************************************/ + +//! Strong scaling benchmark with predefined number of iterations (N), each parallel_for task +//! suspends and resumes itself with a predefined busy-waiting iterations (work size). +//! Reports 3 numbers: serial, half of the machine, and full available concurrency +template <bool UseResumableTasks> +void ScalabilityBenchmark(const size_t work_size) { + const int N = 1000; + const int NUM_THREADS = tbb::task_scheduler_init::default_num_threads(); + const int STEP_RATIO = 2; + + // Count 3 scalability metrics: the serial, half and full machine concurrency + for (int i = 0; i <= NUM_THREADS; i += (NUM_THREADS / STEP_RATIO)) { + const int concurrency = (i == 0) ? 1 : i; // just to make step loop nice looking + tbb::task_scheduler_init init(concurrency); + std::vector<double> times; + for (int j = 0; j < 100; j++) { + tbb::tick_count tick = tbb::tick_count::now(); + tbb::parallel_for(0, N, [&work_size](const int /*j*/) { + if (UseResumableTasks) { + tbb::task::suspend([](tbb::task::suspend_point ctx) { + tbb::task::resume(ctx); + }); + } + for (volatile size_t k = 0; k < work_size; ++k); + }, tbb::simple_partitioner()); + double diff = (tbb::tick_count::now() - tick).seconds() * 1e3; + times.push_back(diff); + } + printf("Test 4 (Scalability): Work Size: %zu, With RT-feature: %s, Concurrency: %d, Time (milliseconds): %.4f\n", + work_size, (UseResumableTasks ? "true" : "false"), concurrency, get_median(times)); + } +} + +/************************************************************************/ +/* NATIVE IMPLEMENTATION */ +/************************************************************************/ + +// Dependencies section for co_context.h + +#if _WIN32 +#include <windows.h> // GetSystemInfo +#else +#include <unistd.h> // sysconf(_SC_PAGESIZE) +#endif + +namespace tbb { +namespace internal { +//! System dependent impl +inline size_t GetDefaultSystemPageSize() { +#if _WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwPageSize; +#else + return sysconf(_SC_PAGESIZE); +#endif +} +class governor { + //! Caches the size of OS regular memory page + static size_t DefaultPageSize; +public: + //! Staic accessor for OS regular memory page size + static size_t default_page_size () { + return DefaultPageSize ? DefaultPageSize : DefaultPageSize = GetDefaultSystemPageSize(); + } +}; +size_t governor::DefaultPageSize; +} // namespace internal +} // namespace tbb + +// No-op versions of __TBB_ASSERT/EX for co_context.h header +#define __TBB_ASSERT(predicate,comment) ((void)0) +#define __TBB_ASSERT_EX(predicate,comment) ((void)(1 && (predicate))) + +// TBB coroutines implementation +// Disable governor header to remove the dependency +#define _TBB_governor_H +#include "../tbb/co_context.h" +using namespace tbb::internal; +#undef _TBB_governor_H + +#define HARNESS_CUSTOM_MAIN 1 +#include "../test/harness.h" // NativeParallelFor + +namespace tbb { +namespace internal { +// Our native coroutine function +#if _WIN32 +/* [[noreturn]] */ inline void __stdcall co_local_wait_for_all(void* arg) { +#else +/* [[noreturn]] */ inline void co_local_wait_for_all(void* arg) { +#endif + coroutine_type next = *static_cast<coroutine_type*>(arg); + coroutine_type current; current_coroutine(current); + swap_coroutine(current, next); +} +} // namespace internal +} // namespace tbb + +// The same scalability benchmark as for TBB, but written with native OS fibers implementation +void BenchNativeImpl(const size_t work_size) { + const int N = 1000; + const int NUM_THREADS = tbb::task_scheduler_init::default_num_threads(); + const int STEP_RATIO = 2; + const size_t STACK_SIZE = 4 * 1024 * 1024; // Just like default TBB worker thread stack size + + // Count 3 scalability metrics: the serial, half and full machine concurrency + for (int i = 0; i <= NUM_THREADS; i += (NUM_THREADS / STEP_RATIO)) { + const int concurrency = (i == 0) ? 1 : i; // just to make step loop nice looking + const int sub_range = N / concurrency; + std::vector<double> times; + for (int r = 0; r < 100; r++) { + tbb::tick_count tick = tbb::tick_count::now(); + NativeParallelFor(concurrency, [=, &work_size, &sub_range](int /*idx*/) { + // Each iteration of sub-range emulates a single TBB task + for (int j = 0; j < sub_range; j++) { + coroutine_type co_next; + coroutine_type co_current; current_coroutine(co_current); + create_coroutine(co_next, STACK_SIZE, &co_current); + swap_coroutine(co_current, co_next); + + // Busy-wait for a while emulating some work + for (volatile size_t k = 0; k < work_size; ++k); + destroy_coroutine(co_next); + } + }); + double diff = (tbb::tick_count::now() - tick).seconds() * 1e3; + times.push_back(diff); + } + printf("Test 5 (Native Implementation): Work size: %zu, Concurrency: %d, Time (milliseconds): %.4f\n", + work_size, concurrency, get_median(times)); + } +} + +/************************************************************************/ +/* MAIN DRIVER */ +/************************************************************************/ + +int main() { + // Serial microbenchmarks + BenchCoroutinesAllocation(); + BenchReusage(); + BenchContextSwitch(); + + // Scalability benchmarks + // Big work size + no resumable tasks feature (false) + ScalabilityBenchmark<false>(100000); + // Big work size + resumable tasks feature (true) + ScalabilityBenchmark<true>(100000); + // Small work size + no resumable tasks feature (false) + ScalabilityBenchmark<false>(1000); + // Small work size + resumable tasks feature (true) + ScalabilityBenchmark<true>(1000); + // No any work + just resumable tasks feature (true) + ScalabilityBenchmark<true>(0); + + // Native implementation + // Big work size + BenchNativeImpl(100000); + // Small work size + BenchNativeImpl(1000); + // Just coroutines/fibers switching + BenchNativeImpl(0); + + return 0; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_sandbox.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_sandbox.h new file mode 100644 index 00000000..2b7ca7cf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_sandbox.h @@ -0,0 +1,167 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TIME_FRAMEWORK_H__ +#error time_framework.h must be included +#endif + +#define INJECT_TBB namespace tbb { using namespace ::tbb; namespace internal { using namespace ::tbb::internal; } } +#define INJECT_TBB5 namespace tbb { namespace interface5 { using namespace ::tbb::interface5; namespace internal { using namespace ::tbb::interface5::internal; } } } + +#ifndef INJECT_BOX_NAMES +#if defined(__TBB_task_H) || defined(__TBB_concurrent_unordered_internal_H) || defined(__TBB_reader_writer_lock_H) || defined(__TBB__concurrent_unordered_impl_H) +#define INJECT_BOX_NAMES INJECT_TBB INJECT_TBB5 +#else +#define INJECT_BOX_NAMES INJECT_TBB +#endif +#endif + +#ifdef BOX1 +namespace sandbox1 { + INJECT_BOX_NAMES +# ifdef BOX1HEADER +# include BOX1HEADER +# endif + typedef ::BOX1TEST testbox; +} +#endif +#ifdef BOX2 +namespace sandbox2 { + INJECT_BOX_NAMES +# ifdef BOX2HEADER +# include BOX2HEADER +# endif + typedef ::BOX2TEST testbox; +} +#endif +#ifdef BOX3 +namespace sandbox3 { + INJECT_BOX_NAMES +# ifdef BOX3HEADER +# include BOX3HEADER +# endif + typedef ::BOX3TEST testbox; +} +#endif +#ifdef BOX4 +namespace sandbox4 { + INJECT_BOX_NAMES +# ifdef BOX4HEADER +# include BOX4HEADER +# endif + typedef ::BOX4TEST testbox; +} +#endif +#ifdef BOX5 +namespace sandbox5 { + INJECT_BOX_NAMES +# ifdef BOX5HEADER +# include BOX5HEADER +# endif + typedef ::BOX5TEST testbox; +} +#endif +#ifdef BOX6 +namespace sandbox6 { + INJECT_BOX_NAMES +# ifdef BOX6HEADER +# include BOX6HEADER +# endif + typedef ::BOX6TEST testbox; +} +#endif +#ifdef BOX7 +namespace sandbox7 { + INJECT_BOX_NAMES +# ifdef BOX7HEADER +# include BOX7HEADER +# endif + typedef ::BOX7TEST testbox; +} +#endif +#ifdef BOX8 +namespace sandbox8 { + INJECT_BOX_NAMES +# ifdef BOX8HEADER +# include BOX8HEADER +# endif + typedef ::BOX8TEST testbox; +} +#endif +#ifdef BOX9 +namespace sandbox9 { + INJECT_BOX_NAMES +# ifdef BOX9HEADER +# include BOX9HEADER +# endif + typedef ::BOX9TEST testbox; +} +#endif + +//if harness.h included +#if defined(ASSERT) && !HARNESS_NO_PARSE_COMMAND_LINE +#ifndef TEST_PREFIX +#define TEST_PREFIX if(Verbose) printf("Processing with %d threads: %ld...\n", threads, long(value)); +#endif +#endif//harness included + +#ifndef TEST_PROCESSOR_NAME +#define TEST_PROCESSOR_NAME test_sandbox +#endif + +class TEST_PROCESSOR_NAME : public TestProcessor { +public: + TEST_PROCESSOR_NAME(const char *name, StatisticsCollector::Sorting sort_by = StatisticsCollector::ByAlg) + : TestProcessor(name, sort_by) {} + void factory(arg_t value, int threads) { +#ifdef TEST_PREFIX + TEST_PREFIX +#endif + process( value, threads, +#define RUNBOX(n) run(#n"."BOX##n, new sandbox##n::testbox() ) +#ifdef BOX1 + RUNBOX(1), +#endif +#ifdef BOX2 + RUNBOX(2), +#endif +#ifdef BOX3 + RUNBOX(3), +#endif +#ifdef BOX4 + RUNBOX(4), +#endif +#ifdef BOX5 + RUNBOX(5), +#endif +#ifdef BOX6 + RUNBOX(6), +#endif +#ifdef BOX7 + RUNBOX(7), +#endif +#ifdef BOX8 + RUNBOX(8), +#endif +#ifdef BOX9 + RUNBOX(9), +#endif + end ); +#ifdef TEST_POSTFIX + TEST_POSTFIX +#endif + } +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_split_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_split_node.cpp new file mode 100644 index 00000000..f19c209c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_split_node.cpp @@ -0,0 +1,116 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <iostream> +#include "tbb/flow_graph.h" +#include "tbb/tick_count.h" +#include "tbb/task_scheduler_init.h" + +static double bm_split_node(tbb::flow::graph& g, int nIter); +static double bm_broadcast_node(tbb::flow::graph& g, int nIter); +static double bm_queue_node(tbb::flow::graph& g, int nIter); + +typedef int my_type; +//typedef std::vector<int> my_type; + +const int nIter = 1 << 24; //16M +const int nSize = 100000000; + +int main() +{ + //set up one thread to eliminate scheduler overheads + tbb::task_scheduler_init tsi(1); + + tbb::flow::graph g; + + //1. queue_node benchmark; calculate queue_node time + plus threads creation time (if we have multi-threading) + std::cout << "queue benchmark: number of calls of putting element:" << nIter; + const double tQueue = bm_queue_node(g, nIter); + std::cout << "; time:" << tQueue << std::endl << std::endl; + + //2. split_node benchmark + std::cout << "split_node benchmark: number of calls:" << nIter; + const double tSplitNode = bm_split_node(g, nIter); + //output split_node benchmark result + std::cout << "; time:" << tSplitNode << std::endl; + std::cout << "exclusive split_node time:" << tSplitNode - tQueue << std::endl << std::endl; + + //3. broadcast_node benchmark + std::cout << "broadcast_node benchmark: number of calls:" << nIter; + const double tBNode = bm_broadcast_node(g, nIter); + //output broadcast_node benchmark result + std::cout << "; time:" << tBNode << std::endl; + std::cout << "exclusive broadcast_node time:" << tBNode - tQueue << std::endl; + + return 0; +} + +//! Dummy executing split_node, "nIter" calls; Returns time in seconds. +double bm_split_node(tbb::flow::graph& g, int nIter) +{ + my_type v1(nSize); + + tbb::flow::queue_node<my_type> my_queue1(g); + tbb::flow::tuple<my_type> my_tuple(1); + + tbb::flow::split_node< tbb::flow::tuple<my_type> > my_split_node(g); + make_edge(tbb::flow::get<0>(my_split_node.output_ports()), my_queue1); + + const tbb::tick_count t0 = tbb::tick_count::now(); + + //using split_node + for (int i = 0; i < nIter; ++i) + my_split_node.try_put(my_tuple); + + //barrier sync + g.wait_for_all(); + + return (tbb::tick_count::now() - t0).seconds(); +} + +//! Dummy executing broadcast_node; "nIter" calls; Returns time in seconds. +double bm_broadcast_node(tbb::flow::graph& g, int nIter) +{ + tbb::flow::queue_node<my_type> my_queue(g); + tbb::flow::broadcast_node<my_type> my_broadcast_node(g); + make_edge(my_broadcast_node, my_queue); + + my_type v(nSize); + + const tbb::tick_count t0 = tbb::tick_count::now(); + + //using broadcast_node + for (int i = 0; i < nIter; ++i) + my_broadcast_node.try_put(v); + //barrier sync + g.wait_for_all(); + + return (tbb::tick_count::now() - t0).seconds(); +} + +double bm_queue_node(tbb::flow::graph& g, int nIter) +{ + tbb::flow::queue_node<my_type> first_queue(g); + + my_type v(nSize); + + tbb::tick_count t0 = tbb::tick_count::now(); + //using queue_node + for (int i = 0; i < nIter; ++i) + first_queue.try_put(v); + g.wait_for_all(); + return (tbb::tick_count::now() - t0).seconds(); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_vector.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_vector.cpp new file mode 100644 index 00000000..ca23758a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/perf/time_vector.cpp @@ -0,0 +1,245 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +//#define DO_SCALABLEALLOC + +#include <cstdlib> +#include <cmath> +#include <vector> +#include <algorithm> +#include <functional> +#include <numeric> +#include "tbb/tbb_stddef.h" +#include "tbb/spin_mutex.h" +#ifdef DO_SCALABLEALLOC +#include "tbb/scalable_allocator.h" +#endif +#include "tbb/concurrent_vector.h" +#include "tbb/tbb_allocator.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/tick_count.h" +#include "tbb/blocked_range.h" +#define HARNESS_CUSTOM_MAIN 1 +#include "../test/harness.h" +//#include "harness_barrier.h" +#include "../test/harness_allocator.h" +#define STATISTICS_INLINE +#include "statistics.h" + +using namespace tbb; +bool ExtraVerbose = false; + +class Timer { + tbb::tick_count tick; +public: + Timer() { tick = tbb::tick_count::now(); } + double get_time() { return (tbb::tick_count::now() - tick).seconds(); } + double diff_time(const Timer &newer) { return (newer.tick - tick).seconds(); } + double mark_time() { tick_count t1(tbb::tick_count::now()), t2(tick); tick = t1; return (t1 - t2).seconds(); } + double mark_time(const Timer &newer) { tick_count t(tick); tick = newer.tick; return (tick - t).seconds(); } +}; + +/************************************************************************/ +/* TEST1 */ +/************************************************************************/ +#define mk_vector_test1(v, a) vector_test1<v<Timer, static_counting_allocator<a<Timer> > >, v<double, static_counting_allocator<a<double> > > > +template<class timers_vector_t, class values_vector_t> +class vector_test1 { + const char *mode; + StatisticsCollector &stat; + StatisticsCollector::TestCase key[16]; + +public: + vector_test1(const char *m, StatisticsCollector &s) : mode(m), stat(s) {} + + vector_test1 &operator()(size_t len) { + if(Verbose) printf("test1<%s>(%u): collecting timing statistics\n", mode, unsigned(len)); + __TBB_ASSERT(sizeof(Timer) == sizeof(double), NULL); + static const char *test_names[] = { + "b)creation wholly", + "a)creation by push", + "c)operation time per item", + 0 }; + for(int i = 0; test_names[i]; ++i) key[i] = stat.SetTestCase(test_names[i], mode, len); + + Timer timer0; timers_vector_t::allocator_type::init_counters(); + timers_vector_t tv(len); + Timer timer1; values_vector_t::allocator_type::init_counters(); + values_vector_t dv; + for (size_t i = 0; i < len; ++i) + dv.push_back( i ); + Timer timer2; + for (size_t i = 0; i < len; ++i) + { + dv[len-i-1] = timer0.diff_time(tv[i]); + tv[i].mark_time(); + } + stat.AddStatisticValue( key[2], "1total, ms", "%.3f", timer2.get_time()*1e+3 ); + stat.AddStatisticValue( key[1], "1total, ms", "%.3f", timer1.diff_time(timer2)*1e+3 ); + stat.AddStatisticValue( key[0], "1total, ms", "%.3f", timer0.diff_time(timer1)*1e+3 ); + //allocator statistics + stat.AddStatisticValue( key[0], "2total allocations", "%d", int(timers_vector_t::allocator_type::allocations) ); + stat.AddStatisticValue( key[1], "2total allocations", "%d", int(values_vector_t::allocator_type::allocations) ); + stat.AddStatisticValue( key[2], "2total allocations", "%d", 0); + stat.AddStatisticValue( key[0], "3total alloc#items", "%d", int(timers_vector_t::allocator_type::items_allocated) ); + stat.AddStatisticValue( key[1], "3total alloc#items", "%d", int(values_vector_t::allocator_type::items_allocated) ); + stat.AddStatisticValue( key[2], "3total alloc#items", "%d", 0); + //remarks + stat.AddStatisticValue( key[0], "9note", "segment creation time, us:"); + stat.AddStatisticValue( key[2], "9note", "average op-time per item, us:"); + Timer last_timer(timer2); double last_value = 0; + for (size_t j = 0, i = 2; i < len; i *= 2, j++) { + stat.AddRoundResult( key[0], (dv[len-i-1]-last_value)*1e+6 ); + last_value = dv[len-i-1]; + stat.AddRoundResult( key[2], last_timer.diff_time(tv[i])/double(i)*1e+6 ); + last_timer = tv[i]; + stat.SetRoundTitle(j, i); + } + tv.clear(); dv.clear(); + //__TBB_ASSERT(timers_vector_t::allocator_type::items_allocated == timers_vector_t::allocator_type::items_freed, NULL); + //__TBB_ASSERT(values_vector_t::allocator_type::items_allocated == values_vector_t::allocator_type::items_freed, NULL); + return *this; + } +}; + +/************************************************************************/ +/* TEST2 */ +/************************************************************************/ +#define mk_vector_test2(v, a) vector_test2<v<size_t, a<size_t> > > +template<class vector_t> +class vector_test2 { + const char *mode; + static const int ntrial = 10; + StatisticsCollector &stat; + +public: + vector_test2(const char *m, StatisticsCollector &s) : mode(m), stat(s) {} + + vector_test2 &operator()(size_t len) { + if(Verbose) printf("test2<%s>(%u): performing standard transformation sequence on vector\n", mode, unsigned(len)); + StatisticsCollector::TestCase init_key = stat.SetTestCase("allocate", mode, len); + StatisticsCollector::TestCase fill_key = stat.SetTestCase("fill", mode, len); + StatisticsCollector::TestCase proc_key = stat.SetTestCase("process", mode, len); + StatisticsCollector::TestCase full_key = stat.SetTestCase("total time", mode, len); + for (int i = 0; i < ntrial; i++) { + Timer timer0; + vector_t v1(len); + vector_t v2(len); + Timer timer1; + std::generate(v1.begin(), v1.end(), values(0)); + std::generate(v2.begin(), v2.end(), values(size_t(-len))); + Timer timer2; + std::reverse(v1.rbegin(), v1.rend()); + std::inner_product(v1.begin(), v1.end(), v2.rbegin(), 1); + std::sort(v1.rbegin(), v1.rend()); + std::sort(v2.rbegin(), v2.rend()); + std::set_intersection(v1.begin(), v1.end(), v2.rbegin(), v2.rend(), v1.begin()); + Timer timer3; + stat.AddRoundResult( proc_key, timer2.diff_time(timer3)*1e+3 ); + stat.AddRoundResult( fill_key, timer1.diff_time(timer2)*1e+3 ); + stat.AddRoundResult( init_key, timer0.diff_time(timer1)*1e+3 ); + stat.AddRoundResult( full_key, timer0.diff_time(timer3)*1e+3 ); + } + stat.SetStatisticFormula("1Average", "=AVERAGE(ROUNDS)"); + stat.SetStatisticFormula("2+/-", "=(MAX(ROUNDS)-MIN(ROUNDS))/2"); + return *this; + } + + class values + { + size_t value; + public: + values(size_t i) : value(i) {} + size_t operator()() { + return value++%(1|(value^55)); + } + }; +}; + +/************************************************************************/ +/* TEST3 */ +/************************************************************************/ +#define mk_vector_test3(v, a) vector_test3<v<char, local_counting_allocator<a<char>, size_t > > > +template<class vector_t> +class vector_test3 { + const char *mode; + StatisticsCollector &stat; + +public: + vector_test3(const char *m, StatisticsCollector &s) : mode(m), stat(s) {} + + vector_test3 &operator()(size_t len) { + if(Verbose) printf("test3<%s>(%u): collecting allocator statistics\n", mode, unsigned(len)); + static const size_t sz = 1024; + vector_t V[sz]; + StatisticsCollector::TestCase vinst_key = stat.SetTestCase("instances number", mode, len); + StatisticsCollector::TestCase count_key = stat.SetTestCase("allocations count", mode, len); + StatisticsCollector::TestCase items_key = stat.SetTestCase("allocated items", mode, len); + //stat.ReserveRounds(sz-1); + for (size_t c = 0, i = 0, s = sz/2; s >= 1 && i < sz; s /= 2, c++) + { + const size_t count = c? 1<<(c-1) : 0; + for (size_t e = i+s; i < e; i++) { + //if(count >= 16) V[i].reserve(count); + for (size_t j = 0; j < count; j++) + V[i].push_back(j); + } + stat.SetRoundTitle ( c, count ); + stat.AddRoundResult( vinst_key, s ); + stat.AddRoundResult( count_key, V[i-1].get_allocator().allocations ); + stat.AddRoundResult( items_key, V[i-1].get_allocator().items_allocated ); + } + return *this; + } +}; + +/************************************************************************/ +/* TYPES SET FOR TESTS */ +/************************************************************************/ +#define types_set(n, title, op) { StatisticsCollector Collector("time_vector"#n); Collector.SetTitle title; \ + {mk_vector_test##n(tbb::concurrent_vector, tbb::cache_aligned_allocator) ("TBB:NFS", Collector)op;} \ + {mk_vector_test##n(tbb::concurrent_vector, tbb::tbb_allocator) ("TBB:TBB", Collector)op;} \ + {mk_vector_test##n(tbb::concurrent_vector, std::allocator) ("TBB:STD", Collector)op;} \ + {mk_vector_test##n(std::vector, tbb::cache_aligned_allocator) ("STL:NFS", Collector)op;} \ + {mk_vector_test##n(std::vector, tbb::tbb_allocator) ("STL:TBB", Collector)op;} \ + {mk_vector_test##n(std::vector, std::allocator) ("STL:STD", Collector)op;} \ + Collector.Print(StatisticsCollector::Stdout|StatisticsCollector::HTMLFile|StatisticsCollector::ExcelXML); } + + +/************************************************************************/ +/* MAIN DRIVER */ +/************************************************************************/ +int main(int argc, char* argv[]) { + if(argc>1) Verbose = true; + if(argc>2) ExtraVerbose = true; + MinThread = 0; MaxThread = 500000; // use in another meaning - test#:problem size + ParseCommandLine( argc, argv ); + + ASSERT(tbb_allocator<int>::allocator_type() == tbb_allocator<int>::scalable, "expecting scalable allocator library to be loaded"); + + if(!MinThread || MinThread == 1) + types_set(1, ("Vectors performance test #1 for %d", MaxThread), (MaxThread) ) + if(!MinThread || MinThread == 2) + types_set(2, ("Vectors performance test #2 for %d", MaxThread), (MaxThread) ) + if(!MinThread || MinThread == 3) + types_set(3, ("Vectors performance test #3 for %d", MaxThread), (MaxThread) ) + + if(!Verbose) printf("done\n"); + return 0; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/index.html new file mode 100644 index 00000000..81a02952 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/index.html @@ -0,0 +1,42 @@ +<HTML> +<BODY> +<H2>Overview</H2> + +This directory has source code that must be statically linked into an RML client. + +<H2>Files</H2> + +<DL> +<DT><A HREF="rml_factory.h">rml_factory.h</A> +<DD>Text shared by <A HREF="rml_omp.cpp">rml_omp.cpp</A> and <A HREF="rml_tbb.cpp">rml_tbb.cpp</A>. + This is not an ordinary include file, so it does not have an #ifndef guard.</DD></DT> +</DL> + +<H3> Specific to client=OpenMP</H3> +<DL> +<DT><A HREF="rml_omp.cpp">rml_omp.cpp</A> +<DD>Source file for OpenMP client.</DD></DT> +<DT><A HREF="omp_dynamic_link.h">omp_dynamic_link.h</A></DT> +<DT><A HREF="omp_dynamic_link.cpp">omp_dynamic_link.cpp</A> +<DD>Source files for dynamic linking support. + The code is the code from the TBB source directory, but adjusted so that it + appears in namespace <TT>__kmp</TT> instead of namespace <TT>tbb::internal</TT>.</DD></DT> +</DL> +<H3> Specific to client=TBB</H3> +<DL> +<DT><A HREF="rml_tbb.cpp">rml_tbb.cpp</A> +<DD>Source file for TBB client. It uses the dynamic linking support from the TBB source directory.</DD></DT> +</DL> + +<HR/> +<A HREF="../index.html">Up to parent directory</A> +<p></p> +Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +<P></P> +Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +<p></p> +* Other names and brands may be claimed as the property of others. +</BODY> +</HTML> + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/library_assert.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/library_assert.h new file mode 100644 index 00000000..18ef9eb8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/library_assert.h @@ -0,0 +1,30 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef LIBRARY_ASSERT_H +#define LIBRARY_ASSERT_H + +#ifndef LIBRARY_ASSERT +#ifdef KMP_ASSERT2 +#define LIBRARY_ASSERT(x,y) KMP_ASSERT2((x),(y)) +#else +#include <assert.h> +#define LIBRARY_ASSERT(x,y) assert(x) +#define __TBB_DYNAMIC_LOAD_ENABLED 1 +#endif +#endif /* LIBRARY_ASSERT */ + +#endif /* LIBRARY_ASSERT_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/omp_dynamic_link.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/omp_dynamic_link.cpp new file mode 100644 index 00000000..71fdb234 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/omp_dynamic_link.cpp @@ -0,0 +1,20 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "omp_dynamic_link.h" +#include "library_assert.h" +#include "tbb/dynamic_link.cpp" // Refers to src/tbb, not include/tbb + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/omp_dynamic_link.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/omp_dynamic_link.h new file mode 100644 index 00000000..576c21f3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/omp_dynamic_link.h @@ -0,0 +1,26 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __KMP_omp_dynamic_link_H +#define __KMP_omp_dynamic_link_H + +#define OPEN_INTERNAL_NAMESPACE namespace __kmp { +#define CLOSE_INTERNAL_NAMESPACE } + +#include "library_assert.h" +#include "tbb/dynamic_link.h" // Refers to src/tbb, not include/tbb + +#endif /* __KMP_omp_dynamic_link_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_factory.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_factory.h new file mode 100644 index 00000000..0d6d6720 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_factory.h @@ -0,0 +1,90 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// No ifndef guard because this file is not a normal include file. + +#if TBB_USE_DEBUG +#define DEBUG_SUFFIX "_debug" +#else +#define DEBUG_SUFFIX +#endif /* TBB_USE_DEBUG */ + +// RML_SERVER_NAME is the name of the RML server library. +#if _WIN32||_WIN64 +#define RML_SERVER_NAME "irml" DEBUG_SUFFIX ".dll" +#elif __APPLE__ +#define RML_SERVER_NAME "libirml" DEBUG_SUFFIX ".dylib" +#elif __linux__ +#define RML_SERVER_NAME "libirml" DEBUG_SUFFIX ".so.1" +#elif __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __sun || _AIX +#define RML_SERVER_NAME "libirml" DEBUG_SUFFIX ".so" +#else +#error Unknown OS +#endif + +const ::rml::versioned_object::version_type CLIENT_VERSION = 2; + +#if __TBB_WEAK_SYMBOLS_PRESENT + #pragma weak __RML_open_factory + #pragma weak __RML_close_factory + extern "C" { + ::rml::factory::status_type __RML_open_factory ( ::rml::factory&, ::rml::versioned_object::version_type&, ::rml::versioned_object::version_type ); + void __RML_close_factory( ::rml::factory& f ); + } +#endif /* __TBB_WEAK_SYMBOLS_PRESENT */ + +::rml::factory::status_type FACTORY::open() { + // Failure of following assertion indicates that factory is already open, or not zero-inited. + LIBRARY_ASSERT( !library_handle, NULL ); + status_type (*open_factory_routine)( factory&, version_type&, version_type ); + dynamic_link_descriptor server_link_table[4] = { + DLD(__RML_open_factory,open_factory_routine), + MAKE_SERVER(my_make_server_routine), + DLD(__RML_close_factory,my_wait_to_close_routine), + GET_INFO(my_call_with_server_info_routine), + }; + status_type result; + if( dynamic_link( RML_SERVER_NAME, server_link_table, 4, &library_handle ) ) { + version_type server_version; + result = (*open_factory_routine)( *this, server_version, CLIENT_VERSION ); + // server_version can be checked here for incompatibility if necessary. + } else { + library_handle = NULL; + result = st_not_found; + } + return result; +} + +void FACTORY::close() { + if( library_handle ) + (*my_wait_to_close_routine)(*this); + if( (size_t)library_handle>FACTORY::c_dont_unload ) { + dynamic_unlink(library_handle); + library_handle = NULL; + } +} + +::rml::factory::status_type FACTORY::make_server( SERVER*& s, CLIENT& c) { + // Failure of following assertion means that factory was not successfully opened. + LIBRARY_ASSERT( my_make_server_routine, NULL ); + return (*my_make_server_routine)(*this,s,c); +} + +void FACTORY::call_with_server_info( ::rml::server_info_callback_t cb, void* arg ) const { + // Failure of following assertion means that factory was not successfully opened. + LIBRARY_ASSERT( my_call_with_server_info_routine, NULL ); + (*my_call_with_server_info_routine)( cb, arg ); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_omp.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_omp.cpp new file mode 100644 index 00000000..114ab90e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_omp.cpp @@ -0,0 +1,42 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "rml_omp.h" +#include "omp_dynamic_link.h" +#include <assert.h> + +namespace __kmp { +namespace rml { + +#define MAKE_SERVER(x) DLD(__KMP_make_rml_server,x) +#define GET_INFO(x) DLD(__KMP_call_with_my_server_info,x) +#define SERVER omp_server +#define CLIENT omp_client +#define FACTORY omp_factory + +#if __TBB_WEAK_SYMBOLS_PRESENT + #pragma weak __KMP_make_rml_server + #pragma weak __KMP_call_with_my_server_info + extern "C" { + omp_factory::status_type __KMP_make_rml_server( omp_factory& f, omp_server*& server, omp_client& client ); + void __KMP_call_with_my_server_info( ::rml::server_info_callback_t cb, void* arg ); + } +#endif /* __TBB_WEAK_SYMBOLS_PRESENT */ + +#include "rml_factory.h" + +} // rml +} // __kmp diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_tbb.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_tbb.cpp new file mode 100644 index 00000000..648c9276 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/client/rml_tbb.cpp @@ -0,0 +1,44 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../include/rml_tbb.h" +#include "tbb/dynamic_link.h" +#include <assert.h> + +namespace tbb { +namespace internal { +namespace rml { + +#define MAKE_SERVER(x) DLD(__TBB_make_rml_server,x) +#define GET_INFO(x) DLD(__TBB_call_with_my_server_info,x) +#define SERVER tbb_server +#define CLIENT tbb_client +#define FACTORY tbb_factory + +#if __TBB_WEAK_SYMBOLS_PRESENT + #pragma weak __TBB_make_rml_server + #pragma weak __TBB_call_with_my_server_info + extern "C" { + ::rml::factory::status_type __TBB_make_rml_server( tbb::internal::rml::tbb_factory& f, tbb::internal::rml::tbb_server*& server, tbb::internal::rml::tbb_client& client ); + void __TBB_call_with_my_server_info( ::rml::server_info_callback_t cb, void* arg ); + } +#endif /* __TBB_WEAK_SYMBOLS_PRESENT */ + +#include "rml_factory.h" + +} // rml +} // internal +} // tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/index.html new file mode 100644 index 00000000..d0bbf05b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/index.html @@ -0,0 +1,29 @@ +<HTML> +<BODY> +<H2>Overview</H2> + +This directory has the include files for the Resource Management Layer (RML). + +<H2>Files</H2> + +<DL> +<DT><P><A HREF="rml_base.h">rml_base.h</A> +<DD>Interfaces shared by TBB and OpenMP.</P> +<DT><P><A HREF="rml_omp.h">rml_omp.h</A> +<DD>Interface exclusive to OpenMP.</P> +<DT><P><A HREF="rml_tbb.h">rml_tbb.h</A> +<DD>Interface exclusive to TBB.</P> +</DL> + +<HR> +<A HREF="../index.html">Up to parent directory</A> +<p></p> +Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +<P></P> +Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +<p></p> +* Other names and brands may be claimed as the property of others. +</BODY> +</HTML> + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_base.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_base.h new file mode 100644 index 00000000..8303b9ae --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_base.h @@ -0,0 +1,184 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Header guard and namespace names follow rml conventions. + +#ifndef __RML_rml_base_H +#define __RML_rml_base_H + +#include <cstddef> + +#if _WIN32||_WIN64 +#include <windows.h> +#endif /* _WIN32||_WIN64 */ + +#ifdef RML_PURE_VIRTUAL_HANDLER +#define RML_PURE(T) {RML_PURE_VIRTUAL_HANDLER(); return (T)0;} +#else +#define RML_PURE(T) = 0; +#endif + +namespace rml { + +//! Base class for denying assignment and copy constructor. +class no_copy { + void operator=( no_copy& ); + no_copy( no_copy& ); +public: + no_copy() {} +}; + +class server; + +class versioned_object { +public: + //! A version number + typedef unsigned version_type; + + //! Get version of this object + /** The version number is incremented when a incompatible change is introduced. + The version number is invariant for the lifetime of the object. */ + virtual version_type version() const RML_PURE(version_type) +}; + +//! Represents a client's job for an execution context. +/** A job object is constructed by the client. + Not derived from versioned_object because version is same as for client. */ +class job { + friend class server; + + //! Word for use by server + /** Typically the server uses it to speed up internal lookup. + Clients must not modify the word. */ + void* scratch_ptr; +}; + +//! Information that client provides to server when asking for a server. +/** The instance must endure at least until acknowledge_close_connection is called. */ +class client: public versioned_object { +public: + //! Typedef for convenience of derived classes in other namespaces. + typedef ::rml::job job; + + //! Index of a job in a job pool + typedef unsigned size_type; + + //! Maximum number of threads that client can exploit profitably if nothing else is running on the machine. + /** The returned value should remain invariant for the lifetime of the connection. [idempotent] */ + virtual size_type max_job_count() const RML_PURE(size_type) + + //! Minimum stack size for each job. 0 means to use default stack size. [idempotent] + virtual std::size_t min_stack_size() const RML_PURE(std::size_t) + + //! Server calls this routine when it needs client to create a job object. + virtual job* create_one_job() RML_PURE(job*) + + //! Acknowledge that all jobs have been cleaned up. + /** Called by server in response to request_close_connection + after cleanup(job) has been called for each job. */ + virtual void acknowledge_close_connection() RML_PURE(void) + + enum policy_type {turnaround,throughput}; + + //! Inform server of desired policy. [idempotent] + virtual policy_type policy() const RML_PURE(policy_type) + + //! Inform client that server is done with *this. + /** Client should destroy the job. + Not necessarily called by execution context represented by *this. + Never called while any other thread is working on the job. */ + virtual void cleanup( job& ) RML_PURE(void) + + // In general, we should not add new virtual methods, because that would + // break derived classes. Think about reserving some vtable slots. +}; + +// Information that server provides to client. +// Virtual functions are routines provided by the server for the client to call. +class server: public versioned_object { +public: + //! Typedef for convenience of derived classes. + typedef ::rml::job job; + +#if _WIN32||_WIN64 + typedef void* execution_resource_t; +#endif + + //! Request that connection to server be closed. + /** Causes each job associated with the client to have its cleanup method called, + possibly by a thread different than the thread that created the job. + This method can return before all cleanup methods return. + Actions that have to wait after all cleanup methods return should be part of + client::acknowledge_close_connection. + Pass true as exiting if request_close_connection() is called because exit() is + called. In that case, it is the client's responsibility to make sure all threads + are terminated. In all other cases, pass false. */ + virtual void request_close_connection( bool exiting = false ) = 0; + + //! Called by client thread when it reaches a point where it cannot make progress until other threads do. + virtual void yield() = 0; + + //! Called by client to indicate a change in the number of non-RML threads that are running. + /** This is a performance hint to the RML to adjust how many threads it should let run + concurrently. The delta is the change in the number of non-RML threads that are running. + For example, a value of 1 means the client has started running another thread, and a value + of -1 indicates that the client has blocked or terminated one of its threads. */ + virtual void independent_thread_number_changed( int delta ) = 0; + + //! Default level of concurrency for which RML strives when there are no non-RML threads running. + /** Normally, the value is the hardware concurrency minus one. + The "minus one" accounts for the thread created by main(). */ + virtual unsigned default_concurrency() const = 0; + +protected: + static void*& scratch_ptr( job& j ) {return j.scratch_ptr;} +}; + +class factory { +public: + //! status results + enum status_type { + st_success=0, + st_connection_exists, + st_not_found, + st_incompatible + }; + + //! Scratch pointer for use by RML. + void* scratch_ptr; + +protected: + //! Pointer to routine that waits for server to indicate when client can close itself. + status_type (*my_wait_to_close_routine)( factory& ); + +public: + //! Library handle for use by RML. +#if _WIN32||_WIN64 + HMODULE library_handle; +#else + void* library_handle; +#endif /* _WIN32||_WIN64 */ + + //! Special marker to keep dll from being unloaded prematurely + static const std::size_t c_dont_unload = 1; +}; + +//! Typedef for callback functions to print server info +typedef void (*server_info_callback_t)( void* arg, const char* server_info ); + +} // namespace rml + +#endif /* __RML_rml_base_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_omp.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_omp.h new file mode 100644 index 00000000..6838d48c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_omp.h @@ -0,0 +1,126 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Header guard and namespace names follow OpenMP runtime conventions. + +#ifndef KMP_RML_OMP_H +#define KMP_RML_OMP_H + +#include "rml_base.h" + +namespace __kmp { +namespace rml { + +class omp_client; + +//------------------------------------------------------------------------ +// Classes instantiated by the server +//------------------------------------------------------------------------ + +//! Represents a set of omp worker threads provided by the server. +class omp_server: public ::rml::server { +public: + //! A number of coins (i.e., threads) + typedef unsigned size_type; + + //! Return the number of coins in the bank. (negative if machine is oversubscribed). + virtual int current_balance() const = 0; + + //! Request n coins. Returns number of coins granted. Oversubscription amount if negative. + /** Always granted if is_strict is true. + - Positive or zero result indicates that the number of coins was taken from the bank. + - Negative result indicates that no coins were taken, and that the bank has deficit + by that amount and the caller (if being a good citizen) should return that many coins. + */ + virtual int try_increase_load( size_type /*n*/, bool /*strict*/ ) = 0; + + //! Return n coins into the bank. + virtual void decrease_load( size_type /*n*/ ) = 0; + + //! Convert n coins into n threads. + /** When a thread returns, it is converted back into a coin and the coin is returned to the bank. */ + virtual void get_threads( size_type /*m*/, void* /*cookie*/, job* /*array*/[] ) = 0; + + /** Putting a thread to sleep - convert a thread into a coin + Waking up a thread - convert a coin into a thread + + Note: conversion between a coin and a thread does not affect the accounting. + */ +#if _WIN32||_WIN64 + //! Inform server of a TBB master thread. + virtual void register_master( execution_resource_t& /*v*/ ) = 0; + + //! Inform server that the TBB master thread is done with its work. + virtual void unregister_master( execution_resource_t /*v*/ ) = 0; + + //! deactivate + /** give control to ConcRT RM */ + virtual void deactivate( job* ) = 0; + + //! reactivate + virtual void reactivate( job* ) = 0; +#endif /* _WIN32||_WIN64 */ +}; + + +//------------------------------------------------------------------------ +// Classes (or base classes thereof) instantiated by the client +//------------------------------------------------------------------------ + +class omp_client: public ::rml::client { +public: + //! Called by server thread when it delivers a thread to client + /** The index argument is a 0-origin index of the job for this thread within the array + returned by method get_threads. Server decreases the load by 1 (i.e., returning the coin + back to the bank) after this method returns. */ + virtual void process( job&, void* /*cookie*/, size_type /*index*/ ) RML_PURE(void) +}; + +/** Client must ensure that instance is zero-inited, typically by being a file-scope object. */ +class omp_factory: public ::rml::factory { + + //! Pointer to routine that creates an RML server. + status_type (*my_make_server_routine)( omp_factory&, omp_server*&, omp_client& ); + + //! Pointer to routine that calls callback function with server version info. + void (*my_call_with_server_info_routine)( ::rml::server_info_callback_t cb, void* arg ); + +public: + typedef ::rml::versioned_object::version_type version_type; + typedef omp_client client_type; + typedef omp_server server_type; + + //! Open factory. + /** Dynamically links against RML library. + Returns st_success, st_incompatible, or st_not_found. */ + status_type open(); + + //! Factory method to be called by client to create a server object. + /** Factory must be open. + Returns st_success or st_incompatible . */ + status_type make_server( server_type*&, client_type& ); + + //! Close factory. + void close(); + + //! Call the callback with the server build info. + void call_with_server_info( ::rml::server_info_callback_t cb, void* arg ) const; +}; + +} // namespace rml +} // namespace __kmp + +#endif /* KMP_RML_OMP_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_tbb.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_tbb.h new file mode 100644 index 00000000..452a8967 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/include/rml_tbb.h @@ -0,0 +1,97 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Header guard and namespace names follow TBB conventions. + +#ifndef __TBB_rml_tbb_H +#define __TBB_rml_tbb_H + +#include "tbb/tbb_config.h" +#include "rml_base.h" + +namespace tbb { +namespace internal { +namespace rml { + +class tbb_client; + +//------------------------------------------------------------------------ +// Classes instantiated by the server +//------------------------------------------------------------------------ + +//! Represents a set of TBB worker threads provided by the server. +class tbb_server: public ::rml::server { +public: + //! Inform server of adjustments in the number of workers that the client can profitably use. + virtual void adjust_job_count_estimate( int delta ) = 0; + +#if _WIN32||_WIN64 + //! Inform server of a TBB master thread. + virtual void register_master( execution_resource_t& v ) = 0; + + //! Inform server that the TBB master thread is done with its work. + virtual void unregister_master( execution_resource_t v ) = 0; +#endif /* _WIN32||_WIN64 */ +}; + +//------------------------------------------------------------------------ +// Classes instantiated by the client +//------------------------------------------------------------------------ + +class tbb_client: public ::rml::client { +public: + //! Defined by TBB to steal a task and execute it. + /** Called by server when it wants an execution context to do some TBB work. + The method should return when it is okay for the thread to yield indefinitely. */ + virtual void process( job& ) RML_PURE(void) +}; + +/** Client must ensure that instance is zero-inited, typically by being a file-scope object. */ +class tbb_factory: public ::rml::factory { + + //! Pointer to routine that creates an RML server. + status_type (*my_make_server_routine)( tbb_factory&, tbb_server*&, tbb_client& ); + + //! Pointer to routine that calls callback function with server version info. + void (*my_call_with_server_info_routine)( ::rml::server_info_callback_t cb, void* arg ); + +public: + typedef ::rml::versioned_object::version_type version_type; + typedef tbb_client client_type; + typedef tbb_server server_type; + + //! Open factory. + /** Dynamically links against RML library. + Returns st_success, st_incompatible, or st_not_found. */ + status_type open(); + + //! Factory method to be called by client to create a server object. + /** Factory must be open. + Returns st_success, or st_incompatible . */ + status_type make_server( server_type*&, client_type& ); + + //! Close factory + void close(); + + //! Call the callback with the server build info + void call_with_server_info( ::rml::server_info_callback_t cb, void* arg ) const; +}; + +} // namespace rml +} // namespace internal +} // namespace tbb + +#endif /*__TBB_rml_tbb_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/index.html new file mode 100644 index 00000000..b974713b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/index.html @@ -0,0 +1,31 @@ +<HTML> +<BODY> +<H2>Overview</H2> + +The subdirectories pertain to the Resource Management Layer (RML). + +<H2>Directories</H2> + +<DL> +<DT><P><A HREF="include/index.html">include/</A> +<DD>Include files used by clients of RML.</P> +<DT><P><A HREF="client/index.html">client/</A> +<DD>Source files for code that must be statically linked with a client.</P> +<DT><P><A HREF="server/index.html">server/</A> +<DD>Source files for the RML server.</P> +<DT><P><A HREF="test">test/</A> +<DD>Unit tests for RML server and its components.</P> +</DL> + +<HR> +<A HREF="../index.html">Up to parent directory</A> +<p></p> +Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +<P></P> +Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +<p></p> +* Other names and brands may be claimed as the property of others. +</BODY> +</HTML> + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/omp_nested.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/omp_nested.cpp new file mode 100644 index 00000000..34ac3742 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/omp_nested.cpp @@ -0,0 +1,140 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <cstddef> +#include <cstdlib> +#include <cstdio> +#include <float.h> +#include <math.h> +#include <time.h> + +#include <omp.h> +#include <assert.h> + +#include "thread_level.h" + +#if _WIN32||_WIN64 +#include <Windows.h> /* Need Sleep */ +#else +#include <unistd.h> /* Need usleep */ +#endif + +void MilliSleep( unsigned milliseconds ) { +#if _WIN32||_WIN64 + Sleep( milliseconds ); +#else + usleep( milliseconds*1000 ); +#endif /* _WIN32||_WIN64 */ +} + +// Algorithm parameters +const int Max_OMP_Outer_Threads = 8; + +// Global variables +int max_outer_threads = Max_OMP_Outer_Threads; + +// Print help on command-line arguments +void help_message(char *prog_name) { + fprintf(stderr, "\n%s usage:\n", prog_name); + fprintf(stderr, + " Parameters:\n" + " -o<num> : max # of threads OMP should use at outer level\n" + "\n Help:\n" + " -h : print this help message\n"); +} + +// Process command-line arguments +void process_args(int argc, char *argv[], int *max_outer_t) { + (*max_outer_t) = omp_get_max_threads(); + for (int i=1; i<argc; ++i) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 'o': // set max_outer_threads + if (sscanf(&argv[i][2], "%d", max_outer_t) != 1 || *max_outer_t < 1) { + fprintf(stderr, "%s Warning: argument of -o option unacceptable: %s\n", argv[0], &argv[i][2]); + help_message(argv[0]); + } + break; + case 'h': // print help message + help_message(argv[0]); + exit(0); + break; + default: + fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]); + help_message(argv[0]); + break; + } + } else { + fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]); + help_message(argv[0]); + } + } +} + +int main(int argc, char *argv[]) { + process_args(argc, argv, &max_outer_threads); +#ifdef LOG_THREADS + TotalThreadLevel.init(); +#endif + + double start, end; + start = omp_get_wtime( ); + +#pragma omp parallel num_threads(max_outer_threads) + { + int omp_thread = omp_get_thread_num(); +#ifdef LOG_THREADS + if (omp_thread == 0) + TotalThreadLevel.change_level(omp_get_num_threads(), omp_outer); +#endif + if (omp_thread == 0) { + MilliSleep(3000); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, omp_outer); +#endif +#pragma omp parallel + { + int my_omp_thread = omp_get_thread_num(); +#ifdef LOG_THREADS + if (my_omp_thread == 0) + TotalThreadLevel.change_level(omp_get_num_threads(), omp_inner); +#endif + printf("Inner thread %d nested inside outer thread %d\n", my_omp_thread, omp_thread); +#ifdef LOG_THREADS + if (my_omp_thread == 0) + TotalThreadLevel.change_level(-omp_get_num_threads(), omp_inner); +#endif + } +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, omp_outer); +#endif + } + else { + MilliSleep(6000); + } +#ifdef LOG_THREADS + if (omp_thread == 0) + TotalThreadLevel.change_level(-omp_get_num_threads(), omp_outer); +#endif + } + end = omp_get_wtime( ); + printf("Simple test of nested OMP (%d outer threads max) took: %6.6f\n", + max_outer_threads, end-start); +#ifdef LOG_THREADS + TotalThreadLevel.dump(); +#endif + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/omp_simple.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/omp_simple.cpp new file mode 100644 index 00000000..12e4e5b2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/omp_simple.cpp @@ -0,0 +1,156 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <cstddef> +#include <cstdlib> +#include <cstdio> +#include <float.h> +#include <math.h> +#include <time.h> + +#include <omp.h> +#include <assert.h> + +#include "thread_level.h" + +#include "tbb/task.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" + +#if _WIN32||_WIN64 +#include <Windows.h> /* Need Sleep */ +#else +#include <unistd.h> /* Need usleep */ +#endif + +void MilliSleep( unsigned milliseconds ) { +#if _WIN32||_WIN64 + Sleep( milliseconds ); +#else + usleep( milliseconds*1000 ); +#endif /* _WIN32||_WIN64 */ +} + +using namespace std; +using namespace tbb; + +// Algorithm parameters +const int Max_TBB_Threads = 16; +const int Max_OMP_Threads = 16; + +// Global variables +int max_tbb_threads = Max_TBB_Threads; +int max_omp_threads = Max_OMP_Threads; + +// Print help on command-line arguments +void help_message(char *prog_name) { + fprintf(stderr, "\n%s usage:\n", prog_name); + fprintf(stderr, + " Parameters:\n" + " -t<num> : max # of threads TBB should use\n" + " -o<num> : max # of threads OMP should use\n" + "\n Help:\n" + " -h : print this help message\n"); +} + +// Process command-line arguments +void process_args(int argc, char *argv[], int *max_tbb_t, int *max_omp_t) { + for (int i=1; i<argc; ++i) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 't': // set max_tbb_threads + if (sscanf(&argv[i][2], "%d", max_tbb_t) != 1 || *max_tbb_t < 1) { + fprintf(stderr, "%s Warning: argument of -t option unacceptable: %s\n", argv[0], &argv[i][2]); + help_message(argv[0]); + } + break; + case 'o': // set max_omp_threads + if (sscanf(&argv[i][2], "%d", max_omp_t) != 1 || *max_omp_t < 1) { + fprintf(stderr, "%s Warning: argument of -o option unacceptable: %s\n", argv[0], &argv[i][2]); + help_message(argv[0]); + } + break; + case 'h': // print help message + help_message(argv[0]); + exit(0); + break; + default: + fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]); + help_message(argv[0]); + break; + } + } else { + fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]); + help_message(argv[0]); + } + } +} + +int main(int argc, char *argv[]) { + process_args(argc, argv, &max_tbb_threads, &max_omp_threads); + TotalThreadLevel.init(); + + double start, end; + start = omp_get_wtime(); + +#pragma omp parallel num_threads(max_omp_threads) + { + int omp_thread = omp_get_thread_num(); +#ifdef LOG_THREADS + if (omp_thread == 0) + TotalThreadLevel.change_level(omp_get_num_threads(), omp_outer); +#endif + task_scheduler_init phase(max_tbb_threads); + if (omp_thread == 0) { + MilliSleep(3000); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, omp_outer); +#endif + parallel_for(blocked_range<size_t>(0, 1000), + [=](const blocked_range<size_t>& range) { +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, tbb_inner); +#endif +#pragma ivdep + for (size_t i=range.begin(); i!=range.end(); ++i) { + if (i==range.begin()) + printf("TBB range starting at %d on OMP thread %d\n", (int)i, omp_thread); + } +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_inner); +#endif + }, auto_partitioner()); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, omp_outer); +#endif + } + else { + MilliSleep(6000); + } +#ifdef LOG_THREADS + if (omp_thread == 0) + TotalThreadLevel.change_level(-omp_get_num_threads(), omp_outer); +#endif + } + end = omp_get_wtime(); + printf("Simple test of OMP (%d threads max) with TBB (%d threads max) inside took: %6.6f\n", + max_omp_threads, max_tbb_threads, end-start); +#ifdef LOG_THREADS + TotalThreadLevel.dump(); +#endif + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/tbb_multi_omp.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/tbb_multi_omp.cpp new file mode 100644 index 00000000..0fc28b73 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/tbb_multi_omp.cpp @@ -0,0 +1,182 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <cstddef> +#include <cstdlib> +#include <cstdio> +#include <float.h> +#include <math.h> +#include <time.h> + +#include <omp.h> +#include <assert.h> + +#include "thread_level.h" + +#include "tbb/task.h" +#include "tbb/tick_count.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/scalable_allocator.h" + +#if _WIN32||_WIN64 +#include <Windows.h> /* Need Sleep */ +#else +#include <unistd.h> /* Need usleep */ +#endif + +void MilliSleep( unsigned milliseconds ) { +#if _WIN32||_WIN64 + Sleep( milliseconds ); +#else + usleep( milliseconds*1000 ); +#endif /* _WIN32||_WIN64 */ +} + +using namespace std; +using namespace tbb; + +// Algorithm parameters +const int Max_TBB_Threads = 16; +const int Max_OMP_Threads = 16; + +// Global variables +int max_tbb_threads = Max_TBB_Threads; +int max_omp_threads = Max_OMP_Threads; + +// Print help on command-line arguments +void help_message(char *prog_name) { + fprintf(stderr, "\n%s usage:\n", prog_name); + fprintf(stderr, + " Parameters:\n" + " -t<num> : max # of threads TBB should use\n" + " -o<num> : max # of threads OMP should use\n" + "\n Help:\n" + " -h : print this help message\n"); +} + +// Process command-line arguments +void process_args(int argc, char *argv[], int *max_tbb_t, int *max_omp_t) { + for (int i=1; i<argc; ++i) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 't': // set max_tbb_threads + if (sscanf(&argv[i][2], "%d", max_tbb_t) != 1 || *max_tbb_t < 1) { + fprintf(stderr, "%s Warning: argument of -t option unacceptable: %s\n", argv[0], &argv[i][2]); + help_message(argv[0]); + } + break; + case 'o': // set max_omp_threads + if (sscanf(&argv[i][2], "%d", max_omp_t) != 1 || *max_omp_t < 1) { + fprintf(stderr, "%s Warning: argument of -o option unacceptable: %s\n", argv[0], &argv[i][2]); + help_message(argv[0]); + } + break; + case 'h': // print help message + help_message(argv[0]); + exit(0); + break; + default: + fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]); + help_message(argv[0]); + break; + } + } else { + fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]); + help_message(argv[0]); + } + } +} + +class SimpleTask : public task { + bool isLeaf; + int myId; +public: + SimpleTask(bool isLeaf_, int myId_) : isLeaf(isLeaf_), myId(myId_) {} + task* execute() { +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, tbb_outer); +#endif + omp_set_num_threads(max_omp_threads); + if (!isLeaf) { + set_ref_count(65); + for (int i=0; i<64; ++i) { + SimpleTask& st = *new(allocate_child()) SimpleTask(true, i); + spawn(st); + } +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); +#endif + wait_for_all(); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, tbb_outer); +#endif + } + else { + if (myId%2 == 0) { + MilliSleep(3000); +#pragma omp parallel + { +#ifdef LOG_THREADS + if (omp_get_thread_num() == 0) + TotalThreadLevel.change_level(omp_get_num_threads()-1, omp_inner); +#endif + //printf("In OMP parallel region on TBB task with myId=0: thread %d of %d\n", omp_get_thread_num(), omp_get_num_threads()); +#ifdef LOG_THREADS + if (omp_get_thread_num() == 0) + TotalThreadLevel.change_level(-(omp_get_num_threads()-1), omp_inner); +#endif + } + } + else { + MilliSleep(6000); + } + } +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); +#endif + return NULL; + } +}; + + +int main(int argc, char *argv[]) { +#ifdef LOG_THREADS + TotalThreadLevel.init(); + TotalThreadLevel.change_level(1, tbb_outer); +#endif + process_args(argc, argv, &max_tbb_threads, &max_omp_threads); + + task_scheduler_init phase(max_tbb_threads); + tick_count start, end; + start = tick_count::now(); + SimpleTask& st = *new(task::allocate_root()) SimpleTask(false, -1); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); +#endif + task::spawn_root_and_wait(st); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, tbb_outer); +#endif + end = tick_count::now(); + printf("Simple Test of TBB (%d threads max) with OMP (%d threads max) inside took: %6.6f\n", + max_tbb_threads, max_omp_threads, (end-start).seconds()); + +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); + TotalThreadLevel.dump(); +#endif + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/tbb_simple.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/tbb_simple.cpp new file mode 100644 index 00000000..4435ece1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/tbb_simple.cpp @@ -0,0 +1,187 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <cstddef> +#include <cstdlib> +#include <cstdio> +#include <float.h> +#include <math.h> +#include <time.h> + +#include <omp.h> +#include <assert.h> + +#include "thread_level.h" + +#include "tbb/task.h" +#include "tbb/tick_count.h" +#include "tbb/task_scheduler_init.h" + +#if _WIN32||_WIN64 +#include <Windows.h> /* Need Sleep */ +#else +#include <unistd.h> /* Need usleep */ +#endif + +void MilliSleep( unsigned milliseconds ) { +#if _WIN32||_WIN64 + Sleep( milliseconds ); +#else + usleep( milliseconds*1000 ); +#endif /* _WIN32||_WIN64 */ +} + +using namespace std; +using namespace tbb; + +// Algorithm parameters +const int Max_TBB_Threads = 16; +const int Max_OMP_Threads = 16; + +// Global variables +int max_tbb_threads = Max_TBB_Threads; +int max_omp_threads = Max_OMP_Threads; + +// Print help on command-line arguments +void help_message(char *prog_name) { + fprintf(stderr, "\n%s usage:\n", prog_name); + fprintf(stderr, + " Parameters:\n" + " -t<num> : max # of threads TBB should use\n" + " -o<num> : max # of threads OMP should use\n" + "\n Help:\n" + " -h : print this help message\n"); +} + +// Process command-line arguments +void process_args(int argc, char *argv[], int *max_tbb_t, int *max_omp_t) { + for (int i=1; i<argc; ++i) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 't': // set max_tbb_threads + if (sscanf(&argv[i][2], "%d", max_tbb_t) != 1 || *max_tbb_t < 1) { + fprintf(stderr, "%s Warning: argument of -t option unacceptable: %s\n", argv[0], &argv[i][2]); + help_message(argv[0]); + } + break; + case 'o': // set max_omp_threads + if (sscanf(&argv[i][2], "%d", max_omp_t) != 1 || *max_omp_t < 1) { + fprintf(stderr, "%s Warning: argument of -o option unacceptable: %s\n", argv[0], &argv[i][2]); + help_message(argv[0]); + } + break; + case 'h': // print help message + help_message(argv[0]); + exit(0); + break; + default: + fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]); + help_message(argv[0]); + break; + } + } else { + fprintf(stderr, "%s: Warning: command-line option ignored: %s\n", argv[0], argv[i]); + help_message(argv[0]); + } + } +} + +class SimpleTask : public task { + bool isLeaf; + int myId; +public: + SimpleTask(bool isLeaf_, int myId_) : isLeaf(isLeaf_), myId(myId_) {} + task* execute() { +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, tbb_outer); +#endif + omp_set_num_threads(max_omp_threads); + if (!isLeaf) { + set_ref_count(17); + for (int i=0; i<16; ++i) { + SimpleTask& st = *new(allocate_child()) SimpleTask(true, i); + spawn(st); + } +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); +#endif + wait_for_all(); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, tbb_outer); +#endif + } + else { + if (myId == 0) { + MilliSleep(3000); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); +#endif +#pragma omp parallel + { +#ifdef LOG_THREADS + if (omp_get_thread_num() == 0) + TotalThreadLevel.change_level(omp_get_num_threads(), omp_inner); +#endif + printf("In OMP parallel region on TBB task with myId=0: thread %d of %d\n", + omp_get_thread_num(), omp_get_num_threads()); +#ifdef LOG_THREADS + if (omp_get_thread_num() == 0) + TotalThreadLevel.change_level(-omp_get_num_threads(), omp_inner); +#endif + } +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, tbb_outer); +#endif + } + else { + MilliSleep(6000); + } + } +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); +#endif + return NULL; + } +}; + + +int main(int argc, char *argv[]) { +#ifdef LOG_THREADS + TotalThreadLevel.init(); + TotalThreadLevel.change_level(1, tbb_outer); +#endif + process_args(argc, argv, &max_tbb_threads, &max_omp_threads); + + task_scheduler_init phase(max_tbb_threads); + tick_count start, end; + start = tick_count::now(); + SimpleTask& st = *new(task::allocate_root()) SimpleTask(false, -1); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); +#endif + task::spawn_root_and_wait(st); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(1, tbb_outer); +#endif + end = tick_count::now(); + printf("Simple Test of TBB (%d threads max) with OMP (%d threads max) inside took: %6.6f\n", + max_tbb_threads, max_omp_threads, (end-start).seconds()); +#ifdef LOG_THREADS + TotalThreadLevel.change_level(-1, tbb_outer); + TotalThreadLevel.dump(); +#endif + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/thread_level.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/thread_level.h new file mode 100644 index 00000000..ca416c0e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/perfor/thread_level.h @@ -0,0 +1,130 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Thread level recorder +#ifndef __THREAD_LEVEL_H +#define __THREAD_LEVEL_H +#include <cstdio> +#include <omp.h> +#include <assert.h> +#include "tbb/atomic.h" +#include "tbb/tick_count.h" + +//#define LOG_THREADS // use this to ifdef out calls to this class +//#define NO_BAIL_OUT // continue execution after detecting oversubscription + +using namespace tbb; + +typedef enum {tbb_outer, tbb_inner, omp_outer, omp_inner} client_t; + +class ThreadLevelRecorder { + tbb::atomic<int> tbb_outer_level; + tbb::atomic<int> tbb_inner_level; + tbb::atomic<int> omp_outer_level; + tbb::atomic<int> omp_inner_level; + struct record { + tbb::tick_count time; + int n_tbb_outer_thread; + int n_tbb_inner_thread; + int n_omp_outer_thread; + int n_omp_inner_thread; + }; + tbb::atomic<unsigned> next; + /** Must be power of two */ + static const unsigned max_record_count = 1<<20; + record array[max_record_count]; + int max_threads; + bool fail; + public: + void change_level(int delta, client_t whichClient); + void dump(); + void init(); +}; + +void ThreadLevelRecorder::change_level(int delta, client_t whichClient) { + int tox=tbb_outer_level, tix=tbb_inner_level, oox=omp_outer_level, oix=omp_inner_level; + if (whichClient == tbb_outer) { + tox = tbb_outer_level+=delta; + } else if (whichClient == tbb_inner) { + tix = tbb_inner_level+=delta; + } else if (whichClient == omp_outer) { + oox = omp_outer_level+=delta; + } else if (whichClient == omp_inner) { + oix = omp_inner_level+=delta; + } else { + printf("WARNING: Bad client type; ignoring.\n"); + return; + } + // log non-negative entries + tbb::tick_count t = tbb::tick_count::now(); + unsigned k = next++; + if (k<max_record_count) { + record& r = array[k]; + r.time = t; + r.n_tbb_outer_thread = tox>=0?tox:0; + r.n_omp_outer_thread = oox>=0?oox:0; + r.n_tbb_inner_thread = tix>=0?tix:0; + r.n_omp_inner_thread = oix>=0?oix:0; + } + char errStr[100]; + int tot_threads; + tot_threads = tox+tix+oox+oix; + sprintf(errStr, "ERROR: Number of threads (%d+%d+%d+%d=%d) in use exceeds maximum (%d).\n", + tox, tix, oox, oix, tot_threads, max_threads); + if (tot_threads > max_threads) { +#ifdef NO_BAIL_OUT + if (!fail) { + printf("%sContinuing...\n", errStr); + fail = true; + } +#else + dump(); + printf("%s\n", errStr); + assert(tot_threads <= max_threads); +#endif + } +} + +void ThreadLevelRecorder::dump() { + FILE* f = fopen("time.txt","w"); + if (!f) { + perror("fopen(time.txt)\n"); + exit(1); + } + unsigned limit = next; + if (limit>max_record_count) { // Clip + limit = max_record_count; + } + for (unsigned i=0; i<limit; ++i) { + fprintf(f,"%f\t%d\t%d\t%d\t%d\n",(array[i].time-array[0].time).seconds(), array[i].n_tbb_outer_thread, + array[i].n_tbb_inner_thread, array[i].n_omp_outer_thread, array[i].n_omp_inner_thread); + } + fclose(f); + int tox=tbb_outer_level, tix=tbb_inner_level, oox=omp_outer_level, oix=omp_inner_level; + int tot_threads; + tot_threads = tox+tix+oox+oix; + if (!fail) printf("INFO: Passed.\n"); + else printf("INFO: Failed.\n"); +} + +void ThreadLevelRecorder::init() { + fail = false; + max_threads = omp_get_max_threads(); + printf("INFO: Getting maximum hardware threads... %d.\n", max_threads); +} + +ThreadLevelRecorder TotalThreadLevel; +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/index.html new file mode 100644 index 00000000..a32f8f42 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/index.html @@ -0,0 +1,18 @@ +<HTML> +<BODY> +<H2>Overview</H2> + +This directory has source code internal to the server. + +<HR> +<A HREF="../index.html">Up to parent directory</A> +<p></p> +Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +<P></P> +Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +<p></p> +* Other names and brands may be claimed as the property of others. +</BODY> +</HTML> + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/irml.rc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/irml.rc new file mode 100644 index 00000000..8ab95998 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/irml.rc @@ -0,0 +1,112 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Microsoft Visual C++ generated resource script. +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include <winresrc.h> +#define ENDL "\r\n" +#include "tbb/tbb_version.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// manifest integration +#ifdef TBB_MANIFEST +#include "winuser.h" +2 RT_MANIFEST tbbmanifest.exe.manifest +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION TBB_VERNUMBERS + PRODUCTVERSION TBB_VERNUMBERS + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Intel Corporation\0" + VALUE "FileDescription", "Intel(R) Threading Building Blocks resource manager library\0" + VALUE "FileVersion", TBB_VERSION "\0" + VALUE "LegalCopyright", "Copyright 2005-2020 Intel Corporation. All Rights Reserved.\0" + VALUE "LegalTrademarks", "\0" +#ifndef TBB_USE_DEBUG + VALUE "OriginalFilename", "irml.dll\0" +#else + VALUE "OriginalFilename", "irml_debug.dll\0" +#endif + VALUE "ProductName", "Intel(R) Threading Building Blocks for Windows\0" + VALUE "ProductVersion", TBB_VERSION "\0" + VALUE "PrivateBuild", "\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/job_automaton.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/job_automaton.h new file mode 100644 index 00000000..548f9749 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/job_automaton.h @@ -0,0 +1,141 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __RML_job_automaton_H +#define __RML_job_automaton_H + +#include "rml_base.h" +#include "tbb/atomic.h" + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + #pragma warning (push) + #pragma warning (disable: 4244) +#endif + +namespace rml { + +namespace internal { + +//! Finite state machine. +/** /--------------\ + / V + 0 --> 1--> ptr --> -1 + ^ + | + | + V + ptr|1 + +"owner" = corresponding server_thread. +Odd states (except -1) indicate that someone is executing code on the job. +Most transitions driven only by owner. +Transition 0-->-1 is driven by non-owner. +Transition ptr->-1 is driven by owner or non-owner. +*/ +class job_automaton: no_copy { +private: + tbb::atomic<intptr_t> my_job; +public: + /** Created by non-owner */ + job_automaton() { + my_job = 0; + } + + ~job_automaton() { + __TBB_ASSERT( my_job==-1, "must plug before destroying" ); + } + + //! Try to transition 0-->1 or ptr-->ptr|1. + /** Should only be called by owner. */ + bool try_acquire() { + intptr_t snapshot = my_job; + if( snapshot==-1 ) { + return false; + } else { + __TBB_ASSERT( (snapshot&1)==0, "already marked that way" ); + intptr_t old = my_job.compare_and_swap( snapshot|1, snapshot ); + __TBB_ASSERT( old==snapshot || old==-1, "unexpected interference" ); + return old==snapshot; + } + } + //! Transition ptr|1-->ptr + /** Should only be called by owner. */ + void release() { + intptr_t snapshot = my_job; + __TBB_ASSERT( snapshot&1, NULL ); + // Atomic store suffices here. + my_job = snapshot&~1; + } + + //! Transition 1-->ptr + /** Should only be called by owner. */ + void set_and_release( rml::job* job ) { + intptr_t value = reinterpret_cast<intptr_t>(job); + __TBB_ASSERT( (value&1)==0, "job misaligned" ); + __TBB_ASSERT( value!=0, "null job" ); + __TBB_ASSERT( my_job==1, "already set, or not marked busy?" ); + // Atomic store suffices here. + my_job = value; + } + + //! Transition 0-->-1 + /** If successful, return true. called by non-owner (for TBB and the likes) */ + bool try_plug_null() { + return my_job.compare_and_swap( -1, 0 )==0; + } + + //! Try to transition to -1. If successful, set j to contents and return true. + /** Called by owner or non-owner. (for OpenMP and the likes) */ + bool try_plug( rml::job*&j ) { + for(;;) { + intptr_t snapshot = my_job; + if( snapshot&1 ) { + j = NULL; + return false; + } + // Not busy + if( my_job.compare_and_swap( -1, snapshot )==snapshot ) { + j = reinterpret_cast<rml::job*>(snapshot); + return true; + } + // Need to retry, because current thread may be non-owner that read a 0, and owner might have + // caused transition 0->1->ptr after we took our snapshot. + } + } + + /** Called by non-owner to wait for transition to ptr. */ + rml::job* wait_for_job() const { + intptr_t snapshot; + for(;;) { + snapshot = my_job; + if( snapshot&~1 ) break; + __TBB_Yield(); + } + __TBB_ASSERT( snapshot!=-1, "wait on plugged job_automaton" ); + return reinterpret_cast<rml::job*>(snapshot&~1); + } +}; + +} // namespace internal +} // namespace rml + + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warning 4244 are back + +#endif /* __RML_job_automaton_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/lin-rml-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/lin-rml-export.def new file mode 100644 index 00000000..fe116f68 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/lin-rml-export.def @@ -0,0 +1,26 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: +__RML_open_factory; +__RML_close_factory; +__TBB_make_rml_server; +__KMP_make_rml_server; +__TBB_call_with_my_server_info; +__KMP_call_with_my_server_info; +local:*; +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/rml_server.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/rml_server.cpp new file mode 100644 index 00000000..d73c6e66 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/rml_server.cpp @@ -0,0 +1,3305 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "rml_tbb.h" +#define private public /* Sleazy trick to avoid publishing internal names in public header. */ +#include "rml_omp.h" +#undef private + +#include "tbb/tbb_allocator.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/aligned_space.h" +#include "tbb/atomic.h" +#include "tbb/spin_mutex.h" +#include "tbb/tbb_misc.h" // Get AvailableHwConcurrency() from here. +#if _MSC_VER==1500 && !defined(__INTEL_COMPILER) +// VS2008/VC9 seems to have an issue; +#pragma warning( push ) +#pragma warning( disable: 4985 ) +#endif +#include "tbb/concurrent_vector.h" +#if _MSC_VER==1500 && !defined(__INTEL_COMPILER) +#pragma warning( pop ) +#endif +#if _MSC_VER && defined(_Wp64) +// Workaround for overzealous compiler warnings +#pragma warning (push) +#pragma warning (disable: 4244) +#endif + +#include "job_automaton.h" +#include "wait_counter.h" +#include "thread_monitor.h" + +#if RML_USE_WCRM +#include <concrt.h> +#include <concrtrm.h> +using namespace Concurrency; +#include <vector> +#include <unordered_map> +#define __RML_REMOVE_VIRTUAL_PROCESSORS_DISABLED 0 +#endif /* RML_USE_WCRM */ + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +namespace rml { +namespace internal { + +using tbb::internal::rml::tbb_client; +using tbb::internal::rml::tbb_server; + +using __kmp::rml::omp_client; +using __kmp::rml::omp_server; + +typedef versioned_object::version_type version_type; + +#define SERVER_VERSION 2 +#define EARLIEST_COMPATIBLE_CLIENT_VERSION 2 + +static const size_t cache_line_size = tbb::internal::NFS_MaxLineSize; + +template<typename Server, typename Client> class generic_connection; +class tbb_connection_v2; +class omp_connection_v2; + +#if RML_USE_WCRM +//! State of a server_thread +/** Below are diagrams of legal state transitions. + + ts_busy + ^ ^ + / \ + / V + ts_done <----- ts_asleep <------> ts_idle +*/ + +enum thread_state_t { + ts_idle, + ts_asleep, + ts_busy, + ts_done +}; + +//! Extra state of an omp server thread +enum thread_extra_state_t { + ts_none, + ts_removed, + ts_lent +}; + +//! Results from try_grab_for() +enum thread_grab_t { + wk_failed, + wk_from_asleep, + wk_from_idle +}; + +#else /* !RML_USE_WCRM */ + +//! State of a server_thread +/** Below are diagrams of legal state transitions. + + OMP + ts_omp_busy + ^ ^ + / \ + / V + ts_asleep <-----------> ts_idle + + + ts_deactivated + ^ ^ + / \ + V \ + ts_none <--------------> ts_reactivated + + TBB + ts_tbb_busy + ^ ^ + / \ + / V + ts_asleep <-----------> ts_idle --> ts_done + + For TBB only. Extra state transition. + + ts_created -> ts_started -> ts_visited + */ +enum thread_state_t { + //! Thread not doing anything useful, but running and looking for work. + ts_idle, + //! Thread not doing anything useful and is asleep */ + ts_asleep, + //! Thread is enlisted into OpenMP team + ts_omp_busy, + //! Thread is busy doing TBB work. + ts_tbb_busy, + //! For TBB threads only + ts_done, + ts_created, + ts_started, + ts_visited, + //! For omp threads only + ts_none, + ts_deactivated, + ts_reactivated +}; +#endif /* RML_USE_WCRM */ + +#if TBB_USE_ASSERT +#define PRODUCE_ARG(x) ,x +#else +#define PRODUCE_ARG(x) +#endif /* TBB_USE_ASSERT */ + +//! Synchronizes dispatch of OpenMP work. +class omp_dispatch_type { + typedef ::rml::job job_type; + omp_client* client; + void* cookie; + omp_client::size_type index; + tbb::atomic<job_type*> job; +#if TBB_USE_ASSERT + omp_connection_v2* server; +#endif /* TBB_USE_ASSERT */ +public: + omp_dispatch_type() {job=NULL;} + void consume(); + void produce( omp_client& c, job_type* j, void* cookie_, omp_client::size_type index_ PRODUCE_ARG( omp_connection_v2& s )) { + __TBB_ASSERT( j, NULL ); + __TBB_ASSERT( !job, "job already set" ); + client = &c; +#if TBB_USE_ASSERT + server = &s; +#endif /* TBB_USE_ASSERT */ + cookie = cookie_; + index = index_; + // Must be last + job = j; + } +}; + +//! A reference count. +/** No default constructor, because users of ref_count must be very careful about whether the + initial reference count is 0 or 1. */ +class ref_count: no_copy { + friend class thread_map; + tbb::atomic<int> my_ref_count; +public: + ref_count(int k ) {my_ref_count=k;} + ~ref_count() {__TBB_ASSERT( !my_ref_count, "premature destruction of refcounted object" );} + //! Add one and return new value. + int add_ref() { + int k = ++my_ref_count; + __TBB_ASSERT(k>=1,"reference count underflowed before add_ref"); + return k; + } + //! Subtract one and return new value. + int remove_ref() { + int k = --my_ref_count; + __TBB_ASSERT(k>=0,"reference count underflow"); + return k; + } +}; + +#if RML_USE_WCRM + +#if USE_UMS_THREAD +#define RML_THREAD_KIND UmsThreadDefault +#define RML_THREAD_KIND_STRING "UmsThread" +#else +#define RML_THREAD_KIND ThreadScheduler +#define RML_THREAD_KIND_STRING "WinThread" +#endif + +// Forward declaration +class thread_map; + +static const IExecutionResource* c_remove_prepare = (IExecutionResource*)0; +static const IExecutionResource* c_remove_returned = (IExecutionResource*)1; + +//! Server thread representation +class server_thread_rep : no_copy { + friend class thread_map; + friend class omp_connection_v2; + friend class server_thread; + friend class tbb_server_thread; + friend class omp_server_thread; + template<typename Connection> friend void make_job( Connection& c, typename Connection::server_thread_type& t ); + typedef int thread_state_rep_t; +public: + //! Ctor + server_thread_rep( bool assigned, IScheduler* s, IExecutionResource* r, thread_map& map, rml::client& cl ) : + uid( GetExecutionContextId() ), my_scheduler(s), my_proxy(NULL), + my_thread_map(map), my_client(cl), my_job(NULL) + { + my_state = assigned ? ts_busy : ts_idle; + my_extra_state = ts_none; + terminate = false; + my_execution_resource = r; + } + //! Dtor + ~server_thread_rep() {} + + //! Synchronization routine + inline rml::job* wait_for_job() { + if( !my_job ) my_job = my_job_automaton.wait_for_job(); + return my_job; + } + + // Getters and setters + inline thread_state_t read_state() const { thread_state_rep_t s = my_state; return static_cast<thread_state_t>(s); } + inline void set_state( thread_state_t to ) {my_state = to;} + inline void set_removed() { __TBB_ASSERT( my_extra_state==ts_none, NULL ); my_extra_state = ts_removed; } + inline bool is_removed() const { return my_extra_state==ts_removed; } + inline bool is_lent() const {return my_extra_state==ts_lent;} + inline void set_lent() { my_extra_state=ts_lent; } + inline void set_returned() { my_extra_state=ts_none; } + inline IExecutionResource* get_execution_resource() { return my_execution_resource; } + inline IVirtualProcessorRoot* get_virtual_processor() { return (IVirtualProcessorRoot*)get_execution_resource(); } + + //! Enlist the thread for work + inline bool wakeup( thread_state_t to, thread_state_t from ) { + __TBB_ASSERT( from==ts_asleep && (to==ts_idle||to==ts_busy||to==ts_done), NULL ); + return my_state.compare_and_swap( to, from )==from; + } + + //! Enlist the thread for. + thread_grab_t try_grab_for(); + + //! Destroy the client job associated with the thread + template<typename Connection> bool destroy_job( Connection* c ); + + //! Try to re-use the thread + void revive( IScheduler* s, IExecutionResource* r, rml::client& c ) { + // the variables may not have been set before a thread was told to quit + __TBB_ASSERT( my_scheduler==s, "my_scheduler has been altered?\n" ); + my_scheduler = s; + __TBB_ASSERT( &my_client==&c, "my_client has been altered?\n" ); + if( r ) my_execution_resource = r; + my_client = c; + my_state = ts_idle; + __TBB_ASSERT( my_extra_state==ts_removed, NULL ); + my_extra_state = ts_none; + } + +protected: + const int uid; + IScheduler* my_scheduler; + IThreadProxy* my_proxy; + tbb::atomic<IExecutionResource*> my_execution_resource; /* for non-masters, it is IVirtualProcessorRoot */ + thread_map& my_thread_map; + rml::client& my_client; + job* my_job; + job_automaton my_job_automaton; + tbb::atomic<bool> terminate; + tbb::atomic<thread_state_rep_t> my_state; + tbb::atomic<thread_extra_state_t> my_extra_state; +}; + +//! Class that implements IExecutionContext +class server_thread : public IExecutionContext, public server_thread_rep { + friend class tbb_connection_v2; + friend class omp_connection_v2; + friend class tbb_server_thread; + friend class omp_server_thread; + friend class thread_map; + template<typename Connection> friend void make_job( Connection& c, typename Connection::server_thread_type& t ); +protected: + server_thread( bool is_tbb, bool assigned, IScheduler* s, IExecutionResource* r, thread_map& map, rml::client& cl ) : server_thread_rep(assigned,s,r,map,cl), tbb_thread(is_tbb) {} + ~server_thread() {} + unsigned int GetId() const __TBB_override { return uid; } + IScheduler* GetScheduler() __TBB_override { return my_scheduler; } + IThreadProxy* GetProxy() __TBB_override { return my_proxy; } + void SetProxy( IThreadProxy* thr_proxy ) __TBB_override { my_proxy = thr_proxy; } + +private: + bool tbb_thread; +}; + +// Forward declaration +class tbb_connection_v2; +class omp_connection_v2; + +//! TBB server thread +class tbb_server_thread : public server_thread { + friend class tbb_connection_v2; +public: + tbb_server_thread( bool assigned, IScheduler* s, IExecutionResource* r, tbb_connection_v2* con, thread_map& map, rml::client& cl ) : server_thread(true,assigned,s,r,map,cl), my_conn(con) { + activation_count = 0; + } + ~tbb_server_thread() {} + void Dispatch( DispatchState* ) __TBB_override; + inline bool initiate_termination(); + bool sleep_perhaps(); + //! Switch out this thread + bool switch_out(); +private: + tbb_connection_v2* my_conn; +public: + tbb::atomic<int> activation_count; +}; + +//! OMP server thread +class omp_server_thread : public server_thread { + friend class omp_connection_v2; +public: + omp_server_thread( bool assigned, IScheduler* s, IExecutionResource* r, omp_connection_v2* con, thread_map& map, rml::client& cl ) : + server_thread(false,assigned,s,r,map,cl), my_conn(con), my_cookie(NULL), my_index(UINT_MAX) {} + ~omp_server_thread() {} + void Dispatch( DispatchState* ) __TBB_override; + inline void* get_cookie() {return my_cookie;} + inline ::__kmp::rml::omp_client::size_type get_index() {return my_index;} + + inline IExecutionResource* get_execution_resource() { return get_execution_resource(); } + inline bool initiate_termination() { return destroy_job( (omp_connection_v2*) my_conn ); } + void sleep_perhaps(); +private: + omp_connection_v2* my_conn; + void* my_cookie; + ::__kmp::rml::omp_client::size_type my_index; + omp_dispatch_type omp_data; +}; + +//! Class that implements IScheduler +template<typename Connection> +class scheduler : no_copy, public IScheduler { +public: + unsigned int GetId() const __TBB_override {return uid;} + void Statistics( unsigned int* /*pTaskCompletionRate*/, unsigned int* /*pTaskArrivalRate*/, unsigned int* /*pNumberOfTaskEnqueued*/) __TBB_override {} + SchedulerPolicy GetPolicy() const __TBB_override { __TBB_ASSERT(my_policy,NULL); return *my_policy; } + void AddVirtualProcessors( IVirtualProcessorRoot** vproots, unsigned int count ) __TBB_override { if( !my_conn.is_closing() ) my_conn.add_virtual_processors( vproots, count); } + void RemoveVirtualProcessors( IVirtualProcessorRoot** vproots, unsigned int count ) __TBB_override; + void NotifyResourcesExternallyIdle( IVirtualProcessorRoot** vproots, unsigned int count ) __TBB_override { __TBB_ASSERT( false, "This call is not allowed for TBB" ); } + void NotifyResourcesExternallyBusy( IVirtualProcessorRoot** vproots, unsigned int count ) __TBB_override { __TBB_ASSERT( false, "This call is not allowed for TBB" ); } +protected: + scheduler( Connection& conn ); + virtual ~scheduler() { __TBB_ASSERT( my_policy, NULL ); delete my_policy; } + +public: + static scheduler* create( Connection& conn ) {return new scheduler( conn );} + +private: + const int uid; + Connection& my_conn; + SchedulerPolicy* my_policy; +}; + + +/* + * --> ts_busy --> ts_done + */ +class thread_scavenger_thread : public IExecutionContext, no_copy { +public: + thread_scavenger_thread( IScheduler* s, IVirtualProcessorRoot* r, thread_map& map ) : + uid( GetExecutionContextId() ), my_scheduler(s), my_virtual_processor_root(r), my_proxy(NULL), my_thread_map(map) + { + my_state = ts_busy; +#if TBB_USE_ASSERT + activation_count = 0; +#endif + } + ~thread_scavenger_thread() {} + unsigned int GetId() const __TBB_override { return uid; } + IScheduler* GetScheduler() __TBB_override { return my_scheduler; } + IThreadProxy* GetProxy() __TBB_override { return my_proxy; } + void SetProxy( IThreadProxy* thr_proxy ) __TBB_override { my_proxy = thr_proxy; } + void Dispatch( DispatchState* ) __TBB_override; + inline thread_state_t read_state() { return my_state; } + inline void set_state( thread_state_t s ) { my_state = s; } + inline IVirtualProcessorRoot* get_virtual_processor() { return my_virtual_processor_root; } +private: + const int uid; + IScheduler* my_scheduler; + IVirtualProcessorRoot* my_virtual_processor_root; + IThreadProxy* my_proxy; + thread_map& my_thread_map; + tbb::atomic<thread_state_t> my_state; +#if TBB_USE_ASSERT +public: + tbb::atomic<int> activation_count; +#endif +}; + +static const thread_scavenger_thread* c_claimed = reinterpret_cast<thread_scavenger_thread*>(1); + +struct garbage_connection_queue { + tbb::atomic<uintptr_t> head; + tbb::atomic<uintptr_t> tail; + static const uintptr_t empty = 0; // connection scavenger thread empty list + static const uintptr_t plugged = 1; // end of use of the list + static const uintptr_t plugged_acked = 2; // connection scavenger saw the plugged flag, and it freed all connections +}; + +//! Connection scavenger +/** It collects closed connection objects, wait for worker threads belonging to the connection to return to ConcRT RM + * then return the object to the memory manager. + */ +class connection_scavenger_thread { + friend void assist_cleanup_connections(); + /* + * connection_scavenger_thread's state + * ts_busy <----> ts_asleep <-- + */ + tbb::atomic<thread_state_t> state; + + /* We steal two bits from a connection pointer to encode + * whether the connection is for TBB or for OMP. + * + * ---------------------------------- + * | | | | + * ---------------------------------- + * ^ ^ + * / | + * 1 : tbb, 0 : omp | + * if set, terminate + */ + // FIXME: pad these? + thread_monitor monitor; + HANDLE thr_handle; +#if TBB_USE_ASSERT + tbb::atomic<int> n_scavenger_threads; +#endif + +public: + connection_scavenger_thread() : thr_handle(NULL) { + state = ts_asleep; +#if TBB_USE_ASSERT + n_scavenger_threads = 0; +#endif + } + + ~connection_scavenger_thread() {} + + void wakeup() { + if( state.compare_and_swap( ts_busy, ts_asleep )==ts_asleep ) + monitor.notify(); + } + + void sleep_perhaps(); + + void process_requests( uintptr_t conn_ex ); + + static __RML_DECL_THREAD_ROUTINE thread_routine( void* arg ); + + void launch() { + thread_monitor::launch( connection_scavenger_thread::thread_routine, this, NULL ); + } + + template<typename Server, typename Client> + void add_request( generic_connection<Server,Client>* conn_to_close ); + + template<typename Server, typename Client> + uintptr_t grab_and_prepend( generic_connection<Server,Client>* last_conn_to_close ); +}; + +void free_all_connections( uintptr_t ); + +#endif /* RML_USE_WCRM */ + +#if !RML_USE_WCRM +class server_thread; + +//! thread_map_base; we need to make the iterator type available to server_thread +struct thread_map_base { + //! A value in the map + class value_type { + public: + server_thread& thread() { + __TBB_ASSERT( my_thread, "thread_map::value_type::thread() called when !my_thread" ); + return *my_thread; + } + rml::job& job() { + __TBB_ASSERT( my_job, "thread_map::value_type::job() called when !my_job" ); + return *my_job; + } + value_type() : my_thread(NULL), my_job(NULL) {} + server_thread& wait_for_thread() const { + for(;;) { + server_thread* ptr=const_cast<server_thread*volatile&>(my_thread); + if( ptr ) + return *ptr; + __TBB_Yield(); + } + } + /** Shortly after when a connection is established, it is possible for the server + to grab a server_thread that has not yet created a job object for that server. */ + rml::job* wait_for_job() const { + if( !my_job ) { + my_job = my_automaton.wait_for_job(); + } + return my_job; + } + private: + server_thread* my_thread; + /** Marked mutable because though it is physically modified, conceptually it is a duplicate of + the job held by job_automaton. */ + mutable rml::job* my_job; + job_automaton my_automaton; + // FIXME - pad out to cache line, because my_automaton is hit hard by thread() + friend class thread_map; + }; + typedef tbb::concurrent_vector<value_type,tbb::zero_allocator<value_type,tbb::cache_aligned_allocator> > array_type; +}; +#endif /* !RML_USE_WCRM */ + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warnings about uninstantiable class + #pragma warning(push) + #pragma warning(disable:4510 4610) +#endif + +template<typename T> +class padded: public T { + char pad[cache_line_size - sizeof(T)%cache_line_size]; +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +// FIXME - should we pad out memory to avoid false sharing of our global variables? +static unsigned the_default_concurrency; +static tbb::atomic<int> the_balance; +static tbb::atomic<tbb::internal::do_once_state> rml_module_state; + +#if !RML_USE_WCRM +//! Per thread information +/** ref_count holds number of clients that are using this, + plus 1 if a host thread owns this instance. */ +class server_thread: public ref_count { + friend class thread_map; + template<typename Server, typename Client> friend class generic_connection; + friend class tbb_connection_v2; + friend class omp_connection_v2; + //! Integral type that can hold a thread_state_t + typedef int thread_state_rep_t; + tbb::atomic<thread_state_rep_t> state; +public: + thread_monitor monitor; +private: + bool is_omp_thread; + tbb::atomic<thread_state_rep_t> my_extra_state; + server_thread* link; + thread_map_base::array_type::iterator my_map_pos; + rml::server *my_conn; + rml::job* my_job; + job_automaton* my_ja; + size_t my_index; + tbb::atomic<bool> terminate; + omp_dispatch_type omp_dispatch; + +#if TBB_USE_ASSERT + //! Flag used to check if thread is still using *this. + bool has_active_thread; +#endif /* TBB_USE_ASSERT */ + + //! Volunteer to sleep. + void sleep_perhaps( thread_state_t asleep ); + + //! Destroy job corresponding to given client + /** Return true if thread must quit. */ + template<typename Connection> + bool destroy_job( Connection& c ); + + //! Do terminate the thread + /** Return true if thread must quit. */ + bool do_termination(); + + void loop(); + static __RML_DECL_THREAD_ROUTINE thread_routine( void* arg ); + +public: + server_thread(); + + ~server_thread(); + + //! Read the thread state + thread_state_t read_state() const { + thread_state_rep_t s = state; + __TBB_ASSERT( unsigned(s)<=unsigned(ts_done), "corrupted server thread?" ); + return thread_state_t(s); + } + + //! Read the tbb-specific extra thread state + thread_state_t read_extra_state() const { + thread_state_rep_t s = my_extra_state; + return thread_state_t(s); + } + + //! Launch a thread that is bound to *this. + void launch( size_t stack_size ); + + //! Attempt to wakeup a thread + /** The value "to" is the new state for the thread, if it was woken up. + Returns true if thread was woken up, false otherwise. */ + bool wakeup( thread_state_t to, thread_state_t from ); + + //! Attempt to enslave a thread for OpenMP/TBB. + /** Returns true if state is successfully changed. 's' takes either ts_omp_busy or ts_tbb_busy */ + bool try_grab_for( thread_state_t s ); + +#if _WIN32||_WIN64 + //! Send the worker thread to sleep temporarily + void deactivate(); + + //! Wake the worker thread up + void reactivate(); +#endif /* _WIN32||_WIN64 */ +}; + +//! Bag of threads that are private to a client. +class private_thread_bag { + struct list_thread: server_thread { + list_thread* next; + }; + //! Root of atomic linked list of list_thread + /** ABA problem is avoided because items are only atomically pushed, never popped. */ + tbb::atomic<list_thread*> my_root; + tbb::cache_aligned_allocator<padded<list_thread> > my_allocator; +public: + //! Construct empty bag + private_thread_bag() {my_root=NULL;} + + //! Create a fresh server_thread object. + server_thread& add_one_thread() { + list_thread* t = my_allocator.allocate(1); + new( t ) list_thread; + // Atomically add to list + list_thread* old_root; + do { + old_root = my_root; + t->next = old_root; + } while( my_root.compare_and_swap( t, old_root )!=old_root ); + return *t; + } + + //! Destroy the bag and threads in it. + ~private_thread_bag() { + while( my_root ) { + // Unlink thread from list. + list_thread* t = my_root; + my_root = t->next; + // Destroy and deallocate the thread. + t->~list_thread(); + my_allocator.deallocate(static_cast<padded<list_thread>*>(t),1); + } + } +}; + +//! Forward declaration +void wakeup_some_tbb_threads(); + +//! Type-independent part of class generic_connection. +/** One to one map from server threads to jobs, and associated reference counting. */ +class thread_map : public thread_map_base { +public: + typedef rml::client::size_type size_type; + //! ctor + thread_map( wait_counter& fc, ::rml::client& client ) : + all_visited_at_least_once(false), my_min_stack_size(0), my_server_ref_count(1), + my_client_ref_count(1), my_client(client), my_factory_counter(fc) + { my_unrealized_threads = 0; } + //! dtor + ~thread_map() {} + typedef array_type::iterator iterator; + iterator begin() {return my_array.begin();} + iterator end() {return my_array.end();} + void bind(); + void unbind(); + void assist_cleanup( bool assist_null_only ); + + /** Returns number of unrealized threads to create. */ + size_type wakeup_tbb_threads( size_type n ); + bool wakeup_next_thread( iterator i, tbb_connection_v2& conn ); + void release_tbb_threads( server_thread* t ); + void adjust_balance( int delta ); + + //! Add a server_thread object to the map, but do not bind it. + /** Return NULL if out of unrealized threads. */ + value_type* add_one_thread( bool is_omp_thread_ ); + + void bind_one_thread( rml::server& server, value_type& x ); + + void remove_client_ref(); + int add_server_ref() {return my_server_ref_count.add_ref();} + int remove_server_ref() {return my_server_ref_count.remove_ref();} + + ::rml::client& client() const {return my_client;} + + size_type get_unrealized_threads() { return my_unrealized_threads; } + +private: + private_thread_bag my_private_threads; + bool all_visited_at_least_once; + array_type my_array; + size_t my_min_stack_size; + tbb::atomic<size_type> my_unrealized_threads; + + //! Number of threads referencing *this, plus one extra. + /** When it becomes zero, the containing server object can be safely deleted. */ + ref_count my_server_ref_count; + + //! Number of jobs that need cleanup, plus one extra. + /** When it becomes zero, acknowledge_close_connection is called. */ + ref_count my_client_ref_count; + + ::rml::client& my_client; + //! Counter owned by factory that produced this thread_map. + wait_counter& my_factory_counter; +}; + +void thread_map::bind_one_thread( rml::server& server, value_type& x ) { + // Add one to account for the thread referencing this map hereforth. + server_thread& t = x.thread(); + my_server_ref_count.add_ref(); + my_client_ref_count.add_ref(); +#if TBB_USE_ASSERT + __TBB_ASSERT( t.add_ref()==1, NULL ); +#else + t.add_ref(); +#endif + // Have responsibility to start the thread. + t.my_conn = &server; + t.my_ja = &x.my_automaton; + t.launch( my_min_stack_size ); + /* Must wake thread up so it can fill in its "my_job" field in *this. + Otherwise deadlock can occur where wait_for_job spins on thread that is sleeping. */ + __TBB_ASSERT( t.state!=ts_tbb_busy, NULL ); + t.wakeup( ts_idle, ts_asleep ); +} + +thread_map::value_type* thread_map::add_one_thread( bool is_omp_thread_ ) { + size_type u; + do { + u = my_unrealized_threads; + if( !u ) return NULL; + } while( my_unrealized_threads.compare_and_swap(u-1,u)!=u ); + server_thread& t = my_private_threads.add_one_thread(); + t.is_omp_thread = is_omp_thread_; + __TBB_ASSERT( u>=1, NULL ); + t.my_index = u - 1; + __TBB_ASSERT( t.state!=ts_tbb_busy, NULL ); + t.my_extra_state = t.is_omp_thread ? ts_none : ts_created; + + iterator i = t.my_map_pos = my_array.grow_by(1); + value_type& v = *i; + v.my_thread = &t; + return &v; +} + +void thread_map::bind() { + ++my_factory_counter; + my_min_stack_size = my_client.min_stack_size(); + __TBB_ASSERT( my_unrealized_threads==0, "already called bind?" ); + my_unrealized_threads = my_client.max_job_count(); +} + +void thread_map::unbind() { + // Ask each server_thread to cleanup its job for this server. + for( iterator i=begin(); i!=end(); ++i ) { + server_thread& t = i->thread(); + t.terminate = true; + t.wakeup( ts_idle, ts_asleep ); + } + // Remove extra ref to client. + remove_client_ref(); +} + +void thread_map::assist_cleanup( bool assist_null_only ) { + // To avoid deadlock, the current thread *must* help out with cleanups that have not started, + // because the thread that created the job may be busy for a long time. + for( iterator i = begin(); i!=end(); ++i ) { + rml::job* j=0; + job_automaton& ja = i->my_automaton; + if( assist_null_only ? ja.try_plug_null() : ja.try_plug(j) ) { + if( j ) { + my_client.cleanup(*j); + } else { + // server thread did not get a chance to create a job. + } + remove_client_ref(); + } + } +} + +thread_map::size_type thread_map::wakeup_tbb_threads( size_type n ) { + __TBB_ASSERT(n>0,"must specify positive number of threads to wake up"); + iterator e = end(); + for( iterator k=begin(); k!=e; ++k ) { + // If another thread added *k, there is a tiny timing window where thread() is invalid. + server_thread& t = k->wait_for_thread(); + thread_state_t thr_s = t.read_state(); + if( t.read_extra_state()==ts_created || thr_s==ts_tbb_busy || thr_s==ts_done ) + continue; + if( --the_balance>=0 ) { // try to withdraw a coin from the deposit + while( !t.try_grab_for( ts_tbb_busy ) ) { + thr_s = t.read_state(); + if( thr_s==ts_tbb_busy || thr_s==ts_done ) { + // we lost; move on to the next. + ++the_balance; + goto skip; + } + } + if( --n==0 ) + return 0; + } else { + // overdraft. + ++the_balance; + break; + } +skip: + ; + } + return n<my_unrealized_threads ? n : size_type(my_unrealized_threads); +} +#else /* RML_USE_WCRM */ + +class thread_map : no_copy { + friend class omp_connection_v2; + typedef ::std::unordered_map<uintptr_t,server_thread*> unordered_map_type; + size_t my_min_stack_size; + size_t my_unrealized_threads; + ::rml::client& my_client; + //! Counter owned by factory that produced this thread_map. + wait_counter& my_factory_counter; + //! Ref counters + ref_count my_server_ref_count; + ref_count my_client_ref_count; + // FIXME: pad this? + unordered_map_type my_map; + bool shutdown_in_progress; + std::vector<IExecutionResource*> original_exec_resources; + tbb::cache_aligned_allocator<padded<tbb_server_thread> > my_tbb_allocator; + tbb::cache_aligned_allocator<padded<omp_server_thread> > my_omp_allocator; + tbb::cache_aligned_allocator<padded<thread_scavenger_thread> > my_scavenger_allocator; + IResourceManager* my_concrt_resource_manager; + IScheduler* my_scheduler; + ISchedulerProxy* my_scheduler_proxy; + tbb::atomic<thread_scavenger_thread*> my_thread_scavenger_thread; +#if TBB_USE_ASSERT + tbb::atomic<int> n_add_vp_requests; + tbb::atomic<int> n_thread_scavengers_created; +#endif +public: + thread_map( wait_counter& fc, ::rml::client& client ) : + my_min_stack_size(0), my_client(client), my_factory_counter(fc), + my_server_ref_count(1), my_client_ref_count(1), shutdown_in_progress(false), + my_concrt_resource_manager(NULL), my_scheduler(NULL), my_scheduler_proxy(NULL) + { + my_thread_scavenger_thread = NULL; +#if TBB_USE_ASSERT + n_add_vp_requests = 0; + n_thread_scavengers_created; +#endif + } + + ~thread_map() { + __TBB_ASSERT( n_thread_scavengers_created<=1, "too many scavenger thread created" ); + // if thread_scavenger_thread is launched, wait for it to complete + if( my_thread_scavenger_thread ) { + __TBB_ASSERT( my_thread_scavenger_thread!=c_claimed, NULL ); + while( my_thread_scavenger_thread->read_state()==ts_busy ) + __TBB_Yield(); + thread_scavenger_thread* tst = my_thread_scavenger_thread; + my_scavenger_allocator.deallocate(static_cast<padded<thread_scavenger_thread>*>(tst),1); + } + // deallocate thread contexts + for( unordered_map_type::const_iterator hi=my_map.begin(); hi!=my_map.end(); ++hi ) { + server_thread* thr = hi->second; + if( thr->tbb_thread ) { + while( ((tbb_server_thread*)thr)->activation_count>1 ) + __TBB_Yield(); + ((tbb_server_thread*)thr)->~tbb_server_thread(); + my_tbb_allocator.deallocate(static_cast<padded<tbb_server_thread>*>(thr),1); + } else { + ((omp_server_thread*)thr)->~omp_server_thread(); + my_omp_allocator.deallocate(static_cast<padded<omp_server_thread>*>(thr),1); + } + } + if( my_scheduler_proxy ) { + my_scheduler_proxy->Shutdown(); + my_concrt_resource_manager->Release(); + __TBB_ASSERT( my_scheduler, NULL ); + delete my_scheduler; + } else { + __TBB_ASSERT( !my_scheduler, NULL ); + } + } + typedef unordered_map_type::key_type key_type; + typedef unordered_map_type::value_type value_type; + typedef unordered_map_type::iterator iterator; + iterator begin() {return my_map.begin();} + iterator end() {return my_map.end();} + iterator find( key_type k ) {return my_map.find( k );} + iterator insert( key_type k, server_thread* v ) { + std::pair<iterator,bool> res = my_map.insert( value_type(k,v) ); + return res.first; + } + void bind( IScheduler* s ) { + ++my_factory_counter; + if( s ) { + my_unrealized_threads = s->GetPolicy().GetPolicyValue( MaxConcurrency ); + __TBB_ASSERT( my_unrealized_threads>0, NULL ); + my_scheduler = s; + my_concrt_resource_manager = CreateResourceManager(); // reference count==3 when first created. + my_scheduler_proxy = my_concrt_resource_manager->RegisterScheduler( s, CONCRT_RM_VERSION_1 ); + my_scheduler_proxy->RequestInitialVirtualProcessors( false ); + } + } + bool is_closing() { return shutdown_in_progress; } + void unbind( rml::server& server, ::tbb::spin_mutex& mtx ); + void add_client_ref() { my_server_ref_count.add_ref(); } + void remove_client_ref(); + void add_server_ref() {my_server_ref_count.add_ref();} + int remove_server_ref() {return my_server_ref_count.remove_ref();} + int get_server_ref_count() { int k = my_server_ref_count.my_ref_count; return k; } + void assist_cleanup( bool assist_null_only ); + void adjust_balance( int delta ); + int current_balance() const {int k = the_balance; return k;} + ::rml::client& client() const {return my_client;} + void register_as_master( server::execution_resource_t& v ) const { (IExecutionResource*&)v = my_scheduler_proxy ? my_scheduler_proxy->SubscribeCurrentThread() : NULL; } + // Remove() should be called from the same thread that subscribed the current h/w thread (i.e., the one that + // called register_as_master() ). + void unregister( server::execution_resource_t v ) const {if( v ) ((IExecutionResource*)v)->Remove( my_scheduler );} + void add_virtual_processors( IVirtualProcessorRoot** vprocs, unsigned int count, tbb_connection_v2& conn, ::tbb::spin_mutex& mtx ); + void add_virtual_processors( IVirtualProcessorRoot** vprocs, unsigned int count, omp_connection_v2& conn, ::tbb::spin_mutex& mtx ); + void remove_virtual_processors( IVirtualProcessorRoot** vproots, unsigned count, ::tbb::spin_mutex& mtx ); + void mark_virtual_processors_as_lent( IVirtualProcessorRoot** vproots, unsigned count, ::tbb::spin_mutex& mtx ); + void create_oversubscribers( unsigned n, std::vector<server_thread*>& thr_vec, omp_connection_v2& conn, ::tbb::spin_mutex& mtx ); + void wakeup_tbb_threads( int c, ::tbb::spin_mutex& mtx ); + void mark_virtual_processors_as_returned( IVirtualProcessorRoot** vprocs, unsigned int count, tbb::spin_mutex& mtx ); + inline void addto_original_exec_resources( IExecutionResource* r, ::tbb::spin_mutex& mtx ) { + ::tbb::spin_mutex::scoped_lock lck(mtx); + __TBB_ASSERT( !is_closing(), "trying to register master while connection is being shutdown?" ); + original_exec_resources.push_back( r ); + } +#if !__RML_REMOVE_VIRTUAL_PROCESSORS_DISABLED + void allocate_thread_scavenger( IExecutionResource* v ); +#endif + inline thread_scavenger_thread* get_thread_scavenger() { return my_thread_scavenger_thread; } +}; + +garbage_connection_queue connections_to_reclaim; +connection_scavenger_thread connection_scavenger; + +#endif /* !RML_USE_WCRM */ + +//------------------------------------------------------------------------ +// generic_connection +//------------------------------------------------------------------------ + +template<typename Server, typename Client> +struct connection_traits {}; + +// head of the active TBB connections +static tbb::atomic<uintptr_t> active_tbb_connections; +static tbb::atomic<int> current_tbb_conn_readers; +static size_t current_tbb_conn_reader_epoch; +static tbb::atomic<size_t> close_tbb_connection_event_count; + +#if RML_USE_WCRM +template<typename Connection> +void make_job( Connection& c, server_thread& t ); +#endif + +template<typename Server, typename Client> +class generic_connection: public Server, no_copy { + version_type version() const __TBB_override {return SERVER_VERSION;} + void yield() __TBB_override {thread_monitor::yield();} + void independent_thread_number_changed( int delta ) __TBB_override { my_thread_map.adjust_balance( -delta ); } + unsigned default_concurrency() const __TBB_override { return the_default_concurrency; } + friend void wakeup_some_tbb_threads(); + friend class connection_scavenger_thread; + +protected: + thread_map my_thread_map; + generic_connection* next_conn; + size_t my_ec; +#if RML_USE_WCRM + // FIXME: pad it? + tbb::spin_mutex map_mtx; + IScheduler* my_scheduler; + void do_open( IScheduler* s ) { + my_scheduler = s; + my_thread_map.bind( s ); + } + bool is_closing() { return my_thread_map.is_closing(); } + void request_close_connection( bool existing ); +#else + void do_open() {my_thread_map.bind();} + void request_close_connection( bool ); +#endif /* RML_USE_WCRM */ + //! Make destructor virtual + virtual ~generic_connection() {} +#if !RML_USE_WCRM + generic_connection( wait_counter& fc, Client& c ) : my_thread_map(fc,c), next_conn(NULL), my_ec(0) {} +#else + generic_connection( wait_counter& fc, Client& c ) : + my_thread_map(fc,c), next_conn(NULL), my_ec(0), map_mtx(), my_scheduler(NULL) {} + void add_virtual_processors( IVirtualProcessorRoot** vprocs, unsigned int count ); + void remove_virtual_processors( IVirtualProcessorRoot** vprocs, unsigned int count ); + void notify_resources_externally_busy( IVirtualProcessorRoot** vprocs, unsigned int count ) { my_thread_map.mark_virtual_processors_as_lent( vprocs, count, map_mtx ); } + void notify_resources_externally_idle( IVirtualProcessorRoot** vprocs, unsigned int count ) { + my_thread_map.mark_virtual_processors_as_returned( vprocs, count, map_mtx ); + } +#endif /* !RML_USE_WCRM */ + +public: + typedef Server server_type; + typedef Client client_type; + Client& client() const {return static_cast<Client&>(my_thread_map.client());} + void set_scratch_ptr( job& j, void* ptr ) { ::rml::server::scratch_ptr(j) = ptr; } +#if RML_USE_WCRM + template<typename Connection> + friend void make_job( Connection& c, server_thread& t ); + void add_server_ref () {my_thread_map.add_server_ref();} + void remove_server_ref() {if( my_thread_map.remove_server_ref()==0 ) delete this;} + void add_client_ref () {my_thread_map.add_client_ref();} + void remove_client_ref() {my_thread_map.remove_client_ref();} +#else /* !RML_USE_WCRM */ + int add_server_ref () {return my_thread_map.add_server_ref();} + void remove_server_ref() {if( my_thread_map.remove_server_ref()==0 ) delete this;} + void remove_client_ref() {my_thread_map.remove_client_ref();} + void make_job( server_thread& t, job_automaton& ja ); +#endif /* RML_USE_WCRM */ + static generic_connection* get_addr( uintptr_t addr_ex ) { + return reinterpret_cast<generic_connection*>( addr_ex&~(uintptr_t)3 ); + } +}; + +//------------------------------------------------------------------------ +// TBB server +//------------------------------------------------------------------------ + +template<> +struct connection_traits<tbb_server,tbb_client> { + static const bool assist_null_only = true; + static const bool is_tbb = true; +}; + +//! Represents a server/client binding. +/** The internal representation uses inheritance for the server part and a pointer for the client part. */ +class tbb_connection_v2: public generic_connection<tbb_server,tbb_client> { + void adjust_job_count_estimate( int delta ) __TBB_override; +#if !RML_USE_WCRM +#if _WIN32||_WIN64 + void register_master ( rml::server::execution_resource_t& /*v*/ ) __TBB_override {} + void unregister_master ( rml::server::execution_resource_t /*v*/ ) __TBB_override {} +#endif +#else + void register_master ( rml::server::execution_resource_t& v ) __TBB_override { + my_thread_map.register_as_master(v); + if( v ) ++nesting; + } + void unregister_master ( rml::server::execution_resource_t v ) __TBB_override { + if( v ) { + __TBB_ASSERT( nesting>0, NULL ); + if( --nesting==0 ) { +#if !__RML_REMOVE_VIRTUAL_PROCESSORS_DISABLED + my_thread_map.allocate_thread_scavenger( (IExecutionResource*)v ); +#endif + } + } + my_thread_map.unregister(v); + } + IScheduler* create_scheduler() {return( scheduler<tbb_connection_v2>::create( *this ) );} + friend void free_all_connections( uintptr_t ); + friend class scheduler<tbb_connection_v2>; + friend class execution_context; + friend class connection_scavenger_thread; +#endif /* RML_USE_WCRM */ + friend void wakeup_some_tbb_threads(); + //! Estimate on number of jobs without threads working on them. + tbb::atomic<int> my_slack; + friend class dummy_class_to_shut_up_gratuitous_warning_from_gcc_3_2_3; +#if TBB_USE_ASSERT + tbb::atomic<int> my_job_count_estimate; +#endif /* TBB_USE_ASSERT */ + + tbb::atomic<int> n_adjust_job_count_requests; +#if RML_USE_WCRM + tbb::atomic<int> nesting; +#endif + + // dtor + ~tbb_connection_v2(); + +public: +#if RML_USE_WCRM + typedef tbb_server_thread server_thread_type; +#endif + //! True if there is slack that try_process can use. + bool has_slack() const {return my_slack>0;} + +#if RML_USE_WCRM + bool try_process( job& job ) +#else + bool try_process( server_thread& t, job& job ) +#endif + { + bool visited = false; + // No check for my_slack>0 here because caller is expected to do that check. + int k = --my_slack; + if( k>=0 ) { +#if !RML_USE_WCRM + t.my_extra_state = ts_visited; // remember the thread paid a trip to process() at least once +#endif + client().process(job); + visited = true; + } + ++my_slack; + return visited; + } + + tbb_connection_v2( wait_counter& fc, tbb_client& client ) : generic_connection<tbb_server,tbb_client>(fc,client) + { + my_slack = 0; +#if RML_USE_WCRM + nesting = 0; +#endif +#if TBB_USE_ASSERT + my_job_count_estimate = 0; +#endif /* TBB_USE_ASSERT */ + __TBB_ASSERT( !my_slack, NULL ); + +#if RML_USE_WCRM + do_open( client.max_job_count()>0 ? create_scheduler() : NULL ); +#else + do_open(); +#endif /* !RML_USE_WCRM */ + n_adjust_job_count_requests = 0; + + // Acquire head of active_tbb_connections & push the connection into the list + uintptr_t conn; + do { + for( ; (conn=active_tbb_connections)&1; ) + __TBB_Yield(); + } while( active_tbb_connections.compare_and_swap( conn|1, conn )!=conn ); + + this->next_conn = generic_connection<tbb_server,tbb_client>::get_addr(conn); + // Update and release head of active_tbb_connections + active_tbb_connections = (uintptr_t) this; // set and release + } + inline void wakeup_tbb_threads( unsigned n ) { + my_thread_map.wakeup_tbb_threads( n +#if RML_USE_WCRM + , map_mtx +#endif + ); + } +#if RML_USE_WCRM + inline int get_nesting_level() { return nesting; } +#else + inline bool wakeup_next_thread( thread_map::iterator i ) {return my_thread_map.wakeup_next_thread( i, *this );} + inline thread_map::size_type get_unrealized_threads () {return my_thread_map.get_unrealized_threads();} +#endif /* !RML_USE_WCRM */ +}; + +//------------------------------------------------------------------------ +// OpenMP server +//------------------------------------------------------------------------ + +template<> +struct connection_traits<omp_server,omp_client> { + static const bool assist_null_only = false; + static const bool is_tbb = false; +}; + +class omp_connection_v2: public generic_connection<omp_server,omp_client> { +#if !RML_USE_WCRM + int current_balance() const __TBB_override {return the_balance;} +#else + friend void free_all_connections( uintptr_t ); + friend class scheduler<omp_connection_v2>; + int current_balance() const __TBB_override {return my_thread_map.current_balance();} +#endif /* !RML_USE_WCRM */ + int try_increase_load( size_type n, bool strict ) __TBB_override; + void decrease_load( size_type n ) __TBB_override; + void get_threads( size_type request_size, void* cookie, job* array[] ) __TBB_override; +#if !RML_USE_WCRM +#if _WIN32||_WIN64 + void register_master ( rml::server::execution_resource_t& /*v*/ ) __TBB_override {} + void unregister_master ( rml::server::execution_resource_t /*v*/ ) __TBB_override {} +#endif +#else + void register_master ( rml::server::execution_resource_t& v ) __TBB_override { + my_thread_map.register_as_master( v ); + my_thread_map.addto_original_exec_resources( (IExecutionResource*)v, map_mtx ); + } + void unregister_master ( rml::server::execution_resource_t v ) __TBB_override { my_thread_map.unregister(v); } +#endif /* !RML_USE_WCRM */ +#if _WIN32||_WIN64 + void deactivate( rml::job* j ) __TBB_override; + void reactivate( rml::job* j ) __TBB_override; +#endif /* _WIN32||_WIN64 */ +#if RML_USE_WCRM +public: + typedef omp_server_thread server_thread_type; +private: + IScheduler* create_scheduler() {return( scheduler<omp_connection_v2>::create( *this ) );} +#endif /* RML_USE_WCRM */ +public: +#if TBB_USE_ASSERT + //! Net change in delta caused by this connection. + /** Should be zero when connection is broken */ + tbb::atomic<int> net_delta; +#endif /* TBB_USE_ASSERT */ + + omp_connection_v2( wait_counter& fc, omp_client& client ) : generic_connection<omp_server,omp_client>(fc,client) { +#if TBB_USE_ASSERT + net_delta = 0; +#endif /* TBB_USE_ASSERT */ +#if RML_USE_WCRM + do_open( create_scheduler() ); +#else + do_open(); +#endif /* RML_USE_WCRM */ + } + ~omp_connection_v2() {__TBB_ASSERT( net_delta==0, "net increase/decrease of load is nonzero" );} +}; + +#if !RML_USE_WCRM +/* to deal with cases where the machine is oversubscribed; we want each thread to trip to try_process() at least once */ +/* this should not involve computing the_balance */ +bool thread_map::wakeup_next_thread( thread_map::iterator this_thr, tbb_connection_v2& conn ) { + if( all_visited_at_least_once ) + return false; + + iterator e = end(); +retry: + bool exist = false; + iterator k=this_thr; + for( ++k; k!=e; ++k ) { + // If another thread added *k, there is a tiny timing window where thread() is invalid. + server_thread& t = k->wait_for_thread(); + if( t.my_extra_state!=ts_visited ) + exist = true; + if( t.read_state()!=ts_tbb_busy && t.my_extra_state==ts_started ) + if( t.try_grab_for( ts_tbb_busy ) ) + return true; + } + for( k=begin(); k!=this_thr; ++k ) { + server_thread& t = k->wait_for_thread(); + if( t.my_extra_state!=ts_visited ) + exist = true; + if( t.read_state()!=ts_tbb_busy && t.my_extra_state==ts_started ) + if( t.try_grab_for( ts_tbb_busy ) ) + return true; + } + + if( exist ) + if( conn.has_slack() ) + goto retry; + else + all_visited_at_least_once = true; + return false; +} + +void thread_map::release_tbb_threads( server_thread* t ) { + for( ; t; t = t->link ) { + while( t->read_state()!=ts_asleep ) + __TBB_Yield(); + t->my_extra_state = ts_started; + } +} +#endif /* !RML_USE_WCRM */ + +void thread_map::adjust_balance( int delta ) { + int new_balance = the_balance += delta; + if( new_balance>0 && 0>=new_balance-delta /*== old the_balance*/ ) + wakeup_some_tbb_threads(); +} + +void thread_map::remove_client_ref() { + int k = my_client_ref_count.remove_ref(); + if( k==0 ) { + // Notify factory that thread has crossed back into RML. + --my_factory_counter; + // Notify client that RML is done with the client object. + my_client.acknowledge_close_connection(); + } +} + +#if RML_USE_WCRM +/** Not a member of generic_connection because we need Connection to be the derived class. */ +template<typename Connection> +void make_job( Connection& c, typename Connection::server_thread_type& t ) { + if( t.my_job_automaton.try_acquire() ) { + rml::job* j = t.my_client.create_one_job(); + __TBB_ASSERT( j!=NULL, "client:::create_one_job returned NULL" ); + __TBB_ASSERT( (intptr_t(j)&1)==0, "client::create_one_job returned misaligned job" ); + t.my_job_automaton.set_and_release( j ); + c.set_scratch_ptr( *j, (void*) &t ); + } +} +#endif /* RML_USE_WCRM */ + +#if _MSC_VER && !defined(__INTEL_COMPILER) +// Suppress "conditional expression is constant" warning. +#pragma warning( push ) +#pragma warning( disable: 4127 ) +#endif +#if RML_USE_WCRM +template<typename Server, typename Client> +void generic_connection<Server,Client>::request_close_connection( bool exiting ) { + // for TBB connections, exiting should always be false + if( connection_traits<Server,Client>::is_tbb ) + __TBB_ASSERT( !exiting, NULL); +#if TBB_USE_ASSERT + else if( exiting ) + reinterpret_cast<omp_connection_v2*>(this)->net_delta = 0; +#endif + if( exiting ) { + uintptr_t tail = connections_to_reclaim.tail; + while( connections_to_reclaim.tail.compare_and_swap( garbage_connection_queue::plugged, tail )!=tail ) + __TBB_Yield(); + my_thread_map.unbind( *this, map_mtx ); + my_thread_map.assist_cleanup( connection_traits<Server,Client>::assist_null_only ); + // It is assumed that the client waits for all other threads to terminate before + // calling request_close_connection with true. Thus, it is safe to return all + // outstanding connection objects that are reachable. It is possible that there may + // be some unreachable connection objects lying somewhere. + free_all_connections( connection_scavenger.grab_and_prepend( this ) ); + return; + } +#else /* !RML_USE_WCRM */ +template<typename Server, typename Client> +void generic_connection<Server,Client>::request_close_connection( bool ) { +#endif /* RML_USE_WCRM */ + if( connection_traits<Server,Client>::is_tbb ) { + // acquire the head of active TBB connections + uintptr_t conn; + do { + for( ; (conn=active_tbb_connections)&1; ) + __TBB_Yield(); + } while( active_tbb_connections.compare_and_swap( conn|1, conn )!=conn ); + + // Locate the current connection + generic_connection* pred_conn = NULL; + generic_connection* curr_conn = (generic_connection*) conn; + for( ; curr_conn && curr_conn!=this; curr_conn=curr_conn->next_conn ) + pred_conn = curr_conn; + __TBB_ASSERT( curr_conn==this, "the current connection is not in the list?" ); + + // Remove this from the list + if( pred_conn ) { + pred_conn->next_conn = curr_conn->next_conn; + active_tbb_connections = reinterpret_cast<uintptr_t>(generic_connection<tbb_server,tbb_client>::get_addr(active_tbb_connections)); // release it + } else + active_tbb_connections = (uintptr_t) curr_conn->next_conn; // update & release it + curr_conn->next_conn = NULL; + // Increment the TBB connection close event count + my_ec = ++close_tbb_connection_event_count; + // Wait happens in tbb_connection_v2::~tbb_connection_v2() + } +#if RML_USE_WCRM + my_thread_map.unbind( *this, map_mtx ); + my_thread_map.assist_cleanup( connection_traits<Server,Client>::assist_null_only ); + connection_scavenger.add_request( this ); +#else + my_thread_map.unbind(); + my_thread_map.assist_cleanup( connection_traits<Server,Client>::assist_null_only ); + // Remove extra reference + remove_server_ref(); +#endif +} +#if _MSC_VER && !defined(__INTEL_COMPILER) +#pragma warning( pop ) +#endif + +#if RML_USE_WCRM + +template<typename Server, typename Client> +void generic_connection<Server,Client>::add_virtual_processors( IVirtualProcessorRoot** vproots, unsigned int count ) +{} + +template<> +void generic_connection<tbb_server,tbb_client>::add_virtual_processors( IVirtualProcessorRoot** vproots, unsigned int count ) +{ + my_thread_map.add_virtual_processors( vproots, count, (tbb_connection_v2&)*this, map_mtx ); +} +template<> +void generic_connection<omp_server,omp_client>::add_virtual_processors( IVirtualProcessorRoot** vproots, unsigned int count ) +{ + // For OMP, since it uses ScheudlerPolicy of MinThreads==MaxThreads, this is called once when + // RequestInitialVirtualProcessors() is called. + my_thread_map.add_virtual_processors( vproots, count, (omp_connection_v2&)*this, map_mtx ); +} + +template<typename Server, typename Client> +void generic_connection<Server,Client>::remove_virtual_processors( IVirtualProcessorRoot** vproots, unsigned int count ) +{ + __TBB_ASSERT( false, "should not be called" ); +} +/* For OMP, RemoveVirtualProcessors() will never be called. */ + +template<> +void generic_connection<tbb_server,tbb_client>::remove_virtual_processors( IVirtualProcessorRoot** vproots, unsigned int count ) +{ + my_thread_map.remove_virtual_processors( vproots, count, map_mtx ); +} + +void tbb_connection_v2::adjust_job_count_estimate( int delta ) { +#if TBB_USE_ASSERT + my_job_count_estimate += delta; +#endif /* TBB_USE_ASSERT */ + // Atomically update slack. + int c = my_slack+=delta; + if( c>0 ) { + ++n_adjust_job_count_requests; + my_thread_map.wakeup_tbb_threads( c, map_mtx ); + --n_adjust_job_count_requests; + } +} +#endif /* RML_USE_WCRM */ + +tbb_connection_v2::~tbb_connection_v2() { +#if TBB_USE_ASSERT + if( my_job_count_estimate!=0 ) { + fprintf(stderr, "TBB client tried to disconnect with non-zero net job count estimate of %d\n", int(my_job_count_estimate )); + abort(); + } + __TBB_ASSERT( !my_slack, "attempt to destroy tbb_server with nonzero slack" ); + __TBB_ASSERT( this!=static_cast<tbb_connection_v2*>(generic_connection<tbb_server,tbb_client >::get_addr(active_tbb_connections)), "request_close_connection() must be called" ); +#endif /* TBB_USE_ASSERT */ +#if !RML_USE_WCRM + // If there are other threads ready for work, give them coins + if( the_balance>0 ) + wakeup_some_tbb_threads(); +#endif + // Someone might be accessing my data members + while( current_tbb_conn_readers>0 && (ptrdiff_t)(my_ec-current_tbb_conn_reader_epoch)>0 ) + __TBB_Yield(); +} + +#if !RML_USE_WCRM +template<typename Server, typename Client> +void generic_connection<Server,Client>::make_job( server_thread& t, job_automaton& ja ) { + if( ja.try_acquire() ) { + rml::job* j = client().create_one_job(); + __TBB_ASSERT( j!=NULL, "client:::create_one_job returned NULL" ); + __TBB_ASSERT( (intptr_t(j)&1)==0, "client::create_one_job returned misaligned job" ); + ja.set_and_release( j ); + __TBB_ASSERT( t.my_conn && t.my_ja && t.my_job==NULL, NULL ); + t.my_job = j; + set_scratch_ptr( *j, (void*) &t ); + } +} + +void tbb_connection_v2::adjust_job_count_estimate( int delta ) { +#if TBB_USE_ASSERT + my_job_count_estimate += delta; +#endif /* TBB_USE_ASSERT */ + // Atomically update slack. + int c = my_slack+=delta; + if( c>0 ) { + ++n_adjust_job_count_requests; + // The client has work to do and there are threads available + thread_map::size_type n = my_thread_map.wakeup_tbb_threads(c); + + server_thread* new_threads_anchor = NULL; + thread_map::size_type i; + { + tbb::internal::affinity_helper fpa; + for( i=0; i<n; ++i ) { + // Obtain unrealized threads + thread_map::value_type* k = my_thread_map.add_one_thread( false ); + if( !k ) + // No unrealized threads left. + break; + // Eagerly start the thread off. + fpa.protect_affinity_mask( /*restore_process_mask=*/true ); + my_thread_map.bind_one_thread( *this, *k ); + server_thread& t = k->thread(); + __TBB_ASSERT( !t.link, NULL ); + t.link = new_threads_anchor; + new_threads_anchor = &t; + } + // Implicit destruction of fpa resets original affinity mask. + } + + thread_map::size_type j=0; + for( ; the_balance>0 && j<i; ++j ) { + if( --the_balance>=0 ) { + // Withdraw a coin from the bank + __TBB_ASSERT( new_threads_anchor, NULL ); + + server_thread* t = new_threads_anchor; + new_threads_anchor = t->link; + while( !t->try_grab_for( ts_tbb_busy ) ) + __TBB_Yield(); + t->my_extra_state = ts_started; + } else { + // Overdraft. return it to the bank + ++the_balance; + break; + } + } + __TBB_ASSERT( i-j!=0||new_threads_anchor==NULL, NULL ); + // Mark the ones that did not get started as eligible for being snatched. + if( new_threads_anchor ) + my_thread_map.release_tbb_threads( new_threads_anchor ); + + --n_adjust_job_count_requests; + } +} +#endif /* RML_USE_WCRM */ + +#if RML_USE_WCRM +int omp_connection_v2::try_increase_load( size_type n, bool strict ) { + __TBB_ASSERT(int(n)>=0,NULL); + if( strict ) { + the_balance -= int(n); + } else { + int avail, old; + do { + avail = the_balance; + if( avail<=0 ) { + // No atomic read-write-modify operation necessary. + return avail; + } + // Don't read the_system_balance; if it changes, compare_and_swap will fail anyway. + old = the_balance.compare_and_swap( int(n)<avail ? avail-n : 0, avail ); + } while( old!=avail ); + if( int(n)>avail ) + n=avail; + } +#if TBB_USE_ASSERT + net_delta += n; +#endif /* TBB_USE_ASSERT */ + return n; +} + +void omp_connection_v2::decrease_load( size_type /*n*/ ) {} + +void omp_connection_v2::get_threads( size_type request_size, void* cookie, job* array[] ) { + unsigned index = 0; + std::vector<omp_server_thread*> enlisted(request_size); + std::vector<thread_grab_t> to_activate(request_size); + + if( request_size==0 ) return; + + { + tbb::spin_mutex::scoped_lock lock(map_mtx); + + __TBB_ASSERT( !is_closing(), "try to get threads while connection is being shutdown?" ); + + for( int scan=0; scan<2; ++scan ) { + for( thread_map::iterator i=my_thread_map.begin(); i!=my_thread_map.end(); ++i ) { + omp_server_thread* thr = (omp_server_thread*) (*i).second; + // in the first scan, skip VPs that are lent + if( scan==0 && thr->is_lent() ) continue; + thread_grab_t res = thr->try_grab_for(); + if( res!=wk_failed ) {// && if is not busy by some other scheduler + to_activate[index] = res; + enlisted[index] = thr; + if( ++index==request_size ) + goto activate_threads; + } + } + } + } + +activate_threads: + + for( unsigned i=0; i<index; ++i ) { + omp_server_thread* thr = enlisted[i]; + if( to_activate[i]==wk_from_asleep ) + thr->get_virtual_processor()->Activate( thr ); + job* j = thr->wait_for_job(); + array[i] = j; + thr->omp_data.produce( client(), j, cookie, i PRODUCE_ARG(*this) ); + } + + if( index==request_size ) + return; + + // If we come to this point, it must be because dynamic==false + // Create Oversubscribers.. + + // Note that our policy is such that MinConcurrency==MaxConcurrency. + // RM will deliver MaxConcurrency of VirtualProcessors and no more. + __TBB_ASSERT( request_size>index, NULL ); + unsigned n = request_size - index; + std::vector<server_thread*> thr_vec(n); + typedef std::vector<server_thread*>::iterator iterator_thr; + my_thread_map.create_oversubscribers( n, thr_vec, *this, map_mtx ); + for( iterator_thr ti=thr_vec.begin(); ti!=thr_vec.end(); ++ti ) { + omp_server_thread* thr = (omp_server_thread*) *ti; + __TBB_ASSERT( thr, "thread not created?" ); + // Thread is already grabbed; since it is newly created, we need to activate it. + thr->get_virtual_processor()->Activate( thr ); + job* j = thr->wait_for_job(); + array[index] = j; + thr->omp_data.produce( client(), j, cookie, index PRODUCE_ARG(*this) ); + ++index; + } +} + +#if _WIN32||_WIN64 +void omp_connection_v2::deactivate( rml::job* j ) +{ + my_thread_map.adjust_balance(1); +#if TBB_USE_ASSERT + net_delta -= 1; +#endif + omp_server_thread* thr = (omp_server_thread*) scratch_ptr( *j ); + (thr->get_virtual_processor())->Deactivate( thr ); +} + +void omp_connection_v2::reactivate( rml::job* j ) +{ + // Should not adjust the_balance because OMP client is supposed to + // do try_increase_load() to reserve the threads to use. + omp_server_thread* thr = (omp_server_thread*) scratch_ptr( *j ); + (thr->get_virtual_processor())->Activate( thr ); +} +#endif /* !_WIN32||_WIN64 */ + +#endif /* RML_USE_WCRM */ + +//! Wake up some available TBB threads +void wakeup_some_tbb_threads() +{ + /* First, atomically grab the connection, then increase the server ref count to keep + it from being released prematurely. Second, check if the balance is available for TBB + and the TBB connection has slack to exploit. If the answer is true, go ahead and + try to wake some up. */ + if( generic_connection<tbb_server,tbb_client >::get_addr(active_tbb_connections)==0 ) + // the next connection will see the change; return. + return; + +start_it_over: + int n_curr_readers = ++current_tbb_conn_readers; + if( n_curr_readers>1 ) // I lost + return; + // if n_curr_readers==1, i am the first one, so I will take responsibility for waking TBB threads up. + + // update the current epoch + current_tbb_conn_reader_epoch = close_tbb_connection_event_count; + + // read and clear + // Newly added connection will not invalidate the pointer, and it will + // compete with the current one to claim coins. + // One that is about to close the connection increments the event count + // after it removes the connection from the list. But it will keep around + // the connection until all readers including this one catch up. So, reading + // the head and clearing the lock bit should be o.k. + generic_connection<tbb_server,tbb_client>* next_conn_wake_up = generic_connection<tbb_server,tbb_client>::get_addr( active_tbb_connections ); + + for( ; next_conn_wake_up; ) { + /* some threads are creating TBB server threads; they may not see my changes made to the_balance */ + /* When a thread is in adjust_job_count_estimate() to increase the slack + RML tries to activate worker threads on behalf of the requesting thread + by repeatedly drawing a coin from the bank optimistically and grabbing a + thread. If it finds the bank overdrafted, it returns the coin back to + the bank and returns the control to the thread (return from the method). + There lies a tiny timing hole. + + When the overdraft occurs (note that multiple masters may be in + adjust_job_count_estimate() so the_balance can be any negative value) and + a worker returns from the TBB work at that moment, its returning the coin + does not bump up the_balance over 0, so it happily returns from + wakeup_some_tbb_threads() without attempting to give coins to worker threads + that are ready. + */ + while( ((tbb_connection_v2*)next_conn_wake_up)->n_adjust_job_count_requests>0 ) + __TBB_Yield(); + + int bal = the_balance; + n_curr_readers = current_tbb_conn_readers; // get the snapshot + if( bal<=0 ) break; + // if the connection is deleted, the following will immediately return because its slack would be 0 or less. + + tbb_connection_v2* tbb_conn = (tbb_connection_v2*)next_conn_wake_up; + int my_slack = tbb_conn->my_slack; + if( my_slack>0 ) tbb_conn->wakeup_tbb_threads( my_slack ); + next_conn_wake_up = next_conn_wake_up->next_conn; + } + + int delta = current_tbb_conn_readers -= n_curr_readers; + //if delta>0, more threads entered the routine since this one took the snapshot + if( delta>0 ) { + current_tbb_conn_readers = 0; + if( the_balance>0 && generic_connection<tbb_server,tbb_client >::get_addr(active_tbb_connections)!=0 ) + goto start_it_over; + } + + // Signal any connection that is waiting for me to complete my access that I am done. + current_tbb_conn_reader_epoch = close_tbb_connection_event_count; +} + +#if !RML_USE_WCRM +int omp_connection_v2::try_increase_load( size_type n, bool strict ) { + __TBB_ASSERT(int(n)>=0,NULL); + if( strict ) { + the_balance -= int(n); + } else { + int avail, old; + do { + avail = the_balance; + if( avail<=0 ) { + // No atomic read-write-modify operation necessary. + return avail; + } + // don't read the_balance; if it changes, compare_and_swap will fail anyway. + old = the_balance.compare_and_swap( int(n)<avail ? avail-n : 0, avail ); + } while( old!=avail ); + if( int(n)>avail ) + n=avail; + } +#if TBB_USE_ASSERT + net_delta += n; +#endif /* TBB_USE_ASSERT */ + return n; +} + +void omp_connection_v2::decrease_load( size_type n ) { + __TBB_ASSERT(int(n)>=0,NULL); + my_thread_map.adjust_balance(int(n)); +#if TBB_USE_ASSERT + net_delta -= n; +#endif /* TBB_USE_ASSERT */ +} + +void omp_connection_v2::get_threads( size_type request_size, void* cookie, job* array[] ) { + + if( !request_size ) + return; + + unsigned index = 0; + for(;;) { // don't return until all request_size threads are grabbed. + // Need to grab some threads + thread_map::iterator k_end=my_thread_map.end(); + for( thread_map::iterator k=my_thread_map.begin(); k!=k_end; ++k ) { + // If another thread added *k, there is a tiny timing window where thread() is invalid. + server_thread& t = k->wait_for_thread(); + if( t.try_grab_for( ts_omp_busy ) ) { + // The preincrement instead of post-increment of index is deliberate. + job* j = k->wait_for_job(); + array[index] = j; + t.omp_dispatch.produce( client(), j, cookie, index PRODUCE_ARG(*this) ); + if( ++index==request_size ) + return; + } + } + // Need to allocate more threads + for( unsigned i=index; i<request_size; ++i ) { + __TBB_ASSERT( index<request_size, NULL ); + thread_map::value_type* k = my_thread_map.add_one_thread( true ); +#if TBB_USE_ASSERT + if( !k ) { + // Client erred + __TBB_ASSERT(false, "server::get_threads: exceeded job_count\n"); + } +#endif + my_thread_map.bind_one_thread( *this, *k ); + server_thread& t = k->thread(); + if( t.try_grab_for( ts_omp_busy ) ) { + job* j = k->wait_for_job(); + array[index] = j; + // The preincrement instead of post-increment of index is deliberate. + t.omp_dispatch.produce( client(), j, cookie, index PRODUCE_ARG(*this) ); + if( ++index==request_size ) + return; + } // else someone else snatched it. + } + } +} +#endif /* !RML_USE_WCRM */ + +//------------------------------------------------------------------------ +// Methods of omp_dispatch_type +//------------------------------------------------------------------------ +void omp_dispatch_type::consume() { + // Wait for short window between when master sets state of this thread to ts_omp_busy + // and master thread calls produce. + job_type* j; + tbb::internal::atomic_backoff backoff; + while( (j = job)==NULL ) backoff.pause(); + job = static_cast<job_type*>(NULL); + client->process(*j,cookie,index); +#if TBB_USE_ASSERT + // Return of method process implies "decrease_load" from client's viewpoint, even though + // the actual adjustment of the_balance only happens when this thread really goes to sleep. + --server->net_delta; +#endif /* TBB_USE_ASSERT */ +} + +#if !RML_USE_WCRM +#if _WIN32||_WIN64 +void omp_connection_v2::deactivate( rml::job* j ) +{ +#if TBB_USE_ASSERT + net_delta -= 1; +#endif + __TBB_ASSERT( j, NULL ); + server_thread* thr = (server_thread*) scratch_ptr( *j ); + thr->deactivate(); +} + +void omp_connection_v2::reactivate( rml::job* j ) +{ + // Should not adjust the_balance because OMP client is supposed to + // do try_increase_load() to reserve the threads to use. + __TBB_ASSERT( j, NULL ); + server_thread* thr = (server_thread*) scratch_ptr( *j ); + thr->reactivate(); +} +#endif /* _WIN32||_WIN64 */ + +//------------------------------------------------------------------------ +// Methods of server_thread +//------------------------------------------------------------------------ + +server_thread::server_thread() : + ref_count(0), + link(NULL), + my_map_pos(), + my_conn(NULL), my_job(NULL), my_ja(NULL) +{ + state = ts_idle; + terminate = false; +#if TBB_USE_ASSERT + has_active_thread = false; +#endif /* TBB_USE_ASSERT */ +} + +server_thread::~server_thread() { + __TBB_ASSERT( !has_active_thread, NULL ); +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warnings about an initialized variable 'sink_for_alloca' not referenced + #pragma warning(push) + #pragma warning(disable:4189) +#endif +__RML_DECL_THREAD_ROUTINE server_thread::thread_routine( void* arg ) { + server_thread* self = static_cast<server_thread*>(arg); + AVOID_64K_ALIASING( self->my_index ); +#if TBB_USE_ASSERT + __TBB_ASSERT( !self->has_active_thread, NULL ); + self->has_active_thread = true; +#endif /* TBB_USE_ASSERT */ + self->loop(); + return 0; +} +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +void server_thread::launch( size_t stack_size ) { +#if USE_WINTHREAD + thread_monitor::launch( thread_routine, this, stack_size, &this->my_index ); +#else + thread_monitor::launch( thread_routine, this, stack_size ); +#endif /* USE_PTHREAD */ +} + +void server_thread::sleep_perhaps( thread_state_t asleep ) { + if( terminate ) return; + __TBB_ASSERT( asleep==ts_asleep, NULL ); + thread_monitor::cookie c; + monitor.prepare_wait(c); + if( state.compare_and_swap( asleep, ts_idle )==ts_idle ) { + if( !terminate ) { + monitor.commit_wait(c); + // Someone else woke me up. The compare_and_swap further below deals with spurious wakeups. + } else { + monitor.cancel_wait(); + } + thread_state_t s = read_state(); + if( s==ts_asleep ) { + state.compare_and_swap( ts_idle, ts_asleep ); + // I woke myself up, either because I cancelled the wait or suffered a spurious wakeup. + } else { + // Someone else woke me up; there the_balance is decremented by 1. -- tbb only + if( !is_omp_thread ) { + __TBB_ASSERT( s==ts_tbb_busy||s==ts_idle, NULL ); + } + } + } else { + // someone else made it busy ; see try_grab_for when state==ts_idle. + __TBB_ASSERT( state==ts_omp_busy||state==ts_tbb_busy, NULL ); + monitor.cancel_wait(); + } + __TBB_ASSERT( read_state()!=asleep, "a thread can only put itself to sleep" ); +} + +bool server_thread::wakeup( thread_state_t to, thread_state_t from ) { + bool success = false; + __TBB_ASSERT( from==ts_asleep && (to==ts_idle||to==ts_omp_busy||to==ts_tbb_busy), NULL ); + if( state.compare_and_swap( to, from )==from ) { + if( !is_omp_thread ) __TBB_ASSERT( to==ts_idle||to==ts_tbb_busy, NULL ); + // There is a small timing window that permits balance to become negative, + // but such occurrences are probably rare enough to not worry about, since + // at worst the result is slight temporary oversubscription. + monitor.notify(); + success = true; + } + return success; +} + +//! Attempt to change a thread's state to ts_omp_busy, and waking it up if necessary. +bool server_thread::try_grab_for( thread_state_t target_state ) { + bool success = false; + switch( read_state() ) { + case ts_asleep: + success = wakeup( target_state, ts_asleep ); + break; + case ts_idle: + success = state.compare_and_swap( target_state, ts_idle )==ts_idle; + break; + default: + // Thread is not available to be part of an OpenMP thread team. + break; + } + return success; +} + +#if _WIN32||_WIN64 +void server_thread::deactivate() { + thread_state_t es = (thread_state_t) my_extra_state.fetch_and_store( ts_deactivated ); + __TBB_ASSERT( my_extra_state==ts_deactivated, "someone else tampered with my_extra_state?" ); + if( es==ts_none ) + state = ts_idle; + else + __TBB_ASSERT( es==ts_reactivated, "Cannot call deactivate() while in ts_deactivated" ); + // only the thread can transition itself from ts_deactivted to ts_none + __TBB_ASSERT( my_extra_state==ts_deactivated, "someone else tampered with my_extra_state?" ); + my_extra_state = ts_none; // release the critical section + int bal = ++the_balance; + if( bal>0 ) + wakeup_some_tbb_threads(); + if( es==ts_none ) + sleep_perhaps( ts_asleep ); +} + +void server_thread::reactivate() { + thread_state_t es; + do { + while( (es=read_extra_state())==ts_deactivated ) + __TBB_Yield(); + if( es==ts_reactivated ) { + __TBB_ASSERT( false, "two Reactivate() calls in a row. Should not happen" ); + return; + } + __TBB_ASSERT( es==ts_none, NULL ); + } while( (thread_state_t)my_extra_state.compare_and_swap( ts_reactivated, ts_none )!=ts_none ); + if( state!=ts_omp_busy ) { + my_extra_state = ts_none; + while( !try_grab_for( ts_omp_busy ) ) + __TBB_Yield(); + } +} +#endif /* _WIN32||_WIN64 */ + + +template<typename Connection> +bool server_thread::destroy_job( Connection& c ) { + __TBB_ASSERT( !is_omp_thread||(state==ts_idle||state==ts_omp_busy), NULL ); + __TBB_ASSERT( is_omp_thread||(state==ts_idle||state==ts_tbb_busy), NULL ); + if( !is_omp_thread ) { + __TBB_ASSERT( state==ts_idle||state==ts_tbb_busy, NULL ); + if( state==ts_idle ) + state.compare_and_swap( ts_done, ts_idle ); + // 'state' may be set to ts_tbb_busy by another thread. + + if( state==ts_tbb_busy ) { // return the coin to the deposit + // need to deposit first to let the next connection see the change + ++the_balance; + state = ts_done; // no other thread changes the state when it is ts_*_busy + } + } + if( job_automaton* ja = my_ja ) { + rml::job* j; + if( ja->try_plug(j) ) { + __TBB_ASSERT( j, NULL ); + c.client().cleanup(*j); + c.remove_client_ref(); + } else { + // Some other thread took responsibility for cleaning up the job. + } + } + // Must do remove client reference first, because execution of + // c.remove_ref() can cause *this to be destroyed. + int k = remove_ref(); + __TBB_ASSERT_EX( k==0, "more than one references?" ); +#if TBB_USE_ASSERT + has_active_thread = false; +#endif /* TBB_USE_ASSERT */ + c.remove_server_ref(); + return true; +} + +bool server_thread::do_termination() { + if( is_omp_thread ) + return destroy_job( *static_cast<omp_connection_v2*>(my_conn) ); + else + return destroy_job( *static_cast<tbb_connection_v2*>(my_conn) ); +} + +//! Loop that each thread executes +void server_thread::loop() { + if( is_omp_thread ) + static_cast<omp_connection_v2*>(my_conn)->make_job( *this, *my_ja ); + else + static_cast<tbb_connection_v2*>(my_conn)->make_job( *this, *my_ja ); + for(;;) { + __TBB_Yield(); + if( state==ts_idle ) + sleep_perhaps( ts_asleep ); + + // Check whether I should quit. + if( terminate ) + if( do_termination() ) + return; + + // read the state + thread_state_t s = read_state(); + __TBB_ASSERT( s==ts_idle||s==ts_omp_busy||s==ts_tbb_busy, NULL ); + + if( s==ts_omp_busy ) { + // Enslaved by OpenMP team. + omp_dispatch.consume(); + /* here wake TBB threads up if feasible */ + if( ++the_balance>0 ) + wakeup_some_tbb_threads(); + state = ts_idle; + } else if( s==ts_tbb_busy ) { + // do some TBB work. + __TBB_ASSERT( my_conn && my_job, NULL ); + tbb_connection_v2& conn = *static_cast<tbb_connection_v2*>(my_conn); + // give openmp higher priority + bool has_coin = true; + if( conn.has_slack() ) { + // it has the coin, it should trip to the scheduler at least once as long as its slack is positive + do { + if( conn.try_process( *this, *my_job ) ) + if( conn.has_slack() && the_balance>=0 ) + has_coin = !conn.wakeup_next_thread( my_map_pos ); + } while( has_coin && conn.has_slack() && the_balance>=0 ); + } + state = ts_idle; + if( has_coin ) { + ++the_balance; // return the coin back to the deposit + if( conn.has_slack() ) { // a new adjust_job_request_estimate() is in progress + // it may have missed my changes to state and/or the_balance + if( --the_balance>=0 ) { // try to grab the coin back + // I got the coin + if( state.compare_and_swap( ts_tbb_busy, ts_idle )!=ts_idle ) + ++the_balance; // someone else enlisted me. + } else { + // overdraft. return the coin + ++the_balance; + } + } // else the new request will see my changes to state & the_balance. + } + /* here wake TBB threads up if feasible */ + if( the_balance>0 ) + wakeup_some_tbb_threads(); + } + } +} +#endif /* !RML_USE_WCRM */ + +#if RML_USE_WCRM + +class tbb_connection_v2; +class omp_connection_v2; + +#define CREATE_SCHEDULER_POLICY(policy,min_thrs,max_thrs,stack_size) \ + try { \ + policy = new SchedulerPolicy (7, \ + SchedulerKind, RML_THREAD_KIND, /*defined in _rml_serer_msrt.h*/ \ + MinConcurrency, min_thrs, \ + MaxConcurrency, max_thrs, \ + TargetOversubscriptionFactor, 1, \ + ContextStackSize, stack_size/1000, /*ConcRT:kB, iRML:bytes*/ \ + ContextPriority, THREAD_PRIORITY_NORMAL, \ + DynamicProgressFeedback, ProgressFeedbackDisabled ); \ + } catch ( invalid_scheduler_policy_key & ) { \ + __TBB_ASSERT( false, "invalid scheduler policy key exception caught" );\ + } catch ( invalid_scheduler_policy_value & ) { \ + __TBB_ASSERT( false, "invalid scheduler policy value exception caught" );\ + } + +static unsigned int core_count; +static tbb::atomic<int> core_count_inited; + + +static unsigned int get_processor_count() +{ + if( core_count_inited!=2 ) { + if( core_count_inited.compare_and_swap( 1, 0 )==0 ) { + core_count = GetProcessorCount(); + core_count_inited = 2; + } else { + tbb::internal::spin_wait_until_eq( core_count_inited, 2 ); + } + } + return core_count; +} + +template<typename Connection> +scheduler<Connection>::scheduler( Connection& conn ) : uid(GetSchedulerId()), my_conn(conn) {} + +template<> +scheduler<tbb_connection_v2>::scheduler( tbb_connection_v2& conn ) : uid(GetSchedulerId()), my_conn(conn) +{ + rml::client& cl = my_conn.client(); + unsigned max_job_count = cl.max_job_count(); + unsigned count = get_processor_count(); + __TBB_ASSERT( max_job_count>0, "max job count must be positive" ); + __TBB_ASSERT( count>1, "The processor count must be greater than 1" ); + if( max_job_count>count-1) max_job_count = count-1; + CREATE_SCHEDULER_POLICY( my_policy, 0, max_job_count, cl.min_stack_size() ); +} + +#if __RML_REMOVE_VIRTUAL_PROCESSORS_DISABLED +template<> +void scheduler<tbb_connection_v2>::RemoveVirtualProcessors( IVirtualProcessorRoot**, unsigned int) +{ +} +#else +template<> +void scheduler<tbb_connection_v2>::RemoveVirtualProcessors( IVirtualProcessorRoot** vproots, unsigned int count ) +{ + if( !my_conn.is_closing() ) + my_conn.remove_virtual_processors( vproots, count ); +} +#endif + +template<> +void scheduler<tbb_connection_v2>::NotifyResourcesExternallyIdle( IVirtualProcessorRoot** /*vproots*/, unsigned int /*count*/) +{ + __TBB_ASSERT( false, "NotifyResourcesExternallyIdle() is not allowed for TBB" ); +} + +template<> +void scheduler<tbb_connection_v2>::NotifyResourcesExternallyBusy( IVirtualProcessorRoot** /*vproots*/, unsigned int /*count*/ ) +{ + __TBB_ASSERT( false, "NotifyResourcesExternallyBusy() is not allowed for TBB" ); +} + +template<> +scheduler<omp_connection_v2>::scheduler( omp_connection_v2& conn ) : uid(GetSchedulerId()), my_conn(conn) +{ + unsigned count = get_processor_count(); + rml::client& cl = my_conn.client(); + __TBB_ASSERT( count>1, "The processor count must be greater than 1" ); + CREATE_SCHEDULER_POLICY( my_policy, count-1, count-1, cl.min_stack_size() ); +} + +template<> +void scheduler<omp_connection_v2>::RemoveVirtualProcessors( IVirtualProcessorRoot** /*vproots*/, unsigned int /*count*/ ) { + __TBB_ASSERT( false, "RemoveVirtualProcessors() is not allowed for OMP" ); +} + +template<> +void scheduler<omp_connection_v2>::NotifyResourcesExternallyIdle( IVirtualProcessorRoot** vproots, unsigned int count ){ + if( !my_conn.is_closing() ) + my_conn.notify_resources_externally_idle( vproots, count ); +} + +template<> +void scheduler<omp_connection_v2>::NotifyResourcesExternallyBusy( IVirtualProcessorRoot** vproots, unsigned int count ){ + if( !my_conn.is_closing() ) + my_conn.notify_resources_externally_busy( vproots, count ); +} + +/* ts_idle, ts_asleep, ts_busy */ +void tbb_server_thread::Dispatch( DispatchState* ) { + // Activate() will resume a thread right after Deactivate() as if it returns from the call + tbb_connection_v2* tbb_conn = static_cast<tbb_connection_v2*>(my_conn); + make_job( *tbb_conn, *this ); + + for( ;; ) { + // Try to wake some TBB threads if the balance is positive. + // When a thread is added by ConcRT and enter here for the first time, + // the thread may wake itself up (i.e., atomically change its state to ts_busy. + if( the_balance>0 ) + wakeup_some_tbb_threads(); + if( read_state()!=ts_busy ) + if( sleep_perhaps() ) + return; + if( terminate ) + if( initiate_termination() ) + return; + if( read_state()==ts_busy ) { + // this thread has a coin (i.e., state=ts_busy; it should trip to the scheduler at least once + if ( tbb_conn->has_slack() ) { + do { + tbb_conn->try_process( *wait_for_job() ); + } while( tbb_conn->has_slack() && the_balance>=0 && !is_removed() ); + } + __TBB_ASSERT( read_state()==ts_busy, "thread is not in busy state after returning from process()" ); + // see remove_virtual_processors() + if( my_state.compare_and_swap( ts_idle, ts_busy )==ts_busy ) { + int bal = ++the_balance; + if( tbb_conn->has_slack() ) { + // slack is positive, volunteer to help + bal = --the_balance; // try to grab the coin back + if( bal>=0 ) { // got the coin back + if( my_state.compare_and_swap( ts_busy, ts_idle )!=ts_idle ) + ++the_balance; // someone else enlisted me. + // else my_state is ts_busy, I will come back to tbb_conn->try_process(). + } else { + // overdraft. return the coin + ++the_balance; + } + } // else the new request will see my changes to state & the_balance. + } else { + __TBB_ASSERT( false, "someone tampered with my state" ); + } + } // someone else might set the state to something other than ts_idle + } +} + +void omp_server_thread::Dispatch( DispatchState* ) { + // Activate() will resume a thread right after Deactivate() as if it returns from the call + make_job( *static_cast<omp_connection_v2*>(my_conn), *this ); + + for( ;; ) { + if( read_state()!=ts_busy ) + sleep_perhaps(); + if( terminate ) { + if( initiate_termination() ) + return; + } + if( read_state()==ts_busy ) { + omp_data.consume(); + __TBB_ASSERT( read_state()==ts_busy, "thread is not in busy state after returning from process()" ); + my_thread_map.adjust_balance( 1 ); + set_state( ts_idle ); + } + // someone else might set the state to something other than ts_idle + } +} + +//! Attempt to change a thread's state to ts_omp_busy, and waking it up if necessary. +thread_grab_t server_thread_rep::try_grab_for() { + thread_grab_t res = wk_failed; + thread_state_t s = read_state(); + switch( s ) { + case ts_asleep: + if( wakeup( ts_busy, ts_asleep ) ) + res = wk_from_asleep; + __TBB_ASSERT( res==wk_failed||read_state()==ts_busy, NULL ); + break; + case ts_idle: + if( my_state.compare_and_swap( ts_busy, ts_idle )==ts_idle ) + res = wk_from_idle; + // At this point a thread is grabbed (i.e., its state has changed to ts_busy. + // It is possible that the thread 1) processes the job, returns from process() and + // sets its state ts_idle again. In some cases, it even sets its state to ts_asleep. + break; + default: + break; + } + return res; +} + +bool tbb_server_thread::switch_out() { + thread_state_t s = read_state(); + __TBB_ASSERT( s==ts_asleep||s==ts_busy, NULL ); + // This thread comes back from the TBB scheduler, and changed its state to ts_asleep successfully. + // The master enlisted it and woke it up by Activate()'ing it; now it is emerging from Deactivated(). + // ConcRT requested for removal of the vp associated with the thread, and RML marks it removed. + // Now, it has ts_busy, and removed. -- we should remove it. + IExecutionResource* old_vp = my_execution_resource; + if( s==ts_busy ) { + ++the_balance; + my_state = ts_asleep; + } + IThreadProxy* proxy = my_proxy; + __TBB_ASSERT( proxy, NULL ); + my_execution_resource = (IExecutionResource*) c_remove_prepare; + old_vp->Remove( my_scheduler ); + my_execution_resource = (IExecutionResource*) c_remove_returned; + int cnt = --activation_count; + __TBB_ASSERT_EX( cnt==0||cnt==1, "too many activations?" ); + proxy->SwitchOut(); + if( terminate ) { + bool activated = activation_count==1; +#if TBB_USE_ASSERT + /* In a rare sequence of events, a thread comes out of SwitchOut with activation_count==1. + * 1) The thread is SwitchOut'ed. + * 2) AddVirtualProcessors() arrived and the thread is Activated. + * 3) The thread is coming out of SwitchOut(). + * 4) request_close_connection arrives and inform the thread that it is time to terminate. + * 5) The thread hits the check and falls into the path with 'activated==true'. + * In that case, do the clean-up but do not switch to the thread scavenger; rather simply return to RM. + */ + if( activated ) { + // thread is 'revived' in add_virtual_processors after being Activated(). + // so, if the thread extra state is still marked 'removed', it will shortly change to 'none' + // i.e., !is_remove(). The thread state is changed to ts_idle before the extra state, so + // the thread's state should be either ts_idle or ts_done. + while( is_removed() ) + __TBB_Yield(); + thread_state_t state = read_state(); + __TBB_ASSERT( state==ts_idle || state==ts_done, NULL ); + } +#endif + __TBB_ASSERT( my_state==ts_asleep||my_state==ts_idle, NULL ); + // it is possible that in make_job() the thread may not have a chance to create a job. + // my_job may not be set if the thread did not get a chance to process client's job (i.e., call try_process()) + rml::job* j; + if( my_job_automaton.try_plug(j) ) { + __TBB_ASSERT( j, NULL ); + my_client.cleanup(*j); + my_conn->remove_client_ref(); + } + // Must do remove client reference first, because execution of + // c.remove_ref() can cause *this to be destroyed. + if( !activated ) + proxy->SwitchTo( my_thread_map.get_thread_scavenger(), Idle ); + my_conn->remove_server_ref(); + return true; + } + // We revive a thread in add_virtual_processors() after we Activate the thread on a new virtual processor. + // So briefly wait until the thread's my_execution_resource gets set. + while( get_virtual_processor()==c_remove_returned ) + __TBB_Yield(); + return false; +} + +bool tbb_server_thread::sleep_perhaps () { + if( terminate ) return false; + thread_state_t s = read_state(); + if( s==ts_idle ) { + if( my_state.compare_and_swap( ts_asleep, ts_idle )==ts_idle ) { + // If a thread is between read_state() and compare_and_swap(), and the master tries to terminate, + // the master's compare_and_swap() will fail because the thread's state is ts_idle. + // We need to check if terminate is true or not before letting the thread go to sleep, + // otherwise we will miss the terminate signal. + if( !terminate ) { + if( !is_removed() ) { + --activation_count; + get_virtual_processor()->Deactivate( this ); + } + if( is_removed() ) { + if( switch_out() ) + return true; + __TBB_ASSERT( my_execution_resource>c_remove_returned, NULL ); + } + // in add_virtual_processors(), when we revive a thread, we change its state after Activate the thread + // in that case the state may be ts_asleep for a short period + while( read_state()==ts_asleep ) + __TBB_Yield(); + } else { + if( my_state.compare_and_swap( ts_done, ts_asleep )!=ts_asleep ) { + --activation_count; + // unbind() changed my state. It will call Activate(). So issue a matching Deactivate() + get_virtual_processor()->Deactivate( this ); + } + } + } + } else { + __TBB_ASSERT( s==ts_busy, NULL ); + } + return false; +} + +void omp_server_thread::sleep_perhaps () { + if( terminate ) return; + thread_state_t s = read_state(); + if( s==ts_idle ) { + if( my_state.compare_and_swap( ts_asleep, ts_idle )==ts_idle ) { + // If a thread is between read_state() and compare_and_swap(), and the master tries to terminate, + // the master's compare_and_swap() will fail because the thread's state is ts_idle. + // We need to check if terminate is true or not before letting the thread go to sleep, + // otherwise we will miss the terminate signal. + if( !terminate ) { + get_virtual_processor()->Deactivate( this ); + __TBB_ASSERT( !is_removed(), "OMP threads should not be deprived of a virtual processor" ); + __TBB_ASSERT( read_state()!=ts_asleep, NULL ); + } else { + if( my_state.compare_and_swap( ts_done, ts_asleep )!=ts_asleep ) + // unbind() changed my state. It will call Activate(). So issue a matching Deactivate() + get_virtual_processor()->Deactivate( this ); + } + } + } else { + __TBB_ASSERT( s==ts_busy, NULL ); + } +} + +bool tbb_server_thread::initiate_termination() { + if( read_state()==ts_busy ) { + int bal = ++the_balance; + if( bal>0 ) wakeup_some_tbb_threads(); + } + return destroy_job( (tbb_connection_v2*) my_conn ); +} + +template<typename Connection> +bool server_thread_rep::destroy_job( Connection* c ) { + __TBB_ASSERT( my_state!=ts_asleep, NULL ); + rml::job* j; + if( my_job_automaton.try_plug(j) ) { + __TBB_ASSERT( j, NULL ); + my_client.cleanup(*j); + c->remove_client_ref(); + } + // Must do remove client reference first, because execution of + // c.remove_ref() can cause *this to be destroyed. + c->remove_server_ref(); + return true; +} + +void thread_map::assist_cleanup( bool assist_null_only ) { + // To avoid deadlock, the current thread *must* help out with cleanups that have not started, + // because the thread that created the job may be busy for a long time. + for( iterator i = begin(); i!=end(); ++i ) { + rml::job* j=0; + server_thread* thr = (*i).second; + job_automaton& ja = thr->my_job_automaton; + if( assist_null_only ? ja.try_plug_null() : ja.try_plug(j) ) { + if( j ) { + my_client.cleanup(*j); + } else { + // server thread did not get a chance to create a job. + } + remove_client_ref(); + } + } +} + +void thread_map::add_virtual_processors( IVirtualProcessorRoot** vproots, unsigned int count, tbb_connection_v2& conn, ::tbb::spin_mutex& mtx ) +{ +#if TBB_USE_ASSERT + int req_cnt = ++n_add_vp_requests; + __TBB_ASSERT( req_cnt==1, NULL ); +#endif + std::vector<thread_map::iterator> vec(count); + std::vector<tbb_server_thread*> tvec(count); + iterator end; + + { + tbb::spin_mutex::scoped_lock lck( mtx ); + __TBB_ASSERT( my_map.size()==0||count==1, NULL ); + end = my_map.end(); //remember 'end' at the time of 'find' + // find entries in the map for those VPs that were previously added and then removed. + for( size_t i=0; i<count; ++i ) { + vec[i] = my_map.find( (key_type) vproots[i] ); +#if TBB_USE_DEBUG + if( vec[i]!=end ) { + tbb_server_thread* t = (tbb_server_thread*) (*vec[i]).second; + IVirtualProcessorRoot* v = t->get_virtual_processor(); + __TBB_ASSERT( v==c_remove_prepare||v==c_remove_returned, NULL ); + } +#endif + } + + iterator nxt = my_map.begin(); + for( size_t i=0; i<count; ++i ) { + if( vec[i]!=end ) { +#if TBB_USE_ASSERT + tbb_server_thread* t = (tbb_server_thread*) (*vec[i]).second; + __TBB_ASSERT( t->read_state()==ts_asleep, NULL ); + IVirtualProcessorRoot* r = t->get_virtual_processor(); + __TBB_ASSERT( r==c_remove_prepare||r==c_remove_returned, NULL ); +#endif + continue; + } + + if( my_unrealized_threads>0 ) { + --my_unrealized_threads; + } else { + __TBB_ASSERT( nxt!=end, "nxt should not be thread_map::iterator::end" ); + // find a removed thread context for i + for( ; nxt!=end; ++nxt ) { + tbb_server_thread* t = (tbb_server_thread*) (*nxt).second; + if( t->is_removed() && t->read_state()==ts_asleep && t->get_virtual_processor()==c_remove_returned ) { + vec[i] = nxt++; + break; + } + } + // break target + if( vec[i]==end ) // ignore excessive VP. + vproots[i] = NULL; + } + } + } + + for( size_t i=0; i<count; ++i ) { + __TBB_ASSERT( !tvec[i], NULL ); + if( vec[i]==end ) { + if( vproots[i] ) { + tvec[i] = my_tbb_allocator.allocate(1); + new ( tvec[i] ) tbb_server_thread( false, my_scheduler, (IExecutionResource*)vproots[i], &conn, *this, my_client ); + } +#if TBB_USE_ASSERT + } else { + tbb_server_thread* t = (tbb_server_thread*) (*vec[i]).second; + __TBB_ASSERT( t->GetProxy(), "Proxy is cleared?" ); +#endif + } + } + + { + tbb::spin_mutex::scoped_lock lck( mtx ); + + bool closing = is_closing(); + + for( size_t i=0; i<count; ++i ) { + if( vec[i]==end ) { + if( vproots[i] ) { + thread_map::key_type key = (thread_map::key_type) vproots[i]; + vec[i] = insert( key, (server_thread*) tvec[i] ); + my_client_ref_count.add_ref(); + my_server_ref_count.add_ref(); + } + } else if( !closing ) { + tbb_server_thread* t = (tbb_server_thread*) (*vec[i]).second; + + if( (*vec[i]).first!=(thread_map::key_type)vproots[i] ) { + my_map.erase( vec[i] ); + thread_map::key_type key = (thread_map::key_type) vproots[i]; + __TBB_ASSERT( key, NULL ); + vec[i] = insert( key, t ); + } + __TBB_ASSERT( t->read_state()==ts_asleep, NULL ); + // We did not decrement server/client ref count when a thread is removed. + // So, don't increment server/client ref count here. + } + } + + // we could check is_closing() earlier. That requires marking the newly allocated server_thread objects + // that are not inserted into the thread_map, and deallocate them. Doing so seems more cumbersome + // than simply adding these to the thread_map and let thread_map's destructor take care of reclamation. + __TBB_ASSERT( closing==is_closing(), NULL ); + if( closing ) return; + } + + for( size_t i=0; i<count; ++i ) { + if( vproots[i] ) { + tbb_server_thread* t = (tbb_server_thread*) (*vec[i]).second; + __TBB_ASSERT( tvec[i]!=NULL||t->GetProxy(), "Proxy is cleared?" ); + if( t->is_removed() ) + __TBB_ASSERT( t->get_virtual_processor()==c_remove_returned, NULL ); + int cnt = ++t->activation_count; + __TBB_ASSERT_EX( cnt==0||cnt==1, NULL ); + vproots[i]->Activate( t ); + if( t->is_removed() ) + t->revive( my_scheduler, vproots[i], my_client ); + } + } +#if TBB_USE_ASSERT + req_cnt = --n_add_vp_requests; + __TBB_ASSERT( req_cnt==0, NULL ); +#endif +} + +void thread_map::remove_virtual_processors( IVirtualProcessorRoot** vproots, unsigned count, ::tbb::spin_mutex& mtx ) { + if( my_map.size()==0 ) + return; + tbb::spin_mutex::scoped_lock lck( mtx ); + + if( is_closing() ) return; + + for( unsigned int c=0; c<count; ++c ) { + iterator i = my_map.find( (key_type) vproots[c] ); + if( i==my_map.end() ) { + thread_scavenger_thread* tst = my_thread_scavenger_thread; + if( !tst ) { + // Remove unknown vp from my scheduler; + vproots[c]->Remove( my_scheduler ); + } else { + while( (tst=my_thread_scavenger_thread)==c_claimed ) + __TBB_Yield(); + if( vproots[c]!=tst->get_virtual_processor() ) + vproots[c]->Remove( my_scheduler ); + } + continue; + } + tbb_server_thread* thr = (tbb_server_thread*) (*i).second; + __TBB_ASSERT( thr->tbb_thread, "incorrect type of server_thread" ); + thr->set_removed(); + if( thr->read_state()==ts_asleep ) { + while( thr->activation_count>0 ) { + if( thr->get_virtual_processor()<=c_remove_returned ) + break; + __TBB_Yield(); + } + if( thr->get_virtual_processor()>c_remove_returned ) { + // the thread is in Deactivated state + ++thr->activation_count; + // wake the thread up so that it Switches Out itself. + thr->get_virtual_processor()->Activate( thr ); + } // else, it is Switched Out + } // else the thread will see that it is removed and proceed to switch itself out without Deactivation + } +} + +void thread_map::add_virtual_processors( IVirtualProcessorRoot** vproots, unsigned int count, omp_connection_v2& conn, ::tbb::spin_mutex& mtx ) +{ + std::vector<thread_map::iterator> vec(count); + std::vector<server_thread*> tvec(count); + iterator end; + + { + tbb::spin_mutex::scoped_lock lck( mtx ); + // read the map + end = my_map.end(); //remember 'end' at the time of 'find' + for( size_t i=0; i<count; ++i ) + vec[i] = my_map.find( (key_type) vproots[i] ); + } + + for( size_t i=0; i<count; ++i ) { + __TBB_ASSERT( !tvec[i], NULL ); + if( vec[i]==end ) { + tvec[i] = my_omp_allocator.allocate(1); + new ( tvec[i] ) omp_server_thread( false, my_scheduler, (IExecutionResource*)vproots[i], &conn, *this, my_client ); + } + } + + { + tbb::spin_mutex::scoped_lock lck( mtx ); + + for( size_t i=0; i<count; ++i ) { + if( vec[i]==my_map.end() ) { + thread_map::key_type key = (thread_map::key_type) vproots[i]; + vec[i] = insert( key, tvec[i] ); + my_client_ref_count.add_ref(); + my_server_ref_count.add_ref(); + } + } + + // we could check is_closing() earlier. That requires marking the newly allocated server_thread objects + // that are not inserted into the thread_map, and deallocate them. Doing so seems more cumbersome + // than simply adding these to the thread_map and let thread_map's destructor take care of reclamation. + if( is_closing() ) return; + } + + for( size_t i=0; i<count; ++i ) + vproots[i]->Activate( (*vec[i]).second ); + + { + tbb::spin_mutex::scoped_lock lck( mtx ); + for( size_t i=0; i<count; ++i ) + original_exec_resources.push_back( vproots[i] ); + } +} + +void thread_map::mark_virtual_processors_as_lent( IVirtualProcessorRoot** vproots, unsigned count, ::tbb::spin_mutex& mtx ) { + tbb::spin_mutex::scoped_lock lck( mtx ); + + if( is_closing() ) return; + + iterator end = my_map.end(); + for( unsigned int c=0; c<count; ++c ) { + iterator i = my_map.find( (key_type) vproots[c] ); + if( i==end ) { + // The vproc has not been added to the map in create_oversubscribers() + my_map.insert( unordered_map_type::value_type( (key_type) vproots[c], (server_thread*)1 ) ); + } else { + server_thread* thr = (*i).second; + if( ((uintptr_t)thr)&~(uintptr_t)1 ) { + __TBB_ASSERT( !thr->is_removed(), "incorrectly removed" ); + ((omp_server_thread*)thr)->set_lent(); + } + } + } +} + +void thread_map::create_oversubscribers( unsigned n, std::vector<server_thread*>& thr_vec, omp_connection_v2& conn, ::tbb::spin_mutex& mtx ) { + std::vector<IExecutionResource*> curr_exec_rsc; + { + tbb::spin_mutex::scoped_lock lck( mtx ); + curr_exec_rsc = original_exec_resources; // copy construct + } + typedef std::vector<IExecutionResource*>::iterator iterator_er; + typedef ::std::vector<std::pair<unordered_map_type::key_type, unordered_map_type::mapped_type> > map_val_vector_t; + map_val_vector_t v_vec(n); + iterator_er begin = curr_exec_rsc.begin(); + iterator_er end = curr_exec_rsc.end(); + iterator_er i = begin; + for( unsigned c=0; c<n; ++c ) { + IVirtualProcessorRoot* vpr = my_scheduler_proxy->CreateOversubscriber( *i ); + omp_server_thread* t = new ( my_omp_allocator.allocate(1) ) omp_server_thread( true, my_scheduler, (IExecutionResource*)vpr, &conn, *this, my_client ); + thr_vec[c] = t; + v_vec[c] = unordered_map_type::value_type( (key_type) vpr, t ); + if( ++i==end ) i = begin; + } + + { + tbb::spin_mutex::scoped_lock lck( mtx ); + + if( is_closing() ) return; + + iterator map_end = my_map.end(); + unsigned c = 0; + for( map_val_vector_t::iterator vi=v_vec.begin(); vi!=v_vec.end(); ++vi, ++c ) { + iterator j = my_map.find( (key_type) (*vi).first ); + if( j==map_end ) { + my_map.insert( *vi ); + } else { + // the vproc has not been added to the map in mark_virtual_processors_as_returned(); + uintptr_t lent = (uintptr_t) (*j).second; + __TBB_ASSERT( lent<=1, "vproc map entry added incorrectly?"); + (*j).second = thr_vec[c]; + if( lent ) + ((omp_server_thread*)thr_vec[c])->set_lent(); + else + ((omp_server_thread*)thr_vec[c])->set_returned(); + } + my_client_ref_count.add_ref(); + my_server_ref_count.add_ref(); + } + } +} + +void thread_map::wakeup_tbb_threads( int c, ::tbb::spin_mutex& mtx ) { + std::vector<tbb_server_thread*> vec(c); + + size_t idx = 0; + { + tbb::spin_mutex::scoped_lock lck( mtx ); + + if( is_closing() ) return; + // only one RML thread is in here to wake worker threads up. + + int bal = the_balance; + int cnt = c<bal ? c : bal; + + if( cnt<=0 ) { return; } + + for( iterator i=begin(); i!=end(); ++i ) { + tbb_server_thread* thr = (tbb_server_thread*) (*i).second; + // ConcRT RM should take threads away from TBB scheduler instead of lending them to another scheduler + if( thr->is_removed() ) + continue; + + if( --the_balance>=0 ) { + thread_grab_t res; + while( (res=thr->try_grab_for())!=wk_from_idle ) { + if( res==wk_from_asleep ) { + vec[idx++] = thr; + break; + } else { + thread_state_t s = thr->read_state(); + if( s==ts_busy ) {// failed because already assigned. move on. + ++the_balance; + goto skip; + } + } + } + thread_state_t s = thr->read_state(); + __TBB_ASSERT_EX( s==ts_busy, "should have set the state to ts_busy" ); + if( --cnt==0 ) + break; + } else { + // overdraft + ++the_balance; + break; + } +skip: + ; + } + } + + for( size_t i=0; i<idx; ++i ) { + tbb_server_thread* thr = vec[i]; + __TBB_ASSERT( thr, NULL ); + thread_state_t s = thr->read_state(); + __TBB_ASSERT_EX( s==ts_busy, "should have set the state to ts_busy" ); + ++thr->activation_count; + thr->get_virtual_processor()->Activate( thr ); + } + +} + +void thread_map::mark_virtual_processors_as_returned( IVirtualProcessorRoot** vprocs, unsigned int count, tbb::spin_mutex& mtx ) { + { + tbb::spin_mutex::scoped_lock lck( mtx ); + + if( is_closing() ) return; + + iterator end = my_map.end(); + for(unsigned c=0; c<count; ++c ) { + iterator i = my_map.find( (key_type) vprocs[c] ); + if( i==end ) { + // the vproc has not been added to the map in create_oversubscribers() + my_map.insert( unordered_map_type::value_type( (key_type) vprocs[c], static_cast<server_thread*>(0) ) ); + } else { + omp_server_thread* thr = (omp_server_thread*) (*i).second; + if( ((uintptr_t)thr)&~(uintptr_t)1 ) { + __TBB_ASSERT( !thr->is_removed(), "incorrectly removed" ); + // we should not make any assumption on the initial state of an added vproc. + thr->set_returned(); + } + } + } + } +} + + +void thread_map::unbind( rml::server& /*server*/, tbb::spin_mutex& mtx ) { + { + tbb::spin_mutex::scoped_lock lck( mtx ); + shutdown_in_progress = true; // ignore any callbacks from ConcRT RM + + // Ask each server_thread to cleanup its job for this server. + for( iterator i = begin(); i!=end(); ++i ) { + server_thread* t = (*i).second; + t->terminate = true; + if( t->is_removed() ) { + // This is for TBB only as ConcRT RM does not request OMP schedulers to remove virtual processors + if( t->read_state()==ts_asleep ) { + __TBB_ASSERT( my_thread_scavenger_thread, "this is TBB connection; thread_scavenger_thread must be allocated" ); + // thread is on its way to switch_out; see remove_virtual_processors() where + // the thread is Activated() to bring it back from 'Deactivated' in sleep_perhaps() + // now assume that the thread will go to SwitchOut() +#if TBB_USE_ASSERT + while( t->get_virtual_processor()>c_remove_returned ) + __TBB_Yield(); +#endif + // A removed thread is supposed to proceed to SwithcOut. + // There, we remove client&server references. + } + } else { + if( t->wakeup( ts_done, ts_asleep ) ) { + if( t->tbb_thread ) + ++((tbb_server_thread*)t)->activation_count; + t->get_virtual_processor()->Activate( t ); + // We mark in the thread_map such that when termination sequence started, we ignore + // all notification from ConcRT RM. + } + } + } + } + // Remove extra ref to client. + remove_client_ref(); + + if( my_thread_scavenger_thread ) { + thread_scavenger_thread* tst; + while( (tst=my_thread_scavenger_thread)==c_claimed ) + __TBB_Yield(); +#if TBB_USE_ASSERT + ++my_thread_scavenger_thread->activation_count; +#endif + tst->get_virtual_processor()->Activate( tst ); + } +} + +#if !__RML_REMOVE_VIRTUAL_PROCESSORS_DISABLED +void thread_map::allocate_thread_scavenger( IExecutionResource* v ) +{ + if( my_thread_scavenger_thread>c_claimed ) return; + thread_scavenger_thread* c = my_thread_scavenger_thread.fetch_and_store((thread_scavenger_thread*)c_claimed); + if( c==NULL ) { // successfully claimed + add_server_ref(); +#if TBB_USE_ASSERT + ++n_thread_scavengers_created; +#endif + __TBB_ASSERT( v, NULL ); + IVirtualProcessorRoot* vpr = my_scheduler_proxy->CreateOversubscriber( v ); + my_thread_scavenger_thread = c = new ( my_scavenger_allocator.allocate(1) ) thread_scavenger_thread( my_scheduler, vpr, *this ); +#if TBB_USE_ASSERT + ++c->activation_count; +#endif + vpr->Activate( c ); + } else if( c>c_claimed ) { + my_thread_scavenger_thread = c; + } +} +#endif + +void thread_scavenger_thread::Dispatch( DispatchState* ) +{ + __TBB_ASSERT( my_proxy, NULL ); +#if TBB_USE_ASSERT + --activation_count; +#endif + get_virtual_processor()->Deactivate( this ); + for( thread_map::iterator i=my_thread_map.begin(); i!=my_thread_map.end(); ++i ) { + tbb_server_thread* t = (tbb_server_thread*) (*i).second; + if( t->read_state()==ts_asleep && t->is_removed() ) { + while( t->get_execution_resource()!=c_remove_returned ) + __TBB_Yield(); + my_proxy->SwitchTo( t, Blocking ); + } + } + get_virtual_processor()->Remove( my_scheduler ); + my_thread_map.remove_server_ref(); + // signal to the connection scavenger that i am done with the map. + __TBB_ASSERT( activation_count==1, NULL ); + set_state( ts_done ); +} + +//! Windows "DllMain" that handles startup and shutdown of dynamic library. +extern "C" bool WINAPI DllMain( HINSTANCE /*hinstDLL*/, DWORD fwdReason, LPVOID lpvReserved ) { + void assist_cleanup_connections(); + if( fwdReason==DLL_PROCESS_DETACH ) { + // dll is being unloaded + if( !lpvReserved ) // if FreeLibrary has been called + assist_cleanup_connections(); + } + return true; +} + +void free_all_connections( uintptr_t conn_ex ) { + while( conn_ex ) { + bool is_tbb = (conn_ex&2)>0; + //clear extra bits + uintptr_t curr_conn = conn_ex & ~(uintptr_t)3; + __TBB_ASSERT( curr_conn, NULL ); + + // Wait for worker threads to return + if( is_tbb ) { + tbb_connection_v2* tbb_conn = reinterpret_cast<tbb_connection_v2*>(curr_conn); + conn_ex = reinterpret_cast<uintptr_t>(tbb_conn->next_conn); + while( tbb_conn->my_thread_map.remove_server_ref()>0 ) + __TBB_Yield(); + delete tbb_conn; + } else { + omp_connection_v2* omp_conn = reinterpret_cast<omp_connection_v2*>(curr_conn); + conn_ex = reinterpret_cast<uintptr_t>(omp_conn->next_conn); + while( omp_conn->my_thread_map.remove_server_ref()>0 ) + __TBB_Yield(); + delete omp_conn; + } + } +} + +void assist_cleanup_connections() +{ + //signal to connection_scavenger_thread to terminate + uintptr_t tail = connections_to_reclaim.tail; + while( connections_to_reclaim.tail.compare_and_swap( garbage_connection_queue::plugged, tail )!=tail ) { + __TBB_Yield(); + tail = connections_to_reclaim.tail; + } + + __TBB_ASSERT( connection_scavenger.state==ts_busy || connection_scavenger.state==ts_asleep, NULL ); + // Scavenger thread may be busy freeing connections + DWORD thr_exit_code = STILL_ACTIVE; + while( connection_scavenger.state==ts_busy ) { + if( GetExitCodeThread( connection_scavenger.thr_handle, &thr_exit_code )>0 ) + if( thr_exit_code!=STILL_ACTIVE ) + break; + __TBB_Yield(); + thr_exit_code = STILL_ACTIVE; + } + if( connection_scavenger.state==ts_asleep && thr_exit_code==STILL_ACTIVE ) + connection_scavenger.wakeup(); // wake the connection scavenger thread up + + // it is possible that the connection scavenger thread already exited. Take over its responsibility. + if( tail && connections_to_reclaim.tail!=garbage_connection_queue::plugged_acked ) { + // atomically claim the head of the list. + uintptr_t head = connections_to_reclaim.head.fetch_and_store( garbage_connection_queue::empty ); + if( head==garbage_connection_queue::empty ) + head = tail; + connection_scavenger.process_requests( head ); + } + __TBB_ASSERT( connections_to_reclaim.tail==garbage_connection_queue::plugged||connections_to_reclaim.tail==garbage_connection_queue::plugged_acked, "someone else added a request after termination has initiated" ); + __TBB_ASSERT( (unsigned)the_balance==the_default_concurrency, NULL ); +} + +void connection_scavenger_thread::sleep_perhaps() { + uintptr_t tail = connections_to_reclaim.tail; + // connections_to_reclaim.tail==garbage_connection_queue::plugged --> terminate, + // connections_to_reclaim.tail>garbage_connection_queue::plugged : we got work to do + if( tail>=garbage_connection_queue::plugged ) return; + __TBB_ASSERT( !tail, NULL ); + thread_monitor::cookie c; + monitor.prepare_wait(c); + if( state.compare_and_swap( ts_asleep, ts_busy )==ts_busy ) { + if( connections_to_reclaim.tail!=garbage_connection_queue::plugged ) { + monitor.commit_wait(c); + // Someone else woke me up. The compare_and_swap further below deals with spurious wakeups. + } else { + monitor.cancel_wait(); + } + thread_state_t s = state; + if( s==ts_asleep ) // if spurious wakeup. + state.compare_and_swap( ts_busy, ts_asleep ); + // I woke myself up, either because I cancelled the wait or suffered a spurious wakeup. + } else { + __TBB_ASSERT( false, "someone else tampered with my state" ); + } + __TBB_ASSERT( state==ts_busy, "a thread can only put itself to sleep" ); +} + +void connection_scavenger_thread::process_requests( uintptr_t conn_ex ) +{ + __TBB_ASSERT( conn_ex>1, NULL ); + __TBB_ASSERT( n_scavenger_threads==1||connections_to_reclaim.tail==garbage_connection_queue::plugged, "more than one connection_scavenger_thread being active?" ); + + bool done = false; + while( !done ) { + bool is_tbb = (conn_ex&2)>0; + //clear extra bits + uintptr_t curr_conn = conn_ex & ~(uintptr_t)3; + + // no contention. there is only one connection_scavenger_thread!! + uintptr_t next_conn; + tbb_connection_v2* tbb_conn = NULL; + omp_connection_v2* omp_conn = NULL; + // Wait for worker threads to return + if( is_tbb ) { + tbb_conn = reinterpret_cast<tbb_connection_v2*>(curr_conn); + next_conn = reinterpret_cast<uintptr_t>(tbb_conn->next_conn); + while( tbb_conn->my_thread_map.get_server_ref_count()>1 ) + __TBB_Yield(); + } else { + omp_conn = reinterpret_cast<omp_connection_v2*>(curr_conn); + next_conn = reinterpret_cast<uintptr_t>(omp_conn->next_conn); + while( omp_conn->my_thread_map.get_server_ref_count()>1 ) + __TBB_Yield(); + } + + //someone else may try to write into this connection object. + //So access next_conn field first before remove the extra server ref count. + + if( next_conn==0 ) { + uintptr_t tail = connections_to_reclaim.tail; + if( tail==garbage_connection_queue::plugged ) { + tail = garbage_connection_queue::plugged_acked; // connection scavenger saw the flag, and it freed all connections. + done = true; + } else if( tail==conn_ex ) { + if( connections_to_reclaim.tail.compare_and_swap( garbage_connection_queue::empty, tail )==tail ) { + __TBB_ASSERT( !connections_to_reclaim.head, NULL ); + done = true; + } + } + + if( !done ) { + // A new connection to close is added to connections_to_reclaim.tail; + // Wait for curr_conn->next_conn to be set. + if( is_tbb ) { + while( !tbb_conn->next_conn ) + __TBB_Yield(); + conn_ex = reinterpret_cast<uintptr_t>(tbb_conn->next_conn); + } else { + while( !omp_conn->next_conn ) + __TBB_Yield(); + conn_ex = reinterpret_cast<uintptr_t>(omp_conn->next_conn); + } + } + } else { + conn_ex = next_conn; + } + __TBB_ASSERT( conn_ex, NULL ); + if( is_tbb ) + // remove extra server ref count; this will trigger Shutdown/Release of ConcRT RM + tbb_conn->remove_server_ref(); + else + // remove extra server ref count; this will trigger Shutdown/Release of ConcRT RM + omp_conn->remove_server_ref(); + } +} + +__RML_DECL_THREAD_ROUTINE connection_scavenger_thread::thread_routine( void* arg ) { + connection_scavenger_thread* thr = (connection_scavenger_thread*) arg; + thr->state = ts_busy; + thr->thr_handle = GetCurrentThread(); +#if TBB_USE_ASSERT + ++thr->n_scavenger_threads; +#endif + for(;;) { + __TBB_Yield(); + thr->sleep_perhaps(); + if( connections_to_reclaim.tail==garbage_connection_queue::plugged || connections_to_reclaim.tail==garbage_connection_queue::plugged_acked ) { + thr->state = ts_asleep; + return 0; + } + + __TBB_ASSERT( connections_to_reclaim.tail!=garbage_connection_queue::plugged_acked, NULL ); + __TBB_ASSERT( connections_to_reclaim.tail>garbage_connection_queue::plugged && (connections_to_reclaim.tail&garbage_connection_queue::plugged)==0 , NULL ); + while( connections_to_reclaim.head==garbage_connection_queue::empty ) + __TBB_Yield(); + uintptr_t head = connections_to_reclaim.head.fetch_and_store( garbage_connection_queue::empty ); + thr->process_requests( head ); + wakeup_some_tbb_threads(); + } +} + +template<typename Server, typename Client> +void connection_scavenger_thread::add_request( generic_connection<Server,Client>* conn_to_close ) +{ + uintptr_t conn_ex = (uintptr_t)conn_to_close | (connection_traits<Server,Client>::is_tbb<<1); + __TBB_ASSERT( !conn_to_close->next_conn, NULL ); + const uintptr_t old_tail_ex = connections_to_reclaim.tail.fetch_and_store(conn_ex); + __TBB_ASSERT( old_tail_ex==0||old_tail_ex>garbage_connection_queue::plugged_acked, "Unloading DLL called while this connection is being closed?" ); + + if( old_tail_ex==garbage_connection_queue::empty ) + connections_to_reclaim.head = conn_ex; + else { + bool is_tbb = (old_tail_ex&2)>0; + uintptr_t old_tail = old_tail_ex & ~(uintptr_t)3; + if( is_tbb ) + reinterpret_cast<tbb_connection_v2*>(old_tail)->next_conn = reinterpret_cast<tbb_connection_v2*>(conn_ex); + else + reinterpret_cast<omp_connection_v2*>(old_tail)->next_conn = reinterpret_cast<omp_connection_v2*>(conn_ex); + } + + if( state==ts_asleep ) + wakeup(); +} + +template<> +uintptr_t connection_scavenger_thread::grab_and_prepend( generic_connection<tbb_server,tbb_client>* /*last_conn_to_close*/ ) { return 0;} + +template<> +uintptr_t connection_scavenger_thread::grab_and_prepend( generic_connection<omp_server,omp_client>* last_conn_to_close ) +{ + uintptr_t conn_ex = (uintptr_t)last_conn_to_close; + uintptr_t head = connections_to_reclaim.head.fetch_and_store( garbage_connection_queue::empty ); + reinterpret_cast<omp_connection_v2*>(last_conn_to_close)->next_conn = reinterpret_cast<omp_connection_v2*>(head); + return conn_ex; +} + +extern "C" ULONGLONG NTAPI VerSetConditionMask( ULONGLONG, DWORD, BYTE); + +bool is_windows7_or_later () +{ + try { + return GetOSVersion()>=IResourceManager::Win7OrLater; + } catch( ... ) { + return false; + } +} + +#endif /* RML_USE_WCRM */ + +template<typename Connection, typename Server, typename Client> +static factory::status_type connect( factory& f, Server*& server, Client& client ) { + server = new Connection(*static_cast<wait_counter*>(f.scratch_ptr),client); + return factory::st_success; +} + +void init_rml_module () { + the_balance = the_default_concurrency = tbb::internal::AvailableHwConcurrency() - 1; +#if RML_USE_WCRM + connection_scavenger.launch(); +#endif +} + +extern "C" factory::status_type __RML_open_factory( factory& f, version_type& server_version, version_type client_version ) { + // Hack to keep this library from being closed by causing the first client's dlopen to not have a corresponding dlclose. + // This code will be removed once we figure out how to do shutdown of the RML perfectly. + static tbb::atomic<bool> one_time_flag; + if( one_time_flag.compare_and_swap(true,false)==false) { + __TBB_ASSERT( (size_t)f.library_handle!=factory::c_dont_unload, NULL ); +#if _WIN32||_WIN64 + f.library_handle = reinterpret_cast<HMODULE>(factory::c_dont_unload); +#else + f.library_handle = reinterpret_cast<void*>(factory::c_dont_unload); +#endif + } + // End of hack + + // Initialize the_balance only once + tbb::internal::atomic_do_once ( &init_rml_module, rml_module_state ); + + server_version = SERVER_VERSION; + f.scratch_ptr = 0; + if( client_version==0 ) { + return factory::st_incompatible; +#if RML_USE_WCRM + } else if ( !is_windows7_or_later() ) { +#if TBB_USE_DEBUG + fprintf(stderr, "This version of the RML library requires Windows 7 to run on.\nConnection request denied.\n"); +#endif + return factory::st_incompatible; +#endif + } else { +#if TBB_USE_DEBUG + if( client_version<EARLIEST_COMPATIBLE_CLIENT_VERSION ) + fprintf(stderr, "This client library is too old for the current RML server.\nThe connection request is granted but oversubscription/undersubscription may occur.\n"); +#endif + f.scratch_ptr = new wait_counter; + return factory::st_success; + } +} + +extern "C" void __RML_close_factory( factory& f ) { + if( wait_counter* fc = static_cast<wait_counter*>(f.scratch_ptr) ) { + f.scratch_ptr = 0; + fc->wait(); + size_t bal = the_balance; + f.scratch_ptr = (void*)bal; + delete fc; + } +} + +void call_with_build_date_str( ::rml::server_info_callback_t cb, void* arg ); + +}} // rml::internal + +namespace tbb { +namespace internal { +namespace rml { + +extern "C" tbb_factory::status_type __TBB_make_rml_server( tbb_factory& f, tbb_server*& server, tbb_client& client ) { + return ::rml::internal::connect< ::rml::internal::tbb_connection_v2>(f,server,client); +} + +extern "C" void __TBB_call_with_my_server_info( ::rml::server_info_callback_t cb, void* arg ) { + return ::rml::internal::call_with_build_date_str( cb, arg ); +} + +}}} + +namespace __kmp { +namespace rml { + +extern "C" omp_factory::status_type __KMP_make_rml_server( omp_factory& f, omp_server*& server, omp_client& client ) { + return ::rml::internal::connect< ::rml::internal::omp_connection_v2>(f,server,client); +} + +extern "C" void __KMP_call_with_my_server_info( ::rml::server_info_callback_t cb, void* arg ) { + return ::rml::internal::call_with_build_date_str( cb, arg ); +} + +}} + +/* + * RML server info + */ +#include "version_string.ver" + +#ifndef __TBB_VERSION_STRINGS +#pragma message("Warning: version_string.ver isn't generated properly by version_info.sh script!") +#endif + +// We use the build time as the RML server info. TBB is required to build RML, so we make it the same as the TBB build time. +#ifndef __TBB_DATETIME +#define __TBB_DATETIME __DATE__ " " __TIME__ +#endif + +#if !RML_USE_WCRM +#define RML_SERVER_BUILD_TIME "Intel(R) RML library built: " __TBB_DATETIME +#define RML_SERVER_VERSION_ST "Intel(R) RML library version: v" TOSTRING(SERVER_VERSION) +#else +#define RML_SERVER_BUILD_TIME "Intel(R) RML library built: " __TBB_DATETIME +#define RML_SERVER_VERSION_ST "Intel(R) RML library version: v" TOSTRING(SERVER_VERSION) " on ConcRT RM with " RML_THREAD_KIND_STRING +#endif + +namespace rml { +namespace internal { + +void call_with_build_date_str( ::rml::server_info_callback_t cb, void* arg ) +{ + (*cb)( arg, RML_SERVER_BUILD_TIME ); + (*cb)( arg, RML_SERVER_VERSION_ST ); +} +}} // rml::internal diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/thread_monitor.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/thread_monitor.h new file mode 100644 index 00000000..5793cb2b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/thread_monitor.h @@ -0,0 +1,268 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// All platform-specific threading support is encapsulated here. */ + +#ifndef __RML_thread_monitor_H +#define __RML_thread_monitor_H + +#if USE_WINTHREAD +#include <windows.h> +#include <process.h> +#include <malloc.h> //_alloca +#include "tbb/tbb_misc.h" // support for processor groups +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) +#include <thread> +#endif +#elif USE_PTHREAD +#include <pthread.h> +#include <string.h> +#include <stdlib.h> +#else +#error Unsupported platform +#endif +#include <stdio.h> +#include "tbb/itt_notify.h" +#include "tbb/atomic.h" +#include "tbb/semaphore.h" + +// All platform-specific threading support is in this header. + +#if (_WIN32||_WIN64)&&!__TBB_ipf +// Deal with 64K aliasing. The formula for "offset" is a Fibonacci hash function, +// which has the desirable feature of spreading out the offsets fairly evenly +// without knowing the total number of offsets, and furthermore unlikely to +// accidentally cancel out other 64K aliasing schemes that Microsoft might implement later. +// See Knuth Vol 3. "Theorem S" for details on Fibonacci hashing. +// The second statement is really does need "volatile", otherwise the compiler might remove the _alloca. +#define AVOID_64K_ALIASING(idx) \ + size_t offset = (idx+1) * 40503U % (1U<<16); \ + void* volatile sink_for_alloca = _alloca(offset); \ + __TBB_ASSERT_EX(sink_for_alloca, "_alloca failed"); +#else +// Linux thread allocators avoid 64K aliasing. +#define AVOID_64K_ALIASING(idx) tbb::internal::suppress_unused_warning(idx) +#endif /* _WIN32||_WIN64 */ + +namespace rml { + +namespace internal { + +#if DO_ITT_NOTIFY +static const ::tbb::tchar *SyncType_RML = _T("%Constant"); +static const ::tbb::tchar *SyncObj_ThreadMonitor = _T("RML Thr Monitor"); +#endif /* DO_ITT_NOTIFY */ + +//! Monitor with limited two-phase commit form of wait. +/** At most one thread should wait on an instance at a time. */ +class thread_monitor { +public: + class cookie { + friend class thread_monitor; + tbb::atomic<size_t> my_epoch; + }; + thread_monitor() : skipped_wakeup(false), my_sema() { + my_cookie.my_epoch = 0; + ITT_SYNC_CREATE(&my_sema, SyncType_RML, SyncObj_ThreadMonitor); + in_wait = false; + } + ~thread_monitor() {} + + //! If a thread is waiting or started a two-phase wait, notify it. + /** Can be called by any thread. */ + void notify(); + + //! Begin two-phase wait. + /** Should only be called by thread that owns the monitor. + The caller must either complete the wait or cancel it. */ + void prepare_wait( cookie& c ); + + //! Complete a two-phase wait and wait until notification occurs after the earlier prepare_wait. + void commit_wait( cookie& c ); + + //! Cancel a two-phase wait. + void cancel_wait(); + +#if USE_WINTHREAD + typedef HANDLE handle_type; + + #define __RML_DECL_THREAD_ROUTINE unsigned WINAPI + typedef unsigned (WINAPI *thread_routine_type)(void*); + + //! Launch a thread + static handle_type launch( thread_routine_type thread_routine, void* arg, size_t stack_size, const size_t* worker_index = NULL ); + +#elif USE_PTHREAD + typedef pthread_t handle_type; + + #define __RML_DECL_THREAD_ROUTINE void* + typedef void*(*thread_routine_type)(void*); + + //! Launch a thread + static handle_type launch( thread_routine_type thread_routine, void* arg, size_t stack_size ); +#endif /* USE_PTHREAD */ + + //! Yield control to OS + /** Affects the calling thread. **/ + static void yield(); + + //! Join thread + static void join(handle_type handle); + + //! Detach thread + static void detach_thread(handle_type handle); +private: + cookie my_cookie; // epoch counter + tbb::atomic<bool> in_wait; + bool skipped_wakeup; + tbb::internal::binary_semaphore my_sema; +#if USE_PTHREAD + static void check( int error_code, const char* routine ); +#endif +}; + +#if USE_WINTHREAD + +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION +#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 +#endif + +// _beginthreadex API is not available in Windows 8 Store* applications, so use std::thread instead +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) +inline thread_monitor::handle_type thread_monitor::launch( thread_routine_type thread_function, void* arg, size_t, const size_t*) { +//TODO: check that exception thrown from std::thread is not swallowed silently + std::thread* thread_tmp=new std::thread(thread_function, arg); + return thread_tmp->native_handle(); +} +#else +inline thread_monitor::handle_type thread_monitor::launch( thread_routine_type thread_routine, void* arg, size_t stack_size, const size_t* worker_index ) { + unsigned thread_id; + int number_of_processor_groups = ( worker_index ) ? tbb::internal::NumberOfProcessorGroups() : 0; + unsigned create_flags = ( number_of_processor_groups > 1 ) ? CREATE_SUSPENDED : 0; + HANDLE h = (HANDLE)_beginthreadex( NULL, unsigned(stack_size), thread_routine, arg, STACK_SIZE_PARAM_IS_A_RESERVATION | create_flags, &thread_id ); + if( !h ) { + fprintf(stderr,"thread_monitor::launch: _beginthreadex failed\n"); + exit(1); + } + if ( number_of_processor_groups > 1 ) { + tbb::internal::MoveThreadIntoProcessorGroup( h, + tbb::internal::FindProcessorGroupIndex( static_cast<int>(*worker_index) ) ); + ResumeThread( h ); + } + return h; +} +#endif //__TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) + +void thread_monitor::join(handle_type handle) { +#if TBB_USE_ASSERT + DWORD res = +#endif + WaitForSingleObjectEx(handle, INFINITE, FALSE); + __TBB_ASSERT( res==WAIT_OBJECT_0, NULL ); +#if TBB_USE_ASSERT + BOOL val = +#endif + CloseHandle(handle); + __TBB_ASSERT( val, NULL ); +} + +void thread_monitor::detach_thread(handle_type handle) { +#if TBB_USE_ASSERT + BOOL val = +#endif + CloseHandle(handle); + __TBB_ASSERT( val, NULL ); +} + +inline void thread_monitor::yield() { +// TODO: consider unification via __TBB_Yield or tbb::this_tbb_thread::yield +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) + std::this_thread::yield(); +#else + SwitchToThread(); +#endif +} +#endif /* USE_WINTHREAD */ + +#if USE_PTHREAD +// TODO: can we throw exceptions instead of termination? +inline void thread_monitor::check( int error_code, const char* routine ) { + if( error_code ) { + fprintf(stderr,"thread_monitor %s in %s\n", strerror(error_code), routine ); + exit(1); + } +} + +inline thread_monitor::handle_type thread_monitor::launch( void* (*thread_routine)(void*), void* arg, size_t stack_size ) { + // FIXME - consider more graceful recovery than just exiting if a thread cannot be launched. + // Note that there are some tricky situations to deal with, such that the thread is already + // grabbed as part of an OpenMP team. + pthread_attr_t s; + check(pthread_attr_init( &s ), "pthread_attr_init"); + if( stack_size>0 ) + check(pthread_attr_setstacksize( &s, stack_size ), "pthread_attr_setstack_size" ); + pthread_t handle; + check( pthread_create( &handle, &s, thread_routine, arg ), "pthread_create" ); + check( pthread_attr_destroy( &s ), "pthread_attr_destroy" ); + return handle; +} + +void thread_monitor::join(handle_type handle) { + check(pthread_join(handle, NULL), "pthread_join"); +} + +void thread_monitor::detach_thread(handle_type handle) { + check(pthread_detach(handle), "pthread_detach"); +} + +inline void thread_monitor::yield() { + sched_yield(); +} +#endif /* USE_PTHREAD */ + +inline void thread_monitor::notify() { + my_cookie.my_epoch = my_cookie.my_epoch + 1; + bool do_signal = in_wait.fetch_and_store( false ); + if( do_signal ) + my_sema.V(); +} + +inline void thread_monitor::prepare_wait( cookie& c ) { + if( skipped_wakeup ) { + // Lazily consume a signal that was skipped due to cancel_wait + skipped_wakeup = false; + my_sema.P(); // does not really wait on the semaphore + } + c = my_cookie; + in_wait.store<tbb::full_fence>( true ); +} + +inline void thread_monitor::commit_wait( cookie& c ) { + bool do_it = ( c.my_epoch == my_cookie.my_epoch ); + if( do_it ) my_sema.P(); + else cancel_wait(); +} + +inline void thread_monitor::cancel_wait() { + // if not in_wait, then some thread has sent us a signal; + // it will be consumed by the next prepare_wait call + skipped_wakeup = ! in_wait.fetch_and_store( false ); +} + +} // namespace internal +} // namespace rml + +#endif /* __RML_thread_monitor_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/wait_counter.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/wait_counter.h new file mode 100644 index 00000000..df0535f9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/wait_counter.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __RML_wait_counter_H +#define __RML_wait_counter_H + +#include "thread_monitor.h" +#include "tbb/atomic.h" + +namespace rml { +namespace internal { + +class wait_counter { + thread_monitor my_monitor; + tbb::atomic<int> my_count; + tbb::atomic<int> n_transients; +public: + wait_counter() { + // The "1" here is subtracted by the call to "wait". + my_count=1; + n_transients=0; + } + + //! Wait for number of operator-- invocations to match number of operator++ invocations. + /** Exactly one thread should call this method. */ + void wait() { + int k = --my_count; + __TBB_ASSERT( k>=0, "counter underflow" ); + if( k>0 ) { + thread_monitor::cookie c; + my_monitor.prepare_wait(c); + if( my_count ) + my_monitor.commit_wait(c); + else + my_monitor.cancel_wait(); + } + while( n_transients>0 ) + __TBB_Yield(); + } + void operator++() { + ++my_count; + } + void operator--() { + ++n_transients; + int k = --my_count; + __TBB_ASSERT( k>=0, "counter underflow" ); + if( k==0 ) + my_monitor.notify(); + --n_transients; + } +}; + +} // namespace internal +} // namespace rml + +#endif /* __RML_wait_counter_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/win32-rml-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/win32-rml-export.def new file mode 100644 index 00000000..9723cca0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/win32-rml-export.def @@ -0,0 +1,23 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +EXPORTS + +__RML_open_factory +__RML_close_factory +__TBB_make_rml_server +__KMP_make_rml_server +__TBB_call_with_my_server_info +__KMP_call_with_my_server_info + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/win64-rml-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/win64-rml-export.def new file mode 100644 index 00000000..9723cca0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/server/win64-rml-export.def @@ -0,0 +1,23 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +EXPORTS + +__RML_open_factory +__RML_close_factory +__TBB_make_rml_server +__KMP_make_rml_server +__TBB_call_with_my_server_info +__KMP_call_with_my_server_info + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/rml_omp_stub.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/rml_omp_stub.cpp new file mode 100644 index 00000000..8a24ceb2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/rml_omp_stub.cpp @@ -0,0 +1,68 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// This file is compiled with C++, but linked with a program written in C. +// The intent is to find dependencies on the C++ run-time. + +#include <stdlib.h> +#include "../../../include/tbb/tbb_stddef.h" // __TBB_override +#include "harness_defs.h" +#define RML_PURE_VIRTUAL_HANDLER abort + +#if _MSC_VER==1500 && !defined(__INTEL_COMPILER) +// VS2008/VC9 seems to have an issue; +#pragma warning( push ) +#pragma warning( disable: 4100 ) +#elif __TBB_MSVC_UNREACHABLE_CODE_IGNORED +// VS2012-2013 issues "warning C4702: unreachable code" for the code which really +// shouldn't be reached according to the test logic: rml::client has the +// implementation for the "pure" virtual methods to be aborted if they are +// called. +#pragma warning( push ) +#pragma warning( disable: 4702 ) +#endif +#include "rml_omp.h" +#if ( _MSC_VER==1500 && !defined(__INTEL_COMPILER)) || __TBB_MSVC_UNREACHABLE_CODE_IGNORED +#pragma warning( pop ) +#endif + +rml::versioned_object::version_type Version; + +class MyClient: public __kmp::rml::omp_client { +public: + rml::versioned_object::version_type version() const __TBB_override {return 0;} + size_type max_job_count() const __TBB_override {return 1024;} + size_t min_stack_size() const __TBB_override {return 1<<20;} + rml::job* create_one_job() __TBB_override {return NULL;} + void acknowledge_close_connection() __TBB_override {} + void cleanup(job&) __TBB_override {} + policy_type policy() const __TBB_override {return throughput;} + void process( job&, void*, __kmp::rml::omp_client::size_type ) __TBB_override {} + +}; + +//! Never actually set, because point of test is to find linkage issues. +__kmp::rml::omp_server* MyServerPtr; + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#define HARNESS_CUSTOM_MAIN 1 +#include "harness.h" + +extern "C" void Cplusplus() { + MyClient client; + Version = client.version(); + REPORT("done\n"); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_job_automaton.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_job_automaton.cpp new file mode 100644 index 00000000..06b7acaf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_job_automaton.cpp @@ -0,0 +1,148 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness.h" +#if __TBB_MIC_OFFLOAD +int TestMain () { + return Harness::Skipped; +} +#else +#include "job_automaton.h" +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness_barrier.h" + +class State { + Harness::SpinBarrier barrier; + rml::internal::job_automaton ja; + rml::job job; + tbb::atomic<int> job_created; + tbb::atomic<int> job_destroyed; + tbb::atomic<bool> job_received; +public: + State() : barrier(2) { + job_created = 0; + job_destroyed = 0; + job_received = false; + } + void exercise( bool is_owner ); + ~State() { + ASSERT( job_created==job_destroyed, "accounting error" ); + ASSERT( job_destroyed<=1, "destroyed job twice" ); + } +}; + +int DelayMask; +const int N = 14; +tbb::atomic<int> Coverage[N]; + +//! Mark kth interval as covered and insert delay if kth bit of DelayMask is set. +/** An interval is the code between two operations on the job_automaton that we are testing. */ +void Cover( int k ) { + ASSERT( k<N, NULL ); + ++Coverage[k]; + if( DelayMask>>k&1 ) { + // Introduce delay (and possibly a thread context switch) + __TBB_Yield(); + } +} + +void State::exercise( bool is_owner ) { + barrier.wait(); + if( is_owner ) { + Cover(0); + if( ja.try_acquire() ) { + Cover(1); + ++job_created; + ja.set_and_release(&job); + Cover(2); + if( ja.try_acquire() ) { + Cover(3); + ja.release(); + Cover(4); + if( ja.try_acquire() ) { + Cover(5); + ja.release(); + } + } + Cover(6); + } else { + Cover(7); + } + if( DelayMask&1<<N ) { + while( !job_received ) + __TBB_Yield(); + } + } else { + // Using extra bit of DelayMask for choosing whether to run wait_for_job or not. + if( DelayMask&1<<N ) { + rml::job* j= ja.wait_for_job(); + if( j!=&job ) REPORT("%p\n",j); + ASSERT( j==&job, NULL ); + job_received = true; + } + Cover(8); + } + rml::job* j; + if( ja.try_plug(j) ) { + ASSERT( j==&job || !j, NULL ); + if( j ) { + Cover(9+is_owner); + ++job_destroyed; + } else { + __TBB_ASSERT( !is_owner, "owner failed to create job but plugged self" ); + Cover(11); + } + } else { + Cover(12+is_owner); + } +} + +class Loop: NoAssign { + State& s; +public: + Loop(State& s_) : s(s_) {} + void operator()( int i ) const {s.exercise(i==0);} +}; + +/** Return true if coverage is acceptable. + If report==true, issue message if it is unacceptable. */ +bool CheckCoverage( bool report ) { + bool okay = true; + for( int i=0; i<N; ++i ) { + const int min_coverage = 4; + if( Coverage[i]<min_coverage ) { + okay = false; + if( report ) + REPORT("Warning: Coverage[%d]=%d is less than acceptable minimum of %d\n", i, int(Coverage[i]),min_coverage); + } + } + return okay; +} + +int TestMain () { + for( DelayMask=0; DelayMask<8<<N; ++DelayMask ) { + State s; + NativeParallelFor( 2, Loop(s) ); + if( CheckCoverage(false) ) { + // Reached acceptable code coverage level + break; + } + } + CheckCoverage(true); + return Harness::Done; +} + +#endif /* __TBB_MIC_OFFLOAD */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_mixed.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_mixed.cpp new file mode 100644 index 00000000..f54c20d5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_mixed.cpp @@ -0,0 +1,314 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <tbb/tbb_config.h> +#if __TBB_WIN8UI_SUPPORT || __TBB_MIC_OFFLOAD +#include "harness.h" +int TestMain () { + return Harness::Skipped; +} +#else +#include "rml_tbb.h" +#include "rml_omp.h" +#include "tbb/atomic.h" +#include "tbb/tick_count.h" + +#define HARNESS_DEFAULT_MIN_THREADS 4 +#include "harness.h" + +// dynamic_link initializes its data structures in a static constructor. But +// the initialization order of static constructors in different modules is +// non-deterministic. Thus dynamic_link fails on some systems when the +// application changes its current directory after the library (TBB/OpenMP/...) +// is loaded but before the static constructors in the library are executed. +#define CHDIR_SUPPORT_BROKEN ( __TBB_GCC_VERSION >= 40600 || (__linux__ && __TBB_CLANG_VERSION >= 30500) ) + +const int OMP_ParallelRegionSize = 16; +int TBB_MaxThread = 4; // Includes master +int OMP_MaxThread = int(~0u>>1); // Includes master + +template<typename Client> +class ClientBase: public Client { +protected: + typedef typename Client::version_type version_type; + typedef typename Client::job job; + typedef typename Client::policy_type policy_type; + +private: + version_type version() const __TBB_override { + return 0; + } + size_t min_stack_size() const __TBB_override { + return 1<<20; + } + job* create_one_job() __TBB_override { + return new rml::job; + } + policy_type policy() const __TBB_override { + return Client::turnaround; + } + void acknowledge_close_connection() __TBB_override { + delete this; + } + void cleanup( job& j ) __TBB_override {delete &j;} + +public: + virtual ~ClientBase() {} +}; + +#if _WIN32 +#include <direct.h> +#define PATH_LEN MAX_PATH+1 +#define SLASH '\\' +#define ROOT_DIR "\\" +// ROOT_DIR_REST means how many symbols before first slash in the path +#define ROOT_DIR_REST 2 +#else +#include <unistd.h> +#include <limits.h> +#define PATH_LEN PATH_MAX+1 +#define SLASH '/' +#define ROOT_DIR "/" +// ROOT_DIR_REST means how many symbols before first slash in the path +#define ROOT_DIR_REST 0 +#define _getcwd getcwd +#define _chdir chdir +#endif + +#if !CHDIR_SUPPORT_BROKEN +class ChangeCurrentDir { + char dir[PATH_LEN+1]; + char *last_slash; +public: + ChangeCurrentDir() { + if ( !_getcwd( dir, PATH_LEN ) ) { + REPORT_FATAL_ERROR("ERROR: Couldn't get current working directory\n"); + } + + last_slash = strrchr( dir, SLASH ); + ASSERT( last_slash, "The current directory doesn't contain slashes" ); + *last_slash = 0; + + if ( _chdir( last_slash-dir == ROOT_DIR_REST ? ROOT_DIR : dir ) ) { + REPORT_FATAL_ERROR("ERROR: Couldn't change current working directory (%s)\n", dir ); + } + } + + // Restore current dir + ~ChangeCurrentDir() { + *last_slash = SLASH; + if ( _chdir(dir) ) { + REPORT_FATAL_ERROR("ERROR: Couldn't change current working directory\n"); + } + } +}; +#endif + +//! Represents a TBB or OpenMP run-time that uses RML. +template<typename Factory, typename Client> +class RunTime { +public: + //! Factory that run-time uses to make servers. + Factory factory; + Client* client; + typename Factory::server_type* server; +#if _WIN32||_WIN64 + ::rml::server::execution_resource_t me; +#endif + RunTime() { + factory.open(); + } + ~RunTime() { + factory.close(); + } + //! Create server for this run-time + void create_connection(); + + //! Destroy server for this run-time + void destroy_connection(); +}; + +class ThreadLevelRecorder { + tbb::atomic<int> level; + struct record { + tbb::tick_count time; + int nthread; + }; + tbb::atomic<unsigned> next; + /** Must be power of two */ + static const unsigned max_record_count = 1<<20; + record array[max_record_count]; +public: + void change_level( int delta ); + void dump(); +}; + +void ThreadLevelRecorder::change_level( int delta ) { + int x = level+=delta; + tbb::tick_count t = tbb::tick_count::now(); + unsigned k = next++; + if( k<max_record_count ) { + record& r = array[k]; + r.time = t; + r.nthread = x; + } +} + +void ThreadLevelRecorder::dump() { + FILE* f = fopen("time.txt","w"); + if( !f ) { + perror("fopen(time.txt)\n"); + exit(1); + } + unsigned limit = next; + if( limit>max_record_count ) { + // Clip + limit = next; + } + for( unsigned i=0; i<limit; ++i ) { + fprintf(f,"%f\t%d\n",(array[i].time-array[0].time).seconds(),array[i].nthread); + } + fclose(f); +} + +class TBB_Client: public ClientBase<tbb::internal::rml::tbb_client> { + void process( job& j ) __TBB_override; + size_type max_job_count() const __TBB_override { + return TBB_MaxThread-1; + } +}; + +class OMP_Client: public ClientBase<__kmp::rml::omp_client> { + void process( job&, void* cookie, omp_client::size_type ) __TBB_override; + size_type max_job_count() const __TBB_override { + return OMP_MaxThread-1; + } +}; + +#if !CHDIR_SUPPORT_BROKEN +// A global instance of ChangeCurrentDir should be declared before TBB_RunTime and OMP_RunTime +// since we want to change current directory before opening factory +ChangeCurrentDir Changer; +#endif +RunTime<tbb::internal::rml::tbb_factory, TBB_Client> TBB_RunTime; +RunTime<__kmp::rml::omp_factory, OMP_Client> OMP_RunTime; +ThreadLevelRecorder TotalThreadLevel; + +template<typename Factory, typename Client> +void RunTime<Factory,Client>::create_connection() { + client = new Client; + typename Factory::status_type status = factory.make_server( server, *client ); + ASSERT( status==Factory::st_success, NULL ); +#if _WIN32||_WIN64 + server->register_master( me ); +#endif /* _WIN32||_WIN64 */ +} + +template<typename Factory, typename Client> +void RunTime<Factory,Client>::destroy_connection() { +#if _WIN32||_WIN64 + server->unregister_master( me ); +#endif /* _WIN32||_WIN64 */ + server->request_close_connection(); + server = NULL; +} + +class OMP_Team { +public: + OMP_Team( __kmp::rml::omp_server& ) {} + tbb::atomic<unsigned> barrier; +}; + +tbb::atomic<int> AvailWork; +tbb::atomic<int> CompletionCount; + +void OMPWork() { + tbb::atomic<int> x; + for( x=0; x<2000000; ++x ) { + continue; + } +} + +void TBBWork() { + if( AvailWork>=0 ) { + int k = --AvailWork; + if( k==-1 ) { + TBB_RunTime.server->adjust_job_count_estimate(-(TBB_MaxThread-1)); + ++CompletionCount; + } else if( k>=0 ) { + for( int j=0; j<4; ++j ) { + OMP_Team team( *OMP_RunTime.server ); + int n = OMP_RunTime.server->try_increase_load( OMP_ParallelRegionSize-1, /*strict=*/false ); + team.barrier = 0; + ::rml::job* array[OMP_ParallelRegionSize-1]; + if( n>0) + OMP_RunTime.server->get_threads( n, &team, array ); + // Master does work inside parallel region too. + OMPWork(); + // Master waits for workers to finish + if( n>0 ) + while( team.barrier!=unsigned(n) ) { + __TBB_Yield(); + } + } + ++CompletionCount; + } + } +} + +void TBB_Client::process( job& ) { + TotalThreadLevel.change_level(1); + TBBWork(); + TotalThreadLevel.change_level(-1); +} + +void OMP_Client::process( job& /* j */, void* cookie, omp_client::size_type ) { + TotalThreadLevel.change_level(1); + ASSERT( OMP_RunTime.server, NULL ); + OMPWork(); + ASSERT( OMP_RunTime.server, NULL ); + static_cast<OMP_Team*>(cookie)->barrier+=1; + TotalThreadLevel.change_level(-1); +} + +void TBBOutSideOpenMPInside() { + TotalThreadLevel.change_level(1); + CompletionCount = 0; + int tbbtasks = 32; + AvailWork = tbbtasks; + TBB_RunTime.server->adjust_job_count_estimate(TBB_MaxThread-1); + while( CompletionCount!=tbbtasks+1 ) { + TBBWork(); + } + TotalThreadLevel.change_level(-1); +} + +int TestMain () { +#if CHDIR_SUPPORT_BROKEN + REPORT("Known issue: dynamic_link does not support current directory changing before its initialization.\n"); +#endif + for( TBB_MaxThread=MinThread; TBB_MaxThread<=MaxThread; ++TBB_MaxThread ) { + REMARK("Testing with TBB_MaxThread=%d\n", TBB_MaxThread); + TBB_RunTime.create_connection(); + OMP_RunTime.create_connection(); + TBBOutSideOpenMPInside(); + OMP_RunTime.destroy_connection(); + TBB_RunTime.destroy_connection(); + } + TotalThreadLevel.dump(); + return Harness::Done; +} +#endif /* __TBB_WIN8UI_SUPPORT || __TBB_MIC_OFFLOAD */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_omp.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_omp.cpp new file mode 100644 index 00000000..daa91e5c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_omp.cpp @@ -0,0 +1,199 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <tbb/tbb_config.h> +#if __TBB_WIN8UI_SUPPORT || __TBB_MIC_OFFLOAD +#include "harness.h" +int TestMain () { + return Harness::Skipped; +} +#else +#include "rml_omp.h" + +typedef __kmp::rml::omp_server MyServer; +typedef __kmp::rml::omp_factory MyFactory; + +// Forward declaration for the function used in test_server.h +void DoClientSpecificVerification( MyServer& , int ); + +#define HARNESS_DEFAULT_MIN_THREADS 0 +#include "test_server.h" +#include "tbb/tbb_misc.h" + +static bool StrictTeam; + +class MyTeam { + MyTeam& operator=( const MyTeam& ) ; +public: + struct info_type { + rml::job* job; + bool ran; + info_type() : job(NULL), ran(false) {} + }; + MyTeam( MyServer& /* server */, size_t max_thread_ ) : + max_thread(max_thread_) + { + self_ptr = this; + info = new info_type[max_thread]; + } + ~MyTeam() { + delete[] info; + } + const size_t max_thread; + size_t n_thread; + tbb::atomic<int> barrier; + /** Indexed with 1-origin index */ + info_type* info; + int iteration; + MyTeam* self_ptr; +}; + +class MyClient: public ClientBase<__kmp::rml::omp_client> { +public: + MyServer* server; + void process( job& j, void* cookie, size_type index ) __TBB_override { + MyTeam& t = *static_cast<MyTeam*>(cookie); + ASSERT( t.self_ptr==&t, "trashed cookie" ); + ASSERT( index<t.max_thread, NULL ); + ASSERT( !t.info[index].ran, "duplicate index?" ); + t.info[index].job = &j; + t.info[index].ran = true; + do_process(&j); + if( index==1 && nesting.level<nesting.limit ) { + DoOneConnection<MyFactory,MyClient> doc(MaxThread,Nesting(nesting.level+1,nesting.limit),0,false); + doc(0); + } +#if _WIN32||_WIN64 + // test activate/deactivate + if( t.n_thread>1 && t.n_thread%2==0 ) { + if( nesting.level==0 ) { + if( index&1 ) { + size_type target = index-1; + ASSERT( target<t.max_thread, NULL ); + // wait until t.info[target].job is defined + tbb::internal::spin_wait_until_eq( t.info[target].ran, true ); + server->try_increase_load( 1, true ); + server->reactivate( t.info[target].job ); + } else { + server->deactivate( &j ); + } + } + } +#endif /* _WIN32||_WIN64 */ + ++t.barrier; + } + static const bool is_omp = true; + bool is_strict() const {return StrictTeam;} +}; + +void FireUpJobs( MyServer& server, MyClient& client, int max_thread, int n_extra, Checker* checker ) { + ASSERT( max_thread>=0, NULL ); +#if _WIN32||_WIN64 + ::rml::server::execution_resource_t me; + server.register_master( me ); +#endif /* _WIN32||_WIN64 */ + client.server = &server; + MyTeam team(server,size_t(max_thread)); + MyServer::size_type n_thread = 0; + for( int iteration=0; iteration<4; ++iteration ) { + for( size_t i=0; i<team.max_thread; ++i ) + team.info[i].ran = false; + switch( iteration ) { + default: + n_thread = int(max_thread); + break; + case 1: + // No change in number of threads + break; + case 2: + // Decrease number of threads. + n_thread = int(max_thread)/2; + break; + // Case 3 is same code as the default, but has effect of increasing the number of threads. + } + team.barrier = 0; + REMARK("client %d: server.run with n_thread=%d\n", client.client_id(), int(n_thread) ); + server.independent_thread_number_changed( n_extra ); + if( checker ) { + // Give RML time to respond to change in number of threads. + Harness::Sleep(1); + } + int n_delivered = server.try_increase_load( n_thread, StrictTeam ); + ASSERT( !StrictTeam || n_delivered==int(n_thread), "server failed to satisfy strict request" ); + if( n_delivered<0 ) { + REMARK( "client %d: oversubscription occurred (by %d)\n", client.client_id(), -n_delivered ); + server.independent_thread_number_changed( -n_extra ); + n_delivered = 0; + } else { + team.n_thread = n_delivered; + ::rml::job* job_array[JobArraySize]; + job_array[n_delivered] = (::rml::job*)intptr_t(-1); + server.get_threads( n_delivered, &team, job_array ); + __TBB_ASSERT( job_array[n_delivered]== (::rml::job*)intptr_t(-1), NULL ); + for( int i=0; i<n_delivered; ++i ) { + MyJob* j = static_cast<MyJob*>(job_array[i]); + int s = j->state; + ASSERT( s==MyJob::idle||s==MyJob::busy, NULL ); + } + server.independent_thread_number_changed( -n_extra ); + REMARK("client %d: team size is %d\n", client.client_id(), n_delivered); + if( checker ) { + checker->check_number_of_threads_delivered( n_delivered, n_thread, n_extra ); + } + // Protocol requires that master wait until workers have called "done_processing" + while( team.barrier!=n_delivered ) { + ASSERT( team.barrier>=0, NULL ); + ASSERT( team.barrier<=n_delivered, NULL ); + __TBB_Yield(); + } + REMARK("client %d: team completed\n", client.client_id() ); + for( int i=0; i<n_delivered; ++i ) { + ASSERT( team.info[i].ran, "thread on team allegedly delivered, but did not run?" ); + } + } + for( MyServer::size_type i=n_delivered; i<MyServer::size_type(max_thread); ++i ) { + ASSERT( !team.info[i].ran, "thread on team ran with illegal index" ); + } + } +#if _WIN32||_WIN64 + server.unregister_master( me ); +#endif +} + +void DoClientSpecificVerification( MyServer& server, int /*n_thread*/ ) +{ + ASSERT( server.current_balance()==int(tbb::internal::AvailableHwConcurrency())-1, NULL ); +} + +int TestMain () { +#if _MSC_VER == 1600 && RML_USE_WCRM + REPORT("Known issue: RML resets the process mask when Concurrency Runtime is used.\n"); + // AvailableHwConcurrency reads process mask when the first call. That's why it should + // be called before RML initialization. + tbb::internal::AvailableHwConcurrency(); +#endif + + StrictTeam = true; + VerifyInitialization<MyFactory,MyClient>( MaxThread ); + SimpleTest<MyFactory,MyClient>(); + + StrictTeam = false; + VerifyInitialization<MyFactory,MyClient>( MaxThread ); + SimpleTest<MyFactory,MyClient>(); + + return Harness::Done; +} +#endif /* __TBB_WIN8UI_SUPPORT || __TBB_MIC_OFFLOAD */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_omp_c_linkage.c b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_omp_c_linkage.c new file mode 100644 index 00000000..540559a3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_omp_c_linkage.c @@ -0,0 +1,22 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +void Cplusplus(); + +int main() { + Cplusplus(); + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_tbb.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_tbb.cpp new file mode 100644 index 00000000..37e04adc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_rml_tbb.cpp @@ -0,0 +1,201 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <tbb/tbb_config.h> +#if __TBB_WIN8UI_SUPPORT || __TBB_MIC_OFFLOAD +#include "harness.h" +int TestMain () { + return Harness::Skipped; +} +#else +#include "rml_tbb.h" + +typedef tbb::internal::rml::tbb_server MyServer; +typedef tbb::internal::rml::tbb_factory MyFactory; + +// Forward declaration of the function used in test_server.h +void DoClientSpecificVerification( MyServer&, int ); + +#define HARNESS_DEFAULT_MIN_THREADS 0 +#include "test_server.h" + +tbb::atomic<int> n_available_hw_threads; + +class MyClient: public ClientBase<tbb::internal::rml::tbb_client> { + tbb::atomic<int> counter; + tbb::atomic<int> gate; + void process( job& j ) __TBB_override { + do_process(&j); + //wait until the gate is open. + while( gate==0 ) + Harness::Sleep(1); + + __TBB_ASSERT( nesting.limit<=2, NULL ); + if( nesting.level>=nesting.limit ) + return; + + size_type max_outstanding_connections = max_job_count(); // if nesting.level==0 + if( nesting.level==1 ) + max_outstanding_connections *= (1+max_outstanding_connections); + + if( default_concurrency()<=max_outstanding_connections+2 ) + // i.e., if it is not guaranteed that at least two connections may be made without depleting the_balance + return; + + // at this point, ( nesting.level<nesting.limit ) && ( my_server->default_concurrency()-max_outstanding_connections>2 ) + for( ;; ) { + while( n_available_hw_threads<=1 ) + Harness::Sleep(1); + + int n = --n_available_hw_threads; + if( n>0 ) break; + // else I lost + ++n_available_hw_threads; + } + + DoOneConnection<MyFactory,MyClient> doc(max_job_count(),Nesting(nesting.level+1,nesting.limit),0,false); + doc(0); + + ++n_available_hw_threads; + } +public: + MyClient() {counter=1;} + static const bool is_omp = false; + bool is_strict() const {return false;} + void open_the_gate() { gate = 1; } + void close_the_gate() { gate = 0; } +}; + +void FireUpJobs( MyServer& server, MyClient& client, int n_thread, int n_extra, Checker* checker ) { + REMARK("client %d: calling adjust_job_count_estimate(%d)\n", client.client_id(),n_thread); + // Exercise independent_thread_number_changed, even for zero values. + server.independent_thread_number_changed( n_extra ); +#if _WIN32||_WIN64 + ::rml::server::execution_resource_t me; + server.register_master( me ); +#endif /* _WIN32||_WIN64 */ + // Experiments indicate that when oversubscribing, the main thread should wait a little + // while for the RML worker threads to do some work. + if( checker ) { + // Give RML time to respond to change in number of threads. + Harness::Sleep(1); + for( int k=0; k<n_thread; ++k ) + client.job_array[k].processing_count = 0; + } + //close the gate to keep worker threads from returning to RML until a snapshot is taken + client.close_the_gate(); + server.adjust_job_count_estimate( n_thread ); + int n_used = 0; + if( checker ) { + Harness::Sleep(100); + for( int k=0; k<n_thread; ++k ) + if( client.job_array[k].processing_count ) + ++n_used; + } + // open the gate + client.open_the_gate(); + // Logic further below presumes that jobs never starve, so undo previous call + // to independent_thread_number_changed before waiting on those jobs. + server.independent_thread_number_changed( -n_extra ); + REMARK("client %d: wait for each job to be processed at least once\n",client.client_id()); + // Calculate the number of jobs that are expected to get threads. + int expected = n_thread; + // Wait for expected number of jobs to be processed. +#if RML_USE_WCRM + int default_concurrency = server.default_concurrency(); + if( N_TestConnections>0 ) { + if( default_concurrency+1>=8 && n_thread<=3 && N_TestConnections<=3 && (default_concurrency/int(N_TestConnections)-1)>=n_thread ) { +#endif /* RML_USE_WCRM */ + for(;;) { + int n = 0; + for( int k=0; k<n_thread; ++k ) + if( client.job_array[k].processing_count!=0 ) + ++n; + if( n>=expected ) break; + server.yield(); + } +#if RML_USE_WCRM + } else if( n_thread>0 ) { + for( int m=0; m<20; ++m ) { + int n = 0; + for( int k=0; k<n_thread; ++k ) + if( client.job_array[k].processing_count!=0 ) + ++n; + if( n>=expected ) break; + Harness::Sleep(1); + } + } + } +#endif /* RML_USE_WCRM */ + server.adjust_job_count_estimate(-n_thread); +#if _WIN32||_WIN64 + server.unregister_master( me ); +#endif + // Give RML some time to respond + if( checker ) { + Harness::Sleep(1); + checker->check_number_of_threads_delivered( n_used, n_thread, n_extra ); + } +} + +void DoClientSpecificVerification( MyServer&, int n_thread ) +{ + MyClient* client = new MyClient; + client->initialize( n_thread, Nesting(), ClientStackSize[0] ); + MyFactory factory; + memset( &factory, 0, sizeof(factory) ); + MyFactory::status_type status = factory.open(); + ASSERT( status!=MyFactory::st_not_found, "could not find RML library" ); + ASSERT( status!=MyFactory::st_incompatible, NULL ); + ASSERT( status==MyFactory::st_success, NULL ); + MyFactory::server_type* server; + status = factory.make_server( server, *client ); + ASSERT( status==MyFactory::st_success, NULL ); + client->set_server( server ); + client->expect_close_connection = true; + server->request_close_connection(); + // Client deletes itself when it sees call to acknowledge_close_connection from server. + factory.close(); +} + +void Initialize() +{ + MyClient* client = new MyClient; + client->initialize( 1, Nesting(), ClientStackSize[0] ); + MyFactory factory; + memset( &factory, 0, sizeof(factory) ); + factory.open(); + MyFactory::server_type* server; + factory.make_server( server, *client ); + client->set_server( server ); + n_available_hw_threads = server->default_concurrency(); + client->expect_close_connection = true; + server->request_close_connection(); + // Client deletes itself when it sees call to acknowledge_close_connection from server. + factory.close(); +} + +int TestMain () { + VerifyInitialization<MyFactory,MyClient>( MaxThread ); + if ( server_concurrency<1 ) { + REPORT("The test is not intended to run on 1 thread\n"); + return Harness::Skipped; + } + Initialize(); + SimpleTest<MyFactory,MyClient>(); + return Harness::Done; +} +#endif /* __TBB_WIN8UI_SUPPORT || __TBB_MIC_OFFLOAD */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_server.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_server.h new file mode 100644 index 00000000..dcde2a7f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_server.h @@ -0,0 +1,429 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* This header contains code shared by test_omp_server.cpp and test_tbb_server.cpp + There is no ifndef guard - test is supposed to include this file exactly once. + The test is also executed to have #include of rml_omp.h or rml_tbb.h before + including this header. + + This header should not use any parts of TBB that require linking in the TBB run-time. + It uses a few instances of tbb::atomic<T>, all of which are completely inlined. */ + +#include "tbb/atomic.h" +#include "tbb/tbb_thread.h" +#include "harness.h" +#include "harness_memory.h" +#include "harness_concurrency_tracker.h" + +//! Define TRIVIAL as 1 to test only a single client, no nesting, no extra threads. +#define TRIVIAL 0 + +//! Maximum number of clients +#if TRIVIAL +const size_t MaxClient = 1; +#else +const size_t MaxClient = 4; +#endif + +const size_t ClientStackSize[MaxClient] = { + 1000000 +#if !TRIVIAL + ,2000000 + ,1000000 + ,4000000 +#endif /* TRIVIAL */ +}; + +const size_t OverheadStackSize = 500000; + +const size_t JobArraySize = 1000; + +static bool TestSingleConnection; + +static size_t N_TestConnections; + +static int server_concurrency; + +class MyJob: public ::rml::job { +public: + //! Enumeration for tracking states of a job. + enum state_t { + //! Job has not yet been allocated. + unallocated, + //! Is idle. + idle, + //! Has a thread working on it. + busy, + //! After call to client::cleanup + clean + }; + tbb::atomic<int> state; + tbb::atomic<int> processing_count; + void update( state_t new_state, state_t old_state ) { + int o = state.compare_and_swap(new_state,old_state); + ASSERT( o==old_state, "illegal transition" ); + } + void update_from_either( state_t new_state, state_t old_state1, state_t old_state2 ) { + int snapshot; + do { + snapshot = state; + ASSERT( snapshot==old_state1||snapshot==old_state2, "illegal transition" ); + } while( state.compare_and_swap(new_state,snapshot)!=snapshot ); + } + MyJob() { + state=unallocated; + processing_count=0; + } + ~MyJob() { + // Overwrite so that accidental use after destruction can be detected. + memset(static_cast<void*>(this),-1,sizeof(*this)); + } +}; + +static tbb::atomic<int> ClientConstructions; +static tbb::atomic<int> ClientDestructions; + +struct Nesting { + int level; + int limit; + Nesting() : level(0), limit(0) {} + Nesting( int level_, int limit_ ) : level(level_), limit(limit_) {} +}; + +template<typename Client> +class ClientBase: public Client { +protected: + typedef typename Client::size_type size_type; + typedef typename Client::version_type version_type; + typedef typename Client::policy_type policy_type; + typedef typename Client::job job; +private: + size_type my_max_job_count; + size_t my_stack_size; + tbb::atomic<size_t> next_job_index; + int my_client_id; + rml::server* my_server; + +public: + enum state_t { + //! Treat *this as constructed. + live=0x1234, + //! Treat *this as destroyed. + destroyed=0xDEAD + }; + + tbb::atomic<int> state; + void update( state_t new_state, state_t old_state ) { + int o = state.compare_and_swap(new_state,old_state); + ASSERT( o==old_state, NULL ); + } + + tbb::atomic<bool> expect_close_connection; + + MyJob *job_array; + + version_type version() const __TBB_override { + ASSERT( state==live, NULL ); + return 1; + } + + size_type max_job_count() const __TBB_override { + ASSERT( state==live, NULL ); + return my_max_job_count; + } + + size_t min_stack_size() const __TBB_override { + ASSERT( state==live, NULL ); + return my_stack_size; + } + + policy_type policy() const __TBB_override {return Client::throughput;} + + void acknowledge_close_connection() __TBB_override { + ASSERT( expect_close_connection, NULL ); + for( size_t k=next_job_index; k>0; ) { + --k; + ASSERT( job_array[k].state==MyJob::clean, NULL ); + } + delete[] job_array; + job_array = NULL; + ASSERT( my_server, NULL ); + update( destroyed, live ); + delete this; + } + + void cleanup( job& j_ ) __TBB_override { + REMARK("client %d: cleanup(%p) called\n",client_id(),&j_); + ASSERT( state==live, NULL ); + MyJob& j = static_cast<MyJob&>(j_); + while( j.state==MyJob::busy ) + my_server->yield(); + j.update(MyJob::clean,MyJob::idle); + REMARK("client %d: cleanup(%p) returns\n",client_id(),&j_); + } + + job* create_one_job(); + +protected: + void do_process( job* j_ ) { + ASSERT( state==live, NULL ); + MyJob& j = static_cast<MyJob&>(*j_); + ASSERT( j_, NULL ); + j.update(MyJob::busy,MyJob::idle); + // use of the plain addition (not the atomic increment) is intentonial + j.processing_count = j.processing_count + 1; + ASSERT( my_stack_size>OverheadStackSize, NULL ); +#ifdef __ia64__ + // Half of the stack is reserved for RSE, so test only remaining half. + UseStackSpace( (my_stack_size-OverheadStackSize)/2 ); +#else + UseStackSpace( my_stack_size-OverheadStackSize ); +#endif + j.update(MyJob::idle,MyJob::busy); + my_server->yield(); + } +public: + ClientBase() : my_server(NULL) { + my_client_id = ClientConstructions++; + next_job_index = 0; + } + int client_id() const {return my_client_id;} + + Nesting nesting; + + void initialize( size_type max_job_count, Nesting nesting_, size_t stack_size ) { + ASSERT( stack_size>0, NULL ); + my_max_job_count = max_job_count; + nesting = nesting_; + my_stack_size = stack_size; + job_array = new MyJob[JobArraySize]; + expect_close_connection = false; + state = live; + } + + void set_server( rml::server* s ) {my_server=s;} + + unsigned default_concurrency() const { ASSERT( my_server, NULL); return my_server->default_concurrency(); } + + virtual ~ClientBase() { + ASSERT( state==destroyed, NULL ); + ++ClientDestructions; + } +}; + +template<typename Client> +typename Client::job* ClientBase<Client>::create_one_job() { + REMARK("client %d: create_one_job() called\n",client_id()); + size_t k = next_job_index++; + ASSERT( state==live, NULL ); + // Following assertion depends on assumption that implementation does not destroy jobs until + // the connection is closed. If the implementation is changed to destroy jobs sooner, the + // test logic in this header will have to be reworked. + ASSERT( k<my_max_job_count, "RML allocated more than max_job_count jobs simultaneously" ); + ASSERT( k<JobArraySize, "JobArraySize not big enough (problem is in test, not RML)" ); + MyJob& j = job_array[k]; + j.update(MyJob::idle,MyJob::unallocated); + REMARK("client %d: create_one_job() for k=%d returns %p\n",client_id(),int(k),&j); + return &j; +} + +struct warning_tracker { + tbb::atomic<int> n_more_than_available; + tbb::atomic<int> n_too_many_threads; + tbb::atomic<int> n_system_overload; + warning_tracker() { + n_more_than_available = 0; + n_too_many_threads = 0; + n_system_overload = 0; + } + bool all_set() { return n_more_than_available>0 && n_too_many_threads>0 && n_system_overload>0; } +} tracker; + +class Checker { +public: + int default_concurrency; + void check_number_of_threads_delivered( int n_delivered, int n_requested, int n_extra ) const; + Checker( rml::server& server ) : default_concurrency(int(server.default_concurrency())) {} +}; + +void Checker::check_number_of_threads_delivered( int n_delivered, int n_requested, int n_extra ) const { + ASSERT( default_concurrency>=0, NULL ); + if( tracker.all_set() ) return; + // Check that number of threads delivered is reasonable. + int n_avail = default_concurrency; + if( n_extra>0 ) + n_avail-=n_extra; + if( n_avail<0 ) + n_avail=0; + if( n_requested>default_concurrency ) + n_avail += n_requested-default_concurrency; + int n_expected = n_requested; + if( n_expected>n_avail ) + n_expected=n_avail; + const char* msg = NULL; + if( n_delivered>n_avail ) { + if( ++tracker.n_more_than_available>1 ) + return; + msg = "server delivered more threads than were theoretically available"; + } else if( n_delivered>n_expected ) { + if( ++tracker.n_too_many_threads>1 ) + return; + msg = "server delivered more threads than expected"; + } else if( n_delivered<n_expected ) { + if( ++tracker.n_system_overload>1 ) + return; + msg = "server delivered fewer threads than ideal; or, the system is overloaded?"; + } + if( msg ) { + REPORT("Warning: %s (n_delivered=%d n_avail=%d n_requested=%d n_extra=%d default_concurrency=%d)\n", + msg, n_delivered, n_avail, n_requested, n_extra, default_concurrency ); + } +} + +template<typename Factory,typename Client> +class DoOneConnection: NoAssign { + //! Number of threads to request + const int n_thread; + //! Nesting + const Nesting nesting; + //! Number of extra threads to pretend having outside the RML + const int n_extra; + //! If true, check number of threads actually delivered. + const bool check_delivered; +public: + DoOneConnection( int n_thread_, Nesting nesting_, int n_extra_, bool check_delivered_ ) : + n_thread(n_thread_), + nesting(nesting_), + n_extra(n_extra_), + check_delivered(check_delivered_) + { + } + + //! Test ith connection + void operator()( size_t i ) const; +}; + +template<typename Factory,typename Client> +void DoOneConnection<Factory,Client>::operator()( size_t i ) const { + ASSERT( i<MaxClient, NULL ); + Client* client = new Client; + client->initialize( Client::is_omp ? JobArraySize : n_thread, nesting, ClientStackSize[i] ); + Factory factory; + memset( &factory, 0, sizeof(factory) ); + typename Factory::status_type status = factory.open(); + ASSERT( status==Factory::st_success, NULL ); + + typename Factory::server_type* server; + status = factory.make_server( server, *client ); + ASSERT( status==Factory::st_success, NULL ); + Harness::ConcurrencyTracker ct; + REMARK("client %d: opened server n_thread=%d nesting=(%d,%d)\n", + client->client_id(), n_thread, nesting.level, nesting.limit); + client->set_server( server ); + Checker checker( *server ); + + FireUpJobs( *server, *client, n_thread, n_extra, check_delivered && !client->is_strict() ? &checker : NULL ); + + // Close the connection + client->expect_close_connection = true; + REMARK("client %d: calling request_close_connection\n", client->client_id()); +#if !RML_USE_WCRM + int default_concurrency = server->default_concurrency(); +#endif + server->request_close_connection(); + // Client deletes itself when it sees call to acknowledge_close_connection from server. + factory.close(); +#if !RML_USE_WCRM + if( TestSingleConnection ) + __TBB_ASSERT_EX( uintptr_t(factory.scratch_ptr)==uintptr_t(default_concurrency), "under/over subscription?" ); +#endif +} + +//! Test with n_threads threads and n_client clients. +template<typename Factory, typename Client> +void SimpleTest() { + Harness::ConcurrencyTracker::Reset(); + TestSingleConnection = true; + N_TestConnections = 1; + for( int n_thread=MinThread; n_thread<=MaxThread; ++n_thread ) { + // Test a single connection, no nesting, no extra threads + DoOneConnection<Factory,Client> doc(n_thread,Nesting(0,0),0,false); + doc(0); + } +#if !TRIVIAL + TestSingleConnection = false; + for( int n_thread=MinThread; n_thread<=MaxThread; ++n_thread ) { + // Test parallel connections + for( int n_client=1; n_client<=int(MaxClient); ++n_client ) { + N_TestConnections = n_client; + REMARK("SimpleTest: n_thread=%d n_client=%d\n",n_thread,n_client); + NativeParallelFor( n_client, DoOneConnection<Factory,Client>(n_thread,Nesting(0,0),0,false) ); + } + // Test server::independent_thread_number_changed + N_TestConnections = 1; + for( int n_extra=-4; n_extra<=32; n_extra=n_extra+1+n_extra/5 ) { + DoOneConnection<Factory,Client> doc(n_thread,Nesting(0,0),n_extra,true); + doc(0); + } +#if !RML_USE_WCRM + // Test nested connections + DoOneConnection<Factory,Client> doc(n_thread,Nesting(0,2),0,false); + doc(0); +#endif + } + ASSERT( Harness::ConcurrencyTracker::PeakParallelism()>1 || server_concurrency==0, "No multiple connections exercised?" ); +#endif /* !TRIVIAL */ + // Let RML catch up. + while( ClientConstructions!=ClientDestructions ) + Harness::Sleep(1); +} + +static void check_server_info( void* arg, const char* server_info ) +{ + ASSERT( strstr(server_info, (char*)arg), NULL ); +} + +template<typename Factory, typename Client> +void VerifyInitialization( int n_thread ) { + Client* client = new Client; + client->initialize( Client::is_omp ? JobArraySize : n_thread, Nesting(), ClientStackSize[0] ); + Factory factory; + memset( &factory, 0, sizeof(factory) ); + typename Factory::status_type status = factory.open(); + ASSERT( status!=Factory::st_not_found, "could not find RML library" ); + ASSERT( status!=Factory::st_incompatible, NULL ); + ASSERT( status==Factory::st_success, NULL ); + factory.call_with_server_info( check_server_info, (void*)"Intel(R) RML library" ); + typename Factory::server_type* server; + status = factory.make_server( server, *client ); + ASSERT( status!=Factory::st_incompatible, NULL ); + ASSERT( status!=Factory::st_not_found, NULL ); + ASSERT( status==Factory::st_success, NULL ); + REMARK("client %d: opened server n_thread=%d nesting=(%d,%d)\n", + client->client_id(), n_thread, 0, 0); + ASSERT( server, NULL ); + client->set_server( server ); + server_concurrency = server->default_concurrency(); + + DoClientSpecificVerification( *server, n_thread ); + + // Close the connection + client->expect_close_connection = true; + REMARK("client %d: calling request_close_connection\n", client->client_id()); + server->request_close_connection(); + // Client deletes itself when it sees call to acknowledge_close_connection from server. + factory.close(); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_thread_monitor.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_thread_monitor.cpp new file mode 100644 index 00000000..b3e59fb2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/rml/test/test_thread_monitor.cpp @@ -0,0 +1,113 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness.h" +#if __TBB_MIC_OFFLOAD +int TestMain () { + return Harness::Skipped; +} +#else +#include "thread_monitor.h" +#include "harness_memory.h" +#include "tbb/semaphore.cpp" + +class ThreadState { + void loop(); +public: + static __RML_DECL_THREAD_ROUTINE routine( void* arg ) { + static_cast<ThreadState*>(arg)->loop(); + return 0; + } + typedef rml::internal::thread_monitor thread_monitor; + thread_monitor monitor; + volatile int request; + volatile int ack; + volatile unsigned clock; + volatile unsigned stamp; + ThreadState() : request(-1), ack(-1), clock(0) {} +}; + +void ThreadState::loop() { + for(;;) { + ++clock; + if( ack==request ) { + thread_monitor::cookie c; + monitor.prepare_wait(c); + if( ack==request ) { + REMARK("%p: request=%d ack=%d\n", this, request, ack ); + monitor.commit_wait(c); + } else + monitor.cancel_wait(); + } else { + // Throw in delay occasionally + switch( request%8 ) { + case 0: + case 1: + case 5: + rml::internal::thread_monitor::yield(); + } + int r = request; + ack = request; + if( !r ) return; + } + } +} + +// Linux on IA-64 architecture seems to require at least 1<<18 bytes per stack. +const size_t MinStackSize = 1<<18; +const size_t MaxStackSize = 1<<22; + +int TestMain () { + for( int p=MinThread; p<=MaxThread; ++p ) { + ThreadState* t = new ThreadState[p]; + for( size_t stack_size = MinStackSize; stack_size<=MaxStackSize; stack_size*=2 ) { + REMARK("launching %d threads\n",p); + for( int i=0; i<p; ++i ) + rml::internal::thread_monitor::launch( ThreadState::routine, t+i, stack_size ); + for( int k=1000; k>=0; --k ) { + if( k%8==0 ) { + // Wait for threads to wait. + for( int i=0; i<p; ++i ) { + unsigned count = 0; + do { + t[i].stamp = t[i].clock; + rml::internal::thread_monitor::yield(); + if( ++count>=1000 ) { + REPORT("Warning: thread %d not waiting\n",i); + break; + } + } while( t[i].stamp!=t[i].clock ); + } + } + REMARK("notifying threads\n"); + for( int i=0; i<p; ++i ) { + // Change state visible to launched thread + t[i].request = k; + t[i].monitor.notify(); + } + REMARK("waiting for threads to respond\n"); + for( int i=0; i<p; ++i ) + // Wait for thread to respond + while( t[i].ack!=k ) + rml::internal::thread_monitor::yield(); + } + } + delete[] t; + } + + return Harness::Done; +} +#endif /* __TBB_MIC_OFFLOAD */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/arena.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/arena.cpp new file mode 100644 index 00000000..8e95460b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/arena.cpp @@ -0,0 +1,1220 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/global_control.h" // thread_stack_size + +#include "scheduler.h" +#include "governor.h" +#include "arena.h" +#include "itt_notify.h" +#include "semaphore.h" +#include "tbb/internal/_flow_graph_impl.h" + +#include <functional> + +#if __TBB_STATISTICS_STDOUT +#include <cstdio> +#endif + +namespace tbb { +namespace internal { + +#if __TBB_NUMA_SUPPORT +class numa_binding_observer : public tbb::task_scheduler_observer { + int my_numa_node_id; + binding_handler* binding_handler_ptr; +public: + numa_binding_observer( task_arena* ta, int numa_id, int num_slots ) + : task_scheduler_observer(*ta) + , my_numa_node_id(numa_id) + , binding_handler_ptr(tbb::internal::construct_binding_handler(num_slots)) + {} + + void on_scheduler_entry( bool ) __TBB_override { + tbb::internal::bind_thread_to_node( + binding_handler_ptr, this_task_arena::current_thread_index(), my_numa_node_id); + } + + void on_scheduler_exit( bool ) __TBB_override { + tbb::internal::restore_affinity_mask(binding_handler_ptr, this_task_arena::current_thread_index()); + } + + ~numa_binding_observer(){ + tbb::internal::destroy_binding_handler(binding_handler_ptr); + } +}; + +numa_binding_observer* construct_binding_observer( tbb::interface7::task_arena* ta, + int numa_id, int num_slots ) { + numa_binding_observer* binding_observer = NULL; + // numa_topology initialization will be lazily performed inside nodes_count() call + if (numa_id >= 0 && numa_topology::nodes_count() > 1) { + binding_observer = new numa_binding_observer(ta, numa_id, num_slots); + __TBB_ASSERT(binding_observer, "Failure during NUMA binding observer allocation and construction"); + binding_observer->observe(true); + } + return binding_observer; +} + +void destroy_binding_observer( numa_binding_observer* binding_observer ) { + __TBB_ASSERT(binding_observer, "Trying to deallocate NULL pointer"); + binding_observer->observe(false); + delete binding_observer; +} +#endif + +// put it here in order to enable compiler to inline it into arena::process and nested_arena_entry +void generic_scheduler::attach_arena( arena* a, size_t index, bool is_master ) { + __TBB_ASSERT( a->my_market == my_market, NULL ); + my_arena = a; + my_arena_index = index; + my_arena_slot = a->my_slots + index; + attach_mailbox( affinity_id(index+1) ); + if ( is_master && my_inbox.is_idle_state( true ) ) { + // Master enters an arena with its own task to be executed. It means that master is not + // going to enter stealing loop and take affinity tasks. + my_inbox.set_is_idle( false ); + } +#if __TBB_TASK_GROUP_CONTEXT + // Context to be used by root tasks by default (if the user has not specified one). + if( !is_master ) + my_dummy_task->prefix().context = a->my_default_ctx; +#endif /* __TBB_TASK_GROUP_CONTEXT */ +#if __TBB_TASK_PRIORITY + // In the current implementation master threads continue processing even when + // there are other masters with higher priority. Only TBB worker threads are + // redistributed between arenas based on the latters' priority. Thus master + // threads use arena's top priority as a reference point (in contrast to workers + // that use my_market->my_global_top_priority). + if( is_master ) { + my_ref_top_priority = &a->my_top_priority; + my_ref_reload_epoch = &a->my_reload_epoch; + } + my_local_reload_epoch = *my_ref_reload_epoch; + __TBB_ASSERT( !my_offloaded_tasks, NULL ); +#endif /* __TBB_TASK_PRIORITY */ +} + +inline static bool occupy_slot( generic_scheduler*& slot, generic_scheduler& s ) { + return !slot && as_atomic( slot ).compare_and_swap( &s, NULL ) == NULL; +} + +size_t arena::occupy_free_slot_in_range( generic_scheduler& s, size_t lower, size_t upper ) { + if ( lower >= upper ) return out_of_arena; + // Start search for an empty slot from the one we occupied the last time + size_t index = s.my_arena_index; + if ( index < lower || index >= upper ) index = s.my_random.get() % (upper - lower) + lower; + __TBB_ASSERT( index >= lower && index < upper, NULL ); + // Find a free slot + for ( size_t i = index; i < upper; ++i ) + if ( occupy_slot(my_slots[i].my_scheduler, s) ) return i; + for ( size_t i = lower; i < index; ++i ) + if ( occupy_slot(my_slots[i].my_scheduler, s) ) return i; + return out_of_arena; +} + +template <bool as_worker> +size_t arena::occupy_free_slot( generic_scheduler& s ) { + // Firstly, masters try to occupy reserved slots + size_t index = as_worker ? out_of_arena : occupy_free_slot_in_range( s, 0, my_num_reserved_slots ); + if ( index == out_of_arena ) { + // Secondly, all threads try to occupy all non-reserved slots + index = occupy_free_slot_in_range( s, my_num_reserved_slots, my_num_slots ); + // Likely this arena is already saturated + if ( index == out_of_arena ) + return out_of_arena; + } + + ITT_NOTIFY(sync_acquired, my_slots + index); + atomic_update( my_limit, (unsigned)(index + 1), std::less<unsigned>() ); + return index; +} + +void arena::process( generic_scheduler& s ) { + __TBB_ASSERT( is_alive(my_guard), NULL ); + __TBB_ASSERT( governor::is_set(&s), NULL ); + __TBB_ASSERT( s.my_innermost_running_task == s.my_dummy_task, NULL ); + __TBB_ASSERT( s.worker_outermost_level(), NULL ); + + __TBB_ASSERT( my_num_slots > 1, NULL ); + + size_t index = occupy_free_slot</*as_worker*/true>( s ); + if ( index == out_of_arena ) + goto quit; + + __TBB_ASSERT( index >= my_num_reserved_slots, "Workers cannot occupy reserved slots" ); + s.attach_arena( this, index, /*is_master*/false ); + +#if !__TBB_FP_CONTEXT + my_cpu_ctl_env.set_env(); +#endif + +#if __TBB_ARENA_OBSERVER + __TBB_ASSERT( !s.my_last_local_observer, "There cannot be notified local observers when entering arena" ); + my_observers.notify_entry_observers( s.my_last_local_observer, /*worker=*/true ); +#endif /* __TBB_ARENA_OBSERVER */ + + // Task pool can be marked as non-empty if the worker occupies the slot left by a master. + if ( s.my_arena_slot->task_pool != EmptyTaskPool ) { + __TBB_ASSERT( s.my_inbox.is_idle_state(false), NULL ); + s.local_wait_for_all( *s.my_dummy_task, NULL ); + __TBB_ASSERT( s.my_inbox.is_idle_state(true), NULL ); + } + + for ( ;; ) { + __TBB_ASSERT( s.my_innermost_running_task == s.my_dummy_task, NULL ); + __TBB_ASSERT( s.worker_outermost_level(), NULL ); + __TBB_ASSERT( is_alive(my_guard), NULL ); + __TBB_ASSERT( s.is_quiescent_local_task_pool_reset(), + "Worker cannot leave arena while its task pool is not reset" ); + __TBB_ASSERT( s.my_arena_slot->task_pool == EmptyTaskPool, "Empty task pool is not marked appropriately" ); + // This check prevents relinquishing more than necessary workers because + // of the non-atomicity of the decision making procedure + if ( is_recall_requested() ) + break; + // Try to steal a task. + // Passing reference count is technically unnecessary in this context, + // but omitting it here would add checks inside the function. + task* t = s.receive_or_steal_task( __TBB_ISOLATION_ARG( s.my_dummy_task->prefix().ref_count, no_isolation ) ); + if (t) { + // A side effect of receive_or_steal_task is that my_innermost_running_task can be set. + // But for the outermost dispatch loop it has to be a dummy task. + s.my_innermost_running_task = s.my_dummy_task; + s.local_wait_for_all(*s.my_dummy_task,t); + } + } +#if __TBB_ARENA_OBSERVER + my_observers.notify_exit_observers( s.my_last_local_observer, /*worker=*/true ); + s.my_last_local_observer = NULL; +#endif /* __TBB_ARENA_OBSERVER */ +#if __TBB_TASK_PRIORITY + if ( s.my_offloaded_tasks ) + orphan_offloaded_tasks( s ); +#endif /* __TBB_TASK_PRIORITY */ +#if __TBB_STATISTICS + ++s.my_counters.arena_roundtrips; + *my_slots[index].my_counters += s.my_counters; + s.my_counters.reset(); +#endif /* __TBB_STATISTICS */ + __TBB_store_with_release( my_slots[index].my_scheduler, (generic_scheduler*)NULL ); + s.my_arena_slot = 0; // detached from slot + s.my_inbox.detach(); + __TBB_ASSERT( s.my_inbox.is_idle_state(true), NULL ); + __TBB_ASSERT( s.my_innermost_running_task == s.my_dummy_task, NULL ); + __TBB_ASSERT( s.worker_outermost_level(), NULL ); + __TBB_ASSERT( is_alive(my_guard), NULL ); +quit: + // In contrast to earlier versions of TBB (before 3.0 U5) now it is possible + // that arena may be temporarily left unpopulated by threads. See comments in + // arena::on_thread_leaving() for more details. + on_thread_leaving<ref_worker>(); +} + +arena::arena ( market& m, unsigned num_slots, unsigned num_reserved_slots ) { + __TBB_ASSERT( !my_guard, "improperly allocated arena?" ); + __TBB_ASSERT( sizeof(my_slots[0]) % NFS_GetLineSize()==0, "arena::slot size not multiple of cache line size" ); + __TBB_ASSERT( (uintptr_t)this % NFS_GetLineSize()==0, "arena misaligned" ); +#if __TBB_TASK_PRIORITY + __TBB_ASSERT( !my_reload_epoch && !my_orphaned_tasks && !my_skipped_fifo_priority, "New arena object is not zeroed" ); +#endif /* __TBB_TASK_PRIORITY */ + my_market = &m; + my_limit = 1; + // Two slots are mandatory: for the master, and for 1 worker (required to support starvation resistant tasks). + my_num_slots = num_arena_slots(num_slots); + my_num_reserved_slots = num_reserved_slots; + my_max_num_workers = num_slots-num_reserved_slots; + my_references = ref_external; // accounts for the master +#if __TBB_TASK_PRIORITY + my_bottom_priority = my_top_priority = normalized_normal_priority; +#endif /* __TBB_TASK_PRIORITY */ + my_aba_epoch = m.my_arenas_aba_epoch; +#if __TBB_ARENA_OBSERVER + my_observers.my_arena = this; +#endif +#if __TBB_PREVIEW_RESUMABLE_TASKS + my_co_cache.init(4 * num_slots); +#endif + __TBB_ASSERT ( my_max_num_workers <= my_num_slots, NULL ); + // Construct slots. Mark internal synchronization elements for the tools. + for( unsigned i = 0; i < my_num_slots; ++i ) { + __TBB_ASSERT( !my_slots[i].my_scheduler && !my_slots[i].task_pool, NULL ); + __TBB_ASSERT( !my_slots[i].task_pool_ptr, NULL ); + __TBB_ASSERT( !my_slots[i].my_task_pool_size, NULL ); +#if __TBB_PREVIEW_RESUMABLE_TASKS + __TBB_ASSERT( !my_slots[i].my_scheduler_is_recalled, NULL ); +#endif + ITT_SYNC_CREATE(my_slots + i, SyncType_Scheduler, SyncObj_WorkerTaskPool); + mailbox(i+1).construct(); + ITT_SYNC_CREATE(&mailbox(i+1), SyncType_Scheduler, SyncObj_Mailbox); + my_slots[i].hint_for_pop = i; +#if __TBB_PREVIEW_CRITICAL_TASKS + my_slots[i].hint_for_critical = i; +#endif +#if __TBB_STATISTICS + my_slots[i].my_counters = new ( NFS_Allocate(1, sizeof(statistics_counters), NULL) ) statistics_counters; +#endif /* __TBB_STATISTICS */ + } + my_task_stream.initialize(my_num_slots); + ITT_SYNC_CREATE(&my_task_stream, SyncType_Scheduler, SyncObj_TaskStream); +#if __TBB_PREVIEW_CRITICAL_TASKS + my_critical_task_stream.initialize(my_num_slots); + ITT_SYNC_CREATE(&my_critical_task_stream, SyncType_Scheduler, SyncObj_CriticalTaskStream); +#endif +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + my_local_concurrency_mode = false; + my_global_concurrency_mode = false; +#endif +#if !__TBB_FP_CONTEXT + my_cpu_ctl_env.get_env(); +#endif +} + +arena& arena::allocate_arena( market& m, unsigned num_slots, unsigned num_reserved_slots ) { + __TBB_ASSERT( sizeof(base_type) + sizeof(arena_slot) == sizeof(arena), "All arena data fields must go to arena_base" ); + __TBB_ASSERT( sizeof(base_type) % NFS_GetLineSize() == 0, "arena slots area misaligned: wrong padding" ); + __TBB_ASSERT( sizeof(mail_outbox) == NFS_MaxLineSize, "Mailbox padding is wrong" ); + size_t n = allocation_size(num_arena_slots(num_slots)); + unsigned char* storage = (unsigned char*)NFS_Allocate( 1, n, NULL ); + // Zero all slots to indicate that they are empty + memset( storage, 0, n ); + return *new( storage + num_arena_slots(num_slots) * sizeof(mail_outbox) ) arena(m, num_slots, num_reserved_slots); +} + +void arena::free_arena () { + __TBB_ASSERT( is_alive(my_guard), NULL ); + __TBB_ASSERT( !my_references, "There are threads in the dying arena" ); + __TBB_ASSERT( !my_num_workers_requested && !my_num_workers_allotted, "Dying arena requests workers" ); + __TBB_ASSERT( my_pool_state == SNAPSHOT_EMPTY || !my_max_num_workers, "Inconsistent state of a dying arena" ); +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + __TBB_ASSERT( !my_global_concurrency_mode, NULL ); +#endif +#if !__TBB_STATISTICS_EARLY_DUMP + GATHER_STATISTIC( dump_arena_statistics() ); +#endif + poison_value( my_guard ); + intptr_t drained = 0; + for ( unsigned i = 0; i < my_num_slots; ++i ) { + __TBB_ASSERT( !my_slots[i].my_scheduler, "arena slot is not empty" ); + // TODO: understand the assertion and modify + // __TBB_ASSERT( my_slots[i].task_pool == EmptyTaskPool, NULL ); + __TBB_ASSERT( my_slots[i].head == my_slots[i].tail, NULL ); // TODO: replace by is_quiescent_local_task_pool_empty + my_slots[i].free_task_pool(); +#if __TBB_STATISTICS + NFS_Free( my_slots[i].my_counters ); +#endif /* __TBB_STATISTICS */ + drained += mailbox(i+1).drain(); + } + __TBB_ASSERT( my_task_stream.drain()==0, "Not all enqueued tasks were executed"); +#if __TBB_PREVIEW_RESUMABLE_TASKS + // Cleanup coroutines/schedulers cache + my_co_cache.cleanup(); +#endif +#if __TBB_PREVIEW_CRITICAL_TASKS + __TBB_ASSERT( my_critical_task_stream.drain()==0, "Not all critical tasks were executed"); +#endif +#if __TBB_COUNT_TASK_NODES + my_market->update_task_node_count( -drained ); +#endif /* __TBB_COUNT_TASK_NODES */ + // remove an internal reference + my_market->release( /*is_public=*/false, /*blocking_terminate=*/false ); +#if __TBB_TASK_GROUP_CONTEXT + __TBB_ASSERT( my_default_ctx, "Master thread never entered the arena?" ); + my_default_ctx->~task_group_context(); + NFS_Free(my_default_ctx); +#endif /* __TBB_TASK_GROUP_CONTEXT */ +#if __TBB_ARENA_OBSERVER + if ( !my_observers.empty() ) + my_observers.clear(); +#endif /* __TBB_ARENA_OBSERVER */ + void* storage = &mailbox(my_num_slots); + __TBB_ASSERT( my_references == 0, NULL ); + __TBB_ASSERT( my_pool_state == SNAPSHOT_EMPTY || !my_max_num_workers, NULL ); + this->~arena(); +#if TBB_USE_ASSERT > 1 + memset( storage, 0, allocation_size(my_num_slots) ); +#endif /* TBB_USE_ASSERT */ + NFS_Free( storage ); +} + +#if __TBB_STATISTICS +void arena::dump_arena_statistics () { + statistics_counters total; + for( unsigned i = 0; i < my_num_slots; ++i ) { +#if __TBB_STATISTICS_EARLY_DUMP + generic_scheduler* s = my_slots[i].my_scheduler; + if ( s ) + *my_slots[i].my_counters += s->my_counters; +#else + __TBB_ASSERT( !my_slots[i].my_scheduler, NULL ); +#endif + if ( i != 0 ) { + total += *my_slots[i].my_counters; + dump_statistics( *my_slots[i].my_counters, i ); + } + } + dump_statistics( *my_slots[0].my_counters, 0 ); +#if __TBB_STATISTICS_STDOUT +#if !__TBB_STATISTICS_TOTALS_ONLY + printf( "----------------------------------------------\n" ); +#endif + dump_statistics( total, workers_counters_total ); + total += *my_slots[0].my_counters; + dump_statistics( total, arena_counters_total ); +#if !__TBB_STATISTICS_TOTALS_ONLY + printf( "==============================================\n" ); +#endif +#endif /* __TBB_STATISTICS_STDOUT */ +} +#endif /* __TBB_STATISTICS */ + +#if __TBB_TASK_PRIORITY +// The method inspects a scheduler to determine: +// 1. if it has tasks that can be retrieved and executed (via the return value); +// 2. if it has any tasks at all, including those of lower priority (via tasks_present); +// 3. if it is able to work with enqueued tasks (via dequeuing_possible). +inline bool arena::may_have_tasks ( generic_scheduler* s, bool& tasks_present, bool& dequeuing_possible ) { + if ( !s || s->my_arena != this ) + return false; + dequeuing_possible |= s->worker_outermost_level(); + if ( s->my_pool_reshuffling_pending ) { + // This primary task pool is nonempty and may contain tasks at the current + // priority level. Its owner is winnowing lower priority tasks at the moment. + tasks_present = true; + return true; + } + if ( s->my_offloaded_tasks ) { + tasks_present = true; + if ( s->my_local_reload_epoch < *s->my_ref_reload_epoch ) { + // This scheduler's offload area is nonempty and may contain tasks at the + // current priority level. + return true; + } + } + return false; +} + +void arena::orphan_offloaded_tasks(generic_scheduler& s) { + __TBB_ASSERT( s.my_offloaded_tasks, NULL ); + GATHER_STATISTIC( ++s.my_counters.prio_orphanings ); + ++my_abandonment_epoch; + __TBB_ASSERT( s.my_offloaded_task_list_tail_link && !*s.my_offloaded_task_list_tail_link, NULL ); + task* orphans; + do { + orphans = const_cast<task*>(my_orphaned_tasks); + *s.my_offloaded_task_list_tail_link = orphans; + } while ( as_atomic(my_orphaned_tasks).compare_and_swap(s.my_offloaded_tasks, orphans) != orphans ); + s.my_offloaded_tasks = NULL; +#if TBB_USE_ASSERT + s.my_offloaded_task_list_tail_link = NULL; +#endif /* TBB_USE_ASSERT */ +} +#endif /* __TBB_TASK_PRIORITY */ + +bool arena::has_enqueued_tasks() { + // Look for enqueued tasks at all priority levels + for ( int p = 0; p < num_priority_levels; ++p ) + if ( !my_task_stream.empty(p) ) + return true; + return false; +} + +void arena::restore_priority_if_need() { + // Check for the presence of enqueued tasks "lost" on some of + // priority levels because updating arena priority and switching + // arena into "populated" (FULL) state happen non-atomically. + // Imposing atomicity would require task::enqueue() to use a lock, + // which is unacceptable. + if ( has_enqueued_tasks() ) { + advertise_new_work<work_enqueued>(); +#if __TBB_TASK_PRIORITY + // update_arena_priority() expects non-zero arena::my_num_workers_requested, + // so must be called after advertise_new_work<work_enqueued>() + for ( int p = 0; p < num_priority_levels; ++p ) + if ( !my_task_stream.empty(p) ) { + if ( p < my_bottom_priority || p > my_top_priority ) + my_market->update_arena_priority(*this, p); + } +#endif + } +} + +bool arena::is_out_of_work() { + // TODO: rework it to return at least a hint about where a task was found; better if the task itself. + for(;;) { + pool_state_t snapshot = my_pool_state; + switch( snapshot ) { + case SNAPSHOT_EMPTY: + return true; + case SNAPSHOT_FULL: { + // Use unique id for "busy" in order to avoid ABA problems. + const pool_state_t busy = pool_state_t(&busy); + // Request permission to take snapshot + if( my_pool_state.compare_and_swap( busy, SNAPSHOT_FULL )==SNAPSHOT_FULL ) { + // Got permission. Take the snapshot. + // NOTE: This is not a lock, as the state can be set to FULL at + // any moment by a thread that spawns/enqueues new task. + size_t n = my_limit; + // Make local copies of volatile parameters. Their change during + // snapshot taking procedure invalidates the attempt, and returns + // this thread into the dispatch loop. +#if __TBB_TASK_PRIORITY + uintptr_t reload_epoch = __TBB_load_with_acquire( my_reload_epoch ); + intptr_t top_priority = my_top_priority; + // Inspect primary task pools first +#endif /* __TBB_TASK_PRIORITY */ + size_t k; + for( k=0; k<n; ++k ) { + if( my_slots[k].task_pool != EmptyTaskPool && + __TBB_load_relaxed(my_slots[k].head) < __TBB_load_relaxed(my_slots[k].tail) ) + { + // k-th primary task pool is nonempty and does contain tasks. + break; + } + if( my_pool_state!=busy ) + return false; // the work was published + } + __TBB_ASSERT( k <= n, NULL ); + bool work_absent = k == n; +#if __TBB_PREVIEW_CRITICAL_TASKS + bool no_critical_tasks = my_critical_task_stream.empty(0); + work_absent &= no_critical_tasks; +#endif +#if __TBB_TASK_PRIORITY + // Variable tasks_present indicates presence of tasks at any priority + // level, while work_absent refers only to the current priority. + bool tasks_present = !work_absent || my_orphaned_tasks; + bool dequeuing_possible = false; + if ( work_absent ) { + // Check for the possibility that recent priority changes + // brought some tasks to the current priority level + + uintptr_t abandonment_epoch = my_abandonment_epoch; + // Master thread's scheduler needs special handling as it + // may be destroyed at any moment (workers' schedulers are + // guaranteed to be alive while at least one thread is in arena). + // The lock below excludes concurrency with task group state change + // propagation and guarantees lifetime of the master thread. + the_context_state_propagation_mutex.lock(); + work_absent = !may_have_tasks( my_slots[0].my_scheduler, tasks_present, dequeuing_possible ); + the_context_state_propagation_mutex.unlock(); + // The following loop is subject to data races. While k-th slot's + // scheduler is being examined, corresponding worker can either + // leave to RML or migrate to another arena. + // But the races are not prevented because all of them are benign. + // First, the code relies on the fact that worker thread's scheduler + // object persists until the whole library is deinitialized. + // Second, in the worst case the races can only cause another + // round of stealing attempts to be undertaken. Introducing complex + // synchronization into this coldest part of the scheduler's control + // flow does not seem to make sense because it both is unlikely to + // ever have any observable performance effect, and will require + // additional synchronization code on the hotter paths. + for( k = 1; work_absent && k < n; ++k ) { + if( my_pool_state!=busy ) + return false; // the work was published + work_absent = !may_have_tasks( my_slots[k].my_scheduler, tasks_present, dequeuing_possible ); + } + // Preclude premature switching arena off because of a race in the previous loop. + work_absent = work_absent + && !__TBB_load_with_acquire(my_orphaned_tasks) + && abandonment_epoch == my_abandonment_epoch; + } +#endif /* __TBB_TASK_PRIORITY */ + // Test and test-and-set. + if( my_pool_state==busy ) { +#if __TBB_TASK_PRIORITY + bool no_fifo_tasks = my_task_stream.empty(top_priority); + work_absent = work_absent && (!dequeuing_possible || no_fifo_tasks) + && top_priority == my_top_priority && reload_epoch == my_reload_epoch; +#else + bool no_fifo_tasks = my_task_stream.empty(0); + work_absent = work_absent && no_fifo_tasks; +#endif /* __TBB_TASK_PRIORITY */ + if( work_absent ) { +#if __TBB_TASK_PRIORITY + if ( top_priority > my_bottom_priority ) { + if ( my_market->lower_arena_priority(*this, top_priority - 1, reload_epoch) + && !my_task_stream.empty(top_priority) ) + { + atomic_update( my_skipped_fifo_priority, top_priority, std::less<intptr_t>()); + } + } + else if ( !tasks_present && !my_orphaned_tasks && no_fifo_tasks ) { +#endif /* __TBB_TASK_PRIORITY */ + // save current demand value before setting SNAPSHOT_EMPTY, + // to avoid race with advertise_new_work. + int current_demand = (int)my_max_num_workers; + if( my_pool_state.compare_and_swap( SNAPSHOT_EMPTY, busy )==busy ) { + // This thread transitioned pool to empty state, and thus is + // responsible for telling the market that there is no work to do. + my_market->adjust_demand( *this, -current_demand ); + restore_priority_if_need(); + return true; + } + return false; +#if __TBB_TASK_PRIORITY + } +#endif /* __TBB_TASK_PRIORITY */ + } + // Undo previous transition SNAPSHOT_FULL-->busy, unless another thread undid it. + my_pool_state.compare_and_swap( SNAPSHOT_FULL, busy ); + } + } + return false; + } + default: + // Another thread is taking a snapshot. + return false; + } + } +} + +#if __TBB_COUNT_TASK_NODES +intptr_t arena::workers_task_node_count() { + intptr_t result = 0; + for( unsigned i = 1; i < my_num_slots; ++i ) { + generic_scheduler* s = my_slots[i].my_scheduler; + if( s ) + result += s->my_task_node_count; + } + return result; +} +#endif /* __TBB_COUNT_TASK_NODES */ + +void arena::enqueue_task( task& t, intptr_t prio, FastRandom &random ) +{ +#if __TBB_RECYCLE_TO_ENQUEUE + __TBB_ASSERT( t.state()==task::allocated || t.state()==task::to_enqueue, "attempt to enqueue task with inappropriate state" ); +#else + __TBB_ASSERT( t.state()==task::allocated, "attempt to enqueue task that is not in 'allocated' state" ); +#endif + t.prefix().state = task::ready; + t.prefix().extra_state |= es_task_enqueued; // enqueued task marker + +#if TBB_USE_ASSERT + if( task* parent = t.parent() ) { + internal::reference_count ref_count = parent->prefix().ref_count; + __TBB_ASSERT( ref_count!=0, "attempt to enqueue task whose parent has a ref_count==0 (forgot to set_ref_count?)" ); + __TBB_ASSERT( ref_count>0, "attempt to enqueue task whose parent has a ref_count<0" ); + parent->prefix().extra_state |= es_ref_count_active; + } + __TBB_ASSERT(t.prefix().affinity==affinity_id(0), "affinity is ignored for enqueued tasks"); +#endif /* TBB_USE_ASSERT */ +#if __TBB_PREVIEW_CRITICAL_TASKS + +#if __TBB_TASK_PRIORITY + bool is_critical = internal::is_critical( t ) || prio == internal::priority_critical; +#else /*!__TBB_TASK_PRIORITY*/ + bool is_critical = internal::is_critical( t ); +#endif /*!__TBB_TASK_PRIORITY*/ + + if( is_critical ) { + // TODO: consider using of 'scheduler::handled_as_critical' + internal::make_critical( t ); + generic_scheduler* s = governor::local_scheduler_if_initialized(); + ITT_NOTIFY(sync_releasing, &my_critical_task_stream); + if( s && s->my_arena_slot ) { + // Scheduler is initialized and it is attached to the arena, + // propagate isolation level to critical task +#if __TBB_TASK_ISOLATION + t.prefix().isolation = s->my_innermost_running_task->prefix().isolation; +#endif + unsigned& lane = s->my_arena_slot->hint_for_critical; + my_critical_task_stream.push( &t, 0, tbb::internal::subsequent_lane_selector(lane) ); + } else { + // Either scheduler is not initialized or it is not attached to the arena + // use random lane for the task + my_critical_task_stream.push( &t, 0, internal::random_lane_selector(random) ); + } + advertise_new_work<work_spawned>(); + return; + } +#endif /* __TBB_PREVIEW_CRITICAL_TASKS */ + + ITT_NOTIFY(sync_releasing, &my_task_stream); +#if __TBB_TASK_PRIORITY + intptr_t p = prio ? normalize_priority(priority_t(prio)) : normalized_normal_priority; + assert_priority_valid(p); +#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_CPF_BUILD + my_task_stream.push( &t, p, internal::random_lane_selector(random) ); +#else + my_task_stream.push( &t, p, random ); +#endif + if ( p != my_top_priority ) + my_market->update_arena_priority( *this, p ); +#else /* !__TBB_TASK_PRIORITY */ + __TBB_ASSERT_EX(prio == 0, "the library is not configured to respect the task priority"); +#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_CPF_BUILD + my_task_stream.push( &t, 0, internal::random_lane_selector(random) ); +#else + my_task_stream.push( &t, 0, random ); +#endif +#endif /* !__TBB_TASK_PRIORITY */ + advertise_new_work<work_enqueued>(); +#if __TBB_TASK_PRIORITY + if ( p != my_top_priority ) + my_market->update_arena_priority( *this, p ); +#endif /* __TBB_TASK_PRIORITY */ +} + +class nested_arena_context : no_copy { +public: + nested_arena_context(generic_scheduler *s, arena* a, size_t slot_index, bool type, bool same) + : my_scheduler(*s), my_orig_ctx(NULL), same_arena(same) { + if (same_arena) { + my_orig_state.my_properties = my_scheduler.my_properties; + my_orig_state.my_innermost_running_task = my_scheduler.my_innermost_running_task; + mimic_outermost_level(a, type); + } else { + my_orig_state = *s; +#if __TBB_PREVIEW_RESUMABLE_TASKS + my_scheduler.my_properties.genuine = true; + my_scheduler.my_current_is_recalled = NULL; +#endif + mimic_outermost_level(a, type); + s->nested_arena_entry(a, slot_index); + } + } + ~nested_arena_context() { +#if __TBB_TASK_GROUP_CONTEXT + my_scheduler.my_dummy_task->prefix().context = my_orig_ctx; // restore context of dummy task +#endif + if (same_arena) { + my_scheduler.my_properties = my_orig_state.my_properties; + my_scheduler.my_innermost_running_task = my_orig_state.my_innermost_running_task; + } else { + my_scheduler.nested_arena_exit(); + static_cast<scheduler_state&>(my_scheduler) = my_orig_state; // restore arena settings +#if __TBB_TASK_PRIORITY + my_scheduler.my_local_reload_epoch = *my_orig_state.my_ref_reload_epoch; +#endif + governor::assume_scheduler(&my_scheduler); + } + } + +private: + generic_scheduler &my_scheduler; + scheduler_state my_orig_state; + task_group_context *my_orig_ctx; + const bool same_arena; + + void mimic_outermost_level(arena* a, bool type) { + my_scheduler.my_properties.outermost = true; + my_scheduler.my_properties.type = type; + my_scheduler.my_innermost_running_task = my_scheduler.my_dummy_task; +#if __TBB_PREVIEW_CRITICAL_TASKS + my_scheduler.my_properties.has_taken_critical_task = false; +#endif +#if __TBB_TASK_GROUP_CONTEXT + // Save dummy's context and replace it by arena's context + my_orig_ctx = my_scheduler.my_dummy_task->prefix().context; + my_scheduler.my_dummy_task->prefix().context = a->my_default_ctx; +#endif + } +}; + +void generic_scheduler::nested_arena_entry(arena* a, size_t slot_index) { + __TBB_ASSERT( is_alive(a->my_guard), NULL ); + __TBB_ASSERT( a!=my_arena, NULL); + + // overwrite arena settings +#if __TBB_TASK_PRIORITY + if ( my_offloaded_tasks ) + my_arena->orphan_offloaded_tasks( *this ); + my_offloaded_tasks = NULL; +#endif /* __TBB_TASK_PRIORITY */ + attach_arena( a, slot_index, /*is_master*/true ); + __TBB_ASSERT( my_arena == a, NULL ); + governor::assume_scheduler( this ); + // TODO? ITT_NOTIFY(sync_acquired, a->my_slots + index); + // TODO: it requires market to have P workers (not P-1) + // TODO: a preempted worker should be excluded from assignment to other arenas e.g. my_slack-- + if( !is_worker() && slot_index >= my_arena->my_num_reserved_slots ) + my_arena->my_market->adjust_demand(*my_arena, -1); +#if __TBB_ARENA_OBSERVER + my_last_local_observer = 0; // TODO: try optimize number of calls + my_arena->my_observers.notify_entry_observers( my_last_local_observer, /*worker=*/false ); +#endif +#if __TBB_PREVIEW_RESUMABLE_TASKS + my_wait_task = NULL; +#endif +} + +void generic_scheduler::nested_arena_exit() { +#if __TBB_ARENA_OBSERVER + my_arena->my_observers.notify_exit_observers( my_last_local_observer, /*worker=*/false ); +#endif /* __TBB_ARENA_OBSERVER */ +#if __TBB_TASK_PRIORITY + if ( my_offloaded_tasks ) + my_arena->orphan_offloaded_tasks( *this ); +#endif + if( !is_worker() && my_arena_index >= my_arena->my_num_reserved_slots ) + my_arena->my_market->adjust_demand(*my_arena, 1); + // Free the master slot. + __TBB_ASSERT(my_arena->my_slots[my_arena_index].my_scheduler, "A slot is already empty"); + __TBB_store_with_release(my_arena->my_slots[my_arena_index].my_scheduler, (generic_scheduler*)NULL); + my_arena->my_exit_monitors.notify_one(); // do not relax! +} + +void generic_scheduler::wait_until_empty() { + my_dummy_task->prefix().ref_count++; // prevents exit from local_wait_for_all when local work is done enforcing the stealing + while( my_arena->my_pool_state != arena::SNAPSHOT_EMPTY ) + local_wait_for_all(*my_dummy_task, NULL); + my_dummy_task->prefix().ref_count--; +} + +#if __TBB_PREVIEW_RESUMABLE_TASKS +class resume_task : public task { + generic_scheduler& my_target; +public: + resume_task(generic_scheduler& target) : my_target(target) {} + task* execute() __TBB_override { + generic_scheduler* s = governor::local_scheduler_if_initialized(); + __TBB_ASSERT(s, NULL); + if (s->prepare_resume(my_target)) { + s->resume(my_target); + } else { + __TBB_ASSERT(prefix().state == task::executing, NULL); + // Request the dispatch loop to exit (because we in a coroutine on the outermost level). + prefix().state = task::to_resume; + } + return NULL; + } +}; + +static generic_scheduler& create_coroutine(generic_scheduler& curr) { + // We may have some coroutines cached + generic_scheduler* co_sched = curr.my_arena->my_co_cache.pop(); + if (!co_sched) { + // TODO: avoid setting/unsetting the scheduler. + governor::assume_scheduler(NULL); + co_sched = generic_scheduler::create_worker(*curr.my_market, curr.my_arena_index, /* genuine = */ false); + governor::assume_scheduler(&curr); + // Prepare newly created scheduler + co_sched->my_arena = curr.my_arena; + } + // Prepare scheduler (general) + co_sched->my_dummy_task->prefix().context = co_sched->my_arena->my_default_ctx; + // Prolong the arena's lifetime until all coroutines is alive + // (otherwise the arena can be destroyed while some tasks are suspended). + co_sched->my_arena->my_references += arena::ref_external; + return *co_sched; +} + +void internal_suspend(void* suspend_callback, void* user_callback) { + generic_scheduler& s = *governor::local_scheduler(); + __TBB_ASSERT(s.my_arena_slot->my_scheduler_is_recalled != NULL, NULL); + bool is_recalled = *s.my_arena_slot->my_scheduler_is_recalled; + generic_scheduler& target = is_recalled ? *s.my_arena_slot->my_scheduler : create_coroutine(s); + + generic_scheduler::callback_t callback = { + (generic_scheduler::suspend_callback_t)suspend_callback, user_callback, &s }; + target.set_post_resume_action(generic_scheduler::PRA_CALLBACK, &callback); + s.resume(target); +} + +void internal_resume(task::suspend_point tag) { + generic_scheduler& s = *static_cast<generic_scheduler*>(tag); + task* t = new(&s.allocate_task(sizeof(resume_task), __TBB_CONTEXT_ARG(NULL, s.my_dummy_task->context()))) resume_task(s); + make_critical(*t); + + // TODO: remove this work-around + // Prolong the arena's lifetime until all coroutines is alive + // (otherwise the arena can be destroyed while some tasks are suspended). + arena& a = *s.my_arena; + a.my_references += arena::ref_external; + + a.my_critical_task_stream.push(t, 0, tbb::internal::random_lane_selector(s.my_random)); + // Do not access 's' after that point. + a.advertise_new_work<arena::work_spawned>(); + + // Release our reference to my_arena. + a.on_thread_leaving<arena::ref_external>(); +} + +task::suspend_point internal_current_suspend_point() { + return governor::local_scheduler(); +} +#endif /* __TBB_PREVIEW_RESUMABLE_TASKS */ + +} // namespace internal +} // namespace tbb + +#include "scheduler_utility.h" +#include "tbb/task_arena.h" // task_arena_base + +namespace tbb { +namespace interface7 { +namespace internal { + +void task_arena_base::internal_initialize( ) { + governor::one_time_init(); + if( my_max_concurrency < 1 ) +#if __TBB_NUMA_SUPPORT + my_max_concurrency = tbb::internal::numa_topology::default_concurrency(numa_id()); +#else /*__TBB_NUMA_SUPPORT*/ + my_max_concurrency = (int)governor::default_num_threads(); +#endif /*__TBB_NUMA_SUPPORT*/ + __TBB_ASSERT( my_master_slots <= (unsigned)my_max_concurrency, "Number of slots reserved for master should not exceed arena concurrency"); + arena* new_arena = market::create_arena( my_max_concurrency, my_master_slots, 0 ); + // add an internal market reference; a public reference was added in create_arena + market &m = market::global_market( /*is_public=*/false ); + // allocate default context for task_arena +#if __TBB_TASK_GROUP_CONTEXT + new_arena->my_default_ctx = new ( NFS_Allocate(1, sizeof(task_group_context), NULL) ) + task_group_context( task_group_context::isolated, task_group_context::default_traits ); +#if __TBB_FP_CONTEXT + new_arena->my_default_ctx->capture_fp_settings(); +#endif +#endif /* __TBB_TASK_GROUP_CONTEXT */ + // threads might race to initialize the arena + if(as_atomic(my_arena).compare_and_swap(new_arena, NULL) != NULL) { + __TBB_ASSERT(my_arena, NULL); // another thread won the race + // release public market reference + m.release( /*is_public=*/true, /*blocking_terminate=*/false ); + new_arena->on_thread_leaving<arena::ref_external>(); // destroy unneeded arena +#if __TBB_TASK_GROUP_CONTEXT + spin_wait_while_eq(my_context, (task_group_context*)NULL); +#endif /*__TBB_TASK_GROUP_CONTEXT*/ +#if __TBB_TASK_GROUP_CONTEXT || __TBB_NUMA_SUPPORT + } else { +#if __TBB_NUMA_SUPPORT + my_arena->my_numa_binding_observer = tbb::internal::construct_binding_observer( + static_cast<task_arena*>(this), numa_id(), my_arena->my_num_slots); +#endif /*__TBB_NUMA_SUPPORT*/ +#if __TBB_TASK_GROUP_CONTEXT + new_arena->my_default_ctx->my_version_and_traits |= my_version_and_traits & exact_exception_flag; + as_atomic(my_context) = new_arena->my_default_ctx; +#endif /*__TBB_TASK_GROUP_CONTEXT*/ + } +#endif /*__TBB_TASK_GROUP_CONTEXT || __TBB_NUMA_SUPPORT*/ + + // TODO: should it trigger automatic initialization of this thread? + governor::local_scheduler_weak(); +} + +void task_arena_base::internal_terminate( ) { + if( my_arena ) {// task_arena was initialized +#if __TBB_NUMA_SUPPORT + if( my_arena->my_numa_binding_observer != NULL ) { + tbb::internal::destroy_binding_observer(my_arena->my_numa_binding_observer); + my_arena->my_numa_binding_observer = NULL; + } +#endif /*__TBB_NUMA_SUPPORT*/ + my_arena->my_market->release( /*is_public=*/true, /*blocking_terminate=*/false ); + my_arena->on_thread_leaving<arena::ref_external>(); + my_arena = 0; +#if __TBB_TASK_GROUP_CONTEXT + my_context = 0; +#endif + } +} + +void task_arena_base::internal_attach( ) { + __TBB_ASSERT(!my_arena, NULL); + generic_scheduler* s = governor::local_scheduler_if_initialized(); + if( s && s->my_arena ) { + // There is an active arena to attach to. + // It's still used by s, so won't be destroyed right away. + my_arena = s->my_arena; + __TBB_ASSERT( my_arena->my_references > 0, NULL ); + my_arena->my_references += arena::ref_external; +#if __TBB_TASK_GROUP_CONTEXT + my_context = my_arena->my_default_ctx; + my_version_and_traits |= my_context->my_version_and_traits & exact_exception_flag; +#endif + my_master_slots = my_arena->my_num_reserved_slots; + my_max_concurrency = my_master_slots + my_arena->my_max_num_workers; + __TBB_ASSERT(arena::num_arena_slots(my_max_concurrency)==my_arena->my_num_slots, NULL); + // increases market's ref count for task_arena + market::global_market( /*is_public=*/true ); + } +} + +void task_arena_base::internal_enqueue( task& t, intptr_t prio ) const { + __TBB_ASSERT(my_arena, NULL); + generic_scheduler* s = governor::local_scheduler_weak(); // scheduler is only needed for FastRandom instance + __TBB_ASSERT(s, "Scheduler is not initialized"); // we allocated a task so can expect the scheduler +#if __TBB_TASK_GROUP_CONTEXT + // Is there a better place for checking the state of my_default_ctx? + __TBB_ASSERT(!(my_arena->my_default_ctx == t.prefix().context && my_arena->my_default_ctx->is_group_execution_cancelled()), + "The task will not be executed because default task_group_context of task_arena is cancelled. Has previously enqueued task thrown an exception?"); +#endif + my_arena->enqueue_task( t, prio, s->my_random ); +} + +class delegated_task : public task { + internal::delegate_base & my_delegate; + concurrent_monitor & my_monitor; + task * my_root; + task* execute() __TBB_override { + generic_scheduler& s = *(generic_scheduler*)prefix().owner; + __TBB_ASSERT(s.outermost_level(), "expected to be enqueued and received on the outermost level"); + struct outermost_context : internal::no_copy { + delegated_task * t; + generic_scheduler & s; + task * orig_dummy; + task_group_context * orig_ctx; + scheduler_properties orig_props; + outermost_context(delegated_task *_t, generic_scheduler &_s) + : t(_t), s(_s), orig_dummy(s.my_dummy_task), orig_props(s.my_properties) { + __TBB_ASSERT(s.my_innermost_running_task == t, NULL); +#if __TBB_TASK_GROUP_CONTEXT + orig_ctx = t->prefix().context; + t->prefix().context = s.my_arena->my_default_ctx; +#endif + // Mimics outermost master + s.my_dummy_task = t; + s.my_properties.type = scheduler_properties::master; + } + ~outermost_context() { +#if __TBB_TASK_GROUP_CONTEXT + // Restore context for sake of registering potential exception + t->prefix().context = orig_ctx; +#endif + // Restore scheduler state + s.my_properties = orig_props; + s.my_dummy_task = orig_dummy; + } + } scope(this, s); + my_delegate(); + return NULL; + } + ~delegated_task() { + // potential exception was already registered. It must happen before the notification + __TBB_ASSERT(my_root->ref_count() == 2, NULL); + task_prefix& prefix = my_root->prefix(); +#if __TBB_PREVIEW_RESUMABLE_TASKS + reference_count old_ref_count = __TBB_FetchAndStoreW(&prefix.ref_count, 1); + // Check if the scheduler was abandoned. + if (old_ref_count == internal::abandon_flag + 2) { + __TBB_ASSERT(prefix.abandoned_scheduler, NULL); + // The wait has been completed. Spawn a resume task. + tbb::task::resume(prefix.abandoned_scheduler); + } +#else + __TBB_store_with_release(prefix.ref_count, 1); // must precede the wakeup +#endif + my_monitor.notify(*this); // do not relax, it needs a fence! + } +public: + delegated_task( internal::delegate_base & d, concurrent_monitor & s, task * t ) + : my_delegate(d), my_monitor(s), my_root(t) {} + // predicate for concurrent_monitor notification + bool operator()(uintptr_t ctx) const { return (void*)ctx == (void*)&my_delegate; } +}; + +void task_arena_base::internal_execute(internal::delegate_base& d) const { + __TBB_ASSERT(my_arena, NULL); + generic_scheduler* s = governor::local_scheduler_weak(); + __TBB_ASSERT(s, "Scheduler is not initialized"); + + bool same_arena = s->my_arena == my_arena; + size_t index1 = s->my_arena_index; + if (!same_arena) { + index1 = my_arena->occupy_free_slot</* as_worker*/false>(*s); + if (index1 == arena::out_of_arena) { + +#if __TBB_USE_OPTIONAL_RTTI + // Workaround for the bug inside graph. If the thread can not occupy arena slot during task_arena::execute() + // and all aggregator operations depend on this task completion (all other threads are inside arena already) + // deadlock appears, because enqueued task will never enter arena. + // Workaround: check if the task came from graph via RTTI (casting to graph::spawn_functor) + // and enqueue this task with non-blocking internal_enqueue method. + // TODO: have to change behaviour later in next GOLD release (maybe to add new library entry point - try_execute) + typedef tbb::flow::interface10::graph::spawn_functor graph_funct; + internal::delegated_function< graph_funct, void >* deleg_funct = + dynamic_cast< internal::delegated_function< graph_funct, void>* >(&d); + + if (deleg_funct) { + internal_enqueue(*new(task::allocate_root(__TBB_CONTEXT_ARG1(*my_context))) + internal::function_task< internal::strip< graph_funct >::type > + (internal::forward< graph_funct >(deleg_funct->my_func)), 0); + return; + } else { +#endif /* __TBB_USE_OPTIONAL_RTTI */ + concurrent_monitor::thread_context waiter; +#if __TBB_TASK_GROUP_CONTEXT + task_group_context exec_context(task_group_context::isolated, my_version_and_traits & exact_exception_flag); +#if __TBB_FP_CONTEXT + exec_context.copy_fp_settings(*my_context); +#endif +#endif + auto_empty_task root(__TBB_CONTEXT_ARG(s, &exec_context)); + root.prefix().ref_count = 2; + my_arena->enqueue_task(*new(task::allocate_root(__TBB_CONTEXT_ARG1(exec_context))) + delegated_task(d, my_arena->my_exit_monitors, &root), + 0, s->my_random); // TODO: priority? + size_t index2 = arena::out_of_arena; + do { + my_arena->my_exit_monitors.prepare_wait(waiter, (uintptr_t)&d); + if (__TBB_load_with_acquire(root.prefix().ref_count) < 2) { + my_arena->my_exit_monitors.cancel_wait(waiter); + break; + } + index2 = my_arena->occupy_free_slot</*as_worker*/false>(*s); + if (index2 != arena::out_of_arena) { + my_arena->my_exit_monitors.cancel_wait(waiter); + nested_arena_context scope(s, my_arena, index2, scheduler_properties::master, same_arena); + s->local_wait_for_all(root, NULL); +#if TBB_USE_EXCEPTIONS + __TBB_ASSERT(!exec_context.my_exception, NULL); // exception can be thrown above, not deferred +#endif + __TBB_ASSERT(root.prefix().ref_count == 0, NULL); + break; + } + my_arena->my_exit_monitors.commit_wait(waiter); + } while (__TBB_load_with_acquire(root.prefix().ref_count) == 2); + if (index2 == arena::out_of_arena) { + // notify a waiting thread even if this thread did not enter arena, + // in case it was woken by a leaving thread but did not need to enter + my_arena->my_exit_monitors.notify_one(); // do not relax! + } +#if TBB_USE_EXCEPTIONS + // process possible exception + if (task_group_context::exception_container_type *pe = exec_context.my_exception) + TbbRethrowException(pe); +#endif + return; +#if __TBB_USE_OPTIONAL_RTTI + } // if task came from graph +#endif + } // if (index1 == arena::out_of_arena) + } // if (!same_arena) + + context_guard_helper</*report_tasks=*/false> context_guard; + context_guard.set_ctx(__TBB_CONTEXT_ARG1(my_context)); +#if TBB_USE_EXCEPTIONS + try { +#endif + //TODO: replace dummy tasks for workers as well to avoid using of the_dummy_context + nested_arena_context scope(s, my_arena, index1, scheduler_properties::master, same_arena); + d(); +#if TBB_USE_EXCEPTIONS + } + catch (...) { + context_guard.restore_default(); // TODO: is it needed on Windows? + if (my_version_and_traits & exact_exception_flag) throw; + else { + task_group_context exception_container(task_group_context::isolated, + task_group_context::default_traits & ~task_group_context::exact_exception); + exception_container.register_pending_exception(); + __TBB_ASSERT(exception_container.my_exception, NULL); + TbbRethrowException(exception_container.my_exception); + } + } +#endif +} + +// this wait task is a temporary approach to wait for arena emptiness for masters without slots +// TODO: it will be rather reworked for one source of notification from is_out_of_work +class wait_task : public task { + binary_semaphore & my_signal; + task* execute() __TBB_override { + generic_scheduler* s = governor::local_scheduler_if_initialized(); + __TBB_ASSERT( s, NULL ); + __TBB_ASSERT( s->outermost_level(), "The enqueued task can be processed only on outermost level" ); + if ( s->is_worker() ) { + __TBB_ASSERT( s->my_innermost_running_task == this, NULL ); + // Mimic worker on outermost level to run remaining tasks + s->my_innermost_running_task = s->my_dummy_task; + s->local_wait_for_all( *s->my_dummy_task, NULL ); + s->my_innermost_running_task = this; + } else s->my_arena->is_out_of_work(); // avoids starvation of internal_wait: issuing this task makes arena full + my_signal.V(); + return NULL; + } +public: + wait_task ( binary_semaphore & sema ) : my_signal(sema) {} +}; + +void task_arena_base::internal_wait() const { + __TBB_ASSERT(my_arena, NULL); + generic_scheduler* s = governor::local_scheduler_weak(); + __TBB_ASSERT(s, "Scheduler is not initialized"); + __TBB_ASSERT(s->my_arena != my_arena || s->my_arena_index == 0, "task_arena::wait_until_empty() is not supported within a worker context" ); + if( s->my_arena == my_arena ) { + //unsupported, but try do something for outermost master + __TBB_ASSERT(s->master_outermost_level(), "unsupported"); + if( !s->my_arena_index ) + while( my_arena->num_workers_active() ) + s->wait_until_empty(); + } else for(;;) { + while( my_arena->my_pool_state != arena::SNAPSHOT_EMPTY ) { + if( !__TBB_load_with_acquire(my_arena->my_slots[0].my_scheduler) // TODO TEMP: one master, make more masters + && as_atomic(my_arena->my_slots[0].my_scheduler).compare_and_swap(s, NULL) == NULL ) { + nested_arena_context a(s, my_arena, 0, scheduler_properties::worker, false); + s->wait_until_empty(); + } else { + binary_semaphore waiter; // TODO: replace by a single event notification from is_out_of_work + internal_enqueue( *new( task::allocate_root(__TBB_CONTEXT_ARG1(*my_context)) ) wait_task(waiter), 0 ); // TODO: priority? + waiter.P(); // TODO: concurrent_monitor + } + } + if( !my_arena->num_workers_active() && !my_arena->my_slots[0].my_scheduler) // no activity + break; // spin until workers active but avoid spinning in a worker + __TBB_Yield(); // wait until workers and master leave + } +} + +/*static*/ int task_arena_base::internal_current_slot() { + generic_scheduler* s = governor::local_scheduler_if_initialized(); + return s? int(s->my_arena_index) : -1; +} + +#if __TBB_TASK_ISOLATION +class isolation_guard : tbb::internal::no_copy { + isolation_tag &guarded; + isolation_tag previous_value; +public: + isolation_guard( isolation_tag &isolation ) : guarded( isolation ), previous_value( isolation ) {} + ~isolation_guard() { + guarded = previous_value; + } +}; + +void isolate_within_arena( delegate_base& d, intptr_t isolation ) { + // TODO: Decide what to do if the scheduler is not initialized. Is there a use case for it? + generic_scheduler* s = governor::local_scheduler_weak(); + __TBB_ASSERT( s, "this_task_arena::isolate() needs an initialized scheduler" ); + // Theoretically, we can keep the current isolation in the scheduler; however, it makes sense to store it in innermost + // running task because it can in principle be queried via task::self(). + isolation_tag& current_isolation = s->my_innermost_running_task->prefix().isolation; + // We temporarily change the isolation tag of the currently running task. It will be restored in the destructor of the guard. + isolation_guard guard( current_isolation ); + current_isolation = isolation? isolation : reinterpret_cast<isolation_tag>(&d); + d(); +} +#endif /* __TBB_TASK_ISOLATION */ + +int task_arena_base::internal_max_concurrency(const task_arena *ta) { + arena* a = NULL; + if( ta ) // for special cases of ta->max_concurrency() + a = ta->my_arena; + else if( generic_scheduler* s = governor::local_scheduler_if_initialized() ) + a = s->my_arena; // the current arena if any + + if( a ) { // Get parameters from the arena + __TBB_ASSERT( !ta || ta->my_max_concurrency==1, NULL ); + return a->my_num_reserved_slots + a->my_max_num_workers; + } else { + __TBB_ASSERT( !ta || ta->my_max_concurrency==automatic, NULL ); + return int(governor::default_num_threads()); + } +} +} // tbb::interfaceX::internal +} // tbb::interfaceX +} // tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/arena.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/arena.h new file mode 100644 index 00000000..a24aba86 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/arena.h @@ -0,0 +1,556 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_arena_H +#define _TBB_arena_H + +#include "tbb/tbb_stddef.h" +#include "tbb/atomic.h" + +#include "tbb/tbb_machine.h" + +#include "scheduler_common.h" +#include "intrusive_list.h" +#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_CPF_BUILD +#include "task_stream_extended.h" +#else +#include "task_stream.h" +#endif +#include "../rml/include/rml_tbb.h" +#include "mailbox.h" +#include "observer_proxy.h" +#include "market.h" +#include "governor.h" +#include "concurrent_monitor.h" + +#if __TBB_PREVIEW_RESUMABLE_TASKS +#include "tbb/spin_mutex.h" +#endif + +namespace tbb { + +class task_group_context; +class allocate_root_with_context_proxy; + +namespace internal { + +#if __TBB_NUMA_SUPPORT +class numa_binding_observer; +#endif /*__TBB_NUMA_SUPPORT*/ + +#if __TBB_PREVIEW_RESUMABLE_TASKS +//! Bounded coroutines cache LIFO ring buffer +class arena_co_cache { + //! Ring buffer storage + generic_scheduler** my_co_scheduler_cache; + //! Current cache index + unsigned my_head; + //! Cache capacity for arena + unsigned my_max_index; + //! Accessor lock for modification operations + tbb::spin_mutex my_co_cache_mutex; + + unsigned next_index() { + return ( my_head == my_max_index ) ? 0 : my_head + 1; + } + + unsigned prev_index() { + return ( my_head == 0 ) ? my_max_index : my_head - 1; + } + + bool internal_empty() { + return my_co_scheduler_cache[prev_index()] == NULL; + } + + void internal_scheduler_cleanup(generic_scheduler* to_cleanup) { + to_cleanup->my_arena_slot = NULL; + // Needed by cleanup_worker function, as well as arena slot clearing + governor::assume_scheduler(to_cleanup); + generic_scheduler::cleanup_worker(to_cleanup, true); + } + +public: + void init(unsigned cache_capacity) { + size_t alloc_size = cache_capacity * sizeof(generic_scheduler*); + my_co_scheduler_cache = (generic_scheduler**)NFS_Allocate(1, alloc_size, NULL); + memset( my_co_scheduler_cache, 0, alloc_size ); + my_head = 0; + my_max_index = cache_capacity - 1; + } + + void cleanup() { + generic_scheduler* current = governor::local_scheduler_if_initialized(); + while (generic_scheduler* to_cleanup = pop()) { + internal_scheduler_cleanup(to_cleanup); + } + governor::assume_scheduler(current); + NFS_Free(my_co_scheduler_cache); + } + + //! Insert scheduler to the current available place. + //! Replace an old value, if necessary. + void push(generic_scheduler* s) { + generic_scheduler* to_cleanup = NULL; + { + tbb::spin_mutex::scoped_lock lock(my_co_cache_mutex); + // Check if we are replacing some existing buffer entrance + if (my_co_scheduler_cache[my_head] != NULL) { + to_cleanup = my_co_scheduler_cache[my_head]; + } + // Store the cached value + my_co_scheduler_cache[my_head] = s; + // Move head index to the next slot + my_head = next_index(); + } + // Cleanup replaced buffer if any + if (to_cleanup) { + generic_scheduler* current = governor::local_scheduler_if_initialized(); + internal_scheduler_cleanup(to_cleanup); + governor::assume_scheduler(current); + } + } + + //! Get a cached scheduler if any + generic_scheduler* pop() { + tbb::spin_mutex::scoped_lock lock(my_co_cache_mutex); + // No cached coroutine + if (internal_empty()) return NULL; + // Move head index to the currently available value + my_head = prev_index(); + // Retrieve the value from the buffer + generic_scheduler* to_return = my_co_scheduler_cache[my_head]; + // Clear the previous entrance value + my_co_scheduler_cache[my_head] = NULL; + return to_return; + } +}; +#endif // __TBB_PREVIEW_RESUMABLE_TASKS + +//! The structure of an arena, except the array of slots. +/** Separated in order to simplify padding. + Intrusive list node base class is used by market to form a list of arenas. **/ +struct arena_base : padded<intrusive_list_node> { + //! The number of workers that have been marked out by the resource manager to service the arena. + unsigned my_num_workers_allotted; // heavy use in stealing loop + + //! Reference counter for the arena. + /** Worker and master references are counted separately: first several bits are for references + from master threads or explicit task_arenas (see arena::ref_external_bits below); + the rest counts the number of workers servicing the arena. */ + atomic<unsigned> my_references; // heavy use in stealing loop + +#if __TBB_TASK_PRIORITY + //! The highest priority of recently spawned or enqueued tasks. + volatile intptr_t my_top_priority; // heavy use in stealing loop +#endif /* !__TBB_TASK_PRIORITY */ + + //! The maximal number of currently busy slots. + atomic<unsigned> my_limit; // heavy use in stealing loop + + //! Task pool for the tasks scheduled via task::enqueue() method. + /** Such scheduling guarantees eventual execution even if + - new tasks are constantly coming (by extracting scheduled tasks in + relaxed FIFO order); + - the enqueuing thread does not call any of wait_for_all methods. + Depending on __TBB_TASK_PRIORITY, num_priority_levels can be 1 or more. **/ +#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_CPF_BUILD + task_stream<num_priority_levels, front_accessor> my_task_stream; // heavy use in stealing loop +#else + task_stream<num_priority_levels> my_task_stream; // heavy use in stealing loop +#endif + +#if __TBB_PREVIEW_CRITICAL_TASKS + //! Task pool for the tasks with critical property set. + /** Critical tasks are scheduled for execution ahead of other sources (including local task pool + and even bypassed tasks) unless the thread already executes a critical task in an outer + dispatch loop **/ + // used on the hot path of the task dispatch loop + task_stream<1, back_nonnull_accessor> my_critical_task_stream; +#endif + + //! The number of workers requested by the master thread owning the arena. + unsigned my_max_num_workers; + + //! The number of workers that are currently requested from the resource manager. + int my_num_workers_requested; + + //! Current task pool state and estimate of available tasks amount. + /** The estimate is either 0 (SNAPSHOT_EMPTY) or infinity (SNAPSHOT_FULL). + Special state is "busy" (any other unsigned value). + Note that the implementation of arena::is_busy_or_empty() requires + my_pool_state to be unsigned. */ + tbb::atomic<uintptr_t> my_pool_state; + +#if __TBB_ARENA_OBSERVER + //! The list of local observers attached to this arena. + observer_list my_observers; +#endif + +#if __TBB_NUMA_SUPPORT + //! Pointer to internal observer that allows to bind threads in arena to certain NUMA node. + numa_binding_observer* my_numa_binding_observer; +#endif /*__TBB_NUMA_SUPPORT*/ + +#if __TBB_TASK_PRIORITY + //! The lowest normalized priority of available spawned or enqueued tasks. + intptr_t my_bottom_priority; + + //! Tracks events that may bring tasks in offload areas to the top priority level. + /** Incremented when arena top priority changes or a task group priority + is elevated to the current arena's top level. **/ + uintptr_t my_reload_epoch; + + //! The list of offloaded tasks abandoned by workers revoked by the market. + task* my_orphaned_tasks; + + //! Counter used to track the occurrence of recent orphaning and re-sharing operations. + tbb::atomic<uintptr_t> my_abandonment_epoch; + + //! The highest priority level containing enqueued tasks. + /** It being greater than 0 means that high priority enqueued tasks had to be + bypassed because all workers were blocked in nested dispatch loops and + were unable to progress at then current priority level. **/ + tbb::atomic<intptr_t> my_skipped_fifo_priority; +#endif /* !__TBB_TASK_PRIORITY */ + + // Below are rarely modified members + + //! The market that owns this arena. + market* my_market; + + //! ABA prevention marker. + uintptr_t my_aba_epoch; + +#if !__TBB_FP_CONTEXT + //! FPU control settings of arena's master thread captured at the moment of arena instantiation. + cpu_ctl_env my_cpu_ctl_env; +#endif + +#if __TBB_TASK_GROUP_CONTEXT + //! Default task group context. + /** Used by root tasks allocated directly by the master thread (not from inside + a TBB task) without explicit context specification. **/ + task_group_context* my_default_ctx; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + //! The number of slots in the arena. + unsigned my_num_slots; + + //! The number of reserved slots (can be occupied only by masters). + unsigned my_num_reserved_slots; + +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + // arena needs an extra worker despite the arena limit + bool my_local_concurrency_mode; + // arena needs an extra worker despite a global limit + bool my_global_concurrency_mode; +#endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ + + //! Waiting object for master threads that cannot join the arena. + concurrent_monitor my_exit_monitors; + +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! Coroutines cache buffer + arena_co_cache my_co_cache; +#endif + +#if TBB_USE_ASSERT + //! Used to trap accesses to the object after its destruction. + uintptr_t my_guard; +#endif /* TBB_USE_ASSERT */ +}; // struct arena_base + +class arena: public padded<arena_base> +{ + //! If enqueued tasks found, restore arena priority and task presence status + void restore_priority_if_need(); +public: + typedef padded<arena_base> base_type; + + //! Types of work advertised by advertise_new_work() + enum new_work_type { + work_spawned, + wakeup, + work_enqueued + }; + + //! Constructor + arena ( market&, unsigned max_num_workers, unsigned num_reserved_slots ); + + //! Allocate an instance of arena. + static arena& allocate_arena( market&, unsigned num_slots, unsigned num_reserved_slots ); + + static int unsigned num_arena_slots ( unsigned num_slots ) { + return max(2u, num_slots); + } + + static int allocation_size ( unsigned num_slots ) { + return sizeof(base_type) + num_slots * (sizeof(mail_outbox) + sizeof(arena_slot)); + } + + //! Get reference to mailbox corresponding to given affinity_id. + mail_outbox& mailbox( affinity_id id ) { + __TBB_ASSERT( 0<id, "affinity id must be positive integer" ); + __TBB_ASSERT( id <= my_num_slots, "affinity id out of bounds" ); + + return ((mail_outbox*)this)[-(int)id]; + } + + //! Completes arena shutdown, destructs and deallocates it. + void free_arena (); + + typedef uintptr_t pool_state_t; + + //! No tasks to steal since last snapshot was taken + static const pool_state_t SNAPSHOT_EMPTY = 0; + + //! At least one task has been offered for stealing since the last snapshot started + static const pool_state_t SNAPSHOT_FULL = pool_state_t(-1); + + //! The number of least significant bits for external references + static const unsigned ref_external_bits = 12; // up to 4095 external and 1M workers + + //! Reference increment values for externals and workers + static const unsigned ref_external = 1; + static const unsigned ref_worker = 1<<ref_external_bits; + + //! No tasks to steal or snapshot is being taken. + static bool is_busy_or_empty( pool_state_t s ) { return s < SNAPSHOT_FULL; } + + //! The number of workers active in the arena. + unsigned num_workers_active() const { + return my_references >> ref_external_bits; + } + + //! Check if the recall is requested by the market. + bool is_recall_requested() const { + return num_workers_active() > my_num_workers_allotted; + } + + //! If necessary, raise a flag that there is new job in arena. + template<arena::new_work_type work_type> void advertise_new_work(); + + //! Check if there is job anywhere in arena. + /** Return true if no job or if arena is being cleaned up. */ + bool is_out_of_work(); + + //! enqueue a task into starvation-resistance queue + void enqueue_task( task&, intptr_t, FastRandom & ); + + //! Registers the worker with the arena and enters TBB scheduler dispatch loop + void process( generic_scheduler& ); + + //! Notification that worker or master leaves its arena + template<unsigned ref_param> + inline void on_thread_leaving ( ); + +#if __TBB_STATISTICS + //! Outputs internal statistics accumulated by the arena + void dump_arena_statistics (); +#endif /* __TBB_STATISTICS */ + +#if __TBB_TASK_PRIORITY + //! Check if recent priority changes may bring some tasks to the current priority level soon + /** /param tasks_present indicates presence of tasks at any priority level. **/ + inline bool may_have_tasks ( generic_scheduler*, bool& tasks_present, bool& dequeuing_possible ); + + //! Puts offloaded tasks into global list of orphaned tasks + void orphan_offloaded_tasks ( generic_scheduler& s ); +#endif /* __TBB_TASK_PRIORITY */ + +#if __TBB_COUNT_TASK_NODES + //! Returns the number of task objects "living" in worker threads + intptr_t workers_task_node_count(); +#endif + + //! Check for the presence of enqueued tasks at all priority levels + bool has_enqueued_tasks(); + + static const size_t out_of_arena = ~size_t(0); + //! Tries to occupy a slot in the arena. On success, returns the slot index; if no slot is available, returns out_of_arena. + template <bool as_worker> + size_t occupy_free_slot( generic_scheduler& s ); + //! Tries to occupy a slot in the specified range. + size_t occupy_free_slot_in_range( generic_scheduler& s, size_t lower, size_t upper ); + + /** Must be the last data field */ + arena_slot my_slots[1]; +}; // class arena + +template<unsigned ref_param> +inline void arena::on_thread_leaving ( ) { + // + // Implementation of arena destruction synchronization logic contained various + // bugs/flaws at the different stages of its evolution, so below is a detailed + // description of the issues taken into consideration in the framework of the + // current design. + // + // In case of using fire-and-forget tasks (scheduled via task::enqueue()) + // master thread is allowed to leave its arena before all its work is executed, + // and market may temporarily revoke all workers from this arena. Since revoked + // workers never attempt to reset arena state to EMPTY and cancel its request + // to RML for threads, the arena object is destroyed only when both the last + // thread is leaving it and arena's state is EMPTY (that is its master thread + // left and it does not contain any work). + // Thus resetting arena to EMPTY state (as earlier TBB versions did) should not + // be done here (or anywhere else in the master thread to that matter); doing so + // can result either in arena's premature destruction (at least without + // additional costly checks in workers) or in unnecessary arena state changes + // (and ensuing workers migration). + // + // A worker that checks for work presence and transitions arena to the EMPTY + // state (in snapshot taking procedure arena::is_out_of_work()) updates + // arena::my_pool_state first and only then arena::my_num_workers_requested. + // So the check for work absence must be done against the latter field. + // + // In a time window between decrementing the active threads count and checking + // if there is an outstanding request for workers. New worker thread may arrive, + // finish remaining work, set arena state to empty, and leave decrementing its + // refcount and destroying. Then the current thread will destroy the arena + // the second time. To preclude it a local copy of the outstanding request + // value can be stored before decrementing active threads count. + // + // But this technique may cause two other problem. When the stored request is + // zero, it is possible that arena still has threads and they can generate new + // tasks and thus re-establish non-zero requests. Then all the threads can be + // revoked (as described above) leaving this thread the last one, and causing + // it to destroy non-empty arena. + // + // The other problem takes place when the stored request is non-zero. Another + // thread may complete the work, set arena state to empty, and leave without + // arena destruction before this thread decrements the refcount. This thread + // cannot destroy the arena either. Thus the arena may be "orphaned". + // + // In both cases we cannot dereference arena pointer after the refcount is + // decremented, as our arena may already be destroyed. + // + // If this is the master thread, the market is protected by refcount to it. + // In case of workers market's liveness is ensured by the RML connection + // rundown protocol, according to which the client (i.e. the market) lives + // until RML server notifies it about connection termination, and this + // notification is fired only after all workers return into RML. + // + // Thus if we decremented refcount to zero we ask the market to check arena + // state (including the fact if it is alive) under the lock. + // + uintptr_t aba_epoch = my_aba_epoch; + market* m = my_market; + __TBB_ASSERT(my_references >= ref_param, "broken arena reference counter"); +#if __TBB_STATISTICS_EARLY_DUMP + // While still holding a reference to the arena, compute how many external references are left. + // If just one, dump statistics. + if ( modulo_power_of_two(my_references,ref_worker)==ref_param ) // may only be true with ref_external + GATHER_STATISTIC( dump_arena_statistics() ); +#endif +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + // When there is no workers someone must free arena, as + // without workers, no one calls is_out_of_work(). + // Skip workerless arenas because they have no demand for workers. + // TODO: consider more strict conditions for the cleanup, + // because it can create the demand of workers, + // but the arena can be already empty (and so ready for destroying) + // TODO: Fix the race: while we check soft limit and it might be changed. + if( ref_param==ref_external && my_num_slots != my_num_reserved_slots + && 0 == m->my_num_workers_soft_limit && !my_global_concurrency_mode ) { + bool is_out = false; + for (int i=0; i<num_priority_levels; i++) { + is_out = is_out_of_work(); + if (is_out) + break; + } + // We expect, that in worst case it's enough to have num_priority_levels-1 + // calls to restore priorities and yet another is_out_of_work() to conform + // that no work was found. But as market::set_active_num_workers() can be called + // concurrently, can't guarantee last is_out_of_work() return true. + } +#endif + if ( (my_references -= ref_param ) == 0 ) + m->try_destroy_arena( this, aba_epoch ); +} + +template<arena::new_work_type work_type> void arena::advertise_new_work() { + if( work_type == work_enqueued ) { +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + if ( as_atomic(my_market->my_num_workers_soft_limit) == 0 && as_atomic(my_global_concurrency_mode) == false ) + my_market->enable_mandatory_concurrency(this); + + if ( my_max_num_workers == 0 && my_num_reserved_slots == 1 ) { + __TBB_ASSERT(!my_local_concurrency_mode, NULL); + my_local_concurrency_mode = true; + my_pool_state = SNAPSHOT_FULL; + my_max_num_workers = 1; + my_market->adjust_demand(*this, my_max_num_workers); + return; + } +#endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ + // Local memory fence here and below is required to avoid missed wakeups; see the comment below. + // Starvation resistant tasks require concurrency, so missed wakeups are unacceptable. + atomic_fence(); + } + else if( work_type == wakeup ) { + __TBB_ASSERT(my_max_num_workers!=0, "Unexpected worker wakeup request"); + atomic_fence(); + } + // Double-check idiom that, in case of spawning, is deliberately sloppy about memory fences. + // Technically, to avoid missed wakeups, there should be a full memory fence between the point we + // released the task pool (i.e. spawned task) and read the arena's state. However, adding such a + // fence might hurt overall performance more than it helps, because the fence would be executed + // on every task pool release, even when stealing does not occur. Since TBB allows parallelism, + // but never promises parallelism, the missed wakeup is not a correctness problem. + pool_state_t snapshot = my_pool_state; + if( is_busy_or_empty(snapshot) ) { + // Attempt to mark as full. The compare_and_swap below is a little unusual because the + // result is compared to a value that can be different than the comparand argument. + if( my_pool_state.compare_and_swap( SNAPSHOT_FULL, snapshot )==SNAPSHOT_EMPTY ) { + if( snapshot!=SNAPSHOT_EMPTY ) { + // This thread read "busy" into snapshot, and then another thread transitioned + // my_pool_state to "empty" in the meantime, which caused the compare_and_swap above + // to fail. Attempt to transition my_pool_state from "empty" to "full". + if( my_pool_state.compare_and_swap( SNAPSHOT_FULL, SNAPSHOT_EMPTY )!=SNAPSHOT_EMPTY ) { + // Some other thread transitioned my_pool_state from "empty", and hence became + // responsible for waking up workers. + return; + } + } + // This thread transitioned pool from empty to full state, and thus is responsible for + // telling the market that there is work to do. +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + if( work_type == work_spawned ) { + if( my_local_concurrency_mode ) { + __TBB_ASSERT(my_max_num_workers==1, ""); + __TBB_ASSERT(!governor::local_scheduler()->is_worker(), ""); + // There was deliberate oversubscription on 1 core for sake of starvation-resistant tasks. + // Now a single active thread (must be the master) supposedly starts a new parallel region + // with relaxed sequential semantics, and oversubscription should be avoided. + // Demand for workers has been decreased to 0 during SNAPSHOT_EMPTY, so just keep it. + my_max_num_workers = 0; + my_local_concurrency_mode = false; + return; + } + if ( as_atomic(my_global_concurrency_mode) == true ) + my_market->mandatory_concurrency_disable( this ); + } +#endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ + // TODO: investigate adjusting of arena's demand by a single worker. + my_market->adjust_demand( *this, my_max_num_workers ); + } + } +} + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_arena_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/cache_aligned_allocator.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/cache_aligned_allocator.cpp new file mode 100644 index 00000000..4267014b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/cache_aligned_allocator.cpp @@ -0,0 +1,252 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/tbb_allocator.h" +#include "tbb/tbb_exception.h" +#include "tbb_misc.h" +#include "dynamic_link.h" +#include <cstdlib> + +#if _WIN32||_WIN64 +#include "tbb/machine/windows_api.h" +#else +#include <dlfcn.h> +#endif /* _WIN32||_WIN64 */ + +#if __TBB_WEAK_SYMBOLS_PRESENT + +#pragma weak scalable_malloc +#pragma weak scalable_free +#pragma weak scalable_aligned_malloc +#pragma weak scalable_aligned_free + +extern "C" { + void* scalable_malloc( size_t ); + void scalable_free( void* ); + void* scalable_aligned_malloc( size_t, size_t ); + void scalable_aligned_free( void* ); +} + +#endif /* __TBB_WEAK_SYMBOLS_PRESENT */ + +namespace tbb { + +namespace internal { + +//! Dummy routine used for first indirect call via MallocHandler. +static void* DummyMalloc( size_t size ); + +//! Dummy routine used for first indirect call via FreeHandler. +static void DummyFree( void * ptr ); + +//! Handler for memory allocation +static void* (*MallocHandler)( size_t size ) = &DummyMalloc; + +//! Handler for memory deallocation +static void (*FreeHandler)( void* pointer ) = &DummyFree; + +//! Dummy routine used for first indirect call via padded_allocate_handler. +static void* dummy_padded_allocate( size_t bytes, size_t alignment ); + +//! Dummy routine used for first indirect call via padded_free_handler. +static void dummy_padded_free( void * ptr ); + +// ! Allocates memory using standard malloc. It is used when scalable_allocator is not available +static void* padded_allocate( size_t bytes, size_t alignment ); + +// ! Allocates memory using standard free. It is used when scalable_allocator is not available +static void padded_free( void* p ); + +//! Handler for padded memory allocation +static void* (*padded_allocate_handler)( size_t bytes, size_t alignment ) = &dummy_padded_allocate; + +//! Handler for padded memory deallocation +static void (*padded_free_handler)( void* p ) = &dummy_padded_free; + +//! Table describing how to link the handlers. +static const dynamic_link_descriptor MallocLinkTable[] = { + DLD(scalable_malloc, MallocHandler), + DLD(scalable_free, FreeHandler), + DLD(scalable_aligned_malloc, padded_allocate_handler), + DLD(scalable_aligned_free, padded_free_handler), +}; + + +#if TBB_USE_DEBUG +#define DEBUG_SUFFIX "_debug" +#else +#define DEBUG_SUFFIX +#endif /* TBB_USE_DEBUG */ + +// MALLOCLIB_NAME is the name of the TBB memory allocator library. +#if _WIN32||_WIN64 +#define MALLOCLIB_NAME "tbbmalloc" DEBUG_SUFFIX ".dll" +#elif __APPLE__ +#define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".dylib" +#elif __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __sun || _AIX || __ANDROID__ +#define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".so" +#elif __linux__ // Note that order of these #elif's is important! +#define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX __TBB_STRING(.so.TBB_COMPATIBLE_INTERFACE_VERSION) +#else +#error Unknown OS +#endif + +//! Initialize the allocation/free handler pointers. +/** Caller is responsible for ensuring this routine is called exactly once. + The routine attempts to dynamically link with the TBB memory allocator. + If that allocator is not found, it links to malloc and free. */ +void initialize_handler_pointers() { + __TBB_ASSERT( MallocHandler==&DummyMalloc, NULL ); + bool success = dynamic_link( MALLOCLIB_NAME, MallocLinkTable, 4 ); + if( !success ) { + // If unsuccessful, set the handlers to the default routines. + // This must be done now, and not before FillDynamicLinks runs, because if other + // threads call the handlers, we want them to go through the DoOneTimeInitializations logic, + // which forces them to wait. + FreeHandler = &std::free; + MallocHandler = &std::malloc; + padded_allocate_handler = &padded_allocate; + padded_free_handler = &padded_free; + } +#if !__TBB_RML_STATIC + PrintExtraVersionInfo( "ALLOCATOR", success?"scalable_malloc":"malloc" ); +#endif +} + +static tbb::atomic<do_once_state> initialization_state; +void initialize_cache_aligned_allocator() { + atomic_do_once( &initialize_handler_pointers, initialization_state ); +} + +//! Executed on very first call through MallocHandler +static void* DummyMalloc( size_t size ) { + initialize_cache_aligned_allocator(); + __TBB_ASSERT( MallocHandler!=&DummyMalloc, NULL ); + return (*MallocHandler)( size ); +} + +//! Executed on very first call through FreeHandler +static void DummyFree( void * ptr ) { + initialize_cache_aligned_allocator(); + __TBB_ASSERT( FreeHandler!=&DummyFree, NULL ); + (*FreeHandler)( ptr ); +} + +//! Executed on very first call through padded_allocate_handler +static void* dummy_padded_allocate( size_t bytes, size_t alignment ) { + initialize_cache_aligned_allocator(); + __TBB_ASSERT( padded_allocate_handler!=&dummy_padded_allocate, NULL ); + return (*padded_allocate_handler)(bytes, alignment); +} + +//! Executed on very first call through padded_free_handler +static void dummy_padded_free( void * ptr ) { + initialize_cache_aligned_allocator(); + __TBB_ASSERT( padded_free_handler!=&dummy_padded_free, NULL ); + (*padded_free_handler)( ptr ); +} + +// TODO: use CPUID to find actual line size, though consider backward compatibility +static size_t NFS_LineSize = 128; + +size_t NFS_GetLineSize() { + return NFS_LineSize; +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // unary minus operator applied to unsigned type, result still unsigned + #pragma warning( disable: 4146 4706 ) +#endif + +void* NFS_Allocate( size_t n, size_t element_size, void* /*hint*/ ) { + //TODO: make this functionality available via an adaptor over generic STL like allocator + const size_t nfs_cache_line_size = NFS_LineSize; + __TBB_ASSERT( nfs_cache_line_size <= NFS_MaxLineSize, "illegal value for NFS_LineSize" ); + __TBB_ASSERT( is_power_of_two(nfs_cache_line_size), "must be power of two" ); + size_t bytes = n*element_size; + + if (bytes<n || bytes+nfs_cache_line_size<bytes) { + // Overflow + throw_exception(eid_bad_alloc); + } + // scalable_aligned_malloc considers zero size request an error, and returns NULL + if (bytes==0) bytes = 1; + + void* result = (*padded_allocate_handler)( bytes, nfs_cache_line_size ); + if (!result) + throw_exception(eid_bad_alloc); + + __TBB_ASSERT( is_aligned(result, nfs_cache_line_size), "The address returned isn't aligned to cache line size" ); + return result; +} + +void NFS_Free( void* p ) { + (*padded_free_handler)( p ); +} + +static void* padded_allocate( size_t bytes, size_t alignment ) { + unsigned char* result = NULL; + unsigned char* base = (unsigned char*)std::malloc(alignment+bytes); + if( base ) { + // Round up to the next line + result = (unsigned char*)((uintptr_t)(base+alignment)&-alignment); + // Record where block actually starts. + ((uintptr_t*)result)[-1] = uintptr_t(base); + } + return result; +} + +static void padded_free( void* p ) { + if( p ) { + __TBB_ASSERT( (uintptr_t)p>=0x4096, "attempt to free block not obtained from cache_aligned_allocator" ); + // Recover where block actually starts + unsigned char* base = ((unsigned char**)p)[-1]; + __TBB_ASSERT( (void*)((uintptr_t)(base+NFS_LineSize)&-NFS_LineSize)==p, "not allocated by NFS_Allocate?" ); + std::free(base); + } +} + +void* __TBB_EXPORTED_FUNC allocate_via_handler_v3( size_t n ) { + void* result = (*MallocHandler) (n); + if (!result) { + throw_exception(eid_bad_alloc); + } + return result; +} + +void __TBB_EXPORTED_FUNC deallocate_via_handler_v3( void *p ) { + if( p ) { + (*FreeHandler)( p ); + } +} + +bool __TBB_EXPORTED_FUNC is_malloc_used_v3() { + if (MallocHandler == &DummyMalloc) { + void* void_ptr = (*MallocHandler)(1); + (*FreeHandler)(void_ptr); + } + __TBB_ASSERT( MallocHandler!=&DummyMalloc && FreeHandler!=&DummyFree, NULL ); + // Cast to void avoids type mismatch errors on some compilers (e.g. __IBMCPP__) + __TBB_ASSERT( !(((void*)MallocHandler==(void*)&std::malloc) ^ ((void*)FreeHandler==(void*)&std::free)), + "Both shim pointers must refer to routines from the same package (either TBB or CRT)" ); + return (void*)MallocHandler == (void*)&std::malloc; +} + +} // namespace internal + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/cilk-tbb-interop.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/cilk-tbb-interop.h new file mode 100644 index 00000000..a7d535bf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/cilk-tbb-interop.h @@ -0,0 +1,111 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* The API to enable interoperability between Intel(R) Cilk(TM) Plus and + Intel(R) Threading Building Blocks. */ + +#ifndef CILK_TBB_INTEROP_H +#define CILK_TBB_INTEROP_H + +#ifndef _WIN32 +#ifdef IN_CILK_RUNTIME +#define CILK_EXPORT __attribute__((visibility("protected"))) +#else +#define CILK_EXPORT /* nothing */ +#endif +#else +#ifdef IN_CILK_RUNTIME +#define CILK_EXPORT __declspec(dllexport) +#else +#define CILK_EXPORT __declspec(dllimport) +#endif // IN_CILK_RUNTIME +#endif // _WIN32 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* A return code. 0 indicates success */ +typedef int __cilk_tbb_retcode; + +enum __cilk_tbb_stack_op { + CILK_TBB_STACK_ORPHAN, // disconnecting stack from a thread + CILK_TBB_STACK_ADOPT, // reconnecting orphaned stack to a trhead + CILK_TBB_STACK_RELEASE // releasing stack +}; + +typedef __cilk_tbb_retcode (*__cilk_tbb_pfn_stack_op)(enum __cilk_tbb_stack_op, void* data); + +typedef __cilk_tbb_retcode (*__cilk_tbb_pfn_unwatch_stacks)(void *data); + +/* Each thunk structure has two pointers: "routine" and "data". + The caller of the thunk invokes *routine, passing "data" as the void* parameter. */ + +/* Thunk invoked by Intel Cilk Plus runtime (cilkrts) when it changes the relationship + between a stack and a thread. It does not matter what stack the thunk runs on. + The thread (not fiber) on which the thunk runs is important. + + CILK_TBB_STACK_ORPHAN + The thunk must be invoked on the thread disconnecting itself from the stack. + Must "happen before" the stack is adopted elsewhere. + CILK_TBB_STACK_ADOPT + The thunk must be invoked on the thread adopting the stack. + CILK_TBB_STACK_RELEASE + The thunk must be invoked on the thread doing the releasing, + Must "happen before" the stack is used elsewhere. + + When a non-empty stack is transferred between threads, the first thread must orphan it + and the second thread must adopt it. + + An empty stack can be transferred similarly, or simply released by the first thread. + + Here is a summary of the actions as transitions on a state machine. + + watch ORPHAN + -->--> -->-- + / \ / \ + (freed empty stack) (TBB sees stack running on thread) (stack in limbo) + | \ / \ / | + | --<-- --<-- | + ^ RELEASE or ADOPT V + \ unwatch / + \ / + --------------------------<--------------------------- + RELEASE +*/ +struct __cilk_tbb_stack_op_thunk { + __cilk_tbb_pfn_stack_op routine; + void* data; /* Set by TBB */ +}; + +/* Thunk invoked by TBB when it is no longer interested in watching the stack bound to the current thread. */ +struct __cilk_tbb_unwatch_thunk { + __cilk_tbb_pfn_unwatch_stacks routine; + void* data; +}; + +/* Defined by cilkrts, called by TBB. + Requests that cilkrts invoke __cilk_tbb_stack_op_thunk when it orphans a stack. + cilkrts sets *u to a thunk that TBB should call when it is no longer interested in watching the stack. */ +CILK_EXPORT +__cilk_tbb_retcode __cilkrts_watch_stack(struct __cilk_tbb_unwatch_thunk* u, + struct __cilk_tbb_stack_op_thunk o); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // CILK_TBB_INTEROP_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/co_context.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/co_context.h new file mode 100644 index 00000000..19e49390 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/co_context.h @@ -0,0 +1,217 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_co_context_H +#define _TBB_co_context_H + +#if _WIN32 +#include <windows.h> +namespace tbb { +namespace internal { + typedef LPVOID coroutine_type; +}} +#else // !_WIN32 +// ucontext.h API is deprecated since macOS 10.6 +#if __APPLE__ + #if __INTEL_COMPILER + #pragma warning(push) + #pragma warning(disable:1478) + #elif __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + #endif +#endif // __APPLE__ + +#include <ucontext.h> +#include <sys/mman.h> // mprotect + +#include "governor.h" // default_page_size() + +#ifndef MAP_STACK +// macOS* does not define MAP_STACK +#define MAP_STACK 0 +#endif +#ifndef MAP_ANONYMOUS +// macOS* defines MAP_ANON, which is deprecated in Linux*. +#define MAP_ANONYMOUS MAP_ANON +#endif + +namespace tbb { +namespace internal { + struct coroutine_type { + coroutine_type() : my_context(), my_stack(), my_stack_size() {} + ucontext_t my_context; + void* my_stack; + size_t my_stack_size; + }; +}} +#endif // _WIN32 + +namespace tbb { +namespace internal { + + // Forward declaration of the coroutine API. + void create_coroutine(coroutine_type& c, size_t stack_size, void* arg); + void current_coroutine(coroutine_type& c); + void swap_coroutine(coroutine_type& prev_coroutine, coroutine_type& new_coroutine); + void destroy_coroutine(coroutine_type& c); + +class co_context { + enum co_state { + co_invalid, + co_suspended, + co_executing, + co_destroyed + }; + coroutine_type my_coroutine; + co_state my_state; + +public: + co_context(size_t stack_size, void* arg) + : my_state(arg ? co_suspended : co_executing) + { + if (arg) { + create_coroutine(my_coroutine, stack_size, arg); + } else { + current_coroutine(my_coroutine); + } + } + + ~co_context() { + __TBB_ASSERT(1 << my_state & (1 << co_suspended | 1 << co_executing), NULL); + if (my_state == co_suspended) + destroy_coroutine(my_coroutine); + my_state = co_destroyed; + } + + void resume(co_context& target) { + // Do not create non-trivial objects on the stack of this function. They might never be destroyed. + __TBB_ASSERT(my_state == co_executing, NULL); + __TBB_ASSERT(target.my_state == co_suspended, NULL); + + my_state = co_suspended; + target.my_state = co_executing; + + // 'target' can reference an invalid object after swap_coroutine. Do not access it. + swap_coroutine(my_coroutine, target.my_coroutine); + + __TBB_ASSERT(my_state == co_executing, NULL); + } +#if !_WIN32 + void* get_stack_limit() { + return my_coroutine.my_stack; + } +#endif +}; + +// Defined in scheduler.h +#if _WIN32 +void __stdcall co_local_wait_for_all(void*); +#else +void co_local_wait_for_all(void*); +#endif + +#if _WIN32 +inline void create_coroutine(coroutine_type& c, size_t stack_size, void* arg) { + __TBB_ASSERT(arg, NULL); + c = CreateFiber(stack_size, co_local_wait_for_all, arg); + __TBB_ASSERT(c, NULL); +} + +inline void current_coroutine(coroutine_type& c) { + c = IsThreadAFiber() ? GetCurrentFiber() : + ConvertThreadToFiberEx(nullptr, FIBER_FLAG_FLOAT_SWITCH); + __TBB_ASSERT(c, NULL); +} + +inline void swap_coroutine(coroutine_type& prev_coroutine, coroutine_type& new_coroutine) { + __TBB_ASSERT(IsThreadAFiber(), NULL); + __TBB_ASSERT(new_coroutine, NULL); + prev_coroutine = GetCurrentFiber(); + __TBB_ASSERT(prev_coroutine, NULL); + SwitchToFiber(new_coroutine); +} + +inline void destroy_coroutine(coroutine_type& c) { + __TBB_ASSERT(c, NULL); + DeleteFiber(c); +} +#else // !_WIN32 + +inline void create_coroutine(coroutine_type& c, size_t stack_size, void* arg) { + const size_t REG_PAGE_SIZE = governor::default_page_size(); + const size_t page_aligned_stack_size = (stack_size + (REG_PAGE_SIZE - 1)) & ~(REG_PAGE_SIZE - 1); + const size_t protected_stack_size = page_aligned_stack_size + 2 * REG_PAGE_SIZE; + + // Allocate the stack with protection property + uintptr_t stack_ptr = (uintptr_t)mmap(NULL, protected_stack_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + __TBB_ASSERT((void*)stack_ptr != MAP_FAILED, NULL); + + // Allow read write on our stack (guarded pages are still protected) + int err = mprotect((void*)(stack_ptr + REG_PAGE_SIZE), page_aligned_stack_size, PROT_READ | PROT_WRITE); + __TBB_ASSERT_EX(!err, NULL); + + // Remember the stack state + c.my_stack = (void*)(stack_ptr + REG_PAGE_SIZE); + c.my_stack_size = page_aligned_stack_size; + + err = getcontext(&c.my_context); + __TBB_ASSERT_EX(!err, NULL); + + c.my_context.uc_link = 0; + // cast to char* to disable FreeBSD clang-3.4.1 'incompatible type' error + c.my_context.uc_stack.ss_sp = (char*)c.my_stack; + c.my_context.uc_stack.ss_size = c.my_stack_size; + c.my_context.uc_stack.ss_flags = 0; + + typedef void(*coroutine_func_t)(); + makecontext(&c.my_context, (coroutine_func_t)co_local_wait_for_all, sizeof(arg) / sizeof(int), arg); +} + +inline void current_coroutine(coroutine_type& c) { + int err = getcontext(&c.my_context); + __TBB_ASSERT_EX(!err, NULL); +} + +inline void swap_coroutine(coroutine_type& prev_coroutine, coroutine_type& new_coroutine) { + int err = swapcontext(&prev_coroutine.my_context, &new_coroutine.my_context); + __TBB_ASSERT_EX(!err, NULL); +} + +inline void destroy_coroutine(coroutine_type& c) { + const size_t REG_PAGE_SIZE = governor::default_page_size(); + // Free stack memory with guarded pages + munmap((void*)((uintptr_t)c.my_stack - REG_PAGE_SIZE), c.my_stack_size + 2 * REG_PAGE_SIZE); + // Clear the stack state afterwards + c.my_stack = NULL; + c.my_stack_size = 0; +} + +#if __APPLE__ + #if __INTEL_COMPILER + #pragma warning(pop) // 1478 warning + #elif __clang__ + #pragma clang diagnostic pop // "-Wdeprecated-declarations" + #endif +#endif + +#endif // _WIN32 + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_co_context_H */ + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_hash_map.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_hash_map.cpp new file mode 100644 index 00000000..7ba5c8f8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_hash_map.cpp @@ -0,0 +1,54 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/concurrent_hash_map.h" + +namespace tbb { + +namespace internal { +#if !TBB_NO_LEGACY +struct hash_map_segment_base { + typedef spin_rw_mutex segment_mutex_t; + //! Type of a hash code. + typedef size_t hashcode_t; + //! Log2 of n_segment + static const size_t n_segment_bits = 6; + //! Maximum size of array of chains + static const size_t max_physical_size = size_t(1)<<(8*sizeof(hashcode_t)-n_segment_bits); + //! Mutex that protects this segment + segment_mutex_t my_mutex; + // Number of nodes + atomic<size_t> my_logical_size; + // Size of chains + /** Always zero or a power of two */ + size_t my_physical_size; + //! True if my_logical_size>=my_physical_size. + /** Used to support Intel(R) Thread Checker. */ + bool __TBB_EXPORTED_METHOD internal_grow_predicate() const; +}; + +bool hash_map_segment_base::internal_grow_predicate() const { + // Intel(R) Thread Checker considers the following reads to be races, so we hide them in the + // library so that Intel(R) Thread Checker will ignore them. The reads are used in a double-check + // context, so the program is nonetheless correct despite the race. + return my_logical_size >= my_physical_size && my_physical_size < max_physical_size; +} +#endif//!TBB_NO_LEGACY + +} // namespace internal + +} // namespace tbb + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_monitor.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_monitor.cpp new file mode 100644 index 00000000..648f314b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_monitor.cpp @@ -0,0 +1,132 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "concurrent_monitor.h" + +namespace tbb { +namespace internal { + +void concurrent_monitor::thread_context::init() { + new (sema.begin()) binary_semaphore; + ready = true; +} + +concurrent_monitor::~concurrent_monitor() { + abort_all(); + __TBB_ASSERT( waitset_ec.empty(), "waitset not empty?" ); +} + +void concurrent_monitor::prepare_wait( thread_context& thr, uintptr_t ctx ) { + if( !thr.ready ) + thr.init(); + // this is good place to pump previous skipped wakeup + else if( thr.skipped_wakeup ) { + thr.skipped_wakeup = false; + thr.semaphore().P(); + } + thr.context = ctx; + thr.in_waitset = true; + { + tbb::spin_mutex::scoped_lock l( mutex_ec ); + __TBB_store_relaxed( thr.epoch, __TBB_load_relaxed(epoch) ); + waitset_ec.add( (waitset_t::node_t*)&thr ); + } + atomic_fence(); +} + +void concurrent_monitor::cancel_wait( thread_context& thr ) { + // possible skipped wakeup will be pumped in the following prepare_wait() + thr.skipped_wakeup = true; + // try to remove node from waitset + bool th_in_waitset = thr.in_waitset; + if( th_in_waitset ) { + tbb::spin_mutex::scoped_lock l( mutex_ec ); + if (thr.in_waitset) { + waitset_ec.remove( (waitset_t::node_t&)thr ); + // node is removed from waitset, so there will be no wakeup + thr.in_waitset = false; + thr.skipped_wakeup = false; + } + } +} + +void concurrent_monitor::notify_one_relaxed() { + if( waitset_ec.empty() ) + return; + waitset_node_t* n; + const waitset_node_t* end = waitset_ec.end(); + { + tbb::spin_mutex::scoped_lock l( mutex_ec ); + __TBB_store_relaxed( epoch, __TBB_load_relaxed(epoch) + 1 ); + n = waitset_ec.front(); + if( n!=end ) { + waitset_ec.remove( *n ); + to_thread_context(n)->in_waitset = false; + } + } + if( n!=end ) + to_thread_context(n)->semaphore().V(); +} + +void concurrent_monitor::notify_all_relaxed() { + if( waitset_ec.empty() ) + return; + waitset_t temp; + const waitset_node_t* end; + { + tbb::spin_mutex::scoped_lock l( mutex_ec ); + __TBB_store_relaxed( epoch, __TBB_load_relaxed(epoch) + 1 ); + waitset_ec.flush_to( temp ); + end = temp.end(); + for( waitset_node_t* n=temp.front(); n!=end; n=n->next ) + to_thread_context(n)->in_waitset = false; + } + waitset_node_t* nxt; + for( waitset_node_t* n=temp.front(); n!=end; n=nxt ) { + nxt = n->next; + to_thread_context(n)->semaphore().V(); + } +#if TBB_USE_ASSERT + temp.clear(); +#endif +} + +void concurrent_monitor::abort_all_relaxed() { + if( waitset_ec.empty() ) + return; + waitset_t temp; + const waitset_node_t* end; + { + tbb::spin_mutex::scoped_lock l( mutex_ec ); + __TBB_store_relaxed( epoch, __TBB_load_relaxed(epoch) + 1 ); + waitset_ec.flush_to( temp ); + end = temp.end(); + for( waitset_node_t* n=temp.front(); n!=end; n=n->next ) + to_thread_context(n)->in_waitset = false; + } + waitset_node_t* nxt; + for( waitset_node_t* n=temp.front(); n!=end; n=nxt ) { + nxt = n->next; + to_thread_context(n)->aborted = true; + to_thread_context(n)->semaphore().V(); + } +#if TBB_USE_ASSERT + temp.clear(); +#endif +} + +} // namespace internal +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_monitor.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_monitor.h new file mode 100644 index 00000000..28479771 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_monitor.h @@ -0,0 +1,237 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_concurrent_monitor_H +#define __TBB_concurrent_monitor_H + +#include "tbb/tbb_stddef.h" +#include "tbb/atomic.h" +#include "tbb/spin_mutex.h" +#include "tbb/tbb_exception.h" +#include "tbb/aligned_space.h" + +#include "semaphore.h" + +namespace tbb { +namespace internal { + +//! Circular doubly-linked list with sentinel +/** head.next points to the front and head.prev points to the back */ +class circular_doubly_linked_list_with_sentinel : no_copy { +public: + struct node_t { + node_t* next; + node_t* prev; + explicit node_t() : next((node_t*)(uintptr_t)0xcdcdcdcd), prev((node_t*)(uintptr_t)0xcdcdcdcd) {} + }; + + // ctor + circular_doubly_linked_list_with_sentinel() {clear();} + // dtor + ~circular_doubly_linked_list_with_sentinel() {__TBB_ASSERT( head.next==&head && head.prev==&head, "the list is not empty" );} + + inline size_t size() const {return count;} + inline bool empty() const {return size()==0;} + inline node_t* front() const {return head.next;} + inline node_t* last() const {return head.prev;} + inline node_t* begin() const {return front();} + inline const node_t* end() const {return &head;} + + //! add to the back of the list + inline void add( node_t* n ) { + __TBB_store_relaxed(count, __TBB_load_relaxed(count) + 1); + n->prev = head.prev; + n->next = &head; + head.prev->next = n; + head.prev = n; + } + + //! remove node 'n' + inline void remove( node_t& n ) { + __TBB_ASSERT( count > 0, "attempt to remove an item from an empty list" ); + __TBB_store_relaxed(count, __TBB_load_relaxed(count) - 1); + n.prev->next = n.next; + n.next->prev = n.prev; + } + + //! move all elements to 'lst' and initialize the 'this' list + inline void flush_to( circular_doubly_linked_list_with_sentinel& lst ) { + if( const size_t l_count = __TBB_load_relaxed(count) ) { + __TBB_store_relaxed(lst.count, l_count); + lst.head.next = head.next; + lst.head.prev = head.prev; + head.next->prev = &lst.head; + head.prev->next = &lst.head; + clear(); + } + } + + void clear() {head.next = head.prev = &head; __TBB_store_relaxed(count, 0);} +private: + __TBB_atomic size_t count; + node_t head; +}; + +typedef circular_doubly_linked_list_with_sentinel waitset_t; +typedef circular_doubly_linked_list_with_sentinel::node_t waitset_node_t; + +//! concurrent_monitor +/** fine-grained concurrent_monitor implementation */ +class concurrent_monitor : no_copy { +public: + /** per-thread descriptor for concurrent_monitor */ + class thread_context : waitset_node_t, no_copy { + friend class concurrent_monitor; + public: + thread_context() : skipped_wakeup(false), aborted(false), ready(false), context(0) { + epoch = 0; + in_waitset = false; + } + ~thread_context() { + if (ready) { + if( skipped_wakeup ) semaphore().P(); + semaphore().~binary_semaphore(); + } + } + binary_semaphore& semaphore() { return *sema.begin(); } + private: + //! The method for lazy initialization of the thread_context's semaphore. + // Inlining of the method is undesirable, due to extra instructions for + // exception support added at caller side. + __TBB_NOINLINE( void init() ); + tbb::aligned_space<binary_semaphore> sema; + __TBB_atomic unsigned epoch; + tbb::atomic<bool> in_waitset; + bool skipped_wakeup; + bool aborted; + bool ready; + uintptr_t context; + }; + + //! ctor + concurrent_monitor() {__TBB_store_relaxed(epoch, 0);} + + //! dtor + ~concurrent_monitor() ; + + //! prepare wait by inserting 'thr' into the wait queue + void prepare_wait( thread_context& thr, uintptr_t ctx = 0 ); + + //! Commit wait if event count has not changed; otherwise, cancel wait. + /** Returns true if committed, false if canceled. */ + inline bool commit_wait( thread_context& thr ) { + const bool do_it = thr.epoch == __TBB_load_relaxed(epoch); + // this check is just an optimization + if( do_it ) { + __TBB_ASSERT( thr.ready, "use of commit_wait() without prior prepare_wait()"); + thr.semaphore().P(); + __TBB_ASSERT( !thr.in_waitset, "still in the queue?" ); + if( thr.aborted ) + throw_exception( eid_user_abort ); + } else { + cancel_wait( thr ); + } + return do_it; + } + //! Cancel the wait. Removes the thread from the wait queue if not removed yet. + void cancel_wait( thread_context& thr ); + + //! Wait for a condition to be satisfied with waiting-on context + template<typename WaitUntil, typename Context> + void wait( WaitUntil until, Context on ); + + //! Notify one thread about the event + void notify_one() {atomic_fence(); notify_one_relaxed();} + + //! Notify one thread about the event. Relaxed version. + void notify_one_relaxed(); + + //! Notify all waiting threads of the event + void notify_all() {atomic_fence(); notify_all_relaxed();} + + //! Notify all waiting threads of the event; Relaxed version + void notify_all_relaxed(); + + //! Notify waiting threads of the event that satisfies the given predicate + template<typename P> void notify( const P& predicate ) {atomic_fence(); notify_relaxed( predicate );} + + //! Notify waiting threads of the event that satisfies the given predicate; Relaxed version + template<typename P> void notify_relaxed( const P& predicate ); + + //! Abort any sleeping threads at the time of the call + void abort_all() {atomic_fence(); abort_all_relaxed(); } + + //! Abort any sleeping threads at the time of the call; Relaxed version + void abort_all_relaxed(); + +private: + tbb::spin_mutex mutex_ec; + waitset_t waitset_ec; + __TBB_atomic unsigned epoch; + thread_context* to_thread_context( waitset_node_t* n ) { return static_cast<thread_context*>(n); } +}; + +template<typename WaitUntil, typename Context> +void concurrent_monitor::wait( WaitUntil until, Context on ) +{ + bool slept = false; + thread_context thr_ctx; + prepare_wait( thr_ctx, on() ); + while( !until() ) { + if( (slept = commit_wait( thr_ctx ) )==true ) + if( until() ) break; + slept = false; + prepare_wait( thr_ctx, on() ); + } + if( !slept ) + cancel_wait( thr_ctx ); +} + +template<typename P> +void concurrent_monitor::notify_relaxed( const P& predicate ) { + if( waitset_ec.empty() ) + return; + waitset_t temp; + waitset_node_t* nxt; + const waitset_node_t* end = waitset_ec.end(); + { + tbb::spin_mutex::scoped_lock l( mutex_ec ); + __TBB_store_relaxed(epoch, __TBB_load_relaxed(epoch) + 1); + for( waitset_node_t* n=waitset_ec.last(); n!=end; n=nxt ) { + nxt = n->prev; + thread_context* thr = to_thread_context( n ); + if( predicate( thr->context ) ) { + waitset_ec.remove( *n ); + thr->in_waitset = false; + temp.add( n ); + } + } + } + + end = temp.end(); + for( waitset_node_t* n=temp.front(); n!=end; n=nxt ) { + nxt = n->next; + to_thread_context(n)->semaphore().V(); + } +#if TBB_USE_ASSERT + temp.clear(); +#endif +} + +} // namespace internal +} // namespace tbb + +#endif /* __TBB_concurrent_monitor_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_queue.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_queue.cpp new file mode 100644 index 00000000..ebdda73f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_queue.cpp @@ -0,0 +1,670 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_stddef.h" +#include "tbb/tbb_machine.h" +#include "tbb/tbb_exception.h" +// Define required to satisfy test in internal file. +#define __TBB_concurrent_queue_H +#include "tbb/internal/_concurrent_queue_impl.h" +#include "concurrent_monitor.h" +#include "itt_notify.h" +#include <new> +#include <cstring> // for memset() + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4267) +#endif + +#define RECORD_EVENTS 0 + + +namespace tbb { + +namespace internal { + +typedef concurrent_queue_base_v3 concurrent_queue_base; + +typedef size_t ticket; + +//! A queue using simple locking. +/** For efficiency, this class has no constructor. + The caller is expected to zero-initialize it. */ +struct micro_queue { + typedef concurrent_queue_base::page page; + + friend class micro_queue_pop_finalizer; + + atomic<page*> head_page; + atomic<ticket> head_counter; + + atomic<page*> tail_page; + atomic<ticket> tail_counter; + + spin_mutex page_mutex; + + void push( const void* item, ticket k, concurrent_queue_base& base, + concurrent_queue_base::copy_specifics op_type ); + + void abort_push( ticket k, concurrent_queue_base& base ); + + bool pop( void* dst, ticket k, concurrent_queue_base& base ); + + micro_queue& assign( const micro_queue& src, concurrent_queue_base& base, + concurrent_queue_base::copy_specifics op_type ); + + page* make_copy ( concurrent_queue_base& base, const page* src_page, size_t begin_in_page, + size_t end_in_page, ticket& g_index, concurrent_queue_base::copy_specifics op_type ) ; + + void make_invalid( ticket k ); +}; + +// we need to yank it out of micro_queue because of concurrent_queue_base::deallocate_page being virtual. +class micro_queue_pop_finalizer: no_copy { + typedef concurrent_queue_base::page page; + ticket my_ticket; + micro_queue& my_queue; + page* my_page; + concurrent_queue_base &base; +public: + micro_queue_pop_finalizer( micro_queue& queue, concurrent_queue_base& b, ticket k, page* p ) : + my_ticket(k), my_queue(queue), my_page(p), base(b) + {} + ~micro_queue_pop_finalizer() { + page* p = my_page; + if( p ) { + spin_mutex::scoped_lock lock( my_queue.page_mutex ); + page* q = p->next; + my_queue.head_page = q; + if( !q ) { + my_queue.tail_page = NULL; + } + } + my_queue.head_counter = my_ticket; + if( p ) + base.deallocate_page( p ); + } +}; + +struct predicate_leq { + ticket t; + predicate_leq( ticket t_ ) : t(t_) {} + bool operator() ( uintptr_t p ) const {return (ticket)p<=t;} +}; + +//! Internal representation of a ConcurrentQueue. +/** For efficiency, this class has no constructor. + The caller is expected to zero-initialize it. */ +class concurrent_queue_rep { +public: +private: + friend struct micro_queue; + + //! Approximately n_queue/golden ratio + static const size_t phi = 3; + +public: + //! Must be power of 2 + static const size_t n_queue = 8; + + //! Map ticket to an array index + static size_t index( ticket k ) { + return k*phi%n_queue; + } + + atomic<ticket> head_counter; + concurrent_monitor items_avail; + atomic<size_t> n_invalid_entries; + char pad1[NFS_MaxLineSize-((sizeof(atomic<ticket>)+sizeof(concurrent_monitor)+sizeof(atomic<size_t>))&(NFS_MaxLineSize-1))]; + + atomic<ticket> tail_counter; + concurrent_monitor slots_avail; + char pad2[NFS_MaxLineSize-((sizeof(atomic<ticket>)+sizeof(concurrent_monitor))&(NFS_MaxLineSize-1))]; + micro_queue array[n_queue]; + + micro_queue& choose( ticket k ) { + // The formula here approximates LRU in a cache-oblivious way. + return array[index(k)]; + } + + atomic<unsigned> abort_counter; + + //! Value for effective_capacity that denotes unbounded queue. + static const ptrdiff_t infinite_capacity = ptrdiff_t(~size_t(0)/2); +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // unary minus operator applied to unsigned type, result still unsigned + #pragma warning( push ) + #pragma warning( disable: 4146 ) +#endif + +static void* static_invalid_page; + +//------------------------------------------------------------------------ +// micro_queue +//------------------------------------------------------------------------ +void micro_queue::push( const void* item, ticket k, concurrent_queue_base& base, + concurrent_queue_base::copy_specifics op_type ) { + k &= -concurrent_queue_rep::n_queue; + page* p = NULL; + // find index on page where we would put the data + size_t index = modulo_power_of_two( k/concurrent_queue_rep::n_queue, base.items_per_page ); + if( !index ) { // make a new page + __TBB_TRY { + p = base.allocate_page(); + } __TBB_CATCH(...) { + ++base.my_rep->n_invalid_entries; + make_invalid( k ); + __TBB_RETHROW(); + } + p->mask = 0; + p->next = NULL; + } + + // wait for my turn + if( tail_counter!=k ) // The developer insisted on keeping first check out of the backoff loop + for( atomic_backoff b(true);;b.pause() ) { + ticket tail = tail_counter; + if( tail==k ) break; + else if( tail&0x1 ) { + // no memory. throws an exception; assumes concurrent_queue_rep::n_queue>1 + ++base.my_rep->n_invalid_entries; + throw_exception( eid_bad_last_alloc ); + } + } + + if( p ) { // page is newly allocated; insert in micro_queue + spin_mutex::scoped_lock lock( page_mutex ); + if( page* q = tail_page ) + q->next = p; + else + head_page = p; + tail_page = p; + } + + if (item) { + p = tail_page; + ITT_NOTIFY( sync_acquired, p ); + __TBB_TRY { + if( concurrent_queue_base::copy == op_type ) { + base.copy_item( *p, index, item ); + } else { + __TBB_ASSERT( concurrent_queue_base::move == op_type, NULL ); + static_cast<concurrent_queue_base_v8&>(base).move_item( *p, index, item ); + } + } __TBB_CATCH(...) { + ++base.my_rep->n_invalid_entries; + tail_counter += concurrent_queue_rep::n_queue; + __TBB_RETHROW(); + } + ITT_NOTIFY( sync_releasing, p ); + // If no exception was thrown, mark item as present. + p->mask |= uintptr_t(1)<<index; + } + else // no item; this was called from abort_push + ++base.my_rep->n_invalid_entries; + + tail_counter += concurrent_queue_rep::n_queue; +} + + +void micro_queue::abort_push( ticket k, concurrent_queue_base& base ) { + push(NULL, k, base, concurrent_queue_base::copy); +} + +bool micro_queue::pop( void* dst, ticket k, concurrent_queue_base& base ) { + k &= -concurrent_queue_rep::n_queue; + spin_wait_until_eq( head_counter, k ); + spin_wait_while_eq( tail_counter, k ); + page *p = head_page; + __TBB_ASSERT( p, NULL ); + size_t index = modulo_power_of_two( k/concurrent_queue_rep::n_queue, base.items_per_page ); + bool success = false; + { + micro_queue_pop_finalizer finalizer( *this, base, k+concurrent_queue_rep::n_queue, index==base.items_per_page-1 ? p : NULL ); + if( p->mask & uintptr_t(1)<<index ) { + success = true; + ITT_NOTIFY( sync_acquired, dst ); + ITT_NOTIFY( sync_acquired, head_page ); + base.assign_and_destroy_item( dst, *p, index ); + ITT_NOTIFY( sync_releasing, head_page ); + } else { + --base.my_rep->n_invalid_entries; + } + } + return success; +} + +micro_queue& micro_queue::assign( const micro_queue& src, concurrent_queue_base& base, + concurrent_queue_base::copy_specifics op_type ) +{ + head_counter = src.head_counter; + tail_counter = src.tail_counter; + + const page* srcp = src.head_page; + if( srcp ) { + ticket g_index = head_counter; + __TBB_TRY { + size_t n_items = (tail_counter-head_counter)/concurrent_queue_rep::n_queue; + size_t index = modulo_power_of_two( head_counter/concurrent_queue_rep::n_queue, base.items_per_page ); + size_t end_in_first_page = (index+n_items<base.items_per_page)?(index+n_items):base.items_per_page; + + head_page = make_copy( base, srcp, index, end_in_first_page, g_index, op_type ); + page* cur_page = head_page; + + if( srcp != src.tail_page ) { + for( srcp = srcp->next; srcp!=src.tail_page; srcp=srcp->next ) { + cur_page->next = make_copy( base, srcp, 0, base.items_per_page, g_index, op_type ); + cur_page = cur_page->next; + } + + __TBB_ASSERT( srcp==src.tail_page, NULL ); + + size_t last_index = modulo_power_of_two( tail_counter/concurrent_queue_rep::n_queue, base.items_per_page ); + if( last_index==0 ) last_index = base.items_per_page; + + cur_page->next = make_copy( base, srcp, 0, last_index, g_index, op_type ); + cur_page = cur_page->next; + } + tail_page = cur_page; + } __TBB_CATCH(...) { + make_invalid( g_index ); + __TBB_RETHROW(); + } + } else { + head_page = tail_page = NULL; + } + return *this; +} + +concurrent_queue_base::page* micro_queue::make_copy( concurrent_queue_base& base, + const concurrent_queue_base::page* src_page, size_t begin_in_page, size_t end_in_page, + ticket& g_index, concurrent_queue_base::copy_specifics op_type ) +{ + page* new_page = base.allocate_page(); + new_page->next = NULL; + new_page->mask = src_page->mask; + for( ; begin_in_page!=end_in_page; ++begin_in_page, ++g_index ) + if( new_page->mask & uintptr_t(1)<<begin_in_page ) { + if( concurrent_queue_base::copy == op_type ) { + base.copy_page_item( *new_page, begin_in_page, *src_page, begin_in_page ); + } else { + __TBB_ASSERT( concurrent_queue_base::move == op_type, NULL ); + static_cast<concurrent_queue_base_v8&>(base).move_page_item( *new_page, begin_in_page, *src_page, begin_in_page ); + } + } + return new_page; +} + +void micro_queue::make_invalid( ticket k ) +{ + static concurrent_queue_base::page dummy = {static_cast<page*>((void*)1), 0}; + // mark it so that no more pushes are allowed. + static_invalid_page = &dummy; + { + spin_mutex::scoped_lock lock( page_mutex ); + tail_counter = k+concurrent_queue_rep::n_queue+1; + if( page* q = tail_page ) + q->next = static_cast<page*>(static_invalid_page); + else + head_page = static_cast<page*>(static_invalid_page); + tail_page = static_cast<page*>(static_invalid_page); + } +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning( pop ) +#endif // warning 4146 is back + +//------------------------------------------------------------------------ +// concurrent_queue_base +//------------------------------------------------------------------------ +concurrent_queue_base_v3::concurrent_queue_base_v3( size_t item_sz ) { + items_per_page = item_sz<= 8 ? 32 : + item_sz<= 16 ? 16 : + item_sz<= 32 ? 8 : + item_sz<= 64 ? 4 : + item_sz<=128 ? 2 : + 1; + my_capacity = size_t(-1)/(item_sz>1 ? item_sz : 2); + my_rep = cache_aligned_allocator<concurrent_queue_rep>().allocate(1); + __TBB_ASSERT( is_aligned(my_rep, NFS_GetLineSize()), "alignment error" ); + __TBB_ASSERT( is_aligned(&my_rep->head_counter, NFS_GetLineSize()), "alignment error" ); + __TBB_ASSERT( is_aligned(&my_rep->tail_counter, NFS_GetLineSize()), "alignment error" ); + __TBB_ASSERT( is_aligned(&my_rep->array, NFS_GetLineSize()), "alignment error" ); + std::memset(static_cast<void*>(my_rep),0,sizeof(concurrent_queue_rep)); + new ( &my_rep->items_avail ) concurrent_monitor(); + new ( &my_rep->slots_avail ) concurrent_monitor(); + this->item_size = item_sz; +} + +concurrent_queue_base_v3::~concurrent_queue_base_v3() { + size_t nq = my_rep->n_queue; + for( size_t i=0; i<nq; i++ ) + __TBB_ASSERT( my_rep->array[i].tail_page==NULL, "pages were not freed properly" ); + cache_aligned_allocator<concurrent_queue_rep>().deallocate(my_rep,1); +} + +void concurrent_queue_base_v3::internal_push( const void* src ) { + internal_insert_item( src, copy ); +} + +void concurrent_queue_base_v8::internal_push_move( const void* src ) { + internal_insert_item( src, move ); +} + +void concurrent_queue_base_v3::internal_insert_item( const void* src, copy_specifics op_type ) { + concurrent_queue_rep& r = *my_rep; + unsigned old_abort_counter = r.abort_counter; + ticket k = r.tail_counter++; + ptrdiff_t e = my_capacity; +#if DO_ITT_NOTIFY + bool sync_prepare_done = false; +#endif + if( (ptrdiff_t)(k-r.head_counter)>=e ) { // queue is full +#if DO_ITT_NOTIFY + if( !sync_prepare_done ) { + ITT_NOTIFY( sync_prepare, &sync_prepare_done ); + sync_prepare_done = true; + } +#endif + bool slept = false; + concurrent_monitor::thread_context thr_ctx; + r.slots_avail.prepare_wait( thr_ctx, ((ptrdiff_t)(k-e)) ); + while( (ptrdiff_t)(k-r.head_counter)>=const_cast<volatile ptrdiff_t&>(e = my_capacity) ) { + __TBB_TRY { + if( r.abort_counter!=old_abort_counter ) { + r.slots_avail.cancel_wait( thr_ctx ); + throw_exception( eid_user_abort ); + } + slept = r.slots_avail.commit_wait( thr_ctx ); + } __TBB_CATCH( tbb::user_abort& ) { + r.choose(k).abort_push(k, *this); + __TBB_RETHROW(); + } __TBB_CATCH(...) { + __TBB_RETHROW(); + } + if (slept == true) break; + r.slots_avail.prepare_wait( thr_ctx, ((ptrdiff_t)(k-e)) ); + } + if( !slept ) + r.slots_avail.cancel_wait( thr_ctx ); + } + ITT_NOTIFY( sync_acquired, &sync_prepare_done ); + __TBB_ASSERT( (ptrdiff_t)(k-r.head_counter)<my_capacity, NULL); + r.choose( k ).push( src, k, *this, op_type ); + r.items_avail.notify( predicate_leq(k) ); +} + +void concurrent_queue_base_v3::internal_pop( void* dst ) { + concurrent_queue_rep& r = *my_rep; + ticket k; +#if DO_ITT_NOTIFY + bool sync_prepare_done = false; +#endif + unsigned old_abort_counter = r.abort_counter; + // This loop is a single pop operation; abort_counter should not be re-read inside + do { + k=r.head_counter++; + if ( (ptrdiff_t)(r.tail_counter-k)<=0 ) { // queue is empty +#if DO_ITT_NOTIFY + if( !sync_prepare_done ) { + ITT_NOTIFY( sync_prepare, dst ); + sync_prepare_done = true; + } +#endif + bool slept = false; + concurrent_monitor::thread_context thr_ctx; + r.items_avail.prepare_wait( thr_ctx, k ); + while( (ptrdiff_t)(r.tail_counter-k)<=0 ) { + __TBB_TRY { + if( r.abort_counter!=old_abort_counter ) { + r.items_avail.cancel_wait( thr_ctx ); + throw_exception( eid_user_abort ); + } + slept = r.items_avail.commit_wait( thr_ctx ); + } __TBB_CATCH( tbb::user_abort& ) { + r.head_counter--; + __TBB_RETHROW(); + } __TBB_CATCH(...) { + __TBB_RETHROW(); + } + if (slept == true) break; + r.items_avail.prepare_wait( thr_ctx, k ); + } + if( !slept ) + r.items_avail.cancel_wait( thr_ctx ); + } + __TBB_ASSERT((ptrdiff_t)(r.tail_counter-k)>0, NULL); + } while( !r.choose(k).pop(dst,k,*this) ); + + // wake up a producer.. + r.slots_avail.notify( predicate_leq(k) ); +} + +void concurrent_queue_base_v3::internal_abort() { + concurrent_queue_rep& r = *my_rep; + ++r.abort_counter; + r.items_avail.abort_all(); + r.slots_avail.abort_all(); +} + +bool concurrent_queue_base_v3::internal_pop_if_present( void* dst ) { + concurrent_queue_rep& r = *my_rep; + ticket k; + do { + k = r.head_counter; + for(;;) { + if( (ptrdiff_t)(r.tail_counter-k)<=0 ) { + // Queue is empty + return false; + } + // Queue had item with ticket k when we looked. Attempt to get that item. + ticket tk=k; + k = r.head_counter.compare_and_swap( tk+1, tk ); + if( k==tk ) + break; + // Another thread snatched the item, retry. + } + } while( !r.choose( k ).pop( dst, k, *this ) ); + + r.slots_avail.notify( predicate_leq(k) ); + + return true; +} + +bool concurrent_queue_base_v3::internal_push_if_not_full( const void* src ) { + return internal_insert_if_not_full( src, copy ); +} + +bool concurrent_queue_base_v8::internal_push_move_if_not_full( const void* src ) { + return internal_insert_if_not_full( src, move ); +} + +bool concurrent_queue_base_v3::internal_insert_if_not_full( const void* src, copy_specifics op_type ) { + concurrent_queue_rep& r = *my_rep; + ticket k = r.tail_counter; + for(;;) { + if( (ptrdiff_t)(k-r.head_counter)>=my_capacity ) { + // Queue is full + return false; + } + // Queue had empty slot with ticket k when we looked. Attempt to claim that slot. + ticket tk=k; + k = r.tail_counter.compare_and_swap( tk+1, tk ); + if( k==tk ) + break; + // Another thread claimed the slot, so retry. + } + r.choose(k).push(src, k, *this, op_type); + r.items_avail.notify( predicate_leq(k) ); + return true; +} + +ptrdiff_t concurrent_queue_base_v3::internal_size() const { + __TBB_ASSERT( sizeof(ptrdiff_t)<=sizeof(size_t), NULL ); + return ptrdiff_t(my_rep->tail_counter-my_rep->head_counter-my_rep->n_invalid_entries); +} + +bool concurrent_queue_base_v3::internal_empty() const { + ticket tc = my_rep->tail_counter; + ticket hc = my_rep->head_counter; + // if tc!=r.tail_counter, the queue was not empty at some point between the two reads. + return ( tc==my_rep->tail_counter && ptrdiff_t(tc-hc-my_rep->n_invalid_entries)<=0 ); +} + +void concurrent_queue_base_v3::internal_set_capacity( ptrdiff_t capacity, size_t /*item_sz*/ ) { + my_capacity = capacity<0 ? concurrent_queue_rep::infinite_capacity : capacity; +} + +void concurrent_queue_base_v3::internal_finish_clear() { + size_t nq = my_rep->n_queue; + for( size_t i=0; i<nq; ++i ) { + page* tp = my_rep->array[i].tail_page; + __TBB_ASSERT( my_rep->array[i].head_page==tp, "at most one page should remain" ); + if( tp!=NULL) { + if( tp!=static_invalid_page ) deallocate_page( tp ); + my_rep->array[i].tail_page = NULL; + } + } +} + +void concurrent_queue_base_v3::internal_throw_exception() const { + throw_exception( eid_bad_alloc ); +} + +void concurrent_queue_base_v3::internal_assign( const concurrent_queue_base& src, copy_specifics op_type ) { + items_per_page = src.items_per_page; + my_capacity = src.my_capacity; + + // copy concurrent_queue_rep. + my_rep->head_counter = src.my_rep->head_counter; + my_rep->tail_counter = src.my_rep->tail_counter; + my_rep->n_invalid_entries = src.my_rep->n_invalid_entries; + my_rep->abort_counter = src.my_rep->abort_counter; + + // copy micro_queues + for( size_t i = 0; i<my_rep->n_queue; ++i ) + my_rep->array[i].assign( src.my_rep->array[i], *this, op_type ); + + __TBB_ASSERT( my_rep->head_counter==src.my_rep->head_counter && my_rep->tail_counter==src.my_rep->tail_counter, + "the source concurrent queue should not be concurrently modified." ); +} + +void concurrent_queue_base_v3::assign( const concurrent_queue_base& src ) { + internal_assign( src, copy ); +} + +void concurrent_queue_base_v8::move_content( concurrent_queue_base_v8& src ) { + internal_assign( src, move ); +} + +//------------------------------------------------------------------------ +// concurrent_queue_iterator_rep +//------------------------------------------------------------------------ +class concurrent_queue_iterator_rep: no_assign { +public: + ticket head_counter; + const concurrent_queue_base& my_queue; + const size_t offset_of_last; + concurrent_queue_base::page* array[concurrent_queue_rep::n_queue]; + concurrent_queue_iterator_rep( const concurrent_queue_base& queue, size_t offset_of_last_ ) : + head_counter(queue.my_rep->head_counter), + my_queue(queue), + offset_of_last(offset_of_last_) + { + const concurrent_queue_rep& rep = *queue.my_rep; + for( size_t k=0; k<concurrent_queue_rep::n_queue; ++k ) + array[k] = rep.array[k].head_page; + } + //! Set item to point to kth element. Return true if at end of queue or item is marked valid; false otherwise. + bool get_item( void*& item, size_t k ) { + if( k==my_queue.my_rep->tail_counter ) { + item = NULL; + return true; + } else { + concurrent_queue_base::page* p = array[concurrent_queue_rep::index(k)]; + __TBB_ASSERT(p,NULL); + size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, my_queue.items_per_page ); + item = static_cast<unsigned char*>(static_cast<void*>(p)) + offset_of_last + my_queue.item_size*i; + return (p->mask & uintptr_t(1)<<i)!=0; + } + } +}; + +//------------------------------------------------------------------------ +// concurrent_queue_iterator_base +//------------------------------------------------------------------------ + +void concurrent_queue_iterator_base_v3::initialize( const concurrent_queue_base& queue, size_t offset_of_last ) { + my_rep = cache_aligned_allocator<concurrent_queue_iterator_rep>().allocate(1); + new( my_rep ) concurrent_queue_iterator_rep(queue,offset_of_last); + size_t k = my_rep->head_counter; + if( !my_rep->get_item(my_item, k) ) advance(); +} + +concurrent_queue_iterator_base_v3::concurrent_queue_iterator_base_v3( const concurrent_queue_base& queue ) { + initialize(queue,0); +} + +concurrent_queue_iterator_base_v3::concurrent_queue_iterator_base_v3( const concurrent_queue_base& queue, size_t offset_of_last ) { + initialize(queue,offset_of_last); +} + +void concurrent_queue_iterator_base_v3::assign( const concurrent_queue_iterator_base& other ) { + if( my_rep!=other.my_rep ) { + if( my_rep ) { + cache_aligned_allocator<concurrent_queue_iterator_rep>().deallocate(my_rep, 1); + my_rep = NULL; + } + if( other.my_rep ) { + my_rep = cache_aligned_allocator<concurrent_queue_iterator_rep>().allocate(1); + new( my_rep ) concurrent_queue_iterator_rep( *other.my_rep ); + } + } + my_item = other.my_item; +} + +void concurrent_queue_iterator_base_v3::advance() { + __TBB_ASSERT( my_item, "attempt to increment iterator past end of queue" ); + size_t k = my_rep->head_counter; + const concurrent_queue_base& queue = my_rep->my_queue; +#if TBB_USE_ASSERT + void* tmp; + my_rep->get_item(tmp,k); + __TBB_ASSERT( my_item==tmp, NULL ); +#endif /* TBB_USE_ASSERT */ + size_t i = modulo_power_of_two( k/concurrent_queue_rep::n_queue, queue.items_per_page ); + if( i==queue.items_per_page-1 ) { + concurrent_queue_base::page*& root = my_rep->array[concurrent_queue_rep::index(k)]; + root = root->next; + } + // advance k + my_rep->head_counter = ++k; + if( !my_rep->get_item(my_item, k) ) advance(); +} + +concurrent_queue_iterator_base_v3::~concurrent_queue_iterator_base_v3() { + //delete my_rep; + cache_aligned_allocator<concurrent_queue_iterator_rep>().deallocate(my_rep, 1); + my_rep = NULL; +} + +} // namespace internal + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_vector.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_vector.cpp new file mode 100644 index 00000000..660aff15 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/concurrent_vector.cpp @@ -0,0 +1,610 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if (_MSC_VER) + //MSVC 10 "deprecated" application of some std:: algorithms to raw pointers as not safe. + //The reason is that destination is not checked against bounds/having enough place. + #define _SCL_SECURE_NO_WARNINGS +#endif + +#include "tbb/concurrent_vector.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/tbb_exception.h" +#include "tbb_misc.h" +#include "itt_notify.h" + +#include <cstring> +#include <memory> //for uninitialized_fill_n + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4267) +#endif + +namespace tbb { + +namespace internal { +class concurrent_vector_base_v3::helper :no_assign { +public: + //! memory page size + static const size_type page_size = 4096; + + inline static bool incompact_predicate(size_type size) { // assert size != 0, see source/test/test_vector_layout.cpp + return size < page_size || ((size-1)%page_size < page_size/2 && size < page_size * 128); // for more details + } + + inline static size_type find_segment_end(const concurrent_vector_base_v3 &v) { + segment_t *s = v.my_segment; + segment_index_t u = s==v.my_storage? pointers_per_short_table : pointers_per_long_table; + segment_index_t k = 0; + while( k < u && (s[k].load<relaxed>()==segment_allocated() )) + ++k; + return k; + } + + // TODO: optimize accesses to my_first_block + //! assign first segment size. k - is index of last segment to be allocated, not a count of segments + inline static void assign_first_segment_if_necessary(concurrent_vector_base_v3 &v, segment_index_t k) { + if( !v.my_first_block ) { + /* There was a suggestion to set first segment according to incompact_predicate: + while( k && !helper::incompact_predicate(segment_size( k ) * element_size) ) + --k; // while previous vector size is compact, decrement + // reasons to not do it: + // * constructor(n) is not ready to accept fragmented segments + // * backward compatibility due to that constructor + // * current version gives additional guarantee and faster init. + // * two calls to reserve() will give the same effect. + */ + v.my_first_block.compare_and_swap(k+1, 0); // store number of segments + } + } + + inline static void *allocate_segment(concurrent_vector_base_v3 &v, size_type n) { + void *ptr = v.vector_allocator_ptr(v, n); + if(!ptr) throw_exception(eid_bad_alloc); // check for bad allocation, throw exception + return ptr; + } + + //! Publish segment so other threads can see it. + template<typename argument_type> + inline static void publish_segment( segment_t& s, argument_type rhs ) { + // see also itt_store_pointer_with_release_v3() + ITT_NOTIFY( sync_releasing, &s ); + s.store<release>(rhs); + } + + static size_type enable_segment(concurrent_vector_base_v3 &v, size_type k, size_type element_size, bool mark_as_not_used_on_failure = false); + + // TODO: rename as get_segments_table() and return segment pointer + inline static void extend_table_if_necessary(concurrent_vector_base_v3 &v, size_type k, size_type start ) { + if(k >= pointers_per_short_table && v.my_segment == v.my_storage) + extend_segment_table(v, start ); + } + + static void extend_segment_table(concurrent_vector_base_v3 &v, size_type start); + + struct segment_not_used_predicate: no_assign { + segment_t &s; + segment_not_used_predicate(segment_t &segment) : s(segment) {} + bool operator()() const { return s.load<relaxed>() == segment_not_used ();} + }; + inline static segment_t& acquire_segment(concurrent_vector_base_v3 &v, size_type index, size_type element_size, bool owner) { + segment_t &s = v.my_segment[index]; // TODO: pass v.my_segment as argument + if( s.load<acquire>() == segment_not_used() ) { // do not check for segment_allocation_failed state + if( owner ) { + enable_segment( v, index, element_size ); + } else { + ITT_NOTIFY(sync_prepare, &s); + spin_wait_while(segment_not_used_predicate(s)); + ITT_NOTIFY(sync_acquired, &s); + } + } else { + ITT_NOTIFY(sync_acquired, &s); + } + enforce_segment_allocated(s.load<relaxed>()); //it's hard to recover correctly after segment_allocation_failed state + return s; + } + + ///// non-static fields of helper for exception-safe iteration across segments + segment_t *table;// TODO: review all segment_index_t as just short type + size_type first_block, k, sz, start, finish, element_size; + helper(segment_t *segments, size_type fb, size_type esize, size_type index, size_type s, size_type f) throw() + : table(segments), first_block(fb), k(index), sz(0), start(s), finish(f), element_size(esize) {} + inline void first_segment() throw() { + __TBB_ASSERT( start <= finish, NULL ); + __TBB_ASSERT( first_block || !finish, NULL ); + if( k < first_block ) k = 0; // process solid segment at a time + size_type base = segment_base( k ); + __TBB_ASSERT( base <= start, NULL ); + finish -= base; start -= base; // rebase as offsets from segment k + sz = k ? base : segment_size( first_block ); // sz==base for k>0 + } + inline void next_segment() throw() { + finish -= sz; start = 0; // offsets from next segment + if( !k ) k = first_block; + else { ++k; sz = segment_size( k ); } + } + template<typename F> + inline size_type apply(const F &func) { + first_segment(); + while( sz < finish ) { // work for more than one segment + //TODO: remove extra load() of table[k] inside func + func( table[k], table[k].load<relaxed>().pointer<char>() + element_size*start, sz - start ); + next_segment(); + } + func( table[k], table[k].load<relaxed>().pointer<char>() + element_size*start, finish - start ); + return k; + } + inline segment_value_t get_segment_value(size_type index, bool wait) { + segment_t &s = table[index]; + if( wait && (s.load<acquire>() == segment_not_used()) ) { + ITT_NOTIFY(sync_prepare, &s); + spin_wait_while(segment_not_used_predicate(s)); + ITT_NOTIFY(sync_acquired, &s); + } + return s.load<relaxed>(); + } + ~helper() { + if( sz >= finish ) return; // the work is done correctly + cleanup(); + } + + //! Out of line code to assists destructor in infrequent cases. + void cleanup(); + + /// TODO: turn into lambda functions when available + struct init_body { + internal_array_op2 func; + const void *arg; + init_body(internal_array_op2 init, const void *src) : func(init), arg(src) {} + void operator()(segment_t &, void *begin, size_type n) const { + func( begin, arg, n ); + } + }; + struct safe_init_body { + internal_array_op2 func; + const void *arg; + safe_init_body(internal_array_op2 init, const void *src) : func(init), arg(src) {} + void operator()(segment_t &s, void *begin, size_type n) const { + enforce_segment_allocated(s.load<relaxed>()); + func( begin, arg, n ); + } + }; + struct destroy_body { + internal_array_op1 func; + destroy_body(internal_array_op1 destroy) : func(destroy) {} + void operator()(segment_t &s, void *begin, size_type n) const { + if(s.load<relaxed>() == segment_allocated()) + func( begin, n ); + } + }; +}; // class helper + +void concurrent_vector_base_v3::helper::extend_segment_table(concurrent_vector_base_v3 &v, concurrent_vector_base_v3::size_type start) { + if( start > segment_size(pointers_per_short_table) ) start = segment_size(pointers_per_short_table); + // If other threads are trying to set pointers in the short segment, wait for them to finish their + // assignments before we copy the short segment to the long segment. Note: grow_to_at_least depends on it + for( segment_index_t i = 0; segment_base(i) < start && v.my_segment == v.my_storage; i++ ){ + if(v.my_storage[i].load<relaxed>() == segment_not_used()) { + ITT_NOTIFY(sync_prepare, &v.my_storage[i]); + atomic_backoff backoff(true); + while( v.my_segment == v.my_storage && (v.my_storage[i].load<relaxed>() == segment_not_used()) ) + backoff.pause(); + ITT_NOTIFY(sync_acquired, &v.my_storage[i]); + } + } + if( v.my_segment != v.my_storage ) return; + + segment_t* new_segment_table = (segment_t*)NFS_Allocate( pointers_per_long_table, sizeof(segment_t), NULL ); + __TBB_ASSERT(new_segment_table, "NFS_Allocate should throws exception if it cannot allocate the requested storage, and not returns zero pointer" ); + std::uninitialized_fill_n(new_segment_table,size_t(pointers_per_long_table),segment_t()); //init newly allocated table + //TODO: replace with static assert + __TBB_STATIC_ASSERT(pointers_per_long_table >= pointers_per_short_table, "size of the big table should be not lesser than of the small one, as we copy values to it" ); + std::copy(v.my_storage, v.my_storage+pointers_per_short_table, new_segment_table);//copy values from old table, here operator= of segment_t is used + if( v.my_segment.compare_and_swap( new_segment_table, v.my_storage ) != v.my_storage ) + NFS_Free( new_segment_table ); + // else TODO: add ITT_NOTIFY signals for v.my_segment? +} + +concurrent_vector_base_v3::size_type concurrent_vector_base_v3::helper::enable_segment(concurrent_vector_base_v3 &v, concurrent_vector_base_v3::size_type k, concurrent_vector_base_v3::size_type element_size, + bool mark_as_not_used_on_failure ) { + + struct segment_scope_guard : no_copy{ + segment_t* my_segment_ptr; + bool my_mark_as_not_used; + segment_scope_guard(segment_t& segment, bool mark_as_not_used) : my_segment_ptr(&segment), my_mark_as_not_used(mark_as_not_used){} + void dismiss(){ my_segment_ptr = 0;} + ~segment_scope_guard(){ + if (my_segment_ptr){ + if (!my_mark_as_not_used){ + publish_segment(*my_segment_ptr, segment_allocation_failed()); + }else{ + publish_segment(*my_segment_ptr, segment_not_used()); + } + } + } + }; + + segment_t* s = v.my_segment; // TODO: optimize out as argument? Optimize accesses to my_first_block + __TBB_ASSERT(s[k].load<relaxed>() != segment_allocated(), "concurrent operation during growth?"); + + size_type size_of_enabled_segment = segment_size(k); + size_type size_to_allocate = size_of_enabled_segment; + if( !k ) { + assign_first_segment_if_necessary(v, default_initial_segments-1); + size_of_enabled_segment = 2 ; + size_to_allocate = segment_size(v.my_first_block); + + } else { + spin_wait_while_eq( v.my_first_block, segment_index_t(0) ); + } + + if( k && (k < v.my_first_block)){ //no need to allocate anything + // s[0].array is changed only once ( 0 -> !0 ) and points to uninitialized memory + segment_value_t array0 = s[0].load<acquire>(); + if(array0 == segment_not_used()){ + // sync_prepare called only if there is a wait + ITT_NOTIFY(sync_prepare, &s[0]); + spin_wait_while( segment_not_used_predicate(s[0])); + array0 = s[0].load<acquire>(); + } + ITT_NOTIFY(sync_acquired, &s[0]); + + segment_scope_guard k_segment_guard(s[k], false); + enforce_segment_allocated(array0); // initial segment should be allocated + k_segment_guard.dismiss(); + + publish_segment( s[k], + static_cast<void*>(array0.pointer<char>() + segment_base(k)*element_size ) + ); + } else { + segment_scope_guard k_segment_guard(s[k], mark_as_not_used_on_failure); + publish_segment(s[k], allocate_segment(v, size_to_allocate)); + k_segment_guard.dismiss(); + } + return size_of_enabled_segment; +} + +void concurrent_vector_base_v3::helper::cleanup() { + if( !sz ) { // allocation failed, restore the table + segment_index_t k_start = k, k_end = segment_index_of(finish-1); + if( segment_base( k_start ) < start ) + get_segment_value(k_start++, true); // wait + if( k_start < first_block ) { + segment_value_t segment0 = get_segment_value(0, start>0); // wait if necessary + if((segment0 != segment_not_used()) && !k_start ) ++k_start; + if(segment0 != segment_allocated()) + for(; k_start < first_block && k_start <= k_end; ++k_start ) + publish_segment(table[k_start], segment_allocation_failed()); + else for(; k_start < first_block && k_start <= k_end; ++k_start ) + publish_segment(table[k_start], static_cast<void*>( + (segment0.pointer<char>()) + segment_base(k_start)*element_size) ); + } + for(; k_start <= k_end; ++k_start ) // not in first block + if(table[k_start].load<acquire>() == segment_not_used()) + publish_segment(table[k_start], segment_allocation_failed()); + // fill allocated items + first_segment(); + goto recover; + } + while( sz <= finish ) { // there is still work for at least one segment + next_segment(); +recover: + segment_value_t array = table[k].load<relaxed>(); + if(array == segment_allocated()) + std::memset( (array.pointer<char>()) + element_size*start, 0, ((sz<finish?sz:finish) - start)*element_size ); + else __TBB_ASSERT( array == segment_allocation_failed(), NULL ); + } +} + +concurrent_vector_base_v3::~concurrent_vector_base_v3() { + segment_t* s = my_segment; + if( s != my_storage ) { +#if TBB_USE_ASSERT + //to please assert in segment_t destructor + std::fill_n(my_storage,size_t(pointers_per_short_table),segment_t()); +#endif /* TBB_USE_ASSERT */ +#if TBB_USE_DEBUG + for( segment_index_t i = 0; i < pointers_per_long_table; i++) + __TBB_ASSERT( my_segment[i].load<relaxed>() != segment_allocated(), "Segment should have been freed. Please recompile with new TBB before using exceptions."); +#endif + my_segment = my_storage; + NFS_Free( s ); + } +} + +concurrent_vector_base_v3::size_type concurrent_vector_base_v3::internal_capacity() const { + return segment_base( helper::find_segment_end(*this) ); +} + +void concurrent_vector_base_v3::internal_throw_exception(size_type t) const { + exception_id ids[] = { eid_out_of_range, eid_segment_range_error, eid_index_range_error }; + __TBB_ASSERT(t < sizeof(ids) / sizeof(exception_id), NULL); + throw_exception(ids[t]); +} + +void concurrent_vector_base_v3::internal_reserve( size_type n, size_type element_size, size_type max_size ) { + if( n>max_size ) + throw_exception(eid_reservation_length_error); + __TBB_ASSERT( n, NULL ); + helper::assign_first_segment_if_necessary(*this, segment_index_of(n-1)); + segment_index_t k = helper::find_segment_end(*this); + + for( ; segment_base(k)<n; ++k ) { + helper::extend_table_if_necessary(*this, k, 0); + if(my_segment[k].load<relaxed>() != segment_allocated()) + helper::enable_segment(*this, k, element_size, true ); //in case of failure mark segments as not used + } +} + +//TODO: Looks like atomic loads can be done relaxed here, as the only place this method is called from +//is the constructor, which does not require synchronization (for more details see comment in the +// concurrent_vector_base constructor). +void concurrent_vector_base_v3::internal_copy( const concurrent_vector_base_v3& src, size_type element_size, internal_array_op2 copy ) { + size_type n = src.my_early_size; + __TBB_ASSERT( my_segment == my_storage, NULL); + if( n ) { + helper::assign_first_segment_if_necessary(*this, segment_index_of(n-1)); + size_type b; + for( segment_index_t k=0; (b=segment_base(k))<n; ++k ) { + if( (src.my_segment.load<acquire>() == src.my_storage && k >= pointers_per_short_table) + || (src.my_segment[k].load<relaxed>() != segment_allocated())) { + my_early_size = b; break; + } + helper::extend_table_if_necessary(*this, k, 0); + size_type m = helper::enable_segment(*this, k, element_size); + if( m > n-b ) m = n-b; + my_early_size = b+m; + copy( my_segment[k].load<relaxed>().pointer<void>(), src.my_segment[k].load<relaxed>().pointer<void>(), m ); + } + } +} + +void concurrent_vector_base_v3::internal_assign( const concurrent_vector_base_v3& src, size_type element_size, internal_array_op1 destroy, internal_array_op2 assign, internal_array_op2 copy ) { + size_type n = src.my_early_size; + while( my_early_size>n ) { // TODO: improve + segment_index_t k = segment_index_of( my_early_size-1 ); + size_type b=segment_base(k); + size_type new_end = b>=n ? b : n; + __TBB_ASSERT( my_early_size>new_end, NULL ); + enforce_segment_allocated(my_segment[k].load<relaxed>()); //if vector was broken before + // destructors are supposed to not throw any exceptions + destroy( my_segment[k].load<relaxed>().pointer<char>() + element_size*(new_end-b), my_early_size-new_end ); + my_early_size = new_end; + } + size_type dst_initialized_size = my_early_size; + my_early_size = n; + helper::assign_first_segment_if_necessary(*this, segment_index_of(n)); + size_type b; + for( segment_index_t k=0; (b=segment_base(k))<n; ++k ) { + if( (src.my_segment.load<acquire>() == src.my_storage && k >= pointers_per_short_table) + || src.my_segment[k].load<relaxed>() != segment_allocated() ) { // if source is damaged + my_early_size = b; break; // TODO: it may cause undestructed items + } + helper::extend_table_if_necessary(*this, k, 0); + if( my_segment[k].load<relaxed>() == segment_not_used()) + helper::enable_segment(*this, k, element_size); + else + enforce_segment_allocated(my_segment[k].load<relaxed>()); + size_type m = k? segment_size(k) : 2; + if( m > n-b ) m = n-b; + size_type a = 0; + if( dst_initialized_size>b ) { + a = dst_initialized_size-b; + if( a>m ) a = m; + assign( my_segment[k].load<relaxed>().pointer<void>(), src.my_segment[k].load<relaxed>().pointer<void>(), a ); + m -= a; + a *= element_size; + } + if( m>0 ) + copy( my_segment[k].load<relaxed>().pointer<char>() + a, src.my_segment[k].load<relaxed>().pointer<char>() + a, m ); + } + __TBB_ASSERT( src.my_early_size==n, "detected use of concurrent_vector::operator= with right side that was concurrently modified" ); +} + +void* concurrent_vector_base_v3::internal_push_back( size_type element_size, size_type& index ) { + __TBB_ASSERT( sizeof(my_early_size)==sizeof(uintptr_t), NULL ); + size_type tmp = my_early_size.fetch_and_increment<acquire>(); + index = tmp; + segment_index_t k_old = segment_index_of( tmp ); + size_type base = segment_base(k_old); + helper::extend_table_if_necessary(*this, k_old, tmp); + segment_t& s = helper::acquire_segment(*this, k_old, element_size, base==tmp); + size_type j_begin = tmp-base; + return (void*)(s.load<relaxed>().pointer<char>() + element_size*j_begin); +} + +void concurrent_vector_base_v3::internal_grow_to_at_least( size_type new_size, size_type element_size, internal_array_op2 init, const void *src ) { + internal_grow_to_at_least_with_result( new_size, element_size, init, src ); +} + +concurrent_vector_base_v3::size_type concurrent_vector_base_v3::internal_grow_to_at_least_with_result( size_type new_size, size_type element_size, internal_array_op2 init, const void *src ) { + size_type e = my_early_size; + while( e<new_size ) { + size_type f = my_early_size.compare_and_swap(new_size,e); + if( f==e ) { + internal_grow( e, new_size, element_size, init, src ); + break; + } + e = f; + } + // Check/wait for segments allocation completes + segment_index_t i, k_old = segment_index_of( new_size-1 ); + if( k_old >= pointers_per_short_table && my_segment == my_storage ) { + spin_wait_while_eq( my_segment, my_storage ); + } + for( i = 0; i <= k_old; ++i ) { + segment_t &s = my_segment[i]; + if(s.load<relaxed>() == segment_not_used()) { + ITT_NOTIFY(sync_prepare, &s); + atomic_backoff backoff(true); + while( my_segment[i].load<acquire>() == segment_not_used() ) // my_segment may change concurrently + backoff.pause(); + ITT_NOTIFY(sync_acquired, &s); + } + enforce_segment_allocated(my_segment[i].load<relaxed>()); + } +#if TBB_USE_DEBUG + size_type capacity = internal_capacity(); + __TBB_ASSERT( capacity >= new_size, NULL); +#endif + return e; +} + +concurrent_vector_base_v3::size_type concurrent_vector_base_v3::internal_grow_by( size_type delta, size_type element_size, internal_array_op2 init, const void *src ) { + size_type result = my_early_size.fetch_and_add(delta); + internal_grow( result, result+delta, element_size, init, src ); + return result; +} + +void concurrent_vector_base_v3::internal_grow( const size_type start, size_type finish, size_type element_size, internal_array_op2 init, const void *src ) { + __TBB_ASSERT( start<finish, "start must be less than finish" ); + segment_index_t k_start = segment_index_of(start), k_end = segment_index_of(finish-1); + helper::assign_first_segment_if_necessary(*this, k_end); + helper::extend_table_if_necessary(*this, k_end, start); + helper range(my_segment, my_first_block, element_size, k_start, start, finish); + for(; k_end > k_start && k_end >= range.first_block; --k_end ) // allocate segments in reverse order + helper::acquire_segment(*this, k_end, element_size, true/*for k_end>k_start*/); + for(; k_start <= k_end; ++k_start ) // but allocate first block in straight order + helper::acquire_segment(*this, k_start, element_size, segment_base( k_start ) >= start ); + range.apply( helper::init_body(init, src) ); +} + +void concurrent_vector_base_v3::internal_resize( size_type n, size_type element_size, size_type max_size, const void *src, + internal_array_op1 destroy, internal_array_op2 init ) { + size_type j = my_early_size; + if( n > j ) { // construct items + internal_reserve(n, element_size, max_size); + my_early_size = n; + helper for_each(my_segment, my_first_block, element_size, segment_index_of(j), j, n); + for_each.apply( helper::safe_init_body(init, src) ); + } else { + my_early_size = n; + helper for_each(my_segment, my_first_block, element_size, segment_index_of(n), n, j); + for_each.apply( helper::destroy_body(destroy) ); + } +} + +concurrent_vector_base_v3::segment_index_t concurrent_vector_base_v3::internal_clear( internal_array_op1 destroy ) { + __TBB_ASSERT( my_segment, NULL ); + size_type j = my_early_size; + my_early_size = 0; + helper for_each(my_segment, my_first_block, 0, 0, 0, j); // element_size is safe to be zero if 'start' is zero + j = for_each.apply( helper::destroy_body(destroy) ); + size_type i = helper::find_segment_end(*this); + return j < i? i : j+1; +} + +void *concurrent_vector_base_v3::internal_compact( size_type element_size, void *table, internal_array_op1 destroy, internal_array_op2 copy ) +{ + const size_type my_size = my_early_size; + const segment_index_t k_end = helper::find_segment_end(*this); // allocated segments + const segment_index_t k_stop = my_size? segment_index_of(my_size-1) + 1 : 0; // number of segments to store existing items: 0=>0; 1,2=>1; 3,4=>2; [5-8]=>3;.. + const segment_index_t first_block = my_first_block; // number of merged segments, getting values from atomics + + segment_index_t k = first_block; + if(k_stop < first_block) + k = k_stop; + else + while (k < k_stop && helper::incompact_predicate(segment_size( k ) * element_size) ) k++; + if(k_stop == k_end && k == first_block) + return NULL; + + segment_t *const segment_table = my_segment; + internal_segments_table &old = *static_cast<internal_segments_table*>( table ); + //this call is left here for sake of backward compatibility, and as a placeholder for table initialization + std::fill_n(old.table,sizeof(old.table)/sizeof(old.table[0]),segment_t()); + old.first_block=0; + + if ( k != first_block && k ) // first segment optimization + { + // exception can occur here + void *seg = helper::allocate_segment(*this, segment_size(k)); + old.table[0].store<relaxed>(seg); + old.first_block = k; // fill info for freeing new segment if exception occurs + // copy items to the new segment + size_type my_segment_size = segment_size( first_block ); + for (segment_index_t i = 0, j = 0; i < k && j < my_size; j = my_segment_size) { + __TBB_ASSERT( segment_table[i].load<relaxed>() == segment_allocated(), NULL); + void *s = static_cast<void*>( + static_cast<char*>(seg) + segment_base(i)*element_size ); + //TODO: refactor to use std::min + if(j + my_segment_size >= my_size) my_segment_size = my_size - j; + __TBB_TRY { // exception can occur here + copy( s, segment_table[i].load<relaxed>().pointer<void>(), my_segment_size ); + } __TBB_CATCH(...) { // destroy all the already copied items + helper for_each(&old.table[0], old.first_block, element_size, + 0, 0, segment_base(i)+ my_segment_size); + for_each.apply( helper::destroy_body(destroy) ); + __TBB_RETHROW(); + } + my_segment_size = i? segment_size( ++i ) : segment_size( i = first_block ); + } + // commit the changes + std::copy(segment_table,segment_table + k,old.table); + for (segment_index_t i = 0; i < k; i++) { + segment_table[i].store<relaxed>(static_cast<void*>( + static_cast<char*>(seg) + segment_base(i)*element_size )); + } + old.first_block = first_block; my_first_block = k; // now, first_block != my_first_block + // destroy original copies + my_segment_size = segment_size( first_block ); // old.first_block actually + for (segment_index_t i = 0, j = 0; i < k && j < my_size; j = my_segment_size) { + if(j + my_segment_size >= my_size) my_segment_size = my_size - j; + // destructors are supposed to not throw any exceptions + destroy( old.table[i].load<relaxed>().pointer<void>(), my_segment_size ); + my_segment_size = i? segment_size( ++i ) : segment_size( i = first_block ); + } + } + // free unnecessary segments allocated by reserve() call + if ( k_stop < k_end ) { + old.first_block = first_block; + std::copy(segment_table+k_stop, segment_table+k_end, old.table+k_stop ); + std::fill_n(segment_table+k_stop, (k_end-k_stop), segment_t()); + if( !k ) my_first_block = 0; + } + return table; +} + +void concurrent_vector_base_v3::internal_swap(concurrent_vector_base_v3& v) +{ + size_type my_sz = my_early_size.load<acquire>(); + size_type v_sz = v.my_early_size.load<relaxed>(); + if(!my_sz && !v_sz) return; + + bool my_was_short = (my_segment.load<relaxed>() == my_storage); + bool v_was_short = (v.my_segment.load<relaxed>() == v.my_storage); + + //In C++11, this would be: swap(my_storage, v.my_storage); + for (int i=0; i < pointers_per_short_table; ++i){ + swap(my_storage[i], v.my_storage[i]); + } + tbb::internal::swap<relaxed>(my_first_block, v.my_first_block); + tbb::internal::swap<relaxed>(my_segment, v.my_segment); + if (my_was_short){ + v.my_segment.store<relaxed>(v.my_storage); + } + if(v_was_short){ + my_segment.store<relaxed>(my_storage); + } + + my_early_size.store<relaxed>(v_sz); + v.my_early_size.store<release>(my_sz); +} + +} // namespace internal + +} // tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/condition_variable.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/condition_variable.cpp new file mode 100644 index 00000000..369a7f77 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/condition_variable.cpp @@ -0,0 +1,205 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" +#include "tbb/compat/condition_variable" +#include "tbb/atomic.h" +#include "tbb_misc.h" +#include "dynamic_link.h" +#include "itt_notify.h" + +namespace tbb { + +namespace internal { + +//condition_variable +#if _WIN32||_WIN64 +using tbb::interface5::internal::condition_variable_using_event; + +static atomic<do_once_state> condvar_api_state; + +void WINAPI init_condvar_using_event( condition_variable_using_event* cv_event ) +{ + // TODO: For Metro port, we can always use the API for condition variables, without dynamic_link etc. + cv_event->event = CreateEventEx(NULL, NULL, 0x1 /*CREATE_EVENT_MANUAL_RESET*/, EVENT_ALL_ACCESS ); + InitializeCriticalSectionEx( &cv_event->mutex, 4000, 0 ); + cv_event->n_waiters = 0; + cv_event->release_count = 0; + cv_event->epoch = 0; +} + +BOOL WINAPI sleep_condition_variable_cs_using_event( condition_variable_using_event* cv_event, LPCRITICAL_SECTION cs, DWORD dwMilliseconds ) +{ + EnterCriticalSection( &cv_event->mutex ); + ++cv_event->n_waiters; + unsigned my_generation = cv_event->epoch; + LeaveCriticalSection( &cv_event->mutex ); + LeaveCriticalSection( cs ); + for (;;) { + // should come here at least once + DWORD rc = WaitForSingleObjectEx( cv_event->event, dwMilliseconds, FALSE ); + EnterCriticalSection( &cv_event->mutex ); + if( rc!=WAIT_OBJECT_0 ) { + --cv_event->n_waiters; + LeaveCriticalSection( &cv_event->mutex ); + if( rc==WAIT_TIMEOUT ) { + SetLastError( WAIT_TIMEOUT ); + EnterCriticalSection( cs ); + } + return false; + } + __TBB_ASSERT( rc==WAIT_OBJECT_0, NULL ); + if( cv_event->release_count>0 && cv_event->epoch!=my_generation ) + break; + LeaveCriticalSection( &cv_event->mutex ); + } + + // still in the critical section + --cv_event->n_waiters; + int count = --cv_event->release_count; + LeaveCriticalSection( &cv_event->mutex ); + + if( count==0 ) { + __TBB_ASSERT( cv_event->event, "Premature destruction of condition variable?" ); + ResetEvent( cv_event->event ); + } + EnterCriticalSection( cs ); + return true; +} + +void WINAPI wake_condition_variable_using_event( condition_variable_using_event* cv_event ) +{ + EnterCriticalSection( &cv_event->mutex ); + if( cv_event->n_waiters>cv_event->release_count ) { + SetEvent( cv_event->event ); // Signal the manual-reset event. + ++cv_event->release_count; + ++cv_event->epoch; + } + LeaveCriticalSection( &cv_event->mutex ); +} + +void WINAPI wake_all_condition_variable_using_event( condition_variable_using_event* cv_event ) +{ + EnterCriticalSection( &cv_event->mutex ); + if( cv_event->n_waiters>0 ) { + SetEvent( cv_event->event ); + cv_event->release_count = cv_event->n_waiters; + ++cv_event->epoch; + } + LeaveCriticalSection( &cv_event->mutex ); +} + +void WINAPI destroy_condvar_using_event( condition_variable_using_event* cv_event ) +{ + HANDLE my_event = cv_event->event; + EnterCriticalSection( &cv_event->mutex ); + // NULL is an invalid HANDLE value + cv_event->event = NULL; + if( cv_event->n_waiters>0 ) { + LeaveCriticalSection( &cv_event->mutex ); + spin_wait_until_eq( cv_event->n_waiters, 0 ); + // make sure the last thread completes its access to cv + EnterCriticalSection( &cv_event->mutex ); + } + LeaveCriticalSection( &cv_event->mutex ); + CloseHandle( my_event ); +} + +void WINAPI destroy_condvar_noop( CONDITION_VARIABLE* /*cv*/ ) { /*no op*/ } + +static void (WINAPI *__TBB_init_condvar)( PCONDITION_VARIABLE ) = (void (WINAPI *)(PCONDITION_VARIABLE))&init_condvar_using_event; +static BOOL (WINAPI *__TBB_condvar_wait)( PCONDITION_VARIABLE, LPCRITICAL_SECTION, DWORD ) = (BOOL (WINAPI *)(PCONDITION_VARIABLE,LPCRITICAL_SECTION, DWORD))&sleep_condition_variable_cs_using_event; +static void (WINAPI *__TBB_condvar_notify_one)( PCONDITION_VARIABLE ) = (void (WINAPI *)(PCONDITION_VARIABLE))&wake_condition_variable_using_event; +static void (WINAPI *__TBB_condvar_notify_all)( PCONDITION_VARIABLE ) = (void (WINAPI *)(PCONDITION_VARIABLE))&wake_all_condition_variable_using_event; +static void (WINAPI *__TBB_destroy_condvar)( PCONDITION_VARIABLE ) = (void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_using_event; + +//! Table describing how to link the handlers. +static const dynamic_link_descriptor CondVarLinkTable[] = { + DLD(InitializeConditionVariable, __TBB_init_condvar), + DLD(SleepConditionVariableCS, __TBB_condvar_wait), + DLD(WakeConditionVariable, __TBB_condvar_notify_one), + DLD(WakeAllConditionVariable, __TBB_condvar_notify_all) +}; + +void init_condvar_module() +{ + __TBB_ASSERT( (uintptr_t)__TBB_init_condvar==(uintptr_t)&init_condvar_using_event, NULL ); +#if __TBB_WIN8UI_SUPPORT + // We expect condition variables to be always available for Windows* store applications, + // so there is no need to check presence and use alternative implementation. + __TBB_init_condvar = (void (WINAPI *)(PCONDITION_VARIABLE))&InitializeConditionVariable; + __TBB_condvar_wait = (BOOL(WINAPI *)(PCONDITION_VARIABLE, LPCRITICAL_SECTION, DWORD))&SleepConditionVariableCS; + __TBB_condvar_notify_one = (void (WINAPI *)(PCONDITION_VARIABLE))&WakeConditionVariable; + __TBB_condvar_notify_all = (void (WINAPI *)(PCONDITION_VARIABLE))&WakeAllConditionVariable; + __TBB_destroy_condvar = (void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_noop; +#else + if (dynamic_link("Kernel32.dll", CondVarLinkTable, 4)) + __TBB_destroy_condvar = (void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_noop; +#endif +} +#endif /* _WIN32||_WIN64 */ + +} // namespace internal + +#if _WIN32||_WIN64 + +namespace interface5 { +namespace internal { + +using tbb::internal::condvar_api_state; +using tbb::internal::__TBB_init_condvar; +using tbb::internal::__TBB_condvar_wait; +using tbb::internal::__TBB_condvar_notify_one; +using tbb::internal::__TBB_condvar_notify_all; +using tbb::internal::__TBB_destroy_condvar; +using tbb::internal::init_condvar_module; + +void internal_initialize_condition_variable( condvar_impl_t& cv ) +{ + atomic_do_once( &init_condvar_module, condvar_api_state ); + __TBB_init_condvar( &cv.cv_native ); +} + +void internal_destroy_condition_variable( condvar_impl_t& cv ) +{ + __TBB_destroy_condvar( &cv.cv_native ); +} + +void internal_condition_variable_notify_one( condvar_impl_t& cv ) +{ + __TBB_condvar_notify_one ( &cv.cv_native ); +} + +void internal_condition_variable_notify_all( condvar_impl_t& cv ) +{ + __TBB_condvar_notify_all( &cv.cv_native ); +} + +bool internal_condition_variable_wait( condvar_impl_t& cv, mutex* mtx, const tick_count::interval_t* i ) +{ + DWORD duration = i ? DWORD((i->seconds()*1000)) : INFINITE; + mtx->set_state( mutex::INITIALIZED ); + BOOL res = __TBB_condvar_wait( &cv.cv_native, mtx->native_handle(), duration ); + mtx->set_state( mutex::HELD ); + return res?true:false; +} + +} // namespace internal +} // nameespace interface5 + +#endif /* _WIN32||_WIN64 */ + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/critical_section.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/critical_section.cpp new file mode 100644 index 00000000..9dbb9fa3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/critical_section.cpp @@ -0,0 +1,27 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/critical_section.h" +#include "itt_notify.h" + +namespace tbb { + namespace internal { + +void critical_section_v4::internal_construct() { + ITT_SYNC_CREATE(&my_impl, _T("ppl::critical_section"), _T("")); +} +} // namespace internal +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/custom_scheduler.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/custom_scheduler.h new file mode 100644 index 00000000..f43a3862 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/custom_scheduler.h @@ -0,0 +1,829 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_custom_scheduler_H +#define _TBB_custom_scheduler_H + +#include "scheduler.h" +#include "observer_proxy.h" +#include "itt_notify.h" + +namespace tbb { +namespace internal { + +//------------------------------------------------------------------------ +//! Traits classes for scheduler +//------------------------------------------------------------------------ + +struct DefaultSchedulerTraits { + static const bool itt_possible = true; + static const bool has_slow_atomic = false; +}; + +struct IntelSchedulerTraits { + static const bool itt_possible = false; +#if __TBB_x86_32||__TBB_x86_64 + static const bool has_slow_atomic = true; +#else + static const bool has_slow_atomic = false; +#endif /* __TBB_x86_32||__TBB_x86_64 */ +}; + +//------------------------------------------------------------------------ +// custom_scheduler +//------------------------------------------------------------------------ + +//! A scheduler with a customized evaluation loop. +/** The customization can use SchedulerTraits to make decisions without needing a run-time check. */ +template<typename SchedulerTraits> +class custom_scheduler: private generic_scheduler { + typedef custom_scheduler<SchedulerTraits> scheduler_type; + + custom_scheduler( market& m, bool genuine ) : generic_scheduler(m, genuine) {} + + //! Scheduler loop that dispatches tasks. + /** If child is non-NULL, it is dispatched first. + Then, until "parent" has a reference count of 1, other task are dispatched or stolen. */ + void local_wait_for_all( task& parent, task* child ) __TBB_override; + + //! Entry point from client code to the scheduler loop that dispatches tasks. + /** The method is virtual, but the *this object is used only for sake of dispatching on the correct vtable, + not necessarily the correct *this object. The correct *this object is looked up in TLS. */ + void wait_for_all( task& parent, task* child ) __TBB_override { + static_cast<custom_scheduler*>(governor::local_scheduler())->scheduler_type::local_wait_for_all( parent, child ); + } + + //! Decrements ref_count of a predecessor. + /** If it achieves 0, the predecessor is scheduled for execution. + When changing, remember that this is a hot path function. */ + void tally_completion_of_predecessor( task& s, __TBB_ISOLATION_ARG( task*& bypass_slot, isolation_tag isolation ) ) { + task_prefix& p = s.prefix(); + __TBB_ASSERT(p.ref_count > 0, NULL); + if( SchedulerTraits::itt_possible ) + ITT_NOTIFY(sync_releasing, &p.ref_count); + if( SchedulerTraits::has_slow_atomic && p.ref_count==1 ) + p.ref_count=0; + else { + reference_count old_ref_count = __TBB_FetchAndDecrementWrelease(&p.ref_count); +#if __TBB_PREVIEW_RESUMABLE_TASKS + if (old_ref_count == internal::abandon_flag + 2) { + // Remove the abandon flag. + p.ref_count = 1; + // The wait has been completed. Spawn a resume task. + tbb::task::resume(p.abandoned_scheduler); + return; + } +#endif + if (old_ref_count > 1) { + // more references exist + // '__TBB_cl_evict(&p)' degraded performance of parallel_preorder example + return; + } + } + + // Ordering on p.ref_count (superfluous if SchedulerTraits::has_slow_atomic) + __TBB_control_consistency_helper(); + __TBB_ASSERT(p.ref_count==0, "completion of task caused predecessor's reference count to underflow"); + if( SchedulerTraits::itt_possible ) + ITT_NOTIFY(sync_acquired, &p.ref_count); +#if TBB_USE_ASSERT + p.extra_state &= ~es_ref_count_active; +#endif /* TBB_USE_ASSERT */ +#if __TBB_TASK_ISOLATION + if ( isolation != no_isolation ) { + // The parent is allowed not to have isolation (even if a child has isolation) because it has never spawned. + __TBB_ASSERT(p.isolation == no_isolation || p.isolation == isolation, NULL); + p.isolation = isolation; + } +#endif /* __TBB_TASK_ISOLATION */ + +#if __TBB_RECYCLE_TO_ENQUEUE + if (p.state==task::to_enqueue) { + // related to __TBB_TASK_ARENA TODO: try keep priority of the task + // e.g. rework task_prefix to remember priority of received task and use here + my_arena->enqueue_task(s, 0, my_random ); + } else +#endif /*__TBB_RECYCLE_TO_ENQUEUE*/ + if( bypass_slot==NULL ) + bypass_slot = &s; +#if __TBB_PREVIEW_CRITICAL_TASKS + else if( internal::is_critical( s ) ) { + local_spawn( bypass_slot, bypass_slot->prefix().next ); + bypass_slot = &s; + } +#endif /* __TBB_PREVIEW_CRITICAL_TASKS */ + else + local_spawn( &s, s.prefix().next ); + } + + //! Implements the bypass loop of the dispatch loop (local_wait_for_all). + bool process_bypass_loop( context_guard_helper</*report_tasks=*/SchedulerTraits::itt_possible>& context_guard, + __TBB_ISOLATION_ARG(task* t, isolation_tag isolation) ); + +public: + static generic_scheduler* allocate_scheduler( market& m, bool genuine ) { + void* p = NFS_Allocate(1, sizeof(scheduler_type), NULL); + std::memset(p, 0, sizeof(scheduler_type)); + scheduler_type* s = new( p ) scheduler_type( m, genuine ); + s->assert_task_pool_valid(); + ITT_SYNC_CREATE(s, SyncType_Scheduler, SyncObj_TaskPoolSpinning); + return s; + } + + //! Try getting a task from the mailbox or stealing from another scheduler. + /** Returns the stolen task or NULL if all attempts fail. */ + task* receive_or_steal_task( __TBB_ISOLATION_ARG( __TBB_atomic reference_count& completion_ref_count, isolation_tag isolation ) ) __TBB_override; + +}; // class custom_scheduler<> + +//------------------------------------------------------------------------ +// custom_scheduler methods +//------------------------------------------------------------------------ +template<typename SchedulerTraits> +task* custom_scheduler<SchedulerTraits>::receive_or_steal_task( __TBB_ISOLATION_ARG(__TBB_atomic reference_count& completion_ref_count, isolation_tag isolation) ) { + task* t = NULL; + bool outermost_worker_level = worker_outermost_level(); + bool outermost_dispatch_level = outermost_worker_level || master_outermost_level(); + bool can_steal_here = can_steal(); + bool outermost_current_worker_level = outermost_worker_level; +#if __TBB_PREVIEW_RESUMABLE_TASKS + outermost_current_worker_level &= my_properties.genuine; +#endif + my_inbox.set_is_idle( true ); +#if __TBB_HOARD_NONLOCAL_TASKS + __TBB_ASSERT(!my_nonlocal_free_list, NULL); +#endif +#if __TBB_TASK_PRIORITY + if ( outermost_dispatch_level ) { + if ( intptr_t skipped_priority = my_arena->my_skipped_fifo_priority ) { + // This thread can dequeue FIFO tasks, and some priority levels of + // FIFO tasks have been bypassed (to prevent deadlock caused by + // dynamic priority changes in nested task group hierarchy). + if ( my_arena->my_skipped_fifo_priority.compare_and_swap(0, skipped_priority) == skipped_priority + && skipped_priority > my_arena->my_top_priority ) + { + my_market->update_arena_priority( *my_arena, skipped_priority ); + } + } + } +#endif /* !__TBB_TASK_PRIORITY */ + // TODO: Try to find a place to reset my_limit (under market's lock) + // The number of slots potentially used in the arena. Updated once in a while, as my_limit changes rarely. + size_t n = my_arena->my_limit-1; + int yield_count = 0; + // The state "failure_count==-1" is used only when itt_possible is true, + // and denotes that a sync_prepare has not yet been issued. + for( int failure_count = -static_cast<int>(SchedulerTraits::itt_possible);; ++failure_count) { + __TBB_ASSERT( my_arena->my_limit > 0, NULL ); + __TBB_ASSERT( my_arena_index <= n, NULL ); + if( completion_ref_count == 1 ) { + if( SchedulerTraits::itt_possible ) { + if( failure_count!=-1 ) { + ITT_NOTIFY(sync_prepare, &completion_ref_count); + // Notify Intel(R) Thread Profiler that thread has stopped spinning. + ITT_NOTIFY(sync_acquired, this); + } + ITT_NOTIFY(sync_acquired, &completion_ref_count); + } + __TBB_ASSERT( !t, NULL ); + // A worker thread in its outermost dispatch loop (i.e. its execution stack is empty) should + // exit it either when there is no more work in the current arena, or when revoked by the market. + __TBB_ASSERT( !outermost_worker_level, NULL ); + __TBB_control_consistency_helper(); // on ref_count + break; // exit stealing loop and return; + } + // Check if the resource manager requires our arena to relinquish some threads + if ( outermost_current_worker_level ) { + if ( ( my_arena->my_num_workers_allotted < my_arena->num_workers_active() ) ) { + if ( SchedulerTraits::itt_possible && failure_count != -1 ) + ITT_NOTIFY(sync_cancel, this); + return NULL; + } + } +#if __TBB_PREVIEW_RESUMABLE_TASKS + else if ( *my_arena_slot->my_scheduler_is_recalled ) { + // Original scheduler was requested, return from stealing loop and recall. + if ( my_inbox.is_idle_state(true) ) + my_inbox.set_is_idle(false); + return NULL; + } +#endif +#if __TBB_TASK_PRIORITY + const int p = int(my_arena->my_top_priority); +#else /* !__TBB_TASK_PRIORITY */ + static const int p = 0; +#endif + // Check if there are tasks mailed to this thread via task-to-thread affinity mechanism. + __TBB_ASSERT(my_affinity_id, NULL); + if ( n && !my_inbox.empty() ) { + t = get_mailbox_task( __TBB_ISOLATION_EXPR( isolation ) ); +#if __TBB_TASK_ISOLATION + // There is a race with a thread adding a new task (possibly with suitable isolation) + // to our mailbox, so the below conditions might result in a false positive. + // Then set_is_idle(false) allows that task to be stolen; it's OK. + if ( isolation != no_isolation && !t && !my_inbox.empty() + && my_inbox.is_idle_state( true ) ) { + // We have proxy tasks in our mailbox but the isolation blocks their execution. + // So publish the proxy tasks in mailbox to be available for stealing from owner's task pool. + my_inbox.set_is_idle( false ); + } +#endif /* __TBB_TASK_ISOLATION */ + } + if ( t ) { + GATHER_STATISTIC( ++my_counters.mails_received ); + } + // Check if there are tasks in starvation-resistant stream. + // Only allowed at the outermost dispatch level without isolation. + else if (__TBB_ISOLATION_EXPR(isolation == no_isolation &&) outermost_dispatch_level && + !my_arena->my_task_stream.empty(p) && ( +#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_CPF_BUILD + t = my_arena->my_task_stream.pop( p, subsequent_lane_selector(my_arena_slot->hint_for_pop) ) +#else + t = my_arena->my_task_stream.pop( p, my_arena_slot->hint_for_pop ) +#endif + ) ) { + ITT_NOTIFY(sync_acquired, &my_arena->my_task_stream); + // just proceed with the obtained task + } +#if __TBB_TASK_PRIORITY + // Check if any earlier offloaded non-top priority tasks become returned to the top level + else if ( my_offloaded_tasks && (t = reload_tasks( __TBB_ISOLATION_EXPR( isolation ) )) ) { + __TBB_ASSERT( !is_proxy(*t), "The proxy task cannot be offloaded" ); + // just proceed with the obtained task + } +#endif /* __TBB_TASK_PRIORITY */ + else if ( can_steal_here && n && (t = steal_task( __TBB_ISOLATION_EXPR(isolation) )) ) { + // just proceed with the obtained task + } +#if __TBB_PREVIEW_CRITICAL_TASKS + else if( (t = get_critical_task( __TBB_ISOLATION_EXPR(isolation) )) ) { + __TBB_ASSERT( internal::is_critical(*t), "Received task must be critical one" ); + ITT_NOTIFY(sync_acquired, &my_arena->my_critical_task_stream); + // just proceed with the obtained task + } +#endif // __TBB_PREVIEW_CRITICAL_TASKS + else + goto fail; + // A task was successfully obtained somewhere + __TBB_ASSERT(t,NULL); +#if __TBB_ARENA_OBSERVER + my_arena->my_observers.notify_entry_observers( my_last_local_observer, is_worker() ); +#endif +#if __TBB_SCHEDULER_OBSERVER + the_global_observer_list.notify_entry_observers( my_last_global_observer, is_worker() ); +#endif /* __TBB_SCHEDULER_OBSERVER */ + if ( SchedulerTraits::itt_possible && failure_count != -1 ) { + // FIXME - might be victim, or might be selected from a mailbox + // Notify Intel(R) Thread Profiler that thread has stopped spinning. + ITT_NOTIFY(sync_acquired, this); + } + break; // exit stealing loop and return +fail: + GATHER_STATISTIC( ++my_counters.steals_failed ); + if( SchedulerTraits::itt_possible && failure_count==-1 ) { + // The first attempt to steal work failed, so notify Intel(R) Thread Profiler that + // the thread has started spinning. Ideally, we would do this notification + // *before* the first failed attempt to steal, but at that point we do not + // know that the steal will fail. + ITT_NOTIFY(sync_prepare, this); + failure_count = 0; + } + // Pause, even if we are going to yield, because the yield might return immediately. + prolonged_pause(); + const int failure_threshold = 2*int(n+1); + if( failure_count>=failure_threshold ) { +#if __TBB_YIELD2P + failure_count = 0; +#else + failure_count = failure_threshold; +#endif + __TBB_Yield(); +#if __TBB_TASK_PRIORITY + // Check if there are tasks abandoned by other workers + if ( my_arena->my_orphaned_tasks ) { + // Epoch must be advanced before seizing the list pointer + ++my_arena->my_abandonment_epoch; + task* orphans = (task*)__TBB_FetchAndStoreW( &my_arena->my_orphaned_tasks, 0 ); + if ( orphans ) { + task** link = NULL; + // Get local counter out of the way (we've just brought in external tasks) + my_local_reload_epoch--; + t = reload_tasks( orphans, link, __TBB_ISOLATION_ARG( effective_reference_priority(), isolation ) ); + if ( orphans ) { + *link = my_offloaded_tasks; + if ( !my_offloaded_tasks ) + my_offloaded_task_list_tail_link = link; + my_offloaded_tasks = orphans; + } + __TBB_ASSERT( !my_offloaded_tasks == !my_offloaded_task_list_tail_link, NULL ); + if ( t ) { + if( SchedulerTraits::itt_possible ) + ITT_NOTIFY(sync_cancel, this); + __TBB_ASSERT( !is_proxy(*t), "The proxy task cannot be offloaded" ); + break; // exit stealing loop and return + } + } + } +#endif /* __TBB_TASK_PRIORITY */ +#if __APPLE__ + // threshold value tuned separately for macOS due to high cost of sched_yield there + const int yield_threshold = 10; +#else + const int yield_threshold = 100; +#endif + if( yield_count++ >= yield_threshold ) { + // When a worker thread has nothing to do, return it to RML. + // For purposes of affinity support, the thread is considered idle while in RML. +#if __TBB_TASK_PRIORITY + if( outermost_current_worker_level || my_arena->my_top_priority > my_arena->my_bottom_priority ) { + if ( my_arena->is_out_of_work() && outermost_current_worker_level ) { +#else /* !__TBB_TASK_PRIORITY */ + if ( outermost_current_worker_level && my_arena->is_out_of_work() ) { +#endif /* !__TBB_TASK_PRIORITY */ + if( SchedulerTraits::itt_possible ) + ITT_NOTIFY(sync_cancel, this); + return NULL; + } +#if __TBB_TASK_PRIORITY + } + if ( my_offloaded_tasks ) { + // Safeguard against any sloppiness in managing reload epoch + // counter (e.g. on the hot path because of performance reasons). + my_local_reload_epoch--; + // Break the deadlock caused by a higher priority dispatch loop + // stealing and offloading a lower priority task. Priority check + // at the stealing moment cannot completely preclude such cases + // because priorities can changes dynamically. + if ( !outermost_worker_level && *my_ref_top_priority > my_arena->my_top_priority ) { + GATHER_STATISTIC( ++my_counters.prio_ref_fixups ); + my_ref_top_priority = &my_arena->my_top_priority; + // it's expected that only outermost workers can use global reload epoch + __TBB_ASSERT(my_ref_reload_epoch == &my_arena->my_reload_epoch, NULL); + } + } +#endif /* __TBB_TASK_PRIORITY */ + } // end of arena snapshot branch + // If several attempts did not find work, re-read the arena limit. + n = my_arena->my_limit-1; + } // end of yielding branch + } // end of nonlocal task retrieval loop + if ( my_inbox.is_idle_state( true ) ) + my_inbox.set_is_idle( false ); + return t; +} + +template<typename SchedulerTraits> +bool custom_scheduler<SchedulerTraits>::process_bypass_loop( + context_guard_helper</*report_tasks=*/SchedulerTraits::itt_possible>& context_guard, + __TBB_ISOLATION_ARG(task* t, isolation_tag isolation) ) +{ + while ( t ) { + __TBB_ASSERT( my_inbox.is_idle_state(false), NULL ); + __TBB_ASSERT(!is_proxy(*t),"unexpected proxy"); + __TBB_ASSERT( t->prefix().owner, NULL ); +#if __TBB_TASK_ISOLATION + __TBB_ASSERT_EX( isolation == no_isolation || isolation == t->prefix().isolation, + "A task from another isolated region is going to be executed" ); +#endif /* __TBB_TASK_ISOLATION */ + assert_task_valid(t); +#if __TBB_TASK_GROUP_CONTEXT && TBB_USE_ASSERT + assert_context_valid(t->prefix().context); + if ( !t->prefix().context->my_cancellation_requested ) +#endif + // TODO: make the assert stronger by prohibiting allocated state. + __TBB_ASSERT( 1L<<t->state() & (1L<<task::allocated|1L<<task::ready|1L<<task::reexecute), NULL ); + assert_task_pool_valid(); +#if __TBB_PREVIEW_CRITICAL_TASKS + // TODO: check performance and optimize if needed for added conditions on the + // hot-path. + if( !internal::is_critical(*t) && !t->is_enqueued_task() ) { + if( task* critical_task = get_critical_task( __TBB_ISOLATION_EXPR(isolation) ) ) { + __TBB_ASSERT( internal::is_critical(*critical_task), + "Received task must be critical one" ); + ITT_NOTIFY(sync_acquired, &my_arena->my_critical_task_stream); + t->prefix().state = task::allocated; + my_innermost_running_task = t; // required during spawn to propagate isolation + local_spawn(t, t->prefix().next); + t = critical_task; + } else { +#endif /* __TBB_PREVIEW_CRITICAL_TASKS */ +#if __TBB_TASK_PRIORITY + intptr_t p = priority(*t); + if ( p != *my_ref_top_priority + && !t->is_enqueued_task() ) { + assert_priority_valid(p); + if ( p != my_arena->my_top_priority ) { + my_market->update_arena_priority( *my_arena, p ); + } + if ( p < effective_reference_priority() ) { + if ( !my_offloaded_tasks ) { + my_offloaded_task_list_tail_link = &t->prefix().next_offloaded; + // Erase possible reference to the owner scheduler + // (next_offloaded is a union member) + *my_offloaded_task_list_tail_link = NULL; + } + offload_task( *t, p ); + t = NULL; + if ( is_task_pool_published() ) { + t = winnow_task_pool( __TBB_ISOLATION_EXPR( isolation ) ); + if ( t ) + continue; + } else { + // Mark arena as full to unlock arena priority level adjustment + // by arena::is_out_of_work(), and ensure worker's presence. + my_arena->advertise_new_work<arena::wakeup>(); + } + break; /* exit bypass loop */ + } + } +#endif /* __TBB_TASK_PRIORITY */ +#if __TBB_PREVIEW_CRITICAL_TASKS + } + } // if is not critical +#endif + task* t_next = NULL; + my_innermost_running_task = t; + t->prefix().owner = this; + t->prefix().state = task::executing; +#if __TBB_TASK_GROUP_CONTEXT + context_guard.set_ctx( t->prefix().context ); + if ( !t->prefix().context->my_cancellation_requested ) +#endif + { + GATHER_STATISTIC( ++my_counters.tasks_executed ); + GATHER_STATISTIC( my_counters.avg_arena_concurrency += my_arena->num_workers_active() ); + GATHER_STATISTIC( my_counters.avg_assigned_workers += my_arena->my_num_workers_allotted ); +#if __TBB_TASK_PRIORITY + GATHER_STATISTIC( my_counters.avg_arena_prio += p ); + GATHER_STATISTIC( my_counters.avg_market_prio += my_market->my_global_top_priority ); +#endif /* __TBB_TASK_PRIORITY */ + ITT_STACK(SchedulerTraits::itt_possible, callee_enter, t->prefix().context->itt_caller); + t_next = t->execute(); + ITT_STACK(SchedulerTraits::itt_possible, callee_leave, t->prefix().context->itt_caller); + if (t_next) { + assert_task_valid(t_next); + __TBB_ASSERT( t_next->state()==task::allocated, + "if task::execute() returns task, it must be marked as allocated" ); + reset_extra_state(t_next); + __TBB_ISOLATION_EXPR( t_next->prefix().isolation = t->prefix().isolation ); +#if TBB_USE_ASSERT + affinity_id next_affinity=t_next->prefix().affinity; + if (next_affinity != 0 && next_affinity != my_affinity_id) + GATHER_STATISTIC( ++my_counters.affinity_ignored ); +#endif + } // if there is bypassed task + } + assert_task_pool_valid(); + switch( t->state() ) { + case task::executing: { + task* s = t->parent(); + __TBB_ASSERT( my_innermost_running_task==t, NULL ); + __TBB_ASSERT( t->prefix().ref_count==0, "Task still has children after it has been executed" ); + t->~task(); + if( s ) + tally_completion_of_predecessor( *s, __TBB_ISOLATION_ARG( t_next, t->prefix().isolation ) ); + free_task<no_hint>( *t ); + poison_pointer( my_innermost_running_task ); + assert_task_pool_valid(); + break; + } + + case task::recycle: // set by recycle_as_safe_continuation() + t->prefix().state = task::allocated; +#if __TBB_RECYCLE_TO_ENQUEUE + __TBB_fallthrough; + case task::to_enqueue: // set by recycle_to_enqueue() +#endif + __TBB_ASSERT( t_next != t, "a task returned from method execute() can not be recycled in another way" ); + reset_extra_state(t); + // for safe continuation, need atomically decrement ref_count; + tally_completion_of_predecessor(*t, __TBB_ISOLATION_ARG( t_next, t->prefix().isolation ) ); + assert_task_pool_valid(); + break; + + case task::reexecute: // set by recycle_to_reexecute() + __TBB_ASSERT( t_next, "reexecution requires that method execute() return another task" ); + __TBB_ASSERT( t_next != t, "a task returned from method execute() can not be recycled in another way" ); + t->prefix().state = task::allocated; + reset_extra_state(t); + local_spawn( t, t->prefix().next ); + assert_task_pool_valid(); + break; + case task::allocated: + reset_extra_state(t); + break; +#if __TBB_PREVIEW_RESUMABLE_TASKS + case task::to_resume: + __TBB_ASSERT(my_innermost_running_task == t, NULL); + __TBB_ASSERT(t->prefix().ref_count == 0, "Task still has children after it has been executed"); + t->~task(); + free_task<no_hint>(*t); + __TBB_ASSERT(!my_properties.genuine && my_properties.outermost, + "Only a coroutine on outermost level can be left."); + // Leave the outermost coroutine + return false; +#endif +#if TBB_USE_ASSERT + case task::ready: + __TBB_ASSERT( false, "task is in READY state upon return from method execute()" ); + break; +#endif + default: + __TBB_ASSERT( false, "illegal state" ); + break; + } + GATHER_STATISTIC( t_next ? ++my_counters.spawns_bypassed : 0 ); + t = t_next; + } // end of scheduler bypass loop + return true; +} + +// TODO: Rename args 'parent' into 'controlling_task' and 'child' into 't' or consider introducing +// a wait object (a la task_handle) to replace the 'parent' logic. +template<typename SchedulerTraits> +void custom_scheduler<SchedulerTraits>::local_wait_for_all( task& parent, task* child ) { + __TBB_ASSERT( governor::is_set(this), NULL ); + __TBB_ASSERT( parent.ref_count() >= (child && child->parent() == &parent ? 2 : 1), "ref_count is too small" ); + __TBB_ASSERT( my_innermost_running_task, NULL ); +#if __TBB_TASK_GROUP_CONTEXT + __TBB_ASSERT( parent.prefix().context, "parent task does not have context" ); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + assert_task_pool_valid(); + // Using parent's refcount in sync_prepare (in the stealing loop below) is + // a workaround for TP. We need to name it here to display correctly in Ampl. + if( SchedulerTraits::itt_possible ) + ITT_SYNC_CREATE(&parent.prefix().ref_count, SyncType_Scheduler, SyncObj_TaskStealingLoop); + + // TODO: consider extending the "context" guard to a "dispatch loop" guard to additionally + // guard old_innermost_running_task and old_properties states. + context_guard_helper</*report_tasks=*/SchedulerTraits::itt_possible> context_guard; + task* old_innermost_running_task = my_innermost_running_task; + scheduler_properties old_properties = my_properties; + + task* t = child; + bool cleanup = !is_worker() && &parent==my_dummy_task; + // Remove outermost property to indicate nested level. + __TBB_ASSERT(my_properties.outermost || my_innermost_running_task!=my_dummy_task, "The outermost property should be set out of a dispatch loop"); + my_properties.outermost &= my_innermost_running_task==my_dummy_task; +#if __TBB_PREVIEW_CRITICAL_TASKS + my_properties.has_taken_critical_task |= is_critical(*my_innermost_running_task); +#endif +#if __TBB_TASK_PRIORITY + __TBB_ASSERT( (uintptr_t)*my_ref_top_priority < (uintptr_t)num_priority_levels, NULL ); + volatile intptr_t *old_ref_top_priority = my_ref_top_priority; + // When entering nested parallelism level market level counter + // must be replaced with the one local to this arena. + volatile uintptr_t *old_ref_reload_epoch = my_ref_reload_epoch; + if ( !outermost_level() ) { + // We are in a nested dispatch loop. + // Market or arena priority must not prevent child tasks from being + // executed so that dynamic priority changes did not cause deadlock. + my_ref_top_priority = &parent.prefix().context->my_priority; + my_ref_reload_epoch = &my_arena->my_reload_epoch; + if (my_ref_reload_epoch != old_ref_reload_epoch) + my_local_reload_epoch = *my_ref_reload_epoch - 1; + } +#endif /* __TBB_TASK_PRIORITY */ +#if __TBB_TASK_ISOLATION + isolation_tag isolation = my_innermost_running_task->prefix().isolation; + if (t && isolation != no_isolation) { + __TBB_ASSERT(t->prefix().isolation == no_isolation, NULL); + // Propagate the isolation to the task executed without spawn. + t->prefix().isolation = isolation; + } +#endif /* __TBB_TASK_ISOLATION */ +#if __TBB_PREVIEW_RESUMABLE_TASKS + // The recall flag for the original owner of this scheduler. + // It is used only on outermost level of currently attached arena slot. + tbb::atomic<bool> recall_flag; + recall_flag = false; + if (outermost_level() && my_wait_task == NULL && my_properties.genuine) { + __TBB_ASSERT(my_arena_slot->my_scheduler == this, NULL); + __TBB_ASSERT(my_arena_slot->my_scheduler_is_recalled == NULL, NULL); + my_arena_slot->my_scheduler_is_recalled = &recall_flag; + my_current_is_recalled = &recall_flag; + } + __TBB_ASSERT(my_arena_slot->my_scheduler_is_recalled != NULL, NULL); + task* old_wait_task = my_wait_task; + my_wait_task = &parent; +#endif +#if TBB_USE_EXCEPTIONS + // Infinite safeguard EH loop + for (;;) { + try { +#endif /* TBB_USE_EXCEPTIONS */ + // Outer loop receives tasks from global environment (via mailbox, FIFO queue(s), + // and by stealing from other threads' task pools). + // All exit points from the dispatch loop are located in its immediate scope. + for(;;) { + // Middle loop retrieves tasks from the local task pool. + for(;;) { + // Inner loop evaluates tasks coming from nesting loops and those returned + // by just executed tasks (bypassing spawn or enqueue calls). + if ( !process_bypass_loop( context_guard, __TBB_ISOLATION_ARG(t, isolation) ) ) { +#if __TBB_PREVIEW_RESUMABLE_TASKS + // Restore the old properties for the coroutine reusage (leave in a valid state) + my_innermost_running_task = old_innermost_running_task; + my_properties = old_properties; + my_wait_task = old_wait_task; +#endif + return; + } + + // Check "normal" exit condition when parent's work is done. + if ( parent.prefix().ref_count == 1 ) { + __TBB_ASSERT( !cleanup, NULL ); + __TBB_control_consistency_helper(); // on ref_count + ITT_NOTIFY( sync_acquired, &parent.prefix().ref_count ); + goto done; + } +#if __TBB_PREVIEW_RESUMABLE_TASKS + // The thread may be otside of its original scheduler. Check the recall request. + if ( &recall_flag != my_arena_slot->my_scheduler_is_recalled ) { + __TBB_ASSERT( my_arena_slot->my_scheduler_is_recalled != NULL, "A broken recall flag" ); + if ( *my_arena_slot->my_scheduler_is_recalled ) { + if ( !resume_original_scheduler() ) { + // We are requested to finish the current coroutine before the resume. + __TBB_ASSERT( !my_properties.genuine && my_properties.outermost, + "Only a coroutine on outermost level can be left." ); + // Restore the old properties for the coroutine reusage (leave in a valid state) + my_innermost_running_task = old_innermost_running_task; + my_properties = old_properties; + my_wait_task = old_wait_task; + return; + } + } + } +#endif + // Retrieve the task from local task pool. + __TBB_ASSERT( is_task_pool_published() || is_quiescent_local_task_pool_reset(), NULL ); + t = is_task_pool_published() ? get_task( __TBB_ISOLATION_EXPR( isolation ) ) : NULL; + assert_task_pool_valid(); + + if ( !t ) // No tasks in the local task pool. Go to stealing loop. + break; + }; // end of local task pool retrieval loop + +#if __TBB_HOARD_NONLOCAL_TASKS + // before stealing, previously stolen task objects are returned + for (; my_nonlocal_free_list; my_nonlocal_free_list = t ) { + t = my_nonlocal_free_list->prefix().next; + free_nonlocal_small_task( *my_nonlocal_free_list ); + } +#endif + if ( cleanup ) { + __TBB_ASSERT( !is_task_pool_published() && is_quiescent_local_task_pool_reset(), NULL ); + __TBB_ASSERT( !worker_outermost_level(), NULL ); + my_innermost_running_task = old_innermost_running_task; + my_properties = old_properties; +#if __TBB_TASK_PRIORITY + my_ref_top_priority = old_ref_top_priority; + if(my_ref_reload_epoch != old_ref_reload_epoch) + my_local_reload_epoch = *old_ref_reload_epoch-1; + my_ref_reload_epoch = old_ref_reload_epoch; +#endif /* __TBB_TASK_PRIORITY */ +#if __TBB_PREVIEW_RESUMABLE_TASKS + if (&recall_flag != my_arena_slot->my_scheduler_is_recalled) { + // The recall point + __TBB_ASSERT(!recall_flag, NULL); + tbb::task::suspend(recall_functor(&recall_flag)); + if (my_inbox.is_idle_state(true)) + my_inbox.set_is_idle(false); + continue; + } + __TBB_ASSERT(&recall_flag == my_arena_slot->my_scheduler_is_recalled, NULL); + __TBB_ASSERT(!(my_wait_task->prefix().ref_count & internal::abandon_flag), NULL); + my_wait_task = old_wait_task; +#endif + return; + } + t = receive_or_steal_task( __TBB_ISOLATION_ARG( parent.prefix().ref_count, isolation ) ); + if ( !t ) { +#if __TBB_PREVIEW_RESUMABLE_TASKS + if ( *my_arena_slot->my_scheduler_is_recalled ) + continue; + // Done if either original thread enters or we are on the nested level or attached the same arena + if ( &recall_flag == my_arena_slot->my_scheduler_is_recalled || old_wait_task != NULL ) + goto done; + // The recall point. Continue dispatch loop because recalled thread may have tasks in it's task pool. + __TBB_ASSERT(!recall_flag, NULL); + tbb::task::suspend( recall_functor(&recall_flag) ); + if ( my_inbox.is_idle_state(true) ) + my_inbox.set_is_idle(false); +#else + // Just exit dispatch loop + goto done; +#endif + } + } // end of infinite stealing loop +#if TBB_USE_EXCEPTIONS + __TBB_ASSERT( false, "Must never get here" ); + } // end of try-block + TbbCatchAll( my_innermost_running_task->prefix().context ); + t = my_innermost_running_task; + // Complete post-processing ... + if( t->state() == task::recycle +#if __TBB_RECYCLE_TO_ENQUEUE + // TODO: the enqueue semantics gets lost below, consider reimplementing + || t->state() == task::to_enqueue +#endif + ) { + // ... for recycled tasks to atomically decrement ref_count + t->prefix().state = task::allocated; + if( SchedulerTraits::itt_possible ) + ITT_NOTIFY(sync_releasing, &t->prefix().ref_count); + if( __TBB_FetchAndDecrementWrelease(&t->prefix().ref_count)==1 ) { + if( SchedulerTraits::itt_possible ) + ITT_NOTIFY(sync_acquired, &t->prefix().ref_count); + }else{ + t = NULL; + } + } + } // end of infinite EH loop + __TBB_ASSERT( false, "Must never get here too" ); +#endif /* TBB_USE_EXCEPTIONS */ +done: +#if __TBB_PREVIEW_RESUMABLE_TASKS + __TBB_ASSERT(!(parent.prefix().ref_count & internal::abandon_flag), NULL); + my_wait_task = old_wait_task; + if (my_wait_task == NULL) { + __TBB_ASSERT(outermost_level(), "my_wait_task could be NULL only on outermost level"); + if (&recall_flag != my_arena_slot->my_scheduler_is_recalled) { + // The recall point. + __TBB_ASSERT(my_properties.genuine, NULL); + __TBB_ASSERT(!recall_flag, NULL); + tbb::task::suspend(recall_functor(&recall_flag)); + if (my_inbox.is_idle_state(true)) + my_inbox.set_is_idle(false); + } + __TBB_ASSERT(my_arena_slot->my_scheduler == this, NULL); + my_arena_slot->my_scheduler_is_recalled = NULL; + my_current_is_recalled = NULL; + } + +#endif /* __TBB_PREVIEW_RESUMABLE_TASKS */ + my_innermost_running_task = old_innermost_running_task; + my_properties = old_properties; +#if __TBB_TASK_PRIORITY + my_ref_top_priority = old_ref_top_priority; + if(my_ref_reload_epoch != old_ref_reload_epoch) + my_local_reload_epoch = *old_ref_reload_epoch-1; + my_ref_reload_epoch = old_ref_reload_epoch; +#endif /* __TBB_TASK_PRIORITY */ + if ( !ConcurrentWaitsEnabled(parent) ) { + if ( parent.prefix().ref_count != 1) { + // This is a worker that was revoked by the market. + __TBB_ASSERT( worker_outermost_level(), + "Worker thread exits nested dispatch loop prematurely" ); + return; + } + parent.prefix().ref_count = 0; + } +#if TBB_USE_ASSERT + parent.prefix().extra_state &= ~es_ref_count_active; +#endif /* TBB_USE_ASSERT */ +#if __TBB_TASK_GROUP_CONTEXT + __TBB_ASSERT(parent.prefix().context && default_context(), NULL); + task_group_context* parent_ctx = parent.prefix().context; + if ( parent_ctx->my_cancellation_requested ) { + task_group_context::exception_container_type *pe = parent_ctx->my_exception; + if ( master_outermost_level() && parent_ctx == default_context() ) { + // We are in the outermost task dispatch loop of a master thread, and + // the whole task tree has been collapsed. So we may clear cancellation data. + parent_ctx->my_cancellation_requested = 0; + // TODO: Add assertion that master's dummy task context does not have children + parent_ctx->my_state &= ~(uintptr_t)task_group_context::may_have_children; + } + if ( pe ) { + // On Windows, FPU control settings changed in the helper destructor are not visible + // outside a catch block. So restore the default settings manually before rethrowing + // the exception. + context_guard.restore_default(); + TbbRethrowException( pe ); + } + } + __TBB_ASSERT(!is_worker() || !CancellationInfoPresent(*my_dummy_task), + "Worker's dummy task context modified"); + __TBB_ASSERT(!master_outermost_level() || !CancellationInfoPresent(*my_dummy_task), + "Unexpected exception or cancellation data in the master's dummy task"); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + assert_task_pool_valid(); +} + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_custom_scheduler_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/dynamic_link.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/dynamic_link.cpp new file mode 100644 index 00000000..d17f042b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/dynamic_link.cpp @@ -0,0 +1,573 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "dynamic_link.h" +#include "tbb/tbb_config.h" + +/* + This file is used by both TBB and OpenMP RTL. Do not use __TBB_ASSERT() macro + and runtime_warning() function because they are not available in OpenMP. Use + LIBRARY_ASSERT and DYNAMIC_LINK_WARNING instead. +*/ + +#include <cstdarg> // va_list etc. +#if _WIN32 + #include <malloc.h> + + // Unify system calls + #define dlopen( name, flags ) LoadLibrary( name ) + #define dlsym( handle, name ) GetProcAddress( handle, name ) + #define dlclose( handle ) ( ! FreeLibrary( handle ) ) + #define dlerror() GetLastError() +#ifndef PATH_MAX + #define PATH_MAX MAX_PATH +#endif +#else /* _WIN32 */ + #include <dlfcn.h> + #include <string.h> + #include <unistd.h> + #include <limits.h> + #include <stdlib.h> +#endif /* _WIN32 */ + +#if __TBB_WEAK_SYMBOLS_PRESENT && !__TBB_DYNAMIC_LOAD_ENABLED + //TODO: use function attribute for weak symbols instead of the pragma. + #pragma weak dlopen + #pragma weak dlsym + #pragma weak dlclose +#endif /* __TBB_WEAK_SYMBOLS_PRESENT && !__TBB_DYNAMIC_LOAD_ENABLED */ + +#include "tbb_misc.h" + +#define __USE_TBB_ATOMICS ( !(__linux__&&__ia64__) || __TBB_BUILD ) +#define __USE_STATIC_DL_INIT ( !__ANDROID__ ) + +#if !__USE_TBB_ATOMICS +#include <pthread.h> +#endif + +/* +dynamic_link is a common interface for searching for required symbols in an +executable and dynamic libraries. + +dynamic_link provides certain guarantees: + 1. Either all or none of the requested symbols are resolved. Moreover, if + symbols are not resolved, the dynamic_link_descriptor table is not modified; + 2. All returned symbols have secured lifetime: this means that none of them + can be invalidated until dynamic_unlink is called; + 3. Any loaded library is loaded only via the full path. The full path is that + from which the runtime itself was loaded. (This is done to avoid security + issues caused by loading libraries from insecure paths). + +dynamic_link searches for the requested symbols in three stages, stopping as +soon as all of the symbols have been resolved. + + 1. Search the global scope: + a. On Windows: dynamic_link tries to obtain the handle of the requested + library and if it succeeds it resolves the symbols via that handle. + b. On Linux: dynamic_link tries to search for the symbols in the global + scope via the main program handle. If the symbols are present in the global + scope their lifetime is not guaranteed (since dynamic_link does not know + anything about the library from which they are exported). Therefore it + tries to "pin" the symbols by obtaining the library name and reopening it. + dlopen may fail to reopen the library in two cases: + i. The symbols are exported from the executable. Currently dynamic _link + cannot handle this situation, so it will not find these symbols in this + step. + ii. The necessary library has been unloaded and cannot be reloaded. It + seems there is nothing that can be done in this case. No symbols are + returned. + + 2. Dynamic load: an attempt is made to load the requested library via the + full path. + The full path used is that from which the runtime itself was loaded. If the + library can be loaded, then an attempt is made to resolve the requested + symbols in the newly loaded library. + If the symbols are not found the library is unloaded. + + 3. Weak symbols: if weak symbols are available they are returned. +*/ + +OPEN_INTERNAL_NAMESPACE + +#if __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED + +#if !defined(DYNAMIC_LINK_WARNING) && !__TBB_WIN8UI_SUPPORT && __TBB_DYNAMIC_LOAD_ENABLED + // Report runtime errors and continue. + #define DYNAMIC_LINK_WARNING dynamic_link_warning + static void dynamic_link_warning( dynamic_link_error_t code, ... ) { + (void) code; + } // library_warning +#endif /* !defined(DYNAMIC_LINK_WARNING) && !__TBB_WIN8UI_SUPPORT && __TBB_DYNAMIC_LOAD_ENABLED */ + + static bool resolve_symbols( dynamic_link_handle module, const dynamic_link_descriptor descriptors[], size_t required ) + { + if ( !module ) + return false; + + #if !__TBB_DYNAMIC_LOAD_ENABLED /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */ + if ( !dlsym ) return false; + #endif /* !__TBB_DYNAMIC_LOAD_ENABLED */ + + const size_t n_desc=20; // Usually we don't have more than 20 descriptors per library + LIBRARY_ASSERT( required <= n_desc, "Too many descriptors is required" ); + if ( required > n_desc ) return false; + pointer_to_handler h[n_desc]; + + for ( size_t k = 0; k < required; ++k ) { + dynamic_link_descriptor const & desc = descriptors[k]; + pointer_to_handler addr = (pointer_to_handler)dlsym( module, desc.name ); + if ( !addr ) { + return false; + } + h[k] = addr; + } + + // Commit the entry points. + // Cannot use memset here, because the writes must be atomic. + for( size_t k = 0; k < required; ++k ) + *descriptors[k].handler = h[k]; + return true; + } + +#if __TBB_WIN8UI_SUPPORT + bool dynamic_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required, dynamic_link_handle*, int flags ) { + dynamic_link_handle tmp_handle = NULL; + TCHAR wlibrary[256]; + if ( MultiByteToWideChar(CP_UTF8, 0, library, -1, wlibrary, 255) == 0 ) return false; + if ( flags & DYNAMIC_LINK_LOAD ) + tmp_handle = LoadPackagedLibrary( wlibrary, 0 ); + if (tmp_handle != NULL){ + return resolve_symbols(tmp_handle, descriptors, required); + }else{ + return false; + } + } + void dynamic_unlink( dynamic_link_handle ) {} + void dynamic_unlink_all() {} +#else +#if __TBB_DYNAMIC_LOAD_ENABLED +/* + There is a security issue on Windows: LoadLibrary() may load and execute malicious code. + See http://www.microsoft.com/technet/security/advisory/2269637.mspx for details. + To avoid the issue, we have to pass full path (not just library name) to LoadLibrary. This + function constructs full path to the specified library (it is assumed the library located + side-by-side with the tbb.dll. + + The function constructs absolute path for given relative path. Important: Base directory is not + current one, it is the directory tbb.dll loaded from. + + Example: + Let us assume "tbb.dll" is located in "c:\program files\common\intel\" directory, e. g. + absolute path of tbb library is "c:\program files\common\intel\tbb.dll". Absolute path for + "tbbmalloc.dll" would be "c:\program files\common\intel\tbbmalloc.dll". Absolute path for + "malloc\tbbmalloc.dll" would be "c:\program files\common\intel\malloc\tbbmalloc.dll". +*/ + + // Struct handle_storage is used by dynamic_link routine to store handles of + // all loaded or pinned dynamic libraries. When TBB is shut down, it calls + // dynamic_unlink_all() that unloads modules referenced by handle_storage. + // This struct should not have any constructors since it may be used before + // the constructor is called. + #define MAX_LOADED_MODULES 8 // The number of maximum possible modules which can be loaded + +#if __USE_TBB_ATOMICS + typedef ::tbb::atomic<size_t> atomic_incrementer; + void init_atomic_incrementer( atomic_incrementer & ) {} + + static void atomic_once( void( *func ) (void), tbb::atomic< tbb::internal::do_once_state > &once_state ) { + tbb::internal::atomic_do_once( func, once_state ); + } + #define ATOMIC_ONCE_DECL( var ) tbb::atomic< tbb::internal::do_once_state > var +#else + static void pthread_assert( int error_code, const char* msg ) { + LIBRARY_ASSERT( error_code == 0, msg ); + } + + class atomic_incrementer { + size_t my_val; + pthread_spinlock_t my_lock; + public: + void init() { + my_val = 0; + pthread_assert( pthread_spin_init( &my_lock, PTHREAD_PROCESS_PRIVATE ), "pthread_spin_init failed" ); + } + size_t operator++(int) { + pthread_assert( pthread_spin_lock( &my_lock ), "pthread_spin_lock failed" ); + size_t prev_val = my_val++; + pthread_assert( pthread_spin_unlock( &my_lock ), "pthread_spin_unlock failed" ); + return prev_val; + } + operator size_t() { + pthread_assert( pthread_spin_lock( &my_lock ), "pthread_spin_lock failed" ); + size_t val = my_val; + pthread_assert( pthread_spin_unlock( &my_lock ), "pthread_spin_unlock failed" ); + return val; + } + ~atomic_incrementer() { + pthread_assert( pthread_spin_destroy( &my_lock ), "pthread_spin_destroy failed" ); + } + }; + + void init_atomic_incrementer( atomic_incrementer &r ) { + r.init(); + } + + static void atomic_once( void( *func ) (), pthread_once_t &once_state ) { + pthread_assert( pthread_once( &once_state, func ), "pthread_once failed" ); + } + #define ATOMIC_ONCE_DECL( var ) pthread_once_t var = PTHREAD_ONCE_INIT +#endif /* __USE_TBB_ATOMICS */ + + struct handles_t { + atomic_incrementer my_size; + dynamic_link_handle my_handles[MAX_LOADED_MODULES]; + + void init() { + init_atomic_incrementer( my_size ); + } + + void add(const dynamic_link_handle &handle) { + const size_t ind = my_size++; + LIBRARY_ASSERT( ind < MAX_LOADED_MODULES, "Too many modules are loaded" ); + my_handles[ind] = handle; + } + + void free() { + const size_t size = my_size; + for (size_t i=0; i<size; ++i) + dynamic_unlink( my_handles[i] ); + } + } handles; + + ATOMIC_ONCE_DECL( init_dl_data_state ); + + static struct ap_data_t { + char _path[PATH_MAX+1]; + size_t _len; + } ap_data; + + static void init_ap_data() { + #if _WIN32 + // Get handle of our DLL first. + HMODULE handle; + BOOL brc = GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCSTR)( & dynamic_link ), // any function inside the library can be used for the address + & handle + ); + if ( !brc ) { // Error occurred. + int err = GetLastError(); + DYNAMIC_LINK_WARNING( dl_sys_fail, "GetModuleHandleEx", err ); + return; + } + // Now get path to our DLL. + DWORD drc = GetModuleFileName( handle, ap_data._path, static_cast< DWORD >( PATH_MAX ) ); + if ( drc == 0 ) { // Error occurred. + int err = GetLastError(); + DYNAMIC_LINK_WARNING( dl_sys_fail, "GetModuleFileName", err ); + return; + } + if ( drc >= PATH_MAX ) { // Buffer too short. + DYNAMIC_LINK_WARNING( dl_buff_too_small ); + return; + } + // Find the position of the last backslash. + char *backslash = strrchr( ap_data._path, '\\' ); + + if ( !backslash ) { // Backslash not found. + LIBRARY_ASSERT( backslash!=NULL, "Unbelievable."); + return; + } + LIBRARY_ASSERT( backslash >= ap_data._path, "Unbelievable."); + ap_data._len = (size_t)(backslash - ap_data._path) + 1; + *(backslash+1) = 0; + #else + // Get the library path + Dl_info dlinfo; + int res = dladdr( (void*)&dynamic_link, &dlinfo ); // any function inside the library can be used for the address + if ( !res ) { + char const * err = dlerror(); + DYNAMIC_LINK_WARNING( dl_sys_fail, "dladdr", err ); + return; + } else { + LIBRARY_ASSERT( dlinfo.dli_fname!=NULL, "Unbelievable." ); + } + + char const *slash = strrchr( dlinfo.dli_fname, '/' ); + size_t fname_len=0; + if ( slash ) { + LIBRARY_ASSERT( slash >= dlinfo.dli_fname, "Unbelievable."); + fname_len = (size_t)(slash - dlinfo.dli_fname) + 1; + } + + size_t rc; + if ( dlinfo.dli_fname[0]=='/' ) { + // The library path is absolute + rc = 0; + ap_data._len = 0; + } else { + // The library path is relative so get the current working directory + if ( !getcwd( ap_data._path, sizeof(ap_data._path)/sizeof(ap_data._path[0]) ) ) { + DYNAMIC_LINK_WARNING( dl_buff_too_small ); + return; + } + ap_data._len = strlen( ap_data._path ); + ap_data._path[ap_data._len++]='/'; + rc = ap_data._len; + } + + if ( fname_len>0 ) { + if ( ap_data._len>PATH_MAX ) { + DYNAMIC_LINK_WARNING( dl_buff_too_small ); + ap_data._len=0; + return; + } + strncpy( ap_data._path+rc, dlinfo.dli_fname, fname_len ); + ap_data._len += fname_len; + ap_data._path[ap_data._len]=0; + } + #endif /* _WIN32 */ + } + + static void init_dl_data() { + handles.init(); + init_ap_data(); + } + + /* + The function constructs absolute path for given relative path. Important: Base directory is not + current one, it is the directory libtbb.so loaded from. + + Arguments: + in name -- Name of a file (may be with relative path; it must not be an absolute one). + out path -- Buffer to save result (absolute path) to. + in len -- Size of buffer. + ret -- 0 -- Error occurred. + > len -- Buffer too short, required size returned. + otherwise -- Ok, number of characters (incl. terminating null) written to buffer. + */ + static size_t abs_path( char const * name, char * path, size_t len ) { + if ( ap_data._len == 0 ) + return 0; + + size_t name_len = strlen( name ); + size_t full_len = name_len+ap_data._len; + if ( full_len < len ) { + __TBB_ASSERT(ap_data._path[ap_data._len] == 0, NULL); + strcpy( path, ap_data._path ); + strcat( path, name ); + } + return full_len+1; // +1 for null character + } +#endif // __TBB_DYNAMIC_LOAD_ENABLED + + void init_dynamic_link_data() { + #if __TBB_DYNAMIC_LOAD_ENABLED + atomic_once( &init_dl_data, init_dl_data_state ); + #endif + } + + #if __USE_STATIC_DL_INIT + // ap_data structure is initialized with current directory on Linux. + // So it should be initialized as soon as possible since the current directory may be changed. + // static_init_ap_data object provides this initialization during library loading. + static struct static_init_dl_data_t { + static_init_dl_data_t() { + init_dynamic_link_data(); + } + } static_init_dl_data; + #endif + + #if __TBB_WEAK_SYMBOLS_PRESENT + static bool weak_symbol_link( const dynamic_link_descriptor descriptors[], size_t required ) + { + // Check if the required entries are present in what was loaded into our process. + for ( size_t k = 0; k < required; ++k ) + if ( !descriptors[k].ptr ) + return false; + // Commit the entry points. + for ( size_t k = 0; k < required; ++k ) + *descriptors[k].handler = (pointer_to_handler) descriptors[k].ptr; + return true; + } + #else + static bool weak_symbol_link( const dynamic_link_descriptor[], size_t ) { + return false; + } + #endif /* __TBB_WEAK_SYMBOLS_PRESENT */ + + void dynamic_unlink( dynamic_link_handle handle ) { + #if !__TBB_DYNAMIC_LOAD_ENABLED /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */ + if ( !dlclose ) return; + #endif + if ( handle ) { + dlclose( handle ); + } + } + + void dynamic_unlink_all() { + #if __TBB_DYNAMIC_LOAD_ENABLED + handles.free(); + #endif + } + +#if !_WIN32 +#if __TBB_DYNAMIC_LOAD_ENABLED + static dynamic_link_handle pin_symbols( dynamic_link_descriptor desc, const dynamic_link_descriptor* descriptors, size_t required ) { + // It is supposed that all symbols are from the only one library + // The library has been loaded by another module and contains at least one requested symbol. + // But after we obtained the symbol the library can be unloaded by another thread + // invalidating our symbol. Therefore we need to pin the library in memory. + dynamic_link_handle library_handle = 0; + Dl_info info; + // Get library's name from earlier found symbol + if ( dladdr( (void*)*desc.handler, &info ) ) { + // Pin the library + library_handle = dlopen( info.dli_fname, RTLD_LAZY ); + if ( library_handle ) { + // If original library was unloaded before we pinned it + // and then another module loaded in its place, the earlier + // found symbol would become invalid. So revalidate them. + if ( !resolve_symbols( library_handle, descriptors, required ) ) { + // Wrong library. + dynamic_unlink(library_handle); + library_handle = 0; + } + } else { + char const * err = dlerror(); + DYNAMIC_LINK_WARNING( dl_lib_not_found, info.dli_fname, err ); + } + } + // else the library has been unloaded by another thread + return library_handle; + } +#endif /* __TBB_DYNAMIC_LOAD_ENABLED */ +#endif /* !_WIN32 */ + + static dynamic_link_handle global_symbols_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required ) { + ::tbb::internal::suppress_unused_warning( library ); + dynamic_link_handle library_handle; +#if _WIN32 + if ( GetModuleHandleEx( 0, library, &library_handle ) ) { + if ( resolve_symbols( library_handle, descriptors, required ) ) + return library_handle; + else + FreeLibrary( library_handle ); + } +#else /* _WIN32 */ + #if !__TBB_DYNAMIC_LOAD_ENABLED /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */ + if ( !dlopen ) return 0; + #endif /* !__TBB_DYNAMIC_LOAD_ENABLED */ + library_handle = dlopen( NULL, RTLD_LAZY ); + #if !__ANDROID__ + // On Android dlopen( NULL ) returns NULL if it is called during dynamic module initialization. + LIBRARY_ASSERT( library_handle, "The handle for the main program is NULL" ); + #endif + #if __TBB_DYNAMIC_LOAD_ENABLED + // Check existence of the first symbol only, then use it to find the library and load all necessary symbols. + pointer_to_handler handler; + dynamic_link_descriptor desc; + desc.name = descriptors[0].name; + desc.handler = &handler; + if ( resolve_symbols( library_handle, &desc, 1 ) ) { + dynamic_unlink( library_handle ); + return pin_symbols( desc, descriptors, required ); + } + #else /* only __TBB_WEAK_SYMBOLS_PRESENT is defined */ + if ( resolve_symbols( library_handle, descriptors, required ) ) + return library_handle; + #endif + dynamic_unlink( library_handle ); +#endif /* _WIN32 */ + return 0; + } + + static void save_library_handle( dynamic_link_handle src, dynamic_link_handle *dst ) { + LIBRARY_ASSERT( src, "The library handle to store must be non-zero" ); + if ( dst ) + *dst = src; + #if __TBB_DYNAMIC_LOAD_ENABLED + else + handles.add( src ); + #endif /* __TBB_DYNAMIC_LOAD_ENABLED */ + } + + dynamic_link_handle dynamic_load( const char* library, const dynamic_link_descriptor descriptors[], size_t required ) { + ::tbb::internal::suppress_unused_warning( library, descriptors, required ); +#if __TBB_DYNAMIC_LOAD_ENABLED + + size_t const len = PATH_MAX + 1; + char path[ len ]; + size_t rc = abs_path( library, path, len ); + if ( 0 < rc && rc <= len ) { +#if _WIN32 + // Prevent Windows from displaying silly message boxes if it fails to load library + // (e.g. because of MS runtime problems - one of those crazy manifest related ones) + UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS); +#endif /* _WIN32 */ + dynamic_link_handle library_handle = dlopen( path, RTLD_LAZY ); +#if _WIN32 + SetErrorMode (prev_mode); +#endif /* _WIN32 */ + if( library_handle ) { + if( !resolve_symbols( library_handle, descriptors, required ) ) { + // The loaded library does not contain all the expected entry points + dynamic_unlink( library_handle ); + library_handle = NULL; + } + } else + DYNAMIC_LINK_WARNING( dl_lib_not_found, path, dlerror() ); + return library_handle; + } else if ( rc>len ) + DYNAMIC_LINK_WARNING( dl_buff_too_small ); + // rc == 0 means failing of init_ap_data so the warning has already been issued. + +#endif /* __TBB_DYNAMIC_LOAD_ENABLED */ + return 0; + } + + bool dynamic_link( const char* library, const dynamic_link_descriptor descriptors[], size_t required, dynamic_link_handle *handle, int flags ) { + init_dynamic_link_data(); + + // TODO: May global_symbols_link find weak symbols? + dynamic_link_handle library_handle = ( flags & DYNAMIC_LINK_GLOBAL ) ? global_symbols_link( library, descriptors, required ) : 0; + + if ( !library_handle && ( flags & DYNAMIC_LINK_LOAD ) ) + library_handle = dynamic_load( library, descriptors, required ); + + if ( !library_handle && ( flags & DYNAMIC_LINK_WEAK ) ) + return weak_symbol_link( descriptors, required ); + + if ( library_handle ) { + save_library_handle( library_handle, handle ); + return true; + } + return false; + } + +#endif /*__TBB_WIN8UI_SUPPORT*/ +#else /* __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED */ + bool dynamic_link( const char*, const dynamic_link_descriptor*, size_t, dynamic_link_handle *handle, int ) { + if ( handle ) + *handle=0; + return false; + } + void dynamic_unlink( dynamic_link_handle ) {} + void dynamic_unlink_all() {} +#endif /* __TBB_WEAK_SYMBOLS_PRESENT || __TBB_DYNAMIC_LOAD_ENABLED */ + +CLOSE_INTERNAL_NAMESPACE diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/dynamic_link.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/dynamic_link.h new file mode 100644 index 00000000..15b8410e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/dynamic_link.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_dynamic_link +#define __TBB_dynamic_link + +// Support for dynamic loading entry points from other shared libraries. + +#include "tbb/tbb_stddef.h" + +#ifdef LIBRARY_ASSERT + #undef __TBB_ASSERT + #define __TBB_ASSERT(x,y) LIBRARY_ASSERT(x,y) +#else + #define LIBRARY_ASSERT(x,y) __TBB_ASSERT_EX(x,y) +#endif /* !LIBRARY_ASSERT */ + +/** By default, symbols declared and defined here go into namespace tbb::internal. + To put them in other namespace, define macros OPEN_INTERNAL_NAMESPACE + and CLOSE_INTERNAL_NAMESPACE to override the following default definitions. **/ +#ifndef OPEN_INTERNAL_NAMESPACE +#define OPEN_INTERNAL_NAMESPACE namespace tbb { namespace internal { +#define CLOSE_INTERNAL_NAMESPACE }} +#endif /* OPEN_INTERNAL_NAMESPACE */ + +#include <stddef.h> +#if _WIN32 +#include "tbb/machine/windows_api.h" +#endif /* _WIN32 */ + +OPEN_INTERNAL_NAMESPACE + +//! Type definition for a pointer to a void somefunc(void) +typedef void (*pointer_to_handler)(); + +//! The helper to construct dynamic_link_descriptor structure +// Double cast through the void* in DLD macro is necessary to +// prevent warnings from some compilers (g++ 4.1) +#if __TBB_WEAK_SYMBOLS_PRESENT +#define DLD(s,h) {#s, (pointer_to_handler*)(void*)(&h), (pointer_to_handler)&s} +#define DLD_NOWEAK(s,h) {#s, (pointer_to_handler*)(void*)(&h), NULL} +#else +#define DLD(s,h) {#s, (pointer_to_handler*)(void*)(&h)} +#define DLD_NOWEAK(s,h) DLD(s,h) +#endif /* __TBB_WEAK_SYMBOLS_PRESENT */ +//! Association between a handler name and location of pointer to it. +struct dynamic_link_descriptor { + //! Name of the handler + const char* name; + //! Pointer to the handler + pointer_to_handler* handler; +#if __TBB_WEAK_SYMBOLS_PRESENT + //! Weak symbol + pointer_to_handler ptr; +#endif +}; + +#if _WIN32 +typedef HMODULE dynamic_link_handle; +#else +typedef void* dynamic_link_handle; +#endif /* _WIN32 */ + +const int DYNAMIC_LINK_GLOBAL = 0x01; +const int DYNAMIC_LINK_LOAD = 0x02; +const int DYNAMIC_LINK_WEAK = 0x04; +const int DYNAMIC_LINK_ALL = DYNAMIC_LINK_GLOBAL | DYNAMIC_LINK_LOAD | DYNAMIC_LINK_WEAK; + +//! Fill in dynamically linked handlers. +/** 'library' is the name of the requested library. It should not contain a full + path since dynamic_link adds the full path (from which the runtime itself + was loaded) to the library name. + 'required' is the number of the initial entries in the array descriptors[] + that have to be found in order for the call to succeed. If the library and + all the required handlers are found, then the corresponding handler + pointers are set, and the return value is true. Otherwise the original + array of descriptors is left untouched and the return value is false. + 'required' is limited by 20 (exceeding of this value will result in failure + to load the symbols and the return value will be false). + 'handle' is the handle of the library if it is loaded. Otherwise it is left + untouched. + 'flags' is the set of DYNAMIC_LINK_* flags. Each of the DYNAMIC_LINK_* flags + allows its corresponding linking stage. +**/ +bool dynamic_link( const char* library, + const dynamic_link_descriptor descriptors[], + size_t required, + dynamic_link_handle* handle = 0, + int flags = DYNAMIC_LINK_ALL ); + +void dynamic_unlink( dynamic_link_handle handle ); + +void dynamic_unlink_all(); + +enum dynamic_link_error_t { + dl_success = 0, + dl_lib_not_found, // char const * lib, dlerr_t err + dl_sym_not_found, // char const * sym, dlerr_t err + // Note: dlerr_t depends on OS: it is char const * on Linux* and macOS*, int on Windows*. + dl_sys_fail, // char const * func, int err + dl_buff_too_small // none +}; // dynamic_link_error_t + +CLOSE_INTERNAL_NAMESPACE + +#endif /* __TBB_dynamic_link */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/governor.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/governor.cpp new file mode 100644 index 00000000..49502451 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/governor.cpp @@ -0,0 +1,549 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include "governor.h" +#include "tbb_main.h" +#include "scheduler.h" +#include "market.h" +#include "arena.h" + +#include "tbb/task_scheduler_init.h" + +#include "dynamic_link.h" + +namespace tbb { +namespace internal { + +//------------------------------------------------------------------------ +// governor +//------------------------------------------------------------------------ + +#if __TBB_SURVIVE_THREAD_SWITCH +// Support for interoperability with Intel(R) Cilk(TM) Plus. + +#if _WIN32 +#define CILKLIB_NAME "cilkrts20.dll" +#else +#define CILKLIB_NAME "libcilkrts.so" +#endif + +//! Handler for interoperation with cilkrts library. +static __cilk_tbb_retcode (*watch_stack_handler)(struct __cilk_tbb_unwatch_thunk* u, + struct __cilk_tbb_stack_op_thunk o); + +//! Table describing how to link the handlers. +static const dynamic_link_descriptor CilkLinkTable[] = { + DLD_NOWEAK(__cilkrts_watch_stack, watch_stack_handler) +}; + +static atomic<do_once_state> cilkrts_load_state; + +bool initialize_cilk_interop() { + // Pinning can fail. This is a normal situation, and means that the current + // thread does not use cilkrts and consequently does not need interop. + return dynamic_link( CILKLIB_NAME, CilkLinkTable, 1, /*handle=*/0, DYNAMIC_LINK_GLOBAL ); +} +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ + +namespace rml { + tbb_server* make_private_server( tbb_client& client ); +} + +void governor::acquire_resources () { +#if USE_PTHREAD + int status = theTLS.create(auto_terminate); +#else + int status = theTLS.create(); +#endif + if( status ) + handle_perror(status, "TBB failed to initialize task scheduler TLS\n"); + is_speculation_enabled = cpu_has_speculation(); + is_rethrow_broken = gcc_rethrow_exception_broken(); +} + +void governor::release_resources () { + theRMLServerFactory.close(); + destroy_process_mask(); +#if TBB_USE_ASSERT + if( __TBB_InitOnce::initialization_done() && theTLS.get() ) + runtime_warning( "TBB is unloaded while tbb::task_scheduler_init object is alive?" ); +#endif + int status = theTLS.destroy(); + if( status ) + runtime_warning("failed to destroy task scheduler TLS: %s", strerror(status)); + dynamic_unlink_all(); +} + +rml::tbb_server* governor::create_rml_server ( rml::tbb_client& client ) { + rml::tbb_server* server = NULL; + if( !UsePrivateRML ) { + ::rml::factory::status_type status = theRMLServerFactory.make_server( server, client ); + if( status != ::rml::factory::st_success ) { + UsePrivateRML = true; + runtime_warning( "rml::tbb_factory::make_server failed with status %x, falling back on private rml", status ); + } + } + if ( !server ) { + __TBB_ASSERT( UsePrivateRML, NULL ); + server = rml::make_private_server( client ); + } + __TBB_ASSERT( server, "Failed to create RML server" ); + return server; +} + + +uintptr_t governor::tls_value_of( generic_scheduler* s ) { + __TBB_ASSERT( (uintptr_t(s)&1) == 0, "Bad pointer to the scheduler" ); + // LSB marks the scheduler initialized with arena + return uintptr_t(s) | uintptr_t((s && (s->my_arena || s->is_worker()))? 1 : 0); +} + +void governor::assume_scheduler( generic_scheduler* s ) { + theTLS.set( tls_value_of(s) ); +} + +bool governor::is_set( generic_scheduler* s ) { + return theTLS.get() == tls_value_of(s); +} + +void governor::sign_on(generic_scheduler* s) { + __TBB_ASSERT( is_set(NULL) && s, NULL ); + assume_scheduler( s ); +#if __TBB_SURVIVE_THREAD_SWITCH + if( watch_stack_handler ) { + __cilk_tbb_stack_op_thunk o; + o.routine = &stack_op_handler; + o.data = s; + if( (*watch_stack_handler)(&s->my_cilk_unwatch_thunk, o) ) { + // Failed to register with cilkrts, make sure we are clean + s->my_cilk_unwatch_thunk.routine = NULL; + } +#if TBB_USE_ASSERT + else + s->my_cilk_state = generic_scheduler::cs_running; +#endif /* TBB_USE_ASSERT */ + } +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ + __TBB_ASSERT( is_set(s), NULL ); +} + +void governor::sign_off(generic_scheduler* s) { + suppress_unused_warning(s); + __TBB_ASSERT( is_set(s), "attempt to unregister a wrong scheduler instance" ); + assume_scheduler(NULL); +#if __TBB_SURVIVE_THREAD_SWITCH + __cilk_tbb_unwatch_thunk &ut = s->my_cilk_unwatch_thunk; + if ( ut.routine ) + (*ut.routine)(ut.data); +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ +} + +void governor::one_time_init() { + if( !__TBB_InitOnce::initialization_done() ) + DoOneTimeInitializations(); +#if __TBB_SURVIVE_THREAD_SWITCH + atomic_do_once( &initialize_cilk_interop, cilkrts_load_state ); +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ +} + +generic_scheduler* governor::init_scheduler_weak() { + one_time_init(); + __TBB_ASSERT( is_set(NULL), "TLS contains a scheduler?" ); + generic_scheduler* s = generic_scheduler::create_master( NULL ); // without arena + s->my_auto_initialized = true; + return s; +} + +generic_scheduler* governor::init_scheduler( int num_threads, stack_size_type stack_size, bool auto_init ) { + one_time_init(); + if ( uintptr_t v = theTLS.get() ) { + generic_scheduler* s = tls_scheduler_of( v ); + if ( (v&1) == 0 ) { // TLS holds scheduler instance without arena + __TBB_ASSERT( s->my_ref_count == 1, "weakly initialized scheduler must have refcount equal to 1" ); + __TBB_ASSERT( !s->my_arena, "weakly initialized scheduler must have no arena" ); + __TBB_ASSERT( s->my_auto_initialized, "weakly initialized scheduler is supposed to be auto-initialized" ); + s->attach_arena( market::create_arena( default_num_threads(), 1, 0 ), 0, /*is_master*/true ); + __TBB_ASSERT( s->my_arena_index == 0, "Master thread must occupy the first slot in its arena" ); + s->my_arena_slot->my_scheduler = s; +#if __TBB_TASK_GROUP_CONTEXT + s->my_arena->my_default_ctx = s->default_context(); // it also transfers implied ownership +#endif + // Mark the scheduler as fully initialized + assume_scheduler( s ); + } + // Increment refcount only for explicit instances of task_scheduler_init. + if ( !auto_init ) s->my_ref_count += 1; + __TBB_ASSERT( s->my_arena, "scheduler is not initialized fully" ); + return s; + } + // Create new scheduler instance with arena + if( num_threads == task_scheduler_init::automatic ) + num_threads = default_num_threads(); + arena *a = market::create_arena( num_threads, 1, stack_size ); + generic_scheduler* s = generic_scheduler::create_master( a ); + __TBB_ASSERT(s, "Somehow a local scheduler creation for a master thread failed"); + __TBB_ASSERT( is_set(s), NULL ); + s->my_auto_initialized = auto_init; + return s; +} + +bool governor::terminate_scheduler( generic_scheduler* s, bool blocking ) { + bool ok = false; + __TBB_ASSERT( is_set(s), "Attempt to terminate non-local scheduler instance" ); + if (0 == --(s->my_ref_count)) { + ok = s->cleanup_master( blocking ); + __TBB_ASSERT( is_set(NULL), "cleanup_master has not cleared its TLS slot" ); + } + return ok; +} + +void governor::auto_terminate(void* arg){ + generic_scheduler* s = tls_scheduler_of( uintptr_t(arg) ); // arg is equivalent to theTLS.get() + if( s && s->my_auto_initialized ) { + if( !--(s->my_ref_count) ) { + // If the TLS slot is already cleared by OS or underlying concurrency + // runtime, restore its value. + if( !is_set(s) ) + assume_scheduler(s); + s->cleanup_master( /*blocking_terminate=*/false ); + __TBB_ASSERT( is_set(NULL), "cleanup_master has not cleared its TLS slot" ); + } + } +} + +void governor::print_version_info () { + if ( UsePrivateRML ) + PrintExtraVersionInfo( "RML", "private" ); + else { + PrintExtraVersionInfo( "RML", "shared" ); + theRMLServerFactory.call_with_server_info( PrintRMLVersionInfo, (void*)"" ); + } +#if __TBB_SURVIVE_THREAD_SWITCH + if( watch_stack_handler ) + PrintExtraVersionInfo( "CILK", CILKLIB_NAME ); +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ +} + +void governor::initialize_rml_factory () { + ::rml::factory::status_type res = theRMLServerFactory.open(); + UsePrivateRML = res != ::rml::factory::st_success; +} + +#if __TBB_SURVIVE_THREAD_SWITCH +__cilk_tbb_retcode governor::stack_op_handler( __cilk_tbb_stack_op op, void* data ) { + __TBB_ASSERT(data,NULL); + generic_scheduler* s = static_cast<generic_scheduler*>(data); +#if TBB_USE_ASSERT + void* current = local_scheduler_if_initialized(); +#if _WIN32||_WIN64 + uintptr_t thread_id = GetCurrentThreadId(); +#else + uintptr_t thread_id = uintptr_t(pthread_self()); +#endif +#endif /* TBB_USE_ASSERT */ + switch( op ) { + case CILK_TBB_STACK_ADOPT: { + __TBB_ASSERT( !current && s->my_cilk_state==generic_scheduler::cs_limbo || + current==s && s->my_cilk_state==generic_scheduler::cs_running, "invalid adoption" ); +#if TBB_USE_ASSERT + if( current==s ) + runtime_warning( "redundant adoption of %p by thread %p\n", s, (void*)thread_id ); + s->my_cilk_state = generic_scheduler::cs_running; +#endif /* TBB_USE_ASSERT */ + assume_scheduler( s ); + break; + } + case CILK_TBB_STACK_ORPHAN: { + __TBB_ASSERT( current==s && s->my_cilk_state==generic_scheduler::cs_running, "invalid orphaning" ); +#if TBB_USE_ASSERT + s->my_cilk_state = generic_scheduler::cs_limbo; +#endif /* TBB_USE_ASSERT */ + assume_scheduler(NULL); + break; + } + case CILK_TBB_STACK_RELEASE: { + __TBB_ASSERT( !current && s->my_cilk_state==generic_scheduler::cs_limbo || + current==s && s->my_cilk_state==generic_scheduler::cs_running, "invalid release" ); +#if TBB_USE_ASSERT + s->my_cilk_state = generic_scheduler::cs_freed; +#endif /* TBB_USE_ASSERT */ + s->my_cilk_unwatch_thunk.routine = NULL; + auto_terminate( s ); + break; + } + default: + __TBB_ASSERT(0, "invalid op"); + } + return 0; +} +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ + +#if __TBB_NUMA_SUPPORT + +#if __TBB_WEAK_SYMBOLS_PRESENT +#pragma weak initialize_numa_topology +#pragma weak allocate_binding_handler +#pragma weak deallocate_binding_handler +#pragma weak bind_to_node +#pragma weak restore_affinity + +extern "C" { +void initialize_numa_topology( + size_t groups_num, int& nodes_count, int*& indexes_list, int*& concurrency_list ); + +binding_handler* allocate_binding_handler( int slot_num ); +void deallocate_binding_handler( binding_handler* handler_ptr ); + +void bind_to_node( binding_handler* handler_ptr, int slot_num, int numa_id ); +void restore_affinity( binding_handler* handler_ptr, int slot_num ); +} +#endif /* __TBB_WEAK_SYMBOLS_PRESENT */ + +// Handlers for communication with TBBbind +#if _WIN32 || _WIN64 || __linux__ +static void (*initialize_numa_topology_ptr)( + size_t groups_num, int& nodes_count, int*& indexes_list, int*& concurrency_list ) = NULL; +#endif /* _WIN32 || _WIN64 || __linux__ */ + +static binding_handler* (*allocate_binding_handler_ptr)( int slot_num ) = NULL; +static void (*deallocate_binding_handler_ptr)( binding_handler* handler_ptr ) = NULL; + +static void (*bind_to_node_ptr)( binding_handler* handler_ptr, int slot_num, int numa_id ) = NULL; +static void (*restore_affinity_ptr)( binding_handler* handler_ptr, int slot_num ) = NULL; + +#if _WIN32 || _WIN64 || __linux__ +// Table describing how to link the handlers. +static const dynamic_link_descriptor TbbBindLinkTable[] = { + DLD(initialize_numa_topology, initialize_numa_topology_ptr), + DLD(allocate_binding_handler, allocate_binding_handler_ptr), + DLD(deallocate_binding_handler, deallocate_binding_handler_ptr), + DLD(bind_to_node, bind_to_node_ptr), + DLD(restore_affinity, restore_affinity_ptr) +}; + +static const unsigned LinkTableSize = 5; + +#if TBB_USE_DEBUG +#define DEBUG_SUFFIX "_debug" +#else +#define DEBUG_SUFFIX +#endif /* TBB_USE_DEBUG */ + +#if _WIN32 || _WIN64 +#define TBBBIND_NAME "tbbbind" DEBUG_SUFFIX ".dll" +#elif __linux__ +#define TBBBIND_NAME "libtbbbind" DEBUG_SUFFIX __TBB_STRING(.so.TBB_COMPATIBLE_INTERFACE_VERSION) +#endif /* __linux__ */ +#endif /* _WIN32 || _WIN64 || __linux__ */ + +// Stubs that will be used if TBBbind library is unavailable. +static binding_handler* dummy_allocate_binding_handler ( int ) { return NULL; } +static void dummy_deallocate_binding_handler ( binding_handler* ) { } +static void dummy_bind_to_node ( binding_handler*, int, int ) { } +static void dummy_restore_affinity ( binding_handler*, int ) { } + +// Representation of NUMA topology information on the TBB side. +// NUMA topology may be initialized by third-party component (e.g. hwloc) +// or just filled by default stubs (1 NUMA node with 0 index and +// default_num_threads value as default_concurrency). +namespace numa_topology { +namespace { +int numa_nodes_count = 0; +int* numa_indexes = NULL; +int* default_concurrency_list = NULL; +static tbb::atomic<do_once_state> numa_topology_init_state; +} // internal namespace + +// Tries to load TBBbind library API, if success, gets NUMA topology information from it, +// in another case, fills NUMA topology by stubs. +// TODO: Add TBBbind loading status if TBB_VERSION is set. +void initialization_impl() { + governor::one_time_init(); + +#if _WIN32 || _WIN64 || __linux__ + bool load_tbbbind = true; +#if _WIN32 && !_WIN64 + // For 32-bit Windows applications, process affinity masks can only support up to 32 logical CPUs. + SYSTEM_INFO si; + GetNativeSystemInfo(&si); + load_tbbbind = si.dwNumberOfProcessors <= 32; +#endif /* _WIN32 && !_WIN64 */ + + if (load_tbbbind && dynamic_link(TBBBIND_NAME, TbbBindLinkTable, LinkTableSize)) { + int number_of_groups = 1; +#if _WIN32 || _WIN64 + number_of_groups = NumberOfProcessorGroups(); +#endif /* _WIN32 || _WIN64 */ + initialize_numa_topology_ptr( + number_of_groups, numa_nodes_count, numa_indexes, default_concurrency_list); + + if (numa_nodes_count==1 && numa_indexes[0] >= 0) { + __TBB_ASSERT(default_concurrency_list[numa_indexes[0]] == (int)governor::default_num_threads(), + "default_concurrency() should be equal to governor::default_num_threads() on single" + "NUMA node systems."); + } + return; + } +#endif /* _WIN32 || _WIN64 || __linux__ */ + + static int dummy_index = -1; + static int dummy_concurrency = governor::default_num_threads(); + + numa_nodes_count = 1; + numa_indexes = &dummy_index; + default_concurrency_list = &dummy_concurrency; + + allocate_binding_handler_ptr = dummy_allocate_binding_handler; + deallocate_binding_handler_ptr = dummy_deallocate_binding_handler; + + bind_to_node_ptr = dummy_bind_to_node; + restore_affinity_ptr = dummy_restore_affinity; +} + +void initialize() { + atomic_do_once(initialization_impl, numa_topology_init_state); +} + +unsigned nodes_count() { + initialize(); + return numa_nodes_count; +} + +void fill( int* indexes_array ) { + initialize(); + for ( int i = 0; i < numa_nodes_count; i++ ) { + indexes_array[i] = numa_indexes[i]; + } +} + +int default_concurrency( int node_id ) { + if (node_id >= 0) { + initialize(); + return default_concurrency_list[node_id]; + } + return governor::default_num_threads(); +} + +} // namespace numa_topology + +binding_handler* construct_binding_handler(int slot_num) { + __TBB_ASSERT(allocate_binding_handler_ptr, "tbbbind loading was not perfromed"); + return allocate_binding_handler_ptr(slot_num); +} + +void destroy_binding_handler(binding_handler* handler_ptr) { + __TBB_ASSERT(deallocate_binding_handler_ptr, "tbbbind loading was not perfromed"); + deallocate_binding_handler_ptr(handler_ptr); +} + +void bind_thread_to_node(binding_handler* handler_ptr, int slot_num , int numa_id) { + __TBB_ASSERT(slot_num >= 0, "Negative thread index"); + __TBB_ASSERT(bind_to_node_ptr, "tbbbind loading was not perfromed"); + bind_to_node_ptr(handler_ptr, slot_num, numa_id); +} + +void restore_affinity_mask(binding_handler* handler_ptr, int slot_num) { + __TBB_ASSERT(slot_num >= 0, "Negative thread index"); + __TBB_ASSERT(restore_affinity_ptr, "tbbbind loading was not perfromed"); + restore_affinity_ptr(handler_ptr, slot_num); +} + +#endif /* __TBB_NUMA_SUPPORT */ + +} // namespace internal + +//------------------------------------------------------------------------ +// task_scheduler_init +//------------------------------------------------------------------------ + +using namespace internal; + +/** Left out-of-line for the sake of the backward binary compatibility **/ +void task_scheduler_init::initialize( int number_of_threads ) { + initialize( number_of_threads, 0 ); +} + +void task_scheduler_init::initialize( int number_of_threads, stack_size_type thread_stack_size ) { +#if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS + uintptr_t new_mode = thread_stack_size & propagation_mode_mask; +#endif + thread_stack_size &= ~(stack_size_type)propagation_mode_mask; + if( number_of_threads!=deferred ) { + __TBB_ASSERT_RELEASE( !my_scheduler, "task_scheduler_init already initialized" ); + __TBB_ASSERT_RELEASE( number_of_threads==automatic || number_of_threads > 0, + "number_of_threads for task_scheduler_init must be automatic or positive" ); + internal::generic_scheduler *s = governor::init_scheduler( number_of_threads, thread_stack_size, /*auto_init=*/false ); +#if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS + if ( s->master_outermost_level() ) { + uintptr_t &vt = s->default_context()->my_version_and_traits; + uintptr_t prev_mode = vt & task_group_context::exact_exception ? propagation_mode_exact : 0; + vt = new_mode & propagation_mode_exact ? vt | task_group_context::exact_exception + : new_mode & propagation_mode_captured ? vt & ~task_group_context::exact_exception : vt; + // Use least significant bit of the scheduler pointer to store previous mode. + // This is necessary when components compiled with different compilers and/or + // TBB versions initialize the + my_scheduler = static_cast<scheduler*>((generic_scheduler*)((uintptr_t)s | prev_mode)); + } + else +#endif /* __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS */ + my_scheduler = s; + } else { + __TBB_ASSERT_RELEASE( !thread_stack_size, "deferred initialization ignores stack size setting" ); + } +} + +bool task_scheduler_init::internal_terminate( bool blocking ) { +#if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS + uintptr_t prev_mode = (uintptr_t)my_scheduler & propagation_mode_exact; + my_scheduler = (scheduler*)((uintptr_t)my_scheduler & ~(uintptr_t)propagation_mode_exact); +#endif /* __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS */ + generic_scheduler* s = static_cast<generic_scheduler*>(my_scheduler); + my_scheduler = NULL; + __TBB_ASSERT_RELEASE( s, "task_scheduler_init::terminate without corresponding task_scheduler_init::initialize()"); +#if __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS + if ( s->master_outermost_level() ) { + uintptr_t &vt = s->default_context()->my_version_and_traits; + vt = prev_mode & propagation_mode_exact ? vt | task_group_context::exact_exception + : vt & ~task_group_context::exact_exception; + } +#endif /* __TBB_TASK_GROUP_CONTEXT && TBB_USE_EXCEPTIONS */ + return governor::terminate_scheduler(s, blocking); +} + +void task_scheduler_init::terminate() { + internal_terminate(/*blocking_terminate=*/false); +} + +#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE +bool task_scheduler_init::internal_blocking_terminate( bool throwing ) { + bool ok = internal_terminate( /*blocking_terminate=*/true ); +#if TBB_USE_EXCEPTIONS + if( throwing && !ok ) + throw_exception( eid_blocking_thread_join_impossible ); +#else + suppress_unused_warning( throwing ); +#endif + return ok; +} +#endif // __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE + +int task_scheduler_init::default_num_threads() { + return governor::default_num_threads(); +} + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/governor.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/governor.h new file mode 100644 index 00000000..8cecdf2e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/governor.h @@ -0,0 +1,166 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_governor_H +#define _TBB_governor_H + +#include "tbb/task_scheduler_init.h" +#include "../rml/include/rml_tbb.h" + +#include "tbb_misc.h" // for AvailableHwConcurrency +#include "tls.h" + +#if __TBB_SURVIVE_THREAD_SWITCH +#include "cilk-tbb-interop.h" +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ + +namespace tbb { +namespace internal { + +class market; +class generic_scheduler; +class __TBB_InitOnce; + +namespace rml { +class tbb_client; +} + +//------------------------------------------------------------------------ +// Class governor +//------------------------------------------------------------------------ + +//! The class handles access to the single instance of market, and to TLS to keep scheduler instances. +/** It also supports automatic on-demand initialization of the TBB scheduler. + The class contains only static data members and methods.*/ +class governor { +private: + friend class __TBB_InitOnce; + friend class market; + + //! TLS for scheduler instances associated with individual threads + static basic_tls<uintptr_t> theTLS; + + //! Caches the maximal level of parallelism supported by the hardware + static unsigned DefaultNumberOfThreads; + + //! Caches the size of OS regular memory page + static size_t DefaultPageSize; + + static rml::tbb_factory theRMLServerFactory; + + static bool UsePrivateRML; + + // Flags for runtime-specific conditions + static bool is_speculation_enabled; + static bool is_rethrow_broken; + + //! Create key for thread-local storage and initialize RML. + static void acquire_resources (); + + //! Destroy the thread-local storage key and deinitialize RML. + static void release_resources (); + + static rml::tbb_server* create_rml_server ( rml::tbb_client& ); + + //! The internal routine to undo automatic initialization. + /** The signature is written with void* so that the routine + can be the destructor argument to pthread_key_create. */ + static void auto_terminate(void* scheduler); + +public: + static unsigned default_num_threads () { + // No memory fence required, because at worst each invoking thread calls AvailableHwConcurrency once. + return DefaultNumberOfThreads ? DefaultNumberOfThreads : + DefaultNumberOfThreads = AvailableHwConcurrency(); + } + static size_t default_page_size () { + return DefaultPageSize ? DefaultPageSize : + DefaultPageSize = DefaultSystemPageSize(); + } + static void one_time_init(); + //! Processes scheduler initialization request (possibly nested) in a master thread + /** If necessary creates new instance of arena and/or local scheduler. + The auto_init argument specifies if the call is due to automatic initialization. **/ + static generic_scheduler* init_scheduler( int num_threads, stack_size_type stack_size, bool auto_init ); + + //! Automatic initialization of scheduler in a master thread with default settings without arena + static generic_scheduler* init_scheduler_weak(); + + //! Processes scheduler termination request (possibly nested) in a master thread + static bool terminate_scheduler( generic_scheduler* s, bool blocking ); + + //! Register TBB scheduler instance in thread-local storage. + static void sign_on( generic_scheduler* s ); + + //! Unregister TBB scheduler instance from thread-local storage. + static void sign_off( generic_scheduler* s ); + + //! Used to check validity of the local scheduler TLS contents. + static bool is_set( generic_scheduler* s ); + + //! Temporarily set TLS slot to the given scheduler + static void assume_scheduler( generic_scheduler* s ); + + //! Computes the value of the TLS + static uintptr_t tls_value_of( generic_scheduler* s ); + + // TODO IDEA: refactor bit manipulations over pointer types to a class? + //! Converts TLS value to the scheduler pointer + static generic_scheduler* tls_scheduler_of( uintptr_t v ) { + return (generic_scheduler*)(v & ~uintptr_t(1)); + } + + //! Obtain the thread-local instance of the TBB scheduler. + /** If the scheduler has not been initialized yet, initialization is done automatically. + Note that auto-initialized scheduler instance is destroyed only when its thread terminates. **/ + static generic_scheduler* local_scheduler () { + uintptr_t v = theTLS.get(); + return (v&1) ? tls_scheduler_of(v) : init_scheduler( task_scheduler_init::automatic, 0, /*auto_init=*/true ); + } + + static generic_scheduler* local_scheduler_weak () { + uintptr_t v = theTLS.get(); + return v ? tls_scheduler_of(v) : init_scheduler_weak(); + } + + static generic_scheduler* local_scheduler_if_initialized () { + return tls_scheduler_of( theTLS.get() ); + } + + //! Undo automatic initialization if necessary; call when a thread exits. + static void terminate_auto_initialized_scheduler() { + auto_terminate( local_scheduler_if_initialized() ); + } + + static void print_version_info (); + + static void initialize_rml_factory (); + + static bool does_client_join_workers (const tbb::internal::rml::tbb_client &client); + +#if __TBB_SURVIVE_THREAD_SWITCH + static __cilk_tbb_retcode stack_op_handler( __cilk_tbb_stack_op op, void* ); +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ + + static bool speculation_enabled() { return is_speculation_enabled; } + static bool rethrow_exception_broken() { return is_rethrow_broken; } + +}; // class governor + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_governor_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/atomic_support.asm b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/atomic_support.asm new file mode 100644 index 00000000..3c196231 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/atomic_support.asm @@ -0,0 +1,184 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +.686 +.model flat,c +.code + ALIGN 4 + PUBLIC c __TBB_machine_fetchadd1 +__TBB_machine_fetchadd1: + mov edx,4[esp] + mov eax,8[esp] + lock xadd [edx],al + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_fetchstore1 +__TBB_machine_fetchstore1: + mov edx,4[esp] + mov eax,8[esp] + lock xchg [edx],al + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_cmpswp1 +__TBB_machine_cmpswp1: + mov edx,4[esp] + mov ecx,8[esp] + mov eax,12[esp] + lock cmpxchg [edx],cl + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_fetchadd2 +__TBB_machine_fetchadd2: + mov edx,4[esp] + mov eax,8[esp] + lock xadd [edx],ax + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_fetchstore2 +__TBB_machine_fetchstore2: + mov edx,4[esp] + mov eax,8[esp] + lock xchg [edx],ax + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_cmpswp2 +__TBB_machine_cmpswp2: + mov edx,4[esp] + mov ecx,8[esp] + mov eax,12[esp] + lock cmpxchg [edx],cx + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_fetchadd4 +__TBB_machine_fetchadd4: + mov edx,4[esp] + mov eax,8[esp] + lock xadd [edx],eax + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_fetchstore4 +__TBB_machine_fetchstore4: + mov edx,4[esp] + mov eax,8[esp] + lock xchg [edx],eax + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_cmpswp4 +__TBB_machine_cmpswp4: + mov edx,4[esp] + mov ecx,8[esp] + mov eax,12[esp] + lock cmpxchg [edx],ecx + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_fetchadd8 +__TBB_machine_fetchadd8: + push ebx + push edi + mov edi,12[esp] + mov eax,[edi] + mov edx,4[edi] +__TBB_machine_fetchadd8_loop: + mov ebx,16[esp] + mov ecx,20[esp] + add ebx,eax + adc ecx,edx + lock cmpxchg8b qword ptr [edi] + jnz __TBB_machine_fetchadd8_loop + pop edi + pop ebx + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_fetchstore8 +__TBB_machine_fetchstore8: + push ebx + push edi + mov edi,12[esp] + mov ebx,16[esp] + mov ecx,20[esp] + mov eax,[edi] + mov edx,4[edi] +__TBB_machine_fetchstore8_loop: + lock cmpxchg8b qword ptr [edi] + jnz __TBB_machine_fetchstore8_loop + pop edi + pop ebx + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_cmpswp8 +__TBB_machine_cmpswp8: + push ebx + push edi + mov edi,12[esp] + mov ebx,16[esp] + mov ecx,20[esp] + mov eax,24[esp] + mov edx,28[esp] + lock cmpxchg8b qword ptr [edi] + pop edi + pop ebx + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_load8 +__TBB_machine_Load8: + ; If location is on stack, compiler may have failed to align it correctly, so we do dynamic check. + mov ecx,4[esp] + test ecx,7 + jne load_slow + ; Load within a cache line + sub esp,12 + fild qword ptr [ecx] + fistp qword ptr [esp] + mov eax,[esp] + mov edx,4[esp] + add esp,12 + ret +load_slow: + ; Load is misaligned. Use cmpxchg8b. + push ebx + push edi + mov edi,ecx + xor eax,eax + xor ebx,ebx + xor ecx,ecx + xor edx,edx + lock cmpxchg8b qword ptr [edi] + pop edi + pop ebx + ret +EXTRN __TBB_machine_store8_slow:PROC +.code + ALIGN 4 + PUBLIC c __TBB_machine_store8 +__TBB_machine_Store8: + ; If location is on stack, compiler may have failed to align it correctly, so we do dynamic check. + mov ecx,4[esp] + test ecx,7 + jne __TBB_machine_store8_slow ;; tail call to tbb_misc.cpp + fild qword ptr 8[esp] + fistp qword ptr [ecx] + ret +end diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/itsx.asm b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/itsx.asm new file mode 100644 index 00000000..d89da227 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/itsx.asm @@ -0,0 +1,76 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +.686 +.model flat,c +.code + ALIGN 4 + PUBLIC c __TBB_machine_try_lock_elided +__TBB_machine_try_lock_elided: + mov ecx, 4[esp] + xor eax, eax + mov al, 1 + BYTE 0F2H + xchg al, byte ptr [ecx] + xor al, 1 + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_unlock_elided +__TBB_machine_unlock_elided: + mov ecx, 4[esp] + BYTE 0F3H + mov byte ptr [ecx], 0 + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_begin_transaction +__TBB_machine_begin_transaction: + mov eax, -1 + BYTE 0C7H + BYTE 0F8H + BYTE 000H + BYTE 000H + BYTE 000H + BYTE 000H + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_end_transaction +__TBB_machine_end_transaction: + BYTE 00FH + BYTE 001H + BYTE 0D5H + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_transaction_conflict_abort +__TBB_machine_transaction_conflict_abort: + BYTE 0C6H + BYTE 0F8H + BYTE 0FFH ; 12.4.5 Abort argument: lock not free when tested + ret +.code + ALIGN 4 + PUBLIC c __TBB_machine_is_in_transaction +__TBB_machine_is_in_transaction: + xor eax, eax + BYTE 00FH + BYTE 001H + BYTE 0D6H + JZ rset + MOV al,1 +rset: + RET +end diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/lock_byte.asm b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/lock_byte.asm new file mode 100644 index 00000000..7baeec21 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia32-masm/lock_byte.asm @@ -0,0 +1,34 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +; DO NOT EDIT - AUTOMATICALLY GENERATED FROM .s FILE +.686 +.model flat,c +.code + ALIGN 4 + PUBLIC c __TBB_machine_trylockbyte +__TBB_machine_trylockbyte: + mov edx,4[esp] + mov al,[edx] + mov cl,1 + test al,1 + jnz __TBB_machine_trylockbyte_contended + lock cmpxchg [edx],cl + jne __TBB_machine_trylockbyte_contended + mov eax,1 + ret +__TBB_machine_trylockbyte_contended: + xor eax,eax + ret +end diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/atomic_support.s b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/atomic_support.s new file mode 100644 index 00000000..4c49fedf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/atomic_support.s @@ -0,0 +1,666 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh +# 1 "<stdin>" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "<stdin>" + + + + + + .section .text + .align 16 + + + .proc __TBB_machine_fetchadd1__TBB_full_fence# + .global __TBB_machine_fetchadd1__TBB_full_fence# +__TBB_machine_fetchadd1__TBB_full_fence: +{ + mf + br __TBB_machine_fetchadd1acquire +} + .endp __TBB_machine_fetchadd1__TBB_full_fence# + + .proc __TBB_machine_fetchadd1acquire# + .global __TBB_machine_fetchadd1acquire# +__TBB_machine_fetchadd1acquire: + + + + + + + + ld1 r9=[r32] +;; +Retry_1acquire: + mov ar.ccv=r9 + mov r8=r9; + add r10=r9,r33 +;; + cmpxchg1.acq r9=[r32],r10,ar.ccv +;; + cmp.ne p7,p0=r8,r9 + (p7) br.cond.dpnt Retry_1acquire + br.ret.sptk.many b0 +# 49 "<stdin>" + .endp __TBB_machine_fetchadd1acquire# +# 62 "<stdin>" + .section .text + .align 16 + .proc __TBB_machine_fetchstore1__TBB_full_fence# + .global __TBB_machine_fetchstore1__TBB_full_fence# +__TBB_machine_fetchstore1__TBB_full_fence: + mf +;; + xchg1 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore1__TBB_full_fence# + + + .proc __TBB_machine_fetchstore1acquire# + .global __TBB_machine_fetchstore1acquire# +__TBB_machine_fetchstore1acquire: + xchg1 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore1acquire# +# 88 "<stdin>" + .section .text + .align 16 + + + .proc __TBB_machine_cmpswp1__TBB_full_fence# + .global __TBB_machine_cmpswp1__TBB_full_fence# +__TBB_machine_cmpswp1__TBB_full_fence: +{ + mf + br __TBB_machine_cmpswp1acquire +} + .endp __TBB_machine_cmpswp1__TBB_full_fence# + + .proc __TBB_machine_cmpswp1acquire# + .global __TBB_machine_cmpswp1acquire# +__TBB_machine_cmpswp1acquire: + + zxt1 r34=r34 +;; + + mov ar.ccv=r34 +;; + cmpxchg1.acq r8=[r32],r33,ar.ccv + br.ret.sptk.many b0 + .endp __TBB_machine_cmpswp1acquire# +// DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh +# 1 "<stdin>" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "<stdin>" + + + + + + .section .text + .align 16 + + + .proc __TBB_machine_fetchadd2__TBB_full_fence# + .global __TBB_machine_fetchadd2__TBB_full_fence# +__TBB_machine_fetchadd2__TBB_full_fence: +{ + mf + br __TBB_machine_fetchadd2acquire +} + .endp __TBB_machine_fetchadd2__TBB_full_fence# + + .proc __TBB_machine_fetchadd2acquire# + .global __TBB_machine_fetchadd2acquire# +__TBB_machine_fetchadd2acquire: + + + + + + + + ld2 r9=[r32] +;; +Retry_2acquire: + mov ar.ccv=r9 + mov r8=r9; + add r10=r9,r33 +;; + cmpxchg2.acq r9=[r32],r10,ar.ccv +;; + cmp.ne p7,p0=r8,r9 + (p7) br.cond.dpnt Retry_2acquire + br.ret.sptk.many b0 +# 49 "<stdin>" + .endp __TBB_machine_fetchadd2acquire# +# 62 "<stdin>" + .section .text + .align 16 + .proc __TBB_machine_fetchstore2__TBB_full_fence# + .global __TBB_machine_fetchstore2__TBB_full_fence# +__TBB_machine_fetchstore2__TBB_full_fence: + mf +;; + xchg2 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore2__TBB_full_fence# + + + .proc __TBB_machine_fetchstore2acquire# + .global __TBB_machine_fetchstore2acquire# +__TBB_machine_fetchstore2acquire: + xchg2 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore2acquire# +# 88 "<stdin>" + .section .text + .align 16 + + + .proc __TBB_machine_cmpswp2__TBB_full_fence# + .global __TBB_machine_cmpswp2__TBB_full_fence# +__TBB_machine_cmpswp2__TBB_full_fence: +{ + mf + br __TBB_machine_cmpswp2acquire +} + .endp __TBB_machine_cmpswp2__TBB_full_fence# + + .proc __TBB_machine_cmpswp2acquire# + .global __TBB_machine_cmpswp2acquire# +__TBB_machine_cmpswp2acquire: + + zxt2 r34=r34 +;; + + mov ar.ccv=r34 +;; + cmpxchg2.acq r8=[r32],r33,ar.ccv + br.ret.sptk.many b0 + .endp __TBB_machine_cmpswp2acquire# +// DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh +# 1 "<stdin>" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "<stdin>" + + + + + + .section .text + .align 16 + + + .proc __TBB_machine_fetchadd4__TBB_full_fence# + .global __TBB_machine_fetchadd4__TBB_full_fence# +__TBB_machine_fetchadd4__TBB_full_fence: +{ + mf + br __TBB_machine_fetchadd4acquire +} + .endp __TBB_machine_fetchadd4__TBB_full_fence# + + .proc __TBB_machine_fetchadd4acquire# + .global __TBB_machine_fetchadd4acquire# +__TBB_machine_fetchadd4acquire: + + cmp.eq p6,p0=1,r33 + cmp.eq p8,p0=-1,r33 + (p6) br.cond.dptk Inc_4acquire + (p8) br.cond.dpnt Dec_4acquire +;; + + ld4 r9=[r32] +;; +Retry_4acquire: + mov ar.ccv=r9 + mov r8=r9; + add r10=r9,r33 +;; + cmpxchg4.acq r9=[r32],r10,ar.ccv +;; + cmp.ne p7,p0=r8,r9 + (p7) br.cond.dpnt Retry_4acquire + br.ret.sptk.many b0 + +Inc_4acquire: + fetchadd4.acq r8=[r32],1 + br.ret.sptk.many b0 +Dec_4acquire: + fetchadd4.acq r8=[r32],-1 + br.ret.sptk.many b0 + + .endp __TBB_machine_fetchadd4acquire# +# 62 "<stdin>" + .section .text + .align 16 + .proc __TBB_machine_fetchstore4__TBB_full_fence# + .global __TBB_machine_fetchstore4__TBB_full_fence# +__TBB_machine_fetchstore4__TBB_full_fence: + mf +;; + xchg4 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore4__TBB_full_fence# + + + .proc __TBB_machine_fetchstore4acquire# + .global __TBB_machine_fetchstore4acquire# +__TBB_machine_fetchstore4acquire: + xchg4 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore4acquire# +# 88 "<stdin>" + .section .text + .align 16 + + + .proc __TBB_machine_cmpswp4__TBB_full_fence# + .global __TBB_machine_cmpswp4__TBB_full_fence# +__TBB_machine_cmpswp4__TBB_full_fence: +{ + mf + br __TBB_machine_cmpswp4acquire +} + .endp __TBB_machine_cmpswp4__TBB_full_fence# + + .proc __TBB_machine_cmpswp4acquire# + .global __TBB_machine_cmpswp4acquire# +__TBB_machine_cmpswp4acquire: + + zxt4 r34=r34 +;; + + mov ar.ccv=r34 +;; + cmpxchg4.acq r8=[r32],r33,ar.ccv + br.ret.sptk.many b0 + .endp __TBB_machine_cmpswp4acquire# +// DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh +# 1 "<stdin>" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "<stdin>" + + + + + + .section .text + .align 16 + + + .proc __TBB_machine_fetchadd8__TBB_full_fence# + .global __TBB_machine_fetchadd8__TBB_full_fence# +__TBB_machine_fetchadd8__TBB_full_fence: +{ + mf + br __TBB_machine_fetchadd8acquire +} + .endp __TBB_machine_fetchadd8__TBB_full_fence# + + .proc __TBB_machine_fetchadd8acquire# + .global __TBB_machine_fetchadd8acquire# +__TBB_machine_fetchadd8acquire: + + cmp.eq p6,p0=1,r33 + cmp.eq p8,p0=-1,r33 + (p6) br.cond.dptk Inc_8acquire + (p8) br.cond.dpnt Dec_8acquire +;; + + ld8 r9=[r32] +;; +Retry_8acquire: + mov ar.ccv=r9 + mov r8=r9; + add r10=r9,r33 +;; + cmpxchg8.acq r9=[r32],r10,ar.ccv +;; + cmp.ne p7,p0=r8,r9 + (p7) br.cond.dpnt Retry_8acquire + br.ret.sptk.many b0 + +Inc_8acquire: + fetchadd8.acq r8=[r32],1 + br.ret.sptk.many b0 +Dec_8acquire: + fetchadd8.acq r8=[r32],-1 + br.ret.sptk.many b0 + + .endp __TBB_machine_fetchadd8acquire# +# 62 "<stdin>" + .section .text + .align 16 + .proc __TBB_machine_fetchstore8__TBB_full_fence# + .global __TBB_machine_fetchstore8__TBB_full_fence# +__TBB_machine_fetchstore8__TBB_full_fence: + mf +;; + xchg8 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore8__TBB_full_fence# + + + .proc __TBB_machine_fetchstore8acquire# + .global __TBB_machine_fetchstore8acquire# +__TBB_machine_fetchstore8acquire: + xchg8 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore8acquire# +# 88 "<stdin>" + .section .text + .align 16 + + + .proc __TBB_machine_cmpswp8__TBB_full_fence# + .global __TBB_machine_cmpswp8__TBB_full_fence# +__TBB_machine_cmpswp8__TBB_full_fence: +{ + mf + br __TBB_machine_cmpswp8acquire +} + .endp __TBB_machine_cmpswp8__TBB_full_fence# + + .proc __TBB_machine_cmpswp8acquire# + .global __TBB_machine_cmpswp8acquire# +__TBB_machine_cmpswp8acquire: + + + + + mov ar.ccv=r34 +;; + cmpxchg8.acq r8=[r32],r33,ar.ccv + br.ret.sptk.many b0 + .endp __TBB_machine_cmpswp8acquire# +// DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh +# 1 "<stdin>" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "<stdin>" + + + + + + .section .text + .align 16 +# 19 "<stdin>" + .proc __TBB_machine_fetchadd1release# + .global __TBB_machine_fetchadd1release# +__TBB_machine_fetchadd1release: + + + + + + + + ld1 r9=[r32] +;; +Retry_1release: + mov ar.ccv=r9 + mov r8=r9; + add r10=r9,r33 +;; + cmpxchg1.rel r9=[r32],r10,ar.ccv +;; + cmp.ne p7,p0=r8,r9 + (p7) br.cond.dpnt Retry_1release + br.ret.sptk.many b0 +# 49 "<stdin>" + .endp __TBB_machine_fetchadd1release# +# 62 "<stdin>" + .section .text + .align 16 + .proc __TBB_machine_fetchstore1release# + .global __TBB_machine_fetchstore1release# +__TBB_machine_fetchstore1release: + mf +;; + xchg1 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore1release# +# 88 "<stdin>" + .section .text + .align 16 +# 101 "<stdin>" + .proc __TBB_machine_cmpswp1release# + .global __TBB_machine_cmpswp1release# +__TBB_machine_cmpswp1release: + + zxt1 r34=r34 +;; + + mov ar.ccv=r34 +;; + cmpxchg1.rel r8=[r32],r33,ar.ccv + br.ret.sptk.many b0 + .endp __TBB_machine_cmpswp1release# +// DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh +# 1 "<stdin>" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "<stdin>" + + + + + + .section .text + .align 16 +# 19 "<stdin>" + .proc __TBB_machine_fetchadd2release# + .global __TBB_machine_fetchadd2release# +__TBB_machine_fetchadd2release: + + + + + + + + ld2 r9=[r32] +;; +Retry_2release: + mov ar.ccv=r9 + mov r8=r9; + add r10=r9,r33 +;; + cmpxchg2.rel r9=[r32],r10,ar.ccv +;; + cmp.ne p7,p0=r8,r9 + (p7) br.cond.dpnt Retry_2release + br.ret.sptk.many b0 +# 49 "<stdin>" + .endp __TBB_machine_fetchadd2release# +# 62 "<stdin>" + .section .text + .align 16 + .proc __TBB_machine_fetchstore2release# + .global __TBB_machine_fetchstore2release# +__TBB_machine_fetchstore2release: + mf +;; + xchg2 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore2release# +# 88 "<stdin>" + .section .text + .align 16 +# 101 "<stdin>" + .proc __TBB_machine_cmpswp2release# + .global __TBB_machine_cmpswp2release# +__TBB_machine_cmpswp2release: + + zxt2 r34=r34 +;; + + mov ar.ccv=r34 +;; + cmpxchg2.rel r8=[r32],r33,ar.ccv + br.ret.sptk.many b0 + .endp __TBB_machine_cmpswp2release# +// DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh +# 1 "<stdin>" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "<stdin>" + + + + + + .section .text + .align 16 +# 19 "<stdin>" + .proc __TBB_machine_fetchadd4release# + .global __TBB_machine_fetchadd4release# +__TBB_machine_fetchadd4release: + + cmp.eq p6,p0=1,r33 + cmp.eq p8,p0=-1,r33 + (p6) br.cond.dptk Inc_4release + (p8) br.cond.dpnt Dec_4release +;; + + ld4 r9=[r32] +;; +Retry_4release: + mov ar.ccv=r9 + mov r8=r9; + add r10=r9,r33 +;; + cmpxchg4.rel r9=[r32],r10,ar.ccv +;; + cmp.ne p7,p0=r8,r9 + (p7) br.cond.dpnt Retry_4release + br.ret.sptk.many b0 + +Inc_4release: + fetchadd4.rel r8=[r32],1 + br.ret.sptk.many b0 +Dec_4release: + fetchadd4.rel r8=[r32],-1 + br.ret.sptk.many b0 + + .endp __TBB_machine_fetchadd4release# +# 62 "<stdin>" + .section .text + .align 16 + .proc __TBB_machine_fetchstore4release# + .global __TBB_machine_fetchstore4release# +__TBB_machine_fetchstore4release: + mf +;; + xchg4 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore4release# +# 88 "<stdin>" + .section .text + .align 16 +# 101 "<stdin>" + .proc __TBB_machine_cmpswp4release# + .global __TBB_machine_cmpswp4release# +__TBB_machine_cmpswp4release: + + zxt4 r34=r34 +;; + + mov ar.ccv=r34 +;; + cmpxchg4.rel r8=[r32],r33,ar.ccv + br.ret.sptk.many b0 + .endp __TBB_machine_cmpswp4release# +// DO NOT EDIT - AUTOMATICALLY GENERATED FROM tools/generate_atomic/ipf_generate.sh +# 1 "<stdin>" +# 1 "<built-in>" +# 1 "<command line>" +# 1 "<stdin>" + + + + + + .section .text + .align 16 +# 19 "<stdin>" + .proc __TBB_machine_fetchadd8release# + .global __TBB_machine_fetchadd8release# +__TBB_machine_fetchadd8release: + + cmp.eq p6,p0=1,r33 + cmp.eq p8,p0=-1,r33 + (p6) br.cond.dptk Inc_8release + (p8) br.cond.dpnt Dec_8release +;; + + ld8 r9=[r32] +;; +Retry_8release: + mov ar.ccv=r9 + mov r8=r9; + add r10=r9,r33 +;; + cmpxchg8.rel r9=[r32],r10,ar.ccv +;; + cmp.ne p7,p0=r8,r9 + (p7) br.cond.dpnt Retry_8release + br.ret.sptk.many b0 + +Inc_8release: + fetchadd8.rel r8=[r32],1 + br.ret.sptk.many b0 +Dec_8release: + fetchadd8.rel r8=[r32],-1 + br.ret.sptk.many b0 + + .endp __TBB_machine_fetchadd8release# +# 62 "<stdin>" + .section .text + .align 16 + .proc __TBB_machine_fetchstore8release# + .global __TBB_machine_fetchstore8release# +__TBB_machine_fetchstore8release: + mf +;; + xchg8 r8=[r32],r33 + br.ret.sptk.many b0 + .endp __TBB_machine_fetchstore8release# +# 88 "<stdin>" + .section .text + .align 16 +# 101 "<stdin>" + .proc __TBB_machine_cmpswp8release# + .global __TBB_machine_cmpswp8release# +__TBB_machine_cmpswp8release: + + + + + mov ar.ccv=r34 +;; + cmpxchg8.rel r8=[r32],r33,ar.ccv + br.ret.sptk.many b0 + .endp __TBB_machine_cmpswp8release# diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/ia64_misc.s b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/ia64_misc.s new file mode 100644 index 00000000..73554a7e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/ia64_misc.s @@ -0,0 +1,95 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + // RSE backing store pointer retrieval + .section .text + .align 16 + .proc __TBB_get_bsp# + .global __TBB_get_bsp# +__TBB_get_bsp: + mov r8=ar.bsp + br.ret.sptk.many b0 + .endp __TBB_get_bsp# + + .section .text + .align 16 + .proc __TBB_machine_load8_relaxed# + .global __TBB_machine_load8_relaxed# +__TBB_machine_load8_relaxed: + ld8 r8=[r32] + br.ret.sptk.many b0 + .endp __TBB_machine_load8_relaxed# + + .section .text + .align 16 + .proc __TBB_machine_store8_relaxed# + .global __TBB_machine_store8_relaxed# +__TBB_machine_store8_relaxed: + st8 [r32]=r33 + br.ret.sptk.many b0 + .endp __TBB_machine_store8_relaxed# + + .section .text + .align 16 + .proc __TBB_machine_load4_relaxed# + .global __TBB_machine_load4_relaxed# +__TBB_machine_load4_relaxed: + ld4 r8=[r32] + br.ret.sptk.many b0 + .endp __TBB_machine_load4_relaxed# + + .section .text + .align 16 + .proc __TBB_machine_store4_relaxed# + .global __TBB_machine_store4_relaxed# +__TBB_machine_store4_relaxed: + st4 [r32]=r33 + br.ret.sptk.many b0 + .endp __TBB_machine_store4_relaxed# + + .section .text + .align 16 + .proc __TBB_machine_load2_relaxed# + .global __TBB_machine_load2_relaxed# +__TBB_machine_load2_relaxed: + ld2 r8=[r32] + br.ret.sptk.many b0 + .endp __TBB_machine_load2_relaxed# + + .section .text + .align 16 + .proc __TBB_machine_store2_relaxed# + .global __TBB_machine_store2_relaxed# +__TBB_machine_store2_relaxed: + st2 [r32]=r33 + br.ret.sptk.many b0 + .endp __TBB_machine_store2_relaxed# + + .section .text + .align 16 + .proc __TBB_machine_load1_relaxed# + .global __TBB_machine_load1_relaxed# +__TBB_machine_load1_relaxed: + ld1 r8=[r32] + br.ret.sptk.many b0 + .endp __TBB_machine_load1_relaxed# + + .section .text + .align 16 + .proc __TBB_machine_store1_relaxed# + .global __TBB_machine_store1_relaxed# +__TBB_machine_store1_relaxed: + st1 [r32]=r33 + br.ret.sptk.many b0 + .endp __TBB_machine_store1_relaxed# diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/lock_byte.s b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/lock_byte.s new file mode 100644 index 00000000..ee9c240b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/lock_byte.s @@ -0,0 +1,42 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + // Support for class TinyLock + .section .text + .align 16 + // unsigned int __TBB_machine_trylockbyte( byte& flag ); + // r32 = address of flag + .proc __TBB_machine_trylockbyte# + .global __TBB_machine_trylockbyte# +ADDRESS_OF_FLAG=r32 +RETCODE=r8 +FLAG=r9 +BUSY=r10 +SCRATCH=r11 +__TBB_machine_trylockbyte: + ld1.acq FLAG=[ADDRESS_OF_FLAG] + mov BUSY=1 + mov RETCODE=0 +;; + cmp.ne p6,p0=0,FLAG + mov ar.ccv=r0 +(p6) br.ret.sptk.many b0 +;; + cmpxchg1.acq SCRATCH=[ADDRESS_OF_FLAG],BUSY,ar.ccv // Try to acquire lock +;; + cmp.eq p6,p0=0,SCRATCH +;; +(p6) mov RETCODE=1 + br.ret.sptk.many b0 + .endp __TBB_machine_trylockbyte# diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/log2.s b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/log2.s new file mode 100644 index 00000000..be3f2be6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/log2.s @@ -0,0 +1,54 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + .section .text + .align 16 + // unsigned long __TBB_machine_lg( unsigned long x ); + // r32 = x + .proc __TBB_machine_lg# + .global __TBB_machine_lg# +__TBB_machine_lg: + shr r16=r32,1 // .x +;; + shr r17=r32,2 // ..x + or r32=r32,r16 // xx +;; + shr r16=r32,3 // ...xx + or r32=r32,r17 // xxx +;; + shr r17=r32,5 // .....xxx + or r32=r32,r16 // xxxxx +;; + shr r16=r32,8 // ........xxxxx + or r32=r32,r17 // xxxxxxxx +;; + shr r17=r32,13 + or r32=r32,r16 // 13x +;; + shr r16=r32,21 + or r32=r32,r17 // 21x +;; + shr r17=r32,34 + or r32=r32,r16 // 34x +;; + shr r16=r32,55 + or r32=r32,r17 // 55x +;; + or r32=r32,r16 // 64x +;; + popcnt r8=r32 +;; + add r8=-1,r8 + br.ret.sptk.many b0 + .endp __TBB_machine_lg# diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/pause.s b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/pause.s new file mode 100644 index 00000000..e4dfeb47 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ia64-gas/pause.s @@ -0,0 +1,29 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + .section .text + .align 16 + // void __TBB_machine_pause( long count ); + // r32 = count + .proc __TBB_machine_pause# + .global __TBB_machine_pause# +count = r32 +__TBB_machine_pause: + hint.m 0 + add count=-1,count +;; + cmp.eq p6,p7=0,count +(p7) br.cond.dpnt __TBB_machine_pause +(p6) br.ret.sptk.many b0 + .endp __TBB_machine_pause# diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ibm_aix51/atomic_support.c b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ibm_aix51/atomic_support.c new file mode 100644 index 00000000..24850b8a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/ibm_aix51/atomic_support.c @@ -0,0 +1,51 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <stdint.h> +#include <sys/atomic_op.h> + +/* This file must be compiled with gcc. The IBM compiler doesn't seem to + support inline assembly statements (October 2007). */ + +#ifdef __GNUC__ + +int32_t __TBB_machine_cas_32 (volatile void* ptr, int32_t value, int32_t comparand) { + __asm__ __volatile__ ("sync\n"); /* memory release operation */ + compare_and_swap ((atomic_p) ptr, &comparand, value); + __asm__ __volatile__ ("isync\n"); /* memory acquire operation */ + return comparand; +} + +int64_t __TBB_machine_cas_64 (volatile void* ptr, int64_t value, int64_t comparand) { + __asm__ __volatile__ ("sync\n"); /* memory release operation */ + compare_and_swaplp ((atomic_l) ptr, &comparand, value); + __asm__ __volatile__ ("isync\n"); /* memory acquire operation */ + return comparand; +} + +void __TBB_machine_flush () { + __asm__ __volatile__ ("sync\n"); +} + +void __TBB_machine_lwsync () { + __asm__ __volatile__ ("lwsync\n"); +} + +void __TBB_machine_isync () { + __asm__ __volatile__ ("isync\n"); +} + +#endif /* __GNUC__ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/index.html new file mode 100644 index 00000000..e6fe3afb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/index.html @@ -0,0 +1,31 @@ +<HTML> +<BODY> + +<H2>Overview</H2> +This directory contains the source code of the TBB core components. + +<H2>Directories</H2> +<DL> +<DT><A HREF="tools_api">tools_api</A> +<DD>Source code of the interface components provided by the Intel® Parallel Studio tools. +<DT><A HREF="intel64-masm">intel64-masm</A> +<DD>Assembly code for the Intel® 64 architecture. +<DT><A HREF="ia32-masm">ia32-masm</A> +<DD>Assembly code for IA32 architecture. +<DT><A HREF="ia64-gas">ia64-gas</A> +<DD>Assembly code for IA-64 architecture. +<DT><A HREF="ibm_aix51">ibm_aix51</A> +<DD>Assembly code for AIX 5.1 port. +</DL> + +<HR> +<A HREF="../index.html">Up to parent directory</A> +<p></p> +Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +<P></P> +Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +<p></p> +* Other names and brands may be claimed as the property of others. +</BODY> +</HTML> diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/atomic_support.asm b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/atomic_support.asm new file mode 100644 index 00000000..c34538e9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/atomic_support.asm @@ -0,0 +1,68 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +; DO NOT EDIT - AUTOMATICALLY GENERATED FROM .s FILE +.code + ALIGN 8 + PUBLIC __TBB_machine_fetchadd1 +__TBB_machine_fetchadd1: + mov rax,rdx + lock xadd [rcx],al + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_fetchstore1 +__TBB_machine_fetchstore1: + mov rax,rdx + lock xchg [rcx],al + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_cmpswp1 +__TBB_machine_cmpswp1: + mov rax,r8 + lock cmpxchg [rcx],dl + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_fetchadd2 +__TBB_machine_fetchadd2: + mov rax,rdx + lock xadd [rcx],ax + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_fetchstore2 +__TBB_machine_fetchstore2: + mov rax,rdx + lock xchg [rcx],ax + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_cmpswp2 +__TBB_machine_cmpswp2: + mov rax,r8 + lock cmpxchg [rcx],dx + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_pause +__TBB_machine_pause: +L1: + dw 090f3H; pause + add ecx,-1 + jne L1 + ret +end + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/intel64_misc.asm b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/intel64_misc.asm new file mode 100644 index 00000000..dc05c8f3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/intel64_misc.asm @@ -0,0 +1,29 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +.code + ALIGN 8 + PUBLIC __TBB_get_cpu_ctl_env +__TBB_get_cpu_ctl_env: + stmxcsr [rcx] + fstcw [rcx+4] + ret +.code + ALIGN 8 + PUBLIC __TBB_set_cpu_ctl_env +__TBB_set_cpu_ctl_env: + ldmxcsr [rcx] + fldcw [rcx+4] + ret +end diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/itsx.asm b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/itsx.asm new file mode 100644 index 00000000..3c75dcef --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intel64-masm/itsx.asm @@ -0,0 +1,72 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +.code + ALIGN 8 + PUBLIC __TBB_machine_try_lock_elided +__TBB_machine_try_lock_elided: + xor rax, rax + mov al, 1 + BYTE 0F2H + xchg al, byte ptr [rcx] + xor al, 1 + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_unlock_elided +__TBB_machine_unlock_elided: + BYTE 0F3H + mov byte ptr [rcx], 0 + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_begin_transaction +__TBB_machine_begin_transaction: + mov eax, -1 + BYTE 0C7H + BYTE 0F8H + BYTE 000H + BYTE 000H + BYTE 000H + BYTE 000H + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_end_transaction +__TBB_machine_end_transaction: + BYTE 00FH + BYTE 001H + BYTE 0D5H + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_transaction_conflict_abort +__TBB_machine_transaction_conflict_abort: + BYTE 0C6H + BYTE 0F8H + BYTE 0FFH ; 12.4.5 Abort argument: lock not free when tested + ret +.code + ALIGN 8 + PUBLIC __TBB_machine_is_in_transaction +__TBB_machine_is_in_transaction: + xor eax, eax + BYTE 00FH ; _xtest sets or clears ZF + BYTE 001H + BYTE 0D6H + jz rset + mov al,1 +rset: + ret +end diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intrusive_list.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intrusive_list.h new file mode 100644 index 00000000..add58e72 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/intrusive_list.h @@ -0,0 +1,237 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_intrusive_list_H +#define _TBB_intrusive_list_H + +#include "tbb/tbb_stddef.h" +#include "tbb/internal/_template_helpers.h" + +namespace tbb { +namespace internal { + +//! Data structure to be inherited by the types that can form intrusive lists. +/** Intrusive list is formed by means of the member_intrusive_list<T> template class. + Note that type T must derive from intrusive_list_node either publicly or + declare instantiation member_intrusive_list<T> as a friend. + This class implements a limited subset of std::list interface. **/ +struct intrusive_list_node { + intrusive_list_node *my_prev_node, + *my_next_node; +#if TBB_USE_ASSERT + intrusive_list_node () { my_prev_node = my_next_node = this; } +#endif /* TBB_USE_ASSERT */ +}; + +//! List of element of type T, where T is derived from intrusive_list_node +/** The class is not thread safe. **/ +template <class List, class T> +class intrusive_list_base { + //! Pointer to the head node + intrusive_list_node my_head; + + //! Number of list elements + size_t my_size; + + static intrusive_list_node& node ( T& item ) { return List::node(item); } + + static T& item ( intrusive_list_node* node ) { return List::item(node); } + + static const T& item( const intrusive_list_node* node ) { return List::item(node); } + + template <typename DereferenceType> + class iterator_impl { + __TBB_STATIC_ASSERT((tbb::internal::is_same_type<DereferenceType, T>::value || + tbb::internal::is_same_type<DereferenceType, const T>::value), + "Incorrect DereferenceType in iterator_impl"); + typedef typename tbb::internal::conditional<tbb::internal::is_same_type<DereferenceType, T>::value, + intrusive_list_node*, + const intrusive_list_node*>::type pointer_type; + public: + iterator_impl() : my_pos(NULL) {} + + iterator_impl( pointer_type pos ) : my_pos(pos) {} + + iterator_impl& operator=( const iterator_impl& other ) { + if (this != &other) { + my_pos = other.my_pos; + } + return *this; + } + + iterator_impl& operator=( const T& val ) { + my_pos = &node(val); + return *this; + } + + iterator_impl& operator++() { + my_pos = my_pos->my_next_node; + return *this; + } + + iterator_impl operator++( int ) { + iterator_impl it(*this); + ++*this; + return it; + } + + iterator_impl& operator--() { + my_pos = my_pos->my_prev_node; + return *this; + } + + iterator_impl operator--( int ) { + iterator_impl it(*this); + --*this; + return it; + } + + bool operator==( const iterator_impl& rhs ) const { + return my_pos == rhs.my_pos; + } + + bool operator!=( const iterator_impl& rhs ) const { + return my_pos != rhs.my_pos; + } + + DereferenceType& operator*() const { + return intrusive_list_base::item(my_pos); + } + + DereferenceType* operator->() const { + return &intrusive_list_base::item(my_pos); + } + + private: + // Node the iterator points to at the moment + pointer_type my_pos; + }; // class iterator_impl + + void assert_ok () const { + __TBB_ASSERT( (my_head.my_prev_node == &my_head && !my_size) || + (my_head.my_next_node != &my_head && my_size >0), "intrusive_list_base corrupted" ); +#if TBB_USE_ASSERT >= 2 + size_t i = 0; + for ( intrusive_list_node *n = my_head.my_next_node; n != &my_head; n = n->my_next_node ) + ++i; + __TBB_ASSERT( my_size == i, "Wrong size" ); +#endif /* TBB_USE_ASSERT >= 2 */ + } + +public: + typedef iterator_impl<T> iterator; + typedef iterator_impl<const T> const_iterator; + + intrusive_list_base () : my_size(0) { + my_head.my_prev_node = &my_head; + my_head.my_next_node = &my_head; + } + + bool empty () const { return my_head.my_next_node == &my_head; } + + size_t size () const { return my_size; } + + iterator begin () { return iterator(my_head.my_next_node); } + + iterator end () { return iterator(&my_head); } + + const_iterator begin () const { return const_iterator(my_head.my_next_node); } + + const_iterator end () const { return const_iterator(&my_head); } + + void push_front ( T& val ) { + __TBB_ASSERT( node(val).my_prev_node == &node(val) && node(val).my_next_node == &node(val), + "Object with intrusive list node can be part of only one intrusive list simultaneously" ); + // An object can be part of only one intrusive list at the given moment via the given node member + node(val).my_prev_node = &my_head; + node(val).my_next_node = my_head.my_next_node; + my_head.my_next_node->my_prev_node = &node(val); + my_head.my_next_node = &node(val); + ++my_size; + assert_ok(); + } + + void remove( T& val ) { + __TBB_ASSERT( node(val).my_prev_node != &node(val) && node(val).my_next_node != &node(val), "Element to remove is not in the list" ); + __TBB_ASSERT( node(val).my_prev_node->my_next_node == &node(val) && node(val).my_next_node->my_prev_node == &node(val), "Element to remove is not in the list" ); + --my_size; + node(val).my_next_node->my_prev_node = node(val).my_prev_node; + node(val).my_prev_node->my_next_node = node(val).my_next_node; +#if TBB_USE_ASSERT + node(val).my_prev_node = node(val).my_next_node = &node(val); +#endif + assert_ok(); + } + + iterator erase ( iterator it ) { + T& val = *it; + ++it; + remove( val ); + return it; + } + +}; // intrusive_list_base + + +//! Double linked list of items of type T containing a member of type intrusive_list_node. +/** NodePtr is a member pointer to the node data field. Class U is either T or + a base class of T containing the node member. Default values exist for the sake + of a partial specialization working with inheritance case. + + The list does not have ownership of its items. Its purpose is to avoid dynamic + memory allocation when forming lists of existing objects. + + The class is not thread safe. **/ +template <class T, class U, intrusive_list_node U::*NodePtr> +class memptr_intrusive_list : public intrusive_list_base<memptr_intrusive_list<T, U, NodePtr>, T> +{ + friend class intrusive_list_base<memptr_intrusive_list<T, U, NodePtr>, T>; + + static intrusive_list_node& node ( T& val ) { return val.*NodePtr; } + + static T& item ( intrusive_list_node* node ) { + // Cannot use __TBB_offsetof (and consequently __TBB_get_object_ref) macro + // with *NodePtr argument because gcc refuses to interpret pasted "->" and "*" + // as member pointer dereferencing operator, and explicit usage of ## in + // __TBB_offsetof implementation breaks operations with normal member names. + return *reinterpret_cast<T*>((char*)node - ((ptrdiff_t)&(reinterpret_cast<T*>(0x1000)->*NodePtr) - 0x1000)); + } + + static const T& item( const intrusive_list_node* node ) { + return item(const_cast<intrusive_list_node*>(node)); + } +}; // intrusive_list<T, U, NodePtr> + +//! Double linked list of items of type T that is derived from intrusive_list_node class. +/** The list does not have ownership of its items. Its purpose is to avoid dynamic + memory allocation when forming lists of existing objects. + + The class is not thread safe. **/ +template <class T> +class intrusive_list : public intrusive_list_base<intrusive_list<T>, T> +{ + friend class intrusive_list_base<intrusive_list<T>, T>; + + static intrusive_list_node& node ( T& val ) { return val; } + + static T& item ( intrusive_list_node* node ) { return *static_cast<T*>(node); } + static const T& item( const intrusive_list_node* node ) { return *static_cast<const T*>(node); } +}; // intrusive_list<T> + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_intrusive_list_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/itt_notify.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/itt_notify.cpp new file mode 100644 index 00000000..ac505344 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/itt_notify.cpp @@ -0,0 +1,95 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if DO_ITT_NOTIFY + +#if _WIN32||_WIN64 + #ifndef UNICODE + #define UNICODE + #endif +#else + #pragma weak dlopen + #pragma weak dlsym + #pragma weak dlerror +#endif /* WIN */ + +#if __TBB_BUILD + +extern "C" void ITT_DoOneTimeInitialization(); +#define __itt_init_ittlib_name(x,y) (ITT_DoOneTimeInitialization(), true) + +#elif __TBBMALLOC_BUILD + +extern "C" void MallocInitializeITT(); +#define __itt_init_ittlib_name(x,y) (MallocInitializeITT(), true) + +#else +#error This file is expected to be used for either TBB or TBB allocator build. +#endif // __TBB_BUILD + +#include "tools_api/ittnotify_static.c" + +namespace tbb { +namespace internal { +int __TBB_load_ittnotify() { +#if !(_WIN32||_WIN64) + // tool_api crashes without dlopen, check that it's present. Common case + // for lack of dlopen is static binaries, i.e. ones build with -static. + if (dlopen == NULL) + return 0; +#endif + return __itt_init_ittlib(NULL, // groups for: + (__itt_group_id)(__itt_group_sync // prepare/cancel/acquired/releasing + | __itt_group_thread // name threads + | __itt_group_stitch // stack stitching + | __itt_group_structure + )); +} + +}} // namespaces + +#endif /* DO_ITT_NOTIFY */ + +#define __TBB_NO_IMPLICIT_LINKAGE 1 +#include "itt_notify.h" + +namespace tbb { + +#if DO_ITT_NOTIFY + const tchar + *SyncType_GlobalLock = _T("TbbGlobalLock"), + *SyncType_Scheduler = _T("%Constant") + ; + const tchar + *SyncObj_SchedulerInitialization = _T("TbbSchedulerInitialization"), + *SyncObj_SchedulersList = _T("TbbSchedulersList"), + *SyncObj_WorkerLifeCycleMgmt = _T("TBB Scheduler"), + *SyncObj_TaskStealingLoop = _T("TBB Scheduler"), + *SyncObj_WorkerTaskPool = _T("TBB Scheduler"), + *SyncObj_MasterTaskPool = _T("TBB Scheduler"), + *SyncObj_TaskPoolSpinning = _T("TBB Scheduler"), + *SyncObj_Mailbox = _T("TBB Scheduler"), + *SyncObj_TaskReturnList = _T("TBB Scheduler"), + *SyncObj_TaskStream = _T("TBB Scheduler"), +#if __TBB_PREVIEW_CRITICAL_TASKS + *SyncObj_CriticalTaskStream = _T("TBB Scheduler"), +#endif + *SyncObj_ContextsList = _T("TBB Scheduler") + ; +#endif /* DO_ITT_NOTIFY */ + +} // namespace tbb + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/itt_notify.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/itt_notify.h new file mode 100644 index 00000000..699e1086 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/itt_notify.h @@ -0,0 +1,131 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_ITT_NOTIFY +#define _TBB_ITT_NOTIFY + +#include "tbb/tbb_stddef.h" + +#if DO_ITT_NOTIFY + +#if _WIN32||_WIN64 + #ifndef UNICODE + #define UNICODE + #endif +#endif /* WIN */ + +#ifndef INTEL_ITTNOTIFY_API_PRIVATE +#define INTEL_ITTNOTIFY_API_PRIVATE +#endif + +#include "tools_api/ittnotify.h" +#include "tools_api/legacy/ittnotify.h" +extern "C" void __itt_fini_ittlib(void); + +#if _WIN32||_WIN64 + #undef _T +#endif /* WIN */ + +#endif /* DO_ITT_NOTIFY */ + +#if !ITT_CALLER_NULL +#define ITT_CALLER_NULL ((__itt_caller)0) +#endif + +namespace tbb { +//! Unicode support +#if (_WIN32||_WIN64) && !__MINGW32__ + //! Unicode character type. Always wchar_t on Windows. + /** We do not use typedefs from Windows TCHAR family to keep consistence of TBB coding style. **/ + typedef wchar_t tchar; + //! Standard Windows macro to markup the string literals. + #define _T(string_literal) L ## string_literal +#else /* !WIN */ + typedef char tchar; + //! Standard Windows style macro to markup the string literals. + #define _T(string_literal) string_literal +#endif /* !WIN */ +} // namespace tbb + +#if DO_ITT_NOTIFY +namespace tbb { + //! Display names of internal synchronization types + extern const tchar + *SyncType_GlobalLock, + *SyncType_Scheduler; + //! Display names of internal synchronization components/scenarios + extern const tchar + *SyncObj_SchedulerInitialization, + *SyncObj_SchedulersList, + *SyncObj_WorkerLifeCycleMgmt, + *SyncObj_TaskStealingLoop, + *SyncObj_WorkerTaskPool, + *SyncObj_MasterTaskPool, + *SyncObj_TaskPoolSpinning, + *SyncObj_Mailbox, + *SyncObj_TaskReturnList, + *SyncObj_TaskStream, +#if __TBB_PREVIEW_CRITICAL_TASKS + *SyncObj_CriticalTaskStream, +#endif + *SyncObj_ContextsList + ; + + namespace internal { + void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void* obj, const tchar* name); + + } // namespace internal +} // namespace tbb + +// const_cast<void*>() is necessary to cast off volatility +#define ITT_NOTIFY(name,obj) __itt_##name(const_cast<void*>(static_cast<volatile void*>(obj))) +#define ITT_THREAD_SET_NAME(name) __itt_thread_set_name(name) +#define ITT_FINI_ITTLIB() __itt_fini_ittlib() +#define ITT_SYNC_CREATE(obj, type, name) __itt_sync_create((void*)(obj), type, name, 2) +#define ITT_SYNC_RENAME(obj, name) __itt_sync_rename(obj, name) +#define ITT_STACK_CREATE(obj) obj = __itt_stack_caller_create() +#if __TBB_TASK_GROUP_CONTEXT +#define ITT_STACK(precond, name, obj) (precond) ? __itt_stack_##name(obj) : ((void)0); +#else +#define ITT_STACK(precond, name, obj) ((void)0) +#endif /* !__TBB_TASK_GROUP_CONTEXT */ + +#define ITT_TASK_GROUP(obj,name,parent) itt_make_task_group_v7(internal::ITT_DOMAIN_MAIN,(void*)(obj),ALGORITHM,(void*)(parent),(parent!=NULL) ? ALGORITHM : FLOW_NULL,name) +#define ITT_TASK_BEGIN(obj,name,id) itt_task_begin_v7(internal::ITT_DOMAIN_MAIN,(void*)(id),ALGORITHM,(void*)(obj),ALGORITHM,name) +#define ITT_TASK_END itt_task_end_v7(internal::ITT_DOMAIN_MAIN) + +#else /* !DO_ITT_NOTIFY */ + +#define ITT_NOTIFY(name,obj) ((void)0) +#define ITT_THREAD_SET_NAME(name) ((void)0) +#define ITT_FINI_ITTLIB() ((void)0) +#define ITT_SYNC_CREATE(obj, type, name) ((void)0) +#define ITT_SYNC_RENAME(obj, name) ((void)0) +#define ITT_STACK_CREATE(obj) ((void)0) +#define ITT_STACK(precond, name, obj) ((void)0) + +#define ITT_TASK_GROUP(type,name,parent) ((void)0) +#define ITT_TASK_BEGIN(type,name,id) ((void)0) +#define ITT_TASK_END ((void)0) + +#endif /* !DO_ITT_NOTIFY */ + +namespace tbb { +namespace internal { +int __TBB_load_ittnotify(); +}} + +#endif /* _TBB_ITT_NOTIFY */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbb-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbb-export.def new file mode 100644 index 00000000..2df55ce5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbb-export.def @@ -0,0 +1,45 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: + +#define __TBB_SYMBOL( sym ) sym; +#include "lin32-tbb-export.lst" + +local: + +/* TBB symbols */ +*3tbb*; +*__TBB*; + +/* ITT symbols */ +__itt_*; + +/* Intel Compiler (libirc) symbols */ +__intel_*; +_intel_*; +get_memcpy_largest_cachelinesize; +get_memcpy_largest_cache_size; +get_mem_ops_method; +init_mem_ops_method; +irc__get_msg; +irc__print; +override_mem_ops_method; +set_memcpy_largest_cachelinesize; +set_memcpy_largest_cache_size; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbb-export.lst new file mode 100644 index 00000000..3026a4d5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbb-export.lst @@ -0,0 +1,410 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +/* cache_aligned_allocator.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEjjPv ) +__TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) +__TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Ej ) +__TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) + +/* task.cpp v3 */ +__TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) +__TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) +__TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) +__TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) +__TBB_SYMBOL( _ZN3tbb4task4selfEv ) +__TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEj ) +__TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEj ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEj ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEj ) +__TBB_SYMBOL( _ZTIN3tbb4taskE ) +__TBB_SYMBOL( _ZTSN3tbb4taskE ) +__TBB_SYMBOL( _ZTVN3tbb4taskE ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEij ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init27internal_blocking_terminateEb ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) +#endif /* __TBB_SCHEDULER_OBSERVER */ +__TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) +__TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) + +/* arena.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base15internal_attachEv ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEi ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base24internal_max_concurrencyEPKNS0_10task_arenaE ) +#if __TBB_NUMA_SUPPORT +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology11nodes_countEv ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology4fillEPi ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology19default_concurrencyEi ) +#endif /*__TBB_NUMA_SUPPORT*/ +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEi ) +#endif /* __TBB_TASK_ISOLATION */ + +#if !TBB_NO_LEGACY +/* task_v2.cpp */ +__TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) +#endif /* !TBB_NO_LEGACY */ + +/* Exception handling in task scheduler */ +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEj ) +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) +__TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZN3tbb13tbb_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +/* Symbols for exceptions thrown from TBB */ +__TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) +__TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) +__TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) +__TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) +__TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) +__TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) +__TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) +__TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTSN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTVN3tbb10user_abortE ) + +/* tbb_misc.cpp */ +__TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) +__TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) +__TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) +__TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) +__TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) +#if __TBB_x86_32 +__TBB_SYMBOL( __TBB_machine_store8_slow_perf_warning ) +__TBB_SYMBOL( __TBB_machine_store8_slow ) +#endif +__TBB_SYMBOL( TBB_runtime_interface_version ) + +/* tbb_main.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) +__TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_region_begin_v9ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_region_end_v9ENS0_15itt_domain_enumEPvy ) +__TBB_SYMBOL( _ZN3tbb8internal24itt_metadata_ptr_add_v11ENS0_15itt_domain_enumEPvyNS0_12string_indexES2_ ) + +/* pipeline.cpp */ +__TBB_SYMBOL( _ZTIN3tbb6filterE ) +__TBB_SYMBOL( _ZTSN3tbb6filterE ) +__TBB_SYMBOL( _ZTVN3tbb6filterE ) +__TBB_SYMBOL( _ZN3tbb6filterD2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline3runEj ) +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZN3tbb8pipeline3runEjRNS_18task_group_contextE ) +#endif +__TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) +__TBB_SYMBOL( _ZTIN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTSN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTVN3tbb8pipelineE ) +__TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) +__TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) + +/* queuing_rw_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) + +/* reader_writer_lock.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) + +#if !TBB_NO_LEGACY +/* spin_rw_mutex.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) +#endif + +/* spin_rw_mutex v3 */ +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) + +// x86_rtm_rw_mutex.cpp +#if __TBB_TSX_AVAILABLE +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) +#endif + +/* spin_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) + +/* mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) + +/* recursive_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) + +/* QueuingMutex.cpp */ +__TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) + +/* critical_section.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) + +#if !TBB_NO_LEGACY +/* concurrent_hash_map */ +__TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) + +/* concurrent_queue.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityEij ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Ej ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) +__TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) +#endif + +/* concurrent_queue v3 */ +/* constructors */ +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Ej ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Ej ) +/* destructors */ +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) +/* typeinfo */ +__TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) +/* vtable */ +__TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) +/* methods */ +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityEij ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) + +#if !TBB_NO_LEGACY +/* concurrent_vector.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_jPFvPvPKvjE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvjEb ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_jPFvPvjEPFvS4_PKvjESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEjjPFvPvjE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEjjj ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEjRj ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEjjPFvPvjE ) +__TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) +#endif + +/* concurrent_vector v3 */ +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_jPFvPvPKvjE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvjE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_jPFvPvjEPFvS4_PKvjESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEjjPFvPvPKvjES4_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEjjj ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEjRj ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEjjPFvPvPKvjES4_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEjPvPFvS2_jEPFvS2_PKvjE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEj ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEjjjPKvPFvPvjEPFvS4_S3_jE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEjjPFvPvPKvjES4_ ) + +/* tbb_thread */ +#if __MINGW32__ +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFjPvES2_ ) +#else +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) +#endif +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) +__TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Ej ) +__TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) + +#if __MINGW32__ +/* condition_variable */ +__TBB_SYMBOL( _ZN3tbb10interface58internal32internal_condition_variable_waitERNS1_14condvar_impl_tEPNS_5mutexEPKNS_10tick_count10interval_tE ) +__TBB_SYMBOL( _ZN3tbb10interface58internal35internal_destroy_condition_variableERNS1_14condvar_impl_tE ) +__TBB_SYMBOL( _ZN3tbb10interface58internal38internal_condition_variable_notify_allERNS1_14condvar_impl_tE ) +__TBB_SYMBOL( _ZN3tbb10interface58internal38internal_condition_variable_notify_oneERNS1_14condvar_impl_tE ) +__TBB_SYMBOL( _ZN3tbb10interface58internal38internal_initialize_condition_variableERNS1_14condvar_impl_tE ) +#endif + +// global parameter +__TBB_SYMBOL( _ZN3tbb10interface914global_control12active_valueEi ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control15internal_createEv ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control16internal_destroyEv ) + +#if __TBB_PREVIEW_RESUMABLE_TASKS +__TBB_SYMBOL( _ZN3tbb8internal16internal_suspendEPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal15internal_resumeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal30internal_current_suspend_pointEv ) +#endif + +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbbbind-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbbbind-export.def new file mode 100644 index 00000000..efec2cb9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin32-tbbbind-export.def @@ -0,0 +1,24 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: +initialize_numa_topology; +bind_to_node; +restore_affinity; +allocate_binding_handler; +deallocate_binding_handler; +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbb-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbb-export.def new file mode 100644 index 00000000..d2e54ea1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbb-export.def @@ -0,0 +1,42 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: + +#define __TBB_SYMBOL( sym ) sym; +#include "lin64-tbb-export.lst" + +local: + +/* TBB symbols */ +*3tbb*; +*__TBB*; + +/* ITT symbols */ +__itt_*; + +/* Intel Compiler (libirc) symbols */ +__intel_*; +_intel_*; +get_msg_buf; +get_text_buf; +message_catalog; +print_buf; +irc__get_msg; +irc__print; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbb-export.lst new file mode 100644 index 00000000..758ef224 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbb-export.lst @@ -0,0 +1,391 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +/* cache_aligned_allocator.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEmmPv ) +__TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) +__TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) + +/* task.cpp v3 */ +__TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) +__TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) +__TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) +__TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) +__TBB_SYMBOL( _ZN3tbb4task4selfEv ) +__TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEm ) +__TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm ) +__TBB_SYMBOL( _ZTIN3tbb4taskE ) +__TBB_SYMBOL( _ZTSN3tbb4taskE ) +__TBB_SYMBOL( _ZTVN3tbb4taskE ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEim ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init27internal_blocking_terminateEb ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) +#endif /* __TBB_SCHEDULER_OBSERVER */ +__TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) +__TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) + +/* arena.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base15internal_attachEv ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base24internal_max_concurrencyEPKNS0_10task_arenaE ) +#if __TBB_NUMA_SUPPORT +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology11nodes_countEv ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology4fillEPi ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology19default_concurrencyEi ) +#endif /*__TBB_NUMA_SUPPORT*/ +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl ) +#endif + +#if !TBB_NO_LEGACY +/* task_v2.cpp */ +__TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) +#endif /* !TBB_NO_LEGACY */ + +/* Exception handling in task scheduler */ +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) +__TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZN3tbb13tbb_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +/* Symbols for exceptions thrown from TBB */ +__TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) +__TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) +__TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) +__TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) +__TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) +__TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) +__TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) +__TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTSN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTVN3tbb10user_abortE ) +/* tbb_misc.cpp */ +__TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) +__TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) +__TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) +__TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) +__TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) +__TBB_SYMBOL( TBB_runtime_interface_version ) + +/* tbb_main.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) +__TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc ) +__TBB_SYMBOL( _ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y ) +__TBB_SYMBOL( _ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_region_begin_v9ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_region_end_v9ENS0_15itt_domain_enumEPvy ) +__TBB_SYMBOL( _ZN3tbb8internal24itt_metadata_ptr_add_v11ENS0_15itt_domain_enumEPvyNS0_12string_indexES2_ ) + +/* pipeline.cpp */ +__TBB_SYMBOL( _ZTIN3tbb6filterE ) +__TBB_SYMBOL( _ZTSN3tbb6filterE ) +__TBB_SYMBOL( _ZTVN3tbb6filterE ) +__TBB_SYMBOL( _ZN3tbb6filterD2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline3runEm ) +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZN3tbb8pipeline3runEmRNS_18task_group_contextE ) +#endif +__TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) +__TBB_SYMBOL( _ZTIN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTSN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTVN3tbb8pipelineE ) +__TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) +__TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) + +/* queuing_rw_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) + +/* reader_writer_lock.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) + +#if !TBB_NO_LEGACY +/* spin_rw_mutex.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) +#endif + +// x86_rtm_rw_mutex.cpp +#if __TBB_TSX_AVAILABLE +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) +#endif + +/* spin_rw_mutex v3 */ +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) + +/* spin_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) + +/* mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) + +/* recursive_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) + +/* QueuingMutex.cpp */ +__TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) + +/* critical_section.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) + +#if !TBB_NO_LEGACY +/* concurrent_hash_map */ +__TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) + +/* concurrent_queue.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityElm ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Em ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) +__TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) +#endif + +/* concurrent_queue v3 */ +/* constructors */ +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Em ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em ) +/* destructors */ +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) +/* typeinfo */ +__TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) +/* vtable */ +__TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) +/* methods */ +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityElm ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) + +#if !TBB_NO_LEGACY +/* concurrent_vector.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE ) +__TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) +#endif + +/* concurrent_vector v3 */ +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_ ) + +/* tbb_thread */ +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) +__TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) + +/* global_parameter */ +__TBB_SYMBOL( _ZN3tbb10interface914global_control12active_valueEi ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control15internal_createEv ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control16internal_destroyEv ) + +#if __TBB_PREVIEW_RESUMABLE_TASKS +__TBB_SYMBOL( _ZN3tbb8internal16internal_suspendEPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal15internal_resumeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal30internal_current_suspend_pointEv ) +#endif +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbbbind-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbbbind-export.def new file mode 100644 index 00000000..efec2cb9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64-tbbbind-export.def @@ -0,0 +1,24 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: +initialize_numa_topology; +bind_to_node; +restore_affinity; +allocate_binding_handler; +deallocate_binding_handler; +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64ipf-tbb-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64ipf-tbb-export.def new file mode 100644 index 00000000..2b37d75b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64ipf-tbb-export.def @@ -0,0 +1,44 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: + +#define __TBB_SYMBOL( sym ) sym; +#include "lin64ipf-tbb-export.lst" + +local: + +/* TBB symbols */ +*3tbb*; +*__TBB*; + +/* ITT symbols */ +__itt_*; + +/* Intel Compiler (libirc) symbols */ +__intel_*; +_intel_*; +?0_memcopyA; +?0_memcopyDu; +?0_memcpyD; +?1__memcpy; +?1__memmove; +?1__serial_memmove; +memcpy; +memset; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64ipf-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64ipf-tbb-export.lst new file mode 100644 index 00000000..678553bd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/lin64ipf-tbb-export.lst @@ -0,0 +1,427 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +/* cache_aligned_allocator.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEmmPv ) +__TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) +__TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) + +/* task.cpp v3 */ +__TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) +__TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) +__TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) +__TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) +__TBB_SYMBOL( _ZN3tbb4task4selfEv ) +__TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEm ) +__TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm ) +__TBB_SYMBOL( _ZTIN3tbb4taskE ) +__TBB_SYMBOL( _ZTSN3tbb4taskE ) +__TBB_SYMBOL( _ZTVN3tbb4taskE ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEim ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init27internal_blocking_terminateEb ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) +#endif /* __TBB_SCHEDULER_OBSERVER */ +__TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) +__TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) + +/* arena.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base15internal_attachEv ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base24internal_max_concurrencyEPKNS0_10task_arenaE ) +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl ) +#endif + +#if !TBB_NO_LEGACY +/* task_v2.cpp */ +__TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) +#endif /* !TBB_NO_LEGACY */ + +/* Exception handling in task scheduler */ +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) +__TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZN3tbb13tbb_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +/* Symbols for exceptions thrown from TBB */ +__TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) +__TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) +__TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) +__TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) +__TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) +__TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) +__TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) +__TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTSN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTVN3tbb10user_abortE ) + +/* tbb_misc.cpp */ +__TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) +__TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) +__TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) +__TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) +__TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) +__TBB_SYMBOL( TBB_runtime_interface_version ) + +/* tbb_main.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) +__TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc ) +__TBB_SYMBOL( _ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y ) +__TBB_SYMBOL( _ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_region_begin_v9ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_region_end_v9ENS0_15itt_domain_enumEPvy ) +__TBB_SYMBOL( _ZN3tbb8internal24itt_metadata_ptr_add_v11ENS0_15itt_domain_enumEPvyNS0_12string_indexES2_ ) + +/* pipeline.cpp */ +__TBB_SYMBOL( _ZTIN3tbb6filterE ) +__TBB_SYMBOL( _ZTSN3tbb6filterE ) +__TBB_SYMBOL( _ZTVN3tbb6filterE ) +__TBB_SYMBOL( _ZN3tbb6filterD2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline3runEm ) +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZN3tbb8pipeline3runEmRNS_18task_group_contextE ) +#endif +__TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) +__TBB_SYMBOL( _ZTIN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTSN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTVN3tbb8pipelineE ) +__TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) +__TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) + +/* queuing_rw_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) + +/* reader_writer_lock.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) + +#if !TBB_NO_LEGACY +/* spin_rw_mutex.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) +#endif + +/* spin_rw_mutex v3 */ +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) + +/* spin_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) + +/* mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) + +/* recursive_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) + +/* QueuingMutex.cpp */ +__TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) + +/* critical_section.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) + +#if !TBB_NO_LEGACY +/* concurrent_hash_map */ +__TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) + +/* concurrent_queue.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityElm ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Em ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) +__TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) +#endif + +/* concurrent_queue v3 */ +/* constructors */ +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Em ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em ) +/* destructors */ +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) +/* typeinfo */ +__TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) +/* vtable */ +__TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) +/* methods */ +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityElm ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) + +#if !TBB_NO_LEGACY +/* concurrent_vector.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE ) +__TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) +#endif + +/* concurrent_vector v3 */ +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_ ) + +/* tbb_thread */ +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) +__TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) + +/* asm functions */ +__TBB_SYMBOL( __TBB_machine_fetchadd1__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_fetchadd2__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_fetchadd4__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_fetchadd8__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_fetchstore1__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_fetchstore2__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_fetchstore4__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_fetchstore8__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_fetchadd1acquire ) +__TBB_SYMBOL( __TBB_machine_fetchadd1release ) +__TBB_SYMBOL( __TBB_machine_fetchadd2acquire ) +__TBB_SYMBOL( __TBB_machine_fetchadd2release ) +__TBB_SYMBOL( __TBB_machine_fetchadd4acquire ) +__TBB_SYMBOL( __TBB_machine_fetchadd4release ) +__TBB_SYMBOL( __TBB_machine_fetchadd8acquire ) +__TBB_SYMBOL( __TBB_machine_fetchadd8release ) +__TBB_SYMBOL( __TBB_machine_fetchstore1acquire ) +__TBB_SYMBOL( __TBB_machine_fetchstore1release ) +__TBB_SYMBOL( __TBB_machine_fetchstore2acquire ) +__TBB_SYMBOL( __TBB_machine_fetchstore2release ) +__TBB_SYMBOL( __TBB_machine_fetchstore4acquire ) +__TBB_SYMBOL( __TBB_machine_fetchstore4release ) +__TBB_SYMBOL( __TBB_machine_fetchstore8acquire ) +__TBB_SYMBOL( __TBB_machine_fetchstore8release ) +__TBB_SYMBOL( __TBB_machine_cmpswp1acquire ) +__TBB_SYMBOL( __TBB_machine_cmpswp1release ) +__TBB_SYMBOL( __TBB_machine_cmpswp1__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_cmpswp2acquire ) +__TBB_SYMBOL( __TBB_machine_cmpswp2release ) +__TBB_SYMBOL( __TBB_machine_cmpswp2__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_cmpswp4acquire ) +__TBB_SYMBOL( __TBB_machine_cmpswp4release ) +__TBB_SYMBOL( __TBB_machine_cmpswp4__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_cmpswp8acquire ) +__TBB_SYMBOL( __TBB_machine_cmpswp8release ) +__TBB_SYMBOL( __TBB_machine_cmpswp8__TBB_full_fence ) +__TBB_SYMBOL( __TBB_machine_lg ) +__TBB_SYMBOL( __TBB_machine_lockbyte ) +__TBB_SYMBOL( __TBB_machine_pause ) +__TBB_SYMBOL( __TBB_machine_trylockbyte ) +__TBB_SYMBOL( __TBB_machine_load8_relaxed ) +__TBB_SYMBOL( __TBB_machine_store8_relaxed ) +__TBB_SYMBOL( __TBB_machine_load4_relaxed ) +__TBB_SYMBOL( __TBB_machine_store4_relaxed ) +__TBB_SYMBOL( __TBB_machine_load2_relaxed ) +__TBB_SYMBOL( __TBB_machine_store2_relaxed ) +__TBB_SYMBOL( __TBB_machine_load1_relaxed ) +__TBB_SYMBOL( __TBB_machine_store1_relaxed ) + +/* global parameter */ +__TBB_SYMBOL( _ZN3tbb10interface914global_control12active_valueEi ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control15internal_createEv ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control16internal_destroyEv ) + +#if __TBB_PREVIEW_RESUMABLE_TASKS +__TBB_SYMBOL( _ZN3tbb8internal16internal_suspendEPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal15internal_resumeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal30internal_current_suspend_pointEv ) +#endif + +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac32-tbb-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac32-tbb-export.def new file mode 100644 index 00000000..f4dbcca4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac32-tbb-export.def @@ -0,0 +1,19 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define __TBB_SYMBOL( sym ) _##sym +#include "mac32-tbb-export.lst" + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac32-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac32-tbb-export.lst new file mode 100644 index 00000000..0e2e32cc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac32-tbb-export.lst @@ -0,0 +1,418 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +/* + Sometimes macOS* requires leading underscore (e. g. in export list file), but sometimes not + (e. g. when searching symbol in a dynamic library via dlsym()). Symbols in this file SHOULD + be listed WITHOUT one leading underscore. __TBB_SYMBOL macro should add underscore when + necessary, depending on the intended usage. +*/ + +// cache_aligned_allocator.cpp +__TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEmmPv ) +__TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) +__TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) + +// task.cpp v3 +__TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) +__TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) +__TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) +__TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) +__TBB_SYMBOL( _ZN3tbb4task4selfEv ) +__TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEm ) +__TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) +__TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm ) +__TBB_SYMBOL( _ZTIN3tbb4taskE ) +__TBB_SYMBOL( _ZTSN3tbb4taskE ) +__TBB_SYMBOL( _ZTVN3tbb4taskE ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEim ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init27internal_blocking_terminateEb ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) +#endif /* __TBB_SCHEDULER_OBSERVER */ +__TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) +__TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) + +/* arena.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base15internal_attachEv ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base24internal_max_concurrencyEPKNS0_10task_arenaE ) +#if __TBB_NUMA_SUPPORT +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology11nodes_countEv ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology4fillEPi ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology19default_concurrencyEi ) +#endif /*__TBB_NUMA_SUPPORT*/ +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl ) +#endif /* __TBB_TASK_ISOLATION */ + +#if !TBB_NO_LEGACY +// task_v2.cpp +__TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) +#endif + +// Exception handling in task scheduler +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) +__TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +// Symbols for exceptions thrown from TBB +__TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) +__TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) +__TBB_SYMBOL( _ZNSt13runtime_errorD1Ev ) +__TBB_SYMBOL( _ZTISt13runtime_error ) +__TBB_SYMBOL( _ZTSSt13runtime_error ) +__TBB_SYMBOL( _ZNSt16invalid_argumentD1Ev ) +__TBB_SYMBOL( _ZTISt16invalid_argument ) +__TBB_SYMBOL( _ZTSSt16invalid_argument ) +__TBB_SYMBOL( _ZNSt11range_errorD1Ev ) +__TBB_SYMBOL( _ZTISt11range_error ) +__TBB_SYMBOL( _ZTSSt11range_error ) +__TBB_SYMBOL( _ZNSt12length_errorD1Ev ) +__TBB_SYMBOL( _ZTISt12length_error ) +__TBB_SYMBOL( _ZTSSt12length_error ) +__TBB_SYMBOL( _ZNSt12out_of_rangeD1Ev ) +__TBB_SYMBOL( _ZTISt12out_of_range ) +__TBB_SYMBOL( _ZTSSt12out_of_range ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) +__TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) +__TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) +__TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) +__TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) +__TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) +__TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTSN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTVN3tbb10user_abortE ) + +// tbb_misc.cpp +__TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) +__TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) +__TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) +__TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) +#if __TBB_x86_32 +__TBB_SYMBOL( __TBB_machine_store8_slow_perf_warning ) +__TBB_SYMBOL( __TBB_machine_store8_slow ) +#endif +__TBB_SYMBOL( TBB_runtime_interface_version ) + +// tbb_main.cpp +__TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) +__TBB_SYMBOL( _ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_region_begin_v9ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_region_end_v9ENS0_15itt_domain_enumEPvy ) +__TBB_SYMBOL( _ZN3tbb8internal24itt_metadata_ptr_add_v11ENS0_15itt_domain_enumEPvyNS0_12string_indexES2_ ) + +// pipeline.cpp +__TBB_SYMBOL( _ZTIN3tbb6filterE ) +__TBB_SYMBOL( _ZTSN3tbb6filterE ) +__TBB_SYMBOL( _ZTVN3tbb6filterE ) +__TBB_SYMBOL( _ZN3tbb6filterD2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline3runEm ) +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZN3tbb8pipeline3runEmRNS_18task_group_contextE ) +#endif +__TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) +__TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTSN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTVN3tbb8pipelineE ) +__TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) + +// queuing_rw_mutex.cpp +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) + +// reader_writer_lock.cpp +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) + +#if !TBB_NO_LEGACY +// spin_rw_mutex.cpp v2 +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) +#endif + +// spin_rw_mutex v3 +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) + +// x86_rtm_rw_mutex.cpp +#if __TBB_TSX_AVAILABLE +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) +#endif + +// spin_mutex.cpp +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) + +// mutex.cpp +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) + +// recursive_mutex.cpp +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) + +// queuing_mutex.cpp +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) + +// critical_section.cpp +__TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) + +#if !TBB_NO_LEGACY +// concurrent_hash_map +__TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) + +// concurrent_queue.cpp v2 +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityEim ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Em ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) +__TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) +#endif + +// concurrent_queue v3 +// constructors +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Em ) +// destructors +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) +// typeinfo +__TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) +// vtable +__TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) +// methods +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityEim ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) + +#if !TBB_NO_LEGACY +// concurrent_vector.cpp v2 +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE ) +__TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) +#endif + +// concurrent_vector v3 +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_ ) + +// tbb_thread +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) +__TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) + +// global parameter +__TBB_SYMBOL( _ZN3tbb10interface914global_control12active_valueEi ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control15internal_createEv ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control16internal_destroyEv ) + +#if __TBB_PREVIEW_RESUMABLE_TASKS +__TBB_SYMBOL( _ZN3tbb8internal16internal_suspendEPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal15internal_resumeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal30internal_current_suspend_pointEv ) +#endif + +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac64-tbb-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac64-tbb-export.def new file mode 100644 index 00000000..21a77ad7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac64-tbb-export.def @@ -0,0 +1,19 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define __TBB_SYMBOL( sym ) _##sym +#include "mac64-tbb-export.lst" + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac64-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac64-tbb-export.lst new file mode 100644 index 00000000..3b45e88f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mac64-tbb-export.lst @@ -0,0 +1,415 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +/* + Sometimes macOS* requires leading underscore (e. g. in export list file), but sometimes not + (e. g. when searching symbol in a dynamic library via dlsym()). Symbols in this file SHOULD + be listed WITHOUT one leading underscore. __TBB_SYMBOL macro should add underscore when + necessary, depending on the intended usage. +*/ + +// cache_aligned_allocator.cpp +__TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEmmPv ) +__TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) +__TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) + +// task.cpp v3 +__TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) +__TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) +__TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) +__TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) +__TBB_SYMBOL( _ZN3tbb4task4selfEv ) +__TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEm ) +__TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) +__TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEm ) +__TBB_SYMBOL( _ZTIN3tbb4taskE ) +__TBB_SYMBOL( _ZTSN3tbb4taskE ) +__TBB_SYMBOL( _ZTVN3tbb4taskE ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEim ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init27internal_blocking_terminateEb ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) +#endif /* __TBB_SCHEDULER_OBSERVER */ +__TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) +__TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) + +/* arena.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base15internal_attachEv ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEl ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base24internal_max_concurrencyEPKNS0_10task_arenaE ) +#if __TBB_NUMA_SUPPORT +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology11nodes_countEv ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology4fillEPi ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology19default_concurrencyEi ) +#endif /*__TBB_NUMA_SUPPORT*/ +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl ) +#endif /* __TBB_TASK_ISOLATION */ + +#if !TBB_NO_LEGACY +// task_v2.cpp +__TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) +#endif + +// Exception handling in task scheduler +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEm ) +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) +__TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +// Symbols for exceptions thrown from TBB +__TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) +__TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) +__TBB_SYMBOL( _ZNSt13runtime_errorD1Ev ) +__TBB_SYMBOL( _ZTISt13runtime_error ) +__TBB_SYMBOL( _ZTSSt13runtime_error ) +__TBB_SYMBOL( _ZNSt16invalid_argumentD1Ev ) +__TBB_SYMBOL( _ZTISt16invalid_argument ) +__TBB_SYMBOL( _ZTSSt16invalid_argument ) +__TBB_SYMBOL( _ZNSt11range_errorD1Ev ) +__TBB_SYMBOL( _ZTISt11range_error ) +__TBB_SYMBOL( _ZTSSt11range_error ) +__TBB_SYMBOL( _ZNSt12length_errorD1Ev ) +__TBB_SYMBOL( _ZTISt12length_error ) +__TBB_SYMBOL( _ZTSSt12length_error ) +__TBB_SYMBOL( _ZNSt12out_of_rangeD1Ev ) +__TBB_SYMBOL( _ZTISt12out_of_range ) +__TBB_SYMBOL( _ZTSSt12out_of_range ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) +__TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) +__TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) +__TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) +__TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) +__TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) +__TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTSN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTVN3tbb10user_abortE ) + + +// tbb_misc.cpp +__TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) +__TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) +__TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) +__TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) +__TBB_SYMBOL( TBB_runtime_interface_version ) + +// tbb_main.cpp +__TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) +__TBB_SYMBOL( _ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc ) +__TBB_SYMBOL( _ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y ) +__TBB_SYMBOL( _ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_region_begin_v9ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_region_end_v9ENS0_15itt_domain_enumEPvy ) +__TBB_SYMBOL( _ZN3tbb8internal24itt_metadata_ptr_add_v11ENS0_15itt_domain_enumEPvyNS0_12string_indexES2_ ) + +// pipeline.cpp +__TBB_SYMBOL( _ZTIN3tbb6filterE ) +__TBB_SYMBOL( _ZTSN3tbb6filterE ) +__TBB_SYMBOL( _ZTVN3tbb6filterE ) +__TBB_SYMBOL( _ZN3tbb6filterD2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline3runEm ) +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZN3tbb8pipeline3runEmRNS_18task_group_contextE ) +#endif +__TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) +__TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTSN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTVN3tbb8pipelineE ) +__TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) + +// queuing_rw_mutex.cpp +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) + +// reader_writer_lock.cpp +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) + +#if !TBB_NO_LEGACY +// spin_rw_mutex.cpp v2 +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) +#endif + +// spin_rw_mutex v3 +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) + +// x86_rtm_rw_mutex.cpp +#if __TBB_TSX_AVAILABLE +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) +#endif + +// spin_mutex.cpp +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) + +// mutex.cpp +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) + +// recursive_mutex.cpp +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) + +// queuing_mutex.cpp +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) + +// critical_section.cpp +__TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) + +#if !TBB_NO_LEGACY +// concurrent_hash_map +__TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) + +// concurrent_queue.cpp v2 +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityElm ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Em ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) +__TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) +#endif + +// concurrent_queue v3 +// constructors +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Em ) +// destructors +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) +// typeinfo +__TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) +// vtable +__TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) +// methods +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityElm ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) + +#if !TBB_NO_LEGACY +// concurrent_vector.cpp v2 +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_mPFvPvPKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvmEb ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEmmPFvPvmE ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEmmm ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEmRm ) +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEmmPFvPvmE ) +__TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) +#endif + +// concurrent_vector v3 +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_mPFvPvPKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_mPFvPvmEPFvS4_PKvmESA_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEmmPFvPvPKvmES4_ ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEmmm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEmRm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEmmPFvPvPKvmES4_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEmPvPFvS2_mEPFvS2_PKvmE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEm ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEmmmPKvPFvPvmEPFvS4_S3_mE ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEmmPFvPvPKvmES4_ ) + +// tbb_thread +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) +__TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFPvS2_ES2_ ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Em ) +__TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) + +// global parameter +__TBB_SYMBOL( _ZN3tbb10interface914global_control12active_valueEi ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control15internal_createEv ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control16internal_destroyEv ) + +#if __TBB_PREVIEW_RESUMABLE_TASKS +__TBB_SYMBOL( _ZN3tbb8internal16internal_suspendEPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal15internal_resumeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal30internal_current_suspend_pointEv ) +#endif + +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mailbox.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mailbox.h new file mode 100644 index 00000000..795f01b8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mailbox.h @@ -0,0 +1,242 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_mailbox_H +#define _TBB_mailbox_H + +#include "tbb/tbb_stddef.h" +#include "tbb/cache_aligned_allocator.h" + +#include "scheduler_common.h" +#include "tbb/atomic.h" + +namespace tbb { +namespace internal { + +struct task_proxy : public task { + static const intptr_t pool_bit = 1<<0; + static const intptr_t mailbox_bit = 1<<1; + static const intptr_t location_mask = pool_bit | mailbox_bit; + /* All but two low-order bits represent a (task*). + Two low-order bits mean: + 1 = proxy is/was/will be in task pool + 2 = proxy is/was/will be in mailbox */ + intptr_t task_and_tag; + + //! Pointer to next task_proxy in a mailbox + task_proxy *__TBB_atomic next_in_mailbox; + + //! Mailbox to which this was mailed. + mail_outbox* outbox; + + //! True if the proxy is stored both in its sender's pool and in the destination mailbox. + static bool is_shared ( intptr_t tat ) { + return (tat & location_mask) == location_mask; + } + + //! Returns a pointer to the encapsulated task or NULL. + static task* task_ptr ( intptr_t tat ) { + return (task*)(tat & ~location_mask); + } + + //! Returns a pointer to the encapsulated task or NULL, and frees proxy if necessary. + template<intptr_t from_bit> + inline task* extract_task () { + __TBB_ASSERT( prefix().extra_state == es_task_proxy, "Normal task misinterpreted as a proxy?" ); + intptr_t tat = __TBB_load_with_acquire(task_and_tag); + __TBB_ASSERT( tat == from_bit || (is_shared(tat) && task_ptr(tat)), + "Proxy's tag cannot specify both locations if the proxy " + "was retrieved from one of its original locations" ); + if ( tat != from_bit ) { + const intptr_t cleaner_bit = location_mask & ~from_bit; + // Attempt to transition the proxy to the "empty" state with + // cleaner_bit specifying entity responsible for its eventual freeing. + // Explicit cast to void* is to work around a seeming ICC 11.1 bug. + if ( as_atomic(task_and_tag).compare_and_swap(cleaner_bit, tat) == tat ) { + // Successfully grabbed the task, and left new owner with the job of freeing the proxy + return task_ptr(tat); + } + } + // Proxied task has already been claimed from another proxy location. + __TBB_ASSERT( task_and_tag == from_bit, "Empty proxy cannot contain non-zero task pointer" ); + return NULL; + } +}; // struct task_proxy + +//! Internal representation of mail_outbox, without padding. +class unpadded_mail_outbox { +protected: + typedef task_proxy*__TBB_atomic proxy_ptr; + + //! Pointer to first task_proxy in mailbox, or NULL if box is empty. + proxy_ptr my_first; + + //! Pointer to pointer that will point to next item in the queue. Never NULL. + proxy_ptr* __TBB_atomic my_last; + + //! Approximate number of tasks in mailbox to prevent an unlimited grow when the owner is not available. + tbb::atomic<int> my_task_count; + + //! Owner of mailbox is not executing a task, and has drained its own task pool. + bool my_is_idle; +}; + +//! Class representing where mail is put. +/** Padded to occupy a cache line. */ +class mail_outbox : padded<unpadded_mail_outbox> { + static const int mailbox_task_limit = 32; + + task_proxy* internal_pop( __TBB_ISOLATION_EXPR(isolation_tag isolation) ) { + task_proxy* curr = __TBB_load_relaxed( my_first ); + if ( !curr ) + return NULL; + task_proxy **prev_ptr = &my_first; +#if __TBB_TASK_ISOLATION + if ( isolation != no_isolation ) { + while ( curr->prefix().isolation != isolation ) { + prev_ptr = &curr->next_in_mailbox; + curr = curr->next_in_mailbox; + if ( !curr ) + return NULL; + } + } +#endif /* __TBB_TASK_ISOLATION */ + __TBB_control_consistency_helper(); // on my_first + // There is a first item in the mailbox. See if there is a second. + if ( task_proxy* second = curr->next_in_mailbox ) { + // There are at least two items, so first item can be popped easily. + *prev_ptr = second; + } else { + // There is only one item. Some care is required to pop it. + *prev_ptr = NULL; + if ( as_atomic( my_last ).compare_and_swap( prev_ptr, &curr->next_in_mailbox ) == &curr->next_in_mailbox ) { + // Successfully transitioned mailbox from having one item to having none. + __TBB_ASSERT( !curr->next_in_mailbox, NULL ); + } else { + // Some other thread updated my_last but has not filled in first->next_in_mailbox + // Wait until first item points to second item. + atomic_backoff backoff; + while ( !(second = curr->next_in_mailbox) ) backoff.pause(); + *prev_ptr = second; + } + } + --my_task_count; + __TBB_ASSERT( my_task_count >= 0, NULL ); + __TBB_ASSERT( curr, NULL ); + return curr; + } +public: + friend class mail_inbox; + + //! Push task_proxy onto the mailbox queue of another thread. + /** Implementation is wait-free. + Returns false if there are too many tasks. */ + bool push( task_proxy* t ) { + if (my_task_count > mailbox_task_limit) + return false; + ++my_task_count; + __TBB_ASSERT(t, NULL); + t->next_in_mailbox = NULL; + proxy_ptr * const link = (proxy_ptr *)__TBB_FetchAndStoreW(&my_last,(intptr_t)&t->next_in_mailbox); + // No release fence required for the next store, because there are no memory operations + // between the previous fully fenced atomic operation and the store. + __TBB_store_relaxed(*link, t); + return true; + } + + //! Return true if mailbox is empty + bool empty() { + return __TBB_load_relaxed(my_first) == NULL; + } + + //! Construct *this as a mailbox from zeroed memory. + /** Raise assertion if *this is not previously zeroed, or sizeof(this) is wrong. + This method is provided instead of a full constructor since we know the object + will be constructed in zeroed memory. */ + void construct() { + __TBB_ASSERT( sizeof(*this)==NFS_MaxLineSize, NULL ); + __TBB_ASSERT( !my_first, NULL ); + __TBB_ASSERT( !my_last, NULL ); + __TBB_ASSERT( !my_is_idle, NULL ); + my_last=&my_first; + suppress_unused_warning(pad); + } + + //! Drain the mailbox + intptr_t drain() { + intptr_t k = 0; + // No fences here because other threads have already quit. + for( ; task_proxy* t = my_first; ++k ) { + my_first = t->next_in_mailbox; + NFS_Free((char*)t - task_prefix_reservation_size); + } + return k; + } + + //! True if thread that owns this mailbox is looking for work. + bool recipient_is_idle() { + return my_is_idle; + } +}; // class mail_outbox + +//! Class representing source of mail. +class mail_inbox { + //! Corresponding sink where mail that we receive will be put. + mail_outbox* my_putter; +public: + //! Construct unattached inbox + mail_inbox() : my_putter(NULL) {} + + //! Attach inbox to a corresponding outbox. + void attach( mail_outbox& putter ) { + my_putter = &putter; + } + //! Detach inbox from its outbox + void detach() { + __TBB_ASSERT(my_putter,"not attached"); + my_putter = NULL; + } + //! Get next piece of mail, or NULL if mailbox is empty. + task_proxy* pop( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ) { + return my_putter->internal_pop( __TBB_ISOLATION_EXPR( isolation ) ); + } + //! Return true if mailbox is empty + bool empty() { + return my_putter->empty(); + } + //! Indicate whether thread that reads this mailbox is idle. + /** Raises assertion failure if mailbox is redundantly marked as not idle. */ + void set_is_idle( bool value ) { + if( my_putter ) { + __TBB_ASSERT( my_putter->my_is_idle || value, "attempt to redundantly mark mailbox as not idle" ); + my_putter->my_is_idle = value; + } + } + //! Indicate whether thread that reads this mailbox is idle. + bool is_idle_state ( bool value ) const { + return !my_putter || my_putter->my_is_idle == value; + } + +#if DO_ITT_NOTIFY + //! Get pointer to corresponding outbox used for ITT_NOTIFY calls. + void* outbox() const {return my_putter;} +#endif /* DO_ITT_NOTIFY */ +}; // class mail_inbox + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_mailbox_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/market.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/market.cpp new file mode 100644 index 00000000..418bfded --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/market.cpp @@ -0,0 +1,819 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_stddef.h" +#include "tbb/global_control.h" // global_control::active_value + +#include "market.h" +#include "tbb_main.h" +#include "governor.h" +#include "scheduler.h" +#include "itt_notify.h" + +namespace tbb { +namespace internal { + +void market::insert_arena_into_list ( arena& a ) { +#if __TBB_TASK_PRIORITY + arena_list_type &arenas = my_priority_levels[a.my_top_priority].arenas; + arena *&next = my_priority_levels[a.my_top_priority].next_arena; +#else /* !__TBB_TASK_PRIORITY */ + arena_list_type &arenas = my_arenas; + arena *&next = my_next_arena; +#endif /* !__TBB_TASK_PRIORITY */ + arenas.push_front( a ); + if ( arenas.size() == 1 ) + next = &*arenas.begin(); +} + +void market::remove_arena_from_list ( arena& a ) { +#if __TBB_TASK_PRIORITY + arena_list_type &arenas = my_priority_levels[a.my_top_priority].arenas; + arena *&next = my_priority_levels[a.my_top_priority].next_arena; +#else /* !__TBB_TASK_PRIORITY */ + arena_list_type &arenas = my_arenas; + arena *&next = my_next_arena; +#endif /* !__TBB_TASK_PRIORITY */ + arena_list_type::iterator it = next; + __TBB_ASSERT( it != arenas.end(), NULL ); + if ( next == &a ) { + if ( ++it == arenas.end() && arenas.size() > 1 ) + it = arenas.begin(); + next = &*it; + } + arenas.remove( a ); +} + +//------------------------------------------------------------------------ +// market +//------------------------------------------------------------------------ + +market::market ( unsigned workers_soft_limit, unsigned workers_hard_limit, size_t stack_size ) + : my_num_workers_hard_limit(workers_hard_limit) + , my_num_workers_soft_limit(workers_soft_limit) +#if __TBB_TASK_PRIORITY + , my_global_top_priority(normalized_normal_priority) + , my_global_bottom_priority(normalized_normal_priority) +#endif /* __TBB_TASK_PRIORITY */ + , my_ref_count(1) + , my_stack_size(stack_size) + , my_workers_soft_limit_to_report(workers_soft_limit) +{ +#if __TBB_TASK_PRIORITY + __TBB_ASSERT( my_global_reload_epoch == 0, NULL ); + my_priority_levels[normalized_normal_priority].workers_available = my_num_workers_soft_limit; +#endif /* __TBB_TASK_PRIORITY */ + + // Once created RML server will start initializing workers that will need + // global market instance to get worker stack size + my_server = governor::create_rml_server( *this ); + __TBB_ASSERT( my_server, "Failed to create RML server" ); +} + +static unsigned calc_workers_soft_limit(unsigned workers_soft_limit, unsigned workers_hard_limit) { + if( int soft_limit = market::app_parallelism_limit() ) + workers_soft_limit = soft_limit-1; + else // if user set no limits (yet), use market's parameter + workers_soft_limit = max( governor::default_num_threads() - 1, workers_soft_limit ); + if( workers_soft_limit >= workers_hard_limit ) + workers_soft_limit = workers_hard_limit-1; + return workers_soft_limit; +} + +market& market::global_market ( bool is_public, unsigned workers_requested, size_t stack_size ) { + global_market_mutex_type::scoped_lock lock( theMarketMutex ); + market *m = theMarket; + if( m ) { + ++m->my_ref_count; + const unsigned old_public_count = is_public? m->my_public_ref_count++ : /*any non-zero value*/1; + lock.release(); + if( old_public_count==0 ) + set_active_num_workers( calc_workers_soft_limit(workers_requested, m->my_num_workers_hard_limit) ); + + // do not warn if default number of workers is requested + if( workers_requested != governor::default_num_threads()-1 ) { + __TBB_ASSERT( skip_soft_limit_warning > workers_requested, + "skip_soft_limit_warning must be larger than any valid workers_requested" ); + unsigned soft_limit_to_report = m->my_workers_soft_limit_to_report; + if( soft_limit_to_report < workers_requested ) { + runtime_warning( "The number of workers is currently limited to %u. " + "The request for %u workers is ignored. Further requests for more workers " + "will be silently ignored until the limit changes.\n", + soft_limit_to_report, workers_requested ); + // The race is possible when multiple threads report warnings. + // We are OK with that, as there are just multiple warnings. + internal::as_atomic(m->my_workers_soft_limit_to_report). + compare_and_swap(skip_soft_limit_warning, soft_limit_to_report); + } + + } + if( m->my_stack_size < stack_size ) + runtime_warning( "Thread stack size has been already set to %u. " + "The request for larger stack (%u) cannot be satisfied.\n", + m->my_stack_size, stack_size ); + } + else { + // TODO: A lot is done under theMarketMutex locked. Can anything be moved out? + if( stack_size == 0 ) + stack_size = global_control::active_value(global_control::thread_stack_size); + // Expecting that 4P is suitable for most applications. + // Limit to 2P for large thread number. + // TODO: ask RML for max concurrency and possibly correct hard_limit + const unsigned factor = governor::default_num_threads()<=128? 4 : 2; + // The requested number of threads is intentionally not considered in + // computation of the hard limit, in order to separate responsibilities + // and avoid complicated interactions between global_control and task_scheduler_init. + // The market guarantees that at least 256 threads might be created. + const unsigned workers_hard_limit = max(max(factor*governor::default_num_threads(), 256u), app_parallelism_limit()); + const unsigned workers_soft_limit = calc_workers_soft_limit(workers_requested, workers_hard_limit); + // Create the global market instance + size_t size = sizeof(market); +#if __TBB_TASK_GROUP_CONTEXT + __TBB_ASSERT( __TBB_offsetof(market, my_workers) + sizeof(generic_scheduler*) == sizeof(market), + "my_workers must be the last data field of the market class"); + size += sizeof(generic_scheduler*) * (workers_hard_limit - 1); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + __TBB_InitOnce::add_ref(); + void* storage = NFS_Allocate(1, size, NULL); + memset( storage, 0, size ); + // Initialize and publish global market + m = new (storage) market( workers_soft_limit, workers_hard_limit, stack_size ); + if( is_public ) + m->my_public_ref_count = 1; + theMarket = m; + // This check relies on the fact that for shared RML default_concurrency==max_concurrency + if ( !governor::UsePrivateRML && m->my_server->default_concurrency() < workers_soft_limit ) + runtime_warning( "RML might limit the number of workers to %u while %u is requested.\n" + , m->my_server->default_concurrency(), workers_soft_limit ); + } + return *m; +} + +void market::destroy () { +#if __TBB_COUNT_TASK_NODES + if ( my_task_node_count ) + runtime_warning( "Leaked %ld task objects\n", (long)my_task_node_count ); +#endif /* __TBB_COUNT_TASK_NODES */ + this->market::~market(); // qualified to suppress warning + NFS_Free( this ); + __TBB_InitOnce::remove_ref(); +} + +bool market::release ( bool is_public, bool blocking_terminate ) { + __TBB_ASSERT( theMarket == this, "Global market instance was destroyed prematurely?" ); + bool do_release = false; + { + global_market_mutex_type::scoped_lock lock( theMarketMutex ); + if ( blocking_terminate ) { + __TBB_ASSERT( is_public, "Only an object with a public reference can request the blocking terminate" ); + while ( my_public_ref_count == 1 && my_ref_count > 1 ) { + lock.release(); + // To guarantee that request_close_connection() is called by the last master, we need to wait till all + // references are released. Re-read my_public_ref_count to limit waiting if new masters are created. + // Theoretically, new private references to the market can be added during waiting making it potentially + // endless. + // TODO: revise why the weak scheduler needs market's pointer and try to remove this wait. + // Note that the market should know about its schedulers for cancellation/exception/priority propagation, + // see e.g. task_group_context::cancel_group_execution() + while ( __TBB_load_with_acquire( my_public_ref_count ) == 1 && __TBB_load_with_acquire( my_ref_count ) > 1 ) + __TBB_Yield(); + lock.acquire( theMarketMutex ); + } + } + if ( is_public ) { + __TBB_ASSERT( theMarket == this, "Global market instance was destroyed prematurely?" ); + __TBB_ASSERT( my_public_ref_count, NULL ); + --my_public_ref_count; + } + if ( --my_ref_count == 0 ) { + __TBB_ASSERT( !my_public_ref_count, NULL ); + do_release = true; + theMarket = NULL; + } + } + if( do_release ) { + __TBB_ASSERT( !__TBB_load_with_acquire(my_public_ref_count), "No public references remain if we remove the market." ); + // inform RML that blocking termination is required + my_join_workers = blocking_terminate; + my_server->request_close_connection(); + return blocking_terminate; + } + return false; +} + +int market::update_workers_request() { + int old_request = my_num_workers_requested; + my_num_workers_requested = min(my_total_demand, (int)my_num_workers_soft_limit); +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + if (my_mandatory_num_requested > 0) { + __TBB_ASSERT(my_num_workers_soft_limit == 0, NULL); + my_num_workers_requested = 1; + } +#endif +#if __TBB_TASK_PRIORITY + my_priority_levels[my_global_top_priority].workers_available = my_num_workers_requested; + update_allotment(my_global_top_priority); +#else + update_allotment(my_num_workers_requested); +#endif + return my_num_workers_requested - old_request; +} + +void market::set_active_num_workers ( unsigned soft_limit ) { + market *m; + + { + global_market_mutex_type::scoped_lock lock( theMarketMutex ); + if ( !theMarket ) + return; // actual value will be used at market creation + m = theMarket; + if (m->my_num_workers_soft_limit == soft_limit) + return; + ++m->my_ref_count; + } + // have my_ref_count for market, use it safely + + int delta = 0; + { + arenas_list_mutex_type::scoped_lock lock( m->my_arenas_list_mutex ); + __TBB_ASSERT(soft_limit <= m->my_num_workers_hard_limit, NULL); + +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY +#if __TBB_TASK_PRIORITY +#define FOR_EACH_PRIORITY_LEVEL_BEGIN { \ + for (int p = m->my_global_top_priority; p >= m->my_global_bottom_priority; --p) { \ + priority_level_info& pl = m->my_priority_levels[p]; \ + arena_list_type& arenas = pl.arenas; +#else +#define FOR_EACH_PRIORITY_LEVEL_BEGIN { { \ + const int p = 0; \ + tbb::internal::suppress_unused_warning(p); \ + arena_list_type& arenas = m->my_arenas; +#endif +#define FOR_EACH_PRIORITY_LEVEL_END } } + + if (m->my_num_workers_soft_limit == 0 && m->my_mandatory_num_requested > 0) { + FOR_EACH_PRIORITY_LEVEL_BEGIN + for (arena_list_type::iterator it = arenas.begin(); it != arenas.end(); ++it) + if (it->my_global_concurrency_mode) + m->disable_mandatory_concurrency_impl(&*it); + FOR_EACH_PRIORITY_LEVEL_END + } + __TBB_ASSERT(m->my_mandatory_num_requested == 0, NULL); +#endif + + as_atomic(m->my_num_workers_soft_limit) = soft_limit; + // report only once after new soft limit value is set + m->my_workers_soft_limit_to_report = soft_limit; + +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + if (m->my_num_workers_soft_limit == 0) { + FOR_EACH_PRIORITY_LEVEL_BEGIN + for (arena_list_type::iterator it = arenas.begin(); it != arenas.end(); ++it) { + if (!it->my_task_stream.empty(p)) + m->enable_mandatory_concurrency_impl(&*it); + } + FOR_EACH_PRIORITY_LEVEL_END + } +#undef FOR_EACH_PRIORITY_LEVEL_BEGIN +#undef FOR_EACH_PRIORITY_LEVEL_END +#endif + + delta = m->update_workers_request(); + } + // adjust_job_count_estimate must be called outside of any locks + if( delta!=0 ) + m->my_server->adjust_job_count_estimate( delta ); + // release internal market reference to match ++m->my_ref_count above + m->release( /*is_public=*/false, /*blocking_terminate=*/false ); +} + +bool governor::does_client_join_workers (const tbb::internal::rml::tbb_client &client) { + return ((const market&)client).must_join_workers(); +} + +arena* market::create_arena ( int num_slots, int num_reserved_slots, size_t stack_size ) { + __TBB_ASSERT( num_slots > 0, NULL ); + __TBB_ASSERT( num_reserved_slots <= num_slots, NULL ); + // Add public market reference for master thread/task_arena (that adds an internal reference in exchange). + market &m = global_market( /*is_public=*/true, num_slots-num_reserved_slots, stack_size ); + + arena& a = arena::allocate_arena( m, num_slots, num_reserved_slots ); + // Add newly created arena into the existing market's list. + arenas_list_mutex_type::scoped_lock lock(m.my_arenas_list_mutex); + m.insert_arena_into_list(a); + return &a; +} + +/** This method must be invoked under my_arenas_list_mutex. **/ +void market::detach_arena ( arena& a ) { + __TBB_ASSERT( theMarket == this, "Global market instance was destroyed prematurely?" ); + __TBB_ASSERT( !a.my_slots[0].my_scheduler, NULL ); + if (a.my_global_concurrency_mode) + disable_mandatory_concurrency_impl(&a); + + remove_arena_from_list(a); + if ( a.my_aba_epoch == my_arenas_aba_epoch ) + ++my_arenas_aba_epoch; +} + +void market::try_destroy_arena ( arena* a, uintptr_t aba_epoch ) { + bool locked = true; + __TBB_ASSERT( a, NULL ); + // we hold reference to the market, so it cannot be destroyed at any moment here + __TBB_ASSERT( this == theMarket, NULL ); + __TBB_ASSERT( my_ref_count!=0, NULL ); + my_arenas_list_mutex.lock(); + assert_market_valid(); +#if __TBB_TASK_PRIORITY + // scan all priority levels, not only in [my_global_bottom_priority;my_global_top_priority] + // range, because arena to be destroyed can have no outstanding request for workers + for ( int p = num_priority_levels-1; p >= 0; --p ) { + priority_level_info &pl = my_priority_levels[p]; + arena_list_type &my_arenas = pl.arenas; +#endif /* __TBB_TASK_PRIORITY */ + arena_list_type::iterator it = my_arenas.begin(); + for ( ; it != my_arenas.end(); ++it ) { + if ( a == &*it ) { + if ( it->my_aba_epoch == aba_epoch ) { + // Arena is alive + if ( !a->my_num_workers_requested && !a->my_references ) { + __TBB_ASSERT( !a->my_num_workers_allotted && (a->my_pool_state == arena::SNAPSHOT_EMPTY || !a->my_max_num_workers), "Inconsistent arena state" ); + // Arena is abandoned. Destroy it. + detach_arena( *a ); + my_arenas_list_mutex.unlock(); + locked = false; + a->free_arena(); + } + } + if (locked) + my_arenas_list_mutex.unlock(); + return; + } + } +#if __TBB_TASK_PRIORITY + } +#endif /* __TBB_TASK_PRIORITY */ + my_arenas_list_mutex.unlock(); +} + +/** This method must be invoked under my_arenas_list_mutex. **/ +arena* market::arena_in_need ( arena_list_type &arenas, arena *hint ) { + if ( arenas.empty() ) + return NULL; + arena_list_type::iterator it = hint; + __TBB_ASSERT( it != arenas.end(), NULL ); + do { + arena& a = *it; + if ( ++it == arenas.end() ) + it = arenas.begin(); + if( a.num_workers_active() < a.my_num_workers_allotted ) { + a.my_references += arena::ref_worker; + return &a; + } + } while ( it != hint ); + return NULL; +} + +int market::update_allotment ( arena_list_type& arenas, int workers_demand, int max_workers ) { + __TBB_ASSERT( workers_demand > 0, NULL ); + max_workers = min(workers_demand, max_workers); + int assigned = 0; + int carry = 0; + for (arena_list_type::iterator it = arenas.begin(); it != arenas.end(); ++it) { + arena& a = *it; + if (a.my_num_workers_requested <= 0) { + __TBB_ASSERT(!a.my_num_workers_allotted, NULL); + continue; + } + int allotted = 0; +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + if (my_num_workers_soft_limit == 0) { + __TBB_ASSERT(max_workers == 0 || max_workers == 1, NULL); + allotted = a.my_global_concurrency_mode && assigned < max_workers ? 1 : 0; + } else +#endif + { + int tmp = a.my_num_workers_requested * max_workers + carry; + allotted = tmp / workers_demand; + carry = tmp % workers_demand; + // a.my_num_workers_requested may temporarily exceed a.my_max_num_workers + allotted = min(allotted, (int)a.my_max_num_workers); + } + a.my_num_workers_allotted = allotted; + assigned += allotted; + } + __TBB_ASSERT( 0 <= assigned && assigned <= max_workers, NULL ); + return assigned; +} + +/** This method must be invoked under my_arenas_list_mutex. **/ +bool market::is_arena_in_list( arena_list_type &arenas, arena *a ) { + if ( a ) { + for ( arena_list_type::iterator it = arenas.begin(); it != arenas.end(); ++it ) + if ( a == &*it ) + return true; + } + return false; +} + +#if __TBB_TASK_PRIORITY +inline void market::update_global_top_priority ( intptr_t newPriority ) { + GATHER_STATISTIC( ++governor::local_scheduler_if_initialized()->my_counters.market_prio_switches ); + my_global_top_priority = newPriority; + my_priority_levels[newPriority].workers_available = +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + my_mandatory_num_requested && !my_num_workers_soft_limit ? 1 : +#endif + my_num_workers_soft_limit; + advance_global_reload_epoch(); +} + +inline void market::reset_global_priority () { + my_global_bottom_priority = normalized_normal_priority; + update_global_top_priority(normalized_normal_priority); +} + +arena* market::arena_in_need ( arena* prev_arena ) { + if( as_atomic(my_total_demand) <= 0 ) + return NULL; + arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex, /*is_writer=*/false); + assert_market_valid(); + int p = my_global_top_priority; + arena *a = NULL; + + // Checks if arena is alive or not + if ( is_arena_in_list( my_priority_levels[p].arenas, prev_arena ) ) { + a = arena_in_need( my_priority_levels[p].arenas, prev_arena ); + } + + while ( !a && p >= my_global_bottom_priority ) { + priority_level_info &pl = my_priority_levels[p--]; + a = arena_in_need( pl.arenas, pl.next_arena ); + if ( a ) { + as_atomic(pl.next_arena) = a; // a subject for innocent data race under the reader lock + // TODO: rework global round robin policy to local or random to avoid this write + } + // TODO: When refactoring task priority code, take into consideration the + // __TBB_TRACK_PRIORITY_LEVEL_SATURATION sections from earlier versions of TBB + } + return a; +} + +void market::update_allotment ( intptr_t highest_affected_priority ) { + intptr_t i = highest_affected_priority; + int available = my_priority_levels[i].workers_available; + for ( ; i >= my_global_bottom_priority; --i ) { + priority_level_info &pl = my_priority_levels[i]; + pl.workers_available = available; + if ( pl.workers_requested ) { + available -= update_allotment( pl.arenas, pl.workers_requested, available ); + if ( available <= 0 ) { // TODO: assertion? + available = 0; + break; + } + } + } + __TBB_ASSERT( i <= my_global_bottom_priority || !available, NULL ); + for ( --i; i >= my_global_bottom_priority; --i ) { + priority_level_info &pl = my_priority_levels[i]; + pl.workers_available = 0; + arena_list_type::iterator it = pl.arenas.begin(); + for ( ; it != pl.arenas.end(); ++it ) { + __TBB_ASSERT( it->my_num_workers_requested >= 0 || !it->my_num_workers_allotted, NULL ); + it->my_num_workers_allotted = 0; + } + } +} +#endif /* __TBB_TASK_PRIORITY */ + +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY +void market::enable_mandatory_concurrency_impl ( arena *a ) { + __TBB_ASSERT(!a->my_global_concurrency_mode, NULL); + __TBB_ASSERT(my_num_workers_soft_limit == 0, NULL); + + a->my_global_concurrency_mode = true; + my_mandatory_num_requested++; +} + +void market::enable_mandatory_concurrency ( arena *a ) { + int delta = 0; + { + arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); + if (my_num_workers_soft_limit != 0 || a->my_global_concurrency_mode) + return; + + enable_mandatory_concurrency_impl(a); + delta = update_workers_request(); + } + + if (delta != 0) + my_server->adjust_job_count_estimate(delta); +} + +void market::disable_mandatory_concurrency_impl(arena* a) { + __TBB_ASSERT(a->my_global_concurrency_mode, NULL); + __TBB_ASSERT(my_mandatory_num_requested > 0, NULL); + + a->my_global_concurrency_mode = false; + my_mandatory_num_requested--; +} + +void market::mandatory_concurrency_disable ( arena *a ) { + int delta = 0; + { + arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); + if (!a->my_global_concurrency_mode) + return; + // There is a racy window in advertise_new_work between mandtory concurrency enabling and + // setting SNAPSHOT_FULL. It gives a chance to spawn request to disable mandatory concurrency. + // Therefore, we double check that there is no enqueued tasks. + if (a->has_enqueued_tasks()) + return; + + __TBB_ASSERT(my_num_workers_soft_limit == 0, NULL); + disable_mandatory_concurrency_impl(a); + + delta = update_workers_request(); + } + if (delta != 0) + my_server->adjust_job_count_estimate(delta); +} +#endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ + +void market::adjust_demand ( arena& a, int delta ) { + __TBB_ASSERT( theMarket, "market instance was destroyed prematurely?" ); + if ( !delta ) + return; + my_arenas_list_mutex.lock(); + int prev_req = a.my_num_workers_requested; + a.my_num_workers_requested += delta; + if ( a.my_num_workers_requested <= 0 ) { + a.my_num_workers_allotted = 0; + if ( prev_req <= 0 ) { + my_arenas_list_mutex.unlock(); + return; + } + delta = -prev_req; + } + else if ( prev_req < 0 ) { + delta = a.my_num_workers_requested; + } + my_total_demand += delta; + unsigned effective_soft_limit = my_num_workers_soft_limit; + if (my_mandatory_num_requested > 0) { + __TBB_ASSERT(effective_soft_limit == 0, NULL); + effective_soft_limit = 1; + } +#if !__TBB_TASK_PRIORITY + update_allotment(effective_soft_limit); +#else /* !__TBB_TASK_PRIORITY */ + intptr_t p = a.my_top_priority; + priority_level_info &pl = my_priority_levels[p]; + pl.workers_requested += delta; + __TBB_ASSERT( pl.workers_requested >= 0, NULL ); + if ( a.my_num_workers_requested <= 0 ) { + if ( a.my_top_priority != normalized_normal_priority ) { + GATHER_STATISTIC( ++governor::local_scheduler_if_initialized()->my_counters.arena_prio_resets ); + update_arena_top_priority( a, normalized_normal_priority ); + } + a.my_bottom_priority = normalized_normal_priority; + } + if ( p == my_global_top_priority ) { + if ( !pl.workers_requested ) { + while ( --p >= my_global_bottom_priority && !my_priority_levels[p].workers_requested ) + continue; + if ( p < my_global_bottom_priority ) + reset_global_priority(); + else + update_global_top_priority(p); + } + my_priority_levels[my_global_top_priority].workers_available = effective_soft_limit; + update_allotment( my_global_top_priority ); + } + else if ( p > my_global_top_priority ) { + __TBB_ASSERT( pl.workers_requested > 0, NULL ); + // TODO: investigate if the following invariant is always valid + __TBB_ASSERT( a.my_num_workers_requested >= 0, NULL ); + update_global_top_priority(p); + a.my_num_workers_allotted = min( (int)effective_soft_limit, a.my_num_workers_requested ); + my_priority_levels[p - 1].workers_available = effective_soft_limit - a.my_num_workers_allotted; + update_allotment( p - 1 ); + } + else if ( p == my_global_bottom_priority ) { + if ( !pl.workers_requested ) { + while ( ++p <= my_global_top_priority && !my_priority_levels[p].workers_requested ) + continue; + if ( p > my_global_top_priority ) + reset_global_priority(); + else + my_global_bottom_priority = p; + } + else + update_allotment( p ); + } + else if ( p < my_global_bottom_priority ) { + int prev_bottom = my_global_bottom_priority; + my_global_bottom_priority = p; + update_allotment( prev_bottom ); + } + else { + __TBB_ASSERT( my_global_bottom_priority < p && p < my_global_top_priority, NULL ); + update_allotment( p ); + } + __TBB_ASSERT( my_global_top_priority >= a.my_top_priority || a.my_num_workers_requested<=0, NULL ); + assert_market_valid(); +#endif /* !__TBB_TASK_PRIORITY */ + if ( delta > 0 ) { + // can't overflow soft_limit, but remember values request by arenas in + // my_total_demand to not prematurely release workers to RML + if ( my_num_workers_requested+delta > (int)effective_soft_limit) + delta = effective_soft_limit - my_num_workers_requested; + } else { + // the number of workers should not be decreased below my_total_demand + if ( my_num_workers_requested+delta < my_total_demand ) + delta = min(my_total_demand, (int)effective_soft_limit) - my_num_workers_requested; + } + my_num_workers_requested += delta; + __TBB_ASSERT( my_num_workers_requested <= (int)effective_soft_limit, NULL ); + + my_arenas_list_mutex.unlock(); + // Must be called outside of any locks + my_server->adjust_job_count_estimate( delta ); + GATHER_STATISTIC( governor::local_scheduler_if_initialized() ? ++governor::local_scheduler_if_initialized()->my_counters.gate_switches : 0 ); +} + +void market::process( job& j ) { + generic_scheduler& s = static_cast<generic_scheduler&>(j); + // s.my_arena can be dead. Don't access it until arena_in_need is called + arena *a = s.my_arena; + __TBB_ASSERT( governor::is_set(&s), NULL ); + + for (int i = 0; i < 2; ++i) { + while ( (a = arena_in_need(a)) ) { + a->process(s); + a = NULL; // to avoid double checks in arena_in_need(arena*) for the same priority level + } + // Workers leave market because there is no arena in need. It can happen earlier than + // adjust_job_count_estimate() decreases my_slack and RML can put this thread to sleep. + // It might result in a busy-loop checking for my_slack<0 and calling this method instantly. + // the yield refines this spinning. + if ( !i ) + __TBB_Yield(); + } + + GATHER_STATISTIC( ++s.my_counters.market_roundtrips ); +} + +void market::cleanup( job& j ) { + __TBB_ASSERT( theMarket != this, NULL ); + generic_scheduler& s = static_cast<generic_scheduler&>(j); + generic_scheduler* mine = governor::local_scheduler_if_initialized(); + __TBB_ASSERT( !mine || mine->is_worker(), NULL ); + if( mine!=&s ) { + governor::assume_scheduler( &s ); + generic_scheduler::cleanup_worker( &s, mine!=NULL ); + governor::assume_scheduler( mine ); + } else { + generic_scheduler::cleanup_worker( &s, true ); + } +} + +void market::acknowledge_close_connection() { + destroy(); +} + +::rml::job* market::create_one_job() { + unsigned index = ++my_first_unused_worker_idx; + __TBB_ASSERT( index > 0, NULL ); + ITT_THREAD_SET_NAME(_T("TBB Worker Thread")); + // index serves as a hint decreasing conflicts between workers when they migrate between arenas + generic_scheduler* s = generic_scheduler::create_worker( *this, index, /* genuine = */ true ); +#if __TBB_TASK_GROUP_CONTEXT + __TBB_ASSERT( index <= my_num_workers_hard_limit, NULL ); + __TBB_ASSERT( !my_workers[index - 1], NULL ); + my_workers[index - 1] = s; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + return s; +} + +#if __TBB_TASK_PRIORITY +void market::update_arena_top_priority ( arena& a, intptr_t new_priority ) { + GATHER_STATISTIC( ++governor::local_scheduler_if_initialized()->my_counters.arena_prio_switches ); + __TBB_ASSERT( a.my_top_priority != new_priority, NULL ); + priority_level_info &prev_level = my_priority_levels[a.my_top_priority], + &new_level = my_priority_levels[new_priority]; + remove_arena_from_list(a); + a.my_top_priority = new_priority; + insert_arena_into_list(a); + as_atomic( a.my_reload_epoch ).fetch_and_increment<tbb::release>(); // TODO: synch with global reload epoch in order to optimize usage of local reload epoch + prev_level.workers_requested -= a.my_num_workers_requested; + new_level.workers_requested += a.my_num_workers_requested; + __TBB_ASSERT( prev_level.workers_requested >= 0 && new_level.workers_requested >= 0, NULL ); +} + +bool market::lower_arena_priority ( arena& a, intptr_t new_priority, uintptr_t old_reload_epoch ) { + // TODO: replace the lock with a try_lock loop which performs a double check of the epoch + arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); + if ( a.my_reload_epoch != old_reload_epoch ) { + assert_market_valid(); + return false; + } + __TBB_ASSERT( a.my_top_priority > new_priority, NULL ); + __TBB_ASSERT( my_global_top_priority >= a.my_top_priority, NULL ); + + intptr_t p = a.my_top_priority; + update_arena_top_priority( a, new_priority ); + if ( a.my_num_workers_requested > 0 ) { + if ( my_global_bottom_priority > new_priority ) { + my_global_bottom_priority = new_priority; + } + if ( p == my_global_top_priority && !my_priority_levels[p].workers_requested ) { + // Global top level became empty + for ( --p; p>my_global_bottom_priority && !my_priority_levels[p].workers_requested; --p ) continue; + update_global_top_priority(p); + } + update_allotment( p ); + } + + __TBB_ASSERT( my_global_top_priority >= a.my_top_priority, NULL ); + assert_market_valid(); + return true; +} + +bool market::update_arena_priority ( arena& a, intptr_t new_priority ) { + // TODO: do not acquire this global lock while checking arena's state. + arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex); + + tbb::internal::assert_priority_valid(new_priority); + __TBB_ASSERT( my_global_top_priority >= a.my_top_priority || a.my_num_workers_requested <= 0, NULL ); + assert_market_valid(); + if ( a.my_top_priority == new_priority ) { + return false; + } + else if ( a.my_top_priority > new_priority ) { + if ( a.my_bottom_priority > new_priority ) + a.my_bottom_priority = new_priority; + return false; + } + else if ( a.my_num_workers_requested <= 0 ) { + return false; + } + + __TBB_ASSERT( my_global_top_priority >= a.my_top_priority, NULL ); + + intptr_t p = a.my_top_priority; + intptr_t highest_affected_level = max(p, new_priority); + update_arena_top_priority( a, new_priority ); + + if ( my_global_top_priority < new_priority ) { + update_global_top_priority(new_priority); + } + else if ( my_global_top_priority == new_priority ) { + advance_global_reload_epoch(); + } + else { + __TBB_ASSERT( new_priority < my_global_top_priority, NULL ); + __TBB_ASSERT( new_priority > my_global_bottom_priority, NULL ); + if ( p == my_global_top_priority && !my_priority_levels[p].workers_requested ) { + // Global top level became empty + __TBB_ASSERT( my_global_bottom_priority < p, NULL ); + for ( --p; !my_priority_levels[p].workers_requested; --p ) continue; + __TBB_ASSERT( p >= new_priority, NULL ); + update_global_top_priority(p); + highest_affected_level = p; + } + } + if ( p == my_global_bottom_priority ) { + // Arena priority was increased from the global bottom level. + __TBB_ASSERT( p < new_priority, NULL ); + __TBB_ASSERT( new_priority <= my_global_top_priority, NULL ); + while ( my_global_bottom_priority < my_global_top_priority + && !my_priority_levels[my_global_bottom_priority].workers_requested ) + ++my_global_bottom_priority; + __TBB_ASSERT( my_global_bottom_priority <= new_priority, NULL ); + __TBB_ASSERT( my_priority_levels[my_global_bottom_priority].workers_requested > 0, NULL ); + } + update_allotment( highest_affected_level ); + + __TBB_ASSERT( my_global_top_priority >= a.my_top_priority, NULL ); + assert_market_valid(); + return true; +} +#endif /* __TBB_TASK_PRIORITY */ + +} // namespace internal +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/market.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/market.h new file mode 100644 index 00000000..8c4a1282 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/market.h @@ -0,0 +1,391 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_market_H +#define _TBB_market_H + +#include "tbb/tbb_stddef.h" + +#include "scheduler_common.h" +#include "tbb/atomic.h" +#include "tbb/spin_rw_mutex.h" +#include "../rml/include/rml_tbb.h" + +#include "intrusive_list.h" + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (push) + #pragma warning (disable: 4244) +#endif + +namespace tbb { + +class task_group_context; + +namespace internal { + +//------------------------------------------------------------------------ +// Class market +//------------------------------------------------------------------------ + +class market : no_copy, rml::tbb_client { + friend class generic_scheduler; + friend class arena; + friend class tbb::interface7::internal::task_arena_base; + template<typename SchedulerTraits> friend class custom_scheduler; + friend class tbb::task_group_context; +private: + friend void ITT_DoUnsafeOneTimeInitialization (); + + typedef intrusive_list<arena> arena_list_type; + typedef intrusive_list<generic_scheduler> scheduler_list_type; + + //! Currently active global market + static market* theMarket; + + typedef scheduler_mutex_type global_market_mutex_type; + + //! Mutex guarding creation/destruction of theMarket, insertions/deletions in my_arenas, and cancellation propagation + static global_market_mutex_type theMarketMutex; + + //! Lightweight mutex guarding accounting operations with arenas list + typedef spin_rw_mutex arenas_list_mutex_type; + arenas_list_mutex_type my_arenas_list_mutex; + + //! Pointer to the RML server object that services this TBB instance. + rml::tbb_server* my_server; + + //! Maximal number of workers allowed for use by the underlying resource manager + /** It can't be changed after market creation. **/ + unsigned my_num_workers_hard_limit; + + //! Current application-imposed limit on the number of workers (see set_active_num_workers()) + /** It can't be more than my_num_workers_hard_limit. **/ + unsigned my_num_workers_soft_limit; + + //! Number of workers currently requested from RML + int my_num_workers_requested; + + //! First unused index of worker + /** Used to assign indices to the new workers coming from RML, and busy part + of my_workers array. **/ + atomic<unsigned> my_first_unused_worker_idx; + + //! Number of workers that were requested by all arenas + int my_total_demand; + +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + //! How many times mandatory concurrency was requested from the market + int my_mandatory_num_requested; +#endif + +#if __TBB_TASK_PRIORITY + //! Highest priority among active arenas in the market. + /** Arena priority level is its tasks highest priority (specified by arena's + my_top_priority member). + Arena is active when it has outstanding request for workers. Note that + inactive arena may have workers lingering there for some time. **/ + intptr_t my_global_top_priority; + + //! Lowest priority among active arenas in the market. + /** See also my_global_top_priority **/ + intptr_t my_global_bottom_priority; + + //! Tracks events that may bring tasks in offload areas to the top priority level. + /** Incremented when global top priority is decremented or a task group priority + is elevated to the current top level. **/ + uintptr_t my_global_reload_epoch; + + //! Information about arenas at a particular priority level + struct priority_level_info { + //! List of arenas at this priority level + arena_list_type arenas; + + //! The first arena to be checked when idle worker seeks for an arena to enter + /** The check happens in round-robin fashion. **/ + arena *next_arena; + + //! Total amount of workers requested by arenas at this priority level. + int workers_requested; + + //! Maximal amount of workers the market can tell off to this priority level. + int workers_available; + }; // struct priority_level_info + + //! Information about arenas at different priority levels + priority_level_info my_priority_levels[num_priority_levels]; + +#else /* !__TBB_TASK_PRIORITY */ + + //! List of registered arenas + arena_list_type my_arenas; + + //! The first arena to be checked when idle worker seeks for an arena to enter + /** The check happens in round-robin fashion. **/ + arena *my_next_arena; +#endif /* !__TBB_TASK_PRIORITY */ + + //! ABA prevention marker to assign to newly created arenas + uintptr_t my_arenas_aba_epoch; + + //! Reference count controlling market object lifetime + unsigned my_ref_count; + + //! Count of master threads attached + unsigned my_public_ref_count; + + //! Stack size of worker threads + size_t my_stack_size; + + //! Shutdown mode + bool my_join_workers; + + //! The value indicating that the soft limit warning is unnecessary + static const unsigned skip_soft_limit_warning = ~0U; + + //! Either workers soft limit to be reported via runtime_warning() or skip_soft_limit_warning + unsigned my_workers_soft_limit_to_report; +#if __TBB_COUNT_TASK_NODES + //! Net number of nodes that have been allocated from heap. + /** Updated each time a scheduler or arena is destroyed. */ + atomic<intptr_t> my_task_node_count; +#endif /* __TBB_COUNT_TASK_NODES */ + + //! Constructor + market ( unsigned workers_soft_limit, unsigned workers_hard_limit, size_t stack_size ); + + //! Factory method creating new market object + static market& global_market ( bool is_public, unsigned max_num_workers = 0, size_t stack_size = 0 ); + + //! Destroys and deallocates market object created by market::create() + void destroy (); + + //! Recalculates the number of workers requested from RML and updates the allotment. + int update_workers_request(); + +#if __TBB_TASK_PRIORITY + //! Returns next arena that needs more workers, or NULL. + arena* arena_in_need ( arena* prev_arena ); + + //! Recalculates the number of workers assigned to each arena at and below the specified priority. + /** The actual number of workers servicing a particular arena may temporarily + deviate from the calculated value. **/ + void update_allotment ( intptr_t highest_affected_priority ); + + //! Changes arena's top priority and updates affected priority levels info in the market. + void update_arena_top_priority ( arena& a, intptr_t newPriority ); + + //! Changes market's global top priority and related settings. + inline void update_global_top_priority ( intptr_t newPriority ); + + //! Resets empty market's global top and bottom priority to the normal level. + inline void reset_global_priority (); + + inline void advance_global_reload_epoch () { + __TBB_store_with_release( my_global_reload_epoch, my_global_reload_epoch + 1 ); + } + + void assert_market_valid () const { + __TBB_ASSERT( (my_priority_levels[my_global_top_priority].workers_requested > 0 + && !my_priority_levels[my_global_top_priority].arenas.empty()) + || (my_global_top_priority == my_global_bottom_priority && + my_global_top_priority == normalized_normal_priority), NULL ); + } + +#else /* !__TBB_TASK_PRIORITY */ + + //! Recalculates the number of workers assigned to each arena in the list. + /** The actual number of workers servicing a particular arena may temporarily + deviate from the calculated value. **/ + void update_allotment (unsigned effective_soft_limit) { + if ( my_total_demand ) + update_allotment( my_arenas, my_total_demand, (int)effective_soft_limit ); + } + + // TODO: consider to rewrite the code with is_arena_in_list function + //! Returns next arena that needs more workers, or NULL. + arena* arena_in_need (arena* prev_arena) { + if(__TBB_load_with_acquire(my_total_demand) <= 0) + return NULL; + arenas_list_mutex_type::scoped_lock lock(my_arenas_list_mutex, /*is_writer=*/false); + arena* a = NULL; + + // Checks if arena is alive or not + if ( is_arena_in_list( my_arenas, prev_arena ) ) { + a = arena_in_need( my_arenas, prev_arena ); + } else { + a = arena_in_need( my_arenas, my_next_arena ); + if (a) { + as_atomic(my_next_arena) = a; // a subject for innocent data race under the reader lock + // TODO: rework global round robin policy to local or random to avoid this write + } + } + + return a; + } + + void assert_market_valid () const {} +#endif /* !__TBB_TASK_PRIORITY */ + + //////////////////////////////////////////////////////////////////////////////// + // Helpers to unify code branches dependent on priority feature presence + + void insert_arena_into_list ( arena& a ); + + void remove_arena_from_list ( arena& a ); + + arena* arena_in_need ( arena_list_type &arenas, arena *hint ); + + int update_allotment ( arena_list_type& arenas, int total_demand, int max_workers ); + + bool is_arena_in_list( arena_list_type &arenas, arena *a ); + + + //////////////////////////////////////////////////////////////////////////////// + // Implementation of rml::tbb_client interface methods + + version_type version () const __TBB_override { return 0; } + + unsigned max_job_count () const __TBB_override { return my_num_workers_hard_limit; } + + size_t min_stack_size () const __TBB_override { return worker_stack_size(); } + + policy_type policy () const __TBB_override { return throughput; } + + job* create_one_job () __TBB_override; + + void cleanup( job& j ) __TBB_override; + + void acknowledge_close_connection () __TBB_override; + + void process( job& j ) __TBB_override; + +public: + //! Creates an arena object + /** If necessary, also creates global market instance, and boosts its ref count. + Each call to create_arena() must be matched by the call to arena::free_arena(). **/ + static arena* create_arena ( int num_slots, int num_reserved_slots, size_t stack_size ); + + //! Removes the arena from the market's list + void try_destroy_arena ( arena*, uintptr_t aba_epoch ); + + //! Removes the arena from the market's list + void detach_arena ( arena& ); + + //! Decrements market's refcount and destroys it in the end + bool release ( bool is_public, bool blocking_terminate ); + +#if __TBB_ENQUEUE_ENFORCED_CONCURRENCY + //! Imlpementation of mandatory concurrency enabling + void enable_mandatory_concurrency_impl ( arena *a ); + + //! Inform the master that there is an arena with mandatory concurrency + void enable_mandatory_concurrency ( arena *a ); + + //! Inform the master that the arena is no more interested in mandatory concurrency + void disable_mandatory_concurrency_impl(arena* a); + + //! Inform the master that the arena is no more interested in mandatory concurrency + void mandatory_concurrency_disable ( arena *a ); +#endif /* __TBB_ENQUEUE_ENFORCED_CONCURRENCY */ + + //! Request that arena's need in workers should be adjusted. + /** Concurrent invocations are possible only on behalf of different arenas. **/ + void adjust_demand ( arena&, int delta ); + + //! Used when RML asks for join mode during workers termination. + bool must_join_workers () const { return my_join_workers; } + + //! Returns the requested stack size of worker threads. + size_t worker_stack_size () const { return my_stack_size; } + + //! Set number of active workers + static void set_active_num_workers( unsigned w ); + + //! Reports active parallelism level according to user's settings + static unsigned app_parallelism_limit(); + +#if _WIN32||_WIN64 + //! register master with the resource manager + void register_master( ::rml::server::execution_resource_t& rsc_handle ) { + __TBB_ASSERT( my_server, "RML server not defined?" ); + // the server may ignore registration and set master_exec_resource to NULL. + my_server->register_master( rsc_handle ); + } + + //! unregister master with the resource manager + void unregister_master( ::rml::server::execution_resource_t& rsc_handle ) const { + my_server->unregister_master( rsc_handle ); + } +#endif /* WIN */ + +#if __TBB_TASK_GROUP_CONTEXT + //! Finds all contexts affected by the state change and propagates the new state to them. + /** The propagation is relayed to the market because tasks created by one + master thread can be passed to and executed by other masters. This means + that context trees can span several arenas at once and thus state change + propagation cannot be generally localized to one arena only. **/ + template <typename T> + bool propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#if __TBB_TASK_PRIORITY + //! Lowers arena's priority is not higher than newPriority + /** Returns true if arena priority was actually elevated. **/ + bool lower_arena_priority ( arena& a, intptr_t new_priority, uintptr_t old_reload_epoch ); + + //! Makes sure arena's priority is not lower than newPriority + /** Returns true if arena priority was elevated. Also updates arena's bottom + priority boundary if necessary. + + This method is called whenever a user changes priority, because whether + it was hiked or sunk can be determined for sure only under the lock used + by this function. **/ + bool update_arena_priority ( arena& a, intptr_t new_priority ); +#endif /* __TBB_TASK_PRIORITY */ + +#if __TBB_COUNT_TASK_NODES + //! Net number of nodes that have been allocated from heap. + /** Updated each time a scheduler or arena is destroyed. */ + void update_task_node_count( intptr_t delta ) { my_task_node_count += delta; } +#endif /* __TBB_COUNT_TASK_NODES */ + +#if __TBB_TASK_GROUP_CONTEXT + //! List of registered master threads + scheduler_list_type my_masters; + + //! Array of pointers to the registered workers + /** Used by cancellation propagation mechanism. + Must be the last data member of the class market. **/ + generic_scheduler* my_workers[1]; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + static unsigned max_num_workers() { + global_market_mutex_type::scoped_lock lock( theMarketMutex ); + return theMarket? theMarket->my_num_workers_hard_limit : 0; + } +}; // class market + +} // namespace internal +} // namespace tbb + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (pop) +#endif // warning 4244 is back + +#endif /* _TBB_market_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mutex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mutex.cpp new file mode 100644 index 00000000..603109ae --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/mutex.cpp @@ -0,0 +1,148 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _WIN32||_WIN64 +#include <errno.h> // EDEADLK +#endif +#include "tbb/mutex.h" +#include "itt_notify.h" +#if __TBB_TSX_AVAILABLE +#include "governor.h" // for speculation_enabled() +#endif + +namespace tbb { + void mutex::scoped_lock::internal_acquire( mutex& m ) { + +#if _WIN32||_WIN64 + switch( m.state ) { + case INITIALIZED: + case HELD: + EnterCriticalSection( &m.impl ); + // If a thread comes here, and another thread holds the lock, it will block + // in EnterCriticalSection. When it returns from EnterCriticalSection, + // m.state must be set to INITIALIZED. If the same thread tries to acquire a lock it + // already holds, the lock is in HELD state, thus will cause throwing the exception. + if (m.state==HELD) + tbb::internal::handle_perror(EDEADLK,"mutex::scoped_lock: deadlock caused by attempt to reacquire held mutex"); + m.state = HELD; + break; + case DESTROYED: + __TBB_ASSERT(false,"mutex::scoped_lock: mutex already destroyed"); + break; + default: + __TBB_ASSERT(false,"mutex::scoped_lock: illegal mutex state"); + break; + } +#else + int error_code = pthread_mutex_lock(&m.impl); + if( error_code ) + tbb::internal::handle_perror(error_code,"mutex::scoped_lock: pthread_mutex_lock failed"); +#endif /* _WIN32||_WIN64 */ + my_mutex = &m; + } + +void mutex::scoped_lock::internal_release() { + __TBB_ASSERT( my_mutex, "mutex::scoped_lock: not holding a mutex" ); +#if _WIN32||_WIN64 + switch( my_mutex->state ) { + case INITIALIZED: + __TBB_ASSERT(false,"mutex::scoped_lock: try to release the lock without acquisition"); + break; + case HELD: + my_mutex->state = INITIALIZED; + LeaveCriticalSection(&my_mutex->impl); + break; + case DESTROYED: + __TBB_ASSERT(false,"mutex::scoped_lock: mutex already destroyed"); + break; + default: + __TBB_ASSERT(false,"mutex::scoped_lock: illegal mutex state"); + break; + } +#else + int error_code = pthread_mutex_unlock(&my_mutex->impl); + __TBB_ASSERT_EX(!error_code, "mutex::scoped_lock: pthread_mutex_unlock failed"); +#endif /* _WIN32||_WIN64 */ + my_mutex = NULL; +} + +bool mutex::scoped_lock::internal_try_acquire( mutex& m ) { +#if _WIN32||_WIN64 + switch( m.state ) { + case INITIALIZED: + case HELD: + break; + case DESTROYED: + __TBB_ASSERT(false,"mutex::scoped_lock: mutex already destroyed"); + break; + default: + __TBB_ASSERT(false,"mutex::scoped_lock: illegal mutex state"); + break; + } +#endif /* _WIN32||_WIN64 */ + + bool result; +#if _WIN32||_WIN64 + result = TryEnterCriticalSection(&m.impl)!=0; + if( result ) { + __TBB_ASSERT(m.state!=HELD, "mutex::scoped_lock: deadlock caused by attempt to reacquire held mutex"); + m.state = HELD; + } +#else + result = pthread_mutex_trylock(&m.impl)==0; +#endif /* _WIN32||_WIN64 */ + if( result ) + my_mutex = &m; + return result; +} + +void mutex::internal_construct() { +#if _WIN32||_WIN64 + InitializeCriticalSectionEx(&impl, 4000, 0); + state = INITIALIZED; +#else + int error_code = pthread_mutex_init(&impl,NULL); + if( error_code ) + tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed"); +#endif /* _WIN32||_WIN64*/ + ITT_SYNC_CREATE(&impl, _T("tbb::mutex"), _T("")); +} + +void mutex::internal_destroy() { +#if _WIN32||_WIN64 + switch( state ) { + case INITIALIZED: + DeleteCriticalSection(&impl); + break; + case DESTROYED: + __TBB_ASSERT(false,"mutex: already destroyed"); + break; + default: + __TBB_ASSERT(false,"mutex: illegal state for destruction"); + break; + } + state = DESTROYED; +#else + int error_code = pthread_mutex_destroy(&impl); +#if __TBB_TSX_AVAILABLE + // For processors with speculative execution, skip the error code check due to glibc bug #16657 + if( tbb::internal::governor::speculation_enabled() ) return; +#endif + __TBB_ASSERT_EX(!error_code,"mutex: pthread_mutex_destroy failed"); +#endif /* _WIN32||_WIN64 */ +} + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/observer_proxy.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/observer_proxy.cpp new file mode 100644 index 00000000..b22f3c63 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/observer_proxy.cpp @@ -0,0 +1,365 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +#if __TBB_SCHEDULER_OBSERVER + +#include "observer_proxy.h" +#include "tbb_main.h" +#include "governor.h" +#include "scheduler.h" +#include "arena.h" + +namespace tbb { +namespace internal { + +padded<observer_list> the_global_observer_list; + +#if TBB_USE_ASSERT +static atomic<int> observer_proxy_count; + +struct check_observer_proxy_count { + ~check_observer_proxy_count() { + if( observer_proxy_count!=0 ) { + runtime_warning( "Leaked %ld observer_proxy objects\n", long(observer_proxy_count) ); + } + } +}; + +static check_observer_proxy_count the_check_observer_proxy_count; +#endif /* TBB_USE_ASSERT */ + +#if __TBB_ARENA_OBSERVER +interface6::task_scheduler_observer* observer_proxy::get_v6_observer() { + if(my_version != 6) return NULL; + return static_cast<interface6::task_scheduler_observer*>(my_observer); +} +#endif + +#if __TBB_ARENA_OBSERVER +bool observer_proxy::is_global() { + return !get_v6_observer() || get_v6_observer()->my_context_tag == interface6::task_scheduler_observer::global_tag; +} +#endif /* __TBB_ARENA_OBSERVER */ + +observer_proxy::observer_proxy( task_scheduler_observer_v3& tso ) + : my_list(NULL), my_next(NULL), my_prev(NULL), my_observer(&tso) +{ +#if TBB_USE_ASSERT + ++observer_proxy_count; +#endif /* TBB_USE_ASSERT */ + // 1 for observer + my_ref_count = 1; + my_version = +#if __TBB_ARENA_OBSERVER + load<relaxed>(my_observer->my_busy_count) + == interface6::task_scheduler_observer::v6_trait ? 6 : +#endif + 0; + __TBB_ASSERT( my_version >= 6 || !load<relaxed>(my_observer->my_busy_count), NULL ); +} + +#if TBB_USE_ASSERT +observer_proxy::~observer_proxy () { + __TBB_ASSERT( !my_ref_count, "Attempt to destroy proxy still in use" ); + poison_value(my_ref_count); + poison_pointer(my_prev); + poison_pointer(my_next); + --observer_proxy_count; +} +#endif /* TBB_USE_ASSERT */ + +template<memory_semantics M, class T, class V> +T atomic_fetch_and_store ( T* addr, const V& val ) { + return (T)atomic_traits<sizeof(T), M>::fetch_and_store( addr, (T)val ); +} + +void observer_list::clear () { + __TBB_ASSERT( this != &the_global_observer_list, "Method clear() cannot be used on the list of global observers" ); + // Though the method will work fine for the empty list, we require the caller + // to check for the list emptiness before invoking it to avoid extra overhead. + __TBB_ASSERT( !empty(), NULL ); + { + scoped_lock lock(mutex(), /*is_writer=*/true); + observer_proxy *next = my_head; + while ( observer_proxy *p = next ) { + __TBB_ASSERT( p->my_version >= 6, NULL ); + next = p->my_next; + // Both proxy p and observer p->my_observer (if non-null) are guaranteed + // to be alive while the list is locked. + task_scheduler_observer_v3 *obs = p->my_observer; + // Make sure that possible concurrent observer destruction does not + // conflict with the proxy list cleanup. + if ( !obs || !(p = (observer_proxy*)__TBB_FetchAndStoreW(&obs->my_proxy, 0)) ) + continue; + // accessing 'obs' after detaching of obs->my_proxy leads to the race with observer destruction + __TBB_ASSERT( !next || p == next->my_prev, NULL ); + __TBB_ASSERT( is_alive(p->my_ref_count), "Observer's proxy died prematurely" ); + __TBB_ASSERT( p->my_ref_count == 1, "Reference for observer is missing" ); +#if TBB_USE_ASSERT + p->my_observer = NULL; + p->my_ref_count = 0; +#endif /* TBB_USE_ASSERT */ + remove(p); + delete p; + } + } + while( my_head ) + __TBB_Yield(); +} + +void observer_list::insert ( observer_proxy* p ) { + scoped_lock lock(mutex(), /*is_writer=*/true); + if ( my_head ) { + p->my_prev = my_tail; + my_tail->my_next = p; + } + else + my_head = p; + my_tail = p; +} + +void observer_list::remove ( observer_proxy* p ) { + __TBB_ASSERT( my_head, "Attempt to remove an item from an empty list" ); + __TBB_ASSERT( !my_tail->my_next, "Last item's my_next must be NULL" ); + if( p == my_tail ) { + __TBB_ASSERT( !p->my_next, NULL ); + my_tail = p->my_prev; + } + else { + __TBB_ASSERT( p->my_next, NULL ); + p->my_next->my_prev = p->my_prev; + } + if ( p == my_head ) { + __TBB_ASSERT( !p->my_prev, NULL ); + my_head = p->my_next; + } + else { + __TBB_ASSERT( p->my_prev, NULL ); + p->my_prev->my_next = p->my_next; + } + __TBB_ASSERT( (my_head && my_tail) || (!my_head && !my_tail), NULL ); +} + +void observer_list::remove_ref( observer_proxy* p ) { + int r = p->my_ref_count; + __TBB_ASSERT( is_alive(r), NULL ); + while(r>1) { + __TBB_ASSERT( r!=0, NULL ); + int r_old = p->my_ref_count.compare_and_swap(r-1,r); + if( r_old==r ) { + // Successfully decremented count. + return; + } + r = r_old; + } + __TBB_ASSERT( r==1, NULL ); + // Reference count might go to zero + { + // Use lock to avoid resurrection by a thread concurrently walking the list + observer_list::scoped_lock lock(mutex(), /*is_writer=*/true); + r = --p->my_ref_count; + if( !r ) + remove(p); + } + __TBB_ASSERT( r || !p->my_ref_count, NULL ); + if( !r ) + delete p; +} + +void observer_list::do_notify_entry_observers( observer_proxy*& last, bool worker ) { + // Pointer p marches though the list from last (exclusively) to the end. + observer_proxy *p = last, *prev = p; + for(;;) { + task_scheduler_observer_v3* tso=NULL; + // Hold lock on list only long enough to advance to the next proxy in the list. + { + scoped_lock lock(mutex(), /*is_writer=*/false); + do { + if( p ) { + // We were already processing the list. + if( observer_proxy* q = p->my_next ) { + if( p == prev ) + remove_ref_fast(prev); // sets prev to NULL if successful + p = q; + } + else { + // Reached the end of the list. + if( p == prev ) { + // Keep the reference as we store the 'last' pointer in scheduler + __TBB_ASSERT(p->my_ref_count >= 1 + (p->my_observer?1:0), NULL); + } else { + // The last few proxies were empty + __TBB_ASSERT(p->my_ref_count, NULL); + ++p->my_ref_count; + if( prev ) { + lock.release(); + remove_ref(prev); + } + } + last = p; + return; + } + } else { + // Starting pass through the list + p = my_head; + if( !p ) + return; + } + tso = p->my_observer; + } while( !tso ); + ++p->my_ref_count; + ++tso->my_busy_count; + } + __TBB_ASSERT( !prev || p!=prev, NULL ); + // Release the proxy pinned before p + if( prev ) + remove_ref(prev); + // Do not hold any locks on the list while calling user's code. + // Do not intercept any exceptions that may escape the callback so that + // they are either handled by the TBB scheduler or passed to the debugger. + tso->on_scheduler_entry(worker); + __TBB_ASSERT(p->my_ref_count, NULL); + intptr_t bc = --tso->my_busy_count; + __TBB_ASSERT_EX( bc>=0, "my_busy_count underflowed" ); + prev = p; + } +} + +void observer_list::do_notify_exit_observers( observer_proxy* last, bool worker ) { + // Pointer p marches though the list from the beginning to last (inclusively). + observer_proxy *p = NULL, *prev = NULL; + for(;;) { + task_scheduler_observer_v3* tso=NULL; + // Hold lock on list only long enough to advance to the next proxy in the list. + { + scoped_lock lock(mutex(), /*is_writer=*/false); + do { + if( p ) { + // We were already processing the list. + if( p != last ) { + __TBB_ASSERT( p->my_next, "List items before 'last' must have valid my_next pointer" ); + if( p == prev ) + remove_ref_fast(prev); // sets prev to NULL if successful + p = p->my_next; + } else { + // remove the reference from the last item + remove_ref_fast(p); + if( p ) { + lock.release(); + remove_ref(p); + } + return; + } + } else { + // Starting pass through the list + p = my_head; + __TBB_ASSERT( p, "Nonzero 'last' must guarantee that the global list is non-empty" ); + } + tso = p->my_observer; + } while( !tso ); + // The item is already refcounted + if ( p != last ) // the last is already referenced since entry notification + ++p->my_ref_count; + ++tso->my_busy_count; + } + __TBB_ASSERT( !prev || p!=prev, NULL ); + if( prev ) + remove_ref(prev); + // Do not hold any locks on the list while calling user's code. + // Do not intercept any exceptions that may escape the callback so that + // they are either handled by the TBB scheduler or passed to the debugger. + tso->on_scheduler_exit(worker); + __TBB_ASSERT(p->my_ref_count || p == last, NULL); + intptr_t bc = --tso->my_busy_count; + __TBB_ASSERT_EX( bc>=0, "my_busy_count underflowed" ); + prev = p; + } +} + +void task_scheduler_observer_v3::observe( bool enable ) { + if( enable ) { + if( !my_proxy ) { + my_proxy = new observer_proxy( *this ); + my_busy_count = 0; // proxy stores versioning information, clear it +#if __TBB_ARENA_OBSERVER + if ( !my_proxy->is_global() ) { + // Local observer activation + generic_scheduler* s = governor::local_scheduler_if_initialized(); + __TBB_ASSERT( my_proxy->get_v6_observer(), NULL ); + intptr_t tag = my_proxy->get_v6_observer()->my_context_tag; + if( tag != interface6::task_scheduler_observer::implicit_tag ) { // explicit arena + task_arena *a = reinterpret_cast<task_arena*>(tag); + if ( a->my_arena==NULL ) // Avoid recursion during arena initialization + a->initialize(); + my_proxy->my_list = &a->my_arena->my_observers; + } else { + if( !(s && s->my_arena) ) + s = governor::init_scheduler( task_scheduler_init::automatic, 0, true ); + __TBB_ASSERT( __TBB_InitOnce::initialization_done(), NULL ); + __TBB_ASSERT( s && s->my_arena, NULL ); + my_proxy->my_list = &s->my_arena->my_observers; + } + my_proxy->my_list->insert(my_proxy); + // Notify newly activated observer and other pending ones if it belongs to current arena + if(s && &s->my_arena->my_observers == my_proxy->my_list ) + my_proxy->my_list->notify_entry_observers( s->my_last_local_observer, s->is_worker() ); + } else +#endif /* __TBB_ARENA_OBSERVER */ + { + // Obsolete. Global observer activation + if( !__TBB_InitOnce::initialization_done() ) + DoOneTimeInitializations(); + my_proxy->my_list = &the_global_observer_list; + my_proxy->my_list->insert(my_proxy); + if( generic_scheduler* s = governor::local_scheduler_if_initialized() ) { + // Notify newly created observer of its own thread. + // Any other pending observers are notified too. + the_global_observer_list.notify_entry_observers( s->my_last_global_observer, s->is_worker() ); + } + } + } + } else { + // Make sure that possible concurrent proxy list cleanup does not conflict + // with the observer destruction here. + if ( observer_proxy* proxy = (observer_proxy*)__TBB_FetchAndStoreW(&my_proxy, 0) ) { + // List destruction should not touch this proxy after we've won the above interlocked exchange. + __TBB_ASSERT( proxy->my_observer == this, NULL ); + __TBB_ASSERT( is_alive(proxy->my_ref_count), "Observer's proxy died prematurely" ); + __TBB_ASSERT( proxy->my_ref_count >= 1, "reference for observer missing" ); + observer_list &list = *proxy->my_list; + { + // Ensure that none of the list walkers relies on observer pointer validity + observer_list::scoped_lock lock(list.mutex(), /*is_writer=*/true); + proxy->my_observer = NULL; + // Proxy may still be held by other threads (to track the last notified observer) + if( !--proxy->my_ref_count ) {// nobody can increase it under exclusive lock + list.remove(proxy); + __TBB_ASSERT( !proxy->my_ref_count, NULL ); + delete proxy; + } + } + while( my_busy_count ) // other threads are still accessing the callback + __TBB_Yield(); + } + } +} + +} // namespace internal +} // namespace tbb + +#endif /* __TBB_SCHEDULER_OBSERVER */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/observer_proxy.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/observer_proxy.h new file mode 100644 index 00000000..50b652e1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/observer_proxy.h @@ -0,0 +1,169 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_observer_proxy_H +#define _TBB_observer_proxy_H + +#if __TBB_SCHEDULER_OBSERVER + +#include "scheduler_common.h" // to include task.h +#include "tbb/task_scheduler_observer.h" +#include "tbb/spin_rw_mutex.h" +#include "tbb/aligned_space.h" + +namespace tbb { +namespace internal { + +class observer_list { + friend class arena; + + // Mutex is wrapped with aligned_space to shut up warnings when its destructor + // is called while threads are still using it. + typedef aligned_space<spin_rw_mutex> my_mutex_type; + + //! Pointer to the head of this list. + observer_proxy* my_head; + + //! Pointer to the tail of this list. + observer_proxy* my_tail; + + //! Mutex protecting this list. + my_mutex_type my_mutex; + + //! Back-pointer to the arena this list belongs to. + arena* my_arena; + + //! Decrement refcount of the proxy p if there are other outstanding references. + /** In case of success sets p to NULL. Must be invoked from under the list lock. **/ + inline static void remove_ref_fast( observer_proxy*& p ); + + //! Implements notify_entry_observers functionality. + void do_notify_entry_observers( observer_proxy*& last, bool worker ); + + //! Implements notify_exit_observers functionality. + void do_notify_exit_observers( observer_proxy* last, bool worker ); + +public: + observer_list () : my_head(NULL), my_tail(NULL) {} + + //! Removes and destroys all observer proxies from the list. + /** Cannot be used concurrently with other methods. **/ + void clear (); + + //! Add observer proxy to the tail of the list. + void insert ( observer_proxy* p ); + + //! Remove observer proxy from the list. + void remove ( observer_proxy* p ); + + //! Decrement refcount of the proxy and destroy it if necessary. + /** When refcount reaches zero removes the proxy from the list and destructs it. **/ + void remove_ref( observer_proxy* p ); + + //! Type of the scoped lock for the reader-writer mutex associated with the list. + typedef spin_rw_mutex::scoped_lock scoped_lock; + + //! Accessor to the reader-writer mutex associated with the list. + spin_rw_mutex& mutex () { return my_mutex.begin()[0]; } + + bool empty () const { return my_head == NULL; } + + //! Call entry notifications on observers added after last was notified. + /** Updates last to become the last notified observer proxy (in the global list) + or leaves it to be NULL. The proxy has its refcount incremented. **/ + inline void notify_entry_observers( observer_proxy*& last, bool worker ); + + //! Call exit notifications on last and observers added before it. + inline void notify_exit_observers( observer_proxy*& last, bool worker ); +}; // class observer_list + +//! Wrapper for an observer object +/** To maintain shared lists of observers the scheduler first wraps each observer + object into a proxy so that a list item remained valid even after the corresponding + proxy object is destroyed by the user code. **/ +class observer_proxy { + friend class task_scheduler_observer_v3; + friend class observer_list; + //! Reference count used for garbage collection. + /** 1 for reference from my task_scheduler_observer. + 1 for each task dispatcher's last observer pointer. + No accounting for neighbors in the shared list. */ + atomic<int> my_ref_count; + //! Reference to the list this observer belongs to. + observer_list* my_list; + //! Pointer to next observer in the list specified by my_head. + /** NULL for the last item in the list. **/ + observer_proxy* my_next; + //! Pointer to the previous observer in the list specified by my_head. + /** For the head of the list points to the last item. **/ + observer_proxy* my_prev; + //! Associated observer + task_scheduler_observer_v3* my_observer; + //! Version + char my_version; + +#if __TBB_ARENA_OBSERVER + interface6::task_scheduler_observer* get_v6_observer(); +#endif +#if __TBB_ARENA_OBSERVER + bool is_global(); //TODO: move them back inline when un-CPF'ing +#endif + + //! Constructs proxy for the given observer and adds it to the specified list. + observer_proxy( task_scheduler_observer_v3& ); + +#if TBB_USE_ASSERT + ~observer_proxy(); +#endif /* TBB_USE_ASSERT */ + + //! Shut up the warning + observer_proxy& operator = ( const observer_proxy& ); +}; // class observer_proxy + +inline void observer_list::remove_ref_fast( observer_proxy*& p ) { + if( p->my_observer ) { + // Can decrement refcount quickly, as it cannot drop to zero while under the lock. + int r = --p->my_ref_count; + __TBB_ASSERT_EX( r, NULL ); + p = NULL; + } else { + // Use slow form of refcount decrementing, after the lock is released. + } +} + +inline void observer_list::notify_entry_observers( observer_proxy*& last, bool worker ) { + if ( last == my_tail ) + return; + do_notify_entry_observers( last, worker ); +} + +inline void observer_list::notify_exit_observers( observer_proxy*& last, bool worker ) { + if ( !last ) + return; + __TBB_ASSERT(is_alive((uintptr_t)last), NULL); + do_notify_exit_observers( last, worker ); + __TBB_ASSERT(last, NULL); + poison_value(last); +} + +extern padded<observer_list> the_global_observer_list; + +} // namespace internal +} // namespace tbb + +#endif /* __TBB_SCHEDULER_OBSERVER */ + +#endif /* _TBB_observer_proxy_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/pipeline.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/pipeline.cpp new file mode 100644 index 00000000..89c66f9f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/pipeline.cpp @@ -0,0 +1,788 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/pipeline.h" +#include "tbb/spin_mutex.h" +#include "tbb/cache_aligned_allocator.h" +#include "itt_notify.h" +#include "semaphore.h" +#include "tls.h" // for parallel filters that do not use NULL as end_of_input + + +namespace tbb { + +namespace internal { + +//! This structure is used to store task information in a input buffer +struct task_info { + void* my_object; + //! Invalid unless a task went through an ordered stage. + Token my_token; + //! False until my_token is set. + bool my_token_ready; + //! True if my_object is valid. + bool is_valid; + //! Set to initial state (no object, no token) + void reset() { + my_object = NULL; + my_token = 0; + my_token_ready = false; + is_valid = false; + } +}; +//! A buffer of input items for a filter. +/** Each item is a task_info, inserted into a position in the buffer corresponding to a Token. */ +class input_buffer : no_copy { + friend class tbb::internal::pipeline_root_task; + friend class tbb::filter; + friend class tbb::thread_bound_filter; + friend class tbb::internal::stage_task; + friend class tbb::pipeline; + + typedef Token size_type; + + //! Array of deferred tasks that cannot yet start executing. + task_info* array; + + //! for thread-bound filter, semaphore for waiting, NULL otherwise. + semaphore* my_sem; + + //! Size of array + /** Always 0 or a power of 2 */ + size_type array_size; + + //! Lowest token that can start executing. + /** All prior Token have already been seen. */ + Token low_token; + + //! Serializes updates. + spin_mutex array_mutex; + + //! Resize "array". + /** Caller is responsible to acquiring a lock on "array_mutex". */ + void grow( size_type minimum_size ); + + //! Initial size for "array" + /** Must be a power of 2 */ + static const size_type initial_buffer_size = 4; + + //! Used for out of order buffer, and for assigning my_token if is_ordered and my_token not already assigned + Token high_token; + + //! True for ordered filter, false otherwise. + bool is_ordered; + + //! True for thread-bound filter, false otherwise. + bool is_bound; + + //! for parallel filters that accepts NULLs, thread-local flag for reaching end_of_input + typedef basic_tls<intptr_t> end_of_input_tls_t; + end_of_input_tls_t end_of_input_tls; + bool end_of_input_tls_allocated; // no way to test pthread creation of TLS + + void create_sema(size_t initial_tokens) { __TBB_ASSERT(!my_sem,NULL); my_sem = new internal::semaphore(initial_tokens); } + void free_sema() { __TBB_ASSERT(my_sem,NULL); delete my_sem; } + void sema_P() { __TBB_ASSERT(my_sem,NULL); my_sem->P(); } + void sema_V() { __TBB_ASSERT(my_sem,NULL); my_sem->V(); } + +public: + //! Construct empty buffer. + input_buffer( bool is_ordered_, bool is_bound_ ) : + array(NULL), my_sem(NULL), array_size(0), + low_token(0), high_token(0), + is_ordered(is_ordered_), is_bound(is_bound_), + end_of_input_tls_allocated(false) { + grow(initial_buffer_size); + __TBB_ASSERT( array, NULL ); + if(is_bound) create_sema(0); + } + + //! Destroy the buffer. + ~input_buffer() { + __TBB_ASSERT( array, NULL ); + cache_aligned_allocator<task_info>().deallocate(array,array_size); + poison_pointer( array ); + if(my_sem) { + free_sema(); + } + if(end_of_input_tls_allocated) { + destroy_my_tls(); + } + } + + //! Put a token into the buffer. + /** If task information was placed into buffer, returns true; + otherwise returns false, informing the caller to create and spawn a task. + If input buffer owned by thread-bound filter and the item at + low_token was not valid, issue a V() + If the input_buffer is owned by a successor to a thread-bound filter, + the force_put parameter should be true to ensure the token is inserted + in the buffer. + */ + bool put_token( task_info& info_, bool force_put = false ) { + { + info_.is_valid = true; + spin_mutex::scoped_lock lock( array_mutex ); + Token token; + bool was_empty = !array[low_token&(array_size-1)].is_valid; + if( is_ordered ) { + if( !info_.my_token_ready ) { + info_.my_token = high_token++; + info_.my_token_ready = true; + } + token = info_.my_token; + } else + token = high_token++; + __TBB_ASSERT( (tokendiff_t)(token-low_token)>=0, NULL ); + if( token!=low_token || is_bound || force_put ) { + // Trying to put token that is beyond low_token. + // Need to wait until low_token catches up before dispatching. + if( token-low_token>=array_size ) + grow( token-low_token+1 ); + ITT_NOTIFY( sync_releasing, this ); + array[token&(array_size-1)] = info_; + if(was_empty && is_bound) { + sema_V(); + } + return true; + } + } + return false; + } + + //! Note that processing of a token is finished. + /** Fires up processing of the next token, if processing was deferred. */ + // Uses template to avoid explicit dependency on stage_task. + // This is only called for serial filters, and is the reason for the + // advance parameter in return_item (we're incrementing low_token here.) + // Non-TBF serial stages don't advance the token at the start because the presence + // of the current token in the buffer keeps another stage from being spawned. + template<typename StageTask> + void note_done( Token token, StageTask& spawner ) { + task_info wakee; + wakee.reset(); + { + spin_mutex::scoped_lock lock( array_mutex ); + if( !is_ordered || token==low_token ) { + // Wake the next task + task_info& item = array[++low_token & (array_size-1)]; + ITT_NOTIFY( sync_acquired, this ); + wakee = item; + item.is_valid = false; + } + } + if( wakee.is_valid ) + spawner.spawn_stage_task(wakee); + } + +#if __TBB_TASK_GROUP_CONTEXT + //! The method destroys all data in filters to prevent memory leaks + void clear( filter* my_filter ) { + long t=low_token; + for( size_type i=0; i<array_size; ++i, ++t ){ + task_info& temp = array[t&(array_size-1)]; + if (temp.is_valid ) { + my_filter->finalize(temp.my_object); + temp.is_valid = false; + } + } + } +#endif + + //! return an item, invalidate the queued item, but only advance if the filter + // is parallel (as indicated by advance == true). If the filter is serial, leave the + // item in the buffer to keep another stage from being spawned. + bool return_item(task_info& info, bool advance) { + spin_mutex::scoped_lock lock( array_mutex ); + task_info& item = array[low_token&(array_size-1)]; + ITT_NOTIFY( sync_acquired, this ); + if( item.is_valid ) { + info = item; + item.is_valid = false; + if (advance) low_token++; + return true; + } + return false; + } + + //! true if the current low_token is valid. + bool has_item() { spin_mutex::scoped_lock lock(array_mutex); return array[low_token&(array_size -1)].is_valid; } + + // end_of_input signal for parallel_pipeline, parallel input filters with 0 tokens allowed. + void create_my_tls() { int status = end_of_input_tls.create(); if(status) handle_perror(status, "TLS not allocated for filter"); end_of_input_tls_allocated = true; } + void destroy_my_tls() { int status = end_of_input_tls.destroy(); if(status) handle_perror(status, "Failed to destroy filter TLS"); } + bool my_tls_end_of_input() { return end_of_input_tls.get() != 0; } + void set_my_tls_end_of_input() { end_of_input_tls.set(1); } +}; + +void input_buffer::grow( size_type minimum_size ) { + size_type old_size = array_size; + size_type new_size = old_size ? 2*old_size : initial_buffer_size; + while( new_size<minimum_size ) + new_size*=2; + task_info* new_array = cache_aligned_allocator<task_info>().allocate(new_size); + task_info* old_array = array; + for( size_type i=0; i<new_size; ++i ) + new_array[i].is_valid = false; + long t=low_token; + for( size_type i=0; i<old_size; ++i, ++t ) + new_array[t&(new_size-1)] = old_array[t&(old_size-1)]; + array = new_array; + array_size = new_size; + if( old_array ) + cache_aligned_allocator<task_info>().deallocate(old_array,old_size); +} + +class stage_task: public task, public task_info { +private: + friend class tbb::pipeline; + pipeline& my_pipeline; + filter* my_filter; + //! True if this task has not yet read the input. + bool my_at_start; + +public: + //! Construct stage_task for first stage in a pipeline. + /** Such a stage has not read any input yet. */ + stage_task( pipeline& pipeline ) : + my_pipeline(pipeline), + my_filter(pipeline.filter_list), + my_at_start(true) + { + task_info::reset(); + } + //! Construct stage_task for a subsequent stage in a pipeline. + stage_task( pipeline& pipeline, filter* filter_, const task_info& info ) : + task_info(info), + my_pipeline(pipeline), + my_filter(filter_), + my_at_start(false) + {} + //! Roughly equivalent to the constructor of input stage task + void reset() { + task_info::reset(); + my_filter = my_pipeline.filter_list; + my_at_start = true; + } + //! The virtual task execution method + task* execute() __TBB_override; +#if __TBB_TASK_GROUP_CONTEXT + ~stage_task() + { + if (my_filter && my_object && (my_filter->my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(4)) { + __TBB_ASSERT(is_cancelled(), "Trying to finalize the task that wasn't cancelled"); + my_filter->finalize(my_object); + my_object = NULL; + } + } +#endif // __TBB_TASK_GROUP_CONTEXT + //! Creates and spawns stage_task from task_info + void spawn_stage_task(const task_info& info) + { + stage_task* clone = new (allocate_additional_child_of(*parent())) + stage_task( my_pipeline, my_filter, info ); + spawn(*clone); + } +}; + +task* stage_task::execute() { + __TBB_ASSERT( !my_at_start || !my_object, NULL ); + __TBB_ASSERT( !my_filter->is_bound(), NULL ); + if( my_at_start ) { + if( my_filter->is_serial() ) { + my_object = (*my_filter)(my_object); + if( my_object || ( my_filter->object_may_be_null() && !my_pipeline.end_of_input) ) + { + if( my_filter->is_ordered() ) { + my_token = my_pipeline.token_counter++; // ideally, with relaxed semantics + my_token_ready = true; + } else if( (my_filter->my_filter_mode & my_filter->version_mask) >= __TBB_PIPELINE_VERSION(5) ) { + if( my_pipeline.has_thread_bound_filters ) + my_pipeline.token_counter++; // ideally, with relaxed semantics + } + if( !my_filter->next_filter_in_pipeline ) { // we're only filter in pipeline + reset(); + goto process_another_stage; + } else { + ITT_NOTIFY( sync_releasing, &my_pipeline.input_tokens ); + if( --my_pipeline.input_tokens>0 ) + spawn( *new( allocate_additional_child_of(*parent()) ) stage_task( my_pipeline ) ); + } + } else { + my_pipeline.end_of_input = true; + return NULL; + } + } else /*not is_serial*/ { + if( my_pipeline.end_of_input ) + return NULL; + if( (my_filter->my_filter_mode & my_filter->version_mask) >= __TBB_PIPELINE_VERSION(5) ) { + if( my_pipeline.has_thread_bound_filters ) + my_pipeline.token_counter++; + } + ITT_NOTIFY( sync_releasing, &my_pipeline.input_tokens ); + if( --my_pipeline.input_tokens>0 ) + spawn( *new( allocate_additional_child_of(*parent()) ) stage_task( my_pipeline ) ); + my_object = (*my_filter)(my_object); + if( !my_object && (!my_filter->object_may_be_null() || my_filter->my_input_buffer->my_tls_end_of_input()) ) + { + my_pipeline.end_of_input = true; + if( (my_filter->my_filter_mode & my_filter->version_mask) >= __TBB_PIPELINE_VERSION(5) ) { + if( my_pipeline.has_thread_bound_filters ) + my_pipeline.token_counter--; // fix token_counter + } + return NULL; + } + } + my_at_start = false; + } else { + my_object = (*my_filter)(my_object); + if( my_filter->is_serial() ) + my_filter->my_input_buffer->note_done(my_token, *this); + } + my_filter = my_filter->next_filter_in_pipeline; + if( my_filter ) { + // There is another filter to execute. + if( my_filter->is_serial() ) { + // The next filter must execute tokens in order + if( my_filter->my_input_buffer->put_token(*this) ){ + // Can't proceed with the same item + if( my_filter->is_bound() ) { + // Find the next non-thread-bound filter + do { + my_filter = my_filter->next_filter_in_pipeline; + } while( my_filter && my_filter->is_bound() ); + // Check if there is an item ready to process + if( my_filter && my_filter->my_input_buffer->return_item(*this, !my_filter->is_serial())) + goto process_another_stage; + } + my_filter = NULL; // To prevent deleting my_object twice if exception occurs + return NULL; + } + } + } else { + // Reached end of the pipe. + size_t ntokens_avail = ++my_pipeline.input_tokens; + if(my_pipeline.filter_list->is_bound() ) { + if(ntokens_avail == 1) { + my_pipeline.filter_list->my_input_buffer->sema_V(); + } + return NULL; + } + if( ntokens_avail>1 // Only recycle if there is one available token + || my_pipeline.end_of_input ) { + return NULL; // No need to recycle for new input + } + ITT_NOTIFY( sync_acquired, &my_pipeline.input_tokens ); + // Recycle as an input stage task. + reset(); + } +process_another_stage: + /* A semi-hackish way to reexecute the same task object immediately without spawning. + recycle_as_continuation marks the task for future execution, + and then 'this' pointer is returned to bypass spawning. */ + recycle_as_continuation(); + return this; +} + +class pipeline_root_task: public task { + pipeline& my_pipeline; + bool do_segment_scanning; + + task* execute() __TBB_override { + if( !my_pipeline.end_of_input ) + if( !my_pipeline.filter_list->is_bound() ) + if( my_pipeline.input_tokens > 0 ) { + recycle_as_continuation(); + set_ref_count(1); + return new( allocate_child() ) stage_task( my_pipeline ); + } + if( do_segment_scanning ) { + filter* current_filter = my_pipeline.filter_list->next_segment; + /* first non-thread-bound filter that follows thread-bound one + and may have valid items to process */ + filter* first_suitable_filter = current_filter; + while( current_filter ) { + __TBB_ASSERT( !current_filter->is_bound(), "filter is thread-bound?" ); + __TBB_ASSERT( current_filter->prev_filter_in_pipeline->is_bound(), "previous filter is not thread-bound?" ); + if( !my_pipeline.end_of_input || current_filter->has_more_work()) + { + task_info info; + info.reset(); + task* bypass = NULL; + int refcnt = 0; + task_list list; + // No new tokens are created; it's OK to process all waiting tokens. + // If the filter is serial, the second call to return_item will return false. + while( current_filter->my_input_buffer->return_item(info, !current_filter->is_serial()) ) { + task* t = new( allocate_child() ) stage_task( my_pipeline, current_filter, info ); + if( ++refcnt == 1 ) + bypass = t; + else // there's more than one task + list.push_back(*t); + // TODO: limit the list size (to arena size?) to spawn tasks sooner + __TBB_ASSERT( refcnt <= int(my_pipeline.token_counter), "token counting error" ); + info.reset(); + } + if( refcnt ) { + set_ref_count( refcnt ); + if( refcnt > 1 ) + spawn(list); + recycle_as_continuation(); + return bypass; + } + current_filter = current_filter->next_segment; + if( !current_filter ) { + if( !my_pipeline.end_of_input ) { + recycle_as_continuation(); + return this; + } + current_filter = first_suitable_filter; + __TBB_Yield(); + } + } else { + /* The preceding pipeline segment is empty. + Fast-forward to the next post-TBF segment. */ + first_suitable_filter = first_suitable_filter->next_segment; + current_filter = first_suitable_filter; + } + } /* while( current_filter ) */ + return NULL; + } else { + if( !my_pipeline.end_of_input ) { + recycle_as_continuation(); + return this; + } + return NULL; + } + } +public: + pipeline_root_task( pipeline& pipeline ): my_pipeline(pipeline), do_segment_scanning(false) + { + __TBB_ASSERT( my_pipeline.filter_list, NULL ); + filter* first = my_pipeline.filter_list; + if( (first->my_filter_mode & first->version_mask) >= __TBB_PIPELINE_VERSION(5) ) { + // Scanning the pipeline for segments + filter* head_of_previous_segment = first; + for( filter* subfilter=first->next_filter_in_pipeline; + subfilter!=NULL; + subfilter=subfilter->next_filter_in_pipeline ) + { + if( subfilter->prev_filter_in_pipeline->is_bound() && !subfilter->is_bound() ) { + do_segment_scanning = true; + head_of_previous_segment->next_segment = subfilter; + head_of_previous_segment = subfilter; + } + } + } + } +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + // Suppress compiler warning about constant conditional expression + #pragma warning (disable: 4127) +#endif + +// The class destroys end_counter and clears all input buffers if pipeline was cancelled. +class pipeline_cleaner: internal::no_copy { + pipeline& my_pipeline; +public: + pipeline_cleaner(pipeline& _pipeline) : + my_pipeline(_pipeline) + {} + ~pipeline_cleaner(){ +#if __TBB_TASK_GROUP_CONTEXT + if (my_pipeline.end_counter->is_cancelled()) // Pipeline was cancelled + my_pipeline.clear_filters(); +#endif + my_pipeline.end_counter = NULL; + } +}; + +} // namespace internal + +void pipeline::inject_token( task& ) { + __TBB_ASSERT(false,"illegal call to inject_token"); +} + +#if __TBB_TASK_GROUP_CONTEXT +void pipeline::clear_filters() { + for( filter* f = filter_list; f; f = f->next_filter_in_pipeline ) { + if ((f->my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(4)) + if( internal::input_buffer* b = f->my_input_buffer ) + b->clear(f); + } +} +#endif + +pipeline::pipeline() : + filter_list(NULL), + filter_end(NULL), + end_counter(NULL), + end_of_input(false), + has_thread_bound_filters(false) +{ + token_counter = 0; + input_tokens = 0; +} + +pipeline::~pipeline() { + clear(); +} + +void pipeline::clear() { + filter* next; + for( filter* f = filter_list; f; f=next ) { + if( internal::input_buffer* b = f->my_input_buffer ) { + delete b; + f->my_input_buffer = NULL; + } + next=f->next_filter_in_pipeline; + f->next_filter_in_pipeline = filter::not_in_pipeline(); + if ( (f->my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(3) ) { + f->prev_filter_in_pipeline = filter::not_in_pipeline(); + f->my_pipeline = NULL; + } + if ( (f->my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(5) ) + f->next_segment = NULL; + } + filter_list = filter_end = NULL; +} + +void pipeline::add_filter( filter& filter_ ) { +#if TBB_USE_ASSERT + if ( (filter_.my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(3) ) + __TBB_ASSERT( filter_.prev_filter_in_pipeline==filter::not_in_pipeline(), "filter already part of pipeline?" ); + __TBB_ASSERT( filter_.next_filter_in_pipeline==filter::not_in_pipeline(), "filter already part of pipeline?" ); + __TBB_ASSERT( !end_counter, "invocation of add_filter on running pipeline" ); +#endif + if ( (filter_.my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(3) ) { + filter_.my_pipeline = this; + filter_.prev_filter_in_pipeline = filter_end; + if ( filter_list == NULL) + filter_list = &filter_; + else + filter_end->next_filter_in_pipeline = &filter_; + filter_.next_filter_in_pipeline = NULL; + filter_end = &filter_; + } else { + if( !filter_end ) + filter_end = reinterpret_cast<filter*>(&filter_list); + + *reinterpret_cast<filter**>(filter_end) = &filter_; + filter_end = reinterpret_cast<filter*>(&filter_.next_filter_in_pipeline); + *reinterpret_cast<filter**>(filter_end) = NULL; + } + if( (filter_.my_filter_mode & filter_.version_mask) >= __TBB_PIPELINE_VERSION(5) ) { + if( filter_.is_serial() ) { + if( filter_.is_bound() ) + has_thread_bound_filters = true; + filter_.my_input_buffer = new internal::input_buffer( filter_.is_ordered(), filter_.is_bound() ); + } else { + if(filter_.prev_filter_in_pipeline) { + if(filter_.prev_filter_in_pipeline->is_bound()) { + // successors to bound filters must have an input_buffer + filter_.my_input_buffer = new internal::input_buffer( /*is_ordered*/false, false ); + } + } else { // input filter + if(filter_.object_may_be_null() ) { + //TODO: buffer only needed to hold TLS; could improve + filter_.my_input_buffer = new internal::input_buffer( /*is_ordered*/false, false ); + filter_.my_input_buffer->create_my_tls(); + } + } + } + } else { + if( filter_.is_serial() ) { + filter_.my_input_buffer = new internal::input_buffer( filter_.is_ordered(), false ); + } + } + +} + +void pipeline::remove_filter( filter& filter_ ) { + __TBB_ASSERT( filter_.prev_filter_in_pipeline!=filter::not_in_pipeline(), "filter not part of pipeline" ); + __TBB_ASSERT( filter_.next_filter_in_pipeline!=filter::not_in_pipeline(), "filter not part of pipeline" ); + __TBB_ASSERT( !end_counter, "invocation of remove_filter on running pipeline" ); + if (&filter_ == filter_list) + filter_list = filter_.next_filter_in_pipeline; + else { + __TBB_ASSERT( filter_.prev_filter_in_pipeline, "filter list broken?" ); + filter_.prev_filter_in_pipeline->next_filter_in_pipeline = filter_.next_filter_in_pipeline; + } + if (&filter_ == filter_end) + filter_end = filter_.prev_filter_in_pipeline; + else { + __TBB_ASSERT( filter_.next_filter_in_pipeline, "filter list broken?" ); + filter_.next_filter_in_pipeline->prev_filter_in_pipeline = filter_.prev_filter_in_pipeline; + } + if( internal::input_buffer* b = filter_.my_input_buffer ) { + delete b; + filter_.my_input_buffer = NULL; + } + filter_.next_filter_in_pipeline = filter_.prev_filter_in_pipeline = filter::not_in_pipeline(); + if ( (filter_.my_filter_mode & filter::version_mask) >= __TBB_PIPELINE_VERSION(5) ) + filter_.next_segment = NULL; + filter_.my_pipeline = NULL; +} + +void pipeline::run( size_t max_number_of_live_tokens +#if __TBB_TASK_GROUP_CONTEXT + , tbb::task_group_context& context +#endif + ) { + __TBB_ASSERT( max_number_of_live_tokens>0, "pipeline::run must have at least one token" ); + __TBB_ASSERT( !end_counter, "pipeline already running?" ); + if( filter_list ) { + internal::pipeline_cleaner my_pipeline_cleaner(*this); + end_of_input = false; + input_tokens = internal::Token(max_number_of_live_tokens); + if(has_thread_bound_filters) { + // release input filter if thread-bound + if(filter_list->is_bound()) { + filter_list->my_input_buffer->sema_V(); + } + } +#if __TBB_TASK_GROUP_CONTEXT + end_counter = new( task::allocate_root(context) ) internal::pipeline_root_task( *this ); +#else + end_counter = new( task::allocate_root() ) internal::pipeline_root_task( *this ); +#endif + // Start execution of tasks + task::spawn_root_and_wait( *end_counter ); + + if(has_thread_bound_filters) { + for(filter* f = filter_list->next_filter_in_pipeline; f; f=f->next_filter_in_pipeline) { + if(f->is_bound()) { + f->my_input_buffer->sema_V(); // wake to end + } + } + } + } +} + +#if __TBB_TASK_GROUP_CONTEXT +void pipeline::run( size_t max_number_of_live_tokens ) { + if( filter_list ) { + // Construct task group context with the exception propagation mode expected + // by the pipeline caller. + uintptr_t ctx_traits = filter_list->my_filter_mode & filter::exact_exception_propagation ? + task_group_context::default_traits : + task_group_context::default_traits & ~task_group_context::exact_exception; + task_group_context context(task_group_context::bound, ctx_traits); + run(max_number_of_live_tokens, context); + } +} +#endif // __TBB_TASK_GROUP_CONTEXT + +bool filter::has_more_work() { + __TBB_ASSERT(my_pipeline, NULL); + __TBB_ASSERT(my_input_buffer, "has_more_work() called for filter with no input buffer"); + return (internal::tokendiff_t)(my_pipeline->token_counter - my_input_buffer->low_token) != 0; +} + +filter::~filter() { + if ( (my_filter_mode & version_mask) >= __TBB_PIPELINE_VERSION(3) ) { + if ( next_filter_in_pipeline != filter::not_in_pipeline() ) + my_pipeline->remove_filter(*this); + else + __TBB_ASSERT( prev_filter_in_pipeline == filter::not_in_pipeline(), "probably filter list is broken" ); + } else { + __TBB_ASSERT( next_filter_in_pipeline==filter::not_in_pipeline(), "cannot destroy filter that is part of pipeline" ); + } +} + +void filter::set_end_of_input() { + __TBB_ASSERT(my_input_buffer, NULL); + __TBB_ASSERT(object_may_be_null(), NULL); + if(is_serial()) { + my_pipeline->end_of_input = true; + } else { + __TBB_ASSERT(my_input_buffer->end_of_input_tls_allocated, NULL); + my_input_buffer->set_my_tls_end_of_input(); + } +} + +thread_bound_filter::result_type thread_bound_filter::process_item() { + return internal_process_item(true); +} + +thread_bound_filter::result_type thread_bound_filter::try_process_item() { + return internal_process_item(false); +} + +thread_bound_filter::result_type thread_bound_filter::internal_process_item(bool is_blocking) { + __TBB_ASSERT(my_pipeline != NULL,"It's not supposed that process_item is called for a filter that is not in a pipeline."); + internal::task_info info; + info.reset(); + + if( my_pipeline->end_of_input && !has_more_work() ) + return end_of_stream; + + if( !prev_filter_in_pipeline ) { + if( my_pipeline->end_of_input ) + return end_of_stream; + while( my_pipeline->input_tokens == 0 ) { + if( !is_blocking ) + return item_not_available; + my_input_buffer->sema_P(); + } + info.my_object = (*this)(info.my_object); + if( info.my_object ) { + __TBB_ASSERT(my_pipeline->input_tokens > 0, "Token failed in thread-bound filter"); + my_pipeline->input_tokens--; + if( is_ordered() ) { + info.my_token = my_pipeline->token_counter; + info.my_token_ready = true; + } + my_pipeline->token_counter++; // ideally, with relaxed semantics + } else { + my_pipeline->end_of_input = true; + return end_of_stream; + } + } else { /* this is not an input filter */ + while( !my_input_buffer->has_item() ) { + if( !is_blocking ) { + return item_not_available; + } + my_input_buffer->sema_P(); + if( my_pipeline->end_of_input && !has_more_work() ) { + return end_of_stream; + } + } + if( !my_input_buffer->return_item(info, /*advance*/true) ) { + __TBB_ASSERT(false,"return_item failed"); + } + info.my_object = (*this)(info.my_object); + } + if( next_filter_in_pipeline ) { + if ( !next_filter_in_pipeline->my_input_buffer->put_token(info,/*force_put=*/true) ) { + __TBB_ASSERT(false, "Couldn't put token after thread-bound buffer"); + } + } else { + size_t ntokens_avail = ++(my_pipeline->input_tokens); + if( my_pipeline->filter_list->is_bound() ) { + if( ntokens_avail == 1 ) { + my_pipeline->filter_list->my_input_buffer->sema_V(); + } + } + } + + return success; +} + +} // tbb + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/private_server.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/private_server.cpp new file mode 100644 index 00000000..d0639038 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/private_server.cpp @@ -0,0 +1,418 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../rml/include/rml_tbb.h" +#include "../rml/server/thread_monitor.h" +#include "tbb/atomic.h" +#include "tbb/cache_aligned_allocator.h" +#include "scheduler_common.h" +#include "governor.h" +#include "tbb_misc.h" + +using rml::internal::thread_monitor; + +namespace tbb { +namespace internal { +namespace rml { + +typedef thread_monitor::handle_type thread_handle; + +class private_server; + +class private_worker: no_copy { +private: + //! State in finite-state machine that controls the worker. + /** State diagram: + init --> starting --> normal + | | | + | V | + \------> quit <------/ + */ + enum state_t { + //! *this is initialized + st_init, + //! *this has associated thread that is starting up. + st_starting, + //! Associated thread is doing normal life sequence. + st_normal, + //! Associated thread has ended normal life sequence and promises to never touch *this again. + st_quit + }; + atomic<state_t> my_state; + + //! Associated server + private_server& my_server; + + //! Associated client + tbb_client& my_client; + + //! index used for avoiding the 64K aliasing problem + const size_t my_index; + + //! Monitor for sleeping when there is no work to do. + /** The invariant that holds for sleeping workers is: + "my_slack<=0 && my_state==st_normal && I am on server's list of asleep threads" */ + thread_monitor my_thread_monitor; + + //! Handle of the OS thread associated with this worker + thread_handle my_handle; + + //! Link for list of workers that are sleeping or have no associated thread. + private_worker* my_next; + + friend class private_server; + + //! Actions executed by the associated thread + void run(); + + //! Wake up associated thread (or launch a thread if there is none) + void wake_or_launch(); + + //! Called by a thread (usually not the associated thread) to commence termination. + void start_shutdown(); + + static __RML_DECL_THREAD_ROUTINE thread_routine( void* arg ); + + static void release_handle(thread_handle my_handle, bool join); + +protected: + private_worker( private_server& server, tbb_client& client, const size_t i ) : + my_server(server), my_client(client), my_index(i), + my_thread_monitor(), my_handle(), my_next() + { + my_state = st_init; + } +}; + +static const size_t cache_line_size = tbb::internal::NFS_MaxLineSize; + + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warnings about uninstantiable class + #pragma warning(push) + #pragma warning(disable:4510 4610) +#endif +class padded_private_worker: public private_worker { + char pad[cache_line_size - sizeof(private_worker)%cache_line_size]; +public: + padded_private_worker( private_server& server, tbb_client& client, const size_t i ) + : private_worker(server,client,i) { suppress_unused_warning(pad); } +}; +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +class private_server: public tbb_server, no_copy { +private: + tbb_client& my_client; + //! Maximum number of threads to be created. + /** Threads are created lazily, so maximum might not actually be reached. */ + const tbb_client::size_type my_n_thread; + + //! Stack size for each thread. */ + const size_t my_stack_size; + + //! Number of jobs that could use their associated thread minus number of active threads. + /** If negative, indicates oversubscription. + If positive, indicates that more threads should run. + Can be lowered asynchronously, but must be raised only while holding my_asleep_list_mutex, + because raising it impacts the invariant for sleeping threads. */ + atomic<int> my_slack; + + //! Counter used to determine when to delete this. + atomic<int> my_ref_count; + + padded_private_worker* my_thread_array; + + //! List of workers that are asleep or committed to sleeping until notified by another thread. + tbb::atomic<private_worker*> my_asleep_list_root; + + //! Protects my_asleep_list_root + typedef scheduler_mutex_type asleep_list_mutex_type; + asleep_list_mutex_type my_asleep_list_mutex; + +#if TBB_USE_ASSERT + atomic<int> my_net_slack_requests; +#endif /* TBB_USE_ASSERT */ + + //! Wake up to two sleeping workers, if there are any sleeping. + /** The call is used to propagate a chain reaction where each thread wakes up two threads, + which in turn each wake up two threads, etc. */ + void propagate_chain_reaction() { + // First test of a double-check idiom. Second test is inside wake_some(0). + if( my_asleep_list_root ) + wake_some(0); + } + + //! Try to add t to list of sleeping workers + bool try_insert_in_asleep_list( private_worker& t ); + + //! Equivalent of adding additional_slack to my_slack and waking up to 2 threads if my_slack permits. + void wake_some( int additional_slack ); + + virtual ~private_server(); + + void remove_server_ref() { + if( --my_ref_count==0 ) { + my_client.acknowledge_close_connection(); + this->~private_server(); + tbb::cache_aligned_allocator<private_server>().deallocate( this, 1 ); + } + } + + friend class private_worker; +public: + private_server( tbb_client& client ); + + version_type version() const __TBB_override { + return 0; + } + + void request_close_connection( bool /*exiting*/ ) __TBB_override { + for( size_t i=0; i<my_n_thread; ++i ) + my_thread_array[i].start_shutdown(); + remove_server_ref(); + } + + void yield() __TBB_override {__TBB_Yield();} + + void independent_thread_number_changed( int ) __TBB_override {__TBB_ASSERT(false,NULL);} + + unsigned default_concurrency() const __TBB_override { return governor::default_num_threads() - 1; } + + void adjust_job_count_estimate( int delta ) __TBB_override; + +#if _WIN32||_WIN64 + void register_master ( ::rml::server::execution_resource_t& ) __TBB_override {} + void unregister_master ( ::rml::server::execution_resource_t ) __TBB_override {} +#endif /* _WIN32||_WIN64 */ +}; + +//------------------------------------------------------------------------ +// Methods of private_worker +//------------------------------------------------------------------------ +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warnings about an initialized variable 'sink_for_alloca' not referenced + #pragma warning(push) + #pragma warning(disable:4189) +#endif +#if __MINGW32__ && __GNUC__==4 &&__GNUC_MINOR__>=2 && !__MINGW64__ +// ensure that stack is properly aligned for TBB threads +__attribute__((force_align_arg_pointer)) +#endif +__RML_DECL_THREAD_ROUTINE private_worker::thread_routine( void* arg ) { + private_worker* self = static_cast<private_worker*>(arg); + AVOID_64K_ALIASING( self->my_index ); + self->run(); + return 0; +} +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +void private_worker::release_handle(thread_handle handle, bool join) { + if (join) + thread_monitor::join(handle); + else + thread_monitor::detach_thread(handle); +} + +void private_worker::start_shutdown() { + state_t s; + + do { + s = my_state; + __TBB_ASSERT( s!=st_quit, NULL ); + } while( my_state.compare_and_swap( st_quit, s )!=s ); + if( s==st_normal || s==st_starting ) { + // May have invalidated invariant for sleeping, so wake up the thread. + // Note that the notify() here occurs without maintaining invariants for my_slack. + // It does not matter, because my_state==st_quit overrides checking of my_slack. + my_thread_monitor.notify(); + // Do not need release handle in st_init state, + // because in this case the thread wasn't started yet. + // For st_starting release is done at launch site. + if (s==st_normal) + release_handle(my_handle, governor::does_client_join_workers(my_client)); + } else if( s==st_init ) { + // Perform action that otherwise would be performed by associated thread when it quits. + my_server.remove_server_ref(); + } +} + +void private_worker::run() { + my_server.propagate_chain_reaction(); + + // Transiting to st_normal here would require setting my_handle, + // which would create race with the launching thread and + // complications in handle management on Windows. + + ::rml::job& j = *my_client.create_one_job(); + while( my_state!=st_quit ) { + if( my_server.my_slack>=0 ) { + my_client.process(j); + } else { + thread_monitor::cookie c; + // Prepare to wait + my_thread_monitor.prepare_wait(c); + // Check/set the invariant for sleeping + if( my_state!=st_quit && my_server.try_insert_in_asleep_list(*this) ) { + my_thread_monitor.commit_wait(c); + __TBB_ASSERT( my_state==st_quit || !my_next, "Thread monitor missed a spurious wakeup?" ); + my_server.propagate_chain_reaction(); + } else { + // Invariant broken + my_thread_monitor.cancel_wait(); + } + } + } + my_client.cleanup(j); + + ++my_server.my_slack; + my_server.remove_server_ref(); +} + +inline void private_worker::wake_or_launch() { + if( my_state==st_init && my_state.compare_and_swap( st_starting, st_init )==st_init ) { + // after this point, remove_server_ref() must be done by created thread +#if USE_WINTHREAD + my_handle = thread_monitor::launch( thread_routine, this, my_server.my_stack_size, &this->my_index ); +#elif USE_PTHREAD + { + affinity_helper fpa; + fpa.protect_affinity_mask( /*restore_process_mask=*/true ); + my_handle = thread_monitor::launch( thread_routine, this, my_server.my_stack_size ); + // Implicit destruction of fpa resets original affinity mask. + } +#endif /* USE_PTHREAD */ + state_t s = my_state.compare_and_swap( st_normal, st_starting ); + if (st_starting != s) { + // Do shutdown during startup. my_handle can't be released + // by start_shutdown, because my_handle value might be not set yet + // at time of transition from st_starting to st_quit. + __TBB_ASSERT( s==st_quit, NULL ); + release_handle(my_handle, governor::does_client_join_workers(my_client)); + } + } + else { + __TBB_ASSERT( !my_next, "Should not wake a thread while it's still in asleep list" ); + my_thread_monitor.notify(); + } +} + +//------------------------------------------------------------------------ +// Methods of private_server +//------------------------------------------------------------------------ +private_server::private_server( tbb_client& client ) : + my_client(client), + my_n_thread(client.max_job_count()), + my_stack_size(client.min_stack_size()), + my_thread_array(NULL) +{ + my_ref_count = my_n_thread+1; + my_slack = 0; +#if TBB_USE_ASSERT + my_net_slack_requests = 0; +#endif /* TBB_USE_ASSERT */ + my_asleep_list_root = NULL; + my_thread_array = tbb::cache_aligned_allocator<padded_private_worker>().allocate( my_n_thread ); + for( size_t i=0; i<my_n_thread; ++i ) { + private_worker* t = new( &my_thread_array[i] ) padded_private_worker( *this, client, i ); + t->my_next = my_asleep_list_root; + my_asleep_list_root = t; + } +} + +private_server::~private_server() { + __TBB_ASSERT( my_net_slack_requests==0, NULL ); + for( size_t i=my_n_thread; i--; ) + my_thread_array[i].~padded_private_worker(); + tbb::cache_aligned_allocator<padded_private_worker>().deallocate( my_thread_array, my_n_thread ); + tbb::internal::poison_pointer( my_thread_array ); +} + +inline bool private_server::try_insert_in_asleep_list( private_worker& t ) { + asleep_list_mutex_type::scoped_lock lock; + if( !lock.try_acquire(my_asleep_list_mutex) ) + return false; + // Contribute to slack under lock so that if another takes that unit of slack, + // it sees us sleeping on the list and wakes us up. + int k = ++my_slack; + if( k<=0 ) { + t.my_next = my_asleep_list_root; + my_asleep_list_root = &t; + return true; + } else { + --my_slack; + return false; + } +} + +void private_server::wake_some( int additional_slack ) { + __TBB_ASSERT( additional_slack>=0, NULL ); + private_worker* wakee[2]; + private_worker**w = wakee; + { + asleep_list_mutex_type::scoped_lock lock(my_asleep_list_mutex); + while( my_asleep_list_root && w<wakee+2 ) { + if( additional_slack>0 ) { + if (additional_slack+my_slack<=0) // additional demand does not exceed surplus supply + break; + --additional_slack; + } else { + // Chain reaction; Try to claim unit of slack + int old; + do { + old = my_slack; + if( old<=0 ) goto done; + } while( my_slack.compare_and_swap(old-1,old)!=old ); + } + // Pop sleeping worker to combine with claimed unit of slack + my_asleep_list_root = (*w++ = my_asleep_list_root)->my_next; + } + if( additional_slack ) { + // Contribute our unused slack to my_slack. + my_slack += additional_slack; + } + } +done: + while( w>wakee ) { + private_worker* ww = *--w; + ww->my_next = NULL; + ww->wake_or_launch(); + } +} + +void private_server::adjust_job_count_estimate( int delta ) { +#if TBB_USE_ASSERT + my_net_slack_requests+=delta; +#endif /* TBB_USE_ASSERT */ + if( delta<0 ) { + my_slack+=delta; + } else if( delta>0 ) { + wake_some( delta ); + } +} + +//! Factory method called from task.cpp to create a private_server. +tbb_server* make_private_server( tbb_client& client ) { + return new( tbb::cache_aligned_allocator<private_server>().allocate(1) ) private_server(client); +} + +} // namespace rml +} // namespace internal + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/queuing_mutex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/queuing_mutex.cpp new file mode 100644 index 00000000..4d71052d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/queuing_mutex.cpp @@ -0,0 +1,104 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/queuing_mutex.h" +#include "tbb/tbb_machine.h" +#include "tbb/tbb_stddef.h" +#include "tbb_misc.h" +#include "itt_notify.h" + +namespace tbb { + +using namespace internal; + +//! A method to acquire queuing_mutex lock +void queuing_mutex::scoped_lock::acquire( queuing_mutex& m ) +{ + __TBB_ASSERT( !this->mutex, "scoped_lock is already holding a mutex"); + + // Must set all fields before the fetch_and_store, because once the + // fetch_and_store executes, *this becomes accessible to other threads. + mutex = &m; + next = NULL; + going = 0; + + // The fetch_and_store must have release semantics, because we are + // "sending" the fields initialized above to other processors. + scoped_lock* pred = m.q_tail.fetch_and_store<tbb::release>(this); + if( pred ) { + ITT_NOTIFY(sync_prepare, mutex); +#if TBB_USE_ASSERT + __TBB_control_consistency_helper(); // on "m.q_tail" + __TBB_ASSERT( !pred->next, "the predecessor has another successor!"); +#endif + pred->next = this; + spin_wait_while_eq( going, 0ul ); + } + ITT_NOTIFY(sync_acquired, mutex); + + // Force acquire so that user's critical section receives correct values + // from processor that was previously in the user's critical section. + __TBB_load_with_acquire(going); +} + +//! A method to acquire queuing_mutex if it is free +bool queuing_mutex::scoped_lock::try_acquire( queuing_mutex& m ) +{ + __TBB_ASSERT( !this->mutex, "scoped_lock is already holding a mutex"); + + // Must set all fields before the fetch_and_store, because once the + // fetch_and_store executes, *this becomes accessible to other threads. + next = NULL; + going = 0; + + // The CAS must have release semantics, because we are + // "sending" the fields initialized above to other processors. + if( m.q_tail.compare_and_swap<tbb::release>(this, NULL) ) + return false; + + // Force acquire so that user's critical section receives correct values + // from processor that was previously in the user's critical section. + __TBB_load_with_acquire(going); + mutex = &m; + ITT_NOTIFY(sync_acquired, mutex); + return true; +} + +//! A method to release queuing_mutex lock +void queuing_mutex::scoped_lock::release( ) +{ + __TBB_ASSERT(this->mutex!=NULL, "no lock acquired"); + + ITT_NOTIFY(sync_releasing, mutex); + if( !next ) { + if( this == mutex->q_tail.compare_and_swap<tbb::release>(NULL, this) ) { + // this was the only item in the queue, and the queue is now empty. + goto done; + } + // Someone in the queue + spin_wait_while_eq( next, (scoped_lock*)0 ); + } + __TBB_ASSERT(next,NULL); + __TBB_store_with_release(next->going, 1); +done: + initialize(); +} + +void queuing_mutex::internal_construct() { + ITT_SYNC_CREATE(this, _T("tbb::queuing_mutex"), _T("")); +} + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/queuing_rw_mutex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/queuing_rw_mutex.cpp new file mode 100644 index 00000000..ca496054 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/queuing_rw_mutex.cpp @@ -0,0 +1,488 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** Before making any changes in the implementation, please emulate algorithmic changes + with SPIN tool using <TBB directory>/tools/spin_models/ReaderWriterMutex.pml. + There could be some code looking as "can be restructured" but its structure does matter! */ + +#include "tbb/queuing_rw_mutex.h" +#include "tbb/tbb_machine.h" +#include "tbb/tbb_stddef.h" +#include "tbb/tbb_machine.h" +#include "itt_notify.h" + + +namespace tbb { + +using namespace internal; + +//! Flag bits in a state_t that specify information about a locking request. +enum state_t_flags { + STATE_NONE = 0, + STATE_WRITER = 1<<0, + STATE_READER = 1<<1, + STATE_READER_UNBLOCKNEXT = 1<<2, + STATE_ACTIVEREADER = 1<<3, + STATE_UPGRADE_REQUESTED = 1<<4, + STATE_UPGRADE_WAITING = 1<<5, + STATE_UPGRADE_LOSER = 1<<6, + STATE_COMBINED_WAITINGREADER = STATE_READER | STATE_READER_UNBLOCKNEXT, + STATE_COMBINED_READER = STATE_COMBINED_WAITINGREADER | STATE_ACTIVEREADER, + STATE_COMBINED_UPGRADING = STATE_UPGRADE_WAITING | STATE_UPGRADE_LOSER +}; + +const unsigned char RELEASED = 0; +const unsigned char ACQUIRED = 1; + +inline bool queuing_rw_mutex::scoped_lock::try_acquire_internal_lock() +{ + return as_atomic(my_internal_lock).compare_and_swap<tbb::acquire>(ACQUIRED,RELEASED) == RELEASED; +} + +inline void queuing_rw_mutex::scoped_lock::acquire_internal_lock() +{ + // Usually, we would use the test-test-and-set idiom here, with exponential backoff. + // But so far, experiments indicate there is no value in doing so here. + while( !try_acquire_internal_lock() ) { + __TBB_Pause(1); + } +} + +inline void queuing_rw_mutex::scoped_lock::release_internal_lock() +{ + __TBB_store_with_release(my_internal_lock,RELEASED); +} + +inline void queuing_rw_mutex::scoped_lock::wait_for_release_of_internal_lock() +{ + spin_wait_until_eq(my_internal_lock, RELEASED); +} + +inline void queuing_rw_mutex::scoped_lock::unblock_or_wait_on_internal_lock( uintptr_t flag ) { + if( flag ) + wait_for_release_of_internal_lock(); + else + release_internal_lock(); +} + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + #pragma warning (push) + #pragma warning (disable: 4311 4312) +#endif + +//! A view of a T* with additional functionality for twiddling low-order bits. +template<typename T> +class tricky_atomic_pointer: no_copy { +public: + typedef typename atomic_selector<sizeof(T*)>::word word; + + template<memory_semantics M> + static T* fetch_and_add( T* volatile * location, word addend ) { + return reinterpret_cast<T*>( atomic_traits<sizeof(T*),M>::fetch_and_add(location, addend) ); + } + template<memory_semantics M> + static T* fetch_and_store( T* volatile * location, T* value ) { + return reinterpret_cast<T*>( atomic_traits<sizeof(T*),M>::fetch_and_store(location, reinterpret_cast<word>(value)) ); + } + template<memory_semantics M> + static T* compare_and_swap( T* volatile * location, T* value, T* comparand ) { + return reinterpret_cast<T*>( + atomic_traits<sizeof(T*),M>::compare_and_swap(location, reinterpret_cast<word>(value), + reinterpret_cast<word>(comparand)) + ); + } + + T* & ref; + tricky_atomic_pointer( T*& original ) : ref(original) {}; + tricky_atomic_pointer( T* volatile & original ) : ref(original) {}; + T* operator&( word operand2 ) const { + return reinterpret_cast<T*>( reinterpret_cast<word>(ref) & operand2 ); + } + T* operator|( word operand2 ) const { + return reinterpret_cast<T*>( reinterpret_cast<word>(ref) | operand2 ); + } +}; + +typedef tricky_atomic_pointer<queuing_rw_mutex::scoped_lock> tricky_pointer; + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + #pragma warning (pop) +#endif + +//! Mask for low order bit of a pointer. +static const tricky_pointer::word FLAG = 0x1; + +inline +uintptr_t get_flag( queuing_rw_mutex::scoped_lock* ptr ) { + return uintptr_t(ptr) & FLAG; +} + +//------------------------------------------------------------------------ +// Methods of queuing_rw_mutex::scoped_lock +//------------------------------------------------------------------------ + +//! A method to acquire queuing_rw_mutex lock +void queuing_rw_mutex::scoped_lock::acquire( queuing_rw_mutex& m, bool write ) +{ + __TBB_ASSERT( !my_mutex, "scoped_lock is already holding a mutex"); + + // Must set all fields before the fetch_and_store, because once the + // fetch_and_store executes, *this becomes accessible to other threads. + my_mutex = &m; + __TBB_store_relaxed(my_prev , (scoped_lock*)0); + __TBB_store_relaxed(my_next , (scoped_lock*)0); + __TBB_store_relaxed(my_going, 0); + my_state = state_t(write ? STATE_WRITER : STATE_READER); + my_internal_lock = RELEASED; + + queuing_rw_mutex::scoped_lock* pred = m.q_tail.fetch_and_store<tbb::release>(this); + + if( write ) { // Acquiring for write + + if( pred ) { + ITT_NOTIFY(sync_prepare, my_mutex); + pred = tricky_pointer(pred) & ~FLAG; + __TBB_ASSERT( !( uintptr_t(pred) & FLAG ), "use of corrupted pointer!" ); +#if TBB_USE_ASSERT + __TBB_control_consistency_helper(); // on "m.q_tail" + __TBB_ASSERT( !__TBB_load_relaxed(pred->my_next), "the predecessor has another successor!"); +#endif + __TBB_store_with_release(pred->my_next,this); + spin_wait_until_eq(my_going, 1); + } + + } else { // Acquiring for read +#if DO_ITT_NOTIFY + bool sync_prepare_done = false; +#endif + if( pred ) { + unsigned short pred_state; + __TBB_ASSERT( !__TBB_load_relaxed(my_prev), "the predecessor is already set" ); + if( uintptr_t(pred) & FLAG ) { + /* this is only possible if pred is an upgrading reader and it signals us to wait */ + pred_state = STATE_UPGRADE_WAITING; + pred = tricky_pointer(pred) & ~FLAG; + } else { + // Load pred->my_state now, because once pred->my_next becomes + // non-NULL, we must assume that *pred might be destroyed. + pred_state = pred->my_state.compare_and_swap<tbb::acquire>(STATE_READER_UNBLOCKNEXT, STATE_READER); + } + __TBB_store_relaxed(my_prev, pred); + __TBB_ASSERT( !( uintptr_t(pred) & FLAG ), "use of corrupted pointer!" ); +#if TBB_USE_ASSERT + __TBB_control_consistency_helper(); // on "m.q_tail" + __TBB_ASSERT( !__TBB_load_relaxed(pred->my_next), "the predecessor has another successor!"); +#endif + __TBB_store_with_release(pred->my_next,this); + if( pred_state != STATE_ACTIVEREADER ) { +#if DO_ITT_NOTIFY + sync_prepare_done = true; + ITT_NOTIFY(sync_prepare, my_mutex); +#endif + spin_wait_until_eq(my_going, 1); + } + } + + // The protected state must have been acquired here before it can be further released to any other reader(s): + unsigned short old_state = my_state.compare_and_swap<tbb::acquire>(STATE_ACTIVEREADER, STATE_READER); + if( old_state!=STATE_READER ) { +#if DO_ITT_NOTIFY + if( !sync_prepare_done ) + ITT_NOTIFY(sync_prepare, my_mutex); +#endif + // Failed to become active reader -> need to unblock the next waiting reader first + __TBB_ASSERT( my_state==STATE_READER_UNBLOCKNEXT, "unexpected state" ); + spin_wait_while_eq(my_next, (scoped_lock*)NULL); + /* my_state should be changed before unblocking the next otherwise it might finish + and another thread can get our old state and left blocked */ + my_state = STATE_ACTIVEREADER; + __TBB_store_with_release(my_next->my_going,1); + } + } + + ITT_NOTIFY(sync_acquired, my_mutex); + + // Force acquire so that user's critical section receives correct values + // from processor that was previously in the user's critical section. + __TBB_load_with_acquire(my_going); +} + +//! A method to acquire queuing_rw_mutex if it is free +bool queuing_rw_mutex::scoped_lock::try_acquire( queuing_rw_mutex& m, bool write ) +{ + __TBB_ASSERT( !my_mutex, "scoped_lock is already holding a mutex"); + + if( load<relaxed>(m.q_tail) ) + return false; // Someone already took the lock + + // Must set all fields before the fetch_and_store, because once the + // fetch_and_store executes, *this becomes accessible to other threads. + __TBB_store_relaxed(my_prev, (scoped_lock*)0); + __TBB_store_relaxed(my_next, (scoped_lock*)0); + __TBB_store_relaxed(my_going, 0); // TODO: remove dead assignment? + my_state = state_t(write ? STATE_WRITER : STATE_ACTIVEREADER); + my_internal_lock = RELEASED; + + // The CAS must have release semantics, because we are + // "sending" the fields initialized above to other processors. + if( m.q_tail.compare_and_swap<tbb::release>(this, NULL) ) + return false; // Someone already took the lock + // Force acquire so that user's critical section receives correct values + // from processor that was previously in the user's critical section. + __TBB_load_with_acquire(my_going); + my_mutex = &m; + ITT_NOTIFY(sync_acquired, my_mutex); + return true; +} + +//! A method to release queuing_rw_mutex lock +void queuing_rw_mutex::scoped_lock::release( ) +{ + __TBB_ASSERT(my_mutex!=NULL, "no lock acquired"); + + ITT_NOTIFY(sync_releasing, my_mutex); + + if( my_state == STATE_WRITER ) { // Acquired for write + + // The logic below is the same as "writerUnlock", but elides + // "return" from the middle of the routine. + // In the statement below, acquire semantics of reading my_next is required + // so that following operations with fields of my_next are safe. + scoped_lock* n = __TBB_load_with_acquire(my_next); + if( !n ) { + if( this == my_mutex->q_tail.compare_and_swap<tbb::release>(NULL, this) ) { + // this was the only item in the queue, and the queue is now empty. + goto done; + } + spin_wait_while_eq( my_next, (scoped_lock*)NULL ); + n = __TBB_load_with_acquire(my_next); + } + __TBB_store_relaxed(n->my_going, 2); // protect next queue node from being destroyed too early + if( n->my_state==STATE_UPGRADE_WAITING ) { + // the next waiting for upgrade means this writer was upgraded before. + acquire_internal_lock(); + queuing_rw_mutex::scoped_lock* tmp = tricky_pointer::fetch_and_store<tbb::release>(&(n->my_prev), NULL); + n->my_state = STATE_UPGRADE_LOSER; + __TBB_store_with_release(n->my_going,1); + unblock_or_wait_on_internal_lock(get_flag(tmp)); + } else { + __TBB_ASSERT( my_state & (STATE_COMBINED_WAITINGREADER | STATE_WRITER), "unexpected state" ); + __TBB_ASSERT( !( uintptr_t(__TBB_load_relaxed(n->my_prev)) & FLAG ), "use of corrupted pointer!" ); + __TBB_store_relaxed(n->my_prev, (scoped_lock*)0); + __TBB_store_with_release(n->my_going,1); + } + + } else { // Acquired for read + + queuing_rw_mutex::scoped_lock *tmp = NULL; +retry: + // Addition to the original paper: Mark my_prev as in use + queuing_rw_mutex::scoped_lock *pred = tricky_pointer::fetch_and_add<tbb::acquire>(&my_prev, FLAG); + + if( pred ) { + if( !(pred->try_acquire_internal_lock()) ) + { + // Failed to acquire the lock on pred. The predecessor either unlinks or upgrades. + // In the second case, it could or could not know my "in use" flag - need to check + tmp = tricky_pointer::compare_and_swap<tbb::release>(&my_prev, pred, tricky_pointer(pred) | FLAG ); + if( !(uintptr_t(tmp) & FLAG) ) { + // Wait for the predecessor to change my_prev (e.g. during unlink) + spin_wait_while_eq( my_prev, tricky_pointer(pred)|FLAG ); + // Now owner of pred is waiting for _us_ to release its lock + pred->release_internal_lock(); + } + // else the "in use" flag is back -> the predecessor didn't get it and will release itself; nothing to do + + tmp = NULL; + goto retry; + } + __TBB_ASSERT(pred && pred->my_internal_lock==ACQUIRED, "predecessor's lock is not acquired"); + __TBB_store_relaxed(my_prev, pred); + acquire_internal_lock(); + + __TBB_store_with_release(pred->my_next,static_cast<scoped_lock *>(NULL)); + + if( !__TBB_load_relaxed(my_next) && this != my_mutex->q_tail.compare_and_swap<tbb::release>(pred, this) ) { + spin_wait_while_eq( my_next, (void*)NULL ); + } + __TBB_ASSERT( !get_flag(__TBB_load_relaxed(my_next)), "use of corrupted pointer" ); + + // ensure acquire semantics of reading 'my_next' + if( scoped_lock *const l_next = __TBB_load_with_acquire(my_next) ) { // I->next != nil, TODO: rename to n after clearing up and adapting the n in the comment two lines below + // Equivalent to I->next->prev = I->prev but protected against (prev[n]&FLAG)!=0 + tmp = tricky_pointer::fetch_and_store<tbb::release>(&(l_next->my_prev), pred); + // I->prev->next = I->next; + __TBB_ASSERT(__TBB_load_relaxed(my_prev)==pred, NULL); + __TBB_store_with_release(pred->my_next, my_next); + } + // Safe to release in the order opposite to acquiring which makes the code simpler + pred->release_internal_lock(); + + } else { // No predecessor when we looked + acquire_internal_lock(); // "exclusiveLock(&I->EL)" + scoped_lock* n = __TBB_load_with_acquire(my_next); + if( !n ) { + if( this != my_mutex->q_tail.compare_and_swap<tbb::release>(NULL, this) ) { + spin_wait_while_eq( my_next, (scoped_lock*)NULL ); + n = __TBB_load_relaxed(my_next); + } else { + goto unlock_self; + } + } + __TBB_store_relaxed(n->my_going, 2); // protect next queue node from being destroyed too early + tmp = tricky_pointer::fetch_and_store<tbb::release>(&(n->my_prev), NULL); + __TBB_store_with_release(n->my_going,1); + } +unlock_self: + unblock_or_wait_on_internal_lock(get_flag(tmp)); + } +done: + spin_wait_while_eq( my_going, 2 ); + + initialize(); +} + +bool queuing_rw_mutex::scoped_lock::downgrade_to_reader() +{ + if ( my_state == STATE_ACTIVEREADER ) return true; // Already a reader + + ITT_NOTIFY(sync_releasing, my_mutex); + my_state = STATE_READER; + if( ! __TBB_load_relaxed(my_next) ) { + // the following load of q_tail must not be reordered with setting STATE_READER above + if( this==my_mutex->q_tail.load<full_fence>() ) { + unsigned short old_state = my_state.compare_and_swap<tbb::release>(STATE_ACTIVEREADER, STATE_READER); + if( old_state==STATE_READER ) + return true; // Downgrade completed + } + /* wait for the next to register */ + spin_wait_while_eq( my_next, (void*)NULL ); + } + scoped_lock *const n = __TBB_load_with_acquire(my_next); + __TBB_ASSERT( n, "still no successor at this point!" ); + if( n->my_state & STATE_COMBINED_WAITINGREADER ) + __TBB_store_with_release(n->my_going,1); + else if( n->my_state==STATE_UPGRADE_WAITING ) + // the next waiting for upgrade means this writer was upgraded before. + n->my_state = STATE_UPGRADE_LOSER; + my_state = STATE_ACTIVEREADER; + return true; +} + +bool queuing_rw_mutex::scoped_lock::upgrade_to_writer() +{ + if ( my_state == STATE_WRITER ) return true; // Already a writer + + queuing_rw_mutex::scoped_lock * tmp; + queuing_rw_mutex::scoped_lock * me = this; + + ITT_NOTIFY(sync_releasing, my_mutex); + my_state = STATE_UPGRADE_REQUESTED; +requested: + __TBB_ASSERT( !(uintptr_t(__TBB_load_relaxed(my_next)) & FLAG), "use of corrupted pointer!" ); + acquire_internal_lock(); + if( this != my_mutex->q_tail.compare_and_swap<tbb::release>(tricky_pointer(me)|FLAG, this) ) { + spin_wait_while_eq( my_next, (void*)NULL ); + queuing_rw_mutex::scoped_lock * n; + n = tricky_pointer::fetch_and_add<tbb::acquire>(&my_next, FLAG); + unsigned short n_state = n->my_state; + /* the next reader can be blocked by our state. the best thing to do is to unblock it */ + if( n_state & STATE_COMBINED_WAITINGREADER ) + __TBB_store_with_release(n->my_going,1); + tmp = tricky_pointer::fetch_and_store<tbb::release>(&(n->my_prev), this); + unblock_or_wait_on_internal_lock(get_flag(tmp)); + if( n_state & (STATE_COMBINED_READER | STATE_UPGRADE_REQUESTED) ) { + // save n|FLAG for simplicity of following comparisons + tmp = tricky_pointer(n)|FLAG; + for( atomic_backoff b; __TBB_load_relaxed(my_next)==tmp; b.pause() ) { + if( my_state & STATE_COMBINED_UPGRADING ) { + if( __TBB_load_with_acquire(my_next)==tmp ) + __TBB_store_relaxed(my_next, n); + goto waiting; + } + } + __TBB_ASSERT(__TBB_load_relaxed(my_next) != (tricky_pointer(n)|FLAG), NULL); + goto requested; + } else { + __TBB_ASSERT( n_state & (STATE_WRITER | STATE_UPGRADE_WAITING), "unexpected state"); + __TBB_ASSERT( (tricky_pointer(n)|FLAG) == __TBB_load_relaxed(my_next), NULL); + __TBB_store_relaxed(my_next, n); + } + } else { + /* We are in the tail; whoever comes next is blocked by q_tail&FLAG */ + release_internal_lock(); + } // if( this != my_mutex->q_tail... ) + my_state.compare_and_swap<tbb::acquire>(STATE_UPGRADE_WAITING, STATE_UPGRADE_REQUESTED); + +waiting: + __TBB_ASSERT( !( intptr_t(__TBB_load_relaxed(my_next)) & FLAG ), "use of corrupted pointer!" ); + __TBB_ASSERT( my_state & STATE_COMBINED_UPGRADING, "wrong state at upgrade waiting_retry" ); + __TBB_ASSERT( me==this, NULL ); + ITT_NOTIFY(sync_prepare, my_mutex); + /* if no one was blocked by the "corrupted" q_tail, turn it back */ + my_mutex->q_tail.compare_and_swap<tbb::release>( this, tricky_pointer(me)|FLAG ); + queuing_rw_mutex::scoped_lock * pred; + pred = tricky_pointer::fetch_and_add<tbb::acquire>(&my_prev, FLAG); + if( pred ) { + bool success = pred->try_acquire_internal_lock(); + pred->my_state.compare_and_swap<tbb::release>(STATE_UPGRADE_WAITING, STATE_UPGRADE_REQUESTED); + if( !success ) { + tmp = tricky_pointer::compare_and_swap<tbb::release>(&my_prev, pred, tricky_pointer(pred)|FLAG ); + if( uintptr_t(tmp) & FLAG ) { + spin_wait_while_eq(my_prev, pred); + pred = __TBB_load_relaxed(my_prev); + } else { + spin_wait_while_eq( my_prev, tricky_pointer(pred)|FLAG ); + pred->release_internal_lock(); + } + } else { + __TBB_store_relaxed(my_prev, pred); + pred->release_internal_lock(); + spin_wait_while_eq(my_prev, pred); + pred = __TBB_load_relaxed(my_prev); + } + if( pred ) + goto waiting; + } else { + // restore the corrupted my_prev field for possible further use (e.g. if downgrade back to reader) + __TBB_store_relaxed(my_prev, pred); + } + __TBB_ASSERT( !pred && !__TBB_load_relaxed(my_prev), NULL ); + + // additional lifetime issue prevention checks + // wait for the successor to finish working with my fields + wait_for_release_of_internal_lock(); + // now wait for the predecessor to finish working with my fields + spin_wait_while_eq( my_going, 2 ); + + // Acquire critical section indirectly from previous owner or directly from predecessor (TODO: not clear). + __TBB_control_consistency_helper(); // on either "my_mutex->q_tail" or "my_going" (TODO: not clear) + + bool result = ( my_state != STATE_UPGRADE_LOSER ); + my_state = STATE_WRITER; + __TBB_store_relaxed(my_going, 1); + + ITT_NOTIFY(sync_acquired, my_mutex); + return result; +} + +void queuing_rw_mutex::internal_construct() { + ITT_SYNC_CREATE(this, _T("tbb::queuing_rw_mutex"), _T("")); +} + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/reader_writer_lock.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/reader_writer_lock.cpp new file mode 100644 index 00000000..0ee81861 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/reader_writer_lock.cpp @@ -0,0 +1,343 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/reader_writer_lock.h" +#include "tbb/tbb_machine.h" +#include "tbb/tbb_exception.h" +#include "itt_notify.h" + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4244) +#endif + +namespace tbb { +namespace interface5 { + +const uintptr_t WFLAG1 = 0x1; // writer interested or active +const uintptr_t WFLAG2 = 0x2; // writers interested, no entering readers +const uintptr_t RFLAG = 0x4; // reader interested but not active +const uintptr_t RC_INCR = 0x8; // to adjust reader count + + +// Perform an atomic bitwise-OR on the operand, and return its previous value. +inline uintptr_t fetch_and_or(atomic<uintptr_t>& operand, uintptr_t value) { + for (tbb::internal::atomic_backoff b;;b.pause()) { + uintptr_t old = operand; + uintptr_t result = operand.compare_and_swap(old|value, old); + if (result==old) return result; + } +} + +// Perform an atomic bitwise-AND on the operand, and return its previous value. +inline uintptr_t fetch_and_and(atomic<uintptr_t>& operand, uintptr_t value) { + for (tbb::internal::atomic_backoff b;;b.pause()) { + uintptr_t old = operand; + uintptr_t result = operand.compare_and_swap(old&value, old); + if (result==old) return result; + } +} + +//! Spin WHILE the value at the location is greater than or equal to a given value +/** T and U should be comparable types. */ +template<typename T, typename U> +void spin_wait_while_geq( const volatile T& location, U value ) { + tbb::internal::atomic_backoff backoff; + while( location>=value ) backoff.pause(); +} + +//! Spin UNTIL (location & value) is true. +/** T and U should be comparable types. */ +template<typename T, typename U> +void spin_wait_until_and( const volatile T& location, U value ) { + tbb::internal::atomic_backoff backoff; + while( !(location & value) ) backoff.pause(); +} + + +void reader_writer_lock::internal_construct() { + reader_head = NULL; + writer_head = NULL; + writer_tail = NULL; + rdr_count_and_flags = 0; + my_current_writer = tbb_thread::id(); +#if TBB_USE_THREADING_TOOLS + ITT_SYNC_CREATE(this, _T("tbb::reader_writer_lock"), _T("")); +#endif /* TBB_USE_THREADING_TOOLS */ +} + +void reader_writer_lock::internal_destroy() { + __TBB_ASSERT(rdr_count_and_flags==0, "reader_writer_lock destroyed with pending readers/writers."); + __TBB_ASSERT(reader_head==NULL, "reader_writer_lock destroyed with pending readers."); + __TBB_ASSERT(writer_tail==NULL, "reader_writer_lock destroyed with pending writers."); + __TBB_ASSERT(writer_head==NULL, "reader_writer_lock destroyed with pending/active writers."); +} + +// Acquires the reader_writer_lock for write. If the lock is currently held in write +// mode by another context, the writer will block by spinning on a local variable. +// Throws exception improper_lock if the context tries to acquire a +// reader_writer_lock that it already has write ownership of. +void reader_writer_lock::lock() { + if (is_current_writer()) { // recursive lock attempt + // we don't support recursive writer locks; throw exception + tbb::internal::throw_exception(tbb::internal::eid_improper_lock); + } + else { + scoped_lock *a_writer_lock = new scoped_lock(); + (void) start_write(a_writer_lock); + } +} + +// Tries to acquire the reader_writer_lock for write. This function does not block. +// Return Value: True or false, depending on whether the lock is acquired or not. +// If the lock is already held by this acquiring context, try_lock() returns false. +bool reader_writer_lock::try_lock() { + if (is_current_writer()) { // recursive lock attempt + return false; + } + else { + scoped_lock *a_writer_lock = new scoped_lock(); + a_writer_lock->status = waiting_nonblocking; + return start_write(a_writer_lock); + } +} + +bool reader_writer_lock::start_write(scoped_lock *I) { + tbb_thread::id id = this_tbb_thread::get_id(); + scoped_lock *pred = NULL; + if (I->status == waiting_nonblocking) { + if ((pred = writer_tail.compare_and_swap(I, NULL)) != NULL) { + delete I; + return false; + } + } + else { + ITT_NOTIFY(sync_prepare, this); + pred = writer_tail.fetch_and_store(I); + } + if (pred) + pred->next = I; + else { + set_next_writer(I); + if (I->status == waiting_nonblocking) { + if (I->next) { // potentially more writers + set_next_writer(I->next); + } + else { // no more writers + writer_head.fetch_and_store(NULL); + if (I != writer_tail.compare_and_swap(NULL, I)) { // an incoming writer is in the process of being added + spin_wait_while_eq(I->next, (scoped_lock *)NULL); // wait for new writer to be added + __TBB_ASSERT(I->next, "There should be a node following the last writer."); + set_next_writer(I->next); + } + } + delete I; + return false; + } + } + spin_wait_while_eq(I->status, waiting); + ITT_NOTIFY(sync_acquired, this); + my_current_writer = id; + return true; +} + +void reader_writer_lock::set_next_writer(scoped_lock *W) { + writer_head = W; + if (W->status == waiting_nonblocking) { + if (rdr_count_and_flags.compare_and_swap(WFLAG1+WFLAG2, 0) == 0) { + W->status = active; + } + } + else { + if (fetch_and_or(rdr_count_and_flags, WFLAG1) & RFLAG) { // reader present + spin_wait_until_and(rdr_count_and_flags, WFLAG2); // block until readers set WFLAG2 + } + else { // no reader in timing window + __TBB_AtomicOR(&rdr_count_and_flags, WFLAG2); + } + spin_wait_while_geq(rdr_count_and_flags, RC_INCR); // block until readers finish + W->status = active; + } +} + +// Acquires the reader_writer_lock for read. If the lock is currently held by a writer, +// this reader will block and wait until the writers are done. +// Throws exception improper_lock when the context tries to acquire a reader_writer_lock +// that it already has write ownership of. +void reader_writer_lock::lock_read() { + if (is_current_writer()) { // recursive lock attempt + // we don't support writer->reader downgrade; throw exception + tbb::internal::throw_exception(tbb::internal::eid_improper_lock); + } + else { + scoped_lock_read a_reader_lock; + start_read(&a_reader_lock); + } +} + +// Tries to acquire the reader_writer_lock for read. This function does not block. +// Return Value: True or false, depending on whether the lock is acquired or not. +bool reader_writer_lock::try_lock_read() { + if (is_current_writer()) { // recursive lock attempt + return false; + } + else { + if (rdr_count_and_flags.fetch_and_add(RC_INCR) & (WFLAG1+WFLAG2)) { // writers present + rdr_count_and_flags -= RC_INCR; + return false; + } + else { // no writers + ITT_NOTIFY(sync_acquired, this); + return true; + } + } +} + +void reader_writer_lock::start_read(scoped_lock_read *I) { + ITT_NOTIFY(sync_prepare, this); + I->next = reader_head.fetch_and_store(I); + if (!I->next) { // first arriving reader in my group; set RFLAG, test writer flags + // unblock and/or update statuses of non-blocking readers + if (!(fetch_and_or(rdr_count_and_flags, RFLAG) & (WFLAG1+WFLAG2))) { // no writers + unblock_readers(); + } + } + __TBB_ASSERT(I->status == waiting || I->status == active, "Lock requests should be waiting or active before blocking."); + spin_wait_while_eq(I->status, waiting); // block + if (I->next) { + __TBB_ASSERT(I->next->status == waiting, NULL); + rdr_count_and_flags += RC_INCR; + I->next->status = active; // wake successor + } + ITT_NOTIFY(sync_acquired, this); +} + +void reader_writer_lock::unblock_readers() { + // clear rdr interest flag, increment rdr count + __TBB_ASSERT(rdr_count_and_flags&RFLAG, NULL); + rdr_count_and_flags += RC_INCR-RFLAG; + __TBB_ASSERT(rdr_count_and_flags >= RC_INCR, NULL); + // indicate clear of window + if (rdr_count_and_flags & WFLAG1 && !(rdr_count_and_flags & WFLAG2)) { + __TBB_AtomicOR(&rdr_count_and_flags, WFLAG2); + } + // unblock waiting readers + scoped_lock_read *head = reader_head.fetch_and_store(NULL); + __TBB_ASSERT(head, NULL); + __TBB_ASSERT(head->status == waiting, NULL); + head->status = active; +} + +// Releases the reader_writer_lock +void reader_writer_lock::unlock() { + if( my_current_writer!=tbb_thread::id() ) { + // A writer owns the lock + __TBB_ASSERT(is_current_writer(), "caller of reader_writer_lock::unlock() does not own the lock."); + __TBB_ASSERT(writer_head, NULL); + __TBB_ASSERT(writer_head->status==active, NULL); + scoped_lock *a_writer_lock = writer_head; + end_write(a_writer_lock); + __TBB_ASSERT(a_writer_lock != writer_head, "Internal error: About to turn writer_head into dangling reference."); + delete a_writer_lock; + } else { + end_read(); + } +} + +void reader_writer_lock::end_write(scoped_lock *I) { + __TBB_ASSERT(I==writer_head, "Internal error: can't unlock a thread that is not holding the lock."); + my_current_writer = tbb_thread::id(); + ITT_NOTIFY(sync_releasing, this); + if (I->next) { // potentially more writers + writer_head = I->next; + writer_head->status = active; + } + else { // No more writers; clear writer flag, test reader interest flag + __TBB_ASSERT(writer_head, NULL); + if (fetch_and_and(rdr_count_and_flags, ~(WFLAG1+WFLAG2)) & RFLAG) { + unblock_readers(); + } + writer_head.fetch_and_store(NULL); + if (I != writer_tail.compare_and_swap(NULL, I)) { // an incoming writer is in the process of being added + spin_wait_while_eq(I->next, (scoped_lock *)NULL); // wait for new writer to be added + __TBB_ASSERT(I->next, "There should be a node following the last writer."); + set_next_writer(I->next); + } + } +} + +void reader_writer_lock::end_read() { + ITT_NOTIFY(sync_releasing, this); + __TBB_ASSERT(rdr_count_and_flags >= RC_INCR, "unlock() called but no readers hold the lock."); + rdr_count_and_flags -= RC_INCR; +} + +inline bool reader_writer_lock::is_current_writer() { + return my_current_writer==this_tbb_thread::get_id(); +} + +// Construct with a blocking attempt to acquire a write lock on the passed reader_writer_lock +void reader_writer_lock::scoped_lock::internal_construct (reader_writer_lock& lock) { + mutex = &lock; + next = NULL; + status = waiting; + if (mutex->is_current_writer()) { // recursive lock attempt + // we don't support recursive writer locks; throw exception + tbb::internal::throw_exception(tbb::internal::eid_improper_lock); + } + else { // this thread holds no locks + (void) mutex->start_write(this); + } +} + +inline reader_writer_lock::scoped_lock::scoped_lock() : mutex(NULL), next(NULL) { + status = waiting; +} + +// Construct with a blocking attempt to acquire a write lock on the passed reader_writer_lock +void reader_writer_lock::scoped_lock_read::internal_construct (reader_writer_lock& lock) { + mutex = &lock; + next = NULL; + status = waiting; + if (mutex->is_current_writer()) { // recursive lock attempt + // we don't support writer->reader downgrade; throw exception + tbb::internal::throw_exception(tbb::internal::eid_improper_lock); + } + else { // this thread holds no locks + mutex->start_read(this); + } +} + +inline reader_writer_lock::scoped_lock_read::scoped_lock_read() : mutex(NULL), next(NULL) { + status = waiting; +} + +void reader_writer_lock::scoped_lock::internal_destroy() { + if (mutex) { + __TBB_ASSERT(mutex->is_current_writer(), "~scoped_lock() destroyed by thread different than thread that holds lock."); + mutex->end_write(this); + } + status = invalid; +} + +void reader_writer_lock::scoped_lock_read::internal_destroy() { + if (mutex) + mutex->end_read(); + status = invalid; +} + +} // namespace interface5 +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/recursive_mutex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/recursive_mutex.cpp new file mode 100644 index 00000000..6e815618 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/recursive_mutex.cpp @@ -0,0 +1,132 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/recursive_mutex.h" +#include "itt_notify.h" + +namespace tbb { + +void recursive_mutex::scoped_lock::internal_acquire( recursive_mutex& m ) { +#if _WIN32||_WIN64 + switch( m.state ) { + case INITIALIZED: + // since we cannot look into the internal of the CriticalSection object + // we won't know how many times the lock has been acquired, and thus + // we won't know when we may safely set the state back to INITIALIZED + // if we change the state to HELD as in mutex.cpp. thus, we won't change + // the state for recursive_mutex + EnterCriticalSection( &m.impl ); + break; + case DESTROYED: + __TBB_ASSERT(false,"recursive_mutex::scoped_lock: mutex already destroyed"); + break; + default: + __TBB_ASSERT(false,"recursive_mutex::scoped_lock: illegal mutex state"); + break; + } +#else + int error_code = pthread_mutex_lock(&m.impl); + if( error_code ) + tbb::internal::handle_perror(error_code,"recursive_mutex::scoped_lock: pthread_mutex_lock failed"); +#endif /* _WIN32||_WIN64 */ + my_mutex = &m; +} + +void recursive_mutex::scoped_lock::internal_release() { + __TBB_ASSERT( my_mutex, "recursive_mutex::scoped_lock: not holding a mutex" ); +#if _WIN32||_WIN64 + switch( my_mutex->state ) { + case INITIALIZED: + LeaveCriticalSection( &my_mutex->impl ); + break; + case DESTROYED: + __TBB_ASSERT(false,"recursive_mutex::scoped_lock: mutex already destroyed"); + break; + default: + __TBB_ASSERT(false,"recursive_mutex::scoped_lock: illegal mutex state"); + break; + } +#else + int error_code = pthread_mutex_unlock(&my_mutex->impl); + __TBB_ASSERT_EX(!error_code, "recursive_mutex::scoped_lock: pthread_mutex_unlock failed"); +#endif /* _WIN32||_WIN64 */ + my_mutex = NULL; +} + +bool recursive_mutex::scoped_lock::internal_try_acquire( recursive_mutex& m ) { +#if _WIN32||_WIN64 + switch( m.state ) { + case INITIALIZED: + break; + case DESTROYED: + __TBB_ASSERT(false,"recursive_mutex::scoped_lock: mutex already destroyed"); + break; + default: + __TBB_ASSERT(false,"recursive_mutex::scoped_lock: illegal mutex state"); + break; + } +#endif /* _WIN32||_WIN64 */ + bool result; +#if _WIN32||_WIN64 + result = TryEnterCriticalSection(&m.impl)!=0; +#else + result = pthread_mutex_trylock(&m.impl)==0; +#endif /* _WIN32||_WIN64 */ + if( result ) + my_mutex = &m; + return result; +} + +void recursive_mutex::internal_construct() { +#if _WIN32||_WIN64 + InitializeCriticalSectionEx(&impl, 4000, 0); + state = INITIALIZED; +#else + pthread_mutexattr_t mtx_attr; + int error_code = pthread_mutexattr_init( &mtx_attr ); + if( error_code ) + tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutexattr_init failed"); + + pthread_mutexattr_settype( &mtx_attr, PTHREAD_MUTEX_RECURSIVE ); + error_code = pthread_mutex_init( &impl, &mtx_attr ); + if( error_code ) + tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_init failed"); + pthread_mutexattr_destroy( &mtx_attr ); +#endif /* _WIN32||_WIN64*/ + ITT_SYNC_CREATE(&impl, _T("tbb::recursive_mutex"), _T("")); +} + +void recursive_mutex::internal_destroy() { +#if _WIN32||_WIN64 + switch( state ) { + case INITIALIZED: + DeleteCriticalSection(&impl); + break; + case DESTROYED: + __TBB_ASSERT(false,"recursive_mutex: already destroyed"); + break; + default: + __TBB_ASSERT(false,"recursive_mutex: illegal state for destruction"); + break; + } + state = DESTROYED; +#else + int error_code = pthread_mutex_destroy(&impl); + __TBB_ASSERT_EX(!error_code,"recursive_mutex: pthread_mutex_destroy failed"); +#endif /* _WIN32||_WIN64 */ +} + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler.cpp new file mode 100644 index 00000000..f98440d4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler.cpp @@ -0,0 +1,1472 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "custom_scheduler.h" +#include "scheduler_utility.h" +#include "governor.h" +#include "market.h" +#include "arena.h" +#include "mailbox.h" +#include "observer_proxy.h" +#include "tbb/tbb_machine.h" +#include "tbb/atomic.h" + +namespace tbb { +namespace internal { + +//------------------------------------------------------------------------ +// Library initialization +//------------------------------------------------------------------------ + +/** Defined in tbb_main.cpp **/ +extern generic_scheduler* (*AllocateSchedulerPtr)( market&, bool ); + +inline generic_scheduler* allocate_scheduler ( market& m, bool genuine ) { + return AllocateSchedulerPtr( m, genuine); +} + +#if __TBB_TASK_GROUP_CONTEXT +context_state_propagation_mutex_type the_context_state_propagation_mutex; + +uintptr_t the_context_state_propagation_epoch = 0; + +//! Context to be associated with dummy tasks of worker threads schedulers. +/** It is never used for its direct purpose, and is introduced solely for the sake + of avoiding one extra conditional branch in the end of wait_for_all method. **/ +static task_group_context the_dummy_context(task_group_context::isolated); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +void Scheduler_OneTimeInitialization ( bool itt_present ) { + AllocateSchedulerPtr = itt_present ? &custom_scheduler<DefaultSchedulerTraits>::allocate_scheduler : + &custom_scheduler<IntelSchedulerTraits>::allocate_scheduler; +#if __TBB_TASK_GROUP_CONTEXT + // There must be no tasks belonging to this fake task group. Mark invalid for the assert + __TBB_ASSERT(!(task_group_context::low_unused_state_bit & (task_group_context::low_unused_state_bit-1)), NULL); + the_dummy_context.my_state = task_group_context::low_unused_state_bit; +#if __TBB_TASK_PRIORITY + // It should never prevent tasks from being passed to execution. + the_dummy_context.my_priority = num_priority_levels - 1; +#endif /* __TBB_TASK_PRIORITY */ +#endif /* __TBB_TASK_GROUP_CONTEXT */ +} + +//------------------------------------------------------------------------ +// scheduler interface +//------------------------------------------------------------------------ + +// A pure virtual destructor should still have a body +// so the one for tbb::internal::scheduler::~scheduler() is provided here +scheduler::~scheduler( ) {} + +//------------------------------------------------------------------------ +// generic_scheduler +//------------------------------------------------------------------------ + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warning about using 'this' in base initializer list. + #pragma warning(push) + #pragma warning(disable:4355) +#endif + +generic_scheduler::generic_scheduler( market& m, bool genuine ) + : my_market(&m) + , my_random(this) + , my_ref_count(1) +#if __TBB_PREVIEW_RESUMABLE_TASKS + , my_co_context(m.worker_stack_size(), genuine ? NULL : this) +#endif + , my_small_task_count(1) // Extra 1 is a guard reference +#if __TBB_SURVIVE_THREAD_SWITCH && TBB_USE_ASSERT + , my_cilk_state(cs_none) +#endif /* __TBB_SURVIVE_THREAD_SWITCH && TBB_USE_ASSERT */ +{ + __TBB_ASSERT( !my_arena_index, "constructor expects the memory being zero-initialized" ); + __TBB_ASSERT( governor::is_set(NULL), "scheduler is already initialized for this thread" ); + + my_innermost_running_task = my_dummy_task = &allocate_task( sizeof(task), __TBB_CONTEXT_ARG(NULL, &the_dummy_context) ); +#if __TBB_PREVIEW_CRITICAL_TASKS + my_properties.has_taken_critical_task = false; +#endif +#if __TBB_PREVIEW_RESUMABLE_TASKS + my_properties.genuine = genuine; + my_current_is_recalled = NULL; + my_post_resume_action = PRA_NONE; + my_post_resume_arg = NULL; + my_wait_task = NULL; +#else + suppress_unused_warning(genuine); +#endif + my_properties.outermost = true; +#if __TBB_TASK_PRIORITY + my_ref_top_priority = &m.my_global_top_priority; + my_ref_reload_epoch = &m.my_global_reload_epoch; +#endif /* __TBB_TASK_PRIORITY */ +#if __TBB_TASK_GROUP_CONTEXT + // Sync up the local cancellation state with the global one. No need for fence here. + my_context_state_propagation_epoch = the_context_state_propagation_epoch; + my_context_list_head.my_prev = &my_context_list_head; + my_context_list_head.my_next = &my_context_list_head; + ITT_SYNC_CREATE(&my_context_list_mutex, SyncType_Scheduler, SyncObj_ContextsList); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + ITT_SYNC_CREATE(&my_dummy_task->prefix().ref_count, SyncType_Scheduler, SyncObj_WorkerLifeCycleMgmt); + ITT_SYNC_CREATE(&my_return_list, SyncType_Scheduler, SyncObj_TaskReturnList); +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif // warning 4355 is back + +#if TBB_USE_ASSERT > 1 +void generic_scheduler::assert_task_pool_valid() const { + if ( !my_arena_slot ) + return; + acquire_task_pool(); + task** tp = my_arena_slot->task_pool_ptr; + if ( my_arena_slot->my_task_pool_size ) + __TBB_ASSERT( my_arena_slot->my_task_pool_size >= min_task_pool_size, NULL ); + const size_t H = __TBB_load_relaxed(my_arena_slot->head); // mirror + const size_t T = __TBB_load_relaxed(my_arena_slot->tail); // mirror + __TBB_ASSERT( H <= T, NULL ); + for ( size_t i = 0; i < H; ++i ) + __TBB_ASSERT( tp[i] == poisoned_ptr, "Task pool corrupted" ); + for ( size_t i = H; i < T; ++i ) { + if ( tp[i] ) { + assert_task_valid( tp[i] ); + __TBB_ASSERT( tp[i]->prefix().state == task::ready || + tp[i]->prefix().extra_state == es_task_proxy, "task in the deque has invalid state" ); + } + } + for ( size_t i = T; i < my_arena_slot->my_task_pool_size; ++i ) + __TBB_ASSERT( tp[i] == poisoned_ptr, "Task pool corrupted" ); + release_task_pool(); +} +#endif /* TBB_USE_ASSERT > 1 */ + +void generic_scheduler::init_stack_info () { + // Stacks are growing top-down. Highest address is called "stack base", + // and the lowest is "stack limit". + __TBB_ASSERT( !my_stealing_threshold, "Stealing threshold has already been calculated" ); + size_t stack_size = my_market->worker_stack_size(); +#if USE_WINTHREAD +#if defined(_MSC_VER)&&_MSC_VER<1400 && !_WIN64 + NT_TIB *pteb; + __asm mov eax, fs:[0x18] + __asm mov pteb, eax +#else + NT_TIB *pteb = (NT_TIB*)NtCurrentTeb(); +#endif + __TBB_ASSERT( &pteb < pteb->StackBase && &pteb > pteb->StackLimit, "invalid stack info in TEB" ); + __TBB_ASSERT( stack_size >0, "stack_size not initialized?" ); + // When a thread is created with the attribute STACK_SIZE_PARAM_IS_A_RESERVATION, stack limit + // in the TIB points to the committed part of the stack only. This renders the expression + // "(uintptr_t)pteb->StackBase / 2 + (uintptr_t)pteb->StackLimit / 2" virtually useless. + // Thus for worker threads we use the explicit stack size we used while creating them. + // And for master threads we rely on the following fact and assumption: + // - the default stack size of a master thread on Windows is 1M; + // - if it was explicitly set by the application it is at least as large as the size of a worker stack. + if ( is_worker() || stack_size < MByte ) + my_stealing_threshold = (uintptr_t)pteb->StackBase - stack_size / 2; + else + my_stealing_threshold = (uintptr_t)pteb->StackBase - MByte / 2; +#else /* USE_PTHREAD */ + // There is no portable way to get stack base address in Posix, so we use + // non-portable method (on all modern Linux) or the simplified approach + // based on the common sense assumptions. The most important assumption + // is that the main thread's stack size is not less than that of other threads. + // See also comment 3 at the end of this file + void *stack_base = &stack_size; +#if __linux__ && !__bg__ +#if __TBB_ipf + void *rsb_base = __TBB_get_bsp(); +#endif + size_t np_stack_size = 0; + // Points to the lowest addressable byte of a stack. + void *stack_limit = NULL; + +#if __TBB_PREVIEW_RESUMABLE_TASKS + if ( !my_properties.genuine ) { + stack_limit = my_co_context.get_stack_limit(); + __TBB_ASSERT( (uintptr_t)stack_base > (uintptr_t)stack_limit, "stack size must be positive" ); + // Size of the stack free part + stack_size = size_t((char*)stack_base - (char*)stack_limit); + } +#endif + + pthread_attr_t np_attr_stack; + if( !stack_limit && 0 == pthread_getattr_np(pthread_self(), &np_attr_stack) ) { + if ( 0 == pthread_attr_getstack(&np_attr_stack, &stack_limit, &np_stack_size) ) { +#if __TBB_ipf + pthread_attr_t attr_stack; + if ( 0 == pthread_attr_init(&attr_stack) ) { + if ( 0 == pthread_attr_getstacksize(&attr_stack, &stack_size) ) { + if ( np_stack_size < stack_size ) { + // We are in a secondary thread. Use reliable data. + // IA-64 architecture stack is split into RSE backup and memory parts + rsb_base = stack_limit; + stack_size = np_stack_size/2; + // Limit of the memory part of the stack + stack_limit = (char*)stack_limit + stack_size; + } + // We are either in the main thread or this thread stack + // is bigger that that of the main one. As we cannot discern + // these cases we fall back to the default (heuristic) values. + } + pthread_attr_destroy(&attr_stack); + } + // IA-64 architecture stack is split into RSE backup and memory parts + my_rsb_stealing_threshold = (uintptr_t)((char*)rsb_base + stack_size/2); +#endif /* __TBB_ipf */ + // TODO: pthread_attr_getstack cannot be used with Intel(R) Cilk(TM) Plus + // __TBB_ASSERT( (uintptr_t)stack_base > (uintptr_t)stack_limit, "stack size must be positive" ); + // Size of the stack free part + stack_size = size_t((char*)stack_base - (char*)stack_limit); + } + pthread_attr_destroy(&np_attr_stack); + } +#endif /* __linux__ */ + __TBB_ASSERT( stack_size>0, "stack size must be positive" ); + my_stealing_threshold = (uintptr_t)((char*)stack_base - stack_size/2); +#endif /* USE_PTHREAD */ +} + +#if __TBB_TASK_GROUP_CONTEXT +/** The function uses synchronization scheme similar to the one in the destructor + of task_group_context augmented with interlocked state change of each context + object. The purpose of this algo is to prevent threads doing nonlocal context + destruction from accessing destroyed owner-scheduler instance still pointed to + by the context object. **/ +void generic_scheduler::cleanup_local_context_list () { + // Detach contexts remaining in the local list + bool wait_for_concurrent_destroyers_to_leave = false; + uintptr_t local_count_snapshot = my_context_state_propagation_epoch; + my_local_ctx_list_update.store<relaxed>(1); + { + // This is just a definition. Actual lock is acquired only in case of conflict. + spin_mutex::scoped_lock lock; + // Full fence prevents reordering of store to my_local_ctx_list_update with + // load from my_nonlocal_ctx_list_update. + atomic_fence(); + // Check for the conflict with concurrent destroyer or cancellation propagator + if ( my_nonlocal_ctx_list_update.load<relaxed>() || local_count_snapshot != the_context_state_propagation_epoch ) + lock.acquire(my_context_list_mutex); + // No acquire fence is necessary for loading my_context_list_head.my_next, + // as the list can be updated by this thread only. + context_list_node_t *node = my_context_list_head.my_next; + while ( node != &my_context_list_head ) { + task_group_context &ctx = __TBB_get_object_ref(task_group_context, my_node, node); + __TBB_ASSERT( __TBB_load_relaxed(ctx.my_kind) != task_group_context::binding_required, "Only a context bound to a root task can be detached" ); + node = node->my_next; + __TBB_ASSERT( is_alive(ctx.my_version_and_traits), "Walked into a destroyed context while detaching contexts from the local list" ); + // Synchronizes with ~task_group_context(). TODO: evaluate and perhaps relax + if ( internal::as_atomic(ctx.my_kind).fetch_and_store(task_group_context::detached) == task_group_context::dying ) + wait_for_concurrent_destroyers_to_leave = true; + } + } + my_local_ctx_list_update.store<release>(0); + // Wait until other threads referencing this scheduler object finish with it + if ( wait_for_concurrent_destroyers_to_leave ) + spin_wait_until_eq( my_nonlocal_ctx_list_update, 0u ); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +void generic_scheduler::destroy() { + __TBB_ASSERT(my_small_task_count == 0, "The scheduler is still in use."); + this->~generic_scheduler(); +#if TBB_USE_DEBUG + memset((void*)this, -1, sizeof(generic_scheduler)); +#endif + NFS_Free(this); +} + +void generic_scheduler::cleanup_scheduler() { + __TBB_ASSERT( !my_arena_slot, NULL ); +#if __TBB_TASK_PRIORITY + __TBB_ASSERT( my_offloaded_tasks == NULL, NULL ); +#endif +#if __TBB_PREVIEW_CRITICAL_TASKS + __TBB_ASSERT( !my_properties.has_taken_critical_task, "Critical tasks miscount." ); +#endif +#if __TBB_TASK_GROUP_CONTEXT + cleanup_local_context_list(); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + free_task<small_local_task>( *my_dummy_task ); + +#if __TBB_HOARD_NONLOCAL_TASKS + while( task* t = my_nonlocal_free_list ) { + task_prefix& p = t->prefix(); + my_nonlocal_free_list = p.next; + __TBB_ASSERT( p.origin && p.origin!=this, NULL ); + free_nonlocal_small_task(*t); + } +#endif + // k accounts for a guard reference and each task that we deallocate. + intptr_t k = 1; + for(;;) { + while( task* t = my_free_list ) { + my_free_list = t->prefix().next; + deallocate_task(*t); + ++k; + } + if( my_return_list==plugged_return_list() ) + break; + my_free_list = (task*)__TBB_FetchAndStoreW( &my_return_list, (intptr_t)plugged_return_list() ); + } +#if __TBB_COUNT_TASK_NODES + my_market->update_task_node_count( my_task_node_count ); +#endif /* __TBB_COUNT_TASK_NODES */ + // Update my_small_task_count last. Doing so sooner might cause another thread to free *this. + __TBB_ASSERT( my_small_task_count>=k, "my_small_task_count corrupted" ); + governor::sign_off(this); + if( __TBB_FetchAndAddW( &my_small_task_count, -k )==k ) + destroy(); +} + +task& generic_scheduler::allocate_task( size_t number_of_bytes, + __TBB_CONTEXT_ARG(task* parent, task_group_context* context) ) { + GATHER_STATISTIC(++my_counters.active_tasks); + task *t; + if( number_of_bytes<=quick_task_size ) { +#if __TBB_HOARD_NONLOCAL_TASKS + if( (t = my_nonlocal_free_list) ) { + GATHER_STATISTIC(--my_counters.free_list_length); + __TBB_ASSERT( t->state()==task::freed, "free list of tasks is corrupted" ); + my_nonlocal_free_list = t->prefix().next; + } else +#endif + if( (t = my_free_list) ) { + GATHER_STATISTIC(--my_counters.free_list_length); + __TBB_ASSERT( t->state()==task::freed, "free list of tasks is corrupted" ); + my_free_list = t->prefix().next; + } else if( my_return_list ) { + // No fence required for read of my_return_list above, because __TBB_FetchAndStoreW has a fence. + t = (task*)__TBB_FetchAndStoreW( &my_return_list, 0 ); // with acquire + __TBB_ASSERT( t, "another thread emptied the my_return_list" ); + __TBB_ASSERT( t->prefix().origin==this, "task returned to wrong my_return_list" ); + ITT_NOTIFY( sync_acquired, &my_return_list ); + my_free_list = t->prefix().next; + } else { + t = (task*)((char*)NFS_Allocate( 1, task_prefix_reservation_size+quick_task_size, NULL ) + task_prefix_reservation_size ); +#if __TBB_COUNT_TASK_NODES + ++my_task_node_count; +#endif /* __TBB_COUNT_TASK_NODES */ + t->prefix().origin = this; + t->prefix().next = 0; + ++my_small_task_count; + } +#if __TBB_PREFETCHING + task *t_next = t->prefix().next; + if( !t_next ) { // the task was last in the list +#if __TBB_HOARD_NONLOCAL_TASKS + if( my_free_list ) + t_next = my_free_list; + else +#endif + if( my_return_list ) // enable prefetching, gives speedup + t_next = my_free_list = (task*)__TBB_FetchAndStoreW( &my_return_list, 0 ); + } + if( t_next ) { // gives speedup for both cache lines + __TBB_cl_prefetch(t_next); + __TBB_cl_prefetch(&t_next->prefix()); + } +#endif /* __TBB_PREFETCHING */ + } else { + GATHER_STATISTIC(++my_counters.big_tasks); + t = (task*)((char*)NFS_Allocate( 1, task_prefix_reservation_size+number_of_bytes, NULL ) + task_prefix_reservation_size ); +#if __TBB_COUNT_TASK_NODES + ++my_task_node_count; +#endif /* __TBB_COUNT_TASK_NODES */ + t->prefix().origin = NULL; + } + task_prefix& p = t->prefix(); +#if __TBB_TASK_GROUP_CONTEXT + p.context = context; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + // Obsolete. But still in use, so has to be assigned correct value here. + p.owner = this; + p.ref_count = 0; + // Obsolete. Assign some not outrageously out-of-place value for a while. + p.depth = 0; + p.parent = parent; + // In TBB 2.1 and later, the constructor for task sets extra_state to indicate the version of the tbb/task.h header. + // In TBB 2.0 and earlier, the constructor leaves extra_state as zero. + p.extra_state = 0; + p.affinity = 0; + p.state = task::allocated; + __TBB_ISOLATION_EXPR( p.isolation = no_isolation ); + return *t; +} + +void generic_scheduler::free_nonlocal_small_task( task& t ) { + __TBB_ASSERT( t.state()==task::freed, NULL ); + generic_scheduler& s = *static_cast<generic_scheduler*>(t.prefix().origin); + __TBB_ASSERT( &s!=this, NULL ); + for(;;) { + task* old = s.my_return_list; + if( old==plugged_return_list() ) + break; + // Atomically insert t at head of s.my_return_list + t.prefix().next = old; + ITT_NOTIFY( sync_releasing, &s.my_return_list ); + if( as_atomic(s.my_return_list).compare_and_swap(&t, old )==old ) { +#if __TBB_PREFETCHING + __TBB_cl_evict(&t.prefix()); + __TBB_cl_evict(&t); +#endif + return; + } + } + deallocate_task(t); + if( __TBB_FetchAndDecrementWrelease( &s.my_small_task_count )==1 ) { + // We freed the last task allocated by scheduler s, so it's our responsibility + // to free the scheduler. + s.destroy(); + } +} + +inline size_t generic_scheduler::prepare_task_pool ( size_t num_tasks ) { + size_t T = __TBB_load_relaxed(my_arena_slot->tail); // mirror + if ( T + num_tasks <= my_arena_slot->my_task_pool_size ) + return T; + + size_t new_size = num_tasks; + + if ( !my_arena_slot->my_task_pool_size ) { + __TBB_ASSERT( !is_task_pool_published() && is_quiescent_local_task_pool_reset(), NULL ); + __TBB_ASSERT( !my_arena_slot->task_pool_ptr, NULL ); + if ( num_tasks < min_task_pool_size ) new_size = min_task_pool_size; + my_arena_slot->allocate_task_pool( new_size ); + return 0; + } + + acquire_task_pool(); + size_t H = __TBB_load_relaxed( my_arena_slot->head ); // mirror + task** task_pool = my_arena_slot->task_pool_ptr;; + __TBB_ASSERT( my_arena_slot->my_task_pool_size >= min_task_pool_size, NULL ); + // Count not skipped tasks. Consider using std::count_if. + for ( size_t i = H; i < T; ++i ) + if ( task_pool[i] ) ++new_size; + // If the free space at the beginning of the task pool is too short, we + // are likely facing a pathological single-producer-multiple-consumers + // scenario, and thus it's better to expand the task pool + bool allocate = new_size > my_arena_slot->my_task_pool_size - min_task_pool_size/4; + if ( allocate ) { + // Grow task pool. As this operation is rare, and its cost is asymptotically + // amortizable, we can tolerate new task pool allocation done under the lock. + if ( new_size < 2 * my_arena_slot->my_task_pool_size ) + new_size = 2 * my_arena_slot->my_task_pool_size; + my_arena_slot->allocate_task_pool( new_size ); // updates my_task_pool_size + } + // Filter out skipped tasks. Consider using std::copy_if. + size_t T1 = 0; + for ( size_t i = H; i < T; ++i ) + if ( task_pool[i] ) + my_arena_slot->task_pool_ptr[T1++] = task_pool[i]; + // Deallocate the previous task pool if a new one has been allocated. + if ( allocate ) + NFS_Free( task_pool ); + else + my_arena_slot->fill_with_canary_pattern( T1, my_arena_slot->tail ); + // Publish the new state. + commit_relocated_tasks( T1 ); + assert_task_pool_valid(); + return T1; +} + +/** ATTENTION: + This method is mostly the same as generic_scheduler::lock_task_pool(), with + a little different logic of slot state checks (slot is either locked or points + to our task pool). + Thus if either of them is changed, consider changing the counterpart as well. **/ +inline void generic_scheduler::acquire_task_pool() const { + if ( !is_task_pool_published() ) + return; // we are not in arena - nothing to lock + bool sync_prepare_done = false; + for( atomic_backoff b;;b.pause() ) { +#if TBB_USE_ASSERT + __TBB_ASSERT( my_arena_slot == my_arena->my_slots + my_arena_index, "invalid arena slot index" ); + // Local copy of the arena slot task pool pointer is necessary for the next + // assertion to work correctly to exclude asynchronous state transition effect. + task** tp = my_arena_slot->task_pool; + __TBB_ASSERT( tp == LockedTaskPool || tp == my_arena_slot->task_pool_ptr, "slot ownership corrupt?" ); +#endif + if( my_arena_slot->task_pool != LockedTaskPool && + as_atomic(my_arena_slot->task_pool).compare_and_swap(LockedTaskPool, my_arena_slot->task_pool_ptr ) == my_arena_slot->task_pool_ptr ) + { + // We acquired our own slot + ITT_NOTIFY(sync_acquired, my_arena_slot); + break; + } + else if( !sync_prepare_done ) { + // Start waiting + ITT_NOTIFY(sync_prepare, my_arena_slot); + sync_prepare_done = true; + } + // Someone else acquired a lock, so pause and do exponential backoff. + } + __TBB_ASSERT( my_arena_slot->task_pool == LockedTaskPool, "not really acquired task pool" ); +} // generic_scheduler::acquire_task_pool + +inline void generic_scheduler::release_task_pool() const { + if ( !is_task_pool_published() ) + return; // we are not in arena - nothing to unlock + __TBB_ASSERT( my_arena_slot, "we are not in arena" ); + __TBB_ASSERT( my_arena_slot->task_pool == LockedTaskPool, "arena slot is not locked" ); + ITT_NOTIFY(sync_releasing, my_arena_slot); + __TBB_store_with_release( my_arena_slot->task_pool, my_arena_slot->task_pool_ptr ); +} + +/** ATTENTION: + This method is mostly the same as generic_scheduler::acquire_task_pool(), + with a little different logic of slot state checks (slot can be empty, locked + or point to any task pool other than ours, and asynchronous transitions between + all these states are possible). + Thus if any of them is changed, consider changing the counterpart as well **/ +inline task** generic_scheduler::lock_task_pool( arena_slot* victim_arena_slot ) const { + task** victim_task_pool; + bool sync_prepare_done = false; + for( atomic_backoff backoff;; /*backoff pause embedded in the loop*/) { + victim_task_pool = victim_arena_slot->task_pool; + // NOTE: Do not use comparison of head and tail indices to check for + // the presence of work in the victim's task pool, as they may give + // incorrect indication because of task pool relocations and resizes. + if ( victim_task_pool == EmptyTaskPool ) { + // The victim thread emptied its task pool - nothing to lock + if( sync_prepare_done ) + ITT_NOTIFY(sync_cancel, victim_arena_slot); + break; + } + if( victim_task_pool != LockedTaskPool && + as_atomic(victim_arena_slot->task_pool).compare_and_swap(LockedTaskPool, victim_task_pool ) == victim_task_pool ) + { + // We've locked victim's task pool + ITT_NOTIFY(sync_acquired, victim_arena_slot); + break; + } + else if( !sync_prepare_done ) { + // Start waiting + ITT_NOTIFY(sync_prepare, victim_arena_slot); + sync_prepare_done = true; + } + GATHER_STATISTIC( ++my_counters.thieves_conflicts ); + // Someone else acquired a lock, so pause and do exponential backoff. +#if __TBB_STEALING_ABORT_ON_CONTENTION + if(!backoff.bounded_pause()) { + // the 16 was acquired empirically and a theory behind it supposes + // that number of threads becomes much bigger than number of + // tasks which can be spawned by one thread causing excessive contention. + // TODO: However even small arenas can benefit from the abort on contention + // if preemption of a thief is a problem + if(my_arena->my_limit >= 16) + return EmptyTaskPool; + __TBB_Yield(); + } +#else + backoff.pause(); +#endif + } + __TBB_ASSERT( victim_task_pool == EmptyTaskPool || + (victim_arena_slot->task_pool == LockedTaskPool && victim_task_pool != LockedTaskPool), + "not really locked victim's task pool?" ); + return victim_task_pool; +} // generic_scheduler::lock_task_pool + +inline void generic_scheduler::unlock_task_pool( arena_slot* victim_arena_slot, + task** victim_task_pool ) const { + __TBB_ASSERT( victim_arena_slot, "empty victim arena slot pointer" ); + __TBB_ASSERT( victim_arena_slot->task_pool == LockedTaskPool, "victim arena slot is not locked" ); + ITT_NOTIFY(sync_releasing, victim_arena_slot); + __TBB_store_with_release( victim_arena_slot->task_pool, victim_task_pool ); +} + + +inline task* generic_scheduler::prepare_for_spawning( task* t ) { + __TBB_ASSERT( t->state()==task::allocated, "attempt to spawn task that is not in 'allocated' state" ); + t->prefix().state = task::ready; +#if TBB_USE_ASSERT + if( task* parent = t->parent() ) { + internal::reference_count ref_count = parent->prefix().ref_count; + __TBB_ASSERT( ref_count>=0, "attempt to spawn task whose parent has a ref_count<0" ); + __TBB_ASSERT( ref_count!=0, "attempt to spawn task whose parent has a ref_count==0 (forgot to set_ref_count?)" ); + parent->prefix().extra_state |= es_ref_count_active; + } +#endif /* TBB_USE_ASSERT */ + affinity_id dst_thread = t->prefix().affinity; + __TBB_ASSERT( dst_thread == 0 || is_version_3_task(*t), + "backwards compatibility to TBB 2.0 tasks is broken" ); +#if __TBB_TASK_ISOLATION + isolation_tag isolation = my_innermost_running_task->prefix().isolation; + t->prefix().isolation = isolation; +#endif /* __TBB_TASK_ISOLATION */ + if( dst_thread != 0 && dst_thread != my_affinity_id ) { + task_proxy& proxy = (task_proxy&)allocate_task( sizeof(task_proxy), + __TBB_CONTEXT_ARG(NULL, NULL) ); + // Mark as a proxy + proxy.prefix().extra_state = es_task_proxy; + proxy.outbox = &my_arena->mailbox(dst_thread); + // Mark proxy as present in both locations (sender's task pool and destination mailbox) + proxy.task_and_tag = intptr_t(t) | task_proxy::location_mask; +#if __TBB_TASK_PRIORITY + poison_pointer( proxy.prefix().context ); +#endif /* __TBB_TASK_PRIORITY */ + __TBB_ISOLATION_EXPR( proxy.prefix().isolation = isolation ); + ITT_NOTIFY( sync_releasing, proxy.outbox ); + // Mail the proxy, if success, it may be destroyed by another thread at any moment after this point. + if ( proxy.outbox->push(&proxy) ) + return &proxy; + // The mailbox is overfilled, deallocate the proxy and return the initial task. + free_task<small_task>(proxy); + } + return t; +} + +#if __TBB_PREVIEW_CRITICAL_TASKS +bool generic_scheduler::handled_as_critical( task& t ) { + if( !internal::is_critical( t ) ) + return false; +#if __TBB_TASK_ISOLATION + t.prefix().isolation = my_innermost_running_task->prefix().isolation; +#endif + ITT_NOTIFY(sync_releasing, &my_arena->my_critical_task_stream); + __TBB_ASSERT( my_arena, "Must be attached to the arena." ); + __TBB_ASSERT( my_arena_slot, "Must occupy a slot in the attached arena" ); + my_arena->my_critical_task_stream.push( + &t, 0, tbb::internal::subsequent_lane_selector(my_arena_slot->hint_for_critical) ); + return true; +} +#endif /* __TBB_PREVIEW_CRITICAL_TASKS */ + +/** Conceptually, this method should be a member of class scheduler. + But doing so would force us to publish class scheduler in the headers. */ +void generic_scheduler::local_spawn( task* first, task*& next ) { + __TBB_ASSERT( first, NULL ); + __TBB_ASSERT( governor::is_set(this), NULL ); +#if __TBB_TODO + // We need to consider capping the max task pool size and switching + // to in-place task execution whenever it is reached. +#endif + if ( &first->prefix().next == &next ) { + // Single task is being spawned +#if __TBB_TODO + // TODO: + // In the future we need to add overloaded spawn method for a single task, + // and a method accepting an array of task pointers (we may also want to + // change the implementation of the task_list class). But since such changes + // may affect the binary compatibility, we postpone them for a while. +#endif +#if __TBB_PREVIEW_CRITICAL_TASKS + if( !handled_as_critical( *first ) ) +#endif + { + size_t T = prepare_task_pool( 1 ); + my_arena_slot->task_pool_ptr[T] = prepare_for_spawning( first ); + commit_spawned_tasks( T + 1 ); + if ( !is_task_pool_published() ) + publish_task_pool(); + } + } + else { + // Task list is being spawned +#if __TBB_TODO + // TODO: add task_list::front() and implement&document the local execution ordering which is + // opposite to the current implementation. The idea is to remove hackish fast_reverse_vector + // and use push_back/push_front when accordingly LIFO and FIFO order of local execution is + // desired. It also requires refactoring of the reload_tasks method and my_offloaded_tasks list. + // Additional benefit may come from adding counter to the task_list so that it can reserve enough + // space in the task pool in advance and move all the tasks directly without any intermediate + // storages. But it requires dealing with backward compatibility issues and still supporting + // counter-less variant (though not necessarily fast implementation). +#endif + task *arr[min_task_pool_size]; + fast_reverse_vector<task*> tasks(arr, min_task_pool_size); + task *t_next = NULL; + for( task* t = first; ; t = t_next ) { + // If t is affinitized to another thread, it may already be executed + // and destroyed by the time prepare_for_spawning returns. + // So milk it while it is alive. + bool end = &t->prefix().next == &next; + t_next = t->prefix().next; +#if __TBB_PREVIEW_CRITICAL_TASKS + if( !handled_as_critical( *t ) ) +#endif + tasks.push_back( prepare_for_spawning(t) ); + if( end ) + break; + } + if( size_t num_tasks = tasks.size() ) { + size_t T = prepare_task_pool( num_tasks ); + tasks.copy_memory( my_arena_slot->task_pool_ptr + T ); + commit_spawned_tasks( T + num_tasks ); + if ( !is_task_pool_published() ) + publish_task_pool(); + } + } + my_arena->advertise_new_work<arena::work_spawned>(); + assert_task_pool_valid(); +} + +void generic_scheduler::local_spawn_root_and_wait( task* first, task*& next ) { + __TBB_ASSERT( governor::is_set(this), NULL ); + __TBB_ASSERT( first, NULL ); + auto_empty_task dummy( __TBB_CONTEXT_ARG(this, first->prefix().context) ); + internal::reference_count n = 0; + for( task* t=first; ; t=t->prefix().next ) { + ++n; + __TBB_ASSERT( !t->prefix().parent, "not a root task, or already running" ); + t->prefix().parent = &dummy; + if( &t->prefix().next==&next ) break; +#if __TBB_TASK_GROUP_CONTEXT + __TBB_ASSERT( t->prefix().context == t->prefix().next->prefix().context, + "all the root tasks in list must share the same context"); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + } + dummy.prefix().ref_count = n+1; + if( n>1 ) + local_spawn( first->prefix().next, next ); + local_wait_for_all( dummy, first ); +} + +void tbb::internal::generic_scheduler::spawn( task& first, task*& next ) { + governor::local_scheduler()->local_spawn( &first, next ); +} + +void tbb::internal::generic_scheduler::spawn_root_and_wait( task& first, task*& next ) { + governor::local_scheduler()->local_spawn_root_and_wait( &first, next ); +} + +void tbb::internal::generic_scheduler::enqueue( task& t, void* prio ) { + generic_scheduler *s = governor::local_scheduler(); + // these redirections are due to bw-compatibility, consider reworking some day + __TBB_ASSERT( s->my_arena, "thread is not in any arena" ); + s->my_arena->enqueue_task(t, (intptr_t)prio, s->my_random ); +} + +#if __TBB_TASK_PRIORITY +class auto_indicator : no_copy { + volatile bool& my_indicator; +public: + auto_indicator ( volatile bool& indicator ) : my_indicator(indicator) { my_indicator = true ;} + ~auto_indicator () { my_indicator = false; } +}; + +task *generic_scheduler::get_task_and_activate_task_pool( size_t H0, __TBB_ISOLATION_ARG( size_t T0, isolation_tag isolation ) ) { + __TBB_ASSERT( is_local_task_pool_quiescent(), NULL ); + + // Go through the task pool to find an available task for execution. + task *t = NULL; +#if __TBB_TASK_ISOLATION + size_t T = T0; + bool tasks_omitted = false; + while ( !t && T>H0 ) { + t = get_task( --T, isolation, tasks_omitted ); + if ( !tasks_omitted ) { + poison_pointer( my_arena_slot->task_pool_ptr[T] ); + --T0; + } + } + // Make a hole if some tasks have been skipped. + if ( t && tasks_omitted ) { + my_arena_slot->task_pool_ptr[T] = NULL; + if ( T == H0 ) { + // The obtained task is on the head. So we can move the head instead of making a hole. + ++H0; + poison_pointer( my_arena_slot->task_pool_ptr[T] ); + } + } +#else + while ( !t && T0 ) { + t = get_task( --T0 ); + poison_pointer( my_arena_slot->task_pool_ptr[T0] ); + } +#endif /* __TBB_TASK_ISOLATION */ + + if ( H0 < T0 ) { + // There are some tasks in the task pool. Publish them. + __TBB_store_relaxed( my_arena_slot->head, H0 ); + __TBB_store_relaxed( my_arena_slot->tail, T0 ); + if ( is_task_pool_published() ) + release_task_pool(); + else + publish_task_pool(); + } else { + __TBB_store_relaxed( my_arena_slot->head, 0 ); + __TBB_store_relaxed( my_arena_slot->tail, 0 ); + if ( is_task_pool_published() ) + leave_task_pool(); + } + +#if __TBB_TASK_ISOLATION + // Now it is safe to call note_affinity because the task pool is restored. + if ( tasks_omitted && my_innermost_running_task == t ) { + assert_task_valid( t ); + t->note_affinity( my_affinity_id ); + } +#endif /* __TBB_TASK_ISOLATION */ + + assert_task_pool_valid(); + return t; +} + +task* generic_scheduler::winnow_task_pool( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ) { + GATHER_STATISTIC( ++my_counters.prio_winnowings ); + __TBB_ASSERT( is_task_pool_published(), NULL ); + __TBB_ASSERT( my_offloaded_tasks, "At least one task is expected to be already offloaded" ); + // To eliminate possible sinking of the store to the indicator below the subsequent + // store to my_arena_slot->tail, the stores should have either been separated + // by full fence or both use release fences. And resetting indicator should have + // been done with release fence. But since this is just an optimization, and + // the corresponding checking sequence in arena::is_out_of_work() is not atomic + // anyway, fences aren't used, so that not to penalize warmer path. + auto_indicator indicator( my_pool_reshuffling_pending ); + + // Locking the task pool unconditionally produces simpler code, + // scalability of which should not suffer unless priority jitter takes place. + // TODO: consider the synchronization algorithm here is for the owner thread + // to avoid locking task pool most of the time. + acquire_task_pool(); + size_t T0 = __TBB_load_relaxed( my_arena_slot->tail ); + size_t H0 = __TBB_load_relaxed( my_arena_slot->head ); + size_t T1 = 0; + for ( size_t src = H0; src<T0; ++src ) { + if ( task *t = my_arena_slot->task_pool_ptr[src] ) { + // We cannot offload a proxy task (check the priority of it) because it can be already consumed. + if ( !is_proxy( *t ) ) { + intptr_t p = priority( *t ); + if ( p<*my_ref_top_priority ) { + offload_task( *t, p ); + continue; + } + } + my_arena_slot->task_pool_ptr[T1++] = t; + } + } + __TBB_ASSERT( T1<=T0, NULL ); + + // Choose max(T1, H0) because ranges [0, T1) and [H0, T0) can overlap. + my_arena_slot->fill_with_canary_pattern( max( T1, H0 ), T0 ); + return get_task_and_activate_task_pool( 0, __TBB_ISOLATION_ARG( T1, isolation ) ); +} + +task* generic_scheduler::reload_tasks ( task*& offloaded_tasks, task**& offloaded_task_list_link, __TBB_ISOLATION_ARG( intptr_t top_priority, isolation_tag isolation ) ) { + GATHER_STATISTIC( ++my_counters.prio_reloads ); +#if __TBB_TASK_ISOLATION + // In many cases, locking the task pool is no-op here because the task pool is in the empty + // state. However, isolation allows entering stealing loop with non-empty task pool. + // In principle, it is possible to process reloaded tasks without locking but it will + // complicate the logic of get_task_and_activate_task_pool (TODO: evaluate). + acquire_task_pool(); +#else + __TBB_ASSERT( !is_task_pool_published(), NULL ); +#endif + task *arr[min_task_pool_size]; + fast_reverse_vector<task*> tasks(arr, min_task_pool_size); + task **link = &offloaded_tasks; + while ( task *t = *link ) { + task** next_ptr = &t->prefix().next_offloaded; + __TBB_ASSERT( !is_proxy(*t), "The proxy tasks cannot be offloaded" ); + if ( priority(*t) >= top_priority ) { + tasks.push_back( t ); + // Note that owner is an alias of next_offloaded. Thus the following + // assignment overwrites *next_ptr + task* next = *next_ptr; + t->prefix().owner = this; + __TBB_ASSERT( t->prefix().state == task::ready, NULL ); + *link = next; + } + else { + link = next_ptr; + } + } + if ( link == &offloaded_tasks ) { + offloaded_tasks = NULL; +#if TBB_USE_ASSERT + offloaded_task_list_link = NULL; +#endif /* TBB_USE_ASSERT */ + } + else { + __TBB_ASSERT( link, NULL ); + // Mark end of list + *link = NULL; + offloaded_task_list_link = link; + } + __TBB_ASSERT( link, NULL ); + size_t num_tasks = tasks.size(); + if ( !num_tasks ) { + __TBB_ISOLATION_EXPR( release_task_pool() ); + return NULL; + } + + // Copy found tasks into the task pool. + GATHER_STATISTIC( ++my_counters.prio_tasks_reloaded ); + size_t T = prepare_task_pool( num_tasks ); + tasks.copy_memory( my_arena_slot->task_pool_ptr + T ); + + // Find a task available for execution. + task *t = get_task_and_activate_task_pool( __TBB_load_relaxed( my_arena_slot->head ), __TBB_ISOLATION_ARG( T + num_tasks, isolation ) ); + if ( t ) --num_tasks; + if ( num_tasks ) + my_arena->advertise_new_work<arena::work_spawned>(); + + return t; +} + +task* generic_scheduler::reload_tasks( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ) { + uintptr_t reload_epoch = *my_ref_reload_epoch; + __TBB_ASSERT( my_offloaded_tasks, NULL ); + __TBB_ASSERT( my_local_reload_epoch <= reload_epoch + || my_local_reload_epoch - reload_epoch > uintptr_t(-1)/2, + "Reload epoch counter overflow?" ); + if ( my_local_reload_epoch == reload_epoch ) + return NULL; + __TBB_ASSERT( my_offloaded_tasks, NULL ); + intptr_t top_priority = effective_reference_priority(); + __TBB_ASSERT( (uintptr_t)top_priority < (uintptr_t)num_priority_levels, NULL ); + task *t = reload_tasks( my_offloaded_tasks, my_offloaded_task_list_tail_link, __TBB_ISOLATION_ARG( top_priority, isolation ) ); + if ( my_offloaded_tasks && (my_arena->my_bottom_priority >= top_priority || !my_arena->my_num_workers_requested) ) { + // Safeguard against deliberately relaxed synchronization while checking + // for the presence of work in arena (so that not to impact hot paths). + // Arena may be reset to empty state when offloaded low priority tasks + // are still present. This results in both bottom and top priority bounds + // becoming 'normal', which makes offloaded low priority tasks unreachable. + // Update arena's bottom priority to accommodate them. + // NOTE: If the number of priority levels is increased, we may want + // to calculate minimum of priorities in my_offloaded_tasks. + + // First indicate the presence of lower-priority tasks + my_market->update_arena_priority( *my_arena, priority(*my_offloaded_tasks) ); + // Then mark arena as full to unlock arena priority level adjustment + // by arena::is_out_of_work(), and ensure worker's presence + my_arena->advertise_new_work<arena::wakeup>(); + } + my_local_reload_epoch = reload_epoch; + return t; +} +#endif /* __TBB_TASK_PRIORITY */ + +#if __TBB_TASK_ISOLATION +inline task* generic_scheduler::get_task( size_t T, isolation_tag isolation, bool& tasks_omitted ) +#else +inline task* generic_scheduler::get_task( size_t T ) +#endif /* __TBB_TASK_ISOLATION */ +{ + __TBB_ASSERT( __TBB_load_relaxed( my_arena_slot->tail ) <= T + || is_local_task_pool_quiescent(), "Is it safe to get a task at position T?" ); + + task* result = my_arena_slot->task_pool_ptr[T]; + __TBB_ASSERT( !is_poisoned( result ), "The poisoned task is going to be processed" ); +#if __TBB_TASK_ISOLATION + if ( !result ) + return NULL; + + bool omit = isolation != no_isolation && isolation != result->prefix().isolation; + if ( !omit && !is_proxy( *result ) ) + return result; + else if ( omit ) { + tasks_omitted = true; + return NULL; + } +#else + poison_pointer( my_arena_slot->task_pool_ptr[T] ); + if ( !result || !is_proxy( *result ) ) + return result; +#endif /* __TBB_TASK_ISOLATION */ + + task_proxy& tp = static_cast<task_proxy&>(*result); + if ( task *t = tp.extract_task<task_proxy::pool_bit>() ) { + GATHER_STATISTIC( ++my_counters.proxies_executed ); + // Following assertion should be true because TBB 2.0 tasks never specify affinity, and hence are not proxied. + __TBB_ASSERT( is_version_3_task( *t ), "backwards compatibility with TBB 2.0 broken" ); + my_innermost_running_task = t; // prepare for calling note_affinity() +#if __TBB_TASK_ISOLATION + // Task affinity has changed. Postpone calling note_affinity because the task pool is in invalid state. + if ( !tasks_omitted ) +#endif /* __TBB_TASK_ISOLATION */ + { + poison_pointer( my_arena_slot->task_pool_ptr[T] ); + t->note_affinity( my_affinity_id ); + } + return t; + } + + // Proxy was empty, so it's our responsibility to free it + free_task<small_task>( tp ); +#if __TBB_TASK_ISOLATION + if ( tasks_omitted ) + my_arena_slot->task_pool_ptr[T] = NULL; +#endif /* __TBB_TASK_ISOLATION */ + return NULL; +} + +inline task* generic_scheduler::get_task( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ) { + __TBB_ASSERT( is_task_pool_published(), NULL ); + // The current task position in the task pool. + size_t T0 = __TBB_load_relaxed( my_arena_slot->tail ); + // The bounds of available tasks in the task pool. H0 is only used when the head bound is reached. + size_t H0 = (size_t)-1, T = T0; + task* result = NULL; + bool task_pool_empty = false; + __TBB_ISOLATION_EXPR( bool tasks_omitted = false ); + do { + __TBB_ASSERT( !result, NULL ); + __TBB_store_relaxed( my_arena_slot->tail, --T ); + atomic_fence(); + if ( (intptr_t)__TBB_load_relaxed( my_arena_slot->head ) > (intptr_t)T ) { + acquire_task_pool(); + H0 = __TBB_load_relaxed( my_arena_slot->head ); + if ( (intptr_t)H0 > (intptr_t)T ) { + // The thief has not backed off - nothing to grab. + __TBB_ASSERT( H0 == __TBB_load_relaxed( my_arena_slot->head ) + && T == __TBB_load_relaxed( my_arena_slot->tail ) + && H0 == T + 1, "victim/thief arbitration algorithm failure" ); + reset_task_pool_and_leave(); + // No tasks in the task pool. + task_pool_empty = true; + break; + } else if ( H0 == T ) { + // There is only one task in the task pool. + reset_task_pool_and_leave(); + task_pool_empty = true; + } else { + // Release task pool if there are still some tasks. + // After the release, the tail will be less than T, thus a thief + // will not attempt to get a task at position T. + release_task_pool(); + } + } + __TBB_control_consistency_helper(); // on my_arena_slot->head +#if __TBB_TASK_ISOLATION + result = get_task( T, isolation, tasks_omitted ); + if ( result ) { + poison_pointer( my_arena_slot->task_pool_ptr[T] ); + break; + } else if ( !tasks_omitted ) { + poison_pointer( my_arena_slot->task_pool_ptr[T] ); + __TBB_ASSERT( T0 == T+1, NULL ); + T0 = T; + } +#else + result = get_task( T ); +#endif /* __TBB_TASK_ISOLATION */ + } while ( !result && !task_pool_empty ); + +#if __TBB_TASK_ISOLATION + if ( tasks_omitted ) { + if ( task_pool_empty ) { + // All tasks have been checked. The task pool should be in reset state. + // We just restore the bounds for the available tasks. + // TODO: Does it have sense to move them to the beginning of the task pool? + __TBB_ASSERT( is_quiescent_local_task_pool_reset(), NULL ); + if ( result ) { + // If we have a task, it should be at H0 position. + __TBB_ASSERT( H0 == T, NULL ); + ++H0; + } + __TBB_ASSERT( H0 <= T0, NULL ); + if ( H0 < T0 ) { + // Restore the task pool if there are some tasks. + __TBB_store_relaxed( my_arena_slot->head, H0 ); + __TBB_store_relaxed( my_arena_slot->tail, T0 ); + // The release fence is used in publish_task_pool. + publish_task_pool(); + // Synchronize with snapshot as we published some tasks. + my_arena->advertise_new_work<arena::wakeup>(); + } + } else { + // A task has been obtained. We need to make a hole in position T. + __TBB_ASSERT( is_task_pool_published(), NULL ); + __TBB_ASSERT( result, NULL ); + my_arena_slot->task_pool_ptr[T] = NULL; + __TBB_store_with_release( my_arena_slot->tail, T0 ); + // Synchronize with snapshot as we published some tasks. + // TODO: consider some approach not to call wakeup for each time. E.g. check if the tail reached the head. + my_arena->advertise_new_work<arena::wakeup>(); + } + + // Now it is safe to call note_affinity because the task pool is restored. + if ( my_innermost_running_task == result ) { + assert_task_valid( result ); + result->note_affinity( my_affinity_id ); + } + } +#endif /* __TBB_TASK_ISOLATION */ + __TBB_ASSERT( (intptr_t)__TBB_load_relaxed( my_arena_slot->tail ) >= 0, NULL ); + __TBB_ASSERT( result || __TBB_ISOLATION_EXPR( tasks_omitted || ) is_quiescent_local_task_pool_reset(), NULL ); + return result; +} // generic_scheduler::get_task + +task* generic_scheduler::steal_task( __TBB_ISOLATION_EXPR(isolation_tag isolation) ) { + // Try to steal a task from a random victim. + size_t k = my_random.get() % (my_arena->my_limit-1); + arena_slot* victim = &my_arena->my_slots[k]; + // The following condition excludes the master that might have + // already taken our previous place in the arena from the list . + // of potential victims. But since such a situation can take + // place only in case of significant oversubscription, keeping + // the checks simple seems to be preferable to complicating the code. + if( k >= my_arena_index ) + ++victim; // Adjusts random distribution to exclude self + task **pool = victim->task_pool; + task *t = NULL; + if( pool == EmptyTaskPool || !(t = steal_task_from( __TBB_ISOLATION_ARG(*victim, isolation) )) ) + return NULL; + if( is_proxy(*t) ) { + task_proxy &tp = *(task_proxy*)t; + t = tp.extract_task<task_proxy::pool_bit>(); + if ( !t ) { + // Proxy was empty, so it's our responsibility to free it + free_task<no_cache_small_task>(tp); + return NULL; + } + GATHER_STATISTIC( ++my_counters.proxies_stolen ); + } + t->prefix().extra_state |= es_task_is_stolen; + if( is_version_3_task(*t) ) { + my_innermost_running_task = t; + t->prefix().owner = this; + t->note_affinity( my_affinity_id ); + } + GATHER_STATISTIC( ++my_counters.steals_committed ); + return t; +} + +task* generic_scheduler::steal_task_from( __TBB_ISOLATION_ARG( arena_slot& victim_slot, isolation_tag isolation ) ) { + task** victim_pool = lock_task_pool( &victim_slot ); + if ( !victim_pool ) + return NULL; + task* result = NULL; + size_t H = __TBB_load_relaxed(victim_slot.head); // mirror + size_t H0 = H; + bool tasks_omitted = false; + do { + __TBB_store_relaxed( victim_slot.head, ++H ); + atomic_fence(); + if ( (intptr_t)H > (intptr_t)__TBB_load_relaxed( victim_slot.tail ) ) { + // Stealing attempt failed, deque contents has not been changed by us + GATHER_STATISTIC( ++my_counters.thief_backoffs ); + __TBB_store_relaxed( victim_slot.head, /*dead: H = */ H0 ); + __TBB_ASSERT( !result, NULL ); + goto unlock; + } + __TBB_control_consistency_helper(); // on victim_slot.tail + result = victim_pool[H-1]; + __TBB_ASSERT( !is_poisoned( result ), NULL ); + + if ( result ) { + __TBB_ISOLATION_EXPR( if ( isolation == no_isolation || isolation == result->prefix().isolation ) ) + { + if ( !is_proxy( *result ) ) + break; + task_proxy& tp = *static_cast<task_proxy*>(result); + // If mailed task is likely to be grabbed by its destination thread, skip it. + if ( !(task_proxy::is_shared( tp.task_and_tag ) && tp.outbox->recipient_is_idle()) ) + break; + GATHER_STATISTIC( ++my_counters.proxies_bypassed ); + } + // The task cannot be executed either due to isolation or proxy constraints. + result = NULL; + tasks_omitted = true; + } else if ( !tasks_omitted ) { + // Cleanup the task pool from holes until a task is skipped. + __TBB_ASSERT( H0 == H-1, NULL ); + poison_pointer( victim_pool[H0] ); + H0 = H; + } + } while ( !result ); + __TBB_ASSERT( result, NULL ); + + // emit "task was consumed" signal + ITT_NOTIFY( sync_acquired, (void*)((uintptr_t)&victim_slot+sizeof( uintptr_t )) ); + poison_pointer( victim_pool[H-1] ); + if ( tasks_omitted ) { + // Some proxies in the task pool have been omitted. Set the stolen task to NULL. + victim_pool[H-1] = NULL; + __TBB_store_relaxed( victim_slot.head, /*dead: H = */ H0 ); + } +unlock: + unlock_task_pool( &victim_slot, victim_pool ); +#if __TBB_PREFETCHING + __TBB_cl_evict(&victim_slot.head); + __TBB_cl_evict(&victim_slot.tail); +#endif + if ( tasks_omitted ) + // Synchronize with snapshot as the head and tail can be bumped which can falsely trigger EMPTY state + my_arena->advertise_new_work<arena::wakeup>(); + return result; +} + +#if __TBB_PREVIEW_CRITICAL_TASKS +// Retrieves critical task respecting isolation level, if provided. The rule is: +// 1) If no outer critical task and no isolation => take any critical task +// 2) If working on an outer critical task and no isolation => cannot take any critical task +// 3) If no outer critical task but isolated => respect isolation +// 4) If working on an outer critical task and isolated => respect isolation +task* generic_scheduler::get_critical_task( __TBB_ISOLATION_EXPR(isolation_tag isolation) ) { + __TBB_ASSERT( my_arena && my_arena_slot, "Must be attached to arena" ); + if( my_arena->my_critical_task_stream.empty(0) ) + return NULL; + task* critical_task = NULL; + // To keep some LIFO-ness, start search with the lane that was used during push operation. + unsigned& start_lane = my_arena_slot->hint_for_critical; +#if __TBB_TASK_ISOLATION + if( isolation != no_isolation ) { + critical_task = my_arena->my_critical_task_stream.pop_specific( 0, start_lane, isolation ); + } else +#endif + if( !my_properties.has_taken_critical_task ) { + critical_task = my_arena->my_critical_task_stream.pop( 0, preceding_lane_selector(start_lane) ); + } + return critical_task; +} +#endif + +task* generic_scheduler::get_mailbox_task( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ) { + __TBB_ASSERT( my_affinity_id>0, "not in arena" ); + while ( task_proxy* const tp = my_inbox.pop( __TBB_ISOLATION_EXPR( isolation ) ) ) { + if ( task* result = tp->extract_task<task_proxy::mailbox_bit>() ) { + ITT_NOTIFY( sync_acquired, my_inbox.outbox() ); + result->prefix().extra_state |= es_task_is_stolen; + return result; + } + // We have exclusive access to the proxy, and can destroy it. + free_task<no_cache_small_task>(*tp); + } + return NULL; +} + +inline void generic_scheduler::publish_task_pool() { + __TBB_ASSERT ( my_arena, "no arena: initialization not completed?" ); + __TBB_ASSERT ( my_arena_index < my_arena->my_num_slots, "arena slot index is out-of-bound" ); + __TBB_ASSERT ( my_arena_slot == &my_arena->my_slots[my_arena_index], NULL); + __TBB_ASSERT ( my_arena_slot->task_pool == EmptyTaskPool, "someone else grabbed my arena slot?" ); + __TBB_ASSERT ( __TBB_load_relaxed(my_arena_slot->head) < __TBB_load_relaxed(my_arena_slot->tail), + "entering arena without tasks to share" ); + // Release signal on behalf of previously spawned tasks (when this thread was not in arena yet) + ITT_NOTIFY(sync_releasing, my_arena_slot); + __TBB_store_with_release( my_arena_slot->task_pool, my_arena_slot->task_pool_ptr ); +} + +inline void generic_scheduler::leave_task_pool() { + __TBB_ASSERT( is_task_pool_published(), "Not in arena" ); + // Do not reset my_arena_index. It will be used to (attempt to) re-acquire the slot next time + __TBB_ASSERT( &my_arena->my_slots[my_arena_index] == my_arena_slot, "arena slot and slot index mismatch" ); + __TBB_ASSERT ( my_arena_slot->task_pool == LockedTaskPool, "Task pool must be locked when leaving arena" ); + __TBB_ASSERT ( is_quiescent_local_task_pool_empty(), "Cannot leave arena when the task pool is not empty" ); + ITT_NOTIFY(sync_releasing, &my_arena->my_slots[my_arena_index]); + // No release fence is necessary here as this assignment precludes external + // accesses to the local task pool when becomes visible. Thus it is harmless + // if it gets hoisted above preceding local bookkeeping manipulations. + __TBB_store_relaxed( my_arena_slot->task_pool, EmptyTaskPool ); +} + +generic_scheduler* generic_scheduler::create_worker( market& m, size_t index, bool genuine ) { + generic_scheduler* s = allocate_scheduler( m, genuine ); + __TBB_ASSERT(!genuine || index, "workers should have index > 0"); + s->my_arena_index = index; // index is not a real slot in arena yet + s->my_dummy_task->prefix().ref_count = 2; + s->my_properties.type = scheduler_properties::worker; + // Do not call init_stack_info before the scheduler is set as master or worker. + if (genuine) + s->init_stack_info(); + governor::sign_on(s); + return s; +} + +// TODO: make it a member method +generic_scheduler* generic_scheduler::create_master( arena* a ) { + // add an internal market reference; the public reference is possibly added in create_arena + generic_scheduler* s = allocate_scheduler( market::global_market(/*is_public=*/false), /* genuine = */ true ); + __TBB_ASSERT( !s->my_arena, NULL ); + __TBB_ASSERT( s->my_market, NULL ); + task& t = *s->my_dummy_task; + s->my_properties.type = scheduler_properties::master; + t.prefix().ref_count = 1; +#if __TBB_TASK_GROUP_CONTEXT + t.prefix().context = new ( NFS_Allocate(1, sizeof(task_group_context), NULL) ) + task_group_context( task_group_context::isolated, task_group_context::default_traits ); +#if __TBB_FP_CONTEXT + s->default_context()->capture_fp_settings(); +#endif + // Do not call init_stack_info before the scheduler is set as master or worker. + s->init_stack_info(); + context_state_propagation_mutex_type::scoped_lock lock(the_context_state_propagation_mutex); + s->my_market->my_masters.push_front( *s ); + lock.release(); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + if( a ) { + // Master thread always occupies the first slot + s->attach_arena( a, /*index*/0, /*is_master*/true ); + s->my_arena_slot->my_scheduler = s; +#if __TBB_TASK_GROUP_CONTEXT + a->my_default_ctx = s->default_context(); // also transfers implied ownership +#endif + } + __TBB_ASSERT( s->my_arena_index == 0, "Master thread must occupy the first slot in its arena" ); + governor::sign_on(s); + +#if _WIN32||_WIN64 + s->my_market->register_master( s->master_exec_resource ); +#endif /* _WIN32||_WIN64 */ + // Process any existing observers. +#if __TBB_ARENA_OBSERVER + __TBB_ASSERT( !a || a->my_observers.empty(), "Just created arena cannot have any observers associated with it" ); +#endif +#if __TBB_SCHEDULER_OBSERVER + the_global_observer_list.notify_entry_observers( s->my_last_global_observer, /*worker=*/false ); +#endif /* __TBB_SCHEDULER_OBSERVER */ + return s; +} + +void generic_scheduler::cleanup_worker( void* arg, bool worker ) { + generic_scheduler& s = *(generic_scheduler*)arg; + __TBB_ASSERT( !s.my_arena_slot, "cleaning up attached worker" ); +#if __TBB_SCHEDULER_OBSERVER + if ( worker ) // can be called by master for worker, do not notify master twice + the_global_observer_list.notify_exit_observers( s.my_last_global_observer, /*worker=*/true ); +#endif /* __TBB_SCHEDULER_OBSERVER */ + s.cleanup_scheduler(); +} + +bool generic_scheduler::cleanup_master( bool blocking_terminate ) { + arena* const a = my_arena; + market * const m = my_market; + __TBB_ASSERT( my_market, NULL ); + if( a && is_task_pool_published() ) { + acquire_task_pool(); + if ( my_arena_slot->task_pool == EmptyTaskPool || + __TBB_load_relaxed(my_arena_slot->head) >= __TBB_load_relaxed(my_arena_slot->tail) ) + { + // Local task pool is empty + leave_task_pool(); + } + else { + // Master's local task pool may e.g. contain proxies of affinitized tasks. + release_task_pool(); + __TBB_ASSERT ( governor::is_set(this), "TLS slot is cleared before the task pool cleanup" ); + // Set refcount to make the following dispach loop infinite (it is interrupted by the cleanup logic). + my_dummy_task->set_ref_count(2); + local_wait_for_all( *my_dummy_task, NULL ); + __TBB_ASSERT( !is_task_pool_published(), NULL ); + __TBB_ASSERT ( governor::is_set(this), "Other thread reused our TLS key during the task pool cleanup" ); + } + } +#if __TBB_ARENA_OBSERVER + if( a ) + a->my_observers.notify_exit_observers( my_last_local_observer, /*worker=*/false ); +#endif +#if __TBB_SCHEDULER_OBSERVER + the_global_observer_list.notify_exit_observers( my_last_global_observer, /*worker=*/false ); +#endif /* __TBB_SCHEDULER_OBSERVER */ +#if _WIN32||_WIN64 + m->unregister_master( master_exec_resource ); +#endif /* _WIN32||_WIN64 */ + if( a ) { + __TBB_ASSERT(a->my_slots+0 == my_arena_slot, NULL); +#if __TBB_STATISTICS + *my_arena_slot->my_counters += my_counters; +#endif /* __TBB_STATISTICS */ + __TBB_store_with_release(my_arena_slot->my_scheduler, (generic_scheduler*)NULL); + } +#if __TBB_TASK_GROUP_CONTEXT + else { // task_group_context ownership was not transferred to arena + default_context()->~task_group_context(); + NFS_Free(default_context()); + } + context_state_propagation_mutex_type::scoped_lock lock(the_context_state_propagation_mutex); + my_market->my_masters.remove( *this ); + lock.release(); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + my_arena_slot = NULL; // detached from slot + cleanup_scheduler(); // do not use scheduler state after this point + + if( a ) + a->on_thread_leaving<arena::ref_external>(); + // If there was an associated arena, it added a public market reference + return m->release( /*is_public*/ a != NULL, blocking_terminate ); +} + +} // namespace internal +} // namespace tbb + +/* + Comments: + +1. The premise of the cancellation support implementation is that cancellations are + not part of the hot path of the program execution. Therefore all changes in its + implementation in order to reduce the overhead of the cancellation control flow + should be done only in ways that do not increase overhead of the normal execution. + + In general contexts are used by all threads and their descendants are created in + different threads as well. In order to minimize impact of the cross-thread tree + maintenance (first of all because of the synchronization), the tree of contexts + is split into pieces, each of which is handled by the only thread. Such pieces + are represented as lists of contexts, members of which are contexts that were + bound to their parents in the given thread. + + The context tree maintenance and cancellation propagation algorithms is designed + in such a manner that cross-thread access to a context list will take place only + when cancellation signal is sent (by user or when an exception happens), and + synchronization is necessary only then. Thus the normal execution flow (without + exceptions and cancellation) remains free from any synchronization done on + behalf of exception handling and cancellation support. + +2. Consider parallel cancellations at the different levels of the context tree: + + Ctx1 <- Cancelled by Thread1 |- Thread2 started processing + | | + Ctx2 |- Thread1 started processing + | T1 |- Thread2 finishes and syncs up local counters + Ctx3 <- Cancelled by Thread2 | + | |- Ctx5 is bound to Ctx2 + Ctx4 | + T2 |- Thread1 reaches Ctx2 + + Thread-propagator of each cancellation increments global counter. However the thread + propagating the cancellation from the outermost context (Thread1) may be the last + to finish. Which means that the local counters may be synchronized earlier (by Thread2, + at Time1) than it propagated cancellation into Ctx2 (at time Time2). If a new context + (Ctx5) is created and bound to Ctx2 between Time1 and Time2, checking its parent only + (Ctx2) may result in cancellation request being lost. + + This issue is solved by doing the whole propagation under the lock. + + If we need more concurrency while processing parallel cancellations, we could try + the following modification of the propagation algorithm: + + advance global counter and remember it + for each thread: + scan thread's list of contexts + for each thread: + sync up its local counter only if the global counter has not been changed + + However this version of the algorithm requires more analysis and verification. + +3. There is no portable way to get stack base address in Posix, however the modern + Linux versions provide pthread_attr_np API that can be used to obtain thread's + stack size and base address. Unfortunately even this function does not provide + enough information for the main thread on IA-64 architecture (RSE spill area + and memory stack are allocated as two separate discontinuous chunks of memory), + and there is no portable way to discern the main and the secondary threads. + Thus for macOS* and IA-64 architecture for Linux* OS we use the TBB worker stack size for + all threads and use the current stack top as the stack base. This simplified + approach is based on the following assumptions: + 1) If the default stack size is insufficient for the user app needs, the + required amount will be explicitly specified by the user at the point of the + TBB scheduler initialization (as an argument to tbb::task_scheduler_init + constructor). + 2) When a master thread initializes the scheduler, it has enough space on its + stack. Here "enough" means "at least as much as worker threads have". + 3) If the user app strives to conserve the memory by cutting stack size, it + should do this for TBB workers too (as in the #1). +*/ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler.h new file mode 100644 index 00000000..eff182d5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler.h @@ -0,0 +1,1027 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_scheduler_H +#define _TBB_scheduler_H + +#include "scheduler_common.h" +#include "tbb/spin_mutex.h" +#include "mailbox.h" +#include "tbb_misc.h" // for FastRandom +#include "itt_notify.h" +#include "../rml/include/rml_tbb.h" + +#include "intrusive_list.h" + +#if __TBB_SURVIVE_THREAD_SWITCH +#include "cilk-tbb-interop.h" +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ + +#if __TBB_PREVIEW_RESUMABLE_TASKS +#include "co_context.h" +#endif + +namespace tbb { +namespace internal { + +template<typename SchedulerTraits> class custom_scheduler; + +//------------------------------------------------------------------------ +// generic_scheduler +//------------------------------------------------------------------------ + +#define EmptyTaskPool ((task**)0) +#define LockedTaskPool ((task**)~(intptr_t)0) + +//! Bit-field representing properties of a sheduler +struct scheduler_properties { + static const bool worker = false; + static const bool master = true; + //! Indicates that a scheduler acts as a master or a worker. + bool type : 1; + //! Indicates that a scheduler is on outermost level. + /** Note that the explicit execute method will set this property. **/ + bool outermost : 1; +#if __TBB_PREVIEW_CRITICAL_TASKS + //! Indicates that a scheduler is in the process of executing critical task(s). + bool has_taken_critical_task : 1; +#endif +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! Indicates that the scheduler is bound to an original thread stack. + bool genuine : 1; +#endif + //! Reserved bits + unsigned char : +#if __TBB_PREVIEW_RESUMABLE_TASKS + 4; +#elif __TBB_PREVIEW_CRITICAL_TASKS + 5; +#else + 6; +#endif +}; + +struct scheduler_state { + //! Index of the arena slot the scheduler occupies now, or occupied last time. + size_t my_arena_index; // TODO: make it unsigned and pair with my_affinity_id to fit into cache line + + //! Pointer to the slot in the arena we own at the moment. + arena_slot* my_arena_slot; + + //! The arena that I own (if master) or am servicing at the moment (if worker) + arena* my_arena; + + //! Innermost task whose task::execute() is running. A dummy task on the outermost level. + task* my_innermost_running_task; + + mail_inbox my_inbox; + + //! The mailbox id assigned to this scheduler. + /** The id is assigned upon first entry into the arena. + TODO: how are id's being garbage collected? + TODO: master thread may enter arena and leave and then reenter. + We want to give it the same affinity_id upon reentry, if practical. + TODO: investigate if it makes sense to merge this field into scheduler_properties. + */ + affinity_id my_affinity_id; + + scheduler_properties my_properties; + +#if __TBB_SCHEDULER_OBSERVER + //! Last observer in the global observers list processed by this scheduler + observer_proxy* my_last_global_observer; +#endif + +#if __TBB_ARENA_OBSERVER + //! Last observer in the local observers list processed by this scheduler + observer_proxy* my_last_local_observer; +#endif +#if __TBB_TASK_PRIORITY + //! Latest known highest priority of tasks in the market or arena. + /** Master threads currently tracks only tasks in their arenas, while workers + take into account global top priority (among all arenas in the market). **/ + volatile intptr_t *my_ref_top_priority; + + //! Pointer to market's (for workers) or current arena's (for the master) reload epoch counter. + volatile uintptr_t *my_ref_reload_epoch; +#endif /* __TBB_TASK_PRIORITY */ +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! The currently waited task. + task* my_wait_task; + + //! The currently recalled stack. + tbb::atomic<bool>* my_current_is_recalled; +#endif +}; + +//! Work stealing task scheduler. +/** None of the fields here are ever read or written by threads other than + the thread that creates the instance. + + Class generic_scheduler is an abstract base class that contains most of the scheduler, + except for tweaks specific to processors and tools (e.g. VTune(TM) Performance Tools). + The derived template class custom_scheduler<SchedulerTraits> fills in the tweaks. */ +class generic_scheduler: public scheduler + , public ::rml::job + , public intrusive_list_node + , public scheduler_state { +public: // almost every class in TBB uses generic_scheduler + + //! If sizeof(task) is <=quick_task_size, it is handled on a free list instead of malloc'd. + static const size_t quick_task_size = 256-task_prefix_reservation_size; + + static bool is_version_3_task( task& t ) { +#if __TBB_PREVIEW_CRITICAL_TASKS + return (t.prefix().extra_state & 0x7)>=0x1; +#else + return (t.prefix().extra_state & 0x0F)>=0x1; +#endif + } + + //! Position in the call stack specifying its maximal filling when stealing is still allowed + uintptr_t my_stealing_threshold; +#if __TBB_ipf + //! Position in the RSE backup area specifying its maximal filling when stealing is still allowed + uintptr_t my_rsb_stealing_threshold; +#endif + + static const size_t null_arena_index = ~size_t(0); + + inline bool is_task_pool_published () const; + + inline bool is_local_task_pool_quiescent () const; + + inline bool is_quiescent_local_task_pool_empty () const; + + inline bool is_quiescent_local_task_pool_reset () const; + + //! The market I am in + market* my_market; + + //! Random number generator used for picking a random victim from which to steal. + FastRandom my_random; + + //! Free list of small tasks that can be reused. + task* my_free_list; + +#if __TBB_HOARD_NONLOCAL_TASKS + //! Free list of small non-local tasks that should be returned or can be reused. + task* my_nonlocal_free_list; +#endif + //! Fake root task created by slave threads. + /** The task is used as the "parent" argument to method wait_for_all. */ + task* my_dummy_task; + + //! Reference count for scheduler + /** Number of task_scheduler_init objects that point to this scheduler */ + long my_ref_count; + + inline void attach_mailbox( affinity_id id ); + + /* A couple of bools can be located here because space is otherwise just padding after my_affinity_id. */ + + //! True if *this was created by automatic TBB initialization + bool my_auto_initialized; + +#if __TBB_COUNT_TASK_NODES + //! Net number of big task objects that have been allocated but not yet freed. + intptr_t my_task_node_count; +#endif /* __TBB_COUNT_TASK_NODES */ + +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! The list of possible post resume actions. + enum post_resume_action { + PRA_INVALID, + PRA_ABANDON, + PRA_CALLBACK, + PRA_CLEANUP, + PRA_NOTIFY, + PRA_NONE + }; + + //! The suspend callback function type. + typedef void(*suspend_callback_t)(void*, task::suspend_point); + + //! The callback to call the user callback passed to tbb::suspend. + struct callback_t { + suspend_callback_t suspend_callback; + void* user_callback; + task::suspend_point tag; + + void operator()() { + if (suspend_callback) { + __TBB_ASSERT(suspend_callback && user_callback && tag, NULL); + suspend_callback(user_callback, tag); + } + } + }; + + //! The coroutine context associated with the current scheduler. + co_context my_co_context; + + //! The post resume action requested for the current scheduler. + post_resume_action my_post_resume_action; + + //! The post resume action argument. + void* my_post_resume_arg; + + //! The scheduler to resume on exit. + generic_scheduler* my_target_on_exit; + + //! Set post resume action to perform after resume. + void set_post_resume_action(post_resume_action, void* arg); + + //! Performs post resume action. + void do_post_resume_action(); + + //! Decides how to switch and sets post resume action. + /** Returns false if the caller should finish the coroutine and then resume the target scheduler. + Returns true if the caller should resume the target scheduler immediately. **/ + bool prepare_resume(generic_scheduler& target); + + //! Resumes the original scheduler of the calling thread. + /** Returns false if the current stack should be left to perform the resume. + Returns true if the current stack is resumed. **/ + bool resume_original_scheduler(); + + //! Resumes the target scheduler. The prepare_resume must be called for the target scheduler in advance. + void resume(generic_scheduler& target); + + friend void recall_function(task::suspend_point tag); +#endif /* __TBB_PREVIEW_RESUMABLE_TASKS */ + + //! Sets up the data necessary for the stealing limiting heuristics + void init_stack_info (); + + //! Returns true if stealing is allowed + bool can_steal () { + int anchor; + // TODO IDEA: Add performance warning? +#if __TBB_ipf + return my_stealing_threshold < (uintptr_t)&anchor && (uintptr_t)__TBB_get_bsp() < my_rsb_stealing_threshold; +#else + return my_stealing_threshold < (uintptr_t)&anchor; +#endif + } + + //! Used by workers to enter the task pool + /** Does not lock the task pool in case if arena slot has been successfully grabbed. **/ + void publish_task_pool(); + + //! Leave the task pool + /** Leaving task pool automatically releases the task pool if it is locked. **/ + void leave_task_pool(); + + //! Resets head and tail indices to 0, and leaves task pool + /** The task pool must be locked by the owner (via acquire_task_pool).**/ + inline void reset_task_pool_and_leave (); + + //! Locks victim's task pool, and returns pointer to it. The pointer can be NULL. + /** Garbles victim_arena_slot->task_pool for the duration of the lock. **/ + task** lock_task_pool( arena_slot* victim_arena_slot ) const; + + //! Unlocks victim's task pool + /** Restores victim_arena_slot->task_pool munged by lock_task_pool. **/ + void unlock_task_pool( arena_slot* victim_arena_slot, task** victim_task_pool ) const; + + //! Locks the local task pool + /** Garbles my_arena_slot->task_pool for the duration of the lock. Requires + correctly set my_arena_slot->task_pool_ptr. **/ + void acquire_task_pool() const; + + //! Unlocks the local task pool + /** Restores my_arena_slot->task_pool munged by acquire_task_pool. Requires + correctly set my_arena_slot->task_pool_ptr. **/ + void release_task_pool() const; + + //! Checks if t is affinitized to another thread, and if so, bundles it as proxy. + /** Returns either t or proxy containing t. **/ + task* prepare_for_spawning( task* t ); + + //! Makes newly spawned tasks visible to thieves + inline void commit_spawned_tasks( size_t new_tail ); + + //! Makes relocated tasks visible to thieves and releases the local task pool. + /** Obviously, the task pool must be locked when calling this method. **/ + inline void commit_relocated_tasks( size_t new_tail ); + + //! Get a task from the local pool. + /** Called only by the pool owner. + Returns the pointer to the task or NULL if a suitable task is not found. + Resets the pool if it is empty. **/ + task* get_task( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ); + + //! Get a task from the local pool at specified location T. + /** Returns the pointer to the task or NULL if the task cannot be executed, + e.g. proxy has been deallocated or isolation constraint is not met. + tasks_omitted tells if some tasks have been omitted. + Called only by the pool owner. The caller should guarantee that the + position T is not available for a thief. **/ +#if __TBB_TASK_ISOLATION + task* get_task( size_t T, isolation_tag isolation, bool& tasks_omitted ); +#else + task* get_task( size_t T ); +#endif /* __TBB_TASK_ISOLATION */ + //! Attempt to get a task from the mailbox. + /** Gets a task only if it has not been executed by its sender or a thief + that has stolen it from the sender's task pool. Otherwise returns NULL. + + This method is intended to be used only by the thread extracting the proxy + from its mailbox. (In contrast to local task pool, mailbox can be read only + by its owner). **/ + task* get_mailbox_task( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ); + + //! True if t is a task_proxy + static bool is_proxy( const task& t ) { + return t.prefix().extra_state==es_task_proxy; + } + + //! Attempts to steal a task from a randomly chosen thread/scheduler + task* steal_task( __TBB_ISOLATION_EXPR(isolation_tag isolation) ); + + //! Steal task from another scheduler's ready pool. + task* steal_task_from( __TBB_ISOLATION_ARG( arena_slot& victim_arena_slot, isolation_tag isolation ) ); + +#if __TBB_PREVIEW_CRITICAL_TASKS + //! Tries to find critical task in critical task stream + task* get_critical_task( __TBB_ISOLATION_EXPR(isolation_tag isolation) ); + + //! Pushes task to critical task stream if it appears to be such task and returns + //! true. Otherwise does nothing and returns false. + bool handled_as_critical( task& t ); +#endif + + /** Initial size of the task deque sufficient to serve without reallocation + 4 nested parallel_for calls with iteration space of 65535 grains each. **/ + static const size_t min_task_pool_size = 64; + + //! Makes sure that the task pool can accommodate at least n more elements + /** If necessary relocates existing task pointers or grows the ready task deque. + Returns (possible updated) tail index (not accounting for n). **/ + size_t prepare_task_pool( size_t n ); + + //! Initialize a scheduler for a master thread. + static generic_scheduler* create_master( arena* a ); + + //! Perform necessary cleanup when a master thread stops using TBB. + bool cleanup_master( bool blocking_terminate ); + + //! Initialize a scheduler for a worker thread. + static generic_scheduler* create_worker( market& m, size_t index, bool geniune ); + + //! Perform necessary cleanup when a worker thread finishes. + static void cleanup_worker( void* arg, bool worker ); + +protected: + template<typename SchedulerTraits> friend class custom_scheduler; + generic_scheduler( market &, bool ); + +public: +#if TBB_USE_ASSERT > 1 + //! Check that internal data structures are in consistent state. + /** Raises __TBB_ASSERT failure if inconsistency is found. */ + void assert_task_pool_valid() const; +#else + void assert_task_pool_valid() const {} +#endif /* TBB_USE_ASSERT <= 1 */ + + void attach_arena( arena*, size_t index, bool is_master ); + void nested_arena_entry( arena*, size_t ); + void nested_arena_exit(); + void wait_until_empty(); + + void spawn( task& first, task*& next ) __TBB_override; + + void spawn_root_and_wait( task& first, task*& next ) __TBB_override; + + void enqueue( task&, void* reserved ) __TBB_override; + + void local_spawn( task* first, task*& next ); + void local_spawn_root_and_wait( task* first, task*& next ); + virtual void local_wait_for_all( task& parent, task* child ) = 0; + + //! Destroy and deallocate this scheduler object. + void destroy(); + + //! Cleans up this scheduler (the scheduler might be destroyed). + void cleanup_scheduler(); + + //! Allocate task object, either from the heap or a free list. + /** Returns uninitialized task object with initialized prefix. */ + task& allocate_task( size_t number_of_bytes, + __TBB_CONTEXT_ARG(task* parent, task_group_context* context) ); + + //! Put task on free list. + /** Does not call destructor. */ + template<free_task_hint h> + void free_task( task& t ); + + //! Return task object to the memory allocator. + inline void deallocate_task( task& t ); + + //! True if running on a worker thread, false otherwise. + inline bool is_worker() const; + + //! True if the scheduler is on the outermost dispatch level. + inline bool outermost_level() const; + + //! True if the scheduler is on the outermost dispatch level in a master thread. + /** Returns true when this scheduler instance is associated with an application + thread, and is not executing any TBB task. This includes being in a TBB + dispatch loop (one of wait_for_all methods) invoked directly from that thread. **/ + inline bool master_outermost_level () const; + + //! True if the scheduler is on the outermost dispatch level in a worker thread. + inline bool worker_outermost_level () const; + + //! Returns the concurrency limit of the current arena. + unsigned max_threads_in_arena(); + +#if __TBB_COUNT_TASK_NODES + intptr_t get_task_node_count( bool count_arena_workers = false ); +#endif /* __TBB_COUNT_TASK_NODES */ + + //! Special value used to mark my_return_list as not taking any more entries. + static task* plugged_return_list() {return (task*)(intptr_t)(-1);} + + //! Number of small tasks that have been allocated by this scheduler. + __TBB_atomic intptr_t my_small_task_count; + + //! List of small tasks that have been returned to this scheduler by other schedulers. + // TODO IDEA: see if putting my_return_list on separate cache line improves performance + task* my_return_list; + + //! Try getting a task from other threads (via mailbox, stealing, FIFO queue, orphans adoption). + /** Returns obtained task or NULL if all attempts fail. */ + virtual task* receive_or_steal_task( __TBB_ISOLATION_ARG( __TBB_atomic reference_count& completion_ref_count, isolation_tag isolation ) ) = 0; + + //! Free a small task t that that was allocated by a different scheduler + void free_nonlocal_small_task( task& t ); + +#if __TBB_TASK_GROUP_CONTEXT + //! Returns task group context used by this scheduler instance. + /** This context is associated with root tasks created by a master thread + without explicitly specified context object outside of any running task. + + Note that the default context of a worker thread is never accessed by + user code (directly or indirectly). **/ + inline task_group_context* default_context (); + + //! Padding isolating thread-local members from members that can be written to by other threads. + char _padding1[NFS_MaxLineSize - sizeof(context_list_node_t)]; + + //! Head of the thread specific list of task group contexts. + context_list_node_t my_context_list_head; + + //! Mutex protecting access to the list of task group contexts. + // TODO: check whether it can be deadly preempted and replace by spinning/sleeping mutex + spin_mutex my_context_list_mutex; + + //! Last state propagation epoch known to this thread + /** Together with the_context_state_propagation_epoch constitute synchronization protocol + that keeps hot path of task group context construction destruction mostly + lock-free. + When local epoch equals the global one, the state of task group contexts + registered with this thread is consistent with that of the task group trees + they belong to. **/ + uintptr_t my_context_state_propagation_epoch; + + //! Flag indicating that a context is being destructed by its owner thread + /** Together with my_nonlocal_ctx_list_update constitute synchronization protocol + that keeps hot path of context destruction (by the owner thread) mostly + lock-free. **/ + tbb::atomic<uintptr_t> my_local_ctx_list_update; + +#if __TBB_TASK_PRIORITY + //! Returns reference priority used to decide whether a task should be offloaded. + inline intptr_t effective_reference_priority () const; + + // TODO: move into slots and fix is_out_of_work + //! Task pool for offloading tasks with priorities lower than the current top priority. + task* my_offloaded_tasks; + + //! Points to the last offloaded task in the my_offloaded_tasks list. + task** my_offloaded_task_list_tail_link; + + //! Indicator of how recently the offload area was checked for the presence of top priority tasks. + uintptr_t my_local_reload_epoch; + + //! Indicates that the pool is likely non-empty even if appears so from outside + volatile bool my_pool_reshuffling_pending; + + //! Searches offload area for top priority tasks and reloads found ones into primary task pool. + /** Returns one of the found tasks or NULL. **/ + task* reload_tasks( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ); + + task* reload_tasks( task*& offloaded_tasks, task**& offloaded_task_list_link, __TBB_ISOLATION_ARG( intptr_t top_priority, isolation_tag isolation ) ); + + //! Moves tasks with priority below the top one from primary task pool into offload area. + /** Returns the next execution candidate task or NULL. **/ + task* winnow_task_pool ( __TBB_ISOLATION_EXPR( isolation_tag isolation ) ); + + //! Get a task from locked or empty pool in range [H0, T0). Releases or unlocks the task pool. + /** Returns the found task or NULL. **/ + task *get_task_and_activate_task_pool( size_t H0 , __TBB_ISOLATION_ARG( size_t T0, isolation_tag isolation ) ); + + //! Unconditionally moves the task into offload area. + inline void offload_task ( task& t, intptr_t task_priority ); +#endif /* __TBB_TASK_PRIORITY */ + + //! Detaches abandoned contexts + /** These contexts must be destroyed by other threads. **/ + void cleanup_local_context_list (); + + //! Finds all contexts registered by this scheduler affected by the state change + //! and propagates the new state to them. + template <typename T> + void propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ); + + // check consistency + static void assert_context_valid(const task_group_context *tgc) { + suppress_unused_warning(tgc); +#if TBB_USE_ASSERT + __TBB_ASSERT(tgc, NULL); + uintptr_t ctx = tgc->my_version_and_traits; + __TBB_ASSERT(is_alive(ctx), "referenced task_group_context was destroyed"); + static const char *msg = "task_group_context is invalid"; + __TBB_ASSERT(!(ctx&~(3|(7<<task_group_context::traits_offset))), msg); // the value fits known values of versions and traits + __TBB_ASSERT(tgc->my_kind < task_group_context::dying, msg); + __TBB_ASSERT(tgc->my_cancellation_requested == 0 || tgc->my_cancellation_requested == 1, msg); + __TBB_ASSERT(tgc->my_state < task_group_context::low_unused_state_bit, msg); + if(tgc->my_kind != task_group_context::isolated) { + __TBB_ASSERT(tgc->my_owner, msg); + __TBB_ASSERT(tgc->my_node.my_next && tgc->my_node.my_prev, msg); + } +#if __TBB_TASK_PRIORITY + assert_priority_valid(tgc->my_priority); +#endif + if(tgc->my_parent) +#if TBB_USE_ASSERT > 1 + assert_context_valid(tgc->my_parent); +#else + __TBB_ASSERT(is_alive(tgc->my_parent->my_version_and_traits), msg); +#endif +#endif + } +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#if _WIN32||_WIN64 +private: + //! Handle returned by RML when registering a master with RML + ::rml::server::execution_resource_t master_exec_resource; +public: +#endif /* _WIN32||_WIN64 */ + +#if __TBB_TASK_GROUP_CONTEXT + //! Flag indicating that a context is being destructed by non-owner thread. + /** See also my_local_ctx_list_update. **/ + tbb::atomic<uintptr_t> my_nonlocal_ctx_list_update; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#if __TBB_SURVIVE_THREAD_SWITCH + __cilk_tbb_unwatch_thunk my_cilk_unwatch_thunk; +#if TBB_USE_ASSERT + //! State values used to check interface contract with cilkrts. + /** Names of cs_running...cs_freed derived from state machine diagram in cilk-tbb-interop.h */ + enum cilk_state_t { + cs_none=0xF000, // Start at nonzero value so that we can detect use of zeroed memory. + cs_running, + cs_limbo, + cs_freed + }; + cilk_state_t my_cilk_state; +#endif /* TBB_USE_ASSERT */ +#endif /* __TBB_SURVIVE_THREAD_SWITCH */ + +#if __TBB_STATISTICS + //! Set of counters to track internal statistics on per thread basis + /** Placed at the end of the class definition to minimize the disturbance of + the core logic memory operations. **/ + mutable statistics_counters my_counters; +#endif /* __TBB_STATISTICS */ + +}; // class generic_scheduler + + +} // namespace internal +} // namespace tbb + +#include "arena.h" +#include "governor.h" + +namespace tbb { +namespace internal { + +inline bool generic_scheduler::is_task_pool_published () const { + __TBB_ASSERT(my_arena_slot, 0); + return my_arena_slot->task_pool != EmptyTaskPool; +} + +inline bool generic_scheduler::is_local_task_pool_quiescent () const { + __TBB_ASSERT(my_arena_slot, 0); + task** tp = my_arena_slot->task_pool; + return tp == EmptyTaskPool || tp == LockedTaskPool; +} + +inline bool generic_scheduler::is_quiescent_local_task_pool_empty () const { + __TBB_ASSERT( is_local_task_pool_quiescent(), "Task pool is not quiescent" ); + return __TBB_load_relaxed(my_arena_slot->head) == __TBB_load_relaxed(my_arena_slot->tail); +} + +inline bool generic_scheduler::is_quiescent_local_task_pool_reset () const { + __TBB_ASSERT( is_local_task_pool_quiescent(), "Task pool is not quiescent" ); + return __TBB_load_relaxed(my_arena_slot->head) == 0 && __TBB_load_relaxed(my_arena_slot->tail) == 0; +} + +inline bool generic_scheduler::outermost_level () const { + return my_properties.outermost; +} + +inline bool generic_scheduler::master_outermost_level () const { + return !is_worker() && outermost_level(); +} + +inline bool generic_scheduler::worker_outermost_level () const { + return is_worker() && outermost_level(); +} + +#if __TBB_TASK_GROUP_CONTEXT +inline task_group_context* generic_scheduler::default_context () { + return my_dummy_task->prefix().context; +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +inline void generic_scheduler::attach_mailbox( affinity_id id ) { + __TBB_ASSERT(id>0,NULL); + my_inbox.attach( my_arena->mailbox(id) ); + my_affinity_id = id; +} + +inline bool generic_scheduler::is_worker() const { + return my_properties.type == scheduler_properties::worker; +} + +inline unsigned generic_scheduler::max_threads_in_arena() { + __TBB_ASSERT(my_arena, NULL); + return my_arena->my_num_slots; +} + +//! Return task object to the memory allocator. +inline void generic_scheduler::deallocate_task( task& t ) { +#if TBB_USE_ASSERT + task_prefix& p = t.prefix(); + p.state = 0xFF; + p.extra_state = 0xFF; + poison_pointer(p.next); +#endif /* TBB_USE_ASSERT */ + NFS_Free((char*)&t-task_prefix_reservation_size); +#if __TBB_COUNT_TASK_NODES + --my_task_node_count; +#endif /* __TBB_COUNT_TASK_NODES */ +} + +#if __TBB_COUNT_TASK_NODES +inline intptr_t generic_scheduler::get_task_node_count( bool count_arena_workers ) { + return my_task_node_count + (count_arena_workers? my_arena->workers_task_node_count(): 0); +} +#endif /* __TBB_COUNT_TASK_NODES */ + +inline void generic_scheduler::reset_task_pool_and_leave () { + __TBB_ASSERT( my_arena_slot->task_pool == LockedTaskPool, "Task pool must be locked when resetting task pool" ); + __TBB_store_relaxed( my_arena_slot->tail, 0 ); + __TBB_store_relaxed( my_arena_slot->head, 0 ); + leave_task_pool(); +} + +//TODO: move to arena_slot +inline void generic_scheduler::commit_spawned_tasks( size_t new_tail ) { + __TBB_ASSERT ( new_tail <= my_arena_slot->my_task_pool_size, "task deque end was overwritten" ); + // emit "task was released" signal + ITT_NOTIFY(sync_releasing, (void*)((uintptr_t)my_arena_slot+sizeof(uintptr_t))); + // Release fence is necessary to make sure that previously stored task pointers + // are visible to thieves. + __TBB_store_with_release( my_arena_slot->tail, new_tail ); +} + +void generic_scheduler::commit_relocated_tasks ( size_t new_tail ) { + __TBB_ASSERT( is_local_task_pool_quiescent(), + "Task pool must be locked when calling commit_relocated_tasks()" ); + __TBB_store_relaxed( my_arena_slot->head, 0 ); + // Tail is updated last to minimize probability of a thread making arena + // snapshot being misguided into thinking that this task pool is empty. + __TBB_store_release( my_arena_slot->tail, new_tail ); + release_task_pool(); +} + +template<free_task_hint hint> +void generic_scheduler::free_task( task& t ) { +#if __TBB_HOARD_NONLOCAL_TASKS + static const int h = hint&(~local_task); +#else + static const free_task_hint h = hint; +#endif + GATHER_STATISTIC(--my_counters.active_tasks); + task_prefix& p = t.prefix(); + // Verify that optimization hints are correct. + __TBB_ASSERT( h!=small_local_task || p.origin==this, NULL ); + __TBB_ASSERT( !(h&small_task) || p.origin, NULL ); + __TBB_ASSERT( !(h&local_task) || (!p.origin || uintptr_t(p.origin) > uintptr_t(4096)), "local_task means allocated"); + poison_value(p.depth); + poison_value(p.ref_count); + poison_pointer(p.owner); +#if __TBB_PREVIEW_RESUMABLE_TASKS + __TBB_ASSERT(1L << t.state() & (1L << task::executing | 1L << task::allocated | 1 << task::to_resume), NULL); +#else + __TBB_ASSERT(1L << t.state() & (1L << task::executing | 1L << task::allocated), NULL); +#endif + p.state = task::freed; + if( h==small_local_task || p.origin==this ) { + GATHER_STATISTIC(++my_counters.free_list_length); + p.next = my_free_list; + my_free_list = &t; + } else if( !(h&local_task) && p.origin && uintptr_t(p.origin) < uintptr_t(4096) ) { + // a special value reserved for future use, do nothing since + // origin is not pointing to a scheduler instance + } else if( !(h&local_task) && p.origin ) { + GATHER_STATISTIC(++my_counters.free_list_length); +#if __TBB_HOARD_NONLOCAL_TASKS + if( !(h&no_cache) ) { + p.next = my_nonlocal_free_list; + my_nonlocal_free_list = &t; + } else +#endif + free_nonlocal_small_task(t); + } else { + GATHER_STATISTIC(--my_counters.big_tasks); + deallocate_task(t); + } +} + +#if __TBB_TASK_PRIORITY +inline intptr_t generic_scheduler::effective_reference_priority () const { + // Workers on the outermost dispatch level (i.e. with empty stack) use market's + // priority as a reference point (to speedup discovering process level priority + // changes). But when there are enough workers to service (even if only partially) + // a lower priority arena, they should use arena's priority as a reference, lest + // be trapped in a futile spinning (because market's priority would prohibit + // executing ANY tasks in this arena). + return !worker_outermost_level() || + my_arena->my_num_workers_allotted < my_arena->num_workers_active() ? *my_ref_top_priority : my_arena->my_top_priority; +} + +inline void generic_scheduler::offload_task ( task& t, intptr_t /*priority*/ ) { + GATHER_STATISTIC( ++my_counters.prio_tasks_offloaded ); + __TBB_ASSERT( !is_proxy(t), "The proxy task cannot be offloaded" ); + __TBB_ASSERT( my_offloaded_task_list_tail_link && !*my_offloaded_task_list_tail_link, NULL ); +#if TBB_USE_ASSERT + t.prefix().state = task::ready; +#endif /* TBB_USE_ASSERT */ + t.prefix().next_offloaded = my_offloaded_tasks; + my_offloaded_tasks = &t; +} +#endif /* __TBB_TASK_PRIORITY */ + +#if __TBB_PREVIEW_RESUMABLE_TASKS +inline void generic_scheduler::set_post_resume_action(post_resume_action pra, void* arg) { + __TBB_ASSERT(my_post_resume_action == PRA_NONE, "Post resume action has already been set."); + __TBB_ASSERT(!my_post_resume_arg, NULL); + + my_post_resume_action = pra; + my_post_resume_arg = arg; +} + +inline bool generic_scheduler::prepare_resume(generic_scheduler& target) { + // The second condition is valid for worker or cleanup operation for master + if (my_properties.outermost && my_wait_task == my_dummy_task) { + if (my_properties.genuine) { + // We are in someone's original scheduler. + target.set_post_resume_action(PRA_NOTIFY, my_current_is_recalled); + return true; + } + // We are in a coroutine on outermost level. + target.set_post_resume_action(PRA_CLEANUP, this); + my_target_on_exit = ⌖ + // Request to finish coroutine instead of immediate resume. + return false; + } + __TBB_ASSERT(my_wait_task != my_dummy_task, NULL); + // We are in the coroutine on a nested level. + my_wait_task->prefix().abandoned_scheduler = this; + target.set_post_resume_action(PRA_ABANDON, my_wait_task); + return true; +} + +inline bool generic_scheduler::resume_original_scheduler() { + generic_scheduler& target = *my_arena_slot->my_scheduler; + if (!prepare_resume(target)) { + // We should return and finish the current coroutine. + return false; + } + resume(target); + return true; +} + +inline void generic_scheduler::resume(generic_scheduler& target) { + // Do not create non-trivial objects on the stack of this function. They might never be destroyed. + __TBB_ASSERT(governor::is_set(this), NULL); + __TBB_ASSERT(target.my_post_resume_action != PRA_NONE, + "The post resume action is not set. Has prepare_resume been called?"); + __TBB_ASSERT(target.my_post_resume_arg, NULL); + __TBB_ASSERT(&target != this, NULL); + __TBB_ASSERT(target.my_arena == my_arena, "Cross-arena switch is forbidden."); + + // Transfer thread related data. + target.my_arena_index = my_arena_index; + target.my_arena_slot = my_arena_slot; +#if __TBB_SCHEDULER_OBSERVER + target.my_last_global_observer = my_last_global_observer; +#endif +#if __TBB_ARENA_OBSERVER + target.my_last_local_observer = my_last_local_observer; +#endif + target.attach_mailbox(affinity_id(target.my_arena_index + 1)); + +#if __TBB_TASK_PRIORITY + if (my_offloaded_tasks) + my_arena->orphan_offloaded_tasks(*this); +#endif /* __TBB_TASK_PRIORITY */ + + governor::assume_scheduler(&target); + my_co_context.resume(target.my_co_context); + __TBB_ASSERT(governor::is_set(this), NULL); + + do_post_resume_action(); + if (this == my_arena_slot->my_scheduler) { + my_arena_slot->my_scheduler_is_recalled->store<tbb::relaxed>(false); + } +} + +inline void generic_scheduler::do_post_resume_action() { + __TBB_ASSERT(my_post_resume_action != PRA_NONE, "The post resume action is not set."); + __TBB_ASSERT(my_post_resume_arg, NULL); + + switch (my_post_resume_action) { + case PRA_ABANDON: + { + task_prefix& wait_task_prefix = static_cast<task*>(my_post_resume_arg)->prefix(); + reference_count old_ref_count = __TBB_FetchAndAddW(&wait_task_prefix.ref_count, internal::abandon_flag); + __TBB_ASSERT(old_ref_count > 0, NULL); + if (old_ref_count == 1) { + // Remove the abandon flag. + __TBB_store_with_release(wait_task_prefix.ref_count, 1); + // The wait has been completed. Spawn a resume task. + tbb::task::resume(wait_task_prefix.abandoned_scheduler); + } + break; + } + case PRA_CALLBACK: + { + callback_t callback = *static_cast<callback_t*>(my_post_resume_arg); + callback(); + break; + } + case PRA_CLEANUP: + { + generic_scheduler* to_cleanup = static_cast<generic_scheduler*>(my_post_resume_arg); + __TBB_ASSERT(!to_cleanup->my_properties.genuine, NULL); + // Release coroutine's reference to my_arena. + to_cleanup->my_arena->on_thread_leaving<arena::ref_external>(); + // Cache the coroutine for possible later re-usage + to_cleanup->my_arena->my_co_cache.push(to_cleanup); + break; + } + case PRA_NOTIFY: + { + tbb::atomic<bool>& scheduler_recall_flag = *static_cast<tbb::atomic<bool>*>(my_post_resume_arg); + scheduler_recall_flag = true; + // Do not access recall_flag because it can be destroyed after the notification. + break; + } + default: + __TBB_ASSERT(false, NULL); + } + + my_post_resume_action = PRA_NONE; + my_post_resume_arg = NULL; +} + +struct recall_functor { + tbb::atomic<bool>* scheduler_recall_flag; + + recall_functor(tbb::atomic<bool>* recall_flag_) : + scheduler_recall_flag(recall_flag_) {} + + void operator()(task::suspend_point /*tag*/) { + *scheduler_recall_flag = true; + } +}; + +#if _WIN32 +/* [[noreturn]] */ inline void __stdcall co_local_wait_for_all(void* arg) { +#else +/* [[noreturn]] */ inline void co_local_wait_for_all(void* arg) { +#endif + // Do not create non-trivial objects on the stack of this function. They will never be destroyed. + generic_scheduler& s = *static_cast<generic_scheduler*>(arg); + __TBB_ASSERT(governor::is_set(&s), NULL); + // For correct task stealing threshold, calculate stack on a coroutine start + s.init_stack_info(); + // Basically calls the user callback passed to the tbb::task::suspend function + s.do_post_resume_action(); + // Endless loop here because coroutine could be reused + for( ;; ) { + __TBB_ASSERT(s.my_innermost_running_task == s.my_dummy_task, NULL); + __TBB_ASSERT(s.worker_outermost_level(), NULL); + s.local_wait_for_all(*s.my_dummy_task, NULL); + __TBB_ASSERT(s.my_target_on_exit, NULL); + __TBB_ASSERT(s.my_wait_task == NULL, NULL); + s.resume(*s.my_target_on_exit); + } + // This code is unreachable +} +#endif /* __TBB_PREVIEW_RESUMABLE_TASKS */ + +#if __TBB_TASK_GROUP_CONTEXT +//! Helper class for tracking floating point context and task group context switches +/** Assuming presence of an itt collector, in addition to keeping track of floating + point context, this class emits itt events to indicate begin and end of task group + context execution **/ +template <bool report_tasks> +class context_guard_helper { + const task_group_context *curr_ctx; +#if __TBB_FP_CONTEXT + cpu_ctl_env guard_cpu_ctl_env; + cpu_ctl_env curr_cpu_ctl_env; +#endif +public: + context_guard_helper() : curr_ctx( NULL ) { +#if __TBB_FP_CONTEXT + guard_cpu_ctl_env.get_env(); + curr_cpu_ctl_env = guard_cpu_ctl_env; +#endif + } + ~context_guard_helper() { +#if __TBB_FP_CONTEXT + if ( curr_cpu_ctl_env != guard_cpu_ctl_env ) + guard_cpu_ctl_env.set_env(); +#endif + if ( report_tasks && curr_ctx ) + ITT_TASK_END; + } + // The function is called from bypass dispatch loop on the hot path. + // Consider performance issues when refactoring. + void set_ctx( const task_group_context *ctx ) { + generic_scheduler::assert_context_valid( ctx ); +#if __TBB_FP_CONTEXT + const cpu_ctl_env &ctl = *punned_cast<cpu_ctl_env*>( &ctx->my_cpu_ctl_env ); + // Compare the FPU settings directly because the context can be reused between parallel algorithms. + if ( ctl != curr_cpu_ctl_env ) { + curr_cpu_ctl_env = ctl; + curr_cpu_ctl_env.set_env(); + } +#endif + if ( report_tasks && ctx != curr_ctx ) { + // if task group context was active, report end of current execution frame. + if ( curr_ctx ) + ITT_TASK_END; + // reporting begin of new task group context execution frame. + // using address of task group context object to group tasks (parent). + // id of task execution frame is NULL and reserved for future use. + ITT_TASK_BEGIN( ctx,ctx->my_name, NULL ); + curr_ctx = ctx; + } + } + void restore_default() { +#if __TBB_FP_CONTEXT + if ( curr_cpu_ctl_env != guard_cpu_ctl_env ) { + guard_cpu_ctl_env.set_env(); + curr_cpu_ctl_env = guard_cpu_ctl_env; + } +#endif + } +}; +#else +template <bool T> +struct context_guard_helper { + void set_ctx() {} + void restore_default() {} +}; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_scheduler_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler_common.h new file mode 100644 index 00000000..60a03798 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler_common.h @@ -0,0 +1,455 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_scheduler_common_H +#define _TBB_scheduler_common_H + +#include "tbb/tbb_machine.h" +#include "tbb/cache_aligned_allocator.h" + +#include <string.h> // for memset, memcpy, memmove + +#include "tbb_statistics.h" + +#if TBB_USE_ASSERT > 1 +#include <stdio.h> +#endif /* TBB_USE_ASSERT > 1 */ + +/* Temporarily change "private" to "public" while including "tbb/task.h". + This hack allows us to avoid publishing internal types and methods + in the public header files just for sake of friend declarations. */ +#ifndef private + #define private public + #define undef_private +#endif + +#include "tbb/task.h" +#include "tbb/tbb_exception.h" + +#ifdef undef_private + #undef private +#endif + +#ifndef __TBB_SCHEDULER_MUTEX_TYPE +#define __TBB_SCHEDULER_MUTEX_TYPE tbb::spin_mutex +#endif +// TODO: add conditional inclusion based on specified type +#include "tbb/spin_mutex.h" + +// This macro is an attempt to get rid of ugly ifdefs in the shared parts of the code. +// It drops the second argument depending on whether the controlling macro is defined. +// The first argument is just a convenience allowing to keep comma before the macro usage. +#if __TBB_TASK_GROUP_CONTEXT + #define __TBB_CONTEXT_ARG1(context) context + #define __TBB_CONTEXT_ARG(arg1, context) arg1, context +#else /* !__TBB_TASK_GROUP_CONTEXT */ + #define __TBB_CONTEXT_ARG1(context) + #define __TBB_CONTEXT_ARG(arg1, context) arg1 +#endif /* !__TBB_TASK_GROUP_CONTEXT */ + +#if __TBB_TASK_ISOLATION + #define __TBB_ISOLATION_EXPR(isolation) isolation + #define __TBB_ISOLATION_ARG(arg1, isolation) arg1, isolation +#else + #define __TBB_ISOLATION_EXPR(isolation) + #define __TBB_ISOLATION_ARG(arg1, isolation) arg1 +#endif /* __TBB_TASK_ISOLATION */ + + +#if DO_TBB_TRACE +#include <cstdio> +#define TBB_TRACE(x) ((void)std::printf x) +#else +#define TBB_TRACE(x) ((void)(0)) +#endif /* DO_TBB_TRACE */ + +#if !__TBB_CPU_CTL_ENV_PRESENT +#include <fenv.h> +#endif + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + // These particular warnings are so ubiquitous that no attempt is made to narrow + // the scope of the warnings. + #pragma warning (disable: 4100 4127 4312 4244 4267 4706) +#endif + +namespace tbb { +namespace interface7 { +namespace internal { +class task_arena_base; +class delegated_task; +class wait_task; +}} +namespace internal { +using namespace interface7::internal; + +class arena; +template<typename SchedulerTraits> class custom_scheduler; +class generic_scheduler; +class governor; +class mail_outbox; +class market; +class observer_proxy; +class task_scheduler_observer_v3; + +#if __TBB_TASK_PRIORITY +static const intptr_t num_priority_levels = 3; +static const intptr_t normalized_normal_priority = (num_priority_levels - 1) / 2; + +inline intptr_t normalize_priority ( priority_t p ) { + return intptr_t(p - priority_low) / priority_stride_v4; +} + +static const priority_t priority_from_normalized_rep[num_priority_levels] = { + priority_low, priority_normal, priority_high +}; + +inline void assert_priority_valid ( intptr_t p ) { + __TBB_ASSERT_EX( p >= 0 && p < num_priority_levels, NULL ); +} + +inline intptr_t& priority ( task& t ) { + return t.prefix().context->my_priority; +} +#else /* __TBB_TASK_PRIORITY */ +static const intptr_t num_priority_levels = 1; +#endif /* __TBB_TASK_PRIORITY */ + +//! Mutex type for global locks in the scheduler +typedef __TBB_SCHEDULER_MUTEX_TYPE scheduler_mutex_type; + +#if __TBB_TASK_GROUP_CONTEXT +//! Task group state change propagation global epoch +/** Together with generic_scheduler::my_context_state_propagation_epoch forms + cross-thread signaling mechanism that allows to avoid locking at the hot path + of normal execution flow. + + When a descendant task group context is registered or unregistered, the global + and local epochs are compared. If they differ, a state change is being propagated, + and thus registration/deregistration routines take slower branch that may block + (at most one thread of the pool can be blocked at any moment). Otherwise the + control path is lock-free and fast. **/ +extern uintptr_t the_context_state_propagation_epoch; + +//! Mutex guarding state change propagation across task groups forest. +/** Also protects modification of related data structures. **/ +typedef scheduler_mutex_type context_state_propagation_mutex_type; +extern context_state_propagation_mutex_type the_context_state_propagation_mutex; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +//! Alignment for a task object +const size_t task_alignment = 32; + +//! Number of bytes reserved for a task prefix +/** If not exactly sizeof(task_prefix), the extra bytes *precede* the task_prefix. */ +const size_t task_prefix_reservation_size = ((sizeof(internal::task_prefix)-1)/task_alignment+1)*task_alignment; + +//! Definitions for bits in task_prefix::extra_state +enum task_extra_state { + //! Tag for v1 tasks (i.e. tasks in TBB 1.0 and 2.0) + es_version_1_task = 0, + //! Tag for v3 tasks (i.e. tasks in TBB 2.1-2.2) + es_version_3_task = 1, +#if __TBB_PREVIEW_CRITICAL_TASKS + //! Tag for critical tasks + es_task_critical = 0x8, +#endif + //! Tag for enqueued tasks + es_task_enqueued = 0x10, + //! Tag for v3 task_proxy. + es_task_proxy = 0x20, + //! Set if ref_count might be changed by another thread. Used for debugging. + es_ref_count_active = 0x40, + //! Set if the task has been stolen + es_task_is_stolen = 0x80 +}; + +inline void reset_extra_state ( task *t ) { + t->prefix().extra_state &= ~(es_task_is_stolen | es_task_enqueued); +} + +//! Optimization hint to free_task that enables it omit unnecessary tests and code. +enum free_task_hint { + //! No hint + no_hint=0, + //! Task is known to have been allocated by this scheduler + local_task=1, + //! Task is known to be a small task. + /** Task should be returned to the free list of *some* scheduler, possibly not this scheduler. */ + small_task=2, + //! Bitwise-OR of local_task and small_task. + /** Task should be returned to free list of this scheduler. */ + small_local_task=3, + //! Disable caching for a small task. + no_cache = 4, + //! Task is known to be a small task and must not be cached. + no_cache_small_task = no_cache | small_task +}; + +//------------------------------------------------------------------------ +// Debugging support +//------------------------------------------------------------------------ + +#if TBB_USE_ASSERT + +static const uintptr_t venom = tbb::internal::select_size_t_constant<0xDEADBEEFU,0xDDEEAADDDEADBEEFULL>::value; + +template <typename T> +void poison_value ( T& val ) { val = * punned_cast<T*>(&venom); } + +/** Expected to be used in assertions only, thus no empty form is defined. **/ +inline bool is_alive( uintptr_t v ) { return v != venom; } + +/** Logically, this method should be a member of class task. + But we do not want to publish it, so it is here instead. */ +inline void assert_task_valid( const task* task ) { + __TBB_ASSERT( task!=NULL, NULL ); + __TBB_ASSERT( !is_poisoned(&task), NULL ); + __TBB_ASSERT( (uintptr_t)task % task_alignment == 0, "misaligned task" ); + __TBB_ASSERT( task->prefix().ref_count >= 0, NULL); +#if __TBB_RECYCLE_TO_ENQUEUE + __TBB_ASSERT( (unsigned)task->state()<=(unsigned)task::to_enqueue, "corrupt task (invalid state)" ); +#else + __TBB_ASSERT( (unsigned)task->state()<=(unsigned)task::recycle, "corrupt task (invalid state)" ); +#endif +} + +#else /* !TBB_USE_ASSERT */ + +/** In contrast to debug version poison_value() is a macro here because + the variable used as its argument may be undefined in release builds. **/ +#define poison_value(g) ((void)0) + +inline void assert_task_valid( const task* ) {} + +#endif /* !TBB_USE_ASSERT */ + +//------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------ + +#if __TBB_TASK_GROUP_CONTEXT +inline bool ConcurrentWaitsEnabled ( task& t ) { + return (t.prefix().context->my_version_and_traits & task_group_context::concurrent_wait) != 0; +} + +inline bool CancellationInfoPresent ( task& t ) { + return t.prefix().context->my_cancellation_requested != 0; +} + +#if TBB_USE_CAPTURED_EXCEPTION + inline tbb_exception* TbbCurrentException( task_group_context*, tbb_exception* src) { return src->move(); } + inline tbb_exception* TbbCurrentException( task_group_context* c, captured_exception* src) { + if( c->my_version_and_traits & task_group_context::exact_exception ) + runtime_warning( "Exact exception propagation is requested by application but the linked library is built without support for it"); + return src; + } + #define TbbRethrowException(TbbCapturedException) (TbbCapturedException)->throw_self() +#else + // Using macro instead of an inline function here allows to avoid evaluation of the + // TbbCapturedException expression when exact propagation is enabled for the context. + #define TbbCurrentException(context, TbbCapturedException) \ + context->my_version_and_traits & task_group_context::exact_exception \ + ? tbb_exception_ptr::allocate() \ + : tbb_exception_ptr::allocate( *(TbbCapturedException) ); + #define TbbRethrowException(TbbCapturedException) \ + { \ + if( governor::rethrow_exception_broken() ) fix_broken_rethrow(); \ + (TbbCapturedException)->throw_self(); \ + } +#endif /* !TBB_USE_CAPTURED_EXCEPTION */ + +#define TbbRegisterCurrentException(context, TbbCapturedException) \ + if ( context->cancel_group_execution() ) { \ + /* We are the first to signal cancellation, so store the exception that caused it. */ \ + context->my_exception = TbbCurrentException( context, TbbCapturedException ); \ + } + +#define TbbCatchAll(context) \ + catch ( tbb_exception& exc ) { \ + TbbRegisterCurrentException( context, &exc ); \ + } catch ( std::exception& exc ) { \ + TbbRegisterCurrentException( context, captured_exception::allocate(typeid(exc).name(), exc.what()) ); \ + } catch ( ... ) { \ + TbbRegisterCurrentException( context, captured_exception::allocate("...", "Unidentified exception") );\ + } + +#else /* !__TBB_TASK_GROUP_CONTEXT */ + +inline bool ConcurrentWaitsEnabled ( task& t ) { return false; } + +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +inline void prolonged_pause() { +#if defined(__TBB_time_stamp) && !__TBB_STEALING_PAUSE + // Assumption based on practice: 1000-2000 ticks seems to be a suitable invariant for the + // majority of platforms. Currently, skip platforms that define __TBB_STEALING_PAUSE + // because these platforms require very careful tuning. + machine_tsc_t prev = __TBB_time_stamp(); + const machine_tsc_t finish = prev + 1000; + atomic_backoff backoff; + do { + backoff.bounded_pause(); + machine_tsc_t curr = __TBB_time_stamp(); + if ( curr <= prev ) + // Possibly, the current logical thread is moved to another hardware thread or overflow is occurred. + break; + prev = curr; + } while ( prev < finish ); +#else +#ifdef __TBB_STEALING_PAUSE + static const long PauseTime = __TBB_STEALING_PAUSE; +#elif __TBB_ipf + static const long PauseTime = 1500; +#else + static const long PauseTime = 80; +#endif + // TODO IDEA: Update PauseTime adaptively? + __TBB_Pause(PauseTime); +#endif +} + +//------------------------------------------------------------------------ +// arena_slot +//------------------------------------------------------------------------ +struct arena_slot_line1 { + //TODO: make this tbb:atomic<>. + //! Scheduler of the thread attached to the slot + /** Marks the slot as busy, and is used to iterate through the schedulers belonging to this arena **/ + generic_scheduler* my_scheduler; + + // Synchronization of access to Task pool + /** Also is used to specify if the slot is empty or locked: + 0 - empty + -1 - locked **/ + task* *__TBB_atomic task_pool; + + //! Index of the first ready task in the deque. + /** Modified by thieves, and by the owner during compaction/reallocation **/ + __TBB_atomic size_t head; + +#if __TBB_PREVIEW_RESUMABLE_TASKS + //! The flag is raised when the original owner of the scheduler should return to this scheduler (for resume). + tbb::atomic<bool>* my_scheduler_is_recalled; +#endif +}; + +struct arena_slot_line2 { + //! Hint provided for operations with the container of starvation-resistant tasks. + /** Modified by the owner thread (during these operations). **/ + unsigned hint_for_pop; + +#if __TBB_PREVIEW_CRITICAL_TASKS + //! Similar to 'hint_for_pop' but for critical tasks. + unsigned hint_for_critical; +#endif + + //! Index of the element following the last ready task in the deque. + /** Modified by the owner thread. **/ + __TBB_atomic size_t tail; + + //! Capacity of the primary task pool (number of elements - pointers to task). + size_t my_task_pool_size; + + //! Task pool of the scheduler that owns this slot + task* *__TBB_atomic task_pool_ptr; + +#if __TBB_STATISTICS + //! Set of counters to accumulate internal statistics related to this arena + statistics_counters *my_counters; +#endif /* __TBB_STATISTICS */ +}; + +struct arena_slot : padded<arena_slot_line1>, padded<arena_slot_line2> { +#if TBB_USE_ASSERT + void fill_with_canary_pattern ( size_t first, size_t last ) { + for ( size_t i = first; i < last; ++i ) + poison_pointer(task_pool_ptr[i]); + } +#else + void fill_with_canary_pattern ( size_t, size_t ) {} +#endif /* TBB_USE_ASSERT */ + + void allocate_task_pool( size_t n ) { + size_t byte_size = ((n * sizeof(task*) + NFS_MaxLineSize - 1) / NFS_MaxLineSize) * NFS_MaxLineSize; + my_task_pool_size = byte_size / sizeof(task*); + task_pool_ptr = (task**)NFS_Allocate( 1, byte_size, NULL ); + // No need to clear the fresh deque since valid items are designated by the head and tail members. + // But fill it with a canary pattern in the high vigilance debug mode. + fill_with_canary_pattern( 0, my_task_pool_size ); + } + + //! Deallocate task pool that was allocated by means of allocate_task_pool. + void free_task_pool( ) { + // TODO: understand the assertion and modify + // __TBB_ASSERT( !task_pool /*TODO: == EmptyTaskPool*/, NULL); + if( task_pool_ptr ) { + __TBB_ASSERT( my_task_pool_size, NULL); + NFS_Free( task_pool_ptr ); + task_pool_ptr = NULL; + my_task_pool_size = 0; + } + } +}; + +#if !__TBB_CPU_CTL_ENV_PRESENT +class cpu_ctl_env { + fenv_t *my_fenv_ptr; +public: + cpu_ctl_env() : my_fenv_ptr(NULL) {} + ~cpu_ctl_env() { + if ( my_fenv_ptr ) + tbb::internal::NFS_Free( (void*)my_fenv_ptr ); + } + // It is possible not to copy memory but just to copy pointers but the following issues should be addressed: + // 1. The arena lifetime and the context lifetime are independent; + // 2. The user is allowed to recapture different FPU settings to context so 'current FPU settings' inside + // dispatch loop may become invalid. + // But do we really want to improve the fenv implementation? It seems to be better to replace the fenv implementation + // with a platform specific implementation. + cpu_ctl_env( const cpu_ctl_env &src ) : my_fenv_ptr(NULL) { + *this = src; + } + cpu_ctl_env& operator=( const cpu_ctl_env &src ) { + __TBB_ASSERT( src.my_fenv_ptr, NULL ); + if ( !my_fenv_ptr ) + my_fenv_ptr = (fenv_t*)tbb::internal::NFS_Allocate(1, sizeof(fenv_t), NULL); + *my_fenv_ptr = *src.my_fenv_ptr; + return *this; + } + bool operator!=( const cpu_ctl_env &ctl ) const { + __TBB_ASSERT( my_fenv_ptr, "cpu_ctl_env is not initialized." ); + __TBB_ASSERT( ctl.my_fenv_ptr, "cpu_ctl_env is not initialized." ); + return memcmp( (void*)my_fenv_ptr, (void*)ctl.my_fenv_ptr, sizeof(fenv_t) ); + } + void get_env () { + if ( !my_fenv_ptr ) + my_fenv_ptr = (fenv_t*)tbb::internal::NFS_Allocate(1, sizeof(fenv_t), NULL); + fegetenv( my_fenv_ptr ); + } + const cpu_ctl_env& set_env () const { + __TBB_ASSERT( my_fenv_ptr, "cpu_ctl_env is not initialized." ); + fesetenv( my_fenv_ptr ); + return *this; + } +}; +#endif /* !__TBB_CPU_CTL_ENV_PRESENT */ + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_scheduler_common_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler_utility.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler_utility.h new file mode 100644 index 00000000..790156b5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/scheduler_utility.h @@ -0,0 +1,129 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_scheduler_utility_H +#define _TBB_scheduler_utility_H + +#include "scheduler.h" + +namespace tbb { +namespace internal { + +//------------------------------------------------------------------------ +// auto_empty_task +//------------------------------------------------------------------------ + +//! Smart holder for the empty task class with automatic destruction +class auto_empty_task { + task* my_task; + generic_scheduler* my_scheduler; +public: + auto_empty_task ( __TBB_CONTEXT_ARG(generic_scheduler *s, task_group_context* context) ) + : my_task( new(&s->allocate_task(sizeof(empty_task), __TBB_CONTEXT_ARG(NULL, context))) empty_task ) + , my_scheduler(s) + {} + // empty_task has trivial destructor, so there's no need to call it. + ~auto_empty_task () { my_scheduler->free_task<small_local_task>(*my_task); } + + operator task& () { return *my_task; } + task* operator & () { return my_task; } + task_prefix& prefix () { return my_task->prefix(); } +}; // class auto_empty_task + +//------------------------------------------------------------------------ +// fast_reverse_vector +//------------------------------------------------------------------------ + +//! Vector that grows without reallocations, and stores items in the reverse order. +/** Requires to initialize its first segment with a preallocated memory chunk + (usually it is static array or an array allocated on the stack). + The second template parameter specifies maximal number of segments. Each next + segment is twice as large as the previous one. **/ +template<typename T, size_t max_segments = 16> +class fast_reverse_vector +{ +public: + fast_reverse_vector ( T* initial_segment, size_t segment_size ) + : m_cur_segment(initial_segment) + , m_cur_segment_size(segment_size) + , m_pos(segment_size) + , m_num_segments(0) + , m_size(0) + { + __TBB_ASSERT ( initial_segment && segment_size, "Nonempty initial segment must be supplied"); + } + + ~fast_reverse_vector () + { + for ( size_t i = 1; i < m_num_segments; ++i ) + NFS_Free( m_segments[i] ); + } + + size_t size () const { return m_size + m_cur_segment_size - m_pos; } + + void push_back ( const T& val ) + { + if ( !m_pos ) { + if ( !m_num_segments ) m_segments[m_num_segments++] = m_cur_segment; + m_size += m_cur_segment_size; + m_cur_segment_size *= 2; + m_pos = m_cur_segment_size; + m_segments[m_num_segments++] = m_cur_segment = (T*)NFS_Allocate( m_cur_segment_size, sizeof(T), NULL ); + __TBB_ASSERT ( m_num_segments < max_segments, "Maximal capacity exceeded" ); + } + m_cur_segment[--m_pos] = val; + } + + //! Copies the contents of the vector into the dst array. + /** Can only be used when T is a POD type, as copying does not invoke copy constructors. **/ + void copy_memory ( T* dst ) const + { + size_t sz = m_cur_segment_size - m_pos; + memcpy( dst, m_cur_segment + m_pos, sz * sizeof(T) ); + dst += sz; + sz = m_cur_segment_size / 2; + for ( long i = (long)m_num_segments - 2; i >= 0; --i ) { + memcpy( dst, m_segments[i], sz * sizeof(T) ); + dst += sz; + sz /= 2; + } + } + +protected: + //! The current (not completely filled) segment + T *m_cur_segment; + + //! Capacity of m_cur_segment + size_t m_cur_segment_size; + + //! Insertion position in m_cur_segment + size_t m_pos; + + //! Array of segments (has fixed size specified by the second template parameter) + T *m_segments[max_segments]; + + //! Number of segments (the size of m_segments) + size_t m_num_segments; + + //! Number of items in the segments in m_segments + size_t m_size; + +}; // class fast_reverse_vector + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_scheduler_utility_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/semaphore.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/semaphore.cpp new file mode 100644 index 00000000..ae7f4d5a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/semaphore.cpp @@ -0,0 +1,90 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "semaphore.h" +#if __TBB_USE_SRWLOCK +#include "dynamic_link.h" // Refers to src/tbb, not include/tbb +#include "tbb_misc.h" +#endif + +namespace tbb { +namespace internal { + +// TODO: For new win UI port, we can use SRWLock API without dynamic_link etc. +#if __TBB_USE_SRWLOCK + +static atomic<do_once_state> concmon_module_inited; + +void WINAPI init_binsem_using_event( SRWLOCK* h_ ) +{ + srwl_or_handle* shptr = (srwl_or_handle*) h_; + shptr->h = CreateEventEx( NULL, NULL, 0, EVENT_ALL_ACCESS|SEMAPHORE_ALL_ACCESS ); +} + +void WINAPI acquire_binsem_using_event( SRWLOCK* h_ ) +{ + srwl_or_handle* shptr = (srwl_or_handle*) h_; + WaitForSingleObjectEx( shptr->h, INFINITE, FALSE ); +} + +void WINAPI release_binsem_using_event( SRWLOCK* h_ ) +{ + srwl_or_handle* shptr = (srwl_or_handle*) h_; + SetEvent( shptr->h ); +} + +static void (WINAPI *__TBB_init_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&init_binsem_using_event; +static void (WINAPI *__TBB_acquire_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&acquire_binsem_using_event; +static void (WINAPI *__TBB_release_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&release_binsem_using_event; + +//! Table describing the how to link the handlers. +static const dynamic_link_descriptor SRWLLinkTable[] = { + DLD(InitializeSRWLock, __TBB_init_binsem), + DLD(AcquireSRWLockExclusive, __TBB_acquire_binsem), + DLD(ReleaseSRWLockExclusive, __TBB_release_binsem) +}; + +inline void init_concmon_module() +{ + __TBB_ASSERT( (uintptr_t)__TBB_init_binsem==(uintptr_t)&init_binsem_using_event, NULL ); + if( dynamic_link( "Kernel32.dll", SRWLLinkTable, sizeof(SRWLLinkTable)/sizeof(dynamic_link_descriptor) ) ) { + __TBB_ASSERT( (uintptr_t)__TBB_init_binsem!=(uintptr_t)&init_binsem_using_event, NULL ); + __TBB_ASSERT( (uintptr_t)__TBB_acquire_binsem!=(uintptr_t)&acquire_binsem_using_event, NULL ); + __TBB_ASSERT( (uintptr_t)__TBB_release_binsem!=(uintptr_t)&release_binsem_using_event, NULL ); + } +} + +binary_semaphore::binary_semaphore() { + atomic_do_once( &init_concmon_module, concmon_module_inited ); + + __TBB_init_binsem( &my_sem.lock ); + if( (uintptr_t)__TBB_init_binsem!=(uintptr_t)&init_binsem_using_event ) + P(); +} + +binary_semaphore::~binary_semaphore() { + if( (uintptr_t)__TBB_init_binsem==(uintptr_t)&init_binsem_using_event ) + CloseHandle( my_sem.h ); +} + +void binary_semaphore::P() { __TBB_acquire_binsem( &my_sem.lock ); } + +void binary_semaphore::V() { __TBB_release_binsem( &my_sem.lock ); } + +#endif /* __TBB_USE_SRWLOCK */ + +} // namespace internal +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/semaphore.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/semaphore.h new file mode 100644 index 00000000..0545b95a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/semaphore.h @@ -0,0 +1,250 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbb_semaphore_H +#define __TBB_tbb_semaphore_H + +#include <tbb/atomic.h> +#include "tbb/tbb_stddef.h" + +#if _WIN32||_WIN64 +#include "tbb/machine/windows_api.h" + +#elif __APPLE__ +#include <mach/semaphore.h> +#include <mach/task.h> +#include <mach/mach_init.h> +#include <mach/error.h> + +#else +#include <semaphore.h> +#ifdef TBB_USE_DEBUG +#include <errno.h> +#endif +#endif /*_WIN32||_WIN64*/ + +namespace tbb { +namespace internal { + + +#if _WIN32||_WIN64 +typedef LONG sem_count_t; +//! Edsger Dijkstra's counting semaphore +class semaphore : no_copy { + static const int max_semaphore_cnt = MAXLONG; +public: + //! ctor + semaphore(size_t start_cnt_ = 0) {init_semaphore(start_cnt_);} + //! dtor + ~semaphore() {CloseHandle( sem );} + //! wait/acquire + void P() {WaitForSingleObjectEx( sem, INFINITE, FALSE );} + //! post/release + void V() {ReleaseSemaphore( sem, 1, NULL );} +private: + HANDLE sem; + void init_semaphore(size_t start_cnt_) { + sem = CreateSemaphoreEx( NULL, LONG(start_cnt_), max_semaphore_cnt, NULL, 0, SEMAPHORE_ALL_ACCESS ); + } +}; +#elif __APPLE__ +//! Edsger Dijkstra's counting semaphore +class semaphore : no_copy { +public: + //! ctor + semaphore(int start_cnt_ = 0) : sem(start_cnt_) { init_semaphore(start_cnt_); } + //! dtor + ~semaphore() { + kern_return_t ret = semaphore_destroy( mach_task_self(), sem ); + __TBB_ASSERT_EX( ret==err_none, NULL ); + } + //! wait/acquire + void P() { + int ret; + do { + ret = semaphore_wait( sem ); + } while( ret==KERN_ABORTED ); + __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" ); + } + //! post/release + void V() { semaphore_signal( sem ); } +private: + semaphore_t sem; + void init_semaphore(int start_cnt_) { + kern_return_t ret = semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, start_cnt_ ); + __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" ); + } +}; +#else /* Linux/Unix */ +typedef uint32_t sem_count_t; +//! Edsger Dijkstra's counting semaphore +class semaphore : no_copy { +public: + //! ctor + semaphore(int start_cnt_ = 0 ) { init_semaphore( start_cnt_ ); } + + //! dtor + ~semaphore() { + int ret = sem_destroy( &sem ); + __TBB_ASSERT_EX( !ret, NULL ); + } + //! wait/acquire + void P() { + while( sem_wait( &sem )!=0 ) + __TBB_ASSERT( errno==EINTR, NULL ); + } + //! post/release + void V() { sem_post( &sem ); } +private: + sem_t sem; + void init_semaphore(int start_cnt_) { + int ret = sem_init( &sem, /*shared among threads*/ 0, start_cnt_ ); + __TBB_ASSERT_EX( !ret, NULL ); + } +}; +#endif /* _WIN32||_WIN64 */ + + +//! for performance reasons, we want specialized binary_semaphore +#if _WIN32||_WIN64 +#if !__TBB_USE_SRWLOCK +//! binary_semaphore for concurrent_monitor +class binary_semaphore : no_copy { +public: + //! ctor + binary_semaphore() { my_sem = CreateEventEx( NULL, NULL, 0, EVENT_ALL_ACCESS ); } + //! dtor + ~binary_semaphore() { CloseHandle( my_sem ); } + //! wait/acquire + void P() { WaitForSingleObjectEx( my_sem, INFINITE, FALSE ); } + //! post/release + void V() { SetEvent( my_sem ); } +private: + HANDLE my_sem; +}; +#else /* __TBB_USE_SRWLOCK */ + +union srwl_or_handle { + SRWLOCK lock; + HANDLE h; +}; + +//! binary_semaphore for concurrent_monitor +class binary_semaphore : no_copy { +public: + //! ctor + binary_semaphore(); + //! dtor + ~binary_semaphore(); + //! wait/acquire + void P(); + //! post/release + void V(); +private: + srwl_or_handle my_sem; +}; +#endif /* !__TBB_USE_SRWLOCK */ +#elif __APPLE__ +//! binary_semaphore for concurrent monitor +class binary_semaphore : no_copy { +public: + //! ctor + binary_semaphore() : my_sem(0) { + kern_return_t ret = semaphore_create( mach_task_self(), &my_sem, SYNC_POLICY_FIFO, 0 ); + __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" ); + } + //! dtor + ~binary_semaphore() { + kern_return_t ret = semaphore_destroy( mach_task_self(), my_sem ); + __TBB_ASSERT_EX( ret==err_none, NULL ); + } + //! wait/acquire + void P() { + int ret; + do { + ret = semaphore_wait( my_sem ); + } while( ret==KERN_ABORTED ); + __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" ); + } + //! post/release + void V() { semaphore_signal( my_sem ); } +private: + semaphore_t my_sem; +}; +#else /* Linux/Unix */ + +#if __TBB_USE_FUTEX +class binary_semaphore : no_copy { +// The implementation is equivalent to the "Mutex, Take 3" one +// in the paper "Futexes Are Tricky" by Ulrich Drepper +public: + //! ctor + binary_semaphore() { my_sem = 1; } + //! dtor + ~binary_semaphore() {} + //! wait/acquire + void P() { + int s; + if( (s = my_sem.compare_and_swap( 1, 0 ))!=0 ) { + if( s!=2 ) + s = my_sem.fetch_and_store( 2 ); + while( s!=0 ) { // This loop deals with spurious wakeup + futex_wait( &my_sem, 2 ); + s = my_sem.fetch_and_store( 2 ); + } + } + } + //! post/release + void V() { + __TBB_ASSERT( my_sem>=1, "multiple V()'s in a row?" ); + if( my_sem.fetch_and_store( 0 )==2 ) + futex_wakeup_one( &my_sem ); + } +private: + atomic<int> my_sem; // 0 - open; 1 - closed, no waits; 2 - closed, possible waits +}; +#else +typedef uint32_t sem_count_t; +//! binary_semaphore for concurrent monitor +class binary_semaphore : no_copy { +public: + //! ctor + binary_semaphore() { + int ret = sem_init( &my_sem, /*shared among threads*/ 0, 0 ); + __TBB_ASSERT_EX( !ret, NULL ); + } + //! dtor + ~binary_semaphore() { + int ret = sem_destroy( &my_sem ); + __TBB_ASSERT_EX( !ret, NULL ); + } + //! wait/acquire + void P() { + while( sem_wait( &my_sem )!=0 ) + __TBB_ASSERT( errno==EINTR, NULL ); + } + //! post/release + void V() { sem_post( &my_sem ); } +private: + sem_t my_sem; +}; +#endif /* __TBB_USE_FUTEX */ +#endif /* _WIN32||_WIN64 */ + +} // namespace internal +} // namespace tbb + +#endif /* __TBB_tbb_semaphore_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/spin_mutex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/spin_mutex.cpp new file mode 100644 index 00000000..efe1dcc1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/spin_mutex.cpp @@ -0,0 +1,54 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_machine.h" +#include "tbb/spin_mutex.h" +#include "itt_notify.h" +#include "tbb_misc.h" + +namespace tbb { + +void spin_mutex::scoped_lock::internal_acquire( spin_mutex& m ) { + __TBB_ASSERT( !my_mutex, "already holding a lock on a spin_mutex" ); + ITT_NOTIFY(sync_prepare, &m); + __TBB_LockByte(m.flag); + my_mutex = &m; + ITT_NOTIFY(sync_acquired, &m); +} + +void spin_mutex::scoped_lock::internal_release() { + __TBB_ASSERT( my_mutex, "release on spin_mutex::scoped_lock that is not holding a lock" ); + + ITT_NOTIFY(sync_releasing, my_mutex); + __TBB_UnlockByte(my_mutex->flag); + my_mutex = NULL; +} + +bool spin_mutex::scoped_lock::internal_try_acquire( spin_mutex& m ) { + __TBB_ASSERT( !my_mutex, "already holding a lock on a spin_mutex" ); + bool result = bool( __TBB_TryLockByte(m.flag) ); + if( result ) { + my_mutex = &m; + ITT_NOTIFY(sync_acquired, &m); + } + return result; +} + +void spin_mutex::internal_construct() { + ITT_SYNC_CREATE(this, _T("tbb::spin_mutex"), _T("")); +} + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/spin_rw_mutex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/spin_rw_mutex.cpp new file mode 100644 index 00000000..e033f12c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/spin_rw_mutex.cpp @@ -0,0 +1,155 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/spin_rw_mutex.h" +#include "tbb/tbb_machine.h" +#include "tbb/atomic.h" +#include "itt_notify.h" + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4244) +#endif + +namespace tbb { + +template<typename T> // a template can work with private spin_rw_mutex::state_t +static inline T CAS(volatile T &addr, T newv, T oldv) { + // ICC (9.1 and 10.1 tried) unable to do implicit conversion + // from "volatile T*" to "volatile void*", so explicit cast added. + return tbb::internal::as_atomic(addr).compare_and_swap( newv, oldv ); +} + +//! Acquire write lock on the given mutex. +bool spin_rw_mutex_v3::internal_acquire_writer() +{ + ITT_NOTIFY(sync_prepare, this); + for( internal::atomic_backoff backoff;;backoff.pause() ){ + state_t s = const_cast<volatile state_t&>(state); // ensure reloading + if( !(s & BUSY) ) { // no readers, no writers + if( CAS(state, WRITER, s)==s ) + break; // successfully stored writer flag + backoff.reset(); // we could be very close to complete op. + } else if( !(s & WRITER_PENDING) ) { // no pending writers + __TBB_AtomicOR(&state, WRITER_PENDING); + } + } + ITT_NOTIFY(sync_acquired, this); + return false; +} + +//! Release writer lock on the given mutex +void spin_rw_mutex_v3::internal_release_writer() +{ + ITT_NOTIFY(sync_releasing, this); + __TBB_AtomicAND( &state, READERS ); +} + +//! Acquire read lock on given mutex. +void spin_rw_mutex_v3::internal_acquire_reader() +{ + ITT_NOTIFY(sync_prepare, this); + for( internal::atomic_backoff b;;b.pause() ){ + state_t s = const_cast<volatile state_t&>(state); // ensure reloading + if( !(s & (WRITER|WRITER_PENDING)) ) { // no writer or write requests + state_t t = (state_t)__TBB_FetchAndAddW( &state, (intptr_t) ONE_READER ); + if( !( t&WRITER )) + break; // successfully stored increased number of readers + // writer got there first, undo the increment + __TBB_FetchAndAddW( &state, -(intptr_t)ONE_READER ); + } + } + + ITT_NOTIFY(sync_acquired, this); + __TBB_ASSERT( state & READERS, "invalid state of a read lock: no readers" ); +} + +//! Upgrade reader to become a writer. +/** Returns whether the upgrade happened without releasing and re-acquiring the lock */ +bool spin_rw_mutex_v3::internal_upgrade() +{ + state_t s = state; + __TBB_ASSERT( s & READERS, "invalid state before upgrade: no readers " ); + // check and set writer-pending flag + // required conditions: either no pending writers, or we are the only reader + // (with multiple readers and pending writer, another upgrade could have been requested) + while( (s & READERS)==ONE_READER || !(s & WRITER_PENDING) ) { + state_t old_s = s; + if( (s=CAS(state, s | WRITER | WRITER_PENDING, s))==old_s ) { + ITT_NOTIFY(sync_prepare, this); + internal::atomic_backoff backoff; + while( (state & READERS) != ONE_READER ) backoff.pause(); + __TBB_ASSERT((state&(WRITER_PENDING|WRITER))==(WRITER_PENDING|WRITER),"invalid state when upgrading to writer"); + // both new readers and writers are blocked at this time + __TBB_FetchAndAddW( &state, - (intptr_t)(ONE_READER+WRITER_PENDING)); + ITT_NOTIFY(sync_acquired, this); + return true; // successfully upgraded + } + } + // slow reacquire + internal_release_reader(); + return internal_acquire_writer(); // always returns false +} + +//! Downgrade writer to a reader +void spin_rw_mutex_v3::internal_downgrade() { + ITT_NOTIFY(sync_releasing, this); + __TBB_FetchAndAddW( &state, (intptr_t)(ONE_READER-WRITER)); + __TBB_ASSERT( state & READERS, "invalid state after downgrade: no readers" ); +} + +//! Release read lock on the given mutex +void spin_rw_mutex_v3::internal_release_reader() +{ + __TBB_ASSERT( state & READERS, "invalid state of a read lock: no readers" ); + ITT_NOTIFY(sync_releasing, this); // release reader + __TBB_FetchAndAddWrelease( &state,-(intptr_t)ONE_READER); +} + +//! Try to acquire write lock on the given mutex +bool spin_rw_mutex_v3::internal_try_acquire_writer() +{ + // for a writer: only possible to acquire if no active readers or writers + state_t s = state; + if( !(s & BUSY) ) // no readers, no writers; mask is 1..1101 + if( CAS(state, WRITER, s)==s ) { + ITT_NOTIFY(sync_acquired, this); + return true; // successfully stored writer flag + } + return false; +} + +//! Try to acquire read lock on the given mutex +bool spin_rw_mutex_v3::internal_try_acquire_reader() +{ + // for a reader: acquire if no active or waiting writers + state_t s = state; + if( !(s & (WRITER|WRITER_PENDING)) ) { // no writers + state_t t = (state_t)__TBB_FetchAndAddW( &state, (intptr_t) ONE_READER ); + if( !( t&WRITER )) { // got the lock + ITT_NOTIFY(sync_acquired, this); + return true; // successfully stored increased number of readers + } + // writer got there first, undo the increment + __TBB_FetchAndAddW( &state, -(intptr_t)ONE_READER ); + } + return false; +} + +void spin_rw_mutex_v3::internal_construct() { + ITT_SYNC_CREATE(this, _T("tbb::spin_rw_mutex"), _T("")); +} +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task.cpp new file mode 100644 index 00000000..70fdc7e1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task.cpp @@ -0,0 +1,271 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Do not include task.h directly. Use scheduler_common.h instead +#include "scheduler_common.h" +#include "governor.h" +#include "scheduler.h" +#include "itt_notify.h" + +#include "tbb/cache_aligned_allocator.h" +#include "tbb/partitioner.h" + +#include <new> + +namespace tbb { + +namespace internal { + +//------------------------------------------------------------------------ +// Methods of allocate_root_proxy +//------------------------------------------------------------------------ +task& allocate_root_proxy::allocate( size_t size ) { + internal::generic_scheduler* v = governor::local_scheduler_weak(); + __TBB_ASSERT( v, "thread did not activate a task_scheduler_init object?" ); +#if __TBB_TASK_GROUP_CONTEXT + task_prefix& p = v->my_innermost_running_task->prefix(); + + ITT_STACK_CREATE(p.context->itt_caller); +#endif + // New root task becomes part of the currently running task's cancellation context + return v->allocate_task( size, __TBB_CONTEXT_ARG(NULL, p.context) ); +} + +void allocate_root_proxy::free( task& task ) { + internal::generic_scheduler* v = governor::local_scheduler_weak(); + __TBB_ASSERT( v, "thread does not have initialized task_scheduler_init object?" ); +#if __TBB_TASK_GROUP_CONTEXT + // No need to do anything here as long as there is no context -> task connection +#endif /* __TBB_TASK_GROUP_CONTEXT */ + v->free_task<local_task>( task ); +} + +#if __TBB_TASK_GROUP_CONTEXT +//------------------------------------------------------------------------ +// Methods of allocate_root_with_context_proxy +//------------------------------------------------------------------------ +task& allocate_root_with_context_proxy::allocate( size_t size ) const { + internal::generic_scheduler* s = governor::local_scheduler_weak(); + __TBB_ASSERT( s, "Scheduler auto-initialization failed?" ); + __TBB_ASSERT( &my_context, "allocate_root(context) argument is a dereferenced NULL pointer" ); + task& t = s->allocate_task( size, NULL, &my_context ); + // Supported usage model prohibits concurrent initial binding. Thus we do not + // need interlocked operations or fences to manipulate with my_context.my_kind + if ( __TBB_load_relaxed(my_context.my_kind) == task_group_context::binding_required ) { + // If we are in the outermost task dispatch loop of a master thread, then + // there is nothing to bind this context to, and we skip the binding part + // treating the context as isolated. + if ( s->master_outermost_level() ) + __TBB_store_relaxed(my_context.my_kind, task_group_context::isolated); + else + my_context.bind_to( s ); + } +#if __TBB_FP_CONTEXT + if ( __TBB_load_relaxed(my_context.my_kind) == task_group_context::isolated && + !(my_context.my_version_and_traits & task_group_context::fp_settings) ) + my_context.copy_fp_settings( *s->default_context() ); +#endif + ITT_STACK_CREATE(my_context.itt_caller); + return t; +} + +void allocate_root_with_context_proxy::free( task& task ) const { + internal::generic_scheduler* v = governor::local_scheduler_weak(); + __TBB_ASSERT( v, "thread does not have initialized task_scheduler_init object?" ); + // No need to do anything here as long as unbinding is performed by context destructor only. + v->free_task<local_task>( task ); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +//------------------------------------------------------------------------ +// Methods of allocate_continuation_proxy +//------------------------------------------------------------------------ +task& allocate_continuation_proxy::allocate( size_t size ) const { + task* t = (task*)this; + assert_task_valid(t); + generic_scheduler* s = governor::local_scheduler_weak(); + task* parent = t->parent(); + t->prefix().parent = NULL; + return s->allocate_task( size, __TBB_CONTEXT_ARG(parent, t->prefix().context) ); +} + +void allocate_continuation_proxy::free( task& mytask ) const { + // Restore the parent as it was before the corresponding allocate was called. + ((task*)this)->prefix().parent = mytask.parent(); + governor::local_scheduler_weak()->free_task<local_task>(mytask); +} + +//------------------------------------------------------------------------ +// Methods of allocate_child_proxy +//------------------------------------------------------------------------ +task& allocate_child_proxy::allocate( size_t size ) const { + task* t = (task*)this; + assert_task_valid(t); + generic_scheduler* s = governor::local_scheduler_weak(); + return s->allocate_task( size, __TBB_CONTEXT_ARG(t, t->prefix().context) ); +} + +void allocate_child_proxy::free( task& mytask ) const { + governor::local_scheduler_weak()->free_task<local_task>(mytask); +} + +//------------------------------------------------------------------------ +// Methods of allocate_additional_child_of_proxy +//------------------------------------------------------------------------ +task& allocate_additional_child_of_proxy::allocate( size_t size ) const { + parent.increment_ref_count(); + generic_scheduler* s = governor::local_scheduler_weak(); + return s->allocate_task( size, __TBB_CONTEXT_ARG(&parent, parent.prefix().context) ); +} + +void allocate_additional_child_of_proxy::free( task& task ) const { + // Undo the increment. We do not check the result of the fetch-and-decrement. + // We could consider be spawning the task if the fetch-and-decrement returns 1. + // But we do not know that was the programmer's intention. + // Furthermore, if it was the programmer's intention, the program has a fundamental + // race condition (that we warn about in Reference manual), because the + // reference count might have become zero before the corresponding call to + // allocate_additional_child_of_proxy::allocate. + parent.internal_decrement_ref_count(); + governor::local_scheduler_weak()->free_task<local_task>(task); +} + +//------------------------------------------------------------------------ +// Support for auto_partitioner +//------------------------------------------------------------------------ +size_t get_initial_auto_partitioner_divisor() { + const size_t X_FACTOR = 4; + return X_FACTOR * governor::local_scheduler()->max_threads_in_arena(); +} + +//------------------------------------------------------------------------ +// Methods of affinity_partitioner_base_v3 +//------------------------------------------------------------------------ +void affinity_partitioner_base_v3::resize( unsigned factor ) { + // Check factor to avoid asking for number of workers while there might be no arena. + size_t new_size = factor ? factor*governor::local_scheduler()->max_threads_in_arena() : 0; + if( new_size!=my_size ) { + if( my_array ) { + NFS_Free( my_array ); + // Following two assignments must be done here for sake of exception safety. + my_array = NULL; + my_size = 0; + } + if( new_size ) { + my_array = static_cast<affinity_id*>(NFS_Allocate(new_size,sizeof(affinity_id), NULL )); + memset( my_array, 0, sizeof(affinity_id)*new_size ); + my_size = new_size; + } + } +} + +} // namespace internal + +using namespace tbb::internal; + +//------------------------------------------------------------------------ +// task +//------------------------------------------------------------------------ + +void task::internal_set_ref_count( int count ) { + __TBB_ASSERT( count>=0, "count must not be negative" ); + task_prefix &p = prefix(); + __TBB_ASSERT(p.ref_count==1 && p.state==allocated && self().parent()==this + || !(p.extra_state & es_ref_count_active), "ref_count race detected"); + ITT_NOTIFY(sync_releasing, &p.ref_count); + p.ref_count = count; +} + +internal::reference_count task::internal_decrement_ref_count() { + ITT_NOTIFY( sync_releasing, &prefix().ref_count ); + internal::reference_count k = __TBB_FetchAndDecrementWrelease( &prefix().ref_count ); + __TBB_ASSERT( k>=1, "task's reference count underflowed" ); + if( k==1 ) + ITT_NOTIFY( sync_acquired, &prefix().ref_count ); + return k-1; +} + +task& task::self() { + generic_scheduler *v = governor::local_scheduler_weak(); + v->assert_task_pool_valid(); + __TBB_ASSERT( v->my_innermost_running_task, NULL ); + return *v->my_innermost_running_task; +} + +bool task::is_owned_by_current_thread() const { + return true; +} + +void interface5::internal::task_base::destroy( task& victim ) { + // 1 may be a guard reference for wait_for_all, which was not reset because + // of concurrent_wait mode or because prepared root task was not actually used + // for spawning tasks (as in structured_task_group). + __TBB_ASSERT( (intptr_t)victim.prefix().ref_count <= 1, "Task being destroyed must not have children" ); + __TBB_ASSERT( victim.state()==task::allocated, "illegal state for victim task" ); + task* parent = victim.parent(); + victim.~task(); + if( parent ) { + __TBB_ASSERT( parent->state()!=task::freed && parent->state()!=task::ready, + "attempt to destroy child of running or corrupted parent?" ); + // 'reexecute' and 'executing' are also signs of a race condition, since most tasks + // set their ref_count upon entry but "es_ref_count_active" should detect this + parent->internal_decrement_ref_count(); + // Even if the last reference to *parent is removed, it should not be spawned (documented behavior). + } + governor::local_scheduler_weak()->free_task<no_cache>( victim ); +} + +void task::spawn_and_wait_for_all( task_list& list ) { + generic_scheduler* s = governor::local_scheduler(); + task* t = list.first; + if( t ) { + if( &t->prefix().next!=list.next_ptr ) + s->local_spawn( t->prefix().next, *list.next_ptr ); + list.clear(); + } + s->local_wait_for_all( *this, t ); +} + +/** Defined out of line so that compiler does not replicate task's vtable. + It's pointless to define it inline anyway, because all call sites to it are virtual calls + that the compiler is unlikely to optimize. */ +void task::note_affinity( affinity_id ) { +} + +#if __TBB_TASK_GROUP_CONTEXT +void task::change_group ( task_group_context& ctx ) { + prefix().context = &ctx; + internal::generic_scheduler* s = governor::local_scheduler_weak(); + if ( __TBB_load_relaxed(ctx.my_kind) == task_group_context::binding_required ) { + // If we are in the outermost task dispatch loop of a master thread, then + // there is nothing to bind this context to, and we skip the binding part + // treating the context as isolated. + if ( s->master_outermost_level() ) + __TBB_store_relaxed(ctx.my_kind, task_group_context::isolated); + else + ctx.bind_to( s ); + } +#if __TBB_FP_CONTEXT + if ( __TBB_load_relaxed(ctx.my_kind) == task_group_context::isolated && + !(ctx.my_version_and_traits & task_group_context::fp_settings) ) + ctx.copy_fp_settings( *s->default_context() ); +#endif + ITT_STACK_CREATE(ctx.itt_caller); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +} // namespace tbb + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_group_context.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_group_context.cpp new file mode 100644 index 00000000..910d54e5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_group_context.cpp @@ -0,0 +1,493 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "scheduler.h" + +#include "itt_notify.h" + +namespace tbb { + +#if __TBB_TASK_GROUP_CONTEXT + +using namespace internal; + +//------------------------------------------------------------------------ +// captured_exception +//------------------------------------------------------------------------ + +inline char* duplicate_string ( const char* src ) { + char* dst = NULL; + if ( src ) { + size_t len = strlen(src) + 1; + dst = (char*)allocate_via_handler_v3(len); + strncpy (dst, src, len); + } + return dst; +} + +captured_exception::~captured_exception () throw() { + clear(); +} + +void captured_exception::set ( const char* a_name, const char* info ) throw() { + my_exception_name = duplicate_string( a_name ); + my_exception_info = duplicate_string( info ); +} + +void captured_exception::clear () throw() { + deallocate_via_handler_v3 (const_cast<char*>(my_exception_name)); + deallocate_via_handler_v3 (const_cast<char*>(my_exception_info)); +} + +captured_exception* captured_exception::move () throw() { + captured_exception *e = (captured_exception*)allocate_via_handler_v3(sizeof(captured_exception)); + if ( e ) { + ::new (e) captured_exception(); + e->my_exception_name = my_exception_name; + e->my_exception_info = my_exception_info; + e->my_dynamic = true; + my_exception_name = my_exception_info = NULL; + } + return e; +} + +void captured_exception::destroy () throw() { + __TBB_ASSERT ( my_dynamic, "Method destroy can be used only on objects created by clone or allocate" ); + if ( my_dynamic ) { + this->captured_exception::~captured_exception(); + deallocate_via_handler_v3 (this); + } +} + +captured_exception* captured_exception::allocate ( const char* a_name, const char* info ) { + captured_exception *e = (captured_exception*)allocate_via_handler_v3( sizeof(captured_exception) ); + if ( e ) { + ::new (e) captured_exception(a_name, info); + e->my_dynamic = true; + } + return e; +} + +const char* captured_exception::name() const throw() { + return my_exception_name; +} + +const char* captured_exception::what() const throw() { + return my_exception_info; +} + + +//------------------------------------------------------------------------ +// tbb_exception_ptr +//------------------------------------------------------------------------ + +#if !TBB_USE_CAPTURED_EXCEPTION + +namespace internal { + +template<typename T> +tbb_exception_ptr* AllocateExceptionContainer( const T& src ) { + tbb_exception_ptr *eptr = (tbb_exception_ptr*)allocate_via_handler_v3( sizeof(tbb_exception_ptr) ); + if ( eptr ) + new (eptr) tbb_exception_ptr(src); + return eptr; +} + +tbb_exception_ptr* tbb_exception_ptr::allocate () { + return AllocateExceptionContainer( std::current_exception() ); +} + +tbb_exception_ptr* tbb_exception_ptr::allocate ( const tbb_exception& ) { + return AllocateExceptionContainer( std::current_exception() ); +} + +tbb_exception_ptr* tbb_exception_ptr::allocate ( captured_exception& src ) { + tbb_exception_ptr *res = AllocateExceptionContainer( src ); + src.destroy(); + return res; +} + +void tbb_exception_ptr::destroy () throw() { + this->tbb_exception_ptr::~tbb_exception_ptr(); + deallocate_via_handler_v3 (this); +} + +} // namespace internal +#endif /* !TBB_USE_CAPTURED_EXCEPTION */ + + +//------------------------------------------------------------------------ +// task_group_context +//------------------------------------------------------------------------ + +task_group_context::~task_group_context () { + if ( __TBB_load_relaxed(my_kind) == binding_completed ) { + if ( governor::is_set(my_owner) ) { + // Local update of the context list + uintptr_t local_count_snapshot = my_owner->my_context_state_propagation_epoch; + my_owner->my_local_ctx_list_update.store<relaxed>(1); + // Prevent load of nonlocal update flag from being hoisted before the + // store to local update flag. + atomic_fence(); + if ( my_owner->my_nonlocal_ctx_list_update.load<relaxed>() ) { + spin_mutex::scoped_lock lock(my_owner->my_context_list_mutex); + my_node.my_prev->my_next = my_node.my_next; + my_node.my_next->my_prev = my_node.my_prev; + my_owner->my_local_ctx_list_update.store<relaxed>(0); + } + else { + my_node.my_prev->my_next = my_node.my_next; + my_node.my_next->my_prev = my_node.my_prev; + // Release fence is necessary so that update of our neighbors in + // the context list was committed when possible concurrent destroyer + // proceeds after local update flag is reset by the following store. + my_owner->my_local_ctx_list_update.store<release>(0); + if ( local_count_snapshot != the_context_state_propagation_epoch ) { + // Another thread was propagating cancellation request when we removed + // ourselves from the list. We must ensure that it is not accessing us + // when this destructor finishes. We'll be able to acquire the lock + // below only after the other thread finishes with us. + spin_mutex::scoped_lock lock(my_owner->my_context_list_mutex); + } + } + } + else { + // Nonlocal update of the context list + // Synchronizes with generic_scheduler::cleanup_local_context_list() + // TODO: evaluate and perhaps relax, or add some lock instead + if ( internal::as_atomic(my_kind).fetch_and_store(dying) == detached ) { + my_node.my_prev->my_next = my_node.my_next; + my_node.my_next->my_prev = my_node.my_prev; + } + else { + //TODO: evaluate and perhaps relax + my_owner->my_nonlocal_ctx_list_update.fetch_and_increment<full_fence>(); + //TODO: evaluate and perhaps remove + spin_wait_until_eq( my_owner->my_local_ctx_list_update, 0u ); + my_owner->my_context_list_mutex.lock(); + my_node.my_prev->my_next = my_node.my_next; + my_node.my_next->my_prev = my_node.my_prev; + my_owner->my_context_list_mutex.unlock(); + //TODO: evaluate and perhaps relax + my_owner->my_nonlocal_ctx_list_update.fetch_and_decrement<full_fence>(); + } + } + } +#if __TBB_FP_CONTEXT + internal::punned_cast<cpu_ctl_env*>(&my_cpu_ctl_env)->~cpu_ctl_env(); +#endif + poison_value(my_version_and_traits); + if ( my_exception ) + my_exception->destroy(); + ITT_STACK(itt_caller != ITT_CALLER_NULL, caller_destroy, itt_caller); +} + +void task_group_context::init () { +#if DO_ITT_NOTIFY + // Check version of task group context to avoid reporting misleading identifier. + if( ( my_version_and_traits & version_mask ) < 3 ) + my_name = internal::CUSTOM_CTX; +#endif + ITT_TASK_GROUP(this, my_name, NULL); + __TBB_STATIC_ASSERT ( sizeof(my_version_and_traits) >= 4, "Layout of my_version_and_traits must be reconsidered on this platform" ); + __TBB_STATIC_ASSERT ( sizeof(task_group_context) == 2 * NFS_MaxLineSize, "Context class has wrong size - check padding and members alignment" ); + __TBB_ASSERT ( (uintptr_t(this) & (sizeof(my_cancellation_requested) - 1)) == 0, "Context is improperly aligned" ); + __TBB_ASSERT ( __TBB_load_relaxed(my_kind) == isolated || __TBB_load_relaxed(my_kind) == bound, "Context can be created only as isolated or bound" ); + my_parent = NULL; + my_node.my_next = NULL; + my_node.my_prev = NULL; + my_cancellation_requested = 0; + my_exception = NULL; + my_owner = NULL; + my_state = 0; + itt_caller = ITT_CALLER_NULL; +#if __TBB_TASK_PRIORITY + my_priority = normalized_normal_priority; +#endif /* __TBB_TASK_PRIORITY */ +#if __TBB_FP_CONTEXT + __TBB_STATIC_ASSERT( sizeof(my_cpu_ctl_env) == sizeof(internal::uint64_t), "The reserved space for FPU settings are not equal sizeof(uint64_t)" ); + __TBB_STATIC_ASSERT( sizeof(cpu_ctl_env) <= sizeof(my_cpu_ctl_env), "FPU settings storage does not fit to uint64_t" ); + suppress_unused_warning( my_cpu_ctl_env.space ); + + cpu_ctl_env &ctl = *internal::punned_cast<cpu_ctl_env*>(&my_cpu_ctl_env); + new ( &ctl ) cpu_ctl_env; + if ( my_version_and_traits & fp_settings ) + ctl.get_env(); +#endif +} + +void task_group_context::register_with ( generic_scheduler *local_sched ) { + __TBB_ASSERT( local_sched, NULL ); + my_owner = local_sched; + // state propagation logic assumes new contexts are bound to head of the list + my_node.my_prev = &local_sched->my_context_list_head; + // Notify threads that may be concurrently destroying contexts registered + // in this scheduler's list that local list update is underway. + local_sched->my_local_ctx_list_update.store<relaxed>(1); + // Prevent load of global propagation epoch counter from being hoisted before + // speculative stores above, as well as load of nonlocal update flag from + // being hoisted before the store to local update flag. + atomic_fence(); + // Finalize local context list update + if ( local_sched->my_nonlocal_ctx_list_update.load<relaxed>() ) { + spin_mutex::scoped_lock lock(my_owner->my_context_list_mutex); + local_sched->my_context_list_head.my_next->my_prev = &my_node; + my_node.my_next = local_sched->my_context_list_head.my_next; + my_owner->my_local_ctx_list_update.store<relaxed>(0); + local_sched->my_context_list_head.my_next = &my_node; + } + else { + local_sched->my_context_list_head.my_next->my_prev = &my_node; + my_node.my_next = local_sched->my_context_list_head.my_next; + my_owner->my_local_ctx_list_update.store<release>(0); + // Thread-local list of contexts allows concurrent traversal by another thread + // while propagating state change. To ensure visibility of my_node's members + // to the concurrently traversing thread, the list's head is updated by means + // of store-with-release. + __TBB_store_with_release(local_sched->my_context_list_head.my_next, &my_node); + } +} + +void task_group_context::bind_to ( generic_scheduler *local_sched ) { + __TBB_ASSERT ( __TBB_load_relaxed(my_kind) == binding_required, "Already bound or isolated?" ); + __TBB_ASSERT ( !my_parent, "Parent is set before initial binding" ); + my_parent = local_sched->my_innermost_running_task->prefix().context; +#if __TBB_FP_CONTEXT + // Inherit FPU settings only if the context has not captured FPU settings yet. + if ( !(my_version_and_traits & fp_settings) ) + copy_fp_settings(*my_parent); +#endif + + // Condition below prevents unnecessary thrashing parent context's cache line + if ( !(my_parent->my_state & may_have_children) ) + my_parent->my_state |= may_have_children; // full fence is below + if ( my_parent->my_parent ) { + // Even if this context were made accessible for state change propagation + // (by placing __TBB_store_with_release(s->my_context_list_head.my_next, &my_node) + // above), it still could be missed if state propagation from a grand-ancestor + // was underway concurrently with binding. + // Speculative propagation from the parent together with epoch counters + // detecting possibility of such a race allow to avoid taking locks when + // there is no contention. + + // Acquire fence is necessary to prevent reordering subsequent speculative + // loads of parent state data out of the scope where epoch counters comparison + // can reliably validate it. + uintptr_t local_count_snapshot = __TBB_load_with_acquire( my_parent->my_owner->my_context_state_propagation_epoch ); + // Speculative propagation of parent's state. The speculation will be + // validated by the epoch counters check further on. + my_cancellation_requested = my_parent->my_cancellation_requested; +#if __TBB_TASK_PRIORITY + my_priority = my_parent->my_priority; +#endif /* __TBB_TASK_PRIORITY */ + register_with( local_sched ); // Issues full fence + + // If no state propagation was detected by the following condition, the above + // full fence guarantees that the parent had correct state during speculative + // propagation before the fence. Otherwise the propagation from parent is + // repeated under the lock. + if ( local_count_snapshot != the_context_state_propagation_epoch ) { + // Another thread may be propagating state change right now. So resort to lock. + context_state_propagation_mutex_type::scoped_lock lock(the_context_state_propagation_mutex); + my_cancellation_requested = my_parent->my_cancellation_requested; +#if __TBB_TASK_PRIORITY + my_priority = my_parent->my_priority; +#endif /* __TBB_TASK_PRIORITY */ + } + } + else { + register_with( local_sched ); // Issues full fence + // As we do not have grand-ancestors, concurrent state propagation (if any) + // may originate only from the parent context, and thus it is safe to directly + // copy the state from it. + my_cancellation_requested = my_parent->my_cancellation_requested; +#if __TBB_TASK_PRIORITY + my_priority = my_parent->my_priority; +#endif /* __TBB_TASK_PRIORITY */ + } + __TBB_store_relaxed(my_kind, binding_completed); +} + +template <typename T> +void task_group_context::propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ) { + if (this->*mptr_state == new_state) { + // Nothing to do, whether descending from "src" or not, so no need to scan. + // Hopefully this happens often thanks to earlier invocations. + // This optimization is enabled by LIFO order in the context lists: + // - new contexts are bound to the beginning of lists; + // - descendants are newer than ancestors; + // - earlier invocations are therefore likely to "paint" long chains. + } + else if (this == &src) { + // This clause is disjunct from the traversal below, which skips src entirely. + // Note that src.*mptr_state is not necessarily still equal to new_state (another thread may have changed it again). + // Such interference is probably not frequent enough to aim for optimisation by writing new_state again (to make the other thread back down). + // Letting the other thread prevail may also be fairer. + } + else { + for ( task_group_context *ancestor = my_parent; ancestor != NULL; ancestor = ancestor->my_parent ) { + __TBB_ASSERT(internal::is_alive(ancestor->my_version_and_traits), "context tree was corrupted"); + if ( ancestor == &src ) { + for ( task_group_context *ctx = this; ctx != ancestor; ctx = ctx->my_parent ) + ctx->*mptr_state = new_state; + break; + } + } + } +} + +template <typename T> +void generic_scheduler::propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ) { + spin_mutex::scoped_lock lock(my_context_list_mutex); + // Acquire fence is necessary to ensure that the subsequent node->my_next load + // returned the correct value in case it was just inserted in another thread. + // The fence also ensures visibility of the correct my_parent value. + context_list_node_t *node = __TBB_load_with_acquire(my_context_list_head.my_next); + while ( node != &my_context_list_head ) { + task_group_context &ctx = __TBB_get_object_ref(task_group_context, my_node, node); + if ( ctx.*mptr_state != new_state ) + ctx.propagate_task_group_state( mptr_state, src, new_state ); + node = node->my_next; + __TBB_ASSERT( is_alive(ctx.my_version_and_traits), "Local context list contains destroyed object" ); + } + // Sync up local propagation epoch with the global one. Release fence prevents + // reordering of possible store to *mptr_state after the sync point. + __TBB_store_with_release(my_context_state_propagation_epoch, the_context_state_propagation_epoch); +} + +template <typename T> +bool market::propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state ) { + if ( !(src.my_state & task_group_context::may_have_children) ) + return true; + // The whole propagation algorithm is under the lock in order to ensure correctness + // in case of concurrent state changes at the different levels of the context tree. + // See comment at the bottom of scheduler.cpp + context_state_propagation_mutex_type::scoped_lock lock(the_context_state_propagation_mutex); + if ( src.*mptr_state != new_state ) + // Another thread has concurrently changed the state. Back down. + return false; + // Advance global state propagation epoch + __TBB_FetchAndAddWrelease(&the_context_state_propagation_epoch, 1); + // Propagate to all workers and masters and sync up their local epochs with the global one + unsigned num_workers = my_first_unused_worker_idx; + for ( unsigned i = 0; i < num_workers; ++i ) { + generic_scheduler *s = my_workers[i]; + // If the worker is only about to be registered, skip it. + if ( s ) + s->propagate_task_group_state( mptr_state, src, new_state ); + } + // Propagate to all master threads + // The whole propagation sequence is locked, thus no contention is expected + for( scheduler_list_type::iterator it = my_masters.begin(); it != my_masters.end(); it++ ) + it->propagate_task_group_state( mptr_state, src, new_state ); + return true; +} + +bool task_group_context::cancel_group_execution () { + __TBB_ASSERT ( my_cancellation_requested == 0 || my_cancellation_requested == 1, "Invalid cancellation state"); + if ( my_cancellation_requested || as_atomic(my_cancellation_requested).compare_and_swap(1, 0) ) { + // This task group and any descendants have already been canceled. + // (A newly added descendant would inherit its parent's my_cancellation_requested, + // not missing out on any cancellation still being propagated, and a context cannot be uncanceled.) + return false; + } + governor::local_scheduler_weak()->my_market->propagate_task_group_state( &task_group_context::my_cancellation_requested, *this, (uintptr_t)1 ); + return true; +} + +bool task_group_context::is_group_execution_cancelled () const { + return my_cancellation_requested != 0; +} + +// IMPORTANT: It is assumed that this method is not used concurrently! +void task_group_context::reset () { + //! TODO: Add assertion that this context does not have children + // No fences are necessary since this context can be accessed from another thread + // only after stealing happened (which means necessary fences were used). + if ( my_exception ) { + my_exception->destroy(); + my_exception = NULL; + } + my_cancellation_requested = 0; +} + +#if __TBB_FP_CONTEXT +// IMPORTANT: It is assumed that this method is not used concurrently! +void task_group_context::capture_fp_settings () { + //! TODO: Add assertion that this context does not have children + // No fences are necessary since this context can be accessed from another thread + // only after stealing happened (which means necessary fences were used). + cpu_ctl_env &ctl = *internal::punned_cast<cpu_ctl_env*>(&my_cpu_ctl_env); + if ( !(my_version_and_traits & fp_settings) ) { + new ( &ctl ) cpu_ctl_env; + my_version_and_traits |= fp_settings; + } + ctl.get_env(); +} + +void task_group_context::copy_fp_settings( const task_group_context &src ) { + __TBB_ASSERT( !(my_version_and_traits & fp_settings), "The context already has FPU settings." ); + __TBB_ASSERT( src.my_version_and_traits & fp_settings, "The source context does not have FPU settings." ); + + cpu_ctl_env &ctl = *internal::punned_cast<cpu_ctl_env*>(&my_cpu_ctl_env); + cpu_ctl_env &src_ctl = *internal::punned_cast<cpu_ctl_env*>(&src.my_cpu_ctl_env); + new (&ctl) cpu_ctl_env( src_ctl ); + my_version_and_traits |= fp_settings; +} +#endif /* __TBB_FP_CONTEXT */ + +void task_group_context::register_pending_exception () { + if ( my_cancellation_requested ) + return; +#if TBB_USE_EXCEPTIONS + try { + throw; + } TbbCatchAll( this ); +#endif /* TBB_USE_EXCEPTIONS */ +} + +#if __TBB_TASK_PRIORITY +void task_group_context::set_priority ( priority_t prio ) { + __TBB_ASSERT( prio == priority_low || prio == priority_normal || prio == priority_high, "Invalid priority level value" ); + intptr_t p = normalize_priority(prio); + if ( my_priority == p && !(my_state & task_group_context::may_have_children)) + return; + my_priority = p; + internal::generic_scheduler* s = governor::local_scheduler_if_initialized(); + if ( !s || !s->my_arena || !s->my_market->propagate_task_group_state(&task_group_context::my_priority, *this, p) ) + return; + + //! TODO: the arena of the calling thread might be unrelated; + // need to find out the right arena for priority update. + // The executing status check only guarantees being inside some working arena. + if ( s->my_innermost_running_task->state() == task::executing ) + // Updating arena priority here does not eliminate necessity of checking each + // task priority and updating arena priority if necessary before the task execution. + // These checks will be necessary because: + // a) set_priority() may be invoked before any tasks from this task group are spawned; + // b) all spawned tasks from this task group are retrieved from the task pools. + // These cases create a time window when arena priority may be lowered. + s->my_market->update_arena_priority( *s->my_arena, p ); +} + +priority_t task_group_context::priority () const { + return static_cast<priority_t>(priority_from_normalized_rep[my_priority]); +} +#endif /* __TBB_TASK_PRIORITY */ + +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_stream.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_stream.h new file mode 100644 index 00000000..b4500ffa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_stream.h @@ -0,0 +1,168 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_task_stream_H +#define _TBB_task_stream_H + +#include "tbb/tbb_stddef.h" +#include <deque> +#include <climits> +#include "tbb/atomic.h" // for __TBB_Atomic* +#include "tbb/spin_mutex.h" +#include "tbb/tbb_allocator.h" +#include "scheduler_common.h" +#include "tbb_misc.h" // for FastRandom + +namespace tbb { +namespace internal { + +//! Essentially, this is just a pair of a queue and a mutex to protect the queue. +/** The reason std::pair is not used is that the code would look less clean + if field names were replaced with 'first' and 'second'. **/ +template< typename T, typename mutex_t > +struct queue_and_mutex { + typedef std::deque< T, tbb_allocator<T> > queue_base_t; + + queue_base_t my_queue; + mutex_t my_mutex; + + queue_and_mutex () : my_queue(), my_mutex() {} + ~queue_and_mutex () {} +}; + +typedef uintptr_t population_t; +const population_t one = 1; + +inline void set_one_bit( population_t& dest, int pos ) { + __TBB_ASSERT( pos>=0, NULL ); + __TBB_ASSERT( pos<int(sizeof(population_t)*CHAR_BIT), NULL ); + __TBB_AtomicOR( &dest, one<<pos ); +} + +inline void clear_one_bit( population_t& dest, int pos ) { + __TBB_ASSERT( pos>=0, NULL ); + __TBB_ASSERT( pos<int(sizeof(population_t)*CHAR_BIT), NULL ); + __TBB_AtomicAND( &dest, ~(one<<pos) ); +} + +inline bool is_bit_set( population_t val, int pos ) { + __TBB_ASSERT( pos>=0, NULL ); + __TBB_ASSERT( pos<int(sizeof(population_t)*CHAR_BIT), NULL ); + return (val & (one<<pos)) != 0; +} + +//! The container for "fairness-oriented" aka "enqueued" tasks. +template<int Levels> +class task_stream : no_copy { + typedef queue_and_mutex <task*, spin_mutex> lane_t; + population_t population[Levels]; + padded<lane_t>* lanes[Levels]; + unsigned N; + +public: + task_stream() : N() { + for(int level = 0; level < Levels; level++) { + population[level] = 0; + lanes[level] = NULL; + } + } + + void initialize( unsigned n_lanes ) { + const unsigned max_lanes = sizeof(population_t) * CHAR_BIT; + + N = n_lanes>=max_lanes ? max_lanes : n_lanes>2 ? 1<<(__TBB_Log2(n_lanes-1)+1) : 2; + __TBB_ASSERT( N==max_lanes || N>=n_lanes && ((N-1)&N)==0, "number of lanes miscalculated"); + __TBB_ASSERT( N <= sizeof(population_t) * CHAR_BIT, NULL ); + for(int level = 0; level < Levels; level++) { + lanes[level] = new padded<lane_t>[N]; + __TBB_ASSERT( !population[level], NULL ); + } + } + + ~task_stream() { + for(int level = 0; level < Levels; level++) + if (lanes[level]) delete[] lanes[level]; + } + + //! Push a task into a lane. + void push( task* source, int level, FastRandom& random ) { + // Lane selection is random. Each thread should keep a separate seed value. + unsigned idx; + for( ; ; ) { + idx = random.get() & (N-1); + spin_mutex::scoped_lock lock; + if( lock.try_acquire(lanes[level][idx].my_mutex) ) { + lanes[level][idx].my_queue.push_back(source); + set_one_bit( population[level], idx ); //TODO: avoid atomic op if the bit is already set + break; + } + } + } + + //! Try finding and popping a task. + task* pop( int level, unsigned& last_used_lane ) { + task* result = NULL; + // Lane selection is round-robin. Each thread should keep its last used lane. + unsigned idx = (last_used_lane+1)&(N-1); + for( ; population[level]; idx=(idx+1)&(N-1) ) { + if( is_bit_set( population[level], idx ) ) { + lane_t& lane = lanes[level][idx]; + spin_mutex::scoped_lock lock; + if( lock.try_acquire(lane.my_mutex) && !lane.my_queue.empty() ) { + result = lane.my_queue.front(); + lane.my_queue.pop_front(); + if( lane.my_queue.empty() ) + clear_one_bit( population[level], idx ); + break; + } + } + } + last_used_lane = idx; + return result; + } + + //! Checks existence of a task. + bool empty(int level) { + return !population[level]; + } + + //! Destroys all remaining tasks in every lane. Returns the number of destroyed tasks. + /** Tasks are not executed, because it would potentially create more tasks at a late stage. + The scheduler is really expected to execute all tasks before task_stream destruction. */ + intptr_t drain() { + intptr_t result = 0; + for(int level = 0; level < Levels; level++) + for(unsigned i=0; i<N; ++i) { + lane_t& lane = lanes[level][i]; + spin_mutex::scoped_lock lock(lane.my_mutex); + for(lane_t::queue_base_t::iterator it=lane.my_queue.begin(); + it!=lane.my_queue.end(); ++it, ++result) + { + __TBB_ASSERT( is_bit_set( population[level], i ), NULL ); + task* t = *it; + tbb::task::destroy(*t); + } + lane.my_queue.clear(); + clear_one_bit( population[level], i ); + } + return result; + } +}; // task_stream + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_task_stream_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_stream_extended.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_stream_extended.h new file mode 100644 index 00000000..dcb08cb8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/task_stream_extended.h @@ -0,0 +1,319 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_task_stream_extended_H +#define _TBB_task_stream_extended_H + +//! This file is a possible future replacement for the task_stream class implemented in +//! task_stream.h. It refactors the code and extends task_stream capabilities by moving lane +//! management during operations on caller side. Despite the fact that new implementation should not +//! affect performance of the original task stream, analysis on this subject was not made at the +//! time it was developed. In addition, it is not clearly seen at the moment that this container +//! would be suitable for critical tasks due to linear time complexity on its operations. + + +#if _TBB_task_stream_H +#error Either task_stream.h or this file can be included at the same time. +#endif + +#if !__TBB_CPF_BUILD +#error This code bears a preview status until it proves its usefulness/performance suitability. +#endif + +#include "tbb/tbb_stddef.h" +#include <deque> +#include <climits> +#include "tbb/atomic.h" // for __TBB_Atomic* +#include "tbb/spin_mutex.h" +#include "tbb/tbb_allocator.h" +#include "scheduler_common.h" +#include "tbb_misc.h" // for FastRandom + +namespace tbb { +namespace internal { + +//! Essentially, this is just a pair of a queue and a mutex to protect the queue. +/** The reason std::pair is not used is that the code would look less clean + if field names were replaced with 'first' and 'second'. **/ +template< typename T, typename mutex_t > +struct queue_and_mutex { + typedef std::deque< T, tbb_allocator<T> > queue_base_t; + + queue_base_t my_queue; + mutex_t my_mutex; + + queue_and_mutex () : my_queue(), my_mutex() {} + ~queue_and_mutex () {} +}; + +typedef uintptr_t population_t; +const population_t one = 1; + +inline void set_one_bit( population_t& dest, int pos ) { + __TBB_ASSERT( pos>=0, NULL ); + __TBB_ASSERT( pos<int(sizeof(population_t)*CHAR_BIT), NULL ); + __TBB_AtomicOR( &dest, one<<pos ); +} + +inline void clear_one_bit( population_t& dest, int pos ) { + __TBB_ASSERT( pos>=0, NULL ); + __TBB_ASSERT( pos<int(sizeof(population_t)*CHAR_BIT), NULL ); + __TBB_AtomicAND( &dest, ~(one<<pos) ); +} + +inline bool is_bit_set( population_t val, int pos ) { + __TBB_ASSERT( pos>=0, NULL ); + __TBB_ASSERT( pos<int(sizeof(population_t)*CHAR_BIT), NULL ); + return (val & (one<<pos)) != 0; +} + +struct random_lane_selector : +#if __INTEL_COMPILER == 1110 || __INTEL_COMPILER == 1500 + no_assign +#else + no_copy +#endif +{ + random_lane_selector( FastRandom& random ) : my_random( random ) {} + unsigned operator()( unsigned out_of ) const { + __TBB_ASSERT( ((out_of-1) & out_of) == 0, "number of lanes is not power of two." ); + return my_random.get() & (out_of-1); + } +private: + FastRandom& my_random; +}; + +struct lane_selector_base : +#if __INTEL_COMPILER == 1110 || __INTEL_COMPILER == 1500 + no_assign +#else + no_copy +#endif +{ + unsigned& my_previous; + lane_selector_base( unsigned& previous ) : my_previous( previous ) {} +}; + +struct subsequent_lane_selector : lane_selector_base { + subsequent_lane_selector( unsigned& previous ) : lane_selector_base( previous ) {} + unsigned operator()( unsigned out_of ) const { + __TBB_ASSERT( ((out_of-1) & out_of) == 0, "number of lanes is not power of two." ); + return (++my_previous &= out_of-1); + } +}; + +struct preceding_lane_selector : lane_selector_base { + preceding_lane_selector( unsigned& previous ) : lane_selector_base( previous ) {} + unsigned operator()( unsigned out_of ) const { + __TBB_ASSERT( ((out_of-1) & out_of) == 0, "number of lanes is not power of two." ); + return (--my_previous &= (out_of-1)); + } +}; + +class task_stream_base : no_copy { +protected: + typedef queue_and_mutex <task*, spin_mutex> lane_t; +}; + +enum task_stream_accessor_type { front_accessor = 0, back_nonnull_accessor }; + +//! Specializes from which side of the underlying container elements are retrieved. Method must be +//! called under corresponding mutex locked. +template<task_stream_accessor_type accessor> +class task_stream_accessor : public task_stream_base { +protected: + using task_stream_base::lane_t; + task* get_item( lane_t::queue_base_t& queue ) { + task* result = queue.front(); + queue.pop_front(); + return result; + } +}; + +template<> +class task_stream_accessor< back_nonnull_accessor > : public task_stream_base { +protected: + task* get_item( lane_t::queue_base_t& queue ) { + task* result = NULL; + do { + result = queue.back(); + queue.pop_back(); + } while( !result && !queue.empty() ); + return result; + } +}; + +//! The container for "fairness-oriented" aka "enqueued" tasks. +template<int Levels, task_stream_accessor_type accessor> +class task_stream : public task_stream_accessor< accessor > { + typedef typename task_stream_accessor<accessor>::lane_t lane_t; + population_t population[Levels]; + padded<lane_t>* lanes[Levels]; + unsigned N; + +public: + task_stream() : N() { + for(int level = 0; level < Levels; level++) { + population[level] = 0; + lanes[level] = NULL; + } + } + + void initialize( unsigned n_lanes ) { + const unsigned max_lanes = sizeof(population_t) * CHAR_BIT; + + N = n_lanes>=max_lanes ? max_lanes : n_lanes>2 ? 1<<(__TBB_Log2(n_lanes-1)+1) : 2; + __TBB_ASSERT( N==max_lanes || N>=n_lanes && ((N-1)&N)==0, "number of lanes miscalculated"); + __TBB_ASSERT( N <= sizeof(population_t) * CHAR_BIT, NULL ); + for(int level = 0; level < Levels; level++) { + lanes[level] = new padded<lane_t>[N]; + __TBB_ASSERT( !population[level], NULL ); + } + } + + ~task_stream() { + for(int level = 0; level < Levels; level++) + if (lanes[level]) delete[] lanes[level]; + } + + //! Returns true on successful push, otherwise - false. + bool try_push( task* source, int level, unsigned lane_idx ) { + __TBB_ASSERT( 0 <= level && level < Levels, "Incorrect lane level specified." ); + spin_mutex::scoped_lock lock; + if( lock.try_acquire( lanes[level][lane_idx].my_mutex ) ) { + lanes[level][lane_idx].my_queue.push_back( source ); + set_one_bit( population[level], lane_idx ); // TODO: avoid atomic op if the bit is already set + return true; + } + return false; + } + + //! Push a task into a lane. Lane selection is performed by passed functor. + template<typename lane_selector_t> + void push( task* source, int level, const lane_selector_t& next_lane ) { + bool succeed = false; + unsigned lane = 0; + do { + lane = next_lane( /*out_of=*/N ); + __TBB_ASSERT( lane < N, "Incorrect lane index." ); + } while( ! (succeed = try_push( source, level, lane )) ); + } + + //! Returns pointer to task on successful pop, otherwise - NULL. + task* try_pop( int level, unsigned lane_idx ) { + __TBB_ASSERT( 0 <= level && level < Levels, "Incorrect lane level specified." ); + if( !is_bit_set( population[level], lane_idx ) ) + return NULL; + task* result = NULL; + lane_t& lane = lanes[level][lane_idx]; + spin_mutex::scoped_lock lock; + if( lock.try_acquire( lane.my_mutex ) && !lane.my_queue.empty() ) { + result = this->get_item( lane.my_queue ); + if( lane.my_queue.empty() ) + clear_one_bit( population[level], lane_idx ); + } + return result; + } + + //! Try finding and popping a task using passed functor for lane selection. Last used lane is + //! updated inside lane selector. + template<typename lane_selector_t> + task* pop( int level, const lane_selector_t& next_lane ) { + task* popped = NULL; + unsigned lane = 0; + do { + lane = next_lane( /*out_of=*/N ); + __TBB_ASSERT( lane < N, "Incorrect lane index." ); + } while( !empty( level ) && !(popped = try_pop( level, lane )) ); + return popped; + } + + // TODO: unify '*_specific' logic with 'pop' methods above + task* look_specific( __TBB_ISOLATION_ARG(task_stream_base::lane_t::queue_base_t& queue, isolation_tag isolation) ) { + __TBB_ASSERT( !queue.empty(), NULL ); + // TODO: add a worst-case performance test and consider an alternative container with better + // performance for isolation search. + typename lane_t::queue_base_t::iterator curr = queue.end(); + do { + // TODO: consider logic from get_task to simplify the code. + task* result = *--curr; + if( result __TBB_ISOLATION_EXPR( && result->prefix().isolation == isolation ) ) { + if( queue.end() - curr == 1 ) + queue.pop_back(); // a little of housekeeping along the way + else + *curr = 0; // grabbing task with the same isolation + // TODO: move one of the container's ends instead if the task has been found there + return result; + } + } while( curr != queue.begin() ); + return NULL; + } + + //! Try finding and popping a related task. + task* pop_specific( int level, __TBB_ISOLATION_ARG(unsigned& last_used_lane, isolation_tag isolation) ) { + task* result = NULL; + // Lane selection is round-robin in backward direction. + unsigned idx = last_used_lane & (N-1); + do { + if( is_bit_set( population[level], idx ) ) { + lane_t& lane = lanes[level][idx]; + spin_mutex::scoped_lock lock; + if( lock.try_acquire(lane.my_mutex) && !lane.my_queue.empty() ) { + result = look_specific( __TBB_ISOLATION_ARG(lane.my_queue, isolation) ); + if( lane.my_queue.empty() ) + clear_one_bit( population[level], idx ); + if( result ) + break; + } + } + idx=(idx-1)&(N-1); + } while( !empty(level) && idx != last_used_lane ); + last_used_lane = idx; + return result; + } + + //! Checks existence of a task. + bool empty(int level) { + return !population[level]; + } + + //! Destroys all remaining tasks in every lane. Returns the number of destroyed tasks. + /** Tasks are not executed, because it would potentially create more tasks at a late stage. + The scheduler is really expected to execute all tasks before task_stream destruction. */ + intptr_t drain() { + intptr_t result = 0; + for(int level = 0; level < Levels; level++) + for(unsigned i=0; i<N; ++i) { + lane_t& lane = lanes[level][i]; + spin_mutex::scoped_lock lock(lane.my_mutex); + for(typename lane_t::queue_base_t::iterator it=lane.my_queue.begin(); + it!=lane.my_queue.end(); ++it, ++result) + { + __TBB_ASSERT( is_bit_set( population[level], i ), NULL ); + task* t = *it; + tbb::task::destroy(*t); + } + lane.my_queue.clear(); + clear_one_bit( population[level], i ); + } + return result; + } +}; // task_stream + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_task_stream_extended_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_assert_impl.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_assert_impl.h new file mode 100644 index 00000000..bad2a634 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_assert_impl.h @@ -0,0 +1,102 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_assert_impl_H +#define _TBB_assert_impl_H + +// IMPORTANT: To use assertion handling in TBB, exactly one of the TBB source files +// should #include tbb_assert_impl.h thus instantiating assertion handling routines. +// The intent of putting it to a separate file is to allow some tests to use it +// as well in order to avoid dependency on the library. + +// include headers for required function declarations +#include <cstdlib> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#if _MSC_VER +#include <crtdbg.h> +#endif + +#if _MSC_VER >= 1400 +#define __TBB_EXPORTED_FUNC __cdecl +#else +#define __TBB_EXPORTED_FUNC +#endif + +#if __TBBMALLOC_BUILD +namespace rml { namespace internal { +#else +namespace tbb { +#endif + //! Type for an assertion handler + typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment ); + + static assertion_handler_type assertion_handler; + + assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler ) { + assertion_handler_type old_handler = assertion_handler; + assertion_handler = new_handler; + return old_handler; + } + + void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment ) { + if( assertion_handler_type a = assertion_handler ) { + (*a)(filename,line,expression,comment); + } else { + static bool already_failed; + if( !already_failed ) { + already_failed = true; + fprintf( stderr, "Assertion %s failed on line %d of file %s\n", + expression, line, filename ); + if( comment ) + fprintf( stderr, "Detailed description: %s\n", comment ); +#if _MSC_VER && _DEBUG + if(1 == _CrtDbgReport(_CRT_ASSERT, filename, line, "tbb_debug.dll", "%s\r\n%s", expression, comment?comment:"")) + _CrtDbgBreak(); +#else + fflush(stderr); + std::abort(); +#endif + } + } + } + +#if defined(_MSC_VER)&&_MSC_VER<1400 +# define vsnprintf _vsnprintf +#endif + +#if !__TBBMALLOC_BUILD && !__TBBBIND_BUILD + namespace internal { + //! Report a runtime warning. + void __TBB_EXPORTED_FUNC runtime_warning( const char* format, ... ) + { + char str[1024]; memset(str, 0, 1024); + va_list args; va_start(args, format); + vsnprintf( str, 1024-1, format, args); + va_end(args); + fprintf( stderr, "TBB Warning: %s\n", str); + } + } // namespace internal +#endif + +#if __TBBMALLOC_BUILD +}} // namespaces rml::internal +#else +} // namespace tbb +#endif + +#endif /*_TBB_assert_impl_H*/ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_bind.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_bind.cpp new file mode 100644 index 00000000..36bd5bce --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_bind.cpp @@ -0,0 +1,302 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "../tbb/tbb_assert_impl.h" // Out-of-line TBB assertion handling routines are instantiated here. +#include "tbb/tbb_stddef.h" + +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning( push ) +#pragma warning( disable : 4100 ) +#endif +#include <hwloc.h> +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning( pop ) +#endif + +#include <vector> + +// Most of hwloc calls returns negative exit code on error. +// This macro tracks error codes that are returned from the hwloc interfaces. +#define assertion_hwloc_wrapper(command, ...) \ + __TBB_ASSERT_EX( (command(__VA_ARGS__)) >= 0, "Error occurred during call to hwloc API."); + +namespace tbb { +namespace internal { + +//------------------------------------------------------------------------ +// Information about the machine's hardware TBB is happen to work on +//------------------------------------------------------------------------ +class platform_topology { + friend class numa_affinity_handler; + + // TODO: add the `my_` prefix to the members + hwloc_topology_t topology; + hwloc_cpuset_t process_cpu_affinity_mask; + hwloc_nodeset_t process_node_affinity_mask; + std::vector<hwloc_cpuset_t> affinity_masks_list; + + std::vector<int> default_concurrency_list; + std::vector<int> numa_indexes_list; + int numa_nodes_count; + + enum init_stages { uninitialized, + started, + topology_allocated, + topology_loaded, + topology_parsed } initialization_state; + + // Binding threads to NUMA nodes that locates in another Windows Processor groups + // is allowed only if machine topology contains several Windows Processors groups + // and process affinity mask wasn`t limited manually (affinity mask cannot violates + // processors group boundaries). + bool intergroup_binding_allowed(size_t groups_num) { return groups_num > 1; } + + platform_topology() : topology(NULL), + process_cpu_affinity_mask(NULL), + process_node_affinity_mask(NULL), + numa_nodes_count(0), + initialization_state(uninitialized) {} + +public: + typedef hwloc_cpuset_t affinity_mask; + typedef hwloc_const_cpuset_t const_affinity_mask; + + static platform_topology& instance() { + static platform_topology topology; + return topology; + } + + bool is_topology_parsed() { return initialization_state == topology_parsed; } + + void initialize( size_t groups_num ) { + if ( initialization_state != uninitialized ) + return; + initialization_state = started; + + // Parse topology + if ( hwloc_topology_init( &topology ) == 0 ) { + initialization_state = topology_allocated; + if ( hwloc_topology_load( topology ) == 0 ) { + initialization_state = topology_loaded; + } + } + + // Fill parameters with stubs if topology parsing is broken. + if ( initialization_state != topology_loaded ) { + if ( initialization_state == topology_allocated ) { + hwloc_topology_destroy(topology); + } + numa_nodes_count = 1; + numa_indexes_list.push_back(-1); + default_concurrency_list.push_back(-1); + return; + } + + // Getting process affinity mask + if ( intergroup_binding_allowed(groups_num) ) { + process_cpu_affinity_mask = hwloc_bitmap_dup(hwloc_topology_get_complete_cpuset (topology)); + process_node_affinity_mask = hwloc_bitmap_dup(hwloc_topology_get_complete_nodeset(topology)); + } else { + process_cpu_affinity_mask = hwloc_bitmap_alloc(); + process_node_affinity_mask = hwloc_bitmap_alloc(); + + assertion_hwloc_wrapper(hwloc_get_cpubind, topology, process_cpu_affinity_mask, 0); + hwloc_cpuset_to_nodeset(topology, process_cpu_affinity_mask, process_node_affinity_mask); + } + + // If system contains no NUMA nodes, HWLOC 1.11 returns an infinitely filled bitmap. + // hwloc_bitmap_weight() returns negative value for such bitmaps, so we use this check + // to change way of topology initialization. + if (hwloc_bitmap_weight(process_node_affinity_mask) < 0) { + numa_nodes_count = 1; + numa_indexes_list.push_back(0); + default_concurrency_list.push_back(hwloc_bitmap_weight(process_cpu_affinity_mask)); + + affinity_masks_list.push_back(hwloc_bitmap_dup(process_cpu_affinity_mask)); + initialization_state = topology_parsed; + return; + } + + // Get number of available NUMA nodes + numa_nodes_count = hwloc_bitmap_weight(process_node_affinity_mask); + __TBB_ASSERT(numa_nodes_count > 0, "Any system must contain one or more NUMA nodes"); + + // Get NUMA logical indexes list + unsigned counter = 0; + int i = 0; + int max_numa_index = -1; + numa_indexes_list.resize(numa_nodes_count); + hwloc_obj_t node_buffer; + hwloc_bitmap_foreach_begin(i, process_node_affinity_mask) { + node_buffer = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, i); + numa_indexes_list[counter] = static_cast<int>(node_buffer->logical_index); + + if ( numa_indexes_list[counter] > max_numa_index ) { + max_numa_index = numa_indexes_list[counter]; + } + + counter++; + } hwloc_bitmap_foreach_end(); + __TBB_ASSERT(max_numa_index >= 0, "Maximal NUMA index must not be negative"); + + // Fill concurrency and affinity masks lists + default_concurrency_list.resize(max_numa_index + 1); + affinity_masks_list.resize(max_numa_index + 1); + + int index = 0; + hwloc_bitmap_foreach_begin(i, process_node_affinity_mask) { + node_buffer = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, i); + index = static_cast<int>(node_buffer->logical_index); + + hwloc_cpuset_t& current_mask = affinity_masks_list[index]; + current_mask = hwloc_bitmap_dup(node_buffer->cpuset); + + hwloc_bitmap_and(current_mask, current_mask, process_cpu_affinity_mask); + __TBB_ASSERT(!hwloc_bitmap_iszero(current_mask), "hwloc detected unavailable NUMA node"); + default_concurrency_list[index] = hwloc_bitmap_weight(current_mask); + } hwloc_bitmap_foreach_end(); + initialization_state = topology_parsed; + } + + ~platform_topology() { + if ( is_topology_parsed() ) { + for (int i = 0; i < numa_nodes_count; i++) { + hwloc_bitmap_free(affinity_masks_list[numa_indexes_list[i]]); + } + hwloc_bitmap_free(process_node_affinity_mask); + hwloc_bitmap_free(process_cpu_affinity_mask); + } + + if ( initialization_state >= topology_allocated ) { + hwloc_topology_destroy(topology); + } + + initialization_state = uninitialized; + } + + void fill(int& nodes_count, int*& indexes_list, int*& concurrency_list ) { + __TBB_ASSERT(is_topology_parsed(), "Trying to get access to uninitialized platform_topology"); + nodes_count = numa_nodes_count; + indexes_list = &numa_indexes_list.front(); + concurrency_list = &default_concurrency_list.front(); + } + + affinity_mask allocate_process_affinity_mask() { + __TBB_ASSERT(is_topology_parsed(), "Trying to get access to uninitialized platform_topology"); + return hwloc_bitmap_dup(process_cpu_affinity_mask); + } + + void free_affinity_mask( affinity_mask mask_to_free ) { + hwloc_bitmap_free(mask_to_free); // If bitmap is NULL, no operation is performed. + } + + void store_current_affinity_mask( affinity_mask current_mask ) { + assertion_hwloc_wrapper(hwloc_get_cpubind, topology, current_mask, HWLOC_CPUBIND_THREAD); + + hwloc_bitmap_and(current_mask, current_mask, process_cpu_affinity_mask); + __TBB_ASSERT(!hwloc_bitmap_iszero(current_mask), + "Current affinity mask must intersects with process affinity mask"); + } + + void set_new_affinity_mask( const_affinity_mask new_mask ) { + assertion_hwloc_wrapper(hwloc_set_cpubind, topology, new_mask, HWLOC_CPUBIND_THREAD); + } + + const_affinity_mask get_node_affinity_mask( int node_index ) { + __TBB_ASSERT((int)affinity_masks_list.size() > node_index, + "Trying to get affinity mask for uninitialized NUMA node"); + return affinity_masks_list[node_index]; + } +}; + +class binding_handler { + // Following vector saves thread affinity mask on scheduler entry to return it to this thread + // on scheduler exit. + typedef std::vector<platform_topology::affinity_mask> affinity_masks_container; + affinity_masks_container affinity_backup; + +public: + binding_handler( size_t size ) : affinity_backup(size) { + for (affinity_masks_container::iterator it = affinity_backup.begin(); + it != affinity_backup.end(); it++) { + *it = platform_topology::instance().allocate_process_affinity_mask(); + } + } + + ~binding_handler() { + for (affinity_masks_container::iterator it = affinity_backup.begin(); + it != affinity_backup.end(); it++) { + platform_topology::instance().free_affinity_mask(*it); + } + } + + void bind_thread_to_node( unsigned slot_num, unsigned numa_node_id ) { + __TBB_ASSERT(slot_num < affinity_backup.size(), + "The slot number is greater than the number of slots in the arena"); + __TBB_ASSERT(platform_topology::instance().is_topology_parsed(), + "Trying to get access to uninitialized platform_topology"); + platform_topology::instance().store_current_affinity_mask(affinity_backup[slot_num]); + + platform_topology::instance().set_new_affinity_mask( + platform_topology::instance().get_node_affinity_mask(numa_node_id)); + } + + void restore_previous_affinity_mask( unsigned slot_num ) { + __TBB_ASSERT(platform_topology::instance().is_topology_parsed(), + "Trying to get access to uninitialized platform_topology"); + platform_topology::instance().set_new_affinity_mask(affinity_backup[slot_num]); + }; + +}; + +extern "C" { // exported to TBB interfaces + +void initialize_numa_topology( size_t groups_num, + int& nodes_count, int*& indexes_list, int*& concurrency_list ) { + platform_topology::instance().initialize(groups_num); + platform_topology::instance().fill(nodes_count, indexes_list, concurrency_list); +} + +binding_handler* allocate_binding_handler(int slot_num) { + __TBB_ASSERT(slot_num > 0, "Trying to create numa handler for 0 threads."); + return new binding_handler(slot_num); +} + +void deallocate_binding_handler(binding_handler* handler_ptr) { + __TBB_ASSERT(handler_ptr != NULL, "Trying to deallocate NULL pointer."); + delete handler_ptr; +} + +void bind_to_node(binding_handler* handler_ptr, int slot_num, int numa_id) { + __TBB_ASSERT(handler_ptr != NULL, "Trying to get access to uninitialized metadata."); + __TBB_ASSERT(platform_topology::instance().is_topology_parsed(), + "Trying to get access to uninitialized platform_topology."); + handler_ptr->bind_thread_to_node(slot_num, numa_id); +} + +void restore_affinity(binding_handler* handler_ptr, int slot_num) { + __TBB_ASSERT(handler_ptr != NULL, "Trying to get access to uninitialized metadata."); + __TBB_ASSERT(platform_topology::instance().is_topology_parsed(), + "Trying to get access to uninitialized platform_topology."); + handler_ptr->restore_previous_affinity_mask(slot_num); +} + +} // extern "C" + +} // namespace internal +} // namespace tbb + +#undef assertion_hwloc_wrapper diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_environment.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_environment.h new file mode 100644 index 00000000..e6a88cca --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_environment.h @@ -0,0 +1,85 @@ +/* + Copyright (c) 2018-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbb_environment_H +#define __TBB_tbb_environment_H + +#include <cstdlib> +#include <cstring> +#include <cerrno> +#include <cctype> + +namespace tbb { + +namespace internal { + +#if __TBB_WIN8UI_SUPPORT +static inline bool GetBoolEnvironmentVariable( const char * ) { + return false; +} + +static inline long GetIntegralEnvironmentVariable( const char * ) { + return -1; +} +#else /* __TBB_WIN8UI_SUPPORT */ +static inline bool GetBoolEnvironmentVariable( const char * name ) { + if( const char* s = std::getenv(name) ) + { + // The result is defined as true only if the environment variable contains + // no characters except one '1' character and an arbitrary number of spaces + // (including the absence of spaces). + size_t index = std::strspn(s, " "); + if (s[index] != '1') return false; + index++; + // Memory access after incrementing is safe, since the getenv() returns a + // NULL terminated string, and even if the character getting by index is '1', + // and this character is the end of string, after incrementing we will get + // an index of character, that contains '\0' + index += std::strspn(&s[index], " "); + return !s[index]; + } + return false; +} + +static inline long GetIntegralEnvironmentVariable( const char * name ) { + if( const char* s = std::getenv(name) ) + { + char* end = NULL; + errno = 0; + long value = std::strtol(s, &end, 10); + + // We have exceeded the range, value is negative or string is incovertable + if ( errno == ERANGE || value < 0 || end==s ) + { + return -1; + } + + for ( ; *end != '\0'; end++ ) + { + if ( !std::isspace(*end) ) + return -1; + } + + return value; + } + return -1; +} +#endif /* __TBB_WIN8UI_SUPPORT */ + +} // namespace internal +} // namespace tbb + +#endif // __TBB_tbb_environment_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_main.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_main.cpp new file mode 100644 index 00000000..4fa2ea50 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_main.cpp @@ -0,0 +1,585 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" +#include "tbb/global_control.h" +#include "tbb_main.h" +#include "governor.h" +#include "market.h" +#include "tbb_misc.h" +#include "itt_notify.h" + +namespace tbb { +namespace internal { + +//------------------------------------------------------------------------ +// Begin shared data layout. +// The following global data items are mostly read-only after initialization. +//------------------------------------------------------------------------ + +//! Padding in order to prevent false sharing. +static const char _pad[NFS_MaxLineSize - sizeof(int)] = {}; + +//------------------------------------------------------------------------ +// governor data +basic_tls<uintptr_t> governor::theTLS; +unsigned governor::DefaultNumberOfThreads; +size_t governor::DefaultPageSize; +rml::tbb_factory governor::theRMLServerFactory; +bool governor::UsePrivateRML; +bool governor::is_speculation_enabled; +bool governor::is_rethrow_broken; + +//------------------------------------------------------------------------ +// market data +market* market::theMarket; +market::global_market_mutex_type market::theMarketMutex; + +//------------------------------------------------------------------------ +// One time initialization data + +//! Counter of references to global shared resources such as TLS. +atomic<int> __TBB_InitOnce::count; + +__TBB_atomic_flag __TBB_InitOnce::InitializationLock; + +//! Flag that is set to true after one-time initializations are done. +bool __TBB_InitOnce::InitializationDone; + +#if DO_ITT_NOTIFY + static bool ITT_Present; + static atomic<bool> ITT_InitializationDone; +#endif + +#if !(_WIN32||_WIN64) || __TBB_SOURCE_DIRECTLY_INCLUDED + static __TBB_InitOnce __TBB_InitOnceHiddenInstance; +#endif + +//------------------------------------------------------------------------ +// generic_scheduler data + +//! Pointer to the scheduler factory function +generic_scheduler* (*AllocateSchedulerPtr)( market&, bool ); + +#if __TBB_OLD_PRIMES_RNG +//! Table of primes used by fast random-number generator (FastRandom). +/** Also serves to keep anything else from being placed in the same + cache line as the global data items preceding it. */ +static const unsigned Primes[] = { + 0x9e3779b1, 0xffe6cc59, 0x2109f6dd, 0x43977ab5, + 0xba5703f5, 0xb495a877, 0xe1626741, 0x79695e6b, + 0xbc98c09f, 0xd5bee2b3, 0x287488f9, 0x3af18231, + 0x9677cd4d, 0xbe3a6929, 0xadc6a877, 0xdcf0674b, + 0xbe4d6fe9, 0x5f15e201, 0x99afc3fd, 0xf3f16801, + 0xe222cfff, 0x24ba5fdb, 0x0620452d, 0x79f149e3, + 0xc8b93f49, 0x972702cd, 0xb07dd827, 0x6c97d5ed, + 0x085a3d61, 0x46eb5ea7, 0x3d9910ed, 0x2e687b5b, + 0x29609227, 0x6eb081f1, 0x0954c4e1, 0x9d114db9, + 0x542acfa9, 0xb3e6bd7b, 0x0742d917, 0xe9f3ffa7, + 0x54581edb, 0xf2480f45, 0x0bb9288f, 0xef1affc7, + 0x85fa0ca7, 0x3ccc14db, 0xe6baf34b, 0x343377f7, + 0x5ca19031, 0xe6d9293b, 0xf0a9f391, 0x5d2e980b, + 0xfc411073, 0xc3749363, 0xb892d829, 0x3549366b, + 0x629750ad, 0xb98294e5, 0x892d9483, 0xc235baf3, + 0x3d2402a3, 0x6bdef3c9, 0xbec333cd, 0x40c9520f +}; + +//------------------------------------------------------------------------ +// End of shared data layout +//------------------------------------------------------------------------ + +//------------------------------------------------------------------------ +// Shared data accessors +//------------------------------------------------------------------------ + +unsigned GetPrime ( unsigned seed ) { + return Primes[seed%(sizeof(Primes)/sizeof(Primes[0]))]; +} +#endif //__TBB_OLD_PRIMES_RNG + +//------------------------------------------------------------------------ +// __TBB_InitOnce +//------------------------------------------------------------------------ + +void __TBB_InitOnce::add_ref() { + if( ++count==1 ) + governor::acquire_resources(); +} + +void __TBB_InitOnce::remove_ref() { + int k = --count; + __TBB_ASSERT(k>=0,"removed __TBB_InitOnce ref that was not added?"); + if( k==0 ) { + governor::release_resources(); + ITT_FINI_ITTLIB(); + } +} + +//------------------------------------------------------------------------ +// One-time Initializations +//------------------------------------------------------------------------ + +//! Defined in cache_aligned_allocator.cpp +void initialize_cache_aligned_allocator(); + +//! Defined in scheduler.cpp +void Scheduler_OneTimeInitialization ( bool itt_present ); + +#if DO_ITT_NOTIFY + +static __itt_domain *tbb_domains[ITT_NUM_DOMAINS] = {}; + +struct resource_string { + const char *str; + __itt_string_handle *itt_str_handle; +}; + +// +// populate resource strings +// +#define TBB_STRING_RESOURCE( index_name, str ) { str, NULL }, +static resource_string strings_for_itt[] = { + #include "tbb/internal/_tbb_strings.h" + { "num_resource_strings", NULL } +}; +#undef TBB_STRING_RESOURCE + +static __itt_string_handle *ITT_get_string_handle(int idx) { + __TBB_ASSERT( idx >= 0 && idx < NUM_STRINGS, "string handle out of valid range"); + return (idx >= 0 && idx < NUM_STRINGS) ? strings_for_itt[idx].itt_str_handle : NULL; +} + +static void ITT_init_domains() { + tbb_domains[ITT_DOMAIN_MAIN] = __itt_domain_create( _T("tbb") ); + tbb_domains[ITT_DOMAIN_MAIN]->flags = 1; + tbb_domains[ITT_DOMAIN_FLOW] = __itt_domain_create( _T("tbb.flow") ); + tbb_domains[ITT_DOMAIN_FLOW]->flags = 1; + tbb_domains[ITT_DOMAIN_ALGO] = __itt_domain_create( _T("tbb.algorithm") ); + tbb_domains[ITT_DOMAIN_ALGO]->flags = 1; +} + +static void ITT_init_strings() { + for ( int i = 0; i < NUM_STRINGS; ++i ) { +#if _WIN32||_WIN64 + strings_for_itt[i].itt_str_handle = __itt_string_handle_createA( strings_for_itt[i].str ); +#else + strings_for_itt[i].itt_str_handle = __itt_string_handle_create( strings_for_itt[i].str ); +#endif + } +} + +static void ITT_init() { + ITT_init_domains(); + ITT_init_strings(); +} + +/** Thread-unsafe lazy one-time initialization of tools interop. + Used by both dummy handlers and general TBB one-time initialization routine. **/ +void ITT_DoUnsafeOneTimeInitialization () { + // Double check ITT_InitializationDone is necessary because the first check + // in ITT_DoOneTimeInitialization is not guarded with the __TBB_InitOnce lock. + if ( !ITT_InitializationDone ) { + ITT_Present = (__TBB_load_ittnotify()!=0); + if (ITT_Present) ITT_init(); + ITT_InitializationDone = true; + ITT_SYNC_CREATE(&market::theMarketMutex, SyncType_GlobalLock, SyncObj_SchedulerInitialization); + } +} + +/** Thread-safe lazy one-time initialization of tools interop. + Used by dummy handlers only. **/ +extern "C" +void ITT_DoOneTimeInitialization() { + if ( !ITT_InitializationDone ) { + __TBB_InitOnce::lock(); + ITT_DoUnsafeOneTimeInitialization(); + __TBB_InitOnce::unlock(); + } +} +#endif /* DO_ITT_NOTIFY */ + +//! Performs thread-safe lazy one-time general TBB initialization. +void DoOneTimeInitializations() { + suppress_unused_warning(_pad); + __TBB_InitOnce::lock(); + // No fence required for load of InitializationDone, because we are inside a critical section. + if( !__TBB_InitOnce::InitializationDone ) { + __TBB_InitOnce::add_ref(); + if( GetBoolEnvironmentVariable("TBB_VERSION") ) + PrintVersion(); + bool itt_present = false; +#if DO_ITT_NOTIFY + ITT_DoUnsafeOneTimeInitialization(); + itt_present = ITT_Present; +#endif /* DO_ITT_NOTIFY */ + initialize_cache_aligned_allocator(); + governor::initialize_rml_factory(); + Scheduler_OneTimeInitialization( itt_present ); + // Force processor groups support detection + governor::default_num_threads(); + // Force OS regular page size detection + governor::default_page_size(); + // Dump version data + governor::print_version_info(); + PrintExtraVersionInfo( "Tools support", itt_present ? "enabled" : "disabled" ); + __TBB_InitOnce::InitializationDone = true; + } + __TBB_InitOnce::unlock(); +} + +#if (_WIN32||_WIN64) && !__TBB_SOURCE_DIRECTLY_INCLUDED +//! Windows "DllMain" that handles startup and shutdown of dynamic library. +extern "C" bool WINAPI DllMain( HANDLE /*hinstDLL*/, DWORD reason, LPVOID lpvReserved ) { + switch( reason ) { + case DLL_PROCESS_ATTACH: + __TBB_InitOnce::add_ref(); + break; + case DLL_PROCESS_DETACH: + // Since THREAD_DETACH is not called for the main thread, call auto-termination + // here as well - but not during process shutdown (due to risk of a deadlock). + if( lpvReserved==NULL ) // library unload + governor::terminate_auto_initialized_scheduler(); + __TBB_InitOnce::remove_ref(); + // It is assumed that InitializationDone is not set after DLL_PROCESS_DETACH, + // and thus no race on InitializationDone is possible. + if( __TBB_InitOnce::initialization_done() ) { + // Remove reference that we added in DoOneTimeInitializations. + __TBB_InitOnce::remove_ref(); + } + break; + case DLL_THREAD_DETACH: + governor::terminate_auto_initialized_scheduler(); + break; + } + return true; +} +#endif /* (_WIN32||_WIN64) && !__TBB_SOURCE_DIRECTLY_INCLUDED */ + +void itt_store_pointer_with_release_v3( void* dst, void* src ) { + ITT_NOTIFY(sync_releasing, dst); + __TBB_store_with_release(*static_cast<void**>(dst),src); +} + +void* itt_load_pointer_with_acquire_v3( const void* src ) { + void* result = __TBB_load_with_acquire(*static_cast<void*const*>(src)); + ITT_NOTIFY(sync_acquired, const_cast<void*>(src)); + return result; +} + +#if DO_ITT_NOTIFY +void call_itt_notify_v5(int t, void *ptr) { + switch (t) { + case 0: ITT_NOTIFY(sync_prepare, ptr); break; + case 1: ITT_NOTIFY(sync_cancel, ptr); break; + case 2: ITT_NOTIFY(sync_acquired, ptr); break; + case 3: ITT_NOTIFY(sync_releasing, ptr); break; + } +} +#else +void call_itt_notify_v5(int /*t*/, void* /*ptr*/) {} +#endif + +#if DO_ITT_NOTIFY +const __itt_id itt_null_id = {0, 0, 0}; + +static inline __itt_domain* get_itt_domain( itt_domain_enum idx ) { + if (tbb_domains[idx] == NULL) { + ITT_DoOneTimeInitialization(); + } + return tbb_domains[idx]; +} + +static inline void itt_id_make(__itt_id *id, void* addr, unsigned long long extra) { + *id = __itt_id_make(addr, extra); +} + +static inline void itt_id_create(const __itt_domain *domain, __itt_id id) { + ITTNOTIFY_VOID_D1(id_create, domain, id); +} + +void itt_make_task_group_v7( itt_domain_enum domain, void *group, unsigned long long group_extra, + void *parent, unsigned long long parent_extra, string_index name_index ) { + if ( __itt_domain *d = get_itt_domain( domain ) ) { + __itt_id group_id = itt_null_id; + __itt_id parent_id = itt_null_id; + itt_id_make( &group_id, group, group_extra ); + itt_id_create( d, group_id ); + if ( parent ) { + itt_id_make( &parent_id, parent, parent_extra ); + } + __itt_string_handle *n = ITT_get_string_handle(name_index); + ITTNOTIFY_VOID_D3(task_group, d, group_id, parent_id, n); + } +} + +void itt_metadata_str_add_v7( itt_domain_enum domain, void *addr, unsigned long long addr_extra, + string_index key, const char *value ) { + if ( __itt_domain *d = get_itt_domain( domain ) ) { + __itt_id id = itt_null_id; + itt_id_make( &id, addr, addr_extra ); + __itt_string_handle *k = ITT_get_string_handle(key); + size_t value_length = strlen( value ); +#if _WIN32||_WIN64 + ITTNOTIFY_VOID_D4(metadata_str_addA, d, id, k, value, value_length); +#else + ITTNOTIFY_VOID_D4(metadata_str_add, d, id, k, value, value_length); +#endif + } +} + +void itt_metadata_ptr_add_v11( itt_domain_enum domain, void *addr, unsigned long long addr_extra, + string_index key, void *value ) { + if ( __itt_domain *d = get_itt_domain( domain ) ) { + __itt_id id = itt_null_id; + itt_id_make( &id, addr, addr_extra ); + __itt_string_handle *k = ITT_get_string_handle(key); +#if __TBB_x86_32 + ITTNOTIFY_VOID_D5(metadata_add, d, id, k, __itt_metadata_u32, 1, value); +#else + ITTNOTIFY_VOID_D5(metadata_add, d, id, k, __itt_metadata_u64, 1, value); +#endif + } +} + + +void itt_relation_add_v7( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, + itt_relation relation, void *addr1, unsigned long long addr1_extra ) { + if ( __itt_domain *d = get_itt_domain( domain ) ) { + __itt_id id0 = itt_null_id; + __itt_id id1 = itt_null_id; + itt_id_make( &id0, addr0, addr0_extra ); + itt_id_make( &id1, addr1, addr1_extra ); + ITTNOTIFY_VOID_D3(relation_add, d, id0, (__itt_relation)relation, id1); + } +} + +void itt_task_begin_v7( itt_domain_enum domain, void *task, unsigned long long task_extra, + void *parent, unsigned long long parent_extra, string_index name_index ) { + if ( __itt_domain *d = get_itt_domain( domain ) ) { + __itt_id task_id = itt_null_id; + __itt_id parent_id = itt_null_id; + if ( task ) { + itt_id_make( &task_id, task, task_extra ); + } + if ( parent ) { + itt_id_make( &parent_id, parent, parent_extra ); + } + __itt_string_handle *n = ITT_get_string_handle(name_index); + ITTNOTIFY_VOID_D3(task_begin, d, task_id, parent_id, n ); + } +} + +void itt_task_end_v7( itt_domain_enum domain ) { + if ( __itt_domain *d = get_itt_domain( domain ) ) { + ITTNOTIFY_VOID_D0(task_end, d); + } +} + +void itt_region_begin_v9( itt_domain_enum domain, void *region, unsigned long long region_extra, + void *parent, unsigned long long parent_extra, string_index /* name_index */ ) { + if ( __itt_domain *d = get_itt_domain( domain ) ) { + __itt_id region_id = itt_null_id; + __itt_id parent_id = itt_null_id; + itt_id_make( ®ion_id, region, region_extra ); + if ( parent ) { + itt_id_make( &parent_id, parent, parent_extra ); + } + ITTNOTIFY_VOID_D3(region_begin, d, region_id, parent_id, NULL ); + } +} + +void itt_region_end_v9( itt_domain_enum domain, void *region, unsigned long long region_extra ) { + if ( __itt_domain *d = get_itt_domain( domain ) ) { + __itt_id region_id = itt_null_id; + itt_id_make( ®ion_id, region, region_extra ); + ITTNOTIFY_VOID_D1( region_end, d, region_id ); + } +} + +#else // DO_ITT_NOTIFY + +void itt_make_task_group_v7( itt_domain_enum /*domain*/, void* /*group*/, unsigned long long /*group_extra*/, + void* /*parent*/, unsigned long long /*parent_extra*/, string_index /*name_index*/ ) { } + +void itt_metadata_str_add_v7( itt_domain_enum /*domain*/, void* /*addr*/, unsigned long long /*addr_extra*/, + string_index /*key*/, const char* /*value*/ ) { } + +void itt_relation_add_v7( itt_domain_enum /*domain*/, void* /*addr0*/, unsigned long long /*addr0_extra*/, + itt_relation /*relation*/, void* /*addr1*/, unsigned long long /*addr1_extra*/ ) { } + +void itt_metadata_ptr_add_v11( itt_domain_enum /*domain*/, void * /*addr*/, unsigned long long /*addr_extra*/, + string_index /*key*/, void * /*value*/ ) {} + +void itt_task_begin_v7( itt_domain_enum /*domain*/, void* /*task*/, unsigned long long /*task_extra*/, + void* /*parent*/, unsigned long long /*parent_extra*/, string_index /*name_index*/ ) { } + +void itt_task_end_v7( itt_domain_enum /*domain*/ ) { } + +void itt_region_begin_v9( itt_domain_enum /*domain*/, void* /*region*/, unsigned long long /*region_extra*/, + void* /*parent*/, unsigned long long /*parent_extra*/, string_index /*name_index*/ ) { } + +void itt_region_end_v9( itt_domain_enum /*domain*/, void* /*region*/, unsigned long long /*region_extra*/ ) { } + +#endif // DO_ITT_NOTIFY + +void* itt_load_pointer_v3( const void* src ) { + //TODO: replace this with __TBB_load_relaxed + void* result = *static_cast<void*const*>(src); + return result; +} + +void itt_set_sync_name_v3( void* obj, const tchar* name) { + ITT_SYNC_RENAME(obj, name); + suppress_unused_warning(obj, name); +} + +class control_storage { + friend class tbb::interface9::global_control; +protected: + size_t my_active_value; + atomic<global_control*> my_head; + spin_mutex my_list_mutex; + + virtual size_t default_value() const = 0; + virtual void apply_active() const {} + virtual bool is_first_arg_preferred(size_t a, size_t b) const { + return a>b; // prefer max by default + } + virtual size_t active_value() const { + return my_head? my_active_value : default_value(); + } +}; + +class allowed_parallelism_control : public padded<control_storage> { + virtual size_t default_value() const __TBB_override { + return max(1U, governor::default_num_threads()); + } + virtual bool is_first_arg_preferred(size_t a, size_t b) const __TBB_override { + return a<b; // prefer min allowed parallelism + } + virtual void apply_active() const __TBB_override { + __TBB_ASSERT( my_active_value>=1, NULL ); + // -1 to take master into account + market::set_active_num_workers( my_active_value-1 ); + } + virtual size_t active_value() const __TBB_override { +/* Reading of my_active_value is not synchronized with possible updating + of my_head by other thread. It's ok, as value of my_active_value became + not invalid, just obsolete. */ + if (!my_head) + return default_value(); + // non-zero, if market is active + const size_t workers = market::max_num_workers(); + // We can't exceed market's maximal number of workers. + // +1 to take master into account + return workers? min(workers+1, my_active_value): my_active_value; + } +public: + size_t active_value_if_present() const { + return my_head? my_active_value : 0; + } +}; + +class stack_size_control : public padded<control_storage> { + virtual size_t default_value() const __TBB_override { + return tbb::internal::ThreadStackSize; + } + virtual void apply_active() const __TBB_override { +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) + __TBB_ASSERT( false, "For Windows 8 Store* apps we must not set stack size" ); +#endif + } +}; + +static allowed_parallelism_control allowed_parallelism_ctl; +static stack_size_control stack_size_ctl; + +static control_storage *controls[] = {&allowed_parallelism_ctl, &stack_size_ctl}; + +unsigned market::app_parallelism_limit() { + return allowed_parallelism_ctl.active_value_if_present(); +} + +} // namespace internal + +namespace interface9 { + +using namespace internal; +using namespace tbb::internal; + +void global_control::internal_create() { + __TBB_ASSERT_RELEASE( my_param < global_control::parameter_max, NULL ); + control_storage *const c = controls[my_param]; + + spin_mutex::scoped_lock lock(c->my_list_mutex); + if (!c->my_head || c->is_first_arg_preferred(my_value, c->my_active_value)) { + c->my_active_value = my_value; + // to guarantee that apply_active() is called with current active value, + // calls it here and in internal_destroy() under my_list_mutex + c->apply_active(); + } + my_next = c->my_head; + // publish my_head, at this point my_active_value must be valid + c->my_head = this; +} + +void global_control::internal_destroy() { + global_control *prev = 0; + + __TBB_ASSERT_RELEASE( my_param < global_control::parameter_max, NULL ); + control_storage *const c = controls[my_param]; + __TBB_ASSERT( c->my_head, NULL ); + + // Concurrent reading and changing global parameter is possible. + // In this case, my_active_value may not match current state of parameters. + // This is OK because: + // 1) my_active_value is either current or previous + // 2) my_active_value is current on internal_destroy leave + spin_mutex::scoped_lock lock(c->my_list_mutex); + size_t new_active = (size_t)-1, old_active = c->my_active_value; + + if ( c->my_head != this ) + new_active = c->my_head->my_value; + else if ( c->my_head->my_next ) + new_active = c->my_head->my_next->my_value; + // if there is only one element, new_active will be set later + for ( global_control *curr = c->my_head; curr; prev = curr, curr = curr->my_next ) + if ( curr == this ) { + if ( prev ) + prev->my_next = my_next; + else + c->my_head = my_next; + } else + if (c->is_first_arg_preferred(curr->my_value, new_active)) + new_active = curr->my_value; + + if ( !c->my_head ) { + __TBB_ASSERT( new_active==(size_t)-1, NULL ); + new_active = c->default_value(); + } + if ( new_active != old_active ) { + c->my_active_value = new_active; + c->apply_active(); + } +} + +size_t global_control::active_value( int param ) { + __TBB_ASSERT_RELEASE( param < global_control::parameter_max, NULL ); + return controls[param]->active_value(); +} + +} // tbb::interface9 +} // namespace tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_main.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_main.h new file mode 100644 index 00000000..917e35dd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_main.h @@ -0,0 +1,95 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_tbb_main_H +#define _TBB_tbb_main_H + +#include "tbb/atomic.h" +#include "governor.h" +#include "tbb_environment.h" + +namespace tbb { + +namespace internal { + +void DoOneTimeInitializations (); + +//------------------------------------------------------------------------ +// __TBB_InitOnce +//------------------------------------------------------------------------ + +//! Class that supports TBB initialization. +/** It handles acquisition and release of global resources (e.g. TLS) during startup and shutdown, + as well as synchronization for DoOneTimeInitializations. */ +class __TBB_InitOnce { + friend void DoOneTimeInitializations(); + friend void ITT_DoUnsafeOneTimeInitialization (); + + static atomic<int> count; + + //! Platform specific code to acquire resources. + static void acquire_resources(); + + //! Platform specific code to release resources. + static void release_resources(); + + //! Specifies if the one-time initializations has been done. + static bool InitializationDone; + + //! Global initialization lock + /** Scenarios are possible when tools interop has to be initialized before the + TBB itself. This imposes a requirement that the global initialization lock + has to support valid static initialization, and does not issue any tool + notifications in any build mode. **/ + static __TBB_atomic_flag InitializationLock; + +public: + static void lock() { __TBB_LockByte( InitializationLock ); } + + static void unlock() { __TBB_UnlockByte( InitializationLock ); } + + static bool initialization_done() { return __TBB_load_with_acquire(InitializationDone); } + + //! Add initial reference to resources. + /** We assume that dynamic loading of the library prevents any other threads + from entering the library until this constructor has finished running. **/ + __TBB_InitOnce() { add_ref(); } + + //! Remove the initial reference to resources. + /** This is not necessarily the last reference if other threads are still running. **/ + ~__TBB_InitOnce() { + governor::terminate_auto_initialized_scheduler(); // TLS dtor not called for the main thread + remove_ref(); + // We assume that InitializationDone is not set after file-scope destructors + // start running, and thus no race on InitializationDone is possible. + if( initialization_done() ) { + // Remove an extra reference that was added in DoOneTimeInitializations. + remove_ref(); + } + } + //! Add reference to resources. If first reference added, acquire the resources. + static void add_ref(); + + //! Remove reference to resources. If last reference removed, release the resources. + static void remove_ref(); +}; // class __TBB_InitOnce + + +} // namespace internal + +} // namespace tbb + +#endif /* _TBB_tbb_main_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc.cpp new file mode 100644 index 00000000..7c4fec50 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc.cpp @@ -0,0 +1,318 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Source file for miscellaneous entities that are infrequently referenced by +// an executing program. + +#include "tbb/tbb_stddef.h" +#include "tbb_assert_impl.h" // Out-of-line TBB assertion handling routines are instantiated here. +#include "tbb/tbb_exception.h" +#include "tbb/tbb_machine.h" +#include "tbb_misc.h" +#include "tbb_version.h" + +#include <cstdio> +#include <cstdlib> +#include <stdexcept> +#include <cstring> + +#if _WIN32||_WIN64 +#include "tbb/machine/windows_api.h" +#endif + +#if !_WIN32 +#include <unistd.h> // sysconf(_SC_PAGESIZE) +#endif + +#define __TBB_STD_RETHROW_EXCEPTION_POSSIBLY_BROKEN \ + (__GLIBCXX__ && __TBB_GLIBCXX_VERSION>=40700 && __TBB_GLIBCXX_VERSION<60000 \ + && TBB_USE_EXCEPTIONS && !TBB_USE_CAPTURED_EXCEPTION) + +#if __TBB_STD_RETHROW_EXCEPTION_POSSIBLY_BROKEN +// GCC ABI declarations necessary for a workaround +#include <cxxabi.h> +#endif + +namespace tbb { + +const char* bad_last_alloc::what() const throw() { return "bad allocation in previous or concurrent attempt"; } +const char* improper_lock::what() const throw() { return "attempted recursive lock on critical section or non-recursive mutex"; } +const char* user_abort::what() const throw() { return "User-initiated abort has terminated this operation"; } +const char* invalid_multiple_scheduling::what() const throw() { return "The same task_handle object cannot be executed more than once"; } +const char* missing_wait::what() const throw() { return "wait() was not called on the structured_task_group"; } + +namespace internal { + +#if TBB_USE_EXCEPTIONS + #define DO_THROW(exc, init_args) throw exc init_args; +#else /* !TBB_USE_EXCEPTIONS */ + #define PRINT_ERROR_AND_ABORT(exc_name, msg) \ + fprintf (stderr, "Exception %s with message %s would've been thrown, " \ + "if exception handling were not disabled. Aborting.\n", exc_name, msg); \ + fflush(stderr); \ + std::abort(); + #define DO_THROW(exc, init_args) PRINT_ERROR_AND_ABORT(#exc, #init_args) +#endif /* !TBB_USE_EXCEPTIONS */ + +size_t DefaultSystemPageSize() { +#if _WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwPageSize; +#else + return sysconf(_SC_PAGESIZE); +#endif +} + +/* The "what" should be fairly short, not more than about 128 characters. + Because we control all the call sites to handle_perror, it is pointless + to bullet-proof it for very long strings. + + Design note: ADR put this routine off to the side in tbb_misc.cpp instead of + Task.cpp because the throw generates a pathetic lot of code, and ADR wanted + this large chunk of code to be placed on a cold page. */ +void handle_perror( int error_code, const char* what ) { + char buf[256]; +#if _MSC_VER + #define snprintf _snprintf +#endif + int written = snprintf(buf, sizeof(buf), "%s: %s", what, strerror( error_code )); + // On overflow, the returned value exceeds sizeof(buf) (for GLIBC) or is negative (for MSVC). + __TBB_ASSERT_EX( written>0 && written<(int)sizeof(buf), "Error description is too long" ); + // Ensure that buffer ends in terminator. + buf[sizeof(buf)-1] = 0; +#if TBB_USE_EXCEPTIONS + throw std::runtime_error(buf); +#else + PRINT_ERROR_AND_ABORT( "runtime_error", buf); +#endif /* !TBB_USE_EXCEPTIONS */ +} + +#if _WIN32||_WIN64 +void handle_win_error( int error_code ) { + char buf[512]; +#if !__TBB_WIN8UI_SUPPORT + FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error_code, 0, buf, sizeof(buf), NULL ); +#else +//TODO: update with right replacement for FormatMessageA + sprintf_s((char*)&buf, 512, "error code %d", error_code); +#endif +#if TBB_USE_EXCEPTIONS + throw std::runtime_error(buf); +#else + PRINT_ERROR_AND_ABORT( "runtime_error", buf); +#endif /* !TBB_USE_EXCEPTIONS */ +} +#endif // _WIN32||_WIN64 + +void throw_bad_last_alloc_exception_v4() { + throw_exception_v4(eid_bad_last_alloc); +} + +void throw_exception_v4 ( exception_id eid ) { + __TBB_ASSERT ( eid > 0 && eid < eid_max, "Unknown exception ID" ); + switch ( eid ) { + case eid_bad_alloc: DO_THROW(std::bad_alloc, () ); + case eid_bad_last_alloc: DO_THROW( bad_last_alloc, () ); + case eid_nonpositive_step: DO_THROW(std::invalid_argument, ("Step must be positive") ); + case eid_out_of_range: DO_THROW(std::out_of_range, ("Index out of requested size range") ); + case eid_segment_range_error: DO_THROW(std::range_error, ("Index out of allocated segment slots") ); + case eid_index_range_error: DO_THROW(std::range_error, ("Index is not allocated") ); + case eid_missing_wait: DO_THROW( missing_wait, () ); + case eid_invalid_multiple_scheduling: DO_THROW( invalid_multiple_scheduling, () ); + case eid_improper_lock: DO_THROW( improper_lock, () ); + case eid_possible_deadlock: DO_THROW(std::runtime_error, ("Resource deadlock would occur") ); + case eid_operation_not_permitted: DO_THROW(std::runtime_error, ("Operation not permitted") ); + case eid_condvar_wait_failed: DO_THROW(std::runtime_error, ("Wait on condition variable failed") ); + case eid_invalid_load_factor: DO_THROW(std::out_of_range, ("Invalid hash load factor") ); + case eid_reserved: DO_THROW(std::out_of_range, ("[backward compatibility] Invalid number of buckets") ); + case eid_invalid_swap: DO_THROW(std::invalid_argument, ("swap() is invalid on non-equal allocators") ); + case eid_reservation_length_error: DO_THROW(std::length_error, ("reservation size exceeds permitted max size") ); + case eid_invalid_key: DO_THROW(std::out_of_range, ("invalid key") ); + case eid_user_abort: DO_THROW( user_abort, () ); + case eid_bad_tagged_msg_cast: DO_THROW(std::runtime_error, ("Illegal tagged_msg cast") ); +#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE + case eid_blocking_thread_join_impossible: DO_THROW(std::runtime_error, ("Blocking terminate failed") ); +#endif + default: break; + } +#if !TBB_USE_EXCEPTIONS && __APPLE__ + out_of_range e1(""); + length_error e2(""); + range_error e3(""); + invalid_argument e4(""); +#endif /* !TBB_USE_EXCEPTIONS && __APPLE__ */ +} + +#if __TBB_STD_RETHROW_EXCEPTION_POSSIBLY_BROKEN +// Runtime detection and workaround for the GCC bug 62258. +// The problem is that std::rethrow_exception() does not increment a counter +// of active exceptions, causing std::uncaught_exception() to return a wrong value. +// The code is created after, and roughly reflects, the workaround +// at https://gcc.gnu.org/bugzilla/attachment.cgi?id=34683 + +void fix_broken_rethrow() { + struct gcc_eh_data { + void * caughtExceptions; + unsigned int uncaughtExceptions; + }; + gcc_eh_data* eh_data = punned_cast<gcc_eh_data*>( abi::__cxa_get_globals() ); + ++eh_data->uncaughtExceptions; +} + +bool gcc_rethrow_exception_broken() { + bool is_broken; + __TBB_ASSERT( !std::uncaught_exception(), + "gcc_rethrow_exception_broken() must not be called when an exception is active" ); + try { + // Throw, catch, and rethrow an exception + try { + throw __TBB_GLIBCXX_VERSION; + } catch(...) { + std::rethrow_exception( std::current_exception() ); + } + } catch(...) { + // Check the bug presence + is_broken = std::uncaught_exception(); + } + if( is_broken ) fix_broken_rethrow(); + __TBB_ASSERT( !std::uncaught_exception(), NULL ); + return is_broken; +} +#else +void fix_broken_rethrow() {} +bool gcc_rethrow_exception_broken() { return false; } +#endif /* __TBB_STD_RETHROW_EXCEPTION_POSSIBLY_BROKEN */ + +/** The leading "\0" is here so that applying "strings" to the binary delivers a clean result. */ +static const char VersionString[] = "\0" TBB_VERSION_STRINGS; + +static bool PrintVersionFlag = false; + +void PrintVersion() { + PrintVersionFlag = true; + fputs(VersionString+1,stderr); +} + +void PrintExtraVersionInfo( const char* category, const char* format, ... ) { + if( PrintVersionFlag ) { + char str[1024]; memset(str, 0, 1024); + va_list args; va_start(args, format); + // Note: correct vsnprintf definition obtained from tbb_assert_impl.h + vsnprintf( str, 1024-1, format, args); + va_end(args); + fprintf(stderr, "TBB: %s\t%s\n", category, str ); + } +} + +void PrintRMLVersionInfo( void* arg, const char* server_info ) { + PrintExtraVersionInfo( server_info, (const char *)arg ); +} + +//! check for transaction support. +#if _MSC_VER +#include <intrin.h> // for __cpuid +#endif +bool cpu_has_speculation() { +#if __TBB_TSX_AVAILABLE +#if (__INTEL_COMPILER || __GNUC__ || _MSC_VER || __SUNPRO_CC) + bool result = false; + const int rtm_ebx_mask = 1<<11; +#if _MSC_VER + int info[4] = {0,0,0,0}; + const int reg_ebx = 1; + __cpuidex(info, 7, 0); + result = (info[reg_ebx] & rtm_ebx_mask)!=0; +#elif __GNUC__ || __SUNPRO_CC + int32_t reg_ebx = 0; + int32_t reg_eax = 7; + int32_t reg_ecx = 0; + __asm__ __volatile__ ( "movl %%ebx, %%esi\n" + "cpuid\n" + "movl %%ebx, %0\n" + "movl %%esi, %%ebx\n" + : "=a"(reg_ebx) : "0" (reg_eax), "c" (reg_ecx) : "esi", +#if __TBB_x86_64 + "ebx", +#endif + "edx" + ); + result = (reg_ebx & rtm_ebx_mask)!=0 ; +#endif + return result; +#else + #error Speculation detection not enabled for compiler +#endif /* __INTEL_COMPILER || __GNUC__ || _MSC_VER */ +#else /* __TBB_TSX_AVAILABLE */ + return false; +#endif /* __TBB_TSX_AVAILABLE */ +} + +} // namespace internal + +extern "C" int TBB_runtime_interface_version() { + return TBB_INTERFACE_VERSION; +} + +} // namespace tbb + +#if !__TBB_RML_STATIC +#if __TBB_x86_32 + +#include "tbb/atomic.h" + +// in MSVC environment, int64_t defined in tbb::internal namespace only (see tbb_stddef.h) +#if _MSC_VER +using tbb::internal::int64_t; +#endif + +//! Warn about 8-byte store that crosses a cache line. +extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr ) { + // Report run-time warning unless we have already recently reported warning for that address. + const unsigned n = 4; + static tbb::atomic<void*> cache[n]; + static tbb::atomic<unsigned> k; + for( unsigned i=0; i<n; ++i ) + if( ptr==cache[i] ) + goto done; + cache[(k++)%n] = const_cast<void*>(ptr); + tbb::internal::runtime_warning( "atomic store on misaligned 8-byte location %p is slow", ptr ); +done:; +} + +//! Handle 8-byte store that crosses a cache line. +extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value ) { + for( tbb::internal::atomic_backoff b;;b.pause() ) { + int64_t tmp = *(int64_t*)ptr; + if( __TBB_machine_cmpswp8(ptr,value,tmp)==tmp ) + break; + } +} + +#endif /* __TBB_x86_32 */ +#endif /* !__TBB_RML_STATIC */ + +#if __TBB_ipf +/* It was found that on IA-64 architecture inlining of __TBB_machine_lockbyte leads + to serious performance regression with ICC. So keep it out-of-line. + */ +extern "C" intptr_t __TBB_machine_lockbyte( volatile unsigned char& flag ) { + tbb::internal::atomic_backoff backoff; + while( !__TBB_TryLockByte(flag) ) backoff.pause(); + return 0; +} +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc.h new file mode 100644 index 00000000..31d887b8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc.h @@ -0,0 +1,292 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_tbb_misc_H +#define _TBB_tbb_misc_H + +#include "tbb/tbb_stddef.h" +#include "tbb/tbb_machine.h" +#include "tbb/atomic.h" // For atomic_xxx definitions + +#if __TBB_NUMA_SUPPORT +#include "tbb/info.h" +#endif /*__TBB_NUMA_SUPPORT*/ + +#if __linux__ || __FreeBSD__ +#include <sys/param.h> // __FreeBSD_version +#if __FreeBSD_version >= 701000 +#include <sys/cpuset.h> +#endif +#endif + +// Does the operating system have a system call to pin a thread to a set of OS processors? +#define __TBB_OS_AFFINITY_SYSCALL_PRESENT ((__linux__ && !__ANDROID__) || (__FreeBSD_version >= 701000)) +// On IBM* Blue Gene* CNK nodes, the affinity API has restrictions that prevent its usability for TBB, +// and also sysconf(_SC_NPROCESSORS_ONLN) already takes process affinity into account. +#define __TBB_USE_OS_AFFINITY_SYSCALL (__TBB_OS_AFFINITY_SYSCALL_PRESENT && !__bg__) + +namespace tbb { + +namespace internal { + +const size_t MByte = 1024*1024; + +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) +// In Win8UI mode (Windows 8 Store* applications), TBB uses a thread creation API +// that does not allow to specify the stack size. +// Still, the thread stack size value, either explicit or default, is used by the scheduler. +// So here we set the default value to match the platform's default of 1MB. +const size_t ThreadStackSize = 1*MByte; +#else +const size_t ThreadStackSize = (sizeof(uintptr_t) <= 4 ? 2 : 4 )*MByte; +#endif + +#ifndef __TBB_HardwareConcurrency + +//! Returns maximal parallelism level supported by the current OS configuration. +int AvailableHwConcurrency(); + +#else + +inline int AvailableHwConcurrency() { + int n = __TBB_HardwareConcurrency(); + return n > 0 ? n : 1; // Fail safety strap +} +#endif /* __TBB_HardwareConcurrency */ + +//! Returns OS regular memory page size +size_t DefaultSystemPageSize(); + +#if _WIN32||_WIN64 + +//! Returns number of processor groups in the current OS configuration. +/** AvailableHwConcurrency must be called at least once before calling this method. **/ +int NumberOfProcessorGroups(); + +//! Retrieves index of processor group containing processor with the given index +int FindProcessorGroupIndex ( int processorIndex ); + +//! Affinitizes the thread to the specified processor group +void MoveThreadIntoProcessorGroup( void* hThread, int groupIndex ); + +#endif /* _WIN32||_WIN64 */ + +//! Throws std::runtime_error with what() returning error_code description prefixed with aux_info +void handle_win_error( int error_code ); + +//! Prints TBB version information on stderr +void PrintVersion(); + +//! Prints arbitrary extra TBB version information on stderr +void PrintExtraVersionInfo( const char* category, const char* format, ... ); + +//! A callback routine to print RML version information on stderr +void PrintRMLVersionInfo( void* arg, const char* server_info ); + +// For TBB compilation only; not to be used in public headers +#if defined(min) || defined(max) +#undef min +#undef max +#endif + +//! Utility template function returning lesser of the two values. +/** Provided here to avoid including not strict safe <algorithm>.\n + In case operands cause signed/unsigned or size mismatch warnings it is caller's + responsibility to do the appropriate cast before calling the function. **/ +template<typename T> +T min ( const T& val1, const T& val2 ) { + return val1 < val2 ? val1 : val2; +} + +//! Utility template function returning greater of the two values. +/** Provided here to avoid including not strict safe <algorithm>.\n + In case operands cause signed/unsigned or size mismatch warnings it is caller's + responsibility to do the appropriate cast before calling the function. **/ +template<typename T> +T max ( const T& val1, const T& val2 ) { + return val1 < val2 ? val2 : val1; +} + +//! Utility helper structure to ease overload resolution +template<int > struct int_to_type {}; + +//------------------------------------------------------------------------ +// FastRandom +//------------------------------------------------------------------------ + +/** Defined in tbb_main.cpp **/ +unsigned GetPrime ( unsigned seed ); + +//! A fast random number generator. +/** Uses linear congruential method. */ +class FastRandom { +private: +#if __TBB_OLD_PRIMES_RNG + unsigned x, a; + static const unsigned c = 1; +#else + unsigned x, c; + static const unsigned a = 0x9e3779b1; // a big prime number +#endif //__TBB_OLD_PRIMES_RNG +public: + //! Get a random number. + unsigned short get() { + return get(x); + } + //! Get a random number for the given seed; update the seed for next use. + unsigned short get( unsigned& seed ) { + unsigned short r = (unsigned short)(seed>>16); + __TBB_ASSERT(c&1, "c must be odd for big rng period"); + seed = seed*a+c; + return r; + } + //! Construct a random number generator. + FastRandom( void* unique_ptr ) { init(uintptr_t(unique_ptr)); } + FastRandom( uint32_t seed) { init(seed); } + FastRandom( uint64_t seed) { init(seed); } + template <typename T> + void init( T seed ) { + init(seed,int_to_type<sizeof(seed)>()); + } + void init( uint64_t seed , int_to_type<8> ) { + init(uint32_t((seed>>32)+seed), int_to_type<4>()); + } + void init( uint32_t seed, int_to_type<4> ) { +#if __TBB_OLD_PRIMES_RNG + x = seed; + a = GetPrime( seed ); +#else + // threads use different seeds for unique sequences + c = (seed|1)*0xba5703f5; // c must be odd, shuffle by a prime number + x = c^(seed>>1); // also shuffle x for the first get() invocation +#endif + } +}; + +//------------------------------------------------------------------------ +// Atomic extensions +//------------------------------------------------------------------------ + +//! Atomically replaces value of dst with newValue if they satisfy condition of compare predicate +/** Return value semantics is the same as for CAS. **/ +template<typename T1, typename T2, class Pred> +T1 atomic_update ( tbb::atomic<T1>& dst, T2 newValue, Pred compare ) { + T1 oldValue = dst; + while ( compare(oldValue, newValue) ) { + if ( dst.compare_and_swap((T1)newValue, oldValue) == oldValue ) + break; + oldValue = dst; + } + return oldValue; +} + +//! One-time initialization states +enum do_once_state { + do_once_uninitialized = 0, ///< No execution attempts have been undertaken yet + do_once_pending, ///< A thread is executing associated do-once routine + do_once_executed, ///< Do-once routine has been executed + initialization_complete = do_once_executed ///< Convenience alias +}; + +//! One-time initialization function +/** /param initializer Pointer to function without arguments + The variant that returns bool is used for cases when initialization can fail + and it is OK to continue execution, but the state should be reset so that + the initialization attempt was repeated the next time. + /param state Shared state associated with initializer that specifies its + initialization state. Must be initially set to #uninitialized value + (e.g. by means of default static zero initialization). **/ +template <typename F> +void atomic_do_once ( const F& initializer, atomic<do_once_state>& state ) { + // tbb::atomic provides necessary acquire and release fences. + // The loop in the implementation is necessary to avoid race when thread T2 + // that arrived in the middle of initialization attempt by another thread T1 + // has just made initialization possible. + // In such a case T2 has to rely on T1 to initialize, but T1 may already be past + // the point where it can recognize the changed conditions. + while ( state != do_once_executed ) { + if( state == do_once_uninitialized ) { + if( state.compare_and_swap( do_once_pending, do_once_uninitialized ) == do_once_uninitialized ) { + run_initializer( initializer, state ); + break; + } + } + spin_wait_while_eq( state, do_once_pending ); + } +} + +// Run the initializer which can not fail +inline void run_initializer( void (*f)(), atomic<do_once_state>& state ) { + f(); + state = do_once_executed; +} + +// Run the initializer which can require repeated call +inline void run_initializer( bool (*f)(), atomic<do_once_state>& state ) { + state = f() ? do_once_executed : do_once_uninitialized; +} + +#if __TBB_USE_OS_AFFINITY_SYSCALL + #if __linux__ + typedef cpu_set_t basic_mask_t; + #elif __FreeBSD_version >= 701000 + typedef cpuset_t basic_mask_t; + #else + #error affinity_helper is not implemented in this OS + #endif + class affinity_helper : no_copy { + basic_mask_t* threadMask; + int is_changed; + public: + affinity_helper() : threadMask(NULL), is_changed(0) {} + ~affinity_helper(); + void protect_affinity_mask( bool restore_process_mask ); + void dismiss(); + }; + void destroy_process_mask(); +#else + class affinity_helper : no_copy { + public: + void protect_affinity_mask( bool ) {} + void dismiss() {} + }; + inline void destroy_process_mask(){} +#endif /* __TBB_USE_OS_AFFINITY_SYSCALL */ + +bool cpu_has_speculation(); +bool gcc_rethrow_exception_broken(); +void fix_broken_rethrow(); + +#if __TBB_NUMA_SUPPORT +class binding_handler; + +binding_handler* construct_binding_handler(int slot_num); +void destroy_binding_handler(binding_handler* handler_ptr); +void bind_thread_to_node(binding_handler* handler_ptr, int slot_num , int numa_id); +void restore_affinity_mask(binding_handler* handler_ptr, int slot_num); + +namespace numa_topology { + bool is_initialized(); + void initialize(); + void destroy(); +} + +#endif /*__TBB_NUMA_SUPPORT*/ + +} // namespace internal +} // namespace tbb + +#endif /* _TBB_tbb_misc_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc_ex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc_ex.cpp new file mode 100644 index 00000000..a35792b6 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_misc_ex.cpp @@ -0,0 +1,401 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Source file for miscellaneous entities that are infrequently referenced by +// an executing program, and implementation of which requires dynamic linking. + +#include "tbb_misc.h" + +#if !defined(__TBB_HardwareConcurrency) + +#include "dynamic_link.h" +#include <stdio.h> +#include <limits.h> + +#if _WIN32||_WIN64 +#include "tbb/machine/windows_api.h" +#if __TBB_WIN8UI_SUPPORT +#include <thread> +#endif +#else +#include <unistd.h> +#if __linux__ +#include <sys/sysinfo.h> +#include <string.h> +#include <sched.h> +#include <errno.h> +#elif __sun +#include <sys/sysinfo.h> +#elif __FreeBSD__ +#include <errno.h> +#include <string.h> +#include <sys/param.h> // Required by <sys/cpuset.h> +#include <sys/cpuset.h> +#endif +#endif + +namespace tbb { +namespace internal { + +#if __TBB_USE_OS_AFFINITY_SYSCALL + +#if __linux__ +// Handlers for interoperation with libiomp +static int (*libiomp_try_restoring_original_mask)(); +// Table for mapping to libiomp entry points +static const dynamic_link_descriptor iompLinkTable[] = { + DLD_NOWEAK( kmp_set_thread_affinity_mask_initial, libiomp_try_restoring_original_mask ) +}; +#endif + +static void set_thread_affinity_mask( size_t maskSize, const basic_mask_t* threadMask ) { +#if __linux__ + if( sched_setaffinity( 0, maskSize, threadMask ) ) +#else /* FreeBSD */ + if( cpuset_setaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, maskSize, threadMask ) ) +#endif + runtime_warning( "setaffinity syscall failed" ); +} + +static void get_thread_affinity_mask( size_t maskSize, basic_mask_t* threadMask ) { +#if __linux__ + if( sched_getaffinity( 0, maskSize, threadMask ) ) +#else /* FreeBSD */ + if( cpuset_getaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, maskSize, threadMask ) ) +#endif + runtime_warning( "getaffinity syscall failed" ); +} + +static basic_mask_t* process_mask; +static int num_masks; + +void destroy_process_mask() { + if( process_mask ) { + delete [] process_mask; + } +} + +#define curMaskSize sizeof(basic_mask_t) * num_masks +affinity_helper::~affinity_helper() { + if( threadMask ) { + if( is_changed ) { + set_thread_affinity_mask( curMaskSize, threadMask ); + } + delete [] threadMask; + } +} +void affinity_helper::protect_affinity_mask( bool restore_process_mask ) { + if( threadMask == NULL && num_masks ) { // TODO: assert num_masks validity? + threadMask = new basic_mask_t [num_masks]; + memset( threadMask, 0, curMaskSize ); + get_thread_affinity_mask( curMaskSize, threadMask ); + if( restore_process_mask ) { + __TBB_ASSERT( process_mask, "A process mask is requested but not yet stored" ); + is_changed = memcmp( process_mask, threadMask, curMaskSize ); + if( is_changed ) + set_thread_affinity_mask( curMaskSize, process_mask ); + } else { + // Assume that the mask will be changed by the caller. + is_changed = 1; + } + } +} +void affinity_helper::dismiss() { + if( threadMask ) { + delete [] threadMask; + threadMask = NULL; + } + is_changed = 0; +} +#undef curMaskSize + +static atomic<do_once_state> hardware_concurrency_info; + +static int theNumProcs; + +static void initialize_hardware_concurrency_info () { + int err; + int availableProcs = 0; + int numMasks = 1; +#if __linux__ +#if __TBB_MAIN_THREAD_AFFINITY_BROKEN + int maxProcs = INT_MAX; // To check the entire mask. + int pid = 0; // Get the mask of the calling thread. +#else + int maxProcs = sysconf(_SC_NPROCESSORS_ONLN); + int pid = getpid(); +#endif +#else /* FreeBSD >= 7.1 */ + int maxProcs = sysconf(_SC_NPROCESSORS_ONLN); +#endif + basic_mask_t* processMask; + const size_t BasicMaskSize = sizeof(basic_mask_t); + for (;;) { + const int curMaskSize = BasicMaskSize * numMasks; + processMask = new basic_mask_t[numMasks]; + memset( processMask, 0, curMaskSize ); +#if __linux__ + err = sched_getaffinity( pid, curMaskSize, processMask ); + if ( !err || errno != EINVAL || curMaskSize * CHAR_BIT >= 256 * 1024 ) + break; +#else /* FreeBSD >= 7.1 */ + // CPU_LEVEL_WHICH - anonymous (current) mask, CPU_LEVEL_CPUSET - assigned mask +#if __TBB_MAIN_THREAD_AFFINITY_BROKEN + err = cpuset_getaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, curMaskSize, processMask ); +#else + err = cpuset_getaffinity( CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, curMaskSize, processMask ); +#endif + if ( !err || errno != ERANGE || curMaskSize * CHAR_BIT >= 16 * 1024 ) + break; +#endif /* FreeBSD >= 7.1 */ + delete[] processMask; + numMasks <<= 1; + } + if ( !err ) { + // We have found the mask size and captured the process affinity mask into processMask. + num_masks = numMasks; // do here because it's needed for affinity_helper to work +#if __linux__ + // For better coexistence with libiomp which might have changed the mask already, + // check for its presence and ask it to restore the mask. + dynamic_link_handle libhandle; + if ( dynamic_link( "libiomp5.so", iompLinkTable, 1, &libhandle, DYNAMIC_LINK_GLOBAL ) ) { + // We have found the symbol provided by libiomp5 for restoring original thread affinity. + affinity_helper affhelp; + affhelp.protect_affinity_mask( /*restore_process_mask=*/false ); + if ( libiomp_try_restoring_original_mask()==0 ) { + // Now we have the right mask to capture, restored by libiomp. + const int curMaskSize = BasicMaskSize * numMasks; + memset( processMask, 0, curMaskSize ); + get_thread_affinity_mask( curMaskSize, processMask ); + } else + affhelp.dismiss(); // thread mask has not changed + dynamic_unlink( libhandle ); + // Destructor of affinity_helper restores the thread mask (unless dismissed). + } +#endif + for ( int m = 0; availableProcs < maxProcs && m < numMasks; ++m ) { + for ( size_t i = 0; (availableProcs < maxProcs) && (i < BasicMaskSize * CHAR_BIT); ++i ) { + if ( CPU_ISSET( i, processMask + m ) ) + ++availableProcs; + } + } + process_mask = processMask; + } + else { + // Failed to get the process affinity mask; assume the whole machine can be used. + availableProcs = (maxProcs == INT_MAX) ? sysconf(_SC_NPROCESSORS_ONLN) : maxProcs; + delete[] processMask; + } + theNumProcs = availableProcs > 0 ? availableProcs : 1; // Fail safety strap + __TBB_ASSERT( theNumProcs <= sysconf(_SC_NPROCESSORS_ONLN), NULL ); +} + +int AvailableHwConcurrency() { + atomic_do_once( &initialize_hardware_concurrency_info, hardware_concurrency_info ); + return theNumProcs; +} + +/* End of __TBB_USE_OS_AFFINITY_SYSCALL implementation */ +#elif __ANDROID__ + +// Work-around for Android that reads the correct number of available CPUs since system calls are unreliable. +// Format of "present" file is: ([<int>-<int>|<int>],)+ +int AvailableHwConcurrency() { + FILE *fp = fopen("/sys/devices/system/cpu/present", "r"); + if (fp == NULL) return 1; + int num_args, lower, upper, num_cpus=0; + while ((num_args = fscanf(fp, "%u-%u", &lower, &upper)) != EOF) { + switch(num_args) { + case 2: num_cpus += upper - lower + 1; break; + case 1: num_cpus += 1; break; + } + fscanf(fp, ","); + } + return (num_cpus > 0) ? num_cpus : 1; +} + +#elif defined(_SC_NPROCESSORS_ONLN) + +int AvailableHwConcurrency() { + int n = sysconf(_SC_NPROCESSORS_ONLN); + return (n > 0) ? n : 1; +} + +#elif _WIN32||_WIN64 + +static atomic<do_once_state> hardware_concurrency_info; + +static const WORD TBB_ALL_PROCESSOR_GROUPS = 0xffff; + +// Statically allocate an array for processor group information. +// Windows 7 supports maximum 4 groups, but let's look ahead a little. +static const WORD MaxProcessorGroups = 64; + +struct ProcessorGroupInfo { + DWORD_PTR mask; ///< Affinity mask covering the whole group + int numProcs; ///< Number of processors in the group + int numProcsRunningTotal; ///< Subtotal of processors in this and preceding groups + + //! Total number of processor groups in the system + static int NumGroups; + + //! Index of the group with a slot reserved for the first master thread + /** In the context of multiple processor groups support current implementation + defines "the first master thread" as the first thread to invoke + AvailableHwConcurrency(). + + TODO: Implement a dynamic scheme remapping workers depending on the pending + master threads affinity. **/ + static int HoleIndex; +}; + +int ProcessorGroupInfo::NumGroups = 1; +int ProcessorGroupInfo::HoleIndex = 0; + +ProcessorGroupInfo theProcessorGroups[MaxProcessorGroups]; + +struct TBB_GROUP_AFFINITY { + DWORD_PTR Mask; + WORD Group; + WORD Reserved[3]; +}; + +static DWORD (WINAPI *TBB_GetActiveProcessorCount)( WORD groupIndex ) = NULL; +static WORD (WINAPI *TBB_GetActiveProcessorGroupCount)() = NULL; +static BOOL (WINAPI *TBB_SetThreadGroupAffinity)( HANDLE hThread, + const TBB_GROUP_AFFINITY* newAff, TBB_GROUP_AFFINITY *prevAff ); +static BOOL (WINAPI *TBB_GetThreadGroupAffinity)( HANDLE hThread, TBB_GROUP_AFFINITY* ); + +static const dynamic_link_descriptor ProcessorGroupsApiLinkTable[] = { + DLD(GetActiveProcessorCount, TBB_GetActiveProcessorCount) + , DLD(GetActiveProcessorGroupCount, TBB_GetActiveProcessorGroupCount) + , DLD(SetThreadGroupAffinity, TBB_SetThreadGroupAffinity) + , DLD(GetThreadGroupAffinity, TBB_GetThreadGroupAffinity) +}; + +static void initialize_hardware_concurrency_info () { +#if __TBB_WIN8UI_SUPPORT + // For these applications processor groups info is unavailable + // Setting up a number of processors for one processor group + theProcessorGroups[0].numProcs = theProcessorGroups[0].numProcsRunningTotal = std::thread::hardware_concurrency(); +#else /* __TBB_WIN8UI_SUPPORT */ + dynamic_link( "Kernel32.dll", ProcessorGroupsApiLinkTable, + sizeof(ProcessorGroupsApiLinkTable)/sizeof(dynamic_link_descriptor) ); + SYSTEM_INFO si; + GetNativeSystemInfo(&si); + DWORD_PTR pam, sam, m = 1; + GetProcessAffinityMask( GetCurrentProcess(), &pam, &sam ); + int nproc = 0; + for ( size_t i = 0; i < sizeof(DWORD_PTR) * CHAR_BIT; ++i, m <<= 1 ) { + if ( pam & m ) + ++nproc; + } + __TBB_ASSERT( nproc <= (int)si.dwNumberOfProcessors, NULL ); + // By default setting up a number of processors for one processor group + theProcessorGroups[0].numProcs = theProcessorGroups[0].numProcsRunningTotal = nproc; + // Setting up processor groups in case the process does not restrict affinity mask and more than one processor group is present + if ( nproc == (int)si.dwNumberOfProcessors && TBB_GetActiveProcessorCount ) { + // The process does not have restricting affinity mask and multiple processor groups are possible + ProcessorGroupInfo::NumGroups = (int)TBB_GetActiveProcessorGroupCount(); + __TBB_ASSERT( ProcessorGroupInfo::NumGroups <= MaxProcessorGroups, NULL ); + // Fail safety bootstrap. Release versions will limit available concurrency + // level, while debug ones would assert. + if ( ProcessorGroupInfo::NumGroups > MaxProcessorGroups ) + ProcessorGroupInfo::NumGroups = MaxProcessorGroups; + if ( ProcessorGroupInfo::NumGroups > 1 ) { + TBB_GROUP_AFFINITY ga; + if ( TBB_GetThreadGroupAffinity( GetCurrentThread(), &ga ) ) + ProcessorGroupInfo::HoleIndex = ga.Group; + int nprocs = 0; + for ( WORD i = 0; i < ProcessorGroupInfo::NumGroups; ++i ) { + ProcessorGroupInfo &pgi = theProcessorGroups[i]; + pgi.numProcs = (int)TBB_GetActiveProcessorCount(i); + __TBB_ASSERT( pgi.numProcs <= (int)sizeof(DWORD_PTR) * CHAR_BIT, NULL ); + pgi.mask = pgi.numProcs == sizeof(DWORD_PTR) * CHAR_BIT ? ~(DWORD_PTR)0 : (DWORD_PTR(1) << pgi.numProcs) - 1; + pgi.numProcsRunningTotal = nprocs += pgi.numProcs; + } + __TBB_ASSERT( nprocs == (int)TBB_GetActiveProcessorCount( TBB_ALL_PROCESSOR_GROUPS ), NULL ); + } + } +#endif /* __TBB_WIN8UI_SUPPORT */ + + PrintExtraVersionInfo("Processor groups", "%d", ProcessorGroupInfo::NumGroups); + if (ProcessorGroupInfo::NumGroups>1) + for (int i=0; i<ProcessorGroupInfo::NumGroups; ++i) + PrintExtraVersionInfo( "----- Group", "%d: size %d", i, theProcessorGroups[i].numProcs); +} + +int NumberOfProcessorGroups() { + __TBB_ASSERT( hardware_concurrency_info == initialization_complete, "NumberOfProcessorGroups is used before AvailableHwConcurrency" ); + return ProcessorGroupInfo::NumGroups; +} + +// Offset for the slot reserved for the first master thread +#define HoleAdjusted(procIdx, grpIdx) (procIdx + (holeIdx <= grpIdx)) + +int FindProcessorGroupIndex ( int procIdx ) { + // In case of oversubscription spread extra workers in a round robin manner + int holeIdx; + const int numProcs = theProcessorGroups[ProcessorGroupInfo::NumGroups - 1].numProcsRunningTotal; + if ( procIdx >= numProcs - 1 ) { + holeIdx = INT_MAX; + procIdx = (procIdx - numProcs + 1) % numProcs; + } + else + holeIdx = ProcessorGroupInfo::HoleIndex; + __TBB_ASSERT( hardware_concurrency_info == initialization_complete, "FindProcessorGroupIndex is used before AvailableHwConcurrency" ); + // Approximate the likely group index assuming all groups are of the same size + int i = procIdx / theProcessorGroups[0].numProcs; + // Make sure the approximation is a valid group index + if (i >= ProcessorGroupInfo::NumGroups) i = ProcessorGroupInfo::NumGroups-1; + // Now adjust the approximation up or down + if ( theProcessorGroups[i].numProcsRunningTotal > HoleAdjusted(procIdx, i) ) { + while ( theProcessorGroups[i].numProcsRunningTotal - theProcessorGroups[i].numProcs > HoleAdjusted(procIdx, i) ) { + __TBB_ASSERT( i > 0, NULL ); + --i; + } + } + else { + do { + ++i; + } while ( theProcessorGroups[i].numProcsRunningTotal <= HoleAdjusted(procIdx, i) ); + } + __TBB_ASSERT( i < ProcessorGroupInfo::NumGroups, NULL ); + return i; +} + +void MoveThreadIntoProcessorGroup( void* hThread, int groupIndex ) { + __TBB_ASSERT( hardware_concurrency_info == initialization_complete, "MoveThreadIntoProcessorGroup is used before AvailableHwConcurrency" ); + if ( !TBB_SetThreadGroupAffinity ) + return; + TBB_GROUP_AFFINITY ga = { theProcessorGroups[groupIndex].mask, (WORD)groupIndex, {0,0,0} }; + TBB_SetThreadGroupAffinity( hThread, &ga, NULL ); +} + +int AvailableHwConcurrency() { + atomic_do_once( &initialize_hardware_concurrency_info, hardware_concurrency_info ); + return theProcessorGroups[ProcessorGroupInfo::NumGroups - 1].numProcsRunningTotal; +} + +/* End of _WIN32||_WIN64 implementation */ +#else + #error AvailableHwConcurrency is not implemented for this OS +#endif + +} // namespace internal +} // namespace tbb + +#endif /* !__TBB_HardwareConcurrency */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_resource.rc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_resource.rc new file mode 100644 index 00000000..2bf623fc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_resource.rc @@ -0,0 +1,112 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Microsoft Visual C++ generated resource script. +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include <winresrc.h> +#define ENDL "\r\n" +#include "tbb_version.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +//#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// manifest integration +#ifdef TBB_MANIFEST +#include "winuser.h" +2 RT_MANIFEST tbbmanifest.exe.manifest +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION TBB_VERNUMBERS + PRODUCTVERSION TBB_VERNUMBERS + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Intel Corporation\0" + VALUE "FileDescription", "Intel(R) Threading Building Blocks library\0" + VALUE "FileVersion", TBB_VERSION "\0" + VALUE "LegalCopyright", "Copyright 2005-2020 Intel Corporation. All Rights Reserved.\0" + VALUE "LegalTrademarks", "\0" +#ifndef TBB_USE_DEBUG + VALUE "OriginalFilename", "tbb.dll\0" +#else + VALUE "OriginalFilename", "tbb_debug.dll\0" +#endif + VALUE "ProductName", "Intel(R) Threading Building Blocks for Windows\0" + VALUE "ProductVersion", TBB_VERSION "\0" + VALUE "PrivateBuild", "\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +//#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_statistics.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_statistics.cpp new file mode 100644 index 00000000..c1a9d126 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_statistics.cpp @@ -0,0 +1,183 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb_statistics.h" + +#if __TBB_STATISTICS + +#include <climits> +#include <cstdarg> +#if __TBB_STATISTICS_STDOUT +#include <cstdio> +#endif + +#include "tbb/spin_mutex.h" + +namespace tbb { +namespace internal { + +//! Human readable titles of statistics groups defined by statistics_groups enum. +/** The order of this vector elements must correspond to the statistics_counters + structure layout. **/ +const char* StatGroupTitles[] = { + "task objects", "tasks executed", "stealing attempts", "task proxies", "arena", "market", "priority ops", "prio ops details" +}; + +//! Human readable titles of statistics elements defined by statistics_counters struct. +/** The order of this vector elements must correspond to the statistics_counters + structure layout (with NULLs interspersed to separate groups). **/ +const char* StatFieldTitles[] = { + /*task objects*/ "active", "freed", "big", NULL, + /*tasks executed*/ "total", "w/o spawn", NULL, + /*stealing attempts*/ "succeeded", "failed", "conflicts", "backoffs", NULL, + /*task proxies*/ "mailed", "revoked", "stolen", "bypassed", "ignored", NULL, + /*arena*/ "switches", "roundtrips", "avg.conc", "avg.allot", NULL, + /*market*/ "roundtrips", NULL, + /*priority ops*/ "ar.switch", "mkt.switch", "ar.reset", "ref.fixup", "avg.ar.pr", "avg.mkt.pr", NULL, + /*prio ops details*/ "winnows", "reloads", "orphaned", "winnowed", "reloaded", NULL +}; + +//! Class for logging statistics +/** There should be only one instance of this class. + Results are written to a file "statistics.txt" in tab-separated format. */ +class statistics_logger { +public: + statistics_logger () { + __TBB_ASSERT( sg_end - 1 == 1 << (sizeof(StatGroupTitles)/sizeof(*StatGroupTitles) - 1), NULL ); + + my_file = fopen("statistics.txt","w"); + if( !my_file ) + perror("fopen(\"statistics.txt\"\")"); + // Initialize groups dump layout info + group_start_field[0] = 0; + for ( size_t i = 0, j = 0; i < NumGroups; ++i, ++j ) { + __TBB_ASSERT( StatFieldTitles[j], "Empty group occurred" ); + while ( StatFieldTitles[j] ) + ++j; + group_start_field[i + 1] = j - i; // -i accounts for preceding NULL separators + } + __TBB_ASSERT( group_start_field[NumGroups] == statistics_counters::size(), + "Wrong number of elements in StatFieldTitles" ); + dump( "\n%-*s", IDColumnWidth, ""); + process_groups( &statistics_logger::print_group_title ); + dump( "%-*s", IDColumnWidth, "ID"); + process_groups( &statistics_logger::print_field_titles ); + } + + ~statistics_logger () { fclose(my_file); } + + void record( const statistics_counters& c, size_t id ) { + spin_mutex::scoped_lock lock(my_mutex); + counters_to_dump = &c; +#if __TBB_STATISTICS_TOTALS_ONLY + if ( id == arena_counters_total ) { + dump( "%-*s", IDColumnWidth, "Tot" ); + process_groups( &statistics_logger::print_field_values ); + } +#else /* !__TBB_STATISTICS_TOTALS_ONLY */ + const char* idString = NULL; + switch ( id ) { + case 0: + idString = "M"; break; + case workers_counters_total: + idString = "Wtot"; break; + case arena_counters_total: + idString = "Tot"; break; + default: + dump( "W%-*u", IDColumnWidth - 1, id ); + } + if ( idString ) + dump( "%-*s", IDColumnWidth, idString ); + process_groups( &statistics_logger::print_field_values ); +#endif /* !__TBB_STATISTICS_TOTALS_ONLY */ + } +private: + static const size_t IDColumnWidth = 5; + static const size_t StatisticsColumnWidth = 10; + static const size_t NumGroups = sizeof(StatGroupTitles)/sizeof(char*); + + //! File into which statistics are written. + FILE* my_file; + //! Mutex that serializes accesses to my_file + spin_mutex my_mutex; + //! Indices of the each group's first field in statistics_counters struct. + /** An extra element is used to track the total number of statistics fields. **/ + size_t group_start_field[NumGroups + 1]; + //! Currently processed set of counters. + const statistics_counters* counters_to_dump; + + static const size_t NumFields = sizeof(StatFieldTitles)/sizeof(*StatFieldTitles) - NumGroups; + bool averages_fields[NumFields]; + + void dump ( char const* fmt, ... ) { + va_list args; + if ( my_file ) { + va_start( args, fmt ); + vfprintf( my_file, fmt, args ); + va_end( args ); + } +#if __TBB_STATISTICS_STDOUT + va_start( args, fmt ); + vprintf( fmt, args ); + va_end( args ); +#endif + } + + void process_groups ( void (statistics_logger::*per_group_action)(size_t group_idx) ) { + for ( size_t i = 0, group_flag = 1; i < NumGroups; ++i, group_flag <<= 1 ) { + __TBB_ASSERT( group_flag < sg_end, "StatGroupTitles contents is incompatible with statistics_groups definition" ); + if ( __TBB_ActiveStatisticsGroups & group_flag ) + (this->*per_group_action)( i ); + } + dump( "\n" ); + } + + void print_group_title ( size_t group_idx ) { + dump( "%-*s", (group_start_field[group_idx + 1] - group_start_field[group_idx]) * (StatisticsColumnWidth + 1), + StatGroupTitles[group_idx] ); + } + + void print_field_titles ( size_t group_idx ) { + // +group_idx accounts for preceding NULL separators + size_t i = group_start_field[group_idx] + group_idx; + while ( StatFieldTitles[i] ) { + averages_fields[i - group_idx] = strncmp(StatFieldTitles[i], "avg.", 4) == 0; + dump( "%-*s ", StatisticsColumnWidth, StatFieldTitles[i++] ); + } + } + + void print_field_values ( size_t group_idx ) { + size_t begin = group_start_field[group_idx], + end = group_start_field[group_idx + 1]; + for ( size_t i = begin; i < end; ++i ) { + if ( averages_fields[i] ) + dump( "%-*.2f ", StatisticsColumnWidth, (double)counters_to_dump->field(i)/counters_to_dump->tasks_executed ); + else + dump( "%-*ld ", StatisticsColumnWidth, counters_to_dump->field(i) ); + } + } +}; // class statistics_logger + +static statistics_logger the_statistics; + +void dump_statistics ( const statistics_counters& c, size_t id ) { + the_statistics.record(c, id); +} + +} // namespace internal +} // namespace tbb + +#endif /* __TBB_STATISTICS */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_statistics.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_statistics.h new file mode 100644 index 00000000..03bc437c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_statistics.h @@ -0,0 +1,236 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_tbb_statistics_H +#define _TBB_tbb_statistics_H + +/** + This file defines parameters of the internal statistics collected by the TBB + library (currently by the task scheduler only). + + Statistics is accumulated separately in each thread and is dumped when + the scheduler instance associated with the given thread is destroyed. + For apps with multiple master threads or with the same master repeatedly + initializing and then deinitializing task scheduler this results in TBB + workers statistics getting inseparably mixed. + + Therefore statistics is accumulated in arena slots, and should be dumped + when arena is destroyed. This separates statistics collected for each + scheduler activity region in each master thread. + + With the current RML implementation (TBB 2.2, 3.0) to avoid complete loss of + statistics data during app shutdown (because of lazy workers deinitialization + logic) set __TBB_STATISTICS_EARLY_DUMP macro to write the statistics at the + moment a master thread deinitializes its scheduler. This may happen a little + earlier than the moment of arena destruction resulting in the following undesired + (though usually tolerable) effects: + - a few events related to unsuccessful stealing or thread pool activity may be lost, + - statistics may be substantially incomplete in case of FIFO tasks used in + the FAF mode. + + Macro __TBB_STATISTICS_STDOUT and global variable __TBB_ActiveStatisticsGroups + defined below can be used to configure the statistics output. + + To add new counter: + 1) Insert it into the appropriate group range in statistics_counters; + 2) Insert the corresponding field title into StatFieldTitles (preserving + relative order of the fields). + + To add new counters group: + 1) Insert new group bit flag into statistics_groups; + 2) Insert the new group title into StatGroupTitles (preserving + relative order of the groups). + 3) Add counter belonging to the new group as described above +**/ + +#include "tbb/tbb_stddef.h" + +#ifndef __TBB_STATISTICS +#define __TBB_STATISTICS 0 +#endif /* __TBB_STATISTICS */ + +#if __TBB_STATISTICS + +#include <string.h> // for memset + +//! Dump counters into stdout as well. +/** By default statistics counters are written to the file "statistics.txt" only. **/ +#define __TBB_STATISTICS_STDOUT 1 + +//! Dump only totals for all threads in the given arena +/** By default statistics counters for each arena slot are dumped separately, as + well as the subtotal for workers. **/ +#define __TBB_STATISTICS_TOTALS_ONLY 1 + +//! Dump statistics for an arena when its master completes +/** By default (when this macro is not set) the statistics is sent to output when + arena object is destroyed. But with the current lazy workers termination + logic default behavior may result in losing all statistics output. **/ +#define __TBB_STATISTICS_EARLY_DUMP 1 + +#define GATHER_STATISTIC(x) (x) + +namespace tbb { +namespace internal { + +//! Groups of statistics counters. +/** The order of enumerators must be the same as the order of the corresponding + field groups in the statistics_counters structure. **/ +enum statistics_groups { + sg_task_allocation = 0x01, + sg_task_execution = 0x02, + sg_stealing = 0x04, + sg_affinity = 0x08, + sg_arena = 0x10, + sg_market = 0x20, + sg_prio = 0x40, + sg_prio_ex = 0x80, + // List end marker. Insert new groups only before it. + sg_end +}; + +//! Groups of counters to output +const uintptr_t __TBB_ActiveStatisticsGroups = sg_task_execution | sg_stealing | sg_affinity | sg_arena | sg_market; + +//! A set of various statistics counters that are updated by the library on per thread basis. +/** All the fields must be of the same type (statistics_counters::counter_type). + This is necessary to allow reinterpreting this structure as an array. **/ +struct statistics_counters { + typedef long counter_type; + + // Group: sg_task_allocation + // Counters in this group can have negative values as the tasks migrate across + // threads while the associated counters are updated in the current thread only + // to avoid data races + + //! Number of tasks allocated and not yet destroyed + counter_type active_tasks; + //! Number of task corpses stored for future reuse + counter_type free_list_length; + //! Number of big tasks allocated during the run + /** To find total number of tasks malloc'd, compute (big_tasks+my_small_task_count) */ + counter_type big_tasks; + + // Group: sg_task_execution + + //! Number of tasks executed + counter_type tasks_executed; + //! Number of elided spawns + counter_type spawns_bypassed; + + // Group: sg_stealing + + //! Number of tasks successfully stolen + counter_type steals_committed; + //! Number of failed stealing attempts + counter_type steals_failed; + //! Number of failed attempts to lock victim's task pool + counter_type thieves_conflicts; + //! Number of times thief backed off because of the collision with the owner + counter_type thief_backoffs; + + // Group: sg_affinity + + //! Number of tasks received from mailbox + counter_type mails_received; + //! Number of affinitized tasks executed by the owner + /** Goes as "revoked" in statistics printout. **/ + counter_type proxies_executed; + //! Number of affinitized tasks intercepted by thieves + counter_type proxies_stolen; + //! Number of proxy bypasses by thieves during stealing + counter_type proxies_bypassed; + //! Number of affinitized tasks executed by the owner via scheduler bypass mechanism + counter_type affinity_ignored; + + // Group: sg_arena + + //! Number of times the state of arena switched between "full" and "empty" + counter_type gate_switches; + //! Number of times workers left an arena and returned into the market + counter_type arena_roundtrips; + // !Average concurrency level of this arena + counter_type avg_arena_concurrency; + //! Average assigned priority + counter_type avg_assigned_workers; + + // Group: sg_market + + //! Number of times workers left the market and returned into RML + counter_type market_roundtrips; + + // Group; sg_prio + + //! Number of arena priority switches + counter_type arena_prio_switches; + //! Number of market priority switches + counter_type market_prio_switches; + //! Number of arena priority switches + counter_type arena_prio_resets; + //! Number of reference priority source fixups to avoid deadlock + counter_type prio_ref_fixups; + //! Average arena priority + counter_type avg_arena_prio; + //! Average market priority + counter_type avg_market_prio; + + // Group; sg_prio_ex + + //! Number of times local task pools were winnowed + counter_type prio_winnowings; + //! Number of times secondary task pools were searched for top priority tasks + counter_type prio_reloads; + //! Number of times secondary task pools were abandoned by quitting workers + counter_type prio_orphanings; + //! Number of tasks offloaded into secondary task pools + counter_type prio_tasks_offloaded; + //! Number of tasks reloaded from secondary task pools + counter_type prio_tasks_reloaded; + + // Constructor and helpers + + statistics_counters() { reset(); } + + void reset () { memset( this, 0, sizeof(statistics_counters) ); } + + counter_type& field ( size_t index ) { return reinterpret_cast<counter_type*>(this)[index]; } + + const counter_type& field ( size_t index ) const { return reinterpret_cast<const counter_type*>(this)[index]; } + + static size_t size () { return sizeof(statistics_counters) / sizeof(counter_type); } + + const statistics_counters& operator += ( const statistics_counters& rhs ) { + for ( size_t i = 0; i < size(); ++i ) + field(i) += rhs.field(i); + return *this; + } +}; // statistics_counters + +static const size_t workers_counters_total = (size_t)-1; +static const size_t arena_counters_total = (size_t)-2; + +void dump_statistics ( const statistics_counters& c, size_t id ); + +} // namespace internal +} // namespace tbb + +#else /* !__TBB_STATISTICS */ + +#define GATHER_STATISTIC(x) ((void)0) + +#endif /* !__TBB_STATISTICS */ + +#endif /* _TBB_tbb_statistics_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_thread.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_thread.cpp new file mode 100644 index 00000000..85d1b7ee --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_thread.cpp @@ -0,0 +1,192 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _WIN32||_WIN64 +#include <process.h> // _beginthreadex() +#endif +#include <errno.h> +#include "tbb_misc.h" // handle_win_error() +#include "tbb/tbb_stddef.h" +#include "tbb/tbb_thread.h" +#include "tbb/tbb_allocator.h" +#include "tbb/global_control.h" // thread_stack_size +#include "governor.h" // default_num_threads() +#if __TBB_WIN8UI_SUPPORT +#include <thread> +#endif + +namespace tbb { +namespace internal { + +//! Allocate a closure +void* allocate_closure_v3( size_t size ) +{ + return allocate_via_handler_v3( size ); +} + +//! Free a closure allocated by allocate_closure_v3 +void free_closure_v3( void *ptr ) +{ + deallocate_via_handler_v3( ptr ); +} + +void tbb_thread_v3::join() +{ + if (!joinable()) + handle_perror( EINVAL, "tbb_thread::join" ); // Invalid argument + if (this_tbb_thread::get_id() == get_id()) + handle_perror( EDEADLK, "tbb_thread::join" ); // Resource deadlock avoided +#if _WIN32||_WIN64 +#if __TBB_WIN8UI_SUPPORT + std::thread* thread_tmp=(std::thread*)my_thread_id; + thread_tmp->join(); + delete thread_tmp; +#else // __TBB_WIN8UI_SUPPORT + DWORD status = WaitForSingleObjectEx( my_handle, INFINITE, FALSE ); + if ( status == WAIT_FAILED ) + handle_win_error( GetLastError() ); + BOOL close_stat = CloseHandle( my_handle ); + if ( close_stat == 0 ) + handle_win_error( GetLastError() ); + my_thread_id = 0; +#endif // __TBB_WIN8UI_SUPPORT +#else + int status = pthread_join( my_handle, NULL ); + if( status ) + handle_perror( status, "pthread_join" ); +#endif // _WIN32||_WIN64 + my_handle = 0; +} + +void tbb_thread_v3::detach() { + if (!joinable()) + handle_perror( EINVAL, "tbb_thread::detach" ); // Invalid argument +#if _WIN32||_WIN64 + BOOL status = CloseHandle( my_handle ); + if ( status == 0 ) + handle_win_error( GetLastError() ); + my_thread_id = 0; +#else + int status = pthread_detach( my_handle ); + if( status ) + handle_perror( status, "pthread_detach" ); +#endif // _WIN32||_WIN64 + my_handle = 0; +} + +void tbb_thread_v3::internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), + void* closure ) { +#if _WIN32||_WIN64 +#if __TBB_WIN8UI_SUPPORT + std::thread* thread_tmp=new std::thread(start_routine, closure); + my_handle = thread_tmp->native_handle(); +// TODO: to find out the way to find thread_id without GetThreadId and other +// desktop functions. +// Now tbb_thread does have its own thread_id that stores std::thread object + my_thread_id = (size_t)thread_tmp; +#else + unsigned thread_id; + // The return type of _beginthreadex is "uintptr_t" on new MS compilers, + // and 'unsigned long' on old MS compilers. uintptr_t works for both. + uintptr_t status = _beginthreadex( NULL, (unsigned)global_control::active_value(global_control::thread_stack_size), + start_routine, closure, 0, &thread_id ); + if( status==0 ) + handle_perror(errno,"__beginthreadex"); + else { + my_handle = (HANDLE)status; + my_thread_id = thread_id; + } +#endif +#else + pthread_t thread_handle; + int status; + pthread_attr_t stack_size; + status = pthread_attr_init( &stack_size ); + if( status ) + handle_perror( status, "pthread_attr_init" ); + status = pthread_attr_setstacksize( &stack_size, global_control::active_value(global_control::thread_stack_size) ); + if( status ) + handle_perror( status, "pthread_attr_setstacksize" ); + + status = pthread_create( &thread_handle, &stack_size, start_routine, closure ); + if( status ) + handle_perror( status, "pthread_create" ); + status = pthread_attr_destroy( &stack_size ); + if( status ) + handle_perror( status, "pthread_attr_destroy" ); + + my_handle = thread_handle; +#endif // _WIN32||_WIN64 +} + +unsigned tbb_thread_v3::hardware_concurrency() __TBB_NOEXCEPT(true) { + return governor::default_num_threads(); +} + +tbb_thread_v3::id thread_get_id_v3() { +#if _WIN32||_WIN64 + return tbb_thread_v3::id( GetCurrentThreadId() ); +#else + return tbb_thread_v3::id( pthread_self() ); +#endif // _WIN32||_WIN64 +} + +void move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ) +{ + if (t1.joinable()) + t1.detach(); + t1.my_handle = t2.my_handle; + t2.my_handle = 0; +#if _WIN32||_WIN64 + t1.my_thread_id = t2.my_thread_id; + t2.my_thread_id = 0; +#endif // _WIN32||_WIN64 +} + +void thread_yield_v3() +{ + __TBB_Yield(); +} + +void thread_sleep_v3(const tick_count::interval_t &i) +{ +#if _WIN32||_WIN64 + tick_count t0 = tick_count::now(); + tick_count t1 = t0; + for(;;) { + double remainder = (i-(t1-t0)).seconds()*1e3; // milliseconds remaining to sleep + if( remainder<=0 ) break; + DWORD t = remainder>=INFINITE ? INFINITE-1 : DWORD(remainder); +#if !__TBB_WIN8UI_SUPPORT + Sleep( t ); +#else + std::chrono::milliseconds sleep_time( t ); + std::this_thread::sleep_for( sleep_time ); +#endif + t1 = tick_count::now(); + } +#else + struct timespec req; + double sec = i.seconds(); + + req.tv_sec = static_cast<long>(sec); + req.tv_nsec = static_cast<long>( (sec - req.tv_sec)*1e9 ); + nanosleep(&req, NULL); +#endif // _WIN32||_WIN64 +} + +} // internal +} // tbb diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_version.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_version.h new file mode 100644 index 00000000..5aff3e25 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tbb_version.h @@ -0,0 +1,115 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Please define version number in the file: +#include "tbb/tbb_stddef.h" + +// And don't touch anything below +#ifndef ENDL +#define ENDL "\n" +#endif +#include "version_string.ver" + +#ifndef __TBB_VERSION_STRINGS +#pragma message("Warning: version_string.ver isn't generated properly by version_info.sh script!") +// here is an example of macros value: +#define __TBB_VERSION_STRINGS \ +"TBB: BUILD_HOST\tUnknown\n" \ +"TBB: BUILD_ARCH\tUnknown\n" \ +"TBB: BUILD_OS\t\tUnknown\n" \ +"TBB: BUILD_CL\t\tUnknown\n" \ +"TBB: BUILD_COMPILER\tUnknown\n" \ +"TBB: BUILD_COMMAND\tUnknown\n" +#endif +#ifndef __TBB_DATETIME +#ifdef RC_INVOKED +#define __TBB_DATETIME "Unknown" +#else +#define __TBB_DATETIME __DATE__ __TIME__ +#endif +#endif + +#define __TBB_VERSION_NUMBER(N) #N ": VERSION\t\t" __TBB_STRING(TBB_VERSION_MAJOR.TBB_VERSION_MINOR) ENDL +#define __TBB_INTERFACE_VERSION_NUMBER(N) #N ": INTERFACE VERSION\t" __TBB_STRING(TBB_INTERFACE_VERSION) ENDL + +#define __TBB_VERSION_DATETIME(N) #N ": BUILD_DATE\t\t" __TBB_DATETIME ENDL +#ifndef TBB_USE_DEBUG + #define __TBB_VERSION_USE_DEBUG(N) #N ": TBB_USE_DEBUG\tundefined" ENDL +#elif TBB_USE_DEBUG==0 + #define __TBB_VERSION_USE_DEBUG(N) #N ": TBB_USE_DEBUG\t0" ENDL +#elif TBB_USE_DEBUG==1 + #define __TBB_VERSION_USE_DEBUG(N) #N ": TBB_USE_DEBUG\t1" ENDL +#elif TBB_USE_DEBUG==2 + #define __TBB_VERSION_USE_DEBUG(N) #N ": TBB_USE_DEBUG\t2" ENDL +#else + #error Unexpected value for TBB_USE_DEBUG +#endif + +/* Make __TBB_VERSION_USE_ASSERT and __TBB_VERSION_DO_NOTIFY empty for rc + * because rc from VS2005 crashed with fatal error RC10056 for too complex + * macros (for example, when __TBB_CPF_BUILD is enabled). + * All information is available in BUILD_COMMAND anyway. + */ + +#ifdef RC_INVOKED + #define __TBB_VERSION_USE_ASSERT(N) +#else // RC_INVOKED +#ifndef TBB_USE_ASSERT + #define __TBB_VERSION_USE_ASSERT(N) #N ": TBB_USE_ASSERT\tundefined" ENDL +#elif TBB_USE_ASSERT==0 + #define __TBB_VERSION_USE_ASSERT(N) #N ": TBB_USE_ASSERT\t0" ENDL +#elif TBB_USE_ASSERT==1 + #define __TBB_VERSION_USE_ASSERT(N) #N ": TBB_USE_ASSERT\t1" ENDL +#elif TBB_USE_ASSERT==2 + #define __TBB_VERSION_USE_ASSERT(N) #N ": TBB_USE_ASSERT\t2" ENDL +#else + #error Unexpected value for TBB_USE_ASSERT +#endif +#endif // RC_INVOKED + +#ifndef __TBB_CPF_BUILD + #define __TBB_VERSION_TBB_PREVIEW_BINARY(N) +#else + #define __TBB_VERSION_TBB_PREVIEW_BINARY(N) #N ": TBB_PREVIEW_BINARY\t1" ENDL +#endif + +#ifdef RC_INVOKED + #define __TBB_VERSION_DO_NOTIFY(N) +#else +#ifndef DO_ITT_NOTIFY + #define __TBB_VERSION_DO_NOTIFY(N) #N ": DO_ITT_NOTIFY\tundefined" ENDL +#elif DO_ITT_NOTIFY==1 + #define __TBB_VERSION_DO_NOTIFY(N) #N ": DO_ITT_NOTIFY\t1" ENDL +#elif DO_ITT_NOTIFY==0 + #define __TBB_VERSION_DO_NOTIFY(N) +#else + #error Unexpected value for DO_ITT_NOTIFY +#endif +#endif // RC_INVOKED + +#define TBB_VERSION_STRINGS_P(N) __TBB_VERSION_NUMBER(N) __TBB_INTERFACE_VERSION_NUMBER(N) __TBB_VERSION_DATETIME(N) __TBB_VERSION_STRINGS(N) __TBB_VERSION_USE_DEBUG(N) __TBB_VERSION_USE_ASSERT(N) __TBB_VERSION_TBB_PREVIEW_BINARY(N) __TBB_VERSION_DO_NOTIFY(N) + +#define TBB_VERSION_STRINGS TBB_VERSION_STRINGS_P(TBB) +#define TBBMALLOC_VERSION_STRINGS TBB_VERSION_STRINGS_P(TBBmalloc) + +// numbers +#ifndef __TBB_VERSION_YMD +#define __TBB_VERSION_YMD 0, 0 +#endif + +#define TBB_VERNUMBERS TBB_VERSION_MAJOR, TBB_VERSION_MINOR, __TBB_VERSION_YMD + +#define TBB_VERSION __TBB_STRING(TBB_VERNUMBERS) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tls.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tls.h new file mode 100644 index 00000000..2a3f79e7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tls.h @@ -0,0 +1,120 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_tls_H +#define _TBB_tls_H + +#if USE_PTHREAD +#include <pthread.h> +#else /* assume USE_WINTHREAD */ +#include "tbb/machine/windows_api.h" +#endif + +namespace tbb { + +namespace internal { + +typedef void (*tls_dtor_t)(void*); + +//! Basic cross-platform wrapper class for TLS operations. +template <typename T> +class basic_tls { +#if USE_PTHREAD + typedef pthread_key_t tls_key_t; +public: + int create( tls_dtor_t dtor = NULL ) { + return pthread_key_create(&my_key, dtor); + } + int destroy() { return pthread_key_delete(my_key); } + void set( T value ) { pthread_setspecific(my_key, (void*)value); } + T get() { return (T)pthread_getspecific(my_key); } +#else /* USE_WINTHREAD */ + typedef DWORD tls_key_t; +public: +#if !__TBB_WIN8UI_SUPPORT + int create() { + tls_key_t tmp = TlsAlloc(); + if( tmp==TLS_OUT_OF_INDEXES ) + return TLS_OUT_OF_INDEXES; + my_key = tmp; + return 0; + } + int destroy() { TlsFree(my_key); my_key=0; return 0; } + void set( T value ) { TlsSetValue(my_key, (LPVOID)value); } + T get() { return (T)TlsGetValue(my_key); } +#else /*!__TBB_WIN8UI_SUPPORT*/ + int create() { + tls_key_t tmp = FlsAlloc(NULL); + if( tmp== (DWORD)0xFFFFFFFF ) + return (DWORD)0xFFFFFFFF; + my_key = tmp; + return 0; + } + int destroy() { FlsFree(my_key); my_key=0; return 0; } + void set( T value ) { FlsSetValue(my_key, (LPVOID)value); } + T get() { return (T)FlsGetValue(my_key); } +#endif /* !__TBB_WIN8UI_SUPPORT */ +#endif /* USE_WINTHREAD */ +private: + tls_key_t my_key; +}; + +//! More advanced TLS support template class. +/** It supports RAII and to some extent mimic __declspec(thread) variables. */ +template <typename T> +class tls : public basic_tls<T> { + typedef basic_tls<T> base; +public: + tls() { base::create(); } + ~tls() { base::destroy(); } + T operator=(T value) { base::set(value); return value; } + operator T() { return base::get(); } +}; + +template <typename T> +class tls<T*> : basic_tls<T*> { + typedef basic_tls<T*> base; + static void internal_dtor(void* ptr) { + if (ptr) delete (T*)ptr; + } + T* internal_get() { + T* result = base::get(); + if (!result) { + result = new T; + base::set(result); + } + return result; + } +public: + tls() { +#if USE_PTHREAD + base::create( internal_dtor ); +#else + base::create(); +#endif + } + ~tls() { base::destroy(); } + T* operator=(T* value) { base::set(value); return value; } + operator T*() { return internal_get(); } + T* operator->() { return internal_get(); } + T& operator*() { return *internal_get(); } +}; + +} // namespace internal + +} // namespace tbb + +#endif /* _TBB_tls_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/disable_warnings.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/disable_warnings.h new file mode 100644 index 00000000..34621c40 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/disable_warnings.h @@ -0,0 +1,35 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ittnotify_config.h" + +#if ITT_PLATFORM==ITT_PLATFORM_WIN + +#pragma warning (disable: 593) /* parameter "XXXX" was set but never used */ +#pragma warning (disable: 344) /* typedef name has already been declared (with same type) */ +#pragma warning (disable: 174) /* expression has no effect */ +#pragma warning (disable: 4127) /* conditional expression is constant */ +#pragma warning (disable: 4306) /* conversion from '?' to '?' of greater size */ + +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#if defined __INTEL_COMPILER + +#pragma warning (disable: 869) /* parameter "XXXXX" was never referenced */ +#pragma warning (disable: 1418) /* external function definition with no prior declaration */ +#pragma warning (disable: 1419) /* external declaration in primary source file */ + +#endif /* __INTEL_COMPILER */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify.h new file mode 100644 index 00000000..95ca8e60 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify.h @@ -0,0 +1,4164 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _ITTNOTIFY_H_ +#define _ITTNOTIFY_H_ + +/** +@file +@brief Public User API functions and types +@mainpage + +The Instrumentation and Tracing Technology API (ITT API) is used to annotate a user's program with additional information +that can be used by correctness and performance tools. The user inserts +calls in their program. Those calls generate information that is collected +at runtime, and used by Intel(R) Threading Tools. + +@section API Concepts +The following general concepts are used throughout the API. + +@subsection Unicode Support +Many API functions take character string arguments. On Windows, there +are two versions of each such function. The function name is suffixed +by W if Unicode support is enabled, and by A otherwise. Any API function +that takes a character string argument adheres to this convention. + +@subsection Conditional Compilation +Many users prefer having an option to modify ITT API code when linking it +inside their runtimes. ITT API header file provides a mechanism to replace +ITT API function names inside your code with empty strings. To do this, +define the macros INTEL_NO_ITTNOTIFY_API during compilation and remove the +static library from the linker script. + +@subsection Domains +[see domains] +Domains provide a way to separate notification for different modules or +libraries in a program. Domains are specified by dotted character strings, +e.g. TBB.Internal.Control. + +A mechanism (to be specified) is provided to enable and disable +domains. By default, all domains are enabled. +@subsection Named Entities and Instances +Named entities (frames, regions, tasks, and markers) communicate +information about the program to the analysis tools. A named entity often +refers to a section of program code, or to some set of logical concepts +that the programmer wants to group together. + +Named entities relate to the programmer's static view of the program. When +the program actually executes, many instances of a given named entity +may be created. + +The API annotations denote instances of named entities. The actual +named entities are displayed using the analysis tools. In other words, +the named entities come into existence when instances are created. + +Instances of named entities may have instance identifiers (IDs). Some +API calls use instance identifiers to create relationships between +different instances of named entities. Other API calls associate data +with instances of named entities. + +Some named entities must always have instance IDs. In particular, regions +and frames always have IDs. Task and markers need IDs only if the ID is +needed in another API call (such as adding a relation or metadata). + +The lifetime of instance IDs is distinct from the lifetime of +instances. This allows various relationships to be specified separate +from the actual execution of instances. This flexibility comes at the +expense of extra API calls. + +The same ID may not be reused for different instances, unless a previous +[ref] __itt_id_destroy call for that ID has been issued. +*/ + +/** @cond exclude_from_documentation */ +#ifndef ITT_OS_WIN +# define ITT_OS_WIN 1 +#endif /* ITT_OS_WIN */ + +#ifndef ITT_OS_LINUX +# define ITT_OS_LINUX 2 +#endif /* ITT_OS_LINUX */ + +#ifndef ITT_OS_MAC +# define ITT_OS_MAC 3 +#endif /* ITT_OS_MAC */ + +#ifndef ITT_OS_FREEBSD +# define ITT_OS_FREEBSD 4 +#endif /* ITT_OS_FREEBSD */ + +#ifndef ITT_OS +# if defined WIN32 || defined _WIN32 +# define ITT_OS ITT_OS_WIN +# elif defined( __APPLE__ ) && defined( __MACH__ ) +# define ITT_OS ITT_OS_MAC +# elif defined( __FreeBSD__ ) +# define ITT_OS ITT_OS_FREEBSD +# else +# define ITT_OS ITT_OS_LINUX +# endif +#endif /* ITT_OS */ + +#ifndef ITT_PLATFORM_WIN +# define ITT_PLATFORM_WIN 1 +#endif /* ITT_PLATFORM_WIN */ + +#ifndef ITT_PLATFORM_POSIX +# define ITT_PLATFORM_POSIX 2 +#endif /* ITT_PLATFORM_POSIX */ + +#ifndef ITT_PLATFORM_MAC +# define ITT_PLATFORM_MAC 3 +#endif /* ITT_PLATFORM_MAC */ + +#ifndef ITT_PLATFORM_FREEBSD +# define ITT_PLATFORM_FREEBSD 4 +#endif /* ITT_PLATFORM_FREEBSD */ + +#ifndef ITT_PLATFORM +# if ITT_OS==ITT_OS_WIN +# define ITT_PLATFORM ITT_PLATFORM_WIN +# elif ITT_OS==ITT_OS_MAC +# define ITT_PLATFORM ITT_PLATFORM_MAC +# elif ITT_OS==ITT_OS_FREEBSD +# define ITT_PLATFORM ITT_PLATFORM_FREEBSD +# else +# define ITT_PLATFORM ITT_PLATFORM_POSIX +# endif +#endif /* ITT_PLATFORM */ + +#if defined(_UNICODE) && !defined(UNICODE) +#define UNICODE +#endif + +#include <stddef.h> +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#include <tchar.h> +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#include <stdint.h> +#if defined(UNICODE) || defined(_UNICODE) +#include <wchar.h> +#endif /* UNICODE || _UNICODE */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef ITTAPI_CDECL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define ITTAPI_CDECL __cdecl +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define ITTAPI_CDECL __attribute__ ((cdecl)) +# else /* _M_IX86 || __i386__ */ +# define ITTAPI_CDECL /* actual only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* ITTAPI_CDECL */ + +#ifndef STDCALL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define STDCALL __stdcall +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define STDCALL __attribute__ ((stdcall)) +# else /* _M_IX86 || __i386__ */ +# define STDCALL /* supported only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* STDCALL */ + +#define ITTAPI ITTAPI_CDECL +#define LIBITTAPI ITTAPI_CDECL + +/* TODO: Temporary for compatibility! */ +#define ITTAPI_CALL ITTAPI_CDECL +#define LIBITTAPI_CALL ITTAPI_CDECL + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +/* use __forceinline (VC++ specific) */ +#define ITT_INLINE __forceinline +#define ITT_INLINE_ATTRIBUTE /* nothing */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/* + * Generally, functions are not inlined unless optimization is specified. + * For functions declared inline, this attribute inlines the function even + * if no optimization level was specified. + */ +#ifdef __STRICT_ANSI__ +#define ITT_INLINE static +#define ITT_INLINE_ATTRIBUTE __attribute__((unused)) +#else /* __STRICT_ANSI__ */ +#define ITT_INLINE static inline +#define ITT_INLINE_ATTRIBUTE __attribute__((always_inline, unused)) +#endif /* __STRICT_ANSI__ */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/** @endcond */ + +#ifdef INTEL_ITTNOTIFY_ENABLE_LEGACY +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# pragma message("WARNING!!! Deprecated API is used. Please undefine INTEL_ITTNOTIFY_ENABLE_LEGACY macro") +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +// #warning usage leads to ICC's compilation error +// # warning "Deprecated API is used. Please undefine INTEL_ITTNOTIFY_ENABLE_LEGACY macro" +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# include "legacy/ittnotify.h" +#endif /* INTEL_ITTNOTIFY_ENABLE_LEGACY */ + +/** @cond exclude_from_documentation */ +/* Helper macro for joining tokens */ +#define ITT_JOIN_AUX(p,n) p##n +#define ITT_JOIN(p,n) ITT_JOIN_AUX(p,n) + +#ifdef ITT_MAJOR +#undef ITT_MAJOR +#endif +#ifdef ITT_MINOR +#undef ITT_MINOR +#endif +#define ITT_MAJOR 3 +#define ITT_MINOR 0 + +/* Standard versioning of a token with major and minor version numbers */ +#define ITT_VERSIONIZE(x) \ + ITT_JOIN(x, \ + ITT_JOIN(_, \ + ITT_JOIN(ITT_MAJOR, \ + ITT_JOIN(_, ITT_MINOR)))) + +#ifndef INTEL_ITTNOTIFY_PREFIX +# define INTEL_ITTNOTIFY_PREFIX __itt_ +#endif /* INTEL_ITTNOTIFY_PREFIX */ +#ifndef INTEL_ITTNOTIFY_POSTFIX +# define INTEL_ITTNOTIFY_POSTFIX _ptr_ +#endif /* INTEL_ITTNOTIFY_POSTFIX */ + +#define ITTNOTIFY_NAME_AUX(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) +#define ITTNOTIFY_NAME(n) ITT_VERSIONIZE(ITTNOTIFY_NAME_AUX(ITT_JOIN(n,INTEL_ITTNOTIFY_POSTFIX))) + +#define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n) +#define ITTNOTIFY_DATA(n) (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n) + +#define ITTNOTIFY_VOID_D0(n,d) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d) +#define ITTNOTIFY_VOID_D1(n,d,x) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x) +#define ITTNOTIFY_VOID_D2(n,d,x,y) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y) +#define ITTNOTIFY_VOID_D3(n,d,x,y,z) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z) +#define ITTNOTIFY_VOID_D4(n,d,x,y,z,a) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) +#define ITTNOTIFY_VOID_D5(n,d,x,y,z,a,b) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) +#define ITTNOTIFY_VOID_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) +#define ITTNOTIFY_DATA_D0(n,d) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d) +#define ITTNOTIFY_DATA_D1(n,d,x) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x) +#define ITTNOTIFY_DATA_D2(n,d,x,y) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y) +#define ITTNOTIFY_DATA_D3(n,d,x,y,z) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z) +#define ITTNOTIFY_DATA_D4(n,d,x,y,z,a) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) +#define ITTNOTIFY_DATA_D5(n,d,x,y,z,a,b) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) +#define ITTNOTIFY_DATA_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) + +#ifdef ITT_STUB +#undef ITT_STUB +#endif +#ifdef ITT_STUBV +#undef ITT_STUBV +#endif +#define ITT_STUBV(api,type,name,args) \ + typedef type (api* ITT_JOIN(ITTNOTIFY_NAME(name),_t)) args; \ + extern ITT_JOIN(ITTNOTIFY_NAME(name),_t) ITTNOTIFY_NAME(name); +#define ITT_STUB ITT_STUBV +/** @endcond */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @cond exclude_from_gpa_documentation */ +/** + * @defgroup public Public API + * @{ + * @} + */ + +/** + * @defgroup control Collection Control + * @ingroup public + * General behavior: application continues to run, but no profiling information is being collected + * + * Pausing occurs not only for the current thread but for all process as well as spawned processes + * - Intel(R) Parallel Inspector and Intel(R) Inspector XE: + * - Does not analyze or report errors that involve memory access. + * - Other errors are reported as usual. Pausing data collection in + * Intel(R) Parallel Inspector and Intel(R) Inspector XE + * only pauses tracing and analyzing memory access. + * It does not pause tracing or analyzing threading APIs. + * . + * - Intel(R) Parallel Amplifier and Intel(R) VTune(TM) Amplifier XE: + * - Does continue to record when new threads are started. + * . + * - Other effects: + * - Possible reduction of runtime overhead. + * . + * @{ + */ +/** @brief Pause collection */ +void ITTAPI __itt_pause(void); +/** @brief Resume collection */ +void ITTAPI __itt_resume(void); +/** @brief Detach collection */ +void ITTAPI __itt_detach(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, pause, (void)) +ITT_STUBV(ITTAPI, void, resume, (void)) +ITT_STUBV(ITTAPI, void, detach, (void)) +#define __itt_pause ITTNOTIFY_VOID(pause) +#define __itt_pause_ptr ITTNOTIFY_NAME(pause) +#define __itt_resume ITTNOTIFY_VOID(resume) +#define __itt_resume_ptr ITTNOTIFY_NAME(resume) +#define __itt_detach ITTNOTIFY_VOID(detach) +#define __itt_detach_ptr ITTNOTIFY_NAME(detach) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_pause() +#define __itt_pause_ptr 0 +#define __itt_resume() +#define __itt_resume_ptr 0 +#define __itt_detach() +#define __itt_detach_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_pause_ptr 0 +#define __itt_resume_ptr 0 +#define __itt_detach_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} control group */ +/** @endcond */ + +/** + * @defgroup Intel Processor Trace control + * API from this group provides control over collection and analysis of Intel Processor Trace (Intel PT) data + * Information about Intel Processor Trace technology can be found here (Volume 3 chapter 35): + * https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf + * Use this API to mark particular code regions for loading detailed performance statistics. + * This mode makes your analysis faster and more accurate. + * @{ +*/ +typedef unsigned char __itt_pt_region; + +/** + * @brief function saves a region name marked with Intel PT API and returns a region id. + * Only 7 names can be registered. Attempts to register more names will be ignored and a region id with auto names will be returned. + * For automatic naming of regions pass NULL as function parameter +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_pt_region ITTAPI __itt_pt_region_createA(const char *name); +__itt_pt_region ITTAPI __itt_pt_region_createW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_pt_region_create __itt_pt_region_createW +#else /* UNICODE */ +# define __itt_pt_region_create __itt_pt_region_createA +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_pt_region ITTAPI __itt_pt_region_create(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_createA, (const char *name)) +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_createW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_create, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_pt_region_createA ITTNOTIFY_DATA(pt_region_createA) +#define __itt_pt_region_createA_ptr ITTNOTIFY_NAME(pt_region_createA) +#define __itt_pt_region_createW ITTNOTIFY_DATA(pt_region_createW) +#define __itt_pt_region_createW_ptr ITTNOTIFY_NAME(pt_region_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_pt_region_create ITTNOTIFY_DATA(pt_region_create) +#define __itt_pt_region_create_ptr ITTNOTIFY_NAME(pt_region_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_pt_region_createA(name) (__itt_pt_region)0 +#define __itt_pt_region_createA_ptr 0 +#define __itt_pt_region_createW(name) (__itt_pt_region)0 +#define __itt_pt_region_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_pt_region_create(name) (__itt_pt_region)0 +#define __itt_pt_region_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_pt_region_createA_ptr 0 +#define __itt_pt_region_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_pt_region_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief function contains a special code pattern identified on the post-processing stage and + * marks the beginning of a code region targeted for Intel PT analysis + * @param[in] region - region id, 0 <= region < 8 +*/ +void __itt_mark_pt_region_begin(__itt_pt_region region); +/** + * @brief function contains a special code pattern identified on the post-processing stage and + * marks the end of a code region targeted for Intel PT analysis + * @param[in] region - region id, 0 <= region < 8 +*/ +void __itt_mark_pt_region_end(__itt_pt_region region); +/** @} Intel PT control group*/ + +/** + * @defgroup threads Threads + * @ingroup public + * Give names to threads + * @{ + */ +/** + * @brief Sets thread name of calling thread + * @param[in] name - name of thread + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_thread_set_nameA(const char *name); +void ITTAPI __itt_thread_set_nameW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_thread_set_name __itt_thread_set_nameW +# define __itt_thread_set_name_ptr __itt_thread_set_nameW_ptr +#else /* UNICODE */ +# define __itt_thread_set_name __itt_thread_set_nameA +# define __itt_thread_set_name_ptr __itt_thread_set_nameA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_thread_set_name(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, thread_set_nameA, (const char *name)) +ITT_STUBV(ITTAPI, void, thread_set_nameW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, thread_set_name, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thread_set_nameA ITTNOTIFY_VOID(thread_set_nameA) +#define __itt_thread_set_nameA_ptr ITTNOTIFY_NAME(thread_set_nameA) +#define __itt_thread_set_nameW ITTNOTIFY_VOID(thread_set_nameW) +#define __itt_thread_set_nameW_ptr ITTNOTIFY_NAME(thread_set_nameW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thread_set_name ITTNOTIFY_VOID(thread_set_name) +#define __itt_thread_set_name_ptr ITTNOTIFY_NAME(thread_set_name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thread_set_nameA(name) +#define __itt_thread_set_nameA_ptr 0 +#define __itt_thread_set_nameW(name) +#define __itt_thread_set_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thread_set_name(name) +#define __itt_thread_set_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thread_set_nameA_ptr 0 +#define __itt_thread_set_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thread_set_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @cond exclude_from_gpa_documentation */ + +/** + * @brief Mark current thread as ignored from this point on, for the duration of its existence. + */ +void ITTAPI __itt_thread_ignore(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, thread_ignore, (void)) +#define __itt_thread_ignore ITTNOTIFY_VOID(thread_ignore) +#define __itt_thread_ignore_ptr ITTNOTIFY_NAME(thread_ignore) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_thread_ignore() +#define __itt_thread_ignore_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_thread_ignore_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} threads group */ + +/** + * @defgroup suppress Error suppression + * @ingroup public + * General behavior: application continues to run, but errors are suppressed + * + * @{ + */ + +/*****************************************************************//** + * @name group of functions used for error suppression in correctness tools + *********************************************************************/ +/** @{ */ +/** + * @hideinitializer + * @brief possible value for suppression mask + */ +#define __itt_suppress_all_errors 0x7fffffff + +/** + * @hideinitializer + * @brief possible value for suppression mask (suppresses errors from threading analysis) + */ +#define __itt_suppress_threading_errors 0x000000ff + +/** + * @hideinitializer + * @brief possible value for suppression mask (suppresses errors from memory analysis) + */ +#define __itt_suppress_memory_errors 0x0000ff00 + +/** + * @brief Start suppressing errors identified in mask on this thread + */ +void ITTAPI __itt_suppress_push(unsigned int mask); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, suppress_push, (unsigned int mask)) +#define __itt_suppress_push ITTNOTIFY_VOID(suppress_push) +#define __itt_suppress_push_ptr ITTNOTIFY_NAME(suppress_push) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_suppress_push(mask) +#define __itt_suppress_push_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_suppress_push_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Undo the effects of the matching call to __itt_suppress_push + */ +void ITTAPI __itt_suppress_pop(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, suppress_pop, (void)) +#define __itt_suppress_pop ITTNOTIFY_VOID(suppress_pop) +#define __itt_suppress_pop_ptr ITTNOTIFY_NAME(suppress_pop) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_suppress_pop() +#define __itt_suppress_pop_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_suppress_pop_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @enum __itt_model_disable + * @brief Enumerator for the disable methods + */ +typedef enum __itt_suppress_mode { + __itt_unsuppress_range, + __itt_suppress_range +} __itt_suppress_mode_t; + +/** + * @brief Mark a range of memory for error suppression or unsuppression for error types included in mask + */ +void ITTAPI __itt_suppress_mark_range(__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, suppress_mark_range, (__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size)) +#define __itt_suppress_mark_range ITTNOTIFY_VOID(suppress_mark_range) +#define __itt_suppress_mark_range_ptr ITTNOTIFY_NAME(suppress_mark_range) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_suppress_mark_range(mask) +#define __itt_suppress_mark_range_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_suppress_mark_range_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Undo the effect of a matching call to __itt_suppress_mark_range. If not matching + * call is found, nothing is changed. + */ +void ITTAPI __itt_suppress_clear_range(__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, suppress_clear_range, (__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size)) +#define __itt_suppress_clear_range ITTNOTIFY_VOID(suppress_clear_range) +#define __itt_suppress_clear_range_ptr ITTNOTIFY_NAME(suppress_clear_range) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_suppress_clear_range(mask) +#define __itt_suppress_clear_range_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_suppress_clear_range_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} */ +/** @} suppress group */ + +/** + * @defgroup sync Synchronization + * @ingroup public + * Indicate user-written synchronization code + * @{ + */ +/** + * @hideinitializer + * @brief possible value of attribute argument for sync object type + */ +#define __itt_attr_barrier 1 + +/** + * @hideinitializer + * @brief possible value of attribute argument for sync object type + */ +#define __itt_attr_mutex 2 + +/** +@brief Name a synchronization object +@param[in] addr Handle for the synchronization object. You should +use a real address to uniquely identify the synchronization object. +@param[in] objtype null-terminated object type string. If NULL is +passed, the name will be "User Synchronization". +@param[in] objname null-terminated object name string. If NULL, +no name will be assigned to the object. +@param[in] attribute one of [#__itt_attr_barrier, #__itt_attr_mutex] + */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_sync_createA(void *addr, const char *objtype, const char *objname, int attribute); +void ITTAPI __itt_sync_createW(void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_sync_create __itt_sync_createW +# define __itt_sync_create_ptr __itt_sync_createW_ptr +#else /* UNICODE */ +# define __itt_sync_create __itt_sync_createA +# define __itt_sync_create_ptr __itt_sync_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_sync_create (void *addr, const char *objtype, const char *objname, int attribute); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, sync_createA, (void *addr, const char *objtype, const char *objname, int attribute)) +ITT_STUBV(ITTAPI, void, sync_createW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_create, (void *addr, const char* objtype, const char* objname, int attribute)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_createA ITTNOTIFY_VOID(sync_createA) +#define __itt_sync_createA_ptr ITTNOTIFY_NAME(sync_createA) +#define __itt_sync_createW ITTNOTIFY_VOID(sync_createW) +#define __itt_sync_createW_ptr ITTNOTIFY_NAME(sync_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_create ITTNOTIFY_VOID(sync_create) +#define __itt_sync_create_ptr ITTNOTIFY_NAME(sync_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_createA(addr, objtype, objname, attribute) +#define __itt_sync_createA_ptr 0 +#define __itt_sync_createW(addr, objtype, objname, attribute) +#define __itt_sync_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_create(addr, objtype, objname, attribute) +#define __itt_sync_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_createA_ptr 0 +#define __itt_sync_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** +@brief Rename a synchronization object + +You can use the rename call to assign or reassign a name to a given +synchronization object. +@param[in] addr handle for the synchronization object. +@param[in] name null-terminated object name string. +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_sync_renameA(void *addr, const char *name); +void ITTAPI __itt_sync_renameW(void *addr, const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_sync_rename __itt_sync_renameW +# define __itt_sync_rename_ptr __itt_sync_renameW_ptr +#else /* UNICODE */ +# define __itt_sync_rename __itt_sync_renameA +# define __itt_sync_rename_ptr __itt_sync_renameA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_sync_rename(void *addr, const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, sync_renameA, (void *addr, const char *name)) +ITT_STUBV(ITTAPI, void, sync_renameW, (void *addr, const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_rename, (void *addr, const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_renameA ITTNOTIFY_VOID(sync_renameA) +#define __itt_sync_renameA_ptr ITTNOTIFY_NAME(sync_renameA) +#define __itt_sync_renameW ITTNOTIFY_VOID(sync_renameW) +#define __itt_sync_renameW_ptr ITTNOTIFY_NAME(sync_renameW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_rename ITTNOTIFY_VOID(sync_rename) +#define __itt_sync_rename_ptr ITTNOTIFY_NAME(sync_rename) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_renameA(addr, name) +#define __itt_sync_renameA_ptr 0 +#define __itt_sync_renameW(addr, name) +#define __itt_sync_renameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_rename(addr, name) +#define __itt_sync_rename_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_renameA_ptr 0 +#define __itt_sync_renameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_rename_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + @brief Destroy a synchronization object. + @param addr Handle for the synchronization object. + */ +void ITTAPI __itt_sync_destroy(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_destroy, (void *addr)) +#define __itt_sync_destroy ITTNOTIFY_VOID(sync_destroy) +#define __itt_sync_destroy_ptr ITTNOTIFY_NAME(sync_destroy) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_destroy(addr) +#define __itt_sync_destroy_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_destroy_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/*****************************************************************//** + * @name group of functions is used for performance measurement tools + *********************************************************************/ +/** @{ */ +/** + * @brief Enter spin loop on user-defined sync object + */ +void ITTAPI __itt_sync_prepare(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_prepare, (void *addr)) +#define __itt_sync_prepare ITTNOTIFY_VOID(sync_prepare) +#define __itt_sync_prepare_ptr ITTNOTIFY_NAME(sync_prepare) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_prepare(addr) +#define __itt_sync_prepare_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_prepare_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Quit spin loop without acquiring spin object + */ +void ITTAPI __itt_sync_cancel(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_cancel, (void *addr)) +#define __itt_sync_cancel ITTNOTIFY_VOID(sync_cancel) +#define __itt_sync_cancel_ptr ITTNOTIFY_NAME(sync_cancel) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_cancel(addr) +#define __itt_sync_cancel_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_cancel_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Successful spin loop completion (sync object acquired) + */ +void ITTAPI __itt_sync_acquired(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_acquired, (void *addr)) +#define __itt_sync_acquired ITTNOTIFY_VOID(sync_acquired) +#define __itt_sync_acquired_ptr ITTNOTIFY_NAME(sync_acquired) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_acquired(addr) +#define __itt_sync_acquired_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_acquired_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Start sync object releasing code. Is called before the lock release call. + */ +void ITTAPI __itt_sync_releasing(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, sync_releasing, (void *addr)) +#define __itt_sync_releasing ITTNOTIFY_VOID(sync_releasing) +#define __itt_sync_releasing_ptr ITTNOTIFY_NAME(sync_releasing) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_sync_releasing(addr) +#define __itt_sync_releasing_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_sync_releasing_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} */ + +/** @} sync group */ + +/**************************************************************//** + * @name group of functions is used for correctness checking tools + ******************************************************************/ +/** @{ */ +/** + * @ingroup legacy + * @deprecated Legacy API + * @brief Fast synchronization which does no require spinning. + * - This special function is to be used by TBB and OpenMP libraries only when they know + * there is no spin but they need to suppress TC warnings about shared variable modifications. + * - It only has corresponding pointers in static library and does not have corresponding function + * in dynamic library. + * @see void __itt_sync_prepare(void* addr); + */ +void ITTAPI __itt_fsync_prepare(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, fsync_prepare, (void *addr)) +#define __itt_fsync_prepare ITTNOTIFY_VOID(fsync_prepare) +#define __itt_fsync_prepare_ptr ITTNOTIFY_NAME(fsync_prepare) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_fsync_prepare(addr) +#define __itt_fsync_prepare_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_fsync_prepare_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup legacy + * @deprecated Legacy API + * @brief Fast synchronization which does no require spinning. + * - This special function is to be used by TBB and OpenMP libraries only when they know + * there is no spin but they need to suppress TC warnings about shared variable modifications. + * - It only has corresponding pointers in static library and does not have corresponding function + * in dynamic library. + * @see void __itt_sync_cancel(void *addr); + */ +void ITTAPI __itt_fsync_cancel(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, fsync_cancel, (void *addr)) +#define __itt_fsync_cancel ITTNOTIFY_VOID(fsync_cancel) +#define __itt_fsync_cancel_ptr ITTNOTIFY_NAME(fsync_cancel) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_fsync_cancel(addr) +#define __itt_fsync_cancel_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_fsync_cancel_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup legacy + * @deprecated Legacy API + * @brief Fast synchronization which does no require spinning. + * - This special function is to be used by TBB and OpenMP libraries only when they know + * there is no spin but they need to suppress TC warnings about shared variable modifications. + * - It only has corresponding pointers in static library and does not have corresponding function + * in dynamic library. + * @see void __itt_sync_acquired(void *addr); + */ +void ITTAPI __itt_fsync_acquired(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, fsync_acquired, (void *addr)) +#define __itt_fsync_acquired ITTNOTIFY_VOID(fsync_acquired) +#define __itt_fsync_acquired_ptr ITTNOTIFY_NAME(fsync_acquired) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_fsync_acquired(addr) +#define __itt_fsync_acquired_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_fsync_acquired_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup legacy + * @deprecated Legacy API + * @brief Fast synchronization which does no require spinning. + * - This special function is to be used by TBB and OpenMP libraries only when they know + * there is no spin but they need to suppress TC warnings about shared variable modifications. + * - It only has corresponding pointers in static library and does not have corresponding function + * in dynamic library. + * @see void __itt_sync_releasing(void* addr); + */ +void ITTAPI __itt_fsync_releasing(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, fsync_releasing, (void *addr)) +#define __itt_fsync_releasing ITTNOTIFY_VOID(fsync_releasing) +#define __itt_fsync_releasing_ptr ITTNOTIFY_NAME(fsync_releasing) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_fsync_releasing(addr) +#define __itt_fsync_releasing_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_fsync_releasing_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} */ + +/** + * @defgroup model Modeling by Intel(R) Parallel Advisor + * @ingroup public + * This is the subset of itt used for modeling by Intel(R) Parallel Advisor. + * This API is called ONLY using annotate.h, by "Annotation" macros + * the user places in their sources during the parallelism modeling steps. + * + * site_begin/end and task_begin/end take the address of handle variables, + * which are writeable by the API. Handles must be 0 initialized prior + * to the first call to begin, or may cause a run-time failure. + * The handles are initialized in a multi-thread safe way by the API if + * the handle is 0. The commonly expected idiom is one static handle to + * identify a site or task. If a site or task of the same name has already + * been started during this collection, the same handle MAY be returned, + * but is not required to be - it is unspecified if data merging is done + * based on name. These routines also take an instance variable. Like + * the lexical instance, these must be 0 initialized. Unlike the lexical + * instance, this is used to track a single dynamic instance. + * + * API used by the Intel(R) Parallel Advisor to describe potential concurrency + * and related activities. User-added source annotations expand to calls + * to these procedures to enable modeling of a hypothetical concurrent + * execution serially. + * @{ + */ +#if !defined(_ADVISOR_ANNOTATE_H_) || defined(ANNOTATE_EXPAND_NULL) + +typedef void* __itt_model_site; /*!< @brief handle for lexical site */ +typedef void* __itt_model_site_instance; /*!< @brief handle for dynamic instance */ +typedef void* __itt_model_task; /*!< @brief handle for lexical site */ +typedef void* __itt_model_task_instance; /*!< @brief handle for dynamic instance */ + +/** + * @enum __itt_model_disable + * @brief Enumerator for the disable methods + */ +typedef enum { + __itt_model_disable_observation, + __itt_model_disable_collection +} __itt_model_disable; + +#endif /* !_ADVISOR_ANNOTATE_H_ || ANNOTATE_EXPAND_NULL */ + +/** + * @brief ANNOTATE_SITE_BEGIN/ANNOTATE_SITE_END support. + * + * site_begin/end model a potential concurrency site. + * site instances may be recursively nested with themselves. + * site_end exits the most recently started but unended site for the current + * thread. The handle passed to end may be used to validate structure. + * Instances of a site encountered on different threads concurrently + * are considered completely distinct. If the site name for two different + * lexical sites match, it is unspecified whether they are treated as the + * same or different for data presentation. + */ +void ITTAPI __itt_model_site_begin(__itt_model_site *site, __itt_model_site_instance *instance, const char *name); +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_model_site_beginW(const wchar_t *name); +#endif +void ITTAPI __itt_model_site_beginA(const char *name); +void ITTAPI __itt_model_site_beginAL(const char *name, size_t siteNameLen); +void ITTAPI __itt_model_site_end (__itt_model_site *site, __itt_model_site_instance *instance); +void ITTAPI __itt_model_site_end_2(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_site_begin, (__itt_model_site *site, __itt_model_site_instance *instance, const char *name)) +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, model_site_beginW, (const wchar_t *name)) +#endif +ITT_STUBV(ITTAPI, void, model_site_beginA, (const char *name)) +ITT_STUBV(ITTAPI, void, model_site_beginAL, (const char *name, size_t siteNameLen)) +ITT_STUBV(ITTAPI, void, model_site_end, (__itt_model_site *site, __itt_model_site_instance *instance)) +ITT_STUBV(ITTAPI, void, model_site_end_2, (void)) +#define __itt_model_site_begin ITTNOTIFY_VOID(model_site_begin) +#define __itt_model_site_begin_ptr ITTNOTIFY_NAME(model_site_begin) +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_site_beginW ITTNOTIFY_VOID(model_site_beginW) +#define __itt_model_site_beginW_ptr ITTNOTIFY_NAME(model_site_beginW) +#endif +#define __itt_model_site_beginA ITTNOTIFY_VOID(model_site_beginA) +#define __itt_model_site_beginA_ptr ITTNOTIFY_NAME(model_site_beginA) +#define __itt_model_site_beginAL ITTNOTIFY_VOID(model_site_beginAL) +#define __itt_model_site_beginAL_ptr ITTNOTIFY_NAME(model_site_beginAL) +#define __itt_model_site_end ITTNOTIFY_VOID(model_site_end) +#define __itt_model_site_end_ptr ITTNOTIFY_NAME(model_site_end) +#define __itt_model_site_end_2 ITTNOTIFY_VOID(model_site_end_2) +#define __itt_model_site_end_2_ptr ITTNOTIFY_NAME(model_site_end_2) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_site_begin(site, instance, name) +#define __itt_model_site_begin_ptr 0 +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_site_beginW(name) +#define __itt_model_site_beginW_ptr 0 +#endif +#define __itt_model_site_beginA(name) +#define __itt_model_site_beginA_ptr 0 +#define __itt_model_site_beginAL(name, siteNameLen) +#define __itt_model_site_beginAL_ptr 0 +#define __itt_model_site_end(site, instance) +#define __itt_model_site_end_ptr 0 +#define __itt_model_site_end_2() +#define __itt_model_site_end_2_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_site_begin_ptr 0 +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_site_beginW_ptr 0 +#endif +#define __itt_model_site_beginA_ptr 0 +#define __itt_model_site_beginAL_ptr 0 +#define __itt_model_site_end_ptr 0 +#define __itt_model_site_end_2_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_TASK_BEGIN/ANNOTATE_TASK_END support + * + * task_begin/end model a potential task, which is contained within the most + * closely enclosing dynamic site. task_end exits the most recently started + * but unended task. The handle passed to end may be used to validate + * structure. It is unspecified if bad dynamic nesting is detected. If it + * is, it should be encoded in the resulting data collection. The collector + * should not fail due to construct nesting issues, nor attempt to directly + * indicate the problem. + */ +void ITTAPI __itt_model_task_begin(__itt_model_task *task, __itt_model_task_instance *instance, const char *name); +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_model_task_beginW(const wchar_t *name); +void ITTAPI __itt_model_iteration_taskW(const wchar_t *name); +#endif +void ITTAPI __itt_model_task_beginA(const char *name); +void ITTAPI __itt_model_task_beginAL(const char *name, size_t taskNameLen); +void ITTAPI __itt_model_iteration_taskA(const char *name); +void ITTAPI __itt_model_iteration_taskAL(const char *name, size_t taskNameLen); +void ITTAPI __itt_model_task_end (__itt_model_task *task, __itt_model_task_instance *instance); +void ITTAPI __itt_model_task_end_2(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_task_begin, (__itt_model_task *task, __itt_model_task_instance *instance, const char *name)) +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, model_task_beginW, (const wchar_t *name)) +ITT_STUBV(ITTAPI, void, model_iteration_taskW, (const wchar_t *name)) +#endif +ITT_STUBV(ITTAPI, void, model_task_beginA, (const char *name)) +ITT_STUBV(ITTAPI, void, model_task_beginAL, (const char *name, size_t taskNameLen)) +ITT_STUBV(ITTAPI, void, model_iteration_taskA, (const char *name)) +ITT_STUBV(ITTAPI, void, model_iteration_taskAL, (const char *name, size_t taskNameLen)) +ITT_STUBV(ITTAPI, void, model_task_end, (__itt_model_task *task, __itt_model_task_instance *instance)) +ITT_STUBV(ITTAPI, void, model_task_end_2, (void)) +#define __itt_model_task_begin ITTNOTIFY_VOID(model_task_begin) +#define __itt_model_task_begin_ptr ITTNOTIFY_NAME(model_task_begin) +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_task_beginW ITTNOTIFY_VOID(model_task_beginW) +#define __itt_model_task_beginW_ptr ITTNOTIFY_NAME(model_task_beginW) +#define __itt_model_iteration_taskW ITTNOTIFY_VOID(model_iteration_taskW) +#define __itt_model_iteration_taskW_ptr ITTNOTIFY_NAME(model_iteration_taskW) +#endif +#define __itt_model_task_beginA ITTNOTIFY_VOID(model_task_beginA) +#define __itt_model_task_beginA_ptr ITTNOTIFY_NAME(model_task_beginA) +#define __itt_model_task_beginAL ITTNOTIFY_VOID(model_task_beginAL) +#define __itt_model_task_beginAL_ptr ITTNOTIFY_NAME(model_task_beginAL) +#define __itt_model_iteration_taskA ITTNOTIFY_VOID(model_iteration_taskA) +#define __itt_model_iteration_taskA_ptr ITTNOTIFY_NAME(model_iteration_taskA) +#define __itt_model_iteration_taskAL ITTNOTIFY_VOID(model_iteration_taskAL) +#define __itt_model_iteration_taskAL_ptr ITTNOTIFY_NAME(model_iteration_taskAL) +#define __itt_model_task_end ITTNOTIFY_VOID(model_task_end) +#define __itt_model_task_end_ptr ITTNOTIFY_NAME(model_task_end) +#define __itt_model_task_end_2 ITTNOTIFY_VOID(model_task_end_2) +#define __itt_model_task_end_2_ptr ITTNOTIFY_NAME(model_task_end_2) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_task_begin(task, instance, name) +#define __itt_model_task_begin_ptr 0 +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_task_beginW(name) +#define __itt_model_task_beginW_ptr 0 +#endif +#define __itt_model_task_beginA(name) +#define __itt_model_task_beginA_ptr 0 +#define __itt_model_task_beginAL(name, siteNameLen) +#define __itt_model_task_beginAL_ptr 0 +#define __itt_model_iteration_taskA(name) +#define __itt_model_iteration_taskA_ptr 0 +#define __itt_model_iteration_taskAL(name, siteNameLen) +#define __itt_model_iteration_taskAL_ptr 0 +#define __itt_model_task_end(task, instance) +#define __itt_model_task_end_ptr 0 +#define __itt_model_task_end_2() +#define __itt_model_task_end_2_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_task_begin_ptr 0 +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_model_task_beginW_ptr 0 +#endif +#define __itt_model_task_beginA_ptr 0 +#define __itt_model_task_beginAL_ptr 0 +#define __itt_model_iteration_taskA_ptr 0 +#define __itt_model_iteration_taskAL_ptr 0 +#define __itt_model_task_end_ptr 0 +#define __itt_model_task_end_2_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_LOCK_ACQUIRE/ANNOTATE_LOCK_RELEASE support + * + * lock_acquire/release model a potential lock for both lockset and + * performance modeling. Each unique address is modeled as a separate + * lock, with invalid addresses being valid lock IDs. Specifically: + * no storage is accessed by the API at the specified address - it is only + * used for lock identification. Lock acquires may be self-nested and are + * unlocked by a corresponding number of releases. + * (These closely correspond to __itt_sync_acquired/__itt_sync_releasing, + * but may not have identical semantics.) + */ +void ITTAPI __itt_model_lock_acquire(void *lock); +void ITTAPI __itt_model_lock_acquire_2(void *lock); +void ITTAPI __itt_model_lock_release(void *lock); +void ITTAPI __itt_model_lock_release_2(void *lock); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_lock_acquire, (void *lock)) +ITT_STUBV(ITTAPI, void, model_lock_acquire_2, (void *lock)) +ITT_STUBV(ITTAPI, void, model_lock_release, (void *lock)) +ITT_STUBV(ITTAPI, void, model_lock_release_2, (void *lock)) +#define __itt_model_lock_acquire ITTNOTIFY_VOID(model_lock_acquire) +#define __itt_model_lock_acquire_ptr ITTNOTIFY_NAME(model_lock_acquire) +#define __itt_model_lock_acquire_2 ITTNOTIFY_VOID(model_lock_acquire_2) +#define __itt_model_lock_acquire_2_ptr ITTNOTIFY_NAME(model_lock_acquire_2) +#define __itt_model_lock_release ITTNOTIFY_VOID(model_lock_release) +#define __itt_model_lock_release_ptr ITTNOTIFY_NAME(model_lock_release) +#define __itt_model_lock_release_2 ITTNOTIFY_VOID(model_lock_release_2) +#define __itt_model_lock_release_2_ptr ITTNOTIFY_NAME(model_lock_release_2) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_lock_acquire(lock) +#define __itt_model_lock_acquire_ptr 0 +#define __itt_model_lock_acquire_2(lock) +#define __itt_model_lock_acquire_2_ptr 0 +#define __itt_model_lock_release(lock) +#define __itt_model_lock_release_ptr 0 +#define __itt_model_lock_release_2(lock) +#define __itt_model_lock_release_2_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_lock_acquire_ptr 0 +#define __itt_model_lock_acquire_2_ptr 0 +#define __itt_model_lock_release_ptr 0 +#define __itt_model_lock_release_2_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_RECORD_ALLOCATION/ANNOTATE_RECORD_DEALLOCATION support + * + * record_allocation/deallocation describe user-defined memory allocator + * behavior, which may be required for correctness modeling to understand + * when storage is not expected to be actually reused across threads. + */ +void ITTAPI __itt_model_record_allocation (void *addr, size_t size); +void ITTAPI __itt_model_record_deallocation(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_record_allocation, (void *addr, size_t size)) +ITT_STUBV(ITTAPI, void, model_record_deallocation, (void *addr)) +#define __itt_model_record_allocation ITTNOTIFY_VOID(model_record_allocation) +#define __itt_model_record_allocation_ptr ITTNOTIFY_NAME(model_record_allocation) +#define __itt_model_record_deallocation ITTNOTIFY_VOID(model_record_deallocation) +#define __itt_model_record_deallocation_ptr ITTNOTIFY_NAME(model_record_deallocation) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_record_allocation(addr, size) +#define __itt_model_record_allocation_ptr 0 +#define __itt_model_record_deallocation(addr) +#define __itt_model_record_deallocation_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_record_allocation_ptr 0 +#define __itt_model_record_deallocation_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_INDUCTION_USES support + * + * Note particular storage is inductive through the end of the current site + */ +void ITTAPI __itt_model_induction_uses(void* addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_induction_uses, (void *addr, size_t size)) +#define __itt_model_induction_uses ITTNOTIFY_VOID(model_induction_uses) +#define __itt_model_induction_uses_ptr ITTNOTIFY_NAME(model_induction_uses) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_induction_uses(addr, size) +#define __itt_model_induction_uses_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_induction_uses_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_REDUCTION_USES support + * + * Note particular storage is used for reduction through the end + * of the current site + */ +void ITTAPI __itt_model_reduction_uses(void* addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_reduction_uses, (void *addr, size_t size)) +#define __itt_model_reduction_uses ITTNOTIFY_VOID(model_reduction_uses) +#define __itt_model_reduction_uses_ptr ITTNOTIFY_NAME(model_reduction_uses) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_reduction_uses(addr, size) +#define __itt_model_reduction_uses_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_reduction_uses_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_OBSERVE_USES support + * + * Have correctness modeling record observations about uses of storage + * through the end of the current site + */ +void ITTAPI __itt_model_observe_uses(void* addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_observe_uses, (void *addr, size_t size)) +#define __itt_model_observe_uses ITTNOTIFY_VOID(model_observe_uses) +#define __itt_model_observe_uses_ptr ITTNOTIFY_NAME(model_observe_uses) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_observe_uses(addr, size) +#define __itt_model_observe_uses_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_observe_uses_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_CLEAR_USES support + * + * Clear the special handling of a piece of storage related to induction, + * reduction or observe_uses + */ +void ITTAPI __itt_model_clear_uses(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_clear_uses, (void *addr)) +#define __itt_model_clear_uses ITTNOTIFY_VOID(model_clear_uses) +#define __itt_model_clear_uses_ptr ITTNOTIFY_NAME(model_clear_uses) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_clear_uses(addr) +#define __itt_model_clear_uses_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_clear_uses_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief ANNOTATE_DISABLE_*_PUSH/ANNOTATE_DISABLE_*_POP support + * + * disable_push/disable_pop push and pop disabling based on a parameter. + * Disabling observations stops processing of memory references during + * correctness modeling, and all annotations that occur in the disabled + * region. This allows description of code that is expected to be handled + * specially during conversion to parallelism or that is not recognized + * by tools (e.g. some kinds of synchronization operations.) + * This mechanism causes all annotations in the disabled region, other + * than disable_push and disable_pop, to be ignored. (For example, this + * might validly be used to disable an entire parallel site and the contained + * tasks and locking in it for data collection purposes.) + * The disable for collection is a more expensive operation, but reduces + * collector overhead significantly. This applies to BOTH correctness data + * collection and performance data collection. For example, a site + * containing a task might only enable data collection for the first 10 + * iterations. Both performance and correctness data should reflect this, + * and the program should run as close to full speed as possible when + * collection is disabled. + */ +void ITTAPI __itt_model_disable_push(__itt_model_disable x); +void ITTAPI __itt_model_disable_pop(void); +void ITTAPI __itt_model_aggregate_task(size_t x); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, model_disable_push, (__itt_model_disable x)) +ITT_STUBV(ITTAPI, void, model_disable_pop, (void)) +ITT_STUBV(ITTAPI, void, model_aggregate_task, (size_t x)) +#define __itt_model_disable_push ITTNOTIFY_VOID(model_disable_push) +#define __itt_model_disable_push_ptr ITTNOTIFY_NAME(model_disable_push) +#define __itt_model_disable_pop ITTNOTIFY_VOID(model_disable_pop) +#define __itt_model_disable_pop_ptr ITTNOTIFY_NAME(model_disable_pop) +#define __itt_model_aggregate_task ITTNOTIFY_VOID(model_aggregate_task) +#define __itt_model_aggregate_task_ptr ITTNOTIFY_NAME(model_aggregate_task) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_model_disable_push(x) +#define __itt_model_disable_push_ptr 0 +#define __itt_model_disable_pop() +#define __itt_model_disable_pop_ptr 0 +#define __itt_model_aggregate_task(x) +#define __itt_model_aggregate_task_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_model_disable_push_ptr 0 +#define __itt_model_disable_pop_ptr 0 +#define __itt_model_aggregate_task_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} model group */ + +/** + * @defgroup heap Heap + * @ingroup public + * Heap group + * @{ + */ + +typedef void* __itt_heap_function; + +/** + * @brief Create an identification for heap function + * @return non-zero identifier or NULL + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_heap_function ITTAPI __itt_heap_function_createA(const char* name, const char* domain); +__itt_heap_function ITTAPI __itt_heap_function_createW(const wchar_t* name, const wchar_t* domain); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_heap_function_create __itt_heap_function_createW +# define __itt_heap_function_create_ptr __itt_heap_function_createW_ptr +#else +# define __itt_heap_function_create __itt_heap_function_createA +# define __itt_heap_function_create_ptr __itt_heap_function_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_heap_function ITTAPI __itt_heap_function_create(const char* name, const char* domain); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createA, (const char* name, const char* domain)) +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createW, (const wchar_t* name, const wchar_t* domain)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_create, (const char* name, const char* domain)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_heap_function_createA ITTNOTIFY_DATA(heap_function_createA) +#define __itt_heap_function_createA_ptr ITTNOTIFY_NAME(heap_function_createA) +#define __itt_heap_function_createW ITTNOTIFY_DATA(heap_function_createW) +#define __itt_heap_function_createW_ptr ITTNOTIFY_NAME(heap_function_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_heap_function_create ITTNOTIFY_DATA(heap_function_create) +#define __itt_heap_function_create_ptr ITTNOTIFY_NAME(heap_function_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_heap_function_createA(name, domain) (__itt_heap_function)0 +#define __itt_heap_function_createA_ptr 0 +#define __itt_heap_function_createW(name, domain) (__itt_heap_function)0 +#define __itt_heap_function_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_heap_function_create(name, domain) (__itt_heap_function)0 +#define __itt_heap_function_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_heap_function_createA_ptr 0 +#define __itt_heap_function_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_heap_function_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an allocation begin occurrence. + */ +void ITTAPI __itt_heap_allocate_begin(__itt_heap_function h, size_t size, int initialized); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_allocate_begin, (__itt_heap_function h, size_t size, int initialized)) +#define __itt_heap_allocate_begin ITTNOTIFY_VOID(heap_allocate_begin) +#define __itt_heap_allocate_begin_ptr ITTNOTIFY_NAME(heap_allocate_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_allocate_begin(h, size, initialized) +#define __itt_heap_allocate_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_allocate_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an allocation end occurrence. + */ +void ITTAPI __itt_heap_allocate_end(__itt_heap_function h, void** addr, size_t size, int initialized); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_allocate_end, (__itt_heap_function h, void** addr, size_t size, int initialized)) +#define __itt_heap_allocate_end ITTNOTIFY_VOID(heap_allocate_end) +#define __itt_heap_allocate_end_ptr ITTNOTIFY_NAME(heap_allocate_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_allocate_end(h, addr, size, initialized) +#define __itt_heap_allocate_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_allocate_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an free begin occurrence. + */ +void ITTAPI __itt_heap_free_begin(__itt_heap_function h, void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_free_begin, (__itt_heap_function h, void* addr)) +#define __itt_heap_free_begin ITTNOTIFY_VOID(heap_free_begin) +#define __itt_heap_free_begin_ptr ITTNOTIFY_NAME(heap_free_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_free_begin(h, addr) +#define __itt_heap_free_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_free_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an free end occurrence. + */ +void ITTAPI __itt_heap_free_end(__itt_heap_function h, void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_free_end, (__itt_heap_function h, void* addr)) +#define __itt_heap_free_end ITTNOTIFY_VOID(heap_free_end) +#define __itt_heap_free_end_ptr ITTNOTIFY_NAME(heap_free_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_free_end(h, addr) +#define __itt_heap_free_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_free_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an reallocation begin occurrence. + */ +void ITTAPI __itt_heap_reallocate_begin(__itt_heap_function h, void* addr, size_t new_size, int initialized); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_reallocate_begin, (__itt_heap_function h, void* addr, size_t new_size, int initialized)) +#define __itt_heap_reallocate_begin ITTNOTIFY_VOID(heap_reallocate_begin) +#define __itt_heap_reallocate_begin_ptr ITTNOTIFY_NAME(heap_reallocate_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_reallocate_begin(h, addr, new_size, initialized) +#define __itt_heap_reallocate_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_reallocate_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an reallocation end occurrence. + */ +void ITTAPI __itt_heap_reallocate_end(__itt_heap_function h, void* addr, void** new_addr, size_t new_size, int initialized); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_reallocate_end, (__itt_heap_function h, void* addr, void** new_addr, size_t new_size, int initialized)) +#define __itt_heap_reallocate_end ITTNOTIFY_VOID(heap_reallocate_end) +#define __itt_heap_reallocate_end_ptr ITTNOTIFY_NAME(heap_reallocate_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_reallocate_end(h, addr, new_addr, new_size, initialized) +#define __itt_heap_reallocate_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_reallocate_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief internal access begin */ +void ITTAPI __itt_heap_internal_access_begin(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_internal_access_begin, (void)) +#define __itt_heap_internal_access_begin ITTNOTIFY_VOID(heap_internal_access_begin) +#define __itt_heap_internal_access_begin_ptr ITTNOTIFY_NAME(heap_internal_access_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_internal_access_begin() +#define __itt_heap_internal_access_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_internal_access_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief internal access end */ +void ITTAPI __itt_heap_internal_access_end(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_internal_access_end, (void)) +#define __itt_heap_internal_access_end ITTNOTIFY_VOID(heap_internal_access_end) +#define __itt_heap_internal_access_end_ptr ITTNOTIFY_NAME(heap_internal_access_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_internal_access_end() +#define __itt_heap_internal_access_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_internal_access_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief record memory growth begin */ +void ITTAPI __itt_heap_record_memory_growth_begin(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_record_memory_growth_begin, (void)) +#define __itt_heap_record_memory_growth_begin ITTNOTIFY_VOID(heap_record_memory_growth_begin) +#define __itt_heap_record_memory_growth_begin_ptr ITTNOTIFY_NAME(heap_record_memory_growth_begin) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_record_memory_growth_begin() +#define __itt_heap_record_memory_growth_begin_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_record_memory_growth_begin_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief record memory growth end */ +void ITTAPI __itt_heap_record_memory_growth_end(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_record_memory_growth_end, (void)) +#define __itt_heap_record_memory_growth_end ITTNOTIFY_VOID(heap_record_memory_growth_end) +#define __itt_heap_record_memory_growth_end_ptr ITTNOTIFY_NAME(heap_record_memory_growth_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_record_memory_growth_end() +#define __itt_heap_record_memory_growth_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_record_memory_growth_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Specify the type of heap detection/reporting to modify. + */ +/** + * @hideinitializer + * @brief Report on memory leaks. + */ +#define __itt_heap_leaks 0x00000001 + +/** + * @hideinitializer + * @brief Report on memory growth. + */ +#define __itt_heap_growth 0x00000002 + + +/** @brief heap reset detection */ +void ITTAPI __itt_heap_reset_detection(unsigned int reset_mask); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_reset_detection, (unsigned int reset_mask)) +#define __itt_heap_reset_detection ITTNOTIFY_VOID(heap_reset_detection) +#define __itt_heap_reset_detection_ptr ITTNOTIFY_NAME(heap_reset_detection) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_reset_detection() +#define __itt_heap_reset_detection_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_reset_detection_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief report */ +void ITTAPI __itt_heap_record(unsigned int record_mask); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, heap_record, (unsigned int record_mask)) +#define __itt_heap_record ITTNOTIFY_VOID(heap_record) +#define __itt_heap_record_ptr ITTNOTIFY_NAME(heap_record) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_heap_record() +#define __itt_heap_record_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_heap_record_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @} heap group */ +/** @endcond */ +/* ========================================================================== */ + +/** + * @defgroup domains Domains + * @ingroup public + * Domains group + * @{ + */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_domain +{ + volatile int flags; /*!< Zero if disabled, non-zero if enabled. The meaning of different non-zero values is reserved to the runtime */ + const char* nameA; /*!< Copy of original name in ASCII. */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* nameW; /*!< Copy of original name in UNICODE. */ +#else /* UNICODE || _UNICODE */ + void* nameW; +#endif /* UNICODE || _UNICODE */ + int extra1; /*!< Reserved to the runtime */ + void* extra2; /*!< Reserved to the runtime */ + struct ___itt_domain* next; +} __itt_domain; + +#pragma pack(pop) +/** @endcond */ + +/** + * @ingroup domains + * @brief Create a domain. + * Create domain using some domain name: the URI naming style is recommended. + * Because the set of domains is expected to be static over the application's + * execution time, there is no mechanism to destroy a domain. + * Any domain can be accessed by any thread in the process, regardless of + * which thread created the domain. This call is thread-safe. + * @param[in] name name of domain + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_domain* ITTAPI __itt_domain_createA(const char *name); +__itt_domain* ITTAPI __itt_domain_createW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_domain_create __itt_domain_createW +# define __itt_domain_create_ptr __itt_domain_createW_ptr +#else /* UNICODE */ +# define __itt_domain_create __itt_domain_createA +# define __itt_domain_create_ptr __itt_domain_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_domain* ITTAPI __itt_domain_create(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_domain*, domain_createA, (const char *name)) +ITT_STUB(ITTAPI, __itt_domain*, domain_createW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_domain*, domain_create, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_domain_createA ITTNOTIFY_DATA(domain_createA) +#define __itt_domain_createA_ptr ITTNOTIFY_NAME(domain_createA) +#define __itt_domain_createW ITTNOTIFY_DATA(domain_createW) +#define __itt_domain_createW_ptr ITTNOTIFY_NAME(domain_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_domain_create ITTNOTIFY_DATA(domain_create) +#define __itt_domain_create_ptr ITTNOTIFY_NAME(domain_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_domain_createA(name) (__itt_domain*)0 +#define __itt_domain_createA_ptr 0 +#define __itt_domain_createW(name) (__itt_domain*)0 +#define __itt_domain_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_domain_create(name) (__itt_domain*)0 +#define __itt_domain_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_domain_createA_ptr 0 +#define __itt_domain_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_domain_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} domains group */ + +/** + * @defgroup ids IDs + * @ingroup public + * IDs group + * @{ + */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_id +{ + unsigned long long d1, d2, d3; +} __itt_id; + +#pragma pack(pop) +/** @endcond */ + +static const __itt_id __itt_null = { 0, 0, 0 }; + +/** + * @ingroup ids + * @brief A convenience function is provided to create an ID without domain control. + * @brief This is a convenience function to initialize an __itt_id structure. This function + * does not affect the collector runtime in any way. After you make the ID with this + * function, you still must create it with the __itt_id_create function before using the ID + * to identify a named entity. + * @param[in] addr The address of object; high QWORD of the ID value. + * @param[in] extra The extra data to unique identify object; low QWORD of the ID value. + */ + +ITT_INLINE __itt_id ITTAPI __itt_id_make(void* addr, unsigned long long extra) ITT_INLINE_ATTRIBUTE; +ITT_INLINE __itt_id ITTAPI __itt_id_make(void* addr, unsigned long long extra) +{ + __itt_id id = __itt_null; + id.d1 = (unsigned long long)((uintptr_t)addr); + id.d2 = (unsigned long long)extra; + id.d3 = (unsigned long long)0; /* Reserved. Must be zero */ + return id; +} + +/** + * @ingroup ids + * @brief Create an instance of identifier. + * This establishes the beginning of the lifetime of an instance of + * the given ID in the trace. Once this lifetime starts, the ID + * can be used to tag named entity instances in calls such as + * __itt_task_begin, and to specify relationships among + * identified named entity instances, using the \ref relations APIs. + * Instance IDs are not domain specific! + * @param[in] domain The domain controlling the execution of this call. + * @param[in] id The ID to create. + */ +void ITTAPI __itt_id_create(const __itt_domain *domain, __itt_id id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, id_create, (const __itt_domain *domain, __itt_id id)) +#define __itt_id_create(d,x) ITTNOTIFY_VOID_D1(id_create,d,x) +#define __itt_id_create_ptr ITTNOTIFY_NAME(id_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_id_create(domain,id) +#define __itt_id_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_id_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup ids + * @brief Destroy an instance of identifier. + * This ends the lifetime of the current instance of the given ID value in the trace. + * Any relationships that are established after this lifetime ends are invalid. + * This call must be performed before the given ID value can be reused for a different + * named entity instance. + * @param[in] domain The domain controlling the execution of this call. + * @param[in] id The ID to destroy. + */ +void ITTAPI __itt_id_destroy(const __itt_domain *domain, __itt_id id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, id_destroy, (const __itt_domain *domain, __itt_id id)) +#define __itt_id_destroy(d,x) ITTNOTIFY_VOID_D1(id_destroy,d,x) +#define __itt_id_destroy_ptr ITTNOTIFY_NAME(id_destroy) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_id_destroy(domain,id) +#define __itt_id_destroy_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_id_destroy_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} ids group */ + +/** + * @defgroup handless String Handles + * @ingroup public + * String Handles group + * @{ + */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_string_handle +{ + const char* strA; /*!< Copy of original string in ASCII. */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* strW; /*!< Copy of original string in UNICODE. */ +#else /* UNICODE || _UNICODE */ + void* strW; +#endif /* UNICODE || _UNICODE */ + int extra1; /*!< Reserved. Must be zero */ + void* extra2; /*!< Reserved. Must be zero */ + struct ___itt_string_handle* next; +} __itt_string_handle; + +#pragma pack(pop) +/** @endcond */ + +/** + * @ingroup handles + * @brief Create a string handle. + * Create and return handle value that can be associated with a string. + * Consecutive calls to __itt_string_handle_create with the same name + * return the same value. Because the set of string handles is expected to remain + * static during the application's execution time, there is no mechanism to destroy a string handle. + * Any string handle can be accessed by any thread in the process, regardless of which thread created + * the string handle. This call is thread-safe. + * @param[in] name The input string + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_string_handle* ITTAPI __itt_string_handle_createA(const char *name); +__itt_string_handle* ITTAPI __itt_string_handle_createW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_string_handle_create __itt_string_handle_createW +# define __itt_string_handle_create_ptr __itt_string_handle_createW_ptr +#else /* UNICODE */ +# define __itt_string_handle_create __itt_string_handle_createA +# define __itt_string_handle_create_ptr __itt_string_handle_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_string_handle* ITTAPI __itt_string_handle_create(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createA, (const char *name)) +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_create, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_string_handle_createA ITTNOTIFY_DATA(string_handle_createA) +#define __itt_string_handle_createA_ptr ITTNOTIFY_NAME(string_handle_createA) +#define __itt_string_handle_createW ITTNOTIFY_DATA(string_handle_createW) +#define __itt_string_handle_createW_ptr ITTNOTIFY_NAME(string_handle_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_string_handle_create ITTNOTIFY_DATA(string_handle_create) +#define __itt_string_handle_create_ptr ITTNOTIFY_NAME(string_handle_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_string_handle_createA(name) (__itt_string_handle*)0 +#define __itt_string_handle_createA_ptr 0 +#define __itt_string_handle_createW(name) (__itt_string_handle*)0 +#define __itt_string_handle_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_string_handle_create(name) (__itt_string_handle*)0 +#define __itt_string_handle_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_string_handle_createA_ptr 0 +#define __itt_string_handle_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_string_handle_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} handles group */ + +/** @cond exclude_from_documentation */ +typedef unsigned long long __itt_timestamp; +/** @endcond */ + +#define __itt_timestamp_none ((__itt_timestamp)-1LL) + +/** @cond exclude_from_gpa_documentation */ + +/** + * @ingroup timestamps + * @brief Return timestamp corresponding to the current moment. + * This returns the timestamp in the format that is the most relevant for the current + * host or platform (RDTSC, QPC, and others). You can use the "<" operator to + * compare __itt_timestamp values. + */ +__itt_timestamp ITTAPI __itt_get_timestamp(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_timestamp, get_timestamp, (void)) +#define __itt_get_timestamp ITTNOTIFY_DATA(get_timestamp) +#define __itt_get_timestamp_ptr ITTNOTIFY_NAME(get_timestamp) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_get_timestamp() +#define __itt_get_timestamp_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_get_timestamp_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} timestamps */ +/** @endcond */ + +/** @cond exclude_from_gpa_documentation */ + +/** + * @defgroup regions Regions + * @ingroup public + * Regions group + * @{ + */ +/** + * @ingroup regions + * @brief Begin of region instance. + * Successive calls to __itt_region_begin with the same ID are ignored + * until a call to __itt_region_end with the same ID + * @param[in] domain The domain for this region instance + * @param[in] id The instance ID for this region instance. Must not be __itt_null + * @param[in] parentid The instance ID for the parent of this region instance, or __itt_null + * @param[in] name The name of this region + */ +void ITTAPI __itt_region_begin(const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name); + +/** + * @ingroup regions + * @brief End of region instance. + * The first call to __itt_region_end with a given ID ends the + * region. Successive calls with the same ID are ignored, as are + * calls that do not have a matching __itt_region_begin call. + * @param[in] domain The domain for this region instance + * @param[in] id The instance ID for this region instance + */ +void ITTAPI __itt_region_end(const __itt_domain *domain, __itt_id id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, region_begin, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, region_end, (const __itt_domain *domain, __itt_id id)) +#define __itt_region_begin(d,x,y,z) ITTNOTIFY_VOID_D3(region_begin,d,x,y,z) +#define __itt_region_begin_ptr ITTNOTIFY_NAME(region_begin) +#define __itt_region_end(d,x) ITTNOTIFY_VOID_D1(region_end,d,x) +#define __itt_region_end_ptr ITTNOTIFY_NAME(region_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_region_begin(d,x,y,z) +#define __itt_region_begin_ptr 0 +#define __itt_region_end(d,x) +#define __itt_region_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_region_begin_ptr 0 +#define __itt_region_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} regions group */ + +/** + * @defgroup frames Frames + * @ingroup public + * Frames are similar to regions, but are intended to be easier to use and to implement. + * In particular: + * - Frames always represent periods of elapsed time + * - By default, frames have no nesting relationships + * @{ + */ + +/** + * @ingroup frames + * @brief Begin a frame instance. + * Successive calls to __itt_frame_begin with the + * same ID are ignored until a call to __itt_frame_end with the same ID. + * @param[in] domain The domain for this frame instance + * @param[in] id The instance ID for this frame instance or NULL + */ +void ITTAPI __itt_frame_begin_v3(const __itt_domain *domain, __itt_id *id); + +/** + * @ingroup frames + * @brief End a frame instance. + * The first call to __itt_frame_end with a given ID + * ends the frame. Successive calls with the same ID are ignored, as are + * calls that do not have a matching __itt_frame_begin call. + * @param[in] domain The domain for this frame instance + * @param[in] id The instance ID for this frame instance or NULL for current + */ +void ITTAPI __itt_frame_end_v3(const __itt_domain *domain, __itt_id *id); + +/** + * @ingroup frames + * @brief Submits a frame instance. + * Successive calls to __itt_frame_begin or __itt_frame_submit with the + * same ID are ignored until a call to __itt_frame_end or __itt_frame_submit + * with the same ID. + * Passing special __itt_timestamp_none value as "end" argument means + * take the current timestamp as the end timestamp. + * @param[in] domain The domain for this frame instance + * @param[in] id The instance ID for this frame instance or NULL + * @param[in] begin Timestamp of the beginning of the frame + * @param[in] end Timestamp of the end of the frame + */ +void ITTAPI __itt_frame_submit_v3(const __itt_domain *domain, __itt_id *id, + __itt_timestamp begin, __itt_timestamp end); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, frame_begin_v3, (const __itt_domain *domain, __itt_id *id)) +ITT_STUBV(ITTAPI, void, frame_end_v3, (const __itt_domain *domain, __itt_id *id)) +ITT_STUBV(ITTAPI, void, frame_submit_v3, (const __itt_domain *domain, __itt_id *id, __itt_timestamp begin, __itt_timestamp end)) +#define __itt_frame_begin_v3(d,x) ITTNOTIFY_VOID_D1(frame_begin_v3,d,x) +#define __itt_frame_begin_v3_ptr ITTNOTIFY_NAME(frame_begin_v3) +#define __itt_frame_end_v3(d,x) ITTNOTIFY_VOID_D1(frame_end_v3,d,x) +#define __itt_frame_end_v3_ptr ITTNOTIFY_NAME(frame_end_v3) +#define __itt_frame_submit_v3(d,x,b,e) ITTNOTIFY_VOID_D3(frame_submit_v3,d,x,b,e) +#define __itt_frame_submit_v3_ptr ITTNOTIFY_NAME(frame_submit_v3) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_frame_begin_v3(domain,id) +#define __itt_frame_begin_v3_ptr 0 +#define __itt_frame_end_v3(domain,id) +#define __itt_frame_end_v3_ptr 0 +#define __itt_frame_submit_v3(domain,id,begin,end) +#define __itt_frame_submit_v3_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_frame_begin_v3_ptr 0 +#define __itt_frame_end_v3_ptr 0 +#define __itt_frame_submit_v3_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} frames group */ +/** @endcond */ + +/** + * @defgroup taskgroup Task Group + * @ingroup public + * Task Group + * @{ + */ +/** + * @ingroup task_groups + * @brief Denotes a task_group instance. + * Successive calls to __itt_task_group with the same ID are ignored. + * @param[in] domain The domain for this task_group instance + * @param[in] id The instance ID for this task_group instance. Must not be __itt_null. + * @param[in] parentid The instance ID for the parent of this task_group instance, or __itt_null. + * @param[in] name The name of this task_group + */ +void ITTAPI __itt_task_group(const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, task_group, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) +#define __itt_task_group(d,x,y,z) ITTNOTIFY_VOID_D3(task_group,d,x,y,z) +#define __itt_task_group_ptr ITTNOTIFY_NAME(task_group) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_task_group(d,x,y,z) +#define __itt_task_group_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_task_group_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} taskgroup group */ + +/** + * @defgroup tasks Tasks + * @ingroup public + * A task instance represents a piece of work performed by a particular + * thread for a period of time. A call to __itt_task_begin creates a + * task instance. This becomes the current instance for that task on that + * thread. A following call to __itt_task_end on the same thread ends the + * instance. There may be multiple simultaneous instances of tasks with the + * same name on different threads. If an ID is specified, the task instance + * receives that ID. Nested tasks are allowed. + * + * Note: The task is defined by the bracketing of __itt_task_begin and + * __itt_task_end on the same thread. If some scheduling mechanism causes + * task switching (the thread executes a different user task) or task + * switching (the user task switches to a different thread) then this breaks + * the notion of current instance. Additional API calls are required to + * deal with that possibility. + * @{ + */ + +/** + * @ingroup tasks + * @brief Begin a task instance. + * @param[in] domain The domain for this task + * @param[in] taskid The instance ID for this task instance, or __itt_null + * @param[in] parentid The parent instance to which this task instance belongs, or __itt_null + * @param[in] name The name of this task + */ +void ITTAPI __itt_task_begin(const __itt_domain *domain, __itt_id taskid, __itt_id parentid, __itt_string_handle *name); + +/** + * @ingroup tasks + * @brief Begin a task instance. + * @param[in] domain The domain for this task + * @param[in] taskid The identifier for this task instance (may be 0) + * @param[in] parentid The parent of this task (may be 0) + * @param[in] fn The pointer to the function you are tracing + */ +void ITTAPI __itt_task_begin_fn(const __itt_domain *domain, __itt_id taskid, __itt_id parentid, void* fn); + +/** + * @ingroup tasks + * @brief End the current task instance. + * @param[in] domain The domain for this task + */ +void ITTAPI __itt_task_end(const __itt_domain *domain); + +/** + * @ingroup tasks + * @brief Begin an overlapped task instance. + * @param[in] domain The domain for this task. + * @param[in] taskid The identifier for this task instance, *cannot* be __itt_null. + * @param[in] parentid The parent of this task, or __itt_null. + * @param[in] name The name of this task. + */ +void ITTAPI __itt_task_begin_overlapped(const __itt_domain* domain, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); + +/** + * @ingroup tasks + * @brief End an overlapped task instance. + * @param[in] domain The domain for this task + * @param[in] taskid Explicit ID of finished task + */ +void ITTAPI __itt_task_end_overlapped(const __itt_domain *domain, __itt_id taskid); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, task_begin, (const __itt_domain *domain, __itt_id id, __itt_id parentid, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, task_begin_fn, (const __itt_domain *domain, __itt_id id, __itt_id parentid, void* fn)) +ITT_STUBV(ITTAPI, void, task_end, (const __itt_domain *domain)) +ITT_STUBV(ITTAPI, void, task_begin_overlapped, (const __itt_domain *domain, __itt_id taskid, __itt_id parentid, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, task_end_overlapped, (const __itt_domain *domain, __itt_id taskid)) +#define __itt_task_begin(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin,d,x,y,z) +#define __itt_task_begin_ptr ITTNOTIFY_NAME(task_begin) +#define __itt_task_begin_fn(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin_fn,d,x,y,z) +#define __itt_task_begin_fn_ptr ITTNOTIFY_NAME(task_begin_fn) +#define __itt_task_end(d) ITTNOTIFY_VOID_D0(task_end,d) +#define __itt_task_end_ptr ITTNOTIFY_NAME(task_end) +#define __itt_task_begin_overlapped(d,x,y,z) ITTNOTIFY_VOID_D3(task_begin_overlapped,d,x,y,z) +#define __itt_task_begin_overlapped_ptr ITTNOTIFY_NAME(task_begin_overlapped) +#define __itt_task_end_overlapped(d,x) ITTNOTIFY_VOID_D1(task_end_overlapped,d,x) +#define __itt_task_end_overlapped_ptr ITTNOTIFY_NAME(task_end_overlapped) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_task_begin(domain,id,parentid,name) +#define __itt_task_begin_ptr 0 +#define __itt_task_begin_fn(domain,id,parentid,fn) +#define __itt_task_begin_fn_ptr 0 +#define __itt_task_end(domain) +#define __itt_task_end_ptr 0 +#define __itt_task_begin_overlapped(domain,taskid,parentid,name) +#define __itt_task_begin_overlapped_ptr 0 +#define __itt_task_end_overlapped(domain,taskid) +#define __itt_task_end_overlapped_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_task_begin_ptr 0 +#define __itt_task_begin_fn_ptr 0 +#define __itt_task_end_ptr 0 +#define __itt_task_begin_overlapped_ptr 0 +#define __itt_task_end_overlapped_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} tasks group */ + + +/** + * @defgroup markers Markers + * Markers represent a single discreet event in time. Markers have a scope, + * described by an enumerated type __itt_scope. Markers are created by + * the API call __itt_marker. A marker instance can be given an ID for use in + * adding metadata. + * @{ + */ + +/** + * @brief Describes the scope of an event object in the trace. + */ +typedef enum +{ + __itt_scope_unknown = 0, + __itt_scope_global, + __itt_scope_track_group, + __itt_scope_track, + __itt_scope_task, + __itt_scope_marker +} __itt_scope; + +/** @cond exclude_from_documentation */ +#define __itt_marker_scope_unknown __itt_scope_unknown +#define __itt_marker_scope_global __itt_scope_global +#define __itt_marker_scope_process __itt_scope_track_group +#define __itt_marker_scope_thread __itt_scope_track +#define __itt_marker_scope_task __itt_scope_task +/** @endcond */ + +/** + * @ingroup markers + * @brief Create a marker instance + * @param[in] domain The domain for this marker + * @param[in] id The instance ID for this marker or __itt_null + * @param[in] name The name for this marker + * @param[in] scope The scope for this marker + */ +void ITTAPI __itt_marker(const __itt_domain *domain, __itt_id id, __itt_string_handle *name, __itt_scope scope); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, marker, (const __itt_domain *domain, __itt_id id, __itt_string_handle *name, __itt_scope scope)) +#define __itt_marker(d,x,y,z) ITTNOTIFY_VOID_D3(marker,d,x,y,z) +#define __itt_marker_ptr ITTNOTIFY_NAME(marker) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_marker(domain,id,name,scope) +#define __itt_marker_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_marker_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} markers group */ + +/** + * @defgroup metadata Metadata + * The metadata API is used to attach extra information to named + * entities. Metadata can be attached to an identified named entity by ID, + * or to the current entity (which is always a task). + * + * Conceptually metadata has a type (what kind of metadata), a key (the + * name of the metadata), and a value (the actual data). The encoding of + * the value depends on the type of the metadata. + * + * The type of metadata is specified by an enumerated type __itt_metdata_type. + * @{ + */ + +/** + * @ingroup parameters + * @brief describes the type of metadata + */ +typedef enum { + __itt_metadata_unknown = 0, + __itt_metadata_u64, /**< Unsigned 64-bit integer */ + __itt_metadata_s64, /**< Signed 64-bit integer */ + __itt_metadata_u32, /**< Unsigned 32-bit integer */ + __itt_metadata_s32, /**< Signed 32-bit integer */ + __itt_metadata_u16, /**< Unsigned 16-bit integer */ + __itt_metadata_s16, /**< Signed 16-bit integer */ + __itt_metadata_float, /**< Signed 32-bit floating-point */ + __itt_metadata_double /**< SIgned 64-bit floating-point */ +} __itt_metadata_type; + +/** + * @ingroup parameters + * @brief Add metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task + * @param[in] key The name of the metadata + * @param[in] type The type of the metadata + * @param[in] count The number of elements of the given type. If count == 0, no metadata will be added. + * @param[in] data The metadata itself +*/ +void ITTAPI __itt_metadata_add(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, metadata_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data)) +#define __itt_metadata_add(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(metadata_add,d,x,y,z,a,b) +#define __itt_metadata_add_ptr ITTNOTIFY_NAME(metadata_add) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_metadata_add(d,x,y,z,a,b) +#define __itt_metadata_add_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_metadata_add_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup parameters + * @brief Add string metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task + * @param[in] key The name of the metadata + * @param[in] data The metadata itself + * @param[in] length The number of characters in the string, or -1 if the length is unknown but the string is null-terminated +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_metadata_str_addA(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length); +void ITTAPI __itt_metadata_str_addW(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const wchar_t *data, size_t length); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_metadata_str_add __itt_metadata_str_addW +# define __itt_metadata_str_add_ptr __itt_metadata_str_addW_ptr +#else /* UNICODE */ +# define __itt_metadata_str_add __itt_metadata_str_addA +# define __itt_metadata_str_add_ptr __itt_metadata_str_addA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_metadata_str_add(const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length); +#endif + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, metadata_str_addA, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length)) +ITT_STUBV(ITTAPI, void, metadata_str_addW, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const wchar_t *data, size_t length)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, metadata_str_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char *data, size_t length)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_addA(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_addA,d,x,y,z,a) +#define __itt_metadata_str_addA_ptr ITTNOTIFY_NAME(metadata_str_addA) +#define __itt_metadata_str_addW(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_addW,d,x,y,z,a) +#define __itt_metadata_str_addW_ptr ITTNOTIFY_NAME(metadata_str_addW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add,d,x,y,z,a) +#define __itt_metadata_str_add_ptr ITTNOTIFY_NAME(metadata_str_add) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_addA(d,x,y,z,a) +#define __itt_metadata_str_addA_ptr 0 +#define __itt_metadata_str_addW(d,x,y,z,a) +#define __itt_metadata_str_addW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add(d,x,y,z,a) +#define __itt_metadata_str_add_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_addA_ptr 0 +#define __itt_metadata_str_addW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup parameters + * @brief Add metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] scope The scope of the instance to which the metadata is to be added + + * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task + + * @param[in] key The name of the metadata + * @param[in] type The type of the metadata + * @param[in] count The number of elements of the given type. If count == 0, no metadata will be added. + * @param[in] data The metadata itself +*/ +void ITTAPI __itt_metadata_add_with_scope(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, metadata_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data)) +#define __itt_metadata_add_with_scope(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(metadata_add_with_scope,d,x,y,z,a,b) +#define __itt_metadata_add_with_scope_ptr ITTNOTIFY_NAME(metadata_add_with_scope) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_metadata_add_with_scope(d,x,y,z,a,b) +#define __itt_metadata_add_with_scope_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_metadata_add_with_scope_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup parameters + * @brief Add string metadata to an instance of a named entity. + * @param[in] domain The domain controlling the call + * @param[in] scope The scope of the instance to which the metadata is to be added + + * @param[in] id The identifier of the instance to which the metadata is to be added, or __itt_null to add to the current task + + * @param[in] key The name of the metadata + * @param[in] data The metadata itself + * @param[in] length The number of characters in the string, or -1 if the length is unknown but the string is null-terminated +*/ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_metadata_str_add_with_scopeA(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length); +void ITTAPI __itt_metadata_str_add_with_scopeW(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const wchar_t *data, size_t length); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_metadata_str_add_with_scope __itt_metadata_str_add_with_scopeW +# define __itt_metadata_str_add_with_scope_ptr __itt_metadata_str_add_with_scopeW_ptr +#else /* UNICODE */ +# define __itt_metadata_str_add_with_scope __itt_metadata_str_add_with_scopeA +# define __itt_metadata_str_add_with_scope_ptr __itt_metadata_str_add_with_scopeA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_metadata_str_add_with_scope(const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length); +#endif + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeA, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length)) +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeW, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const wchar_t *data, size_t length)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_add_with_scopeA(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scopeA,d,x,y,z,a) +#define __itt_metadata_str_add_with_scopeA_ptr ITTNOTIFY_NAME(metadata_str_add_with_scopeA) +#define __itt_metadata_str_add_with_scopeW(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scopeW,d,x,y,z,a) +#define __itt_metadata_str_add_with_scopeW_ptr ITTNOTIFY_NAME(metadata_str_add_with_scopeW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add_with_scope(d,x,y,z,a) ITTNOTIFY_VOID_D4(metadata_str_add_with_scope,d,x,y,z,a) +#define __itt_metadata_str_add_with_scope_ptr ITTNOTIFY_NAME(metadata_str_add_with_scope) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_add_with_scopeA(d,x,y,z,a) +#define __itt_metadata_str_add_with_scopeA_ptr 0 +#define __itt_metadata_str_add_with_scopeW(d,x,y,z,a) +#define __itt_metadata_str_add_with_scopeW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add_with_scope(d,x,y,z,a) +#define __itt_metadata_str_add_with_scope_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_metadata_str_add_with_scopeA_ptr 0 +#define __itt_metadata_str_add_with_scopeW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_metadata_str_add_with_scope_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @} metadata group */ + +/** + * @defgroup relations Relations + * Instances of named entities can be explicitly associated with other + * instances using instance IDs and the relationship API calls. + * + * @{ + */ + +/** + * @ingroup relations + * @brief The kind of relation between two instances is specified by the enumerated type __itt_relation. + * Relations between instances can be added with an API call. The relation + * API uses instance IDs. Relations can be added before or after the actual + * instances are created and persist independently of the instances. This + * is the motivation for having different lifetimes for instance IDs and + * the actual instances. + */ +typedef enum +{ + __itt_relation_is_unknown = 0, + __itt_relation_is_dependent_on, /**< "A is dependent on B" means that A cannot start until B completes */ + __itt_relation_is_sibling_of, /**< "A is sibling of B" means that A and B were created as a group */ + __itt_relation_is_parent_of, /**< "A is parent of B" means that A created B */ + __itt_relation_is_continuation_of, /**< "A is continuation of B" means that A assumes the dependencies of B */ + __itt_relation_is_child_of, /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */ + __itt_relation_is_continued_by, /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */ + __itt_relation_is_predecessor_to /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */ +} __itt_relation; + +/** + * @ingroup relations + * @brief Add a relation to the current task instance. + * The current task instance is the head of the relation. + * @param[in] domain The domain controlling this call + * @param[in] relation The kind of relation + * @param[in] tail The ID for the tail of the relation + */ +void ITTAPI __itt_relation_add_to_current(const __itt_domain *domain, __itt_relation relation, __itt_id tail); + +/** + * @ingroup relations + * @brief Add a relation between two instance identifiers. + * @param[in] domain The domain controlling this call + * @param[in] head The ID for the head of the relation + * @param[in] relation The kind of relation + * @param[in] tail The ID for the tail of the relation + */ +void ITTAPI __itt_relation_add(const __itt_domain *domain, __itt_id head, __itt_relation relation, __itt_id tail); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, relation_add_to_current, (const __itt_domain *domain, __itt_relation relation, __itt_id tail)) +ITT_STUBV(ITTAPI, void, relation_add, (const __itt_domain *domain, __itt_id head, __itt_relation relation, __itt_id tail)) +#define __itt_relation_add_to_current(d,x,y) ITTNOTIFY_VOID_D2(relation_add_to_current,d,x,y) +#define __itt_relation_add_to_current_ptr ITTNOTIFY_NAME(relation_add_to_current) +#define __itt_relation_add(d,x,y,z) ITTNOTIFY_VOID_D3(relation_add,d,x,y,z) +#define __itt_relation_add_ptr ITTNOTIFY_NAME(relation_add) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_relation_add_to_current(d,x,y) +#define __itt_relation_add_to_current_ptr 0 +#define __itt_relation_add(d,x,y,z) +#define __itt_relation_add_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_relation_add_to_current_ptr 0 +#define __itt_relation_add_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} relations group */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_clock_info +{ + unsigned long long clock_freq; /*!< Clock domain frequency */ + unsigned long long clock_base; /*!< Clock domain base timestamp */ +} __itt_clock_info; + +#pragma pack(pop) +/** @endcond */ + +/** @cond exclude_from_documentation */ +typedef void (ITTAPI *__itt_get_clock_info_fn)(__itt_clock_info* clock_info, void* data); +/** @endcond */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_clock_domain +{ + __itt_clock_info info; /*!< Most recent clock domain info */ + __itt_get_clock_info_fn fn; /*!< Callback function pointer */ + void* fn_data; /*!< Input argument for the callback function */ + int extra1; /*!< Reserved. Must be zero */ + void* extra2; /*!< Reserved. Must be zero */ + struct ___itt_clock_domain* next; +} __itt_clock_domain; + +#pragma pack(pop) +/** @endcond */ + +/** + * @ingroup clockdomains + * @brief Create a clock domain. + * Certain applications require the capability to trace their application using + * a clock domain different than the CPU, for instance the instrumentation of events + * that occur on a GPU. + * Because the set of domains is expected to be static over the application's execution time, + * there is no mechanism to destroy a domain. + * Any domain can be accessed by any thread in the process, regardless of which thread created + * the domain. This call is thread-safe. + * @param[in] fn A pointer to a callback function which retrieves alternative CPU timestamps + * @param[in] fn_data Argument for a callback function; may be NULL + */ +__itt_clock_domain* ITTAPI __itt_clock_domain_create(__itt_get_clock_info_fn fn, void* fn_data); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_clock_domain*, clock_domain_create, (__itt_get_clock_info_fn fn, void* fn_data)) +#define __itt_clock_domain_create ITTNOTIFY_DATA(clock_domain_create) +#define __itt_clock_domain_create_ptr ITTNOTIFY_NAME(clock_domain_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_clock_domain_create(fn,fn_data) (__itt_clock_domain*)0 +#define __itt_clock_domain_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_clock_domain_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup clockdomains + * @brief Recalculate clock domains frequencies and clock base timestamps. + */ +void ITTAPI __itt_clock_domain_reset(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, clock_domain_reset, (void)) +#define __itt_clock_domain_reset ITTNOTIFY_VOID(clock_domain_reset) +#define __itt_clock_domain_reset_ptr ITTNOTIFY_NAME(clock_domain_reset) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_clock_domain_reset() +#define __itt_clock_domain_reset_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_clock_domain_reset_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup clockdomain + * @brief Create an instance of identifier. This establishes the beginning of the lifetime of + * an instance of the given ID in the trace. Once this lifetime starts, the ID can be used to + * tag named entity instances in calls such as __itt_task_begin, and to specify relationships among + * identified named entity instances, using the \ref relations APIs. + * @param[in] domain The domain controlling the execution of this call. + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] id The ID to create. + */ +void ITTAPI __itt_id_create_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id); + +/** + * @ingroup clockdomain + * @brief Destroy an instance of identifier. This ends the lifetime of the current instance of the + * given ID value in the trace. Any relationships that are established after this lifetime ends are + * invalid. This call must be performed before the given ID value can be reused for a different + * named entity instance. + * @param[in] domain The domain controlling the execution of this call. + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] id The ID to destroy. + */ +void ITTAPI __itt_id_destroy_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, id_create_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id)) +ITT_STUBV(ITTAPI, void, id_destroy_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id)) +#define __itt_id_create_ex(d,x,y,z) ITTNOTIFY_VOID_D3(id_create_ex,d,x,y,z) +#define __itt_id_create_ex_ptr ITTNOTIFY_NAME(id_create_ex) +#define __itt_id_destroy_ex(d,x,y,z) ITTNOTIFY_VOID_D3(id_destroy_ex,d,x,y,z) +#define __itt_id_destroy_ex_ptr ITTNOTIFY_NAME(id_destroy_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_id_create_ex(domain,clock_domain,timestamp,id) +#define __itt_id_create_ex_ptr 0 +#define __itt_id_destroy_ex(domain,clock_domain,timestamp,id) +#define __itt_id_destroy_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_id_create_ex_ptr 0 +#define __itt_id_destroy_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup clockdomain + * @brief Begin a task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] taskid The instance ID for this task instance, or __itt_null + * @param[in] parentid The parent instance to which this task instance belongs, or __itt_null + * @param[in] name The name of this task + */ +void ITTAPI __itt_task_begin_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); + +/** + * @ingroup clockdomain + * @brief Begin a task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] taskid The identifier for this task instance, or __itt_null + * @param[in] parentid The parent of this task, or __itt_null + * @param[in] fn The pointer to the function you are tracing + */ +void ITTAPI __itt_task_begin_fn_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, void* fn); + +/** + * @ingroup clockdomain + * @brief End the current task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + */ +void ITTAPI __itt_task_end_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, task_begin_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, task_begin_fn_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, void* fn)) +ITT_STUBV(ITTAPI, void, task_end_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp)) +#define __itt_task_begin_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_ex,d,x,y,z,a,b) +#define __itt_task_begin_ex_ptr ITTNOTIFY_NAME(task_begin_ex) +#define __itt_task_begin_fn_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_fn_ex,d,x,y,z,a,b) +#define __itt_task_begin_fn_ex_ptr ITTNOTIFY_NAME(task_begin_fn_ex) +#define __itt_task_end_ex(d,x,y) ITTNOTIFY_VOID_D2(task_end_ex,d,x,y) +#define __itt_task_end_ex_ptr ITTNOTIFY_NAME(task_end_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_task_begin_ex(domain,clock_domain,timestamp,id,parentid,name) +#define __itt_task_begin_ex_ptr 0 +#define __itt_task_begin_fn_ex(domain,clock_domain,timestamp,id,parentid,fn) +#define __itt_task_begin_fn_ex_ptr 0 +#define __itt_task_end_ex(domain,clock_domain,timestamp) +#define __itt_task_end_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_task_begin_ex_ptr 0 +#define __itt_task_begin_fn_ex_ptr 0 +#define __itt_task_end_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @defgroup counters Counters + * @ingroup public + * Counters are user-defined objects with a monotonically increasing + * value. Counter values are 64-bit unsigned integers. + * Counters have names that can be displayed in + * the tools. + * @{ + */ + +/** + * @brief opaque structure for counter identification + */ +/** @cond exclude_from_documentation */ + +typedef struct ___itt_counter* __itt_counter; + +/** + * @brief Create an unsigned 64 bits integer counter with given name/domain + * + * After __itt_counter_create() is called, __itt_counter_inc(id), __itt_counter_inc_delta(id, delta), + * __itt_counter_set_value(id, value_ptr) or __itt_counter_set_value_ex(id, clock_domain, timestamp, value_ptr) + * can be used to change the value of the counter, where value_ptr is a pointer to an unsigned 64 bits integer + * + * The call is equal to __itt_counter_create_typed(name, domain, __itt_metadata_u64) + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_counter ITTAPI __itt_counter_createA(const char *name, const char *domain); +__itt_counter ITTAPI __itt_counter_createW(const wchar_t *name, const wchar_t *domain); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_counter_create __itt_counter_createW +# define __itt_counter_create_ptr __itt_counter_createW_ptr +#else /* UNICODE */ +# define __itt_counter_create __itt_counter_createA +# define __itt_counter_create_ptr __itt_counter_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_counter ITTAPI __itt_counter_create(const char *name, const char *domain); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_counter, counter_createA, (const char *name, const char *domain)) +ITT_STUB(ITTAPI, __itt_counter, counter_createW, (const wchar_t *name, const wchar_t *domain)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_counter, counter_create, (const char *name, const char *domain)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA ITTNOTIFY_DATA(counter_createA) +#define __itt_counter_createA_ptr ITTNOTIFY_NAME(counter_createA) +#define __itt_counter_createW ITTNOTIFY_DATA(counter_createW) +#define __itt_counter_createW_ptr ITTNOTIFY_NAME(counter_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create ITTNOTIFY_DATA(counter_create) +#define __itt_counter_create_ptr ITTNOTIFY_NAME(counter_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA(name, domain) +#define __itt_counter_createA_ptr 0 +#define __itt_counter_createW(name, domain) +#define __itt_counter_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create(name, domain) +#define __itt_counter_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_createA_ptr 0 +#define __itt_counter_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Increment the unsigned 64 bits integer counter value + * + * Calling this function to non-unsigned 64 bits integer counters has no effect + */ +void ITTAPI __itt_counter_inc(__itt_counter id); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_inc, (__itt_counter id)) +#define __itt_counter_inc ITTNOTIFY_VOID(counter_inc) +#define __itt_counter_inc_ptr ITTNOTIFY_NAME(counter_inc) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_inc(id) +#define __itt_counter_inc_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_inc_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** + * @brief Increment the unsigned 64 bits integer counter value with x + * + * Calling this function to non-unsigned 64 bits integer counters has no effect + */ +void ITTAPI __itt_counter_inc_delta(__itt_counter id, unsigned long long value); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_inc_delta, (__itt_counter id, unsigned long long value)) +#define __itt_counter_inc_delta ITTNOTIFY_VOID(counter_inc_delta) +#define __itt_counter_inc_delta_ptr ITTNOTIFY_NAME(counter_inc_delta) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_inc_delta(id, value) +#define __itt_counter_inc_delta_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_inc_delta_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Decrement the unsigned 64 bits integer counter value + * + * Calling this function to non-unsigned 64 bits integer counters has no effect + */ +void ITTAPI __itt_counter_dec(__itt_counter id); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_dec, (__itt_counter id)) +#define __itt_counter_dec ITTNOTIFY_VOID(counter_dec) +#define __itt_counter_dec_ptr ITTNOTIFY_NAME(counter_dec) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_dec(id) +#define __itt_counter_dec_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_dec_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** + * @brief Decrement the unsigned 64 bits integer counter value with x + * + * Calling this function to non-unsigned 64 bits integer counters has no effect + */ +void ITTAPI __itt_counter_dec_delta(__itt_counter id, unsigned long long value); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_dec_delta, (__itt_counter id, unsigned long long value)) +#define __itt_counter_dec_delta ITTNOTIFY_VOID(counter_dec_delta) +#define __itt_counter_dec_delta_ptr ITTNOTIFY_NAME(counter_dec_delta) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_dec_delta(id, value) +#define __itt_counter_dec_delta_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_dec_delta_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup counters + * @brief Increment a counter by one. + * The first call with a given name creates a counter by that name and sets its + * value to zero. Successive calls increment the counter value. + * @param[in] domain The domain controlling the call. Counter names are not domain specific. + * The domain argument is used only to enable or disable the API calls. + * @param[in] name The name of the counter + */ +void ITTAPI __itt_counter_inc_v3(const __itt_domain *domain, __itt_string_handle *name); + +/** + * @ingroup counters + * @brief Increment a counter by the value specified in delta. + * @param[in] domain The domain controlling the call. Counter names are not domain specific. + * The domain argument is used only to enable or disable the API calls. + * @param[in] name The name of the counter + * @param[in] delta The amount by which to increment the counter + */ +void ITTAPI __itt_counter_inc_delta_v3(const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_inc_v3, (const __itt_domain *domain, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, counter_inc_delta_v3, (const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta)) +#define __itt_counter_inc_v3(d,x) ITTNOTIFY_VOID_D1(counter_inc_v3,d,x) +#define __itt_counter_inc_v3_ptr ITTNOTIFY_NAME(counter_inc_v3) +#define __itt_counter_inc_delta_v3(d,x,y) ITTNOTIFY_VOID_D2(counter_inc_delta_v3,d,x,y) +#define __itt_counter_inc_delta_v3_ptr ITTNOTIFY_NAME(counter_inc_delta_v3) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_inc_v3(domain,name) +#define __itt_counter_inc_v3_ptr 0 +#define __itt_counter_inc_delta_v3(domain,name,delta) +#define __itt_counter_inc_delta_v3_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_inc_v3_ptr 0 +#define __itt_counter_inc_delta_v3_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + + +/** + * @ingroup counters + * @brief Decrement a counter by one. + * The first call with a given name creates a counter by that name and sets its + * value to zero. Successive calls decrement the counter value. + * @param[in] domain The domain controlling the call. Counter names are not domain specific. + * The domain argument is used only to enable or disable the API calls. + * @param[in] name The name of the counter + */ +void ITTAPI __itt_counter_dec_v3(const __itt_domain *domain, __itt_string_handle *name); + +/** + * @ingroup counters + * @brief Decrement a counter by the value specified in delta. + * @param[in] domain The domain controlling the call. Counter names are not domain specific. + * The domain argument is used only to enable or disable the API calls. + * @param[in] name The name of the counter + * @param[in] delta The amount by which to decrement the counter + */ +void ITTAPI __itt_counter_dec_delta_v3(const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_dec_v3, (const __itt_domain *domain, __itt_string_handle *name)) +ITT_STUBV(ITTAPI, void, counter_dec_delta_v3, (const __itt_domain *domain, __itt_string_handle *name, unsigned long long delta)) +#define __itt_counter_dec_v3(d,x) ITTNOTIFY_VOID_D1(counter_dec_v3,d,x) +#define __itt_counter_dec_v3_ptr ITTNOTIFY_NAME(counter_dec_v3) +#define __itt_counter_dec_delta_v3(d,x,y) ITTNOTIFY_VOID_D2(counter_dec_delta_v3,d,x,y) +#define __itt_counter_dec_delta_v3_ptr ITTNOTIFY_NAME(counter_dec_delta_v3) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_dec_v3(domain,name) +#define __itt_counter_dec_v3_ptr 0 +#define __itt_counter_dec_delta_v3(domain,name,delta) +#define __itt_counter_dec_delta_v3_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_dec_v3_ptr 0 +#define __itt_counter_dec_delta_v3_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @} counters group */ + + +/** + * @brief Set the counter value + */ +void ITTAPI __itt_counter_set_value(__itt_counter id, void *value_ptr); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_set_value, (__itt_counter id, void *value_ptr)) +#define __itt_counter_set_value ITTNOTIFY_VOID(counter_set_value) +#define __itt_counter_set_value_ptr ITTNOTIFY_NAME(counter_set_value) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_set_value(id, value_ptr) +#define __itt_counter_set_value_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_set_value_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Set the counter value + */ +void ITTAPI __itt_counter_set_value_ex(__itt_counter id, __itt_clock_domain *clock_domain, unsigned long long timestamp, void *value_ptr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_set_value_ex, (__itt_counter id, __itt_clock_domain *clock_domain, unsigned long long timestamp, void *value_ptr)) +#define __itt_counter_set_value_ex ITTNOTIFY_VOID(counter_set_value_ex) +#define __itt_counter_set_value_ex_ptr ITTNOTIFY_NAME(counter_set_value_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_set_value_ex(id, clock_domain, timestamp, value_ptr) +#define __itt_counter_set_value_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_set_value_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Create a typed counter with given name/domain + * + * After __itt_counter_create_typed() is called, __itt_counter_inc(id), __itt_counter_inc_delta(id, delta), + * __itt_counter_set_value(id, value_ptr) or __itt_counter_set_value_ex(id, clock_domain, timestamp, value_ptr) + * can be used to change the value of the counter + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_counter ITTAPI __itt_counter_create_typedA(const char *name, const char *domain, __itt_metadata_type type); +__itt_counter ITTAPI __itt_counter_create_typedW(const wchar_t *name, const wchar_t *domain, __itt_metadata_type type); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_counter_create_typed __itt_counter_create_typedW +# define __itt_counter_create_typed_ptr __itt_counter_create_typedW_ptr +#else /* UNICODE */ +# define __itt_counter_create_typed __itt_counter_create_typedA +# define __itt_counter_create_typed_ptr __itt_counter_create_typedA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_counter ITTAPI __itt_counter_create_typed(const char *name, const char *domain, __itt_metadata_type type); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_counter, counter_create_typedA, (const char *name, const char *domain, __itt_metadata_type type)) +ITT_STUB(ITTAPI, __itt_counter, counter_create_typedW, (const wchar_t *name, const wchar_t *domain, __itt_metadata_type type)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_counter, counter_create_typed, (const char *name, const char *domain, __itt_metadata_type type)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_create_typedA ITTNOTIFY_DATA(counter_create_typedA) +#define __itt_counter_create_typedA_ptr ITTNOTIFY_NAME(counter_create_typedA) +#define __itt_counter_create_typedW ITTNOTIFY_DATA(counter_create_typedW) +#define __itt_counter_create_typedW_ptr ITTNOTIFY_NAME(counter_create_typedW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_typed ITTNOTIFY_DATA(counter_create_typed) +#define __itt_counter_create_typed_ptr ITTNOTIFY_NAME(counter_create_typed) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_create_typedA(name, domain, type) +#define __itt_counter_create_typedA_ptr 0 +#define __itt_counter_create_typedW(name, domain, type) +#define __itt_counter_create_typedW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_typed(name, domain, type) +#define __itt_counter_create_typed_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_counter_create_typedA_ptr 0 +#define __itt_counter_create_typedW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_counter_create_typed_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Destroy the counter identified by the pointer previously returned by __itt_counter_create() or + * __itt_counter_create_typed() + */ +void ITTAPI __itt_counter_destroy(__itt_counter id); + +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, counter_destroy, (__itt_counter id)) +#define __itt_counter_destroy ITTNOTIFY_VOID(counter_destroy) +#define __itt_counter_destroy_ptr ITTNOTIFY_NAME(counter_destroy) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_counter_destroy(id) +#define __itt_counter_destroy_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_counter_destroy_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} counters group */ + +/** + * @ingroup markers + * @brief Create a marker instance. + * @param[in] domain The domain for this marker + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] id The instance ID for this marker, or __itt_null + * @param[in] name The name for this marker + * @param[in] scope The scope for this marker + */ +void ITTAPI __itt_marker_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_string_handle *name, __itt_scope scope); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, marker_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_string_handle *name, __itt_scope scope)) +#define __itt_marker_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(marker_ex,d,x,y,z,a,b) +#define __itt_marker_ex_ptr ITTNOTIFY_NAME(marker_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_marker_ex(domain,clock_domain,timestamp,id,name,scope) +#define __itt_marker_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_marker_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @ingroup clockdomain + * @brief Add a relation to the current task instance. + * The current task instance is the head of the relation. + * @param[in] domain The domain controlling this call + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] relation The kind of relation + * @param[in] tail The ID for the tail of the relation + */ +void ITTAPI __itt_relation_add_to_current_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_relation relation, __itt_id tail); + +/** + * @ingroup clockdomain + * @brief Add a relation between two instance identifiers. + * @param[in] domain The domain controlling this call + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] head The ID for the head of the relation + * @param[in] relation The kind of relation + * @param[in] tail The ID for the tail of the relation + */ +void ITTAPI __itt_relation_add_ex(const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id head, __itt_relation relation, __itt_id tail); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, relation_add_to_current_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_relation relation, __itt_id tail)) +ITT_STUBV(ITTAPI, void, relation_add_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id head, __itt_relation relation, __itt_id tail)) +#define __itt_relation_add_to_current_ex(d,x,y,z,a) ITTNOTIFY_VOID_D4(relation_add_to_current_ex,d,x,y,z,a) +#define __itt_relation_add_to_current_ex_ptr ITTNOTIFY_NAME(relation_add_to_current_ex) +#define __itt_relation_add_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(relation_add_ex,d,x,y,z,a,b) +#define __itt_relation_add_ex_ptr ITTNOTIFY_NAME(relation_add_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_relation_add_to_current_ex(domain,clock_domain,timestame,relation,tail) +#define __itt_relation_add_to_current_ex_ptr 0 +#define __itt_relation_add_ex(domain,clock_domain,timestamp,head,relation,tail) +#define __itt_relation_add_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_relation_add_to_current_ex_ptr 0 +#define __itt_relation_add_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @cond exclude_from_documentation */ +typedef enum ___itt_track_group_type +{ + __itt_track_group_type_normal = 0 +} __itt_track_group_type; +/** @endcond */ + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_track_group +{ + __itt_string_handle* name; /*!< Name of the track group */ + struct ___itt_track* track; /*!< List of child tracks */ + __itt_track_group_type tgtype; /*!< Type of the track group */ + int extra1; /*!< Reserved. Must be zero */ + void* extra2; /*!< Reserved. Must be zero */ + struct ___itt_track_group* next; +} __itt_track_group; + +#pragma pack(pop) +/** @endcond */ + +/** + * @brief Placeholder for custom track types. Currently, "normal" custom track + * is the only available track type. + */ +typedef enum ___itt_track_type +{ + __itt_track_type_normal = 0 +#ifdef INTEL_ITTNOTIFY_API_PRIVATE + , __itt_track_type_queue +#endif /* INTEL_ITTNOTIFY_API_PRIVATE */ +} __itt_track_type; + +/** @cond exclude_from_documentation */ +#pragma pack(push, 8) + +typedef struct ___itt_track +{ + __itt_string_handle* name; /*!< Name of the track group */ + __itt_track_group* group; /*!< Parent group to a track */ + __itt_track_type ttype; /*!< Type of the track */ + int extra1; /*!< Reserved. Must be zero */ + void* extra2; /*!< Reserved. Must be zero */ + struct ___itt_track* next; +} __itt_track; + +#pragma pack(pop) +/** @endcond */ + +/** + * @brief Create logical track group. + */ +__itt_track_group* ITTAPI __itt_track_group_create(__itt_string_handle* name, __itt_track_group_type track_group_type); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_track_group*, track_group_create, (__itt_string_handle* name, __itt_track_group_type track_group_type)) +#define __itt_track_group_create ITTNOTIFY_DATA(track_group_create) +#define __itt_track_group_create_ptr ITTNOTIFY_NAME(track_group_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_track_group_create(name) (__itt_track_group*)0 +#define __itt_track_group_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_track_group_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Create logical track. + */ +__itt_track* ITTAPI __itt_track_create(__itt_track_group* track_group, __itt_string_handle* name, __itt_track_type track_type); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_track*, track_create, (__itt_track_group* track_group,__itt_string_handle* name, __itt_track_type track_type)) +#define __itt_track_create ITTNOTIFY_DATA(track_create) +#define __itt_track_create_ptr ITTNOTIFY_NAME(track_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_track_create(track_group,name,track_type) (__itt_track*)0 +#define __itt_track_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_track_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Set the logical track. + */ +void ITTAPI __itt_set_track(__itt_track* track); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, set_track, (__itt_track *track)) +#define __itt_set_track ITTNOTIFY_VOID(set_track) +#define __itt_set_track_ptr ITTNOTIFY_NAME(set_track) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_set_track(track) +#define __itt_set_track_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_set_track_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/* ========================================================================== */ +/** @cond exclude_from_gpa_documentation */ +/** + * @defgroup events Events + * @ingroup public + * Events group + * @{ + */ +/** @brief user event type */ +typedef int __itt_event; + +/** + * @brief Create an event notification + * @note name or namelen being null/name and namelen not matching, user event feature not enabled + * @return non-zero event identifier upon success and __itt_err otherwise + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_event LIBITTAPI __itt_event_createA(const char *name, int namelen); +__itt_event LIBITTAPI __itt_event_createW(const wchar_t *name, int namelen); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_event_create __itt_event_createW +# define __itt_event_create_ptr __itt_event_createW_ptr +#else +# define __itt_event_create __itt_event_createA +# define __itt_event_create_ptr __itt_event_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_event LIBITTAPI __itt_event_create(const char *name, int namelen); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, __itt_event, event_createA, (const char *name, int namelen)) +ITT_STUB(LIBITTAPI, __itt_event, event_createW, (const wchar_t *name, int namelen)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, __itt_event, event_create, (const char *name, int namelen)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA ITTNOTIFY_DATA(event_createA) +#define __itt_event_createA_ptr ITTNOTIFY_NAME(event_createA) +#define __itt_event_createW ITTNOTIFY_DATA(event_createW) +#define __itt_event_createW_ptr ITTNOTIFY_NAME(event_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create ITTNOTIFY_DATA(event_create) +#define __itt_event_create_ptr ITTNOTIFY_NAME(event_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA(name, namelen) (__itt_event)0 +#define __itt_event_createA_ptr 0 +#define __itt_event_createW(name, namelen) (__itt_event)0 +#define __itt_event_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create(name, namelen) (__itt_event)0 +#define __itt_event_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA_ptr 0 +#define __itt_event_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an event occurrence. + * @return __itt_err upon failure (invalid event id/user event feature not enabled) + */ +int LIBITTAPI __itt_event_start(__itt_event event); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(LIBITTAPI, int, event_start, (__itt_event event)) +#define __itt_event_start ITTNOTIFY_DATA(event_start) +#define __itt_event_start_ptr ITTNOTIFY_NAME(event_start) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_event_start(event) (int)0 +#define __itt_event_start_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_event_start_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an event end occurrence. + * @note It is optional if events do not have durations. + * @return __itt_err upon failure (invalid event id/user event feature not enabled) + */ +int LIBITTAPI __itt_event_end(__itt_event event); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(LIBITTAPI, int, event_end, (__itt_event event)) +#define __itt_event_end ITTNOTIFY_DATA(event_end) +#define __itt_event_end_ptr ITTNOTIFY_NAME(event_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_event_end(event) (int)0 +#define __itt_event_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_event_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} events group */ + + +/** + * @defgroup arrays Arrays Visualizer + * @ingroup public + * Visualize arrays + * @{ + */ + +/** + * @enum __itt_av_data_type + * @brief Defines types of arrays data (for C/C++ intrinsic types) + */ +typedef enum +{ + __itt_e_first = 0, + __itt_e_char = 0, /* 1-byte integer */ + __itt_e_uchar, /* 1-byte unsigned integer */ + __itt_e_int16, /* 2-byte integer */ + __itt_e_uint16, /* 2-byte unsigned integer */ + __itt_e_int32, /* 4-byte integer */ + __itt_e_uint32, /* 4-byte unsigned integer */ + __itt_e_int64, /* 8-byte integer */ + __itt_e_uint64, /* 8-byte unsigned integer */ + __itt_e_float, /* 4-byte floating */ + __itt_e_double, /* 8-byte floating */ + __itt_e_last = __itt_e_double +} __itt_av_data_type; + +/** + * @brief Save an array data to a file. + * Output format is defined by the file extension. The csv and bmp formats are supported (bmp - for 2-dimensional array only). + * @param[in] data - pointer to the array data + * @param[in] rank - the rank of the array + * @param[in] dimensions - pointer to an array of integers, which specifies the array dimensions. + * The size of dimensions must be equal to the rank + * @param[in] type - the type of the array, specified as one of the __itt_av_data_type values (for intrinsic types) + * @param[in] filePath - the file path; the output format is defined by the file extension + * @param[in] columnOrder - defines how the array is stored in the linear memory. + * It should be 1 for column-major order (e.g. in FORTRAN) or 0 - for row-major order (e.g. in C). + */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int ITTAPI __itt_av_saveA(void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder); +int ITTAPI __itt_av_saveW(void *data, int rank, const int *dimensions, int type, const wchar_t *filePath, int columnOrder); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_av_save __itt_av_saveW +# define __itt_av_save_ptr __itt_av_saveW_ptr +#else /* UNICODE */ +# define __itt_av_save __itt_av_saveA +# define __itt_av_save_ptr __itt_av_saveA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int ITTAPI __itt_av_save(void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, av_saveA, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder)) +ITT_STUB(ITTAPI, int, av_saveW, (void *data, int rank, const int *dimensions, int type, const wchar_t *filePath, int columnOrder)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, av_save, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_av_saveA ITTNOTIFY_DATA(av_saveA) +#define __itt_av_saveA_ptr ITTNOTIFY_NAME(av_saveA) +#define __itt_av_saveW ITTNOTIFY_DATA(av_saveW) +#define __itt_av_saveW_ptr ITTNOTIFY_NAME(av_saveW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_av_save ITTNOTIFY_DATA(av_save) +#define __itt_av_save_ptr ITTNOTIFY_NAME(av_save) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_av_saveA(name) +#define __itt_av_saveA_ptr 0 +#define __itt_av_saveW(name) +#define __itt_av_saveW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_av_save(name) +#define __itt_av_save_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_av_saveA_ptr 0 +#define __itt_av_saveW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_av_save_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +void ITTAPI __itt_enable_attach(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, enable_attach, (void)) +#define __itt_enable_attach ITTNOTIFY_VOID(enable_attach) +#define __itt_enable_attach_ptr ITTNOTIFY_NAME(enable_attach) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_enable_attach() +#define __itt_enable_attach_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_enable_attach_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @cond exclude_from_gpa_documentation */ + +/** @} arrays group */ + +/** @endcond */ + +/** + * @brief Module load info + * This API is used to report necessary information in case of module relocation + * @param[in] start_addr - relocated module start address + * @param[in] end_addr - relocated module end address + * @param[in] path - file system path to the module + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_module_loadA(void *start_addr, void *end_addr, const char *path); +void ITTAPI __itt_module_loadW(void *start_addr, void *end_addr, const wchar_t *path); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_module_load __itt_module_loadW +# define __itt_module_load_ptr __itt_module_loadW_ptr +#else /* UNICODE */ +# define __itt_module_load __itt_module_loadA +# define __itt_module_load_ptr __itt_module_loadA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_module_load(void *start_addr, void *end_addr, const char *path); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, void, module_loadA, (void *start_addr, void *end_addr, const char *path)) +ITT_STUB(ITTAPI, void, module_loadW, (void *start_addr, void *end_addr, const wchar_t *path)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, void, module_load, (void *start_addr, void *end_addr, const char *path)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_module_loadA ITTNOTIFY_VOID(module_loadA) +#define __itt_module_loadA_ptr ITTNOTIFY_NAME(module_loadA) +#define __itt_module_loadW ITTNOTIFY_VOID(module_loadW) +#define __itt_module_loadW_ptr ITTNOTIFY_NAME(module_loadW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_module_load ITTNOTIFY_VOID(module_load) +#define __itt_module_load_ptr ITTNOTIFY_NAME(module_load) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_module_loadA(start_addr, end_addr, path) +#define __itt_module_loadA_ptr 0 +#define __itt_module_loadW(start_addr, end_addr, path) +#define __itt_module_loadW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_module_load(start_addr, end_addr, path) +#define __itt_module_load_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_module_loadA_ptr 0 +#define __itt_module_loadW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_module_load_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ITTNOTIFY_H_ */ + +#ifdef INTEL_ITTNOTIFY_API_PRIVATE + +#ifndef _ITTNOTIFY_PRIVATE_ +#define _ITTNOTIFY_PRIVATE_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @ingroup clockdomain + * @brief Begin an overlapped task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] taskid The identifier for this task instance, *cannot* be __itt_null. + * @param[in] parentid The parent of this task, or __itt_null. + * @param[in] name The name of this task. + */ +void ITTAPI __itt_task_begin_overlapped_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name); + +/** + * @ingroup clockdomain + * @brief End an overlapped task instance. + * @param[in] domain The domain for this task + * @param[in] clock_domain The clock domain controlling the execution of this call. + * @param[in] timestamp The user defined timestamp. + * @param[in] taskid Explicit ID of finished task + */ +void ITTAPI __itt_task_end_overlapped_ex(const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, task_begin_overlapped_ex, (const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid, __itt_id parentid, __itt_string_handle* name)) +ITT_STUBV(ITTAPI, void, task_end_overlapped_ex, (const __itt_domain* domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id taskid)) +#define __itt_task_begin_overlapped_ex(d,x,y,z,a,b) ITTNOTIFY_VOID_D5(task_begin_overlapped_ex,d,x,y,z,a,b) +#define __itt_task_begin_overlapped_ex_ptr ITTNOTIFY_NAME(task_begin_overlapped_ex) +#define __itt_task_end_overlapped_ex(d,x,y,z) ITTNOTIFY_VOID_D3(task_end_overlapped_ex,d,x,y,z) +#define __itt_task_end_overlapped_ex_ptr ITTNOTIFY_NAME(task_end_overlapped_ex) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_task_begin_overlapped_ex(domain,clock_domain,timestamp,taskid,parentid,name) +#define __itt_task_begin_overlapped_ex_ptr 0 +#define __itt_task_end_overlapped_ex(domain,clock_domain,timestamp,taskid) +#define __itt_task_end_overlapped_ex_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_task_begin_overlapped_ex_ptr 0 +#define __itt_task_end_overlapped_ptr 0 +#define __itt_task_end_overlapped_ex_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @defgroup makrs_internal Marks + * @ingroup internal + * Marks group + * @warning Internal API: + * - It is not shipped to outside of Intel + * - It is delivered to internal Intel teams using e-mail or SVN access only + * @{ + */ +/** @brief user mark type */ +typedef int __itt_mark_type; + +/** + * @brief Creates a user mark type with the specified name using char or Unicode string. + * @param[in] name - name of mark to create + * @return Returns a handle to the mark type + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_mark_type ITTAPI __itt_mark_createA(const char *name); +__itt_mark_type ITTAPI __itt_mark_createW(const wchar_t *name); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_mark_create __itt_mark_createW +# define __itt_mark_create_ptr __itt_mark_createW_ptr +#else /* UNICODE */ +# define __itt_mark_create __itt_mark_createA +# define __itt_mark_create_ptr __itt_mark_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_mark_type ITTAPI __itt_mark_create(const char *name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_mark_type, mark_createA, (const char *name)) +ITT_STUB(ITTAPI, __itt_mark_type, mark_createW, (const wchar_t *name)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_mark_type, mark_create, (const char *name)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_createA ITTNOTIFY_DATA(mark_createA) +#define __itt_mark_createA_ptr ITTNOTIFY_NAME(mark_createA) +#define __itt_mark_createW ITTNOTIFY_DATA(mark_createW) +#define __itt_mark_createW_ptr ITTNOTIFY_NAME(mark_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_create ITTNOTIFY_DATA(mark_create) +#define __itt_mark_create_ptr ITTNOTIFY_NAME(mark_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_createA(name) (__itt_mark_type)0 +#define __itt_mark_createA_ptr 0 +#define __itt_mark_createW(name) (__itt_mark_type)0 +#define __itt_mark_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_create(name) (__itt_mark_type)0 +#define __itt_mark_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_createA_ptr 0 +#define __itt_mark_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Creates a "discrete" user mark type of the specified type and an optional parameter using char or Unicode string. + * + * - The mark of "discrete" type is placed to collection results in case of success. It appears in overtime view(s) as a special tick sign. + * - The call is "synchronous" - function returns after mark is actually added to results. + * - This function is useful, for example, to mark different phases of application + * (beginning of the next mark automatically meand end of current region). + * - Can be used together with "continuous" marks (see below) at the same collection session + * @param[in] mt - mark, created by __itt_mark_create(const char* name) function + * @param[in] parameter - string parameter of mark + * @return Returns zero value in case of success, non-zero value otherwise. + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int ITTAPI __itt_markA(__itt_mark_type mt, const char *parameter); +int ITTAPI __itt_markW(__itt_mark_type mt, const wchar_t *parameter); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_mark __itt_markW +# define __itt_mark_ptr __itt_markW_ptr +#else /* UNICODE */ +# define __itt_mark __itt_markA +# define __itt_mark_ptr __itt_markA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int ITTAPI __itt_mark(__itt_mark_type mt, const char *parameter); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, markA, (__itt_mark_type mt, const char *parameter)) +ITT_STUB(ITTAPI, int, markW, (__itt_mark_type mt, const wchar_t *parameter)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, mark, (__itt_mark_type mt, const char *parameter)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_markA ITTNOTIFY_DATA(markA) +#define __itt_markA_ptr ITTNOTIFY_NAME(markA) +#define __itt_markW ITTNOTIFY_DATA(markW) +#define __itt_markW_ptr ITTNOTIFY_NAME(markW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark ITTNOTIFY_DATA(mark) +#define __itt_mark_ptr ITTNOTIFY_NAME(mark) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_markA(mt, parameter) (int)0 +#define __itt_markA_ptr 0 +#define __itt_markW(mt, parameter) (int)0 +#define __itt_markW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark(mt, parameter) (int)0 +#define __itt_mark_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_markA_ptr 0 +#define __itt_markW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Use this if necessary to create a "discrete" user event type (mark) for process + * rather then for one thread + * @see int __itt_mark(__itt_mark_type mt, const char* parameter); + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int ITTAPI __itt_mark_globalA(__itt_mark_type mt, const char *parameter); +int ITTAPI __itt_mark_globalW(__itt_mark_type mt, const wchar_t *parameter); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_mark_global __itt_mark_globalW +# define __itt_mark_global_ptr __itt_mark_globalW_ptr +#else /* UNICODE */ +# define __itt_mark_global __itt_mark_globalA +# define __itt_mark_global_ptr __itt_mark_globalA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int ITTAPI __itt_mark_global(__itt_mark_type mt, const char *parameter); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, mark_globalA, (__itt_mark_type mt, const char *parameter)) +ITT_STUB(ITTAPI, int, mark_globalW, (__itt_mark_type mt, const wchar_t *parameter)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, mark_global, (__itt_mark_type mt, const char *parameter)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_globalA ITTNOTIFY_DATA(mark_globalA) +#define __itt_mark_globalA_ptr ITTNOTIFY_NAME(mark_globalA) +#define __itt_mark_globalW ITTNOTIFY_DATA(mark_globalW) +#define __itt_mark_globalW_ptr ITTNOTIFY_NAME(mark_globalW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_global ITTNOTIFY_DATA(mark_global) +#define __itt_mark_global_ptr ITTNOTIFY_NAME(mark_global) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_globalA(mt, parameter) (int)0 +#define __itt_mark_globalA_ptr 0 +#define __itt_mark_globalW(mt, parameter) (int)0 +#define __itt_mark_globalW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_global(mt, parameter) (int)0 +#define __itt_mark_global_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_mark_globalA_ptr 0 +#define __itt_mark_globalW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_mark_global_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Creates an "end" point for "continuous" mark with specified name. + * + * - Returns zero value in case of success, non-zero value otherwise. + * Also returns non-zero value when preceding "begin" point for the + * mark with the same name failed to be created or not created. + * - The mark of "continuous" type is placed to collection results in + * case of success. It appears in overtime view(s) as a special tick + * sign (different from "discrete" mark) together with line from + * corresponding "begin" mark to "end" mark. + * @note Continuous marks can overlap and be nested inside each other. + * Discrete mark can be nested inside marked region + * @param[in] mt - mark, created by __itt_mark_create(const char* name) function + * @return Returns zero value in case of success, non-zero value otherwise. + */ +int ITTAPI __itt_mark_off(__itt_mark_type mt); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, int, mark_off, (__itt_mark_type mt)) +#define __itt_mark_off ITTNOTIFY_DATA(mark_off) +#define __itt_mark_off_ptr ITTNOTIFY_NAME(mark_off) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_mark_off(mt) (int)0 +#define __itt_mark_off_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_mark_off_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Use this if necessary to create an "end" point for mark of process + * @see int __itt_mark_off(__itt_mark_type mt); + */ +int ITTAPI __itt_mark_global_off(__itt_mark_type mt); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, int, mark_global_off, (__itt_mark_type mt)) +#define __itt_mark_global_off ITTNOTIFY_DATA(mark_global_off) +#define __itt_mark_global_off_ptr ITTNOTIFY_NAME(mark_global_off) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_mark_global_off(mt) (int)0 +#define __itt_mark_global_off_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_mark_global_off_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} marks group */ + +/** + * @defgroup counters_internal Counters + * @ingroup internal + * Counters group + * @{ + */ + + +/** + * @defgroup stitch Stack Stitching + * @ingroup internal + * Stack Stitching group + * @{ + */ +/** + * @brief opaque structure for counter identification + */ +typedef struct ___itt_caller *__itt_caller; + +/** + * @brief Create the stitch point e.g. a point in call stack where other stacks should be stitched to. + * The function returns a unique identifier which is used to match the cut points with corresponding stitch points. + */ +__itt_caller ITTAPI __itt_stack_caller_create(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_caller, stack_caller_create, (void)) +#define __itt_stack_caller_create ITTNOTIFY_DATA(stack_caller_create) +#define __itt_stack_caller_create_ptr ITTNOTIFY_NAME(stack_caller_create) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_stack_caller_create() (__itt_caller)0 +#define __itt_stack_caller_create_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_stack_caller_create_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Destroy the information about stitch point identified by the pointer previously returned by __itt_stack_caller_create() + */ +void ITTAPI __itt_stack_caller_destroy(__itt_caller id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, stack_caller_destroy, (__itt_caller id)) +#define __itt_stack_caller_destroy ITTNOTIFY_VOID(stack_caller_destroy) +#define __itt_stack_caller_destroy_ptr ITTNOTIFY_NAME(stack_caller_destroy) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_stack_caller_destroy(id) +#define __itt_stack_caller_destroy_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_stack_caller_destroy_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Sets the cut point. Stack from each event which occurs after this call will be cut + * at the same stack level the function was called and stitched to the corresponding stitch point. + */ +void ITTAPI __itt_stack_callee_enter(__itt_caller id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, stack_callee_enter, (__itt_caller id)) +#define __itt_stack_callee_enter ITTNOTIFY_VOID(stack_callee_enter) +#define __itt_stack_callee_enter_ptr ITTNOTIFY_NAME(stack_callee_enter) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_stack_callee_enter(id) +#define __itt_stack_callee_enter_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_stack_callee_enter_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief This function eliminates the cut point which was set by latest __itt_stack_callee_enter(). + */ +void ITTAPI __itt_stack_callee_leave(__itt_caller id); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, stack_callee_leave, (__itt_caller id)) +#define __itt_stack_callee_leave ITTNOTIFY_VOID(stack_callee_leave) +#define __itt_stack_callee_leave_ptr ITTNOTIFY_NAME(stack_callee_leave) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_stack_callee_leave(id) +#define __itt_stack_callee_leave_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_stack_callee_leave_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @} stitch group */ + +/* ***************************************************************************************************************************** */ + +#include <stdarg.h> + +/** @cond exclude_from_documentation */ +typedef enum __itt_error_code +{ + __itt_error_success = 0, /*!< no error */ + __itt_error_no_module = 1, /*!< module can't be loaded */ + /* %1$s -- library name; win: %2$d -- system error code; unx: %2$s -- system error message. */ + __itt_error_no_symbol = 2, /*!< symbol not found */ + /* %1$s -- library name, %2$s -- symbol name. */ + __itt_error_unknown_group = 3, /*!< unknown group specified */ + /* %1$s -- env var name, %2$s -- group name. */ + __itt_error_cant_read_env = 4, /*!< GetEnvironmentVariable() failed */ + /* %1$s -- env var name, %2$d -- system error. */ + __itt_error_env_too_long = 5, /*!< variable value too long */ + /* %1$s -- env var name, %2$d -- actual length of the var, %3$d -- max allowed length. */ + __itt_error_system = 6 /*!< pthread_mutexattr_init or pthread_mutex_init failed */ + /* %1$s -- function name, %2$d -- errno. */ +} __itt_error_code; + +typedef void (__itt_error_handler_t)(__itt_error_code code, va_list); +__itt_error_handler_t* __itt_set_error_handler(__itt_error_handler_t*); + +const char* ITTAPI __itt_api_version(void); +/** @endcond */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#define __itt_error_handler ITT_JOIN(INTEL_ITTNOTIFY_PREFIX, error_handler) +void __itt_error_handler(__itt_error_code code, va_list args); +extern const int ITTNOTIFY_NAME(err); +#define __itt_err ITTNOTIFY_NAME(err) +ITT_STUB(ITTAPI, const char*, api_version, (void)) +#define __itt_api_version ITTNOTIFY_DATA(api_version) +#define __itt_api_version_ptr ITTNOTIFY_NAME(api_version) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_api_version() (const char*)0 +#define __itt_api_version_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_api_version_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ITTNOTIFY_PRIVATE_ */ + +#endif /* INTEL_ITTNOTIFY_API_PRIVATE */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_config.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_config.h new file mode 100644 index 00000000..bdb4ec29 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_config.h @@ -0,0 +1,585 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _ITTNOTIFY_CONFIG_H_ +#define _ITTNOTIFY_CONFIG_H_ + +/** @cond exclude_from_documentation */ +#ifndef ITT_OS_WIN +# define ITT_OS_WIN 1 +#endif /* ITT_OS_WIN */ + +#ifndef ITT_OS_LINUX +# define ITT_OS_LINUX 2 +#endif /* ITT_OS_LINUX */ + +#ifndef ITT_OS_MAC +# define ITT_OS_MAC 3 +#endif /* ITT_OS_MAC */ + +#ifndef ITT_OS_FREEBSD +# define ITT_OS_FREEBSD 4 +#endif /* ITT_OS_FREEBSD */ + +#ifndef ITT_OS +# if defined WIN32 || defined _WIN32 +# define ITT_OS ITT_OS_WIN +# elif defined( __APPLE__ ) && defined( __MACH__ ) +# define ITT_OS ITT_OS_MAC +# elif defined( __FreeBSD__ ) +# define ITT_OS ITT_OS_FREEBSD +# else +# define ITT_OS ITT_OS_LINUX +# endif +#endif /* ITT_OS */ + +#ifndef ITT_PLATFORM_WIN +# define ITT_PLATFORM_WIN 1 +#endif /* ITT_PLATFORM_WIN */ + +#ifndef ITT_PLATFORM_POSIX +# define ITT_PLATFORM_POSIX 2 +#endif /* ITT_PLATFORM_POSIX */ + +#ifndef ITT_PLATFORM_MAC +# define ITT_PLATFORM_MAC 3 +#endif /* ITT_PLATFORM_MAC */ + +#ifndef ITT_PLATFORM_FREEBSD +# define ITT_PLATFORM_FREEBSD 4 +#endif /* ITT_PLATFORM_FREEBSD */ + +#ifndef ITT_PLATFORM +# if ITT_OS==ITT_OS_WIN +# define ITT_PLATFORM ITT_PLATFORM_WIN +# elif ITT_OS==ITT_OS_MAC +# define ITT_PLATFORM ITT_PLATFORM_MAC +# elif ITT_OS==ITT_OS_FREEBSD +# define ITT_PLATFORM ITT_PLATFORM_FREEBSD +# else +# define ITT_PLATFORM ITT_PLATFORM_POSIX +# endif +#endif /* ITT_PLATFORM */ + +#if defined(_UNICODE) && !defined(UNICODE) +#define UNICODE +#endif + +#include <stddef.h> +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#include <tchar.h> +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#include <stdint.h> +#if defined(UNICODE) || defined(_UNICODE) +#include <wchar.h> +#endif /* UNICODE || _UNICODE */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef ITTAPI_CDECL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define ITTAPI_CDECL __cdecl +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define ITTAPI_CDECL __attribute__ ((cdecl)) +# else /* _M_IX86 || __i386__ */ +# define ITTAPI_CDECL /* actual only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* ITTAPI_CDECL */ + +#ifndef STDCALL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define STDCALL __stdcall +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define STDCALL __attribute__ ((stdcall)) +# else /* _M_IX86 || __i386__ */ +# define STDCALL /* supported only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* STDCALL */ + +#define ITTAPI ITTAPI_CDECL +#define LIBITTAPI ITTAPI_CDECL + +/* TODO: Temporary for compatibility! */ +#define ITTAPI_CALL ITTAPI_CDECL +#define LIBITTAPI_CALL ITTAPI_CDECL + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +/* use __forceinline (VC++ specific) */ +#define ITT_INLINE __forceinline +#define ITT_INLINE_ATTRIBUTE /* nothing */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/* + * Generally, functions are not inlined unless optimization is specified. + * For functions declared inline, this attribute inlines the function even + * if no optimization level was specified. + */ +#ifdef __STRICT_ANSI__ +#define ITT_INLINE static +#define ITT_INLINE_ATTRIBUTE __attribute__((unused)) +#else /* __STRICT_ANSI__ */ +#define ITT_INLINE static inline +#define ITT_INLINE_ATTRIBUTE __attribute__((always_inline, unused)) +#endif /* __STRICT_ANSI__ */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/** @endcond */ + +#ifndef ITT_ARCH_IA32 +# define ITT_ARCH_IA32 1 +#endif /* ITT_ARCH_IA32 */ + +#ifndef ITT_ARCH_IA32E +# define ITT_ARCH_IA32E 2 +#endif /* ITT_ARCH_IA32E */ + +#ifndef ITT_ARCH_ARM +# define ITT_ARCH_ARM 4 +#endif /* ITT_ARCH_ARM */ + +#ifndef ITT_ARCH_PPC64 +# define ITT_ARCH_PPC64 5 +#endif /* ITT_ARCH_PPC64 */ + +#ifndef ITT_ARCH +# if defined _M_IX86 || defined __i386__ +# define ITT_ARCH ITT_ARCH_IA32 +# elif defined _M_X64 || defined _M_AMD64 || defined __x86_64__ +# define ITT_ARCH ITT_ARCH_IA32E +# elif defined _M_IA64 || defined __ia64__ +# define ITT_ARCH ITT_ARCH_IA64 +# elif defined _M_ARM || defined __arm__ +# define ITT_ARCH ITT_ARCH_ARM +# elif defined __powerpc64__ +# define ITT_ARCH ITT_ARCH_PPC64 +# endif +#endif + +#ifdef __cplusplus +# define ITT_EXTERN_C extern "C" +# define ITT_EXTERN_C_BEGIN extern "C" { +# define ITT_EXTERN_C_END } +#else +# define ITT_EXTERN_C /* nothing */ +# define ITT_EXTERN_C_BEGIN /* nothing */ +# define ITT_EXTERN_C_END /* nothing */ +#endif /* __cplusplus */ + +#define ITT_TO_STR_AUX(x) #x +#define ITT_TO_STR(x) ITT_TO_STR_AUX(x) + +#define __ITT_BUILD_ASSERT(expr, suffix) do { \ + static char __itt_build_check_##suffix[(expr) ? 1 : -1]; \ + __itt_build_check_##suffix[0] = 0; \ +} while(0) +#define _ITT_BUILD_ASSERT(expr, suffix) __ITT_BUILD_ASSERT((expr), suffix) +#define ITT_BUILD_ASSERT(expr) _ITT_BUILD_ASSERT((expr), __LINE__) + +#define ITT_MAGIC { 0xED, 0xAB, 0xAB, 0xEC, 0x0D, 0xEE, 0xDA, 0x30 } + +/* Replace with snapshot date YYYYMMDD for promotion build. */ +#define API_VERSION_BUILD 20180723 + +#ifndef API_VERSION_NUM +#define API_VERSION_NUM 0.0.0 +#endif /* API_VERSION_NUM */ + +#define API_VERSION "ITT-API-Version " ITT_TO_STR(API_VERSION_NUM) \ + " (" ITT_TO_STR(API_VERSION_BUILD) ")" + +/* OS communication functions */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#include <windows.h> +typedef HMODULE lib_t; +typedef DWORD TIDT; +typedef CRITICAL_SECTION mutex_t; +#define MUTEX_INITIALIZER { 0 } +#define strong_alias(name, aliasname) /* empty for Windows */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#include <dlfcn.h> +#if defined(UNICODE) || defined(_UNICODE) +#include <wchar.h> +#endif /* UNICODE */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 /* need for PTHREAD_MUTEX_RECURSIVE */ +#endif /* _GNU_SOURCE */ +#ifndef __USE_UNIX98 +#define __USE_UNIX98 1 /* need for PTHREAD_MUTEX_RECURSIVE, on SLES11.1 with gcc 4.3.4 wherein pthread.h missing dependency on __USE_XOPEN2K8 */ +#endif /*__USE_UNIX98*/ +#include <pthread.h> +typedef void* lib_t; +typedef pthread_t TIDT; +typedef pthread_mutex_t mutex_t; +#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define _strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); +#define strong_alias(name, aliasname) _strong_alias(name, aliasname) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_get_proc(lib, name) GetProcAddress(lib, name) +#define __itt_mutex_init(mutex) InitializeCriticalSection(mutex) +#define __itt_mutex_lock(mutex) EnterCriticalSection(mutex) +#define __itt_mutex_unlock(mutex) LeaveCriticalSection(mutex) +#define __itt_load_lib(name) LoadLibraryA(name) +#define __itt_unload_lib(handle) FreeLibrary(handle) +#define __itt_system_error() (int)GetLastError() +#define __itt_fstrcmp(s1, s2) lstrcmpA(s1, s2) +#define __itt_fstrnlen(s, l) strnlen_s(s, l) +#define __itt_fstrcpyn(s1, b, s2, l) strncpy_s(s1, b, s2, l) +#define __itt_fstrdup(s) _strdup(s) +#define __itt_thread_id() GetCurrentThreadId() +#define __itt_thread_yield() SwitchToThread() +#ifndef ITT_SIMPLE_INIT +ITT_INLINE long +__itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE; +ITT_INLINE long __itt_interlocked_increment(volatile long* ptr) +{ + return InterlockedIncrement(ptr); +} +#endif /* ITT_SIMPLE_INIT */ + +#define DL_SYMBOLS (1) +#define PTHREAD_SYMBOLS (1) + +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +#define __itt_get_proc(lib, name) dlsym(lib, name) +#define __itt_mutex_init(mutex) {\ + pthread_mutexattr_t mutex_attr; \ + int error_code = pthread_mutexattr_init(&mutex_attr); \ + if (error_code) \ + __itt_report_error(__itt_error_system, "pthread_mutexattr_init", \ + error_code); \ + error_code = pthread_mutexattr_settype(&mutex_attr, \ + PTHREAD_MUTEX_RECURSIVE); \ + if (error_code) \ + __itt_report_error(__itt_error_system, "pthread_mutexattr_settype", \ + error_code); \ + error_code = pthread_mutex_init(mutex, &mutex_attr); \ + if (error_code) \ + __itt_report_error(__itt_error_system, "pthread_mutex_init", \ + error_code); \ + error_code = pthread_mutexattr_destroy(&mutex_attr); \ + if (error_code) \ + __itt_report_error(__itt_error_system, "pthread_mutexattr_destroy", \ + error_code); \ +} +#define __itt_mutex_lock(mutex) pthread_mutex_lock(mutex) +#define __itt_mutex_unlock(mutex) pthread_mutex_unlock(mutex) +#define __itt_load_lib(name) dlopen(name, RTLD_LAZY) +#define __itt_unload_lib(handle) dlclose(handle) +#define __itt_system_error() errno +#define __itt_fstrcmp(s1, s2) strcmp(s1, s2) + +/* makes customer code define safe APIs for SDL_STRNLEN_S and SDL_STRNCPY_S */ +#ifdef SDL_STRNLEN_S +#define __itt_fstrnlen(s, l) SDL_STRNLEN_S(s, l) +#else +#define __itt_fstrnlen(s, l) strlen(s) +#endif /* SDL_STRNLEN_S */ +#ifdef SDL_STRNCPY_S +#define __itt_fstrcpyn(s1, b, s2, l) SDL_STRNCPY_S(s1, b, s2, l) +#else +#define __itt_fstrcpyn(s1, b, s2, l) { \ + if (b > 0) { \ + /* 'volatile' is used to suppress the warning that a destination */ \ + /* bound depends on the length of the source. */ \ + volatile size_t num_to_copy = (size_t)(b - 1) < (size_t)(l) ? \ + (size_t)(b - 1) : (size_t)(l); \ + strncpy(s1, s2, num_to_copy); \ + s1[num_to_copy] = 0; \ + } \ +} +#endif /* SDL_STRNCPY_S */ + +#define __itt_fstrdup(s) strdup(s) +#define __itt_thread_id() pthread_self() +#define __itt_thread_yield() sched_yield() +#if ITT_ARCH==ITT_ARCH_IA64 +#ifdef __INTEL_COMPILER +#define __TBB_machine_fetchadd4(addr, val) __fetchadd4_acq((void *)addr, val) +#else /* __INTEL_COMPILER */ +/* TODO: Add Support for not Intel compilers for IA-64 architecture */ +#endif /* __INTEL_COMPILER */ +#elif ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_IA32E /* ITT_ARCH!=ITT_ARCH_IA64 */ +ITT_INLINE long +__TBB_machine_fetchadd4(volatile void* ptr, long addend) ITT_INLINE_ATTRIBUTE; +ITT_INLINE long __TBB_machine_fetchadd4(volatile void* ptr, long addend) +{ + long result; + __asm__ __volatile__("lock\nxadd %0,%1" + : "=r"(result),"=m"(*(int*)ptr) + : "0"(addend), "m"(*(int*)ptr) + : "memory"); + return result; +} +#elif ITT_ARCH==ITT_ARCH_ARM || ITT_ARCH==ITT_ARCH_PPC64 +#define __TBB_machine_fetchadd4(addr, val) __sync_fetch_and_add(addr, val) +#endif /* ITT_ARCH==ITT_ARCH_IA64 */ +#ifndef ITT_SIMPLE_INIT +ITT_INLINE long +__itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE; +ITT_INLINE long __itt_interlocked_increment(volatile long* ptr) +{ + return __TBB_machine_fetchadd4(ptr, 1) + 1L; +} +#endif /* ITT_SIMPLE_INIT */ + +void* dlopen(const char*, int) __attribute__((weak)); +void* dlsym(void*, const char*) __attribute__((weak)); +int dlclose(void*) __attribute__((weak)); +#define DL_SYMBOLS (dlopen && dlsym && dlclose) + +int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*) __attribute__((weak)); +int pthread_mutex_lock(pthread_mutex_t*) __attribute__((weak)); +int pthread_mutex_unlock(pthread_mutex_t*) __attribute__((weak)); +int pthread_mutex_destroy(pthread_mutex_t*) __attribute__((weak)); +int pthread_mutexattr_init(pthread_mutexattr_t*) __attribute__((weak)); +int pthread_mutexattr_settype(pthread_mutexattr_t*, int) __attribute__((weak)); +int pthread_mutexattr_destroy(pthread_mutexattr_t*) __attribute__((weak)); +pthread_t pthread_self(void) __attribute__((weak)); +#define PTHREAD_SYMBOLS (pthread_mutex_init && pthread_mutex_lock && pthread_mutex_unlock && pthread_mutex_destroy && pthread_mutexattr_init && pthread_mutexattr_settype && pthread_mutexattr_destroy && pthread_self) + +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +typedef enum { + __itt_collection_normal = 0, + __itt_collection_paused = 1 +} __itt_collection_state; + +typedef enum { + __itt_thread_normal = 0, + __itt_thread_ignored = 1 +} __itt_thread_state; + +#pragma pack(push, 8) + +typedef struct ___itt_thread_info +{ + const char* nameA; /*!< Copy of original name in ASCII. */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* nameW; /*!< Copy of original name in UNICODE. */ +#else /* UNICODE || _UNICODE */ + void* nameW; +#endif /* UNICODE || _UNICODE */ + TIDT tid; + __itt_thread_state state; /*!< Thread state (paused or normal) */ + int extra1; /*!< Reserved to the runtime */ + void* extra2; /*!< Reserved to the runtime */ + struct ___itt_thread_info* next; +} __itt_thread_info; + +#include "ittnotify_types.h" /* For __itt_group_id definition */ + +typedef struct ___itt_api_info_20101001 +{ + const char* name; + void** func_ptr; + void* init_func; + __itt_group_id group; +} __itt_api_info_20101001; + +typedef struct ___itt_api_info +{ + const char* name; + void** func_ptr; + void* init_func; + void* null_func; + __itt_group_id group; +} __itt_api_info; + +typedef struct __itt_counter_info +{ + const char* nameA; /*!< Copy of original name in ASCII. */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* nameW; /*!< Copy of original name in UNICODE. */ +#else /* UNICODE || _UNICODE */ + void* nameW; +#endif /* UNICODE || _UNICODE */ + const char* domainA; /*!< Copy of original name in ASCII. */ +#if defined(UNICODE) || defined(_UNICODE) + const wchar_t* domainW; /*!< Copy of original name in UNICODE. */ +#else /* UNICODE || _UNICODE */ + void* domainW; +#endif /* UNICODE || _UNICODE */ + int type; + long index; + int extra1; /*!< Reserved to the runtime */ + void* extra2; /*!< Reserved to the runtime */ + struct __itt_counter_info* next; +} __itt_counter_info_t; + +struct ___itt_domain; +struct ___itt_string_handle; + +typedef struct ___itt_global +{ + unsigned char magic[8]; + unsigned long version_major; + unsigned long version_minor; + unsigned long version_build; + volatile long api_initialized; + volatile long mutex_initialized; + volatile long atomic_counter; + mutex_t mutex; + lib_t lib; + void* error_handler; + const char** dll_path_ptr; + __itt_api_info* api_list_ptr; + struct ___itt_global* next; + /* Joinable structures below */ + __itt_thread_info* thread_list; + struct ___itt_domain* domain_list; + struct ___itt_string_handle* string_list; + __itt_collection_state state; + __itt_counter_info_t* counter_list; + unsigned int ipt_collect_events; +} __itt_global; + +#pragma pack(pop) + +#define NEW_THREAD_INFO_W(gptr,h,h_tail,t,s,n) { \ + h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \ + if (h != NULL) { \ + h->tid = t; \ + h->nameA = NULL; \ + h->nameW = n ? _wcsdup(n) : NULL; \ + h->state = s; \ + h->extra1 = 0; /* reserved */ \ + h->extra2 = NULL; /* reserved */ \ + h->next = NULL; \ + if (h_tail == NULL) \ + (gptr)->thread_list = h; \ + else \ + h_tail->next = h; \ + } \ +} + +#define NEW_THREAD_INFO_A(gptr,h,h_tail,t,s,n) { \ + h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \ + if (h != NULL) { \ + h->tid = t; \ + h->nameA = n ? __itt_fstrdup(n) : NULL; \ + h->nameW = NULL; \ + h->state = s; \ + h->extra1 = 0; /* reserved */ \ + h->extra2 = NULL; /* reserved */ \ + h->next = NULL; \ + if (h_tail == NULL) \ + (gptr)->thread_list = h; \ + else \ + h_tail->next = h; \ + } \ +} + +#define NEW_DOMAIN_W(gptr,h,h_tail,name) { \ + h = (__itt_domain*)malloc(sizeof(__itt_domain)); \ + if (h != NULL) { \ + h->flags = 1; /* domain is enabled by default */ \ + h->nameA = NULL; \ + h->nameW = name ? _wcsdup(name) : NULL; \ + h->extra1 = 0; /* reserved */ \ + h->extra2 = NULL; /* reserved */ \ + h->next = NULL; \ + if (h_tail == NULL) \ + (gptr)->domain_list = h; \ + else \ + h_tail->next = h; \ + } \ +} + +#define NEW_DOMAIN_A(gptr,h,h_tail,name) { \ + h = (__itt_domain*)malloc(sizeof(__itt_domain)); \ + if (h != NULL) { \ + h->flags = 1; /* domain is enabled by default */ \ + h->nameA = name ? __itt_fstrdup(name) : NULL; \ + h->nameW = NULL; \ + h->extra1 = 0; /* reserved */ \ + h->extra2 = NULL; /* reserved */ \ + h->next = NULL; \ + if (h_tail == NULL) \ + (gptr)->domain_list = h; \ + else \ + h_tail->next = h; \ + } \ +} + +#define NEW_STRING_HANDLE_W(gptr,h,h_tail,name) { \ + h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \ + if (h != NULL) { \ + h->strA = NULL; \ + h->strW = name ? _wcsdup(name) : NULL; \ + h->extra1 = 0; /* reserved */ \ + h->extra2 = NULL; /* reserved */ \ + h->next = NULL; \ + if (h_tail == NULL) \ + (gptr)->string_list = h; \ + else \ + h_tail->next = h; \ + } \ +} + +#define NEW_STRING_HANDLE_A(gptr,h,h_tail,name) { \ + h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \ + if (h != NULL) { \ + h->strA = name ? __itt_fstrdup(name) : NULL; \ + h->strW = NULL; \ + h->extra1 = 0; /* reserved */ \ + h->extra2 = NULL; /* reserved */ \ + h->next = NULL; \ + if (h_tail == NULL) \ + (gptr)->string_list = h; \ + else \ + h_tail->next = h; \ + } \ +} + +#define NEW_COUNTER_W(gptr,h,h_tail,name,domain,type) { \ + h = (__itt_counter_info_t*)malloc(sizeof(__itt_counter_info_t)); \ + if (h != NULL) { \ + h->nameA = NULL; \ + h->nameW = name ? _wcsdup(name) : NULL; \ + h->domainA = NULL; \ + h->domainW = name ? _wcsdup(domain) : NULL; \ + h->type = type; \ + h->index = 0; \ + h->next = NULL; \ + if (h_tail == NULL) \ + (gptr)->counter_list = h; \ + else \ + h_tail->next = h; \ + } \ +} + +#define NEW_COUNTER_A(gptr,h,h_tail,name,domain,type) { \ + h = (__itt_counter_info_t*)malloc(sizeof(__itt_counter_info_t)); \ + if (h != NULL) { \ + h->nameA = name ? __itt_fstrdup(name) : NULL; \ + h->nameW = NULL; \ + h->domainA = domain ? __itt_fstrdup(domain) : NULL; \ + h->domainW = NULL; \ + h->type = type; \ + h->index = 0; \ + h->next = NULL; \ + if (h_tail == NULL) \ + (gptr)->counter_list = h; \ + else \ + h_tail->next = h; \ + } \ +} + +#endif /* _ITTNOTIFY_CONFIG_H_ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_static.c b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_static.c new file mode 100644 index 00000000..05146973 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_static.c @@ -0,0 +1,1244 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ittnotify_config.h" + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define PATH_MAX 512 +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +#include <limits.h> +#include <dlfcn.h> +#include <errno.h> +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> + +#define INTEL_NO_MACRO_BODY +#define INTEL_ITTNOTIFY_API_PRIVATE +#include "ittnotify.h" +#include "legacy/ittnotify.h" + +#include "disable_warnings.h" + +static const char api_version[] = API_VERSION "\0\n@(#) $Revision$\n"; + +#define _N_(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) + +#if ITT_OS==ITT_OS_WIN +static const char* ittnotify_lib_name = "libittnotify.dll"; +#elif ITT_OS==ITT_OS_LINUX || ITT_OS==ITT_OS_FREEBSD +static const char* ittnotify_lib_name = "libittnotify.so"; +#elif ITT_OS==ITT_OS_MAC +static const char* ittnotify_lib_name = "libittnotify.dylib"; +#else +#error Unsupported or unknown OS. +#endif + +#ifdef __ANDROID__ +#include <android/log.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <linux/limits.h> + +#ifdef ITT_ANDROID_LOG + #define ITT_ANDROID_LOG_TAG "INTEL_VTUNE_USERAPI" + #define ITT_ANDROID_LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, ITT_ANDROID_LOG_TAG, __VA_ARGS__)) + #define ITT_ANDROID_LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, ITT_ANDROID_LOG_TAG, __VA_ARGS__)) + #define ITT_ANDROID_LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,ITT_ANDROID_LOG_TAG, __VA_ARGS__)) + #define ITT_ANDROID_LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG,ITT_ANDROID_LOG_TAG, __VA_ARGS__)) +#else + #define ITT_ANDROID_LOGI(...) + #define ITT_ANDROID_LOGW(...) + #define ITT_ANDROID_LOGE(...) + #define ITT_ANDROID_LOGD(...) +#endif + +/* default location of userapi collector on Android */ +#define ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(x) "/data/data/com.intel.vtune/perfrun/lib" \ + #x "/runtime/libittnotify.so" + +#if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM +#define ANDROID_ITTNOTIFY_DEFAULT_PATH ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(32) +#else +#define ANDROID_ITTNOTIFY_DEFAULT_PATH ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(64) +#endif + +#endif + + +#ifndef LIB_VAR_NAME +#if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM +#define LIB_VAR_NAME INTEL_LIBITTNOTIFY32 +#else +#define LIB_VAR_NAME INTEL_LIBITTNOTIFY64 +#endif +#endif /* LIB_VAR_NAME */ + +#define ITT_MUTEX_INIT_AND_LOCK(p) { \ + if (PTHREAD_SYMBOLS) \ + { \ + if (!p.mutex_initialized) \ + { \ + if (__itt_interlocked_increment(&p.atomic_counter) == 1) \ + { \ + __itt_mutex_init(&p.mutex); \ + p.mutex_initialized = 1; \ + } \ + else \ + while (!p.mutex_initialized) \ + __itt_thread_yield(); \ + } \ + __itt_mutex_lock(&p.mutex); \ + } \ +} + +const int _N_(err) = 0; + +typedef int (__itt_init_ittlib_t)(const char*, __itt_group_id); + +/* this define used to control initialization function name. */ +#ifndef __itt_init_ittlib_name +ITT_EXTERN_C int _N_(init_ittlib)(const char*, __itt_group_id); +static __itt_init_ittlib_t* __itt_init_ittlib_ptr = _N_(init_ittlib); +#define __itt_init_ittlib_name __itt_init_ittlib_ptr +#endif /* __itt_init_ittlib_name */ + +typedef void (__itt_fini_ittlib_t)(void); + +/* this define used to control finalization function name. */ +#ifndef __itt_fini_ittlib_name +ITT_EXTERN_C void _N_(fini_ittlib)(void); +static __itt_fini_ittlib_t* __itt_fini_ittlib_ptr = _N_(fini_ittlib); +#define __itt_fini_ittlib_name __itt_fini_ittlib_ptr +#endif /* __itt_fini_ittlib_name */ + +extern __itt_global _N_(_ittapi_global); + +/* building pointers to imported funcs */ +#undef ITT_STUBV +#undef ITT_STUB +#define ITT_STUB(api,type,name,args,params,ptr,group,format) \ +static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ +typedef type api ITT_JOIN(_N_(name),_t) args; \ +ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END \ +static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \ +{ \ + if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) \ + __itt_init_ittlib_name(NULL, __itt_group_all); \ + if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \ + return ITTNOTIFY_NAME(name) params; \ + else \ + return (type)0; \ +} + +#define ITT_STUBV(api,type,name,args,params,ptr,group,format) \ +static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ +typedef type api ITT_JOIN(_N_(name),_t) args; \ +ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END \ +static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \ +{ \ + if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) \ + __itt_init_ittlib_name(NULL, __itt_group_all); \ + if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \ + ITTNOTIFY_NAME(name) params; \ + else \ + return; \ +} + +#undef __ITT_INTERNAL_INIT +#include "ittnotify_static.h" + +#undef ITT_STUB +#undef ITT_STUBV +#define ITT_STUB(api,type,name,args,params,ptr,group,format) \ +static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ +typedef type api ITT_JOIN(_N_(name),_t) args; \ +ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END + +#define ITT_STUBV(api,type,name,args,params,ptr,group,format) \ +static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ +typedef type api ITT_JOIN(_N_(name),_t) args; \ +ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END + +#define __ITT_INTERNAL_INIT +#include "ittnotify_static.h" +#undef __ITT_INTERNAL_INIT + +ITT_GROUP_LIST(group_list); + +#pragma pack(push, 8) + +typedef struct ___itt_group_alias +{ + const char* env_var; + __itt_group_id groups; +} __itt_group_alias; + +static __itt_group_alias group_alias[] = { + { "KMP_FOR_TPROFILE", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_mark) }, + { "KMP_FOR_TCHECK", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_fsync | __itt_group_mark | __itt_group_suppress) }, + { NULL, (__itt_group_none) }, + { api_version, (__itt_group_none) } /* !!! Just to avoid unused code elimination !!! */ +}; + +#pragma pack(pop) + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#pragma warning(push) +#pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +static __itt_api_info api_list[] = { +/* Define functions with static implementation */ +#undef ITT_STUB +#undef ITT_STUBV +#define ITT_STUB(api,type,name,args,params,nameindll,group,format) { ITT_TO_STR(ITT_JOIN(__itt_,nameindll)), (void**)(void*)&ITTNOTIFY_NAME(name), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), (__itt_group_id)(group)}, +#define ITT_STUBV ITT_STUB +#define __ITT_INTERNAL_INIT +#include "ittnotify_static.h" +#undef __ITT_INTERNAL_INIT +/* Define functions without static implementation */ +#undef ITT_STUB +#undef ITT_STUBV +#define ITT_STUB(api,type,name,args,params,nameindll,group,format) {ITT_TO_STR(ITT_JOIN(__itt_,nameindll)), (void**)(void*)&ITTNOTIFY_NAME(name), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), NULL, (__itt_group_id)(group)}, +#define ITT_STUBV ITT_STUB +#include "ittnotify_static.h" + {NULL, NULL, NULL, NULL, __itt_group_none} +}; + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#pragma warning(pop) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +static const char dll_path[PATH_MAX] = { 0 }; + +/* static part descriptor which handles. all notification api attributes. */ +__itt_global _N_(_ittapi_global) = { + ITT_MAGIC, /* identification info */ + ITT_MAJOR, ITT_MINOR, API_VERSION_BUILD, /* version info */ + 0, /* api_initialized */ + 0, /* mutex_initialized */ + 0, /* atomic_counter */ + MUTEX_INITIALIZER, /* mutex */ + NULL, /* dynamic library handle */ + NULL, /* error_handler */ + (const char**)&dll_path, /* dll_path_ptr */ + (__itt_api_info*)&api_list, /* api_list_ptr */ + NULL, /* next __itt_global */ + NULL, /* thread_list */ + NULL, /* domain_list */ + NULL, /* string_list */ + __itt_collection_normal, /* collection state */ + NULL, /* counter_list */ + 0 /* ipt_collect_events */ +}; + +typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id); +typedef void (__itt_api_fini_t)(__itt_global*); + +/* ========================================================================= */ + +#ifdef ITT_NOTIFY_EXT_REPORT +ITT_EXTERN_C void _N_(error_handler)(__itt_error_code, va_list args); +#endif /* ITT_NOTIFY_EXT_REPORT */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#pragma warning(push) +#pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +static void __itt_report_error_impl(int code, ...) { + va_list args; + va_start(args, code); + if (_N_(_ittapi_global).error_handler != NULL) + { + __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; + handler((__itt_error_code)code, args); + } +#ifdef ITT_NOTIFY_EXT_REPORT + _N_(error_handler)(code, args); +#endif /* ITT_NOTIFY_EXT_REPORT */ + va_end(args); +} + +//va_start cannot take enum (__itt_error_code) on clang, so it is necessary to transform it to int +#define __itt_report_error(code, ...) \ + __itt_report_error_impl((int)code,__VA_ARGS__) + + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#pragma warning(pop) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name) +{ + __itt_domain *h_tail = NULL, *h = NULL; + + if (name == NULL) + { + return NULL; + } + + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { + if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))) + { + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(domain_createW)(name); + } + } + for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) + { + if (h->nameW != NULL && !wcscmp(h->nameW, name)) break; + } + if (h == NULL) + { + NEW_DOMAIN_W(&_N_(_ittapi_global),h,h_tail,name); + } + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return h; +} + +static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))(const char* name) +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))(const char* name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +{ + __itt_domain *h_tail = NULL, *h = NULL; + + if (name == NULL) + { + return NULL; + } + + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { +#if ITT_PLATFORM==ITT_PLATFORM_WIN + if (ITTNOTIFY_NAME(domain_createA) && ITTNOTIFY_NAME(domain_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))) + { + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(domain_createA)(name); + } +#else + if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))) + { + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(domain_create)(name); + } +#endif + } + for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) + { + if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break; + } + if (h == NULL) + { + NEW_DOMAIN_A(&_N_(_ittapi_global),h,h_tail,name); + } + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return h; +} + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))(const wchar_t* name) +{ + __itt_string_handle *h_tail = NULL, *h = NULL; + + if (name == NULL) + { + return NULL; + } + + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { + if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))) + { + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(string_handle_createW)(name); + } + } + for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) + { + if (h->strW != NULL && !wcscmp(h->strW, name)) break; + } + if (h == NULL) + { + NEW_STRING_HANDLE_W(&_N_(_ittapi_global),h,h_tail,name); + } + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return h; +} + +static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))(const char* name) +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))(const char* name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +{ + __itt_string_handle *h_tail = NULL, *h = NULL; + + if (name == NULL) + { + return NULL; + } + + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { +#if ITT_PLATFORM==ITT_PLATFORM_WIN + if (ITTNOTIFY_NAME(string_handle_createA) && ITTNOTIFY_NAME(string_handle_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))) + { + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(string_handle_createA)(name); + } +#else + if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))) + { + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(string_handle_create)(name); + } +#endif + } + for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) + { + if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) break; + } + if (h == NULL) + { + NEW_STRING_HANDLE_A(&_N_(_ittapi_global),h,h_tail,name); + } + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return h; +} + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))(const wchar_t *name, const wchar_t *domain) +{ + __itt_counter_info_t *h_tail = NULL, *h = NULL; + __itt_metadata_type type = __itt_metadata_u64; + + if (name == NULL) + { + return NULL; + } + + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { + if (ITTNOTIFY_NAME(counter_createW) && ITTNOTIFY_NAME(counter_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))) + { + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(counter_createW)(name, domain); + } + } + for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) + { + if (h->nameW != NULL && h->type == type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) || + (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break; + + } + if (h == NULL) + { + NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type); + } + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return (__itt_counter)h; +} + +static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))(const char *name, const char *domain) +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))(const char *name, const char *domain) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +{ + __itt_counter_info_t *h_tail = NULL, *h = NULL; + __itt_metadata_type type = __itt_metadata_u64; + + if (name == NULL) + { + return NULL; + } + + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { +#if ITT_PLATFORM==ITT_PLATFORM_WIN + if (ITTNOTIFY_NAME(counter_createA) && ITTNOTIFY_NAME(counter_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))) + { + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(counter_createA)(name, domain); + } +#else + if (ITTNOTIFY_NAME(counter_create) && ITTNOTIFY_NAME(counter_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))) + { + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(counter_create)(name, domain); + } +#endif + } + for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) + { + if (h->nameA != NULL && h->type == type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) || + (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break; + } + if (h == NULL) + { + NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type); + } + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return (__itt_counter)h; +} + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init))(const wchar_t *name, const wchar_t *domain, __itt_metadata_type type) +{ + __itt_counter_info_t *h_tail = NULL, *h = NULL; + + if (name == NULL) + { + return NULL; + } + + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { + if (ITTNOTIFY_NAME(counter_create_typedW) && ITTNOTIFY_NAME(counter_create_typedW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init))) + { + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(counter_create_typedW)(name, domain, type); + } + } + for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) + { + if (h->nameW != NULL && h->type == type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) || + (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break; + + } + if (h == NULL) + { + NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type); + } + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return (__itt_counter)h; +} + +static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))(const char *name, const char *domain, __itt_metadata_type type) +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))(const char *name, const char *domain, __itt_metadata_type type) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +{ + __itt_counter_info_t *h_tail = NULL, *h = NULL; + + if (name == NULL) + { + return NULL; + } + + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { +#if ITT_PLATFORM==ITT_PLATFORM_WIN + if (ITTNOTIFY_NAME(counter_create_typedA) && ITTNOTIFY_NAME(counter_create_typedA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))) + { + __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(counter_create_typedA)(name, domain, type); + } +#else + if (ITTNOTIFY_NAME(counter_create_typed) && ITTNOTIFY_NAME(counter_create_typed) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))) + { + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return ITTNOTIFY_NAME(counter_create_typed)(name, domain, type); + } +#endif + } + for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) + { + if (h->nameA != NULL && h->type == type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) || + (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break; + } + if (h == NULL) + { + NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type); + } + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + return (__itt_counter)h; +} + +/* -------------------------------------------------------------------------- */ + +static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void) +{ + if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) + { + __itt_init_ittlib_name(NULL, __itt_group_all); + } + if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))) + { + ITTNOTIFY_NAME(pause)(); + } + else + { + _N_(_ittapi_global).state = __itt_collection_paused; + } +} + +static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void) +{ + if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) + { + __itt_init_ittlib_name(NULL, __itt_group_all); + } + if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))) + { + ITTNOTIFY_NAME(resume)(); + } + else + { + _N_(_ittapi_global).state = __itt_collection_normal; + } +} + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name) +{ + if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) + { + __itt_init_ittlib_name(NULL, __itt_group_all); + } + if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))) + { + ITTNOTIFY_NAME(thread_set_nameW)(name); + } +} + +static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen) +{ + (void)namelen; + ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name); + return 0; +} + +static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(const char* name) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(const char* name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +{ + if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) + { + __itt_init_ittlib_name(NULL, __itt_group_all); + } +#if ITT_PLATFORM==ITT_PLATFORM_WIN + if (ITTNOTIFY_NAME(thread_set_nameA) && ITTNOTIFY_NAME(thread_set_nameA) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))) + { + ITTNOTIFY_NAME(thread_set_nameA)(name); + } +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + if (ITTNOTIFY_NAME(thread_set_name) && ITTNOTIFY_NAME(thread_set_name) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))) + { + ITTNOTIFY_NAME(thread_set_name)(name); + } +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +} + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setA),_init))(const char* name, int namelen) +{ + (void)namelen; + ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name); + return 0; +} +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_set),_init))(const char* name, int namelen) +{ + (void)namelen; + ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name); + return 0; +} +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void) +{ + if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) + { + __itt_init_ittlib_name(NULL, __itt_group_all); + } + if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))) + { + ITTNOTIFY_NAME(thread_ignore)(); + } +} + +static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void) +{ + ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(); +} + +static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void) +{ +#ifdef __ANDROID__ + /* + * if LIB_VAR_NAME env variable were set before then stay previous value + * else set default path + */ + setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0); +#endif +} + +/* -------------------------------------------------------------------------- */ + +static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len) +{ + int i; + int j; + + if (!s || !sep || !out || !len) + return NULL; + + for (i = 0; s[i]; i++) + { + int b = 0; + for (j = 0; sep[j]; j++) + if (s[i] == sep[j]) + { + b = 1; + break; + } + if (!b) + break; + } + + if (!s[i]) + return NULL; + + *len = 0; + *out = &s[i]; + + for (; s[i]; i++, (*len)++) + { + int b = 0; + for (j = 0; sep[j]; j++) + if (s[i] == sep[j]) + { + b = 1; + break; + } + if (b) + break; + } + + for (; s[i]; i++) + { + int b = 0; + for (j = 0; sep[j]; j++) + if (s[i] == sep[j]) + { + b = 1; + break; + } + if (!b) + break; + } + + return &s[i]; +} + +/* This function return value of env variable that placed into static buffer. + * !!! The same static buffer is used for subsequent calls. !!! + * This was done to avoid dynamic allocation for few calls. + * Actually we need this function only four times. + */ +static const char* __itt_get_env_var(const char* name) +{ +#define MAX_ENV_VALUE_SIZE 4086 + static char env_buff[MAX_ENV_VALUE_SIZE]; + static char* env_value = (char*)env_buff; + + if (name != NULL) + { +#if ITT_PLATFORM==ITT_PLATFORM_WIN + size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); + DWORD rc = GetEnvironmentVariableA(name, env_value, (DWORD)max_len); + if (rc >= max_len) + __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1)); + else if (rc > 0) + { + const char* ret = (const char*)env_value; + env_value += rc + 1; + return ret; + } + else + { + /* If environment variable is empty, GetEnvirornmentVariables() + * returns zero (number of characters (not including terminating null), + * and GetLastError() returns ERROR_SUCCESS. */ + DWORD err = GetLastError(); + if (err == ERROR_SUCCESS) + return env_value; + + if (err != ERROR_ENVVAR_NOT_FOUND) + __itt_report_error(__itt_error_cant_read_env, name, (int)err); + } +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ + char* env = getenv(name); + if (env != NULL) + { + size_t len = __itt_fstrnlen(env, MAX_ENV_VALUE_SIZE); + size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); + if (len < max_len) + { + const char* ret = (const char*)env_value; + __itt_fstrcpyn(env_value, max_len, env, len + 1); + env_value += len + 1; + return ret; + } else + __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1)); + } +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + } + return NULL; +} + +static const char* __itt_get_lib_name(void) +{ + const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); + +#ifdef __ANDROID__ + if (lib_name == NULL) + { + +#if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM + const char* const marker_filename = "com.intel.itt.collector_lib_32"; +#else + const char* const marker_filename = "com.intel.itt.collector_lib_64"; +#endif + + char system_wide_marker_filename[PATH_MAX] = {0}; + int itt_marker_file_fd = -1; + ssize_t res = 0; + + res = snprintf(system_wide_marker_filename, PATH_MAX - 1, "%s%s", "/data/local/tmp/", marker_filename); + if (res < 0) + { + ITT_ANDROID_LOGE("Unable to concatenate marker file string."); + return lib_name; + } + itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY); + + if (itt_marker_file_fd == -1) + { + const pid_t my_pid = getpid(); + char cmdline_path[PATH_MAX] = {0}; + char package_name[PATH_MAX] = {0}; + char app_sandbox_file[PATH_MAX] = {0}; + int cmdline_fd = 0; + + ITT_ANDROID_LOGI("Unable to open system-wide marker file."); + res = snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid); + if (res < 0) + { + ITT_ANDROID_LOGE("Unable to get cmdline path string."); + return lib_name; + } + + ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path); + cmdline_fd = open(cmdline_path, O_RDONLY); + if (cmdline_fd == -1) + { + ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path); + return lib_name; + } + res = read(cmdline_fd, package_name, PATH_MAX - 1); + if (res == -1) + { + ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path); + res = close(cmdline_fd); + if (res == -1) + { + ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); + } + return lib_name; + } + res = close(cmdline_fd); + if (res == -1) + { + ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); + return lib_name; + } + ITT_ANDROID_LOGI("Package name: %s\n", package_name); + res = snprintf(app_sandbox_file, PATH_MAX - 1, "/data/data/%s/%s", package_name, marker_filename); + if (res < 0) + { + ITT_ANDROID_LOGE("Unable to concatenate marker file string."); + return lib_name; + } + + ITT_ANDROID_LOGI("Lib marker file name: %s\n", app_sandbox_file); + itt_marker_file_fd = open(app_sandbox_file, O_RDONLY); + if (itt_marker_file_fd == -1) + { + ITT_ANDROID_LOGE("Unable to open app marker file!"); + return lib_name; + } + } + + { + char itt_lib_name[PATH_MAX] = {0}; + + res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1); + if (res == -1) + { + ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd); + res = close(itt_marker_file_fd); + if (res == -1) + { + ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); + } + return lib_name; + } + ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name); + res = close(itt_marker_file_fd); + if (res == -1) + { + ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); + return lib_name; + } + ITT_ANDROID_LOGI("Set env %s to %s", ITT_TO_STR(LIB_VAR_NAME), itt_lib_name); + res = setenv(ITT_TO_STR(LIB_VAR_NAME), itt_lib_name, 0); + if (res == -1) + { + ITT_ANDROID_LOGE("Unable to set env var!"); + return lib_name; + } + lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); + ITT_ANDROID_LOGI("ITT Lib path from env: %s", lib_name); + } + } +#endif + + return lib_name; +} + +/* Avoid clashes with std::min, reported by tbb team */ +#define __itt_min(a,b) ((a) < (b) ? (a) : (b)) + +static __itt_group_id __itt_get_groups(void) +{ + int i; + __itt_group_id res = __itt_group_none; + const char* var_name = "INTEL_ITTNOTIFY_GROUPS"; + const char* group_str = __itt_get_env_var(var_name); + + if (group_str != NULL) + { + int len; + char gr[255]; + const char* chunk; + while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL) + { + int min_len = __itt_min(len, (int)(sizeof(gr) - 1)); + __itt_fstrcpyn(gr, sizeof(gr) - 1, chunk, min_len); + gr[min_len] = 0; + + for (i = 0; group_list[i].name != NULL; i++) + { + if (!__itt_fstrcmp(gr, group_list[i].name)) + { + res = (__itt_group_id)(res | group_list[i].id); + break; + } + } + } + /* TODO: !!! Workaround for bug with warning for unknown group !!! + * Should be fixed in new initialization scheme. + * Now the following groups should be set always. */ + for (i = 0; group_list[i].id != __itt_group_none; i++) + if (group_list[i].id != __itt_group_all && + group_list[i].id > __itt_group_splitter_min && + group_list[i].id < __itt_group_splitter_max) + res = (__itt_group_id)(res | group_list[i].id); + return res; + } + else + { + for (i = 0; group_alias[i].env_var != NULL; i++) + if (__itt_get_env_var(group_alias[i].env_var) != NULL) + return group_alias[i].groups; + } + + return res; +} + +#undef __itt_min + +static int __itt_lib_version(lib_t lib) +{ + if (lib == NULL) + return 0; + if (__itt_get_proc(lib, "__itt_api_init")) + return 2; + if (__itt_get_proc(lib, "__itt_api_version")) + return 1; + return 0; +} + +/* It's not used right now! Comment it out to avoid warnings. +static void __itt_reinit_all_pointers(void) +{ + register int i; + // Fill all pointers with initial stubs + for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) + *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].init_func; +} +*/ + +static void __itt_nullify_all_pointers(void) +{ + int i; + /* Nulify all pointers except domain_create, string_handle_create and counter_create */ + for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) + *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; +} + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#pragma warning(push) +#pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ +#pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +ITT_EXTERN_C void _N_(fini_ittlib)(void) +{ + __itt_api_fini_t* __itt_api_fini_ptr = NULL; + static volatile TIDT current_thread = 0; + + if (_N_(_ittapi_global).api_initialized) + { + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); + if (_N_(_ittapi_global).api_initialized) + { + if (current_thread == 0) + { + if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id(); + if (_N_(_ittapi_global).lib != NULL) + { + __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini"); + } + if (__itt_api_fini_ptr) + { + __itt_api_fini_ptr(&_N_(_ittapi_global)); + } + + __itt_nullify_all_pointers(); + + /* TODO: !!! not safe !!! don't support unload so far. + * if (_N_(_ittapi_global).lib != NULL) + * __itt_unload_lib(_N_(_ittapi_global).lib); + * _N_(_ittapi_global).lib = NULL; + */ + _N_(_ittapi_global).api_initialized = 0; + current_thread = 0; + } + } + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); + } +} + +ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups) +{ + int i; + __itt_group_id groups; +#ifdef ITT_COMPLETE_GROUP + __itt_group_id zero_group = __itt_group_none; +#endif /* ITT_COMPLETE_GROUP */ + static volatile TIDT current_thread = 0; + + if (!_N_(_ittapi_global).api_initialized) + { +#ifndef ITT_SIMPLE_INIT + ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); +#endif /* ITT_SIMPLE_INIT */ + + if (!_N_(_ittapi_global).api_initialized) + { + if (current_thread == 0) + { + if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id(); + if (lib_name == NULL) + { + lib_name = __itt_get_lib_name(); + } + groups = __itt_get_groups(); + if (DL_SYMBOLS && (groups != __itt_group_none || lib_name != NULL)) + { + _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name); + + if (_N_(_ittapi_global).lib != NULL) + { + __itt_api_init_t* __itt_api_init_ptr; + int lib_version = __itt_lib_version(_N_(_ittapi_global).lib); + + switch (lib_version) { + case 0: + groups = __itt_group_legacy; + /* Falls through */ + case 1: + /* Fill all pointers from dynamic library */ + for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) + { + if (_N_(_ittapi_global).api_list_ptr[i].group & groups & init_groups) + { + *_N_(_ittapi_global).api_list_ptr[i].func_ptr = (void*)__itt_get_proc(_N_(_ittapi_global).lib, _N_(_ittapi_global).api_list_ptr[i].name); + if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr == NULL) + { + /* Restore pointers for function with static implementation */ + *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; + __itt_report_error(__itt_error_no_symbol, lib_name, _N_(_ittapi_global).api_list_ptr[i].name); +#ifdef ITT_COMPLETE_GROUP + zero_group = (__itt_group_id)(zero_group | _N_(_ittapi_global).api_list_ptr[i].group); +#endif /* ITT_COMPLETE_GROUP */ + } + } + else + *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; + } + + if (groups == __itt_group_legacy) + { + /* Compatibility with legacy tools */ + ITTNOTIFY_NAME(thread_ignore) = ITTNOTIFY_NAME(thr_ignore); +#if ITT_PLATFORM==ITT_PLATFORM_WIN + ITTNOTIFY_NAME(sync_createA) = ITTNOTIFY_NAME(sync_set_nameA); + ITTNOTIFY_NAME(sync_createW) = ITTNOTIFY_NAME(sync_set_nameW); +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ + ITTNOTIFY_NAME(sync_create) = ITTNOTIFY_NAME(sync_set_name); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + ITTNOTIFY_NAME(sync_prepare) = ITTNOTIFY_NAME(notify_sync_prepare); + ITTNOTIFY_NAME(sync_cancel) = ITTNOTIFY_NAME(notify_sync_cancel); + ITTNOTIFY_NAME(sync_acquired) = ITTNOTIFY_NAME(notify_sync_acquired); + ITTNOTIFY_NAME(sync_releasing) = ITTNOTIFY_NAME(notify_sync_releasing); + } + +#ifdef ITT_COMPLETE_GROUP + for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) + if (_N_(_ittapi_global).api_list_ptr[i].group & zero_group) + *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; +#endif /* ITT_COMPLETE_GROUP */ + break; + case 2: + __itt_api_init_ptr = (__itt_api_init_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_init"); + if (__itt_api_init_ptr) + __itt_api_init_ptr(&_N_(_ittapi_global), init_groups); + break; + } + } + else + { + __itt_nullify_all_pointers(); + +#if ITT_PLATFORM==ITT_PLATFORM_WIN + int error = __itt_system_error(); +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + const char* error = dlerror(); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + __itt_report_error(__itt_error_no_module, lib_name, error); + } + } + else + { + __itt_nullify_all_pointers(); + } + _N_(_ittapi_global).api_initialized = 1; + current_thread = 0; + /* !!! Just to avoid unused code elimination !!! */ + if (__itt_fini_ittlib_ptr == _N_(fini_ittlib)) current_thread = 0; + } + } + +#ifndef ITT_SIMPLE_INIT + if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); +#endif /* ITT_SIMPLE_INIT */ + } + + /* Evaluating if any function ptr is non empty and it's in init_groups */ + for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) + { + if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr != _N_(_ittapi_global).api_list_ptr[i].null_func && + _N_(_ittapi_global).api_list_ptr[i].group & init_groups) + { + return 1; + } + } + return 0; +} + +ITT_EXTERN_C __itt_error_handler_t* _N_(set_error_handler)(__itt_error_handler_t* handler) +{ + __itt_error_handler_t* prev = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; + _N_(_ittapi_global).error_handler = (void*)(size_t)handler; + return prev; +} + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#pragma warning(pop) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** __itt_mark_pt_region functions marks region of interest + * region parameter defines different regions. + * 0 <= region < 8 */ + +#if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__) +void __itt_pt_mark(__itt_pt_region region); +void __itt_pt_mark_event(__itt_pt_region region); +#endif + +ITT_EXTERN_C void _N_(mark_pt_region_begin)(__itt_pt_region region) +{ +#if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__) + if (_N_(_ittapi_global).ipt_collect_events == 1) + { + __itt_pt_mark_event(2*region); + } + else + { + __itt_pt_mark(2*region); + } +#else + (void)region; +#endif +} + +ITT_EXTERN_C void _N_(mark_pt_region_end)(__itt_pt_region region) +{ +#if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__) + if (_N_(_ittapi_global).ipt_collect_events == 1) + { + __itt_pt_mark_event(2*region + 1); + } + else + { + __itt_pt_mark(2*region + 1); + } +#else + (void)region; +#endif +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_static.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_static.h new file mode 100644 index 00000000..21ebf951 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_static.h @@ -0,0 +1,354 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ittnotify_config.h" + +#ifndef ITT_FORMAT_DEFINED +# ifndef ITT_FORMAT +# define ITT_FORMAT +# endif /* ITT_FORMAT */ +# ifndef ITT_NO_PARAMS +# define ITT_NO_PARAMS +# endif /* ITT_NO_PARAMS */ +#endif /* ITT_FORMAT_DEFINED */ + +/* + * parameters for macro expected: + * ITT_STUB(api, type, func_name, arguments, params, func_name_in_dll, group, printf_fmt) + */ +#ifdef __ITT_INTERNAL_INIT + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_domain*, domain_createA, (const char *name), (ITT_FORMAT name), domain_createA, __itt_group_structure, "\"%s\"") +ITT_STUB(ITTAPI, __itt_domain*, domain_createW, (const wchar_t *name), (ITT_FORMAT name), domain_createW, __itt_group_structure, "\"%S\"") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_domain*, domain_create, (const char *name), (ITT_FORMAT name), domain_create, __itt_group_structure, "\"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createA, (const char *name), (ITT_FORMAT name), string_handle_createA, __itt_group_structure, "\"%s\"") +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_createW, (const wchar_t *name), (ITT_FORMAT name), string_handle_createW, __itt_group_structure, "\"%S\"") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_string_handle*, string_handle_create, (const char *name), (ITT_FORMAT name), string_handle_create, __itt_group_structure, "\"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_counter, counter_createA, (const char *name, const char *domain), (ITT_FORMAT name, domain), counter_createA, __itt_group_counter, "\"%s\", \"%s\"") +ITT_STUB(ITTAPI, __itt_counter, counter_createW, (const wchar_t *name, const wchar_t *domain), (ITT_FORMAT name, domain), counter_createW, __itt_group_counter, "\"%s\", \"%s\"") +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_counter, counter_create, (const char *name, const char *domain), (ITT_FORMAT name, domain), counter_create, __itt_group_counter, "\"%s\", \"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_counter, counter_create_typedA, (const char *name, const char *domain, __itt_metadata_type type), (ITT_FORMAT name, domain, type), counter_create_typedA, __itt_group_counter, "\"%s\", \"%s\", %d") +ITT_STUB(ITTAPI, __itt_counter, counter_create_typedW, (const wchar_t *name, const wchar_t *domain, __itt_metadata_type type), (ITT_FORMAT name, domain, type), counter_create_typedW, __itt_group_counter, "\"%s\", \"%s\", %d") +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_counter, counter_create_typed, (const char *name, const char *domain, __itt_metadata_type type), (ITT_FORMAT name, domain, type), counter_create_typed, __itt_group_counter, "\"%s\", \"%s\", %d") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + + +ITT_STUBV(ITTAPI, void, pause, (void), (ITT_NO_PARAMS), pause, __itt_group_control | __itt_group_legacy, "no args") +ITT_STUBV(ITTAPI, void, resume, (void), (ITT_NO_PARAMS), resume, __itt_group_control | __itt_group_legacy, "no args") + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, thread_set_nameA, (const char *name), (ITT_FORMAT name), thread_set_nameA, __itt_group_thread, "\"%s\"") +ITT_STUBV(ITTAPI, void, thread_set_nameW, (const wchar_t *name), (ITT_FORMAT name), thread_set_nameW, __itt_group_thread, "\"%S\"") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, thread_set_name, (const char *name), (ITT_FORMAT name), thread_set_name, __itt_group_thread, "\"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, thread_ignore, (void), (ITT_NO_PARAMS), thread_ignore, __itt_group_thread, "no args") + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, int, thr_name_setA, (const char *name, int namelen), (ITT_FORMAT name, namelen), thr_name_setA, __itt_group_thread | __itt_group_legacy, "\"%s\", %d") +ITT_STUB(LIBITTAPI, int, thr_name_setW, (const wchar_t *name, int namelen), (ITT_FORMAT name, namelen), thr_name_setW, __itt_group_thread | __itt_group_legacy, "\"%S\", %d") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, int, thr_name_set, (const char *name, int namelen), (ITT_FORMAT name, namelen), thr_name_set, __itt_group_thread | __itt_group_legacy, "\"%s\", %d") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(LIBITTAPI, void, thr_ignore, (void), (ITT_NO_PARAMS), thr_ignore, __itt_group_thread | __itt_group_legacy, "no args") +#endif /* __ITT_INTERNAL_BODY */ + +ITT_STUBV(ITTAPI, void, enable_attach, (void), (ITT_NO_PARAMS), enable_attach, __itt_group_all, "no args") + +#else /* __ITT_INTERNAL_INIT */ + +ITT_STUBV(ITTAPI, void, detach, (void), (ITT_NO_PARAMS), detach, __itt_group_control | __itt_group_legacy, "no args") + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, sync_createA, (void *addr, const char *objtype, const char *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_createA, __itt_group_sync | __itt_group_fsync, "%p, \"%s\", \"%s\", %x") +ITT_STUBV(ITTAPI, void, sync_createW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_createW, __itt_group_sync | __itt_group_fsync, "%p, \"%S\", \"%S\", %x") +ITT_STUBV(ITTAPI, void, sync_renameA, (void *addr, const char *name), (ITT_FORMAT addr, name), sync_renameA, __itt_group_sync | __itt_group_fsync, "%p, \"%s\"") +ITT_STUBV(ITTAPI, void, sync_renameW, (void *addr, const wchar_t *name), (ITT_FORMAT addr, name), sync_renameW, __itt_group_sync | __itt_group_fsync, "%p, \"%S\"") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_create, (void *addr, const char *objtype, const char *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_create, __itt_group_sync | __itt_group_fsync, "%p, \"%s\", \"%s\", %x") +ITT_STUBV(ITTAPI, void, sync_rename, (void *addr, const char *name), (ITT_FORMAT addr, name), sync_rename, __itt_group_sync | __itt_group_fsync, "%p, \"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_destroy, (void *addr), (ITT_FORMAT addr), sync_destroy, __itt_group_sync | __itt_group_fsync, "%p") + +ITT_STUBV(ITTAPI, void, sync_prepare, (void* addr), (ITT_FORMAT addr), sync_prepare, __itt_group_sync, "%p") +ITT_STUBV(ITTAPI, void, sync_cancel, (void *addr), (ITT_FORMAT addr), sync_cancel, __itt_group_sync, "%p") +ITT_STUBV(ITTAPI, void, sync_acquired, (void *addr), (ITT_FORMAT addr), sync_acquired, __itt_group_sync, "%p") +ITT_STUBV(ITTAPI, void, sync_releasing, (void* addr), (ITT_FORMAT addr), sync_releasing, __itt_group_sync, "%p") + +ITT_STUBV(ITTAPI, void, suppress_push, (unsigned int mask), (ITT_FORMAT mask), suppress_push, __itt_group_suppress, "%p") +ITT_STUBV(ITTAPI, void, suppress_pop, (void), (ITT_NO_PARAMS), suppress_pop, __itt_group_suppress, "no args") +ITT_STUBV(ITTAPI, void, suppress_mark_range, (__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size),(ITT_FORMAT mode, mask, address, size), suppress_mark_range, __itt_group_suppress, "%d, %p, %p, %d") +ITT_STUBV(ITTAPI, void, suppress_clear_range,(__itt_suppress_mode_t mode, unsigned int mask, void * address, size_t size),(ITT_FORMAT mode, mask, address, size), suppress_clear_range,__itt_group_suppress, "%d, %p, %p, %d") + +ITT_STUBV(ITTAPI, void, fsync_prepare, (void* addr), (ITT_FORMAT addr), sync_prepare, __itt_group_fsync, "%p") +ITT_STUBV(ITTAPI, void, fsync_cancel, (void *addr), (ITT_FORMAT addr), sync_cancel, __itt_group_fsync, "%p") +ITT_STUBV(ITTAPI, void, fsync_acquired, (void *addr), (ITT_FORMAT addr), sync_acquired, __itt_group_fsync, "%p") +ITT_STUBV(ITTAPI, void, fsync_releasing, (void* addr), (ITT_FORMAT addr), sync_releasing, __itt_group_fsync, "%p") + +ITT_STUBV(ITTAPI, void, model_site_begin, (__itt_model_site *site, __itt_model_site_instance *instance, const char *name), (ITT_FORMAT site, instance, name), model_site_begin, __itt_group_model, "%p, %p, \"%s\"") +ITT_STUBV(ITTAPI, void, model_site_end, (__itt_model_site *site, __itt_model_site_instance *instance), (ITT_FORMAT site, instance), model_site_end, __itt_group_model, "%p, %p") +ITT_STUBV(ITTAPI, void, model_task_begin, (__itt_model_task *task, __itt_model_task_instance *instance, const char *name), (ITT_FORMAT task, instance, name), model_task_begin, __itt_group_model, "%p, %p, \"%s\"") +ITT_STUBV(ITTAPI, void, model_task_end, (__itt_model_task *task, __itt_model_task_instance *instance), (ITT_FORMAT task, instance), model_task_end, __itt_group_model, "%p, %p") +ITT_STUBV(ITTAPI, void, model_lock_acquire, (void *lock), (ITT_FORMAT lock), model_lock_acquire, __itt_group_model, "%p") +ITT_STUBV(ITTAPI, void, model_lock_release, (void *lock), (ITT_FORMAT lock), model_lock_release, __itt_group_model, "%p") +ITT_STUBV(ITTAPI, void, model_record_allocation, (void *addr, size_t size), (ITT_FORMAT addr, size), model_record_allocation, __itt_group_model, "%p, %d") +ITT_STUBV(ITTAPI, void, model_record_deallocation, (void *addr), (ITT_FORMAT addr), model_record_deallocation, __itt_group_model, "%p") +ITT_STUBV(ITTAPI, void, model_induction_uses, (void* addr, size_t size), (ITT_FORMAT addr, size), model_induction_uses, __itt_group_model, "%p, %d") +ITT_STUBV(ITTAPI, void, model_reduction_uses, (void* addr, size_t size), (ITT_FORMAT addr, size), model_reduction_uses, __itt_group_model, "%p, %d") +ITT_STUBV(ITTAPI, void, model_observe_uses, (void* addr, size_t size), (ITT_FORMAT addr, size), model_observe_uses, __itt_group_model, "%p, %d") +ITT_STUBV(ITTAPI, void, model_clear_uses, (void* addr), (ITT_FORMAT addr), model_clear_uses, __itt_group_model, "%p") + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, model_site_beginW, (const wchar_t *name), (ITT_FORMAT name), model_site_beginW, __itt_group_model, "\"%s\"") +ITT_STUBV(ITTAPI, void, model_task_beginW, (const wchar_t *name), (ITT_FORMAT name), model_task_beginW, __itt_group_model, "\"%s\"") +ITT_STUBV(ITTAPI, void, model_iteration_taskW, (const wchar_t *name), (ITT_FORMAT name), model_iteration_taskW, __itt_group_model, "\"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, model_site_beginA, (const char *name), (ITT_FORMAT name), model_site_beginA, __itt_group_model, "\"%s\"") +ITT_STUBV(ITTAPI, void, model_site_beginAL, (const char *name, size_t len), (ITT_FORMAT name, len), model_site_beginAL, __itt_group_model, "\"%s\", %d") +ITT_STUBV(ITTAPI, void, model_task_beginA, (const char *name), (ITT_FORMAT name), model_task_beginA, __itt_group_model, "\"%s\"") +ITT_STUBV(ITTAPI, void, model_task_beginAL, (const char *name, size_t len), (ITT_FORMAT name, len), model_task_beginAL, __itt_group_model, "\"%s\", %d") +ITT_STUBV(ITTAPI, void, model_iteration_taskA, (const char *name), (ITT_FORMAT name), model_iteration_taskA, __itt_group_model, "\"%s\"") +ITT_STUBV(ITTAPI, void, model_iteration_taskAL, (const char *name, size_t len), (ITT_FORMAT name, len), model_iteration_taskAL, __itt_group_model, "\"%s\", %d") +ITT_STUBV(ITTAPI, void, model_site_end_2, (void), (ITT_NO_PARAMS), model_site_end_2, __itt_group_model, "no args") +ITT_STUBV(ITTAPI, void, model_task_end_2, (void), (ITT_NO_PARAMS), model_task_end_2, __itt_group_model, "no args") +ITT_STUBV(ITTAPI, void, model_lock_acquire_2, (void *lock), (ITT_FORMAT lock), model_lock_acquire_2, __itt_group_model, "%p") +ITT_STUBV(ITTAPI, void, model_lock_release_2, (void *lock), (ITT_FORMAT lock), model_lock_release_2, __itt_group_model, "%p") +ITT_STUBV(ITTAPI, void, model_aggregate_task, (size_t count), (ITT_FORMAT count), model_aggregate_task, __itt_group_model, "%d") +ITT_STUBV(ITTAPI, void, model_disable_push, (__itt_model_disable x), (ITT_FORMAT x), model_disable_push, __itt_group_model, "%p") +ITT_STUBV(ITTAPI, void, model_disable_pop, (void), (ITT_NO_PARAMS), model_disable_pop, __itt_group_model, "no args") +#endif /* __ITT_INTERNAL_BODY */ + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createA, (const char *name, const char *domain), (ITT_FORMAT name, domain), heap_function_createA, __itt_group_heap, "\"%s\", \"%s\"") +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_createW, (const wchar_t *name, const wchar_t *domain), (ITT_FORMAT name, domain), heap_function_createW, __itt_group_heap, "\"%s\", \"%s\"") +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_heap_function, heap_function_create, (const char *name, const char *domain), (ITT_FORMAT name, domain), heap_function_create, __itt_group_heap, "\"%s\", \"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* __ITT_INTERNAL_BODY */ +ITT_STUBV(ITTAPI, void, heap_allocate_begin, (__itt_heap_function h, size_t size, int initialized), (ITT_FORMAT h, size, initialized), heap_allocate_begin, __itt_group_heap, "%p, %lu, %d") +ITT_STUBV(ITTAPI, void, heap_allocate_end, (__itt_heap_function h, void** addr, size_t size, int initialized), (ITT_FORMAT h, addr, size, initialized), heap_allocate_end, __itt_group_heap, "%p, %p, %lu, %d") +ITT_STUBV(ITTAPI, void, heap_free_begin, (__itt_heap_function h, void* addr), (ITT_FORMAT h, addr), heap_free_begin, __itt_group_heap, "%p, %p") +ITT_STUBV(ITTAPI, void, heap_free_end, (__itt_heap_function h, void* addr), (ITT_FORMAT h, addr), heap_free_end, __itt_group_heap, "%p, %p") +ITT_STUBV(ITTAPI, void, heap_reallocate_begin, (__itt_heap_function h, void* addr, size_t new_size, int initialized), (ITT_FORMAT h, addr, new_size, initialized), heap_reallocate_begin, __itt_group_heap, "%p, %p, %lu, %d") +ITT_STUBV(ITTAPI, void, heap_reallocate_end, (__itt_heap_function h, void* addr, void** new_addr, size_t new_size, int initialized), (ITT_FORMAT h, addr, new_addr, new_size, initialized), heap_reallocate_end, __itt_group_heap, "%p, %p, %p, %lu, %d") +ITT_STUBV(ITTAPI, void, heap_internal_access_begin, (void), (ITT_NO_PARAMS), heap_internal_access_begin, __itt_group_heap, "no args") +ITT_STUBV(ITTAPI, void, heap_internal_access_end, (void), (ITT_NO_PARAMS), heap_internal_access_end, __itt_group_heap, "no args") +ITT_STUBV(ITTAPI, void, heap_record_memory_growth_begin, (void), (ITT_NO_PARAMS), heap_record_memory_growth_begin, __itt_group_heap, "no args") +ITT_STUBV(ITTAPI, void, heap_record_memory_growth_end, (void), (ITT_NO_PARAMS), heap_record_memory_growth_end, __itt_group_heap, "no args") +ITT_STUBV(ITTAPI, void, heap_reset_detection, (unsigned int reset_mask), (ITT_FORMAT reset_mask), heap_reset_detection, __itt_group_heap, "%u") +ITT_STUBV(ITTAPI, void, heap_record, (unsigned int record_mask), (ITT_FORMAT record_mask), heap_record, __itt_group_heap, "%u") + +ITT_STUBV(ITTAPI, void, id_create, (const __itt_domain *domain, __itt_id id), (ITT_FORMAT domain, id), id_create, __itt_group_structure, "%p, %lu") +ITT_STUBV(ITTAPI, void, id_destroy, (const __itt_domain *domain, __itt_id id), (ITT_FORMAT domain, id), id_destroy, __itt_group_structure, "%p, %lu") + +ITT_STUB(ITTAPI, __itt_timestamp, get_timestamp, (void), (ITT_NO_PARAMS), get_timestamp, __itt_group_structure, "no args") + +ITT_STUBV(ITTAPI, void, region_begin, (const __itt_domain *domain, __itt_id id, __itt_id parent, __itt_string_handle *name), (ITT_FORMAT domain, id, parent, name), region_begin, __itt_group_structure, "%p, %lu, %lu, %p") +ITT_STUBV(ITTAPI, void, region_end, (const __itt_domain *domain, __itt_id id), (ITT_FORMAT domain, id), region_end, __itt_group_structure, "%p, %lu") + +#ifndef __ITT_INTERNAL_BODY +ITT_STUBV(ITTAPI, void, frame_begin_v3, (const __itt_domain *domain, __itt_id *id), (ITT_FORMAT domain, id), frame_begin_v3, __itt_group_structure, "%p, %p") +ITT_STUBV(ITTAPI, void, frame_end_v3, (const __itt_domain *domain, __itt_id *id), (ITT_FORMAT domain, id), frame_end_v3, __itt_group_structure, "%p, %p") +ITT_STUBV(ITTAPI, void, frame_submit_v3, (const __itt_domain *domain, __itt_id *id, __itt_timestamp begin, __itt_timestamp end), (ITT_FORMAT domain, id, begin, end), frame_submit_v3, __itt_group_structure, "%p, %p, %lu, %lu") +#endif /* __ITT_INTERNAL_BODY */ + +ITT_STUBV(ITTAPI, void, task_group, (const __itt_domain *domain, __itt_id id, __itt_id parent, __itt_string_handle *name), (ITT_FORMAT domain, id, parent, name), task_group, __itt_group_structure, "%p, %lu, %lu, %p") + +ITT_STUBV(ITTAPI, void, task_begin, (const __itt_domain *domain, __itt_id id, __itt_id parent, __itt_string_handle *name), (ITT_FORMAT domain, id, parent, name), task_begin, __itt_group_structure, "%p, %lu, %lu, %p") +ITT_STUBV(ITTAPI, void, task_begin_fn, (const __itt_domain *domain, __itt_id id, __itt_id parent, void* fn), (ITT_FORMAT domain, id, parent, fn), task_begin_fn, __itt_group_structure, "%p, %lu, %lu, %p") +ITT_STUBV(ITTAPI, void, task_end, (const __itt_domain *domain), (ITT_FORMAT domain), task_end, __itt_group_structure, "%p") + +ITT_STUBV(ITTAPI, void, counter_inc_v3, (const __itt_domain *domain, __itt_string_handle *name), (ITT_FORMAT domain, name), counter_inc_v3, __itt_group_structure, "%p, %p") +ITT_STUBV(ITTAPI, void, counter_inc_delta_v3, (const __itt_domain *domain, __itt_string_handle *name, unsigned long long value), (ITT_FORMAT domain, name, value), counter_inc_delta_v3, __itt_group_structure, "%p, %p, %lu") +ITT_STUBV(ITTAPI, void, counter_dec_v3, (const __itt_domain *domain, __itt_string_handle *name), (ITT_FORMAT domain, name), counter_dec_v3, __itt_group_structure, "%p, %p") +ITT_STUBV(ITTAPI, void, counter_dec_delta_v3, (const __itt_domain *domain, __itt_string_handle *name, unsigned long long value), (ITT_FORMAT domain, name, value), counter_dec_delta_v3, __itt_group_structure, "%p, %p, %lu") + +ITT_STUBV(ITTAPI, void, marker, (const __itt_domain *domain, __itt_id id, __itt_string_handle *name, __itt_scope scope), (ITT_FORMAT domain, id, name, scope), marker, __itt_group_structure, "%p, %lu, %p, %d") + +ITT_STUBV(ITTAPI, void, metadata_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data), (ITT_FORMAT domain, id, key, type, count, data), metadata_add, __itt_group_structure, "%p, %lu, %p, %d, %lu, %p") +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, metadata_str_addA, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char* data, size_t length), (ITT_FORMAT domain, id, key, data, length), metadata_str_addA, __itt_group_structure, "%p, %lu, %p, %p, %lu") +ITT_STUBV(ITTAPI, void, metadata_str_addW, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const wchar_t* data, size_t length), (ITT_FORMAT domain, id, key, data, length), metadata_str_addW, __itt_group_structure, "%p, %lu, %p, %p, %lu") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, metadata_str_add, (const __itt_domain *domain, __itt_id id, __itt_string_handle *key, const char* data, size_t length), (ITT_FORMAT domain, id, key, data, length), metadata_str_add, __itt_group_structure, "%p, %lu, %p, %p, %lu") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +ITT_STUBV(ITTAPI, void, relation_add_to_current, (const __itt_domain *domain, __itt_relation relation, __itt_id tail), (ITT_FORMAT domain, relation, tail), relation_add_to_current, __itt_group_structure, "%p, %lu, %p") +ITT_STUBV(ITTAPI, void, relation_add, (const __itt_domain *domain, __itt_id head, __itt_relation relation, __itt_id tail), (ITT_FORMAT domain, head, relation, tail), relation_add, __itt_group_structure, "%p, %p, %lu, %p") + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, __itt_event, event_createA, (const char *name, int namelen), (ITT_FORMAT name, namelen), event_createA, __itt_group_mark | __itt_group_legacy, "\"%s\", %d") +ITT_STUB(LIBITTAPI, __itt_event, event_createW, (const wchar_t *name, int namelen), (ITT_FORMAT name, namelen), event_createW, __itt_group_mark | __itt_group_legacy, "\"%S\", %d") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, __itt_event, event_create, (const char *name, int namelen), (ITT_FORMAT name, namelen), event_create, __itt_group_mark | __itt_group_legacy, "\"%s\", %d") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, int, event_start, (__itt_event event), (ITT_FORMAT event), event_start, __itt_group_mark | __itt_group_legacy, "%d") +ITT_STUB(LIBITTAPI, int, event_end, (__itt_event event), (ITT_FORMAT event), event_end, __itt_group_mark | __itt_group_legacy, "%d") +#endif /* __ITT_INTERNAL_BODY */ + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, sync_set_nameA, (void *addr, const char *objtype, const char *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_set_nameA, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%s\", \"%s\", %x") +ITT_STUBV(ITTAPI, void, sync_set_nameW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_set_nameW, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%S\", \"%S\", %x") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_set_name, (void *addr, const char *objtype, const char *objname, int attribute), (ITT_FORMAT addr, objtype, objname, attribute), sync_set_name, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "p, \"%s\", \"%s\", %x") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, int, notify_sync_nameA, (void *p, const char *objtype, int typelen, const char *objname, int namelen, int attribute), (ITT_FORMAT p, objtype, typelen, objname, namelen, attribute), notify_sync_nameA, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%s\", %d, \"%s\", %d, %x") +ITT_STUB(LIBITTAPI, int, notify_sync_nameW, (void *p, const wchar_t *objtype, int typelen, const wchar_t *objname, int namelen, int attribute), (ITT_FORMAT p, objtype, typelen, objname, namelen, attribute), notify_sync_nameW, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%S\", %d, \"%S\", %d, %x") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, int, notify_sync_name, (void *p, const char *objtype, int typelen, const char *objname, int namelen, int attribute), (ITT_FORMAT p, objtype, typelen, objname, namelen, attribute), notify_sync_name, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p, \"%s\", %d, \"%s\", %d, %x") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +ITT_STUBV(LIBITTAPI, void, notify_sync_prepare, (void *p), (ITT_FORMAT p), notify_sync_prepare, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p") +ITT_STUBV(LIBITTAPI, void, notify_sync_cancel, (void *p), (ITT_FORMAT p), notify_sync_cancel, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p") +ITT_STUBV(LIBITTAPI, void, notify_sync_acquired, (void *p), (ITT_FORMAT p), notify_sync_acquired, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p") +ITT_STUBV(LIBITTAPI, void, notify_sync_releasing, (void *p), (ITT_FORMAT p), notify_sync_releasing, __itt_group_sync | __itt_group_fsync | __itt_group_legacy, "%p") +#endif /* __ITT_INTERNAL_BODY */ + +ITT_STUBV(LIBITTAPI, void, memory_read, (void *addr, size_t size), (ITT_FORMAT addr, size), memory_read, __itt_group_legacy, "%p, %lu") +ITT_STUBV(LIBITTAPI, void, memory_write, (void *addr, size_t size), (ITT_FORMAT addr, size), memory_write, __itt_group_legacy, "%p, %lu") +ITT_STUBV(LIBITTAPI, void, memory_update, (void *addr, size_t size), (ITT_FORMAT addr, size), memory_update, __itt_group_legacy, "%p, %lu") + +ITT_STUB(LIBITTAPI, __itt_state_t, state_get, (void), (ITT_NO_PARAMS), state_get, __itt_group_legacy, "no args") +ITT_STUB(LIBITTAPI, __itt_state_t, state_set, (__itt_state_t s), (ITT_FORMAT s), state_set, __itt_group_legacy, "%d") +ITT_STUB(LIBITTAPI, __itt_obj_state_t, obj_mode_set, (__itt_obj_prop_t p, __itt_obj_state_t s), (ITT_FORMAT p, s), obj_mode_set, __itt_group_legacy, "%d, %d") +ITT_STUB(LIBITTAPI, __itt_thr_state_t, thr_mode_set, (__itt_thr_prop_t p, __itt_thr_state_t s), (ITT_FORMAT p, s), thr_mode_set, __itt_group_legacy, "%d, %d") + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_frame, frame_createA, (const char *domain), (ITT_FORMAT domain), frame_createA, __itt_group_frame, "\"%s\"") +ITT_STUB(ITTAPI, __itt_frame, frame_createW, (const wchar_t *domain), (ITT_FORMAT domain), frame_createW, __itt_group_frame, "\"%s\"") +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_frame, frame_create, (const char *domain), (ITT_FORMAT domain), frame_create, __itt_group_frame, "\"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_createA, (const char *name), (ITT_FORMAT name), pt_region_createA, __itt_group_structure, "\"%s\"") +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_createW, (const wchar_t *name), (ITT_FORMAT name), pt_region_createW, __itt_group_structure, "\"%S\"") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_pt_region, pt_region_create, (const char *name), (ITT_FORMAT name), pt_region_create, __itt_group_structure, "\"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* __ITT_INTERNAL_BODY */ +ITT_STUBV(ITTAPI, void, frame_begin, (__itt_frame frame), (ITT_FORMAT frame), frame_begin, __itt_group_frame, "%p") +ITT_STUBV(ITTAPI, void, frame_end, (__itt_frame frame), (ITT_FORMAT frame), frame_end, __itt_group_frame, "%p") + +ITT_STUBV(ITTAPI, void, counter_destroy, (__itt_counter id), (ITT_FORMAT id), counter_destroy, __itt_group_counter, "%p") +ITT_STUBV(ITTAPI, void, counter_inc, (__itt_counter id), (ITT_FORMAT id), counter_inc, __itt_group_counter, "%p") +ITT_STUBV(ITTAPI, void, counter_inc_delta, (__itt_counter id, unsigned long long value), (ITT_FORMAT id, value), counter_inc_delta, __itt_group_counter, "%p, %lu") +ITT_STUBV(ITTAPI, void, counter_dec, (__itt_counter id), (ITT_FORMAT id), counter_dec, __itt_group_counter, "%p") +ITT_STUBV(ITTAPI, void, counter_dec_delta, (__itt_counter id, unsigned long long value), (ITT_FORMAT id, value), counter_dec_delta, __itt_group_counter, "%p, %lu") +ITT_STUBV(ITTAPI, void, counter_set_value, (__itt_counter id, void *value_ptr), (ITT_FORMAT id, value_ptr), counter_set_value, __itt_group_counter, "%p, %p") +ITT_STUBV(ITTAPI, void, counter_set_value_ex, (__itt_counter id, __itt_clock_domain *clock_domain, unsigned long long timestamp, void *value_ptr), (ITT_FORMAT id, clock_domain, timestamp, value_ptr), counter_set_value_ex, __itt_group_counter, "%p, %p, %llu, %p") + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_mark_type, mark_createA, (const char *name), (ITT_FORMAT name), mark_createA, __itt_group_mark, "\"%s\"") +ITT_STUB(ITTAPI, __itt_mark_type, mark_createW, (const wchar_t *name), (ITT_FORMAT name), mark_createW, __itt_group_mark, "\"%S\"") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_mark_type, mark_create, (const char *name), (ITT_FORMAT name), mark_create, __itt_group_mark, "\"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* __ITT_INTERNAL_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, markA, (__itt_mark_type mt, const char *parameter), (ITT_FORMAT mt, parameter), markA, __itt_group_mark, "%d, \"%s\"") +ITT_STUB(ITTAPI, int, markW, (__itt_mark_type mt, const wchar_t *parameter), (ITT_FORMAT mt, parameter), markW, __itt_group_mark, "%d, \"%S\"") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, mark, (__itt_mark_type mt, const char *parameter), (ITT_FORMAT mt, parameter), mark, __itt_group_mark, "%d, \"%s\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, mark_off, (__itt_mark_type mt), (ITT_FORMAT mt), mark_off, __itt_group_mark, "%d") +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, mark_globalA, (__itt_mark_type mt, const char *parameter), (ITT_FORMAT mt, parameter), mark_globalA, __itt_group_mark, "%d, \"%s\"") +ITT_STUB(ITTAPI, int, mark_globalW, (__itt_mark_type mt, const wchar_t *parameter), (ITT_FORMAT mt, parameter), mark_globalW, __itt_group_mark, "%d, \"%S\"") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, mark_global, (__itt_mark_type mt, const char *parameter), (ITT_FORMAT mt, parameter), mark_global, __itt_group_mark, "%d, \"%S\"") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, mark_global_off, (__itt_mark_type mt), (ITT_FORMAT mt), mark_global_off, __itt_group_mark, "%d") + +#ifndef __ITT_INTERNAL_BODY +ITT_STUB(ITTAPI, __itt_caller, stack_caller_create, (void), (ITT_NO_PARAMS), stack_caller_create, __itt_group_stitch, "no args") +#endif /* __ITT_INTERNAL_BODY */ +ITT_STUBV(ITTAPI, void, stack_caller_destroy, (__itt_caller id), (ITT_FORMAT id), stack_caller_destroy, __itt_group_stitch, "%p") +ITT_STUBV(ITTAPI, void, stack_callee_enter, (__itt_caller id), (ITT_FORMAT id), stack_callee_enter, __itt_group_stitch, "%p") +ITT_STUBV(ITTAPI, void, stack_callee_leave, (__itt_caller id), (ITT_FORMAT id), stack_callee_leave, __itt_group_stitch, "%p") + +ITT_STUB(ITTAPI, __itt_clock_domain*, clock_domain_create, (__itt_get_clock_info_fn fn, void* fn_data), (ITT_FORMAT fn, fn_data), clock_domain_create, __itt_group_structure, "%p, %p") +ITT_STUBV(ITTAPI, void, clock_domain_reset, (void), (ITT_NO_PARAMS), clock_domain_reset, __itt_group_structure, "no args") +ITT_STUBV(ITTAPI, void, id_create_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id), (ITT_FORMAT domain, clock_domain, timestamp, id), id_create_ex, __itt_group_structure, "%p, %p, %lu, %lu") +ITT_STUBV(ITTAPI, void, id_destroy_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id), (ITT_FORMAT domain, clock_domain, timestamp, id), id_destroy_ex, __itt_group_structure, "%p, %p, %lu, %lu") +ITT_STUBV(ITTAPI, void, task_begin_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, __itt_string_handle *name), (ITT_FORMAT domain, clock_domain, timestamp, id, parentid, name), task_begin_ex, __itt_group_structure, "%p, %p, %lu, %lu, %lu, %p") +ITT_STUBV(ITTAPI, void, task_begin_fn_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, void* fn), (ITT_FORMAT domain, clock_domain, timestamp, id, parentid, fn), task_begin_fn_ex, __itt_group_structure, "%p, %p, %lu, %lu, %lu, %p") +ITT_STUBV(ITTAPI, void, task_end_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp), (ITT_FORMAT domain, clock_domain, timestamp), task_end_ex, __itt_group_structure, "%p, %p, %lu") +ITT_STUBV(ITTAPI, void, task_begin_overlapped, (const __itt_domain *domain, __itt_id id, __itt_id parent, __itt_string_handle *name), (ITT_FORMAT domain, id, parent, name), task_begin_overlapped, __itt_group_structure, "%p, %lu, %lu, %p") +ITT_STUBV(ITTAPI, void, task_begin_overlapped_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_id parentid, __itt_string_handle *name), (ITT_FORMAT domain, clock_domain, timestamp, id, parentid, name), task_begin_overlapped_ex, __itt_group_structure, "%p, %p, %lu, %lu, %lu, %p") +ITT_STUBV(ITTAPI, void, task_end_overlapped, (const __itt_domain *domain, __itt_id id), (ITT_FORMAT domain, id), task_end_overlapped, __itt_group_structure, "%p, %lu") +ITT_STUBV(ITTAPI, void, task_end_overlapped_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id), (ITT_FORMAT domain, clock_domain, timestamp, id), task_end_overlapped_ex, __itt_group_structure, "%p, %p, %lu, %lu") +ITT_STUBV(ITTAPI, void, marker_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id id, __itt_string_handle *name, __itt_scope scope), (ITT_FORMAT domain, clock_domain, timestamp, id, name, scope), marker_ex, __itt_group_structure, "%p, %p, %lu, %lu, %p, %d") +ITT_STUBV(ITTAPI, void, metadata_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data), (ITT_FORMAT domain, scope, key, type, count, data), metadata_add_with_scope, __itt_group_structure, "%p, %d, %p, %d, %lu, %p") +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeA, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length), (ITT_FORMAT domain, scope, key, data, length), metadata_str_add_with_scopeA, __itt_group_structure, "%p, %d, %p, %p, %lu") +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scopeW, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const wchar_t *data, size_t length), (ITT_FORMAT domain, scope, key, data, length), metadata_str_add_with_scopeW, __itt_group_structure, "%p, %d, %p, %p, %lu") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, metadata_str_add_with_scope, (const __itt_domain *domain, __itt_scope scope, __itt_string_handle *key, const char *data, size_t length), (ITT_FORMAT domain, scope, key, data, length), metadata_str_add_with_scope, __itt_group_structure, "%p, %d, %p, %p, %lu") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, relation_add_to_current_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_relation relation, __itt_id tail), (ITT_FORMAT domain, clock_domain, timestamp, relation, tail), relation_add_to_current_ex, __itt_group_structure, "%p, %p, %lu, %d, %lu") +ITT_STUBV(ITTAPI, void, relation_add_ex, (const __itt_domain *domain, __itt_clock_domain* clock_domain, unsigned long long timestamp, __itt_id head, __itt_relation relation, __itt_id tail), (ITT_FORMAT domain, clock_domain, timestamp, head, relation, tail), relation_add_ex, __itt_group_structure, "%p, %p, %lu, %lu, %d, %lu") +ITT_STUB(ITTAPI, __itt_track_group*, track_group_create, (__itt_string_handle* name, __itt_track_group_type track_group_type), (ITT_FORMAT name, track_group_type), track_group_create, __itt_group_structure, "%p, %d") +ITT_STUB(ITTAPI, __itt_track*, track_create, (__itt_track_group* track_group,__itt_string_handle* name, __itt_track_type track_type), (ITT_FORMAT track_group, name, track_type), track_create, __itt_group_structure, "%p, %p, %d") +ITT_STUBV(ITTAPI, void, set_track, (__itt_track *track), (ITT_FORMAT track), set_track, __itt_group_structure, "%p") + +#ifndef __ITT_INTERNAL_BODY +ITT_STUB(ITTAPI, const char*, api_version, (void), (ITT_NO_PARAMS), api_version, __itt_group_all & ~__itt_group_legacy, "no args") +#endif /* __ITT_INTERNAL_BODY */ + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, int, av_saveA, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder), (ITT_FORMAT data, rank, dimensions, type, filePath, columnOrder), av_saveA, __itt_group_arrays, "%p, %d, %p, %d, \"%s\", %d") +ITT_STUB(ITTAPI, int, av_saveW, (void *data, int rank, const int *dimensions, int type, const wchar_t *filePath, int columnOrder), (ITT_FORMAT data, rank, dimensions, type, filePath, columnOrder), av_saveW, __itt_group_arrays, "%p, %d, %p, %d, \"%S\", %d") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, int, av_save, (void *data, int rank, const int *dimensions, int type, const char *filePath, int columnOrder), (ITT_FORMAT data, rank, dimensions, type, filePath, columnOrder), av_save, __itt_group_arrays, "%p, %d, %p, %d, \"%s\", %d") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* __ITT_INTERNAL_BODY */ + +#ifndef __ITT_INTERNAL_BODY +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, module_loadA, (void *start_addr, void* end_addr, const char *path), (ITT_FORMAT start_addr, end_addr, path), module_loadA, __itt_group_none, "%p, %p, %p") +ITT_STUBV(ITTAPI, void, module_loadW, (void *start_addr, void* end_addr, const wchar_t *path), (ITT_FORMAT start_addr, end_addr, path), module_loadW, __itt_group_none, "%p, %p, %p") +#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, module_load, (void *start_addr, void *end_addr, const char *path), (ITT_FORMAT start_addr, end_addr, path), module_load, __itt_group_none, "%p, %p, %p") +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* __ITT_INTERNAL_BODY */ + + +#endif /* __ITT_INTERNAL_INIT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_types.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_types.h new file mode 100644 index 00000000..281f1ac2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/ittnotify_types.h @@ -0,0 +1,73 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _ITTNOTIFY_TYPES_H_ +#define _ITTNOTIFY_TYPES_H_ + +typedef enum ___itt_group_id +{ + __itt_group_none = 0, + __itt_group_legacy = 1<<0, + __itt_group_control = 1<<1, + __itt_group_thread = 1<<2, + __itt_group_mark = 1<<3, + __itt_group_sync = 1<<4, + __itt_group_fsync = 1<<5, + __itt_group_jit = 1<<6, + __itt_group_model = 1<<7, + __itt_group_splitter_min = 1<<7, + __itt_group_counter = 1<<8, + __itt_group_frame = 1<<9, + __itt_group_stitch = 1<<10, + __itt_group_heap = 1<<11, + __itt_group_splitter_max = 1<<12, + __itt_group_structure = 1<<12, + __itt_group_suppress = 1<<13, + __itt_group_arrays = 1<<14, + __itt_group_all = -1 +} __itt_group_id; + +#pragma pack(push, 8) + +typedef struct ___itt_group_list +{ + __itt_group_id id; + const char* name; +} __itt_group_list; + +#pragma pack(pop) + +#define ITT_GROUP_LIST(varname) \ + static __itt_group_list varname[] = { \ + { __itt_group_all, "all" }, \ + { __itt_group_control, "control" }, \ + { __itt_group_thread, "thread" }, \ + { __itt_group_mark, "mark" }, \ + { __itt_group_sync, "sync" }, \ + { __itt_group_fsync, "fsync" }, \ + { __itt_group_jit, "jit" }, \ + { __itt_group_model, "model" }, \ + { __itt_group_counter, "counter" }, \ + { __itt_group_frame, "frame" }, \ + { __itt_group_stitch, "stitch" }, \ + { __itt_group_heap, "heap" }, \ + { __itt_group_structure, "structure" }, \ + { __itt_group_suppress, "suppress" }, \ + { __itt_group_arrays, "arrays" }, \ + { __itt_group_none, NULL } \ + } + +#endif /* _ITTNOTIFY_TYPES_H_ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h new file mode 100644 index 00000000..5e9834a7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/tools_api/legacy/ittnotify.h @@ -0,0 +1,998 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _LEGACY_ITTNOTIFY_H_ +#define _LEGACY_ITTNOTIFY_H_ + +/** + * @file + * @brief Legacy User API functions and types + */ + +/** @cond exclude_from_documentation */ +#ifndef ITT_OS_WIN +# define ITT_OS_WIN 1 +#endif /* ITT_OS_WIN */ + +#ifndef ITT_OS_LINUX +# define ITT_OS_LINUX 2 +#endif /* ITT_OS_LINUX */ + +#ifndef ITT_OS_MAC +# define ITT_OS_MAC 3 +#endif /* ITT_OS_MAC */ + +#ifndef ITT_OS_FREEBSD +# define ITT_OS_FREEBSD 4 +#endif /* ITT_OS_FREEBSD */ + +#ifndef ITT_OS +# if defined WIN32 || defined _WIN32 +# define ITT_OS ITT_OS_WIN +# elif defined( __APPLE__ ) && defined( __MACH__ ) +# define ITT_OS ITT_OS_MAC +# elif defined( __FreeBSD__ ) +# define ITT_OS ITT_OS_FREEBSD +# else +# define ITT_OS ITT_OS_LINUX +# endif +#endif /* ITT_OS */ + +#ifndef ITT_PLATFORM_WIN +# define ITT_PLATFORM_WIN 1 +#endif /* ITT_PLATFORM_WIN */ + +#ifndef ITT_PLATFORM_POSIX +# define ITT_PLATFORM_POSIX 2 +#endif /* ITT_PLATFORM_POSIX */ + +#ifndef ITT_PLATFORM_MAC +# define ITT_PLATFORM_MAC 3 +#endif /* ITT_PLATFORM_MAC */ + +#ifndef ITT_PLATFORM_FREEBSD +# define ITT_PLATFORM_FREEBSD 4 +#endif /* ITT_PLATFORM_FREEBSD */ + +#ifndef ITT_PLATFORM +# if ITT_OS==ITT_OS_WIN +# define ITT_PLATFORM ITT_PLATFORM_WIN +# elif ITT_OS==ITT_OS_MAC +# define ITT_PLATFORM ITT_PLATFORM_MAC +# elif ITT_OS==ITT_OS_FREEBSD +# define ITT_PLATFORM ITT_PLATFORM_FREEBSD +# else +# define ITT_PLATFORM ITT_PLATFORM_POSIX +# endif +#endif /* ITT_PLATFORM */ + +#if defined(_UNICODE) && !defined(UNICODE) +#define UNICODE +#endif + +#include <stddef.h> +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#include <tchar.h> +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#include <stdint.h> +#if defined(UNICODE) || defined(_UNICODE) +#include <wchar.h> +#endif /* UNICODE || _UNICODE */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +#ifndef ITTAPI_CDECL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define ITTAPI_CDECL __cdecl +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define ITTAPI_CDECL __attribute__ ((cdecl)) +# else /* _M_IX86 || __i386__ */ +# define ITTAPI_CDECL /* actual only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* ITTAPI_CDECL */ + +#ifndef STDCALL +# if ITT_PLATFORM==ITT_PLATFORM_WIN +# define STDCALL __stdcall +# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +# if defined _M_IX86 || defined __i386__ +# define STDCALL __attribute__ ((stdcall)) +# else /* _M_IX86 || __i386__ */ +# define STDCALL /* supported only on x86 platform */ +# endif /* _M_IX86 || __i386__ */ +# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* STDCALL */ + +#define ITTAPI ITTAPI_CDECL +#define LIBITTAPI ITTAPI_CDECL + +/* TODO: Temporary for compatibility! */ +#define ITTAPI_CALL ITTAPI_CDECL +#define LIBITTAPI_CALL ITTAPI_CDECL + +#if ITT_PLATFORM==ITT_PLATFORM_WIN +/* use __forceinline (VC++ specific) */ +#define ITT_INLINE __forceinline +#define ITT_INLINE_ATTRIBUTE /* nothing */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/* + * Generally, functions are not inlined unless optimization is specified. + * For functions declared inline, this attribute inlines the function even + * if no optimization level was specified. + */ +#ifdef __STRICT_ANSI__ +#define ITT_INLINE static +#define ITT_INLINE_ATTRIBUTE __attribute__((unused)) +#else /* __STRICT_ANSI__ */ +#define ITT_INLINE static inline +#define ITT_INLINE_ATTRIBUTE __attribute__((always_inline, unused)) +#endif /* __STRICT_ANSI__ */ +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +/** @endcond */ + +/** @cond exclude_from_documentation */ +/* Helper macro for joining tokens */ +#define ITT_JOIN_AUX(p,n) p##n +#define ITT_JOIN(p,n) ITT_JOIN_AUX(p,n) + +#ifdef ITT_MAJOR +#undef ITT_MAJOR +#endif +#ifdef ITT_MINOR +#undef ITT_MINOR +#endif +#define ITT_MAJOR 3 +#define ITT_MINOR 0 + +/* Standard versioning of a token with major and minor version numbers */ +#define ITT_VERSIONIZE(x) \ + ITT_JOIN(x, \ + ITT_JOIN(_, \ + ITT_JOIN(ITT_MAJOR, \ + ITT_JOIN(_, ITT_MINOR)))) + +#ifndef INTEL_ITTNOTIFY_PREFIX +# define INTEL_ITTNOTIFY_PREFIX __itt_ +#endif /* INTEL_ITTNOTIFY_PREFIX */ +#ifndef INTEL_ITTNOTIFY_POSTFIX +# define INTEL_ITTNOTIFY_POSTFIX _ptr_ +#endif /* INTEL_ITTNOTIFY_POSTFIX */ + +#define ITTNOTIFY_NAME_AUX(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) +#define ITTNOTIFY_NAME(n) ITT_VERSIONIZE(ITTNOTIFY_NAME_AUX(ITT_JOIN(n,INTEL_ITTNOTIFY_POSTFIX))) + +#define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n) +#define ITTNOTIFY_DATA(n) (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n) + +#define ITTNOTIFY_VOID_D0(n,d) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d) +#define ITTNOTIFY_VOID_D1(n,d,x) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x) +#define ITTNOTIFY_VOID_D2(n,d,x,y) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y) +#define ITTNOTIFY_VOID_D3(n,d,x,y,z) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z) +#define ITTNOTIFY_VOID_D4(n,d,x,y,z,a) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) +#define ITTNOTIFY_VOID_D5(n,d,x,y,z,a,b) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) +#define ITTNOTIFY_VOID_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? (void)0 : (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) +#define ITTNOTIFY_DATA_D0(n,d) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d) +#define ITTNOTIFY_DATA_D1(n,d,x) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x) +#define ITTNOTIFY_DATA_D2(n,d,x,y) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y) +#define ITTNOTIFY_DATA_D3(n,d,x,y,z) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z) +#define ITTNOTIFY_DATA_D4(n,d,x,y,z,a) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a) +#define ITTNOTIFY_DATA_D5(n,d,x,y,z,a,b) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b) +#define ITTNOTIFY_DATA_D6(n,d,x,y,z,a,b,c) (!(d)->flags) ? 0 : (!ITTNOTIFY_NAME(n)) ? 0 : ITTNOTIFY_NAME(n)(d,x,y,z,a,b,c) + +#ifdef ITT_STUB +#undef ITT_STUB +#endif +#ifdef ITT_STUBV +#undef ITT_STUBV +#endif +#define ITT_STUBV(api,type,name,args) \ + typedef type (api* ITT_JOIN(ITTNOTIFY_NAME(name),_t)) args; \ + extern ITT_JOIN(ITTNOTIFY_NAME(name),_t) ITTNOTIFY_NAME(name); +#define ITT_STUB ITT_STUBV +/** @endcond */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup legacy Legacy API + * @{ + * @} + */ + +/** + * @defgroup legacy_control Collection Control + * @ingroup legacy + * General behavior: application continues to run, but no profiling information is being collected + * + * Pausing occurs not only for the current thread but for all process as well as spawned processes + * - Intel(R) Parallel Inspector and Intel(R) Inspector XE: + * - Does not analyze or report errors that involve memory access. + * - Other errors are reported as usual. Pausing data collection in + * Intel(R) Parallel Inspector and Intel(R) Inspector XE + * only pauses tracing and analyzing memory access. + * It does not pause tracing or analyzing threading APIs. + * . + * - Intel(R) Parallel Amplifier and Intel(R) VTune(TM) Amplifier XE: + * - Does continue to record when new threads are started. + * . + * - Other effects: + * - Possible reduction of runtime overhead. + * . + * @{ + */ +#ifndef _ITTNOTIFY_H_ +/** @brief Pause collection */ +void ITTAPI __itt_pause(void); +/** @brief Resume collection */ +void ITTAPI __itt_resume(void); +/** @brief Detach collection */ +void ITTAPI __itt_detach(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, pause, (void)) +ITT_STUBV(ITTAPI, void, resume, (void)) +ITT_STUBV(ITTAPI, void, detach, (void)) +#define __itt_pause ITTNOTIFY_VOID(pause) +#define __itt_pause_ptr ITTNOTIFY_NAME(pause) +#define __itt_resume ITTNOTIFY_VOID(resume) +#define __itt_resume_ptr ITTNOTIFY_NAME(resume) +#define __itt_detach ITTNOTIFY_VOID(detach) +#define __itt_detach_ptr ITTNOTIFY_NAME(detach) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_pause() +#define __itt_pause_ptr 0 +#define __itt_resume() +#define __itt_resume_ptr 0 +#define __itt_detach() +#define __itt_detach_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_pause_ptr 0 +#define __itt_resume_ptr 0 +#define __itt_detach_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +#endif /* _ITTNOTIFY_H_ */ +/** @} legacy_control group */ + +/** + * @defgroup legacy_threads Threads + * @ingroup legacy + * Threads group + * @warning Legacy API + * @{ + */ +/** + * @deprecated Legacy API + * @brief Set name to be associated with thread in analysis GUI. + * @return __itt_err upon failure (name or namelen being null,name and namelen mismatched) + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int LIBITTAPI __itt_thr_name_setA(const char *name, int namelen); +int LIBITTAPI __itt_thr_name_setW(const wchar_t *name, int namelen); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_thr_name_set __itt_thr_name_setW +# define __itt_thr_name_set_ptr __itt_thr_name_setW_ptr +#else +# define __itt_thr_name_set __itt_thr_name_setA +# define __itt_thr_name_set_ptr __itt_thr_name_setA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int LIBITTAPI __itt_thr_name_set(const char *name, int namelen); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, int, thr_name_setA, (const char *name, int namelen)) +ITT_STUB(LIBITTAPI, int, thr_name_setW, (const wchar_t *name, int namelen)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, int, thr_name_set, (const char *name, int namelen)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thr_name_setA ITTNOTIFY_DATA(thr_name_setA) +#define __itt_thr_name_setA_ptr ITTNOTIFY_NAME(thr_name_setA) +#define __itt_thr_name_setW ITTNOTIFY_DATA(thr_name_setW) +#define __itt_thr_name_setW_ptr ITTNOTIFY_NAME(thr_name_setW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thr_name_set ITTNOTIFY_DATA(thr_name_set) +#define __itt_thr_name_set_ptr ITTNOTIFY_NAME(thr_name_set) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thr_name_setA(name, namelen) +#define __itt_thr_name_setA_ptr 0 +#define __itt_thr_name_setW(name, namelen) +#define __itt_thr_name_setW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thr_name_set(name, namelen) +#define __itt_thr_name_set_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_thr_name_setA_ptr 0 +#define __itt_thr_name_setW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_thr_name_set_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Mark current thread as ignored from this point on, for the duration of its existence. + */ +void LIBITTAPI __itt_thr_ignore(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, thr_ignore, (void)) +#define __itt_thr_ignore ITTNOTIFY_VOID(thr_ignore) +#define __itt_thr_ignore_ptr ITTNOTIFY_NAME(thr_ignore) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_thr_ignore() +#define __itt_thr_ignore_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_thr_ignore_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_threads group */ + +/** + * @defgroup legacy_sync Synchronization + * @ingroup legacy + * Synchronization group + * @warning Legacy API + * @{ + */ +/** + * @hideinitializer + * @brief possible value of attribute argument for sync object type + */ +#define __itt_attr_barrier 1 + +/** + * @hideinitializer + * @brief possible value of attribute argument for sync object type + */ +#define __itt_attr_mutex 2 + +/** + * @deprecated Legacy API + * @brief Assign a name to a sync object using char or Unicode string + * @param[in] addr - pointer to the sync object. You should use a real pointer to your object + * to make sure that the values don't clash with other object addresses + * @param[in] objtype - null-terminated object type string. If NULL is passed, the object will + * be assumed to be of generic "User Synchronization" type + * @param[in] objname - null-terminated object name string. If NULL, no name will be assigned + * to the object -- you can use the __itt_sync_rename call later to assign + * the name + * @param[in] attribute - one of [#__itt_attr_barrier, #__itt_attr_mutex] values which defines the + * exact semantics of how prepare/acquired/releasing calls work. + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +void ITTAPI __itt_sync_set_nameA(void *addr, const char *objtype, const char *objname, int attribute); +void ITTAPI __itt_sync_set_nameW(void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_sync_set_name __itt_sync_set_nameW +# define __itt_sync_set_name_ptr __itt_sync_set_nameW_ptr +#else /* UNICODE */ +# define __itt_sync_set_name __itt_sync_set_nameA +# define __itt_sync_set_name_ptr __itt_sync_set_nameA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +void ITTAPI __itt_sync_set_name(void *addr, const char* objtype, const char* objname, int attribute); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUBV(ITTAPI, void, sync_set_nameA, (void *addr, const char *objtype, const char *objname, int attribute)) +ITT_STUBV(ITTAPI, void, sync_set_nameW, (void *addr, const wchar_t *objtype, const wchar_t *objname, int attribute)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUBV(ITTAPI, void, sync_set_name, (void *addr, const char *objtype, const char *objname, int attribute)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_set_nameA ITTNOTIFY_VOID(sync_set_nameA) +#define __itt_sync_set_nameA_ptr ITTNOTIFY_NAME(sync_set_nameA) +#define __itt_sync_set_nameW ITTNOTIFY_VOID(sync_set_nameW) +#define __itt_sync_set_nameW_ptr ITTNOTIFY_NAME(sync_set_nameW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_set_name ITTNOTIFY_VOID(sync_set_name) +#define __itt_sync_set_name_ptr ITTNOTIFY_NAME(sync_set_name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_set_nameA(addr, objtype, objname, attribute) +#define __itt_sync_set_nameA_ptr 0 +#define __itt_sync_set_nameW(addr, objtype, objname, attribute) +#define __itt_sync_set_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_set_name(addr, objtype, objname, attribute) +#define __itt_sync_set_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_sync_set_nameA_ptr 0 +#define __itt_sync_set_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_sync_set_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Assign a name and type to a sync object using char or Unicode string + * @param[in] addr - pointer to the sync object. You should use a real pointer to your object + * to make sure that the values don't clash with other object addresses + * @param[in] objtype - null-terminated object type string. If NULL is passed, the object will + * be assumed to be of generic "User Synchronization" type + * @param[in] objname - null-terminated object name string. If NULL, no name will be assigned + * to the object -- you can use the __itt_sync_rename call later to assign + * the name + * @param[in] typelen, namelen - a length of string for appropriate objtype and objname parameter + * @param[in] attribute - one of [#__itt_attr_barrier, #__itt_attr_mutex] values which defines the + * exact semantics of how prepare/acquired/releasing calls work. + * @return __itt_err upon failure (name or namelen being null,name and namelen mismatched) + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +int LIBITTAPI __itt_notify_sync_nameA(void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute); +int LIBITTAPI __itt_notify_sync_nameW(void *addr, const wchar_t *objtype, int typelen, const wchar_t *objname, int namelen, int attribute); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_notify_sync_name __itt_notify_sync_nameW +#else +# define __itt_notify_sync_name __itt_notify_sync_nameA +#endif +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +int LIBITTAPI __itt_notify_sync_name(void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, int, notify_sync_nameA, (void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute)) +ITT_STUB(LIBITTAPI, int, notify_sync_nameW, (void *addr, const wchar_t *objtype, int typelen, const wchar_t *objname, int namelen, int attribute)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, int, notify_sync_name, (void *addr, const char *objtype, int typelen, const char *objname, int namelen, int attribute)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_notify_sync_nameA ITTNOTIFY_DATA(notify_sync_nameA) +#define __itt_notify_sync_nameA_ptr ITTNOTIFY_NAME(notify_sync_nameA) +#define __itt_notify_sync_nameW ITTNOTIFY_DATA(notify_sync_nameW) +#define __itt_notify_sync_nameW_ptr ITTNOTIFY_NAME(notify_sync_nameW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_notify_sync_name ITTNOTIFY_DATA(notify_sync_name) +#define __itt_notify_sync_name_ptr ITTNOTIFY_NAME(notify_sync_name) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_notify_sync_nameA(addr, objtype, typelen, objname, namelen, attribute) +#define __itt_notify_sync_nameA_ptr 0 +#define __itt_notify_sync_nameW(addr, objtype, typelen, objname, namelen, attribute) +#define __itt_notify_sync_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_notify_sync_name(addr, objtype, typelen, objname, namelen, attribute) +#define __itt_notify_sync_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_notify_sync_nameA_ptr 0 +#define __itt_notify_sync_nameW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_notify_sync_name_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Enter spin loop on user-defined sync object + */ +void LIBITTAPI __itt_notify_sync_prepare(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, notify_sync_prepare, (void *addr)) +#define __itt_notify_sync_prepare ITTNOTIFY_VOID(notify_sync_prepare) +#define __itt_notify_sync_prepare_ptr ITTNOTIFY_NAME(notify_sync_prepare) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_notify_sync_prepare(addr) +#define __itt_notify_sync_prepare_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_notify_sync_prepare_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Quit spin loop without acquiring spin object + */ +void LIBITTAPI __itt_notify_sync_cancel(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, notify_sync_cancel, (void *addr)) +#define __itt_notify_sync_cancel ITTNOTIFY_VOID(notify_sync_cancel) +#define __itt_notify_sync_cancel_ptr ITTNOTIFY_NAME(notify_sync_cancel) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_notify_sync_cancel(addr) +#define __itt_notify_sync_cancel_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_notify_sync_cancel_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Successful spin loop completion (sync object acquired) + */ +void LIBITTAPI __itt_notify_sync_acquired(void *addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, notify_sync_acquired, (void *addr)) +#define __itt_notify_sync_acquired ITTNOTIFY_VOID(notify_sync_acquired) +#define __itt_notify_sync_acquired_ptr ITTNOTIFY_NAME(notify_sync_acquired) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_notify_sync_acquired(addr) +#define __itt_notify_sync_acquired_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_notify_sync_acquired_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Start sync object releasing code. Is called before the lock release call. + */ +void LIBITTAPI __itt_notify_sync_releasing(void* addr); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, notify_sync_releasing, (void *addr)) +#define __itt_notify_sync_releasing ITTNOTIFY_VOID(notify_sync_releasing) +#define __itt_notify_sync_releasing_ptr ITTNOTIFY_NAME(notify_sync_releasing) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_notify_sync_releasing(addr) +#define __itt_notify_sync_releasing_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_notify_sync_releasing_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_sync group */ + +#ifndef _ITTNOTIFY_H_ +/** + * @defgroup legacy_events Events + * @ingroup legacy + * Events group + * @{ + */ + +/** @brief user event type */ +typedef int __itt_event; + +/** + * @brief Create an event notification + * @note name or namelen being null/name and namelen not matching, user event feature not enabled + * @return non-zero event identifier upon success and __itt_err otherwise + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_event LIBITTAPI __itt_event_createA(const char *name, int namelen); +__itt_event LIBITTAPI __itt_event_createW(const wchar_t *name, int namelen); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_event_create __itt_event_createW +# define __itt_event_create_ptr __itt_event_createW_ptr +#else +# define __itt_event_create __itt_event_createA +# define __itt_event_create_ptr __itt_event_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_event LIBITTAPI __itt_event_create(const char *name, int namelen); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(LIBITTAPI, __itt_event, event_createA, (const char *name, int namelen)) +ITT_STUB(LIBITTAPI, __itt_event, event_createW, (const wchar_t *name, int namelen)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(LIBITTAPI, __itt_event, event_create, (const char *name, int namelen)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA ITTNOTIFY_DATA(event_createA) +#define __itt_event_createA_ptr ITTNOTIFY_NAME(event_createA) +#define __itt_event_createW ITTNOTIFY_DATA(event_createW) +#define __itt_event_createW_ptr ITTNOTIFY_NAME(event_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create ITTNOTIFY_DATA(event_create) +#define __itt_event_create_ptr ITTNOTIFY_NAME(event_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA(name, namelen) (__itt_event)0 +#define __itt_event_createA_ptr 0 +#define __itt_event_createW(name, namelen) (__itt_event)0 +#define __itt_event_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create(name, namelen) (__itt_event)0 +#define __itt_event_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_event_createA_ptr 0 +#define __itt_event_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_event_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an event occurrence. + * @return __itt_err upon failure (invalid event id/user event feature not enabled) + */ +int LIBITTAPI __itt_event_start(__itt_event event); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(LIBITTAPI, int, event_start, (__itt_event event)) +#define __itt_event_start ITTNOTIFY_DATA(event_start) +#define __itt_event_start_ptr ITTNOTIFY_NAME(event_start) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_event_start(event) (int)0 +#define __itt_event_start_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_event_start_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @brief Record an event end occurrence. + * @note It is optional if events do not have durations. + * @return __itt_err upon failure (invalid event id/user event feature not enabled) + */ +int LIBITTAPI __itt_event_end(__itt_event event); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(LIBITTAPI, int, event_end, (__itt_event event)) +#define __itt_event_end ITTNOTIFY_DATA(event_end) +#define __itt_event_end_ptr ITTNOTIFY_NAME(event_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_event_end(event) (int)0 +#define __itt_event_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_event_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_events group */ +#endif /* _ITTNOTIFY_H_ */ + +/** + * @defgroup legacy_memory Memory Accesses + * @ingroup legacy + */ + +/** + * @deprecated Legacy API + * @brief Inform the tool of memory accesses on reading + */ +void LIBITTAPI __itt_memory_read(void *addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, memory_read, (void *addr, size_t size)) +#define __itt_memory_read ITTNOTIFY_VOID(memory_read) +#define __itt_memory_read_ptr ITTNOTIFY_NAME(memory_read) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_memory_read(addr, size) +#define __itt_memory_read_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_memory_read_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Inform the tool of memory accesses on writing + */ +void LIBITTAPI __itt_memory_write(void *addr, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, memory_write, (void *addr, size_t size)) +#define __itt_memory_write ITTNOTIFY_VOID(memory_write) +#define __itt_memory_write_ptr ITTNOTIFY_NAME(memory_write) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_memory_write(addr, size) +#define __itt_memory_write_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_memory_write_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief Inform the tool of memory accesses on updating + */ +void LIBITTAPI __itt_memory_update(void *address, size_t size); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(LIBITTAPI, void, memory_update, (void *addr, size_t size)) +#define __itt_memory_update ITTNOTIFY_VOID(memory_update) +#define __itt_memory_update_ptr ITTNOTIFY_NAME(memory_update) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_memory_update(addr, size) +#define __itt_memory_update_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_memory_update_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_memory group */ + +/** + * @defgroup legacy_state Thread and Object States + * @ingroup legacy + */ + +/** @brief state type */ +typedef int __itt_state_t; + +/** @cond exclude_from_documentation */ +typedef enum __itt_obj_state { + __itt_obj_state_err = 0, + __itt_obj_state_clr = 1, + __itt_obj_state_set = 2, + __itt_obj_state_use = 3 +} __itt_obj_state_t; + +typedef enum __itt_thr_state { + __itt_thr_state_err = 0, + __itt_thr_state_clr = 1, + __itt_thr_state_set = 2 +} __itt_thr_state_t; + +typedef enum __itt_obj_prop { + __itt_obj_prop_watch = 1, + __itt_obj_prop_ignore = 2, + __itt_obj_prop_sharable = 3 +} __itt_obj_prop_t; + +typedef enum __itt_thr_prop { + __itt_thr_prop_quiet = 1 +} __itt_thr_prop_t; +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief managing thread and object states + */ +__itt_state_t LIBITTAPI __itt_state_get(void); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_state_t, state_get, (void)) +#define __itt_state_get ITTNOTIFY_DATA(state_get) +#define __itt_state_get_ptr ITTNOTIFY_NAME(state_get) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_state_get(void) (__itt_state_t)0 +#define __itt_state_get_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_state_get_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief managing thread and object states + */ +__itt_state_t LIBITTAPI __itt_state_set(__itt_state_t s); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_state_t, state_set, (__itt_state_t s)) +#define __itt_state_set ITTNOTIFY_DATA(state_set) +#define __itt_state_set_ptr ITTNOTIFY_NAME(state_set) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_state_set(s) (__itt_state_t)0 +#define __itt_state_set_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_state_set_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief managing thread and object modes + */ +__itt_thr_state_t LIBITTAPI __itt_thr_mode_set(__itt_thr_prop_t p, __itt_thr_state_t s); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_thr_state_t, thr_mode_set, (__itt_thr_prop_t p, __itt_thr_state_t s)) +#define __itt_thr_mode_set ITTNOTIFY_DATA(thr_mode_set) +#define __itt_thr_mode_set_ptr ITTNOTIFY_NAME(thr_mode_set) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_thr_mode_set(p, s) (__itt_thr_state_t)0 +#define __itt_thr_mode_set_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_thr_mode_set_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** + * @deprecated Legacy API + * @brief managing thread and object modes + */ +__itt_obj_state_t LIBITTAPI __itt_obj_mode_set(__itt_obj_prop_t p, __itt_obj_state_t s); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUB(ITTAPI, __itt_obj_state_t, obj_mode_set, (__itt_obj_prop_t p, __itt_obj_state_t s)) +#define __itt_obj_mode_set ITTNOTIFY_DATA(obj_mode_set) +#define __itt_obj_mode_set_ptr ITTNOTIFY_NAME(obj_mode_set) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_obj_mode_set(p, s) (__itt_obj_state_t)0 +#define __itt_obj_mode_set_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_obj_mode_set_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} legacy_state group */ + +/** + * @defgroup frames Frames + * @ingroup legacy + * Frames group + * @{ + */ +/** + * @brief opaque structure for frame identification + */ +typedef struct __itt_frame_t *__itt_frame; + +/** + * @brief Create a global frame with given domain + */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +__itt_frame ITTAPI __itt_frame_createA(const char *domain); +__itt_frame ITTAPI __itt_frame_createW(const wchar_t *domain); +#if defined(UNICODE) || defined(_UNICODE) +# define __itt_frame_create __itt_frame_createW +# define __itt_frame_create_ptr __itt_frame_createW_ptr +#else /* UNICODE */ +# define __itt_frame_create __itt_frame_createA +# define __itt_frame_create_ptr __itt_frame_createA_ptr +#endif /* UNICODE */ +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +__itt_frame ITTAPI __itt_frame_create(const char *domain); +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +#if ITT_PLATFORM==ITT_PLATFORM_WIN +ITT_STUB(ITTAPI, __itt_frame, frame_createA, (const char *domain)) +ITT_STUB(ITTAPI, __itt_frame, frame_createW, (const wchar_t *domain)) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +ITT_STUB(ITTAPI, __itt_frame, frame_create, (const char *domain)) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_frame_createA ITTNOTIFY_DATA(frame_createA) +#define __itt_frame_createA_ptr ITTNOTIFY_NAME(frame_createA) +#define __itt_frame_createW ITTNOTIFY_DATA(frame_createW) +#define __itt_frame_createW_ptr ITTNOTIFY_NAME(frame_createW) +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_frame_create ITTNOTIFY_DATA(frame_create) +#define __itt_frame_create_ptr ITTNOTIFY_NAME(frame_create) +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#else /* INTEL_NO_ITTNOTIFY_API */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_frame_createA(domain) +#define __itt_frame_createA_ptr 0 +#define __itt_frame_createW(domain) +#define __itt_frame_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_frame_create(domain) +#define __itt_frame_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#if ITT_PLATFORM==ITT_PLATFORM_WIN +#define __itt_frame_createA_ptr 0 +#define __itt_frame_createW_ptr 0 +#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#define __itt_frame_create_ptr 0 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ + +/** @brief Record an frame begin occurrence. */ +void ITTAPI __itt_frame_begin(__itt_frame frame); +/** @brief Record an frame end occurrence. */ +void ITTAPI __itt_frame_end (__itt_frame frame); + +/** @cond exclude_from_documentation */ +#ifndef INTEL_NO_MACRO_BODY +#ifndef INTEL_NO_ITTNOTIFY_API +ITT_STUBV(ITTAPI, void, frame_begin, (__itt_frame frame)) +ITT_STUBV(ITTAPI, void, frame_end, (__itt_frame frame)) +#define __itt_frame_begin ITTNOTIFY_VOID(frame_begin) +#define __itt_frame_begin_ptr ITTNOTIFY_NAME(frame_begin) +#define __itt_frame_end ITTNOTIFY_VOID(frame_end) +#define __itt_frame_end_ptr ITTNOTIFY_NAME(frame_end) +#else /* INTEL_NO_ITTNOTIFY_API */ +#define __itt_frame_begin(frame) +#define __itt_frame_begin_ptr 0 +#define __itt_frame_end(frame) +#define __itt_frame_end_ptr 0 +#endif /* INTEL_NO_ITTNOTIFY_API */ +#else /* INTEL_NO_MACRO_BODY */ +#define __itt_frame_begin_ptr 0 +#define __itt_frame_end_ptr 0 +#endif /* INTEL_NO_MACRO_BODY */ +/** @endcond */ +/** @} frames group */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _LEGACY_ITTNOTIFY_H_ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbb-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbb-export.def new file mode 100644 index 00000000..1941c886 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbb-export.def @@ -0,0 +1,24 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +EXPORTS + +#define __TBB_SYMBOL( sym ) sym +#if _M_ARM +#include "winrt-tbb-export.lst" +#else +#include "win32-tbb-export.lst" +#endif + + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbb-export.lst new file mode 100644 index 00000000..42d2a399 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbb-export.lst @@ -0,0 +1,350 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +#include "tbb/tbb_config.h" + +// Assembly-language support that is called directly by clients +// __TBB_SYMBOL( __TBB_machine_cmpswp1 ) +// __TBB_SYMBOL( __TBB_machine_cmpswp2 ) +// __TBB_SYMBOL( __TBB_machine_cmpswp4 ) +__TBB_SYMBOL( __TBB_machine_cmpswp8 ) +// __TBB_SYMBOL( __TBB_machine_fetchadd1 ) +// __TBB_SYMBOL( __TBB_machine_fetchadd2 ) +// __TBB_SYMBOL( __TBB_machine_fetchadd4 ) +__TBB_SYMBOL( __TBB_machine_fetchadd8 ) +// __TBB_SYMBOL( __TBB_machine_fetchstore1 ) +// __TBB_SYMBOL( __TBB_machine_fetchstore2 ) +// __TBB_SYMBOL( __TBB_machine_fetchstore4 ) +__TBB_SYMBOL( __TBB_machine_fetchstore8 ) +__TBB_SYMBOL( __TBB_machine_store8 ) +__TBB_SYMBOL( __TBB_machine_load8 ) +__TBB_SYMBOL( __TBB_machine_trylockbyte ) +__TBB_SYMBOL( __TBB_machine_try_lock_elided ) +__TBB_SYMBOL( __TBB_machine_unlock_elided ) +__TBB_SYMBOL( __TBB_machine_is_in_transaction ) + +// cache_aligned_allocator.cpp +__TBB_SYMBOL( ?NFS_Allocate@internal@tbb@@YAPAXIIPAX@Z ) +__TBB_SYMBOL( ?NFS_GetLineSize@internal@tbb@@YAIXZ ) +__TBB_SYMBOL( ?NFS_Free@internal@tbb@@YAXPAX@Z ) +__TBB_SYMBOL( ?allocate_via_handler_v3@internal@tbb@@YAPAXI@Z ) +__TBB_SYMBOL( ?deallocate_via_handler_v3@internal@tbb@@YAXPAX@Z ) +__TBB_SYMBOL( ?is_malloc_used_v3@internal@tbb@@YA_NXZ ) + +// task.cpp v3 +__TBB_SYMBOL( ?allocate@allocate_additional_child_of_proxy@internal@tbb@@QBEAAVtask@3@I@Z ) +__TBB_SYMBOL( ?allocate@allocate_child_proxy@internal@tbb@@QBEAAVtask@3@I@Z ) +__TBB_SYMBOL( ?allocate@allocate_continuation_proxy@internal@tbb@@QBEAAVtask@3@I@Z ) +__TBB_SYMBOL( ?allocate@allocate_root_proxy@internal@tbb@@SAAAVtask@3@I@Z ) +__TBB_SYMBOL( ?destroy@task_base@internal@interface5@tbb@@SAXAAVtask@4@@Z ) +__TBB_SYMBOL( ?free@allocate_additional_child_of_proxy@internal@tbb@@QBEXAAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_child_proxy@internal@tbb@@QBEXAAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_continuation_proxy@internal@tbb@@QBEXAAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_root_proxy@internal@tbb@@SAXAAVtask@3@@Z ) +__TBB_SYMBOL( ?internal_set_ref_count@task@tbb@@AAEXH@Z ) +__TBB_SYMBOL( ?internal_decrement_ref_count@task@tbb@@AAEHXZ ) +__TBB_SYMBOL( ?is_owned_by_current_thread@task@tbb@@QBE_NXZ ) +__TBB_SYMBOL( ?note_affinity@task@tbb@@UAEXG@Z ) +__TBB_SYMBOL( ?resize@affinity_partitioner_base_v3@internal@tbb@@AAEXI@Z ) +__TBB_SYMBOL( ?self@task@tbb@@SAAAV12@XZ ) +__TBB_SYMBOL( ?spawn_and_wait_for_all@task@tbb@@QAEXAAVtask_list@2@@Z ) +__TBB_SYMBOL( ?default_num_threads@task_scheduler_init@tbb@@SAHXZ ) +__TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QAEXHI@Z ) +__TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QAEXH@Z ) +__TBB_SYMBOL( ?terminate@task_scheduler_init@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?internal_blocking_terminate@task_scheduler_init@tbb@@AAE_N_N@Z ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( ?observe@task_scheduler_observer_v3@internal@tbb@@QAEX_N@Z ) +#endif /* __TBB_SCHEDULER_OBSERVER */ + +/* arena.cpp */ +__TBB_SYMBOL( ?internal_max_concurrency@task_arena_base@internal@interface7@tbb@@KAHPBVtask_arena@34@@Z ) +__TBB_SYMBOL( ?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ ) +__TBB_SYMBOL( ?internal_initialize@task_arena_base@internal@interface7@tbb@@IAEXXZ ) +__TBB_SYMBOL( ?internal_terminate@task_arena_base@internal@interface7@tbb@@IAEXXZ ) +__TBB_SYMBOL( ?internal_attach@task_arena_base@internal@interface7@tbb@@IAEXXZ ) +__TBB_SYMBOL( ?internal_enqueue@task_arena_base@internal@interface7@tbb@@IBEXAAVtask@4@H@Z ) +__TBB_SYMBOL( ?internal_execute@task_arena_base@internal@interface7@tbb@@IBEXAAVdelegate_base@234@@Z ) +__TBB_SYMBOL( ?internal_wait@task_arena_base@internal@interface7@tbb@@IBEXXZ ) +#if __TBB_NUMA_SUPPORT +__TBB_SYMBOL( ?nodes_count@numa_topology@internal@tbb@@YAIXZ ) +__TBB_SYMBOL( ?fill@numa_topology@internal@tbb@@YAXPAH@Z ) +__TBB_SYMBOL( ?default_concurrency@numa_topology@internal@tbb@@YAHH@Z ) +#endif /*__TBB_NUMA_SUPPORT*/ +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( ?isolate_within_arena@internal@interface7@tbb@@YAXAAVdelegate_base@123@H@Z ) +#endif /* __TBB_TASK_ISOLATION */ + +#if !TBB_NO_LEGACY +// task_v2.cpp +__TBB_SYMBOL( ?destroy@task@tbb@@QAEXAAV12@@Z ) +#endif + +// exception handling support +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( ?allocate@allocate_root_with_context_proxy@internal@tbb@@QBEAAVtask@3@I@Z ) +__TBB_SYMBOL( ?free@allocate_root_with_context_proxy@internal@tbb@@QBEXAAVtask@3@@Z ) +__TBB_SYMBOL( ?change_group@task@tbb@@QAEXAAVtask_group_context@2@@Z ) +__TBB_SYMBOL( ?is_group_execution_cancelled@task_group_context@tbb@@QBE_NXZ ) +__TBB_SYMBOL( ?cancel_group_execution@task_group_context@tbb@@QAE_NXZ ) +__TBB_SYMBOL( ?reset@task_group_context@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?capture_fp_settings@task_group_context@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?init@task_group_context@tbb@@IAEXXZ ) +__TBB_SYMBOL( ?register_pending_exception@task_group_context@tbb@@QAEXXZ ) +__TBB_SYMBOL( ??1task_group_context@tbb@@QAE@XZ ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( ?set_priority@task_group_context@tbb@@QAEXW4priority_t@2@@Z ) +__TBB_SYMBOL( ?priority@task_group_context@tbb@@QBE?AW4priority_t@2@XZ ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( ?name@captured_exception@tbb@@UBEPBDXZ ) +__TBB_SYMBOL( ?what@captured_exception@tbb@@UBEPBDXZ ) +__TBB_SYMBOL( ??1captured_exception@tbb@@UAE@XZ ) +__TBB_SYMBOL( ?move@captured_exception@tbb@@UAEPAV12@XZ ) +__TBB_SYMBOL( ?destroy@captured_exception@tbb@@UAEXXZ ) +__TBB_SYMBOL( ?set@captured_exception@tbb@@QAEXPBD0@Z ) +__TBB_SYMBOL( ?clear@captured_exception@tbb@@QAEXXZ ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +// Symbols for exceptions thrown from TBB +__TBB_SYMBOL( ?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ ) +__TBB_SYMBOL( ?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z ) +__TBB_SYMBOL( ?what@bad_last_alloc@tbb@@UBEPBDXZ ) +__TBB_SYMBOL( ?what@missing_wait@tbb@@UBEPBDXZ ) +__TBB_SYMBOL( ?what@invalid_multiple_scheduling@tbb@@UBEPBDXZ ) +__TBB_SYMBOL( ?what@improper_lock@tbb@@UBEPBDXZ ) +__TBB_SYMBOL( ?what@user_abort@tbb@@UBEPBDXZ ) + +// tbb_misc.cpp +__TBB_SYMBOL( ?assertion_failure@tbb@@YAXPBDH00@Z ) +__TBB_SYMBOL( ?get_initial_auto_partitioner_divisor@internal@tbb@@YAIXZ ) +__TBB_SYMBOL( ?handle_perror@internal@tbb@@YAXHPBD@Z ) +__TBB_SYMBOL( ?set_assertion_handler@tbb@@YAP6AXPBDH00@ZP6AX0H00@Z@Z ) +__TBB_SYMBOL( ?runtime_warning@internal@tbb@@YAXPBDZZ ) +__TBB_SYMBOL( TBB_runtime_interface_version ) + +// tbb_main.cpp +__TBB_SYMBOL( ?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPAXPBX@Z ) +__TBB_SYMBOL( ?itt_store_pointer_with_release_v3@internal@tbb@@YAXPAX0@Z ) +__TBB_SYMBOL( ?call_itt_notify_v5@internal@tbb@@YAXHPAX@Z ) +__TBB_SYMBOL( ?itt_set_sync_name_v3@internal@tbb@@YAXPAXPB_W@Z ) +__TBB_SYMBOL( ?itt_load_pointer_v3@internal@tbb@@YAPAXPBX@Z ) +__TBB_SYMBOL( ?itt_make_task_group_v7@internal@tbb@@YAXW4itt_domain_enum@12@PAX_K12W4string_index@12@@Z ) +__TBB_SYMBOL( ?itt_metadata_str_add_v7@internal@tbb@@YAXW4itt_domain_enum@12@PAX_KW4string_index@12@PBD@Z ) +__TBB_SYMBOL( ?itt_relation_add_v7@internal@tbb@@YAXW4itt_domain_enum@12@PAX_KW4itt_relation@12@12@Z ) +__TBB_SYMBOL( ?itt_task_begin_v7@internal@tbb@@YAXW4itt_domain_enum@12@PAX_K12W4string_index@12@@Z ) +__TBB_SYMBOL( ?itt_task_end_v7@internal@tbb@@YAXW4itt_domain_enum@12@@Z ) +__TBB_SYMBOL( ?itt_region_begin_v9@internal@tbb@@YAXW4itt_domain_enum@12@PAX_K12W4string_index@12@@Z ) +__TBB_SYMBOL( ?itt_region_end_v9@internal@tbb@@YAXW4itt_domain_enum@12@PAX_K@Z ) +__TBB_SYMBOL( ?itt_metadata_ptr_add_v11@internal@tbb@@YAXW4itt_domain_enum@12@PAX_KW4string_index@12@1@Z ) + +// pipeline.cpp +__TBB_SYMBOL( ??0pipeline@tbb@@QAE@XZ ) +__TBB_SYMBOL( ??1filter@tbb@@UAE@XZ ) +__TBB_SYMBOL( ??1pipeline@tbb@@UAE@XZ ) +__TBB_SYMBOL( ??_7pipeline@tbb@@6B@ ) +__TBB_SYMBOL( ?add_filter@pipeline@tbb@@QAEXAAVfilter@2@@Z ) +__TBB_SYMBOL( ?clear@pipeline@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?inject_token@pipeline@tbb@@AAEXAAVtask@2@@Z ) +__TBB_SYMBOL( ?run@pipeline@tbb@@QAEXI@Z ) +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( ?run@pipeline@tbb@@QAEXIAAVtask_group_context@2@@Z ) +#endif +__TBB_SYMBOL( ?process_item@thread_bound_filter@tbb@@QAE?AW4result_type@12@XZ ) +__TBB_SYMBOL( ?try_process_item@thread_bound_filter@tbb@@QAE?AW4result_type@12@XZ ) +__TBB_SYMBOL( ?set_end_of_input@filter@tbb@@IAEXXZ ) + +// queuing_rw_mutex.cpp +__TBB_SYMBOL( ?internal_construct@queuing_rw_mutex@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?acquire@scoped_lock@queuing_rw_mutex@tbb@@QAEXAAV23@_N@Z ) +__TBB_SYMBOL( ?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QAE_NXZ ) +__TBB_SYMBOL( ?release@scoped_lock@queuing_rw_mutex@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QAE_NXZ ) +__TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QAE_NAAV23@_N@Z ) + +// reader_writer_lock.cpp +__TBB_SYMBOL( ?try_lock_read@reader_writer_lock@interface5@tbb@@QAE_NXZ ) +__TBB_SYMBOL( ?try_lock@reader_writer_lock@interface5@tbb@@QAE_NXZ ) +__TBB_SYMBOL( ?unlock@reader_writer_lock@interface5@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?lock_read@reader_writer_lock@interface5@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?lock@reader_writer_lock@interface5@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?internal_construct@reader_writer_lock@interface5@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_destroy@reader_writer_lock@interface5@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_construct@scoped_lock@reader_writer_lock@interface5@tbb@@AAEXAAV234@@Z ) +__TBB_SYMBOL( ?internal_destroy@scoped_lock@reader_writer_lock@interface5@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_construct@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAEXAAV234@@Z ) +__TBB_SYMBOL( ?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAEXXZ ) + +#if !TBB_NO_LEGACY +// spin_rw_mutex.cpp v2 +__TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) +__TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) +__TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) +__TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) +#endif + +// spin_rw_mutex v3 +__TBB_SYMBOL( ?internal_construct@spin_rw_mutex_v3@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex_v3@tbb@@AAE_NXZ ) +__TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex_v3@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AAE_NXZ ) +__TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex_v3@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex_v3@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AAE_NXZ ) +__TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AAE_NXZ ) + +// x86_rtm_rw_mutex.cpp +__TBB_SYMBOL( ?internal_construct@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_release@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@@Z ) +__TBB_SYMBOL( ?internal_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@_N@Z ) +__TBB_SYMBOL( ?internal_acquire_reader@x86_rtm_rw_mutex@internal@interface8@tbb@@AAEXAAVscoped_lock@1234@_N@Z ) +__TBB_SYMBOL( ?internal_upgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z ) +__TBB_SYMBOL( ?internal_downgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z ) +__TBB_SYMBOL( ?internal_try_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AAE_NAAVscoped_lock@1234@@Z ) + +// spin_mutex.cpp +__TBB_SYMBOL( ?internal_construct@spin_mutex@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?internal_acquire@scoped_lock@spin_mutex@tbb@@AAEXAAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@spin_mutex@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AAE_NAAV23@@Z ) + +// mutex.cpp +__TBB_SYMBOL( ?internal_acquire@scoped_lock@mutex@tbb@@AAEXAAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@mutex@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@mutex@tbb@@AAE_NAAV23@@Z ) +__TBB_SYMBOL( ?internal_construct@mutex@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_destroy@mutex@tbb@@AAEXXZ ) + +// recursive_mutex.cpp +__TBB_SYMBOL( ?internal_acquire@scoped_lock@recursive_mutex@tbb@@AAEXAAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@recursive_mutex@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AAE_NAAV23@@Z ) +__TBB_SYMBOL( ?internal_construct@recursive_mutex@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_destroy@recursive_mutex@tbb@@AAEXXZ ) + +// queuing_mutex.cpp +__TBB_SYMBOL( ?internal_construct@queuing_mutex@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?acquire@scoped_lock@queuing_mutex@tbb@@QAEXAAV23@@Z ) +__TBB_SYMBOL( ?release@scoped_lock@queuing_mutex@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_mutex@tbb@@QAE_NAAV23@@Z ) + +// critical_section.cpp +__TBB_SYMBOL( ?internal_construct@critical_section_v4@internal@tbb@@QAEXXZ ) + +#if !TBB_NO_LEGACY +// concurrent_hash_map.cpp +__TBB_SYMBOL( ?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QBE_NXZ ) + +// concurrent_queue.cpp v2 +__TBB_SYMBOL( ?advance@concurrent_queue_iterator_base@internal@tbb@@IAEXXZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_iterator_base@internal@tbb@@IAEXABV123@@Z ) +__TBB_SYMBOL( ?internal_size@concurrent_queue_base@internal@tbb@@IBEHXZ ) +__TBB_SYMBOL( ??0concurrent_queue_base@internal@tbb@@IAE@I@Z ) +__TBB_SYMBOL( ??0concurrent_queue_iterator_base@internal@tbb@@IAE@ABVconcurrent_queue_base@12@@Z ) +__TBB_SYMBOL( ??1concurrent_queue_base@internal@tbb@@MAE@XZ ) +__TBB_SYMBOL( ??1concurrent_queue_iterator_base@internal@tbb@@IAE@XZ ) +__TBB_SYMBOL( ?internal_pop@concurrent_queue_base@internal@tbb@@IAEXPAX@Z ) +__TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IAE_NPAX@Z ) +__TBB_SYMBOL( ?internal_push@concurrent_queue_base@internal@tbb@@IAEXPBX@Z ) +__TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IAE_NPBX@Z ) +__TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base@internal@tbb@@IAEXHI@Z ) +#endif + +// concurrent_queue v3 +__TBB_SYMBOL( ??1concurrent_queue_iterator_base_v3@internal@tbb@@IAE@XZ ) +__TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAE@ABVconcurrent_queue_base_v3@12@@Z ) +__TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAE@ABVconcurrent_queue_base_v3@12@I@Z ) +__TBB_SYMBOL( ?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IAEXXZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IAEXABV123@@Z ) +__TBB_SYMBOL( ??0concurrent_queue_base_v3@internal@tbb@@IAE@I@Z ) +__TBB_SYMBOL( ??1concurrent_queue_base_v3@internal@tbb@@MAE@XZ ) +__TBB_SYMBOL( ?internal_pop@concurrent_queue_base_v3@internal@tbb@@IAEXPAX@Z ) +__TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IAE_NPAX@Z ) +__TBB_SYMBOL( ?internal_abort@concurrent_queue_base_v3@internal@tbb@@IAEXXZ ) +__TBB_SYMBOL( ?internal_push@concurrent_queue_base_v3@internal@tbb@@IAEXPBX@Z ) +__TBB_SYMBOL( ?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IAEXPBX@Z ) +__TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IAE_NPBX@Z ) +__TBB_SYMBOL( ?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IAE_NPBX@Z ) +__TBB_SYMBOL( ?internal_size@concurrent_queue_base_v3@internal@tbb@@IBEHXZ ) +__TBB_SYMBOL( ?internal_empty@concurrent_queue_base_v3@internal@tbb@@IBE_NXZ ) +__TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IAEXHI@Z ) +__TBB_SYMBOL( ?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IAEXXZ ) +__TBB_SYMBOL( ?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IBEXXZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_base_v3@internal@tbb@@IAEXABV123@@Z ) +__TBB_SYMBOL( ?move_content@concurrent_queue_base_v8@internal@tbb@@IAEXAAV123@@Z ) + +#if !TBB_NO_LEGACY +// concurrent_vector.cpp v2 +__TBB_SYMBOL( ?internal_assign@concurrent_vector_base@internal@tbb@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z ) +__TBB_SYMBOL( ?internal_capacity@concurrent_vector_base@internal@tbb@@IBEIXZ ) +__TBB_SYMBOL( ?internal_clear@concurrent_vector_base@internal@tbb@@IAEXP6AXPAXI@Z_N@Z ) +__TBB_SYMBOL( ?internal_copy@concurrent_vector_base@internal@tbb@@IAEXABV123@IP6AXPAXPBXI@Z@Z ) +__TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base@internal@tbb@@IAEIIIP6AXPAXI@Z@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IAEXIIP6AXPAXI@Z@Z ) +__TBB_SYMBOL( ?internal_push_back@concurrent_vector_base@internal@tbb@@IAEPAXIAAI@Z ) +__TBB_SYMBOL( ?internal_reserve@concurrent_vector_base@internal@tbb@@IAEXIII@Z ) +#endif + +// concurrent_vector v3 +__TBB_SYMBOL( ??1concurrent_vector_base_v3@internal@tbb@@IAE@XZ ) +__TBB_SYMBOL( ?internal_assign@concurrent_vector_base_v3@internal@tbb@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z ) +__TBB_SYMBOL( ?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IBEIXZ ) +__TBB_SYMBOL( ?internal_clear@concurrent_vector_base_v3@internal@tbb@@IAEIP6AXPAXI@Z@Z ) +__TBB_SYMBOL( ?internal_copy@concurrent_vector_base_v3@internal@tbb@@IAEXABV123@IP6AXPAXPBXI@Z@Z ) +__TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IAEIIIP6AXPAXPBXI@Z1@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IAEXIIP6AXPAXPBXI@Z1@Z ) +__TBB_SYMBOL( ?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IAEPAXIAAI@Z ) +__TBB_SYMBOL( ?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IAEXIII@Z ) +__TBB_SYMBOL( ?internal_compact@concurrent_vector_base_v3@internal@tbb@@IAEPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z ) +__TBB_SYMBOL( ?internal_swap@concurrent_vector_base_v3@internal@tbb@@IAEXAAV123@@Z ) +__TBB_SYMBOL( ?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IBEXI@Z ) +__TBB_SYMBOL( ?internal_resize@concurrent_vector_base_v3@internal@tbb@@IAEXIIIPBXP6AXPAXI@ZP6AX10I@Z@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least_with_result@concurrent_vector_base_v3@internal@tbb@@IAEIIIP6AXPAXPBXI@Z1@Z ) + +// tbb_thread +__TBB_SYMBOL( ?join@tbb_thread_v3@internal@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?detach@tbb_thread_v3@internal@tbb@@QAEXXZ ) +__TBB_SYMBOL( ?internal_start@tbb_thread_v3@internal@tbb@@AAEXP6GIPAX@Z0@Z ) +__TBB_SYMBOL( ?allocate_closure_v3@internal@tbb@@YAPAXI@Z ) +__TBB_SYMBOL( ?free_closure_v3@internal@tbb@@YAXPAX@Z ) +__TBB_SYMBOL( ?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ ) +__TBB_SYMBOL( ?thread_yield_v3@internal@tbb@@YAXXZ ) +__TBB_SYMBOL( ?thread_sleep_v3@internal@tbb@@YAXABVinterval_t@tick_count@2@@Z ) +__TBB_SYMBOL( ?move_v3@internal@tbb@@YAXAAVtbb_thread_v3@12@0@Z ) +__TBB_SYMBOL( ?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ ) + +// condition_variable +__TBB_SYMBOL( ?internal_initialize_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_wait@internal@interface5@tbb@@YA_NAATcondvar_impl_t@123@PAVmutex@3@PBVinterval_t@tick_count@3@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_notify_one@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_notify_all@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) + +// global parameter +__TBB_SYMBOL( ?active_value@global_control@interface9@tbb@@CAIH@Z ) +__TBB_SYMBOL( ?internal_create@global_control@interface9@tbb@@AAEXXZ ) +__TBB_SYMBOL( ?internal_destroy@global_control@interface9@tbb@@AAEXXZ ) + +#if __TBB_PREVIEW_RESUMABLE_TASKS +__TBB_SYMBOL( ?internal_suspend@internal@tbb@@YAXPAX0@Z ) +__TBB_SYMBOL( ?internal_resume@internal@tbb@@YAXPAX@Z ) +__TBB_SYMBOL( ?internal_current_suspend_point@internal@tbb@@YAPAXXZ ) +#endif + +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbbbind-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbbbind-export.def new file mode 100644 index 00000000..557c9056 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win32-tbbbind-export.def @@ -0,0 +1,22 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +EXPORTS + +global +initialize_numa_topology +bind_to_node +restore_affinity +allocate_binding_handler +deallocate_binding_handler diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-gcc-tbb-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-gcc-tbb-export.def new file mode 100644 index 00000000..4444ad88 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-gcc-tbb-export.def @@ -0,0 +1,40 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: + +#define __TBB_SYMBOL( sym ) sym; +#include "win64-gcc-tbb-export.lst" + +local: + +/* TBB symbols */ +*3tbb*; +*__TBB*; + +/* Intel Compiler (libirc) symbols */ +__intel_*; +_intel_*; +get_msg_buf; +get_text_buf; +message_catalog; +print_buf; +irc__get_msg; +irc__print; + +}; + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-gcc-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-gcc-tbb-export.lst new file mode 100644 index 00000000..0e98ff41 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-gcc-tbb-export.lst @@ -0,0 +1,399 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +/* cache_aligned_allocator.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal12NFS_AllocateEyyPv ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal15NFS_GetLineSizeEv ) +__TBB_SYMBOL( _ZN3tbb8internal8NFS_FreeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal23allocate_via_handler_v3Ey ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25deallocate_via_handler_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal17is_malloc_used_v3Ev ) + +/* task.cpp v3 */ +__TBB_SYMBOL( _ZN3tbb4task13note_affinityEt ) +__TBB_SYMBOL( _ZN3tbb4task22internal_set_ref_countEi ) +__TBB_SYMBOL( _ZN3tbb4task28internal_decrement_ref_countEv ) +__TBB_SYMBOL( _ZN3tbb4task22spawn_and_wait_for_allERNS_9task_listE ) +__TBB_SYMBOL( _ZN3tbb4task4selfEv ) +__TBB_SYMBOL( _ZN3tbb10interface58internal9task_base7destroyERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb4task26is_owned_by_current_threadEv ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8internal19allocate_root_proxy8allocateEy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal28affinity_partitioner_base_v36resizeEj ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal20allocate_child_proxy8allocateEy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal27allocate_continuation_proxy8allocateEy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZNK3tbb8internal34allocate_additional_child_of_proxy8allocateEy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZTIN3tbb4taskE ) +__TBB_SYMBOL( _ZTSN3tbb4taskE ) +__TBB_SYMBOL( _ZTVN3tbb4taskE ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init19default_num_threadsEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEiy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init10initializeEi ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init9terminateEv ) +__TBB_SYMBOL( _ZN3tbb19task_scheduler_init27internal_blocking_terminateEb ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( _ZN3tbb8internal26task_scheduler_observer_v37observeEb ) +#endif /* __TBB_SCHEDULER_OBSERVER */ +__TBB_SYMBOL( _ZN3tbb10empty_task7executeEv ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD0Ev ) +__TBB_SYMBOL( _ZN3tbb10empty_taskD1Ev ) +__TBB_SYMBOL( _ZTIN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTSN3tbb10empty_taskE ) +__TBB_SYMBOL( _ZTVN3tbb10empty_taskE ) + +/* arena.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base19internal_initializeEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base18internal_terminateEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base15internal_attachEv ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_enqueueERNS_4taskEx ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base16internal_executeERNS1_13delegate_baseE ) +__TBB_SYMBOL( _ZNK3tbb10interface78internal15task_arena_base13internal_waitEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base21internal_current_slotEv ) +__TBB_SYMBOL( _ZN3tbb10interface78internal15task_arena_base24internal_max_concurrencyEPKNS0_10task_arenaE ) +#if __TBB_NUMA_SUPPORT +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology11nodes_countEv ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology4fillEPi ) +__TBB_SYMBOL( _ZN3tbb8internal13numa_topology19default_concurrencyEi ) +#endif /*__TBB_NUMA_SUPPORT*/ +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEx ) +#endif /* __TBB_TASK_ISOLATION */ + +#if !TBB_NO_LEGACY +/* task_v2.cpp */ +__TBB_SYMBOL( _ZN3tbb4task7destroyERS0_ ) +#endif /* !TBB_NO_LEGACY */ + +/* Exception handling in task scheduler */ +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy8allocateEy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZNK3tbb8internal32allocate_root_with_context_proxy4freeERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb4task12change_groupERNS_18task_group_contextE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context28is_group_execution_cancelledEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context22cancel_group_executionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context26register_pending_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context5resetEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context19capture_fp_settingsEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_context4initEv ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD1Ev ) +__TBB_SYMBOL( _ZN3tbb18task_group_contextD2Ev ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( _ZN3tbb18task_group_context12set_priorityENS_10priority_tE ) +__TBB_SYMBOL( _ZNK3tbb18task_group_context8priorityEv ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( _ZNK3tbb18captured_exception4nameEv ) +__TBB_SYMBOL( _ZNK3tbb18captured_exception4whatEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception10throw_selfEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception3setEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exception4moveEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception5clearEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception7destroyEv ) +__TBB_SYMBOL( _ZN3tbb18captured_exception8allocateEPKcS2_ ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD0Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD1Ev ) +__TBB_SYMBOL( _ZN3tbb18captured_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb18captured_exceptionE ) +__TBB_SYMBOL( _ZN3tbb13tbb_exceptionD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTSN3tbb13tbb_exceptionE ) +__TBB_SYMBOL( _ZTVN3tbb13tbb_exceptionE ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +/* Symbols for exceptions thrown from TBB */ +__TBB_SYMBOL( _ZN3tbb8internal33throw_bad_last_alloc_exception_v4Ev ) +__TBB_SYMBOL( _ZN3tbb8internal18throw_exception_v4ENS0_12exception_idE ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD0Ev ) +__TBB_SYMBOL( _ZN3tbb14bad_last_allocD1Ev ) +__TBB_SYMBOL( _ZNK3tbb14bad_last_alloc4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTSN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZTVN3tbb14bad_last_allocE ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD0Ev ) +__TBB_SYMBOL( _ZN3tbb12missing_waitD1Ev ) +__TBB_SYMBOL( _ZNK3tbb12missing_wait4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTSN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZTVN3tbb12missing_waitE ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD0Ev ) +__TBB_SYMBOL( _ZN3tbb27invalid_multiple_schedulingD1Ev ) +__TBB_SYMBOL( _ZNK3tbb27invalid_multiple_scheduling4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTSN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZTVN3tbb27invalid_multiple_schedulingE ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD0Ev ) +__TBB_SYMBOL( _ZN3tbb13improper_lockD1Ev ) +__TBB_SYMBOL( _ZNK3tbb13improper_lock4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTSN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZTVN3tbb13improper_lockE ) +__TBB_SYMBOL( _ZN3tbb10user_abortD0Ev ) +__TBB_SYMBOL( _ZN3tbb10user_abortD1Ev ) +__TBB_SYMBOL( _ZNK3tbb10user_abort4whatEv ) +__TBB_SYMBOL( _ZTIN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTSN3tbb10user_abortE ) +__TBB_SYMBOL( _ZTVN3tbb10user_abortE ) + +/* tbb_misc.cpp */ +__TBB_SYMBOL( _ZN3tbb17assertion_failureEPKciS1_S1_ ) +__TBB_SYMBOL( _ZN3tbb21set_assertion_handlerEPFvPKciS1_S1_E ) +__TBB_SYMBOL( _ZN3tbb8internal36get_initial_auto_partitioner_divisorEv ) +__TBB_SYMBOL( _ZN3tbb8internal13handle_perrorEiPKc ) +__TBB_SYMBOL( _ZN3tbb8internal15runtime_warningEPKcz ) +__TBB_SYMBOL( TBB_runtime_interface_version ) + +/* tbb_main.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal32itt_load_pointer_with_acquire_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal33itt_store_pointer_with_release_v3EPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal18call_itt_notify_v5EiPv ) +__TBB_SYMBOL( _ZN3tbb8internal20itt_set_sync_name_v3EPvPKc ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_load_pointer_v3EPKv ) +__TBB_SYMBOL( _ZN3tbb8internal22itt_make_task_group_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal23itt_metadata_str_add_v7ENS0_15itt_domain_enumEPvyNS0_12string_indexEPKc ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_relation_add_v7ENS0_15itt_domain_enumEPvyNS0_12itt_relationES2_y ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_task_begin_v7ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal15itt_task_end_v7ENS0_15itt_domain_enumE ) +__TBB_SYMBOL( _ZN3tbb8internal19itt_region_begin_v9ENS0_15itt_domain_enumEPvyS2_yNS0_12string_indexE ) +__TBB_SYMBOL( _ZN3tbb8internal17itt_region_end_v9ENS0_15itt_domain_enumEPvy ) +__TBB_SYMBOL( _ZN3tbb8internal24itt_metadata_ptr_add_v11ENS0_15itt_domain_enumEPvyNS0_12string_indexES2_ ) + +/* pipeline.cpp */ +__TBB_SYMBOL( _ZTIN3tbb6filterE ) +__TBB_SYMBOL( _ZTSN3tbb6filterE ) +__TBB_SYMBOL( _ZTVN3tbb6filterE ) +__TBB_SYMBOL( _ZN3tbb6filterD2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipeline10add_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline12inject_tokenERNS_4taskE ) +__TBB_SYMBOL( _ZN3tbb8pipeline13remove_filterERNS_6filterE ) +__TBB_SYMBOL( _ZN3tbb8pipeline3runEy ) // MODIFIED LINUX ENTRY +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( _ZN3tbb8pipeline3runEyRNS_18task_group_contextE ) // MODIFIED LINUX ENTRY +#endif +__TBB_SYMBOL( _ZN3tbb8pipeline5clearEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter12process_itemEv ) +__TBB_SYMBOL( _ZN3tbb19thread_bound_filter16try_process_itemEv ) +__TBB_SYMBOL( _ZTIN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTSN3tbb8pipelineE ) +__TBB_SYMBOL( _ZTVN3tbb8pipelineE ) +__TBB_SYMBOL( _ZN3tbb8pipelineC1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineC2Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD0Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD1Ev ) +__TBB_SYMBOL( _ZN3tbb8pipelineD2Ev ) +__TBB_SYMBOL( _ZN3tbb6filter16set_end_of_inputEv ) + +/* queuing_rw_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock17upgrade_to_writerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock19downgrade_to_readerEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7acquireERS0_b ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb16queuing_rw_mutex11scoped_lock11try_acquireERS0_b ) + +/* reader_writer_lock.cpp */ +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock11scoped_lock18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock13try_lock_readEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16scoped_lock_read18internal_constructERS1_ ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock4lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock6unlockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock8try_lockEv ) +__TBB_SYMBOL( _ZN3tbb10interface518reader_writer_lock9lock_readEv ) + +#if !TBB_NO_LEGACY +/* spin_rw_mutex.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex16internal_upgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex22internal_itt_releasingEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_acquire_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex18internal_downgradeEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex23internal_release_writerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_readerEPS0_ ) +__TBB_SYMBOL( _ZN3tbb13spin_rw_mutex27internal_try_acquire_writerEPS0_ ) +#endif + +// x86_rtm_rw_mutex.cpp +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_writerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex27internal_try_acquire_writerERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex23internal_acquire_readerERNS2_11scoped_lockEb ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_releaseERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex16internal_upgradeERNS2_11scoped_lockE ) +__TBB_SYMBOL( _ZN3tbb10interface88internal16x86_rtm_rw_mutex18internal_downgradeERNS2_11scoped_lockE ) + +/* spin_rw_mutex v3 */ +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v316internal_upgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v318internal_downgradeEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_acquire_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v323internal_release_writerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_readerEv ) +__TBB_SYMBOL( _ZN3tbb16spin_rw_mutex_v327internal_try_acquire_writerEv ) + +/* spin_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb10spin_mutex18internal_constructEv ) + +/* mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb5mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb5mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb5mutex18internal_constructEv ) + +/* recursive_mutex.cpp */ +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock16internal_releaseEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex11scoped_lock20internal_try_acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex16internal_destroyEv ) +__TBB_SYMBOL( _ZN3tbb15recursive_mutex18internal_constructEv ) + +/* QueuingMutex.cpp */ +__TBB_SYMBOL( _ZN3tbb13queuing_mutex18internal_constructEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7acquireERS0_ ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock7releaseEv ) +__TBB_SYMBOL( _ZN3tbb13queuing_mutex11scoped_lock11try_acquireERS0_ ) + +/* critical_section.cpp */ +__TBB_SYMBOL( _ZN3tbb8internal19critical_section_v418internal_constructEv ) + +#if !TBB_NO_LEGACY +/* concurrent_hash_map */ +__TBB_SYMBOL( _ZNK3tbb8internal21hash_map_segment_base23internal_grow_predicateEv ) + +/* concurrent_queue.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base12internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base13internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base21internal_set_capacityExy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base23internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_base25internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseC2Ey ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal21concurrent_queue_baseD2Ev ) +__TBB_SYMBOL( _ZTIN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTSN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZTVN3tbb8internal21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base6assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_base7advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseC2ERKNS0_21concurrent_queue_baseE ) +__TBB_SYMBOL( _ZN3tbb8internal30concurrent_queue_iterator_baseD2Ev ) +__TBB_SYMBOL( _ZNK3tbb8internal21concurrent_queue_base13internal_sizeEv ) +#endif + +/* concurrent_queue v3 */ +/* constructors */ +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3C2Ey ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3C2ERKNS0_24concurrent_queue_base_v3Ey ) // MODIFIED LINUX ENTRY +/* destructors */ +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v3D2Ev ) +/* typeinfo */ +__TBB_SYMBOL( _ZTIN3tbb8internal24concurrent_queue_base_v3E ) +__TBB_SYMBOL( _ZTSN3tbb8internal24concurrent_queue_base_v3E ) +/* vtable */ +__TBB_SYMBOL( _ZTVN3tbb8internal24concurrent_queue_base_v3E ) +/* methods */ +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal33concurrent_queue_iterator_base_v37advanceEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v313internal_pushEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v818internal_push_moveEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v325internal_push_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v830internal_push_move_if_not_fullEPKv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v312internal_popEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v323internal_pop_if_presentEPv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v314internal_abortEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_finish_clearEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v321internal_set_capacityExy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v313internal_sizeEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v314internal_emptyEv ) +__TBB_SYMBOL( _ZNK3tbb8internal24concurrent_queue_base_v324internal_throw_exceptionEv ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v36assignERKS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal24concurrent_queue_base_v812move_contentERS1_ ) + + +#if !TBB_NO_LEGACY +/* concurrent_vector.cpp v2 */ +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base13internal_copyERKS1_yPFvPvPKvyE ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base14internal_clearEPFvPvyEb ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base15internal_assignERKS1_yPFvPvyEPFvS4_PKvyESA_ ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_grow_byEyyPFvPvyE ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base16internal_reserveEyyy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base18internal_push_backEyRy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal22concurrent_vector_base25internal_grow_to_at_leastEyyPFvPvyE ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZNK3tbb8internal22concurrent_vector_base17internal_capacityEv ) +#endif + +/* concurrent_vector v3 */ +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_copyERKS1_yPFvPvPKvyE ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v314internal_clearEPFvPvyE ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_assignERKS1_yPFvPvyEPFvS4_PKvyESA_ ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_grow_byEyyPFvPvPKvyES4_ ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_reserveEyyy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v318internal_push_backEyRy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v325internal_grow_to_at_leastEyyPFvPvPKvyES4_ ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v317internal_capacityEv ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v316internal_compactEyPvPFvS2_yEPFvS2_PKvyE ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v313internal_swapERS1_ ) +__TBB_SYMBOL( _ZNK3tbb8internal25concurrent_vector_base_v324internal_throw_exceptionEy ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v3D2Ev ) +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v315internal_resizeEyyyPKvPFvPvyEPFvS4_S3_yE ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal25concurrent_vector_base_v337internal_grow_to_at_least_with_resultEyyPFvPvPKvyES4_ ) // MODIFIED LINUX ENTRY + +/* tbb_thread */ +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v320hardware_concurrencyEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v36detachEv ) +__TBB_SYMBOL( _ZN3tbb8internal16thread_get_id_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal15free_closure_v3EPv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v34joinEv ) +__TBB_SYMBOL( _ZN3tbb8internal13tbb_thread_v314internal_startEPFjPvES2_ ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal19allocate_closure_v3Ey ) // MODIFIED LINUX ENTRY +__TBB_SYMBOL( _ZN3tbb8internal7move_v3ERNS0_13tbb_thread_v3ES2_ ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_yield_v3Ev ) +__TBB_SYMBOL( _ZN3tbb8internal15thread_sleep_v3ERKNS_10tick_count10interval_tE ) + +/* condition_variable */ +__TBB_SYMBOL( _ZN3tbb10interface58internal32internal_condition_variable_waitERNS1_14condvar_impl_tEPNS_5mutexEPKNS_10tick_count10interval_tE ) +__TBB_SYMBOL( _ZN3tbb10interface58internal35internal_destroy_condition_variableERNS1_14condvar_impl_tE ) +__TBB_SYMBOL( _ZN3tbb10interface58internal38internal_condition_variable_notify_allERNS1_14condvar_impl_tE ) +__TBB_SYMBOL( _ZN3tbb10interface58internal38internal_condition_variable_notify_oneERNS1_14condvar_impl_tE ) +__TBB_SYMBOL( _ZN3tbb10interface58internal38internal_initialize_condition_variableERNS1_14condvar_impl_tE ) + +// global parameter +__TBB_SYMBOL( _ZN3tbb10interface914global_control12active_valueEi ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control15internal_createEv ) +__TBB_SYMBOL( _ZN3tbb10interface914global_control16internal_destroyEv ) + +#if __TBB_PREVIEW_RESUMABLE_TASKS +__TBB_SYMBOL( _ZN3tbb8internal16internal_suspendEPvS1_ ) +__TBB_SYMBOL( _ZN3tbb8internal15internal_resumeEPv ) +__TBB_SYMBOL( _ZN3tbb8internal30internal_current_suspend_pointEv ) +#endif + +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbb-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbb-export.def new file mode 100644 index 00000000..ea7b3ea9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbb-export.def @@ -0,0 +1,22 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +; This file is organized with a section for each .cpp file. +; Each of these sections is in alphabetical order. + +EXPORTS + +#define __TBB_SYMBOL( sym ) sym +#include "win64-tbb-export.lst" + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbb-export.lst new file mode 100644 index 00000000..978651f7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbb-export.lst @@ -0,0 +1,345 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +// This file is organized with a section for each .cpp file. +// Each of these sections is in alphabetical order. + +#include "tbb/tbb_config.h" + +// Assembly-language support that is called directly by clients +__TBB_SYMBOL( __TBB_machine_cmpswp1 ) +__TBB_SYMBOL( __TBB_machine_fetchadd1 ) +__TBB_SYMBOL( __TBB_machine_fetchstore1 ) +__TBB_SYMBOL( __TBB_machine_cmpswp2 ) +__TBB_SYMBOL( __TBB_machine_fetchadd2 ) +__TBB_SYMBOL( __TBB_machine_fetchstore2 ) +__TBB_SYMBOL( __TBB_machine_pause ) +__TBB_SYMBOL( __TBB_machine_try_lock_elided ) +__TBB_SYMBOL( __TBB_machine_unlock_elided ) +__TBB_SYMBOL( __TBB_machine_is_in_transaction ) + +// cache_aligned_allocator.cpp +__TBB_SYMBOL( ?NFS_Allocate@internal@tbb@@YAPEAX_K0PEAX@Z ) +__TBB_SYMBOL( ?NFS_GetLineSize@internal@tbb@@YA_KXZ ) +__TBB_SYMBOL( ?NFS_Free@internal@tbb@@YAXPEAX@Z ) +__TBB_SYMBOL( ?allocate_via_handler_v3@internal@tbb@@YAPEAX_K@Z ) +__TBB_SYMBOL( ?deallocate_via_handler_v3@internal@tbb@@YAXPEAX@Z ) +__TBB_SYMBOL( ?is_malloc_used_v3@internal@tbb@@YA_NXZ ) + + +// task.cpp v3 +__TBB_SYMBOL( ?resize@affinity_partitioner_base_v3@internal@tbb@@AEAAXI@Z ) +__TBB_SYMBOL( ?allocate@allocate_additional_child_of_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z ) +__TBB_SYMBOL( ?allocate@allocate_child_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z ) +__TBB_SYMBOL( ?allocate@allocate_continuation_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z ) +__TBB_SYMBOL( ?allocate@allocate_root_proxy@internal@tbb@@SAAEAVtask@3@_K@Z ) +__TBB_SYMBOL( ?destroy@task_base@internal@interface5@tbb@@SAXAEAVtask@4@@Z ) +__TBB_SYMBOL( ?free@allocate_additional_child_of_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_child_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_continuation_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_root_proxy@internal@tbb@@SAXAEAVtask@3@@Z ) +__TBB_SYMBOL( ?internal_set_ref_count@task@tbb@@AEAAXH@Z ) +__TBB_SYMBOL( ?internal_decrement_ref_count@task@tbb@@AEAA_JXZ ) +__TBB_SYMBOL( ?is_owned_by_current_thread@task@tbb@@QEBA_NXZ ) +__TBB_SYMBOL( ?note_affinity@task@tbb@@UEAAXG@Z ) +__TBB_SYMBOL( ?self@task@tbb@@SAAEAV12@XZ ) +__TBB_SYMBOL( ?spawn_and_wait_for_all@task@tbb@@QEAAXAEAVtask_list@2@@Z ) +__TBB_SYMBOL( ?default_num_threads@task_scheduler_init@tbb@@SAHXZ ) +__TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QEAAXH_K@Z ) +__TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QEAAXH@Z ) +__TBB_SYMBOL( ?terminate@task_scheduler_init@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?internal_blocking_terminate@task_scheduler_init@tbb@@AEAA_N_N@Z ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( ?observe@task_scheduler_observer_v3@internal@tbb@@QEAAX_N@Z ) +#endif /* __TBB_SCHEDULER_OBSERVER */ + +/* arena.cpp */ +__TBB_SYMBOL( ?internal_max_concurrency@task_arena_base@internal@interface7@tbb@@KAHPEBVtask_arena@34@@Z ) +__TBB_SYMBOL( ?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ ) +__TBB_SYMBOL( ?internal_initialize@task_arena_base@internal@interface7@tbb@@IEAAXXZ ) +__TBB_SYMBOL( ?internal_terminate@task_arena_base@internal@interface7@tbb@@IEAAXXZ ) +__TBB_SYMBOL( ?internal_attach@task_arena_base@internal@interface7@tbb@@IEAAXXZ ) +__TBB_SYMBOL( ?internal_enqueue@task_arena_base@internal@interface7@tbb@@IEBAXAEAVtask@4@_J@Z ) +__TBB_SYMBOL( ?internal_execute@task_arena_base@internal@interface7@tbb@@IEBAXAEAVdelegate_base@234@@Z ) +__TBB_SYMBOL( ?internal_wait@task_arena_base@internal@interface7@tbb@@IEBAXXZ ) +#if __TBB_NUMA_SUPPORT +__TBB_SYMBOL( ?nodes_count@numa_topology@internal@tbb@@YAIXZ ) +__TBB_SYMBOL( ?fill@numa_topology@internal@tbb@@YAXPEAH@Z ) +__TBB_SYMBOL( ?default_concurrency@numa_topology@internal@tbb@@YAHH@Z ) +#endif /*__TBB_NUMA_SUPPORT*/ +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( ?isolate_within_arena@internal@interface7@tbb@@YAXAEAVdelegate_base@123@_J@Z ) +#endif /* __TBB_TASK_ISOLATION */ +#if !TBB_NO_LEGACY +// task_v2.cpp +__TBB_SYMBOL( ?destroy@task@tbb@@QEAAXAEAV12@@Z ) +#endif + +// Exception handling in task scheduler +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( ?allocate@allocate_root_with_context_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z ) +__TBB_SYMBOL( ?free@allocate_root_with_context_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z ) +__TBB_SYMBOL( ?change_group@task@tbb@@QEAAXAEAVtask_group_context@2@@Z ) +__TBB_SYMBOL( ?is_group_execution_cancelled@task_group_context@tbb@@QEBA_NXZ ) +__TBB_SYMBOL( ?cancel_group_execution@task_group_context@tbb@@QEAA_NXZ ) +__TBB_SYMBOL( ?reset@task_group_context@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?capture_fp_settings@task_group_context@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?init@task_group_context@tbb@@IEAAXXZ ) +__TBB_SYMBOL( ?register_pending_exception@task_group_context@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ??1task_group_context@tbb@@QEAA@XZ ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( ?set_priority@task_group_context@tbb@@QEAAXW4priority_t@2@@Z ) +__TBB_SYMBOL( ?priority@task_group_context@tbb@@QEBA?AW4priority_t@2@XZ ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( ?name@captured_exception@tbb@@UEBAPEBDXZ ) +__TBB_SYMBOL( ?what@captured_exception@tbb@@UEBAPEBDXZ ) +__TBB_SYMBOL( ??1captured_exception@tbb@@UEAA@XZ ) +__TBB_SYMBOL( ?move@captured_exception@tbb@@UEAAPEAV12@XZ ) +__TBB_SYMBOL( ?destroy@captured_exception@tbb@@UEAAXXZ ) +__TBB_SYMBOL( ?set@captured_exception@tbb@@QEAAXPEBD0@Z ) +__TBB_SYMBOL( ?clear@captured_exception@tbb@@QEAAXXZ ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +// Symbols for exceptions thrown from TBB +__TBB_SYMBOL( ?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ ) +__TBB_SYMBOL( ?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z ) +__TBB_SYMBOL( ?what@bad_last_alloc@tbb@@UEBAPEBDXZ ) +__TBB_SYMBOL( ?what@missing_wait@tbb@@UEBAPEBDXZ ) +__TBB_SYMBOL( ?what@invalid_multiple_scheduling@tbb@@UEBAPEBDXZ ) +__TBB_SYMBOL( ?what@improper_lock@tbb@@UEBAPEBDXZ ) +__TBB_SYMBOL( ?what@user_abort@tbb@@UEBAPEBDXZ ) + +// tbb_misc.cpp +__TBB_SYMBOL( ?assertion_failure@tbb@@YAXPEBDH00@Z ) +__TBB_SYMBOL( ?get_initial_auto_partitioner_divisor@internal@tbb@@YA_KXZ ) +__TBB_SYMBOL( ?handle_perror@internal@tbb@@YAXHPEBD@Z ) +__TBB_SYMBOL( ?set_assertion_handler@tbb@@YAP6AXPEBDH00@ZP6AX0H00@Z@Z ) +__TBB_SYMBOL( ?runtime_warning@internal@tbb@@YAXPEBDZZ ) +__TBB_SYMBOL( TBB_runtime_interface_version ) + +// tbb_main.cpp +__TBB_SYMBOL( ?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPEAXPEBX@Z ) +__TBB_SYMBOL( ?itt_store_pointer_with_release_v3@internal@tbb@@YAXPEAX0@Z ) +__TBB_SYMBOL( ?call_itt_notify_v5@internal@tbb@@YAXHPEAX@Z ) +__TBB_SYMBOL( ?itt_load_pointer_v3@internal@tbb@@YAPEAXPEBX@Z ) +__TBB_SYMBOL( ?itt_set_sync_name_v3@internal@tbb@@YAXPEAXPEB_W@Z ) +__TBB_SYMBOL( ?itt_make_task_group_v7@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_K12W4string_index@12@@Z ) +__TBB_SYMBOL( ?itt_metadata_str_add_v7@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_KW4string_index@12@PEBD@Z ) +__TBB_SYMBOL( ?itt_relation_add_v7@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_KW4itt_relation@12@12@Z ) +__TBB_SYMBOL( ?itt_task_begin_v7@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_K12W4string_index@12@@Z ) +__TBB_SYMBOL( ?itt_task_end_v7@internal@tbb@@YAXW4itt_domain_enum@12@@Z ) +__TBB_SYMBOL( ?itt_region_begin_v9@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_K12W4string_index@12@@Z ) +__TBB_SYMBOL( ?itt_region_end_v9@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_K@Z ) +__TBB_SYMBOL( ?itt_metadata_ptr_add_v11@internal@tbb@@YAXW4itt_domain_enum@12@PEAX_KW4string_index@12@1@Z ) + +// pipeline.cpp +__TBB_SYMBOL( ??_7pipeline@tbb@@6B@ ) +__TBB_SYMBOL( ??0pipeline@tbb@@QEAA@XZ ) +__TBB_SYMBOL( ??1filter@tbb@@UEAA@XZ ) +__TBB_SYMBOL( ??1pipeline@tbb@@UEAA@XZ ) +__TBB_SYMBOL( ?add_filter@pipeline@tbb@@QEAAXAEAVfilter@2@@Z ) +__TBB_SYMBOL( ?clear@pipeline@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?inject_token@pipeline@tbb@@AEAAXAEAVtask@2@@Z ) +__TBB_SYMBOL( ?run@pipeline@tbb@@QEAAX_K@Z ) +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( ?run@pipeline@tbb@@QEAAX_KAEAVtask_group_context@2@@Z ) +#endif +__TBB_SYMBOL( ?process_item@thread_bound_filter@tbb@@QEAA?AW4result_type@12@XZ ) +__TBB_SYMBOL( ?try_process_item@thread_bound_filter@tbb@@QEAA?AW4result_type@12@XZ ) +__TBB_SYMBOL( ?set_end_of_input@filter@tbb@@IEAAXXZ ) + +// queuing_rw_mutex.cpp +__TBB_SYMBOL( ?internal_construct@queuing_rw_mutex@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?acquire@scoped_lock@queuing_rw_mutex@tbb@@QEAAXAEAV23@_N@Z ) +__TBB_SYMBOL( ?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NXZ ) +__TBB_SYMBOL( ?release@scoped_lock@queuing_rw_mutex@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NXZ ) +__TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QEAA_NAEAV23@_N@Z ) + +// reader_writer_lock.cpp +__TBB_SYMBOL( ?try_lock_read@reader_writer_lock@interface5@tbb@@QEAA_NXZ ) +__TBB_SYMBOL( ?try_lock@reader_writer_lock@interface5@tbb@@QEAA_NXZ ) +__TBB_SYMBOL( ?unlock@reader_writer_lock@interface5@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?lock_read@reader_writer_lock@interface5@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?lock@reader_writer_lock@interface5@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?internal_construct@reader_writer_lock@interface5@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_destroy@reader_writer_lock@interface5@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_construct@scoped_lock@reader_writer_lock@interface5@tbb@@AEAAXAEAV234@@Z ) +__TBB_SYMBOL( ?internal_destroy@scoped_lock@reader_writer_lock@interface5@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_construct@scoped_lock_read@reader_writer_lock@interface5@tbb@@AEAAXAEAV234@@Z ) +__TBB_SYMBOL( ?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AEAAXXZ ) + +#if !TBB_NO_LEGACY +// spin_rw_mutex.cpp v2 +__TBB_SYMBOL( ?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) +__TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPEAV12@@Z ) +__TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) +__TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) +__TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex@tbb@@CA_NPEAV12@@Z ) +__TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) +__TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex@tbb@@CAXPEAV12@@Z ) +__TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPEAV12@@Z ) +__TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPEAV12@@Z ) +#endif + +// spin_rw_mutex v3 +__TBB_SYMBOL( ?internal_construct@spin_rw_mutex_v3@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex_v3@tbb@@AEAA_NXZ ) +__TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex_v3@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AEAA_NXZ ) +__TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex_v3@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex_v3@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AEAA_NXZ ) +__TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AEAA_NXZ ) + +// x86_rtm_rw_mutex.cpp +__TBB_SYMBOL( ?internal_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@_N@Z ) +__TBB_SYMBOL( ?internal_acquire_reader@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@_N@Z ) +__TBB_SYMBOL( ?internal_upgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z ) +__TBB_SYMBOL( ?internal_downgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z ) +__TBB_SYMBOL( ?internal_try_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z ) +__TBB_SYMBOL( ?internal_release@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@@Z ) +__TBB_SYMBOL( ?internal_construct@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXXZ ) + +// spin_mutex.cpp +__TBB_SYMBOL( ?internal_construct@spin_mutex@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?internal_acquire@scoped_lock@spin_mutex@tbb@@AEAAXAEAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@spin_mutex@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AEAA_NAEAV23@@Z ) + +// mutex.cpp +__TBB_SYMBOL( ?internal_acquire@scoped_lock@mutex@tbb@@AEAAXAEAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@mutex@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@mutex@tbb@@AEAA_NAEAV23@@Z ) +__TBB_SYMBOL( ?internal_construct@mutex@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_destroy@mutex@tbb@@AEAAXXZ ) + +// recursive_mutex.cpp +__TBB_SYMBOL( ?internal_construct@recursive_mutex@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_destroy@recursive_mutex@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_acquire@scoped_lock@recursive_mutex@tbb@@AEAAXAEAV23@@Z ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AEAA_NAEAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@recursive_mutex@tbb@@AEAAXXZ ) + +// queuing_mutex.cpp +__TBB_SYMBOL( ?internal_construct@queuing_mutex@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?acquire@scoped_lock@queuing_mutex@tbb@@QEAAXAEAV23@@Z ) +__TBB_SYMBOL( ?release@scoped_lock@queuing_mutex@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_mutex@tbb@@QEAA_NAEAV23@@Z ) + +//critical_section.cpp +__TBB_SYMBOL( ?internal_construct@critical_section_v4@internal@tbb@@QEAAXXZ ) + +#if !TBB_NO_LEGACY +// concurrent_hash_map.cpp +__TBB_SYMBOL( ?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QEBA_NXZ ) + +// concurrent_queue.cpp v2 +__TBB_SYMBOL( ??0concurrent_queue_base@internal@tbb@@IEAA@_K@Z ) +__TBB_SYMBOL( ??0concurrent_queue_iterator_base@internal@tbb@@IEAA@AEBVconcurrent_queue_base@12@@Z ) +__TBB_SYMBOL( ??1concurrent_queue_base@internal@tbb@@MEAA@XZ ) +__TBB_SYMBOL( ??1concurrent_queue_iterator_base@internal@tbb@@IEAA@XZ ) +__TBB_SYMBOL( ?advance@concurrent_queue_iterator_base@internal@tbb@@IEAAXXZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_iterator_base@internal@tbb@@IEAAXAEBV123@@Z ) +__TBB_SYMBOL( ?internal_pop@concurrent_queue_base@internal@tbb@@IEAAXPEAX@Z ) +__TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IEAA_NPEAX@Z ) +__TBB_SYMBOL( ?internal_push@concurrent_queue_base@internal@tbb@@IEAAXPEBX@Z ) +__TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IEAA_NPEBX@Z ) +__TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base@internal@tbb@@IEAAX_J_K@Z ) +__TBB_SYMBOL( ?internal_size@concurrent_queue_base@internal@tbb@@IEBA_JXZ ) +#endif + +// concurrent_queue v3 +__TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@AEBVconcurrent_queue_base_v3@12@@Z ) +__TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@AEBVconcurrent_queue_base_v3@12@_K@Z ) +__TBB_SYMBOL( ??1concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@XZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IEAAXAEBV123@@Z ) +__TBB_SYMBOL( ?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IEAAXXZ ) +__TBB_SYMBOL( ??0concurrent_queue_base_v3@internal@tbb@@IEAA@_K@Z ) +__TBB_SYMBOL( ??1concurrent_queue_base_v3@internal@tbb@@MEAA@XZ ) +__TBB_SYMBOL( ?internal_push@concurrent_queue_base_v3@internal@tbb@@IEAAXPEBX@Z ) +__TBB_SYMBOL( ?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IEAAXPEBX@Z ) +__TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IEAA_NPEBX@Z ) +__TBB_SYMBOL( ?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IEAA_NPEBX@Z ) +__TBB_SYMBOL( ?internal_pop@concurrent_queue_base_v3@internal@tbb@@IEAAXPEAX@Z ) +__TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IEAA_NPEAX@Z ) +__TBB_SYMBOL( ?internal_abort@concurrent_queue_base_v3@internal@tbb@@IEAAXXZ ) +__TBB_SYMBOL( ?internal_size@concurrent_queue_base_v3@internal@tbb@@IEBA_JXZ ) +__TBB_SYMBOL( ?internal_empty@concurrent_queue_base_v3@internal@tbb@@IEBA_NXZ ) +__TBB_SYMBOL( ?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IEAAXXZ ) +__TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IEAAX_J_K@Z ) +__TBB_SYMBOL( ?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IEBAXXZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_base_v3@internal@tbb@@IEAAXAEBV123@@Z ) +__TBB_SYMBOL( ?move_content@concurrent_queue_base_v8@internal@tbb@@IEAAXAEAV123@@Z ) + +#if !TBB_NO_LEGACY +// concurrent_vector.cpp v2 +__TBB_SYMBOL( ?internal_assign@concurrent_vector_base@internal@tbb@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z ) +__TBB_SYMBOL( ?internal_capacity@concurrent_vector_base@internal@tbb@@IEBA_KXZ ) +__TBB_SYMBOL( ?internal_clear@concurrent_vector_base@internal@tbb@@IEAAXP6AXPEAX_K@Z_N@Z ) +__TBB_SYMBOL( ?internal_copy@concurrent_vector_base@internal@tbb@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z ) +__TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base@internal@tbb@@IEAA_K_K0P6AXPEAX0@Z@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IEAAX_K0P6AXPEAX0@Z@Z ) +__TBB_SYMBOL( ?internal_push_back@concurrent_vector_base@internal@tbb@@IEAAPEAX_KAEA_K@Z ) +__TBB_SYMBOL( ?internal_reserve@concurrent_vector_base@internal@tbb@@IEAAX_K00@Z ) +#endif + +// concurrent_vector v3 +__TBB_SYMBOL( ??1concurrent_vector_base_v3@internal@tbb@@IEAA@XZ ) +__TBB_SYMBOL( ?internal_assign@concurrent_vector_base_v3@internal@tbb@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z ) +__TBB_SYMBOL( ?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IEBA_KXZ ) +__TBB_SYMBOL( ?internal_clear@concurrent_vector_base_v3@internal@tbb@@IEAA_KP6AXPEAX_K@Z@Z ) +__TBB_SYMBOL( ?internal_copy@concurrent_vector_base_v3@internal@tbb@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z ) +__TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IEAAX_K0P6AXPEAXPEBX0@Z2@Z ) +__TBB_SYMBOL( ?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IEAAPEAX_KAEA_K@Z ) +__TBB_SYMBOL( ?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IEAAX_K00@Z ) +__TBB_SYMBOL( ?internal_compact@concurrent_vector_base_v3@internal@tbb@@IEAAPEAX_KPEAXP6AX10@ZP6AX1PEBX0@Z@Z ) +__TBB_SYMBOL( ?internal_swap@concurrent_vector_base_v3@internal@tbb@@IEAAXAEAV123@@Z ) +__TBB_SYMBOL( ?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IEBAX_K@Z ) +__TBB_SYMBOL( ?internal_resize@concurrent_vector_base_v3@internal@tbb@@IEAAX_K00PEBXP6AXPEAX0@ZP6AX210@Z@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least_with_result@concurrent_vector_base_v3@internal@tbb@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z ) + +// tbb_thread +__TBB_SYMBOL( ?allocate_closure_v3@internal@tbb@@YAPEAX_K@Z ) +__TBB_SYMBOL( ?detach@tbb_thread_v3@internal@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?free_closure_v3@internal@tbb@@YAXPEAX@Z ) +__TBB_SYMBOL( ?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ ) +__TBB_SYMBOL( ?internal_start@tbb_thread_v3@internal@tbb@@AEAAXP6AIPEAX@Z0@Z ) +__TBB_SYMBOL( ?join@tbb_thread_v3@internal@tbb@@QEAAXXZ ) +__TBB_SYMBOL( ?move_v3@internal@tbb@@YAXAEAVtbb_thread_v3@12@0@Z ) +__TBB_SYMBOL( ?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ ) +__TBB_SYMBOL( ?thread_sleep_v3@internal@tbb@@YAXAEBVinterval_t@tick_count@2@@Z ) +__TBB_SYMBOL( ?thread_yield_v3@internal@tbb@@YAXXZ ) + +// condition_variable +__TBB_SYMBOL( ?internal_initialize_condition_variable@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_wait@internal@interface5@tbb@@YA_NAEATcondvar_impl_t@123@PEAVmutex@3@PEBVinterval_t@tick_count@3@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_notify_one@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_notify_all@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z ) + +// global parameter +__TBB_SYMBOL( ?active_value@global_control@interface9@tbb@@CA_KH@Z ) +__TBB_SYMBOL( ?internal_create@global_control@interface9@tbb@@AEAAXXZ ) +__TBB_SYMBOL( ?internal_destroy@global_control@interface9@tbb@@AEAAXXZ ) + +#if __TBB_PREVIEW_RESUMABLE_TASKS +__TBB_SYMBOL( ?internal_suspend@internal@tbb@@YAXPEAX0@Z ) +__TBB_SYMBOL( ?internal_resume@internal@tbb@@YAXPEAX@Z ) +__TBB_SYMBOL( ?internal_current_suspend_point@internal@tbb@@YAPEAXXZ ) +#endif + +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbbbind-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbbbind-export.def new file mode 100644 index 00000000..557c9056 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/win64-tbbbind-export.def @@ -0,0 +1,22 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +EXPORTS + +global +initialize_numa_topology +bind_to_node +restore_affinity +allocate_binding_handler +deallocate_binding_handler diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/winrt-tbb-export.lst b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/winrt-tbb-export.lst new file mode 100644 index 00000000..b4b3ea53 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/winrt-tbb-export.lst @@ -0,0 +1,296 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +#include "tbb/tbb_config.h" + +// cache_aligned_allocator.cpp +__TBB_SYMBOL( ?NFS_Allocate@internal@tbb@@YAPAXIIPAX@Z ) +__TBB_SYMBOL( ?NFS_GetLineSize@internal@tbb@@YAIXZ ) +__TBB_SYMBOL( ?NFS_Free@internal@tbb@@YAXPAX@Z ) +__TBB_SYMBOL( ?allocate_via_handler_v3@internal@tbb@@YAPAXI@Z ) +__TBB_SYMBOL( ?deallocate_via_handler_v3@internal@tbb@@YAXPAX@Z ) +__TBB_SYMBOL( ?is_malloc_used_v3@internal@tbb@@YA_NXZ ) + +// task.cpp v3 +__TBB_SYMBOL( ?allocate@allocate_additional_child_of_proxy@internal@tbb@@QBAAAVtask@3@I@Z ) +__TBB_SYMBOL( ?allocate@allocate_child_proxy@internal@tbb@@QBAAAVtask@3@I@Z ) +__TBB_SYMBOL( ?allocate@allocate_continuation_proxy@internal@tbb@@QBAAAVtask@3@I@Z ) +__TBB_SYMBOL( ?allocate@allocate_root_proxy@internal@tbb@@SAAAVtask@3@I@Z ) +__TBB_SYMBOL( ?destroy@task_base@internal@interface5@tbb@@SAXAAVtask@4@@Z ) +__TBB_SYMBOL( ?free@allocate_additional_child_of_proxy@internal@tbb@@QBAXAAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_child_proxy@internal@tbb@@QBAXAAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_continuation_proxy@internal@tbb@@QBAXAAVtask@3@@Z ) +__TBB_SYMBOL( ?free@allocate_root_proxy@internal@tbb@@SAXAAVtask@3@@Z ) +__TBB_SYMBOL( ?internal_set_ref_count@task@tbb@@AAAXH@Z ) +__TBB_SYMBOL( ?internal_decrement_ref_count@task@tbb@@AAAHXZ ) +__TBB_SYMBOL( ?is_owned_by_current_thread@task@tbb@@QBA_NXZ ) +__TBB_SYMBOL( ?note_affinity@task@tbb@@UAAXG@Z ) +__TBB_SYMBOL( ?resize@affinity_partitioner_base_v3@internal@tbb@@AAAXI@Z ) +__TBB_SYMBOL( ?self@task@tbb@@SAAAV12@XZ ) +__TBB_SYMBOL( ?spawn_and_wait_for_all@task@tbb@@QAAXAAVtask_list@2@@Z ) +__TBB_SYMBOL( ?default_num_threads@task_scheduler_init@tbb@@SAHXZ ) +__TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QAAXHI@Z ) +__TBB_SYMBOL( ?initialize@task_scheduler_init@tbb@@QAAXH@Z ) +__TBB_SYMBOL( ?terminate@task_scheduler_init@tbb@@QAAXXZ ) +#if __TBB_SCHEDULER_OBSERVER +__TBB_SYMBOL( ?observe@task_scheduler_observer_v3@internal@tbb@@QAAX_N@Z ) +#endif /* __TBB_SCHEDULER_OBSERVER */ + +/* arena.cpp */ +__TBB_SYMBOL( ?internal_max_concurrency@task_arena_base@internal@interface7@tbb@@KAHPBVtask_arena@34@@Z ) +__TBB_SYMBOL( ?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ ) +__TBB_SYMBOL( ?internal_initialize@task_arena_base@internal@interface7@tbb@@IAAXXZ ) +__TBB_SYMBOL( ?internal_terminate@task_arena_base@internal@interface7@tbb@@IAAXXZ ) +__TBB_SYMBOL( ?internal_attach@task_arena_base@internal@interface7@tbb@@IAAXXZ ) +__TBB_SYMBOL( ?internal_enqueue@task_arena_base@internal@interface7@tbb@@IBAXAAVtask@4@H@Z ) +__TBB_SYMBOL( ?internal_execute@task_arena_base@internal@interface7@tbb@@IBAXAAVdelegate_base@234@@Z ) +__TBB_SYMBOL( ?internal_wait@task_arena_base@internal@interface7@tbb@@IBAXXZ ) +#if __TBB_TASK_ISOLATION +__TBB_SYMBOL( ?isolate_within_arena@internal@interface7@tbb@@YAXAAVdelegate_base@123@H@Z ) +#endif /* __TBB_TASK_ISOLATION */ + +#if !TBB_NO_LEGACY +// task_v2.cpp +__TBB_SYMBOL( ?destroy@task@tbb@@QAAXAAV12@@Z ) +#endif + +// exception handling support +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( ?allocate@allocate_root_with_context_proxy@internal@tbb@@QBAAAVtask@3@I@Z ) +__TBB_SYMBOL( ?free@allocate_root_with_context_proxy@internal@tbb@@QBAXAAVtask@3@@Z ) +__TBB_SYMBOL( ?change_group@task@tbb@@QAAXAAVtask_group_context@2@@Z ) +__TBB_SYMBOL( ?is_group_execution_cancelled@task_group_context@tbb@@QBA_NXZ ) +__TBB_SYMBOL( ?cancel_group_execution@task_group_context@tbb@@QAA_NXZ ) +__TBB_SYMBOL( ?reset@task_group_context@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?capture_fp_settings@task_group_context@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?init@task_group_context@tbb@@IAAXXZ ) +__TBB_SYMBOL( ?register_pending_exception@task_group_context@tbb@@QAAXXZ ) +__TBB_SYMBOL( ??1task_group_context@tbb@@QAA@XZ ) +#if __TBB_TASK_PRIORITY +__TBB_SYMBOL( ?set_priority@task_group_context@tbb@@QAAXW4priority_t@2@@Z ) +__TBB_SYMBOL( ?priority@task_group_context@tbb@@QBA?AW4priority_t@2@XZ ) +#endif /* __TBB_TASK_PRIORITY */ +__TBB_SYMBOL( ?name@captured_exception@tbb@@UBAPBDXZ ) +__TBB_SYMBOL( ?what@captured_exception@tbb@@UBAPBDXZ ) +__TBB_SYMBOL( ??1captured_exception@tbb@@UAA@XZ ) +__TBB_SYMBOL( ?move@captured_exception@tbb@@UAAPAV12@XZ ) +__TBB_SYMBOL( ?destroy@captured_exception@tbb@@UAAXXZ ) +__TBB_SYMBOL( ?set@captured_exception@tbb@@QAAXPBD0@Z ) +__TBB_SYMBOL( ?clear@captured_exception@tbb@@QAAXXZ ) +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +// Symbols for exceptions thrown from TBB +__TBB_SYMBOL( ?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ ) +__TBB_SYMBOL( ?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z ) +__TBB_SYMBOL( ?what@bad_last_alloc@tbb@@UBAPBDXZ ) +__TBB_SYMBOL( ?what@missing_wait@tbb@@UBAPBDXZ ) +__TBB_SYMBOL( ?what@invalid_multiple_scheduling@tbb@@UBAPBDXZ ) +__TBB_SYMBOL( ?what@improper_lock@tbb@@UBAPBDXZ ) +__TBB_SYMBOL( ?what@user_abort@tbb@@UBAPBDXZ ) + +// tbb_misc.cpp +__TBB_SYMBOL( ?assertion_failure@tbb@@YAXPBDH00@Z ) +__TBB_SYMBOL( ?get_initial_auto_partitioner_divisor@internal@tbb@@YAIXZ ) +__TBB_SYMBOL( ?handle_perror@internal@tbb@@YAXHPBD@Z ) +__TBB_SYMBOL( ?set_assertion_handler@tbb@@YAP6AXPBDH00@ZP6AX0H00@Z@Z ) +__TBB_SYMBOL( ?runtime_warning@internal@tbb@@YAXPBDZZ ) +__TBB_SYMBOL( TBB_runtime_interface_version ) + +// tbb_main.cpp +__TBB_SYMBOL( ?itt_load_pointer_with_acquire_v3@internal@tbb@@YAPAXPBX@Z ) +__TBB_SYMBOL( ?itt_store_pointer_with_release_v3@internal@tbb@@YAXPAX0@Z ) +__TBB_SYMBOL( ?call_itt_notify_v5@internal@tbb@@YAXHPAX@Z ) +__TBB_SYMBOL( ?itt_set_sync_name_v3@internal@tbb@@YAXPAXPB_W@Z ) +__TBB_SYMBOL( ?itt_load_pointer_v3@internal@tbb@@YAPAXPBX@Z ) + +// pipeline.cpp +__TBB_SYMBOL( ??0pipeline@tbb@@QAA@XZ ) +__TBB_SYMBOL( ??1filter@tbb@@UAA@XZ ) +__TBB_SYMBOL( ??1pipeline@tbb@@UAA@XZ ) +__TBB_SYMBOL( ??_7pipeline@tbb@@6B@ ) +__TBB_SYMBOL( ?add_filter@pipeline@tbb@@QAAXAAVfilter@2@@Z ) +__TBB_SYMBOL( ?clear@pipeline@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?inject_token@pipeline@tbb@@AAAXAAVtask@2@@Z ) +__TBB_SYMBOL( ?run@pipeline@tbb@@QAAXI@Z ) +#if __TBB_TASK_GROUP_CONTEXT +__TBB_SYMBOL( ?run@pipeline@tbb@@QAAXIAAVtask_group_context@2@@Z ) +#endif +__TBB_SYMBOL( ?process_item@thread_bound_filter@tbb@@QAA?AW4result_type@12@XZ ) +__TBB_SYMBOL( ?try_process_item@thread_bound_filter@tbb@@QAA?AW4result_type@12@XZ ) +__TBB_SYMBOL( ?set_end_of_input@filter@tbb@@IAAXXZ ) + +// queuing_rw_mutex.cpp +__TBB_SYMBOL( ?internal_construct@queuing_rw_mutex@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?acquire@scoped_lock@queuing_rw_mutex@tbb@@QAAXAAV23@_N@Z ) +__TBB_SYMBOL( ?downgrade_to_reader@scoped_lock@queuing_rw_mutex@tbb@@QAA_NXZ ) +__TBB_SYMBOL( ?release@scoped_lock@queuing_rw_mutex@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?upgrade_to_writer@scoped_lock@queuing_rw_mutex@tbb@@QAA_NXZ ) +__TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_rw_mutex@tbb@@QAA_NAAV23@_N@Z ) + +// reader_writer_lock.cpp +__TBB_SYMBOL( ?try_lock_read@reader_writer_lock@interface5@tbb@@QAA_NXZ ) +__TBB_SYMBOL( ?try_lock@reader_writer_lock@interface5@tbb@@QAA_NXZ ) +__TBB_SYMBOL( ?unlock@reader_writer_lock@interface5@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?lock_read@reader_writer_lock@interface5@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?lock@reader_writer_lock@interface5@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?internal_construct@reader_writer_lock@interface5@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_destroy@reader_writer_lock@interface5@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_construct@scoped_lock@reader_writer_lock@interface5@tbb@@AAAXAAV234@@Z ) +__TBB_SYMBOL( ?internal_destroy@scoped_lock@reader_writer_lock@interface5@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_construct@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAAXAAV234@@Z ) +__TBB_SYMBOL( ?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AAAXXZ ) + +#if !TBB_NO_LEGACY +// spin_rw_mutex.cpp v2 +__TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) +__TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex@tbb@@CAXPAV12@@Z ) +__TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) +__TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) +__TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPAV12@@Z ) +#endif + +// spin_rw_mutex v3 +__TBB_SYMBOL( ?internal_construct@spin_rw_mutex_v3@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_upgrade@spin_rw_mutex_v3@tbb@@AAA_NXZ ) +__TBB_SYMBOL( ?internal_downgrade@spin_rw_mutex_v3@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_acquire_reader@spin_rw_mutex_v3@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_acquire_writer@spin_rw_mutex_v3@tbb@@AAA_NXZ ) +__TBB_SYMBOL( ?internal_release_reader@spin_rw_mutex_v3@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_release_writer@spin_rw_mutex_v3@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_try_acquire_reader@spin_rw_mutex_v3@tbb@@AAA_NXZ ) +__TBB_SYMBOL( ?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AAA_NXZ ) + +// spin_mutex.cpp +__TBB_SYMBOL( ?internal_construct@spin_mutex@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?internal_acquire@scoped_lock@spin_mutex@tbb@@AAAXAAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@spin_mutex@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@spin_mutex@tbb@@AAA_NAAV23@@Z ) + +// mutex.cpp +__TBB_SYMBOL( ?internal_acquire@scoped_lock@mutex@tbb@@AAAXAAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@mutex@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@mutex@tbb@@AAA_NAAV23@@Z ) +__TBB_SYMBOL( ?internal_construct@mutex@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_destroy@mutex@tbb@@AAAXXZ ) + +// recursive_mutex.cpp +__TBB_SYMBOL( ?internal_acquire@scoped_lock@recursive_mutex@tbb@@AAAXAAV23@@Z ) +__TBB_SYMBOL( ?internal_release@scoped_lock@recursive_mutex@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_try_acquire@scoped_lock@recursive_mutex@tbb@@AAA_NAAV23@@Z ) +__TBB_SYMBOL( ?internal_construct@recursive_mutex@tbb@@AAAXXZ ) +__TBB_SYMBOL( ?internal_destroy@recursive_mutex@tbb@@AAAXXZ ) + +// queuing_mutex.cpp +__TBB_SYMBOL( ?internal_construct@queuing_mutex@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?acquire@scoped_lock@queuing_mutex@tbb@@QAAXAAV23@@Z ) +__TBB_SYMBOL( ?release@scoped_lock@queuing_mutex@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?try_acquire@scoped_lock@queuing_mutex@tbb@@QAA_NAAV23@@Z ) + +// critical_section.cpp +__TBB_SYMBOL( ?internal_construct@critical_section_v4@internal@tbb@@QAAXXZ ) + +#if !TBB_NO_LEGACY +// concurrent_hash_map.cpp +__TBB_SYMBOL( ?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QBA_NXZ ) + +// concurrent_queue.cpp v2 +__TBB_SYMBOL( ?advance@concurrent_queue_iterator_base@internal@tbb@@IAAXXZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_iterator_base@internal@tbb@@IAAXABV123@@Z ) +__TBB_SYMBOL( ?internal_size@concurrent_queue_base@internal@tbb@@IBAHXZ ) +__TBB_SYMBOL( ??0concurrent_queue_base@internal@tbb@@IAA@I@Z ) +__TBB_SYMBOL( ??0concurrent_queue_iterator_base@internal@tbb@@IAA@ABVconcurrent_queue_base@12@@Z ) +__TBB_SYMBOL( ??1concurrent_queue_base@internal@tbb@@MAA@XZ ) +__TBB_SYMBOL( ??1concurrent_queue_iterator_base@internal@tbb@@IAA@XZ ) +__TBB_SYMBOL( ?internal_pop@concurrent_queue_base@internal@tbb@@IAAXPAX@Z ) +__TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base@internal@tbb@@IAA_NPAX@Z ) +__TBB_SYMBOL( ?internal_push@concurrent_queue_base@internal@tbb@@IAAXPBX@Z ) +__TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base@internal@tbb@@IAA_NPBX@Z ) +__TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base@internal@tbb@@IAAXHI@Z ) +#endif + +// concurrent_queue v3 +__TBB_SYMBOL( ??1concurrent_queue_iterator_base_v3@internal@tbb@@IAA@XZ ) +__TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAA@ABVconcurrent_queue_base_v3@12@@Z ) +__TBB_SYMBOL( ??0concurrent_queue_iterator_base_v3@internal@tbb@@IAA@ABVconcurrent_queue_base_v3@12@I@Z ) +__TBB_SYMBOL( ?advance@concurrent_queue_iterator_base_v3@internal@tbb@@IAAXXZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_iterator_base_v3@internal@tbb@@IAAXABV123@@Z ) +__TBB_SYMBOL( ??0concurrent_queue_base_v3@internal@tbb@@IAA@I@Z ) +__TBB_SYMBOL( ??1concurrent_queue_base_v3@internal@tbb@@MAA@XZ ) +__TBB_SYMBOL( ?internal_pop@concurrent_queue_base_v3@internal@tbb@@IAAXPAX@Z ) +__TBB_SYMBOL( ?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IAA_NPAX@Z ) +__TBB_SYMBOL( ?internal_abort@concurrent_queue_base_v3@internal@tbb@@IAAXXZ ) +__TBB_SYMBOL( ?internal_push@concurrent_queue_base_v3@internal@tbb@@IAAXPBX@Z ) +__TBB_SYMBOL( ?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IAAXPBX@Z ) +__TBB_SYMBOL( ?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IAA_NPBX@Z ) +__TBB_SYMBOL( ?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IAA_NPBX@Z ) +__TBB_SYMBOL( ?internal_size@concurrent_queue_base_v3@internal@tbb@@IBAHXZ ) +__TBB_SYMBOL( ?internal_empty@concurrent_queue_base_v3@internal@tbb@@IBA_NXZ ) +__TBB_SYMBOL( ?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IAAXHI@Z ) +__TBB_SYMBOL( ?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IAAXXZ ) +__TBB_SYMBOL( ?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IBAXXZ ) +__TBB_SYMBOL( ?assign@concurrent_queue_base_v3@internal@tbb@@IAAXABV123@@Z ) +__TBB_SYMBOL( ?move_content@concurrent_queue_base_v8@internal@tbb@@IAAXAAV123@@Z ) + +#if !TBB_NO_LEGACY +// concurrent_vector.cpp v2 +__TBB_SYMBOL( ?internal_assign@concurrent_vector_base@internal@tbb@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z ) +__TBB_SYMBOL( ?internal_capacity@concurrent_vector_base@internal@tbb@@IBAIXZ ) +__TBB_SYMBOL( ?internal_clear@concurrent_vector_base@internal@tbb@@IAAXP6AXPAXI@Z_N@Z ) +__TBB_SYMBOL( ?internal_copy@concurrent_vector_base@internal@tbb@@IAAXABV123@IP6AXPAXPBXI@Z@Z ) +__TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base@internal@tbb@@IAAIIIP6AXPAXI@Z@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base@internal@tbb@@IAAXIIP6AXPAXI@Z@Z ) +__TBB_SYMBOL( ?internal_push_back@concurrent_vector_base@internal@tbb@@IAAPAXIAAI@Z ) +__TBB_SYMBOL( ?internal_reserve@concurrent_vector_base@internal@tbb@@IAAXIII@Z ) +#endif + +// concurrent_vector v3 +__TBB_SYMBOL( ??1concurrent_vector_base_v3@internal@tbb@@IAA@XZ ) +__TBB_SYMBOL( ?internal_assign@concurrent_vector_base_v3@internal@tbb@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z ) +__TBB_SYMBOL( ?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IBAIXZ ) +__TBB_SYMBOL( ?internal_clear@concurrent_vector_base_v3@internal@tbb@@IAAIP6AXPAXI@Z@Z ) +__TBB_SYMBOL( ?internal_copy@concurrent_vector_base_v3@internal@tbb@@IAAXABV123@IP6AXPAXPBXI@Z@Z ) +__TBB_SYMBOL( ?internal_grow_by@concurrent_vector_base_v3@internal@tbb@@IAAIIIP6AXPAXPBXI@Z1@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least@concurrent_vector_base_v3@internal@tbb@@IAAXIIP6AXPAXPBXI@Z1@Z ) +__TBB_SYMBOL( ?internal_push_back@concurrent_vector_base_v3@internal@tbb@@IAAPAXIAAI@Z ) +__TBB_SYMBOL( ?internal_reserve@concurrent_vector_base_v3@internal@tbb@@IAAXIII@Z ) +__TBB_SYMBOL( ?internal_compact@concurrent_vector_base_v3@internal@tbb@@IAAPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z ) +__TBB_SYMBOL( ?internal_swap@concurrent_vector_base_v3@internal@tbb@@IAAXAAV123@@Z ) +__TBB_SYMBOL( ?internal_throw_exception@concurrent_vector_base_v3@internal@tbb@@IBAXI@Z ) +__TBB_SYMBOL( ?internal_resize@concurrent_vector_base_v3@internal@tbb@@IAAXIIIPBXP6AXPAXI@ZP6AX10I@Z@Z ) +__TBB_SYMBOL( ?internal_grow_to_at_least_with_result@concurrent_vector_base_v3@internal@tbb@@IAAIIIP6AXPAXPBXI@Z1@Z ) + +// tbb_thread +__TBB_SYMBOL( ?join@tbb_thread_v3@internal@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?detach@tbb_thread_v3@internal@tbb@@QAAXXZ ) +__TBB_SYMBOL( ?internal_start@tbb_thread_v3@internal@tbb@@AAAXP6AIPAX@Z0@Z ) +__TBB_SYMBOL( ?allocate_closure_v3@internal@tbb@@YAPAXI@Z ) +__TBB_SYMBOL( ?free_closure_v3@internal@tbb@@YAXPAX@Z ) +__TBB_SYMBOL( ?hardware_concurrency@tbb_thread_v3@internal@tbb@@SAIXZ ) +__TBB_SYMBOL( ?thread_yield_v3@internal@tbb@@YAXXZ ) +__TBB_SYMBOL( ?thread_sleep_v3@internal@tbb@@YAXABVinterval_t@tick_count@2@@Z ) +__TBB_SYMBOL( ?move_v3@internal@tbb@@YAXAAVtbb_thread_v3@12@0@Z ) +__TBB_SYMBOL( ?thread_get_id_v3@internal@tbb@@YA?AVid@tbb_thread_v3@12@XZ ) + +// condition_variable +__TBB_SYMBOL( ?internal_initialize_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_wait@internal@interface5@tbb@@YA_NAATcondvar_impl_t@123@PAVmutex@3@PBVinterval_t@tick_count@3@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_notify_one@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_condition_variable_notify_all@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) +__TBB_SYMBOL( ?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAATcondvar_impl_t@123@@Z ) + +#undef __TBB_SYMBOL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/x86_rtm_rw_mutex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/x86_rtm_rw_mutex.cpp new file mode 100644 index 00000000..e321b593 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbb/x86_rtm_rw_mutex.cpp @@ -0,0 +1,278 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" +#if __TBB_TSX_AVAILABLE +#include "tbb/spin_rw_mutex.h" +#include "tbb/tbb_machine.h" +#include "itt_notify.h" +#include "governor.h" +#include "tbb/atomic.h" + +// __TBB_RW_MUTEX_DELAY_TEST shifts the point where flags aborting speculation are +// added to the read-set of the operation. If 1, will add the test just before +// the transaction is ended; this technique is called lazy subscription. +// CAUTION: due to proven issues of lazy subscription, use of __TBB_RW_MUTEX_DELAY_TEST is discouraged! +#ifndef __TBB_RW_MUTEX_DELAY_TEST + #define __TBB_RW_MUTEX_DELAY_TEST 0 +#endif + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4244) +#endif + +namespace tbb { + +namespace interface8 { +namespace internal { + +// abort code for mutexes that detect a conflict with another thread. +// value is hexadecimal +enum { + speculation_transaction_aborted = 0x01, + speculation_can_retry = 0x02, + speculation_memadd_conflict = 0x04, + speculation_buffer_overflow = 0x08, + speculation_breakpoint_hit = 0x10, + speculation_nested_abort = 0x20, + speculation_xabort_mask = 0xFF000000, + speculation_xabort_shift = 24, + speculation_retry = speculation_transaction_aborted + | speculation_can_retry + | speculation_memadd_conflict +}; + +// maximum number of times to retry +// TODO: experiment on retry values. +static const int retry_threshold_read = 10; +static const int retry_threshold_write = 10; + +//! Release speculative mutex +void x86_rtm_rw_mutex::internal_release(x86_rtm_rw_mutex::scoped_lock& s) { + switch(s.transaction_state) { + case RTM_transacting_writer: + case RTM_transacting_reader: + { + __TBB_ASSERT(__TBB_machine_is_in_transaction(), "transaction_state && not speculating"); +#if __TBB_RW_MUTEX_DELAY_TEST + if(s.transaction_state == RTM_transacting_reader) { + if(this->w_flag) __TBB_machine_transaction_conflict_abort(); + } else { + if(this->state) __TBB_machine_transaction_conflict_abort(); + } +#endif + __TBB_machine_end_transaction(); + s.my_scoped_lock.mutex = NULL; + } + break; + case RTM_real_reader: + __TBB_ASSERT(!this->w_flag, "w_flag set but read lock acquired"); + s.my_scoped_lock.release(); + break; + case RTM_real_writer: + __TBB_ASSERT(this->w_flag, "w_flag unset but write lock acquired"); + this->w_flag = false; + s.my_scoped_lock.release(); + break; + case RTM_not_in_mutex: + __TBB_ASSERT(false, "RTM_not_in_mutex, but in release"); + break; + default: + __TBB_ASSERT(false, "invalid transaction_state"); + } + s.transaction_state = RTM_not_in_mutex; +} + +//! Acquire write lock on the given mutex. +void x86_rtm_rw_mutex::internal_acquire_writer(x86_rtm_rw_mutex::scoped_lock& s, bool only_speculate) +{ + __TBB_ASSERT(s.transaction_state == RTM_not_in_mutex, "scoped_lock already in transaction"); + if(tbb::internal::governor::speculation_enabled()) { + int num_retries = 0; + unsigned int abort_code; + do { + tbb::internal::atomic_backoff backoff; + if(this->state) { + if(only_speculate) return; + do { + backoff.pause(); // test the spin_rw_mutex (real readers or writers) + } while(this->state); + } + // _xbegin returns -1 on success or the abort code, so capture it + if(( abort_code = __TBB_machine_begin_transaction()) == ~(unsigned int)(0) ) + { + // started speculation +#if !__TBB_RW_MUTEX_DELAY_TEST + if(this->state) { // add spin_rw_mutex to read-set. + // reader or writer grabbed the lock, so abort. + __TBB_machine_transaction_conflict_abort(); + } +#endif + s.transaction_state = RTM_transacting_writer; + // Don not wrap the following assignment to a function, + // because it can abort the transaction in debug. Need mutex for release(). + s.my_scoped_lock.mutex = this; + return; // successfully started speculation + } + ++num_retries; + } while( (abort_code & speculation_retry) != 0 && (num_retries < retry_threshold_write) ); + } + + if(only_speculate) return; // should apply a real try_lock... + s.my_scoped_lock.acquire(*this, true); // kill transactional writers + __TBB_ASSERT(!w_flag, "After acquire for write, w_flag already true"); + w_flag = true; // kill transactional readers + s.transaction_state = RTM_real_writer; + return; +} + +//! Acquire read lock on given mutex. +// only_speculate : true if we are doing a try_acquire. If true and we fail to speculate, don't +// really acquire the lock, return and do a try_acquire on the contained spin_rw_mutex. If +// the lock is already held by a writer, just return. +void x86_rtm_rw_mutex::internal_acquire_reader(x86_rtm_rw_mutex::scoped_lock& s, bool only_speculate) { + __TBB_ASSERT(s.transaction_state == RTM_not_in_mutex, "scoped_lock already in transaction"); + if(tbb::internal::governor::speculation_enabled()) { + int num_retries = 0; + unsigned int abort_code; + do { + tbb::internal::atomic_backoff backoff; + // if in try_acquire, and lock is held as writer, don't attempt to speculate. + if(w_flag) { + if(only_speculate) return; + do { + backoff.pause(); // test the spin_rw_mutex (real readers or writers) + } while(w_flag); + } + // _xbegin returns -1 on success or the abort code, so capture it + if((abort_code = __TBB_machine_begin_transaction()) == ~(unsigned int)(0) ) + { + // started speculation +#if !__TBB_RW_MUTEX_DELAY_TEST + if(w_flag) { // add w_flag to read-set. + __TBB_machine_transaction_conflict_abort(); // writer grabbed the lock, so abort. + } +#endif + s.transaction_state = RTM_transacting_reader; + // Don not wrap the following assignment to a function, + // because it can abort the transaction in debug. Need mutex for release(). + s.my_scoped_lock.mutex = this; + return; // successfully started speculation + } + // fallback path + // retry only if there is any hope of getting into a transaction soon + // Retry in the following cases (from Section 8.3.5 of Intel(R) + // Architecture Instruction Set Extensions Programming Reference): + // 1. abort caused by XABORT instruction (bit 0 of EAX register is set) + // 2. the transaction may succeed on a retry (bit 1 of EAX register is set) + // 3. if another logical processor conflicted with a memory address + // that was part of the transaction that aborted (bit 2 of EAX register is set) + // That is, retry if (abort_code & 0x7) is non-zero + ++num_retries; + } while( (abort_code & speculation_retry) != 0 && (num_retries < retry_threshold_read) ); + } + + if(only_speculate) return; + s.my_scoped_lock.acquire( *this, false ); + s.transaction_state = RTM_real_reader; +} + +//! Upgrade reader to become a writer. +/** Returns whether the upgrade happened without releasing and re-acquiring the lock */ +bool x86_rtm_rw_mutex::internal_upgrade(x86_rtm_rw_mutex::scoped_lock& s) +{ + switch(s.transaction_state) { + case RTM_real_reader: { + s.transaction_state = RTM_real_writer; + bool no_release = s.my_scoped_lock.upgrade_to_writer(); + __TBB_ASSERT(!w_flag, "After upgrade_to_writer, w_flag already true"); + w_flag = true; + return no_release; + } + case RTM_transacting_reader: +#if !__TBB_RW_MUTEX_DELAY_TEST + if(this->state) { // add spin_rw_mutex to read-set. + // Real reader or writer holds the lock; so commit the read and re-acquire for write. + internal_release(s); + internal_acquire_writer(s); + return false; + } else +#endif + { + s.transaction_state = RTM_transacting_writer; + return true; + } + default: + __TBB_ASSERT(false, "Invalid state for upgrade"); + return false; + } +} + +//! Downgrade writer to a reader. +bool x86_rtm_rw_mutex::internal_downgrade(x86_rtm_rw_mutex::scoped_lock& s) { + switch(s.transaction_state) { + case RTM_real_writer: + s.transaction_state = RTM_real_reader; + __TBB_ASSERT(w_flag, "Before downgrade_to_reader w_flag not true"); + w_flag = false; + return s.my_scoped_lock.downgrade_to_reader(); + case RTM_transacting_writer: +#if __TBB_RW_MUTEX_DELAY_TEST + if(this->state) { // a reader or writer has acquired mutex for real. + __TBB_machine_transaction_conflict_abort(); + } +#endif + s.transaction_state = RTM_transacting_reader; + return true; + default: + __TBB_ASSERT(false, "Invalid state for downgrade"); + return false; + } +} + +//! Try to acquire write lock on the given mutex. +// There may be reader(s) which acquired the spin_rw_mutex, as well as possibly +// transactional reader(s). If this is the case, the acquire will fail, and assigning +// w_flag will kill the transactors. So we only assign w_flag if we have successfully +// acquired the lock. +bool x86_rtm_rw_mutex::internal_try_acquire_writer(x86_rtm_rw_mutex::scoped_lock& s) +{ + internal_acquire_writer(s, /*only_speculate=*/true); + if(s.transaction_state == RTM_transacting_writer) { + return true; + } + __TBB_ASSERT(s.transaction_state == RTM_not_in_mutex, "Trying to acquire writer which is already allocated"); + // transacting write acquire failed. try_acquire the real mutex + bool result = s.my_scoped_lock.try_acquire(*this, true); + if(result) { + // only shoot down readers if we're not transacting ourselves + __TBB_ASSERT(!w_flag, "After try_acquire_writer, w_flag already true"); + w_flag = true; + s.transaction_state = RTM_real_writer; + } + return result; +} + +void x86_rtm_rw_mutex::internal_construct() { + ITT_SYNC_CREATE(this, _T("tbb::x86_rtm_rw_mutex"), _T("")); +} + +} // namespace internal +} // namespace interface8 +} // namespace tbb + +#endif /* __TBB_TSX_AVAILABLE */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Customize.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Customize.h new file mode 100644 index 00000000..7493b0ec --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Customize.h @@ -0,0 +1,146 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_malloc_Customize_H_ +#define _TBB_malloc_Customize_H_ + +// customizing MALLOC_ASSERT macro +#include "tbb/tbb_stddef.h" +#define MALLOC_ASSERT(assertion, message) __TBB_ASSERT(assertion, message) +#define MALLOC_ASSERT_EX(assertion, message) __TBB_ASSERT_EX(assertion, message) + +#ifndef MALLOC_DEBUG +#define MALLOC_DEBUG TBB_USE_DEBUG +#endif + +#include "Synchronize.h" + +#if DO_ITT_NOTIFY +#include "tbb/itt_notify.h" +#define MALLOC_ITT_SYNC_PREPARE(pointer) ITT_NOTIFY(sync_prepare, (pointer)) +#define MALLOC_ITT_SYNC_ACQUIRED(pointer) ITT_NOTIFY(sync_acquired, (pointer)) +#define MALLOC_ITT_SYNC_RELEASING(pointer) ITT_NOTIFY(sync_releasing, (pointer)) +#define MALLOC_ITT_SYNC_CANCEL(pointer) ITT_NOTIFY(sync_cancel, (pointer)) +#define MALLOC_ITT_FINI_ITTLIB() ITT_FINI_ITTLIB() +#else +#define MALLOC_ITT_SYNC_PREPARE(pointer) ((void)0) +#define MALLOC_ITT_SYNC_ACQUIRED(pointer) ((void)0) +#define MALLOC_ITT_SYNC_RELEASING(pointer) ((void)0) +#define MALLOC_ITT_SYNC_CANCEL(pointer) ((void)0) +#define MALLOC_ITT_FINI_ITTLIB() ((void)0) +#endif + +inline intptr_t BitScanRev(uintptr_t x) { + return !x? -1 : __TBB_Log2(x); +} + +template<typename T> +static inline bool isAligned(T* arg, uintptr_t alignment) { + return tbb::internal::is_aligned(arg,alignment); +} + +static inline bool isPowerOfTwo(uintptr_t arg) { + return tbb::internal::is_power_of_two(arg); +} +static inline bool isPowerOfTwoAtLeast(uintptr_t arg, uintptr_t power2) { + return arg && tbb::internal::is_power_of_two_at_least(arg,power2); +} + +#define MALLOC_STATIC_ASSERT(condition,msg) __TBB_STATIC_ASSERT(condition,msg) + +#define USE_DEFAULT_MEMORY_MAPPING 1 + +// To support malloc replacement +#include "proxy.h" + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED +#define malloc_proxy __TBB_malloc_proxy +extern "C" void * __TBB_malloc_proxy(size_t) __attribute__ ((weak)); +#elif MALLOC_ZONE_OVERLOAD_ENABLED +// as there is no significant overhead, always suppose that proxy can be present +const bool malloc_proxy = true; +#else +const bool malloc_proxy = false; +#endif + +namespace rml { +namespace internal { + void init_tbbmalloc(); +} } // namespaces + +#define MALLOC_EXTRA_INITIALIZATION rml::internal::init_tbbmalloc() + +// Need these to work regardless of tools support. +namespace tbb { + namespace internal { + + enum notify_type {prepare=0, cancel, acquired, releasing}; + +#if TBB_USE_THREADING_TOOLS + inline void call_itt_notify(notify_type t, void *ptr) { + switch ( t ) { + case prepare: + MALLOC_ITT_SYNC_PREPARE( ptr ); + break; + case cancel: + MALLOC_ITT_SYNC_CANCEL( ptr ); + break; + case acquired: + MALLOC_ITT_SYNC_ACQUIRED( ptr ); + break; + case releasing: + MALLOC_ITT_SYNC_RELEASING( ptr ); + break; + } + } +#else + inline void call_itt_notify(notify_type /*t*/, void * /*ptr*/) {} +#endif // TBB_USE_THREADING_TOOLS + + template <typename T> + inline void itt_store_word_with_release(T& dst, T src) { +#if TBB_USE_THREADING_TOOLS + call_itt_notify(releasing, &dst); +#endif // TBB_USE_THREADING_TOOLS + FencedStore(*(intptr_t*)&dst, src); + } + + template <typename T> + inline T itt_load_word_with_acquire(T& src) { + T result = FencedLoad(*(intptr_t*)&src); +#if TBB_USE_THREADING_TOOLS + call_itt_notify(acquired, &src); +#endif // TBB_USE_THREADING_TOOLS + return result; + + } + } // namespace internal +} // namespace tbb + +#include "tbb/internal/_aggregator_impl.h" + +template <typename OperationType> +struct MallocAggregator { + typedef tbb::internal::aggregator_generic<OperationType> type; +}; + +//! aggregated_operation base class +template <typename Derived> +struct MallocAggregatedOperation { + typedef tbb::internal::aggregated_operation<Derived> type; +}; + +#endif /* _TBB_malloc_Customize_H_ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/MapMemory.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/MapMemory.h new file mode 100644 index 00000000..bb0a109b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/MapMemory.h @@ -0,0 +1,205 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _itt_shared_malloc_MapMemory_H +#define _itt_shared_malloc_MapMemory_H + +#include <stdlib.h> + +void *ErrnoPreservingMalloc(size_t bytes) +{ + int prevErrno = errno; + void *ret = malloc( bytes ); + if (!ret) + errno = prevErrno; + return ret; +} + +#if __linux__ || __APPLE__ || __sun || __FreeBSD__ + +#if __sun && !defined(_XPG4_2) + // To have void* as mmap's 1st argument + #define _XPG4_2 1 + #define XPG4_WAS_DEFINED 1 +#endif + +#include <sys/mman.h> +#if __linux__ +/* __TBB_MAP_HUGETLB is MAP_HUGETLB from system header linux/mman.h. + The header is not included here, as on some Linux flavors inclusion of + linux/mman.h leads to compilation error, + while changing of MAP_HUGETLB is highly unexpected. +*/ +#define __TBB_MAP_HUGETLB 0x40000 +#else +#define __TBB_MAP_HUGETLB 0 +#endif + +#if XPG4_WAS_DEFINED + #undef _XPG4_2 + #undef XPG4_WAS_DEFINED +#endif + +inline void* mmap_impl(size_t map_size, void* map_hint = NULL, int map_flags = 0) { +#ifndef MAP_ANONYMOUS +// macOS* defines MAP_ANON, which is deprecated in Linux*. +#define MAP_ANONYMOUS MAP_ANON +#endif /* MAP_ANONYMOUS */ + return mmap(map_hint, map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | map_flags, -1, 0); +} + +inline void* mmapTHP(size_t bytes) { + // Initializes in zero-initialized data section + static void* hint; + + // Optimistically try to use a last huge page aligned region end + // as a hint for mmap. + hint = hint ? (void*)((uintptr_t)hint - bytes) : hint; + void* result = mmap_impl(bytes, hint); + + // Something went wrong + if (result == MAP_FAILED) { + hint = NULL; + return MAP_FAILED; + } + + // Otherwise, fall back to the slow path - map oversized region + // and trim excess parts. + if (!isAligned(result, HUGE_PAGE_SIZE)) { + // Undo previous try + munmap(result, bytes); + + // Map oversized on huge page size region + result = mmap_impl(bytes + HUGE_PAGE_SIZE); + + // Something went wrong + if (result == MAP_FAILED) { + hint = NULL; + return MAP_FAILED; + } + + // Misalignment offset + uintptr_t offset = 0; + + if (!isAligned(result, HUGE_PAGE_SIZE)) { + // Trim excess head of a region if it is no aligned + offset = HUGE_PAGE_SIZE - ((uintptr_t)result & (HUGE_PAGE_SIZE - 1)); + munmap(result, offset); + + // New region beginning + result = (void*)((uintptr_t)result + offset); + } + + // Trim excess tail of a region + munmap((void*)((uintptr_t)result + bytes), HUGE_PAGE_SIZE - offset); + } + + // Assume, that mmap virtual addresses grow down by default + // So, set a hint as a result of a last successful allocation + // and then use it minus requested size as a new mapping point. + // TODO: Atomic store is meant here, fence not needed, but + // currently we don't have such function. + hint = result; + + MALLOC_ASSERT(isAligned(result, HUGE_PAGE_SIZE), "Mapped address is not aligned on huge page size."); + + return result; +} + +#define MEMORY_MAPPING_USES_MALLOC 0 +void* MapMemory (size_t bytes, PageType pageType) +{ + void* result = 0; + int prevErrno = errno; + + switch (pageType) { + case REGULAR: + { + result = mmap_impl(bytes); + break; + } + case PREALLOCATED_HUGE_PAGE: + { + MALLOC_ASSERT((bytes % HUGE_PAGE_SIZE) == 0, "Mapping size should be divisible by huge page size"); + result = mmap_impl(bytes, NULL, __TBB_MAP_HUGETLB); + break; + } + case TRANSPARENT_HUGE_PAGE: + { + MALLOC_ASSERT((bytes % HUGE_PAGE_SIZE) == 0, "Mapping size should be divisible by huge page size"); + result = mmapTHP(bytes); + break; + } + default: + { + MALLOC_ASSERT(false, "Unknown page type"); + } + } + + if (result == MAP_FAILED) { + errno = prevErrno; + return 0; + } + + return result; +} + +int UnmapMemory(void *area, size_t bytes) +{ + int prevErrno = errno; + int ret = munmap(area, bytes); + if (-1 == ret) + errno = prevErrno; + return ret; +} + +#elif (_WIN32 || _WIN64) && !__TBB_WIN8UI_SUPPORT +#include <windows.h> + +#define MEMORY_MAPPING_USES_MALLOC 0 +void* MapMemory (size_t bytes, PageType) +{ + /* Is VirtualAlloc thread safe? */ + return VirtualAlloc(NULL, bytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); +} + +int UnmapMemory(void *area, size_t /*bytes*/) +{ + BOOL result = VirtualFree(area, 0, MEM_RELEASE); + return !result; +} + +#else + +#define MEMORY_MAPPING_USES_MALLOC 1 +void* MapMemory (size_t bytes, PageType) +{ + return ErrnoPreservingMalloc( bytes ); +} + +int UnmapMemory(void *area, size_t /*bytes*/) +{ + free( area ); + return 0; +} + +#endif /* OS dependent */ + +#if MALLOC_CHECK_RECURSION && MEMORY_MAPPING_USES_MALLOC +#error Impossible to protect against malloc recursion when memory mapping uses malloc. +#endif + +#endif /* _itt_shared_malloc_MapMemory_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Statistics.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Statistics.h new file mode 100644 index 00000000..09fc9c56 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Statistics.h @@ -0,0 +1,125 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define MAX_THREADS 1024 +#define NUM_OF_BINS 30 +#define ThreadCommonCounters NUM_OF_BINS + +enum counter_type { + allocBlockNew = 0, + allocBlockPublic, + allocBumpPtrUsed, + allocFreeListUsed, + allocPrivatized, + examineEmptyEnough, + examineNotEmpty, + freeRestoreBumpPtr, + freeByOtherThread, + freeToActiveBlock, + freeToInactiveBlock, + freeBlockPublic, + freeBlockBack, + MaxCounters +}; +enum common_counter_type { + allocNewLargeObj = 0, + allocCachedLargeObj, + cacheLargeObj, + freeLargeObj, + lockPublicFreeList, + freeToOtherThread +}; + +#if COLLECT_STATISTICS +/* Statistics reporting callback registered via a static object dtor + on Posix or DLL_PROCESS_DETACH on Windows. + */ + +static bool reportAllocationStatistics; + +struct bin_counters { + int counter[MaxCounters]; +}; + +static bin_counters statistic[MAX_THREADS][NUM_OF_BINS+1]; //zero-initialized; + +static inline int STAT_increment(int thread, int bin, int ctr) +{ + return reportAllocationStatistics && thread < MAX_THREADS ? ++(statistic[thread][bin].counter[ctr]) : 0; +} + +static inline void initStatisticsCollection() { +#if defined(MALLOCENV_COLLECT_STATISTICS) + if (NULL != getenv(MALLOCENV_COLLECT_STATISTICS)) + reportAllocationStatistics = true; +#endif +} + +#else +#define STAT_increment(a,b,c) ((void)0) +#endif /* COLLECT_STATISTICS */ + +#if COLLECT_STATISTICS +static inline void STAT_print(int thread) +{ + if (!reportAllocationStatistics) + return; + + char filename[100]; +#if USE_PTHREAD + sprintf(filename, "stat_ScalableMalloc_proc%04d_thr%04d.log", getpid(), thread); +#else + sprintf(filename, "stat_ScalableMalloc_thr%04d.log", thread); +#endif + FILE* outfile = fopen(filename, "w"); + for(int i=0; i<NUM_OF_BINS; ++i) + { + bin_counters& ctrs = statistic[thread][i]; + fprintf(outfile, "Thr%04d Bin%02d", thread, i); + fprintf(outfile, ": allocNewBlocks %5d", ctrs.counter[allocBlockNew]); + fprintf(outfile, ", allocPublicBlocks %5d", ctrs.counter[allocBlockPublic]); + fprintf(outfile, ", restoreBumpPtr %5d", ctrs.counter[freeRestoreBumpPtr]); + fprintf(outfile, ", privatizeCalled %10d", ctrs.counter[allocPrivatized]); + fprintf(outfile, ", emptyEnough %10d", ctrs.counter[examineEmptyEnough]); + fprintf(outfile, ", notEmptyEnough %10d", ctrs.counter[examineNotEmpty]); + fprintf(outfile, ", freeBlocksPublic %5d", ctrs.counter[freeBlockPublic]); + fprintf(outfile, ", freeBlocksBack %5d", ctrs.counter[freeBlockBack]); + fprintf(outfile, "\n"); + } + for(int i=0; i<NUM_OF_BINS; ++i) + { + bin_counters& ctrs = statistic[thread][i]; + fprintf(outfile, "Thr%04d Bin%02d", thread, i); + fprintf(outfile, ": allocBumpPtr %10d", ctrs.counter[allocBumpPtrUsed]); + fprintf(outfile, ", allocFreeList %10d", ctrs.counter[allocFreeListUsed]); + fprintf(outfile, ", freeToActiveBlk %10d", ctrs.counter[freeToActiveBlock]); + fprintf(outfile, ", freeToInactive %10d", ctrs.counter[freeToInactiveBlock]); + fprintf(outfile, ", freedByOther %10d", ctrs.counter[freeByOtherThread]); + fprintf(outfile, "\n"); + } + bin_counters& ctrs = statistic[thread][ThreadCommonCounters]; + fprintf(outfile, "Thr%04d common counters", thread); + fprintf(outfile, ": allocNewLargeObject %5d", ctrs.counter[allocNewLargeObj]); + fprintf(outfile, ": allocCachedLargeObject %5d", ctrs.counter[allocCachedLargeObj]); + fprintf(outfile, ", cacheLargeObject %5d", ctrs.counter[cacheLargeObj]); + fprintf(outfile, ", freeLargeObject %5d", ctrs.counter[freeLargeObj]); + fprintf(outfile, ", lockPublicFreeList %5d", ctrs.counter[lockPublicFreeList]); + fprintf(outfile, ", freeToOtherThread %10d", ctrs.counter[freeToOtherThread]); + fprintf(outfile, "\n"); + + fclose(outfile); +} +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Synchronize.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Synchronize.h new file mode 100644 index 00000000..0d11a296 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/Synchronize.h @@ -0,0 +1,104 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_malloc_Synchronize_H_ +#define __TBB_malloc_Synchronize_H_ + +#include "tbb/tbb_machine.h" + +//! Stripped down version of spin_mutex. +/** Instances of MallocMutex must be declared in memory that is zero-initialized. + There are no constructors. This is a feature that lets it be + used in situations where the mutex might be used while file-scope constructors + are running. + + There are no methods "acquire" or "release". The scoped_lock must be used + in a strict block-scoped locking pattern. Omitting these methods permitted + further simplification. */ +class MallocMutex : tbb::internal::no_copy { + __TBB_atomic_flag flag; + +public: + class scoped_lock : tbb::internal::no_copy { + MallocMutex& mutex; + bool taken; + public: + scoped_lock( MallocMutex& m ) : mutex(m), taken(true) { __TBB_LockByte(m.flag); } + scoped_lock( MallocMutex& m, bool block, bool *locked ) : mutex(m), taken(false) { + if (block) { + __TBB_LockByte(m.flag); + taken = true; + } else { + taken = __TBB_TryLockByte(m.flag); + } + if (locked) *locked = taken; + } + ~scoped_lock() { + if (taken) __TBB_UnlockByte(mutex.flag); + } + }; + friend class scoped_lock; +}; + +// TODO: use signed/unsigned in atomics more consistently +inline intptr_t AtomicIncrement( volatile intptr_t& counter ) { + return __TBB_FetchAndAddW( &counter, 1 )+1; +} + +inline uintptr_t AtomicAdd( volatile intptr_t& counter, intptr_t value ) { + return __TBB_FetchAndAddW( &counter, value ); +} + +inline intptr_t AtomicCompareExchange( volatile intptr_t& location, intptr_t new_value, intptr_t comparand) { + return __TBB_CompareAndSwapW( &location, new_value, comparand ); +} + +inline uintptr_t AtomicFetchStore(volatile void* location, uintptr_t value) { + return __TBB_FetchAndStoreW(location, value); +} + +inline void AtomicOr(volatile void *operand, uintptr_t addend) { + __TBB_AtomicOR(operand, addend); +} + +inline void AtomicAnd(volatile void *operand, uintptr_t addend) { + __TBB_AtomicAND(operand, addend); +} + +inline intptr_t FencedLoad( const volatile intptr_t &location ) { + return __TBB_load_with_acquire(location); +} + +inline void FencedStore( volatile intptr_t &location, intptr_t value ) { + __TBB_store_with_release(location, value); +} + +inline void SpinWaitWhileEq(const volatile intptr_t &location, const intptr_t value) { + tbb::internal::spin_wait_while_eq(location, value); +} + +class AtomicBackoff { + tbb::internal::atomic_backoff backoff; +public: + AtomicBackoff() {} + void pause() { backoff.pause(); } +}; + +inline void SpinWaitUntilEq(const volatile intptr_t &location, const intptr_t value) { + tbb::internal::spin_wait_until_eq(location, value); +} + +#endif /* __TBB_malloc_Synchronize_H_ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/TypeDefinitions.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/TypeDefinitions.h new file mode 100644 index 00000000..aa6763b0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/TypeDefinitions.h @@ -0,0 +1,58 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _itt_shared_malloc_TypeDefinitions_H_ +#define _itt_shared_malloc_TypeDefinitions_H_ + +// Define preprocessor symbols used to determine architecture +#if _WIN32||_WIN64 +# if defined(_M_X64)||defined(__x86_64__) // the latter for MinGW support +# define __ARCH_x86_64 1 +# elif defined(_M_IA64) +# define __ARCH_ipf 1 +# elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support +# define __ARCH_x86_32 1 +# elif defined(_M_ARM) +# define __ARCH_other 1 +# else +# error Unknown processor architecture for Windows +# endif +# define USE_WINTHREAD 1 +#else /* Assume generic Unix */ +# if __x86_64__ +# define __ARCH_x86_64 1 +# elif __ia64__ +# define __ARCH_ipf 1 +# elif __i386__ || __i386 +# define __ARCH_x86_32 1 +# else +# define __ARCH_other 1 +# endif +# define USE_PTHREAD 1 +#endif + +// According to C99 standard INTPTR_MIN defined for C++ +// iff __STDC_LIMIT_MACROS pre-defined +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +//! PROVIDE YOUR OWN Customize.h IF YOU FEEL NECESSARY +#include "Customize.h" + +#include "shared_utils.h" + +#endif /* _itt_shared_malloc_TypeDefinitions_H_ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backend.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backend.cpp new file mode 100644 index 00000000..f78630f0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backend.cpp @@ -0,0 +1,1489 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <string.h> /* for memset */ +#include <errno.h> +#include "tbbmalloc_internal.h" + +namespace rml { +namespace internal { + +/*********** Code to acquire memory from the OS or other executive ****************/ + +/* + syscall/malloc can set non-zero errno in case of failure, + but later allocator might be able to find memory to fulfill the request. + And we do not want changing of errno by successful scalable_malloc call. + To support this, restore old errno in (get|free)RawMemory, and set errno + in frontend just before returning to user code. + Please note: every syscall/libc call used inside scalable_malloc that + sets errno must be protected this way, not just memory allocation per se. +*/ + +#if USE_DEFAULT_MEMORY_MAPPING +#include "MapMemory.h" +#else +/* assume MapMemory and UnmapMemory are customized */ +#endif + +void* getRawMemory (size_t size, PageType pageType) { + return MapMemory(size, pageType); +} + +int freeRawMemory (void *object, size_t size) { + return UnmapMemory(object, size); +} + +#if CHECK_ALLOCATION_RANGE + +void Backend::UsedAddressRange::registerAlloc(uintptr_t left, uintptr_t right) +{ + MallocMutex::scoped_lock lock(mutex); + if (left < leftBound) + leftBound = left; + if (right > rightBound) + rightBound = right; + MALLOC_ASSERT(leftBound, ASSERT_TEXT); + MALLOC_ASSERT(leftBound < rightBound, ASSERT_TEXT); + MALLOC_ASSERT(leftBound <= left && right <= rightBound, ASSERT_TEXT); +} + +void Backend::UsedAddressRange::registerFree(uintptr_t left, uintptr_t right) +{ + MallocMutex::scoped_lock lock(mutex); + if (leftBound == left) { + if (rightBound == right) { + leftBound = ADDRESS_UPPER_BOUND; + rightBound = 0; + } else + leftBound = right; + } else if (rightBound == right) + rightBound = left; + MALLOC_ASSERT((!rightBound && leftBound == ADDRESS_UPPER_BOUND) + || leftBound < rightBound, ASSERT_TEXT); +} +#endif // CHECK_ALLOCATION_RANGE + +// Initialized in frontend inside defaultMemPool +extern HugePagesStatus hugePages; + +void *Backend::allocRawMem(size_t &size) +{ + void *res = NULL; + size_t allocSize = 0; + + if (extMemPool->userPool()) { + if (extMemPool->fixedPool && bootsrapMemDone == FencedLoad(bootsrapMemStatus)) + return NULL; + MALLOC_ASSERT(bootsrapMemStatus != bootsrapMemNotDone, + "Backend::allocRawMem() called prematurely?"); + // TODO: support for raw mem not aligned at sizeof(uintptr_t) + // memory from fixed pool is asked once and only once + allocSize = alignUpGeneric(size, extMemPool->granularity); + res = (*extMemPool->rawAlloc)(extMemPool->poolId, allocSize); + } else { + // Align allocation on page size + size_t pageSize = hugePages.isEnabled ? hugePages.getGranularity() : extMemPool->granularity; + MALLOC_ASSERT(pageSize, "Page size cannot be zero."); + allocSize = alignUpGeneric(size, pageSize); + + // If user requested huge pages and they are available, try to use preallocated ones firstly. + // If there are none, lets check transparent huge pages support and use them instead. + if (hugePages.isEnabled) { + if (hugePages.isHPAvailable) { + res = getRawMemory(allocSize, PREALLOCATED_HUGE_PAGE); + } + if (!res && hugePages.isTHPAvailable) { + res = getRawMemory(allocSize, TRANSPARENT_HUGE_PAGE); + } + } + + if (!res) { + res = getRawMemory(allocSize, REGULAR); + } + } + + if (res) { + MALLOC_ASSERT(allocSize > 0, "Invalid size of an allocated region."); + size = allocSize; + if (!extMemPool->userPool()) + usedAddrRange.registerAlloc((uintptr_t)res, (uintptr_t)res+size); +#if MALLOC_DEBUG + volatile size_t curTotalSize = totalMemSize; // to read global value once + MALLOC_ASSERT(curTotalSize+size > curTotalSize, "Overflow allocation size."); +#endif + AtomicAdd((intptr_t&)totalMemSize, size); + } + + return res; +} + +bool Backend::freeRawMem(void *object, size_t size) +{ + bool fail; +#if MALLOC_DEBUG + volatile size_t curTotalSize = totalMemSize; // to read global value once + MALLOC_ASSERT(curTotalSize-size < curTotalSize, "Negative allocation size."); +#endif + AtomicAdd((intptr_t&)totalMemSize, -size); + if (extMemPool->userPool()) { + MALLOC_ASSERT(!extMemPool->fixedPool, "No free for fixed-size pools."); + fail = (*extMemPool->rawFree)(extMemPool->poolId, object, size); + } else { + usedAddrRange.registerFree((uintptr_t)object, (uintptr_t)object + size); + fail = freeRawMemory(object, size); + } + // TODO: use result in all freeRawMem() callers + return !fail; +} + +/********* End memory acquisition code ********************************/ + +// Protected object size. After successful locking returns size of locked block, +// and releasing requires setting block size. +class GuardedSize : tbb::internal::no_copy { + uintptr_t value; +public: + enum State { + LOCKED, + COAL_BLOCK, // block is coalescing now + MAX_LOCKED_VAL = COAL_BLOCK, + LAST_REGION_BLOCK, // used to mark last block in region + // values after this are "normal" block sizes + MAX_SPEC_VAL = LAST_REGION_BLOCK + }; + + void initLocked() { value = LOCKED; } + void makeCoalscing() { + MALLOC_ASSERT(value == LOCKED, ASSERT_TEXT); + value = COAL_BLOCK; + } + size_t tryLock(State state) { + size_t szVal, sz; + MALLOC_ASSERT(state <= MAX_LOCKED_VAL, ASSERT_TEXT); + for (;;) { + sz = FencedLoad((intptr_t&)value); + if (sz <= MAX_LOCKED_VAL) + break; + szVal = AtomicCompareExchange((intptr_t&)value, state, sz); + + if (szVal==sz) + break; + } + return sz; + } + void unlock(size_t size) { + MALLOC_ASSERT(value <= MAX_LOCKED_VAL, "The lock is not locked"); + MALLOC_ASSERT(size > MAX_LOCKED_VAL, ASSERT_TEXT); + FencedStore((intptr_t&)value, size); + } + bool isLastRegionBlock() const { return value==LAST_REGION_BLOCK; } + friend void Backend::IndexedBins::verify(); +}; + +struct MemRegion { + MemRegion *next, // keep all regions in any pool to release all them on + *prev; // pool destroying, 2-linked list to release individual + // regions. + size_t allocSz, // got from pool callback + blockSz; // initial and maximal inner block size + MemRegionType type; +}; + +// this data must be unmodified while block is in use, so separate it +class BlockMutexes { +protected: + GuardedSize myL, // lock for me + leftL; // lock for left neighbor +}; + +class FreeBlock : BlockMutexes { +public: + static const size_t minBlockSize; + friend void Backend::IndexedBins::verify(); + + FreeBlock *prev, // in 2-linked list related to bin + *next, + *nextToFree; // used to form a queue during coalescing + // valid only when block is in processing, i.e. one is not free and not + size_t sizeTmp; // used outside of backend + int myBin; // bin that is owner of the block + bool slabAligned; + bool blockInBin; // this block in myBin already + + FreeBlock *rightNeig(size_t sz) const { + MALLOC_ASSERT(sz, ASSERT_TEXT); + return (FreeBlock*)((uintptr_t)this+sz); + } + FreeBlock *leftNeig(size_t sz) const { + MALLOC_ASSERT(sz, ASSERT_TEXT); + return (FreeBlock*)((uintptr_t)this - sz); + } + + void initHeader() { myL.initLocked(); leftL.initLocked(); } + void setMeFree(size_t size) { myL.unlock(size); } + size_t trySetMeUsed(GuardedSize::State s) { return myL.tryLock(s); } + bool isLastRegionBlock() const { return myL.isLastRegionBlock(); } + + void setLeftFree(size_t sz) { leftL.unlock(sz); } + size_t trySetLeftUsed(GuardedSize::State s) { return leftL.tryLock(s); } + + size_t tryLockBlock() { + size_t rSz, sz = trySetMeUsed(GuardedSize::LOCKED); + + if (sz <= GuardedSize::MAX_LOCKED_VAL) + return false; + rSz = rightNeig(sz)->trySetLeftUsed(GuardedSize::LOCKED); + if (rSz <= GuardedSize::MAX_LOCKED_VAL) { + setMeFree(sz); + return false; + } + MALLOC_ASSERT(rSz == sz, ASSERT_TEXT); + return sz; + } + void markCoalescing(size_t blockSz) { + myL.makeCoalscing(); + rightNeig(blockSz)->leftL.makeCoalscing(); + sizeTmp = blockSz; + nextToFree = NULL; + } + void markUsed() { + myL.initLocked(); + rightNeig(sizeTmp)->leftL.initLocked(); + nextToFree = NULL; + } + static void markBlocks(FreeBlock *fBlock, int num, size_t size) { + for (int i=1; i<num; i++) { + fBlock = (FreeBlock*)((uintptr_t)fBlock + size); + fBlock->initHeader(); + } + } +}; + +// Last block in any region. Its "size" field is GuardedSize::LAST_REGION_BLOCK, +// This kind of blocks used to find region header +// and have a possibility to return region back to OS +struct LastFreeBlock : public FreeBlock { + MemRegion *memRegion; +}; + +const size_t FreeBlock::minBlockSize = sizeof(FreeBlock); + +inline bool BackendSync::waitTillBlockReleased(intptr_t startModifiedCnt) +{ + AtomicBackoff backoff; +#if __TBB_MALLOC_BACKEND_STAT + class ITT_Guard { + void *ptr; + public: + ITT_Guard(void *p) : ptr(p) { + MALLOC_ITT_SYNC_PREPARE(ptr); + } + ~ITT_Guard() { + MALLOC_ITT_SYNC_ACQUIRED(ptr); + } + }; + ITT_Guard ittGuard(&inFlyBlocks); +#endif + for (intptr_t myBinsInFlyBlocks = FencedLoad(inFlyBlocks), + myCoalescQInFlyBlocks = backend->blocksInCoalescing(); ; + backoff.pause()) { + MALLOC_ASSERT(myBinsInFlyBlocks>=0 && myCoalescQInFlyBlocks>=0, NULL); + intptr_t currBinsInFlyBlocks = FencedLoad(inFlyBlocks), + currCoalescQInFlyBlocks = backend->blocksInCoalescing(); + WhiteboxTestingYield(); + // Stop waiting iff: + + // 1) blocks were removed from processing, not added + if (myBinsInFlyBlocks > currBinsInFlyBlocks + // 2) released during delayed coalescing queue + || myCoalescQInFlyBlocks > currCoalescQInFlyBlocks) + break; + // 3) if there are blocks in coalescing, and no progress in its processing, + // try to scan coalescing queue and stop waiting, if changes were made + // (if there are no changes and in-fly blocks exist, we continue + // waiting to not increase load on coalescQ) + if (currCoalescQInFlyBlocks > 0 && backend->scanCoalescQ(/*forceCoalescQDrop=*/false)) + break; + // 4) when there are no blocks + if (!currBinsInFlyBlocks && !currCoalescQInFlyBlocks) + // re-scan make sense only if bins were modified since scanned + return startModifiedCnt != getNumOfMods(); + myBinsInFlyBlocks = currBinsInFlyBlocks; + myCoalescQInFlyBlocks = currCoalescQInFlyBlocks; + } + return true; +} + +void CoalRequestQ::putBlock(FreeBlock *fBlock) +{ + MALLOC_ASSERT(fBlock->sizeTmp >= FreeBlock::minBlockSize, ASSERT_TEXT); + fBlock->markUsed(); + // the block is in the queue, do not forget that it's here + AtomicIncrement(inFlyBlocks); + + for (;;) { + FreeBlock *myBlToFree = (FreeBlock*)FencedLoad((intptr_t&)blocksToFree); + + fBlock->nextToFree = myBlToFree; + if (myBlToFree == + (FreeBlock*)AtomicCompareExchange((intptr_t&)blocksToFree, + (intptr_t)fBlock, + (intptr_t)myBlToFree)) + return; + } +} + +FreeBlock *CoalRequestQ::getAll() +{ + for (;;) { + FreeBlock *myBlToFree = (FreeBlock*)FencedLoad((intptr_t&)blocksToFree); + + if (!myBlToFree) + return NULL; + else { + if (myBlToFree == + (FreeBlock*)AtomicCompareExchange((intptr_t&)blocksToFree, + 0, (intptr_t)myBlToFree)) + return myBlToFree; + else + continue; + } + } +} + +inline void CoalRequestQ::blockWasProcessed() +{ + bkndSync->binsModified(); + int prev = AtomicAdd(inFlyBlocks, -1); + MALLOC_ASSERT(prev > 0, ASSERT_TEXT); +} + +// Try to get a block from a bin. +// If the remaining free space would stay in the same bin, +// split the block without removing it. +// If the free space should go to other bin(s), remove the block. +// alignedBin is true, if all blocks in the bin have slab-aligned right side. +FreeBlock *Backend::IndexedBins::getFromBin(int binIdx, BackendSync *sync, size_t size, + bool needAlignedRes, bool alignedBin, bool wait, int *binLocked) +{ + Bin *b = &freeBins[binIdx]; +try_next: + FreeBlock *fBlock = NULL; + if (b->head) { + bool locked; + MallocMutex::scoped_lock scopedLock(b->tLock, wait, &locked); + + if (!locked) { + if (binLocked) (*binLocked)++; + return NULL; + } + + for (FreeBlock *curr = b->head; curr; curr = curr->next) { + size_t szBlock = curr->tryLockBlock(); + if (!szBlock) { + // block is locked, re-do bin lock, as there is no place to spin + // while block coalescing + goto try_next; + } + + // GENERAL CASE + if (alignedBin || !needAlignedRes) { + size_t splitSz = szBlock - size; + // If we got a block as split result, it must have a room for control structures. + if (szBlock >= size && (splitSz >= FreeBlock::minBlockSize || !splitSz)) + fBlock = curr; + } else { + // SPECIAL CASE, to get aligned block from unaligned bin we have to cut the middle of a block + // and return remaining left and right part. Possible only in fixed pool scenario, assert for this + // is set inside splitBlock() function. + + void *newB = alignUp(curr, slabSize); + uintptr_t rightNew = (uintptr_t)newB + size; + uintptr_t rightCurr = (uintptr_t)curr + szBlock; + // Check if the block size is sufficient, + // and also left and right split results are either big enough or non-existent + if (rightNew <= rightCurr + && (newB == curr || ((uintptr_t)newB - (uintptr_t)curr) >= FreeBlock::minBlockSize) + && (rightNew == rightCurr || (rightCurr - rightNew) >= FreeBlock::minBlockSize)) + fBlock = curr; + } + + if (fBlock) { + // consume must be called before result of removing from a bin is visible externally. + sync->blockConsumed(); + // TODO: think about cases when block stays in the same bin + b->removeBlock(fBlock); + if (freeBins[binIdx].empty()) + bitMask.set(binIdx, false); + fBlock->sizeTmp = szBlock; + break; + } else { // block size is not valid, search for next block in the bin + curr->setMeFree(szBlock); + curr->rightNeig(szBlock)->setLeftFree(szBlock); + } + } + } + return fBlock; +} + +bool Backend::IndexedBins::tryReleaseRegions(int binIdx, Backend *backend) +{ + Bin *b = &freeBins[binIdx]; + FreeBlock *fBlockList = NULL; + + // got all blocks from the bin and re-do coalesce on them + // to release single-block regions +try_next: + if (b->head) { + MallocMutex::scoped_lock binLock(b->tLock); + for (FreeBlock *curr = b->head; curr; ) { + size_t szBlock = curr->tryLockBlock(); + if (!szBlock) + goto try_next; + + FreeBlock *next = curr->next; + + b->removeBlock(curr); + curr->sizeTmp = szBlock; + curr->nextToFree = fBlockList; + fBlockList = curr; + curr = next; + } + } + return backend->coalescAndPutList(fBlockList, /*forceCoalescQDrop=*/true, + /*reportBlocksProcessed=*/false); +} + +void Backend::Bin::removeBlock(FreeBlock *fBlock) +{ + MALLOC_ASSERT(fBlock->next||fBlock->prev||fBlock==head, + "Detected that a block is not in the bin."); + if (head == fBlock) + head = fBlock->next; + if (tail == fBlock) + tail = fBlock->prev; + if (fBlock->prev) + fBlock->prev->next = fBlock->next; + if (fBlock->next) + fBlock->next->prev = fBlock->prev; +} + +void Backend::IndexedBins::addBlock(int binIdx, FreeBlock *fBlock, size_t blockSz, bool addToTail) +{ + Bin *b = &freeBins[binIdx]; + fBlock->myBin = binIdx; + fBlock->next = fBlock->prev = NULL; + { + MallocMutex::scoped_lock scopedLock(b->tLock); + if (addToTail) { + fBlock->prev = b->tail; + b->tail = fBlock; + if (fBlock->prev) + fBlock->prev->next = fBlock; + if (!b->head) + b->head = fBlock; + } else { + fBlock->next = b->head; + b->head = fBlock; + if (fBlock->next) + fBlock->next->prev = fBlock; + if (!b->tail) + b->tail = fBlock; + } + } + bitMask.set(binIdx, true); +} + +bool Backend::IndexedBins::tryAddBlock(int binIdx, FreeBlock *fBlock, bool addToTail) +{ + bool locked; + Bin *b = &freeBins[binIdx]; + fBlock->myBin = binIdx; + if (addToTail) { + fBlock->next = NULL; + { + MallocMutex::scoped_lock scopedLock(b->tLock, /*wait=*/false, &locked); + if (!locked) + return false; + fBlock->prev = b->tail; + b->tail = fBlock; + if (fBlock->prev) + fBlock->prev->next = fBlock; + if (!b->head) + b->head = fBlock; + } + } else { + fBlock->prev = NULL; + { + MallocMutex::scoped_lock scopedLock(b->tLock, /*wait=*/false, &locked); + if (!locked) + return false; + fBlock->next = b->head; + b->head = fBlock; + if (fBlock->next) + fBlock->next->prev = fBlock; + if (!b->tail) + b->tail = fBlock; + } + } + bitMask.set(binIdx, true); + return true; +} + +void Backend::IndexedBins::reset() +{ + for (int i=0; i<Backend::freeBinsNum; i++) + freeBins[i].reset(); + bitMask.reset(); +} + +void Backend::IndexedBins::lockRemoveBlock(int binIdx, FreeBlock *fBlock) +{ + MallocMutex::scoped_lock scopedLock(freeBins[binIdx].tLock); + freeBins[binIdx].removeBlock(fBlock); + if (freeBins[binIdx].empty()) + bitMask.set(binIdx, false); +} + +bool ExtMemoryPool::regionsAreReleaseable() const +{ + return !keepAllMemory && !delayRegsReleasing; +} + +FreeBlock *Backend::splitBlock(FreeBlock *fBlock, int num, size_t size, bool blockIsAligned, bool needAlignedBlock) +{ + const size_t totalSize = num * size; + + // SPECIAL CASE, for unaligned block we have to cut the middle of a block + // and return remaining left and right part. Possible only in a fixed pool scenario. + if (needAlignedBlock && !blockIsAligned) { + MALLOC_ASSERT(extMemPool->fixedPool, + "Aligned block request from unaligned bin possible only in fixed pool scenario."); + + // Space to use is in the middle + FreeBlock *newBlock = alignUp(fBlock, slabSize); + FreeBlock *rightPart = (FreeBlock*)((uintptr_t)newBlock + totalSize); + uintptr_t fBlockEnd = (uintptr_t)fBlock + fBlock->sizeTmp; + + // Return free right part + if ((uintptr_t)rightPart != fBlockEnd) { + rightPart->initHeader(); // to prevent coalescing rightPart with fBlock + size_t rightSize = fBlockEnd - (uintptr_t)rightPart; + coalescAndPut(rightPart, rightSize, toAlignedBin(rightPart, rightSize)); + } + // And free left part + if (newBlock != fBlock) { + newBlock->initHeader(); // to prevent coalescing fBlock with newB + size_t leftSize = (uintptr_t)newBlock - (uintptr_t)fBlock; + coalescAndPut(fBlock, leftSize, toAlignedBin(fBlock, leftSize)); + } + fBlock = newBlock; + } else if (size_t splitSize = fBlock->sizeTmp - totalSize) { // need to split the block + // GENERAL CASE, cut the left or right part of the block + FreeBlock *splitBlock = NULL; + if (needAlignedBlock) { + // For slab aligned blocks cut the right side of the block + // and return it to a requester, original block returns to backend + splitBlock = fBlock; + fBlock = (FreeBlock*)((uintptr_t)splitBlock + splitSize); + fBlock->initHeader(); + } else { + // For large object blocks cut original block and put free righ part to backend + splitBlock = (FreeBlock*)((uintptr_t)fBlock + totalSize); + splitBlock->initHeader(); + } + // Mark free block as it`s parent only when the requested type (needAlignedBlock) + // and returned from Bins/OS block (isAligned) are equal (XOR operation used) + bool markAligned = (blockIsAligned ^ needAlignedBlock) ? toAlignedBin(splitBlock, splitSize) : blockIsAligned; + coalescAndPut(splitBlock, splitSize, markAligned); + } + MALLOC_ASSERT(!needAlignedBlock || isAligned(fBlock, slabSize), "Expect to get aligned block, if one was requested."); + FreeBlock::markBlocks(fBlock, num, size); + return fBlock; +} + +size_t Backend::getMaxBinnedSize() const +{ + return hugePages.isEnabled && !inUserPool() ? + maxBinned_HugePage : maxBinned_SmallPage; +} + +inline bool Backend::MaxRequestComparator::operator()(size_t oldMaxReq, size_t requestSize) const +{ + return requestSize > oldMaxReq && requestSize < backend->getMaxBinnedSize(); +} + +// last chance to get memory +FreeBlock *Backend::releaseMemInCaches(intptr_t startModifiedCnt, + int *lockedBinsThreshold, int numOfLockedBins) +{ + // something released from caches + if (extMemPool->hardCachesCleanup() + // ..or can use blocks that are in processing now + || bkndSync.waitTillBlockReleased(startModifiedCnt)) + return (FreeBlock*)VALID_BLOCK_IN_BIN; + // OS can't give us more memory, but we have some in locked bins + if (*lockedBinsThreshold && numOfLockedBins) { + *lockedBinsThreshold = 0; + return (FreeBlock*)VALID_BLOCK_IN_BIN; + } + return NULL; // nothing found, give up +} + +FreeBlock *Backend::askMemFromOS(size_t blockSize, intptr_t startModifiedCnt, + int *lockedBinsThreshold, int numOfLockedBins, + bool *splittableRet, bool needSlabRegion) +{ + FreeBlock *block; + // The block sizes can be divided into 3 groups: + // 1. "quite small": popular object size, we are in bootstarp or something + // like; request several regions. + // 2. "quite large": we want to have several such blocks in the region + // but not want several pre-allocated regions. + // 3. "huge": exact fit, we allocate only one block and do not allow + // any other allocations to placed in a region. + // Dividing the block sizes in these groups we are trying to balance between + // too small regions (that leads to fragmentation) and too large ones (that + // leads to excessive address space consumption). If a region is "too + // large", allocate only one, to prevent fragmentation. It supposedly + // doesn't hurt performance, because the object requested by user is large. + // Bounds for the groups are: + const size_t maxBinned = getMaxBinnedSize(); + const size_t quiteSmall = maxBinned / 8; + const size_t quiteLarge = maxBinned; + + if (blockSize >= quiteLarge) { + // Do not interact with other threads via semaphores, as for exact fit + // we can't share regions with them, memory requesting is individual. + block = addNewRegion(blockSize, MEMREG_ONE_BLOCK, /*addToBin=*/false); + if (!block) + return releaseMemInCaches(startModifiedCnt, lockedBinsThreshold, numOfLockedBins); + *splittableRet = false; + } else { + const size_t regSz_sizeBased = alignUp(4*maxRequestedSize, 1024*1024); + // Another thread is modifying backend while we can't get the block. + // Wait while it leaves and re-do the scan + // before trying other ways to extend the backend. + if (bkndSync.waitTillBlockReleased(startModifiedCnt) + // semaphore is protecting adding more more memory from OS + || memExtendingSema.wait()) + return (FreeBlock*)VALID_BLOCK_IN_BIN; + + if (startModifiedCnt != bkndSync.getNumOfMods()) { + memExtendingSema.signal(); + return (FreeBlock*)VALID_BLOCK_IN_BIN; + } + + if (blockSize < quiteSmall) { + // For this size of blocks, add NUM_OF_REG "advance" regions in bin, + // and return one as a result. + // TODO: add to bin first, because other threads can use them right away. + // This must be done carefully, because blocks in bins can be released + // in releaseCachesToLimit(). + const unsigned NUM_OF_REG = 3; + MemRegionType regType = needSlabRegion ? MEMREG_SLAB_BLOCKS : MEMREG_LARGE_BLOCKS; + block = addNewRegion(regSz_sizeBased, regType, /*addToBin=*/false); + if (block) + for (unsigned idx=0; idx<NUM_OF_REG; idx++) + if (! addNewRegion(regSz_sizeBased, regType, /*addToBin=*/true)) + break; + } else { + block = addNewRegion(regSz_sizeBased, MEMREG_LARGE_BLOCKS, /*addToBin=*/false); + } + memExtendingSema.signal(); + + // no regions found, try to clean cache + if (!block || block == (FreeBlock*)VALID_BLOCK_IN_BIN) + return releaseMemInCaches(startModifiedCnt, lockedBinsThreshold, numOfLockedBins); + // Since a region can hold more than one block it can be split. + *splittableRet = true; + } + // after asking memory from OS, release caches if we above the memory limits + releaseCachesToLimit(); + + return block; +} + +void Backend::releaseCachesToLimit() +{ + if (!memSoftLimit || totalMemSize <= memSoftLimit) + return; + size_t locTotalMemSize, locMemSoftLimit; + + scanCoalescQ(/*forceCoalescQDrop=*/false); + if (extMemPool->softCachesCleanup() && + (locTotalMemSize = FencedLoad((intptr_t&)totalMemSize)) <= + (locMemSoftLimit = FencedLoad((intptr_t&)memSoftLimit))) + return; + // clean global large-object cache, if this is not enough, clean local caches + // do this in several tries, because backend fragmentation can prevent + // region from releasing + for (int cleanLocal = 0; cleanLocal<2; cleanLocal++) + while (cleanLocal ? + extMemPool->allLocalCaches.cleanup(/*cleanOnlyUnused=*/true) : + extMemPool->loc.decreasingCleanup()) + if ((locTotalMemSize = FencedLoad((intptr_t&)totalMemSize)) <= + (locMemSoftLimit = FencedLoad((intptr_t&)memSoftLimit))) + return; + // last chance to match memSoftLimit + extMemPool->hardCachesCleanup(); +} + +int Backend::IndexedBins::getMinNonemptyBin(unsigned startBin) const +{ + int p = bitMask.getMinTrue(startBin); + return p == -1 ? Backend::freeBinsNum : p; +} + +FreeBlock *Backend::IndexedBins::findBlock(int nativeBin, BackendSync *sync, size_t size, + bool needAlignedBlock, bool alignedBin, int *numOfLockedBins) +{ + for (int i=getMinNonemptyBin(nativeBin); i<freeBinsNum; i=getMinNonemptyBin(i+1)) + if (FreeBlock *block = getFromBin(i, sync, size, needAlignedBlock, alignedBin, /*wait=*/false, numOfLockedBins)) + return block; + + return NULL; +} + +void Backend::requestBootstrapMem() +{ + if (bootsrapMemDone == FencedLoad(bootsrapMemStatus)) + return; + MallocMutex::scoped_lock lock( bootsrapMemStatusMutex ); + if (bootsrapMemDone == bootsrapMemStatus) + return; + MALLOC_ASSERT(bootsrapMemNotDone == bootsrapMemStatus, ASSERT_TEXT); + bootsrapMemStatus = bootsrapMemInitializing; + // request some rather big region during bootstrap in advance + // ok to get NULL here, as later we re-do a request with more modest size + addNewRegion(2*1024*1024, MEMREG_SLAB_BLOCKS, /*addToBin=*/true); + bootsrapMemStatus = bootsrapMemDone; +} + +// try to allocate size Byte block in available bins +// needAlignedRes is true if result must be slab-aligned +FreeBlock *Backend::genericGetBlock(int num, size_t size, bool needAlignedBlock) +{ + FreeBlock *block = NULL; + const size_t totalReqSize = num*size; + // no splitting after requesting new region, asks exact size + const int nativeBin = sizeToBin(totalReqSize); + + requestBootstrapMem(); + // If we found 2 or less locked bins, it's time to ask more memory from OS. + // But nothing can be asked from fixed pool. And we prefer wait, not ask + // for more memory, if block is quite large. + int lockedBinsThreshold = extMemPool->fixedPool || size>=maxBinned_SmallPage? 0 : 2; + + // Find maximal requested size limited by getMaxBinnedSize() + AtomicUpdate(maxRequestedSize, totalReqSize, MaxRequestComparator(this)); + scanCoalescQ(/*forceCoalescQDrop=*/false); + + bool splittable = true; + for (;;) { + const intptr_t startModifiedCnt = bkndSync.getNumOfMods(); + int numOfLockedBins; + + do { + numOfLockedBins = 0; + if (needAlignedBlock) { + block = freeSlabAlignedBins.findBlock(nativeBin, &bkndSync, num*size, needAlignedBlock, + /*alignedBin=*/true, &numOfLockedBins); + if (!block && extMemPool->fixedPool) + block = freeLargeBlockBins.findBlock(nativeBin, &bkndSync, num*size, needAlignedBlock, + /*alignedBin=*/false, &numOfLockedBins); + } else { + block = freeLargeBlockBins.findBlock(nativeBin, &bkndSync, num*size, needAlignedBlock, + /*alignedBin=*/false, &numOfLockedBins); + if (!block && extMemPool->fixedPool) + block = freeSlabAlignedBins.findBlock(nativeBin, &bkndSync, num*size, needAlignedBlock, + /*alignedBin=*/true, &numOfLockedBins); + } + } while (!block && numOfLockedBins>lockedBinsThreshold); + + if (block) + break; + + if (!(scanCoalescQ(/*forceCoalescQDrop=*/true) | extMemPool->softCachesCleanup())) { + // bins are not updated, + // only remaining possibility is to ask for more memory + block = askMemFromOS(totalReqSize, startModifiedCnt, &lockedBinsThreshold, + numOfLockedBins, &splittable, needAlignedBlock); + if (!block) + return NULL; + if (block != (FreeBlock*)VALID_BLOCK_IN_BIN) { + // size can be increased in askMemFromOS, that's why >= + MALLOC_ASSERT(block->sizeTmp >= size, ASSERT_TEXT); + break; + } + // valid block somewhere in bins, let's find it + block = NULL; + } + } + MALLOC_ASSERT(block, ASSERT_TEXT); + if (splittable) { + // At this point we have to be sure that slabAligned attribute describes the right block state + block = splitBlock(block, num, size, block->slabAligned, needAlignedBlock); + } + // matched blockConsumed() from startUseBlock() + bkndSync.blockReleased(); + + return block; +} + +LargeMemoryBlock *Backend::getLargeBlock(size_t size) +{ + LargeMemoryBlock *lmb = + (LargeMemoryBlock*)genericGetBlock(1, size, /*needAlignedRes=*/false); + if (lmb) { + lmb->unalignedSize = size; + if (extMemPool->userPool()) + extMemPool->lmbList.add(lmb); + } + return lmb; +} + +BlockI *Backend::getSlabBlock(int num) { + BlockI *b = (BlockI*)genericGetBlock(num, slabSize, /*slabAligned=*/true); + MALLOC_ASSERT(isAligned(b, slabSize), ASSERT_TEXT); + return b; +} + +void Backend::putSlabBlock(BlockI *block) { + genericPutBlock((FreeBlock *)block, slabSize, /*slabAligned=*/true); +} + +void *Backend::getBackRefSpace(size_t size, bool *rawMemUsed) +{ + // This block is released only at shutdown, so it can prevent + // a entire region releasing when it's received from the backend, + // so prefer getRawMemory using. + if (void *ret = getRawMemory(size, REGULAR)) { + *rawMemUsed = true; + return ret; + } + void *ret = genericGetBlock(1, size, /*needAlignedRes=*/false); + if (ret) *rawMemUsed = false; + return ret; +} + +void Backend::putBackRefSpace(void *b, size_t size, bool rawMemUsed) +{ + if (rawMemUsed) + freeRawMemory(b, size); + // ignore not raw mem, as it released on region releasing +} + +void Backend::removeBlockFromBin(FreeBlock *fBlock) +{ + if (fBlock->myBin != Backend::NO_BIN) { + if (fBlock->slabAligned) + freeSlabAlignedBins.lockRemoveBlock(fBlock->myBin, fBlock); + else + freeLargeBlockBins.lockRemoveBlock(fBlock->myBin, fBlock); + } +} + +void Backend::genericPutBlock(FreeBlock *fBlock, size_t blockSz, bool slabAligned) +{ + bkndSync.blockConsumed(); + coalescAndPut(fBlock, blockSz, slabAligned); + bkndSync.blockReleased(); +} + +void AllLargeBlocksList::add(LargeMemoryBlock *lmb) +{ + MallocMutex::scoped_lock scoped_cs(largeObjLock); + lmb->gPrev = NULL; + lmb->gNext = loHead; + if (lmb->gNext) + lmb->gNext->gPrev = lmb; + loHead = lmb; +} + +void AllLargeBlocksList::remove(LargeMemoryBlock *lmb) +{ + MallocMutex::scoped_lock scoped_cs(largeObjLock); + if (loHead == lmb) + loHead = lmb->gNext; + if (lmb->gNext) + lmb->gNext->gPrev = lmb->gPrev; + if (lmb->gPrev) + lmb->gPrev->gNext = lmb->gNext; +} + +void Backend::putLargeBlock(LargeMemoryBlock *lmb) +{ + if (extMemPool->userPool()) + extMemPool->lmbList.remove(lmb); + genericPutBlock((FreeBlock *)lmb, lmb->unalignedSize, false); +} + +void Backend::returnLargeObject(LargeMemoryBlock *lmb) +{ + removeBackRef(lmb->backRefIdx); + putLargeBlock(lmb); + STAT_increment(getThreadId(), ThreadCommonCounters, freeLargeObj); +} + +#if BACKEND_HAS_MREMAP +void *Backend::remap(void *ptr, size_t oldSize, size_t newSize, size_t alignment) +{ + // no remap for user pools and for object too small that living in bins + if (inUserPool() || min(oldSize, newSize)<maxBinned_SmallPage + // during remap, can't guarantee alignment more strict than current or + // more strict than page alignment + || !isAligned(ptr, alignment) || alignment>extMemPool->granularity) + return NULL; + const LargeMemoryBlock* lmbOld = ((LargeObjectHdr *)ptr - 1)->memoryBlock; + const size_t oldUnalignedSize = lmbOld->unalignedSize; + FreeBlock *oldFBlock = (FreeBlock *)lmbOld; + FreeBlock *right = oldFBlock->rightNeig(oldUnalignedSize); + // in every region only one block can have LAST_REGION_BLOCK on right, + // so don't need no synchronization + if (!right->isLastRegionBlock()) + return NULL; + + MemRegion *oldRegion = static_cast<LastFreeBlock*>(right)->memRegion; + MALLOC_ASSERT( oldRegion < ptr, ASSERT_TEXT ); + const size_t oldRegionSize = oldRegion->allocSz; + if (oldRegion->type != MEMREG_ONE_BLOCK) + return NULL; // we are not single in the region + const size_t userOffset = (uintptr_t)ptr - (uintptr_t)oldRegion; + const size_t alignedSize = LargeObjectCache::alignToBin(newSize + userOffset); + const size_t requestSize = + alignUp(sizeof(MemRegion) + alignedSize + sizeof(LastFreeBlock), extMemPool->granularity); + if (requestSize < alignedSize) // is wrapped around? + return NULL; + regionList.remove(oldRegion); + + void *ret = mremap(oldRegion, oldRegion->allocSz, requestSize, MREMAP_MAYMOVE); + if (MAP_FAILED == ret) { // can't remap, revert and leave + regionList.add(oldRegion); + return NULL; + } + MemRegion *region = (MemRegion*)ret; + MALLOC_ASSERT(region->type == MEMREG_ONE_BLOCK, ASSERT_TEXT); + region->allocSz = requestSize; + region->blockSz = alignedSize; + + FreeBlock *fBlock = (FreeBlock *)alignUp((uintptr_t)region + sizeof(MemRegion), + largeObjectAlignment); + + regionList.add(region); + startUseBlock(region, fBlock, /*addToBin=*/false); + MALLOC_ASSERT(fBlock->sizeTmp == region->blockSz, ASSERT_TEXT); + // matched blockConsumed() in startUseBlock(). + // TODO: get rid of useless pair blockConsumed()/blockReleased() + bkndSync.blockReleased(); + + // object must start at same offset from region's start + void *object = (void*)((uintptr_t)region + userOffset); + MALLOC_ASSERT(isAligned(object, alignment), ASSERT_TEXT); + LargeObjectHdr *header = (LargeObjectHdr*)object - 1; + setBackRef(header->backRefIdx, header); + + LargeMemoryBlock *lmb = (LargeMemoryBlock*)fBlock; + lmb->unalignedSize = region->blockSz; + lmb->objectSize = newSize; + lmb->backRefIdx = header->backRefIdx; + header->memoryBlock = lmb; + MALLOC_ASSERT((uintptr_t)lmb + lmb->unalignedSize >= + (uintptr_t)object + lmb->objectSize, "An object must fit to the block."); + + usedAddrRange.registerFree((uintptr_t)oldRegion, (uintptr_t)oldRegion + oldRegionSize); + usedAddrRange.registerAlloc((uintptr_t)region, (uintptr_t)region + requestSize); + AtomicAdd((intptr_t&)totalMemSize, region->allocSz - oldRegionSize); + + return object; +} +#endif /* BACKEND_HAS_MREMAP */ + +void Backend::releaseRegion(MemRegion *memRegion) +{ + regionList.remove(memRegion); + freeRawMem(memRegion, memRegion->allocSz); +} + +// coalesce fBlock with its neighborhood +FreeBlock *Backend::doCoalesc(FreeBlock *fBlock, MemRegion **mRegion) +{ + FreeBlock *resBlock = fBlock; + size_t resSize = fBlock->sizeTmp; + MemRegion *memRegion = NULL; + + fBlock->markCoalescing(resSize); + resBlock->blockInBin = false; + + // coalescing with left neighbor + size_t leftSz = fBlock->trySetLeftUsed(GuardedSize::COAL_BLOCK); + if (leftSz != GuardedSize::LOCKED) { + if (leftSz == GuardedSize::COAL_BLOCK) { + coalescQ.putBlock(fBlock); + return NULL; + } else { + FreeBlock *left = fBlock->leftNeig(leftSz); + size_t lSz = left->trySetMeUsed(GuardedSize::COAL_BLOCK); + if (lSz <= GuardedSize::MAX_LOCKED_VAL) { + fBlock->setLeftFree(leftSz); // rollback + coalescQ.putBlock(fBlock); + return NULL; + } else { + MALLOC_ASSERT(lSz == leftSz, "Invalid header"); + left->blockInBin = true; + resBlock = left; + resSize += leftSz; + resBlock->sizeTmp = resSize; + } + } + } + // coalescing with right neighbor + FreeBlock *right = fBlock->rightNeig(fBlock->sizeTmp); + size_t rightSz = right->trySetMeUsed(GuardedSize::COAL_BLOCK); + if (rightSz != GuardedSize::LOCKED) { + // LastFreeBlock is on the right side + if (GuardedSize::LAST_REGION_BLOCK == rightSz) { + right->setMeFree(GuardedSize::LAST_REGION_BLOCK); + memRegion = static_cast<LastFreeBlock*>(right)->memRegion; + } else if (GuardedSize::COAL_BLOCK == rightSz) { + if (resBlock->blockInBin) { + resBlock->blockInBin = false; + removeBlockFromBin(resBlock); + } + coalescQ.putBlock(resBlock); + return NULL; + } else { + size_t rSz = right->rightNeig(rightSz)-> + trySetLeftUsed(GuardedSize::COAL_BLOCK); + if (rSz <= GuardedSize::MAX_LOCKED_VAL) { + right->setMeFree(rightSz); // rollback + if (resBlock->blockInBin) { + resBlock->blockInBin = false; + removeBlockFromBin(resBlock); + } + coalescQ.putBlock(resBlock); + return NULL; + } else { + MALLOC_ASSERT(rSz == rightSz, "Invalid header"); + removeBlockFromBin(right); + resSize += rightSz; + + // Is LastFreeBlock on the right side of right? + FreeBlock *nextRight = right->rightNeig(rightSz); + size_t nextRightSz = nextRight-> + trySetMeUsed(GuardedSize::COAL_BLOCK); + if (nextRightSz > GuardedSize::MAX_LOCKED_VAL) { + if (nextRightSz == GuardedSize::LAST_REGION_BLOCK) + memRegion = static_cast<LastFreeBlock*>(nextRight)->memRegion; + + nextRight->setMeFree(nextRightSz); + } + } + } + } + if (memRegion) { + MALLOC_ASSERT((uintptr_t)memRegion + memRegion->allocSz >= + (uintptr_t)right + sizeof(LastFreeBlock), ASSERT_TEXT); + MALLOC_ASSERT((uintptr_t)memRegion < (uintptr_t)resBlock, ASSERT_TEXT); + *mRegion = memRegion; + } else + *mRegion = NULL; + resBlock->sizeTmp = resSize; + return resBlock; +} + +bool Backend::coalescAndPutList(FreeBlock *list, bool forceCoalescQDrop, bool reportBlocksProcessed) +{ + bool regionReleased = false; + + for (FreeBlock *helper; list; + list = helper, + // matches block enqueue in CoalRequestQ::putBlock() + reportBlocksProcessed? coalescQ.blockWasProcessed() : (void)0) { + MemRegion *memRegion; + bool addToTail = false; + + helper = list->nextToFree; + FreeBlock *toRet = doCoalesc(list, &memRegion); + if (!toRet) + continue; + + if (memRegion && memRegion->blockSz == toRet->sizeTmp + && !extMemPool->fixedPool) { + if (extMemPool->regionsAreReleaseable()) { + // release the region, because there is no used blocks in it + if (toRet->blockInBin) + removeBlockFromBin(toRet); + releaseRegion(memRegion); + regionReleased = true; + continue; + } else // add block from empty region to end of bin, + addToTail = true; // preserving for exact fit + } + size_t currSz = toRet->sizeTmp; + int bin = sizeToBin(currSz); + bool toAligned = extMemPool->fixedPool ? toAlignedBin(toRet, currSz) : toRet->slabAligned; + bool needAddToBin = true; + + if (toRet->blockInBin) { + // Does it stay in same bin? + if (toRet->myBin == bin && toRet->slabAligned == toAligned) + needAddToBin = false; + else { + toRet->blockInBin = false; + removeBlockFromBin(toRet); + } + } + + // Does not stay in same bin, or bin-less; add it + if (needAddToBin) { + toRet->prev = toRet->next = toRet->nextToFree = NULL; + toRet->myBin = NO_BIN; + toRet->slabAligned = toAligned; + + // If the block is too small to fit in any bin, keep it bin-less. + // It's not a leak because the block later can be coalesced. + if (currSz >= minBinnedSize) { + toRet->sizeTmp = currSz; + IndexedBins *target = toRet->slabAligned ? &freeSlabAlignedBins : &freeLargeBlockBins; + if (forceCoalescQDrop) { + target->addBlock(bin, toRet, toRet->sizeTmp, addToTail); + } else if (!target->tryAddBlock(bin, toRet, addToTail)) { + coalescQ.putBlock(toRet); + continue; + } + } + toRet->sizeTmp = 0; + } + // Free (possibly coalesced) free block. + // Adding to bin must be done before this point, + // because after a block is free it can be coalesced, and + // using its pointer became unsafe. + // Remember that coalescing is not done under any global lock. + toRet->setMeFree(currSz); + toRet->rightNeig(currSz)->setLeftFree(currSz); + } + return regionReleased; +} + +// Coalesce fBlock and add it back to a bin; +// processing delayed coalescing requests. +void Backend::coalescAndPut(FreeBlock *fBlock, size_t blockSz, bool slabAligned) +{ + fBlock->sizeTmp = blockSz; + fBlock->nextToFree = NULL; + fBlock->slabAligned = slabAligned; + + coalescAndPutList(fBlock, /*forceCoalescQDrop=*/false, /*reportBlocksProcessed=*/false); +} + +bool Backend::scanCoalescQ(bool forceCoalescQDrop) +{ + FreeBlock *currCoalescList = coalescQ.getAll(); + + if (currCoalescList) + // reportBlocksProcessed=true informs that the blocks leave coalescQ, + // matches blockConsumed() from CoalRequestQ::putBlock() + coalescAndPutList(currCoalescList, forceCoalescQDrop, + /*reportBlocksProcessed=*/true); + // returns status of coalescQ.getAll(), as an indication of possible changes in backend + // TODO: coalescAndPutList() may report is some new free blocks became available or not + return currCoalescList; +} + +FreeBlock *Backend::findBlockInRegion(MemRegion *region, size_t exactBlockSize) +{ + FreeBlock *fBlock; + size_t blockSz; + uintptr_t fBlockEnd, + lastFreeBlock = (uintptr_t)region + region->allocSz - sizeof(LastFreeBlock); + + MALLOC_STATIC_ASSERT(sizeof(LastFreeBlock) % sizeof(uintptr_t) == 0, + "Atomic applied on LastFreeBlock, and we put it at the end of region, that" + " is uintptr_t-aligned, so no unaligned atomic operations are possible."); + // right bound is slab-aligned, keep LastFreeBlock after it + if (region->type == MEMREG_SLAB_BLOCKS) { + fBlock = (FreeBlock *)alignUp((uintptr_t)region + sizeof(MemRegion), sizeof(uintptr_t)); + fBlockEnd = alignDown(lastFreeBlock, slabSize); + } else { + fBlock = (FreeBlock *)alignUp((uintptr_t)region + sizeof(MemRegion), largeObjectAlignment); + fBlockEnd = (uintptr_t)fBlock + exactBlockSize; + MALLOC_ASSERT(fBlockEnd <= lastFreeBlock, ASSERT_TEXT); + } + if (fBlockEnd <= (uintptr_t)fBlock) + return NULL; // allocSz is too small + blockSz = fBlockEnd - (uintptr_t)fBlock; + // TODO: extend getSlabBlock to support degradation, i.e. getting less blocks + // then requested, and then relax this check + // (now all or nothing is implemented, check according to this) + if (blockSz < numOfSlabAllocOnMiss*slabSize) + return NULL; + + region->blockSz = blockSz; + return fBlock; +} + +// startUseBlock may add the free block to a bin, the block can be used and +// even released after this, so the region must be added to regionList already +void Backend::startUseBlock(MemRegion *region, FreeBlock *fBlock, bool addToBin) +{ + size_t blockSz = region->blockSz; + fBlock->initHeader(); + fBlock->setMeFree(blockSz); + + LastFreeBlock *lastBl = static_cast<LastFreeBlock*>(fBlock->rightNeig(blockSz)); + // to not get unaligned atomics during LastFreeBlock access + MALLOC_ASSERT(isAligned(lastBl, sizeof(uintptr_t)), NULL); + lastBl->initHeader(); + lastBl->setMeFree(GuardedSize::LAST_REGION_BLOCK); + lastBl->setLeftFree(blockSz); + lastBl->myBin = NO_BIN; + lastBl->memRegion = region; + + if (addToBin) { + unsigned targetBin = sizeToBin(blockSz); + // during adding advance regions, register bin for a largest block in region + advRegBins.registerBin(targetBin); + if (region->type == MEMREG_SLAB_BLOCKS) { + fBlock->slabAligned = true; + freeSlabAlignedBins.addBlock(targetBin, fBlock, blockSz, /*addToTail=*/false); + } else { + fBlock->slabAligned = false; + freeLargeBlockBins.addBlock(targetBin, fBlock, blockSz, /*addToTail=*/false); + } + } else { + // to match with blockReleased() in genericGetBlock + bkndSync.blockConsumed(); + // Understand our alignment for correct splitBlock operation + fBlock->slabAligned = region->type == MEMREG_SLAB_BLOCKS ? true : false; + fBlock->sizeTmp = fBlock->tryLockBlock(); + MALLOC_ASSERT(fBlock->sizeTmp >= FreeBlock::minBlockSize, "Locking must be successful"); + } +} + +void MemRegionList::add(MemRegion *r) +{ + r->prev = NULL; + MallocMutex::scoped_lock lock(regionListLock); + r->next = head; + head = r; + if (head->next) + head->next->prev = head; +} + +void MemRegionList::remove(MemRegion *r) +{ + MallocMutex::scoped_lock lock(regionListLock); + if (head == r) + head = head->next; + if (r->next) + r->next->prev = r->prev; + if (r->prev) + r->prev->next = r->next; +} + +#if __TBB_MALLOC_BACKEND_STAT +int MemRegionList::reportStat(FILE *f) +{ + int regNum = 0; + MallocMutex::scoped_lock lock(regionListLock); + for (MemRegion *curr = head; curr; curr = curr->next) { + fprintf(f, "%p: max block %lu B, ", curr, curr->blockSz); + regNum++; + } + return regNum; +} +#endif + +FreeBlock *Backend::addNewRegion(size_t size, MemRegionType memRegType, bool addToBin) +{ + MALLOC_STATIC_ASSERT(sizeof(BlockMutexes) <= sizeof(BlockI), + "Header must be not overwritten in used blocks"); + MALLOC_ASSERT(FreeBlock::minBlockSize > GuardedSize::MAX_SPEC_VAL, + "Block length must not conflict with special values of GuardedSize"); + // If the region is not "for slabs" we should reserve some space for + // a region header, the worst case alignment and the last block mark. + const size_t requestSize = memRegType == MEMREG_SLAB_BLOCKS ? size : + size + sizeof(MemRegion) + largeObjectAlignment + + FreeBlock::minBlockSize + sizeof(LastFreeBlock); + + size_t rawSize = requestSize; + MemRegion *region = (MemRegion*)allocRawMem(rawSize); + if (!region) { + MALLOC_ASSERT(rawSize==requestSize, "getRawMem has not allocated memory but changed the allocated size."); + return NULL; + } + if (rawSize < sizeof(MemRegion)) { + if (!extMemPool->fixedPool) + freeRawMem(region, rawSize); + return NULL; + } + + region->type = memRegType; + region->allocSz = rawSize; + FreeBlock *fBlock = findBlockInRegion(region, size); + if (!fBlock) { + if (!extMemPool->fixedPool) + freeRawMem(region, rawSize); + return NULL; + } + regionList.add(region); + startUseBlock(region, fBlock, addToBin); + bkndSync.binsModified(); + return addToBin? (FreeBlock*)VALID_BLOCK_IN_BIN : fBlock; +} + +void Backend::init(ExtMemoryPool *extMemoryPool) +{ + extMemPool = extMemoryPool; + usedAddrRange.init(); + coalescQ.init(&bkndSync); + bkndSync.init(this); +} + +void Backend::reset() +{ + MALLOC_ASSERT(extMemPool->userPool(), "Only user pool can be reset."); + // no active threads are allowed in backend while reset() called + verify(); + + freeLargeBlockBins.reset(); + freeSlabAlignedBins.reset(); + advRegBins.reset(); + + for (MemRegion *curr = regionList.head; curr; curr = curr->next) { + FreeBlock *fBlock = findBlockInRegion(curr, curr->blockSz); + MALLOC_ASSERT(fBlock, "A memory region unexpectedly got smaller"); + startUseBlock(curr, fBlock, /*addToBin=*/true); + } +} + +bool Backend::destroy() +{ + bool noError = true; + // no active threads are allowed in backend while destroy() called + verify(); + if (!inUserPool()) { + freeLargeBlockBins.reset(); + freeSlabAlignedBins.reset(); + } + while (regionList.head) { + MemRegion *helper = regionList.head->next; + noError &= freeRawMem(regionList.head, regionList.head->allocSz); + regionList.head = helper; + } + return noError; +} + +bool Backend::clean() +{ + scanCoalescQ(/*forceCoalescQDrop=*/false); + + bool res = false; + // We can have several blocks occupying a whole region, + // because such regions are added in advance (see askMemFromOS() and reset()), + // and never used. Release them all. + for (int i = advRegBins.getMinUsedBin(0); i != -1; i = advRegBins.getMinUsedBin(i+1)) { + if (i == freeSlabAlignedBins.getMinNonemptyBin(i)) + res |= freeSlabAlignedBins.tryReleaseRegions(i, this); + if (i == freeLargeBlockBins.getMinNonemptyBin(i)) + res |= freeLargeBlockBins.tryReleaseRegions(i, this); + } + + return res; +} + +void Backend::IndexedBins::verify() +{ + for (int i=0; i<freeBinsNum; i++) { + for (FreeBlock *fb = freeBins[i].head; fb; fb=fb->next) { + uintptr_t mySz = fb->myL.value; + MALLOC_ASSERT(mySz>GuardedSize::MAX_SPEC_VAL, ASSERT_TEXT); + FreeBlock *right = (FreeBlock*)((uintptr_t)fb + mySz); + suppress_unused_warning(right); + MALLOC_ASSERT(right->myL.value<=GuardedSize::MAX_SPEC_VAL, ASSERT_TEXT); + MALLOC_ASSERT(right->leftL.value==mySz, ASSERT_TEXT); + MALLOC_ASSERT(fb->leftL.value<=GuardedSize::MAX_SPEC_VAL, ASSERT_TEXT); + } + } +} + +// For correct operation, it must be called when no other threads +// is changing backend. +void Backend::verify() +{ +#if MALLOC_DEBUG + scanCoalescQ(/*forceCoalescQDrop=*/false); + + freeLargeBlockBins.verify(); + freeSlabAlignedBins.verify(); +#endif // MALLOC_DEBUG +} + +#if __TBB_MALLOC_BACKEND_STAT +size_t Backend::Bin::countFreeBlocks() +{ + size_t cnt = 0; + { + MallocMutex::scoped_lock lock(tLock); + for (FreeBlock *fb = head; fb; fb = fb->next) + cnt++; + } + return cnt; +} + +size_t Backend::Bin::reportFreeBlocks(FILE *f) +{ + size_t totalSz = 0; + MallocMutex::scoped_lock lock(tLock); + for (FreeBlock *fb = head; fb; fb = fb->next) { + size_t sz = fb->tryLockBlock(); + fb->setMeFree(sz); + fprintf(f, " [%p;%p]", fb, (void*)((uintptr_t)fb+sz)); + totalSz += sz; + } + return totalSz; +} + +void Backend::IndexedBins::reportStat(FILE *f) +{ + size_t totalSize = 0; + + for (int i=0; i<Backend::freeBinsNum; i++) + if (size_t cnt = freeBins[i].countFreeBlocks()) { + totalSize += freeBins[i].reportFreeBlocks(f); + fprintf(f, " %d:%lu, ", i, cnt); + } + fprintf(f, "\ttotal size %lu KB", totalSize/1024); +} + +void Backend::reportStat(FILE *f) +{ + scanCoalescQ(/*forceCoalescQDrop=*/false); + + fprintf(f, "\n regions:\n"); + int regNum = regionList.reportStat(f); + fprintf(f, "\n%d regions, %lu KB in all regions\n free bins:\nlarge bins: ", + regNum, totalMemSize/1024); + freeLargeBlockBins.reportStat(f); + fprintf(f, "\naligned bins: "); + freeSlabAlignedBins.reportStat(f); + fprintf(f, "\n"); +} +#endif // __TBB_MALLOC_BACKEND_STAT + +} } // namespaces diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backend.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backend.h new file mode 100644 index 00000000..197775ac --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backend.h @@ -0,0 +1,385 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbbmalloc_internal_H + #error tbbmalloc_internal.h must be included at this point +#endif + +#ifndef __TBB_backend_H +#define __TBB_backend_H + +// Included from namespace rml::internal + +// global state of blocks currently in processing +class BackendSync { + // Class instances should reside in zero-initialized memory! + // The number of blocks currently removed from a bin and not returned back + intptr_t inFlyBlocks; // to another + intptr_t binsModifications; // incremented on every bin modification + Backend *backend; +public: + void init(Backend *b) { backend = b; } + void blockConsumed() { AtomicIncrement(inFlyBlocks); } + void binsModified() { AtomicIncrement(binsModifications); } + void blockReleased() { +#if __TBB_MALLOC_BACKEND_STAT + MALLOC_ITT_SYNC_RELEASING(&inFlyBlocks); +#endif + AtomicIncrement(binsModifications); + intptr_t prev = AtomicAdd(inFlyBlocks, -1); + MALLOC_ASSERT(prev > 0, ASSERT_TEXT); + suppress_unused_warning(prev); + } + intptr_t getNumOfMods() const { return FencedLoad(binsModifications); } + // return true if need re-do the blocks search + inline bool waitTillBlockReleased(intptr_t startModifiedCnt); +}; + +class CoalRequestQ { // queue of free blocks that coalescing was delayed +private: + FreeBlock *blocksToFree; + BackendSync *bkndSync; + // counted blocks in blocksToFree and that are leaved blocksToFree + // and still in active coalescing + intptr_t inFlyBlocks; +public: + void init(BackendSync *bSync) { bkndSync = bSync; } + FreeBlock *getAll(); // return current list of blocks and make queue empty + void putBlock(FreeBlock *fBlock); + inline void blockWasProcessed(); + intptr_t blocksInFly() const { return FencedLoad(inFlyBlocks); } +}; + +class MemExtendingSema { + intptr_t active; +public: + bool wait() { + bool rescanBins = false; + // up to 3 threads can add more memory from OS simultaneously, + // rest of threads have to wait + for (;;) { + intptr_t prevCnt = FencedLoad(active); + if (prevCnt < 3) { + intptr_t n = AtomicCompareExchange(active, prevCnt+1, prevCnt); + if (n == prevCnt) + break; + } else { + SpinWaitWhileEq(active, prevCnt); + rescanBins = true; + break; + } + } + return rescanBins; + } + void signal() { AtomicAdd(active, -1); } +}; + +enum MemRegionType { + // The region holds only slabs + MEMREG_SLAB_BLOCKS = 0, + // The region can hold several large object blocks + MEMREG_LARGE_BLOCKS, + // The region holds only one block with a requested size + MEMREG_ONE_BLOCK +}; + +class MemRegionList { + MallocMutex regionListLock; +public: + MemRegion *head; + void add(MemRegion *r); + void remove(MemRegion *r); + int reportStat(FILE *f); +}; + +class Backend { +private: +/* Blocks in range [minBinnedSize; getMaxBinnedSize()] are kept in bins, + one region can contains several blocks. Larger blocks are allocated directly + and one region always contains one block. +*/ + enum { + minBinnedSize = 8*1024UL, + /* If huge pages are available, maxBinned_HugePage used. + If not, maxBinned_SmallPage is the threshold. + TODO: use pool's granularity for upper bound setting.*/ + maxBinned_SmallPage = 1024*1024UL, + // TODO: support other page sizes + maxBinned_HugePage = 4*1024*1024UL + }; + enum { + VALID_BLOCK_IN_BIN = 1 // valid block added to bin, not returned as result + }; +public: + // Backend bins step is the same as CacheStep for large object cache + static const size_t freeBinsStep = LargeObjectCache::LargeBSProps::CacheStep; + static const unsigned freeBinsNum = (maxBinned_HugePage-minBinnedSize)/freeBinsStep + 1; + + // if previous access missed per-thread slabs pool, + // allocate numOfSlabAllocOnMiss blocks in advance + static const int numOfSlabAllocOnMiss = 2; + + enum { + NO_BIN = -1, + // special bin for blocks >= maxBinned_HugePage, blocks go to this bin + // when pool is created with keepAllMemory policy + // TODO: currently this bin is scanned using "1st fit", as it accumulates + // blocks of different sizes, "best fit" is preferred in terms of fragmentation + HUGE_BIN = freeBinsNum-1 + }; + + // Bin keeps 2-linked list of free blocks. It must be 2-linked + // because during coalescing a block it's removed from a middle of the list. + struct Bin { + FreeBlock *head, + *tail; + MallocMutex tLock; + + void removeBlock(FreeBlock *fBlock); + void reset() { head = tail = 0; } + bool empty() const { return !head; } + + size_t countFreeBlocks(); + size_t reportFreeBlocks(FILE *f); + void reportStat(FILE *f); + }; + + typedef BitMaskMin<Backend::freeBinsNum> BitMaskBins; + + // array of bins supplemented with bitmask for fast finding of non-empty bins + class IndexedBins { + BitMaskBins bitMask; + Bin freeBins[Backend::freeBinsNum]; + FreeBlock *getFromBin(int binIdx, BackendSync *sync, size_t size, + bool needAlignedBlock, bool alignedBin, bool wait, int *resLocked); + public: + FreeBlock *findBlock(int nativeBin, BackendSync *sync, size_t size, + bool needAlignedBlock, bool alignedBin,int *numOfLockedBins); + bool tryReleaseRegions(int binIdx, Backend *backend); + void lockRemoveBlock(int binIdx, FreeBlock *fBlock); + void addBlock(int binIdx, FreeBlock *fBlock, size_t blockSz, bool addToTail); + bool tryAddBlock(int binIdx, FreeBlock *fBlock, bool addToTail); + int getMinNonemptyBin(unsigned startBin) const; + void verify(); + void reset(); + void reportStat(FILE *f); + }; + +private: + class AdvRegionsBins { + BitMaskBins bins; + public: + void registerBin(int regBin) { bins.set(regBin, 1); } + int getMinUsedBin(int start) const { return bins.getMinTrue(start); } + void reset() { bins.reset(); } + }; + // auxiliary class to atomic maximum request finding + class MaxRequestComparator { + const Backend *backend; + public: + MaxRequestComparator(const Backend *be) : backend(be) {} + inline bool operator()(size_t oldMaxReq, size_t requestSize) const; + }; + +#if CHECK_ALLOCATION_RANGE + // Keep min and max of all addresses requested from OS, + // use it for checking memory possibly allocated by replaced allocators + // and for debugging purposes. Valid only for default memory pool. + class UsedAddressRange { + static const uintptr_t ADDRESS_UPPER_BOUND = UINTPTR_MAX; + + uintptr_t leftBound, + rightBound; + MallocMutex mutex; + public: + // rightBound is zero-initialized + void init() { leftBound = ADDRESS_UPPER_BOUND; } + void registerAlloc(uintptr_t left, uintptr_t right); + void registerFree(uintptr_t left, uintptr_t right); + // as only left and right bounds are kept, we can return true + // for pointer not allocated by us, if more than single region + // was requested from OS + bool inRange(void *ptr) const { + const uintptr_t p = (uintptr_t)ptr; + return leftBound<=p && p<=rightBound; + } + }; +#else + class UsedAddressRange { + public: + void init() { } + void registerAlloc(uintptr_t, uintptr_t) {} + void registerFree(uintptr_t, uintptr_t) {} + bool inRange(void *) const { return true; } + }; +#endif + + ExtMemoryPool *extMemPool; + // used for release every region on pool destroying + MemRegionList regionList; + + CoalRequestQ coalescQ; // queue of coalescing requests + BackendSync bkndSync; + // semaphore protecting adding more more memory from OS + MemExtendingSema memExtendingSema; + size_t totalMemSize, + memSoftLimit; + UsedAddressRange usedAddrRange; + // to keep 1st allocation large than requested, keep bootstrapping status + enum { + bootsrapMemNotDone = 0, + bootsrapMemInitializing, + bootsrapMemDone + }; + intptr_t bootsrapMemStatus; + MallocMutex bootsrapMemStatusMutex; + + // Using of maximal observed requested size allows decrease + // memory consumption for small requests and decrease fragmentation + // for workloads when small and large allocation requests are mixed. + // TODO: decrease, not only increase it + size_t maxRequestedSize; + + // register bins related to advance regions + AdvRegionsBins advRegBins; + // Storage for split FreeBlocks + IndexedBins freeLargeBlockBins, + freeSlabAlignedBins; + + // Our friends + friend class BackendSync; + + /******************************** Backend methods ******************************/ + + /*--------------------------- Coalescing functions ----------------------------*/ + void coalescAndPut(FreeBlock *fBlock, size_t blockSz, bool slabAligned); + bool coalescAndPutList(FreeBlock *head, bool forceCoalescQDrop, bool reportBlocksProcessed); + + // Main coalescing operation + FreeBlock *doCoalesc(FreeBlock *fBlock, MemRegion **memRegion); + + // Queue for conflicted blocks during coalescing + bool scanCoalescQ(bool forceCoalescQDrop); + intptr_t blocksInCoalescing() const { return coalescQ.blocksInFly(); } + + /*--------------------- FreeBlock backend accessors ---------------------------*/ + FreeBlock *genericGetBlock(int num, size_t size, bool slabAligned); + void genericPutBlock(FreeBlock *fBlock, size_t blockSz, bool slabAligned); + + // Split the block and return remaining parts to backend if possible + FreeBlock *splitBlock(FreeBlock *fBlock, int num, size_t size, bool isAligned, bool needAlignedBlock); + + void removeBlockFromBin(FreeBlock *fBlock); + + // TODO: combine with returnLargeObject + void putLargeBlock(LargeMemoryBlock *lmb); + + /*------------------- Starting point for OS allocation ------------------------*/ + void requestBootstrapMem(); + FreeBlock *askMemFromOS(size_t totalReqSize, intptr_t startModifiedCnt, + int *lockedBinsThreshold, int numOfLockedBins, + bool *splittable, bool needSlabRegion); + + /*---------------------- Memory regions allocation ----------------------------*/ + FreeBlock *addNewRegion(size_t size, MemRegionType type, bool addToBin); + void releaseRegion(MemRegion *region); + + // TODO: combine in one initMemoryRegion function + FreeBlock *findBlockInRegion(MemRegion *region, size_t exactBlockSize); + void startUseBlock(MemRegion *region, FreeBlock *fBlock, bool addToBin); + + /*------------------------- Raw memory accessors ------------------------------*/ + void *allocRawMem(size_t &size); + bool freeRawMem(void *object, size_t size); + + /*------------------------------ Cleanup functions ----------------------------*/ + // Clean all memory from all caches (extMemPool hard cleanup) + FreeBlock *releaseMemInCaches(intptr_t startModifiedCnt, int *lockedBinsThreshold, int numOfLockedBins); + // Soft heap limit (regular cleanup, then maybe hard cleanup) + void releaseCachesToLimit(); + + /*---------------------------------- Utility ----------------------------------*/ + // TODO: move inside IndexedBins class + static int sizeToBin(size_t size) { + if (size >= maxBinned_HugePage) + return HUGE_BIN; + else if (size < minBinnedSize) + return NO_BIN; + + int bin = (size - minBinnedSize)/freeBinsStep; + + MALLOC_ASSERT(bin < HUGE_BIN, "Invalid size."); + return bin; + } + static bool toAlignedBin(FreeBlock *block, size_t size) { + return isAligned((char*)block + size, slabSize) && size >= slabSize; + } + +public: + /*--------------------- Init, reset, destroy, verify -------------------------*/ + void init(ExtMemoryPool *extMemoryPool); + bool destroy(); + + void verify(); + void reset(); + bool clean(); // clean on caches cleanup + + /*------------------------- Slab block request --------------------------------*/ + BlockI *getSlabBlock(int num); + void putSlabBlock(BlockI *block); + + /*-------------------------- Large object request -----------------------------*/ + LargeMemoryBlock *getLargeBlock(size_t size); + // TODO: make consistent with getLargeBlock + void returnLargeObject(LargeMemoryBlock *lmb); + + /*-------------------------- Backreference memory request ----------------------*/ + void *getBackRefSpace(size_t size, bool *rawMemUsed); + void putBackRefSpace(void *b, size_t size, bool rawMemUsed); + + /*----------------------------- Remap object ----------------------------------*/ + void *remap(void *ptr, size_t oldSize, size_t newSize, size_t alignment); + + /*---------------------------- Validation -------------------------------------*/ + bool inUserPool() const; + bool ptrCanBeValid(void *ptr) const { return usedAddrRange.inRange(ptr); } + + /*-------------------------- Configuration API --------------------------------*/ + // Soft heap limit + void setRecommendedMaxSize(size_t softLimit) { + memSoftLimit = softLimit; + releaseCachesToLimit(); + } + + /*------------------------------- Info ----------------------------------------*/ + size_t getMaxBinnedSize() const; + + /*-------------------------- Testing, statistics ------------------------------*/ +#if __TBB_MALLOC_WHITEBOX_TEST + size_t getTotalMemSize() const { return totalMemSize; } +#endif +#if __TBB_MALLOC_BACKEND_STAT + void reportStat(FILE *f); +private: + static size_t binToSize(int bin) { + MALLOC_ASSERT(bin <= HUGE_BIN, "Invalid bin."); + + return bin*freeBinsStep + minBinnedSize; + } +#endif +}; + +#endif // __TBB_backend_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backref.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backref.cpp new file mode 100644 index 00000000..eeea2b90 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/backref.cpp @@ -0,0 +1,338 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbbmalloc_internal.h" +#include <new> /* for placement new */ + +namespace rml { +namespace internal { + + +/********* backreferences ***********************/ +/* Each slab block and each large memory object header contains BackRefIdx + * that points out in some BackRefBlock which points back to this block or header. + */ +struct BackRefBlock : public BlockI { + BackRefBlock *nextForUse; // the next in the chain of blocks with free items + FreeObject *bumpPtr; // bump pointer moves from the end to the beginning of the block + FreeObject *freeList; + // list of all blocks that were allocated from raw mem (i.e., not from backend) + BackRefBlock *nextRawMemBlock; + int allocatedCount; // the number of objects allocated + BackRefIdx::master_t myNum; // the index in the master + MallocMutex blockMutex; + // true if this block has been added to the listForUse chain, + // modifications protected by masterMutex + bool addedToForUse; + + BackRefBlock(const BackRefBlock *blockToUse, intptr_t num) : + nextForUse(NULL), bumpPtr((FreeObject*)((uintptr_t)blockToUse + slabSize - sizeof(void*))), + freeList(NULL), nextRawMemBlock(NULL), allocatedCount(0), myNum(num), + addedToForUse(false) { + memset(&blockMutex, 0, sizeof(MallocMutex)); + + MALLOC_ASSERT(!(num >> CHAR_BIT*sizeof(BackRefIdx::master_t)), + "index in BackRefMaster must fit to BackRefIdx::master"); + } + // clean all but header + void zeroSet() { memset(this+1, 0, BackRefBlock::bytes-sizeof(BackRefBlock)); } + static const int bytes = slabSize; +}; + +// max number of backreference pointers in slab block +static const int BR_MAX_CNT = (BackRefBlock::bytes-sizeof(BackRefBlock))/sizeof(void*); + +struct BackRefMaster { +/* On 64-bit systems a slab block can hold up to ~2K back pointers to slab blocks + * or large objects, so it can address at least 32MB. The master array of 256KB + * holds 32K pointers to such blocks, addressing ~1 TB. + * On 32-bit systems there is ~4K back pointers in a slab block, so ~64MB can be addressed. + * The master array of 8KB holds 2K pointers to leaves, so ~128 GB can addressed. + */ + static const size_t bytes = sizeof(uintptr_t)>4? 256*1024 : 8*1024; + static const int dataSz; +/* space is reserved for master table and 4 leaves + taking into account VirtualAlloc allocation granularity */ + static const int leaves = 4; + static const size_t masterSize = BackRefMaster::bytes+leaves*BackRefBlock::bytes; + // The size of memory request for a few more leaf blocks; + // selected to match VirtualAlloc granularity + static const size_t blockSpaceSize = 64*1024; + + Backend *backend; + BackRefBlock *active; // if defined, use it for allocations + BackRefBlock *listForUse; // the chain of data blocks with free items + BackRefBlock *allRawMemBlocks; + intptr_t lastUsed; // index of the last used block + bool rawMemUsed; + MallocMutex requestNewSpaceMutex; + BackRefBlock *backRefBl[1]; // the real size of the array is dataSz + + BackRefBlock *findFreeBlock(); + void addToForUseList(BackRefBlock *bl); + void initEmptyBackRefBlock(BackRefBlock *newBl); + bool requestNewSpace(); +}; + +const int BackRefMaster::dataSz + = 1+(BackRefMaster::bytes-sizeof(BackRefMaster))/sizeof(BackRefBlock*); + +static MallocMutex masterMutex; +static BackRefMaster *backRefMaster; + +bool initBackRefMaster(Backend *backend) +{ + bool rawMemUsed; + BackRefMaster *master = + (BackRefMaster*)backend->getBackRefSpace(BackRefMaster::masterSize, + &rawMemUsed); + if (! master) + return false; + master->backend = backend; + master->listForUse = master->allRawMemBlocks = NULL; + master->rawMemUsed = rawMemUsed; + master->lastUsed = -1; + memset(&master->requestNewSpaceMutex, 0, sizeof(MallocMutex)); + for (int i=0; i<BackRefMaster::leaves; i++) { + BackRefBlock *bl = (BackRefBlock*)((uintptr_t)master + BackRefMaster::bytes + i*BackRefBlock::bytes); + bl->zeroSet(); + master->initEmptyBackRefBlock(bl); + if (i) + master->addToForUseList(bl); + else // active leaf is not needed in listForUse + master->active = bl; + } + // backRefMaster is read in getBackRef, so publish it in consistent state + FencedStore((intptr_t&)backRefMaster, (intptr_t)master); + return true; +} + +void destroyBackRefMaster(Backend *backend) +{ + if (backRefMaster) { // Is initBackRefMaster() called? + for (BackRefBlock *curr=backRefMaster->allRawMemBlocks; curr; ) { + BackRefBlock *next = curr->nextRawMemBlock; + // allRawMemBlocks list is only for raw mem blocks + backend->putBackRefSpace(curr, BackRefMaster::blockSpaceSize, + /*rawMemUsed=*/true); + curr = next; + } + backend->putBackRefSpace(backRefMaster, BackRefMaster::masterSize, + backRefMaster->rawMemUsed); + } +} + +void BackRefMaster::addToForUseList(BackRefBlock *bl) +{ + bl->nextForUse = listForUse; + listForUse = bl; + bl->addedToForUse = true; +} + +void BackRefMaster::initEmptyBackRefBlock(BackRefBlock *newBl) +{ + intptr_t nextLU = lastUsed+1; + new (newBl) BackRefBlock(newBl, nextLU); + MALLOC_ASSERT(nextLU < dataSz, NULL); + backRefBl[nextLU] = newBl; + // lastUsed is read in getBackRef, and access to backRefBl[lastUsed] + // is possible only after checking backref against current lastUsed + FencedStore(lastUsed, nextLU); +} + +bool BackRefMaster::requestNewSpace() +{ + bool isRawMemUsed; + MALLOC_STATIC_ASSERT(!(blockSpaceSize % BackRefBlock::bytes), + "Must request space for whole number of blocks."); + + if (backRefMaster->dataSz <= lastUsed + 1) // no space in master + return false; + + // only one thread at a time may add blocks + MallocMutex::scoped_lock newSpaceLock(requestNewSpaceMutex); + + if (listForUse) // double check that only one block is available + return true; + BackRefBlock *newBl = + (BackRefBlock*)backend->getBackRefSpace(blockSpaceSize, &isRawMemUsed); + if (!newBl) return false; + + // touch a page for the 1st time without taking masterMutex ... + for (BackRefBlock *bl = newBl; (uintptr_t)bl < (uintptr_t)newBl + blockSpaceSize; + bl = (BackRefBlock*)((uintptr_t)bl + BackRefBlock::bytes)) + bl->zeroSet(); + + MallocMutex::scoped_lock lock(masterMutex); // ... and share under lock + + const size_t numOfUnusedIdxs = backRefMaster->dataSz - lastUsed - 1; + if (numOfUnusedIdxs <= 0) { // no space in master under lock, roll back + backend->putBackRefSpace(newBl, blockSpaceSize, isRawMemUsed); + return false; + } + // It's possible that only part of newBl is used, due to lack of indices in master. + // This is OK as such underutilization is possible only once for backreferneces table. + int blocksToUse = min(numOfUnusedIdxs, blockSpaceSize / BackRefBlock::bytes); + + // use the first block in the batch to maintain the list of "raw" memory + // to be released at shutdown + if (isRawMemUsed) { + newBl->nextRawMemBlock = backRefMaster->allRawMemBlocks; + backRefMaster->allRawMemBlocks = newBl; + } + for (BackRefBlock *bl = newBl; blocksToUse>0; + bl = (BackRefBlock*)((uintptr_t)bl + BackRefBlock::bytes), blocksToUse--) { + initEmptyBackRefBlock(bl); + if (active->allocatedCount == BR_MAX_CNT) + active = bl; // active leaf is not needed in listForUse + else + addToForUseList(bl); + } + return true; +} + +BackRefBlock *BackRefMaster::findFreeBlock() +{ + if (active->allocatedCount < BR_MAX_CNT) + return active; + + if (listForUse) { // use released list + MallocMutex::scoped_lock lock(masterMutex); + + if (active->allocatedCount == BR_MAX_CNT && listForUse) { + active = listForUse; + listForUse = listForUse->nextForUse; + MALLOC_ASSERT(active->addedToForUse, ASSERT_TEXT); + active->addedToForUse = false; + } + } else // allocate new data node + if (!requestNewSpace()) + return NULL; + return active; +} + +void *getBackRef(BackRefIdx backRefIdx) +{ + // !backRefMaster means no initialization done, so it can't be valid memory + // see addEmptyBackRefBlock for fences around lastUsed + if (!FencedLoad((intptr_t&)backRefMaster) + || backRefIdx.getMaster() > FencedLoad(backRefMaster->lastUsed) + || backRefIdx.getOffset() >= BR_MAX_CNT) + return NULL; + return *(void**)((uintptr_t)backRefMaster->backRefBl[backRefIdx.getMaster()] + + sizeof(BackRefBlock)+backRefIdx.getOffset()*sizeof(void*)); +} + +void setBackRef(BackRefIdx backRefIdx, void *newPtr) +{ + MALLOC_ASSERT(backRefIdx.getMaster()<=backRefMaster->lastUsed && backRefIdx.getOffset()<BR_MAX_CNT, + ASSERT_TEXT); + *(void**)((uintptr_t)backRefMaster->backRefBl[backRefIdx.getMaster()] + + sizeof(BackRefBlock) + backRefIdx.getOffset()*sizeof(void*)) = newPtr; +} + +BackRefIdx BackRefIdx::newBackRef(bool largeObj) +{ + BackRefBlock *blockToUse; + void **toUse; + BackRefIdx res; + bool lastBlockFirstUsed = false; + + do { + MALLOC_ASSERT(backRefMaster, ASSERT_TEXT); + blockToUse = backRefMaster->findFreeBlock(); + if (!blockToUse) + return BackRefIdx(); + toUse = NULL; + { // the block is locked to find a reference + MallocMutex::scoped_lock lock(blockToUse->blockMutex); + + if (blockToUse->freeList) { + toUse = (void**)blockToUse->freeList; + blockToUse->freeList = blockToUse->freeList->next; + MALLOC_ASSERT(!blockToUse->freeList || + ((uintptr_t)blockToUse->freeList>=(uintptr_t)blockToUse + && (uintptr_t)blockToUse->freeList < + (uintptr_t)blockToUse + slabSize), ASSERT_TEXT); + } else if (blockToUse->allocatedCount < BR_MAX_CNT) { + toUse = (void**)blockToUse->bumpPtr; + blockToUse->bumpPtr = + (FreeObject*)((uintptr_t)blockToUse->bumpPtr - sizeof(void*)); + if (blockToUse->allocatedCount == BR_MAX_CNT-1) { + MALLOC_ASSERT((uintptr_t)blockToUse->bumpPtr + < (uintptr_t)blockToUse+sizeof(BackRefBlock), + ASSERT_TEXT); + blockToUse->bumpPtr = NULL; + } + } + if (toUse) { + if (!blockToUse->allocatedCount && !backRefMaster->listForUse) + lastBlockFirstUsed = true; + blockToUse->allocatedCount++; + } + } // end of lock scope + } while (!toUse); + // The first thread that uses the last block requests new space in advance; + // possible failures are ignored. + if (lastBlockFirstUsed) + backRefMaster->requestNewSpace(); + + res.master = blockToUse->myNum; + uintptr_t offset = + ((uintptr_t)toUse - ((uintptr_t)blockToUse + sizeof(BackRefBlock)))/sizeof(void*); + // Is offset too big? + MALLOC_ASSERT(!(offset >> 15), ASSERT_TEXT); + res.offset = offset; + if (largeObj) res.largeObj = largeObj; + + return res; +} + +void removeBackRef(BackRefIdx backRefIdx) +{ + MALLOC_ASSERT(!backRefIdx.isInvalid(), ASSERT_TEXT); + MALLOC_ASSERT(backRefIdx.getMaster()<=backRefMaster->lastUsed + && backRefIdx.getOffset()<BR_MAX_CNT, ASSERT_TEXT); + BackRefBlock *currBlock = backRefMaster->backRefBl[backRefIdx.getMaster()]; + FreeObject *freeObj = (FreeObject*)((uintptr_t)currBlock + sizeof(BackRefBlock) + + backRefIdx.getOffset()*sizeof(void*)); + MALLOC_ASSERT(((uintptr_t)freeObj>(uintptr_t)currBlock && + (uintptr_t)freeObj<(uintptr_t)currBlock + slabSize), ASSERT_TEXT); + { + MallocMutex::scoped_lock lock(currBlock->blockMutex); + + freeObj->next = currBlock->freeList; + MALLOC_ASSERT(!freeObj->next || + ((uintptr_t)freeObj->next > (uintptr_t)currBlock + && (uintptr_t)freeObj->next < + (uintptr_t)currBlock + slabSize), ASSERT_TEXT); + currBlock->freeList = freeObj; + currBlock->allocatedCount--; + } + // TODO: do we need double-check here? + if (!currBlock->addedToForUse && currBlock!=backRefMaster->active) { + MallocMutex::scoped_lock lock(masterMutex); + + if (!currBlock->addedToForUse && currBlock!=backRefMaster->active) + backRefMaster->addToForUseList(currBlock); + } +} + +/********* End of backreferences ***********************/ + +} // namespace internal +} // namespace rml + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/frontend.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/frontend.cpp new file mode 100644 index 00000000..9f16d8e4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/frontend.cpp @@ -0,0 +1,3291 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + + +#include "tbbmalloc_internal.h" +#include <errno.h> +#include <new> /* for placement new */ +#include <string.h> /* for memset */ + +#include "../tbb/tbb_version.h" +#include "../tbb/tbb_environment.h" +#include "../tbb/itt_notify.h" // for __TBB_load_ittnotify() + +#if USE_PTHREAD + #define TlsSetValue_func pthread_setspecific + #define TlsGetValue_func pthread_getspecific + #define GetMyTID() pthread_self() + #include <sched.h> + inline void do_yield() {sched_yield();} + extern "C" { static void mallocThreadShutdownNotification(void*); } + #if __sun || __SUNPRO_CC + #define __asm__ asm + #endif + #include <unistd.h> // sysconf(_SC_PAGESIZE) +#elif USE_WINTHREAD + #define GetMyTID() GetCurrentThreadId() +#if __TBB_WIN8UI_SUPPORT + #include<thread> + #define TlsSetValue_func FlsSetValue + #define TlsGetValue_func FlsGetValue + #define TlsAlloc() FlsAlloc(NULL) + #define TLS_ALLOC_FAILURE FLS_OUT_OF_INDEXES + #define TlsFree FlsFree + inline void do_yield() {std::this_thread::yield();} +#else + #define TlsSetValue_func TlsSetValue + #define TlsGetValue_func TlsGetValue + #define TLS_ALLOC_FAILURE TLS_OUT_OF_INDEXES + inline void do_yield() {SwitchToThread();} +#endif +#else + #error Must define USE_PTHREAD or USE_WINTHREAD + +#endif + + +#define FREELIST_NONBLOCKING 1 + +namespace rml { +class MemoryPool; +namespace internal { + +class Block; +class MemoryPool; + +#if MALLOC_CHECK_RECURSION + +inline bool isMallocInitialized(); + +bool RecursiveMallocCallProtector::noRecursion() { + MALLOC_ASSERT(isMallocInitialized(), + "Recursion status can be checked only when initialization was done."); + return !mallocRecursionDetected; +} + +#endif // MALLOC_CHECK_RECURSION + +/** Support for handling the special UNUSABLE pointer state **/ +const intptr_t UNUSABLE = 0x1; +inline bool isSolidPtr( void* ptr ) { + return (UNUSABLE|(intptr_t)ptr)!=UNUSABLE; +} +inline bool isNotForUse( void* ptr ) { + return (intptr_t)ptr==UNUSABLE; +} + +/* + * Block::objectSize value used to mark blocks allocated by startupAlloc + */ +const uint16_t startupAllocObjSizeMark = ~(uint16_t)0; + +/* + * The following constant is used to define the size of struct Block, the block header. + * The intent is to have the size of a Block multiple of the cache line size, this allows us to + * get good alignment at the cost of some overhead equal to the amount of padding included in the Block. + */ +const int blockHeaderAlignment = estimatedCacheLineSize; + +/********* The data structures and global objects **************/ + +/* + * The malloc routines themselves need to be able to occasionally malloc some space, + * in order to set up the structures used by the thread local structures. This + * routine performs that functions. + */ +class BootStrapBlocks { + MallocMutex bootStrapLock; + Block *bootStrapBlock; + Block *bootStrapBlockUsed; + FreeObject *bootStrapObjectList; +public: + void *allocate(MemoryPool *memPool, size_t size); + void free(void* ptr); + void reset(); +}; + +#if USE_INTERNAL_TID +class ThreadId { + static tls_key_t Tid_key; + static intptr_t ThreadCount; + + unsigned int id; + + static unsigned int tlsNumber() { + unsigned int result = reinterpret_cast<intptr_t>(TlsGetValue_func(Tid_key)); + if( !result ) { + RecursiveMallocCallProtector scoped; + // Thread-local value is zero -> first call from this thread, + // need to initialize with next ID value (IDs start from 1) + result = AtomicIncrement(ThreadCount); // returned new value! + TlsSetValue_func( Tid_key, reinterpret_cast<void*>(result) ); + } + return result; + } +public: + static bool init() { +#if USE_WINTHREAD + Tid_key = TlsAlloc(); + if (Tid_key == TLS_ALLOC_FAILURE) + return false; +#else + int status = pthread_key_create( &Tid_key, NULL ); + if ( status ) { + fprintf (stderr, "The memory manager cannot create tls key during initialization\n"); + return false; + } +#endif /* USE_WINTHREAD */ + return true; + } + static void destroy() { + if( Tid_key ) { +#if USE_WINTHREAD + BOOL status = !(TlsFree( Tid_key )); // fail is zero +#else + int status = pthread_key_delete( Tid_key ); +#endif /* USE_WINTHREAD */ + if ( status ) + fprintf (stderr, "The memory manager cannot delete tls key\n"); + Tid_key = 0; + } + } + + ThreadId() : id(ThreadId::tlsNumber()) {} + bool isCurrentThreadId() const { return id == ThreadId::tlsNumber(); } + +#if COLLECT_STATISTICS || MALLOC_TRACE + friend unsigned int getThreadId() { return ThreadId::tlsNumber(); } +#endif +#if COLLECT_STATISTICS + static unsigned getMaxThreadId() { return ThreadCount; } + + friend int STAT_increment(ThreadId tid, int bin, int ctr); +#endif +}; + +tls_key_t ThreadId::Tid_key; +intptr_t ThreadId::ThreadCount; + +#if COLLECT_STATISTICS +int STAT_increment(ThreadId tid, int bin, int ctr) +{ + return ::STAT_increment(tid.id, bin, ctr); +} +#endif + +#else // USE_INTERNAL_TID + +class ThreadId { +#if USE_PTHREAD + pthread_t tid; +#else + DWORD tid; +#endif +public: + ThreadId() : tid(GetMyTID()) {} +#if USE_PTHREAD + bool isCurrentThreadId() const { return pthread_equal(pthread_self(), tid); } +#else + bool isCurrentThreadId() const { return GetCurrentThreadId() == tid; } +#endif + static bool init() { return true; } + static void destroy() {} +}; + +#endif // USE_INTERNAL_TID + +/*********** Code to provide thread ID and a thread-local void pointer **********/ + +bool TLSKey::init() +{ +#if USE_WINTHREAD + TLS_pointer_key = TlsAlloc(); + if (TLS_pointer_key == TLS_ALLOC_FAILURE) + return false; +#else + int status = pthread_key_create( &TLS_pointer_key, mallocThreadShutdownNotification ); + if ( status ) + return false; +#endif /* USE_WINTHREAD */ + return true; +} + +bool TLSKey::destroy() +{ +#if USE_WINTHREAD + BOOL status1 = !(TlsFree(TLS_pointer_key)); // fail is zero +#else + int status1 = pthread_key_delete(TLS_pointer_key); +#endif /* USE_WINTHREAD */ + MALLOC_ASSERT(!status1, "The memory manager cannot delete tls key."); + return status1==0; +} + +inline TLSData* TLSKey::getThreadMallocTLS() const +{ + return (TLSData *)TlsGetValue_func( TLS_pointer_key ); +} + +inline void TLSKey::setThreadMallocTLS( TLSData * newvalue ) { + RecursiveMallocCallProtector scoped; + TlsSetValue_func( TLS_pointer_key, newvalue ); +} + +/* The 'next' field in the block header has to maintain some invariants: + * it needs to be on a 16K boundary and the first field in the block. + * Any value stored there needs to have the lower 14 bits set to 0 + * so that various assert work. This means that if you want to smash this memory + * for debugging purposes you will need to obey this invariant. + * The total size of the header needs to be a power of 2 to simplify + * the alignment requirements. For now it is a 128 byte structure. + * To avoid false sharing, the fields changed only locally are separated + * from the fields changed by foreign threads. + * Changing the size of the block header would require to change + * some bin allocation sizes, in particular "fitting" sizes (see above). + */ +class Bin; +class StartupBlock; + +class MemoryPool { + // if no explicit grainsize, expect to see malloc in user's pAlloc + // and set reasonable low granularity + static const size_t defaultGranularity = estimatedCacheLineSize; + + MemoryPool(); // deny +public: + static MallocMutex memPoolListLock; + + // list of all active pools is used to release + // all TLS data on thread termination or library unload + MemoryPool *next, + *prev; + ExtMemoryPool extMemPool; + BootStrapBlocks bootStrapBlocks; + + static void initDefaultPool(); + + bool init(intptr_t poolId, const MemPoolPolicy* memPoolPolicy); + bool reset(); + bool destroy(); + void onThreadShutdown(TLSData *tlsData); + + inline TLSData *getTLS(bool create); + void clearTLS() { extMemPool.tlsPointerKey.setThreadMallocTLS(NULL); } + + Block *getEmptyBlock(size_t size); + void returnEmptyBlock(Block *block, bool poolTheBlock); + + // get/put large object to/from local large object cache + void *getFromLLOCache(TLSData *tls, size_t size, size_t alignment); + void putToLLOCache(TLSData *tls, void *object); +}; + +static intptr_t defaultMemPool_space[sizeof(MemoryPool)/sizeof(intptr_t) + + (sizeof(MemoryPool)%sizeof(intptr_t)? 1 : 0)]; +static MemoryPool *defaultMemPool = (MemoryPool*)defaultMemPool_space; +const size_t MemoryPool::defaultGranularity; +// zero-initialized +MallocMutex MemoryPool::memPoolListLock; +// TODO: move huge page status to default pool, because that's its states +HugePagesStatus hugePages; +static bool usedBySrcIncluded = false; + +// Padding helpers +template<size_t padd> +struct PaddingImpl { + size_t __padding[padd]; +}; + +template<> +struct PaddingImpl<0> {}; + +template<int N> +struct Padding : PaddingImpl<N/sizeof(size_t)> {}; + +// Slab block is 16KB-aligned. To prevent false sharing, separate locally-accessed +// fields and fields commonly accessed by not owner threads. +class GlobalBlockFields : public BlockI { +protected: + FreeObject *publicFreeList; + Block *nextPrivatizable; + MemoryPool *poolPtr; +}; + +class LocalBlockFields : public GlobalBlockFields, Padding<blockHeaderAlignment - sizeof(GlobalBlockFields)> { +protected: + Block *next; + Block *previous; /* Use double linked list to speed up removal */ + FreeObject *bumpPtr; /* Bump pointer moves from the end to the beginning of a block */ + FreeObject *freeList; + /* Pointer to local data for the owner thread. Used for fast finding tls + when releasing object from a block that current thread owned. + NULL for orphaned blocks. */ + TLSData *tlsPtr; + ThreadId ownerTid; /* the ID of the thread that owns or last owned the block */ + BackRefIdx backRefIdx; + uint16_t allocatedCount; /* Number of objects allocated (obviously by the owning thread) */ + uint16_t objectSize; + bool isFull; + + friend class FreeBlockPool; + friend class StartupBlock; + friend class LifoList; + friend void *BootStrapBlocks::allocate(MemoryPool *, size_t); + friend bool OrphanedBlocks::cleanup(Backend*); + friend Block *MemoryPool::getEmptyBlock(size_t); +}; + +// Use inheritance to guarantee that a user data start on next cache line. +// Can't use member for it, because when LocalBlockFields already on cache line, +// we must have no additional memory consumption for all compilers. +class Block : public LocalBlockFields, + Padding<2*blockHeaderAlignment - sizeof(LocalBlockFields)> { +public: + bool empty() const { + if (allocatedCount > 0) return false; + MALLOC_ASSERT(!isSolidPtr(publicFreeList), ASSERT_TEXT); + return true; + } + inline FreeObject* allocate(); + inline FreeObject *allocateFromFreeList(); + + inline bool adjustFullness(); + void adjustPositionInBin(Bin* bin = NULL); + + bool freeListNonNull() { return freeList; } + void freePublicObject(FreeObject *objectToFree); + inline void freeOwnObject(void *object); + void reset(); + void privatizePublicFreeList( bool reset = true ); + void restoreBumpPtr(); + void privatizeOrphaned(TLSData *tls, unsigned index); + bool readyToShare(); + void shareOrphaned(intptr_t binTag, unsigned index); + unsigned int getSize() const { + MALLOC_ASSERT(isStartupAllocObject() || objectSize<minLargeObjectSize, + "Invalid object size"); + return isStartupAllocObject()? 0 : objectSize; + } + const BackRefIdx *getBackRefIdx() const { return &backRefIdx; } + inline bool isOwnedByCurrentThread() const; + bool isStartupAllocObject() const { return objectSize == startupAllocObjSizeMark; } + inline FreeObject *findObjectToFree(const void *object) const; + void checkFreePrecond(const void *object) const { +#if MALLOC_DEBUG + const char *msg = "Possible double free or heap corruption."; + // small objects are always at least sizeof(size_t) Byte aligned, + // try to check this before this dereference as for invalid objects + // this may be unreadable + MALLOC_ASSERT(isAligned(object, sizeof(size_t)), "Try to free invalid small object"); + // releasing to free slab + MALLOC_ASSERT(allocatedCount>0, msg); + // must not point to slab's header + MALLOC_ASSERT((uintptr_t)object - (uintptr_t)this >= sizeof(Block), msg); + if (startupAllocObjSizeMark == objectSize) // startup block + MALLOC_ASSERT(object<=bumpPtr, msg); + else { + // non-startup objects are 8 Byte aligned + MALLOC_ASSERT(isAligned(object, 8), "Try to free invalid small object"); + MALLOC_ASSERT(allocatedCount <= (slabSize-sizeof(Block))/objectSize + && (!bumpPtr || object>bumpPtr), msg); + FreeObject *toFree = findObjectToFree(object); + // check against head of freeList, as this is mostly + // expected after double free + MALLOC_ASSERT(toFree != freeList, msg); + // check against head of publicFreeList, to detect double free + // involving foreign thread + MALLOC_ASSERT(toFree != publicFreeList, msg); + } +#else + suppress_unused_warning(object); +#endif + } + void initEmptyBlock(TLSData *tls, size_t size); + size_t findObjectSize(void *object) const; + MemoryPool *getMemPool() const { return poolPtr; } // do not use on the hot path! + +protected: + void cleanBlockHeader(); + +private: + static const float emptyEnoughRatio; /* Threshold on free space needed to "reactivate" a block */ + + inline FreeObject *allocateFromBumpPtr(); + inline FreeObject *findAllocatedObject(const void *address) const; + inline bool isProperlyPlaced(const void *object) const; + inline void markOwned(TLSData *tls) { + MALLOC_ASSERT(!tlsPtr, ASSERT_TEXT); + ownerTid = ThreadId(); /* save the ID of the current thread */ + tlsPtr = tls; + } + inline void markOrphaned() { + MALLOC_ASSERT(tlsPtr, ASSERT_TEXT); + tlsPtr = NULL; + } + + friend class Bin; + friend class TLSData; + friend bool MemoryPool::destroy(); +}; + +const float Block::emptyEnoughRatio = 1.0 / 4.0; + +MALLOC_STATIC_ASSERT(sizeof(Block) <= 2*estimatedCacheLineSize, + "The class Block does not fit into 2 cache lines on this platform. " + "Defining USE_INTERNAL_TID may help to fix it."); + +class Bin { +private: + Block *activeBlk; + Block *mailbox; + MallocMutex mailLock; + +public: + inline Block* getActiveBlock() const { return activeBlk; } + void resetActiveBlock() { activeBlk = NULL; } + bool activeBlockUnused() const { return activeBlk && !activeBlk->allocatedCount; } + inline void setActiveBlock(Block *block); + inline Block* setPreviousBlockActive(); + Block* getPrivatizedFreeListBlock(); + void moveBlockToFront(Block *block); + bool cleanPublicFreeLists(); + void processEmptyBlock(Block *block, bool poolTheBlock); + void addPublicFreeListBlock(Block* block); + + void outofTLSBin(Block* block); + void verifyTLSBin(size_t size) const; + void pushTLSBin(Block* block); + + void verifyInitState() const { + MALLOC_ASSERT( !activeBlk, ASSERT_TEXT ); + MALLOC_ASSERT( !mailbox, ASSERT_TEXT ); + } + + friend void Block::freePublicObject (FreeObject *objectToFree); +}; + +/********* End of the data structures **************/ + +/* + * There are bins for all 8 byte aligned objects less than this segregated size; 8 bins in total + */ +const uint32_t minSmallObjectIndex = 0; +const uint32_t numSmallObjectBins = 8; +const uint32_t maxSmallObjectSize = 64; + +/* + * There are 4 bins between each couple of powers of 2 [64-128-256-...] + * from maxSmallObjectSize till this size; 16 bins in total + */ +const uint32_t minSegregatedObjectIndex = minSmallObjectIndex+numSmallObjectBins; +const uint32_t numSegregatedObjectBins = 16; +const uint32_t maxSegregatedObjectSize = 1024; + +/* + * And there are 5 bins with allocation sizes that are multiples of estimatedCacheLineSize + * and selected to fit 9, 6, 4, 3, and 2 allocations in a block. + */ +const uint32_t minFittingIndex = minSegregatedObjectIndex+numSegregatedObjectBins; +const uint32_t numFittingBins = 5; + +const uint32_t fittingAlignment = estimatedCacheLineSize; + +#define SET_FITTING_SIZE(N) ( (slabSize-sizeof(Block))/N ) & ~(fittingAlignment-1) +// For blockSize=16*1024, sizeof(Block)=2*estimatedCacheLineSize and fittingAlignment=estimatedCacheLineSize, +// the comments show the fitting sizes and the amounts left unused for estimatedCacheLineSize=64/128: +const uint32_t fittingSize1 = SET_FITTING_SIZE(9); // 1792/1792 128/000 +const uint32_t fittingSize2 = SET_FITTING_SIZE(6); // 2688/2688 128/000 +const uint32_t fittingSize3 = SET_FITTING_SIZE(4); // 4032/3968 128/256 +const uint32_t fittingSize4 = SET_FITTING_SIZE(3); // 5376/5376 128/000 +const uint32_t fittingSize5 = SET_FITTING_SIZE(2); // 8128/8064 000/000 +#undef SET_FITTING_SIZE + +/* + * The total number of thread-specific Block-based bins + */ +const uint32_t numBlockBins = minFittingIndex+numFittingBins; + +/* + * Objects of this size and larger are considered large objects. + */ +const uint32_t minLargeObjectSize = fittingSize5 + 1; + +/* + * Per-thread pool of slab blocks. Idea behind it is to not share with other + * threads memory that are likely in local cache(s) of our CPU. + */ +class FreeBlockPool { +private: + Block *head; + int size; + Backend *backend; + bool lastAccessMiss; +public: + static const int POOL_HIGH_MARK = 32; + static const int POOL_LOW_MARK = 8; + + class ResOfGet { + ResOfGet(); + public: + Block* block; + bool lastAccMiss; + ResOfGet(Block *b, bool lastMiss) : block(b), lastAccMiss(lastMiss) {} + }; + + // allocated in zero-initialized memory + FreeBlockPool(Backend *bknd) : backend(bknd) {} + ResOfGet getBlock(); + void returnBlock(Block *block); + bool externalCleanup(); // can be called by another thread +}; + +template<int LOW_MARK, int HIGH_MARK> +class LocalLOCImpl { +private: + static const size_t MAX_TOTAL_SIZE = 4*1024*1024; + // TODO: can single-linked list be faster here? + LargeMemoryBlock *head, + *tail; // need it when do releasing on overflow + size_t totalSize; + int numOfBlocks; +public: + bool put(LargeMemoryBlock *object, ExtMemoryPool *extMemPool); + LargeMemoryBlock *get(size_t size); + bool externalCleanup(ExtMemoryPool *extMemPool); +#if __TBB_MALLOC_WHITEBOX_TEST + LocalLOCImpl() : head(NULL), tail(NULL), totalSize(0), numOfBlocks(0) {} + static size_t getMaxSize() { return MAX_TOTAL_SIZE; } + static const int LOC_HIGH_MARK = HIGH_MARK; +#else + // no ctor, object must be created in zero-initialized memory +#endif +}; + +typedef LocalLOCImpl<8,32> LocalLOC; // set production code parameters + +class TLSData : public TLSRemote { + MemoryPool *memPool; +public: + Bin bin[numBlockBinLimit]; + FreeBlockPool freeSlabBlocks; + LocalLOC lloc; + unsigned currCacheIdx; +private: + bool unused; +public: + TLSData(MemoryPool *mPool, Backend *bknd) : memPool(mPool), freeSlabBlocks(bknd) {} + MemoryPool *getMemPool() const { return memPool; } + Bin* getAllocationBin(size_t size); + void release(); + bool externalCleanup(bool cleanOnlyUnused, bool cleanBins) { + if (!unused && cleanOnlyUnused) return false; + // Heavy operation in terms of synchronization complexity, + // should be called only for the current thread + bool released = cleanBins ? cleanupBlockBins() : false; + // both cleanups to be called, and the order is not important + return released | lloc.externalCleanup(&memPool->extMemPool) | freeSlabBlocks.externalCleanup(); + } + bool cleanupBlockBins(); + void markUsed() { unused = false; } // called by owner when TLS touched + void markUnused() { unused = true; } // can be called by not owner thread +}; + +TLSData *TLSKey::createTLS(MemoryPool *memPool, Backend *backend) +{ + MALLOC_ASSERT( sizeof(TLSData) >= sizeof(Bin) * numBlockBins + sizeof(FreeBlockPool), ASSERT_TEXT ); + TLSData* tls = (TLSData*) memPool->bootStrapBlocks.allocate(memPool, sizeof(TLSData)); + if ( !tls ) + return NULL; + new(tls) TLSData(memPool, backend); + /* the block contains zeroes after bootStrapMalloc, so bins are initialized */ +#if MALLOC_DEBUG + for (uint32_t i = 0; i < numBlockBinLimit; i++) + tls->bin[i].verifyInitState(); +#endif + setThreadMallocTLS(tls); + memPool->extMemPool.allLocalCaches.registerThread(tls); + return tls; +} + +bool TLSData::cleanupBlockBins() +{ + bool released = false; + for (uint32_t i = 0; i < numBlockBinLimit; i++) { + released |= bin[i].cleanPublicFreeLists(); + // After cleaning public free lists, only the active block might be empty. + // Do not use processEmptyBlock because it will just restore bumpPtr. + Block *block = bin[i].getActiveBlock(); + if (block && block->empty()) { + bin[i].outofTLSBin(block); + memPool->returnEmptyBlock(block, /*poolTheBlock=*/false); + released = true; + } + } + return released; +} + +bool ExtMemoryPool::releaseAllLocalCaches() +{ + // Iterate all registered TLS data and clean LLOC and Slab pools + bool released = allLocalCaches.cleanup(/*cleanOnlyUnused=*/false); + + // Bins privatization is done only for the current thread + if (TLSData *tlsData = tlsPointerKey.getThreadMallocTLS()) + released |= tlsData->cleanupBlockBins(); + + return released; +} + +void AllLocalCaches::registerThread(TLSRemote *tls) +{ + tls->prev = NULL; + MallocMutex::scoped_lock lock(listLock); + MALLOC_ASSERT(head!=tls, ASSERT_TEXT); + tls->next = head; + if (head) + head->prev = tls; + head = tls; + MALLOC_ASSERT(head->next!=head, ASSERT_TEXT); +} + +void AllLocalCaches::unregisterThread(TLSRemote *tls) +{ + MallocMutex::scoped_lock lock(listLock); + MALLOC_ASSERT(head, "Can't unregister thread: no threads are registered."); + if (head == tls) + head = tls->next; + if (tls->next) + tls->next->prev = tls->prev; + if (tls->prev) + tls->prev->next = tls->next; + MALLOC_ASSERT(!tls->next || tls->next->next!=tls->next, ASSERT_TEXT); +} + +bool AllLocalCaches::cleanup(bool cleanOnlyUnused) +{ + bool released = false; + { + MallocMutex::scoped_lock lock(listLock); + for (TLSRemote *curr=head; curr; curr=curr->next) + released |= static_cast<TLSData*>(curr)->externalCleanup(cleanOnlyUnused, /*cleanBins=*/false); + } + return released; +} + +void AllLocalCaches::markUnused() +{ + bool locked; + MallocMutex::scoped_lock lock(listLock, /*block=*/false, &locked); + if (!locked) // not wait for marking if someone doing something with it + return; + + for (TLSRemote *curr=head; curr; curr=curr->next) + static_cast<TLSData*>(curr)->markUnused(); +} + +#if MALLOC_CHECK_RECURSION +MallocMutex RecursiveMallocCallProtector::rmc_mutex; +pthread_t RecursiveMallocCallProtector::owner_thread; +void *RecursiveMallocCallProtector::autoObjPtr; +bool RecursiveMallocCallProtector::mallocRecursionDetected; +#if __FreeBSD__ +bool RecursiveMallocCallProtector::canUsePthread; +#endif + +#endif + +/*********** End code to provide thread ID and a TLS pointer **********/ + +// Parameter for isLargeObject, keeps our expectations on memory origin. +// Assertions must use unknownMem to reliably report object invalidity. +enum MemoryOrigin { + ourMem, // allocated by TBB allocator + unknownMem // can be allocated by system allocator or TBB allocator +}; + +template<MemoryOrigin> bool isLargeObject(void *object); +static void *internalMalloc(size_t size); +static void internalFree(void *object); +static void *internalPoolMalloc(MemoryPool* mPool, size_t size); +static bool internalPoolFree(MemoryPool *mPool, void *object, size_t size); + +#if !MALLOC_DEBUG +#if __INTEL_COMPILER || _MSC_VER +#define NOINLINE(decl) __declspec(noinline) decl +#define ALWAYSINLINE(decl) __forceinline decl +#elif __GNUC__ +#define NOINLINE(decl) decl __attribute__ ((noinline)) +#define ALWAYSINLINE(decl) decl __attribute__ ((always_inline)) +#else +#define NOINLINE(decl) decl +#define ALWAYSINLINE(decl) decl +#endif + +static NOINLINE( bool doInitialization() ); +ALWAYSINLINE( bool isMallocInitialized() ); + +#undef ALWAYSINLINE +#undef NOINLINE +#endif /* !MALLOC_DEBUG */ + + +/********* Now some rough utility code to deal with indexing the size bins. **************/ + +/* + * Given a number return the highest non-zero bit in it. It is intended to work with 32-bit values only. + * Moreover, on IPF, for sake of simplicity and performance, it is narrowed to only serve for 64 to 1023. + * This is enough for current algorithm of distribution of sizes among bins. + * __TBB_Log2 is not used here to minimize dependencies on TBB specific sources. + */ +#if _WIN64 && _MSC_VER>=1400 && !__INTEL_COMPILER +extern "C" unsigned char _BitScanReverse( unsigned long* i, unsigned long w ); +#pragma intrinsic(_BitScanReverse) +#endif +static inline unsigned int highestBitPos(unsigned int n) +{ + MALLOC_ASSERT( n>=64 && n<1024, ASSERT_TEXT ); // only needed for bsr array lookup, but always true + unsigned int pos; +#if __ARCH_x86_32||__ARCH_x86_64 + +# if __linux__||__APPLE__||__FreeBSD__||__NetBSD__||__OpenBSD__||__sun||__MINGW32__ + __asm__ ("bsr %1,%0" : "=r"(pos) : "r"(n)); +# elif (_WIN32 && (!_WIN64 || __INTEL_COMPILER)) + __asm + { + bsr eax, n + mov pos, eax + } +# elif _WIN64 && _MSC_VER>=1400 + _BitScanReverse((unsigned long*)&pos, (unsigned long)n); +# else +# error highestBitPos() not implemented for this platform +# endif +#elif __arm__ + __asm__ __volatile__ + ( + "clz %0, %1\n" + "rsb %0, %0, %2\n" + :"=r" (pos) :"r" (n), "I" (31) + ); +#else + static unsigned int bsr[16] = {0/*N/A*/,6,7,7,8,8,8,8,9,9,9,9,9,9,9,9}; + pos = bsr[ n>>6 ]; +#endif /* __ARCH_* */ + return pos; +} + +template<bool Is32Bit> +unsigned int getSmallObjectIndex(unsigned int size) +{ + return (size-1)>>3; +} +template<> +unsigned int getSmallObjectIndex</*Is32Bit=*/false>(unsigned int size) +{ + // For 64-bit malloc, 16 byte alignment is needed except for bin 0. + unsigned int result = (size-1)>>3; + if (result) result |= 1; // 0,1,3,5,7; bins 2,4,6 are not aligned to 16 bytes + return result; +} +/* + * Depending on indexRequest, for a given size return either the index into the bin + * for objects of this size, or the actual size of objects in this bin. + */ +template<bool indexRequest> +static unsigned int getIndexOrObjectSize (unsigned int size) +{ + if (size <= maxSmallObjectSize) { // selection from 8/16/24/32/40/48/56/64 + unsigned int index = getSmallObjectIndex</*Is32Bit=*/(sizeof(size_t)<=4)>( size ); + /* Bin 0 is for 8 bytes, bin 1 is for 16, and so forth */ + return indexRequest ? index : (index+1)<<3; + } + else if (size <= maxSegregatedObjectSize ) { // 80/96/112/128 / 160/192/224/256 / 320/384/448/512 / 640/768/896/1024 + unsigned int order = highestBitPos(size-1); // which group of bin sizes? + MALLOC_ASSERT( 6<=order && order<=9, ASSERT_TEXT ); + if (indexRequest) + return minSegregatedObjectIndex - (4*6) - 4 + (4*order) + ((size-1)>>(order-2)); + else { + unsigned int alignment = 128 >> (9-order); // alignment in the group + MALLOC_ASSERT( alignment==16 || alignment==32 || alignment==64 || alignment==128, ASSERT_TEXT ); + return alignUp(size,alignment); + } + } + else { + if( size <= fittingSize3 ) { + if( size <= fittingSize2 ) { + if( size <= fittingSize1 ) + return indexRequest ? minFittingIndex : fittingSize1; + else + return indexRequest ? minFittingIndex+1 : fittingSize2; + } else + return indexRequest ? minFittingIndex+2 : fittingSize3; + } else { + if( size <= fittingSize5 ) { + if( size <= fittingSize4 ) + return indexRequest ? minFittingIndex+3 : fittingSize4; + else + return indexRequest ? minFittingIndex+4 : fittingSize5; + } else { + MALLOC_ASSERT( 0,ASSERT_TEXT ); // this should not happen + return ~0U; + } + } + } +} + +static unsigned int getIndex (unsigned int size) +{ + return getIndexOrObjectSize</*indexRequest=*/true>(size); +} + +static unsigned int getObjectSize (unsigned int size) +{ + return getIndexOrObjectSize</*indexRequest=*/false>(size); +} + + +void *BootStrapBlocks::allocate(MemoryPool *memPool, size_t size) +{ + FreeObject *result; + + MALLOC_ASSERT( size == sizeof(TLSData), ASSERT_TEXT ); + + { // Lock with acquire + MallocMutex::scoped_lock scoped_cs(bootStrapLock); + + if( bootStrapObjectList) { + result = bootStrapObjectList; + bootStrapObjectList = bootStrapObjectList->next; + } else { + if (!bootStrapBlock) { + bootStrapBlock = memPool->getEmptyBlock(size); + if (!bootStrapBlock) return NULL; + } + result = bootStrapBlock->bumpPtr; + bootStrapBlock->bumpPtr = (FreeObject *)((uintptr_t)bootStrapBlock->bumpPtr - bootStrapBlock->objectSize); + if ((uintptr_t)bootStrapBlock->bumpPtr < (uintptr_t)bootStrapBlock+sizeof(Block)) { + bootStrapBlock->bumpPtr = NULL; + bootStrapBlock->next = bootStrapBlockUsed; + bootStrapBlockUsed = bootStrapBlock; + bootStrapBlock = NULL; + } + } + } // Unlock with release + + memset (result, 0, size); + return (void*)result; +} + +void BootStrapBlocks::free(void* ptr) +{ + MALLOC_ASSERT( ptr, ASSERT_TEXT ); + { // Lock with acquire + MallocMutex::scoped_lock scoped_cs(bootStrapLock); + ((FreeObject*)ptr)->next = bootStrapObjectList; + bootStrapObjectList = (FreeObject*)ptr; + } // Unlock with release +} + +void BootStrapBlocks::reset() +{ + bootStrapBlock = bootStrapBlockUsed = NULL; + bootStrapObjectList = NULL; +} + +#if !(FREELIST_NONBLOCKING) +static MallocMutex publicFreeListLock; // lock for changes of publicFreeList +#endif + +/********* End rough utility code **************/ + +/* LifoList assumes zero initialization so a vector of it can be created + * by just allocating some space with no call to constructor. + * On Linux, it seems to be necessary to avoid linking with C++ libraries. + * + * By usage convention there is no race on the initialization. */ +LifoList::LifoList( ) : top(NULL) +{ + // MallocMutex assumes zero initialization + memset(&lock, 0, sizeof(MallocMutex)); +} + +void LifoList::push(Block *block) +{ + MallocMutex::scoped_lock scoped_cs(lock); + block->next = top; + top = block; +} + +Block *LifoList::pop() +{ + Block *block=NULL; + if (top) { + MallocMutex::scoped_lock scoped_cs(lock); + if (top) { + block = top; + top = block->next; + } + } + return block; +} + +Block *LifoList::grab() +{ + Block *block = NULL; + if (top) { + MallocMutex::scoped_lock scoped_cs(lock); + block = top; + top = NULL; + } + return block; +} + +/********* Thread and block related code *************/ + +template<bool poolDestroy> void AllLargeBlocksList::releaseAll(Backend *backend) { + LargeMemoryBlock *next, *lmb = loHead; + loHead = NULL; + + for (; lmb; lmb = next) { + next = lmb->gNext; + if (poolDestroy) { + // as it's pool destruction, no need to return object to backend, + // only remove backrefs, as they are global + removeBackRef(lmb->backRefIdx); + } else { + // clean g(Next|Prev) to prevent removing lmb + // from AllLargeBlocksList inside returnLargeObject + lmb->gNext = lmb->gPrev = NULL; + backend->returnLargeObject(lmb); + } + } +} + +TLSData* MemoryPool::getTLS(bool create) +{ + TLSData* tls = extMemPool.tlsPointerKey.getThreadMallocTLS(); + if (create && !tls) + tls = extMemPool.tlsPointerKey.createTLS(this, &extMemPool.backend); + return tls; +} + +/* + * Return the bin for the given size. + */ +inline Bin* TLSData::getAllocationBin(size_t size) +{ + return bin + getIndex(size); +} + +/* Return an empty uninitialized block in a non-blocking fashion. */ +Block *MemoryPool::getEmptyBlock(size_t size) +{ + TLSData* tls = getTLS(/*create=*/false); + // try to use per-thread cache, if TLS available + FreeBlockPool::ResOfGet resOfGet = tls? + tls->freeSlabBlocks.getBlock() : FreeBlockPool::ResOfGet(NULL, false); + Block *result = resOfGet.block; + + if (!result) { // not found in local cache, asks backend for slabs + int num = resOfGet.lastAccMiss? Backend::numOfSlabAllocOnMiss : 1; + BackRefIdx backRefIdx[Backend::numOfSlabAllocOnMiss]; + + result = static_cast<Block*>(extMemPool.backend.getSlabBlock(num)); + if (!result) return NULL; + + if (!extMemPool.userPool()) + for (int i=0; i<num; i++) { + backRefIdx[i] = BackRefIdx::newBackRef(/*largeObj=*/false); + if (backRefIdx[i].isInvalid()) { + // roll back resource allocation + for (int j=0; j<i; j++) + removeBackRef(backRefIdx[j]); + Block *b = result; + for (int j=0; j<num; b=(Block*)((uintptr_t)b+slabSize), j++) + extMemPool.backend.putSlabBlock(b); + return NULL; + } + } + // resources were allocated, register blocks + Block *b = result; + for (int i=0; i<num; b=(Block*)((uintptr_t)b+slabSize), i++) { + // slab block in user's pool must have invalid backRefIdx + if (extMemPool.userPool()) { + new (&b->backRefIdx) BackRefIdx(); + } else { + setBackRef(backRefIdx[i], b); + b->backRefIdx = backRefIdx[i]; + } + b->tlsPtr = tls; + b->poolPtr = this; + // all but first one go to per-thread pool + if (i > 0) { + MALLOC_ASSERT(tls, ASSERT_TEXT); + tls->freeSlabBlocks.returnBlock(b); + } + } + } + MALLOC_ASSERT(result, ASSERT_TEXT); + result->initEmptyBlock(tls, size); + STAT_increment(getThreadId(), getIndex(result->objectSize), allocBlockNew); + return result; +} + +void MemoryPool::returnEmptyBlock(Block *block, bool poolTheBlock) +{ + block->reset(); + if (poolTheBlock) { + getTLS(/*create=*/false)->freeSlabBlocks.returnBlock(block); + } else { + // slab blocks in user's pools do not have valid backRefIdx + if (!extMemPool.userPool()) + removeBackRef(*(block->getBackRefIdx())); + extMemPool.backend.putSlabBlock(block); + } +} + +bool ExtMemoryPool::init(intptr_t poolId, rawAllocType rawAlloc, + rawFreeType rawFree, size_t granularity, + bool keepAllMemory, bool fixedPool) +{ + this->poolId = poolId; + this->rawAlloc = rawAlloc; + this->rawFree = rawFree; + this->granularity = granularity; + this->keepAllMemory = keepAllMemory; + this->fixedPool = fixedPool; + this->delayRegsReleasing = false; + if (!initTLS()) + return false; + loc.init(this); + backend.init(this); + MALLOC_ASSERT(isPoolValid(), NULL); + return true; +} + +bool ExtMemoryPool::initTLS() { return tlsPointerKey.init(); } + +bool MemoryPool::init(intptr_t poolId, const MemPoolPolicy *policy) +{ + if (!extMemPool.init(poolId, policy->pAlloc, policy->pFree, + policy->granularity? policy->granularity : defaultGranularity, + policy->keepAllMemory, policy->fixedPool)) + return false; + { + MallocMutex::scoped_lock lock(memPoolListLock); + next = defaultMemPool->next; + defaultMemPool->next = this; + prev = defaultMemPool; + if (next) + next->prev = this; + } + return true; +} + +bool MemoryPool::reset() +{ + MALLOC_ASSERT(extMemPool.userPool(), "No reset for the system pool."); + // memory is not releasing during pool reset + // TODO: mark regions to release unused on next reset() + extMemPool.delayRegionsReleasing(true); + + bootStrapBlocks.reset(); + extMemPool.lmbList.releaseAll</*poolDestroy=*/false>(&extMemPool.backend); + if (!extMemPool.reset()) + return false; + + if (!extMemPool.initTLS()) + return false; + extMemPool.delayRegionsReleasing(false); + return true; +} + +bool MemoryPool::destroy() +{ +#if __TBB_MALLOC_LOCACHE_STAT + extMemPool.loc.reportStat(stdout); +#endif +#if __TBB_MALLOC_BACKEND_STAT + extMemPool.backend.reportStat(stdout); +#endif + { + MallocMutex::scoped_lock lock(memPoolListLock); + // remove itself from global pool list + if (prev) + prev->next = next; + if (next) + next->prev = prev; + } + // slab blocks in non-default pool do not have backreferences, + // only large objects do + if (extMemPool.userPool()) + extMemPool.lmbList.releaseAll</*poolDestroy=*/true>(&extMemPool.backend); + else { + // only one non-userPool() is supported now + MALLOC_ASSERT(this==defaultMemPool, NULL); + // There and below in extMemPool.destroy(), do not restore initial state + // for user pool, because it's just about to be released. But for system + // pool restoring, we do not want to do zeroing of it on subsequent reload. + bootStrapBlocks.reset(); + extMemPool.orphanedBlocks.reset(); + } + return extMemPool.destroy(); +} + +void MemoryPool::onThreadShutdown(TLSData *tlsData) +{ + if (tlsData) { // might be called for "empty" TLS + tlsData->release(); + bootStrapBlocks.free(tlsData); + clearTLS(); + } +} + +#if MALLOC_DEBUG +void Bin::verifyTLSBin (size_t size) const +{ +/* The debug version verifies the TLSBin as needed */ + uint32_t objSize = getObjectSize(size); + + if (activeBlk) { + MALLOC_ASSERT( activeBlk->isOwnedByCurrentThread(), ASSERT_TEXT ); + MALLOC_ASSERT( activeBlk->objectSize == objSize, ASSERT_TEXT ); +#if MALLOC_DEBUG>1 + for (Block* temp = activeBlk->next; temp; temp=temp->next) { + MALLOC_ASSERT( temp!=activeBlk, ASSERT_TEXT ); + MALLOC_ASSERT( temp->isOwnedByCurrentThread(), ASSERT_TEXT ); + MALLOC_ASSERT( temp->objectSize == objSize, ASSERT_TEXT ); + MALLOC_ASSERT( temp->previous->next == temp, ASSERT_TEXT ); + if (temp->next) { + MALLOC_ASSERT( temp->next->previous == temp, ASSERT_TEXT ); + } + } + for (Block* temp = activeBlk->previous; temp; temp=temp->previous) { + MALLOC_ASSERT( temp!=activeBlk, ASSERT_TEXT ); + MALLOC_ASSERT( temp->isOwnedByCurrentThread(), ASSERT_TEXT ); + MALLOC_ASSERT( temp->objectSize == objSize, ASSERT_TEXT ); + MALLOC_ASSERT( temp->next->previous == temp, ASSERT_TEXT ); + if (temp->previous) { + MALLOC_ASSERT( temp->previous->next == temp, ASSERT_TEXT ); + } + } +#endif /* MALLOC_DEBUG>1 */ + } +} +#else /* MALLOC_DEBUG */ +inline void Bin::verifyTLSBin (size_t) const { } +#endif /* MALLOC_DEBUG */ + +/* + * Add a block to the start of this tls bin list. + */ +void Bin::pushTLSBin(Block* block) +{ + /* The objectSize should be defined and not a parameter + because the function is applied to partially filled blocks as well */ + unsigned int size = block->objectSize; + + MALLOC_ASSERT( block->isOwnedByCurrentThread(), ASSERT_TEXT ); + MALLOC_ASSERT( block->objectSize != 0, ASSERT_TEXT ); + MALLOC_ASSERT( block->next == NULL, ASSERT_TEXT ); + MALLOC_ASSERT( block->previous == NULL, ASSERT_TEXT ); + + MALLOC_ASSERT( this, ASSERT_TEXT ); + verifyTLSBin(size); + + block->next = activeBlk; + if( activeBlk ) { + block->previous = activeBlk->previous; + activeBlk->previous = block; + if( block->previous ) + block->previous->next = block; + } else { + activeBlk = block; + } + + verifyTLSBin(size); +} + +/* + * Take a block out of its tls bin (e.g. before removal). + */ +void Bin::outofTLSBin(Block* block) +{ + unsigned int size = block->objectSize; + + MALLOC_ASSERT( block->isOwnedByCurrentThread(), ASSERT_TEXT ); + MALLOC_ASSERT( block->objectSize != 0, ASSERT_TEXT ); + + MALLOC_ASSERT( this, ASSERT_TEXT ); + verifyTLSBin(size); + + if (block == activeBlk) { + activeBlk = block->previous? block->previous : block->next; + } + /* Unlink the block */ + if (block->previous) { + MALLOC_ASSERT( block->previous->next == block, ASSERT_TEXT ); + block->previous->next = block->next; + } + if (block->next) { + MALLOC_ASSERT( block->next->previous == block, ASSERT_TEXT ); + block->next->previous = block->previous; + } + block->next = NULL; + block->previous = NULL; + + verifyTLSBin(size); +} + +Block* Bin::getPrivatizedFreeListBlock() +{ + Block* block; + MALLOC_ASSERT( this, ASSERT_TEXT ); + // if this method is called, active block usage must be unsuccessful + MALLOC_ASSERT( !activeBlk && !mailbox || activeBlk && activeBlk->isFull, ASSERT_TEXT ); + +// the counter should be changed STAT_increment(getThreadId(), ThreadCommonCounters, lockPublicFreeList); + if (!FencedLoad((intptr_t&)mailbox)) // hotpath is empty mailbox + return NULL; + else { // mailbox is not empty, take lock and inspect it + MallocMutex::scoped_lock scoped_cs(mailLock); + block = mailbox; + if( block ) { + MALLOC_ASSERT( block->isOwnedByCurrentThread(), ASSERT_TEXT ); + MALLOC_ASSERT( !isNotForUse(block->nextPrivatizable), ASSERT_TEXT ); + mailbox = block->nextPrivatizable; + block->nextPrivatizable = (Block*) this; + } + } + if( block ) { + MALLOC_ASSERT( isSolidPtr(block->publicFreeList), ASSERT_TEXT ); + block->privatizePublicFreeList(); + block->adjustPositionInBin(this); + } + return block; +} + +void Bin::addPublicFreeListBlock(Block* block) +{ + MallocMutex::scoped_lock scoped_cs(mailLock); + block->nextPrivatizable = mailbox; + mailbox = block; +} + +// Process publicly freed objects in all blocks and return empty blocks +// to the backend in order to reduce overall footprint. +bool Bin::cleanPublicFreeLists() +{ + Block* block; + if (!FencedLoad((intptr_t&)mailbox)) + return false; + else { + // Grab all the blocks in the mailbox + MallocMutex::scoped_lock scoped_cs(mailLock); + block = mailbox; + mailbox = NULL; + } + bool released = false; + while (block) { + MALLOC_ASSERT( block->isOwnedByCurrentThread(), ASSERT_TEXT ); + Block* tmp = block->nextPrivatizable; + block->nextPrivatizable = (Block*) this; + block->privatizePublicFreeList(); + if (block->empty()) { + processEmptyBlock(block, /*poolTheBlock=*/false); + released = true; + } else + block->adjustPositionInBin(this); + block = tmp; + } + return released; +} + +bool Block::adjustFullness() +{ + if (bumpPtr) { + /* If we are still using a bump ptr for this block it is empty enough to use. */ + STAT_increment(getThreadId(), getIndex(objectSize), examineEmptyEnough); + isFull = false; + } else { + const float threshold = (slabSize - sizeof(Block)) * (1 - emptyEnoughRatio); + /* allocatedCount shows how many objects in the block are in use; however it still counts + * blocks freed by other threads; so prior call to privatizePublicFreeList() is recommended */ + isFull = (allocatedCount*objectSize > threshold) ? true : false; +#if COLLECT_STATISTICS + if (isFull) + STAT_increment(getThreadId(), getIndex(objectSize), examineNotEmpty); + else + STAT_increment(getThreadId(), getIndex(objectSize), examineEmptyEnough); +#endif + } + return isFull; +} + +// This method resides in class Block, and not in class Bin, in order to avoid +// calling getAllocationBin on a reasonably hot path in Block::freeOwnObject +void Block::adjustPositionInBin(Bin* bin/*=NULL*/) +{ + // If the block were full, but became empty enough to use, + // move it to the front of the list + if (isFull && !adjustFullness()) { + if (!bin) + bin = tlsPtr->getAllocationBin(objectSize); + bin->moveBlockToFront(this); + } +} + +/* Restore the bump pointer for an empty block that is planned to use */ +void Block::restoreBumpPtr() +{ + MALLOC_ASSERT( allocatedCount == 0, ASSERT_TEXT ); + MALLOC_ASSERT( !isSolidPtr(publicFreeList), ASSERT_TEXT ); + STAT_increment(getThreadId(), getIndex(objectSize), freeRestoreBumpPtr); + bumpPtr = (FreeObject *)((uintptr_t)this + slabSize - objectSize); + freeList = NULL; + isFull = false; +} + +void Block::freeOwnObject(void *object) +{ + tlsPtr->markUsed(); + allocatedCount--; + MALLOC_ASSERT( allocatedCount < (slabSize-sizeof(Block))/objectSize, ASSERT_TEXT ); +#if COLLECT_STATISTICS + // Note that getAllocationBin is not called on the hottest path with statistics off. + if (tlsPtr->getAllocationBin(objectSize)->getActiveBlock() != this) + STAT_increment(getThreadId(), getIndex(objectSize), freeToInactiveBlock); + else + STAT_increment(getThreadId(), getIndex(objectSize), freeToActiveBlock); +#endif + if (empty()) { + // If the last object of a slab is freed, the slab cannot be marked full + MALLOC_ASSERT(!isFull, ASSERT_TEXT); + tlsPtr->getAllocationBin(objectSize)->processEmptyBlock(this, /*poolTheBlock=*/true); + } else { // hot path + FreeObject *objectToFree = findObjectToFree(object); + objectToFree->next = freeList; + freeList = objectToFree; + adjustPositionInBin(); + } +} + +void Block::freePublicObject (FreeObject *objectToFree) +{ + FreeObject *localPublicFreeList; + + MALLOC_ITT_SYNC_RELEASING(&publicFreeList); +#if FREELIST_NONBLOCKING + FreeObject *temp = publicFreeList; + do { + localPublicFreeList = objectToFree->next = temp; + temp = (FreeObject*)AtomicCompareExchange( + (intptr_t&)publicFreeList, + (intptr_t)objectToFree, (intptr_t)localPublicFreeList ); + // no backoff necessary because trying to make change, not waiting for a change + } while( temp != localPublicFreeList ); +#else + STAT_increment(getThreadId(), ThreadCommonCounters, lockPublicFreeList); + { + MallocMutex::scoped_lock scoped_cs(publicFreeListLock); + localPublicFreeList = objectToFree->next = publicFreeList; + publicFreeList = objectToFree; + } +#endif + + if( localPublicFreeList==NULL ) { + // if the block is abandoned, its nextPrivatizable pointer should be UNUSABLE + // otherwise, it should point to the bin the block belongs to. + // reading nextPrivatizable is thread-safe below, because: + // 1) the executing thread atomically got publicFreeList==NULL and changed it to non-NULL; + // 2) only owning thread can change it back to NULL, + // 3) but it can not be done until the block is put to the mailbox + // So the executing thread is now the only one that can change nextPrivatizable + if( !isNotForUse(nextPrivatizable) ) { + MALLOC_ASSERT( nextPrivatizable!=NULL, ASSERT_TEXT ); + Bin* theBin = (Bin*) nextPrivatizable; + theBin->addPublicFreeListBlock(this); + } + } + STAT_increment(getThreadId(), ThreadCommonCounters, freeToOtherThread); + STAT_increment(ownerTid, getIndex(objectSize), freeByOtherThread); +} + +// Make objects freed by other threads available for use again +void Block::privatizePublicFreeList( bool reset ) +{ + FreeObject *localPublicFreeList; + // If reset is false, publicFreeList should not be zeroed but set to UNUSABLE + // to properly synchronize with other threads freeing objects to this slab. + const intptr_t endMarker = reset ? 0 : UNUSABLE; + + // Only the owner thread may reset the pointer to NULL + MALLOC_ASSERT( isOwnedByCurrentThread() || !reset, ASSERT_TEXT ); +#if FREELIST_NONBLOCKING + localPublicFreeList = (FreeObject*)AtomicFetchStore( &publicFreeList, endMarker ); +#else + STAT_increment(getThreadId(), ThreadCommonCounters, lockPublicFreeList); + { + MallocMutex::scoped_lock scoped_cs(publicFreeListLock); + localPublicFreeList = publicFreeList; + publicFreeList = endMarker; + } +#endif + MALLOC_ITT_SYNC_ACQUIRED(&publicFreeList); + MALLOC_ASSERT( !(reset && isNotForUse(publicFreeList)), ASSERT_TEXT ); + + // publicFreeList must have been UNUSABLE or valid, but not NULL + MALLOC_ASSERT( localPublicFreeList!=NULL, ASSERT_TEXT ); + if( isSolidPtr(localPublicFreeList) ) { + MALLOC_ASSERT( allocatedCount <= (slabSize-sizeof(Block))/objectSize, ASSERT_TEXT ); + /* other threads did not change the counter freeing our blocks */ + allocatedCount--; + FreeObject *temp = localPublicFreeList; + while( isSolidPtr(temp->next) ){ // the list will end with either NULL or UNUSABLE + temp = temp->next; + allocatedCount--; + MALLOC_ASSERT( allocatedCount < (slabSize-sizeof(Block))/objectSize, ASSERT_TEXT ); + } + /* merge with local freeList */ + temp->next = freeList; + freeList = localPublicFreeList; + STAT_increment(getThreadId(), getIndex(objectSize), allocPrivatized); + } +} + +void Block::privatizeOrphaned(TLSData *tls, unsigned index) +{ + Bin* bin = tls->bin + index; + STAT_increment(getThreadId(), index, allocBlockPublic); + next = NULL; + previous = NULL; + MALLOC_ASSERT( publicFreeList!=NULL, ASSERT_TEXT ); + /* There is not a race here since no other thread owns this block */ + markOwned(tls); + // It is safe to change nextPrivatizable, as publicFreeList is not null + MALLOC_ASSERT( isNotForUse(nextPrivatizable), ASSERT_TEXT ); + nextPrivatizable = (Block*)bin; + // the next call is required to change publicFreeList to 0 + privatizePublicFreeList(); + if( empty() ) { + restoreBumpPtr(); + } else { + adjustFullness(); // check the block fullness and set isFull + } + MALLOC_ASSERT( !isNotForUse(publicFreeList), ASSERT_TEXT ); +} + + +bool Block::readyToShare() +{ + void* oldval; +#if FREELIST_NONBLOCKING + oldval = (void*)AtomicCompareExchange((intptr_t&)publicFreeList, UNUSABLE, 0); +#else + STAT_increment(getThreadId(), ThreadCommonCounters, lockPublicFreeList); + { + MallocMutex::scoped_lock scoped_cs(publicFreeListLock); + if ( (oldval=publicFreeList)==NULL ) + (intptr_t&)(publicFreeList) = UNUSABLE; + } +#endif + return oldval==NULL; +} + +void Block::shareOrphaned(intptr_t binTag, unsigned index) +{ + MALLOC_ASSERT( binTag, ASSERT_TEXT ); + STAT_increment(getThreadId(), index, freeBlockPublic); + markOrphaned(); + if ((intptr_t)nextPrivatizable==binTag) { + // First check passed: the block is not in mailbox yet. + // Need to set publicFreeList to non-zero, so other threads + // will not change nextPrivatizable and it can be zeroed. + if ( !readyToShare() ) { + // another thread freed an object; we need to wait until it finishes. + // There is no need for exponential backoff, as the wait here is not for a lock; + // but need to yield, so the thread we wait has a chance to run. + // TODO: add a pause to also be friendly to hyperthreads + int count = 256; + while( (intptr_t)const_cast<Block* volatile &>(nextPrivatizable)==binTag ) { + if (--count==0) { + do_yield(); + count = 256; + } + } + } + } + MALLOC_ASSERT( publicFreeList!=NULL, ASSERT_TEXT ); + // now it is safe to change our data + previous = NULL; + // it is caller responsibility to ensure that the list of blocks + // formed by nextPrivatizable pointers is kept consistent if required. + // if only called from thread shutdown code, it does not matter. + (intptr_t&)(nextPrivatizable) = UNUSABLE; +} + +void Block::cleanBlockHeader() +{ + next = NULL; + previous = NULL; + freeList = NULL; + allocatedCount = 0; + isFull = false; + tlsPtr = NULL; + + publicFreeList = NULL; +} + +void Block::initEmptyBlock(TLSData *tls, size_t size) +{ + // Having getIndex and getObjectSize called next to each other + // allows better compiler optimization as they basically share the code. + unsigned int index = getIndex(size); + unsigned int objSz = getObjectSize(size); + + cleanBlockHeader(); + objectSize = objSz; + markOwned(tls); + // bump pointer should be prepared for first allocation - thus mode it down to objectSize + bumpPtr = (FreeObject *)((uintptr_t)this + slabSize - objectSize); + + // each block should have the address where the head of the list of "privatizable" blocks is kept + // the only exception is a block for boot strap which is initialized when TLS is yet NULL + nextPrivatizable = tls? (Block*)(tls->bin + index) : NULL; + TRACEF(( "[ScalableMalloc trace] Empty block %p is initialized, owner is %ld, objectSize is %d, bumpPtr is %p\n", + this, tlsPtr ? getThreadId() : -1, objectSize, bumpPtr )); +} + +Block *OrphanedBlocks::get(TLSData *tls, unsigned int size) +{ + // TODO: try to use index from getAllocationBin + unsigned int index = getIndex(size); + Block *block = bins[index].pop(); + if (block) { + MALLOC_ITT_SYNC_ACQUIRED(bins+index); + block->privatizeOrphaned(tls, index); + } + return block; +} + +void OrphanedBlocks::put(intptr_t binTag, Block *block) +{ + unsigned int index = getIndex(block->getSize()); + block->shareOrphaned(binTag, index); + MALLOC_ITT_SYNC_RELEASING(bins+index); + bins[index].push(block); +} + +void OrphanedBlocks::reset() +{ + for (uint32_t i=0; i<numBlockBinLimit; i++) + new (bins+i) LifoList(); +} + +bool OrphanedBlocks::cleanup(Backend* backend) +{ + bool released = false; + for (uint32_t i=0; i<numBlockBinLimit; i++) { + Block* block = bins[i].grab(); + MALLOC_ITT_SYNC_ACQUIRED(bins+i); + while (block) { + Block* next = block->next; + block->privatizePublicFreeList( /*reset=*/false ); // do not set publicFreeList to NULL + if (block->empty()) { + block->reset(); + // slab blocks in user's pools do not have valid backRefIdx + if (!backend->inUserPool()) + removeBackRef(*(block->getBackRefIdx())); + backend->putSlabBlock(block); + released = true; + } else { + MALLOC_ITT_SYNC_RELEASING(bins+i); + bins[i].push(block); + } + block = next; + } + } + return released; +} + +FreeBlockPool::ResOfGet FreeBlockPool::getBlock() +{ + Block *b = (Block*)AtomicFetchStore(&head, 0); + + if (b) { + size--; + Block *newHead = b->next; + lastAccessMiss = false; + FencedStore((intptr_t&)head, (intptr_t)newHead); + } else + lastAccessMiss = true; + + return ResOfGet(b, lastAccessMiss); +} + +void FreeBlockPool::returnBlock(Block *block) +{ + MALLOC_ASSERT( size <= POOL_HIGH_MARK, ASSERT_TEXT ); + Block *localHead = (Block*)AtomicFetchStore(&head, 0); + + if (!localHead) + size = 0; // head was stolen by externalClean, correct size accordingly + else if (size == POOL_HIGH_MARK) { + // release cold blocks and add hot one, + // so keep POOL_LOW_MARK-1 blocks and add new block to head + Block *headToFree = localHead, *helper; + for (int i=0; i<POOL_LOW_MARK-2; i++) + headToFree = headToFree->next; + Block *last = headToFree; + headToFree = headToFree->next; + last->next = NULL; + size = POOL_LOW_MARK-1; + for (Block *currBl = headToFree; currBl; currBl = helper) { + helper = currBl->next; + // slab blocks in user's pools do not have valid backRefIdx + if (!backend->inUserPool()) + removeBackRef(currBl->backRefIdx); + backend->putSlabBlock(currBl); + } + } + size++; + block->next = localHead; + FencedStore((intptr_t&)head, (intptr_t)block); +} + +bool FreeBlockPool::externalCleanup() +{ + Block *helper; + bool released = false; + + for (Block *currBl=(Block*)AtomicFetchStore(&head, 0); currBl; currBl=helper) { + helper = currBl->next; + // slab blocks in user's pools do not have valid backRefIdx + if (!backend->inUserPool()) + removeBackRef(currBl->backRefIdx); + backend->putSlabBlock(currBl); + released = true; + } + return released; +} + +/* Prepare the block for returning to FreeBlockPool */ +void Block::reset() +{ + // it is caller's responsibility to ensure no data is lost before calling this + MALLOC_ASSERT( allocatedCount==0, ASSERT_TEXT ); + MALLOC_ASSERT( !isSolidPtr(publicFreeList), ASSERT_TEXT ); + if (!isStartupAllocObject()) + STAT_increment(getThreadId(), getIndex(objectSize), freeBlockBack); + + cleanBlockHeader(); + + nextPrivatizable = NULL; + + objectSize = 0; + // for an empty block, bump pointer should point right after the end of the block + bumpPtr = (FreeObject *)((uintptr_t)this + slabSize); +} + +inline void Bin::setActiveBlock (Block *block) +{ +// MALLOC_ASSERT( bin, ASSERT_TEXT ); + MALLOC_ASSERT( block->isOwnedByCurrentThread(), ASSERT_TEXT ); + // it is the caller responsibility to keep bin consistence (i.e. ensure this block is in the bin list) + activeBlk = block; +} + +inline Block* Bin::setPreviousBlockActive() +{ + MALLOC_ASSERT( activeBlk, ASSERT_TEXT ); + Block* temp = activeBlk->previous; + if( temp ) { + MALLOC_ASSERT( !(temp->isFull), ASSERT_TEXT ); + activeBlk = temp; + } + return temp; +} + +inline bool Block::isOwnedByCurrentThread() const { + return tlsPtr && ownerTid.isCurrentThreadId(); +} + +FreeObject *Block::findObjectToFree(const void *object) const +{ + FreeObject *objectToFree; + // Due to aligned allocations, a pointer passed to scalable_free + // might differ from the address of internally allocated object. + // Small objects however should always be fine. + if (objectSize <= maxSegregatedObjectSize) + objectToFree = (FreeObject*)object; + // "Fitting size" allocations are suspicious if aligned higher than naturally + else { + if ( ! isAligned(object,2*fittingAlignment) ) + // TODO: the above check is questionable - it gives false negatives in ~50% cases, + // so might even be slower in average than unconditional use of findAllocatedObject. + // here it should be a "real" object + objectToFree = (FreeObject*)object; + else + // here object can be an aligned address, so applying additional checks + objectToFree = findAllocatedObject(object); + MALLOC_ASSERT( isAligned(objectToFree,fittingAlignment), ASSERT_TEXT ); + } + MALLOC_ASSERT( isProperlyPlaced(objectToFree), ASSERT_TEXT ); + + return objectToFree; +} + +void TLSData::release() +{ + memPool->extMemPool.allLocalCaches.unregisterThread(this); + externalCleanup(/*cleanOnlyUnused=*/false, /*cleanBins=*/false); + + for (unsigned index = 0; index < numBlockBins; index++) { + Block *activeBlk = bin[index].getActiveBlock(); + if (!activeBlk) + continue; + Block *threadlessBlock = activeBlk->previous; + while (threadlessBlock) { + Block *threadBlock = threadlessBlock->previous; + if (threadlessBlock->empty()) { + /* we destroy the thread, so not use its block pool */ + memPool->returnEmptyBlock(threadlessBlock, /*poolTheBlock=*/false); + } else { + memPool->extMemPool.orphanedBlocks.put(intptr_t(bin+index), threadlessBlock); + } + threadlessBlock = threadBlock; + } + threadlessBlock = activeBlk; + while (threadlessBlock) { + Block *threadBlock = threadlessBlock->next; + if (threadlessBlock->empty()) { + /* we destroy the thread, so not use its block pool */ + memPool->returnEmptyBlock(threadlessBlock, /*poolTheBlock=*/false); + } else { + memPool->extMemPool.orphanedBlocks.put(intptr_t(bin+index), threadlessBlock); + } + threadlessBlock = threadBlock; + } + bin[index].resetActiveBlock(); + } +} + + +#if MALLOC_CHECK_RECURSION +// TODO: Use dedicated heap for this + +/* + * It's a special kind of allocation that can be used when malloc is + * not available (either during startup or when malloc was already called and + * we are, say, inside pthread_setspecific's call). + * Block can contain objects of different sizes, + * allocations are performed by moving bump pointer and increasing of object counter, + * releasing is done via counter of objects allocated in the block + * or moving bump pointer if releasing object is on a bound. + * TODO: make bump pointer to grow to the same backward direction as all the others. + */ + +class StartupBlock : public Block { + size_t availableSize() const { + return slabSize - ((uintptr_t)bumpPtr - (uintptr_t)this); + } + static StartupBlock *getBlock(); +public: + static FreeObject *allocate(size_t size); + static size_t msize(void *ptr) { return *((size_t*)ptr - 1); } + void free(void *ptr); +}; + +static MallocMutex startupMallocLock; +static StartupBlock *firstStartupBlock; + +StartupBlock *StartupBlock::getBlock() +{ + BackRefIdx backRefIdx = BackRefIdx::newBackRef(/*largeObj=*/false); + if (backRefIdx.isInvalid()) return NULL; + + StartupBlock *block = static_cast<StartupBlock*>( + defaultMemPool->extMemPool.backend.getSlabBlock(1)); + if (!block) return NULL; + + block->cleanBlockHeader(); + setBackRef(backRefIdx, block); + block->backRefIdx = backRefIdx; + // use startupAllocObjSizeMark to mark objects from startup block marker + block->objectSize = startupAllocObjSizeMark; + block->bumpPtr = (FreeObject *)((uintptr_t)block + sizeof(StartupBlock)); + return block; +} + +FreeObject *StartupBlock::allocate(size_t size) +{ + FreeObject *result; + StartupBlock *newBlock = NULL; + bool newBlockUnused = false; + + /* Objects must be aligned on their natural bounds, + and objects bigger than word on word's bound. */ + size = alignUp(size, sizeof(size_t)); + // We need size of an object to implement msize. + size_t reqSize = size + sizeof(size_t); + // speculatively allocates newBlock to try avoid allocation while holding lock + /* TODO: The function is called when malloc nested call is detected, + so simultaneous usage from different threads seems unlikely. + If pre-allocation is found useless, the code might be simplified. */ + if (!firstStartupBlock || firstStartupBlock->availableSize() < reqSize) { + newBlock = StartupBlock::getBlock(); + if (!newBlock) return NULL; + } + { + MallocMutex::scoped_lock scoped_cs(startupMallocLock); + // Re-check whether we need a new block (conditions might have changed) + if (!firstStartupBlock || firstStartupBlock->availableSize() < reqSize) { + if (!newBlock) { + newBlock = StartupBlock::getBlock(); + if (!newBlock) return NULL; + } + newBlock->next = (Block*)firstStartupBlock; + if (firstStartupBlock) + firstStartupBlock->previous = (Block*)newBlock; + firstStartupBlock = newBlock; + } else + newBlockUnused = true; + result = firstStartupBlock->bumpPtr; + firstStartupBlock->allocatedCount++; + firstStartupBlock->bumpPtr = + (FreeObject *)((uintptr_t)firstStartupBlock->bumpPtr + reqSize); + } + if (newBlock && newBlockUnused) + defaultMemPool->returnEmptyBlock(newBlock, /*poolTheBlock=*/false); + + // keep object size at the negative offset + *((size_t*)result) = size; + return (FreeObject*)((size_t*)result+1); +} + +void StartupBlock::free(void *ptr) +{ + Block* blockToRelease = NULL; + { + MallocMutex::scoped_lock scoped_cs(startupMallocLock); + + MALLOC_ASSERT(firstStartupBlock, ASSERT_TEXT); + MALLOC_ASSERT(startupAllocObjSizeMark==objectSize + && allocatedCount>0, ASSERT_TEXT); + MALLOC_ASSERT((uintptr_t)ptr>=(uintptr_t)this+sizeof(StartupBlock) + && (uintptr_t)ptr+StartupBlock::msize(ptr)<=(uintptr_t)this+slabSize, + ASSERT_TEXT); + if (0 == --allocatedCount) { + if (this == firstStartupBlock) + firstStartupBlock = (StartupBlock*)firstStartupBlock->next; + if (previous) + previous->next = next; + if (next) + next->previous = previous; + blockToRelease = this; + } else if ((uintptr_t)ptr + StartupBlock::msize(ptr) == (uintptr_t)bumpPtr) { + // last object in the block released + FreeObject *newBump = (FreeObject*)((size_t*)ptr - 1); + MALLOC_ASSERT((uintptr_t)newBump>(uintptr_t)this+sizeof(StartupBlock), + ASSERT_TEXT); + bumpPtr = newBump; + } + } + if (blockToRelease) { + blockToRelease->previous = blockToRelease->next = NULL; + defaultMemPool->returnEmptyBlock(blockToRelease, /*poolTheBlock=*/false); + } +} + +#endif /* MALLOC_CHECK_RECURSION */ + +/********* End thread related code *************/ + +/********* Library initialization *************/ + +//! Value indicating the state of initialization. +/* 0 = initialization not started. + * 1 = initialization started but not finished. + * 2 = initialization finished. + * In theory, we only need values 0 and 2. But value 1 is nonetheless + * useful for detecting errors in the double-check pattern. + */ +static intptr_t mallocInitialized; // implicitly initialized to 0 +static MallocMutex initMutex; + +/** The leading "\0" is here so that applying "strings" to the binary + delivers a clean result. */ +static char VersionString[] = "\0" TBBMALLOC_VERSION_STRINGS; + +#if USE_PTHREAD && (__TBB_SOURCE_DIRECTLY_INCLUDED || __TBB_USE_DLOPEN_REENTRANCY_WORKAROUND) + +/* Decrease race interval between dynamic library unloading and pthread key + destructor. Protect only Pthreads with supported unloading. */ +class ShutdownSync { +/* flag is the number of threads in pthread key dtor body + (i.e., between threadDtorStart() and threadDtorDone()) + or the signal to skip dtor, if flag < 0 */ + intptr_t flag; + static const intptr_t skipDtor = INTPTR_MIN/2; +public: + void init() { flag = 0; } +/* Suppose that 2*abs(skipDtor) or more threads never call threadDtorStart() + simultaneously, so flag never becomes negative because of that. */ + bool threadDtorStart() { + if (flag < 0) + return false; + if (AtomicIncrement(flag) <= 0) { // note that new value returned + AtomicAdd(flag, -1); // flag is spoiled by us, restore it + return false; + } + return true; + } + void threadDtorDone() { + AtomicAdd(flag, -1); + } + void processExit() { + if (AtomicAdd(flag, skipDtor) != 0) + SpinWaitUntilEq(flag, skipDtor); + } +}; + +#else + +class ShutdownSync { +public: + void init() { } + bool threadDtorStart() { return true; } + void threadDtorDone() { } + void processExit() { } +}; + +#endif // USE_PTHREAD && (__TBB_SOURCE_DIRECTLY_INCLUDED || __TBB_USE_DLOPEN_REENTRANCY_WORKAROUND) + +static ShutdownSync shutdownSync; + +inline bool isMallocInitialized() { + // Load must have acquire fence; otherwise thread taking "initialized" path + // might perform textually later loads *before* mallocInitialized becomes 2. + return 2 == FencedLoad(mallocInitialized); +} + +bool isMallocInitializedExt() { + return isMallocInitialized(); +} + +/* Caller is responsible for ensuring this routine is called exactly once. */ +extern "C" void MallocInitializeITT() { +#if DO_ITT_NOTIFY + if (!usedBySrcIncluded) + tbb::internal::__TBB_load_ittnotify(); +#endif +} + +void MemoryPool::initDefaultPool() { + hugePages.init(); +} + +/* + * Allocator initialization routine; + * it is called lazily on the very first scalable_malloc call. + */ +static bool initMemoryManager() +{ + TRACEF(( "[ScalableMalloc trace] sizeof(Block) is %d (expected 128); sizeof(uintptr_t) is %d\n", + sizeof(Block), sizeof(uintptr_t) )); + MALLOC_ASSERT( 2*blockHeaderAlignment == sizeof(Block), ASSERT_TEXT ); + MALLOC_ASSERT( sizeof(FreeObject) == sizeof(void*), ASSERT_TEXT ); + MALLOC_ASSERT( isAligned(defaultMemPool, sizeof(intptr_t)), + "Memory pool must be void*-aligned for atomic to work over aligned arguments."); + +#if USE_WINTHREAD + const size_t granularity = 64*1024; // granulatity of VirtualAlloc +#else + // POSIX.1-2001-compliant way to get page size + const size_t granularity = sysconf(_SC_PAGESIZE); +#endif + if (!defaultMemPool) { + // Do not rely on static constructors and do the assignment in case + // of library static section not initialized at this call yet. + defaultMemPool = (MemoryPool*)defaultMemPool_space; + } + bool initOk = defaultMemPool-> + extMemPool.init(0, NULL, NULL, granularity, + /*keepAllMemory=*/false, /*fixedPool=*/false); +// TODO: extMemPool.init() to not allocate memory + if (!initOk || !initBackRefMaster(&defaultMemPool->extMemPool.backend) || !ThreadId::init()) + return false; + MemoryPool::initDefaultPool(); + // init() is required iff initMemoryManager() is called + // after mallocProcessShutdownNotification() + shutdownSync.init(); +#if COLLECT_STATISTICS + initStatisticsCollection(); +#endif + return true; +} + +static bool GetBoolEnvironmentVariable(const char* name) { + return tbb::internal::GetBoolEnvironmentVariable(name); +} + +//! Ensures that initMemoryManager() is called once and only once. +/** Does not return until initMemoryManager() has been completed by a thread. + There is no need to call this routine if mallocInitialized==2 . */ +static bool doInitialization() +{ + MallocMutex::scoped_lock lock( initMutex ); + if (mallocInitialized!=2) { + MALLOC_ASSERT( mallocInitialized==0, ASSERT_TEXT ); + mallocInitialized = 1; + RecursiveMallocCallProtector scoped; + if (!initMemoryManager()) { + mallocInitialized = 0; // restore and out + return false; + } +#ifdef MALLOC_EXTRA_INITIALIZATION + MALLOC_EXTRA_INITIALIZATION; +#endif +#if MALLOC_CHECK_RECURSION + RecursiveMallocCallProtector::detectNaiveOverload(); +#endif + MALLOC_ASSERT( mallocInitialized==1, ASSERT_TEXT ); + // Store must have release fence, otherwise mallocInitialized==2 + // might become remotely visible before side effects of + // initMemoryManager() become remotely visible. + FencedStore( mallocInitialized, 2 ); + if( GetBoolEnvironmentVariable("TBB_VERSION") ) { + fputs(VersionString+1,stderr); + hugePages.printStatus(); + } + } + /* It can't be 0 or I would have initialized it */ + MALLOC_ASSERT( mallocInitialized==2, ASSERT_TEXT ); + return true; +} + +/********* End library initialization *************/ + +/********* The malloc show begins *************/ + + +FreeObject *Block::allocateFromFreeList() +{ + FreeObject *result; + + if (!freeList) return NULL; + + result = freeList; + MALLOC_ASSERT( result, ASSERT_TEXT ); + + freeList = result->next; + MALLOC_ASSERT( allocatedCount < (slabSize-sizeof(Block))/objectSize, ASSERT_TEXT ); + allocatedCount++; + STAT_increment(getThreadId(), getIndex(objectSize), allocFreeListUsed); + + return result; +} + +FreeObject *Block::allocateFromBumpPtr() +{ + FreeObject *result = bumpPtr; + if (result) { + bumpPtr = (FreeObject *) ((uintptr_t) bumpPtr - objectSize); + if ( (uintptr_t)bumpPtr < (uintptr_t)this+sizeof(Block) ) { + bumpPtr = NULL; + } + MALLOC_ASSERT( allocatedCount < (slabSize-sizeof(Block))/objectSize, ASSERT_TEXT ); + allocatedCount++; + STAT_increment(getThreadId(), getIndex(objectSize), allocBumpPtrUsed); + } + return result; +} + +inline FreeObject* Block::allocate() +{ + MALLOC_ASSERT( isOwnedByCurrentThread(), ASSERT_TEXT ); + + /* for better cache locality, first looking in the free list. */ + if ( FreeObject *result = allocateFromFreeList() ) { + return result; + } + MALLOC_ASSERT( !freeList, ASSERT_TEXT ); + + /* if free list is empty, try thread local bump pointer allocation. */ + if ( FreeObject *result = allocateFromBumpPtr() ) { + return result; + } + MALLOC_ASSERT( !bumpPtr, ASSERT_TEXT ); + + /* the block is considered full. */ + isFull = true; + return NULL; +} + +size_t Block::findObjectSize(void *object) const +{ + size_t blSize = getSize(); +#if MALLOC_CHECK_RECURSION + // Currently, there is no aligned allocations from startup blocks, + // so we can return just StartupBlock::msize(). + // TODO: This must be extended if we add aligned allocation from startup blocks. + if (!blSize) + return StartupBlock::msize(object); +#endif + // object can be aligned, so real size can be less than block's + size_t size = + blSize - ((uintptr_t)object - (uintptr_t)findObjectToFree(object)); + MALLOC_ASSERT(size>0 && size<minLargeObjectSize, ASSERT_TEXT); + return size; +} + +void Bin::moveBlockToFront(Block *block) +{ + /* move the block to the front of the bin */ + if (block == activeBlk) return; + outofTLSBin(block); + pushTLSBin(block); +} + +void Bin::processEmptyBlock(Block *block, bool poolTheBlock) +{ + if (block != activeBlk) { + /* We are not using this block; return it to the pool */ + outofTLSBin(block); + block->getMemPool()->returnEmptyBlock(block, poolTheBlock); + } else { + /* all objects are free - let's restore the bump pointer */ + block->restoreBumpPtr(); + } +} + +template<int LOW_MARK, int HIGH_MARK> +bool LocalLOCImpl<LOW_MARK, HIGH_MARK>::put(LargeMemoryBlock *object, ExtMemoryPool *extMemPool) +{ + const size_t size = object->unalignedSize; + // not spoil cache with too large object, that can cause its total cleanup + if (size > MAX_TOTAL_SIZE) + return false; + LargeMemoryBlock *localHead = (LargeMemoryBlock*)AtomicFetchStore(&head, 0); + + object->prev = NULL; + object->next = localHead; + if (localHead) + localHead->prev = object; + else { + // those might not be cleaned during local cache stealing, correct them + totalSize = 0; + numOfBlocks = 0; + tail = object; + } + localHead = object; + totalSize += size; + numOfBlocks++; + // must meet both size and number of cached objects constrains + if (totalSize > MAX_TOTAL_SIZE || numOfBlocks >= HIGH_MARK) { + // scanning from tail until meet conditions + while (totalSize > MAX_TOTAL_SIZE || numOfBlocks > LOW_MARK) { + totalSize -= tail->unalignedSize; + numOfBlocks--; + tail = tail->prev; + } + LargeMemoryBlock *headToRelease = tail->next; + tail->next = NULL; + + extMemPool->freeLargeObjectList(headToRelease); + } + + FencedStore((intptr_t&)head, (intptr_t)localHead); + return true; +} + +template<int LOW_MARK, int HIGH_MARK> +LargeMemoryBlock *LocalLOCImpl<LOW_MARK, HIGH_MARK>::get(size_t size) +{ + LargeMemoryBlock *localHead, *res=NULL; + + if (size > MAX_TOTAL_SIZE) + return NULL; + + if (!head || (localHead = (LargeMemoryBlock*)AtomicFetchStore(&head, 0)) == NULL) { + // do not restore totalSize, numOfBlocks and tail at this point, + // as they are used only in put(), where they must be restored + return NULL; + } + + for (LargeMemoryBlock *curr = localHead; curr; curr=curr->next) { + if (curr->unalignedSize == size) { + res = curr; + if (curr->next) + curr->next->prev = curr->prev; + else + tail = curr->prev; + if (curr != localHead) + curr->prev->next = curr->next; + else + localHead = curr->next; + totalSize -= size; + numOfBlocks--; + break; + } + } + FencedStore((intptr_t&)head, (intptr_t)localHead); + return res; +} + +template<int LOW_MARK, int HIGH_MARK> +bool LocalLOCImpl<LOW_MARK, HIGH_MARK>::externalCleanup(ExtMemoryPool *extMemPool) +{ + if (LargeMemoryBlock *localHead = (LargeMemoryBlock*)AtomicFetchStore(&head, 0)) { + extMemPool->freeLargeObjectList(localHead); + return true; + } + return false; +} + +void *MemoryPool::getFromLLOCache(TLSData* tls, size_t size, size_t alignment) +{ + LargeMemoryBlock *lmb = NULL; + + size_t headersSize = sizeof(LargeMemoryBlock)+sizeof(LargeObjectHdr); + size_t allocationSize = LargeObjectCache::alignToBin(size+headersSize+alignment); + if (allocationSize < size) // allocationSize is wrapped around after alignToBin + return NULL; + MALLOC_ASSERT(allocationSize >= alignment, "Overflow must be checked before."); + + if (tls) { + tls->markUsed(); + lmb = tls->lloc.get(allocationSize); + } + if (!lmb) + lmb = extMemPool.mallocLargeObject(this, allocationSize); + + if (lmb) { + // doing shuffle we suppose that alignment offset guarantees + // that different cache lines are in use + MALLOC_ASSERT(alignment >= estimatedCacheLineSize, ASSERT_TEXT); + + void *alignedArea = (void*)alignUp((uintptr_t)lmb+headersSize, alignment); + uintptr_t alignedRight = + alignDown((uintptr_t)lmb+lmb->unalignedSize - size, alignment); + // Has some room to shuffle object between cache lines? + // Note that alignedRight and alignedArea are aligned at alignment. + unsigned ptrDelta = alignedRight - (uintptr_t)alignedArea; + if (ptrDelta && tls) { // !tls is cold path + // for the hot path of alignment==estimatedCacheLineSize, + // allow compilers to use shift for division + // (since estimatedCacheLineSize is a power-of-2 constant) + unsigned numOfPossibleOffsets = alignment == estimatedCacheLineSize? + ptrDelta / estimatedCacheLineSize : + ptrDelta / alignment; + unsigned myCacheIdx = ++tls->currCacheIdx; + unsigned offset = myCacheIdx % numOfPossibleOffsets; + + // Move object to a cache line with an offset that is different from + // previous allocation. This supposedly allows us to use cache + // associativity more efficiently. + alignedArea = (void*)((uintptr_t)alignedArea + offset*alignment); + } + MALLOC_ASSERT((uintptr_t)lmb+lmb->unalignedSize >= + (uintptr_t)alignedArea+size, "Object doesn't fit the block."); + LargeObjectHdr *header = (LargeObjectHdr*)alignedArea-1; + header->memoryBlock = lmb; + header->backRefIdx = lmb->backRefIdx; + setBackRef(header->backRefIdx, header); + + lmb->objectSize = size; + + MALLOC_ASSERT( isLargeObject<unknownMem>(alignedArea), ASSERT_TEXT ); + MALLOC_ASSERT( isAligned(alignedArea, alignment), ASSERT_TEXT ); + + return alignedArea; + } + return NULL; +} + +void MemoryPool::putToLLOCache(TLSData *tls, void *object) +{ + LargeObjectHdr *header = (LargeObjectHdr*)object - 1; + // overwrite backRefIdx to simplify double free detection + header->backRefIdx = BackRefIdx(); + + if (tls) { + tls->markUsed(); + if (tls->lloc.put(header->memoryBlock, &extMemPool)) + return; + } + extMemPool.freeLargeObject(header->memoryBlock); +} + +/* + * All aligned allocations fall into one of the following categories: + * 1. if both request size and alignment are <= maxSegregatedObjectSize, + * we just align the size up, and request this amount, because for every size + * aligned to some power of 2, the allocated object is at least that aligned. + * 2. for size<minLargeObjectSize, check if already guaranteed fittingAlignment is enough. + * 3. if size+alignment<minLargeObjectSize, we take an object of fittingSizeN and align + * its address up; given such pointer, scalable_free could find the real object. + * Wrapping of size+alignment is impossible because maximal allowed + * alignment plus minLargeObjectSize can't lead to wrapping. + * 4. otherwise, aligned large object is allocated. + */ +static void *allocateAligned(MemoryPool *memPool, size_t size, size_t alignment) +{ + MALLOC_ASSERT( isPowerOfTwo(alignment), ASSERT_TEXT ); + + if (!isMallocInitialized()) + if (!doInitialization()) + return NULL; + + void *result; + if (size<=maxSegregatedObjectSize && alignment<=maxSegregatedObjectSize) + result = internalPoolMalloc(memPool, alignUp(size? size: sizeof(size_t), alignment)); + else if (size<minLargeObjectSize) { + if (alignment<=fittingAlignment) + result = internalPoolMalloc(memPool, size); + else if (size+alignment < minLargeObjectSize) { + void *unaligned = internalPoolMalloc(memPool, size+alignment); + if (!unaligned) return NULL; + result = alignUp(unaligned, alignment); + } else + goto LargeObjAlloc; + } else { + LargeObjAlloc: + TLSData *tls = memPool->getTLS(/*create=*/true); + // take into account only alignment that are higher then natural + result = + memPool->getFromLLOCache(tls, size, largeObjectAlignment>alignment? + largeObjectAlignment: alignment); + } + + MALLOC_ASSERT( isAligned(result, alignment), ASSERT_TEXT ); + return result; +} + +static void *reallocAligned(MemoryPool *memPool, void *ptr, + size_t newSize, size_t alignment = 0) +{ + void *result; + size_t copySize; + + if (isLargeObject<ourMem>(ptr)) { + LargeMemoryBlock* lmb = ((LargeObjectHdr *)ptr - 1)->memoryBlock; + copySize = lmb->unalignedSize-((uintptr_t)ptr-(uintptr_t)lmb); + + // Apply different strategies if size decreases + if (newSize <= copySize && (0 == alignment || isAligned(ptr, alignment))) { + + // For huge objects (that do not fit in backend cache), keep the same space unless + // the new size is at least twice smaller + bool isMemoryBlockHuge = copySize > memPool->extMemPool.backend.getMaxBinnedSize(); + size_t threshold = isMemoryBlockHuge ? copySize / 2 : 0; + if (newSize > threshold) { + lmb->objectSize = newSize; + return ptr; + } + // TODO: For large objects suitable for the backend cache, + // split out the excessive part and put it to the backend. + } + // Reallocate for real + copySize = lmb->objectSize; +#if BACKEND_HAS_MREMAP + if (void *r = memPool->extMemPool.remap(ptr, copySize, newSize, + alignment < largeObjectAlignment ? largeObjectAlignment : alignment)) + return r; +#endif + result = alignment ? allocateAligned(memPool, newSize, alignment) : + internalPoolMalloc(memPool, newSize); + + } else { + Block* block = (Block *)alignDown(ptr, slabSize); + copySize = block->findObjectSize(ptr); + + // TODO: Move object to another bin if size decreases and the current bin is "empty enough". + // Currently, in case of size decreasing, old pointer is returned + if (newSize <= copySize && (0==alignment || isAligned(ptr, alignment))) { + return ptr; + } else { + result = alignment ? allocateAligned(memPool, newSize, alignment) : + internalPoolMalloc(memPool, newSize); + } + } + if (result) { + memcpy(result, ptr, copySize < newSize ? copySize : newSize); + internalPoolFree(memPool, ptr, 0); + } + return result; +} + +/* A predicate checks if an object is properly placed inside its block */ +inline bool Block::isProperlyPlaced(const void *object) const +{ + return 0 == ((uintptr_t)this + slabSize - (uintptr_t)object) % objectSize; +} + +/* Finds the real object inside the block */ +FreeObject *Block::findAllocatedObject(const void *address) const +{ + // calculate offset from the end of the block space + uint16_t offset = (uintptr_t)this + slabSize - (uintptr_t)address; + MALLOC_ASSERT( offset<=slabSize-sizeof(Block), ASSERT_TEXT ); + // find offset difference from a multiple of allocation size + offset %= objectSize; + // and move the address down to where the real object starts. + return (FreeObject*)((uintptr_t)address - (offset? objectSize-offset: 0)); +} + +/* + * Bad dereference caused by a foreign pointer is possible only here, not earlier in call chain. + * Separate function isolates SEH code, as it has bad influence on compiler optimization. + */ +static inline BackRefIdx safer_dereference (const BackRefIdx *ptr) +{ + BackRefIdx id; +#if _MSC_VER + __try { +#endif + id = *ptr; +#if _MSC_VER + } __except( GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION? + EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ) { + id = BackRefIdx(); + } +#endif + return id; +} + +template<MemoryOrigin memOrigin> +bool isLargeObject(void *object) +{ + if (!isAligned(object, largeObjectAlignment)) + return false; + LargeObjectHdr *header = (LargeObjectHdr*)object - 1; + BackRefIdx idx = (memOrigin == unknownMem) ? + safer_dereference(&header->backRefIdx) : header->backRefIdx; + + return idx.isLargeObject() + // in valid LargeObjectHdr memoryBlock is not NULL + && header->memoryBlock + // in valid LargeObjectHdr memoryBlock points somewhere before header + // TODO: more strict check + && (uintptr_t)header->memoryBlock < (uintptr_t)header + && getBackRef(idx) == header; +} + +static inline bool isSmallObject (void *ptr) +{ + Block* expectedBlock = (Block*)alignDown(ptr, slabSize); + const BackRefIdx* idx = expectedBlock->getBackRefIdx(); + + bool isSmall = expectedBlock == getBackRef(safer_dereference(idx)); + if (isSmall) + expectedBlock->checkFreePrecond(ptr); + return isSmall; +} + +/**** Check if an object was allocated by scalable_malloc ****/ +static inline bool isRecognized (void* ptr) +{ + return defaultMemPool->extMemPool.backend.ptrCanBeValid(ptr) && + (isLargeObject<unknownMem>(ptr) || isSmallObject(ptr)); +} + +static inline void freeSmallObject(void *object) +{ + /* mask low bits to get the block */ + Block *block = (Block *)alignDown(object, slabSize); + block->checkFreePrecond(object); + +#if MALLOC_CHECK_RECURSION + if (block->isStartupAllocObject()) { + ((StartupBlock *)block)->free(object); + return; + } +#endif + if (block->isOwnedByCurrentThread()) { + block->freeOwnObject(object); + } else { /* Slower path to add to the shared list, the allocatedCount is updated by the owner thread in malloc. */ + FreeObject *objectToFree = block->findObjectToFree(object); + block->freePublicObject(objectToFree); + } +} + +static void *internalPoolMalloc(MemoryPool* memPool, size_t size) +{ + Bin* bin; + Block * mallocBlock; + + if (!memPool) return NULL; + + if (!size) size = sizeof(size_t); + + TLSData *tls = memPool->getTLS(/*create=*/true); + + /* Allocate a large object */ + if (size >= minLargeObjectSize) + return memPool->getFromLLOCache(tls, size, largeObjectAlignment); + + if (!tls) return NULL; + + tls->markUsed(); + /* + * Get an element in thread-local array corresponding to the given size; + * It keeps ptr to the active block for allocations of this size + */ + bin = tls->getAllocationBin(size); + if ( !bin ) return NULL; + + /* Get a block to try to allocate in. */ + for( mallocBlock = bin->getActiveBlock(); mallocBlock; + mallocBlock = bin->setPreviousBlockActive() ) // the previous block should be empty enough + { + if( FreeObject *result = mallocBlock->allocate() ) + return result; + } + + /* + * else privatize publicly freed objects in some block and allocate from it + */ + mallocBlock = bin->getPrivatizedFreeListBlock(); + if (mallocBlock) { + MALLOC_ASSERT( mallocBlock->freeListNonNull(), ASSERT_TEXT ); + if ( FreeObject *result = mallocBlock->allocateFromFreeList() ) + return result; + /* Else something strange happened, need to retry from the beginning; */ + TRACEF(( "[ScalableMalloc trace] Something is wrong: no objects in public free list; reentering.\n" )); + return internalPoolMalloc(memPool, size); + } + + /* + * no suitable own blocks, try to get a partial block that some other thread has discarded. + */ + mallocBlock = memPool->extMemPool.orphanedBlocks.get(tls, size); + while (mallocBlock) { + bin->pushTLSBin(mallocBlock); + bin->setActiveBlock(mallocBlock); // TODO: move under the below condition? + if( FreeObject *result = mallocBlock->allocate() ) + return result; + mallocBlock = memPool->extMemPool.orphanedBlocks.get(tls, size); + } + + /* + * else try to get a new empty block + */ + mallocBlock = memPool->getEmptyBlock(size); + if (mallocBlock) { + bin->pushTLSBin(mallocBlock); + bin->setActiveBlock(mallocBlock); + if( FreeObject *result = mallocBlock->allocate() ) + return result; + /* Else something strange happened, need to retry from the beginning; */ + TRACEF(( "[ScalableMalloc trace] Something is wrong: no objects in empty block; reentering.\n" )); + return internalPoolMalloc(memPool, size); + } + /* + * else nothing works so return NULL + */ + TRACEF(( "[ScalableMalloc trace] No memory found, returning NULL.\n" )); + return NULL; +} + +// When size==0 (i.e. unknown), detect here whether the object is large. +// For size is known and < minLargeObjectSize, we still need to check +// if the actual object is large, because large objects might be used +// for aligned small allocations. +static bool internalPoolFree(MemoryPool *memPool, void *object, size_t size) +{ + if (!memPool || !object) return false; + + // The library is initialized at allocation call, so releasing while + // not initialized means foreign object is releasing. + MALLOC_ASSERT(isMallocInitialized(), ASSERT_TEXT); + MALLOC_ASSERT(memPool->extMemPool.userPool() || isRecognized(object), + "Invalid pointer during object releasing is detected."); + + if (size >= minLargeObjectSize || isLargeObject<ourMem>(object)) + memPool->putToLLOCache(memPool->getTLS(/*create=*/false), object); + else + freeSmallObject(object); + return true; +} + +static void *internalMalloc(size_t size) +{ + if (!size) size = sizeof(size_t); + +#if MALLOC_CHECK_RECURSION + if (RecursiveMallocCallProtector::sameThreadActive()) + return size<minLargeObjectSize? StartupBlock::allocate(size) : + // nested allocation, so skip tls + (FreeObject*)defaultMemPool->getFromLLOCache(NULL, size, slabSize); +#endif + + if (!isMallocInitialized()) + if (!doInitialization()) + return NULL; + return internalPoolMalloc(defaultMemPool, size); +} + +static void internalFree(void *object) +{ + internalPoolFree(defaultMemPool, object, 0); +} + +static size_t internalMsize(void* ptr) +{ + MALLOC_ASSERT(ptr, "Invalid pointer passed to internalMsize"); + if (isLargeObject<ourMem>(ptr)) { + // TODO: return the maximum memory size, that can be written to this object + LargeMemoryBlock* lmb = ((LargeObjectHdr*)ptr - 1)->memoryBlock; + return lmb->objectSize; + } else { + Block *block = (Block*)alignDown(ptr, slabSize); + return block->findObjectSize(ptr); + } +} + +} // namespace internal + +using namespace rml::internal; + +// legacy entry point saved for compatibility with binaries complied +// with pre-6003 versions of TBB +rml::MemoryPool *pool_create(intptr_t pool_id, const MemPoolPolicy *policy) +{ + rml::MemoryPool *pool; + MemPoolPolicy pol(policy->pAlloc, policy->pFree, policy->granularity); + + pool_create_v1(pool_id, &pol, &pool); + return pool; +} + +rml::MemPoolError pool_create_v1(intptr_t pool_id, const MemPoolPolicy *policy, + rml::MemoryPool **pool) +{ + if ( !policy->pAlloc || policy->version<MemPoolPolicy::TBBMALLOC_POOL_VERSION + // empty pFree allowed only for fixed pools + || !(policy->fixedPool || policy->pFree)) { + *pool = NULL; + return INVALID_POLICY; + } + if ( policy->version>MemPoolPolicy::TBBMALLOC_POOL_VERSION // future versions are not supported + // new flags can be added in place of reserved, but default + // behaviour must be supported by this version + || policy->reserved ) { + *pool = NULL; + return UNSUPPORTED_POLICY; + } + if (!isMallocInitialized()) + if (!doInitialization()) { + *pool = NULL; + return NO_MEMORY; + } + rml::internal::MemoryPool *memPool = + (rml::internal::MemoryPool*)internalMalloc((sizeof(rml::internal::MemoryPool))); + if (!memPool) { + *pool = NULL; + return NO_MEMORY; + } + memset(memPool, 0, sizeof(rml::internal::MemoryPool)); + if (!memPool->init(pool_id, policy)) { + internalFree(memPool); + *pool = NULL; + return NO_MEMORY; + } + + *pool = (rml::MemoryPool*)memPool; + return POOL_OK; +} + +bool pool_destroy(rml::MemoryPool* memPool) +{ + if (!memPool) return false; + bool ret = ((rml::internal::MemoryPool*)memPool)->destroy(); + internalFree(memPool); + + return ret; +} + +bool pool_reset(rml::MemoryPool* memPool) +{ + if (!memPool) return false; + + return ((rml::internal::MemoryPool*)memPool)->reset(); +} + +void *pool_malloc(rml::MemoryPool* mPool, size_t size) +{ + return internalPoolMalloc((rml::internal::MemoryPool*)mPool, size); +} + +void *pool_realloc(rml::MemoryPool* mPool, void *object, size_t size) +{ + if (!object) + return internalPoolMalloc((rml::internal::MemoryPool*)mPool, size); + if (!size) { + internalPoolFree((rml::internal::MemoryPool*)mPool, object, 0); + return NULL; + } + return reallocAligned((rml::internal::MemoryPool*)mPool, object, size, 0); +} + +void *pool_aligned_malloc(rml::MemoryPool* mPool, size_t size, size_t alignment) +{ + if (!isPowerOfTwo(alignment) || 0==size) + return NULL; + + return allocateAligned((rml::internal::MemoryPool*)mPool, size, alignment); +} + +void *pool_aligned_realloc(rml::MemoryPool* memPool, void *ptr, size_t size, size_t alignment) +{ + if (!isPowerOfTwo(alignment)) + return NULL; + rml::internal::MemoryPool *mPool = (rml::internal::MemoryPool*)memPool; + void *tmp; + + if (!ptr) + tmp = allocateAligned(mPool, size, alignment); + else if (!size) { + internalPoolFree(mPool, ptr, 0); + return NULL; + } else + tmp = reallocAligned(mPool, ptr, size, alignment); + + return tmp; +} + +bool pool_free(rml::MemoryPool *mPool, void *object) +{ + return internalPoolFree((rml::internal::MemoryPool*)mPool, object, 0); +} + +rml::MemoryPool *pool_identify(void *object) +{ + rml::internal::MemoryPool *pool; + if (isLargeObject<ourMem>(object)) { + LargeObjectHdr *header = (LargeObjectHdr*)object - 1; + pool = header->memoryBlock->pool; + } else { + Block *block = (Block*)alignDown(object, slabSize); + pool = block->getMemPool(); + } + // do not return defaultMemPool, as it can't be used in pool_free() etc + __TBB_ASSERT_RELEASE(pool!=defaultMemPool, + "rml::pool_identify() can't be used for scalable_malloc() etc results."); + return (rml::MemoryPool*)pool; +} + +size_t pool_msize(rml::MemoryPool *mPool, void* object) +{ + if (object) { + // No assert for object recognition, cause objects allocated from non-default + // memory pool do not participate in range checking and do not have valid backreferences for + // small objects. Instead, check that an object belong to the certain memory pool. + MALLOC_ASSERT_EX(mPool == pool_identify(object), "Object does not belong to the specified pool"); + return internalMsize(object); + } + errno = EINVAL; + // Unlike _msize, return 0 in case of parameter error. + // Returning size_t(-1) looks more like the way to troubles. + return 0; +} + +} // namespace rml + +using namespace rml::internal; + +#if MALLOC_TRACE +static unsigned int threadGoingDownCount = 0; +#endif + +/* + * When a thread is shutting down this routine should be called to remove all the thread ids + * from the malloc blocks and replace them with a NULL thread id. + * + * For pthreads, the function is set as a callback in pthread_key_create for TLS bin. + * It will be automatically called at thread exit with the key value as the argument, + * unless that value is NULL. + * For Windows, it is called from DllMain( DLL_THREAD_DETACH ). + * + * However neither of the above is called for the main process thread, so the routine + * also needs to be called during the process shutdown. + * +*/ +// TODO: Consider making this function part of class MemoryPool. +void doThreadShutdownNotification(TLSData* tls, bool main_thread) +{ + TRACEF(( "[ScalableMalloc trace] Thread id %d blocks return start %d\n", + getThreadId(), threadGoingDownCount++ )); + +#if USE_PTHREAD + if (tls) { + if (!shutdownSync.threadDtorStart()) return; + tls->getMemPool()->onThreadShutdown(tls); + shutdownSync.threadDtorDone(); + } else +#endif + { + suppress_unused_warning(tls); // not used on Windows + // The default pool is safe to use at this point: + // on Linux, only the main thread can go here before destroying defaultMemPool; + // on Windows, shutdown is synchronized via loader lock and isMallocInitialized(). + // See also __TBB_mallocProcessShutdownNotification() + defaultMemPool->onThreadShutdown(defaultMemPool->getTLS(/*create=*/false)); + // Take lock to walk through other pools; but waiting might be dangerous at this point + // (e.g. on Windows the main thread might deadlock) + bool locked; + MallocMutex::scoped_lock lock(MemoryPool::memPoolListLock, /*wait=*/!main_thread, &locked); + if (locked) { // the list is safe to process + for (MemoryPool *memPool = defaultMemPool->next; memPool; memPool = memPool->next) + memPool->onThreadShutdown(memPool->getTLS(/*create=*/false)); + } + } + + TRACEF(( "[ScalableMalloc trace] Thread id %d blocks return end\n", getThreadId() )); +} + +#if USE_PTHREAD +void mallocThreadShutdownNotification(void* arg) +{ + // The routine is called for each pool (as TLS dtor) on each thread, except for the main thread + if (!isMallocInitialized()) return; + doThreadShutdownNotification((TLSData*)arg, false); +} +#else +extern "C" void __TBB_mallocThreadShutdownNotification() +{ + // The routine is called once per thread on Windows + if (!isMallocInitialized()) return; + doThreadShutdownNotification(NULL, false); +} +#endif + +extern "C" void __TBB_mallocProcessShutdownNotification(bool windows_process_dying) +{ + if (!isMallocInitialized()) return; + + // Don't clean allocator internals if the entire process is exiting + if (!windows_process_dying) { + doThreadShutdownNotification(NULL, /*main_thread=*/true); + } +#if __TBB_MALLOC_LOCACHE_STAT + printf("cache hit ratio %f, size hit %f\n", + 1.*cacheHits/mallocCalls, 1.*memHitKB/memAllocKB); + defaultMemPool->extMemPool.loc.reportStat(stdout); +#endif + + shutdownSync.processExit(); +#if __TBB_SOURCE_DIRECTLY_INCLUDED +/* Pthread keys must be deleted as soon as possible to not call key dtor + on thread termination when then the tbbmalloc code can be already unloaded. +*/ + defaultMemPool->destroy(); + destroyBackRefMaster(&defaultMemPool->extMemPool.backend); + ThreadId::destroy(); // Delete key for thread id + hugePages.reset(); + // new total malloc initialization is possible after this point + FencedStore(mallocInitialized, 0); +#elif __TBB_USE_DLOPEN_REENTRANCY_WORKAROUND +/* In most cases we prevent unloading tbbmalloc, and don't clean up memory + on process shutdown. When impossible to prevent, library unload results + in shutdown notification, and it makes sense to release unused memory + at that point (we can't release all memory because it's possible that + it will be accessed after this point). + TODO: better support systems where we can't prevent unloading by removing + pthread destructors and releasing caches. + */ + defaultMemPool->extMemPool.hardCachesCleanup(); +#endif // __TBB_SOURCE_DIRECTLY_INCLUDED + +#if COLLECT_STATISTICS + unsigned nThreads = ThreadId::getMaxThreadId(); + for( int i=1; i<=nThreads && i<MAX_THREADS; ++i ) + STAT_print(i); +#endif + if (!usedBySrcIncluded) + MALLOC_ITT_FINI_ITTLIB(); +} + +extern "C" void * scalable_malloc(size_t size) +{ + void *ptr = internalMalloc(size); + if (!ptr) errno = ENOMEM; + return ptr; +} + +extern "C" void scalable_free(void *object) +{ + internalFree(object); +} + +#if MALLOC_ZONE_OVERLOAD_ENABLED +extern "C" void __TBB_malloc_free_definite_size(void *object, size_t size) +{ + internalPoolFree(defaultMemPool, object, size); +} +#endif + +/* + * A variant that provides additional memory safety, by checking whether the given address + * was obtained with this allocator, and if not redirecting to the provided alternative call. + */ +extern "C" void __TBB_malloc_safer_free(void *object, void (*original_free)(void*)) +{ + if (!object) + return; + + // tbbmalloc can allocate object only when tbbmalloc has been initialized + if (FencedLoad(mallocInitialized) && defaultMemPool->extMemPool.backend.ptrCanBeValid(object)) { + if (isLargeObject<unknownMem>(object)) { + // must check 1st for large object, because small object check touches 4 pages on left, + // and it can be inaccessible + TLSData *tls = defaultMemPool->getTLS(/*create=*/false); + + defaultMemPool->putToLLOCache(tls, object); + return; + } else if (isSmallObject(object)) { + freeSmallObject(object); + return; + } + } + if (original_free) + original_free(object); +} + +/********* End the free code *************/ + +/********* Code for scalable_realloc ***********/ + +/* + * From K&R + * "realloc changes the size of the object pointed to by p to size. The contents will + * be unchanged up to the minimum of the old and the new sizes. If the new size is larger, + * the new space is uninitialized. realloc returns a pointer to the new space, or + * NULL if the request cannot be satisfied, in which case *p is unchanged." + * + */ +extern "C" void* scalable_realloc(void* ptr, size_t size) +{ + void *tmp; + + if (!ptr) + tmp = internalMalloc(size); + else if (!size) { + internalFree(ptr); + return NULL; + } else + tmp = reallocAligned(defaultMemPool, ptr, size, 0); + + if (!tmp) errno = ENOMEM; + return tmp; +} + +/* + * A variant that provides additional memory safety, by checking whether the given address + * was obtained with this allocator, and if not redirecting to the provided alternative call. + */ +extern "C" void* __TBB_malloc_safer_realloc(void* ptr, size_t sz, void* original_realloc) +{ + void *tmp; // TODO: fix warnings about uninitialized use of tmp + + if (!ptr) { + tmp = internalMalloc(sz); + } else if (FencedLoad(mallocInitialized) && isRecognized(ptr)) { + if (!sz) { + internalFree(ptr); + return NULL; + } else { + tmp = reallocAligned(defaultMemPool, ptr, sz, 0); + } + } +#if USE_WINTHREAD + else if (original_realloc && sz) { + orig_ptrs *original_ptrs = static_cast<orig_ptrs*>(original_realloc); + if ( original_ptrs->msize ){ + size_t oldSize = original_ptrs->msize(ptr); + tmp = internalMalloc(sz); + if (tmp) { + memcpy(tmp, ptr, sz<oldSize? sz : oldSize); + if ( original_ptrs->free ){ + original_ptrs->free( ptr ); + } + } + } else + tmp = NULL; + } +#else + else if (original_realloc) { + typedef void* (*realloc_ptr_t)(void*,size_t); + realloc_ptr_t original_realloc_ptr; + (void *&)original_realloc_ptr = original_realloc; + tmp = original_realloc_ptr(ptr,sz); + } +#endif + else tmp = NULL; + + if (!tmp) errno = ENOMEM; + return tmp; +} + +/********* End code for scalable_realloc ***********/ + +/********* Code for scalable_calloc ***********/ + +/* + * From K&R + * calloc returns a pointer to space for an array of nobj objects, + * each of size size, or NULL if the request cannot be satisfied. + * The space is initialized to zero bytes. + * + */ + +extern "C" void * scalable_calloc(size_t nobj, size_t size) +{ + // it's square root of maximal size_t value + const size_t mult_not_overflow = size_t(1) << (sizeof(size_t)*CHAR_BIT/2); + const size_t arraySize = nobj * size; + + // check for overflow during multiplication: + if (nobj>=mult_not_overflow || size>=mult_not_overflow) // 1) heuristic check + if (nobj && arraySize / nobj != size) { // 2) exact check + errno = ENOMEM; + return NULL; + } + void* result = internalMalloc(arraySize); + if (result) + memset(result, 0, arraySize); + else + errno = ENOMEM; + return result; +} + +/********* End code for scalable_calloc ***********/ + +/********* Code for aligned allocation API **********/ + +extern "C" int scalable_posix_memalign(void **memptr, size_t alignment, size_t size) +{ + if ( !isPowerOfTwoAtLeast(alignment, sizeof(void*)) ) + return EINVAL; + void *result = allocateAligned(defaultMemPool, size, alignment); + if (!result) + return ENOMEM; + *memptr = result; + return 0; +} + +extern "C" void * scalable_aligned_malloc(size_t size, size_t alignment) +{ + if (!isPowerOfTwo(alignment) || 0==size) { + errno = EINVAL; + return NULL; + } + void *tmp = allocateAligned(defaultMemPool, size, alignment); + if (!tmp) errno = ENOMEM; + return tmp; +} + +extern "C" void * scalable_aligned_realloc(void *ptr, size_t size, size_t alignment) +{ + if (!isPowerOfTwo(alignment)) { + errno = EINVAL; + return NULL; + } + void *tmp; + + if (!ptr) + tmp = allocateAligned(defaultMemPool, size, alignment); + else if (!size) { + scalable_free(ptr); + return NULL; + } else + tmp = reallocAligned(defaultMemPool, ptr, size, alignment); + + if (!tmp) errno = ENOMEM; + return tmp; +} + +extern "C" void * __TBB_malloc_safer_aligned_realloc(void *ptr, size_t size, size_t alignment, void* orig_function) +{ + /* corner cases left out of reallocAligned to not deal with errno there */ + if (!isPowerOfTwo(alignment)) { + errno = EINVAL; + return NULL; + } + void *tmp = NULL; + + if (!ptr) { + tmp = allocateAligned(defaultMemPool, size, alignment); + } else if (FencedLoad(mallocInitialized) && isRecognized(ptr)) { + if (!size) { + internalFree(ptr); + return NULL; + } else { + tmp = reallocAligned(defaultMemPool, ptr, size, alignment); + } + } +#if USE_WINTHREAD + else { + orig_aligned_ptrs *original_ptrs = static_cast<orig_aligned_ptrs*>(orig_function); + if (size) { + // Without orig_msize, we can't do anything with this. + // Just keeping old pointer. + if ( original_ptrs->aligned_msize ){ + // set alignment and offset to have possibly correct oldSize + size_t oldSize = original_ptrs->aligned_msize(ptr, sizeof(void*), 0); + tmp = allocateAligned(defaultMemPool, size, alignment); + if (tmp) { + memcpy(tmp, ptr, size<oldSize? size : oldSize); + if ( original_ptrs->aligned_free ){ + original_ptrs->aligned_free( ptr ); + } + } + } + } else { + if ( original_ptrs->aligned_free ){ + original_ptrs->aligned_free( ptr ); + } + return NULL; + } + } +#else + // As original_realloc can't align result, and there is no way to find + // size of reallocating object, we are giving up. + suppress_unused_warning(orig_function); +#endif + if (!tmp) errno = ENOMEM; + return tmp; +} + +extern "C" void scalable_aligned_free(void *ptr) +{ + internalFree(ptr); +} + +/********* end code for aligned allocation API **********/ + +/********* Code for scalable_msize ***********/ + +/* + * Returns the size of a memory block allocated in the heap. + */ +extern "C" size_t scalable_msize(void* ptr) +{ + if (ptr) { + MALLOC_ASSERT(isRecognized(ptr), "Invalid pointer in scalable_msize detected."); + return internalMsize(ptr); + } + errno = EINVAL; + // Unlike _msize, return 0 in case of parameter error. + // Returning size_t(-1) looks more like the way to troubles. + return 0; +} + +/* + * A variant that provides additional memory safety, by checking whether the given address + * was obtained with this allocator, and if not redirecting to the provided alternative call. + */ +extern "C" size_t __TBB_malloc_safer_msize(void *object, size_t (*original_msize)(void*)) +{ + if (object) { + // Check if the memory was allocated by scalable_malloc + if (FencedLoad(mallocInitialized) && isRecognized(object)) + return internalMsize(object); + else if (original_msize) + return original_msize(object); + } + // object is NULL or unknown, or foreign and no original_msize +#if USE_WINTHREAD + errno = EINVAL; // errno expected to be set only on this platform +#endif + return 0; +} + +/* + * The same as above but for _aligned_msize case + */ +extern "C" size_t __TBB_malloc_safer_aligned_msize(void *object, size_t alignment, size_t offset, size_t (*orig_aligned_msize)(void*,size_t,size_t)) +{ + if (object) { + // Check if the memory was allocated by scalable_malloc + if (FencedLoad(mallocInitialized) && isRecognized(object)) + return internalMsize(object); + else if (orig_aligned_msize) + return orig_aligned_msize(object,alignment,offset); + } + // object is NULL or unknown + errno = EINVAL; + return 0; +} + +/********* End code for scalable_msize ***********/ + +extern "C" int scalable_allocation_mode(int param, intptr_t value) +{ + if (param == TBBMALLOC_SET_SOFT_HEAP_LIMIT) { + defaultMemPool->extMemPool.backend.setRecommendedMaxSize((size_t)value); + return TBBMALLOC_OK; + } else if (param == USE_HUGE_PAGES) { +#if __linux__ + switch (value) { + case 0: + case 1: + hugePages.setMode(value); + return TBBMALLOC_OK; + default: + return TBBMALLOC_INVALID_PARAM; + } +#else + return TBBMALLOC_NO_EFFECT; +#endif +#if __TBB_SOURCE_DIRECTLY_INCLUDED + } else if (param == TBBMALLOC_INTERNAL_SOURCE_INCLUDED) { + switch (value) { + case 0: // used by dynamic library + case 1: // used by static library or directly included sources + usedBySrcIncluded = value; + return TBBMALLOC_OK; + default: + return TBBMALLOC_INVALID_PARAM; + } +#endif + } else if (param == TBBMALLOC_SET_HUGE_SIZE_THRESHOLD) { + defaultMemPool->extMemPool.loc.setHugeSizeThreshold((size_t)value); + return TBBMALLOC_OK; + } + return TBBMALLOC_INVALID_PARAM; +} + +extern "C" int scalable_allocation_command(int cmd, void *param) +{ + if (param) + return TBBMALLOC_INVALID_PARAM; + + bool released = false; + switch(cmd) { + case TBBMALLOC_CLEAN_THREAD_BUFFERS: + if (TLSData *tls = defaultMemPool->getTLS(/*create=*/false)) + released = tls->externalCleanup(/*cleanOnlyUnused*/false, /*cleanBins=*/true); + break; + case TBBMALLOC_CLEAN_ALL_BUFFERS: + released = defaultMemPool->extMemPool.hardCachesCleanup(); + break; + default: + return TBBMALLOC_INVALID_PARAM; + } + return released ? TBBMALLOC_OK : TBBMALLOC_NO_EFFECT; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/index.html b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/index.html new file mode 100644 index 00000000..28fc7e09 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/index.html @@ -0,0 +1,54 @@ +<HTML> +<body> +<H2>Overview</H2> +<P> +This directory contains the Intel® Threading Building Blocks (Intel® TBB) scalable allocator library source files. +</P> + +<HR> +<p></p> +Copyright © 2005-2020 Intel Corporation. All Rights Reserved. +<P></P> +Intel is a registered trademark or trademark of Intel Corporation +or its subsidiaries in the United States and other countries. +<p></p> +* Other names and brands may be claimed as the property of others. + +<P> +<H3>Third Party and Open Source Licenses</H3> +</P> +<P> + <pre> + proxy_overload_osx.h + // Copyright (c) 2011, Google Inc. + // All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions are + // met: + // + // * Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // * Redistributions in binary form must reproduce the above + // copyright notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // * Neither the name of Google Inc. nor the names of its + // contributors may be used to endorse or promote products derived from + // this software without specific prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + </pre> +</P> +</body> +</HTML> diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/large_objects.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/large_objects.cpp new file mode 100644 index 00000000..c5230b6f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/large_objects.cpp @@ -0,0 +1,1033 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbbmalloc_internal.h" +#include "tbb/tbb_environment.h" + +/******************************* Allocation of large objects *********************************************/ + +namespace rml { +namespace internal { + +/* ---------------------------- Large Object cache init section ---------------------------------------- */ + +void LargeObjectCache::init(ExtMemoryPool *memPool) +{ + extMemPool = memPool; + // scalable_allocation_mode can be called before allocator initialization, respect this manual request + if (hugeSizeThreshold == 0) { + // Huge size threshold initialization if environment variable was set + long requestedThreshold = tbb::internal::GetIntegralEnvironmentVariable("TBB_MALLOC_SET_HUGE_SIZE_THRESHOLD"); + // Read valid env or initialize by default with max possible values + if (requestedThreshold != -1) { + setHugeSizeThreshold(requestedThreshold); + } else { + setHugeSizeThreshold(maxHugeSize); + } + } +} + +/* ----------------------------- Huge size threshold settings ----------------------------------------- */ + +void LargeObjectCache::setHugeSizeThreshold(size_t value) +{ + // Valid in the huge cache range: [MaxLargeSize, MaxHugeSize]. + if (value <= maxHugeSize) { + hugeSizeThreshold = value >= maxLargeSize ? alignToBin(value) : maxLargeSize; + + // Calculate local indexes for the global threshold size (for fast search inside a regular cleanup) + largeCache.hugeSizeThresholdIdx = LargeCacheType::numBins; + hugeCache.hugeSizeThresholdIdx = HugeCacheType::sizeToIdx(hugeSizeThreshold); + } +} + +bool LargeObjectCache::sizeInCacheRange(size_t size) +{ + return size <= maxHugeSize && (size <= defaultMaxHugeSize || size >= hugeSizeThreshold); +} + +/* ----------------------------------------------------------------------------------------------------- */ + +/* The functor called by the aggregator for the operation list */ +template<typename Props> +class CacheBinFunctor { + typename LargeObjectCacheImpl<Props>::CacheBin *const bin; + ExtMemoryPool *const extMemPool; + typename LargeObjectCacheImpl<Props>::BinBitMask *const bitMask; + const int idx; + + LargeMemoryBlock *toRelease; + bool needCleanup; + uintptr_t currTime; + + /* Do preprocessing under the operation list. */ + /* All the OP_PUT_LIST operations are merged in the one operation. + All OP_GET operations are merged with the OP_PUT_LIST operations but + it demands the update of the moving average value in the bin. + Only the last OP_CLEAN_TO_THRESHOLD operation has sense. + The OP_CLEAN_ALL operation also should be performed only once. + Moreover it cancels the OP_CLEAN_TO_THRESHOLD operation. */ + class OperationPreprocessor { + // TODO: remove the dependency on CacheBin. + typename LargeObjectCacheImpl<Props>::CacheBin *const bin; + + /* Contains the relative time in the operation list. + It counts in the reverse order since the aggregator also + provides operations in the reverse order. */ + uintptr_t lclTime; + + /* opGet contains only OP_GET operations which cannot be merge with OP_PUT operations + opClean contains all OP_CLEAN_TO_THRESHOLD and OP_CLEAN_ALL operations. */ + CacheBinOperation *opGet, *opClean; + /* The time of the last OP_CLEAN_TO_THRESHOLD operations */ + uintptr_t cleanTime; + + /* lastGetOpTime - the time of the last OP_GET operation. + lastGet - the same meaning as CacheBin::lastGet */ + uintptr_t lastGetOpTime, lastGet; + + /* The total sum of all usedSize changes requested with CBOP_UPDATE_USED_SIZE operations. */ + size_t updateUsedSize; + + /* The list of blocks for the OP_PUT_LIST operation. */ + LargeMemoryBlock *head, *tail; + int putListNum; + + /* if the OP_CLEAN_ALL is requested. */ + bool isCleanAll; + + inline void commitOperation(CacheBinOperation *op) const; + inline void addOpToOpList(CacheBinOperation *op, CacheBinOperation **opList) const; + bool getFromPutList(CacheBinOperation* opGet, uintptr_t currTime); + void addToPutList( LargeMemoryBlock *head, LargeMemoryBlock *tail, int num ); + + public: + OperationPreprocessor(typename LargeObjectCacheImpl<Props>::CacheBin *bin) : + bin(bin), lclTime(0), opGet(NULL), opClean(NULL), cleanTime(0), + lastGetOpTime(0), updateUsedSize(0), head(NULL), isCleanAll(false) {} + void operator()(CacheBinOperation* opList); + uintptr_t getTimeRange() const { return -lclTime; } + + friend class CacheBinFunctor; + }; + +public: + CacheBinFunctor(typename LargeObjectCacheImpl<Props>::CacheBin *bin, ExtMemoryPool *extMemPool, + typename LargeObjectCacheImpl<Props>::BinBitMask *bitMask, int idx) : + bin(bin), extMemPool(extMemPool), bitMask(bitMask), idx(idx), toRelease(NULL), needCleanup(false) {} + void operator()(CacheBinOperation* opList); + + bool isCleanupNeeded() const { return needCleanup; } + LargeMemoryBlock *getToRelease() const { return toRelease; } + uintptr_t getCurrTime() const { return currTime; } +}; + +/* ---------------- Cache Bin Aggregator Operation Helpers ---------------- */ + +// The list of structures which describe the operation data +struct OpGet { + static const CacheBinOperationType type = CBOP_GET; + LargeMemoryBlock **res; + size_t size; + uintptr_t currTime; +}; + +struct OpPutList { + static const CacheBinOperationType type = CBOP_PUT_LIST; + LargeMemoryBlock *head; +}; + +struct OpCleanToThreshold { + static const CacheBinOperationType type = CBOP_CLEAN_TO_THRESHOLD; + LargeMemoryBlock **res; + uintptr_t currTime; +}; + +struct OpCleanAll { + static const CacheBinOperationType type = CBOP_CLEAN_ALL; + LargeMemoryBlock **res; +}; + +struct OpUpdateUsedSize { + static const CacheBinOperationType type = CBOP_UPDATE_USED_SIZE; + size_t size; +}; + +union CacheBinOperationData { +private: + OpGet opGet; + OpPutList opPutList; + OpCleanToThreshold opCleanToThreshold; + OpCleanAll opCleanAll; + OpUpdateUsedSize opUpdateUsedSize; +}; + +// Forward declarations +template <typename OpTypeData> OpTypeData& opCast(CacheBinOperation &op); + +// Describes the aggregator operation +struct CacheBinOperation : public MallocAggregatedOperation<CacheBinOperation>::type { + CacheBinOperationType type; + + template <typename OpTypeData> + CacheBinOperation(OpTypeData &d, CacheBinOperationStatus st = CBST_WAIT) { + opCast<OpTypeData>(*this) = d; + type = OpTypeData::type; + MallocAggregatedOperation<CacheBinOperation>::type::status = st; + } +private: + CacheBinOperationData data; + + template <typename OpTypeData> + friend OpTypeData& opCast(CacheBinOperation &op); +}; + +// The opCast function can be the member of CacheBinOperation but it will have +// small stylistic ambiguity: it will look like a getter (with a cast) for the +// CacheBinOperation::data data member but it should return a reference to +// simplify the code from a lot of getter/setter calls. So the global cast in +// the style of static_cast (or reinterpret_cast) seems to be more readable and +// have more explicit semantic. +template <typename OpTypeData> +OpTypeData& opCast(CacheBinOperation &op) { + return *reinterpret_cast<OpTypeData*>(&op.data); +} + +/* ------------------------------------------------------------------------ */ + +#if __TBB_MALLOC_LOCACHE_STAT +intptr_t mallocCalls, cacheHits; +intptr_t memAllocKB, memHitKB; +#endif + +inline bool lessThanWithOverflow(intptr_t a, intptr_t b) +{ + return (a < b && (b - a < UINTPTR_MAX/2)) || + (a > b && (a - b > UINTPTR_MAX/2)); +} + +/* ----------------------------------- Operation processing methods ------------------------------------ */ + +template<typename Props> void CacheBinFunctor<Props>:: + OperationPreprocessor::commitOperation(CacheBinOperation *op) const +{ + FencedStore( (intptr_t&)(op->status), CBST_DONE ); +} + +template<typename Props> void CacheBinFunctor<Props>:: + OperationPreprocessor::addOpToOpList(CacheBinOperation *op, CacheBinOperation **opList) const +{ + op->next = *opList; + *opList = op; +} + +template<typename Props> bool CacheBinFunctor<Props>:: + OperationPreprocessor::getFromPutList(CacheBinOperation *opGet, uintptr_t currTime) +{ + if ( head ) { + uintptr_t age = head->age; + LargeMemoryBlock *next = head->next; + *opCast<OpGet>(*opGet).res = head; + commitOperation( opGet ); + head = next; + putListNum--; + MALLOC_ASSERT( putListNum>=0, ASSERT_TEXT ); + + // use moving average with current hit interval + bin->updateMeanHitRange( currTime - age ); + return true; + } + return false; +} + +template<typename Props> void CacheBinFunctor<Props>:: + OperationPreprocessor::addToPutList(LargeMemoryBlock *h, LargeMemoryBlock *t, int num) +{ + if ( head ) { + MALLOC_ASSERT( tail, ASSERT_TEXT ); + tail->next = h; + h->prev = tail; + tail = t; + putListNum += num; + } else { + head = h; + tail = t; + putListNum = num; + } +} + +template<typename Props> void CacheBinFunctor<Props>:: + OperationPreprocessor::operator()(CacheBinOperation* opList) +{ + for ( CacheBinOperation *op = opList, *opNext; op; op = opNext ) { + opNext = op->next; + switch ( op->type ) { + case CBOP_GET: + { + lclTime--; + if ( !lastGetOpTime ) { + lastGetOpTime = lclTime; + lastGet = 0; + } else if ( !lastGet ) lastGet = lclTime; + + if ( !getFromPutList(op,lclTime) ) { + opCast<OpGet>(*op).currTime = lclTime; + addOpToOpList( op, &opGet ); + } + } + break; + + case CBOP_PUT_LIST: + { + LargeMemoryBlock *head = opCast<OpPutList>(*op).head; + LargeMemoryBlock *curr = head, *prev = NULL; + + int num = 0; + do { + // we do not kept prev pointers during assigning blocks to bins, set them now + curr->prev = prev; + + // Save the local times to the memory blocks. Local times are necessary + // for the getFromPutList function which updates the hit range value in + // CacheBin when OP_GET and OP_PUT_LIST operations are merged successfully. + // The age will be updated to the correct global time after preprocessing + // when global cache time is updated. + curr->age = --lclTime; + + prev = curr; + num += 1; + + STAT_increment(getThreadId(), ThreadCommonCounters, cacheLargeObj); + } while ((curr = curr->next) != NULL); + + LargeMemoryBlock *tail = prev; + addToPutList(head, tail, num); + + while ( opGet ) { + CacheBinOperation *next = opGet->next; + if ( !getFromPutList(opGet, opCast<OpGet>(*opGet).currTime) ) + break; + opGet = next; + } + } + break; + + case CBOP_UPDATE_USED_SIZE: + updateUsedSize += opCast<OpUpdateUsedSize>(*op).size; + commitOperation( op ); + break; + + case CBOP_CLEAN_ALL: + isCleanAll = true; + addOpToOpList( op, &opClean ); + break; + + case CBOP_CLEAN_TO_THRESHOLD: + { + uintptr_t currTime = opCast<OpCleanToThreshold>(*op).currTime; + // We don't worry about currTime overflow since it is a rare + // occurrence and doesn't affect correctness + cleanTime = cleanTime < currTime ? currTime : cleanTime; + addOpToOpList( op, &opClean ); + } + break; + + default: + MALLOC_ASSERT( false, "Unknown operation." ); + } + } + MALLOC_ASSERT( !( opGet && head ), "Not all put/get pairs are processed!" ); +} + +template<typename Props> void CacheBinFunctor<Props>::operator()(CacheBinOperation* opList) +{ + MALLOC_ASSERT( opList, "Empty operation list is passed into operation handler." ); + + OperationPreprocessor prep(bin); + prep(opList); + + if ( uintptr_t timeRange = prep.getTimeRange() ) { + uintptr_t startTime = extMemPool->loc.getCurrTimeRange(timeRange); + // endTime is used as the current (base) time since the local time is negative. + uintptr_t endTime = startTime + timeRange; + + if ( prep.lastGetOpTime && prep.lastGet ) bin->setLastGet(prep.lastGet+endTime); + + if ( CacheBinOperation *opGet = prep.opGet ) { + bool isEmpty = false; + do { +#if __TBB_MALLOC_WHITEBOX_TEST + tbbmalloc_whitebox::locGetProcessed++; +#endif + const OpGet &opGetData = opCast<OpGet>(*opGet); + if ( !isEmpty ) { + if ( LargeMemoryBlock *res = bin->get() ) { + uintptr_t getTime = opGetData.currTime + endTime; + // use moving average with current hit interval + bin->updateMeanHitRange( getTime - res->age); + bin->updateCachedSize( -opGetData.size ); + *opGetData.res = res; + } else { + isEmpty = true; + uintptr_t lastGetOpTime = prep.lastGetOpTime+endTime; + bin->forgetOutdatedState(lastGetOpTime); + bin->updateAgeThreshold(lastGetOpTime); + } + } + + CacheBinOperation *opNext = opGet->next; + bin->updateUsedSize( opGetData.size, bitMask, idx ); + prep.commitOperation( opGet ); + opGet = opNext; + } while ( opGet ); + if ( prep.lastGetOpTime ) + bin->setLastGet( prep.lastGetOpTime + endTime ); + } else if ( LargeMemoryBlock *curr = prep.head ) { + curr->prev = NULL; + while ( curr ) { + // Update local times to global times + curr->age += endTime; + curr=curr->next; + } +#if __TBB_MALLOC_WHITEBOX_TEST + tbbmalloc_whitebox::locPutProcessed+=prep.putListNum; +#endif + toRelease = bin->putList(prep.head, prep.tail, bitMask, idx, prep.putListNum, extMemPool->loc.hugeSizeThreshold); + } + needCleanup = extMemPool->loc.isCleanupNeededOnRange(timeRange, startTime); + currTime = endTime - 1; + } + + if ( CacheBinOperation *opClean = prep.opClean ) { + if ( prep.isCleanAll ) + *opCast<OpCleanAll>(*opClean).res = bin->cleanAll(bitMask, idx); + else + *opCast<OpCleanToThreshold>(*opClean).res = bin->cleanToThreshold(prep.cleanTime, bitMask, idx); + + CacheBinOperation *opNext = opClean->next; + prep.commitOperation( opClean ); + + while ((opClean = opNext) != NULL) { + opNext = opClean->next; + prep.commitOperation(opClean); + } + } + + if ( size_t size = prep.updateUsedSize ) + bin->updateUsedSize(size, bitMask, idx); +} +/* ----------------------------------------------------------------------------------------------------- */ +/* --------------------------- Methods for creating and executing operations --------------------------- */ +template<typename Props> void LargeObjectCacheImpl<Props>:: + CacheBin::ExecuteOperation(CacheBinOperation *op, ExtMemoryPool *extMemPool, BinBitMask *bitMask, int idx, bool longLifeTime) +{ + CacheBinFunctor<Props> func( this, extMemPool, bitMask, idx ); + aggregator.execute( op, func, longLifeTime ); + + if ( LargeMemoryBlock *toRelease = func.getToRelease()) { + extMemPool->backend.returnLargeObject(toRelease); + } + + if ( func.isCleanupNeeded() ) { + extMemPool->loc.doCleanup( func.getCurrTime(), /*doThreshDecr=*/false); + } +} + +template<typename Props> LargeMemoryBlock *LargeObjectCacheImpl<Props>:: + CacheBin::get(ExtMemoryPool *extMemPool, size_t size, BinBitMask *bitMask, int idx) +{ + LargeMemoryBlock *lmb=NULL; + OpGet data = {&lmb, size}; + CacheBinOperation op(data); + ExecuteOperation( &op, extMemPool, bitMask, idx ); + return lmb; +} + +template<typename Props> void LargeObjectCacheImpl<Props>:: + CacheBin::putList(ExtMemoryPool *extMemPool, LargeMemoryBlock *head, BinBitMask *bitMask, int idx) +{ + MALLOC_ASSERT(sizeof(LargeMemoryBlock)+sizeof(CacheBinOperation)<=head->unalignedSize, "CacheBinOperation is too large to be placed in LargeMemoryBlock!"); + + OpPutList data = {head}; + CacheBinOperation *op = new (head+1) CacheBinOperation(data, CBST_NOWAIT); + ExecuteOperation( op, extMemPool, bitMask, idx, false ); +} + +template<typename Props> bool LargeObjectCacheImpl<Props>:: + CacheBin::cleanToThreshold(ExtMemoryPool *extMemPool, BinBitMask *bitMask, uintptr_t currTime, int idx) +{ + LargeMemoryBlock *toRelease = NULL; + + /* oldest may be more recent then age, that's why cast to signed type + was used. age overflow is also processed correctly. */ + if (last && (intptr_t)(currTime - oldest) > ageThreshold) { + OpCleanToThreshold data = {&toRelease, currTime}; + CacheBinOperation op(data); + ExecuteOperation( &op, extMemPool, bitMask, idx ); + } + bool released = toRelease; + + Backend *backend = &extMemPool->backend; + while ( toRelease ) { + LargeMemoryBlock *helper = toRelease->next; + backend->returnLargeObject(toRelease); + toRelease = helper; + } + return released; +} + +template<typename Props> bool LargeObjectCacheImpl<Props>:: + CacheBin::releaseAllToBackend(ExtMemoryPool *extMemPool, BinBitMask *bitMask, int idx) +{ + LargeMemoryBlock *toRelease = NULL; + + if (last) { + OpCleanAll data = {&toRelease}; + CacheBinOperation op(data); + ExecuteOperation(&op, extMemPool, bitMask, idx); + } + bool released = toRelease; + + Backend *backend = &extMemPool->backend; + while ( toRelease ) { + LargeMemoryBlock *helper = toRelease->next; + MALLOC_ASSERT(!helper || lessThanWithOverflow(helper->age, toRelease->age), + ASSERT_TEXT); + backend->returnLargeObject(toRelease); + toRelease = helper; + } + return released; +} + +template<typename Props> void LargeObjectCacheImpl<Props>:: + CacheBin::updateUsedSize(ExtMemoryPool *extMemPool, size_t size, BinBitMask *bitMask, int idx) +{ + OpUpdateUsedSize data = {size}; + CacheBinOperation op(data); + ExecuteOperation( &op, extMemPool, bitMask, idx ); +} + +/* ------------------------------ Unsafe methods used with the aggregator ------------------------------ */ + +template<typename Props> LargeMemoryBlock *LargeObjectCacheImpl<Props>:: + CacheBin::putList(LargeMemoryBlock *head, LargeMemoryBlock *tail, BinBitMask *bitMask, int idx, int num, size_t hugeSizeThreshold) +{ + size_t size = head->unalignedSize; + usedSize -= num*size; + MALLOC_ASSERT( !last || (last->age != 0 && last->age != -1U), ASSERT_TEXT ); + MALLOC_ASSERT( (tail==head && num==1) || (tail!=head && num>1), ASSERT_TEXT ); + LargeMemoryBlock *toRelease = NULL; + if (size < hugeSizeThreshold && !lastCleanedAge) { + // 1st object of such size was released. + // Not cache it, and remember when this occurs + // to take into account during cache miss. + lastCleanedAge = tail->age; + toRelease = tail; + tail = tail->prev; + if (tail) + tail->next = NULL; + else + head = NULL; + num--; + } + if (num) { + // add [head;tail] list to cache + MALLOC_ASSERT( tail, ASSERT_TEXT ); + tail->next = first; + if (first) + first->prev = tail; + first = head; + if (!last) { + MALLOC_ASSERT(0 == oldest, ASSERT_TEXT); + oldest = tail->age; + last = tail; + } + + cachedSize += num*size; + } + + // No used object, and nothing in the bin, mark the bin as empty + if (!usedSize && !first) + bitMask->set(idx, false); + + return toRelease; +} + +template<typename Props> LargeMemoryBlock *LargeObjectCacheImpl<Props>:: + CacheBin::get() +{ + LargeMemoryBlock *result=first; + if (result) { + first = result->next; + if (first) + first->prev = NULL; + else { + last = NULL; + oldest = 0; + } + } + + return result; +} + +template<typename Props> void LargeObjectCacheImpl<Props>:: + CacheBin::forgetOutdatedState(uintptr_t currTime) +{ + // If the time since the last get is LongWaitFactor times more than ageThreshold + // for the bin, treat the bin as rarely-used and forget everything we know + // about it. + // If LongWaitFactor is too small, we forget too early and + // so prevents good caching, while if too high, caching blocks + // with unrelated usage pattern occurs. + const uintptr_t sinceLastGet = currTime - lastGet; + bool doCleanup = false; + + if (ageThreshold) + doCleanup = sinceLastGet > Props::LongWaitFactor * ageThreshold; + else if (lastCleanedAge) + doCleanup = sinceLastGet > Props::LongWaitFactor * (lastCleanedAge - lastGet); + + if (doCleanup) { + lastCleanedAge = 0; + ageThreshold = 0; + } + +} + +template<typename Props> LargeMemoryBlock *LargeObjectCacheImpl<Props>:: + CacheBin::cleanToThreshold(uintptr_t currTime, BinBitMask *bitMask, int idx) +{ + /* oldest may be more recent then age, that's why cast to signed type + was used. age overflow is also processed correctly. */ + if ( !last || (intptr_t)(currTime - last->age) < ageThreshold ) return NULL; + +#if MALLOC_DEBUG + uintptr_t nextAge = 0; +#endif + do { +#if MALLOC_DEBUG + // check that list ordered + MALLOC_ASSERT(!nextAge || lessThanWithOverflow(nextAge, last->age), + ASSERT_TEXT); + nextAge = last->age; +#endif + cachedSize -= last->unalignedSize; + last = last->prev; + } while (last && (intptr_t)(currTime - last->age) > ageThreshold); + + LargeMemoryBlock *toRelease = NULL; + if (last) { + toRelease = last->next; + oldest = last->age; + last->next = NULL; + } else { + toRelease = first; + first = NULL; + oldest = 0; + if (!usedSize) + bitMask->set(idx, false); + } + MALLOC_ASSERT( toRelease, ASSERT_TEXT ); + lastCleanedAge = toRelease->age; + + return toRelease; +} + +template<typename Props> LargeMemoryBlock *LargeObjectCacheImpl<Props>:: + CacheBin::cleanAll(BinBitMask *bitMask, int idx) +{ + if (!last) return NULL; + + LargeMemoryBlock *toRelease = first; + last = NULL; + first = NULL; + oldest = 0; + cachedSize = 0; + if (!usedSize) + bitMask->set(idx, false); + + return toRelease; +} + +/* ----------------------------------------------------------------------------------------------------- */ + +template<typename Props> size_t LargeObjectCacheImpl<Props>:: + CacheBin::reportStat(int num, FILE *f) +{ +#if __TBB_MALLOC_LOCACHE_STAT + if (first) + printf("%d(%lu): total %lu KB thr %ld lastCln %lu oldest %lu\n", + num, num*Props::CacheStep+Props::MinSize, + cachedSize/1024, ageThreshold, lastCleanedAge, oldest); +#else + suppress_unused_warning(num); + suppress_unused_warning(f); +#endif + return cachedSize; +} + +// Release objects from cache blocks that are older than ageThreshold +template<typename Props> +bool LargeObjectCacheImpl<Props>::regularCleanup(ExtMemoryPool *extMemPool, uintptr_t currTime, bool doThreshDecr) +{ + bool released = false; + BinsSummary binsSummary; + + // Threshold settings is below this cache or starts from zero index + if (hugeSizeThresholdIdx == 0) return false; + + // Starting searching for bin that is less than huge size threshold (can be cleaned-up) + int startSearchIdx = hugeSizeThresholdIdx - 1; + + for (int i = bitMask.getMaxTrue(startSearchIdx); i >= 0; i = bitMask.getMaxTrue(i-1)) { + bin[i].updateBinsSummary(&binsSummary); + if (!doThreshDecr && tooLargeLOC > 2 && binsSummary.isLOCTooLarge()) { + // if LOC is too large for quite long time, decrease the threshold + // based on bin hit statistics. + // For this, redo cleanup from the beginning. + // Note: on this iteration total usedSz can be not too large + // in comparison to total cachedSz, as we calculated it only + // partially. We are ok with it. + i = bitMask.getMaxTrue(startSearchIdx)+1; + doThreshDecr = true; + binsSummary.reset(); + continue; + } + if (doThreshDecr) + bin[i].decreaseThreshold(); + + if (bin[i].cleanToThreshold(extMemPool, &bitMask, currTime, i)) { + released = true; + } + } + // We want to find if LOC was too large for some time continuously, + // so OK with races between incrementing and zeroing, but incrementing + // must be atomic. + if (binsSummary.isLOCTooLarge()) + AtomicIncrement(tooLargeLOC); + else + tooLargeLOC = 0; + return released; +} + +template<typename Props> +bool LargeObjectCacheImpl<Props>::cleanAll(ExtMemoryPool *extMemPool) +{ + bool released = false; + for (int i = numBins-1; i >= 0; i--) { + released |= bin[i].releaseAllToBackend(extMemPool, &bitMask, i); + } + return released; +} + +template<typename Props> +void LargeObjectCacheImpl<Props>::reset() { + tooLargeLOC = 0; + for (int i = numBins-1; i >= 0; i--) + bin[i].init(); + bitMask.reset(); +} + +#if __TBB_MALLOC_WHITEBOX_TEST +template<typename Props> +size_t LargeObjectCacheImpl<Props>::getLOCSize() const +{ + size_t size = 0; + for (int i = numBins-1; i >= 0; i--) + size += bin[i].getSize(); + return size; +} + +size_t LargeObjectCache::getLOCSize() const +{ + return largeCache.getLOCSize() + hugeCache.getLOCSize(); +} + +template<typename Props> +size_t LargeObjectCacheImpl<Props>::getUsedSize() const +{ + size_t size = 0; + for (int i = numBins-1; i >= 0; i--) + size += bin[i].getUsedSize(); + return size; +} + +size_t LargeObjectCache::getUsedSize() const +{ + return largeCache.getUsedSize() + hugeCache.getUsedSize(); +} +#endif // __TBB_MALLOC_WHITEBOX_TEST + +inline bool LargeObjectCache::isCleanupNeededOnRange(uintptr_t range, uintptr_t currTime) +{ + return range >= cacheCleanupFreq + || currTime+range < currTime-1 // overflow, 0 is power of 2, do cleanup + // (prev;prev+range] contains n*cacheCleanupFreq + || alignUp(currTime, cacheCleanupFreq)<currTime+range; +} + +bool LargeObjectCache::doCleanup(uintptr_t currTime, bool doThreshDecr) +{ + if (!doThreshDecr) + extMemPool->allLocalCaches.markUnused(); + return largeCache.regularCleanup(extMemPool, currTime, doThreshDecr) + | hugeCache.regularCleanup(extMemPool, currTime, doThreshDecr); +} + +bool LargeObjectCache::decreasingCleanup() +{ + return doCleanup(FencedLoad((intptr_t&)cacheCurrTime), /*doThreshDecr=*/true); +} + +bool LargeObjectCache::regularCleanup() +{ + return doCleanup(FencedLoad((intptr_t&)cacheCurrTime), /*doThreshDecr=*/false); +} + +bool LargeObjectCache::cleanAll() +{ + return largeCache.cleanAll(extMemPool) | hugeCache.cleanAll(extMemPool); +} + +void LargeObjectCache::reset() +{ + largeCache.reset(); + hugeCache.reset(); +} + +template<typename Props> +LargeMemoryBlock *LargeObjectCacheImpl<Props>::get(ExtMemoryPool *extMemoryPool, size_t size) +{ + int idx = Props::sizeToIdx(size); + + LargeMemoryBlock *lmb = bin[idx].get(extMemoryPool, size, &bitMask, idx); + + if (lmb) { + MALLOC_ITT_SYNC_ACQUIRED(bin+idx); + STAT_increment(getThreadId(), ThreadCommonCounters, allocCachedLargeObj); + } + return lmb; +} + +template<typename Props> +void LargeObjectCacheImpl<Props>::updateCacheState(ExtMemoryPool *extMemPool, DecreaseOrIncrease op, size_t size) +{ + int idx = Props::sizeToIdx(size); + MALLOC_ASSERT(idx<numBins, ASSERT_TEXT); + bin[idx].updateUsedSize(extMemPool, op==decrease? -size : size, &bitMask, idx); +} + +#if __TBB_MALLOC_LOCACHE_STAT +template<typename Props> +void LargeObjectCacheImpl<Props>::reportStat(FILE *f) +{ + size_t cachedSize = 0; + for (int i=0; i<numBins; i++) + cachedSize += bin[i].reportStat(i, f); + fprintf(f, "total LOC size %lu MB\n", cachedSize/1024/1024); +} + +void LargeObjectCache::reportStat(FILE *f) +{ + largeCache.reportStat(f); + hugeCache.reportStat(f); + fprintf(f, "cache time %lu\n", cacheCurrTime); +} +#endif + +template<typename Props> +void LargeObjectCacheImpl<Props>::putList(ExtMemoryPool *extMemPool, LargeMemoryBlock *toCache) +{ + int toBinIdx = Props::sizeToIdx(toCache->unalignedSize); + + MALLOC_ITT_SYNC_RELEASING(bin+toBinIdx); + bin[toBinIdx].putList(extMemPool, toCache, &bitMask, toBinIdx); +} + +void LargeObjectCache::updateCacheState(DecreaseOrIncrease op, size_t size) +{ + if (size < maxLargeSize) + largeCache.updateCacheState(extMemPool, op, size); + else if (size < maxHugeSize) + hugeCache.updateCacheState(extMemPool, op, size); +} + +uintptr_t LargeObjectCache::getCurrTime() +{ + return (uintptr_t)AtomicIncrement((intptr_t&)cacheCurrTime); +} + +uintptr_t LargeObjectCache::getCurrTimeRange(uintptr_t range) +{ + return (uintptr_t)AtomicAdd((intptr_t&)cacheCurrTime, range) + 1; +} + +void LargeObjectCache::registerRealloc(size_t oldSize, size_t newSize) +{ + updateCacheState(decrease, oldSize); + updateCacheState(increase, alignToBin(newSize)); +} + +size_t LargeObjectCache::alignToBin(size_t size) { + return size < maxLargeSize ? LargeCacheType::alignToBin(size) : HugeCacheType::alignToBin(size); +} + +// Used for internal purpose +int LargeObjectCache::sizeToIdx(size_t size) +{ + MALLOC_ASSERT(size <= maxHugeSize, ASSERT_TEXT); + return size < maxLargeSize ? + LargeCacheType::sizeToIdx(size) : + LargeCacheType::numBins + HugeCacheType::sizeToIdx(size); +} + +void LargeObjectCache::putList(LargeMemoryBlock *list) +{ + LargeMemoryBlock *toProcess, *n; + + for (LargeMemoryBlock *curr = list; curr; curr = toProcess) { + LargeMemoryBlock *tail = curr; + toProcess = curr->next; + if (!sizeInCacheRange(curr->unalignedSize)) { + extMemPool->backend.returnLargeObject(curr); + continue; + } + int currIdx = sizeToIdx(curr->unalignedSize); + + // Find all blocks fitting to same bin. Not use more efficient sorting + // algorithm because list is short (commonly, + // LocalLOC's HIGH_MARK-LOW_MARK, i.e. 24 items). + for (LargeMemoryBlock *b = toProcess; b; b = n) { + n = b->next; + if (sizeToIdx(b->unalignedSize) == currIdx) { + tail->next = b; + tail = b; + if (toProcess == b) + toProcess = toProcess->next; + else { + b->prev->next = b->next; + if (b->next) + b->next->prev = b->prev; + } + } + } + tail->next = NULL; + if (curr->unalignedSize < maxLargeSize) + largeCache.putList(extMemPool, curr); + else + hugeCache.putList(extMemPool, curr); + } +} + +void LargeObjectCache::put(LargeMemoryBlock *largeBlock) +{ + size_t blockSize = largeBlock->unalignedSize; + if (sizeInCacheRange(blockSize)) { + largeBlock->next = NULL; + if (blockSize < maxLargeSize) + largeCache.putList(extMemPool, largeBlock); + else + hugeCache.putList(extMemPool, largeBlock); + } else { + extMemPool->backend.returnLargeObject(largeBlock); + } +} + +LargeMemoryBlock *LargeObjectCache::get(size_t size) +{ + MALLOC_ASSERT( size >= minLargeSize, ASSERT_TEXT ); + if (sizeInCacheRange(size)) { + return size < maxLargeSize ? + largeCache.get(extMemPool, size) : hugeCache.get(extMemPool, size); + } + return NULL; +} + +LargeMemoryBlock *ExtMemoryPool::mallocLargeObject(MemoryPool *pool, size_t allocationSize) +{ +#if __TBB_MALLOC_LOCACHE_STAT + AtomicIncrement(mallocCalls); + AtomicAdd(memAllocKB, allocationSize/1024); +#endif + LargeMemoryBlock* lmb = loc.get(allocationSize); + if (!lmb) { + BackRefIdx backRefIdx = BackRefIdx::newBackRef(/*largeObj=*/true); + if (backRefIdx.isInvalid()) + return NULL; + + // unalignedSize is set in getLargeBlock + lmb = backend.getLargeBlock(allocationSize); + if (!lmb) { + removeBackRef(backRefIdx); + loc.updateCacheState(decrease, allocationSize); + return NULL; + } + lmb->backRefIdx = backRefIdx; + lmb->pool = pool; + STAT_increment(getThreadId(), ThreadCommonCounters, allocNewLargeObj); + } else { +#if __TBB_MALLOC_LOCACHE_STAT + AtomicIncrement(cacheHits); + AtomicAdd(memHitKB, allocationSize/1024); +#endif + } + return lmb; +} + +void ExtMemoryPool::freeLargeObject(LargeMemoryBlock *mBlock) +{ + loc.put(mBlock); +} + +void ExtMemoryPool::freeLargeObjectList(LargeMemoryBlock *head) +{ + loc.putList(head); +} + +bool ExtMemoryPool::softCachesCleanup() +{ + return loc.regularCleanup(); +} + +bool ExtMemoryPool::hardCachesCleanup() +{ + // thread-local caches must be cleaned before LOC, + // because object from thread-local cache can be released to LOC + bool ret = releaseAllLocalCaches(); + ret |= orphanedBlocks.cleanup(&backend); + ret |= loc.cleanAll(); + ret |= backend.clean(); + return ret; +} + +#if BACKEND_HAS_MREMAP +void *ExtMemoryPool::remap(void *ptr, size_t oldSize, size_t newSize, size_t alignment) +{ + const size_t oldUnalignedSize = ((LargeObjectHdr*)ptr - 1)->memoryBlock->unalignedSize; + void *o = backend.remap(ptr, oldSize, newSize, alignment); + if (o) { + LargeMemoryBlock *lmb = ((LargeObjectHdr*)o - 1)->memoryBlock; + loc.registerRealloc(oldUnalignedSize, lmb->unalignedSize); + } + return o; +} +#endif /* BACKEND_HAS_MREMAP */ + +/*********** End allocation of large objects **********/ + +} // namespace internal +} // namespace rml + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/large_objects.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/large_objects.h new file mode 100644 index 00000000..de7c2058 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/large_objects.h @@ -0,0 +1,368 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbbmalloc_internal_H + #error tbbmalloc_internal.h must be included at this point +#endif + +#ifndef __TBB_large_objects_H +#define __TBB_large_objects_H + +//! The list of possible Cache Bin Aggregator operations. +/* Declared here to avoid Solaris Studio* 12.2 "multiple definitions" error */ +enum CacheBinOperationType { + CBOP_INVALID = 0, + CBOP_GET, + CBOP_PUT_LIST, + CBOP_CLEAN_TO_THRESHOLD, + CBOP_CLEAN_ALL, + CBOP_UPDATE_USED_SIZE +}; + +// The Cache Bin Aggregator operation status list. +// CBST_NOWAIT can be specified for non-blocking operations. +enum CacheBinOperationStatus { + CBST_WAIT = 0, + CBST_NOWAIT, + CBST_DONE +}; + +/* + * Bins that grow with arithmetic step + */ +template<size_t MIN_SIZE, size_t MAX_SIZE> +struct LargeBinStructureProps { +public: + static const size_t MinSize = MIN_SIZE, MaxSize = MAX_SIZE; + static const size_t CacheStep = 8 * 1024; + static const unsigned NumBins = (MaxSize - MinSize) / CacheStep; + + static size_t alignToBin(size_t size) { + return alignUp(size, CacheStep); + } + + static int sizeToIdx(size_t size) { + MALLOC_ASSERT(MinSize <= size && size < MaxSize, ASSERT_TEXT); + MALLOC_ASSERT(size % CacheStep == 0, ASSERT_TEXT); + return (size - MinSize) / CacheStep; + } +}; + +/* + * Bins that grow with special geometric progression. + */ +template<size_t MIN_SIZE, size_t MAX_SIZE> +struct HugeBinStructureProps { + +private: + // Sizes grow with the following formula: Size = MinSize * (2 ^ (Index / StepFactor)) + // There are StepFactor bins (8 be default) between each power of 2 bin + static const int MaxSizeExp = Log2<MAX_SIZE>::value; + static const int MinSizeExp = Log2<MIN_SIZE>::value; + static const int StepFactor = 8; + static const int StepFactorExp = Log2<StepFactor>::value; + +public: + static const size_t MinSize = MIN_SIZE, MaxSize = MAX_SIZE; + static const unsigned NumBins = (MaxSizeExp - MinSizeExp) * StepFactor; + + static size_t alignToBin(size_t size) { + size_t minorStepExp = BitScanRev(size) - StepFactorExp; + return alignUp(size, 1ULL << minorStepExp); + } + + // Sizes between the power of 2 values are aproximated to StepFactor. + static int sizeToIdx(size_t size) { + MALLOC_ASSERT(MinSize <= size && size <= MaxSize, ASSERT_TEXT); + int sizeExp = (int)BitScanRev(size); // same as __TBB_Log2 + size_t majorStepSize = 1ULL << sizeExp; + int minorStepExp = sizeExp - StepFactorExp; + int minorIdx = (size - majorStepSize) >> minorStepExp; + MALLOC_ASSERT(size == majorStepSize + ((size_t)minorIdx << minorStepExp), + "Size is not aligned on the bin"); + return StepFactor * (sizeExp - MinSizeExp) + minorIdx; + } +}; + +/* + * Cache properties accessor + * + * TooLargeFactor -- when cache size treated "too large" in comparison to user data size + * OnMissFactor -- If cache miss occurred and cache was cleaned, + * set ageThreshold to OnMissFactor * the difference + * between current time and last time cache was cleaned. + * LongWaitFactor -- to detect rarely-used bins and forget about their usage history + */ +template<typename StructureProps, int TOO_LARGE, int ON_MISS, int LONG_WAIT> +struct LargeObjectCacheProps : public StructureProps { + static const int TooLargeFactor = TOO_LARGE, OnMissFactor = ON_MISS, LongWaitFactor = LONG_WAIT; +}; + +template<typename Props> +class LargeObjectCacheImpl { +private: + + // Current sizes of used and cached objects. It's calculated while we are + // traversing bins, and used for isLOCTooLarge() check at the same time. + class BinsSummary { + size_t usedSz; + size_t cachedSz; + public: + BinsSummary() : usedSz(0), cachedSz(0) {} + // "too large" criteria + bool isLOCTooLarge() const { return cachedSz > Props::TooLargeFactor * usedSz; } + void update(size_t usedSize, size_t cachedSize) { + usedSz += usedSize; + cachedSz += cachedSize; + } + void reset() { usedSz = cachedSz = 0; } + }; + +public: + // The number of bins to cache large/huge objects. + static const uint32_t numBins = Props::NumBins; + + typedef BitMaskMax<numBins> BinBitMask; + + // 2-linked list of same-size cached blocks ordered by age (oldest on top) + // TODO: are we really want the list to be 2-linked? This allows us + // reduce memory consumption and do less operations under lock. + // TODO: try to switch to 32-bit logical time to save space in CacheBin + // and move bins to different cache lines. + class CacheBin { + private: + LargeMemoryBlock *first, + *last; + /* age of an oldest block in the list; equal to last->age, if last defined, + used for quick checking it without acquiring the lock. */ + uintptr_t oldest; + /* currAge when something was excluded out of list because of the age, + not because of cache hit */ + uintptr_t lastCleanedAge; + /* Current threshold value for the blocks of a particular size. + Set on cache miss. */ + intptr_t ageThreshold; + + /* total size of all objects corresponding to the bin and allocated by user */ + size_t usedSize, + /* total size of all objects cached in the bin */ + cachedSize; + /* mean time of presence of block in the bin before successful reuse */ + intptr_t meanHitRange; + /* time of last get called for the bin */ + uintptr_t lastGet; + + typename MallocAggregator<CacheBinOperation>::type aggregator; + + void ExecuteOperation(CacheBinOperation *op, ExtMemoryPool *extMemPool, BinBitMask *bitMask, int idx, bool longLifeTime = true); + + /* should be placed in zero-initialized memory, ctor not needed. */ + CacheBin(); + + public: + void init() { + memset(this, 0, sizeof(CacheBin)); + } + + /* ---------- Cache accessors ---------- */ + void putList(ExtMemoryPool *extMemPool, LargeMemoryBlock *head, BinBitMask *bitMask, int idx); + LargeMemoryBlock *get(ExtMemoryPool *extMemPool, size_t size, BinBitMask *bitMask, int idx); + + /* ---------- Cleanup functions -------- */ + bool cleanToThreshold(ExtMemoryPool *extMemPool, BinBitMask *bitMask, uintptr_t currTime, int idx); + bool releaseAllToBackend(ExtMemoryPool *extMemPool, BinBitMask *bitMask, int idx); + /* ------------------------------------- */ + + void updateUsedSize(ExtMemoryPool *extMemPool, size_t size, BinBitMask *bitMask, int idx); + void decreaseThreshold() { + if (ageThreshold) + ageThreshold = (ageThreshold + meanHitRange) / 2; + } + void updateBinsSummary(BinsSummary *binsSummary) const { + binsSummary->update(usedSize, cachedSize); + } + size_t getSize() const { return cachedSize; } + size_t getUsedSize() const { return usedSize; } + size_t reportStat(int num, FILE *f); + + /* --------- Unsafe methods used with the aggregator ------- */ + void forgetOutdatedState(uintptr_t currTime); + LargeMemoryBlock *putList(LargeMemoryBlock *head, LargeMemoryBlock *tail, BinBitMask *bitMask, + int idx, int num, size_t hugeObjectThreshold); + LargeMemoryBlock *get(); + LargeMemoryBlock *cleanToThreshold(uintptr_t currTime, BinBitMask *bitMask, int idx); + LargeMemoryBlock *cleanAll(BinBitMask *bitMask, int idx); + void updateUsedSize(size_t size, BinBitMask *bitMask, int idx) { + if (!usedSize) bitMask->set(idx, true); + usedSize += size; + if (!usedSize && !first) bitMask->set(idx, false); + } + void updateMeanHitRange( intptr_t hitRange ) { + hitRange = hitRange >= 0 ? hitRange : 0; + meanHitRange = meanHitRange ? (meanHitRange + hitRange) / 2 : hitRange; + } + void updateAgeThreshold( uintptr_t currTime ) { + if (lastCleanedAge) + ageThreshold = Props::OnMissFactor*(currTime - lastCleanedAge); + } + void updateCachedSize(size_t size) { + cachedSize += size; + } + void setLastGet( uintptr_t newLastGet ) { + lastGet = newLastGet; + } + /* -------------------------------------------------------- */ + }; + + // Huge bins index for fast regular cleanup searching in case of + // the "huge size threshold" setting defined + intptr_t hugeSizeThresholdIdx; + +private: + // How many times LOC was "too large" + intptr_t tooLargeLOC; + // for fast finding of used bins and bins with non-zero usedSize; + // indexed from the end, as we need largest 1st + BinBitMask bitMask; + // bins with lists of recently freed large blocks cached for re-use + CacheBin bin[numBins]; + +public: + /* ------------ CacheBin structure dependent stuff ------------ */ + static size_t alignToBin(size_t size) { + return Props::alignToBin(size); + } + static int sizeToIdx(size_t size) { + return Props::sizeToIdx(size); + } + + /* --------- Main cache functions (put, get object) ------------ */ + void putList(ExtMemoryPool *extMemPool, LargeMemoryBlock *largeBlock); + LargeMemoryBlock *get(ExtMemoryPool *extMemPool, size_t size); + + /* ------------------------ Cleanup ---------------------------- */ + bool regularCleanup(ExtMemoryPool *extMemPool, uintptr_t currAge, bool doThreshDecr); + bool cleanAll(ExtMemoryPool *extMemPool); + + /* -------------------------- Other ---------------------------- */ + void updateCacheState(ExtMemoryPool *extMemPool, DecreaseOrIncrease op, size_t size); + + void reset(); + void reportStat(FILE *f); +#if __TBB_MALLOC_WHITEBOX_TEST + size_t getLOCSize() const; + size_t getUsedSize() const; +#endif +}; + +class LargeObjectCache { +private: + // Large bins [minLargeSize, maxLargeSize) + // Huge bins [maxLargeSize, maxHugeSize) + static const size_t minLargeSize = 8 * 1024, + maxLargeSize = 8 * 1024 * 1024, + // Cache memory up to 1TB (or 2GB for 32-bit arch), but sieve objects from the special threshold + maxHugeSize = tbb::internal::select_size_t_constant<2147483648U, 1099511627776ULL>::value; + +public: + // Upper bound threshold for caching size. After that size all objects sieve through cache + // By default - 64MB, previous value was 129MB (needed by some Intel(R) Math Kernel Library (Intel(R) MKL) benchmarks) + static const size_t defaultMaxHugeSize = 64UL * 1024UL * 1024UL; + // After that size large object interpreted as huge and does not participate in regular cleanup. + // Can be changed during the program execution. + size_t hugeSizeThreshold; + +private: + // Large objects cache properties + typedef LargeBinStructureProps<minLargeSize, maxLargeSize> LargeBSProps; + typedef LargeObjectCacheProps<LargeBSProps, 2, 2, 16> LargeCacheTypeProps; + + // Huge objects cache properties + typedef HugeBinStructureProps<maxLargeSize, maxHugeSize> HugeBSProps; + typedef LargeObjectCacheProps<HugeBSProps, 1, 1, 4> HugeCacheTypeProps; + + // Cache implementation type with properties + typedef LargeObjectCacheImpl< LargeCacheTypeProps > LargeCacheType; + typedef LargeObjectCacheImpl< HugeCacheTypeProps > HugeCacheType; + + // Beginning of largeCache is more actively used and smaller than hugeCache, + // so put hugeCache first to prevent false sharing + // with LargeObjectCache's predecessor + HugeCacheType hugeCache; + LargeCacheType largeCache; + + /* logical time, incremented on each put/get operation + To prevent starvation between pools, keep separately for each pool. + Overflow is OK, as we only want difference between + its current value and some recent. + + Both malloc and free should increment logical time, as in + a different case multiple cached blocks would have same age, + and accuracy of predictors suffers. + */ + uintptr_t cacheCurrTime; + + // Memory pool that owns this LargeObjectCache. + // strict 1:1 relation, never changed + ExtMemoryPool *extMemPool; + + // Returns artificial bin index, + // it's used only during sorting and never saved + static int sizeToIdx(size_t size); + + // Our friends + friend class Backend; + +public: + void init(ExtMemoryPool *memPool); + + // Item accessors + void put(LargeMemoryBlock *largeBlock); + void putList(LargeMemoryBlock *head); + LargeMemoryBlock *get(size_t size); + + void updateCacheState(DecreaseOrIncrease op, size_t size); + bool isCleanupNeededOnRange(uintptr_t range, uintptr_t currTime); + + // Cleanup operations + bool doCleanup(uintptr_t currTime, bool doThreshDecr); + bool decreasingCleanup(); + bool regularCleanup(); + bool cleanAll(); + void reset(); + + void reportStat(FILE *f); +#if __TBB_MALLOC_WHITEBOX_TEST + size_t getLOCSize() const; + size_t getUsedSize() const; +#endif + + // Cache deals with exact-fit sizes, so need to align each size + // to the specific bin when put object to cache + static size_t alignToBin(size_t size); + + void setHugeSizeThreshold(size_t value); + + // Check if we should cache or sieve this size + bool sizeInCacheRange(size_t size); + + uintptr_t getCurrTime(); + uintptr_t getCurrTimeRange(uintptr_t range); + void registerRealloc(size_t oldSize, size_t newSize); +}; + +#endif // __TBB_large_objects_H + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin32-proxy-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin32-proxy-export.def new file mode 100644 index 00000000..329664a5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin32-proxy-export.def @@ -0,0 +1,55 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: +calloc; +free; +malloc; +realloc; +posix_memalign; +memalign; +aligned_alloc; +valloc; +pvalloc; +mallinfo; +mallopt; +malloc_usable_size; +__libc_malloc; +__libc_realloc; +__libc_calloc; +__libc_free; +__libc_memalign; +__libc_pvalloc; +__libc_valloc; +__TBB_malloc_proxy; +_ZdaPv; /* next ones are new/delete */ +_ZdaPvRKSt9nothrow_t; +_ZdlPv; +_ZdlPvRKSt9nothrow_t; +_Znaj; +_ZnajRKSt9nothrow_t; +_Znwj; +_ZnwjRKSt9nothrow_t; + +local: + +/* TBB symbols */ +*3rml8internal*; +*3tbb*; +*__TBB*; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin32-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin32-tbbmalloc-export.def new file mode 100644 index 00000000..3e078d14 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin32-tbbmalloc-export.def @@ -0,0 +1,73 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: + +scalable_calloc; +scalable_free; +scalable_malloc; +scalable_realloc; +scalable_posix_memalign; +scalable_aligned_malloc; +scalable_aligned_realloc; +scalable_aligned_free; +scalable_msize; +scalable_allocation_mode; +scalable_allocation_command; +__TBB_malloc_safer_aligned_msize; +__TBB_malloc_safer_aligned_realloc; +__TBB_malloc_safer_free; +__TBB_malloc_safer_msize; +__TBB_malloc_safer_realloc; + +/* memory pool stuff */ +_ZN3rml10pool_resetEPNS_10MemoryPoolE; +_ZN3rml11pool_createEiPKNS_13MemPoolPolicyE; +_ZN3rml14pool_create_v1EiPKNS_13MemPoolPolicyEPPNS_10MemoryPoolE; +_ZN3rml11pool_mallocEPNS_10MemoryPoolEj; +_ZN3rml12pool_destroyEPNS_10MemoryPoolE; +_ZN3rml9pool_freeEPNS_10MemoryPoolEPv; +_ZN3rml12pool_reallocEPNS_10MemoryPoolEPvj; +_ZN3rml20pool_aligned_reallocEPNS_10MemoryPoolEPvjj; +_ZN3rml19pool_aligned_mallocEPNS_10MemoryPoolEjj; +_ZN3rml13pool_identifyEPv; +_ZN3rml10pool_msizeEPNS_10MemoryPoolEPv; + +local: + +/* TBB symbols */ +*3rml*; +*3tbb*; +*__TBB*; +__itt_*; +ITT_DoOneTimeInitialization; +TBB_runtime_interface_version; + +/* Intel Compiler (libirc) symbols */ +__intel_*; +_intel_*; +get_memcpy_largest_cachelinesize; +get_memcpy_largest_cache_size; +get_mem_ops_method; +init_mem_ops_method; +irc__get_msg; +irc__print; +override_mem_ops_method; +set_memcpy_largest_cachelinesize; +set_memcpy_largest_cache_size; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64-proxy-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64-proxy-export.def new file mode 100644 index 00000000..913aa78d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64-proxy-export.def @@ -0,0 +1,55 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: +calloc; +free; +malloc; +realloc; +posix_memalign; +memalign; +aligned_alloc; +valloc; +pvalloc; +mallinfo; +mallopt; +malloc_usable_size; +__libc_malloc; +__libc_realloc; +__libc_calloc; +__libc_free; +__libc_memalign; +__libc_pvalloc; +__libc_valloc; +__TBB_malloc_proxy; +_ZdaPv; /* next ones are new/delete */ +_ZdaPvRKSt9nothrow_t; +_ZdlPv; +_ZdlPvRKSt9nothrow_t; +_Znam; +_ZnamRKSt9nothrow_t; +_Znwm; +_ZnwmRKSt9nothrow_t; + +local: + +/* TBB symbols */ +*3rml8internal*; +*3tbb*; +*__TBB*; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64-tbbmalloc-export.def new file mode 100644 index 00000000..663a35c0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64-tbbmalloc-export.def @@ -0,0 +1,73 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: + +scalable_calloc; +scalable_free; +scalable_malloc; +scalable_realloc; +scalable_posix_memalign; +scalable_aligned_malloc; +scalable_aligned_realloc; +scalable_aligned_free; +scalable_msize; +scalable_allocation_mode; +scalable_allocation_command; +__TBB_malloc_safer_aligned_msize; +__TBB_malloc_safer_aligned_realloc; +__TBB_malloc_safer_free; +__TBB_malloc_safer_msize; +__TBB_malloc_safer_realloc; + +/* memory pool stuff */ +_ZN3rml11pool_createElPKNS_13MemPoolPolicyE; +_ZN3rml14pool_create_v1ElPKNS_13MemPoolPolicyEPPNS_10MemoryPoolE; +_ZN3rml10pool_resetEPNS_10MemoryPoolE; +_ZN3rml11pool_mallocEPNS_10MemoryPoolEm; +_ZN3rml12pool_destroyEPNS_10MemoryPoolE; +_ZN3rml9pool_freeEPNS_10MemoryPoolEPv; +_ZN3rml12pool_reallocEPNS_10MemoryPoolEPvm; +_ZN3rml20pool_aligned_reallocEPNS_10MemoryPoolEPvmm; +_ZN3rml19pool_aligned_mallocEPNS_10MemoryPoolEmm; +_ZN3rml13pool_identifyEPv; +_ZN3rml10pool_msizeEPNS_10MemoryPoolEPv; + +local: + +/* TBB symbols */ +*3rml*; +*3tbb*; +*__TBB*; +__itt_*; +ITT_DoOneTimeInitialization; +TBB_runtime_interface_version; + +/* Intel Compiler (libirc) symbols */ +__intel_*; +_intel_*; +get_memcpy_largest_cachelinesize; +get_memcpy_largest_cache_size; +get_mem_ops_method; +init_mem_ops_method; +irc__get_msg; +irc__print; +override_mem_ops_method; +set_memcpy_largest_cachelinesize; +set_memcpy_largest_cache_size; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64ipf-proxy-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64ipf-proxy-export.def new file mode 100644 index 00000000..913aa78d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64ipf-proxy-export.def @@ -0,0 +1,55 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: +calloc; +free; +malloc; +realloc; +posix_memalign; +memalign; +aligned_alloc; +valloc; +pvalloc; +mallinfo; +mallopt; +malloc_usable_size; +__libc_malloc; +__libc_realloc; +__libc_calloc; +__libc_free; +__libc_memalign; +__libc_pvalloc; +__libc_valloc; +__TBB_malloc_proxy; +_ZdaPv; /* next ones are new/delete */ +_ZdaPvRKSt9nothrow_t; +_ZdlPv; +_ZdlPvRKSt9nothrow_t; +_Znam; +_ZnamRKSt9nothrow_t; +_Znwm; +_ZnwmRKSt9nothrow_t; + +local: + +/* TBB symbols */ +*3rml8internal*; +*3tbb*; +*__TBB*; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64ipf-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64ipf-tbbmalloc-export.def new file mode 100644 index 00000000..e8a56171 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/lin64ipf-tbbmalloc-export.def @@ -0,0 +1,76 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: + +scalable_calloc; +scalable_free; +scalable_malloc; +scalable_realloc; +scalable_posix_memalign; +scalable_aligned_malloc; +scalable_aligned_realloc; +scalable_aligned_free; +scalable_msize; +scalable_allocation_mode; +scalable_allocation_command; +__TBB_malloc_safer_aligned_msize; +__TBB_malloc_safer_aligned_realloc; +__TBB_malloc_safer_free; +__TBB_malloc_safer_msize; +__TBB_malloc_safer_realloc; +/* For tbbmalloc proxy to use MallocMutex with new_handler feature */ +__TBB_machine_lockbyte; +__TBB_machine_trylockbyte; + +/* memory pool stuff */ +_ZN3rml11pool_createElPKNS_13MemPoolPolicyE; +_ZN3rml14pool_create_v1ElPKNS_13MemPoolPolicyEPPNS_10MemoryPoolE; +_ZN3rml10pool_resetEPNS_10MemoryPoolE; +_ZN3rml11pool_mallocEPNS_10MemoryPoolEm; +_ZN3rml12pool_destroyEPNS_10MemoryPoolE; +_ZN3rml9pool_freeEPNS_10MemoryPoolEPv; +_ZN3rml12pool_reallocEPNS_10MemoryPoolEPvm; +_ZN3rml20pool_aligned_reallocEPNS_10MemoryPoolEPvmm; +_ZN3rml19pool_aligned_mallocEPNS_10MemoryPoolEmm; +_ZN3rml13pool_identifyEPv; +_ZN3rml10pool_msizeEPNS_10MemoryPoolEPv; + +local: + +/* TBB symbols */ +*3rml*; +*3tbb*; +*__TBB*; +__itt_*; +ITT_DoOneTimeInitialization; +TBB_runtime_interface_version; + +/* Intel Compiler (libirc) symbols */ +__intel_*; +_intel_*; +get_memcpy_largest_cachelinesize; +get_memcpy_largest_cache_size; +get_mem_ops_method; +init_mem_ops_method; +irc__get_msg; +irc__print; +override_mem_ops_method; +set_memcpy_largest_cachelinesize; +set_memcpy_largest_cache_size; + +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/mac32-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/mac32-tbbmalloc-export.def new file mode 100644 index 00000000..82759dff --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/mac32-tbbmalloc-export.def @@ -0,0 +1,46 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +_scalable_calloc +_scalable_free +_scalable_malloc +_scalable_realloc +_scalable_posix_memalign +_scalable_aligned_malloc +_scalable_aligned_realloc +_scalable_aligned_free +_scalable_msize +_scalable_allocation_mode +_scalable_allocation_command +___TBB_malloc_safer_aligned_msize +___TBB_malloc_safer_aligned_realloc +___TBB_malloc_safer_free +___TBB_malloc_safer_msize +___TBB_malloc_safer_realloc +___TBB_malloc_free_definite_size +/* memory pool stuff */ +__ZN3rml11pool_createElPKNS_13MemPoolPolicyE +__ZN3rml14pool_create_v1ElPKNS_13MemPoolPolicyEPPNS_10MemoryPoolE +__ZN3rml10pool_resetEPNS_10MemoryPoolE +__ZN3rml12pool_destroyEPNS_10MemoryPoolE +__ZN3rml11pool_mallocEPNS_10MemoryPoolEm +__ZN3rml9pool_freeEPNS_10MemoryPoolEPv +__ZN3rml12pool_reallocEPNS_10MemoryPoolEPvm +__ZN3rml20pool_aligned_reallocEPNS_10MemoryPoolEPvmm +__ZN3rml19pool_aligned_mallocEPNS_10MemoryPoolEmm +__ZN3rml13pool_identifyEPv +__ZN3rml10pool_msizeEPNS_10MemoryPoolEPv + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/mac64-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/mac64-tbbmalloc-export.def new file mode 100644 index 00000000..82759dff --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/mac64-tbbmalloc-export.def @@ -0,0 +1,46 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +_scalable_calloc +_scalable_free +_scalable_malloc +_scalable_realloc +_scalable_posix_memalign +_scalable_aligned_malloc +_scalable_aligned_realloc +_scalable_aligned_free +_scalable_msize +_scalable_allocation_mode +_scalable_allocation_command +___TBB_malloc_safer_aligned_msize +___TBB_malloc_safer_aligned_realloc +___TBB_malloc_safer_free +___TBB_malloc_safer_msize +___TBB_malloc_safer_realloc +___TBB_malloc_free_definite_size +/* memory pool stuff */ +__ZN3rml11pool_createElPKNS_13MemPoolPolicyE +__ZN3rml14pool_create_v1ElPKNS_13MemPoolPolicyEPPNS_10MemoryPoolE +__ZN3rml10pool_resetEPNS_10MemoryPoolE +__ZN3rml12pool_destroyEPNS_10MemoryPoolE +__ZN3rml11pool_mallocEPNS_10MemoryPoolEm +__ZN3rml9pool_freeEPNS_10MemoryPoolEPv +__ZN3rml12pool_reallocEPNS_10MemoryPoolEPvm +__ZN3rml20pool_aligned_reallocEPNS_10MemoryPoolEPvmm +__ZN3rml19pool_aligned_mallocEPNS_10MemoryPoolEmm +__ZN3rml13pool_identifyEPv +__ZN3rml10pool_msizeEPNS_10MemoryPoolEPv + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy.cpp new file mode 100644 index 00000000..2de52333 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy.cpp @@ -0,0 +1,809 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __linux__ && !__ANDROID__ +// include <bits/c++config.h> indirectly so that <cstdlib> is not included +#include <cstddef> +// include <features.h> indirectly so that <stdlib.h> is not included +#include <unistd.h> +// Working around compiler issue with Anaconda's gcc 7.3 compiler package. +// New gcc ported for old libc may provide their inline implementation +// of aligned_alloc as required by new C++ standard, this makes it hard to +// redefine aligned_alloc here. However, running on systems with new libc +// version, it still needs it to be redefined, thus tricking system headers +#if defined(__GLIBC_PREREQ) && !__GLIBC_PREREQ(2, 16) && _GLIBCXX_HAVE_ALIGNED_ALLOC +// tell <cstdlib> that there is no aligned_alloc +#undef _GLIBCXX_HAVE_ALIGNED_ALLOC +// trick <stdlib.h> to define another symbol instead +#define aligned_alloc __hidden_redefined_aligned_alloc +// Fix the state and undefine the trick +#include <cstdlib> +#undef aligned_alloc +#endif // defined(__GLIBC_PREREQ)&&!__GLIBC_PREREQ(2, 16)&&_GLIBCXX_HAVE_ALIGNED_ALLOC +#endif // __linux__ && !__ANDROID__ + +#include "proxy.h" +#include "tbb/tbb_config.h" +#include "tbb/tbb_environment.h" + +#if !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) && !defined(__SUNPRO_CC) + #if TBB_USE_EXCEPTIONS + #error Compilation settings do not support exception handling. Please do not set TBB_USE_EXCEPTIONS macro or set it to 0. + #elif !defined(TBB_USE_EXCEPTIONS) + #define TBB_USE_EXCEPTIONS 0 + #endif +#elif !defined(TBB_USE_EXCEPTIONS) + #define TBB_USE_EXCEPTIONS 1 +#endif + +#if __TBB_CPP11_PRESENT +#define __TBB_THROW_BAD_ALLOC +#define __TBB_NO_THROW noexcept +#else +#define __TBB_THROW_BAD_ALLOC throw(std::bad_alloc) +#define __TBB_NO_THROW throw() +#endif + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED || _WIN32 && !__TBB_WIN8UI_SUPPORT +/*** internal global operator new implementation (Linux, Windows) ***/ +#include <new> + +// Synchronization primitives to protect original library pointers and new_handler +#include "Synchronize.h" + +#if __TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT +// Use MallocMutex implementation +typedef MallocMutex ProxyMutex; +#else +// One byte atomic intrinsics are not available, +// so use simple pointer based spin mutex +class SimpleSpinMutex : tbb::internal::no_copy { + intptr_t flag; +public: + class scoped_lock : tbb::internal::no_copy { + SimpleSpinMutex& mutex; + public: + scoped_lock( SimpleSpinMutex& m ) : mutex(m) { + while( !(AtomicFetchStore( &(m.flag), 1 ) == 0) ); + } + ~scoped_lock() { + FencedStore(mutex.flag, 0); + } + }; + friend class scoped_lock; +}; +typedef SimpleSpinMutex ProxyMutex; +#endif /* __TBB_MSVC_PART_WORD_INTERLOCKED_INTRINSICS_PRESENT */ + +// In case there is no std::get_new_handler function +// which provides synchronized access to std::new_handler +#if !__TBB_CPP11_GET_NEW_HANDLER_PRESENT +static ProxyMutex new_lock; +#endif + +static inline void* InternalOperatorNew(size_t sz) { + void* res = scalable_malloc(sz); +#if TBB_USE_EXCEPTIONS + while (!res) { + std::new_handler handler; +#if __TBB_CPP11_GET_NEW_HANDLER_PRESENT + handler = std::get_new_handler(); +#else + { + ProxyMutex::scoped_lock lock(new_lock); + handler = std::set_new_handler(0); + std::set_new_handler(handler); + } +#endif + if (handler) { + (*handler)(); + } else { + throw std::bad_alloc(); + } + res = scalable_malloc(sz); +} +#endif /* TBB_USE_EXCEPTIONS */ + return res; +} +/*** end of internal global operator new implementation ***/ +#endif // MALLOC_UNIXLIKE_OVERLOAD_ENABLED || _WIN32 && !__TBB_WIN8UI_SUPPORT + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED + +#ifndef __THROW +#define __THROW +#endif + +/*** service functions and variables ***/ +#include <string.h> // for memset +#include <unistd.h> // for sysconf + +static long memoryPageSize; + +static inline void initPageSize() +{ + memoryPageSize = sysconf(_SC_PAGESIZE); +} + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED +#include <dlfcn.h> +#include <malloc.h> // mallinfo + +/* __TBB_malloc_proxy used as a weak symbol by libtbbmalloc for: + 1) detection that the proxy library is loaded + 2) check that dlsym("malloc") found something different from our replacement malloc +*/ +// Starting from GCC 9, the -Wmissing-attributes warning was extended for alias below +#if __GNUC__ == 9 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wmissing-attributes" +#endif +extern "C" void *__TBB_malloc_proxy(size_t) __attribute__ ((alias ("malloc"))); +#if __GNUC__ == 9 + #pragma GCC diagnostic pop +#endif + +static void *orig_msize; + +#elif MALLOC_ZONE_OVERLOAD_ENABLED + +#include "proxy_overload_osx.h" + +#endif // MALLOC_ZONE_OVERLOAD_ENABLED + +// Original (i.e., replaced) functions, +// they are never changed for MALLOC_ZONE_OVERLOAD_ENABLED. +static void *orig_free, + *orig_realloc; + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED +#define ZONE_ARG +#define PREFIX(name) name + +static void *orig_libc_free, + *orig_libc_realloc; + +// We already tried to find ptr to original functions. +static intptr_t origFuncSearched; + +inline void InitOrigPointers() +{ + // race is OK here, as different threads found same functions + if (!FencedLoad(origFuncSearched)) { + orig_free = dlsym(RTLD_NEXT, "free"); + orig_realloc = dlsym(RTLD_NEXT, "realloc"); + orig_msize = dlsym(RTLD_NEXT, "malloc_usable_size"); + orig_libc_free = dlsym(RTLD_NEXT, "__libc_free"); + orig_libc_realloc = dlsym(RTLD_NEXT, "__libc_realloc"); + + FencedStore(origFuncSearched, 1); + } +} + +/*** replacements for malloc and the family ***/ +extern "C" { +#elif MALLOC_ZONE_OVERLOAD_ENABLED + +// each impl_* function has such 1st argument, it's unused +#define ZONE_ARG struct _malloc_zone_t *, +#define PREFIX(name) impl_##name +// not interested in original functions for zone overload +inline void InitOrigPointers() {} + +#endif // MALLOC_UNIXLIKE_OVERLOAD_ENABLED and MALLOC_ZONE_OVERLOAD_ENABLED + +void *PREFIX(malloc)(ZONE_ARG size_t size) __THROW +{ + return scalable_malloc(size); +} + +void *PREFIX(calloc)(ZONE_ARG size_t num, size_t size) __THROW +{ + return scalable_calloc(num, size); +} + +void PREFIX(free)(ZONE_ARG void *object) __THROW +{ + InitOrigPointers(); + __TBB_malloc_safer_free(object, (void (*)(void*))orig_free); +} + +void *PREFIX(realloc)(ZONE_ARG void* ptr, size_t sz) __THROW +{ + InitOrigPointers(); + return __TBB_malloc_safer_realloc(ptr, sz, orig_realloc); +} + +/* The older *NIX interface for aligned allocations; + it's formally substituted by posix_memalign and deprecated, + so we do not expect it to cause cyclic dependency with C RTL. */ +void *PREFIX(memalign)(ZONE_ARG size_t alignment, size_t size) __THROW +{ + return scalable_aligned_malloc(size, alignment); +} + +/* valloc allocates memory aligned on a page boundary */ +void *PREFIX(valloc)(ZONE_ARG size_t size) __THROW +{ + if (! memoryPageSize) initPageSize(); + + return scalable_aligned_malloc(size, memoryPageSize); +} + +#undef ZONE_ARG +#undef PREFIX + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED + +// match prototype from system headers +#if __ANDROID__ +size_t malloc_usable_size(const void *ptr) __THROW +#else +size_t malloc_usable_size(void *ptr) __THROW +#endif +{ + InitOrigPointers(); + return __TBB_malloc_safer_msize(const_cast<void*>(ptr), (size_t (*)(void*))orig_msize); +} + +int posix_memalign(void **memptr, size_t alignment, size_t size) __THROW +{ + return scalable_posix_memalign(memptr, alignment, size); +} + +/* pvalloc allocates smallest set of complete pages which can hold + the requested number of bytes. Result is aligned on page boundary. */ +void *pvalloc(size_t size) __THROW +{ + if (! memoryPageSize) initPageSize(); + // align size up to the page size, + // pvalloc(0) returns 1 page, see man libmpatrol + size = size? ((size-1) | (memoryPageSize-1)) + 1 : memoryPageSize; + + return scalable_aligned_malloc(size, memoryPageSize); +} + +int mallopt(int /*param*/, int /*value*/) __THROW +{ + return 1; +} + +struct mallinfo mallinfo() __THROW +{ + struct mallinfo m; + memset(&m, 0, sizeof(struct mallinfo)); + + return m; +} + +#if __ANDROID__ +// Android doesn't have malloc_usable_size, provide it to be compatible +// with Linux, in addition overload dlmalloc_usable_size() that presented +// under Android. +size_t dlmalloc_usable_size(const void *ptr) __attribute__ ((alias ("malloc_usable_size"))); +#else // __ANDROID__ +// C11 function, supported starting GLIBC 2.16 +void *aligned_alloc(size_t alignment, size_t size) __attribute__ ((alias ("memalign"))); +// Those non-standard functions are exported by GLIBC, and might be used +// in conjunction with standard malloc/free, so we must ovberload them. +// Bionic doesn't have them. Not removing from the linker scripts, +// as absent entry points are ignored by the linker. + +// Starting from GCC 9, the -Wmissing-attributes warning was extended for aliases below +#if __GNUC__ == 9 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wmissing-attributes" +#endif +void *__libc_malloc(size_t size) __attribute__ ((alias ("malloc"))); +void *__libc_calloc(size_t num, size_t size) __attribute__ ((alias ("calloc"))); +void *__libc_memalign(size_t alignment, size_t size) __attribute__ ((alias ("memalign"))); +void *__libc_pvalloc(size_t size) __attribute__ ((alias ("pvalloc"))); +void *__libc_valloc(size_t size) __attribute__ ((alias ("valloc"))); +#if __GNUC__ == 9 + #pragma GCC diagnostic pop +#endif + +// call original __libc_* to support naive replacement of free via __libc_free etc +void __libc_free(void *ptr) +{ + InitOrigPointers(); + __TBB_malloc_safer_free(ptr, (void (*)(void*))orig_libc_free); +} + +void *__libc_realloc(void *ptr, size_t size) +{ + InitOrigPointers(); + return __TBB_malloc_safer_realloc(ptr, size, orig_libc_realloc); +} +#endif // !__ANDROID__ + +} /* extern "C" */ + +/*** replacements for global operators new and delete ***/ + +void* operator new(size_t sz) __TBB_THROW_BAD_ALLOC { + return InternalOperatorNew(sz); +} +void* operator new[](size_t sz) __TBB_THROW_BAD_ALLOC { + return InternalOperatorNew(sz); +} +void operator delete(void* ptr) __TBB_NO_THROW { + InitOrigPointers(); + __TBB_malloc_safer_free(ptr, (void (*)(void*))orig_free); +} +void operator delete[](void* ptr) __TBB_NO_THROW { + InitOrigPointers(); + __TBB_malloc_safer_free(ptr, (void (*)(void*))orig_free); +} +void* operator new(size_t sz, const std::nothrow_t&) __TBB_NO_THROW { + return scalable_malloc(sz); +} +void* operator new[](std::size_t sz, const std::nothrow_t&) __TBB_NO_THROW { + return scalable_malloc(sz); +} +void operator delete(void* ptr, const std::nothrow_t&) __TBB_NO_THROW { + InitOrigPointers(); + __TBB_malloc_safer_free(ptr, (void (*)(void*))orig_free); +} +void operator delete[](void* ptr, const std::nothrow_t&) __TBB_NO_THROW { + InitOrigPointers(); + __TBB_malloc_safer_free(ptr, (void (*)(void*))orig_free); +} + +#endif /* MALLOC_UNIXLIKE_OVERLOAD_ENABLED */ +#endif /* MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED */ + +#ifdef _WIN32 +#include <windows.h> + +#if !__TBB_WIN8UI_SUPPORT + +#include <stdio.h> +#include "tbb_function_replacement.h" +#include "shared_utils.h" + +void __TBB_malloc_safer_delete( void *ptr) +{ + __TBB_malloc_safer_free( ptr, NULL ); +} + +void* safer_aligned_malloc( size_t size, size_t alignment ) +{ + // workaround for "is power of 2 pow N" bug that accepts zeros + return scalable_aligned_malloc( size, alignment>sizeof(size_t*)?alignment:sizeof(size_t*) ); +} + +// we do not support _expand(); +void* safer_expand( void *, size_t ) +{ + return NULL; +} + +#define __TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(CRTLIB) \ +void (*orig_free_##CRTLIB)(void*); \ +void __TBB_malloc_safer_free_##CRTLIB(void *ptr) \ +{ \ + __TBB_malloc_safer_free( ptr, orig_free_##CRTLIB ); \ +} \ + \ +void (*orig__aligned_free_##CRTLIB)(void*); \ +void __TBB_malloc_safer__aligned_free_##CRTLIB(void *ptr) \ +{ \ + __TBB_malloc_safer_free( ptr, orig__aligned_free_##CRTLIB ); \ +} \ + \ +size_t (*orig__msize_##CRTLIB)(void*); \ +size_t __TBB_malloc_safer__msize_##CRTLIB(void *ptr) \ +{ \ + return __TBB_malloc_safer_msize( ptr, orig__msize_##CRTLIB ); \ +} \ + \ +size_t (*orig__aligned_msize_##CRTLIB)(void*, size_t, size_t); \ +size_t __TBB_malloc_safer__aligned_msize_##CRTLIB( void *ptr, size_t alignment, size_t offset) \ +{ \ + return __TBB_malloc_safer_aligned_msize( ptr, alignment, offset, orig__aligned_msize_##CRTLIB ); \ +} \ + \ +void* __TBB_malloc_safer_realloc_##CRTLIB( void *ptr, size_t size ) \ +{ \ + orig_ptrs func_ptrs = {orig_free_##CRTLIB, orig__msize_##CRTLIB}; \ + return __TBB_malloc_safer_realloc( ptr, size, &func_ptrs ); \ +} \ + \ +void* __TBB_malloc_safer__aligned_realloc_##CRTLIB( void *ptr, size_t size, size_t alignment ) \ +{ \ + orig_aligned_ptrs func_ptrs = {orig__aligned_free_##CRTLIB, orig__aligned_msize_##CRTLIB}; \ + return __TBB_malloc_safer_aligned_realloc( ptr, size, alignment, &func_ptrs ); \ +} + +// Only for ucrtbase: substitution for _o_free +void (*orig__o_free)(void*); +void __TBB_malloc__o_free(void *ptr) +{ + __TBB_malloc_safer_free( ptr, orig__o_free ); +} +// Only for ucrtbase: substitution for _free_base +void(*orig__free_base)(void*); +void __TBB_malloc__free_base(void *ptr) +{ + __TBB_malloc_safer_free(ptr, orig__free_base); +} + +// Size limit is MAX_PATTERN_SIZE (28) byte codes / 56 symbols per line. +// * can be used to match any digit in byte codes. +// # followed by several * indicate a relative address that needs to be corrected. +// Purpose of the pattern is to mark an instruction bound; it should consist of several +// full instructions plus one extra byte code. It's not required for the patterns +// to be unique (i.e., it's OK to have same pattern for unrelated functions). +// TODO: use hot patch prologues if exist +const char* known_bytecodes[] = { +#if _WIN64 +// "========================================================" - 56 symbols + "4883EC284885C974", // release free() + "4883EC284885C975", // release _msize() + "4885C974375348", // release free() 8.0.50727.42, 10.0 + "E907000000CCCC", // release _aligned_msize(), _aligned_free() ucrtbase.dll + "C7442410000000008B", // release free() ucrtbase.dll 10.0.14393.33 + "E90B000000CCCC", // release _msize() ucrtbase.dll 10.0.14393.33 + "48895C24085748", // release _aligned_msize() ucrtbase.dll 10.0.14393.33 + "E903000000CCCC", // release _aligned_msize() ucrtbase.dll 10.0.16299.522 + "48894C24084883EC28BA", // debug prologue + "4C894424184889542410", // debug _aligned_msize() 10.0 + "48894C24084883EC2848", // debug _aligned_free 10.0 + "488BD1488D0D#*******E9", // _o_free(), ucrtbase.dll + #if __TBB_OVERLOAD_OLD_MSVCR + "48895C2408574883EC3049", // release _aligned_msize 9.0 + "4883EC384885C975", // release _msize() 9.0 + "4C8BC1488B0DA6E4040033", // an old win64 SDK + #endif +#else // _WIN32 +// "========================================================" - 56 symbols + "8BFF558BEC8B", // multiple + "8BFF558BEC83", // release free() & _msize() 10.0.40219.325, _msize() ucrtbase.dll + "8BFF558BECFF", // release _aligned_msize ucrtbase.dll + "8BFF558BEC51", // release free() & _msize() ucrtbase.dll 10.0.14393.33 + "558BEC8B450885C074", // release _aligned_free 11.0 + "558BEC837D08000F", // release _msize() 11.0.51106.1 + "558BEC837D08007419FF", // release free() 11.0.50727.1 + "558BEC8B450885C075", // release _aligned_msize() 11.0.50727.1 + "558BEC6A018B", // debug free() & _msize() 11.0 + "558BEC8B451050", // debug _aligned_msize() 11.0 + "558BEC8B450850", // debug _aligned_free 11.0 + "8BFF558BEC6A", // debug free() & _msize() 10.0.40219.325 + #if __TBB_OVERLOAD_OLD_MSVCR + "6A1868********E8", // release free() 8.0.50727.4053, 9.0 + "6A1C68********E8", // release _msize() 8.0.50727.4053, 9.0 + #endif +#endif // _WIN64/_WIN32 + NULL + }; + +#define __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY(CRT_VER,function_name,dbgsuffix) \ + ReplaceFunctionWithStore( #CRT_VER #dbgsuffix ".dll", #function_name, \ + (FUNCPTR)__TBB_malloc_safer_##function_name##_##CRT_VER##dbgsuffix, \ + known_bytecodes, (FUNCPTR*)&orig_##function_name##_##CRT_VER##dbgsuffix ); + +#define __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY_NO_FALLBACK(CRT_VER,function_name,dbgsuffix) \ + ReplaceFunctionWithStore( #CRT_VER #dbgsuffix ".dll", #function_name, \ + (FUNCPTR)__TBB_malloc_safer_##function_name##_##CRT_VER##dbgsuffix, 0, NULL ); + +#define __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY_REDIRECT(CRT_VER,function_name,dest_func,dbgsuffix) \ + ReplaceFunctionWithStore( #CRT_VER #dbgsuffix ".dll", #function_name, \ + (FUNCPTR)__TBB_malloc_safer_##dest_func##_##CRT_VER##dbgsuffix, 0, NULL ); + +#define __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_IMPL(CRT_VER,dbgsuffix) \ + if (BytecodesAreKnown(#CRT_VER #dbgsuffix ".dll")) { \ + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY(CRT_VER,free,dbgsuffix) \ + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY(CRT_VER,_msize,dbgsuffix) \ + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY_NO_FALLBACK(CRT_VER,realloc,dbgsuffix) \ + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY(CRT_VER,_aligned_free,dbgsuffix) \ + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY(CRT_VER,_aligned_msize,dbgsuffix) \ + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_ENTRY_NO_FALLBACK(CRT_VER,_aligned_realloc,dbgsuffix) \ + } else \ + SkipReplacement(#CRT_VER #dbgsuffix ".dll"); + +#define __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_RELEASE(CRT_VER) __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_IMPL(CRT_VER,) +#define __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_DEBUG(CRT_VER) __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_IMPL(CRT_VER,d) + +#define __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL(CRT_VER) \ + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_RELEASE(CRT_VER) \ + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_DEBUG(CRT_VER) + +#if __TBB_OVERLOAD_OLD_MSVCR +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr70d); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr70); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr71d); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr71); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr80d); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr80); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr90d); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr90); +#endif +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr100d); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr100); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr110d); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr110); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr120d); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(msvcr120); +__TBB_ORIG_ALLOCATOR_REPLACEMENT_WRAPPER(ucrtbase); + +/*** replacements for global operators new and delete ***/ + +#if _MSC_VER && !defined(__INTEL_COMPILER) +#pragma warning( push ) +#pragma warning( disable : 4290 ) +#endif + +/*** operator new overloads internals (Linux, Windows) ***/ + +void* operator_new(size_t sz) __TBB_THROW_BAD_ALLOC { + return InternalOperatorNew(sz); +} +void* operator_new_arr(size_t sz) __TBB_THROW_BAD_ALLOC { + return InternalOperatorNew(sz); +} +void operator_delete(void* ptr) __TBB_NO_THROW { + __TBB_malloc_safer_delete(ptr); +} +#if _MSC_VER && !defined(__INTEL_COMPILER) +#pragma warning( pop ) +#endif + +void operator_delete_arr(void* ptr) __TBB_NO_THROW { + __TBB_malloc_safer_delete(ptr); +} +void* operator_new_t(size_t sz, const std::nothrow_t&) __TBB_NO_THROW { + return scalable_malloc(sz); +} +void* operator_new_arr_t(std::size_t sz, const std::nothrow_t&) __TBB_NO_THROW { + return scalable_malloc(sz); +} +void operator_delete_t(void* ptr, const std::nothrow_t&) __TBB_NO_THROW { + __TBB_malloc_safer_delete(ptr); +} +void operator_delete_arr_t(void* ptr, const std::nothrow_t&) __TBB_NO_THROW { + __TBB_malloc_safer_delete(ptr); +} + +struct Module { + const char *name; + bool doFuncReplacement; // do replacement in the DLL +}; + +Module modules_to_replace[] = { + {"msvcr100d.dll", true}, + {"msvcr100.dll", true}, + {"msvcr110d.dll", true}, + {"msvcr110.dll", true}, + {"msvcr120d.dll", true}, + {"msvcr120.dll", true}, + {"ucrtbase.dll", true}, +// "ucrtbased.dll" is not supported because of problems with _dbg functions +#if __TBB_OVERLOAD_OLD_MSVCR + {"msvcr90d.dll", true}, + {"msvcr90.dll", true}, + {"msvcr80d.dll", true}, + {"msvcr80.dll", true}, + {"msvcr70d.dll", true}, + {"msvcr70.dll", true}, + {"msvcr71d.dll", true}, + {"msvcr71.dll", true}, +#endif +#if __TBB_TODO + // TODO: Try enabling replacement for non-versioned system binaries below + {"msvcrtd.dll", true}, + {"msvcrt.dll", true}, +#endif + }; + +/* +We need to replace following functions: +malloc +calloc +_aligned_malloc +_expand (by dummy implementation) +??2@YAPAXI@Z operator new (ia32) +??_U@YAPAXI@Z void * operator new[] (size_t size) (ia32) +??3@YAXPAX@Z operator delete (ia32) +??_V@YAXPAX@Z operator delete[] (ia32) +??2@YAPEAX_K@Z void * operator new(unsigned __int64) (intel64) +??_V@YAXPEAX@Z void * operator new[](unsigned __int64) (intel64) +??3@YAXPEAX@Z operator delete (intel64) +??_V@YAXPEAX@Z operator delete[] (intel64) +??2@YAPAXIABUnothrow_t@std@@@Z void * operator new (size_t sz, const std::nothrow_t&) throw() (optional) +??_U@YAPAXIABUnothrow_t@std@@@Z void * operator new[] (size_t sz, const std::nothrow_t&) throw() (optional) + +and these functions have runtime-specific replacement: +realloc +free +_msize +_aligned_realloc +_aligned_free +_aligned_msize +*/ + +typedef struct FRData_t { + //char *_module; + const char *_func; + FUNCPTR _fptr; + FRR_ON_ERROR _on_error; +} FRDATA; + +FRDATA c_routines_to_replace[] = { + { "malloc", (FUNCPTR)scalable_malloc, FRR_FAIL }, + { "calloc", (FUNCPTR)scalable_calloc, FRR_FAIL }, + { "_aligned_malloc", (FUNCPTR)safer_aligned_malloc, FRR_FAIL }, + { "_expand", (FUNCPTR)safer_expand, FRR_IGNORE }, +}; + +FRDATA cxx_routines_to_replace[] = { +#if _WIN64 + { "??2@YAPEAX_K@Z", (FUNCPTR)operator_new, FRR_FAIL }, + { "??_U@YAPEAX_K@Z", (FUNCPTR)operator_new_arr, FRR_FAIL }, + { "??3@YAXPEAX@Z", (FUNCPTR)operator_delete, FRR_FAIL }, + { "??_V@YAXPEAX@Z", (FUNCPTR)operator_delete_arr, FRR_FAIL }, +#else + { "??2@YAPAXI@Z", (FUNCPTR)operator_new, FRR_FAIL }, + { "??_U@YAPAXI@Z", (FUNCPTR)operator_new_arr, FRR_FAIL }, + { "??3@YAXPAX@Z", (FUNCPTR)operator_delete, FRR_FAIL }, + { "??_V@YAXPAX@Z", (FUNCPTR)operator_delete_arr, FRR_FAIL }, +#endif + { "??2@YAPAXIABUnothrow_t@std@@@Z", (FUNCPTR)operator_new_t, FRR_IGNORE }, + { "??_U@YAPAXIABUnothrow_t@std@@@Z", (FUNCPTR)operator_new_arr_t, FRR_IGNORE } +}; + +#ifndef UNICODE +typedef char unicode_char_t; +#define WCHAR_SPEC "%s" +#else +typedef wchar_t unicode_char_t; +#define WCHAR_SPEC "%ls" +#endif + +// Check that we recognize bytecodes that should be replaced by trampolines. +// If some functions have unknown prologue patterns, replacement should not be done. +bool BytecodesAreKnown(const unicode_char_t *dllName) +{ + const char *funcName[] = {"free", "_msize", "_aligned_free", "_aligned_msize", 0}; + HMODULE module = GetModuleHandle(dllName); + + if (!module) + return false; + for (int i=0; funcName[i]; i++) + if (! IsPrologueKnown(dllName, funcName[i], known_bytecodes, module)) { + fprintf(stderr, "TBBmalloc: skip allocation functions replacement in " WCHAR_SPEC + ": unknown prologue for function " WCHAR_SPEC "\n", dllName, funcName[i]); + return false; + } + return true; +} + +void SkipReplacement(const unicode_char_t *dllName) +{ +#ifndef UNICODE + const char *dllStr = dllName; +#else + const size_t sz = 128; // all DLL name must fit + + char buffer[sz]; + size_t real_sz; + char *dllStr = buffer; + + errno_t ret = wcstombs_s(&real_sz, dllStr, sz, dllName, sz-1); + __TBB_ASSERT(!ret, "Dll name conversion failed"); +#endif + + for (size_t i=0; i<arrayLength(modules_to_replace); i++) + if (!strcmp(modules_to_replace[i].name, dllStr)) { + modules_to_replace[i].doFuncReplacement = false; + break; + } +} + +void ReplaceFunctionWithStore( const unicode_char_t *dllName, const char *funcName, FUNCPTR newFunc, const char ** opcodes, FUNCPTR* origFunc, FRR_ON_ERROR on_error = FRR_FAIL ) +{ + FRR_TYPE res = ReplaceFunction( dllName, funcName, newFunc, opcodes, origFunc ); + + if (res == FRR_OK || res == FRR_NODLL || (res == FRR_NOFUNC && on_error == FRR_IGNORE)) + return; + + fprintf(stderr, "Failed to %s function %s in module %s\n", + res==FRR_NOFUNC? "find" : "replace", funcName, dllName); + + // Unable to replace a required function + // Aborting because incomplete replacement of memory management functions + // may leave the program in an invalid state + abort(); +} + +void doMallocReplacement() +{ + // Replace functions and keep backup of original code (separate for each runtime) +#if __TBB_OVERLOAD_OLD_MSVCR + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL(msvcr70) + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL(msvcr71) + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL(msvcr80) + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL(msvcr90) +#endif + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL(msvcr100) + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL(msvcr110) + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL(msvcr120) + __TBB_ORIG_ALLOCATOR_REPLACEMENT_CALL_RELEASE(ucrtbase) + + // Replace functions without storing original code + for (size_t j = 0; j < arrayLength(modules_to_replace); j++) { + if (!modules_to_replace[j].doFuncReplacement) + continue; + for (size_t i = 0; i < arrayLength(c_routines_to_replace); i++) + { + ReplaceFunctionWithStore( modules_to_replace[j].name, c_routines_to_replace[i]._func, c_routines_to_replace[i]._fptr, NULL, NULL, c_routines_to_replace[i]._on_error ); + } + if ( strcmp(modules_to_replace[j].name, "ucrtbase.dll") == 0 ) { + HMODULE ucrtbase_handle = GetModuleHandle("ucrtbase.dll"); + if (!ucrtbase_handle) + continue; + // If _o_free function is present and patchable, redirect it to tbbmalloc as well + // This prevents issues with other _o_* functions which might allocate memory with malloc + if ( IsPrologueKnown("ucrtbase.dll", "_o_free", known_bytecodes, ucrtbase_handle)) { + ReplaceFunctionWithStore( "ucrtbase.dll", "_o_free", (FUNCPTR)__TBB_malloc__o_free, known_bytecodes, (FUNCPTR*)&orig__o_free, FRR_FAIL ); + } + // Similarly for _free_base + if (IsPrologueKnown("ucrtbase.dll", "_free_base", known_bytecodes, ucrtbase_handle)) { + ReplaceFunctionWithStore("ucrtbase.dll", "_free_base", (FUNCPTR)__TBB_malloc__free_base, known_bytecodes, (FUNCPTR*)&orig__free_base, FRR_FAIL); + } + // ucrtbase.dll does not export operator new/delete, so skip the rest of the loop. + continue; + } + + for (size_t i = 0; i < arrayLength(cxx_routines_to_replace); i++) + { +#if !_WIN64 + // in Microsoft* Visual Studio* 2012 and 2013 32-bit operator delete consists of 2 bytes only: short jump to free(ptr); + // replacement should be skipped for this particular case. + if ( ((strcmp(modules_to_replace[j].name, "msvcr110.dll") == 0) || (strcmp(modules_to_replace[j].name, "msvcr120.dll") == 0)) && (strcmp(cxx_routines_to_replace[i]._func, "??3@YAXPAX@Z") == 0) ) continue; + // in Microsoft* Visual Studio* 2013 32-bit operator delete[] consists of 2 bytes only: short jump to free(ptr); + // replacement should be skipped for this particular case. + if ( (strcmp(modules_to_replace[j].name, "msvcr120.dll") == 0) && (strcmp(cxx_routines_to_replace[i]._func, "??_V@YAXPAX@Z") == 0) ) continue; +#endif + ReplaceFunctionWithStore( modules_to_replace[j].name, cxx_routines_to_replace[i]._func, cxx_routines_to_replace[i]._fptr, NULL, NULL, cxx_routines_to_replace[i]._on_error ); + } + } +} + +#endif // !__TBB_WIN8UI_SUPPORT + +extern "C" BOOL WINAPI DllMain( HINSTANCE hInst, DWORD callReason, LPVOID reserved ) +{ + + if ( callReason==DLL_PROCESS_ATTACH && reserved && hInst ) { +#if !__TBB_WIN8UI_SUPPORT + if (!tbb::internal::GetBoolEnvironmentVariable("TBB_MALLOC_DISABLE_REPLACEMENT")) + { + doMallocReplacement(); + } +#endif // !__TBB_WIN8UI_SUPPORT + } + + return TRUE; +} + +// Just to make the linker happy and link the DLL to the application +extern "C" __declspec(dllexport) void __TBB_malloc_proxy() +{ + +} + +#endif //_WIN32 diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy.h new file mode 100644 index 00000000..a6a8479a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy.h @@ -0,0 +1,62 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _TBB_malloc_proxy_H_ +#define _TBB_malloc_proxy_H_ + +#define MALLOC_UNIXLIKE_OVERLOAD_ENABLED __linux__ +#define MALLOC_ZONE_OVERLOAD_ENABLED __APPLE__ + +// MALLOC_UNIXLIKE_OVERLOAD_ENABLED depends on MALLOC_CHECK_RECURSION stuff +// TODO: limit MALLOC_CHECK_RECURSION to *_OVERLOAD_ENABLED only +#if __linux__ || __APPLE__ || __sun || __FreeBSD__ || MALLOC_UNIXLIKE_OVERLOAD_ENABLED +#define MALLOC_CHECK_RECURSION 1 +#endif + +#include <stddef.h> + +extern "C" { + void * scalable_malloc(size_t size); + void * scalable_calloc(size_t nobj, size_t size); + void scalable_free(void *ptr); + void * scalable_realloc(void* ptr, size_t size); + void * scalable_aligned_malloc(size_t size, size_t alignment); + void * scalable_aligned_realloc(void* ptr, size_t size, size_t alignment); + int scalable_posix_memalign(void **memptr, size_t alignment, size_t size); + size_t scalable_msize(void *ptr); + void __TBB_malloc_safer_free( void *ptr, void (*original_free)(void*)); + void * __TBB_malloc_safer_realloc( void *ptr, size_t, void* ); + void * __TBB_malloc_safer_aligned_realloc( void *ptr, size_t, size_t, void* ); + size_t __TBB_malloc_safer_msize( void *ptr, size_t (*orig_msize_crt80d)(void*)); + size_t __TBB_malloc_safer_aligned_msize( void *ptr, size_t, size_t, size_t (*orig_msize_crt80d)(void*,size_t,size_t)); + +#if MALLOC_ZONE_OVERLOAD_ENABLED + void __TBB_malloc_free_definite_size(void *object, size_t size); +#endif +} // extern "C" + +// Struct with original free() and _msize() pointers +struct orig_ptrs { + void (*free) (void*); + size_t (*msize)(void*); +}; + +struct orig_aligned_ptrs { + void (*aligned_free) (void*); + size_t (*aligned_msize)(void*,size_t,size_t); +}; + +#endif /* _TBB_malloc_proxy_H_ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy_overload_osx.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy_overload_osx.h new file mode 100644 index 00000000..c052b1b5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/proxy_overload_osx.h @@ -0,0 +1,186 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// The original source for this code is +// Copyright (c) 2011, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <AvailabilityMacros.h> +#include <malloc/malloc.h> +#include <mach/mach.h> +#include <stdlib.h> + +static kern_return_t enumerator(task_t, void *, unsigned, vm_address_t, + memory_reader_t, vm_range_recorder_t) +{ + return KERN_FAILURE; +} + +static size_t good_size(malloc_zone_t *, size_t size) +{ + return size; +} + +static boolean_t zone_check(malloc_zone_t *) /* Consistency checker */ +{ + return true; +} + +static void zone_print(malloc_zone_t *, boolean_t) { } +static void zone_log(malloc_zone_t *, void *) {} +static void zone_force_lock(malloc_zone_t *) {} +static void zone_force_unlock(malloc_zone_t *) {} + +static void zone_statistics(malloc_zone_t *, malloc_statistics_t *s) +{ + s->blocks_in_use = 0; + s->size_in_use = s->max_size_in_use = s->size_allocated = 0; +} + +static boolean_t zone_locked(malloc_zone_t *) +{ + return false; +} + +static boolean_t impl_zone_enable_discharge_checking(malloc_zone_t *) +{ + return false; +} + +static void impl_zone_disable_discharge_checking(malloc_zone_t *) {} +static void impl_zone_discharge(malloc_zone_t *, void *) {} +static void impl_zone_destroy(struct _malloc_zone_t *) {} + +/* note: impl_malloc_usable_size() is called for each free() call, so it must be fast */ +static size_t impl_malloc_usable_size(struct _malloc_zone_t *, const void *ptr) +{ + // malloc_usable_size() is used by macOS* to recognize which memory manager + // allocated the address, so our wrapper must not redirect to the original function. + return __TBB_malloc_safer_msize(const_cast<void*>(ptr), NULL); +} + +static void *impl_malloc(struct _malloc_zone_t *, size_t size); +static void *impl_calloc(struct _malloc_zone_t *, size_t num_items, size_t size); +static void *impl_valloc(struct _malloc_zone_t *, size_t size); +static void impl_free(struct _malloc_zone_t *, void *ptr); +static void *impl_realloc(struct _malloc_zone_t *, void *ptr, size_t size); +static void *impl_memalign(struct _malloc_zone_t *, size_t alignment, size_t size); + +/* ptr is in zone and have reported size */ +static void impl_free_definite_size(struct _malloc_zone_t*, void *ptr, size_t size) +{ + __TBB_malloc_free_definite_size(ptr, size); +} + +/* Empty out caches in the face of memory pressure. */ +static size_t impl_pressure_relief(struct _malloc_zone_t *, size_t goal) +{ + return 0; +} + +static malloc_zone_t *system_zone = NULL; + +struct DoMallocReplacement { + DoMallocReplacement() { + static malloc_introspection_t introspect; + memset(&introspect, 0, sizeof(malloc_introspection_t)); + static malloc_zone_t zone; + memset(&zone, 0, sizeof(malloc_zone_t)); + + introspect.enumerator = &enumerator; + introspect.good_size = &good_size; + introspect.check = &zone_check; + introspect.print = &zone_print; + introspect.log = zone_log; + introspect.force_lock = &zone_force_lock; + introspect.force_unlock = &zone_force_unlock; + introspect.statistics = zone_statistics; + introspect.zone_locked = &zone_locked; + introspect.enable_discharge_checking = &impl_zone_enable_discharge_checking; + introspect.disable_discharge_checking = &impl_zone_disable_discharge_checking; + introspect.discharge = &impl_zone_discharge; + + zone.size = &impl_malloc_usable_size; + zone.malloc = &impl_malloc; + zone.calloc = &impl_calloc; + zone.valloc = &impl_valloc; + zone.free = &impl_free; + zone.realloc = &impl_realloc; + zone.destroy = &impl_zone_destroy; + zone.zone_name = "tbbmalloc"; + zone.introspect = &introspect; + zone.version = 8; + zone.memalign = impl_memalign; + zone.free_definite_size = &impl_free_definite_size; + zone.pressure_relief = &impl_pressure_relief; + + // make sure that default purgeable zone is initialized + malloc_default_purgeable_zone(); + void* ptr = malloc(1); + // get all registered memory zones + unsigned zcount = 0; + malloc_zone_t** zone_array = NULL; + kern_return_t errorcode = malloc_get_all_zones(mach_task_self(),NULL,(vm_address_t**)&zone_array,&zcount); + if (!errorcode && zone_array && zcount>0) { + // find the zone that allocated ptr + for (unsigned i=0; i<zcount; ++i) { + malloc_zone_t* z = zone_array[i]; + if (z && z->size(z,ptr)>0) { // the right one is found + system_zone = z; + break; + } + } + } + free(ptr); + + malloc_zone_register(&zone); + if (system_zone) { + // after unregistration of the system zone, the last registered (i.e. our) zone becomes the default + malloc_zone_unregister(system_zone); + // register the system zone back + malloc_zone_register(system_zone); + } + } +}; + +static DoMallocReplacement doMallocReplacement; + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/shared_utils.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/shared_utils.h new file mode 100644 index 00000000..6904663e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/shared_utils.h @@ -0,0 +1,151 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_shared_utils_H +#define __TBB_shared_utils_H + +// Include files containing declarations of intptr_t and uintptr_t +#include <stddef.h> // size_t +#if _MSC_VER +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + #if !UINTPTR_MAX + #define UINTPTR_MAX SIZE_MAX + #endif +#else // _MSC_VER +#include <stdint.h> +#endif + +/* + * Functions to align an integer down or up to the given power of two, + * and test for such an alignment, and for power of two. + */ +template<typename T> +static inline T alignDown(T arg, uintptr_t alignment) { + return T( (uintptr_t)arg & ~(alignment-1)); +} +template<typename T> +static inline T alignUp (T arg, uintptr_t alignment) { + return T(((uintptr_t)arg+(alignment-1)) & ~(alignment-1)); + // /*is this better?*/ return (((uintptr_t)arg-1) | (alignment-1)) + 1; +} +template<typename T> // works for not power-of-2 alignments +static inline T alignUpGeneric(T arg, uintptr_t alignment) { + if (size_t rem = arg % alignment) { + arg += alignment - rem; + } + return arg; +} + +template<typename T, size_t N> // generic function to find length of array +inline size_t arrayLength(const T(&)[N]) { + return N; +} + +/* + * Compile time Log2 calculation + */ +template <size_t NUM> +struct Log2 { static const int value = 1 + Log2<(NUM >> 1)>::value; }; +template <> +struct Log2<1> { static const int value = 0; }; + +#if defined(min) +#undef min +#endif + +template<typename T> +T min ( const T& val1, const T& val2 ) { + return val1 < val2 ? val1 : val2; +} + +/* + * Functions to parse files information (system files for example) + */ + +#include <stdio.h> + +#if defined(_MSC_VER) && (_MSC_VER<1900) && !defined(__INTEL_COMPILER) + // Suppress overzealous compiler warnings that default ctor and assignment + // operator cannot be generated and object 'class' can never be instantiated. + #pragma warning(push) + #pragma warning(disable:4510 4512 4610) +#endif + +#if __SUNPRO_CC + // Suppress overzealous compiler warnings that a class with a reference member + // lacks a user-defined constructor, which can lead to errors + #pragma error_messages (off, refmemnoconstr) +#endif + +// TODO: add a constructor to remove warnings suppression +struct parseFileItem { + const char* format; + unsigned long long& value; +}; + +#if defined(_MSC_VER) && (_MSC_VER<1900) && !defined(__INTEL_COMPILER) + #pragma warning(pop) +#endif + +#if __SUNPRO_CC + #pragma error_messages (on, refmemnoconstr) +#endif + +template <int BUF_LINE_SIZE, int N> +void parseFile(const char* file, const parseFileItem (&items)[N]) { + // Tries to find all items in each line + int found[N] = { 0 }; + // If all items found, stop forward file reading + int numFound = 0; + // Line storage + char buf[BUF_LINE_SIZE]; + + if (FILE *f = fopen(file, "r")) { + while (numFound < N && fgets(buf, BUF_LINE_SIZE, f)) { + for (int i = 0; i < N; ++i) { + if (!found[i] && 1 == sscanf(buf, items[i].format, &items[i].value)) { + ++numFound; + found[i] = 1; + } + } + } + fclose(f); + } +} + +namespace rml { +namespace internal { + +/* + * Best estimate of cache line size, for the purpose of avoiding false sharing. + * Too high causes memory overhead, too low causes false-sharing overhead. + * Because, e.g., 32-bit code might run on a 64-bit system with a larger cache line size, + * it would probably be better to probe at runtime where possible and/or allow for an environment variable override, + * but currently this is still used for compile-time layout of class Block, so the change is not entirely trivial. + */ +#if __powerpc64__ || __ppc64__ || __bgp__ +const uint32_t estimatedCacheLineSize = 128; +#else +const uint32_t estimatedCacheLineSize = 64; +#endif + +} // namespace internal +} // namespace rml + +#endif /* __TBB_shared_utils_H */ + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbb_function_replacement.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbb_function_replacement.cpp new file mode 100644 index 00000000..602ec681 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbb_function_replacement.cpp @@ -0,0 +1,583 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +#if !__TBB_WIN8UI_SUPPORT && defined(_WIN32) + +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#define __TBB_NO_IMPLICIT_LINKAGE 1 + +// no standard-conforming implementation of snprintf prior to VS 2015 +#if !defined(_MSC_VER) || _MSC_VER>=1900 +#define LOG_PRINT(s, n, format, ...) snprintf(s, n, format, __VA_ARGS__) +#else +#define LOG_PRINT(s, n, format, ...) _snprintf_s(s, n, _TRUNCATE, format, __VA_ARGS__) +#endif + +#include <windows.h> +#include <new> +#include <stdio.h> +#include <string.h> +#include "tbb_function_replacement.h" + +#include "tbb/tbb_stddef.h" +#include "../tbb/tbb_assert_impl.h" + +// The information about a standard memory allocation function for the replacement log +struct FunctionInfo { + const char* funcName; + const char* dllName; +}; + +// Namespace that processes and manages the output of records to the Log journal +// that will be provided to user by TBB_malloc_replacement_log() +namespace Log { + // Value of RECORDS_COUNT is set due to the fact that we maximally + // scan 8 modules, and in every module we can swap 6 opcodes. (rounded to 8) + static const unsigned RECORDS_COUNT = 8 * 8; + static const unsigned RECORD_LENGTH = MAX_PATH; + + // Need to add 1 to count of records, because last record must be always NULL + static char *records[RECORDS_COUNT + 1]; + static bool replacement_status = true; + + // Internal counter that contains number of next string for record + static unsigned record_number = 0; + + // Function that writes info about (not)found opcodes to the Log journal + // functionInfo - information about a standard memory allocation function for the replacement log + // opcodeString - string, that contain byte code of this function + // status - information about function replacement status + static void record(FunctionInfo functionInfo, const char * opcodeString, bool status) { + __TBB_ASSERT(functionInfo.dllName, "Empty DLL name value"); + __TBB_ASSERT(functionInfo.funcName, "Empty function name value"); + __TBB_ASSERT(opcodeString, "Empty opcode"); + __TBB_ASSERT(record_number <= RECORDS_COUNT, "Incorrect record number"); + + //If some replacement failed -> set status to false + replacement_status &= status; + + // If we reach the end of the log, write this message to the last line + if (record_number == RECORDS_COUNT) { + // %s - workaround to fix empty variable argument parsing behavior in GCC + LOG_PRINT(records[RECORDS_COUNT - 1], RECORD_LENGTH, "%s", "Log was truncated."); + return; + } + + char* entry = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, RECORD_LENGTH); + __TBB_ASSERT(entry, "Invalid memory was returned"); + + LOG_PRINT(entry, RECORD_LENGTH, "%s: %s (%s), byte pattern: <%s>", + status ? "Success" : "Fail", functionInfo.funcName, functionInfo.dllName, opcodeString); + + records[record_number++] = entry; + } +}; + +inline UINT_PTR Ptr2Addrint(LPVOID ptr) +{ + Int2Ptr i2p; + i2p.lpv = ptr; + return i2p.uip; +} + +inline LPVOID Addrint2Ptr(UINT_PTR ptr) +{ + Int2Ptr i2p; + i2p.uip = ptr; + return i2p.lpv; +} + +// Is the distance between addr1 and addr2 smaller than dist +inline bool IsInDistance(UINT_PTR addr1, UINT_PTR addr2, __int64 dist) +{ + __int64 diff = addr1>addr2 ? addr1-addr2 : addr2-addr1; + return diff<dist; +} + +/* + * When inserting a probe in 64 bits process the distance between the insertion + * point and the target may be bigger than 2^32. In this case we are using + * indirect jump through memory where the offset to this memory location + * is smaller than 2^32 and it contains the absolute address (8 bytes). + * + * This class is used to hold the pages used for the above trampolines. + * Since this utility will be used to replace malloc functions this implementation + * doesn't allocate memory dynamically. + * + * The struct MemoryBuffer holds the data about a page in the memory used for + * replacing functions in 64-bit code where the target is too far to be replaced + * with a short jump. All the calculations of m_base and m_next are in a multiple + * of SIZE_OF_ADDRESS (which is 8 in Win64). + */ +class MemoryProvider { +private: + struct MemoryBuffer { + UINT_PTR m_base; // base address of the buffer + UINT_PTR m_next; // next free location in the buffer + DWORD m_size; // size of buffer + + // Default constructor + MemoryBuffer() : m_base(0), m_next(0), m_size(0) {} + + // Constructor + MemoryBuffer(void *base, DWORD size) + { + m_base = Ptr2Addrint(base); + m_next = m_base; + m_size = size; + } + }; + +MemoryBuffer *CreateBuffer(UINT_PTR addr) + { + // No more room in the pages database + if (m_lastBuffer - m_pages == MAX_NUM_BUFFERS) + return 0; + + void *newAddr = Addrint2Ptr(addr); + // Get information for the region which the given address belongs to + MEMORY_BASIC_INFORMATION memInfo; + if (VirtualQuery(newAddr, &memInfo, sizeof(memInfo)) != sizeof(memInfo)) + return 0; + + for(;;) { + // The new address to check is beyond the current region and aligned to allocation size + newAddr = Addrint2Ptr( (Ptr2Addrint(memInfo.BaseAddress) + memInfo.RegionSize + m_allocSize) & ~(UINT_PTR)(m_allocSize-1) ); + + // Check that the address is in the right distance. + // VirtualAlloc can only round the address down; so it will remain in the right distance + if (!IsInDistance(addr, Ptr2Addrint(newAddr), MAX_DISTANCE)) + break; + + if (VirtualQuery(newAddr, &memInfo, sizeof(memInfo)) != sizeof(memInfo)) + break; + + if (memInfo.State == MEM_FREE && memInfo.RegionSize >= m_allocSize) + { + // Found a free region, try to allocate a page in this region + void *newPage = VirtualAlloc(newAddr, m_allocSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); + if (!newPage) + break; + + // Add the new page to the pages database + MemoryBuffer *pBuff = new (m_lastBuffer) MemoryBuffer(newPage, m_allocSize); + ++m_lastBuffer; + return pBuff; + } + } + + // Failed to find a buffer in the distance + return 0; + } + +public: + MemoryProvider() + { + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + m_allocSize = sysInfo.dwAllocationGranularity; + m_lastBuffer = &m_pages[0]; + } + + // We can't free the pages in the destructor because the trampolines + // are using these memory locations and a replaced function might be called + // after the destructor was called. + ~MemoryProvider() + { + } + + // Return a memory location in distance less than 2^31 from input address + UINT_PTR GetLocation(UINT_PTR addr) + { + MemoryBuffer *pBuff = m_pages; + for (; pBuff<m_lastBuffer && IsInDistance(pBuff->m_next, addr, MAX_DISTANCE); ++pBuff) + { + if (pBuff->m_next < pBuff->m_base + pBuff->m_size) + { + UINT_PTR loc = pBuff->m_next; + pBuff->m_next += MAX_PROBE_SIZE; + return loc; + } + } + + pBuff = CreateBuffer(addr); + if(!pBuff) + return 0; + + UINT_PTR loc = pBuff->m_next; + pBuff->m_next += MAX_PROBE_SIZE; + return loc; + } + +private: + MemoryBuffer m_pages[MAX_NUM_BUFFERS]; + MemoryBuffer *m_lastBuffer; + DWORD m_allocSize; +}; + +static MemoryProvider memProvider; + +// Compare opcodes from dictionary (str1) and opcodes from code (str2) +// str1 might contain '*' to mask addresses +// RETURN: 0 if opcodes did not match, 1 on success +size_t compareStrings( const char *str1, const char *str2 ) +{ + for (size_t i=0; str1[i]!=0; i++){ + if( str1[i]!='*' && str1[i]!='#' && str1[i]!=str2[i] ) return 0; + } + return 1; +} + +// Check function prologue with known prologues from the dictionary +// opcodes - dictionary +// inpAddr - pointer to function prologue +// Dictionary contains opcodes for several full asm instructions +// + one opcode byte for the next asm instruction for safe address processing +// RETURN: 1 + the index of the matched pattern, or 0 if no match found. +static UINT CheckOpcodes( const char ** opcodes, void *inpAddr, bool abortOnError, const FunctionInfo* functionInfo = NULL) +{ + static size_t opcodesStringsCount = 0; + static size_t maxOpcodesLength = 0; + static size_t opcodes_pointer = (size_t)opcodes; + char opcodeString[2*MAX_PATTERN_SIZE+1]; + size_t i; + size_t result = 0; + + // Get the values for static variables + // max length and number of patterns + if( !opcodesStringsCount || opcodes_pointer != (size_t)opcodes ){ + while( *(opcodes + opcodesStringsCount)!= NULL ){ + if( (i=strlen(*(opcodes + opcodesStringsCount))) > maxOpcodesLength ) + maxOpcodesLength = i; + opcodesStringsCount++; + } + opcodes_pointer = (size_t)opcodes; + __TBB_ASSERT( maxOpcodesLength/2 <= MAX_PATTERN_SIZE, "Pattern exceeded the limit of 28 opcodes/56 symbols" ); + } + + // Translate prologue opcodes to string format to compare + for( i=0; i<maxOpcodesLength/2 && i<MAX_PATTERN_SIZE; ++i ){ + sprintf( opcodeString + 2*i, "%.2X", *((unsigned char*)inpAddr+i) ); + } + opcodeString[2*i] = 0; + + // Compare translated opcodes with patterns + for( UINT idx=0; idx<opcodesStringsCount; ++idx ){ + result = compareStrings( opcodes[idx],opcodeString ); + if( result ) { + if (functionInfo) { + Log::record(*functionInfo, opcodeString, /*status*/ true); + } + return idx + 1; // avoid 0 which indicates a failure + } + } + if (functionInfo) { + Log::record(*functionInfo, opcodeString, /*status*/ false); + } + if (abortOnError) { + // Impossibility to find opcodes in the dictionary is a serious issue, + // as if we unable to call original function, leak or crash is expected result. + __TBB_ASSERT_RELEASE( false, "CheckOpcodes failed" ); + } + return 0; +} + +// Modify offsets in original code after moving it to a trampoline. +// We do not have more than one offset to correct in existing opcode patterns. +static void CorrectOffset( UINT_PTR address, const char* pattern, UINT distance ) +{ + const char* pos = strstr(pattern, "#*******"); + if( pos ) { + address += (pos - pattern)/2; // compute the offset position + UINT value; + // UINT assignment is not used to avoid potential alignment issues + memcpy(&value, Addrint2Ptr(address), sizeof(value)); + value += distance; + memcpy(Addrint2Ptr(address), &value, sizeof(value)); + } +} + +// Insert jump relative instruction to the input address +// RETURN: the size of the trampoline or 0 on failure +static DWORD InsertTrampoline32(void *inpAddr, void *targetAddr, const char* pattern, void** storedAddr) +{ + size_t bytesToMove = SIZE_OF_RELJUMP; + UINT_PTR srcAddr = Ptr2Addrint(inpAddr); + UINT_PTR tgtAddr = Ptr2Addrint(targetAddr); + // Check that the target fits in 32 bits + if (!IsInDistance(srcAddr, tgtAddr, MAX_DISTANCE)) + return 0; + + UINT_PTR offset; + UINT offset32; + UCHAR *codePtr = (UCHAR *)inpAddr; + + if ( storedAddr ){ // If requested, store original function code + bytesToMove = strlen(pattern)/2-1; // The last byte matching the pattern must not be copied + __TBB_ASSERT_RELEASE( bytesToMove >= SIZE_OF_RELJUMP, "Incorrect bytecode pattern?" ); + UINT_PTR trampAddr = memProvider.GetLocation(srcAddr); + if (!trampAddr) + return 0; + *storedAddr = Addrint2Ptr(trampAddr); + // Set 'executable' flag for original instructions in the new place + DWORD pageFlags = PAGE_EXECUTE_READWRITE; + if (!VirtualProtect(*storedAddr, MAX_PROBE_SIZE, pageFlags, &pageFlags)) return 0; + // Copy original instructions to the new place + memcpy(*storedAddr, codePtr, bytesToMove); + offset = srcAddr - trampAddr; + offset32 = (UINT)(offset & 0xFFFFFFFF); + CorrectOffset( trampAddr, pattern, offset32 ); + // Set jump to the code after replacement + offset32 -= SIZE_OF_RELJUMP; + *(UCHAR*)(trampAddr+bytesToMove) = 0xE9; + memcpy((UCHAR*)(trampAddr+bytesToMove+1), &offset32, sizeof(offset32)); + } + + // The following will work correctly even if srcAddr>tgtAddr, as long as + // address difference is less than 2^31, which is guaranteed by IsInDistance. + offset = tgtAddr - srcAddr - SIZE_OF_RELJUMP; + offset32 = (UINT)(offset & 0xFFFFFFFF); + // Insert the jump to the new code + *codePtr = 0xE9; + memcpy(codePtr+1, &offset32, sizeof(offset32)); + + // Fill the rest with NOPs to correctly see disassembler of old code in debugger. + for( unsigned i=SIZE_OF_RELJUMP; i<bytesToMove; i++ ){ + *(codePtr+i) = 0x90; + } + + return SIZE_OF_RELJUMP; +} + +// This function is called when the offset doesn't fit in 32 bits +// 1 Find and allocate a page in the small distance (<2^31) from input address +// 2 Put jump RIP relative indirect through the address in the close page +// 3 Put the absolute address of the target in the allocated location +// RETURN: the size of the trampoline or 0 on failure +static DWORD InsertTrampoline64(void *inpAddr, void *targetAddr, const char* pattern, void** storedAddr) +{ + size_t bytesToMove = SIZE_OF_INDJUMP; + + UINT_PTR srcAddr = Ptr2Addrint(inpAddr); + UINT_PTR tgtAddr = Ptr2Addrint(targetAddr); + + // Get a location close to the source address + UINT_PTR location = memProvider.GetLocation(srcAddr); + if (!location) + return 0; + + UINT_PTR offset; + UINT offset32; + UCHAR *codePtr = (UCHAR *)inpAddr; + + // Fill the location + UINT_PTR *locPtr = (UINT_PTR *)Addrint2Ptr(location); + *locPtr = tgtAddr; + + if ( storedAddr ){ // If requested, store original function code + bytesToMove = strlen(pattern)/2-1; // The last byte matching the pattern must not be copied + __TBB_ASSERT_RELEASE( bytesToMove >= SIZE_OF_INDJUMP, "Incorrect bytecode pattern?" ); + UINT_PTR trampAddr = memProvider.GetLocation(srcAddr); + if (!trampAddr) + return 0; + *storedAddr = Addrint2Ptr(trampAddr); + // Set 'executable' flag for original instructions in the new place + DWORD pageFlags = PAGE_EXECUTE_READWRITE; + if (!VirtualProtect(*storedAddr, MAX_PROBE_SIZE, pageFlags, &pageFlags)) return 0; + // Copy original instructions to the new place + memcpy(*storedAddr, codePtr, bytesToMove); + offset = srcAddr - trampAddr; + offset32 = (UINT)(offset & 0xFFFFFFFF); + CorrectOffset( trampAddr, pattern, offset32 ); + // Set jump to the code after replacement. It is within the distance of relative jump! + offset32 -= SIZE_OF_RELJUMP; + *(UCHAR*)(trampAddr+bytesToMove) = 0xE9; + memcpy((UCHAR*)(trampAddr+bytesToMove+1), &offset32, sizeof(offset32)); + } + + // Fill the buffer + offset = location - srcAddr - SIZE_OF_INDJUMP; + offset32 = (UINT)(offset & 0xFFFFFFFF); + *(codePtr) = 0xFF; + *(codePtr+1) = 0x25; + memcpy(codePtr+2, &offset32, sizeof(offset32)); + + // Fill the rest with NOPs to correctly see disassembler of old code in debugger. + for( unsigned i=SIZE_OF_INDJUMP; i<bytesToMove; i++ ){ + *(codePtr+i) = 0x90; + } + + return SIZE_OF_INDJUMP; +} + +// Insert a jump instruction in the inpAddr to the targetAddr +// 1. Get the memory protection of the page containing the input address +// 2. Change the memory protection to writable +// 3. Call InsertTrampoline32 or InsertTrampoline64 +// 4. Restore memory protection +// RETURN: FALSE on failure, TRUE on success +static bool InsertTrampoline(void *inpAddr, void *targetAddr, const char ** opcodes, void** origFunc) +{ + DWORD probeSize; + // Change page protection to EXECUTE+WRITE + DWORD origProt = 0; + if (!VirtualProtect(inpAddr, MAX_PROBE_SIZE, PAGE_EXECUTE_WRITECOPY, &origProt)) + return FALSE; + + const char* pattern = NULL; + if ( origFunc ){ // Need to store original function code + UCHAR * const codePtr = (UCHAR *)inpAddr; + if ( *codePtr == 0xE9 ){ // JMP relative instruction + // For the special case when a system function consists of a single near jump, + // instead of moving it somewhere we use the target of the jump as the original function. + unsigned offsetInJmp = *(unsigned*)(codePtr + 1); + *origFunc = (void*)(Ptr2Addrint(inpAddr) + offsetInJmp + SIZE_OF_RELJUMP); + origFunc = NULL; // now it must be ignored by InsertTrampoline32/64 + } else { + // find the right opcode pattern + UINT opcodeIdx = CheckOpcodes( opcodes, inpAddr, /*abortOnError=*/true ); + __TBB_ASSERT( opcodeIdx > 0, "abortOnError ignored in CheckOpcodes?" ); + pattern = opcodes[opcodeIdx-1]; // -1 compensates for +1 in CheckOpcodes + } + } + + probeSize = InsertTrampoline32(inpAddr, targetAddr, pattern, origFunc); + if (!probeSize) + probeSize = InsertTrampoline64(inpAddr, targetAddr, pattern, origFunc); + + // Restore original protection + VirtualProtect(inpAddr, MAX_PROBE_SIZE, origProt, &origProt); + + if (!probeSize) + return FALSE; + + FlushInstructionCache(GetCurrentProcess(), inpAddr, probeSize); + FlushInstructionCache(GetCurrentProcess(), origFunc, probeSize); + + return TRUE; +} + +// Routine to replace the functions +// TODO: replace opcodesNumber with opcodes and opcodes number to check if we replace right code. +FRR_TYPE ReplaceFunctionA(const char *dllName, const char *funcName, FUNCPTR newFunc, const char ** opcodes, FUNCPTR* origFunc) +{ + // Cache the results of the last search for the module + // Assume that there was no DLL unload between + static char cachedName[MAX_PATH+1]; + static HMODULE cachedHM = 0; + + if (!dllName || !*dllName) + return FRR_NODLL; + + if (!cachedHM || strncmp(dllName, cachedName, MAX_PATH) != 0) + { + // Find the module handle for the input dll + HMODULE hModule = GetModuleHandleA(dllName); + if (hModule == 0) + { + // Couldn't find the module with the input name + cachedHM = 0; + return FRR_NODLL; + } + + cachedHM = hModule; + strncpy(cachedName, dllName, MAX_PATH); + } + + FARPROC inpFunc = GetProcAddress(cachedHM, funcName); + if (inpFunc == 0) + { + // Function was not found + return FRR_NOFUNC; + } + + if (!InsertTrampoline((void*)inpFunc, (void*)newFunc, opcodes, (void**)origFunc)){ + // Failed to insert the trampoline to the target address + return FRR_FAILED; + } + + return FRR_OK; +} + +FRR_TYPE ReplaceFunctionW(const wchar_t *dllName, const char *funcName, FUNCPTR newFunc, const char ** opcodes, FUNCPTR* origFunc) +{ + // Cache the results of the last search for the module + // Assume that there was no DLL unload between + static wchar_t cachedName[MAX_PATH+1]; + static HMODULE cachedHM = 0; + + if (!dllName || !*dllName) + return FRR_NODLL; + + if (!cachedHM || wcsncmp(dllName, cachedName, MAX_PATH) != 0) + { + // Find the module handle for the input dll + HMODULE hModule = GetModuleHandleW(dllName); + if (hModule == 0) + { + // Couldn't find the module with the input name + cachedHM = 0; + return FRR_NODLL; + } + + cachedHM = hModule; + wcsncpy(cachedName, dllName, MAX_PATH); + } + + FARPROC inpFunc = GetProcAddress(cachedHM, funcName); + if (inpFunc == 0) + { + // Function was not found + return FRR_NOFUNC; + } + + if (!InsertTrampoline((void*)inpFunc, (void*)newFunc, opcodes, (void**)origFunc)){ + // Failed to insert the trampoline to the target address + return FRR_FAILED; + } + + return FRR_OK; +} + +bool IsPrologueKnown(const char* dllName, const char *funcName, const char **opcodes, HMODULE module) +{ + FARPROC inpFunc = GetProcAddress(module, funcName); + FunctionInfo functionInfo = { funcName, dllName }; + + if (!inpFunc) { + Log::record(functionInfo, "unknown", /*status*/ false); + return false; + } + + return CheckOpcodes( opcodes, (void*)inpFunc, /*abortOnError=*/false, &functionInfo) != 0; +} + +// Public Windows API +extern "C" __declspec(dllexport) int TBB_malloc_replacement_log(char *** function_replacement_log_ptr) +{ + if (function_replacement_log_ptr != NULL) { + *function_replacement_log_ptr = Log::records; + } + + // If we have no logs -> return false status + return Log::replacement_status && Log::records[0] != NULL ? 0 : -1; +} + +#endif /* !__TBB_WIN8UI_SUPPORT && defined(_WIN32) */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbb_function_replacement.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbb_function_replacement.h new file mode 100644 index 00000000..109536bc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbb_function_replacement.h @@ -0,0 +1,79 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_function_replacement_H +#define __TBB_function_replacement_H + +#include <stddef.h> //for ptrdiff_t +typedef enum { + FRR_OK, /* Succeeded in replacing the function */ + FRR_NODLL, /* The requested DLL was not found */ + FRR_NOFUNC, /* The requested function was not found */ + FRR_FAILED, /* The function replacement request failed */ +} FRR_TYPE; + +typedef enum { + FRR_FAIL, /* Required function */ + FRR_IGNORE, /* optional function */ +} FRR_ON_ERROR; + +typedef void (*FUNCPTR)(); + +#ifndef UNICODE +#define ReplaceFunction ReplaceFunctionA +#else +#define ReplaceFunction ReplaceFunctionW +#endif //UNICODE + +FRR_TYPE ReplaceFunctionA(const char *dllName, const char *funcName, FUNCPTR newFunc, const char ** opcodes, FUNCPTR* origFunc=NULL); +FRR_TYPE ReplaceFunctionW(const wchar_t *dllName, const char *funcName, FUNCPTR newFunc, const char ** opcodes, FUNCPTR* origFunc=NULL); + +bool IsPrologueKnown(const char* dllName, const char *funcName, const char **opcodes, HMODULE module); + +// Utilities to convert between ADDRESS and LPVOID +union Int2Ptr { + UINT_PTR uip; + LPVOID lpv; +}; + +inline UINT_PTR Ptr2Addrint(LPVOID ptr); +inline LPVOID Addrint2Ptr(UINT_PTR ptr); + +// The size of a trampoline region +const unsigned MAX_PROBE_SIZE = 32; + +// The size of a jump relative instruction "e9 00 00 00 00" +const unsigned SIZE_OF_RELJUMP = 5; + +// The size of jump RIP relative indirect "ff 25 00 00 00 00" +const unsigned SIZE_OF_INDJUMP = 6; + +// The size of address we put in the location (in Intel64) +const unsigned SIZE_OF_ADDRESS = 8; + +// The size limit (in bytes) for an opcode pattern to fit into a trampoline +// There should be enough space left for a relative jump; +1 is for the extra pattern byte. +const unsigned MAX_PATTERN_SIZE = MAX_PROBE_SIZE - SIZE_OF_RELJUMP + 1; + +// The max distance covered in 32 bits: 2^31 - 1 - C +// where C should not be smaller than the size of a probe. +// The latter is important to correctly handle "backward" jumps. +const __int64 MAX_DISTANCE = (((__int64)1 << 31) - 1) - MAX_PROBE_SIZE; + +// The maximum number of distinct buffers in memory +const ptrdiff_t MAX_NUM_BUFFERS = 256; + +#endif //__TBB_function_replacement_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc.cpp new file mode 100644 index 00000000..080ce1d4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc.cpp @@ -0,0 +1,117 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "TypeDefinitions.h" // Customize.h and proxy.h get included +#include "tbbmalloc_internal_api.h" + +#include "../tbb/tbb_assert_impl.h" // Out-of-line TBB assertion handling routines are instantiated here. + +#undef UNICODE + +#if USE_PTHREAD +#include <dlfcn.h> // dlopen +#elif USE_WINTHREAD +#include "tbb/machine/windows_api.h" +#endif + +namespace rml { +namespace internal { + +#if TBB_USE_DEBUG +#define DEBUG_SUFFIX "_debug" +#else +#define DEBUG_SUFFIX +#endif /* TBB_USE_DEBUG */ + +// MALLOCLIB_NAME is the name of the TBB memory allocator library. +#if _WIN32||_WIN64 +#define MALLOCLIB_NAME "tbbmalloc" DEBUG_SUFFIX ".dll" +#elif __APPLE__ +#define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".dylib" +#elif __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __sun || _AIX || __ANDROID__ +#define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".so" +#elif __linux__ +#define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX __TBB_STRING(.so.TBB_COMPATIBLE_INTERFACE_VERSION) +#else +#error Unknown OS +#endif + +void init_tbbmalloc() { +#if DO_ITT_NOTIFY + MallocInitializeITT(); +#endif + +/* Preventing TBB allocator library from unloading to prevent + resource leak, as memory is not released on the library unload. +*/ +#if USE_WINTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED && !__TBB_WIN8UI_SUPPORT + // Prevent Windows from displaying message boxes if it fails to load library + UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS); + HMODULE lib; + BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS + |GET_MODULE_HANDLE_EX_FLAG_PIN, + (LPCTSTR)&scalable_malloc, &lib); + MALLOC_ASSERT(lib && ret, "Allocator can't find itself."); + SetErrorMode (prev_mode); +#endif /* USE_PTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED */ +} + +#if !__TBB_SOURCE_DIRECTLY_INCLUDED +#if USE_WINTHREAD +extern "C" BOOL WINAPI DllMain( HINSTANCE /*hInst*/, DWORD callReason, LPVOID lpvReserved) +{ + if (callReason==DLL_THREAD_DETACH) + { + __TBB_mallocThreadShutdownNotification(); + } + else if (callReason==DLL_PROCESS_DETACH) + { + __TBB_mallocProcessShutdownNotification(lpvReserved != NULL); + } + return TRUE; +} +#else /* !USE_WINTHREAD */ +struct RegisterProcessShutdownNotification { +// Work around non-reentrancy in dlopen() on Android +#if !__TBB_USE_DLOPEN_REENTRANCY_WORKAROUND + RegisterProcessShutdownNotification() { + // prevents unloading, POSIX case + dlopen(MALLOCLIB_NAME, RTLD_NOW); + } +#endif /* !__TBB_USE_DLOPEN_REENTRANCY_WORKAROUND */ + ~RegisterProcessShutdownNotification() { + __TBB_mallocProcessShutdownNotification(false); + } +}; + +static RegisterProcessShutdownNotification reg; +#endif /* !USE_WINTHREAD */ +#endif /* !__TBB_SOURCE_DIRECTLY_INCLUDED */ + +} } // namespaces + +#if __TBB_ipf +/* It was found that on IA-64 architecture inlining of __TBB_machine_lockbyte leads + to serious performance regression with ICC. So keep it out-of-line. + + This code is copy-pasted from tbb_misc.cpp. + */ +extern "C" intptr_t __TBB_machine_lockbyte( volatile unsigned char& flag ) { + tbb::internal::atomic_backoff backoff; + while( !__TBB_TryLockByte(flag) ) backoff.pause(); + return 0; +} +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc.rc b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc.rc new file mode 100644 index 00000000..6c6eedfc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc.rc @@ -0,0 +1,115 @@ +// Copyright (c) 2005-2020 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Microsoft Visual C++ generated resource script. +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include <winresrc.h> +#define ENDL "\r\n" +#include "tbb/tbb_version.h" + +#define TBBMALLOC_VERNUMBERS TBB_VERSION_MAJOR, TBB_VERSION_MINOR, __TBB_VERSION_YMD +#define TBBMALLOC_VERSION __TBB_STRING(TBBMALLOC_VERNUMBERS) + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// manifest integration +#ifdef TBB_MANIFEST +#include "winuser.h" +2 RT_MANIFEST tbbmanifest.exe.manifest +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION TBBMALLOC_VERNUMBERS + PRODUCTVERSION TBB_VERNUMBERS + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Intel Corporation\0" + VALUE "FileDescription", "Scalable Allocator library\0" + VALUE "FileVersion", TBBMALLOC_VERSION "\0" + VALUE "LegalCopyright", "Copyright 2005-2020 Intel Corporation. All Rights Reserved.\0" + VALUE "LegalTrademarks", "\0" +#ifndef TBB_USE_DEBUG + VALUE "OriginalFilename", "tbbmalloc.dll\0" +#else + VALUE "OriginalFilename", "tbbmalloc_debug.dll\0" +#endif + VALUE "ProductName", "Intel(R) Threading Building Blocks for Windows\0" + VALUE "ProductVersion", TBB_VERSION "\0" + VALUE "PrivateBuild", "\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc_internal.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc_internal.h new file mode 100644 index 00000000..8f95aa05 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc_internal.h @@ -0,0 +1,717 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbbmalloc_internal_H +#define __TBB_tbbmalloc_internal_H + + +#include "TypeDefinitions.h" /* Also includes customization layer Customize.h */ + +#if USE_PTHREAD + // Some pthreads documentation says that <pthreads.h> must be first header. + #include <pthread.h> + typedef pthread_key_t tls_key_t; +#elif USE_WINTHREAD + #include "tbb/machine/windows_api.h" + typedef DWORD tls_key_t; +#else + #error Must define USE_PTHREAD or USE_WINTHREAD +#endif + +// TODO: *BSD also has it +#define BACKEND_HAS_MREMAP __linux__ +#define CHECK_ALLOCATION_RANGE MALLOC_DEBUG || MALLOC_ZONE_OVERLOAD_ENABLED || MALLOC_UNIXLIKE_OVERLOAD_ENABLED + +#include "tbb/tbb_config.h" // for __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN +#if __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN + #define _EXCEPTION_PTR_H /* prevents exception_ptr.h inclusion */ + #define _GLIBCXX_NESTED_EXCEPTION_H /* prevents nested_exception.h inclusion */ +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> // for CHAR_BIT +#include <string.h> // for memset +#if MALLOC_CHECK_RECURSION +#include <new> /* for placement new */ +#endif +#include "tbb/scalable_allocator.h" +#include "tbbmalloc_internal_api.h" + +/********* Various compile-time options **************/ + +#if !__TBB_DEFINE_MIC && __TBB_MIC_NATIVE + #error Intel(R) Many Integrated Core Compiler does not define __MIC__ anymore. +#endif + +#define MALLOC_TRACE 0 + +#if MALLOC_TRACE +#define TRACEF(x) printf x +#else +#define TRACEF(x) ((void)0) +#endif /* MALLOC_TRACE */ + +#define ASSERT_TEXT NULL + +#define COLLECT_STATISTICS ( MALLOC_DEBUG && MALLOCENV_COLLECT_STATISTICS ) +#ifndef USE_INTERNAL_TID +#define USE_INTERNAL_TID COLLECT_STATISTICS || MALLOC_TRACE +#endif + +#include "Statistics.h" + +// call yield for whitebox testing, skip in real library +#ifndef WhiteboxTestingYield +#define WhiteboxTestingYield() ((void)0) +#endif + + +/********* End compile-time options **************/ + +namespace rml { + +namespace internal { + +#if __TBB_MALLOC_LOCACHE_STAT +extern intptr_t mallocCalls, cacheHits; +extern intptr_t memAllocKB, memHitKB; +#endif + +//! Utility template function to prevent "unused" warnings by various compilers. +template<typename T> +void suppress_unused_warning( const T& ) {} + +/********** Various global default constants ********/ + +/* + * Default huge page size + */ +static const size_t HUGE_PAGE_SIZE = 2 * 1024 * 1024; + +/********** End of global default constatns *********/ + +/********** Various numeric parameters controlling allocations ********/ + +/* + * slabSize - the size of a block for allocation of small objects, + * it must be larger than maxSegregatedObjectSize. + */ +const uintptr_t slabSize = 16*1024; + +/* + * Large blocks cache cleanup frequency. + * It should be power of 2 for the fast checking. + */ +const unsigned cacheCleanupFreq = 256; + +/* + * Alignment of large (>= minLargeObjectSize) objects. + */ +const size_t largeObjectAlignment = estimatedCacheLineSize; + +/* + * This number of bins in the TLS that leads to blocks that we can allocate in. + */ +const uint32_t numBlockBinLimit = 31; + +/********** End of numeric parameters controlling allocations *********/ + +class BlockI; +class Block; +struct LargeMemoryBlock; +struct ExtMemoryPool; +struct MemRegion; +class FreeBlock; +class TLSData; +class Backend; +class MemoryPool; +struct CacheBinOperation; +extern const uint32_t minLargeObjectSize; + +enum DecreaseOrIncrease { + decrease, increase +}; + +class TLSKey { + tls_key_t TLS_pointer_key; +public: + bool init(); + bool destroy(); + TLSData* getThreadMallocTLS() const; + void setThreadMallocTLS( TLSData * newvalue ); + TLSData* createTLS(MemoryPool *memPool, Backend *backend); +}; + +template<typename Arg, typename Compare> +inline void AtomicUpdate(Arg &location, Arg newVal, const Compare &cmp) +{ + MALLOC_STATIC_ASSERT(sizeof(Arg) == sizeof(intptr_t), + "Type of argument must match AtomicCompareExchange type."); + for (Arg old = location; cmp(old, newVal); ) { + Arg val = AtomicCompareExchange((intptr_t&)location, (intptr_t)newVal, old); + if (val == old) + break; + // TODO: do we need backoff after unsuccessful CAS? + old = val; + } +} + +// TODO: make BitMaskBasic more general +// (currently, it fits BitMaskMin well, but not as suitable for BitMaskMax) +template<unsigned NUM> +class BitMaskBasic { + static const unsigned SZ = (NUM-1)/(CHAR_BIT*sizeof(uintptr_t))+1; + static const unsigned WORD_LEN = CHAR_BIT*sizeof(uintptr_t); + uintptr_t mask[SZ]; +protected: + void set(size_t idx, bool val) { + MALLOC_ASSERT(idx<NUM, ASSERT_TEXT); + + size_t i = idx / WORD_LEN; + int pos = WORD_LEN - idx % WORD_LEN - 1; + if (val) + AtomicOr(&mask[i], 1ULL << pos); + else + AtomicAnd(&mask[i], ~(1ULL << pos)); + } + int getMinTrue(unsigned startIdx) const { + unsigned idx = startIdx / WORD_LEN; + int pos; + + if (startIdx % WORD_LEN) { + // only interested in part of a word, clear bits before startIdx + pos = WORD_LEN - startIdx % WORD_LEN; + uintptr_t actualMask = mask[idx] & (((uintptr_t)1<<pos) - 1); + idx++; + if (-1 != (pos = BitScanRev(actualMask))) + return idx*WORD_LEN - pos - 1; + } + + while (idx<SZ) + if (-1 != (pos = BitScanRev(mask[idx++]))) + return idx*WORD_LEN - pos - 1; + return -1; + } +public: + void reset() { for (unsigned i=0; i<SZ; i++) mask[i] = 0; } +}; + +template<unsigned NUM> +class BitMaskMin : public BitMaskBasic<NUM> { +public: + void set(size_t idx, bool val) { BitMaskBasic<NUM>::set(idx, val); } + int getMinTrue(unsigned startIdx) const { + return BitMaskBasic<NUM>::getMinTrue(startIdx); + } +}; + +template<unsigned NUM> +class BitMaskMax : public BitMaskBasic<NUM> { +public: + void set(size_t idx, bool val) { + BitMaskBasic<NUM>::set(NUM - 1 - idx, val); + } + int getMaxTrue(unsigned startIdx) const { + int p = BitMaskBasic<NUM>::getMinTrue(NUM-startIdx-1); + return -1==p? -1 : (int)NUM - 1 - p; + } +}; + + +// The part of thread-specific data that can be modified by other threads. +// Such modifications must be protected by AllLocalCaches::listLock. +struct TLSRemote { + TLSRemote *next, + *prev; +}; + +// The list of all thread-local data; supporting cleanup of thread caches +class AllLocalCaches { + TLSRemote *head; + MallocMutex listLock; // protects operations in the list +public: + void registerThread(TLSRemote *tls); + void unregisterThread(TLSRemote *tls); + bool cleanup(bool cleanOnlyUnused); + void markUnused(); + void reset() { head = NULL; } +}; + +class LifoList { +public: + inline LifoList(); + inline void push(Block *block); + inline Block *pop(); + inline Block *grab(); + +private: + Block *top; + MallocMutex lock; +}; + +/* + * When a block that is not completely free is returned for reuse by other threads + * this is where the block goes. + * + * LifoList assumes zero initialization; so below its constructors are omitted, + * to avoid linking with C++ libraries on Linux. + */ + +class OrphanedBlocks { + LifoList bins[numBlockBinLimit]; +public: + Block *get(TLSData *tls, unsigned int size); + void put(intptr_t binTag, Block *block); + void reset(); + bool cleanup(Backend* backend); +}; + +/* Large objects entities */ +#include "large_objects.h" + +// select index size for BackRefMaster based on word size: default is uint32_t, +// uint16_t for 32-bit platforms +template<bool> +struct MasterIndexSelect { + typedef uint32_t master_type; +}; + +template<> +struct MasterIndexSelect<false> { + typedef uint16_t master_type; +}; + +class BackRefIdx { // composite index to backreference array +public: + typedef MasterIndexSelect<4 < sizeof(uintptr_t)>::master_type master_t; +private: + static const master_t invalid = ~master_t(0); + master_t master; // index in BackRefMaster + uint16_t largeObj:1; // is this object "large"? + uint16_t offset :15; // offset from beginning of BackRefBlock +public: + BackRefIdx() : master(invalid), largeObj(0), offset(0) {} + bool isInvalid() const { return master == invalid; } + bool isLargeObject() const { return largeObj; } + master_t getMaster() const { return master; } + uint16_t getOffset() const { return offset; } + + // only newBackRef can modify BackRefIdx + static BackRefIdx newBackRef(bool largeObj); +}; + +// Block header is used during block coalescing +// and must be preserved in used blocks. +class BlockI { + intptr_t blockState[2]; +}; + +struct LargeMemoryBlock : public BlockI { + MemoryPool *pool; // owner pool + LargeMemoryBlock *next, // ptrs in list of cached blocks + *prev, + // 2-linked list of pool's large objects + // Used to destroy backrefs on pool destroy (backrefs are global) + // and for object releasing during pool reset. + *gPrev, + *gNext; + uintptr_t age; // age of block while in cache + size_t objectSize; // the size requested by a client + size_t unalignedSize; // the size requested from backend + BackRefIdx backRefIdx; // cached here, used copy is in LargeObjectHdr +}; + +// Classes and methods for backend.cpp +#include "backend.h" + +// An TBB allocator mode that can be controlled by user +// via API/environment variable. Must be placed in zero-initialized memory. +// External synchronization assumed. +// TODO: TBB_VERSION support +class AllocControlledMode { + intptr_t val; + bool setDone; + +public: + intptr_t get() const { + MALLOC_ASSERT(setDone, ASSERT_TEXT); + return val; + } + + // Note: set() can be called before init() + void set(intptr_t newVal) { + val = newVal; + setDone = true; + } + + bool ready() const { + return setDone; + } + + // envName - environment variable to get controlled mode + void initReadEnv(const char *envName, intptr_t defaultVal) { + if (!setDone) { +#if !__TBB_WIN8UI_SUPPORT + // TODO: use strtol to get the actual value of the envirable + const char *envVal = getenv(envName); + if (envVal && !strcmp(envVal, "1")) + val = 1; + else +#endif + val = defaultVal; + setDone = true; + } + } +}; + +// Page type to be used inside MapMemory. +// Regular (4KB aligned), Huge and Transparent Huge Pages (2MB aligned). +enum PageType { + REGULAR = 0, + PREALLOCATED_HUGE_PAGE, + TRANSPARENT_HUGE_PAGE +}; + +// init() and printStatus() is called only under global initialization lock. +// Race is possible between registerAllocation() and registerReleasing(), +// harm is that up to single huge page releasing is missed (because failure +// to get huge page is registered only 1st time), that is negligible. +// setMode is also can be called concurrently. +// Object must reside in zero-initialized memory +// TODO: can we check for huge page presence during every 10th mmap() call +// in case huge page is released by another process? +class HugePagesStatus { +private: + AllocControlledMode requestedMode; // changed only by user + // to keep enabled and requestedMode consistent + MallocMutex setModeLock; + size_t pageSize; + intptr_t needActualStatusPrint; + + static void doPrintStatus(bool state, const char *stateName) { + // Under macOS* fprintf/snprintf acquires an internal lock, so when + // 1st allocation is done under the lock, we got a deadlock. + // Do not use fprintf etc during initialization. + fputs("TBBmalloc: huge pages\t", stderr); + if (!state) + fputs("not ", stderr); + fputs(stateName, stderr); + fputs("\n", stderr); + } + + void parseSystemMemInfo() { + bool hpAvailable = false; + bool thpAvailable = false; + unsigned long long hugePageSize = 0; + +#if __linux__ + // Check huge pages existence + unsigned long long meminfoHugePagesTotal = 0; + + parseFileItem meminfoItems[] = { + // Parse system huge page size + { "Hugepagesize: %llu kB", hugePageSize }, + // Check if there are preallocated huge pages on the system + // https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt + { "HugePages_Total: %llu", meminfoHugePagesTotal } }; + + parseFile</*BUFF_SIZE=*/100>("/proc/meminfo", meminfoItems); + + // Double check another system information regarding preallocated + // huge pages if there are no information in /proc/meminfo + unsigned long long vmHugePagesTotal = 0; + + parseFileItem vmItem[] = { { "%llu", vmHugePagesTotal } }; + + // We parse a counter number, it can't be huge + parseFile</*BUFF_SIZE=*/100>("/proc/sys/vm/nr_hugepages", vmItem); + + if (meminfoHugePagesTotal > 0 || vmHugePagesTotal > 0) { + MALLOC_ASSERT(hugePageSize != 0, "Huge Page size can't be zero if we found preallocated."); + + // Any non zero value clearly states that there are preallocated + // huge pages on the system + hpAvailable = true; + } + + // Check if there is transparent huge pages support on the system + unsigned long long thpPresent = 'n'; + parseFileItem thpItem[] = { { "[alwa%cs] madvise never\n", thpPresent } }; + parseFile</*BUFF_SIZE=*/100>("/sys/kernel/mm/transparent_hugepage/enabled", thpItem); + + if (thpPresent == 'y') { + MALLOC_ASSERT(hugePageSize != 0, "Huge Page size can't be zero if we found thp existence."); + thpAvailable = true; + } +#endif + MALLOC_ASSERT(!pageSize, "Huge page size can't be set twice. Double initialization."); + + // Initialize object variables + pageSize = hugePageSize * 1024; // was read in KB from meminfo + isHPAvailable = hpAvailable; + isTHPAvailable = thpAvailable; + } + +public: + + // System information + bool isHPAvailable; + bool isTHPAvailable; + + // User defined value + bool isEnabled; + + void init() { + parseSystemMemInfo(); + MallocMutex::scoped_lock lock(setModeLock); + requestedMode.initReadEnv("TBB_MALLOC_USE_HUGE_PAGES", 0); + isEnabled = (isHPAvailable || isTHPAvailable) && requestedMode.get(); + } + + // Could be set from user code at any place. + // If we didn't call init() at this place, isEnabled will be false + void setMode(intptr_t newVal) { + MallocMutex::scoped_lock lock(setModeLock); + requestedMode.set(newVal); + isEnabled = (isHPAvailable || isTHPAvailable) && newVal; + } + + bool isRequested() const { + return requestedMode.ready() ? requestedMode.get() : false; + } + + void reset() { + pageSize = needActualStatusPrint = 0; + isEnabled = isHPAvailable = isTHPAvailable = false; + } + + // If memory mapping size is a multiple of huge page size, some OS kernels + // can use huge pages transparently. Use this when huge pages are requested. + size_t getGranularity() const { + if (requestedMode.ready()) + return requestedMode.get() ? pageSize : 0; + else + return HUGE_PAGE_SIZE; // the mode is not yet known; assume typical 2MB huge pages + } + + void printStatus() { + doPrintStatus(requestedMode.get(), "requested"); + if (requestedMode.get()) { // report actual status iff requested + if (pageSize) + FencedStore(needActualStatusPrint, 1); + else + doPrintStatus(/*state=*/false, "available"); + } + } +}; + +class AllLargeBlocksList { + MallocMutex largeObjLock; + LargeMemoryBlock *loHead; +public: + void add(LargeMemoryBlock *lmb); + void remove(LargeMemoryBlock *lmb); + template<bool poolDestroy> void releaseAll(Backend *backend); +}; + +struct ExtMemoryPool { + Backend backend; + LargeObjectCache loc; + AllLocalCaches allLocalCaches; + OrphanedBlocks orphanedBlocks; + + intptr_t poolId; + // To find all large objects. Used during user pool destruction, + // to release all backreferences in large blocks (slab blocks do not have them). + AllLargeBlocksList lmbList; + // Callbacks to be used instead of MapMemory/UnmapMemory. + rawAllocType rawAlloc; + rawFreeType rawFree; + size_t granularity; + bool keepAllMemory, + delayRegsReleasing, + // TODO: implements fixedPool with calling rawFree on destruction + fixedPool; + TLSKey tlsPointerKey; // per-pool TLS key + + bool init(intptr_t poolId, rawAllocType rawAlloc, rawFreeType rawFree, + size_t granularity, bool keepAllMemory, bool fixedPool); + bool initTLS(); + + // i.e., not system default pool for scalable_malloc/scalable_free + bool userPool() const { return rawAlloc; } + + // true if something has been released + bool softCachesCleanup(); + bool releaseAllLocalCaches(); + bool hardCachesCleanup(); + void *remap(void *ptr, size_t oldSize, size_t newSize, size_t alignment); + bool reset() { + loc.reset(); + allLocalCaches.reset(); + orphanedBlocks.reset(); + bool ret = tlsPointerKey.destroy(); + backend.reset(); + return ret; + } + bool destroy() { + MALLOC_ASSERT(isPoolValid(), + "Possible double pool_destroy or heap corruption"); + if (!userPool()) { + loc.reset(); + allLocalCaches.reset(); + } + // pthread_key_dtors must be disabled before memory unmapping + // TODO: race-free solution + bool ret = tlsPointerKey.destroy(); + if (rawFree || !userPool()) + ret &= backend.destroy(); + // pool is not valid after this point + granularity = 0; + return ret; + } + void delayRegionsReleasing(bool mode) { delayRegsReleasing = mode; } + inline bool regionsAreReleaseable() const; + + LargeMemoryBlock *mallocLargeObject(MemoryPool *pool, size_t allocationSize); + void freeLargeObject(LargeMemoryBlock *lmb); + void freeLargeObjectList(LargeMemoryBlock *head); + // use granulatity as marker for pool validity + bool isPoolValid() const { return granularity; } +}; + +inline bool Backend::inUserPool() const { return extMemPool->userPool(); } + +struct LargeObjectHdr { + LargeMemoryBlock *memoryBlock; + /* Backreference points to LargeObjectHdr. + Duplicated in LargeMemoryBlock to reuse in subsequent allocations. */ + BackRefIdx backRefIdx; +}; + +struct FreeObject { + FreeObject *next; +}; + + +/******* A helper class to support overriding malloc with scalable_malloc *******/ +#if MALLOC_CHECK_RECURSION + +class RecursiveMallocCallProtector { + // pointer to an automatic data of holding thread + static void *autoObjPtr; + static MallocMutex rmc_mutex; + static pthread_t owner_thread; +/* Under FreeBSD 8.0 1st call to any pthread function including pthread_self + leads to pthread initialization, that causes malloc calls. As 1st usage of + RecursiveMallocCallProtector can be before pthread initialized, pthread calls + can't be used in 1st instance of RecursiveMallocCallProtector. + RecursiveMallocCallProtector is used 1st time in checkInitialization(), + so there is a guarantee that on 2nd usage pthread is initialized. + No such situation observed with other supported OSes. + */ +#if __FreeBSD__ + static bool canUsePthread; +#else + static const bool canUsePthread = true; +#endif +/* + The variable modified in checkInitialization, + so can be read without memory barriers. + */ + static bool mallocRecursionDetected; + + MallocMutex::scoped_lock* lock_acquired; + char scoped_lock_space[sizeof(MallocMutex::scoped_lock)+1]; + + static uintptr_t absDiffPtr(void *x, void *y) { + uintptr_t xi = (uintptr_t)x, yi = (uintptr_t)y; + return xi > yi ? xi - yi : yi - xi; + } +public: + + RecursiveMallocCallProtector() : lock_acquired(NULL) { + lock_acquired = new (scoped_lock_space) MallocMutex::scoped_lock( rmc_mutex ); + if (canUsePthread) + owner_thread = pthread_self(); + autoObjPtr = &scoped_lock_space; + } + ~RecursiveMallocCallProtector() { + if (lock_acquired) { + autoObjPtr = NULL; + lock_acquired->~scoped_lock(); + } + } + static bool sameThreadActive() { + if (!autoObjPtr) // fast path + return false; + // Some thread has an active recursive call protector; check if the current one. + // Exact pthread_self based test + if (canUsePthread) { + if (pthread_equal( owner_thread, pthread_self() )) { + mallocRecursionDetected = true; + return true; + } else + return false; + } + // inexact stack size based test + const uintptr_t threadStackSz = 2*1024*1024; + int dummy; + return absDiffPtr(autoObjPtr, &dummy)<threadStackSz; + } + static bool noRecursion(); +/* The function is called on 1st scalable_malloc call to check if malloc calls + scalable_malloc (nested call must set mallocRecursionDetected). */ + static void detectNaiveOverload() { + if (!malloc_proxy) { +#if __FreeBSD__ +/* If !canUsePthread, we can't call pthread_self() before, but now pthread + is already on, so can do it. */ + if (!canUsePthread) { + canUsePthread = true; + owner_thread = pthread_self(); + } +#endif + free(malloc(1)); + } + } +}; + +#else + +class RecursiveMallocCallProtector { +public: + RecursiveMallocCallProtector() {} + ~RecursiveMallocCallProtector() {} +}; + +#endif /* MALLOC_CHECK_RECURSION */ + +bool isMallocInitializedExt(); + +unsigned int getThreadId(); + +bool initBackRefMaster(Backend *backend); +void destroyBackRefMaster(Backend *backend); +void removeBackRef(BackRefIdx backRefIdx); +void setBackRef(BackRefIdx backRefIdx, void *newPtr); +void *getBackRef(BackRefIdx backRefIdx); + +} // namespace internal +} // namespace rml + +#endif // __TBB_tbbmalloc_internal_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h new file mode 100644 index 00000000..0f0803c3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/tbbmalloc_internal_api.h @@ -0,0 +1,40 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_tbbmalloc_internal_api_H +#define __TBB_tbbmalloc_internal_api_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef enum { + /* Tune usage of source included allocator. Selected value is large enough + to not intercept with constants from AllocationModeParam. */ + TBBMALLOC_INTERNAL_SOURCE_INCLUDED = 65536 +} AllocationModeInternalParam; + +void MallocInitializeITT(); +void __TBB_mallocProcessShutdownNotification(bool); +#if _WIN32||_WIN64 +void __TBB_mallocThreadShutdownNotification(); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* __TBB_tbbmalloc_internal_api_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win32-gcc-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win32-gcc-tbbmalloc-export.def new file mode 100644 index 00000000..9c3a2c82 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win32-gcc-tbbmalloc-export.def @@ -0,0 +1,49 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: +scalable_calloc; +scalable_free; +scalable_malloc; +scalable_realloc; +scalable_posix_memalign; +scalable_aligned_malloc; +scalable_aligned_realloc; +scalable_aligned_free; +scalable_msize; +scalable_allocation_mode; +scalable_allocation_command; +__TBB_malloc_safer_free; +__TBB_malloc_safer_realloc; +__TBB_malloc_safer_msize; +__TBB_malloc_safer_aligned_msize; +__TBB_malloc_safer_aligned_realloc; +/* memory pool stuff */ +_ZN3rml10pool_resetEPNS_10MemoryPoolE; +_ZN3rml11pool_createEiPKNS_13MemPoolPolicyE; +_ZN3rml14pool_create_v1EiPKNS_13MemPoolPolicyEPPNS_10MemoryPoolE; +_ZN3rml11pool_mallocEPNS_10MemoryPoolEj; +_ZN3rml12pool_destroyEPNS_10MemoryPoolE; +_ZN3rml9pool_freeEPNS_10MemoryPoolEPv; +_ZN3rml12pool_reallocEPNS_10MemoryPoolEPvj; +_ZN3rml20pool_aligned_reallocEPNS_10MemoryPoolEPvjj; +_ZN3rml19pool_aligned_mallocEPNS_10MemoryPoolEjj; +_ZN3rml13pool_identifyEPv; +_ZN3rml10pool_msizeEPNS_10MemoryPoolEPv; + +local:*; +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win32-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win32-tbbmalloc-export.def new file mode 100644 index 00000000..29fd4ac7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win32-tbbmalloc-export.def @@ -0,0 +1,45 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +EXPORTS + +; frontend.cpp +scalable_calloc +scalable_free +scalable_malloc +scalable_realloc +scalable_posix_memalign +scalable_aligned_malloc +scalable_aligned_realloc +scalable_aligned_free +scalable_msize +scalable_allocation_mode +scalable_allocation_command +__TBB_malloc_safer_free +__TBB_malloc_safer_realloc +__TBB_malloc_safer_msize +__TBB_malloc_safer_aligned_msize +__TBB_malloc_safer_aligned_realloc +?pool_create@rml@@YAPAVMemoryPool@1@HPBUMemPoolPolicy@1@@Z +?pool_create_v1@rml@@YA?AW4MemPoolError@1@HPBUMemPoolPolicy@1@PAPAVMemoryPool@1@@Z +?pool_destroy@rml@@YA_NPAVMemoryPool@1@@Z +?pool_malloc@rml@@YAPAXPAVMemoryPool@1@I@Z +?pool_free@rml@@YA_NPAVMemoryPool@1@PAX@Z +?pool_reset@rml@@YA_NPAVMemoryPool@1@@Z +?pool_realloc@rml@@YAPAXPAVMemoryPool@1@PAXI@Z +?pool_aligned_realloc@rml@@YAPAXPAVMemoryPool@1@PAXII@Z +?pool_aligned_malloc@rml@@YAPAXPAVMemoryPool@1@II@Z +?pool_identify@rml@@YAPAVMemoryPool@1@PAX@Z +?pool_msize@rml@@YAIPAVMemoryPool@1@PAX@Z + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win64-gcc-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win64-gcc-tbbmalloc-export.def new file mode 100644 index 00000000..caf162d3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win64-gcc-tbbmalloc-export.def @@ -0,0 +1,49 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +{ +global: +scalable_calloc; +scalable_free; +scalable_malloc; +scalable_realloc; +scalable_posix_memalign; +scalable_aligned_malloc; +scalable_aligned_realloc; +scalable_aligned_free; +scalable_msize; +scalable_allocation_mode; +scalable_allocation_command; +__TBB_malloc_safer_free; +__TBB_malloc_safer_realloc; +__TBB_malloc_safer_msize; +__TBB_malloc_safer_aligned_msize; +__TBB_malloc_safer_aligned_realloc; +/* memory pool stuff */ +_ZN3rml10pool_resetEPNS_10MemoryPoolE; +_ZN3rml11pool_createExPKNS_13MemPoolPolicyE; +_ZN3rml14pool_create_v1ExPKNS_13MemPoolPolicyEPPNS_10MemoryPoolE; +_ZN3rml11pool_mallocEPNS_10MemoryPoolEy; +_ZN3rml12pool_destroyEPNS_10MemoryPoolE; +_ZN3rml9pool_freeEPNS_10MemoryPoolEPv; +_ZN3rml12pool_reallocEPNS_10MemoryPoolEPvy; +_ZN3rml20pool_aligned_reallocEPNS_10MemoryPoolEPvyy; +_ZN3rml19pool_aligned_mallocEPNS_10MemoryPoolEyy; +_ZN3rml13pool_identifyEPv; +_ZN3rml10pool_msizeEPNS_10MemoryPoolEPv; + +local:*; +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win64-tbbmalloc-export.def b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win64-tbbmalloc-export.def new file mode 100644 index 00000000..aba13bdc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbmalloc/win64-tbbmalloc-export.def @@ -0,0 +1,46 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +EXPORTS + +; frontend.cpp +scalable_calloc +scalable_free +scalable_malloc +scalable_realloc +scalable_posix_memalign +scalable_aligned_malloc +scalable_aligned_realloc +scalable_aligned_free +scalable_msize +scalable_allocation_mode +scalable_allocation_command +__TBB_malloc_safer_free +__TBB_malloc_safer_realloc +__TBB_malloc_safer_msize +__TBB_malloc_safer_aligned_msize +__TBB_malloc_safer_aligned_realloc +; memory pool stuff +?pool_create@rml@@YAPEAVMemoryPool@1@_JPEBUMemPoolPolicy@1@@Z +?pool_create_v1@rml@@YA?AW4MemPoolError@1@_JPEBUMemPoolPolicy@1@PEAPEAVMemoryPool@1@@Z +?pool_destroy@rml@@YA_NPEAVMemoryPool@1@@Z +?pool_malloc@rml@@YAPEAXPEAVMemoryPool@1@_K@Z +?pool_free@rml@@YA_NPEAVMemoryPool@1@PEAX@Z +?pool_reset@rml@@YA_NPEAVMemoryPool@1@@Z +?pool_realloc@rml@@YAPEAXPEAVMemoryPool@1@PEAX_K@Z +?pool_aligned_realloc@rml@@YAPEAXPEAVMemoryPool@1@PEAX_K2@Z +?pool_aligned_malloc@rml@@YAPEAXPEAVMemoryPool@1@_K1@Z +?pool_identify@rml@@YAPEAVMemoryPool@1@PEAX@Z +?pool_msize@rml@@YA_KPEAVMemoryPool@1@PEAX@Z + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbproxy/tbbproxy-windows.asm b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbproxy/tbbproxy-windows.asm new file mode 100644 index 00000000..a751a74d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbproxy/tbbproxy-windows.asm @@ -0,0 +1,107 @@ +; Copyright (c) 2005-2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +// __TBB_STRING macro defined in "tbb_stddef.h". However, we cannot include "tbb_stddef.h" +// because it contains a lot of C/C++ definitions. So, we have to define __TBB_STRING here: +#define __TBB_STRING_AUX( x ) #x +#define __TBB_STRING( x ) __TBB_STRING_AUX( x ) + +// Eliminate difference between IA-32 and Intel 64: AWORD is a type of pointer, LANG is language +// specification for extern directive. +#ifdef ARCH_ia32 + #define AWORD dword + #define LANG c +#else + #define AWORD qword + #define LANG +#endif + +#ifdef ARCH_ia32 + // These directives are required for IA32 architecture only. + .686 + .model flat, syscall +#endif + +/* + Symbol names. +*/ + +// Note: masm for IA-32 does not like symbols defined as "name:" in data sections, +// so we have to define symbols with "name label type" directive instead. + +fname macro sym:req + align sizeof AWORD + Ln_&sym& label byte + byte "&sym&", 0 +endm + +.const // Symbol names are constants. +#define __TBB_SYMBOL( sym ) fname sym +#include __TBB_STRING( __TBB_LST ) + +/* + Symbol descriptors. +*/ + +extern LANG __tbb_internal_runtime_loader_stub : AWORD + +fsymbol macro sym:req + Ls_&sym& label AWORD + AWORD __tbb_internal_runtime_loader_stub + AWORD Ln_&sym& + dword sizeof AWORD + dword 1 +endm + +.data +align sizeof AWORD +public LANG __tbb_internal_runtime_loader_symbols +__tbb_internal_runtime_loader_symbols label AWORD +#define __TBB_SYMBOL( sym ) fsymbol sym +#include __TBB_STRING( __TBB_LST ) +AWORD 0, 0 // Terminator of the __tbb_internal_runtime_loader_symbols array. +dword 0, 0 + +/* + Generate functions. +*/ + +// Helper assembler macro to handle different naming conventions on IA-32 and Intel 64: +// IA-32: C++ names preserved, C names require leading underscore. +// Intel 64: All names preserved. +mangle macro name:req + #ifdef ARCH_ia32 + if @instr( 1, name, <?> ) + exitm @catstr( name ) + else + exitm @catstr( <_>, name ) + endif + #else + exitm @catstr( name ) + #endif +endm + +function macro sym:req + mangle( sym ) proc + jmp AWORD ptr Ls_&sym& + mangle( sym ) endp +endm + +.code +#define __TBB_SYMBOL( sym ) function sym +#include __TBB_STRING( __TBB_LST ) + +end + +// end of file // diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbproxy/tbbproxy.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbproxy/tbbproxy.cpp new file mode 100644 index 00000000..8d3b4c9d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/tbbproxy/tbbproxy.cpp @@ -0,0 +1,608 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" +#if !__TBB_WIN8UI_SUPPORT +#define TBB_PREVIEW_RUNTIME_LOADER 1 +#include "tbb/runtime_loader.h" +#include "tbb/tbb_stddef.h" +#include "tbb_environment.h" + +// C standard headers. +#include <cctype> // isspace +#include <cstdarg> // va_list, etc. +#include <cstdio> // fprintf, stderr, etc. +#include <cstdlib> // malloc, free, abort. +#include <cstring> // strlen, etc. + +// C++ standard headers. +#include <typeinfo> + +// OS-specific includes. +#if _WIN32 || _WIN64 + #include <windows.h> + #define snprintf _snprintf + #undef max +#else + #include <dlfcn.h> // dlopen, dlsym, dlclose, dlerror. +#endif + +#if TBB_USE_ASSERT + // We cannot use __TBB_ASSERT as it is because it calls a function from tbb library which may + // be not yet loaded. Redefine __TBB_ASSERT not to call tbb functions. + #undef __TBB_ASSERT + #define __TBB_ASSERT( cond, msg ) { \ + if ( ! (cond) ) { \ + say( "%s:%d: Assertion failed: %s.", __FILE__, __LINE__, (msg) ); \ + } /* if */ \ + /* TODO: abort? */ \ + } +#endif + +// Declare here, define at the bottom. +extern "C" int __tbb_internal_runtime_loader_stub(); + +namespace tbb { + +namespace interface6 { + +namespace internal { + +namespace runtime_loader { + + +/* + ------------------------------------------------------------------------------------------------ + User interaction utilities. + ------------------------------------------------------------------------------------------------ +*/ + + +// Print message to stderr. Do not call it directly, use say() or tell() instead. +static void _say( char const * format, va_list args ) { + /* + On 64-bit Linux* OS, vsnprintf() modifies args argument, + so vsnprintf() crashes if it is called for the second time with the same args. + To prevent the crash, we have to pass a fresh intact copy of args to vsnprintf() each time. + + On Windows* OS, unfortunately, standard va_copy() macro is not available. However, it + seems vsnprintf() does not modify args argument. + */ + #if ! ( _WIN32 || _WIN64 ) + va_list _args; + __va_copy( _args, args ); // Make copy of args. + #define args _args // Substitute args with its copy, _args. + #endif + int len = vsnprintf( NULL, 0, format, args ); + #if ! ( _WIN32 || _WIN64 ) + #undef args // Remove substitution. + va_end( _args ); + #endif + char * buf = reinterpret_cast< char * >( malloc( len + 1 ) ); + if ( buf != NULL ) { + vsnprintf( buf, len + 1, format, args ); + fprintf( stderr, "TBB: %s\n", buf ); + free( buf ); + } else { + fprintf( stderr, "TBB: Not enough memory for message: %s\n", format ); + } +} // _say + + +// Debug/test/troubleshooting printing controlled by TBB_VERSION environment variable. +// To enable printing, the variable must be set and not empty. +// Do not call it directly, use tell() instead. +static void _tell( char const * format, va_list args ) { + if ( tbb::internal::GetBoolEnvironmentVariable("TBB_VERSION") ) { + _say( format, args ); + } // if +} // _tell + + +// Print message to stderr unconditionally. +static void say( char const * format, ... ) { + va_list args; + va_start( args, format ); + _say( format, args ); + va_end( args ); +} // say + + +// Debug/test/troubleshooting printing controlled by TBB_VERSION environment variable. +// To enable printing, the variable must be set and not empty. +static void tell( char const * format, ... ) { + va_list args; + va_start( args, format ); + _tell( format, args ); + va_end( args ); +} // tell + + +// Error reporting utility. Behavior depends on mode. +static tbb::runtime_loader::error_code error( tbb::runtime_loader::error_mode mode, tbb::runtime_loader::error_code err, char const * format, ... ) { + va_list args; + va_start( args, format ); + if ( mode == tbb::runtime_loader::em_abort ) { + // In em_abort mode error message printed unconditionally. + _say( format, args ); + } else { + // In other modes printing depends on TBB_VERSION environment variable. + _tell( format, args ); + } // if + va_end( args ); + switch ( mode ) { + case tbb::runtime_loader::em_abort : { + say( "Aborting..." ); + #if TBB_USE_DEBUG && ( _WIN32 || _WIN64 ) + DebugBreak(); + #endif + abort(); + } break; + case tbb::runtime_loader::em_throw : { + throw err; + } break; + case tbb::runtime_loader::em_status : { + // Do nothing. + } break; + } // switch + return err; +} // error + + +/* + ------------------------------------------------------------------------------------------------ + General-purpose string manipulation utilities. + ------------------------------------------------------------------------------------------------ +*/ + + +// Delete character ch from string str in-place. +static void strip( char * str, char ch ) { + int in = 0; // Input character index. + int out = 0; // Output character index. + for ( ; ; ) { + if ( str[ in ] != ch ) { + str[ out ] = str[ in ]; + ++ out; + } // if + if ( str[ in ] == 0 ) { + break; + } // if + ++ in; + } // forever +} // func strip + + +// Strip trailing whitespaces in-place. +static void trim( char * str ) { + size_t len = strlen( str ); + while ( len > 0 && isspace( str[ len - 1 ] ) ) { + -- len; + } // while + str[ len ] = 0; +} // func trim + + +#if _WIN32 || _WIN64 + // "When specifying a path, be sure to use backslashes (\), not forward slashes (/)." + // (see http://msdn.microsoft.com/en-us/library/ms886736.aspx). + const char proper_slash = '\\'; + inline char char_or_slash( char c ) { return c=='/'? '\\': c; } +#else + const char proper_slash = '/'; + inline char char_or_slash( char c ) { return c; } +#endif + +// Concatenate name of directory and name of file. +void cat_file( char const * dir, char const * file, char * buffer, size_t len ) { + size_t i = 0; + // Copy directory name + for( ; i<len && *dir; ++i, ++dir ) { + buffer[i] = char_or_slash(*dir); + } + // Append trailing slash if missed. + if( i>0 && i<len && buffer[i-1]!=proper_slash ) { + buffer[i++] = proper_slash; + } + // Copy file name + __TBB_ASSERT( char_or_slash(*file)!=proper_slash, "File name starts with a slash" ); + for( ; i<len && *file; ++i, ++file ) { + buffer[i] = *file; + } + // Append null terminator + buffer[ i<len? i: len-1 ] = '\0'; +} // cat_file + + +/* + ------------------------------------------------------------------------------------------------ + Windows implementation of dlopen, dlclose, dlsym, dlerror. + ------------------------------------------------------------------------------------------------ +*/ + + +#if _WIN32 || _WIN64 + + // Implement Unix-like interface (dlopen, dlclose, dlsym, dlerror) via Win32 API functions. + + // Type of dlopen result. + typedef HMODULE handle_t; + + enum rtld_flags_t { + RTLD_NOW, + RTLD_GLOBAL + }; // enum rtld_flags_t + + // Unix-like dlopen(). + static handle_t dlopen( char const * name, rtld_flags_t ) { + return LoadLibrary( name ); + } // dlopen + + // Unix-like dlsym(). + static void * dlsym( handle_t lib, char const * sym ) { + return (void*)GetProcAddress( lib, sym ); + } // dlsym + + // Unix-like dlclose(). + static int dlclose( handle_t lib ) { + return ! FreeLibrary( lib ); + } // dlclose + + // The function mimics Unix dlerror() function. + // Note: Not thread-safe due to statically allocated buffer. + static char * dlerror() { + + static char buffer[ 2048 ]; // Note: statically allocated buffer. + + DWORD err = GetLastError(); + if ( err == ERROR_SUCCESS ) { + return NULL; + } // if + + DWORD rc; + rc = + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err, + MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language. + reinterpret_cast< LPTSTR >( & buffer ), + sizeof( buffer ), + NULL + ); + if ( rc == 0 ) { + // FormatMessage() failed to format system error message. Buffer to short or another issue. + snprintf( buffer, sizeof( buffer ), "System error %u.", err ); + } else { + /* + FormatMessage() returns Windows-style end-of-lines, "\r\n". When string is printed, + printf() also replaces all the occurrences of "\n" with "\r\n" (again!), so sequences + like "\r\r\r\n" appear in output. It is not too good. Stripping all "\r" normalizes + string and returns it to canonical form, so printf() will produce correct end-of-line + sequences. + */ + strip( buffer, '\r' ); // Delete carriage returns if any. + trim( buffer ); // Delete trailing newlines and spaces. + } // if + + return buffer; + + } // dlerror + +#else + + // Type of dlopen() result. + typedef void * handle_t; + +#endif + + +/* + ------------------------------------------------------------------------------------------------ + Runtime loader stuff. + ------------------------------------------------------------------------------------------------ +*/ + + +// Descriptor table declaration. It is defined in assembler file. +enum symbol_type_t { + st_object = 0, + st_function = 1 +}; // enum symbol_type_t +struct symbol_t { + void * addr; + char const * name; + int size; + symbol_type_t type; +}; // symbol_t +extern "C" symbol_t __tbb_internal_runtime_loader_symbols[]; + +// Hooks for internal use (e. g. for testing). +tbb::runtime_loader::error_mode stub_mode = tbb::runtime_loader::em_abort; + +static char const * tbb_dll_name = __TBB_STRING(__TBB_DLL_NAME); // Name of TBB library. +static handle_t handle = NULL; // Handle of loaded TBB library or NULL. +static int version = 0; // Version of the loaded library. +static int counter = 0; // Number of runtime_loader objects using the loaded library. + +#define ANOTHER_RTL "probably multiple runtime_loader objects work in parallel" + + +// One attempt to load library (dll_name can be a full path or just a file name). +static tbb::runtime_loader::error_code _load( char const * dll_name, int min_ver, int max_ver ) { + + tbb::runtime_loader::error_mode mode = tbb::runtime_loader::em_status; + tbb::runtime_loader::error_code code = tbb::runtime_loader::ec_ok; + + /* + If these variables declared at the first usage, Intel(R) C++ Compiler may issue warning(s): + transfer of control [goto error] bypasses initialization of: ... + Declaring variables at the beginning of the function eliminates warnings. + */ + typedef int (*int_func_t)( void ); + char const * get_ver_name = "TBB_runtime_interface_version"; // Name of function. + int_func_t get_ver_func = NULL; // Pointer to function. + handle_t _handle = NULL; + int _version = 0; + int total = 0; + int not_found = 0; + + // This function should be called iff there is no loaded library. + __TBB_ASSERT( handle == NULL, "Handle is invalid; " ANOTHER_RTL ); + __TBB_ASSERT( version == 0, "Version is invalid; " ANOTHER_RTL ); + __TBB_ASSERT( counter == 0, "Counter is invalid; " ANOTHER_RTL ); + + tell( "Loading \"%s\"...", dll_name ); + + // First load the library. + _handle = dlopen( dll_name, RTLD_NOW ); + if ( _handle == NULL ) { + const char * msg = dlerror(); + code = error( mode, tbb::runtime_loader::ec_no_lib, "Loading \"%s\" failed; system error: %s", dll_name, msg ); + goto error; + } // if + + // Then try to find out its version. + /* + g++ 3.4 issues error: + ISO C++ forbids casting between pointer-to-function and pointer-to-object + on reinterpret_cast<>. Thus, we have no choice but using C-style type cast. + */ + get_ver_func = (int_func_t) dlsym( _handle, get_ver_name ); + if ( get_ver_func == NULL ) { + code = error( mode, tbb::runtime_loader::ec_bad_lib, "Symbol \"%s\" not found; library rejected.", get_ver_name ); + goto error; + } // if + _version = get_ver_func(); + if ( ! ( min_ver <= _version && _version <= max_ver ) ) { + code = error( mode, tbb::runtime_loader::ec_bad_ver, "Version %d is out of requested range; library rejected.", _version ); + goto error; + } // if + + // Library is suitable. Mark it as loaded. + handle = _handle; + version = _version; + counter += 1; + __TBB_ASSERT( counter == 1, "Counter is invalid; " ANOTHER_RTL ); + + // Now search for all known symbols. + for ( int i = 0; __tbb_internal_runtime_loader_symbols[ i ].name != NULL; ++ i ) { + symbol_t & symbol = __tbb_internal_runtime_loader_symbols[ i ]; + // Verify symbol descriptor. + __TBB_ASSERT( symbol.type == st_object || symbol.type == st_function, "Invalid symbol type" ); + #if _WIN32 || _WIN64 + __TBB_ASSERT( symbol.type == st_function, "Should not be symbols of object type on Windows" ); + #endif + if ( symbol.type == st_object ) { + __TBB_ASSERT( symbol.addr != NULL, "Object address invalid" ); + __TBB_ASSERT( symbol.size > 0, "Symbol size must be > 0" ); + __TBB_ASSERT( symbol.size <= 0x1000, "Symbol size too big" ); + } else { // Function + // __TBB_ASSERT( symbol.addr == reinterpret_cast< void * >( & stub ), "Invalid symbol address" ); + __TBB_ASSERT( symbol.size == sizeof( void * ), "Invalid symbol size" ); + } // if + void * addr = dlsym( _handle, symbol.name ); + if ( addr != NULL ) { + if ( symbol.type == st_object ) { + if ( strncmp( symbol.name, "_ZTS", 4 ) == 0 ) { + // If object name begins with "_ZTS", it is a string, mangled type name. + // Its value must equal to name of symbol without "_ZTS" prefix. + char const * name = static_cast< char const * >( addr ); + __TBB_ASSERT( strlen( name ) + 1 == size_t( symbol.size ), "Unexpected size of typeinfo name" ); + __TBB_ASSERT( strcmp( symbol.name + 4, name ) == 0, "Unexpected content of typeinfo name" ); + strncpy( reinterpret_cast< char * >( symbol.addr ), name, symbol.size ); + reinterpret_cast< char * >( symbol.addr )[ symbol.size - 1 ] = 0; + } else { + #if TBB_USE_ASSERT + // If object name begins with "_ZTI", it is an object of std::type_info class. + // Its protected value must equal to name of symbol without "_ZTI" prefix. + if ( strncmp( symbol.name, "_ZTI", 4 ) == 0 ) { + std::type_info const * info = static_cast< std::type_info const * >( addr ); + __TBB_ASSERT( size_t( symbol.size ) >= sizeof( std::type_info ), "typeinfo size is too small" ); + // std::type_info::name is not a virtual method, it is safe to call it. + __TBB_ASSERT( strcmp( symbol.name + 4, info->name() ) == 0, "Unexpected content of typeinfo" ); + } // if + #endif + // Copy object content from libtbb into runtime_loader. + memcpy( symbol.addr, addr, symbol.size ); + }; // if + } else { // Function + symbol.addr = addr; + } // if + } else { + char const * msg = dlerror(); + tell( "Symbol \"%s\" not found; system error: %s", symbol.name, msg ); + ++ not_found; + } // if + ++ total; + } // for i + + if ( not_found > 0 ) { + tell( "%d of %d symbols not found.", not_found, total ); + } // if + + tell( "The library successfully loaded." ); + return code; + + error: + if ( _handle != NULL ) { + int rc = dlclose( _handle ); + if ( rc != 0 ) { + // Error occurred. + __TBB_ASSERT( rc != 0, "Unexpected error: dlclose() failed" ); + } // if + } // if + _handle = NULL; + return code; + +} // _load + + +static tbb::runtime_loader::error_code load( tbb::runtime_loader::error_mode mode, char const * path[], int min_ver, int max_ver ) { + // Check arguments first. + if ( min_ver <= 0 ) { + return error( mode, tbb::runtime_loader::ec_bad_arg, "tbb::runtime_loader::load(): Invalid value of min_ver argument: %d.", min_ver ); + } // if + if ( max_ver <= 0 ) { + return error( mode, tbb::runtime_loader::ec_bad_arg, "tbb::runtime_loader::load(): Invalid value of max_ver argument: %d.", max_ver ); + } // if + if ( min_ver > max_ver ) { + return error( mode, tbb::runtime_loader::ec_bad_arg, "tbb::runtime_loader::load(): min_ver and max_ver specify empty range: [%d, %d].", min_ver, max_ver ); + } // if + if ( min_ver == max_ver ) { + tell( "Searching for \"%s\" version %d...", tbb_dll_name, min_ver ); + } else if ( max_ver == INT_MAX ) { + tell( "Searching for \"%s\" version %d+...", tbb_dll_name, min_ver ); + } else { + tell( "Searching for \"%s\" version in range [%d, %d]...", tbb_dll_name, min_ver, max_ver ); + } // if + // Then check whether a library already loaded. + if ( handle != NULL ) { + // Library already loaded. Check whether the version is compatible. + __TBB_ASSERT( version > 0, "Version is invalid; " ANOTHER_RTL ); + __TBB_ASSERT( counter > 0, "Counter is invalid; " ANOTHER_RTL ); + if ( min_ver <= version && version <= max_ver ) { + // Version is ok, let us use this library. + tell( "Library version %d is already loaded.", version ); + counter += 1; + return tbb::runtime_loader::ec_ok; + } else { + // Version is not suitable. + return error( mode, tbb::runtime_loader::ec_bad_ver, "Library version %d is already loaded.", version ); + } // if + } // if + // There is no loaded library, try to load it using provided directories. + __TBB_ASSERT( version == 0, "Version is invalid; " ANOTHER_RTL ); + __TBB_ASSERT( counter == 0, "Counter is invalid; " ANOTHER_RTL ); + size_t namelen = strlen(tbb_dll_name); + size_t buflen = 0; + char * buffer = NULL; + for ( int i = 0; path[i] != NULL; ++ i ) { + size_t len = strlen(path[i]) + namelen + 2; // 1 for slash and 1 for null terminator + if( buflen<len ) { + free( buffer ); + buflen = len; + buffer = (char*)malloc( buflen ); + if( !buffer ) + return error( mode, tbb::runtime_loader::ec_no_lib, "Not enough memory." ); + } + cat_file( path[i], tbb_dll_name, buffer, buflen ); + __TBB_ASSERT(strstr(buffer,tbb_dll_name), "Name concatenation error"); + tbb::runtime_loader::error_code ec = _load( buffer, min_ver, max_ver ); + if ( ec == tbb::runtime_loader::ec_ok ) { + return ec; // Success. Exiting... + } // if + } // for i + free( buffer ); + return error( mode, tbb::runtime_loader::ec_no_lib, "No suitable library found." ); +} // load + + + + +// Suppress "defined but not used" compiler warnings. +static void const * dummy[] = { + (void *) & strip, + (void *) & trim, + & dummy, + NULL +}; + + +} // namespace runtime_loader + +} // namespace internal + + +runtime_loader::runtime_loader( error_mode mode ) : + my_mode( mode ), + my_status( ec_ok ), + my_loaded( false ) +{ +} // ctor + + +runtime_loader::runtime_loader( char const * path[], int min_ver, int max_ver, error_mode mode ) : + my_mode( mode ), + my_status( ec_ok ), + my_loaded( false ) +{ + load( path, min_ver, max_ver ); +} // ctor + + +runtime_loader::~runtime_loader() { +} // dtor + + +tbb::runtime_loader::error_code runtime_loader::load( char const * path[], int min_ver, int max_ver ) { + if ( my_loaded ) { + my_status = tbb::interface6::internal::runtime_loader::error( my_mode, ec_bad_call, "tbb::runtime_loader::load(): Library already loaded by this runtime_loader object." ); + } else { + my_status = internal::runtime_loader::load( my_mode, path, min_ver, max_ver ); + if ( my_status == ec_ok ) { + my_loaded = true; + } // if + } // if + return my_status; +} // load + + + + +tbb::runtime_loader::error_code runtime_loader::status() { + return my_status; +} // status + + +} // namespace interface6 + +} // namespace tbb + + +// Stub function replaces all TBB entry points when no library is loaded. +int __tbb_internal_runtime_loader_stub() { + char const * msg = NULL; + if ( tbb::interface6::internal::runtime_loader::handle == NULL ) { + msg = "A function is called while TBB library is not loaded"; + } else { + msg = "A function is called which is not present in loaded TBB library"; + } // if + return tbb::interface6::internal::runtime_loader::error( tbb::interface6::internal::runtime_loader::stub_mode, tbb::runtime_loader::ec_no_lib, msg ); +} // stub + +#endif // !__TBB_WIN8UI_SUPPORT // +// end of file // diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness.h new file mode 100644 index 00000000..9c015775 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness.h @@ -0,0 +1,882 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Declarations for rock-bottom simple test harness. +// Just include this file to use it. +// Every test is presumed to have a command line of the form "test [-v] [MinThreads[:MaxThreads]]" +// The default for MinThreads is 1, for MaxThreads 4. +// The defaults can be overridden by defining macros HARNESS_DEFAULT_MIN_THREADS +// and HARNESS_DEFAULT_MAX_THREADS before including harness.h + +#ifndef tbb_tests_harness_H +#define tbb_tests_harness_H + +#include "tbb/tbb_config.h" +#include "harness_defs.h" + +namespace Harness { + enum TestResult { + Done, + Skipped, + Unknown + }; +} + +//! Entry point to a TBB unit test application +/** It MUST be defined by the test application. + + If HARNESS_NO_PARSE_COMMAND_LINE macro was not explicitly set before including harness.h, + then global variables MinThread, and MaxThread will be available and + initialized when it is called. + + Returns Harness::Done when the tests passed successfully. When the test fail, it must + not return, calling exit(errcode) or abort() instead. When the test is not supported + for the given platform/compiler/etc, it should return Harness::Skipped. + + To provide non-standard variant of main() for the test, define HARNESS_CUSTOM_MAIN + before including harness.h **/ +int TestMain (); + +#if __SUNPRO_CC + #include <stdlib.h> + #include <string.h> + #include <ucontext.h> +#else /* !__SUNPRO_CC */ + #include <cstdlib> + #include <cstring> +#endif /* !__SUNPRO_CC */ +#include <cerrno> +#include <cctype> + +#include <new> + +#if __TBB_MIC_NATIVE + #include "harness_mic.h" +#else + #define HARNESS_EXPORT + #define REPORT_FATAL_ERROR REPORT +#endif /* !__MIC__ */ + +#if _WIN32||_WIN64 + #include "tbb/machine/windows_api.h" + #if _WIN32_WINNT > 0x0501 && _MSC_VER && !_M_ARM + // Suppress "typedef ignored ... when no variable is declared" warning by vc14 + #pragma warning (push) + #pragma warning (disable: 4091) + #include <dbghelp.h> + #pragma warning (pop) + #pragma comment (lib, "dbghelp.lib") + #endif + #if __TBB_WIN8UI_SUPPORT + #include <thread> + #endif + #if _MSC_VER + #include <crtdbg.h> + #endif + #include <process.h> +#else + #include <pthread.h> +#endif + +#if __linux__ + #include <sys/utsname.h> /* for uname */ + #include <errno.h> /* for use in LinuxKernelVersion() */ + #include <features.h> +#endif +// at least GLIBC 2.1 or OSX 10.5 +#if __GLIBC__>2 || ( __GLIBC__==2 && __GLIBC_MINOR__ >= 1) || __APPLE__ + #include <execinfo.h> /*backtrace*/ + #define BACKTRACE_FUNCTION_AVAILABLE 1 +#endif + +namespace Harness { + class NativeMutex { +#if _WIN32||_WIN64 + CRITICAL_SECTION my_critical_section; + public: + NativeMutex() { + InitializeCriticalSectionEx(&my_critical_section, 4000, 0); + } + void lock() { + EnterCriticalSection(&my_critical_section); + } + void unlock() { + LeaveCriticalSection(&my_critical_section); + } + ~NativeMutex() { + DeleteCriticalSection(&my_critical_section); + } +#else + pthread_mutex_t m_mutex; + public: + NativeMutex() { + pthread_mutex_init(&m_mutex, NULL); + } + void lock() { + pthread_mutex_lock(&m_mutex); + } + void unlock() { + pthread_mutex_unlock(&m_mutex); + } + ~NativeMutex() { + pthread_mutex_destroy(&m_mutex); + } +#endif + }; + namespace internal { + static NativeMutex print_stack_mutex; + } +} + +#include "harness_runtime_loader.h" +#include "harness_report.h" + +//! Prints current call stack +void print_call_stack() { + Harness::internal::print_stack_mutex.lock(); + fflush(stdout); fflush(stderr); + #if BACKTRACE_FUNCTION_AVAILABLE + const int sz = 100; // max number of frames to capture + void *buff[sz]; + int n = backtrace(buff, sz); + REPORT("Call stack info (%d):\n", n); + backtrace_symbols_fd(buff, n, fileno(stdout)); + #elif __SUNPRO_CC + REPORT("Call stack info:\n"); + printstack(fileno(stdout)); + #elif _WIN32_WINNT > 0x0501 && _MSC_VER>=1500 && !__TBB_WIN8UI_SUPPORT + const int sz = 62; // XP limitation for number of frames + void *buff[sz]; + int n = CaptureStackBackTrace(0, sz, buff, NULL); + REPORT("Call stack info (%d):\n", n); + static LONG once = 0; + if( !InterlockedExchange(&once, 1) ) + SymInitialize(GetCurrentProcess(), NULL, TRUE); + const int len = 255; // just some reasonable string buffer size + union { SYMBOL_INFO sym; char pad[sizeof(SYMBOL_INFO)+len]; }; + sym.MaxNameLen = len; + sym.SizeOfStruct = sizeof( SYMBOL_INFO ); + DWORD64 offset; + for(int i = 1; i < n; i++) { // skip current frame + if(!SymFromAddr( GetCurrentProcess(), DWORD64(buff[i]), &offset, &sym )) { + sym.Address = ULONG64(buff[i]); offset = 0; sym.Name[0] = 0; + } + REPORT("[%d] %016I64X+%04I64X: %s\n", i, sym.Address, offset, sym.Name); //TODO: print module name + } + #endif /*BACKTRACE_FUNCTION_AVAILABLE*/ + Harness::internal::print_stack_mutex.unlock(); +} + +#if !HARNESS_NO_ASSERT + #include <exception> //for set_terminate + #include "harness_assert.h" + #if TEST_USES_TBB + #include <tbb/tbb_stddef.h> /*set_assertion_handler*/ + #endif + + struct InitReporter { + void (*default_terminate_handler)() ; + InitReporter(): default_terminate_handler(NULL) { + #if TEST_USES_TBB + #if TBB_USE_ASSERT + tbb::set_assertion_handler(ReportError); + #endif + ASSERT_WARNING(TBB_INTERFACE_VERSION <= tbb::TBB_runtime_interface_version(), "runtime version mismatch"); + #endif + #if TBB_USE_EXCEPTIONS + default_terminate_handler = std::set_terminate(handle_terminate); + #endif + } + static void handle_terminate(); + }; + static InitReporter InitReportError; + + void InitReporter::handle_terminate(){ + REPORT("std::terminate called.\n"); + print_call_stack(); + if (InitReportError.default_terminate_handler){ + InitReportError.default_terminate_handler(); + } + } + + typedef void (*test_error_extra_t)(void); + static test_error_extra_t ErrorExtraCall; + //! Set additional handler to process failed assertions + void SetHarnessErrorProcessing( test_error_extra_t extra_call ) { + ErrorExtraCall = extra_call; + } + + //! Reports errors issued by failed assertions + void ReportError( const char* filename, int line, const char* expression, const char * message ) { + print_call_stack(); + #if __TBB_ICL_11_1_CODE_GEN_BROKEN + printf("%s:%d, assertion %s: %s\n", filename, line, expression, message ? message : "failed" ); + #else + REPORT_FATAL_ERROR("%s:%d, assertion %s: %s\n", filename, line, expression, message ? message : "failed" ); + #endif + + if( ErrorExtraCall ) + (*ErrorExtraCall)(); + fflush(stdout); fflush(stderr); + #if HARNESS_TERMINATE_ON_ASSERT + TerminateProcess(GetCurrentProcess(), 1); + #elif HARNESS_EXIT_ON_ASSERT + exit(1); + #elif HARNESS_CONTINUE_ON_ASSERT + // continue testing + #elif _MSC_VER && _DEBUG + // aligned with tbb_assert_impl.h behavior + if(1 == _CrtDbgReport(_CRT_ASSERT, filename, line, NULL, "%s\r\n%s", expression, message?message:"")) + _CrtDbgBreak(); + #else + abort(); + #endif /* HARNESS_EXIT_ON_ASSERT */ + } + //! Reports warnings issued by failed warning assertions + void ReportWarning( const char* filename, int line, const char* expression, const char * message ) { + REPORT("Warning: %s:%d, assertion %s: %s\n", filename, line, expression, message ? message : "failed" ); + } + +#else /* !HARNESS_NO_ASSERT */ + + #define ASSERT(p,msg) (Harness::suppress_unused_warning(p), (void)0) + #define ASSERT_WARNING(p,msg) (Harness::suppress_unused_warning(p), (void)0) + +#endif /* !HARNESS_NO_ASSERT */ + +namespace Harness { + //TODO: unify with utility::internal::array_length from examples common utilities + template<typename T, size_t N> + inline size_t array_length(const T(&)[N]) + { + return N; + } + + template<typename T, size_t N> + inline T* end( T(& array)[N]) + { + return array+ array_length(array) ; + } + +} //namespace Harness + +#if TEST_USES_TBB + #include "tbb/blocked_range.h" + + namespace Harness { + template<typename T, size_t N> + tbb::blocked_range<T*> make_blocked_range( T(& array)[N]){ return tbb::blocked_range<T*>(array, array + N);} + } +#endif + +#if !HARNESS_NO_PARSE_COMMAND_LINE + +//! Controls level of commentary printed via printf-like REMARK() macro. +/** If true, makes the test print commentary. If false, test should print "done" and nothing more. */ +static bool Verbose; + +#ifndef HARNESS_DEFAULT_MIN_THREADS + #define HARNESS_DEFAULT_MIN_THREADS 1 +#endif + +//! Minimum number of threads +static int MinThread = HARNESS_DEFAULT_MIN_THREADS; + +#ifndef HARNESS_DEFAULT_MAX_THREADS + #define HARNESS_DEFAULT_MAX_THREADS 4 +#endif + +//! Maximum number of threads +static int MaxThread = HARNESS_DEFAULT_MAX_THREADS; + +//! Parse command line of the form "name [-v] [MinThreads[:MaxThreads]]" +/** Sets Verbose, MinThread, and MaxThread accordingly. + The nthread argument can be a single number or a range of the form m:n. + A single number m is interpreted as if written m:m. + The numbers must be non-negative. + Clients often treat the value 0 as "run sequentially." */ +inline void ParseCommandLine( int argc, char* argv[] ) { + if( !argc ) REPORT("Command line with 0 arguments\n"); + int i = 1; + if( i<argc ) { + if( strncmp( argv[i], "-v", 2 )==0 ) { + Verbose = true; + ++i; + } + } + if( i<argc ) { + char* endptr; + MinThread = strtol( argv[i], &endptr, 0 ); + if( *endptr==':' ) + MaxThread = strtol( endptr+1, &endptr, 0 ); + else if( *endptr=='\0' ) + MaxThread = MinThread; + if( *endptr!='\0' ) { + REPORT_FATAL_ERROR("garbled nthread range\n"); + exit(1); + } + if( MinThread<0 ) { + REPORT_FATAL_ERROR("nthread must be nonnegative\n"); + exit(1); + } + if( MaxThread<MinThread ) { + REPORT_FATAL_ERROR("nthread range is backwards\n"); + exit(1); + } + ++i; + } +#if __TBB_STDARGS_BROKEN + if ( !argc ) + argc = 1; + else { + while ( i < argc && argv[i][0] == 0 ) + ++i; + } +#endif /* __TBB_STDARGS_BROKEN */ + if( i!=argc ) { + REPORT_FATAL_ERROR("Usage: %s [-v] [nthread|minthread:maxthread]\n", argv[0] ); + exit(1); + } +} +#endif /* HARNESS_NO_PARSE_COMMAND_LINE */ + +#if !HARNESS_CUSTOM_MAIN + +#if __TBB_MPI_INTEROP +#undef SEEK_SET +#undef SEEK_CUR +#undef SEEK_END +#include "mpi.h" +#endif + +#if __TBB_MIC_OFFLOAD && __MIC__ +extern "C" int COIProcessProxyFlush(); +#endif + +HARNESS_EXPORT +#if HARNESS_NO_PARSE_COMMAND_LINE +int main() { +#if __TBB_MPI_INTEROP + MPI_Init(NULL,NULL); +#endif +#else +int main(int argc, char* argv[]) { + ParseCommandLine( argc, argv ); +#if __TBB_MPI_INTEROP + MPI_Init(&argc,&argv); +#endif +#endif +#if HARNESS_SKIP_TEST + REPORT( "skip\n" ); + return 0; +#else +#if __TBB_MPI_INTEROP + // Simple TBB/MPI interoperability harness for most of tests + // Worker processes send blocking messages to the master process about their rank and group size + // Master process receives this info and print it in verbose mode + int rank, size, myrank; + MPI_Status status; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&myrank); + if (myrank == 0) { +#if !HARNESS_NO_PARSE_COMMAND_LINE + REMARK("Hello mpi world. I am %d of %d\n", myrank, size); +#endif + for ( int i = 1; i < size; i++ ) { + MPI_Recv (&rank, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &status); + MPI_Recv (&size, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &status); +#if !HARNESS_NO_PARSE_COMMAND_LINE + REMARK("Hello mpi world. I am %d of %d\n", rank, size); +#endif + } + } else { + MPI_Send (&myrank, 1, MPI_INT, 0, 1, MPI_COMM_WORLD); + MPI_Send (&size, 1, MPI_INT, 0, 1, MPI_COMM_WORLD); + } +#endif + + int res = Harness::Unknown; +#if __TBB_MIC_OFFLOAD + // "mic:-1" or "mandatory" specifies execution on the target. The runtime + // system chooses the specific target. Execution on the CPU is not allowed. +#if __INTEL_COMPILER < 1400 + #pragma offload target(mic:-1) out(res) +#else + #pragma offload target(mic) out(res) mandatory +#endif +#endif + { + res = TestMain(); +#if __TBB_MIC_OFFLOAD && __MIC__ + // It is recommended not to use the __MIC__ macro directly in the offload block but it is Ok here + // since it does not lead to an unexpected difference between host and target compilation phases. + // We need to flush internal Intel(R) Coprocessor Offload Infrastructure (Intel(R) COI) buffers + // to order output from the offload part before the host part. + // Also it is work-around for the issue with missed output. + COIProcessProxyFlush(); +#endif + } + + ASSERT( res==Harness::Done || res==Harness::Skipped, "Wrong return code by TestMain"); +#if __TBB_MPI_INTEROP + if (myrank == 0) { + REPORT( res==Harness::Done ? "done\n" : "skip\n" ); + } + MPI_Finalize(); +#else + REPORT( res==Harness::Done ? "done\n" : "skip\n" ); +#endif + return 0; +#endif /* HARNESS_SKIP_TEST */ +} + +#endif /* !HARNESS_CUSTOM_MAIN */ + +#if __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT + +//! Base class for types that should not be assigned. +class NoAssign { +public: + void operator=( const NoAssign& ) = delete; + NoAssign( const NoAssign& ) = default; + NoAssign() = default; +}; + +//! Base class for types that should not be copied or assigned. +class NoCopy: NoAssign { +public: + NoCopy( const NoCopy& ) = delete; + NoCopy() = default; +}; + +#else /*__TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT*/ + +//! Base class for prohibiting compiler-generated operator= +class NoAssign { + //! Assignment not allowed + void operator=( const NoAssign& ); +public: + NoAssign() {} // explicitly defined to prevent gratuitous warnings +}; + +//! Base class for prohibiting compiler-generated copy constructor or operator= +class NoCopy: NoAssign { + //! Copy construction not allowed + NoCopy( const NoCopy& ); +public: + NoCopy() {} +}; + +#endif /*__TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT*/ + +#if __TBB_CPP11_RVALUE_REF_PRESENT +#include <utility> + +//! Base class for objects which support move ctors +class Movable { +public: + Movable() : alive(true) {} + void Reset() { alive = true; } + Movable(Movable&& other) { + ASSERT(other.alive, "Moving from a dead object"); + alive = true; + other.alive = false; + } + Movable& operator=(Movable&& other) { + ASSERT(alive, "Assignment to a dead object"); + ASSERT(other.alive, "Assignment of a dead object"); + other.alive = false; + return *this; + } + Movable& operator=(const Movable& other) { + ASSERT(alive, "Assignment to a dead object"); + ASSERT(other.alive, "Assignment of a dead object"); + return *this; + } + Movable(const Movable& other) { + ASSERT(other.alive, "Const reference to a dead object"); + alive = true; + } + ~Movable() { alive = false; } + volatile bool alive; +}; + +class MoveOnly : Movable, NoCopy { +public: + MoveOnly() : Movable() {} + MoveOnly(MoveOnly&& other) : Movable( std::move(other) ) {} +}; +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +#if HARNESS_TBBMALLOC_THREAD_SHUTDOWN && __TBB_SOURCE_DIRECTLY_INCLUDED && (_WIN32||_WIN64) +#include "../tbbmalloc/tbbmalloc_internal_api.h" +#endif + +//! For internal use by template function NativeParallelFor +template<typename Index, typename Body> +class NativeParallelForTask: NoCopy { +public: + NativeParallelForTask( Index index_, const Body& body_ ) : + index(index_), + body(body_) + {} + + //! Start task + void start() { +#if _WIN32||_WIN64 + unsigned thread_id; +#if __TBB_WIN8UI_SUPPORT + std::thread* thread_tmp=new std::thread(thread_function, this); + thread_handle = thread_tmp->native_handle(); + thread_id = 0; +#else + unsigned stack_size = 0; +#if HARNESS_THREAD_STACK_SIZE + stack_size = HARNESS_THREAD_STACK_SIZE; +#endif + thread_handle = (HANDLE)_beginthreadex( NULL, stack_size, thread_function, this, 0, &thread_id ); +#endif + ASSERT( thread_handle!=0, "NativeParallelFor: _beginthreadex failed" ); +#else +#if __ICC==1100 + #pragma warning (push) + #pragma warning (disable: 2193) +#endif /* __ICC==1100 */ + // Some machines may have very large hard stack limit. When the test is + // launched by make, the default stack size is set to the hard limit, and + // calls to pthread_create fail with out-of-memory error. + // Therefore we set the stack size explicitly (as for TBB worker threads). +#if !defined(HARNESS_THREAD_STACK_SIZE) +#if __i386__||__i386||__arm__ + const size_t stack_size = 1*MByte; +#elif __x86_64__ + const size_t stack_size = 2*MByte; +#else + const size_t stack_size = 4*MByte; +#endif +#else + const size_t stack_size = HARNESS_THREAD_STACK_SIZE; +#endif /* HARNESS_THREAD_STACK_SIZE */ + pthread_attr_t attr_stack; + int status = pthread_attr_init(&attr_stack); + ASSERT(0==status, "NativeParallelFor: pthread_attr_init failed"); + status = pthread_attr_setstacksize( &attr_stack, stack_size ); + ASSERT(0==status, "NativeParallelFor: pthread_attr_setstacksize failed"); + status = pthread_create(&thread_id, &attr_stack, thread_function, this); + ASSERT(0==status, "NativeParallelFor: pthread_create failed"); + pthread_attr_destroy(&attr_stack); +#if __ICC==1100 + #pragma warning (pop) +#endif +#endif /* _WIN32||_WIN64 */ + } + + //! Wait for task to finish + void wait_to_finish() { +#if _WIN32||_WIN64 + DWORD status = WaitForSingleObjectEx( thread_handle, INFINITE, FALSE ); + ASSERT( status!=WAIT_FAILED, "WaitForSingleObject failed" ); + CloseHandle( thread_handle ); +#else + int status = pthread_join( thread_id, NULL ); + ASSERT( !status, "pthread_join failed" ); +#endif +#if HARNESS_NO_ASSERT + (void)status; +#endif + } + +private: +#if _WIN32||_WIN64 + HANDLE thread_handle; +#else + pthread_t thread_id; +#endif + + //! Range over which task will invoke the body. + const Index index; + + //! Body to invoke over the range. + const Body body; + +#if _WIN32||_WIN64 + static unsigned __stdcall thread_function( void* object ) +#else + static void* thread_function(void* object) +#endif + { + NativeParallelForTask& self = *static_cast<NativeParallelForTask*>(object); + (self.body)(self.index); +#if HARNESS_TBBMALLOC_THREAD_SHUTDOWN && __TBB_SOURCE_DIRECTLY_INCLUDED && (_WIN32||_WIN64) + // in those cases can't release per-thread cache automatically, + // so do it manually + // TODO: investigate less-intrusive way to do it, for example via FLS keys + __TBB_mallocThreadShutdownNotification(); +#endif + return 0; + } +}; + +//! Execute body(i) in parallel for i in the interval [0,n). +/** Each iteration is performed by a separate thread. */ +template<typename Index, typename Body> +void NativeParallelFor( Index n, const Body& body ) { + typedef NativeParallelForTask<Index,Body> task; + + if( n>0 ) { + // Allocate array to hold the tasks + task* array = static_cast<task*>(operator new( n*sizeof(task) )); + + // Construct the tasks + for( Index i=0; i!=n; ++i ) + new( &array[i] ) task(i,body); + + // Start the tasks + for( Index i=0; i!=n; ++i ) + array[i].start(); + + // Wait for the tasks to finish and destroy each one. + for( Index i=n; i; --i ) { + array[i-1].wait_to_finish(); + array[i-1].~task(); + } + + // Deallocate the task array + operator delete(array); + } +} + +//! The function to zero-initialize arrays; useful to avoid warnings +template <typename T> +void zero_fill(void* array, size_t n) { + memset(array, 0, sizeof(T)*n); +} + +#if __SUNPRO_CC && defined(min) +#undef min +#undef max +#endif + +#ifndef min +//! Utility template function returning lesser of the two values. +/** Provided here to avoid including not strict safe <algorithm>.\n + In case operands cause signed/unsigned or size mismatch warnings it is caller's + responsibility to do the appropriate cast before calling the function. **/ +template<typename T1, typename T2> +T1 min ( const T1& val1, const T2& val2 ) { + return val1 < val2 ? val1 : val2; +} +#endif /* !min */ + +#ifndef max +//! Utility template function returning greater of the two values. +/** Provided here to avoid including not strict safe <algorithm>.\n + In case operands cause signed/unsigned or size mismatch warnings it is caller's + responsibility to do the appropriate cast before calling the function. **/ +template<typename T1, typename T2> +T1 max ( const T1& val1, const T2& val2 ) { + return val1 < val2 ? val2 : val1; +} +#endif /* !max */ + +template<typename T> +static inline bool is_aligned(T arg, size_t alignment) { + return 0==((size_t)arg & (alignment-1)); +} + +#if __linux__ +inline unsigned LinuxKernelVersion() +{ + unsigned digit1, digit2, digit3; + struct utsname utsnameBuf; + + if (-1 == uname(&utsnameBuf)) { + REPORT_FATAL_ERROR("Can't call uname: errno %d\n", errno); + exit(1); + } + if (3 != sscanf(utsnameBuf.release, "%u.%u.%u", &digit1, &digit2, &digit3)) { + REPORT_FATAL_ERROR("Unable to parse OS release '%s'\n", utsnameBuf.release); + exit(1); + } + return 1000000*digit1+1000*digit2+digit3; +} +#endif + +namespace Harness { + +#if !HARNESS_NO_ASSERT +//! Base class that asserts that no operations are made with the object after its destruction. +class NoAfterlife { +protected: + enum state_t { + LIVE=0x56781234, + DEAD=0xDEADBEEF + } m_state; + +public: + NoAfterlife() : m_state(LIVE) {} + NoAfterlife( const NoAfterlife& src ) : m_state(LIVE) { + ASSERT( src.IsLive(), "Constructing from the dead source" ); + } + ~NoAfterlife() { + ASSERT( IsLive(), "Repeated destructor call" ); + m_state = DEAD; + } + const NoAfterlife& operator=( const NoAfterlife& src ) { + ASSERT( IsLive(), NULL ); + ASSERT( src.IsLive(), NULL ); + return *this; + } + void AssertLive() const { + ASSERT( IsLive(), "Already dead" ); + } + bool IsLive() const { + return m_state == LIVE; + } +}; // NoAfterlife +#endif /* !HARNESS_NO_ASSERT */ + +#if _WIN32 || _WIN64 + void Sleep ( int ms ) { +#if !__TBB_WIN8UI_SUPPORT + ::Sleep(ms); +#else + std::chrono::milliseconds sleep_time( ms ); + std::this_thread::sleep_for( sleep_time ); +#endif + + } + + typedef DWORD tid_t; + tid_t CurrentTid () { return GetCurrentThreadId(); } + +#else /* !WIN */ + + void Sleep ( int ms ) { + timespec requested = { ms / 1000, (ms % 1000)*1000000 }; + timespec remaining = { 0, 0 }; + nanosleep(&requested, &remaining); + } + + typedef pthread_t tid_t; + tid_t CurrentTid () { return pthread_self(); } +#endif /* !WIN */ + + static const unsigned Primes[] = { + 0x9e3779b1, 0xffe6cc59, 0x2109f6dd, 0x43977ab5, 0xba5703f5, 0xb495a877, 0xe1626741, 0x79695e6b, + 0xbc98c09f, 0xd5bee2b3, 0x287488f9, 0x3af18231, 0x9677cd4d, 0xbe3a6929, 0xadc6a877, 0xdcf0674b, + 0xbe4d6fe9, 0x5f15e201, 0x99afc3fd, 0xf3f16801, 0xe222cfff, 0x24ba5fdb, 0x0620452d, 0x79f149e3, + 0xc8b93f49, 0x972702cd, 0xb07dd827, 0x6c97d5ed, 0x085a3d61, 0x46eb5ea7, 0x3d9910ed, 0x2e687b5b, + 0x29609227, 0x6eb081f1, 0x0954c4e1, 0x9d114db9, 0x542acfa9, 0xb3e6bd7b, 0x0742d917, 0xe9f3ffa7, + 0x54581edb, 0xf2480f45, 0x0bb9288f, 0xef1affc7, 0x85fa0ca7, 0x3ccc14db, 0xe6baf34b, 0x343377f7, + 0x5ca19031, 0xe6d9293b, 0xf0a9f391, 0x5d2e980b, 0xfc411073, 0xc3749363, 0xb892d829, 0x3549366b, + 0x629750ad, 0xb98294e5, 0x892d9483, 0xc235baf3, 0x3d2402a3, 0x6bdef3c9, 0xbec333cd, 0x40c9520f + }; + + class FastRandom { + unsigned x, a; + public: + unsigned short get() { + unsigned short r = (unsigned short)(x >> 16); + x = x*a + 1; + return r; + } + explicit FastRandom( unsigned seed ) { + x = seed; + a = Primes[seed % (sizeof(Primes) / sizeof(Primes[0]))]; + } + }; + template<typename T> + class FastRandomBody { + FastRandom r; + public: + explicit FastRandomBody( unsigned seed ) : r(seed) {} + // Depending on the input type T the result distribution formed from this operator() + // might possess different characteristics than the original one used in FastRandom instance. + T operator()() { return T(r.get()); } + }; + + int SetEnv( const char *envname, const char *envval ) { + ASSERT( envname && envval, "Harness::SetEnv() requires two valid C strings" ); +#if __TBB_WIN8UI_SUPPORT + ASSERT( false, "Harness::SetEnv() should not be called in code built for win8ui" ); + return -1; +#elif !(_MSC_VER || __MINGW32__ || __MINGW64__) + // On POSIX systems use setenv + return setenv(envname, envval, /*overwrite=*/1); +#elif __STDC_SECURE_LIB__>=200411 + // this macro is set in VC & MinGW if secure API functions are present + return _putenv_s(envname, envval); +#else + // If no secure API on Windows, use _putenv + size_t namelen = strlen(envname), valuelen = strlen(envval); + char* buf = new char[namelen+valuelen+2]; + strncpy(buf, envname, namelen); + buf[namelen] = '='; + strncpy(buf+namelen+1, envval, valuelen); + buf[namelen+1+valuelen] = char(0); + int status = _putenv(buf); + delete[] buf; + return status; +#endif + } + + char* GetEnv(const char *envname) { + ASSERT(envname, "Harness::GetEnv() requires a valid C string"); +#if __TBB_WIN8UI_SUPPORT + return NULL; +#else + return std::getenv(envname); +#endif + } + + long GetIntEnv( const char * envname ) { + ASSERT(envname, "Harness::GetIntEnv() requires a valid C string"); +#if !__TBB_WIN8UI_SUPPORT + if( const char* s = std::getenv(envname) ){ + char* end = NULL; + errno = 0; + long value = std::strtol(s, &end, 10); + + // We have exceeded the range, value is negative or string is incovertable + if ( errno == ERANGE || value < 0 || end==s ) + { + return -1; + } + + for ( ; *end != '\0'; end++ ) + { + if ( !std::isspace(*end) ) + return -1; + } + + return value; + } +#endif + return -1; + } + + class DummyBody { + int m_numIters; + public: + explicit DummyBody( int iters ) : m_numIters( iters ) {} + void operator()( int ) const { + for ( volatile int i = 0; i < m_numIters; ++i ) {} + } + }; +} // namespace Harness + +#endif /* tbb_tests_harness_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_allocator.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_allocator.h new file mode 100644 index 00000000..0a5b5f5e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_allocator.h @@ -0,0 +1,869 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Declarations for simple estimate of the memory being used by a program. +// Not yet implemented for macOS*. +// This header is an optional part of the test harness. +// It assumes that "harness_assert.h" has already been included. + +#ifndef tbb_test_harness_allocator_H +#define tbb_test_harness_allocator_H + +#include "harness_defs.h" + +#if __linux__ || __APPLE__ || __sun +#include <unistd.h> +#elif _WIN32 +#include "tbb/machine/windows_api.h" +#endif /* OS specific */ +#include <memory> +#include <new> +#include <cstdio> +#include <stdexcept> +#include <utility> +#include __TBB_STD_SWAP_HEADER + +#include "tbb/atomic.h" +#include "tbb/tbb_allocator.h" + +#if __SUNPRO_CC +using std::printf; +#endif + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (push) +#if defined(_Wp64) + #pragma warning (disable: 4267) +#endif +#if _MSC_VER <= 1600 + #pragma warning (disable: 4355) +#endif +#if _MSC_VER <= 1800 + #pragma warning (disable: 4512) +#endif +#endif + +#if TBB_INTERFACE_VERSION >= 7005 +// Allocator traits were introduced in 4.2 U5 +namespace Harness { +#if __TBB_ALLOCATOR_TRAITS_PRESENT + using std::true_type; + using std::false_type; +#else + using tbb::internal::true_type; + using tbb::internal::false_type; +#endif //__TBB_ALLOCATOR_TRAITS_PRESENT +} +#endif + +template<typename counter_type = size_t> +struct arena_data { + char * const my_buffer; + size_t const my_size; //in bytes + counter_type my_allocated; // in bytes + + template<typename T> + arena_data(T * a_buffer, size_t a_size) __TBB_NOEXCEPT(true) + : my_buffer(reinterpret_cast<char*>(a_buffer)) + , my_size(a_size * sizeof(T)) + { + my_allocated =0; + } +private: + void operator=( const arena_data& ); // NoAssign is not used to avoid dependency on harness.h +}; + +template<typename T, typename pocma = Harness::false_type, typename counter_type = size_t> +struct arena { + typedef arena_data<counter_type> arena_data_t; +private: + arena_data_t * my_data; +public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template<typename U> struct rebind { + typedef arena<U, pocma, counter_type> other; + }; + + typedef pocma propagate_on_container_move_assignment; + + arena(arena_data_t & data) __TBB_NOEXCEPT(true) : my_data(&data) {} + + template<typename U1, typename U2, typename U3> + friend struct arena; + + template<typename U1, typename U2 > + arena(arena<U1, U2, counter_type> const& other) __TBB_NOEXCEPT(true) : my_data(other.my_data) {} + + friend void swap(arena & lhs ,arena & rhs){ + std::swap(lhs.my_data, rhs.my_data); + } + + pointer address(reference x) const {return &x;} + const_pointer address(const_reference x) const {return &x;} + + //! Allocate space for n objects, starting on a cache/sector line. + pointer allocate( size_type n, const void* =0) { + size_t new_size = (my_data->my_allocated += n*sizeof(T)); + ASSERT(my_data->my_allocated <= my_data->my_size,"trying to allocate more than was reserved"); + char* result = &(my_data->my_buffer[new_size - n*sizeof(T)]); + return reinterpret_cast<pointer>(result); + } + + //! Free block of memory that starts on a cache line + void deallocate( pointer p_arg, size_type n) { + char* p = reinterpret_cast<char*>(p_arg); + ASSERT(p >=my_data->my_buffer && p <= my_data->my_buffer + my_data->my_size, "trying to deallocate pointer not from arena ?"); + ASSERT(p + n*sizeof(T) <= my_data->my_buffer + my_data->my_size, "trying to deallocate incorrect number of items?"); + tbb::internal::suppress_unused_warning(p, n); + } + + //! Largest value for which method allocate might succeed. + size_type max_size() const throw() { + return my_data->my_size / sizeof(T); + } + + //! Copy-construct value at location pointed to by p. +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + template<typename U, typename... Args> + void construct(U *p, Args&&... args) + { ::new((void *)p) U(std::forward<Args>(args)...); } +#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#if __TBB_CPP11_RVALUE_REF_PRESENT + void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));} +#endif + void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);} +#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + + //! Destroy value at location pointed to by p. + void destroy( pointer p ) { + p->~value_type(); + // suppress "unreferenced parameter" warnings by MSVC up to and including 2015 + tbb::internal::suppress_unused_warning(p); + } + + friend bool operator==(arena const& lhs, arena const& rhs){ + return lhs.my_data == rhs.my_data; + } + + friend bool operator!=(arena const& lhs, arena const& rhs){ + return !(lhs== rhs); + } +}; + +template <typename count_t = tbb::atomic<size_t> > +struct allocator_counters { + count_t items_allocated; + count_t items_freed; + count_t allocations; + count_t frees; + + friend bool operator==(allocator_counters const & lhs, allocator_counters const & rhs){ + return lhs.items_allocated == rhs.items_allocated + && lhs.items_freed == rhs.items_freed + && lhs.allocations == rhs.allocations + && lhs.frees == rhs.frees + ; + } +}; + +template <typename base_alloc_t, typename count_t = tbb::atomic<size_t> > +class static_counting_allocator : public base_alloc_t +{ +public: + typedef typename base_alloc_t::pointer pointer; + typedef typename base_alloc_t::const_pointer const_pointer; + typedef typename base_alloc_t::reference reference; + typedef typename base_alloc_t::const_reference const_reference; + typedef typename base_alloc_t::value_type value_type; + typedef typename base_alloc_t::size_type size_type; + typedef typename base_alloc_t::difference_type difference_type; + template<typename U> struct rebind { + typedef static_counting_allocator<typename base_alloc_t::template rebind<U>::other,count_t> other; + }; + + typedef allocator_counters<count_t> counters_t; + + static size_t max_items; + static count_t items_allocated; + static count_t items_freed; + static count_t allocations; + static count_t frees; + static bool verbose, throwing; + + static_counting_allocator() throw() { } + + static_counting_allocator(const base_alloc_t& src) throw() + : base_alloc_t(src) { } + + static_counting_allocator(const static_counting_allocator& src) throw() + : base_alloc_t(src) { } + + template<typename U, typename C> + static_counting_allocator(const static_counting_allocator<U, C>& src) throw() + : base_alloc_t(src) { } + + pointer allocate(const size_type n) + { + if(verbose) printf("\t+%d|", int(n)); + if(max_items && items_allocated + n >= max_items) { + if(verbose) printf("items limit hits!"); + if(throwing) + __TBB_THROW( std::bad_alloc() ); + return NULL; + } + pointer p = base_alloc_t::allocate(n, pointer(0)); + allocations++; + items_allocated += n; + return p; + } + + pointer allocate(const size_type n, const void * const) + { return allocate(n); } + + void deallocate(const pointer ptr, const size_type n) + { + if(verbose) printf("\t-%d|", int(n)); + frees++; + items_freed += n; + base_alloc_t::deallocate(ptr, n); + } + + static counters_t counters(){ + counters_t c = {items_allocated, items_freed, allocations, frees} ; + return c; + } + + static void init_counters(bool v = false) { + verbose = v; + if(verbose) printf("\n------------------------------------------- Allocations:\n"); + items_allocated = 0; + items_freed = 0; + allocations = 0; + frees = 0; + max_items = 0; + } + + static void set_limits(size_type max = 0, bool do_throw = true) { + max_items = max; + throwing = do_throw; + } +}; + +template <typename base_alloc_t, typename count_t> +size_t static_counting_allocator<base_alloc_t, count_t>::max_items; +template <typename base_alloc_t, typename count_t> +count_t static_counting_allocator<base_alloc_t, count_t>::items_allocated; +template <typename base_alloc_t, typename count_t> +count_t static_counting_allocator<base_alloc_t, count_t>::items_freed; +template <typename base_alloc_t, typename count_t> +count_t static_counting_allocator<base_alloc_t, count_t>::allocations; +template <typename base_alloc_t, typename count_t> +count_t static_counting_allocator<base_alloc_t, count_t>::frees; +template <typename base_alloc_t, typename count_t> +bool static_counting_allocator<base_alloc_t, count_t>::verbose; +template <typename base_alloc_t, typename count_t> +bool static_counting_allocator<base_alloc_t, count_t>::throwing; + + +template <typename tag, typename count_t = tbb::atomic<size_t> > +class static_shared_counting_allocator_base +{ +public: + typedef allocator_counters<count_t> counters_t; + + static size_t max_items; + static count_t items_allocated; + static count_t items_freed; + static count_t allocations; + static count_t frees; + static bool verbose, throwing; + + static counters_t counters(){ + counters_t c = {items_allocated, items_freed, allocations, frees} ; + return c; + } + + static void init_counters(bool v = false) { + verbose = v; + if(verbose) printf("\n------------------------------------------- Allocations:\n"); + items_allocated = 0; + items_freed = 0; + allocations = 0; + frees = 0; + max_items = 0; + } + + static void set_limits(size_t max = 0, bool do_throw = true) { + max_items = max; + throwing = do_throw; + } +}; + +template <typename tag, typename count_t> +size_t static_shared_counting_allocator_base<tag, count_t>::max_items; + +template <typename tag, typename count_t> +count_t static_shared_counting_allocator_base<tag, count_t>::items_allocated; + +template <typename tag, typename count_t> +count_t static_shared_counting_allocator_base<tag, count_t>::items_freed; + +template <typename tag, typename count_t> +count_t static_shared_counting_allocator_base<tag, count_t>::allocations; + +template <typename tag, typename count_t> +count_t static_shared_counting_allocator_base<tag, count_t>::frees; + +template <typename tag, typename count_t> +bool static_shared_counting_allocator_base<tag, count_t>::verbose; + +template <typename tag, typename count_t> +bool static_shared_counting_allocator_base<tag, count_t>::throwing; + +template <typename tag, typename base_alloc_t, typename count_t = tbb::atomic<size_t> > +class static_shared_counting_allocator : public static_shared_counting_allocator_base<tag, count_t>, public base_alloc_t +{ + typedef static_shared_counting_allocator_base<tag, count_t> base_t; +public: + typedef typename base_alloc_t::pointer pointer; + typedef typename base_alloc_t::const_pointer const_pointer; + typedef typename base_alloc_t::reference reference; + typedef typename base_alloc_t::const_reference const_reference; + typedef typename base_alloc_t::value_type value_type; + typedef typename base_alloc_t::size_type size_type; + typedef typename base_alloc_t::difference_type difference_type; + template<typename U> struct rebind { + typedef static_shared_counting_allocator<tag, typename base_alloc_t::template rebind<U>::other, count_t> other; + }; + + static_shared_counting_allocator() throw() { } + + static_shared_counting_allocator(const base_alloc_t& src) throw() + : base_alloc_t(src) { } + + static_shared_counting_allocator(const static_shared_counting_allocator& src) throw() + : base_alloc_t(src) { } + + template<typename U, typename C> + static_shared_counting_allocator(const static_shared_counting_allocator<tag, U, C>& src) throw() + : base_alloc_t(src) { } + + pointer allocate(const size_type n) + { + if(base_t::verbose) printf("\t+%d|", int(n)); + if(base_t::max_items && base_t::items_allocated + n >= base_t::max_items) { + if(base_t::verbose) printf("items limit hits!"); + if(base_t::throwing) + __TBB_THROW( std::bad_alloc() ); + return NULL; + } + base_t::allocations++; + base_t::items_allocated += n; + return base_alloc_t::allocate(n, pointer(0)); + } + + pointer allocate(const size_type n, const void * const) + { return allocate(n); } + + void deallocate(const pointer ptr, const size_type n) + { + if(base_t::verbose) printf("\t-%d|", int(n)); + base_t::frees++; + base_t::items_freed += n; + base_alloc_t::deallocate(ptr, n); + } +}; + +template <typename base_alloc_t, typename count_t = tbb::atomic<size_t> > +class local_counting_allocator : public base_alloc_t +{ +public: + typedef typename base_alloc_t::pointer pointer; + typedef typename base_alloc_t::const_pointer const_pointer; + typedef typename base_alloc_t::reference reference; + typedef typename base_alloc_t::const_reference const_reference; + typedef typename base_alloc_t::value_type value_type; + typedef typename base_alloc_t::size_type size_type; + typedef typename base_alloc_t::difference_type difference_type; + template<typename U> struct rebind { + typedef local_counting_allocator<typename base_alloc_t::template rebind<U>::other,count_t> other; + }; + + count_t items_allocated; + count_t items_freed; + count_t allocations; + count_t frees; + size_t max_items; + + void set_counters(const count_t & a_items_allocated, const count_t & a_items_freed, const count_t & a_allocations, const count_t & a_frees, const count_t & a_max_items){ + items_allocated = a_items_allocated; + items_freed = a_items_freed; + allocations = a_allocations; + frees = a_frees; + max_items = a_max_items; + } + + template< typename allocator_t> + void set_counters(const allocator_t & a){ + this->set_counters(a.items_allocated, a.items_freed, a.allocations, a.frees, a.max_items); + } + + void clear_counters(){ + count_t zero; + zero = 0; + this->set_counters(zero,zero,zero,zero,zero); + } + + local_counting_allocator() throw() { + this->clear_counters(); + } + + local_counting_allocator(const local_counting_allocator &a) throw() + : base_alloc_t(a) + , items_allocated(a.items_allocated) + , items_freed(a.items_freed) + , allocations(a.allocations) + , frees(a.frees) + , max_items(a.max_items) + { } + + template<typename U, typename C> + local_counting_allocator(const static_counting_allocator<U,C> & a) throw() { + this->set_counters(a); + } + + template<typename U, typename C> + local_counting_allocator(const local_counting_allocator<U,C> &a) throw() + : items_allocated(a.items_allocated) + , items_freed(a.items_freed) + , allocations(a.allocations) + , frees(a.frees) + , max_items(a.max_items) + { } + + bool operator==(const local_counting_allocator &a) const + { return static_cast<const base_alloc_t&>(a) == *this; } + + pointer allocate(const size_type n) + { + if(max_items && items_allocated + n >= max_items) + __TBB_THROW( std::bad_alloc() ); + pointer p = base_alloc_t::allocate(n, pointer(0)); + ++allocations; + items_allocated += n; + return p; + } + + pointer allocate(const size_type n, const void * const) + { return allocate(n); } + + void deallocate(const pointer ptr, const size_type n) + { + ++frees; + items_freed += n; + base_alloc_t::deallocate(ptr, n); + } + + void set_limits(size_type max = 0) { + max_items = max; + } +}; + +template <typename T, template<typename X> class Allocator = std::allocator> +class debug_allocator : public Allocator<T> +{ +public: + typedef Allocator<T> base_allocator_type; + typedef typename base_allocator_type::value_type value_type; + typedef typename base_allocator_type::pointer pointer; + typedef typename base_allocator_type::const_pointer const_pointer; + typedef typename base_allocator_type::reference reference; + typedef typename base_allocator_type::const_reference const_reference; + typedef typename base_allocator_type::size_type size_type; + typedef typename base_allocator_type::difference_type difference_type; + template<typename U> struct rebind { + typedef debug_allocator<U, Allocator> other; + }; + + debug_allocator() throw() { } + debug_allocator(const debug_allocator &a) throw() : base_allocator_type( a ) { } + template<typename U> + debug_allocator(const debug_allocator<U> &a) throw() : base_allocator_type( Allocator<U>( a ) ) { } + + pointer allocate(const size_type n, const void *hint = 0 ) { + pointer ptr = base_allocator_type::allocate( n, hint ); + std::memset( (void*)ptr, 0xE3E3E3E3, n * sizeof(value_type) ); + return ptr; + } +}; + +//! Analogous to std::allocator<void>, as defined in ISO C++ Standard, Section 20.4.1 +/** @ingroup memory_allocation */ +template<template<typename T> class Allocator> +class debug_allocator<void, Allocator> : public Allocator<void> { +public: + typedef Allocator<void> base_allocator_type; + typedef typename base_allocator_type::value_type value_type; + typedef typename base_allocator_type::pointer pointer; + typedef typename base_allocator_type::const_pointer const_pointer; + template<typename U> struct rebind { + typedef debug_allocator<U, Allocator> other; + }; +}; + +template<typename T1, template<typename X1> class B1, typename T2, template<typename X2> class B2> +inline bool operator==( const debug_allocator<T1,B1> &a, const debug_allocator<T2,B2> &b) { + return static_cast< B1<T1> >(a) == static_cast< B2<T2> >(b); +} +template<typename T1, template<typename X1> class B1, typename T2, template<typename X2> class B2> +inline bool operator!=( const debug_allocator<T1,B1> &a, const debug_allocator<T2,B2> &b) { + return static_cast< B1<T1> >(a) != static_cast< B2<T2> >(b); +} + +template <typename T, typename pocma = Harness::false_type, template<typename X> class Allocator = std::allocator> +class stateful_allocator : public Allocator<T> +{ + void* unique_pointer; + + template<typename T1, typename pocma1, template<typename X1> class Allocator1> + friend class stateful_allocator; +public: + typedef Allocator<T> base_allocator_type; + typedef typename base_allocator_type::value_type value_type; + typedef typename base_allocator_type::pointer pointer; + typedef typename base_allocator_type::const_pointer const_pointer; + typedef typename base_allocator_type::reference reference; + typedef typename base_allocator_type::const_reference const_reference; + typedef typename base_allocator_type::size_type size_type; + typedef typename base_allocator_type::difference_type difference_type; + template<typename U> struct rebind { + typedef stateful_allocator<U, pocma, Allocator> other; + }; + typedef pocma propagate_on_container_move_assignment; + + stateful_allocator() throw() : unique_pointer(this) { } + + template<typename U> + stateful_allocator(const stateful_allocator<U, pocma> &a) throw() : base_allocator_type( Allocator<U>( a ) ), unique_pointer(a.uniqe_pointer) { } + + friend bool operator==(stateful_allocator const& lhs, stateful_allocator const& rhs){ + return lhs.unique_pointer == rhs.unique_pointer; + } + + friend bool operator!=(stateful_allocator const& rhs, stateful_allocator const& lhs){ + return !(lhs == rhs); + } + +}; + +template <typename T> +class pmr_stateful_allocator +{ +private: + pmr_stateful_allocator& operator=(const pmr_stateful_allocator&); /* = deleted */ +public: + typedef T value_type; + typedef Harness::false_type propagate_on_container_move_assignment; + typedef Harness::false_type propagate_on_container_copy_assignment; + typedef Harness::false_type propagate_on_container_swap; + +// These types are required in C++03 +#if !__TBB_ALLOCATOR_TRAITS_PRESENT + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template<class U> struct rebind { + typedef pmr_stateful_allocator<U> other; + }; +#endif + + pmr_stateful_allocator() throw() : unique_pointer(this) {} + + pmr_stateful_allocator(const pmr_stateful_allocator &a) : unique_pointer(a.unique_pointer) {} + + template<typename U> + pmr_stateful_allocator(const pmr_stateful_allocator<U> &a) throw() : unique_pointer(a.unique_pointer) {} + + value_type* allocate( size_t n, const void* /*hint*/ = 0 ) { + return static_cast<value_type*>( malloc( n * sizeof(value_type) ) ); + } + + void deallocate( value_type* p, size_t ) { + free( p ); + } + +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + //! Copy-construct value at location pointed to by p. + template<typename U, typename... Args> + void construct(U *p, Args&&... args) + { + ::new((void *)p) U(std::forward<Args>(args)...); + } +#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC +#if __TBB_CPP11_RVALUE_REF_PRESENT + void construct(value_type* p, value_type&& value) { ::new((void*)(p)) value_type(std::move(value)); } +#endif + void construct(value_type* p, const value_type& value) { ::new((void*)(p)) value_type(value); } +#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + + //! Destroy value at location pointed to by p. + void destroy(value_type* p) { + p->~value_type(); + // suppress "unreferenced parameter" warnings by MSVC up to and including 2015 + tbb::internal::suppress_unused_warning(p); + } + + friend bool operator==(pmr_stateful_allocator const& lhs, pmr_stateful_allocator const& rhs){ + return lhs.unique_pointer == rhs.unique_pointer; + } + + friend bool operator!=(pmr_stateful_allocator const& rhs, pmr_stateful_allocator const& lhs){ + return !(lhs == rhs); + } + + void* unique_pointer; +}; + +// C++03 allocator doesn't have to be assignable or swappable, so +// tbb::internal::allocator_traits defines POCCA and POCS as false_type +#if __TBB_ALLOCATOR_TRAITS_PRESENT +#include "tbb/internal/_allocator_traits.h" // Need traits_true/false_type + +template <typename Allocator, typename POCMA = tbb::internal::traits_false_type, + typename POCCA = tbb::internal::traits_false_type, typename POCS = tbb::internal::traits_false_type> +struct propagating_allocator : Allocator { + typedef POCMA propagate_on_container_move_assignment; + typedef POCCA propagate_on_container_copy_assignment; + typedef POCS propagate_on_container_swap; + bool* propagated_on_copy_assignment; + bool* propagated_on_move_assignment; + bool* propagated_on_swap; + bool* selected_on_copy_construction; + + template <typename U> + struct rebind { + typedef propagating_allocator<typename tbb::internal::allocator_rebind<Allocator, U>::type, + POCMA, POCCA, POCS> other; + }; + + propagating_allocator() : propagated_on_copy_assignment(NULL), + propagated_on_move_assignment(NULL), + propagated_on_swap(NULL), + selected_on_copy_construction(NULL) {} + + propagating_allocator(bool& poca, bool& poma, bool& pos, bool& soc) + : propagated_on_copy_assignment(&poca), + propagated_on_move_assignment(&poma), + propagated_on_swap(&pos), + selected_on_copy_construction(&soc) {} + + propagating_allocator(const propagating_allocator& other) + : Allocator(other), + propagated_on_copy_assignment(other.propagated_on_copy_assignment), + propagated_on_move_assignment(other.propagated_on_move_assignment), + propagated_on_swap(other.propagated_on_swap), + selected_on_copy_construction(other.selected_on_copy_construction) {} + + template <typename Allocator2> + propagating_allocator(const propagating_allocator<Allocator2, POCMA, POCCA, POCS>& other) + : Allocator(other), + propagated_on_copy_assignment(other.propagated_on_copy_assignment), + propagated_on_move_assignment(other.propagated_on_move_assignment), + propagated_on_swap(other.propagated_on_swap), + selected_on_copy_construction(other.selected_on_copy_construction) {} + + propagating_allocator& operator=(const propagating_allocator&) { + ASSERT(POCCA::value, "Allocator should not copy assign if pocca is false"); + if (propagated_on_copy_assignment) + *propagated_on_copy_assignment = true; + return *this; + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + propagating_allocator& operator=(propagating_allocator&&) { + ASSERT(POCMA::value, "Allocator should not move assign if pocma is false"); + if (propagated_on_move_assignment) + *propagated_on_move_assignment = true; + return *this; + } +#endif + + propagating_allocator select_on_container_copy_construction() const { + if (selected_on_copy_construction) + *selected_on_copy_construction = true; + return *this; + } +}; + +namespace propagating_allocators { +typedef tbb::tbb_allocator<int> base_allocator; +typedef tbb::internal::traits_true_type true_type; +typedef tbb::internal::traits_false_type false_type; + +typedef propagating_allocator<base_allocator, /*POCMA=*/true_type, /*POCCA=*/true_type, + /*POCS=*/true_type> always_propagating_allocator; +typedef propagating_allocator<base_allocator, false_type, false_type, false_type> never_propagating_allocator; +typedef propagating_allocator<base_allocator, true_type, false_type, false_type> pocma_allocator; +typedef propagating_allocator<base_allocator, false_type, true_type, false_type> pocca_allocator; +typedef propagating_allocator<base_allocator, false_type, false_type, true_type> pocs_allocator; +} + +template <typename Allocator, typename POCMA, typename POCCA, typename POCS> +void swap(propagating_allocator<Allocator, POCMA, POCCA, POCS>& lhs, + propagating_allocator<Allocator, POCMA, POCCA, POCS>&) { + ASSERT(POCS::value, "Allocator should not swap if pocs is false"); + if (lhs.propagated_on_swap) + *lhs.propagated_on_swap = true; +} + +template <typename ContainerType> +void test_allocator_traits_support() { + typedef typename ContainerType::allocator_type allocator_type; + typedef std::allocator_traits<allocator_type> allocator_traits; + typedef typename allocator_traits::propagate_on_container_copy_assignment pocca_type; +#if __TBB_CPP11_RVALUE_REF_PRESENT + typedef typename allocator_traits::propagate_on_container_move_assignment pocma_type; +#endif + typedef typename allocator_traits::propagate_on_container_swap pocs_type; + + bool propagated_on_copy = false; + bool propagated_on_move = false; + bool propagated_on_swap = false; + bool selected_on_copy = false; + + allocator_type alloc(propagated_on_copy, propagated_on_move, propagated_on_swap, selected_on_copy); + + ContainerType c1(alloc), c2(c1); + ASSERT(selected_on_copy, "select_on_container_copy_construction function was not called"); + + c1 = c2; + ASSERT(propagated_on_copy == pocca_type::value, "Unexpected allocator propagation on copy assignment"); + +#if __TBB_CPP11_RVALUE_REF_PRESENT + c2 = std::move(c1); + ASSERT(propagated_on_move == pocma_type::value, "Unexpected allocator propagation on move assignment"); +#endif + + c1.swap(c2); + ASSERT(propagated_on_swap == pocs_type::value, "Unexpected allocator propagation on swap"); +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +class non_movable_object { + non_movable_object() {} +private: + non_movable_object(non_movable_object&&); + non_movable_object& operator=(non_movable_object&&); +}; + +template <typename ContainerType> +void test_allocator_traits_with_non_movable_value_type() { + // Check, that if pocma is true, container allows move assignment without per-element move + typedef typename ContainerType::allocator_type allocator_type; + typedef std::allocator_traits<allocator_type> allocator_traits; + typedef typename allocator_traits::propagate_on_container_move_assignment pocma_type; + ASSERT(pocma_type::value, "Allocator POCMA must be true for this test"); + allocator_type alloc; + ContainerType container1(alloc), container2(alloc); + container1 = std::move(container2); +} +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + +#endif // __TBB_ALLOCATOR_TRAITS_PRESENT + +#if __TBB_CPP11_RVALUE_REF_PRESENT + +template<typename Allocator> +class allocator_aware_data { +public: + static bool assert_on_constructions; + typedef Allocator allocator_type; + + allocator_aware_data(const allocator_type& allocator = allocator_type()) + : my_allocator(allocator), my_value(0) {} + allocator_aware_data(int v, const allocator_type& allocator = allocator_type()) + : my_allocator(allocator), my_value(v) {} + allocator_aware_data(const allocator_aware_data&) { + ASSERT(!assert_on_constructions, "Allocator should propagate to the data during copy construction"); + } + allocator_aware_data(allocator_aware_data&&) { + ASSERT(!assert_on_constructions, "Allocator should propagate to the data during move construction"); + } + allocator_aware_data(const allocator_aware_data& rhs, const allocator_type& allocator) + : my_allocator(allocator), my_value(rhs.my_value) {} + allocator_aware_data(allocator_aware_data&& rhs, const allocator_type& allocator) + : my_allocator(allocator), my_value(rhs.my_value) {} + + int value() const { return my_value; } +private: + allocator_type my_allocator; + int my_value; +}; + +template<typename Allocator> +bool allocator_aware_data<Allocator>::assert_on_constructions = false; + +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + #pragma warning (pop) +#endif // warning 4267,4512,4355 is back + +namespace Harness { + + struct IsEqual { +#if __TBB_CPP11_SMART_POINTERS_PRESENT + template <typename T> + static bool compare( const std::weak_ptr<T> &t1, const std::weak_ptr<T> &t2 ) { + // Compare real pointers. + return t1.lock().get() == t2.lock().get(); + } + template <typename T> + static bool compare( const std::unique_ptr<T> &t1, const std::unique_ptr<T> &t2 ) { + // Compare real values. + return *t1 == *t2; + } + template <typename T1, typename T2> + static bool compare( const std::pair< const std::weak_ptr<T1>, std::weak_ptr<T2> > &t1, + const std::pair< const std::weak_ptr<T1>, std::weak_ptr<T2> > &t2 ) { + // Compare real pointers. + return t1.first.lock().get() == t2.first.lock().get() && + t1.second.lock().get() == t2.second.lock().get(); + } +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ + template <typename T1, typename T2> + static bool compare( const T1 &t1, const T2 &t2 ) { + return t1 == t2; + } + template <typename T1, typename T2> + bool operator()( T1 &t1, T2 &t2) const { + return compare( (const T1&)t1, (const T2&)t2 ); + } + }; + +} // Harness +#endif // tbb_test_harness_allocator_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_allocator_overload.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_allocator_overload.h new file mode 100644 index 00000000..7ad2c379 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_allocator_overload.h @@ -0,0 +1,35 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef tbb_test_harness_allocator_overload_H +#define tbb_test_harness_allocator_overload_H + +#include "../tbbmalloc/proxy.h" // for MALLOC_UNIXLIKE_OVERLOAD_ENABLED, MALLOC_ZONE_OVERLOAD_ENABLED +#include "tbb/tbb_config.h" // for __TBB_WIN8UI_SUPPORT + +// Skip configurations with unsupported system malloc overload: +// skip unsupported MSVCs, WIN8UI and MINGW (it doesn't define _MSC_VER), +// no support for MSVC 2015 and greater in debug for now, +// don't use defined(_MSC_VER), because result of using defined() in macro expansion is undefined +#define MALLOC_WINDOWS_OVERLOAD_ENABLED ((_WIN32||_WIN64) && !__TBB_WIN8UI_SUPPORT && _MSC_VER >= 1500 && !(_MSC_VER >= 1900 && _DEBUG)) + +// Skip configurations with unsupported system malloc overload: +// * overload via linking with -lmalloc_proxy is broken in offload, +// as the library is loaded too late in that mode, +// * LD_PRELOAD mechanism is broken in offload +#define HARNESS_SKIP_TEST ((!MALLOC_WINDOWS_OVERLOAD_ENABLED && !MALLOC_UNIXLIKE_OVERLOAD_ENABLED && !MALLOC_ZONE_OVERLOAD_ENABLED) || __TBB_MIC_OFFLOAD) + +#endif // tbb_test_harness_allocator_overload_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_assert.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_assert.h new file mode 100644 index 00000000..776159f1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_assert.h @@ -0,0 +1,37 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Just the assertion portion of the harness. +// This is useful for writing portions of tests that include +// the minimal number of necessary header files. +// +// The full "harness.h" must be included later. + +#ifndef harness_assert_H +#define harness_assert_H + +void ReportError( const char* filename, int line, const char* expression, const char* message); +void ReportWarning( const char* filename, int line, const char* expression, const char* message); + +#define ASSERT_CUSTOM(p,message,file,line) ((p)?(void)0:ReportError(file,line,#p,message)) +#define ASSERT(p,message) ASSERT_CUSTOM(p,message,__FILE__,__LINE__) +#define ASSERT_WARNING(p,message) ((p)?(void)0:ReportWarning(__FILE__,__LINE__,#p,message)) + +//! Compile-time error if x and y have different types +template<typename T> +void AssertSameType( const T& /*x*/, const T& /*y*/ ) {} + +#endif /* harness_assert_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_bad_expr.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_bad_expr.h new file mode 100644 index 00000000..797848ac --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_bad_expr.h @@ -0,0 +1,73 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Declarations for checking __TBB_ASSERT checks inside TBB. +// This header is an optional part of the test harness. +// It assumes that "harness.h" has already been included. + +#define TRY_BAD_EXPR_ENABLED (TBB_USE_ASSERT && TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN) + +#if TRY_BAD_EXPR_ENABLED + +//! Check that expression x raises assertion failure with message containing given substring. +/** Assumes that tbb::set_assertion_handler( AssertionFailureHandler ) was called earlier. */ +#define TRY_BAD_EXPR(x,substr) \ + { \ + const char* message = NULL; \ + bool okay = false; \ + try { \ + x; \ + } catch( AssertionFailure a ) { \ + okay = true; \ + message = a.message; \ + } \ + CheckAssertionFailure(__LINE__,#x,okay,message,substr); \ + } + +//! Exception object that holds a message. +struct AssertionFailure { + const char* message; + AssertionFailure( const char* filename, int line, const char* expression, const char* comment ); +}; + +AssertionFailure::AssertionFailure( const char* filename, int line, const char* expression, const char* comment ) : + message(comment) +{ + ASSERT(filename,"missing filename"); + ASSERT(0<line,"line number must be positive"); + // All of our current files have fewer than 4000 lines. + ASSERT(line<5000,"dubiously high line number"); + ASSERT(expression,"missing expression"); +} + +void AssertionFailureHandler( const char* filename, int line, const char* expression, const char* comment ) { + throw AssertionFailure(filename,line,expression,comment); +} + +void CheckAssertionFailure( int line, const char* expression, bool okay, const char* message, const char* substr ) { + if( !okay ) { + REPORT("Line %d, %s failed to fail\n", line, expression ); + abort(); + } else if( !message ) { + REPORT("Line %d, %s failed without a message\n", line, expression ); + abort(); + } else if( strstr(message,substr)==0 ) { + REPORT("Line %d, %s failed with message '%s' missing substring '%s'\n", __LINE__, expression, message, substr ); + abort(); + } +} + +#endif /* TRY_BAD_EXPR_ENABLED */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_barrier.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_barrier.h new file mode 100644 index 00000000..a01071f9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_barrier.h @@ -0,0 +1,136 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/atomic.h" +#include "tbb/tick_count.h" + +#ifndef harness_barrier_H +#define harness_barrier_H + +namespace Harness { + +//! Spin WHILE the value of the variable is equal to a given value +/** T and U should be comparable types. */ +class TimedWaitWhileEq { + //! Assignment not allowed + void operator=( const TimedWaitWhileEq& ); + double &my_limit; +public: + TimedWaitWhileEq(double &n_seconds) : my_limit(n_seconds) {} + TimedWaitWhileEq(const TimedWaitWhileEq &src) : my_limit(src.my_limit) {} + template<typename T, typename U> + void operator()( const volatile T& location, U value ) const { + tbb::tick_count start = tbb::tick_count::now(); + double time_passed; + do { + time_passed = (tbb::tick_count::now()-start).seconds(); + if( time_passed < 0.0001 ) __TBB_Pause(10); else __TBB_Yield(); + } while( time_passed < my_limit && location == value); + my_limit -= time_passed; + } +}; +//! Spin WHILE the value of the variable is equal to a given value +/** T and U should be comparable types. */ +class WaitWhileEq { + //! Assignment not allowed + void operator=( const WaitWhileEq& ); +public: + template<typename T, typename U> + void operator()( const volatile T& location, U value ) const { + tbb::internal::spin_wait_while_eq(location, value); + } +}; +class SpinBarrier +{ + unsigned numThreads; + tbb::atomic<unsigned> numThreadsFinished; // reached the barrier in this epoch + // the number of times the barrier was opened; TODO: move to a separate cache line + tbb::atomic<unsigned> epoch; + // a throwaway barrier can be used only once, then wait() becomes a no-op + bool throwaway; + + struct DummyCallback { + void operator() () const {} + template<typename T, typename U> + void operator()( const T&, U) const {} + }; + + SpinBarrier( const SpinBarrier& ); // no copy ctor + void operator=( const SpinBarrier& ); // no assignment +public: + SpinBarrier( unsigned nthreads = 0, bool throwaway_ = false ) { + initialize(nthreads, throwaway_); + } + void initialize( unsigned nthreads, bool throwaway_ = false ) { + numThreads = nthreads; + numThreadsFinished = 0; + epoch = 0; + throwaway = throwaway_; + } + + // Returns whether this thread was the last to reach the barrier. + // onWaitCallback is called by a thread for waiting; + // onOpenBarrierCallback is called by the last thread before unblocking other threads. + template<typename WaitEq, typename Callback> + bool custom_wait(const WaitEq &onWaitCallback, const Callback &onOpenBarrierCallback) + { + if (throwaway && epoch) + return false; + unsigned myEpoch = epoch; + unsigned myNumThreads = numThreads; // read it before the increment + int threadsLeft = myNumThreads - numThreadsFinished.fetch_and_increment() - 1; + ASSERT(threadsLeft>=0, "Broken barrier"); + if (threadsLeft > 0) { + /* this thread is not the last; wait until the epoch changes & return false */ + onWaitCallback(epoch, myEpoch); + return false; + } + /* This thread is the last one at the barrier in this epoch */ + onOpenBarrierCallback(); + /* reset the barrier, increment the epoch, and return true */ + threadsLeft = numThreadsFinished -= myNumThreads; + ASSERT( threadsLeft == 0, "Broken barrier"); + /* wakes up threads waiting to exit in this epoch */ + myEpoch -= epoch++; + ASSERT( myEpoch == 0, "Broken barrier"); + return true; + } + bool timed_wait_noerror(double n_seconds) { + custom_wait(TimedWaitWhileEq(n_seconds), DummyCallback()); + return n_seconds >= 0.0001; + } + bool timed_wait(double n_seconds, const char *msg="Time is out while waiting on a barrier") { + bool is_last = custom_wait(TimedWaitWhileEq(n_seconds), DummyCallback()); + ASSERT( n_seconds >= 0, msg); // TODO: refactor to avoid passing msg here and rising assertion + return is_last; + } + // onOpenBarrierCallback is called by the last thread before unblocking other threads. + template<typename Callback> + bool wait(const Callback &onOpenBarrierCallback) { + return custom_wait(WaitWhileEq(), onOpenBarrierCallback); + } + bool wait(){ + return wait(DummyCallback()); + } + //! signal to the barrier, rather a semaphore functionality + bool signal_nowait() { + return custom_wait(DummyCallback(),DummyCallback()); + } +}; + +} + +#endif //harness_barrier_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_checktype.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_checktype.h new file mode 100644 index 00000000..79174002 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_checktype.h @@ -0,0 +1,95 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef tbb_tests_harness_checktype_H +#define tbb_tests_harness_checktype_H + +// type that checks construction and destruction. + +#ifndef __HARNESS_CHECKTYPE_DEFAULT_CTOR + #define __HARNESS_CHECKTYPE_DEFAULT_CTOR 1 +#endif + +template<class Counter> +class check_type : Harness::NoAfterlife { + Counter id; + bool am_ready; +public: + static tbb::atomic<int> check_type_counter; + // if only non-default constructors are desired, set __HARNESS_CHECKTYPE_NODEFAULT_CTOR + check_type(Counter _n +#if __HARNESS_CHECKTYPE_DEFAULT_CTOR + = 0 +#endif + ) : id(_n), am_ready(false) { + ++check_type_counter; + } + + check_type(const check_type& other) : Harness::NoAfterlife(other) { + other.AssertLive(); + AssertLive(); + id = other.id; + am_ready = other.am_ready; + ++check_type_counter; + } + + operator int() const { return (int)my_id(); } + check_type& operator++() { ++id; return *this;; } + + ~check_type() { + AssertLive(); + --check_type_counter; + ASSERT(check_type_counter >= 0, "too many destructions"); + } + + check_type &operator=(const check_type &other) { + other.AssertLive(); + AssertLive(); + id = other.id; + am_ready = other.am_ready; + return *this; + } + + Counter my_id() const { AssertLive(); return id; } + bool is_ready() { AssertLive(); return am_ready; } + void function() { + AssertLive(); + if( id == (Counter)0 ) { + id = (Counter)1; + am_ready = true; + } + } + +}; + +template<class Counter> +tbb::atomic<int> check_type<Counter>::check_type_counter; + +// provide a class that for a check_type will initialize the counter on creation, and on +// destruction will check that the constructions and destructions of check_type match. +template<class MyClass> +struct Check { + Check() {} // creation does nothing + ~Check() {} // destruction checks nothing +}; + +template<class Counttype> +struct Check<check_type< Counttype > > { + Check() { check_type<Counttype>::check_type_counter = 0; } + ~Check() { ASSERT(check_type<Counttype>::check_type_counter == 0, "check_type constructions and destructions don't match"); } +}; + +#endif // tbb_tests_harness_checktype_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_concurrency.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_concurrency.h new file mode 100644 index 00000000..785378fe --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_concurrency.h @@ -0,0 +1,101 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef tbb_tests_harness_concurrency_H +#define tbb_tests_harness_concurrency_H + +#if _WIN32||_WIN64 +#include "tbb/machine/windows_api.h" +#elif __linux__ +#include <unistd.h> +#include <sys/sysinfo.h> +#include <string.h> +#include <sched.h> +#elif __FreeBSD__ +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <sys/param.h> // Required by <sys/cpuset.h> +#include <sys/cpuset.h> +#endif + +#include <limits.h> + +namespace Harness { + static int maxProcs = 0; + static int GetMaxProcs() { + if ( !maxProcs ) { +#if _WIN32||_WIN64 + SYSTEM_INFO si; + GetNativeSystemInfo(&si); + maxProcs = si.dwNumberOfProcessors; +#elif __linux__ + maxProcs = get_nprocs(); +#else /* __FreeBSD__ */ + maxProcs = sysconf(_SC_NPROCESSORS_ONLN); +#endif + } + return maxProcs; + } + + int LimitNumberOfThreads(int max_threads) { + ASSERT( max_threads >= 1 , "The limited number of threads should be positive." ); + maxProcs = GetMaxProcs(); + if ( maxProcs < max_threads ) + // Suppose that process mask is not set so the number of available threads equals maxProcs + return maxProcs; + +#if _WIN32||_WIN64 + ASSERT( max_threads <= 64 , "LimitNumberOfThreads doesn't support max_threads to be more than 64 on Windows." ); + DWORD_PTR mask = 1; + for ( int i = 1; i < max_threads; ++i ) + mask |= mask << 1; + bool err = !SetProcessAffinityMask( GetCurrentProcess(), mask ); +#else /* !WIN */ +#if __linux__ + typedef cpu_set_t mask_t; +#if __TBB_MAIN_THREAD_AFFINITY_BROKEN +#define setaffinity(mask) sched_setaffinity(0 /*get the mask of the calling thread*/, sizeof(mask_t), &mask) +#else +#define setaffinity(mask) sched_setaffinity(getpid(), sizeof(mask_t), &mask) +#endif +#else /* __FreeBSD__ */ + typedef cpuset_t mask_t; +#if __TBB_MAIN_THREAD_AFFINITY_BROKEN +#define setaffinity(mask) cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mask_t), &mask) +#else +#define setaffinity(mask) cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(mask_t), &mask) +#endif +#endif /* __FreeBSD__ */ + mask_t newMask; + CPU_ZERO(&newMask); + + int maskSize = (int)sizeof(mask_t) * CHAR_BIT; + ASSERT_WARNING( maskSize >= maxProcs, "The mask size doesn't seem to be big enough to call setaffinity. The call may return an error." ); + + ASSERT( max_threads <= (int)sizeof(mask_t) * CHAR_BIT , "The mask size is not enough to set the requested number of threads." ); + for ( int i = 0; i < max_threads; ++i ) + CPU_SET( i, &newMask ); + int err = setaffinity( newMask ); +#endif /* !WIN */ + ASSERT( !err, "Setting process affinity failed" ); + + return max_threads; + } + +} // namespace Harness + +#endif /* tbb_tests_harness_concurrency_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_concurrency_tracker.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_concurrency_tracker.h new file mode 100644 index 00000000..436ac55c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_concurrency_tracker.h @@ -0,0 +1,170 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef tbb_tests_harness_concurrency_tracker_H +#define tbb_tests_harness_concurrency_tracker_H + +#include "harness_assert.h" +#include "harness_barrier.h" +#include "tbb/atomic.h" +#include "../tbb/tls.h" +// Note: This file is used by RML tests which do not link TBB. +// Functionality that requires TBB binaries must be guarded by !__TBB_NO_IMPLICIT_LINKAGE +#if !defined(__TBB_NO_IMPLICIT_LINKAGE) +#include "tbb/mutex.h" +#include "tbb/task.h" +#include "tbb/combinable.h" +#include "tbb/parallel_for.h" +#include <functional> // for std::plus +#include "harness.h" // for Harness::NoCopy +#endif + +namespace Harness { + +static tbb::atomic<unsigned> ctInstantParallelism; +static tbb::atomic<unsigned> ctPeakParallelism; +static tbb::internal::tls<uintptr_t> ctNested; + +class ConcurrencyTracker { + bool m_Outer; + + static void Started () { + unsigned p = ++ctInstantParallelism; + unsigned q = ctPeakParallelism; + while( q<p ) { + q = ctPeakParallelism.compare_and_swap(p,q); + } + } + + static void Stopped () { + ASSERT ( ctInstantParallelism > 0, "Mismatched call to ConcurrencyTracker::Stopped()" ); + --ctInstantParallelism; + } +public: + ConcurrencyTracker() : m_Outer(false) { + uintptr_t nested = ctNested; + ASSERT (nested == 0 || nested == 1, NULL); + if ( !ctNested ) { + Started(); + m_Outer = true; + ctNested = 1; + } + } + ~ConcurrencyTracker() { + if ( m_Outer ) { + Stopped(); + ctNested = 0; + } + } + + static unsigned PeakParallelism() { return ctPeakParallelism; } + static unsigned InstantParallelism() { return ctInstantParallelism; } + + static void Reset() { + ASSERT (ctInstantParallelism == 0, "Reset cannot be called when concurrency tracking is underway"); + ctInstantParallelism = ctPeakParallelism = 0; + } +}; // ConcurrencyTracker + +#if !defined(__TBB_NO_IMPLICIT_LINKAGE) +struct ExactConcurrencyLevel : NoCopy { + typedef tbb::combinable<size_t> Combinable; +private: + Harness::SpinBarrier *myBarrier; + // count unique worker threads + Combinable *myUniqueThreads; + mutable tbb::atomic<size_t> myActiveBodyCnt; + // output parameter for parallel_for body to report that max is reached + mutable bool myReachedMax; + // zero timeout means no barrier is used during concurrency level detection + const double myTimeout; + const size_t myConcLevel; + const bool myCrashOnFail; + + static tbb::mutex global_mutex; + + ExactConcurrencyLevel(double timeout, size_t concLevel, Combinable *uniq, bool crashOnFail) : + myBarrier(NULL), myUniqueThreads(uniq), myReachedMax(false), + myTimeout(timeout), myConcLevel(concLevel), myCrashOnFail(crashOnFail) { + myActiveBodyCnt = 0; + } + bool run() { + const int LOOP_ITERS = 100; + tbb::combinable<size_t> uniq; + Harness::SpinBarrier barrier((unsigned)myConcLevel, /*throwaway=*/true); + if (myTimeout != 0.) + myBarrier = &barrier; + if (!myUniqueThreads) + myUniqueThreads = &uniq; + tbb::parallel_for((size_t)0, myConcLevel*LOOP_ITERS, *this, tbb::simple_partitioner()); + return myReachedMax; + } +public: + void operator()(size_t) const { + size_t v = ++myActiveBodyCnt; + ASSERT(v <= myConcLevel, "Number of active bodies is too high."); + if (v == myConcLevel) // record that the max expected concurrency was observed + myReachedMax = true; + // try to get barrier when 1st time in the thread + if (myBarrier && !myBarrier->timed_wait_noerror(myTimeout)) + ASSERT(!myCrashOnFail, "Timeout was detected."); + + myUniqueThreads->local() = 1; + for (int i=0; i<100; i++) + __TBB_Pause(1); + --myActiveBodyCnt; + } + + enum Mode { + None, + // When multiple blocking checks are performed, there might be not enough + // concurrency for all of them. Serialize check() calls. + Serialize + }; + + // check that we have never got more than concLevel threads, + // and that in some moment we saw exactly concLevel threads + static void check(size_t concLevel, Mode m = None) { + ExactConcurrencyLevel o(30., concLevel, NULL, /*crashOnFail=*/true); + + tbb::mutex::scoped_lock lock; + if (m == Serialize) + lock.acquire(global_mutex); + bool ok = o.run(); + ASSERT(ok, NULL); + } + + static bool isEqual(size_t concLevel) { + ExactConcurrencyLevel o(3., concLevel, NULL, /*crashOnFail=*/false); + return o.run(); + } + + static void checkLessOrEqual(size_t concLevel, tbb::combinable<size_t> *unique) { + ExactConcurrencyLevel o(0., concLevel, unique, /*crashOnFail=*/true); + + o.run(); // ignore result, as without a barrier it is not reliable + const size_t num = unique->combine(std::plus<size_t>()); + ASSERT(num<=concLevel, "Too many workers observed."); + } +}; + +tbb::mutex ExactConcurrencyLevel::global_mutex; + +#endif /* !defined(__TBB_NO_IMPLICIT_LINKAGE) */ + +} // namespace Harness + +#endif /* tbb_tests_harness_concurrency_tracker_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_cpu.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_cpu.h new file mode 100644 index 00000000..0102b3c0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_cpu.h @@ -0,0 +1,116 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Declarations for simple estimate of CPU time being used by a program. +// This header is an optional part of the test harness. +// It assumes that "harness_assert.h" has already been included. + +#if _WIN32 + #include <windows.h> +#else + #include <sys/time.h> + #include <sys/resource.h> +#endif + +//! Return time (in seconds) spent by the current process in user mode. +/* Returns 0 if not implemented on platform. */ +static double GetCPUUserTime() { +#if __TBB_WIN8UI_SUPPORT + return 0; +#elif _WIN32 + FILETIME my_times[4]; + bool status = GetProcessTimes(GetCurrentProcess(), my_times, my_times+1, my_times+2, my_times+3)!=0; + ASSERT( status, NULL ); + LARGE_INTEGER usrtime; + usrtime.LowPart = my_times[3].dwLowDateTime; + usrtime.HighPart = my_times[3].dwHighDateTime; + return double(usrtime.QuadPart)*1E-7; +#else + // Generic UNIX, including __APPLE__ + + // On Linux, there is no good way to get CPU usage info for the current process: + // getrusage(RUSAGE_SELF, ...) that is used now only returns info for the calling thread; + // getrusage(RUSAGE_CHILDREN, ...) only counts for finished children threads; + // tms_utime and tms_cutime got with times(struct tms*) are equivalent to the above items; + // finally, /proc/self/task/<task_id>/stat doesn't exist on older kernels + // and it isn't quite convenient to read it for every task_id. + + struct rusage resources; + bool status = getrusage(RUSAGE_SELF, &resources)==0; + ASSERT( status, NULL ); + return (double(resources.ru_utime.tv_sec)*1E6 + double(resources.ru_utime.tv_usec))*1E-6; +#endif +} + +#include "tbb/tick_count.h" +#include <cstdio> + +// The resolution of GetCPUUserTime is 10-15 ms or so; waittime should be a few times bigger. +const double WAITTIME = 0.1; // in seconds, i.e. 100 ms +const double THRESHOLD = WAITTIME/100; + +static void TestCPUUserTime( int nthreads, int nactive = 1 ) { + // The test will always pass on Linux; read the comments in GetCPUUserTime for details + // Also it will not detect spinning issues on systems with only one processing core. + + int nworkers = nthreads-nactive; + if( !nworkers ) return; + double lastusrtime = GetCPUUserTime(); + if( !lastusrtime ) return; + + static double minimal_waittime = WAITTIME, + maximal_waittime = WAITTIME * 10; + double usrtime_delta; + double waittime_delta; + tbb::tick_count stamp = tbb::tick_count::now(); + volatile intptr_t k = (intptr_t)&usrtime_delta; + // wait for GetCPUUserTime update + while( (usrtime_delta=GetCPUUserTime()-lastusrtime) < THRESHOLD ) { + for ( int i = 0; i < 1000; ++i ) ++k; // do fake work without which user time can stall + if ( (waittime_delta = (tbb::tick_count::now()-stamp).seconds()) > maximal_waittime ) { + REPORT( "Warning: %.2f sec elapsed but user mode time is still below its threshold (%g < %g)\n", + waittime_delta, usrtime_delta, THRESHOLD ); + break; + } + } + lastusrtime += usrtime_delta; + + // Wait for workers to go sleep + stamp = tbb::tick_count::now(); + while( ((waittime_delta=(tbb::tick_count::now()-stamp).seconds()) < minimal_waittime) + || ((usrtime_delta=GetCPUUserTime()-lastusrtime) < THRESHOLD) ) + { + for ( int i = 0; i < 1000; ++i ) ++k; // do fake work without which user time can stall + if ( waittime_delta > maximal_waittime ) { + REPORT( "Warning: %.2f sec elapsed but GetCPUUserTime reported only %g sec\n", waittime_delta, usrtime_delta ); + break; + } + } + + // Test that all workers sleep when no work. + while( nactive>1 && usrtime_delta-nactive*waittime_delta<0 ) { + // probably the number of active threads was mispredicted + --nactive; ++nworkers; + } + double avg_worker_usrtime = (usrtime_delta-nactive*waittime_delta)/nworkers; + + if( avg_worker_usrtime > waittime_delta/2 ) + REPORT( "ERROR: %d worker threads are spinning; waittime: %g; usrtime: %g; avg worker usrtime: %g\n", + nworkers, waittime_delta, usrtime_delta, avg_worker_usrtime); + else + REMARK("%d worker threads; waittime: %g; usrtime: %g; avg worker usrtime: %g\n", + nworkers, waittime_delta, usrtime_delta, avg_worker_usrtime); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_defs.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_defs.h new file mode 100644 index 00000000..37abbbaa --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_defs.h @@ -0,0 +1,220 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_harness_defs_H +#define __TBB_harness_defs_H + +#include "tbb/tbb_config.h" +#if __FreeBSD__ +#include <sys/param.h> // for __FreeBSD_version +#endif + +#if __TBB_TEST_PIC && !__PIC__ +#define __TBB_TEST_SKIP_PIC_MODE 1 +#else +#define __TBB_TEST_SKIP_PIC_MODE 0 +#endif + +// no need to test GCC builtins mode on ICC +#define __TBB_TEST_SKIP_GCC_BUILTINS_MODE ( __TBB_TEST_BUILTINS && (!__TBB_GCC_BUILTIN_ATOMICS_PRESENT || __INTEL_COMPILER) ) + +#define __TBB_TEST_SKIP_ICC_BUILTINS_MODE ( __TBB_TEST_BUILTINS && !__TBB_ICC_BUILTIN_ATOMICS_PRESENT ) + +#ifndef TBB_USE_GCC_BUILTINS + // Force TBB to use GCC intrinsics port, but not on ICC, as no need + #define TBB_USE_GCC_BUILTINS ( __TBB_TEST_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT && !__INTEL_COMPILER ) +#endif + +#ifndef TBB_USE_ICC_BUILTINS + // Force TBB to use ICC c++11 style intrinsics port + #define TBB_USE_ICC_BUILTINS ( __TBB_TEST_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT ) +#endif + +#if (_WIN32 && !__TBB_WIN8UI_SUPPORT) || (__linux__ && !__ANDROID__ && !__bg__) || __FreeBSD_version >= 701000 +#define __TBB_TEST_SKIP_AFFINITY 0 +#else +#define __TBB_TEST_SKIP_AFFINITY 1 +#endif + +#if __INTEL_COMPILER + #define __TBB_CPP11_REFERENCE_WRAPPER_PRESENT ( __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200 && \ + ( _MSC_VER >= 1600 || __TBB_GLIBCXX_VERSION >= 40400 || ( _LIBCPP_VERSION && __cplusplus >= 201103L ) ) ) + #define __TBB_RANGE_BASED_FOR_PRESENT ( __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1300 ) + #define __TBB_SCOPED_ENUM_PRESENT ( __INTEL_CXX11_MODE__ && __INTEL_COMPILER > 1100 ) +#elif __clang__ + #define __TBB_CPP11_REFERENCE_WRAPPER_PRESENT ( __cplusplus >= 201103L && (__TBB_GLIBCXX_VERSION >= 40400 || _LIBCPP_VERSION) ) + #define __TBB_RANGE_BASED_FOR_PRESENT ( __has_feature(__cxx_range_for) ) + #define __TBB_SCOPED_ENUM_PRESENT ( __has_feature(cxx_strong_enums) ) +#elif __GNUC__ + #define __TBB_CPP11_REFERENCE_WRAPPER_PRESENT ( __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400 ) + #define __TBB_RANGE_BASED_FOR_PRESENT ( __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40500 ) + #define __TBB_SCOPED_ENUM_PRESENT ( __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400 ) + #define __TBB_GCC_WARNING_IGNORED_ATTRIBUTES_PRESENT (__TBB_GCC_VERSION >= 60100) +#elif _MSC_VER + #define __TBB_CPP11_REFERENCE_WRAPPER_PRESENT ( _MSC_VER >= 1600 ) + #define __TBB_RANGE_BASED_FOR_PRESENT ( _MSC_VER >= 1700 ) + #define __TBB_SCOPED_ENUM_PRESENT ( _MSC_VER >= 1700 ) +#endif + +#define __TBB_CPP14_GENERIC_LAMBDAS_PRESENT (__cpp_generic_lambdas >= 201304 ) + +#define __TBB_TEST_SKIP_LAMBDA (__TBB_ICC_13_0_CPP11_STDLIB_SUPPORT_BROKEN || !__TBB_CPP11_LAMBDAS_PRESENT) + +#if __GNUC__ && __ANDROID__ +// On Android* OS, GCC does not support _thread keyword + #define __TBB_THREAD_LOCAL_VARIABLES_PRESENT 0 +#else + #define __TBB_THREAD_LOCAL_VARIABLES_PRESENT 1 +#endif + +// ICC has a bug in assumptions of the modifications made via atomic pointer +#define __TBB_ICC_BUILTIN_ATOMICS_POINTER_ALIASING_BROKEN (TBB_USE_ICC_BUILTINS && __INTEL_COMPILER < 1400 && __INTEL_COMPILER > 1200) + +// clang on Android/IA-32 fails on exception thrown from static move constructor +#define __TBB_CPP11_EXCEPTION_IN_STATIC_TEST_BROKEN (__ANDROID__ && __SIZEOF_POINTER__==4 && __clang__) + +// MSVC 2013 is unable to properly resolve call to overloaded operator= with std::initializer_list argument for std::pair list elements +// clang on Android/IA-32 fails on "std::vector<std::pair<int,int>> vd{{1,1},{1,1},{1,1}};" line in release mode +#define __TBB_CPP11_INIT_LIST_TEST_BROKEN (_MSC_VER <= 1800 && _MSC_VER && !__INTEL_COMPILER) || (__ANDROID__ && __TBB_x86_32 && __clang__) +// MSVC 2013 is unable to manage lifetime of temporary objects passed to a std::initializer_list constructor properly +#define __TBB_CPP11_INIT_LIST_TEMP_OBJS_LIFETIME_BROKEN (_MSC_FULL_VER < 180030501 && _MSC_VER && !__INTEL_COMPILER) + +// Implementation of C++11 std::placeholders in libstdc++ coming with GCC prior to 4.5 reveals bug in Intel(R) C++ Compiler 13 causing "multiple definition" link errors. +#define __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN ((__INTEL_COMPILER == 1300 || __INTEL_COMPILER == 1310) && __GXX_EXPERIMENTAL_CXX0X__ && __GLIBCXX__ && __TBB_GLIBCXX_VERSION < 40500) + +// Intel C++ Compiler has an issue when a scoped enum with a specified underlying type has negative values. +#define __TBB_ICC_SCOPED_ENUM_WITH_UNDERLYING_TYPE_NEGATIVE_VALUE_BROKEN ( _MSC_VER && !__TBB_DEBUG && __INTEL_COMPILER && __INTEL_COMPILER <= 1500 ) +// Intel C++ Compiler has an issue with __atomic_load_explicit from a scoped enum with a specified underlying type. +#define __TBB_ICC_SCOPED_ENUM_WITH_UNDERLYING_TYPE_ATOMIC_LOAD_BROKEN ( TBB_USE_ICC_BUILTINS && !__TBB_DEBUG && __INTEL_COMPILER && __INTEL_COMPILER <= 1500 ) + +// Unable to use constexpr member functions to initialize compile time constants +#define __TBB_CONSTEXPR_MEMBER_FUNCTION_BROKEN (__INTEL_COMPILER == 1500) +// Some versions of MSVC do not do compile-time initialization of static variables with constexpr constructors in debug mode +#define __TBB_STATIC_CONSTEXPR_INIT_BROKEN (_MSC_VER >= 1900 && _MSC_VER <= 1914 && !__INTEL_COMPILER && _DEBUG) + +#if __GNUC__ && __ANDROID__ + #define __TBB_EXCEPTION_TYPE_INFO_BROKEN ( __TBB_GCC_VERSION < 40600 ) +#elif _MSC_VER + #define __TBB_EXCEPTION_TYPE_INFO_BROKEN ( _MSC_VER < 1400 ) +#else + #define __TBB_EXCEPTION_TYPE_INFO_BROKEN 0 +#endif + +// a function ptr cannot be converted to const T& template argument without explicit cast +#define __TBB_FUNC_PTR_AS_TEMPL_PARAM_BROKEN ( ((__linux__ || __APPLE__) && __INTEL_COMPILER && __INTEL_COMPILER < 1100) || __SUNPRO_CC ) + +#define __TBB_UNQUALIFIED_CALL_OF_DTOR_BROKEN (__GNUC__==3 && __GNUC_MINOR__<=3) + +#define __TBB_CAS_8_CODEGEN_BROKEN (__TBB_x86_32 && __PIC__ && __TBB_GCC_VERSION == 40102 && !__INTEL_COMPILER) + +#define __TBB_THROW_FROM_DTOR_BROKEN (__clang__ && __apple_build_version__ && __apple_build_version__ < 5000279) + +// std::uncaught_exception is broken on some version of stdlibc++ (it returns true with no active exception) +#define __TBB_STD_UNCAUGHT_EXCEPTION_BROKEN (__TBB_GLIBCXX_VERSION == 40407) + +#if __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN + #define _EXCEPTION_PTR_H /* prevents exception_ptr.h inclusion */ + #define _GLIBCXX_NESTED_EXCEPTION_H /* prevents nested_exception.h inclusion */ +#endif + +// TODO: Investigate the cases that require this macro. +#define __TBB_COMPLICATED_ADL_BROKEN ( __GNUC__ && __TBB_GCC_VERSION < 40400 ) + +// Intel C++ Compiler fails to compile the comparison of tuples in some cases +#if __INTEL_COMPILER && __INTEL_COMPILER < 1700 + #define __TBB_TUPLE_COMPARISON_COMPILATION_BROKEN (__TBB_GLIBCXX_VERSION >= 40800 || __MIC__) +#endif + +// Intel C++ Compiler fails to compile std::reference in some cases +#if __INTEL_COMPILER && __INTEL_COMPILER < 1600 || __INTEL_COMPILER == 1600 && __INTEL_COMPILER_UPDATE <= 1 + #define __TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN (__TBB_GLIBCXX_VERSION >= 40800 && __TBB_GLIBCXX_VERSION <= 50101 || __MIC__) +#endif + +// Intel C++ Compiler fails to generate non-throwing move members for a class inherited from template +#define __TBB_NOTHROW_MOVE_MEMBERS_IMPLICIT_GENERATION_BROKEN \ + (__INTEL_COMPILER>=1600 && __INTEL_COMPILER<=1900 || __INTEL_COMPILER==1500 && __INTEL_COMPILER_UPDATE>3) + +// std::is_copy_constructible<T>::value returns 'true' for non copyable type when MSVC compiler is used. +#define __TBB_IS_COPY_CONSTRUCTIBLE_BROKEN ( _MSC_VER && (_MSC_VER <= 1700 || _MSC_VER <= 1800 && !__INTEL_COMPILER) ) + +// GCC 4.7 and 4.8 might fail to take an address of overloaded template function (bug 57043) +#if __GNUC__ && !__INTEL_COMPILER && !__clang__ + #define __TBB_GCC_OVERLOADED_TEMPLATE_FUNCTION_ADDRESS_BROKEN \ + (__TBB_GCC_VERSION>=40700 && __TBB_GCC_VERSION<40704 || __TBB_GCC_VERSION>=40800 && __TBB_GCC_VERSION<40803 ) +#endif + +// Swapping of scoped_allocator_adaptors is broken on GCC 4.9 and lower and on Android for Windows +// Allocator propagation into std::pair is broken for Apple clang, lower then 9.0 +// Compilation of <scoped_allocator> header is broken for Visual Studio 2017 with ICC 17.8 +#define __TBB_SCOPED_ALLOCATOR_BROKEN (__TBB_GCC_VERSION <= 50100 || (__APPLE__ && __TBB_CLANG_VERSION < 90000) || \ + (__FreeBSD__ && __TBB_CLANG_VERSION <= 60000) || \ + (__ANDROID__ && (_WIN32 || _WIN64)) || \ + (_MSC_VER && _MSC_VER == 1912 && __INTEL_COMPILER == 1700)) + + + +// The tuple-based tests with more inputs take a long time to compile. If changes +// are made to the tuple implementation or any switch that controls it, or if testing +// with a new platform implementation of std::tuple, the test should be compiled with +// MAX_TUPLE_TEST_SIZE >= 10 (or the largest number of elements supported) to ensure +// all tuple sizes are tested. Expect a very long compile time. +#ifndef MAX_TUPLE_TEST_SIZE + #if TBB_USE_DEBUG + #define MAX_TUPLE_TEST_SIZE 3 + #else + #define MAX_TUPLE_TEST_SIZE 5 + #endif +#else + #if _MSC_VER +// test sizes <= 8 don't get "decorated name length exceeded" errors. (disable : 4503) + #if MAX_TUPLE_TEST_SIZE > 8 + #undef MAX_TUPLE_TEST_SIZE + #define MAX_TUPLE_TEST_SIZE 8 + #endif + #endif + #if MAX_TUPLE_TEST_SIZE > __TBB_VARIADIC_MAX + #undef MAX_TUPLE_TEST_SIZE + #define MAX_TUPLE_TEST_SIZE __TBB_VARIADIC_MAX + #endif +#endif + +#if __TBB_CPF_BUILD + #ifndef TBB_PREVIEW_FLOW_GRAPH_FEATURES + #define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1 + #endif + #ifndef TBB_PREVIEW_FLOW_GRAPH_TRACE + #define TBB_PREVIEW_FLOW_GRAPH_TRACE 1 + #endif + #ifndef TBB_PREVIEW_ALGORITHM_TRACE + #define TBB_PREVIEW_ALGORITHM_TRACE 1 + #endif + #ifndef TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR + #define TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR 1 + #endif +#endif + +namespace Harness { + //! Utility template function to prevent "unused" warnings by various compilers. + template<typename T> void suppress_unused_warning( const T& ) {} + + //TODO: unify with one in tbb::internal + //! Utility helper structure to ease overload resolution + template<int > struct int_to_type {}; +} + +const unsigned MByte = 1024*1024; + +#endif /* __TBB_harness_defs_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_dynamic_libs.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_dynamic_libs.h new file mode 100644 index 00000000..95599263 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_dynamic_libs.h @@ -0,0 +1,124 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +// Include this header file before harness.h for HARNESS_SKIP_TEST to take effect +#if !__TBB_DYNAMIC_LOAD_ENABLED +#define HARNESS_SKIP_TEST 1 +#else + +#if _WIN32 || _WIN64 +#include "tbb/machine/windows_api.h" +#else +#include <dlfcn.h> +#endif +#include "harness_assert.h" + +namespace Harness { + +#if TBB_USE_DEBUG +#define SUFFIX1 "_debug" +#define SUFFIX2 +#else +#define SUFFIX1 +#define SUFFIX2 "_debug" +#endif /* TBB_USE_DEBUG */ + +#if _WIN32||_WIN64 +#define PREFIX +#define EXT ".dll" +#else +#define PREFIX "lib" +#if __APPLE__ +#define EXT ".dylib" +// Android SDK build system does not support .so file name versioning +#elif __FreeBSD__ || __NetBSD__ || __sun || _AIX || __ANDROID__ +#define EXT ".so" +#elif __linux__ // Order of these elif's matters! +#define EXT __TBB_STRING(.so.TBB_COMPATIBLE_INTERFACE_VERSION) +#else +#error Unknown OS +#endif +#endif + +// Form the names of the TBB memory allocator binaries. +#define MALLOCLIB_NAME1 PREFIX "tbbmalloc" SUFFIX1 EXT +#define MALLOCLIB_NAME2 PREFIX "tbbmalloc" SUFFIX2 EXT + +#if _WIN32 || _WIN64 +typedef HMODULE LIBRARY_HANDLE; +#else +typedef void *LIBRARY_HANDLE; +#endif + +#if _WIN32 || _WIN64 +#define TEST_LIBRARY_NAME(base) base".dll" +#elif __APPLE__ +#define TEST_LIBRARY_NAME(base) base".dylib" +#else +#define TEST_LIBRARY_NAME(base) base".so" +#endif + +LIBRARY_HANDLE OpenLibrary(const char *name) +{ +#if _WIN32 || _WIN64 +#if __TBB_WIN8UI_SUPPORT + TCHAR wlibrary[MAX_PATH]; + if ( MultiByteToWideChar(CP_UTF8, 0, name, -1, wlibrary, MAX_PATH) == 0 ) return false; + return :: LoadPackagedLibrary( wlibrary, 0 ); +#else + return ::LoadLibrary(name); +#endif +#else + return dlopen(name, RTLD_NOW|RTLD_GLOBAL); +#endif +} + +void CloseLibrary(LIBRARY_HANDLE lib) +{ +#if _WIN32 || _WIN64 + BOOL ret = FreeLibrary(lib); + ASSERT(ret, "FreeLibrary must be successful"); +#else + int ret = dlclose(lib); + ASSERT(ret == 0, "dlclose must be successful"); +#endif +} + +typedef void (*FunctionAddress)(); + +template <typename FunctionPointer> +void GetAddress(Harness::LIBRARY_HANDLE lib, const char *name, FunctionPointer& func) +{ +#if _WIN32 || _WIN64 + func = (FunctionPointer)(void*)GetProcAddress(lib, name); +#else + func = (FunctionPointer)dlsym(lib, name); +#endif + ASSERT(func, "Can't find required symbol in dynamic library"); +} + +FunctionAddress GetAddress(Harness::LIBRARY_HANDLE lib, const char *name) +{ + FunctionAddress func; + GetAddress(lib, name, func); + return func; +} + +} // namespace Harness + +#endif // __TBB_DYNAMIC_LOAD_ENABLED diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_eh.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_eh.h new file mode 100644 index 00000000..721c5d40 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_eh.h @@ -0,0 +1,313 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include <typeinfo> +#include "tbb/tbb_exception.h" +#include "tbb/atomic.h" +#if USE_TASK_SCHEDULER_OBSERVER +#include "tbb/task_scheduler_observer.h" +#endif +#include "harness.h" +#include "harness_concurrency_tracker.h" + +int g_NumThreads = 0; +Harness::tid_t g_Master = 0; +const char * g_Orig_Wakeup_Msg = "Missed wakeup or machine is overloaded?"; +const char * g_Wakeup_Msg = g_Orig_Wakeup_Msg; + +tbb::atomic<intptr_t> g_CurExecuted, + g_ExecutedAtLastCatch, + g_ExecutedAtFirstCatch, + g_ExceptionsThrown, + g_MasterExecutedThrow, // number of times master entered exception code + g_NonMasterExecutedThrow, // number of times nonmaster entered exception code + g_PipelinesStarted; +volatile bool g_ExceptionCaught = false, + g_UnknownException = false; + +#if USE_TASK_SCHEDULER_OBSERVER +tbb::atomic<intptr_t> g_ActualMaxThreads; +tbb::atomic<intptr_t> g_ActualCurrentThreads; +#endif + +volatile bool g_ThrowException = true, + // g_Flog is true for nested construct tests with catches (exceptions are not allowed to + // propagate to the TBB construct itself.) + g_Flog = false, + g_MasterExecuted = false, + g_NonMasterExecuted = false; + +bool g_ExceptionInMaster = false; +bool g_SolitaryException = false; +bool g_NestedPipelines = false; + +//! Number of exceptions propagated into the user code (i.e. intercepted by the tests) +tbb::atomic<intptr_t> g_NumExceptionsCaught; + +//----------------------------------------------------------- + +#if USE_TASK_SCHEDULER_OBSERVER +class eh_test_observer : public tbb::task_scheduler_observer { +public: + void on_scheduler_entry(bool is_worker) __TBB_override { + if(is_worker) { // we've already counted the master + size_t p = ++g_ActualCurrentThreads; + size_t q = g_ActualMaxThreads; + while(q < p) { + q = g_ActualMaxThreads.compare_and_swap(p,q); + } + } + else { + // size_t q = g_ActualMaxThreads; + } + } + void on_scheduler_exit(bool is_worker) __TBB_override { + if(is_worker) { + --g_ActualCurrentThreads; + } + } +}; +#endif +//----------------------------------------------------------- + +inline void ResetEhGlobals ( bool throwException = true, bool flog = false ) { + Harness::ConcurrencyTracker::Reset(); + g_CurExecuted = g_ExecutedAtLastCatch = g_ExecutedAtFirstCatch = 0; + g_ExceptionCaught = false; + g_UnknownException = false; + g_NestedPipelines = false; + g_ThrowException = throwException; + g_MasterExecutedThrow = 0; + g_NonMasterExecutedThrow = 0; + g_Flog = flog; + g_MasterExecuted = false; + g_NonMasterExecuted = false; +#if USE_TASK_SCHEDULER_OBSERVER + g_ActualMaxThreads = 1; // count master + g_ActualCurrentThreads = 1; // count master +#endif + g_ExceptionsThrown = g_NumExceptionsCaught = g_PipelinesStarted = 0; +} + +#if TBB_USE_EXCEPTIONS +class test_exception : public std::exception { + const char* my_description; +public: + test_exception ( const char* description ) : my_description(description) {} + + const char* what() const throw() __TBB_override { return my_description; } +}; + +class solitary_test_exception : public test_exception { +public: + solitary_test_exception ( const char* description ) : test_exception(description) {} +}; + +#if TBB_USE_CAPTURED_EXCEPTION + typedef tbb::captured_exception PropagatedException; + #define EXCEPTION_NAME(e) e.name() +#else + typedef test_exception PropagatedException; + #define EXCEPTION_NAME(e) typeid(e).name() +#endif + +#define EXCEPTION_DESCR "Test exception" + +#if HARNESS_EH_SIMPLE_MODE + +static void ThrowTestException () { + ++g_ExceptionsThrown; + throw test_exception(EXCEPTION_DESCR); +} + +#else /* !HARNESS_EH_SIMPLE_MODE */ + +static void ThrowTestException ( intptr_t threshold ) { + bool inMaster = (Harness::CurrentTid() == g_Master); + if ( !g_ThrowException || // if we're not supposed to throw + (!g_Flog && // if we're not catching throw in bodies and + (g_ExceptionInMaster ^ inMaster)) ) { // we're the master and not expected to throw + // or are the master and the master is not the one to throw (??) + return; + } + while ( Existed() < threshold ) + __TBB_Yield(); + if ( !g_SolitaryException ) { + ++g_ExceptionsThrown; + if(inMaster) ++g_MasterExecutedThrow; else ++g_NonMasterExecutedThrow; + throw test_exception(EXCEPTION_DESCR); + } + // g_SolitaryException == true + if(g_NestedPipelines) { + // only throw exception if we have started at least two inner pipelines + // else return + if(g_PipelinesStarted >= 3) { + if ( g_ExceptionsThrown.compare_and_swap(1, 0) == 0 ) { + if(inMaster) ++g_MasterExecutedThrow; else ++g_NonMasterExecutedThrow; + throw solitary_test_exception(EXCEPTION_DESCR); + } + } + } + else { + if ( g_ExceptionsThrown.compare_and_swap(1, 0) == 0 ) { + if(inMaster) ++g_MasterExecutedThrow; else ++g_NonMasterExecutedThrow; + throw solitary_test_exception(EXCEPTION_DESCR); + } + } +} +#endif /* !HARNESS_EH_SIMPLE_MODE */ + +#define UPDATE_COUNTS() \ + { \ + ++g_CurExecuted; \ + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; \ + else g_NonMasterExecuted = true; \ + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; \ + } + +#define CATCH() \ + } catch ( PropagatedException& e ) { \ + g_ExecutedAtFirstCatch.compare_and_swap(g_CurExecuted,0); \ + g_ExecutedAtLastCatch = g_CurExecuted; \ + ASSERT( e.what(), "Empty what() string" ); \ + ASSERT (__TBB_EXCEPTION_TYPE_INFO_BROKEN || strcmp(EXCEPTION_NAME(e), (g_SolitaryException ? typeid(solitary_test_exception) : typeid(test_exception)).name() ) == 0, "Unexpected original exception name"); \ + ASSERT (__TBB_EXCEPTION_TYPE_INFO_BROKEN || strcmp(e.what(), EXCEPTION_DESCR) == 0, "Unexpected original exception info"); \ + g_ExceptionCaught = l_ExceptionCaughtAtCurrentLevel = true; \ + ++g_NumExceptionsCaught; \ + } catch ( tbb::tbb_exception& e ) { \ + REPORT("Unexpected %s\n", e.name()); \ + ASSERT (g_UnknownException && !g_UnknownException, "Unexpected tbb::tbb_exception" ); \ + } catch ( std::exception& e ) { \ + REPORT("Unexpected %s\n", typeid(e).name()); \ + ASSERT (g_UnknownException && !g_UnknownException, "Unexpected std::exception" ); \ + } catch ( ... ) { \ + g_ExceptionCaught = l_ExceptionCaughtAtCurrentLevel = true; \ + g_UnknownException = unknownException = true; \ + } \ + if ( !g_SolitaryException ) \ + REMARK_ONCE ("Multiple exceptions mode: %d throws", (intptr_t)g_ExceptionsThrown); + +#define ASSERT_EXCEPTION() \ + { \ + ASSERT (!g_ExceptionsThrown || g_ExceptionCaught, "throw without catch"); \ + ASSERT (!g_ExceptionCaught || g_ExceptionsThrown, "catch without throw"); \ + ASSERT (g_ExceptionCaught || (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow), "no exception occurred"); \ + ASSERT (__TBB_EXCEPTION_TYPE_INFO_BROKEN || !g_UnknownException, "unknown exception was caught"); \ + } + +#define CATCH_AND_ASSERT() \ + CATCH() \ + ASSERT_EXCEPTION() + +#else /* !TBB_USE_EXCEPTIONS */ + +inline void ThrowTestException ( intptr_t ) {} + +#endif /* !TBB_USE_EXCEPTIONS */ + +#define TRY() \ + bool l_ExceptionCaughtAtCurrentLevel = false, unknownException = false; \ + __TBB_TRY { + +// "l_ExceptionCaughtAtCurrentLevel || unknownException" is used only to "touch" otherwise unused local variables +#define CATCH_AND_FAIL() } __TBB_CATCH(...) { \ + ASSERT (false, "Cancelling tasks must not cause any exceptions"); \ + (void)(l_ExceptionCaughtAtCurrentLevel && unknownException); \ + } + +const int c_Timeout = 1000000; + +void WaitUntilConcurrencyPeaks ( int expected_peak ) { + if ( g_Flog ) + return; + int n = 0; +retry: + while ( ++n < c_Timeout && (int)Harness::ConcurrencyTracker::PeakParallelism() < expected_peak ) + __TBB_Yield(); +#if USE_TASK_SCHEDULER_OBSERVER + ASSERT_WARNING( g_NumThreads == g_ActualMaxThreads, "Library did not provide sufficient threads"); +#endif + ASSERT_WARNING(n < c_Timeout,g_Wakeup_Msg); + // Workaround in case a missed wakeup takes place + if ( n == c_Timeout ) { + tbb::task &r = *new( tbb::task::allocate_root() ) tbb::empty_task(); + r.spawn(r); + n = 0; + goto retry; + } +} + +inline void WaitUntilConcurrencyPeaks () { WaitUntilConcurrencyPeaks(g_NumThreads); } + +inline bool IsMaster() { + return Harness::CurrentTid() == g_Master; +} + +inline bool IsThrowingThread() { + return g_ExceptionInMaster ^ IsMaster() ? true : false; +} + +class CancellatorTask : public tbb::task { + static volatile bool s_Ready; + tbb::task_group_context &m_groupToCancel; + intptr_t m_cancellationThreshold; + + tbb::task* execute () __TBB_override { + Harness::ConcurrencyTracker ct; + s_Ready = true; + while ( g_CurExecuted < m_cancellationThreshold ) + __TBB_Yield(); + m_groupToCancel.cancel_group_execution(); + g_ExecutedAtLastCatch = g_CurExecuted; + return NULL; + } +public: + CancellatorTask ( tbb::task_group_context& ctx, intptr_t threshold ) + : m_groupToCancel(ctx), m_cancellationThreshold(threshold) + { + s_Ready = false; + } + + static void Reset () { s_Ready = false; } + + static bool WaitUntilReady () { + const intptr_t limit = 10000000; + intptr_t n = 0; + do { + __TBB_Yield(); + } while( !s_Ready && ++n < limit ); + // should yield once, then continue if Cancellator is ready. + ASSERT( s_Ready || n == limit, NULL ); + return s_Ready; + } +}; + +volatile bool CancellatorTask::s_Ready = false; + +template<class LauncherTaskT, class CancellatorTaskT> +void RunCancellationTest ( intptr_t threshold = 1 ) +{ + tbb::task_group_context ctx; + tbb::empty_task &r = *new( tbb::task::allocate_root(ctx) ) tbb::empty_task; + r.set_ref_count(3); + r.spawn( *new( r.allocate_child() ) CancellatorTaskT(ctx, threshold) ); + __TBB_Yield(); + r.spawn( *new( r.allocate_child() ) LauncherTaskT(ctx) ); + TRY(); + r.wait_for_all(); + CATCH_AND_FAIL(); + r.destroy(r); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_fp.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_fp.h new file mode 100644 index 00000000..b007e2b8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_fp.h @@ -0,0 +1,168 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// include system header to prevent standard library to be included under private=public first time +#include <cstddef> +#define private public +#include "tbb/tbb_machine.h" +#undef private +#include "harness_assert.h" + +#if ( __TBB_x86_32 || __TBB_x86_64 ) && __TBB_CPU_CTL_ENV_PRESENT && !defined(__TBB_WIN32_USE_CL_BUILTINS) + +const int FE_TONEAREST = 0x0000, + FE_DOWNWARD = 0x0400, + FE_UPWARD = 0x0800, + FE_TOWARDZERO = 0x0c00, + FE_RND_MODE_MASK = FE_TOWARDZERO, + SSE_RND_MODE_MASK = FE_RND_MODE_MASK << 3, + SSE_DAZ = 0x0040, + SSE_FTZ = 0x8000, + SSE_MODE_MASK = SSE_DAZ | SSE_FTZ, + SSE_STATUS_MASK = 0x3F; + +const int NumSseModes = 4; +const int SseModes[NumSseModes] = { 0, SSE_DAZ, SSE_FTZ, SSE_DAZ | SSE_FTZ }; + +#if _WIN64 && !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE && !__MINGW64__ +// MinGW uses inline implementation from tbb/machine/linux_intel64.h +// and when inline asm is not available, the library uses out of line assembly which is not exported +// thus reimplementing them here + +#include <float.h> + +inline void __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* fe ) { + fe->x87cw = short(_control87(0, 0) & _MCW_RC) << 2; + fe->mxcsr = _mm_getcsr(); +} +inline void __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* fe ) { + ASSERT( (fe->x87cw & FE_RND_MODE_MASK) == ((fe->x87cw & FE_RND_MODE_MASK) >> 2 & _MCW_RC) << 2, "Check float.h constants" ); + _control87( (fe->x87cw & FE_RND_MODE_MASK) >> 6, _MCW_RC ); + _mm_setcsr( fe->mxcsr ); +} + +#endif /* _WIN64 && !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE && !__MINGW64__ */ + +inline int GetRoundingMode ( bool checkConsistency = true ) { + tbb::internal::cpu_ctl_env ctl; + ctl.get_env(); + ASSERT( !checkConsistency || (ctl.mxcsr & SSE_RND_MODE_MASK) >> 3 == (ctl.x87cw & FE_RND_MODE_MASK), NULL ); + return ctl.x87cw & FE_RND_MODE_MASK; +} + +inline void SetRoundingMode ( int mode ) { + tbb::internal::cpu_ctl_env ctl; + ctl.get_env(); + ctl.mxcsr = (ctl.mxcsr & ~SSE_RND_MODE_MASK) | (mode & FE_RND_MODE_MASK) << 3; + ctl.x87cw = short((ctl.x87cw & ~FE_RND_MODE_MASK) | (mode & FE_RND_MODE_MASK)); + ctl.set_env(); +} + +inline int GetSseMode () { + tbb::internal::cpu_ctl_env ctl; + ctl.get_env(); + return ctl.mxcsr & SSE_MODE_MASK; +} + +inline void SetSseMode ( int mode ) { + tbb::internal::cpu_ctl_env ctl; + ctl.get_env(); + ctl.mxcsr = (ctl.mxcsr & ~SSE_MODE_MASK) | (mode & SSE_MODE_MASK); + ctl.set_env(); +} + +#elif defined(_M_ARM) || defined(__TBB_WIN32_USE_CL_BUILTINS) +const int NumSseModes = 1; +const int SseModes[NumSseModes] = { 0 }; + +inline int GetSseMode () { return 0; } +inline void SetSseMode ( int ) {} + +const int FE_TONEAREST = _RC_NEAR, + FE_DOWNWARD = _RC_DOWN, + FE_UPWARD = _RC_UP, + FE_TOWARDZERO = _RC_CHOP; + +inline int GetRoundingMode ( bool = true ) { + tbb::internal::cpu_ctl_env ctl; + ctl.get_env(); + return ctl.my_ctl; +} +inline void SetRoundingMode ( int mode ) { + tbb::internal::cpu_ctl_env ctl; + ctl.my_ctl = mode; + ctl.set_env(); +} + +#else /* Other archs */ + +#include <fenv.h> + +const int RND_MODE_MASK = FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO; + +const int NumSseModes = 1; +const int SseModes[NumSseModes] = { 0 }; + +inline int GetRoundingMode ( bool = true ) { return fegetround(); } +inline void SetRoundingMode ( int rnd ) { fesetround(rnd); } + +inline int GetSseMode () { return 0; } +inline void SetSseMode ( int ) {} + +#endif /* Other archs */ + +const int NumRoundingModes = 4; +const int RoundingModes[NumRoundingModes] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO }; +const int numFPModes = NumRoundingModes*NumSseModes; + +inline void SetFPMode( int mode ) { + SetRoundingMode( RoundingModes[mode/NumSseModes%NumRoundingModes] ); + SetSseMode( SseModes[mode%NumSseModes] ); +} + +#define AssertFPMode( mode ) { \ + ASSERT( GetRoundingMode() == RoundingModes[mode/NumSseModes%NumRoundingModes], "FPU control state has not been set correctly." ); \ + ASSERT( GetSseMode() == SseModes[mode%NumSseModes], "SSE control state has not been set correctly." ); \ +} + +inline int SetNextFPMode( int mode, int step = 1 ) { + const int nextMode = (mode+step)%numFPModes; + SetFPMode( nextMode ); + return nextMode; +} + +class FPModeContext { + int origSse, origRounding; + int currentMode; +public: + FPModeContext(int newMode) { + origSse = GetSseMode(); + origRounding = GetRoundingMode(); + SetFPMode(currentMode = newMode); + } + ~FPModeContext() { + assertFPMode(); + SetRoundingMode(origRounding); + SetSseMode(origSse); + } + int setNextFPMode() { + assertFPMode(); + return currentMode = SetNextFPMode(currentMode); + } + void assertFPMode() { + AssertFPMode(currentMode); + } +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_graph.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_graph.h new file mode 100644 index 00000000..06176711 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_graph.h @@ -0,0 +1,1240 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** @file harness_graph.cpp + This contains common helper classes and functions for testing graph nodes +**/ + +#ifndef harness_graph_H +#define harness_graph_H + +#include "harness.h" +#include "harness_barrier.h" +#include "tbb/flow_graph.h" +#include "tbb/null_rw_mutex.h" +#include "tbb/atomic.h" +#include "tbb/concurrent_unordered_map.h" +#include "tbb/task.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/compat/condition_variable" +#include "tbb/mutex.h" +#include "tbb/tbb_thread.h" + +using tbb::flow::internal::SUCCESSFULLY_ENQUEUED; + +#define WAIT_MAX 2000000 +#define BACKOFF_WAIT(ex,msg) \ +{ \ + int wait_cnt = 0; \ + tbb::internal::atomic_backoff backoff; \ + do { \ + backoff.pause(); \ + ++wait_cnt; \ + } \ + while( (ex) && (wait_cnt < WAIT_MAX)); \ + ASSERT(wait_cnt < WAIT_MAX, msg); \ +} +#define BACKOFF_WAIT_NOASSERT(ex,msg) \ +{ \ + int wait_cnt = 0; \ + tbb::internal::atomic_backoff backoff; \ + do { \ + backoff.pause(); \ + ++wait_cnt; \ + } \ + while( (ex) && (wait_cnt < WAIT_MAX)); \ + if(wait_cnt >= WAIT_MAX) REMARK("%s\n",msg); \ +} + +// Needed conversion to and from continue_msg, but didn't want to add +// conversion operators to the class, since we don't want it in general, +// only in these tests. +template<typename InputType, typename OutputType> +struct converter { + static OutputType convert_value(const InputType &i) { + return OutputType(i); + } +}; + +template<typename InputType> +struct converter<InputType,tbb::flow::continue_msg> { + static tbb::flow::continue_msg convert_value(const InputType &/*i*/) { + return tbb::flow::continue_msg(); + } +}; + +template<typename OutputType> +struct converter<tbb::flow::continue_msg,OutputType> { + static OutputType convert_value(const tbb::flow::continue_msg &/*i*/) { + return OutputType(); + } +}; + +// helper for multifunction_node tests. +template<size_t N> +struct mof_helper { + template<typename InputType, typename ports_type> + static inline void output_converted_value(const InputType &i, ports_type &p) { + (void)tbb::flow::get<N-1>(p).try_put(converter<InputType,typename tbb::flow::tuple_element<N-1,ports_type>::type::output_type>::convert_value(i)); + output_converted_value<N-1>(i, p); + } +}; + +template<> +struct mof_helper<1> { + template<typename InputType, typename ports_type> + static inline void output_converted_value(const InputType &i, ports_type &p) { + // just emit a default-constructed object + (void)tbb::flow::get<0>(p).try_put(converter<InputType,typename tbb::flow::tuple_element<0,ports_type>::type::output_type>::convert_value(i)); + } +}; + +template< typename InputType, typename OutputType > +struct harness_graph_default_functor { + static OutputType construct( InputType v ) { + return OutputType(v); + } +}; + +template< typename OutputType > +struct harness_graph_default_functor< tbb::flow::continue_msg, OutputType > { + static OutputType construct( tbb::flow::continue_msg ) { + return OutputType(); + } +}; + +template< typename InputType > +struct harness_graph_default_functor< InputType, tbb::flow::continue_msg > { + static tbb::flow::continue_msg construct( InputType ) { + return tbb::flow::continue_msg(); + } +}; + +template< > +struct harness_graph_default_functor< tbb::flow::continue_msg, tbb::flow::continue_msg > { + static tbb::flow::continue_msg construct( tbb::flow::continue_msg ) { + return tbb::flow::continue_msg(); + } +}; + +template<typename InputType, typename OutputSet> +struct harness_graph_default_multifunction_functor { + static const int N = tbb::flow::tuple_size<OutputSet>::value; + typedef typename tbb::flow::multifunction_node<InputType,OutputSet>::output_ports_type ports_type; + static void construct(const InputType &i, ports_type &p) { + mof_helper<N>::output_converted_value(i, p); + } +}; + +//! An executor that accepts InputType and generates OutputType +template< typename InputType, typename OutputType > +struct harness_graph_executor { + + typedef OutputType (*function_ptr_type)( InputType v ); + + template<typename RW> + struct mutex_holder { static RW mutex; }; + + static function_ptr_type fptr; + static tbb::atomic<size_t> execute_count; + static tbb::atomic<size_t> current_executors; + static size_t max_executors; + + static inline OutputType func( InputType v ) { + size_t c; // Declaration separate from initialization to avoid ICC internal error on IA-64 architecture + c = current_executors.fetch_and_increment(); + ASSERT( max_executors == 0 || c <= max_executors, NULL ); + ++execute_count; + OutputType v2 = (*fptr)(v); + current_executors.fetch_and_decrement(); + return v2; + } + + template< typename RW > + static inline OutputType tfunc( InputType v ) { + // Invocations allowed to be concurrent, the lock is acquired in shared ("read") mode. + // A test can take it exclusively, thus creating a barrier for invocations. + typename RW::scoped_lock l( mutex_holder<RW>::mutex, /*write=*/false ); + return func(v); + } + + template< typename RW > + struct tfunctor { + tbb::atomic<size_t> my_execute_count; + tfunctor() { my_execute_count = 0; } + tfunctor( const tfunctor &f ) { my_execute_count = f.my_execute_count; } + OutputType operator()( InputType i ) { + typename RW::scoped_lock l( harness_graph_executor::mutex_holder<RW>::mutex, /*write=*/false ); + my_execute_count.fetch_and_increment(); + return harness_graph_executor::func(i); + } + }; + typedef tfunctor<tbb::null_rw_mutex> functor; + +}; + +//! A multifunction executor that accepts InputType and has only one Output of OutputType. +template< typename InputType, typename OutputTuple > +struct harness_graph_multifunction_executor { + typedef typename tbb::flow::multifunction_node<InputType,OutputTuple>::output_ports_type ports_type; + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type OutputType; + + typedef void (*mfunction_ptr_type)( const InputType& v, ports_type &p ); + + template<typename RW> + struct mutex_holder { static RW mutex; }; + + static mfunction_ptr_type fptr; + static tbb::atomic<size_t> execute_count; + static tbb::atomic<size_t> current_executors; + static size_t max_executors; + + static inline void empty_func( const InputType&, ports_type& ) { + } + + static inline void func( const InputType &v, ports_type &p ) { + size_t c; // Declaration separate from initialization to avoid ICC internal error on IA-64 architecture + c = current_executors.fetch_and_increment(); + ASSERT( max_executors == 0 || c <= max_executors, NULL ); + ASSERT(tbb::flow::tuple_size<OutputTuple>::value == 1, NULL); + ++execute_count; + (*fptr)(v,p); + current_executors.fetch_and_decrement(); + } + + template< typename RW > + static inline void tfunc( const InputType& v, ports_type &p ) { + // Shared lock in invocations, exclusive in a test; see a comment in harness_graph_executor. + typename RW::scoped_lock l( mutex_holder<RW>::mutex, /*write=*/false ); + func(v,p); + } + + template< typename RW > + struct tfunctor { + tbb::atomic<size_t> my_execute_count; + tfunctor() { my_execute_count = 0; } + tfunctor( const tfunctor &f ) { my_execute_count = f.my_execute_count; } + void operator()( const InputType &i, ports_type &p ) { + typename RW::scoped_lock l( harness_graph_multifunction_executor::mutex_holder<RW>::mutex, /*write=*/false ); + my_execute_count.fetch_and_increment(); + harness_graph_multifunction_executor::func(i,p); + } + }; + typedef tfunctor<tbb::null_rw_mutex> functor; + +}; + +// static vars for function_node tests +template< typename InputType, typename OutputType > +template< typename RW > +RW harness_graph_executor<InputType, OutputType>::mutex_holder<RW>::mutex; + +template< typename InputType, typename OutputType > +tbb::atomic<size_t> harness_graph_executor<InputType, OutputType>::execute_count; + +template< typename InputType, typename OutputType > +typename harness_graph_executor<InputType, OutputType>::function_ptr_type harness_graph_executor<InputType, OutputType>::fptr + = harness_graph_default_functor< InputType, OutputType >::construct; + +template< typename InputType, typename OutputType > +tbb::atomic<size_t> harness_graph_executor<InputType, OutputType>::current_executors; + +template< typename InputType, typename OutputType > +size_t harness_graph_executor<InputType, OutputType>::max_executors = 0; + +// static vars for multifunction_node tests +template< typename InputType, typename OutputTuple > +template< typename RW > +RW harness_graph_multifunction_executor<InputType, OutputTuple>::mutex_holder<RW>::mutex; + +template< typename InputType, typename OutputTuple > +tbb::atomic<size_t> harness_graph_multifunction_executor<InputType, OutputTuple>::execute_count; + +template< typename InputType, typename OutputTuple > +typename harness_graph_multifunction_executor<InputType, OutputTuple>::mfunction_ptr_type harness_graph_multifunction_executor<InputType, OutputTuple>::fptr + = harness_graph_default_multifunction_functor< InputType, OutputTuple >::construct; + +template< typename InputType, typename OutputTuple > +tbb::atomic<size_t> harness_graph_multifunction_executor<InputType, OutputTuple>::current_executors; + +template< typename InputType, typename OutputTuple > +size_t harness_graph_multifunction_executor<InputType, OutputTuple>::max_executors = 0; + +//! Counts the number of puts received +template< typename T > +struct harness_counting_receiver : public tbb::flow::receiver<T>, NoAssign { + + tbb::atomic< size_t > my_count; + T max_value; + size_t num_copies; + tbb::flow::graph& my_graph; + + harness_counting_receiver(tbb::flow::graph& g) : num_copies(1), my_graph(g) { + my_count = 0; + } + + void initialize_map( const T& m, size_t c ) { + my_count = 0; + max_value = m; + num_copies = c; + } + + tbb::flow::graph& graph_reference() const __TBB_override { + return my_graph; + } + + tbb::task *try_put_task( const T & ) __TBB_override { + ++my_count; + return const_cast<tbb::task *>(SUCCESSFULLY_ENQUEUED); + } + + void validate() { + size_t n = my_count; + ASSERT( n == num_copies*max_value, NULL ); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::receiver<T>::built_predecessors_type built_predecessors_type; + built_predecessors_type mbp; + built_predecessors_type &built_predecessors() __TBB_override { return mbp; } + typedef typename tbb::flow::receiver<T>::predecessor_list_type predecessor_list_type; + typedef typename tbb::flow::receiver<T>::predecessor_type predecessor_type; + void internal_add_built_predecessor(predecessor_type &) __TBB_override {} + void internal_delete_built_predecessor(predecessor_type &) __TBB_override {} + void copy_predecessors(predecessor_list_type &) __TBB_override { } + size_t predecessor_count() __TBB_override { return 0; } +#endif + void reset_receiver(tbb::flow::reset_flags /*f*/) __TBB_override { my_count = 0; } +}; + +//! Counts the number of puts received +template< typename T > +struct harness_mapped_receiver : public tbb::flow::receiver<T>, NoCopy { + + tbb::atomic< size_t > my_count; + T max_value; + size_t num_copies; + typedef tbb::concurrent_unordered_map< T, tbb::atomic< size_t > > map_type; + map_type *my_map; + tbb::flow::graph& my_graph; + + harness_mapped_receiver(tbb::flow::graph& g) : my_map(NULL), my_graph(g) { + my_count = 0; + } + + ~harness_mapped_receiver() { + if ( my_map ) delete my_map; + } + + void initialize_map( const T& m, size_t c ) { + my_count = 0; + max_value = m; + num_copies = c; + if ( my_map ) delete my_map; + my_map = new map_type; + } + + tbb::task * try_put_task( const T &t ) __TBB_override { + if ( my_map ) { + tbb::atomic<size_t> a; + a = 1; + std::pair< typename map_type::iterator, bool > r = (*my_map).insert( typename map_type::value_type( t, a ) ); + if ( r.second == false ) { + size_t v = r.first->second.fetch_and_increment(); + ASSERT( v < num_copies, NULL ); + } + } else { + ++my_count; + } + return const_cast<tbb::task *>(SUCCESSFULLY_ENQUEUED); + } + + tbb::flow::graph& graph_reference() const __TBB_override { + return my_graph; + } + + void validate() { + if ( my_map ) { + for ( size_t i = 0; i < (size_t)max_value; ++i ) { + size_t n = (*my_map)[(int)i]; + ASSERT( n == num_copies, NULL ); + } + } else { + size_t n = my_count; + ASSERT( n == num_copies*max_value, NULL ); + } + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::receiver<T>::built_predecessors_type built_predecessors_type; + built_predecessors_type mbp; + built_predecessors_type &built_predecessors() __TBB_override { return mbp; } + typedef typename tbb::flow::receiver<T>::predecessor_list_type predecessor_list_type; + typedef typename tbb::flow::receiver<T>::predecessor_type predecessor_type; + void internal_add_built_predecessor(predecessor_type &) __TBB_override {} + void internal_delete_built_predecessor(predecessor_type &) __TBB_override {} + void copy_predecessors(predecessor_list_type &) __TBB_override { } + size_t predecessor_count() __TBB_override { return 0; } +#endif + void reset_receiver(tbb::flow::reset_flags /*f*/) __TBB_override { + my_count = 0; + if(my_map) delete my_map; + my_map = new map_type; + } + +}; + +//! Counts the number of puts received +template< typename T > +struct harness_counting_sender : public tbb::flow::sender<T>, NoCopy { + + typedef typename tbb::flow::sender<T>::successor_type successor_type; + tbb::atomic< successor_type * > my_receiver; + tbb::atomic< size_t > my_count; + tbb::atomic< size_t > my_received; + size_t my_limit; + + harness_counting_sender( ) : my_limit(~size_t(0)) { + my_receiver = NULL; + my_count = 0; + my_received = 0; + } + + harness_counting_sender( size_t limit ) : my_limit(limit) { + my_receiver = NULL; + my_count = 0; + my_received = 0; + } + + bool register_successor( successor_type &r ) __TBB_override { + my_receiver = &r; + return true; + } + + bool remove_successor( successor_type &r ) __TBB_override { + successor_type *s = my_receiver.fetch_and_store( NULL ); + ASSERT( s == &r, NULL ); + return true; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::sender<T>::successor_list_type successor_list_type; + typedef typename tbb::flow::sender<T>::built_successors_type built_successors_type; + built_successors_type bst; + built_successors_type &built_successors() __TBB_override { return bst; } + void internal_add_built_successor( successor_type &) __TBB_override {} + void internal_delete_built_successor( successor_type &) __TBB_override {} + void copy_successors(successor_list_type &) __TBB_override { } + size_t successor_count() __TBB_override { return 0; } +#endif + + bool try_get( T & v ) __TBB_override { + size_t i = my_count.fetch_and_increment(); + if ( i < my_limit ) { + v = T( i ); + ++my_received; + return true; + } else { + return false; + } + } + + bool try_put_once() { + successor_type *s = my_receiver; + size_t i = my_count.fetch_and_increment(); + if ( s->try_put( T(i) ) ) { + ++my_received; + return true; + } else { + return false; + } + } + + void try_put_until_false() { + successor_type *s = my_receiver; + size_t i = my_count.fetch_and_increment(); + + while ( s->try_put( T(i) ) ) { + ++my_received; + i = my_count.fetch_and_increment(); + } + } + + void try_put_until_limit() { + successor_type *s = my_receiver; + + for ( int i = 0; i < (int)my_limit; ++i ) { + ASSERT( s->try_put( T(i) ), NULL ); + ++my_received; + } + ASSERT( my_received == my_limit, NULL ); + } + +}; + +// test for resets of buffer-type nodes. +tbb::atomic<int> serial_fn_state0; +tbb::atomic<int> serial_fn_state1; +tbb::atomic<int> serial_continue_state0; + +template<typename T> +struct serial_fn_body { + tbb::atomic<int> *_flag; + serial_fn_body(tbb::atomic<int> &myatomic) : _flag(&myatomic) { } + T operator()(const T& in) { + if(*_flag == 0) { + *_flag = 1; + // wait until we are released + tbb::internal::atomic_backoff backoff; + do { + backoff.pause(); + } while(*_flag == 1); + } + // return value + return in; + } +}; + +template<typename T> +struct serial_continue_body { + tbb::atomic<int> *_flag; + serial_continue_body(tbb::atomic<int> &myatomic) : _flag(&myatomic) {} + T operator()(const tbb::flow::continue_msg& /*in*/) { + // signal we have received a value + *_flag = 1; + // wait until we are released + tbb::internal::atomic_backoff backoff; + do { + backoff.pause(); + } while(*_flag == 1); + // return value + return (T)1; + } +}; + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + + +// walk two lists via iterator, match elements of each, in possibly-different ordder, and +// return true if all elements of sv appear in tv. +template<typename SV, typename TV> +bool lists_match(SV &sv, TV &tv) { + if(sv.size() != tv.size()) { + return false; + } + std::vector<bool> bv(sv.size(), false); + for(typename TV::iterator itv = tv.begin(); itv != tv.end(); ++itv) { + int ibv = 0; + for(typename SV::iterator isv = sv.begin(); isv != sv.end(); ++isv) { + if(!bv[ibv]) { + if(*itv == *isv) { + bv[ibv] = true; + goto found_it;; + } + } + ++ibv; + } + return false; +found_it: + continue; + } + return true; +} +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +template<typename T, typename BufferType> +void test_resets() { + const int NN = 3; + tbb::task_scheduler_init init(4); + tbb::task_group_context tgc; + tbb::flow::graph g(tgc); + BufferType b0(g); + tbb::flow::queue_node<T> q0(g); + T j; + bool nFound[NN]; + + // reset empties buffer + for(T i = 0; i < NN; ++i) { + b0.try_put(i); + nFound[(int)i] = false; + } + g.wait_for_all(); + g.reset(); + ASSERT(!b0.try_get(j), "reset did not empty buffer"); + + // reset doesn't delete edge + + tbb::flow::make_edge(b0,q0); + g.reset(); + for(T i = 0; i < NN; ++i) { + b0.try_put(i); + } + + g.wait_for_all(); + for( T i = 0; i < NN; ++i) { + ASSERT(q0.try_get(j), "Missing value from buffer"); + ASSERT(!nFound[(int)j], "Duplicate value found"); + nFound[(int)j] = true; + } + + for(int ii = 0; ii < NN; ++ii) { + ASSERT(nFound[ii], "missing value"); + } + ASSERT(!q0.try_get(j), "Extra values in output"); + + // reset reverses a reversed edge. + // we will use a serial rejecting node to get the edge to reverse. + tbb::flow::function_node<T, T, tbb::flow::rejecting> sfn(g, tbb::flow::serial, serial_fn_body<T>(serial_fn_state0)); + tbb::flow::queue_node<T> outq(g); + tbb::flow::remove_edge(b0,q0); + tbb::flow::make_edge(b0, sfn); + tbb::flow::make_edge(sfn,outq); + g.wait_for_all(); // wait for all the tasks started by building the graph are done. + serial_fn_state0 = 0; + + // b0 ------> sfn ------> outq + + for(int icnt = 0; icnt < 2; ++icnt) { + g.wait_for_all(); + serial_fn_state0 = 0; + b0.try_put((T)0); // will start sfn + // wait until function_node starts + BACKOFF_WAIT(serial_fn_state0 == 0,"Timed out waiting for function_node to start"); + // now the function_node is executing. + // this will start a task to forward the second item + // to the serial function node + b0.try_put((T)1); // first item will be consumed by task completing the execution + BACKOFF_WAIT_NOASSERT(g.root_task()->ref_count() >= 3,"Timed out waiting try_put task to wind down"); + b0.try_put((T)2); // second item will remain after cancellation + // now wait for the task that attempts to forward the buffer item to + // complete. + BACKOFF_WAIT_NOASSERT(g.root_task()->ref_count() >= 3,"Timed out waiting for tasks to wind down"); + // now cancel the graph. + ASSERT(tgc.cancel_group_execution(), "task group already cancelled"); + serial_fn_state0 = 0; // release the function_node. + g.wait_for_all(); // wait for all the tasks to complete. + // check that at most one output reached the queue_node + T outt; + T outt2; + bool got_item1 = outq.try_get(outt); + bool got_item2 = outq.try_get(outt2); + // either the output queue was empty (if the function_node tested for cancellation before putting the + // result to the queue) or there was one element in the queue (the 0). + ASSERT(!got_item1 || ((int)outt == 0 && !got_item2), "incorrect output from function_node"); + // the edge between the buffer and the function_node should be reversed, and the last + // message we put in the buffer should still be there. We can't directly test for the + // edge reversal. + got_item1 = b0.try_get(outt); + ASSERT(got_item1, " buffer lost a message"); + ASSERT(2 == (int)outt || 1 == (int)outt, " buffer had incorrect message"); // the one not consumed by the node. + ASSERT(g.is_cancelled(), "Graph was not cancelled"); + g.reset(); + } // icnt + + // reset with remove_edge removes edge. (icnt ==0 => forward edge, 1 => reversed edge + for(int icnt = 0; icnt < 2; ++icnt) { + if(icnt == 1) { + // set up reversed edge + tbb::flow::make_edge(b0, sfn); + tbb::flow::make_edge(sfn,outq); + serial_fn_state0 = 0; + b0.try_put((T)0); // starts up the function node + b0.try_put((T)1); // shoyuld reverse the edge + BACKOFF_WAIT(serial_fn_state0 == 0,"Timed out waiting for edge reversal"); + ASSERT(tgc.cancel_group_execution(), "task group already cancelled"); + serial_fn_state0 = 0; // release the function_node. + g.wait_for_all(); // wait for all the tasks to complete. + } + g.reset(tbb::flow::rf_clear_edges); + // test that no one is a successor to the buffer now. + serial_fn_state0 = 1; // let the function_node go if it gets an input message + b0.try_put((T)23); + g.wait_for_all(); + ASSERT((int)serial_fn_state0 == 1, "function_node executed when it shouldn't"); + T outt; + ASSERT(b0.try_get(outt) && (T)23 == outt, "node lost its input"); + } +} + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + +template< typename NODE_TYPE > +class test_buffer_base_extract { +protected: + tbb::flow::graph &g; + NODE_TYPE &in0; + NODE_TYPE &in1; + NODE_TYPE &middle; + NODE_TYPE &out0; + NODE_TYPE &out1; + NODE_TYPE *ins[2]; + NODE_TYPE *outs[2]; + typename NODE_TYPE::successor_type *ms_ptr; + typename NODE_TYPE::predecessor_type *mp_ptr; + + typename NODE_TYPE::predecessor_list_type in0_p_list; + typename NODE_TYPE::successor_list_type in0_s_list; + typename NODE_TYPE::predecessor_list_type in1_p_list; + typename NODE_TYPE::successor_list_type in1_s_list; + typename NODE_TYPE::predecessor_list_type out0_p_list; + typename NODE_TYPE::successor_list_type out0_s_list; + typename NODE_TYPE::predecessor_list_type out1_p_list; + typename NODE_TYPE::successor_list_type out1_s_list; + typename NODE_TYPE::predecessor_list_type mp_list; + typename NODE_TYPE::predecessor_list_type::iterator mp_list_iter; + typename NODE_TYPE::successor_list_type ms_list; + typename NODE_TYPE::successor_list_type::iterator ms_list_iter; + + virtual void set_up_lists() { + in0_p_list.clear(); + in0_s_list.clear(); + in1_p_list.clear(); + in1_s_list.clear(); + mp_list.clear(); + ms_list.clear(); + out0_p_list.clear(); + out0_s_list.clear(); + out1_p_list.clear(); + out1_s_list.clear(); + in0.copy_predecessors(in0_p_list); + in0.copy_successors(in0_s_list); + in1.copy_predecessors(in1_p_list); + in1.copy_successors(in1_s_list); + middle.copy_predecessors(mp_list); + middle.copy_successors(ms_list); + out0.copy_predecessors(out0_p_list); + out0.copy_successors(out0_s_list); + out1.copy_predecessors(out1_p_list); + out1.copy_successors(out1_s_list); + } + + void make_and_validate_full_graph() { + /* in0 out0 */ + /* \ / */ + /* middle */ + /* / \ */ + /* in1 out1 */ + tbb::flow::make_edge( in0, middle ); + tbb::flow::make_edge( in1, middle ); + tbb::flow::make_edge( middle, out0 ); + tbb::flow::make_edge( middle, out1 ); + + set_up_lists(); + + ASSERT( in0.predecessor_count() == 0 && in0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in0.successor_count() == 1 && in0_s_list.size() == 1 && *(in0_s_list.begin()) == ms_ptr, "expected 1 successor" ); + ASSERT( in1.predecessor_count() == 0 && in1_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in1.successor_count() == 1 && in1_s_list.size() == 1 && *(in1_s_list.begin()) == ms_ptr, "expected 1 successor" ); + ASSERT( middle.predecessor_count() == 2 && mp_list.size() == 2, "expected 2 predecessors" ); + ASSERT( middle.successor_count() == 2 && ms_list.size() == 2, "expected 2 successors" ); + ASSERT( out0.predecessor_count() == 1 && out0_p_list.size() == 1 && *(out0_p_list.begin()) == mp_ptr, "expected 1 predecessor" ); + ASSERT( out0.successor_count() == 0 && out0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( out1.predecessor_count() == 1 && out1_p_list.size() == 1 && *(out1_p_list.begin()) == mp_ptr, "expected 1 predecessor" ); + ASSERT( out1.successor_count() == 0 && out1_s_list.size() == 0, "expected 0 successors" ); + + int first_pred = *(mp_list.begin()) == ins[0] ? 0 : ( *(mp_list.begin()) == ins[1] ? 1 : -1 ); + mp_list_iter = mp_list.begin(); ++mp_list_iter; + int second_pred = *mp_list_iter == ins[0] ? 0 : ( *mp_list_iter == ins[1] ? 1 : -1 ); + ASSERT( first_pred != -1 && second_pred != -1 && first_pred != second_pred, "bad predecessor(s) for middle" ); + + int first_succ = *(ms_list.begin()) == outs[0] ? 0 : ( *(ms_list.begin()) == outs[1] ? 1 : -1 ); + ms_list_iter = ++(ms_list.begin()); + int second_succ = *ms_list_iter == outs[0] ? 0 : ( *ms_list_iter == outs[1] ? 1 : -1 ); + ASSERT( first_succ != -1 && second_succ != -1 && first_succ != second_succ, "bad successor(s) for middle" ); + + in0.try_put(1); + in1.try_put(2); + g.wait_for_all(); + + int r = 0; + int v = 0; + + ASSERT( in0.try_get(v) == false, "buffer should not have a value" ); + ASSERT( in1.try_get(v) == false, "buffer should not have a value" ); + ASSERT( middle.try_get(v) == false, "buffer should not have a value" ); + while ( out0.try_get(v) ) { + ASSERT( (v == 1 || v == 2) && (v&r) == 0, "duplicate value" ); + r |= v; + g.wait_for_all(); + } + while ( out1.try_get(v) ) { + ASSERT( (v == 1 || v == 2) && (v&r) == 0, "duplicate value" ); + r |= v; + g.wait_for_all(); + } + ASSERT( r == 3, "not all values received" ); + g.wait_for_all(); + } + + void validate_half_graph() { + /* in0 out0 */ + /* */ + /* middle */ + /* / \ */ + /* in1 out1 */ + set_up_lists(); + + ASSERT( in0.predecessor_count() == 0 && in0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in0.successor_count() == 0 && in0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( in1.predecessor_count() == 0 && in1_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in1.successor_count() == 1 && in1_s_list.size() == 1 && *(in1_s_list.begin()) == ms_ptr, "expected 1 successor" ); + ASSERT( middle.predecessor_count() == 1 && mp_list.size() == 1, "expected 1 predecessor" ); + ASSERT( middle.successor_count() == 1 && ms_list.size() == 1, "expected 1 successor" ); + ASSERT( out0.predecessor_count() == 0 && out0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( out0.successor_count() == 0 && out0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( out1.predecessor_count() == 1 && out1_p_list.size() == 1 && *(out1_p_list.begin()) == mp_ptr, "expected 1 predecessor" ); + ASSERT( out1.successor_count() == 0 && out1_s_list.size() == 0, "expected 0 successors" ); + + ASSERT( middle.predecessor_count() == 1 && mp_list.size() == 1, "expected two predecessors" ); + ASSERT( middle.successor_count() == 1 && ms_list.size() == 1, "expected two successors" ); + + ASSERT( *(mp_list.begin()) == ins[1], "incorrect predecessor" ); + ASSERT( *(ms_list.begin()) == outs[1], "incorrect successor" ); + + in0.try_put(1); + in1.try_put(2); + g.wait_for_all(); + + int v = 0; + ASSERT( in0.try_get(v) == true && v == 1, "buffer should have a value of 1" ); + ASSERT( in1.try_get(v) == false, "buffer should not have a value" ); + ASSERT( middle.try_get(v) == false, "buffer should not have a value" ); + ASSERT( out0.try_get(v) == false, "buffer should not have a value" ); + ASSERT( out1.try_get(v) == true && v == 2, "buffer should have a value of 2" ); + g.wait_for_all(); + } + + void validate_empty_graph() { + /* in0 out0 */ + /* */ + /* middle */ + /* */ + /* in1 out1 */ + set_up_lists(); + + ASSERT( in0.predecessor_count() == 0 && in0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in0.successor_count() == 0 && in0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( in1.predecessor_count() == 0 && in1_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in1.successor_count() == 0 && in1_s_list.size() == 0, "expected 0 successors" ); + ASSERT( middle.predecessor_count() == 0 && mp_list.size() == 0, "expected 0 predecessors" ); + ASSERT( middle.successor_count() == 0 && ms_list.size() == 0, "expected 0 successors" ); + ASSERT( out0.predecessor_count() == 0 && out0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( out0.successor_count() == 0 && out0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( out1.predecessor_count() == 0 && out1_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( out1.successor_count() == 0 && out1_s_list.size() == 0, "expected 0 successors" ); + + ASSERT( middle.predecessor_count() == 0 && mp_list.size() == 0, "expected 0 predecessors" ); + ASSERT( middle.successor_count() == 0 && ms_list.size() == 0, "expected 0 successors" ); + + in0.try_put(1); + in1.try_put(2); + g.wait_for_all(); + + int v = 0; + ASSERT( in0.try_get(v) == true && v == 1, "buffer should have a value of 1" ); + ASSERT( in1.try_get(v) == true && v == 2, "buffer should have a value of 2" ); + ASSERT( middle.try_get(v) == false, "buffer should not have a value" ); + ASSERT( out0.try_get(v) == false, "buffer should not have a value" ); + ASSERT( out1.try_get(v) == false, "buffer should not have a value" ); + g.wait_for_all(); + } + + // forbid the ecompiler generation of operator= (VS2012 warning) + test_buffer_base_extract& operator=(test_buffer_base_extract & /*other*/); + +public: + + test_buffer_base_extract(tbb::flow::graph &_g, NODE_TYPE &i0, NODE_TYPE &i1, NODE_TYPE &m, NODE_TYPE &o0, NODE_TYPE &o1) : + g(_g), in0(i0), in1(i1), middle(m), out0(o0), out1(o1) { + ins[0] = &in0; + ins[1] = &in1; + outs[0] = &out0; + outs[1] = &out1; + ms_ptr = static_cast< typename NODE_TYPE::successor_type * >(&middle); + mp_ptr = static_cast< typename NODE_TYPE::predecessor_type *>(&middle); + } + + virtual ~test_buffer_base_extract() {} + + void run_tests() { + make_and_validate_full_graph(); + + in0.extract(); + out0.extract(); + validate_half_graph(); + + in1.extract(); + out1.extract(); + validate_empty_graph(); + + make_and_validate_full_graph(); + + middle.extract(); + validate_empty_graph(); + + make_and_validate_full_graph(); + } + +}; + +template< typename NODE_TYPE > +class test_buffer_extract : public test_buffer_base_extract<NODE_TYPE> { +protected: + tbb::flow::graph my_g; + NODE_TYPE my_in0; + NODE_TYPE my_in1; + NODE_TYPE my_middle; + NODE_TYPE my_out0; + NODE_TYPE my_out1; +public: + test_buffer_extract() : test_buffer_base_extract<NODE_TYPE>( my_g, my_in0, my_in1, my_middle, my_out0, my_out1), + my_in0(my_g), my_in1(my_g), my_middle(my_g), my_out0(my_g), my_out1(my_g) { } +}; + +template< > +class test_buffer_extract< tbb::flow::sequencer_node<int> > : public test_buffer_base_extract< tbb::flow::sequencer_node<int> > { +protected: + typedef tbb::flow::sequencer_node<int> my_node_t; + tbb::flow::graph my_g; + my_node_t my_in0; + my_node_t my_in1; + my_node_t my_middle; + my_node_t my_out0; + my_node_t my_out1; + + typedef tbb::atomic<size_t> count_t; + count_t middle_count; + count_t out0_count; + count_t out1_count; + + struct always_zero { size_t operator()(int) { return 0; } }; + struct always_inc { + count_t *c; + always_inc(count_t &_c) : c(&_c) {} + size_t operator()(int) { + return c->fetch_and_increment(); + } + }; + + void set_up_lists() __TBB_override { + middle_count = 0; + out0_count = 0; + out1_count = 0; + my_g.reset(); // reset the sequencer nodes to start at 0 again + test_buffer_base_extract< my_node_t >::set_up_lists(); + } + + +public: + test_buffer_extract() : test_buffer_base_extract<my_node_t>( my_g, my_in0, my_in1, my_middle, my_out0, my_out1), + my_in0(my_g, always_zero()), my_in1(my_g, always_zero()), my_middle(my_g, always_inc(middle_count)), + my_out0(my_g, always_inc(out0_count)), my_out1(my_g, always_inc(out1_count)) { + } +}; + +// test for simple node that has one input, one output (overwrite_node, write_once_node, limiter_node) +// decrement tests have to be done separately. +template<template< class > class NType, typename ItemType> +void test_extract_on_node() { + tbb::flow::graph g; + ItemType dont_care; + NType<ItemType> node0(g); + tbb::flow::queue_node<ItemType> q0(g); + tbb::flow::queue_node<ItemType> q1(g); + tbb::flow::queue_node<ItemType> q2(g); + for( int i = 0; i < 2; ++i) { + tbb::flow::make_edge(q0,node0); + tbb::flow::make_edge(q1,node0); + tbb::flow::make_edge(node0, q2); + q0.try_put(ItemType(i)); + g.wait_for_all(); + + /* q0 */ + /* \ */ + /* \ */ + /* node0 -- q2 */ + /* / */ + /* / */ + /* q1 */ + + ASSERT(node0.predecessor_count() == 2 && q0.successor_count() == 1 && q1.successor_count() == 1, "bad predecessor count"); + ASSERT(node0.successor_count() == 1 && q2.predecessor_count() == 1, "bad successor count"); + + ASSERT(q2.try_get(dont_care) && int(dont_care) == i, "item not forwarded"); + typename NType<ItemType>::successor_list_type sv, sv1; + typename NType<ItemType>::predecessor_list_type pv, pv1; + + pv1.push_back(&q0); + pv1.push_back(&q1); + sv1.push_back(&q2); + node0.copy_predecessors(pv); + node0.copy_successors(sv); + ASSERT(lists_match(pv,pv1), "predecessor vector incorrect"); + ASSERT(lists_match(sv,sv1), "successor vector incorrect"); + + if(i == 0) { + node0.extract(); + } + else { + q0.extract(); + q1.extract(); + q2.extract(); + } + + q0.try_put(ItemType(2)); + g.wait_for_all(); + ASSERT(!q2.try_get(dont_care), "node0 not disconnected"); + ASSERT(q0.try_get(dont_care), "q0 empty (should have one item)"); + + node0.copy_predecessors(pv); + node0.copy_successors(sv); + ASSERT(node0.predecessor_count() == 0 && q0.successor_count() == 0 && q1.successor_count() == 0, "error in pred count after extract"); + ASSERT(pv.size() == 0, "error in pred array count after extract"); + ASSERT(node0.successor_count() == 0 && q2.predecessor_count() == 0, "error in succ count after extract"); + ASSERT(sv.size() == 0, "error in succ array count after extract"); + g.wait_for_all(); + } +} + +#endif // TBB_DEPRECATED_FLOW_NODE_EXTRACTION + +template<typename NodeType> +void test_input_ports_return_ref(NodeType& mip_node) { + typename NodeType::input_ports_type& input_ports1 = mip_node.input_ports(); + typename NodeType::input_ports_type& input_ports2 = mip_node.input_ports(); + ASSERT(&input_ports1 == &input_ports2, "input_ports() should return reference"); +} + +template<typename NodeType> +void test_output_ports_return_ref(NodeType& mop_node) { + typename NodeType::output_ports_type& output_ports1 = mop_node.output_ports(); + typename NodeType::output_ports_type& output_ports2 = mop_node.output_ports(); + ASSERT(&output_ports1 == &output_ports2, "output_ports() should return reference"); +} + +template< template <typename> class ReservingNodeType, typename DataType, bool DoClear > +class harness_reserving_body : NoAssign { + ReservingNodeType<DataType> &my_reserving_node; + tbb::flow::buffer_node<DataType> &my_buffer_node; +public: + harness_reserving_body(ReservingNodeType<DataType> &reserving_node, tbb::flow::buffer_node<DataType> &bn) : my_reserving_node(reserving_node), my_buffer_node(bn) {} + void operator()(DataType i) const { + my_reserving_node.try_put(i); +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (push) +#pragma warning (disable: 4127) /* suppress conditional expression is constant */ +#endif + if (DoClear) { +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (pop) +#endif + my_reserving_node.clear(); + } + my_buffer_node.try_put(i); + my_reserving_node.try_put(i); + } +}; + +template< template <typename> class ReservingNodeType, typename DataType > +void test_reserving_nodes() { + const size_t N = 300; + + tbb::flow::graph g; + + ReservingNodeType<DataType> reserving_n(g); + + tbb::flow::buffer_node<DataType> buffering_n(g); + tbb::flow::join_node< tbb::flow::tuple<DataType, DataType>, tbb::flow::reserving > join_n(g); + harness_counting_receiver< tbb::flow::tuple<DataType, DataType> > end_receiver(g); + + tbb::flow::make_edge(reserving_n, tbb::flow::input_port<0>(join_n)); + tbb::flow::make_edge(buffering_n, tbb::flow::input_port<1>(join_n)); + tbb::flow::make_edge(join_n, end_receiver); + + NativeParallelFor(N, harness_reserving_body<ReservingNodeType, DataType, false>(reserving_n, buffering_n)); + g.wait_for_all(); + + ASSERT(end_receiver.my_count == N, NULL); + + // Should not hang + NativeParallelFor(N, harness_reserving_body<ReservingNodeType, DataType, true>(reserving_n, buffering_n)); + g.wait_for_all(); + + ASSERT(end_receiver.my_count == 2 * N, NULL); +} + +namespace lightweight_testing { + +typedef tbb::flow::tuple<int, int> output_tuple_type; + +template<typename NodeType> +class native_loop_body : NoAssign { + NodeType& my_node; +public: + native_loop_body(NodeType& node) : my_node(node) {} + + void operator()(int) const { + tbb::tbb_thread::id this_id = tbb::this_tbb_thread::get_id(); + my_node.try_put(this_id); + } +}; + +class concurrency_checker_body { +public: + tbb::atomic<unsigned> my_body_count; + + concurrency_checker_body() { + my_body_count = 0; + } + + template<typename gateway_type> + void operator()(const tbb::tbb_thread::id& input, gateway_type&) { + increase_and_check(input); + } + + output_tuple_type operator()(const tbb::tbb_thread::id& input) { + increase_and_check(input); + return output_tuple_type(); + } + +private: + void increase_and_check(const tbb::tbb_thread::id& input) { + ++my_body_count; + tbb::tbb_thread::id body_thread_id = tbb::this_tbb_thread::get_id(); + ASSERT(input == body_thread_id, "Body executed as not lightweight"); + } +}; + +template<typename NodeType> +void test_unlimited_lightweight_execution(unsigned N) { + tbb::flow::graph g; + NodeType node(g, tbb::flow::unlimited, concurrency_checker_body()); + + NativeParallelFor(N, native_loop_body<NodeType>(node)); + g.wait_for_all(); + + concurrency_checker_body body = tbb::flow::copy_body<concurrency_checker_body>(node); + ASSERT(body.my_body_count == N, "Body needs to be executed N times"); +} + +// Using TBB implementation of condition variable +// not to include std header, which has problems with old GCC +using tbb::interface5::condition_variable; +using tbb::interface5::unique_lock; + +tbb::mutex m; +condition_variable lightweight_condition; +bool work_submitted; +bool lightweight_work_processed; + +template<typename NodeType> +class native_loop_limited_body : NoAssign { + NodeType& my_node; + Harness::SpinBarrier& my_barrier; +public: + native_loop_limited_body(NodeType& node, Harness::SpinBarrier& barrier): + my_node(node), my_barrier(barrier) {} + void operator()(int) const { + tbb::tbb_thread::id this_id = tbb::this_tbb_thread::get_id(); + my_node.try_put(this_id); + if(!lightweight_work_processed) { + my_barrier.wait(); + work_submitted = true; + lightweight_condition.notify_all(); + } + } +}; + +struct condition_predicate { + bool operator()() { + return work_submitted; + } +}; + +class limited_lightweight_checker_body { +public: + tbb::atomic<unsigned> my_body_count; + tbb::atomic<unsigned> my_lightweight_count; + tbb::atomic<unsigned> my_task_count; + limited_lightweight_checker_body() { + my_body_count = 0; + my_lightweight_count = 0; + my_task_count = 0; + } +private: + void increase_and_check(const tbb::tbb_thread::id& /*input*/) { + ++my_body_count; + bool is_task = tbb::task::self().state() == tbb::task::executing; + if(is_task) { + ++my_task_count; + } else { + unique_lock<tbb::mutex> lock(m); + lightweight_condition.wait(lock, condition_predicate()); + ++my_lightweight_count; + lightweight_work_processed = true; + } + } +public: + template<typename gateway_type> + void operator()(const tbb::tbb_thread::id& input, gateway_type&) { + increase_and_check(input); + } + output_tuple_type operator()(const tbb::tbb_thread::id& input) { + increase_and_check(input); + return output_tuple_type(); + } +}; + +template<typename NodeType> +void test_limited_lightweight_execution(unsigned N, unsigned concurrency) { + ASSERT(concurrency != tbb::flow::unlimited, + "Test for limited concurrency cannot be called with unlimited concurrency argument"); + tbb::flow::graph g; + NodeType node(g, concurrency, limited_lightweight_checker_body()); + // Execute first body as lightweight, then wait for all other threads to fill internal buffer. + // Then unblock the lightweightd thread and check if other body executions are inside TBB task. + Harness::SpinBarrier barrier(N - concurrency); + NativeParallelFor(N, native_loop_limited_body<NodeType>(node, barrier)); + g.wait_for_all(); + limited_lightweight_checker_body body = tbb::flow::copy_body<limited_lightweight_checker_body>(node); + ASSERT(body.my_body_count == N, "Body needs to be executed N times"); + ASSERT(body.my_lightweight_count == concurrency, "Body needs to be executed as lightweight once"); + ASSERT(body.my_task_count == N - concurrency, "Body needs to be executed as not lightweight N - 1 times"); + work_submitted = false; + lightweight_work_processed = false; +} + +template<typename NodeType> +void test_lightweight(unsigned N) { + test_unlimited_lightweight_execution<NodeType>(N); + test_limited_lightweight_execution<NodeType>(N, tbb::flow::serial); + test_limited_lightweight_execution<NodeType>(N, (std::min)(tbb::tbb_thread::hardware_concurrency() / 2, N/2)); +} + +template<template<typename, typename, typename, typename> class NodeType> +void test(unsigned N) { + typedef tbb::tbb_thread::id input_type; +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + typedef tbb::cache_aligned_allocator<input_type> allocator_type; +#else + typedef tbb::flow::interface11::null_type allocator_type; +#endif + typedef NodeType<input_type, output_tuple_type, tbb::flow::queueing_lightweight, allocator_type> node_type; + test_lightweight<node_type>(N); +} + +} + +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_inject_scheduler.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_inject_scheduler.h new file mode 100644 index 00000000..2c792bcf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_inject_scheduler.h @@ -0,0 +1,82 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Used in tests that work with TBB scheduler but do not link to the TBB library. +// In other words it embeds the TBB library core into the test executable. + +#ifndef harness_inject_scheduler_H +#define harness_inject_scheduler_H + +#if HARNESS_DEFINE_PRIVATE_PUBLIC +#include <string> // merely prevents LNK2019 error to happen (on ICL+VC9 configurations) +#include <algorithm> // include it first to avoid error on define below +#define private public +#define protected public +#endif + +// Suppress usage of #pragma comment +#define __TBB_NO_IMPLICIT_LINKAGE 1 + +// Enable preview features if any +#define __TBB_BUILD 1 + +#undef DO_ITT_NOTIFY + +#define __TBB_SOURCE_DIRECTLY_INCLUDED 1 +#include "../tbb/tbb_main.cpp" +#include "../tbb/dynamic_link.cpp" +#include "../tbb/tbb_misc_ex.cpp" + +// Tasking subsystem files +#include "../tbb/governor.cpp" +#include "../tbb/market.cpp" +#include "../tbb/arena.cpp" +#include "../tbb/scheduler.cpp" +#include "../tbb/observer_proxy.cpp" +#include "../tbb/task.cpp" +#include "../tbb/task_group_context.cpp" + +// Other dependencies +#include "../tbb/cache_aligned_allocator.cpp" +#include "../tbb/tbb_thread.cpp" +#include "../tbb/mutex.cpp" +#include "../tbb/spin_rw_mutex.cpp" +#include "../tbb/spin_mutex.cpp" +#include "../tbb/private_server.cpp" +#include "../tbb/concurrent_monitor.cpp" +#if _WIN32||_WIN64 +#include "../tbb/semaphore.cpp" +#endif +#include "../rml/client/rml_tbb.cpp" + +#if HARNESS_USE_RUNTIME_LOADER +#undef HARNESS_USE_RUNTIME_LOADER +#include "harness.h" + +int TestMain () { + // Tests that directly include sources make no sense in runtime loader testing mode. + return Harness::Skipped; +} +// Renaming the TestMain function avoids conditional compilation around same function in the test file +#define TestMain TestMainSkipped +#endif + +#if HARNESS_DEFINE_PRIVATE_PUBLIC +#undef protected +#undef private +#endif + +#endif /* harness_inject_scheduler_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_iterator.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_iterator.h new file mode 100644 index 00000000..a6a8722c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_iterator.h @@ -0,0 +1,160 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef harness_iterator_H +#define harness_iterator_H + +#include <iterator> +#include <memory> +#include "tbb/atomic.h" +#include "harness_assert.h" + +namespace Harness { + +template <typename T> +class InputIterator { +public: + typedef std::input_iterator_tag iterator_category; + typedef T value_type; + typedef typename std::allocator<T>::difference_type difference_type; + typedef typename std::allocator<T>::pointer pointer; + typedef typename std::allocator<T>::reference reference; + + explicit InputIterator ( T * ptr ) : my_ptr(ptr), my_shared_epoch(new Epoch), my_current_epoch(0) {} + + InputIterator( const InputIterator& it ) { + ASSERT(it.my_current_epoch == it.my_shared_epoch->epoch, "Copying an invalidated iterator"); + my_ptr = it.my_ptr; + my_shared_epoch = it.my_shared_epoch; + my_current_epoch = it.my_current_epoch; + ++my_shared_epoch->refcounter; + } + + InputIterator& operator= ( const InputIterator& it ) { + ASSERT(it.my_current_epoch == it.my_shared_epoch->epoch, "Assigning an invalidated iterator"); + my_ptr = it.my_ptr; + my_current_epoch = it.my_current_epoch; + if(my_shared_epoch == it.my_shared_epoch) + return *this; + destroy(); + my_shared_epoch = it.my_shared_epoch; + ++my_shared_epoch->refcounter; + return *this; + } + + T& operator* () const { + ASSERT(my_shared_epoch->epoch == my_current_epoch, "Dereferencing an invalidated input iterator"); + return *my_ptr; + } + + InputIterator& operator++ () { + ASSERT(my_shared_epoch->epoch == my_current_epoch, "Incrementing an invalidated input iterator"); + ++my_ptr; + ++my_current_epoch; + ++my_shared_epoch->epoch; + return *this; + } + + bool operator== ( const InputIterator& it ) const { + ASSERT(my_shared_epoch->epoch == my_current_epoch, "Comparing an invalidated input iterator"); + ASSERT(it.my_shared_epoch->epoch == it.my_current_epoch, "Comparing with an invalidated input iterator"); + return my_ptr == it.my_ptr; + } + + ~InputIterator() { + destroy(); + } +private: + void destroy() { + if(0 == --my_shared_epoch->refcounter) { + delete my_shared_epoch; + } + } + struct Epoch { + typedef tbb::atomic<size_t> Counter; + Epoch() { epoch = 0; refcounter = 1; } + Counter epoch; + Counter refcounter; + }; + + T * my_ptr; + Epoch *my_shared_epoch; + size_t my_current_epoch; +}; + +template <typename T> +class ForwardIterator { + T * my_ptr; +public: + typedef std::forward_iterator_tag iterator_category; + typedef T value_type; + typedef typename std::allocator<T>::difference_type difference_type; + typedef typename std::allocator<T>::pointer pointer; + typedef typename std::allocator<T>::reference reference; + + explicit ForwardIterator ( T * ptr ) : my_ptr(ptr){} + + ForwardIterator ( const ForwardIterator& r ) : my_ptr(r.my_ptr){} + T& operator* () const { return *my_ptr; } + ForwardIterator& operator++ () { ++my_ptr; return *this; } + bool operator== ( const ForwardIterator& r ) const { return my_ptr == r.my_ptr; } +}; + +template <typename T> +class RandomIterator { + T * my_ptr; +public: + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef typename std::allocator<T>::pointer pointer; + typedef typename std::allocator<T>::reference reference; + typedef typename std::allocator<T>::difference_type difference_type; + + explicit RandomIterator ( T * ptr ) : my_ptr(ptr){} + RandomIterator ( const RandomIterator& r ) : my_ptr(r.my_ptr){} + T& operator* () const { return *my_ptr; } + RandomIterator& operator++ () { ++my_ptr; return *this; } + bool operator== ( const RandomIterator& r ) const { return my_ptr == r.my_ptr; } + bool operator!= ( const RandomIterator& r ) const { return my_ptr != r.my_ptr; } + difference_type operator- (const RandomIterator &r) const {return my_ptr - r.my_ptr;} + RandomIterator operator+ (difference_type n) const {return RandomIterator(my_ptr + n);} + bool operator< (const RandomIterator &r) const {return my_ptr < r.my_ptr;} +}; + +template <typename T> +class ConstRandomIterator { + const T * my_ptr; +public: + typedef std::random_access_iterator_tag iterator_category; + typedef const T value_type; + typedef typename std::allocator<T>::const_pointer pointer; + typedef typename std::allocator<T>::const_reference reference; + typedef typename std::allocator<T>::difference_type difference_type; + + explicit ConstRandomIterator ( const T * ptr ) : my_ptr(ptr){} + ConstRandomIterator ( const ConstRandomIterator& r ) : my_ptr(r.my_ptr){} + const T& operator* () const { return *my_ptr; } + ConstRandomIterator& operator++ () { ++my_ptr; return *this; } + bool operator== ( const ConstRandomIterator& r ) const { return my_ptr == r.my_ptr; } + bool operator!= ( const ConstRandomIterator& r ) const { return my_ptr != r.my_ptr; } + difference_type operator- (const ConstRandomIterator &r) const {return my_ptr - r.my_ptr;} + ConstRandomIterator operator+ (difference_type n) const {return ConstRandomIterator(my_ptr + n);} + bool operator< (const ConstRandomIterator &r) const {return my_ptr < r.my_ptr;} +}; + +} // namespace Harness + +#endif //harness_iterator_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_m128.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_m128.h new file mode 100644 index 00000000..cee8314d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_m128.h @@ -0,0 +1,125 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Header that sets HAVE_m128/HAVE_m256 if vector types (__m128/__m256) are available + +//! Class for testing safety of using vector types. +/** Uses circuitous logic forces compiler to put __m128/__m256 objects on stack while + executing various methods, and thus tempt it to use aligned loads and stores + on the stack. */ +// Do not create file-scope objects of the class, because MinGW (as of May 2010) +// did not always provide proper stack alignment in destructors of such objects. + +#if (_MSC_VER>=1600) +//TODO: handle /arch:AVX in the right way. +#pragma warning (push) +#pragma warning (disable: 4752) +#endif + +#if __TBB_GCC_WARNING_SUPPRESSION_PRESENT && __TBB_GCC_WARNING_IGNORED_ATTRIBUTES_PRESENT +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wignored-attributes" +#endif + + +template<typename __Mvec> +class ClassWithVectorType { + static const int n = 16; + static const int F = sizeof(__Mvec)/sizeof(float); + __Mvec field[n]; + void init( int start ); +public: + ClassWithVectorType() {init(-n);} + ClassWithVectorType( int i ) {init(i);} + ClassWithVectorType( const ClassWithVectorType& src ) { + for( int i=0; i<n; ++i ) { + field[i] = src.field[i]; + } + } + void operator=( const ClassWithVectorType& src ) { + __Mvec stack[n]; + for( int i=0; i<n; ++i ) + stack[i^5] = src.field[i]; + for( int i=0; i<n; ++i ) + field[i^5] = stack[i]; + } + ~ClassWithVectorType() {init(-2*n);} + friend bool operator==( const ClassWithVectorType& x, const ClassWithVectorType& y ) { + for( int i=0; i<F*n; ++i ) + if( ((const float*)x.field)[i]!=((const float*)y.field)[i] ) + return false; + return true; + } + friend bool operator!=( const ClassWithVectorType& x, const ClassWithVectorType& y ) { + return !(x==y); + } +}; + +template<typename __Mvec> +void ClassWithVectorType<__Mvec>::init( int start ) { + __Mvec stack[n]; + for( int i=0; i<n; ++i ) { + // Declaring value as a one-element array instead of a scalar quites + // gratuitous warnings about possible use of "value" before it was set. + __Mvec value[1]; + for( int j=0; j<F; ++j ) + ((float*)value)[j] = float(n*start+F*i+j); + stack[i^5] = value[0]; + } + for( int i=0; i<n; ++i ) + field[i^5] = stack[i]; +} + +#if (__AVX__ || (_MSC_VER>=1600 && _M_X64)) && !defined(__sun) +#include <immintrin.h> +#define HAVE_m256 1 +typedef ClassWithVectorType<__m256> ClassWithAVX; +#if _MSC_VER +#include <intrin.h> // for __cpuid +#endif +bool have_AVX() { + bool result = false; + const int avx_mask = 1<<28; +#if _MSC_VER || __INTEL_COMPILER + int info[4] = {0,0,0,0}; + const int ECX = 2; + __cpuid(info, 1); + result = (info[ECX] & avx_mask)!=0; +#elif __GNUC__ + int ECX; + __asm__( "cpuid" + : "=c"(ECX) + : "a" (1) + : "ebx", "edx" ); + result = (ECX & avx_mask); +#endif + return result; +} +#endif /* __AVX__ etc */ + +#if (__SSE__ || _M_IX86_FP || _M_X64) && !defined(__sun) +#include <xmmintrin.h> +#define HAVE_m128 1 +typedef ClassWithVectorType<__m128> ClassWithSSE; +#endif + +#if __TBB_GCC_WARNING_SUPPRESSION_PRESENT && __TBB_GCC_WARNING_IGNORED_ATTRIBUTES_PRESENT +#pragma GCC diagnostic pop +#endif + +#if (_MSC_VER>=1600) +#pragma warning (pop) +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_memory.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_memory.h new file mode 100644 index 00000000..27a8b4cb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_memory.h @@ -0,0 +1,141 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Declarations for simple estimate of the memory being used by a program. +// Not yet implemented for macOS*. +// This header is an optional part of the test harness. +// It assumes that "harness_assert.h" has already been included. + +#if __linux__ || __sun +#include <sys/resource.h> +#include <unistd.h> + +#elif __APPLE__ && !__ARM_ARCH +#include <unistd.h> +#include <mach/mach.h> +#include <AvailabilityMacros.h> +#if MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6 || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 +#include <mach/shared_region.h> +#else +#include <mach/shared_memory_server.h> +#endif +#if SHARED_TEXT_REGION_SIZE || SHARED_DATA_REGION_SIZE +const size_t shared_size = SHARED_TEXT_REGION_SIZE+SHARED_DATA_REGION_SIZE; +#else +const size_t shared_size = 0; +#endif + +#elif _WIN32 && !__TBB_WIN8UI_SUPPORT +#include <windows.h> +#include <psapi.h> +#if _MSC_VER +#pragma comment(lib, "psapi") +#endif + +#endif /* OS selection */ + +enum MemoryStatType { + currentUsage, + peakUsage +}; + +//! Return estimate of number of bytes of memory that this program is currently using. +/* Returns 0 if not implemented on platform. */ +size_t GetMemoryUsage(MemoryStatType stat = currentUsage) { + ASSERT(stat==currentUsage || stat==peakUsage, NULL); +#if __TBB_WIN8UI_SUPPORT + return 0; +#elif _WIN32 + PROCESS_MEMORY_COUNTERS mem; + bool status = GetProcessMemoryInfo(GetCurrentProcess(), &mem, sizeof(mem))!=0; + ASSERT(status, NULL); + return stat==currentUsage? mem.PagefileUsage : mem.PeakPagefileUsage; +#elif __linux__ + long unsigned size = 0; + FILE *fst = fopen("/proc/self/status", "r"); + ASSERT(fst, NULL); + const int BUF_SZ = 200; + char buf_stat[BUF_SZ]; + const char *pattern = stat==peakUsage ? "VmPeak: %lu" : "VmSize: %lu"; + while (NULL != fgets(buf_stat, BUF_SZ, fst)) { + if (1==sscanf(buf_stat, pattern, &size)) { + ASSERT(size, "Invalid value of memory consumption."); + break; + } + } + // VmPeak is available in kernels staring 2.6.15 + if (stat!=peakUsage || LinuxKernelVersion() >= 2006015) + ASSERT(size, "Invalid /proc/self/status format, pattern not found."); + fclose(fst); + return size*1024; +#elif __APPLE__ && !__ARM_ARCH + // TODO: find how detect peak virtual memory size under macOS + if (stat == peakUsage) + return 0; + kern_return_t status; + task_basic_info info; + mach_msg_type_number_t msg_type = TASK_BASIC_INFO_COUNT; + status = task_info(mach_task_self(), TASK_BASIC_INFO, reinterpret_cast<task_info_t>(&info), &msg_type); + ASSERT(status==KERN_SUCCESS, NULL); + return info.virtual_size - shared_size; +#else + return 0; +#endif +} + +//! Use approximately a specified amount of stack space. +/** Recursion is used here instead of alloca because some implementations of alloca do not use the stack. */ +void UseStackSpace( size_t amount, char* top=0 ) { + char x[1000]; + memset( x, -1, sizeof(x) ); + if( !top ) + top = x; + ASSERT( x<=top, "test assumes that stacks grow downwards" ); + if( size_t(top-x)<amount ) + UseStackSpace( amount, top ); +} + +#if __linux__ +// Parse file utility +#include "../tbbmalloc/shared_utils.h" + +inline bool isTHPEnabledOnMachine() { + unsigned long long thpPresent = 'n'; + parseFileItem thpItem[] = { { "[alwa%cs] madvise never\n", thpPresent } }; + parseFile</*BUFF_SIZE=*/100>("/sys/kernel/mm/transparent_hugepage/enabled", thpItem); + + if (thpPresent == 'y') { + return true; + } else { + return false; + } +} +inline unsigned long long getSystemTHPAllocatedSize() { + unsigned long long anonHugePagesSize = 0; + parseFileItem meminfoItems[] = { + { "AnonHugePages: %llu kB", anonHugePagesSize } }; + parseFile</*BUFF_SIZE=*/100>("/proc/meminfo", meminfoItems); + return anonHugePagesSize; +} +inline unsigned long long getSystemTHPCount() { + unsigned long long anonHugePages = 0; + parseFileItem vmstatItems[] = { + { "nr_anon_transparent_hugepages %llu", anonHugePages } }; + parseFile</*BUFF_SIZE=*/100>("/proc/vmstat", vmstatItems); + return anonHugePages; +} +#endif // __linux__ + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_mic.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_mic.h new file mode 100644 index 00000000..95225532 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_mic.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef tbb_test_harness_mic_H +#define tbb_test_harness_mic_H + +#if ! __TBB_DEFINE_MIC + #error test/harness_mic.h should be included only when building for Intel(R) Many Integrated Core Architecture +#endif + +// test for unifed sources. See makefiles +#undef HARNESS_INCOMPLETE_SOURCES + +#include <stdlib.h> +#include <stdio.h> + +#define TBB_TEST_LOW_WORKLOAD 1 + +#define REPORT_FATAL_ERROR REPORT +#define HARNESS_EXPORT + +#if __TBB_MIC_NATIVE + #define HARNESS_EXIT_ON_ASSERT 1 + #define __TBB_PLACEMENT_NEW_EXCEPTION_SAFETY_BROKEN 1 +#else + #define HARNESS_TERMINATE_ON_ASSERT 1 +#endif + +#endif /* tbb_test_harness_mic_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_preload.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_preload.h new file mode 100644 index 00000000..5d5c5226 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_preload.h @@ -0,0 +1,43 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// This file is intended for preloading (via compiler options such as -include) into every test. +// Alas, not all compilers have such options, so the file is "optional". + +// Only add here things that are necessary for *every* test! +// In particular, avoid including other headers. +// Since this file can be omitted, checking compiler-specific conditions is strongly recommended. + +#ifndef harness_preload_H +#define harness_preload_H + +#if __GNUC__>=5 && !__INTEL_COMPILER && !__clang__ && __GXX_EXPERIMENTAL_CXX0X__ +// GCC 5 has added -Wsuggest-override, but unfortunately enables it even in pre-C++11 mode. +// We only want to use it for C++11 though. +#pragma GCC diagnostic warning "-Wsuggest-override" +#define __TBB_TEST_USE_WSUGGEST_OVERRIDE 1 +#endif +// TODO: consider adding a similar option for clang + +#if __TBB_TEST_NO_EXCEPTIONS +// This code breaks our own recommendations above, and it's deliberate: +// it includes another file, but that file should only have macros and pragmas; +// it does not check for compiler, as that is checked in the included file. +// The file also defines TBB_USE_EXCEPTIONS=0, which is set for all tests via makefiles anyway. +#include "tbb/tbb_disable_exceptions.h" +#endif + +#endif /* harness_preload_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_report.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_report.h new file mode 100644 index 00000000..33fe502c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_report.h @@ -0,0 +1,174 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Just the tracing portion of the harness. +// +// This header defines TRACE and TRACENL macros, which use REPORT like syntax and +// are useful for duplicating trace output to the standard debug output on Windows. +// It is possible to add the ability of automatic extending messages with additional +// info (file, line, function, time, thread ID, ...). +// +// Macros output nothing when test app runs in non-verbose mode (default). +// + +#ifndef tbb_tests_harness_report_H +#define tbb_tests_harness_report_H + +#if defined(MAX_TRACE_SIZE) && MAX_TRACE_SIZE < 1024 + #undef MAX_TRACE_SIZE +#endif +#ifndef MAX_TRACE_SIZE + #define MAX_TRACE_SIZE 1024 +#endif + +#if __SUNPRO_CC +#include <stdio.h> +#else +#include <cstdio> +#endif + +#include <cstdarg> + +// Need to include "tbb/tbb_config.h" to obtain the definition of __TBB_DEFINE_MIC. +#include "tbb/tbb_config.h" + +#if __TBB_DEFINE_MIC +#include "harness_mic.h" +#endif + +#ifdef HARNESS_INCOMPLETE_SOURCES +#error Source files are not complete. Check the build environment +#endif + +#if _MSC_VER + #define snprintf _snprintf +#if _MSC_VER<=1400 + #define vsnprintf _vsnprintf +#endif +#endif + +namespace Harness { + namespace internal { + +#ifndef TbbHarnessReporter + struct TbbHarnessReporter { + void Report ( const char* msg ) { + printf( "%s", msg ); + fflush(stdout); +#ifdef _WINDOWS_ + OutputDebugStringA(msg); +#endif + } + }; // struct TbbHarnessReporter +#endif /* !TbbHarnessReporter */ + + class Tracer { + int m_flags; + const char *m_file; + const char *m_func; + size_t m_line; + + TbbHarnessReporter m_reporter; + + public: + enum { + prefix = 1, + need_lf = 2 + }; + + Tracer(): m_flags(0), m_file(NULL), m_func(NULL), m_line(0) {} + + Tracer* set_trace_info ( int flags, const char *file, size_t line, const char *func ) { + m_flags = flags; + m_line = line; + m_file = file; + m_func = func; + return this; + } + + void trace ( const char* fmt, ... ) { + char msg[MAX_TRACE_SIZE]; + char msg_fmt_buf[MAX_TRACE_SIZE]; + const char *msg_fmt = fmt; + if ( m_flags & prefix ) { + snprintf (msg_fmt_buf, MAX_TRACE_SIZE, "[%s] %s", m_func, fmt); + msg_fmt = msg_fmt_buf; + } + std::va_list argptr; + va_start (argptr, fmt); + int len = vsnprintf (msg, MAX_TRACE_SIZE, msg_fmt, argptr); + va_end (argptr); + if ( m_flags & need_lf && + len < MAX_TRACE_SIZE - 1 && msg_fmt[len-1] != '\n' ) + { + msg[len] = '\n'; + msg[len + 1] = 0; + } + m_reporter.Report(msg); + } + }; // class Tracer + + static Tracer tracer; + + template<int> + bool not_the_first_call () { + static bool first_call = false; + bool res = first_call; + first_call = true; + return res; + } + + } // namespace internal +} // namespace Harness + +#if defined(_MSC_VER) && _MSC_VER >= 1300 || defined(__GNUC__) || defined(__GNUG__) + #define HARNESS_TRACE_ORIG_INFO __FILE__, __LINE__, __FUNCTION__ +#else + #define HARNESS_TRACE_ORIG_INFO __FILE__, __LINE__, "" + #define __FUNCTION__ "" +#endif + + +//! printf style tracing macro +/** This variant of TRACE adds trailing line-feed (new line) character, if it is absent. **/ +#define TRACE Harness::internal::tracer.set_trace_info(Harness::internal::Tracer::need_lf, HARNESS_TRACE_ORIG_INFO)->trace + +//! printf style tracing macro without automatic new line character adding +#define TRACENL Harness::internal::tracer.set_trace_info(0, HARNESS_TRACE_ORIG_INFO)->trace + +//! printf style tracing macro with additional information prefix (e.g. current function name) +#define TRACEP Harness::internal::tracer.set_trace_info(Harness::internal::Tracer::prefix | \ + Harness::internal::Tracer::need_lf, HARNESS_TRACE_ORIG_INFO)->trace + +//! printf style remark macro +/** Produces output only when the test is run with the -v (verbose) option. **/ +#define REMARK !Verbose ? (void)0 : TRACENL + +//! printf style remark macro +/** Produces output only when invoked first time. + Only one instance of this macro is allowed per source code line. **/ +#define REMARK_ONCE (!Verbose || Harness::internal::not_the_first_call<__LINE__>()) ? (void)0 : TRACE + +//! printf style reporting macro +/** On heterogeneous platforms redirects its output to the host side. **/ +#define REPORT TRACENL + +//! printf style reporting macro +/** Produces output only when invoked first time. + Only one instance of this macro is allowed per source code line. **/ +#define REPORT_ONCE (Harness::internal::not_the_first_call<__LINE__>()) ? (void)0 : TRACENL + +#endif /* tbb_tests_harness_report_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_runtime_loader.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_runtime_loader.h new file mode 100644 index 00000000..14436fa5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_runtime_loader.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef harness_runtime_loader_H +#define harness_runtime_loader_H + +#if HARNESS_USE_RUNTIME_LOADER + #if TEST_USES_TBB + #define TBB_PREVIEW_RUNTIME_LOADER 1 + #include "tbb/runtime_loader.h" + static char const * _path[] = { ".", NULL }; + // declaration must be placed before 1st TBB call + static tbb::runtime_loader _runtime_loader( _path ); + #else // TEST_USES_TBB + // if TBB library is not used, no need to test Runtime Loader + #define HARNESS_SKIP_TEST 1 + #endif // TEST_USES_TBB +#endif // HARNESS_USE_RUNTIME_LOADER + +#endif /* harness_runtime_loader_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_state_trackable.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_state_trackable.h new file mode 100644 index 00000000..625c0556 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_state_trackable.h @@ -0,0 +1,143 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Declarations for a class that can track operations applied to its objects. +// This header is an optional part of the test harness. + +#ifndef tbb_test_harness_state_trackable_H +#define tbb_test_harness_state_trackable_H + +#include <cstddef> +#include <map> +#include <tbb/atomic.h> + +#include "harness_assert.h" + +namespace Harness{ + struct StateTrackableBase { + enum StateValue { + ZeroInitialized = 0, + DefaultInitialized = 0xDEFAUL, + DirectInitialized = 0xD1111, + CopyInitialized = 0xC0314, + MoveInitialized = 0xAAAAA, + Assigned = 0x11AED, + MoveAssigned = 0x22AED, + MovedFrom = 0xFFFFF, + Destroyed = 0xDEADF00, + Unspecified = 0xEEEEE + }; + + class State { + public: + State() __TBB_NOEXCEPT(true) : state(Unspecified) { + assignNewState(Unspecified); + } + State(const State& s) : state(Unspecified) { + assignNewState(s.state); + } + State(StateValue s) __TBB_NOEXCEPT(true) : state(Unspecified) { + assignNewState(s); + }; + State& operator=(StateValue s) __TBB_NOEXCEPT(true) { + assignNewState(s); + return *this; + } + operator StateValue() const __TBB_NOEXCEPT(true) { return state; } + private: + void assignNewState(StateValue s) __TBB_NOEXCEPT(true); + StateValue state; + }; + }; + + struct StateTrackableCounters { + static void reset() { + counters[StateTrackableBase::ZeroInitialized] = counters[StateTrackableBase::DefaultInitialized] = + counters[StateTrackableBase::DirectInitialized] = counters[StateTrackableBase::CopyInitialized] = + counters[StateTrackableBase::MoveInitialized] = counters[StateTrackableBase::Assigned] = + counters[StateTrackableBase::MoveAssigned] = counters[StateTrackableBase::MovedFrom] = + counters[StateTrackableBase::Destroyed] = counters[StateTrackableBase::Unspecified] = 0; + } + + static bool initialize() { + reset(); + return true; + } + + typedef std::map<StateTrackableBase::StateValue, tbb::atomic<std::size_t> > counters_t; + static counters_t counters; + }; + + StateTrackableCounters::counters_t StateTrackableCounters::counters; + static const bool stateTrackableBaseStateInitialized = StateTrackableCounters::initialize(); + + void StateTrackableBase::State::assignNewState(StateValue s) __TBB_NOEXCEPT(true) { + ASSERT(stateTrackableBaseStateInitialized, "State trackable counters are not initialized"); + ASSERT(s == StateTrackableBase::Unspecified || + StateTrackableCounters::counters.find(s) != StateTrackableCounters::counters.end(), "The current state value is unknown"); + ASSERT(state == StateTrackableBase::Unspecified || + StateTrackableCounters::counters.find(state) != StateTrackableCounters::counters.end(), "The new state value is unknown"); + state = s; + ++StateTrackableCounters::counters[state]; + } + + template<bool allow_zero_initialized_state = false> + struct StateTrackable: StateTrackableBase { + static const bool is_zero_initialized_state_allowed = allow_zero_initialized_state; + State state; + + bool is_valid() const { + return state == DefaultInitialized || state == DirectInitialized || state == CopyInitialized + || state == MoveInitialized || state == Assigned || state == MoveAssigned || state == MovedFrom + || (allow_zero_initialized_state && state == ZeroInitialized) + ; + } + + StateTrackable (intptr_t) __TBB_NOEXCEPT(true) : state (DirectInitialized){} + StateTrackable () __TBB_NOEXCEPT(true) : state (DefaultInitialized){} + StateTrackable (const StateTrackable & src) __TBB_NOEXCEPT(true) { + ASSERT( src.is_valid(), "bad source for copy" ); + state = CopyInitialized; + } + #if __TBB_CPP11_RVALUE_REF_PRESENT + StateTrackable (StateTrackable && src) __TBB_NOEXCEPT(true) { + ASSERT( src.is_valid(), "bad source for move?" ); + state = MoveInitialized; + src.state = MovedFrom; + } + StateTrackable & operator=(StateTrackable && src) __TBB_NOEXCEPT(true) { + ASSERT( src.is_valid(), "bad source for assignment" ); + ASSERT( is_valid(), "assigning to invalid instance?" ); + + src.state = MovedFrom; + state = MoveAssigned; + return *this; + } + #endif + StateTrackable & operator=(const StateTrackable & src) __TBB_NOEXCEPT(true) { + ASSERT( src.is_valid(), "bad source for assignment?" ); + ASSERT( is_valid(), "assigning to invalid instance?" ); + + state = Assigned; + return *this; + } + ~StateTrackable () __TBB_NOEXCEPT(true) { + ASSERT( is_valid(), "Calling destructor on invalid instance? (twice destructor call?)" ); + state = Destroyed; + } + }; +} // Harness +#endif // tbb_test_harness_state_trackable_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_task.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_task.h new file mode 100644 index 00000000..954c036c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_task.h @@ -0,0 +1,51 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/task.h" +#include "harness.h" + +//! Helper for verifying that old use cases of spawn syntax still work. +tbb::task* GetTaskPtr( int& counter ) { + ++counter; + return NULL; +} + +class TaskGenerator: public tbb::task { + int m_ChildCount; + int m_Depth; + +public: + TaskGenerator( int child_count, int _depth ) : m_ChildCount(child_count), m_Depth(_depth) {} + ~TaskGenerator( ) { m_ChildCount = m_Depth = -125; } + + tbb::task* execute() __TBB_override { + ASSERT( m_ChildCount>=0 && m_Depth>=0, NULL ); + if( m_Depth>0 ) { + recycle_as_safe_continuation(); + set_ref_count( m_ChildCount+1 ); + int k=0; + for( int j=0; j<m_ChildCount; ++j ) { + tbb::task& t = *new( allocate_child() ) TaskGenerator(m_ChildCount/2,m_Depth-1); + GetTaskPtr(k)->spawn(t); + } + ASSERT(k==m_ChildCount,NULL); + --m_Depth; + __TBB_Yield(); + ASSERT( state()==recycle && ref_count()>0, NULL); + } + return NULL; + } +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tbb_independence.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tbb_independence.h new file mode 100644 index 00000000..acd16393 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tbb_independence.h @@ -0,0 +1,83 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef harness_tbb_independence_H +#define harness_tbb_independence_H + +// The tests which include tbb/atomic.h gain the dependency on the __TBB_ASSERT +// implementation even the test does not use anything from it. But almost all +// compilers optimize out unused inline function so they throw out the +// dependency. But to be pedantic with the standard the __TBB_ASSERT +// implementation should be provided. Moreover the offload compiler really +// requires it. +#include "../tbb/tbb_assert_impl.h" + +#if __linux__ && __ia64__ + +#define __TBB_NO_IMPLICIT_LINKAGE 1 +#include "tbb/tbb_machine.h" + +#include <pthread.h> + +// Can't use Intel compiler intrinsic due to internal error reported by 10.1 compiler +pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; + +int32_t __TBB_machine_fetchadd4__TBB_full_fence (volatile void *ptr, int32_t value) +{ + pthread_mutex_lock(&counter_mutex); + int32_t result = *(int32_t*)ptr; + *(int32_t*)ptr = result + value; + pthread_mutex_unlock(&counter_mutex); + return result; +} + +int64_t __TBB_machine_fetchadd8__TBB_full_fence (volatile void *ptr, int64_t value) +{ + pthread_mutex_lock(&counter_mutex); + int32_t result = *(int32_t*)ptr; + *(int32_t*)ptr = result + value; + pthread_mutex_unlock(&counter_mutex); + return result; +} + +void __TBB_machine_pause(int32_t /*delay*/) { __TBB_Yield(); } + +pthread_mutex_t cas_mutex = PTHREAD_MUTEX_INITIALIZER; + +extern "C" int64_t __TBB_machine_cmpswp8__TBB_full_fence(volatile void *ptr, int64_t value, int64_t comparand) +{ + pthread_mutex_lock(&cas_mutex); + int64_t result = *(int64_t*)ptr; + if (result == comparand) + *(int64_t*)ptr = value; + pthread_mutex_unlock(&cas_mutex); + return result; +} + +pthread_mutex_t fetchstore_mutex = PTHREAD_MUTEX_INITIALIZER; + +int64_t __TBB_machine_fetchstore8__TBB_full_fence (volatile void *ptr, int64_t value) +{ + pthread_mutex_lock(&fetchstore_mutex); + int64_t result = *(int64_t*)ptr; + *(int64_t*)ptr = value; + pthread_mutex_unlock(&fetchstore_mutex); + return result; +} + +#endif /* __linux__ && __ia64 */ + +#endif // harness_tbb_independence_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_test_cases_framework.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_test_cases_framework.h new file mode 100644 index 00000000..06a63915 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_test_cases_framework.h @@ -0,0 +1,236 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef tbb_harness_test_cases_framework_H +#define tbb_harness_test_cases_framework_H + +#if defined(_MSC_VER) + #define _SCL_SECURE_NO_WARNINGS +#endif + +#undef DO_ITT_NOTIFY + +#include "harness.h" +#include "harness_assert.h" +#include "tbb/tbb_stddef.h" + +#include <cstdlib> + +#include <vector> +#include <algorithm> +#include <string> +#include <sstream> +#include <iostream> + +namespace test_framework{ + template<typename test_class> + void run_test(){ + test_class()(); + } + +#if TBB_USE_EXCEPTIONS + struct assertion_failure:std::exception{ + const char* my_filename; + int my_line; + const char* my_expression; + const char * my_comment; + assertion_failure(const char* filename, int line, const char* expression, const char * comment): + my_filename(filename), + my_line(line), + my_expression(expression), + my_comment(comment) + {} + virtual const char* what() const throw() __TBB_override { + return "test assertion failed"; + } + }; + void throw_assertion_failure(){throw assertion_failure("",0,"","");} + void throw_assertion_failure(const char* filename, int line, const char* expression, const char * comment){ + throw assertion_failure(filename, line, expression, comment); + } +#endif // TBB_USE_EXCEPTIONS + + class test_suite{ + typedef void(*run_test_function_pointer_type)(); + typedef std::pair<std::string, run_test_function_pointer_type> tc_record_pair; + std::vector<tc_record_pair > test_cases; + public: + template<class test_class> + void register_test_case(std::string const& name, test_class * ){ + test_cases.push_back(tc_record_pair(name,& run_test<test_class>)); + } + std::string operator()(bool silent=false){ + std::stringstream str; + size_t failed=0; + for (size_t i=0;i<test_cases.size();++i){ +#if TBB_USE_EXCEPTIONS + try{ + (test_cases[i].second)(); + }catch(std::exception& e){ + failed++; + str<<"test case \""<<test_cases[i].first<<"\" failed with exception. what():\""<<e.what()<<"\""<<std::endl; + } +#else + (test_cases[i].second)(); +#endif + } + if (!silent) { + str<<test_cases.size()<<" test cases are run; "<<failed<<" failed"<<std::endl; + } + return str.str(); + } + }; + test_suite& get_suite_ref(){static test_suite ts; return ts;} + void run_all_and_print_results(test_suite& ts,std::ostream& o , bool silent=false){ + o<<ts(silent); + } +} +using test_framework::get_suite_ref; +#define TEST_CASE_WITH_FIXTURE(TC_NAME,FIXTURE_NAME) \ + struct TC_NAME; \ + struct TC_NAME:FIXTURE_NAME { \ + /* explicitly implemented default constructor \ + is need here to please gcc 4.3.2*/ \ + TC_NAME(){} \ + void operator()(); \ + }; \ + bool TC_NAME##_registerd = (get_suite_ref().register_test_case(#TC_NAME,static_cast<TC_NAME*>(0)),true);\ + void TC_NAME::operator()() + +namespace test_framework_unit_tests{ + namespace test_helper{ + template <size_t id> struct tag{}; + template<typename tag> + struct test_case{ + static bool is_run; + void operator()(){ + is_run=true; + } + }; + template<typename tag> bool test_case<tag>::is_run = false; + + } + using namespace test_framework; + namespace test_test_suite_ref{ + void run_all_runs_all_registered_test_cases(){ + test_suite s; + using test_helper::tag; + test_helper::test_case<tag<__LINE__> > tc1; + test_helper::test_case<tag<__LINE__> > tc2; + s.register_test_case("tc1",&tc1); + s.register_test_case("tc2",&tc2); + s(); + ASSERT(tc1.is_run && tc2.is_run,"test_suite::operator() should run all the tests"); + } + + struct silent_switch_fixture{ + test_helper::test_case<test_helper::tag<__LINE__> > empty_test_case; + }; + struct run_all_and_print_results_should_respect_silent_mode: silent_switch_fixture{ + void operator()(){ + using test_helper::tag; + test_helper::test_case<tag<__LINE__> > do_nothing_tc; + test_suite ts; + ts.register_test_case("tc_name",&do_nothing_tc); + bool silent =true; + ASSERT(ts(silent).empty(),"in silent mode no message except error should be output"); + } + }; + struct run_all_and_print_results_should_respect_verbose_mode: silent_switch_fixture{ + void operator()(){ + using test_helper::tag; + test_helper::test_case<tag<__LINE__> > do_nothing_tc; + test_suite ts; + ts.register_test_case("tc_name",&do_nothing_tc); + bool silent =true; + ASSERT(!ts(!silent).empty(),"in verbose mode all messages should be outputted"); + } + }; + } + namespace test_test_case_macro{ + test_suite& get_suite_ref(){static test_suite ts; return ts;} + typedef test_helper::test_case<test_helper::tag<__LINE__> > unique_test_type; + TEST_CASE_WITH_FIXTURE(test_auto_registration,unique_test_type){ + unique_test_type::operator()(); + } + void run_test_test_case_macro(){ + get_suite_ref()(); + ASSERT(unique_test_type::is_run,"test case macro should register the test case in suite"); + } + void test_test_case_macro_does_not_create_test_case_object(){ + ASSERT(false,"to implement"); + } + } + namespace internal_assertions_failure_test_cases{ + + test_suite& get_suite_ref(){static test_suite ts; return ts;} + + //TODO: investigate compilation errors regarding tbb::set_assertion_handler +// struct empty_fixture{}; +// TEST_CASE_WITH_FIXTURE(test_internal_assertion_does_not_stop_test_suite,empty_fixture){ +// struct handler{ +// static void _( const char* /*filename*/, int /*line*/, const char* /*expression*/, const char * /*comment*/ ){ +// } +// }; +// +// tbb::assertion_handler_type previous = tbb::set_assertion_handler(handler::_); +// __TBB_ASSERT(false,"this assert should not stop the test suite run"); +// tbb::set_assertion_handler(previous ); +//// ASSERT(assertion_handler::is_called,"__TBB_ASSERT should call installed assertion handler"); +// } +// TEST_CASE_WITH_FIXTURE(test_internal_assertion_does_mark_the_test_as_failed,empty_fixture){ +// test_suite ts; +// struct _{ +//// static +// static void assertion_handler_type( const char* /*filename*/, int /*line*/, const char* /*expression*/, const char * /*comment*/ ){ +// } +// }; +// tbb::assertion_handler_type previous = tbb::set_assertion_handler(_::assertion_handler_type); +// __TBB_ASSERT(false,"this assert should not stop the test suite run"); +// tbb::set_assertion_handler(previous ); +// std::string result = ts(); +// std::size_t test_case_name_begin_pos = result.find("test case \""); +// std::size_t failed_begin_pos = result.find("failed"); +// ASSERT(test_case_name_begin_pos!=std::string::npos && failed_begin_pos!=std::string::npos && test_case_name_begin_pos<failed_begin_pos,"internal assertion should result in test failure"); +// } + + } + void run_all_test(){ + test_test_suite_ref::run_all_runs_all_registered_test_cases(); + test_test_suite_ref::run_all_and_print_results_should_respect_silent_mode()(); + test_test_suite_ref::run_all_and_print_results_should_respect_verbose_mode()(); + test_test_case_macro::run_test_test_case_macro(); + //TODO: uncomment and implement +// test_test_case_macro::test_test_case_macro_does_not_create_test_case_object(); + run_all_and_print_results(internal_assertions_failure_test_cases::get_suite_ref(),std::cout,!Verbose); + } +} + +int TestMain (){ +#if TBB_USE_EXCEPTIONS + SetHarnessErrorProcessing(test_framework::throw_assertion_failure); + //TODO: deal with assertions during stack unwinding + //tbb::set_assertion_handler( test_framework::throw_assertion_failure ); +#endif + { + test_framework_unit_tests::run_all_test(); + } + bool silent = !Verbose; + run_all_and_print_results(test_framework::get_suite_ref(),std::cout,silent); + return Harness::Done; +} + +#endif //tbb_harness_test_cases_framework_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tls.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tls.h new file mode 100644 index 00000000..acb6b163 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tls.h @@ -0,0 +1,75 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +class LimitTLSKeysTo { +#if _WIN32 || _WIN64 + #if __TBB_WIN8UI_SUPPORT && !defined(TLS_OUT_OF_INDEXES) + // for SDKs for Windows*8 Store Apps that did not redirect TLS to FLS + #define TlsAlloc() FlsAlloc(NULL) + #define TlsFree FlsFree + #define TLS_OUT_OF_INDEXES FLS_OUT_OF_INDEXES + #endif + typedef DWORD handle; +#else // _WIN32 || _WIN64 + typedef pthread_key_t handle; +#endif + // for platforms that not limit number of TLS keys, set artificial limit + static const int LIMIT = 16*1024; + handle handles[LIMIT]; + int lastUsedIdx; +public: + LimitTLSKeysTo(int keep_keys) { + for (lastUsedIdx=0; lastUsedIdx<LIMIT; lastUsedIdx++) { +#if _WIN32 || _WIN64 + handle h = TlsAlloc(); + if (h==TLS_OUT_OF_INDEXES) +#else + int setspecific_dummy=10; + if (pthread_key_create(&handles[lastUsedIdx], NULL)!=0) +#endif + { + break; + } +#if _WIN32 || _WIN64 + handles[lastUsedIdx] = h; +#else + pthread_setspecific(handles[lastUsedIdx], &setspecific_dummy); +#endif + } + lastUsedIdx--; + ASSERT(lastUsedIdx >= keep_keys-1, "Less TLS keys are available than requested"); + for (; keep_keys>0; keep_keys--, lastUsedIdx--) { +#if _WIN32 || _WIN64 + TlsFree(handles[lastUsedIdx]); +#else + int ret = pthread_key_delete(handles[lastUsedIdx]); + ASSERT(!ret, "Can't delete a key"); +#endif + } + REMARK("%d thread local objects allocated in advance\n", lastUsedIdx+1); + } + ~LimitTLSKeysTo() { + for (int i=0; i<=lastUsedIdx; i++) { +#if _WIN32 || _WIN64 + TlsFree(handles[i]); +#else + int ret = pthread_key_delete(handles[i]); + ASSERT(!ret, "Can't delete a key"); +#endif + } + lastUsedIdx = 0; + } +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tsx.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tsx.h new file mode 100644 index 00000000..9159b53e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/harness_tsx.h @@ -0,0 +1,66 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Header that includes Intel(R) Transactional Synchronization Extensions (Intel(R) TSX) specific test functions + +#if __TBB_TSX_AVAILABLE +#define __TBB_TSX_TESTING_ENABLED_FOR_THIS_COMPILER (__INTEL_COMPILER || __GNUC__ || _MSC_VER || __SUNPRO_CC) +#if __TBB_TSX_TESTING_ENABLED_FOR_THIS_COMPILER + +#include "harness_defs.h" + +inline static bool IsInsideTx() +{ + return __TBB_machine_is_in_transaction() != 0; +} + +#if _MSC_VER +#include <intrin.h> // for __cpuid +#endif +// TODO: consider reusing tbb_misc.cpp:cpu_has_speculation() instead of code duplication. +bool have_TSX() { + bool result = false; + const int hle_ebx_mask = 1<<4; + const int rtm_ebx_mask = 1<<11; +#if _MSC_VER + int info[4] = {0,0,0,0}; + const int reg_ebx = 1; + int old_ecx = 0; + __cpuidex(info, 7, old_ecx); + result = (info[reg_ebx] & rtm_ebx_mask)!=0; + if( result ) ASSERT( (info[reg_ebx] & hle_ebx_mask)!=0, NULL ); +#elif __GNUC__ || __SUNPRO_CC + int32_t reg_ebx = 0; + int32_t reg_eax = 7; + int32_t reg_ecx = 0; + __asm__ __volatile__ ( "movl %%ebx, %%esi\n" + "cpuid\n" + "movl %%ebx, %0\n" + "movl %%esi, %%ebx\n" + : "=a"(reg_ebx) : "0" (reg_eax), "c" (reg_ecx) : "esi", +#if __TBB_x86_64 + "ebx", +#endif + "edx" + ); + result = (reg_ebx & rtm_ebx_mask)!=0 ; + if( result ) ASSERT( (reg_ebx & hle_ebx_mask)!=0, NULL ); +#endif + return result; +} + +#endif /* __TBB_TSX_TESTING_ENABLED_FOR_THIS_COMPILER */ +#endif /* __TBB_TSX_AVAILABLE */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ScalableAllocator.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ScalableAllocator.cpp new file mode 100644 index 00000000..4c99eba5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ScalableAllocator.cpp @@ -0,0 +1,223 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Test whether scalable_allocator complies with the requirements in 20.1.5 of ISO C++ Standard (1998). + +#define __TBB_EXTRA_DEBUG 1 // enables additional checks +#define TBB_PREVIEW_MEMORY_POOL 1 + +#include "harness_assert.h" +#if !__TBB_SOURCE_DIRECTLY_INCLUDED +#include "harness_tbb_independence.h" // because harness_allocator.h requires atomics +#endif +#include "tbb/memory_pool.h" +#include "tbb/scalable_allocator.h" + +#define HARNESS_TBBMALLOC_THREAD_SHUTDOWN 1 +// the actual body of the test is there: +#include "test_allocator.h" +#include "harness_allocator.h" + +#if _MSC_VER +#include "tbb/machine/windows_api.h" +#endif /* _MSC_VER */ + +typedef static_counting_allocator<tbb::memory_pool_allocator<char> > cnt_alloc_t; +typedef local_counting_allocator<std::allocator<char> > cnt_provider_t; +class MinimalAllocator : cnt_provider_t { +public: + typedef char value_type; + MinimalAllocator() { + REMARK("%p::ctor\n", this); + } + MinimalAllocator(const MinimalAllocator&s) : cnt_provider_t(s) { + REMARK("%p::ctor(%p)\n", this, &s); + } + ~MinimalAllocator() { + REMARK("%p::dtor: alloc=%u/%u free=%u/%u\n", this, + unsigned(items_allocated),unsigned(allocations), + unsigned(items_freed), unsigned(frees) ); + ASSERT(allocations==frees && items_allocated==items_freed,0); + if( allocations ) { // non-temporal copy + // TODO: describe consumption requirements + ASSERT(items_allocated>cnt_alloc_t::items_allocated, 0); + } + } + void *allocate(size_t sz) { + void *p = cnt_provider_t::allocate(sz); + REMARK("%p::allocate(%u) = %p\n", this, unsigned(sz), p); + return p; + } + void deallocate(void *p, size_t sz) { + ASSERT(allocations>frees,0); + REMARK("%p::deallocate(%p, %u)\n", this, p, unsigned(sz)); + cnt_provider_t::deallocate(cnt_provider_t::pointer(p), sz); + } +}; + +class NullAllocator { +public: + typedef char value_type; + NullAllocator() { } + NullAllocator(const NullAllocator&) { } + ~NullAllocator() { } + void *allocate(size_t) { return NULL; } + void deallocate(void *, size_t) { ASSERT(0, NULL); } +}; + +void TestZeroSpaceMemoryPool() +{ + tbb::memory_pool<NullAllocator> pool; + bool allocated = pool.malloc(16) || pool.malloc(9*1024); + ASSERT(!allocated, "Allocator with no memory must not allocate anything."); +} + +#if !TBB_USE_EXCEPTIONS +struct FixedPool { + void *buf; + size_t size; + bool used; + FixedPool(void *a_buf, size_t a_size) : buf(a_buf), size(a_size), used(false) {} +}; + +static void *fixedBufGetMem(intptr_t pool_id, size_t &bytes) +{ + if (((FixedPool*)pool_id)->used) + return NULL; + + ((FixedPool*)pool_id)->used = true; + bytes = ((FixedPool*)pool_id)->size; + return bytes? ((FixedPool*)pool_id)->buf : NULL; +} +#endif + +/* test that pools in small space are either usable or not created + (i.e., exception raised) */ +void TestSmallFixedSizePool() +{ + char *buf; + bool allocated = false; + + for (size_t sz = 0; sz < 64*1024; sz = sz? 3*sz : 3) { + buf = (char*)malloc(sz); +#if TBB_USE_EXCEPTIONS + try { + tbb::fixed_pool pool(buf, sz); +/* Check that pool is usable, i.e. such an allocation exists, + that can be fulfilled from the pool. 16B allocation fits in 16KB slabs, + so it requires at least 16KB. Requirement of 9KB allocation is more modest. +*/ + allocated = pool.malloc( 16 ) || pool.malloc( 9*1024 ); + } catch (std::invalid_argument&) { + ASSERT(!sz, "expect std::invalid_argument for zero-sized pool only"); + } catch (...) { + ASSERT(0, "wrong exception type;"); + } +#else +/* Do not test high-level pool interface because pool ctor emit exception + on creation failure. Instead test same functionality via low-level interface. + TODO: add support for configuration with disabled exceptions to pools. +*/ + rml::MemPoolPolicy pol(fixedBufGetMem, NULL, 0, /*fixedSizePool=*/true, + /*keepMemTillDestroy=*/false); + rml::MemoryPool *pool; + FixedPool fixedPool(buf, sz); + + rml::MemPoolError ret = pool_create_v1((intptr_t)&fixedPool, &pol, &pool); + + if (ret == rml::POOL_OK) { + allocated = pool_malloc(pool, 16) || pool_malloc(pool, 9*1024); + pool_destroy(pool); + } else + ASSERT(ret == rml::NO_MEMORY, "Expected that pool either valid " + "or have no memory to be created"); +#endif + free(buf); + } + ASSERT(allocated, "Maximal buf size should be enough to create working fixed_pool"); +#if TBB_USE_EXCEPTIONS + try { + tbb::fixed_pool pool(NULL, 10*1024*1024); + ASSERT(0, "Useless allocator with no memory must not be created"); + } catch (std::invalid_argument&) { + } catch (...) { + ASSERT(0, "wrong exception type; expected invalid_argument"); + } +#endif +} + +int TestMain () { +#if _MSC_VER && !__TBBMALLOC_NO_IMPLICIT_LINKAGE && !__TBB_WIN8UI_SUPPORT + #ifdef _DEBUG + ASSERT(!GetModuleHandle("tbbmalloc.dll") && GetModuleHandle("tbbmalloc_debug.dll"), + "test linked with wrong (non-debug) tbbmalloc library"); + #else + ASSERT(!GetModuleHandle("tbbmalloc_debug.dll") && GetModuleHandle("tbbmalloc.dll"), + "test linked with wrong (debug) tbbmalloc library"); + #endif +#endif /* _MSC_VER && !__TBBMALLOC_NO_IMPLICIT_LINKAGE */ + int result = TestMain<tbb::scalable_allocator<void> >(); + { + tbb::memory_pool<tbb::scalable_allocator<int> > pool; + result += TestMain(tbb::memory_pool_allocator<void>(pool) ); + }{ + tbb::memory_pool<MinimalAllocator> pool; + cnt_alloc_t alloc(( tbb::memory_pool_allocator<char>(pool) )); // double parentheses to avoid function declaration + result += TestMain(alloc); + }{ + static char buf[1024*1024*4]; + tbb::fixed_pool pool(buf, sizeof(buf)); + const char *text = "this is a test";// 15 bytes + char *p1 = (char*)pool.malloc( 16 ); + ASSERT(p1, NULL); + strcpy(p1, text); + char *p2 = (char*)pool.realloc( p1, 15 ); + ASSERT( p2 && !strcmp(p2, text), "realloc broke memory" ); + + result += TestMain(tbb::memory_pool_allocator<void>(pool) ); + + // try allocate almost entire buf keeping some reasonable space for internals + char *p3 = (char*)pool.realloc( p2, sizeof(buf)-128*1024 ); + ASSERT( p3, "defragmentation failed" ); + ASSERT( !strcmp(p3, text), "realloc broke memory" ); + for( size_t sz = 10; sz < sizeof(buf); sz *= 2) { + ASSERT( pool.malloc( sz ), NULL); + pool.recycle(); + } + + result += TestMain(tbb::memory_pool_allocator<void>(pool) ); + }{ + // Two nested level allocators case with fixed pool allocator as an underlying layer + // serving allocRawMem requests for the top level scalable allocator + typedef tbb::memory_pool<tbb::memory_pool_allocator<char, tbb::fixed_pool> > NestedPool; + + static char buffer[8*1024*1024]; + tbb::fixed_pool fixedPool(buffer, sizeof(buffer)); + // Underlying fixed pool allocator + tbb::memory_pool_allocator<char, tbb::fixed_pool> fixedPoolAllocator(fixedPool); + // Memory pool that handles fixed pool allocator + NestedPool nestedPool(fixedPoolAllocator); + // Top level memory pool allocator + tbb::memory_pool_allocator<char, NestedPool> nestedAllocator(nestedPool); + + result += TestMain(nestedAllocator); + } + TestSmallFixedSizePool(); + TestZeroSpaceMemoryPool(); + + ASSERT( !result, NULL ); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ScalableAllocator_STL.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ScalableAllocator_STL.cpp new file mode 100644 index 00000000..3df05ea3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ScalableAllocator_STL.cpp @@ -0,0 +1,50 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Test whether scalable_allocator works with some of the host's STL containers. + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#define __TBB_EXTRA_DEBUG 1 // enables additional checks +#define TBB_PREVIEW_MEMORY_POOL 1 + +#include "harness_assert.h" +#include "tbb/memory_pool.h" +#include "tbb/scalable_allocator.h" +#include <iostream> + +// The actual body of the test is there: +#include "test_allocator_STL.h" + +int TestMain () { + TestAllocatorWithSTL<tbb::scalable_allocator<void> >(); + tbb::memory_pool<tbb::scalable_allocator<int> > mpool; + TestAllocatorWithSTL(tbb::memory_pool_allocator<void>(mpool) ); + static char buf[1024*1024*4]; + tbb::fixed_pool fpool(buf, sizeof(buf)); + TestAllocatorWithSTL(tbb::memory_pool_allocator<void>(fpool) ); + +#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT + ASSERT(!tbb::scalable_memory_resource()->is_equal(*std::pmr::get_default_resource()), + "Scalable resource shouldn't be equal to standard resource." ); + ASSERT(tbb::scalable_memory_resource()->is_equal(*tbb::scalable_memory_resource()), + "Memory that was allocated by one scalable resource should be deallocated by any other instance."); + + typedef std::pmr::polymorphic_allocator<void> pmr_alloc_t; + TestAllocatorWithSTL(pmr_alloc_t(tbb::scalable_memory_resource())); +#endif + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_aggregator.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_aggregator.cpp new file mode 100644 index 00000000..8e370d47 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_aggregator.cpp @@ -0,0 +1,180 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef TBB_PREVIEW_AGGREGATOR + #define TBB_PREVIEW_AGGREGATOR 1 +#endif + +#include "tbb/aggregator.h" +#include "harness.h" +#include <queue> + +typedef std::priority_queue<int, std::vector<int>, std::less<int> > pq_t; + +int N; +int* shared_data; + +// Code for testing basic interface using function objects +class push_fnobj : NoAssign, Harness::NoAfterlife { + pq_t& pq; + int threadID; +public: + push_fnobj(pq_t& pq_, int tid) : pq(pq_), threadID(tid) {} + void operator()() const { + AssertLive(); + pq.push(threadID); + } +}; + +class pop_fnobj : NoAssign, Harness::NoAfterlife { + pq_t& pq; +public: + pop_fnobj(pq_t& pq_) : pq(pq_) {} + void operator()() const { + AssertLive(); + ASSERT(!pq.empty(), "queue should not be empty yet"); + int elem = pq.top(); + pq.pop(); + shared_data[elem]++; + } +}; + +class BasicBody : NoAssign { + pq_t& pq; + tbb::aggregator& agg; +public: + BasicBody(pq_t& pq_, tbb::aggregator& agg_) : pq(pq_), agg(agg_) {} + void operator()(const int threadID) const { + for (int i=0; i<N; ++i) agg.execute( push_fnobj(pq, threadID) ); + for (int i=0; i<N; ++i) agg.execute( pop_fnobj(pq) ); + } +}; + +void TestBasicInterface(int nThreads) { + pq_t my_pq; + tbb::aggregator agg; + for (int i=0; i<MaxThread; ++i) shared_data[i] = 0; + REMARK("Testing aggregator basic interface.\n"); + NativeParallelFor(nThreads, BasicBody(my_pq, agg)); + for (int i=0; i<nThreads; ++i) + ASSERT(shared_data[i] == N, "wrong number of elements pushed"); + REMARK("Done testing aggregator basic interface.\n"); +} +// End of code for testing basic interface using function objects + + +// Code for testing basic interface using lambda expressions +#if __TBB_CPP11_LAMBDAS_PRESENT +void TestBasicLambdaInterface(int nThreads) { + pq_t my_pq; + tbb::aggregator agg; + for (int i=0; i<MaxThread; ++i) shared_data[i] = 0; + REMARK("Testing aggregator basic lambda interface.\n"); + NativeParallelFor(nThreads, [&agg, &my_pq](const int threadID) { + for (int i=0; i<N; ++i) + agg.execute( [&, threadID]() { my_pq.push(threadID); } ); + for (int i=0; i<N; ++i) { + agg.execute( [&]() { + ASSERT(!my_pq.empty(), "queue should not be empty yet"); + int elem = my_pq.top(); + my_pq.pop(); + shared_data[elem]++; + } ); + } + } ); + for (int i=0; i<nThreads; ++i) + ASSERT(shared_data[i] == N, "wrong number of elements pushed"); + REMARK("Done testing aggregator basic lambda interface.\n"); +} +#endif /* __TBB_CPP11_LAMBDAS_PRESENT */ +// End of code for testing basic interface using lambda expressions + +// Code for testing expert interface +class op_data : public tbb::aggregator_operation, NoAssign { +public: + const int tid; + op_data(const int tid_=-1) : tbb::aggregator_operation(), tid(tid_) {} +}; + +class my_handler { + pq_t *pq; +public: + my_handler() {} + my_handler(pq_t *pq_) : pq(pq_) {} + void operator()(tbb::aggregator_operation* op_list) const { + while (op_list) { + op_data& request = static_cast<op_data&>(*op_list); + op_list = op_list->next(); + request.start(); + if (request.tid >= 0) pq->push(request.tid); + else { + ASSERT(!pq->empty(), "queue should not be empty!"); + int elem = pq->top(); + pq->pop(); + shared_data[elem]++; + } + request.finish(); + } + } +}; + +class ExpertBody : NoAssign { + tbb::aggregator_ext<my_handler>& agg; +public: + ExpertBody(tbb::aggregator_ext<my_handler>& agg_) : agg(agg_) {} + void operator()(const int threadID) const { + for (int i=0; i<N; ++i) { + op_data to_push(threadID); + agg.process( &to_push ); + } + for (int i=0; i<N; ++i) { + op_data to_pop; + agg.process( &to_pop ); + } + } +}; + +void TestExpertInterface(int nThreads) { + pq_t my_pq; + tbb::aggregator_ext<my_handler> agg((my_handler(&my_pq))); + for (int i=0; i<MaxThread; ++i) shared_data[i] = 0; + REMARK("Testing aggregator expert interface.\n"); + NativeParallelFor(nThreads, ExpertBody(agg)); + for (int i=0; i<nThreads; ++i) + ASSERT(shared_data[i] == N, "wrong number of elements pushed"); + REMARK("Done testing aggregator expert interface.\n"); +} +// End of code for testing expert interface + +int TestMain() { + if (MinThread < 1) + MinThread = 1; + shared_data = new int[MaxThread]; + for (int p = MinThread; p <= MaxThread; ++p) { + REMARK("Testing on %d threads.\n", p); + N = 0; + while (N <= 100) { + REMARK("Testing with N=%d\n", N); + TestBasicInterface(p); +#if __TBB_CPP11_LAMBDAS_PRESENT + TestBasicLambdaInterface(p); +#endif + TestExpertInterface(p); + N = N ? N*10 : 1; + } + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_aligned_space.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_aligned_space.cpp new file mode 100644 index 00000000..ec5b852b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_aligned_space.cpp @@ -0,0 +1,115 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +#if __TBB_GCC_STRICT_ALIASING_BROKEN + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + +//! Wrapper around T where all members are private. +/** Used to prove that aligned_space<T,N> never calls member of T. */ +template<typename T> +class Minimal { + Minimal(); + Minimal( Minimal& min ); + ~Minimal(); + void operator=( const Minimal& ); + T pad; + template<typename U> + friend void AssignToCheckAlignment( Minimal<U>& dst, const Minimal<U>& src ) ; +}; + +template<typename T> +void AssignToCheckAlignment( Minimal<T>& dst, const Minimal<T>& src ) { + dst.pad = src.pad; +} + +#include "tbb/aligned_space.h" +#include "harness_assert.h" + +static bool SpaceWasted; + +template<typename U, size_t N> +void TestAlignedSpaceN() { + typedef Minimal<U> T; + struct { + //! Pad byte increases chance that subsequent member will be misaligned if there is a problem. + char pad; + tbb::aligned_space<T ,N> space; + } x; + AssertSameType( static_cast< T *>(0), x.space.begin() ); + AssertSameType( static_cast< T *>(0), x.space.end() ); + ASSERT( reinterpret_cast<void *>(x.space.begin())==reinterpret_cast< void *>(&x.space), NULL ); + ASSERT( x.space.end()-x.space.begin()==N, NULL ); + ASSERT( reinterpret_cast<void *>(x.space.begin())>=reinterpret_cast< void *>(&x.space), NULL ); + ASSERT( x.space.end()<=reinterpret_cast< T *>(&x.space+1), NULL ); + // Though not required, a good implementation of aligned_space<T,N> does not use any more space than a T[N]. + SpaceWasted |= sizeof(x.space)!=sizeof(T)*N; + for( size_t k=1; k<N; ++k ) + AssignToCheckAlignment( x.space.begin()[k-1], x.space.begin()[k] ); +} + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" + +#include <typeinfo> +template<typename T> +void PrintSpaceWastingWarning() { + REPORT( "Consider rewriting aligned_space<%s,N> to waste less space\n", typeid(T).name() ); +} + +// RTTI for long double (128 bit) is broken in libc++ up-to NDK11c. Check on newer versions of NDK. +#if ( __ANDROID__ && __clang__ && _LIBCPP_VERSION && __TBB_x86_64 ) +template<> +void PrintSpaceWastingWarning<long double>() { + REPORT( "Consider rewriting aligned_space<ld,N> to waste less space\n" ); +} +#endif + +template<typename T> +void TestAlignedSpace() { + SpaceWasted = false; + TestAlignedSpaceN<T,1>(); + TestAlignedSpaceN<T,2>(); + TestAlignedSpaceN<T,3>(); + TestAlignedSpaceN<T,4>(); + TestAlignedSpaceN<T,5>(); + TestAlignedSpaceN<T,6>(); + TestAlignedSpaceN<T,7>(); + TestAlignedSpaceN<T,8>(); + if( SpaceWasted ) + PrintSpaceWastingWarning<T>(); +} + +#include "harness_m128.h" + +int TestMain () { + TestAlignedSpace<char>(); + TestAlignedSpace<short>(); + TestAlignedSpace<int>(); + TestAlignedSpace<float>(); + TestAlignedSpace<double>(); + TestAlignedSpace<long double>(); + TestAlignedSpace<size_t>(); +#if HAVE_m128 + TestAlignedSpace<__m128>(); +#endif +#if HAVE_m256 + if (have_AVX()) TestAlignedSpace<__m256>(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_allocator.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_allocator.h new file mode 100644 index 00000000..608d7647 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_allocator.h @@ -0,0 +1,278 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Basic testing of an allocator +// Tests against requirements in 20.1.5 of ISO C++ Standard (1998). +// Does not check for thread safety or false sharing issues. +// +// Tests for compatibility with the host's STL are in +// test_Allocator_STL.h. Those tests are in a separate file +// because they bring in lots of STL headers, and the tests here +// are supposed to work in the abscense of STL. + +#include "harness.h" +#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + #include <utility> //for std::pair +#endif + +template<typename A> +struct is_zero_filling { + static const bool value = false; +}; + +int NumberOfFoo; + +template<typename T, size_t N> +struct Foo { + T foo_array[N]; + Foo() { + zero_fill<T>(foo_array, N); + ++NumberOfFoo; + } + Foo( const Foo& x ) { + *this = x; + //Internal call of assignment + } + Foo& operator=( const Foo& x ) { + for (size_t i = 0; i < N; i++) + foo_array[i] = x.foo_array[i]; + ++NumberOfFoo; + return *this; + } + + ~Foo() { + --NumberOfFoo; + } +}; + +inline char PseudoRandomValue( size_t j, size_t k ) { + return char(j*3 ^ j>>4 ^ k); +} + +#if __APPLE__ +#include <fcntl.h> +#include <unistd.h> + +// A RAII class to disable stderr in a certain scope. It's not thread-safe. +class DisableStderr { + int stderrCopy; + static void dupToStderrAndClose(int fd) { + int ret = dup2(fd, STDERR_FILENO); // close current stderr + ASSERT(ret != -1, NULL); + ret = close(fd); + ASSERT(ret != -1, NULL); + } +public: + DisableStderr() { + int devNull = open("/dev/null", O_WRONLY); + ASSERT(devNull != -1, NULL); + stderrCopy = dup(STDERR_FILENO); + ASSERT(stderrCopy != -1, NULL); + dupToStderrAndClose(devNull); + } + ~DisableStderr() { + dupToStderrAndClose(stderrCopy); + } +}; +#endif + +//! T is type and A is allocator for that type +template<typename T, typename A> +void TestBasic( A& a ) { + T x; + const T cx = T(); + + // See Table 32 in ISO ++ Standard + typename A::pointer px = &x; + typename A::const_pointer pcx = &cx; + + typename A::reference rx = x; + ASSERT( &rx==&x, NULL ); + + typename A::const_reference rcx = cx; + ASSERT( &rcx==&cx, NULL ); + + typename A::value_type v = x; + + typename A::size_type size; + size = 0; + --size; + ASSERT( size>0, "not an unsigned integral type?" ); + + typename A::difference_type difference; + difference = 0; + --difference; + ASSERT( difference<0, "not an signed integral type?" ); + + // "rebind" tested by our caller + + ASSERT( a.address(rx)==px, NULL ); + + ASSERT( a.address(rcx)==pcx, NULL ); + + typename A::pointer array[100]; + size_t sizeof_T = sizeof(T); + for( size_t k=0; k<100; ++k ) { + array[k] = k&1 ? a.allocate(k,array[0]) : a.allocate(k); + char* s = reinterpret_cast<char*>(reinterpret_cast<void*>(array[k])); + for( size_t j=0; j<k*sizeof_T; ++j ) + s[j] = PseudoRandomValue(j,k); + } + + // Test hint argument. This can't be compiled when hint is void*, It should be const void* + typename A::pointer a_ptr; + const void * const_hint = NULL; + a_ptr = a.allocate (1, const_hint); + a.deallocate(a_ptr, 1); + + // Test "a.deallocate(p,n) + for( size_t k=0; k<100; ++k ) { + char* s = reinterpret_cast<char*>(reinterpret_cast<void*>(array[k])); + for( size_t j=0; j<k*sizeof_T; ++j ) + ASSERT( s[j] == PseudoRandomValue(j,k), NULL ); + a.deallocate(array[k],k); + } + + // Test "a.max_size()" + AssertSameType( a.max_size(), typename A::size_type(0) ); + // Following assertion catches case where max_size() is so large that computation of + // number of bytes for such an allocation would overflow size_type. + ASSERT( a.max_size()*typename A::size_type(sizeof(T))>=a.max_size(), "max_size larger than reasonable" ); + + // Test "a.construct(p,t)" + int n = NumberOfFoo; + typename A::pointer p = a.allocate(1); + a.construct( p, cx ); + ASSERT( NumberOfFoo==n+1, "constructor for Foo not called?" ); + + // Test "a.destroy(p)" + a.destroy( p ); + ASSERT( NumberOfFoo==n, "destructor for Foo not called?" ); + a.deallocate(p,1); + +#if TBB_USE_EXCEPTIONS + volatile size_t too_big = (~size_t(0) - 1024*1024)/sizeof(T); + bool exception_caught = false; + typename A::pointer p1 = NULL; + try { +#if __APPLE__ + // On macOS*, failure to map memory results in messages to stderr; + // suppress them. + DisableStderr disableStderr; +#endif + p1 = a.allocate(too_big); + } catch ( std::bad_alloc& ) { + exception_caught = true; + } + ASSERT( exception_caught, "allocate expected to throw bad_alloc" ); + a.deallocate(p1, too_big); +#endif // TBB_USE_EXCEPTIONS + + #if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC + { + typedef typename A:: template rebind<std::pair<typename A::value_type, typename A::value_type> >::other pair_allocator_type; + pair_allocator_type pair_allocator(a); + int NumberOfFooBeforeConstruct= NumberOfFoo; + typename pair_allocator_type::pointer pair_pointer = pair_allocator.allocate(1); + pair_allocator.construct( pair_pointer, cx, cx); + ASSERT( NumberOfFoo==NumberOfFooBeforeConstruct+2, "constructor for Foo not called appropriate number of times?" ); + + pair_allocator.destroy( pair_pointer ); + ASSERT( NumberOfFoo==NumberOfFooBeforeConstruct, "destructor for Foo not called appropriate number of times?" ); + pair_allocator.deallocate(pair_pointer,1); + } + #endif + +} + +#include "tbb/blocked_range.h" + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for erroneous "conditional expression is constant" warning in method check_allocate. + #pragma warning (disable: 4127) +#endif + +// A is an allocator for some type +template<typename A> +struct Body: NoAssign { + static const size_t max_k = 100000; + A &a; + Body(A &a_) : a(a_) {} + void check_allocate( typename A::pointer array[], size_t i, size_t t ) const + { + ASSERT(array[i] == 0, NULL); + size_t size = i * (i&3); + array[i] = i&1 ? a.allocate(size, array[i>>3]) : a.allocate(size); + ASSERT(array[i] != 0, "allocator returned null"); + char* s = reinterpret_cast<char*>(reinterpret_cast<void*>(array[i])); + for( size_t j=0; j<size*sizeof(typename A::value_type); ++j ) { + if(is_zero_filling<typename A::template rebind<void>::other>::value) + ASSERT( !s[j], NULL); + s[j] = PseudoRandomValue(i, t); + } + } + + void check_deallocate( typename A::pointer array[], size_t i, size_t t ) const + { + ASSERT(array[i] != 0, NULL); + size_t size = i * (i&3); + char* s = reinterpret_cast<char*>(reinterpret_cast<void*>(array[i])); + for( size_t j=0; j<size*sizeof(typename A::value_type); ++j ) + ASSERT( s[j] == PseudoRandomValue(i, t), "Thread safety test failed" ); + a.deallocate(array[i], size); + array[i] = 0; + } + + void operator()( size_t thread_id ) const { + typename A::pointer array[256]; + + for( size_t k=0; k<256; ++k ) + array[k] = 0; + for( size_t k=0; k<max_k; ++k ) { + size_t i = static_cast<unsigned char>(PseudoRandomValue(k,thread_id)); + if(!array[i]) check_allocate(array, i, thread_id); + else check_deallocate(array, i, thread_id); + } + for( size_t k=0; k<256; ++k ) + if(array[k]) + check_deallocate(array, k, thread_id); + } +}; + +// A is an allocator for some type, and U is another type +template<typename U, typename A> +void Test(A &a) { + typename A::template rebind<U>::other b(a); + TestBasic<U>(b); + TestBasic<typename A::value_type>(a); + + // thread safety + NativeParallelFor( 4, Body<A>(a) ); + ASSERT( NumberOfFoo==0, "Allocate/deallocate count mismatched" ); + + ASSERT( a==b, NULL ); + ASSERT( !(a!=b), NULL ); +} + +template<typename Allocator> +int TestMain(const Allocator &a = Allocator()) { + NumberOfFoo = 0; + typename Allocator::template rebind<Foo<char,1> >::other a1(a); + typename Allocator::template rebind<Foo<double,1> >::other a2(a); + Test<Foo<int,17> >( a1 ); + Test<Foo<float,23> >( a2 ); + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_allocator_STL.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_allocator_STL.h new file mode 100644 index 00000000..dddd12d8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_allocator_STL.h @@ -0,0 +1,147 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Tests for compatibility with the host's STL. + +#include "harness.h" + +template<typename Container> +void TestSequence(const typename Container::allocator_type &a) { + Container c(a); + for( int i=0; i<1000; ++i ) + c.push_back(i*i); + typename Container::const_iterator p = c.begin(); + for( int i=0; i<1000; ++i ) { + ASSERT( *p==i*i, NULL ); + ++p; + } + // regression test against compilation error for GCC 4.6.2 + c.resize(1000); +} + +template<typename Set> +void TestSet(const typename Set::allocator_type &a) { + Set s(typename Set::key_compare(), a); + typedef typename Set::value_type value_type; + for( int i=0; i<100; ++i ) + s.insert(value_type(3*i)); + for( int i=0; i<300; ++i ) { + ASSERT( s.erase(i)==size_t(i%3==0), NULL ); + } +} + +template<typename Map> +void TestMap(const typename Map::allocator_type &a) { + Map m(typename Map::key_compare(), a); + typedef typename Map::value_type value_type; + for( int i=0; i<100; ++i ) + m.insert(value_type(i,i*i)); + for( int i=0; i<100; ++i ) + ASSERT( m.find(i)->second==i*i, NULL ); +} + +#include <deque> +#include <list> +#include <map> +#include <set> +#include <vector> + +#if __TBB_CPP11_RVALUE_REF_PRESENT +struct MoveOperationTracker { + int my_value; + + MoveOperationTracker( int value = 0 ) : my_value( value ) {} + MoveOperationTracker(const MoveOperationTracker&) { + ASSERT( false, "Copy constructor is called" ); + } + MoveOperationTracker(MoveOperationTracker&& m) __TBB_NOEXCEPT( true ) : my_value( m.my_value ) { + } + MoveOperationTracker& operator=(MoveOperationTracker const&) { + ASSERT( false, "Copy assignment operator is called" ); + return *this; + } + MoveOperationTracker& operator=(MoveOperationTracker&& m) __TBB_NOEXCEPT( true ) { + my_value = m.my_value; + return *this; + } + + bool operator==(int value) const { + return my_value == value; + } + + bool operator==(const MoveOperationTracker& m) const { + return my_value == m.my_value; + } +}; +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +template<typename Allocator> +void TestAllocatorWithSTL(const Allocator &a = Allocator() ) { + +// Allocator type conversion section +#if __TBB_ALLOCATOR_TRAITS_PRESENT + typedef typename std::allocator_traits<Allocator>::template rebind_alloc<int> Ai; + typedef typename std::allocator_traits<Allocator>::template rebind_alloc<std::pair<const int, int> > Acii; +#if _MSC_VER + typedef typename std::allocator_traits<Allocator>::template rebind_alloc<const int> Aci; + typedef typename std::allocator_traits<Allocator>::template rebind_alloc<std::pair<int, int> > Aii; +#endif // _MSC_VER +#else + typedef typename Allocator::template rebind<int>::other Ai; + typedef typename Allocator::template rebind<std::pair<const int, int> >::other Acii; +#if _MSC_VER + typedef typename Allocator::template rebind<const int>::other Aci; + typedef typename Allocator::template rebind<std::pair<int, int> >::other Aii; +#endif // _MSC_VER +#endif // __TBB_ALLOCATOR_TRAITS_PRESENT + + // Sequenced containers + TestSequence<std::deque <int,Ai> >(a); + TestSequence<std::list <int,Ai> >(a); + TestSequence<std::vector<int,Ai> >(a); + +#if __TBB_CPP11_RVALUE_REF_PRESENT +#if __TBB_ALLOCATOR_TRAITS_PRESENT + typedef typename std::allocator_traits<Allocator>::template rebind_alloc<MoveOperationTracker> Amot; +#else + typedef typename Allocator::template rebind<MoveOperationTracker>::other Amot; +#endif // __TBB_ALLOCATOR_TRAITS_PRESENT + TestSequence<std::deque <MoveOperationTracker, Amot> >(a); + TestSequence<std::list <MoveOperationTracker, Amot> >(a); + TestSequence<std::vector<MoveOperationTracker, Amot> >(a); +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + + // Associative containers + TestSet<std::set <int, std::less<int>, Ai> >(a); + TestSet<std::multiset<int, std::less<int>, Ai> >(a); + TestMap<std::map <int, int, std::less<int>, Acii> >(a); + TestMap<std::multimap<int, int, std::less<int>, Acii> >(a); + +#if _MSC_VER && _CPPLIB_VER < 650 + // Test compatibility with Microsoft's implementation of std::allocator for some cases that + // are undefined according to the ISO standard but permitted by Microsoft. + TestSequence<std::deque <const int,Aci> >(a); +#if _CPPLIB_VER>=500 + TestSequence<std::list <const int,Aci> >(a); +#endif + TestSequence<std::vector<const int,Aci> >(a); + TestSet<std::set<const int, std::less<int>, Aci> >(a); + TestMap<std::map<int, int, std::less<int>, Aii> >(a); + TestMap<std::map<const int, int, std::less<int>, Acii> >(a); + TestMap<std::multimap<int, int, std::less<int>, Aii> >(a); + TestMap<std::multimap<const int, int, std::less<int>, Acii> >(a); +#endif /* _MSC_VER */ +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_arena_constraints_hwloc.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_arena_constraints_hwloc.cpp new file mode 100644 index 00000000..bffe707e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_arena_constraints_hwloc.cpp @@ -0,0 +1,383 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_PREVIEW_NUMA_SUPPORT 1 +#define __TBB_EXTRA_DEBUG 1 + +#ifndef NUMBER_OF_PROCESSORS_GROUPS +#define NUMBER_OF_PROCESSORS_GROUPS 1 +#endif + +#include "tbb/tbb_config.h" + +#include "harness.h" +#include "harness_memory.h" +#include "harness_barrier.h" + +#include "tbb/task_arena.h" +#include "tbb/task_scheduler_init.h" + +#include <vector> + +#if __TBB_CPP11_PRESENT +#include <atomic> +#endif /*__TBB_CPP11_PRESENT*/ + +#if _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4100 ) +#endif +#include <hwloc.h> +#if _MSC_VER +#pragma warning( pop ) +#endif + +#include "tbb/concurrent_unordered_set.h" +#include "tbb/parallel_for.h" + +// Macro to check hwloc interfaces return codes +#define hwloc_assert_ex(command, ...) \ + ASSERT(command(__VA_ARGS__) >= 0, "Error occured inside hwloc call."); + +namespace numa_validation { + namespace { + class system_info_t { + hwloc_topology_t topology; + + hwloc_nodeset_t process_node_set; + hwloc_cpuset_t process_cpu_set; + + hwloc_cpuset_t buffer_cpu_set; + hwloc_cpuset_t buffer_node_set; + + // hwloc_cpuset_t, hwloc_nodeset_t (inherited from hwloc_bitmap_t ) is pointers, + // so we must manage memory allocation and deallocation + typedef tbb::concurrent_unordered_set<hwloc_bitmap_t> memory_handler_t; + memory_handler_t memory_handler; + + bool is_initialized; + public: + system_info_t() : memory_handler() { + is_initialized = false; + } + + void initialize() { + if (is_initialized) return; + + hwloc_assert_ex(hwloc_topology_init, &topology); + hwloc_assert_ex(hwloc_topology_load, topology); + + if ( Harness::GetIntEnv("NUMBER_OF_PROCESSORS_GROUPS") > 1 ) { + process_cpu_set = hwloc_bitmap_dup(hwloc_topology_get_complete_cpuset (topology)); + process_node_set = hwloc_bitmap_dup(hwloc_topology_get_complete_nodeset(topology)); + } else { + process_cpu_set = hwloc_bitmap_alloc(); + process_node_set = hwloc_bitmap_alloc(); + + hwloc_assert_ex(hwloc_get_cpubind, topology, process_cpu_set, 0); + hwloc_cpuset_to_nodeset(topology, process_cpu_set, process_node_set); + } + + // If system contains no NUMA nodes, HWLOC 1.11 returns an infinitely filled bitmap. + // hwloc_bitmap_weight() returns negative value for such bitmaps, so we use this check + // to workaround this case. + if (hwloc_bitmap_weight(process_node_set) <= 0) { + hwloc_bitmap_only(process_node_set, 0); + } + +// Debug macros for test topology parser validation +#if NUMBER_OF_NUMA_NODES + ASSERT(hwloc_bitmap_weight(process_node_set) == NUMBER_OF_NUMA_NODES, + "Manual NUMA nodes count check."); +#endif /*NUMBER_OF_NUMA_NODES*/ + + buffer_cpu_set = hwloc_bitmap_alloc(); + buffer_node_set = hwloc_bitmap_alloc(); + + is_initialized = true; + } + + ~system_info_t() { + if (is_initialized) { + for (memory_handler_t::iterator it = memory_handler.begin(); + it != memory_handler.end(); it++) { + hwloc_bitmap_free(*it); + } + hwloc_bitmap_free(process_cpu_set); + hwloc_bitmap_free(process_node_set); + hwloc_bitmap_free(buffer_cpu_set); + hwloc_bitmap_free(buffer_node_set); + + hwloc_topology_destroy(topology); + } + } + + hwloc_bitmap_t allocate_empty_affinity_mask() { + __TBB_ASSERT(is_initialized, "Call of uninitialized system_info"); + hwloc_bitmap_t result = hwloc_bitmap_alloc(); + memory_handler.insert(result); + return result; + } + + hwloc_cpuset_t allocate_current_cpu_set() { + __TBB_ASSERT(is_initialized, "Call of uninitialized system_info"); + hwloc_cpuset_t current_affinity_mask = allocate_empty_affinity_mask(); + hwloc_assert_ex(hwloc_get_cpubind, topology, current_affinity_mask, HWLOC_CPUBIND_THREAD ); + ASSERT(!hwloc_bitmap_iszero(current_affinity_mask), "Empty current affinity mask."); + return current_affinity_mask; + } + + hwloc_const_cpuset_t get_process_cpu_set() { + __TBB_ASSERT(is_initialized, "Call of uninitialized system_info"); + return process_cpu_set; + } + + hwloc_const_nodeset_t get_process_node_set() { + __TBB_ASSERT(is_initialized, "Call of uninitialized system_info"); + return process_node_set; + } + + int numa_node_max_concurrency(int index) { + __TBB_ASSERT(is_initialized, "Call of uninitialized system_info"); + hwloc_bitmap_only(buffer_node_set, index); + hwloc_cpuset_from_nodeset(topology, buffer_cpu_set, buffer_node_set); + hwloc_bitmap_and(buffer_cpu_set, buffer_cpu_set, process_cpu_set); + ASSERT(hwloc_bitmap_weight(buffer_cpu_set) > 0, "Negative concurrency."); + return hwloc_bitmap_weight(buffer_cpu_set); + } + }; + + static system_info_t system_info; + } /*internal namespace*/ + +typedef hwloc_bitmap_t affinity_mask; +typedef hwloc_const_bitmap_t const_affinity_mask; + +void initialize_system_info() { system_info.initialize(); } + +affinity_mask allocate_current_cpu_set() { + return system_info.allocate_current_cpu_set(); +} + +bool affinity_masks_isequal(const_affinity_mask first, const_affinity_mask second) { + return hwloc_bitmap_isequal(first, second) ? true : false; +} + +bool affinity_masks_intersects(const_affinity_mask first, const_affinity_mask second) { + return hwloc_bitmap_intersects(first, second) ? true : false; +} + +void validate_topology_information(std::vector<int> numa_indexes) { + // Generate available numa nodes bitmap + const_affinity_mask process_node_set = system_info.get_process_node_set(); + + // Parse input indexes list to numa nodes bitmap + affinity_mask merged_input_node_set = system_info.allocate_empty_affinity_mask(); + int whole_system_concurrency = 0; + for (unsigned i = 0; i < numa_indexes.size(); i++) { + ASSERT(!hwloc_bitmap_isset(merged_input_node_set, numa_indexes[i]), "Indices are repeated."); + hwloc_bitmap_set(merged_input_node_set, numa_indexes[i]); + + ASSERT(tbb::info::default_concurrency(numa_indexes[i]) == + system_info.numa_node_max_concurrency(numa_indexes[i]), + "Wrong default concurrency value."); + whole_system_concurrency += tbb::info::default_concurrency(numa_indexes[i]); + } + + ASSERT(whole_system_concurrency == tbb::task_scheduler_init::default_num_threads(), + "Wrong whole system default concurrency level."); + ASSERT(affinity_masks_isequal(process_node_set, merged_input_node_set), + "Input array of indices is not equal with proccess numa node set."); +} + +} /*namespace numa_validation*/ + +#if __TBB_CPP11_PRESENT +namespace numa_validation { + template <typename It> + typename std::enable_if<std::is_same<typename std::iterator_traits<It>::value_type, affinity_mask>::value, void>:: + type affinity_set_verification(It begin, It end) { + affinity_mask buffer_mask = system_info.allocate_empty_affinity_mask(); + for (auto it = begin; it != end; it++) { + ASSERT(!hwloc_bitmap_intersects(buffer_mask, *it), + "Bitmaps that are binded to different nodes are intersects."); + // Add masks to buffer_mask to concatenate process affinity mask + hwloc_bitmap_or(buffer_mask, buffer_mask, *it); + } + + ASSERT(affinity_masks_isequal(system_info.get_process_cpu_set(), buffer_mask), + "Some cores was not included to bitmaps."); + } +} /*namespace numa_validation*/ + +struct execute_wrapper { + template <typename Callable> + void emplace_function(tbb::task_arena& ta, Callable functor) { + ta.execute(functor); + } +}; + +struct enqueue_wrapper { + template <typename Callable> + void emplace_function(tbb::task_arena& ta, Callable functor) { + ta.enqueue(functor); + } +}; + +template <typename It, typename FuncWrapper> +typename std::enable_if<std::is_same<typename std::iterator_traits<It>::value_type, tbb::task_arena>::value, void>:: +type test_numa_binding_impl(It begin, It end, FuncWrapper wrapper) { + tbb::concurrent_unordered_set<numa_validation::affinity_mask> affinity_masks; + std::atomic<unsigned> counter(0), expected_count(0); + + auto affinity_mask_checker = [&counter, &affinity_masks]() { + affinity_masks.insert(numa_validation::allocate_current_cpu_set()); + counter++; + }; + + for (auto it = begin; it != end; it++) { + expected_count++; + wrapper.emplace_function(*it, affinity_mask_checker); + } + + // Wait for all spawned tasks + while (counter != expected_count) {} + numa_validation::affinity_set_verification(affinity_masks.begin(),affinity_masks.end()); +} + +void test_numa_binding(std::vector<int> numa_indexes_vector) { + + std::vector<tbb::task_arena> arenas(numa_indexes_vector.size()); + + for(unsigned i = 0; i < numa_indexes_vector.size(); i++) { + // Bind arenas to numa nodes + arenas[i].initialize(tbb::task_arena::constraints(numa_indexes_vector[i])); + } + + test_numa_binding_impl(arenas.begin(), arenas.end(), execute_wrapper()); + test_numa_binding_impl(arenas.begin(), arenas.end(), enqueue_wrapper()); +} + +void recursive_arena_binding(int*, int, numa_validation::affinity_mask); + +void recursive_arena_binding(int* numa_indexes, size_t count, + std::vector<numa_validation::affinity_mask>& affinity_masks) { + if (count > 0) { + tbb::task_arena current_level_arena; + current_level_arena.initialize(tbb::task_arena::constraints(numa_indexes[count - 1])); + current_level_arena.execute( + [&numa_indexes, &count, &affinity_masks]() { + affinity_masks.push_back(numa_validation::allocate_current_cpu_set()); + recursive_arena_binding(numa_indexes, --count, affinity_masks); + } + ); + } else { + // Validation of assigned affinity masks at the deepest recursion step + numa_validation::affinity_set_verification(affinity_masks.begin(), affinity_masks.end()); + } + + if (!affinity_masks.empty()) { + ASSERT(numa_validation::affinity_masks_isequal(affinity_masks.back(), + numa_validation::allocate_current_cpu_set()), + "After binding to different NUMA node thread affinity was not returned to previous state."); + affinity_masks.pop_back(); + } +} + +void test_nested_numa_binding(std::vector<int> numa_indexes_vector) { + std::vector<numa_validation::affinity_mask> affinity_masks; + recursive_arena_binding(numa_indexes_vector.data(), numa_indexes_vector.size(), affinity_masks); +} + +void test_memory_leak(std::vector<int> numa_indexes_vector){ + size_t big_number = 1000; + size_t current_memory_usage = 0, previous_memory_usage = 0, stability_counter=0; + for (size_t i = 0; i < big_number; i++) { + { /* All DTORs must be called before GetMemoryUsage() call*/ + std::vector<tbb::task_arena> arenas(numa_indexes_vector.size()); + std::vector<Harness::SpinBarrier> barriers(numa_indexes_vector.size()); + + for(unsigned j = 0; j < numa_indexes_vector.size(); j++) { + arenas[j].initialize(tbb::task_arena::constraints(numa_indexes_vector[j])); + barriers[j].initialize(arenas[j].max_concurrency()); + Harness::SpinBarrier& barrier_ref = barriers[j]; + arenas[j].enqueue([&barrier_ref](){ + tbb::parallel_for(tbb::blocked_range<size_t>(0, tbb::this_task_arena::max_concurrency()), + [&barrier_ref](const tbb::blocked_range<size_t>&){ + barrier_ref.wait(); + }); + }); + } + + for(unsigned j = 0; j < numa_indexes_vector.size(); j++) { + arenas[j].debug_wait_until_empty(); + } + } + + current_memory_usage = GetMemoryUsage(); + stability_counter = current_memory_usage==previous_memory_usage ? stability_counter + 1 : 0; + // If the amount of used memory has not changed during 10% of executions, + // then we can assume that the check was successful + if (stability_counter > big_number / 10) return; + previous_memory_usage = current_memory_usage; + } + ASSERT(false, "Seems like we get memory leak here."); +} + +// Check that arena constraints are copied during copy construction +void test_arena_constraints_copying(std::vector<int> numa_indexes) { + for (auto index: numa_indexes) { + numa_validation::affinity_mask constructed_mask, copied_mask; + + tbb::task_arena constructed{tbb::task_arena::constraints(index)}; + constructed.execute([&constructed_mask](){ + constructed_mask = numa_validation::allocate_current_cpu_set(); + }); + + tbb::task_arena copied(constructed); + copied.execute([&copied_mask](){ + copied_mask = numa_validation::allocate_current_cpu_set(); + }); + + ASSERT(numa_validation::affinity_masks_isequal(constructed_mask, copied_mask), + "Affinity mask brokes during copy construction"); + } +} +#endif /*__TBB_CPP11_PRESENT*/ + +//TODO: Write a test that checks for memory leaks during dynamic link/unlink of TBBbind. +int TestMain() { +#if _WIN32 && !_WIN64 + // HWLOC cannot proceed affinity masks on Windows in 32-bit mode if there are more than 32 logical CPU. + SYSTEM_INFO si; + GetNativeSystemInfo(&si); + if (si.dwNumberOfProcessors > 32) return Harness::Skipped; +#endif // _WIN32 && !_WIN64 + + numa_validation::initialize_system_info(); + + std::vector<int> numa_indexes = tbb::info::numa_nodes(); + numa_validation::validate_topology_information(numa_indexes); + +#if __TBB_CPP11_PRESENT + test_numa_binding(numa_indexes); + test_nested_numa_binding(numa_indexes); + test_memory_leak(numa_indexes); + test_arena_constraints_copying(numa_indexes); +#endif /*__TBB_CPP11_PRESENT*/ + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_arena_constraints_stubs.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_arena_constraints_stubs.cpp new file mode 100644 index 00000000..838c1985 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_arena_constraints_stubs.cpp @@ -0,0 +1,41 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +#define TBB_PREVIEW_NUMA_SUPPORT 1 +#include "tbb/tbb_config.h" + +#include "harness.h" + +#include "tbb/task_arena.h" +#include "tbb/task_scheduler_init.h" + +#include <vector> + +void test_stubs(std::vector<int> numa_indexes) { + ASSERT(numa_indexes.size() == 1, "Number of NUMA nodes must be pinned to 1," + " if we have no HWLOC on the system."); + ASSERT(numa_indexes[0] == -1, "Index of NUMA node must be pinned to 0," + " if we have no HWLOC on the system."); + ASSERT(tbb::info::default_concurrency(numa_indexes[0]) == tbb::task_scheduler_init::default_num_threads(), + "Concurrency for NUMA node must be equal to default_num_threads()," + " if we have no HWLOC on the system."); +} + +int TestMain() { + std::vector<int> numa_indexes = tbb::info::numa_nodes(); + test_stubs(numa_indexes); + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_assembly.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_assembly.cpp new file mode 100644 index 00000000..800b3eab --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_assembly.cpp @@ -0,0 +1,160 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Program for basic correctness testing of assembly-language routines. +#include "harness_defs.h" +//for ICC builtins mode the test will be skipped as +//macro __TBB_GCC_BUILTIN_ATOMICS_PRESENT used to define __TBB_TEST_SKIP_GCC_BUILTINS_MODE +//will not be defined (it is explicitly disabled for ICC) +#if __TBB_TEST_SKIP_GCC_BUILTINS_MODE +#include "harness.h" +int TestMain() { + REPORT("Known issue: GCC builtins aren't available\n"); + return Harness::Skipped; +} +#else + +#include "tbb/task.h" + +#include <new> +#include "harness.h" + +using tbb::internal::reference_count; + +//TODO: remove this function when atomic function __TBB_XXX are dropped +//! Test __TBB_CompareAndSwapW +static void TestCompareExchange() { + ASSERT( intptr_t(-10)<10, "intptr_t not a signed integral type?" ); + REMARK("testing __TBB_CompareAndSwapW\n"); + for( intptr_t a=-10; a<10; ++a ) + for( intptr_t b=-10; b<10; ++b ) + for( intptr_t c=-10; c<10; ++c ) { +// Workaround for a bug in GCC 4.3.0; and one more is below. +#if __TBB_GCC_OPTIMIZER_ORDERING_BROKEN + intptr_t x; + __TBB_store_with_release( x, a ); +#else + intptr_t x = a; +#endif + intptr_t y = __TBB_CompareAndSwapW(&x,b,c); + ASSERT( y==a, NULL ); + if( a==c ) + ASSERT( x==b, NULL ); + else + ASSERT( x==a, NULL ); + } +} + +//TODO: remove this function when atomic function __TBB_XXX are dropped +//! Test __TBB___TBB_FetchAndIncrement and __TBB___TBB_FetchAndDecrement +static void TestAtomicCounter() { + // "canary" is a value used to detect illegal overwrites. + const reference_count canary = ~(uintptr_t)0/3; + REMARK("testing __TBB_FetchAndIncrement\n"); + struct { + reference_count prefix, i, suffix; + } x; + x.prefix = canary; + x.i = 0; + x.suffix = canary; + for( int k=0; k<10; ++k ) { + reference_count j = __TBB_FetchAndIncrementWacquire((volatile void *)&x.i); + ASSERT( x.prefix==canary, NULL ); + ASSERT( x.suffix==canary, NULL ); + ASSERT( x.i==k+1, NULL ); + ASSERT( j==k, NULL ); + } + REMARK("testing __TBB_FetchAndDecrement\n"); + x.i = 10; + for( int k=10; k>0; --k ) { + reference_count j = __TBB_FetchAndDecrementWrelease((volatile void *)&x.i); + ASSERT( j==k, NULL ); + ASSERT( x.i==k-1, NULL ); + ASSERT( x.prefix==canary, NULL ); + ASSERT( x.suffix==canary, NULL ); + } +} + +static void TestTinyLock() { + REMARK("testing __TBB_LockByte\n"); + __TBB_atomic_flag flags[16]; + for( unsigned int i=0; i<16; ++i ) + flags[i] = (__TBB_Flag)i; +#if __TBB_GCC_OPTIMIZER_ORDERING_BROKEN + __TBB_store_with_release( flags[8], 0 ); +#else + flags[8] = 0; +#endif + __TBB_LockByte(flags[8]); + for( unsigned int i=0; i<16; ++i ) + #ifdef __sparc + ASSERT( flags[i]==(i==8?0xff:i), NULL ); + #else + ASSERT( flags[i]==(i==8?1:i), NULL ); + #endif + __TBB_UnlockByte(flags[8]); + for( unsigned int i=0; i<16; ++i ) + ASSERT( flags[i] == (i==8?0:i), NULL ); +} + +static void TestLog2() { + REMARK("testing __TBB_Log2\n"); + for( uintptr_t i=1; i; i<<=1 ) { + for( uintptr_t j=1; j<1<<16; ++j ) { + if( uintptr_t k = i*j ) { + uintptr_t actual = __TBB_Log2(k); + const uintptr_t ONE = 1; // warning suppression again + ASSERT( k >= ONE<<actual, NULL ); + ASSERT( k>>1 < ONE<<actual, NULL ); + } + } + } +} + +static void TestPause() { + REMARK("testing __TBB_Pause\n"); + __TBB_Pause(1); +} + +static void TestTimeStamp() { + REMARK("testing __TBB_time_stamp"); +#if defined(__TBB_time_stamp) + tbb::internal::machine_tsc_t prev = __TBB_time_stamp(); + for ( int i=0; i<1000; ++i ) { + tbb::internal::machine_tsc_t curr = __TBB_time_stamp(); + ASSERT(curr>prev, "__TBB_time_stamp has returned non-monotonically increasing quantity"); + prev=curr; + } + REMARK("\n"); +#else + REMARK(" skipped\n"); +#endif +} + +int TestMain () { + __TBB_TRY { + TestLog2(); + TestTinyLock(); + TestCompareExchange(); + TestAtomicCounter(); + TestPause(); + TestTimeStamp(); + } __TBB_CATCH(...) { + ASSERT(0,"unexpected exception"); + } + return Harness::Done; +} +#endif // __TBB_TEST_SKIP_BUILTINS_MODE diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_async_msg.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_async_msg.cpp new file mode 100644 index 00000000..267d07d9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_async_msg.cpp @@ -0,0 +1,599 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef TBB_PREVIEW_FLOW_GRAPH_FEATURES + #define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1 +#endif + +#include "tbb/tbb_config.h" + +#if __TBB_PREVIEW_ASYNC_MSG + +#if _MSC_VER +#pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning +#endif + +#include "tbb/flow_graph.h" +#include "tbb/tbb_thread.h" +#include "tbb/concurrent_queue.h" + +#include "harness.h" +#include "harness_graph.h" +#include "harness_barrier.h" + +#include <sstream> // std::ostringstream +#include <type_traits> // std::is_base_of + +static const int USE_N = 1000; +static const int ACTIVITY_PAUSE_MS_NODE1 = 0;//500; +static const int ACTIVITY_PAUSE_MS_NODE2 = 0;//100; + +#define _TRACE_(msg) { \ + if (Verbose) { \ + std::ostringstream os; \ + os << "[TID=" << tbb::this_tbb_thread::get_id() << "] " << msg; \ + REMARK("%s\n", os.str().c_str()); \ + } \ +} + +class UserAsyncActivity // Singleton +{ +public: + static UserAsyncActivity* create(const tbb::flow::async_msg<int>& msg, int timeoutMS) { + ASSERT(s_Activity == NULL, "created twice"); + _TRACE_( "Create UserAsyncActivity" ); + s_Activity = new UserAsyncActivity(msg, timeoutMS); + _TRACE_( "CREATED! UserAsyncActivity" ); + return s_Activity; + } + + static void destroy() { + _TRACE_( "Start UserAsyncActivity::destroy()" ); + ASSERT(s_Activity != NULL, "destroyed twice"); + s_Activity->myThread.join(); + delete s_Activity; + s_Activity = NULL; + _TRACE_( "End UserAsyncActivity::destroy()" ); + } + + static int s_Result; + +private: + static void threadFunc(UserAsyncActivity* activity) { + _TRACE_( "UserAsyncActivity::threadFunc" ); + + Harness::Sleep(activity->myTimeoutMS); + + const int result = static_cast<int>(reinterpret_cast<size_t>(activity)) & 0xFF; // just different random results + s_Result = result; + + _TRACE_( "UserAsyncActivity::threadFunc - returned result " << result ); + + activity->returnActivityResults(result); + } + + UserAsyncActivity(const tbb::flow::async_msg<int>& msg, int timeoutMS) : myMsg(msg), myTimeoutMS(timeoutMS) + , myThread(threadFunc, this) + { + // Start local thread here... + _TRACE_( "Started AsyncActivity" ); + } + + // Will be called from working thread + void returnActivityResults(int result) { + myMsg.set(result); + } + +private: // DATA + tbb::flow::async_msg<int> myMsg; + int myTimeoutMS; + tbb::tbb_thread myThread; + + static UserAsyncActivity* s_Activity; +}; + +UserAsyncActivity* UserAsyncActivity::s_Activity = NULL; +int UserAsyncActivity::s_Result = -1; + +class UserAsyncMsg1 : public tbb::flow::async_msg<int> +{ +public: + typedef tbb::flow::async_msg<int> base; +}; + +struct F2_body : tbb::internal::no_assign +{ + static int s_FinalResult; + + int& myI; + bool myAlive; + + F2_body(int& i) : myI(i), myAlive(true) {} + + F2_body(const F2_body& b) : no_assign(), myI(b.myI), myAlive(true) {} + + ~F2_body() { + myAlive = false; + _TRACE_( "~F2_body" ); + } + + void operator () (int result) { + __TBB_ASSERT(myAlive, "dead node"); + + // Handle async activity result here + s_FinalResult = result; + _TRACE_( "F2: Got async_msg result = " << result ); + } +}; + +// static +int F2_body::s_FinalResult = -2; + +static bool testSimplestCase() { + bool bOk = true; + _TRACE_( "--- SAMPLE 1 (simple case 3-in-1: F1(A<T>) ---> F2(T)) " ); + + for (int i = 0; i <= 2; ++i) { + _TRACE_( "CASE " << i + 1 << ": data is " << (i > 0 ? "NOT " : "") << "ready in storage" << (i > 1 ? " NO WAITING in graph" : "") ); + _TRACE_( "MAIN THREAD" ); + + { + tbb::flow::graph g; + tbb::flow::function_node< tbb::flow::continue_msg, UserAsyncMsg1 > f1( g, tbb::flow::unlimited, + [&]( tbb::flow::continue_msg ) -> UserAsyncMsg1 { + _TRACE_( "F1: Created async_msg" ); + + UserAsyncMsg1 a; + UserAsyncActivity::create(a, (i == 0 ? 0 : 1)*ACTIVITY_PAUSE_MS_NODE1); + + Harness::Sleep(ACTIVITY_PAUSE_MS_NODE2); // let activity to finish + return a; + } + ); + + + tbb::flow::function_node< int > f2( g, tbb::flow::unlimited, + F2_body(i) + ); + + make_edge(f1, f2); + f1.try_put( tbb::flow::continue_msg() ); + g.wait_for_all(); + UserAsyncActivity::destroy(); + _TRACE_( "Done UserAsyncActivity::destroy" ); + g.wait_for_all(); + _TRACE_( "Done g.wait_for_all()" ); + } + + _TRACE_( "--- THE END --- " ); + + if (F2_body::s_FinalResult >= 0 && UserAsyncActivity::s_Result == F2_body::s_FinalResult) { + _TRACE_( "CASE " << i + 1 << ": " << "PASSED" ); + } + else { + _TRACE_( "CASE " << i + 1 << ": " << "FAILED! " << UserAsyncActivity::s_Result << " != " << F2_body::s_FinalResult ); + bOk = false; + ASSERT(0, "testSimplestCase failed"); + } + } + + return bOk; +} + +// ======================================================== + +class UserAsyncActivityChaining; + +class UserAsyncMsg : public tbb::flow::async_msg<int> +{ +public: + typedef tbb::flow::async_msg<int> base; + + UserAsyncMsg() : base() {} + UserAsyncMsg(int value) : base(value) {} + + // Notify AsyncActivity that it must return result because async calculation chain is over + void finalize() const __TBB_override; +}; + +class UserAsyncActivityChaining // Singleton: task queue in worker thread +{ +public: + static UserAsyncActivityChaining* instance() { + if (s_Activity == NULL) { + s_Activity = new UserAsyncActivityChaining(); + } + + return s_Activity; + } + + static void destroy() { + ASSERT(s_Activity != NULL, "destroyed twice"); + s_Activity->myThread.join(); + delete s_Activity; + s_Activity = NULL; + } + + static void finish(const UserAsyncMsg& msg) { + ASSERT(UserAsyncActivityChaining::s_Activity != NULL, "activity must be alive"); + UserAsyncActivityChaining::s_Activity->finishTaskQueue(msg); + } + + void addWork(int addValue, int timeout = 0) { + myQueue.push( MyTask(addValue, timeout) ); + } + + void finishTaskQueue(const UserAsyncMsg& msg) { + myMsg = msg; + myQueue.push( MyTask(0, 0, true) ); + } + + static int s_Result; + +private: + struct MyTask + { + MyTask(int addValue = 0, int timeout = 0, bool finishFlag = false) + : myAddValue(addValue), myTimeout(timeout), myFinishFlag(finishFlag) {} + + int myAddValue; + int myTimeout; + bool myFinishFlag; + }; + + static void threadFunc(UserAsyncActivityChaining* activity) + { + _TRACE_( "UserAsyncActivityChaining::threadFunc" ); + + for (;;) + { + // Process task queue + MyTask work; + activity->myQueue.pop(work); // Waits until it can succeed + + _TRACE_( "UserAsyncActivityChaining::threadFunc - work: add " + << work.myAddValue << " (timeout = " << work.myTimeout << ")" << (work.myFinishFlag ? " FINAL" : "") ); + + // 'finish flag' task is not real task, just end of queue flag + Harness::Sleep(work.myTimeout); + + if (work.myFinishFlag) { + break; + } + + activity->myQueueSum += work.myAddValue; + } + + s_Result = activity->myQueueSum; + _TRACE_( "UserAsyncActivityChaining::threadFunc - returned result " << activity->myQueueSum ); + + // Get result back to Flow Graph + activity->myMsg.set(activity->myQueueSum); + } + + UserAsyncActivityChaining() + : myQueueSum(0) + , myThread(threadFunc, this) + { + // Start local thread here... + _TRACE_( "Started AsyncActivityChaining" ); + } + +private: // DATA + tbb::concurrent_bounded_queue<MyTask> myQueue; + int myQueueSum; + UserAsyncMsg myMsg; + + tbb::tbb_thread myThread; + + static UserAsyncActivityChaining* s_Activity; +}; + +// static +UserAsyncActivityChaining* UserAsyncActivityChaining::s_Activity = NULL; +// static +int UserAsyncActivityChaining::s_Result = -4; + +// override +void UserAsyncMsg::finalize() const { + _TRACE_( "UserAsyncMsg::finalize()" ); + UserAsyncActivityChaining::finish(*this); +} + +struct F3_body : tbb::internal::no_assign +{ + static int s_FinalResult; + + int& myI; + bool myAlive; + + F3_body(int& _i) : myI(_i), myAlive(true) {} + + F3_body(const F3_body& b) : no_assign(), myI(b.myI), myAlive(true) {} + + ~F3_body() { + myAlive = false; + _TRACE_( "~F3_body" ); + } + + void operator () (int result) { + __TBB_ASSERT(myAlive, "dead node"); + // Handle async activity result here + s_FinalResult = result; + _TRACE_( "F3: Got async_msg result = " << result ); + } +}; + +// static +int F3_body::s_FinalResult = -8; + +static bool testChaining() { + bool bOk = true; + _TRACE_( "--- SAMPLE 2 (case with chaining: F1(A<T>) ---> F2(A<T>) ---> F3(T)) " ); + + for (int i = 0; i <= 2; ++i) { + _TRACE_( "CASE " << i + 1 << ": data is " << (i > 0 ? "NOT " : "") << "ready in storage" << (i > 1 ? " NO WAITING in graph" : "") ); + _TRACE_( "MAIN THREAD" ); + + tbb::flow::graph g; + tbb::flow::function_node< tbb::flow::continue_msg, UserAsyncMsg > f1( g, tbb::flow::unlimited, + [&]( tbb::flow::continue_msg ) -> UserAsyncMsg { + _TRACE_( "F1: Created UserAsyncMsg" ); + + UserAsyncMsg a; + UserAsyncActivityChaining::instance()->addWork(11, (i == 0 ? 0 : 1)*ACTIVITY_PAUSE_MS_NODE1); + + return a; + } + ); + + tbb::flow::function_node< UserAsyncMsg, UserAsyncMsg > f2( g, tbb::flow::unlimited, + [&]( UserAsyncMsg a) -> UserAsyncMsg { + _TRACE_( "F2: resend UserAsyncMsg" ); + + UserAsyncActivityChaining::instance()->addWork(22, (i == 0 ? 0 : 1)*ACTIVITY_PAUSE_MS_NODE1); + + Harness::Sleep(ACTIVITY_PAUSE_MS_NODE2); // let activity to finish + return a; + } + ); + + tbb::flow::function_node< int > f3( g, tbb::flow::unlimited, + F3_body(i) + ); + + make_edge(f1, f2); + make_edge(f2, f3); + f1.try_put( tbb::flow::continue_msg() ); + g.wait_for_all(); + + UserAsyncActivityChaining::destroy(); + _TRACE_( "Done UserAsyncActivityChaining::destroy" ); + g.wait_for_all(); + _TRACE_( "Done g.wait_for_all()" ); + + _TRACE_( "--- THE END ---" ); + + if (F3_body::s_FinalResult >= 0 && UserAsyncActivityChaining::s_Result == F3_body::s_FinalResult) { + _TRACE_( "CASE " << i + 1 << ": " << "PASSED" ); + } + else { + _TRACE_( "CASE " << i + 1 << ": " << "FAILED! " << UserAsyncActivityChaining::s_Result << " != " << F3_body::s_FinalResult ); + bOk = false; + ASSERT(0, "testChaining failed"); + } + } + + return bOk; +} + +// ======================================================== +namespace testFunctionsAvailabilityNS { + +using namespace tbb::flow; +using tbb::flow::interface11::internal::untyped_sender; +using tbb::flow::interface11::internal::untyped_receiver; + +using tbb::internal::is_same_type; +using tbb::internal::strip; +using tbb::flow::interface11::internal::wrap_tuple_elements; +using tbb::flow::interface11::internal::async_helpers; + +class A {}; // Any type (usually called 'T') +struct ImpossibleType {}; + +template <typename T> +struct UserAsync_T : public async_msg<T> { + UserAsync_T() {} + UserAsync_T(const T& t) : async_msg<T>(t) {} +}; + +typedef UserAsync_T<int > UserAsync_int; +typedef UserAsync_T<float> UserAsync_float; +typedef UserAsync_T<A > UserAsync_A; + +typedef tuple< UserAsync_A, UserAsync_float, UserAsync_int, async_msg<A>, async_msg<float>, async_msg<int>, A, float, int > TypeTuple; + +static int g_CheckerCounter = 0; + +template <typename T, typename U> +struct CheckerTryPut { + static ImpossibleType check( ... ); + + template <typename C> + static auto check( C* p, U* q ) -> decltype(p->try_put(*q)); + + static const bool value = !is_same_type<decltype(check(static_cast<T*>(0), 0)), ImpossibleType>::value; +}; + +template <typename T1, typename T2> +struct CheckerMakeEdge { + static ImpossibleType checkMake( ... ); + static ImpossibleType checkRemove( ... ); + + template <typename N1, typename N2> + static auto checkMake( N1* n1, N2* n2 ) -> decltype(tbb::flow::make_edge(*n1, *n2)); + + template <typename N1, typename N2> + static auto checkRemove( N1* n1, N2* n2 ) -> decltype(tbb::flow::remove_edge(*n1, *n2)); + + static const bool valueMake = !is_same_type<decltype(checkMake (static_cast<T1*>(0), static_cast<T2*>(0))), ImpossibleType>::value; + static const bool valueRemove = !is_same_type<decltype(checkRemove(static_cast<T1*>(0), static_cast<T2*>(0))), ImpossibleType>::value; + + __TBB_STATIC_ASSERT( valueMake == valueRemove, "make_edge() availability is NOT equal to remove_edge() availability" ); + + static const bool value = valueMake; +}; + +template <typename T1, typename T2> +struct TypeChecker { + TypeChecker() { + ++g_CheckerCounter; + + REMARK("%d: %s -> %s: %s %s \n", g_CheckerCounter, typeid(T1).name(), typeid(T2).name(), + (bAllowed ? "YES" : "no"), (bConvertible ? " (Convertible)" : "")); + } + +// +// Check connection: function_node<continue_msg, SENDING_TYPE> <-> function_node<RECEIVING_TYPE> +// R E C E I V I N G T Y P E +// S 'bAllowed' | int | float | A | async_msg | async_msg | async_msg | UserAsync | UserAsync | UserAsync | +// E value | | | | <int> | <float> | <A> | _int | _float | _A | +// N ------------------------------------------------------------------------------------------------------------- +// D int | Y | | | Y | | | Y | | | +// I float | | Y | | | Y | | | Y | | +// N A | | | Y | | | Y | | | Y | +// G async_msg<int> | Y | | | Y | | | | | | +// async_msg<float> | | Y | | | Y | | | | | +// T async_msg<A> | | | Y | | | Y | | | | +// Y UserAsync_int | Y | | | | | | Y | | | +// P UserAsync_float | | Y | | | | | | Y | | +// E UserAsync_A | | | Y | | | | | | Y | +// + // Test make_edge() & remove_edge() availability + static const bool bAllowed = is_same_type<T1, T2>::value + || is_same_type<typename async_helpers<T1>::filtered_type, T2>::value + || is_same_type<T1, typename async_helpers<T2>::filtered_type>::value; + + static const bool bConvertible = bAllowed + || std::is_base_of<T1, T2>::value + || (is_same_type<typename async_helpers<T1>::filtered_type, int>::value && is_same_type<T2, float>::value) + || (is_same_type<typename async_helpers<T1>::filtered_type, float>::value && is_same_type<T2, int>::value); + + __TBB_STATIC_ASSERT( (bAllowed == CheckerMakeEdge<function_node<continue_msg, T1>, function_node<T2> >::value), "invalid connection Fn<T1> -> Fn<T2>" ); + __TBB_STATIC_ASSERT( (bAllowed == CheckerMakeEdge<queue_node<T1>, function_node<T2> >::value), "invalid connection Queue<T1> -> Fn<T2>" ); + + // Test make_edge() & remove_edge() availability with output_port<N>(node&) + __TBB_STATIC_ASSERT( (bAllowed == CheckerMakeEdge<typename strip< decltype( + output_port<0>( *static_cast<multifunction_node< continue_msg, tuple<T1, int> >*>(0) ) ) >::type, + function_node<T2> >::value), "invalid connection MultuFn<0><T1,int> -> Fn<T2>" ); + + __TBB_STATIC_ASSERT( (bAllowed == CheckerMakeEdge<typename strip< decltype( + output_port<1>( *static_cast<multifunction_node< continue_msg, tuple<int, T1> >*>(0) ) ) >::type, + function_node<T2> >::value), "invalid connection MultuFn<1><int, T1> -> Fn<T2>" ); + + // Test untyped_sender connections + __TBB_STATIC_ASSERT( (true == CheckerMakeEdge< untyped_sender, function_node<T1> >::value), "cannot connect UntypedSender -> Fn<T1>" ); + // Test untyped_receiver connections + __TBB_STATIC_ASSERT( (true == CheckerMakeEdge< function_node<continue_msg, T1>, untyped_receiver >::value), "cannot connect F<.., T1> -> UntypedReceiver" ); + + // Test untyped_receiver->try_put(T2) availability + __TBB_STATIC_ASSERT( (true == CheckerTryPut<untyped_receiver, T2>::value), "untyped_receiver cannot try_put(T2)" ); + // Test receiver<T1>->try_put(T2) availability + __TBB_STATIC_ASSERT( (bConvertible == CheckerTryPut<receiver<T1>, T2>::value), "invalid availability of receiver<T1>->try_put(T2)" ); +}; + +template <typename T1> +struct WrappedChecker { + WrappedChecker() {} // Workaround for compilation error + + template <typename T2> + struct T1T2Checker : TypeChecker<T1, T2> {}; + + typename wrap_tuple_elements< tuple_size<TypeTuple>::value, T1T2Checker, TypeTuple >::type a; +}; + +typedef wrap_tuple_elements< tuple_size<TypeTuple>::value, WrappedChecker, TypeTuple >::type Checker; + +} // namespace testFunctionsAvailabilityNS + +static void testTryPut() { + { + tbb::flow::graph g; + tbb::flow::function_node< int > f(g, tbb::flow::unlimited, [&](int) {}); + + ASSERT(f.try_put(5), "try_put(int) must return true"); + ASSERT(f.try_put(7), "try_put(int) must return true"); + + tbb::flow::async_msg<int> a1, a2; + a1.set(5); + ASSERT(f.try_put(a1), "try_put(async_msg) must return true"); + ASSERT(f.try_put(a2), "try_put(async_msg) must return true"); + a2.set(7); + g.wait_for_all(); + } + { + tbb::flow::graph g; + typedef tbb::flow::indexer_node< int >::output_type output_type; + tbb::flow::indexer_node< int > i(g); + tbb::flow::function_node< output_type > f(g, tbb::flow::unlimited, [&](output_type) {}); + make_edge(i, f); + + ASSERT(tbb::flow::input_port<0>(i).try_put(5), "try_put(int) must return true"); + ASSERT(tbb::flow::input_port<0>(i).try_put(7), "try_put(int) must return true"); + + tbb::flow::async_msg<int> a1(5), a2(7); + ASSERT(tbb::flow::input_port<0>(i).try_put(a1), "try_put(async_msg) must return true"); + ASSERT(tbb::flow::input_port<0>(i).try_put(a2), "try_put(async_msg) must return true"); + g.wait_for_all(); + } +} + +int TestMain() { + REMARK(" *** CHECKING FUNCTIONS: make_edge/remove_edge(node<.., T1>, node<T2>) & node<T1>->try_put(T2) ***\n"); + testFunctionsAvailabilityNS::Checker a; + const int typeTupleSize = tbb::flow::tuple_size<testFunctionsAvailabilityNS::TypeTuple>::value; + ASSERT(testFunctionsAvailabilityNS::g_CheckerCounter == typeTupleSize*typeTupleSize, "Type checker counter value is incorrect"); + + testTryPut(); + + // NOTE: Use '-v' command line argument to get traces & remarks + tbb::task_scheduler_init init(4); + bool bOk = true; + + for (int i = 0; i < USE_N; ++i) { + if (i > 0 && i%1000 == 0) { + REPORT(" *** Starting TEST %d... ***\n", i); + } + + REMARK(" *** TEST %d ***\n", i); + bOk = bOk && testSimplestCase(); + bOk = bOk && testChaining(); + } + + _TRACE_( " *** " << USE_N << " tests: " << (bOk ? "all tests passed" : "TESTS FAILED !!!") << " ***" ); + return (bOk ? Harness::Done : Harness::Unknown); +} + +#else // __TBB_PREVIEW_ASYNC_MSG + +#include "harness.h" + +int TestMain() { + return Harness::Skipped; +} + +#endif // __TBB_PREVIEW_ASYNC_MSG diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_async_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_async_node.cpp new file mode 100644 index 00000000..78e0fcb8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_async_node.cpp @@ -0,0 +1,857 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_DEPRECATED_FLOW_NODE_ALLOCATOR __TBB_CPF_BUILD + +#include "harness.h" +#include "harness_graph.h" +#include "harness_barrier.h" +#include "tbb/concurrent_queue.h" +#include "tbb/flow_graph.h" +#include "tbb/task.h" +#include "tbb/tbb_thread.h" +#include "tbb/mutex.h" +#include "tbb/compat/condition_variable" + +#include <string> + +class minimal_type { + template<typename T> + friend struct place_wrapper; + + int value; + +public: + minimal_type() : value(-1) {} + minimal_type(int v) : value(v) {} + minimal_type(const minimal_type &m) : value(m.value) { } + minimal_type &operator=(const minimal_type &m) { value = m.value; return *this; } +}; + +template <typename T> +struct place_wrapper { + typedef T wrapped_type; + T value; + tbb::tbb_thread::id thread_id; + tbb::task* task_ptr; + + place_wrapper( ) : value(0) { + thread_id = tbb::this_tbb_thread::get_id(); + task_ptr = &tbb::task::self(); + } + place_wrapper( int v ) : value(v) { + thread_id = tbb::this_tbb_thread::get_id(); + task_ptr = &tbb::task::self(); + } + + place_wrapper( const place_wrapper<int> &v ) : value(v.value), thread_id(v.thread_id), task_ptr(v.task_ptr) { } + + place_wrapper( const place_wrapper<minimal_type> &v ) : value(v.value), thread_id(v.thread_id), task_ptr(v.task_ptr) { } + + place_wrapper<minimal_type>& operator=(const place_wrapper<minimal_type> &v) { + if( this != &v ) { + value = v.value; + thread_id = v.thread_id; + task_ptr = v.task_ptr; + } + return *this; + } +}; + +template<typename T1, typename T2> +struct wrapper_helper { + static void check(const T1 &, const T2 &) { } + + static void copy_value(const T1 &in, T2 &out) { + out = in; + } +}; + +template<typename T1, typename T2> +struct wrapper_helper< place_wrapper<T1>, place_wrapper<T2> > { + static void check(const place_wrapper<T1> &a, const place_wrapper<T2> &b) { + REMARK("a.task_ptr == %p != b.task_ptr == %p\n", a.task_ptr, b.task_ptr); + ASSERT( (a.thread_id != b.thread_id), "same thread used to execute adjacent nodes"); + ASSERT( (a.task_ptr != b.task_ptr), "same task used to execute adjacent nodes"); + return; + } + static void copy_value(const place_wrapper<T1> &in, place_wrapper<T2> &out) { + out.value = in.value; + } +}; + +const int NUMBER_OF_MSGS = 10; +const int UNKNOWN_NUMBER_OF_ITEMS = -1; +tbb::atomic<int> async_body_exec_count; +tbb::atomic<int> async_activity_processed_msg_count; +tbb::atomic<int> end_body_exec_count; + +// queueing required in test_reset for testing of cancellation +typedef tbb::flow::async_node< int, int, tbb::flow::queueing > counting_async_node_type; +typedef counting_async_node_type::gateway_type counting_gateway_type; + +struct counting_async_body { + tbb::atomic<int> my_async_body_exec_count; + + counting_async_body() { + my_async_body_exec_count = 0; + } + + void operator()( const int &input, counting_gateway_type& gateway) { + REMARK( "Body execution with input == %d\n", input); + ++my_async_body_exec_count; + ++async_body_exec_count; + if ( input == -1 ) { + bool result = tbb::task::self().group()->cancel_group_execution(); + REMARK( "Canceling graph execution\n" ); + ASSERT( result == true, "attempted to cancel graph twice" ); + Harness::Sleep(50); + } + gateway.try_put(input); + } +}; + +void test_reset() { + const int N = NUMBER_OF_MSGS; + async_body_exec_count = 0; + + tbb::flow::graph g; + counting_async_node_type a(g, tbb::flow::serial, counting_async_body() ); + + const int R = 3; + std::vector< harness_counting_receiver<int> > r(R, harness_counting_receiver<int>(g)); + + for (int i = 0; i < R; ++i) { +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + tbb::flow::make_edge(a, r[i]); +#else + tbb::flow::make_edge( tbb::flow::output_port<0>(a), r[i] ); +#endif + } + + REMARK( "One body execution\n" ); + a.try_put(-1); + for (int i = 0; i < N; ++i) { + a.try_put(i); + } + g.wait_for_all(); + // should be canceled with only 1 item reaching the async_body and the counting receivers + // and N items left in the node's queue + ASSERT( g.is_cancelled() == true, "task group not canceled" ); + + counting_async_body b1 = tbb::flow::copy_body<counting_async_body>(a); + ASSERT( int(async_body_exec_count) == int(b1.my_async_body_exec_count), "body and global body counts are different" ); + ASSERT( int(async_body_exec_count) == 1, "global body execution count not 1" ); + for (int i = 0; i < R; ++i) { + ASSERT( int(r[i].my_count) == 1, "counting receiver count not 1" ); + } + + // should clear the async_node queue, but retain its local count at 1 and keep all edges + g.reset(tbb::flow::rf_reset_protocol); + + REMARK( "N body executions\n" ); + for (int i = 0; i < N; ++i) { + a.try_put(i); + } + g.wait_for_all(); + ASSERT( g.is_cancelled() == false, "task group not canceled" ); + + // a total of N+1 items should have passed through the node body + // the local body count should also be N+1 + // and the counting receivers should all have a count of N+1 + counting_async_body b2 = tbb::flow::copy_body<counting_async_body>(a); + ASSERT( int(async_body_exec_count) == int(b2.my_async_body_exec_count), "local and global body execution counts are different" ); + REMARK( "async_body_exec_count==%d\n", int(async_body_exec_count) ); + ASSERT( int(async_body_exec_count) == N+1, "globcal body execution count not N+1" ); + for (int i = 0; i < R; ++i) { + ASSERT( int(r[i].my_count) == N+1, "counting receiver has not received N+1 items" ); + } + + REMARK( "N body executions with new bodies\n" ); + // should clear the async_node queue and reset its local count to 0, but keep all edges + g.reset(tbb::flow::rf_reset_bodies); + for (int i = 0; i < N; ++i) { + a.try_put(i); + } + g.wait_for_all(); + ASSERT( g.is_cancelled() == false, "task group not canceled" ); + + // a total of 2N+1 items should have passed through the node body + // the local body count should be N + // and the counting receivers should all have a count of 2N+1 + counting_async_body b3 = tbb::flow::copy_body<counting_async_body>(a); + ASSERT( int(async_body_exec_count) == 2*N+1, "global body execution count not 2N+1" ); + ASSERT( int(b3.my_async_body_exec_count) == N, "local body execution count not N" ); + for (int i = 0; i < R; ++i) { + ASSERT( int(r[i].my_count) == 2*N+1, "counting receiver has not received 2N+1 items" ); + } + + // should clear the async_node queue and keep its local count at N and remove all edges + REMARK( "N body executions with no edges\n" ); + g.reset(tbb::flow::rf_clear_edges); + for (int i = 0; i < N; ++i) { + a.try_put(i); + } + g.wait_for_all(); + ASSERT( g.is_cancelled() == false, "task group not canceled" ); + + // a total of 3N+1 items should have passed through the node body + // the local body count should now be 2*N + // and the counting receivers should remain at a count of 2N+1 + counting_async_body b4 = tbb::flow::copy_body<counting_async_body>(a); + ASSERT( int(async_body_exec_count) == 3*N+1, "global body execution count not 3N+1" ); + ASSERT( int(b4.my_async_body_exec_count) == 2*N, "local body execution count not 2N" ); + for (int i = 0; i < R; ++i) { + ASSERT( int(r[i].my_count) == 2*N+1, "counting receiver has not received 2N+1 items" ); + } + + // put back 1 edge to receiver 0 + REMARK( "N body executions with 1 edge\n" ); +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + tbb::flow::make_edge(a, r[0]); +#else + tbb::flow::make_edge( tbb::flow::output_port<0>(a), r[0] ); +#endif + for (int i = 0; i < N; ++i) { + a.try_put(i); + } + g.wait_for_all(); + ASSERT( g.is_cancelled() == false, "task group not canceled" ); + + // a total of 4N+1 items should have passed through the node body + // the local body count should now be 3*N + // and all of the counting receivers should remain at a count of 2N+1, except r[0] which should be 3N+1 + counting_async_body b5 = tbb::flow::copy_body<counting_async_body>(a); + ASSERT( int(async_body_exec_count) == 4*N+1, "global body execution count not 4N+1" ); + ASSERT( int(b5.my_async_body_exec_count) == 3*N, "local body execution count not 3N" ); + ASSERT( int(r[0].my_count) == 3*N+1, "counting receiver has not received 3N+1 items" ); + for (int i = 1; i < R; ++i) { + ASSERT( int(r[i].my_count) == 2*N+1, "counting receiver has not received 2N+1 items" ); + } + + // should clear the async_node queue and keep its local count at N and remove all edges + REMARK( "N body executions with no edges and new body\n" ); + g.reset(static_cast<tbb::flow::reset_flags>(tbb::flow::rf_reset_bodies|tbb::flow::rf_clear_edges)); + for (int i = 0; i < N; ++i) { + a.try_put(i); + } + g.wait_for_all(); + ASSERT( g.is_cancelled() == false, "task group not canceled" ); + + // a total of 4N+1 items should have passed through the node body + // the local body count should now be 3*N + // and all of the counting receivers should remain at a count of 2N+1, except r[0] which should be 3N+1 + counting_async_body b6 = tbb::flow::copy_body<counting_async_body>(a); + ASSERT( int(async_body_exec_count) == 5*N+1, "global body execution count not 5N+1" ); + ASSERT( int(b6.my_async_body_exec_count) == N, "local body execution count not N" ); + ASSERT( int(r[0].my_count) == 3*N+1, "counting receiver has not received 3N+1 items" ); + for (int i = 1; i < R; ++i) { + ASSERT( int(r[i].my_count) == 2*N+1, "counting receiver has not received 2N+1 items" ); + } +} + +template< typename Input, typename Output > +class async_activity : NoAssign { +public: + typedef Input input_type; + typedef Output output_type; + typedef tbb::flow::async_node< input_type, output_type > async_node_type; + typedef typename async_node_type::gateway_type gateway_type; + + struct work_type { + input_type input; + gateway_type* gateway; + }; + + class ServiceThreadBody { + public: + ServiceThreadBody( async_activity* activity ) : my_activity( activity ) {} + + void operator()() { + my_activity->process(); + } + private: + async_activity* my_activity; + }; + + async_activity(int expected_items, bool deferred = false, int sleep_time = 50) + : my_expected_items(expected_items), my_sleep_time(sleep_time) { + is_active = !deferred; + my_quit = false; + tbb::tbb_thread( ServiceThreadBody( this ) ).swap( my_service_thread ); + } + +private: + + async_activity( const async_activity& ) + : my_expected_items(UNKNOWN_NUMBER_OF_ITEMS), my_sleep_time(0) { + is_active = true; + } + +public: + ~async_activity() { + stop(); + my_service_thread.join(); + } + + void submit( const input_type &input, gateway_type& gateway ) { + work_type work = { input, &gateway}; + my_work_queue.push( work ); + } + + void process() { + do { + work_type work; + if( is_active && my_work_queue.try_pop( work ) ) { + Harness::Sleep(my_sleep_time); + ++async_activity_processed_msg_count; + output_type output; + wrapper_helper<output_type, output_type>::copy_value(work.input, output); + wrapper_helper<output_type, output_type>::check(work.input, output); + work.gateway->try_put(output); + if ( my_expected_items == UNKNOWN_NUMBER_OF_ITEMS || + int(async_activity_processed_msg_count) == my_expected_items ) { + work.gateway->release_wait(); + } + } + } while( my_quit == false || !my_work_queue.empty()); + } + + void stop() { + my_quit = true; + } + + void activate() { + is_active = true; + } + + bool should_reserve_each_time() { + if ( my_expected_items == UNKNOWN_NUMBER_OF_ITEMS ) + return true; + else + return false; + } + +private: + + const int my_expected_items; + const int my_sleep_time; + tbb::atomic< bool > is_active; + + tbb::concurrent_queue< work_type > my_work_queue; + + tbb::atomic< bool > my_quit; + + tbb::tbb_thread my_service_thread; +}; + +template<typename Input, typename Output> +struct basic_test { + typedef Input input_type; + typedef Output output_type; + typedef tbb::flow::async_node< input_type, output_type > async_node_type; + typedef typename async_node_type::gateway_type gateway_type; + + class start_body_type { + typedef Input input_type; + public: + input_type operator()( int input ) { + return input_type(input); + } + }; + +#if !__TBB_CPP11_LAMBDAS_PRESENT + class async_body_type { + typedef Input input_type; + typedef Output output_type; + typedef tbb::flow::async_node< input_type, output_type > async_node_type; + typedef typename async_node_type::gateway_type gateway_type; + public: + typedef async_activity<input_type, output_type> async_activity_type; + + async_body_type( async_activity_type* aa ) : my_async_activity( aa ) { } + + async_body_type( const async_body_type& other ) : my_async_activity( other.my_async_activity ) { } + + void operator()( const input_type &input, gateway_type& gateway ) { + ++async_body_exec_count; + my_async_activity->submit( input, gateway); + if ( my_async_activity->should_reserve_each_time() ) + gateway.reserve_wait(); + } + + private: + async_activity_type* my_async_activity; + }; +#endif + + class end_body_type { + typedef Output output_type; + public: + void operator()( const output_type &input ) { + ++end_body_exec_count; + output_type output; + wrapper_helper<output_type, output_type>::check(input, output); + } + }; + + basic_test() {} + +public: + + static int run(int async_expected_items = UNKNOWN_NUMBER_OF_ITEMS) { + async_activity<input_type, output_type> my_async_activity(async_expected_items); + tbb::flow::graph g; + tbb::flow::function_node< int, input_type > start_node( g, tbb::flow::unlimited, start_body_type() ); +#if __TBB_CPP11_LAMBDAS_PRESENT + async_node_type offload_node(g, tbb::flow::unlimited, [&] (const input_type &input, gateway_type& gateway) { + ++async_body_exec_count; + my_async_activity.submit(input, gateway); + if(my_async_activity.should_reserve_each_time()) + gateway.reserve_wait(); + } ); +#else + async_node_type offload_node( g, tbb::flow::unlimited, async_body_type( &my_async_activity ) ); +#endif + + tbb::flow::function_node< output_type > end_node( g, tbb::flow::unlimited, end_body_type() ); + + tbb::flow::make_edge( start_node, offload_node ); +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + tbb::flow::make_edge( offload_node, end_node ); +#else + tbb::flow::make_edge( tbb::flow::output_port<0>(offload_node), end_node ); +#endif + async_body_exec_count = 0; + async_activity_processed_msg_count = 0; + end_body_exec_count = 0; + + if (async_expected_items != UNKNOWN_NUMBER_OF_ITEMS ) { + offload_node.gateway().reserve_wait(); + } + for (int i = 0; i < NUMBER_OF_MSGS; ++i) { + start_node.try_put(i); + } + g.wait_for_all(); + ASSERT( async_body_exec_count == NUMBER_OF_MSGS, "AsyncBody processed wrong number of signals" ); + ASSERT( async_activity_processed_msg_count == NUMBER_OF_MSGS, "AsyncActivity processed wrong number of signals" ); + ASSERT( end_body_exec_count == NUMBER_OF_MSGS, "EndBody processed wrong number of signals"); + REMARK("async_body_exec_count == %d == async_activity_processed_msg_count == %d == end_body_exec_count == %d\n", + int(async_body_exec_count), int(async_activity_processed_msg_count), int(end_body_exec_count)); + return Harness::Done; + } + +}; + +int test_copy_ctor() { + const int N = NUMBER_OF_MSGS; + async_body_exec_count = 0; + + tbb::flow::graph g; + + harness_counting_receiver<int> r1(g); + harness_counting_receiver<int> r2(g); + + counting_async_node_type a(g, tbb::flow::unlimited, counting_async_body() ); + counting_async_node_type b(a); +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + tbb::flow::make_edge(a, r1); + tbb::flow::make_edge(b, r2); +#else + tbb::flow::make_edge(tbb::flow::output_port<0>(a), r1); + tbb::flow::make_edge(tbb::flow::output_port<0>(b), r2); +#endif + + for (int i = 0; i < N; ++i) { + a.try_put(i); + } + g.wait_for_all(); + + REMARK("async_body_exec_count = %d\n", int(async_body_exec_count)); + REMARK("r1.my_count == %d and r2.my_count = %d\n", int(r1.my_count), int(r2.my_count)); + ASSERT( int(async_body_exec_count) == NUMBER_OF_MSGS, "AsyncBody processed wrong number of signals" ); + ASSERT( int(r1.my_count) == N, "counting receiver r1 has not received N items" ); + ASSERT( int(r2.my_count) == 0, "counting receiver r2 has not received 0 items" ); + + for (int i = 0; i < N; ++i) { + b.try_put(i); + } + g.wait_for_all(); + + REMARK("async_body_exec_count = %d\n", int(async_body_exec_count)); + REMARK("r1.my_count == %d and r2.my_count = %d\n", int(r1.my_count), int(r2.my_count)); + ASSERT( int(async_body_exec_count) == 2*NUMBER_OF_MSGS, "AsyncBody processed wrong number of signals" ); + ASSERT( int(r1.my_count) == N, "counting receiver r1 has not received N items" ); + ASSERT( int(r2.my_count) == N, "counting receiver r2 has not received N items" ); + return Harness::Done; +} + +tbb::atomic<int> main_tid_count; + +template<typename Input, typename Output> +struct spin_test { + typedef Input input_type; + typedef Output output_type; + typedef tbb::flow::async_node< input_type, output_type > async_node_type; + typedef typename async_node_type::gateway_type gateway_type; + + class start_body_type { + typedef Input input_type; + public: + input_type operator()( int input ) { + return input_type(input); + } + }; + +#if !__TBB_CPP11_LAMBDAS_PRESENT + class async_body_type { + typedef Input input_type; + typedef Output output_type; + typedef tbb::flow::async_node< input_type, output_type > async_node_type; + typedef typename async_node_type::gateway_type gateway_type; + public: + typedef async_activity<input_type, output_type> async_activity_type; + + async_body_type( async_activity_type* aa ) : my_async_activity( aa ) { } + + async_body_type( const async_body_type& other ) : my_async_activity( other.my_async_activity ) { } + + void operator()(const input_type &input, gateway_type& gateway) { + ++async_body_exec_count; + my_async_activity->submit(input, gateway); + if(my_async_activity->should_reserve_each_time()) + gateway.reserve_wait(); + } + + private: + async_activity_type* my_async_activity; + }; +#endif + + class end_body_type { + typedef Output output_type; + tbb::tbb_thread::id my_main_tid; + Harness::SpinBarrier *my_barrier; + public: + end_body_type(tbb::tbb_thread::id t, Harness::SpinBarrier &b) : my_main_tid(t), my_barrier(&b) { } + + void operator()( const output_type & ) { + ++end_body_exec_count; + if (tbb::this_tbb_thread::get_id() == my_main_tid) { + ++main_tid_count; + } + my_barrier->timed_wait_noerror(10); + } + }; + + spin_test() {} + + static int run(int nthreads, int async_expected_items = UNKNOWN_NUMBER_OF_ITEMS) { + async_activity<input_type, output_type> my_async_activity(async_expected_items, false, 0); + Harness::SpinBarrier spin_barrier(nthreads); + tbb::flow::graph g; + tbb::flow::function_node< int, input_type > start_node( g, tbb::flow::unlimited, start_body_type() ); +#if __TBB_CPP11_LAMBDAS_PRESENT + async_node_type offload_node(g, tbb::flow::unlimited, [&](const input_type &input, gateway_type& gateway) { + ++async_body_exec_count; + my_async_activity.submit(input, gateway); + if(my_async_activity.should_reserve_each_time()) + gateway.reserve_wait(); + }); +#else + async_node_type offload_node( g, tbb::flow::unlimited, async_body_type( &my_async_activity ) ); +#endif + tbb::flow::function_node< output_type > end_node( g, tbb::flow::unlimited, end_body_type(tbb::this_tbb_thread::get_id(), spin_barrier) ); + tbb::flow::make_edge( start_node, offload_node ); +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + tbb::flow::make_edge( offload_node, end_node ); +#else + tbb::flow::make_edge( tbb::flow::output_port<0>(offload_node), end_node ); +#endif + async_body_exec_count = 0; + async_activity_processed_msg_count = 0; + end_body_exec_count = 0; + main_tid_count = 0; + + if (async_expected_items != UNKNOWN_NUMBER_OF_ITEMS ) { + offload_node.gateway().reserve_wait(); + } + for (int i = 0; i < nthreads*NUMBER_OF_MSGS; ++i) { + start_node.try_put(i); + } + g.wait_for_all(); + ASSERT( async_body_exec_count == nthreads*NUMBER_OF_MSGS, "AsyncBody processed wrong number of signals" ); + ASSERT( async_activity_processed_msg_count == nthreads*NUMBER_OF_MSGS, "AsyncActivity processed wrong number of signals" ); + ASSERT( end_body_exec_count == nthreads*NUMBER_OF_MSGS, "EndBody processed wrong number of signals"); + ASSERT_WARNING( main_tid_count != 0, "Main thread did not participate in end_body tasks"); + REMARK("async_body_exec_count == %d == async_activity_processed_msg_count == %d == end_body_exec_count == %d\n", + int(async_body_exec_count), int(async_activity_processed_msg_count), int(end_body_exec_count)); + return Harness::Done; + } + +}; + +void test_for_spin_avoidance() { + spin_test<int, int>::run(4); +} + +template< typename Input, typename Output > +int run_tests() { + basic_test<Input, Output>::run(); + basic_test<Input, Output>::run(NUMBER_OF_MSGS); + basic_test<place_wrapper<Input>, place_wrapper<Output> >::run(); + basic_test<place_wrapper<Input>, place_wrapper<Output> >::run(NUMBER_OF_MSGS); + return Harness::Done; +} + +#include "tbb/parallel_for.h" +template<typename Input, typename Output> +class equeueing_on_inner_level { + typedef Input input_type; + typedef Output output_type; + typedef async_activity<input_type, output_type> async_activity_type; + typedef tbb::flow::async_node<Input, Output> async_node_type; + typedef typename async_node_type::gateway_type gateway_type; + + class start_body_type { + public: + input_type operator() ( int input ) { + return input_type( input); + } + }; + + class async_body_type { + public: + async_body_type( async_activity_type& activity ) : my_async_activity(&activity) {} + + void operator() ( const input_type &input, gateway_type& gateway ) { + gateway.reserve_wait(); + my_async_activity->submit( input, gateway ); + } + private: + async_activity_type* my_async_activity; + }; + + class end_body_type { + public: + void operator()( output_type ) {} + }; + + class body_graph_with_async { + public: + body_graph_with_async( Harness::SpinBarrier& barrier, async_activity_type& activity ) + : spin_barrier(&barrier), my_async_activity(&activity) {} + + void operator()(int) const { + tbb::flow::graph g; + tbb::flow::function_node< int, input_type > start_node( g, tbb::flow::unlimited, start_body_type() ); + + async_node_type offload_node( g, tbb::flow::unlimited, async_body_type( *my_async_activity ) ); + + tbb::flow::function_node< output_type > end_node( g, tbb::flow::unlimited, end_body_type() ); + + tbb::flow::make_edge( start_node, offload_node ); + tbb::flow::make_edge( offload_node, end_node ); + + start_node.try_put(1); + + spin_barrier->wait(); + + my_async_activity->activate(); + + g.wait_for_all(); + } + + private: + Harness::SpinBarrier* spin_barrier; + async_activity_type* my_async_activity; + }; + + +public: + static int run () + { + const int nthreads = tbb::this_task_arena::max_concurrency(); + Harness::SpinBarrier spin_barrier( nthreads ); + + async_activity_type my_async_activity( UNKNOWN_NUMBER_OF_ITEMS, true ); + + tbb::parallel_for( 0, nthreads, body_graph_with_async( spin_barrier, my_async_activity ) ); + return Harness::Done; + } +}; + +int run_test_equeueing_on_inner_level() { + equeueing_on_inner_level<int, int>::run(); + return Harness::Done; +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <thread> + +template<typename NodeType> +class AsyncActivity { +public: + using gateway_t = typename NodeType::gateway_type; + + struct work_type { + int input; + gateway_t* gateway; + }; + + AsyncActivity(size_t limit) : thr([this]() { + while(!end_of_work()) { + work_type w; + while( my_q.try_pop(w) ) { + int res = do_work(w.input); + w.gateway->try_put(res); + w.gateway->release_wait(); + ++c; + } + } + }), stop_limit(limit), c(0) {} + + void submit(int i, gateway_t* gateway) { + work_type w = {i, gateway}; + gateway->reserve_wait(); + my_q.push(w); + } + + void wait_for_all() { thr.join(); } + +private: + bool end_of_work() { return c >= stop_limit; } + + int do_work(int& i) { return i + i; } + + tbb::concurrent_queue<work_type> my_q; + tbb::tbb_thread thr; + size_t stop_limit; + size_t c; +}; + +void test_follows() { + using namespace tbb::flow; + + using input_t = int; + using output_t = int; + using node_t = async_node<input_t, output_t>; + + graph g; + + AsyncActivity<node_t> async_activity(3); + + std::array<broadcast_node<input_t>, 3> preds = { + { + broadcast_node<input_t>(g), + broadcast_node<input_t>(g), + broadcast_node<input_t>(g) + } + }; + + node_t node(follows(preds[0], preds[1], preds[2]), unlimited, [&](int input, node_t::gateway_type& gtw) { + async_activity.submit(input, >w); + }); + + buffer_node<output_t> buf(g); + make_edge(node, buf); + + for(auto& pred: preds) { + pred.try_put(1); + } + + g.wait_for_all(); + async_activity.wait_for_all(); + + output_t storage; + ASSERT((buf.try_get(storage) && buf.try_get(storage) && buf.try_get(storage) && !buf.try_get(storage)), + "Not exact edge quantity was made"); +} + +void test_precedes() { + using namespace tbb::flow; + + using input_t = int; + using output_t = int; + using node_t = async_node<input_t, output_t>; + + graph g; + + AsyncActivity<node_t> async_activity(1); + + std::array<buffer_node<input_t>, 1> successors = { {buffer_node<input_t>(g)} }; + + broadcast_node<input_t> start(g); + + node_t node(precedes(successors[0]), unlimited, [&](int input, node_t::gateway_type& gtw) { + async_activity.submit(input, >w); + }); + + make_edge(start, node); + + start.try_put(1); + + g.wait_for_all(); + async_activity.wait_for_all(); + + for(auto& successor : successors) { + output_t storage; + ASSERT(successor.try_get(storage) && !successor.try_get(storage), + "Not exact edge quantity was made"); + } +} + +void test_follows_and_precedes_api() { + test_follows(); + test_precedes(); +} +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +typedef tbb::flow::async_node< int, int, tbb::flow::queueing, std::allocator<int> > async_node_type; + +struct async_body { + void operator()( const int&, async_node_type::gateway_type& ) {} +}; + +void test_node_allocator() { + tbb::flow::graph g; + async_node_type tmp(g, tbb::flow::unlimited, async_body()); +} +#endif + +int TestMain() { + tbb::task_scheduler_init init(4); + run_tests<int, int>(); + run_tests<minimal_type, minimal_type>(); + run_tests<int, minimal_type>(); + + lightweight_testing::test<tbb::flow::async_node>(NUMBER_OF_MSGS); + + test_reset(); + test_copy_ctor(); + test_for_spin_avoidance(); + run_test_equeueing_on_inner_level(); +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + test_node_allocator(); +#endif + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_atomic.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_atomic.cpp new file mode 100644 index 00000000..e809415e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_atomic.cpp @@ -0,0 +1,1601 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_defs.h" + +#if __TBB_TEST_SKIP_PIC_MODE || (__TBB_TEST_SKIP_GCC_BUILTINS_MODE && __TBB_TEST_SKIP_ICC_BUILTINS_MODE) +#include "harness.h" +int TestMain() { + REPORT("Known issue: %s\n", + __TBB_TEST_SKIP_PIC_MODE? "PIC mode is not supported" : "Compiler builtins for atomic operations aren't available"); + return Harness::Skipped; +} +#else + +// Put tbb/atomic.h first, so if it is missing a prerequisite header, we find out about it. +// The tests here do *not* test for atomicity, just serial correctness. */ + +#include "tbb/atomic.h" +#include "harness_assert.h" +#include <cstring> // memcmp +#include "tbb/aligned_space.h" +#include <new> //for placement new + +using std::memcmp; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Unary minus operator applied to unsigned type, result still unsigned + // Constant conditional expression + #pragma warning( disable: 4127 4310 ) +#endif + +#if __TBB_GCC_STRICT_ALIASING_BROKEN + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + +enum LoadStoreExpression { + UseOperators, + UseImplicitAcqRel, + UseExplicitFullyFenced, + UseExplicitAcqRel, + UseExplicitRelaxed, + UseGlobalHelperFullyFenced, + UseGlobalHelperAcqRel, + UseGlobalHelperRelaxed +}; + +//! Structure that holds an atomic<T> and some guard bytes around it. +template<typename T, LoadStoreExpression E = UseOperators> +struct TestStruct { + typedef unsigned char byte_type; + T prefix; + tbb::atomic<T> counter; + T suffix; + TestStruct( T i ) { + ASSERT( sizeof(*this)==3*sizeof(T), NULL ); + for (size_t j = 0; j < sizeof(T); ++j) { + reinterpret_cast<byte_type*>(&prefix)[j] = byte_type(0x11*(j+1)); + reinterpret_cast<byte_type*>(&suffix)[sizeof(T)-j-1] = byte_type(0x11*(j+1)); + } + if ( E == UseOperators ) + counter = i; + else if ( E == UseExplicitRelaxed ) + counter.template store<tbb::relaxed>(i); + else + tbb::store<tbb::full_fence>( counter, i ); + } + ~TestStruct() { + // Check for writes outside the counter. + for (size_t j = 0; j < sizeof(T); ++j) { + ASSERT( reinterpret_cast<byte_type*>(&prefix)[j] == byte_type(0x11*(j+1)), NULL ); + ASSERT( reinterpret_cast<byte_type*>(&suffix)[sizeof(T)-j-1] == byte_type(0x11*(j+1)), NULL ); + } + } + static tbb::atomic<T> gCounter; +}; + +// A global variable of type tbb::atomic<> +template<typename T, LoadStoreExpression E> tbb::atomic<T> TestStruct<T, E>::gCounter; + +//! Test compare_and_swap template members of class atomic<T> for memory_semantics=M +template<typename T,tbb::memory_semantics M> +void TestCompareAndSwapWithExplicitOrdering( T i, T j, T k ) { + ASSERT( i!=k && i!=j, "values must be distinct" ); + // Test compare_and_swap that should fail + TestStruct<T> x(i); + T old = x.counter.template compare_and_swap<M>( j, k ); + ASSERT( old==i, NULL ); + ASSERT( x.counter==i, "old value not retained" ); + // Test compare and swap that should succeed + old = x.counter.template compare_and_swap<M>( j, i ); + ASSERT( old==i, NULL ); + ASSERT( x.counter==j, "value not updated?" ); +} + +//! i, j, k must be different values +template<typename T> +void TestCompareAndSwap( T i, T j, T k ) { + ASSERT( i!=k && i!=j, "values must be distinct" ); + // Test compare_and_swap that should fail + TestStruct<T> x(i); + T old = x.counter.compare_and_swap( j, k ); + ASSERT( old==i, NULL ); + ASSERT( x.counter==i, "old value not retained" ); + // Test compare and swap that should succeed + old = x.counter.compare_and_swap( j, i ); + ASSERT( old==i, NULL ); + if( x.counter==i ) { + ASSERT( x.counter==j, "value not updated?" ); + } else { + ASSERT( x.counter==j, "value trashed" ); + } + // Check that atomic global variables work + TestStruct<T>::gCounter = i; + old = TestStruct<T>::gCounter.compare_and_swap( j, i ); + ASSERT( old==i, NULL ); + ASSERT( TestStruct<T>::gCounter==j, "value not updated?" ); + TestCompareAndSwapWithExplicitOrdering<T,tbb::full_fence>(i,j,k); + TestCompareAndSwapWithExplicitOrdering<T,tbb::acquire>(i,j,k); + TestCompareAndSwapWithExplicitOrdering<T,tbb::release>(i,j,k); + TestCompareAndSwapWithExplicitOrdering<T,tbb::relaxed>(i,j,k); +} + +//! memory_semantics variation on TestFetchAndStore +template<typename T, tbb::memory_semantics M> +void TestFetchAndStoreWithExplicitOrdering( T i, T j ) { + ASSERT( i!=j, "values must be distinct" ); + TestStruct<T> x(i); + T old = x.counter.template fetch_and_store<M>( j ); + ASSERT( old==i, NULL ); + ASSERT( x.counter==j, NULL ); +} + +//! i and j must be different values +template<typename T> +void TestFetchAndStore( T i, T j ) { + ASSERT( i!=j, "values must be distinct" ); + TestStruct<T> x(i); + T old = x.counter.fetch_and_store( j ); + ASSERT( old==i, NULL ); + ASSERT( x.counter==j, NULL ); + // Check that atomic global variables work + TestStruct<T>::gCounter = i; + old = TestStruct<T>::gCounter.fetch_and_store( j ); + ASSERT( old==i, NULL ); + ASSERT( TestStruct<T>::gCounter==j, "value not updated?" ); + TestFetchAndStoreWithExplicitOrdering<T,tbb::full_fence>(i,j); + TestFetchAndStoreWithExplicitOrdering<T,tbb::acquire>(i,j); + TestFetchAndStoreWithExplicitOrdering<T,tbb::release>(i,j); + TestFetchAndStoreWithExplicitOrdering<T,tbb::relaxed>(i,j); +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // conversion from <bigger integer> to <smaller integer>, possible loss of data + // the warning seems a complete nonsense when issued for e.g. short+=short + #pragma warning( disable: 4244 ) +#endif + +//! Test fetch_and_add members of class atomic<T> for memory_semantics=M +template<typename T,tbb::memory_semantics M> +void TestFetchAndAddWithExplicitOrdering( T i ) { + TestStruct<T> x(i); + T actual; + T expected = i; + + // Test fetch_and_add member template + for( int j=0; j<10; ++j ) { + actual = x.counter.fetch_and_add(j); + ASSERT( actual==expected, NULL ); + expected += j; + } + for( int j=0; j<10; ++j ) { + actual = x.counter.fetch_and_add(-j); + ASSERT( actual==expected, NULL ); + expected -= j; + } + + // Test fetch_and_increment member template + ASSERT( x.counter==i, NULL ); + actual = x.counter.template fetch_and_increment<M>(); + ASSERT( actual==i, NULL ); + ASSERT( x.counter==T(i+1), NULL ); + + // Test fetch_and_decrement member template + actual = x.counter.template fetch_and_decrement<M>(); + ASSERT( actual==T(i+1), NULL ); + ASSERT( x.counter==i, NULL ); +} + +//! Test fetch_and_add and related operators +template<typename T> +void TestFetchAndAdd( T i ) { + TestStruct<T> x(i); + T value; + value = ++x.counter; + ASSERT( value==T(i+1), NULL ); + value = x.counter++; + ASSERT( value==T(i+1), NULL ); + value = x.counter--; + ASSERT( value==T(i+2), NULL ); + value = --x.counter; + ASSERT( value==i, NULL ); + T actual; + T expected = i; + for( int j=-100; j<=100; ++j ) { + expected += j; + actual = x.counter += j; + ASSERT( actual==expected, NULL ); + } + for( int j=-100; j<=100; ++j ) { + expected -= j; + actual = x.counter -= j; + ASSERT( actual==expected, NULL ); + } + // Test fetch_and_increment + ASSERT( x.counter==i, NULL ); + actual = x.counter.fetch_and_increment(); + ASSERT( actual==i, NULL ); + ASSERT( x.counter==T(i+1), NULL ); + + // Test fetch_and_decrement + actual = x.counter.fetch_and_decrement(); + ASSERT( actual==T(i+1), NULL ); + ASSERT( x.counter==i, NULL ); + x.counter = i; + ASSERT( x.counter==i, NULL ); + + // Check that atomic global variables work + TestStruct<T>::gCounter = i; + value = TestStruct<T>::gCounter.fetch_and_add( 42 ); + expected = i+42; + ASSERT( value==i, NULL ); + ASSERT( TestStruct<T>::gCounter==expected, "value not updated?" ); + TestFetchAndAddWithExplicitOrdering<T,tbb::full_fence>(i); + TestFetchAndAddWithExplicitOrdering<T,tbb::acquire>(i); + TestFetchAndAddWithExplicitOrdering<T,tbb::release>(i); + TestFetchAndAddWithExplicitOrdering<T,tbb::relaxed>(i); +} + +//! A type with unknown size. +class IncompleteType; + +void TestFetchAndAdd( IncompleteType* ) { + // There are no fetch-and-add operations on a IncompleteType*. +} +void TestFetchAndAdd( void* ) { + // There are no fetch-and-add operations on a void*. +} + +void TestFetchAndAdd( bool ) { + // There are no fetch-and-add operations on a bool. +} + +template<typename T> +void TestConst( T i ) { + // Try const + const TestStruct<T> x(i); + ASSERT( memcmp( &i, &x.counter, sizeof(T) )==0, "write to atomic<T> broken?" ); + ASSERT( x.counter==i, "read of atomic<T> broken?" ); + const TestStruct<T, UseExplicitRelaxed> y(i); + ASSERT( memcmp( &i, &y.counter, sizeof(T) )==0, "relaxed write to atomic<T> broken?" ); + ASSERT( tbb::load<tbb::relaxed>(y.counter) == i, "relaxed read of atomic<T> broken?" ); + const TestStruct<T, UseGlobalHelperFullyFenced> z(i); + ASSERT( memcmp( &i, &z.counter, sizeof(T) )==0, "sequentially consistent write to atomic<T> broken?" ); + ASSERT( z.counter.template load<tbb::full_fence>() == i, "sequentially consistent read of atomic<T> broken?" ); +} + +#include "harness.h" + +#include <sstream> + +//TODO: consider moving it to separate file, and unify with one in examples command line interface +template<typename T> +std::string to_string(const T& a){ + std::stringstream str; str <<a; + return str.str(); +} +namespace initialization_tests { + template<typename T> + struct test_initialization_fixture{ + typedef tbb::atomic<T> atomic_t; + tbb::aligned_space<atomic_t> non_zeroed_storage; + enum {fill_value = 0xFF }; + test_initialization_fixture(){ + memset(static_cast<void*>(non_zeroed_storage.begin()),fill_value, + sizeof(non_zeroed_storage)); + ASSERT( char(fill_value)==*(reinterpret_cast<char*>(non_zeroed_storage.begin())) + ,"failed to fill the storage; memset error?"); + } + //TODO: consider move it to destructor, even in a price of UB + void tear_down(){ + non_zeroed_storage.begin()->~atomic_t(); + } + }; + + template<typename T> + struct TestValueInitialization : test_initialization_fixture<T>{ + void operator()(){ + typedef typename test_initialization_fixture<T>::atomic_t atomic_type; + //please note that explicit braces below are needed to get zero initialization. + //in C++11, 8.5 Initializers [dcl.init], see paragraphs 10,7,5 + new (this->non_zeroed_storage.begin()) atomic_type(); + //TODO: add use of KNOWN_ISSUE macro on SunCC 5.11 + #if !__SUNPRO_CC || __SUNPRO_CC > 0x5110 + //TODO: add printing of typename to the assertion + ASSERT(char(0)==*(reinterpret_cast<char*>(this->non_zeroed_storage.begin())) + ,("value initialization for tbb::atomic should do zero initialization; " + "actual value:"+to_string(this->non_zeroed_storage.begin()->load())).c_str()); + #endif + this->tear_down(); + }; + }; + + template<typename T> + struct TestDefaultInitialization : test_initialization_fixture<T>{ + void operator ()(){ + typedef typename test_initialization_fixture<T>::atomic_t atomic_type; + new (this->non_zeroed_storage.begin()) atomic_type; + ASSERT( char(this->fill_value)==*(reinterpret_cast<char*>(this->non_zeroed_storage.begin())) + ,"default initialization for atomic should do no initialization"); + this->tear_down(); + } + }; +# if __TBB_ATOMIC_CTORS + template<typename T> + struct TestDirectInitialization : test_initialization_fixture<T> { + void operator()(T i){ + typedef typename test_initialization_fixture<T>::atomic_t atomic_type; + new (this->non_zeroed_storage.begin()) atomic_type(i); + ASSERT(i == this->non_zeroed_storage.begin()->load() + ,("tbb::atomic initialization failed; " + "value:"+to_string(this->non_zeroed_storage.begin()->load())+ + "; expected:"+to_string(i)).c_str()); + this->tear_down(); + } + }; +# endif +} +template<typename T> +void TestValueInitialization(){ + initialization_tests::TestValueInitialization<T>()(); +} +template<typename T> +void TestDefaultInitialization(){ + initialization_tests::TestDefaultInitialization<T>()(); +} + +#if __TBB_ATOMIC_CTORS +template<typename T> +void TestDirectInitialization(T i){ + initialization_tests::TestDirectInitialization<T>()(i); +} +//TODO: it would be great to have constructor doing dynamic initialization of local atomic objects implicitly (with zero?), +// but do no dynamic initializations by default for static objects +namespace test_constexpr_initialization_helper { + struct white_box_ad_hoc_type { + int _int; + constexpr white_box_ad_hoc_type(int a =0) : _int(a) {}; + constexpr operator int() const { return _int; } + }; +} +//some white boxing +namespace tbb { namespace internal { + template<> + struct atomic_impl<test_constexpr_initialization_helper::white_box_ad_hoc_type>: atomic_impl<int> { + atomic_impl() = default; + constexpr atomic_impl(test_constexpr_initialization_helper::white_box_ad_hoc_type value):atomic_impl<int>(value){} + constexpr operator int() const { return this->my_storage.my_value; } + }; +}} + +//TODO: make this a parameterized macro +void TestConstExprInitializationIsTranslationTime(){ + const char* ct_init_failed_msg = "translation time init failed?"; + typedef tbb::atomic<int> atomic_t; + constexpr atomic_t a(8); + ASSERT(a == 8,ct_init_failed_msg); + +#if !__TBB_CONSTEXPR_MEMBER_FUNCTION_BROKEN + constexpr tbb::atomic<test_constexpr_initialization_helper::white_box_ad_hoc_type> ct_atomic(10); + //for some unknown reason clang does not managed to enum syntax +#if __clang__ + constexpr int ct_atomic_value_ten = (int)ct_atomic; +#else + enum {ct_atomic_value_ten = (int)ct_atomic}; +#endif + __TBB_STATIC_ASSERT(ct_atomic_value_ten == 10, "translation time init failed?"); + ASSERT(ct_atomic_value_ten == 10,ct_init_failed_msg); + int array[ct_atomic_value_ten]; + ASSERT(Harness::array_length(array) == 10,ct_init_failed_msg); +#endif //__TBB_CONSTEXPR_MEMBER_FUNCTION_BROKEN +} + +#include <string> +#include <vector> +namespace TestConstExprInitializationOfGlobalObjectsHelper{ + struct static_objects_dynamic_init_order_tester { + static int order_hash; + template<int N> struct nth { + nth(){ order_hash = (order_hash<<4)+N; } + }; + + static nth<2> second; + static nth<3> third; + }; + + int static_objects_dynamic_init_order_tester::order_hash=1; + static_objects_dynamic_init_order_tester::nth<2> static_objects_dynamic_init_order_tester::second; + static_objects_dynamic_init_order_tester::nth<3> static_objects_dynamic_init_order_tester::third; + + void TestStaticsDynamicInitializationOrder(){ + ASSERT(static_objects_dynamic_init_order_tester::order_hash==0x123,"Statics dynamic initialization order is broken? "); + } + + template<typename T> + void TestStaticInit(); + + namespace auto_registered_tests_helper { + template<typename T> + struct type_name ; + + #define REGISTER_TYPE_NAME(T) \ + namespace auto_registered_tests_helper{ \ + template<> \ + struct type_name<T> { \ + static const char* name; \ + }; \ + const char* type_name<T>::name = #T; \ + } \ + + typedef void (* p_test_function_type)(); + static std::vector<p_test_function_type> const_expr_tests; + + template <typename T> + struct registration{ + registration(){const_expr_tests.push_back(&TestStaticInit<T>);} + }; + } + //according to ISO C++11 [basic.start.init], static data fields of class template have unordered + //initialization unless it is an explicit specialization + template<typename T> + struct tester; + + #define TESTER_SPECIALIZATION(T,ct_value) \ + template<> \ + struct tester<T> { \ + struct static_before; \ + static bool result; \ + static static_before static_before_; \ + static tbb::atomic<T> static_atomic; \ + \ + static auto_registered_tests_helper::registration<T> registered; \ + }; \ + bool tester<T>::result = false; \ + \ + struct tester<T>::static_before { \ + static_before(){ result = (static_atomic==ct_value); } \ + } ; \ + \ + tester<T>::static_before tester<T>::static_before_; \ + tbb::atomic<T> tester<T>::static_atomic(ct_value); \ + \ + auto_registered_tests_helper::registration<T> tester<T>::registered; \ + REGISTER_TYPE_NAME(T) \ + + template<typename T> + void TestStaticInit(){ + //TODO: add printing of values to the assertion + std::string type_name = auto_registered_tests_helper::type_name<T>::name; + ASSERT(tester<T>::result,("Static initialization failed for atomic " + type_name).c_str()); + } + + void CallExprInitTests(){ +# if __TBB_STATIC_CONSTEXPR_INIT_BROKEN + REPORT("Known issue: Compile-time initialization fails for static tbb::atomic variables\n"); +# else + using namespace auto_registered_tests_helper; + for (size_t i =0; i<const_expr_tests.size(); ++i){ + (*const_expr_tests[i])(); + } + REMARK("ran %d constexpr static init test \n",const_expr_tests.size()); +# endif + } + + //TODO: unify somehow list of tested types with one in TestMain + //TODO: add specializations for: + //T,T(-T(1) + //T,1 +# if __TBB_64BIT_ATOMICS + TESTER_SPECIALIZATION(long long,8LL) + TESTER_SPECIALIZATION(unsigned long long,8ULL) +# endif + TESTER_SPECIALIZATION(unsigned long,8UL) + TESTER_SPECIALIZATION(long,8L) + TESTER_SPECIALIZATION(unsigned int,8U) + TESTER_SPECIALIZATION(int,8) + TESTER_SPECIALIZATION(unsigned short,8) + TESTER_SPECIALIZATION(short,8) + TESTER_SPECIALIZATION(unsigned char,8) + TESTER_SPECIALIZATION(signed char,8) + TESTER_SPECIALIZATION(char,8) + TESTER_SPECIALIZATION(wchar_t,8) + + int dummy; + TESTER_SPECIALIZATION(void*,&dummy); + TESTER_SPECIALIZATION(bool,false); + //TODO: add test for constexpt initialization of floating types + //for some unknown reasons 0.1 becomes 0.10000001 and equality comparison fails + enum written_number_enum{one=2,two}; + TESTER_SPECIALIZATION(written_number_enum,one); + //TODO: add test for ArrayElement<> as in TestMain +} + +void TestConstExprInitializationOfGlobalObjects(){ + //first assert that assumption the test based on are correct + TestConstExprInitializationOfGlobalObjectsHelper::TestStaticsDynamicInitializationOrder(); + TestConstExprInitializationOfGlobalObjectsHelper::CallExprInitTests(); +} +#endif //__TBB_ATOMIC_CTORS +template<typename T> +void TestOperations( T i, T j, T k ) { + TestValueInitialization<T>(); + TestDefaultInitialization<T>(); +# if __TBB_ATOMIC_CTORS + TestConstExprInitializationIsTranslationTime(); + TestDirectInitialization<T>(i); + TestDirectInitialization<T>(j); + TestDirectInitialization<T>(k); +# endif + TestConst(i); + TestCompareAndSwap(i,j,k); + TestFetchAndStore(i,k); // Pass i,k instead of i,j, because callee requires two distinct values. +} + +template<typename T> +void TestParallel( const char* name ); + +bool ParallelError; + +template<typename T> +struct AlignmentChecker { + char c; + tbb::atomic<T> i; +}; + +//TODO: candidate for test_compiler? +template<typename T> +void TestAlignment( const char* name ) { + AlignmentChecker<T> ac; + tbb::atomic<T> x; + x = T(0); + bool is_stack_variable_aligned = tbb::internal::is_aligned(&x,sizeof(T)); + bool is_member_variable_aligned = tbb::internal::is_aligned(&ac.i,sizeof(T)); + bool is_struct_size_correct = (sizeof(AlignmentChecker<T>)==2*sizeof(tbb::atomic<T>)); + bool known_issue_condition = __TBB_FORCE_64BIT_ALIGNMENT_BROKEN && ( sizeof(T)==8); + //TODO: replace these ifs with KNOWN_ISSUE macro when it available + if (!is_stack_variable_aligned){ + std::string msg = "Compiler failed to properly align local atomic variable?; size:"+to_string(sizeof(T)) + " type: " + +to_string(name) + " location:" + to_string(&x) +"\n"; + if (known_issue_condition) { + REPORT(("Known issue: "+ msg).c_str()); + }else{ + ASSERT(false,msg.c_str()); + } + } + if (!is_member_variable_aligned){ + std::string msg = "Compiler failed to properly align atomic member variable?; size:"+to_string(sizeof(T)) + " type: " + +to_string(name) + " location:" + to_string(&ac.i) +"\n"; + if (known_issue_condition) { + REPORT(("Known issue: "+ msg).c_str()); + }else{ + ASSERT(false,msg.c_str()); + } + } + if (!is_struct_size_correct){ + std::string msg = "Compiler failed to properly add padding to structure with atomic member variable?; Structure size:"+to_string(sizeof(AlignmentChecker<T>)) + + " atomic size:"+to_string(sizeof(tbb::atomic<T>)) + " type: " + to_string(name) +"\n"; + if (known_issue_condition) { + REPORT(("Known issue: "+ msg).c_str()); + }else{ + ASSERT(false,msg.c_str()); + } + } + + AlignmentChecker<T> array[5]; + for( int k=0; k<5; ++k ) { + bool is_member_variable_in_array_aligned = tbb::internal::is_aligned(&array[k].i,sizeof(T)); + if (!is_member_variable_in_array_aligned) { + std::string msg = "Compiler failed to properly align atomic member variable inside an array?; size:"+to_string(sizeof(T)) + " type:"+to_string(name) + + " location:" + to_string(&array[k].i) + "\n"; + if (known_issue_condition){ + REPORT(("Known issue: "+ msg).c_str()); + }else{ + ASSERT(false,msg.c_str()); + } + } + } +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning( disable: 4146 ) // unary minus operator applied to unsigned type, result still unsigned + #pragma warning( disable: 4334 ) // result of 32-bit shift implicitly converted to 64 bits +#endif + +/** T is an integral type. */ +template<typename T> +void TestAtomicInteger( const char* name ) { + REMARK("testing atomic<%s> (size=%d)\n",name,sizeof(tbb::atomic<T>)); + TestAlignment<T>(name); + TestOperations<T>(0L, T(-T(1)), T(1)); + for( int k=0; k<int(sizeof(long))*8-1; ++k ) { + const long p = 1L<<k; + TestOperations<T>(T(p), T(~(p)), T(1-(p))); + TestOperations<T>(T(-(p)), T(~(-(p))), T(1-(-(p)))); + TestFetchAndAdd<T>(T(-(p))); + } + TestParallel<T>( name ); +} + +namespace test_indirection_helpers { + template<typename T> + struct Foo { + T x, y, z; + }; +} + +template<typename T> +void TestIndirection() { + using test_indirection_helpers::Foo; + Foo<T> item; + tbb::atomic<Foo<T>*> pointer; + pointer = &item; + for( int k=-10; k<=10; ++k ) { + // Test various syntaxes for indirection to fields with non-zero offset. + T value1=T(), value2=T(); + for( size_t j=0; j<sizeof(T); ++j ) { + ((char*)&value1)[j] = char(k^j); + ((char*)&value2)[j] = char(k^j*j); + } + pointer->y = value1; + (*pointer).z = value2; + T result1 = (*pointer).y; + T result2 = pointer->z; + ASSERT( memcmp(&value1,&result1,sizeof(T))==0, NULL ); + ASSERT( memcmp(&value2,&result2,sizeof(T))==0, NULL ); + } + #if __TBB_ICC_BUILTIN_ATOMICS_POINTER_ALIASING_BROKEN + //prevent ICC compiler from assuming 'item' is unused and reusing it's storage + item.x = item.y=item.z; + #endif +} + +//! Test atomic<T*> +template<typename T> +void TestAtomicPointer() { + REMARK("testing atomic pointer (%d)\n",int(sizeof(T))); + T array[1000]; + TestOperations<T*>(&array[500],&array[250],&array[750]); + TestFetchAndAdd<T*>(&array[500]); + TestIndirection<T>(); + TestParallel<T*>( "pointer" ); + +} + +//! Test atomic<Ptr> where Ptr is a pointer to a type of unknown size +template<typename Ptr> +void TestAtomicPointerToTypeOfUnknownSize( const char* name ) { + REMARK("testing atomic<%s>\n",name); + char array[1000]; + TestOperations<Ptr>((Ptr)(void*)&array[500],(Ptr)(void*)&array[250],(Ptr)(void*)&array[750]); + TestParallel<Ptr>( name ); +} + +void TestAtomicBool() { + REMARK("testing atomic<bool>\n"); + TestOperations<bool>(false,true,true); + TestOperations<bool>(true,false,false); + TestParallel<bool>( "bool" ); +} + +template<typename EnumType> +struct HasImplicitConversionToInt { + typedef bool yes; + typedef int no; + __TBB_STATIC_ASSERT( sizeof(yes) != sizeof(no), "The helper needs two types of different sizes to work." ); + + static yes detect( int ); + static no detect( ... ); + + enum { value = (sizeof(yes) == sizeof(detect( EnumType() ))) }; +}; + +enum Color {Red=0,Green=1,Blue=-1}; + +void TestAtomicEnum() { + REMARK("testing atomic<Color>\n"); + TestOperations<Color>(Red,Green,Blue); + TestParallel<Color>( "Color" ); + __TBB_STATIC_ASSERT( HasImplicitConversionToInt< tbb::atomic<Color> >::value, "The implicit conversion is expected." ); +} + +#if __TBB_SCOPED_ENUM_PRESENT +enum class ScopedColor1 {ScopedRed,ScopedGreen,ScopedBlue=-1}; +// TODO: extend the test to cover 2 byte scoped enum as well +#if __TBB_ICC_SCOPED_ENUM_WITH_UNDERLYING_TYPE_NEGATIVE_VALUE_BROKEN +enum class ScopedColor2 : signed char {ScopedZero, ScopedOne,ScopedRed=42,ScopedGreen=-1,ScopedBlue=127}; +#else +enum class ScopedColor2 : signed char {ScopedZero, ScopedOne,ScopedRed=-128,ScopedGreen=-1,ScopedBlue=127}; +#endif + +// TODO: replace the hack of getting symbolic enum name with a better implementation +std::string enum_strings[] = {"ScopedZero","ScopedOne","ScopedRed","ScopedGreen","ScopedBlue"}; +template<> +std::string to_string<ScopedColor1>(const ScopedColor1& a){ + return enum_strings[a==ScopedColor1::ScopedBlue? 4 : (int)a+2]; +} +template<> +std::string to_string<ScopedColor2>(const ScopedColor2& a){ + return enum_strings[a==ScopedColor2::ScopedRed? 2 : + a==ScopedColor2::ScopedGreen? 3 : a==ScopedColor2::ScopedBlue? 4 : (int)a ]; +} + +void TestAtomicScopedEnum() { + REMARK("testing atomic<ScopedColor>\n"); + TestOperations<ScopedColor1>(ScopedColor1::ScopedRed,ScopedColor1::ScopedGreen,ScopedColor1::ScopedBlue); + TestParallel<ScopedColor1>( "ScopedColor1" ); +#if __TBB_ICC_SCOPED_ENUM_WITH_UNDERLYING_TYPE_ATOMIC_LOAD_BROKEN + REPORT("Known issue: the operation tests for a scoped enum with a specified underlying type are skipped.\n"); +#else + TestOperations<ScopedColor2>(ScopedColor2::ScopedRed,ScopedColor2::ScopedGreen,ScopedColor2::ScopedBlue); + TestParallel<ScopedColor2>( "ScopedColor2" ); +#endif + __TBB_STATIC_ASSERT( !HasImplicitConversionToInt< tbb::atomic<ScopedColor1> >::value, "The implicit conversion is not expected." ); + __TBB_STATIC_ASSERT( !HasImplicitConversionToInt< tbb::atomic<ScopedColor1> >::value, "The implicit conversion is not expected." ); + __TBB_STATIC_ASSERT( sizeof(tbb::atomic<ScopedColor1>) == sizeof(ScopedColor1), "tbb::atomic instantiated with scoped enum should have the same size as scoped enum." ); + __TBB_STATIC_ASSERT( sizeof(tbb::atomic<ScopedColor2>) == sizeof(ScopedColor2), "tbb::atomic instantiated with scoped enum should have the same size as scoped enum." ); +} +#endif /* __TBB_SCOPED_ENUM_PRESENT */ + +template<typename T> +void TestAtomicFloat( const char* name ) { + REMARK("testing atomic<%s>\n", name ); + TestAlignment<T>(name); + TestOperations<T>(0.5,3.25,10.75); + TestParallel<T>( name ); +} + +#define __TBB_TEST_GENERIC_PART_WORD_CAS (__TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED) +#if __TBB_TEST_GENERIC_PART_WORD_CAS +void TestEndianness() { + // Test for pure endianness (assumed by simpler probe in __TBB_MaskedCompareAndSwap()). + bool is_big_endian = true, is_little_endian = true; + const tbb::internal::uint32_t probe = 0x03020100; + ASSERT (tbb::internal::is_aligned(&probe,4), NULL); + for( const char *pc_begin = reinterpret_cast<const char*>(&probe) + , *pc = pc_begin, *pc_end = pc_begin + sizeof(probe) + ; pc != pc_end; ++pc) { + if (*pc != pc_end-1-pc) is_big_endian = false; + if (*pc != pc-pc_begin) is_little_endian = false; + } + ASSERT (!is_big_endian || !is_little_endian, NULL); + #if __TBB_ENDIANNESS==__TBB_ENDIAN_DETECT + ASSERT (is_big_endian || is_little_endian, "__TBB_ENDIANNESS should be set to __TBB_ENDIAN_UNSUPPORTED"); + #elif __TBB_ENDIANNESS==__TBB_ENDIAN_BIG + ASSERT (is_big_endian, "__TBB_ENDIANNESS should NOT be set to __TBB_ENDIAN_BIG"); + #elif __TBB_ENDIANNESS==__TBB_ENDIAN_LITTLE + ASSERT (is_little_endian, "__TBB_ENDIANNESS should NOT be set to __TBB_ENDIAN_LITTLE"); + #elif __TBB_ENDIANNESS==__TBB_ENDIAN_UNSUPPORTED + #error Generic implementation of part-word CAS may not be used: unsupported endianness + #else + #error Unexpected value of __TBB_ENDIANNESS + #endif +} + +namespace masked_cas_helpers { + const int numMaskedOperations = 100000; + const int testSpaceSize = 8; + int prime[testSpaceSize] = {3,5,7,11,13,17,19,23}; + + template<typename T> + class TestMaskedCAS_Body: NoAssign { + T* test_space_uncontended; + T* test_space_contended; + public: + TestMaskedCAS_Body( T* _space1, T* _space2 ) : test_space_uncontended(_space1), test_space_contended(_space2) {} + void operator()( int my_idx ) const { + using tbb::internal::__TBB_MaskedCompareAndSwap; + const volatile T my_prime = T(prime[my_idx]); // 'volatile' prevents erroneous optimizations by SunCC + T* const my_ptr = test_space_uncontended+my_idx; + T old_value=0; + for( int i=0; i<numMaskedOperations; ++i, old_value+=my_prime ){ + T result; + // Test uncontended case + T new_value = old_value + my_prime; + // The following CAS should always fail + result = __TBB_MaskedCompareAndSwap<T>(my_ptr,new_value,old_value-1); + ASSERT(result!=old_value-1, "masked CAS succeeded while it should fail"); + ASSERT(result==*my_ptr, "masked CAS result mismatch with real value"); + // The following one should succeed + result = __TBB_MaskedCompareAndSwap<T>(my_ptr,new_value,old_value); + ASSERT(result==old_value && *my_ptr==new_value, "masked CAS failed while it should succeed"); + // The following one should fail again + result = __TBB_MaskedCompareAndSwap<T>(my_ptr,new_value,old_value); + ASSERT(result!=old_value, "masked CAS succeeded while it should fail"); + ASSERT(result==*my_ptr, "masked CAS result mismatch with real value"); + // Test contended case + for( int j=0; j<testSpaceSize; ++j ){ + // try adding my_prime until success + T value; + do { + value = test_space_contended[j]; + result = __TBB_MaskedCompareAndSwap<T>(test_space_contended+j,value+my_prime,value); + } while( result!=value ); + } + } + } + }; + + template<typename T> + struct intptr_as_array_of + { + static const int how_many_Ts = sizeof(intptr_t)/sizeof(T); + union { + intptr_t result; + T space[ how_many_Ts ]; + }; + }; + + template<typename T> + intptr_t getCorrectUncontendedValue(int slot_idx) { + intptr_as_array_of<T> slot; + slot.result = 0; + for( int i=0; i<slot.how_many_Ts; ++i ) { + const T my_prime = T(prime[slot_idx*slot.how_many_Ts + i]); + for( int j=0; j<numMaskedOperations; ++j ) + slot.space[i] += my_prime; + } + return slot.result; + } + + template<typename T> + intptr_t getCorrectContendedValue() { + intptr_as_array_of<T> slot; + slot.result = 0; + for( int i=0; i<slot.how_many_Ts; ++i ) + for( int primes=0; primes<testSpaceSize; ++primes ) + for( int j=0; j<numMaskedOperations; ++j ) + slot.space[i] += prime[primes]; + return slot.result; + } +} // namespace masked_cas_helpers + +template<typename T> +void TestMaskedCAS() { + using namespace masked_cas_helpers; + REMARK("testing masked CAS<%d>\n",int(sizeof(T))); + + const int num_slots = sizeof(T)*testSpaceSize/sizeof(intptr_t); + intptr_t arr1[num_slots+2]; // two more "canary" slots at boundaries + intptr_t arr2[num_slots+2]; + for(int i=0; i<num_slots+2; ++i) + arr2[i] = arr1[i] = 0; + T* test_space_uncontended = (T*)(arr1+1); + T* test_space_contended = (T*)(arr2+1); + + NativeParallelFor( testSpaceSize, TestMaskedCAS_Body<T>(test_space_uncontended, test_space_contended) ); + + ASSERT( arr1[0]==0 && arr1[num_slots+1]==0 && arr2[0]==0 && arr2[num_slots+1]==0 , "adjacent memory was overwritten" ); + const intptr_t correctContendedValue = getCorrectContendedValue<T>(); + for(int i=0; i<num_slots; ++i) { + ASSERT( arr1[i+1]==getCorrectUncontendedValue<T>(i), "unexpected value in an uncontended slot" ); + ASSERT( arr2[i+1]==correctContendedValue, "unexpected value in a contended slot" ); + } +} +#endif // __TBB_TEST_GENERIC_PART_WORD_CAS + +template <typename T> +class TestRelaxedLoadStorePlainBody { + static T s_turn, + s_ready; + +public: + static unsigned s_count1, + s_count2; + + void operator() ( int id ) const { + using tbb::internal::__TBB_load_relaxed; + using tbb::internal::__TBB_store_relaxed; + + if ( id == 0 ) { + while ( !__TBB_load_relaxed(s_turn) ) { + ++s_count1; + __TBB_store_relaxed(s_ready, 1); + } + } + else { + while ( !__TBB_load_relaxed(s_ready) ) { + ++s_count2; + continue; + } + __TBB_store_relaxed(s_turn, 1); + } + } +}; // class TestRelaxedLoadStorePlainBody<T> + +template <typename T> T TestRelaxedLoadStorePlainBody<T>::s_turn = 0; +template <typename T> T TestRelaxedLoadStorePlainBody<T>::s_ready = 0; +template <typename T> unsigned TestRelaxedLoadStorePlainBody<T>::s_count1 = 0; +template <typename T> unsigned TestRelaxedLoadStorePlainBody<T>::s_count2 = 0; + +template <typename T> +class TestRelaxedLoadStoreAtomicBody { + static tbb::atomic<T> s_turn, + s_ready; + +public: + static unsigned s_count1, + s_count2; + + void operator() ( int id ) const { + if ( id == 0 ) { + while ( s_turn.template load<tbb::relaxed>() == 0 ) { + ++s_count1; + s_ready.template store<tbb::relaxed>(1); + } + } + else { + while ( s_ready.template load<tbb::relaxed>() == 0 ) { + ++s_count2; + continue; + } + s_turn.template store<tbb::relaxed>(1); + } + } +}; // class TestRelaxedLoadStoreAtomicBody<T> + +template <typename T> tbb::atomic<T> TestRelaxedLoadStoreAtomicBody<T>::s_turn; +template <typename T> tbb::atomic<T> TestRelaxedLoadStoreAtomicBody<T>::s_ready; +template <typename T> unsigned TestRelaxedLoadStoreAtomicBody<T>::s_count1 = 0; +template <typename T> unsigned TestRelaxedLoadStoreAtomicBody<T>::s_count2 = 0; + +template <typename T> +void TestRegisterPromotionSuppression () { + REMARK("testing register promotion suppression (size=%d)\n", (int)sizeof(T)); + NativeParallelFor( 2, TestRelaxedLoadStorePlainBody<T>() ); + NativeParallelFor( 2, TestRelaxedLoadStoreAtomicBody<T>() ); +} + +template<unsigned N> +class ArrayElement { + char item[N]; +}; + +#include "harness_barrier.h" +namespace bit_operation_test_suite{ + struct fixture : NoAssign{ + static const uintptr_t zero = 0; + const uintptr_t random_value ; + const uintptr_t inverted_random_value ; + fixture(): + random_value (tbb::internal::select_size_t_constant<0x9E3779B9,0x9E3779B97F4A7C15ULL>::value), + inverted_random_value ( ~random_value) + {} + }; + + struct TestAtomicORSerially : fixture { + void operator()(){ + //these additional variable are needed to get more meaningful expression in the assert + uintptr_t initial_value = zero; + uintptr_t atomic_or_result = initial_value; + uintptr_t atomic_or_operand = random_value; + + __TBB_AtomicOR(&atomic_or_result,atomic_or_operand); + + ASSERT(atomic_or_result == (initial_value | atomic_or_operand),"AtomicOR should do the OR operation"); + } + }; + struct TestAtomicANDSerially : fixture { + void operator()(){ + //these additional variable are needed to get more meaningful expression in the assert + uintptr_t initial_value = inverted_random_value; + uintptr_t atomic_and_result = initial_value; + uintptr_t atomic_and_operand = random_value; + + __TBB_AtomicAND(&atomic_and_result,atomic_and_operand); + + ASSERT(atomic_and_result == (initial_value & atomic_and_operand),"AtomicAND should do the AND operation"); + } + }; + + struct TestAtomicORandANDConcurrently : fixture { + static const uintptr_t bit_per_word = sizeof(uintptr_t) * 8; + static const uintptr_t threads_number = bit_per_word; + Harness::SpinBarrier m_barrier; + uintptr_t bitmap; + TestAtomicORandANDConcurrently():bitmap(zero) {} + + struct thread_body{ + TestAtomicORandANDConcurrently* test; + thread_body(TestAtomicORandANDConcurrently* the_test) : test(the_test) {} + void operator()(int thread_index)const{ + const uintptr_t single_bit_mask = ((uintptr_t)1u) << (thread_index % bit_per_word); + test->m_barrier.wait(); + static const char* error_msg = "AtomicOR and AtomicAND should be atomic"; + for (uintptr_t attempts=0; attempts<1000; attempts++ ){ + //Set and clear designated bits in a word. + __TBB_AtomicOR(&test->bitmap,single_bit_mask); + __TBB_Yield(); + bool the_bit_is_set_after_set_via_atomic_or = ((__TBB_load_with_acquire(test->bitmap) & single_bit_mask )== single_bit_mask); + ASSERT(the_bit_is_set_after_set_via_atomic_or,error_msg); + + __TBB_AtomicAND(&test->bitmap,~single_bit_mask); + __TBB_Yield(); + bool the_bit_is_clear_after_clear_via_atomic_and = ((__TBB_load_with_acquire(test->bitmap) & single_bit_mask )== zero); + ASSERT(the_bit_is_clear_after_clear_via_atomic_and,error_msg); + } + } + }; + void operator()(){ + m_barrier.initialize(threads_number); + NativeParallelFor(threads_number,thread_body(this)); + } + }; +} +void TestBitOperations(){ + using namespace bit_operation_test_suite; + TestAtomicORSerially()(); + TestAtomicANDSerially()(); + TestAtomicORandANDConcurrently()(); +} + +int TestMain () { +# if __TBB_ATOMIC_CTORS + TestConstExprInitializationOfGlobalObjects(); +# endif //__TBB_ATOMIC_CTORS +# if __TBB_64BIT_ATOMICS && !__TBB_CAS_8_CODEGEN_BROKEN + TestAtomicInteger<unsigned long long>("unsigned long long"); + TestAtomicInteger<long long>("long long"); +# elif __TBB_CAS_8_CODEGEN_BROKEN + REPORT("Known issue: compiler generates incorrect code for 64-bit atomics on this configuration\n"); +# else + REPORT("Known issue: 64-bit atomics are not supported\n"); + ASSERT(sizeof(long long)==8, "type long long is not 64 bits"); +# endif + TestAtomicInteger<unsigned long>("unsigned long"); + TestAtomicInteger<long>("long"); + TestAtomicInteger<unsigned int>("unsigned int"); + TestAtomicInteger<int>("int"); + TestAtomicInteger<unsigned short>("unsigned short"); + TestAtomicInteger<short>("short"); + TestAtomicInteger<signed char>("signed char"); + TestAtomicInteger<unsigned char>("unsigned char"); + TestAtomicInteger<char>("char"); + TestAtomicInteger<wchar_t>("wchar_t"); + TestAtomicInteger<size_t>("size_t"); + TestAtomicInteger<ptrdiff_t>("ptrdiff_t"); + TestAtomicPointer<ArrayElement<1> >(); + TestAtomicPointer<ArrayElement<2> >(); + TestAtomicPointer<ArrayElement<3> >(); + TestAtomicPointer<ArrayElement<4> >(); + TestAtomicPointer<ArrayElement<5> >(); + TestAtomicPointer<ArrayElement<6> >(); + TestAtomicPointer<ArrayElement<7> >(); + TestAtomicPointer<ArrayElement<8> >(); + TestAtomicPointerToTypeOfUnknownSize<IncompleteType*>( "IncompleteType*" ); + TestAtomicPointerToTypeOfUnknownSize<void*>( "void*" ); + TestAtomicBool(); + TestAtomicEnum(); +# if __TBB_SCOPED_ENUM_PRESENT + TestAtomicScopedEnum(); +# endif + TestAtomicFloat<float>("float"); +# if __TBB_64BIT_ATOMICS && !__TBB_CAS_8_CODEGEN_BROKEN + TestAtomicFloat<double>("double"); +# else + ASSERT(sizeof(double)==8, "type double is not 64 bits"); +# endif + ASSERT( !ParallelError, NULL ); +# if __TBB_TEST_GENERIC_PART_WORD_CAS + TestEndianness(); + ASSERT (sizeof(short)==2, NULL); + TestMaskedCAS<unsigned short>(); + TestMaskedCAS<short>(); + TestMaskedCAS<unsigned char>(); + TestMaskedCAS<signed char>(); + TestMaskedCAS<char>(); +# elif __TBB_USE_GENERIC_PART_WORD_CAS +# error Generic part-word CAS is enabled, but not covered by the test +# else + REPORT("Skipping test for generic part-word CAS\n"); +# endif +# if __TBB_64BIT_ATOMICS && !__TBB_CAS_8_CODEGEN_BROKEN + TestRegisterPromotionSuppression<tbb::internal::int64_t>(); +# endif + TestRegisterPromotionSuppression<tbb::internal::int32_t>(); + TestRegisterPromotionSuppression<tbb::internal::int16_t>(); + TestRegisterPromotionSuppression<tbb::internal::int8_t>(); + TestBitOperations(); + + return Harness::Done; +} + +template<typename T, bool aligned> +class AlignedAtomic: NoAssign { + //tbb::aligned_space can not be used here, because internally it utilize align pragma/attribute, + //which has bugs on 8byte alignment on ia32 on some compilers( see according ****_BROKEN macro) + // Allocate space big enough to always contain sizeof(T)-byte locations that are aligned and misaligned. + char raw_space[2*sizeof(T) -1]; +public: + tbb::atomic<T>& construct_atomic(){ + std::memset(&raw_space[0],0, sizeof(raw_space)); + uintptr_t delta = aligned ? 0 : sizeof(T)/2; + size_t index=sizeof(T)-1; + tbb::atomic<T>* y = reinterpret_cast<tbb::atomic<T>*>((reinterpret_cast<uintptr_t>(&raw_space[index+delta])&~index) - delta); + // Assertion checks that y really did end up somewhere inside "raw_space". + ASSERT( raw_space<=reinterpret_cast<char*>(y), "y starts before raw_space" ); + ASSERT( reinterpret_cast<char*>(y+1) <= raw_space+sizeof(raw_space), "y starts after raw_space" ); + ASSERT( !(aligned ^ tbb::internal::is_aligned(y,sizeof(T))), "y is not aligned as it required" ); + return *(new (y) tbb::atomic<T>()); + } +}; + +template<typename T, bool aligned> +struct FlagAndMessage: AlignedAtomic<T,aligned> { + //! 0 if message not set yet, 1 if message is set. + tbb::atomic<T>& flag; + /** Force flag and message to be on distinct cache lines for machines with cache line size <= 4096 bytes */ + char pad[4096/sizeof(T)]; + //! Non-zero if message is ready + T message; + FlagAndMessage(): flag(FlagAndMessage::construct_atomic()) { + std::memset(pad,0,sizeof(pad)); + } +}; + +// A special template function used for summation. +// Actually it is only necessary because of its specialization for void* +template<typename T> +T special_sum(intptr_t arg1, intptr_t arg2) { + return (T)((T)arg1 + arg2); +} + +// The specialization for IncompleteType* is required +// because pointer arithmetic (+) is impossible with IncompleteType* +template<> +IncompleteType* special_sum<IncompleteType*>(intptr_t arg1, intptr_t arg2) { + return (IncompleteType*)(arg1 + arg2); +} + +// The specialization for void* is required +// because pointer arithmetic (+) is impossible with void* +template<> +void* special_sum<void*>(intptr_t arg1, intptr_t arg2) { + return (void*)(arg1 + arg2); +} + +// The specialization for bool is required to shut up gratuitous compiler warnings, +// because some compilers warn about casting int to bool. +template<> +bool special_sum<bool>(intptr_t arg1, intptr_t arg2) { + return ((arg1!=0) + arg2)!=0; +} + +#if __TBB_SCOPED_ENUM_PRESENT +// The specialization for scoped enumerators is required +// because scoped enumerators prohibit implicit conversion to int +template<> +ScopedColor1 special_sum<ScopedColor1>(intptr_t arg1, intptr_t arg2) { + return (ScopedColor1)(arg1 + arg2); +} +template<> +ScopedColor2 special_sum<ScopedColor2>(intptr_t arg1, intptr_t arg2) { + return (ScopedColor2)(arg1 + arg2); +} +#endif + +volatile int One = 1; + +inline bool IsRelaxed ( LoadStoreExpression e ) { + return e == UseExplicitRelaxed || e == UseGlobalHelperRelaxed; +} + +template <typename T, LoadStoreExpression E> +struct LoadStoreTraits; + +template <typename T> +struct LoadStoreTraits<T, UseOperators> { + static void load ( T& dst, const tbb::atomic<T>& src ) { dst = src; } + static void store ( tbb::atomic<T>& dst, const T& src ) { dst = src; } +}; + +template <typename T> +struct LoadStoreTraits<T, UseImplicitAcqRel> { + static void load ( T& dst, const tbb::atomic<T>& src ) { dst = src.load(); } + static void store ( tbb::atomic<T>& dst, const T& src ) { dst.store(src); } +}; + +template <typename T> +struct LoadStoreTraits<T, UseExplicitFullyFenced> { + static void load ( T& dst, const tbb::atomic<T>& src ) { dst = src.template load<tbb::full_fence>(); } + static void store ( tbb::atomic<T>& dst, const T& src ) { dst.template store<tbb::full_fence>(src); } +}; + +template <typename T> +struct LoadStoreTraits<T, UseExplicitAcqRel> { + static void load ( T& dst, const tbb::atomic<T>& src ) { dst = src.template load<tbb::acquire>(); } + static void store ( tbb::atomic<T>& dst, const T& src ) { dst.template store<tbb::release>(src); } +}; + +template <typename T> +struct LoadStoreTraits<T, UseExplicitRelaxed> { + static void load ( T& dst, const tbb::atomic<T>& src ) { dst = src.template load<tbb::relaxed>(); } + static void store ( tbb::atomic<T>& dst, const T& src ) { dst.template store<tbb::relaxed>(src); } +}; + +template <typename T> +struct LoadStoreTraits<T, UseGlobalHelperFullyFenced> { + static void load ( T& dst, const tbb::atomic<T>& src ) { dst = tbb::load<tbb::full_fence>(src); } + static void store ( tbb::atomic<T>& dst, const T& src ) { tbb::store<tbb::full_fence>(dst, src); } +}; + +template <typename T> +struct LoadStoreTraits<T, UseGlobalHelperAcqRel> { + static void load ( T& dst, const tbb::atomic<T>& src ) { dst = tbb::load<tbb::acquire>(src); } + static void store ( tbb::atomic<T>& dst, const T& src ) { tbb::store<tbb::release>(dst, src); } +}; + +template <typename T> +struct LoadStoreTraits<T, UseGlobalHelperRelaxed> { + static void load ( T& dst, const tbb::atomic<T>& src ) { dst = tbb::load<tbb::relaxed>(src); } + static void store ( tbb::atomic<T>& dst, const T& src ) { tbb::store<tbb::relaxed>(dst, src); } +}; + +template<typename T, bool aligned, LoadStoreExpression E> +struct HammerLoadAndStoreFence: NoAssign { + typedef FlagAndMessage<T,aligned> fam_type; +private: + typedef LoadStoreTraits<T, E> trait; + fam_type* fam; + const int n; + const int p; + const int trial; + const char* name; + mutable T accum; +public: + HammerLoadAndStoreFence( fam_type* fam_, int n_, int p_, const char* name_, int trial_ ) : fam(fam_), n(n_), p(p_), trial(trial_), name(name_) {} + void operator()( int k ) const { + int one = One; + fam_type* s = fam+k; + fam_type* s_next = fam + (k+1)%p; + for( int i=0; i<n; ++i ) { + // The inner for loop is a spin-wait loop, which is normally considered very bad style. + // But we must use it here because we are interested in examining subtle hardware effects. + for(unsigned short cnt=1; ; ++cnt) { + if( !(cnt%1024) ) // to help 1-core or oversubscribed systems complete the test, yield every 2^10 iterations + __TBB_Yield(); + // Compilers typically generate non-trivial sequence for division by a constant. + // The expression here is dependent on the loop index i, so it cannot be hoisted. + #define COMPLICATED_ZERO (i*(one-1)/100) + // Read flag and then the message + T flag, message; + if( trial&1 ) { + // COMPLICATED_ZERO here tempts compiler to hoist load of message above reading of flag. + trait::load( flag, (s+COMPLICATED_ZERO)->flag ); + message = s->message; + } else { + trait::load( flag, s->flag ); + message = s->message; + } + if ( flag != T(0) ) { + if( flag!=(T)-1 ) { + REPORT("ERROR: flag!=(T)-1 k=%d i=%d trial=%x type=%s (atomicity problem?)\n", k, i, trial, name ); + ParallelError = true; + } + if( !IsRelaxed(E) && message!=(T)-1 ) { + REPORT("ERROR: message!=(T)-1 k=%d i=%d trial=%x type=%s mode=%d (memory fence problem?)\n", k, i, trial, name, E ); + ParallelError = true; + } + s->message = T(0); + trait::store( s->flag, T(0) ); + // Prevent deadlock possible in relaxed mode because of store(0) + // to the first thread's flag being reordered after the last + // thread's store(-1) into it. + if ( IsRelaxed(E) ) { + while( s_next->flag.template load<tbb::relaxed>() != T(0) ) + __TBB_Yield(); + } + else + ASSERT( s_next->flag == T(0), NULL ); + // Set message and then the flag + if( trial&2 ) { + // COMPLICATED_ZERO here tempts compiler to sink store below setting of flag + s_next->message = special_sum<T>(-1, COMPLICATED_ZERO); + trait::store( s_next->flag, (T)-1 ); + } else { + s_next->message = (T)-1; + trait::store( s_next->flag, (T)-1 ); + } + break; + } else { + // Force compiler to use message anyway, so it cannot sink read of s->message below the if. + accum = message; + } + } + } + } +}; + +//! Test that atomic<T> has acquire semantics for loads and release semantics for stores. +/** Test performs round-robin passing of message among p processors, + where p goes from MinThread to MaxThread. */ +template<typename T, bool aligned, LoadStoreExpression E> +void TestLoadAndStoreFences( const char* name ) { + typedef HammerLoadAndStoreFence<T, aligned, E> hammer_load_store_type; + typedef typename hammer_load_store_type::fam_type fam_type; + for( int p=MinThread<2 ? 2 : MinThread; p<=MaxThread; ++p ) { + fam_type * fam = new fam_type[p]; + // Each of four trials exercise slightly different expression pattern within the test. + // See occurrences of COMPLICATED_ZERO for details. + for( int trial=0; trial<4; ++trial ) { + fam->message = (T)-1; + fam->flag = (T)-1; + NativeParallelFor( p, hammer_load_store_type( fam, 100, p, name, trial ) ); + if ( !IsRelaxed(E) ) { + for( int k=0; k<p; ++k ) { + ASSERT( fam[k].message==(k==0 ? (T)-1 : T(0)), "incomplete round-robin?" ); + ASSERT( fam[k].flag==(k==0 ? (T)-1 : T(0)), "incomplete round-robin?" ); + } + } + } + delete[] fam; + } +} + +//! Sparse set of values of integral type T. +/** Set is designed so that if a value is read or written non-atomically, + the resulting intermediate value is likely to not be a member of the set. */ +template<typename T> +class SparseValueSet { + T factor; +public: + SparseValueSet() { + // Compute factor such that: + // 1. It has at least one 1 in most of its bytes. + // 2. The bytes are typically different. + // 3. When multiplied by any value <=127, the product does not overflow. + factor = T(0); + for( unsigned i=0; i<sizeof(T)*8-7; i+=7 ) + factor = T(factor | T(1)<<i); + } + //! Get ith member of set + T get( int i ) const { + // Create multiple of factor. The & prevents overflow of the product. + return T((i&0x7F)*factor); + } + //! True if set contains x + bool contains( T x ) const { + // True if + return (x%factor)==0; + } +}; + +//! Specialization for pointer types. The pointers are random and should not be dereferenced. +template<typename T> +class SparseValueSet<T*> { + SparseValueSet<ptrdiff_t> my_set; +public: + T* get( int i ) const {return reinterpret_cast<T*>(my_set.get(i));} + bool contains( T* x ) const {return my_set.contains(reinterpret_cast<ptrdiff_t>(x));} +}; + +//! Specialization for bool. +/** Checking bool for atomic read/write is pointless in practice, because + there is no way to *not* atomically read or write a bool value. */ +template<> +class SparseValueSet<bool> { +public: + bool get( int i ) const {return i&1;} + bool contains( bool ) const {return true;} +}; + +#if _MSC_VER==1500 && !defined(__INTEL_COMPILER) + // VS2008/VC9 seems to have an issue; limits pull in math.h + #pragma warning( push ) + #pragma warning( disable: 4985 ) +#endif +#include <limits> /* Need std::numeric_limits */ +#if _MSC_VER==1500 && !defined(__INTEL_COMPILER) + #pragma warning( pop ) +#endif + +//! Commonality inherited by specializations for floating-point types. +template<typename T> +class SparseFloatSet: NoAssign { + const T epsilon; +public: + SparseFloatSet() : epsilon(std::numeric_limits<T>::epsilon()) {} + T get( int i ) const { + return i==0 ? T(0) : 1/T((i&0x7F)+1); + } + bool contains( T x ) const { + if( x==T(0) ) { + return true; + } else { + int j = int(1/x+T(0.5)); + if( 0<j && j<=128 ) { + T error = x*T(j)-T(1); + // In the calculation above, if x was indeed generated by method get, the error should be + // at most epsilon, because x is off by at most 1/2 ulp from its infinitely precise value, + // j is exact, and the multiplication incurs at most another 1/2 ulp of round-off error. + if( -epsilon<=error && error<=epsilon ) { + return true; + } else { + REPORT("Warning: excessive floating-point error encountered j=%d x=%.15g error=%.15g\n",j,x,error); + } + } + return false; + } + }; +}; + +template<> +class SparseValueSet<float>: public SparseFloatSet<float> {}; + +template<> +class SparseValueSet<double>: public SparseFloatSet<double> {}; + +#if __TBB_SCOPED_ENUM_PRESENT +//! Commonality inherited by specializations for scoped enumerator types. +template<typename EnumType> +class SparseEnumValueSet { +public: + EnumType get( int i ) const {return i%3==0 ? EnumType::ScopedRed : i%3==1 ? EnumType::ScopedGreen : EnumType::ScopedBlue;} + bool contains( EnumType e ) const {return e==EnumType::ScopedRed || e==EnumType::ScopedGreen || e==EnumType::ScopedBlue;} +}; +template<> +class SparseValueSet<ScopedColor1> : public SparseEnumValueSet<ScopedColor1> {}; +template<> +class SparseValueSet<ScopedColor2> : public SparseEnumValueSet<ScopedColor2> {}; +#endif + +template<typename T, bool aligned> +class HammerAssignment: AlignedAtomic<T,aligned> { + tbb::atomic<T>& x; + const char* name; + SparseValueSet<T> set; +public: + HammerAssignment(const char* name_ ) : x(HammerAssignment::construct_atomic()), name(name_) { + x = set.get(0); + } + void operator()( int k ) const { + const int n = 1000000; + if( k ) { + tbb::atomic<T> z; + AssertSameType( z=x, z ); // Check that return type from assignment is correct + for( int i=0; i<n; ++i ) { + // Read x atomically into z. + z = x; + if( !set.contains(z) ) { + REPORT("ERROR: assignment of atomic<%s> is not atomic\n", name); + ParallelError = true; + return; + } + } + } else { + tbb::atomic<T> y; + for( int i=0; i<n; ++i ) { + // Get pseudo-random value. + y = set.get(i); + // Write y atomically into x. + x = y; + } + } + } +}; + +// Compile-time check that a class method has the required signature. +// Intended to check the assignment operator of tbb::atomic. +template<typename T> void TestAssignmentSignature( T& (T::*)(const T&) ) {} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning( disable: 4355 4800 ) +#endif + +template<typename T, bool aligned> +void TestAssignment( const char* name ) { + TestAssignmentSignature( &tbb::atomic<T>::operator= ); + NativeParallelFor( 2, HammerAssignment<T,aligned>(name ) ); +} + +template <typename T, bool aligned, LoadStoreExpression E> +class DekkerArbitrationBody : NoAssign, Harness::NoAfterlife { + typedef LoadStoreTraits<T, E> trait; + + mutable Harness::FastRandom my_rand; + static const unsigned short c_rand_ceil = 10; + mutable AlignedAtomic<T,aligned> s_ready_storage[2]; + mutable AlignedAtomic<T,aligned> s_turn_storage; + mutable tbb::atomic<T>* s_ready[2]; + tbb::atomic<T>& s_turn; + mutable volatile bool s_inside; + +public: + void operator() ( int id ) const { + const int me = id; + const T other = (T)(uintptr_t)(1 - id), + cleared = T(0), + signaled = T(1); + for ( int i = 0; i < 100000; ++i ) { + trait::store( *s_ready[me], signaled ); + trait::store( s_turn, other ); + T r, t; + for ( int j = 0; ; ++j ) { + trait::load(r, *s_ready[(uintptr_t)other]); + trait::load(t, s_turn); + if ( r != signaled || t != other ) + break; + __TBB_Pause(1); + if ( j == 2<<12 ) { + j = 0; + __TBB_Yield(); + } + } + // Entered critical section + ASSERT( !s_inside, "Peterson lock is broken - some fences are missing" ); + s_inside = true; + unsigned short spin = my_rand.get() % c_rand_ceil; + for ( volatile int j = 0; j < spin; ++j ) + continue; + s_inside = false; + ASSERT( !s_inside, "Peterson lock is broken - some fences are missing" ); + // leaving critical section + trait::store( *s_ready[me], cleared ); + spin = my_rand.get() % c_rand_ceil; + for ( volatile int j = 0; j < spin; ++j ) + continue; + } + } + + DekkerArbitrationBody () + : my_rand((unsigned)(uintptr_t)this) + , s_turn(s_turn_storage.construct_atomic()) + , s_inside (false) + { + //atomics pointed to by s_ready and s_turn will be zeroed by the + //according construct_atomic() calls + s_ready[0] = &s_ready_storage[0].construct_atomic(); + s_ready[1] = &s_ready_storage[1].construct_atomic(); + } +}; + +template <typename T, bool aligned, LoadStoreExpression E> +void TestDekkerArbitration () { + NativeParallelFor( 2, DekkerArbitrationBody<T,aligned, E>() ); +} + +template<typename T> +void TestParallel( const char* name ) { + //TODO: looks like there are no tests for operations other than load/store ? +#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN + if (sizeof(T)==8){ + TestLoadAndStoreFences<T, false, UseOperators>(name); + TestLoadAndStoreFences<T, false, UseImplicitAcqRel>(name); + TestLoadAndStoreFences<T, false, UseExplicitFullyFenced>(name); + TestLoadAndStoreFences<T, false, UseExplicitAcqRel>(name); + TestLoadAndStoreFences<T, false, UseExplicitRelaxed>(name); + TestLoadAndStoreFences<T, false, UseGlobalHelperFullyFenced>(name); + TestLoadAndStoreFences<T, false, UseGlobalHelperAcqRel>(name); + TestLoadAndStoreFences<T, false, UseGlobalHelperRelaxed>(name); + TestAssignment<T,false>(name); + TestDekkerArbitration<T, false, UseExplicitFullyFenced>(); + TestDekkerArbitration<T, false, UseGlobalHelperFullyFenced>(); + } +#endif + + TestLoadAndStoreFences<T, true, UseOperators>(name); + TestLoadAndStoreFences<T, true, UseImplicitAcqRel>(name); + TestLoadAndStoreFences<T, true, UseExplicitFullyFenced>(name); + TestLoadAndStoreFences<T, true, UseExplicitAcqRel>(name); + TestLoadAndStoreFences<T, true, UseExplicitRelaxed>(name); + TestLoadAndStoreFences<T, true, UseGlobalHelperFullyFenced>(name); + TestLoadAndStoreFences<T, true, UseGlobalHelperAcqRel>(name); + TestLoadAndStoreFences<T, true, UseGlobalHelperRelaxed>(name); + TestAssignment<T,true>(name); + TestDekkerArbitration<T, true, UseExplicitFullyFenced>(); + TestDekkerArbitration<T, true, UseGlobalHelperFullyFenced>(); +} + +#endif // __TBB_TEST_SKIP_PIC_MODE || __TBB_TEST_SKIP_BUILTINS_MODE diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range.cpp new file mode 100644 index 00000000..7fe9f7dd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range.cpp @@ -0,0 +1,206 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/blocked_range.h" +#include "harness_assert.h" + +// First test as much as we can without including other headers. +// Doing so should catch problems arising from failing to include headers. + +class AbstractValueType { + AbstractValueType() {} + int value; +public: + friend AbstractValueType MakeAbstractValueType( int i ); + friend int GetValueOf( const AbstractValueType& v ) {return v.value;} +}; + +AbstractValueType MakeAbstractValueType( int i ) { + AbstractValueType x; + x.value = i; + return x; +} + +std::size_t operator-( const AbstractValueType& u, const AbstractValueType& v ) { + return GetValueOf(u) - GetValueOf(v); +} + +bool operator<( const AbstractValueType& u, const AbstractValueType& v ) { + return GetValueOf(u) < GetValueOf(v); +} + +AbstractValueType operator+( const AbstractValueType& u, std::size_t offset ) { + return MakeAbstractValueType(GetValueOf(u) + int(offset)); +} + +static void SerialTest() { + for( int x=-10; x<10; ++x ) + for( int y=-10; y<10; ++y ) { + AbstractValueType i = MakeAbstractValueType(x); + AbstractValueType j = MakeAbstractValueType(y); + for( std::size_t k=1; k<10; ++k ) { + typedef tbb::blocked_range<AbstractValueType> range_type; + range_type r( i, j, k ); + AssertSameType( r.empty(), true ); + AssertSameType( range_type::size_type(), std::size_t() ); + AssertSameType( static_cast<range_type::const_iterator*>(0), static_cast<AbstractValueType*>(0) ); + AssertSameType( r.begin(), MakeAbstractValueType(0) ); + AssertSameType( r.end(), MakeAbstractValueType(0) ); + ASSERT( r.empty()==(y<=x), NULL ); + ASSERT( r.grainsize()==k, NULL ); + if( x<=y ) { + AssertSameType( r.is_divisible(), true ); + ASSERT( r.is_divisible()==(std::size_t(y-x)>k), NULL ); + ASSERT( r.size()==std::size_t(y-x), NULL ); + if( r.is_divisible() ) { + tbb::blocked_range<AbstractValueType> r2(r,tbb::split()); + ASSERT( GetValueOf(r.begin())==x, NULL ); + ASSERT( GetValueOf(r.end())==GetValueOf(r2.begin()), NULL ); + ASSERT( GetValueOf(r2.end())==y, NULL ); + ASSERT( r.grainsize()==k, NULL ); + ASSERT( r2.grainsize()==k, NULL ); + } + } + } + } +} + +#include "tbb/parallel_for.h" +#include "harness.h" + +const int N = 1<<22; + +unsigned char Array[N]; + +struct Striker { + // Note: we use <int> here instead of <long> in order to test for Quad 407676 + void operator()( const tbb::blocked_range<int>& r ) const { + for( tbb::blocked_range<int>::const_iterator i=r.begin(); i!=r.end(); ++i ) + ++Array[i]; + } +}; + +void ParallelTest() { + for( int i=0; i<N; i=i<3 ? i+1 : i*3 ) { + const tbb::blocked_range<int> r( 0, i, 10 ); + tbb::parallel_for( r, Striker() ); + for( int k=0; k<N; ++k ) { + ASSERT( Array[k]==(k<i), NULL ); + Array[k] = 0; + } + } +} + +#if __TBB_RANGE_BASED_FOR_PRESENT +#include "test_range_based_for.h" +#include <functional> +void TestRangeBasedFor() { + using namespace range_based_for_support_tests; + REMARK("testing range based for loop compatibility \n"); + + size_t int_array[100] = {0}; + const size_t sequence_length = Harness::array_length(int_array); + + for (size_t i = 0; i < sequence_length; ++i) { + int_array[i] = i + 1; + } + + const tbb::blocked_range<size_t*> r(int_array, Harness::end(int_array), 1); + + ASSERT(range_based_for_accumulate<size_t>(r, std::plus<size_t>(), size_t(0)) == gauss_summ_of_int_sequence(sequence_length), "incorrect accumulated value generated via range based for ?"); +} +#endif //if __TBB_RANGE_BASED_FOR_PRESENT + +#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES + +void TestProportionalSplitOverflow() +{ + REMARK("Testing overflow during proportional split - "); + using tbb::blocked_range; + using tbb::proportional_split; + + blocked_range<size_t> r1(0, size_t(-1) / 2); + size_t size = r1.size(); + size_t begin = r1.begin(); + size_t end = r1.end(); + + proportional_split p(1, 3); + blocked_range<size_t> r2(r1, p); + + // overflow-free computation + size_t parts = p.left() + p.right(); + size_t int_part = size / parts; + size_t fraction = size - int_part * parts; // fraction < parts + size_t right_idx = int_part * p.right() + fraction * p.right() / parts + 1; + size_t newRangeBegin = end - right_idx; + + // Division in 'right_idx' very likely is inexact also. + size_t tolerance = 1; + size_t diff = (r2.begin() < newRangeBegin) ? (newRangeBegin - r2.begin()) : (r2.begin() - newRangeBegin); + bool is_split_correct = diff <= tolerance; + bool test_passed = (r1.begin() == begin && r1.end() == r2.begin() && is_split_correct && + r2.end() == end); + if (!test_passed) { + REPORT("Incorrect split of blocked range[%lu, %lu) into r1[%lu, %lu) and r2[%lu, %lu), " + "must be r1[%lu, %lu) and r2[%lu, %lu)\n", begin, end, r1.begin(), r1.end(), r2.begin(), r2.end(), begin, newRangeBegin, newRangeBegin, end); + ASSERT(test_passed, NULL); + } + REMARK("OK\n"); +} +#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void TestDeductionGuides() { + std::vector<const int *> v; + + // check blocked_range(Value, Value, size_t) + tbb::blocked_range r1(v.begin(), v.end()); + static_assert(std::is_same<decltype(r1), tbb::blocked_range<decltype(v)::iterator>>::value); + + // check blocked_range(blocked_range &) + tbb::blocked_range r2(r1); + static_assert(std::is_same<decltype(r2), decltype(r1)>::value); + + // check blocked_range(blocked_range &&) + tbb::blocked_range r3(std::move(r1)); + static_assert(std::is_same<decltype(r3), decltype(r1)>::value); +} +#endif + +//------------------------------------------------------------------------ +// Test driver +#include "tbb/task_scheduler_init.h" + +int TestMain () { + SerialTest(); + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + ParallelTest(); + } + + #if __TBB_RANGE_BASED_FOR_PRESENT + TestRangeBasedFor(); + #endif //if __TBB_RANGE_BASED_FOR_PRESENT + + #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES + TestProportionalSplitOverflow(); + #endif + + #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides(); + #endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range2d.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range2d.cpp new file mode 100644 index 00000000..13c81f0b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range2d.cpp @@ -0,0 +1,168 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/blocked_range2d.h" +#include "harness_assert.h" + +// First test as much as we can without including other headers. +// Doing so should catch problems arising from failing to include headers. + +template<typename Tag> +class AbstractValueType { + AbstractValueType() {} + int value; +public: + template<typename OtherTag> + friend AbstractValueType<OtherTag> MakeAbstractValueType( int i ); + + template<typename OtherTag> + friend int GetValueOf( const AbstractValueType<OtherTag>& v ) ; +}; + +template<typename Tag> +AbstractValueType<Tag> MakeAbstractValueType( int i ) { + AbstractValueType<Tag> x; + x.value = i; + return x; +} + +template<typename Tag> +int GetValueOf( const AbstractValueType<Tag>& v ) {return v.value;} + +template<typename Tag> +bool operator<( const AbstractValueType<Tag>& u, const AbstractValueType<Tag>& v ) { + return GetValueOf(u)<GetValueOf(v); +} + +template<typename Tag> +std::size_t operator-( const AbstractValueType<Tag>& u, const AbstractValueType<Tag>& v ) { + return GetValueOf(u)-GetValueOf(v); +} + +template<typename Tag> +AbstractValueType<Tag> operator+( const AbstractValueType<Tag>& u, std::size_t offset ) { + return MakeAbstractValueType<Tag>(GetValueOf(u)+int(offset)); +} + +struct RowTag {}; +struct ColTag {}; + +static void SerialTest() { + typedef AbstractValueType<RowTag> row_type; + typedef AbstractValueType<ColTag> col_type; + typedef tbb::blocked_range2d<row_type,col_type> range_type; + for( int row_x=-10; row_x<10; ++row_x ) { + for( int row_y=row_x; row_y<10; ++row_y ) { + row_type row_i = MakeAbstractValueType<RowTag>(row_x); + row_type row_j = MakeAbstractValueType<RowTag>(row_y); + for( int row_grain=1; row_grain<10; ++row_grain ) { + for( int col_x=-10; col_x<10; ++col_x ) { + for( int col_y=col_x; col_y<10; ++col_y ) { + col_type col_i = MakeAbstractValueType<ColTag>(col_x); + col_type col_j = MakeAbstractValueType<ColTag>(col_y); + for( int col_grain=1; col_grain<10; ++col_grain ) { + range_type r( row_i, row_j, row_grain, col_i, col_j, col_grain ); + AssertSameType( r.is_divisible(), true ); + AssertSameType( r.empty(), true ); + AssertSameType( static_cast<range_type::row_range_type::const_iterator*>(0), static_cast<row_type*>(0) ); + AssertSameType( static_cast<range_type::col_range_type::const_iterator*>(0), static_cast<col_type*>(0) ); + AssertSameType( r.rows(), tbb::blocked_range<row_type>( row_i, row_j, 1 )); + AssertSameType( r.cols(), tbb::blocked_range<col_type>( col_i, col_j, 1 )); + ASSERT( r.empty()==(row_x==row_y||col_x==col_y), NULL ); + ASSERT( r.is_divisible()==(row_y-row_x>row_grain||col_y-col_x>col_grain), NULL ); + if( r.is_divisible() ) { + range_type r2(r,tbb::split()); + if( GetValueOf(r2.rows().begin())==GetValueOf(r.rows().begin()) ) { + ASSERT( GetValueOf(r2.rows().end())==GetValueOf(r.rows().end()), NULL ); + ASSERT( GetValueOf(r2.cols().begin())==GetValueOf(r.cols().end()), NULL ); + } else { + ASSERT( GetValueOf(r2.cols().end())==GetValueOf(r.cols().end()), NULL ); + ASSERT( GetValueOf(r2.rows().begin())==GetValueOf(r.rows().end()), NULL ); + } + } + } + } + } + } + } + } +} + +#include "tbb/parallel_for.h" +#include "harness.h" + +const int N = 1<<10; + +unsigned char Array[N][N]; + +struct Striker { + // Note: we use <int> here instead of <long> in order to test for problems similar to Quad 407676 + void operator()( const tbb::blocked_range2d<int>& r ) const { + for( tbb::blocked_range<int>::const_iterator i=r.rows().begin(); i!=r.rows().end(); ++i ) + for( tbb::blocked_range<int>::const_iterator j=r.cols().begin(); j!=r.cols().end(); ++j ) + ++Array[i][j]; + } +}; + +void ParallelTest() { + for( int i=0; i<N; i=i<3 ? i+1 : i*3 ) { + for( int j=0; j<N; j=j<3 ? j+1 : j*3 ) { + const tbb::blocked_range2d<int> r( 0, i, 7, 0, j, 5 ); + tbb::parallel_for( r, Striker() ); + for( int k=0; k<N; ++k ) { + for( int l=0; l<N; ++l ) { + ASSERT( Array[k][l]==(k<i && l<j), NULL ); + Array[k][l] = 0; + } + } + } + } +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +#include <vector> +void TestDeductionGuides() { + std::vector<const unsigned long *> v; + std::vector<double> v2; + + // check blocked_range2d(RowValue, RowValue, size_t, ColValue, ColValue, size_t) + tbb::blocked_range2d r1(v.begin(), v.end(), 2, v2.begin(), v2.end(), 2); + static_assert(std::is_same<decltype(r1), tbb::blocked_range2d<decltype(v)::iterator, decltype(v2)::iterator>>::value); + + // check blocked_range2d(blocked_range2d &) + tbb::blocked_range2d r2(r1); + static_assert(std::is_same<decltype(r2), decltype(r1)>::value); + + // check blocked_range2d(blocked_range2d &&) + tbb::blocked_range2d r3(std::move(r1)); + static_assert(std::is_same<decltype(r3), decltype(r1)>::value); +} +#endif + +#include "tbb/task_scheduler_init.h" + +int TestMain () { + SerialTest(); + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + ParallelTest(); + } + + #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides(); + #endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range3d.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range3d.cpp new file mode 100644 index 00000000..bfbd4875 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_range3d.cpp @@ -0,0 +1,201 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/blocked_range3d.h" +#include "harness_assert.h" + +// First test as much as we can without including other headers. +// Doing so should catch problems arising from failing to include headers. + +template<typename Tag> +class AbstractValueType { + AbstractValueType() {} + int value; +public: + template<typename OtherTag> + friend AbstractValueType<OtherTag> MakeAbstractValueType( int i ); + + template<typename OtherTag> + friend int GetValueOf( const AbstractValueType<OtherTag>& v ) ; +}; + +template<typename Tag> +AbstractValueType<Tag> MakeAbstractValueType( int i ) { + AbstractValueType<Tag> x; + x.value = i; + return x; +} + +template<typename Tag> +int GetValueOf( const AbstractValueType<Tag>& v ) {return v.value;} + +template<typename Tag> +bool operator<( const AbstractValueType<Tag>& u, const AbstractValueType<Tag>& v ) { + return GetValueOf(u)<GetValueOf(v); +} + +template<typename Tag> +std::size_t operator-( const AbstractValueType<Tag>& u, const AbstractValueType<Tag>& v ) { + return GetValueOf(u)-GetValueOf(v); +} + +template<typename Tag> +AbstractValueType<Tag> operator+( const AbstractValueType<Tag>& u, std::size_t offset ) { + return MakeAbstractValueType<Tag>(GetValueOf(u)+int(offset)); +} + +struct PageTag {}; +struct RowTag {}; +struct ColTag {}; + +static void SerialTest() { + typedef AbstractValueType<PageTag> page_type; + typedef AbstractValueType<RowTag> row_type; + typedef AbstractValueType<ColTag> col_type; + typedef tbb::blocked_range3d<page_type,row_type,col_type> range_type; + for( int page_x=-4; page_x<4; ++page_x ) { + for( int page_y=page_x; page_y<4; ++page_y ) { + page_type page_i = MakeAbstractValueType<PageTag>(page_x); + page_type page_j = MakeAbstractValueType<PageTag>(page_y); + for( int page_grain=1; page_grain<4; ++page_grain ) { + for( int row_x=-4; row_x<4; ++row_x ) { + for( int row_y=row_x; row_y<4; ++row_y ) { + row_type row_i = MakeAbstractValueType<RowTag>(row_x); + row_type row_j = MakeAbstractValueType<RowTag>(row_y); + for( int row_grain=1; row_grain<4; ++row_grain ) { + for( int col_x=-4; col_x<4; ++col_x ) { + for( int col_y=col_x; col_y<4; ++col_y ) { + col_type col_i = MakeAbstractValueType<ColTag>(col_x); + col_type col_j = MakeAbstractValueType<ColTag>(col_y); + for( int col_grain=1; col_grain<4; ++col_grain ) { + range_type r( page_i, page_j, page_grain, row_i, row_j, row_grain, col_i, col_j, col_grain ); + AssertSameType( r.is_divisible(), true ); + + AssertSameType( r.empty(), true ); + + AssertSameType( static_cast<range_type::page_range_type::const_iterator*>(0), static_cast<page_type*>(0) ); + AssertSameType( static_cast<range_type::row_range_type::const_iterator*>(0), static_cast<row_type*>(0) ); + AssertSameType( static_cast<range_type::col_range_type::const_iterator*>(0), static_cast<col_type*>(0) ); + + AssertSameType( r.pages(), tbb::blocked_range<page_type>( page_i, page_j, 1 )); + AssertSameType( r.rows(), tbb::blocked_range<row_type>( row_i, row_j, 1 )); + AssertSameType( r.cols(), tbb::blocked_range<col_type>( col_i, col_j, 1 )); + + ASSERT( r.empty()==(page_x==page_y||row_x==row_y||col_x==col_y), NULL ); + + ASSERT( r.is_divisible()==(page_y-page_x>page_grain||row_y-row_x>row_grain||col_y-col_x>col_grain), NULL ); + + if( r.is_divisible() ) { + range_type r2(r,tbb::split()); + if( (GetValueOf(r2.pages().begin())==GetValueOf(r.pages().begin())) && (GetValueOf(r2.rows().begin())==GetValueOf(r.rows().begin())) ) { + ASSERT( GetValueOf(r2.pages().end())==GetValueOf(r.pages().end()), NULL ); + ASSERT( GetValueOf(r2.rows().end())==GetValueOf(r.rows().end()), NULL ); + ASSERT( GetValueOf(r2.cols().begin())==GetValueOf(r.cols().end()), NULL ); + } else { + if ( (GetValueOf(r2.pages().begin())==GetValueOf(r.pages().begin())) && (GetValueOf(r2.cols().begin())==GetValueOf(r.cols().begin())) ) { + ASSERT( GetValueOf(r2.pages().end())==GetValueOf(r.pages().end()), NULL ); + ASSERT( GetValueOf(r2.cols().end())==GetValueOf(r.cols().end()), NULL ); + ASSERT( GetValueOf(r2.rows().begin())==GetValueOf(r.rows().end()), NULL ); + } else { + ASSERT( GetValueOf(r2.rows().end())==GetValueOf(r.rows().end()), NULL ); + ASSERT( GetValueOf(r2.cols().end())==GetValueOf(r.cols().end()), NULL ); + ASSERT( GetValueOf(r2.pages().begin())==GetValueOf(r.pages().end()), NULL ); + } + } + } + } + } + } + } + } + } + } + } + } +} + +#include "tbb/parallel_for.h" +#include "harness.h" + +const int N = 1<<5; + +unsigned char Array[N][N][N]; + +struct Striker { + // Note: we use <int> here instead of <long> in order to test for problems similar to Quad 407676 + void operator()( const tbb::blocked_range3d<int>& r ) const { + for( tbb::blocked_range<int>::const_iterator i=r.pages().begin(); i!=r.pages().end(); ++i ) + for( tbb::blocked_range<int>::const_iterator j=r.rows().begin(); j!=r.rows().end(); ++j ) + for( tbb::blocked_range<int>::const_iterator k=r.cols().begin(); k!=r.cols().end(); ++k ) + ++Array[i][j][k]; + } +}; + +void ParallelTest() { + for( int i=0; i<N; i=i<3 ? i+1 : i*3 ) { + for( int j=0; j<N; j=j<3 ? j+1 : j*3 ) { + for( int k=0; k<N; k=k<3 ? k+1 : k*3 ) { + const tbb::blocked_range3d<int> r( 0, i, 5, 0, j, 3, 0, k, 1 ); + tbb::parallel_for( r, Striker() ); + for( int l=0; l<N; ++l ) { + for( int m=0; m<N; ++m ) { + for( int n=0; n<N; ++n ) { + ASSERT( Array[l][m][n]==(l<i && m<j && n<k), NULL ); + Array[l][m][n] = 0; + } + } + } + } + } + } +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +#include <vector> +void TestDeductionGuides() { + std::vector<const unsigned long *> v; + std::vector<double> v2; + std::vector<std::vector<int>> v3; + + // check blocked_range2d(PageValue, PageValue, size_t, RowValue, RowValue, size_t, ColValue, ColValue, size_t) + tbb::blocked_range3d r1(v.begin(), v.end(), 2, v2.begin(), v2.end(), 2, v3.begin(), v3.end(), 6); + static_assert(std::is_same<decltype(r1), + tbb::blocked_range3d<decltype(v)::iterator, decltype(v2)::iterator, decltype(v3)::iterator>>::value); + + // check blocked_range2d(blocked_range3d &) + tbb::blocked_range3d r2(r1); + static_assert(std::is_same<decltype(r2), decltype(r1)>::value); + + // check blocked_range2d(blocked_range3d &&) + tbb::blocked_range3d r3(std::move(r1)); + static_assert(std::is_same<decltype(r2), decltype(r1)>::value); +} +#endif + +#include "tbb/task_scheduler_init.h" + +int TestMain () { + SerialTest(); + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + ParallelTest(); + } + + #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides(); + #endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_rangeNd.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_rangeNd.cpp new file mode 100644 index 00000000..17dac527 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_blocked_rangeNd.cpp @@ -0,0 +1,255 @@ +/* + Copyright (c) 2017-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_PREVIEW_BLOCKED_RANGE_ND 1 +#include "tbb/blocked_rangeNd.h" + +#include "tbb/tbb_config.h" + +#if __TBB_CPP11_PRESENT && __TBB_CPP11_ARRAY_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT +// AbstractValueType class represents Value concept's requirements in the most abstract way +class AbstractValueType { + int value; + AbstractValueType() {} +public: + friend AbstractValueType MakeAbstractValue(int i); + friend int GetValueOf(const AbstractValueType& v); +}; + +int GetValueOf(const AbstractValueType& v) { return v.value; } + +AbstractValueType MakeAbstractValue(int i) { + AbstractValueType x; + x.value = i; + return x; +} + +// operator- returns amount of elements of AbstractValueType between u and v +std::size_t operator-(const AbstractValueType& u, const AbstractValueType& v) { + return GetValueOf(u) - GetValueOf(v); +} + +bool operator<(const AbstractValueType& u, const AbstractValueType& v) { + return GetValueOf(u) < GetValueOf(v); +} + +AbstractValueType operator+(const AbstractValueType& u, std::size_t offset) { + return MakeAbstractValue(GetValueOf(u) + int(offset)); +} + +#include "harness_assert.h" +#include <algorithm> // std::for_each +#include <array> + +namespace internal { + template<typename range_t, unsigned int N> + struct utils { + using val_t = typename range_t::value_type; + + template<typename EntityType, std::size_t DimSize> + using data_type = std::array<typename utils<range_t, N - 1>::template data_type<EntityType, DimSize>, DimSize>; + + template<typename EntityType, std::size_t DimSize> + static void init_data(data_type<EntityType, DimSize>& data) { + std::for_each(data.begin(), data.end(), utils<range_t, N - 1>::template init_data<EntityType, DimSize>); + } + + template<typename EntityType, std::size_t DimSize> + static void increment_data(const range_t& range, data_type<EntityType, DimSize>& data) { + auto begin = data.begin() + range.dim(N - 1).begin(); + // same as "auto end = out.begin() + range.dim(N - 1).end();" + auto end = begin + range.dim(N - 1).size(); + for (auto i = begin; i != end; ++i) { + utils<range_t, N - 1>::template increment_data<EntityType, DimSize>(range, *i); + } + } + + template<typename EntityType, std::size_t DimSize> + static void check_data(const range_t& range, data_type<EntityType, DimSize>& data) { + auto begin = data.begin() + range.dim(N - 1).begin(); + // same as "auto end = out.begin() + range.dim(N - 1).end();" + auto end = begin + range.dim(N - 1).size(); + for (auto i = begin; i != end; ++i) { + utils<range_t, N - 1>::template check_data<EntityType, DimSize>(range, *i); + } + } + + template<typename input_t, std::size_t... Is> + static range_t make_range(std::size_t shift, bool negative, val_t(*gen)(input_t), tbb::internal::index_sequence<Is...>) { + return range_t( { { + /* begin =*/gen(negative ? -input_t(Is + shift) : 0), + /* end =*/gen(input_t(Is + shift)), + /*grainsize =*/Is + 1} + /*pack expansion*/... } ); + } + + static bool is_empty(const range_t& range) { + if (range.dim(N - 1).empty()) { return true; } + return utils<range_t, N - 1>::is_empty(range); + } + + static bool is_divisible(const range_t& range) { + if (range.dim(N - 1).is_divisible()) { return true; } + return utils<range_t, N - 1>::is_divisible(range); + } + + static void check_splitting(const range_t& range_split, const range_t& range_new, int(*get)(const val_t&), bool split_checker = false) { + if (get(range_split.dim(N - 1).begin()) == get(range_new.dim(N - 1).begin())) { + ASSERT(get(range_split.dim(N - 1).end()) == get(range_new.dim(N - 1).end()), NULL); + } + else { + ASSERT(get(range_split.dim(N - 1).end()) == get(range_new.dim(N - 1).begin()) && !split_checker, NULL); + split_checker = true; + } + utils<range_t, N - 1>::check_splitting(range_split, range_new, get, split_checker); + } + + }; + + template<typename range_t> + struct utils<range_t, 0> { + using val_t = typename range_t::value_type; + + template<typename EntityType, std::size_t DimSize> + using data_type = EntityType; + + template<typename EntityType, std::size_t DimSize> + static void init_data(data_type<EntityType, DimSize>& data) { data = 0; } + + template<typename EntityType, std::size_t DimSize> + static void increment_data(const range_t&, data_type<EntityType, DimSize>& data) { ++data; } + + template<typename EntityType, std::size_t DimSize> + static void check_data(const range_t&, data_type<EntityType, DimSize>& data) { + ASSERT(data == 1, NULL); + } + + static bool is_empty(const range_t&) { return false; } + + static bool is_divisible(const range_t&) { return false; } + + static void check_splitting(const range_t&, const range_t&, int(*)(const val_t&), bool) {} + }; + + // We need MakeInt function to pass it into make_range as factory function + // because of matching make_range with AbstractValueType and other types too + int MakeInt(int i) { return i; } +} + +template<unsigned int DimAmount> +void SerialTest() { + __TBB_STATIC_ASSERT((tbb::blocked_rangeNd<int, DimAmount>::ndims() + == tbb::blocked_rangeNd<AbstractValueType, DimAmount>::ndims()), + "different amount of dimensions"); + + using range_t = tbb::blocked_rangeNd<AbstractValueType, DimAmount>; + // 'typedef' instead of 'using' because of GCC 4.7.2 bug on Debian 7.0 + typedef internal::utils<range_t, DimAmount> utils; + + // Generate empty range + range_t r = utils::make_range(0, true, &MakeAbstractValue, tbb::internal::make_index_sequence<DimAmount>()); + + AssertSameType(r.is_divisible(), bool()); + AssertSameType(r.empty(), bool()); + AssertSameType(range_t::ndims(), 0U); + + ASSERT(r.empty() == utils::is_empty(r) && r.empty(), NULL); + ASSERT(r.is_divisible() == utils::is_divisible(r), NULL); + + // Generate not-empty range divisible range + r = utils::make_range(1, true, &MakeAbstractValue, tbb::internal::make_index_sequence<DimAmount>()); + ASSERT(r.empty() == utils::is_empty(r) && !r.empty(), NULL); + ASSERT(r.is_divisible() == utils::is_divisible(r) && r.is_divisible(), NULL); + + range_t r_new(r, tbb::split()); + utils::check_splitting(r, r_new, &GetValueOf); + + SerialTest<DimAmount - 1>(); +} +template<> void SerialTest<0>() {} + +#include "tbb/parallel_for.h" + +template<unsigned int DimAmount> +void ParallelTest() { + using range_t = tbb::blocked_rangeNd<int, DimAmount>; + // 'typedef' instead of 'using' because of GCC 4.7.2 bug on Debian 7.0 + typedef internal::utils<range_t, DimAmount> utils; + + // Max size is 1 << 20 - 1 bytes + // Thus size of one dimension's elements is 1 << (20 / DimAmount - 1) bytes + typename utils::template data_type<unsigned char, 1 << (20 / DimAmount - 1)> data; + utils::init_data(data); + + range_t r = utils::make_range((1 << (20 / DimAmount - 1)) - DimAmount, false, &internal::MakeInt, tbb::internal::make_index_sequence<DimAmount>()); + + tbb::parallel_for(r, [&data](const range_t& range) { + utils::increment_data(range, data); + }); + + utils::check_data(r, data); + + ParallelTest<DimAmount - 1>(); +} +template<> void ParallelTest<0>() {} + +void TestCtors() { + tbb::blocked_rangeNd<int, 1>{ { 0,13,3 } }; + + tbb::blocked_rangeNd<int, 1>{ tbb::blocked_range<int>{ 0,13,3 } }; + + tbb::blocked_rangeNd<int, 2>(tbb::blocked_range<int>(-8923, 8884, 13), tbb::blocked_range<int>(-8923, 5, 13)); + + tbb::blocked_rangeNd<int, 2>({ -8923, 8884, 13 }, { -8923, 8884, 13 }); + + tbb::blocked_range<int> r1(0, 13); + + tbb::blocked_range<int> r2(-12, 23); + + tbb::blocked_rangeNd<int, 2>({ { -8923, 8884, 13 }, r1}); + + tbb::blocked_rangeNd<int, 2>({ r2, r1 }); + + tbb::blocked_rangeNd<int, 2>(r1, r2); + + tbb::blocked_rangeNd<AbstractValueType, 4>({ MakeAbstractValue(-3), MakeAbstractValue(13), 8 }, + { MakeAbstractValue(-53), MakeAbstractValue(23), 2 }, + { MakeAbstractValue(-23), MakeAbstractValue(33), 1 }, + { MakeAbstractValue(-13), MakeAbstractValue(43), 7 }); +} + +static const std::size_t N = 4; + +#include "harness.h" +#include "tbb/task_scheduler_init.h" + +int TestMain() { + TestCtors(); + SerialTest<N>(); + for( int p=MinThread; p<= MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + ParallelTest<N>(); + } + return Harness::Done; +} + +#else + +// tbb::blocked_rangeNd requires C++11 support +#define HARNESS_SKIP_TEST 1 +#include "harness.h" + +#endif /* __TBB_CPP11_PRESENT && __TBB_CPP11_ARRAY_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_broadcast_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_broadcast_node.cpp new file mode 100644 index 00000000..3104f99e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_broadcast_node.cpp @@ -0,0 +1,385 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#endif + +#include "harness.h" + +#include "tbb/flow_graph.h" +#include "tbb/task.h" +#include "tbb/atomic.h" +#include "test_follows_and_precedes_api.h" + +const int N = 1000; +const int R = 4; + +class int_convertable_type : private NoAssign { + + int my_value; + +public: + + int_convertable_type( int v ) : my_value(v) {} + operator int() const { return my_value; } + +}; + + +template< typename T > +class counting_array_receiver : public tbb::flow::receiver<T> { + + tbb::atomic<size_t> my_counters[N]; + tbb::flow::graph& my_graph; + +public: + + counting_array_receiver(tbb::flow::graph& g) : my_graph(g) { + for (int i = 0; i < N; ++i ) + my_counters[i] = 0; + } + + size_t operator[]( int i ) { + size_t v = my_counters[i]; + return v; + } + + tbb::task * try_put_task( const T &v ) __TBB_override { + ++my_counters[(int)v]; + return const_cast<tbb::task *>(tbb::flow::internal::SUCCESSFULLY_ENQUEUED); + } + + tbb::flow::graph& graph_reference() const __TBB_override { + return my_graph; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::receiver<T>::built_predecessors_type built_predecessors_type; + built_predecessors_type mbp; + built_predecessors_type &built_predecessors() __TBB_override { return mbp; } + typedef typename tbb::flow::receiver<T>::predecessor_list_type predecessor_list_type; + typedef typename tbb::flow::receiver<T>::predecessor_type predecessor_type; + void internal_add_built_predecessor(predecessor_type &) __TBB_override {} + void internal_delete_built_predecessor(predecessor_type &) __TBB_override {} + void copy_predecessors(predecessor_list_type &) __TBB_override {} + size_t predecessor_count() __TBB_override { return 0; } +#endif + void reset_receiver(tbb::flow::reset_flags /*f*/) __TBB_override { } + +}; + +template< typename T > +void test_serial_broadcasts() { + + tbb::flow::graph g; + tbb::flow::broadcast_node<T> b(g); + + for ( int num_receivers = 1; num_receivers < R; ++num_receivers ) { + std::vector< counting_array_receiver<T> > receivers(num_receivers, counting_array_receiver<T>(g)); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(b.successor_count() == 0, NULL); + ASSERT(b.predecessor_count() == 0, NULL); + typename tbb::flow::broadcast_node<T>::successor_list_type my_succs; + b.copy_successors(my_succs); + ASSERT(my_succs.size() == 0, NULL); + typename tbb::flow::broadcast_node<T>::predecessor_list_type my_preds; + b.copy_predecessors(my_preds); + ASSERT(my_preds.size() == 0, NULL); +#endif + + for ( int r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( b, receivers[r] ); + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT( b.successor_count() == (size_t)num_receivers, NULL); +#endif + + for (int n = 0; n < N; ++n ) { + ASSERT( b.try_put( (T)n ), NULL ); + } + + for ( int r = 0; r < num_receivers; ++r ) { + for (int n = 0; n < N; ++n ) { + ASSERT( receivers[r][n] == 1, NULL ); + } + tbb::flow::remove_edge( b, receivers[r] ); + } + ASSERT( b.try_put( (T)0 ), NULL ); + for ( int r = 0; r < num_receivers; ++r ) + ASSERT( receivers[0][0] == 1, NULL ); + } + +} + +template< typename T > +class native_body : private NoAssign { + + tbb::flow::broadcast_node<T> &my_b; + +public: + + native_body( tbb::flow::broadcast_node<T> &b ) : my_b(b) {} + + void operator()(int) const { + for (int n = 0; n < N; ++n ) { + ASSERT( my_b.try_put( (T)n ), NULL ); + } + } + +}; + +template< typename T > +void run_parallel_broadcasts(tbb::flow::graph& g, int p, tbb::flow::broadcast_node<T>& b) { + for ( int num_receivers = 1; num_receivers < R; ++num_receivers ) { + std::vector< counting_array_receiver<T> > receivers(num_receivers, counting_array_receiver<T>(g)); + + for ( int r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( b, receivers[r] ); + } + + NativeParallelFor( p, native_body<T>( b ) ); + + for ( int r = 0; r < num_receivers; ++r ) { + for (int n = 0; n < N; ++n ) { + ASSERT( (int)receivers[r][n] == p, NULL ); + } + tbb::flow::remove_edge( b, receivers[r] ); + } + ASSERT( b.try_put( (T)0 ), NULL ); + for ( int r = 0; r < num_receivers; ++r ) + ASSERT( (int)receivers[r][0] == p, NULL ); + } +} + +template< typename T > +void test_parallel_broadcasts(int p) { + + tbb::flow::graph g; + tbb::flow::broadcast_node<T> b(g); + run_parallel_broadcasts(g, p, b); + + // test copy constructor + tbb::flow::broadcast_node<T> b_copy(b); + run_parallel_broadcasts(g, p, b_copy); +} + +// broadcast_node does not allow successors to try_get from it (it does not allow +// the flow edge to switch) so we only need test the forward direction. +template<typename T> +void test_resets() { + tbb::flow::graph g; + tbb::flow::broadcast_node<T> b0(g); + tbb::flow::broadcast_node<T> b1(g); + tbb::flow::queue_node<T> q0(g); + tbb::flow::make_edge(b0,b1); + tbb::flow::make_edge(b1,q0); + T j; + + // test standard reset + for(int testNo = 0; testNo < 2; ++testNo) { + for(T i= 0; i <= 3; i += 1) { + b0.try_put(i); + } + g.wait_for_all(); + for(T i= 0; i <= 3; i += 1) { + ASSERT(q0.try_get(j) && j == i, "Bad value in queue"); + } + ASSERT(!q0.try_get(j), "extra value in queue"); + + // reset the graph. It should work as before. + if (testNo == 0) g.reset(); + } + + g.reset(tbb::flow::rf_clear_edges); + for(T i= 0; i <= 3; i += 1) { + b0.try_put(i); + } + g.wait_for_all(); + ASSERT(!q0.try_get(j), "edge between nodes not removed"); + for(T i= 0; i <= 3; i += 1) { + b1.try_put(i); + } + g.wait_for_all(); + ASSERT(!q0.try_get(j), "edge between nodes not removed"); +} + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +void test_extract() { + int dont_care; + tbb::flow::graph g; + tbb::flow::broadcast_node<int> b0(g); + tbb::flow::broadcast_node<int> b1(g); + tbb::flow::broadcast_node<int> b2(g); + tbb::flow::broadcast_node<int> b3(g); + tbb::flow::broadcast_node<int> b4(g); + tbb::flow::broadcast_node<int> b5(g); + tbb::flow::queue_node<int> q0(g); + tbb::flow::make_edge(b0,b1); + tbb::flow::make_edge(b0,b2); + tbb::flow::make_edge(b1,b3); + tbb::flow::make_edge(b1,b4); + tbb::flow::make_edge(b2,b4); + tbb::flow::make_edge(b2,b5); + tbb::flow::make_edge(b3,q0); + tbb::flow::make_edge(b4,q0); + tbb::flow::make_edge(b5,q0); + + /* b3 */ + /* / \ */ + /* b1 \ */ + /* / \ \ */ + /* b0 b4---q0 */ + /* \ / / */ + /* b2 / */ + /* \ / */ + /* b5 */ + + g.wait_for_all(); + b0.try_put(1); + g.wait_for_all(); + for( int i = 0; i < 4; ++i ) { + int j; + ASSERT(q0.try_get(j) && j == 1, "missing or incorrect message"); + } + ASSERT(!q0.try_get(dont_care), "extra message in queue"); + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 2, "improper count for b0"); + ASSERT(b1.predecessor_count() == 1 && b1.successor_count() == 2, "improper count for b1"); + ASSERT(b2.predecessor_count() == 1 && b2.successor_count() == 2, "improper count for b2"); + ASSERT(b3.predecessor_count() == 1 && b3.successor_count() == 1, "improper count for b3"); + ASSERT(b4.predecessor_count() == 2 && b4.successor_count() == 1, "improper count before extract of b4"); + ASSERT(b5.predecessor_count() == 1 && b5.successor_count() == 1, "improper count for b5"); + b4.extract(); // remove from tree of nodes. + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 2, "improper count for b0 after"); + ASSERT(b1.predecessor_count() == 1 && b1.successor_count() == 1, "improper succ count for b1 after"); + ASSERT(b2.predecessor_count() == 1 && b2.successor_count() == 1, "improper succ count for b2 after"); + ASSERT(b3.predecessor_count() == 1 && b3.successor_count() == 1, "improper succ count for b3 after"); + ASSERT(b4.predecessor_count() == 0 && b4.successor_count() == 0, "improper succ count after extract"); + ASSERT(b5.predecessor_count() == 1 && b5.successor_count() == 1, "improper succ count for b5 after"); + + /* b3 */ + /* / \ */ + /* b1 \ */ + /* / \ */ + /* b0 q0 */ + /* \ / */ + /* b2 / */ + /* \ / */ + /* b5 */ + + b0.try_put(1); + g.wait_for_all(); + for( int i = 0; i < 2; ++i ) { + int j; + ASSERT(q0.try_get(j) && j == 1, "missing or incorrect message"); + } + ASSERT(!q0.try_get(dont_care), "extra message in queue"); + tbb::flow::make_edge(b0,b4); + tbb::flow::make_edge(b4,q0); + g.wait_for_all(); + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 3, "improper count for b0 after"); + ASSERT(b1.predecessor_count() == 1 && b1.successor_count() == 1, "improper succ count for b1 after"); + ASSERT(b2.predecessor_count() == 1 && b2.successor_count() == 1, "improper succ count for b2 after"); + ASSERT(b3.predecessor_count() == 1 && b3.successor_count() == 1, "improper succ count for b3 after"); + ASSERT(b4.predecessor_count() == 1 && b4.successor_count() == 1, "improper succ count after extract"); + ASSERT(b5.predecessor_count() == 1 && b5.successor_count() == 1, "improper succ count for b5 after"); + + /* b3 */ + /* / \ */ + /* b1 \ */ + /* / \ */ + /* b0---b4---q0 */ + /* \ / */ + /* b2 / */ + /* \ / */ + /* b5 */ + + b0.try_put(1); + g.wait_for_all(); + for( int i = 0; i < 3; ++i ) { + int j; + ASSERT(q0.try_get(j) && j == 1, "missing or incorrect message"); + } + ASSERT(!q0.try_get(dont_care), "extra message in queue"); +} +#endif // TBB_DEPRECATED_FLOW_NODE_EXTRACTION + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + using msg_t = tbb::flow::continue_msg; + + std::array<msg_t, 3> messages_for_follows= { {msg_t(), msg_t(), msg_t()} }; + std::vector<msg_t> messages_for_precedes = {msg_t()}; + + follows_and_precedes_testing::test_follows <msg_t, tbb::flow::broadcast_node<msg_t>>(messages_for_follows); + follows_and_precedes_testing::test_precedes <msg_t, tbb::flow::broadcast_node<msg_t>>(messages_for_precedes); +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + + graph g; + + broadcast_node<int> b0(g); +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + buffer_node<int> buf(g); + + broadcast_node b1(follows(buf)); + static_assert(std::is_same_v<decltype(b1), broadcast_node<int>>); + + broadcast_node b2(precedes(buf)); + static_assert(std::is_same_v<decltype(b2), broadcast_node<int>>); +#endif + + broadcast_node b3(b0); + static_assert(std::is_same_v<decltype(b3), broadcast_node<int>>); + g.wait_for_all(); +} +#endif + +int TestMain() { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + + test_serial_broadcasts<int>(); + test_serial_broadcasts<float>(); + test_serial_broadcasts<int_convertable_type>(); + + for( int p=MinThread; p<=MaxThread; ++p ) { + test_parallel_broadcasts<int>(p); + test_parallel_broadcasts<float>(p); + test_parallel_broadcasts<int_convertable_type>(p); + } + + test_resets<int>(); + test_resets<float>(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract(); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_buffer_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_buffer_node.cpp new file mode 100644 index 00000000..0f236bf3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_buffer_node.cpp @@ -0,0 +1,492 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_ALLOCATOR __TBB_CPF_BUILD + +#include "harness.h" +#include "harness_graph.h" + +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" +#include "test_follows_and_precedes_api.h" + +#define N 1000 +#define C 10 + +template< typename T > +void spin_try_get( tbb::flow::buffer_node<T> &b, T &value ) { + while ( b.try_get(value) != true ) {} +} + +template< typename T > +void check_item( T* count_value, T &value ) { + count_value[value / N] += value % N; +} + +template< typename T > +struct parallel_puts : NoAssign { + + tbb::flow::buffer_node<T> &my_b; + + parallel_puts( tbb::flow::buffer_node<T> &b ) : my_b(b) {} + + void operator()(int i) const { + for (int j = 0; j < N; ++j) { + bool msg = my_b.try_put( T(N*i + j) ); + ASSERT( msg == true, NULL ); + } + } +}; + +template< typename T > +struct touches { + + bool **my_touches; + int my_num_threads; + + touches( int num_threads ) : my_num_threads(num_threads) { + my_touches = new bool* [my_num_threads]; + for ( int p = 0; p < my_num_threads; ++p) { + my_touches[p] = new bool[N]; + for ( int n = 0; n < N; ++n) + my_touches[p][n] = false; + } + } + + ~touches() { + for ( int p = 0; p < my_num_threads; ++p) { + delete [] my_touches[p]; + } + delete [] my_touches; + } + + bool check( T v ) { + ASSERT ( my_touches[v/N][v%N] == false, NULL); + my_touches[v/N][v%N] = true; + return true; + } + + bool validate_touches() { + for ( int p = 0; p < my_num_threads; ++p) { + for ( int n = 0; n < N; ++n) { + ASSERT ( my_touches[p][n] == true, NULL); + } + } + return true; + } +}; + +template< typename T > +struct parallel_gets : NoAssign { + + tbb::flow::buffer_node<T> &my_b; + touches<T> &my_touches; + + parallel_gets( tbb::flow::buffer_node<T> &b, touches<T> &t) : my_b(b), my_touches(t) {} + + void operator()(int) const { + for (int j = 0; j < N; ++j) { + T v; + spin_try_get( my_b, v ); + my_touches.check( v ); + } + } + +}; + +template< typename T > +struct parallel_put_get : NoAssign { + + tbb::flow::buffer_node<T> &my_b; + touches<T> &my_touches; + + parallel_put_get( tbb::flow::buffer_node<T> &b, touches<T> &t ) : my_b(b), my_touches(t) {} + + void operator()(int tid) const { + + for ( int i = 0; i < N; i+=C ) { + int j_end = ( N < i + C ) ? N : i + C; + // dump about C values into the buffer + for ( int j = i; j < j_end; ++j ) { + ASSERT( my_b.try_put( T (N*tid + j ) ) == true, NULL ); + } + // receiver about C values from the buffer + for ( int j = i; j < j_end; ++j ) { + T v; + spin_try_get( my_b, v ); + my_touches.check( v ); + } + } + } + +}; + +// +// Tests +// +// Item can be reserved, released, consumed ( single serial receiver ) +// +template< typename T > +int test_reservation() { + tbb::flow::graph g; + T bogus_value(-1); + + // Simple tests + tbb::flow::buffer_node<T> b(g); + + b.try_put(T(1)); + b.try_put(T(2)); + b.try_put(T(3)); + + T v, vsum; + ASSERT( b.try_reserve(v) == true, NULL ); + ASSERT( b.try_release() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + ASSERT( b.try_reserve(v) == true, NULL ); + ASSERT( b.try_consume() == true, NULL ); + vsum += v; + v = bogus_value; + g.wait_for_all(); + + ASSERT( b.try_get(v) == true, NULL ); + vsum += v; + v = bogus_value; + g.wait_for_all(); + + ASSERT( b.try_reserve(v) == true, NULL ); + ASSERT( b.try_release() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + ASSERT( b.try_reserve(v) == true, NULL ); + ASSERT( b.try_consume() == true, NULL ); + vsum += v; + ASSERT( vsum == T(6), NULL); + v = bogus_value; + g.wait_for_all(); + + return 0; +} + +// +// Tests +// +// multiple parallel senders, items in arbitrary order +// multiple parallel senders, multiple parallel receivers, items in arbitrary order and all items received +// * overlapped puts / gets +// * all puts finished before any getS +// +template< typename T > +int test_parallel(int num_threads) { + tbb::flow::graph g; + tbb::flow::buffer_node<T> b(g); + tbb::flow::buffer_node<T> b2(g); + tbb::flow::buffer_node<T> b3(g); + T bogus_value(-1); + T j = bogus_value; + + NativeParallelFor( num_threads, parallel_puts<T>(b) ); + + T *next_value = new T[num_threads]; + for (int tid = 0; tid < num_threads; ++tid) next_value[tid] = T(0); + + for (int i = 0; i < num_threads * N; ++i ) { + spin_try_get( b, j ); + check_item( next_value, j ); + j = bogus_value; + } + for (int tid = 0; tid < num_threads; ++tid) { + ASSERT( next_value[tid] == T((N*(N-1))/2), NULL ); + } + + j = bogus_value; + g.wait_for_all(); + ASSERT( b.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + NativeParallelFor( num_threads, parallel_puts<T>(b) ); + + { + touches< T > t( num_threads ); + NativeParallelFor( num_threads, parallel_gets<T>(b, t) ); + g.wait_for_all(); + ASSERT( t.validate_touches(), NULL ); + } + j = bogus_value; + ASSERT( b.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + g.wait_for_all(); + { + touches< T > t( num_threads ); + NativeParallelFor( num_threads, parallel_put_get<T>(b, t) ); + g.wait_for_all(); + ASSERT( t.validate_touches(), NULL ); + } + j = bogus_value; + ASSERT( b.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::make_edge( b, b2 ); + tbb::flow::make_edge( b2, b3 ); + + NativeParallelFor( num_threads, parallel_puts<T>(b) ); + { + touches< T > t( num_threads ); + NativeParallelFor( num_threads, parallel_gets<T>(b3, t) ); + g.wait_for_all(); + ASSERT( t.validate_touches(), NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( b.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( b2.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( b3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // test copy constructor + ASSERT( b.remove_successor( b2 ), NULL ); + // fill up b: + NativeParallelFor( num_threads, parallel_puts<T>(b) ); + // copy b: + tbb::flow::buffer_node<T> b_copy(b); + + // b_copy should be empty + j = bogus_value; + g.wait_for_all(); + ASSERT( b_copy.try_get( j ) == false, NULL ); + + // hook them together: + ASSERT( b.register_successor(b_copy) == true, NULL ); + // try to get content from b_copy + { + touches< T > t( num_threads ); + NativeParallelFor( num_threads, parallel_gets<T>(b_copy, t) ); + g.wait_for_all(); + ASSERT( t.validate_touches(), NULL ); + } + // now both should be empty + j = bogus_value; + g.wait_for_all(); + ASSERT( b.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( b_copy.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + delete [] next_value; + return 0; +} + +// +// Tests +// +// Predecessors cannot be registered +// Empty buffer rejects item requests +// Single serial sender, items in arbitrary order +// Chained buffers ( 2 & 3 ), single sender, items at last buffer in arbitrary order +// + +template< typename T > +int test_serial() { + tbb::flow::graph g; + T bogus_value(-1); + + tbb::flow::buffer_node<T> b(g); + tbb::flow::buffer_node<T> b2(g); + T j = bogus_value; + + // + // Rejects attempts to add / remove predecessor + // Rejects request from empty buffer + // + ASSERT( b.register_predecessor( b2 ) == false, NULL ); + ASSERT( b.remove_predecessor( b2 ) == false, NULL ); + ASSERT( b.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // + // Simple puts and gets + // + + for (int i = 0; i < N; ++i) { + bool msg = b.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + T vsum = T(0); + for (int i = 0; i < N; ++i) { + j = bogus_value; + spin_try_get( b, j ); + vsum += j; + } + ASSERT( vsum == (N*(N-1))/2, NULL); + j = bogus_value; + g.wait_for_all(); + ASSERT( b.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::make_edge(b, b2); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT( b.successor_count() == 1, NULL); + ASSERT( b.predecessor_count() == 0, NULL); + ASSERT( b2.successor_count() == 0, NULL); + ASSERT( b2.predecessor_count() == 1, NULL); + typename tbb::flow::buffer_node<T>::successor_list_type my_succs; + b.copy_successors(my_succs); + ASSERT(my_succs.size() == 1, NULL); + typename tbb::flow::buffer_node<T>::predecessor_list_type my_preds; + b.copy_predecessors(my_preds); + ASSERT(my_preds.size() == 0, NULL); +#endif + + vsum = T(0); + for (int i = 0; i < N; ++i) { + bool msg = b.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + for (int i = 0; i < N; ++i) { + j = bogus_value; + spin_try_get( b2, j ); + vsum += j; + } + ASSERT( vsum == (N*(N-1))/2, NULL); + j = bogus_value; + g.wait_for_all(); + ASSERT( b.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( b2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::remove_edge(b, b2); + ASSERT( b.try_put( 1 ) == true, NULL ); + g.wait_for_all(); + ASSERT( b2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( b.try_get( j ) == true, NULL ); + ASSERT( j == 1, NULL ); + + tbb::flow::buffer_node<T> b3(g); + tbb::flow::make_edge( b, b2 ); + tbb::flow::make_edge( b2, b3 ); + + vsum = T(0); + for (int i = 0; i < N; ++i) { + bool msg = b.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + for (int i = 0; i < N; ++i) { + j = bogus_value; + spin_try_get( b3, j ); + vsum += j; + } + ASSERT( vsum == (N*(N-1))/2, NULL); + j = bogus_value; + g.wait_for_all(); + ASSERT( b.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( b2.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( b3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::remove_edge(b, b2); + ASSERT( b.try_put( 1 ) == true, NULL ); + g.wait_for_all(); + ASSERT( b2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( b3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( b.try_get( j ) == true, NULL ); + ASSERT( j == 1, NULL ); + + return 0; +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follow_and_precedes_api() { + using msg_t = tbb::flow::continue_msg; + + std::array<msg_t, 3> messages_for_follows = { {msg_t(), msg_t(), msg_t()} }; + std::vector<msg_t> messages_for_precedes = {msg_t(), msg_t(), msg_t()}; + + follows_and_precedes_testing::test_follows<msg_t, tbb::flow::buffer_node<msg_t>>(messages_for_follows); + follows_and_precedes_testing::test_precedes<msg_t, tbb::flow::buffer_node<msg_t>>(messages_for_precedes); +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + graph g; + broadcast_node<int> br(g); + buffer_node<int> b0(g); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + buffer_node b1(follows(br)); + static_assert(std::is_same_v<decltype(b1), buffer_node<int>>); + + buffer_node b2(precedes(br)); + static_assert(std::is_same_v<decltype(b2), buffer_node<int>>); +#endif + + buffer_node b3(b0); + static_assert(std::is_same_v<decltype(b3), buffer_node<int>>); + g.wait_for_all(); +} +#endif + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +void test_node_allocator() { + tbb::flow::graph g; + tbb::flow::buffer_node< int, std::allocator<int> > tmp(g); +} +#endif + +int TestMain() { + tbb::tick_count start = tbb::tick_count::now(), stop; + for (int p = 2; p <= 4; ++p) { + tbb::task_scheduler_init init(p); + test_serial<int>(); + test_parallel<int>(p); + } + stop = tbb::tick_count::now(); + REMARK("Buffer_Node Time=%6.6f\n", (stop-start).seconds()); + test_resets<int,tbb::flow::buffer_node<int> >(); + test_resets<float,tbb::flow::buffer_node<float> >(); +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follow_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_buffer_extract<tbb::flow::buffer_node<int> >().run_tests(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + test_node_allocator(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cache_aligned_allocator.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cache_aligned_allocator.cpp new file mode 100644 index 00000000..eadf9834 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cache_aligned_allocator.cpp @@ -0,0 +1,76 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Test whether cache_aligned_allocator works with some of the host's STL containers. + +#include "tbb/cache_aligned_allocator.h" +#include "tbb/tbb_allocator.h" + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +// the real body of the test is there: +#include "test_allocator.h" + +template<> +struct is_zero_filling<tbb::zero_allocator<void> > { + static const bool value = true; +}; + +// Test that NFS_Allocate() throws bad_alloc if cannot allocate memory. +void Test_NFS_Allocate_Throws() { +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + using namespace tbb::internal; + + // First, allocate a reasonably big amount of memory, big enough + // to not cause warp around in system allocator after adding object header + // during address2 allocation. + const size_t itemsize = 1024; + const size_t nitems = 1024; + void *address1 = NULL; + try { + address1 = NFS_Allocate( nitems, itemsize, NULL ); + } catch( ... ) { + // intentionally empty + } + ASSERT( address1, "NFS_Allocate unable to obtain 1024*1024 bytes" ); + + bool exception_caught = false; + try { + // Try allocating more memory than left in the address space; should cause std::bad_alloc + (void) NFS_Allocate( 1, ~size_t(0) - itemsize*nitems + NFS_GetLineSize(), NULL); + } catch( std::bad_alloc& ) { + exception_caught = true; + } catch( ... ) { + ASSERT( __TBB_EXCEPTION_TYPE_INFO_BROKEN, "Unexpected exception type (std::bad_alloc was expected)" ); + exception_caught = true; + } + ASSERT( exception_caught, "NFS_Allocate did not throw bad_alloc" ); + + try { + NFS_Free( address1 ); + } catch( ... ) { + ASSERT( false, "NFS_Free did not accept the address obtained with NFS_Allocate" ); + } +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ +} + +int TestMain () { + int result = TestMain<tbb::cache_aligned_allocator<void> >(); + result += TestMain<tbb::tbb_allocator<void> >(); + result += TestMain<tbb::zero_allocator<void> >(); + ASSERT( !result, NULL ); + Test_NFS_Allocate_Throws(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cache_aligned_allocator_STL.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cache_aligned_allocator_STL.cpp new file mode 100644 index 00000000..7688861a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cache_aligned_allocator_STL.cpp @@ -0,0 +1,42 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Test whether cache_aligned_allocator works with some of the host's STL containers. + +#include "tbb/cache_aligned_allocator.h" +#include "tbb/tbb_allocator.h" + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "test_allocator_STL.h" + +int TestMain () { + TestAllocatorWithSTL<tbb::cache_aligned_allocator<void> >(); + TestAllocatorWithSTL<tbb::tbb_allocator<void> >(); + TestAllocatorWithSTL<tbb::zero_allocator<void> >(); + +#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT + tbb::cache_aligned_resource aligned_resource; + tbb::cache_aligned_resource equal_aligned_resource(std::pmr::get_default_resource()); + ASSERT(aligned_resource.is_equal(equal_aligned_resource), + "Underlying upstream resources should be equal."); + ASSERT(!aligned_resource.is_equal(*std::pmr::null_memory_resource()), + "Cache aligned resource upstream shouldn't be equal to the standard resource."); + TestAllocatorWithSTL(std::pmr::polymorphic_allocator<void>(&aligned_resource)); +#endif + + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_common.h new file mode 100644 index 00000000..523f31a9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_common.h @@ -0,0 +1,79 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// This file is a common part of test_cilk_interop and test_cilk_dynamic_load tests + +int TBB_Fib( int n ); + +class FibCilkSubtask: public tbb::task { + int n; + int& result; + task* execute() __TBB_override { + if( n<2 ) { + result = n; + } else { + int x, y; + x = cilk_spawn TBB_Fib(n-2); + y = cilk_spawn TBB_Fib(n-1); + cilk_sync; + result = x+y; + } + return NULL; + } +public: + FibCilkSubtask( int& result_, int n_ ) : result(result_), n(n_) {} +}; + +class FibTask: public tbb::task { + int n; + int& result; + task* execute() __TBB_override { + if( !g_sandwich && n<2 ) { + result = n; + } else { + int x,y; + tbb::task_scheduler_init init(P_nested); + task* self0 = &task::self(); + set_ref_count( 3 ); + if ( g_sandwich ) { + spawn (*new( allocate_child() ) FibCilkSubtask(x,n-1)); + spawn (*new( allocate_child() ) FibCilkSubtask(y,n-2)); + } + else { + spawn (*new( allocate_child() ) FibTask(x,n-1)); + spawn (*new( allocate_child() ) FibTask(y,n-2)); + } + wait_for_all(); + task* self1 = &task::self(); + ASSERT( self0 == self1, "failed to preserve TBB TLS" ); + result = x+y; + } + return NULL; + } +public: + FibTask( int& result_, int n_ ) : result(result_), n(n_) {} +}; + +int TBB_Fib( int n ) { + if( n<2 ) { + return n; + } else { + int result; + tbb::task_scheduler_init init(P_nested); + tbb::task::spawn_root_and_wait(*new( tbb::task::allocate_root()) FibTask(result,n) ); + return result; + } +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_dynamic_load.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_dynamic_load.cpp new file mode 100644 index 00000000..f51960cd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_dynamic_load.cpp @@ -0,0 +1,152 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +// Skip the test if no interoperability with cilkrts +#define __TBB_CILK_INTEROP (__TBB_SURVIVE_THREAD_SWITCH && __INTEL_COMPILER>=1200) +// Skip the test when cilkrts did not have dlopen()/dlclose() start up feature +#define CILK_SYMBOLS_VISIBLE (_WIN32||_WIN64) +// The compiler does not add "-lcilkrts" linker option on some linux systems +#define CILK_LINKAGE_BROKEN (__linux__ && __GNUC__<4 && __INTEL_COMPILER_BUILD_DATE <= 20110427) +// Currently, the interop doesn't support the situation: +//1) Intel(R) Threading Building Blocks (Intel(R) TBB) is outermost; +//2) Intel(R) Cilk(TM) Plus, and it should be dynamically loaded with dlopen/LoadLibrary (possibly via a 3rd party module); +//3) Intel(R) TBB again; +//4) Intel(R) Cilk(TM) Plus again. +#define HEAVY_NESTED_INTEROP_SUPPORT ( __INTEL_COMPILER_BUILD_DATE < 20110427 ) + +#if __TBB_CILK_INTEROP && CILK_SYMBOLS_VISIBLE && !CILK_LINKAGE_BROKEN && HEAVY_NESTED_INTEROP_SUPPORT + +#include "tbb/task_scheduler_init.h" +#include "tbb/task.h" + +static const int N = 25; +static const int P_outer = 4; +static const int P_nested = 2; + +#ifdef _USRDLL + +#include <cilk/cilk.h> +#define HARNESS_CUSTOM_MAIN 1 +#include "harness.h" +#undef HARNESS_CUSTOM_MAIN + +#if _WIN32 || _WIN64 +#define CILK_TEST_EXPORT extern "C" __declspec(dllexport) +#else +#define CILK_TEST_EXPORT extern "C" +#endif /* _WIN32 || _WIN64 */ + +bool g_sandwich = true; // have to be declare before #include "test_cilk_common.h" +#include "test_cilk_common.h" + +CILK_TEST_EXPORT int CilkFib( int n ) +{ + return TBB_Fib(n); +} + +CILK_TEST_EXPORT void CilkShutdown() +{ + __cilkrts_end_cilk(); +} + +#else /* _USRDLL undefined */ + +#include "harness.h" +#include "harness_dynamic_libs.h" + +int SerialFib( int n ) { + int a=0, b=1; + for( int i=0; i<n; ++i ) { + b += a; + a = b-a; + } + return a; +} + +int F = SerialFib(N); + +typedef int (*CILK_CALL)(int); +CILK_CALL CilkFib = 0; + +typedef void (*CILK_SHUTDOWN)(); +CILK_SHUTDOWN CilkShutdown = 0; + +class FibTask: public tbb::task { + int n; + int& result; + task* execute() __TBB_override { + if( n<2 ) { + result = n; + } else { + + // TODO: why RTLD_LAZY was used here? + Harness::LIBRARY_HANDLE hLib = + Harness::OpenLibrary(TEST_LIBRARY_NAME("test_cilk_dynamic_load_dll")); + CilkFib = (CILK_CALL)Harness::GetAddress(hLib, "CilkFib"); + CilkShutdown = (CILK_SHUTDOWN)Harness::GetAddress(hLib, "CilkShutdown"); + + int x, y; + x = CilkFib(n-2); + y = CilkFib(n-1); + result = x+y; + + CilkShutdown(); + + Harness::CloseLibrary(hLib); + } + return NULL; + } +public: + FibTask( int& result_, int n_ ) : result(result_), n(n_) {} +}; + + +int TBB_Fib( int n ) { + if( n<2 ) { + return n; + } else { + int result; + tbb::task_scheduler_init init(P_nested); + tbb::task::spawn_root_and_wait(*new( tbb::task::allocate_root()) FibTask(result,n) ); + return result; + } +} + +void RunSandwich() { + tbb::task_scheduler_init init(P_outer); + int m = TBB_Fib(N); + ASSERT( m == F, NULL ); +} + +int TestMain () { + for ( int i = 0; i < 20; ++i ) + RunSandwich(); + return Harness::Done; +} + +#endif /* _USRDLL */ + +#else /* !__TBB_CILK_INTEROP */ + +#include "harness.h" + +int TestMain () { + return Harness::Skipped; +} + +#endif /* !__TBB_CILK_INTEROP */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_interop.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_interop.cpp new file mode 100644 index 00000000..7eb24b6c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_cilk_interop.cpp @@ -0,0 +1,151 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" +#include "harness.h" + +// Skip the test if no interoperability with cilkrts +#define __TBB_CILK_INTEROP (__TBB_SURVIVE_THREAD_SWITCH && __INTEL_COMPILER>=1200) +// The compiler does not add "-lcilkrts" linker option on some linux systems +#define CILK_LINKAGE_BROKEN (__linux__ && __GNUC__<4 && __INTEL_COMPILER_BUILD_DATE <= 20110427) +// In U4, cilkrts incorrectly sends the interop notifications to TBB +#define CILK_NOTIFICATIONS_BROKEN ( __INTEL_COMPILER_BUILD_DATE == 20110427 ) + +#if __TBB_CILK_INTEROP && !CILK_LINKAGE_BROKEN && !CILK_NOTIFICATIONS_BROKEN + +static const int N = 14; +static const int P_outer = 4; +static const int P_nested = 2; + +#include <cilk/cilk.h> +#include <cilk/cilk_api.h> +#define private public +#include "tbb/task.h" +#undef private +#include "tbb/task_scheduler_init.h" +#include <cstdio> +#include <cassert> + +enum tbb_sched_injection_mode_t { + tbbsched_none = 0, + tbbsched_explicit_only = 1, + tbbsched_auto_only = 2, + tbbsched_mixed = 3 +}; + +tbb_sched_injection_mode_t g_sim = tbbsched_none; + +bool g_sandwich = false; // have to be declare before #include "test_cilk_common.h" +#include "test_cilk_common.h" + +// A time delay routine +void Delay( int n ) { + static volatile int Global; + for( int k=0; k<10000; ++k ) + for( int i=0; i<n; ++i ) + ++Global; +} + +int SerialFib( int n ) { + int a=0, b=1; + for( int i=0; i<n; ++i ) { + b += a; + a = b-a; + } + return a; +} + +int F = SerialFib(N); + +int Fib ( int n ) { + if( n < 2 ) { + if ( g_sim ) { + tbb::task_scheduler_init tsi(P_nested); + } + return n; + } else { + tbb::task_scheduler_init *tsi = NULL; + tbb::task *cur = NULL; + if ( g_sim ) { + if ( n % 2 == 0 ) { + if ( g_sim == tbbsched_auto_only || (g_sim == tbbsched_mixed && n % 4 == 0) ) { + // Trigger TBB scheduler auto-initialization + cur = &tbb::task::self(); + } + else { + ASSERT ( g_sim == tbbsched_explicit_only || (g_sim == tbbsched_mixed && n % 4 != 0), NULL ); + // Initialize TBB scheduler explicitly + tsi = new tbb::task_scheduler_init(P_nested); + } + } + } + int x, y; + x = cilk_spawn Fib(n-2); + y = cilk_spawn Fib(n-1); + cilk_sync; + if ( tsi ) + delete tsi; + return x+y; + } +} + +void RunCilkOnly ( tbb_sched_injection_mode_t sim ) { + g_sim = sim; + int m = Fib(N); + ASSERT( m == F, NULL ); +} + +struct FibBody : NoAssign, Harness::NoAfterlife { + void operator() ( int ) const { + int m = Fib(N); + ASSERT( m == F, NULL ); + } +}; + +void RunCilkOnlyConcurrently ( tbb_sched_injection_mode_t sim ) { + g_sim = sim; + NativeParallelFor( P_outer, FibBody() ); +} + +void RunSandwich( bool sandwich ) { + g_sandwich = sandwich; + tbb::task_scheduler_init init(P_outer); + int m = TBB_Fib(N); + ASSERT( g_sandwich == sandwich, "Memory corruption detected" ); + ASSERT( m == F, NULL ); +} + +int TestMain () { + for ( int i = 0; i < 100; ++i ) + RunCilkOnlyConcurrently( tbbsched_none ); + RunCilkOnly( tbbsched_none ); + RunCilkOnly( tbbsched_explicit_only ); + RunCilkOnly( tbbsched_auto_only ); + RunCilkOnly( tbbsched_mixed ); + RunSandwich( false ); + for ( int i = 0; i < 10; ++i ) + RunSandwich( true ); + __cilkrts_end_cilk(); + return Harness::Done; +} + +#else /* !__TBB_CILK_INTEROP */ + +int TestMain () { + return Harness::Skipped; +} + +#endif /* !__TBB_CILK_INTEROP */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_combinable.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_combinable.cpp new file mode 100644 index 00000000..48531369 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_combinable.cpp @@ -0,0 +1,503 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 0 +#define HARNESS_DEFAULT_MAX_THREADS 4 + +#define __TBB_EXTRA_DEBUG 1 // for concurrent_hash_map +#include "tbb/combinable.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" +#include "tbb/tick_count.h" +#include "tbb/tbb_allocator.h" +#include "tbb/tbb_thread.h" + +#include <cstring> +#include <vector> +#include <utility> + +#include "harness_assert.h" +#include "harness.h" +#include "test_container_move_support.h" + +#if __TBB_GCC_WARNING_SUPPRESSION_PRESENT +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + +static tbb::atomic<int> construction_counter; +static tbb::atomic<int> destruction_counter; + +const int REPETITIONS = 10; +const int N = 100000; +const double EXPECTED_SUM = (REPETITIONS + 1) * N; + +// +// A minimal class +// Define: default and copy constructor, and allow implicit operator& +// also operator= +// + +class minimal { +private: + int my_value; +public: + minimal(int val=0) : my_value(val) { ++construction_counter; } + minimal( const minimal &m ) : my_value(m.my_value) { ++construction_counter; } + minimal& operator=(const minimal& other) { my_value = other.my_value; return *this; } + minimal& operator+=(const minimal& other) { my_value += other.my_value; return *this; } + operator int() const { return my_value; } + ~minimal() { ++destruction_counter; } + void set_value( const int i ) { my_value = i; } + int value( ) const { return my_value; } +}; + +//// functors for initialization and combine + +template <typename T> +struct FunctorAddFinit { + T operator()() { return 0; } +}; + +template <typename T> +struct FunctorAddFinit7 { + T operator()() { return 7; } +}; + +template <typename T> +struct FunctorAddCombine { + T operator()(T left, T right ) const { + return left + right; + } +}; + +template <typename T> +struct FunctorAddCombineRef { + T operator()(const T& left, const T& right ) const { + return left + right; + } +}; + +template <typename T> +T my_combine( T left, T right) { return left + right; } + +template <typename T> +T my_combine_ref( const T &left, const T &right) { return left + right; } + +template <typename T> +class CombineEachHelper { +public: + CombineEachHelper(T& _result) : my_result(_result) {} + void operator()(const T& new_bit) { my_result += new_bit; } +private: + T& my_result; +}; + +template <typename T> +class CombineEachHelperCnt { +public: + CombineEachHelperCnt(T& _result, int& _nbuckets) : my_result(_result), nBuckets(_nbuckets) {} + void operator()(const T& new_bit) { my_result += new_bit; ++nBuckets; } +private: + T& my_result; + int& nBuckets; +}; + +template <typename T> +class CombineEachVectorHelper { +public: + typedef std::vector<T, tbb::tbb_allocator<T> > ContainerType; + CombineEachVectorHelper(T& _result) : my_result(_result) { } + void operator()(const ContainerType& new_bit) { + for(typename ContainerType::const_iterator ci = new_bit.begin(); ci != new_bit.end(); ++ci) { + my_result += *ci; + } + } + +private: + T& my_result; +}; + +//// end functors + +// parallel body with a test for first access +template <typename T> +class ParallelScalarBody: NoAssign { + + tbb::combinable<T> &sums; + +public: + + ParallelScalarBody ( tbb::combinable<T> &_sums ) : sums(_sums) { } + + void operator()( const tbb::blocked_range<int> &r ) const { + for (int i = r.begin(); i != r.end(); ++i) { + bool was_there; + T& my_local = sums.local(was_there); + if(!was_there) my_local = 0; + my_local += 1 ; + } + } + +}; + +// parallel body with no test for first access +template <typename T> +class ParallelScalarBodyNoInit: NoAssign { + + tbb::combinable<T> &sums; + +public: + + ParallelScalarBodyNoInit ( tbb::combinable<T> &_sums ) : sums(_sums) { } + + void operator()( const tbb::blocked_range<int> &r ) const { + for (int i = r.begin(); i != r.end(); ++i) { + sums.local() += 1 ; + } + } + +}; + +template< typename T > +void RunParallelScalarTests(const char *test_name) { + + tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred); + for (int p = MinThread; p <= MaxThread; ++p) { + + if (p == 0) continue; + REMARK(" Testing parallel %s on %d thread(s)...\n", test_name, p); + init.initialize(p); + + tbb::tick_count t0; + T combine_sum(0); + T combine_ref_sum(0); + T combine_finit_sum(0); + T combine_each_sum(0); + T copy_construct_sum(0); + T copy_assign_sum(0); +#if __TBB_ETS_USE_CPP11 + T move_construct_sum(0); + T move_assign_sum(0); +#endif + for (int t = -1; t < REPETITIONS; ++t) { + if (Verbose && t == 0) t0 = tbb::tick_count::now(); + + // test uninitialized parallel combinable + tbb::combinable<T> sums; + tbb::parallel_for( tbb::blocked_range<int>( 0, N, 10000 ), ParallelScalarBody<T>( sums ) ); + combine_sum += sums.combine(my_combine<T>); + combine_ref_sum += sums.combine(my_combine_ref<T>); + + // test parallel combinable preinitialized with a functor that returns 0 + FunctorAddFinit<T> my_finit_decl; + tbb::combinable<T> finit_combinable(my_finit_decl); + tbb::parallel_for( tbb::blocked_range<int>( 0, N, 10000 ), ParallelScalarBodyNoInit<T>( finit_combinable ) ); + combine_finit_sum += finit_combinable.combine(my_combine<T>); + + // test another way of combining the elements using CombineEachHelper<T> functor + CombineEachHelper<T> my_helper(combine_each_sum); + sums.combine_each(my_helper); + + // test copy constructor for parallel combinable + tbb::combinable<T> copy_constructed(sums); + copy_construct_sum += copy_constructed.combine(my_combine<T>); + + // test copy assignment for uninitialized parallel combinable + tbb::combinable<T> assigned; + assigned = sums; + copy_assign_sum += assigned.combine(my_combine<T>); + +#if __TBB_ETS_USE_CPP11 + // test move constructor for parallel combinable + tbb::combinable<T> moved1(std::move(sums)); + move_construct_sum += moved1.combine(my_combine<T>); + + // test move assignment for uninitialized parallel combinable + tbb::combinable<T> moved2; + moved2=std::move(finit_combinable); + move_assign_sum += moved2.combine(my_combine<T>); +#endif + } + // Here and below comparison for equality of float numbers succeeds + // as the rounding error doesn't accumulate and doesn't affect the comparison + ASSERT( EXPECTED_SUM == combine_sum, NULL); + ASSERT( EXPECTED_SUM == combine_ref_sum, NULL); + ASSERT( EXPECTED_SUM == combine_finit_sum, NULL); + ASSERT( EXPECTED_SUM == combine_each_sum, NULL); + ASSERT( EXPECTED_SUM == copy_construct_sum, NULL); + ASSERT( EXPECTED_SUM == copy_assign_sum, NULL); +#if __TBB_ETS_USE_CPP11 + ASSERT( EXPECTED_SUM == move_construct_sum, NULL); + ASSERT( EXPECTED_SUM == move_assign_sum, NULL); +#endif + REMARK(" done parallel %s, %d, %g, %g\n", test_name, p, static_cast<double>(combine_sum), + ( tbb::tick_count::now() - t0).seconds()); + init.terminate(); + } +} + +template <typename T> +class ParallelVectorForBody: NoAssign { + + tbb::combinable< std::vector<T, tbb::tbb_allocator<T> > > &locals; + +public: + + ParallelVectorForBody ( tbb::combinable< std::vector<T, tbb::tbb_allocator<T> > > &_locals ) : locals(_locals) { } + + void operator()( const tbb::blocked_range<int> &r ) const { + T one = 1; + + for (int i = r.begin(); i < r.end(); ++i) { + locals.local().push_back( one ); + } + } + +}; + +template< typename T > +void RunParallelVectorTests(const char *test_name) { + + tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred); + + typedef std::vector<T, tbb::tbb_allocator<T> > ContainerType; + + for (int p = MinThread; p <= MaxThread; ++p) { + + if (p == 0) continue; + REMARK(" Testing parallel %s on %d thread(s)... \n", test_name, p); + init.initialize(p); + + tbb::tick_count t0; + T defaultConstructed_sum(0); + T copyConstructed_sum(0); + T copyAssigned_sum(0); +#if __TBB_ETS_USE_CPP11 + T moveConstructed_sum(0); + T moveAssigned_sum(0); +#endif + for (int t = -1; t < REPETITIONS; ++t) { + if (Verbose && t == 0) t0 = tbb::tick_count::now(); + + typedef typename tbb::combinable< ContainerType > CombinableType; + + // test uninitialized parallel combinable + CombinableType vs; + tbb::parallel_for( tbb::blocked_range<int> (0, N, 10000), ParallelVectorForBody<T>( vs ) ); + CombineEachVectorHelper<T> MyCombineEach(defaultConstructed_sum); + vs.combine_each(MyCombineEach); // combine_each sums all elements of each vector into the result + + // test copy constructor for parallel combinable with vectors + CombinableType vs2(vs); + CombineEachVectorHelper<T> MyCombineEach2(copyConstructed_sum); + vs2.combine_each(MyCombineEach2); + + // test copy assignment for uninitialized parallel combinable with vectors + CombinableType vs3; + vs3 = vs; + CombineEachVectorHelper<T> MyCombineEach3(copyAssigned_sum); + vs3.combine_each(MyCombineEach3); + +#if __TBB_ETS_USE_CPP11 + // test move constructor for parallel combinable with vectors + CombinableType vs4(std::move(vs2)); + CombineEachVectorHelper<T> MyCombineEach4(moveConstructed_sum); + vs4.combine_each(MyCombineEach4); + + // test move assignment for uninitialized parallel combinable with vectors + vs4=std::move(vs3); + CombineEachVectorHelper<T> MyCombineEach5(moveAssigned_sum); + vs4.combine_each(MyCombineEach5); +#endif + } + + double ResultValue = defaultConstructed_sum; + ASSERT( EXPECTED_SUM == ResultValue, NULL); + ResultValue = copyConstructed_sum; + ASSERT( EXPECTED_SUM == ResultValue, NULL); + ResultValue = copyAssigned_sum; + ASSERT( EXPECTED_SUM == ResultValue, NULL); +#if __TBB_ETS_USE_CPP11 + ResultValue = moveConstructed_sum; + ASSERT( EXPECTED_SUM == ResultValue, NULL); + ResultValue = moveAssigned_sum; + ASSERT( EXPECTED_SUM == ResultValue, NULL); +#endif + REMARK(" done parallel %s, %d, %g, %g\n", test_name, p, ResultValue, ( tbb::tick_count::now() - t0).seconds()); + init.terminate(); + } +} + +void +RunParallelTests() { + REMARK("Running RunParallelTests\n"); + RunParallelScalarTests<int>("int"); + RunParallelScalarTests<double>("double"); + RunParallelScalarTests<minimal>("minimal"); + RunParallelVectorTests<int>("std::vector<int, tbb::tbb_allocator<int> >"); + RunParallelVectorTests<double>("std::vector<double, tbb::tbb_allocator<double> >"); +} + +template <typename T> +void +RunAssignmentAndCopyConstructorTest(const char *test_name) { + REMARK(" Testing assignment and copy construction for combinable<%s>...\n", test_name); + + // test creation with finit function (combine returns finit return value if no threads have created locals) + FunctorAddFinit7<T> my_finit7_decl; + tbb::combinable<T> create1(my_finit7_decl); + ASSERT(7 == create1.combine(my_combine<T>), "Unexpected combine result for combinable object preinitialized with functor"); + + // test copy construction with function initializer + tbb::combinable<T> copy1(create1); + ASSERT(7 == copy1.combine(my_combine<T>), "Unexpected combine result for copy-constructed combinable object"); + + // test copy assignment with function initializer + FunctorAddFinit<T> my_finit_decl; + tbb::combinable<T> assign1(my_finit_decl); + assign1 = create1; + ASSERT(7 == assign1.combine(my_combine<T>), "Unexpected combine result for copy-assigned combinable object"); + +#if __TBB_ETS_USE_CPP11 + // test move construction with function initializer + tbb::combinable<T> move1(std::move(create1)); + ASSERT(7 == move1.combine(my_combine<T>), "Unexpected combine result for move-constructed combinable object"); + + // test move assignment with function initializer + tbb::combinable<T> move2; + move2=std::move(copy1); + ASSERT(7 == move2.combine(my_combine<T>), "Unexpected combine result for move-assigned combinable object"); +#endif + + REMARK(" done\n"); + +} + +void +RunAssignmentAndCopyConstructorTests() { + REMARK("Running assignment and copy constructor tests:\n"); + RunAssignmentAndCopyConstructorTest<int>("int"); + RunAssignmentAndCopyConstructorTest<double>("double"); + RunAssignmentAndCopyConstructorTest<minimal>("minimal"); +} + +void +RunMoveSemanticsForStateTrackableObjectTest() { + REMARK("Testing move assignment and move construction for combinable<Harness::StateTrackable>...\n"); + + tbb::combinable< Harness::StateTrackable<true> > create1; + ASSERT(create1.local().state == Harness::StateTrackable<true>::DefaultInitialized, + "Unexpected value in default combinable object"); + + // Copy constructing of the new combinable causes copying of stored values + tbb::combinable< Harness::StateTrackable<true> > copy1(create1); + ASSERT(copy1.local().state == Harness::StateTrackable<true>::CopyInitialized, + "Unexpected value in copy-constructed combinable object"); + + // Copy assignment also causes copying of stored values + tbb::combinable< Harness::StateTrackable<true> > copy2; + ASSERT(copy2.local().state == Harness::StateTrackable<true>::DefaultInitialized, + "Unexpected value in default combinable object"); + copy2=create1; + ASSERT(copy2.local().state == Harness::StateTrackable<true>::CopyInitialized, + "Unexpected value in copy-assigned combinable object"); + +#if __TBB_ETS_USE_CPP11 + // Store some marked values in the initial combinable object + create1.local().state = Harness::StateTrackableBase::Unspecified; + + // Move constructing of the new combinable must not cause copying of stored values + tbb::combinable< Harness::StateTrackable<true> > move1(std::move(create1)); + ASSERT(move1.local().state == Harness::StateTrackableBase::Unspecified, "Unexpected value in move-constructed combinable object"); + + // Move assignment must not cause copying of stored values + copy1=std::move(move1); + ASSERT(copy1.local().state == Harness::StateTrackableBase::Unspecified, "Unexpected value in move-assigned combinable object"); + + // Make the stored values valid again in order to delete StateTrackable object correctly + copy1.local().state = Harness::StateTrackable<true>::MoveAssigned; +#endif + + REMARK("done\n"); +} + +#include "harness_barrier.h" + +Harness::SpinBarrier sBarrier; + +struct Body : NoAssign { + tbb::combinable<int>* locals; + const int nthread; + const int nIters; + Body( int nthread_, int niters_ ) : nthread(nthread_), nIters(niters_) { sBarrier.initialize(nthread_); } + + void operator()(int thread_id ) const { + bool existed; + sBarrier.wait(); + for(int i = 0; i < nIters; ++i ) { + existed = thread_id & 1; + int oldval = locals->local(existed); + ASSERT(existed == (i > 0), "Error on first reference"); + ASSERT(!existed || (oldval == thread_id), "Error on fetched value"); + existed = thread_id & 1; + locals->local(existed) = thread_id; + ASSERT(existed, "Error on assignment"); + } + } +}; + +void +TestLocalAllocations( int nthread ) { + ASSERT(nthread > 0, "nthread must be positive"); +#define NITERATIONS 1000 + Body myBody(nthread, NITERATIONS); + tbb::combinable<int> myCombinable; + myBody.locals = &myCombinable; + + NativeParallelFor( nthread, myBody ); + + int mySum = 0; + int mySlots = 0; + CombineEachHelperCnt<int> myCountCombine(mySum, mySlots); + myCombinable.combine_each(myCountCombine); + + ASSERT(nthread == mySlots, "Incorrect number of slots"); + ASSERT(mySum == (nthread - 1) * nthread / 2, "Incorrect values in result"); +} + +void +RunLocalAllocationsTests() { + REMARK("Testing local() allocations\n"); + for(int i = 1 <= MinThread ? MinThread : 1; i <= MaxThread; ++i) { + REMARK(" Testing local() allocation with nthreads=%d...\n", i); + for(int j = 0; j < 100; ++j) { + TestLocalAllocations(i); + } + REMARK(" done\n"); + } +} + +int TestMain () { + if (MaxThread > 0) { + RunParallelTests(); + } + RunAssignmentAndCopyConstructorTests(); + RunMoveSemanticsForStateTrackableObjectTest(); + RunLocalAllocationsTests(); + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_composite_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_composite_node.cpp new file mode 100644 index 00000000..d2205db9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_composite_node.cpp @@ -0,0 +1,602 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness.h" +#if __TBB_FLOW_GRAPH_CPP11_FEATURES +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#include "tbb/flow_graph.h" +#include "harness_graph.h" +#include <tuple> +#include <cmath> +#include <vector> + +struct passthru_body { + int operator()( int i ) { + return i; + } +}; + +class src_body{ + int start; + int finish; + int step; +public: + src_body(int f, int s) : start(1), finish(f), step(s) {} +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(int &a) { + a = start; + if (start <= finish) { + a = start; + start+=step; + return true; + } + else { + return false; + }; + } +#else + int operator()(tbb::flow_control& fc) { + int a = start; + if (start <= finish) { + a = start; + start+=step; + return a; + } + else { + fc.stop(); + return int(); + }; + } +#endif +}; + +struct m_fxn_body{ + void operator()(int, tbb::flow::multifunction_node<int, tbb::flow::tuple<int,int> >::output_ports_type ) {} +}; + +struct ct_body { +ct_body(){} + void operator()(tbb::flow::continue_msg){} +}; + +struct seq_body { +int operator()(int i){return i;} +}; + +template<int N, typename T1, typename T2> +struct compare { + static void compare_refs(T1 tuple1, T2 tuple2) { + ASSERT( &tbb::flow::get<N>(tuple1) == &tbb::flow::get<N>(tuple2), "ports not set correctly"); + compare<N-1, T1, T2>::compare_refs(tuple1, tuple2); + } +}; + +template<typename T1, typename T2> +struct compare<1, T1, T2> { + static void compare_refs(T1 tuple1, T2 tuple2) { + ASSERT(&tbb::flow::get<0>(tuple1) == &tbb::flow::get<0>(tuple2), "port 0 not correctly set"); + } +}; + +void add_all_nodes (){ + tbb::flow::graph g; + + typedef tbb::flow::tuple<tbb::flow::continue_msg, tbb::flow::tuple<int, int>, int, int, int, int, + int, int, int, int, int, int, int, int > InputTupleType; + + typedef tbb::flow::tuple<tbb::flow::continue_msg, tbb::flow::tuple<int, int>, tbb::flow::tagged_msg<size_t, int, float>, + int, int, int, int, int, int, int, int, int, int, int, int > OutputTupleType; + + typedef tbb::flow::tuple< > EmptyTupleType; + + typedef tbb::flow::composite_node<InputTupleType, OutputTupleType > input_output_type; + typedef tbb::flow::composite_node<InputTupleType, EmptyTupleType > input_only_type; + typedef tbb::flow::composite_node<EmptyTupleType, OutputTupleType > output_only_type; + + const size_t NUM_INPUTS = tbb::flow::tuple_size<InputTupleType>::value; + const size_t NUM_OUTPUTS = tbb::flow::tuple_size<OutputTupleType>::value; + + //node types + tbb::flow::continue_node<tbb::flow::continue_msg> ct(g, ct_body()); + tbb::flow::split_node< tbb::flow::tuple<int, int> > s(g); + tbb::flow::input_node<int> src(g, src_body(20,5)); + tbb::flow::function_node<int, int> fxn(g, tbb::flow::unlimited, passthru_body()); + tbb::flow::multifunction_node<int, tbb::flow::tuple<int, int> > m_fxn(g, tbb::flow::unlimited, m_fxn_body()); + tbb::flow::broadcast_node<int> bc(g); + tbb::flow::limiter_node<int> lim(g, 2); + tbb::flow::indexer_node<int, float> ind(g); + tbb::flow::join_node< tbb::flow::tuple< int, int >, tbb::flow::queueing > j(g); + tbb::flow::queue_node<int> q(g); + tbb::flow::buffer_node<int> bf(g); + tbb::flow::priority_queue_node<int> pq(g); + tbb::flow::write_once_node<int> wo(g); + tbb::flow::overwrite_node<int> ovw(g); + tbb::flow::sequencer_node<int> seq(g, seq_body()); + +#if !__TBB_UPCAST_OF_TUPLE_OF_REF_BROKEN + auto input_tuple = std::tie(ct, s, m_fxn, fxn, bc, tbb::flow::input_port<0>(j), lim, q, tbb::flow::input_port<0>(ind), + pq, ovw, wo, bf, seq); + auto output_tuple = std::tie(ct,j, ind, fxn, src, bc, tbb::flow::output_port<0>(s), lim, tbb::flow::output_port<0>(m_fxn), + q, pq, ovw, wo, bf, seq ); +#else + // upcasting from derived to base for a tuple of references created by std::tie + // fails on gcc 4.4 (and all icc in that environment) + input_output_type::input_ports_type input_tuple(ct, s, m_fxn, fxn, bc, tbb::flow::input_port<0>(j), lim, q, + tbb::flow::input_port<0>(ind), pq, ovw, wo, bf, seq); + + input_output_type::output_ports_type output_tuple(ct,j, ind, fxn, src, bc, tbb::flow::output_port<0>(s), + lim, tbb::flow::output_port<0>(m_fxn), q, pq, ovw, wo, bf, seq); +#endif + + //composite_node with both input_ports and output_ports + input_output_type a_node(g); + a_node.set_external_ports(input_tuple, output_tuple); + + a_node.add_visible_nodes(src, fxn, m_fxn, bc, lim, ind, s, ct, j, q, bf, pq, wo, ovw, seq); + a_node.add_nodes(src, fxn, m_fxn, bc, lim, ind, s, ct, j, q, bf, pq, wo, ovw, seq); + + auto a_node_input_ports_ptr = a_node.input_ports(); + compare<NUM_INPUTS-1, decltype(a_node_input_ports_ptr), decltype(input_tuple)>::compare_refs(a_node_input_ports_ptr, input_tuple); + ASSERT (NUM_INPUTS == tbb::flow::tuple_size<decltype(a_node_input_ports_ptr)>::value, "not all declared input ports were bound to nodes"); + + auto a_node_output_ports_ptr = a_node.output_ports(); + compare<NUM_OUTPUTS-1, decltype(a_node_output_ports_ptr), decltype(output_tuple)>::compare_refs(a_node_output_ports_ptr, output_tuple); + ASSERT(NUM_OUTPUTS == tbb::flow::tuple_size<decltype(a_node_output_ports_ptr)>::value, "not all declared output ports were bound to nodes"); + + //composite_node with only input_ports + input_only_type b_node(g); + b_node.set_external_ports(input_tuple); + + b_node.add_visible_nodes(src, fxn, m_fxn, bc, lim, ind, s, ct, j, q, bf, pq, wo, ovw, seq); + b_node.add_nodes(src, fxn, m_fxn, bc, lim, ind, s, ct, j, q, bf, pq, wo, ovw, seq); + + auto b_node_input_ports_ptr = b_node.input_ports(); + compare<NUM_INPUTS-1, decltype(b_node_input_ports_ptr), decltype(input_tuple)>::compare_refs(b_node_input_ports_ptr, input_tuple); + ASSERT (NUM_INPUTS == tbb::flow::tuple_size<decltype(b_node_input_ports_ptr)>::value, "not all declared input ports were bound to nodes"); + + //composite_node with only output_ports + output_only_type c_node(g); + c_node.set_external_ports(output_tuple); + + c_node.add_visible_nodes(src, fxn, m_fxn, bc, lim, ind, s, ct, j, q, bf, pq, wo, ovw, seq); + + c_node.add_nodes(src, fxn, m_fxn, bc, lim, ind, s, ct, j, q, bf, pq, wo, ovw, seq); + + auto c_node_output_ports_ptr = c_node.output_ports(); + compare<NUM_OUTPUTS-1, decltype(c_node_output_ports_ptr), decltype(output_tuple)>::compare_refs(c_node_output_ports_ptr, output_tuple); + ASSERT (NUM_OUTPUTS == tbb::flow::tuple_size<decltype(c_node_output_ports_ptr)>::value, "not all declared input ports were bound to nodes"); +} + +struct tiny_node : public tbb::flow::composite_node< tbb::flow::tuple< int >, tbb::flow::tuple< int > > { + tbb::flow::function_node< int, int > f1; + tbb::flow::function_node< int, int > f2; + typedef tbb::flow::composite_node< tbb::flow::tuple< int >, tbb::flow::tuple< int > > base_type; + +public: + tiny_node(tbb::flow::graph &g, bool hidden = false) : base_type(g), f1(g, tbb::flow::unlimited, passthru_body() ), f2(g, tbb::flow::unlimited, passthru_body() ) { + tbb::flow::make_edge( f1, f2 ); + + tbb::flow::tuple<tbb::flow::function_node< int, int >& > input_tuple(f1); + tbb::flow::tuple<tbb::flow::function_node< int, int >& > output_tuple(f2); + base_type::set_external_ports( input_tuple, output_tuple ); + + if(hidden) + base_type::add_nodes(f1, f2); + else + base_type::add_visible_nodes(f1, f2); + + } +}; + +int test_tiny(bool hidden = false) { + tbb::flow::graph g; + tbb::flow::function_node< int, int > f0( g, tbb::flow::unlimited, passthru_body() ); + tiny_node t(g, hidden); + ASSERT(&tbb::flow::input_port<0>(t) == &t.f1, "f1 not bound to input port 0 in composite_node t"); + ASSERT(&tbb::flow::output_port<0>(t) == &t.f2, "f2 not bound to output port 0 in composite_node t"); + + tiny_node t1(g, hidden); + ASSERT(&tbb::flow::get<0>(t1.input_ports()) == &t1.f1, "f1 not bound to input port 0 in composite_node t1"); + ASSERT(&tbb::flow::get<0>(t1.output_ports()) == &t1.f2, "f2 not bound to output port 0 in composite_node t1"); + + test_input_ports_return_ref(t1); + test_output_ports_return_ref(t1); + + tiny_node t2(g, hidden); + ASSERT(&tbb::flow::input_port<0>(t2) == &t2.f1, "f1 not bound to input port 0 in composite_node t2"); + ASSERT(&tbb::flow::output_port<0>(t2) == &t2.f2, "f2 not bound to output port 0 in composite_node t2"); + + tbb::flow::function_node< int, int > f3( g, tbb::flow::unlimited, passthru_body() ); + tbb::flow::make_edge( f0, t ); + tbb::flow::make_edge( t, t1 ); + tbb::flow::make_edge( t1, t2 ); + tbb::flow::make_edge( t2 , f3 ); + tbb::flow::queue_node<int> q(g); + tbb::flow::make_edge(f3, q); + f0.try_put(1); + g.wait_for_all(); + + int i, j =0; + q.try_get(i); + ASSERT( i == 1, "item did not go through graph"); + q.try_get(j); + ASSERT( !j, "unexpected item in graph"); + g.wait_for_all(); + + tbb::flow::remove_edge(f3, q); + tbb::flow::remove_edge(t2, f3); + tbb::flow::remove_edge(t1, t2); + + tbb::flow::make_edge( t1 , f3 ); + tbb::flow::make_edge(f3, q); + + f0.try_put(2); + g.wait_for_all(); + + q.try_get(i); + ASSERT( i == 2, "item did not go through graph after removal of edge"); + q.try_get(j); + ASSERT( !j, "unexpected item in graph after removal of edge"); + + return 0; +} + +class adder_node : public tbb::flow::composite_node< tbb::flow::tuple< int, int >, tbb::flow::tuple< int > > { +public: + tbb::flow::join_node< tbb::flow::tuple< int, int >, tbb::flow::queueing > j; + tbb::flow::function_node< tbb::flow::tuple< int, int >, int > f; +private: + typedef tbb::flow::composite_node< tbb::flow::tuple< int, int >, tbb::flow::tuple< int > > base_type; + + struct f_body { + int operator()( const tbb::flow::tuple< int, int > &t ) { + return tbb::flow::get<0>(t) + tbb::flow::get<1>(t); + } + }; + +public: + adder_node(tbb::flow::graph &g, bool hidden = false) : base_type(g), j(g), f(g, tbb::flow::unlimited, f_body() ) { + tbb::flow::make_edge( j, f ); + + base_type::set_external_ports(base_type::input_ports_type(tbb::flow::input_port<0>(j), tbb::flow::input_port<1>(j)), base_type::output_ports_type(f)); + + if (hidden) + base_type::add_nodes(j, f); + else + base_type::add_visible_nodes(j, f); + + } +}; + +struct square_body { int operator()(int v) { return v*v; } }; +struct cube_body { int operator()(int v) { return v*v*v; } }; +int adder_sum(int i) { + return (int)(pow(3*pow(i,3) + pow(i, 2),2)); +} +int test_adder(bool hidden = false) { + tbb::flow::graph g; + tbb::flow::function_node<int,int> s(g, tbb::flow::unlimited, square_body()); + tbb::flow::function_node<int,int> c(g, tbb::flow::unlimited, cube_body()); + tbb::flow::function_node<int,int> p(g, tbb::flow::unlimited, passthru_body()); + + adder_node a0(g, hidden); + ASSERT(&tbb::flow::input_port<0>(a0) == &tbb::flow::input_port<0>(a0.j), "input_port 0 of j not bound to input port 0 in composite_node a0"); + ASSERT(&tbb::flow::input_port<1>(a0) == &tbb::flow::input_port<1>(a0.j), "input_port 1 of j not bound to input port 1 in composite_node a0"); + ASSERT(&tbb::flow::output_port<0>(a0) == &a0.f, "f not bound to output port 0 in composite_node a0"); + + adder_node a1(g, hidden); + ASSERT(&tbb::flow::get<0>(a0.input_ports()) == &tbb::flow::input_port<0>(a0.j), "input_port 0 of j not bound to input port 0 in composite_node a1"); + ASSERT(&tbb::flow::get<1>(a0.input_ports()) == &tbb::flow::input_port<1>(a0.j), "input_port1 of j not bound to input port 1 in composite_node a1"); + ASSERT(&tbb::flow::get<0>(a0.output_ports()) == &a0.f, "f not bound to output port 0 in composite_node a1"); + + adder_node a2(g, hidden); + ASSERT(&tbb::flow::input_port<0>(a2) == &tbb::flow::input_port<0>(a2.j), "input_port 0 of j not bound to input port 0 in composite_node a2"); + ASSERT(&tbb::flow::input_port<1>(a2) == &tbb::flow::input_port<1>(a2.j), "input_port 1 of j not bound to input port 1 in composite_node a2"); + ASSERT(&tbb::flow::output_port<0>(a2) == &a2.f, "f not bound to output port 0 in composite_node a2"); + + adder_node a3(g, hidden); + ASSERT(&tbb::flow::get<0>(a3.input_ports()) == &tbb::flow::input_port<0>(a3.j), "input_port 0 of j not bound to input port 0 in composite_node a3"); + ASSERT(&tbb::flow::get<1>(a3.input_ports()) == &tbb::flow::input_port<1>(a3.j), "input_port1 of j not bound to input port 1 in composite_node a3"); + ASSERT(&tbb::flow::get<0>(a3.output_ports()) == &a3.f, "f not bound to output port 0 in composite_node a3"); + + tbb::flow::function_node<int,int> s2(g, tbb::flow::unlimited, square_body()); + tbb::flow::queue_node<int> q(g); + + tbb::flow::make_edge( s, tbb::flow::input_port<0>(a0) ); + tbb::flow::make_edge( c, tbb::flow::input_port<1>(a0) ); + + tbb::flow::make_edge( c, tbb::flow::input_port<0>(a1) ); + tbb::flow::make_edge( c, tbb::flow::input_port<1>(a1) ); + + tbb::flow::make_edge( tbb::flow::output_port<0>(a0), tbb::flow::input_port<0>(a2) ); + tbb::flow::make_edge( tbb::flow::output_port<0>(a1), tbb::flow::input_port<1>(a2) ); + + tbb::flow::make_edge( tbb::flow::output_port<0>(a2), s2 ); + tbb::flow::make_edge( s2, q ); + + int sum_total=0; + int result=0; + for ( int i = 1; i < 4; ++i ) { + s.try_put(i); + c.try_put(i); + sum_total += adder_sum(i); + g.wait_for_all(); + } + + int j; + for ( int i = 1; i < 4; ++i ) { + q.try_get(j); + result += j; + } + g.wait_for_all(); + ASSERT(result == sum_total, "the sum from the graph does not match the calculated value"); + + tbb::flow::remove_edge(s2, q); + tbb::flow::remove_edge( a2, s2 ); + tbb::flow::make_edge( a0, a3 ); + tbb::flow::make_edge( a1, tbb::flow::input_port<1>(a3) ); + tbb::flow::make_edge( a3, s2 ); + tbb::flow::make_edge( s2, q ); + + sum_total=0; + result=0; + for ( int i = 10; i < 20; ++i ) { + s.try_put(i); + c.try_put(i); + sum_total += adder_sum(i); + g.wait_for_all(); + } + + for ( int i = 10; i < 20; ++i ) { + q.try_get(j); + result += j; + } + g.wait_for_all(); + ASSERT(result == sum_total, "the new sum after the replacement of the nodes does not match the calculated value"); + + return 0; +} + +/* + outer composite node (outer_node) + |-------------------------------------------------------------------| + | | + | |------------------| |------------------| |------------------| | + |---------------------| |--| inner composite | /| inner composite | /| inner composite | | |-------------------| + |broadcast node(input)|/| | node |/ | node |/ | node |-+-| queue node(output)| + |---------------------|\| |(inner_node1) |\ | (inner_node2) |\ | (inner_node3) | | |-------------------| + |--| | \| | \| | | + | |------------------| |------------------| |------------------| | + | | + |-------------------------------------------------------------------| + +*/ +int test_nested_adder(bool hidden=false) { + tbb::flow::graph g; + tbb::flow::composite_node<tbb::flow::tuple<int, int>, tbb::flow::tuple<int> > outer_node(g); + typedef tbb::flow::composite_node<tbb::flow::tuple<int, int>, tbb::flow::tuple<int> > base_type; + tbb::flow::broadcast_node<int> input(g); + tbb::flow::queue_node<int> output(g); + + adder_node inner_node1(g, hidden); + adder_node inner_node2(g, hidden); + adder_node inner_node3(g, hidden); + + outer_node.set_external_ports(base_type::input_ports_type(tbb::flow::input_port<0>(inner_node1), tbb::flow::input_port<1>(inner_node1)), base_type::output_ports_type(tbb::flow::output_port<0>(inner_node3))); + + ASSERT(&tbb::flow::input_port<0>(outer_node) == &tbb::flow::input_port<0>(inner_node1), "input port 0 of inner_node1 not bound to input port 0 in outer_node"); + ASSERT(&tbb::flow::input_port<1>(outer_node) == &tbb::flow::input_port<1>(inner_node1), "input port 1 of inner_node1 not bound to input port 1 in outer_node"); + ASSERT(&tbb::flow::output_port<0>(outer_node) == &tbb::flow::output_port<0>(inner_node3), "output port 0 of inner_node3 not bound to output port 0 in outer_node"); + + tbb::flow::make_edge(input, tbb::flow::input_port<0>(outer_node)/*inner_node1*/); + tbb::flow::make_edge(input, tbb::flow::input_port<1>(outer_node)/*inner_node1*/); + + tbb::flow::make_edge(inner_node1, tbb::flow::input_port<0>(inner_node2)); + tbb::flow::make_edge(inner_node1, tbb::flow::input_port<1>(inner_node2)); + + tbb::flow::make_edge(inner_node2, tbb::flow::input_port<0>(inner_node3)); + tbb::flow::make_edge(inner_node2, tbb::flow::input_port<1>(inner_node3)); + + tbb::flow::make_edge(outer_node/*inner_node3*/, output); + + if(hidden) + outer_node.add_nodes(inner_node1, inner_node2, inner_node3); + else + outer_node.add_visible_nodes(inner_node1, inner_node2, inner_node3); + + int out; + for (int i = 1; i < 200000; ++i) { + input.try_put(i); + g.wait_for_all(); + output.try_get(out); + ASSERT(tbb::flow::output_port<0>(outer_node).try_get(out) == output.try_get(out), "output from outer_node does not match output from graph"); + ASSERT(out == 8*i, "output from outer_node not correct"); + } + g.wait_for_all(); + + return 0; +} + +template< typename T > +class prefix_node : public tbb::flow::composite_node< tbb::flow::tuple< T, T, T, T, T >, tbb::flow::tuple< T, T, T, T, T > > { + typedef tbb::flow::tuple< T, T, T, T, T > my_tuple_t; +public: + tbb::flow::join_node< my_tuple_t, tbb::flow::queueing > j; + tbb::flow::split_node< my_tuple_t > s; +private: + tbb::flow::function_node< my_tuple_t, my_tuple_t > f; + typedef tbb::flow::composite_node< my_tuple_t, my_tuple_t > base_type; + + struct f_body { + my_tuple_t operator()( const my_tuple_t &t ) { + return my_tuple_t( tbb::flow::get<0>(t), + tbb::flow::get<0>(t) + tbb::flow::get<1>(t), + tbb::flow::get<0>(t) + tbb::flow::get<1>(t) + tbb::flow::get<2>(t), + tbb::flow::get<0>(t) + tbb::flow::get<1>(t) + tbb::flow::get<2>(t) + tbb::flow::get<3>(t), + tbb::flow::get<0>(t) + tbb::flow::get<1>(t) + tbb::flow::get<2>(t) + tbb::flow::get<3>(t) + tbb::flow::get<4>(t) ); + } + }; + +public: + prefix_node(tbb::flow::graph &g, bool hidden = false ) : base_type(g), j(g), s(g), f(g, tbb::flow::serial, f_body() ) { + tbb::flow::make_edge( j, f ); + tbb::flow::make_edge( f, s ); + + typename base_type::input_ports_type input_tuple(tbb::flow::input_port<0>(j), tbb::flow::input_port<1>(j), tbb::flow::input_port<2>(j), tbb::flow::input_port<3>(j), tbb::flow::input_port<4>(j)); + + typename base_type::output_ports_type output_tuple(tbb::flow::output_port<0>(s), tbb::flow::output_port<1>(s), tbb::flow::output_port<2>(s), tbb::flow::output_port<3>(s), tbb::flow::output_port<4>(s)); + + base_type::set_external_ports(input_tuple, output_tuple); + + if(hidden) + base_type::add_nodes(j,s,f); + else + base_type::add_visible_nodes(j,s,f); + + } +}; + +int test_prefix(bool hidden = false) { + tbb::flow::graph g; + prefix_node<double> p(g, hidden); + + ASSERT(&tbb::flow::get<0>(p.input_ports()) == &tbb::flow::input_port<0>(p.j), "input port 0 of j is not bound to input port 0 of composite node p"); + ASSERT(&tbb::flow::input_port<1>(p.j) == &tbb::flow::input_port<1>(p.j), "input port 1 of j is not bound to input port 1 of composite node p"); + ASSERT(&tbb::flow::get<2>(p.input_ports()) == &tbb::flow::input_port<2>(p.j), "input port 2 of j is not bound to input port 2 of composite node p"); + ASSERT(&tbb::flow::input_port<3>(p.j) == &tbb::flow::input_port<3>(p.j), "input port 3 of j is not bound to input port 3 of composite node p"); + ASSERT(&tbb::flow::get<4>(p.input_ports()) == &tbb::flow::input_port<4>(p.j), "input port 4 of j is not bound to input port 4 of composite node p"); + + + ASSERT(&tbb::flow::get<0>(p.output_ports()) == &tbb::flow::output_port<0>(p.s), "output port 0 of s is not bound to output port 0 of composite node p"); + ASSERT(&tbb::flow::output_port<1>(p.s) == &tbb::flow::output_port<1>(p.s), "output port 1 of s is not bound to output port 1 of composite node p"); + ASSERT(&tbb::flow::get<2>(p.output_ports()) == &tbb::flow::output_port<2>(p.s), "output port 2 of s is not bound to output port 2 of composite node p"); + ASSERT(&tbb::flow::output_port<3>(p.s) == &tbb::flow::output_port<3>(p.s), "output port 3 of s is not bound to output port 3 of composite node p"); + ASSERT(&tbb::flow::get<4>(p.output_ports()) == &tbb::flow::output_port<4>(p.s), "output port 4 of s is not bound to output port 4 of composite node p"); + + std::vector< tbb::flow::queue_node<double> > v( 5, tbb::flow::queue_node<double>(g) ); + tbb::flow::make_edge( tbb::flow::output_port<0>(p), v[0] ); + tbb::flow::make_edge( tbb::flow::output_port<1>(p), v[1] ); + tbb::flow::make_edge( tbb::flow::output_port<2>(p), v[2] ); + tbb::flow::make_edge( tbb::flow::output_port<3>(p), v[3] ); + tbb::flow::make_edge( tbb::flow::output_port<4>(p), v[4] ); + + for( double offset = 1; offset < 10000; offset *= 10 ) { + tbb::flow::input_port<0>(p).try_put( offset ); + tbb::flow::input_port<1>(p).try_put( offset + 1 ); + tbb::flow::input_port<2>(p).try_put( offset + 2 ); + tbb::flow::input_port<3>(p).try_put( offset + 3 ); + tbb::flow::input_port<4>(p).try_put( offset + 4 ); + } + g.wait_for_all(); + + double x; + while ( v[0].try_get(x) ) { + g.wait_for_all(); + for ( int i = 1; i < 5; ++i ) { + v[i].try_get(x); + g.wait_for_all(); + } + } + return 0; +} + +struct input_only_output_only_seq { + int operator()(int i){ return (i + 3) / 4 - 1;} +}; + +void input_only_output_only_composite(bool hidden) { + tbb::flow::graph g; +#if TBB_PREVIEW_FLOW_GRAPH_TRACE + tbb::flow::composite_node<tbb::flow::tuple<int>, tbb::flow::tuple<int> > input_output(g, "test_name"); +#else + tbb::flow::composite_node<tbb::flow::tuple<int>, tbb::flow::tuple<int> > input_output(g); +#endif + typedef tbb::flow::composite_node<tbb::flow::tuple<int>, tbb::flow::tuple<> > input_only_composite; + typedef tbb::flow::composite_node<tbb::flow::tuple<>, tbb::flow::tuple<int> > output_only_composite; + typedef tbb::flow::input_node<int> src_type; + typedef tbb::flow::queue_node<int> q_type; + typedef tbb::flow::function_node<int, int> f_type; + typedef tbb::flow::sequencer_node<int> sequencer_type; + + int num = 0; + int finish=1000; + int step = 4; + + input_only_composite a_in(g); + output_only_composite a_out(g); + + src_type src(g, src_body(finish, step)); + q_type que(g); + f_type f(g, 1, passthru_body()); + + // Sequencer_node is needed, because serial function_node guarantees only serial body execution, + // not a sequential order of messages dispatch + sequencer_type seq(g, input_only_output_only_seq()); + + tbb::flow::tuple<f_type& > input_tuple(f); + a_in.set_external_ports(input_tuple); + ASSERT(&tbb::flow::get<0>(a_in.input_ports()) == &f, "f not bound to input port 0 in composite_node a_in"); + + tbb::flow::tuple<src_type&> output_tuple(src); + a_out.set_external_ports(output_tuple); + ASSERT(&tbb::flow::get<0>(a_out.output_ports()) == &src, "src not bound to output port 0 in composite_node a_out"); + + if(hidden) { + a_in.add_nodes(f, seq, que); + a_out.add_nodes(src); + } else { + a_in.add_visible_nodes(f, seq, que); + a_out.add_visible_nodes(src); + } + + tbb::flow::make_edge(a_out, a_in); + tbb::flow::make_edge(f, seq); + tbb::flow::make_edge(seq, que); + src.activate(); + g.wait_for_all(); + + for(int i = 1; i<finish/step; ++i) { + que.try_get(num); + ASSERT(num == 4*i - 3, "number does not match position in sequence"); + } + g.wait_for_all(); +} + +#endif // __TBB_FLOW_GRAPH_CPP11_FEATURES + +int TestMain() { + +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + + add_all_nodes(); + test_tiny(false); + test_tiny(true); + test_adder(false); + test_adder(true); + test_nested_adder(true); + test_nested_adder(false); + test_prefix(false); + test_prefix(true); + input_only_output_only_composite(true); + input_only_output_only_composite(false); + + return Harness::Done; +#else + return Harness::Skipped; +#endif + +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_associative_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_associative_common.h new file mode 100644 index 00000000..a47db762 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_associative_common.h @@ -0,0 +1,1518 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* Some tests in this source file are based on PPL tests provided by Microsoft. */ +#include "tbb/parallel_for.h" +#include "tbb/tick_count.h" +#include "harness.h" +#include "test_container_move_support.h" +// Test that unordered containers do not require keys have default constructors. +#define __HARNESS_CHECKTYPE_DEFAULT_CTOR 0 +#include "harness_checktype.h" +#undef __HARNESS_CHECKTYPE_DEFAULT_CTOR +#include "harness_allocator.h" + +#if _MSC_VER +#pragma warning(disable: 4189) // warning 4189 -- local variable is initialized but not referenced +#pragma warning(disable: 4127) // warning 4127 -- while (true) has a constant expression in it +#endif + +// TestInitListSupportWithoutAssign with an empty initializer list causes internal error in Intel Compiler. +#define __TBB_ICC_EMPTY_INIT_LIST_TESTS_BROKEN (__INTEL_COMPILER && __INTEL_COMPILER <= 1500) + +typedef local_counting_allocator<debug_allocator<std::pair<const int,int>,std::allocator> > MyAllocator; + +template<typename Table> +inline void CheckAllocator(typename Table::allocator_type& a, size_t expected_allocs, size_t expected_frees, + bool exact = true) { + if(exact) { + ASSERT( a.allocations == expected_allocs, NULL); ASSERT( a.frees == expected_frees, NULL); + } else { + ASSERT( a.allocations >= expected_allocs, NULL); ASSERT( a.frees >= expected_frees, NULL); + ASSERT( a.allocations - a.frees == expected_allocs - expected_frees, NULL ); + } +} + +// Check that only dummy node allocated if table is empty +// Specialize this function for custom container, if it node allocation size > 1 +#define CheckEmptyContainerAllocatorE(t,a,f) CheckEmptyContainerAllocator(t,a,f,true,__LINE__) +#define CheckEmptyContainerAllocatorA(t,a,f) CheckEmptyContainerAllocator(t,a,f,false,__LINE__) +template<typename MyTable> +inline void CheckEmptyContainerAllocator(MyTable &table, size_t expected_allocs, size_t expected_frees, bool exact = true, int line = 0); + +template<typename T> +struct strip_const { typedef T type; }; + +template<typename T> +struct strip_const<const T> { typedef T type; }; + +// value generator for map +template <typename K, typename V = std::pair<const K, K> > +struct ValueFactory { + typedef typename strip_const<K>::type Kstrip; + static V make(const K &value) { return V(value, value); } + static Kstrip key(const V &value) { return value.first; } + static Kstrip get(const V &value) { return (Kstrip)value.second; } + template< typename U > + static U convert(const V &value) { return U(value.second); } +}; + +// generator for set +template <typename T> +struct ValueFactory<T, T> { + static T make(const T &value) { return value; } + static T key(const T &value) { return value; } + static T get(const T &value) { return value; } + template< typename U > + static U convert(const T &value) { return U(value); } +}; + +template <typename T> +struct Value : ValueFactory<typename T::key_type, typename T::value_type> { + template<typename U> + static bool compare( const typename T::iterator& it, U val ) { + return (Value::template convert<U>(*it) == val); + } +}; + +template<Harness::StateTrackableBase::StateValue desired_state, typename T> +void check_value_state(/* typename do_check_element_state =*/ tbb::internal::true_type, T const& t, const char* filename, int line ) +{ + ASSERT_CUSTOM(is_state_f<desired_state>()(t), "", filename, line); +} + +template<Harness::StateTrackableBase::StateValue desired_state, typename T> +void check_value_state(/* typename do_check_element_state =*/ tbb::internal::false_type, T const&, const char* , int ) {/*do nothing*/} + +#define ASSERT_VALUE_STATE(do_check_element_state,state,value) check_value_state<state>(do_check_element_state,value,__FILE__,__LINE__) + +#if __TBB_CPP11_RVALUE_REF_PRESENT +template<typename T, typename do_check_element_state, typename V> +void test_rvalue_insert(V v1, V v2) +{ + typedef T container_t; + + container_t cont; + + std::pair<typename container_t::iterator, bool> ins = cont.insert(Value<container_t>::make(v1)); + ASSERT(ins.second == true && Value<container_t>::get(*(ins.first)) == v1, "Element 1 has not been inserted properly"); + ASSERT_VALUE_STATE(do_check_element_state(),Harness::StateTrackableBase::MoveInitialized,*ins.first); + + typename container_t::iterator it2 = cont.insert(ins.first, Value<container_t>::make(v2)); + ASSERT(Value<container_t>::get(*(it2)) == v2, "Element 2 has not been inserted properly"); + ASSERT_VALUE_STATE(do_check_element_state(),Harness::StateTrackableBase::MoveInitialized,*it2); + +} +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +// The test does not use variadic templates, but emplace() does. + +namespace emplace_helpers { +template<typename container_t, typename arg_t, typename value_t> +std::pair<typename container_t::iterator, bool> call_emplace_impl(container_t& c, arg_t&& k, value_t *){ + // this is a set + return c.emplace(std::forward<arg_t>(k)); +} + +template<typename container_t, typename arg_t, typename first_t, typename second_t> +std::pair<typename container_t::iterator, bool> call_emplace_impl(container_t& c, arg_t&& k, std::pair<first_t, second_t> *){ + // this is a map + return c.emplace(k, std::forward<arg_t>(k)); +} + +template<typename container_t, typename arg_t> +std::pair<typename container_t::iterator, bool> call_emplace(container_t& c, arg_t&& k){ + typename container_t::value_type * selector = NULL; + return call_emplace_impl(c, std::forward<arg_t>(k), selector); +} + +template<typename container_t, typename arg_t, typename value_t> +typename container_t::iterator call_emplace_hint_impl(container_t& c, typename container_t::const_iterator hint, arg_t&& k, value_t *){ + // this is a set + return c.emplace_hint(hint, std::forward<arg_t>(k)); +} + +template<typename container_t, typename arg_t, typename first_t, typename second_t> +typename container_t::iterator call_emplace_hint_impl(container_t& c, typename container_t::const_iterator hint, arg_t&& k, std::pair<first_t, second_t> *){ + // this is a map + return c.emplace_hint(hint, k, std::forward<arg_t>(k)); +} + +template<typename container_t, typename arg_t> +typename container_t::iterator call_emplace_hint(container_t& c, typename container_t::const_iterator hint, arg_t&& k){ + typename container_t::value_type * selector = NULL; + return call_emplace_hint_impl(c, hint, std::forward<arg_t>(k), selector); +} +} +template<typename T, typename do_check_element_state, typename V> +void test_emplace_insert(V v1, V v2){ + typedef T container_t; + container_t cont; + + std::pair<typename container_t::iterator, bool> ins = emplace_helpers::call_emplace(cont, v1); + ASSERT(ins.second == true && Value<container_t>::compare(ins.first, v1), "Element 1 has not been inserted properly"); + ASSERT_VALUE_STATE(do_check_element_state(),Harness::StateTrackableBase::DirectInitialized,*ins.first); + + typename container_t::iterator it2 = emplace_helpers::call_emplace_hint(cont, ins.first, v2); + ASSERT(Value<container_t>::compare(it2, v2), "Element 2 has not been inserted properly"); + ASSERT_VALUE_STATE(do_check_element_state(),Harness::StateTrackableBase::DirectInitialized,*it2); +} +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + +template<typename ContainerType, typename Iterator, typename RangeType> +std::pair<intptr_t,intptr_t> CheckRecursiveRange(RangeType range) { + std::pair<intptr_t,intptr_t> sum(0, 0); // count, sum + for( Iterator i = range.begin(), e = range.end(); i != e; ++i ) { + ++sum.first; sum.second += Value<ContainerType>::get(*i); + } + if( range.is_divisible() ) { + RangeType range2( range, tbb::split() ); + std::pair<intptr_t,intptr_t> sum1 = CheckRecursiveRange<ContainerType,Iterator, RangeType>( range ); + std::pair<intptr_t,intptr_t> sum2 = CheckRecursiveRange<ContainerType,Iterator, RangeType>( range2 ); + sum1.first += sum2.first; sum1.second += sum2.second; + ASSERT( sum == sum1, "Mismatched ranges after division"); + } + return sum; +} + +template <typename Map> +void SpecialMapTests( const char *str ){ + Map cont; + const Map &ccont( cont ); + + // mapped_type& operator[](const key_type& k); + cont[1] = 2; + + // bool empty() const; + ASSERT( !ccont.empty( ), "Concurrent container empty after adding an element" ); + + // size_type size() const; + ASSERT( ccont.size( ) == 1, "Concurrent container size incorrect" ); + ASSERT( cont[1] == 2, "Concurrent container value incorrect" ); + + // mapped_type& at( const key_type& k ); + // const mapped_type& at(const key_type& k) const; + ASSERT( cont.at( 1 ) == 2, "Concurrent container value incorrect" ); + ASSERT( ccont.at( 1 ) == 2, "Concurrent container value incorrect" ); + + // iterator find(const key_type& k); + typename Map::iterator it = cont.find( 1 ); + ASSERT( it != cont.end( ) && Value<Map>::get( *(it) ) == 2, "Element with key 1 not properly found" ); + cont.unsafe_erase( it ); + + it = cont.find( 1 ); + ASSERT( it == cont.end( ), "Element with key 1 not properly erased" ); + REMARK( "passed -- specialized %s tests\n", str ); +} + +template <typename MultiMap> +void CheckMultiMap(MultiMap &m, int *targets, int tcount, int key) { + std::vector<bool> vfound(tcount,false); + std::pair<typename MultiMap::iterator, typename MultiMap::iterator> range = m.equal_range( key ); + for(typename MultiMap::iterator it = range.first; it != range.second; ++it) { + bool found = false; + for( int i = 0; i < tcount; ++i) { + if((*it).second == targets[i]) { + if(!vfound[i]) { // we can insert duplicate values + vfound[i] = found = true; + break; + } + } + } + // just in case an extra value in equal_range... + ASSERT(found, "extra value from equal range"); + } + for(int i = 0; i < tcount; ++i) ASSERT(vfound[i], "missing value"); +} + +template <typename MultiMap> +void MultiMapEraseTests(){ + MultiMap cont1, cont2; + + typename MultiMap::iterator erased_it; + for (int i = 0; i < 10; ++i) { + if ( i != 1 ) { + cont1.insert(std::make_pair(1, i)); + cont2.insert(std::make_pair(1, i)); + } else { + erased_it = cont1.insert(std::make_pair(1, i)).first; + } + } + + cont1.unsafe_erase(erased_it); + + ASSERT(cont1.size() == cont2.size(), "Incorrect count of elements was erased"); + typename MultiMap::iterator it1 = cont1.begin(); + typename MultiMap::iterator it2 = cont2.begin(); + + for (typename MultiMap::size_type i = 0; i < cont2.size(); ++i) { + ASSERT(*(it1++) == *(it2++), "Multimap repetitive key was not erased properly"); + } +} + +template <typename MultiMap> +void SpecialMultiMapTests( const char *str ){ + int one_values[] = { 7, 2, 13, 23, 13 }; + int zero_values[] = { 4, 9, 13, 29, 42, 111}; + int n_zero_values = sizeof(zero_values) / sizeof(int); + int n_one_values = sizeof(one_values) / sizeof(int); + MultiMap cont; + const MultiMap &ccont( cont ); + // mapped_type& operator[](const key_type& k); + cont.insert( std::make_pair( 1, one_values[0] ) ); + + // bool empty() const; + ASSERT( !ccont.empty( ), "Concurrent container empty after adding an element" ); + + // size_type size() const; + ASSERT( ccont.size( ) == 1, "Concurrent container size incorrect" ); + ASSERT( (*(cont.begin( ))).second == one_values[0], "Concurrent container value incorrect" ); + ASSERT( (*(cont.equal_range( 1 )).first).second == one_values[0], "Improper value from equal_range" ); + ASSERT( (cont.equal_range( 1 )).second == cont.end( ), "Improper iterator from equal_range" ); + + cont.insert( std::make_pair( 1, one_values[1] ) ); + + // bool empty() const; + ASSERT( !ccont.empty( ), "Concurrent container empty after adding an element" ); + + // size_type size() const; + ASSERT( ccont.size( ) == 2, "Concurrent container size incorrect" ); + CheckMultiMap(cont, one_values, 2, 1); + + // insert the other {1,x} values + for( int i = 2; i < n_one_values; ++i ) { + cont.insert( std::make_pair( 1, one_values[i] ) ); + } + + CheckMultiMap(cont, one_values, n_one_values, 1); + ASSERT( (cont.equal_range( 1 )).second == cont.end( ), "Improper iterator from equal_range" ); + + cont.insert( std::make_pair( 0, zero_values[0] ) ); + + // bool empty() const; + ASSERT( !ccont.empty( ), "Concurrent container empty after adding an element" ); + + // size_type size() const; + ASSERT( ccont.size( ) == (size_t)(n_one_values+1), "Concurrent container size incorrect" ); + CheckMultiMap(cont, one_values, n_one_values, 1); + CheckMultiMap(cont, zero_values, 1, 0); + ASSERT( (*(cont.begin( ))).second == zero_values[0], "Concurrent container value incorrect" ); + // insert the rest of the zero values + for( int i = 1; i < n_zero_values; ++i) { + cont.insert( std::make_pair( 0, zero_values[i] ) ); + } + CheckMultiMap(cont, one_values, n_one_values, 1); + CheckMultiMap(cont, zero_values, n_zero_values, 0); + + // clear, reinsert interleaved + cont.clear(); + int bigger_num = ( n_one_values > n_zero_values ) ? n_one_values : n_zero_values; + for( int i = 0; i < bigger_num; ++i ) { + if(i < n_one_values) cont.insert( std::make_pair( 1, one_values[i] ) ); + if(i < n_zero_values) cont.insert( std::make_pair( 0, zero_values[i] ) ); + } + CheckMultiMap(cont, one_values, n_one_values, 1); + CheckMultiMap(cont, zero_values, n_zero_values, 0); + + MultiMapEraseTests<MultiMap>(); + + REMARK( "passed -- specialized %s tests\n", str ); +} + +template <typename T> +struct SpecialTests { + static void Test(const char *str) {REMARK("skipped -- specialized %s tests\n", str);} +}; + + + +#if __TBB_RANGE_BASED_FOR_PRESENT +#include "test_range_based_for.h" + +template <typename Container> +void TestRangeBasedFor() { + using namespace range_based_for_support_tests; + + REMARK( "testing range based for loop compatibility \n" ); + Container cont; + const int sequence_length = 100; + for ( int i = 1; i <= sequence_length; ++i ) { + cont.insert( Value<Container>::make(i) ); + } + + ASSERT( range_based_for_accumulate( cont, unified_summer(), 0 ) == + gauss_summ_of_int_sequence( sequence_length ), + "incorrect accumulated value generated via range based for ?" ); +} +#endif /* __TBB_RANGE_BASED_FOR_PRESENT */ + +#if __TBB_INITIALIZER_LISTS_PRESENT +// Required by test_initializer_list.h +template<typename container_type> +bool equal_containers(container_type const& lhs, container_type const& rhs) { + if ( lhs.size() != rhs.size() ) { + return false; + } + return std::equal( lhs.begin(), lhs.end(), rhs.begin(), Harness::IsEqual() ); +} + +#include "test_initializer_list.h" + +template <typename Table, typename MultiTable> +void TestInitList( std::initializer_list<typename Table::value_type> il ) { + using namespace initializer_list_support_tests; + REMARK("testing initializer_list methods \n"); + + TestInitListSupportWithoutAssign<Table,test_special_insert>(il); + TestInitListSupportWithoutAssign<MultiTable, test_special_insert>( il ); + +#if __TBB_ICC_EMPTY_INIT_LIST_TESTS_BROKEN + REPORT( "Known issue: TestInitListSupportWithoutAssign with an empty initializer list is skipped.\n"); +#else + TestInitListSupportWithoutAssign<Table, test_special_insert>( {} ); + TestInitListSupportWithoutAssign<MultiTable, test_special_insert>( {} ); +#endif +} +#endif //if __TBB_INITIALIZER_LISTS_PRESENT + +template<typename T, typename do_check_element_state> +void test_basic_common(const char * str, do_check_element_state) +{ + T cont; + const T &ccont(cont); + CheckEmptyContainerAllocatorE(cont, 1, 0); // one dummy is always allocated + // bool empty() const; + ASSERT(ccont.empty(), "Concurrent container is not empty after construction"); + + // size_type size() const; + ASSERT(ccont.size() == 0, "Concurrent container is not empty after construction"); + + // size_type max_size() const; + ASSERT(ccont.max_size() > 0, "Concurrent container max size is invalid"); + + //iterator begin(); + //iterator end(); + ASSERT(cont.begin() == cont.end(), "Concurrent container iterators are invalid after construction"); + ASSERT(ccont.begin() == ccont.end(), "Concurrent container iterators are invalid after construction"); + ASSERT(cont.cbegin() == cont.cend(), "Concurrent container iterators are invalid after construction"); + + //std::pair<iterator, bool> insert(const value_type& obj); + std::pair<typename T::iterator, bool> ins = cont.insert(Value<T>::make(1)); + ASSERT(ins.second == true && Value<T>::get(*(ins.first)) == 1, "Element 1 has not been inserted properly"); + +#if __TBB_CPP11_RVALUE_REF_PRESENT + test_rvalue_insert<T,do_check_element_state>(1,2); +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + test_emplace_insert<T,do_check_element_state>(1,2); +#endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + + // bool empty() const; + ASSERT(!ccont.empty(), "Concurrent container is empty after adding an element"); + + // size_type size() const; + ASSERT(ccont.size() == 1, "Concurrent container size is incorrect"); + + std::pair<typename T::iterator, bool> ins2 = cont.insert(Value<T>::make(1)); + + if (T::allow_multimapping) + { + // std::pair<iterator, bool> insert(const value_type& obj); + ASSERT(ins2.second == true && Value<T>::get(*(ins2.first)) == 1, "Element 1 has not been inserted properly"); + + // size_type size() const; + ASSERT(ccont.size() == 2, "Concurrent container size is incorrect"); + + // size_type count(const key_type& k) const; + ASSERT(ccont.count(1) == 2, "Concurrent container count(1) is incorrect"); + // std::pair<iterator, iterator> equal_range(const key_type& k); + std::pair<typename T::iterator, typename T::iterator> range = cont.equal_range(1); + typename T::iterator it = range.first; + ASSERT(it != cont.end() && Value<T>::get(*it) == 1, "Element 1 has not been found properly"); + unsigned int count = 0; + for (; it != range.second; it++) + { + count++; + ASSERT(Value<T>::get(*it) == 1, "Element 1 has not been found properly"); + } + + ASSERT(count == 2, "Range doesn't have the right number of elements"); + } + else + { + // std::pair<iterator, bool> insert(const value_type& obj); + ASSERT(ins2.second == false && ins2.first == ins.first, "Element 1 should not be re-inserted"); + + // size_type size() const; + ASSERT(ccont.size() == 1, "Concurrent container size is incorrect"); + + // size_type count(const key_type& k) const; + ASSERT(ccont.count(1) == 1, "Concurrent container count(1) is incorrect"); + + // std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + // std::pair<iterator, iterator> equal_range(const key_type& k); + std::pair<typename T::iterator, typename T::iterator> range = cont.equal_range(1); + typename T::iterator it = range.first; + ASSERT(it != cont.end() && Value<T>::get(*it) == 1, "Element 1 has not been found properly"); + ASSERT(++it == range.second, "Range doesn't have the right number of elements"); + } + + // const_iterator find(const key_type& k) const; + // iterator find(const key_type& k); + typename T::iterator it = cont.find(1); + ASSERT(it != cont.end() && Value<T>::get(*(it)) == 1, "Element 1 has not been found properly"); + ASSERT(ccont.find(1) == it, "Element 1 has not been found properly"); + + // Will be implemented in unordered containers later +#if !__TBB_UNORDERED_TEST + //bool contains(const key_type&k) const + ASSERT(cont.contains(1), "contains() cannot detect existing element"); + ASSERT(!cont.contains(0), "contains() detect not existing element"); +#endif /*__TBB_UNORDERED_TEST*/ + + // iterator insert(const_iterator hint, const value_type& obj); + typename T::iterator it2 = cont.insert(ins.first, Value<T>::make(2)); + ASSERT(Value<T>::get(*it2) == 2, "Element 2 has not been inserted properly"); + + // T(const T& _Umap) + T newcont = ccont; + ASSERT(T::allow_multimapping ? (newcont.size() == 3) : (newcont.size() == 2), "Copy construction has not copied the elements properly"); + + // this functionality not implemented yet + // size_type unsafe_erase(const key_type& k); + typename T::size_type size = cont.unsafe_erase(1); + ASSERT(T::allow_multimapping ? (size == 2) : (size == 1), "Erase has not removed the right number of elements"); + + // iterator unsafe_erase(iterator position); + typename T::iterator it4 = cont.unsafe_erase(cont.find(2)); + ASSERT(it4 == cont.end() && cont.size() == 0, "Erase has not removed the last element properly"); + + // iterator unsafe_erase(const_iterator position); + cont.insert(Value<T>::make(3)); + typename T::iterator it5 = cont.unsafe_erase(cont.cbegin()); + ASSERT(it5 == cont.end() && cont.size() == 0, "Erase has not removed the last element properly"); + + // template<class InputIterator> void insert(InputIterator first, InputIterator last); + cont.insert(newcont.begin(), newcont.end()); + ASSERT(T::allow_multimapping ? (cont.size() == 3) : (cont.size() == 2), "Range insert has not copied the elements properly"); + + // this functionality not implemented yet + // iterator unsafe_erase(const_iterator first, const_iterator last); + std::pair<typename T::iterator, typename T::iterator> range2 = newcont.equal_range(1); + newcont.unsafe_erase(range2.first, range2.second); + ASSERT(newcont.size() == 1, "Range erase has not erased the elements properly"); + + // void clear(); + newcont.clear(); + ASSERT(newcont.begin() == newcont.end() && newcont.size() == 0, "Clear has not cleared the container"); + +#if __TBB_INITIALIZER_LISTS_PRESENT +#if __TBB_CPP11_INIT_LIST_TEMP_OBJS_LIFETIME_BROKEN + REPORT("Known issue: the test for insert with initializer_list is skipped.\n"); +#else + // void insert(const std::initializer_list<value_type> &il); + newcont.insert( { Value<T>::make( 1 ), Value<T>::make( 2 ), Value<T>::make( 1 ) } ); + if (T::allow_multimapping) { + ASSERT(newcont.size() == 3, "Concurrent container size is incorrect"); + ASSERT(newcont.count(1) == 2, "Concurrent container count(1) is incorrect"); + ASSERT(newcont.count(2) == 1, "Concurrent container count(2) is incorrect"); + std::pair<typename T::iterator, typename T::iterator> range = cont.equal_range(1); + it = range.first; + ASSERT(it != newcont.end() && Value<T>::get(*it) == 1, "Element 1 has not been found properly"); + unsigned int count = 0; + for (; it != range.second; it++) { + count++; + ASSERT(Value<T>::get(*it) == 1, "Element 1 has not been found properly"); + } + ASSERT(count == 2, "Range doesn't have the right number of elements"); + range = newcont.equal_range(2); it = range.first; + ASSERT(it != newcont.end() && Value<T>::get(*it) == 2, "Element 2 has not been found properly"); + count = 0; + for (; it != range.second; it++) { + count++; + ASSERT(Value<T>::get(*it) == 2, "Element 2 has not been found properly"); + } + ASSERT(count == 1, "Range doesn't have the right number of elements"); + } else { + ASSERT(newcont.size() == 2, "Concurrent container size is incorrect"); + ASSERT(newcont.count(1) == 1, "Concurrent container count(1) is incorrect"); + ASSERT(newcont.count(2) == 1, "Concurrent container count(2) is incorrect"); + std::pair<typename T::iterator, typename T::iterator> range = newcont.equal_range(1); + it = range.first; + ASSERT(it != newcont.end() && Value<T>::get(*it) == 1, "Element 1 has not been found properly"); + ASSERT(++it == range.second, "Range doesn't have the right number of elements"); + range = newcont.equal_range(2); it = range.first; + ASSERT(it != newcont.end() && Value<T>::get(*it) == 2, "Element 2 has not been found properly"); + ASSERT(++it == range.second, "Range doesn't have the right number of elements"); + } +#endif /* __TBB_CPP11_INIT_LIST_TEMP_OBJS_COMPILATION_BROKEN */ +#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ + + // T& operator=(const T& _Umap) + newcont = ccont; + ASSERT(T::allow_multimapping ? (newcont.size() == 3) : (newcont.size() == 2), "Assignment operator has not copied the elements properly"); + + REMARK("passed -- basic %s tests\n", str); + +#if defined (VERBOSE) + REMARK("container dump debug:\n"); + cont._Dump(); + REMARK("container dump release:\n"); + cont.dump(); + REMARK("\n"); +#endif + + cont.clear(); + CheckEmptyContainerAllocatorA(cont, 1, 0); // one dummy is always allocated + for (int i = 0; i < 256; i++) + { + std::pair<typename T::iterator, bool> ins3 = cont.insert(Value<T>::make(i)); + ASSERT(ins3.second == true && Value<T>::get(*(ins3.first)) == i, "Element 1 has not been inserted properly"); + } + ASSERT(cont.size() == 256, "Wrong number of elements have been inserted"); + ASSERT((256 == CheckRecursiveRange<T,typename T::iterator>(cont.range()).first), NULL); + ASSERT((256 == CheckRecursiveRange<T,typename T::const_iterator>(ccont.range()).first), NULL); + + // void swap(T&); + cont.swap(newcont); + ASSERT(newcont.size() == 256, "Wrong number of elements after swap"); + ASSERT(newcont.count(200) == 1, "Element with key 200 is not present after swap"); + ASSERT(newcont.count(16) == 1, "Element with key 16 is not present after swap"); + ASSERT(newcont.count(99) == 1, "Element with key 99 is not present after swap"); + ASSERT(T::allow_multimapping ? (cont.size() == 3) : (cont.size() == 2), "Assignment operator has not copied the elements properly"); + + // Need to be enabled + SpecialTests<T>::Test(str); +} + +template<typename T> +void test_basic_common(const char * str){ + test_basic_common<T>(str, tbb::internal::false_type()); +} + +void test_machine() { + ASSERT(__TBB_ReverseByte(0)==0, NULL ); + ASSERT(__TBB_ReverseByte(1)==0x80, NULL ); + ASSERT(__TBB_ReverseByte(0xFE)==0x7F, NULL ); + ASSERT(__TBB_ReverseByte(0xFF)==0xFF, NULL ); +} + +template<typename T> +class FillTable: NoAssign { + T &table; + const int items; + bool my_asymptotic; + typedef std::pair<typename T::iterator, bool> pairIB; +public: + FillTable(T &t, int i, bool asymptotic) : table(t), items(i), my_asymptotic(asymptotic) { + ASSERT( !(items&1) && items > 100, NULL); + } + void operator()(int threadn) const { + if( threadn == 0 ) { // Fill even keys forward (single thread) + bool last_inserted = true; + for( int i = 0; i < items; i+=2 ) { + pairIB pib = table.insert(Value<T>::make(my_asymptotic?1:i)); + ASSERT(Value<T>::get(*(pib.first)) == (my_asymptotic?1:i), "Element not properly inserted"); + ASSERT( last_inserted || !pib.second, "Previous key was not inserted but this is inserted" ); + last_inserted = pib.second; + } + } else if( threadn == 1 ) { // Fill even keys backward (single thread) + bool last_inserted = true; + for( int i = items-2; i >= 0; i-=2 ) { + pairIB pib = table.insert(Value<T>::make(my_asymptotic?1:i)); + ASSERT(Value<T>::get(*(pib.first)) == (my_asymptotic?1:i), "Element not properly inserted"); + ASSERT( last_inserted || !pib.second, "Previous key was not inserted but this is inserted" ); + last_inserted = pib.second; + } + } else if( !(threadn&1) ) { // Fill odd keys forward (multiple threads) + for( int i = 1; i < items; i+=2 ) +#if __TBB_INITIALIZER_LISTS_PRESENT && !__TBB_CPP11_INIT_LIST_TEMP_OBJS_LIFETIME_BROKEN + if ( i % 32 == 1 && i + 6 < items ) { + if (my_asymptotic) { + table.insert({ Value<T>::make(1), Value<T>::make(1), Value<T>::make(1) }); + ASSERT(Value<T>::get(*table.find(1)) == 1, "Element not properly inserted"); + } + else { + table.insert({ Value<T>::make(i), Value<T>::make(i + 2), Value<T>::make(i + 4) }); + ASSERT(Value<T>::get(*table.find(i)) == i, "Element not properly inserted"); + ASSERT(Value<T>::get(*table.find(i + 2)) == i + 2, "Element not properly inserted"); + ASSERT(Value<T>::get(*table.find(i + 4)) == i + 4, "Element not properly inserted"); + } + i += 4; + } else +#endif + { + pairIB pib = table.insert(Value<T>::make(my_asymptotic ? 1 : i)); + ASSERT(Value<T>::get(*(pib.first)) == (my_asymptotic ? 1 : i), "Element not properly inserted"); + } + } else { // Check odd keys backward (multiple threads) + if (!my_asymptotic) { + bool last_found = false; + for( int i = items-1; i >= 0; i-=2 ) { + typename T::iterator it = table.find(i); + if( it != table.end() ) { // found + ASSERT(Value<T>::get(*it) == i, "Element not properly inserted"); + last_found = true; + } else { + ASSERT( !last_found, "Previous key was found but this is not" ); + } + } + } + } + } +}; + +typedef tbb::atomic<unsigned char> AtomicByte; + +template<typename ContainerType, typename RangeType> +struct ParallelTraverseBody: NoAssign { + const int n; + AtomicByte* const array; + ParallelTraverseBody( AtomicByte an_array[], int a_n ) : + n(a_n), array(an_array) + {} + void operator()( const RangeType& range ) const { + for( typename RangeType::iterator i = range.begin(); i!=range.end(); ++i ) { + int k = static_cast<int>(Value<ContainerType>::key(*i)); + ASSERT( k == Value<ContainerType>::get(*i), NULL ); + ASSERT( 0<=k && k<n, NULL ); + array[k]++; + } + } +}; + +// if multimapping, oddCount is the value that each odd-indexed array element should have. +// not meaningful for non-multimapped case. +void CheckRange( AtomicByte array[], int n, bool allowMultiMapping, int oddCount ) { + if(allowMultiMapping) { + for( int k = 0; k<n; ++k) { + if(k%2) { + if( array[k] != oddCount ) { + REPORT("array[%d]=%d (should be %d)\n", k, int(array[k]), oddCount); + ASSERT(false,NULL); + } + } + else { + if(array[k] != 2) { + REPORT("array[%d]=%d\n", k, int(array[k])); + ASSERT(false,NULL); + } + } + } + } + else { + for( int k=0; k<n; ++k ) { + if( array[k] != 1 ) { + REPORT("array[%d]=%d\n", k, int(array[k])); + ASSERT(false,NULL); + } + } + } +} + +template<typename T> +class CheckTable: NoAssign { + T &table; +public: + CheckTable(T &t) : NoAssign(), table(t) {} + void operator()(int i) const { + int c = (int)table.count( i ); + ASSERT( c, "must exist" ); + } +}; + +template<typename T> +void test_concurrent_common(const char *tablename, bool asymptotic = false) { +#if TBB_USE_ASSERT + int items = 2000; +#else + int items = 20000; +#endif + int nItemsInserted = 0; + int nThreads = 0; +#if __TBB_UNORDERED_TEST + T table(items/1000); +#else + T table; +#endif + #if __bgp__ + nThreads = 6; + #else + nThreads = 16; + #endif + if(T::allow_multimapping) { + // even passes (threads 0 & 1) put N/2 items each + // odd passes (threads > 1) put N/2 if thread is odd, else checks if even. + items = 4*items / (nThreads + 2); // approximately same number of items inserted. + nItemsInserted = items + (nThreads-2) * items / 4; + } + else { + nItemsInserted = items; + } + REMARK("%s items == %d\n", tablename, items); + tbb::tick_count t0 = tbb::tick_count::now(); + NativeParallelFor( nThreads, FillTable<T>(table, items, asymptotic) ); + tbb::tick_count t1 = tbb::tick_count::now(); + REMARK( "time for filling '%s' by %d items = %g\n", tablename, table.size(), (t1-t0).seconds() ); + ASSERT( int(table.size()) == nItemsInserted, NULL); + + if(!asymptotic) { + AtomicByte* array = new AtomicByte[items]; + memset( static_cast<void*>(array), 0, items*sizeof(AtomicByte) ); + + typename T::range_type r = table.range(); + std::pair<intptr_t,intptr_t> p = CheckRecursiveRange<T,typename T::iterator>(r); + ASSERT((nItemsInserted == p.first), NULL); + tbb::parallel_for( r, ParallelTraverseBody<T, typename T::const_range_type>( array, items )); + CheckRange( array, items, T::allow_multimapping, (nThreads - 1)/2 ); + + const T &const_table = table; + memset( static_cast<void*>(array), 0, items*sizeof(AtomicByte) ); + typename T::const_range_type cr = const_table.range(); + ASSERT((nItemsInserted == CheckRecursiveRange<T,typename T::const_iterator>(cr).first), NULL); + tbb::parallel_for( cr, ParallelTraverseBody<T, typename T::const_range_type>( array, items )); + CheckRange( array, items, T::allow_multimapping, (nThreads - 1) / 2 ); + delete[] array; + + tbb::parallel_for( 0, items, CheckTable<T>( table ) ); + } + + table.clear(); + CheckEmptyContainerAllocatorA(table, items+1, items); // one dummy is always allocated + +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +#include "test_container_move_support.h" + +template<typename container_traits> +void test_rvalue_ref_support(const char* container_name){ + TestMoveConstructor<container_traits>(); + TestMoveAssignOperator<container_traits>(); +#if TBB_USE_EXCEPTIONS + TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorMemoryFailure<container_traits>(); + TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorExceptionInElementCtor<container_traits>(); +#endif //TBB_USE_EXCEPTIONS + REMARK("passed -- %s move support tests\n", container_name); +} +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + +namespace test_select_size_t_constant{ + __TBB_STATIC_ASSERT((tbb::internal::select_size_t_constant<1234,1234>::value == 1234),"select_size_t_constant::value is not compile time constant"); +// There will be two constant used in the test 32 bit and 64 bit one. +// The 64 bit constant should chosen so that it 32 bit halves adds up to the 32 bit one ( first constant used in the test). +// % ~0U is used to sum up 32bit halves of the 64 constant. ("% ~0U" essentially adds the 32-bit "digits", like "%9" adds +// the digits (modulo 9) of a number in base 10). +// So iff select_size_t_constant is correct result of the calculation below will be same on both 32bit and 64bit platforms. + __TBB_STATIC_ASSERT((tbb::internal::select_size_t_constant<0x12345678U,0x091A2B3C091A2B3CULL>::value % ~0U == 0x12345678U), + "select_size_t_constant have chosen the wrong constant"); +} + +#if __TBB_CPP11_SMART_POINTERS_PRESENT +// For the sake of simplified testing, make unique_ptr implicitly convertible to/from the pointer +namespace test { + template<typename T> + class unique_ptr : public std::unique_ptr<T> { + public: + typedef typename std::unique_ptr<T>::pointer pointer; + unique_ptr( pointer p ) : std::unique_ptr<T>(p) {} + operator pointer() const { return this->get(); } + }; +} +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ + +#include <vector> +#include <list> +#include <algorithm> + +template <typename ValueType> +class TestRange : NoAssign { + const std::list<ValueType> &my_lst; + std::vector< tbb::atomic<bool> > &my_marks; +public: + TestRange( const std::list<ValueType> &lst, std::vector< tbb::atomic<bool> > &marks ) : my_lst( lst ), my_marks( marks ) { + std::fill( my_marks.begin(), my_marks.end(), false ); + } + template <typename Range> + void operator()( const Range &r ) const { doTestRange( r.begin(), r.end() ); } + template<typename Iterator> + void doTestRange( Iterator i, Iterator j ) const { + for ( Iterator it = i; it != j; ) { + Iterator prev_it = it++; + typename std::list<ValueType>::const_iterator it2 = std::search( my_lst.begin(), my_lst.end(), prev_it, it, Harness::IsEqual() ); + ASSERT( it2 != my_lst.end(), NULL ); + typename std::list<ValueType>::difference_type dist = std::distance( my_lst.begin( ), it2 ); + ASSERT( !my_marks[dist], NULL ); + my_marks[dist] = true; + } + } +}; + +// The helper to call a function only when a doCall == true. +template <bool doCall> struct CallIf { + template<typename FuncType> void operator() ( FuncType func ) const { func(); } +}; +template <> struct CallIf<false> { + template<typename FuncType> void operator()( FuncType ) const {} +}; + +template <typename Table> +class TestOperatorSquareBrackets : NoAssign { + typedef typename Table::value_type ValueType; + Table &my_c; + const ValueType &my_value; +public: + TestOperatorSquareBrackets( Table &c, const ValueType &value ) : my_c( c ), my_value( value ) {} + void operator()() const { + ASSERT( Harness::IsEqual()(my_c[my_value.first], my_value.second), NULL ); + } +}; + +template <bool defCtorPresent, typename Table, typename Value> +void TestMapSpecificMethodsImpl(Table &c, const Value &value){ + CallIf<defCtorPresent>()(TestOperatorSquareBrackets<Table>( c, value )); + ASSERT( Harness::IsEqual()(c.at( value.first ), value.second), NULL ); + const Table &constC = c; + ASSERT( Harness::IsEqual()(constC.at( value.first ), value.second), NULL ); +} + +// do nothing for common case +template <bool defCtorPresent, typename Table, typename Value> +void TestMapSpecificMethods( Table&, const Value& ) {} + +template <bool defCtorPresent, typename Table> +class CheckValue : NoAssign { + Table &my_c; +public: + CheckValue( Table &c ) : my_c( c ) {} + void operator()( const typename Table::value_type &value ) { + typedef typename Table::iterator Iterator; + typedef typename Table::const_iterator ConstIterator; + const Table &constC = my_c; + ASSERT( my_c.count( Value<Table>::key( value ) ) == 1, NULL ); + // find + ASSERT( Harness::IsEqual()(*my_c.find( Value<Table>::key( value ) ), value), NULL ); + ASSERT( Harness::IsEqual()(*constC.find( Value<Table>::key( value ) ), value), NULL ); + // erase + ASSERT( my_c.unsafe_erase( Value<Table>::key( value ) ), NULL ); + ASSERT( my_c.count( Value<Table>::key( value ) ) == 0, NULL ); + // insert + std::pair<Iterator, bool> res = my_c.insert( value ); + ASSERT( Harness::IsEqual()(*res.first, value), NULL ); + ASSERT( res.second, NULL); + // erase + Iterator it = res.first; + it++; + ASSERT( my_c.unsafe_erase( res.first ) == it, NULL ); + // insert + ASSERT( Harness::IsEqual()(*my_c.insert( my_c.begin(), value ), value), NULL ); + // equal_range + std::pair<Iterator, Iterator> r1 = my_c.equal_range( Value<Table>::key( value ) ); + ASSERT( Harness::IsEqual()(*r1.first, value) && ++r1.first == r1.second, NULL ); + std::pair<ConstIterator, ConstIterator> r2 = constC.equal_range( Value<Table>::key( value ) ); + ASSERT( Harness::IsEqual()(*r2.first, value) && ++r2.first == r2.second, NULL ); + + TestMapSpecificMethods<defCtorPresent>( my_c, value ); + } +}; + +#include "tbb/task_scheduler_init.h" + +template <bool defCtorPresent, typename Table> +void CommonExamine( Table c, const std::list<typename Table::value_type> lst) { + typedef typename Table::value_type ValueType; + + ASSERT( !c.empty() && c.size() == lst.size() && c.max_size() >= c.size(), NULL ); + + std::for_each( lst.begin(), lst.end(), CheckValue<defCtorPresent, Table>( c ) ); + + std::vector< tbb::atomic<bool> > marks( lst.size() ); + + TestRange<ValueType>( lst, marks ).doTestRange( c.begin(), c.end() ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + TestRange<ValueType>( lst, marks ).doTestRange( c.begin(), c.end() ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + const Table constC = c; + ASSERT( c.size() == constC.size(), NULL ); + + TestRange<ValueType>( lst, marks ).doTestRange( constC.cbegin(), constC.cend() ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + tbb::task_scheduler_init init; + + tbb::parallel_for( c.range(), TestRange<ValueType>( lst, marks ) ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + tbb::parallel_for( constC.range( ), TestRange<ValueType>( lst, marks ) ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + Table c2; + typename std::list<ValueType>::const_iterator begin5 = lst.begin(); + std::advance( begin5, 5 ); + c2.insert( lst.begin(), begin5 ); + std::for_each( lst.begin(), begin5, CheckValue<defCtorPresent, Table>( c2 ) ); + + c2.swap( c ); + ASSERT( c2.size() == lst.size(), NULL ); + ASSERT( c.size() == 5, NULL ); + std::for_each( lst.begin(), lst.end(), CheckValue<defCtorPresent, Table>( c2 ) ); + + c2.clear(); + ASSERT( c2.size() == 0, NULL ); + + typename Table::allocator_type a = c.get_allocator(); + ValueType *ptr = a.allocate( 1 ); + ASSERT( ptr, NULL ); + a.deallocate( ptr, 1 ); +} + +// overload for set and multiset +// second argument is needed just for right deduction +template <typename Checker> +void TestSetCommonTypes() { + Checker CheckTypes; + const int NUMBER = 10; + + std::list<int> arrInt; + for ( int i = 0; i<NUMBER; ++i ) arrInt.push_back( i ); + CheckTypes.template check</*defCtorPresent = */true>( arrInt ); + + std::list< tbb::atomic<int> > arrTbb(NUMBER); + int seq = 0; + for ( std::list< tbb::atomic<int> >::iterator it = arrTbb.begin(); it != arrTbb.end(); ++it, ++seq ) *it = seq; + CheckTypes.template check</*defCtorPresent = */true>( arrTbb ); + +#if __TBB_CPP11_REFERENCE_WRAPPER_PRESENT && !__TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN + std::list< std::reference_wrapper<int> > arrRef; + for ( std::list<int>::iterator it = arrInt.begin( ); it != arrInt.end( ); ++it ) + arrRef.push_back( std::reference_wrapper<int>(*it) ); + CheckTypes.template check</*defCtorPresent = */false>( arrRef ); +#endif /* __TBB_CPP11_REFERENCE_WRAPPER_PRESENT && !__TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN */ + +#if __TBB_CPP11_SMART_POINTERS_PRESENT + std::list< std::shared_ptr<int> > arrShr; + for ( int i = 0; i<NUMBER; ++i ) arrShr.push_back( std::make_shared<int>( i ) ); + CheckTypes.template check</*defCtorPresent = */true>( arrShr ); + + std::list< std::weak_ptr<int> > arrWk; + std::copy( arrShr.begin( ), arrShr.end( ), std::back_inserter( arrWk ) ); + CheckTypes.template check</*defCtorPresent = */true>( arrWk ); +#else + REPORT( "Known issue: C++11 smart pointer tests are skipped.\n" ); +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ +} + +template <typename Checker> +void TestMapCommonTypes() { + Checker CheckTypes; + const int NUMBER = 10; + + std::list< std::pair<const int, int> > arrIntInt; + for ( int i = 0; i < NUMBER; ++i ) arrIntInt.push_back( std::make_pair( i, NUMBER - i ) ); + CheckTypes.template check</*def_ctor_present = */true>( arrIntInt ); + + std::list< std::pair< const int, tbb::atomic<int> > > arrIntTbb; + for ( int i = 0; i < NUMBER; ++i ) { + tbb::atomic<int> b; + b = NUMBER - i; + arrIntTbb.push_back( std::make_pair( i, b ) ); + } + CheckTypes.template check</*defCtorPresent = */true>( arrIntTbb ); + +#if __TBB_CPP11_REFERENCE_WRAPPER_PRESENT && !__TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN + std::list< std::pair<const std::reference_wrapper<const int>, int> > arrRefInt; + for ( std::list< std::pair<const int, int> >::iterator it = arrIntInt.begin(); it != arrIntInt.end(); ++it ) + arrRefInt.push_back( std::make_pair( std::reference_wrapper<const int>( it->first ), it->second ) ); + CheckTypes.template check</*defCtorPresent = */true>( arrRefInt ); + + std::list< std::pair<const int, std::reference_wrapper<int> > > arrIntRef; + for ( std::list< std::pair<const int, int> >::iterator it = arrIntInt.begin(); it != arrIntInt.end(); ++it ) { + // Using std::make_pair below causes compilation issues with early implementations of std::reference_wrapper. + arrIntRef.push_back( std::pair<const int, std::reference_wrapper<int> >( it->first, std::reference_wrapper<int>( it->second ) ) ); + } + CheckTypes.template check</*defCtorPresent = */false>( arrIntRef ); +#endif /* __TBB_CPP11_REFERENCE_WRAPPER_PRESENT && !__TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN */ + +#if __TBB_CPP11_SMART_POINTERS_PRESENT + std::list< std::pair< const std::shared_ptr<int>, std::shared_ptr<int> > > arrShrShr; + for ( int i = 0; i < NUMBER; ++i ) { + const int NUMBER_minus_i = NUMBER - i; + arrShrShr.push_back( std::make_pair( std::make_shared<int>( i ), std::make_shared<int>( NUMBER_minus_i ) ) ); + } + CheckTypes.template check</*defCtorPresent = */true>( arrShrShr ); + + std::list< std::pair< const std::weak_ptr<int>, std::weak_ptr<int> > > arrWkWk; + std::copy( arrShrShr.begin(), arrShrShr.end(), std::back_inserter( arrWkWk ) ); + CheckTypes.template check</*defCtorPresent = */true>( arrWkWk ); + +#else + REPORT( "Known issue: C++11 smart pointer tests are skipped.\n" ); +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ +} + + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT || __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT +namespace node_handling{ + template<typename Handle> + bool compare_handle_getters( + const Handle& node, const std::pair<typename Handle::key_type, typename Handle::mapped_type>& expected + ) { + return node.key() == expected.first && node.mapped() == expected.second; + } + + template<typename Handle> + bool compare_handle_getters( const Handle& node, const typename Handle::value_type& value) { + return node.value() == value; + } + + template<typename Handle> + void set_node_handle_value( + Handle& node, const std::pair<typename Handle::key_type, typename Handle::mapped_type>& value + ) { + node.key() = value.first; + node.mapped() = value.second; + } + + template<typename Handle> + void set_node_handle_value( Handle& node, const typename Handle::value_type& value) { + node.value() = value; + } + + template <typename node_type> + void TestTraits() { + ASSERT( !std::is_copy_constructible<node_type>::value, + "Node handle: Handle is copy constructable" ); + ASSERT( !std::is_copy_assignable<node_type>::value, + "Node handle: Handle is copy assignable" ); + ASSERT( std::is_move_constructible<node_type>::value, + "Node handle: Handle is not move constructable" ); + ASSERT( std::is_move_assignable<node_type>::value, + "Node handle: Handle is not move constructable" ); + ASSERT( std::is_default_constructible<node_type>::value, + "Node handle: Handle is not default constructable" ); + ASSERT( std::is_destructible<node_type>::value, + "Node handle: Handle is not destructible" ); + } + + template <typename Table> + void TestHandle( Table test_table ) { + ASSERT( test_table.size()>1, "Node handle: Container must contains 2 or more elements" ); + // Initialization + using node_type = typename Table::node_type; + + TestTraits<node_type>(); + + // Default Ctor and empty function + node_type nh; + ASSERT( nh.empty(), "Node handle: Node is not empty after initialization" ); + + // Move Assign + // key/mapped/value function + auto expected_value = *test_table.begin(); + + nh = test_table.unsafe_extract(test_table.begin()); + ASSERT( !nh.empty(), "Node handle: Node handle is empty after valid move assigning" ); + ASSERT( compare_handle_getters(nh,expected_value), + "Node handle: After valid move assigning " + "node handle does not contains expected value"); + + // Move Ctor + // key/mapped/value function + node_type nh2(std::move(nh)); + ASSERT( nh.empty(), "Node handle: After valid move construction node handle is empty" ); + ASSERT( !nh2.empty(), "Node handle: After valid move construction " + "argument hode handle was not moved" ); + ASSERT( compare_handle_getters(nh2,expected_value), + "Node handle: After valid move construction " + "node handle does not contains expected value" ); + + // Bool conversion + ASSERT( nh2, "Node handle: Wrong not handle bool conversion" ); + + // Change key/mapped/value of node handle + auto expected_value2 = *test_table.begin(); + set_node_handle_value(nh2, expected_value2); + ASSERT( compare_handle_getters(nh2, expected_value2), + "Node handle: Wrong node handle key/mapped/value changing behavior" ); + + // Member/non member swap check + node_type empty_node; + // We extract this element for nh2 and nh3 difference + test_table.unsafe_extract(test_table.begin()); + auto expected_value3 = *test_table.begin(); + node_type nh3(test_table.unsafe_extract(test_table.begin())); + + // Both of node handles are not empty + nh3.swap(nh2); + ASSERT( compare_handle_getters(nh3, expected_value2), + "Node handle: Wrong node handle swap behavior" ); + ASSERT( compare_handle_getters(nh2, expected_value3), + "Node handle: Wrong node handle swap behavior" ); + + std::swap(nh2,nh3); + ASSERT( compare_handle_getters(nh3, expected_value3), + "Node handle: Wrong node handle swap behavior" ); + ASSERT( compare_handle_getters(nh2, expected_value2), + "Node handle: Wrong node handle swap behavior" ); + ASSERT( !nh2.empty(), "Node handle: Wrong node handle swap behavior" ); + ASSERT( !nh3.empty(), "Node handle: Wrong node handle swap behavior" ); + + // One of nodes is empty + nh3.swap(empty_node); + ASSERT( compare_handle_getters(std::move(empty_node), expected_value3), + "Node handle: Wrong node handle swap behavior" ); + ASSERT( nh3.empty(), "Node handle: Wrong node handle swap behavior" ); + + std::swap(empty_node, nh3); + ASSERT( compare_handle_getters(std::move(nh3), expected_value3), + "Node handle: Wrong node handle swap behavior" ); + ASSERT( empty_node.empty(), "Node handle: Wrong node handle swap behavior" ); + + empty_node.swap(nh3); + ASSERT( compare_handle_getters(std::move(empty_node), expected_value3), + "Node handle: Wrong node handle swap behavior" ); + ASSERT( nh3.empty(), "Node handle: Wrong node handle swap behavior" ); + } + + template <typename Table> + typename Table::node_type GenerateNodeHandle(const typename Table::value_type& value) { + Table temp_table; + temp_table.insert(value); + return temp_table.unsafe_extract(temp_table.cbegin()); + } + + template <typename Table> + void IteratorAssertion( const Table& table, + const typename Table::iterator& result, + const typename Table::value_type* node_value = nullptr ) { + if (node_value==nullptr) { + ASSERT( result==table.end(), "Insert: Result iterator does not " + "contains end pointer after empty node insertion" ); + } else { + if (!Table::allow_multimapping) { + ASSERT( result==table.find(Value<Table>::key( *node_value )) && + result != table.end(), + "Insert: After node insertion result iterator" + " doesn't contains address to equal element in table" ); + } else { + ASSERT( *result==*node_value, "Insert: Result iterator contains" + "wrong content after successful insertion" ); + + for (auto it = table.begin(); it != table.end(); ++it) { + if (it == result) return; + } + ASSERT( false, "Insert: After successful insertion result " + "iterator contains address that is not in the table" ); + } + } + } + // overload for multitable or insertion with hint iterator + template <typename Table> + void InsertAssertion( const Table& table, + const typename Table::iterator& result, + bool, + const typename Table::value_type* node_value = nullptr ) { + IteratorAssertion(table, result, node_value); + } + + // Not multitable overload + template <typename Table> + void InsertAssertion( const Table& table, + const std::pair<typename Table::iterator, bool>& result, + bool second_value, + const typename Table::value_type* node_value = nullptr ) { + IteratorAssertion(table, result.first, node_value); + + ASSERT( result.second == second_value || Table::allow_multimapping, + "Insert: Returned bool wrong value after node insertion" ); + } + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + // Internal func for testing + // Can't delete ref from "Table" argument because hint must point to element of table + namespace { + template <typename Table, typename... Hint> + void TestInsertOverloads( Table& table_to_insert, + const typename Table::value_type &value, const Hint&... hint ) { + // Insert empty element + typename Table::node_type nh; + + auto table_size = table_to_insert.size(); + auto result = table_to_insert.insert(hint..., std::move(nh)); + InsertAssertion(table_to_insert, result, /*second_value*/ false); + ASSERT( table_to_insert.size() == table_size, + "Insert: After empty node insertion table size changed" ); + + // Standard insertion + nh = GenerateNodeHandle<Table>(value); + + result = table_to_insert.insert(hint..., std::move(nh)); + ASSERT( nh.empty(), "Insert: Not empty handle after successful insertion" ); + InsertAssertion(table_to_insert, result, /*second_value*/ true, &value); + + // Insert existing node + nh = GenerateNodeHandle<Table>(value); + + result = table_to_insert.insert(hint..., std::move(nh)); + + InsertAssertion(table_to_insert, result, /*second_value*/ false, &value); + + if (Table::allow_multimapping){ + ASSERT( nh.empty(), "Insert: Failed insertion to multitable" ); + } else { + ASSERT( !nh.empty() , "Insert: Empty handle after failed insertion" ); + ASSERT( compare_handle_getters( std::move(nh), value ), + "Insert: Existing data does not equal to the one being inserted" ); + } + } + } + + template <typename Table> + void TestInsert( Table table, const typename Table::value_type & value) { + ASSERT( !table.empty(), "Insert: Map should contains 1 or more elements" ); + Table table_backup(table); + TestInsertOverloads(table, value); + TestInsertOverloads(table_backup, value, table_backup.begin()); + } +#endif /*__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT*/ + + template <typename Table> + void TestExtract( Table table_for_extract, typename Table::key_type new_key ) { + ASSERT( table_for_extract.size()>1, "Extract: Container must contains 2 or more element" ); + ASSERT( table_for_extract.find(new_key)==table_for_extract.end(), + "Extract: Table must not contains new element!"); + + // Extract new element + auto nh = table_for_extract.unsafe_extract(new_key); + ASSERT( nh.empty(), "Extract: Node handle is not empty after wrong key extraction" ); + + // Valid key extraction + auto expected_value = *table_for_extract.cbegin(); + auto key = Value<Table>::key( expected_value ); + auto count = table_for_extract.count(key); + + nh = table_for_extract.unsafe_extract(key); + ASSERT( !nh.empty(), + "Extract: After successful extraction by key node handle is empty" ); + ASSERT( compare_handle_getters(std::move(nh), expected_value), + "Extract: After successful extraction by key node handle contains wrong value" ); + ASSERT( table_for_extract.count(key) == count - 1, + "Extract: After successful node extraction by key, table still contains this key" ); + + // Valid iterator overload + auto expected_value2 = *table_for_extract.cbegin(); + auto key2 = Value<Table>::key( expected_value2 ); + auto count2 = table_for_extract.count(key2); + + nh = table_for_extract.unsafe_extract(table_for_extract.cbegin()); + ASSERT( !nh.empty(), + "Extract: After successful extraction by iterator node handle is empty" ); + ASSERT( compare_handle_getters(std::move(nh), expected_value2), + "Extract: After successful extraction by iterator node handle contains wrong value" ); + ASSERT( table_for_extract.count(key2) == count2 - 1, + "Extract: After successful extraction table also contains this element" ); + } + + // All test exclude merge + template <typename Table> + void NodeHandlingTests ( const Table& table, + const typename Table::value_type& new_value) { + TestHandle(table); +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + TestInsert(table, new_value); +#endif /*__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT*/ + TestExtract(table, Value<Table>::key( new_value )); + } + + template <typename TableType1, typename TableType2> + void TestMerge( TableType1 table1, TableType2&& table2 ) { + using Table2PureType = typename std::decay<TableType2>::type; + // Initialization + TableType1 table1_backup = table1; + // For copying lvalue + Table2PureType table2_backup = table2; + + table1.merge(std::forward<TableType2>(table2)); + for (auto it: table2) { + ASSERT( table1.find( Value<Table2PureType>::key( it ) ) != table1.end(), + "Merge: Some key(s) was not merged" ); + } + + // After the following step table1 will contains only merged elements from table2 + for (auto it: table1_backup) { + table1.unsafe_extract(Value<TableType1>::key( it )); + } + // After the following step table2_backup will contains only merged elements from table2 + for (auto it: table2) { + table2_backup.unsafe_extract(Value<Table2PureType>::key( it )); + } + + ASSERT ( table1.size() == table2_backup.size(), "Merge: Size of tables is not equal" ); + for (auto it: table2_backup) { + ASSERT( table1.find( Value<Table2PureType>::key( it ) ) != table1.end(), + "Merge: Wrong merge behavior" ); + } + } + + // Testing of rvalue and lvalue overloads + template <typename TableType1, typename TableType2> + void TestMergeOverloads( const TableType1& table1, TableType2 table2 ) { + TableType2 table_backup(table2); + TestMerge(table1, table2); + TestMerge(table1, std::move(table_backup)); + } + + template <typename Table, typename MultiTable> + void TestMergeTransposition( Table table1, Table table2, + MultiTable multitable1, MultiTable multitable2 ) { + Table empty_map; + MultiTable empty_multimap; + + // Map transpositions + node_handling::TestMergeOverloads(table1, table2); + node_handling::TestMergeOverloads(table1, empty_map); + node_handling::TestMergeOverloads(empty_map, table2); + + // Multimap transpositions + node_handling::TestMergeOverloads(multitable1, multitable2); + node_handling::TestMergeOverloads(multitable1, empty_multimap); + node_handling::TestMergeOverloads(empty_multimap, multitable2); + + // Map/Multimap transposition + node_handling::TestMergeOverloads(table1, multitable1); + node_handling::TestMergeOverloads(multitable2, table2); + } + + template <typename SrcTableType, typename DestTableType> + void AssertionConcurrentMerge ( SrcTableType& start_data, DestTableType& dest_table, + std::vector<SrcTableType>& src_tables, std::true_type) { + ASSERT( dest_table.size() == start_data.size() * src_tables.size(), + "Merge: Incorrect merge for some elements" ); + + for(auto it: start_data) { + ASSERT( dest_table.count( Value<DestTableType>::key( it ) ) == + start_data.count( Value<SrcTableType>::key( it ) ) * src_tables.size(), + "Merge: Incorrect merge for some element" ); + } + + for (size_t i = 0; i < src_tables.size(); i++) { + ASSERT( src_tables[i].empty(), "Merge: Some elements were not merged" ); + } + } + + template <typename SrcTableType, typename DestTableType> + void AssertionConcurrentMerge ( SrcTableType& start_data, DestTableType& dest_table, + std::vector<SrcTableType>& src_tables, std::false_type) { + SrcTableType expected_result; + for (auto table: src_tables) + for (auto it: start_data) { + // If we cannot find some element in some table, then it has been moved + if (table.find( Value<SrcTableType>::key( it ) ) == table.end()){ + bool result = expected_result.insert( it ).second; + ASSERT( result, "Merge: Some element was merged twice or was not " + "returned to his owner after unsuccessful merge"); + } + } + + ASSERT( expected_result.size() == dest_table.size() && start_data.size() == dest_table.size(), + "Merge: wrong size of result table"); + for (auto it: expected_result) { + if ( dest_table.find( Value<SrcTableType>::key( it ) ) != dest_table.end() && + start_data.find( Value<DestTableType>::key( it ) ) != start_data.end() ){ + dest_table.unsafe_extract(Value<SrcTableType>::key( it )); + start_data.unsafe_extract(Value<DestTableType>::key( it )); + } else { + ASSERT( false, "Merge: Incorrect merge for some element" ); + } + } + + ASSERT( dest_table.empty()&&start_data.empty(), "Merge: Some elements were not merged" ); + } + + template <typename SrcTableType, typename DestTableType> + void TestConcurrentMerge (SrcTableType table_data) { + for (auto num_threads = MinThread + 1; num_threads <= MaxThread; num_threads++){ + std::vector<SrcTableType> src_tables; + DestTableType dest_table; + + for (auto j = 0; j < num_threads; j++){ + src_tables.push_back(table_data); + } + + NativeParallelFor( num_threads, [&](size_t index){ dest_table.merge(src_tables[index]); } ); + + AssertionConcurrentMerge( table_data, dest_table, src_tables, + std::integral_constant<bool, DestTableType::allow_multimapping>{}); + } + } + + template <typename Table> + void TestNodeHandling(){ + Table table; + + for (int i = 1; i < 5; i++) + table.insert(Value<Table>::make(i)); + + if (Table::allow_multimapping) + table.insert(Value<Table>::make(4)); + + node_handling::NodeHandlingTests(table, Value<Table>::make(5)); + } + + template <typename TableType1, typename TableType2> + void TestMerge(int size){ + TableType1 table1_1; + TableType1 table1_2; + int i = 1; + for (; i < 5; ++i) { + table1_1.insert(Value<TableType1>::make(i)); + table1_2.insert(Value<TableType1>::make(i*i)); + } + if (TableType1::allow_multimapping) { + table1_1.insert(Value<TableType1>::make(i)); + table1_2.insert(Value<TableType1>::make(i*i)); + } + + TableType2 table2_1; + TableType2 table2_2; + for (i = 3; i < 7; ++i) { + table1_1.insert(Value<TableType2>::make(i)); + table1_2.insert(Value<TableType2>::make(i*i)); + } + if (TableType2::allow_multimapping) { + table2_1.insert(Value<TableType2>::make(i)); + table2_2.insert(Value<TableType2>::make(i*i)); + } + + node_handling::TestMergeTransposition(table1_1, table1_2, + table2_1, table2_2); + + TableType1 table1_3; + for (i = 0; i<size; ++i){ + table1_3.insert(Value<TableType1>::make(i)); + } + node_handling::TestConcurrentMerge<TableType1, TableType2>(table1_3); + + TableType2 table2_3; + for (i = 0; i<size; ++i){ + table2_3.insert(Value<TableType2>::make(i)); + } + node_handling::TestConcurrentMerge<TableType2, TableType1>(table2_3); +} +} +#endif // __TBB_UNORDERED_NODE_HANDLE_PRESENT || __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_hash_map.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_hash_map.cpp new file mode 100644 index 00000000..d9b13323 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_hash_map.cpp @@ -0,0 +1,1713 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef TBB_USE_PERFORMANCE_WARNINGS +#define TBB_USE_PERFORMANCE_WARNINGS 1 +#endif + +// Our tests usually include the header under test first. But this test needs +// to use the preprocessor to edit the identifier runtime_warning in concurrent_hash_map.h. +// Hence we include a few other headers before doing the abusive edit. +#include "tbb/tbb_stddef.h" /* Defines runtime_warning */ +#include "harness_assert.h" /* Prerequisite for defining hooked_warning */ + +// The symbol internal::runtime_warning is normally an entry point into the TBB library. +// Here for sake of testing, we define it to be hooked_warning, a routine peculiar to this unit test. +#define runtime_warning hooked_warning + +static bool bad_hashing = false; + +namespace tbb { + namespace internal { + static void hooked_warning( const char* /*format*/, ... ) { + ASSERT(bad_hashing, "unexpected runtime_warning: bad hashing"); + } + } // namespace internal +} // namespace tbb +#define __TBB_EXTRA_DEBUG 1 // enables additional checks +#include "tbb/concurrent_hash_map.h" + +// Restore runtime_warning as an entry point into the TBB library. +#undef runtime_warning + +namespace Jungle { + struct Tiger {}; + size_t tbb_hasher( const Tiger& ) {return 0;} +} + +#if !defined(_MSC_VER) || _MSC_VER>=1400 || __INTEL_COMPILER +void test_ADL() { + tbb::tbb_hash_compare<Jungle::Tiger>::hash(Jungle::Tiger()); // Instantiation chain finds tbb_hasher via Argument Dependent Lookup +} +#endif + +struct UserDefinedKeyType { +}; + +namespace tbb { + // Test whether tbb_hash_compare can be partially specialized as stated in Reference manual. + template<> struct tbb_hash_compare<UserDefinedKeyType> { + size_t hash( UserDefinedKeyType ) const {return 0;} + bool equal( UserDefinedKeyType /*x*/, UserDefinedKeyType /*y*/ ) {return true;} + }; +} + +#include "harness_runtime_loader.h" + +tbb::concurrent_hash_map<UserDefinedKeyType,int> TestInstantiationWithUserDefinedKeyType; + +// Test whether a sufficient set of headers were included to instantiate a concurrent_hash_map. OSS Bug #120 (& #130): +// http://www.threadingbuildingblocks.org/bug_desc.php?id=120 +tbb::concurrent_hash_map<std::pair<std::pair<int,std::string>,const char*>,int> TestInstantiation; + +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" +#include "tbb/atomic.h" +#include "tbb/tick_count.h" +#include "harness.h" +#include "harness_allocator.h" + +class MyException : public std::bad_alloc { +public: + virtual const char *what() const throw() __TBB_override { return "out of items limit"; } + virtual ~MyException() throw() {} +}; + +/** Has tightly controlled interface so that we can verify + that concurrent_hash_map uses only the required interface. */ +class MyKey { +private: + void operator=( const MyKey& ); // Deny access + int key; + friend class MyHashCompare; + friend class YourHashCompare; +public: + static MyKey make( int i ) { + MyKey result; + result.key = i; + return result; + } + int value_of() const {return key;} +}; +//TODO: unify with Harness::Foo ? +tbb::atomic<long> MyDataCount; +long MyDataCountLimit = 0; + +class MyData { +protected: + friend class MyData2; + int data; + enum state_t { + LIVE=0x1234, + DEAD=0x5678 + } my_state; + void operator=( const MyData& ); // Deny access +public: + MyData(int i = 0) { + my_state = LIVE; + data = i; + if(MyDataCountLimit && MyDataCount + 1 >= MyDataCountLimit) + __TBB_THROW( MyException() ); + ++MyDataCount; + } + MyData( const MyData& other ) { + ASSERT( other.my_state==LIVE, NULL ); + my_state = LIVE; + data = other.data; + if(MyDataCountLimit && MyDataCount + 1 >= MyDataCountLimit) + __TBB_THROW( MyException() ); + ++MyDataCount; + } + ~MyData() { + --MyDataCount; + my_state = DEAD; + } + static MyData make( int i ) { + MyData result; + result.data = i; + return result; + } + int value_of() const { + ASSERT( my_state==LIVE, NULL ); + return data; + } + void set_value( int i ) { + ASSERT( my_state==LIVE, NULL ); + data = i; + } + bool operator==( const MyData& other ) const { + ASSERT( other.my_state==LIVE, NULL ); + ASSERT( my_state==LIVE, NULL ); + return data == other.data; + } +}; + +class MyData2 : public MyData { +public: + MyData2( ) {} + MyData2( const MyData& other ) { + ASSERT( other.my_state==LIVE, NULL ); + ASSERT( my_state==LIVE, NULL ); + data = other.data; + } + void operator=( const MyData& other ) { + ASSERT( other.my_state==LIVE, NULL ); + ASSERT( my_state==LIVE, NULL ); + data = other.data; + } + void operator=( const MyData2& other ) { + ASSERT( other.my_state==LIVE, NULL ); + ASSERT( my_state==LIVE, NULL ); + data = other.data; + } + bool operator==( const MyData2& other ) const { + ASSERT( other.my_state==LIVE, NULL ); + ASSERT( my_state==LIVE, NULL ); + return data == other.data; + } +}; + +class MyHashCompare { +public: + bool equal( const MyKey& j, const MyKey& k ) const { + return j.key==k.key; + } + unsigned long hash( const MyKey& k ) const { + return k.key; + } +}; + +class YourHashCompare { +public: + bool equal( const MyKey& j, const MyKey& k ) const { + return j.key==k.key; + } + unsigned long hash( const MyKey& ) const { + return 1; + } +}; + +typedef local_counting_allocator<std::allocator<MyData> > MyAllocator; +typedef tbb::concurrent_hash_map<MyKey,MyData,MyHashCompare,MyAllocator> MyTable; +typedef tbb::concurrent_hash_map<MyKey,MyData2,MyHashCompare> MyTable2; +typedef tbb::concurrent_hash_map<MyKey,MyData,YourHashCompare> YourTable; + +template<typename MyTable> +inline void CheckAllocator(MyTable &table, size_t expected_allocs, size_t expected_frees, bool exact = true) { + size_t items_allocated = table.get_allocator().items_allocated, items_freed = table.get_allocator().items_freed; + size_t allocations = table.get_allocator().allocations, frees = table.get_allocator().frees; + REMARK("checking allocators: items %u/%u, allocs %u/%u\n", + unsigned(items_allocated), unsigned(items_freed), unsigned(allocations), unsigned(frees) ); + ASSERT( items_allocated == allocations, NULL); ASSERT( items_freed == frees, NULL); + if(exact) { + ASSERT( allocations == expected_allocs, NULL); ASSERT( frees == expected_frees, NULL); + } else { + ASSERT( allocations >= expected_allocs, NULL); ASSERT( frees >= expected_frees, NULL); + ASSERT( allocations - frees == expected_allocs - expected_frees, NULL ); + } +} + +inline bool UseKey( size_t i ) { + return (i&3)!=3; +} + +struct Insert { + static void apply( MyTable& table, int i ) { + if( UseKey(i) ) { + if( i&4 ) { + MyTable::accessor a; + table.insert( a, MyKey::make(i) ); + if( i&1 ) + (*a).second.set_value(i*i); + else + a->second.set_value(i*i); + } else + if( i&1 ) { + MyTable::accessor a; + table.insert( a, std::make_pair(MyKey::make(i), MyData(i*i)) ); + ASSERT( (*a).second.value_of()==i*i, NULL ); + } else { + MyTable::const_accessor ca; + table.insert( ca, std::make_pair(MyKey::make(i), MyData(i*i)) ); + ASSERT( ca->second.value_of()==i*i, NULL ); + } + } + } +}; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +#include "test_container_move_support.h" +typedef tbb::concurrent_hash_map<MyKey,Foo,MyHashCompare> DataStateTrackedTable; + +struct RvalueInsert { + static void apply( DataStateTrackedTable& table, int i ) { + DataStateTrackedTable::accessor a; + ASSERT( (table.insert( a, std::make_pair(MyKey::make(i), Foo(i + 1)))),"already present while should not ?" ); + ASSERT( (*a).second == i + 1, NULL ); + ASSERT( (*a).second.state == Harness::StateTrackableBase::MoveInitialized, ""); + } +}; + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +struct Emplace { + static void apply( DataStateTrackedTable& table, int i ) { + DataStateTrackedTable::accessor a; + ASSERT( (table.emplace( a, MyKey::make(i), (i + 1))),"already present while should not ?" ); + ASSERT( (*a).second == i + 1, NULL ); + ASSERT( (*a).second.state == Harness::StateTrackableBase::DirectInitialized, ""); + } +}; +#endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + +#if __TBB_INITIALIZER_LISTS_PRESENT +struct InsertInitList { + static void apply( MyTable& table, int i ) { + if ( UseKey( i ) ) { + // TODO: investigate why the following sequence causes an additional allocation sometimes: + // table.insert( MyTable::value_type( MyKey::make( i ), i*i ) ); + // table.insert( MyTable::value_type( MyKey::make( i ), i*i+1 ) ); + std::initializer_list<MyTable::value_type> il = { MyTable::value_type( MyKey::make( i ), i*i )/*, MyTable::value_type( MyKey::make( i ), i*i+1 ) */ }; + table.insert( il ); + } + } +}; +#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ + +struct Find { + static void apply( MyTable& table, int i ) { + MyTable::accessor a; + const MyTable::accessor& ca = a; + bool b = table.find( a, MyKey::make(i) ); + ASSERT( b==!a.empty(), NULL ); + if( b ) { + if( !UseKey(i) ) + REPORT("Line %d: unexpected key %d present\n",__LINE__,i); + AssertSameType( &*a, static_cast<MyTable::value_type*>(0) ); + ASSERT( ca->second.value_of()==i*i, NULL ); + ASSERT( (*ca).second.value_of()==i*i, NULL ); + if( i&1 ) + ca->second.set_value( ~ca->second.value_of() ); + else + (*ca).second.set_value( ~ca->second.value_of() ); + } else { + if( UseKey(i) ) + REPORT("Line %d: key %d missing\n",__LINE__,i); + } + } +}; + +struct FindConst { + static void apply( const MyTable& table, int i ) { + MyTable::const_accessor a; + const MyTable::const_accessor& ca = a; + bool b = table.find( a, MyKey::make(i) ); + ASSERT( b==(table.count(MyKey::make(i))>0), NULL ); + ASSERT( b==!a.empty(), NULL ); + ASSERT( b==UseKey(i), NULL ); + if( b ) { + AssertSameType( &*ca, static_cast<const MyTable::value_type*>(0) ); + ASSERT( ca->second.value_of()==~(i*i), NULL ); + ASSERT( (*ca).second.value_of()==~(i*i), NULL ); + } + } +}; + +tbb::atomic<int> EraseCount; + +struct Erase { + static void apply( MyTable& table, int i ) { + bool b; + if(i&4) { + if(i&8) { + MyTable::const_accessor a; + b = table.find( a, MyKey::make(i) ) && table.erase( a ); + } else { + MyTable::accessor a; + b = table.find( a, MyKey::make(i) ) && table.erase( a ); + } + } else + b = table.erase( MyKey::make(i) ); + if( b ) ++EraseCount; + ASSERT( table.count(MyKey::make(i)) == 0, NULL ); + } +}; + +static const int IE_SIZE = 2; +tbb::atomic<YourTable::size_type> InsertEraseCount[IE_SIZE]; + +struct InsertErase { + static void apply( YourTable& table, int i ) { + if ( i%3 ) { + int key = i%IE_SIZE; + if ( table.insert( std::make_pair(MyKey::make(key), MyData2()) ) ) + ++InsertEraseCount[key]; + } else { + int key = i%IE_SIZE; + if( i&1 ) { + YourTable::accessor res; + if(table.find( res, MyKey::make(key) ) && table.erase( res ) ) + --InsertEraseCount[key]; + } else { + YourTable::const_accessor res; + if(table.find( res, MyKey::make(key) ) && table.erase( res ) ) + --InsertEraseCount[key]; + } + } + } +}; + +// Test for the deadlock discussed at: +// http://softwarecommunity.intel.com/isn/Community/en-US/forums/permalink/30253302/30253302/ShowThread.aspx#30253302 +struct InnerInsert { + static void apply( YourTable& table, int i ) { + YourTable::accessor a1, a2; + if(i&1) __TBB_Yield(); + table.insert( a1, MyKey::make(1) ); + __TBB_Yield(); + table.insert( a2, MyKey::make(1 + (1<<30)) ); // the same chain + table.erase( a2 ); // if erase by key it would lead to deadlock for single thread + } +}; + +#include "harness_barrier.h" +// Test for the misuse of constness +struct FakeExclusive : NoAssign { + Harness::SpinBarrier& barrier; + YourTable& table; + FakeExclusive(Harness::SpinBarrier& b, YourTable&t) : barrier(b), table(t) {} + void operator()( int i ) const { + if(i) { + YourTable::const_accessor real_ca; + // const accessor on non-const table acquired as reader (shared) + ASSERT( table.find(real_ca,MyKey::make(1)), NULL ); + barrier.wait(); // item can be erased + Harness::Sleep(10); // let it enter the erase + real_ca->second.value_of(); // check the state while holding accessor + } else { + YourTable::accessor fake_ca; + const YourTable &const_table = table; + // non-const accessor on const table acquired as reader (shared) + ASSERT( const_table.find(fake_ca,MyKey::make(1)), NULL ); + barrier.wait(); // readers acquired + // can mistakenly remove the item while other readers still refers to it + table.erase( fake_ca ); + } + } +}; + +template<typename Op, typename MyTable> +class TableOperation: NoAssign { + MyTable& my_table; +public: + void operator()( const tbb::blocked_range<int>& range ) const { + for( int i=range.begin(); i!=range.end(); ++i ) + Op::apply(my_table,i); + } + TableOperation( MyTable& table ) : my_table(table) {} +}; + +template<typename Op, typename TableType> +void DoConcurrentOperations( TableType& table, int n, const char* what, int nthread ) { + REMARK("testing %s with %d threads\n",what,nthread); + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for( tbb::blocked_range<int>(0,n,100), TableOperation<Op,TableType>(table) ); + tbb::tick_count t1 = tbb::tick_count::now(); + REMARK("time for %s = %g with %d threads\n",what,(t1-t0).seconds(),nthread); +} + +//! Test traversing the table with an iterator. +void TraverseTable( MyTable& table, size_t n, size_t expected_size ) { + REMARK("testing traversal\n"); + size_t actual_size = table.size(); + ASSERT( actual_size==expected_size, NULL ); + size_t count = 0; + bool* array = new bool[n]; + memset( array, 0, n*sizeof(bool) ); + const MyTable& const_table = table; + MyTable::const_iterator ci = const_table.begin(); + for( MyTable::iterator i = table.begin(); i!=table.end(); ++i ) { + // Check iterator + int k = i->first.value_of(); + ASSERT( UseKey(k), NULL ); + ASSERT( (*i).first.value_of()==k, NULL ); + ASSERT( 0<=k && size_t(k)<n, "out of bounds key" ); + ASSERT( !array[k], "duplicate key" ); + array[k] = true; + ++count; + + // Check lower/upper bounds + std::pair<MyTable::iterator, MyTable::iterator> er = table.equal_range(i->first); + std::pair<MyTable::const_iterator, MyTable::const_iterator> cer = const_table.equal_range(i->first); + ASSERT(cer.first == er.first && cer.second == er.second, NULL); + ASSERT(cer.first == i, NULL); + ASSERT(std::distance(cer.first, cer.second) == 1, NULL); + + // Check const_iterator + MyTable::const_iterator cic = ci++; + ASSERT( cic->first.value_of()==k, NULL ); + ASSERT( (*cic).first.value_of()==k, NULL ); + } + ASSERT( ci==const_table.end(), NULL ); + delete[] array; + if( count!=expected_size ) { + REPORT("Line %d: count=%ld but should be %ld\n",__LINE__,long(count),long(expected_size)); + } +} + +typedef tbb::atomic<unsigned char> AtomicByte; + +template<typename RangeType> +struct ParallelTraverseBody: NoAssign { + const size_t n; + AtomicByte* const array; + ParallelTraverseBody( AtomicByte array_[], size_t n_ ) : + n(n_), + array(array_) + {} + void operator()( const RangeType& range ) const { + for( typename RangeType::iterator i = range.begin(); i!=range.end(); ++i ) { + int k = i->first.value_of(); + ASSERT( 0<=k && size_t(k)<n, NULL ); + ++array[k]; + } + } +}; + +void Check( AtomicByte array[], size_t n, size_t expected_size ) { + if( expected_size ) + for( size_t k=0; k<n; ++k ) { + if( array[k] != int(UseKey(k)) ) { + REPORT("array[%d]=%d != %d=UseKey(%d)\n", + int(k), int(array[k]), int(UseKey(k)), int(k)); + ASSERT(false,NULL); + } + } +} + +//! Test traversing the table with a parallel range +void ParallelTraverseTable( MyTable& table, size_t n, size_t expected_size ) { + REMARK("testing parallel traversal\n"); + ASSERT( table.size()==expected_size, NULL ); + AtomicByte* array = new AtomicByte[n]; + + memset( static_cast<void*>(array), 0, n*sizeof(AtomicByte) ); + MyTable::range_type r = table.range(10); + tbb::parallel_for( r, ParallelTraverseBody<MyTable::range_type>( array, n )); + Check( array, n, expected_size ); + + const MyTable& const_table = table; + memset( static_cast<void*>(array), 0, n*sizeof(AtomicByte) ); + MyTable::const_range_type cr = const_table.range(10); + tbb::parallel_for( cr, ParallelTraverseBody<MyTable::const_range_type>( array, n )); + Check( array, n, expected_size ); + + delete[] array; +} + +void TestInsertFindErase( int nthread ) { + int n=250000; + + // compute m = number of unique keys + int m = 0; + for( int i=0; i<n; ++i ) + m += UseKey(i); + + MyAllocator a; a.items_freed = a.frees = 100; + ASSERT( MyDataCount==0, NULL ); + MyTable table(a); + TraverseTable(table,n,0); + ParallelTraverseTable(table,n,0); + CheckAllocator(table, 0, 100); + + int expected_allocs = 0, expected_frees = 100; +#if __TBB_INITIALIZER_LISTS_PRESENT + for ( int i = 0; i < 2; ++i ) { + if ( i==0 ) + DoConcurrentOperations<InsertInitList, MyTable>( table, n, "insert(std::initializer_list)", nthread ); + else +#endif + DoConcurrentOperations<Insert, MyTable>( table, n, "insert", nthread ); + ASSERT( MyDataCount == m, NULL ); + TraverseTable( table, n, m ); + ParallelTraverseTable( table, n, m ); + expected_allocs += m; + CheckAllocator( table, expected_allocs, expected_frees ); + + DoConcurrentOperations<Find, MyTable>( table, n, "find", nthread ); + ASSERT( MyDataCount == m, NULL ); + CheckAllocator( table, expected_allocs, expected_frees ); + + DoConcurrentOperations<FindConst, MyTable>( table, n, "find(const)", nthread ); + ASSERT( MyDataCount == m, NULL ); + CheckAllocator( table, expected_allocs, expected_frees ); + + EraseCount = 0; + DoConcurrentOperations<Erase, MyTable>( table, n, "erase", nthread ); + ASSERT( EraseCount == m, NULL ); + ASSERT( MyDataCount == 0, NULL ); + TraverseTable( table, n, 0 ); + expected_frees += m; + CheckAllocator( table, expected_allocs, expected_frees ); + + bad_hashing = true; + table.clear(); + bad_hashing = false; +#if __TBB_INITIALIZER_LISTS_PRESENT + } +#endif + + if(nthread > 1) { + YourTable ie_table; + for( int i=0; i<IE_SIZE; ++i ) + InsertEraseCount[i] = 0; + DoConcurrentOperations<InsertErase,YourTable>(ie_table,n/2,"insert_erase",nthread); + for( int i=0; i<IE_SIZE; ++i ) + ASSERT( InsertEraseCount[i]==ie_table.count(MyKey::make(i)), NULL ); + + DoConcurrentOperations<InnerInsert,YourTable>(ie_table,2000,"inner insert",nthread); + Harness::SpinBarrier barrier(nthread); + REMARK("testing erase on fake exclusive accessor\n"); + NativeParallelFor( nthread, FakeExclusive(barrier, ie_table)); + } +} + +volatile int Counter; + +class AddToTable: NoAssign { + MyTable& my_table; + const int my_nthread; + const int my_m; +public: + AddToTable( MyTable& table, int nthread, int m ) : my_table(table), my_nthread(nthread), my_m(m) {} + void operator()( int ) const { + for( int i=0; i<my_m; ++i ) { + // Busy wait to synchronize threads + int j = 0; + while( Counter<i ) { + if( ++j==1000000 ) { + // If Counter<i after a million iterations, then we almost surely have + // more logical threads than physical threads, and should yield in + // order to let suspended logical threads make progress. + j = 0; + __TBB_Yield(); + } + } + // Now all threads attempt to simultaneously insert a key. + int k; + { + MyTable::accessor a; + MyKey key = MyKey::make(i); + if( my_table.insert( a, key ) ) + a->second.set_value( 1 ); + else + a->second.set_value( a->second.value_of()+1 ); + k = a->second.value_of(); + } + if( k==my_nthread ) + Counter=i+1; + } + } +}; + +class RemoveFromTable: NoAssign { + MyTable& my_table; + const int my_m; +public: + RemoveFromTable( MyTable& table, int m ) : my_table(table), my_m(m) {} + void operator()(int) const { + for( int i=0; i<my_m; ++i ) { + bool b; + if(i&4) { + if(i&8) { + MyTable::const_accessor a; + b = my_table.find( a, MyKey::make(i) ) && my_table.erase( a ); + } else { + MyTable::accessor a; + b = my_table.find( a, MyKey::make(i) ) && my_table.erase( a ); + } + } else + b = my_table.erase( MyKey::make(i) ); + if( b ) ++EraseCount; + } + } +}; + +//! Test for memory leak in concurrent_hash_map (TR #153). +void TestConcurrency( int nthread ) { + REMARK("testing multiple insertions/deletions of same key with %d threads\n", nthread); + { + ASSERT( MyDataCount==0, NULL ); + MyTable table; + const int m = 1000; + Counter = 0; + tbb::tick_count t0 = tbb::tick_count::now(); + NativeParallelFor( nthread, AddToTable(table,nthread,m) ); + tbb::tick_count t1 = tbb::tick_count::now(); + REMARK("time for %u insertions = %g with %d threads\n",unsigned(MyDataCount),(t1-t0).seconds(),nthread); + ASSERT( MyDataCount==m, "memory leak detected" ); + + EraseCount = 0; + t0 = tbb::tick_count::now(); + NativeParallelFor( nthread, RemoveFromTable(table,m) ); + t1 = tbb::tick_count::now(); + REMARK("time for %u deletions = %g with %d threads\n",unsigned(EraseCount),(t1-t0).seconds(),nthread); + ASSERT( MyDataCount==0, "memory leak detected" ); + ASSERT( EraseCount==m, "return value of erase() is broken" ); + + CheckAllocator(table, m, m, /*exact*/nthread <= 1); + } + ASSERT( MyDataCount==0, "memory leak detected" ); +} + +void TestTypes() { + AssertSameType( static_cast<MyTable::key_type*>(0), static_cast<MyKey*>(0) ); + AssertSameType( static_cast<MyTable::mapped_type*>(0), static_cast<MyData*>(0) ); + AssertSameType( static_cast<MyTable::value_type*>(0), static_cast<std::pair<const MyKey,MyData>*>(0) ); + AssertSameType( static_cast<MyTable::accessor::value_type*>(0), static_cast<MyTable::value_type*>(0) ); + AssertSameType( static_cast<MyTable::const_accessor::value_type*>(0), static_cast<const MyTable::value_type*>(0) ); + AssertSameType( static_cast<MyTable::size_type*>(0), static_cast<size_t*>(0) ); + AssertSameType( static_cast<MyTable::difference_type*>(0), static_cast<ptrdiff_t*>(0) ); +} + +template<typename Iterator, typename T> +void TestIteratorTraits() { + AssertSameType( static_cast<typename Iterator::difference_type*>(0), static_cast<ptrdiff_t*>(0) ); + AssertSameType( static_cast<typename Iterator::value_type*>(0), static_cast<T*>(0) ); + AssertSameType( static_cast<typename Iterator::pointer*>(0), static_cast<T**>(0) ); + AssertSameType( static_cast<typename Iterator::iterator_category*>(0), static_cast<std::forward_iterator_tag*>(0) ); + T x; + typename Iterator::reference xr = x; + typename Iterator::pointer xp = &x; + ASSERT( &xr==xp, NULL ); +} + +template<typename Iterator1, typename Iterator2> +void TestIteratorAssignment( Iterator2 j ) { + Iterator1 i(j), k; + ASSERT( i==j, NULL ); ASSERT( !(i!=j), NULL ); + k = j; + ASSERT( k==j, NULL ); ASSERT( !(k!=j), NULL ); +} + +template<typename Range1, typename Range2> +void TestRangeAssignment( Range2 r2 ) { + Range1 r1(r2); r1 = r2; +} +//------------------------------------------------------------------------ +// Test for copy constructor and assignment +//------------------------------------------------------------------------ + +template<typename MyTable> +static void FillTable( MyTable& x, int n ) { + for( int i=1; i<=n; ++i ) { + MyKey key( MyKey::make(-i) ); // hash values must not be specified in direct order + typename MyTable::accessor a; + bool b = x.insert(a,key); + ASSERT(b, NULL); + a->second.set_value( i*i ); + } +} + +template<typename MyTable> +static void CheckTable( const MyTable& x, int n ) { + ASSERT( x.size()==size_t(n), "table is different size than expected" ); + ASSERT( x.empty()==(n==0), NULL ); + ASSERT( x.size()<=x.max_size(), NULL ); + for( int i=1; i<=n; ++i ) { + MyKey key( MyKey::make(-i) ); + typename MyTable::const_accessor a; + bool b = x.find(a,key); + ASSERT( b, NULL ); + ASSERT( a->second.value_of()==i*i, NULL ); + } + int count = 0; + int key_sum = 0; + for( typename MyTable::const_iterator i(x.begin()); i!=x.end(); ++i ) { + ++count; + key_sum += -i->first.value_of(); + } + ASSERT( count==n, NULL ); + ASSERT( key_sum==n*(n+1)/2, NULL ); +} + +static void TestCopy() { + REMARK("testing copy\n"); + MyTable t1; + for( int i=0; i<10000; i=(i<100 ? i+1 : i*3) ) { + MyDataCount = 0; + + FillTable(t1,i); + // Do not call CheckTable(t1,i) before copying, it enforces rehashing + + MyTable t2(t1); + // Check that copy constructor did not mangle source table. + CheckTable(t1,i); + swap(t1, t2); + CheckTable(t1,i); + ASSERT( !(t1 != t2), NULL ); + + // Clear original table + t2.clear(); + swap(t2, t1); + CheckTable(t1,0); + + // Verify that copy of t1 is correct, even after t1 is cleared. + CheckTable(t2,i); + t2.clear(); + t1.swap( t2 ); + CheckTable(t1,0); + CheckTable(t2,0); + ASSERT( MyDataCount==0, "data leak?" ); + } +} + +void TestAssignment() { + REMARK("testing assignment\n"); + for( int i=0; i<1000; i=(i<30 ? i+1 : i*5) ) { + for( int j=0; j<1000; j=(j<30 ? j+1 : j*7) ) { + MyTable t1; + MyTable t2; + FillTable(t1,i); + FillTable(t2,j); + ASSERT( (t1 == t2) == (i == j), NULL ); + CheckTable(t2,j); + + MyTable& tref = t2=t1; + ASSERT( &tref==&t2, NULL ); + ASSERT( t1 == t2, NULL ); + CheckTable(t1,i); + CheckTable(t2,i); + + t1.clear(); + CheckTable(t1,0); + CheckTable(t2,i); + ASSERT( MyDataCount==i, "data leak?" ); + + t2.clear(); + CheckTable(t1,0); + CheckTable(t2,0); + ASSERT( MyDataCount==0, "data leak?" ); + } + } +} + +void TestIteratorsAndRanges() { + REMARK("testing iterators compliance\n"); + TestIteratorTraits<MyTable::iterator,MyTable::value_type>(); + TestIteratorTraits<MyTable::const_iterator,const MyTable::value_type>(); + + MyTable v; + MyTable const &u = v; + + TestIteratorAssignment<MyTable::const_iterator>( u.begin() ); + TestIteratorAssignment<MyTable::const_iterator>( v.begin() ); + TestIteratorAssignment<MyTable::iterator>( v.begin() ); + // doesn't compile as expected: TestIteratorAssignment<typename V::iterator>( u.begin() ); + + // check for non-existing + ASSERT(v.equal_range(MyKey::make(-1)) == std::make_pair(v.end(), v.end()), NULL); + ASSERT(u.equal_range(MyKey::make(-1)) == std::make_pair(u.end(), u.end()), NULL); + + REMARK("testing ranges compliance\n"); + TestRangeAssignment<MyTable::const_range_type>( u.range() ); + TestRangeAssignment<MyTable::const_range_type>( v.range() ); + TestRangeAssignment<MyTable::range_type>( v.range() ); + // doesn't compile as expected: TestRangeAssignment<typename V::range_type>( u.range() ); + + REMARK("testing construction and insertion from iterators range\n"); + FillTable( v, 1000 ); + MyTable2 t(v.begin(), v.end()); + v.rehash(); + CheckTable(t, 1000); + t.insert(v.begin(), v.end()); // do nothing + CheckTable(t, 1000); + t.clear(); + t.insert(v.begin(), v.end()); // restore + CheckTable(t, 1000); + + REMARK("testing comparison\n"); + typedef tbb::concurrent_hash_map<MyKey,MyData2,YourHashCompare,MyAllocator> YourTable1; + typedef tbb::concurrent_hash_map<MyKey,MyData2,YourHashCompare> YourTable2; + YourTable1 t1; + FillTable( t1, 10 ); + CheckTable(t1, 10 ); + YourTable2 t2(t1.begin(), t1.end()); + MyKey key( MyKey::make(-5) ); MyData2 data; + ASSERT(t2.erase(key), NULL); + YourTable2::accessor a; + ASSERT(t2.insert(a, key), NULL); + data.set_value(0); a->second = data; + ASSERT( t1 != t2, NULL); + data.set_value(5*5); a->second = data; + ASSERT( t1 == t2, NULL); +} + +void TestRehash() { + REMARK("testing rehashing\n"); + MyTable w; + w.insert( std::make_pair(MyKey::make(-5), MyData()) ); + w.rehash(); // without this, assertion will fail + MyTable::iterator it = w.begin(); + int i = 0; // check for non-rehashed buckets + for( ; it != w.end(); i++ ) + w.count( (it++)->first ); + ASSERT( i == 1, NULL ); + for( i=0; i<1000; i=(i<29 ? i+1 : i*2) ) { + for( int j=max(256+i, i*2); j<10000; j*=3 ) { + MyTable v; + FillTable( v, i ); + ASSERT(int(v.size()) == i, NULL); + ASSERT(int(v.bucket_count()) <= j, NULL); + v.rehash( j ); + ASSERT(int(v.bucket_count()) >= j, NULL); + CheckTable( v, i ); + } + } +} + +template<typename base_alloc_t, typename count_t = tbb::atomic<size_t> > +class only_node_counting_allocator : public local_counting_allocator<base_alloc_t, count_t> { + typedef local_counting_allocator<base_alloc_t, count_t> base_type; +public: + template<typename U> + struct rebind { + typedef only_node_counting_allocator<typename base_alloc_t::template rebind<U>::other,count_t> other; + }; + + only_node_counting_allocator() : base_type() {} + only_node_counting_allocator(const only_node_counting_allocator& a) : base_type(a) {} + + template<typename U> + only_node_counting_allocator(const only_node_counting_allocator<U>& a) : base_type(a) {} + + typename base_type::pointer allocate(const typename base_type::size_type n) { + if ( n > 1) { + return base_alloc_t::allocate(n); + } else { + return base_type::allocate(n); + } + } +}; + +#if TBB_USE_EXCEPTIONS +void TestExceptions() { + typedef only_node_counting_allocator<tbb::tbb_allocator<MyData2> > allocator_t; + typedef tbb::concurrent_hash_map<MyKey,MyData2,MyHashCompare,allocator_t> ThrowingTable; + enum methods { + zero_method = 0, + ctor_copy, op_assign, op_insert, + all_methods + }; + REMARK("testing exception-safety guarantees\n"); + ThrowingTable src; + FillTable( src, 1000 ); + ASSERT( MyDataCount==1000, NULL ); + + try { + for(int t = 0; t < 2; t++) // exception type + for(int m = zero_method+1; m < all_methods; m++) + { + allocator_t a; + if(t) MyDataCountLimit = 101; + else a.set_limits(101); + ThrowingTable victim(a); + MyDataCount = 0; + + try { + switch(m) { + case ctor_copy: { + ThrowingTable acopy(src, a); + } break; + case op_assign: { + victim = src; + } break; + case op_insert: { +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TUPLE_PRESENT + // Insertion in cpp11 don't make copy constructions + // during the insertion, so we need to decrement limit + // to throw an exception in the right place and to prevent + // successful insertion of one unexpected item + if (MyDataCountLimit) + --MyDataCountLimit; +#endif + FillTable( victim, 1000 ); + } break; + default:; + } + ASSERT(false, "should throw an exception"); + } catch(std::bad_alloc &e) { + MyDataCountLimit = 0; + size_t size = victim.size(); + switch(m) { + case op_assign: + ASSERT( MyDataCount==100, "data leak?" ); + ASSERT( size>=100, NULL ); + CheckAllocator(victim, 100+t, t); + __TBB_fallthrough; + case ctor_copy: + CheckTable(src, 1000); + break; + case op_insert: + ASSERT( size==size_t(100-t), NULL ); + ASSERT( MyDataCount==100-t, "data leak?" ); + CheckTable(victim, 100-t); + CheckAllocator(victim, 100, t); + break; + + default:; // nothing to check here + } + REMARK("Exception %d: %s\t- ok ()\n", m, e.what()); + } + catch ( ... ) { + ASSERT ( __TBB_EXCEPTION_TYPE_INFO_BROKEN, "Unrecognized exception" ); + } + } + } catch(...) { + ASSERT(false, "unexpected exception"); + } + src.clear(); MyDataCount = 0; +} +#endif /* TBB_USE_EXCEPTIONS */ + + +#if __TBB_INITIALIZER_LISTS_PRESENT +#include "test_initializer_list.h" + +struct test_insert { + template<typename container_type, typename element_type> + static void do_test( std::initializer_list<element_type> il, container_type const& expected ) { + container_type vd; + vd.insert( il ); + ASSERT( vd == expected, "inserting with an initializer list failed" ); + } +}; + +void TestInitList(){ + using namespace initializer_list_support_tests; + REMARK("testing initializer_list methods \n"); + + typedef tbb::concurrent_hash_map<int,int> ch_map_type; + std::initializer_list<ch_map_type::value_type> pairs_il = {{1,1},{2,2},{3,3},{4,4},{5,5}}; + + TestInitListSupportWithoutAssign<ch_map_type, test_insert>( pairs_il ); + TestInitListSupportWithoutAssign<ch_map_type, test_insert>( {} ); +} +#endif //if __TBB_INITIALIZER_LISTS_PRESENT + +#if __TBB_RANGE_BASED_FOR_PRESENT +#include "test_range_based_for.h" + +void TestRangeBasedFor(){ + using namespace range_based_for_support_tests; + + REMARK("testing range based for loop compatibility \n"); + typedef tbb::concurrent_hash_map<int,int> ch_map; + ch_map a_ch_map; + + const int sequence_length = 100; + for (int i = 1; i <= sequence_length; ++i){ + a_ch_map.insert(ch_map::value_type(i,i)); + } + + ASSERT( range_based_for_accumulate(a_ch_map, pair_second_summer(), 0) == gauss_summ_of_int_sequence(sequence_length), "incorrect accumulated value generated via range based for ?"); +} +#endif //if __TBB_RANGE_BASED_FOR_PRESENT + +#include "harness_defs.h" + +// The helper to run a test only when a default construction is present. +template <bool default_construction_present> struct do_default_construction_test { + template<typename FuncType> void operator() ( FuncType func ) const { func(); } +}; +template <> struct do_default_construction_test<false> { + template<typename FuncType> void operator()( FuncType ) const {} +}; + +template <typename Table> +class test_insert_by_key : NoAssign { + typedef typename Table::value_type value_type; + Table &my_c; + const value_type &my_value; +public: + test_insert_by_key( Table &c, const value_type &value ) : my_c(c), my_value(value) {} + void operator()() const { + { + typename Table::accessor a; + ASSERT( my_c.insert( a, my_value.first ), NULL ); + ASSERT( Harness::IsEqual()(a->first, my_value.first), NULL ); + a->second = my_value.second; + } { + typename Table::const_accessor ca; + ASSERT( !my_c.insert( ca, my_value.first ), NULL ); + ASSERT( Harness::IsEqual()(ca->first, my_value.first), NULL); + ASSERT( Harness::IsEqual()(ca->second, my_value.second), NULL); + } + } +}; + +#include <vector> +#include <list> +#include <algorithm> +#if __TBB_CPP11_REFERENCE_WRAPPER_PRESENT +#include <functional> +#endif + +template <typename Table, typename Iterator, typename Range = typename Table::range_type> +class test_range : NoAssign { + typedef typename Table::value_type value_type; + Table &my_c; + const std::list<value_type> &my_lst; + std::vector< tbb::atomic<bool> >& my_marks; +public: + test_range( Table &c, const std::list<value_type> &lst, std::vector< tbb::atomic<bool> > &marks ) : my_c(c), my_lst(lst), my_marks(marks) { + std::fill( my_marks.begin(), my_marks.end(), false ); + } + void operator()( const Range &r ) const { do_test_range( r.begin(), r.end() ); } + void do_test_range( Iterator i, Iterator j ) const { + for ( Iterator it = i; it != j; ) { + Iterator it_prev = it++; + typename std::list<value_type>::const_iterator it2 = std::search( my_lst.begin(), my_lst.end(), it_prev, it, Harness::IsEqual() ); + ASSERT( it2 != my_lst.end(), NULL ); + typename std::list<value_type>::difference_type dist = std::distance( my_lst.begin(), it2 ); + ASSERT( !my_marks[dist], NULL ); + my_marks[dist] = true; + } + } +}; + +template <bool default_construction_present, typename Table> +class check_value : NoAssign { + typedef typename Table::const_iterator const_iterator; + typedef typename Table::iterator iterator; + typedef typename Table::size_type size_type; + Table &my_c; +public: + check_value( Table &c ) : my_c(c) {} + void operator()(const typename Table::value_type &value ) { + const Table &const_c = my_c; + ASSERT( my_c.count( value.first ) == 1, NULL ); + { // tests with a const accessor. + typename Table::const_accessor ca; + // find + ASSERT( my_c.find( ca, value.first ), NULL); + ASSERT( !ca.empty() , NULL); + ASSERT( Harness::IsEqual()(ca->first, value.first), NULL ); + ASSERT( Harness::IsEqual()(ca->second, value.second), NULL ); + // erase + ASSERT( my_c.erase( ca ), NULL ); + ASSERT( my_c.count( value.first ) == 0, NULL ); + // insert (pair) + ASSERT( my_c.insert( ca, value ), NULL); + ASSERT( Harness::IsEqual()(ca->first, value.first), NULL ); + ASSERT( Harness::IsEqual()(ca->second, value.second), NULL ); + } { // tests with a non-const accessor. + typename Table::accessor a; + // find + ASSERT( my_c.find( a, value.first ), NULL); + ASSERT( !a.empty() , NULL); + ASSERT( Harness::IsEqual()(a->first, value.first), NULL ); + ASSERT( Harness::IsEqual()(a->second, value.second), NULL ); + // erase + ASSERT( my_c.erase( a ), NULL ); + ASSERT( my_c.count( value.first ) == 0, NULL ); + // insert + ASSERT( my_c.insert( a, value ), NULL); + ASSERT( Harness::IsEqual()(a->first, value.first), NULL ); + ASSERT( Harness::IsEqual()(a->second, value.second), NULL ); + } + // erase by key + ASSERT( my_c.erase( value.first ), NULL ); + ASSERT( my_c.count( value.first ) == 0, NULL ); + do_default_construction_test<default_construction_present>()(test_insert_by_key<Table>( my_c, value )); + // insert by value + ASSERT( my_c.insert( value ) != default_construction_present, NULL ); + // equal_range + std::pair<iterator,iterator> r1 = my_c.equal_range( value.first ); + iterator r1_first_prev = r1.first++; + ASSERT( Harness::IsEqual()( *r1_first_prev, value ) && Harness::IsEqual()( r1.first, r1.second ), NULL ); + std::pair<const_iterator,const_iterator> r2 = const_c.equal_range( value.first ); + const_iterator r2_first_prev = r2.first++; + ASSERT( Harness::IsEqual()( *r2_first_prev, value ) && Harness::IsEqual()( r2.first, r2.second ), NULL ); + } +}; + +#include "tbb/task_scheduler_init.h" + +template <typename Value, typename U = Value> +struct CompareTables { + template <typename T> + static bool IsEqual( const T& t1, const T& t2 ) { + return (t1 == t2) && !(t1 != t2); + } +}; + +#if __TBB_CPP11_SMART_POINTERS_PRESENT +template <typename U> +struct CompareTables< std::pair<const std::weak_ptr<U>, std::weak_ptr<U> > > { + template <typename T> + static bool IsEqual( const T&, const T& ) { + /* do nothing for std::weak_ptr */ + return true; + } +}; +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ + +template <bool default_construction_present, typename Table> +void Examine( Table c, const std::list<typename Table::value_type> &lst) { + typedef const Table const_table; + typedef typename Table::const_iterator const_iterator; + typedef typename Table::iterator iterator; + typedef typename Table::value_type value_type; + typedef typename Table::size_type size_type; + + ASSERT( !c.empty(), NULL ); + ASSERT( c.size() == lst.size(), NULL ); + ASSERT( c.max_size() >= c.size(), NULL ); + + const check_value<default_construction_present,Table> cv(c); + std::for_each( lst.begin(), lst.end(), cv ); + + std::vector< tbb::atomic<bool> > marks( lst.size() ); + + test_range<Table,iterator>( c, lst, marks ).do_test_range( c.begin(), c.end() ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + test_range<const_table,const_iterator>( c, lst, marks ).do_test_range( c.begin(), c.end() ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + tbb::task_scheduler_init init; + + typedef typename Table::range_type range_type; + tbb::parallel_for( c.range(), test_range<Table,typename range_type::iterator,range_type>( c, lst, marks ) ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + const_table const_c = c; + ASSERT( CompareTables<value_type>::IsEqual( c, const_c ), NULL ); + + typedef typename const_table::const_range_type const_range_type; + tbb::parallel_for( c.range(), test_range<const_table,typename const_range_type::iterator,const_range_type>( const_c, lst, marks ) ); + ASSERT( std::find( marks.begin(), marks.end(), false ) == marks.end(), NULL ); + + const size_type new_bucket_count = 2*c.bucket_count(); + c.rehash( new_bucket_count ); + ASSERT( c.bucket_count() >= new_bucket_count, NULL ); + + Table c2; + typename std::list<value_type>::const_iterator begin5 = lst.begin(); + std::advance( begin5, 5 ); + c2.insert( lst.begin(), begin5 ); + std::for_each( lst.begin(), begin5, check_value<default_construction_present, Table>( c2 ) ); + + c2.swap( c ); + ASSERT( CompareTables<value_type>::IsEqual( c2, const_c ), NULL ); + ASSERT( c.size() == 5, NULL ); + std::for_each( lst.begin(), lst.end(), check_value<default_construction_present,Table>(c2) ); + + tbb::swap( c, c2 ); + ASSERT( CompareTables<value_type>::IsEqual( c, const_c ), NULL ); + ASSERT( c2.size() == 5, NULL ); + + c2.clear(); + ASSERT( CompareTables<value_type>::IsEqual( c2, Table() ), NULL ); + + typename Table::allocator_type a = c.get_allocator(); + value_type *ptr = a.allocate(1); + ASSERT( ptr, NULL ); + a.deallocate( ptr, 1 ); +} + +template<typename T> +struct debug_hash_compare : tbb::tbb_hash_compare<T> {}; + +template <bool default_construction_present, typename Value> +void TypeTester( const std::list<Value> &lst ) { + __TBB_ASSERT( lst.size() >= 5, "Array should have at least 5 elements" ); + typedef typename Value::first_type first_type; + typedef typename Value::second_type second_type; + typedef tbb::concurrent_hash_map<first_type,second_type> ch_map; + debug_hash_compare<first_type> compare; + // Construct an empty hash map. + ch_map c1; + c1.insert( lst.begin(), lst.end() ); + Examine<default_construction_present>( c1, lst ); +#if __TBB_INITIALIZER_LISTS_PRESENT && !__TBB_CPP11_INIT_LIST_TEMP_OBJS_LIFETIME_BROKEN + // Constructor from initializer_list. + typename std::list<Value>::const_iterator it = lst.begin(); + std::initializer_list<Value> il = { *it++, *it++, *it++ }; + ch_map c2( il ); + c2.insert( it, lst.end() ); + Examine<default_construction_present>( c2, lst ); + + // Constructor from initializer_list and compare object + ch_map c3( il, compare); + c3.insert( it, lst.end() ); + Examine<default_construction_present>( c3, lst ); + + // Constructor from initializer_list, compare object and allocator + ch_map c4( il, compare, typename ch_map::allocator_type()); + c4.insert( it, lst.end()); + Examine<default_construction_present>( c4, lst ); +#endif + // Copying constructor. + ch_map c5(c1); + Examine<default_construction_present>( c5, lst ); + // Construct with non-default allocator + typedef tbb::concurrent_hash_map< first_type,second_type,tbb::tbb_hash_compare<first_type>,debug_allocator<Value> > ch_map_debug_alloc; + ch_map_debug_alloc c6; + c6.insert( lst.begin(), lst.end() ); + Examine<default_construction_present>( c6, lst ); + // Copying constructor + ch_map_debug_alloc c7(c6); + Examine<default_construction_present>( c7, lst ); + // Construction empty table with n preallocated buckets. + ch_map c8( lst.size() ); + c8.insert( lst.begin(), lst.end() ); + Examine<default_construction_present>( c8, lst ); + ch_map_debug_alloc c9( lst.size() ); + c9.insert( lst.begin(), lst.end() ); + Examine<default_construction_present>( c9, lst ); + // Construction with copying iteration range. + ch_map c10( c1.begin(), c1.end() ); + Examine<default_construction_present>( c10, lst ); + // Construction with copying iteration range and given allocator instance. + debug_allocator<Value> allocator; + ch_map_debug_alloc c11( lst.begin(), lst.end(), allocator ); + Examine<default_construction_present>( c11, lst ); + + typedef tbb::concurrent_hash_map< first_type,second_type,debug_hash_compare<first_type>,typename ch_map::allocator_type> ch_map_debug_hash; + + // Constructor with two iterators and hash_compare + ch_map_debug_hash c12(c1.begin(), c1.end(), compare); + Examine<default_construction_present>( c12, lst ); + + ch_map_debug_hash c13(c1.begin(), c1.end(), compare, typename ch_map::allocator_type()); + Examine<default_construction_present>( c13, lst ); +} + +#if __TBB_CPP11_SMART_POINTERS_PRESENT +namespace tbb { + template<> struct tbb_hash_compare< const std::shared_ptr<int> > { + static size_t hash( const std::shared_ptr<int>& ptr ) { return static_cast<size_t>( *ptr ) * interface5::internal::hash_multiplier; } + static bool equal( const std::shared_ptr<int>& ptr1, const std::shared_ptr<int>& ptr2 ) { return ptr1 == ptr2; } + }; + template<> struct tbb_hash_compare< const std::weak_ptr<int> > { + static size_t hash( const std::weak_ptr<int>& ptr ) { return static_cast<size_t>( *ptr.lock() ) * interface5::internal::hash_multiplier; } + static bool equal( const std::weak_ptr<int>& ptr1, const std::weak_ptr<int>& ptr2 ) { return ptr1.lock() == ptr2.lock(); } + }; +} +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ + +void TestCPP11Types() { + const int NUMBER = 10; + + typedef std::pair<const int, int> int_int_t; + std::list<int_int_t> arrIntInt; + for ( int i=0; i<NUMBER; ++i ) arrIntInt.push_back( int_int_t(i, NUMBER-i) ); + TypeTester</*default_construction_present = */true>( arrIntInt ); + +#if __TBB_CPP11_REFERENCE_WRAPPER_PRESENT && !__TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN + typedef std::pair<const std::reference_wrapper<const int>, int> ref_int_t; + std::list<ref_int_t> arrRefInt; + for ( std::list<int_int_t>::iterator it = arrIntInt.begin(); it != arrIntInt.end(); ++it ) + arrRefInt.push_back( ref_int_t( it->first, it->second ) ); + TypeTester</*default_construction_present = */true>( arrRefInt ); + + typedef std::pair< const int, std::reference_wrapper<int> > int_ref_t; + std::list<int_ref_t> arrIntRef; + for ( std::list<int_int_t>::iterator it = arrIntInt.begin(); it != arrIntInt.end(); ++it ) + arrIntRef.push_back( int_ref_t( it->first, it->second ) ); + TypeTester</*default_construction_present = */false>( arrIntRef ); +#else + REPORT("Known issue: C++11 reference wrapper tests are skipped.\n"); +#endif /* __TBB_CPP11_REFERENCE_WRAPPER_PRESENT && !__TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN*/ + + typedef std::pair< const int, tbb::atomic<int> > int_tbb_t; + std::list<int_tbb_t> arrIntTbb; + for ( int i=0; i<NUMBER; ++i ) { + tbb::atomic<int> b; + b = NUMBER-i; + arrIntTbb.push_back( int_tbb_t(i, b) ); + } + TypeTester</*default_construction_present = */true>( arrIntTbb ); + +#if __TBB_CPP11_SMART_POINTERS_PRESENT + typedef std::pair< const std::shared_ptr<int>, std::shared_ptr<int> > shr_shr_t; + std::list<shr_shr_t> arrShrShr; + for ( int i=0; i<NUMBER; ++i ) { + const int NUMBER_minus_i = NUMBER - i; + arrShrShr.push_back( shr_shr_t( std::make_shared<int>(i), std::make_shared<int>(NUMBER_minus_i) ) ); + } + TypeTester< /*default_construction_present = */true>( arrShrShr ); + + typedef std::pair< const std::weak_ptr<int>, std::weak_ptr<int> > wk_wk_t; + std::list< wk_wk_t > arrWkWk; + std::copy( arrShrShr.begin(), arrShrShr.end(), std::back_inserter(arrWkWk) ); + TypeTester< /*default_construction_present = */true>( arrWkWk ); +#else + REPORT("Known issue: C++11 smart pointer tests are skipped.\n"); +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT + +struct hash_map_move_traits : default_container_traits { + enum{ expected_number_of_items_to_allocate_for_steal_move = 0 }; + + template<typename T> + struct hash_compare { + bool equal( const T& lhs, const T& rhs ) const { + return lhs==rhs; + } + size_t hash( const T& k ) const { + return tbb::tbb_hasher(k); + } + }; + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_hash_map<element_type, element_type, hash_compare<element_type>, allocator_type > type; + }; + + typedef FooPairIterator init_iterator_type; + template<typename hash_map_type, typename iterator> + static bool equal(hash_map_type const& c, iterator begin, iterator end){ + bool equal_sizes = ( static_cast<size_t>(std::distance(begin, end)) == c.size() ); + if (!equal_sizes) + return false; + + for (iterator it = begin; it != end; ++it ){ + if (c.count( (*it).first) == 0){ + return false; + } + } + return true; + } +}; + +void TestMoveSupport(){ + TestMoveConstructor<hash_map_move_traits>(); + TestConstructorWithMoveIterators<hash_map_move_traits>(); + TestMoveAssignOperator<hash_map_move_traits>(); +#if TBB_USE_EXCEPTIONS + TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorMemoryFailure<hash_map_move_traits>(); + TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorExceptionInElementCtor<hash_map_move_traits>(); +#else + REPORT("Known issue: exception safety tests for C++11 move semantics support are skipped.\n"); +#endif //TBB_USE_EXCEPTIONS +} +#else +void TestMoveSupport(){ + REPORT("Known issue: tests for C++11 move semantics support are skipped.\n"); +} +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +template <template <typename...> typename TMap> +void TestDeductionGuides() { + using Key = int; + using Value = std::string; + + using ComplexType = std::pair<Key, Value>; + using ComplexTypeConst = std::pair<const Key, Value>; + + using DefaultCompare = tbb::tbb_hash_compare<Key>; + using Compare = debug_hash_compare<Key>; + using DefaultAllocator = tbb::tbb_allocator<ComplexTypeConst>; + using Allocator = std::allocator<ComplexType>; + + std::vector<ComplexType> v; + auto l = { ComplexTypeConst(1, "one"), ComplexTypeConst(2, "two") }; + Compare compare; + Allocator allocator; + + // check TMap(InputIterator, InputIterator) + TMap m1(v.begin(), v.end()); + static_assert(std::is_same<decltype(m1), TMap<Key, Value, DefaultCompare, DefaultAllocator>>::value); + + // check TMap(InputIterator, InputIterator, HashCompare) + TMap m2(v.begin(), v.end(), compare); + static_assert(std::is_same<decltype(m2), TMap<Key, Value, Compare>>::value); + + // check TMap(InputIterator, InputIterator, HashCompare, Allocator) + TMap m3(v.begin(), v.end(), compare, allocator); + static_assert(std::is_same<decltype(m3), TMap<Key, Value, Compare, Allocator>>::value); + + // check TMap(InputIterator, InputIterator, Allocator) + TMap m4(v.begin(), v.end(), allocator); + static_assert(std::is_same<decltype(m4), TMap<Key, Value, DefaultCompare, Allocator>>::value); + + // check TMap(std::initializer_list) + TMap m5(l); + static_assert(std::is_same<decltype(m5), TMap<Key, Value, DefaultCompare, DefaultAllocator>>::value); + + // check TMap(std::initializer_list, HashCompare) + TMap m6(l, compare); + static_assert(std::is_same<decltype(m6), TMap<Key, Value, Compare, DefaultAllocator>>::value); + + // check TMap(std::initializer_list, HashCompare, Allocator) + TMap m7(l, compare, allocator); + static_assert(std::is_same<decltype(m7), TMap<Key, Value, Compare, Allocator>>::value); + + // check TMap(std::initializer_list, Allocator) + TMap m8(l, allocator); + static_assert(std::is_same<decltype(m8), TMap<Key, Value, DefaultCompare, Allocator>>::value); + + // check TMap(TMap &) + TMap m9(m1); + static_assert(std::is_same<decltype(m9), decltype(m1)>::value); + + // check TMap(TMap &, Allocator) + TMap m10(m4, allocator); + static_assert(std::is_same<decltype(m10), decltype(m4)>::value); + + // check TMap(TMap &&) + TMap m11(std::move(m1)); + static_assert(std::is_same<decltype(m11), decltype(m1)>::value); + + // check TMap(TMap &&, Allocator) + TMap m12(std::move(m4), allocator); + static_assert(std::is_same<decltype(m12), decltype(m4)>::value); +} +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +template<typename Key> +struct non_default_constructible_hash_compare : tbb::tbb_hash_compare<Key> { + non_default_constructible_hash_compare() { + ASSERT(false, "Hash compare object must not default construct during the construction of hash_map with compare argument"); + } + + non_default_constructible_hash_compare(int) {} +}; + +void TestHashCompareConstructors() { + typedef int key_type; + typedef tbb::concurrent_hash_map<key_type, key_type, non_default_constructible_hash_compare<key_type> > map_type; + + non_default_constructible_hash_compare<key_type> compare(0); + map_type::allocator_type allocator; + + map_type map1(compare); + map_type map2(compare, allocator); + + map_type map3(1, compare); + map_type map4(1, compare, allocator); + + std::vector<map_type::value_type> reference_vector; + map_type map5(reference_vector.begin(), reference_vector.end(), compare); + map_type map6(reference_vector.begin(), reference_vector.end(), compare, allocator); + +#if __TBB_INITIALIZER_LISTS_PRESENT + map_type map7({}, compare); + map_type map8({}, compare, allocator); +#endif +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && !__TBB_SCOPED_ALLOCATOR_BROKEN +#include <scoped_allocator> + +struct custom_hash_compare { + template<typename Allocator> + static size_t hash(const allocator_aware_data<Allocator>& key) { + return tbb::tbb_hash_compare<int>::hash(key.value()); + } + + template<typename Allocator> + static bool equal(const allocator_aware_data<Allocator>& key1, const allocator_aware_data<Allocator>& key2) { + return tbb::tbb_hash_compare<int>::equal(key1.value(), key2.value()); + } +}; + +void TestScopedAllocator() { + typedef allocator_aware_data<std::scoped_allocator_adaptor<tbb::tbb_allocator<int>>> allocator_data_type; + typedef std::scoped_allocator_adaptor<tbb::tbb_allocator<allocator_data_type>> allocator_type; + typedef tbb::concurrent_hash_map<allocator_data_type, allocator_data_type, + custom_hash_compare, allocator_type> hash_map_type; + + allocator_type allocator; + allocator_data_type key1(1, allocator), key2(2, allocator); + allocator_data_type data1(1, allocator), data2(data1, allocator); + hash_map_type map1(allocator), map2(allocator); + + hash_map_type::value_type v1(key1, data1), v2(key2, data2); + + auto init_list = { v1, v2 }; + + allocator_data_type::assert_on_constructions = true; + map1.emplace(key1, data1); + map2.emplace(key2, std::move(data2)); + + map1.clear(); + map2.clear(); + + map1.insert(v1); + map2.insert(std::move(v2)); + + map1.clear(); + map2.clear(); + + map1.insert(init_list); + + map1.clear(); + map2.clear(); + + hash_map_type::accessor a; + map2.insert(a, allocator_data_type(3)); + a.release(); + + map1 = map2; + map2 = std::move(map1); + + hash_map_type map3(allocator); + map3.rehash(1000); + map3 = map2; +} +#endif + +#if __TBB_ALLOCATOR_TRAITS_PRESENT +void TestAllocatorTraits() { + using namespace propagating_allocators; + typedef int key; + typedef int mapped; + typedef tbb::tbb_hash_compare<key> compare; + + typedef tbb::concurrent_hash_map<key, mapped, compare, always_propagating_allocator> always_propagating_map; + typedef tbb::concurrent_hash_map<key, mapped, compare, never_propagating_allocator> never_propagating_map; + typedef tbb::concurrent_hash_map<key, mapped, compare, pocma_allocator> pocma_map; + typedef tbb::concurrent_hash_map<key, mapped, compare, pocca_allocator> pocca_map; + typedef tbb::concurrent_hash_map<key, mapped, compare, pocs_allocator> pocs_map; + + test_allocator_traits_support<always_propagating_map>(); + test_allocator_traits_support<never_propagating_map>(); + test_allocator_traits_support<pocma_map>(); + test_allocator_traits_support<pocca_map>(); + test_allocator_traits_support<pocs_map>(); + +#if __TBB_CPP11_RVALUE_REF_PRESENT + test_allocator_traits_with_non_movable_value_type<pocma_map>(); +#endif +} +#endif // __TBB_ALLOCATOR_TRAITS_PRESENT + +// A test for undocumented member function internal_fast_find +// which is declared protected in concurrent_hash_map for internal TBB use +void TestInternalFastFind() { + typedef tbb::concurrent_hash_map<int, int> basic_chmap_type; + typedef basic_chmap_type::const_pointer const_pointer; + + class chmap : public basic_chmap_type { + public: + chmap() : basic_chmap_type() {} + + using basic_chmap_type::internal_fast_find; + }; + + chmap m; + int sz = 100; + + for (int i = 0; i != sz; ++i) { + m.insert(std::make_pair(i, i * i)); + } + ASSERT(m.size() == 100, "Incorrect concurrent_hash_map size"); + + for (int i = 0; i != sz; ++i) { + const_pointer res = m.internal_fast_find(i); + ASSERT(res != NULL, "Incorrect internal_fast_find return value for existing key"); + basic_chmap_type::value_type val = *res; + ASSERT(val.first == i, "Incorrect key in internal_fast_find return value"); + ASSERT(val.second == i * i, "Incorrect mapped in internal_fast_find return value"); + } + + for (int i = sz; i != 2 * sz; ++i) { + const_pointer res = m.internal_fast_find(i); + ASSERT(res == NULL, "Incorrect internal_fast_find return value for not existing key"); + } +} + +//------------------------------------------------------------------------ +// Test driver +//------------------------------------------------------------------------ +int TestMain () { + if( MinThread<0 ) { + REPORT("ERROR: must use at least one thread\n"); + exit(1); + } + if( MaxThread<2 ) MaxThread=2; + + // Do serial tests + TestTypes(); + TestCopy(); + TestRehash(); + TestAssignment(); + TestIteratorsAndRanges(); +#if __TBB_INITIALIZER_LISTS_PRESENT + TestInitList(); +#endif //__TBB_INITIALIZER_LISTS_PRESENT + +#if __TBB_RANGE_BASED_FOR_PRESENT + TestRangeBasedFor(); +#endif //#if __TBB_RANGE_BASED_FOR_PRESENT + +#if TBB_USE_EXCEPTIONS + TestExceptions(); +#endif /* TBB_USE_EXCEPTIONS */ + + TestMoveSupport(); + { +#if __TBB_CPP11_RVALUE_REF_PRESENT + tbb::task_scheduler_init init( 1 ); + int n=250000; + { + DataStateTrackedTable table; + DoConcurrentOperations<RvalueInsert, DataStateTrackedTable>( table, n, "rvalue ref insert", 1 ); + } +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + { + DataStateTrackedTable table; + DoConcurrentOperations<Emplace, DataStateTrackedTable>( table, n, "emplace", 1 ); + } +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif // __TBB_CPP11_RVALUE_REF_PRESENT + } + + // Do concurrency tests. + for( int nthread=MinThread; nthread<=MaxThread; ++nthread ) { + tbb::task_scheduler_init init( nthread ); + TestInsertFindErase( nthread ); + TestConcurrency( nthread ); + } + // check linking + if(bad_hashing) { //should be false + tbb::internal::runtime_warning("none\nERROR: it must not be executed"); + } + + TestCPP11Types(); + TestHashCompareConstructors(); + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides<tbb::concurrent_hash_map>(); +#endif +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && !__TBB_SCOPED_ALLOCATOR_BROKEN + TestScopedAllocator(); +#endif + +#if __TBB_ALLOCATOR_TRAITS_PRESENT + TestAllocatorTraits(); +#endif + + TestInternalFastFind(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_lru_cache.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_lru_cache.cpp new file mode 100644 index 00000000..3d8042d5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_lru_cache.cpp @@ -0,0 +1,462 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _MSC_VER + #pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning +#endif + +#ifdef TEST_COARSE_GRAINED_LOCK_IMPLEMENTATION + #include "../perf/coarse_grained_raii_lru_cache.h" + #define selected_raii_lru_cache_impl coarse_grained_raii_lru_cache +#else + #define TBB_PREVIEW_CONCURRENT_LRU_CACHE 1 + #include "tbb/concurrent_lru_cache.h" + #define selected_raii_lru_cache_impl tbb::concurrent_lru_cache +#endif + +#include "harness_test_cases_framework.h" +#include "harness.h" +#include "harness_barrier.h" + +#include <utility> + +#include "tbb/task_scheduler_init.h" + +namespace helpers{ + // Busy work and calibration helpers + unsigned int one_us_iters = 345; // default value + + // if user wants to calibrate to microseconds on particular machine, call + // this at beginning of program; sets one_us_iters to number of iters to + // busy_wait for approx. 1 us +// void calibrate_busy_wait() { +// tbb::tick_count t0, t1; +// +// t0 = tbb::tick_count::now(); +// for (volatile unsigned int i=0; i<1000000; ++i) continue; +// t1 = tbb::tick_count::now(); +// +// one_us_iters = (unsigned int)((1000000.0/(t1-t0).seconds())*0.000001); +// printf("one_us_iters: %d\n", one_us_iters); +// } + void busy_wait(int us) + { + unsigned int iter = us*one_us_iters; + for (volatile unsigned int i=0; i<iter; ++i) continue; + } +} +namespace helpers{ + template<class T> void ignore( const T& ) { } + //TODO: add test cases for prevent_optimizing_out function + template<typename type> + void prevent_optimizing_out(type volatile const& s){ + volatile const type* dummy = &s; + ignore(dummy); + } + + struct empty_fixture{}; + + template<typename argument_type> + struct native_for_concurrent_op_repeated:NoAssign{ + typedef void (*test_function_pointer_type)(argument_type&); + + argument_type& m_counter_ref; + test_function_pointer_type m_test_function_pointer_type; + std::size_t m_repeat_number; + native_for_concurrent_op_repeated(argument_type& counter_ref, test_function_pointer_type action, std::size_t repeat_number) + :m_counter_ref(counter_ref), m_test_function_pointer_type(action), m_repeat_number(repeat_number) + {} + template <typename ignored_parameter_type> + void operator()(ignored_parameter_type const&)const{ + for (size_t i=0; i<m_repeat_number;++i){ + m_test_function_pointer_type(m_counter_ref); + } + } + + }; + + template <typename counter_type = size_t> + struct object_instances_counting_type{ + counter_type * m_p_count; + object_instances_counting_type(): m_p_count (new counter_type){*m_p_count =1; } //to overcome absence of constructor in tbb::atomic + ~object_instances_counting_type(){ if (! --(*m_p_count)){delete(m_p_count);}} + object_instances_counting_type(object_instances_counting_type const& other): m_p_count(other.m_p_count){ + ++(*m_p_count); + } + object_instances_counting_type& operator=(object_instances_counting_type other){ + std::swap(this->m_p_count,other.m_p_count); + return *this; + } + size_t instances_count()const {return *m_p_count;} + }; + typedef object_instances_counting_type<> object_instances_counting_serial_type; + typedef object_instances_counting_type<tbb::atomic<std::size_t> > object_instances_counting_concurrent_type; + + namespace object_instances_counting_type_test_cases{ + namespace serial_tests{ + TEST_CASE_WITH_FIXTURE(test_object_instances_counting_type_creation,empty_fixture){ + ASSERT(object_instances_counting_serial_type().instances_count()==1,"newly created instance by definition has instances_count equal to 1"); + } + TEST_CASE_WITH_FIXTURE(test_object_instances_counting_type_copy,empty_fixture){ + object_instances_counting_serial_type source; + ASSERT(object_instances_counting_serial_type(source).instances_count()==2,"copy should increase ref count"); + } + TEST_CASE_WITH_FIXTURE(test_object_instances_counting_type_assignment,empty_fixture){ + object_instances_counting_serial_type source; + object_instances_counting_serial_type assigned; + assigned = source; + ASSERT(source.instances_count()==2,"assign should increase ref count"); + ASSERT(assigned.instances_count()==2,"assign should increase ref count"); + } + } + namespace concurrent_tests{ + typedef native_for_concurrent_op_repeated<object_instances_counting_concurrent_type> native_for_concurrent_op; + + struct native_for_single_op_repeated_fixture{ + object_instances_counting_concurrent_type source; + void run_native_for_and_assert_source_is_unique(native_for_concurrent_op::test_function_pointer_type operation,const char* msg){ + //TODO: refactor number of threads into separate fixture + const size_t number_of_threads = min(4,tbb::task_scheduler_init::default_num_threads()); + const size_t repeats_per_thread = 1000000; + + NativeParallelFor(number_of_threads , native_for_concurrent_op(source,operation,repeats_per_thread)); + ASSERT(source.instances_count()==1,msg); + } + + }; + TEST_CASE_WITH_FIXTURE(test_object_instances_counting_type_copy,native_for_single_op_repeated_fixture){ + struct _{ static void copy(object_instances_counting_concurrent_type& a_source){ + object_instances_counting_concurrent_type copy(a_source); + helpers::prevent_optimizing_out(copy); + }}; + run_native_for_and_assert_source_is_unique(&_::copy,"reference counting during copy construction/destruction is not thread safe ?"); + } + TEST_CASE_WITH_FIXTURE(test_object_instances_counting_type_assignment,native_for_single_op_repeated_fixture){ + struct _{ static void assign(object_instances_counting_concurrent_type& a_source){ + object_instances_counting_concurrent_type assigned; + assigned = a_source; + helpers::prevent_optimizing_out(assigned); + }}; + run_native_for_and_assert_source_is_unique(&_::assign,"reference counting during assigning/destruction is not thread safe ?"); + } + + } +} +} + +struct get_lru_cache_type{ + + template< typename parameter1, typename parameter2, typename parameter3=void> + struct apply{ + typedef selected_raii_lru_cache_impl<parameter1,parameter2,parameter3> type; + }; + template< typename parameter1, typename parameter2> + struct apply<parameter1,parameter2,void>{ + typedef selected_raii_lru_cache_impl<parameter1,parameter2> type; + }; + +}; + +// these includes are needed for test_task_handle_mv_sem* +#include <vector> +#include <string> +#include <functional> + +namespace serial_tests{ + using namespace helpers; + namespace usability{ + namespace compilation_only{ + TEST_CASE_WITH_FIXTURE(test_creation_and_use_interface,empty_fixture){ + struct dummy_function{static int _(int key){return key;}}; + typedef get_lru_cache_type::apply<int,int>::type cache_type; + size_t number_of_lru_history_items = 8; + cache_type cache((&dummy_function::_),(number_of_lru_history_items)); + int dummy_key=0; + cache_type::handle h = cache[dummy_key]; + int value = h.value(); + (void)value; + } + } + namespace behaviour { + namespace helpers { + template <size_t id> struct tag {}; + template< typename tag, typename value_and_key_type> + struct call_counting_function { + static int calls_count; + static value_and_key_type _(value_and_key_type key) { + ++calls_count; + return key; + } + }; + template< typename tag, typename value_and_key_type> + int call_counting_function<tag, value_and_key_type>::calls_count = 0; + } + + using std::string; + struct mv_sem_fixture { + struct item_init{ + static string init(string key) { + return key; + } + }; + typedef tbb::concurrent_lru_cache<string, string> cache_type; + typedef cache_type::handle handle_type; + cache_type cache; + mv_sem_fixture() : cache((&item_init::init), 1) {}; + + handle_type default_ctor_check; + }; + + TEST_CASE_WITH_FIXTURE(test_task_handle_mv_sem, mv_sem_fixture) { + handle_type handle; + handle_type foobar = handle_type(); + + //c++03 : handle_move_t assignment + handle = cache["handle"]; + + //c++03 : init ctor from handle_move_t + handle_type foo = cache["bar"]; + + //c++03 : init ctor from handle_move_t + handle_type handle1(move(handle)); + + //c++03 : handle_move_t assignment + handle = move(handle1); + + ASSERT(!handle_type(), "user-defined to-bool conversion does not work"); + ASSERT(handle, "user-defined to-bool conversion does not work"); + + handle = handle_type(); + } + + TEST_CASE_WITH_FIXTURE(test_task_handle_mv_sem_certain_case, mv_sem_fixture) { + // there is no way to use handle_object as vector argument in C++03 + // because argument must meet requirements of CopyAssignable and + // CopyConstructible (C++ documentation) +#if __TBB_CPP11_RVALUE_REF_PRESENT + // retain handle_object to keep an item in the cache if it is still active without aging + handle_type sheep = cache["sheep"]; + handle_type horse = cache["horse"]; + handle_type bull = cache["bull"]; + + std::vector<handle_type> animals; + animals.reserve(5); + animals.emplace_back(std::move(sheep)); + animals.emplace_back(std::move(horse)); + animals[0] = std::move(bull); + // after resize() vec will be full of default constructed handlers with null pointers + // on item in cache and on cache which item belongs to + animals.resize(10); +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + } + + TEST_CASE_WITH_FIXTURE(test_cache_returns_only_values_from_value_function,empty_fixture){ + struct dummy_function{static int _(int /*key*/){return 0xDEADBEEF;}}; + typedef get_lru_cache_type::apply<int,int>::type cache_type; + size_t number_of_lru_history_items = 8; + int dummy_key=1; + cache_type cache((&dummy_function::_),(number_of_lru_history_items)); + ASSERT(dummy_function::_(dummy_key)==cache[dummy_key].value(),"cache operator() must return only values obtained from value_function "); + } + + TEST_CASE_WITH_FIXTURE(test_value_function_called_only_on_cache_miss,empty_fixture){ + typedef helpers::tag<__LINE__> tag; + typedef helpers::call_counting_function<tag,int> function; + typedef get_lru_cache_type::apply<int,int>::type cache_type; + size_t number_of_lru_history_items = 8; + cache_type cache((&function::_),(number_of_lru_history_items)); + + int dummy_key=0; + cache[dummy_key]; + cache[dummy_key]; + ASSERT(function::calls_count==1,"value function should be called only on a cache miss"); + } + } + namespace helpers{ + using ::helpers::object_instances_counting_serial_type; + } + namespace helpers{ + template<typename value_type> + struct clonning_function:NoAssign{ + value_type& m_ref_original; + clonning_function(value_type& ref_original):m_ref_original(ref_original){} + template<typename key_type> + value_type operator()(key_type)const{ return m_ref_original;} + }; + } + struct instance_counting_fixture{ + static const size_t number_of_lru_history_items = 8; + + typedef helpers::clonning_function<helpers::object_instances_counting_serial_type> cloner_type; + typedef get_lru_cache_type::apply<size_t,helpers::object_instances_counting_serial_type,cloner_type>::type cache_type; + helpers::object_instances_counting_serial_type source; + cloner_type cloner; + cache_type cache; + + instance_counting_fixture():cloner((source)),cache(cloner,number_of_lru_history_items){} + }; + + TEST_CASE_WITH_FIXTURE(test_cache_stores_unused_objects,instance_counting_fixture){ + for (size_t i=0;i<number_of_lru_history_items;++i){ + cache[i]; + } + ASSERT(source.instances_count()> 1,"cache should store some unused objects "); + } + + TEST_CASE_WITH_FIXTURE(test_cache_stores_no_more_then_X_number_of_unused_objects,instance_counting_fixture){ + for (size_t i=0;i<number_of_lru_history_items+1;++i){ + cache[i]; + } + ASSERT(source.instances_count()== number_of_lru_history_items+1,"cache should respect number of stored unused objects to number passed in constructor"); + } + + namespace helpers{ + template< typename key_type, typename value_type> + struct map_searcher:NoAssign{ + typedef std::map<key_type,value_type> map_type; + map_type & m_map_ref; + map_searcher(map_type & map_ref): m_map_ref(map_ref) {} + value_type& operator()(key_type k){ + typename map_type::iterator it =m_map_ref.find(k); + if (it==m_map_ref.end()){ + it = m_map_ref.insert(it,std::make_pair(k,value_type())); + } + return it->second; + } + }; + } + + struct filled_instance_counting_fixture_with_external_map{ + static const size_t number_of_lru_history_items = 8; + + typedef helpers::map_searcher<size_t,helpers::object_instances_counting_serial_type> map_searcher_type; + typedef map_searcher_type::map_type objects_map_type; + typedef get_lru_cache_type::apply<size_t,helpers::object_instances_counting_serial_type,map_searcher_type>::type cache_type; + map_searcher_type::map_type objects_map; + cache_type cache; + filled_instance_counting_fixture_with_external_map():cache(map_searcher_type(objects_map),number_of_lru_history_items){} + bool is_evicted(size_t k){ + objects_map_type::iterator it =objects_map.find(k); + ASSERT(it!=objects_map.end(),"no value for key - error in test logic ?"); + return it->second.instances_count()==1; + } + void fill_up_cache(size_t lower_bound, size_t upper_bound){ + for (size_t i=lower_bound;i<upper_bound;++i){ + cache[i]; + } + } + }; + + TEST_CASE_WITH_FIXTURE(test_cache_should_evict_unused_objects_lru_order,filled_instance_counting_fixture_with_external_map){ + ASSERT(number_of_lru_history_items > 2,"incorrect test setup"); + fill_up_cache(0,number_of_lru_history_items); + //heat up first element + cache[0]; + //cause eviction + cache[number_of_lru_history_items]; + ASSERT(is_evicted(1) && !is_evicted(0),"cache should evict items in lru order"); + } + + TEST_CASE_WITH_FIXTURE(test_live_handler_object_prevents_item_from_eviction,filled_instance_counting_fixture_with_external_map){ + cache_type::handle h = cache[0]; + //cause eviction + fill_up_cache(1,number_of_lru_history_items+2); + ASSERT(is_evicted(1) && !is_evicted(0),"cache should not evict items in use"); + } + TEST_CASE_WITH_FIXTURE(test_live_handler_object_is_ref_counted,filled_instance_counting_fixture_with_external_map){ + cache_type::handle h = cache[0]; + { + cache_type::handle h1 = cache[0]; + } + //cause eviction + fill_up_cache(1,number_of_lru_history_items+2); + ASSERT(is_evicted(1) && !is_evicted(0),"cache should not evict items in use"); + } + } +} + + +namespace concurrency_tests{ + namespace helpers{ + using namespace ::helpers; + } + namespace helpers{ + //key_type must be convertible to array index + template< typename key_type, typename value_type, size_t array_size> + struct array_searcher:NoAssign{ + typedef value_type array_type[array_size]; + array_type const& m_array_ref; + array_searcher(array_type const& array_ref): m_array_ref(array_ref) {} + const value_type& operator()(key_type k)const{ + size_t index = k; + ASSERT(k < array_size,"incorrect test setup"); + return m_array_ref[index]; + } + }; + } + + struct filled_instance_counting_fixture_with_external_array{ + static const size_t number_of_lru_history_items = 8; + static const size_t array_size = 16*number_of_lru_history_items; + + typedef helpers::array_searcher<size_t,helpers::object_instances_counting_concurrent_type,array_size> array_searcher_type; + typedef array_searcher_type::array_type objects_array_type; + typedef get_lru_cache_type::apply<size_t,helpers::object_instances_counting_concurrent_type,array_searcher_type>::type cache_type; + array_searcher_type::array_type objects_array; + cache_type cache; + filled_instance_counting_fixture_with_external_array():cache(array_searcher_type(objects_array),number_of_lru_history_items){} + bool is_evicted(size_t k)const{ + return array_searcher_type(objects_array)(k).instances_count()==1; + } + void fill_up_cache(size_t lower_bound, size_t upper_bound){ + for (size_t i=lower_bound;i<upper_bound;++i){ + cache[i]; + } + } + size_t number_of_non_evicted_from_cache()const{ + size_t result=0; + for (size_t i=0; i<array_size; ++i){ + if (!this->is_evicted(i)){ + ++result; + } + } + return result; + } + }; + + + //TODO: make this more reproducible + //TODO: split this test case in two parts + TEST_CASE_WITH_FIXTURE(correctness_of_braces_and_handle_destructor,filled_instance_counting_fixture_with_external_array){ + typedef correctness_of_braces_and_handle_destructor self_type; + struct _{static void use_cache(self_type& tc){ + for (size_t i=0;i<array_size;++i){ + cache_type::handle h=tc.cache[i]; + helpers::prevent_optimizing_out(h.value()); + } + + }}; + static const size_t repeat_number = 2; + static const size_t number_of_threads = 4 * tbb::task_scheduler_init::default_num_threads(); //have 4x over subscription + static const size_t repeats_per_thread = 4; + + for (size_t i=0; i < repeat_number; i++){ + NativeParallelFor(number_of_threads,helpers::native_for_concurrent_op_repeated<self_type>(*this,&_::use_cache,repeats_per_thread)); + fill_up_cache(0,array_size); + ASSERT(number_of_non_evicted_from_cache()==number_of_lru_history_items,"thread safety is broken for cache "); + } + } +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_map.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_map.cpp new file mode 100644 index 00000000..3ed8e88b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_map.cpp @@ -0,0 +1,265 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define __TBB_EXTRA_DEBUG 1 +#if _MSC_VER +#define _SCL_SECURE_NO_WARNINGS +#endif + +#include "tbb/tbb_config.h" +#include "harness.h" +#if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT + +#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1 +#include "tbb/concurrent_map.h" +#if __TBB_INITIALIZER_LISTS_PRESENT +// These operator== are used implicitly in test_initializer_list.h. +// For some unknown reason clang is not able to find the if they a declared after the +// inclusion of test_initializer_list.h. +template<typename container_type> +bool equal_containers( container_type const& lhs, container_type const& rhs ); +template<typename Key, typename Value> +bool operator==( tbb::concurrent_map<Key, Value> const& lhs, tbb::concurrent_map<Key, Value> const& rhs ) { + return equal_containers( lhs, rhs ); +} +template<typename Key, typename Value> +bool operator==( tbb::concurrent_multimap<Key, Value> const& lhs, tbb::concurrent_multimap<Key, Value> const& rhs ) { + return equal_containers( lhs, rhs ); +} +#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ +#include "test_concurrent_ordered_common.h" + +typedef tbb::concurrent_map<int, int, std::less<int>, MyAllocator> MyMap; +typedef tbb::concurrent_map<int, int, std::greater<int>, MyAllocator> MyGreaterMap; +typedef tbb::concurrent_map<int, check_type<int>, std::less<int>, MyAllocator> MyCheckedMap; +typedef tbb::concurrent_map<intptr_t, FooWithAssign, std::less<intptr_t>, MyAllocator> MyCheckedStateMap; +typedef tbb::concurrent_multimap<int, int, std::less<int>, MyAllocator> MyMultiMap; +typedef tbb::concurrent_multimap<int, int, std::greater<int>, MyAllocator> MyGreaterMultiMap; +typedef tbb::concurrent_multimap<int, check_type<int>, std::less<int>, MyAllocator> MyCheckedMultiMap; + +template <> +struct SpecialTests <MyMap> { + static void Test( const char *str ) { + SpecialMapTests<MyMap>(str); + } +}; + +template <> +struct SpecialTests <MyMultiMap> { + static void Test( const char *str ) { + SpecialMultiMapTests<MyMultiMap>(str); + } +}; + +struct co_map_type : ordered_move_traits_base { + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_map<element_type, element_type, std::less<element_type>, allocator_type > type; + }; + + typedef FooPairIterator init_iterator_type; +}; + +struct co_multimap_type : ordered_move_traits_base { + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_multimap<element_type, element_type, std::less<element_type>, allocator_type > type; + }; + + typedef FooPairIterator init_iterator_type; +}; + +template <bool defCtorPresent, typename Key, typename Element, typename Compare, typename Allocator> +void TestMapSpecificMethods( tbb::concurrent_map<Key, Element, Compare, Allocator> &c, + const typename tbb::concurrent_map<Key, Element, Compare, Allocator>::value_type &value ) { + TestMapSpecificMethodsImpl<defCtorPresent>(c, value); + } + +struct OrderedMapTypesTester{ + template <bool defCtorPresent, typename ValueType> + void check( const std::list<ValueType> &lst ) { + typedef typename ValueType::first_type KeyType; + typedef typename ValueType::second_type ElemType; + TypeTester< defCtorPresent, tbb::concurrent_map< KeyType, ElemType>, + tbb::concurrent_map< KeyType, ElemType, std::less<KeyType>, debug_allocator<ValueType> > >( lst ); + TypeTester< defCtorPresent, tbb::concurrent_multimap< KeyType, ElemType>, + tbb::concurrent_multimap< KeyType, ElemType, std::less<KeyType>, debug_allocator<ValueType> > >( lst ); + } +}; + +void TestTypes() { + TestMapCommonTypes<OrderedMapTypesTester>(); + + #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT + // Regression test for a problem with excessive requirements of emplace() + test_emplace_insert<tbb::concurrent_map< int*, test::unique_ptr<int> >, + tbb::internal::false_type>( new int, new int ); + test_emplace_insert<tbb::concurrent_multimap< int*, test::unique_ptr<int> >, + tbb::internal::false_type>( new int, new int ); + #endif /*__TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT*/ +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +template <template <typename...> typename TMap> +void TestDeductionGuides() { + std::vector<std::pair<int, int>> v(10, {0, 0}); + TMap map(v.begin(), v.end()); + static_assert(std::is_same_v<decltype(map), TMap<int, int> >, "WRONG\n"); + //print(map); + + std::greater<int> compare; + std::allocator<int> allocator; + TMap map2(v.begin(), v.end(), compare); + static_assert(std::is_same_v<decltype(map2), TMap<int, int, decltype(compare)> >, "WRONG\n"); + + TMap map3(v.begin(), v.end(), allocator); + static_assert(std::is_same_v<decltype(map3), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n"); + + TMap map4(v.begin(), v.end(), compare, allocator); + static_assert(std::is_same_v<decltype(map4), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n"); + + using pair_t = std::pair<const int, int>; + auto init = { pair_t{1, 1}, pair_t{2, 2}, pair_t{3, 3} }; + TMap map5(init); + static_assert(std::is_same_v<decltype(map5), TMap<int, int> >, "WRONG\n"); + + TMap map6(init, compare); + static_assert(std::is_same_v<decltype(map6), TMap<int, int, decltype(compare)> >, "WRONG\n"); + + TMap map7(init, allocator); + static_assert(std::is_same_v<decltype(map7), TMap<int, int, std::less<int>, decltype(allocator)> >, "WRONG\n"); + + TMap map8(init, compare, allocator); + static_assert(std::is_same_v<decltype(map8), TMap<int, int, decltype(compare), decltype(allocator)> >, "WRONG\n"); +} +#endif + +void test_heterogeneous_functions() { + check_heterogeneous_functions<tbb::concurrent_map<int, int, transparent_less> >(); + check_heterogeneous_functions<tbb::concurrent_multimap<int, int, transparent_less> >(); +} + +void multicontainer_specific_test() { + check_multicontainer_internal_order<tbb::concurrent_multimap<int, int> >(); + check_multicontainer_internal_order<tbb::concurrent_multimap<int, int, std::greater<int> > >(); +} + +#if !__TBB_SCOPED_ALLOCATOR_BROKEN +#include <scoped_allocator> + +template <template<typename...> class Map> +void test_scoped_allocator() { + using allocator_data_type = allocator_aware_data<std::scoped_allocator_adaptor<tbb::tbb_allocator<int>>>; + using allocator_type = std::scoped_allocator_adaptor<tbb::tbb_allocator<allocator_data_type>>; + using map_type = Map<allocator_data_type, allocator_data_type, allocator_data_compare, allocator_type>; + + allocator_type allocator; + allocator_data_type key1(1, allocator), key2(2, allocator); + allocator_data_type data1(1, allocator), data2(2, allocator); + map_type map1(allocator), map2(allocator); + + typename map_type::value_type v1(key1, data1), v2(key2, data2); + + auto init_list = { v1, v2 }; + + allocator_data_type::assert_on_constructions = true; + map1.emplace(key1, data1); + map2.emplace(key2, std::move(data2)); + + map1.clear(); + map2.clear(); + + map1.insert(v1); + map2.insert(std::move(v2)); + + map1.clear(); + map2.clear(); + + map1.insert(init_list); + + map1.clear(); + map2.clear(); + + map1 = map2; + map2 = std::move(map1); + + map1.swap(map2); + + allocator_data_type::assert_on_constructions = false; +} +#endif // !__TBB_SCOPED_ALLOCATOR_BROKEN + +int TestMain() { + test_machine(); + + test_basic<MyMap>( "concurrent Map" ); + test_basic<MyGreaterMap>( "concurrent greater Map" ); + test_concurrent<MyMap>( "concurrent Map" ); + test_concurrent<MyGreaterMap>( "concurrent greater Map" ); + test_basic<MyMultiMap>( "concurrent MultiMap" ); + test_basic<MyGreaterMultiMap>( "concurrent greater MultiMap" ); + test_concurrent<MyMultiMap>( "concurrent MultiMap" ); + test_concurrent<MyGreaterMultiMap>( "concurrent greater MultiMap" ); + + { Check<MyCheckedMap::value_type> checkit; test_basic<MyCheckedMap>( "concurrent map (checked)" ); } + { Check<MyCheckedMap::value_type> checkit; test_concurrent<MyCheckedMap>( "concurrent map (checked)" ); } + test_basic<MyCheckedStateMap>("concurrent map (checked state of elements)", tbb::internal::true_type()); + test_concurrent<MyCheckedStateMap>("concurrent map (checked state of elements)"); + + { Check<MyCheckedMultiMap::value_type> checkit; test_basic<MyCheckedMultiMap>( "concurrent MultiMap (checked)" ); } + { Check<MyCheckedMultiMap::value_type> checkit; test_concurrent<MyCheckedMultiMap>( "concurrent MultiMap (checked)" ); } + + multicontainer_specific_test(); + + TestInitList< tbb::concurrent_map<int, int>, + tbb::concurrent_multimap<int, int> >( {{1,1},{2,2},{3,3},{4,4},{5,5}} ); + +#if __TBB_RANGE_BASED_FOR_PRESENT + TestRangeBasedFor<MyMap>(); + TestRangeBasedFor<MyMultiMap>(); +#endif + + test_rvalue_ref_support<co_map_type>( "concurrent map" ); + test_rvalue_ref_support<co_multimap_type>( "concurrent multimap" ); + + TestTypes(); + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides<tbb::concurrent_map>(); + TestDeductionGuides<tbb::concurrent_multimap>(); +#endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT*/ + + node_handling::TestNodeHandling<MyMap>(); + node_handling::TestNodeHandling<MyMultiMap>(); + node_handling::TestMerge<MyMap, MyMultiMap>(1000); + + test_heterogeneous_functions(); + + test_allocator_traits<tbb::concurrent_map, int, int, std::less<int>>(); + test_allocator_traits<tbb::concurrent_multimap, int, int, std::less<int>>(); + +#if !__TBB_SCOPED_ALLOCATOR_BROKEN + test_scoped_allocator<tbb::concurrent_map>(); + test_scoped_allocator<tbb::concurrent_multimap>(); +#endif + + return Harness::Done; +} +#else +int TestMain() { + return Harness::Skipped; +} +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_monitor.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_monitor.cpp new file mode 100644 index 00000000..75a2544a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_monitor.cpp @@ -0,0 +1,365 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 6 +#define HARNESS_DEFAULT_MAX_THREADS 8 + +#include "tbb/concurrent_monitor.h" +#include "tbb/atomic.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" +#include "harness.h" +#if _WIN32||_WIN64 +#include "tbb/dynamic_link.cpp" +#endif + +#include "tbb/semaphore.cpp" +#include "tbb/concurrent_monitor.cpp" + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + // Suppress compiler warning about constant conditional expression + #pragma warning (disable: 4127) +#endif + +using namespace tbb; + +//! Queuing lock with concurrent_monitor; to test concurrent_monitor::notify( Predicate p ) +class QueuingMutex { +public: + //! Construct unacquired mutex. + QueuingMutex() { q_tail = NULL; } + + //! The scoped locking pattern + class ScopedLock: internal::no_copy { + void Initialize() { mutex = NULL; } + public: + ScopedLock() {Initialize();} + ScopedLock( QueuingMutex& m, size_t test_mode ) { Initialize(); Acquire(m,test_mode); } + ~ScopedLock() { if( mutex ) Release(); } + void Acquire( QueuingMutex& m, size_t test_mode ); + void Release(); + void SleepPerhaps(); + + private: + QueuingMutex* mutex; + ScopedLock* next; + uintptr_t going; + internal::concurrent_monitor::thread_context thr_ctx; + }; + + friend class ScopedLock; +private: + //! The last competitor requesting the lock + atomic<ScopedLock*> q_tail; + internal::concurrent_monitor waitq; +}; + +struct PredicateEq { + uintptr_t p; + PredicateEq( uintptr_t p_ ) : p(p_) {} + bool operator() ( uintptr_t v ) const {return p==v;} +}; + +struct QueuingMutex_Context { + const QueuingMutex::ScopedLock* lck; + QueuingMutex_Context( QueuingMutex::ScopedLock* l_ ) : lck(l_) {} + uintptr_t operator()() { return uintptr_t(lck); } +}; + +struct QueuingMutex_Until : NoAssign { + uintptr_t& flag; + QueuingMutex_Until( uintptr_t& f_ ) : flag(f_) {} + bool operator()() { return flag!=0ul; } +}; + +//! A method to acquire QueuingMutex lock +void QueuingMutex::ScopedLock::Acquire( QueuingMutex& m, size_t test_mode ) +{ + // Must set all fields before the fetch_and_store, because once the + // fetch_and_store executes, *this becomes accessible to other threads. + mutex = &m; + next = NULL; + going = 0; + + // The fetch_and_store must have release semantics, because we are + // "sending" the fields initialized above to other processors. + ScopedLock* pred = m.q_tail.fetch_and_store<tbb::release>(this); + if( pred ) { +#if TBB_USE_ASSERT + __TBB_control_consistency_helper(); // on "m.q_tail" + ASSERT( !pred->next, "the predecessor has another successor!"); +#endif + pred->next = this; + for( int i=0; i<16; ++i ) { + if( going!=0ul ) break; + __TBB_Yield(); + } + int x = int( test_mode%3 ); + switch( x ) { + case 0: + mutex->waitq.wait( QueuingMutex_Until(going), QueuingMutex_Context(this) ); + break; +#if __TBB_CPP11_LAMBDAS_PRESENT + case 1: + mutex->waitq.wait( [&](){ return going!=0ul; }, [=]() { return (uintptr_t)this; } ); + break; +#endif + default: + SleepPerhaps(); + break; + } + } + + // Acquire critical section indirectly from previous owner or directly from predecessor. + __TBB_control_consistency_helper(); // on either "m.q_tail" or "going" +} + +//! A method to release QueuingMutex lock +void QueuingMutex::ScopedLock::Release( ) +{ + if( !next ) { + if( this == mutex->q_tail.compare_and_swap<tbb::release>(NULL, this) ) { + // this was the only item in the queue, and the queue is now empty. + goto done; + } + // Someone in the queue + spin_wait_while_eq( next, (ScopedLock*)0 ); + } + __TBB_store_with_release(next->going, 1); + mutex->waitq.notify( PredicateEq(uintptr_t(next)) ); +done: + Initialize(); +} + +//! Yield and block; go to sleep +void QueuingMutex::ScopedLock::SleepPerhaps() +{ + bool slept = false; + internal::concurrent_monitor& mq = mutex->waitq; + mq.prepare_wait( thr_ctx, uintptr_t(this) ); + while( going==0ul ) { + if( (slept=mq.commit_wait( thr_ctx ))==true && going!=0ul ) + break; + slept = false; + mq.prepare_wait( thr_ctx, uintptr_t(this) ); + } + if( !slept ) + mq.cancel_wait( thr_ctx ); +} + +// Spin lock with concurrent_monitor; to test concurrent_monitor::notify_all() and concurrent_monitor::notify() +class SpinMutex { +public: + //! Construct unacquired mutex. + SpinMutex() : toggle(false) { flag = 0; } + + //! The scoped locking pattern + class ScopedLock: internal::no_copy { + void Initialize() { mutex = NULL; } + public: + ScopedLock() {Initialize();} + ScopedLock( SpinMutex& m, size_t test_mode ) { Initialize(); Acquire(m,test_mode); } + ~ScopedLock() { if( mutex ) Release(); } + void Acquire( SpinMutex& m, size_t test_mode ); + void Release(); + void SleepPerhaps(); + + private: + SpinMutex* mutex; + internal::concurrent_monitor::thread_context thr_ctx; + }; + + friend class ScopedLock; + friend struct SpinMutex_Until; +private: + tbb::atomic<unsigned> flag; + bool toggle; + internal::concurrent_monitor waitq; +}; + +struct SpinMutex_Context { + const SpinMutex::ScopedLock* lck; + SpinMutex_Context( SpinMutex::ScopedLock* l_ ) : lck(l_) {} + uintptr_t operator()() { return uintptr_t(lck); } +}; + +struct SpinMutex_Until { + const SpinMutex* mtx; + SpinMutex_Until( SpinMutex* m_ ) : mtx(m_) {} + bool operator()() { return mtx->flag==0; } +}; + +//! A method to acquire SpinMutex lock +void SpinMutex::ScopedLock::Acquire( SpinMutex& m, size_t test_mode ) +{ + mutex = &m; +retry: + if( m.flag.compare_and_swap( 1, 0 )!=0 ) { + int x = int( test_mode%3 ); + switch( x ) { + case 0: + mutex->waitq.wait( SpinMutex_Until(mutex), SpinMutex_Context(this) ); + break; +#if __TBB_CPP11_LAMBDAS_PRESENT + case 1: + mutex->waitq.wait( [&](){ return mutex->flag==0; }, [=]() { return (uintptr_t)this; } ); + break; +#endif + default: + SleepPerhaps(); + break; + } + goto retry; + } +} + +//! A method to release SpinMutex lock +void SpinMutex::ScopedLock::Release() +{ + bool old_toggle = mutex->toggle; + mutex->toggle = !mutex->toggle; + mutex->flag = 0; + if( old_toggle ) + mutex->waitq.notify_one(); + else + mutex->waitq.notify_all(); +} + +//! Yield and block; go to sleep +void SpinMutex::ScopedLock::SleepPerhaps() +{ + bool slept = false; + internal::concurrent_monitor& mq = mutex->waitq; + mq.prepare_wait( thr_ctx, uintptr_t(this) ); + while( mutex->flag ) { + if( (slept=mq.commit_wait( thr_ctx ))==true ) + break; + mq.prepare_wait( thr_ctx, uintptr_t(this) ); + } + if( !slept ) + mq.cancel_wait( thr_ctx ); +} + +//! A value protected by a mutex. +template<typename M> +struct Counter { + typedef M mutex_type; + M mutex; + long value; +}; + +//! Function object for use with parallel_for.h. +template<typename C, int D> +struct AddOne: NoAssign { + C& counter; + /** Increments counter once for each iteration in the iteration space. */ + void operator()( tbb::blocked_range<size_t>& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + typename C::mutex_type::ScopedLock lock(counter.mutex, i); + counter.value = counter.value+1; + if( D>0 ) + for( int j=0; j<D; ++j ) __TBB_Yield(); + } + } + AddOne( C& counter_ ) : counter(counter_) {} +}; + +//! Generic test with TBB mutex type M, max range R, and delay D. +template<typename M,int R, int D> +void Test( int p ) { + Counter<M> counter; + counter.value = 0; + const int n = R; + tbb::task_scheduler_init init(p); + tbb::parallel_for(tbb::blocked_range<size_t>(0,n,n/10),AddOne<Counter<M>,D>(counter)); + if( counter.value!=n ) + REPORT("ERROR : counter.value=%ld (instead of %ld)\n",counter.value,n); +} + +#if TBB_USE_EXCEPTIONS +#define NTHRS_USED_IN_DESTRUCTOR_TEST 8 + +atomic<size_t> n_sleepers; + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4244 4267) +#endif + +struct AllButOneSleep : NoAssign { + internal::concurrent_monitor*& mon; + static const size_t VLN = 1024*1024; + void operator()( int i ) const { + internal::concurrent_monitor::thread_context thr_ctx; + + if( i==0 ) { + size_t n_expected_sleepers = NTHRS_USED_IN_DESTRUCTOR_TEST-1; + while( n_sleepers<n_expected_sleepers ) + __TBB_Yield(); + while( n_sleepers.compare_and_swap( VLN+NTHRS_USED_IN_DESTRUCTOR_TEST, n_expected_sleepers )!=n_expected_sleepers ) + __TBB_Yield(); + + for( int j=0; j<100; ++j ) + Harness::Sleep( 1 ); + delete mon; + mon = NULL; + } else { + mon->prepare_wait( thr_ctx, uintptr_t(this) ); + while( n_sleepers<VLN ) { + try { + ++n_sleepers; + mon->commit_wait( thr_ctx ); + if( --n_sleepers>VLN ) + break; + } catch( tbb::user_abort& ) { + // can no longer access 'mon' + break; + } + mon->prepare_wait( thr_ctx, uintptr_t(this) ); + } + } + } + AllButOneSleep( internal::concurrent_monitor*& m_ ) : mon(m_) {} +}; +#endif /* TBB_USE_EXCEPTIONS */ + +void TestDestructor() { +#if TBB_USE_EXCEPTIONS + tbb::task_scheduler_init init(NTHRS_USED_IN_DESTRUCTOR_TEST); + internal::concurrent_monitor* my_mon = new internal::concurrent_monitor; + REMARK( "testing the destructor\n" ); + n_sleepers = 0; + NativeParallelFor(NTHRS_USED_IN_DESTRUCTOR_TEST,AllButOneSleep(my_mon)); + ASSERT( my_mon==NULL, "" ); +#endif /* TBB_USE_EXCEPTIONS */ +} + +int TestMain () { + for( int p=MinThread; p<=MaxThread; ++p ) { + REMARK( "testing with %d workers\n", static_cast<int>(p) ); + // test the predicated notify + Test<QueuingMutex,100000,0>( p ); + Test<QueuingMutex,1000,10000>( p ); + // test the notify_all method + Test<SpinMutex,100000,0>( p ); + Test<SpinMutex,1000,10000>( p ); + REMARK( "calling destructor for task_scheduler_init\n" ); + } + TestDestructor(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_ordered_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_ordered_common.h new file mode 100644 index 00000000..1e5087c5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_ordered_common.h @@ -0,0 +1,375 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "test_concurrent_associative_common.h" + +// Now empty ordered container allocations count is checked by upper bound (calculated manually) +const size_t dummy_head_max_size = 584; + +template<typename MyTable> +inline void CheckEmptyContainerAllocator(MyTable &table, size_t expected_allocs, size_t expected_frees, bool exact, int line) { + typename MyTable::allocator_type a = table.get_allocator(); + REMARK("#%d checking allocators: items %u/%u, allocs %u/%u\n", line, + unsigned(a.items_allocated), unsigned(a.items_freed), unsigned(a.allocations), unsigned(a.frees) ); + CheckAllocator<MyTable>(a, expected_allocs, expected_frees, exact); + ASSERT( a.items_allocated <= a.items_freed + dummy_head_max_size, NULL); +} + +template <typename Table> +struct order_checker { + typename Table::value_compare& val_comp; + typename Table::key_compare& key_comp; + + order_checker(typename Table::value_compare& _val_c,typename Table::key_compare& _key_c): val_comp(_val_c), key_comp(_key_c){} + + + bool operator()(const typename Table::value_type& lhs, const typename Table::value_type& rhs){ + if (Table::allow_multimapping) + // We need to use not greater comparator for multicontainers + return !val_comp(rhs, lhs) && !key_comp(Value<Table>::key(rhs), Value<Table>::key(lhs)); + return val_comp(lhs,rhs) && key_comp(Value<Table>::key(lhs),Value<Table>::key(rhs)); + } +}; + +template< typename Table> +void check_container_order(const Table& cont) { + if (!cont.empty()){ + typename Table::key_compare key_comp = cont.key_comp(); + typename Table::value_compare value_comp = cont.value_comp(); + order_checker<Table> check_order(value_comp, key_comp); + + for (auto it = cont.begin(); std::next(it)!=cont.end();){ + auto pr_it = it++; + ASSERT(check_order(*pr_it, *it),"The order of the elements is broken"); + } + } +} + +template <typename T> +void test_ordered_methods() { + T cont; + + int r, random_threshold = 10, uncontained_key = random_threshold / 2; + for (int i = 0; i < 100; i++) { + r = std::rand() % random_threshold; + if ( r != uncontained_key) { + cont.insert(Value<T>::make(r)); + } + } + + check_container_order(cont); + + typename T::value_compare val_comp = cont.value_comp(); + typename T::iterator l_bound_check, u_bound_check; + for (int key = -1; key < random_threshold + 1; key++) { + + auto eq_range = cont.equal_range(key); + // Check equal_range() content + for (auto it = eq_range.first; it != eq_range.second; it++) + ASSERT(*it == Value<T>::make(key), "equal_range() contain wrong value"); + + // Manual search of upper and lower bounds + l_bound_check = cont.end(); + u_bound_check = cont.end(); + for (auto it = cont.begin() ; it != cont.end(); it++){ + if (!val_comp(*it, Value<T>::make(key)) && l_bound_check == cont.end()){ + l_bound_check = it; + } + if (val_comp(Value<T>::make(key),*it) && u_bound_check == cont.end()){ + u_bound_check = it; + break; + } + } + + typename T::iterator l_bound = cont.lower_bound(key); + typename T::iterator u_bound = cont.upper_bound(key); + + ASSERT(l_bound == l_bound_check, "lower_bound() contains wrong value"); + ASSERT(u_bound == u_bound_check, "upper_bound() contains wrong value"); + + ASSERT(l_bound == eq_range.first && u_bound == eq_range.second, NULL); + } +} + +template<typename T, typename do_check_element_state> +void test_basic(const char * str, do_check_element_state) +{ + test_basic_common<T>(str, do_check_element_state()); + test_ordered_methods<T>(); +} + +template<typename T> +void test_basic(const char * str){ + test_basic_common<T>(str); + test_ordered_methods<T>(); +} + +template<typename T> +void test_concurrent_order() { + for (auto num_threads = MinThread + 1; num_threads <= MaxThread; num_threads++) { + T cont; + int items = 1000; + NativeParallelFor( num_threads, [&](size_t index){ + int step = index % 4 + 1; + bool reverse = (step % 2 == 0); + if (reverse) { + for (int i = 0; i < items; i+=step){ + cont.insert(Value<T>::make(i)); + } + } else { + for (int i = items; i > 0; i-=step){ + cont.insert(Value<T>::make(i)); + } + } + } ); + + check_container_order(cont); + } +} + +template<typename T> +void test_concurrent(const char *tablename, bool asymptotic = false) { + test_concurrent_common<T>(tablename, asymptotic); + test_concurrent_order<T>(); +} + +// If the inserted elements look the same for the comparator, +// they must be inserted in order from the first inserted to the last. +template<typename T> +void check_multicontainer_internal_order(){ + T cont; + for (int counter = 0; counter < 10; counter++){ + cont.emplace(1, counter); + } + + for ( auto it = cont.begin(); std::next(it) != cont.end();){ + auto it_pr = it++; + ASSERT(it_pr->second < it->second, "Internal multicontainers order is broken"); + } +} + +struct ordered_move_traits_base { + enum{ expected_number_of_items_to_allocate_for_steal_move = dummy_head_max_size }; + + template <typename ordered_type, typename iterator_type> + static ordered_type& construct_container(tbb::aligned_space<ordered_type> & storage, iterator_type begin, iterator_type end){ + new (storage.begin()) ordered_type(begin, end); + return * storage.begin(); + } + + template <typename ordered_type, typename iterator_type, typename allocator_type> + static ordered_type& construct_container(tbb::aligned_space<ordered_type> & storage, iterator_type begin, iterator_type end, allocator_type const& a ){ + new (storage.begin()) ordered_type(begin, end, typename ordered_type::key_compare(), a); + return * storage.begin(); + } + + template<typename ordered_type, typename iterator> + static bool equal(ordered_type const& c, iterator begin, iterator end){ + bool equal_sizes = ( static_cast<size_t>(std::distance(begin, end)) == c.size() ); + if (!equal_sizes) + return false; + for (iterator it = begin; it != end; ++it ){ + if (c.find( Value<ordered_type>::key(*it)) == c.end()){ + return false; + } + } + return true; + } +}; + +namespace std { + template<> struct less< std::weak_ptr<int> > { + public: + size_t operator()( const std::weak_ptr<int>& lhs, const std::weak_ptr<int>& rhs ) const { return *lhs.lock() < * rhs.lock(); } + }; + template<> struct less< const std::weak_ptr<int> > { + public: + size_t operator()( const std::weak_ptr<int>& lhs, const std::weak_ptr<int>& rhs ) const { return *lhs.lock() < * rhs.lock(); } + }; +} + +template <bool defCtorPresent, typename Table> +void CustomExamine( Table, const std::list<typename Table::value_type>) { + /*order check - see unordered example*/ +} + +template <bool defCtorPresent, typename Table> +void Examine( Table c, const std::list<typename Table::value_type> &lst) { + CommonExamine<defCtorPresent>(c, lst); + CustomExamine<defCtorPresent>(c, lst); +} + +template <bool defCtorPresent, typename Table, typename TableDebugAlloc> +void TypeTester( const std::list<typename Table::value_type> &lst ) { + ASSERT( lst.size() >= 5, "Array should have at least 5 elements" ); + ASSERT( lst.size() <= 100, "The test has O(n^2) complexity so a big number of elements can lead long execution time" ); + // Construct an empty table. + Table c1; + c1.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c1, lst ); + + typename Table::key_compare compare; + + typename Table::allocator_type allocator; +#if __TBB_INITIALIZER_LISTS_PRESENT && !__TBB_CPP11_INIT_LIST_TEMP_OBJS_LIFETIME_BROKEN + // Constructor from an initializer_list. + typename std::list<typename Table::value_type>::const_iterator it = lst.begin(); + Table c2( { *it++, *it++, *it++ } ); + c2.insert( it, lst.end( ) ); + Examine<defCtorPresent>( c2, lst ); + + it = lst.begin(); + // Constructor from an initializer_list, default comparator and non-default allocator + Table c2_alloc( { *it++, *it++, *it++ }, allocator); + c2_alloc.insert( it, lst.end() ); + Examine<defCtorPresent>( c2_alloc, lst ); + + it = lst.begin(); + // Constructor from an initializer_list, non-default comparator and allocator + Table c2_comp_alloc( { *it++, *it++, *it++ }, compare, allocator ); + c2_comp_alloc.insert( it, lst.end() ); + Examine<defCtorPresent>( c2_comp_alloc, lst ); +#endif + // Copying constructor. + Table c3( c1 ); + Examine<defCtorPresent>( c3, lst ); + // Construct with non-default allocator + TableDebugAlloc c4; + c4.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c4, lst ); + // Copying constructor for a container with a different allocator type. + TableDebugAlloc c5( c4 ); + Examine<defCtorPresent>( c5, lst ); + + // Construction empty table with non-default comparator + Table c6( compare ); + c6.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c6, lst ); + + // Construction empty table with non-default allocator + Table c6_alloc( allocator ); + c6_alloc.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c6_alloc, lst ); + + // Construction empty table with a non-default comparator and allocator + Table c6_comp_alloc( compare, allocator ); + c6_comp_alloc.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c6_alloc, lst ); + + // Construction empty table with a non-default comparator and allocator + TableDebugAlloc c7( compare ); + c7.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c7, lst ); + + // Construction with a copying iteration range and a given allocator instance. + Table c8( c1.begin(), c1.end() ); + Examine<defCtorPresent>( c8, lst ); + + // Construction with a copying iteration range, default compare and non-default allocator + Table c8_alloc( c1.begin(), c1.end(), allocator ); + Examine<defCtorPresent>( c8_alloc, lst ); + + // Construction with a copying iteration range, non-default compare and allocator + Table c8_comp_alloc( c1.begin(), c1.end(), compare, allocator ); + Examine<defCtorPresent>( c8_comp_alloc, lst); + + // Construction with an instance of non-default allocator + typename TableDebugAlloc::allocator_type a; + TableDebugAlloc c9( a ); + c9.insert( c7.begin(), c7.end() ); + Examine<defCtorPresent>( c9, lst ); +} + +struct int_key { + int_key(int i) : my_item(i) {} + int my_item; +}; + +bool operator<(const int_key& ik, int i) { return ik.my_item < i; } +bool operator<(int i, const int_key& ik) { return i < ik.my_item; } +bool operator<(const int_key& ik1, const int_key& ik2) { return ik1.my_item < ik2.my_item; } + +struct transparent_less { + template <typename T, typename U> + auto operator()( T&& lhs, U&& rhs ) const + -> decltype(std::forward<T>(lhs) < std::forward<U>(rhs)){ + return lhs < rhs; + } + + using is_transparent = void; +}; + +template <typename Container> +void check_heterogeneous_functions() { + static_assert(std::is_same<typename Container::key_type, int>::value, + "incorrect key_type for heterogeneous lookup test"); + // Initialization + Container c; + int size = 10; + for (int i = 0; i < size; i++){ + c.insert(Value<Container>::make(i)); + } + // Insert first duplicated element for multicontainers + if (Container::allow_multimapping){ + c.insert(Value<Container>::make(0)); + } + + // Look up testing + for (int i = 0; i < size; i++) { + int_key k(i); + int key = i; + ASSERT(c.find(k) == c.find(key), "Incorrect heterogeneous find return value"); + ASSERT(c.lower_bound(k) == c.lower_bound(key), "Incorrect heterogeneous lower_bound return value"); + ASSERT(c.upper_bound(k) == c.upper_bound(key), "Incorrect heterogeneous upper_bound return value"); + ASSERT(c.equal_range(k) == c.equal_range(key), "Incorrect heterogeneous equal_range return value"); + ASSERT(c.count(k) == c.count(key), "Incorrect heterogeneous count return value"); + ASSERT(c.contains(k) == c.contains(key), "Incorrect heterogeneous contains return value"); + } + + // Erase testing + for (int i = 0; i < size; i++){ + auto count_before_erase = c.count(i); + auto result = c.unsafe_erase(int_key(i)); + ASSERT(count_before_erase==result,"Incorrent erased elements count"); + ASSERT(c.count(i)==0, "Some elements was not erased"); + } +} + +template <template<typename...> class ContainerType, typename... ContainerArgs> +void test_allocator_traits() { + using namespace propagating_allocators; + using always_propagating_container = ContainerType<ContainerArgs..., always_propagating_allocator>; + using never_propagating_container = ContainerType<ContainerArgs..., never_propagating_allocator>; + using pocma_container = ContainerType<ContainerArgs..., pocma_allocator>; + using pocca_container = ContainerType<ContainerArgs..., pocca_allocator>; + using pocs_container = ContainerType<ContainerArgs..., pocs_allocator>; + + test_allocator_traits_support<always_propagating_container>(); + test_allocator_traits_support<never_propagating_container>(); + test_allocator_traits_support<pocma_container>(); + test_allocator_traits_support<pocca_container>(); + test_allocator_traits_support<pocs_container>(); + + test_allocator_traits_with_non_movable_value_type<pocma_container>(); +} + +// Comparator for scoped_allocator tests +struct allocator_data_compare { + template <typename A> + bool operator()(const allocator_aware_data<A>& d1, const allocator_aware_data<A>& d2) const { + return d1.value() < d2.value(); + } +}; diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_priority_queue.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_priority_queue.cpp new file mode 100644 index 00000000..2a7849cd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_priority_queue.cpp @@ -0,0 +1,1216 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_defs.h" +#include "tbb/concurrent_priority_queue.h" +#include "tbb/atomic.h" +#include "tbb/blocked_range.h" +#include "harness.h" +#include <functional> +#include <algorithm> +#include "harness_allocator.h" +#include <vector> +#include "test_container_move_support.h" + +#if _MSC_VER==1500 && !__INTEL_COMPILER + // VS2008/VC9 seems to have an issue; limits pull in math.h + #pragma warning( push ) + #pragma warning( disable: 4985 ) +#endif +#include <climits> +#if _MSC_VER==1500 && !__INTEL_COMPILER + #pragma warning( pop ) +#endif + +#if __INTEL_COMPILER && (_WIN32 || _WIN64) && TBB_USE_DEBUG && _CPPLIB_VER<520 +// The Intel Compiler has an issue that causes the Microsoft Iterator +// Debugging code to crash in vector::pop_back when it is called after a +// vector::push_back throws an exception. +// #define _HAS_ITERATOR_DEBUGGING 0 // Setting this to 0 doesn't solve the problem + // and also provokes a redefinition warning +#define __TBB_ITERATOR_DEBUGGING_EXCEPTIONS_BROKEN +#endif + +using namespace tbb; + +const size_t MAX_ITER = 10000; + +tbb::atomic<unsigned int> counter; + +class my_data_type { +public: + int priority; + char padding[tbb::internal::NFS_MaxLineSize - sizeof(int) % tbb::internal::NFS_MaxLineSize]; + my_data_type() {} + my_data_type(int init_val) : priority(init_val) {} + const my_data_type operator+(const my_data_type& other) const { + return my_data_type(priority+other.priority); + } + bool operator==(const my_data_type& other) const { + return this->priority == other.priority; + } +}; + +const my_data_type DATA_MIN(INT_MIN); +const my_data_type DATA_MAX(INT_MAX); + +class my_less { +public: + bool operator()(const my_data_type d1, const my_data_type d2) const { + return d1.priority<d2.priority; + } +}; + +#if TBB_USE_EXCEPTIONS +class my_throwing_type : public my_data_type { +public: + static int throw_flag; + my_throwing_type() : my_data_type() {} + my_throwing_type(const my_throwing_type& src) : my_data_type(src) { + if (my_throwing_type::throw_flag) throw 42; + } + my_throwing_type& operator=(const my_throwing_type& src) { + priority = src.priority; + return *this; + } +}; +int my_throwing_type::throw_flag = 0; + +typedef concurrent_priority_queue<my_throwing_type, my_less > cpq_ex_test_type; +#endif + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT +const size_t push_selector_variants = 3; +#elif __TBB_CPP11_RVALUE_REF_PRESENT +const size_t push_selector_variants = 2; +#else +const size_t push_selector_variants = 1; +#endif + +template <typename Q, typename E> +void push_selector(Q& q, E e, size_t i) { + switch (i%push_selector_variants) { + case 0: q->push(e); break; +#if __TBB_CPP11_RVALUE_REF_PRESENT + case 1: q->push(tbb::internal::move(e)); break; +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + case 2: q->emplace(e); break; +#endif +#endif + } +} + +template<typename T, typename C> +class FillBody : NoAssign { + int nThread; + T my_max, my_min; + concurrent_priority_queue<T, C> *q; + C less_than; +public: + FillBody(int nThread_, T max_, T min_, concurrent_priority_queue<T, C> *q_) : nThread(nThread_), my_max(max_), my_min(min_), q(q_) {} + void operator()(const int threadID) const { + T elem = my_min + T(threadID); + for (size_t i=0; i<MAX_ITER; ++i) { + // do some pushes + push_selector(q, elem, i); + if (elem == my_max) elem = my_min; + elem = elem + T(nThread); + } + } +}; + +template<typename T, typename C> +struct EmptyBody : NoAssign { + int nThread; + T my_max; + concurrent_priority_queue<T, C> *q; + C less_than; +public: + EmptyBody(int nThread_, T max_, concurrent_priority_queue<T, C> *q_) : nThread(nThread_), my_max(max_), q(q_) {} + void operator()(const int /*threadID*/) const { + T elem(my_max), last; + if (q->try_pop(last)) { + ++counter; + while(q->try_pop(elem)) { + ASSERT(!less_than(last, elem), "FAILED pop/priority test in EmptyBody."); + last = elem; + elem = my_max; + ++counter; + } + } + } +}; + +template <typename T, typename C> +class FloggerBody : NoAssign { + int nThread; + concurrent_priority_queue<T, C> *q; +public: + FloggerBody(int nThread_, concurrent_priority_queue<T, C> *q_) : + nThread(nThread_), q(q_) {} + void operator()(const int threadID) const { + T elem = T(threadID+1); + for (size_t i=0; i<MAX_ITER; ++i) { + push_selector(q, elem, i); + (void) q->try_pop(elem); + } + } +}; + +namespace equality_comparison_helpers { + struct to_vector{ + template <typename element_type, typename compare_t, typename allocator_t> + std::vector<element_type> operator()(tbb::concurrent_priority_queue<element_type, compare_t, allocator_t> const& source) const{ + tbb::concurrent_priority_queue<element_type, compare_t, allocator_t> cpq((source)); + std::vector<element_type> v; v.reserve(cpq.size()); + element_type element; + while (cpq.try_pop(element)){ v.push_back(element);} + std::reverse(v.begin(),v.end()); + return v; + } + }; +} +//TODO: make CPQ more testable instead of hacking ad-hoc operator == +template <typename element_type, typename compare_t, typename allocator_t> +bool operator==(tbb::concurrent_priority_queue<element_type, compare_t, allocator_t> const& lhs, tbb::concurrent_priority_queue<element_type, compare_t, allocator_t> const& rhs){ + using equality_comparison_helpers::to_vector; + return to_vector()(lhs) == to_vector()(rhs); +} + +template <typename range, typename element_type, typename compare_t, typename allocator_t> +bool operator==(tbb::concurrent_priority_queue<element_type, compare_t, allocator_t> const& lhs, range const & rhs ){ + using equality_comparison_helpers::to_vector; + return to_vector()(lhs) == std::vector<element_type>(rhs.begin(),rhs.end()); +} + +void TestToVector(){ + using equality_comparison_helpers::to_vector; + int array[] = {1,5,6,8,4,7}; + tbb::blocked_range<int *> range = Harness::make_blocked_range(array); + std::vector<int> source(range.begin(),range.end()); + tbb::concurrent_priority_queue<int> q(source.begin(),source.end()); + std::vector<int> from_cpq = to_vector()(q); + std::sort(source.begin(),source.end()); + ASSERT(source == from_cpq,"equality_comparison_helpers::to_vector incorrectly copied items from CPQ?"); +} + +void TestHelpers(){ + TestToVector(); +} + +//Comparator with assert in default constructor +template<typename T> +class less_a : public std::less<T> +{ +public: + explicit less_a(bool no_assert = false) { + ASSERT(no_assert,"empty constructor should not be called"); + }; +}; + +void TestConstructorsDestructorsAccessors() { + std::vector<int> v; + std::allocator<int> a; + concurrent_priority_queue<int, std::less<int> > *q, *qo; + concurrent_priority_queue<int, std::less<int>, std::allocator<int> > *qi; + + less_a<int> l(true); + concurrent_priority_queue<int, less_a<int> > *ql; + concurrent_priority_queue<int, less_a<int>, std::allocator<int> > *qla; + + // Test constructors/destructors + REMARK("Testing default constructor.\n"); + q = new concurrent_priority_queue<int, std::less<int> >(); + REMARK("Default constructor complete.\n"); + ASSERT(q->size()==0, "FAILED size test."); + ASSERT(q->empty(), "FAILED empty test."); + REMARK("Testing destructor.\n"); + delete q; + REMARK("Destruction complete.\n"); + REMARK("Testing capacity constructor.\n"); + q = new concurrent_priority_queue<int, std::less<int> >(42); + REMARK("Capacity constructor complete.\n"); + ASSERT(q->size()==0, "FAILED size test."); + ASSERT(q->empty(), "FAILED empty test."); + REMARK("Testing destructor.\n"); + delete q; + REMARK("Destruction complete.\n"); + + REMARK("Testing allocator constructor.\n"); + qi = new concurrent_priority_queue<int, std::less<int>, std::allocator<int> >(a); + REMARK("Allocator constructor complete.\n"); + ASSERT(qi->size()==0, "FAILED size test."); + ASSERT(qi->empty(), "FAILED empty test."); + REMARK("Testing destructor.\n"); + delete qi; + REMARK("Destruction complete.\n"); + + REMARK("Testing compare constructor.\n"); + ql = new concurrent_priority_queue<int, less_a<int> >(l); + REMARK("Compare constructor complete.\n"); + ASSERT(ql->size()==0, "FAILED size test."); + ASSERT(ql->empty(), "FAILED empty test."); + REMARK("Testing destructor.\n"); + delete ql; + REMARK("Destruction complete.\n"); + + REMARK("Testing compare+allocator constructor.\n"); + qla = new concurrent_priority_queue<int, less_a<int>, std::allocator<int> >(l, a); + REMARK("Compare+allocator constructor complete.\n"); + ASSERT(qla->size()==0, "FAILED size test."); + ASSERT(qla->empty(), "FAILED empty test."); + REMARK("Testing destructor.\n"); + delete qla; + REMARK("Destruction complete.\n"); + + REMARK("Testing capacity+allocator constructor.\n"); + qi = new concurrent_priority_queue<int, std::less<int>, std::allocator<int> >(42, a); + REMARK("Capacity+allocator constructor complete.\n"); + ASSERT(qi->size()==0, "FAILED size test."); + ASSERT(qi->empty(), "FAILED empty test."); + REMARK("Testing destructor.\n"); + delete qi; + REMARK("Destruction complete.\n"); + + REMARK("Testing capacity+compare constructor.\n"); + ql = new concurrent_priority_queue<int, less_a<int> >(42, l); + REMARK("Capacity+compare constructor complete.\n"); + ASSERT(ql->size()==0, "FAILED size test."); + ASSERT(ql->empty(), "FAILED empty test."); + REMARK("Testing destructor.\n"); + delete ql; + REMARK("Destruction complete.\n"); + + REMARK("Testing capacity+compare+allocator constructor.\n"); + qla = new concurrent_priority_queue<int, less_a<int>, std::allocator<int> >(42, l, a); + REMARK("Capacity+compare+allocator constructor complete.\n"); + ASSERT(qla->size()==0, "FAILED size test."); + ASSERT(qla->empty(), "FAILED empty test."); + REMARK("Testing destructor.\n"); + delete qla; + REMARK("Destruction complete.\n"); + + REMARK("Destruction complete.\n"); + REMARK("Testing iterator filler constructor.\n"); + for (int i=0; i<42; ++i) + v.push_back(i); + q = new concurrent_priority_queue<int, std::less<int> >(v.begin(), v.end()); + REMARK("Iterator filler constructor complete.\n"); + ASSERT(q->size()==42, "FAILED vector/size test."); + ASSERT(!q->empty(), "FAILED vector/empty test."); + ASSERT(*q == v, "FAILED vector/equality test."); + + REMARK("Destruction complete.\n"); + REMARK("Testing iterator filler +compare constructor.\n"); + ql = new concurrent_priority_queue<int, less_a<int> >(v.begin(), v.end(), l); + REMARK("Iterator filler +compare constructor complete.\n"); + ASSERT(ql->size()==42, "FAILED vector/size test."); + ASSERT(!ql->empty(), "FAILED vector/empty test."); + REMARK("Testing destructor.\n"); + delete ql; + REMARK("Destruction complete.\n"); + + REMARK("Testing copy constructor.\n"); + qo = new concurrent_priority_queue<int, std::less<int> >(*q); + REMARK("Copy constructor complete.\n"); + ASSERT(qo->size()==42, "FAILED cpq/size test."); + ASSERT(!qo->empty(), "FAILED cpq/empty test."); + ASSERT(*q == *qo, "FAILED cpq/equality test."); + + REMARK("Testing destructor.\n"); + delete q; + delete qo; + REMARK("Destruction complete.\n"); +} + +void TestAssignmentClearSwap() { + typedef concurrent_priority_queue<int, std::less<int> > cpq_type; + std::vector<int> v; + cpq_type *q, *qo; + int e; + + for (int i=0; i<42; ++i) + v.push_back(i); + q = new cpq_type(v.begin(), v.end()); + qo = new cpq_type(); + + REMARK("Testing assignment (1).\n"); + *qo = *q; + REMARK("Assignment complete.\n"); + ASSERT(qo->size()==42, "FAILED assignment/size test."); + ASSERT(!qo->empty(), "FAILED assignment/empty test."); + ASSERT(*qo == v,"FAILED assignment/equality test"); + + cpq_type assigned_q; + REMARK("Testing assign(begin,end) (2).\n"); + assigned_q.assign(v.begin(), v.end()); + REMARK("Assignment complete.\n"); + ASSERT(assigned_q.size()==42, "FAILED assignment/size test."); + ASSERT(!assigned_q.empty(), "FAILED assignment/empty test."); + ASSERT(assigned_q == v,"FAILED assignment/equality test"); + + REMARK("Testing clear.\n"); + q->clear(); + REMARK("Clear complete.\n"); + ASSERT(q->size()==0, "FAILED clear/size test."); + ASSERT(q->empty(), "FAILED clear/empty test."); + + for (size_t i=0; i<5; ++i) + (void) qo->try_pop(e); + + REMARK("Testing assignment (3).\n"); + *q = *qo; + REMARK("Assignment complete.\n"); + ASSERT(q->size()==37, "FAILED assignment/size test."); + ASSERT(!q->empty(), "FAILED assignment/empty test."); + + for (size_t i=0; i<5; ++i) + (void) qo->try_pop(e); + + REMARK("Testing swap.\n"); + q->swap(*qo); + REMARK("Swap complete.\n"); + ASSERT(q->size()==32, "FAILED swap/size test."); + ASSERT(!q->empty(), "FAILED swap/empty test."); + ASSERT(qo->size()==37, "FAILED swap_operand/size test."); + ASSERT(!qo->empty(), "FAILED swap_operand/empty test."); + delete q; + delete qo; +} + +void TestSerialPushPop() { + concurrent_priority_queue<int, std::less<int> > *q; + int e=42, prev=INT_MAX; + size_t count=0; + + q = new concurrent_priority_queue<int, std::less<int> >(MAX_ITER); + REMARK("Testing serial push.\n"); + for (size_t i=0; i<MAX_ITER; ++i) { + push_selector(q, e, i); + e = e*-1 + int(i); + } + REMARK("Pushing complete.\n"); + ASSERT(q->size()==MAX_ITER, "FAILED push/size test."); + ASSERT(!q->empty(), "FAILED push/empty test."); + + REMARK("Testing serial pop.\n"); + while (!q->empty()) { + ASSERT(q->try_pop(e), "FAILED pop test."); + ASSERT(prev>=e, "FAILED pop/priority test."); + prev = e; + ++count; + ASSERT(q->size()==MAX_ITER-count, "FAILED swap/size test."); + ASSERT(!q->empty() || count==MAX_ITER, "FAILED swap/empty test."); + } + ASSERT(!q->try_pop(e), "FAILED: successful pop from the empty queue."); + REMARK("Popping complete.\n"); + delete q; +} + +template <typename T, typename C> +void TestParallelPushPop(int nThreads, T t_max, T t_min, C /*compare*/) { + size_t qsize; + + concurrent_priority_queue<T, C> *q = new concurrent_priority_queue<T, C>(0); + FillBody<T, C> filler(nThreads, t_max, t_min, q); + EmptyBody<T, C> emptier(nThreads, t_max, q); + counter = 0; + REMARK("Testing parallel push.\n"); + NativeParallelFor(nThreads, filler); + REMARK("Pushing complete.\n"); + qsize = q->size(); + ASSERT(q->size()==nThreads*MAX_ITER, "FAILED push/size test."); + ASSERT(!q->empty(), "FAILED push/empty test."); + + REMARK("Testing parallel pop.\n"); + NativeParallelFor(nThreads, emptier); + REMARK("Popping complete.\n"); + ASSERT(counter==qsize, "FAILED pop/size test."); + ASSERT(q->size()==0, "FAILED pop/empty test."); + + q->clear(); + delete(q); +} + +void TestExceptions() { +#if TBB_USE_EXCEPTIONS + const size_t TOO_LARGE_SZ = 1000000000; + my_throwing_type elem; + + REMARK("Testing basic constructor exceptions.\n"); + // Allocate empty queue should not throw no matter the type + try { + my_throwing_type::throw_flag = 1; + cpq_ex_test_type q; + } catch(...) { +#if !(_MSC_VER==1900) + ASSERT(false, "FAILED: allocating empty queue should not throw exception.\n"); + // VS2015 warns about the code in this catch block being unreachable +#endif + } + // Allocate small queue should not throw for reasonably sized type + try { + my_throwing_type::throw_flag = 1; + cpq_ex_test_type q(42); + } catch(...) { + ASSERT(false, "FAILED: allocating small queue should not throw exception.\n"); + } + // Allocate a queue with too large initial size + try { + my_throwing_type::throw_flag = 0; + cpq_ex_test_type q(TOO_LARGE_SZ); + REMARK("FAILED: Huge queue did not throw exception.\n"); + } catch(...) {} + + cpq_ex_test_type *pq; + try { + my_throwing_type::throw_flag = 0; + pq = NULL; + pq = new cpq_ex_test_type(TOO_LARGE_SZ); + REMARK("FAILED: Huge queue did not throw exception.\n"); + delete pq; + } catch(...) { + ASSERT(!pq, "FAILED: pq should not be touched when constructor throws.\n"); + } + REMARK("Basic constructor exceptions testing complete.\n"); + REMARK("Testing copy constructor exceptions.\n"); + my_throwing_type::throw_flag = 0; + cpq_ex_test_type src_q(42); + elem.priority = 42; + for (size_t i=0; i<42; ++i) src_q.push(elem); + try { + my_throwing_type::throw_flag = 1; + cpq_ex_test_type q(src_q); + REMARK("FAILED: Copy construct did not throw exception.\n"); + } catch(...) {} + try { + my_throwing_type::throw_flag = 1; + pq = NULL; + pq = new concurrent_priority_queue<my_throwing_type, my_less >(src_q); + REMARK("FAILED: Copy construct did not throw exception.\n"); + delete pq; + } catch(...) { + ASSERT(!pq, "FAILED: pq should not be touched when constructor throws.\n"); + } + REMARK("Copy constructor exceptions testing complete.\n"); + REMARK("Testing assignment exceptions.\n"); + // Assignment is copy-swap, so it should be exception safe + my_throwing_type::throw_flag = 0; + cpq_ex_test_type assign_q(24); + try { + my_throwing_type::throw_flag = 1; + assign_q = src_q; + REMARK("FAILED: Assign did not throw exception.\n"); + } catch(...) { + ASSERT(assign_q.empty(), "FAILED: assign_q should be empty.\n"); + } + REMARK("Assignment exceptions testing complete.\n"); +#ifndef __TBB_ITERATOR_DEBUGGING_EXCEPTIONS_BROKEN + REMARK("Testing push exceptions.\n"); + for (size_t i=0; i<push_selector_variants; ++i) { + my_throwing_type::throw_flag = 0; + pq = new cpq_ex_test_type(3); + try { + push_selector(pq, elem, i); + push_selector(pq, elem, i); + push_selector(pq, elem, i); + } catch(...) { + ASSERT(false, "FAILED: Push should not throw exception... yet.\n"); + } + try { // should crash on copy during expansion of vector + my_throwing_type::throw_flag = 1; + push_selector(pq, elem, i); + REMARK("FAILED: Push did not throw exception.\n"); + } catch(...) { + ASSERT(!pq->empty(), "FAILED: pq should not be empty.\n"); + ASSERT(pq->size()==3, "FAILED: pq should be only three elements.\n"); + ASSERT(pq->try_pop(elem), "FAILED: pq is not functional.\n"); + } + delete pq; + + my_throwing_type::throw_flag = 0; + pq = new cpq_ex_test_type(3); + try { + push_selector(pq, elem, i); + push_selector(pq, elem, i); + } catch(...) { + ASSERT(false, "FAILED: Push should not throw exception... yet.\n"); + } + try { // should crash on push copy of element + my_throwing_type::throw_flag = 1; + push_selector(pq, elem, i); + REMARK("FAILED: Push did not throw exception.\n"); + } catch(...) { + ASSERT(!pq->empty(), "FAILED: pq should not be empty.\n"); + ASSERT(pq->size()==2, "FAILED: pq should be only two elements.\n"); + ASSERT(pq->try_pop(elem), "FAILED: pq is not functional.\n"); + } + delete pq; + } + REMARK("Push exceptions testing complete.\n"); +#endif +#endif // TBB_USE_EXCEPTIONS +} + +template <typename T, typename C> +void TestFlogger(int nThreads, T /*max*/, C /*compare*/) { + REMARK("Testing queue flogger.\n"); + concurrent_priority_queue<T, C> *q = new concurrent_priority_queue<T, C> (0); + NativeParallelFor(nThreads, FloggerBody<T, C >(nThreads, q)); + ASSERT(q->empty(), "FAILED flogger/empty test."); + ASSERT(!q->size(), "FAILED flogger/size test."); + REMARK("Flogging complete.\n"); + delete q; +} + +#if __TBB_INITIALIZER_LISTS_PRESENT +#include "test_initializer_list.h" + +void TestInitList(){ + REMARK("testing initializer_list methods \n"); + using namespace initializer_list_support_tests; + TestInitListSupport<tbb::concurrent_priority_queue<char> >({1,2,3,4,5}); + TestInitListSupport<tbb::concurrent_priority_queue<int> >({}); +} +#endif //if __TBB_INITIALIZER_LISTS_PRESENT + +struct special_member_calls_t { + size_t copy_constructor_called_times; + size_t move_constructor_called_times; + size_t copy_assignment_called_times; + size_t move_assignment_called_times; + + bool friend operator==(special_member_calls_t const& lhs, special_member_calls_t const& rhs){ + return + lhs.copy_constructor_called_times == rhs.copy_constructor_called_times + && lhs.move_constructor_called_times == rhs.move_constructor_called_times + && lhs.copy_assignment_called_times == rhs.copy_assignment_called_times + && lhs.move_assignment_called_times == rhs.move_assignment_called_times; + } + +}; +#if __TBB_CPP11_RVALUE_REF_PRESENT +struct MoveOperationTracker { + static size_t copy_constructor_called_times; + static size_t move_constructor_called_times; + static size_t copy_assignment_called_times; + static size_t move_assignment_called_times; + + static special_member_calls_t special_member_calls(){ + special_member_calls_t calls = {copy_constructor_called_times, move_constructor_called_times, copy_assignment_called_times, move_assignment_called_times}; + return calls; + } + static size_t value_counter; + + size_t value; + + MoveOperationTracker() : value(++value_counter) {} + MoveOperationTracker( const size_t value_ ) : value( value_ ) {} + ~MoveOperationTracker() __TBB_NOEXCEPT( true ) { + value = 0; + } + MoveOperationTracker(const MoveOperationTracker& m) : value(m.value) { + ASSERT(m.value, "The object has been moved or destroyed"); + ++copy_constructor_called_times; + } + MoveOperationTracker(MoveOperationTracker&& m) __TBB_NOEXCEPT(true) : value(m.value) { + ASSERT(m.value, "The object has been moved or destroyed"); + m.value = 0; + ++move_constructor_called_times; + } + MoveOperationTracker& operator=(MoveOperationTracker const& m) { + ASSERT(m.value, "The object has been moved or destroyed"); + value = m.value; + ++copy_assignment_called_times; + return *this; + } + MoveOperationTracker& operator=(MoveOperationTracker&& m) __TBB_NOEXCEPT(true) { + ASSERT(m.value, "The object has been moved or destroyed"); + value = m.value; + m.value = 0; + ++move_assignment_called_times; + return *this; + } + + bool operator<(MoveOperationTracker const &m) const { + ASSERT(value, "The object has been moved or destroyed"); + ASSERT(m.value, "The object has been moved or destroyed"); + return value < m.value; + } + + friend bool operator==(MoveOperationTracker const &lhs, MoveOperationTracker const &rhs){ + return !(lhs < rhs) && !(rhs <lhs); + } +}; +size_t MoveOperationTracker::copy_constructor_called_times = 0; +size_t MoveOperationTracker::move_constructor_called_times = 0; +size_t MoveOperationTracker::copy_assignment_called_times = 0; +size_t MoveOperationTracker::move_assignment_called_times = 0; +size_t MoveOperationTracker::value_counter = 0; + +template<typename allocator = tbb::cache_aligned_allocator<MoveOperationTracker> > +struct cpq_src_fixture : NoAssign { + enum {default_container_size = 100}; + typedef concurrent_priority_queue<MoveOperationTracker, std::less<MoveOperationTracker>, typename allocator:: template rebind<MoveOperationTracker>::other > cpq_t; + + cpq_t cpq_src; + const size_t container_size; + + void init(){ + size_t &mcct = MoveOperationTracker::move_constructor_called_times; + size_t &ccct = MoveOperationTracker::copy_constructor_called_times; + size_t &cact = MoveOperationTracker::copy_assignment_called_times; + size_t &mact = MoveOperationTracker::move_assignment_called_times; + mcct = ccct = cact = mact = 0; + + for (size_t i=1; i <= container_size; ++i){ + cpq_src.push(MoveOperationTracker(i)); + } + ASSERT(cpq_src.size() == container_size, "error in test setup ?" ); + } + + cpq_src_fixture(size_t size = default_container_size) : container_size(size){ + init(); + } + + cpq_src_fixture(typename cpq_t::allocator_type const& a, size_t size = default_container_size) : cpq_src(a), container_size(size){ + init(); + } + +}; + + +void TestStealingMoveConstructor(){ + typedef cpq_src_fixture<> fixture_t; + fixture_t fixture; + fixture_t::cpq_t src_copy(fixture.cpq_src); + + special_member_calls_t previous = MoveOperationTracker::special_member_calls(); + fixture_t::cpq_t dst(std::move(fixture.cpq_src)); + ASSERT(previous == MoveOperationTracker::special_member_calls(), "stealing move constructor should not create any new elements"); + + ASSERT(dst == src_copy, "cpq content changed during stealing move ?"); +} + +void TestStealingMoveConstructorOtherAllocatorInstance(){ + typedef two_memory_arenas_fixture<MoveOperationTracker> arena_fixture_t; + typedef cpq_src_fixture<arena_fixture_t::allocator_t > fixture_t; + + arena_fixture_t arena_fixture(8 * fixture_t::default_container_size, "TestStealingMoveConstructorOtherAllocatorInstance"); + fixture_t fixture(arena_fixture.source_allocator); + fixture_t::cpq_t src_copy(fixture.cpq_src); + + special_member_calls_t previous = MoveOperationTracker::special_member_calls(); + fixture_t::cpq_t dst(std::move(fixture.cpq_src), arena_fixture.source_allocator); + ASSERT(previous == MoveOperationTracker::special_member_calls(), "stealing move constructor should not create any new elements"); + + ASSERT(dst == src_copy, "cpq content changed during stealing move ?"); +} + +void TestPerElementMoveConstructorOtherAllocatorInstance(){ + typedef two_memory_arenas_fixture<MoveOperationTracker> arena_fixture_t; + typedef cpq_src_fixture<arena_fixture_t::allocator_t > fixture_t; + + arena_fixture_t arena_fixture(8 * fixture_t::default_container_size, "TestPerElementMoveConstructorOtherAllocatorInstance"); + fixture_t fixture(arena_fixture.source_allocator); + fixture_t::cpq_t src_copy(fixture.cpq_src); + + special_member_calls_t move_ctor_called_cpq_size_times = MoveOperationTracker::special_member_calls(); + move_ctor_called_cpq_size_times.move_constructor_called_times += fixture.container_size; + + fixture_t::cpq_t dst(std::move(fixture.cpq_src), arena_fixture.dst_allocator); + ASSERT(move_ctor_called_cpq_size_times == MoveOperationTracker::special_member_calls(), "Per element move constructor should move initialize all new elements"); + ASSERT(dst == src_copy, "cpq content changed during move ?"); +} + +void TestgMoveConstructor(){ + TestStealingMoveConstructor(); + TestStealingMoveConstructorOtherAllocatorInstance(); + TestPerElementMoveConstructorOtherAllocatorInstance(); +} + +void TestStealingMoveAssignOperator(){ + typedef cpq_src_fixture<> fixture_t; + fixture_t fixture; + fixture_t::cpq_t src_copy(fixture.cpq_src); + + fixture_t::cpq_t dst; + special_member_calls_t previous = MoveOperationTracker::special_member_calls(); + dst = std::move(fixture.cpq_src); + ASSERT(previous == MoveOperationTracker::special_member_calls(), "stealing move assign operator should not create any new elements"); + + ASSERT(dst == src_copy, "cpq content changed during stealing move ?"); +} + +void TestStealingMoveAssignOperatorWithStatefulAllocator(){ + //Use stateful allocator which is propagated on assignment , i.e. POCMA = true + typedef two_memory_arenas_fixture<MoveOperationTracker, /*pocma =*/Harness::true_type> arena_fixture_t; + typedef cpq_src_fixture<arena_fixture_t::allocator_t > fixture_t; + + arena_fixture_t arena_fixture(8 * fixture_t::default_container_size, "TestStealingMoveAssignOperatorWithStatefullAllocator"); + fixture_t fixture(arena_fixture.source_allocator); + fixture_t::cpq_t src_copy(fixture.cpq_src); + fixture_t::cpq_t dst(arena_fixture.dst_allocator); + + special_member_calls_t previous = MoveOperationTracker::special_member_calls(); + dst = std::move(fixture.cpq_src); + ASSERT(previous == MoveOperationTracker::special_member_calls(), "stealing move assignment operator should not create any new elements"); + + ASSERT(dst == src_copy, "cpq content changed during stealing move ?"); +} + +void TestPerElementMoveAssignOperator(){ + //use stateful allocator which is not propagate on assignment , i.e. POCMA = false + typedef two_memory_arenas_fixture<MoveOperationTracker, /*pocma =*/Harness::false_type> arena_fixture_t; + typedef cpq_src_fixture<arena_fixture_t::allocator_t > fixture_t; + + arena_fixture_t arena_fixture(8 * fixture_t::default_container_size, "TestPerElementMoveAssignOperator"); + fixture_t fixture(arena_fixture.source_allocator); + fixture_t::cpq_t src_copy(fixture.cpq_src); + fixture_t::cpq_t dst(arena_fixture.dst_allocator); + + special_member_calls_t move_ctor_called_cpq_size_times = MoveOperationTracker::special_member_calls(); + move_ctor_called_cpq_size_times.move_constructor_called_times += fixture.container_size; + dst = std::move(fixture.cpq_src); + ASSERT(move_ctor_called_cpq_size_times == MoveOperationTracker::special_member_calls(), "per element move assignment should move initialize new elements"); + + ASSERT(dst == src_copy, "cpq content changed during per element move ?"); +} + +void TestgMoveAssignOperator(){ + TestStealingMoveAssignOperator(); +#if __TBB_ALLOCATOR_TRAITS_PRESENT + TestStealingMoveAssignOperatorWithStatefulAllocator(); +#endif //__TBB_ALLOCATOR_TRAITS_PRESENT + TestPerElementMoveAssignOperator(); +} + +struct ForwardInEmplaceTester { + int a; + static bool moveCtorCalled; + ForwardInEmplaceTester( int a_val ) : a( a_val ) {} + ForwardInEmplaceTester( ForwardInEmplaceTester&& obj, int a_val ) : a( obj.a ) { + moveCtorCalled = true; + obj.a = a_val; + } + bool operator<( ForwardInEmplaceTester const& ) const { return true; } +}; +bool ForwardInEmplaceTester::moveCtorCalled = false; + +struct NoDefaultCtorType { + size_t value1, value2; + NoDefaultCtorType( size_t value1_, size_t value2_ ) : value1( value1_ ), value2( value2_ ) {} + bool operator<(NoDefaultCtorType const &m) const { + return value1+value2 < m.value1+m.value2; + } +}; + +void TestMoveSupportInPushPop() { + REMARK("Testing Move Support in Push/Pop..."); + size_t &mcct = MoveOperationTracker::move_constructor_called_times; + size_t &ccct = MoveOperationTracker::copy_constructor_called_times; + size_t &cact = MoveOperationTracker::copy_assignment_called_times; + size_t &mact = MoveOperationTracker::move_assignment_called_times; + mcct = ccct = cact = mact = 0; + + concurrent_priority_queue<MoveOperationTracker> q1; + + ASSERT(mcct == 0, "Value must be zero-initialized"); + ASSERT(ccct == 0, "Value must be zero-initialized"); + + q1.push(MoveOperationTracker()); + ASSERT(mcct > 0, "Not working push(T&&)?"); + ASSERT(ccct == 0, "Copying of arg occurred during push(T&&)"); + + MoveOperationTracker ob; + const size_t prev_mcct = mcct; + q1.push(std::move(ob)); + ASSERT(mcct > prev_mcct, "Not working push(T&&)?"); + ASSERT(ccct == 0, "Copying of arg occurred during push(T&&)"); + + ASSERT(cact == 0, "Copy assignment called during push(T&&)"); + const size_t prev_mact = mact; + q1.try_pop(ob); + ASSERT(cact == 0, "Copy assignment called during try_pop(T&)"); + ASSERT(mact > prev_mact, "Move assignment was not called during try_pop(T&)"); + + REMARK(" works.\n"); + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + REMARK("Testing Emplace..."); + + concurrent_priority_queue<NoDefaultCtorType> q2; + q2.emplace(15, 3); + q2.emplace(2, 35); + q2.emplace(8, 8); + + NoDefaultCtorType o(0, 0); + q2.try_pop(o); + ASSERT(o.value1 == 2 && o.value2 == 35, "Unexpected data popped; possible emplace() failure."); + q2.try_pop(o); + ASSERT(o.value1 == 15 && o.value2 == 3, "Unexpected data popped; possible emplace() failure."); + q2.try_pop(o); + ASSERT(o.value1 == 8 && o.value2 == 8, "Unexpected data popped; possible emplace() failure."); + ASSERT(!q2.try_pop(o), "The queue should be empty."); + + //TODO: revise this test + concurrent_priority_queue<ForwardInEmplaceTester> q3; + ASSERT( ForwardInEmplaceTester::moveCtorCalled == false, NULL ); + q3.emplace( ForwardInEmplaceTester(5), 2 ); + ASSERT( ForwardInEmplaceTester::moveCtorCalled == true, "Not used std::forward in emplace()?" ); + ForwardInEmplaceTester obj( 0 ); + q3.try_pop( obj ); + ASSERT( obj.a == 5, "Not used std::forward in emplace()?" ); + ASSERT(!q3.try_pop( obj ), "The queue should be empty."); + + REMARK(" works.\n"); +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ +} +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +void TestCpqOnNThreads( int nThreads ) { + std::less<int> int_compare; + my_less data_compare; + + TestConstructorsDestructorsAccessors(); + TestAssignmentClearSwap(); + TestSerialPushPop(); + + TestParallelPushPop( nThreads, INT_MAX, INT_MIN, int_compare ); + TestParallelPushPop( nThreads, (unsigned char)CHAR_MAX, (unsigned char)CHAR_MIN, int_compare ); + TestParallelPushPop( nThreads, DATA_MAX, DATA_MIN, data_compare ); + + TestFlogger( nThreads, INT_MAX, int_compare ); + TestFlogger( nThreads, (unsigned char)CHAR_MAX, int_compare ); + TestFlogger( nThreads, DATA_MAX, data_compare ); +#if __TBB_CPP11_RVALUE_REF_PRESENT + MoveOperationTracker::copy_assignment_called_times = 0; + TestFlogger( nThreads, MoveOperationTracker(), std::less<MoveOperationTracker>() ); + ASSERT( MoveOperationTracker::copy_assignment_called_times == 0, "Copy assignment called during try_pop(T&)?" ); +#endif + +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + TestExceptions(); +#else + REPORT( "Known issue: exception handling tests are skipped.\n" ); +#endif +} + +#if __TBB_CPP11_SMART_POINTERS_PRESENT +struct SmartPointersCompare { + template <typename Type> bool operator() (const std::shared_ptr<Type> &t1, const std::shared_ptr<Type> &t2) { + return *t1 < *t2; + } + template <typename Type> bool operator() (const std::weak_ptr<Type> &t1, const std::weak_ptr<Type> &t2) { + return *t1.lock().get() < *t2.lock().get(); + } + template <typename Type> bool operator() (const std::unique_ptr<Type> &t1, const std::unique_ptr<Type> &t2) { + return *t1 < *t2; + } +}; +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ + +#if __TBB_CPP11_RVALUE_REF_PRESENT +// The helper calls copying or moving push operator if an element has copy constructor. +// Otherwise it calls only moving push operator. +template <bool hasCopyCtor> +struct QueuePushHelper { + template <typename Q, typename T> + static void push( Q &q, T &&t ) { + q.push( std::forward<T>(t) ); + } +}; +template <> +template <typename Q, typename T> +void QueuePushHelper<false>::push( Q &q, T &&t ) { + q.push( std::move(t) ); +} +#else +template <bool hasCopyCtor> +struct QueuePushHelper { + template <typename Q, typename T> + static void push( Q &q, const T &t ) { + q.push( t ); + } +}; +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +template <bool hasCopyCtor, typename Queue> +void Examine(Queue &q1, Queue &q2, const std::vector<typename Queue::value_type> &vecSorted) { + typedef typename Queue::value_type ValueType; + + ASSERT(!q1.empty() && q1.size() == vecSorted.size(), NULL); + + ValueType elem; + + q2.clear(); + ASSERT(q2.empty() && !q2.size() && !q2.try_pop(elem), NULL); + + typename std::vector<ValueType>::const_reverse_iterator it1; + for (it1 = vecSorted.rbegin(); q1.try_pop(elem); it1++) { + ASSERT( Harness::IsEqual()(elem, *it1), NULL ); + if ( std::distance(vecSorted.rbegin(), it1) % 2 ) + QueuePushHelper<hasCopyCtor>::push(q2,elem); + else + QueuePushHelper<hasCopyCtor>::push(q2,tbb::internal::move(elem)); + } + ASSERT(it1 == vecSorted.rend(), NULL); + ASSERT(q1.empty() && !q1.size(), NULL); + ASSERT(!q2.empty() && q2.size() == vecSorted.size(), NULL); + + q1.swap(q2); + ASSERT(q2.empty() && !q2.size(), NULL); + ASSERT(!q1.empty() && q1.size() == vecSorted.size(), NULL); + for (it1 = vecSorted.rbegin(); q1.try_pop(elem); it1++) ASSERT(Harness::IsEqual()(elem, *it1), NULL); + ASSERT(it1 == vecSorted.rend(), NULL); + + typename Queue::allocator_type a = q1.get_allocator(); + ValueType *ptr = a.allocate(1); + ASSERT(ptr, NULL); + a.deallocate(ptr, 1); +} + +template <typename Queue> +void Examine(const Queue &q, const std::vector<typename Queue::value_type> &vecSorted) { + Queue q1(q), q2(q); + Examine</*hasCopyCtor=*/true>( q1, q2, vecSorted ); +} + +template <typename ValueType, typename Compare> +void TypeTester(const std::vector<ValueType> &vec, Compare comp) { + typedef tbb::concurrent_priority_queue<ValueType, Compare> Queue; + typedef tbb::concurrent_priority_queue< ValueType, Compare, debug_allocator<ValueType> > QueueDebugAlloc; + __TBB_ASSERT(vec.size() >= 5, "Array should have at least 5 elements"); + + std::vector<ValueType> vecSorted(vec); + std::sort( vecSorted.begin(), vecSorted.end(), comp ); + + // Construct an empty queue. + Queue q1; + q1.assign(vec.begin(), vec.end()); + Examine(q1, vecSorted); +#if __TBB_INITIALIZER_LISTS_PRESENT + // Constructor from initializer_list. + Queue q2({ vec[0], vec[1], vec[2] }); + for (typename std::vector<ValueType>::const_iterator it = vec.begin() + 3; it != vec.end(); ++it) q2.push(*it); + Examine(q2, vecSorted); + Queue q3; + q3 = { vec[0], vec[1], vec[2] }; + for (typename std::vector<ValueType>::const_iterator it = vec.begin() + 3; it != vec.end(); ++it) q3.push(*it); + Examine(q3, vecSorted); +#endif + // Copying constructor. + Queue q4(q1); + Examine(q4, vecSorted); + // Construct with non-default allocator. + QueueDebugAlloc q5; + q5.assign(vec.begin(), vec.end()); + Examine(q5, vecSorted); + // Copying constructor for vector with different allocator type. + QueueDebugAlloc q6(q5); + Examine(q6, vecSorted); + // Construction with copying iteration range and given allocator instance. + Queue q7(vec.begin(), vec.end()); + Examine(q7, vecSorted); + typename QueueDebugAlloc::allocator_type a; + QueueDebugAlloc q8(a); + q8.assign(vec.begin(), vec.end()); + Examine(q8, vecSorted); +} + +#if __TBB_CPP11_SMART_POINTERS_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT +template <typename T> +void TypeTesterUniquePtr(const std::vector<T> &vec) { + __TBB_ASSERT(vec.size() >= 5, "Array should have at least 5 elements"); + + typedef std::unique_ptr<T> ValueType; + typedef tbb::concurrent_priority_queue<ValueType, SmartPointersCompare> Queue; + typedef tbb::concurrent_priority_queue< ValueType, SmartPointersCompare, debug_allocator<ValueType> > QueueDebugAlloc; + + std::vector<ValueType> vecSorted; + for ( typename std::vector<T>::const_iterator it = vec.begin(); it != vec.end(); ++it ) { + vecSorted.push_back( ValueType(new T(*it)) ); + } + std::sort( vecSorted.begin(), vecSorted.end(), SmartPointersCompare() ); + + Queue q1, q1Copy; + QueueDebugAlloc q2, q2Copy; + for ( typename std::vector<T>::const_iterator it = vec.begin(); it != vec.end(); ++it ) { + q1.push( ValueType(new T(*it)) ); + q1Copy.push( ValueType(new T(*it)) ); + q2.push( ValueType(new T(*it)) ); + q2Copy.push( ValueType(new T(*it)) ); + } + Examine</*isCopyCtor=*/false>(q1, q1Copy, vecSorted); + Examine</*isCopyCtor=*/false>(q2, q2Copy, vecSorted); + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + Queue q3Copy; + QueueDebugAlloc q4Copy; + + q1.clear(); + q2.clear(); + for ( typename std::vector<T>::const_iterator it = vec.begin(); it != vec.end(); ++it ) { + q1.emplace( new T(*it) ); + q3Copy.emplace( new T(*it) ); + q2.emplace( new T(*it) ); + q4Copy.emplace( new T(*it) ); + } + + Queue q3( std::move(q1) ); + QueueDebugAlloc q4( std::move(q2) ); + Examine</*isCopyCtor=*/false>(q3, q3Copy, vecSorted); + Examine</*isCopyCtor=*/false>(q4, q4Copy, vecSorted); +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +} +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT */ + +template <typename ValueType> +void TypeTester(const std::vector<ValueType> &vec) { TypeTester(vec, std::less<ValueType>()); } + +void TestTypes() { + const int NUMBER = 10; + + Harness::FastRandom rnd(1234); + + std::vector<int> arrInt; + for (int i = 0; i<NUMBER; ++i) arrInt.push_back(rnd.get()); + std::vector< tbb::atomic<int> > arrTbb; + for (int i = 0; i<NUMBER; ++i) { + tbb::atomic<int> a; + a = rnd.get(); + arrTbb.push_back(a); + } + + TypeTester(arrInt); + TypeTester(arrTbb); + +#if __TBB_CPP11_SMART_POINTERS_PRESENT + std::vector< std::shared_ptr<int> > arrShr; + for (int i = 0; i<NUMBER; ++i) { + const int rnd_get = rnd.get(); + arrShr.push_back(std::make_shared<int>(rnd_get)); + } + std::vector< std::weak_ptr<int> > arrWk; + std::copy(arrShr.begin(), arrShr.end(), std::back_inserter(arrWk)); + TypeTester(arrShr, SmartPointersCompare()); + TypeTester(arrWk, SmartPointersCompare()); + +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT +#if __TBB_IS_COPY_CONSTRUCTIBLE_BROKEN + REPORT( "Known issue: std::is_copy_constructible is broken for move-only types. So the std::unique_ptr test is skipped.\n" ); +#else + TypeTesterUniquePtr(arrInt); +#endif /* __TBB_IS_COPY_CONSTRUCTIBLE_BROKEN */ +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT */ +#else + REPORT( "Known issue: C++11 smart pointer tests are skipped.\n" ); +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +template <template <typename...>typename TQueue> +void TestDeductionGuides() { + using ComplexType = const std::string*; + std::string s("s"); + std::vector<ComplexType> v; + auto l = {ComplexType(&s), ComplexType(&s) }; + + // check TQueue(InputIterator, InputIterator) + TQueue qv(v.begin(), v.end()); + static_assert(std::is_same<decltype(qv), TQueue<ComplexType> >::value); + + // check TQueue(InputIterator, InputIterator, Allocator) + TQueue qva(v.begin(), v.end(), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(qva), TQueue<ComplexType, std::less<ComplexType>, + std::allocator<ComplexType>>>::value); + + // check TQueue(InputIterator, InputIterator, Compare) + TQueue qvc(v.begin(), v.end(), less_a<ComplexType>(true)); + static_assert(std::is_same<decltype(qvc), TQueue<ComplexType, less_a<ComplexType>>>::value); + + // check TQueue(InputIterator, InputIterator, Compare, Allocator) + TQueue qvca(v.begin(), v.end(), less_a<ComplexType>(true), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(qvca), TQueue<ComplexType, less_a<ComplexType>, + std::allocator<ComplexType>>>::value); + + // check TQueue(std::initializer_list) + TQueue ql(l); + static_assert(std::is_same<decltype(ql), TQueue<ComplexType>>::value); + + // check TQueue(std::initializer_list, Allocator) + TQueue qla(l, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(qla), TQueue<ComplexType, std::less<ComplexType>, + std::allocator<ComplexType>>>::value); + + // check TQueue(std::initializer_list, Compare) + TQueue qlc(l, less_a<ComplexType>(true)); + static_assert(std::is_same<decltype(qlc), TQueue<ComplexType, less_a<ComplexType>>>::value); + + // check TQueue(std::initializer_list, Compare, Allocator) + TQueue qlca(l, less_a<ComplexType>(true), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(qlca), TQueue<ComplexType, less_a<ComplexType>, + std::allocator<ComplexType>>>::value); + + // check TQueue(TQueue &) + TQueue qc(qv); + static_assert(std::is_same<decltype(qv), decltype(qv)>::value); + + // check TQueue(TQueue &, Allocator) + TQueue qca(qva, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(qca), decltype(qva)>::value); + + // check TQueue(TQueue &&) + TQueue qm(std::move(qv)); + static_assert(std::is_same<decltype(qm), decltype(qv)>::value); + + // check TQueue(TQueue &&, Allocator) + TQueue qma(std::move(qva), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(qma), decltype(qva)>::value); +} +#endif + +int TestMain() { + if (MinThread < 1) + MinThread = 1; + + TestHelpers(); +#if __TBB_INITIALIZER_LISTS_PRESENT + TestInitList(); +#else + REPORT("Known issue: initializer list tests are skipped.\n"); +#endif + + TestTypes(); + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides<tbb::concurrent_priority_queue>(); +#endif + +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestgMoveConstructor(); + TestgMoveAssignOperator(); + TestMoveSupportInPushPop(); +#else + REPORT("Known issue: move support tests are skipped.\n"); +#endif + + for (int p = MinThread; p <= MaxThread; ++p) { + REMARK("Testing on %d threads.\n", p); + TestCpqOnNThreads(p); + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_queue.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_queue.cpp new file mode 100644 index 00000000..49241638 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_queue.cpp @@ -0,0 +1,1752 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define NOMINMAX +#include "harness_defs.h" +#include "tbb/concurrent_queue.h" +#include "tbb/tick_count.h" +#include "harness.h" +#include "harness_allocator.h" + +using tbb::internal::spin_wait_while; + +#include <vector> + +static tbb::atomic<long> FooConstructed; +static tbb::atomic<long> FooDestroyed; + +enum state_t{ + LIVE=0x1234, + DEAD=0xDEAD +}; + +class Foo { + state_t state; +public: + int thread_id; + int serial; + Foo() : state(LIVE), thread_id(0), serial(0) { + ++FooConstructed; + } + Foo( const Foo& item ) : state(LIVE) { + ASSERT( item.state==LIVE, NULL ); + ++FooConstructed; + thread_id = item.thread_id; + serial = item.serial; + } + ~Foo() { + ASSERT( state==LIVE, NULL ); + ++FooDestroyed; + state=DEAD; + thread_id=DEAD; + serial=DEAD; + } + void operator=( const Foo& item ) { + ASSERT( item.state==LIVE, NULL ); + ASSERT( state==LIVE, NULL ); + thread_id = item.thread_id; + serial = item.serial; + } + bool is_const() {return false;} + bool is_const() const {return true;} + static void clear_counters() { FooConstructed = 0; FooDestroyed = 0; } + static long get_n_constructed() { return FooConstructed; } + static long get_n_destroyed() { return FooDestroyed; } +}; + +// problem size +static const int N = 50000; // # of bytes + +#if TBB_USE_EXCEPTIONS +//! Exception for concurrent_queue +class Foo_exception : public std::bad_alloc { +public: + virtual const char *what() const throw() __TBB_override { return "out of Foo limit"; } + virtual ~Foo_exception() throw() {} +}; + +static tbb::atomic<long> FooExConstructed; +static tbb::atomic<long> FooExDestroyed; +static tbb::atomic<long> serial_source; +static long MaxFooCount = 0; +static const long Threshold = 400; + +class FooEx { + state_t state; +public: + int serial; + FooEx() : state(LIVE) { + ++FooExConstructed; + serial = serial_source++; + } + FooEx( const FooEx& item ) : state(LIVE) { + ASSERT( item.state == LIVE, NULL ); + ++FooExConstructed; + if( MaxFooCount && (FooExConstructed-FooExDestroyed) >= MaxFooCount ) // in push() + throw Foo_exception(); + serial = item.serial; + } + ~FooEx() { + ASSERT( state==LIVE, NULL ); + ++FooExDestroyed; + state=DEAD; + serial=DEAD; + } + void operator=( FooEx& item ) { + ASSERT( item.state==LIVE, NULL ); + ASSERT( state==LIVE, NULL ); + serial = item.serial; + if( MaxFooCount==2*Threshold && (FooExConstructed-FooExDestroyed) <= MaxFooCount/4 ) // in pop() + throw Foo_exception(); + } +#if __TBB_CPP11_RVALUE_REF_PRESENT + void operator=( FooEx&& item ) { + operator=( item ); + item.serial = 0; + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +} ; +#endif /* TBB_USE_EXCEPTIONS */ + +const size_t MAXTHREAD = 256; + +static int Sum[MAXTHREAD]; + +//! Count of various pop operations +/** [0] = pop_if_present that failed + [1] = pop_if_present that succeeded + [2] = pop */ +static tbb::atomic<long> PopKind[3]; + +const int M = 10000; + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT +const size_t push_selector_variants = 3; +#elif __TBB_CPP11_RVALUE_REF_PRESENT +const size_t push_selector_variants = 2; +#else +const size_t push_selector_variants = 1; +#endif + +template<typename CQ, typename ValueType, typename CounterType> +void push( CQ& q, ValueType v, CounterType i ) { + switch( i % push_selector_variants ) { + case 0: q.push( v ); break; +#if __TBB_CPP11_RVALUE_REF_PRESENT + case 1: q.push( std::move(v) ); break; +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + case 2: q.emplace( v ); break; +#endif +#endif + default: ASSERT( false, NULL ); break; + } +} + +template<typename CQ,typename T> +struct Body: NoAssign { + CQ* queue; + const int nthread; + Body( int nthread_ ) : nthread(nthread_) {} + void operator()( int thread_id ) const { + long pop_kind[3] = {0,0,0}; + int serial[MAXTHREAD+1]; + memset( serial, 0, nthread*sizeof(int) ); + ASSERT( thread_id<nthread, NULL ); + + long sum = 0; + for( long j=0; j<M; ++j ) { + T f; + f.thread_id = DEAD; + f.serial = DEAD; + bool prepopped = false; + if( j&1 ) { + prepopped = queue->try_pop( f ); + ++pop_kind[prepopped]; + } + T g; + g.thread_id = thread_id; + g.serial = j+1; + push( *queue, g, j ); + if( !prepopped ) { + while( !(queue)->try_pop(f) ) __TBB_Yield(); + ++pop_kind[2]; + } + ASSERT( f.thread_id<=nthread, NULL ); + ASSERT( f.thread_id==nthread || serial[f.thread_id]<f.serial, "partial order violation" ); + serial[f.thread_id] = f.serial; + sum += f.serial-1; + } + Sum[thread_id] = sum; + for( int k=0; k<3; ++k ) + PopKind[k] += pop_kind[k]; + } +}; + +// Define wrapper classes to test tbb::concurrent_queue<T> +template<typename T, typename A = tbb::cache_aligned_allocator<T> > +class ConcQWithSizeWrapper : public tbb::concurrent_queue<T, A> { +public: + ConcQWithSizeWrapper() {} + ConcQWithSizeWrapper( const ConcQWithSizeWrapper& q ) : tbb::concurrent_queue<T, A>( q ) {} + ConcQWithSizeWrapper(const A& a) : tbb::concurrent_queue<T, A>( a ) {} +#if __TBB_CPP11_RVALUE_REF_PRESENT + ConcQWithSizeWrapper(ConcQWithSizeWrapper&& q) : tbb::concurrent_queue<T>( std::move(q) ) {} + ConcQWithSizeWrapper(ConcQWithSizeWrapper&& q, const A& a) + : tbb::concurrent_queue<T, A>( std::move(q), a ) { } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + template<typename InputIterator> + ConcQWithSizeWrapper( InputIterator begin, InputIterator end, const A& a = A()) + : tbb::concurrent_queue<T, A>(begin,end,a) {} + size_t size() const { return this->unsafe_size(); } +}; + +template<typename T> +class ConcQPushPopWrapper : public tbb::concurrent_queue<T> { +public: + ConcQPushPopWrapper() : my_capacity( size_t(-1)/(sizeof(void*)+sizeof(T)) ) {} + size_t size() const { return this->unsafe_size(); } + void set_capacity( const ptrdiff_t n ) { my_capacity = n; } + bool try_push( const T& source ) { return this->push( source ); } + bool try_pop( T& dest ) { return this->tbb::concurrent_queue<T>::try_pop( dest ); } + size_t my_capacity; +}; + +template<typename T> +class ConcQWithCapacity : public tbb::concurrent_queue<T> { +public: + ConcQWithCapacity() : my_capacity( size_t(-1)/(sizeof(void*)+sizeof(T)) ) {} + size_t size() const { return this->unsafe_size(); } + size_t capacity() const { return my_capacity; } + void set_capacity( const int n ) { my_capacity = n; } + bool try_push( const T& source ) { this->push( source ); return (size_t)source.serial<my_capacity; } + bool try_pop( T& dest ) { this->tbb::concurrent_queue<T>::try_pop( dest ); return (size_t)dest.serial<my_capacity; } + size_t my_capacity; +}; + +template <typename Queue> +void AssertEquality(Queue &q, const std::vector<typename Queue::value_type> &vec) { + ASSERT(q.size() == typename Queue::size_type(vec.size()), NULL); + ASSERT(std::equal(q.unsafe_begin(), q.unsafe_end(), vec.begin(), Harness::IsEqual()), NULL); +} + +template <typename Queue> +void AssertEmptiness(Queue &q) { + ASSERT(q.empty(), NULL); + ASSERT(!q.size(), NULL); + typename Queue::value_type elem; + ASSERT(!q.try_pop(elem), NULL); +} + +enum push_t { push_op, try_push_op }; + +template<push_t push_op> +struct pusher { +#if __TBB_CPP11_RVALUE_REF_PRESENT + template<typename CQ, typename VType> + static bool push( CQ& queue, VType&& val ) { + queue.push( std::forward<VType>( val ) ); + return true; + } +#else + template<typename CQ, typename VType> + static bool push( CQ& queue, const VType& val ) { + queue.push( val ); + return true; + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +}; + +template<> +struct pusher< try_push_op > { +#if __TBB_CPP11_RVALUE_REF_PRESENT + template<typename CQ, typename VType> + static bool push( CQ& queue, VType&& val ) { + return queue.try_push( std::forward<VType>( val ) ); + } +#else + template<typename CQ, typename VType> + static bool push( CQ& queue, const VType& val ) { + return queue.try_push( val ); + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +}; + +enum pop_t { pop_op, try_pop_op }; + +template<pop_t pop_op> +struct popper { +#if __TBB_CPP11_RVALUE_REF_PRESENT + template<typename CQ, typename VType> + static bool pop( CQ& queue, VType&& val ) { + if( queue.empty() ) return false; + queue.pop( std::forward<VType>( val ) ); + return true; + } +#else + template<typename CQ, typename VType> + static bool pop( CQ& queue, VType& val ) { + if( queue.empty() ) return false; + queue.pop( val ); + return true; + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +}; + +template<> +struct popper< try_pop_op > { +#if __TBB_CPP11_RVALUE_REF_PRESENT + template<typename CQ, typename VType> + static bool pop( CQ& queue, VType&& val ) { + return queue.try_pop( std::forward<VType>( val ) ); + } +#else + template<typename CQ, typename VType> + static bool pop( CQ& queue, VType& val ) { + return queue.try_pop( val ); + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +}; + +template <push_t push_op, typename Queue> +void FillTest(Queue &q, const std::vector<typename Queue::value_type> &vec) { + for (typename std::vector<typename Queue::value_type>::const_iterator it = vec.begin(); it != vec.end(); ++it) + ASSERT(pusher<push_op>::push(q, *it), NULL); + AssertEquality(q, vec); +} + +template <pop_t pop_op, typename Queue> +void EmptyTest(Queue &q, const std::vector<typename Queue::value_type> &vec) { + typedef typename Queue::value_type value_type; + + value_type elem; + typename std::vector<value_type>::const_iterator it = vec.begin(); + while (popper<pop_op>::pop(q, elem)) { + ASSERT(Harness::IsEqual()(elem, *it), NULL); + ++it; + } + ASSERT(it == vec.end(), NULL); + AssertEmptiness(q); +} + +template <typename T, typename A> +void bounded_queue_specific_test(tbb::concurrent_queue<T, A> &, const std::vector<T> &) { /* do nothing */ } + +template <typename T, typename A> +void bounded_queue_specific_test(tbb::concurrent_bounded_queue<T, A> &q, const std::vector<T> &vec) { + typedef typename tbb::concurrent_bounded_queue<T, A>::size_type size_type; + + FillTest<try_push_op>(q, vec); + tbb::concurrent_bounded_queue<T, A> q2 = q; + EmptyTest<pop_op>(q, vec); + + // capacity + q2.set_capacity(size_type(vec.size())); + ASSERT(q2.capacity() == size_type(vec.size()), NULL); + ASSERT(q2.size() == size_type(vec.size()), NULL); + ASSERT(!q2.try_push(vec[0]), NULL); + +#if TBB_USE_EXCEPTIONS + q.abort(); +#endif +} + +template<typename CQ, typename T> +void TestPushPop( size_t prefill, ptrdiff_t capacity, int nthread ) { + ASSERT( nthread>0, "nthread must be positive" ); + ptrdiff_t signed_prefill = ptrdiff_t(prefill); + if( signed_prefill+1>=capacity ) + return; + bool success = false; + for( int k=0; k<3; ++k ) + PopKind[k] = 0; + for( int trial=0; !success; ++trial ) { + T::clear_counters(); + Body<CQ,T> body(nthread); + CQ queue; + queue.set_capacity( capacity ); + body.queue = &queue; + for( size_t i=0; i<prefill; ++i ) { + T f; + f.thread_id = nthread; + f.serial = 1+int(i); + push(queue, f, i); + ASSERT( unsigned(queue.size())==i+1, NULL ); + ASSERT( !queue.empty(), NULL ); + } + tbb::tick_count t0 = tbb::tick_count::now(); + NativeParallelFor( nthread, body ); + tbb::tick_count t1 = tbb::tick_count::now(); + double timing = (t1-t0).seconds(); + REMARK("prefill=%d capacity=%d threads=%d time = %g = %g nsec/operation\n", int(prefill), int(capacity), nthread, timing, timing/(2*M*nthread)*1.E9); + int sum = 0; + for( int k=0; k<nthread; ++k ) + sum += Sum[k]; + int expected = int(nthread*((M-1)*M/2) + ((prefill-1)*prefill)/2); + for( int i=int(prefill); --i>=0; ) { + ASSERT( !queue.empty(), NULL ); + T f; + bool result = queue.try_pop(f); + ASSERT( result, NULL ); + ASSERT( int(queue.size())==i, NULL ); + sum += f.serial-1; + } + ASSERT( queue.empty(), "The queue should be empty" ); + ASSERT( queue.size()==0, "The queue should have zero size" ); + if( sum!=expected ) + REPORT("sum=%d expected=%d\n",sum,expected); + ASSERT( T::get_n_constructed()==T::get_n_destroyed(), NULL ); + // TODO: checks by counting allocators + + success = true; + if( nthread>1 && prefill==0 ) { + // Check that pop_if_present got sufficient exercise + for( int k=0; k<2; ++k ) { +#if (_WIN32||_WIN64) + // The TBB library on Windows seems to have a tough time generating + // the desired interleavings for pop_if_present, so the code tries longer, and settles + // for fewer desired interleavings. + const int max_trial = 100; + const int min_requirement = 20; +#else + const int min_requirement = 100; + const int max_trial = 20; +#endif /* _WIN32||_WIN64 */ + if( PopKind[k]<min_requirement ) { + if( trial>=max_trial ) { + if( Verbose ) + REPORT("Warning: %d threads had only %ld pop_if_present operations %s after %d trials (expected at least %d). " + "This problem may merely be unlucky scheduling. " + "Investigate only if it happens repeatedly.\n", + nthread, long(PopKind[k]), k==0?"failed":"succeeded", max_trial, min_requirement); + else + REPORT("Warning: the number of %s pop_if_present operations is less than expected for %d threads. Investigate if it happens repeatedly.\n", + k==0?"failed":"succeeded", nthread ); + + } else { + success = false; + } + } + } + } + } +} + +class Bar { + state_t state; +public: + static size_t construction_num, destruction_num; + ptrdiff_t my_id; + Bar() : state(LIVE), my_id(-1) {} + Bar(size_t _i) : state(LIVE), my_id(_i) { construction_num++; } + Bar( const Bar& a_bar ) : state(LIVE) { + ASSERT( a_bar.state==LIVE, NULL ); + my_id = a_bar.my_id; + construction_num++; + } + ~Bar() { + ASSERT( state==LIVE, NULL ); + state = DEAD; + my_id = DEAD; + destruction_num++; + } + void operator=( const Bar& a_bar ) { + ASSERT( a_bar.state==LIVE, NULL ); + ASSERT( state==LIVE, NULL ); + my_id = a_bar.my_id; + } + friend bool operator==(const Bar& bar1, const Bar& bar2 ) ; +} ; + +size_t Bar::construction_num = 0; +size_t Bar::destruction_num = 0; + +bool operator==(const Bar& bar1, const Bar& bar2) { + ASSERT( bar1.state==LIVE, NULL ); + ASSERT( bar2.state==LIVE, NULL ); + return bar1.my_id == bar2.my_id; +} + +class BarIterator +{ + Bar* bar_ptr; + BarIterator(Bar* bp_) : bar_ptr(bp_) {} +public: + Bar& operator*() const { + return *bar_ptr; + } + BarIterator& operator++() { + ++bar_ptr; + return *this; + } + Bar* operator++(int) { + Bar* result = &operator*(); + operator++(); + return result; + } + friend bool operator==(const BarIterator& bia, const BarIterator& bib) ; + friend bool operator!=(const BarIterator& bia, const BarIterator& bib) ; + template<typename CQ, typename T, typename TIter, typename CQ_EX, typename T_EX> + friend void TestConstructors (); +} ; + +bool operator==(const BarIterator& bia, const BarIterator& bib) { + return bia.bar_ptr==bib.bar_ptr; +} + +bool operator!=(const BarIterator& bia, const BarIterator& bib) { + return bia.bar_ptr!=bib.bar_ptr; +} + +#if TBB_USE_EXCEPTIONS +class Bar_exception : public std::bad_alloc { +public: + virtual const char *what() const throw() __TBB_override { return "making the entry invalid"; } + virtual ~Bar_exception() throw() {} +}; + +class BarEx { + static int count; +public: + state_t state; + typedef enum { + PREPARATION, + COPY_CONSTRUCT + } mode_t; + static mode_t mode; + ptrdiff_t my_id; + ptrdiff_t my_tilda_id; + static int button; + BarEx() : state(LIVE), my_id(-1), my_tilda_id(-1) {} + BarEx(size_t _i) : state(LIVE), my_id(_i), my_tilda_id(my_id^(-1)) {} + BarEx( const BarEx& a_bar ) : state(LIVE) { + ASSERT( a_bar.state==LIVE, NULL ); + my_id = a_bar.my_id; + if( mode==PREPARATION ) + if( !( ++count % 100 ) ) + throw Bar_exception(); + my_tilda_id = a_bar.my_tilda_id; + } + ~BarEx() { + ASSERT( state==LIVE, NULL ); + state = DEAD; + my_id = DEAD; + } + static void set_mode( mode_t m ) { mode = m; } + void operator=( const BarEx& a_bar ) { + ASSERT( a_bar.state==LIVE, NULL ); + ASSERT( state==LIVE, NULL ); + my_id = a_bar.my_id; + my_tilda_id = a_bar.my_tilda_id; + } + friend bool operator==(const BarEx& bar1, const BarEx& bar2 ) ; +} ; + +int BarEx::count = 0; +BarEx::mode_t BarEx::mode = BarEx::PREPARATION; + +bool operator==(const BarEx& bar1, const BarEx& bar2) { + ASSERT( bar1.state==LIVE, NULL ); + ASSERT( bar2.state==LIVE, NULL ); + ASSERT( (bar1.my_id ^ bar1.my_tilda_id) == -1, NULL ); + ASSERT( (bar2.my_id ^ bar2.my_tilda_id) == -1, NULL ); + return bar1.my_id==bar2.my_id && bar1.my_tilda_id==bar2.my_tilda_id; +} +#endif /* TBB_USE_EXCEPTIONS */ + +template<typename CQ, typename T, typename TIter, typename CQ_EX, typename T_EX> +void TestConstructors () +{ + CQ src_queue; + typename CQ::const_iterator dqb; + typename CQ::const_iterator dqe; + typename CQ::const_iterator iter; + + for( size_t size=0; size<1001; ++size ) { + for( size_t i=0; i<size; ++i ) + src_queue.push(T(i+(i^size))); + typename CQ::const_iterator sqb( src_queue.unsafe_begin() ); + typename CQ::const_iterator sqe( src_queue.unsafe_end() ); + + CQ dst_queue(sqb, sqe); + + ASSERT(src_queue.size()==dst_queue.size(), "different size"); + + src_queue.clear(); + } + + T bar_array[1001]; + for( size_t size=0; size<1001; ++size ) { + for( size_t i=0; i<size; ++i ) + bar_array[i] = T(i+(i^size)); + + const TIter sab(bar_array+0); + const TIter sae(bar_array+size); + + CQ dst_queue2(sab, sae); + + ASSERT( size==unsigned(dst_queue2.size()), NULL ); + ASSERT( sab==TIter(bar_array+0), NULL ); + ASSERT( sae==TIter(bar_array+size), NULL ); + + dqb = dst_queue2.unsafe_begin(); + dqe = dst_queue2.unsafe_end(); + TIter v_iter(sab); + for( ; dqb != dqe; ++dqb, ++v_iter ) + ASSERT( *dqb == *v_iter, "unexpected element" ); + ASSERT( v_iter==sae, "different size?" ); + } + + src_queue.clear(); + + CQ dst_queue3( src_queue ); + ASSERT( src_queue.size()==dst_queue3.size(), NULL ); + ASSERT( 0==dst_queue3.size(), NULL ); + + int k=0; + for( size_t i=0; i<1001; ++i ) { + T tmp_bar; + src_queue.push(T(++k)); + src_queue.push(T(++k)); + src_queue.try_pop(tmp_bar); + + CQ dst_queue4( src_queue ); + + ASSERT( src_queue.size()==dst_queue4.size(), NULL ); + + dqb = dst_queue4.unsafe_begin(); + dqe = dst_queue4.unsafe_end(); + iter = src_queue.unsafe_begin(); + + for( ; dqb != dqe; ++dqb, ++iter ) + ASSERT( *dqb == *iter, "unexpected element" ); + + ASSERT( iter==src_queue.unsafe_end(), "different size?" ); + } + + CQ dst_queue5( src_queue ); + + ASSERT( src_queue.size()==dst_queue5.size(), NULL ); + dqb = dst_queue5.unsafe_begin(); + dqe = dst_queue5.unsafe_end(); + iter = src_queue.unsafe_begin(); + for( ; dqb != dqe; ++dqb, ++iter ) + ASSERT( *dqb == *iter, "unexpected element" ); + + for( size_t i=0; i<100; ++i) { + T tmp_bar; + src_queue.push(T(i+1000)); + src_queue.push(T(i+1000)); + src_queue.try_pop(tmp_bar); + + dst_queue5.push(T(i+1000)); + dst_queue5.push(T(i+1000)); + dst_queue5.try_pop(tmp_bar); + } + + ASSERT( src_queue.size()==dst_queue5.size(), NULL ); + dqb = dst_queue5.unsafe_begin(); + dqe = dst_queue5.unsafe_end(); + iter = src_queue.unsafe_begin(); + for( ; dqb != dqe; ++dqb, ++iter ) + ASSERT( *dqb == *iter, "unexpected element" ); + ASSERT( iter==src_queue.unsafe_end(), "different size?" ); + +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN || __TBB_PLACEMENT_NEW_EXCEPTION_SAFETY_BROKEN + REPORT("Known issue: part of the constructor test is skipped.\n"); +#elif TBB_USE_EXCEPTIONS + k = 0; + typename CQ_EX::size_type n_elements=0; + CQ_EX src_queue_ex; + for( size_t size=0; size<1001; ++size ) { + T_EX tmp_bar_ex; + typename CQ_EX::size_type n_successful_pushes=0; + T_EX::set_mode( T_EX::PREPARATION ); + try { + src_queue_ex.push(T_EX(k+(k^size))); + ++n_successful_pushes; + } catch (...) { + } + ++k; + try { + src_queue_ex.push(T_EX(k+(k^size))); + ++n_successful_pushes; + } catch (...) { + } + ++k; + src_queue_ex.try_pop(tmp_bar_ex); + n_elements += (n_successful_pushes - 1); + ASSERT( src_queue_ex.size()==n_elements, NULL); + + T_EX::set_mode( T_EX::COPY_CONSTRUCT ); + CQ_EX dst_queue_ex( src_queue_ex ); + + ASSERT( src_queue_ex.size()==dst_queue_ex.size(), NULL ); + + typename CQ_EX::const_iterator dqb_ex = dst_queue_ex.unsafe_begin(); + typename CQ_EX::const_iterator dqe_ex = dst_queue_ex.unsafe_end(); + typename CQ_EX::const_iterator iter_ex = src_queue_ex.unsafe_begin(); + + for( ; dqb_ex != dqe_ex; ++dqb_ex, ++iter_ex ) + ASSERT( *dqb_ex == *iter_ex, "unexpected element" ); + ASSERT( iter_ex==src_queue_ex.unsafe_end(), "different size?" ); + } +#endif /* TBB_USE_EXCEPTIONS */ + +#if __TBB_CPP11_RVALUE_REF_PRESENT + // Testing work of move constructors. TODO: merge into TestMoveConstructors? + src_queue.clear(); + + typedef typename CQ::size_type qsize_t; + for( qsize_t size = 0; size < 1001; ++size ) { + for( qsize_t i = 0; i < size; ++i ) + src_queue.push( T(i + (i ^ size)) ); + std::vector<const T*> locations(size); + typename CQ::const_iterator qit = src_queue.unsafe_begin(); + for( qsize_t i = 0; i < size; ++i, ++qit ) + locations[i] = &(*qit); + + qsize_t size_of_queue = src_queue.size(); + CQ dst_queue( std::move(src_queue) ); + + ASSERT( src_queue.empty() && src_queue.size() == 0, "not working move constructor?" ); + ASSERT( size == size_of_queue && size_of_queue == dst_queue.size(), + "not working move constructor?" ); + + qit = dst_queue.unsafe_begin(); + for( qsize_t i = 0; i < size; ++i, ++qit ) + ASSERT( locations[i] == &(*qit), "there was data movement during move constructor" ); + + for( qsize_t i = 0; i < size; ++i ) { + T test(i + (i ^ size)); + T popped; + bool pop_result = dst_queue.try_pop( popped ); + + ASSERT( pop_result, NULL ); + ASSERT( test == popped, NULL ); + } + } +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +template<class T> +class allocator: public tbb::cache_aligned_allocator<T> { +public: + size_t m_unique_id; + + allocator() : m_unique_id( 0 ) {} + + allocator(size_t unique_id) { m_unique_id = unique_id; } + + template<typename U> + allocator(const allocator<U>& a) throw() { m_unique_id = a.m_unique_id; } + + template<typename U> + struct rebind { typedef allocator<U> other; }; + + friend bool operator==(const allocator& lhs, const allocator& rhs) { + return lhs.m_unique_id == rhs.m_unique_id; + } +}; + +// Checks operability of the queue the data was moved from +template<typename T, typename CQ> +void TestQueueOperabilityAfterDataMove( CQ& queue ) { + const size_t size = 10; + std::vector<T> v(size); + for( size_t i = 0; i < size; ++i ) v[i] = T( i * i + i ); + + FillTest<push_op>(queue, v); + EmptyTest<try_pop_op>(queue, v); + bounded_queue_specific_test(queue, v); +} + +template<class CQ, class T> +void TestMoveConstructors() { + T::construction_num = T::destruction_num = 0; + CQ src_queue( allocator<T>(0) ); + const size_t size = 10; + for( size_t i = 0; i < size; ++i ) + src_queue.push( T(i + (i ^ size)) ); + ASSERT( T::construction_num == 2 * size, NULL ); + ASSERT( T::destruction_num == size, NULL ); + + const T* locations[size]; + typename CQ::const_iterator qit = src_queue.unsafe_begin(); + for( size_t i = 0; i < size; ++i, ++qit ) + locations[i] = &(*qit); + + // Ensuring allocation operation takes place during move when allocators are different + T::construction_num = T::destruction_num = 0; + CQ dst_queue( std::move(src_queue), allocator<T>(1) ); + ASSERT( T::construction_num == size, NULL ); + ASSERT( T::destruction_num == size+1, NULL ); // One item is used by the queue destructor + + TestQueueOperabilityAfterDataMove<T>( src_queue ); + + qit = dst_queue.unsafe_begin(); + for( size_t i = 0; i < size; ++i, ++qit ) { + ASSERT( locations[i] != &(*qit), "an item should have been copied but was not" ); + locations[i] = &(*qit); + } + + T::construction_num = T::destruction_num = 0; + // Ensuring there is no allocation operation during move with equal allocators + CQ dst_queue2( std::move(dst_queue), allocator<T>(1) ); + ASSERT( T::construction_num == 0, NULL ); + ASSERT( T::destruction_num == 0, NULL ); + + TestQueueOperabilityAfterDataMove<T>( dst_queue ); + + qit = dst_queue2.unsafe_begin(); + for( size_t i = 0; i < size; ++i, ++qit ) { + ASSERT( locations[i] == &(*qit), "an item should have been moved but was not" ); + } + + for( size_t i = 0; i < size; ++i) { + T test(i + (i ^ size)); + T popped; + bool pop_result = dst_queue2.try_pop( popped ); + ASSERT( pop_result, NULL ); + ASSERT( test == popped, NULL ); + } + ASSERT( dst_queue2.empty(), NULL ); + ASSERT( dst_queue2.size() == 0, NULL ); +} + +void TestMoveConstruction() { + REMARK("Testing move constructors with specified allocators..."); + TestMoveConstructors< ConcQWithSizeWrapper< Bar, allocator<Bar> >, Bar >(); + TestMoveConstructors< tbb::concurrent_bounded_queue< Bar, allocator<Bar> >, Bar >(); + // TODO: add tests with movable data + REMARK(" work\n"); +} +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +template<typename Iterator1, typename Iterator2> +void TestIteratorAux( Iterator1 i, Iterator2 j, int size ) { + Iterator1 old_i; // assigned at first iteration below + for( int k=0; k<size; ++k ) { + ASSERT( i!=j, NULL ); + ASSERT( !(i==j), NULL ); + // Test "->" + ASSERT( k+1==i->serial, NULL ); + if( k&1 ) { + // Test post-increment + Foo f = *old_i++; + ASSERT( k+1==f.serial, NULL ); + // Test assignment + i = old_i; + } else { + // Test pre-increment + if( k<size-1 ) { + Foo f = *++i; + ASSERT( k+2==f.serial, NULL ); + } else ++i; + // Test assignment + old_i = i; + } + } + ASSERT( !(i!=j), NULL ); + ASSERT( i==j, NULL ); +} + +template<typename Iterator1, typename Iterator2> +void TestIteratorAssignment( Iterator2 j ) { + Iterator1 i(j); + ASSERT( i==j, NULL ); + ASSERT( !(i!=j), NULL ); + Iterator1 k; + k = j; + ASSERT( k==j, NULL ); + ASSERT( !(k!=j), NULL ); +} + +template<typename Iterator, typename T> +void TestIteratorTraits() { + AssertSameType( static_cast<typename Iterator::difference_type*>(0), static_cast<ptrdiff_t*>(0) ); + AssertSameType( static_cast<typename Iterator::value_type*>(0), static_cast<T*>(0) ); + AssertSameType( static_cast<typename Iterator::pointer*>(0), static_cast<T**>(0) ); + AssertSameType( static_cast<typename Iterator::iterator_category*>(0), static_cast<std::forward_iterator_tag*>(0) ); + T x; + typename Iterator::reference xr = x; + typename Iterator::pointer xp = &x; + ASSERT( &xr==xp, NULL ); +} + +//! Test the iterators for concurrent_queue +template<typename CQ> +void TestIterator() { + CQ queue; + const CQ& const_queue = queue; + for( int j=0; j<500; ++j ) { + TestIteratorAux( queue.unsafe_begin() , queue.unsafe_end() , j ); + TestIteratorAux( const_queue.unsafe_begin(), const_queue.unsafe_end(), j ); + TestIteratorAux( const_queue.unsafe_begin(), queue.unsafe_end() , j ); + TestIteratorAux( queue.unsafe_begin() , const_queue.unsafe_end(), j ); + Foo f; + f.serial = j+1; + queue.push(f); + } + TestIteratorAssignment<typename CQ::const_iterator>( const_queue.unsafe_begin() ); + TestIteratorAssignment<typename CQ::const_iterator>( queue.unsafe_begin() ); + TestIteratorAssignment<typename CQ::iterator>( queue.unsafe_begin() ); + TestIteratorTraits<typename CQ::const_iterator, const Foo>(); + TestIteratorTraits<typename CQ::iterator, Foo>(); +} + +template<typename CQ> +void TestConcurrentQueueType() { + AssertSameType( typename CQ::value_type(), Foo() ); + Foo f; + const Foo g; + typename CQ::reference r = f; + ASSERT( &r==&f, NULL ); + ASSERT( !r.is_const(), NULL ); + typename CQ::const_reference cr = g; + ASSERT( &cr==&g, NULL ); + ASSERT( cr.is_const(), NULL ); +} + +template<typename CQ, typename T> +void TestEmptyQueue() { + const CQ queue; + ASSERT( queue.size()==0, NULL ); + ASSERT( queue.capacity()>0, NULL ); + ASSERT( size_t(queue.capacity())>=size_t(-1)/(sizeof(void*)+sizeof(T)), NULL ); +} + +template<typename CQ,typename T> +void TestFullQueue() { + for( int n=0; n<10; ++n ) { + T::clear_counters(); + CQ queue; + queue.set_capacity(n); + for( int i=0; i<=n; ++i ) { + T f; + f.serial = i; + bool result = queue.try_push( f ); + ASSERT( result==(i<n), NULL ); + } + for( int i=0; i<=n; ++i ) { + T f; + bool result = queue.try_pop( f ); + ASSERT( result==(i<n), NULL ); + ASSERT( !result || f.serial==i, NULL ); + } + ASSERT( T::get_n_constructed()==T::get_n_destroyed(), NULL ); + } +} + +template<typename CQ> +void TestClear() { + FooConstructed = 0; + FooDestroyed = 0; + const unsigned int n=5; + + CQ queue; + const int q_capacity=10; + queue.set_capacity(q_capacity); + for( size_t i=0; i<n; ++i ) { + Foo f; + f.serial = int(i); + queue.push( f ); + } + ASSERT( unsigned(queue.size())==n, NULL ); + queue.clear(); + ASSERT( queue.size()==0, NULL ); + for( size_t i=0; i<n; ++i ) { + Foo f; + f.serial = int(i); + queue.push( f ); + } + ASSERT( unsigned(queue.size())==n, NULL ); + queue.clear(); + ASSERT( queue.size()==0, NULL ); + for( size_t i=0; i<n; ++i ) { + Foo f; + f.serial = int(i); + queue.push( f ); + } + ASSERT( unsigned(queue.size())==n, NULL ); +} + +template<typename T> +struct TestNegativeQueueBody: NoAssign { + tbb::concurrent_bounded_queue<T>& queue; + const int nthread; + TestNegativeQueueBody( tbb::concurrent_bounded_queue<T>& q, int n ) : queue(q), nthread(n) {} + void operator()( int k ) const { + if( k==0 ) { + int number_of_pops = nthread-1; + // Wait for all pops to pend. + while( queue.size()>-number_of_pops ) { + __TBB_Yield(); + } + for( int i=0; ; ++i ) { + ASSERT( queue.size()==i-number_of_pops, NULL ); + ASSERT( queue.empty()==(queue.size()<=0), NULL ); + if( i==number_of_pops ) break; + // Satisfy another pop + queue.push( T() ); + } + } else { + // Pop item from queue + T item; + queue.pop(item); + } + } +}; + +//! Test a queue with a negative size. +template<typename T> +void TestNegativeQueue( int nthread ) { + tbb::concurrent_bounded_queue<T> queue; + NativeParallelFor( nthread, TestNegativeQueueBody<T>(queue,nthread) ); +} + +#if TBB_USE_EXCEPTIONS +template<template<typename, typename> class CQ,typename A1,typename A2,typename T> +void TestExceptionBody() { + enum methods { + m_push = 0, + m_pop + }; + + REMARK("Testing exception safety\n"); + MaxFooCount = 5; + // verify 'clear()' on exception; queue's destructor calls its clear() + // Do test on queues of two different types at the same time to + // catch problem with incorrect sharing between templates. + { + CQ<T,A1> queue0; + CQ<int,A1> queue1; + for( int i=0; i<2; ++i ) { + bool caught = false; + try { + // concurrent_queue internally rebinds the allocator to the one for 'char' + A2::init_counters(); + A2::set_limits(N/2); + for( int k=0; k<N; k++ ) { + if( i==0 ) + push(queue0, T(), i); + else + queue1.push( k ); + } + } catch (...) { + caught = true; + } + ASSERT( caught, "call to push should have thrown exception" ); + } + } + REMARK("... queue destruction test passed\n"); + + try { + int n_pushed=0, n_popped=0; + for(int t = 0; t <= 1; t++)// exception type -- 0 : from allocator(), 1 : from Foo's constructor + { + CQ<T,A1> queue_test; + for( int m=m_push; m<=m_pop; m++ ) { + // concurrent_queue internally rebinds the allocator to the one for 'char' + A2::init_counters(); + + if(t) MaxFooCount = MaxFooCount + 400; + else A2::set_limits(N/2); + + try { + switch(m) { + case m_push: + for( int k=0; k<N; k++ ) { + push( queue_test, T(), k ); + n_pushed++; + } + break; + case m_pop: + n_popped=0; + for( int k=0; k<n_pushed; k++ ) { + T elt; + queue_test.try_pop( elt ); + n_popped++; + } + n_pushed = 0; + A2::set_limits(); + break; + } + if( !t && m==m_push ) ASSERT(false, "should throw an exception"); + } catch ( Foo_exception & ) { + long tc = MaxFooCount; + MaxFooCount = 0; // disable exception + switch(m) { + case m_push: + ASSERT( ptrdiff_t(queue_test.size())==n_pushed, "incorrect queue size" ); + for( int k=0; k<(int)tc; k++ ) { + push( queue_test, T(), k ); + n_pushed++; + } + break; + case m_pop: + n_pushed -= (n_popped+1); // including one that threw the exception + ASSERT( n_pushed>=0, "n_pushed cannot be less than 0" ); + for( int k=0; k<1000; k++ ) { + push( queue_test, T(), k ); + n_pushed++; + } + ASSERT( !queue_test.empty(), "queue must not be empty" ); + ASSERT( ptrdiff_t(queue_test.size())==n_pushed, "queue size must be equal to n pushed" ); + for( int k=0; k<n_pushed; k++ ) { + T elt; + queue_test.try_pop( elt ); + } + ASSERT( queue_test.empty(), "queue must be empty" ); + ASSERT( queue_test.size()==0, "queue must be empty" ); + break; + } + MaxFooCount = tc; + } catch ( std::bad_alloc & ) { + A2::set_limits(); // disable exception from allocator + size_t size = queue_test.size(); + switch(m) { + case m_push: + ASSERT( size>0, "incorrect queue size"); + break; + case m_pop: + if( !t ) ASSERT( false, "should not throw an exception" ); + break; + } + } + REMARK("... for t=%d and m=%d, exception test passed\n", t, m); + } + } + } catch(...) { + ASSERT(false, "unexpected exception"); + } +} +#endif /* TBB_USE_EXCEPTIONS */ + +void TestExceptions() { +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + REPORT("Known issue: exception safety test is skipped.\n"); +#elif TBB_USE_EXCEPTIONS + typedef static_counting_allocator<std::allocator<FooEx>, size_t> allocator_t; + typedef static_counting_allocator<std::allocator<char>, size_t> allocator_char_t; + TestExceptionBody<ConcQWithSizeWrapper,allocator_t,allocator_char_t,FooEx>(); + TestExceptionBody<tbb::concurrent_bounded_queue,allocator_t,allocator_char_t,FooEx>(); +#endif /* TBB_USE_EXCEPTIONS */ +} + +template<typename CQ, typename T> +struct TestQueueElements: NoAssign { + CQ& queue; + const int nthread; + TestQueueElements( CQ& q, int n ) : queue(q), nthread(n) {} + void operator()( int k ) const { + for( int i=0; i<1000; ++i ) { + if( (i&0x1)==0 ) { + ASSERT( T(k)<T(nthread), NULL ); + queue.push( T(k) ); + } else { + // Pop item from queue + T item = 0; + queue.try_pop(item); + ASSERT( item<=T(nthread), NULL ); + } + } + } +}; + +//! Test concurrent queue with primitive data type +template<typename CQ, typename T> +void TestPrimitiveTypes( int nthread, T exemplar ) +{ + CQ queue; + for( int i=0; i<100; ++i ) + queue.push( exemplar ); + NativeParallelFor( nthread, TestQueueElements<CQ,T>(queue,nthread) ); +} + +#include "harness_m128.h" + +#if HAVE_m128 || HAVE_m256 + +//! Test concurrent queue with vector types +/** Type Queue should be a queue of ClassWithSSE/ClassWithAVX. */ +template<typename ClassWithVectorType, typename Queue> +void TestVectorTypes() { + Queue q1; + for( int i=0; i<100; ++i ) { + // VC8 does not properly align a temporary value; to work around, use explicit variable + ClassWithVectorType bar(i); + q1.push(bar); + } + + // Copy the queue + Queue q2 = q1; + // Check that elements of the copy are correct + typename Queue::const_iterator ci = q2.unsafe_begin(); + for( int i=0; i<100; ++i ) { + ClassWithVectorType foo = *ci; + ClassWithVectorType bar(i); + ASSERT( *ci==bar, NULL ); + ++ci; + } + + for( int i=0; i<101; ++i ) { + ClassWithVectorType tmp; + bool b = q1.try_pop( tmp ); + ASSERT( b==(i<100), NULL ); + ClassWithVectorType bar(i); + ASSERT( !b || tmp==bar, NULL ); + } +} +#endif /* HAVE_m128 || HAVE_m256 */ + +void TestEmptiness() +{ + REMARK(" Test Emptiness\n"); + TestEmptyQueue<ConcQWithCapacity<char>, char>(); + TestEmptyQueue<ConcQWithCapacity<Foo>, Foo>(); + TestEmptyQueue<tbb::concurrent_bounded_queue<char>, char>(); + TestEmptyQueue<tbb::concurrent_bounded_queue<Foo>, Foo>(); +} + +void TestFullness() +{ + REMARK(" Test Fullness\n"); + TestFullQueue<ConcQWithCapacity<Foo>,Foo>(); + TestFullQueue<tbb::concurrent_bounded_queue<Foo>,Foo>(); +} + +void TestClearWorks() +{ + REMARK(" Test concurrent_queue::clear() works\n"); + TestClear<ConcQWithCapacity<Foo> >(); + TestClear<tbb::concurrent_bounded_queue<Foo> >(); +} + +void TestQueueTypeDeclaration() +{ + REMARK(" Test concurrent_queue's types work\n"); + TestConcurrentQueueType<tbb::concurrent_queue<Foo> >(); + TestConcurrentQueueType<tbb::concurrent_bounded_queue<Foo> >(); +} + +void TestQueueIteratorWorks() +{ + REMARK(" Test concurrent_queue's iterators work\n"); + TestIterator<tbb::concurrent_queue<Foo> >(); + TestIterator<tbb::concurrent_bounded_queue<Foo> >(); +} + +#if TBB_USE_EXCEPTIONS +#define BAR_EX BarEx +#else +#define BAR_EX Empty /* passed as template arg but should not be used */ +#endif +class Empty; + +void TestQueueConstructors() +{ + REMARK(" Test concurrent_queue's constructors work\n"); + TestConstructors<ConcQWithSizeWrapper<Bar>,Bar,BarIterator,ConcQWithSizeWrapper<BAR_EX>,BAR_EX>(); + TestConstructors<tbb::concurrent_bounded_queue<Bar>,Bar,BarIterator,tbb::concurrent_bounded_queue<BAR_EX>,BAR_EX>(); +} + +void TestQueueWorksWithPrimitiveTypes() +{ + REMARK(" Test concurrent_queue works with primitive types\n"); + TestPrimitiveTypes<tbb::concurrent_queue<char>, char>( MaxThread, (char)1 ); + TestPrimitiveTypes<tbb::concurrent_queue<int>, int>( MaxThread, (int)-12 ); + TestPrimitiveTypes<tbb::concurrent_queue<float>, float>( MaxThread, (float)-1.2f ); + TestPrimitiveTypes<tbb::concurrent_queue<double>, double>( MaxThread, (double)-4.3 ); + TestPrimitiveTypes<tbb::concurrent_bounded_queue<char>, char>( MaxThread, (char)1 ); + TestPrimitiveTypes<tbb::concurrent_bounded_queue<int>, int>( MaxThread, (int)-12 ); + TestPrimitiveTypes<tbb::concurrent_bounded_queue<float>, float>( MaxThread, (float)-1.2f ); + TestPrimitiveTypes<tbb::concurrent_bounded_queue<double>, double>( MaxThread, (double)-4.3 ); +} + +void TestQueueWorksWithSSE() +{ + REMARK(" Test concurrent_queue works with SSE data\n"); +#if HAVE_m128 + TestVectorTypes<ClassWithSSE, tbb::concurrent_queue<ClassWithSSE> >(); + TestVectorTypes<ClassWithSSE, tbb::concurrent_bounded_queue<ClassWithSSE> >(); +#endif /* HAVE_m128 */ +#if HAVE_m256 + if( have_AVX() ) { + TestVectorTypes<ClassWithAVX, tbb::concurrent_queue<ClassWithAVX> >(); + TestVectorTypes<ClassWithAVX, tbb::concurrent_bounded_queue<ClassWithAVX> >(); + } +#endif /* HAVE_m256 */ +} + +void TestConcurrentPushPop() +{ + REMARK(" Test concurrent_queue's concurrent push and pop\n"); + for( int nthread=MinThread; nthread<=MaxThread; ++nthread ) { + REMARK(" Testing with %d thread(s)\n", nthread ); + TestNegativeQueue<Foo>(nthread); + for( size_t prefill=0; prefill<64; prefill+=(1+prefill/3) ) { + TestPushPop<ConcQPushPopWrapper<Foo>,Foo>(prefill,ptrdiff_t(-1),nthread); + TestPushPop<ConcQPushPopWrapper<Foo>,Foo>(prefill,ptrdiff_t(1),nthread); + TestPushPop<ConcQPushPopWrapper<Foo>,Foo>(prefill,ptrdiff_t(2),nthread); + TestPushPop<ConcQPushPopWrapper<Foo>,Foo>(prefill,ptrdiff_t(10),nthread); + TestPushPop<ConcQPushPopWrapper<Foo>,Foo>(prefill,ptrdiff_t(100),nthread); + } + for( size_t prefill=0; prefill<64; prefill+=(1+prefill/3) ) { + TestPushPop<tbb::concurrent_bounded_queue<Foo>,Foo>(prefill,ptrdiff_t(-1),nthread); + TestPushPop<tbb::concurrent_bounded_queue<Foo>,Foo>(prefill,ptrdiff_t(1),nthread); + TestPushPop<tbb::concurrent_bounded_queue<Foo>,Foo>(prefill,ptrdiff_t(2),nthread); + TestPushPop<tbb::concurrent_bounded_queue<Foo>,Foo>(prefill,ptrdiff_t(10),nthread); + TestPushPop<tbb::concurrent_bounded_queue<Foo>,Foo>(prefill,ptrdiff_t(100),nthread); + } + } +} + +#if TBB_USE_EXCEPTIONS +tbb::atomic<size_t> num_pushed; +tbb::atomic<size_t> num_popped; +tbb::atomic<size_t> failed_pushes; +tbb::atomic<size_t> failed_pops; + +class SimplePushBody { + tbb::concurrent_bounded_queue<int>* q; + int max; +public: + SimplePushBody(tbb::concurrent_bounded_queue<int>* _q, int hi_thr) : q(_q), max(hi_thr) {} + bool operator()() { // predicate for spin_wait_while + return q->size()<max; + } + void operator()(int thread_id) const { + if (thread_id == max) { + spin_wait_while( *this ); + q->abort(); + return; + } + try { + q->push(42); + ++num_pushed; + } catch ( tbb::user_abort& ) { + ++failed_pushes; + } + } +}; + +class SimplePopBody { + tbb::concurrent_bounded_queue<int>* q; + int max; + int prefill; +public: + SimplePopBody(tbb::concurrent_bounded_queue<int>* _q, int hi_thr, int nitems) + : q(_q), max(hi_thr), prefill(nitems) {} + bool operator()() { // predicate for spin_wait_while + // There should be `max` pops, and `prefill` should succeed + return q->size()>prefill-max; + } + void operator()(int thread_id) const { + int e; + if (thread_id == max) { + spin_wait_while( *this ); + q->abort(); + return; + } + try { + q->pop(e); + ++num_popped; + } catch ( tbb::user_abort& ) { + ++failed_pops; + } + } +}; +#endif /* TBB_USE_EXCEPTIONS */ + +void TestAbort() { +#if TBB_USE_EXCEPTIONS + for (int nthreads=MinThread; nthreads<=MaxThread; ++nthreads) { + REMARK("Testing Abort on %d thread(s).\n", nthreads); + + REMARK("...testing pushing to zero-sized queue\n"); + tbb::concurrent_bounded_queue<int> iq1; + iq1.set_capacity(0); + for (int i=0; i<10; ++i) { + num_pushed = num_popped = failed_pushes = failed_pops = 0; + SimplePushBody my_push_body1(&iq1, nthreads); + NativeParallelFor( nthreads+1, my_push_body1 ); + ASSERT(num_pushed == 0, "no elements should have been pushed to zero-sized queue"); + ASSERT((int)failed_pushes == nthreads, "All threads should have failed to push an element to zero-sized queue"); + // Do not test popping each time in order to test queue destruction with no previous pops + if (nthreads < (MaxThread+MinThread)/2) { + int e; + bool queue_empty = !iq1.try_pop(e); + ASSERT(queue_empty, "no elements should have been popped from zero-sized queue"); + } + } + + REMARK("...testing pushing to small-sized queue\n"); + tbb::concurrent_bounded_queue<int> iq2; + iq2.set_capacity(2); + for (int i=0; i<10; ++i) { + num_pushed = num_popped = failed_pushes = failed_pops = 0; + SimplePushBody my_push_body2(&iq2, nthreads); + NativeParallelFor( nthreads+1, my_push_body2 ); + ASSERT(num_pushed <= 2, "at most 2 elements should have been pushed to queue of size 2"); + if (nthreads >= 2) + ASSERT((int)failed_pushes == nthreads-2, "nthreads-2 threads should have failed to push an element to queue of size 2"); + int e; + while (iq2.try_pop(e)) ; + } + + REMARK("...testing popping from small-sized queue\n"); + tbb::concurrent_bounded_queue<int> iq3; + iq3.set_capacity(2); + for (int i=0; i<10; ++i) { + num_pushed = num_popped = failed_pushes = failed_pops = 0; + iq3.push(42); + iq3.push(42); + SimplePopBody my_pop_body(&iq3, nthreads, 2); + NativeParallelFor( nthreads+1, my_pop_body ); + ASSERT(num_popped <= 2, "at most 2 elements should have been popped from queue of size 2"); + if (nthreads >= 2) + ASSERT((int)failed_pops == nthreads-2, "nthreads-2 threads should have failed to pop an element from queue of size 2"); + else { + int e; + iq3.pop(e); + } + } + + REMARK("...testing pushing and popping from small-sized queue\n"); + tbb::concurrent_bounded_queue<int> iq4; + int cap = nthreads/2; + if (!cap) cap=1; + iq4.set_capacity(cap); + for (int i=0; i<10; ++i) { + num_pushed = num_popped = failed_pushes = failed_pops = 0; + SimplePushBody my_push_body2(&iq4, nthreads); + NativeParallelFor( nthreads+1, my_push_body2 ); + ASSERT((int)num_pushed <= cap, "at most cap elements should have been pushed to queue of size cap"); + if (nthreads >= cap) + ASSERT((int)failed_pushes == nthreads-cap, "nthreads-cap threads should have failed to push an element to queue of size cap"); + SimplePopBody my_pop_body(&iq4, nthreads, (int)num_pushed); + NativeParallelFor( nthreads+1, my_pop_body ); + ASSERT((int)num_popped <= cap, "at most cap elements should have been popped from queue of size cap"); + if (nthreads >= cap) + ASSERT((int)failed_pops == nthreads-cap, "nthreads-cap threads should have failed to pop an element from queue of size cap"); + else { + int e; + while (iq4.try_pop(e)) ; + } + } + } +#endif +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +struct MoveOperationTracker { + static size_t copy_constructor_called_times; + static size_t move_constructor_called_times; + static size_t copy_assignment_called_times; + static size_t move_assignment_called_times; + + MoveOperationTracker() {} + MoveOperationTracker(const MoveOperationTracker&) { + ++copy_constructor_called_times; + } + MoveOperationTracker(MoveOperationTracker&&) { + ++move_constructor_called_times; + } + MoveOperationTracker& operator=(MoveOperationTracker const&) { + ++copy_assignment_called_times; + return *this; + } + MoveOperationTracker& operator=(MoveOperationTracker&&) { + ++move_assignment_called_times; + return *this; + } +}; +size_t MoveOperationTracker::copy_constructor_called_times = 0; +size_t MoveOperationTracker::move_constructor_called_times = 0; +size_t MoveOperationTracker::copy_assignment_called_times = 0; +size_t MoveOperationTracker::move_assignment_called_times = 0; + +template <class CQ, push_t push_op, pop_t pop_op> +void TestMoveSupport() { + size_t &mcct = MoveOperationTracker::move_constructor_called_times; + size_t &ccct = MoveOperationTracker::copy_constructor_called_times; + size_t &cact = MoveOperationTracker::copy_assignment_called_times; + size_t &mact = MoveOperationTracker::move_assignment_called_times; + mcct = ccct = cact = mact = 0; + + CQ q; + + ASSERT(mcct == 0, "Value must be zero-initialized"); + ASSERT(ccct == 0, "Value must be zero-initialized"); + ASSERT(pusher<push_op>::push( q, MoveOperationTracker() ), NULL); + ASSERT(mcct == 1, "Not working push(T&&) or try_push(T&&)?"); + ASSERT(ccct == 0, "Copying of arg occurred during push(T&&) or try_push(T&&)"); + + MoveOperationTracker ob; + ASSERT(pusher<push_op>::push( q, std::move(ob) ), NULL); + ASSERT(mcct == 2, "Not working push(T&&) or try_push(T&&)?"); + ASSERT(ccct == 0, "Copying of arg occurred during push(T&&) or try_push(T&&)"); + + ASSERT(cact == 0, "Copy assignment called during push(T&&) or try_push(T&&)"); + ASSERT(mact == 0, "Move assignment called during push(T&&) or try_push(T&&)"); + + bool result = popper<pop_op>::pop( q, ob ); + ASSERT(result, NULL); + ASSERT(cact == 0, "Copy assignment called during try_pop(T&&)"); + ASSERT(mact == 1, "Move assignment was not called during try_pop(T&&)"); +} + +void TestMoveSupportInPushPop() { + REMARK("Testing Move Support in Push/Pop..."); + TestMoveSupport< tbb::concurrent_queue<MoveOperationTracker>, push_op, try_pop_op >(); + TestMoveSupport< tbb::concurrent_bounded_queue<MoveOperationTracker>, push_op, pop_op >(); + TestMoveSupport< tbb::concurrent_bounded_queue<MoveOperationTracker>, try_push_op, try_pop_op >(); + REMARK(" works.\n"); +} + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +class NonTrivialConstructorType { +public: + NonTrivialConstructorType( int a = 0 ) : m_a( a ), m_str( "" ) {} + NonTrivialConstructorType( const std::string& str ) : m_a( 0 ), m_str( str ) {} + NonTrivialConstructorType( int a, const std::string& str ) : m_a( a ), m_str( str ) {} + int get_a() const { return m_a; } + std::string get_str() const { return m_str; } +private: + int m_a; + std::string m_str; +}; + +enum emplace_t { emplace_op, try_emplace_op }; + +template< emplace_t emplace_op > +struct emplacer { + template< typename CQ, typename... Args> + static void emplace( CQ& queue, Args&&... val ) { queue.emplace( std::forward<Args>( val )... ); } +}; + +template<> +struct emplacer< try_emplace_op > { + template<typename CQ, typename... Args> + static void emplace( CQ& queue, Args&&... val ) { + bool result = queue.try_emplace( std::forward<Args>( val )... ); + ASSERT( result, "try_emplace error\n" ); + } +}; + +template<typename CQ, emplace_t emplace_op> +void TestEmplaceInQueue() { + CQ cq; + std::string test_str = "I'm being emplaced!"; + { + emplacer<emplace_op>::emplace( cq, 5 ); + ASSERT( cq.size() == 1, NULL ); + NonTrivialConstructorType popped( -1 ); + bool result = cq.try_pop( popped ); + ASSERT( result, NULL ); + ASSERT( popped.get_a() == 5, NULL ); + ASSERT( popped.get_str() == std::string( "" ), NULL ); + } + + ASSERT( cq.empty(), NULL ); + + { + NonTrivialConstructorType popped( -1 ); + emplacer<emplace_op>::emplace( cq, std::string(test_str) ); + bool result = cq.try_pop( popped ); + ASSERT( result, NULL ); + ASSERT( popped.get_a() == 0, NULL ); + ASSERT( popped.get_str() == test_str, NULL ); + } + + ASSERT( cq.empty(), NULL ); + + { + NonTrivialConstructorType popped( -1, "" ); + emplacer<emplace_op>::emplace( cq, 5, std::string(test_str) ); + bool result = cq.try_pop( popped ); + ASSERT( result, NULL ); + ASSERT( popped.get_a() == 5, NULL ); + ASSERT( popped.get_str() == test_str, NULL ); + } +} +void TestEmplace() { + REMARK("Testing support for 'emplace' method..."); + TestEmplaceInQueue< ConcQWithSizeWrapper<NonTrivialConstructorType>, emplace_op >(); + TestEmplaceInQueue< tbb::concurrent_bounded_queue<NonTrivialConstructorType>, emplace_op >(); + TestEmplaceInQueue< tbb::concurrent_bounded_queue<NonTrivialConstructorType>, try_emplace_op >(); + REMARK(" works.\n"); +} +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +template <typename Queue> +void Examine(Queue q, const std::vector<typename Queue::value_type> &vec) { + typedef typename Queue::value_type value_type; + + AssertEquality(q, vec); + + const Queue cq = q; + AssertEquality(cq, vec); + + q.clear(); + AssertEmptiness(q); + + FillTest<push_op>(q, vec); + EmptyTest<try_pop_op>(q, vec); + + bounded_queue_specific_test(q, vec); + + typename Queue::allocator_type a = q.get_allocator(); + value_type *ptr = a.allocate(1); + ASSERT(ptr, NULL); + a.deallocate(ptr, 1); +} + +template <typename Queue, typename QueueDebugAlloc> +void TypeTester(const std::vector<typename Queue::value_type> &vec) { + typedef typename std::vector<typename Queue::value_type>::const_iterator iterator; + ASSERT(vec.size() >= 5, "Array should have at least 5 elements"); + // Construct an empty queue. + Queue q1; + for (iterator it = vec.begin(); it != vec.end(); ++it) q1.push(*it); + Examine(q1, vec); + // Copying constructor. + Queue q3(q1); + Examine(q3, vec); + // Construct with non-default allocator. + QueueDebugAlloc q4; + for (iterator it = vec.begin(); it != vec.end(); ++it) q4.push(*it); + Examine(q4, vec); + // Copying constructor with the same allocator type. + QueueDebugAlloc q5(q4); + Examine(q5, vec); + // Construction with given allocator instance. + typename QueueDebugAlloc::allocator_type a; + QueueDebugAlloc q6(a); + for (iterator it = vec.begin(); it != vec.end(); ++it) q6.push(*it); + Examine(q6, vec); + // Construction with copying iteration range and given allocator instance. + QueueDebugAlloc q7(q1.unsafe_begin(), q1.unsafe_end(), a); + Examine<QueueDebugAlloc>(q7, vec); +} + +template <typename value_type> +void TestTypes(const std::vector<value_type> &vec) { + TypeTester< ConcQWithSizeWrapper<value_type>, ConcQWithSizeWrapper<value_type, debug_allocator<value_type> > >(vec); + TypeTester< tbb::concurrent_bounded_queue<value_type>, tbb::concurrent_bounded_queue<value_type, debug_allocator<value_type> > >(vec); +} + +void TestTypes() { + const int NUMBER = 10; + + std::vector<int> arrInt; + for (int i = 0; i < NUMBER; ++i) arrInt.push_back(i); + std::vector< tbb::atomic<int> > arrTbb; + for (int i = 0; i < NUMBER; ++i) { + tbb::atomic<int> a; + a = i; + arrTbb.push_back(a); + } + TestTypes(arrInt); + TestTypes(arrTbb); + +#if __TBB_CPP11_SMART_POINTERS_PRESENT + std::vector< std::shared_ptr<int> > arrShr; + for (int i = 0; i < NUMBER; ++i) arrShr.push_back(std::make_shared<int>(i)); + std::vector< std::weak_ptr<int> > arrWk; + std::copy(arrShr.begin(), arrShr.end(), std::back_inserter(arrWk)); + TestTypes(arrShr); + TestTypes(arrWk); +#else + REPORT("Known issue: C++11 smart pointer tests are skipped.\n"); +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +template <template <typename...> typename TQueue> +void TestDeductionGuides() { + using ComplexType = const std::string*; + std::vector<ComplexType> v; + + // check TQueue(InputIterator, InputIterator) + TQueue q1(v.begin(), v.end()); + static_assert(std::is_same<decltype(q1), TQueue<ComplexType>>::value); + + // check TQueue(InputIterator, InputIterator, Allocator) + TQueue q2(v.begin(), v.end(), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(q2), TQueue<ComplexType, std::allocator<ComplexType>>>::value); + + // check TQueue(TQueue &) + TQueue q3(q1); + static_assert(std::is_same<decltype(q3), decltype(q1)>::value); + + // check TQueue(TQueue &, Allocator) + TQueue q4(q2, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(q4), decltype(q2)>::value); + + // check TQueue(TQueue &&) + TQueue q5(std::move(q1)); + static_assert(std::is_same<decltype(q5), decltype(q1)>::value); + + // check TQueue(TQueue &&, Allocator) + TQueue q6(std::move(q4), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(q6), decltype(q4)>::value); +} +#endif + +int TestMain () { + TestEmptiness(); + + TestFullness(); + + TestClearWorks(); + + TestQueueTypeDeclaration(); + + TestQueueIteratorWorks(); + + TestQueueConstructors(); + + TestQueueWorksWithPrimitiveTypes(); + + TestQueueWorksWithSSE(); + + // Test concurrent operations + TestConcurrentPushPop(); + + TestExceptions(); + + TestAbort(); + +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestMoveSupportInPushPop(); + TestMoveConstruction(); +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + TestEmplace(); +#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + TestTypes(); + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides<tbb::concurrent_queue>(); + TestDeductionGuides<tbb::concurrent_bounded_queue>(); +#endif + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_queue_whitebox.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_queue_whitebox.cpp new file mode 100644 index 00000000..740317ff --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_queue_whitebox.cpp @@ -0,0 +1,97 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFINE_PRIVATE_PUBLIC 1 +#include "harness_inject_scheduler.h" +#define private public +#define protected public +#include "tbb/concurrent_queue.h" +#include "../tbb/concurrent_queue.cpp" +#undef protected +#undef private +#include "harness.h" + +#if _MSC_VER==1500 && !__INTEL_COMPILER + // VS2008/VC9 seems to have an issue; limits pull in math.h + #pragma warning( push ) + #pragma warning( disable: 4985 ) +#endif +#include <limits> +#if _MSC_VER==1500 && !__INTEL_COMPILER + #pragma warning( pop ) +#endif + +template <typename Q> +class FloggerBody : NoAssign { + Q& q; + size_t elem_num; +public: + FloggerBody(Q& q_, size_t elem_num_) : q(q_), elem_num(elem_num_) {} + void operator()(const int threadID) const { + typedef typename Q::value_type value_type; + value_type elem = value_type(threadID); + for (size_t i = 0; i < elem_num; ++i) { + q.push(elem); + (void) q.try_pop(elem); + } + } +}; + +template <typename Q> +void TestFloggerHelp(Q& q, size_t items_per_page) { + size_t nq = q.my_rep->n_queue; + size_t reserved_elem_num = nq * items_per_page - 1; + size_t hack_val = std::numeric_limits<std::size_t>::max() & ~reserved_elem_num; + q.my_rep->head_counter = hack_val; + q.my_rep->tail_counter = hack_val; + size_t k = q.my_rep->tail_counter & -(ptrdiff_t)nq; + + for (size_t i=0; i<nq; ++i) { + q.my_rep->array[i].head_counter = k; + q.my_rep->array[i].tail_counter = k; + } + NativeParallelFor(MaxThread, FloggerBody<Q>(q, reserved_elem_num + 20)); // to induce the overflow occurrence + ASSERT(q.empty(), "FAILED flogger/empty test."); + ASSERT(q.my_rep->head_counter < hack_val, "FAILED wraparound test."); +} + +template <typename T> +void TestFlogger() { + { + tbb::concurrent_queue<T> q; + REMARK("Wraparound on strict_ppl::concurrent_queue..."); + TestFloggerHelp(q, q.my_rep->items_per_page); + REMARK(" works.\n"); + } + { + tbb::concurrent_bounded_queue<T> q; + REMARK("Wraparound on tbb::concurrent_bounded_queue..."); + TestFloggerHelp(q, q.items_per_page); + REMARK(" works.\n"); + } +} + +void TestWraparound() { + REMARK("Testing Wraparound...\n"); + TestFlogger<int>(); + TestFlogger<unsigned char>(); + REMARK("Done Testing Wraparound.\n"); +} + +int TestMain () { + TestWraparound(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_set.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_set.cpp new file mode 100644 index 00000000..428409e8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_set.cpp @@ -0,0 +1,253 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define __TBB_EXTRA_DEBUG 1 +#if _MSC_VER +#define _SCL_SECURE_NO_WARNINGS +#endif + +#include "tbb/tbb_config.h" +#include "harness.h" +#if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT + +#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1 +#include "tbb/concurrent_set.h" +#if __TBB_INITIALIZER_LISTS_PRESENT +// These operator== are used implicitly in test_initializer_list.h. +// For some unknown reason clang is not able to find the if they a declared after the +// inclusion of test_initializer_list.h. +template<typename container_type> +bool equal_containers( container_type const& lhs, container_type const& rhs ); +template<typename T> +bool operator==(tbb::concurrent_set<T> const& lhs, tbb::concurrent_set<T> const& rhs) { + return equal_containers( lhs, rhs ); +} + +template<typename T> +bool operator==(tbb::concurrent_multiset<T> const& lhs, tbb::concurrent_multiset<T> const& rhs) { + return equal_containers( lhs, rhs ); +} +#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ +#include "test_concurrent_ordered_common.h" + +typedef tbb::concurrent_set<int, std::less<int>, MyAllocator> MySet; +typedef tbb::concurrent_set<int, std::greater<int>, MyAllocator> MyGreaterSet; +typedef tbb::concurrent_set<check_type<int>, std::less<int>, MyAllocator> MyCheckedSet; +typedef tbb::concurrent_set<FooWithAssign, std::less<Foo>, MyAllocator> MyCheckedStateSet; +typedef tbb::concurrent_multiset<int, std::less<int>, MyAllocator> MyMultiSet; +typedef tbb::concurrent_multiset<int, std::greater<int>, MyAllocator> MyGreaterMultiSet; +typedef tbb::concurrent_multiset<check_type<int>, std::less<int>, MyAllocator> MyCheckedMultiSet; + +struct co_set_type : ordered_move_traits_base { + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_set<element_type, std::less<element_type>, allocator_type > type; + }; + + typedef FooIterator init_iterator_type; +}; + +struct co_multiset_type : ordered_move_traits_base { + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_multiset<element_type, std::less<element_type>, allocator_type > type; + }; + + typedef FooIterator init_iterator_type; +}; + +struct OrderedSetTypesTester{ + template <bool defCtorPresent, typename ValueType> + void check( const std::list<ValueType> &lst ) { + TypeTester< defCtorPresent, tbb::concurrent_set< ValueType >, + tbb::concurrent_set< ValueType , std::less<ValueType>, debug_allocator<ValueType> > >( lst ); + TypeTester< defCtorPresent, tbb::concurrent_multiset< ValueType >, + tbb::concurrent_multiset< ValueType , std::less<ValueType>, debug_allocator<ValueType> > >( lst ); + } +}; + +void TestTypes() { + TestSetCommonTypes<OrderedSetTypesTester>(); + + #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT + // Regression test for a problem with excessive requirements of emplace() + test_emplace_insert<tbb::concurrent_set< test::unique_ptr<int> >, + tbb::internal::false_type>( new int, new int ); + test_emplace_insert<tbb::concurrent_multiset< test::unique_ptr<int> >, + tbb::internal::false_type>( new int, new int ); + #endif /*__TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT*/ +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +template <template <typename ...> typename TSet> +void TestDeductionGuides() { + std::vector<int> vc({1, 2, 3}); + TSet set(vc.begin(), vc.end()); + static_assert(std::is_same_v<decltype(set), TSet<int>>, "Wrong"); + + std::greater<int> compare; + std::allocator<int> allocator; + + TSet set2(vc.begin(), vc.end(), compare); + static_assert(std::is_same_v<decltype(set2), TSet<int, decltype(compare)>>, "Wrong"); + + TSet set3(vc.begin(), vc.end(), allocator); + static_assert(std::is_same_v<decltype(set3), TSet<int, std::less<int>, decltype(allocator)>>, "Wrong"); + + TSet set4(vc.begin(), vc.end(), compare, allocator); + static_assert(std::is_same_v<decltype(set4), TSet<int, decltype(compare), decltype(allocator)>>, "Wrong"); + + auto init_list = { int(1), int(2), int(3) }; + TSet set5(init_list); + static_assert(std::is_same_v<decltype(set5), TSet<int>>, "Wrong"); + + TSet set6(init_list, compare); + static_assert(std::is_same_v<decltype(set6), TSet<int, decltype(compare)>>, "Wrong"); + + TSet set7(init_list, allocator); + static_assert(std::is_same_v<decltype(set7), TSet<int, std::less<int>, decltype(allocator)>>, "Wrong"); + + TSet set8(init_list, compare, allocator); + static_assert(std::is_same_v<decltype(set8), TSet<int, decltype(compare), decltype(allocator)>>, "Wrong"); +} +#endif /*__TBB_CPP17_DEDUCTION_GUIDES_PRESENT*/ + +void test_heterogeneous_functions() { + check_heterogeneous_functions<tbb::concurrent_set<int, transparent_less> >(); + check_heterogeneous_functions<tbb::concurrent_multiset<int, transparent_less> >(); +} + +struct compare_keys_less { + bool operator() (const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const { + return std::less<int>()(lhs.first, rhs.first); + } +}; + +struct compare_keys_greater { + bool operator() (const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const { + return std::greater<int>()(lhs.first, rhs.first); + } +}; + +void multicontainer_specific_test() { + check_multicontainer_internal_order<tbb::concurrent_multiset<std::pair<int, int>, compare_keys_less > >(); + check_multicontainer_internal_order<tbb::concurrent_multiset<std::pair<int, int>, compare_keys_greater > >(); +} + +#if !__TBB_SCOPED_ALLOCATOR_BROKEN +#include <scoped_allocator> + +template <template<typename...> class Set> +void test_scoped_allocator() { + using allocator_data_type = allocator_aware_data<std::scoped_allocator_adaptor<tbb::tbb_allocator<int>>>; + using allocator_type = std::scoped_allocator_adaptor<tbb::tbb_allocator<allocator_data_type>>; + using set_type = Set<allocator_data_type, allocator_data_compare, allocator_type>; + + allocator_type allocator; + allocator_data_type v1(1, allocator), v2(2, allocator); + set_type set1(allocator), set2(allocator); + + auto init_list = { v1, v2 }; + + allocator_data_type::assert_on_constructions = true; + set1.emplace(v1); + set2.emplace(std::move(v1)); + + set1.clear(); + set2.clear(); + + set1.insert(v1); + set2.insert(std::move(v1)); + + set1.clear(); + set2.clear(); + + set1.insert(init_list); + + set1.clear(); + set2.clear(); + + set1 = set2; + set2 = std::move(set1); + + set1.swap(set2); + + allocator_data_type::assert_on_constructions = false; +} + +#endif // !__TBB_SCOPED_ALLOCATOR_BROKEN + +int TestMain() { + test_machine(); + + test_basic<MySet>( "concurrent Set" ); + test_basic<MyGreaterSet>( "concurrent greater Set" ); + test_concurrent<MySet>( "concurrent Set" ); + test_concurrent<MyGreaterSet>( "concurrent greater Set" ); + test_basic<MyMultiSet>( "concurrent MultiSet" ); + test_basic<MyGreaterMultiSet>( "concurrent greater MultiSet" ); + test_concurrent<MyMultiSet>( "concurrent MultiSet" ); + test_concurrent<MyGreaterMultiSet>( "concurrent greater MultiSet" ); + + { Check<MyCheckedSet::value_type> checkit; test_basic<MyCheckedSet>( "concurrent set (checked)" ); } + { Check<MyCheckedSet::value_type> checkit; test_concurrent<MyCheckedSet>( "concurrent set (checked)" ); } + test_basic<MyCheckedStateSet>("concurrent set (checked state of elements)", tbb::internal::true_type()); + test_concurrent<MyCheckedStateSet>("concurrent set (checked state of elements)"); + + { Check<MyCheckedMultiSet::value_type> checkit; test_basic<MyCheckedMultiSet>( "concurrent MultiSet (checked)" ); } + { Check<MyCheckedMultiSet::value_type> checkit; test_concurrent<MyCheckedMultiSet>( "concurrent MultiSet (checked)" ); } + + multicontainer_specific_test(); + + TestInitList< tbb::concurrent_set<int>, + tbb::concurrent_multiset<int> >( {1,2,3,4,5} ); + +#if __TBB_RANGE_BASED_FOR_PRESENT + TestRangeBasedFor<MySet>(); + TestRangeBasedFor<MyMultiSet>(); +#endif + + test_rvalue_ref_support<co_set_type>( "concurrent map" ); + test_rvalue_ref_support<co_multiset_type>( "concurrent multimap" ); + + TestTypes(); + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides<tbb::concurrent_set>(); + TestDeductionGuides<tbb::concurrent_multiset>(); +#endif + + node_handling::TestNodeHandling<MySet>(); + node_handling::TestNodeHandling<MyMultiSet>(); + node_handling::TestMerge<MySet, MyMultiSet>(1000); + + test_heterogeneous_functions(); + + test_allocator_traits<tbb::concurrent_set, int, std::less<int>>(); + test_allocator_traits<tbb::concurrent_multiset, int, std::less<int>>(); + +#if !__TBB_SCOPED_ALLOCATOR_BROKEN + test_scoped_allocator<tbb::concurrent_set>(); + test_scoped_allocator<tbb::concurrent_multiset>(); +#endif + + return Harness::Done; +} +#else +int TestMain() { + return Harness::Skipped; +} +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_common.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_common.h new file mode 100644 index 00000000..12417af8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_common.h @@ -0,0 +1,293 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define __TBB_UNORDERED_TEST 1 + +#include "test_concurrent_associative_common.h" + +template<typename MyTable> +inline void CheckEmptyContainerAllocator(MyTable &table, size_t expected_allocs, size_t expected_frees, bool exact, int line) { + typename MyTable::allocator_type a = table.get_allocator(); + REMARK("#%d checking allocators: items %u/%u, allocs %u/%u\n", line, + unsigned(a.items_allocated), unsigned(a.items_freed), unsigned(a.allocations), unsigned(a.frees) ); + ASSERT( a.items_allocated == a.allocations, NULL); ASSERT( a.items_freed == a.frees, NULL); + ASSERT( a.items_allocated == a.items_freed + 1, NULL); + CheckAllocator<MyTable>(a, expected_allocs, expected_frees, exact); +} + +template<typename T> +struct degenerate_hash { + size_t operator()(const T& /*a*/) const { + return 1; + } +}; + +template <typename T> +void test_unordered_methods(){ + T cont; + cont.insert(Value<T>::make(1)); + cont.insert(Value<T>::make(2)); + // unordered_specific + // void rehash(size_type n); + cont.rehash(16); + + // float load_factor() const; + // float max_load_factor() const; + ASSERT(cont.load_factor() <= cont.max_load_factor(), "Load factor is invalid"); + + // void max_load_factor(float z); + cont.max_load_factor(16.0f); + ASSERT(cont.max_load_factor() == 16.0f, "Max load factor has not been changed properly"); + + // hasher hash_function() const; + cont.hash_function(); + + // key_equal key_eq() const; + cont.key_eq(); + + cont.clear(); + CheckEmptyContainerAllocatorA(cont, 1, 0); // one dummy is always allocated + for (int i = 0; i < 256; i++) + { + std::pair<typename T::iterator, bool> ins3 = cont.insert(Value<T>::make(i)); + ASSERT(ins3.second == true && Value<T>::get(*(ins3.first)) == i, "Element 1 has not been inserted properly"); + } + ASSERT(cont.size() == 256, "Wrong number of elements have been inserted"); + // size_type unsafe_bucket_count() const; + ASSERT(cont.unsafe_bucket_count() == 16, "Wrong number of buckets"); + + // size_type unsafe_max_bucket_count() const; + ASSERT(cont.unsafe_max_bucket_count() > 65536, "Wrong max number of buckets"); + + for (unsigned int i = 0; i < 256; i++) + { + typename T::size_type buck = cont.unsafe_bucket(i); + + // size_type unsafe_bucket(const key_type& k) const; + ASSERT(buck < 16, "Wrong bucket mapping"); + } + + typename T::size_type bucketSizeSum = 0; + typename T::size_type iteratorSizeSum = 0; + + for (unsigned int i = 0; i < 16; i++) + { + bucketSizeSum += cont.unsafe_bucket_size(i); + for (typename T::iterator bit = cont.unsafe_begin(i); bit != cont.unsafe_end(i); bit++) iteratorSizeSum++; + } + ASSERT(bucketSizeSum == 256, "sum of bucket counts incorrect"); + ASSERT(iteratorSizeSum == 256, "sum of iterator counts incorrect"); +} + +template<typename T, typename do_check_element_state> +void test_basic(const char * str, do_check_element_state) +{ + test_basic_common<T>(str, do_check_element_state()); + test_unordered_methods<T>(); +} + +template<typename T> +void test_basic(const char * str){ + test_basic_common<T>(str, tbb::internal::false_type()); + test_unordered_methods<T>(); +} + +template<typename T> +void test_concurrent(const char *tablename, bool asymptotic = false) { + test_concurrent_common<T>(tablename, asymptotic); +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +struct unordered_move_traits_base { + enum{ expected_number_of_items_to_allocate_for_steal_move = 3 }; + + template <typename unordered_type, typename iterator_type> + static unordered_type& construct_container(tbb::aligned_space<unordered_type> & storage, iterator_type begin, iterator_type end){ + new (storage.begin()) unordered_type(begin, end); + return * storage.begin(); + } + + template <typename unordered_type, typename iterator_type, typename allocator_type> + static unordered_type& construct_container(tbb::aligned_space<unordered_type> & storage, iterator_type begin, iterator_type end, allocator_type const& a ){ + size_t deault_n_of_buckets = 8; //can not use concurrent_unordered_base::n_of_buckets as it is inaccessible + new (storage.begin()) unordered_type(begin, end, deault_n_of_buckets, typename unordered_type::hasher(), typename unordered_type::key_equal(), a); + return * storage.begin(); + } + + template<typename unordered_type, typename iterator> + static bool equal(unordered_type const& c, iterator begin, iterator end){ + bool equal_sizes = ( static_cast<size_t>(std::distance(begin, end)) == c.size() ); + if (!equal_sizes) + return false; + + for (iterator it = begin; it != end; ++it ){ + if (c.find( Value<unordered_type>::key(*it)) == c.end()){ + return false; + } + } + return true; + } +}; +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT*/ + +#if __TBB_CPP11_SMART_POINTERS_PRESENT +namespace tbb { + template<> class tbb_hash< std::shared_ptr<int> > { + public: + size_t operator()( const std::shared_ptr<int>& key ) const { return tbb_hasher( *key ); } + }; + template<> class tbb_hash< const std::shared_ptr<int> > { + public: + size_t operator()( const std::shared_ptr<int>& key ) const { return tbb_hasher( *key ); } + }; + template<> class tbb_hash< std::weak_ptr<int> > { + public: + size_t operator()( const std::weak_ptr<int>& key ) const { return tbb_hasher( *key.lock( ) ); } + }; + template<> class tbb_hash< const std::weak_ptr<int> > { + public: + size_t operator()( const std::weak_ptr<int>& key ) const { return tbb_hasher( *key.lock( ) ); } + }; + template<> class tbb_hash< test::unique_ptr<int> > { + public: + size_t operator()( const test::unique_ptr<int>& key ) const { return tbb_hasher( *key ); } + }; + template<> class tbb_hash< const test::unique_ptr<int> > { + public: + size_t operator()( const test::unique_ptr<int>& key ) const { return tbb_hasher( *key ); } + }; +} +#endif /*__TBB_CPP11_SMART_POINTERS_PRESENT*/ + +template <bool defCtorPresent, typename Table> +void CustomExamine( Table c, const std::list<typename Table::value_type> lst) { + typedef typename Table::value_type ValueType; + typedef typename Table::size_type SizeType; + const Table constC = c; + + const SizeType bucket_count = c.unsafe_bucket_count(); + ASSERT( c.unsafe_max_bucket_count() >= bucket_count, NULL ); + SizeType counter = SizeType( 0 ); + for ( SizeType i = 0; i < bucket_count; ++i ) { + const SizeType size = c.unsafe_bucket_size( i ); + typedef typename Table::difference_type diff_type; + ASSERT( std::distance( c.unsafe_begin( i ), c.unsafe_end( i ) ) == diff_type( size ), NULL ); + ASSERT( std::distance( c.unsafe_cbegin( i ), c.unsafe_cend( i ) ) == diff_type( size ), NULL ); + ASSERT( std::distance( constC.unsafe_begin( i ), constC.unsafe_end( i ) ) == diff_type( size ), NULL ); + ASSERT( std::distance( constC.unsafe_cbegin( i ), constC.unsafe_cend( i ) ) == diff_type( size ), NULL ); + counter += size; + } + ASSERT( counter == lst.size(), NULL ); + + for ( typename std::list<ValueType>::const_iterator it = lst.begin(); it != lst.end(); ) { + const SizeType index = c.unsafe_bucket( Value<Table>::key( *it ) ); + typename std::list<ValueType>::const_iterator prev_it = it++; + ASSERT( std::search( c.unsafe_begin( index ), c.unsafe_end( index ), prev_it, it, Harness::IsEqual() ) != c.unsafe_end( index ), NULL ); + } + + c.rehash( 2 * bucket_count ); + ASSERT( c.unsafe_bucket_count() > bucket_count, NULL ); + + ASSERT( c.load_factor() <= c.max_load_factor(), NULL ); + + c.max_load_factor( 1.0f ); + c.hash_function(); + c.key_eq(); +} + +template <bool defCtorPresent, typename Table> +void Examine( Table c, const std::list<typename Table::value_type> &lst) { + CommonExamine<defCtorPresent>(c, lst); + CustomExamine<defCtorPresent>(c, lst); +} + +template <bool defCtorPresent, typename Table, typename TableDebugAlloc> +void TypeTester( const std::list<typename Table::value_type> &lst ) { + ASSERT( lst.size() >= 5, "Array should have at least 5 elements" ); + ASSERT( lst.size() <= 100, "The test has O(n^2) complexity so a big number of elements can lead long execution time" ); + // Construct an empty table. + Table c1; + c1.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c1, lst ); + + typename Table::size_type initial_bucket_number = 8; + typename Table::allocator_type allocator; + typename Table::hasher hasher; +#if __TBB_INITIALIZER_LISTS_PRESENT && !__TBB_CPP11_INIT_LIST_TEMP_OBJS_LIFETIME_BROKEN + // Constructor from an initializer_list. + typename std::list<typename Table::value_type>::const_iterator it = lst.begin(); + Table c2( { *it++, *it++, *it++ } ); + c2.insert( it, lst.end( ) ); + Examine<defCtorPresent>( c2, lst ); + + it = lst.begin(); + // Constructor from an initializer_list, default hasher and key equality and non-default allocator + Table c2_alloc( { *it++, *it++, *it++ }, initial_bucket_number, allocator); + c2_alloc.insert( it, lst.end() ); + Examine<defCtorPresent>( c2_alloc, lst ); + + it = lst.begin(); + // Constructor from an initializer_list, default key equality and non-default hasher and allocator + Table c2_hash_alloc( { *it++, *it++, *it++ }, initial_bucket_number, hasher, allocator ); + c2_hash_alloc.insert( it, lst.end() ); + Examine<defCtorPresent>( c2_hash_alloc, lst ); +#endif + // Copying constructor. + Table c3( c1 ); + Examine<defCtorPresent>( c3, lst ); + // Construct with non-default allocator + TableDebugAlloc c4; + c4.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c4, lst ); + // Copying constructor for a container with a different allocator type. + TableDebugAlloc c5( c4 ); + Examine<defCtorPresent>( c5, lst ); + // Construction empty table with n preallocated buckets. + Table c6( lst.size() ); + c6.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c6, lst ); + + // Construction empty table with n preallocated buckets, default hasher and key equality and non-default allocator + Table c6_alloc( lst.size(), allocator ); + c6_alloc.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c6_alloc, lst ); + + // Construction empty table with n preallocated buckets, default key equality and non-default hasher and allocator + Table c6_hash_alloc( lst.size(), hasher, allocator ); + c6_hash_alloc.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c6_hash_alloc, lst ); + + TableDebugAlloc c7( lst.size( ) ); + c7.insert( lst.begin(), lst.end() ); + Examine<defCtorPresent>( c7, lst ); + // Construction with a copying iteration range and a given allocator instance. + Table c8( c1.begin(), c1.end() ); + Examine<defCtorPresent>( c8, lst ); + + // Construction with a copying iteration range, default hasher and key equality and non-default allocator + Table c8_alloc( c1.begin(), c1.end(), initial_bucket_number, allocator ); + Examine<defCtorPresent>( c8_alloc, lst ); + + // Construction with a copying iteration range, default key equality and non-default hasher and allocator + Table c8_hash_alloc( c1.begin(), c1.end(), initial_bucket_number, hasher, allocator ); + Examine<defCtorPresent>( c8_hash_alloc, lst); + + // Construction with an instance of non-default allocator + typename TableDebugAlloc::allocator_type a; + TableDebugAlloc c9( a ); + c9.insert( c7.begin(), c7.end() ); + Examine<defCtorPresent>( c9, lst ); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_map.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_map.cpp new file mode 100644 index 00000000..2fa4efe9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_map.cpp @@ -0,0 +1,252 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define __TBB_EXTRA_DEBUG 1 +#if _MSC_VER +#define _SCL_SECURE_NO_WARNINGS +#endif + +#include "tbb/concurrent_unordered_map.h" +#if __TBB_INITIALIZER_LISTS_PRESENT +// These operator== are used implicitly in test_initializer_list.h. +// For some unknown reason clang is not able to find the if they a declared after the +// inclusion of test_initializer_list.h. +template<typename container_type> +bool equal_containers( container_type const& lhs, container_type const& rhs ); +template<typename Key, typename Value> +bool operator==( tbb::concurrent_unordered_map<Key, Value> const& lhs, tbb::concurrent_unordered_map<Key, Value> const& rhs ) { + return equal_containers( lhs, rhs ); +} +template<typename Key, typename Value> +bool operator==( tbb::concurrent_unordered_multimap<Key, Value> const& lhs, tbb::concurrent_unordered_multimap<Key, Value> const& rhs ) { + return equal_containers( lhs, rhs ); +} +#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ +#include "test_concurrent_unordered_common.h" + +typedef tbb::concurrent_unordered_map<int, int, tbb::tbb_hash<int>, std::equal_to<int>, MyAllocator> MyMap; +typedef tbb::concurrent_unordered_map<int, int, degenerate_hash<int>, std::equal_to<int>, MyAllocator> MyDegenerateMap; +typedef tbb::concurrent_unordered_map<int, check_type<int>, tbb::tbb_hash<int>, std::equal_to<int>, MyAllocator> MyCheckedMap; +typedef tbb::concurrent_unordered_map<intptr_t, FooWithAssign, tbb::tbb_hash<intptr_t>, std::equal_to<intptr_t>, MyAllocator> MyCheckedStateMap; +typedef tbb::concurrent_unordered_multimap<int, int, tbb::tbb_hash<int>, std::equal_to<int>, MyAllocator> MyMultiMap; +typedef tbb::concurrent_unordered_multimap<int, int, degenerate_hash<int>, std::equal_to<int>, MyAllocator> MyDegenerateMultiMap; +typedef tbb::concurrent_unordered_multimap<int, check_type<int>, tbb::tbb_hash<int>, std::equal_to<int>, MyAllocator> MyCheckedMultiMap; + +template <> +struct SpecialTests <MyMap> { + static void Test( const char *str ) { + SpecialMapTests<MyMap>(str); + } +}; + +template <> +struct SpecialTests <MyMultiMap> { + static void Test( const char *str ) { + SpecialMultiMapTests<MyMultiMap>(str); + } +}; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +struct cu_map_type : unordered_move_traits_base { + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_unordered_map<element_type, element_type, tbb::tbb_hash<element_type>, std::equal_to<element_type>, allocator_type > type; + }; + + typedef FooPairIterator init_iterator_type; +}; + +struct cu_multimap_type : unordered_move_traits_base { + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_unordered_multimap<element_type, element_type, tbb::tbb_hash<element_type>, std::equal_to<element_type>, allocator_type > type; + }; + + typedef FooPairIterator init_iterator_type; +}; +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +template <bool defCtorPresent, typename Key, typename Element, typename Hasher, typename Equality, typename Allocator> +void TestMapSpecificMethods( tbb::concurrent_unordered_map<Key, Element, Hasher, Equality, Allocator> &c, + const typename tbb::concurrent_unordered_map<Key, Element, Hasher, Equality, Allocator>::value_type &value ) { + TestMapSpecificMethodsImpl<defCtorPresent>(c, value); + } + +struct UnorderedMapTypesTester{ + template <bool defCtorPresent, typename ValueType> + void check( const std::list<ValueType> &lst ) { + typedef typename ValueType::first_type KeyType; + typedef typename ValueType::second_type ElemType; + TypeTester< defCtorPresent, tbb::concurrent_unordered_map< KeyType, ElemType, tbb::tbb_hash<KeyType>, Harness::IsEqual>, + tbb::concurrent_unordered_map< KeyType, ElemType, tbb::tbb_hash<KeyType>, Harness::IsEqual, debug_allocator<ValueType> > >( lst ); + TypeTester< defCtorPresent, tbb::concurrent_unordered_multimap< KeyType, ElemType, tbb::tbb_hash<KeyType>, Harness::IsEqual>, + tbb::concurrent_unordered_multimap< KeyType, ElemType, tbb::tbb_hash<KeyType>, Harness::IsEqual, debug_allocator<ValueType> > >( lst ); + } +}; + +void TestTypes() { + TestMapCommonTypes<UnorderedMapTypesTester>(); + + #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT + // Regression test for a problem with excessive requirements of emplace() + test_emplace_insert<tbb::concurrent_unordered_map< int*, test::unique_ptr<int> >, + tbb::internal::false_type>( new int, new int ); + test_emplace_insert<tbb::concurrent_unordered_multimap< int*, test::unique_ptr<int> >, + tbb::internal::false_type>( new int, new int ); + #endif /*__TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT*/ +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +template <template <typename...> typename TMap> +void TestDeductionGuides() { + using ComplexType = std::pair<int, std::string>; + using ComplexTypeConst = std::pair<const int, std::string>; + std::vector<ComplexType> v; + auto l = { ComplexTypeConst(1, "one"), ComplexTypeConst(2, "two")}; + + // check TMap(InputIterator, InputIterator) + TMap m0(v.begin(), v.end()); + static_assert(std::is_same<decltype(m0), TMap<int, std::string>>::value); + + // check TMap(InputIterator, InputIterator, size_t) + TMap m1(v.begin(), v.end(), 1); + static_assert(std::is_same<decltype(m1), TMap<int, std::string>>::value); + + + // check TMap(InputIterator, InputIterator, size_t, Hasher) + TMap m2(v.begin(), v.end(), 4, std::hash<int>()); + static_assert(std::is_same<decltype(m2), TMap<int, std::string, std::hash<int>>>::value); + + // check TMap(InputIterator, InputIterator, size_t, Hasher, Equality) + TMap m3(v.begin(), v.end(), 4, std::hash<int>(), std::less<int>()); + static_assert(std::is_same<decltype(m3), TMap<int, std::string, std::hash<int>, std::less<int>>>::value); + + // check TMap(InputIterator, InputIterator, size_t, Hasher, Equality, Allocator) + TMap m4(v.begin(), v.end(), 4, std::hash<int>(), std::less<int>(), std::allocator<int>()); + static_assert(std::is_same<decltype(m4), TMap<int, std::string, std::hash<int>, + std::less<int>, std::allocator<int>>>::value); + + // check TMap(InputIterator, InputIterator, size_t, Allocator) + TMap m5(v.begin(), v.end(), 5, std::allocator<int>()); + static_assert(std::is_same<decltype(m5), TMap<int, std::string, tbb::tbb_hash<int>, + std::equal_to<int>, std::allocator<int>>>::value); + + // check TMap(InputIterator, InputIterator, size_t, Hasher, Allocator) + TMap m6(v.begin(), v.end(), 4, std::hash<int>(), std::allocator<int>()); + static_assert(std::is_same<decltype(m6), TMap<int, std::string, std::hash<int>, + std::equal_to<int>, std::allocator<int>>>::value); + + // check TMap(std::initializer_list) + TMap m7(l); + static_assert(std::is_same<decltype(m7), TMap<int, std::string>>::value); + + // check TMap(std::initializer_list, size_t) + TMap m8(l, 1); + static_assert(std::is_same<decltype(m8), TMap<int, std::string>>::value); + + // check TMap(std::initializer_list, size_t, Hasher) + TMap m9(l, 4, std::hash<int>()); + static_assert(std::is_same<decltype(m9), TMap<int, std::string, std::hash<int>>>::value); + + // check TMap(std::initializer_list, size_t, Hasher, Equality) + TMap m10(l, 4, std::hash<int>(), std::less<int>()); + static_assert(std::is_same<decltype(m10), TMap<int, std::string, std::hash<int>, std::less<int>>>::value); + + // check TMap(std::initializer_list, size_t, Hasher, Equality, Allocator) + TMap m11(l, 4, std::hash<int>(), std::less<int>(), std::allocator<int>()); + static_assert(std::is_same<decltype(m11), TMap<int, std::string, std::hash<int>, + std::less<int>, std::allocator<int>>>::value); + + // check TMap(std::initializer_list, size_t, Allocator) + TMap m12(l, 4, std::allocator<int>()); + static_assert(std::is_same<decltype(m12), TMap<int, std::string, tbb::tbb_hash<int>, + std::equal_to<int>, std::allocator<int>>>::value); + + // check TMap(std::initializer_list, size_t, Hasher, Allocator) + TMap m13(l, 4, std::hash<int>(), std::allocator<int>()); + static_assert(std::is_same<decltype(m13), TMap<int, std::string, std::hash<int>, + std::equal_to<int>, std::allocator<int>>>::value); + + // check TMap(TMap &) + TMap m14(m1); + static_assert(std::is_same<decltype(m14), decltype(m1)>::value); + + // check TMap(TMap &, Allocator) + TMap m15(m5, std::allocator<int>()); + static_assert(std::is_same<decltype(m15), decltype(m5)>::value); + + // check TMap(TMap &&) + TMap m16(std::move(m1)); + static_assert(std::is_same<decltype(m16), decltype(m1)>::value); + + // check TMap(TMap &&, Allocator) + TMap m17(std::move(m5), std::allocator<int>()); + static_assert(std::is_same<decltype(m17), decltype(m5)>::value); +} +#endif + +int TestMain() { + test_machine(); + + test_basic<MyMap>( "concurrent unordered Map" ); + test_basic<MyDegenerateMap>( "concurrent unordered degenerate Map" ); + test_concurrent<MyMap>( "concurrent unordered Map" ); + test_concurrent<MyDegenerateMap>( "concurrent unordered degenerate Map" ); + test_basic<MyMultiMap>( "concurrent unordered MultiMap" ); + test_basic<MyDegenerateMultiMap>( "concurrent unordered degenerate MultiMap" ); + test_concurrent<MyMultiMap>( "concurrent unordered MultiMap" ); + test_concurrent<MyDegenerateMultiMap>( "concurrent unordered degenerate MultiMap" ); + test_concurrent<MyMultiMap>( "concurrent unordered MultiMap asymptotic", true ); + + { Check<MyCheckedMap::value_type> checkit; test_basic<MyCheckedMap>( "concurrent unordered map (checked)" ); } + { Check<MyCheckedMap::value_type> checkit; test_concurrent<MyCheckedMap>( "concurrent unordered map (checked)" ); } + test_basic<MyCheckedStateMap>("concurrent unordered map (checked state of elements)", tbb::internal::true_type()); + test_concurrent<MyCheckedStateMap>("concurrent unordered map (checked state of elements)"); + + { Check<MyCheckedMultiMap::value_type> checkit; test_basic<MyCheckedMultiMap>( "concurrent unordered MultiMap (checked)" ); } + { Check<MyCheckedMultiMap::value_type> checkit; test_concurrent<MyCheckedMultiMap>( "concurrent unordered MultiMap (checked)" ); } + +#if __TBB_INITIALIZER_LISTS_PRESENT + TestInitList< tbb::concurrent_unordered_map<int, int>, + tbb::concurrent_unordered_multimap<int, int> >( {{1,1},{2,2},{3,3},{4,4},{5,5}} ); +#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ + +#if __TBB_RANGE_BASED_FOR_PRESENT + TestRangeBasedFor<MyMap>(); + TestRangeBasedFor<MyMultiMap>(); +#endif + +#if __TBB_CPP11_RVALUE_REF_PRESENT + test_rvalue_ref_support<cu_map_type>( "concurrent unordered map" ); + test_rvalue_ref_support<cu_multimap_type>( "concurrent unordered multimap" ); +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides<tbb::concurrent_unordered_map>(); + TestDeductionGuides<tbb::concurrent_unordered_multimap>(); +#endif + + TestTypes(); + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + node_handling::TestNodeHandling<MyMap>(); + node_handling::TestNodeHandling<MyMultiMap>(); + node_handling::TestMerge<MyMap, MyMultiMap>(10000); + node_handling::TestMerge<MyMap, MyDegenerateMap>(10000); +#endif /*__TBB_UNORDERED_NODE_HANDLE_PRESENT*/ + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_set.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_set.cpp new file mode 100644 index 00000000..d904defd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_unordered_set.cpp @@ -0,0 +1,272 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _MSC_VER +#define _SCL_SECURE_NO_WARNINGS +#endif + +#include "harness_defs.h" +#if !(__TBB_TEST_SECONDARY && __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN) + +#define __TBB_EXTRA_DEBUG 1 +#include "tbb/concurrent_unordered_set.h" +#include "harness_assert.h" + +#if __TBB_TEST_SECONDARY + +#include "harness_runtime_loader.h" + +#else // __TBB_TEST_SECONDARY +#if __TBB_INITIALIZER_LISTS_PRESENT +// These operator== are used implicitly in test_initializer_list.h. +// For some unknown reason clang is not able to find the if they a declared after the +// inclusion of test_initializer_list.h. +template<typename container_type> +bool equal_containers( container_type const& lhs, container_type const& rhs ); +template<typename T> +bool operator==(tbb::concurrent_unordered_set<T> const& lhs, tbb::concurrent_unordered_set<T> const& rhs) { + return equal_containers( lhs, rhs ); +} + +template<typename T> +bool operator==(tbb::concurrent_unordered_multiset<T> const& lhs, tbb::concurrent_unordered_multiset<T> const& rhs) { + return equal_containers( lhs, rhs ); +} +#endif /* __TBB_INITIALIZER_LISTS_PRESENT */ +#include "test_concurrent_unordered_common.h" + +typedef tbb::concurrent_unordered_set<int, tbb::tbb_hash<int>, std::equal_to<int>, MyAllocator> MySet; +typedef tbb::concurrent_unordered_set<int, degenerate_hash<int>, std::equal_to<int>, MyAllocator> MyDegenerateSet; +typedef tbb::concurrent_unordered_set<check_type<int>, tbb::tbb_hash<check_type<int> >, std::equal_to<check_type<int> >, MyAllocator> MyCheckedSet; +typedef tbb::concurrent_unordered_set<FooWithAssign, tbb::tbb_hash<Foo>, std::equal_to<FooWithAssign>, MyAllocator> MyCheckedStateSet; +typedef tbb::concurrent_unordered_multiset<int, tbb::tbb_hash<int>, std::equal_to<int>, MyAllocator> MyMultiSet; +typedef tbb::concurrent_unordered_multiset<int, degenerate_hash<int>, std::equal_to<int>, MyAllocator> MyDegenerateMultiSet; +typedef tbb::concurrent_unordered_multiset<check_type<int>, tbb::tbb_hash<check_type<int> >, std::equal_to<check_type<int> >, MyAllocator> MyCheckedMultiSet; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +struct cu_set_type : unordered_move_traits_base { + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_unordered_set<element_type, tbb::tbb_hash<element_type>, std::equal_to<element_type>, allocator_type > type; + }; + + typedef FooIterator init_iterator_type; +}; + +struct cu_multiset_type : unordered_move_traits_base { + template<typename element_type, typename allocator_type> + struct apply { + typedef tbb::concurrent_unordered_multiset<element_type, tbb::tbb_hash<element_type>, std::equal_to<element_type>, allocator_type > type; + }; + + typedef FooIterator init_iterator_type; +}; +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ +struct UnorderedSetTypesTester { + template <bool defCtorPresent, typename value_type> + void check( const std::list<value_type> &lst ) { + TypeTester< defCtorPresent, tbb::concurrent_unordered_set<value_type, tbb::tbb_hash<value_type>, Harness::IsEqual>, + tbb::concurrent_unordered_set< value_type, tbb::tbb_hash<value_type>, Harness::IsEqual, debug_allocator<value_type> > >( lst ); + TypeTester< defCtorPresent, tbb::concurrent_unordered_multiset<value_type, tbb::tbb_hash<value_type>, Harness::IsEqual>, + tbb::concurrent_unordered_multiset< value_type, tbb::tbb_hash<value_type>, Harness::IsEqual, debug_allocator<value_type> > >( lst ); + } +}; + +void TestTypes( ) { + TestSetCommonTypes<UnorderedSetTypesTester>(); + +#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT + // Regression test for a problem with excessive requirements of emplace() + test_emplace_insert<tbb::concurrent_unordered_set< test::unique_ptr<int> >, + tbb::internal::false_type>( new int, new int ); + test_emplace_insert<tbb::concurrent_unordered_multiset< test::unique_ptr<int> >, + tbb::internal::false_type>( new int, new int ); +#endif /*__TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_SMART_POINTERS_PRESENT*/ +} + +#endif // __TBB_TEST_SECONDARY + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +template <template <typename ...> typename TSet> +void TestDeductionGuides() { + using ComplexType = const std::string *; + std::vector<ComplexType> v; + std::string s = "s"; + auto l = { ComplexType(&s), ComplexType(&s)}; + + // check TSet(InputIterator,InputIterator) + TSet s1(v.begin(), v.end()); + static_assert(std::is_same<decltype(s1), TSet<ComplexType>>::value); + + // check TSet(InputIterator,InputIterator, size_t, Hasher) + TSet s2(v.begin(), v.end(), 5, std::hash<ComplexType>()); + static_assert(std::is_same<decltype(s2), TSet<ComplexType, std::hash<ComplexType>>>::value); + + // check TSet(InputIterator,InputIterator, size_t, Hasher, Equality) + TSet s3(v.begin(), v.end(), 5, std::hash<ComplexType>(), std::less<ComplexType>()); + static_assert(std::is_same<decltype(s3), TSet<ComplexType, std::hash<ComplexType>, + std::less<ComplexType>>>::value); + + // check TSet(InputIterator,InputIterator, size_t, Hasher, Equality, Allocator) + TSet s4(v.begin(), v.end(), 5, std::hash<ComplexType>(), std::less<ComplexType>(), + std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(s4), TSet<ComplexType, std::hash<ComplexType>, + std::less<ComplexType>, std::allocator<ComplexType>>>::value); + + // check TSet(InputIterator,InputIterator, size_t, Allocator) + TSet s5(v.begin(), v.end(), 5, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(s5), TSet<ComplexType, tbb::tbb_hash<ComplexType>, + std::equal_to<ComplexType>, std::allocator<ComplexType>>>::value); + + // check TSet(InputIterator,InputIterator, size_t, Hasher, Allocator) + TSet s6(v.begin(), v.end(), 5, std::hash<ComplexType>(), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(s6), TSet<ComplexType, std::hash<ComplexType>, + std::equal_to<ComplexType>, std::allocator<ComplexType>>>::value); + + // check TSet(std::initializer_list) + TSet s7(l); + static_assert(std::is_same<decltype(s7), TSet<ComplexType>>::value); + + // check TSet(std::initializer_list, size_t, Hasher) + TSet s8(l, 5, std::hash<ComplexType>()); + static_assert(std::is_same<decltype(s8), TSet<ComplexType, std::hash<ComplexType>>>::value); + + // check TSet(std::initializer_list, size_t, Hasher, Equality) + TSet s9(l, 5, std::hash<ComplexType>(), std::less<ComplexType>()); + static_assert(std::is_same<decltype(s9), TSet<ComplexType, std::hash<ComplexType>, + std::less<ComplexType>>>::value); + + // check TSet(std::initializer_list, size_t, Hasher, Equality, Allocator) + TSet s10(l, 5, std::hash<ComplexType>(), std::less<ComplexType>(), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(s10), TSet<ComplexType, std::hash<ComplexType>, + std::less<ComplexType>, std::allocator<ComplexType>>>::value); + + // check TSet(std::initializer_list, size_t, Allocator) + TSet s11(l, 5, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(s11), TSet<ComplexType, tbb::tbb_hash<ComplexType>, + std::equal_to<ComplexType>, std::allocator<ComplexType>>>::value); + + // check TSet(std::initializer_list, size_t, Hasher, Allocator) + TSet s12(l, 5, std::hash<ComplexType>(), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(s12), TSet<ComplexType, std::hash<ComplexType>, + std::equal_to<ComplexType>, std::allocator<ComplexType>>>::value); + + // check TSet(TSet &) + TSet s13(s1); + static_assert(std::is_same<decltype(s13), decltype(s1)>::value); + + // check TSet(TSet &, Allocator) + TSet s14(s5, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(s14), decltype(s5)>::value); + + // check TSet(TSet &&) + TSet s15(std::move(s1)); + static_assert(std::is_same<decltype(s15), decltype(s1)>::value); + + // check TSet(TSet &&, Allocator) + TSet s16(std::move(s5), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(s16), decltype(s5)>::value); +} +#endif + +#if !__TBB_TEST_SECONDARY +#define INITIALIZATION_TIME_TEST_NAMESPACE initialization_time_test +#define TEST_INITIALIZATION_TIME_OPERATIONS_NAME test_initialization_time_operations +void test_initialization_time_operations_external(); +#else +#define INITIALIZATION_TIME_TEST_NAMESPACE initialization_time_test_external +#define TEST_INITIALIZATION_TIME_OPERATIONS_NAME test_initialization_time_operations_external +#endif + +namespace INITIALIZATION_TIME_TEST_NAMESPACE { + tbb::concurrent_unordered_set<int> static_init_time_set; + int any_non_zero_value = 89432; + bool static_init_time_inserted = (static_init_time_set.insert( any_non_zero_value )).second; + bool static_init_time_found = ((static_init_time_set.find( any_non_zero_value )) != static_init_time_set.end( )); +} +void TEST_INITIALIZATION_TIME_OPERATIONS_NAME( ) { + using namespace INITIALIZATION_TIME_TEST_NAMESPACE; +#define LOCATION ",in function: " __TBB_STRING(TEST_INITIALIZATION_TIME_OPERATIONS_NAME) + ASSERT( static_init_time_inserted, "failed to insert an item during initialization of global objects" LOCATION ); + ASSERT( static_init_time_found, "failed to find an item during initialization of global objects" LOCATION ); + + bool static_init_time_found_in_main = ((static_init_time_set.find( any_non_zero_value )) != static_init_time_set.end( )); + ASSERT( static_init_time_found_in_main, "failed to find during main() an item inserted during initialization of global objects" LOCATION ); +#undef LOCATION +} + +#if !__TBB_TEST_SECONDARY +int TestMain() { + test_machine( ); + + test_basic<MySet>( "concurrent unordered Set" ); + test_basic<MyDegenerateSet>( "concurrent unordered degenerate Set" ); + test_concurrent<MySet>("concurrent unordered Set"); + test_concurrent<MyDegenerateSet>( "concurrent unordered degenerate Set" ); + test_basic<MyMultiSet>("concurrent unordered MultiSet"); + test_basic<MyDegenerateMultiSet>("concurrent unordered degenerate MultiSet"); + test_concurrent<MyMultiSet>( "concurrent unordered MultiSet" ); + test_concurrent<MyDegenerateMultiSet>("concurrent unordered degenerate MultiSet"); + test_concurrent<MyMultiSet>( "concurrent unordered MultiSet asymptotic", true ); + + { Check<MyCheckedSet::value_type> checkit; test_basic<MyCheckedSet>( "concurrent_unordered_set (checked)" ); } + { Check<MyCheckedSet::value_type> checkit; test_concurrent<MyCheckedSet>( "concurrent unordered set (checked)" ); } + test_basic<MyCheckedStateSet>("concurrent unordered set (checked element state)", tbb::internal::true_type()); + test_concurrent<MyCheckedStateSet>("concurrent unordered set (checked element state)"); + + { Check<MyCheckedMultiSet::value_type> checkit; test_basic<MyCheckedMultiSet>("concurrent_unordered_multiset (checked)"); } + { Check<MyCheckedMultiSet::value_type> checkit; test_concurrent<MyCheckedMultiSet>( "concurrent unordered multiset (checked)" ); } + + test_initialization_time_operations( ); +#if !__TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN + test_initialization_time_operations_external( ); +#else + REPORT( "Known issue: global objects initialization time tests skipped.\n" ); +#endif //!__TBB_CPP11_STD_PLACEHOLDERS_LINKING_BROKEN + +#if __TBB_INITIALIZER_LISTS_PRESENT + TestInitList< tbb::concurrent_unordered_set<int>, + tbb::concurrent_unordered_multiset<int> >( {1,2,3,4,5} ); +#endif + +#if __TBB_RANGE_BASED_FOR_PRESENT + TestRangeBasedFor<MySet>(); + TestRangeBasedFor<MyMultiSet>(); +#endif + +#if __TBB_CPP11_RVALUE_REF_PRESENT + test_rvalue_ref_support<cu_set_type>( "concurrent unordered set" ); + test_rvalue_ref_support<cu_multiset_type>( "concurrent unordered multiset" ); +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + + TestTypes(); + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides<tbb::concurrent_unordered_set>(); + TestDeductionGuides<tbb::concurrent_unordered_multiset>(); +#endif + +#if __TBB_UNORDERED_NODE_HANDLE_PRESENT + node_handling::TestNodeHandling<MySet>(); + node_handling::TestNodeHandling<MyMultiSet>(); + node_handling::TestMerge<MySet, MyMultiSet>(10000); + node_handling::TestMerge<MySet, MyDegenerateSet>(10000); +#endif /*__TBB_UNORDERED_NODE_HANDLE_PRESENT*/ + + return Harness::Done; +} +#endif //#if !__TBB_TEST_SECONDARY +#endif //!(__TBB_TEST_SECONDARY && __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_vector.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_vector.cpp new file mode 100644 index 00000000..3671f855 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_concurrent_vector.cpp @@ -0,0 +1,1874 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _MSC_VER +#define _SCL_SECURE_NO_WARNINGS +#endif + +#include "tbb/concurrent_vector.h" +#include "tbb/tbb_allocator.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/tbb_exception.h" +#include <cstdio> +#include <cstdlib> +#include <functional> +#include <vector> +#include <numeric> +#include "harness_report.h" +#include "harness_assert.h" +#include "harness_allocator.h" +#include "harness_defs.h" +#include "test_container_move_support.h" + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (push) + #pragma warning (disable: 4800) +#endif + +#if TBB_USE_EXCEPTIONS +static bool known_issue_verbose = false; +#define KNOWN_ISSUE(msg) if(!known_issue_verbose) known_issue_verbose = true, REPORT(msg) +#endif /* TBB_USE_EXCEPTIONS */ + +inline void NextSize( int& s ) { + if( s<=32 ) ++s; + else s += s/10; +} + +//! Check vector have expected size and filling +template<typename vector_t> +static void CheckVector( const vector_t& cv, size_t expected_size, size_t old_size ) { + ASSERT( cv.capacity()>=expected_size, NULL ); + ASSERT( cv.size()==expected_size, NULL ); + ASSERT( cv.empty()==(expected_size==0), NULL ); + for( int j=0; j<int(expected_size); ++j ) { + if( cv[j].bar()!=~j ) + REPORT("ERROR on line %d for old_size=%ld expected_size=%ld j=%d\n",__LINE__,long(old_size),long(expected_size),j); + } +} + +//! Test of assign, grow, copying with various sizes +void TestResizeAndCopy() { + typedef static_counting_allocator<debug_allocator<Foo,std::allocator>, std::size_t> allocator_t; + typedef tbb::concurrent_vector<Foo, allocator_t> vector_t; + allocator_t::init_counters(); + for( int old_size=0; old_size<=128; NextSize( old_size ) ) { + for( int new_size=0; new_size<=1280; NextSize( new_size ) ) { + size_t count = FooCount; + vector_t v; + ASSERT( count==FooCount, NULL ); + v.assign(old_size/2, Foo() ); + ASSERT( count+old_size/2==FooCount, NULL ); + for( int j=0; j<old_size/2; ++j ) + ASSERT( v[j].state == Foo::CopyInitialized, NULL); + v.assign(FooIterator(0), FooIterator(old_size)); + v.resize(new_size, Foo(33) ); + ASSERT( count+new_size==FooCount, NULL ); + for( int j=0; j<new_size; ++j ) { + int expected = j<old_size ? j : 33; + if( v[j].bar()!=expected ) + REPORT("ERROR on line %d for old_size=%ld new_size=%ld v[%ld].bar()=%d != %d\n",__LINE__,long(old_size),long(new_size),long(j),v[j].bar(), expected); + } + ASSERT( v.size()==size_t(new_size), NULL ); + for( int j=0; j<new_size; ++j ) { + v[j].bar() = ~j; + } + const vector_t& cv = v; + // Try copy constructor + vector_t copy_of_v(cv); + CheckVector(cv,new_size,old_size); + ASSERT( !(v != copy_of_v), NULL ); + v.clear(); + ASSERT( v.empty(), NULL ); + swap(v, copy_of_v); + ASSERT( copy_of_v.empty(), NULL ); + CheckVector(v,new_size,old_size); + } + } + ASSERT( allocator_t::items_allocated == allocator_t::items_freed, NULL); + ASSERT( allocator_t::allocations == allocator_t::frees, NULL); +} + +//! Test reserve, compact, capacity +void TestCapacity() { + typedef static_counting_allocator<debug_allocator<Foo,tbb::cache_aligned_allocator>, std::size_t> allocator_t; + typedef tbb::concurrent_vector<Foo, allocator_t> vector_t; + allocator_t::init_counters(); + for( size_t old_size=0; old_size<=11000; old_size=(old_size<5 ? old_size+1 : 3*old_size) ) { + for( size_t new_size=0; new_size<=11000; new_size=(new_size<5 ? new_size+1 : 3*new_size) ) { + size_t count = FooCount; + { + vector_t v; v.reserve(old_size); + ASSERT( v.capacity()>=old_size, NULL ); + v.reserve( new_size ); + ASSERT( v.capacity()>=old_size, NULL ); + ASSERT( v.capacity()>=new_size, NULL ); + ASSERT( v.empty(), NULL ); + size_t fill_size = 2*new_size; + for( size_t i=0; i<fill_size; ++i ) { + ASSERT( size_t(FooCount)==count+i, NULL ); + size_t j = v.grow_by(1) - v.begin(); + ASSERT( j==i, NULL ); + v[j].bar() = int(~j); + } + vector_t copy_of_v(v); // should allocate first segment with same size as for shrink_to_fit() + if(__TBB_Log2(/*reserved size*/old_size|1) > __TBB_Log2(fill_size|1) ) + ASSERT( v.capacity() != copy_of_v.capacity(), NULL ); + v.shrink_to_fit(); + ASSERT( v.capacity() == copy_of_v.capacity(), NULL ); + CheckVector(v, new_size*2, old_size); // check vector correctness + ASSERT( v==copy_of_v, NULL ); // TODO: check also segments layout equality + } + ASSERT( FooCount==count, NULL ); + } + } + ASSERT( allocator_t::items_allocated == allocator_t::items_freed, NULL); + ASSERT( allocator_t::allocations == allocator_t::frees, NULL); +} + +struct AssignElement { + typedef tbb::concurrent_vector<int>::range_type::iterator iterator; + iterator base; + void operator()( const tbb::concurrent_vector<int>::range_type& range ) const { + for( iterator i=range.begin(); i!=range.end(); ++i ) { + if( *i!=0 ) + REPORT("ERROR for v[%ld]\n", long(i-base)); + *i = int(i-base); + } + } + AssignElement( iterator base_ ) : base(base_) {} +}; + +struct CheckElement { + typedef tbb::concurrent_vector<int>::const_range_type::iterator iterator; + iterator base; + void operator()( const tbb::concurrent_vector<int>::const_range_type& range ) const { + for( iterator i=range.begin(); i!=range.end(); ++i ) + if( *i != int(i-base) ) + REPORT("ERROR for v[%ld]\n", long(i-base)); + } + CheckElement( iterator base_ ) : base(base_) {} +}; + +#include "tbb/tick_count.h" +#include "tbb/parallel_for.h" +#include "harness.h" + +//! Problem size +const size_t N = 500000; + +//! Test parallel access by iterators +void TestParallelFor( int nthread ) { + typedef tbb::concurrent_vector<int> vector_t; + vector_t v; + v.resize(N); + tbb::tick_count t0 = tbb::tick_count::now(); + REMARK("Calling parallel_for with %ld threads\n",long(nthread)); + tbb::parallel_for( v.range(10000), AssignElement(v.begin()) ); + tbb::tick_count t1 = tbb::tick_count::now(); + const vector_t& u = v; + tbb::parallel_for( u.range(10000), CheckElement(u.begin()) ); + tbb::tick_count t2 = tbb::tick_count::now(); + REMARK("Time for parallel_for: assign time = %8.5f, check time = %8.5f\n", + (t1-t0).seconds(),(t2-t1).seconds()); + for( long i=0; size_t(i)<v.size(); ++i ) + if( v[i]!=i ) + REPORT("ERROR for v[%ld]\n", i); +} + +template<typename Iterator1, typename Iterator2> +void TestIteratorAssignment( Iterator2 j ) { + Iterator1 i(j); + ASSERT( i==j, NULL ); + ASSERT( !(i!=j), NULL ); + Iterator1 k; + k = j; + ASSERT( k==j, NULL ); + ASSERT( !(k!=j), NULL ); +} + +template<typename Range1, typename Range2> +void TestRangeAssignment( Range2 r2 ) { + Range1 r1(r2); r1 = r2; +} + +template<typename Iterator, typename T> +void TestIteratorTraits() { + AssertSameType( static_cast<typename Iterator::difference_type*>(0), static_cast<ptrdiff_t*>(0) ); + AssertSameType( static_cast<typename Iterator::value_type*>(0), static_cast<T*>(0) ); + AssertSameType( static_cast<typename Iterator::pointer*>(0), static_cast<T**>(0) ); + AssertSameType( static_cast<typename Iterator::iterator_category*>(0), static_cast<std::random_access_iterator_tag*>(0) ); + T x; + typename Iterator::reference xr = x; + typename Iterator::pointer xp = &x; + ASSERT( &xr==xp, NULL ); +} + +template<typename Vector, typename Iterator> +void CheckConstIterator( const Vector& u, int i, const Iterator& cp ) { + typename Vector::const_reference pref = *cp; + if( pref.bar()!=i ) + REPORT("ERROR for u[%ld] using const_iterator\n", long(i)); + typename Vector::difference_type delta = cp-u.begin(); + ASSERT( delta==i, NULL ); + if( u[i].bar()!=i ) + REPORT("ERROR for u[%ld] using subscripting\n", long(i)); + ASSERT( u.begin()[i].bar()==i, NULL ); +} + +template<typename Iterator1, typename Iterator2, typename V> +void CheckIteratorComparison( V& u ) { + V u2 = u; + Iterator1 i = u.begin(); + + for( int i_count=0; i_count<100; ++i_count ) { + Iterator2 j = u.begin(); + Iterator2 i2 = u2.begin(); + for( int j_count=0; j_count<100; ++j_count ) { + ASSERT( (i==j)==(i_count==j_count), NULL ); + ASSERT( (i!=j)==(i_count!=j_count), NULL ); + ASSERT( (i-j)==(i_count-j_count), NULL ); + ASSERT( (i<j)==(i_count<j_count), NULL ); + ASSERT( (i>j)==(i_count>j_count), NULL ); + ASSERT( (i<=j)==(i_count<=j_count), NULL ); + ASSERT( (i>=j)==(i_count>=j_count), NULL ); + ASSERT( !(i==i2), NULL ); + ASSERT( i!=i2, NULL ); + ++j; + ++i2; + } + ++i; + } +} + +template<typename Vector, typename T> +void TestGrowToAtLeastWithSourceParameter(T const& src){ + static const size_t vector_size = 10; + Vector v1(vector_size,src); + Vector v2; + v2.grow_to_at_least(vector_size,src); + ASSERT(v1==v2,"grow_to_at_least(vector_size,src) did not properly initialize new elements ?"); +} +//! Test sequential iterators for vector type V. +/** Also does timing. */ +template<typename T> +void TestSequentialFor() { + typedef tbb::concurrent_vector<FooWithAssign> V; + V v(N); + ASSERT(v.grow_by(0) == v.grow_by(0, FooWithAssign()), NULL); + + // Check iterator + tbb::tick_count t0 = tbb::tick_count::now(); + typename V::iterator p = v.begin(); + ASSERT( !(*p).is_const(), NULL ); + ASSERT( !p->is_const(), NULL ); + for( int i=0; size_t(i)<v.size(); ++i, ++p ) { + if( (*p).state!=Foo::DefaultInitialized ) + REPORT("ERROR for v[%ld]\n", long(i)); + typename V::reference pref = *p; + pref.bar() = i; + typename V::difference_type delta = p-v.begin(); + ASSERT( delta==i, NULL ); + ASSERT( -delta<=0, "difference type not signed?" ); + } + tbb::tick_count t1 = tbb::tick_count::now(); + + // Check const_iterator going forwards + const V& u = v; + typename V::const_iterator cp = u.begin(); + ASSERT( cp == v.cbegin(), NULL ); + ASSERT( (*cp).is_const(), NULL ); + ASSERT( cp->is_const(), NULL ); + ASSERT( *cp == v.front(), NULL); + for( int i=0; size_t(i)<u.size(); ++i ) { + CheckConstIterator(u,i,cp); + V::const_iterator &cpr = ++cp; + ASSERT( &cpr == &cp, "pre-increment not returning a reference?"); + } + tbb::tick_count t2 = tbb::tick_count::now(); + REMARK("Time for serial for: assign time = %8.5f, check time = %8.5f\n", + (t1-t0).seconds(),(t2-t1).seconds()); + + // Now go backwards + cp = u.end(); + ASSERT( cp == v.cend(), NULL ); + for( int i=int(u.size()); i>0; ) { + --i; + V::const_iterator &cpr = --cp; + ASSERT( &cpr == &cp, "pre-decrement not returning a reference?"); + if( i>0 ) { + typename V::const_iterator cp_old = cp--; + intptr_t here = (*cp_old).bar(); + ASSERT( here==u[i].bar(), NULL ); + typename V::const_iterator cp_new = cp++; + intptr_t prev = (*cp_new).bar(); + ASSERT( prev==u[i-1].bar(), NULL ); + } + CheckConstIterator(u,i,cp); + } + + // Now go forwards and backwards + ptrdiff_t k = 0; + cp = u.begin(); + for( size_t i=0; i<u.size(); ++i ) { + CheckConstIterator(u,int(k),cp); + typename V::difference_type delta = i*3 % u.size(); + if( 0<=k+delta && size_t(k+delta)<u.size() ) { + V::const_iterator &cpr = (cp += delta); + ASSERT( &cpr == &cp, "+= not returning a reference?"); + k += delta; + } + delta = i*7 % u.size(); + if( 0<=k-delta && size_t(k-delta)<u.size() ) { + if( i&1 ) { + V::const_iterator &cpr = (cp -= delta); + ASSERT( &cpr == &cp, "-= not returning a reference?"); + } else + cp = cp - delta; // Test operator- + k -= delta; + } + } + + for( int i=0; size_t(i)<u.size(); i=(i<50?i+1:i*3) ) + for( int j=-i; size_t(i+j)<u.size(); j=(j<50?j+1:j*5) ) { + ASSERT( (u.begin()+i)[j].bar()==i+j, NULL ); + ASSERT( (v.begin()+i)[j].bar()==i+j, NULL ); + ASSERT((v.cbegin()+i)[j].bar()==i+j, NULL ); + ASSERT( (i+u.begin())[j].bar()==i+j, NULL ); + ASSERT( (i+v.begin())[j].bar()==i+j, NULL ); + ASSERT((i+v.cbegin())[j].bar()==i+j, NULL ); + } + + CheckIteratorComparison<typename V::iterator, typename V::iterator>(v); + CheckIteratorComparison<typename V::iterator, typename V::const_iterator>(v); + CheckIteratorComparison<typename V::const_iterator, typename V::iterator>(v); + CheckIteratorComparison<typename V::const_iterator, typename V::const_iterator>(v); + + TestIteratorAssignment<typename V::const_iterator>( u.begin() ); + TestIteratorAssignment<typename V::const_iterator>( v.begin() ); + TestIteratorAssignment<typename V::const_iterator>( v.cbegin() ); + TestIteratorAssignment<typename V::iterator>( v.begin() ); + // doesn't compile as expected: TestIteratorAssignment<typename V::iterator>( u.begin() ); + + TestRangeAssignment<typename V::const_range_type>( u.range() ); + TestRangeAssignment<typename V::const_range_type>( v.range() ); + TestRangeAssignment<typename V::range_type>( v.range() ); + // doesn't compile as expected: TestRangeAssignment<typename V::range_type>( u.range() ); + + // Check reverse_iterator + typename V::reverse_iterator rp = v.rbegin(); + for( size_t i=v.size(); i>0; --i, ++rp ) { + typename V::reference pref = *rp; + ASSERT( size_t(pref.bar())==i-1, NULL ); + ASSERT( rp!=v.rend(), NULL ); + } + ASSERT( rp==v.rend(), NULL ); + + // Check const_reverse_iterator + typename V::const_reverse_iterator crp = u.rbegin(); + ASSERT( crp == v.crbegin(), NULL ); + ASSERT( *crp == v.back(), NULL); + for( size_t i=v.size(); i>0; --i, ++crp ) { + typename V::const_reference cpref = *crp; + ASSERT( size_t(cpref.bar())==i-1, NULL ); + ASSERT( crp!=u.rend(), NULL ); + } + ASSERT( crp == u.rend(), NULL ); + ASSERT( crp == v.crend(), NULL ); + + TestIteratorAssignment<typename V::const_reverse_iterator>( u.rbegin() ); + TestIteratorAssignment<typename V::reverse_iterator>( v.rbegin() ); + + // test compliance with C++ Standard 2003, clause 23.1.1p9 + { + tbb::concurrent_vector<int> v1, v2(1, 100); + v1.assign(1, 100); ASSERT(v1 == v2, NULL); + ASSERT(v1.size() == 1 && v1[0] == 100, "used integral iterators"); + } + + // cross-allocator tests +#if !defined(_WIN64) || defined(_CPPLIB_VER) + typedef local_counting_allocator<std::allocator<int>, size_t> allocator1_t; + typedef tbb::cache_aligned_allocator<int> allocator2_t; + typedef tbb::concurrent_vector<FooWithAssign, allocator1_t> V1; + typedef tbb::concurrent_vector<FooWithAssign, allocator2_t> V2; + V1 v1( v ); // checking cross-allocator copying + V2 v2( 10 ); v2 = v1; // checking cross-allocator assignment + ASSERT( (v1 == v) && !(v2 != v), NULL); + ASSERT( !(v1 < v) && !(v2 > v), NULL); + ASSERT( (v1 <= v) && (v2 >= v), NULL); +#endif +} + +namespace test_grow_to_at_least_helpers { + template<typename MyVector > + class GrowToAtLeast: NoAssign { + typedef typename MyVector::const_reference const_reference; + + const bool my_use_two_args_form ; + MyVector& my_vector; + const_reference my_init_from; + public: + void operator()( const tbb::blocked_range<size_t>& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + size_t n = my_vector.size(); + size_t req = (i % (2*n+1))+1; + + typename MyVector::iterator p; + Foo::State desired_state; + if (my_use_two_args_form){ + p = my_vector.grow_to_at_least(req,my_init_from); + desired_state = Foo::CopyInitialized; + }else{ + p = my_vector.grow_to_at_least(req); + desired_state = Foo::DefaultInitialized; + } + if( p-my_vector.begin() < typename MyVector::difference_type(req) ) + ASSERT( p->state == desired_state || p->state == Foo::ZeroInitialized, NULL ); + ASSERT( my_vector.size()>=req, NULL ); + } + } + GrowToAtLeast(bool use_two_args_form, MyVector& vector, const_reference init_from ) + : my_use_two_args_form(use_two_args_form), my_vector(vector), my_init_from(init_from) {} + }; +} + +template<bool use_two_arg_form> +void TestConcurrentGrowToAtLeastImpl() { + using namespace test_grow_to_at_least_helpers; + typedef static_counting_allocator< tbb::zero_allocator<Foo> > MyAllocator; + typedef tbb::concurrent_vector<Foo, MyAllocator> MyVector; + Foo copy_from; + MyAllocator::init_counters(); + MyVector v(2, Foo(), MyAllocator()); + for( size_t s=1; s<1000; s*=10 ) { + tbb::parallel_for( tbb::blocked_range<size_t>(0,10000*s,s), GrowToAtLeast<MyVector>(use_two_arg_form, v, copy_from), tbb::simple_partitioner() ); + } + v.clear(); + ASSERT( 0 == v.get_allocator().frees, NULL); + v.shrink_to_fit(); + size_t items_allocated = v.get_allocator().items_allocated, + items_freed = v.get_allocator().items_freed; + size_t allocations = v.get_allocator().allocations, + frees = v.get_allocator().frees; + ASSERT( items_allocated == items_freed, NULL); + ASSERT( allocations == frees, NULL); +} + +void TestConcurrentGrowToAtLeast() { + TestConcurrentGrowToAtLeastImpl<false>(); + TestConcurrentGrowToAtLeastImpl<true>(); +} + +struct grain_map: NoAssign { + enum grow_method_enum { + grow_by_range = 1, + grow_by_default, + grow_by_copy, + grow_by_init_list, + push_back, + push_back_move, + emplace_back, + last_method + }; + + struct range_part { + size_t number_of_parts; + grain_map::grow_method_enum method; + bool distribute; + Foo::State expected_element_state; + }; + + const std::vector<range_part> distributed; + const std::vector<range_part> batched; + const size_t total_number_of_parts; + + grain_map(const range_part* begin, const range_part* end) + : distributed(separate(begin,end, &distributed::is_not)) + , batched(separate(begin,end, &distributed::is_yes)) + , total_number_of_parts(std::accumulate(begin, end, (size_t)0, &sum_number_of_parts::sum)) + {} + +private: + struct sum_number_of_parts{ + static size_t sum(size_t accumulator, grain_map::range_part const& rp){ return accumulator + rp.number_of_parts;} + }; + + template <typename functor_t> + static std::vector<range_part> separate(const range_part* begin, const range_part* end, functor_t f){ + std::vector<range_part> part; + part.reserve(std::distance(begin,end)); + //copy all that false==f(*it) + std::remove_copy_if(begin, end, std::back_inserter(part), f); + + return part; + } + + struct distributed { + static bool is_not(range_part const& rp){ return !rp.distribute;} + static bool is_yes(range_part const& rp){ return rp.distribute;} + }; +}; + +//! Test concurrent invocations of method concurrent_vector::grow_by +template<typename MyVector> +class GrowBy: NoAssign { + MyVector& my_vector; + const grain_map& my_grain_map; + size_t my_part_weight; +public: + void operator()( const tbb::blocked_range<size_t>& range ) const { + ASSERT( range.begin() < range.end(), NULL ); + + size_t current_adding_index_in_cvector = range.begin(); + + for(size_t index=0; index < my_grain_map.batched.size(); ++index){ + const grain_map::range_part& batch_part = my_grain_map.batched[index]; + const size_t number_of_items_to_add = batch_part.number_of_parts * my_part_weight; + const size_t end = current_adding_index_in_cvector + number_of_items_to_add; + + switch(batch_part.method){ + case grain_map::grow_by_range : { + my_vector.grow_by(FooIterator(current_adding_index_in_cvector),FooIterator(end)); + } break; + case grain_map::grow_by_default : { + typename MyVector::iterator const s = my_vector.grow_by(number_of_items_to_add); + for( size_t k = 0; k < number_of_items_to_add; ++k ) + s[k].bar() = current_adding_index_in_cvector + k; + } break; +#if __TBB_INITIALIZER_LISTS_PRESENT + case grain_map::grow_by_init_list : { + FooIterator curr(current_adding_index_in_cvector); + for ( size_t k = 0; k < number_of_items_to_add; ++k ) { + if ( k + 4 < number_of_items_to_add ) { + my_vector.grow_by( { *curr++, *curr++, *curr++, *curr++, *curr++ } ); + k += 4; + } else { + my_vector.grow_by( { *curr++ } ); + } + } + ASSERT( curr == FooIterator(end), NULL ); + } break; +#endif + default : { ASSERT(false, "using unimplemented method of batch add in ConcurrentGrow test.");} break; + }; + + current_adding_index_in_cvector = end; + } + + std::vector<size_t> items_left_to_add(my_grain_map.distributed.size()); + for (size_t i=0; i<my_grain_map.distributed.size(); ++i ){ + items_left_to_add[i] = my_grain_map.distributed[i].number_of_parts * my_part_weight; + } + + for (;current_adding_index_in_cvector < range.end(); ++current_adding_index_in_cvector){ + size_t method_index = current_adding_index_in_cvector % my_grain_map.distributed.size(); + + if (! items_left_to_add[method_index]) { + struct not_zero{ + static bool is(size_t items_to_add){ return items_to_add;} + }; + method_index = std::distance(items_left_to_add.begin(), std::find_if(items_left_to_add.begin(), items_left_to_add.end(), ¬_zero::is)); + ASSERT(method_index < my_grain_map.distributed.size(), "incorrect test setup - wrong expected distribution: left free space but no elements to add?"); + }; + + ASSERT(items_left_to_add[method_index], "logic error ?"); + const grain_map::range_part& distributed_part = my_grain_map.distributed[method_index]; + + typename MyVector::iterator r; + typename MyVector::value_type source; + source.bar() = current_adding_index_in_cvector; + + switch(distributed_part.method){ + case grain_map::grow_by_default : { + (r = my_vector.grow_by(1))->bar() = current_adding_index_in_cvector; + } break; + case grain_map::grow_by_copy : { + r = my_vector.grow_by(1, source); + } break; + case grain_map::push_back : { + r = my_vector.push_back(source); + } break; +#if __TBB_CPP11_RVALUE_REF_PRESENT + case grain_map::push_back_move : { + r = my_vector.push_back(std::move(source)); + } break; +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + case grain_map::emplace_back : { + r = my_vector.emplace_back(current_adding_index_in_cvector); + } break; +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + + default : { ASSERT(false, "using unimplemented method of batch add in ConcurrentGrow test.");} break; + }; + + ASSERT( static_cast<size_t>(r->bar()) == current_adding_index_in_cvector, NULL ); + } + } + + GrowBy( MyVector& vector, const grain_map& m, size_t part_weight ) + : my_vector(vector) + , my_grain_map(m) + , my_part_weight(part_weight) + { + } +}; + +const grain_map::range_part concurrent_grow_single_range_map [] = { +// number_of_parts, method, distribute, expected_element_state + {3, grain_map::grow_by_range, false, + #if __TBB_CPP11_RVALUE_REF_PRESENT + Foo::MoveInitialized + #else + Foo::CopyInitialized + #endif + }, +#if __TBB_INITIALIZER_LISTS_PRESENT && !__TBB_CPP11_INIT_LIST_TEMP_OBJS_LIFETIME_BROKEN + {1, grain_map::grow_by_init_list, false, Foo::CopyInitialized}, +#endif + {2, grain_map::grow_by_default, false, Foo::DefaultInitialized}, + {1, grain_map::grow_by_default, true, Foo::DefaultInitialized}, + {1, grain_map::grow_by_copy, true, Foo::CopyInitialized}, + {1, grain_map::push_back, true, Foo::CopyInitialized}, +#if __TBB_CPP11_RVALUE_REF_PRESENT + {1, grain_map::push_back_move, true, Foo::MoveInitialized}, +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + {1, grain_map::emplace_back, true, Foo::DirectInitialized}, +#endif // __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT +}; + +//! Test concurrent invocations of grow methods +void TestConcurrentGrowBy( int nthread ) { + + typedef static_counting_allocator<debug_allocator<Foo> > MyAllocator; + typedef tbb::concurrent_vector<Foo, MyAllocator> MyVector; + +#if __TBB_INITIALIZER_LISTS_PRESENT && __TBB_CPP11_INIT_LIST_TEMP_OBJS_LIFETIME_BROKEN + static bool is_reported = false; + if ( !is_reported ) { + REPORT( "Known issue: concurrent tests of grow_by(std::initializer_list) are skipped.\n" ); + is_reported = true; + } +#endif + + MyAllocator::init_counters(); + { + grain_map m(concurrent_grow_single_range_map, Harness::end(concurrent_grow_single_range_map)); + + static const size_t desired_grain_size = 100; + + static const size_t part_weight = desired_grain_size / m.total_number_of_parts; + static const size_t grain_size = part_weight * m.total_number_of_parts; + static const size_t number_of_grains = 8; //this should be (power of two) in order to get minimal ranges equal to grain_size + static const size_t range_size = grain_size * number_of_grains; + + MyAllocator a; + MyVector v( a ); + tbb::parallel_for( tbb::blocked_range<size_t>(0,range_size,grain_size), GrowBy<MyVector>(v, m, part_weight), tbb::simple_partitioner() ); + ASSERT( v.size()==size_t(range_size), NULL ); + + // Verify that v is a permutation of 0..m + size_t inversions = 0, direct_inits = 0, def_inits = 0, copy_inits = 0, move_inits = 0; + std::vector<bool> found(range_size, 0); + for( size_t i=0; i<range_size; ++i ) { + if( v[i].state == Foo::DefaultInitialized ) ++def_inits; + else if( v[i].state == Foo::DirectInitialized ) ++direct_inits; + else if( v[i].state == Foo::CopyInitialized ) ++copy_inits; + else if( v[i].state == Foo::MoveInitialized ) ++move_inits; + else { + REMARK("i: %d ", i); + ASSERT( false, "v[i] seems not initialized"); + } + intptr_t index = v[i].bar(); + ASSERT( !found[index], NULL ); + found[index] = true; + if( i>0 ) + inversions += v[i].bar()<v[i-1].bar(); + } + for( size_t i=0; i<range_size; ++i ) { + ASSERT( found[i], NULL ); + ASSERT( nthread>1 || v[i].bar() == static_cast<intptr_t>(i), "sequential execution is wrong" ); + } + + REMARK("Initialization by default constructor: %d, by copy: %d, by move: %d\n", def_inits, copy_inits, move_inits); + + size_t expected_direct_inits = 0, expected_def_inits = 0, expected_copy_inits = 0, expected_move_inits = 0; + for (size_t i=0; i<Harness::array_length(concurrent_grow_single_range_map); ++i){ + const grain_map::range_part& rp =concurrent_grow_single_range_map[i]; + switch (rp.expected_element_state){ + case Foo::DefaultInitialized: { expected_def_inits += rp.number_of_parts ; } break; + case Foo::DirectInitialized: { expected_direct_inits += rp.number_of_parts ;} break; + case Foo::MoveInitialized: { expected_move_inits += rp.number_of_parts ;} break; + case Foo::CopyInitialized: { expected_copy_inits += rp.number_of_parts ;} break; + default: {ASSERT(false, "unexpected expected state");}break; + }; + } + + expected_def_inits *= part_weight * number_of_grains; + expected_move_inits *= part_weight * number_of_grains; + expected_copy_inits *= part_weight * number_of_grains; + expected_direct_inits *= part_weight * number_of_grains; + + ASSERT( def_inits == expected_def_inits , NULL); + ASSERT( copy_inits == expected_copy_inits , NULL); + ASSERT( move_inits == expected_move_inits , NULL); + ASSERT( direct_inits == expected_direct_inits , NULL); + + if( nthread>1 && inversions<range_size/20 ) + REPORT("Warning: not much concurrency in TestConcurrentGrowBy (%d inversions)\n", inversions); + } + //TODO: factor this into separate thing, as it seems to used in big number of tests + size_t items_allocated = MyAllocator::items_allocated, + items_freed = MyAllocator::items_freed; + size_t allocations = MyAllocator::allocations, + frees = MyAllocator::frees; + ASSERT( items_allocated == items_freed, NULL); + ASSERT( allocations == frees, NULL); +} + +template <typename Vector> +void test_grow_by_empty_range( Vector &v, typename Vector::value_type* range_begin_end ) { + const Vector v_copy = v; + ASSERT( v.grow_by( range_begin_end, range_begin_end ) == v.end(), "grow_by(empty_range) returned a wrong iterator." ); + ASSERT( v == v_copy, "grow_by(empty_range) has changed the vector." ); +} + +void TestSerialGrowByRange( bool fragmented_vector ) { + tbb::concurrent_vector<int> v; + if ( fragmented_vector ) { + v.reserve( 1 ); + } + int init_range[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + ASSERT( v.grow_by( init_range, init_range + (Harness::array_length( init_range )) ) == v.begin(), "grow_by(I,I) returned a wrong iterator." ); + ASSERT( std::equal( v.begin(), v.end(), init_range ), "grow_by(I,I) did not properly copied all elements ?" ); + test_grow_by_empty_range( v, init_range ); + test_grow_by_empty_range( v, (int*)NULL ); +} + +//TODO: move this to more appropriate place, smth like test_harness.cpp +void TestArrayLength(){ + int five_element_array[5] = {0}; + ASSERT(Harness::array_length(five_element_array)==5,"array_length failed to determine length of non empty non dynamic array"); +} + +#if __TBB_INITIALIZER_LISTS_PRESENT +#include "test_initializer_list.h" + +struct test_grow_by { + template<typename container_type, typename element_type> + static void do_test( std::initializer_list<element_type> const& il, container_type const& expected ) { + container_type vd; + vd.grow_by( il ); + ASSERT( vd == expected, "grow_by with an initializer list failed" ); + } +}; + +void TestInitList() { + REMARK( "testing initializer_list methods \n" ); + using namespace initializer_list_support_tests; + TestInitListSupport<tbb::concurrent_vector<char>, test_grow_by>( { 1, 2, 3, 4, 5 } ); + TestInitListSupport<tbb::concurrent_vector<int>, test_grow_by>( {} ); +} +#endif //if __TBB_INITIALIZER_LISTS_PRESENT + +#if __TBB_RANGE_BASED_FOR_PRESENT +#include "test_range_based_for.h" + +void TestRangeBasedFor(){ + using namespace range_based_for_support_tests; + + REMARK("testing range based for loop compatibility \n"); + typedef tbb::concurrent_vector<int> c_vector; + c_vector a_c_vector; + + const int sequence_length = 100; + for (int i =1; i<= sequence_length; ++i){ + a_c_vector.push_back(i); + } + + ASSERT( range_based_for_accumulate(a_c_vector, std::plus<int>(), 0) == gauss_summ_of_int_sequence(sequence_length), "incorrect accumulated value generated via range based for ?"); +} +#endif //if __TBB_RANGE_BASED_FOR_PRESENT + +#if TBB_USE_EXCEPTIONS +#endif //TBB_USE_EXCEPTIONS + +#if __TBB_CPP11_RVALUE_REF_PRESENT +namespace move_semantics_helpers{ + struct move_only_type:NoCopy{ + const int* my_pointer; + move_only_type(move_only_type && other): my_pointer(other.my_pointer){other.my_pointer=NULL;} + explicit move_only_type(const int* value): my_pointer(value) {} + }; +} + +void TestPushBackMoveOnlyContainee(){ + using namespace move_semantics_helpers; + typedef tbb::concurrent_vector<move_only_type > vector_t; + vector_t v; + static const int magic_number =7; + move_only_type src(&magic_number); + v.push_back(std::move(src)); + ASSERT(v[0].my_pointer == &magic_number,"item was incorrectly moved during push_back?"); + ASSERT(src.my_pointer == NULL,"item was incorrectly moved during push_back?"); +} + +namespace emplace_helpers{ + struct wrapper_type:NoCopy{ + int value1; + int value2; + explicit wrapper_type(int v1, int v2) : value1 (v1), value2(v2) {} + friend bool operator==(const wrapper_type& lhs, const wrapper_type& rhs){ + return (lhs.value1 == rhs.value1) && (lhs.value2 == rhs.value2 ); + } + }; +} +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +//TODO: extend the test to number of types e.g. std::string +void TestEmplaceBack(){ + using namespace emplace_helpers; + typedef tbb::concurrent_vector<wrapper_type > vector_t; + vector_t v; + v.emplace_back(1,2); + ASSERT(v[0] == wrapper_type(1,2),"incorrectly in-place constructed item during emplace_back?"); +} +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + +//! Test the assignment operator and swap +void TestAssign() { + typedef tbb::concurrent_vector<FooWithAssign, local_counting_allocator<std::allocator<FooWithAssign>, size_t > > vector_t; + local_counting_allocator<std::allocator<FooWithAssign>, size_t > init_alloc; + init_alloc.allocations = 100; + for( int dst_size=1; dst_size<=128; NextSize( dst_size ) ) { + for( int src_size=2; src_size<=128; NextSize( src_size ) ) { + vector_t u(FooIterator(0), FooIterator(src_size), init_alloc); + for( int i=0; i<src_size; ++i ) + ASSERT( u[i].bar()==i, NULL ); + vector_t v(dst_size, FooWithAssign(), init_alloc); + for( int i=0; i<dst_size; ++i ) { + ASSERT( v[i].state==Foo::CopyInitialized, NULL ); + v[i].bar() = ~i; + } + ASSERT( v != u, NULL); + v.swap(u); + CheckVector(u, dst_size, src_size); + u.swap(v); + // using assignment + v = u; + ASSERT( v == u, NULL); + u.clear(); + ASSERT( u.size()==0, NULL ); + ASSERT( v.size()==size_t(src_size), NULL ); + for( int i=0; i<src_size; ++i ) + ASSERT( v[i].bar()==i, NULL ); + ASSERT( 0 == u.get_allocator().frees, NULL); + u.shrink_to_fit(); // deallocate unused memory + size_t items_allocated = u.get_allocator().items_allocated, + items_freed = u.get_allocator().items_freed; + size_t allocations = u.get_allocator().allocations, + frees = u.get_allocator().frees + 100; + ASSERT( items_allocated == items_freed, NULL); + ASSERT( allocations == frees, NULL); + } + } +} + +struct c_vector_type : default_container_traits { + template<typename element_type, typename allocator_type> + struct apply{ + typedef tbb::concurrent_vector<element_type, allocator_type > type; + }; + + typedef FooIterator init_iterator_type; + enum{ expected_number_of_items_to_allocate_for_steal_move = 0 }; + + template<typename element_type, typename allocator_type, typename iterator> + static bool equal(tbb::concurrent_vector<element_type, allocator_type > const& c, iterator begin, iterator end){ + bool equal_sizes = (size_t)std::distance(begin, end) == c.size(); + return equal_sizes && std::equal(c.begin(), c.end(), begin); + } +}; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +void TestSerialGrowByWithMoveIterators(){ + typedef default_stateful_fixture_make_helper<c_vector_type>::type fixture_t; + typedef fixture_t::container_t vector_t; + + fixture_t fixture("TestSerialGrowByWithMoveIterators"); + + vector_t dst(fixture.dst_allocator); + dst.grow_by(std::make_move_iterator(fixture.source.begin()), std::make_move_iterator(fixture.source.end())); + + fixture.verify_content_deep_moved(dst); +} + +#if __TBB_MOVE_IF_NOEXCEPT_PRESENT +namespace test_move_in_shrink_to_fit_helpers { + struct dummy : Harness::StateTrackable<>{ + int i; + dummy(int an_i) __TBB_NOEXCEPT(true) : Harness::StateTrackable<>(0), i(an_i) {} +#if !__TBB_IMPLICIT_MOVE_PRESENT || __TBB_NOTHROW_MOVE_MEMBERS_IMPLICIT_GENERATION_BROKEN + dummy(const dummy &src) __TBB_NOEXCEPT(true) : Harness::StateTrackable<>(src), i(src.i) {} + dummy(dummy &&src) __TBB_NOEXCEPT(true) : Harness::StateTrackable<>(std::move(src)), i(src.i) {} + + dummy& operator=(dummy &&src) __TBB_NOEXCEPT(true) { + Harness::StateTrackable<>::operator=(std::move(src)); + i = src.i; + return *this; + } + + //somehow magically this declaration make std::is_nothrow_move_constructible<pod>::value to works correctly on icc14+msvc2013 + ~dummy() __TBB_NOEXCEPT(true) {} +#endif //!__TBB_IMPLICIT_MOVE_PRESENT || __TBB_NOTHROW_MOVE_MEMBERS_IMPLICIT_GENERATION_BROKEN + friend bool operator== (const dummy &lhs, const dummy &rhs){ return lhs.i == rhs.i; } + }; +} +void TestSerialMoveInShrinkToFit(){ + const char* test_name = "TestSerialMoveInShrinkToFit"; + REMARK("running %s \n", test_name); + using test_move_in_shrink_to_fit_helpers::dummy; + + __TBB_STATIC_ASSERT(std::is_nothrow_move_constructible<dummy>::value,"incorrect test setup or broken configuration?"); + { + dummy src(0); + ASSERT_IN_TEST(is_state<Harness::StateTrackableBase::MoveInitialized>(dummy(std::move_if_noexcept(src))),"broken configuration ?", test_name); + } + static const size_t sequence_size = 15; + typedef tbb::concurrent_vector<dummy> c_vector_t; + std::vector<dummy> source(sequence_size, 0); + std::generate_n(source.begin(), source.size(), std::rand); + + c_vector_t c_vector; + c_vector.reserve(1); //make it fragmented + + c_vector.assign(source.begin(), source.end()); + memory_locations c_vector_before_shrink(c_vector); + c_vector.shrink_to_fit(); + + ASSERT_IN_TEST(c_vector_before_shrink.content_location_changed(c_vector), "incorrect test setup? shrink_to_fit should cause moving elements to other memory locations while it is not", test_name); + ASSERT_IN_TEST(all_of(c_vector, is_state_f<Harness::StateTrackableBase::MoveInitialized>()), "container did not move construct some elements?", test_name); + ASSERT_IN_TEST(c_vector == c_vector_t(source.begin(),source.end()),"",test_name); +} +#endif //__TBB_MOVE_IF_NOEXCEPT_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + +#include <string> + +// Test the comparison operators +void TestComparison() { + std::string str[3]; str[0] = "abc"; + str[1].assign("cba"); + str[2].assign("abc"); // same as 0th + tbb::concurrent_vector<char> var[3]; + var[0].assign(str[0].begin(), str[0].end()); + var[1].assign(str[0].rbegin(), str[0].rend()); + var[2].assign(var[1].rbegin(), var[1].rend()); // same as 0th + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + ASSERT( (var[i] == var[j]) == (str[i] == str[j]), NULL ); + ASSERT( (var[i] != var[j]) == (str[i] != str[j]), NULL ); + ASSERT( (var[i] < var[j]) == (str[i] < str[j]), NULL ); + ASSERT( (var[i] > var[j]) == (str[i] > str[j]), NULL ); + ASSERT( (var[i] <= var[j]) == (str[i] <= str[j]), NULL ); + ASSERT( (var[i] >= var[j]) == (str[i] >= str[j]), NULL ); + } + } +} + +//------------------------------------------------------------------------ +// Regression test for problem where on oversubscription caused +// concurrent_vector::grow_by to run very slowly (TR#196). +//------------------------------------------------------------------------ + +#include "tbb/task_scheduler_init.h" +#include <math.h> + +typedef unsigned long Number; + +static tbb::concurrent_vector<Number> Primes; + +class FindPrimes { + bool is_prime( Number val ) const { + int limit, factor = 3; + if( val<5u ) + return val==2; + else { + limit = long(sqrtf(float(val))+0.5f); + while( factor<=limit && val % factor ) + ++factor; + return factor>limit; + } + } +public: + void operator()( const tbb::blocked_range<Number>& r ) const { + for( Number i=r.begin(); i!=r.end(); ++i ) { + if( i%2 && is_prime(i) ) { + Primes.push_back( i ); + } + } + } +}; + +double TimeFindPrimes( int nthread ) { + Primes.clear(); + Primes.reserve(1000000);// TODO: or compact()? + tbb::task_scheduler_init init(nthread); + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for( tbb::blocked_range<Number>(0,1000000,500), FindPrimes() ); + tbb::tick_count t1 = tbb::tick_count::now(); + return (t1-t0).seconds(); +} + +void TestFindPrimes() { + // Time fully subscribed run. + double t2 = TimeFindPrimes( tbb::task_scheduler_init::automatic ); + + // Time parallel run that is very likely oversubscribed. + double t128 = TimeFindPrimes(128); + REMARK("TestFindPrimes: t2==%g t128=%g k=%g\n", t2, t128, t128/t2); + + // We allow the 128-thread run a little extra time to allow for thread overhead. + // Theoretically, following test will fail on machine with >128 processors. + // But that situation is not going to come up in the near future, + // and the generalization to fix the issue is not worth the trouble. + if( t128 > 1.3*t2 ) { + REPORT("Warning: grow_by is pathetically slow: t2==%g t128=%g k=%g\n", t2, t128, t128/t2); + } +} + +//------------------------------------------------------------------------ +// Test compatibility with STL sort. +//------------------------------------------------------------------------ + +#include <algorithm> + +void TestSort() { + for( int n=0; n<100; n=n*3+1 ) { + tbb::concurrent_vector<int> array(n); + for( int i=0; i<n; ++i ) + array.at(i) = (i*7)%n; + std::sort( array.begin(), array.end() ); + for( int i=0; i<n; ++i ) + ASSERT( array[i]==i, NULL ); + } +} + +#if TBB_USE_EXCEPTIONS + +template<typename c_vector> +size_t get_early_size(c_vector & v){ + return v.grow_by(0) - v.begin(); +} + +void verify_c_vector_size(size_t size, size_t capacity, size_t early_size, const char * const test_name){ + ASSERT_IN_TEST( size <= capacity, "", test_name); + ASSERT_IN_TEST( early_size >= size, "", test_name); +} + +template<typename c_vector_t> +void verify_c_vector_size(c_vector_t & c_v, const char * const test_name){ + verify_c_vector_size(c_v.size(), c_v.capacity(), get_early_size(c_v), test_name); +} + +void verify_c_vector_capacity_is_below(size_t capacity, size_t high, const char * const test_name){ + ASSERT_IN_TEST(capacity > 0, "unexpected capacity", test_name); + ASSERT_IN_TEST(capacity < high, "unexpected capacity", test_name); +} + +template<typename vector_t> +void verify_last_segment_allocation_failed(vector_t const& victim, const char* const test_name){ + ASSERT_THROWS_IN_TEST(victim.at(victim.size()), std::range_error, "",test_name ); +} + +template<typename vector_t> +void verify_assignment_operator_throws_bad_last_alloc(vector_t & victim, const char* const test_name){ + vector_t copy_of_victim(victim, victim.get_allocator()); + ASSERT_THROWS_IN_TEST(victim = copy_of_victim, tbb::bad_last_alloc, "", test_name); +} + +template<typename vector_t> +void verify_copy_and_assign_from_produce_the_same(vector_t const& victim, const char* const test_name){ + //TODO: remove explicit copy of allocator when full support of C++11 allocator_traits in concurrent_vector is present + vector_t copy_of_victim(victim, victim.get_allocator()); + ASSERT_IN_TEST(copy_of_victim == victim, "copy doesn't match original", test_name); + vector_t copy_of_victim2(10, victim[0], victim.get_allocator()); + copy_of_victim2 = victim; + ASSERT_IN_TEST(copy_of_victim == copy_of_victim2, "assignment doesn't match copying", test_name); +} + +template<typename allocator_t> +void verify_vector_partially_copied( + tbb::concurrent_vector<FooWithAssign, allocator_t> const& victim, size_t planned_victim_size, + tbb::concurrent_vector<FooWithAssign, allocator_t> const& src, bool is_memory_allocation_failure ,const char* const test_name) +{ + if (is_memory_allocation_failure) { // allocator generated exception + typedef tbb::concurrent_vector<FooWithAssign, allocator_t> vector_t; + ASSERT_IN_TEST( victim == vector_t(src.begin(), src.begin() + victim.size(), src.get_allocator()), "failed to properly copy of source ?", test_name ); + }else{ + ASSERT_IN_TEST( std::equal(victim.begin(), victim.begin() + planned_victim_size, src.begin()), "failed to properly copy items before the exception?", test_name ); + ASSERT_IN_TEST( ::all_of( victim.begin() + planned_victim_size, victim.end(), is_state_f<Foo::ZeroInitialized>() ), "failed to zero-initialize items left not constructed after the exception?", test_name ); + } +} + +//------------------------------------------------------------------------ +// Test exceptions safety (from allocator and items constructors) +//------------------------------------------------------------------------ +void TestExceptions() { + typedef static_counting_allocator<debug_allocator<FooWithAssign>, std::size_t> allocator_t; + typedef tbb::concurrent_vector<FooWithAssign, allocator_t> vector_t; + + enum methods { + zero_method = 0, + ctor_copy, ctor_size, assign_nt, assign_ir, reserve, compact, + all_methods + }; + ASSERT( !FooCount, NULL ); + + try { + vector_t src(FooIterator(0), FooIterator(N)); // original data + + for(int t = 0; t < 2; ++t) // exception type + for(int m = zero_method+1; m < all_methods; ++m) + { + track_foo_count<__LINE__> check_all_foo_destroyed_on_exit("TestExceptions"); + track_allocator_memory<allocator_t> verify_no_leak_at_exit("TestExceptions"); + allocator_t::init_counters(); + if(t) MaxFooCount = FooCount + N/4; + else allocator_t::set_limits(N/4); + vector_t victim; + try { + switch(m) { + case ctor_copy: { + vector_t acopy(src); + } break; // auto destruction after exception is checked by ~Foo + case ctor_size: { + vector_t sized(N); + } break; // auto destruction after exception is checked by ~Foo + // Do not test assignment constructor due to reusing of same methods as below + case assign_nt: { + victim.assign(N, FooWithAssign()); + } break; + case assign_ir: { + victim.assign(FooIterator(0), FooIterator(N)); + } break; + case reserve: { + try { + victim.reserve(victim.max_size()+1); + } catch(std::length_error &) { + } catch(...) { + KNOWN_ISSUE("ERROR: unrecognized exception - known compiler issue\n"); + } + victim.reserve(N); + } break; + case compact: { + if(t) MaxFooCount = 0; else allocator_t::set_limits(); // reset limits + victim.reserve(2); victim = src; // fragmented assignment + if(t) MaxFooCount = FooCount + 10; else allocator_t::set_limits(1, false); // block any allocation, check NULL return from allocator + victim.shrink_to_fit(); // should start defragmenting first segment + } break; + default:; + } + if(!t || m != reserve) ASSERT(false, "should throw an exception"); + } catch(std::bad_alloc &e) { + allocator_t::set_limits(); MaxFooCount = 0; + size_t capacity = victim.capacity(); + size_t size = victim.size(); + + size_t req_size = get_early_size(victim); + + verify_c_vector_size(size, capacity, req_size, "TestExceptions"); + + switch(m) { + case reserve: + if(t) ASSERT(false, NULL); + __TBB_fallthrough; + case assign_nt: + case assign_ir: + if(!t) { + ASSERT(capacity < N/2, "unexpected capacity"); + ASSERT(size == 0, "unexpected size"); + break; + } else { + ASSERT(size == N, "unexpected size"); + ASSERT(capacity >= N, "unexpected capacity"); + int i; + for(i = 1; ; ++i) + if(!victim[i].zero_bar()) break; + else ASSERT(victim[i].bar() == (m == assign_ir? i : initial_value_of_bar), NULL); + for(; size_t(i) < size; ++i) ASSERT(!victim[i].zero_bar(), NULL); + ASSERT(size_t(i) == size, NULL); + break; + } + case compact: + ASSERT(capacity > 0, "unexpected capacity"); + ASSERT(victim == src, "shrink_to_fit() is broken"); + break; + + default:; // nothing to check here + } + REMARK("Exception %d: %s\t- ok\n", m, e.what()); + } + } + } catch(...) { + ASSERT(false, "unexpected exception"); + } +} + +//TODO: split into two separate tests +//TODO: remove code duplication in exception safety tests +void TestExceptionSafetyGuaranteesForAssignOperator(){ + //TODO: use __FUNCTION__ for test name + const char* const test_name = "TestExceptionSafetyGuaranteesForAssignOperator"; + typedef static_counting_allocator<debug_allocator<FooWithAssign>, std::size_t> allocator_t; + typedef tbb::concurrent_vector<FooWithAssign, allocator_t> vector_t; + + track_foo_count<__LINE__> check_all_foo_destroyed_on_exit(test_name); + track_allocator_memory<allocator_t> verify_no_leak_at_exit(test_name); + + vector_t src(FooIterator(0), FooIterator(N)); // original data + + const size_t planned_victim_size = N/4; + + for(int t = 0; t < 2; ++t) {// exception type + vector_t victim; + victim.reserve(2); // get fragmented assignment + + ASSERT_THROWS_IN_TEST( + { + limit_foo_count_in_scope foo_limit(FooCount + planned_victim_size, t); + limit_allocated_items_in_scope<allocator_t> allocator_limit(allocator_t::items_allocated + planned_victim_size, !t); + + victim = src; // fragmented assignment + }, + std::bad_alloc, "", test_name + ); + + verify_c_vector_size(victim, test_name); + + if(!t) { + verify_c_vector_capacity_is_below(victim.capacity(), N, test_name); + } + + verify_vector_partially_copied(victim, planned_victim_size, src, !t, test_name); + verify_last_segment_allocation_failed(victim, test_name); + verify_copy_and_assign_from_produce_the_same(victim, test_name); + verify_assignment_operator_throws_bad_last_alloc(victim, test_name); + } +} +//TODO: split into two separate tests +void TestExceptionSafetyGuaranteesForConcurrentGrow(){ + const char* const test_name = "TestExceptionSafetyGuaranteesForConcurrentGrow"; + typedef static_counting_allocator<debug_allocator<FooWithAssign>, std::size_t> allocator_t; + typedef tbb::concurrent_vector<FooWithAssign, allocator_t> vector_t; + + track_foo_count<__LINE__> check_all_foo_destroyed_on_exit(test_name); + track_allocator_memory<allocator_t> verify_no_leak_at_exit(test_name); + + vector_t src(FooIterator(0), FooIterator(N)); // original data + + const size_t planned_victim_size = N/4; + static const int grain_size = 70; + + tbb::task_scheduler_init init(2); + + for(int t = 0; t < 2; ++t) {// exception type + vector_t victim; + +#if TBB_USE_CAPTURED_EXCEPTION + #define EXPECTED_EXCEPTION tbb::captured_exception +#else + #define EXPECTED_EXCEPTION std::bad_alloc +#endif + + ASSERT_THROWS_IN_TEST( + { + limit_foo_count_in_scope foo_limit(FooCount + 31, t); // these numbers help to reproduce the live lock for versions < TBB2.2 + limit_allocated_items_in_scope<allocator_t> allocator_limit(allocator_t::items_allocated + planned_victim_size, !t); + + grain_map m(concurrent_grow_single_range_map, Harness::end(concurrent_grow_single_range_map)); + + static const size_t part_weight = grain_size / m.total_number_of_parts; + + tbb::parallel_for( + tbb::blocked_range<size_t>(0, N, grain_size), + GrowBy<vector_t>(victim, m, part_weight) + ); + }, + EXPECTED_EXCEPTION, "", test_name + ); + + verify_c_vector_size(victim, test_name); + + if(!t) { + verify_c_vector_capacity_is_below(victim.capacity(), N, test_name); + } + + for(int i = 0; ; ++i) { + try { + Foo &foo = victim.at(i); + ASSERT( foo.is_valid_or_zero(),"" ); + } catch(std::range_error &) { // skip broken segment + ASSERT( size_t(i) < get_early_size(victim), NULL ); + } catch(std::out_of_range &){ + ASSERT( i > 0, NULL ); break; + } catch(...) { + KNOWN_ISSUE("ERROR: unrecognized exception - known compiler issue\n"); break; + } + } + + verify_copy_and_assign_from_produce_the_same(victim, test_name); + } +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +void TestExceptionSafetyGuaranteesForMoveAssignOperatorWithUnEqualAllocatorMemoryFailure(){ + const char* const test_name = "TestExceptionSafetyGuaranteesForMoveAssignOperatorWithUnEqualAllocatorMemoryFailure"; + + //TODO: add ability to inject debug_allocator into stateful_allocator_fixture::allocator_t + //typedef static_counting_allocator<debug_allocator<FooWithAssign>, std::size_t> allocator_t; + typedef default_stateful_fixture_make_helper<c_vector_type, Harness::false_type>::type fixture_t; + typedef arena_allocator_fixture<FooWithAssign, Harness::false_type> arena_allocator_fixture_t; + typedef fixture_t::allocator_t allocator_t; + typedef fixture_t::container_t vector_t; + + fixture_t fixture(test_name); + arena_allocator_fixture_t arena_allocator_fixture(4 * fixture.container_size); + + const size_t allocation_limit = fixture.container_size/4; + + vector_t victim(arena_allocator_fixture.allocator); + victim.reserve(2); // get fragmented assignment + + ASSERT_THROWS_IN_TEST( + { + limit_allocated_items_in_scope<allocator_t> allocator_limit(allocator_t::items_allocated + allocation_limit); + victim = std::move(fixture.source); // fragmented assignment + }, + std::bad_alloc, "", test_name + ); + + verify_c_vector_size(victim, test_name); + verify_c_vector_capacity_is_below(victim.capacity(), allocation_limit + 2, test_name); + + fixture.verify_part_of_content_deep_moved(victim, victim.size()); + + verify_last_segment_allocation_failed(victim, test_name); + verify_copy_and_assign_from_produce_the_same(victim, test_name); + verify_assignment_operator_throws_bad_last_alloc(victim, test_name); +} + +void TestExceptionSafetyGuaranteesForMoveAssignOperatorWithUnEqualAllocatorExceptionInElementCtor(){ + const char* const test_name = "TestExceptionSafetyGuaranteesForMoveAssignOperator"; + //typedef static_counting_allocator<debug_allocator<FooWithAssign>, std::size_t> allocator_t; + typedef default_stateful_fixture_make_helper<c_vector_type, Harness::false_type>::type fixture_t; + typedef arena_allocator_fixture<FooWithAssign, Harness::false_type> arena_allocator_fixture_t; + typedef fixture_t::container_t vector_t; + + fixture_t fixture(test_name); + const size_t planned_victim_size = fixture.container_size/4; + arena_allocator_fixture_t arena_allocator_fixture(4 * fixture.container_size); + + vector_t victim(arena_allocator_fixture.allocator); + victim.reserve(2); // get fragmented assignment + + ASSERT_THROWS_IN_TEST( + { + limit_foo_count_in_scope foo_limit(FooCount + planned_victim_size); + victim = std::move(fixture.source); // fragmented assignment + }, + std::bad_alloc, "", test_name + ); + + verify_c_vector_size(victim, test_name); + + fixture.verify_part_of_content_deep_moved(victim, planned_victim_size); + + verify_last_segment_allocation_failed(victim, test_name); + verify_copy_and_assign_from_produce_the_same(victim, test_name); + verify_assignment_operator_throws_bad_last_alloc(victim, test_name); +} +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + +namespace push_back_exception_safety_helpers{ + //TODO: remove code duplication with emplace_helpers::wrapper_type + struct throwing_foo:Foo{ + int value1; + int value2; + explicit throwing_foo(int v1, int v2) : value1 (v1), value2(v2) { } + }; + + template< typename foo_t = throwing_foo> + struct fixture{ + typedef tbb::concurrent_vector<foo_t, debug_allocator<foo_t> > vector_t; + vector_t v; + + void test( void(*p_test)(vector_t&), const char * test_name){ + track_foo_count<__LINE__> verify_no_foo_leaked_during_exception(test_name); + ASSERT_IN_TEST(v.empty(),"incorrect test setup?", test_name ); + ASSERT_THROWS_IN_TEST(p_test(v), Foo_exception ,"", test_name); + ASSERT_IN_TEST(is_state<Foo::ZeroInitialized>(v[0]),"incorrectly filled item during exception in emplace_back?", test_name); + } + }; +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +void TestPushBackMoveExceptionSafety(){ + typedef push_back_exception_safety_helpers::fixture<Foo> fixture_t; + fixture_t t; + + limit_foo_count_in_scope foo_limit(FooCount + 1); + + struct test{ + static void test_move_push_back(fixture_t::vector_t& v){ + Foo f; + v.push_back(std::move(f)); + } + }; + t.test(&test::test_move_push_back, "TestPushBackMoveExceptionSafety"); +} + +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +void TestEmplaceBackExceptionSafety(){ + typedef push_back_exception_safety_helpers::fixture<> fixture_t; + fixture_t t; + + Foo dummy; //make FooCount non zero; + Harness::suppress_unused_warning(dummy); + limit_foo_count_in_scope foo_limit(FooCount); + + struct test{ + static void test_emplace(fixture_t::vector_t& v){ + v.emplace_back(1,2); + } + }; + t.test(&test::test_emplace, "TestEmplaceBackExceptionSafety"); +} +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + +#endif /* TBB_USE_EXCEPTIONS */ + +//------------------------------------------------------------------------ +// Test support for SIMD instructions +//------------------------------------------------------------------------ +#include "harness_m128.h" + +#if HAVE_m128 || HAVE_m256 + +template<typename ClassWithVectorType> +void TestVectorTypes() { + tbb::concurrent_vector<ClassWithVectorType> v; + for( int i=0; i<100; ++i ) { + // VC8 does not properly align a temporary value; to work around, use explicit variable + ClassWithVectorType foo(i); + v.push_back(foo); + for( int j=0; j<i; ++j ) { + ClassWithVectorType bar(j); + ASSERT( v[j]==bar, NULL ); + } + } +} +#endif /* HAVE_m128 | HAVE_m256 */ + +//------------------------------------------------------------------------ + +namespace v3_backward_compatibility{ + namespace segment_t_layout_helpers{ + //this is previous definition of according inner class of concurrent_vector_base_v3 + struct segment_t_v3 { + void* array; + }; + //helper class to access protected members of concurrent_vector_base + struct access_vector_fields :tbb::internal::concurrent_vector_base_v3 { + using tbb::internal::concurrent_vector_base_v3::segment_t; + using tbb::internal::concurrent_vector_base_v3::segment_index_t; + using tbb::internal::concurrent_vector_base_v3::pointers_per_long_table; + using tbb::internal::concurrent_vector_base_v3::internal_segments_table; + }; + //this is previous definition of according inner class of concurrent_vector_base_v3 + struct internal_segments_table_v3 { + access_vector_fields::segment_index_t first_block; + segment_t_v3 table[access_vector_fields::pointers_per_long_table]; + }; + + template <typename checked_type> + struct alignment_check_helper{ + char dummy; + checked_type checked; + }; + } + void TestSegmentTLayout(){ + using namespace segment_t_layout_helpers; + typedef alignment_check_helper<segment_t_v3> structure_with_old_segment_type; + typedef alignment_check_helper<access_vector_fields::segment_t> structure_with_new_segment_type; + + ASSERT((sizeof(structure_with_old_segment_type)==sizeof(structure_with_new_segment_type)) + ,"layout of new segment_t and old one differ?"); + } + + void TestInternalSegmentsTableLayout(){ + using namespace segment_t_layout_helpers; + typedef alignment_check_helper<internal_segments_table_v3> structure_with_old_segment_table_type; + typedef alignment_check_helper<access_vector_fields::internal_segments_table> structure_with_new_segment_table_type; + + ASSERT((sizeof(structure_with_old_segment_table_type)==sizeof(structure_with_new_segment_table_type)) + ,"layout of new internal_segments_table and old one differ?"); + } +} +void TestV3BackwardCompatibility(){ + using namespace v3_backward_compatibility; + TestSegmentTLayout(); + TestInternalSegmentsTableLayout(); +} + +#include "harness_defs.h" + +#include <vector> +#include <numeric> +#include <functional> + +// The helper to run a test only when a default construction is present. +template <bool default_construction_present> struct do_default_construction_test { + template<typename FuncType> void operator() ( FuncType func ) const { func(); } +}; +template <> struct do_default_construction_test<false> { + template<typename FuncType> void operator()( FuncType ) const {} +}; + +template <typename Type, typename Allocator> +class test_grow_by_and_resize : NoAssign { + tbb::concurrent_vector<Type, Allocator> &my_c; +public: + test_grow_by_and_resize( tbb::concurrent_vector<Type, Allocator> &c ) : my_c(c) {} + void operator()() const { + const typename tbb::concurrent_vector<Type, Allocator>::size_type sz = my_c.size(); + my_c.grow_by( 5 ); + ASSERT( my_c.size() == sz + 5, NULL ); + my_c.resize( sz ); + ASSERT( my_c.size() == sz, NULL ); + } +}; + +template <typename Type, typename Allocator> +void CompareVectors( const tbb::concurrent_vector<Type, Allocator> &c1, const tbb::concurrent_vector<Type, Allocator> &c2 ) { + ASSERT( !(c1 == c2) && c1 != c2, NULL ); + ASSERT( c1 <= c2 && c1 < c2 && c2 >= c1 && c2 > c1, NULL ); +} + +#if __TBB_CPP11_SMART_POINTERS_PRESENT +template <typename Type, typename Allocator> +void CompareVectors( const tbb::concurrent_vector<std::weak_ptr<Type>, Allocator> &, const tbb::concurrent_vector<std::weak_ptr<Type>, Allocator> & ) { + /* do nothing for std::weak_ptr */ +} +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ + +template <bool default_construction_present, typename Type, typename Allocator> +void Examine( tbb::concurrent_vector<Type, Allocator> c, const std::vector<Type> &vec ) { + typedef tbb::concurrent_vector<Type, Allocator> vector_t; + typedef typename vector_t::size_type size_type_t; + + ASSERT( c.size() == vec.size(), NULL ); + for ( size_type_t i=0; i<c.size(); ++i ) ASSERT( Harness::IsEqual()(c[i], vec[i]), NULL ); + do_default_construction_test<default_construction_present>()(test_grow_by_and_resize<Type,Allocator>(c)); + c.grow_by( size_type_t(5), c[0] ); + c.grow_to_at_least( c.size()+5, c.at(0) ); + vector_t c2; + c2.reserve( 5 ); + std::copy( c.begin(), c.begin() + 5, std::back_inserter( c2 ) ); + + c.grow_by( c2.begin(), c2.end() ); + const vector_t& cvcr = c; + ASSERT( Harness::IsEqual()(cvcr.front(), *(c2.rend()-1)), NULL ); + ASSERT( Harness::IsEqual()(cvcr.back(), *c2.rbegin()), NULL); + ASSERT( Harness::IsEqual()(*c.cbegin(), *(c.crend()-1)), NULL ); + ASSERT( Harness::IsEqual()(*(c.cend()-1), *c.crbegin()), NULL ); + c.swap( c2 ); + ASSERT( c.size() == 5, NULL ); + CompareVectors( c, c2 ); + c.swap( c2 ); + c2.clear(); + ASSERT( c2.size() == 0, NULL ); + c2.shrink_to_fit(); + Allocator a = c.get_allocator(); + a.deallocate( a.allocate(1), 1 ); +} + +template <typename Type> +class test_default_construction : NoAssign { + const std::vector<Type> &my_vec; +public: + test_default_construction( const std::vector<Type> &vec ) : my_vec(vec) {} + void operator()() const { + // Construction with initial size specified by argument n. + tbb::concurrent_vector<Type> c7( my_vec.size() ); + std::copy( my_vec.begin(), my_vec.end(), c7.begin() ); + Examine</*default_construction_present = */true>( c7, my_vec ); + tbb::concurrent_vector< Type, debug_allocator<Type> > c8( my_vec.size() ); + std::copy( c7.begin(), c7.end(), c8.begin() ); + Examine</*default_construction_present = */true>( c8, my_vec ); + } +}; + +template <bool default_construction_present, typename Type> +void TypeTester( const std::vector<Type> &vec ) { + __TBB_ASSERT( vec.size() >= 5, "Array should have at least 5 elements" ); + // Construct empty vector. + tbb::concurrent_vector<Type> c1; + std::copy( vec.begin(), vec.end(), std::back_inserter(c1) ); + Examine<default_construction_present>( c1, vec ); +#if __TBB_INITIALIZER_LISTS_PRESENT + // Constructor from initializer_list. + tbb::concurrent_vector<Type> c2({vec[0],vec[1],vec[2]}); + std::copy( vec.begin()+3, vec.end(), std::back_inserter(c2) ); + Examine<default_construction_present>( c2, vec ); +#endif + // Copying constructor. + tbb::concurrent_vector<Type> c3(c1); + Examine<default_construction_present>( c3, vec ); + // Construct with non-default allocator + tbb::concurrent_vector< Type, debug_allocator<Type> > c4; + std::copy( vec.begin(), vec.end(), std::back_inserter(c4) ); + Examine<default_construction_present>( c4, vec ); + // Copying constructor for vector with different allocator type. + tbb::concurrent_vector<Type> c5(c4); + Examine<default_construction_present>( c5, vec ); + tbb::concurrent_vector< Type, debug_allocator<Type> > c6(c3); + Examine<default_construction_present>( c6, vec ); + // Construction with initial size specified by argument n. + do_default_construction_test<default_construction_present>()(test_default_construction<Type>(vec)); + // Construction with initial size specified by argument n, initialization by copying of t, and given allocator instance. + debug_allocator<Type> allocator; + tbb::concurrent_vector< Type, debug_allocator<Type> > c9(vec.size(), vec[1], allocator); + Examine<default_construction_present>( c9, std::vector<Type>(vec.size(), vec[1]) ); + // Construction with copying iteration range and given allocator instance. + tbb::concurrent_vector< Type, debug_allocator<Type> > c10(c1.begin(), c1.end(), allocator); + Examine<default_construction_present>( c10, vec ); + tbb::concurrent_vector<Type> c11(vec.begin(), vec.end()); + Examine<default_construction_present>( c11, vec ); +} + +void TestTypes() { + const int NUMBER = 100; + + std::vector<int> intArr; + for ( int i=0; i<NUMBER; ++i ) intArr.push_back(i); + TypeTester</*default_construction_present = */true>( intArr ); + +#if __TBB_CPP11_REFERENCE_WRAPPER_PRESENT && !__TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN + std::vector< std::reference_wrapper<int> > refArr; + // The constructor of std::reference_wrapper<T> from T& is explicit in some versions of libstdc++. + for ( int i=0; i<NUMBER; ++i ) refArr.push_back( std::reference_wrapper<int>(intArr[i]) ); + TypeTester</*default_construction_present = */false>( refArr ); +#else + REPORT( "Known issue: C++11 reference wrapper tests are skipped.\n" ); +#endif /* __TBB_CPP11_REFERENCE_WRAPPER_PRESENT && !__TBB_REFERENCE_WRAPPER_COMPILATION_BROKEN */ + + std::vector< tbb::atomic<int> > tbbIntArr( NUMBER ); + for ( int i=0; i<NUMBER; ++i ) tbbIntArr[i] = i; + TypeTester</*default_construction_present = */true>( tbbIntArr ); + +#if __TBB_CPP11_SMART_POINTERS_PRESENT + std::vector< std::shared_ptr<int> > shrPtrArr; + for ( int i=0; i<NUMBER; ++i ) shrPtrArr.push_back( std::make_shared<int>(i) ); + TypeTester</*default_construction_present = */true>( shrPtrArr ); + + std::vector< std::weak_ptr<int> > wkPtrArr; + std::copy( shrPtrArr.begin(), shrPtrArr.end(), std::back_inserter(wkPtrArr) ); + TypeTester</*default_construction_present = */true>( wkPtrArr ); +#else + REPORT( "Known issue: C++11 smart pointer tests are skipped.\n" ); +#endif /* __TBB_CPP11_SMART_POINTERS_PRESENT */ +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +template <template <typename...> typename TVector> +void TestDeductionGuides() { + using ComplexType = const std::string*; + std::vector<ComplexType> v; + std::string s = "s"; + auto l = {ComplexType(&s), ComplexType(&s)}; + + // check TVector(InputIterator, InputIterator) + TVector v1(v.begin(), v.end()); + static_assert(std::is_same<decltype(v1), TVector<ComplexType>>::value); + + // check TVector(InputIterator, InputIterator, Alocator) + TVector v2(v.begin(), v.end(), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(v2), + TVector<ComplexType, std::allocator<ComplexType>>>::value); + + // check TVector(std::initializer_list<T>) + TVector v3(l); + static_assert(std::is_same<decltype(v3), + TVector<ComplexType>>::value); + + // check TVector(std::initializer_list, Alocator) + TVector v4(l, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(v4), TVector<ComplexType, std::allocator<ComplexType>>>::value); + + // check TVector(TVector&) + TVector v5(v1); + static_assert(std::is_same<decltype(v5), TVector<ComplexType>>::value); + + // check TVector(TVector&, Allocator) + TVector v6(v5, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(v6), TVector<ComplexType, std::allocator<ComplexType>>>::value); + + // check TVector(TVector&&) + TVector v7(std::move(v1)); + static_assert(std::is_same<decltype(v7), decltype(v1)>::value); + + // check TVector(TVector&&, Allocator) + TVector v8(std::move(v5), std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(v8), TVector<ComplexType, std::allocator<ComplexType>>>::value); + + // check TVector(TVector&, Allocator) + TVector v9(v1, std::allocator<ComplexType>()); + static_assert(std::is_same<decltype(v9), TVector<ComplexType, std::allocator<ComplexType>>>::value); + +} +#endif + +// Currently testing compilation issues with polymorphic allocator, but concurrent_vector does not +// provide full support yet. +// TODO: extend test with full checking polymorphic_allocator with concurrent_vector +void TestPMRSupport() { + typedef pmr_stateful_allocator<int> AType; + typedef tbb::concurrent_vector<int, AType> VType; + const int VEC_SIZE = 1000; + + AType original_alloc; + VType c(original_alloc); + + // General compilation test + for( int i = 0; i < VEC_SIZE; ++i ) { + c.push_back(i*i); + } + VType::const_iterator p = c.begin(); + for( int i = 0; i < VEC_SIZE; ++i ) { + ASSERT( *p == i*i, NULL ); ++p; + } + + // Check that swap is allocator aware + AType swap_alloc; + VType swap_container(swap_alloc); swap_container.swap(c); + ASSERT(c.get_allocator() != swap_container.get_allocator(), "Allocator was swapped, it shouldn't"); + +#if __TBB_CPP11_RVALUE_REF_PRESENT + // Move assignment operator deleted, container is allocator aware + AType move_alloc; + VType move_container(move_alloc); + move_container = std::move(c); + ASSERT(c.get_allocator() != move_container.get_allocator(), "Allocator was moved, it shouldn't"); +#endif +} + +int TestMain () { + if( MinThread<1 ) { + REPORT("ERROR: MinThread=%d, but must be at least 1\n",MinThread); MinThread = 1; + } + TestFoo(); + TestV3BackwardCompatibility(); + TestIteratorTraits<tbb::concurrent_vector<Foo>::iterator,Foo>(); + TestIteratorTraits<tbb::concurrent_vector<Foo>::const_iterator,const Foo>(); + TestArrayLength(); + TestAllOf(); +#if __TBB_INITIALIZER_LISTS_PRESENT + TestInitList(); +#else + REPORT("Known issue: initializer list tests are skipped.\n"); +#endif + TestSequentialFor<FooWithAssign> (); + TestResizeAndCopy(); + TestAssign(); +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestMoveConstructor<c_vector_type>(); + TestMoveAssignOperator<c_vector_type>(); + TestConstructorWithMoveIterators<c_vector_type>(); + TestAssignWithMoveIterators<c_vector_type>(); + TestSerialGrowByWithMoveIterators(); +#if __TBB_MOVE_IF_NOEXCEPT_PRESENT + TestSerialMoveInShrinkToFit(); +#endif // __TBB_MOVE_IF_NOEXCEPT_PRESENT +#else + REPORT("Known issue: tests for vector move constructor/assignment operator are skipped.\n"); +#endif + TestGrowToAtLeastWithSourceParameter<tbb::concurrent_vector<int> >(12345); + TestSerialGrowByRange(false); + TestSerialGrowByRange(true); +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestPushBackMoveOnlyContainee(); +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + TestEmplaceBack(); +#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT +#endif //__TBB_CPP11_RVALUE_REF_PRESENT +#if HAVE_m128 + TestVectorTypes<ClassWithSSE>(); +#endif +#if HAVE_m256 + if (have_AVX()) TestVectorTypes<ClassWithAVX>(); +#endif + TestCapacity(); + ASSERT( !FooCount, NULL ); + for( int nthread=MinThread; nthread<=MaxThread; ++nthread ) { + tbb::task_scheduler_init init( nthread ); + TestParallelFor( nthread ); + TestConcurrentGrowToAtLeast(); + TestConcurrentGrowBy( nthread ); + } + ASSERT( !FooCount, NULL ); + TestComparison(); + TestFindPrimes(); + TestSort(); +#if __TBB_RANGE_BASED_FOR_PRESENT + TestRangeBasedFor(); +#endif //if __TBB_RANGE_BASED_FOR_PRESENT +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + REPORT("Known issue: exception safety test is skipped.\n"); +#elif TBB_USE_EXCEPTIONS + TestExceptions(); + TestExceptionSafetyGuaranteesForAssignOperator(); +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorMemoryFailure<c_vector_type>(); + TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorExceptionInElementCtor<c_vector_type>(); + TestExceptionSafetyGuaranteesForMoveAssignOperatorWithUnEqualAllocatorMemoryFailure(); + TestExceptionSafetyGuaranteesForMoveAssignOperatorWithUnEqualAllocatorExceptionInElementCtor(); + TestPushBackMoveExceptionSafety(); +#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT + TestEmplaceBackExceptionSafety(); +#endif /*__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */ +#else + REPORT("Known issue: exception safety tests for move constructor/assignment operator , grow_by are skipped.\n"); +#endif /*__TBB_CPP11_RVALUE_REF_PRESENT */ +#endif /* TBB_USE_EXCEPTIONS */ + TestTypes(); +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + TestDeductionGuides<tbb::concurrent_vector>(); +#endif + TestPMRSupport(); + + ASSERT( !FooCount, NULL ); + REMARK("sizeof(concurrent_vector<int>) == %d\n", (int)sizeof(tbb::concurrent_vector<int>)); + return Harness::Done; +} + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif // warning 4800 is back diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_condition_variable.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_condition_variable.h new file mode 100644 index 00000000..f700484f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_condition_variable.h @@ -0,0 +1,763 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/compat/condition_variable" +#include "tbb/mutex.h" +#include "tbb/recursive_mutex.h" +#include "tbb/tick_count.h" +#include "tbb/atomic.h" + +#include <stdexcept> + +#include "harness.h" + +#if TBB_IMPLEMENT_CPP0X +// This test deliberately avoids a "using tbb" statement, +// so that the error of putting types in the wrong namespace will be caught. +using namespace std; +#else +using namespace tbb::interface5; +#endif + +#if __TBB_CPP11_RVALUE_REF_PRESENT +template<typename M> +void TestUniqueLockMoveConstructorAndAssignOp(){ + typedef unique_lock<M> unique_lock_t; + + static const bool locked = true; + static const bool unlocked = false; + + struct Locked{ + bool value; + Locked(bool a_value) : value(a_value) {} + }; + + typedef Locked destination; + typedef Locked source; + + struct MutexAndLockFixture{ + M mutex; + unique_lock_t lock; + const bool was_locked; + + MutexAndLockFixture(source lckd_src) : lock(mutex), was_locked(lckd_src.value){ + if (!lckd_src.value) lock.unlock(); + ASSERT(was_locked == lock.owns_lock(), "unlock did not release the mutex while should?"); + } + }; + + struct TestCases{ + const char* filename; + int line; + + TestCases(const char* a_filename, int a_line) : filename(a_filename), line(a_line) {} + + void TestMoveConstructor(source locked_src){ + MutexAndLockFixture src(locked_src); + unique_lock_t dst_lock(std::move(src.lock)); + AssertOwnershipWasTransfered(dst_lock, src.lock, src.was_locked, &src.mutex); + } + + void TestMoveAssignment(source locked_src, destination locked_dest){ + MutexAndLockFixture src(locked_src); + MutexAndLockFixture dst(locked_dest); + + dst.lock = std::move(src.lock); + ASSERT_CUSTOM(unique_lock_t(dst.mutex, try_to_lock).owns_lock(), "unique_lock should release owned mutex on assignment", filename, line); + AssertOwnershipWasTransfered(dst.lock, src.lock, src.was_locked, &src.mutex); + } + + void AssertOwnershipWasTransfered(unique_lock_t const& dest_lock, unique_lock_t const& src_lck, const bool was_locked, const M* mutex) { + ASSERT_CUSTOM(dest_lock.owns_lock() == was_locked, "moved to lock object should have the same state as source before move", filename, line); + ASSERT_CUSTOM(dest_lock.mutex() == mutex, "moved to lock object should have the same state as source before move", filename, line); + ASSERT_CUSTOM(src_lck.owns_lock() == false, "moved from lock object must not left locked", filename, line); + ASSERT_CUSTOM(src_lck.mutex() == NULL, "moved from lock object must not has mutex", filename, line); + } + }; +//TODO: to rework this with an assertion binder +#define AT_LOCATION() TestCases( __FILE__, __LINE__) \ + + AT_LOCATION().TestMoveConstructor(source(locked)); + AT_LOCATION().TestMoveAssignment (source(locked), destination(locked)); + AT_LOCATION().TestMoveAssignment (source(locked), destination(unlocked)); + AT_LOCATION().TestMoveConstructor(source(unlocked)); + AT_LOCATION().TestMoveAssignment (source(unlocked), destination(locked)); + AT_LOCATION().TestMoveAssignment (source(unlocked), destination(unlocked)); + +#undef AT_LOCATION + +} +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + +template<typename M> +struct Counter { + typedef M mutex_type; + M mutex; + volatile long value; + void flog_once_lock_guard( size_t mode ); + void flog_once_unique_lock( size_t mode ); +}; + +template<typename M> +void Counter<M>::flog_once_lock_guard(size_t mode) +/** Increments counter once for each iteration in the iteration space. */ +{ + if( mode&1 ) { + // Try acquire and release with implicit lock_guard + // precondition: if mutex_type is not a recursive mutex, the calling thread does not own the mutex m. + // if the precondition is not met, either dead-lock incorrect 'value' would result in. + lock_guard<M> lg(mutex); + value = value+1; + } else { + // Try acquire and release with adopt lock_quard + // precodition: the calling thread owns the mutex m. + // if the precondition is not met, incorrect 'value' would result in because the thread unlocks + // mutex that it does not own. + mutex.lock(); + lock_guard<M> lg( mutex, adopt_lock ); + value = value+1; + } +} + +template<typename M> +void Counter<M>::flog_once_unique_lock(size_t mode) +/** Increments counter once for each iteration in the iteration space. */ +{ + switch( mode&7 ) { + case 0: + {// implicitly acquire and release mutex with unique_lock + unique_lock<M> ul( mutex ); + value = value+1; + ASSERT( ul==true, NULL ); + } + break; + case 1: + {// unique_lock with defer_lock + unique_lock<M> ul( mutex, defer_lock ); + ASSERT( ul.owns_lock()==false, NULL ); + ul.lock(); + value = value+1; + ASSERT( ul.owns_lock()==true, NULL ); + } + break; + case 2: + {// unique_lock::try_lock() with try_to_lock + unique_lock<M> ul( mutex, try_to_lock ); + if( !ul ) + while( !ul.try_lock() ) + __TBB_Yield(); + value = value+1; + } + break; + case 3: + {// unique_lock::try_lock_for() with try_to_lock + unique_lock<M> ul( mutex, defer_lock ); + tbb::tick_count::interval_t i(1.0); + while( !ul.try_lock_for( i ) ) + ; + value = value+1; + ASSERT( ul.owns_lock()==true, NULL ); + } + break; + case 4: + { + unique_lock<M> ul_o4; + {// unique_lock with adopt_lock + mutex.lock(); + unique_lock<M> ul( mutex, adopt_lock ); + value = value+1; + ASSERT( ul.owns_lock()==true, NULL ); + ASSERT( ul.mutex()==&mutex, NULL ); + ASSERT( ul_o4.owns_lock()==false, NULL ); + ASSERT( ul_o4.mutex()==NULL, NULL ); + swap( ul, ul_o4 ); + ASSERT( ul.owns_lock()==false, NULL ); + ASSERT( ul.mutex()==NULL, NULL ); + ASSERT( ul_o4.owns_lock()==true, NULL ); + ASSERT( ul_o4.mutex()==&mutex, NULL ); + ul_o4.unlock(); + } + ASSERT( ul_o4.owns_lock()==false, NULL ); + } + break; + case 5: + { + unique_lock<M> ul_o5; + {// unique_lock with adopt_lock + mutex.lock(); + unique_lock<M> ul( mutex, adopt_lock ); + value = value+1; + ASSERT( ul.owns_lock()==true, NULL ); + ASSERT( ul.mutex()==&mutex, NULL ); + ASSERT( ul_o5.owns_lock()==false, NULL ); + ASSERT( ul_o5.mutex()==NULL, NULL ); + ul_o5.swap( ul ); + ASSERT( ul.owns_lock()==false, NULL ); + ASSERT( ul.mutex()==NULL, NULL ); + ASSERT( ul_o5.owns_lock()==true, NULL ); + ASSERT( ul_o5.mutex()==&mutex, NULL ); + ul_o5.unlock(); + } + ASSERT( ul_o5.owns_lock()==false, NULL ); + } + break; + default: + {// unique_lock with adopt_lock, and release() + mutex.lock(); + unique_lock<M> ul( mutex, adopt_lock ); + ASSERT( ul==true, NULL ); + value = value+1; + M* old_m = ul.release(); + old_m->unlock(); + ASSERT( ul.owns_lock()==false, NULL ); + } + break; + } +} + +static tbb::atomic<size_t> Order; + +template<typename State, long TestSize> +struct WorkForLocks: NoAssign { + static const size_t chunk = 100; + State& state; + WorkForLocks( State& state_ ) : state(state_) {} + void operator()( int ) const { + size_t step; + while( (step=Order.fetch_and_add<tbb::acquire>(chunk))<TestSize ) { + for( size_t i=0; i<chunk && step<TestSize; ++i, ++step ) { + state.flog_once_lock_guard(step); + state.flog_once_unique_lock(step); + } + } + } +}; + +template<typename M> +void TestLocks( const char* name, int nthread ) { + REMARK("testing %s in TestLocks\n",name); + Counter<M> counter; + counter.value = 0; + Order = 0; + // use the macro because of a gcc 4.6 bug +#define TEST_SIZE 100000 + NativeParallelFor( nthread, WorkForLocks<Counter<M>, TEST_SIZE>(counter) ); + + if( counter.value!=2*TEST_SIZE ) + REPORT("ERROR for %s in TestLocks: counter.value=%ld != 2 * %ld=test_size\n",name,counter.value,TEST_SIZE); +#undef TEST_SIZE +} + +static tbb::atomic<int> barrier; + +// Test if the constructor works and if native_handle() works +template<typename M> +struct WorkForCondVarCtor: NoAssign { + condition_variable& my_cv; + M& my_mtx; + WorkForCondVarCtor( condition_variable& cv_, M& mtx_ ) : my_cv(cv_), my_mtx(mtx_) {} + void operator()( int tid ) const { + ASSERT( tid<=1, NULL ); // test with 2 threads. + condition_variable::native_handle_type handle = my_cv.native_handle(); + if( tid&1 ) { + my_mtx.lock(); + ++barrier; +#if _WIN32||_WIN64 + if( !tbb::interface5::internal::internal_condition_variable_wait( *handle, &my_mtx ) ) { + int ec = GetLastError(); + ASSERT( ec!=WAIT_TIMEOUT, NULL ); + throw_exception( tbb::internal::eid_condvar_wait_failed ); + } +#else + if( pthread_cond_wait( handle, my_mtx.native_handle() ) ) + throw_exception( tbb::internal::eid_condvar_wait_failed ); +#endif + ++barrier; + my_mtx.unlock(); + } else { + bool res; + while( (res=my_mtx.try_lock())==true && barrier==0 ) { + my_mtx.unlock(); + __TBB_Yield(); + } + if( res ) my_mtx.unlock(); + do { +#if _WIN32||_WIN64 + tbb::interface5::internal::internal_condition_variable_notify_one( *handle ); +#else + pthread_cond_signal( handle ); +#endif + __TBB_Yield(); + } while ( barrier<2 ); + } + } +}; + +static condition_variable* test_cv; +static tbb::atomic<int> n_waiters; + +// Test if the destructor works +template<typename M> +struct WorkForCondVarDtor: NoAssign { + int nthread; + M& my_mtx; + WorkForCondVarDtor( int n, M& mtx_ ) : nthread(n), my_mtx(mtx_) {} + void operator()( int tid ) const { + if( tid==0 ) { + unique_lock<M> ul( my_mtx, defer_lock ); + test_cv = new condition_variable; + + while( n_waiters<nthread-1 ) + __TBB_Yield(); + ul.lock(); + test_cv->notify_all(); + ul.unlock(); + while( n_waiters>0 ) + __TBB_Yield(); + delete test_cv; + } else { + while( test_cv==NULL ) + __TBB_Yield(); + unique_lock<M> ul(my_mtx); + ++n_waiters; + test_cv->wait( ul ); + --n_waiters; + } + } +}; + +static const int max_ticket = 100; +static const int short_delay = 10; +static const int long_delay = 100; + +tbb::atomic<int> n_signaled; +tbb::atomic<int> n_done, n_done_1, n_done_2; +tbb::atomic<int> n_timed_out; + +static bool false_to_true; + +struct TestPredicateFalseToTrue { + TestPredicateFalseToTrue() {} + bool operator()() { return false_to_true; } +}; + +struct TestPredicateFalse { + TestPredicateFalse() {} + bool operator()() { return false; } +}; + +struct TestPredicateTrue { + TestPredicateTrue() {} + bool operator()() { return true; } +}; + +// Test timed wait and timed wait with pred +template<typename M> +struct WorkForCondVarTimedWait: NoAssign { + int nthread; + condition_variable& test_cv; + M& my_mtx; + WorkForCondVarTimedWait( int n_, condition_variable& cv_, M& mtx_ ) : nthread(n_), test_cv(cv_), my_mtx(mtx_) {} + void operator()( int tid ) const { + tbb::tick_count t1, t2; + + unique_lock<M> ul( my_mtx, defer_lock ); + + ASSERT( n_timed_out==0, NULL ); + ++barrier; + while( barrier<nthread ) __TBB_Yield(); + + // test if a thread times out with wait_for() + for( int i=1; i<10; ++i ) { + tbb::tick_count::interval_t intv((double)i*0.0999 /*seconds*/); + ul.lock(); + cv_status st = no_timeout; + __TBB_TRY { + /** Some version of glibc return EINVAL instead 0 when spurious wakeup occurs on pthread_cond_timedwait() **/ + st = test_cv.wait_for( ul, intv ); + } __TBB_CATCH( std::runtime_error& ) {} + ASSERT( ul, "mutex should have been reacquired" ); + ul.unlock(); + if( st==timeout ) + ++n_timed_out; + } + + ASSERT( n_timed_out>0, "should have been timed-out at least once\n" ); + ++n_done_1; + while( n_done_1<nthread ) __TBB_Yield(); + + for( int i=1; i<10; ++i ) { + tbb::tick_count::interval_t intv((double)i*0.0001 /*seconds*/); + ul.lock(); + __TBB_TRY { + /** Some version of glibc return EINVAL instead 0 when spurious wakeup occurs on pthread_cond_timedwait() **/ + ASSERT( false==test_cv.wait_for( ul, intv, TestPredicateFalse()), "incorrect return value" ); + } __TBB_CATCH( std::runtime_error& ) {} + ASSERT( ul, "mutex should have been reacquired" ); + ul.unlock(); + } + + if( tid==0 ) + n_waiters = 0; + // barrier + ++n_done_2; + while( n_done_2<nthread ) __TBB_Yield(); + + // at this point, we know wait_for() successfully times out. + // so test if a thread blocked on wait_for() could receive a signal before its waiting time elapses. + if( tid==0 ) { + // signaler + n_signaled = 0; + ASSERT( n_waiters==0, NULL ); + ++n_done_2; // open gate 1 + + while( n_waiters<(nthread-1) ) __TBB_Yield(); // wait until all other threads block on cv. flag_1 + + ul.lock(); + test_cv.notify_all(); + n_waiters = 0; + ul.unlock(); + + while( n_done_2<2*nthread ) __TBB_Yield(); + ASSERT( n_signaled>0, "too small an interval?" ); + n_signaled = 0; + + } else { + while( n_done_2<nthread+1 ) __TBB_Yield(); // gate 1 + + // sleeper + tbb::tick_count::interval_t intv((double)2.0 /*seconds*/); + ul.lock(); + ++n_waiters; // raise flag 1/(nthread-1) + t1 = tbb::tick_count::now(); + cv_status st = test_cv.wait_for( ul, intv ); // gate 2 + t2 = tbb::tick_count::now(); + ul.unlock(); + if( st==no_timeout ) { + ++n_signaled; + ASSERT( (t2-t1).seconds()<intv.seconds(), "got a signal after timed-out?" ); + } + } + + ASSERT( n_done==0, NULL ); + ++n_done_2; + + if( tid==0 ) { + ASSERT( n_waiters==0, NULL ); + ++n_done; // open gate 3 + + while( n_waiters<(nthread-1) ) __TBB_Yield(); // wait until all other threads block on cv. + for( int i=0; i<2*short_delay; ++i ) __TBB_Yield(); // give some time to waiters so that all of them in the waitq + ul.lock(); + false_to_true = true; + test_cv.notify_all(); // open gate 4 + ul.unlock(); + + while( n_done<nthread ) __TBB_Yield(); // wait until all other threads wake up. + ASSERT( n_signaled>0, "too small an interval?" ); + } else { + + while( n_done<1 ) __TBB_Yield(); // gate 3 + + tbb::tick_count::interval_t intv((double)2.0 /*seconds*/); + ul.lock(); + ++n_waiters; + // wait_for w/ predciate + t1 = tbb::tick_count::now(); + ASSERT( test_cv.wait_for( ul, intv, TestPredicateFalseToTrue())==true, NULL ); // gate 4 + t2 = tbb::tick_count::now(); + ul.unlock(); + if( (t2-t1).seconds()<intv.seconds() ) + ++n_signaled; + ++n_done; + } + } +}; + +tbb::atomic<int> ticket_for_sleep, ticket_for_wakeup, signaled_ticket, wokeup_ticket; +tbb::atomic<unsigned> n_visit_to_waitq; +unsigned max_waitq_length; + +template<typename M> +struct WorkForCondVarWaitAndNotifyOne: NoAssign { + int nthread; + condition_variable& test_cv; + M& my_mtx; + WorkForCondVarWaitAndNotifyOne( int n_, condition_variable& cv_, M& mtx_ ) : nthread(n_), test_cv(cv_), my_mtx(mtx_) {} + void operator()( int tid ) const { + if( tid&1 ) { + // exercise signal part + while( ticket_for_wakeup<max_ticket ) { + int my_ticket = ++ticket_for_wakeup; // atomically grab the next ticket + if( my_ticket>max_ticket ) + break; + + for( ;; ) { + unique_lock<M> ul( my_mtx, defer_lock ); + ul.lock(); + if( n_waiters>0 && my_ticket<=ticket_for_sleep && my_ticket==(wokeup_ticket+1) ) { + signaled_ticket = my_ticket; + test_cv.notify_one(); + ++n_signaled; + ul.unlock(); + break; + } + ul.unlock(); + __TBB_Yield(); + } + + // give waiters time to go to sleep. + for( int m=0; m<short_delay; ++m ) + __TBB_Yield(); + } + } else { + while( ticket_for_sleep<max_ticket ) { + unique_lock<M> ul( my_mtx, defer_lock ); + ul.lock(); + // exercise wait part + int my_ticket = ++ticket_for_sleep; // grab my ticket + if( my_ticket>max_ticket ) break; + + // each waiter should go to sleep at least once + unsigned nw = ++n_waiters; + for( ;; ) { + // update to max_waitq_length + if( nw>max_waitq_length ) max_waitq_length = nw; + ++n_visit_to_waitq; + test_cv.wait( ul ); + // if( ret==false ) ++n_timedout; + ASSERT( ul, "mutex should have been locked" ); + --n_waiters; + if( signaled_ticket==my_ticket ) { + wokeup_ticket = my_ticket; + break; + } + if( n_waiters>0 ) + test_cv.notify_one(); + nw = ++n_waiters; // update to max_waitq_length occurs above + } + + ul.unlock(); + __TBB_Yield(); // give other threads chance to run. + } + } + ++n_done; + spin_wait_until_eq( n_done, nthread ); + ASSERT( n_signaled==max_ticket, "incorrect number of notifications sent" ); + } +}; + +struct TestPredicate1 { + int target; + TestPredicate1( int i_ ) : target(i_) {} + bool operator()( ) { return signaled_ticket==target; } +}; + +template<typename M> +struct WorkForCondVarWaitPredAndNotifyAll: NoAssign { + int nthread; + condition_variable& test_cv; + M& my_mtx; + int multiple; + WorkForCondVarWaitPredAndNotifyAll( int n_, condition_variable& cv_, M& mtx_, int m_ ) : + nthread(n_), test_cv(cv_), my_mtx(mtx_), multiple(m_) {} + void operator()( int tid ) const { + if( tid&1 ) { + while( ticket_for_sleep<max_ticket ) { + unique_lock<M> ul( my_mtx, defer_lock ); + // exercise wait part + int my_ticket = ++ticket_for_sleep; // grab my ticket + if( my_ticket>max_ticket ) + break; + + ul.lock(); + ++n_visit_to_waitq; + unsigned nw = ++n_waiters; + if( nw>max_waitq_length ) max_waitq_length = nw; + test_cv.wait( ul, TestPredicate1( my_ticket ) ); + wokeup_ticket = my_ticket; + --n_waiters; + ASSERT( ul, "mutex should have been locked" ); + ul.unlock(); + + __TBB_Yield(); // give other threads chance to run. + } + } else { + // exercise signal part + while( ticket_for_wakeup<max_ticket ) { + int my_ticket = ++ticket_for_wakeup; // atomically grab the next ticket + if( my_ticket>max_ticket ) + break; + + for( ;; ) { + unique_lock<M> ul( my_mtx ); + if( n_waiters>0 && my_ticket<=ticket_for_sleep && my_ticket==(wokeup_ticket+1) ) { + signaled_ticket = my_ticket; + test_cv.notify_all(); + ++n_signaled; + ul.unlock(); + break; + } + ul.unlock(); + __TBB_Yield(); + } + + // give waiters time to go to sleep. + for( int m=0; m<long_delay*multiple; ++m ) + __TBB_Yield(); + } + } + ++n_done; + spin_wait_until_eq( n_done, nthread ); + ASSERT( n_signaled==max_ticket, "incorrect number of notifications sent" ); + } +}; + +void InitGlobalCounters() +{ + ticket_for_sleep = ticket_for_wakeup = signaled_ticket = wokeup_ticket = 0; + n_waiters = 0; + n_signaled = 0; + n_done = n_done_1 = n_done_2 = 0; + n_visit_to_waitq = 0; + n_timed_out = 0; +} + +template<typename M> +void TestConditionVariable( const char* name, int nthread ) +{ + REMARK("testing %s in TestConditionVariable\n",name); + Counter<M> counter; + M mtx; + + ASSERT( nthread>1, "at least two threads are needed for testing condition_variable" ); + REMARK(" - constructor\n" ); + // Test constructor. + { + condition_variable cv1; +#if _WIN32||_WIN64 + condition_variable::native_handle_type handle = cv1.native_handle(); + ASSERT( uintptr_t(&handle->cv_event)==uintptr_t(&handle->cv_native), NULL ); +#endif + M mtx1; + barrier = 0; + NativeParallelFor( 2, WorkForCondVarCtor<M>( cv1, mtx1 ) ); + } + + REMARK(" - destructor\n" ); + // Test destructor. + { + M mtx2; + test_cv = NULL; + n_waiters = 0; + NativeParallelFor( nthread, WorkForCondVarDtor<M>( nthread, mtx2 ) ); + } + + REMARK(" - timed_wait (i.e., wait_for)\n"); + // Test timed wait. + { + condition_variable cv_tw; + M mtx_tw; + barrier = 0; + InitGlobalCounters(); + int nthr = nthread>4?4:nthread; + NativeParallelFor( nthr, WorkForCondVarTimedWait<M>( nthr, cv_tw, mtx_tw ) ); + } + + REMARK(" - wait with notify_one\n"); + // Test wait and notify_one + do { + condition_variable cv3; + M mtx3; + InitGlobalCounters(); + NativeParallelFor( nthread, WorkForCondVarWaitAndNotifyOne<M>( nthread, cv3, mtx3 ) ); + } while( n_visit_to_waitq==0 || max_waitq_length==0 ); + + REMARK(" - predicated wait with notify_all\n"); + // Test wait_pred and notify_all + int delay_multiple = 1; + do { + condition_variable cv4; + M mtx4; + InitGlobalCounters(); + NativeParallelFor( nthread, WorkForCondVarWaitPredAndNotifyAll<M>( nthread, cv4, mtx4, delay_multiple ) ); + if( max_waitq_length<unsigned(nthread/2) ) + ++delay_multiple; + } while( n_visit_to_waitq<=0 || max_waitq_length<unsigned(nthread/2) ); +} + +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN +static tbb::atomic<int> err_count; + +#define TRY_AND_CATCH_RUNTIME_ERROR(op,msg) \ + try { \ + op; \ + ++err_count; \ + } catch( std::runtime_error& e ) {ASSERT( strstr(e.what(), msg) , NULL );} catch(...) {++err_count;} + +template<typename M> +void TestUniqueLockException( const char * name ) { + REMARK("testing %s TestUniqueLockException\n",name); + M mtx; + unique_lock<M> ul_0; + err_count = 0; + + TRY_AND_CATCH_RUNTIME_ERROR( ul_0.lock(), "Operation not permitted" ); + TRY_AND_CATCH_RUNTIME_ERROR( ul_0.try_lock(), "Operation not permitted" ); + + unique_lock<M> ul_1( mtx ); + + TRY_AND_CATCH_RUNTIME_ERROR( ul_1.lock(), "Resource deadlock" ); + TRY_AND_CATCH_RUNTIME_ERROR( ul_1.try_lock(), "Resource deadlock" ); + + ul_1.unlock(); + TRY_AND_CATCH_RUNTIME_ERROR( ul_1.unlock(), "Operation not permitted" ); + + ASSERT( !err_count, "Some exceptions are not thrown or incorrect ones are thrown" ); +} + +template<typename M> +void TestConditionVariableException( const char * name ) { + REMARK("testing %s in TestConditionVariableException; yet to be implemented\n",name); +} +#endif /* TBB_USE_EXCEPTIONS */ + +template<typename Mutex, typename RecursiveMutex> +void DoCondVarTest() +{ +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestUniqueLockMoveConstructorAndAssignOp<Mutex>(); + TestUniqueLockMoveConstructorAndAssignOp<RecursiveMutex>(); +#endif + + for( int p=MinThread; p<=MaxThread; ++p ) { + REMARK( "testing with %d threads\n", p ); + TestLocks<Mutex>( "mutex", p ); + TestLocks<RecursiveMutex>( "recursive_mutex", p ); + + if( p<=1 ) continue; + + // for testing condition_variable, at least one sleeper and one notifier are needed + TestConditionVariable<Mutex>( "mutex", p ); + } +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + REPORT("Known issue: exception handling tests are skipped.\n"); +#elif TBB_USE_EXCEPTIONS + TestUniqueLockException<Mutex>( "mutex" ); + TestUniqueLockException<RecursiveMutex>( "recursive_mutex" ); + TestConditionVariableException<Mutex>( "mutex" ); +#endif /* TBB_USE_EXCEPTIONS */ +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_container_move_support.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_container_move_support.h new file mode 100644 index 00000000..38a0f980 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_container_move_support.h @@ -0,0 +1,897 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_test_container_move_support_H +#define __TBB_test_container_move_support_H + +#include "harness.h" +#include "harness_assert.h" +#include "harness_allocator.h" +#include "harness_state_trackable.h" + +#include "tbb/atomic.h" +#include "tbb/aligned_space.h" +#include "tbb/internal/_allocator_traits.h" + +#include <stdexcept> +#include <string> +#include <functional> + +tbb::atomic<size_t> FooCount; +size_t MaxFooCount = 0; + +//! Exception for concurrent_container +class Foo_exception : public std::bad_alloc { +public: + virtual const char *what() const throw() __TBB_override { return "out of Foo limit"; } + virtual ~Foo_exception() throw() {} +}; + +struct FooLimit { + FooLimit(){ + if(MaxFooCount && FooCount >= MaxFooCount) + __TBB_THROW( Foo_exception() ); + } +}; + +static const intptr_t initial_value_of_bar = 42; + + +struct Foo : FooLimit, Harness::StateTrackable<true>{ + typedef Harness::StateTrackable<true> StateTrackable; + intptr_t my_bar; +public: + bool is_valid_or_zero() const{ + return is_valid()||(state==ZeroInitialized && !my_bar); + } + intptr_t& zero_bar(){ + ASSERT( is_valid_or_zero(), NULL ); + return my_bar; + } + intptr_t zero_bar() const{ + ASSERT( is_valid_or_zero(), NULL ); + return my_bar; + } + intptr_t& bar(){ + ASSERT( is_valid(), NULL ); + return my_bar; + } + intptr_t bar() const{ + ASSERT( is_valid(), NULL ); + return my_bar; + } + operator intptr_t() const{ + return this->bar(); + } + Foo( intptr_t barr ): StateTrackable(0){ + my_bar = barr; + FooCount++; + } + Foo(){ + my_bar = initial_value_of_bar; + FooCount++; + } + Foo( const Foo& foo ): FooLimit(), StateTrackable(foo){ + my_bar = foo.my_bar; + FooCount++; + } +#if __TBB_CPP11_RVALUE_REF_PRESENT + Foo( Foo&& foo ): FooLimit(), StateTrackable(std::move(foo)){ + my_bar = foo.my_bar; + //TODO: consider not using constant here, instead something like ~my_bar + foo.my_bar = -1; + FooCount++; + } +#endif + ~Foo(){ + my_bar = ~initial_value_of_bar; + if(state != ZeroInitialized) --FooCount; + } + friend bool operator==(const int &lhs, const Foo &rhs) { + ASSERT( rhs.is_valid_or_zero(), "comparing invalid objects ?" ); + return lhs == rhs.my_bar; + } + friend bool operator==(const Foo &lhs, const int &rhs) { + ASSERT( lhs.is_valid_or_zero(), "comparing invalid objects ?" ); + return lhs.my_bar == rhs; + } + friend bool operator==(const Foo &lhs, const Foo &rhs) { + ASSERT( lhs.is_valid_or_zero(), "comparing invalid objects ?" ); + ASSERT( rhs.is_valid_or_zero(), "comparing invalid objects ?" ); + return lhs.my_bar == rhs.my_bar; + } + friend bool operator<(const Foo &lhs, const Foo &rhs) { + ASSERT( lhs.is_valid_or_zero(), "comparing invalid objects ?" ); + ASSERT( rhs.is_valid_or_zero(), "comparing invalid objects ?" ); + return lhs.my_bar < rhs.my_bar; + } + bool is_const() const {return true;} + bool is_const() {return false;} +protected: + char reserve[1]; + Foo& operator=( const Foo& x ) { + StateTrackable::operator=(x); + my_bar = x.my_bar; + return *this; + } +#if __TBB_CPP11_RVALUE_REF_PRESENT + Foo& operator=( Foo&& x ) { + ASSERT( x.is_valid_or_zero(), "bad source for assignment" ); + ASSERT( is_valid_or_zero(), NULL ); + StateTrackable::operator=(std::move(x)); + my_bar = x.my_bar; + x.my_bar = -1; + return *this; + } +#endif +}; + +struct FooWithAssign: public Foo { + FooWithAssign() : Foo(){} + FooWithAssign(intptr_t barr) : Foo(barr){} + FooWithAssign(FooWithAssign const& f) : Foo(f) {} + FooWithAssign& operator=(FooWithAssign const& f) { return static_cast<FooWithAssign&>(Foo::operator=(f)); } + + +#if __TBB_CPP11_RVALUE_REF_PRESENT + FooWithAssign(FooWithAssign && f) : Foo(std::move(f)) {} + FooWithAssign& operator=(FooWithAssign && f) { return static_cast<FooWithAssign&>(Foo::operator=(std::move(f))); } +#endif +}; + +template<typename FooIteratorType> +class FooIteratorBase { +protected: + intptr_t x_bar; +private: + FooIteratorType& as_derived(){ return *static_cast<FooIteratorType*>(this);} +public: + FooIteratorBase(intptr_t x) { + x_bar = x; + } + FooIteratorType &operator++() { + x_bar++; return as_derived(); + } + FooIteratorType operator++(int) { + FooIteratorType tmp(as_derived()); x_bar++; return tmp; + } + friend bool operator==(const FooIteratorType & lhs, const FooIteratorType & rhs){ return lhs.x_bar == rhs.x_bar; } + friend bool operator!=(const FooIteratorType & lhs, const FooIteratorType & rhs){ return !(lhs == rhs); } +}; + +class FooIterator: public std::iterator<std::input_iterator_tag,FooWithAssign>, public FooIteratorBase<FooIterator> { +public: + FooIterator(intptr_t x): FooIteratorBase<FooIterator>(x) {} + + FooWithAssign operator*() { + return FooWithAssign(x_bar); + } +}; + +class FooPairIterator: public std::iterator<std::input_iterator_tag, std::pair<FooWithAssign,FooWithAssign> >, public FooIteratorBase<FooPairIterator> { +public: + FooPairIterator(intptr_t x): FooIteratorBase<FooPairIterator>(x) {} + + std::pair<FooWithAssign,FooWithAssign> operator*() { + FooWithAssign foo; foo.bar() = x_bar; + + return std::make_pair(foo, foo); + } +}; + +namespace FooTests{ + template<typename Foo_type> + void TestDefaultConstructor(){ + Foo_type src; + ASSERT(src.state == Foo::DefaultInitialized, "incorrect state for default constructed Foo (derived) ?"); + } + + template<typename Foo_type> + void TestDirectConstructor(){ + Foo_type src(1); + ASSERT(src.state == Foo::DirectInitialized, "incorrect state for direct constructed Foo (derived) ?"); + } + + template<typename Foo_type> + void TestCopyConstructor(){ + Foo_type src; + Foo_type dst(src); + ASSERT(dst.state == Foo::CopyInitialized, "incorrect state for Copy constructed Foo ?"); + } + + template<typename Foo_type> + void TestAssignOperator(){ + Foo_type src; + Foo_type dst; + dst = (src); + + ASSERT(dst.state == Foo::Assigned, "incorrect state for Assigned Foo ?"); + } + +#if __TBB_CPP11_RVALUE_REF_PRESENT + template<typename Foo_type> + void TestMoveConstructor(){ + Foo_type src; + Foo_type dst(std::move(src)); + ASSERT(dst.state == Foo::MoveInitialized, "incorrect state for Move constructed Foo ?"); + ASSERT(src.state == Foo::MovedFrom, "incorrect state for Move from Foo ?"); + } + + template<typename Foo_type> + void TestMoveAssignOperator(){ + Foo_type src; + Foo_type dst; + dst = std::move(src); + + ASSERT(dst.state == Foo::MoveAssigned, "incorrect state for Move Assigned Foo ?"); + ASSERT(src.state == Foo::MovedFrom, "incorrect state for Moved from Foo ?"); + } +#if TBB_USE_EXCEPTIONS + void TestMoveConstructorException(); +#endif //TBB_USE_EXCEPTIONS +#endif //__TBB_CPP11_RVALUE_REF_PRESENT +} + +void TestFoo(){ + using namespace FooTests; + TestDefaultConstructor<Foo>(); + TestDefaultConstructor<FooWithAssign>(); + TestDirectConstructor<Foo>(); + TestDirectConstructor<FooWithAssign>(); + TestCopyConstructor<Foo>(); + TestCopyConstructor<FooWithAssign>(); + TestAssignOperator<FooWithAssign>(); +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestMoveConstructor<Foo>(); + TestMoveConstructor<FooWithAssign>(); + TestMoveAssignOperator<FooWithAssign>(); +#if TBB_USE_EXCEPTIONS && !__TBB_CPP11_EXCEPTION_IN_STATIC_TEST_BROKEN + TestMoveConstructorException(); +#endif //TBB_USE_EXCEPTIONS +#endif //__TBB_CPP11_RVALUE_REF_PRESENT +} + +//TODO: replace _IN_TEST with separately defined macro IN_TEST(msg,test_name) +#define ASSERT_IN_TEST(p,message,test_name) ASSERT(p, (std::string(test_name) + ": " + message).c_str()); +//TODO: move to harness_assert +#define ASSERT_THROWS_IN_TEST(expression, exception_type, message, test_name) \ + try{ \ + expression; \ + ASSERT_IN_TEST(false, "should throw an exception", test_name); \ + }catch(exception_type &){ \ + }catch(...){ASSERT_IN_TEST(false, "unexpected exception", test_name);} \ + +#define ASSERT_THROWS(expression, exception_type, message) ASSERT_THROWS_IN_TEST(expression, exception_type, message, "") + +template<Harness::StateTrackableBase::StateValue desired_state, bool allow_zero_initialized_state> +bool is_state(Harness::StateTrackable<allow_zero_initialized_state> const& f){ return f.state == desired_state;} + +template<Harness::StateTrackableBase::StateValue desired_state> +struct is_not_state_f { + template <bool allow_zero_initialized_state> + bool operator()(Harness::StateTrackable<allow_zero_initialized_state> const& f){ return !is_state<desired_state>(f);} +}; + +template<Harness::StateTrackableBase::StateValue desired_state> +struct is_state_f { + template <bool allow_zero_initialized_state> + bool operator()(Harness::StateTrackable<allow_zero_initialized_state> const& f){ return is_state<desired_state>(f); } + //TODO: cu_map defines key as a const thus by default it is not moved, instead it is copied. Investigate how std::unordered_map behaves + template<typename T1, typename T2> + bool operator()(std::pair<T1, T2> const& p){ return /*is_state<desired_state>(p.first) && */is_state<desired_state>(p.second); } +}; + +template<typename iterator, typename unary_predicate> +bool all_of(iterator begin, iterator const& end, unary_predicate p){ + for (; begin != end; ++begin){ + if ( !p(*begin)) return false; + } + return true; +} + +template<typename container, typename unary_predicate> +bool all_of(container const& c, unary_predicate p){ + return ::all_of( c.begin(), c.end(), p ); +} + +void TestAllOf(){ + Foo foos[] = {Foo(), Foo(), Foo()}; + ASSERT(::all_of(foos, Harness::end(foos), is_state_f<Foo::DefaultInitialized>()), "all_of returned false while true expected"); + ASSERT(! ::all_of(foos, Harness::end(foos), is_state_f<Foo::CopyInitialized>()), "all_of returned true while false expected "); +} + +template<typename static_counter_allocator_type> +struct track_allocator_memory: NoCopy{ + typedef typename static_counter_allocator_type::counters_t counters_t; + + counters_t previous_state; + const char* const test_name; + track_allocator_memory(const char* a_test_name): test_name(a_test_name) { static_counter_allocator_type::init_counters(); } + ~track_allocator_memory(){verify_no_allocator_memory_leaks();} + + void verify_no_allocator_memory_leaks() const{ + ASSERT_IN_TEST( static_counter_allocator_type::items_allocated == static_counter_allocator_type::items_freed, "memory leak?", test_name ); + ASSERT_IN_TEST( static_counter_allocator_type::allocations == static_counter_allocator_type::frees, "memory leak?", test_name ); + } + void save_allocator_counters(){ previous_state = static_counter_allocator_type::counters(); } + void verify_no_more_than_x_memory_items_allocated(size_t expected_number_of_items_to_allocate){ + counters_t now = static_counter_allocator_type::counters(); + ASSERT_IN_TEST( (now.items_allocated - previous_state.items_allocated) <= expected_number_of_items_to_allocate, "More then excepted memory allocated ?", test_name ); + } +}; + +#include <vector> +template<int line_n> +struct track_foo_count: NoCopy{ + bool active; + size_t previous_state; + const char* const test_name; + track_foo_count(const char* a_test_name): active(true), previous_state(FooCount), test_name(a_test_name) { } + ~track_foo_count(){ + if (active){ + this->verify_no_undestroyed_foo_left_and_dismiss(); + } + } + + //TODO: ideally in most places this check should be replaced with "no foo created or destroyed" + //TODO: deactivation of the check seems like a hack + void verify_no_undestroyed_foo_left_and_dismiss() { + ASSERT_IN_TEST( FooCount == previous_state, "Some instances of Foo were not destroyed ?", test_name ); + active = false; + } +}; + +//TODO: inactive mode in these limiters is a temporary workaround for usage in exception type loop of TestException + +struct limit_foo_count_in_scope: NoCopy{ + size_t previous_state; + bool active; + limit_foo_count_in_scope(size_t new_limit, bool an_active = true): previous_state(MaxFooCount), active(an_active) { + if (active){ + MaxFooCount = new_limit; + } + } + ~limit_foo_count_in_scope(){ + if (active) { + MaxFooCount = previous_state; + } + } +}; + +template<typename static_counter_allocator_type> +struct limit_allocated_items_in_scope: NoCopy{ + size_t previous_state; + bool active; + limit_allocated_items_in_scope(size_t new_limit, bool an_active = true) : previous_state(static_counter_allocator_type::max_items), active(an_active) { + if (active){ + static_counter_allocator_type::set_limits(new_limit); + } + } + ~limit_allocated_items_in_scope(){ + if (active) { + static_counter_allocator_type::set_limits(previous_state); + } + } +}; + +struct default_container_traits{ + template <typename container_type, typename iterator_type> + static container_type& construct_container(tbb::aligned_space<container_type> & storage, iterator_type begin, iterator_type end){ + new (storage.begin()) container_type(begin, end); + return *storage.begin(); + } + + template <typename container_type, typename iterator_type, typename allocator_type> + static container_type& construct_container(tbb::aligned_space<container_type> & storage, iterator_type begin, iterator_type end, allocator_type const& a){ + new (storage.begin()) container_type(begin, end, a); + return *storage.begin(); + } +}; + +struct memory_locations { + std::vector<const void*> locations; + + template <typename container_type> + memory_locations(container_type const& source) : locations(source.size()){ + for (typename container_type::const_iterator it = source.begin(); it != source.end(); ++it){locations[std::distance(source.begin(), it)] = & *it;} + } + + template <typename container_t> + bool content_location_unchanged(container_t const& dst){ + struct is_same_location{ + static bool compare(typename container_t::value_type const& v, const void* location){ return &v == location;} + }; + + return std::equal(dst.begin(), dst.end(), locations.begin(), &is_same_location::compare); + } + + template <typename container_t> + bool content_location_changed(container_t const& dst){ + struct is_not_same_location{ + static bool compare(typename container_t::value_type const& v, const void* location){ return &v != location;} + }; + + return std::equal(dst.begin(), dst.end(), locations.begin(), &is_not_same_location::compare); + } + +}; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +#include <algorithm> +void TestMemoryLocaionsHelper(){ + const size_t test_sequence_len = 15; + std::vector<char> source(test_sequence_len, 0); + std::generate_n(source.begin(), source.size(), Harness::FastRandomBody<char>(1)); + + memory_locations source_memory_locations((source)); + + std::vector<char> copy((source)); + ASSERT(source_memory_locations.content_location_changed(copy), ""); + + std::vector<char> alias(std::move(source)); + ASSERT(source_memory_locations.content_location_unchanged(alias), ""); +} +namespace FooTests{ +#if TBB_USE_EXCEPTIONS + void TestMoveConstructorException(){ + Foo src; + const Foo::StateValue source_state_before = src.state; + ASSERT_THROWS_IN_TEST( + { + limit_foo_count_in_scope foo_limit(FooCount); + Foo f1(std::move(src)); + }, + std::bad_alloc, "", "TestLimitInstancesNumber" + ); + ASSERT(source_state_before == src.state, "state of source changed while should not?"); + } +#endif //TBB_USE_EXCEPTIONS +} + +template<typename container_traits, typename allocator_t> +struct move_fixture : NoCopy{ + typedef typename allocator_t::value_type element_type; + typedef typename container_traits:: template apply<element_type, allocator_t>::type container_t; + typedef typename container_traits::init_iterator_type init_iterator_type; + enum {default_container_size = 100}; + const size_t container_size; + tbb::aligned_space<container_t> source_storage; + container_t & source; + //check that location of _all_ elements of container under test is changed/unchanged + memory_locations locations; + + ~move_fixture(){ + source_storage.begin()->~container_t(); + } + + const char* const test_name; + move_fixture(const char* a_test_name, size_t a_container_size = default_container_size ) + : container_size(a_container_size) + , source(container_traits::construct_container(source_storage, init_iterator_type(0), init_iterator_type(container_size))) + , locations(source) + , test_name(a_test_name) + { + init("move_fixture::move_fixture()"); + } + + move_fixture(const char* a_test_name, allocator_t const& a, size_t a_container_size = default_container_size) + : container_size(a_container_size) + , source(container_traits::construct_container(source_storage, init_iterator_type(0), init_iterator_type(container_size), a)) + , locations(source) + , test_name(a_test_name) + { + init("move_fixture::move_fixture(allocator_t const& a)"); + } + + void init(const std::string& ctor_name){ + verify_size(source, ctor_name.c_str()); + verify_content_equal_to_source(source, "did not properly initialized source? Or can not check container for equality with expected ?: " + ctor_name); + verify_size(locations.locations, "move_fixture:init "); + } + + bool content_location_unchanged(container_t const& dst){ + return locations.content_location_unchanged(dst); + } + + bool content_location_changed(container_t const& dst){ + return locations.content_location_changed(dst); + } + + template<typename container_type> + void verify_size(container_type const& dst, const char* a_test_name){ + ASSERT_IN_TEST(container_size == dst.size(), "Did not construct all the elements or allocate enough memory?, while should ?", a_test_name); + } + + void verify_content_equal_to_source(container_t const& dst, const std::string& msg){ + ASSERT_IN_TEST( container_traits::equal(dst, init_iterator_type(0), init_iterator_type(container_size)), msg.c_str(), test_name); + } + + void verify_content_equal_to_source(container_t const& dst){ + verify_content_equal_to_source(dst, "content changed during move/copy ?"); + } + + void verify_content_equal_to_source(container_t const& dst, size_t number_of_constructed_items){ + ASSERT_IN_TEST(number_of_constructed_items <= dst.size(), "incorrect test expectation/input parameters?", test_name); + ASSERT_IN_TEST(std::equal(dst.begin(), dst.begin() + number_of_constructed_items, init_iterator_type(0)), "content changed during move/copy ?", test_name); + } + + //TODO: better name ? e.g. "content_was_stolen" + void verify_content_shallow_moved(container_t const& dst){ + verify_size(dst, test_name); + ASSERT_IN_TEST(content_location_unchanged(dst), "container move constructor actually changed element locations, while should not", test_name); + ASSERT_IN_TEST(source.empty(), "Moved from container instance should not contain any elements", test_name); + verify_content_equal_to_source(dst); + } + + //TODO: better name ? e.g. "element move" + void verify_content_deep_moved(container_t const& dst){ + verify_size(dst, test_name); + ASSERT_IN_TEST(content_location_changed(dst), "container actually did not changed element locations for unequal allocators, while should", test_name); + ASSERT_IN_TEST(all_of(dst, is_state_f<Foo::MoveInitialized>()), "container did not move construct some elements?", test_name); + ASSERT_IN_TEST(all_of(source, is_state_f<Foo::MovedFrom>()), "container did not move all the elements?", test_name); + verify_content_equal_to_source(dst); + } + + void verify_part_of_content_deep_moved(container_t const& dst, size_t number_of_constructed_items){ + ASSERT_IN_TEST(content_location_changed(dst), "Vector actually did not changed element locations for unequal allocators, while should", test_name); + ASSERT_IN_TEST(::all_of(dst.begin(), dst.begin() + number_of_constructed_items, is_state_f<Foo::MoveInitialized>()), "Vector did not move construct some elements?", test_name); + if (dst.size() != number_of_constructed_items) { + ASSERT_IN_TEST(::all_of(dst.begin() + number_of_constructed_items, dst.end(), is_state_f<Foo::ZeroInitialized>()), "Failed to zero-initialize items left not constructed after the exception?", test_name ); + } + verify_content_equal_to_source(dst, number_of_constructed_items); + + ASSERT_IN_TEST(::all_of(source.begin(), source.begin() + number_of_constructed_items, is_state_f<Foo::MovedFrom>()), "Vector did not move all the elements?", test_name); + ASSERT_IN_TEST(::all_of(source.begin() + number_of_constructed_items, source.end(), is_not_state_f<Foo::MovedFrom>()), "Vector changed elements in source after exception point?", test_name); + } +}; + + +template <typename T, typename pocma = Harness::false_type> +struct arena_allocator_fixture : NoCopy{ + typedef arena<T, pocma> allocator_t; + typedef typename allocator_t::arena_data_t arena_data_t; + + std::vector<tbb::aligned_space<T, 1> > storage; + arena_data_t arena_data; + allocator_t allocator; + + arena_allocator_fixture(size_t size_to_allocate) + : storage(size_to_allocate) + , arena_data((*storage.begin()).begin(), storage.size()) + , allocator(arena_data) + {} +}; + +//TODO: add ability to inject debug_allocator into stateful_allocator_fixture::allocator_t +template <typename T, typename pocma = Harness::false_type> +struct two_memory_arenas_fixture : NoCopy{ + typedef arena_allocator_fixture<T, pocma> arena_fixture_t; + typedef typename arena_fixture_t::allocator_t allocator_t; + + arena_fixture_t source_arena_fixture; + arena_fixture_t dst_arena_fixture; + + allocator_t& source_allocator; + allocator_t& dst_allocator; + + const char* test_name; + + two_memory_arenas_fixture(size_t size_to_allocate, const char* a_test_name) + : source_arena_fixture(size_to_allocate) + , dst_arena_fixture(size_to_allocate) + , source_allocator(source_arena_fixture.allocator) + , dst_allocator(dst_arena_fixture.allocator) + , test_name(a_test_name) + { + ASSERT_IN_TEST(&*source_arena_fixture.storage.begin() != &*dst_arena_fixture.storage.begin(), "source and destination arena instances should use different memory regions", test_name); + ASSERT_IN_TEST(source_allocator != dst_allocator, "arenas using different memory regions should not compare equal", test_name); + ASSERT_IN_TEST(pocma::value == tbb::internal::allocator_traits<allocator_t>::propagate_on_container_move_assignment::value, "This test require proper allocator_traits support", test_name); + + //Some ISO C++11 allocator requirements enforcement: + allocator_t source_allocator_copy(source_allocator), dst(dst_allocator); + allocator_t source_previous_state(source_allocator); + ASSERT_IN_TEST(source_previous_state == source_allocator, "Copy of allocator should compare equal to it's source", test_name); + dst = std::move(source_allocator_copy); + ASSERT_IN_TEST(dst == source_previous_state, "Move initialized instance of allocator should compare equal to it's source state before movement", test_name); + } + + void verify_allocator_was_moved(const allocator_t& result_allocator){ + //TODO: add assert that allocator move constructor/assignment operator was called + ASSERT_IN_TEST(result_allocator == source_allocator, "allocator was not moved ?", test_name); + ASSERT_IN_TEST(result_allocator != dst_allocator, "allocator was not moved ?", test_name); + } + +// template <typename any_allocator_t> +// void verify_allocator_was_moved(const any_allocator_t& ){} +}; + +template <typename pocma = Harness::false_type> +struct std_stateful_allocator : NoCopy { + typedef stateful_allocator<FooWithAssign, pocma> allocator_t; + + allocator_t source_allocator; + allocator_t dst_allocator; + + const char* test_name; + + std_stateful_allocator(size_t , const char* a_test_name) + : test_name(a_test_name) + {} + + template <typename any_allocator_t> + void verify_allocator_was_moved(const any_allocator_t& ){} + +}; + +template<typename container_traits, typename pocma = Harness::false_type, typename T = FooWithAssign> +struct default_stateful_fixture_make_helper{ +// typedef std_stateful_allocator<pocma> allocator_fixture_t; + typedef two_memory_arenas_fixture<T, pocma> allocator_fixture_t; + typedef static_shared_counting_allocator<Harness::int_to_type<__LINE__>, typename allocator_fixture_t::allocator_t, std::size_t> allocator_t; + + typedef move_fixture<container_traits, allocator_t> move_fixture_t; + typedef track_allocator_memory<allocator_t> no_leaks_t; + typedef track_foo_count<__LINE__> no_foo_leaks_in_fixture_t; + typedef track_foo_count<__LINE__> no_foo_leaks_in_test_t; + + struct default_stateful_fixture : no_leaks_t, private no_foo_leaks_in_fixture_t, allocator_fixture_t, move_fixture_t, no_foo_leaks_in_test_t { + + default_stateful_fixture(const char* a_test_name) + : no_leaks_t(a_test_name) + , no_foo_leaks_in_fixture_t(a_test_name) + //TODO: calculate needed size more accurately + //allocate twice more storage to handle case when copy constructor called instead of move one + , allocator_fixture_t(2*4 * move_fixture_t::default_container_size, a_test_name) + , move_fixture_t(a_test_name, allocator_fixture_t::source_allocator) + , no_foo_leaks_in_test_t(a_test_name) + { + no_leaks_t::save_allocator_counters(); + } + + void verify_no_more_than_x_memory_items_allocated(){ + no_leaks_t::verify_no_more_than_x_memory_items_allocated(container_traits::expected_number_of_items_to_allocate_for_steal_move); + } + using no_foo_leaks_in_test_t::verify_no_undestroyed_foo_left_and_dismiss; + typedef typename move_fixture_t::container_t::allocator_type allocator_t; + }; + + typedef default_stateful_fixture type; +}; + +template<typename container_traits> +void TestMoveConstructorSingleArgument(){ + typedef typename default_stateful_fixture_make_helper<container_traits>::type fixture_t; + typedef typename fixture_t::container_t container_t; + + fixture_t fixture("TestMoveConstructorSingleArgument"); + + container_t dst(std::move(fixture.source)); + + fixture.verify_content_shallow_moved(dst); + fixture.verify_allocator_was_moved(dst.get_allocator()); + fixture.verify_no_more_than_x_memory_items_allocated(); + fixture.verify_no_undestroyed_foo_left_and_dismiss(); +} + +template<typename container_traits> +void TestMoveConstructorWithEqualAllocator(){ + typedef typename default_stateful_fixture_make_helper<container_traits>::type fixture_t; + typedef typename fixture_t::container_t container_t; + + fixture_t fixture("TestMoveConstructorWithEqualAllocator"); + + container_t dst(std::move(fixture.source), fixture.source.get_allocator()); + + fixture.verify_content_shallow_moved(dst); + fixture.verify_no_more_than_x_memory_items_allocated(); + fixture.verify_no_undestroyed_foo_left_and_dismiss(); +} + +template<typename container_traits> +void TestMoveConstructorWithUnEqualAllocator(){ + typedef typename default_stateful_fixture_make_helper<container_traits>::type fixture_t; + typedef typename fixture_t::container_t container_t; + + fixture_t fixture("TestMoveConstructorWithUnEqualAllocator"); + + container_t dst(std::move(fixture.source), fixture.dst_allocator); + + fixture.verify_content_deep_moved(dst); +} + +template<typename container_traits> +void TestMoveConstructor(){ + TestMoveConstructorSingleArgument<container_traits>(); + TestMoveConstructorWithEqualAllocator<container_traits>(); + TestMoveConstructorWithUnEqualAllocator<container_traits>(); +} + +template<typename container_traits> +void TestMoveAssignOperatorPOCMAStateful(){ + typedef typename default_stateful_fixture_make_helper<container_traits, Harness::true_type>::type fixture_t; + typedef typename fixture_t::container_t container_t; + + fixture_t fixture("TestMoveAssignOperatorPOCMAStateful"); + + container_t dst(fixture.dst_allocator); + + fixture.save_allocator_counters(); + + dst = std::move(fixture.source); + + fixture.verify_content_shallow_moved(dst); + fixture.verify_allocator_was_moved(dst.get_allocator()); + fixture.verify_no_more_than_x_memory_items_allocated(); + fixture.verify_no_undestroyed_foo_left_and_dismiss(); +} + +template<typename container_traits> +void TestMoveAssignOperatorPOCMANonStateful(){ + typedef std::allocator<FooWithAssign> allocator_t; + + typedef move_fixture<container_traits, allocator_t> fixture_t; + typedef typename fixture_t::container_t container_t; + + fixture_t fixture("TestMoveAssignOperatorPOCMANonStateful"); + + ASSERT(fixture.source.get_allocator() == allocator_t(), "Incorrect test setup: allocator is stateful while should not?"); + + container_t dst; + dst = std::move(fixture.source); + + fixture.verify_content_shallow_moved(dst); + //TODO: add an assert that allocator was "moved" when POCMA is set +} + +template<typename container_traits> +void TestMoveAssignOperatorNotPOCMAWithUnEqualAllocator(){ + typedef typename default_stateful_fixture_make_helper<container_traits>::type fixture_t; + typedef typename fixture_t::container_t container_t; + + fixture_t fixture("TestMoveAssignOperatorNotPOCMAWithUnEqualAllocator"); + + container_t dst(fixture.dst_allocator); + dst = std::move(fixture.source); + + fixture.verify_content_deep_moved(dst); +} + +template<typename container_traits> +void TestMoveAssignOperatorNotPOCMAWithEqualAllocator(){ + typedef typename default_stateful_fixture_make_helper<container_traits, Harness::false_type>::type fixture_t; + typedef typename fixture_t::container_t container_t; + fixture_t fixture("TestMoveAssignOperatorNotPOCMAWithEqualAllocator"); + + container_t dst(fixture.source_allocator); + ASSERT(fixture.source.get_allocator() == dst.get_allocator(), "Incorrect test setup: allocators are not equal while should be?"); + + fixture.save_allocator_counters(); + + dst = std::move(fixture.source); + + fixture.verify_content_shallow_moved(dst); + fixture.verify_no_more_than_x_memory_items_allocated(); + fixture.verify_no_undestroyed_foo_left_and_dismiss(); +} + +template<typename container_traits> +void TestMoveAssignOperator(){ +#if __TBB_ALLOCATOR_TRAITS_PRESENT + TestMoveAssignOperatorPOCMANonStateful<container_traits>(); + TestMoveAssignOperatorPOCMAStateful<container_traits>(); +#endif + TestMoveAssignOperatorNotPOCMAWithUnEqualAllocator<container_traits>(); + TestMoveAssignOperatorNotPOCMAWithEqualAllocator<container_traits>(); +} + +template<typename container_traits> +void TestConstructorWithMoveIterators(){ + typedef typename default_stateful_fixture_make_helper<container_traits>::type fixture_t; + typedef typename fixture_t::container_t container_t; + + fixture_t fixture("TestConstructorWithMoveIterators"); + + container_t dst(std::make_move_iterator(fixture.source.begin()), std::make_move_iterator(fixture.source.end()), fixture.dst_allocator); + + fixture.verify_content_deep_moved(dst); +} + +template<typename container_traits> +void TestAssignWithMoveIterators(){ + typedef typename default_stateful_fixture_make_helper<container_traits>::type fixture_t; + typedef typename fixture_t::container_t container_t; + + fixture_t fixture("TestAssignWithMoveIterators"); + + container_t dst(fixture.dst_allocator); + dst.assign(std::make_move_iterator(fixture.source.begin()), std::make_move_iterator(fixture.source.end())); + + fixture.verify_content_deep_moved(dst); +} + +#if TBB_USE_EXCEPTIONS +template<typename container_traits> +void TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorMemoryFailure(){ + typedef typename default_stateful_fixture_make_helper<container_traits>::type fixture_t; + typedef typename fixture_t::container_t container_t; + typedef typename container_t::allocator_type allocator_t; + const char* test_name = "TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorMemoryFailure"; + fixture_t fixture(test_name); + + limit_allocated_items_in_scope<allocator_t> allocator_limit(allocator_t::items_allocated + fixture.container_size/4); + ASSERT_THROWS_IN_TEST(container_t dst(std::move(fixture.source), fixture.dst_allocator), std::bad_alloc, "", test_name); +} + +//TODO: add tests that verify that stealing move constructors/assign operators does not throw exceptions +template<typename container_traits> +void TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorExceptionInElementCtor(){ + typedef typename default_stateful_fixture_make_helper<container_traits>::type fixture_t; + typedef typename fixture_t::container_t container_t; + + const char* test_name = "TestExceptionSafetyGuaranteesMoveConstructorWithUnEqualAllocatorExceptionInElementCtor"; + fixture_t fixture(test_name); + + limit_foo_count_in_scope foo_limit(FooCount + fixture.container_size/4); + ASSERT_THROWS_IN_TEST(container_t dst(std::move(fixture.source), fixture.dst_allocator), std::bad_alloc, "", test_name); +} +#endif /* TBB_USE_EXCEPTIONS */ +#endif//__TBB_CPP11_RVALUE_REF_PRESENT + +namespace helper_stuff_tests { + void inline TestArena(){ + typedef int arena_element; + + arena_element arena_storage[10] = {0}; + typedef arena<arena_element> arena_t; + + arena_t::arena_data_t arena_data(arena_storage,Harness::array_length(arena_storage)); + arena_t a(arena_data); + + ASSERT(a.allocate(1) == arena_storage, ""); + ASSERT(a.allocate(2) == &arena_storage[1], ""); + ASSERT(a.allocate(2) == &arena_storage[2+1], ""); + } + + template<typename static_counting_allocator_type> + void inline TestStaticCountingAllocatorRebound(){ + static_counting_allocator_type::set_limits(1); + typedef typename static_counting_allocator_type:: template rebind<std::pair<int,int> >::other rebound_type; + ASSERT(rebound_type::max_items == static_counting_allocator_type::max_items, "rebound allocator should use the same limits"); + static_counting_allocator_type::set_limits(0); + } + + void inline TestStatefulAllocator(){ + stateful_allocator<int> a1,a2; + stateful_allocator<int> copy_of_a1(a1); + ASSERT(a1 != a2,"non_equal_allocator are designed to simulate stateful allocators"); + ASSERT(copy_of_a1 == a1,""); + } +} +struct TestHelperStuff{ + TestHelperStuff(){ + using namespace helper_stuff_tests; + TestFoo(); + TestAllOf(); + TestArena(); + TestStaticCountingAllocatorRebound<static_shared_counting_allocator<int, arena<int> > >(); + TestStatefulAllocator(); +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestMemoryLocaionsHelper(); +#endif //__TBB_CPP11_RVALUE_REF_PRESENT + } +}; +static TestHelperStuff TestHelperStuff_s; +#endif /* __TBB_test_container_move_support_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_continue_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_continue_node.cpp new file mode 100644 index 00000000..1debba82 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_continue_node.cpp @@ -0,0 +1,568 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#endif + +#include "harness.h" +#include "harness_graph.h" + +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include "test_follows_and_precedes_api.h" + +#define N 1000 +#define MAX_NODES 4 +#define C 8 + +struct empty_no_assign : private NoAssign { + empty_no_assign() {} + empty_no_assign( int ) {} + operator int() { return 0; } +}; + +// A class to use as a fake predecessor of continue_node +struct fake_continue_sender : public tbb::flow::sender<tbb::flow::continue_msg> +{ + typedef tbb::flow::sender<tbb::flow::continue_msg>::successor_type successor_type; + // Define implementations of virtual methods that are abstract in the base class + bool register_successor( successor_type& ) __TBB_override { return false; } + bool remove_successor( successor_type& ) __TBB_override { return false; } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef tbb::flow::sender<tbb::flow::continue_msg>::built_successors_type built_successors_type; + built_successors_type bst; + built_successors_type &built_successors() __TBB_override { return bst; } + void internal_add_built_successor( successor_type &) __TBB_override { } + void internal_delete_built_successor( successor_type &) __TBB_override { } + void copy_successors(successor_list_type &) __TBB_override {} + size_t successor_count() __TBB_override {return 0;} +#endif +}; + +template< typename InputType > +struct parallel_puts : private NoAssign { + + tbb::flow::receiver< InputType > * const my_exe_node; + + parallel_puts( tbb::flow::receiver< InputType > &exe_node ) : my_exe_node(&exe_node) {} + + void operator()( int ) const { + for ( int i = 0; i < N; ++i ) { + // the nodes will accept all puts + ASSERT( my_exe_node->try_put( InputType() ) == true, NULL ); + } + } + +}; + +template< typename OutputType > +void run_continue_nodes( int p, tbb::flow::graph& g, tbb::flow::continue_node< OutputType >& n ) { + fake_continue_sender fake_sender; + for (size_t i = 0; i < N; ++i) { + n.register_predecessor( fake_sender ); + } + + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + std::vector< harness_counting_receiver<OutputType> > receivers(num_receivers, harness_counting_receiver<OutputType>(g)); + harness_graph_executor<tbb::flow::continue_msg, OutputType>::execute_count = 0; + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( n, receivers[r] ); + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(n.successor_count() == (size_t)num_receivers, NULL); + ASSERT(n.predecessor_count() == 0, NULL); + typename tbb::flow::continue_node<OutputType>::successor_list_type my_succs; + typedef typename tbb::flow::continue_node<OutputType>::successor_list_type::iterator sv_iter_type; + n.copy_successors(my_succs); + ASSERT(my_succs.size() == num_receivers, NULL); +#endif + + NativeParallelFor( p, parallel_puts<tbb::flow::continue_msg>(n) ); + g.wait_for_all(); + + // 2) the nodes will receive puts from multiple predecessors simultaneously, + size_t ec = harness_graph_executor<tbb::flow::continue_msg, OutputType>::execute_count; + ASSERT( (int)ec == p, NULL ); + for (size_t r = 0; r < num_receivers; ++r ) { + size_t c = receivers[r].my_count; + // 3) the nodes will send to multiple successors. + ASSERT( (int)c == p, NULL ); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + for(sv_iter_type si=my_succs.begin(); si != my_succs.end(); ++si) { + tbb::flow::remove_edge( n, **si ); + } +#else + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( n, receivers[r] ); + } +#endif + } +} + +template< typename OutputType, typename Body > +void continue_nodes( Body body ) { + for (int p = 1; p < 2*MaxThread; ++p) { + tbb::flow::graph g; + tbb::flow::continue_node< OutputType > exe_node( g, body ); + run_continue_nodes( p, g, exe_node); + exe_node.try_put(tbb::flow::continue_msg()); + tbb::flow::continue_node< OutputType > exe_node_copy( exe_node ); + run_continue_nodes( p, g, exe_node_copy); + } +} + +const size_t Offset = 123; +tbb::atomic<size_t> global_execute_count; + +template< typename OutputType > +struct inc_functor { + + tbb::atomic<size_t> local_execute_count; + inc_functor( ) { local_execute_count = 0; } + inc_functor( const inc_functor &f ) { local_execute_count = f.local_execute_count; } + void operator=(const inc_functor &f) { local_execute_count = f.local_execute_count; } + + OutputType operator()( tbb::flow::continue_msg ) { + ++global_execute_count; + ++local_execute_count; + return OutputType(); + } + +}; + +template< typename OutputType > +void continue_nodes_with_copy( ) { + + for (int p = 1; p < 2*MaxThread; ++p) { + tbb::flow::graph g; + inc_functor<OutputType> cf; + cf.local_execute_count = Offset; + global_execute_count = Offset; + + tbb::flow::continue_node< OutputType > exe_node( g, cf ); + fake_continue_sender fake_sender; + for (size_t i = 0; i < N; ++i) { + exe_node.register_predecessor( fake_sender ); + } + + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + std::vector< harness_counting_receiver<OutputType> > receivers(num_receivers, harness_counting_receiver<OutputType>(g)); + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( exe_node, receivers[r] ); + } + + NativeParallelFor( p, parallel_puts<tbb::flow::continue_msg>(exe_node) ); + g.wait_for_all(); + + // 2) the nodes will receive puts from multiple predecessors simultaneously, + for (size_t r = 0; r < num_receivers; ++r ) { + size_t c = receivers[r].my_count; + // 3) the nodes will send to multiple successors. + ASSERT( (int)c == p, NULL ); + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( exe_node, receivers[r] ); + } + } + + // validate that the local body matches the global execute_count and both are correct + inc_functor<OutputType> body_copy = tbb::flow::copy_body< inc_functor<OutputType> >( exe_node ); + const size_t expected_count = p*MAX_NODES + Offset; + size_t global_count = global_execute_count; + size_t inc_count = body_copy.local_execute_count; + ASSERT( global_count == expected_count && global_count == inc_count, NULL ); + g.reset(tbb::flow::rf_reset_bodies); + body_copy = tbb::flow::copy_body< inc_functor<OutputType> >( exe_node ); + inc_count = body_copy.local_execute_count; + ASSERT( Offset == inc_count, "reset(rf_reset_bodies) did not reset functor" ); + + } +} + +template< typename OutputType > +void run_continue_nodes() { + harness_graph_executor< tbb::flow::continue_msg, OutputType>::max_executors = 0; + #if __TBB_CPP11_LAMBDAS_PRESENT + continue_nodes<OutputType>( []( tbb::flow::continue_msg i ) -> OutputType { return harness_graph_executor<tbb::flow::continue_msg, OutputType>::func(i); } ); + #endif + continue_nodes<OutputType>( &harness_graph_executor<tbb::flow::continue_msg, OutputType>::func ); + continue_nodes<OutputType>( typename harness_graph_executor<tbb::flow::continue_msg, OutputType>::functor() ); + continue_nodes_with_copy<OutputType>(); +} + +//! Tests limited concurrency cases for nodes that accept data messages +void test_concurrency(int num_threads) { + tbb::task_scheduler_init init(num_threads); + run_continue_nodes<tbb::flow::continue_msg>(); + run_continue_nodes<int>(); + run_continue_nodes<empty_no_assign>(); +} +/* + * Connection of two graphs is not currently supported, but works to some limited extent. + * This test is included to check for backward compatibility. It checks that a continue_node + * with predecessors in two different graphs receives the required + * number of continue messages before it executes. + */ +using namespace tbb::flow; + +struct add_to_counter { + int* counter; + add_to_counter(int& var):counter(&var){} + void operator()(continue_msg){*counter+=1;} +}; + +void test_two_graphs(){ + int count=0; + + //graph g with broadcast_node and continue_node + graph g; + broadcast_node<continue_msg> start_g(g); + continue_node<continue_msg> first_g(g, add_to_counter(count)); + + //graph h with broadcast_node + graph h; + broadcast_node<continue_msg> start_h(h); + + //making two edges to first_g from the two graphs + make_edge(start_g,first_g); + make_edge(start_h, first_g); + + //two try_puts from the two graphs + start_g.try_put(continue_msg()); + start_h.try_put(continue_msg()); + g.wait_for_all(); + ASSERT(count==1, "Not all continue messages received"); + + //two try_puts from the graph that doesn't contain the node + count=0; + start_h.try_put(continue_msg()); + start_h.try_put(continue_msg()); + g.wait_for_all(); + ASSERT(count==1, "Not all continue messages received -1"); + + //only one try_put + count=0; + start_g.try_put(continue_msg()); + g.wait_for_all(); + ASSERT(count==0, "Node executed without waiting for all predecessors"); +} + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +void test_extract() { + int my_count = 0; + tbb::flow::continue_msg cm; + tbb::flow::graph g; + tbb::flow::broadcast_node<tbb::flow::continue_msg> b0(g); + tbb::flow::broadcast_node<tbb::flow::continue_msg> b1(g); + tbb::flow::continue_node<tbb::flow::continue_msg> c0(g, add_to_counter(my_count)); + tbb::flow::queue_node<tbb::flow::continue_msg> q0(g); + + tbb::flow::make_edge(b0, c0); + tbb::flow::make_edge(b1, c0); + tbb::flow::make_edge(c0, q0); + for( int i = 0; i < 2; ++i ) { + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 1, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 1, "b1 has incorrect counts"); + ASSERT(c0.predecessor_count() == 2 && c0.successor_count() == 1, "c0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 1 && q0.successor_count() == 0, "q0 has incorrect counts"); + + /* b0 */ + /* \ */ + /* c0 - q0 */ + /* / */ + /* b1 */ + + b0.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(my_count == 0, "continue_node fired too soon"); + b1.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(my_count == 1, "continue_node didn't fire"); + ASSERT(q0.try_get(cm), "continue_node didn't forward"); + + b0.extract(); + + /* b0 */ + /* */ + /* c0 - q0 */ + /* / */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 0, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 1, "b1 has incorrect counts"); + ASSERT(c0.predecessor_count() == 1 && c0.successor_count() == 1, "c0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 1 && q0.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(tbb::flow::continue_msg()); + b0.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(my_count == 1, "b0 messages being forwarded to continue_node even though it is disconnected"); + b1.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(my_count == 2, "continue_node didn't fire though it has only one predecessor"); + ASSERT(q0.try_get(cm), "continue_node didn't forward second time"); + + c0.extract(); + + /* b0 */ + /* */ + /* c0 q0 */ + /* */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 0, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 0, "b1 has incorrect counts"); + ASSERT(c0.predecessor_count() == 0 && c0.successor_count() == 0, "c0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 0 && q0.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(tbb::flow::continue_msg()); + b0.try_put(tbb::flow::continue_msg()); + b1.try_put(tbb::flow::continue_msg()); + b1.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(my_count == 2, "continue didn't fire though it has only one predecessor"); + ASSERT(!q0.try_get(cm), "continue_node forwarded though it shouldn't"); + make_edge(b0, c0); + + /* b0 */ + /* \ */ + /* c0 q0 */ + /* */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 1, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 0, "b1 has incorrect counts"); + ASSERT(c0.predecessor_count() == 1 && c0.successor_count() == 0, "c0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 0 && q0.successor_count() == 0, "q0 has incorrect counts"); + + b0.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + + ASSERT(my_count == 3, "continue didn't fire though it has only one predecessor"); + ASSERT(!q0.try_get(cm), "continue_node forwarded though it shouldn't"); + + tbb::flow::make_edge(b1, c0); + tbb::flow::make_edge(c0, q0); + my_count = 0; + } +} +#endif + +struct lightweight_policy_body : NoAssign { + const tbb::tbb_thread::id my_thread_id; + tbb::atomic<size_t> my_count; + + lightweight_policy_body() : my_thread_id(tbb::this_tbb_thread::get_id()) { + my_count = 0; + } + void operator()(tbb::flow::continue_msg) { + ++my_count; + tbb::tbb_thread::id body_thread_id = tbb::this_tbb_thread::get_id(); + ASSERT(body_thread_id == my_thread_id, "Body executed as not lightweight"); + } +}; + +void test_lightweight_policy() { + tbb::flow::graph g; + tbb::flow::continue_node<tbb::flow::continue_msg, tbb::flow::lightweight> node1(g, lightweight_policy_body()); + tbb::flow::continue_node<tbb::flow::continue_msg, tbb::flow::lightweight> node2(g, lightweight_policy_body()); + + tbb::flow::make_edge(node1, node2); + const size_t n = 10; + for(size_t i = 0; i < n; ++i) { + node1.try_put(tbb::flow::continue_msg()); + } + g.wait_for_all(); + + lightweight_policy_body body1 = tbb::flow::copy_body<lightweight_policy_body>(node1); + lightweight_policy_body body2 = tbb::flow::copy_body<lightweight_policy_body>(node2); + ASSERT(body1.my_count == n, "Body of the first node needs to be executed N times"); + ASSERT(body2.my_count == n, "Body of the second node needs to be executed N times"); +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + using msg_t = tbb::flow::continue_msg; + + std::array<msg_t, 3> messages_for_follows = { { msg_t(), msg_t(), msg_t() } }; + std::vector<msg_t> messages_for_precedes = { msg_t() }; + + auto pass_through = [](const msg_t& msg) { return msg; }; + + follows_and_precedes_testing::test_follows + <msg_t, tbb::flow::continue_node<msg_t>> + (messages_for_follows, pass_through); + + follows_and_precedes_testing::test_precedes + <msg_t, tbb::flow::continue_node<msg_t>> + (messages_for_precedes, pass_through); +} +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +template <typename ExpectedType, typename Body> +void test_deduction_guides_common(Body body) { + using namespace tbb::flow; + graph g; + + continue_node c1(g, body); + static_assert(std::is_same_v<decltype(c1), continue_node<ExpectedType>>); + + continue_node c2(g, body, lightweight()); + static_assert(std::is_same_v<decltype(c2), continue_node<ExpectedType, lightweight>>); + + continue_node c3(g, 5, body); + static_assert(std::is_same_v<decltype(c3), continue_node<ExpectedType>>); + + continue_node c4(g, 5, body, lightweight()); + static_assert(std::is_same_v<decltype(c4), continue_node<ExpectedType, lightweight>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + continue_node c5(g, body, node_priority_t(5)); + static_assert(std::is_same_v<decltype(c5), continue_node<ExpectedType>>); + + continue_node c6(g, body, lightweight(), node_priority_t(5)); + static_assert(std::is_same_v<decltype(c6), continue_node<ExpectedType, lightweight>>); + + continue_node c7(g, 5, body, node_priority_t(5)); + static_assert(std::is_same_v<decltype(c7), continue_node<ExpectedType>>); + + continue_node c8(g, 5, body, lightweight(), node_priority_t(5)); + static_assert(std::is_same_v<decltype(c8), continue_node<ExpectedType, lightweight>>); +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + broadcast_node<continue_msg> b(g); + + continue_node c9(follows(b), body); + static_assert(std::is_same_v<decltype(c9), continue_node<ExpectedType>>); + + continue_node c10(follows(b), body, lightweight()); + static_assert(std::is_same_v<decltype(c10), continue_node<ExpectedType, lightweight>>); + + continue_node c11(follows(b), 5, body); + static_assert(std::is_same_v<decltype(c11), continue_node<ExpectedType>>); + + continue_node c12(follows(b), 5, body, lightweight()); + static_assert(std::is_same_v<decltype(c12), continue_node<ExpectedType, lightweight>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + continue_node c13(follows(b), body, node_priority_t(5)); + static_assert(std::is_same_v<decltype(c13), continue_node<ExpectedType>>); + + continue_node c14(follows(b), body, lightweight(), node_priority_t(5)); + static_assert(std::is_same_v<decltype(c14), continue_node<ExpectedType, lightweight>>); + + continue_node c15(follows(b), 5, body, node_priority_t(5)); + static_assert(std::is_same_v<decltype(c15), continue_node<ExpectedType>>); + + continue_node c16(follows(b), 5, body, lightweight(), node_priority_t(5)); + static_assert(std::is_same_v<decltype(c16), continue_node<ExpectedType, lightweight>>); +#endif +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + + continue_node c17(c1); + static_assert(std::is_same_v<decltype(c17), continue_node<ExpectedType>>); +} + +int continue_body_f(const tbb::flow::continue_msg&) { return 1; } +void continue_void_body_f(const tbb::flow::continue_msg&) {} + +void test_deduction_guides() { + using tbb::flow::continue_msg; + test_deduction_guides_common<int>([](const continue_msg&)->int { return 1; } ); + test_deduction_guides_common<continue_msg>([](const continue_msg&) {}); + + test_deduction_guides_common<int>([](const continue_msg&) mutable ->int { return 1; }); + test_deduction_guides_common<continue_msg>([](const continue_msg&) mutable {}); + + test_deduction_guides_common<int>(continue_body_f); + test_deduction_guides_common<continue_msg>(continue_void_body_f); +} + +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +// TODO: use pass_through from test_function_node instead +template<typename T> +struct passing_body { + T operator()(const T& val) { + return val; + } +}; + +/* + The test covers the case when a node with non-default mutex type is a predecessor for continue_node, + because there used to be a bug when make_edge(node, continue_node) + did not update continue_node's predecesosor threshold + since the specialization of node's successor_cache for a continue_node was not chosen. +*/ +void test_successor_cache_specialization() { + using namespace tbb::flow; + + graph g; + + broadcast_node<continue_msg> node_with_default_mutex_type(g); + buffer_node<continue_msg> node_with_non_default_mutex_type(g); + + continue_node<continue_msg> node(g, passing_body<continue_msg>()); + + make_edge(node_with_default_mutex_type, node); + make_edge(node_with_non_default_mutex_type, node); + + buffer_node<continue_msg> buf(g); + + make_edge(node, buf); + + node_with_default_mutex_type.try_put(continue_msg()); + node_with_non_default_mutex_type.try_put(continue_msg()); + + g.wait_for_all(); + + continue_msg storage; + ASSERT((buf.try_get(storage) && !buf.try_get(storage)), + "Wrong number of messages is passed via continue_node"); +} + +int TestMain() { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + test_concurrency(p); + } + test_two_graphs(); +#if __TBB_PREVIEW_LIGHTWEIGHT_POLICY + test_lightweight_policy(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract(); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + test_successor_cache_specialization(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_critical_section.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_critical_section.cpp new file mode 100644 index 00000000..00facfcc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_critical_section.cpp @@ -0,0 +1,212 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// test critical section +// +#include "tbb/critical_section.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/enumerable_thread_specific.h" +#include "tbb/tick_count.h" +#include "harness_assert.h" +#include "harness.h" +#include <math.h> + +#include "harness_barrier.h" +Harness::SpinBarrier sBarrier; +tbb::critical_section cs; +const int MAX_WORK = 300; + +struct BusyBody : NoAssign { + tbb::enumerable_thread_specific<double> &locals; + const int nThread; + const int WorkRatiox100; + int &unprotected_count; + bool test_throw; + + BusyBody( int nThread_, int workRatiox100_, tbb::enumerable_thread_specific<double> &locals_, int &unprotected_count_, bool test_throw_) : + locals(locals_), + nThread(nThread_), + WorkRatiox100(workRatiox100_), + unprotected_count(unprotected_count_), + test_throw(test_throw_) { + sBarrier.initialize(nThread_); + } + + void operator()(const int /* threadID */ ) const { + int nIters = MAX_WORK/nThread; + sBarrier.wait(); + tbb::tick_count t0 = tbb::tick_count::now(); + for(int j = 0; j < nIters; j++) { + + for(int i = 0; i < MAX_WORK * (100 - WorkRatiox100); i++) { + locals.local() += 1.0; + } + cs.lock(); + ASSERT( !cs.try_lock(), "recursive try_lock must fail" ); +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + if(test_throw && j == (nIters / 2)) { + bool was_caught = false, + unknown_exception = false; + try { + cs.lock(); + } + catch(tbb::improper_lock& e) { + ASSERT( e.what(), "Error message is absent" ); + was_caught = true; + } + catch(...) { + was_caught = unknown_exception = true; + } + ASSERT(was_caught, "Recursive lock attempt did not throw"); + ASSERT(!unknown_exception, "tbb::improper_lock exception is expected"); + } +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ + for(int i = 0; i < MAX_WORK * WorkRatiox100; i++) { + locals.local() += 1.0; + } + unprotected_count++; + cs.unlock(); + } + locals.local() = (tbb::tick_count::now() - t0).seconds(); + } +}; + +struct BusyBodyScoped : NoAssign { + tbb::enumerable_thread_specific<double> &locals; + const int nThread; + const int WorkRatiox100; + int &unprotected_count; + bool test_throw; + + BusyBodyScoped( int nThread_, int workRatiox100_, tbb::enumerable_thread_specific<double> &locals_, int &unprotected_count_, bool test_throw_) : + locals(locals_), + nThread(nThread_), + WorkRatiox100(workRatiox100_), + unprotected_count(unprotected_count_), + test_throw(test_throw_) { + sBarrier.initialize(nThread_); + } + + void operator()(const int /* threadID */ ) const { + int nIters = MAX_WORK/nThread; + sBarrier.wait(); + tbb::tick_count t0 = tbb::tick_count::now(); + for(int j = 0; j < nIters; j++) { + + for(int i = 0; i < MAX_WORK * (100 - WorkRatiox100); i++) { + locals.local() += 1.0; + } + { + tbb::critical_section::scoped_lock my_lock(cs); + for(int i = 0; i < MAX_WORK * WorkRatiox100; i++) { + locals.local() += 1.0; + } + unprotected_count++; + } + } + locals.local() = (tbb::tick_count::now() - t0).seconds(); + } +}; + +void +RunOneCriticalSectionTest(int nThreads, int csWorkRatio, bool test_throw) { + tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred); + tbb::enumerable_thread_specific<double> test_locals; + int myCount = 0; + BusyBody myBody(nThreads, csWorkRatio, test_locals, myCount, test_throw); + BusyBodyScoped myScopedBody(nThreads, csWorkRatio, test_locals, myCount, test_throw); + init.initialize(nThreads); + tbb::tick_count t0; + { + t0 = tbb::tick_count::now(); + myCount = 0; + NativeParallelFor(nThreads, myBody); + ASSERT(myCount == (MAX_WORK - (MAX_WORK % nThreads)), NULL); + REMARK("%d threads, work ratio %d per cent, time %g", nThreads, csWorkRatio, (tbb::tick_count::now() - t0).seconds()); + if (nThreads > 1) { + double etsSum = 0; + double etsMax = 0; + double etsMin = 0; + double etsSigmaSq = 0; + double etsSigma = 0; + + for(tbb::enumerable_thread_specific<double>::const_iterator ci = test_locals.begin(); ci != test_locals.end(); ci++) { + etsSum += *ci; + if(etsMax==0.0) { + etsMin = *ci; + } + else { + if(etsMin > *ci) etsMin = *ci; + } + if(etsMax < *ci) etsMax = *ci; + } + double etsAvg = etsSum / (double)nThreads; + for(tbb::enumerable_thread_specific<double>::const_iterator ci = test_locals.begin(); ci != test_locals.end(); ci++) { + etsSigma = etsAvg - *ci; + etsSigmaSq += etsSigma * etsSigma; + } + // an attempt to gauge the "fairness" of the scheduling of the threads. We figure + // the standard deviation, and compare it with the maximum deviation from the + // average time. If the difference is 0 that means all threads finished in the same + // amount of time. If non-zero, the difference is divided by the time, and the + // negative log is taken. If > 2, then the difference is on the order of 0.01*t + // where T is the average time. We aritrarily define this as "fair." + etsSigma = sqrt(etsSigmaSq/double(nThreads)); + etsMax -= etsAvg; // max - a == delta1 + etsMin = etsAvg - etsMin; // a - min == delta2 + if(etsMax < etsMin) etsMax = etsMin; + etsMax -= etsSigma; + // ASSERT(etsMax >= 0, NULL); // shouldn't the maximum difference from the mean be > the stddev? + etsMax = (etsMax > 0.0) ? etsMax : 0.0; // possible rounding error + double fairness = etsMax / etsAvg; + if(fairness == 0.0) { + fairness = 100.0; + } + else fairness = - log10(fairness); + if(fairness > 2.0 ) { + REMARK(" Fair (%g)\n", fairness); + } + else { + REMARK(" Unfair (%g)\n", fairness); + } + } + myCount = 0; + NativeParallelFor(nThreads, myScopedBody); + ASSERT(myCount == (MAX_WORK - (MAX_WORK % nThreads)), NULL); + + } + + init.terminate(); +} + +void +RunParallelTests() { + for(int p = MinThread; p <= MaxThread; p++) { + for(int cs_ratio = 1; cs_ratio < 95; cs_ratio *= 2) { + RunOneCriticalSectionTest(p, cs_ratio, /*test_throw*/true); + } + } +} + +int TestMain () { + if(MinThread <= 0) MinThread = 1; + + if(MaxThread > 0) { + RunParallelTests(); + } + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_dynamic_link.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_dynamic_link.cpp new file mode 100644 index 00000000..8cd54652 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_dynamic_link.cpp @@ -0,0 +1,80 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +enum FOO_TYPE { + FOO_DUMMY, + FOO_IMPLEMENTATION +}; + +#if _WIN32 || _WIN64 +#define TEST_EXPORT +#else +#define TEST_EXPORT extern "C" +#endif /* _WIN32 || _WIN64 */ + +// foo "implementations". +TEST_EXPORT FOO_TYPE foo1() { return FOO_IMPLEMENTATION; } +TEST_EXPORT FOO_TYPE foo2() { return FOO_IMPLEMENTATION; } +// foo "dummies". +FOO_TYPE dummy_foo1() { return FOO_DUMMY; } +FOO_TYPE dummy_foo2() { return FOO_DUMMY; } + +// Handlers. +static FOO_TYPE (*foo1_handler)() = &dummy_foo1; +static FOO_TYPE (*foo2_handler)() = &dummy_foo2; + +#include "tbb/tbb_config.h" +// Suppress the weak symbol mechanism to avoid surplus compiler warnings. +#ifdef __TBB_WEAK_SYMBOLS_PRESENT +#undef __TBB_WEAK_SYMBOLS_PRESENT +#endif +// Use of harness assert to avoid the dependency on TBB +#include "harness_assert.h" +#define LIBRARY_ASSERT(p,message) ASSERT(p,message) +#include "tbb/dynamic_link.h" +// Table describing how to link the handlers. +static const tbb::internal::dynamic_link_descriptor LinkTable[] = { + { "foo1", (tbb::internal::pointer_to_handler*)(void*)(&foo1_handler) }, + { "foo2", (tbb::internal::pointer_to_handler*)(void*)(&foo2_handler) } +}; + +// The direct include since we want to test internal functionality. +#include "tbb/dynamic_link.cpp" +#include "harness_dynamic_libs.h" +#include "harness.h" + +#if !HARNESS_SKIP_TEST +int TestMain () { +#if !_WIN32 + // Check if the executable exports its symbols. + ASSERT( Harness::GetAddress( Harness::OpenLibrary(NULL), "foo1" ) && Harness::GetAddress( Harness::OpenLibrary(NULL), "foo2" ), + "The executable doesn't export its symbols. Is the -rdynamic switch set during linking?" ); +#endif /* !_WIN32 */ + // We want to link (or fail to link) to the symbols available from the + // executable so it doesn't matter what the library name is specified in + // the dynamic_link call - let it be an empty string. + // Generally speaking the test has sense only on Linux but on Windows it + // checks the dynamic_link graceful behavior with incorrect library name. + if ( tbb::internal::dynamic_link( "", LinkTable, sizeof(LinkTable)/sizeof(LinkTable[0]) ) ) { + ASSERT( foo1_handler && foo2_handler, "The symbols are corrupted by dynamic_link" ); + ASSERT( foo1_handler() == FOO_IMPLEMENTATION && foo2_handler() == FOO_IMPLEMENTATION, + "dynamic_link returned the successful code but symbol(s) are wrong" ); + } else { + ASSERT( foo1_handler==dummy_foo1 && foo2_handler==dummy_foo2, "The symbols are corrupted by dynamic_link" ); + } + return Harness::Done; +} +#endif // HARNESS_SKIP_TEST diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_algorithms.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_algorithms.cpp new file mode 100644 index 00000000..4c17634e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_algorithms.cpp @@ -0,0 +1,1579 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 2 +#define HARNESS_DEFAULT_MAX_THREADS 4 + +#include "harness.h" + +#if __TBB_TASK_GROUP_CONTEXT + +#include <limits.h> // for INT_MAX +#include "tbb/task_scheduler_init.h" +#include "tbb/tbb_exception.h" +#include "tbb/task.h" +#include "tbb/atomic.h" +#include "tbb/parallel_for.h" +#include "tbb/parallel_reduce.h" +#include "tbb/parallel_do.h" +#include "tbb/pipeline.h" +#include "tbb/parallel_scan.h" +#include "tbb/blocked_range.h" +#include "harness_assert.h" + +#define FLAT_RANGE 100000 +#define FLAT_GRAIN 100 +#define OUTER_RANGE 100 +#define OUTER_GRAIN 10 +#define INNER_RANGE (FLAT_RANGE / OUTER_RANGE) +#define INNER_GRAIN (FLAT_GRAIN / OUTER_GRAIN) + +tbb::atomic<intptr_t> g_FedTasksCount; // number of tasks added by parallel_do feeder +tbb::atomic<intptr_t> g_OuterParCalls; // number of actual invocations of the outer construct executed. +tbb::atomic<intptr_t> g_TGCCancelled; // Number of times a task sees its group cancelled at start + +inline intptr_t Existed () { return INT_MAX; } + +#include "harness_eh.h" +/******************************** + Variables in test + +__ Test control variables + g_ExceptionInMaster -- only the master thread is allowed to throw. If false, the master cannot throw + g_SolitaryException -- only one throw may be executed. + +-- controls for ThrowTestException for pipeline tests + g_NestedPipelines -- are inner pipelines being run? + g_PipelinesStarted -- how many pipelines have run their first filter at least once. + +-- Information variables + + g_Master -- Thread ID of the "master" thread + In pipelines sometimes the master thread does not participate, so the tests have to be resilient to this. + +-- Measurement variables + + g_OuterParCalls -- how many outer parallel ranges or filters started + g_TGCCancelled -- how many inner parallel ranges or filters saw task::self().is_cancelled() + g_ExceptionsThrown -- number of throws executed (counted in ThrowTestException) + g_MasterExecutedThrow -- number of times master thread actually executed a throw + g_NonMasterExecutedThrow -- number of times non-master thread actually executed a throw + g_ExceptionCaught -- one of PropagatedException or unknown exception was caught. (Other exceptions cause assertions.) + + -- Tallies for the task bodies which have executed (counted in each inner body, sampled in ThrowTestException) + g_CurExecuted -- total number of inner ranges or filters which executed + g_ExecutedAtLastCatch -- value of g_CurExecuted when last catch was made, 0 if none. + g_ExecutedAtFirstCatch -- value of g_CurExecuted when first catch is made, 0 if none. + *********************************/ + +inline void ResetGlobals ( bool throwException = true, bool flog = false ) { + ResetEhGlobals( throwException, flog ); + g_FedTasksCount = 0; + g_OuterParCalls = 0; + g_NestedPipelines = false; + g_TGCCancelled = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// Tests for tbb::parallel_for and tbb::parallel_reduce + +typedef size_t count_type; +typedef tbb::blocked_range<count_type> range_type; + +inline intptr_t CountSubranges(range_type r) { + if(!r.is_divisible()) return intptr_t(1); + range_type r2(r,tbb::split()); + return CountSubranges(r) + CountSubranges(r2); +} + +inline intptr_t NumSubranges ( intptr_t length, intptr_t grain ) { + return CountSubranges(range_type(0,length,grain)); +} + +template<class Body> +intptr_t TestNumSubrangesCalculation ( intptr_t length, intptr_t grain, intptr_t inner_length, intptr_t inner_grain ) { + ResetGlobals(); + g_ThrowException = false; + intptr_t outerCalls = NumSubranges(length, grain), + innerCalls = NumSubranges(inner_length, inner_grain), + maxExecuted = outerCalls * (innerCalls + 1); + tbb::parallel_for( range_type(0, length, grain), Body() ); + ASSERT (g_CurExecuted == maxExecuted, "Wrong estimation of bodies invocation count"); + return maxExecuted; +} + +class NoThrowParForBody { +public: + void operator()( const range_type& r ) const { + volatile count_type x = 0; + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; + count_type end = r.end(); + for( count_type i=r.begin(); i<end; ++i ) + x += i; + } +}; + +#if TBB_USE_EXCEPTIONS + +void Test0 () { + ResetGlobals(); + tbb::simple_partitioner p; + for( size_t i=0; i<10; ++i ) { + tbb::parallel_for( range_type(0, 0, 1), NoThrowParForBody() ); + tbb::parallel_for( range_type(0, 0, 1), NoThrowParForBody(), p ); + tbb::parallel_for( range_type(0, 128, 8), NoThrowParForBody() ); + tbb::parallel_for( range_type(0, 128, 8), NoThrowParForBody(), p ); + } +} // void Test0 () + +//! Template that creates a functor suitable for parallel_reduce from a functor for parallel_for. +template<typename ParForBody> +class SimpleParReduceBody: NoAssign { + ParForBody m_Body; +public: + void operator()( const range_type& r ) const { m_Body(r); } + SimpleParReduceBody() {} + SimpleParReduceBody( SimpleParReduceBody& left, tbb::split ) : m_Body(left.m_Body) {} + void join( SimpleParReduceBody& /*right*/ ) {} +}; // SimpleParReduceBody + +//! Test parallel_for and parallel_reduce for a given partitioner. +/** The Body need only be suitable for a parallel_for. */ +template<typename ParForBody, typename Partitioner> +void TestParallelLoopAux() { + Partitioner partitioner; + for( int i=0; i<2; ++i ) { + ResetGlobals(); + TRY(); + if( i==0 ) + tbb::parallel_for( range_type(0, FLAT_RANGE, FLAT_GRAIN), ParForBody(), partitioner ); + else { + SimpleParReduceBody<ParForBody> rb; + tbb::parallel_reduce( range_type(0, FLAT_RANGE, FLAT_GRAIN), rb, partitioner ); + } + CATCH_AND_ASSERT(); + // two cases: g_SolitaryException and !g_SolitaryException + // 1) g_SolitaryException: only one thread actually threw. There is only one context, so the exception + // (when caught) will cause that context to be cancelled. After this event, there may be one or + // more threads which are "in-flight", up to g_NumThreads, but no more will be started. The threads, + // when they start, if they see they are cancelled, TGCCancelled is incremented. + // 2) !g_SolitaryException: more than one thread can throw. The number of threads that actually + // threw is g_MasterExecutedThrow if only the master is allowed, else g_NonMasterExecutedThrow. + // Only one context, so TGCCancelled should be <= g_NumThreads. + // + // the reasoning is similar for nested algorithms in a single context (Test2). + // + // If a thread throws in a context, more than one subsequent task body may see the + // cancelled state (if they are scheduled before the state is propagated.) this is + // infrequent, but it occurs. So what was to be an assertion must be a remark. + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks ran after exception thrown"); + if( g_TGCCancelled > g_NumThreads) REMARK( "Too many tasks ran after exception thrown (%d vs. %d)\n", + (int)g_TGCCancelled, (int)g_NumThreads); + ASSERT(g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); + if ( g_SolitaryException ) { + ASSERT(g_NumExceptionsCaught == 1, "No try_blocks in any body expected in this test"); + ASSERT(g_NumExceptionsCaught == (g_ExceptionInMaster ? g_MasterExecutedThrow : g_NonMasterExecutedThrow), + "Not all throws were caught"); + ASSERT(g_ExecutedAtFirstCatch == g_ExecutedAtLastCatch, "Too many exceptions occurred"); + } + else { + ASSERT(g_NumExceptionsCaught >= 1, "No try blocks in any body expected in this test"); + } + } +} // TestParallelLoopAux + +//! Test with parallel_for and parallel_reduce, over all three kinds of partitioners. +/** The Body only needs to be suitable for tbb::parallel_for. */ +template<typename Body> +void TestParallelLoop() { + // The simple and auto partitioners should be const, but not the affinity partitioner. + TestParallelLoopAux<Body, const tbb::simple_partitioner >(); + TestParallelLoopAux<Body, const tbb::auto_partitioner >(); +#define __TBB_TEMPORARILY_DISABLED 1 +#if !__TBB_TEMPORARILY_DISABLED + // TODO: Improve the test so that it tolerates delayed start of tasks with affinity_partitioner + TestParallelLoopAux<Body, /***/ tbb::affinity_partitioner>(); +#endif +#undef __TBB_TEMPORARILY_DISABLED +} + +class SimpleParForBody: NoAssign { +public: + void operator()( const range_type& r ) const { + Harness::ConcurrencyTracker ct; + volatile long x = 0; + ++g_CurExecuted; + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; + for( count_type i = r.begin(); i != r.end(); ++i ) + x += 0; + WaitUntilConcurrencyPeaks(); + ThrowTestException(1); + } +}; + +void Test1() { + // non-nested parallel_for/reduce with throwing body, one context + TestParallelLoop<SimpleParForBody>(); +} // void Test1 () + +class OuterParForBody: NoAssign { +public: + void operator()( const range_type& ) const { + Harness::ConcurrencyTracker ct; + ++g_OuterParCalls; + tbb::parallel_for( tbb::blocked_range<size_t>(0, INNER_RANGE, INNER_GRAIN), SimpleParForBody() ); + } +}; + +//! Uses parallel_for body containing an inner parallel_for with the default context not wrapped by a try-block. +/** Inner algorithms are spawned inside the new bound context by default. Since + exceptions thrown from the inner parallel_for are not handled by the caller + (outer parallel_for body) in this test, they will cancel all the sibling inner + algorithms. **/ +void Test2 () { + TestParallelLoop<OuterParForBody>(); +} // void Test2 () + +class OuterParForBodyWithIsolatedCtx { +public: + void operator()( const range_type& ) const { + tbb::task_group_context ctx(tbb::task_group_context::isolated); + ++g_OuterParCalls; + tbb::parallel_for( tbb::blocked_range<size_t>(0, INNER_RANGE, INNER_GRAIN), SimpleParForBody(), tbb::simple_partitioner(), ctx ); + } +}; + +//! Uses parallel_for body invoking an inner parallel_for with an isolated context without a try-block. +/** Even though exceptions thrown from the inner parallel_for are not handled + by the caller in this test, they will not affect sibling inner algorithms + already running because of the isolated contexts. However because the first + exception cancels the root parallel_for only the first g_NumThreads subranges + will be processed (which launch inner parallel_fors) **/ +void Test3 () { + ResetGlobals(); + typedef OuterParForBodyWithIsolatedCtx body_type; + intptr_t innerCalls = NumSubranges(INNER_RANGE, INNER_GRAIN), + // we expect one thread to throw without counting, the rest to run to completion + // this formula assumes g_numThreads outer pfor ranges will be started, but that is not the + // case; the SimpleParFor subranges are started up as part of the outer ones, and when + // the amount of concurrency reaches g_NumThreads no more outer Pfor ranges are started. + // so we have to count the number of outer Pfors actually started. + minExecuted = (g_NumThreads - 1) * innerCalls; + TRY(); + tbb::parallel_for( range_type(0, OUTER_RANGE, OUTER_GRAIN), body_type() ); + CATCH_AND_ASSERT(); + minExecuted = (g_OuterParCalls - 1) * innerCalls; // see above + + // The first formula above assumes all ranges of the outer parallel for are executed, and one + // cancels. In the event, we have a smaller number of ranges that start before the exception + // is caught. + // + // g_SolitaryException:One inner range throws. Outer parallel_For is cancelled, but sibling + // parallel_fors continue to completion (unless the threads that execute + // are not allowed to throw, in which case we will not see any exceptions). + // !g_SolitaryException:multiple inner ranges may throw. Any which throws will stop, and the + // corresponding range of the outer pfor will stop also. + // + // In either case, once the outer pfor gets the exception it will stop executing further ranges. + + // if the only threads executing were not allowed to throw, then not seeing an exception is okay. + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecuted) || (!g_ExceptionInMaster && !g_NonMasterExecuted); + if ( g_SolitaryException ) { + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived exception"); + ASSERT (g_CurExecuted > minExecuted, "Too few tasks survived exception"); + ASSERT (g_CurExecuted <= minExecuted + (g_ExecutedAtLastCatch + g_NumThreads), "Too many tasks survived exception"); + ASSERT (g_NumExceptionsCaught == 1 || okayNoExceptionsCaught, "No try_blocks in any body expected in this test"); + } + else { + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); + ASSERT (g_NumExceptionsCaught >= 1 || okayNoExceptionsCaught, "No try_blocks in any body expected in this test"); + } +} // void Test3 () + +class OuterParForExceptionSafeBody { +public: + void operator()( const range_type& ) const { + tbb::task_group_context ctx(tbb::task_group_context::isolated); + ++g_OuterParCalls; + TRY(); + tbb::parallel_for( tbb::blocked_range<size_t>(0, INNER_RANGE, INNER_GRAIN), SimpleParForBody(), tbb::simple_partitioner(), ctx ); + CATCH(); // this macro sets g_ExceptionCaught + } +}; + +//! Uses parallel_for body invoking an inner parallel_for (with isolated context) inside a try-block. +/** Since exception(s) thrown from the inner parallel_for are handled by the caller + in this test, they do not affect neither other tasks of the the root parallel_for + nor sibling inner algorithms. **/ +void Test4 () { + ResetGlobals( true, true ); + intptr_t innerCalls = NumSubranges(INNER_RANGE, INNER_GRAIN), + outerCalls = NumSubranges(OUTER_RANGE, OUTER_GRAIN); + TRY(); + tbb::parallel_for( range_type(0, OUTER_RANGE, OUTER_GRAIN), OuterParForExceptionSafeBody() ); + CATCH(); + // g_SolitaryException : one inner pfor will throw, the rest will execute to completion. + // so the count should be (outerCalls -1) * innerCalls, if a throw happened. + // !g_SolitaryException : possible multiple inner pfor throws. Should be approximately + // (outerCalls - g_NumExceptionsCaught) * innerCalls, give or take a few + intptr_t minExecuted = (outerCalls - g_NumExceptionsCaught) * innerCalls; + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecuted) || (!g_ExceptionInMaster && !g_NonMasterExecuted); + if ( g_SolitaryException ) { + // only one task had exception thrown. That task had at least one execution (the one that threw). + // There may be an arbitrary number of ranges executed after the throw but before the exception + // is caught in the scheduler and cancellation is signaled. (seen 9, 11 and 62 (!) for 8 threads) + ASSERT (g_NumExceptionsCaught == 1 || okayNoExceptionsCaught, "No exception registered"); + ASSERT (g_CurExecuted >= minExecuted, "Too few tasks executed"); + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived exception"); + // a small number of threads can execute in a throwing sub-pfor, if the task which is + // to do the solitary throw swaps out after registering its intent to throw but before it + // actually does so. (Or is this caused by the extra threads participating? No, the + // number of extra tasks is sometimes far greater than the number of extra threads.) + ASSERT (g_CurExecuted <= minExecuted + g_NumThreads, "Too many tasks survived exception"); + if(g_CurExecuted > minExecuted + g_NumThreads) REMARK("Unusual number of tasks executed after signal (%d vs. %d)\n", + (int)g_CurExecuted, minExecuted + g_NumThreads); + } + else { + ASSERT ((g_NumExceptionsCaught >= 1 && g_NumExceptionsCaught <= outerCalls) || okayNoExceptionsCaught, "Unexpected actual number of exceptions"); + ASSERT (g_CurExecuted >= minExecuted, "Too few executed tasks reported"); + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived multiple exceptions"); + if(g_CurExecuted > g_ExecutedAtLastCatch + g_NumThreads) REMARK("Unusual number of tasks executed after signal (%d vs. %d)\n", + (int)g_CurExecuted, g_ExecutedAtLastCatch + g_NumThreads); + ASSERT (g_CurExecuted <= outerCalls * (1 + g_NumThreads), "Too many tasks survived exception"); + } +} // void Test4 () + +#endif /* TBB_USE_EXCEPTIONS */ + +class ParForBodyToCancel { +public: + void operator()( const range_type& ) const { + ++g_CurExecuted; + CancellatorTask::WaitUntilReady(); + } +}; + +template<class B> +class ParForLauncherTask : public tbb::task { + tbb::task_group_context &my_ctx; + + tbb::task* execute () __TBB_override { + tbb::parallel_for( range_type(0, FLAT_RANGE, FLAT_GRAIN), B(), tbb::simple_partitioner(), my_ctx ); + return NULL; + } +public: + ParForLauncherTask ( tbb::task_group_context& ctx ) : my_ctx(ctx) {} +}; + +//! Test for cancelling an algorithm from outside (from a task running in parallel with the algorithm). +void TestCancelation1 () { + ResetGlobals( false ); + RunCancellationTest<ParForLauncherTask<ParForBodyToCancel>, CancellatorTask>( NumSubranges(FLAT_RANGE, FLAT_GRAIN) / 4 ); +} + +class CancellatorTask2 : public tbb::task { + tbb::task_group_context &m_GroupToCancel; + + tbb::task* execute () __TBB_override { + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks(); + m_GroupToCancel.cancel_group_execution(); + g_ExecutedAtLastCatch = g_CurExecuted; + return NULL; + } +public: + CancellatorTask2 ( tbb::task_group_context& ctx, intptr_t ) : m_GroupToCancel(ctx) {} +}; + +class ParForBodyToCancel2 { +public: + void operator()( const range_type& ) const { + ++g_CurExecuted; + Harness::ConcurrencyTracker ct; + // The test will hang (and be timed out by the test system) if is_cancelled() is broken + while( !tbb::task::self().is_cancelled() ) + __TBB_Yield(); + } +}; + +//! Test for cancelling an algorithm from outside (from a task running in parallel with the algorithm). +/** This version also tests task::is_cancelled() method. **/ +void TestCancelation2 () { + ResetGlobals(); + RunCancellationTest<ParForLauncherTask<ParForBodyToCancel2>, CancellatorTask2>(); + ASSERT (g_ExecutedAtLastCatch < g_NumThreads, "Somehow worker tasks started their execution before the cancellator task"); + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived cancellation"); + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Some tasks were executed after cancellation"); +} + +//////////////////////////////////////////////////////////////////////////////// +// Regression test based on the contribution by the author of the following forum post: +// http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30254959.aspx + +class Worker { + static const int max_nesting = 3; + static const int reduce_range = 1024; + static const int reduce_grain = 256; +public: + int DoWork (int level); + int Validate (int start_level) { + int expected = 1; // identity for multiplication + for(int i=start_level+1; i<max_nesting; ++i) + expected *= reduce_range; + return expected; + } +}; + +class RecursiveParReduceBodyWithSharedWorker { + Worker * m_SharedWorker; + int m_NestingLevel; + int m_Result; +public: + RecursiveParReduceBodyWithSharedWorker ( RecursiveParReduceBodyWithSharedWorker& src, tbb::split ) + : m_SharedWorker(src.m_SharedWorker) + , m_NestingLevel(src.m_NestingLevel) + , m_Result(0) + {} + RecursiveParReduceBodyWithSharedWorker ( Worker *w, int outer ) + : m_SharedWorker(w) + , m_NestingLevel(outer) + , m_Result(0) + {} + + void operator() ( const tbb::blocked_range<size_t>& r ) { + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; + for (size_t i = r.begin (); i != r.end (); ++i) { + m_Result += m_SharedWorker->DoWork (m_NestingLevel); + } + } + void join (const RecursiveParReduceBodyWithSharedWorker & x) { + m_Result += x.m_Result; + } + int result () { return m_Result; } +}; + +int Worker::DoWork ( int level ) { + ++level; + if ( level < max_nesting ) { + RecursiveParReduceBodyWithSharedWorker rt (this, level); + tbb::parallel_reduce (tbb::blocked_range<size_t>(0, reduce_range, reduce_grain), rt); + return rt.result(); + } + else + return 1; +} + +//! Regression test for hanging that occurred with the first version of cancellation propagation +void TestCancelation3 () { + Worker w; + int result = w.DoWork (0); + int expected = w.Validate(0); + ASSERT ( result == expected, "Wrong calculation result"); +} + +struct StatsCounters { + tbb::atomic<size_t> my_total_created; + tbb::atomic<size_t> my_total_deleted; + StatsCounters() { + my_total_created = 0; + my_total_deleted = 0; + } +}; + +class ParReduceBody { + StatsCounters* my_stats; + size_t my_id; + bool my_exception; + +public: + ParReduceBody( StatsCounters& s_, bool e_ ) : my_stats(&s_), my_exception(e_) { + my_id = my_stats->my_total_created++; + } + + ParReduceBody( const ParReduceBody& lhs ) { + my_stats = lhs.my_stats; + my_id = my_stats->my_total_created++; + } + + ParReduceBody( ParReduceBody& lhs, tbb::split ) { + my_stats = lhs.my_stats; + my_id = my_stats->my_total_created++; + } + + ~ParReduceBody(){ ++my_stats->my_total_deleted; } + + void operator()( const tbb::blocked_range<std::size_t>& /*range*/ ) const { + //Do nothing, except for one task (chosen arbitrarily) + if( my_id >= 12 ) { + if( my_exception ) + ThrowTestException(1); + else + tbb::task::self().cancel_group_execution(); + } + } + + void join( ParReduceBody& /*rhs*/ ) {} +}; + +void TestCancelation4() { + StatsCounters statsObj; + __TBB_TRY { + tbb::task_group_context tgc1, tgc2; + ParReduceBody body_for_cancellation(statsObj, false), body_for_exception(statsObj, true); + tbb::parallel_reduce( tbb::blocked_range<std::size_t>(0,100000000,100), body_for_cancellation, tbb::simple_partitioner(), tgc1 ); + tbb::parallel_reduce( tbb::blocked_range<std::size_t>(0,100000000,100), body_for_exception, tbb::simple_partitioner(), tgc2 ); + } __TBB_CATCH(...) {} + ASSERT ( statsObj.my_total_created==statsObj.my_total_deleted, "Not all parallel_reduce body objects created were reclaimed"); +} + +void RunParForAndReduceTests () { + REMARK( "parallel for and reduce tests\n" ); + tbb::task_scheduler_init init (g_NumThreads); + g_Master = Harness::CurrentTid(); + +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + Test0(); + Test1(); + Test2(); + Test3(); + Test4(); +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ + TestCancelation1(); + TestCancelation2(); + TestCancelation3(); + TestCancelation4(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Tests for tbb::parallel_do + +#define ITER_RANGE 1000 +#define ITEMS_TO_FEED 50 +#define INNER_ITER_RANGE 100 +#define OUTER_ITER_RANGE 50 + +#define PREPARE_RANGE(Iterator, rangeSize) \ + size_t test_vector[rangeSize + 1]; \ + for (int i =0; i < rangeSize; i++) \ + test_vector[i] = i; \ + Iterator begin(&test_vector[0]); \ + Iterator end(&test_vector[rangeSize]) + +void Feed ( tbb::parallel_do_feeder<size_t> &feeder, size_t val ) { + if (g_FedTasksCount < ITEMS_TO_FEED) { + ++g_FedTasksCount; + feeder.add(val); + } +} + +#include "harness_iterator.h" + +#if TBB_USE_EXCEPTIONS + +// Simple functor object with exception +class SimpleParDoBody { +public: + void operator() ( size_t &value ) const { + ++g_CurExecuted; + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; + Harness::ConcurrencyTracker ct; + value += 1000; + WaitUntilConcurrencyPeaks(); + ThrowTestException(1); + } +}; + +// Simple functor object with exception and feeder +class SimpleParDoBodyWithFeeder : SimpleParDoBody { +public: + void operator() ( size_t &value, tbb::parallel_do_feeder<size_t> &feeder ) const { + Feed(feeder, 0); + SimpleParDoBody::operator()(value); + } +}; + +// Tests exceptions without nesting +template <class Iterator, class simple_body> +void Test1_parallel_do () { + ResetGlobals(); + PREPARE_RANGE(Iterator, ITER_RANGE); + TRY(); + tbb::parallel_do<Iterator, simple_body>(begin, end, simple_body() ); + CATCH_AND_ASSERT(); + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived cancellation"); + ASSERT (g_NumExceptionsCaught == 1, "No try_blocks in any body expected in this test"); + if ( !g_SolitaryException ) + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); + +} // void Test1_parallel_do () + +template <class Iterator> +class OuterParDoBody { +public: + void operator()( size_t& /*value*/ ) const { + ++g_OuterParCalls; + PREPARE_RANGE(Iterator, INNER_ITER_RANGE); + tbb::parallel_do<Iterator, SimpleParDoBody>(begin, end, SimpleParDoBody()); + } +}; + +template <class Iterator> +class OuterParDoBodyWithFeeder : OuterParDoBody<Iterator> { +public: + void operator()( size_t& value, tbb::parallel_do_feeder<size_t>& feeder ) const { + Feed(feeder, 0); + OuterParDoBody<Iterator>::operator()(value); + } +}; + +//! Uses parallel_do body containing an inner parallel_do with the default context not wrapped by a try-block. +/** Inner algorithms are spawned inside the new bound context by default. Since + exceptions thrown from the inner parallel_do are not handled by the caller + (outer parallel_do body) in this test, they will cancel all the sibling inner + algorithms. **/ +template <class Iterator, class outer_body> +void Test2_parallel_do () { + ResetGlobals(); + PREPARE_RANGE(Iterator, ITER_RANGE); + TRY(); + tbb::parallel_do<Iterator, outer_body >(begin, end, outer_body() ); + CATCH_AND_ASSERT(); + //if ( g_SolitaryException ) + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived cancellation"); + ASSERT (g_NumExceptionsCaught == 1, "No try_blocks in any body expected in this test"); + if ( !g_SolitaryException ) + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); +} // void Test2_parallel_do () + +template <class Iterator> +class OuterParDoBodyWithIsolatedCtx { +public: + void operator()( size_t& /*value*/ ) const { + tbb::task_group_context ctx(tbb::task_group_context::isolated); + ++g_OuterParCalls; + PREPARE_RANGE(Iterator, INNER_ITER_RANGE); + tbb::parallel_do<Iterator, SimpleParDoBody>(begin, end, SimpleParDoBody(), ctx); + } +}; + +template <class Iterator> +class OuterParDoBodyWithIsolatedCtxWithFeeder : OuterParDoBodyWithIsolatedCtx<Iterator> { +public: + void operator()( size_t& value, tbb::parallel_do_feeder<size_t> &feeder ) const { + Feed(feeder, 0); + OuterParDoBodyWithIsolatedCtx<Iterator>::operator()(value); + } +}; + +//! Uses parallel_do body invoking an inner parallel_do with an isolated context without a try-block. +/** Even though exceptions thrown from the inner parallel_do are not handled + by the caller in this test, they will not affect sibling inner algorithms + already running because of the isolated contexts. However because the first + exception cancels the root parallel_do, at most the first g_NumThreads subranges + will be processed (which launch inner parallel_dos) **/ +template <class Iterator, class outer_body> +void Test3_parallel_do () { + ResetGlobals(); + PREPARE_RANGE(Iterator, OUTER_ITER_RANGE); + intptr_t innerCalls = INNER_ITER_RANGE, + // The assumption here is the same as in outer parallel fors. + minExecuted = (g_NumThreads - 1) * innerCalls; + g_Master = Harness::CurrentTid(); + TRY(); + tbb::parallel_do<Iterator, outer_body >(begin, end, outer_body()); + CATCH_AND_ASSERT(); + // figure actual number of expected executions given the number of outer PDos started. + minExecuted = (g_OuterParCalls - 1) * innerCalls; + // one extra thread may run a task that sees cancellation. Infrequent but possible + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived exception"); + if(g_TGCCancelled > g_NumThreads) REMARK("Extra thread(s) executed after cancel (%d vs. %d)\n", + (int)g_TGCCancelled, (int)g_NumThreads); + if ( g_SolitaryException ) { + ASSERT (g_CurExecuted > minExecuted, "Too few tasks survived exception"); + ASSERT (g_CurExecuted <= minExecuted + (g_ExecutedAtLastCatch + g_NumThreads), "Too many tasks survived exception"); + } + ASSERT (g_NumExceptionsCaught == 1, "No try_blocks in any body expected in this test"); + if ( !g_SolitaryException ) + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); +} // void Test3_parallel_do () + +template <class Iterator> +class OuterParDoWithEhBody { +public: + void operator()( size_t& /*value*/ ) const { + tbb::task_group_context ctx(tbb::task_group_context::isolated); + ++g_OuterParCalls; + PREPARE_RANGE(Iterator, INNER_ITER_RANGE); + TRY(); + tbb::parallel_do<Iterator, SimpleParDoBody>(begin, end, SimpleParDoBody(), ctx); + CATCH(); + } +}; + +template <class Iterator> +class OuterParDoWithEhBodyWithFeeder : NoAssign, OuterParDoWithEhBody<Iterator> { +public: + void operator()( size_t &value, tbb::parallel_do_feeder<size_t> &feeder ) const { + Feed(feeder, 0); + OuterParDoWithEhBody<Iterator>::operator()(value); + } +}; + +//! Uses parallel_for body invoking an inner parallel_for (with default bound context) inside a try-block. +/** Since exception(s) thrown from the inner parallel_for are handled by the caller + in this test, they do not affect neither other tasks of the the root parallel_for + nor sibling inner algorithms. **/ +template <class Iterator, class outer_body_with_eh> +void Test4_parallel_do () { + ResetGlobals( true, true ); + PREPARE_RANGE(Iterator, OUTER_ITER_RANGE); + g_Master = Harness::CurrentTid(); + TRY(); + tbb::parallel_do<Iterator, outer_body_with_eh>(begin, end, outer_body_with_eh()); + CATCH(); + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "All exceptions must have been handled in the parallel_do body"); + intptr_t innerCalls = INNER_ITER_RANGE, + outerCalls = OUTER_ITER_RANGE + g_FedTasksCount, + maxExecuted = outerCalls * innerCalls, + minExecuted = 0; + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived exception"); + if ( g_SolitaryException ) { + minExecuted = maxExecuted - innerCalls; + ASSERT (g_NumExceptionsCaught == 1, "No exception registered"); + ASSERT (g_CurExecuted >= minExecuted, "Too few tasks executed"); + // This test has the same property as Test4 (parallel_for); the exception can be + // thrown, but some number of tasks from the outer Pdo can execute after the throw but + // before the cancellation is signaled (have seen 36). + ASSERT_WARNING(g_CurExecuted < maxExecuted || g_TGCCancelled, "All tasks survived exception. Oversubscription?"); + } + else { + minExecuted = g_NumExceptionsCaught; + ASSERT (g_NumExceptionsCaught > 1 && g_NumExceptionsCaught <= outerCalls, "Unexpected actual number of exceptions"); + ASSERT (g_CurExecuted >= minExecuted, "Too many executed tasks reported"); + ASSERT (g_CurExecuted < g_ExecutedAtLastCatch + g_NumThreads + outerCalls, "Too many tasks survived multiple exceptions"); + ASSERT (g_CurExecuted <= outerCalls * (1 + g_NumThreads), "Too many tasks survived exception"); + } +} // void Test4_parallel_do () + +// This body throws an exception only if the task was added by feeder +class ParDoBodyWithThrowingFeederTasks { +public: + //! This form of the function call operator can be used when the body needs to add more work during the processing + void operator() ( size_t &value, tbb::parallel_do_feeder<size_t> &feeder ) const { + ++g_CurExecuted; + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; + Feed(feeder, 1); + if (value == 1) + ThrowTestException(1); + } +}; // class ParDoBodyWithThrowingFeederTasks + +// Test exception in task, which was added by feeder. +template <class Iterator> +void Test5_parallel_do () { + ResetGlobals(); + PREPARE_RANGE(Iterator, ITER_RANGE); + g_Master = Harness::CurrentTid(); + TRY(); + tbb::parallel_do<Iterator, ParDoBodyWithThrowingFeederTasks>(begin, end, ParDoBodyWithThrowingFeederTasks()); + CATCH(); + if (g_SolitaryException) { + // Failure occurs when g_ExceptionInMaster is false, but all the 1 values in the range + // are handled by the master thread. In this case no throw occurs. + ASSERT (l_ExceptionCaughtAtCurrentLevel // we saw an exception + || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) // non-master throws but none tried + || (g_ExceptionInMaster && !g_MasterExecutedThrow) // master throws but master didn't try + , "At least one exception should occur"); + if(!g_ExceptionCaught) { + if(g_ExceptionInMaster) + REMARK("PDo exception not thrown; non-masters handled all throwing values.\n"); + else + REMARK("PDo exception not thrown; master handled all throwing values.\n"); + } + } +} // void Test5_parallel_do () + +#endif /* TBB_USE_EXCEPTIONS */ + +class ParDoBodyToCancel { +public: + void operator()( size_t& /*value*/ ) const { + ++g_CurExecuted; + CancellatorTask::WaitUntilReady(); + } +}; + +class ParDoBodyToCancelWithFeeder : ParDoBodyToCancel { +public: + void operator()( size_t& value, tbb::parallel_do_feeder<size_t> &feeder ) const { + Feed(feeder, 0); + ParDoBodyToCancel::operator()(value); + } +}; + +template<class B, class Iterator> +class ParDoWorkerTask : public tbb::task { + tbb::task_group_context &my_ctx; + + tbb::task* execute () __TBB_override { + PREPARE_RANGE(Iterator, INNER_ITER_RANGE); + tbb::parallel_do<Iterator, B>( begin, end, B(), my_ctx ); + return NULL; + } +public: + ParDoWorkerTask ( tbb::task_group_context& ctx ) : my_ctx(ctx) {} +}; + +//! Test for cancelling an algorithm from outside (from a task running in parallel with the algorithm). +template <class Iterator, class body_to_cancel> +void TestCancelation1_parallel_do () { + ResetGlobals( false ); + intptr_t threshold = 10; + tbb::task_group_context ctx; + ctx.reset(); + tbb::empty_task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + r.set_ref_count(3); + r.spawn( *new( r.allocate_child() ) CancellatorTask(ctx, threshold) ); + __TBB_Yield(); + r.spawn( *new( r.allocate_child() ) ParDoWorkerTask<body_to_cancel, Iterator>(ctx) ); + TRY(); + r.wait_for_all(); + CATCH_AND_FAIL(); + ASSERT (g_CurExecuted < g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks were executed after cancellation"); + r.destroy(r); +} + +class ParDoBodyToCancel2 { +public: + void operator()( size_t& /*value*/ ) const { + ++g_CurExecuted; + Harness::ConcurrencyTracker ct; + // The test will hang (and be timed out by the test system) if is_cancelled() is broken + while( !tbb::task::self().is_cancelled() ) + __TBB_Yield(); + } +}; + +class ParDoBodyToCancel2WithFeeder : ParDoBodyToCancel2 { +public: + void operator()( size_t& value, tbb::parallel_do_feeder<size_t> &feeder ) const { + Feed(feeder, 0); + ParDoBodyToCancel2::operator()(value); + } +}; + +//! Test for cancelling an algorithm from outside (from a task running in parallel with the algorithm). +/** This version also tests task::is_cancelled() method. **/ +template <class Iterator, class body_to_cancel> +void TestCancelation2_parallel_do () { + ResetGlobals(); + RunCancellationTest<ParDoWorkerTask<body_to_cancel, Iterator>, CancellatorTask2>(); +} + +#define RunWithSimpleBody(func, body) \ + func<Harness::RandomIterator<size_t>, body>(); \ + func<Harness::RandomIterator<size_t>, body##WithFeeder>(); \ + func<Harness::ForwardIterator<size_t>, body>(); \ + func<Harness::ForwardIterator<size_t>, body##WithFeeder>() + +#define RunWithTemplatedBody(func, body) \ + func<Harness::RandomIterator<size_t>, body<Harness::RandomIterator<size_t> > >(); \ + func<Harness::RandomIterator<size_t>, body##WithFeeder<Harness::RandomIterator<size_t> > >(); \ + func<Harness::ForwardIterator<size_t>, body<Harness::ForwardIterator<size_t> > >(); \ + func<Harness::ForwardIterator<size_t>, body##WithFeeder<Harness::ForwardIterator<size_t> > >() + +void RunParDoTests() { + REMARK( "parallel do tests\n" ); + tbb::task_scheduler_init init (g_NumThreads); + g_Master = Harness::CurrentTid(); +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + RunWithSimpleBody(Test1_parallel_do, SimpleParDoBody); + RunWithTemplatedBody(Test2_parallel_do, OuterParDoBody); + RunWithTemplatedBody(Test3_parallel_do, OuterParDoBodyWithIsolatedCtx); + RunWithTemplatedBody(Test4_parallel_do, OuterParDoWithEhBody); + Test5_parallel_do<Harness::ForwardIterator<size_t> >(); + Test5_parallel_do<Harness::RandomIterator<size_t> >(); +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ + RunWithSimpleBody(TestCancelation1_parallel_do, ParDoBodyToCancel); + RunWithSimpleBody(TestCancelation2_parallel_do, ParDoBodyToCancel2); +} + +//////////////////////////////////////////////////////////////////////////////// +// Tests for tbb::pipeline + +#define NUM_ITEMS 100 + +const size_t c_DataEndTag = size_t(~0); + +int g_NumTokens = 0; + +// Simple input filter class, it assigns 1 to all array members +// It stops when it receives item equal to -1 +class InputFilter: public tbb::filter { + tbb::atomic<size_t> m_Item; + size_t m_Buffer[NUM_ITEMS + 1]; +public: + InputFilter() : tbb::filter(parallel) { + m_Item = 0; + for (size_t i = 0; i < NUM_ITEMS; ++i ) + m_Buffer[i] = 1; + m_Buffer[NUM_ITEMS] = c_DataEndTag; + } + + void* operator()( void* ) __TBB_override { + size_t item = m_Item.fetch_and_increment(); + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; + if(item == 1) { + ++g_PipelinesStarted; // count on emitting the first item. + } + if ( item >= NUM_ITEMS ) + return NULL; + m_Buffer[item] = 1; + return &m_Buffer[item]; + } + + size_t* buffer() { return m_Buffer; } +}; // class InputFilter + +// Pipeline filter, without exceptions throwing +class NoThrowFilter : public tbb::filter { + size_t m_Value; +public: + enum operation { + addition, + subtraction, + multiplication + } m_Operation; + + NoThrowFilter(operation _operation, size_t value, bool is_parallel) + : filter(is_parallel? tbb::filter::parallel : tbb::filter::serial_in_order), + m_Value(value), m_Operation(_operation) + {} + void* operator()(void* item) __TBB_override { + size_t &value = *(size_t*)item; + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; + ASSERT(value != c_DataEndTag, "terminator element is being processed"); + switch (m_Operation){ + case addition: + value += m_Value; + break; + case subtraction: + value -= m_Value; + break; + case multiplication: + value *= m_Value; + break; + default: + ASSERT(0, "Wrong operation parameter passed to NoThrowFilter"); + } // switch (m_Operation) + return item; + } +}; + +// Test pipeline without exceptions throwing +void Test0_pipeline () { + ResetGlobals(); + // Run test when serial filter is the first non-input filter + InputFilter inputFilter; //Emits NUM_ITEMS items + NoThrowFilter filter1(NoThrowFilter::addition, 99, false); + NoThrowFilter filter2(NoThrowFilter::subtraction, 90, true); + NoThrowFilter filter3(NoThrowFilter::multiplication, 5, false); + // Result should be 50 for all items except the last + tbb::pipeline p; + p.add_filter(inputFilter); + p.add_filter(filter1); + p.add_filter(filter2); + p.add_filter(filter3); + p.run(8); + for (size_t i = 0; i < NUM_ITEMS; ++i) + ASSERT(inputFilter.buffer()[i] == 50, "pipeline didn't process items properly"); +} // void Test0_pipeline () + +#if TBB_USE_EXCEPTIONS + +// Simple filter with exception throwing. If parallel, will wait until +// as many parallel filters start as there are threads. +class SimpleFilter : public tbb::filter { + bool m_canThrow; +public: + SimpleFilter (tbb::filter::mode _mode, bool canThrow ) : filter (_mode), m_canThrow(canThrow) {} + void* operator()(void* item) __TBB_override { + ++g_CurExecuted; + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled() ) ++g_TGCCancelled; + if ( m_canThrow ) { + if ( !is_serial() ) { + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks( min(g_NumTokens, g_NumThreads) ); + } + ThrowTestException(1); + } + return item; + } +}; // class SimpleFilter + +// This enumeration represents filters order in pipeline +struct FilterSet { + tbb::filter::mode mode1, + mode2; + bool throw1, + throw2; + + FilterSet( tbb::filter::mode m1, tbb::filter::mode m2, bool t1, bool t2 ) + : mode1(m1), mode2(m2), throw1(t1), throw2(t2) + {} +}; // struct FilterSet + +FilterSet serial_parallel( tbb::filter::serial, tbb::filter::parallel, /*throw1*/false, /*throw2*/true ); + +template<typename InFilter, typename Filter> +class CustomPipeline : protected tbb::pipeline { + InFilter inputFilter; + Filter filter1; + Filter filter2; +public: + CustomPipeline( const FilterSet& filters ) + : filter1(filters.mode1, filters.throw1), filter2(filters.mode2, filters.throw2) + { + add_filter(inputFilter); + add_filter(filter1); + add_filter(filter2); + } + void run () { tbb::pipeline::run(g_NumTokens); } + void run ( tbb::task_group_context& ctx ) { tbb::pipeline::run(g_NumTokens, ctx); } + + using tbb::pipeline::add_filter; +}; + +typedef CustomPipeline<InputFilter, SimpleFilter> SimplePipeline; + +// Tests exceptions without nesting +void Test1_pipeline ( const FilterSet& filters ) { + ResetGlobals(); + SimplePipeline testPipeline(filters); + TRY(); + testPipeline.run(); + if ( g_CurExecuted == 2 * NUM_ITEMS ) { + // all the items were processed, though an exception was supposed to occur. + if(!g_ExceptionInMaster && g_NonMasterExecutedThrow > 0) { + // if !g_ExceptionInMaster, the master thread is not allowed to throw. + // if g_nonMasterExcutedThrow > 0 then a thread besides the master tried to throw. + ASSERT(filters.mode1 != tbb::filter::parallel && filters.mode2 != tbb::filter::parallel, "Unusual count"); + } + else { + REMARK("test1_Pipeline with %d threads: Only the master thread tried to throw, and it is not allowed to.\n", (int)g_NumThreads); + } + // In case of all serial filters they might be all executed in the thread(s) + // where exceptions are not allowed by the common test logic. So we just quit. + return; + } + CATCH_AND_ASSERT(); + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived exception"); + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); + ASSERT (g_NumExceptionsCaught == 1, "No try_blocks in any body expected in this test"); + if ( !g_SolitaryException ) + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); + +} // void Test1_pipeline () + +// Filter with nesting +class OuterFilter : public tbb::filter { +public: + OuterFilter (tbb::filter::mode _mode, bool ) : filter (_mode) {} + + void* operator()(void* item) __TBB_override { + ++g_OuterParCalls; + SimplePipeline testPipeline(serial_parallel); + testPipeline.run(); + return item; + } +}; // class OuterFilter + +//! Uses pipeline containing an inner pipeline with the default context not wrapped by a try-block. +/** Inner algorithms are spawned inside the new bound context by default. Since + exceptions thrown from the inner pipeline are not handled by the caller + (outer pipeline body) in this test, they will cancel all the sibling inner + algorithms. **/ +void Test2_pipeline ( const FilterSet& filters ) { + ResetGlobals(); + g_NestedPipelines = true; + CustomPipeline<InputFilter, OuterFilter> testPipeline(filters); + TRY(); + testPipeline.run(); + CATCH_AND_ASSERT(); + bool okayNoExceptionCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow); + ASSERT (g_NumExceptionsCaught == 1 || okayNoExceptionCaught, "No try_blocks in any body expected in this test"); + if ( g_SolitaryException ) { + if( g_TGCCancelled > g_NumThreads) REMARK( "Extra tasks ran after exception thrown (%d vs. %d)\n", + (int)g_TGCCancelled, (int)g_NumThreads); + } + else { + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived exception"); + } +} // void Test2_pipeline () + +//! creates isolated inner pipeline and runs it. +class OuterFilterWithIsolatedCtx : public tbb::filter { +public: + OuterFilterWithIsolatedCtx(tbb::filter::mode m, bool ) : filter(m) {} + + void* operator()(void* item) __TBB_override { + ++g_OuterParCalls; + tbb::task_group_context ctx(tbb::task_group_context::isolated); + // create inner pipeline with serial input, parallel output filter, second filter throws + SimplePipeline testPipeline(serial_parallel); + testPipeline.run(ctx); + return item; + } +}; // class OuterFilterWithIsolatedCtx + +//! Uses pipeline invoking an inner pipeline with an isolated context without a try-block. +/** Even though exceptions thrown from the inner pipeline are not handled + by the caller in this test, they will not affect sibling inner algorithms + already running because of the isolated contexts. However because the first + exception cancels the root parallel_do only the first g_NumThreads subranges + will be processed (which launch inner pipelines) **/ +void Test3_pipeline ( const FilterSet& filters ) { + for( int nTries = 1; nTries <= 4; ++nTries) { + ResetGlobals(); + g_NestedPipelines = true; + g_Master = Harness::CurrentTid(); + intptr_t innerCalls = NUM_ITEMS, + minExecuted = (g_NumThreads - 1) * innerCalls; + CustomPipeline<InputFilter, OuterFilterWithIsolatedCtx> testPipeline(filters); + TRY(); + testPipeline.run(); + CATCH_AND_ASSERT(); + + bool okayNoExceptionCaught = (g_ExceptionInMaster && !g_MasterExecuted) || + (!g_ExceptionInMaster && !g_NonMasterExecuted); + // only test assertions if the test threw an exception (or we don't care) + bool testSucceeded = okayNoExceptionCaught || g_NumExceptionsCaught > 0; + if(testSucceeded) { + if (g_SolitaryException) { + + // The test is one outer pipeline with two NestedFilters that each start an inner pipeline. + // Each time the input filter of a pipeline delivers its first item, it increments + // g_PipelinesStarted. When g_SolitaryException, the throw will not occur until + // g_PipelinesStarted >= 3. (This is so at least a second pipeline in its own isolated + // context will start; that is what we're testing.) + // + // There are two pipelines which will NOT run to completion when a solitary throw + // happens in an isolated inner context: the outer pipeline and the pipeline which + // throws. All the other pipelines which start should run to completion. But only + // inner body invocations are counted. + // + // So g_CurExecuted should be about + // + // (2*NUM_ITEMS) * (g_PipelinesStarted - 2) + 1 + // ^ executions for each completed pipeline + // ^ completing pipelines (remembering two will not complete) + // ^ one for the inner throwing pipeline + + minExecuted = (2*NUM_ITEMS) * (g_PipelinesStarted - 2) + 1; + // each failing pipeline must execute at least two tasks + ASSERT(g_CurExecuted >= minExecuted, "Too few tasks survived exception"); + // no more than g_NumThreads tasks will be executed in a cancelled context. Otherwise + // tasks not executing at throw were scheduled. + ASSERT( g_TGCCancelled <= g_NumThreads, "Tasks not in-flight were executed"); + ASSERT(g_NumExceptionsCaught == 1, "Should have only one exception"); + // if we're only throwing from the master thread, and that thread didn't + // participate in the pipelines, then no throw occurred. + if(g_ExceptionInMaster && !g_MasterExecuted) { + REMARK_ONCE("Master expected to throw, but didn't participate.\n"); + } + else if(!g_ExceptionInMaster && !g_NonMasterExecuted) { + REMARK_ONCE("Non-master expected to throw, but didn't participate.\n"); + } + } + ASSERT (g_NumExceptionsCaught == 1 || okayNoExceptionCaught, "No try_blocks in any body expected in this test"); + ASSERT ((g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads) || okayNoExceptionCaught, "Too many tasks survived exception"); + if(nTries > 1) REMARK("Test3_pipeline succeeeded on try %d\n", nTries); + return; + } + } + REMARK_ONCE("Test3_pipeline failed for g_NumThreads==%d, g_ExceptionInMaster==%s , g_SolitaryException==%s\n", + g_NumThreads, g_ExceptionInMaster?"T":"F", g_SolitaryException?"T":"F"); +} // void Test3_pipeline () + +class OuterFilterWithEhBody : public tbb::filter { +public: + OuterFilterWithEhBody(tbb::filter::mode m, bool ) : filter(m) {} + + void* operator()(void* item) __TBB_override { + tbb::task_group_context ctx(tbb::task_group_context::isolated); + ++g_OuterParCalls; + SimplePipeline testPipeline(serial_parallel); + TRY(); + testPipeline.run(ctx); + CATCH(); + return item; + } +}; // class OuterFilterWithEhBody + +//! Uses pipeline body invoking an inner pipeline (with isolated context) inside a try-block. +/** Since exception(s) thrown from the inner pipeline are handled by the caller + in this test, they do not affect other tasks of the the root pipeline + nor sibling inner algorithms. **/ +void Test4_pipeline ( const FilterSet& filters ) { +#if __GNUC__ && !__INTEL_COMPILER + if ( strncmp(__VERSION__, "4.1.0", 5) == 0 ) { + REMARK_ONCE("Known issue: one of exception handling tests is skipped.\n"); + return; + } +#endif + ResetGlobals( true, true ); + // each outer pipeline stage will start NUM_ITEMS inner pipelines. + // each inner pipeline that doesn't throw will process NUM_ITEMS items. + // for solitary exception there will be one pipeline that only processes one stage, one item. + // innerCalls should be 2*NUM_ITEMS + intptr_t innerCalls = 2*NUM_ITEMS, + outerCalls = 2 * NUM_ITEMS, + maxExecuted = outerCalls * innerCalls; // the number of invocations of the inner pipelines + CustomPipeline<InputFilter, OuterFilterWithEhBody> testPipeline(filters); + TRY(); + testPipeline.run(); + CATCH_AND_ASSERT(); + intptr_t minExecuted = 0; + bool okayNoExceptionCaught = (g_ExceptionInMaster && !g_MasterExecuted) || + (!g_ExceptionInMaster && !g_NonMasterExecuted); + if ( g_SolitaryException ) { + minExecuted = maxExecuted - innerCalls; // one throwing inner pipeline + ASSERT (g_NumExceptionsCaught == 1 || okayNoExceptionCaught, "No exception registered"); + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived exception"); // probably will assert. + } + else { + // we assume throwing pipelines will not count + minExecuted = (outerCalls - g_NumExceptionsCaught) * innerCalls; + ASSERT((g_NumExceptionsCaught >= 1 && g_NumExceptionsCaught <= outerCalls)||okayNoExceptionCaught, "Unexpected actual number of exceptions"); + ASSERT (g_CurExecuted >= minExecuted, "Too many executed tasks reported"); + // too many already-scheduled tasks are started after the first exception is + // thrown. And g_ExecutedAtLastCatch is updated every time an exception is caught. + // So with multiple exceptions there are a variable number of tasks that have been + // discarded because of the signals. + // each throw is caught, so we will see many cancelled tasks. g_ExecutedAtLastCatch is + // updated with each throw, so the value will be the number of tasks executed at the last + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks survived multiple exceptions"); + } +} // void Test4_pipeline () + +//! Testing filter::finalize method +#define BUFFER_SIZE 32 +#define NUM_BUFFERS 1024 + +tbb::atomic<size_t> g_AllocatedCount; // Number of currently allocated buffers +tbb::atomic<size_t> g_TotalCount; // Total number of allocated buffers + +//! Base class for all filters involved in finalize method testing +class FinalizationBaseFilter : public tbb::filter { +public: + FinalizationBaseFilter ( tbb::filter::mode m ) : filter(m) {} + + // Deletes buffers if exception occurred + virtual void finalize( void* item ) __TBB_override { + size_t* m_Item = (size_t*)item; + delete[] m_Item; + --g_AllocatedCount; + } +}; + +//! Input filter to test finalize method +class InputFilterWithFinalization: public FinalizationBaseFilter { +public: + InputFilterWithFinalization() : FinalizationBaseFilter(tbb::filter::serial) { + g_TotalCount = 0; + } + void* operator()( void* ) __TBB_override { + if (g_TotalCount == NUM_BUFFERS) + return NULL; + size_t* item = new size_t[BUFFER_SIZE]; + for (int i = 0; i < BUFFER_SIZE; i++) + item[i] = 1; + ++g_TotalCount; + ++g_AllocatedCount; + return item; + } +}; + +// The filter multiplies each buffer item by 10. +class ProcessingFilterWithFinalization : public FinalizationBaseFilter { +public: + ProcessingFilterWithFinalization (tbb::filter::mode _mode, bool) : FinalizationBaseFilter (_mode) {} + + void* operator()( void* item) __TBB_override { + if(g_Master == Harness::CurrentTid()) g_MasterExecuted = true; + else g_NonMasterExecuted = true; + if( tbb::task::self().is_cancelled()) ++g_TGCCancelled; + if (g_TotalCount > NUM_BUFFERS / 2) + ThrowTestException(1); + size_t* m_Item = (size_t*)item; + for (int i = 0; i < BUFFER_SIZE; i++) + m_Item[i] *= 10; + return item; + } +}; + +// Output filter deletes previously allocated buffer +class OutputFilterWithFinalization : public FinalizationBaseFilter { +public: + OutputFilterWithFinalization (tbb::filter::mode m) : FinalizationBaseFilter (m) {} + + void* operator()( void* item) __TBB_override { + size_t* m_Item = (size_t*)item; + delete[] m_Item; + --g_AllocatedCount; + return NULL; + } +}; + +//! Tests filter::finalize method +void Test5_pipeline ( const FilterSet& filters ) { + ResetGlobals(); + g_AllocatedCount = 0; + CustomPipeline<InputFilterWithFinalization, ProcessingFilterWithFinalization> testPipeline(filters); + OutputFilterWithFinalization my_output_filter(tbb::filter::parallel); + + testPipeline.add_filter(my_output_filter); + TRY(); + testPipeline.run(); + CATCH(); + ASSERT (g_AllocatedCount == 0, "Memory leak: Some my_object weren't destroyed"); +} // void Test5_pipeline () + +//! Tests pipeline function passed with different combination of filters +template<void testFunc(const FilterSet&)> +void TestWithDifferentFilters() { + const int NumFilterTypes = 3; + const tbb::filter::mode modes[NumFilterTypes] = { + tbb::filter::parallel, + tbb::filter::serial, + tbb::filter::serial_out_of_order + }; + for ( int i = 0; i < NumFilterTypes; ++i ) { + for ( int j = 0; j < NumFilterTypes; ++j ) { + for ( int k = 0; k < 2; ++k ) + testFunc( FilterSet(modes[i], modes[j], k == 0, k != 0) ); + } + } +} + +#endif /* TBB_USE_EXCEPTIONS */ + +class FilterToCancel : public tbb::filter { +public: + FilterToCancel(bool is_parallel) + : filter( is_parallel ? tbb::filter::parallel : tbb::filter::serial_in_order ) + {} + void* operator()(void* item) __TBB_override { + ++g_CurExecuted; + CancellatorTask::WaitUntilReady(); + return item; + } +}; // class FilterToCancel + +template <class Filter_to_cancel> +class PipelineLauncherTask : public tbb::task { + tbb::task_group_context &my_ctx; +public: + PipelineLauncherTask ( tbb::task_group_context& ctx ) : my_ctx(ctx) {} + + tbb::task* execute () __TBB_override { + // Run test when serial filter is the first non-input filter + InputFilter inputFilter; + Filter_to_cancel filterToCancel(true); + tbb::pipeline p; + p.add_filter(inputFilter); + p.add_filter(filterToCancel); + p.run(g_NumTokens, my_ctx); + return NULL; + } +}; + +//! Test for cancelling an algorithm from outside (from a task running in parallel with the algorithm). +void TestCancelation1_pipeline () { + ResetGlobals(); + g_ThrowException = false; + intptr_t threshold = 10; + tbb::task_group_context ctx; + ctx.reset(); + tbb::empty_task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + r.set_ref_count(3); + r.spawn( *new( r.allocate_child() ) CancellatorTask(ctx, threshold) ); + __TBB_Yield(); + r.spawn( *new( r.allocate_child() ) PipelineLauncherTask<FilterToCancel>(ctx) ); + TRY(); + r.wait_for_all(); + CATCH_AND_FAIL(); + r.destroy(r); + ASSERT( g_TGCCancelled <= g_NumThreads, "Too many tasks survived cancellation"); + ASSERT (g_CurExecuted < g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks were executed after cancellation"); +} + +class FilterToCancel2 : public tbb::filter { +public: + FilterToCancel2(bool is_parallel) + : filter ( is_parallel ? tbb::filter::parallel : tbb::filter::serial_in_order) + {} + + void* operator()(void* item) __TBB_override { + ++g_CurExecuted; + Harness::ConcurrencyTracker ct; + // The test will hang (and be timed out by the test system) if is_cancelled() is broken + while( !tbb::task::self().is_cancelled() ) + __TBB_Yield(); + return item; + } +}; + +//! Test for cancelling an algorithm from outside (from a task running in parallel with the algorithm). +/** This version also tests task::is_cancelled() method. **/ +void TestCancelation2_pipeline () { + ResetGlobals(); + RunCancellationTest<PipelineLauncherTask<FilterToCancel2>, CancellatorTask2>(); + // g_CurExecuted is always >= g_ExecutedAtLastCatch, because the latter is always a snapshot of the + // former, and g_CurExecuted is monotonic increasing. so the comparison should be at least ==. + // If another filter is started after cancel but before cancellation is propagated, then the + // number will be larger. + ASSERT (g_CurExecuted <= g_ExecutedAtLastCatch, "Some tasks were executed after cancellation"); +} + +void RunPipelineTests() { + REMARK( "pipeline tests\n" ); + tbb::task_scheduler_init init (g_NumThreads); + g_Master = Harness::CurrentTid(); + g_NumTokens = 2 * g_NumThreads; + + Test0_pipeline(); +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + TestWithDifferentFilters<Test1_pipeline>(); + TestWithDifferentFilters<Test2_pipeline>(); + TestWithDifferentFilters<Test3_pipeline>(); + TestWithDifferentFilters<Test4_pipeline>(); + TestWithDifferentFilters<Test5_pipeline>(); +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ + TestCancelation1_pipeline(); + TestCancelation2_pipeline(); +} + + +#if TBB_USE_EXCEPTIONS + +class MyCapturedException : public tbb::captured_exception { +public: + static int m_refCount; + + MyCapturedException () : tbb::captured_exception("MyCapturedException", "test") { ++m_refCount; } + ~MyCapturedException () throw() { --m_refCount; } + + MyCapturedException* move () throw() __TBB_override { + MyCapturedException* movee = (MyCapturedException*)malloc(sizeof(MyCapturedException)); + return ::new (movee) MyCapturedException; + } + void destroy () throw() __TBB_override { + this->~MyCapturedException(); + free(this); + } + void operator delete ( void* p ) { free(p); } +}; + +int MyCapturedException::m_refCount = 0; + +void DeleteTbbException ( volatile tbb::tbb_exception* pe ) { + delete pe; +} + +void TestTbbExceptionAPI () { + const char *name = "Test captured exception", + *reason = "Unit testing"; + tbb::captured_exception e(name, reason); + ASSERT (strcmp(e.name(), name) == 0, "Setting captured exception name failed"); + ASSERT (strcmp(e.what(), reason) == 0, "Setting captured exception reason failed"); + tbb::captured_exception c(e); + ASSERT (strcmp(c.name(), e.name()) == 0, "Copying captured exception name failed"); + ASSERT (strcmp(c.what(), e.what()) == 0, "Copying captured exception reason failed"); + tbb::captured_exception *m = e.move(); + ASSERT (strcmp(m->name(), name) == 0, "Moving captured exception name failed"); + ASSERT (strcmp(m->what(), reason) == 0, "Moving captured exception reason failed"); + ASSERT (!e.name() && !e.what(), "Moving semantics broken"); + m->destroy(); + + MyCapturedException mce; + MyCapturedException *mmce = mce.move(); + ASSERT( MyCapturedException::m_refCount == 2, NULL ); + DeleteTbbException(mmce); + ASSERT( MyCapturedException::m_refCount == 1, NULL ); +} + +#endif /* TBB_USE_EXCEPTIONS */ + +/** If min and max thread numbers specified on the command line are different, + the test is run only for 2 sizes of the thread pool (MinThread and MaxThread) + to be able to test the high and low contention modes while keeping the test reasonably fast **/ +int TestMain () { + if(tbb::task_scheduler_init::default_num_threads() == 1) { + REPORT("Known issue: tests require multiple hardware threads\n"); + return Harness::Skipped; + } + REMARK ("Using %s\n", TBB_USE_CAPTURED_EXCEPTION ? "tbb:captured_exception" : "exact exception propagation"); + MinThread = min(tbb::task_scheduler_init::default_num_threads(), max(2, MinThread)); + MaxThread = max(MinThread, min(tbb::task_scheduler_init::default_num_threads(), MaxThread)); + ASSERT (FLAT_RANGE >= FLAT_GRAIN * MaxThread, "Fix defines"); + int step = max((MaxThread - MinThread + 1)/2, 1); + for ( g_NumThreads = MinThread; g_NumThreads <= MaxThread; g_NumThreads += step ) { + REMARK ("Number of threads %d\n", g_NumThreads); + // Execute in all the possible modes + for ( size_t j = 0; j < 4; ++j ) { + g_ExceptionInMaster = (j & 1) != 0; + g_SolitaryException = (j & 2) != 0; + REMARK("g_ExceptionInMaster==%s, g_SolitaryException==%s\n", g_ExceptionInMaster?"T":"F", g_SolitaryException?"T":"F"); + RunParForAndReduceTests(); + RunParDoTests(); + RunPipelineTests(); + } + } +#if TBB_USE_EXCEPTIONS + TestTbbExceptionAPI(); +#endif +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + REPORT("Known issue: exception handling tests are skipped.\n"); +#endif + return Harness::Done; +} + +#else /* !__TBB_TASK_GROUP_CONTEXT */ + +int TestMain () { + return Harness::Skipped; +} + +#endif /* !__TBB_TASK_GROUP_CONTEXT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_flow_graph.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_flow_graph.cpp new file mode 100644 index 00000000..9cc92a03 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_flow_graph.cpp @@ -0,0 +1,2081 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 2 +#define HARNESS_DEFAULT_MAX_THREADS 4 +#include "harness_defs.h" + +#if _MSC_VER + #pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning +#endif + +#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED + // Suppress "unreachable code" warning by VC++ 17.0-18.0 (VS 2012 or newer) + #pragma warning (disable: 4702) +#endif + +#include "harness.h" + +// global task_scheduler_observer is an imperfect tool to find how many threads are really +// participating. That was the hope, but it counts the entries into the marketplace, +// not the arena. +// #define USE_TASK_SCHEDULER_OBSERVER 1 + +#if _MSC_VER && defined(__INTEL_COMPILER) && !TBB_USE_DEBUG + #define TBB_RUN_BUFFERING_TEST __INTEL_COMPILER > 1210 +#else + #define TBB_RUN_BUFFERING_TEST 1 +#endif + +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#if TBB_USE_EXCEPTIONS +#if USE_TASK_SCHEDULER_OBSERVER +#include "tbb/task_scheduler_observer.h" +#endif +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include <iostream> +#include <vector> +#include "harness_assert.h" +#include "harness_checktype.h" + +inline intptr_t Existed() { return INT_MAX; } // resolve Existed in harness_eh.h + +#include "harness_eh.h" +#include <stdexcept> + +#define NUM_ITEMS 15 +int g_NumItems; + +tbb::atomic<unsigned> nExceptions; +tbb::atomic<intptr_t> g_TGCCancelled; + +enum TestNodeTypeEnum { nonThrowing, isThrowing }; + +static const size_t unlimited_type = 0; +static const size_t serial_type = 1; +static const size_t limited_type = 4; + +template<TestNodeTypeEnum T> struct TestNodeTypeName; +template<> struct TestNodeTypeName<nonThrowing> { static const char *name() { return "nonThrowing"; } }; +template<> struct TestNodeTypeName<isThrowing> { static const char *name() { return "isThrowing"; } }; + +template<size_t Conc> struct concurrencyName; +template<> struct concurrencyName<serial_type>{ static const char *name() { return "serial"; } }; +template<> struct concurrencyName<unlimited_type>{ static const char *name() { return "unlimited"; } }; +template<> struct concurrencyName<limited_type>{ static const char *name() { return "limited"; } }; + +// Class that provides waiting and throwing behavior. If we are not throwing, do nothing +// If serial, we can't wait for concurrency to peak; we may be the bottleneck and will +// stop further processing. We will execute g_NumThreads + 10 times (the "10" is somewhat +// arbitrary, and just makes sure there are enough items in the graph to keep it flowing), +// If parallel or serial and throwing, use Harness::ConcurrencyTracker to wait. + +template<size_t Conc, TestNodeTypeEnum t = nonThrowing> +class WaitThrow; + +template<> +class WaitThrow<serial_type,nonThrowing> { +protected: + void WaitAndThrow(int cnt, const char * /*name*/) { + if(cnt > g_NumThreads + 10) { + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks(); + } + } +}; + +template<> +class WaitThrow<serial_type,isThrowing> { +protected: + void WaitAndThrow(int cnt, const char * /*name*/) { + if(cnt > g_NumThreads + 10) { + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks(); + ThrowTestException(1); + } + } +}; + +// for nodes with limited concurrency, if that concurrency is < g_NumThreads, we need +// to make sure enough other nodes wait for concurrency to peak. If we are attached to +// N successors, for each item we pass to a successor, we will get N executions of the +// "absorbers" (because we broadcast to successors.) for an odd number of threads we +// need (g_NumThreads - limited + 1) / 2 items (that will give us one extra execution +// of an "absorber", but we can't change that without changing the behavior of the node.) +template<> +class WaitThrow<limited_type,nonThrowing> { +protected: + void WaitAndThrow(int cnt, const char * /*name*/) { + if(cnt <= (g_NumThreads - (int)limited_type + 1)/2) { + return; + } + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks(); + } +}; + +template<> +class WaitThrow<limited_type,isThrowing> { +protected: + void WaitAndThrow(int cnt, const char * /*name*/) { + Harness::ConcurrencyTracker ct; + if(cnt <= (g_NumThreads - (int)limited_type + 1)/2) { + return; + } + WaitUntilConcurrencyPeaks(); + ThrowTestException(1); + } +}; + +template<> +class WaitThrow<unlimited_type,nonThrowing> { +protected: + void WaitAndThrow(int /*cnt*/, const char * /*name*/) { + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks(); + } +}; + +template<> +class WaitThrow<unlimited_type,isThrowing> { +protected: + void WaitAndThrow(int /*cnt*/, const char * /*name*/) { + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks(); + ThrowTestException(1); + } +}; + +void +ResetGlobals(bool throwException = true, bool flog = false) { + nExceptions = 0; + g_TGCCancelled = 0; + ResetEhGlobals(throwException, flog); +} + +// -------source_node body ------------------ +template <class OutputType, TestNodeTypeEnum TType> +class test_source_body : WaitThrow<serial_type, TType> { + using WaitThrow<serial_type, TType>::WaitAndThrow; + tbb::atomic<int> *my_current_val; + int my_mult; +public: + test_source_body(tbb::atomic<int> &my_cnt, int multiplier = 1) : my_current_val(&my_cnt), my_mult(multiplier) { + REMARK("- --------- - - - constructed %lx\n", (size_t)(my_current_val)); + } + +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(OutputType & out) { + UPDATE_COUNTS(); + out = OutputType(my_mult * ++(*my_current_val)); + REMARK("xx(%lx) out == %d\n", (size_t)(my_current_val), (int)out); + if(*my_current_val > g_NumItems) { + REMARK(" ------ End of the line!\n"); + *my_current_val = g_NumItems; + return false; + } + WaitAndThrow((int)out,"test_source_body"); + return true; + } +#else + OutputType operator()(tbb::flow_control& fc) { + UPDATE_COUNTS(); + OutputType ret = OutputType(my_mult * ++(*my_current_val)); + if(*my_current_val > g_NumItems) { + *my_current_val = g_NumItems; + fc.stop(); + return OutputType(); + } + WaitAndThrow((int)ret,"test_input_body"); + return ret; + } +#endif + + int count_value() { return (int)*my_current_val; } +}; + +template <TestNodeTypeEnum TType> +class test_source_body<tbb::flow::continue_msg, TType> : WaitThrow<serial_type, TType> { + using WaitThrow<serial_type, TType>::WaitAndThrow; + tbb::atomic<int> *my_current_val; +public: + test_source_body(tbb::atomic<int> &my_cnt) : my_current_val(&my_cnt) { } +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(tbb::flow::continue_msg & out) { + UPDATE_COUNTS(); + int outint = ++(*my_current_val); + out = tbb::flow::continue_msg(); + if(*my_current_val > g_NumItems) { + *my_current_val = g_NumItems; + return false; + } + WaitAndThrow(outint,"test_source_body"); + return true; + } +#else + tbb::flow::continue_msg operator()( tbb::flow_control & fc) { + UPDATE_COUNTS(); + int outint = ++(*my_current_val); + if(*my_current_val > g_NumItems) { + *my_current_val = g_NumItems; + fc.stop(); + return tbb::flow::continue_msg(); + } + WaitAndThrow(outint,"test_input_body"); + return tbb::flow::continue_msg(); + } +#endif + + int count_value() { return (int)*my_current_val; } +}; + +// -------{function/continue}_node body ------------------ +template<class InputType, class OutputType, TestNodeTypeEnum T, size_t Conc> +class absorber_body : WaitThrow<Conc,T> { + using WaitThrow<Conc,T>::WaitAndThrow; + tbb::atomic<int> *my_count; +public: + absorber_body(tbb::atomic<int> &my_cnt) : my_count(&my_cnt) { } + OutputType operator()(const InputType &/*p_in*/) { + UPDATE_COUNTS(); + int out = ++(*my_count); + WaitAndThrow(out,"absorber_body"); + return OutputType(); + } + int count_value() { return *my_count; } +}; + +// -------multifunction_node body ------------------ + +// helper classes +template<int N,class PortsType> +struct IssueOutput { + typedef typename tbb::flow::tuple_element<N-1,PortsType>::type::output_type my_type; + + static void issue_tuple_element( PortsType &my_ports) { + ASSERT(tbb::flow::get<N-1>(my_ports).try_put(my_type()), "Error putting to successor"); + IssueOutput<N-1,PortsType>::issue_tuple_element(my_ports); + } +}; + +template<class PortsType> +struct IssueOutput<1,PortsType> { + typedef typename tbb::flow::tuple_element<0,PortsType>::type::output_type my_type; + + static void issue_tuple_element( PortsType &my_ports) { + ASSERT(tbb::flow::get<0>(my_ports).try_put(my_type()), "Error putting to successor"); + } +}; + +template<class InputType, class OutputTupleType, TestNodeTypeEnum T, size_t Conc> +class multifunction_node_body : WaitThrow<Conc,T> { + using WaitThrow<Conc,T>::WaitAndThrow; + static const int N = tbb::flow::tuple_size<OutputTupleType>::value; + typedef typename tbb::flow::multifunction_node<InputType,OutputTupleType> NodeType; + typedef typename NodeType::output_ports_type PortsType; + tbb::atomic<int> *my_count; +public: + multifunction_node_body(tbb::atomic<int> &my_cnt) : my_count(&my_cnt) { } + void operator()(const InputType& /*in*/, PortsType &my_ports) { + UPDATE_COUNTS(); + int out = ++(*my_count); + WaitAndThrow(out,"multifunction_node_body"); + // issue an item to each output port. + IssueOutput<N,PortsType>::issue_tuple_element(my_ports); + } + + int count_value() { return *my_count; } +}; + +// --------- body to sort items in sequencer_node +template<class BufferItemType> +struct sequencer_body { + size_t operator()(const BufferItemType &s) { + ASSERT(s, "sequencer item out of range (== 0)"); + return size_t(s) - 1; + } +}; + +// --------- body to compare the "priorities" of objects for priority_queue_node five priority levels 0-4. +template<class T> +struct myLess { + bool operator()(const T &t1, const T &t2) { + return (int(t1) % 5) < (int(t2) % 5); + } +}; + +// --------- type for < comparison in priority_queue_node. +template<class ItemType> +struct less_body { + bool operator()(const ItemType &lhs, const ItemType &rhs) { + return (int(lhs) % 3) < (int(rhs) % 3); + } +}; + +// --------- tag methods for tag_matching join_node +template<typename TT> +class tag_func { + TT my_mult; +public: + tag_func(TT multiplier) : my_mult(multiplier) { } + // operator() will return [0 .. Count) + tbb::flow::tag_value operator()( TT v) { + tbb::flow::tag_value t = tbb::flow::tag_value(v / my_mult); + return t; + } +}; + +// --------- Source body for split_node test. +template <class OutputTuple, TestNodeTypeEnum TType> +class tuple_test_source_body : WaitThrow<serial_type, TType> { + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type ItemType0; + typedef typename tbb::flow::tuple_element<1,OutputTuple>::type ItemType1; + using WaitThrow<serial_type, TType>::WaitAndThrow; + tbb::atomic<int> *my_current_val; +public: + tuple_test_source_body(tbb::atomic<int> &my_cnt) : my_current_val(&my_cnt) { } +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(OutputTuple & out) { + UPDATE_COUNTS(); + int ival = ++(*my_current_val); + out = OutputTuple(ItemType0(ival),ItemType1(ival)); + if(*my_current_val > g_NumItems) { + *my_current_val = g_NumItems; // jam the final value; we assert on it later. + return false; + } + WaitAndThrow(ival,"tuple_test_source_body"); + return true; + } +#else + OutputTuple operator()(tbb::flow_control& fc) { + UPDATE_COUNTS(); + int ival = ++(*my_current_val); + if(*my_current_val > g_NumItems) { + *my_current_val = g_NumItems; // jam the final value; we assert on it later. + fc.stop(); + return OutputTuple(); + } + WaitAndThrow(ival,"tuple_test_input_body"); + return OutputTuple(ItemType0(ival),ItemType1(ival)); + } +#endif + + int count_value() { return (int)*my_current_val; } +}; + +// ------- end of node bodies + +// source_node is only-serial. source_node can throw, or the function_node can throw. +// graph being tested is +// +// source_node+---+parallel function_node +// +// After each run the graph is reset(), to test the reset functionality. +// + + +template<class ItemType, TestNodeTypeEnum srcThrowType, TestNodeTypeEnum absorbThrowType> +void run_one_source_node_test(bool throwException, bool flog) { + typedef test_source_body<ItemType,srcThrowType> src_body_type; + typedef absorber_body<ItemType, tbb::flow::continue_msg, absorbThrowType, unlimited_type> parallel_absorb_body_type; + tbb::atomic<int> source_body_count; + tbb::atomic<int> absorber_body_count; + source_body_count = 0; + absorber_body_count = 0; + + tbb::flow::graph g; + + g_Master = Harness::CurrentTid(); + +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + + tbb::flow::input_node<ItemType> sn(g, src_body_type(source_body_count)); + parallel_absorb_body_type ab2(absorber_body_count); + tbb::flow::function_node<ItemType> parallel_fn(g,tbb::flow::unlimited,ab2); + make_edge(sn, parallel_fn); + for(int runcnt = 0; runcnt < 2; ++runcnt) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + sn.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + sn.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int src_cnt = tbb::flow::copy_body<src_body_type>(sn).count_value(); + int sink_cnt = tbb::flow::copy_body<parallel_absorb_body_type>(parallel_fn).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception flag in flow::graph not set"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "canceled flag not set"); + ASSERT(src_cnt <= g_NumItems, "Too many input_node items emitted"); + ASSERT(sink_cnt <= src_cnt, "Too many input_node items received"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(src_cnt == g_NumItems, "Incorrect # input_node items emitted"); + ASSERT(sink_cnt == src_cnt, "Incorrect # input_node items received"); + } + g.reset(); // resets the body of the input_node and the absorb_nodes. + source_body_count = 0; + absorber_body_count = 0; + ASSERT(!g.exception_thrown(), "Reset didn't clear exception_thrown()"); + ASSERT(!g.is_cancelled(), "Reset didn't clear is_cancelled()"); + src_cnt = tbb::flow::copy_body<src_body_type>(sn).count_value(); + sink_cnt = tbb::flow::copy_body<parallel_absorb_body_type>(parallel_fn).count_value(); + ASSERT(src_cnt == 0, "input_node count not reset"); + ASSERT(sink_cnt == 0, "sink_node count not reset"); + } +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} // run_one_input_node_test + + +template<class ItemType, TestNodeTypeEnum srcThrowType, TestNodeTypeEnum absorbThrowType> +void run_source_node_test() { + run_one_source_node_test<ItemType,srcThrowType,absorbThrowType>(false,false); + run_one_source_node_test<ItemType,srcThrowType,absorbThrowType>(true,false); + run_one_source_node_test<ItemType,srcThrowType,absorbThrowType>(true,true); +} // run_source_node_test + +void test_source_node() { + REMARK("Testing source_node\n"); + check_type<int>::check_type_counter = 0; + g_Wakeup_Msg = "source_node(1): Missed wakeup or machine is overloaded?"; + run_source_node_test<check_type<int>, isThrowing, nonThrowing>(); + ASSERT(!check_type<int>::check_type_counter, "Some items leaked in test"); + g_Wakeup_Msg = "source_node(2): Missed wakeup or machine is overloaded?"; + run_source_node_test<int, isThrowing, nonThrowing>(); + g_Wakeup_Msg = "source_node(3): Missed wakeup or machine is overloaded?"; + run_source_node_test<int, nonThrowing, isThrowing>(); + g_Wakeup_Msg = "source_node(4): Missed wakeup or machine is overloaded?"; + run_source_node_test<int, isThrowing, isThrowing>(); + g_Wakeup_Msg = "source_node(5): Missed wakeup or machine is overloaded?"; + run_source_node_test<check_type<int>, isThrowing, isThrowing>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; + ASSERT(!check_type<int>::check_type_counter, "Some items leaked in test"); +} + +// -------- utilities & types to test function_node and multifunction_node. + +// need to tell the template which node type I am using so it attaches successors correctly. +enum NodeFetchType { func_node_type, multifunc_node_type }; + +template<class NodeType, class ItemType, int indx, NodeFetchType NFT> +struct AttachPoint; + +template<class NodeType, class ItemType, int indx> +struct AttachPoint<NodeType,ItemType,indx,multifunc_node_type> { + static tbb::flow::sender<ItemType> &GetSender(NodeType &n) { + return tbb::flow::output_port<indx>(n); + } +}; + +template<class NodeType, class ItemType, int indx> +struct AttachPoint<NodeType,ItemType,indx,func_node_type> { + static tbb::flow::sender<ItemType> &GetSender(NodeType &n) { + return n; + } +}; + + +// common template for running function_node, multifunction_node. continue_node +// has different firing requirements, so it needs a different graph topology. +template< + class SourceNodeType, + class SourceNodeBodyType0, + class SourceNodeBodyType1, + NodeFetchType NFT, + class TestNodeType, + class TestNodeBodyType, + class TypeToSink0, // what kind of item are we sending to sink0 + class TypeToSink1, // what kind of item are we sending to sink1 + class SinkNodeType0, // will be same for function; + class SinkNodeType1, // may differ for multifunction_node + class SinkNodeBodyType0, + class SinkNodeBodyType1, + size_t Conc + > +void +run_one_functype_node_test(bool throwException, bool flog, const char * /*name*/) { + + char mymsg[132]; + char *saved_msg = const_cast<char *>(g_Wakeup_Msg); + tbb::flow::graph g; + + tbb::atomic<int> source0_count; + tbb::atomic<int> source1_count; + tbb::atomic<int> sink0_count; + tbb::atomic<int> sink1_count; + tbb::atomic<int> test_count; + source0_count = source1_count = sink0_count = sink1_count = test_count = 0; + +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + + g_Master = Harness::CurrentTid(); + SourceNodeType source0(g, SourceNodeBodyType0(source0_count)); + SourceNodeType source1(g, SourceNodeBodyType1(source1_count)); + TestNodeType node_to_test(g, Conc, TestNodeBodyType(test_count)); + SinkNodeType0 sink0(g,tbb::flow::unlimited,SinkNodeBodyType0(sink0_count)); + SinkNodeType1 sink1(g,tbb::flow::unlimited,SinkNodeBodyType1(sink1_count)); + make_edge(source0, node_to_test); + make_edge(source1, node_to_test); + make_edge(AttachPoint<TestNodeType, TypeToSink0, 0, NFT>::GetSender(node_to_test), sink0); + make_edge(AttachPoint<TestNodeType, TypeToSink1, 1, NFT>::GetSender(node_to_test), sink1); + + for(int iter = 0; iter < 2; ++iter) { // run, reset, run again + sprintf(mymsg, "%s iter=%d, threads=%d, throw=%s, flog=%s", saved_msg, iter, g_NumThreads, + throwException?"T":"F", flog?"T":"F"); + g_Wakeup_Msg = mymsg; + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source0.activate(); + source1.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source0.activate(); + source1.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb0_cnt = tbb::flow::copy_body<SourceNodeBodyType0>(source0).count_value(); + int sb1_cnt = tbb::flow::copy_body<SourceNodeBodyType1>(source1).count_value(); + int t_cnt = tbb::flow::copy_body<TestNodeBodyType>(node_to_test).count_value(); + int nb0_cnt = tbb::flow::copy_body<SinkNodeBodyType0>(sink0).count_value(); + int nb1_cnt = tbb::flow::copy_body<SinkNodeBodyType1>(sink1).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb0_cnt + sb1_cnt <= 2*g_NumItems, "Too many items sent by sources"); + ASSERT(sb0_cnt + sb1_cnt >= t_cnt, "Too many items received by test node"); + ASSERT(nb0_cnt + nb1_cnt <= t_cnt*2, "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(sb0_cnt + sb1_cnt == 2*g_NumItems, "Missing invocations of input_nodes"); + ASSERT(t_cnt == 2*g_NumItems, "Not all items reached test node"); + ASSERT(nb0_cnt == 2*g_NumItems && nb1_cnt == 2*g_NumItems, "Missing items in absorbers"); + } + g.reset(); // resets the body of the input_nodes, test_node and the absorb_nodes. + source0_count = source1_count = sink0_count = sink1_count = test_count = 0; + ASSERT(0 == tbb::flow::copy_body<SourceNodeBodyType0>(source0).count_value(),"Reset source 0 failed"); + ASSERT(0 == tbb::flow::copy_body<SourceNodeBodyType1>(source1).count_value(),"Reset source 1 failed"); + ASSERT(0 == tbb::flow::copy_body<TestNodeBodyType>(node_to_test).count_value(),"Reset test_node failed"); + ASSERT(0 == tbb::flow::copy_body<SinkNodeBodyType0>(sink0).count_value(),"Reset sink 0 failed"); + ASSERT(0 == tbb::flow::copy_body<SinkNodeBodyType1>(sink1).count_value(),"Reset sink 1 failed"); + + g_Wakeup_Msg = saved_msg; + } +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} + +// Test function_node +// +// graph being tested is +// +// input_node -\ /- parallel function_node +// \ / +// +function_node+ +// / \ x +// input_node -/ \- parallel function_node +// +// After each run the graph is reset(), to test the reset functionality. +// +template< + TestNodeTypeEnum SType1, // does source node 1 throw? + TestNodeTypeEnum SType2, // does source node 2 throw? + class Item12, // type of item passed between sources and test node + TestNodeTypeEnum FType, // does function node throw? + class Item23, // type passed from function_node to sink nodes + TestNodeTypeEnum NType1, // does sink node 1 throw? + TestNodeTypeEnum NType2, // does sink node 1 throw? + class NodePolicy, // rejecting,queueing + size_t Conc // is node concurrent? {serial | limited | unlimited} +> +void run_function_node_test() { + + typedef test_source_body<Item12,SType1> SBodyType1; + typedef test_source_body<Item12,SType2> SBodyType2; + typedef absorber_body<Item12, Item23, FType, Conc> TestBodyType; + typedef absorber_body<Item23,tbb::flow::continue_msg, NType1, unlimited_type> SinkBodyType1; + typedef absorber_body<Item23,tbb::flow::continue_msg, NType2, unlimited_type> SinkBodyType2; + + typedef tbb::flow::input_node<Item12> SrcType; + typedef tbb::flow::function_node<Item12, Item23, NodePolicy> TestType; + typedef tbb::flow::function_node<Item23,tbb::flow::continue_msg> SnkType; + + for(int i = 0; i < 4; ++i ) { + if(i != 2) { // doesn't make sense to flog a non-throwing test + bool doThrow = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_functype_node_test< + /*SourceNodeType*/ SrcType, + /*SourceNodeBodyType0*/ SBodyType1, + /*SourceNodeBodyType1*/ SBodyType2, + /* NFT */ func_node_type, + /*TestNodeType*/ TestType, + /*TestNodeBodyType*/ TestBodyType, + /*TypeToSink0 */ Item23, + /*TypeToSink1 */ Item23, + /*SinkNodeType0*/ SnkType, + /*SinkNodeType1*/ SnkType, + /*SinkNodeBodyType1*/ SinkBodyType1, + /*SinkNodeBodyType2*/ SinkBodyType2, + /*Conc*/ Conc> + (doThrow,doFlog,"function_node"); + } + } +} // run_function_node_test + +void test_function_node() { + REMARK("Testing function_node\n"); + // serial rejecting + g_Wakeup_Msg = "function_node(1a): Missed wakeup or machine is overloaded?"; + run_function_node_test<isThrowing, nonThrowing, int, nonThrowing, int, nonThrowing, nonThrowing, tbb::flow::rejecting, serial_type>(); + g_Wakeup_Msg = "function_node(1b): Missed wakeup or machine is overloaded?"; + run_function_node_test<nonThrowing, nonThrowing, int, isThrowing, int, nonThrowing, nonThrowing, tbb::flow::rejecting, serial_type>(); + g_Wakeup_Msg = "function_node(1c): Missed wakeup or machine is overloaded?"; + run_function_node_test<nonThrowing, nonThrowing, int, nonThrowing, int, isThrowing, nonThrowing, tbb::flow::rejecting, serial_type>(); + + // serial queueing + g_Wakeup_Msg = "function_node(2): Missed wakeup or machine is overloaded?"; + run_function_node_test<isThrowing, nonThrowing, int, nonThrowing, int, nonThrowing, nonThrowing, tbb::flow::queueing, serial_type>(); + run_function_node_test<nonThrowing, nonThrowing, int, isThrowing, int, nonThrowing, nonThrowing, tbb::flow::queueing, serial_type>(); + run_function_node_test<nonThrowing, nonThrowing, int, nonThrowing, int, isThrowing, nonThrowing, tbb::flow::queueing, serial_type>(); + check_type<int>::check_type_counter = 0; + run_function_node_test<nonThrowing, nonThrowing, check_type<int>, nonThrowing, check_type<int>, isThrowing, nonThrowing, tbb::flow::queueing, serial_type>(); + ASSERT(!check_type<int>::check_type_counter, "Some items leaked in test"); + + // unlimited parallel rejecting + g_Wakeup_Msg = "function_node(3): Missed wakeup or machine is overloaded?"; + run_function_node_test<isThrowing, nonThrowing, int, nonThrowing, int, nonThrowing, nonThrowing, tbb::flow::rejecting, unlimited_type>(); + run_function_node_test<nonThrowing, nonThrowing, int, isThrowing, int, nonThrowing, nonThrowing, tbb::flow::rejecting, unlimited_type>(); + run_function_node_test<nonThrowing, nonThrowing, int, nonThrowing, int, nonThrowing, isThrowing, tbb::flow::rejecting, unlimited_type>(); + + // limited parallel rejecting + g_Wakeup_Msg = "function_node(4): Missed wakeup or machine is overloaded?"; + run_function_node_test<isThrowing, nonThrowing, int, nonThrowing, int, nonThrowing, nonThrowing, tbb::flow::rejecting, limited_type>(); + run_function_node_test<nonThrowing, nonThrowing, int, isThrowing, int, nonThrowing, nonThrowing, tbb::flow::rejecting, (size_t)limited_type>(); + run_function_node_test<nonThrowing, nonThrowing, int, nonThrowing, int, nonThrowing, isThrowing, tbb::flow::rejecting, (size_t)limited_type>(); + + // limited parallel queueing + g_Wakeup_Msg = "function_node(5): Missed wakeup or machine is overloaded?"; + run_function_node_test<isThrowing, nonThrowing, int, nonThrowing, int, nonThrowing, nonThrowing, tbb::flow::queueing, (size_t)limited_type>(); + run_function_node_test<nonThrowing, nonThrowing, int, isThrowing, int, nonThrowing, nonThrowing, tbb::flow::queueing, (size_t)limited_type>(); + run_function_node_test<nonThrowing, nonThrowing, int, nonThrowing, int, nonThrowing, isThrowing, tbb::flow::queueing, (size_t)limited_type>(); + + // everyone throwing + g_Wakeup_Msg = "function_node(6): Missed wakeup or machine is overloaded?"; + run_function_node_test<isThrowing, isThrowing, int, isThrowing, int, isThrowing, isThrowing, tbb::flow::rejecting, unlimited_type>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// ----------------------------------- multifunction_node ---------------------------------- +// Test multifunction_node. +// +// graph being tested is +// +// input_node -\ /- parallel function_node +// \ / +// +multifunction_node+ +// / \ x +// input_node -/ \- parallel function_node +// +// After each run the graph is reset(), to test the reset functionality. The +// multifunction_node will put an item to each successor for every item +// received. +// +template< + TestNodeTypeEnum SType0, // does source node 1 throw? + TestNodeTypeEnum SType1, // does source node 2 thorw? + class Item12, // type of item passed between sources and test node + TestNodeTypeEnum FType, // does multifunction node throw? + class ItemTuple, // tuple of types passed from multifunction_node to sink nodes + TestNodeTypeEnum NType1, // does sink node 1 throw? + TestNodeTypeEnum NType2, // does sink node 2 throw? + class NodePolicy, // rejecting,queueing + size_t Conc // is node concurrent? {serial | limited | unlimited} +> +void run_multifunction_node_test() { + + typedef typename tbb::flow::tuple_element<0,ItemTuple>::type Item23Type0; + typedef typename tbb::flow::tuple_element<1,ItemTuple>::type Item23Type1; + typedef test_source_body<Item12,SType0> SBodyType1; + typedef test_source_body<Item12,SType1> SBodyType2; + typedef multifunction_node_body<Item12, ItemTuple, FType, Conc> TestBodyType; + typedef absorber_body<Item23Type0,tbb::flow::continue_msg, NType1, unlimited_type> SinkBodyType1; + typedef absorber_body<Item23Type1,tbb::flow::continue_msg, NType2, unlimited_type> SinkBodyType2; + + typedef tbb::flow::input_node<Item12> SrcType; + typedef tbb::flow::multifunction_node<Item12, ItemTuple, NodePolicy> TestType; + typedef tbb::flow::function_node<Item23Type0,tbb::flow::continue_msg> SnkType0; + typedef tbb::flow::function_node<Item23Type1,tbb::flow::continue_msg> SnkType1; + + for(int i = 0; i < 4; ++i ) { + if(i != 2) { // doesn't make sense to flog a non-throwing test + bool doThrow = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_functype_node_test< + /*SourceNodeType*/ SrcType, + /*SourceNodeBodyType0*/ SBodyType1, + /*SourceNodeBodyType1*/ SBodyType2, + /*NFT*/ multifunc_node_type, + /*TestNodeType*/ TestType, + /*TestNodeBodyType*/ TestBodyType, + /*TypeToSink0*/ Item23Type0, + /*TypeToSink1*/ Item23Type1, + /*SinkNodeType0*/ SnkType0, + /*SinkNodeType1*/ SnkType1, + /*SinkNodeBodyType0*/ SinkBodyType1, + /*SinkNodeBodyType1*/ SinkBodyType2, + /*Conc*/ Conc> + (doThrow,doFlog,"multifunction_node"); + } + } +} // run_multifunction_node_test + +void test_multifunction_node() { + REMARK("Testing multifunction_node\n"); + g_Wakeup_Msg = "multifunction_node(source throws,rejecting,serial): Missed wakeup or machine is overloaded?"; + // serial rejecting + run_multifunction_node_test<isThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,float>, nonThrowing, nonThrowing, tbb::flow::rejecting, serial_type>(); + g_Wakeup_Msg = "multifunction_node(test throws,rejecting,serial): Missed wakeup or machine is overloaded?"; + run_multifunction_node_test<nonThrowing, nonThrowing, int, isThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::rejecting, serial_type>(); + g_Wakeup_Msg = "multifunction_node(sink throws,rejecting,serial): Missed wakeup or machine is overloaded?"; + run_multifunction_node_test<nonThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, isThrowing, nonThrowing, tbb::flow::rejecting, serial_type>(); + + g_Wakeup_Msg = "multifunction_node(2): Missed wakeup or machine is overloaded?"; + // serial queueing + run_multifunction_node_test<isThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::queueing, serial_type>(); + run_multifunction_node_test<nonThrowing, nonThrowing, int, isThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::queueing, serial_type>(); + run_multifunction_node_test<nonThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, isThrowing, nonThrowing, tbb::flow::queueing, serial_type>(); + check_type<int>::check_type_counter = 0; + run_multifunction_node_test<nonThrowing, nonThrowing, check_type<int>, nonThrowing, tbb::flow::tuple<check_type<int>, check_type<int> >, isThrowing, nonThrowing, tbb::flow::queueing, serial_type>(); + ASSERT(!check_type<int>::check_type_counter, "Some items leaked in test"); + + g_Wakeup_Msg = "multifunction_node(3): Missed wakeup or machine is overloaded?"; + // unlimited parallel rejecting + run_multifunction_node_test<isThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::rejecting, unlimited_type>(); + run_multifunction_node_test<nonThrowing, nonThrowing, int, isThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::rejecting, unlimited_type>(); + run_multifunction_node_test<nonThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, nonThrowing, isThrowing, tbb::flow::rejecting, unlimited_type>(); + + g_Wakeup_Msg = "multifunction_node(4): Missed wakeup or machine is overloaded?"; + // limited parallel rejecting + run_multifunction_node_test<isThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::rejecting, limited_type>(); + run_multifunction_node_test<nonThrowing, nonThrowing, int, isThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::rejecting, (size_t)limited_type>(); + run_multifunction_node_test<nonThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, nonThrowing, isThrowing, tbb::flow::rejecting, (size_t)limited_type>(); + + g_Wakeup_Msg = "multifunction_node(5): Missed wakeup or machine is overloaded?"; + // limited parallel queueing + run_multifunction_node_test<isThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::queueing, (size_t)limited_type>(); + run_multifunction_node_test<nonThrowing, nonThrowing, int, isThrowing, tbb::flow::tuple<int,int>, nonThrowing, nonThrowing, tbb::flow::queueing, (size_t)limited_type>(); + run_multifunction_node_test<nonThrowing, nonThrowing, int, nonThrowing, tbb::flow::tuple<int,int>, nonThrowing, isThrowing, tbb::flow::queueing, (size_t)limited_type>(); + + g_Wakeup_Msg = "multifunction_node(6): Missed wakeup or machine is overloaded?"; + // everyone throwing + run_multifunction_node_test<isThrowing, isThrowing, int, isThrowing, tbb::flow::tuple<int,int>, isThrowing, isThrowing, tbb::flow::rejecting, unlimited_type>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// +// Continue node has T predecessors. when it receives messages (continue_msg) on T predecessors +// it executes the body of the node, and forwards a continue_msg to its successors. +// However many predecessors the continue_node has, that's how many continue_msgs it receives +// on input before forwarding a message. +// +// The graph will look like +// +// +broadcast_node+ +// / \ ___ +// input_node+------>+broadcast_node+ +continue_node+--->+absorber +// \ / +// +broadcast_node+ +// +// The continue_node has unlimited parallelism, no input buffering, and broadcasts to successors. +// The absorber is parallel, so each item emitted by the source will result in one thread +// spinning. So for N threads we pass N-1 continue_messages, then spin wait and then throw if +// we are allowed to. + +template < class SourceNodeType, class SourceNodeBodyType, class TTestNodeType, class TestNodeBodyType, + class SinkNodeType, class SinkNodeBodyType> +void run_one_continue_node_test (bool throwException, bool flog) { + tbb::flow::graph g; + + tbb::atomic<int> source_count; + tbb::atomic<int> test_count; + tbb::atomic<int> sink_count; + source_count = test_count = sink_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + g_Master = Harness::CurrentTid(); + SourceNodeType source(g, SourceNodeBodyType(source_count)); + TTestNodeType node_to_test(g, TestNodeBodyType(test_count)); + SinkNodeType sink(g,tbb::flow::unlimited,SinkNodeBodyType(sink_count)); + tbb::flow::broadcast_node<tbb::flow::continue_msg> b1(g), b2(g), b3(g); + make_edge(source, b1); + make_edge(b1,b2); + make_edge(b1,b3); + make_edge(b2,node_to_test); + make_edge(b3,node_to_test); + make_edge(node_to_test, sink); + for(int iter = 0; iter < 2; ++iter) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb_cnt = tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(); + int t_cnt = tbb::flow::copy_body<TestNodeBodyType>(node_to_test).count_value(); + int nb_cnt = tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb_cnt <= g_NumItems, "Too many items sent by sources"); + ASSERT(sb_cnt >= t_cnt, "Too many items received by test node"); + ASSERT(nb_cnt <= t_cnt, "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(sb_cnt == g_NumItems, "Missing invocations of input_node"); + ASSERT(t_cnt == g_NumItems, "Not all items reached test node"); + ASSERT(nb_cnt == g_NumItems, "Missing items in absorbers"); + } + g.reset(); // resets the body of the input_nodes, test_node and the absorb_nodes. + source_count = test_count = sink_count = 0; + ASSERT(0 == (int)test_count, "Atomic wasn't reset properly"); + ASSERT(0 == tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<TestNodeBodyType>(node_to_test).count_value(),"Reset test_node failed"); + ASSERT(0 == tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(),"Reset sink failed"); + } +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} + +template< + class ItemType, + TestNodeTypeEnum SType, // does source node throw? + TestNodeTypeEnum CType, // does continue_node throw? + TestNodeTypeEnum AType> // does absorber throw +void run_continue_node_test() { + typedef test_source_body<tbb::flow::continue_msg,SType> SBodyType; + typedef absorber_body<tbb::flow::continue_msg,ItemType,CType,unlimited_type> ContBodyType; + typedef absorber_body<ItemType,tbb::flow::continue_msg, AType, unlimited_type> SinkBodyType; + + typedef tbb::flow::input_node<tbb::flow::continue_msg> SrcType; + typedef tbb::flow::continue_node<ItemType> TestType; + typedef tbb::flow::function_node<ItemType,tbb::flow::continue_msg> SnkType; + + for(int i = 0; i < 4; ++i ) { + if(i == 2) continue; // don't run (false,true); it doesn't make sense. + bool doThrow = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_continue_node_test< + /*SourceNodeType*/ SrcType, + /*SourceNodeBodyType*/ SBodyType, + /*TestNodeType*/ TestType, + /*TestNodeBodyType*/ ContBodyType, + /*SinkNodeType*/ SnkType, + /*SinkNodeBodyType*/ SinkBodyType> + (doThrow,doFlog); + } +} + +// +void test_continue_node() { + REMARK("Testing continue_node\n"); + g_Wakeup_Msg = "buffer_node(non,is,non): Missed wakeup or machine is overloaded?"; + run_continue_node_test<int,nonThrowing,isThrowing,nonThrowing>(); + g_Wakeup_Msg = "buffer_node(non,non,is): Missed wakeup or machine is overloaded?"; + run_continue_node_test<int,nonThrowing,nonThrowing,isThrowing>(); + g_Wakeup_Msg = "buffer_node(is,non,non): Missed wakeup or machine is overloaded?"; + run_continue_node_test<int,isThrowing,nonThrowing,nonThrowing>(); + g_Wakeup_Msg = "buffer_node(is,is,is): Missed wakeup or machine is overloaded?"; + run_continue_node_test<int,isThrowing,isThrowing,isThrowing>(); + check_type<double>::check_type_counter = 0; + run_continue_node_test<check_type<double>,isThrowing,isThrowing,isThrowing>(); + ASSERT(!check_type<double>::check_type_counter, "Dropped objects in continue_node test"); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// ---------- buffer_node queue_node overwrite_node -------------- + +template< + class BufferItemType, // + class SourceNodeType, + class SourceNodeBodyType, + class TestNodeType, + class SinkNodeType, + class SinkNodeBodyType > +void run_one_buffer_node_test(bool throwException,bool flog) { + tbb::flow::graph g; + + tbb::atomic<int> source_count; + tbb::atomic<int> sink_count; + source_count = sink_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + g_Master = Harness::CurrentTid(); + SourceNodeType source(g, SourceNodeBodyType(source_count)); + TestNodeType node_to_test(g); + SinkNodeType sink(g,tbb::flow::unlimited,SinkNodeBodyType(sink_count)); + make_edge(source,node_to_test); + make_edge(node_to_test, sink); + for(int iter = 0; iter < 2; ++iter) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb_cnt = tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(); + int nb_cnt = tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb_cnt <= g_NumItems, "Too many items sent by sources"); + ASSERT(nb_cnt <= sb_cnt, "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(sb_cnt == g_NumItems, "Missing invocations of input_node"); + ASSERT(nb_cnt == g_NumItems, "Missing items in absorbers"); + } + if(iter == 0) { + remove_edge(node_to_test, sink); + node_to_test.try_put(BufferItemType()); + g.wait_for_all(); + g.reset(); + source_count = sink_count = 0; + BufferItemType tmp; + ASSERT(!node_to_test.try_get(tmp), "node not empty"); + make_edge(node_to_test, sink); + g.wait_for_all(); + } + else { + g.reset(); + source_count = sink_count = 0; + } + ASSERT(0 == tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(),"Reset sink failed"); + } + +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} +template<class BufferItemType, + TestNodeTypeEnum SourceThrowType, + TestNodeTypeEnum SinkThrowType> +void run_buffer_queue_and_overwrite_node_test() { + typedef test_source_body<BufferItemType,SourceThrowType> SourceBodyType; + typedef absorber_body<BufferItemType,tbb::flow::continue_msg,SinkThrowType,unlimited_type> SinkBodyType; + + typedef tbb::flow::input_node<BufferItemType> SrcType; + typedef tbb::flow::buffer_node<BufferItemType> BufType; + typedef tbb::flow::queue_node<BufferItemType> QueType; + typedef tbb::flow::overwrite_node<BufferItemType> OvrType; + typedef tbb::flow::function_node<BufferItemType,tbb::flow::continue_msg> SnkType; + + for(int i = 0; i < 4; ++i) { + if(i == 2) continue; // no need to test flog w/o throws + bool throwException = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; +#if TBB_RUN_BUFFERING_TEST + run_one_buffer_node_test< + /* class BufferItemType*/ BufferItemType, + /*class SourceNodeType*/ SrcType, + /*class SourceNodeBodyType*/ SourceBodyType, + /*class TestNodeType*/ BufType, + /*class SinkNodeType*/ SnkType, + /*class SinkNodeBodyType*/ SinkBodyType + >(throwException, doFlog); + run_one_buffer_node_test< + /* class BufferItemType*/ BufferItemType, + /*class SourceNodeType*/ SrcType, + /*class SourceNodeBodyType*/ SourceBodyType, + /*class TestNodeType*/ QueType, + /*class SinkNodeType*/ SnkType, + /*class SinkNodeBodyType*/ SinkBodyType + >(throwException, doFlog); +#endif + run_one_buffer_node_test< + /* class BufferItemType*/ BufferItemType, + /*class SourceNodeType*/ SrcType, + /*class SourceNodeBodyType*/ SourceBodyType, + /*class TestNodeType*/ OvrType, + /*class SinkNodeType*/ SnkType, + /*class SinkNodeBodyType*/ SinkBodyType + >(throwException, doFlog); + } +} + +void test_buffer_queue_and_overwrite_node() { + REMARK("Testing buffer_node, queue_node and overwrite_node\n"); +#if TBB_RUN_BUFFERING_TEST +#else + REMARK("skip buffer and queue test (known issue)\n"); +#endif + g_Wakeup_Msg = "buffer, queue, overwrite(is,non): Missed wakeup or machine is overloaded?"; + run_buffer_queue_and_overwrite_node_test<int,isThrowing,nonThrowing>(); + g_Wakeup_Msg = "buffer, queue, overwrite(non,is): Missed wakeup or machine is overloaded?"; + run_buffer_queue_and_overwrite_node_test<int,nonThrowing,isThrowing>(); + g_Wakeup_Msg = "buffer, queue, overwrite(is,is): Missed wakeup or machine is overloaded?"; + run_buffer_queue_and_overwrite_node_test<int,isThrowing,isThrowing>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// ---------- sequencer_node ------------------------- + + +template< + class BufferItemType, // + class SourceNodeType, + class SourceNodeBodyType, + class TestNodeType, + class SeqBodyType, + class SinkNodeType, + class SinkNodeBodyType > +void run_one_sequencer_node_test(bool throwException,bool flog) { + tbb::flow::graph g; + + tbb::atomic<int> source_count; + tbb::atomic<int> sink_count; + source_count = sink_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + g_Master = Harness::CurrentTid(); + SourceNodeType source(g, SourceNodeBodyType(source_count)); + TestNodeType node_to_test(g,SeqBodyType()); + SinkNodeType sink(g,tbb::flow::unlimited,SinkNodeBodyType(sink_count)); + make_edge(source,node_to_test); + make_edge(node_to_test, sink); + for(int iter = 0; iter < 2; ++iter) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb_cnt = tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(); + int nb_cnt = tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb_cnt <= g_NumItems, "Too many items sent by sources"); + ASSERT(nb_cnt <= sb_cnt, "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(sb_cnt == g_NumItems, "Missing invocations of input_node"); + ASSERT(nb_cnt == g_NumItems, "Missing items in absorbers"); + } + if(iter == 0) { + remove_edge(node_to_test, sink); + node_to_test.try_put(BufferItemType(g_NumItems + 1)); + node_to_test.try_put(BufferItemType(1)); + g.wait_for_all(); + g.reset(); + source_count = sink_count = 0; + make_edge(node_to_test, sink); + g.wait_for_all(); + } + else { + g.reset(); + source_count = sink_count = 0; + } + ASSERT(0 == tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(),"Reset sink failed"); + } + +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} + +template<class BufferItemType, + TestNodeTypeEnum SourceThrowType, + TestNodeTypeEnum SinkThrowType> +void run_sequencer_node_test() { + typedef test_source_body<BufferItemType,SourceThrowType> SourceBodyType; + typedef absorber_body<BufferItemType,tbb::flow::continue_msg,SinkThrowType,unlimited_type> SinkBodyType; + typedef sequencer_body<BufferItemType> SeqBodyType; + + typedef tbb::flow::input_node<BufferItemType> SrcType; + typedef tbb::flow::sequencer_node<BufferItemType> SeqType; + typedef tbb::flow::function_node<BufferItemType,tbb::flow::continue_msg> SnkType; + + for(int i = 0; i < 4; ++i) { + if(i == 2) continue; // no need to test flog w/o throws + bool throwException = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_sequencer_node_test< + /* class BufferItemType*/ BufferItemType, + /*class SourceNodeType*/ SrcType, + /*class SourceNodeBodyType*/ SourceBodyType, + /*class TestNodeType*/ SeqType, + /*class SeqBodyType*/ SeqBodyType, + /*class SinkNodeType*/ SnkType, + /*class SinkNodeBodyType*/ SinkBodyType + >(throwException, doFlog); + } +} + + + +void test_sequencer_node() { + REMARK("Testing sequencer_node\n"); + g_Wakeup_Msg = "sequencer_node(is,non): Missed wakeup or machine is overloaded?"; + run_sequencer_node_test<int, isThrowing,nonThrowing>(); + check_type<int>::check_type_counter = 0; + g_Wakeup_Msg = "sequencer_node(non,is): Missed wakeup or machine is overloaded?"; + run_sequencer_node_test<check_type<int>, nonThrowing,isThrowing>(); + ASSERT(!check_type<int>::check_type_counter, "Dropped objects in sequencer_node test"); + g_Wakeup_Msg = "sequencer_node(is,is): Missed wakeup or machine is overloaded?"; + run_sequencer_node_test<int, isThrowing,isThrowing>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// ------------ priority_queue_node ------------------ + +template< + class BufferItemType, + class SourceNodeType, + class SourceNodeBodyType, + class TestNodeType, + class SinkNodeType, + class SinkNodeBodyType > +void run_one_priority_queue_node_test(bool throwException,bool flog) { + tbb::flow::graph g; + + tbb::atomic<int> source_count; + tbb::atomic<int> sink_count; + source_count = sink_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + g_Master = Harness::CurrentTid(); + SourceNodeType source(g, SourceNodeBodyType(source_count)); + + TestNodeType node_to_test(g); + + SinkNodeType sink(g,tbb::flow::unlimited,SinkNodeBodyType(sink_count)); + + make_edge(source,node_to_test); + make_edge(node_to_test, sink); + for(int iter = 0; iter < 2; ++iter) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb_cnt = tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(); + int nb_cnt = tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb_cnt <= g_NumItems, "Too many items sent by sources"); + ASSERT(nb_cnt <= sb_cnt, "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(sb_cnt == g_NumItems, "Missing invocations of input_node"); + ASSERT(nb_cnt == g_NumItems, "Missing items in absorbers"); + } + if(iter == 0) { + remove_edge(node_to_test, sink); + node_to_test.try_put(BufferItemType(g_NumItems + 1)); + node_to_test.try_put(BufferItemType(g_NumItems + 2)); + node_to_test.try_put(BufferItemType()); + g.wait_for_all(); + g.reset(); + source_count = sink_count = 0; + make_edge(node_to_test, sink); + g.wait_for_all(); + } + else { + g.reset(); + source_count = sink_count = 0; + } + ASSERT(0 == tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(),"Reset sink failed"); + } + +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} + +template<class BufferItemType, + TestNodeTypeEnum SourceThrowType, + TestNodeTypeEnum SinkThrowType> +void run_priority_queue_node_test() { + typedef test_source_body<BufferItemType,SourceThrowType> SourceBodyType; + typedef absorber_body<BufferItemType,tbb::flow::continue_msg,SinkThrowType,unlimited_type> SinkBodyType; + typedef less_body<BufferItemType> LessBodyType; + + typedef tbb::flow::input_node<BufferItemType> SrcType; + typedef tbb::flow::priority_queue_node<BufferItemType,LessBodyType> PrqType; + typedef tbb::flow::function_node<BufferItemType,tbb::flow::continue_msg> SnkType; + + for(int i = 0; i < 4; ++i) { + if(i == 2) continue; // no need to test flog w/o throws + bool throwException = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_priority_queue_node_test< + /* class BufferItemType*/ BufferItemType, + /*class SourceNodeType*/ SrcType, + /*class SourceNodeBodyType*/ SourceBodyType, + /*class TestNodeType*/ PrqType, + /*class SinkNodeType*/ SnkType, + /*class SinkNodeBodyType*/ SinkBodyType + >(throwException, doFlog); + } +} + +void test_priority_queue_node() { + REMARK("Testing priority_queue_node\n"); + g_Wakeup_Msg = "priority_queue_node(is,non): Missed wakeup or machine is overloaded?"; + run_priority_queue_node_test<int, isThrowing,nonThrowing>(); + check_type<int>::check_type_counter = 0; + g_Wakeup_Msg = "priority_queue_node(non,is): Missed wakeup or machine is overloaded?"; + run_priority_queue_node_test<check_type<int>, nonThrowing,isThrowing>(); + ASSERT(!check_type<int>::check_type_counter, "Dropped objects in priority_queue_node test"); + g_Wakeup_Msg = "priority_queue_node(is,is): Missed wakeup or machine is overloaded?"; + run_priority_queue_node_test<int, isThrowing,isThrowing>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// ------------------- join_node ---------------- +template<class JP> struct graph_policy_name{ + static const char* name() {return "unknown"; } +}; +template<> struct graph_policy_name<tbb::flow::queueing> { + static const char* name() {return "queueing"; } +}; +template<> struct graph_policy_name<tbb::flow::reserving> { + static const char* name() {return "reserving"; } +}; +template<> struct graph_policy_name<tbb::flow::tag_matching> { + static const char* name() {return "tag_matching"; } +}; + + +template< + class JP, + class OutputTuple, + class SourceType0, + class SourceBodyType0, + class SourceType1, + class SourceBodyType1, + class TestJoinType, + class SinkType, + class SinkBodyType + > +struct run_one_join_node_test { + run_one_join_node_test() {} + static void execute_test(bool throwException,bool flog) { + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type ItemType0; + typedef typename tbb::flow::tuple_element<1,OutputTuple>::type ItemType1; + + tbb::flow::graph g; + tbb::atomic<int>source0_count; + tbb::atomic<int>source1_count; + tbb::atomic<int>sink_count; + source0_count = source1_count = sink_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + g_Master = Harness::CurrentTid(); + SourceType0 source0(g, SourceBodyType0(source0_count)); + SourceType1 source1(g, SourceBodyType1(source1_count)); + TestJoinType node_to_test(g); + SinkType sink(g,tbb::flow::unlimited,SinkBodyType(sink_count)); + make_edge(source0,tbb::flow::input_port<0>(node_to_test)); + make_edge(source1,tbb::flow::input_port<1>(node_to_test)); + make_edge(node_to_test, sink); + for(int iter = 0; iter < 2; ++iter) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source0.activate(); + source1.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source0.activate(); + source1.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb0_cnt = tbb::flow::copy_body<SourceBodyType0>(source0).count_value(); + int sb1_cnt = tbb::flow::copy_body<SourceBodyType1>(source1).count_value(); + int nb_cnt = tbb::flow::copy_body<SinkBodyType>(sink).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb0_cnt <= g_NumItems && sb1_cnt <= g_NumItems, "Too many items sent by sources"); + ASSERT(nb_cnt <= ((sb0_cnt < sb1_cnt) ? sb0_cnt : sb1_cnt), "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + if(sb0_cnt != g_NumItems) { + REMARK("throwException == %s\n", throwException ? "true" : "false"); + REMARK("iter == %d\n", (int)iter); + REMARK("sb0_cnt == %d\n", (int)sb0_cnt); + REMARK("g_NumItems == %d\n", (int)g_NumItems); + } + ASSERT(sb0_cnt == g_NumItems, "Missing invocations of input_node0"); // this one + ASSERT(sb1_cnt == g_NumItems, "Missing invocations of input_node1"); + ASSERT(nb_cnt == g_NumItems, "Missing items in absorbers"); + } + if(iter == 0) { + remove_edge(node_to_test, sink); + tbb::flow::input_port<0>(node_to_test).try_put(ItemType0(g_NumItems + 1)); + tbb::flow::input_port<1>(node_to_test).try_put(ItemType1(g_NumItems + 2)); + g.wait_for_all(); + g.reset(); + source0_count = source1_count = sink_count = 0; + make_edge(node_to_test, sink); + g.wait_for_all(); + } + else { + g.wait_for_all(); + g.reset(); + source0_count = source1_count = sink_count = 0; + } + ASSERT(0 == tbb::flow::copy_body<SourceBodyType0>(source0).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<SourceBodyType1>(source1).count_value(),"Reset source failed"); + nb_cnt = tbb::flow::copy_body<SinkBodyType>(sink).count_value(); + ASSERT(0 == tbb::flow::copy_body<SinkBodyType>(sink).count_value(),"Reset sink failed"); + } + +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif + } +}; // run_one_join_node_test + +template< + class OutputTuple, + class SourceType0, + class SourceBodyType0, + class SourceType1, + class SourceBodyType1, + class TestJoinType, + class SinkType, + class SinkBodyType + > +struct run_one_join_node_test< + tbb::flow::tag_matching, + OutputTuple, + SourceType0, + SourceBodyType0, + SourceType1, + SourceBodyType1, + TestJoinType, + SinkType, + SinkBodyType + > { + run_one_join_node_test() {} + static void execute_test(bool throwException,bool flog) { + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type ItemType0; + typedef typename tbb::flow::tuple_element<1,OutputTuple>::type ItemType1; + + tbb::flow::graph g; + + tbb::atomic<int>source0_count; + tbb::atomic<int>source1_count; + tbb::atomic<int>sink_count; + source0_count = source1_count = sink_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + g_Master = Harness::CurrentTid(); + SourceType0 source0(g, SourceBodyType0(source0_count, 2)); + SourceType1 source1(g, SourceBodyType1(source1_count, 3)); + TestJoinType node_to_test(g, tag_func<ItemType0>(ItemType0(2)), tag_func<ItemType1>(ItemType1(3))); + SinkType sink(g,tbb::flow::unlimited,SinkBodyType(sink_count)); + make_edge(source0,tbb::flow::input_port<0>(node_to_test)); + make_edge(source1,tbb::flow::input_port<1>(node_to_test)); + make_edge(node_to_test, sink); + for(int iter = 0; iter < 2; ++iter) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source0.activate(); + source1.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source0.activate(); + source1.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb0_cnt = tbb::flow::copy_body<SourceBodyType0>(source0).count_value(); + int sb1_cnt = tbb::flow::copy_body<SourceBodyType1>(source1).count_value(); + int nb_cnt = tbb::flow::copy_body<SinkBodyType>(sink).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb0_cnt <= g_NumItems && sb1_cnt <= g_NumItems, "Too many items sent by sources"); + ASSERT(nb_cnt <= ((sb0_cnt < sb1_cnt) ? sb0_cnt : sb1_cnt), "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(sb0_cnt == g_NumItems, "Missing invocations of input_node0"); + ASSERT(sb1_cnt == g_NumItems, "Missing invocations of input_node1"); + ASSERT(nb_cnt == g_NumItems, "Missing items in absorbers"); + } + if(iter == 0) { + remove_edge(node_to_test, sink); + tbb::flow::input_port<0>(node_to_test).try_put(ItemType0(g_NumItems + 4)); + tbb::flow::input_port<1>(node_to_test).try_put(ItemType1(g_NumItems + 2)); + g.wait_for_all(); // have to wait for the graph to stop again.... + g.reset(); // resets the body of the input_nodes, test_node and the absorb_nodes. + source0_count = source1_count = sink_count = 0; + make_edge(node_to_test, sink); + g.wait_for_all(); // have to wait for the graph to stop again.... + } + else { + g.wait_for_all(); + g.reset(); + source0_count = source1_count = sink_count = 0; + } + ASSERT(0 == tbb::flow::copy_body<SourceBodyType0>(source0).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<SourceBodyType1>(source1).count_value(),"Reset source failed"); + nb_cnt = tbb::flow::copy_body<SinkBodyType>(sink).count_value(); + ASSERT(0 == tbb::flow::copy_body<SinkBodyType>(sink).count_value(),"Reset sink failed"); + } + +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif + } +}; // run_one_join_node_test<tag_matching> + +template<class JP, class OutputTuple, + TestNodeTypeEnum SourceThrowType, + TestNodeTypeEnum SinkThrowType> +void run_join_node_test() { + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type ItemType0; + typedef typename tbb::flow::tuple_element<1,OutputTuple>::type ItemType1; + typedef test_source_body<ItemType0,SourceThrowType> SourceBodyType0; + typedef test_source_body<ItemType1,SourceThrowType> SourceBodyType1; + typedef absorber_body<OutputTuple,tbb::flow::continue_msg,SinkThrowType,unlimited_type> SinkBodyType; + + typedef typename tbb::flow::input_node<ItemType0> SourceType0; + typedef typename tbb::flow::input_node<ItemType1> SourceType1; + typedef typename tbb::flow::join_node<OutputTuple,JP> TestJoinType; + typedef typename tbb::flow::function_node<OutputTuple,tbb::flow::continue_msg> SinkType; + + for(int i = 0; i < 4; ++i) { + if(2 == i) continue; + bool throwException = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_join_node_test< + JP, + OutputTuple, + SourceType0, + SourceBodyType0, + SourceType1, + SourceBodyType1, + TestJoinType, + SinkType, + SinkBodyType>::execute_test(throwException,doFlog); + } +} + +template<class JP> +void test_join_node() { + REMARK("Testing join_node<%s>\n", graph_policy_name<JP>::name()); + // only doing two-input joins + g_Wakeup_Msg = "join(is,non): Missed wakeup or machine is overloaded?"; + run_join_node_test<JP, tbb::flow::tuple<int,int>, isThrowing, nonThrowing>(); + check_type<int>::check_type_counter = 0; + g_Wakeup_Msg = "join(non,is): Missed wakeup or machine is overloaded?"; + run_join_node_test<JP, tbb::flow::tuple<check_type<int>,int>, nonThrowing, isThrowing>(); + ASSERT(!check_type<int>::check_type_counter, "Dropped items in test"); + g_Wakeup_Msg = "join(is,is): Missed wakeup or machine is overloaded?"; + run_join_node_test<JP, tbb::flow::tuple<int,int>, isThrowing, isThrowing>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// ------------------- limiter_node ------------- + +template< + class BufferItemType, // + class SourceNodeType, + class SourceNodeBodyType, + class TestNodeType, + class SinkNodeType, + class SinkNodeBodyType > +void run_one_limiter_node_test(bool throwException,bool flog) { + tbb::flow::graph g; + + tbb::atomic<int> source_count; + tbb::atomic<int> sink_count; + source_count = sink_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + g_Master = Harness::CurrentTid(); + SourceNodeType source(g, SourceNodeBodyType(source_count)); + TestNodeType node_to_test(g,g_NumThreads + 1); + SinkNodeType sink(g,tbb::flow::unlimited,SinkNodeBodyType(sink_count)); + make_edge(source,node_to_test); + make_edge(node_to_test, sink); + for(int iter = 0; iter < 2; ++iter) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb_cnt = tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(); + int nb_cnt = tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb_cnt <= g_NumItems, "Too many items sent by sources"); + ASSERT(nb_cnt <= sb_cnt, "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + // we stop after limiter's limit, which is g_NumThreads + 1. The input_node + // is invoked one extra time, filling its buffer, so its limit is g_NumThreads + 2. + ASSERT(sb_cnt == g_NumThreads + 2, "Missing invocations of input_node"); + ASSERT(nb_cnt == g_NumThreads + 1, "Missing items in absorbers"); + } + if(iter == 0) { + remove_edge(node_to_test, sink); + node_to_test.try_put(BufferItemType()); + node_to_test.try_put(BufferItemType()); + g.wait_for_all(); + g.reset(); + source_count = sink_count = 0; + BufferItemType tmp; + ASSERT(!node_to_test.try_get(tmp), "node not empty"); + make_edge(node_to_test, sink); + g.wait_for_all(); + } + else { + g.reset(); + source_count = sink_count = 0; + } + ASSERT(0 == tbb::flow::copy_body<SourceNodeBodyType>(source).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<SinkNodeBodyType>(sink).count_value(),"Reset sink failed"); + } + +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} + +template<class BufferItemType, + TestNodeTypeEnum SourceThrowType, + TestNodeTypeEnum SinkThrowType> +void run_limiter_node_test() { + typedef test_source_body<BufferItemType,SourceThrowType> SourceBodyType; + typedef absorber_body<BufferItemType,tbb::flow::continue_msg,SinkThrowType,unlimited_type> SinkBodyType; + + typedef tbb::flow::input_node<BufferItemType> SrcType; + typedef tbb::flow::limiter_node<BufferItemType> LmtType; + typedef tbb::flow::function_node<BufferItemType,tbb::flow::continue_msg> SnkType; + + for(int i = 0; i < 4; ++i) { + if(i == 2) continue; // no need to test flog w/o throws + bool throwException = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_limiter_node_test< + /* class BufferItemType*/ BufferItemType, + /*class SourceNodeType*/ SrcType, + /*class SourceNodeBodyType*/ SourceBodyType, + /*class TestNodeType*/ LmtType, + /*class SinkNodeType*/ SnkType, + /*class SinkNodeBodyType*/ SinkBodyType + >(throwException, doFlog); + } +} + +void test_limiter_node() { + REMARK("Testing limiter_node\n"); + g_Wakeup_Msg = "limiter_node(is,non): Missed wakeup or machine is overloaded?"; + run_limiter_node_test<int,isThrowing,nonThrowing>(); + g_Wakeup_Msg = "limiter_node(non,is): Missed wakeup or machine is overloaded?"; + run_limiter_node_test<int,nonThrowing,isThrowing>(); + g_Wakeup_Msg = "limiter_node(is,is): Missed wakeup or machine is overloaded?"; + run_limiter_node_test<int,isThrowing,isThrowing>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// -------- split_node -------------------- + +template< + class InputTuple, + class SourceType, + class SourceBodyType, + class TestSplitType, + class SinkType0, + class SinkBodyType0, + class SinkType1, + class SinkBodyType1> +void run_one_split_node_test(bool throwException, bool flog) { + + tbb::flow::graph g; + + tbb::atomic<int> source_count; + tbb::atomic<int> sink0_count; + tbb::atomic<int> sink1_count; + source_count = sink0_count = sink1_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + + g_Master = Harness::CurrentTid(); + SourceType source(g, SourceBodyType(source_count)); + TestSplitType node_to_test(g); + SinkType0 sink0(g,tbb::flow::unlimited,SinkBodyType0(sink0_count)); + SinkType1 sink1(g,tbb::flow::unlimited,SinkBodyType1(sink1_count)); + make_edge(source, node_to_test); + make_edge(tbb::flow::output_port<0>(node_to_test), sink0); + make_edge(tbb::flow::output_port<1>(node_to_test), sink1); + + for(int iter = 0; iter < 2; ++iter) { // run, reset, run again + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb_cnt = tbb::flow::copy_body<SourceBodyType>(source).count_value(); + int nb0_cnt = tbb::flow::copy_body<SinkBodyType0>(sink0).count_value(); + int nb1_cnt = tbb::flow::copy_body<SinkBodyType1>(sink1).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb_cnt <= 2*g_NumItems, "Too many items sent by source"); + ASSERT(nb0_cnt + nb1_cnt <= sb_cnt*2, "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(sb_cnt == g_NumItems, "Missing invocations of input_nodes"); + ASSERT(nb0_cnt == g_NumItems && nb1_cnt == g_NumItems, "Missing items in absorbers"); + } + g.reset(); // resets the body of the input_nodes and the absorb_nodes. + source_count = sink0_count = sink1_count = 0; + ASSERT(0 == tbb::flow::copy_body<SourceBodyType>(source).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<SinkBodyType0>(sink0).count_value(),"Reset sink 0 failed"); + ASSERT(0 == tbb::flow::copy_body<SinkBodyType1>(sink1).count_value(),"Reset sink 1 failed"); + } +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} + +template<class InputTuple, + TestNodeTypeEnum SourceThrowType, + TestNodeTypeEnum SinkThrowType> +void run_split_node_test() { + typedef typename tbb::flow::tuple_element<0,InputTuple>::type ItemType0; + typedef typename tbb::flow::tuple_element<1,InputTuple>::type ItemType1; + typedef tuple_test_source_body<InputTuple,SourceThrowType> SourceBodyType; + typedef absorber_body<ItemType0,tbb::flow::continue_msg,SinkThrowType,unlimited_type> SinkBodyType0; + typedef absorber_body<ItemType1,tbb::flow::continue_msg,SinkThrowType,unlimited_type> SinkBodyType1; + + typedef typename tbb::flow::input_node<InputTuple> SourceType; + typedef typename tbb::flow::split_node<InputTuple> TestSplitType; + typedef typename tbb::flow::function_node<ItemType0,tbb::flow::continue_msg> SinkType0; + typedef typename tbb::flow::function_node<ItemType1,tbb::flow::continue_msg> SinkType1; + + for(int i = 0; i < 4; ++i) { + if(2 == i) continue; + bool throwException = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_split_node_test< + InputTuple, + SourceType, + SourceBodyType, + TestSplitType, + SinkType0, + SinkBodyType0, + SinkType1, + SinkBodyType1> + (throwException,doFlog); + } +} + +void test_split_node() { + REMARK("Testing split_node\n"); + g_Wakeup_Msg = "split_node(is,non): Missed wakeup or machine is overloaded?"; + run_split_node_test<tbb::flow::tuple<int,int>, isThrowing, nonThrowing>(); + g_Wakeup_Msg = "split_node(non,is): Missed wakeup or machine is overloaded?"; + run_split_node_test<tbb::flow::tuple<int,int>, nonThrowing, isThrowing>(); + g_Wakeup_Msg = "split_node(is,is): Missed wakeup or machine is overloaded?"; + run_split_node_test<tbb::flow::tuple<int,int>, isThrowing, isThrowing>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg; +} + +// --------- indexer_node ---------------------- + +template < class InputTuple, + class SourceType0, + class SourceBodyType0, + class SourceType1, + class SourceBodyType1, + class TestNodeType, + class SinkType, + class SinkBodyType> +void run_one_indexer_node_test(bool throwException,bool flog) { + typedef typename tbb::flow::tuple_element<0,InputTuple>::type ItemType0; + typedef typename tbb::flow::tuple_element<1,InputTuple>::type ItemType1; + + tbb::flow::graph g; + + tbb::atomic<int> source0_count; + tbb::atomic<int> source1_count; + tbb::atomic<int> sink_count; + source0_count = source1_count = sink_count = 0; +#if USE_TASK_SCHEDULER_OBSERVER + eh_test_observer o; + o.observe(true); +#endif + g_Master = Harness::CurrentTid(); + SourceType0 source0(g, SourceBodyType0(source0_count)); + SourceType1 source1(g, SourceBodyType1(source1_count)); + TestNodeType node_to_test(g); + SinkType sink(g,tbb::flow::unlimited,SinkBodyType(sink_count)); + make_edge(source0,tbb::flow::input_port<0>(node_to_test)); + make_edge(source1,tbb::flow::input_port<1>(node_to_test)); + make_edge(node_to_test, sink); + for(int iter = 0; iter < 2; ++iter) { + ResetGlobals(throwException,flog); + if(throwException) { + TRY(); + source0.activate(); + source1.activate(); + g.wait_for_all(); + CATCH_AND_ASSERT(); + } + else { + TRY(); + source0.activate(); + source1.activate(); + g.wait_for_all(); + CATCH_AND_FAIL(); + } + bool okayNoExceptionsCaught = (g_ExceptionInMaster && !g_MasterExecutedThrow) || (!g_ExceptionInMaster && !g_NonMasterExecutedThrow) || !throwException; + int sb0_cnt = tbb::flow::copy_body<SourceBodyType0>(source0).count_value(); + int sb1_cnt = tbb::flow::copy_body<SourceBodyType1>(source1).count_value(); + int nb_cnt = tbb::flow::copy_body<SinkBodyType>(sink).count_value(); + if(throwException) { + ASSERT(g.exception_thrown() || okayNoExceptionsCaught, "Exception not caught by graph"); + ASSERT(g.is_cancelled() || okayNoExceptionsCaught, "Cancellation not signalled in graph"); + ASSERT(sb0_cnt <= g_NumItems && sb1_cnt <= g_NumItems, "Too many items sent by sources"); + ASSERT(nb_cnt <= sb0_cnt + sb1_cnt, "Too many items received by sink nodes"); + } + else { + ASSERT(!g.exception_thrown(), "Exception flag in flow::graph set but no throw occurred"); + ASSERT(!g.is_cancelled(), "canceled flag set but no throw occurred"); + ASSERT(sb0_cnt == g_NumItems, "Missing invocations of input_node0"); + ASSERT(sb1_cnt == g_NumItems, "Missing invocations of input_node1"); + ASSERT(nb_cnt == 2*g_NumItems, "Missing items in absorbers"); + } + if(iter == 0) { + remove_edge(node_to_test, sink); + tbb::flow::input_port<0>(node_to_test).try_put(ItemType0(g_NumItems + 4)); + tbb::flow::input_port<1>(node_to_test).try_put(ItemType1(g_NumItems + 2)); + g.wait_for_all(); + g.reset(); + source0_count = source1_count = sink_count = 0; + make_edge(node_to_test, sink); + g.wait_for_all(); + } + else { + g.wait_for_all(); + g.reset(); + source0_count = source1_count = sink_count = 0; + } + ASSERT(0 == tbb::flow::copy_body<SourceBodyType0>(source0).count_value(),"Reset source failed"); + ASSERT(0 == tbb::flow::copy_body<SourceBodyType1>(source1).count_value(),"Reset source failed"); + nb_cnt = tbb::flow::copy_body<SinkBodyType>(sink).count_value(); + ASSERT(0 == tbb::flow::copy_body<SinkBodyType>(sink).count_value(),"Reset sink failed"); + } + +#if USE_TASK_SCHEDULER_OBSERVER + o.observe(false); +#endif +} + +template<class InputTuple, + TestNodeTypeEnum SourceThrowType, + TestNodeTypeEnum SinkThrowType> +void run_indexer_node_test() { + typedef typename tbb::flow::tuple_element<0,InputTuple>::type ItemType0; + typedef typename tbb::flow::tuple_element<1,InputTuple>::type ItemType1; + typedef test_source_body<ItemType0,SourceThrowType> SourceBodyType0; + typedef test_source_body<ItemType1,SourceThrowType> SourceBodyType1; + typedef typename tbb::flow::indexer_node<ItemType0, ItemType1> TestNodeType; + typedef absorber_body<typename TestNodeType::output_type,tbb::flow::continue_msg,SinkThrowType,unlimited_type> SinkBodyType; + + typedef typename tbb::flow::input_node<ItemType0> SourceType0; + typedef typename tbb::flow::input_node<ItemType1> SourceType1; + typedef typename tbb::flow::function_node<typename TestNodeType::output_type,tbb::flow::continue_msg> SinkType; + + for(int i = 0; i < 4; ++i) { + if(2 == i) continue; + bool throwException = (i & 0x1) != 0; + bool doFlog = (i & 0x2) != 0; + run_one_indexer_node_test< + InputTuple, + SourceType0, + SourceBodyType0, + SourceType1, + SourceBodyType1, + TestNodeType, + SinkType, + SinkBodyType>(throwException,doFlog); + } +} + +void test_indexer_node() { + REMARK("Testing indexer_node\n"); + g_Wakeup_Msg = "indexer_node(is,non): Missed wakeup or machine is overloaded?"; + run_indexer_node_test<tbb::flow::tuple<int,int>, isThrowing, nonThrowing>(); + g_Wakeup_Msg = "indexer_node(non,is): Missed wakeup or machine is overloaded?"; + run_indexer_node_test<tbb::flow::tuple<int,int>, nonThrowing, isThrowing>(); + g_Wakeup_Msg = "indexer_node(is,is): Missed wakeup or machine is overloaded?"; + run_indexer_node_test<tbb::flow::tuple<int,int>, isThrowing, isThrowing>(); + g_Wakeup_Msg = g_Orig_Wakeup_Msg;; +} + +/////////////////////////////////////////////// +// whole-graph exception test + +class Foo { +private: + // std::vector<int>& m_vec; + std::vector<int>* m_vec; +public: + Foo(std::vector<int>& vec) : m_vec(&vec) { } + void operator() (tbb::flow::continue_msg) const { + ++nExceptions; + tbb::internal::suppress_unused_warning( m_vec->at(m_vec->size()) ); // Will throw out_of_range exception + ASSERT(false, "Exception not thrown by invalid access"); + } +}; + +// test from user ahelwer: http://software.intel.com/en-us/forums/showthread.php?t=103786 +// exception thrown in graph node, not caught in wait_for_all() +void +test_flow_graph_exception0() { + // Initializes body + std::vector<int> vec; + vec.push_back(0); + Foo f(vec); + nExceptions = 0; + + // Construct graph and nodes + tbb::flow::graph g; + tbb::flow::broadcast_node<tbb::flow::continue_msg> start(g); + tbb::flow::continue_node<tbb::flow::continue_msg> fooNode(g, f); + + // Construct edge + tbb::flow::make_edge(start, fooNode); + + // Execute graph + ASSERT(!g.exception_thrown(), "exception_thrown flag already set"); + ASSERT(!g.is_cancelled(), "canceled flag already set"); + try { + start.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(false, "Exception not thrown"); + } + catch(std::out_of_range& ex) { + REMARK("Exception: %s (expected)\n", ex.what()); + } + catch(...) { + REMARK("Unknown exception caught (expected)\n"); + } + ASSERT(nExceptions > 0, "Exception caught, but no body signaled exception being thrown"); + nExceptions = 0; + ASSERT(g.exception_thrown(), "Exception not intercepted"); + // if exception set, cancellation also set. + ASSERT(g.is_cancelled(), "Exception cancellation not signaled"); + // in case we got an exception + try { + g.wait_for_all(); // context still signalled canceled, my_exception still set. + } + catch(...) { + ASSERT(false, "Second exception thrown but no task executing"); + } + ASSERT(nExceptions == 0, "body signaled exception being thrown, but no body executed"); + ASSERT(!g.exception_thrown(), "exception_thrown flag not reset"); + ASSERT(!g.is_cancelled(), "canceled flag not reset"); +} + +void TestOneThreadNum(int nThread) { + REMARK("Testing %d threads\n", nThread); + g_NumItems = ((nThread > NUM_ITEMS) ? nThread *2 : NUM_ITEMS); + g_NumThreads = nThread; + tbb::task_scheduler_init init(nThread); + // whole-graph exception catch and rethrow test + test_flow_graph_exception0(); + for(int i = 0; i < 4; ++i) { + g_ExceptionInMaster = (i & 1) != 0; + g_SolitaryException = (i & 2) != 0; + REMARK("g_ExceptionInMaster == %s, g_SolitaryException == %s\n", + g_ExceptionInMaster ? "T":"F", + g_SolitaryException ? "T":"F"); + test_source_node(); + test_function_node(); + test_continue_node(); // also test broadcast_node + test_multifunction_node(); + // single- and multi-item buffering nodes + test_buffer_queue_and_overwrite_node(); + test_sequencer_node(); + test_priority_queue_node(); + + // join_nodes + test_join_node<tbb::flow::queueing>(); + test_join_node<tbb::flow::reserving>(); + test_join_node<tbb::flow::tag_matching>(); + + test_limiter_node(); + test_split_node(); + // graph for write_once_node will be complicated by the fact the node will + // not do try_puts after it has been set. To get parallelism of N we have + // to attach N successor nodes to the write_once (or play some similar game). + // test_write_once_node(); + test_indexer_node(); + } +} +#endif // TBB_USE_EXCEPTIONS + +#if TBB_USE_EXCEPTIONS +int TestMain() { + // reversing the order of tests + for(int nThread=MaxThread; nThread >= MinThread; --nThread) { + TestOneThreadNum(nThread); + } + + return Harness::Done; +} +#else +int TestMain() { + return Harness::Skipped; +} +#endif // TBB_USE_EXCEPTIONS diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_tasks.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_tasks.cpp new file mode 100644 index 00000000..a0633044 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_eh_tasks.cpp @@ -0,0 +1,787 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 2 +#define HARNESS_DEFAULT_MAX_THREADS 4 +#define __TBB_SHUFFLE_PRESENT (_MSC_VER >= 1900 || __cplusplus >= 201103L && (__TBB_GLIBCXX_VERSION >= 40800 || _LIBCPP_VERSION)) + +#include "harness.h" + +#if __TBB_SHUFFLE_PRESENT +#include <random> +#endif + +#if __TBB_TASK_GROUP_CONTEXT + +#define __TBB_ATOMICS_CODEGEN_BROKEN __SUNPRO_CC + +#define private public +#include "tbb/task.h" +#undef private + +#include "tbb/task_scheduler_init.h" +#include "tbb/spin_mutex.h" +#include "tbb/tick_count.h" + +#include <string> + +#define NUM_CHILD_TASKS 256 +#define NUM_ROOT_TASKS 32 +#define NUM_ROOTS_IN_GROUP 8 + +//! Statistics about number of tasks in different states +class TaskStats { + typedef tbb::spin_mutex::scoped_lock lock_t; + //! Number of tasks allocated that was ever allocated + volatile intptr_t m_Existed; + //! Number of tasks executed to the moment + volatile intptr_t m_Executed; + //! Number of tasks allocated but not yet destroyed to the moment + volatile intptr_t m_Existing; + + mutable tbb::spin_mutex m_Mutex; +public: + //! Assumes that assignment is noncontended for the left-hand operand + const TaskStats& operator= ( const TaskStats& rhs ) { + if ( this != &rhs ) { + lock_t lock(rhs.m_Mutex); + m_Existed = rhs.m_Existed; + m_Executed = rhs.m_Executed; + m_Existing = rhs.m_Existing; + } + return *this; + } + intptr_t Existed() const { return m_Existed; } + intptr_t Executed() const { return m_Executed; } + intptr_t Existing() const { return m_Existing; } + void IncExisted() { lock_t lock(m_Mutex); ++m_Existed; ++m_Existing; } + void IncExecuted() { lock_t lock(m_Mutex); ++m_Executed; } + void DecExisting() { lock_t lock(m_Mutex); --m_Existing; } + //! Assumed to be used in uncontended manner only + void Reset() { m_Executed = m_Existing = m_Existed = 0; } +}; + +TaskStats g_CurStat; + +inline intptr_t Existed () { return g_CurStat.Existed(); } + +#include "harness_eh.h" + +bool g_BoostExecutedCount = true; +volatile bool g_TaskWasCancelled = false; + +inline void ResetGlobals () { + ResetEhGlobals(); + g_BoostExecutedCount = true; + g_TaskWasCancelled = false; + g_CurStat.Reset(); +} + +#define ASSERT_TEST_POSTCOND() \ + ASSERT (g_CurStat.Existed() >= g_CurStat.Executed(), "Total number of tasks is less than executed"); \ + ASSERT (!g_CurStat.Existing(), "Not all task objects have been destroyed"); \ + ASSERT (!tbb::task::self().is_cancelled(), "Scheduler's default context has not been cleaned up properly"); + +inline void WaitForException () { + int n = 0; + while ( ++n < c_Timeout && !__TBB_load_with_acquire(g_ExceptionCaught) ) + __TBB_Yield(); + ASSERT_WARNING( n < c_Timeout, "WaitForException failed" ); +} + +class TaskBase : public tbb::task { + tbb::task* execute () __TBB_override { + tbb::task* t = NULL; + __TBB_TRY { + t = do_execute(); + } __TBB_CATCH( ... ) { + g_CurStat.IncExecuted(); + __TBB_RETHROW(); + } + g_CurStat.IncExecuted(); + return t; + } +protected: + TaskBase ( bool throwException = true ) : m_Throw(throwException) { g_CurStat.IncExisted(); } + ~TaskBase () { g_CurStat.DecExisting(); } + + virtual tbb::task* do_execute () = 0; + + bool m_Throw; +}; // class TaskBase + +class LeafTask : public TaskBase { + tbb::task* do_execute () __TBB_override { + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks(); + if ( g_BoostExecutedCount ) + ++g_CurExecuted; + if ( m_Throw ) + ThrowTestException(NUM_CHILD_TASKS/2); + if ( !g_ThrowException ) + __TBB_Yield(); + return NULL; + } +public: + LeafTask ( bool throw_exception = true ) : TaskBase(throw_exception) {} +}; + +class SimpleRootTask : public TaskBase { + tbb::task* do_execute () __TBB_override { + set_ref_count(NUM_CHILD_TASKS + 1); + for ( size_t i = 0; i < NUM_CHILD_TASKS; ++i ) + spawn( *new( allocate_child() ) LeafTask(m_Throw) ); + wait_for_all(); + return NULL; + } +public: + SimpleRootTask ( bool throw_exception = true ) : TaskBase(throw_exception) {} +}; + +#if TBB_USE_EXCEPTIONS + +class SimpleThrowingTask : public tbb::task { +public: + tbb::task* execute () __TBB_override { throw 0; } + ~SimpleThrowingTask() {} +}; + +//! Checks if innermost running task information is updated correctly during cancellation processing +void Test0 () { + tbb::task_scheduler_init init (1); + tbb::empty_task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + tbb::task_list tl; + tl.push_back( *new( r.allocate_child() ) SimpleThrowingTask ); + tl.push_back( *new( r.allocate_child() ) SimpleThrowingTask ); + r.set_ref_count( 3 ); + try { + r.spawn_and_wait_for_all( tl ); + } + catch (...) {} + r.destroy( r ); +} + +//! Default exception behavior test. +/** Allocates a root task that spawns a bunch of children, one or several of which throw + a test exception in a worker or master thread (depending on the global setting). **/ +void Test1 () { + ResetGlobals(); + tbb::empty_task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + ASSERT (!g_CurStat.Existing() && !g_CurStat.Existed() && !g_CurStat.Executed(), + "something wrong with the task accounting"); + r.set_ref_count(NUM_CHILD_TASKS + 1); + for ( int i = 0; i < NUM_CHILD_TASKS; ++i ) + r.spawn( *new( r.allocate_child() ) LeafTask ); + TRY(); + r.wait_for_all(); + CATCH_AND_ASSERT(); + r.destroy(r); + ASSERT_TEST_POSTCOND(); +} // void Test1 () + +//! Default exception behavior test. +/** Allocates and spawns root task that runs a bunch of children, one of which throws + a test exception in a worker thread. (Similar to Test1, except that the root task + is spawned by the test function, and children are created by the root task instead + of the test function body.) **/ +void Test2 () { + ResetGlobals(); + SimpleRootTask &r = *new( tbb::task::allocate_root() ) SimpleRootTask; + ASSERT (g_CurStat.Existing() == 1 && g_CurStat.Existed() == 1 && !g_CurStat.Executed(), + "something wrong with the task accounting"); + TRY(); + tbb::task::spawn_root_and_wait(r); + CATCH_AND_ASSERT(); + ASSERT (g_ExceptionCaught, "no exception occurred"); + ASSERT_TEST_POSTCOND(); +} // void Test2 () + +//! The same as Test2() except the root task has explicit context. +/** The context is initialized as bound in order to check correctness of its associating + with a root task. **/ +void Test3 () { + ResetGlobals(); + tbb::task_group_context ctx(tbb::task_group_context::bound); + SimpleRootTask &r = *new( tbb::task::allocate_root(ctx) ) SimpleRootTask; + ASSERT (g_CurStat.Existing() == 1 && g_CurStat.Existed() == 1 && !g_CurStat.Executed(), + "something wrong with the task accounting"); + TRY(); + tbb::task::spawn_root_and_wait(r); + CATCH_AND_ASSERT(); + ASSERT (g_ExceptionCaught, "no exception occurred"); + ASSERT_TEST_POSTCOND(); +} // void Test2 () + +class RootLauncherTask : public TaskBase { + tbb::task_group_context::kind_type m_CtxKind; + + tbb::task* do_execute () __TBB_override { + tbb::task_group_context ctx(m_CtxKind); + SimpleRootTask &r = *new( allocate_root() ) SimpleRootTask; + r.change_group(ctx); + TRY(); + spawn_root_and_wait(r); + // Give a child of our siblings a chance to throw the test exception + WaitForException(); + CATCH(); + ASSERT (__TBB_EXCEPTION_TYPE_INFO_BROKEN || !g_UnknownException, "unknown exception was caught"); + return NULL; + } +public: + RootLauncherTask ( tbb::task_group_context::kind_type ctx_kind = tbb::task_group_context::isolated ) : m_CtxKind(ctx_kind) {} +}; + +/** Allocates and spawns a bunch of roots, which allocate and spawn new root with + isolated context, which at last spawns a bunch of children each, one of which + throws a test exception in a worker thread. **/ +void Test4 () { + ResetGlobals(); + tbb::task_list tl; + for ( size_t i = 0; i < NUM_ROOT_TASKS; ++i ) + tl.push_back( *new( tbb::task::allocate_root() ) RootLauncherTask ); + TRY(); + tbb::task::spawn_root_and_wait(tl); + CATCH_AND_ASSERT(); + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "exception in this scope is unexpected"); + intptr_t num_tasks_expected = NUM_ROOT_TASKS * (NUM_CHILD_TASKS + 2); + ASSERT (g_CurStat.Existed() == num_tasks_expected, "Wrong total number of tasks"); + if ( g_SolitaryException ) + ASSERT (g_CurStat.Executed() >= num_tasks_expected - NUM_CHILD_TASKS, "Unexpected number of executed tasks"); + ASSERT_TEST_POSTCOND(); +} // void Test4 () + +/** The same as Test4, except the contexts are bound. **/ +void Test4_1 () { + ResetGlobals(); + tbb::task_list tl; + for ( size_t i = 0; i < NUM_ROOT_TASKS; ++i ) + tl.push_back( *new( tbb::task::allocate_root() ) RootLauncherTask(tbb::task_group_context::bound) ); + TRY(); + tbb::task::spawn_root_and_wait(tl); + CATCH_AND_ASSERT(); + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "exception in this scope is unexpected"); + intptr_t num_tasks_expected = NUM_ROOT_TASKS * (NUM_CHILD_TASKS + 2); + ASSERT (g_CurStat.Existed() == num_tasks_expected, "Wrong total number of tasks"); + if ( g_SolitaryException ) + ASSERT (g_CurStat.Executed() >= num_tasks_expected - NUM_CHILD_TASKS, "Unexpected number of executed tasks"); + ASSERT_TEST_POSTCOND(); +} // void Test4_1 () + + +class RootsGroupLauncherTask : public TaskBase { + tbb::task* do_execute () __TBB_override { + tbb::task_group_context ctx (tbb::task_group_context::isolated); + tbb::task_list tl; + for ( size_t i = 0; i < NUM_ROOT_TASKS; ++i ) + tl.push_back( *new( allocate_root(ctx) ) SimpleRootTask ); + TRY(); + spawn_root_and_wait(tl); + // Give worker a chance to throw exception + WaitForException(); + CATCH_AND_ASSERT(); + return NULL; + } +}; + +/** Allocates and spawns a bunch of roots, which allocate and spawn groups of roots + with an isolated context shared by all group members, which at last spawn a bunch + of children each, one of which throws a test exception in a worker thread. **/ +void Test5 () { + ResetGlobals(); + tbb::task_list tl; + for ( size_t i = 0; i < NUM_ROOTS_IN_GROUP; ++i ) + tl.push_back( *new( tbb::task::allocate_root() ) RootsGroupLauncherTask ); + TRY(); + tbb::task::spawn_root_and_wait(tl); + CATCH_AND_ASSERT(); + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "unexpected exception intercepted"); + if ( g_SolitaryException ) { + intptr_t num_tasks_expected = NUM_ROOTS_IN_GROUP * (1 + NUM_ROOT_TASKS * (1 + NUM_CHILD_TASKS)); + intptr_t min_num_tasks_executed = num_tasks_expected - NUM_ROOT_TASKS * (NUM_CHILD_TASKS + 1); + ASSERT (g_CurStat.Executed() >= min_num_tasks_executed, "Too few tasks executed"); + } + ASSERT_TEST_POSTCOND(); +} // void Test5 () + +class ThrowingRootLauncherTask : public TaskBase { + tbb::task* do_execute () __TBB_override { + tbb::task_group_context ctx (tbb::task_group_context::bound); + SimpleRootTask &r = *new( allocate_root(ctx) ) SimpleRootTask(false); + TRY(); + spawn_root_and_wait(r); + CATCH(); + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "unexpected exception intercepted"); + ThrowTestException(NUM_CHILD_TASKS); + g_TaskWasCancelled |= is_cancelled(); + return NULL; + } +}; + +class BoundHierarchyLauncherTask : public TaskBase { + bool m_Recover; + + void alloc_roots ( tbb::task_group_context& ctx, tbb::task_list& tl ) { + for ( size_t i = 0; i < NUM_ROOT_TASKS; ++i ) + tl.push_back( *new( allocate_root(ctx) ) ThrowingRootLauncherTask ); + } + + tbb::task* do_execute () __TBB_override { + tbb::task_group_context ctx (tbb::task_group_context::isolated); + tbb::task_list tl; + alloc_roots(ctx, tl); + TRY(); + spawn_root_and_wait(tl); + CATCH_AND_ASSERT(); + ASSERT (l_ExceptionCaughtAtCurrentLevel, "no exception occurred"); + ASSERT (!tl.empty(), "task list was cleared somehow"); + if ( g_SolitaryException ) + ASSERT (g_TaskWasCancelled, "No tasks were cancelled despite of exception"); + if ( m_Recover ) { + // Test task_group_context::unbind and task_group_context::reset methods + g_ThrowException = false; + l_ExceptionCaughtAtCurrentLevel = false; + tl.clear(); + alloc_roots(ctx, tl); + ctx.reset(); + try { + spawn_root_and_wait(tl); + } + catch (...) { + l_ExceptionCaughtAtCurrentLevel = true; + } + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "unexpected exception occurred"); + } + return NULL; + } +public: + BoundHierarchyLauncherTask ( bool recover = false ) : m_Recover(recover) {} + +}; // class BoundHierarchyLauncherTask + +//! Test for bound contexts forming 2 level tree. Exception is thrown on the 1st (root) level. +/** Allocates and spawns a root that spawns a bunch of 2nd level roots sharing + the same isolated context, each of which in their turn spawns a single 3rd level + root with the bound context, and these 3rd level roots spawn bunches of leaves + in the end. Leaves do not generate exceptions. The test exception is generated + by one of the 2nd level roots. **/ +void Test6 () { + ResetGlobals(); + BoundHierarchyLauncherTask &r = *new( tbb::task::allocate_root() ) BoundHierarchyLauncherTask; + TRY(); + tbb::task::spawn_root_and_wait(r); + CATCH_AND_ASSERT(); + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "unexpected exception intercepted"); + // After the first of the branches (ThrowingRootLauncherTask) completes, + // the rest of the task tree may be collapsed before having a chance to execute leaves. + // A number of branches running concurrently with the first one will be able to spawn leaves though. + /// \todo: If additional checkpoints are added to scheduler the following assertion must weaken + intptr_t num_tasks_expected = 1 + NUM_ROOT_TASKS * (2 + NUM_CHILD_TASKS); + intptr_t min_num_tasks_created = 1 + g_NumThreads * 2 + NUM_CHILD_TASKS; + // 2 stands for BoundHierarchyLauncherTask and SimpleRootTask + // 1 corresponds to BoundHierarchyLauncherTask + intptr_t min_num_tasks_executed = 2 + 1 + NUM_CHILD_TASKS; + ASSERT (g_CurStat.Existed() <= num_tasks_expected, "Number of expected tasks is calculated incorrectly"); + ASSERT (g_CurStat.Existed() >= min_num_tasks_created, "Too few tasks created"); + ASSERT (g_CurStat.Executed() >= min_num_tasks_executed, "Too few tasks executed"); + ASSERT_TEST_POSTCOND(); +} // void Test6 () + +//! Tests task_group_context::unbind and task_group_context::reset methods. +/** Allocates and spawns a root that spawns a bunch of 2nd level roots sharing + the same isolated context, each of which in their turn spawns a single 3rd level + root with the bound context, and these 3rd level roots spawn bunches of leaves + in the end. Leaves do not generate exceptions. The test exception is generated + by one of the 2nd level roots. **/ +void Test7 () { + ResetGlobals(); + BoundHierarchyLauncherTask &r = *new( tbb::task::allocate_root() ) BoundHierarchyLauncherTask; + TRY(); + tbb::task::spawn_root_and_wait(r); + CATCH_AND_ASSERT(); + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "unexpected exception intercepted"); + ASSERT_TEST_POSTCOND(); +} // void Test6 () + +class BoundHierarchyLauncherTask2 : public TaskBase { + tbb::task* do_execute () __TBB_override { + tbb::task_group_context ctx; + tbb::task_list tl; + for ( size_t i = 0; i < NUM_ROOT_TASKS; ++i ) + tl.push_back( *new( allocate_root(ctx) ) RootLauncherTask(tbb::task_group_context::bound) ); + TRY(); + spawn_root_and_wait(tl); + CATCH_AND_ASSERT(); + // Exception must be intercepted by RootLauncherTask + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "no exception occurred"); + return NULL; + } +}; // class BoundHierarchyLauncherTask2 + +//! Test for bound contexts forming 2 level tree. Exception is thrown in the 2nd (outer) level. +/** Allocates and spawns a root that spawns a bunch of 2nd level roots sharing + the same isolated context, each of which in their turn spawns a single 3rd level + root with the bound context, and these 3rd level roots spawn bunches of leaves + in the end. The test exception is generated by one of the leaves. **/ +void Test8 () { + ResetGlobals(); + BoundHierarchyLauncherTask2 &r = *new( tbb::task::allocate_root() ) BoundHierarchyLauncherTask2; + TRY(); + tbb::task::spawn_root_and_wait(r); + CATCH_AND_ASSERT(); + ASSERT (!l_ExceptionCaughtAtCurrentLevel, "unexpected exception intercepted"); + if ( g_SolitaryException ) { + intptr_t num_tasks_expected = 1 + NUM_ROOT_TASKS * (2 + NUM_CHILD_TASKS); + intptr_t min_num_tasks_created = 1 + g_NumThreads * (2 + NUM_CHILD_TASKS); + intptr_t min_num_tasks_executed = num_tasks_expected - (NUM_CHILD_TASKS + 1); + ASSERT (g_CurStat.Existed() <= num_tasks_expected, "Number of expected tasks is calculated incorrectly"); + ASSERT (g_CurStat.Existed() >= min_num_tasks_created, "Too few tasks created"); + ASSERT (g_CurStat.Executed() >= min_num_tasks_executed, "Too few tasks executed"); + } + ASSERT_TEST_POSTCOND(); +} // void Test8 () + +template<typename T> +void ThrowMovableException ( intptr_t threshold, const T& data ) { + if ( !IsThrowingThread() ) + return; + if ( !g_SolitaryException ) { +#if __TBB_ATOMICS_CODEGEN_BROKEN + g_ExceptionsThrown = g_ExceptionsThrown + 1; +#else + ++g_ExceptionsThrown; +#endif + throw tbb::movable_exception<T>(data); + } + while ( g_CurStat.Existed() < threshold ) + __TBB_Yield(); + if ( g_ExceptionsThrown.compare_and_swap(1, 0) == 0 ) + throw tbb::movable_exception<T>(data); +} + +const int g_IntExceptionData = -375; +const std::string g_StringExceptionData = "My test string"; + +// Exception data class implementing minimal requirements of tbb::movable_exception +class ExceptionData { + const ExceptionData& operator = ( const ExceptionData& src ); + explicit ExceptionData ( int n ) : m_Int(n), m_String(g_StringExceptionData) {} +public: + ExceptionData ( const ExceptionData& src ) : m_Int(src.m_Int), m_String(src.m_String) {} + ~ExceptionData () {} + + int m_Int; + std::string m_String; + + // Simple way to provide an instance when all initializing constructors are private + // and to avoid memory reclamation problems. + static ExceptionData s_data; +}; + +ExceptionData ExceptionData::s_data(g_IntExceptionData); + +typedef tbb::movable_exception<int> SolitaryMovableException; +typedef tbb::movable_exception<ExceptionData> MultipleMovableException; + +class LeafTaskWithMovableExceptions : public TaskBase { + tbb::task* do_execute () __TBB_override { + Harness::ConcurrencyTracker ct; + WaitUntilConcurrencyPeaks(); + if ( g_SolitaryException ) + ThrowMovableException<int>(NUM_CHILD_TASKS/2, g_IntExceptionData); + else + ThrowMovableException<ExceptionData>(NUM_CHILD_TASKS/2, ExceptionData::s_data); + return NULL; + } +}; + +void CheckException ( tbb::tbb_exception& e ) { + ASSERT (strcmp(e.name(), (g_SolitaryException ? typeid(SolitaryMovableException) + : typeid(MultipleMovableException)).name() ) == 0, + "Unexpected original exception name"); + ASSERT (strcmp(e.what(), "tbb::movable_exception") == 0, "Unexpected original exception info "); + if ( g_SolitaryException ) { + SolitaryMovableException& me = dynamic_cast<SolitaryMovableException&>(e); + ASSERT (me.data() == g_IntExceptionData, "Unexpected solitary movable_exception data"); + } + else { + MultipleMovableException& me = dynamic_cast<MultipleMovableException&>(e); + ASSERT (me.data().m_Int == g_IntExceptionData, "Unexpected multiple movable_exception int data"); + ASSERT (me.data().m_String == g_StringExceptionData, "Unexpected multiple movable_exception string data"); + } +} + +void CheckException () { + try { + throw; + } catch ( tbb::tbb_exception& e ) { + CheckException(e); + } + catch ( ... ) { + } +} + +//! Test for movable_exception behavior, and external exception recording. +/** Allocates a root task that spawns a bunch of children, one or several of which throw + a movable exception in a worker or master thread (depending on the global settings). + The test also checks the correctness of multiple rethrowing of the pending exception. **/ +void TestMovableException () { + REMARK( "TestMovableException\n" ); + ResetGlobals(); + bool bUnsupported = false; + tbb::task_group_context ctx; + tbb::empty_task *r = new( tbb::task::allocate_root() ) tbb::empty_task; + ASSERT (!g_CurStat.Existing() && !g_CurStat.Existed() && !g_CurStat.Executed(), + "something wrong with the task accounting"); + r->set_ref_count(NUM_CHILD_TASKS + 1); + for ( int i = 0; i < NUM_CHILD_TASKS; ++i ) + r->spawn( *new( r->allocate_child() ) LeafTaskWithMovableExceptions ); + TRY() + r->wait_for_all(); + } catch ( ... ) { + ASSERT (!ctx.is_group_execution_cancelled(), ""); + CheckException(); + try { + throw; + } catch ( tbb::tbb_exception& e ) { + CheckException(e); + g_ExceptionCaught = l_ExceptionCaughtAtCurrentLevel = true; + } + catch ( ... ) { + g_ExceptionCaught = true; + g_UnknownException = unknownException = true; + } + try { + ctx.register_pending_exception(); + } catch ( ... ) { + bUnsupported = true; + REPORT( "Warning: register_pending_exception() failed. This is expected in case of linking with static msvcrt\n" ); + } + ASSERT (ctx.is_group_execution_cancelled() || bUnsupported, "After exception registration the context must be in the cancelled state"); + } + r->destroy(*r); + ASSERT_EXCEPTION(); + ASSERT_TEST_POSTCOND(); + + r = new( tbb::task::allocate_root(ctx) ) tbb::empty_task; + r->set_ref_count(1); + g_ExceptionCaught = g_UnknownException = false; + try { + r->wait_for_all(); + } catch ( tbb::tbb_exception& e ) { + CheckException(e); + g_ExceptionCaught = true; + } + catch ( ... ) { + g_ExceptionCaught = true; + g_UnknownException = true; + } + ASSERT (g_ExceptionCaught || bUnsupported, "no exception occurred"); + ASSERT (__TBB_EXCEPTION_TYPE_INFO_BROKEN || !g_UnknownException || bUnsupported, "unknown exception was caught"); + r->destroy(*r); +} // void Test10 () + +#endif /* TBB_USE_EXCEPTIONS */ + +template<class T> +class CtxLauncherTask : public tbb::task { + tbb::task_group_context &m_Ctx; + + tbb::task* execute () __TBB_override { + spawn_root_and_wait( *new( allocate_root(m_Ctx) ) T ); + return NULL; + } +public: + CtxLauncherTask ( tbb::task_group_context& ctx ) : m_Ctx(ctx) {} +}; + +//! Test for cancelling a task hierarchy from outside (from a task running in parallel with it). +void TestCancelation () { + ResetGlobals(); + g_ThrowException = false; + tbb::task_group_context ctx; + tbb::task_list tl; + tl.push_back( *new( tbb::task::allocate_root() ) CtxLauncherTask<SimpleRootTask>(ctx) ); + tl.push_back( *new( tbb::task::allocate_root() ) CancellatorTask(ctx, NUM_CHILD_TASKS / 4) ); + TRY(); + tbb::task::spawn_root_and_wait(tl); + CATCH_AND_FAIL(); + ASSERT (g_CurStat.Executed() <= g_ExecutedAtLastCatch + g_NumThreads, "Too many tasks were executed after cancellation"); + ASSERT_TEST_POSTCOND(); +} // void Test9 () + +class CtxDestroyerTask : public tbb::task { + int m_nestingLevel; + + tbb::task* execute () __TBB_override { + ASSERT ( m_nestingLevel >= 0 && m_nestingLevel < MaxNestingDepth, "Wrong nesting level. The test is broken" ); + tbb::task_group_context ctx; + tbb::task *t = new( allocate_root(ctx) ) tbb::empty_task; + int level = ++m_nestingLevel; + if ( level < MaxNestingDepth ) { + execute(); + } + else { + if ( !CancellatorTask::WaitUntilReady() ) + REPORT( "Warning: missing wakeup\n" ); + ++g_CurExecuted; + } + if ( ctx.is_group_execution_cancelled() ) + ++s_numCancelled; + t->destroy(*t); + return NULL; + } +public: + CtxDestroyerTask () : m_nestingLevel(0) { s_numCancelled = 0; } + + static const int MaxNestingDepth = 256; + static int s_numCancelled; +}; + +int CtxDestroyerTask::s_numCancelled = 0; + +//! Test for data race between cancellation propagation and context destruction. +/** If the data race ever occurs, an assertion inside TBB will be triggered. **/ +void TestCtxDestruction () { + REMARK( "TestCtxDestruction\n" ); + for ( size_t i = 0; i < 10; ++i ) { + tbb::task_group_context ctx; + tbb::task_list tl; + ResetGlobals(); + g_BoostExecutedCount = false; + g_ThrowException = false; + CancellatorTask::Reset(); + + tl.push_back( *new( tbb::task::allocate_root() ) CtxLauncherTask<CtxDestroyerTask>(ctx) ); + tl.push_back( *new( tbb::task::allocate_root() ) CancellatorTask(ctx, 1) ); + tbb::task::spawn_root_and_wait(tl); + ASSERT( g_CurExecuted == 1, "Test is broken" ); + ASSERT( CtxDestroyerTask::s_numCancelled <= CtxDestroyerTask::MaxNestingDepth, "Test is broken" ); + } +} // void TestCtxDestruction() + +#include <algorithm> +#include "harness_barrier.h" + +class CtxConcurrentDestroyer : NoAssign, Harness::NoAfterlife { + static const int ContextsPerThread = 512; + + static int s_Concurrency; + static int s_NumContexts; + static tbb::task_group_context** s_Contexts; + static char* s_Buffer; + static Harness::SpinBarrier s_Barrier; + static Harness::SpinBarrier s_ExitBarrier; + + struct Shuffler { + void operator() () const { +#if __TBB_SHUFFLE_PRESENT + std::shuffle(s_Contexts, s_Contexts + s_NumContexts, std::mt19937(std::random_device()())); +#else + std::random_shuffle(s_Contexts, s_Contexts + s_NumContexts); +#endif + } + }; +public: + static void Init ( int p ) { + s_Concurrency = p; + s_NumContexts = p * ContextsPerThread; + s_Contexts = new tbb::task_group_context*[s_NumContexts]; + s_Buffer = new char[s_NumContexts * sizeof(tbb::task_group_context)]; + s_Barrier.initialize( p ); + s_ExitBarrier.initialize( p ); + } + static void Uninit () { + for ( int i = 0; i < s_NumContexts; ++i ) { + tbb::internal::context_list_node_t &node = s_Contexts[i]->my_node; + ASSERT( !node.my_next && !node.my_prev, "Destroyed context was written to during context chain update" ); + } + delete []s_Contexts; + delete []s_Buffer; + } + + void operator() ( int id ) const { + int begin = ContextsPerThread * id, + end = begin + ContextsPerThread; + for ( int i = begin; i < end; ++i ) + s_Contexts[i] = new( s_Buffer + i * sizeof(tbb::task_group_context) ) tbb::task_group_context; + s_Barrier.wait( Shuffler() ); + for ( int i = begin; i < end; ++i ) { + s_Contexts[i]->tbb::task_group_context::~task_group_context(); + memset( static_cast<void*>(s_Contexts[i]), 0, sizeof(tbb::task_group_context) ); + } + s_ExitBarrier.wait(); + } +}; // class CtxConcurrentDestroyer + +int CtxConcurrentDestroyer::s_Concurrency; +int CtxConcurrentDestroyer::s_NumContexts; +tbb::task_group_context** CtxConcurrentDestroyer::s_Contexts; +char* CtxConcurrentDestroyer::s_Buffer; +Harness::SpinBarrier CtxConcurrentDestroyer::s_Barrier; +Harness::SpinBarrier CtxConcurrentDestroyer::s_ExitBarrier; + +void TestConcurrentCtxDestruction () { + REMARK( "TestConcurrentCtxDestruction\n" ); + CtxConcurrentDestroyer::Init(g_NumThreads); + NativeParallelFor( g_NumThreads, CtxConcurrentDestroyer() ); + CtxConcurrentDestroyer::Uninit(); +} + +void RunTests () { + REMARK ("Number of threads %d\n", g_NumThreads); + tbb::task_scheduler_init init (g_NumThreads); + g_Master = Harness::CurrentTid(); +#if TBB_USE_EXCEPTIONS + Test1(); + Test2(); + Test3(); + Test4(); + Test4_1(); + Test5(); + Test6(); + Test7(); + Test8(); + TestMovableException(); +#endif /* TBB_USE_EXCEPTIONS */ + TestCancelation(); + TestCtxDestruction(); +#if !RML_USE_WCRM + TestConcurrentCtxDestruction(); +#endif +} + +int TestMain () { + REMARK ("Using %s\n", TBB_USE_CAPTURED_EXCEPTION ? "tbb:captured_exception" : "exact exception propagation"); + MinThread = min(NUM_ROOTS_IN_GROUP, min(tbb::task_scheduler_init::default_num_threads(), max(2, MinThread))); + MaxThread = min(NUM_ROOTS_IN_GROUP, max(MinThread, min(tbb::task_scheduler_init::default_num_threads(), MaxThread))); + ASSERT (NUM_ROOTS_IN_GROUP < NUM_ROOT_TASKS, "Fix defines"); +#if TBB_USE_EXCEPTIONS + // Test0 always runs on one thread + Test0(); +#endif /* TBB_USE_EXCEPTIONS */ + g_SolitaryException = 0; + for ( g_NumThreads = MinThread; g_NumThreads <= MaxThread; ++g_NumThreads ) + RunTests(); + return Harness::Done; +} + +#else /* !__TBB_TASK_GROUP_CONTEXT */ + +int TestMain () { + return Harness::Skipped; +} + +#endif /* !__TBB_TASK_GROUP_CONTEXT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_enumerable_thread_specific.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_enumerable_thread_specific.cpp new file mode 100644 index 00000000..35de2004 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_enumerable_thread_specific.cpp @@ -0,0 +1,1380 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 0 +#define HARNESS_DEFAULT_MAX_THREADS 4 + +#include "tbb/enumerable_thread_specific.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/parallel_reduce.h" +#include "tbb/blocked_range.h" +#include "tbb/tick_count.h" +#include "tbb/tbb_allocator.h" +#include "tbb/tbb_thread.h" +#include "tbb/atomic.h" + +#include <cstring> +#include <vector> +#include <deque> +#include <list> +#include <map> +#include <utility> + +#include "harness_assert.h" +#include "harness.h" +#include "harness_checktype.h" + +#include "../tbbmalloc/shared_utils.h" +using rml::internal::estimatedCacheLineSize; + +#if __TBB_GCC_WARNING_SUPPRESSION_PRESENT +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + +static tbb::atomic<int> construction_counter; +static tbb::atomic<int> destruction_counter; + +#if TBB_USE_DEBUG +const int REPETITIONS = 4; +const int N = 10000; +const int RANGE_MIN=1000; +#else +const int REPETITIONS = 10; +const int N = 100000; +const int RANGE_MIN=10000; +#endif +const int VALID_NUMBER_OF_KEYS = 100; +const double EXPECTED_SUM = (REPETITIONS + 1) * N; + +//! A minimal class that occupies N bytes. +/** Defines default and copy constructor, and allows implicit operator&. + Hides operator=. */ +template<size_t N=tbb::internal::NFS_MaxLineSize> +class minimal: NoAssign { +private: + int my_value; + bool is_constructed; + char pad[N-sizeof(int) - sizeof(bool)]; +public: + minimal() : NoAssign(), my_value(0) { ++construction_counter; is_constructed = true; } + minimal( const minimal &m ) : NoAssign(), my_value(m.my_value) { ++construction_counter; is_constructed = true; } + ~minimal() { ++destruction_counter; ASSERT(is_constructed, NULL); is_constructed = false; } + void set_value( const int i ) { ASSERT(is_constructed, NULL); my_value = i; } + int value( ) const { ASSERT(is_constructed, NULL); return my_value; } +}; + +static size_t AlignMask = 0; // set to cache-line-size - 1 + +template<typename T> +T& check_alignment(T& t, const char *aname) { + if( !tbb::internal::is_aligned(&t, AlignMask)) { + REPORT_ONCE("alignment error with %s allocator (%x)\n", aname, (int)size_t(&t) & (AlignMask-1)); + } + return t; +} + +template<typename T> +const T& check_alignment(const T& t, const char *aname) { + if( !tbb::internal::is_aligned(&t, AlignMask)) { + REPORT_ONCE("alignment error with %s allocator (%x)\n", aname, (int)size_t(&t) & (AlignMask-1)); + } + return t; +} + +// Test constructors which throw. If an ETS constructor throws before completion, +// the already-built objects are un-constructed. Do not call the destructor if +// this occurs. + +static tbb::atomic<int> gThrowValue; +static int targetThrowValue = 3; + +class Thrower { +public: + Thrower() { +#if TBB_USE_EXCEPTIONS + if(++gThrowValue == targetThrowValue) { + throw std::bad_alloc(); + } +#endif + } +}; + +// MyThrower field of ThrowingConstructor will throw after a certain number of +// construction calls. The constructor unwinder wshould unconstruct the instance +// of check_type<int> that was constructed just before. +class ThrowingConstructor { + check_type<int> m_checktype; + Thrower m_throwing_field; +public: + int m_cnt; + ThrowingConstructor() : m_checktype(), m_throwing_field() { m_cnt = 0;} +private: +}; + +// +// A helper class that simplifies writing the tests since minimal does not +// define = or + operators. +// + +template< typename T > +struct test_helper { + static inline void init(T &e) { e = static_cast<T>(0); } + static inline void sum(T &e, const int addend ) { e += static_cast<T>(addend); } + static inline void sum(T &e, const double addend ) { e += static_cast<T>(addend); } + static inline void set(T &e, const int value ) { e = static_cast<T>(value); } + static inline double get(const T &e ) { return static_cast<double>(e); } +}; + +template<size_t N> +struct test_helper<minimal<N> > { + static inline void init(minimal<N> &sum) { sum.set_value( 0 ); } + static inline void sum(minimal<N> &sum, const int addend ) { sum.set_value( sum.value() + addend); } + static inline void sum(minimal<N> &sum, const double addend ) { sum.set_value( sum.value() + static_cast<int>(addend)); } + static inline void sum(minimal<N> &sum, const minimal<N> &addend ) { sum.set_value( sum.value() + addend.value()); } + static inline void set(minimal<N> &v, const int value ) { v.set_value( static_cast<int>(value) ); } + static inline double get(const minimal<N> &sum ) { return static_cast<double>(sum.value()); } +}; + +template<> +struct test_helper<ThrowingConstructor> { + static inline void init(ThrowingConstructor &sum) { sum.m_cnt = 0; } + static inline void sum(ThrowingConstructor &sum, const int addend ) { sum.m_cnt += addend; } + static inline void sum(ThrowingConstructor &sum, const double addend ) { sum.m_cnt += static_cast<int>(addend); } + static inline void sum(ThrowingConstructor &sum, const ThrowingConstructor &addend ) { sum.m_cnt += addend.m_cnt; } + static inline void set(ThrowingConstructor &v, const int value ) { v.m_cnt = static_cast<int>(value); } + static inline double get(const ThrowingConstructor &sum ) { return static_cast<double>(sum.m_cnt); } +}; + +//! Tag class used to make certain constructors hard to invoke accidentally. +struct SecretTagType {} SecretTag; + +//// functors and routines for initialization and combine + +//! Counts instances of FunctorFinit +static tbb::atomic<int> FinitCounter; + +template <typename T, int Value> +struct FunctorFinit { + FunctorFinit( const FunctorFinit& ) {++FinitCounter;} + FunctorFinit( SecretTagType ) {++FinitCounter;} + ~FunctorFinit() {--FinitCounter;} + T operator()() { return Value; } +}; + +template <int Value> +struct FunctorFinit<ThrowingConstructor,Value> { + FunctorFinit( const FunctorFinit& ) {++FinitCounter;} + FunctorFinit( SecretTagType ) {++FinitCounter;} + ~FunctorFinit() {--FinitCounter;} + ThrowingConstructor operator()() { ThrowingConstructor temp; temp.m_cnt = Value; return temp; } +}; + +template <size_t N, int Value> +struct FunctorFinit<minimal<N>,Value> { + FunctorFinit( const FunctorFinit& ) {++FinitCounter;} + FunctorFinit( SecretTagType ) {++FinitCounter;} + ~FunctorFinit() {--FinitCounter;} + minimal<N> operator()() { + minimal<N> result; + result.set_value( Value ); + return result; + } +}; + +// Addition + +template <typename T> +struct FunctorAddCombineRef { + T operator()(const T& left, const T& right) const { + return left+right; + } +}; + +template <size_t N> +struct FunctorAddCombineRef<minimal<N> > { + minimal<N> operator()(const minimal<N>& left, const minimal<N>& right) const { + minimal<N> result; + result.set_value( left.value() + right.value() ); + return result; + } +}; + +template <> +struct FunctorAddCombineRef<ThrowingConstructor> { + ThrowingConstructor operator()(const ThrowingConstructor& left, const ThrowingConstructor& right) const { + ThrowingConstructor result; + result.m_cnt = ( left.m_cnt + right.m_cnt ); + return result; + } +}; + +template <typename T> +struct FunctorAddCombine { + T operator()(T left, T right ) const { + return FunctorAddCombineRef<T>()( left, right ); + } +}; + +template <typename T> +T FunctionAddByRef( const T &left, const T &right) { + return FunctorAddCombineRef<T>()( left, right ); +} + +template <typename T> +T FunctionAdd( T left, T right) { return FunctionAddByRef(left,right); } + +template <typename T> +class Accumulator { +public: + Accumulator(T& _result) : my_result(_result) {} + Accumulator& operator=(const Accumulator& other) { + test_helper<T>::set(my_result, test_helper<T>::get(other)); + return *this; + } + void operator()(const T& new_bit) { test_helper<T>::sum(my_result, new_bit); } +private: + T& my_result; +}; + +template <typename T> +class ClearingAccumulator { +public: + ClearingAccumulator(T& _result) : my_result(_result) {} + ClearingAccumulator& operator=(const ClearingAccumulator& other) { + test_helper<T>::set(my_result, test_helper<T>::get(other)); + return *this; + } + void operator()(T& new_bit) { + test_helper<T>::sum(my_result, new_bit); + test_helper<T>::init(new_bit); + } + static void AssertClean(const T& thread_local_value) { + T zero; + test_helper<T>::init(zero); + ASSERT(test_helper<T>::get(thread_local_value)==test_helper<T>::get(zero), + "combine_each does not allow to modify thread local values?"); + } +private: + T& my_result; +}; + +//// end functors and routines + +template< typename T > +void run_serial_scalar_tests(const char *test_name) { + tbb::tick_count t0; + T sum; + test_helper<T>::init(sum); + + REMARK("Testing serial %s... ", test_name); + for (int t = -1; t < REPETITIONS; ++t) { + if (Verbose && t == 0) t0 = tbb::tick_count::now(); + for (int i = 0; i < N; ++i) { + test_helper<T>::sum(sum,1); + } + } + + double result_value = test_helper<T>::get(sum); + ASSERT( EXPECTED_SUM == result_value, NULL); + REMARK("done\nserial %s, 0, %g, %g\n", test_name, result_value, ( tbb::tick_count::now() - t0).seconds()); +} + + +template <typename T, template<class> class Allocator> +class parallel_scalar_body: NoAssign { + typedef tbb::enumerable_thread_specific<T, Allocator<T> > ets_type; + ets_type &sums; + const char* allocator_name; + +public: + + parallel_scalar_body ( ets_type &_sums, const char *alloc_name ) : sums(_sums), allocator_name(alloc_name) { } + + void operator()( const tbb::blocked_range<int> &r ) const { + for (int i = r.begin(); i != r.end(); ++i) + test_helper<T>::sum( check_alignment(sums.local(),allocator_name), 1 ); + } + +}; + +template< typename T, template<class> class Allocator> +void run_parallel_scalar_tests_nocombine(const char *test_name, const char *allocator_name) { + + typedef tbb::enumerable_thread_specific<T, Allocator<T> > ets_type; + + Check<T> my_check; + gThrowValue = 0; + { + // We assume that static_sums zero-initialized or has a default constructor that zeros it. + static ets_type static_sums = ets_type( T() ); + + T exemplar; + test_helper<T>::init(exemplar); + + for (int p = MinThread; p <= MaxThread; ++p) { + REMARK("Testing parallel %s with allocator %s on %d thread(s)... ", test_name, allocator_name, p); + tbb::task_scheduler_init init(p); + tbb::tick_count t0; + + T iterator_sum; + test_helper<T>::init(iterator_sum); + + T finit_ets_sum; + test_helper<T>::init(finit_ets_sum); + + T const_iterator_sum; + test_helper<T>::init(const_iterator_sum); + + T range_sum; + test_helper<T>::init(range_sum); + + T const_range_sum; + test_helper<T>::init(const_range_sum); + + T cconst_sum; + test_helper<T>::init(cconst_sum); + + T assign_sum; + test_helper<T>::init(assign_sum); + + T cassgn_sum; + test_helper<T>::init(cassgn_sum); + T non_cassgn_sum; + test_helper<T>::init(non_cassgn_sum); + + T static_sum; + test_helper<T>::init(static_sum); + + for (int t = -1; t < REPETITIONS; ++t) { + if (Verbose && t == 0) t0 = tbb::tick_count::now(); + + static_sums.clear(); + + ets_type sums(exemplar); + FunctorFinit<T,0> my_finit(SecretTag); + ets_type finit_ets(my_finit); + + ASSERT( sums.empty(), NULL); + tbb::parallel_for( tbb::blocked_range<int>( 0, N, RANGE_MIN ), parallel_scalar_body<T,Allocator>( sums, allocator_name ) ); + ASSERT( !sums.empty(), NULL); + + ASSERT( finit_ets.empty(), NULL); + tbb::parallel_for( tbb::blocked_range<int>( 0, N, RANGE_MIN ), parallel_scalar_body<T,Allocator>( finit_ets, allocator_name ) ); + ASSERT( !finit_ets.empty(), NULL); + + ASSERT(static_sums.empty(), NULL); + tbb::parallel_for( tbb::blocked_range<int>( 0, N, RANGE_MIN ), parallel_scalar_body<T,Allocator>( static_sums, allocator_name ) ); + ASSERT( !static_sums.empty(), NULL); + + // use iterator + typename ets_type::size_type size = 0; + for ( typename ets_type::iterator i = sums.begin(); i != sums.end(); ++i ) { + ++size; + test_helper<T>::sum(iterator_sum, *i); + } + ASSERT( sums.size() == size, NULL); + + // use const_iterator + for ( typename ets_type::const_iterator i = sums.begin(); i != sums.end(); ++i ) { + test_helper<T>::sum(const_iterator_sum, *i); + } + + // use range_type + typename ets_type::range_type r = sums.range(); + for ( typename ets_type::range_type::const_iterator i = r.begin(); i != r.end(); ++i ) { + test_helper<T>::sum(range_sum, *i); + } + + // use const_range_type + typename ets_type::const_range_type cr = sums.range(); + for ( typename ets_type::const_range_type::iterator i = cr.begin(); i != cr.end(); ++i ) { + test_helper<T>::sum(const_range_sum, *i); + } + + // test copy constructor, with TLS-cached locals + typedef typename tbb::enumerable_thread_specific<T, Allocator<T>, tbb::ets_key_per_instance> cached_ets_type; + + cached_ets_type cconst(sums); + + for ( typename cached_ets_type::const_iterator i = cconst.begin(); i != cconst.end(); ++i ) { + test_helper<T>::sum(cconst_sum, *i); + } + + // test assignment + ets_type assigned; + assigned = sums; + + for ( typename ets_type::const_iterator i = assigned.begin(); i != assigned.end(); ++i ) { + test_helper<T>::sum(assign_sum, *i); + } + + // test assign to and from cached locals + cached_ets_type cassgn; + cassgn = sums; + for ( typename cached_ets_type::const_iterator i = cassgn.begin(); i != cassgn.end(); ++i ) { + test_helper<T>::sum(cassgn_sum, *i); + } + + ets_type non_cassgn; + non_cassgn = cassgn; + for ( typename ets_type::const_iterator i = non_cassgn.begin(); i != non_cassgn.end(); ++i ) { + test_helper<T>::sum(non_cassgn_sum, *i); + } + + // test finit-initialized ets + for(typename ets_type::const_iterator i = finit_ets.begin(); i != finit_ets.end(); ++i) { + test_helper<T>::sum(finit_ets_sum, *i); + } + + // test static ets + for(typename ets_type::const_iterator i = static_sums.begin(); i != static_sums.end(); ++i) { + test_helper<T>::sum(static_sum, *i); + } + + } + + ASSERT( EXPECTED_SUM == test_helper<T>::get(iterator_sum), NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(const_iterator_sum), NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(range_sum), NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(const_range_sum), NULL); + + ASSERT( EXPECTED_SUM == test_helper<T>::get(cconst_sum), NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(assign_sum), NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(cassgn_sum), NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(non_cassgn_sum), NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(finit_ets_sum), NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(static_sum), NULL); + + REMARK("done\nparallel %s, %d, %g, %g\n", test_name, p, test_helper<T>::get(iterator_sum), + ( tbb::tick_count::now() - t0).seconds()); + } + } // Check block +} + +template< typename T, template<class> class Allocator> +void run_parallel_scalar_tests(const char *test_name, const char *allocator_name) { + + typedef tbb::enumerable_thread_specific<T, Allocator<T> > ets_type; + bool exception_caught = false; + + // We assume that static_sums zero-initialized or has a default constructor that zeros it. + static ets_type static_sums = ets_type( T() ); + + T exemplar; + test_helper<T>::init(exemplar); + + int test_throw_count = 10; + // the test will be performed repeatedly until it does not throw. For non-throwing types + // this means once; for the throwing type test it may loop two or three times. The + // value of targetThrowValue will determine when and if the test will throw. + do { + targetThrowValue = test_throw_count; // keep testing until we get no exception + exception_caught = false; +#if TBB_USE_EXCEPTIONS + try { +#endif + run_parallel_scalar_tests_nocombine<T,Allocator>(test_name, allocator_name); +#if TBB_USE_EXCEPTIONS + } + catch(...) { + REMARK("Exception caught %d\n", targetThrowValue); + } +#endif + for (int p = MinThread; p <= MaxThread; ++p) { + REMARK("Testing parallel %s with allocator %s on %d thread(s)... ", test_name, allocator_name, p); + tbb::task_scheduler_init init(p); + tbb::tick_count t0; + + gThrowValue = 0; + + T combine_sum; + test_helper<T>::init(combine_sum); + + T combine_ref_sum; + test_helper<T>::init(combine_ref_sum); + + T accumulator_sum; + test_helper<T>::init(accumulator_sum); + + T static_sum; + test_helper<T>::init(static_sum); + + T clearing_accumulator_sum; + test_helper<T>::init(clearing_accumulator_sum); + + { + Check<T> my_check; +#if TBB_USE_EXCEPTIONS + try +#endif + { + for (int t = -1; t < REPETITIONS; ++t) { + if (Verbose && t == 0) t0 = tbb::tick_count::now(); + + static_sums.clear(); + + ets_type sums(exemplar); + + ASSERT( sums.empty(), NULL); + tbb::parallel_for( tbb::blocked_range<int>( 0, N, RANGE_MIN ), + parallel_scalar_body<T,Allocator>( sums, allocator_name ) ); + ASSERT( !sums.empty(), NULL); + + ASSERT(static_sums.empty(), NULL); + tbb::parallel_for( tbb::blocked_range<int>( 0, N, RANGE_MIN ), + parallel_scalar_body<T,Allocator>( static_sums, allocator_name ) ); + ASSERT( !static_sums.empty(), NULL); + + // Use combine + test_helper<T>::sum(combine_sum, sums.combine(FunctionAdd<T>)); + test_helper<T>::sum(combine_ref_sum, sums.combine(FunctionAddByRef<T>)); + test_helper<T>::sum(static_sum, static_sums.combine(FunctionAdd<T>)); + + // Accumulate with combine_each + sums.combine_each(Accumulator<T>(accumulator_sum)); + // Accumulate and clear thread-local values + sums.combine_each(ClearingAccumulator<T>(clearing_accumulator_sum)); + // Check that the values were cleared + sums.combine_each(ClearingAccumulator<T>::AssertClean); + } + } +#if TBB_USE_EXCEPTIONS + catch(...) { + REMARK("Exception caught %d\n", targetThrowValue); + exception_caught = true; + } +#endif + } + + ASSERT( EXPECTED_SUM == test_helper<T>::get(combine_sum) || exception_caught, NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(combine_ref_sum) || exception_caught, NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(static_sum) || exception_caught, NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(accumulator_sum) || exception_caught, NULL); + ASSERT( EXPECTED_SUM == test_helper<T>::get(clearing_accumulator_sum) || exception_caught, NULL); + + REMARK("done\nparallel combine %s, %d, %g, %g\n", test_name, p, test_helper<T>::get(combine_sum), + ( tbb::tick_count::now() - t0).seconds()); + } // MinThread .. MaxThread + test_throw_count += 10; // keep testing until we don't get an exception + } while (exception_caught && test_throw_count < 200); + ASSERT(!exception_caught, "No non-exception test completed"); +} + +template <typename T, template<class> class Allocator> +class parallel_vector_for_body: NoAssign { + typedef std::vector<T, tbb::tbb_allocator<T> > container_type; + typedef tbb::enumerable_thread_specific< container_type, Allocator<container_type> > ets_type; + ets_type &locals; + const char *allocator_name; + +public: + + parallel_vector_for_body ( ets_type &_locals, const char *aname ) : locals(_locals), allocator_name(aname) { } + + void operator()( const tbb::blocked_range<int> &r ) const { + T one; + test_helper<T>::set(one, 1); + + for (int i = r.begin(); i < r.end(); ++i) { + check_alignment(locals.local(),allocator_name).push_back( one ); + } + } + +}; + +template <typename R, typename T> +struct parallel_vector_reduce_body { + + T sum; + size_t count; + typedef std::vector<T, tbb::tbb_allocator<T> > container_type; + + parallel_vector_reduce_body ( ) : count(0) { test_helper<T>::init(sum); } + parallel_vector_reduce_body ( parallel_vector_reduce_body<R, T> &, tbb::split ) : count(0) { test_helper<T>::init(sum); } + + void operator()( const R &r ) { + for (typename R::iterator ri = r.begin(); ri != r.end(); ++ri) { + const container_type &v = *ri; + ++count; + for (typename container_type::const_iterator vi = v.begin(); vi != v.end(); ++vi) { + test_helper<T>::sum(sum, *vi); + } + } + } + + void join( const parallel_vector_reduce_body &b ) { + test_helper<T>::sum(sum,b.sum); + count += b.count; + } + +}; + +template< typename T, template<class> class Allocator> +void run_parallel_vector_tests(const char *test_name, const char *allocator_name) { + tbb::tick_count t0; + typedef std::vector<T, tbb::tbb_allocator<T> > container_type; + typedef tbb::enumerable_thread_specific< container_type, Allocator<container_type> > ets_type; + + for (int p = MinThread; p <= MaxThread; ++p) { + REMARK("Testing parallel %s with allocator %s on %d thread(s)... ", test_name, allocator_name, p); + tbb::task_scheduler_init init(p); + + T sum; + test_helper<T>::init(sum); + + for (int t = -1; t < REPETITIONS; ++t) { + if (Verbose && t == 0) t0 = tbb::tick_count::now(); + ets_type vs; + + ASSERT( vs.empty(), NULL ); + tbb::parallel_for( tbb::blocked_range<int> (0, N, RANGE_MIN), + parallel_vector_for_body<T,Allocator>( vs, allocator_name ) ); + ASSERT( !vs.empty(), NULL ); + + // copy construct + ets_type vs2(vs); // this causes an assertion failure, related to allocators... + + // assign + ets_type vs3; + vs3 = vs; + + parallel_vector_reduce_body< typename ets_type::const_range_type, T > pvrb; + tbb::parallel_reduce ( vs.range(1), pvrb ); + + test_helper<T>::sum(sum, pvrb.sum); + + ASSERT( vs.size() == pvrb.count, NULL ); + ASSERT( vs2.size() == pvrb.count, NULL ); + ASSERT( vs3.size() == pvrb.count, NULL ); + + tbb::flattened2d<ets_type> fvs = flatten2d(vs); + size_t ccount = fvs.size(); + ASSERT( ccount == size_t(N), NULL ); + size_t elem_cnt = 0; + for(typename tbb::flattened2d<ets_type>::const_iterator i = fvs.begin(); i != fvs.end(); ++i) { + ++elem_cnt; + }; + ASSERT( ccount == elem_cnt, NULL ); + + elem_cnt = 0; + for(typename tbb::flattened2d<ets_type>::iterator i = fvs.begin(); i != fvs.end(); ++i) { + ++elem_cnt; + }; + ASSERT( ccount == elem_cnt, NULL ); + +#if __TBB_ETS_USE_CPP11 + // Test the ETS constructor with multiple args + T minus_one; + test_helper<T>::set(minus_one, -1); + // Set ETS to construct "local" vectors pre-occupied with 25 "minus_one"s + // Cast 25 to size_type to prevent Intel Compiler SFINAE compilation issues with gcc 5. + ets_type vvs( typename container_type::size_type(25), minus_one, tbb::tbb_allocator<T>() ); + ASSERT( vvs.empty(), NULL ); + tbb::parallel_for ( tbb::blocked_range<int> (0, N, RANGE_MIN), parallel_vector_for_body<T,Allocator>( vvs, allocator_name ) ); + ASSERT( !vvs.empty(), NULL ); + + parallel_vector_reduce_body< typename ets_type::const_range_type, T > pvrb2; + tbb::parallel_reduce ( vvs.range(1), pvrb2 ); + ASSERT( pvrb2.count == vvs.size(), NULL ); + ASSERT( test_helper<T>::get(pvrb2.sum) == N-pvrb2.count*25, NULL ); + + tbb::flattened2d<ets_type> fvvs = flatten2d(vvs); + ccount = fvvs.size(); + ASSERT( ccount == N+pvrb2.count*25, NULL ); +#endif + } + + double result_value = test_helper<T>::get(sum); + ASSERT( EXPECTED_SUM == result_value, NULL); + REMARK("done\nparallel %s, %d, %g, %g\n", test_name, p, result_value, ( tbb::tick_count::now() - t0).seconds()); + } +} + +template<typename T, template<class> class Allocator> +void run_cross_type_vector_tests(const char *test_name) { + tbb::tick_count t0; + const char* allocator_name = "default"; + typedef std::vector<T, tbb::tbb_allocator<T> > container_type; + + for (int p = MinThread; p <= MaxThread; ++p) { + REMARK("Testing parallel %s on %d thread(s)... ", test_name, p); + tbb::task_scheduler_init init(p); + + T sum; + test_helper<T>::init(sum); + + for (int t = -1; t < REPETITIONS; ++t) { + if (Verbose && t == 0) t0 = tbb::tick_count::now(); + typedef typename tbb::enumerable_thread_specific< container_type, Allocator<container_type>, tbb::ets_no_key > ets_nokey_type; + typedef typename tbb::enumerable_thread_specific< container_type, Allocator<container_type>, tbb::ets_key_per_instance > ets_tlskey_type; + ets_nokey_type vs; + + ASSERT( vs.empty(), NULL); + tbb::parallel_for ( tbb::blocked_range<int> (0, N, RANGE_MIN), parallel_vector_for_body<T, Allocator>( vs, allocator_name ) ); + ASSERT( !vs.empty(), NULL); + + // copy construct + ets_tlskey_type vs2(vs); + + // assign + ets_nokey_type vs3; + vs3 = vs2; + + parallel_vector_reduce_body< typename ets_nokey_type::const_range_type, T > pvrb; + tbb::parallel_reduce ( vs3.range(1), pvrb ); + + test_helper<T>::sum(sum, pvrb.sum); + + ASSERT( vs3.size() == pvrb.count, NULL); + + tbb::flattened2d<ets_nokey_type> fvs = flatten2d(vs3); + size_t ccount = fvs.size(); + size_t elem_cnt = 0; + for(typename tbb::flattened2d<ets_nokey_type>::const_iterator i = fvs.begin(); i != fvs.end(); ++i) { + ++elem_cnt; + }; + ASSERT(ccount == elem_cnt, NULL); + + elem_cnt = 0; + for(typename tbb::flattened2d<ets_nokey_type>::iterator i = fvs.begin(); i != fvs.end(); ++i) { + ++elem_cnt; + }; + ASSERT(ccount == elem_cnt, NULL); + } + + double result_value = test_helper<T>::get(sum); + ASSERT( EXPECTED_SUM == result_value, NULL); + REMARK("done\nparallel %s, %d, %g, %g\n", test_name, p, result_value, ( tbb::tick_count::now() - t0).seconds()); + } +} + +template< typename T > +void run_serial_vector_tests(const char *test_name) { + tbb::tick_count t0; + T sum; + test_helper<T>::init(sum); + T one; + test_helper<T>::set(one, 1); + + REMARK("Testing serial %s... ", test_name); + for (int t = -1; t < REPETITIONS; ++t) { + if (Verbose && t == 0) t0 = tbb::tick_count::now(); + std::vector<T, tbb::tbb_allocator<T> > v; + for (int i = 0; i < N; ++i) { + v.push_back( one ); + } + for (typename std::vector<T, tbb::tbb_allocator<T> >::const_iterator i = v.begin(); i != v.end(); ++i) + test_helper<T>::sum(sum, *i); + } + + double result_value = test_helper<T>::get(sum); + ASSERT( EXPECTED_SUM == result_value, NULL); + REMARK("done\nserial %s, 0, %g, %g\n", test_name, result_value, ( tbb::tick_count::now() - t0).seconds()); +} + +const size_t line_size = tbb::internal::NFS_MaxLineSize; + +void run_serial_tests() { + run_serial_scalar_tests<int>("int"); + run_serial_scalar_tests<double>("double"); + run_serial_scalar_tests<minimal<> >("minimal<>"); + run_serial_vector_tests<int>("std::vector<int, tbb::tbb_allocator<int> >"); + run_serial_vector_tests<double>("std::vector<double, tbb::tbb_allocator<double> >"); +} + +template<template<class>class Allocator> +void run_parallel_tests(const char *allocator_name) { + run_parallel_scalar_tests<int, Allocator>("int",allocator_name); + run_parallel_scalar_tests<double, Allocator>("double",allocator_name); + run_parallel_scalar_tests_nocombine<minimal<>,Allocator>("minimal<>",allocator_name); + run_parallel_scalar_tests<ThrowingConstructor, Allocator>("ThrowingConstructor", allocator_name); + run_parallel_vector_tests<int, Allocator>("std::vector<int, tbb::tbb_allocator<int> >",allocator_name); + run_parallel_vector_tests<double, Allocator>("std::vector<double, tbb::tbb_allocator<double> >",allocator_name); +} + +void run_cross_type_tests() { + // cross-type scalar tests are part of run_parallel_scalar_tests_nocombine + run_cross_type_vector_tests<int, tbb::tbb_allocator>("std::vector<int, tbb::tbb_allocator<int> >"); + run_cross_type_vector_tests<double, tbb::tbb_allocator>("std::vector<double, tbb::tbb_allocator<double> >"); +} + +typedef tbb::enumerable_thread_specific<minimal<line_size> > flogged_ets; + +class set_body { + flogged_ets *a; + +public: + set_body( flogged_ets*_a ) : a(_a) { } + + void operator() ( ) const { + for (int i = 0; i < VALID_NUMBER_OF_KEYS; ++i) { + check_alignment(a[i].local(), "default").set_value(i + 1); + } + } + +}; + +void do_tbb_threads( int max_threads, flogged_ets a[] ) { + std::vector< tbb::tbb_thread * > threads; + + for (int p = 0; p < max_threads; ++p) { + threads.push_back( new tbb::tbb_thread ( set_body( a ) ) ); + } + + for (int p = 0; p < max_threads; ++p) { + threads[p]->join(); + } + + for(int p = 0; p < max_threads; ++p) { + delete threads[p]; + } +} + +void flog_key_creation_and_deletion() { + const int FLOG_REPETITIONS = 100; + + for (int p = MinThread; p <= MaxThread; ++p) { + REMARK("Testing repeated deletes on %d threads... ", p); + + for (int j = 0; j < FLOG_REPETITIONS; ++j) { + construction_counter = 0; + destruction_counter = 0; + + // causes VALID_NUMBER_OF_KEYS exemplar instances to be constructed + flogged_ets* a = new flogged_ets[VALID_NUMBER_OF_KEYS]; + ASSERT(int(construction_counter) == 0, NULL); // no exemplars or actual locals have been constructed + ASSERT(int(destruction_counter) == 0, NULL); // and none have been destroyed + + // causes p * VALID_NUMBER_OF_KEYS minimals to be created + do_tbb_threads(p, a); + + for (int i = 0; i < VALID_NUMBER_OF_KEYS; ++i) { + int pcnt = 0; + for ( flogged_ets::iterator tli = a[i].begin(); tli != a[i].end(); ++tli ) { + ASSERT( (*tli).value() == i+1, NULL ); + ++pcnt; + } + ASSERT( pcnt == p, NULL); // should be one local per thread. + } + delete[] a; + } + + ASSERT( int(construction_counter) == (p)*VALID_NUMBER_OF_KEYS, NULL ); + ASSERT( int(destruction_counter) == (p)*VALID_NUMBER_OF_KEYS, NULL ); + + REMARK("done\nTesting repeated clears on %d threads... ", p); + + construction_counter = 0; + destruction_counter = 0; + + // causes VALID_NUMBER_OF_KEYS exemplar instances to be constructed + flogged_ets* a = new flogged_ets[VALID_NUMBER_OF_KEYS]; + + for (int j = 0; j < FLOG_REPETITIONS; ++j) { + + // causes p * VALID_NUMBER_OF_KEYS minimals to be created + do_tbb_threads(p, a); + + for (int i = 0; i < VALID_NUMBER_OF_KEYS; ++i) { + for ( flogged_ets::iterator tli = a[i].begin(); tli != a[i].end(); ++tli ) { + ASSERT( (*tli).value() == i+1, NULL ); + } + a[i].clear(); + ASSERT( static_cast<int>(a[i].end() - a[i].begin()) == 0, NULL ); + } + + } + + delete[] a; + + ASSERT( int(construction_counter) == (FLOG_REPETITIONS*p)*VALID_NUMBER_OF_KEYS, NULL ); + ASSERT( int(destruction_counter) == (FLOG_REPETITIONS*p)*VALID_NUMBER_OF_KEYS, NULL ); + + REMARK("done\n"); + } + +} + +template <typename inner_container> +void flog_segmented_interator() { + + bool found_error = false; + typedef typename inner_container::value_type T; + typedef std::vector< inner_container > nested_vec; + inner_container my_inner_container; + my_inner_container.clear(); + nested_vec my_vec; + + // simple nested vector (neither level empty) + const int maxval = 10; + for(int i=0; i < maxval; i++) { + my_vec.push_back(my_inner_container); + for(int j = 0; j < maxval; j++) { + my_vec.at(i).push_back((T)(maxval * i + j)); + } + } + + tbb::internal::segmented_iterator<nested_vec, T> my_si(my_vec); + + T ii; + for(my_si=my_vec.begin(), ii=0; my_si != my_vec.end(); ++my_si, ++ii) { + if((*my_si) != ii) { + found_error = true; + REMARK( "*my_si=%d\n", int(*my_si)); + } + } + + // outer level empty + my_vec.clear(); + for(my_si=my_vec.begin(); my_si != my_vec.end(); ++my_si) { + found_error = true; + } + + // inner levels empty + my_vec.clear(); + for(int i =0; i < maxval; ++i) { + my_vec.push_back(my_inner_container); + } + for(my_si = my_vec.begin(); my_si != my_vec.end(); ++my_si) { + found_error = true; + } + + // every other inner container is empty + my_vec.clear(); + for(int i=0; i < maxval; ++i) { + my_vec.push_back(my_inner_container); + if(i%2) { + for(int j = 0; j < maxval; ++j) { + my_vec.at(i).push_back((T)(maxval * (i/2) + j)); + } + } + } + for(my_si = my_vec.begin(), ii=0; my_si != my_vec.end(); ++my_si, ++ii) { + if((*my_si) != ii) { + found_error = true; + REMARK("*my_si=%d, ii=%d\n", (int)(*my_si), (int)ii); + } + } + + tbb::internal::segmented_iterator<nested_vec, const T> my_csi(my_vec); + for(my_csi=my_vec.begin(), ii=0; my_csi != my_vec.end(); ++my_csi, ++ii) { + if((*my_csi) != ii) { + found_error = true; + REMARK( "*my_csi=%d\n", int(*my_csi)); + } + } + + // outer level empty + my_vec.clear(); + for(my_csi=my_vec.begin(); my_csi != my_vec.end(); ++my_csi) { + found_error = true; + } + + // inner levels empty + my_vec.clear(); + for(int i =0; i < maxval; ++i) { + my_vec.push_back(my_inner_container); + } + for(my_csi = my_vec.begin(); my_csi != my_vec.end(); ++my_csi) { + found_error = true; + } + + // every other inner container is empty + my_vec.clear(); + for(int i=0; i < maxval; ++i) { + my_vec.push_back(my_inner_container); + if(i%2) { + for(int j = 0; j < maxval; ++j) { + my_vec.at(i).push_back((T)(maxval * (i/2) + j)); + } + } + } + for(my_csi = my_vec.begin(), ii=0; my_csi != my_vec.end(); ++my_csi, ++ii) { + if((*my_csi) != ii) { + found_error = true; + REMARK("*my_csi=%d, ii=%d\n", (int)(*my_csi), (int)ii); + } + } + + + if(found_error) REPORT("segmented_iterator failed\n"); +} + +template <typename Key, typename Val> +void flog_segmented_iterator_map() { + typedef typename std::map<Key, Val> my_map; + typedef std::vector< my_map > nested_vec; + my_map my_inner_container; + my_inner_container.clear(); + nested_vec my_vec; + my_vec.clear(); + bool found_error = false; + + // simple nested vector (neither level empty) + const int maxval = 4; + for(int i=0; i < maxval; i++) { + my_vec.push_back(my_inner_container); + for(int j = 0; j < maxval; j++) { + my_vec.at(i).insert(std::make_pair<Key,Val>(maxval * i + j, 2*(maxval*i + j))); + } + } + + tbb::internal::segmented_iterator<nested_vec, std::pair<const Key, Val> > my_si(my_vec); + Key ii; + for(my_si=my_vec.begin(), ii=0; my_si != my_vec.end(); ++my_si, ++ii) { + if(((*my_si).first != ii) || ((*my_si).second != 2*ii)) { + found_error = true; + REMARK( "ii=%d, (*my_si).first=%d, second=%d\n",ii, int((*my_si).first), int((*my_si).second)); + } + } + + tbb::internal::segmented_iterator<nested_vec, const std::pair<const Key, Val> > my_csi(my_vec); + for(my_csi=my_vec.begin(), ii=0; my_csi != my_vec.end(); ++my_csi, ++ii) { + if(((*my_csi).first != ii) || ((*my_csi).second != 2*ii)) { + found_error = true; + REMARK( "ii=%d, (*my_csi).first=%d, second=%d\n",ii, int((*my_csi).first), int((*my_csi).second)); + } + } + if(found_error) REPORT("segmented_iterator_map failed\n"); +} + +void run_segmented_iterator_tests() { + // only the following containers can be used with the segmented iterator. + REMARK("Running Segmented Iterator Tests\n"); + flog_segmented_interator<std::vector< int > >(); + flog_segmented_interator<std::vector< double > >(); + flog_segmented_interator<std::deque< int > >(); + flog_segmented_interator<std::deque< double > >(); + flog_segmented_interator<std::list< int > >(); + flog_segmented_interator<std::list< double > >(); + + flog_segmented_iterator_map<int, int>(); + flog_segmented_iterator_map<int, double>(); +} + +template<typename T, template<class> class Allocator, typename Init> +tbb::enumerable_thread_specific<T,Allocator<T> > MakeETS( Init init ) { + return tbb::enumerable_thread_specific<T,Allocator<T> >(init); +} +#if __TBB_ETS_USE_CPP11 +// In some GCC versions, parameter packs in lambdas might cause compile errors +template<typename ETS, typename... P> +struct MakeETS_Functor { + ETS operator()( typename tbb::internal::strip<P>::type&&... params ) { + return ETS(std::move(params)...); + } +}; +template<typename T, template<class> class Allocator, typename... P> +tbb::enumerable_thread_specific<T,Allocator<T> > MakeETS( tbb::internal::stored_pack<P...> pack ) { + typedef tbb::enumerable_thread_specific<T,Allocator<T> > result_type; + return tbb::internal::call_and_return< result_type >( + MakeETS_Functor<result_type,P...>(), std::move(pack) + ); +} +#endif + +template<typename T, template<class> class Allocator, typename InitSrc, typename InitDst, typename Validator> +void ets_copy_assign_test( InitSrc init1, InitDst init2, Validator check, const char *allocator_name ) { + typedef tbb::enumerable_thread_specific<T, Allocator<T> > ets_type; + + // Create the source instance + const ets_type& cref_binder = MakeETS<T, Allocator>(init1); + ets_type& source = const_cast<ets_type&>(cref_binder); + check(check_alignment(source.local(),allocator_name)); + + // Test copy construction + bool existed = false; + ets_type copy(source); + check(check_alignment(copy.local(existed),allocator_name)); + ASSERT(existed, "Local data not created by ETS copy constructor"); + copy.clear(); + check(check_alignment(copy.local(),allocator_name)); + + // Test assignment + existed = false; + ets_type assign(init2); + assign = source; + check(check_alignment(assign.local(existed),allocator_name)); + ASSERT(existed, "Local data not created by ETS assignment"); + assign.clear(); + check(check_alignment(assign.local(),allocator_name)); + +#if __TBB_ETS_USE_CPP11 + // Create the source instance + ets_type&& rvref_binder = MakeETS<T, Allocator>(init1); + check(check_alignment(rvref_binder.local(),allocator_name)); + + // Test move construction + existed = false; + ets_type moved(rvref_binder); + check(check_alignment(moved.local(existed),allocator_name)); + ASSERT(existed, "Local data not created by ETS move constructor"); + moved.clear(); + check(check_alignment(moved.local(),allocator_name)); + + // Test assignment + existed = false; + ets_type move_assign(init2); + move_assign = std::move(moved); + check(check_alignment(move_assign.local(existed),allocator_name)); + ASSERT(existed, "Local data not created by ETS move assignment"); + move_assign.clear(); + check(check_alignment(move_assign.local(),allocator_name)); +#endif +} + +template<typename T, int Expected> +struct Validator { + void operator()( const T& value ) { + ASSERT(test_helper<T>::get(value) == Expected, NULL); + } + void operator()( const std::pair<int,T>& value ) { + ASSERT(value.first > 0, NULL); + ASSERT(test_helper<T>::get(value.second) == Expected*value.first, NULL); + } +}; + +template <typename T, template<class> class Allocator> +void run_assign_and_copy_constructor_test(const char *test_name, const char *allocator_name) { + REMARK("Testing assignment and copy construction for %s with allocator %s\n", test_name, allocator_name); + #define EXPECTED 3142 + + // test with exemplar initializer + T src_init; + test_helper<T>::set(src_init,EXPECTED); + T other_init; + test_helper<T>::init(other_init); + ets_copy_assign_test<T, Allocator>(src_init, other_init, Validator<T,EXPECTED>(), allocator_name); + + // test with function initializer + FunctorFinit<T,EXPECTED> src_finit(SecretTag); + FunctorFinit<T,0> other_finit(SecretTag); + ets_copy_assign_test<T, Allocator>(src_finit, other_finit, Validator<T,EXPECTED>(), allocator_name); + +#if __TBB_ETS_USE_CPP11 + // test with multi-argument "emplace" initializer + // The arguments are wrapped into tbb::internal::stored_pack to avoid variadic templates in ets_copy_assign_test. + test_helper<T>::set(src_init,EXPECTED*17); + ets_copy_assign_test< std::pair<int,T>, Allocator>(tbb::internal::save_pack(17,src_init), std::make_pair(-1,T()), Validator<T,EXPECTED>(), allocator_name); +#endif + #undef EXPECTED +} + +template< template<class> class Allocator> +void run_assignment_and_copy_constructor_tests(const char* allocator_name) { + REMARK("Running assignment and copy constructor tests\n"); + run_assign_and_copy_constructor_test<int, Allocator>("int", allocator_name); + run_assign_and_copy_constructor_test<double, Allocator>("double", allocator_name); + // Try class sizes that are close to a cache line in size, in order to check padding calculations. + run_assign_and_copy_constructor_test<minimal<line_size-1>, Allocator >("minimal<line_size-1>", allocator_name); + run_assign_and_copy_constructor_test<minimal<line_size>, Allocator >("minimal<line_size>", allocator_name); + run_assign_and_copy_constructor_test<minimal<line_size+1>, Allocator >("minimal<line_size+1>", allocator_name); + ASSERT(FinitCounter==0, NULL); +} + +// Class with no default constructor +class HasNoDefaultConstructor { + HasNoDefaultConstructor(); +public: + HasNoDefaultConstructor( SecretTagType ) {} +}; +// Initialization functor for HasNoDefaultConstructor +struct HasNoDefaultConstructorFinit { + HasNoDefaultConstructor operator()() { + return HasNoDefaultConstructor(SecretTag); + } +}; +// Combine functor for HasNoDefaultConstructor +struct HasNoDefaultConstructorCombine { + HasNoDefaultConstructor operator()( HasNoDefaultConstructor, HasNoDefaultConstructor ) { + return HasNoDefaultConstructor(SecretTag); + } +}; + +#if __TBB_ETS_USE_CPP11 +// Class that only has a constructor with multiple parameters and a move constructor +class HasSpecialAndMoveCtor : NoCopy { + HasSpecialAndMoveCtor(); +public: + HasSpecialAndMoveCtor( SecretTagType, size_t = size_t(0), const char* = "" ) {} + HasSpecialAndMoveCtor( HasSpecialAndMoveCtor&& ) {} +}; +#endif + +// No-op combine-each functor +template<typename V> +struct EmptyCombineEach { + void operator()( const V& ) { } +}; + +int +align_val(void * const p) { + size_t tmp = (size_t)p; + int a = 1; + while((tmp&0x1) == 0) { a <<=1; tmp >>= 1; } + return a; +} + +bool is_between(void* lowp, void *highp, void *testp) { + if((size_t)lowp < (size_t)testp && (size_t)testp < (size_t)highp) return true; + return (size_t)lowp > (size_t)testp && (size_t)testp > (size_t)highp; +} + +template<class U> struct alignment_of { + typedef struct { char t; U padded; } test_alignment; + static const size_t value = sizeof(test_alignment) - sizeof(U); +}; +using tbb::interface6::internal::ets_element; +template<typename T, typename OtherType> +void allocate_ets_element_on_stack(const char *name) { + typedef T aligning_element_type; + const size_t my_align = alignment_of<aligning_element_type>::value; + OtherType c1; + ets_element<aligning_element_type> my_stack_element; + OtherType c2; + ets_element<aligning_element_type> my_stack_element2; + struct { + OtherType cxx; + ets_element<aligning_element_type> my_struct_element; + } mystruct1; + tbb::internal::suppress_unused_warning(c1,c2); + REMARK("using %s, c1 address == %lx (alignment %d), c2 address == %lx (alignment %d)\n", name, &c1, align_val(&c1), &c2, align_val(&c2)); + REMARK(" ---- my_align == %d\n", (int)my_align); + REMARK(" my_stack_element == %lx (alignment %d), my_stack_element2 == %lx (alignment %d)\n", + &my_stack_element, align_val(&my_stack_element), &my_stack_element2, align_val(&my_stack_element2)); + if(is_between(&c1,&c2,&my_stack_element)) REMARK("my_struct_element is in the middle\n"); + if(is_between(&c1,&c2,&my_stack_element2)) REMARK("my_struct_element2 is in the middle\n"); + if(!is_between(&c1,&c2,&my_stack_element) && !is_between(&c1,&c2,&my_stack_element2)) REMARK("stack vars reorganized\n"); + REMARK(" structure field address == %lx, alignment %d\n", + mystruct1.my_struct_element.value(), + align_val(mystruct1.my_struct_element.value()) + ); + ASSERT(tbb::internal::is_aligned(my_stack_element.value(), my_align), "Error in first stack alignment" ); + ASSERT(tbb::internal::is_aligned(my_stack_element2.value(), my_align), "Error in second stack alignment" ); + ASSERT(tbb::internal::is_aligned(mystruct1.my_struct_element.value(), my_align), "Error in struct element alignment" ); +} + +//! Test situations where only default constructor or copy constructor is required. +template<template<class> class Allocator> +void TestInstantiation(const char *allocator_name) { + REMARK("TestInstantiation<%s>\n", allocator_name); + // Test instantiation is possible when copy constructor is not required. + tbb::enumerable_thread_specific<NoCopy, Allocator<NoCopy> > ets1; + ets1.local(); + ets1.combine_each(EmptyCombineEach<NoCopy>()); + + // Test instantiation when default constructor is not required, because exemplar is provided. + HasNoDefaultConstructor x(SecretTag); + tbb::enumerable_thread_specific<HasNoDefaultConstructor, Allocator<HasNoDefaultConstructor> > ets2(x); + ets2.local(); + ets2.combine(HasNoDefaultConstructorCombine()); + + // Test instantiation when default constructor is not required, because init function is provided. + HasNoDefaultConstructorFinit f; + tbb::enumerable_thread_specific<HasNoDefaultConstructor, Allocator<HasNoDefaultConstructor> > ets3(f); + ets3.local(); + ets3.combine(HasNoDefaultConstructorCombine()); + +#if __TBB_ETS_USE_CPP11 + // Test instantiation with multiple arguments + tbb::enumerable_thread_specific<HasSpecialAndMoveCtor, Allocator<HasSpecialAndMoveCtor> > ets4(SecretTag, 0x42, "meaningless"); + ets4.local(); + ets4.combine_each(EmptyCombineEach<HasSpecialAndMoveCtor>()); + // Test instantiation with one argument that should however use the variadic constructor + tbb::enumerable_thread_specific<HasSpecialAndMoveCtor, Allocator<HasSpecialAndMoveCtor> > ets5(SecretTag); + ets5.local(); + ets5.combine_each(EmptyCombineEach<HasSpecialAndMoveCtor>()); + // Test that move operations do not impose extra requirements + // Default allocator is used. If it does not match Allocator, there will be elementwise move + tbb::enumerable_thread_specific<HasSpecialAndMoveCtor> ets6( std::move(ets4) ); + ets6.combine_each(EmptyCombineEach<HasSpecialAndMoveCtor>()); + ets6 = std::move(ets5); +#endif +} + +class BigType { +public: + BigType() { /* avoid cl warning C4345 about default initialization of POD types */ } + char my_data[12 * 1024 * 1024]; +}; + +template<template<class> class Allocator> +void TestConstructorWithBigType(const char *allocator_name) { + typedef tbb::enumerable_thread_specific<BigType, Allocator<BigType> > CounterBigType; + REMARK("TestConstructorWithBigType<%s>\n", allocator_name); + // Test default constructor + CounterBigType MyCounters; + // Create a local instance. + typename CounterBigType::reference my_local = MyCounters.local(); + my_local.my_data[0] = 'a'; + // Test copy constructor + CounterBigType MyCounters2(MyCounters); + ASSERT(check_alignment(MyCounters2.local(), allocator_name).my_data[0]=='a', NULL); +} + +int TestMain () { + size_t tbb_allocator_mask; + size_t cache_allocator_mask = tbb::internal::NFS_GetLineSize(); + REMARK("estimatedCacheLineSize == %d, NFS_GetLineSize() returns %d\n", + (int)estimatedCacheLineSize, (int)tbb::internal::NFS_GetLineSize()); + //TODO: use __TBB_alignof(T) to check for local() results instead of using internal knowledges of ets element padding + if(tbb::tbb_allocator<int>::allocator_type() == tbb::tbb_allocator<int>::standard) { + // scalable allocator is not available. + tbb_allocator_mask = 1; + REMARK("tbb::tbb_allocator is not available\n"); + } + else { + // this value is for large objects, but will be correct for small. + tbb_allocator_mask = estimatedCacheLineSize; + } + AlignMask = cache_allocator_mask; + TestInstantiation<tbb::cache_aligned_allocator>("tbb::cache_aligned_allocator"); + AlignMask = tbb_allocator_mask; + TestInstantiation<tbb::tbb_allocator>("tbb::tbb_allocator"); + AlignMask = cache_allocator_mask; + run_assignment_and_copy_constructor_tests<tbb::cache_aligned_allocator>("tbb::cache_aligned_allocator"); + AlignMask = tbb_allocator_mask; + run_assignment_and_copy_constructor_tests<tbb::tbb_allocator>("tbb::tbb_allocator"); + run_segmented_iterator_tests(); + flog_key_creation_and_deletion(); + + if (MinThread == 0) { + run_serial_tests(); + MinThread = 1; + } + if (MaxThread > 0) { + AlignMask = cache_allocator_mask; + run_parallel_tests<tbb::cache_aligned_allocator>("tbb::cache_aligned_allocator"); + AlignMask = tbb_allocator_mask; + run_parallel_tests<tbb::tbb_allocator>("tbb::tbb_allocator"); + run_cross_type_tests(); + } + + AlignMask = cache_allocator_mask; + TestConstructorWithBigType<tbb::cache_aligned_allocator>("tbb::cache_aligned_allocator"); + AlignMask = tbb_allocator_mask; + TestConstructorWithBigType<tbb::tbb_allocator>("tbb::tbb_allocator"); + + allocate_ets_element_on_stack<int,char>("int vs. char"); + allocate_ets_element_on_stack<int,short>("int vs. short"); + allocate_ets_element_on_stack<int,char[3]>("int vs. char[3]"); + allocate_ets_element_on_stack<float,char>("float vs. char"); + allocate_ets_element_on_stack<float,short>("float vs. short"); + allocate_ets_element_on_stack<float,char[3]>("float vs. char[3]"); + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_environment_whitebox.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_environment_whitebox.cpp new file mode 100644 index 00000000..7fc6cb29 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_environment_whitebox.cpp @@ -0,0 +1,241 @@ +/* + Copyright (c) 2018-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness.h" +#include "../tbb/tbb_environment.h" + +#include <string> +#include <algorithm> +#include <sstream> +#include <climits> +#include <utility> +#include <vector> + +const char * environment_variable_name = "TEST_VARIABLE_NAME"; + +// For WIN8UI applications reading and writing the environment variables +// is prohibited due to the platform limitations +#if !__TBB_WIN8UI_SUPPORT + +#if _WIN32 || _WIN64 + // Environment variable length is limited by 32K on Windows systems + const size_t large_length = 32000; +#else + const size_t large_length = 1000000; +#endif + +template<typename T> +void set_and_get_test_variable( T (*environment_variable_getter )(const char *), + std::pair<std::string, T> test_case ) { + Harness::SetEnv(environment_variable_name, test_case.first.c_str()); + T result = environment_variable_getter(environment_variable_name); + ASSERT(result == test_case.second, "Wrong Get<Type>EnvironmentVariable return value"); + Harness::SetEnv(environment_variable_name, ""); +} + +Harness::FastRandom rnd(12345); + +struct random_character_generator { + char operator()() { + return rnd.get() % 128; // 127 - the last ASCII symbol + } +}; + +bool alternative_env_variable_checker(const char * str, bool) { + bool result = false; + for (unsigned i = 0; str[i]; i++) { + if (str[i] == '1') { + // if we found more the one '1' character -> return false + result = !result; + if (!result) return false; + } + else if (str[i] != ' ') { + // if we found some character other than ' ' and '1' -> return false + return false; + } + } + return result; +} + +// Suitable alternative checker for GetLongEnvVariable() was not found +// So we use here code from GetLongEnvVariable() realization +long alternative_env_variable_checker(const char * str, long) { + char* end; + errno=0; + long result = std::strtol(str, &end, 10); + + // We have exceeded the range, value is negative or string is incovertable + if (errno == ERANGE || result < 0 || end==str) { + result = -1; + } + + for (; *end != '\0'; end++) { + if (!std::isspace(*end)) + result = -1; + } + return result; +} + +template <typename T> +std::pair<std::string, T> create_random_case(size_t length){ + ASSERT(length != 0, "Requested random string cannot be empty"); + std::string rand_string(length, ' '); + std::generate(rand_string.begin(), rand_string.end(), random_character_generator()); + + T expected_result = alternative_env_variable_checker(rand_string.c_str(), T()); + + return std::make_pair(rand_string, expected_result); +} + +template <typename T> +void prepare_random_cases(std::vector<std::pair<std::string, T> >& cases){ + // Random cases + size_t length = 10000; + + for(size_t i =0; i < 10; ++i) { + cases.push_back(create_random_case<T>((rnd.get() % length) + 1 )); + } + + // Random case with large string + cases.push_back(create_random_case<T>(large_length)); +} + +std::vector<std::pair<std::string, bool> > initialize_cases( bool wrong_result ){ + std::vector<std::pair<std::string, bool> > cases; + // Valid cases + cases.push_back(std::make_pair("1", true)); + cases.push_back(std::make_pair(" 1 ", true)); + cases.push_back(std::make_pair("1 ", true)); + cases.push_back(std::make_pair(" 1 ", true)); + cases.push_back(std::make_pair(" 1", true)); + cases.push_back(std::make_pair((std::string(large_length, ' ')+'1').c_str(), true)); + + // Invalid cases + + cases.push_back(std::make_pair("", wrong_result)); + cases.push_back(std::make_pair(" ", wrong_result)); + cases.push_back(std::make_pair(" 11", wrong_result)); + cases.push_back(std::make_pair("111111", wrong_result)); + cases.push_back(std::make_pair("1 1", wrong_result)); + cases.push_back(std::make_pair(" 1 abc?", wrong_result)); + cases.push_back(std::make_pair("1;", wrong_result)); + cases.push_back(std::make_pair(" d ", wrong_result)); + cases.push_back(std::make_pair("0", wrong_result)); + cases.push_back(std::make_pair("0 ", wrong_result)); + cases.push_back(std::make_pair("000000", wrong_result)); + cases.push_back(std::make_pair("01", wrong_result)); + cases.push_back(std::make_pair("00000001", wrong_result)); + cases.push_back(std::make_pair("ABCDEFG", wrong_result)); + cases.push_back(std::make_pair("2018", wrong_result)); + cases.push_back(std::make_pair("ABC_123", wrong_result)); + cases.push_back(std::make_pair("true", wrong_result)); + cases.push_back(std::make_pair(std::string(large_length, 'A').c_str(), wrong_result)); + + prepare_random_cases(cases); + + return cases; +} + +std::vector<std::pair<std::string, long> > initialize_cases( long wrong_result ){ + std::vector<std::pair<std::string, long> > cases; + std::stringstream ss; + // Valid cases + for (long i = 0; i < 100; i++) { + ss << i; + cases.push_back(std::make_pair(ss.str().c_str(), i)); + ss.str(""); + + ss << " " << i << " "; + cases.push_back(std::make_pair(ss.str().c_str(), i)); + ss.str(""); + + ss << i << " "; + cases.push_back(std::make_pair(ss.str().c_str(),i)); + ss.str(""); + + ss << " " << i; + cases.push_back(std::make_pair(ss.str().c_str(),i)); + ss.str(""); + } + + ss << LONG_MAX; + cases.push_back(std::make_pair(ss.str().c_str(),LONG_MAX)); + ss.str(""); + + cases.push_back(std::make_pair((std::string(large_length, ' ')+'1').c_str(), 1L)); + + // Invalid cases + cases.push_back(std::make_pair("", wrong_result)); + cases.push_back(std::make_pair(" ", wrong_result)); + cases.push_back(std::make_pair("a", wrong_result)); + cases.push_back(std::make_pair("^&*", wrong_result)); + cases.push_back(std::make_pair(" 10 e", wrong_result)); + cases.push_back(std::make_pair("a 12", wrong_result)); + cases.push_back(std::make_pair("eeeeeeeeeeeeeeeeeeeeeeeeee", wrong_result)); + cases.push_back(std::make_pair("200000000000000000000000000", wrong_result)); + cases.push_back(std::make_pair("-1", wrong_result)); + cases.push_back(std::make_pair("-100", wrong_result)); + cases.push_back(std::make_pair("-20000000000000000000000000", wrong_result)); + cases.push_back(std::make_pair("ABBDDRR", wrong_result)); + cases.push_back(std::make_pair("10 10", wrong_result)); + cases.push_back(std::make_pair("true", wrong_result)); + cases.push_back(std::make_pair("false", wrong_result)); + cases.push_back(std::make_pair("1A", wrong_result)); + cases.push_back(std::make_pair("_123", wrong_result)); + cases.push_back(std::make_pair(std::string(large_length, 'A').c_str(), wrong_result)); + + // Prepare string with LONG_MAX + 1 value + ss << LONG_MAX / 10 << (LONG_MAX % 10 + 1); + cases.push_back(std::make_pair(ss.str().c_str(),-1)); + ss.str(""); + + prepare_random_cases(cases); + return cases; +} + +template <typename T> +void test_environment_variable( T (*environment_variables_handler )(const char *), T wrong_result ) { + ASSERT(environment_variables_handler (environment_variable_name) == wrong_result, + "Tested environment variable should not be defined in the beginning of the test"); + + // Every pair is a test case: + // pair.first -> value of environment variable + // pair.second -> expected result + std::vector< std::pair<std::string, T> > cases = initialize_cases(wrong_result); + + for (size_t i = 0; i != cases.size(); i++) { + set_and_get_test_variable(environment_variables_handler, cases[i]); + } +} + + +#else // __TBB_WIN8UI_SUPPORT + +template <typename T> +void test_environment_variable(T (*environment_variables_handler )(const char *), T wrong_result) { + for(size_t i = 0; i < 100; ++i) { + ASSERT(environment_variables_handler(environment_variable_name) == wrong_result, + "Get<Type>EnvironmentVariable should always return false for UWP applications"); + } +} + +#endif // __TBB_WIN8UI_SUPPORT + +int TestMain() { + test_environment_variable(tbb::internal::GetBoolEnvironmentVariable, false); + test_environment_variable(tbb::internal::GetIntegralEnvironmentVariable, -1L); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_examples_common_utility.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_examples_common_utility.cpp new file mode 100644 index 00000000..c94c891e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_examples_common_utility.cpp @@ -0,0 +1,598 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_TEST_USE_WSUGGEST_OVERRIDE +// __TBB_override may not be used in the tested header file +#pragma GCC diagnostic ignored "-Wsuggest-override" +#undef __TBB_TEST_USE_WSUGGEST_OVERRIDE +#endif + +#include "harness_defs.h" // for suppress_unused_warning + +#if TBB_USE_EXCEPTIONS +#include "harness_assert.h" +#include "../../examples/common/utility/utility.h" +#include <sstream> + +namespace implementation_unit_tests { + namespace argument_dest_test_suite{ + void test_type_impl_parse_and_store_simple_parse(){ + int a=0; + utility::internal::type_impl<int> a_("","",a); + a_.parse_and_store("9"); + ASSERT(a==9,""); + } + void test_default_value_of_is_matched(){ + //Testing for result of is_matched() for arguments not yet tried to be parsed. + //I.e. values were set up by argument::constructor. + using utility::internal::argument; + int i; + argument b("","",i); + ASSERT(!b.is_matched(),""); + + argument c = b; + ASSERT(!c.is_matched(),""); + + argument d = b; + d = c; + ASSERT(!d.is_matched(),""); + } + } + //TODO: test cases for argument type management + namespace compile_only{ + //TODO: enhance these to actually do checks by a negative test, or (if possible) + //by a positive test that at compile time selects between two alternatives, + //depending on whether operators exist or not (yes, SFINAE :)) - + //as non_pod class does provide the operators, and test do not check that compiler + //will reject types which don't have those. + using utility::cli_argument_pack; + void arg_chain(){ + cli_argument_pack p; + int size=0; + p.arg(size,"size","size"); + } + namespace tc_helper{ + struct non_pod{ + std::string s; + friend std::ostream& operator<<(std::ostream& o, non_pod){ return o;} + friend std::istream& operator>>(std::istream& i, non_pod){ return i;} + }; + } + void non_pod_dest_type(){ + cli_argument_pack p; + tc_helper::non_pod np; + p.arg(np,"",""); + } + } + namespace cli_argument_pack_suite{ + void test_copy_assign(){ + using utility::cli_argument_pack; + int i=9; + std::stringstream expected_output; using std::endl; + expected_output + << " Program usage is:" << endl + << " the_binary_name [i=value]" + << endl << endl + << " where:" << endl + << " i - i desc (9)" << endl + ; + cli_argument_pack copy(cli_argument_pack().arg(i,"i","i desc")); + ASSERT(copy.usage_string("the_binary_name") == expected_output.str(),"usage string is not as expected"); + cli_argument_pack assignee; assignee = copy; + ASSERT(assignee.usage_string("the_binary_name") == expected_output.str(),"Copying of cli_argument_pack breaks generation of usage string?"); + } + } +} + +#include <utility> +namespace high_level_api_tests { + using utility::cli_argument_pack; + using utility::internal::array_length; + + static const char * wrong_exception = "wrong exception thrown"; + static const char * wrong_exception_description = "caught exception has wrong description"; + void test_parse_basic(){ + char const* argv[]={"some.exe","1","a"}; + cli_argument_pack p; + int i=0; char a=' '; + p.positional_arg(i,"int","").positional_arg(a,"char",""); + p.parse(array_length(argv),argv); + ASSERT(i==1,""); + ASSERT(a=='a',""); + } + //helper function for test of named flag parsing + template<typename T, size_t N> + bool parse_silent_flag( T(& argv)[N]){ + cli_argument_pack p; + bool silent=false; + p.arg(silent,"silent","is extra info needed"); + p.parse(array_length(argv),argv); + return silent; + } + void test_named_flags_success(){ + char const* argv[]={"some.exe","silent"}; + ASSERT(true == parse_silent_flag(argv),""); + } + + void test_named_flags_failure(){ + try { + char const* argv[]={"some.exe","1"}; + parse_silent_flag(argv); + ASSERT(false,"exception was expected due to invalid argument, but not caught"); + } + catch(std::invalid_argument& e){ + ASSERT(e.what()==std::string("unknown parameter starting at:'1'"),wrong_exception_description); + } + catch(...){ASSERT(false,wrong_exception);} + } + + //helper function for test of named flag parsing + template<typename T, size_t N> + std::pair<bool,int> parse_silent_flag_and_int( T(& argv)[N]){ + cli_argument_pack p; + bool silent=false; + int i=125; + p + .arg(silent,"silent","is extra info needed") + .positional_arg(i,"int",""); + p.parse(array_length(argv),argv); + return std::make_pair(silent,i); + } + + void test_named_flags_failure_and_other_arg(){ + char const* argv[]={"some.exe","1"}; + ASSERT(std::make_pair(false,1) == parse_silent_flag_and_int(argv),""); + } + + void test_named_flags_and_other_arg(){ + char const* argv[]={"some.exe","silent","7"}; + ASSERT(std::make_pair(true,7) == parse_silent_flag_and_int(argv),""); + } + + void test_named_flags_and_other_arg_different_order(){ + char const* argv[]={"some.exe","7","silent"}; + ASSERT(std::make_pair(true,7) == parse_silent_flag_and_int(argv),""); + } + + void test_flags_only_others_default(){ + char const* argv[]={"some.exe","silent"}; + ASSERT(std::make_pair(true,125) == parse_silent_flag_and_int(argv),""); + } + + namespace parameters_validation_test_suite{ + namespace test_validation_function_called_helpers{ + struct validator{ + static bool called; + static bool accept(const int & ){ + called = true; + return true; + } + }; + bool validator::called =false; + } + void test_validation_function_called(){ + using test_validation_function_called_helpers::validator; + + char const* argv[]={"some.exe","7"}; + cli_argument_pack p; + int size =0; + p.positional_arg(size,"size","",validator::accept); + p.parse(array_length(argv),argv); + ASSERT((validator::called),"validation function has not been called"); + } + void test_validation_failed(){ + struct validator{ + static bool reject(const int &){ + return false; + } + }; + char const* argv[]={"some.exe","7"}; + cli_argument_pack p; + int size =0; + p.positional_arg(size,"size","",validator::reject); + try { + p.parse(array_length(argv),argv); + ASSERT((false),"An exception was expected due to failed argument validation, " + "but no exception thrown"); + } + catch(std::invalid_argument& e){ + std::string error_msg("'7' is invalid value for argument 'size'"); + ASSERT(e.what()==error_msg , wrong_exception_description); + } + catch(...){ASSERT((false),wrong_exception);} + } + } + namespace error_handling { + void test_wrong_input(){ + char const* argv[]={"some.exe","silent"}; + cli_argument_pack p; + int size =0; + p.positional_arg(size,"size",""); + try{ + p.parse(array_length(argv),argv); + ASSERT(false,"An exception was expected due to wrong input, but no exception thrown"); + } + catch(std::invalid_argument & e){ + std::string error_msg("'silent' is incorrect input for argument 'size' (error converting string 'silent')"); + ASSERT(e.what()==error_msg, wrong_exception_description); + } + catch(...){ASSERT(false,wrong_exception);} + } + void test_duplicate_arg_names(){ + cli_argument_pack p; + int a=0; + p.arg(a,"a",""); + try{ + int dup_a=0; + p.arg(dup_a,"a",""); + ASSERT(false, "An exception was expected due adding duplicate parameter name, but not thrown"); + } + catch(std::invalid_argument& e){ + ASSERT(e.what()==std::string("argument with name: 'a' already registered"),wrong_exception_description); + } + catch(...){ASSERT(false,wrong_exception);} + } + void test_duplicate_positional_arg_names(){ + cli_argument_pack p; + int a=0; + p.positional_arg(a,"a",""); + try{ + int dup_a=0; + p.positional_arg(dup_a,"a",""); + ASSERT(false, "An exception was expected due adding duplicate parameter name, but not thrown"); + } + catch(std::invalid_argument& e){ + ASSERT(e.what()==std::string("argument with name: 'a' already registered"),wrong_exception_description); + } + catch(...){ASSERT(false,wrong_exception);} + } + } + namespace usage_string { + void test_one_arg(){ + cli_argument_pack p; + int size =9; + p.arg(size,"size","size of problem domain"); + std::string const binary_name = "binary.exe"; + std::stringstream expected_output; + using std::endl; + expected_output << " Program usage is:" << endl + << " " << binary_name << " [size=value]" + << endl << endl + << " where:" << endl + << " size - size of problem domain (9)" << endl + ; + std::string usage= p.usage_string(binary_name); + ASSERT(usage==expected_output.str(),""); + } + void test_named_and_postional_args(){ + cli_argument_pack p; + int size =9; + int length =8; + int stride = 7; + p + .arg(size,"size","") + .positional_arg(length,"length","") + .positional_arg(stride,"stride",""); + std::string const binary_name = "binary.exe"; + std::stringstream expected_output; + using std::endl; + expected_output << " Program usage is:" << endl + << " " << binary_name << " [size=value] [length=value] [stride=value] [length [stride]]" + << endl << endl + << " where:" << endl + << " size - (9)" << endl + << " length - (8)" << endl + << " stride - (7)" << endl + ; + std::string usage= p.usage_string(binary_name); + ASSERT(usage==expected_output.str(),""); + } + void test_bool_flag(){ + bool flag=false; + cli_argument_pack p; + p.arg(flag,"flag",""); + std::string const binary_name = "binary.exe"; + std::stringstream expected_output; + using std::endl; + expected_output << " Program usage is:" << endl + << " " << binary_name << " [flag]" + << endl << endl + << " where:" << endl + << " flag - (0)" << endl + ; + std::string usage= p.usage_string(binary_name); + ASSERT(usage==expected_output.str(),""); + + } + + } + namespace name_positional_syntax { + void test_basic(){ + cli_argument_pack p; + int size =0; + int time = 0; + p + .positional_arg(size,"size","") + .positional_arg(time,"time",""); + char const* argv[]={"some.exe","1","2"}; + p.parse(array_length(argv),argv); + ASSERT(size==1,""); + ASSERT(time==2,""); + } + void test_positional_args_explicitly_named(){ + const char* no_or_wrong_exception_error_msg = "exception was expected but not thrown, or wrong exception caught"; + //TODO: Similar functionality is used all over the test. Generalize this helper further, and use as wide within the test as possible? + struct failed_with_exception{ + static bool _(cli_argument_pack & p, std::size_t argc, char const* argv[]){ + try{ + p.parse(argc,argv); + return false; + } + catch(std::exception &){ + return true; + } + catch(...){ + return false; + } + } + }; + { + cli_argument_pack p; + int a,b,c,d; + p + .positional_arg(a,"a","") + .positional_arg(b,"b","") + .positional_arg(c,"c","") + .positional_arg(d,"d",""); + char const* argv[]={"some.exe","a=7","0","1","2","4"}; + ASSERT(failed_with_exception::_(p,array_length(argv),argv),no_or_wrong_exception_error_msg); + } + { + cli_argument_pack p; + int a,b,c,d; + p + .positional_arg(a,"a","") + .positional_arg(b,"b","") + .positional_arg(c,"c","") + .positional_arg(d,"d",""); + char const* argv[]={"some.exe","a=7","0","1","2"}; + ASSERT(failed_with_exception::_(p,array_length(argv),argv),no_or_wrong_exception_error_msg); + } + { + cli_argument_pack p; + int a=-1,b=-1,c = -1,d=-1; + p + .positional_arg(a,"a","") + .positional_arg(b,"b","") + .positional_arg(c,"c","") + .positional_arg(d,"d",""); + char const* argv[]={"some.exe","0","1","d=7",}; + ASSERT(!failed_with_exception::_(p,array_length(argv),argv),"unexpected exception"); + ASSERT(a==0,""); ASSERT(b==1,""); ASSERT(c==-1,"");ASSERT(d==7,""); + } + } + } + namespace name_value_syntax { + void test_basic(){ + cli_argument_pack p; + int size =0; + p.arg(size,"size","size of problem domain"); + char const* argv[]={"some.exe","size=7"}; + p.parse(array_length(argv),argv); + ASSERT(size==7,""); + } + + void test_relaxed_order(){ + cli_argument_pack p; + int size =0; + int time=0; + p + .arg(size,"size","") + .arg(time,"time",""); + char const* argv[]={"some.exe","time=1","size=2"}; + p.parse(array_length(argv),argv); + ASSERT(size==2,""); + ASSERT(time==1,""); + } + + } + namespace number_of_argument_value{ + void test_only_single_values_allowed(){ + cli_argument_pack p; + int a=0; + p.arg(a,"a",""); + const char* argv[] = {"","a=7","a=8"}; + try { + p.parse(array_length(argv),argv); + ASSERT(false,"exception was expected due to duplicated values provided in input, but not thrown"); + } + catch(std::invalid_argument& e){ + //TODO: use patterns (regexp ?) to generate /validate exception descriptions + ASSERT(e.what() == std::string("several values specified for: 'a' argument"),wrong_exception_description); + } + catch(...){ASSERT(false,wrong_exception);} + } + } + namespace thread_range_tests{ + using utility::thread_number_range; + using utility::internal::thread_range_step; + using utility::internal::step_function_multiply; + using utility::internal::step_function_plus; + using utility::internal::step_function_power2_ladder; + + int auto_value(){ + return 100; + } + bool operator ==(thread_range_step const& left, utility::internal::thread_range_step const& right){ + return (left.step_function == right.step_function) + && (left.step_function_argument == right.step_function_argument) + ; + } + + bool operator ==(thread_number_range const& left, thread_number_range const& right){ + return (left.auto_number_of_threads==right.auto_number_of_threads) + && (left.first == right.first) + && (left.last == right.last) + && (left.step == right.step) + ; + } + + void constructor_default_values(){ + thread_number_range r(auto_value); + const int default_num_threads = auto_value(); + ASSERT((r.first==1)&&(r.last==default_num_threads),""); + } + void validation(){ + try{ + thread_number_range range(auto_value,12,6); + Harness::suppress_unused_warning(range); + ASSERT(false,"exception was expected due to invalid range specified, but not thrown"); + } + catch(std::invalid_argument& e){ + ASSERT(e.what() == std::string("decreasing sequence not allowed"), wrong_exception_description); + } + catch(...){ASSERT(false,wrong_exception);} + } + + thread_number_range thread_number_range_from_string(std::string const& string_to_parse){ + thread_number_range r(auto_value,0,0); + std::stringstream str(string_to_parse); str>>r; + return r; + } + static const char* thread_range_parse_failed = "error parsing thread range string"; + void post_process_single_value(){ + ASSERT(thread_number_range_from_string("auto") == + thread_number_range(auto_value,auto_value(),auto_value()) + ,thread_range_parse_failed + ); + } + void post_process_pair_value(){ + ASSERT(thread_number_range_from_string("1:auto") == + thread_number_range(auto_value,1,auto_value()) + ,thread_range_parse_failed + ); + + ASSERT(thread_number_range_from_string("auto:auto") == + thread_number_range(auto_value,auto_value(),auto_value()) + ,thread_range_parse_failed + ); + } + + void post_process_troika_value_with_plus_step(){ + ASSERT(thread_number_range_from_string("1:auto:+2") == + thread_number_range(auto_value,1,auto_value(),thread_range_step(step_function_plus,2)) + ,thread_range_parse_failed + ); + } + + void post_process_troika_value_with_multiply_step(){ + ASSERT(thread_number_range_from_string("1:auto:*2.6") == + thread_number_range(auto_value,1,auto_value(),thread_range_step(step_function_multiply,2.6)) + ,thread_range_parse_failed + ); + } + + void post_process_troika_value_with_ladder_step(){ + try{ + thread_number_range range = thread_number_range_from_string("1:16:#3"); + Harness::suppress_unused_warning(range); + ASSERT(false,"exception was expected due to invalid range specified, but not thrown"); + } + catch(std::invalid_argument& e){ + ASSERT(e.what() == std::string("the argument of # should be a power of 2"), wrong_exception_description); + } + catch(...){ASSERT(false,wrong_exception);} + + ASSERT(thread_number_range_from_string("1:32:#4") == + thread_number_range(auto_value,1,32,thread_range_step(step_function_power2_ladder,4)) + ,thread_range_parse_failed + ); + } + + void test_print_content(){ + std::stringstream str; + str<<thread_number_range(auto_value,1,8,thread_range_step(step_function_multiply,2)); + ASSERT(str.str() == "1:8:*2","Unexpected string"); + } + } +} + +void run_implementation_unit_tests(){ + using namespace implementation_unit_tests; + argument_dest_test_suite::test_type_impl_parse_and_store_simple_parse(); + argument_dest_test_suite::test_default_value_of_is_matched(); + + cli_argument_pack_suite::test_copy_assign(); +} +void run_high_level_api_tests(){ + using namespace high_level_api_tests; + + test_parse_basic(); + test_named_flags_success(); + test_named_flags_failure(); + test_named_flags_failure_and_other_arg(); + test_named_flags_and_other_arg(); + test_flags_only_others_default(); + test_named_flags_and_other_arg_different_order(); + + usage_string::test_one_arg(); + usage_string::test_named_and_postional_args(); + usage_string::test_bool_flag(); + + parameters_validation_test_suite::test_validation_function_called(); + parameters_validation_test_suite::test_validation_failed(); + + name_value_syntax::test_basic(); + name_value_syntax::test_relaxed_order(); + + number_of_argument_value::test_only_single_values_allowed(); + + name_positional_syntax::test_basic(); + name_positional_syntax::test_positional_args_explicitly_named(); + + error_handling::test_wrong_input(); + error_handling::test_duplicate_arg_names(); + error_handling::test_duplicate_positional_arg_names(); + + thread_range_tests::constructor_default_values(); + thread_range_tests::validation(); + thread_range_tests::post_process_single_value(); + thread_range_tests::post_process_pair_value(); + thread_range_tests::post_process_troika_value_with_plus_step(); + thread_range_tests::post_process_troika_value_with_multiply_step(); + thread_range_tests::post_process_troika_value_with_ladder_step(); + thread_range_tests::test_print_content(); +} +#endif // TBB_USE_EXCEPTIONS + +#include "harness.h" +int TestMain(){ +#if TBB_USE_EXCEPTIONS + Harness::suppress_unused_warning(utility::thread_number_range_desc); + try{ + run_implementation_unit_tests(); + run_high_level_api_tests(); + }catch(std::exception& e){ + //something went wrong , dump any possible details + std::stringstream str; str<< "run time error: " << e.what()<<std::endl; + ASSERT(false,str.str().c_str()); + } + return Harness::Done; +#else + REPORT("Known issue: the test cannot work with exceptions disabled\n"); + return Harness::Done; +#endif +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_fast_random.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_fast_random.cpp new file mode 100644 index 00000000..59b834ef --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_fast_random.cpp @@ -0,0 +1,196 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + The test checks that for different ranges of random numbers (from 0 to + [MinThread, MaxThread]) generated with different seeds the probability + of each number in the range deviates from the ideal random distribution + by no more than AcceptableDeviation percent. +**/ + +#define HARNESS_DEFAULT_MIN_THREADS 2 +#define HARNESS_DEFAULT_MAX_THREADS 32 + +#define HARNESS_DEFINE_PRIVATE_PUBLIC 1 +#include "harness_inject_scheduler.h" + +#define TEST_TOTAL_SEQUENCE 0 + +#include "harness.h" +#include "tbb/atomic.h" + +//! Coefficient defining tolerable deviation from ideal random distribution +const double AcceptableDeviation = 2.1; +//! Tolerable probability of failure to achieve tolerable distribution +const double AcceptableProbabilityOfOutliers = 1e-5; +//! Coefficient defining the length of random numbers series used to estimate the distribution +/** Number of random values generated per each range element. I.e. the larger is + the range, the longer is the series of random values. **/ +const uintptr_t SeriesBaseLen = 100; +//! Number of random numbers series to generate +const uintptr_t NumSeries = 100; +//! Number of random number generation series with different seeds +const uintptr_t NumSeeds = 100; + +tbb::atomic<uintptr_t> NumHighOutliers; +tbb::atomic<uintptr_t> NumLowOutliers; + +inline void CheckProbability ( double probability, double expectedProbability, int index, int numIndices, void* seed ) { + double lowerBound = expectedProbability / AcceptableDeviation, + upperBound = expectedProbability * AcceptableDeviation; + if ( probability < lowerBound ) { + if ( !NumLowOutliers ) + REMARK( "Warning: Probability %.3f of hitting index %d among %d elements is out of acceptable range (%.3f - %.3f) for seed %p\n", + probability, index, numIndices, lowerBound, upperBound, seed ); + ++NumLowOutliers; + } + else if ( probability > upperBound ) { + if ( !NumHighOutliers ) + REMARK( "Warning: Probability %.3f of hitting index %d among %d elements is out of acceptable range (%.3f - %.3f) for seed %p\n", + probability, index, numIndices, lowerBound, upperBound, seed ); + ++NumHighOutliers; + } +} + +struct CheckDistributionBody { + void operator() ( int id ) const { + uintptr_t randomRange = id + MinThread; + uintptr_t *curHits = new uintptr_t[randomRange] +#if TEST_TOTAL_SEQUENCE + , *totalHits = new uintptr_t[randomRange] +#endif + ; + double expectedProbability = 1./randomRange; + // Loop through different seeds + for ( uintptr_t i = 0; i < NumSeeds; ++i ) { + // Seed value mimics the one used by the TBB task scheduler + void* seed = (char*)&curHits + i * 16; + tbb::internal::FastRandom random( seed ); + // According to Section 3.2.1.2 of Volume 2 of Knuth's Art of Computer Programming + // the following conditions must be hold for m=2^32: + ASSERT((random.c&1)!=0, "c is relatively prime to m"); + ASSERT((random.a-1)%4==0, "a-1 is a multiple of p, for every prime p dividing m." + " And a-1 is a multiple of 4, if m is a multiple of 4"); + + memset( curHits, 0, randomRange * sizeof(uintptr_t) ); +#if TEST_TOTAL_SEQUENCE + memset( totalHits, 0, randomRange * sizeof(uintptr_t) ); +#endif + const uintptr_t seriesLen = randomRange * SeriesBaseLen, + experimentLen = NumSeries * seriesLen; + uintptr_t *curSeries = new uintptr_t[seriesLen], // circular buffer + randsGenerated = 0; + // Initialize statistics + while ( randsGenerated < seriesLen ) { + uintptr_t idx = random.get() % randomRange; + ++curHits[idx]; +#if TEST_TOTAL_SEQUENCE + ++totalHits[idx]; +#endif + curSeries[randsGenerated++] = idx; + } + while ( randsGenerated < experimentLen ) { + for ( uintptr_t j = 0; j < randomRange; ++j ) { + CheckProbability( double(curHits[j])/seriesLen, expectedProbability, j, randomRange, seed ); +#if TEST_TOTAL_SEQUENCE + CheckProbability( double(totalHits[j])/randsGenerated, expectedProbability, j, randomRange, seed ); +#endif + } + --curHits[curSeries[randsGenerated % seriesLen]]; + int idx = random.get() % randomRange; + ++curHits[idx]; +#if TEST_TOTAL_SEQUENCE + ++totalHits[idx]; +#endif + curSeries[randsGenerated++ % seriesLen] = idx; + } + delete [] curSeries; + } + delete [] curHits; +#if TEST_TOTAL_SEQUENCE + delete [] totalHits; +#endif + } +}; + +struct rng { + tbb::internal::FastRandom my_fast_random; + rng (unsigned seed):my_fast_random(seed) {} + unsigned short operator()(){return my_fast_random.get();} +}; + +template <std::size_t seriesLen > +struct SingleCheck{ + bool operator()(unsigned seed)const{ + std::size_t series1[seriesLen]={0}; + std::size_t series2[seriesLen]={0}; + std::generate(series1,series1+seriesLen,rng(seed)); + std::generate(series2,series2+seriesLen,rng(seed)); + return std::equal(series1,series1+seriesLen,series2); + } +}; + +template <std::size_t seriesLen ,size_t seedsNum> +struct CheckReproducibilityBody:NoAssign{ + unsigned short seeds[seedsNum]; + const std::size_t grainSize; + CheckReproducibilityBody(std::size_t GrainSize): grainSize(GrainSize){ + //first generate seeds to check on, and make sure that sequence is reproducible + ASSERT(SingleCheck<seedsNum>()(0),"Series generated by FastRandom must be reproducible"); + std::generate(seeds,seeds+seedsNum,rng(0)); + } + + void operator()(int id)const{ + for (size_t i=id*grainSize; (i<seedsNum)&&(i< ((id+1)*grainSize));++i ){ + ASSERT(SingleCheck<seriesLen>()(i),"Series generated by FastRandom must be reproducible"); + } + } + +}; +#include "tbb/tbb_thread.h" + +int TestMain () { + ASSERT( AcceptableDeviation < 100, NULL ); + MinThread = max(MinThread, 2); + MaxThread = max(MinThread, MaxThread); + double NumChecks = double(NumSeeds) * (MaxThread - MinThread + 1) * (MaxThread + MinThread) / 2.0 * (SeriesBaseLen * NumSeries - SeriesBaseLen); + REMARK( "Number of distribution quality checks %g\n", NumChecks ); + NumLowOutliers = NumHighOutliers = 0; + // Parallelism is used in this test only to speed up the long serial checks + // Essentially it is a loop over random number ranges + // Ideally tbb::parallel_for could be used to parallelize the outermost loop + // in CheckDistributionBody, but it is not used to avoid unit test contamination. + int P = tbb::tbb_thread::hardware_concurrency(); + enum {reproducibilitySeedsToTest=1000}; + enum {reproducibilitySeriesLen=100}; + CheckReproducibilityBody<reproducibilitySeriesLen,reproducibilitySeedsToTest> CheckReproducibility(reproducibilitySeedsToTest/MaxThread); + while ( MinThread <= MaxThread ) { + int ThreadsToRun = min(P, MaxThread - MinThread + 1); + REMARK("Checking random range [%d;%d)\n", MinThread, MinThread+ThreadsToRun); + NativeParallelFor( ThreadsToRun, CheckDistributionBody() ); + NativeParallelFor( ThreadsToRun, CheckReproducibility ); + MinThread += P; + } + double observedProbabilityOfOutliers = (NumLowOutliers + NumHighOutliers) / NumChecks; + if ( observedProbabilityOfOutliers > AcceptableProbabilityOfOutliers ) { + if ( NumLowOutliers ) + REPORT( "Warning: %d cases of too low probability of a given number detected\n", (int)NumLowOutliers ); + if ( NumHighOutliers ) + REPORT( "Warning: %d cases of too high probability of a given number detected\n", (int)NumHighOutliers ); + ASSERT( observedProbabilityOfOutliers <= AcceptableProbabilityOfOutliers, NULL ); + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph.cpp new file mode 100644 index 00000000..08c7390d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph.cpp @@ -0,0 +1,386 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#include "harness_graph.h" +#include "harness_barrier.h" +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" + + +const int T = 4; +const int W = 4; + +struct decrement_wait : NoAssign { + + tbb::flow::graph * const my_graph; + bool * const my_done_flag; + + decrement_wait( tbb::flow::graph &h, bool *done_flag ) : my_graph(&h), my_done_flag(done_flag) {} + + void operator()(int i) const { + Harness::Sleep(10*i); + my_done_flag[i] = true; + my_graph->decrement_wait_count(); + } +}; + +static void test_wait_count() { + tbb::flow::graph h; + for (int i = 0; i < T; ++i ) { + bool done_flag[W]; + for (int j = 0; j < W; ++j ) { + for ( int w = 0; w < W; ++w ) done_flag[w] = false; + for ( int w = 0; w < j; ++w ) h.increment_wait_count(); + + NativeParallelFor( j, decrement_wait(h, done_flag) ); + h.wait_for_all(); + for ( int w = 0; w < W; ++w ) { + if ( w < j ) ASSERT( done_flag[w] == true, NULL ); + else ASSERT( done_flag[w] == false, NULL ); + } + } + } +} + +const int F = 100; + +#if __TBB_CPP11_LAMBDAS_PRESENT +bool lambda_flag[F]; +#endif +bool functor_flag[F]; + +struct set_functor { + int my_i; + set_functor( int i ) : my_i(i) {} + void operator()() { functor_flag[my_i] = true; } +}; + +struct return_functor { + int my_i; + return_functor( int i ) : my_i(i) {} + int operator()() { return my_i; } +}; + +static void test_run() { + tbb::flow::graph h; + for (int i = 0; i < T; ++i ) { + + // Create receivers and flag arrays + #if __TBB_CPP11_LAMBDAS_PRESENT + harness_mapped_receiver<int> lambda_r(h); + lambda_r.initialize_map( F, 1 ); + #endif + harness_mapped_receiver<int> functor_r(h); + functor_r.initialize_map( F, 1 ); + + // Initialize flag arrays + for (int j = 0; j < F; ++j ) { + #if __TBB_CPP11_LAMBDAS_PRESENT + lambda_flag[j] = false; + #endif + functor_flag[j] = false; + } + + for ( int j = 0; j < F; ++j ) { + #if __TBB_CPP11_LAMBDAS_PRESENT + h.run( [=]() { lambda_flag[j] = true; } ); + h.run( lambda_r, [=]() { return j; } ); + #endif + h.run( set_functor(j) ); + h.run( functor_r, return_functor(j) ); + } + h.wait_for_all(); + for ( int j = 0; j < F; ++j ) { + #if __TBB_CPP11_LAMBDAS_PRESENT + ASSERT( lambda_flag[i] == true, NULL ); + #endif + ASSERT( functor_flag[i] == true, NULL ); + } + #if __TBB_CPP11_LAMBDAS_PRESENT + lambda_r.validate(); + #endif + functor_r.validate(); + } +} + +// Encapsulate object we want to store in vector (because contained type must have +// copy constructor and assignment operator +class my_int_buffer { + tbb::flow::buffer_node<int> *b; + tbb::flow::graph& my_graph; +public: + my_int_buffer(tbb::flow::graph &g) : my_graph(g) { b = new tbb::flow::buffer_node<int>(my_graph); } + my_int_buffer(const my_int_buffer& other) : my_graph(other.my_graph) { + b = new tbb::flow::buffer_node<int>(my_graph); + } + ~my_int_buffer() { delete b; } + my_int_buffer& operator=(const my_int_buffer& /*other*/) { + return *this; + } +}; + +// test the graph iterator, delete nodes from graph, test again +void test_iterator() { + tbb::flow::graph g; + my_int_buffer a_buffer(g); + my_int_buffer b_buffer(g); + my_int_buffer c_buffer(g); + my_int_buffer *d_buffer = new my_int_buffer(g); + my_int_buffer e_buffer(g); + std::vector< my_int_buffer > my_buffer_vector(10, c_buffer); + + int count = 0; + for (tbb::flow::graph::iterator it = g.begin(); it != g.end(); ++it) { + count++; + } + ASSERT(count==15, "error in iterator count"); + + delete d_buffer; + + count = 0; + for (tbb::flow::graph::iterator it = g.begin(); it != g.end(); ++it) { + count++; + } + ASSERT(count==14, "error in iterator count"); + + my_buffer_vector.clear(); + + count = 0; + for (tbb::flow::graph::iterator it = g.begin(); it != g.end(); ++it) { + count++; + } + ASSERT(count==4, "error in iterator count"); +} + +class AddRemoveBody : NoAssign { + tbb::flow::graph& g; + int nThreads; + Harness::SpinBarrier &barrier; +public: + AddRemoveBody(int nthr, Harness::SpinBarrier &barrier_, tbb::flow::graph& _g) : + g(_g), nThreads(nthr), barrier(barrier_) + {} + void operator()(const int /*threadID*/) const { + my_int_buffer b(g); + { + std::vector<my_int_buffer> my_buffer_vector(100, b); + barrier.wait(); // wait until all nodes are created + // now test that the proper number of nodes were created + int count = 0; + for (tbb::flow::graph::iterator it = g.begin(); it != g.end(); ++it) { + count++; + } + ASSERT(count==101*nThreads, "error in iterator count"); + barrier.wait(); // wait until all threads are done counting + } // all nodes but for the initial node on this thread are deleted + barrier.wait(); // wait until all threads have deleted all nodes in their vectors + // now test that all the nodes were deleted except for the initial node + int count = 0; + for (tbb::flow::graph::iterator it = g.begin(); it != g.end(); ++it) { + count++; + } + ASSERT(count==nThreads, "error in iterator count"); + barrier.wait(); // wait until all threads are done counting + } // initial node gets deleted +}; + +void test_parallel(int nThreads) { + tbb::flow::graph g; + Harness::SpinBarrier barrier(nThreads); + AddRemoveBody body(nThreads, barrier, g); + NativeParallelFor(nThreads, body); +} + +/* + * Functors for graph arena spawn tests + */ + +inline void check_arena(tbb::task_arena* a) { + ASSERT(a->max_concurrency() == 2, NULL); + ASSERT(tbb::this_task_arena::max_concurrency() == 1, NULL); +} + +struct run_functor { + tbb::task_arena* my_a; + int return_value; + run_functor(tbb::task_arena* a) : my_a(a), return_value(1) {} + int operator()() { + check_arena(my_a); + return return_value; + } +}; + +template < typename T > +struct function_body { + tbb::task_arena* my_a; + function_body(tbb::task_arena* a) : my_a(a) {} + tbb::flow::continue_msg operator()(const T& /*arg*/) { + check_arena(my_a); + return tbb::flow::continue_msg(); + } +}; + +typedef tbb::flow::multifunction_node< int, tbb::flow::tuple< int > > mf_node; + +struct multifunction_body { + tbb::task_arena* my_a; + multifunction_body(tbb::task_arena* a) : my_a(a) {} + void operator()(const int& /*arg*/, mf_node::output_ports_type& /*outports*/) { + check_arena(my_a); + } +}; + +struct source_body { + tbb::task_arena* my_a; + int counter; + source_body(tbb::task_arena* a) : my_a(a), counter(0) {} + +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(const int& /*i*/) { + check_arena(my_a); + if (counter < 1) { + ++counter; + return true; + } + return false; + } +#else + int operator()(tbb::flow_control &fc) { + check_arena(my_a); + if (counter++ >= 1) { + fc.stop(); + } + return int(); + } +#endif +}; + +struct run_test_functor : tbb::internal::no_assign { + tbb::task_arena* fg_arena; + tbb::flow::graph& my_graph; + + run_test_functor(tbb::task_arena* a, tbb::flow::graph& g) : fg_arena(a), my_graph(g) {} + void operator()() const { + harness_mapped_receiver<int> functor_r(my_graph); + functor_r.initialize_map(F, 1); + + my_graph.run(run_functor(fg_arena)); + my_graph.run(functor_r, run_functor(fg_arena)); + + my_graph.wait_for_all(); + } +}; + +struct nodes_test_functor : tbb::internal::no_assign { + tbb::task_arena* fg_arena; + tbb::flow::graph& my_graph; + + nodes_test_functor(tbb::task_arena* a, tbb::flow::graph& g) : fg_arena(a), my_graph(g) {} + void operator()() const { + + // Define test nodes + // Continue, function, source nodes + tbb::flow::continue_node< tbb::flow::continue_msg > c_n(my_graph, function_body<tbb::flow::continue_msg>(fg_arena)); + tbb::flow::function_node< int > f_n(my_graph, tbb::flow::unlimited, function_body<int>(fg_arena)); + tbb::flow::input_node< int > s_n(my_graph, source_body(fg_arena)); + + // Multifunction node + mf_node m_n(my_graph, tbb::flow::unlimited, multifunction_body(fg_arena)); + + // Join node + tbb::flow::function_node< tbb::flow::tuple< int, int > > join_f_n(my_graph, tbb::flow::unlimited, function_body< tbb::flow::tuple< int, int > >(fg_arena)); + tbb::flow::join_node< tbb::flow::tuple< int, int > > j_n(my_graph); + make_edge(j_n, join_f_n); + + // Split node + tbb::flow::function_node< int > split_f_n1 = f_n; + tbb::flow::function_node< int > split_f_n2 = f_n; + tbb::flow::split_node< tbb::flow::tuple< int, int > > sp_n(my_graph); + make_edge(tbb::flow::output_port<0>(sp_n), split_f_n1); + make_edge(tbb::flow::output_port<1>(sp_n), split_f_n2); + + // Overwrite node + tbb::flow::function_node< int > ow_f_n = f_n; + tbb::flow::overwrite_node< int > ow_n(my_graph); + make_edge(ow_n, ow_f_n); + + // Write once node + tbb::flow::function_node< int > w_f_n = f_n; + tbb::flow::write_once_node< int > w_n(my_graph); + make_edge(w_n, w_f_n); + + // Buffer node + tbb::flow::function_node< int > buf_f_n = f_n; + tbb::flow::buffer_node< int > buf_n(my_graph); + make_edge(w_n, buf_f_n); + + // Limiter node + tbb::flow::function_node< int > l_f_n = f_n; + tbb::flow::limiter_node< int > l_n(my_graph, 1); + make_edge(l_n, l_f_n); + + // Execute nodes + c_n.try_put( tbb::flow::continue_msg() ); + f_n.try_put(1); + m_n.try_put(1); + s_n.activate(); + + tbb::flow::input_port<0>(j_n).try_put(1); + tbb::flow::input_port<1>(j_n).try_put(1); + + tbb::flow::tuple< int, int > sp_tuple(1, 1); + sp_n.try_put(sp_tuple); + + ow_n.try_put(1); + w_n.try_put(1); + buf_n.try_put(1); + l_n.try_put(1); + + my_graph.wait_for_all(); + } +}; + +void test_graph_arena() { + // There is only one thread for execution (master thread). + // So, if graph's tasks get spawned in different arena + // master thread won't be able to find them in its own arena. + // In this case test should hang. + tbb::task_scheduler_init init(1); + + tbb::flow::graph g; + tbb::task_arena fg_arena; + fg_arena.initialize(2); + fg_arena.execute(run_test_functor(&fg_arena, g)); + fg_arena.execute(nodes_test_functor(&fg_arena, g)); +} + +int TestMain() { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + test_wait_count(); + test_run(); + test_iterator(); + test_parallel(p); + } + test_graph_arena(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph_priorities.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph_priorities.cpp new file mode 100644 index 00000000..9c0c8735 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph_priorities.cpp @@ -0,0 +1,611 @@ +/* + Copyright (c) 2018-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_defs.h" + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#include "harness_graph.h" +#include "harness_barrier.h" + +#include "tbb/flow_graph.h" +#include "tbb/tbb_thread.h" +#include "tbb/parallel_for.h" +#include "tbb/concurrent_queue.h" + +#include <vector> +#include <cstdlib> + +using namespace tbb::flow; + +tbb::atomic<unsigned> g_task_num; + +void spin_for( double delta ) { + tbb::tick_count start = tbb::tick_count::now(); + while( (tbb::tick_count::now() - start).seconds() < delta ) ; +} + +namespace PriorityNodesTakePrecedence { + +struct TaskInfo { + TaskInfo() : my_priority(-1), my_task_index(-1) {} + TaskInfo( int priority, int task_index ) + : my_priority(priority), my_task_index(task_index) {} + int my_priority; + int my_task_index; +}; +std::vector<TaskInfo> g_task_info; +tbb::atomic<bool> g_work_submitted; + +const unsigned node_num = 100; +const unsigned start_index = node_num / 3; +const unsigned end_index = node_num * 2 / 3; +tbb::atomic<unsigned> g_priority_task_index; + +void body_func( int priority ) { + while( !g_work_submitted ) __TBB_Yield(); + int current_task_index = g_task_num++; + if( priority ) + g_task_info[g_priority_task_index++] = TaskInfo( priority, current_task_index ); +} + +struct FunctionBody { + FunctionBody( int priority ) : my_priority( priority ) {} + int operator()( int msg ) const { + body_func( my_priority ); + return msg; + } +private: + int my_priority; +}; + +typedef multifunction_node< int,tuple<int> > multi_node; + +struct MultifunctionBody { + MultifunctionBody( int priority ) : my_priority( priority ) {} + void operator()( int msg, multi_node::output_ports_type& op ) const { + body_func( my_priority ); + get<0>(op).try_put( msg ); + } +private: + int my_priority; +}; + +template<typename NodeType, typename BodyType> +NodeType* node_creator( graph& g, unsigned index ) { + if( start_index <= index && index < end_index ) + return new NodeType( g, unlimited, BodyType(index), node_priority_t(index) ); + else + return new NodeType( g, unlimited, BodyType(0) ); +} + +struct passthru_body { + continue_msg operator()( int ) const { + return continue_msg(); + } +}; + +template<typename NodeType> sender<int>& get_sender( NodeType& node ) { return node; } +template<> sender<int>& get_sender<multi_node>( multi_node& node ) { return output_port<0>(node); } + +template<typename NodeType, typename NodeTypeCreator, typename NodePortRetriever> +void test_node( NodeTypeCreator node_creator_func, NodePortRetriever get_sender ) { + graph g; + broadcast_node<int> bn(g); + function_node<int> tn(g, unlimited, passthru_body()); + // Using pointers to nodes to avoid errors on compilers, which try to generate assignment + // operator for the nodes + std::vector<NodeType*> nodes; + for( unsigned i = 0; i < node_num; ++i ) { + nodes.push_back( node_creator_func(g, i) ); + make_edge( bn, *nodes.back() ); + make_edge( get_sender(*nodes.back()), tn ); + } + + const size_t repeats = 50; + const size_t priority_nodes_num = end_index - start_index; + size_t internal_order_failures = 0; + size_t global_order_failures = 0; + for( size_t repeat = 0; repeat < repeats; ++repeat ) { + g_work_submitted = false; + g_task_num = g_priority_task_index = 0; + g_task_info.clear(); g_task_info.resize( priority_nodes_num ); + + bn.try_put( 0 ); + // Setting of the flag is based on the knowledge that the calling thread broadcasts the message + // to successor nodes, that is spawns tasks. Thus, this makes this test to be a whitebox test to + // some extent. + g_work_submitted = true; + + g.wait_for_all(); + + ASSERT( g_priority_task_index == g_task_info.size(), "Incorrect number of tasks with priority" ); + bool found_max = false; + bool found_min = false; + for( unsigned i = 0; i < g_priority_task_index/2; ++i ) { + if( g_task_info[i].my_priority == int(end_index-1) ) + found_max = true; + if( g_task_info[g_priority_task_index-1-i].my_priority == int(start_index) ) + found_min = true; + } + if( !found_min || !found_max ) + ++internal_order_failures; + for( unsigned i = 0; i < g_priority_task_index; ++i ) { + // This check might fail because priorities do not guarantee ordering, i.e. assumption + // that all priority nodes should increment the task counter before any subsequent + // no-priority node is not correct. In the worst case, a thread that took a priority + // node might be preempted and become the last to increment the counter. That's why the + // test passing is based on statistics, which could be affected by machine overload + // unfortunately. + // TODO: make the test deterministic. + if( g_task_info[i].my_task_index > int(priority_nodes_num) + MaxThread ) + ++global_order_failures; + } + } + float failure_ratio = float(internal_order_failures) / float(repeats); + ASSERT( + failure_ratio <= 0.3f, + "Nodes with priorities executed in wrong order among each other too frequently." + ); + failure_ratio = float(global_order_failures) / float(repeats*priority_nodes_num); + ASSERT( + failure_ratio <= 0.1f, + "Nodes with priorities executed in wrong order too frequently over non-prioritized nodes." + ); + for( size_t i = 0; i < nodes.size(); ++i ) + delete nodes[i]; +} + +void test( int num_threads ) { + REMARK( "Testing execution of nodes with priority takes precedence (num_threads=%d) - ", num_threads ); + tbb::task_scheduler_init init(num_threads); + test_node< function_node<int,int> >( &node_creator<function_node<int,int>, FunctionBody>, + &get_sender< function_node<int,int> > ); + test_node<multi_node>( &node_creator<multi_node, MultifunctionBody>, &get_sender< multi_node > ); + REMARK( "done\n" ); +} +} /* namespace PriorityNodesTakePrecedence */ + +namespace ThreadsEagerReaction { + +using Harness::SpinBarrier; + +enum task_type_t { no_task, regular_task, async_task }; + +struct profile_t { + task_type_t task_type; + unsigned global_task_id; + double elapsed; +}; + +std::vector<unsigned> g_async_task_ids; + +typedef unsigned data_type; +typedef async_node<data_type, data_type> async_node_type; +typedef multifunction_node< + data_type, tuple<data_type, data_type> > decider_node_type; +struct AsyncActivity { + typedef async_node_type::gateway_type gateway_type; + + struct work_type { data_type input; gateway_type* gateway; }; + bool done; + tbb::concurrent_queue<work_type> my_queue; + tbb::tbb_thread my_service_thread; + + struct ServiceThreadFunc { + SpinBarrier& my_barrier; + ServiceThreadFunc(SpinBarrier& barrier) : my_barrier(barrier) {} + void operator()(AsyncActivity* activity) { + while (!activity->done) { + work_type work; + while (activity->my_queue.try_pop(work)) { + g_async_task_ids.push_back( ++g_task_num ); + work.gateway->try_put(work.input); + work.gateway->release_wait(); + my_barrier.wait(); + } + } + } + }; + void stop_and_wait() { done = true; my_service_thread.join(); } + + void submit(data_type input, gateway_type* gateway) { + work_type work = { input, gateway }; + gateway->reserve_wait(); + my_queue.push(work); + } + AsyncActivity(SpinBarrier& barrier) + : done(false), my_service_thread(ServiceThreadFunc(barrier), this) {} +}; + +struct StartBody { + bool has_run; +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(data_type& input) { + if (has_run) return false; + else { + input = 1; + has_run = true; + return true; + } + } +#else + data_type operator()(tbb::flow_control& fc) { + if (has_run){ + fc.stop(); + return data_type(); + } + has_run = true; + return 1; + } +#endif + StartBody() : has_run(false) {} +}; + +struct ParallelForBody { + SpinBarrier& my_barrier; + const data_type& my_input; + ParallelForBody(SpinBarrier& barrier, const data_type& input) + : my_barrier(barrier), my_input(input) {} + void operator()(const data_type&) const { + my_barrier.wait(); + ++g_task_num; + } +}; + +struct CpuWorkBody { + SpinBarrier& my_barrier; + const int my_tasks_count; + data_type operator()(const data_type& input) { + tbb::parallel_for(0, my_tasks_count, ParallelForBody(my_barrier, input), tbb::simple_partitioner()); + return input; + } + CpuWorkBody(SpinBarrier& barrier, int tasks_count) + : my_barrier(barrier), my_tasks_count(tasks_count) {} +}; + +struct DeciderBody { + const data_type& my_limit; + DeciderBody( const data_type& limit ) : my_limit( limit ) {} + void operator()(data_type input, decider_node_type::output_ports_type& ports) { + if (input < my_limit) + get<0>(ports).try_put(input + 1); + } +}; + +struct AsyncSubmissionBody { + AsyncActivity* my_activity; + void operator()(data_type input, async_node_type::gateway_type& gateway) { + my_activity->submit(input, &gateway); + } + AsyncSubmissionBody(AsyncActivity* activity) : my_activity(activity) {} +}; + +void test( int num_threads ) { + REMARK( "Testing threads react eagerly on asynchronous tasks (num_threads=%d) - ", num_threads ); + if( num_threads == tbb::task_scheduler_init::default_num_threads() ) { + // one thread is required for asynchronous compute resource + REMARK("skipping test since it is designed to work on less number of threads than " + "hardware concurrency allows\n"); + return; + } + const unsigned cpu_threads = unsigned(num_threads); + const unsigned cpu_tasks_per_thread = 4; + const unsigned nested_cpu_tasks = cpu_tasks_per_thread * cpu_threads; + const unsigned async_subgraph_reruns = 8; + const unsigned cpu_subgraph_reruns = 2; + + SpinBarrier barrier(cpu_threads + /*async thread=*/1); + g_task_num = 0; + g_async_task_ids.clear(); + g_async_task_ids.reserve(async_subgraph_reruns); + + tbb::task_scheduler_init init(cpu_threads); + AsyncActivity activity(barrier); + graph g; + + input_node<data_type> starter_node(g, StartBody()); + function_node<data_type, data_type> cpu_work_node( + g, unlimited, CpuWorkBody(barrier, nested_cpu_tasks)); + decider_node_type cpu_restarter_node(g, unlimited, DeciderBody(cpu_subgraph_reruns)); + async_node_type async_node(g, unlimited, AsyncSubmissionBody(&activity)); + decider_node_type async_restarter_node( + g, unlimited, DeciderBody(async_subgraph_reruns), node_priority_t(1) + ); + + make_edge(starter_node, cpu_work_node); + make_edge(cpu_work_node, cpu_restarter_node); + make_edge(output_port<0>(cpu_restarter_node), cpu_work_node); + + make_edge(starter_node, async_node); + make_edge(async_node, async_restarter_node); + make_edge(output_port<0>(async_restarter_node), async_node); + + starter_node.activate(); + g.wait_for_all(); + activity.stop_and_wait(); + + const size_t async_task_num = size_t(async_subgraph_reruns); + ASSERT( g_async_task_ids.size() == async_task_num, "Incorrect number of async tasks." ); + unsigned max_span = unsigned(2 * cpu_threads + 1); + for( size_t idx = 1; idx < async_task_num; ++idx ) { + ASSERT( g_async_task_ids[idx] - g_async_task_ids[idx-1] <= max_span, + "Async tasks were not able to interfere with CPU tasks." ); + } + REMARK("done\n"); +} +} /* ThreadsEagerReaction */ + +namespace LimitingExecutionToPriorityTask { + +enum work_type_t { NONPRIORITIZED_WORK, PRIORITIZED_WORK }; + +struct execution_tracker_t { + execution_tracker_t() { reset(); } + void reset() { + prioritized_work_submitter = tbb::tbb_thread::id(); + prioritized_work_started = false; + prioritized_work_finished = false; + prioritized_work_interrupted = false; + } + tbb::tbb_thread::id prioritized_work_submitter; + bool prioritized_work_started; + bool prioritized_work_finished; + bool prioritized_work_interrupted; +} exec_tracker; + +template<work_type_t work_type> +void do_node_work( int work_size ); + +template<work_type_t> +void do_nested_work( const tbb::tbb_thread::id& tid, const tbb::blocked_range<int>& subrange ); + +template<work_type_t work_type> +struct CommonBody { + CommonBody() : my_body_size( 0 ) { } + CommonBody( int body_size ) : my_body_size( body_size ) { } + continue_msg operator()( const continue_msg& msg ) const { + do_node_work<work_type>(my_body_size); + return msg; + } + void operator()( const tbb::blocked_range<int>& subrange ) const { + do_nested_work<work_type>( /*tid=*/tbb::this_tbb_thread::get_id(), subrange ); + } + int my_body_size; +}; + +template<work_type_t work_type> +void do_node_work(int work_size) { + tbb::parallel_for( tbb::blocked_range<int>(0, work_size), CommonBody<work_type>(), + tbb::simple_partitioner() ); +} + +template<work_type_t> +void do_nested_work( const tbb::tbb_thread::id& tid, const tbb::blocked_range<int>& /*subrange*/ ) { + // This is non-prioritized work... + if( exec_tracker.prioritized_work_submitter != tid ) + return; + // ...being executed by the thread that initially started prioritized one... + ASSERT( exec_tracker.prioritized_work_started, + "Prioritized work should have been started by that time." ); + // ...prioritized work has been started already... + if( exec_tracker.prioritized_work_finished ) + return; + // ...but has not been finished yet + exec_tracker.prioritized_work_interrupted = true; +} + +struct IsolationFunctor { + int work_size; + IsolationFunctor(int ws) : work_size(ws) {} + void operator()() const { + tbb::parallel_for( tbb::blocked_range<int>(0, work_size), CommonBody<PRIORITIZED_WORK>(), + tbb::simple_partitioner() ); + } +}; + +template<> +void do_node_work<PRIORITIZED_WORK>(int work_size) { + exec_tracker.prioritized_work_submitter = tbb::this_tbb_thread::get_id(); + exec_tracker.prioritized_work_started = true; + tbb::this_task_arena::isolate( IsolationFunctor(work_size) ); + exec_tracker.prioritized_work_finished = true; +} + +template<> +void do_nested_work<PRIORITIZED_WORK>( const tbb::tbb_thread::id& tid, + const tbb::blocked_range<int>& /*subrange*/ ) { + if( exec_tracker.prioritized_work_submitter == tid ) { + ASSERT( !exec_tracker.prioritized_work_interrupted, + "Thread was not fully devoted to processing of prioritized task." ); + } else { + // prolong processing of prioritized work so that the thread that started + // prioritized work has higher probability to help with non-prioritized one. + spin_for(0.1); + } +} + +// Using pointers to nodes to avoid errors on compilers, which try to generate assignment operator +// for the nodes +typedef std::vector< continue_node<continue_msg>* > nodes_container_t; + +void create_nodes( nodes_container_t& nodes, graph& g, int num, int body_size ) { + for( int i = 0; i < num; ++i ) + nodes.push_back( + new continue_node<continue_msg>( g, CommonBody<NONPRIORITIZED_WORK>( body_size ) ) + ); +} + +void test( int num_threads ) { + REMARK( "Testing limit execution to priority tasks (num_threads=%d) - ", num_threads ); + + tbb::task_scheduler_init init( num_threads ); + + const int nodes_num = 100; + const int priority_node_position_part = 10; + const int pivot = nodes_num / priority_node_position_part; + const int nodes_in_lane = 3 * num_threads; + const int small_problem_size = 100; + const int large_problem_size = 1000; + + graph g; + nodes_container_t nodes; + create_nodes( nodes, g, pivot, large_problem_size ); + nodes.push_back( + new continue_node<continue_msg>( + g, CommonBody<PRIORITIZED_WORK>(small_problem_size), node_priority_t(1) + ) + ); + create_nodes( nodes, g, nodes_num - pivot - 1, large_problem_size ); + + broadcast_node<continue_msg> bn(g); + for( int i = 0; i < nodes_num; ++i ) + if( i % nodes_in_lane == 0 ) + make_edge( bn, *nodes[i] ); + else + make_edge( *nodes[i-1], *nodes[i] ); + exec_tracker.reset(); + bn.try_put( continue_msg() ); + g.wait_for_all(); + + for( size_t i = 0; i < nodes.size(); ++i ) + delete nodes[i]; + REMARK( "done\n" ); +} + +} /* namespace LimitingExecutionToPriorityTask */ + +#include "tbb/task_arena.h" +namespace NestedCase { + +using tbb::task_arena; + +struct ResetGraphFunctor { + graph& my_graph; + ResetGraphFunctor(graph& g) : my_graph(g) {} + // copy constructor to please some old compilers + ResetGraphFunctor(const ResetGraphFunctor& rgf) : my_graph(rgf.my_graph) {} + void operator()() const { my_graph.reset(); } +}; + +struct InnerBody { + continue_msg operator()( const continue_msg& ) const { + return continue_msg(); + } +}; + +struct OuterBody { + int my_max_threads; + task_arena& my_inner_arena; + OuterBody( int max_threads, task_arena& inner_arena ) + : my_max_threads(max_threads), my_inner_arena(inner_arena) {} + // copy constructor to please some old compilers + OuterBody( const OuterBody& rhs ) + : my_max_threads(rhs.my_max_threads), my_inner_arena(rhs.my_inner_arena) {} + int operator()( const int& ) { + graph inner_graph; + continue_node<continue_msg> start_node(inner_graph, InnerBody()); + continue_node<continue_msg> mid_node1(inner_graph, InnerBody(), node_priority_t(5)); + continue_node<continue_msg> mid_node2(inner_graph, InnerBody()); + continue_node<continue_msg> end_node(inner_graph, InnerBody(), node_priority_t(15)); + make_edge( start_node, mid_node1 ); + make_edge( mid_node1, end_node ); + make_edge( start_node, mid_node2 ); + make_edge( mid_node2, end_node ); + my_inner_arena.execute( ResetGraphFunctor(inner_graph) ); + start_node.try_put( continue_msg() ); + inner_graph.wait_for_all(); + return 13; + } +}; + +void execute_outer_graph( bool same_arena, task_arena& inner_arena, int max_threads, + graph& outer_graph, function_node<int,int>& start_node ) { + if( same_arena ) { + start_node.try_put( 42 ); + outer_graph.wait_for_all(); + return; + } + for( int num_threads = 1; num_threads <= max_threads; ++num_threads ) { + inner_arena.initialize( num_threads ); + start_node.try_put( 42 ); + outer_graph.wait_for_all(); + inner_arena.terminate(); + } +} + +void test_in_arena( int max_threads, task_arena& outer_arena, task_arena& inner_arena ) { + graph outer_graph; + const unsigned num_outer_nodes = 10; + const size_t concurrency = unlimited; + std::vector< function_node<int,int>* > outer_nodes; + for( unsigned node_index = 0; node_index < num_outer_nodes; ++node_index ) { + internal::node_priority_t priority = internal::no_priority; + if( node_index == num_outer_nodes / 2 ) + priority = 10; + + outer_nodes.push_back( + new function_node<int,int>( + outer_graph, concurrency, OuterBody(max_threads, inner_arena), priority + ) + ); + } + + for( unsigned node_index1 = 0; node_index1 < num_outer_nodes; ++node_index1 ) + for( unsigned node_index2 = node_index1+1; node_index2 < num_outer_nodes; ++node_index2 ) + make_edge( *outer_nodes[node_index1], *outer_nodes[node_index2] ); + + bool same_arena = &outer_arena == &inner_arena; + for( int num_threads = 1; num_threads <= max_threads; ++num_threads ) { + REMARK( "Testing nested nodes with specified priority in %s arenas, num_threads=%d) - ", + same_arena? "same" : "different", num_threads ); + outer_arena.initialize( num_threads ); + outer_arena.execute( ResetGraphFunctor(outer_graph) ); + execute_outer_graph( same_arena, inner_arena, max_threads, outer_graph, *outer_nodes[0] ); + outer_arena.terminate(); + REMARK( "done\n" ); + } + + for( size_t i = 0; i < outer_nodes.size(); ++i ) + delete outer_nodes[i]; +} + +void test( int max_threads ) { + tbb::task_scheduler_init init( max_threads ); + task_arena outer_arena; task_arena inner_arena; + test_in_arena( max_threads, outer_arena, outer_arena ); + test_in_arena( max_threads, outer_arena, inner_arena ); +} +} + +int TestMain() { + if( MinThread < 1 ) { + REPORT( "Number of threads must be positive\n" ); + return Harness::Skipped; + } + for( int p = MinThread; p <= MaxThread; ++p ) { + PriorityNodesTakePrecedence::test( p ); + ThreadsEagerReaction::test( p ); + LimitingExecutionToPriorityTask::test( p ); + } + NestedCase::test( MaxThread ); + return Harness::Done; +} +#else /* __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES */ +#define HARNESS_SKIP_TEST 1 +#include "harness.h" +#endif /* __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph_whitebox.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph_whitebox.cpp new file mode 100644 index 00000000..e63916dc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_flow_graph_whitebox.cpp @@ -0,0 +1,719 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 3 +#define HARNESS_DEFAULT_MAX_THREADS 4 + +#if _MSC_VER + #pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning + #if _MSC_VER==1700 && !defined(__INTEL_COMPILER) + // Suppress "unreachable code" warning by VC++ 17.0 (VS 2012) + #pragma warning (disable: 4702) + #endif +#endif + +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#include "harness.h" +#include <string> // merely prevents LNK2001 error to happen (on ICL+VC9 configurations) + +// need these to get proper external names for private methods in library. +#include "tbb/spin_mutex.h" +#include "tbb/spin_rw_mutex.h" +#include "tbb/task.h" +#include "tbb/task_arena.h" + +#define private public +#define protected public +#include "tbb/flow_graph.h" +#undef protected +#undef private +#include "tbb/task_scheduler_init.h" +#include "harness_graph.h" + +template<typename T> +struct receiverBody { + tbb::flow::continue_msg operator()(const T &/*in*/) { + return tbb::flow::continue_msg(); + } +}; + +// split_nodes cannot have predecessors +// they do not reject messages and always forward. +// they reject edge reversals from successors. +void TestSplitNode() { + typedef tbb::flow::split_node<tbb::flow::tuple<int> > snode_type; + tbb::flow::graph g; + snode_type snode(g); + tbb::flow::function_node<int> rcvr(g,tbb::flow::unlimited, receiverBody<int>()); + REMARK("Testing split_node\n"); + ASSERT(tbb::flow::output_port<0>(snode).my_successors.empty(), "Constructed split_node has successors"); + // tbb::flow::output_port<0>(snode) + tbb::flow::make_edge(tbb::flow::output_port<0>(snode), rcvr); + ASSERT(!(tbb::flow::output_port<0>(snode).my_successors.empty()), "after make_edge, split_node has no successor."); + snode.try_put(tbb::flow::tuple<int>(1)); + g.wait_for_all(); + g.reset(); + ASSERT(!(tbb::flow::output_port<0>(snode).my_successors.empty()), "after reset(), split_node has no successor."); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(tbb::flow::output_port<0>(snode).my_successors.empty(), "after reset(rf_clear_edges), split_node has a successor."); +} + +// buffering nodes cannot have predecessors +// they do not reject messages and always save or forward +// they allow edge reversals from successors +template< typename B > +void TestBufferingNode(const char * name) { + tbb::flow::graph g; + B bnode(g); + tbb::flow::function_node<int,int,tbb::flow::rejecting> fnode(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0)); + REMARK("Testing %s:", name); + for(int icnt = 0; icnt < 2; icnt++) { + bool reverse_edge = (icnt & 0x2) != 0; + serial_fn_state0 = 0; // reset to waiting state. + REMARK(" make_edge"); + tbb::flow::make_edge(bnode, fnode); + ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after make_edge"); + REMARK(" try_put"); + bnode.try_put(1); // will forward to the fnode + BACKOFF_WAIT(serial_fn_state0 == 0, "Timed out waiting for first put"); + if(reverse_edge) { + REMARK(" try_put2"); + bnode.try_put(2); // will reverse the edge + // cannot do a wait_for_all here; the function_node is still executing + BACKOFF_WAIT(!bnode.my_successors.empty(), "Timed out waiting after 2nd put"); + // at this point the only task running is the one for the function_node. + ASSERT(bnode.my_successors.empty(), "successor not removed"); + } + else { + ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after forwarding message"); + } + serial_fn_state0 = 0; // release the function_node. + if(reverse_edge) { + // have to do a second release because the function_node will get the 2nd item + BACKOFF_WAIT( serial_fn_state0 == 0, "Timed out waiting after 2nd put"); + serial_fn_state0 = 0; // release the function_node. + } + g.wait_for_all(); + REMARK(" remove_edge"); + tbb::flow::remove_edge(bnode, fnode); + ASSERT(bnode.my_successors.empty(), "buffering node has a successor after remove_edge"); + } + tbb::flow::join_node<tbb::flow::tuple<int,int>,tbb::flow::reserving> jnode(g); + tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode)); // will spawn a task + g.wait_for_all(); + ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after attaching to join"); + REMARK(" reverse"); + bnode.try_put(1); // the edge should reverse + g.wait_for_all(); + ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving"); + REMARK(" reset()"); + g.wait_for_all(); + g.reset(); // should be in forward direction again + ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after reset()"); + REMARK(" remove_edge"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reset(rf_clear_edges)"); + tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode)); // add edge again + // reverse edge by adding to buffer. + bnode.try_put(1); // the edge should reverse + g.wait_for_all(); + ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving"); + REMARK(" remove_edge(reversed)"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(bnode.my_successors.empty(), "buffering node has no successor after reset()"); + ASSERT(tbb::flow::input_port<0>(jnode).my_predecessors.empty(), "predecessor not reset"); + REMARK(" done\n"); + g.wait_for_all(); +} + +// continue_node has only predecessor count +// they do not have predecessors, only the counts +// successor edges cannot be reversed +void TestContinueNode() { + tbb::flow::graph g; + tbb::flow::function_node<int> fnode0(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0)); + tbb::flow::continue_node<int> cnode(g, 1, serial_continue_body<int>(serial_continue_state0)); + tbb::flow::function_node<int> fnode1(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state1)); + tbb::flow::make_edge(fnode0, cnode); + tbb::flow::make_edge(cnode, fnode1); + REMARK("Testing continue_node:"); + for( int icnt = 0; icnt < 2; ++icnt ) { + REMARK( " initial%d", icnt); + ASSERT(cnode.my_predecessor_count == 2, "predecessor addition didn't increment count"); + ASSERT(!cnode.successors().empty(), "successors empty though we added one"); + ASSERT(cnode.my_current_count == 0, "state of continue_receiver incorrect"); + serial_continue_state0 = 0; + serial_fn_state0 = 0; + serial_fn_state1 = 0; + + fnode0.try_put(1); // start the first function node. + BACKOFF_WAIT(!serial_fn_state0, "Timed out waiting for function_node to start"); + // Now the body of function_node 0 is executing. + serial_fn_state0 = 0; // release the node + // wait for node to count the message (or for the node body to execute, which would be wrong) + BACKOFF_WAIT(serial_continue_state0 == 0 && cnode.my_current_count == 0, "Timed out waiting for continue_state0 to change"); + ASSERT(serial_continue_state0 == 0, "Improperly released continue_node"); + ASSERT(cnode.my_current_count == 1, "state of continue_receiver incorrect"); + if(icnt == 0) { // first time through, let the continue_node fire + REMARK(" firing"); + fnode0.try_put(1); // second message + BACKOFF_WAIT(serial_fn_state0 == 0, "timeout waiting for continue_body to execute"); + // Now the body of function_node 0 is executing. + serial_fn_state0 = 0; // release the node + + BACKOFF_WAIT(!serial_continue_state0,"continue_node didn't start"); // now we wait for the continue_node. + ASSERT(cnode.my_current_count == 0, " my_current_count not reset before body of continue_node started"); + serial_continue_state0 = 0; // release the continue_node + BACKOFF_WAIT(!serial_fn_state1,"successor function_node didn't start"); // wait for the successor function_node to enter body + serial_fn_state1 = 0; // release successor function_node. + g.wait_for_all(); + + // try a try_get() + { + int i; + ASSERT(!cnode.try_get(i), "try_get not rejected"); + } + + REMARK(" reset"); + ASSERT(!cnode.my_successors.empty(), "Empty successors in built graph (before reset)"); + ASSERT(cnode.my_predecessor_count == 2, "predecessor_count reset (before reset)"); + g.reset(); // should still be the same + ASSERT(!cnode.my_successors.empty(), "Empty successors in built graph (after reset)" ); + ASSERT(cnode.my_predecessor_count == 2, "predecessor_count reset (after reset)"); + } + else { // we're going to see if the rf_clear_edges resets things. + g.wait_for_all(); + REMARK(" reset(rf_clear_edges)"); + ASSERT(!cnode.my_successors.empty(), "Empty successors in built graph (before reset)"); + ASSERT(cnode.my_predecessor_count == 2, "predecessor_count reset (before reset)"); + g.reset(tbb::flow::rf_clear_edges); // should be in forward direction again + ASSERT(cnode.my_current_count == 0, "state of continue_receiver incorrect after reset(rf_clear_edges)"); + ASSERT(cnode.my_successors.empty(), "buffering node has a successor after reset(rf_clear_edges)"); + ASSERT(cnode.my_predecessor_count == cnode.my_initial_predecessor_count, "predecessor count not reset"); + } + } + + REMARK(" done\n"); + +} + +// function_node has predecessors and successors +// try_get() rejects +// successor edges cannot be reversed +// predecessors will reverse (only rejecting will reverse) +void TestFunctionNode() { + tbb::flow::graph g; + tbb::flow::queue_node<int> qnode0(g); + tbb::flow::function_node<int,int, tbb::flow::rejecting > fnode0(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0)); + // queueing function node + tbb::flow::function_node<int,int> fnode1(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0)); + + tbb::flow::queue_node<int> qnode1(g); + + tbb::flow::make_edge(fnode0, qnode1); + tbb::flow::make_edge(qnode0, fnode0); + + serial_fn_state0 = 2; // just let it go + // see if the darned thing will work.... + qnode0.try_put(1); + g.wait_for_all(); + int ii; + ASSERT(qnode1.try_get(ii) && ii == 1, "output not passed"); + tbb::flow::remove_edge(qnode0, fnode0); + tbb::flow::remove_edge(fnode0, qnode1); + + tbb::flow::make_edge(fnode1, qnode1); + tbb::flow::make_edge(qnode0, fnode1); + + serial_fn_state0 = 2; // just let it go + // see if the darned thing will work.... + qnode0.try_put(1); + g.wait_for_all(); + ASSERT(qnode1.try_get(ii) && ii == 1, "output not passed"); + tbb::flow::remove_edge(qnode0, fnode1); + tbb::flow::remove_edge(fnode1, qnode1); + + // rejecting + serial_fn_state0 = 0; + tbb::flow::make_edge(fnode0, qnode1); + tbb::flow::make_edge(qnode0, fnode0); + REMARK("Testing rejecting function_node:"); + ASSERT(!fnode0.my_queue, "node should have no queue"); + ASSERT(!fnode0.my_successors.empty(), "successor edge not added"); + qnode0.try_put(1); + BACKOFF_WAIT(!serial_fn_state0,"rejecting function_node didn't start"); + qnode0.try_put(2); // rejecting node should reject, reverse. + BACKOFF_WAIT(fnode0.my_predecessors.empty(), "Missing predecessor ---"); + serial_fn_state0 = 2; // release function_node body. + g.wait_for_all(); + REMARK(" reset"); + g.reset(); // should reverse the edge from the input to the function node. + ASSERT(!qnode0.my_successors.empty(), "empty successors after reset()"); + ASSERT(fnode0.my_predecessors.empty(), "predecessor not reversed"); + tbb::flow::remove_edge(qnode0, fnode0); + tbb::flow::remove_edge(fnode0, qnode1); + REMARK("\n"); + + // queueing + tbb::flow::make_edge(fnode1, qnode1); + REMARK("Testing queueing function_node:"); + ASSERT(fnode1.my_queue, "node should have no queue"); + ASSERT(!fnode1.my_successors.empty(), "successor edge not added"); + REMARK(" add_pred"); + ASSERT(fnode1.register_predecessor(qnode0), "Cannot register as predecessor"); + ASSERT(!fnode1.my_predecessors.empty(), "Missing predecessor"); + REMARK(" reset"); + g.wait_for_all(); + g.reset(); // should reverse the edge from the input to the function node. + ASSERT(!qnode0.my_successors.empty(), "empty successors after reset()"); + ASSERT(fnode1.my_predecessors.empty(), "predecessor not reversed"); + tbb::flow::remove_edge(qnode0, fnode1); + tbb::flow::remove_edge(fnode1, qnode1); + REMARK("\n"); + + serial_fn_state0 = 0; // make the function_node wait + tbb::flow::make_edge(qnode0, fnode0); + REMARK(" start_func"); + qnode0.try_put(1); + BACKOFF_WAIT(serial_fn_state0 == 0, "Timed out waiting after 1st put"); + // now if we put an item to the queues the edges to the function_node will reverse. + REMARK(" put_node(2)"); + qnode0.try_put(2); // start queue node. + // wait for the edges to reverse + BACKOFF_WAIT(fnode0.my_predecessors.empty(), "Timed out waiting"); + ASSERT(!fnode0.my_predecessors.empty(), "function_node edge not reversed"); + g.my_root_task->cancel_group_execution(); + // release the function_node + serial_fn_state0 = 2; + g.wait_for_all(); + ASSERT(!fnode0.my_predecessors.empty() && qnode0.my_successors.empty(), "function_node edge not reversed"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(fnode0.my_predecessors.empty() && qnode0.my_successors.empty(), "function_node edge not removed"); + ASSERT(fnode0.my_successors.empty(), "successor to fnode not removed"); + REMARK(" done\n"); +} + +template<typename TT> +class tag_func { + TT my_mult; +public: + tag_func(TT multiplier) : my_mult(multiplier) { } + // operator() will return [0 .. Count) + tbb::flow::tag_value operator()( TT v) { + tbb::flow::tag_value t = tbb::flow::tag_value(v / my_mult); + return t; + } +}; + +template<typename JNODE_TYPE> +void +TestSimpleSuccessorArc(const char *name) { + tbb::flow::graph g; + { + REMARK("Join<%s> successor test ", name); + tbb::flow::join_node<tbb::flow::tuple<int>, JNODE_TYPE> qj(g); + tbb::flow::broadcast_node<tbb::flow::tuple<int> > bnode(g); + tbb::flow::make_edge(qj, bnode); + ASSERT(!qj.my_successors.empty(),"successor missing after linking"); + g.reset(); + ASSERT(!qj.my_successors.empty(),"successor missing after reset()"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(qj.my_successors.empty(), "successors not removed after reset(rf_clear_edges)"); + } +} + +template<> +void +TestSimpleSuccessorArc<tbb::flow::tag_matching>(const char *name) { + tbb::flow::graph g; + { + REMARK("Join<%s> successor test ", name); + typedef tbb::flow::tuple<int,int> my_tuple; + tbb::flow::join_node<my_tuple, tbb::flow::tag_matching> qj(g, + tag_func<int>(1), + tag_func<int>(1) + ); + tbb::flow::broadcast_node<my_tuple > bnode(g); + tbb::flow::make_edge(qj, bnode); + ASSERT(!qj.my_successors.empty(),"successor missing after linking"); + g.reset(); + ASSERT(!qj.my_successors.empty(),"successor missing after reset()"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(qj.my_successors.empty(), "successors not removed after reset(rf_clear_edges)"); + } +} + +void +TestJoinNode() { + tbb::flow::graph g; + + TestSimpleSuccessorArc<tbb::flow::queueing>("queueing"); + TestSimpleSuccessorArc<tbb::flow::reserving>("reserving"); + TestSimpleSuccessorArc<tbb::flow::tag_matching>("tag_matching"); + + // queueing and tagging join nodes have input queues, so the input ports do not reverse. + REMARK(" reserving preds"); + { + tbb::flow::join_node<tbb::flow::tuple<int,int>, tbb::flow::reserving> rj(g); + tbb::flow::queue_node<int> q0(g); + tbb::flow::queue_node<int> q1(g); + tbb::flow::make_edge(q0,tbb::flow::input_port<0>(rj)); + tbb::flow::make_edge(q1,tbb::flow::input_port<1>(rj)); + q0.try_put(1); + g.wait_for_all(); // quiesce + ASSERT(!(tbb::flow::input_port<0>(rj).my_predecessors.empty()),"reversed port missing predecessor"); + ASSERT((tbb::flow::input_port<1>(rj).my_predecessors.empty()),"non-reversed port has pred"); + g.reset(); + ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"reversed port has pred after reset()"); + ASSERT((tbb::flow::input_port<1>(rj).my_predecessors.empty()),"non-reversed port has pred after reset()"); + q1.try_put(2); + g.wait_for_all(); // quiesce + ASSERT(!(tbb::flow::input_port<1>(rj).my_predecessors.empty()),"reversed port missing predecessor"); + ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"non-reversed port has pred"); + g.reset(); + ASSERT((tbb::flow::input_port<1>(rj).my_predecessors.empty()),"reversed port has pred after reset()"); + ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"non-reversed port has pred after reset()"); + // should reset predecessors just as regular reset. + q1.try_put(3); + g.wait_for_all(); // quiesce + ASSERT(!(tbb::flow::input_port<1>(rj).my_predecessors.empty()),"reversed port missing predecessor"); + ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"non-reversed port has pred"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT((tbb::flow::input_port<1>(rj).my_predecessors.empty()),"reversed port has pred after reset()"); + ASSERT((tbb::flow::input_port<0>(rj).my_predecessors.empty()),"non-reversed port has pred after reset()"); + ASSERT(q0.my_successors.empty(), "edge not removed by reset(rf_clear_edges)"); + ASSERT(q1.my_successors.empty(), "edge not removed by reset(rf_clear_edges)"); + } + REMARK(" done\n"); +} + +void +TestLimiterNode() { + int out_int; + tbb::flow::graph g; + tbb::flow::limiter_node<int> ln(g,1); + REMARK("Testing limiter_node: preds and succs"); + ASSERT(ln.decrement.my_predecessor_count == 0, "error in pred count"); + ASSERT(ln.decrement.my_initial_predecessor_count == 0, "error in initial pred count"); + ASSERT(ln.decrement.my_current_count == 0, "error in current count"); +#if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR + ASSERT(ln.init_decrement_predecessors == 0, "error in decrement predecessors"); +#endif + ASSERT(ln.my_threshold == 1, "error in my_threshold"); + tbb::flow::queue_node<int> inq(g); + tbb::flow::queue_node<int> outq(g); + tbb::flow::broadcast_node<tbb::flow::continue_msg> bn(g); + + tbb::flow::make_edge(inq,ln); + tbb::flow::make_edge(ln,outq); + tbb::flow::make_edge(bn,ln.decrement); + + g.wait_for_all(); + ASSERT(!(ln.my_successors.empty()),"successors empty after make_edge"); + ASSERT(ln.my_predecessors.empty(), "input edge reversed"); + inq.try_put(1); + g.wait_for_all(); + ASSERT(outq.try_get(out_int) && out_int == 1, "limiter_node didn't pass first value"); + ASSERT(ln.my_predecessors.empty(), "input edge reversed"); + inq.try_put(2); + g.wait_for_all(); + ASSERT(!outq.try_get(out_int), "limiter_node incorrectly passed second input"); + ASSERT(!ln.my_predecessors.empty(), "input edge to limiter_node not reversed"); + bn.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(outq.try_get(out_int) && out_int == 2, "limiter_node didn't pass second value"); + g.wait_for_all(); + ASSERT(!ln.my_predecessors.empty(), "input edge was reversed(after try_get())"); + g.reset(); + ASSERT(ln.my_predecessors.empty(), "input edge not reset"); + inq.try_put(3); + g.wait_for_all(); + ASSERT(outq.try_get(out_int) && out_int == 3, "limiter_node didn't pass third value"); + + REMARK(" rf_clear_edges"); + // currently the limiter_node will not pass another message + g.reset(tbb::flow::rf_clear_edges); + ASSERT(ln.decrement.my_predecessor_count == 0, "error in pred count"); + ASSERT(ln.decrement.my_initial_predecessor_count == 0, "error in initial pred count"); + ASSERT(ln.decrement.my_current_count == 0, "error in current count"); +#if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR + ASSERT(ln.init_decrement_predecessors == 0, "error in decrement predecessors"); +#endif + ASSERT(ln.my_threshold == 1, "error in my_threshold"); + ASSERT(ln.my_predecessors.empty(), "preds not reset(rf_clear_edges)"); + ASSERT(ln.my_successors.empty(), "preds not reset(rf_clear_edges)"); + ASSERT(inq.my_successors.empty(), "Arc not removed on reset(rf_clear_edges)"); + ASSERT(inq.my_successors.empty(), "Arc not removed on reset(rf_clear_edges)"); + ASSERT(bn.my_successors.empty(), "control edge not removed on reset(rf_clear_edges)"); + tbb::flow::make_edge(inq,ln); + tbb::flow::make_edge(ln,outq); + inq.try_put(4); + inq.try_put(5); + g.wait_for_all(); + ASSERT(outq.try_get(out_int),"missing output after reset(rf_clear_edges)"); + ASSERT(out_int == 4, "input incorrect (4)"); + bn.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(!outq.try_get(out_int),"second output incorrectly passed (rf_clear_edges)"); + REMARK(" done\n"); +} + +template<typename MF_TYPE> +struct mf_body { + tbb::atomic<int> *_flag; + mf_body( tbb::atomic<int> &myatomic) : _flag(&myatomic) { } + void operator()( const int& in, typename MF_TYPE::output_ports_type &outports) { + if(*_flag == 0) { + *_flag = 1; + BACKOFF_WAIT(*_flag == 1, "multifunction_node not released"); + } + + if(in & 0x1) tbb::flow::get<1>(outports).try_put(in); + else tbb::flow::get<0>(outports).try_put(in); + } +}; + +template<typename P, typename T> +struct test_reversal; +template<typename T> +struct test_reversal<tbb::flow::queueing, T> { + test_reversal() { REMARK("<queueing>"); } + // queueing node will not reverse. + bool operator()( T &node) { return node.my_predecessors.empty(); } +}; + +template<typename T> +struct test_reversal<tbb::flow::rejecting, T> { + test_reversal() { REMARK("<rejecting>"); } + bool operator()( T &node) { return !node.my_predecessors.empty(); } +}; + +template<typename P> +void +TestMultifunctionNode() { + typedef tbb::flow::multifunction_node<int, tbb::flow::tuple<int, int>, P> multinode_type; + REMARK("Testing multifunction_node"); + test_reversal<P,multinode_type> my_test; + REMARK(":"); + tbb::flow::graph g; + multinode_type mf(g, tbb::flow::serial, mf_body<multinode_type>(serial_fn_state0)); + tbb::flow::queue_node<int> qin(g); + tbb::flow::queue_node<int> qodd_out(g); + tbb::flow::queue_node<int> qeven_out(g); + tbb::flow::make_edge(qin,mf); + tbb::flow::make_edge(tbb::flow::output_port<0>(mf), qeven_out); + tbb::flow::make_edge(tbb::flow::output_port<1>(mf), qodd_out); + g.wait_for_all(); + for( int ii = 0; ii < 2 ; ++ii) { + serial_fn_state0 = 0; + if(ii == 0) REMARK(" reset preds"); else REMARK(" 2nd"); + qin.try_put(0); + // wait for node to be active + BACKOFF_WAIT(serial_fn_state0 == 0, "timed out waiting for first put"); + qin.try_put(1); + BACKOFF_WAIT((!my_test(mf)), "Timed out waiting"); + ASSERT(my_test(mf), "fail second put test"); + g.my_root_task->cancel_group_execution(); + // release node + serial_fn_state0 = 2; + g.wait_for_all(); + ASSERT(my_test(mf), "fail cancel group test"); + if( ii == 1) { + REMARK(" rf_clear_edges"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(tbb::flow::output_port<0>(mf).my_successors.empty(), "output_port<0> not reset (rf_clear_edges)"); + ASSERT(tbb::flow::output_port<1>(mf).my_successors.empty(), "output_port<1> not reset (rf_clear_edges)"); + } + else + { + g.reset(); + } + ASSERT(mf.my_predecessors.empty(), "edge didn't reset"); + ASSERT((ii == 0 && !qin.my_successors.empty()) || (ii == 1 && qin.my_successors.empty()), "edge didn't reset"); + } + REMARK(" done\n"); +} + +// indexer_node is like a broadcast_node, in that none of its inputs reverse, and it +// never allows a successor to reverse its edge, so we only need test the successors. +void +TestIndexerNode() { + tbb::flow::graph g; + typedef tbb::flow::indexer_node< int, int > indexernode_type; + indexernode_type inode(g); + REMARK("Testing indexer_node:"); + tbb::flow::queue_node<indexernode_type::output_type> qout(g); + tbb::flow::make_edge(inode,qout); + g.wait_for_all(); + ASSERT(!inode.my_successors.empty(), "successor of indexer_node missing"); + g.reset(); + ASSERT(!inode.my_successors.empty(), "successor of indexer_node missing after reset"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(inode.my_successors.empty(), "successor of indexer_node not removed by reset(rf_clear_edges)"); + REMARK(" done\n"); +} + +template<typename Node> +void +TestScalarNode(const char *name) { + tbb::flow::graph g; + Node on(g); + tbb::flow::queue_node<int> qout(g); + REMARK("Testing %s:", name); + tbb::flow::make_edge(on,qout); + g.wait_for_all(); + ASSERT(!on.my_successors.empty(), "edge not added"); + g.reset(); + ASSERT(!on.my_successors.empty(), "edge improperly removed"); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(on.my_successors.empty(), "edge not removed by reset(rf_clear_edges)"); + REMARK(" done\n"); +} + +struct seq_body { + size_t operator()(const int &in) { + return size_t(in / 3); + } +}; + +// sequencer_node behaves like a queueing node, but requires a different constructor. +void +TestSequencerNode() { + tbb::flow::graph g; + tbb::flow::sequencer_node<int> bnode(g, seq_body()); + REMARK("Testing sequencer_node:"); + tbb::flow::function_node<int> fnode(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0)); + REMARK("Testing sequencer_node:"); + serial_fn_state0 = 0; // reset to waiting state. + REMARK(" make_edge"); + tbb::flow::make_edge(bnode, fnode); + ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after make_edge"); + REMARK(" try_put"); + bnode.try_put(0); // will forward to the fnode + BACKOFF_WAIT( serial_fn_state0 == 0, "timeout waiting for function_node"); // wait for the function_node to fire up + ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after forwarding message"); + serial_fn_state0 = 0; + g.wait_for_all(); + REMARK(" remove_edge"); + tbb::flow::remove_edge(bnode, fnode); + ASSERT(bnode.my_successors.empty(), "buffering node has a successor after remove_edge"); + tbb::flow::join_node<tbb::flow::tuple<int,int>,tbb::flow::reserving> jnode(g); + tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode)); // will spawn a task + g.wait_for_all(); + ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after attaching to join"); + REMARK(" reverse"); + bnode.try_put(3); // the edge should reverse + g.wait_for_all(); + ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving"); + REMARK(" reset()"); + g.wait_for_all(); + g.reset(); // should be in forward direction again + ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after reset()"); + REMARK(" remove_edge"); + g.reset(tbb::flow::rf_clear_edges); // should be in forward direction again + ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reset(rf_clear_edges)"); + ASSERT(fnode.my_predecessors.empty(), "buffering node reversed after reset(rf_clear_edges)"); + REMARK(" done\n"); + g.wait_for_all(); +} + +struct snode_body { + int max_cnt; + int my_cnt; + snode_body( const int &in) : max_cnt(in) { my_cnt = 0; } +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(int &out) { + if(max_cnt <= my_cnt++) return false; + out = my_cnt; + return true; + } +#else + int operator()(tbb::flow_control &fc) { + if(max_cnt <= my_cnt++) { + fc.stop(); + return int(); + } + return my_cnt; + } +#endif +}; + +void +TestSourceNode() { + tbb::flow::graph g; + tbb::flow::input_node<int> sn(g, snode_body(4)); + REMARK("Testing input_node:"); + tbb::flow::queue_node<int> qin(g); + tbb::flow::join_node<tbb::flow::tuple<int,int>, tbb::flow::reserving> jn(g); + tbb::flow::queue_node<tbb::flow::tuple<int,int> > qout(g); + + REMARK(" make_edges"); + tbb::flow::make_edge(sn, tbb::flow::input_port<0>(jn)); + tbb::flow::make_edge(qin, tbb::flow::input_port<1>(jn)); + tbb::flow::make_edge(jn,qout); + ASSERT(!sn.my_successors.empty(), "source node has no successor after make_edge"); + g.wait_for_all(); + g.reset(); + ASSERT(!sn.my_successors.empty(), "source node has no successor after reset"); + g.wait_for_all(); + g.reset(tbb::flow::rf_clear_edges); + ASSERT(sn.my_successors.empty(), "source node has successor after reset(rf_clear_edges)"); + tbb::flow::make_edge(sn, tbb::flow::input_port<0>(jn)); + tbb::flow::make_edge(qin, tbb::flow::input_port<1>(jn)); + tbb::flow::make_edge(jn,qout); + g.wait_for_all(); + REMARK(" activate"); + sn.activate(); // will forward to the fnode + REMARK(" wait1"); + BACKOFF_WAIT( !sn.my_successors.empty(), "Timed out waiting for edge to reverse"); + ASSERT(sn.my_successors.empty(), "source node has no successor after forwarding message"); + + g.wait_for_all(); + g.reset(); + ASSERT(!sn.my_successors.empty(), "input_node has no successors after reset"); + ASSERT(tbb::flow::input_port<0>(jn).my_predecessors.empty(), "successor of input_node has pred after reset."); + REMARK(" done\n"); +} + +int TestMain() { + + if(MinThread < 3) MinThread = 3; + tbb::task_scheduler_init init(MinThread); // tests presume at least three threads + + TestBufferingNode< tbb::flow::buffer_node<int> >("buffer_node"); + TestBufferingNode< tbb::flow::priority_queue_node<int> >("priority_queue_node"); + TestBufferingNode< tbb::flow::queue_node<int> >("queue_node"); + TestSequencerNode(); + + TestMultifunctionNode<tbb::flow::rejecting>(); + TestMultifunctionNode<tbb::flow::queueing>(); + TestSourceNode(); + TestContinueNode(); + TestFunctionNode(); + + TestJoinNode(); + + TestLimiterNode(); + TestIndexerNode(); + TestSplitNode(); + TestScalarNode<tbb::flow::broadcast_node<int> >("broadcast_node"); + TestScalarNode<tbb::flow::overwrite_node<int> >("overwrite_node"); + TestScalarNode<tbb::flow::write_once_node<int> >("write_once_node"); + + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_follows_and_precedes_api.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_follows_and_precedes_api.h new file mode 100644 index 00000000..6fdb89fb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_follows_and_precedes_api.h @@ -0,0 +1,263 @@ +/* + Copyright (c) 2019-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness.h" +#include "tbb/flow_graph.h" + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +#include <type_traits> + +namespace follows_and_precedes_testing{ + +template <typename NodeType> +struct testing_method_follows: std::integral_constant<int, 0> {}; + +template <typename... Args> +struct testing_method_follows<tbb::flow::join_node<Args...>> : std::integral_constant<int, 1> {}; +template <typename... Args> +struct testing_method_follows<tbb::flow::continue_node<Args...>> : std::integral_constant<int, 1> {}; + +template <typename... Args> +struct testing_method_follows<tbb::flow::overwrite_node<Args...>> : std::integral_constant<int, 2> {}; +template <typename... Args> +struct testing_method_follows<tbb::flow::write_once_node<Args...>> : std::integral_constant<int, 2> {}; + +template <typename... Args> +struct testing_method_follows<tbb::flow::multifunction_node<Args...>> : std::integral_constant<int, 3> {}; + +template <typename MessageType, typename NodeType, typename PredecessorType> +class edge_checker_follows { +public: + static void check(tbb::flow::graph& g, + NodeType& node, + std::array<PredecessorType, 3>& preds, + std::array<MessageType, 3>& messages) { + check_impl(g, node, preds, messages, typename testing_method_follows<NodeType>::type()); + } +private: + // Test is applicable for: function_node, buffer_node, queue_node, priority_queue_node, limiter_node, + // broadcast_node, sequencer_node + static void check_impl(tbb::flow::graph& g, + NodeType& node, + std::array<PredecessorType, 3>& preds, + std::array<MessageType, 3>& messages, + std::integral_constant<int, 0>) { + tbb::flow::buffer_node<typename NodeType::output_type> buffer(g); + tbb::flow::make_edge(node, buffer); + + for(size_t i = 0; i < 3; ++i) { + preds[i].try_put(messages[i]); + g.wait_for_all(); + + typename NodeType::output_type storage; + ASSERT((buffer.try_get(storage) && !buffer.try_get(storage)), "Not exact edge quantity was made"); + } + } + // Test is applicable for: continue_node, join_node + static void check_impl(tbb::flow::graph& g, + NodeType& node, + std::array<PredecessorType, 3>& preds, + std::array<MessageType, 3>& messages, + std::integral_constant<int, 1>) { + tbb::flow::buffer_node<typename NodeType::output_type> buffer(g); + tbb::flow::make_edge(node, buffer); + + for(size_t i = 0; i < 3; ++i) { + preds[i].try_put(messages[i]); + g.wait_for_all(); + } + + typename NodeType::output_type storage; + ASSERT((buffer.try_get(storage) && !buffer.try_get(storage)), "Not exact edge quantity was made"); + } + // Test is applicable for: overwrite_node, write_once_node + static void check_impl(tbb::flow::graph& g, + NodeType& node, + std::array<PredecessorType, 3>& preds, + std::array<MessageType, 3>& messages, + std::integral_constant<int, 2>) { + for(size_t i = 0; i < 3; ++i) { + node.clear(); + preds[i].try_put(messages[i]); + g.wait_for_all(); + + typename NodeType::output_type storage; + ASSERT((node.try_get(storage)), "Not exact edge quantity was made"); + } + } + // Test is applicable for: multifunction_node + static void check_impl(tbb::flow::graph& g, + NodeType& node, + std::array<PredecessorType, 3>& preds, + std::array<MessageType, 3>& messages, + std::integral_constant<int, 3>) { + typedef typename std::remove_reference<decltype(tbb::flow::output_port<0>(node))>::type multioutput; + tbb::flow::buffer_node<typename multioutput::output_type> buf(tbb::flow::follows(tbb::flow::output_port<0>(node))); + + for(size_t i = 0; i < 3; ++i) { + preds[i].try_put(messages[i]); + g.wait_for_all(); + + typename multioutput::output_type storage; + ASSERT((buf.try_get(storage) && ! buf.try_get(storage)), "Not exact edge quantity was made"); + } + } +}; + +template <typename NodeType> +struct testing_method_precedes: std::integral_constant<int, 0> {}; + +template <typename... Args> +struct testing_method_precedes<tbb::flow::buffer_node<Args...>> : std::integral_constant<int, 1> {}; +template <typename... Args> +struct testing_method_precedes<tbb::flow::queue_node<Args...>> : std::integral_constant<int, 1> {}; +template <typename... Args> +struct testing_method_precedes<tbb::flow::priority_queue_node<Args...>> : std::integral_constant<int, 1> {}; +template <typename... Args> +struct testing_method_precedes<tbb::flow::sequencer_node<Args...>> : std::integral_constant<int, 1> {}; + +template <typename... Args> +struct testing_method_precedes<tbb::flow::join_node<Args...>> : std::integral_constant<int, 2> {}; + +template <typename MessageType, typename NodeType> +class edge_checker_precedes { + using NodeOutputType = typename NodeType::output_type; + using SuccessorOutputType = typename tbb::flow::buffer_node<NodeOutputType>::output_type; +public: + static void check(tbb::flow::graph& g, + NodeType& node, + std::array<tbb::flow::buffer_node<NodeOutputType>, 3>& successors, + std::vector<MessageType>& messages) { + check_impl(g, node, successors, messages, typename testing_method_precedes<NodeType>::type()); + } +private: + // Testing is applicable for: continue_node, function_node, overwrite_node, buffer_node, + // broadcast_node, write_once_node, limiter_node + static void check_impl(tbb::flow::graph& g, + NodeType& node, + std::array<tbb::flow::buffer_node<NodeOutputType>, 3>& successors, + std::vector<MessageType>& messages, + std::integral_constant<int, 0>) { + ASSERT((messages.size() == 1), + "messages.size() has to be 1 to test nodes what broadcast message to all the successors"); + + node.try_put(messages[0]); + g.wait_for_all(); + + SuccessorOutputType storage; + for(auto& successor: successors) { + ASSERT((successor.try_get(storage) && !successor.try_get(storage)), + "Not exact edge quantity was made"); + } + } + // Testing is applicable for: buffer_node, queue_node, priority_queue_node, sequencer_node + static void check_impl(tbb::flow::graph& g, + NodeType& node, + std::array<tbb::flow::buffer_node<typename NodeType::output_type>, 3>& successors, + std::vector<MessageType>& messages, + std::integral_constant<int, 1>) { + ASSERT((messages.size() == 3), + "messages.size() has to be 3 to test nodes what send a message to the first available successor"); + + tbb::flow::write_once_node<SuccessorOutputType> + buffer(tbb::flow::follows(successors[0], successors[1], successors[2])); + + for(size_t i = 0; i < 3; ++i) { + node.try_put(messages[i]); + g.wait_for_all(); + + SuccessorOutputType storage; + ASSERT((buffer.try_get(storage)), "Not exact edge quantity was made"); + + buffer.clear(); + } + } + // Testing is applicable for: join_node + static void check_impl(tbb::flow::graph& g, + NodeType& node, + std::array<tbb::flow::buffer_node<typename NodeType::output_type>, 3>& successors, + std::vector<MessageType>& messages, + std::integral_constant<int, 2>) { + ASSERT((messages.size() == 3), + "messages.size() has to be 3 to test nodes what send a message to the first available successor"); + std::array<tbb::flow::buffer_node<MessageType>, 3> preds = { + { + tbb::flow::buffer_node<MessageType>(g), + tbb::flow::buffer_node<MessageType>(g), + tbb::flow::buffer_node<MessageType>(g) + } + }; + + make_edge(preds[0], tbb::flow::input_port<0>(node)); + make_edge(preds[1], tbb::flow::input_port<1>(node)); + make_edge(preds[2], tbb::flow::input_port<2>(node)); + + for(size_t i = 0; i < 3; ++i) { + preds[i].try_put(messages[i]); + g.wait_for_all(); + } + + typename NodeType::output_type storage; + for(auto& successor: successors) { + ASSERT((successor.try_get(storage) && !successor.try_get(storage)), + "Not exact edge quantity was made"); + } + } +}; + +template<typename MessageType, + typename NodeType, + typename PredecessorType=tbb::flow::broadcast_node<MessageType>, + typename... ConstructorArgs> +void test_follows(std::array<MessageType, 3>& messages, ConstructorArgs&&... args) { + using namespace tbb::flow; + + graph g; + std::array<PredecessorType, 3> preds = { + { + PredecessorType(g), + PredecessorType(g), + PredecessorType(g) + } + }; + + NodeType node(follows(preds[0], preds[1], preds[2]), std::forward<ConstructorArgs>(args)...); + + edge_checker_follows<MessageType, NodeType, PredecessorType>::check(g, node, preds, messages); +} + +template<typename MessageType, + typename NodeType, + typename... ConstructorArgs> +void test_precedes(std::vector<MessageType>& messages, ConstructorArgs&&... args) { + using namespace tbb::flow; + + using SuccessorType = buffer_node<typename NodeType::output_type>; + + graph g; + + std::array<SuccessorType, 3> successors = { {SuccessorType(g), SuccessorType(g), SuccessorType(g)} }; + + NodeType node(precedes(successors[0], successors[1], successors[2]), std::forward<ConstructorArgs>(args)...); + + edge_checker_precedes<MessageType, NodeType>::check(g, node, successors, messages); +} + +} // follows_and_precedes_testing +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_fp.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_fp.cpp new file mode 100644 index 00000000..eecd2df4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_fp.cpp @@ -0,0 +1,381 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** This test checks the automatic propagation of master thread FPU settings + into the worker threads. **/ + +#include "harness_fp.h" +#include "harness.h" +#define private public +#include "tbb/task.h" +#undef private +#include "tbb/parallel_for.h" +#include "tbb/task_scheduler_init.h" + +const int N = 500000; + +#if ( __TBB_x86_32 || __TBB_x86_64 ) && __TBB_CPU_CTL_ENV_PRESENT && !defined(__TBB_WIN32_USE_CL_BUILTINS) +#include "harness_barrier.h" + +class CheckNoSseStatusPropagationBody : public NoAssign { + Harness::SpinBarrier &barrier; +public: + CheckNoSseStatusPropagationBody( Harness::SpinBarrier &_barrier ) : barrier(_barrier) {} + void operator()( const tbb::blocked_range<int>& ) const { + barrier.wait(); + tbb::internal::cpu_ctl_env ctl; + ctl.get_env(); + ASSERT( (ctl.mxcsr & SSE_STATUS_MASK) == 0, "FPU control status bits have been propagated." ); + } +}; + +void CheckNoSseStatusPropagation() { + tbb::internal::cpu_ctl_env ctl; + ctl.get_env(); + ctl.mxcsr |= SSE_STATUS_MASK; + ctl.set_env(); + const int num_threads = tbb::task_scheduler_init::default_num_threads(); + Harness::SpinBarrier barrier(num_threads); + tbb::task_scheduler_init init(num_threads); + tbb::parallel_for( tbb::blocked_range<int>(0, num_threads), CheckNoSseStatusPropagationBody(barrier) ); + ctl.mxcsr &= ~SSE_STATUS_MASK; + ctl.set_env(); +} +#else /* Other archs */ +void CheckNoSseStatusPropagation() {} +#endif /* Other archs */ + +class RoundingModeCheckBody { + int m_mode; + int m_sseMode; +public: + void operator() ( int /*iter*/ ) const { + ASSERT( GetRoundingMode() == m_mode, "FPU control state has not been propagated." ); + ASSERT( GetSseMode() == m_sseMode, "SSE control state has not been propagated." ); + } + + RoundingModeCheckBody ( int mode, int sseMode ) : m_mode(mode), m_sseMode(sseMode) {} +}; + +void TestArenaFpuEnvPropagation( int id ) { + // TBB scheduler instance in a master thread captures the FPU control state + // at the moment of its initialization and passes it to the workers toiling + // on its behalf. + for( int k = 0; k < NumSseModes; ++k ) { + int sse_mode = SseModes[(k + id) % NumSseModes]; + SetSseMode( sse_mode ); + for( int i = 0; i < NumRoundingModes; ++i ) { + int mode = RoundingModes[(i + id) % NumRoundingModes]; + SetRoundingMode( mode ); + // New mode must be set before TBB scheduler is initialized + tbb::task_scheduler_init init; + tbb::parallel_for( 0, N, 1, RoundingModeCheckBody(mode, sse_mode) ); + ASSERT( GetRoundingMode() == mode, NULL ); + } + } +} + +#if __TBB_FP_CONTEXT +void TestArenaFpuEnvPersistence( int id ) { + // Since the following loop uses auto-initialization, the scheduler instance + // implicitly created by the first parallel_for invocation will persist + // until the thread ends, and thus workers will use the mode set by the + // first iteration. + int captured_mode = RoundingModes[id % NumRoundingModes]; + int captured_sse_mode = SseModes[id % NumSseModes]; + for( int k = 0; k < NumSseModes; ++k ) { + int sse_mode = SseModes[(k + id) % NumSseModes]; + SetSseMode( sse_mode ); + for( int i = 0; i < NumRoundingModes; ++i ) { + int mode = RoundingModes[(i + id) % NumRoundingModes]; + SetRoundingMode( mode ); + tbb::parallel_for( 0, N, 1, RoundingModeCheckBody(captured_mode, captured_sse_mode) ); + ASSERT( GetRoundingMode() == mode, NULL ); + } + } +} +#endif + +class LauncherBody { +public: + void operator() ( int id ) const { + TestArenaFpuEnvPropagation( id ); +#if __TBB_FP_CONTEXT + TestArenaFpuEnvPersistence( id ); +#endif + } +}; + +void TestFpuEnvPropagation () { + const int p = tbb::task_scheduler_init::default_num_threads(); + // The test should be run in an oversubscription mode. So create 4*p threads but + // limit the oversubscription for big machines (p>32) with 4*32+(p-32) threads. + const int num_threads = p + (NumRoundingModes-1)*min(p,32); + NativeParallelFor ( num_threads, LauncherBody() ); +} + +void TestCpuCtlEnvApi () { + for( int k = 0; k < NumSseModes; ++k ) { + SetSseMode( SseModes[k] ); + for( int i = 0; i < NumRoundingModes; ++i ) { + SetRoundingMode( RoundingModes[i] ); + ASSERT( GetRoundingMode() == RoundingModes[i], NULL ); + ASSERT( GetSseMode() == SseModes[k], NULL ); + } + } +} + +#if __TBB_FP_CONTEXT +const int numModes = NumRoundingModes*NumSseModes; +const int numArenas = 4; +tbb::task_group_context *contexts[numModes]; +// +1 for a default context +int roundingModes[numModes+numArenas]; +int sseModes[numModes+numArenas]; + +class TestContextFpuEnvBody { + int arenaNum; + int mode; + int depth; +public: + TestContextFpuEnvBody( int _arenaNum, int _mode, int _depth = 0 ) : arenaNum(_arenaNum), mode(_mode), depth(_depth) {} + void operator()( const tbb::blocked_range<int> &r ) const; +}; + +inline void SetMode( int mode ) { + SetRoundingMode( roundingModes[mode] ); + SetSseMode( sseModes[mode] ); +} + +inline void AssertMode( int mode ) { + ASSERT( GetRoundingMode() == roundingModes[mode], "FPU control state has not been set correctly." ); + ASSERT( GetSseMode() == sseModes[mode], "SSE control state has not been set correctly." ); +} + +inline int SetNextMode( int mode, int step ) { + const int nextMode = (mode+step)%numModes; + SetMode( nextMode ); + return nextMode; +} + +class TestContextFpuEnvTask : public tbb::task { + int arenaNum; + int mode; + int depth; +#if __TBB_CPU_CTL_ENV_PRESENT + static const int MAX_DEPTH = 3; +#else + static const int MAX_DEPTH = 4; +#endif +public: + TestContextFpuEnvTask( int _arenaNum, int _mode, int _depth = 0 ) : arenaNum(_arenaNum), mode(_mode), depth(_depth) {} + tbb::task* execute() __TBB_override { + AssertMode( mode ); + if ( depth < MAX_DEPTH ) { + // Test default context. + const int newMode1 = SetNextMode( mode, depth+1 ); + tbb::parallel_for( tbb::blocked_range<int>(0, numModes+1), TestContextFpuEnvBody( arenaNum, mode, depth+1 ) ); + AssertMode( newMode1 ); + + // Test user default context. + const int newMode2 = SetNextMode( newMode1, depth+1 ); + tbb::task_group_context ctx1; + const int newMode3 = SetNextMode( newMode2, depth+1 ); + tbb::parallel_for( tbb::blocked_range<int>(0, numModes+1), TestContextFpuEnvBody( arenaNum, mode, depth+1 ), ctx1 ); + AssertMode( newMode3 ); + + // Test user context which captured FPU control settings. + const int newMode4 = SetNextMode( newMode3, depth+1 ); + // Capture newMode4 + ctx1.capture_fp_settings(); + const int newMode5 = SetNextMode( newMode4, depth+1 ); + tbb::parallel_for( tbb::blocked_range<int>(0, numModes+1), TestContextFpuEnvBody( arenaNum, newMode4, depth+1 ), ctx1 ); + AssertMode( newMode5 ); + + // And again test user context which captured FPU control settings to check multiple captures. + const int newMode6 = SetNextMode( newMode5, depth+1 ); + // Capture newMode6 + ctx1.capture_fp_settings(); + const int newMode7 = SetNextMode( newMode6, depth+1 ); + tbb::parallel_for( tbb::blocked_range<int>(0, numModes+1), TestContextFpuEnvBody( arenaNum, newMode6, depth+1 ), ctx1 ); + AssertMode( newMode7 ); + + // Test an isolated context. The isolated context should use default FPU control settings. + const int newMode8 = SetNextMode( newMode7, depth+1 ); + tbb::task_group_context ctx2( tbb::task_group_context::isolated ); + const int newMode9 = SetNextMode( newMode8, depth+1 ); + tbb::parallel_for( tbb::blocked_range<int>(0, numModes+1), TestContextFpuEnvBody( arenaNum, numModes+arenaNum, depth+1 ), ctx2 ); + AssertMode( newMode9 ); + + // The binding should not owerrite captured FPU control settings. + const int newMode10 = SetNextMode( newMode9, depth+1 ); + tbb::task_group_context ctx3; + ctx3.capture_fp_settings(); + const int newMode11 = SetNextMode( newMode10, depth+1 ); + tbb::parallel_for( tbb::blocked_range<int>(0, numModes+1), TestContextFpuEnvBody( arenaNum, newMode10, depth+1 ), ctx3 ); + AssertMode( newMode11 ); + + // Restore initial mode since user code in tbb::task::execute should not change FPU settings. + SetMode( mode ); + } + + return NULL; + } +}; + +void TestContextFpuEnvBody::operator()( const tbb::blocked_range<int> &r ) const { + AssertMode( mode ); + + const int newMode = SetNextMode( mode, depth+2 ); + + int end = r.end(); + if ( end-1 == numModes ) { + // For a default context our mode should be inherited. + tbb::task::spawn_root_and_wait( + *new( tbb::task::allocate_root() ) TestContextFpuEnvTask( arenaNum, mode, depth ) ); + AssertMode( newMode ); + end--; + } + for ( int i=r.begin(); i<end; ++i ) { + tbb::task::spawn_root_and_wait( + *new( tbb::task::allocate_root(*contexts[i]) ) TestContextFpuEnvTask( arenaNum, i, depth ) ); + AssertMode( newMode ); + } + + // Restore initial mode since user code in tbb::task::execute should not change FPU settings. + SetMode( mode ); +} + +class TestContextFpuEnvNativeLoopBody { +public: + void operator() ( int arenaNum ) const { + SetMode(numModes+arenaNum); + tbb::task_scheduler_init init; + tbb::task::spawn_root_and_wait( *new (tbb::task::allocate_root() ) TestContextFpuEnvTask( arenaNum, numModes+arenaNum ) ); + } +}; + +#if TBB_USE_EXCEPTIONS +const int NUM_ITERS = 1000; +class TestContextFpuEnvEhBody { + int mode; + int eh_iter; + int depth; +public: + TestContextFpuEnvEhBody( int _mode, int _eh_iter, int _depth = 0 ) : mode(_mode), eh_iter(_eh_iter), depth(_depth) {} + void operator()( const tbb::blocked_range<int> &r ) const { + AssertMode( mode ); + if ( depth < 1 ) { + const int newMode1 = SetNextMode( mode, 1 ); + tbb::task_group_context ctx; + ctx.capture_fp_settings(); + const int newMode2 = SetNextMode( newMode1, 1 ); + try { + tbb::parallel_for( tbb::blocked_range<int>(0, NUM_ITERS), TestContextFpuEnvEhBody(newMode1,rand()%NUM_ITERS,1), tbb::simple_partitioner(), ctx ); + } catch (...) { + AssertMode( newMode2 ); + if ( r.begin() == eh_iter ) throw; + } + AssertMode( newMode2 ); + SetMode( mode ); + } else if ( r.begin() == eh_iter ) throw 0; + } +}; + +class TestContextFpuEnvEhNativeLoopBody { +public: + void operator() ( int arenaNum ) const { + SetMode( arenaNum%numModes ); + try { + tbb::parallel_for( tbb::blocked_range<int>(0, NUM_ITERS), TestContextFpuEnvEhBody((arenaNum+1)%numModes,rand()%NUM_ITERS), + tbb::simple_partitioner(), *contexts[(arenaNum+1)%numModes] ); + ASSERT( false, "parallel_for has not thrown an exception." ); + } catch (...) { + AssertMode( arenaNum%numModes ); + } + } +}; +#endif /* TBB_USE_EXCEPTIONS */ + +void TestContextFpuEnv() { + // Prepare contexts' fp modes. + for ( int i = 0, modeNum = 0; i < NumRoundingModes; ++i ) { + const int roundingMode = RoundingModes[i]; + SetRoundingMode( roundingMode ); + for( int j = 0; j < NumSseModes; ++j, ++modeNum ) { + const int sseMode = SseModes[j]; + SetSseMode( sseMode ); + + contexts[modeNum] = new tbb::task_group_context( tbb::task_group_context::isolated, + tbb::task_group_context::default_traits | tbb::task_group_context::fp_settings ); + roundingModes[modeNum] = roundingMode; + sseModes[modeNum] = sseMode; + } + } + // Prepare arenas' fp modes. + for ( int arenaNum = 0; arenaNum < numArenas; ++arenaNum ) { + roundingModes[numModes+arenaNum] = roundingModes[arenaNum%numModes]; + sseModes[numModes+arenaNum] = sseModes[arenaNum%numModes]; + } + NativeParallelFor( numArenas, TestContextFpuEnvNativeLoopBody() ); +#if TBB_USE_EXCEPTIONS + NativeParallelFor( numArenas, TestContextFpuEnvEhNativeLoopBody() ); +#endif + for ( int modeNum = 0; modeNum < numModes; ++modeNum ) + delete contexts[modeNum]; +} + +tbb::task_group_context glbIsolatedCtx( tbb::task_group_context::isolated ); +int glbIsolatedCtxMode = -1; + +struct TestGlobalIsolatedContextTask : public tbb::task { + tbb::task* execute() __TBB_override { + AssertFPMode( glbIsolatedCtxMode ); + return NULL; + } +}; + +#include "tbb/mutex.h" + +struct TestGlobalIsolatedContextNativeLoopBody { + void operator()( int threadId ) const { + FPModeContext fpGuard( threadId ); + static tbb::mutex rootAllocMutex; + rootAllocMutex.lock(); + if ( glbIsolatedCtxMode == -1 ) + glbIsolatedCtxMode = threadId; + tbb::task &root = *new (tbb::task::allocate_root( glbIsolatedCtx )) TestGlobalIsolatedContextTask(); + rootAllocMutex.unlock(); + tbb::task::spawn_root_and_wait( root ); + } +}; + +void TestGlobalIsolatedContext() { + ASSERT( numArenas > 1, NULL ); + NativeParallelFor( numArenas, TestGlobalIsolatedContextNativeLoopBody() ); +} +#endif /* __TBB_FP_CONTEXT */ + +int TestMain () { + TestCpuCtlEnvApi(); + TestFpuEnvPropagation(); + CheckNoSseStatusPropagation(); +#if __TBB_FP_CONTEXT + TestContextFpuEnv(); + TestGlobalIsolatedContext(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_function_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_function_node.cpp new file mode 100644 index 00000000..b04719a9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_function_node.cpp @@ -0,0 +1,684 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_ALLOCATOR __TBB_CPF_BUILD + +#include "harness.h" +#include "harness_graph.h" + +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/spin_rw_mutex.h" +#include "test_follows_and_precedes_api.h" + +#define N 100 +#define MAX_NODES 4 + +//! Performs test on function nodes with limited concurrency and buffering +/** These tests check: + 1) that the number of executing copies never exceed the concurrency limit + 2) that the node never rejects + 3) that no items are lost + and 4) all of this happens even if there are multiple predecessors and successors +*/ + +template< typename InputType > +struct parallel_put_until_limit : private NoAssign { + + harness_counting_sender<InputType> *my_senders; + + parallel_put_until_limit( harness_counting_sender<InputType> *senders ) : my_senders(senders) {} + + void operator()( int i ) const { + if ( my_senders ) { + my_senders[i].try_put_until_limit(); + } + } + +}; + +template<typename IO> +struct pass_through { + IO operator()(const IO& i) { return i; } +}; + +template< typename InputType, typename OutputType, typename Body > +void buffered_levels( size_t concurrency, Body body ) { + + // Do for lc = 1 to concurrency level + for ( size_t lc = 1; lc <= concurrency; ++lc ) { + tbb::flow::graph g; + + // Set the execute_counter back to zero in the harness + harness_graph_executor<InputType, OutputType>::execute_count = 0; + // Set the number of current executors to zero. + harness_graph_executor<InputType, OutputType>::current_executors = 0; + // Set the max allowed executors to lc. There is a check in the functor to make sure this is never exceeded. + harness_graph_executor<InputType, OutputType>::max_executors = lc; + + // Create the function_node with the appropriate concurrency level, and use default buffering + tbb::flow::function_node< InputType, OutputType > exe_node( g, lc, body ); + tbb::flow::function_node<InputType, InputType> pass_thru( g, tbb::flow::unlimited, pass_through<InputType>()); + + // Create a vector of identical exe_nodes and pass_thrus + std::vector< tbb::flow::function_node< InputType, OutputType > > exe_vec(2, exe_node); + std::vector< tbb::flow::function_node< InputType, InputType > > pass_thru_vec(2, pass_thru); + // Attach each pass_thru to its corresponding exe_node + for (size_t node_idx=0; node_idx<exe_vec.size(); ++node_idx) { + tbb::flow::make_edge(pass_thru_vec[node_idx], exe_vec[node_idx]); + } + + // TODO: why the test is executed serially for the node pairs, not concurrently? + for (size_t node_idx=0; node_idx<exe_vec.size(); ++node_idx) { + // For num_receivers = 1 to MAX_NODES + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + // Create num_receivers counting receivers and connect the exe_vec[node_idx] to them. + std::vector< harness_mapped_receiver<OutputType>* > receivers(num_receivers); + for (size_t i = 0; i < num_receivers; i++) { + receivers[i] = new harness_mapped_receiver<OutputType>(g); + } + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( exe_vec[node_idx], *receivers[r] ); + } + + // Do the test with varying numbers of senders + harness_counting_sender<InputType> *senders = NULL; + for (size_t num_senders = 1; num_senders <= MAX_NODES; ++num_senders ) { + // Create num_senders senders, set there message limit each to N, and connect them to pass_thru_vec[node_idx] + senders = new harness_counting_sender<InputType>[num_senders]; + for (size_t s = 0; s < num_senders; ++s ) { + senders[s].my_limit = N; + senders[s].register_successor(pass_thru_vec[node_idx] ); + } + + // Initialize the receivers so they know how many senders and messages to check for + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->initialize_map( N, num_senders ); + } + + // Do the test + NativeParallelFor( (int)num_senders, parallel_put_until_limit<InputType>(senders) ); + g.wait_for_all(); + + // confirm that each sender was requested from N times + for (size_t s = 0; s < num_senders; ++s ) { + size_t n = senders[s].my_received; + ASSERT( n == N, NULL ); + ASSERT( senders[s].my_receiver == &pass_thru_vec[node_idx], NULL ); + } + // validate the receivers + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->validate(); + } + delete [] senders; + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( exe_vec[node_idx], *receivers[r] ); + } + ASSERT( exe_vec[node_idx].try_put( InputType() ) == true, NULL ); + g.wait_for_all(); + for (size_t r = 0; r < num_receivers; ++r ) { + // since it's detached, nothing should have changed + receivers[r]->validate(); + } + + for (size_t i = 0; i < num_receivers; i++) { + delete receivers[i]; + } + + } // for num_receivers + } // for node_idx + } // for concurrency level lc +} + +const size_t Offset = 123; +tbb::atomic<size_t> global_execute_count; + +struct inc_functor { + + tbb::atomic<size_t> local_execute_count; + inc_functor( ) { local_execute_count = 0; } + inc_functor( const inc_functor &f ) { local_execute_count = f.local_execute_count; } + void operator=( const inc_functor &f ) { local_execute_count = f.local_execute_count; } + + int operator()( int i ) { + ++global_execute_count; + ++local_execute_count; + return i; + } + +}; + +template< typename InputType, typename OutputType > +void buffered_levels_with_copy( size_t concurrency ) { + + // Do for lc = 1 to concurrency level + for ( size_t lc = 1; lc <= concurrency; ++lc ) { + tbb::flow::graph g; + + inc_functor cf; + cf.local_execute_count = Offset; + global_execute_count = Offset; + + tbb::flow::function_node< InputType, OutputType > exe_node( g, lc, cf ); + + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + + std::vector< harness_mapped_receiver<OutputType>* > receivers(num_receivers); + for (size_t i = 0; i < num_receivers; i++) { + receivers[i] = new harness_mapped_receiver<OutputType>(g); + } + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( exe_node, *receivers[r] ); + } + + harness_counting_sender<InputType> *senders = NULL; + for (size_t num_senders = 1; num_senders <= MAX_NODES; ++num_senders ) { + senders = new harness_counting_sender<InputType>[num_senders]; + for (size_t s = 0; s < num_senders; ++s ) { + senders[s].my_limit = N; + tbb::flow::make_edge( senders[s], exe_node ); + } + + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->initialize_map( N, num_senders ); + } + + NativeParallelFor( (int)num_senders, parallel_put_until_limit<InputType>(senders) ); + g.wait_for_all(); + + for (size_t s = 0; s < num_senders; ++s ) { + size_t n = senders[s].my_received; + ASSERT( n == N, NULL ); + ASSERT( senders[s].my_receiver == &exe_node, NULL ); + } + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->validate(); + } + delete [] senders; + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( exe_node, *receivers[r] ); + } + ASSERT( exe_node.try_put( InputType() ) == true, NULL ); + g.wait_for_all(); + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->validate(); + } + + for (size_t i = 0; i < num_receivers; i++) { + delete receivers[i]; + } + } + + // validate that the local body matches the global execute_count and both are correct + inc_functor body_copy = tbb::flow::copy_body<inc_functor>( exe_node ); + const size_t expected_count = N/2 * MAX_NODES * MAX_NODES * ( MAX_NODES + 1 ) + MAX_NODES + Offset; + size_t global_count = global_execute_count; + size_t inc_count = body_copy.local_execute_count; + ASSERT( global_count == expected_count && global_count == inc_count, NULL ); + g.reset(tbb::flow::rf_reset_bodies); + body_copy = tbb::flow::copy_body<inc_functor>( exe_node ); + inc_count = body_copy.local_execute_count; + ASSERT( Offset == inc_count, "reset(rf_reset_bodies) did not reset functor" ); + } +} + +template< typename InputType, typename OutputType > +void run_buffered_levels( int c ) { + #if __TBB_CPP11_LAMBDAS_PRESENT + buffered_levels<InputType,OutputType>( c, []( InputType i ) -> OutputType { return harness_graph_executor<InputType, OutputType>::func(i); } ); + #endif + buffered_levels<InputType,OutputType>( c, &harness_graph_executor<InputType, OutputType>::func ); + buffered_levels<InputType,OutputType>( c, typename harness_graph_executor<InputType, OutputType>::functor() ); + buffered_levels_with_copy<InputType,OutputType>( c ); +} + + +//! Performs test on executable nodes with limited concurrency +/** These tests check: + 1) that the nodes will accepts puts up to the concurrency limit, + 2) the nodes do not exceed the concurrency limit even when run with more threads (this is checked in the harness_graph_executor), + 3) the nodes will receive puts from multiple successors simultaneously, + and 4) the nodes will send to multiple predecessors. + There is no checking of the contents of the messages for corruption. +*/ + +template< typename InputType, typename OutputType, typename Body > +void concurrency_levels( size_t concurrency, Body body ) { + + for ( size_t lc = 1; lc <= concurrency; ++lc ) { + tbb::flow::graph g; + + // Set the execute_counter back to zero in the harness + harness_graph_executor<InputType, OutputType>::execute_count = 0; + // Set the number of current executors to zero. + harness_graph_executor<InputType, OutputType>::current_executors = 0; + // Set the max allowed executors to lc. There is a check in the functor to make sure this is never exceeded. + harness_graph_executor<InputType, OutputType>::max_executors = lc; + + typedef tbb::flow::function_node< InputType, OutputType, tbb::flow::rejecting > fnode_type; + fnode_type exe_node( g, lc, body ); + + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + + std::vector< harness_counting_receiver<OutputType> > receivers(num_receivers, harness_counting_receiver<OutputType>(g)); + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(exe_node.successor_count() == 0, NULL); + ASSERT(exe_node.predecessor_count() == 0, NULL); +#endif + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( exe_node, receivers[r] ); + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(exe_node.successor_count() == num_receivers, NULL); + typename fnode_type::successor_list_type my_succs; + exe_node.copy_successors(my_succs); + ASSERT(my_succs.size() == num_receivers, NULL); + typename fnode_type::predecessor_list_type my_preds; + exe_node.copy_predecessors(my_preds); + ASSERT(my_preds.size() == 0, NULL); +#endif + + harness_counting_sender<InputType> *senders = NULL; + + for (size_t num_senders = 1; num_senders <= MAX_NODES; ++num_senders ) { + senders = new harness_counting_sender<InputType>[num_senders]; + { + // Exclusively lock m to prevent exe_node from finishing + tbb::spin_rw_mutex::scoped_lock l( harness_graph_executor<InputType, OutputType>::template mutex_holder<tbb::spin_rw_mutex>::mutex ); + + // put to lc level, it will accept and then block at m + for ( size_t c = 0 ; c < lc ; ++c ) { + ASSERT( exe_node.try_put( InputType() ) == true, NULL ); + } + // it only accepts to lc level + ASSERT( exe_node.try_put( InputType() ) == false, NULL ); + + for (size_t s = 0; s < num_senders; ++s ) { + // register a sender + senders[s].my_limit = N; + exe_node.register_predecessor( senders[s] ); + } + + } // release lock at end of scope, setting the exe node free to continue + // wait for graph to settle down + g.wait_for_all(); + + // confirm that each sender was requested from N times + for (size_t s = 0; s < num_senders; ++s ) { + size_t n = senders[s].my_received; + ASSERT( n == N, NULL ); + ASSERT( senders[s].my_receiver == &exe_node, NULL ); + } + // confirm that each receivers got N * num_senders + the initial lc puts + for (size_t r = 0; r < num_receivers; ++r ) { + size_t n = receivers[r].my_count; + ASSERT( n == num_senders*N+lc, NULL ); + receivers[r].my_count = 0; + } + delete [] senders; + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( exe_node, receivers[r] ); + } + ASSERT( exe_node.try_put( InputType() ) == true, NULL ); + g.wait_for_all(); + for (size_t r = 0; r < num_receivers; ++r ) { + ASSERT( int(receivers[r].my_count) == 0, NULL ); + } + } + } +} + + +template< typename InputType, typename OutputType > +void run_concurrency_levels( int c ) { + #if __TBB_CPP11_LAMBDAS_PRESENT + concurrency_levels<InputType,OutputType>( c, []( InputType i ) -> OutputType { return harness_graph_executor<InputType, OutputType>::template tfunc<tbb::spin_rw_mutex>(i); } ); + #endif + concurrency_levels<InputType,OutputType>( c, &harness_graph_executor<InputType, OutputType>::template tfunc<tbb::spin_rw_mutex> ); + concurrency_levels<InputType,OutputType>( c, typename harness_graph_executor<InputType, OutputType>::template tfunctor<tbb::spin_rw_mutex>() ); +} + + +struct empty_no_assign { + empty_no_assign() {} + empty_no_assign( int ) {} + operator int() { return 0; } +}; + +template< typename InputType > +struct parallel_puts : private NoAssign { + + tbb::flow::receiver< InputType > * const my_exe_node; + + parallel_puts( tbb::flow::receiver< InputType > &exe_node ) : my_exe_node(&exe_node) {} + + void operator()( int ) const { + for ( int i = 0; i < N; ++i ) { + // the nodes will accept all puts + ASSERT( my_exe_node->try_put( InputType() ) == true, NULL ); + } + } + +}; + +//! Performs test on executable nodes with unlimited concurrency +/** These tests check: + 1) that the nodes will accept all puts + 2) the nodes will receive puts from multiple predecessors simultaneously, + and 3) the nodes will send to multiple successors. + There is no checking of the contents of the messages for corruption. +*/ + +template< typename InputType, typename OutputType, typename Body > +void unlimited_concurrency( Body body ) { + + for (int p = 1; p < 2*MaxThread; ++p) { + tbb::flow::graph g; + tbb::flow::function_node< InputType, OutputType, tbb::flow::rejecting > exe_node( g, tbb::flow::unlimited, body ); + + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + + std::vector< harness_counting_receiver<OutputType> > receivers(num_receivers, harness_counting_receiver<OutputType>(g)); + harness_graph_executor<InputType, OutputType>::execute_count = 0; + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( exe_node, receivers[r] ); + } + + NativeParallelFor( p, parallel_puts<InputType>(exe_node) ); + g.wait_for_all(); + + // 2) the nodes will receive puts from multiple predecessors simultaneously, + size_t ec = harness_graph_executor<InputType, OutputType>::execute_count; + ASSERT( (int)ec == p*N, NULL ); + for (size_t r = 0; r < num_receivers; ++r ) { + size_t c = receivers[r].my_count; + // 3) the nodes will send to multiple successors. + ASSERT( (int)c == p*N, NULL ); + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( exe_node, receivers[r] ); + } + } + } + } + +template< typename InputType, typename OutputType > +void run_unlimited_concurrency() { + harness_graph_executor<InputType, OutputType>::max_executors = 0; + #if __TBB_CPP11_LAMBDAS_PRESENT + unlimited_concurrency<InputType,OutputType>( []( InputType i ) -> OutputType { return harness_graph_executor<InputType, OutputType>::func(i); } ); + #endif + unlimited_concurrency<InputType,OutputType>( &harness_graph_executor<InputType, OutputType>::func ); + unlimited_concurrency<InputType,OutputType>( typename harness_graph_executor<InputType, OutputType>::functor() ); +} + +struct continue_msg_to_int { + int my_int; + continue_msg_to_int(int x) : my_int(x) {} + int operator()(tbb::flow::continue_msg) { return my_int; } +}; + +void test_function_node_with_continue_msg_as_input() { + // If this function terminates, then this test is successful + tbb::flow::graph g; + + tbb::flow::broadcast_node<tbb::flow::continue_msg> Start(g); + + tbb::flow::function_node<tbb::flow::continue_msg, int, tbb::flow::rejecting> FN1( g, tbb::flow::serial, continue_msg_to_int(42)); + tbb::flow::function_node<tbb::flow::continue_msg, int, tbb::flow::rejecting> FN2( g, tbb::flow::serial, continue_msg_to_int(43)); + + tbb::flow::make_edge( Start, FN1 ); + tbb::flow::make_edge( Start, FN2 ); + + Start.try_put( tbb::flow::continue_msg() ); + g.wait_for_all(); +} + +//! Tests limited concurrency cases for nodes that accept data messages +void test_concurrency(int num_threads) { + tbb::task_scheduler_init init(num_threads); + run_concurrency_levels<int,int>(num_threads); + run_concurrency_levels<int,tbb::flow::continue_msg>(num_threads); + run_buffered_levels<int, int>(num_threads); + run_unlimited_concurrency<int,int>(); + run_unlimited_concurrency<int,empty_no_assign>(); + run_unlimited_concurrency<empty_no_assign,int>(); + run_unlimited_concurrency<empty_no_assign,empty_no_assign>(); + run_unlimited_concurrency<int,tbb::flow::continue_msg>(); + run_unlimited_concurrency<empty_no_assign,tbb::flow::continue_msg>(); + test_function_node_with_continue_msg_as_input(); +} + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +struct add_to_counter { + int* counter; + add_to_counter(int& var):counter(&var){} + int operator()(int i){*counter+=1; return i + 1;} +}; + +template<typename FTYPE> +void test_extract() { + int my_count = 0; + int cm; + tbb::flow::graph g; + tbb::flow::broadcast_node<int> b0(g); + tbb::flow::broadcast_node<int> b1(g); + tbb::flow::function_node<int, int, FTYPE> f0(g, tbb::flow::unlimited, add_to_counter(my_count)); + tbb::flow::queue_node<int> q0(g); + + tbb::flow::make_edge(b0, f0); + tbb::flow::make_edge(b1, f0); + tbb::flow::make_edge(f0, q0); + for( int i = 0; i < 2; ++i ) { + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 1, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 1, "b1 has incorrect counts"); + ASSERT(f0.predecessor_count() == 2 && f0.successor_count() == 1, "f0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 1 && q0.successor_count() == 0, "q0 has incorrect counts"); + + /* b0 */ + /* \ */ + /* f0 - q0 */ + /* / */ + /* b1 */ + + b0.try_put(1); + g.wait_for_all(); + ASSERT(my_count == 1, "function_node didn't fire"); + ASSERT(q0.try_get(cm), "function_node didn't forward"); + b1.try_put(1); + g.wait_for_all(); + ASSERT(my_count == 2, "function_node didn't fire"); + ASSERT(q0.try_get(cm), "function_node didn't forward"); + + b0.extract(); + + /* b0 */ + /* */ + /* f0 - q0 */ + /* / */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 0, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 1, "b1 has incorrect counts"); + ASSERT(f0.predecessor_count() == 1 && f0.successor_count() == 1, "f0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 1 && q0.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(1); + b0.try_put(1); + g.wait_for_all(); + ASSERT(my_count == 2, "b0 messages being forwarded to function_node even though it is disconnected"); + b1.try_put(1); + g.wait_for_all(); + ASSERT(my_count == 3, "function_node didn't fire though it has only one predecessor"); + ASSERT(q0.try_get(cm), "function_node didn't forward second time"); + + f0.extract(); + + /* b0 */ + /* */ + /* f0 q0 */ + /* */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 0, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 0, "b1 has incorrect counts"); + ASSERT(f0.predecessor_count() == 0 && f0.successor_count() == 0, "f0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 0 && q0.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(1); + b0.try_put(1); + b1.try_put(1); + b1.try_put(1); + g.wait_for_all(); + ASSERT(my_count == 3, "function_node didn't fire though it has only one predecessor"); + ASSERT(!q0.try_get(cm), "function_node forwarded though it shouldn't"); + make_edge(b0, f0); + + /* b0 */ + /* \ */ + /* f0 q0 */ + /* */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 1, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 0, "b1 has incorrect counts"); + ASSERT(f0.predecessor_count() == 1 && f0.successor_count() == 0, "f0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 0 && q0.successor_count() == 0, "q0 has incorrect counts"); + + b0.try_put(int()); + g.wait_for_all(); + + ASSERT(my_count == 4, "function_node didn't fire though it has only one predecessor"); + ASSERT(!q0.try_get(cm), "function_node forwarded though it shouldn't"); + + tbb::flow::make_edge(b1, f0); + tbb::flow::make_edge(f0, q0); + my_count = 0; + } +} +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + using msg_t = tbb::flow::continue_msg; + + std::array<msg_t, 3> messages_for_follows = { {msg_t(), msg_t(), msg_t()} }; + std::vector<msg_t> messages_for_precedes = { msg_t() }; + + pass_through<msg_t> pass_msg; + + follows_and_precedes_testing::test_follows + <msg_t, tbb::flow::function_node<msg_t, msg_t>> + (messages_for_follows, tbb::flow::unlimited, pass_msg); + follows_and_precedes_testing::test_precedes + <msg_t, tbb::flow::function_node<msg_t, msg_t>> + (messages_for_precedes, tbb::flow::unlimited, pass_msg); +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +int function_body_f(const int&) { return 1; } + +template <typename Body> +void test_deduction_guides_common(Body body) { + using namespace tbb::flow; + graph g; + + function_node f1(g, unlimited, body); + static_assert(std::is_same_v<decltype(f1), function_node<int, int>>); + + function_node f2(g, unlimited, body, rejecting()); + static_assert(std::is_same_v<decltype(f2), function_node<int, int, rejecting>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + function_node f3(g, unlimited, body, node_priority_t(5)); + static_assert(std::is_same_v<decltype(f3), function_node<int, int>>); + + function_node f4(g, unlimited, body, rejecting(), node_priority_t(5)); + static_assert(std::is_same_v<decltype(f4), function_node<int, int, rejecting>>); +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + function_node f5(follows(f2), unlimited, body); + static_assert(std::is_same_v<decltype(f5), function_node<int, int>>); + + function_node f6(follows(f5), unlimited, body, rejecting()); + static_assert(std::is_same_v<decltype(f6), function_node<int, int, rejecting>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES + function_node f7(follows(f6), unlimited, body, node_priority_t(5)); + static_assert(std::is_same_v<decltype(f7), function_node<int, int>>); + + function_node f8(follows(f7), unlimited, body, rejecting(), node_priority_t(5)); + static_assert(std::is_same_v<decltype(f8), function_node<int, int, rejecting>>); +#endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + + function_node f9(f1); + static_assert(std::is_same_v<decltype(f9), function_node<int, int>>); +} + +void test_deduction_guides() { + test_deduction_guides_common([](const int&)->int { return 1; }); + test_deduction_guides_common([](const int&) mutable ->int { return 1; }); + test_deduction_guides_common(function_body_f); +} + +#endif + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +void test_node_allocator(){ + tbb::flow::graph g; + tbb::flow::function_node< int, int, tbb::flow::queueing, std::allocator<int> > tmp( + g, tbb::flow::unlimited, pass_through<int>() + ); +} +#endif + +int TestMain() { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + test_concurrency(p); + } + lightweight_testing::test<tbb::flow::function_node>(10); +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract<tbb::flow::rejecting>(); + test_extract<tbb::flow::queueing>(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + test_node_allocator(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_global_control.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_global_control.cpp new file mode 100644 index 00000000..56acf7dc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_global_control.cpp @@ -0,0 +1,793 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_PREVIEW_WAITING_FOR_WORKERS 1 +#include "tbb/global_control.h" +#include "harness.h" +#include "tbb/task_scheduler_observer.h" + +const size_t MB = 1024*1024; +const double BARRIER_TIMEOUT = 10.; + +void TestStackSizeSimpleControl() +{ + { + tbb::global_control s0(tbb::global_control::thread_stack_size, 1*MB); + + { + tbb::global_control s1(tbb::global_control::thread_stack_size, 8*MB); + + ASSERT(8*MB == tbb::global_control::active_value(tbb::global_control::thread_stack_size), NULL); + } + ASSERT(1*MB == tbb::global_control::active_value(tbb::global_control::thread_stack_size), NULL); + } +} + +#include "harness_concurrency_tracker.h" +#include "tbb/task_scheduler_init.h" +#include <limits.h> // for UINT_MAX + +struct StackSizeRun: NoAssign { + int num_threads; + Harness::SpinBarrier *barr1, *barr2; + + StackSizeRun(int threads, Harness::SpinBarrier *b1, Harness::SpinBarrier *b2) : + num_threads(threads), barr1(b1), barr2(b2) {} + void operator()( int id ) const { + tbb::global_control s1(tbb::global_control::thread_stack_size, (1+id)*MB); + + barr1->timed_wait(BARRIER_TIMEOUT); + + ASSERT(num_threads*MB == tbb::global_control::active_value(tbb::global_control::thread_stack_size), NULL); + barr2->timed_wait(BARRIER_TIMEOUT); + } +}; + +void TestStackSizeThreadsControl() +{ + int threads = 4; + Harness::SpinBarrier barr1(threads), barr2(threads); + NativeParallelFor( threads, StackSizeRun(threads, &barr1, &barr2) ); +} + +void RunWorkersLimited(int tsi_max_threads, size_t parallelism, bool wait) +{ + tbb::global_control s(tbb::global_control::max_allowed_parallelism, parallelism); + // try both configuration with already sleeping workers and with not yet sleeping + if (wait) + Harness::Sleep(100); + const size_t expected_threads = tsi_max_threads>0? + min( (unsigned)tsi_max_threads, parallelism ) + : ( tbb::tbb_thread::hardware_concurrency()==1? 1 : parallelism ); + Harness::ExactConcurrencyLevel::check(expected_threads); +} + +class blocking_task_scheduler_init { + tbb::task_scheduler_init init; +public: + blocking_task_scheduler_init(int num_threads = tbb::task_scheduler_init::automatic) : init(num_threads) {} + ~blocking_task_scheduler_init() { + bool ok = init.blocking_terminate(std::nothrow); + ASSERT(ok, "blocking_terminate has failed"); + } +}; + +void TSI_and_RunWorkers(int tsi_max_threads, size_t parallelism, size_t max_value) +{ + blocking_task_scheduler_init tsi(tsi_max_threads); + size_t active = tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism); + ASSERT(active == max(2U, max_value), "active_value must not be changed by task_scheduler_init"); + RunWorkersLimited(tsi_max_threads, parallelism, /*wait=*/false); +} + +#include "tbb/tbb_thread.h" + +void TestWorkers(size_t curr_par) +{ + const size_t max_parallelism = + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism); + ASSERT(max(2U, tbb::tbb_thread::hardware_concurrency()) == max_parallelism, NULL); + { + const unsigned h_c = tbb::tbb_thread::hardware_concurrency(); + tbb::global_control c(tbb::global_control::max_allowed_parallelism, curr_par); + size_t v = tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism); + ASSERT(!curr_par || max((size_t)2, curr_par) == v, NULL); + if (h_c > 1) + TSI_and_RunWorkers(tbb::task_scheduler_init::automatic, min(h_c, curr_par), curr_par); + if (curr_par) // do not call task_scheduler_init t(0); + TSI_and_RunWorkers((int)curr_par, curr_par, curr_par); + if (curr_par > 2) { // check that min(tsi, parallelism) is active + TSI_and_RunWorkers((int)curr_par-1, curr_par, curr_par); + TSI_and_RunWorkers((int)curr_par, curr_par-1, curr_par); + } + // check constrains on control's value: it can't be increased + tbb::global_control c1(tbb::global_control::max_allowed_parallelism, curr_par+1); + v = tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism); + if (curr_par) + ASSERT(max(2U, curr_par) == v, "It's impossible to increase maximal parallelism."); + else + ASSERT(2 == v, NULL); + } + ASSERT(tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism) + == max_parallelism, + "max parallelism has been restored successfully after decreasing/increasing"); +} + +void TestWorkersConstraints() { + const size_t max_parallelism = + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism); + blocking_task_scheduler_init tsi; + if (max_parallelism > 3) { + tbb::global_control c(tbb::global_control::max_allowed_parallelism, max_parallelism-1); + ASSERT(max_parallelism-1 == + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism), + "Allowed parallelism must be decreasable."); + tbb::global_control c1(tbb::global_control::max_allowed_parallelism, max_parallelism-2); + ASSERT(max_parallelism-2 == + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism), + "Allowed parallelism must be decreasable."); + } + const size_t limit_par = min(max_parallelism, 4U); + // check that constrains are really met + for (int wait=0; wait<2; wait++) { + for (size_t num=2; num<limit_par; num++) + RunWorkersLimited(tbb::task_scheduler_init::automatic, num, wait==1); + for (size_t num=limit_par; num>1; num--) + RunWorkersLimited(tbb::task_scheduler_init::automatic, num, wait==1); + } +} + +struct DummyBody { + void operator()(int) const { + __TBB_Pause(1); + } +}; + +void RunParallelWork() { + const int LOOP_ITERS = 10*1000; + tbb::parallel_for(0, LOOP_ITERS, DummyBody(), tbb::simple_partitioner()); +} + +struct SetUseRun: NoAssign { + Harness::SpinBarrier *barr; + + SetUseRun(Harness::SpinBarrier *b) : barr(b) {} + void operator()( int id ) const { + if (id == 0) { + for (int i=0; i<10; i++) { + blocking_task_scheduler_init tsi; + RunParallelWork(); + barr->timed_wait(BARRIER_TIMEOUT); + } + } else { + for (int i=0; i<10; i++) { + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 8); + barr->timed_wait(BARRIER_TIMEOUT); + } + } + } +}; + +void TestConcurrentSetUseConcurrency() +{ + Harness::SpinBarrier barr(2); + NativeParallelFor( 2, SetUseRun(&barr) ); +} + +// check number of workers after autoinitialization +void TestAutoInit() +{ + const size_t max_parallelism = + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism); + const unsigned expected_threads = tbb::tbb_thread::hardware_concurrency()==1? + 1 : (unsigned)max_parallelism; + Harness::ExactConcurrencyLevel::check(expected_threads); + ASSERT(tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism) + == max_parallelism, "max_allowed_parallelism must not be changed after auto init"); + if (max_parallelism > 2) { + // after autoinit it's possible to decrease workers number + tbb::global_control s(tbb::global_control::max_allowed_parallelism, max_parallelism-1); + Harness::ExactConcurrencyLevel::check(max_parallelism-1); + } +} + +// need this to use TRY_BAD_EXPR_ENABLED when TBB_USE_ASSERT is not defined +#undef TBB_USE_ASSERT +#define TBB_USE_ASSERT 1 + +#include "harness_bad_expr.h" + +void TestInvalidParallelism() +{ +#if TRY_BAD_EXPR_ENABLED + const size_t max_parallelism = + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism); + { + tbb::set_assertion_handler( AssertionFailureHandler ); + TRY_BAD_EXPR( tbb::global_control c(tbb::global_control::max_allowed_parallelism, 0), + "max_allowed_parallelism cannot be 0." ); + tbb::set_assertion_handler( ReportError ); + ASSERT(tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism) + == max_parallelism, NULL); + } + { + const size_t P = 2; + tbb::global_control c(tbb::global_control::max_allowed_parallelism, P); + ASSERT(tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism) + == P, NULL); + tbb::set_assertion_handler( AssertionFailureHandler ); + TRY_BAD_EXPR( tbb::global_control cZ(tbb::global_control::max_allowed_parallelism, 0), + "max_allowed_parallelism cannot be 0." ); + tbb::set_assertion_handler( ReportError ); + ASSERT(tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism) + == P, NULL); + } + ASSERT(tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism) + == max_parallelism, NULL); +#endif /* TRY_BAD_EXPR_ENABLED */ +} + +void TestTooBigStack() +{ +#if __TBB_x86_32 + const size_t stack_sizes[] = {512*MB, 2*1024*MB, UINT_MAX}; +#else + const size_t stack_sizes[] = {512*MB, 2*1024*MB, UINT_MAX, 10LU*1024*MB}; +#endif + +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) + size_t default_ss = tbb::global_control::active_value(tbb::global_control::thread_stack_size); +#endif + for (unsigned i = 0; i<Harness::array_length(stack_sizes); i++) { + // No stack size setting for Windows 8 Store* apps, skip it +#if TRY_BAD_EXPR_ENABLED && __TBB_x86_64 && (_WIN32 || _WIN64) && !(__TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00)) + if (stack_sizes[i] != (unsigned)stack_sizes[i]) { + size_t curr_ss = tbb::global_control::active_value(tbb::global_control::thread_stack_size); + tbb::set_assertion_handler( AssertionFailureHandler ); + TRY_BAD_EXPR( tbb::global_control s1(tbb::global_control::thread_stack_size, stack_sizes[i]), "Stack size is limited to unsigned int range" ); + tbb::set_assertion_handler( ReportError ); + ASSERT(curr_ss == tbb::global_control::active_value(tbb::global_control::thread_stack_size), "Changing of stack size is not expected."); + continue; + } +#endif + tbb::global_control s1(tbb::global_control::thread_stack_size, stack_sizes[i]); + size_t actual_stack_sz = tbb::global_control::active_value(tbb::global_control::thread_stack_size); +#if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00) + ASSERT(actual_stack_sz == default_ss, "It's ignored for Windows 8.x Store* apps"); +#else + ASSERT(actual_stack_sz==stack_sizes[i], NULL); +#endif + } +} + +struct ParallelForRun: NoAssign { + int num_threads; + Harness::SpinBarrier *barr1, *barr2; + + ParallelForRun(Harness::SpinBarrier *b1, Harness::SpinBarrier *b2) : + barr1(b1), barr2(b2) {} + void operator()( int /*id*/ ) const { + barr1->timed_wait(BARRIER_TIMEOUT); + RunParallelWork(); + barr2->timed_wait(BARRIER_TIMEOUT); + } +}; + +class FFTask: public tbb::task { + tbb::atomic<int> *counter; + tbb::task* execute() __TBB_override { + (*counter)++; + return NULL; + } +public: + FFTask(tbb::atomic<int> *counter_) : counter(counter_) {} +}; + +class WaiterTask: public tbb::task { + tbb::atomic<bool> *flag; + tbb::task* execute() __TBB_override { + while(!*flag) + __TBB_Yield(); + return NULL; + } +public: + WaiterTask(tbb::atomic<bool> *flag_) : flag(flag_) {} +}; + +class WorkAndEnqueueTask: public tbb::task { + tbb::atomic<int> *counter; + tbb::atomic<bool> *signalToLeave; + tbb::task* execute() __TBB_override { + RunParallelWork(); + *signalToLeave = true; + for (int i=0; i<ENQUEUE_TASKS; i++) { + FFTask* t = new( tbb::task::allocate_root() ) FFTask(counter); + tbb::task::enqueue(*t); + } + + return NULL; + } +public: + static const int ENQUEUE_TASKS = 10; + WorkAndEnqueueTask(tbb::atomic<int> *counter_, tbb::atomic<bool> *signal_) + : counter(counter_), signalToLeave(signal_) {} +}; + +#if __TBB_TASK_PRIORITY +tbb::priority_t getPriorityByInt(int i) { + return i%3==0? tbb::priority_low : (i%3==1? tbb::priority_normal : + tbb::priority_high); +} +#endif + +class FFTasksRun: NoAssign { + void enqTasks(int id) const { + for (int i=0; i<ITERS; i++) { + FFTask* t = new( tbb::task::allocate_root() ) FFTask(cnt); +#if __TBB_TASK_PRIORITY + tbb::priority_t p = getPriorityByInt(i+id); + tbb::task::enqueue(*t, p); +#else + tbb::internal::suppress_unused_warning(id); + tbb::task::enqueue(*t); +#endif + } + } +public: + static const int ITERS = 20; + Harness::SpinBarrier *barr; + tbb::atomic<int> *cnt; + + FFTasksRun(Harness::SpinBarrier *b, tbb::atomic<int> *c) : + barr(b), cnt(c) {} + void operator()(int id) const { + if (id) + enqTasks(id); + barr->wait(); + if (!id) + enqTasks(id); + } +}; + +void TestTaskEnqueue() +{ + { + blocking_task_scheduler_init tsi(20); + tbb::atomic<int> flag; + tbb::atomic<bool> taskDoneFlag; + flag = 0; + taskDoneFlag = false; + + for (int i=0; i<10; i++) { + WaiterTask* w = new( tbb::task::allocate_root() ) WaiterTask(&taskDoneFlag); + tbb::task::enqueue(*w); + } + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + taskDoneFlag = true; + + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&flag); + tbb::task::enqueue(*t); + while(!flag) + __TBB_Yield(); + } + { + blocking_task_scheduler_init tsi(1); + tbb::atomic<int> flag; + tbb::atomic<bool> taskDoneFlag; + flag = 0; + taskDoneFlag = false; + + WaiterTask* w = new( tbb::task::allocate_root() ) WaiterTask(&taskDoneFlag); + tbb::task::enqueue(*w); + taskDoneFlag = true; + + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&flag); + tbb::task::enqueue(*t); + while(!flag) + __TBB_Yield(); + } + { + blocking_task_scheduler_init tsi(2); + tbb::atomic<int> flag; + flag = 0; + + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&flag); + tbb::task::enqueue(*t); + while(!flag) + __TBB_Yield(); + } + { + blocking_task_scheduler_init tsi(2); + tbb::atomic<int> flag; + flag = 0; + + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&flag); + tbb::task::enqueue(*t); + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + + while(!flag) + __TBB_Yield(); + } + + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + + { // check that enqueue() guarantee mandatory parallelism + blocking_task_scheduler_init tsi(1); + tbb::atomic<int> flag; + flag = 0; + + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&flag); + tbb::task::enqueue(*t); + while(!flag) + __TBB_Yield(); + } + { + tbb::atomic<int> flag; + flag = 0; + { + blocking_task_scheduler_init tsi(1); + + for (int i=0; i<10; i++) { + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&flag); +#if __TBB_TASK_PRIORITY + const tbb::priority_t p = getPriorityByInt(i); + tbb::task::enqueue(*t, p); +#else + tbb::task::enqueue(*t); +#endif + } + } + ASSERT(flag==10, "The tasks must be terminated when task_scheduler_init destroyed."); + } + const unsigned threads = 2; + { + blocking_task_scheduler_init tsi(1); + Harness::SpinBarrier barr1(threads), barr2(threads); + RunWorkersLimited(1, 1, false); + + NativeParallelFor( threads, ParallelForRun(&barr1, &barr2) ); + } + + tbb::atomic<int> counter; + counter = 0; + { + blocking_task_scheduler_init tsi(1); + Harness::SpinBarrier barr(threads); + RunWorkersLimited(1, 1, false); + + NativeParallelFor( threads, FFTasksRun(&barr, &counter) ); + } + ASSERT(counter == threads*FFTasksRun::ITERS, "All tasks must be done when task_scheduler_init destroyed."); + counter = 0; + { // an enqueued task can enqueue other tasks and calls parallel_for + tbb::atomic<bool> signalToLeave; + blocking_task_scheduler_init tsi(1); + + signalToLeave = false; + WorkAndEnqueueTask *t = new( tbb::task::allocate_root() ) + WorkAndEnqueueTask(&counter, &signalToLeave); + tbb::task::enqueue(*t); + RunParallelWork(); + + while (!signalToLeave) + __TBB_Yield(); + } + ASSERT(counter == WorkAndEnqueueTask::ENQUEUE_TASKS, "All tasks must be done when task_scheduler_init destroyed."); +} + +class CountWorkersTask: public tbb::task { + tbb::atomic<bool> *flag; + // count unique worker threads + static tbb::combinable<size_t> uniqThreads; + + tbb::task* execute() __TBB_override { + uniqThreads.local() = 1; + Harness::Sleep(10); + *flag = 1; + return NULL; + } +public: + CountWorkersTask(tbb::atomic<bool> *flag_) : flag(flag_) {} + static size_t observedThreads() { + return uniqThreads.combine(std::plus<size_t>()); + } +}; + +tbb::combinable<size_t> CountWorkersTask::uniqThreads; + +tbb::atomic<int> activeArenas; + +class ArenaObserver: public tbb::task_scheduler_observer { +public: + ArenaObserver() : tbb::task_scheduler_observer(/*local=*/true) { + } + void on_scheduler_entry( bool worker ) __TBB_override { + if (worker) { + ++activeArenas; + } + } + void on_scheduler_exit( bool worker ) __TBB_override { + if (worker) { + --activeArenas; + } + } +}; + +ArenaObserver observers[2]; + +struct ArenasObserveRun: NoAssign { + Harness::SpinBarrier *barr; + + ArenasObserveRun(Harness::SpinBarrier *b) : barr(b) {} + void operator()( int id ) const { + observers[id].observe(true); + ArenaObserver o; + tbb::atomic<bool> flag; + flag = false; + + CountWorkersTask* t = new( tbb::task::allocate_root() ) + CountWorkersTask(&flag); + barr->wait(); + tbb::task::enqueue(*t); + while(!flag) + __TBB_Yield(); + } +}; + +struct ArenaRun: NoAssign { + tbb::atomic<int> *counter; + + ArenaRun(tbb::atomic<int> *counter_) : counter(counter_) {} + void operator()() const { + (*counter)++; + } +}; + +struct ArenaUserRun: NoAssign { + static const int ENQUEUE_TASKS = 10; + tbb::task_arena *arena; + Harness::SpinBarrier *barr; + tbb::atomic<int> *counter; + + ArenaUserRun(tbb::task_arena *a, Harness::SpinBarrier *b, tbb::atomic<int> *c) : + arena(a), barr(b), counter(c) {} + void operator()( int id ) const { + + for (int i=0; i<ENQUEUE_TASKS; i++) + arena->enqueue(ArenaRun(counter)); + barr->wait(); + if (!id) + arena->terminate(); + } +}; + +void TestConcurrentArenas() +{ + Harness::SpinBarrier barrier(2); + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + { + blocking_task_scheduler_init tsi(2); + ArenaObserver observer; + observer.observe(true); + + Harness::ExactConcurrencyLevel::check(1); // must have 0 worker threads + + NativeParallelFor( 2, ArenasObserveRun(&barrier) ); + ASSERT(1 == CountWorkersTask::observedThreads(), + "Single worker is expecting to serve mandatory parallelism."); + while(activeArenas) // wait till single worker termination + __TBB_Yield(); + + // check that without mandatory parallelism, still have 0 worker threads + Harness::ExactConcurrencyLevel::check(1); + } + tbb::atomic<int> counter; + counter = 0; + { + blocking_task_scheduler_init tsi(1); + tbb::task_arena arena(2); + + NativeParallelFor( 2, ArenaUserRun(&arena, &barrier, &counter) ); + } + ASSERT(counter == 2*ArenaUserRun::ENQUEUE_TASKS, "All tasks must be done."); +} + +void TestParallelismRestored() +{ + const int TASKS = 5; + tbb::atomic<int> counter; + counter = 0; + { + const int P = 4; + blocking_task_scheduler_init tsi(P); + { + ASSERT(tbb::this_task_arena::max_concurrency() == P, NULL); + tbb::global_control s(tbb::global_control::max_allowed_parallelism, 1); + Harness::ExactConcurrencyLevel::check(1); + // create enforced concurrency in the arena + for (int i=0; i<TASKS; i++) { + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&counter); + tbb::task::enqueue(*t); + } + ASSERT(tbb::this_task_arena::max_concurrency() == P, NULL); + } + ASSERT(tbb::this_task_arena::max_concurrency() == P, NULL); + // global control is off, check that concurrency P is available + Harness::ExactConcurrencyLevel::check(P); + } + ASSERT(counter==TASKS, "The tasks must be executed at this point."); +} + +class NoUnwantedEnforcedRun { + Harness::SpinBarrier *globalBarrier; +public: + NoUnwantedEnforcedRun(Harness::SpinBarrier *b) : globalBarrier(b) {} + void operator()( int id ) const { + Harness::SpinBarrier barr(1); + + tbb::combinable<size_t> uniqThreads; + Harness::ExactConcurrencyLevel::check(1); + globalBarrier->wait(); + if (id) { + for (int i=0; i<20; i++) { + Harness::ExactConcurrencyLevel::check(1); // no workers expected in the thread + } + } else { + // create enforced concurrency in a separate thread, thus provoke enforced worker without + // work to do to join arena with parallel_for + for (int i=0; i<10; i++) { + tbb::atomic<int> flag; + flag = 0; + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&flag); + tbb::task::enqueue(*t); + Harness::ExactConcurrencyLevel::checkLessOrEqual(2, &uniqThreads); + size_t seen = uniqThreads.combine(std::plus<size_t>()); + ASSERT(seen==1 || seen==2, NULL); + while(!flag) + __TBB_Yield(); + } + } + } +}; + +// test that enforced concurrency from one thread doesn't affect another +void TestNoUnwantedEnforced() +{ + Harness::SpinBarrier barrier(2); + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + blocking_task_scheduler_init tsi(4); + NativeParallelFor( 2, NoUnwantedEnforcedRun(&barrier) ); +} + +class TestMultipleControlsRun { + Harness::SpinBarrier *barrier; +public: + TestMultipleControlsRun(Harness::SpinBarrier *b) : barrier(b) {} + void operator()( int id ) const { + barrier->wait(); + if (id) { + { + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + Harness::ExactConcurrencyLevel::check(1); + barrier->wait(); + } + Harness::ExactConcurrencyLevel::check(1); + barrier->wait(); + { + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 2); + Harness::ExactConcurrencyLevel::check(1); + barrier->wait(); + Harness::ExactConcurrencyLevel::check(2); + barrier->wait(); + } + } else { + { + Harness::ExactConcurrencyLevel::check(1); + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + barrier->wait(); + Harness::ExactConcurrencyLevel::check(1); + barrier->wait(); + Harness::ExactConcurrencyLevel::check(1); + barrier->wait(); + } + Harness::ExactConcurrencyLevel::check(2); + barrier->wait(); + } + } +}; + +// test that global controls from different thread with overlapping lifetime +// still keep parallelism under control +void TestMultipleControls() +{ + blocking_task_scheduler_init tsi(2); // to prevent autoinitialization + Harness::SpinBarrier barrier(2); + NativeParallelFor( 2, TestMultipleControlsRun(&barrier) ); +} + +#if __TBB_TASK_PRIORITY +// enqueued tasks with priority below current must not be forgotten, +// when enqueue enforced priority is enabled +void TestForgottenEnqueuedTasks() +{ + tbb::task_scheduler_init tsi(2); + tbb::atomic<int> counter; + tbb::atomic<bool> waitFlag; + + waitFlag = false; + counter = 0; + tbb::task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + r.set_ref_count(3); + for (int i=0; i<2; i++) { + tbb::task &t = *new( r.allocate_child() ) WaiterTask(&waitFlag); + tbb::task::spawn(t); + } + // all workers are occupied by blocked WaiterTask() + FFTask* t = new( tbb::task::allocate_root() ) FFTask(&counter); + tbb::task::enqueue(*t, tbb::priority_low); + { + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + waitFlag = true; // WaiterTask() done, workers ready to use + while (!counter) // wait till FFTask() executed + __TBB_Yield(); + } + r.wait_for_all(); + tbb::task::destroy(r); +} +#endif + +int TestMain() +{ + TestTaskEnqueue(); + TestConcurrentArenas(); + TestMultipleControls(); + TestNoUnwantedEnforced(); + TestParallelismRestored(); + const unsigned h_c = tbb::tbb_thread::hardware_concurrency(); + bool excessHC; + { + tbb::task_scheduler_init t(h_c+1); + excessHC = Harness::ExactConcurrencyLevel::isEqual(h_c+1); + } + if (h_c>2) + TestWorkers(h_c-1); + if (excessHC) // requires hardware concurrency +1, otherwise hangs + TestWorkers(h_c+1); + if (excessHC || h_c >= 2) + TestWorkers(2); + if (excessHC || h_c >= 3) + TestWorkers(3); + TestWorkersConstraints(); + TestConcurrentSetUseConcurrency(); + TestInvalidParallelism(); + TestAutoInit(); // auto-initialization done at this point + + size_t default_ss = tbb::global_control::active_value(tbb::global_control::thread_stack_size); + ASSERT(default_ss, NULL); + +// it's impossible to change stack size for Windows 8 Store* apps, so skip the tests +#if !(__TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00)) + TestStackSizeSimpleControl(); + TestStackSizeThreadsControl(); +#endif + TestTooBigStack(); + ASSERT(default_ss == tbb::global_control::active_value(tbb::global_control::thread_stack_size), NULL); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_global_control_whitebox.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_global_control_whitebox.cpp new file mode 100644 index 00000000..f0a3dd54 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_global_control_whitebox.cpp @@ -0,0 +1,78 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFINE_PRIVATE_PUBLIC 1 +#include "harness_inject_scheduler.h" +#include "harness.h" + +#include "tbb/global_control.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" + +bool allWorkersSleep() { + using namespace tbb::internal; + using namespace tbb::internal::rml; + + unsigned sleeping_threads = 0; + unsigned threads = ((private_server*)market::theMarket->my_server)->my_n_thread; + + for (private_worker *l = ((private_server*)market::theMarket->my_server)->my_asleep_list_root; + l; l = l->my_next) + sleeping_threads++; + + return threads == sleeping_threads; +} + +class ThreadsTask { +public: + void operator() (const tbb::blocked_range<int> &) const { } + ThreadsTask() {} +}; + +static void RunAndCheckSleeping() +{ + Harness::Sleep(100); + ASSERT(allWorkersSleep(), NULL); + tbb::parallel_for(tbb::blocked_range<int>(0, 100*1000, 1), + ThreadsTask(), tbb::simple_partitioner()); + Harness::Sleep(100); + ASSERT(allWorkersSleep(), NULL); +} + +// test that all workers are sleeping, not spinning +void TestWorkersSleep() { + tbb::task_scheduler_init tsi(8); + const size_t max_parallelism = + tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism); + if (max_parallelism > 2) { + tbb::global_control c(tbb::global_control::max_allowed_parallelism, max_parallelism-1); + } + RunAndCheckSleeping(); + tbb::global_control c(tbb::global_control::max_allowed_parallelism, max_parallelism+1); + RunAndCheckSleeping(); +} + +int TestMain () { + { + tbb::task_scheduler_init tsi; + if (!tbb::internal::governor::UsePrivateRML) + return Harness::Skipped; + } + TestWorkersSleep(); + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_halt.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_halt.cpp new file mode 100644 index 00000000..0e2e5fd0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_halt.cpp @@ -0,0 +1,109 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 4 +#define HARNESS_DEFAULT_MAX_THREADS 8 + +#include "harness_defs.h" +#include <cstdio> +#include <cstdlib> +#include <cassert> +#include <utility> +#include "tbb/task.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" +#include "tbb/mutex.h" +#include "tbb/spin_mutex.h" +#include "tbb/queuing_mutex.h" +#include "harness.h" + +using namespace std; +using namespace tbb; + +///////////////////// Parallel methods //////////////////////// + +// *** Serial shared by mutexes *** // +int SharedI = 1, SharedN; +template<typename M> +class SharedSerialFibBody: NoAssign { + M &mutex; +public: + SharedSerialFibBody( M &m ) : mutex( m ) {} + //! main loop + void operator()( const blocked_range<int>& /*range*/ ) const { + for(;;) { + typename M::scoped_lock lock( mutex ); + if(SharedI >= SharedN) break; + volatile double sum = 7.3; + sum *= 11.17; + ++SharedI; + } + } +}; + +//! Root function +template<class M> +void SharedSerialFib(int n) +{ + SharedI = 1; + SharedN = n; + M mutex; + parallel_for( blocked_range<int>(0,4,1), SharedSerialFibBody<M>( mutex ) ); +} + +/////////////////////////// Main //////////////////////////////////////////////////// + +double Tsum = 0; int Tnum = 0; + +typedef void (*MeasureFunc)(int); +//! Measure ticks count in loop [2..n] +void Measure(const char *name, MeasureFunc func, int n) +{ + tick_count t0; + tick_count::interval_t T; + REMARK("%s",name); + t0 = tick_count::now(); + for(int number = 2; number <= n; number++) + func(number); + T = tick_count::now() - t0; + double avg = Tnum? Tsum/Tnum : 1; + if (avg == 0.0) avg = 1; + if(avg * 100 < T.seconds()) { + REPORT("Warning: halting detected (%g sec, av: %g)\n", T.seconds(), avg); + ASSERT(avg * 1000 > T.seconds(), "Too long halting period"); + } else { + Tsum += T.seconds(); Tnum++; + } + REMARK("\t- in %f msec\n", T.seconds()*1000); +} + +int TestMain () { + MinThread = max(2, MinThread); + int NumbersCount = 100; + short recycle = 100; + do { + for(int threads = MinThread; threads <= MaxThread; threads++) { + task_scheduler_init scheduler_init(threads); + REMARK("Threads number is %d\t", threads); + Measure("Shared serial (wrapper mutex)\t", SharedSerialFib<mutex>, NumbersCount); + //sum = Measure("Shared serial (spin_mutex)", SharedSerialFib<tbb::spin_mutex>, NumbersCount); + //sum = Measure("Shared serial (queuing_mutex)", SharedSerialFib<tbb::queuing_mutex>, NumbersCount); + } + } while(--recycle); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_handle_perror.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_handle_perror.cpp new file mode 100644 index 00000000..0efc19a2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_handle_perror.cpp @@ -0,0 +1,54 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Program for basic correctness of handle_perror, which is internal +// to the TBB shared library. + +#include <cerrno> +#include <stdexcept> + +#include "../tbb/tbb_misc.h" +#include "harness.h" + +#if TBB_USE_EXCEPTIONS + +static void TestHandlePerror() { + bool caught = false; + try { + tbb::internal::handle_perror( EAGAIN, "apple" ); + } catch( std::runtime_error& e ) { +#if TBB_USE_EXCEPTIONS + REMARK("caught runtime_exception('%s')\n",e.what()); + ASSERT( memcmp(e.what(),"apple: ",7)==0, NULL ); + ASSERT( strlen(strstr(e.what(), strerror(EAGAIN))), "bad error message?" ); +#endif /* TBB_USE_EXCEPTIONS */ + caught = true; + } + ASSERT( caught, NULL ); +} + +int TestMain () { + TestHandlePerror(); + return Harness::Done; +} + +#else /* !TBB_USE_EXCEPTIONS */ + +int TestMain () { + return Harness::Skipped; +} + +#endif /* TBB_USE_EXCEPTIONS */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_hw_concurrency.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_hw_concurrency.cpp new file mode 100644 index 00000000..50a9bcaf --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_hw_concurrency.cpp @@ -0,0 +1,52 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_defs.h" + +#if __TBB_TEST_SKIP_AFFINITY +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" +int TestMain() { + return Harness::Skipped; +} +#else /* affinity mask can be set and used by TBB */ + +#include "harness.h" +#include "harness_concurrency.h" + +#include "tbb/task_scheduler_init.h" +#include "tbb/tbb_thread.h" +#include "tbb/enumerable_thread_specific.h" + +// The declaration of a global ETS object is needed to check that +// it does not initialize the task scheduler, and in particular +// does not set the default thread number. TODO: add other objects +// that should not initialize the scheduler. +tbb::enumerable_thread_specific<std::size_t> ets; + +int TestMain () { + int maxProcs = Harness::GetMaxProcs(); + + if ( maxProcs < 2 ) + return Harness::Skipped; + + int availableProcs = maxProcs/2; + ASSERT( Harness::LimitNumberOfThreads( availableProcs ) == availableProcs, "LimitNumberOfThreads has not set the requested limitation." ); + ASSERT( tbb::task_scheduler_init::default_num_threads() == availableProcs, NULL ); + ASSERT( (int)tbb::tbb_thread::hardware_concurrency() == availableProcs, NULL ); + return Harness::Done; +} +#endif /* __TBB_TEST_SKIP_AFFINITY */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_indexer_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_indexer_node.cpp new file mode 100644 index 00000000..27839365 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_indexer_node.cpp @@ -0,0 +1,997 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#endif +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#include "harness.h" +#include "harness_graph.h" +#include "tbb/flow_graph.h" + +// +// Tests +// + +#if defined(_MSC_VER) && _MSC_VER < 1600 + #pragma warning (disable : 4503) //disabling the "decorated name length exceeded" warning for VS2008 and earlier +#endif + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +template< typename T > +class test_indexer_extract { +protected: + typedef tbb::flow::indexer_node<T, T> my_node_t; + typedef tbb::flow::queue_node<T> in_node_t; + typedef tbb::flow::queue_node<typename my_node_t::output_type> out_node_t; + + tbb::flow::graph g; + in_node_t in0; + in_node_t in1; + in_node_t in2; + my_node_t middle; + out_node_t out0; + out_node_t out1; + in_node_t *ins[3]; + out_node_t *outs[2]; + typename in_node_t::successor_type *ms_p0_ptr; + typename in_node_t::successor_type *ms_p1_ptr; + typename out_node_t::predecessor_type *mp_ptr; + typename in_node_t::predecessor_list_type in0_p_list; + typename in_node_t::successor_list_type in0_s_list; + typename in_node_t::predecessor_list_type in1_p_list; + typename in_node_t::successor_list_type in1_s_list; + typename in_node_t::predecessor_list_type in2_p_list; + typename in_node_t::successor_list_type in2_s_list; + typename out_node_t::predecessor_list_type out0_p_list; + typename out_node_t::successor_list_type out0_s_list; + typename out_node_t::predecessor_list_type out1_p_list; + typename out_node_t::successor_list_type out1_s_list; + typename in_node_t::predecessor_list_type mp0_list; + typename in_node_t::predecessor_list_type mp1_list; + typename out_node_t::successor_list_type ms_list; + + virtual void set_up_lists() { + in0_p_list.clear(); + in0_s_list.clear(); + in1_p_list.clear(); + in1_s_list.clear(); + in2_p_list.clear(); + in2_s_list.clear(); + out0_p_list.clear(); + out0_s_list.clear(); + out1_p_list.clear(); + out1_s_list.clear(); + mp0_list.clear(); + mp1_list.clear(); + ms_list.clear(); + + in0.copy_predecessors(in0_p_list); + in0.copy_successors(in0_s_list); + in1.copy_predecessors(in1_p_list); + in1.copy_successors(in1_s_list); + in2.copy_predecessors(in2_p_list); + in2.copy_successors(in2_s_list); + tbb::flow::input_port<0>(middle).copy_predecessors(mp0_list); + tbb::flow::input_port<1>(middle).copy_predecessors(mp1_list); + middle.copy_successors(ms_list); + out0.copy_predecessors(out0_p_list); + out0.copy_successors(out0_s_list); + out1.copy_predecessors(out1_p_list); + out1.copy_successors(out1_s_list); + } + + void check_output(int &r, typename my_node_t::output_type &v) { + T t = tbb::flow::cast_to<T>(v); + if ( t == 1 || t == 2 ) { + ASSERT( v.tag() == 0, "value came in on wrong port" ); + } else if ( t == 4 || t == 8 ) { + ASSERT( v.tag() == 1, "value came in on wrong port" ); + } else { + ASSERT( false, "incorrect value passed through indexer_node" ); + } + ASSERT( (r&t) == 0, "duplicate value passed through indexer_node" ); + r |= t; + } + + void make_and_validate_full_graph() { + /* in0 */ + /* \ */ + /* port0 out0 */ + /* / | / */ + /* in1 middle */ + /* | \ */ + /* in2 - port1 out1 */ + tbb::flow::make_edge( in0, tbb::flow::input_port<0>(middle) ); + tbb::flow::make_edge( in1, tbb::flow::input_port<0>(middle) ); + tbb::flow::make_edge( in2, tbb::flow::input_port<1>(middle) ); + tbb::flow::make_edge( middle, out0 ); + tbb::flow::make_edge( middle, out1 ); + + set_up_lists(); + + ASSERT( in0.predecessor_count() == 0 && in0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in0.successor_count() == 1 && in0_s_list.size() == 1 && *(in0_s_list.begin()) == ms_p0_ptr, "expected 1 successor" ); + ASSERT( in1.predecessor_count() == 0 && in1_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in1.successor_count() == 1 && in1_s_list.size() == 1 && *(in1_s_list.begin()) == ms_p0_ptr, "expected 1 successor" ); + ASSERT( in2.predecessor_count() == 0 && in2_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in2.successor_count() == 1 && in2_s_list.size() == 1 && *(in2_s_list.begin()) == ms_p1_ptr, "expected 1 successor" ); + ASSERT( tbb::flow::input_port<0>(middle).predecessor_count() == 2 && mp0_list.size() == 2, "expected 2 predecessors" ); + ASSERT( tbb::flow::input_port<1>(middle).predecessor_count() == 1 && mp1_list.size() == 1, "expected 1 predecessors" ); + ASSERT( middle.successor_count() == 2 && ms_list.size() == 2, "expected 2 successors" ); + ASSERT( out0.predecessor_count() == 1 && out0_p_list.size() == 1 && *(out0_p_list.begin()) == mp_ptr, "expected 1 predecessor" ); + ASSERT( out0.successor_count() == 0 && out0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( out1.predecessor_count() == 1 && out1_p_list.size() == 1 && *(out1_p_list.begin()) == mp_ptr, "expected 1 predecessor" ); + ASSERT( out1.successor_count() == 0 && out1_s_list.size() == 0, "expected 0 successors" ); + + int first_pred = *(mp0_list.begin()) == ins[0] ? 0 : ( *(mp0_list.begin()) == ins[1] ? 1 : -1 ); + typename in_node_t::predecessor_list_type::iterator piv = mp0_list.begin();++piv; + int second_pred = *piv == ins[0] ? 0 : ( *piv == ins[1] ? 1 : -1 ); + ASSERT( first_pred != -1 && second_pred != -1 && first_pred != second_pred, "bad predecessor(s) for middle port 0" ); + + ASSERT( *(mp1_list.begin()) == ins[2], "bad predecessor for middle port 1" ); + + int first_succ = *(ms_list.begin()) == outs[0] ? 0 : ( *(ms_list.begin()) == outs[1] ? 1 : -1 ); + typename out_node_t::successor_list_type::iterator ms_vec_iter = ms_list.begin(); ++ms_vec_iter; + int second_succ = *ms_vec_iter == outs[0] ? 0 : ( *ms_vec_iter == outs[1] ? 1 : -1 ); + ASSERT( first_succ != -1 && second_succ != -1 && first_succ != second_succ, "bad successor(s) for middle" ); + + in0.try_put(1); + in1.try_put(2); + in2.try_put(8); + in2.try_put(4); + g.wait_for_all(); + + T v_in; + + ASSERT( in0.try_get(v_in) == false, "buffer should not have a value" ); + ASSERT( in1.try_get(v_in) == false, "buffer should not have a value" ); + ASSERT( in1.try_get(v_in) == false, "buffer should not have a value" ); + ASSERT( in2.try_get(v_in) == false, "buffer should not have a value" ); + ASSERT( in2.try_get(v_in) == false, "buffer should not have a value" ); + + typename my_node_t::output_type v; + T r = 0; + while ( out0.try_get(v) ) { + check_output(r,v); + g.wait_for_all(); + } + ASSERT( r == 15, "not all values received" ); + + r = 0; + while ( out1.try_get(v) ) { + check_output(r,v); + g.wait_for_all(); + } + ASSERT( r == 15, "not all values received" ); + g.wait_for_all(); + } + + void validate_partial_graph() { + /* in0 */ + /* */ + /* port0 out0 */ + /* / | */ + /* in1 middle */ + /* | \ */ + /* in2 - port1 out1 */ + set_up_lists(); + + ASSERT( in0.predecessor_count() == 0 && in0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in0.successor_count() == 0 && in0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( in1.predecessor_count() == 0 && in1_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in1.successor_count() == 1 && in1_s_list.size() == 1 && *(in1_s_list.begin()) == ms_p0_ptr, "expected 1 successor" ); + ASSERT( in2.predecessor_count() == 0 && in2_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in2.successor_count() == 1 && in2_s_list.size() == 1 && *(in2_s_list.begin()) == ms_p1_ptr, "expected 1 successor" ); + ASSERT( tbb::flow::input_port<0>(middle).predecessor_count() == 1 && mp0_list.size() == 1 && *(mp0_list.begin()) == ins[1], "expected 1 predecessor" ); + ASSERT( tbb::flow::input_port<1>(middle).predecessor_count() == 1 && mp1_list.size() == 1 && *(mp1_list.begin()) == ins[2], "expected 1 predecessor" ); + ASSERT( middle.successor_count() == 1 && ms_list.size() == 1 && *(ms_list.begin()) == outs[1], "expected 1 successor" ); + ASSERT( out0.predecessor_count() == 0 && out0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( out0.successor_count() == 0 && out0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( out1.predecessor_count() == 1 && out1_p_list.size() == 1 && *(out1_p_list.begin()) == mp_ptr, "expected 1 predecessor" ); + ASSERT( out1.successor_count() == 0 && out1_s_list.size() == 0, "expected 0 successors" ); + + in0.try_put(1); + in1.try_put(2); + in2.try_put(8); + in2.try_put(4); + g.wait_for_all(); + + T v_in; + typename my_node_t::output_type v; + + ASSERT( in0.try_get(v_in) == true && v_in == 1, "buffer should have a value of 1" ); + ASSERT( in1.try_get(v_in) == false, "buffer should not have a value" ); + ASSERT( out0.try_get(v) == false, "buffer should not have a value" ); + ASSERT( in0.try_get(v_in) == false, "buffer should not have a value" ); + + T r = 0; + while ( out1.try_get(v) ) { + check_output(r,v); + g.wait_for_all(); + } + ASSERT( r == 14, "not all values received" ); + g.wait_for_all(); + } + + void validate_empty_graph() { + /* in0 */ + /* */ + /* port0 out0 */ + /* | */ + /* in1 middle */ + /* | */ + /* in2 port1 out1 */ + set_up_lists(); + + ASSERT( in0.predecessor_count() == 0 && in0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in0.successor_count() == 0 && in0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( in1.predecessor_count() == 0 && in1_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in1.successor_count() == 0 && in1_s_list.size() == 0, "expected 0 successors" ); + ASSERT( in2.predecessor_count() == 0 && in2_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( in2.successor_count() == 0 && in2_s_list.size() == 0, "expected 0 successors" ); + ASSERT( tbb::flow::input_port<0>(middle).predecessor_count() == 0 && mp0_list.size() == 0, "expected 0 predecessors" ); + ASSERT( tbb::flow::input_port<1>(middle).predecessor_count() == 0 && mp1_list.size() == 0, "expected 0 predecessors" ); + ASSERT( middle.successor_count() == 0 && ms_list.size() == 0, "expected 0 successors" ); + ASSERT( out0.predecessor_count() == 0 && out0_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( out0.successor_count() == 0 && out0_s_list.size() == 0, "expected 0 successors" ); + ASSERT( out1.predecessor_count() == 0 && out1_p_list.size() == 0, "expected 0 predecessors" ); + ASSERT( out1.successor_count() == 0 && out1_s_list.size() == 0, "expected 0 successors" ); + + in0.try_put(1); + in1.try_put(2); + in2.try_put(8); + in2.try_put(4); + g.wait_for_all(); + + T v_in; + typename my_node_t::output_type v; + + ASSERT( in0.try_get(v_in) == true && v_in == 1, "buffer should have a value of 1" ); + ASSERT( in1.try_get(v_in) == true && v_in == 2, "buffer should have a value of 2" ); + ASSERT( in2.try_get(v_in) == true && v_in == 8, "buffer should have a value of 8" ); + ASSERT( in2.try_get(v_in) == true && v_in == 4, "buffer should have a value of 4" ); + ASSERT( out0.try_get(v) == false, "buffer should not have a value" ); + ASSERT( out1.try_get(v) == false, "buffer should not have a value" ); + g.wait_for_all(); + g.reset(); // NOTE: this should not be necessary!!!!! But it is!!!! + } + +public: + + test_indexer_extract() : in0(g), in1(g), in2(g), middle(g), out0(g), out1(g) { + ins[0] = &in0; + ins[1] = &in1; + ins[2] = &in2; + outs[0] = &out0; + outs[1] = &out1; + ms_p0_ptr = static_cast< typename in_node_t::successor_type * >(&tbb::flow::input_port<0>(middle)); + ms_p1_ptr = static_cast< typename in_node_t::successor_type * >(&tbb::flow::input_port<1>(middle)); + mp_ptr = static_cast< typename out_node_t::predecessor_type *>(&middle); + } + + virtual ~test_indexer_extract() {} + + void run_tests() { + REMARK("full graph\n"); + make_and_validate_full_graph(); + + in0.extract(); + out0.extract(); + REMARK("partial graph\n"); + validate_partial_graph(); + + in1.extract(); + in2.extract(); + out1.extract(); + REMARK("empty graph\n"); + validate_empty_graph(); + + REMARK("full graph\n"); + make_and_validate_full_graph(); + + middle.extract(); + REMARK("empty graph\n"); + validate_empty_graph(); + + REMARK("full graph\n"); + make_and_validate_full_graph(); + + in0.extract(); + in1.extract(); + in2.extract(); + middle.extract(); + REMARK("empty graph\n"); + validate_empty_graph(); + + REMARK("full graph\n"); + make_and_validate_full_graph(); + + out0.extract(); + out1.extract(); + middle.extract(); + REMARK("empty graph\n"); + validate_empty_graph(); + + REMARK("full graph\n"); + make_and_validate_full_graph(); + } +}; +#endif + +const int Count = 150; +const int MaxPorts = 10; +const int MaxNSources = 5; // max # of source_nodes to register for each indexer_node input in parallel test +bool outputCheck[MaxPorts][Count]; // for checking output + +void +check_outputCheck( int nUsed, int maxCnt) { + for(int i=0; i < nUsed; ++i) { + for( int j = 0; j < maxCnt; ++j) { + ASSERT(outputCheck[i][j], NULL); + } + } +} + +void +reset_outputCheck( int nUsed, int maxCnt) { + for(int i=0; i < nUsed; ++i) { + for( int j = 0; j < maxCnt; ++j) { + outputCheck[i][j] = false; + } + } +} + +class test_class { + public: + test_class() { my_val = 0; } + test_class(int i) { my_val = i; } + operator int() { return my_val; } + private: + int my_val; +}; + +template<typename T> +class name_of { +public: + static const char* name() { return "Unknown"; } +}; +template<> +class name_of<int> { +public: + static const char* name() { return "int"; } +}; +template<> +class name_of<float> { +public: + static const char* name() { return "float"; } +}; +template<> +class name_of<double> { +public: + static const char* name() { return "double"; } +}; +template<> +class name_of<long> { +public: + static const char* name() { return "long"; } +}; +template<> +class name_of<short> { +public: + static const char* name() { return "short"; } +}; +template<> +class name_of<test_class> { +public: + static const char* name() { return "test_class"; } +}; + +// TT must be arithmetic, and shouldn't wrap around for reasonable sizes of Count (which is now 150, and maxPorts is 10, +// so the max number generated right now is 1500 or so.) Source will generate a series of TT with value +// (init_val + (i-1)*addend) * my_mult, where i is the i-th invocation of the body. We are attaching addend +// source nodes to a indexer_port, and each will generate part of the numerical series the port is expecting +// to receive. If there is only one source node, the series order will be maintained; if more than one, +// this is not guaranteed. +// The manual specifies bodies can be assigned, so we can't hide the operator=. +template<typename TT> +class source_body { + TT my_mult; + int my_count; + int addend; +public: + source_body(TT multiplier, int init_val, int addto) : my_mult(multiplier), my_count(init_val), addend(addto) { } +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()( TT &v) { + int lc = my_count; + v = my_mult * (TT)my_count; + my_count += addend; + return lc < Count; + } +#else + TT operator()( tbb::flow_control& fc) { + int lc = my_count; + TT ret = my_mult * (TT)my_count; + my_count += addend; + if ( lc < Count){ + return ret; + }else{ + fc.stop(); + return TT(); + } + } +#endif +}; + +// allocator for indexer_node. + +template<typename IType> +class makeIndexer { +public: + static IType *create() { + IType *temp = new IType(); + return temp; + } + static void destroy(IType *p) { delete p; } +}; + +template<int ELEM, typename INT> +struct getval_helper { + + typedef typename INT::output_type OT; + typedef typename tbb::flow::tuple_element<ELEM-1, typename INT::tuple_types>::type stored_type; + + static int get_integer_val(OT const &o) { + stored_type res = tbb::flow::cast_to<stored_type>(o); + return (int)res; + } +}; + +// holder for source_node pointers for eventual deletion + +static void* all_source_nodes[MaxPorts][MaxNSources]; + +template<int ELEM, typename INT> +class source_node_helper { +public: + typedef INT indexer_node_type; + typedef typename indexer_node_type::output_type TT; + typedef typename tbb::flow::tuple_element<ELEM-1,typename INT::tuple_types>::type IT; + typedef typename tbb::flow::input_node<IT> my_source_node_type; + static void print_remark() { + source_node_helper<ELEM-1,INT>::print_remark(); + REMARK(", %s", name_of<IT>::name()); + } + static void add_source_nodes(indexer_node_type &my_indexer, tbb::flow::graph &g, int nInputs) { + for(int i=0; i < nInputs; ++i) { + my_source_node_type *new_node = new my_source_node_type(g, source_body<IT>((IT)(ELEM+1), i, nInputs)); + tbb::flow::make_edge(*new_node, tbb::flow::input_port<ELEM-1>(my_indexer)); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(new_node->successor_count() == 1, NULL); +#endif + all_source_nodes[ELEM-1][i] = (void *)new_node; + new_node->activate(); + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(tbb::flow::input_port<ELEM-1>(my_indexer).predecessor_count() == (size_t)nInputs, NULL); +#endif + // add the next source_node + source_node_helper<ELEM-1, INT>::add_source_nodes(my_indexer, g, nInputs); + } + static void check_value(TT &v) { + if(v.tag() == ELEM-1) { + int ival = getval_helper<ELEM,INT>::get_integer_val(v); + ASSERT(!(ival%(ELEM+1)), NULL); + ival /= (ELEM+1); + ASSERT(!outputCheck[ELEM-1][ival], NULL); + outputCheck[ELEM-1][ival] = true; + } + else { + source_node_helper<ELEM-1,INT>::check_value(v); + } + } + + static void remove_source_nodes(indexer_node_type& my_indexer, int nInputs) { + for(int i=0; i< nInputs; ++i) { + my_source_node_type *dp = reinterpret_cast<my_source_node_type *>(all_source_nodes[ELEM-1][i]); + tbb::flow::remove_edge(*dp, tbb::flow::input_port<ELEM-1>(my_indexer)); + delete dp; + } + source_node_helper<ELEM-1, INT>::remove_source_nodes(my_indexer, nInputs); + } +}; + +template<typename INT> +class source_node_helper<1, INT> { + typedef INT indexer_node_type; + typedef typename indexer_node_type::output_type TT; + typedef typename tbb::flow::tuple_element<0, typename INT::tuple_types>::type IT; + typedef typename tbb::flow::input_node<IT> my_source_node_type; +public: + static void print_remark() { + REMARK("Parallel test of indexer_node< %s", name_of<IT>::name()); + } + static void add_source_nodes(indexer_node_type &my_indexer, tbb::flow::graph &g, int nInputs) { + for(int i=0; i < nInputs; ++i) { + my_source_node_type *new_node = new my_source_node_type(g, source_body<IT>((IT)2, i, nInputs)); + tbb::flow::make_edge(*new_node, tbb::flow::input_port<0>(my_indexer)); + all_source_nodes[0][i] = (void *)new_node; + new_node->activate(); + } + } + static void check_value(TT &v) { + int ival = getval_helper<1,INT>::get_integer_val(v); + ASSERT(!(ival%2), NULL); + ival /= 2; + ASSERT(!outputCheck[0][ival], NULL); + outputCheck[0][ival] = true; + } + static void remove_source_nodes(indexer_node_type& my_indexer, int nInputs) { + for(int i=0; i < nInputs; ++i) { + my_source_node_type *dp = reinterpret_cast<my_source_node_type *>(all_source_nodes[0][i]); + tbb::flow::remove_edge(*dp, tbb::flow::input_port<0>(my_indexer)); + delete dp; + } + } +}; + +template<typename IType> +class parallel_test { +public: + typedef typename IType::output_type TType; + typedef typename IType::tuple_types union_types; + static const int SIZE = tbb::flow::tuple_size<union_types>::value; + static void test() { + TType v; + source_node_helper<SIZE,IType>::print_remark(); + REMARK(" >\n"); + for(int i=0; i < MaxPorts; ++i) { + for(int j=0; j < MaxNSources; ++j) { + all_source_nodes[i][j] = NULL; + } + } + for(int nInputs = 1; nInputs <= MaxNSources; ++nInputs) { + tbb::flow::graph g; + IType* my_indexer = new IType(g); //makeIndexer<IType>::create(); + tbb::flow::queue_node<TType> outq1(g); + tbb::flow::queue_node<TType> outq2(g); + + tbb::flow::make_edge(*my_indexer, outq1); + tbb::flow::make_edge(*my_indexer, outq2); + + source_node_helper<SIZE, IType>::add_source_nodes((*my_indexer), g, nInputs); + + g.wait_for_all(); + + reset_outputCheck(SIZE, Count); + for(int i=0; i < Count*SIZE; ++i) { + ASSERT(outq1.try_get(v), NULL); + source_node_helper<SIZE, IType>::check_value(v); + } + + check_outputCheck(SIZE, Count); + reset_outputCheck(SIZE, Count); + + for(int i=0; i < Count*SIZE; i++) { + ASSERT(outq2.try_get(v), NULL);; + source_node_helper<SIZE, IType>::check_value(v); + } + check_outputCheck(SIZE, Count); + + ASSERT(!outq1.try_get(v), NULL); + ASSERT(!outq2.try_get(v), NULL); + + source_node_helper<SIZE, IType>::remove_source_nodes((*my_indexer), nInputs); + tbb::flow::remove_edge(*my_indexer, outq1); + tbb::flow::remove_edge(*my_indexer, outq2); + makeIndexer<IType>::destroy(my_indexer); + } + } +}; + +std::vector<int> last_index_seen; + +template<int ELEM, typename IType> +class serial_queue_helper { +public: + typedef typename IType::output_type OT; + typedef typename IType::tuple_types TT; + typedef typename tbb::flow::tuple_element<ELEM-1,TT>::type IT; + static void print_remark() { + serial_queue_helper<ELEM-1,IType>::print_remark(); + REMARK(", %s", name_of<IT>::name()); + } + static void fill_one_queue(int maxVal, IType &my_indexer) { + // fill queue to "left" of me + serial_queue_helper<ELEM-1,IType>::fill_one_queue(maxVal,my_indexer); + for(int i = 0; i < maxVal; ++i) { + ASSERT(tbb::flow::input_port<ELEM-1>(my_indexer).try_put((IT)(i*(ELEM+1))), NULL); + } + } + static void put_one_queue_val(int myVal, IType &my_indexer) { + // put this val to my "left". + serial_queue_helper<ELEM-1,IType>::put_one_queue_val(myVal, my_indexer); + ASSERT(tbb::flow::input_port<ELEM-1>(my_indexer).try_put((IT)(myVal*(ELEM+1))), NULL); + } + static void check_queue_value(OT &v) { + if(ELEM - 1 == v.tag()) { + // this assumes each or node input is queueing. + int rval = getval_helper<ELEM,IType>::get_integer_val(v); + ASSERT( rval == (last_index_seen[ELEM-1]+1)*(ELEM+1), NULL); + last_index_seen[ELEM-1] = rval / (ELEM+1); + } + else { + serial_queue_helper<ELEM-1,IType>::check_queue_value(v); + } + } +}; + +template<typename IType> +class serial_queue_helper<1, IType> { +public: + typedef typename IType::output_type OT; + typedef typename IType::tuple_types TT; + typedef typename tbb::flow::tuple_element<0,TT>::type IT; + static void print_remark() { + REMARK("Serial test of indexer_node< %s", name_of<IT>::name()); + } + static void fill_one_queue(int maxVal, IType &my_indexer) { + for(int i = 0; i < maxVal; ++i) { + ASSERT(tbb::flow::input_port<0>(my_indexer).try_put((IT)(i*2)), NULL); + } + } + static void put_one_queue_val(int myVal, IType &my_indexer) { + ASSERT(tbb::flow::input_port<0>(my_indexer).try_put((IT)(myVal*2)), NULL); + } + static void check_queue_value(OT &v) { + ASSERT(v.tag() == 0, NULL); // won't get here unless true + int rval = getval_helper<1,IType>::get_integer_val(v); + ASSERT( rval == (last_index_seen[0]+1)*2, NULL); + last_index_seen[0] = rval / 2; + } +}; + +template<typename IType, typename TType, int SIZE> +void test_one_serial( IType &my_indexer, tbb::flow::graph &g) { + last_index_seen.clear(); + for(int ii=0; ii < SIZE; ++ii) last_index_seen.push_back(-1); + + typedef TType q3_input_type; + tbb::flow::queue_node< q3_input_type > q3(g); + q3_input_type v; + + tbb::flow::make_edge(my_indexer, q3); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(my_indexer.successor_count() == 1, NULL); + ASSERT(tbb::flow::input_port<0>(my_indexer).predecessor_count() == 0, NULL); +#endif + + // fill each queue with its value one-at-a-time + for (int i = 0; i < Count; ++i ) { + serial_queue_helper<SIZE,IType>::put_one_queue_val(i,my_indexer); + } + + g.wait_for_all(); + for (int i = 0; i < Count * SIZE; ++i ) { + g.wait_for_all(); + ASSERT(q3.try_get( v ), "Error in try_get()"); + { + serial_queue_helper<SIZE,IType>::check_queue_value(v); + } + } + ASSERT(!q3.try_get( v ), "extra values in output queue"); + for(int ii=0; ii < SIZE; ++ii) last_index_seen[ii] = -1; + + // fill each queue completely before filling the next. + serial_queue_helper<SIZE, IType>::fill_one_queue(Count,my_indexer); + + g.wait_for_all(); + for (int i = 0; i < Count*SIZE; ++i ) { + g.wait_for_all(); + ASSERT(q3.try_get( v ), "Error in try_get()"); + { + serial_queue_helper<SIZE,IType>::check_queue_value(v); + } + } + ASSERT(!q3.try_get( v ), "extra values in output queue"); +} + +// +// Single predecessor at each port, single accepting successor +// * put to buffer before port0, then put to buffer before port1, ... +// * fill buffer before port0 then fill buffer before port1, ... + +template<typename IType> +class serial_test { + typedef typename IType::output_type TType; // this is the union + typedef typename IType::tuple_types union_types; + static const int SIZE = tbb::flow::tuple_size<union_types>::value; +public: +static void test() { + tbb::flow::graph g; + static const int ELEMS = 3; + IType* my_indexer = new IType(g); //makeIndexer<IType>::create(g); + + test_input_ports_return_ref(*my_indexer); + + serial_queue_helper<SIZE, IType>::print_remark(); REMARK(" >\n"); + + test_one_serial<IType,TType,SIZE>(*my_indexer, g); + + std::vector<IType> indexer_vector(ELEMS,*my_indexer); + + makeIndexer<IType>::destroy(my_indexer); + + for(int e = 0; e < ELEMS; ++e) { + test_one_serial<IType,TType,SIZE>(indexer_vector[e], g); + } +} + +}; // serial_test + +template< + template<typename> class TestType, // serial_test or parallel_test + typename T0, typename T1=void, typename T2=void, typename T3=void, typename T4=void, + typename T5=void, typename T6=void, typename T7=void, typename T8=void, typename T9=void> // type of the inputs to the indexer_node +class generate_test { +public: + typedef tbb::flow::indexer_node<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +//specializations for indexer node inputs +template< + template<typename> class TestType, + typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> +class generate_test<TestType, T0, T1, T2, T3, T4, T5, T6, T7, T8> { +public: + typedef tbb::flow::indexer_node<T0, T1, T2, T3, T4, T5, T6, T7, T8> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +template< + template<typename> class TestType, + typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> +class generate_test<TestType, T0, T1, T2, T3, T4, T5, T6, T7> { +public: + typedef tbb::flow::indexer_node<T0, T1, T2, T3, T4, T5, T6, T7> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +template< + template<typename> class TestType, + typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> +class generate_test<TestType, T0, T1, T2, T3, T4, T5, T6> { +public: + typedef tbb::flow::indexer_node<T0, T1, T2, T3, T4, T5, T6> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +template< + template<typename> class TestType, + typename T0, typename T1, typename T2, typename T3, typename T4, + typename T5> +class generate_test<TestType, T0, T1, T2, T3, T4, T5> { +public: + typedef tbb::flow::indexer_node<T0, T1, T2, T3, T4, T5> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +template< + template<typename> class TestType, + typename T0, typename T1, typename T2, typename T3, typename T4> +class generate_test<TestType, T0, T1, T2, T3, T4> { +public: + typedef tbb::flow::indexer_node<T0, T1, T2, T3, T4> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +template< + template<typename> class TestType, + typename T0, typename T1, typename T2, typename T3> +class generate_test<TestType, T0, T1, T2, T3> { +public: + typedef tbb::flow::indexer_node<T0, T1, T2, T3> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +template< + template<typename> class TestType, + typename T0, typename T1, typename T2> +class generate_test<TestType, T0, T1, T2> { +public: + typedef tbb::flow::indexer_node<T0, T1, T2> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +template< + template<typename> class TestType, + typename T0, typename T1> +class generate_test<TestType, T0, T1> { +public: + typedef tbb::flow::indexer_node<T0, T1> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +template< + template<typename> class TestType, + typename T0> +class generate_test<TestType, T0> { +public: + typedef tbb::flow::indexer_node<T0> indexer_node_type; + static void do_test() { + TestType<indexer_node_type>::test(); + } +}; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +template<typename tagged_msg_t, typename input_t> +void check_edge(tbb::flow::graph& g, + tbb::flow::broadcast_node<input_t>& start, + tbb::flow::buffer_node<tagged_msg_t>& buf, + input_t input_value) { + start.try_put(input_value); + g.wait_for_all(); + + tagged_msg_t msg; + bool is_get_succeeded = buf.try_get(msg); + + ASSERT((is_get_succeeded), "There is no item in the buffer"); + ASSERT((tbb::flow::cast_to<input_t>(msg) == input_value), "Wrong item value"); +} + +void test_follows() { + using namespace tbb::flow; + using indexer_output_t = indexer_node<int, float, double>::output_type; + + graph g; + broadcast_node<continue_msg> start(g); + + broadcast_node<int> start1(g); + broadcast_node<float> start2(g); + broadcast_node<double> start3(g); + + indexer_node<int, float, double> my_indexer(follows(start1, start2, start3)); + + buffer_node<indexer_output_t> buf(g); + make_edge(my_indexer, buf); + + check_edge<indexer_output_t, int>(g, start1, buf, 1); + check_edge<indexer_output_t, float>(g, start2, buf, 2.2f); + check_edge<indexer_output_t, double>(g, start3, buf, 3.3); +} + +void test_precedes() { + using namespace tbb::flow; + + using indexer_output_t = indexer_node<int, float, double>::output_type; + + graph g; + + broadcast_node<int> start1(g); + broadcast_node<float> start2(g); + broadcast_node<double> start3(g); + + buffer_node<indexer_output_t> buf1(g); + buffer_node<indexer_output_t> buf2(g); + buffer_node<indexer_output_t> buf3(g); + + indexer_node<int, float, double> node(precedes(buf1, buf2, buf3)); + + make_edge(start1, input_port<0>(node)); + make_edge(start2, input_port<1>(node)); + make_edge(start3, input_port<2>(node)); + + check_edge<indexer_output_t, int>(g, start1, buf1, 1); + check_edge<indexer_output_t, float>(g, start2, buf2, 2.2f); + check_edge<indexer_output_t, double>(g, start3, buf3, 3.3); +} + +void test_follows_and_precedes_api() { + test_follows(); + test_precedes(); +} +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + graph g; + + broadcast_node<int> b1(g); + broadcast_node<double> b2(g); + indexer_node<int, double> i0(g); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + indexer_node i1(follows(b1, b2)); + static_assert(std::is_same_v<decltype(i1), indexer_node<int, double>>); +#endif + + indexer_node i2(i0); + static_assert(std::is_same_v<decltype(i2), indexer_node<int, double>>); +} + +#endif + +int TestMain() { + REMARK("Testing indexer_node, "); +#if __TBB_USE_TBB_TUPLE + REMARK("using TBB tuple\n"); +#else + REMARK("using platform tuple\n"); +#endif + + for (int p = 0; p < 2; ++p) { + generate_test<serial_test, float>::do_test(); +#if MAX_TUPLE_TEST_SIZE >= 4 + generate_test<serial_test, float, double, int>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 6 + generate_test<serial_test, double, double, int, long, int, short>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 8 + generate_test<serial_test, float, double, double, double, float, int, float, long>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 10 + generate_test<serial_test, float, double, int, double, double, float, long, int, float, long>::do_test(); +#endif + generate_test<parallel_test, float, double>::do_test(); +#if MAX_TUPLE_TEST_SIZE >= 3 + generate_test<parallel_test, float, int, long>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 5 + generate_test<parallel_test, double, double, int, int, short>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 7 + generate_test<parallel_test, float, int, double, float, long, float, long>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 9 + generate_test<parallel_test, float, double, int, double, double, long, int, float, long>::do_test(); +#endif + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_indexer_extract<int>().run_tests(); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_initializer_list.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_initializer_list.h new file mode 100644 index 00000000..5602473a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_initializer_list.h @@ -0,0 +1,172 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_test_initializer_list_H +#define __TBB_test_initializer_list_H +#include "tbb/tbb_config.h" + +#if __TBB_INITIALIZER_LISTS_PRESENT +#include <initializer_list> +#include <vector> +#include "harness_defs.h" //for int_to_type + +namespace initializer_list_support_tests{ + template<typename container_type, typename element_type> + void test_constructor(std::initializer_list<element_type> il, container_type const& expected){ + container_type vd (il); + ASSERT(vd == expected,"initialization via explicit constructor call with init list failed"); + } + + + template<typename container_type, typename element_type> + void test_assignment_operator(std::initializer_list<element_type> il, container_type const& expected){ + container_type va; + va = il; + ASSERT(va == expected,"init list operator= failed"); + } + + struct skip_test { + template<typename container_type, typename element_type> + static void do_test(std::initializer_list<element_type>, container_type const&) { /* do nothing */ } + }; + + struct test_assign { + template<typename container_type, typename element_type> + static void do_test( std::initializer_list<element_type> il, container_type const& expected ) { + container_type vae; + vae.assign( il ); + ASSERT( vae == expected, "init list assign(begin,end) failed" ); + } + }; + + struct test_special_insert { + template<typename container_type, typename element_type> + static void do_test( std::initializer_list<element_type> il, container_type const& expected ) { + container_type vd; + vd.insert( il ); + ASSERT( vd == expected, "inserting with an initializer list failed" ); + } + }; + + template <typename container_type, typename test_assign, typename test_special> + void TestInitListSupport(std::initializer_list<typename container_type::value_type> il){ + typedef typename container_type::value_type element_type; + std::vector<element_type> test_seq(il.begin(),il.end()); + container_type expected(test_seq.begin(), test_seq.end()); + + test_constructor<container_type,element_type>(il, expected); + test_assignment_operator<container_type,element_type>(il, expected); + test_assign::do_test(il, expected); + test_special::do_test(il, expected); + } + + template <typename container_type, typename test_special = skip_test> + void TestInitListSupport(std::initializer_list<typename container_type::value_type> il) { + TestInitListSupport<container_type, test_assign, test_special>(il); + } + + template <typename container_type, typename test_special = skip_test> + void TestInitListSupportWithoutAssign(std::initializer_list<typename container_type::value_type> il){ + TestInitListSupport<container_type, skip_test, test_special>(il); + } + + //TODO: add test for no leaks, and correct element lifetime + //the need for macro comes from desire to test different scenarios where initializer sequence is compile time constant + #define __TBB_TEST_INIT_LIST_SUITE_SINGLE(FUNC_NAME, CONTAINER, ELEMENT_TYPE, INIT_SEQ) \ + void FUNC_NAME(){ \ + typedef ELEMENT_TYPE element_type; \ + typedef CONTAINER<element_type> container_type; \ + element_type test_seq[] = INIT_SEQ; \ + container_type expected(test_seq,test_seq + Harness::array_length(test_seq)); \ + \ + /*test for explicit constructor call*/ \ + container_type vd INIT_SEQ; \ + ASSERT(vd == expected,"initialization via explicit constructor call with init list failed"); \ + /*test for explicit constructor call with std::initializer_list*/ \ + \ + std::initializer_list<element_type> init_list = INIT_SEQ; \ + container_type v1 (init_list); \ + ASSERT(v1 == expected,"initialization via explicit constructor call with std::initializer_list failed"); \ + \ + /*implicit constructor call test*/ \ + container_type v = INIT_SEQ; \ + ASSERT(v == expected,"init list constructor failed"); \ + \ + /*assignment operator test*/ \ + /*TODO: count created and destroyed injects to assert that no extra copy of vector was created implicitly*/ \ + container_type va; \ + va = INIT_SEQ; \ + ASSERT(va == expected,"init list operator= failed"); \ + /*assign(begin,end) test*/ \ + container_type vae; \ + vae.assign(INIT_SEQ); \ + ASSERT(vae == expected,"init list assign(begin,end) failed"); \ + } \ + + namespace initializer_list_helpers{ + template<typename T> + class ad_hoc_container{ + std::vector<T> vec; + public: + ad_hoc_container(){} + typename std::vector<T>::const_iterator begin() const {return vec.begin();} + typename std::vector<T>::const_iterator end() const {return vec.end();} + typename std::vector<T>::size_type size() const {return vec.size();} + template<typename InputIterator> + ad_hoc_container(InputIterator begin, InputIterator end) : vec(begin,end) {} + ad_hoc_container(std::initializer_list<T> il) : vec(il.begin(),il.end()) {} + ad_hoc_container(ad_hoc_container const& other) : vec(other.vec) {} + ad_hoc_container& operator=(ad_hoc_container const& rhs){ vec=rhs.vec; return *this;} + ad_hoc_container& operator=(std::initializer_list<T> il){ vec.assign(il.begin(),il.end()); return *this;} + template<typename InputIterator> + void assign(InputIterator begin, InputIterator end){ vec.assign(begin,end);} + void assign(std::initializer_list<T> il){ vec.assign(il.begin(),il.end());} + friend bool operator==(ad_hoc_container<T> const& lhs, ad_hoc_container<T> const& rhs){ return lhs.vec==rhs.vec;} + }; + } + + #define AD_HOC_INIT_SEQ {1,2,3,4} + __TBB_TEST_INIT_LIST_SUITE_SINGLE(TestCompilerSupportInt, initializer_list_helpers::ad_hoc_container, int, AD_HOC_INIT_SEQ ) + #undef AD_HOC_INIT_SEQ + + #if __TBB_CPP11_INIT_LIST_TEST_BROKEN + void TestCompilerSupportIntPair(){ + REPORT("Known issue: skip initializer_list compiler test for std::pair list elements.\n"); + } + #else + #define AD_HOC_PAIR_INIT_SEQ {{1,1}, {2,2},{3,3}, {4,4}} + #define AD_HOC_INIT_SEQ_PAIR_TYPE std::pair<int,int> + __TBB_TEST_INIT_LIST_SUITE_SINGLE(TestCompilerSupportIntPair, initializer_list_helpers::ad_hoc_container, AD_HOC_INIT_SEQ_PAIR_TYPE, AD_HOC_PAIR_INIT_SEQ ) + #undef AD_HOC_INIT_SEQ_PAIR_TYPE + #undef AD_HOC_PAIR_INIT_SEQ + #endif + + bool TestCompilerForInitializerList(); + namespace { + const bool conpiler_init_list_tests_are_run = TestCompilerForInitializerList(); + } + + //TODO: move this to test_compiler + bool TestCompilerForInitializerList(){ + TestCompilerSupportInt(); + TestCompilerSupportIntPair(); + tbb::internal::suppress_unused_warning(conpiler_init_list_tests_are_run); + return true; + } +} // namespace initializer_list_support_tests + +#endif //__TBB_INITIALIZER_LISTS_PRESENT +#endif //__TBB_test_initializer_list_H diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_inits_loop.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_inits_loop.cpp new file mode 100644 index 00000000..6d992025 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_inits_loop.cpp @@ -0,0 +1,90 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __APPLE__ + +#define HARNESS_CUSTOM_MAIN 1 +#include "harness.h" +#include <cstdlib> +#include "tbb/task_scheduler_init.h" + +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> + +bool exec_test(const char *self) { + int status = 1; + pid_t p = fork(); + if(p < 0) { + REPORT("fork error: errno=%d: %s\n", errno, strerror(errno)); + return true; + } + else if(p) { // parent + if(waitpid(p, &status, 0) != p) { + REPORT("wait error: errno=%d: %s\n", errno, strerror(errno)); + return true; + } + if(WIFEXITED(status)) { + if(!WEXITSTATUS(status)) return false; // ok + else REPORT("child has exited with return code 0x%x\n", WEXITSTATUS(status)); + } else { + REPORT("child error 0x%x:%s%s ", status, WIFSIGNALED(status)?" signalled":"", + WIFSTOPPED(status)?" stopped":""); + if(WIFSIGNALED(status)) + REPORT("%s%s", sys_siglist[WTERMSIG(status)], WCOREDUMP(status)?" core dumped":""); + if(WIFSTOPPED(status)) + REPORT("with %d stop-code", WSTOPSIG(status)); + REPORT("\n"); + } + } + else { // child + // reproduces error much often + execl(self, self, "0", NULL); + REPORT("exec fails %s: %d: %s\n", self, errno, strerror(errno)); + exit(2); + } + return true; +} + +HARNESS_EXPORT +int main( int argc, char * argv[] ) { + MinThread = 3000; + ParseCommandLine( argc, argv ); + if( MinThread <= 0 ) { + tbb::task_scheduler_init init( 2 ); // even number required for an error + } else { + for(int i = 0; i<MinThread; i++) { + if(exec_test(argv[0])) { + REPORT("ERROR: execution fails at %d-th iteration!\n", i); + exit(1); + } + } + REPORT("done\n"); + } +} + +#else /* !__APPLE__ */ + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" + +int TestMain () { + return Harness::Skipped; +} + +#endif /* !__APPLE__ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_input_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_input_node.cpp new file mode 100644 index 00000000..0a7d4d59 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_input_node.cpp @@ -0,0 +1,388 @@ +/* + Copyright (c) 2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// have to expose the reset_node method to be able to reset a function_body + +#include "harness.h" +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#include "harness_graph.h" +#include "tbb/flow_graph.h" +#include "tbb/task.h" +#include "tbb/task_scheduler_init.h" + +const int N = 1000; + +template< typename T > +class test_push_receiver : public tbb::flow::receiver<T>, NoAssign { + + tbb::atomic<int> my_counters[N]; + tbb::flow::graph& my_graph; + +public: + + test_push_receiver(tbb::flow::graph& g) : my_graph(g) { + for (int i = 0; i < N; ++i ) + my_counters[i] = 0; + } + + int get_count( int i ) { + int v = my_counters[i]; + return v; + } + + typedef typename tbb::flow::receiver<T>::predecessor_type predecessor_type; + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::receiver<T>::built_predecessors_type built_predecessors_type; + typedef typename tbb::flow::receiver<T>::predecessor_list_type predecessor_list_type; + built_predecessors_type bpt; + built_predecessors_type &built_predecessors() __TBB_override { return bpt; } + void internal_add_built_predecessor( predecessor_type & ) __TBB_override { } + void internal_delete_built_predecessor( predecessor_type & ) __TBB_override { } + void copy_predecessors( predecessor_list_type & ) __TBB_override { } + size_t predecessor_count() __TBB_override { return 0; } +#endif + + tbb::task *try_put_task( const T &v ) __TBB_override { + int i = (int)v; + ++my_counters[i]; + return const_cast<tbb::task *>(SUCCESSFULLY_ENQUEUED); + } + + tbb::flow::graph& graph_reference() const __TBB_override { + return my_graph; + } + + void reset_receiver(tbb::flow::reset_flags /*f*/) __TBB_override {} +}; + +template< typename T > +class source_body { + + unsigned my_count; + int *ninvocations; + +public: + + source_body() : ninvocations(NULL) { my_count = 0; } + source_body(int &_inv) : ninvocations(&_inv) { my_count = 0; } + +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()( T &v ) { + v = (T)my_count++; + if(ninvocations) ++(*ninvocations); + if ( (int)v < N ) + return true; + else + return false; + } +#else + T operator()( tbb::flow_control& fc ) { + T v = (T)my_count++; + if(ninvocations) ++(*ninvocations); + if ( (int)v < N ){ + return v; + }else{ + fc.stop(); + return T(); + } + } +#endif +}; + +template< typename T > +class function_body { + + tbb::atomic<int> *my_counters; + +public: + + function_body( tbb::atomic<int> *counters ) : my_counters(counters) { + for (int i = 0; i < N; ++i ) + my_counters[i] = 0; + } + + bool operator()( T v ) { + ++my_counters[(int)v]; + return true; + } + +}; + +template< typename T > +void test_single_dest() { + + // push only + tbb::flow::graph g; + tbb::flow::input_node<T> src(g, source_body<T>() ); + test_push_receiver<T> dest(g); + tbb::flow::make_edge( src, dest ); + src.activate(); + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + ASSERT( dest.get_count(i) == 1, NULL ); + } + + // push only + tbb::atomic<int> counters3[N]; + tbb::flow::input_node<T> src3(g, source_body<T>() ); + + function_body<T> b3( counters3 ); + tbb::flow::function_node<T,bool> dest3(g, tbb::flow::unlimited, b3 ); + tbb::flow::make_edge( src3, dest3 ); + src3.activate(); + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + } + + // push & pull + tbb::flow::input_node<T> src2(g, source_body<T>() ); + tbb::atomic<int> counters2[N]; + function_body<T> b2( counters2 ); + tbb::flow::function_node<T,bool,tbb::flow::rejecting> dest2(g, tbb::flow::serial, b2 ); + tbb::flow::make_edge( src2, dest2 ); + src2.activate(); + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters2[i]; + ASSERT( v == 1, NULL ); + } + + // test copy constructor + tbb::flow::input_node<T> src_copy(src); + test_push_receiver<T> dest_c(g); + ASSERT( src_copy.register_successor(dest_c), NULL ); + src_copy.activate(); + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + ASSERT( dest_c.get_count(i) == 1, NULL ); + } +} + +void test_reset() { + // source_node -> function_node + tbb::flow::graph g; + tbb::atomic<int> counters3[N]; + tbb::flow::input_node<int> src3(g, source_body<int>() ); + tbb::flow::input_node<int> src_inactive(g, source_body<int>()); + function_body<int> b3( counters3 ); + tbb::flow::function_node<int,bool> dest3(g, tbb::flow::unlimited, b3 ); + tbb::flow::make_edge( src3, dest3 ); + src3.activate(); + // source_node is now in active state. Let the graph run, + g.wait_for_all(); + // check the array for each value. + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + counters3[i] = 0; + } + + g.reset(tbb::flow::rf_reset_bodies); // <-- re-initializes the counts. + // and spawns task to run source + src3.activate(); + + g.wait_for_all(); + // check output queue again. Should be the same contents. + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + counters3[i] = 0; + } + g.reset(); // doesn't reset the source_node_body to initial state, but does spawn a task + // to run the source_node. + + g.wait_for_all(); + // array should be all zero + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } + + remove_edge(src3, dest3); + make_edge(src_inactive, dest3); + + // src_inactive doesn't run + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } + + // run graph + src_inactive.activate(); + g.wait_for_all(); + // check output + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + counters3[i] = 0; + } + g.reset(tbb::flow::rf_reset_bodies); // <-- reinitializes the counts + // src_inactive doesn't run + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } + + // start it up + src_inactive.activate(); + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + counters3[i] = 0; + } + g.reset(); // doesn't reset the source_node_body to initial state, and doesn't + // spawn a task to run the source_node. + + g.wait_for_all(); + // array should be all zero + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } + src_inactive.activate(); + // source_node_body is already in final state, so source_node will not forward a message. + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } +} + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool source_body_f(int& i) { return i > 5; } +#else + int source_body_f(tbb::flow_control&) { return 42; } +#endif +void test_deduction_guides() { + using namespace tbb::flow; + graph g; + +#if TBB_DEPRECATED_INPUT_NODE_BODY + auto lambda = [](int& i) { return i > 5; }; + auto non_const_lambda = [](int& i) mutable { return i > 5; }; +#else + auto lambda = [](tbb::flow_control&) { return 42; }; + auto non_const_lambda = [](tbb::flow_control&) mutable { return 42; }; +#endif + // Tests for source_node(graph&, Body) + input_node s1(g, lambda); + static_assert(std::is_same_v<decltype(s1), input_node<int>>); + + input_node s2(g, non_const_lambda); + static_assert(std::is_same_v<decltype(s2), input_node<int>>); + + input_node s3(g, source_body_f); + static_assert(std::is_same_v<decltype(s3), input_node<int>>); + + input_node s4(s3); + static_assert(std::is_same_v<decltype(s4), input_node<int>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + broadcast_node<int> bc(g); + + // Tests for source_node(const node_set<Args...>&, Body) + input_node s5(precedes(bc), lambda); + static_assert(std::is_same_v<decltype(s5), input_node<int>>); + + input_node s6(precedes(bc), non_const_lambda); + static_assert(std::is_same_v<decltype(s6), input_node<int>>); + + input_node s7(precedes(bc), source_body_f); + static_assert(std::is_same_v<decltype(s7), input_node<int>>); +#endif + g.wait_for_all(); +} + +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +void test_follows_and_precedes_api() { + using namespace tbb::flow; + + graph g; + + std::array<buffer_node<bool>, 3> successors {{ + buffer_node<bool>(g), + buffer_node<bool>(g), + buffer_node<bool>(g) + }}; + + bool do_try_put = true; + input_node<bool> src(precedes(successors[0], successors[1], successors[2]), + #if TBB_DEPRECATED_INPUT_NODE_BODY + [&](bool& v) -> bool { + if(do_try_put) { + v = do_try_put; + do_try_put = false; + return true; + } + else { + return false; + } + } + #else + [&](tbb::flow_control& fc) -> bool { + if(!do_try_put) + fc.stop(); + do_try_put = !do_try_put; + return true; + } + #endif + ); + + src.activate(); + g.wait_for_all(); + + bool storage; + for(auto& successor: successors) { + ASSERT((successor.try_get(storage) && !successor.try_get(storage)), + "Not exact edge quantity was made"); + } +} +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +int TestMain() { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for ( int p = MinThread; p < MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + test_single_dest<int>(); + test_single_dest<float>(); + } + test_reset(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract(); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_intrusive_list.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_intrusive_list.cpp new file mode 100644 index 00000000..c40f2043 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_intrusive_list.cpp @@ -0,0 +1,146 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" + +#include "../tbb/intrusive_list.h" + +using tbb::internal::intrusive_list_node; + +// Machine word filled with repeated pattern of FC bits +const uintptr_t NoliMeTangere = ~uintptr_t(0)/0xFF*0xFC; + +struct VerificationBase : Harness::NoAfterlife { + uintptr_t m_Canary; + VerificationBase () : m_Canary(NoliMeTangere) {} +}; + +struct DataItemWithInheritedNodeBase : intrusive_list_node { + int m_Data; +public: + DataItemWithInheritedNodeBase ( int value ) : m_Data(value) {} + + int Data() const { return m_Data; } +}; + +class DataItemWithInheritedNode : public VerificationBase, public DataItemWithInheritedNodeBase { + friend class tbb::internal::intrusive_list<DataItemWithInheritedNode>; +public: + DataItemWithInheritedNode ( int value ) : DataItemWithInheritedNodeBase(value) {} +}; + +struct DataItemWithMemberNodeBase { + int m_Data; +public: + // Cannot be used by member_intrusive_list to form lists of objects derived from DataItemBase + intrusive_list_node m_BaseNode; + + DataItemWithMemberNodeBase ( int value ) : m_Data(value) {} + + int Data() const { return m_Data; } +}; + +class DataItemWithMemberNodes : public VerificationBase, public DataItemWithMemberNodeBase { +public: + intrusive_list_node m_Node; + + DataItemWithMemberNodes ( int value ) : DataItemWithMemberNodeBase(value) {} +}; + +typedef tbb::internal::intrusive_list<DataItemWithInheritedNode> IntrusiveList1; +typedef tbb::internal::memptr_intrusive_list<DataItemWithMemberNodes, + DataItemWithMemberNodeBase, &DataItemWithMemberNodeBase::m_BaseNode> IntrusiveList2; +typedef tbb::internal::memptr_intrusive_list<DataItemWithMemberNodes, + DataItemWithMemberNodes, &DataItemWithMemberNodes::m_Node> IntrusiveList3; + +const int NumElements = 256 * 1024; + +//! Iterates through the list forward and backward checking the validity of values stored by the list nodes +template<class List, class Iterator> +void CheckListNodes ( List& il, int valueStep ) { + ASSERT( il.size()==unsigned(NumElements/valueStep), "Wrong size of the list" ); + ASSERT( !il.empty(), "Incorrect result of empty() or the list is corrupted" ); + int i; + Iterator it = il.begin(); + for ( i = valueStep - 1; it != il.end(); ++it, i += valueStep ) { + ASSERT( it->Data() == i, "Unexpected node value while iterating forward" ); + ASSERT( (*it).m_Canary == NoliMeTangere, "Memory corruption" ); + } + ASSERT( i == NumElements + valueStep - 1, "Wrong number of list elements while iterating forward" ); + it = il.end(); + for ( i = NumElements - 1, it--; it != il.end(); --it, i -= valueStep ) { + ASSERT( (*it).Data() == i, "Unexpected node value while iterating backward" ); + ASSERT( it->m_Canary == NoliMeTangere, "Memory corruption" ); + } + ASSERT( i == -1, "Wrong number of list elements while iterating backward" ); +} + +template<class List, class Item> +void TestListOperations () { + typedef typename List::iterator iterator; + List il; + for ( int i = NumElements - 1; i >= 0; --i ) + il.push_front( *new Item(i) ); + CheckListNodes<const List, typename List::const_iterator>( il, 1 ); + iterator it = il.begin(); + for ( ; it != il.end(); ++it ) { + Item &item = *it; + it = il.erase( it ); // also advances the iterator + delete &item; + } + CheckListNodes<List, iterator>( il, 2 ); + for ( it = il.begin(); it != il.end(); ++it ) { + Item &item = *it; + il.remove( *it++ ); // extra advance here as well + delete &item; + } + CheckListNodes<List, iterator>( il, 4 ); + for ( it = il.begin(); it != il.end(); ) { + Item &item = *it++; // the iterator advances only here + il.remove( item ); + delete &item; + } + ASSERT( il.size()==0, "The list has wrong size or not all items were removed" ); + ASSERT( il.empty(), "Incorrect result of empty() or not all items were removed" ); +} + +#include "harness_bad_expr.h" + +template<class List, class Item> +void TestListAssertions () { +#if TRY_BAD_EXPR_ENABLED + tbb::set_assertion_handler( AssertionFailureHandler ); + List il1, il2; + Item n1(1), n2(2), n3(3); + il1.push_front(n1); + TRY_BAD_EXPR( il2.push_front(n1), "only one intrusive list" ); + TRY_BAD_EXPR( il1.push_front(n1), "only one intrusive list" ); + il2.push_front(n2); + TRY_BAD_EXPR( il1.remove(n3), "not in the list" ); + tbb::set_assertion_handler( ReportError ); +#endif /* TRY_BAD_EXPR_ENABLED */ +} + +int TestMain () { + TestListOperations<IntrusiveList1, DataItemWithInheritedNode>(); + TestListOperations<IntrusiveList2, DataItemWithMemberNodes>(); + TestListOperations<IntrusiveList3, DataItemWithMemberNodes>(); + TestListAssertions<IntrusiveList1, DataItemWithInheritedNode>(); + TestListAssertions<IntrusiveList2, DataItemWithMemberNodes>(); + TestListAssertions<IntrusiveList3, DataItemWithMemberNodes>(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_iterators.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_iterators.cpp new file mode 100644 index 00000000..651ec6a0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_iterators.cpp @@ -0,0 +1,281 @@ +/* + Copyright (c) 2017-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +#if __TBB_CPP11_PRESENT + +#include "tbb/iterators.h" +#include "tbb/tbb_stddef.h" + +#include <vector> +#include <iostream> +#include <algorithm> +#include <numeric> +#include <type_traits> + +#include "harness.h" + +//common checks of a random access iterator functionality +template <typename RandomIt> +void test_random_iterator(const RandomIt& it) { + // check that RandomIt has all necessary publicly accessible member types + { + auto t1 = typename RandomIt::difference_type{}; + auto t2 = typename RandomIt::value_type{}; + auto t3 = typename RandomIt::pointer{}; + tbb::internal::suppress_unused_warning(t1,t2,t3); + typename RandomIt::reference ref = *it; + tbb::internal::suppress_unused_warning(ref); + typename RandomIt::iterator_category{}; + } + + ASSERT( it == it, "== returned false negative"); + ASSERT(!(it == it + 1), "== returned false positive"); + ASSERT( it != it + 1, "!= returned false negative"); + ASSERT(!(it != it), "!= returned false positive"); + + ASSERT(*it == *it, "wrong result with operator*"); + + RandomIt it1 = it; + ASSERT(it1 == it, "iterator is not copy constructible"); + RandomIt it2 = RandomIt(it); + ASSERT(it2 == it, "iterator is not move constructible"); + + ++it1; + ASSERT(it1 == it + 1, "wrong result with prefix operator++"); + + using std::swap; + swap(it1, it2); + ASSERT((it1 == it) && (it2 == it + 1), "iterator is not swappable"); + + it2 = it; + ASSERT(it2 == it, "iterator is not copy assignable"); + + ++it2; + it2 = RandomIt(it); + ASSERT(it2 == it, "iterator is not move assignable"); + + it1 = it; + ASSERT((it1++ == it) && (it1 == it + 1), "wrong result with postfix operator++"); + + it1 = it + 1; + ASSERT(--it1 == it, "wrong result with prefix operator--"); + + it1 = it + 1; + ASSERT((it1-- == it + 1) && (it1 == it), "wrong result with postfix operator--"); + + it1 += 1; + ASSERT(it1 == it + 1, "wrong result with operator+="); + + it1 -= 1; + ASSERT(it1 == it, "wrong result with operator-="); + + ASSERT(1 + it == it + 1, "n + iterator != iterator + n"); + + ASSERT((it + 1) - 1 == it, "wrong result with operator-(difference_type)"); + + ASSERT((it + 1) - it == 1, "wrong result with iterator subtraction"); + + ASSERT(it[1] == *(it + 1), "wrong result with operator[]"); + + ASSERT(it < it + 1, "operator< returned false negative"); + ASSERT(!(it < it), "operator< returned false positive"); + + ASSERT(it + 1 > it, "operator> returned false negative"); + ASSERT(!(it > it), "operator> returned false positive"); + + ASSERT(it <= it + 1, "operator<= returned false negative"); + ASSERT(it <= it, "operator<= returned false negative"); + ASSERT(!(it + 1 <= it), "operator<= returned false positive"); + + ASSERT(1 + it >= it, "operator>= returned false negative"); + ASSERT( it >= it, "operator>= returned false negative"); + ASSERT(!(it >= it + 1), "operator>= returned false positive"); +} + +struct test_counting_iterator { + template <typename T, typename IntType> + void operator()( std::vector<T>& in, IntType begin, IntType end, const T& value) { + ASSERT((0 <= begin) && (begin <= end) && (end <= IntType(in.size())), + "incorrect test_counting_iterator 'begin' and/or 'end' argument values"); + + //test that counting_iterator is default constructible + tbb::counting_iterator<IntType> b; + + b = tbb::counting_iterator<IntType>(begin); + auto e = tbb::counting_iterator<IntType>(end); + + //checks in using + std::for_each(b, e, [&in, &value](IntType i) { in[i] = value; }); + + auto res = std::all_of(in.begin(), in.begin() + begin, [&value](const T& a) {return a!=value;}); + ASSERT(res, "wrong result with counting_iterator in vector's begin portion"); + + res = std::all_of(in.begin() + begin, in.begin() + end, [&value](const T& a) {return a==value;}); + ASSERT(res, "wrong result with counting_iterator in vector's main portion"); + + res = std::all_of(in.begin() + end, in.end(), [&value](const T& a) {return a!=value;}); + ASSERT(res, "wrong result with counting_iterator in vector's end portion"); + + //explicit checks of the counting iterator specific + ASSERT(b[0]==begin, "wrong result with operator[] for an iterator"); + ASSERT(*(b + 1) == begin+1, "wrong result with operator+ for an iterator"); + ASSERT(*(b+=1) == begin+1, "wrong result with operator+= for an iterator"); + } +}; + +struct sort_fun{ + template<typename T1, typename T2> + bool operator()(T1 a1, T2 a2) const { + return std::get<0>(a1) < std::get<0>(a2); + } +}; + +template <typename InputIterator> +void test_explicit_move(InputIterator i, InputIterator j) { + using value_type = typename std::iterator_traits<InputIterator>::value_type; + value_type t(std::move(*i)); + *i = std::move(*j); + *j = std::move(t); +} + +struct test_zip_iterator { + template <typename T1, typename T2> + void operator()(std::vector<T1>& in1, std::vector<T2>& in2) { + //test that zip_iterator is default constructible + tbb::zip_iterator<decltype(in1.begin()), decltype(in2.begin())> b; + + b = tbb::make_zip_iterator(in1.begin(), in2.begin()); + auto e = tbb::make_zip_iterator(in1.end(), in2.end()); + + ASSERT( (b+1) != e, "size of input sequence insufficient for test" ); + + //simple check for-loop. + { + std::for_each(b, e, [](const std::tuple<T1&, T2&>& a) { std::get<0>(a) = 1, std::get<1>(a) = 1;}); + auto res = std::all_of(b, e, [](const std::tuple<T1&, T2&>& a) {return std::get<0>(a) == 1 && std::get<1>(a) == 1;}); + ASSERT(res, "wrong result sequence assignment to (1,1) with zip_iterator iterator"); + } + + //check swapping de-referenced iterators (required by sort algorithm) + { + using std::swap; + auto t = std::make_tuple(T1(3), T2(2)); + *b = t; + t = *(b+1); + ASSERT( std::get<0>(t) == 1 && std::get<1>(t) == 1, "wrong result of assignment from zip_iterator"); + swap(*b, *(b+1)); + ASSERT( std::get<0>(*b) == 1 && std::get<1>(*b) == 1, "wrong result swapping zip-iterator"); + ASSERT( std::get<0>(*(b+1)) == 3 && std::get<1>(*(b+1)) == 2, "wrong result swapping zip-iterator"); + // Test leaves sequence un-sorted. + } + + //sort sequences by first stream. + { + // sanity check if sequence is un-sorted. + auto res = std::is_sorted(b, e, sort_fun()); + ASSERT(!res, "input sequence to be sorted is already sorted! Test might lead to false positives."); + std::sort(tbb::make_zip_iterator(in1.begin(), in2.begin()), + tbb::make_zip_iterator(in1.end(), in2.end()), + sort_fun()); + res = std::is_sorted(b, e, sort_fun()); + ASSERT(res, "wrong result sorting sequence using zip-iterator"); + // TODO: Add simple check: comparison with sort_fun(). + } + test_explicit_move(b, b+1); + auto iter_base = b.base(); + static_assert(std::is_same<decltype(iter_base), + std::tuple<decltype(in1.begin()), decltype(in2.begin())>>::value, "base returned wrong type"); + ASSERT(std::get<0>(iter_base) == in1.begin(), "wrong result from base (get<0>)"); + ASSERT(std::get<1>(iter_base) == in2.begin(), "wrong result from base (get<1>)"); + + test_random_iterator(b); + } +}; + +template <typename VecIt1, typename VecIt2> +void test_transform_effect(VecIt1 first1, VecIt1 last1, VecIt2 first2) { + auto triple = [](typename std::iterator_traits<VecIt1>::value_type const& val) { + return typename std::iterator_traits<VecIt2>::value_type (3 * val); + }; + + std::copy( + tbb::make_transform_iterator(first1, triple), + tbb::make_transform_iterator(last1, triple), + first2 + ); + + for (typename std::iterator_traits<VecIt1>::difference_type i = 0; i < last1 - first1; ++i) + if ( first2[i] != (typename std::iterator_traits<VecIt2>::value_type) triple(first1[i]) ) { + std::cout << "wrong effect with transform iterator" << std::endl; + exit(1); + } +} + +struct test_transform_iterator { + template <typename T1, typename T2> + void operator()(std::vector<T1>& in1, std::vector<T2>& in2) { + std::iota(in1.begin(), in1.end(), T1(0)); + + test_transform_effect(in1.begin(), in1.end(), in2.begin()); + test_transform_effect(in1.cbegin(), in1.cend(), in2.begin()); + + auto new_transform_iterator = tbb::make_transform_iterator(in2.begin(), [](T2& x) { return x + 1; }); + test_random_iterator(new_transform_iterator); + } +}; + +template <typename T, typename IntType> +void test_iterator_by_type(IntType n) { + + const IntType beg = 0; + const IntType end = n; + + std::vector<T> in(n, T(0)); + std::vector<IntType> in2(n, IntType(0)); + + test_counting_iterator()(in, beg, end, /*value*/ T(-1)); + test_counting_iterator()(in, beg+123, end-321, /*value*/ T(42)); + test_random_iterator(tbb::counting_iterator<IntType>(beg)); + + test_zip_iterator()(in, in2); + test_transform_iterator()(in, in2); +} + +int TestMain() { + + const auto n1 = 1000; + const auto n2 = 100000; + + test_iterator_by_type<int16_t, int16_t>(n1); + test_iterator_by_type<int16_t, int64_t>(n2); + + test_iterator_by_type<double, int16_t>(n1); + test_iterator_by_type<double, int64_t>(n2); + + return Harness::Done; +} + +#else + +#include "harness.h" + +int TestMain () { + return Harness::Skipped; +} + +#endif /* __TBB_CPP11_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ittnotify.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ittnotify.cpp new file mode 100644 index 00000000..413074af --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_ittnotify.cpp @@ -0,0 +1,88 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 2 +#define HARNESS_DEFAULT_MAX_THREADS 2 + +#if !TBB_USE_THREADING_TOOLS + #define TBB_USE_THREADING_TOOLS 1 +#endif + +#include "harness.h" + +#if DO_ITT_NOTIFY + +#include "tbb/spin_mutex.h" +#include "tbb/spin_rw_mutex.h" +#include "tbb/queuing_rw_mutex.h" +#include "tbb/queuing_mutex.h" +#include "tbb/mutex.h" +#include "tbb/recursive_mutex.h" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" +#include "tbb/task_scheduler_init.h" + + +#include "../tbb/itt_notify.h" + +template<typename M> +class WorkEmulator: NoAssign { + M& m_mutex; + static volatile size_t s_anchor; +public: + void operator()( tbb::blocked_range<size_t>& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + typename M::scoped_lock lock(m_mutex); + for ( size_t j = 0; j!=range.end(); ++j ) + s_anchor = (s_anchor - i) / 2 + (s_anchor + j) / 2; + } + } + WorkEmulator( M& mutex ) : m_mutex(mutex) {} +}; + +template<typename M> +volatile size_t WorkEmulator<M>::s_anchor = 0; + + +template<class M> +void Test( const char * name ) { + REMARK("Testing %s\n",name); + M mtx; + tbb::profiling::set_name(mtx, name); + + const int n = 10000; + tbb::parallel_for( tbb::blocked_range<size_t>(0,n,n/100), WorkEmulator<M>(mtx) ); +} + +#define TEST_MUTEX(type, name) Test<tbb::type>( name ) + +#endif /* !DO_ITT_NOTIFY */ + +int TestMain () { +#if DO_ITT_NOTIFY + for( int p=MinThread; p<=MaxThread; ++p ) { + REMARK( "testing with %d workers\n", p ); + tbb::task_scheduler_init init( p ); + TEST_MUTEX( spin_mutex, "Spin Mutex" ); + TEST_MUTEX( queuing_mutex, "Queuing Mutex" ); + TEST_MUTEX( queuing_rw_mutex, "Queuing RW Mutex" ); + TEST_MUTEX( spin_rw_mutex, "Spin RW Mutex" ); + } + return Harness::Done; +#else /* !DO_ITT_NOTIFY */ + return Harness::Skipped; +#endif /* !DO_ITT_NOTIFY */ +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node.cpp new file mode 100644 index 00000000..cd86fd74 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node.cpp @@ -0,0 +1,192 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#endif +#include "test_join_node.h" + +static tbb::atomic<int> output_count; + +// get the tag from the output tuple and emit it. +// the first tuple component is tag * 2 cast to the type +template<typename OutputTupleType> +class recirc_output_func_body { +public: + // we only need this to use source_node_helper + typedef typename tbb::flow::join_node<OutputTupleType, tbb::flow::tag_matching> join_node_type; + static const int N = tbb::flow::tuple_size<OutputTupleType>::value; + int operator()(const OutputTupleType &v) { + int out = int(tbb::flow::get<0>(v))/2; + source_node_helper<N, join_node_type>::only_check_value(out, v); + ++output_count; + return out; + } +}; + +template<typename JType> +class tag_recirculation_test { +public: + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple<int, tbb::flow::continue_msg> input_tuple_type; + typedef tbb::flow::join_node<input_tuple_type, tbb::flow::reserving> input_join_type; + static const int N = tbb::flow::tuple_size<TType>::value; + static void test() { + source_node_helper<N, JType>::print_remark("Recirculation test of tag-matching join"); + REMARK(" >\n"); + for(int maxTag = 1; maxTag <10; maxTag *= 3) { + for(int i = 0; i < N; ++i) all_source_nodes[i][0] = NULL; + + tbb::flow::graph g; + // this is the tag-matching join we're testing + JType * my_join = makeJoin<N, JType, tbb::flow::tag_matching>::create(g); + // source_node for continue messages + tbb::flow::input_node<tbb::flow::continue_msg> snode(g, recirc_source_node_body()); + // reserving join that matches recirculating tags with continue messages. + input_join_type * my_input_join = makeJoin<2, input_join_type, tbb::flow::reserving>::create(g); + // tbb::flow::make_edge(snode, tbb::flow::input_port<1>(*my_input_join)); + tbb::flow::make_edge(snode, tbb::flow::get<1>(my_input_join->input_ports())); + // queue to hold the tags + tbb::flow::queue_node<int> tag_queue(g); + tbb::flow::make_edge(tag_queue, tbb::flow::input_port<0>(*my_input_join)); + // add all the function_nodes that are inputs to the tag-matching join + source_node_helper<N, JType>::add_recirc_func_nodes(*my_join, *my_input_join, g); + // add the function_node that accepts the output of the join and emits the int tag it was based on + tbb::flow::function_node<TType, int> recreate_tag(g, tbb::flow::unlimited, recirc_output_func_body<TType>()); + tbb::flow::make_edge(*my_join, recreate_tag); + // now the recirculating part (output back to the queue) + tbb::flow::make_edge(recreate_tag, tag_queue); + + // put the tags into the queue + for(int t = 1; t<=maxTag; ++t) tag_queue.try_put(t); + + input_count = Recirc_count; + output_count = 0; + + // start up the source node to get things going + snode.activate(); + + // wait for everything to stop + g.wait_for_all(); + + ASSERT(output_count==Recirc_count, "not all instances were received"); + + int j; + // grab the tags from the queue, record them + std::vector<bool> out_tally(maxTag, false); + for(int i = 0; i < maxTag; ++i) { + ASSERT(tag_queue.try_get(j), "not enough tags in queue"); + ASSERT(!out_tally.at(j-1), "duplicate tag from queue"); + out_tally[j-1] = true; + } + ASSERT(!tag_queue.try_get(j), "Extra tags in recirculation queue"); + + // deconstruct graph + source_node_helper<N, JType>::remove_recirc_func_nodes(*my_join, *my_input_join); + tbb::flow::remove_edge(*my_join, recreate_tag); + makeJoin<N, JType, tbb::flow::tag_matching>::destroy(my_join); + tbb::flow::remove_edge(tag_queue, tbb::flow::input_port<0>(*my_input_join)); + tbb::flow::remove_edge(snode, tbb::flow::input_port<1>(*my_input_join)); + makeJoin<2, input_join_type, tbb::flow::reserving>::destroy(my_input_join); + } + } +}; + +template<typename JType> +class generate_recirc_test { +public: + typedef tbb::flow::join_node<JType, tbb::flow::tag_matching> join_node_type; + static void do_test() { + tag_recirculation_test<join_node_type>::test(); + } +}; + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + using msg_t = tbb::flow::continue_msg; + using JoinOutputType = tbb::flow::tuple<msg_t, msg_t, msg_t>; + + std::array<msg_t, 3> messages_for_follows = { {msg_t(), msg_t(), msg_t()} }; + std::vector<msg_t> messages_for_precedes = {msg_t(), msg_t(), msg_t()}; + + follows_and_precedes_testing::test_follows + <msg_t, tbb::flow::join_node<JoinOutputType>, tbb::flow::buffer_node<msg_t>>(messages_for_follows); + follows_and_precedes_testing::test_follows + <msg_t, tbb::flow::join_node<JoinOutputType, tbb::flow::queueing>>(messages_for_follows); + follows_and_precedes_testing::test_follows + <msg_t, tbb::flow::join_node<JoinOutputType, tbb::flow::reserving>, tbb::flow::buffer_node<msg_t>>(messages_for_follows); + // TODO: add tests for key_matching and message based key matching + + follows_and_precedes_testing::test_precedes + <msg_t, tbb::flow::join_node<JoinOutputType>>(messages_for_precedes); + follows_and_precedes_testing::test_precedes + <msg_t, tbb::flow::join_node<JoinOutputType, tbb::flow::queueing>>(messages_for_precedes); + follows_and_precedes_testing::test_precedes + <msg_t, tbb::flow::join_node<JoinOutputType, tbb::flow::reserving>>(messages_for_precedes); +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + + graph g; + using tuple_type = std::tuple<int, int, int>; + broadcast_node<int> b1(g), b2(g), b3(g); + broadcast_node<tuple_type> b4(g); + join_node<tuple_type> j0(g); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + join_node j1(follows(b1, b2, b3)); + static_assert(std::is_same_v<decltype(j1), join_node<tuple_type>>); + + join_node j2(follows(b1, b2, b3), reserving()); + static_assert(std::is_same_v<decltype(j2), join_node<tuple_type, reserving>>); + + join_node j3(precedes(b4)); + static_assert(std::is_same_v<decltype(j3), join_node<tuple_type>>); + + join_node j4(precedes(b4), reserving()); + static_assert(std::is_same_v<decltype(j4), join_node<tuple_type, reserving>>); +#endif + + join_node j5(j0); + static_assert(std::is_same_v<decltype(j5), join_node<tuple_type>>); +} + +#endif + +int TestMain() { +#if __TBB_USE_TBB_TUPLE + REMARK(" Using TBB tuple\n"); +#else + REMARK(" Using platform tuple\n"); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + TestTaggedBuffers(); + test_main<tbb::flow::queueing>(); + test_main<tbb::flow::reserving>(); + test_main<tbb::flow::tag_matching>(); + generate_recirc_test<tbb::flow::tuple<int,float> >::do_test(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node.h new file mode 100644 index 00000000..3c53bd13 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node.h @@ -0,0 +1,2177 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef tbb_test_join_node_H +#define tbb_test_join_node_H + +#if _MSC_VER +// Suppress "decorated name length exceeded, name was truncated" warning +#if __INTEL_COMPILER +#pragma warning( disable: 2586 ) +#else +#pragma warning( disable: 4503 ) +#endif +#endif + +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#include "harness.h" +#include "harness_graph.h" +#include "harness_checktype.h" + +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include "test_follows_and_precedes_api.h" + +#define __TBB_MIC_OFFLOAD_TEST_COMPILATION_BROKEN __TBB_MIC_OFFLOAD + +const char *names[] = { + "Adam", "Bruce", "Charles", "Daniel", "Evan", "Frederich", "George", "Hiram", "Ichabod", + "John", "Kevin", "Leonard", "Michael", "Ned", "Olin", "Paul", "Quentin", "Ralph", "Steven", + "Thomas", "Ulysses", "Victor", "Walter", "Xerxes", "Yitzhak", "Zebediah", "Anne", "Bethany", + "Clarisse", "Dorothy", "Erin", "Fatima", "Gabrielle", "Helen", "Irene", "Jacqueline", + "Katherine", "Lana", "Marilyn", "Noelle", "Okiilani", "Pauline", "Querida", "Rose", "Sybil", + "Tatiana", "Umiko", "Victoria", "Wilma", "Xena", "Yolanda", "Zoe", "Algernon", "Benjamin", + "Caleb", "Dylan", "Ezra", "Felix", "Gabriel", "Henry", "Issac", "Jasper", "Keifer", + "Lincoln", "Milo", "Nathaniel", "Owen", "Peter", "Quincy", "Ronan", "Silas", "Theodore", + "Uriah", "Vincent", "Wilbur", "Xavier", "Yoda", "Zachary", "Amelia", "Brielle", "Charlotte", + "Daphne", "Emma", "Fiona", "Grace", "Hazel", "Isla", "Juliet", "Keira", "Lily", "Mia", + "Nora", "Olivia", "Penelope", "Quintana", "Ruby", "Sophia", "Tessa", "Ursula", "Violet", + "Willow", "Xanthe", "Yvonne", "ZsaZsa", "Asher", "Bennett", "Connor", "Dominic", "Ethan", + "Finn", "Grayson", "Hudson", "Ian", "Jackson", "Kent", "Liam", "Matthew", "Noah", "Oliver", + "Parker", "Quinn", "Rhys", "Sebastian", "Taylor", "Umberto", "Vito", "William", "Xanto", + "Yogi", "Zane", "Ava", "Brenda", "Chloe", "Delilah", "Ella", "Felicity", "Genevieve", + "Hannah", "Isabella", "Josephine", "Kacie", "Lucy", "Madeline", "Natalie", "Octavia", + "Piper", "Qismah", "Rosalie", "Scarlett", "Tanya", "Uta", "Vivian", "Wendy", "Xola", + "Yaritza", "Zanthe"}; + +static const int NameCnt = sizeof(names)/sizeof(char *); + +template<typename K> +struct index_to_key { + K operator()(const int indx) { + return (K)(3*indx+1); + } +}; + +template<> +struct index_to_key<std::string> { + std::string operator()(const int indx) { + return std::string(names[indx % NameCnt]); + } +}; + +template<typename K> +struct K_deref { + typedef K type; +}; + +template<typename K> +struct K_deref<K&> { + typedef K type; +}; + +template<typename K, typename V> +struct MyKeyFirst { + K my_key; + V my_value; + MyKeyFirst(int i = 0, int v = 0): my_key(index_to_key<K>()(i)), my_value((V)v) { + } + void print_val() const { + REMARK("MyKeyFirst{"); print_my_value(my_key); REMARK(","); print_my_value(my_value); REMARK("}"); + } + operator int() const { return (int)my_value; } +}; + +template<typename K, typename V> +struct MyKeySecond { + V my_value; + K my_key; + MyKeySecond(int i = 0, int v = 0): my_value((V)v), my_key(index_to_key<K>()(i)) { + } + void print_val() const { + REMARK("MyKeySecond{"); print_my_value(my_key); REMARK(","); print_my_value(my_value); REMARK("}"); + } + operator int() const { return (int)my_value; } +}; + +template<typename K, typename V> +struct MyMessageKeyWithoutKey { + V my_value; + K my_message_key; + MyMessageKeyWithoutKey(int i = 0, int v = 0): my_value((V)v), my_message_key(index_to_key<K>()(i)) { + } + void print_val() const { + REMARK("MyMessageKeyWithoutKey{"); print_my_value(my_message_key); REMARK(","); print_my_value(my_value); REMARK("}"); + } + operator int() const { return (int)my_value; } + const K& key() const { + return my_message_key; + } +}; + +template<typename K, typename V> +struct MyMessageKeyWithBrokenKey { + V my_value; + K my_key; + K my_message_key; + MyMessageKeyWithBrokenKey(int i = 0, int v = 0): my_value((V)v), my_key(), my_message_key(index_to_key<K>()(i)) { + } + void print_val() const { + REMARK("MyMessageKeyWithBrokenKey{"); print_my_value(my_message_key); REMARK(","); print_my_value(my_value); REMARK("}"); + } + operator int() const { return (int)my_value; } + const K& key() const { + return my_message_key; + } + +}; + +template<typename K, typename V> +struct MyKeyWithBrokenMessageKey { + V my_value; + K my_key; + MyKeyWithBrokenMessageKey(int i = 0, int v = 0): my_value((V)v), my_key(index_to_key<K>()(i)) { + } + void print_val() const { + REMARK("MyKeyWithBrokenMessageKey{"); print_my_value(my_key); REMARK(","); print_my_value(my_value); REMARK("}"); + } + operator int() const { return (int)my_value; } + K key() const { + ASSERT(false, "The method should never be called"); + return K(); + } +}; + +template<typename K, typename V> +struct MyMessageKeyWithoutKeyMethod { + V my_value; + K my_message_key; + MyMessageKeyWithoutKeyMethod(int i = 0, int v = 0): my_value((V)v), my_message_key(index_to_key<K>()(i)) { + } + void print_val() const { + REMARK("MyMessageKeyWithoutKeyMethod{"); print_my_value(my_message_key); REMARK(","); print_my_value(my_value); REMARK("}"); + } + operator int() const { return (int)my_value; } +#if __TBB_COMPLICATED_ADL_BROKEN + const K& key() const { return my_message_key; } +#endif + //K key() const; // Do not define +}; + +// Overload for MyMessageKeyWithoutKeyMethod +template <typename K, typename V> +K key_from_message(const MyMessageKeyWithoutKeyMethod<typename tbb::internal::strip<K>::type, V> &m) { + return m.my_message_key; +} + + +// pattern for creating values in the tag_matching and key_matching, given an integer and the index in the tuple +template<typename TT, size_t INDEX> +struct make_thingie { + TT operator()(int const &i) { + return TT(i * (INDEX+1)); + } +}; + +template<template <typename, typename> class T, typename K, typename V, size_t INDEX> +struct make_thingie<T<K, V>, INDEX> { + T<K, V> operator()(int const &i) { + return T<K, V>(i, i*(INDEX+1)); + } +}; + +// cast_from<T>::my_int_val(i); +template<typename T> +struct cast_from { + static int my_int_val(T const &i) { return (int)i; } +}; + +template<typename K, typename V> +struct cast_from<MyKeyFirst<K, V> > { + static int my_int_val(MyKeyFirst<K, V> const &i) { return (int)(i.my_value); } +}; + +template<typename K, typename V> +struct cast_from<MyKeySecond<K, V> > { + static int my_int_val(MyKeySecond<K, V> const &i) { return (int)(i.my_value); } +}; + +template<typename T> +void print_my_value(T const &i) { + REMARK(" %d ", cast_from<T>::my_int_val(i)); +} + +template<typename K, typename V> +void print_my_value(MyKeyFirst<K, V> const &i) { + i.print_val(); +} + +template<typename K, typename V> +void print_my_value(MyKeySecond<K, V> const &i) { + i.print_val(); +} + +template<> +void print_my_value(std::string const &i) { + REMARK("\"%s\"", i.c_str()); +} + +// +// Tests +// + +//! +// my_struct_key == given a type V with a field named my_key of type K, will return a copy of my_key +template<class K, typename V> +struct my_struct_key { + K operator()(const V& mv) { + return mv.my_key; + } +}; + +// specialization returning reference to my_key. +template<class K, typename V> +struct my_struct_key<K&, V> { + const K& operator()(const V& mv) { + return const_cast<const K&>(mv.my_key); + } +}; + +using tbb::internal::is_ref; + +template<class K, class V> struct VtoKFB { + typedef tbb::flow::interface11::internal::type_to_key_function_body<V, K> type; +}; + +template<typename K> struct make_hash_compare { typedef typename tbb::tbb_hash_compare<K> type; }; + +template<typename K, class V> +void hash_buffer_test(const char *sname) { + typedef typename K_deref<K>::type KnoR; + tbb::flow::interface11::internal::hash_buffer< + K, + V, + typename VtoKFB<K, V>::type, + tbb::tbb_hash_compare<KnoR> + > my_hash_buffer; + const bool k_is_ref = is_ref<K>::value; + typedef tbb::flow::interface11::internal::type_to_key_function_body_leaf< + V, K, my_struct_key<K, V> > my_func_body_type; + typename VtoKFB<K, V>::type *kp = new my_func_body_type(my_struct_key<K, V>()); + my_hash_buffer.set_key_func(kp); + REMARK("Running hash_buffer test on %s; is ref == %s\n", sname, k_is_ref ? "true" : "false"); + V mv1, mv0; + bool res; + for(int cnt = 0; cnt < 2; ++cnt) { + // insert 50 items after checking they are not already in the table + for(int i = 0; i < 50; ++i) { + KnoR kk = index_to_key<KnoR>()(i); + mv1.my_key = kk; + mv1.my_value = 0.5*i; + res = my_hash_buffer.find_with_key(kk, mv0); + ASSERT(!res, "Found non-inserted item"); + res = my_hash_buffer.insert_with_key(mv1); + ASSERT(res, "insert failed"); + res = my_hash_buffer.find_with_key(kk, mv0); + ASSERT(res, "not found after insert"); + ASSERT(mv0.my_value==mv1.my_value, "result not correct"); + } + // go backwards checking they are still there. + for(int i = 49; i>=0; --i) { + KnoR kk = index_to_key<KnoR>()(i); + double value = 0.5*i; + res = my_hash_buffer.find_with_key(kk, mv0); + ASSERT(res, "find failed"); + ASSERT(mv0.my_value==value, "result not correct"); + } + // delete every third item, check they are gone + for(int i = 0; i < 50; i += 3) { + KnoR kk = index_to_key<KnoR>()(i); + my_hash_buffer.delete_with_key(kk); + res = my_hash_buffer.find_with_key(kk, mv0); + ASSERT(!res, "Found deleted item"); + } + // check the deleted items are gone, the non-deleted items are there. + for(int i = 0; i < 50; ++i) { + KnoR kk = index_to_key<KnoR>()(i); + double value = 0.5*i; + if(i%3==0) { + res = my_hash_buffer.find_with_key(kk, mv0); + ASSERT(!res, "found an item that was previously deleted"); + } + else { + res = my_hash_buffer.find_with_key(kk, mv0); + ASSERT(res, "find failed"); + ASSERT(mv0.my_value==value, "result not correct"); + } + } + // insert new items, check the deleted items return true, the non-deleted items return false. + for(int i = 0; i < 50; ++i) { + KnoR kk = index_to_key<KnoR>()(i); + double value = 1.5*i; + mv1.my_key = kk; + mv1.my_value = value; + res = my_hash_buffer.insert_with_key(mv1); + if(i%3==0) { + ASSERT(res, "didn't insert in empty slot"); + } + else { + ASSERT(!res, "slot was empty on insert"); + } + } + // delete all items + for(int i = 0; i < 50; ++i) { + KnoR kk = index_to_key<KnoR>()(i); + my_hash_buffer.delete_with_key(kk); + res = my_hash_buffer.find_with_key(kk, mv0); + ASSERT(!res, "Found deleted item"); + } + } // perform tasks twice +} + +void +TestTaggedBuffers() { + hash_buffer_test<int, MyKeyFirst<int, double> >("MyKeyFirst<int,double>"); + hash_buffer_test<int&, MyKeyFirst<int, double> >("MyKeyFirst<int,double> with int&"); + hash_buffer_test<int, MyKeySecond<int, double> >("MyKeySecond<int,double>"); + + hash_buffer_test<std::string, MyKeyFirst<std::string, double> >("MyKeyFirst<std::string,double>"); + hash_buffer_test<std::string&, MyKeySecond<std::string, double> >("MyKeySecond<std::string,double> with std::string&"); +} + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +template< typename T, typename NODE_TYPE > +class test_join_base_extract : NoAssign { +protected: + typedef typename NODE_TYPE::output_type tuple_t; + typedef tbb::flow::queue_node<T> in_queue_t; + typedef tbb::flow::queue_node<tuple_t> out_queue_t; + + tbb::flow::graph &g; + in_queue_t &in0; + in_queue_t &in1; + in_queue_t &in2; + NODE_TYPE &middle; + out_queue_t &out0; + out_queue_t &out1; + in_queue_t *ins[3]; + out_queue_t *outs[2]; + typename in_queue_t::successor_type *ms_p0_ptr; + typename in_queue_t::successor_type *ms_p1_ptr; + typename out_queue_t::predecessor_type *mp_ptr; + typename in_queue_t::predecessor_list_type in0_p_list; + typename in_queue_t::successor_list_type in0_s_list; + typename in_queue_t::predecessor_list_type in1_p_list; + typename in_queue_t::successor_list_type in1_s_list; + typename in_queue_t::predecessor_list_type in2_p_list; + typename in_queue_t::successor_list_type in2_s_list; + typename out_queue_t::predecessor_list_type out0_p_list; + typename out_queue_t::successor_list_type out0_s_list; + typename out_queue_t::predecessor_list_type out1_p_list; + typename out_queue_t::successor_list_type out1_s_list; + typename in_queue_t::predecessor_list_type mp0_list; + typename in_queue_t::predecessor_list_type mp1_list; + typename out_queue_t::successor_list_type ms_list; + + virtual void set_up_lists() { + in0_p_list.clear(); + in0_s_list.clear(); + in1_p_list.clear(); + in1_s_list.clear(); + in2_p_list.clear(); + in2_s_list.clear(); + out0_p_list.clear(); + out0_s_list.clear(); + out1_p_list.clear(); + out1_s_list.clear(); + mp0_list.clear(); + mp1_list.clear(); + ms_list.clear(); + + in0.copy_predecessors(in0_p_list); + in0.copy_successors(in0_s_list); + in1.copy_predecessors(in1_p_list); + in1.copy_successors(in1_s_list); + in2.copy_predecessors(in2_p_list); + in2.copy_successors(in2_s_list); + tbb::flow::input_port<0>(middle).copy_predecessors(mp0_list); + tbb::flow::input_port<1>(middle).copy_predecessors(mp1_list); + middle.copy_successors(ms_list); + out0.copy_predecessors(out0_p_list); + out0.copy_successors(out0_s_list); + out1.copy_predecessors(out1_p_list); + out1.copy_successors(out1_s_list); + } + + void check_tuple(T &r, tuple_t &v) { + T t0 = tbb::flow::get<0>(v); + T t1 = tbb::flow::get<1>(v); + ASSERT((t0==1||t0==2)&&(t0&r)==0, "duplicate value"); + r |= t0; + ASSERT((t1==4||t1==8)&&(t1&r)==0, "duplicate value"); + r |= t1; + } + + void make_and_validate_full_graph() { + /* in0 */ + /* \ */ + /* port0 out0 */ + /* / | / */ + /* in1 middle */ + /* | \ */ + /* in2 - port1 out1 */ + tbb::flow::make_edge(in0, tbb::flow::input_port<0>(middle)); + tbb::flow::make_edge(in1, tbb::flow::input_port<0>(middle)); + tbb::flow::make_edge(in2, tbb::flow::input_port<1>(middle)); + tbb::flow::make_edge(middle, out0); + tbb::flow::make_edge(middle, out1); + + set_up_lists(); + + ASSERT(in0.predecessor_count()==0&&in0_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in0.successor_count()==1&&in0_s_list.size()==1&&*(in0_s_list.begin())==ms_p0_ptr, "expected 1 successor"); + ASSERT(in1.predecessor_count()==0&&in1_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in1.successor_count()==1&&in1_s_list.size()==1&&*(in1_s_list.begin())==ms_p0_ptr, "expected 1 successor"); + ASSERT(in2.predecessor_count()==0&&in2_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in2.successor_count()==1&&in2_s_list.size()==1&&*(in2_s_list.begin())==ms_p1_ptr, "expected 1 successor"); + ASSERT(tbb::flow::input_port<0>(middle).predecessor_count()==2&&mp0_list.size()==2, "expected 2 predecessors"); + ASSERT(tbb::flow::input_port<1>(middle).predecessor_count()==1&&mp1_list.size()==1, "expected 1 predecessors"); + ASSERT(middle.successor_count()==2&&ms_list.size()==2, "expected 2 successors"); + ASSERT(out0.predecessor_count()==1&&out0_p_list.size()==1&&*(out0_p_list.begin())==mp_ptr, "expected 1 predecessor"); + ASSERT(out0.successor_count()==0&&out0_s_list.size()==0, "expected 0 successors"); + ASSERT(out1.predecessor_count()==1&&out1_p_list.size()==1&&*(out1_p_list.begin())==mp_ptr, "expected 1 predecessor"); + ASSERT(out1.successor_count()==0&&out1_s_list.size()==0, "expected 0 successors"); + + typename in_queue_t::predecessor_list_type::iterator mp0_list_iter = mp0_list.begin(); ++mp0_list_iter; + int first_pred = *(mp0_list.begin())==ins[0] ? 0 : (*(mp0_list.begin())==ins[1] ? 1 : -1); + int second_pred = *mp0_list_iter==ins[0] ? 0 : (*mp0_list_iter==ins[1] ? 1 : -1); + ASSERT(first_pred!=-1&&second_pred!=-1&&first_pred!=second_pred, "bad predecessor(s) for middle port 0"); + + ASSERT(*(mp1_list.begin())==ins[2], "bad predecessor for middle port 1"); + + typename out_queue_t::successor_list_type::iterator ms_list_iter = ms_list.begin(); ++ms_list_iter; + int first_succ = *(ms_list.begin())==outs[0] ? 0 : (*(ms_list.begin())==outs[1] ? 1 : -1); + int second_succ = *ms_list_iter==outs[0] ? 0 : (*ms_list_iter==outs[1] ? 1 : -1); + ASSERT(first_succ!=-1&&second_succ!=-1&&first_succ!=second_succ, "bad successor(s) for middle"); + + in0.try_put(1); + in1.try_put(2); + in2.try_put(8); + in2.try_put(4); + g.wait_for_all(); + + T v_in; + tuple_t v; + + ASSERT(in0.try_get(v_in)==false, "buffer should not have a value"); + ASSERT(in1.try_get(v_in)==false, "buffer should not have a value"); + ASSERT(in1.try_get(v_in)==false, "buffer should not have a value"); + ASSERT(in2.try_get(v_in)==false, "buffer should not have a value"); + ASSERT(in2.try_get(v_in)==false, "buffer should not have a value"); + + T r = 0; + while(out0.try_get(v)) { + check_tuple(r, v); + g.wait_for_all(); + } + ASSERT(r==15, "not all values received"); + + r = 0; + while(out1.try_get(v)) { + check_tuple(r, v); + g.wait_for_all(); + } + ASSERT(r==15, "not all values received"); + g.wait_for_all(); + } + + void validate_partial_graph() { + /* in0 */ + /* */ + /* port0 out0 */ + /* / | */ + /* in1 middle */ + /* | \ */ + /* in2 - port1 out1 */ + set_up_lists(); + + ASSERT(in0.predecessor_count()==0&&in0_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in0.successor_count()==0&&in0_s_list.size()==0, "expected 0 successors"); + ASSERT(in1.predecessor_count()==0&&in1_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in1.successor_count()==1&&in1_s_list.size()==1&&*(in1_s_list.begin())==ms_p0_ptr, "expected 1 successor"); + ASSERT(in2.predecessor_count()==0&&in2_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in2.successor_count()==1&&in2_s_list.size()==1&&*(in2_s_list.begin())==ms_p1_ptr, "expected 1 successor"); + ASSERT(tbb::flow::input_port<0>(middle).predecessor_count()==1&&mp0_list.size()==1&&*(mp0_list.begin())==ins[1], "expected 1 predecessor"); + ASSERT(tbb::flow::input_port<1>(middle).predecessor_count()==1&&mp1_list.size()==1&&*(mp1_list.begin())==ins[2], "expected 1 predecessor"); + ASSERT(middle.successor_count()==1&&ms_list.size()==1&&*(ms_list.begin())==outs[1], "expected 1 successor"); + ASSERT(out0.predecessor_count()==0&&out0_p_list.size()==0, "expected 1 predecessor"); + ASSERT(out0.successor_count()==0&&out0_s_list.size()==0, "expected 0 successors"); + ASSERT(out1.predecessor_count()==1&&out1_p_list.size()==1&&*(out1_p_list.begin())==mp_ptr, "expected 1 predecessor"); + ASSERT(out1.successor_count()==0&&out1_s_list.size()==0, "expected 0 successors"); + + in0.try_put(1); + in1.try_put(2); + in2.try_put(8); + in2.try_put(4); + g.wait_for_all(); + + T v_in; + tuple_t v; + + ASSERT(in0.try_get(v_in)==true&&v_in==1, "buffer should have a value of 1"); + ASSERT(in1.try_get(v_in)==false, "buffer should not have a value"); + ASSERT(out0.try_get(v)==false, "buffer should not have a value"); + ASSERT(out1.try_get(v)==true&&tbb::flow::get<0>(v)==2&&tbb::flow::get<1>(v)==8, "buffer should have a value of < 2, 8 >"); + ASSERT(in0.try_get(v_in)==false, "buffer should not have a value"); + g.wait_for_all(); + g.reset(); // for queueing and tag_matching the 4 is now in the join + } + + void validate_empty_graph() { + /* in0 */ + /* */ + /* port0 out0 */ + /* | */ + /* in1 middle */ + /* | */ + /* in2 port1 out1 */ + set_up_lists(); + + ASSERT(in0.predecessor_count()==0&&in0_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in0.successor_count()==0&&in0_s_list.size()==0, "expected 0 successors"); + ASSERT(in1.predecessor_count()==0&&in1_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in1.successor_count()==0&&in1_s_list.size()==0, "expected 0 successors"); + ASSERT(in2.predecessor_count()==0&&in2_p_list.size()==0, "expected 0 predecessors"); + ASSERT(in2.successor_count()==0&&in2_s_list.size()==0, "expected 0 successors"); + ASSERT(tbb::flow::input_port<0>(middle).predecessor_count()==0&&mp0_list.size()==0, "expected 0 predecessors"); + ASSERT(tbb::flow::input_port<1>(middle).predecessor_count()==0&&mp1_list.size()==0, "expected 0 predecessors"); + ASSERT(middle.successor_count()==0&&ms_list.size()==0, "expected 0 successors"); + ASSERT(out0.predecessor_count()==0&&out0_p_list.size()==0, "expected 0 predecessors"); + ASSERT(out0.successor_count()==0&&out0_s_list.size()==0, "expected 0 successors"); + ASSERT(out1.predecessor_count()==0&&out1_p_list.size()==0, "expected 0 predecessors"); + ASSERT(out1.successor_count()==0&&out1_s_list.size()==0, "expected 0 successors"); + + in0.try_put(1); + in1.try_put(2); + in2.try_put(8); + in2.try_put(4); + g.wait_for_all(); + + T v_in; + tuple_t v; + + ASSERT(in0.try_get(v_in)==true&&v_in==1, "buffer should have a value of 1"); + ASSERT(in1.try_get(v_in)==true&&v_in==2, "buffer should have a value of 2"); + ASSERT(in2.try_get(v_in)==true&&v_in==8, "buffer should have a value of 8"); + ASSERT(in2.try_get(v_in)==true&&v_in==4, "buffer should have a value of 4"); + ASSERT(out0.try_get(v)==false, "buffer should not have a value"); + ASSERT(out1.try_get(v)==false, "buffer should not have a value"); + g.wait_for_all(); + g.reset(); // NOTE: this should not be necessary!!!!! But it is!!!! + } + +public: + + test_join_base_extract(tbb::flow::graph &_g, in_queue_t &_in0, in_queue_t &_in1, in_queue_t &_in2, NODE_TYPE &m, out_queue_t &_out0, out_queue_t &_out1): + g(_g), in0(_in0), in1(_in1), in2(_in2), middle(m), out0(_out0), out1(_out1) { + ins[0] = &in0; + ins[1] = &in1; + ins[2] = &in2; + outs[0] = &out0; + outs[1] = &out1; + ms_p0_ptr = static_cast< typename in_queue_t::successor_type * >(&tbb::flow::input_port<0>(middle)); + ms_p1_ptr = static_cast< typename in_queue_t::successor_type * >(&tbb::flow::input_port<1>(middle)); + mp_ptr = static_cast< typename out_queue_t::predecessor_type *>(&middle); + } + + virtual ~test_join_base_extract() {} + + void run_tests() { + REMARK("full graph\n"); + make_and_validate_full_graph(); + + in0.extract(); + out0.extract(); + REMARK("partial graph\n"); + validate_partial_graph(); + + in1.extract(); + in2.extract(); + out1.extract(); + REMARK("empty graph\n"); + validate_empty_graph(); + + REMARK("full graph\n"); + make_and_validate_full_graph(); + + middle.extract(); + REMARK("empty graph\n"); + validate_empty_graph(); + + REMARK("full graph\n"); + make_and_validate_full_graph(); + + in0.extract(); + in1.extract(); + in2.extract(); + middle.extract(); + REMARK("empty graph\n"); + validate_empty_graph(); + + REMARK("full graph\n"); + make_and_validate_full_graph(); + + out0.extract(); + out1.extract(); + middle.extract(); + REMARK("empty graph\n"); + validate_empty_graph(); + + REMARK("full graph\n"); + make_and_validate_full_graph(); + } +}; + +template< typename T, typename NODE_TYPE > +class test_join_extract : public test_join_base_extract< T, NODE_TYPE > { +protected: + typedef typename NODE_TYPE::output_type tuple_t; + typedef tbb::flow::queue_node<T> in_queue_t; + typedef tbb::flow::queue_node<tuple_t> out_queue_t; + + tbb::flow::graph my_g; + in_queue_t my_in0; + in_queue_t my_in1; + in_queue_t my_in2; + NODE_TYPE my_middle; + out_queue_t my_out0; + out_queue_t my_out1; + +public: + test_join_extract(): test_join_base_extract<T, NODE_TYPE>(my_g, my_in0, my_in1, my_in2, my_middle, my_out0, my_out1), + my_in0(my_g), my_in1(my_g), my_in2(my_g), my_middle(my_g), my_out0(my_g), my_out1(my_g) { } +}; + +template< typename T > +class test_join_extract<T, tbb::flow::join_node< tbb::flow::tuple<T, T>, tbb::flow::tag_matching> > : + public test_join_base_extract< T, tbb::flow::join_node< tbb::flow::tuple<T, T>, tbb::flow::tag_matching> > { +protected: + typedef tbb::flow::join_node< tbb::flow::tuple<T, T>, tbb::flow::tag_matching> my_node_t; + + typedef typename my_node_t::output_type tuple_t; + typedef tbb::flow::queue_node<T> in_queue_t; + typedef tbb::flow::queue_node<tuple_t> out_queue_t; + + tbb::flow::graph my_g; + in_queue_t my_in0; + in_queue_t my_in1; + in_queue_t my_in2; + my_node_t my_middle; + out_queue_t my_out0; + out_queue_t my_out1; + struct tag_match_0 { size_t operator()(T v) { return v; } }; + struct tag_match_1 { size_t operator()(T v) { return v/4; } }; +public: + test_join_extract(): test_join_base_extract<T, my_node_t>(my_g, my_in0, my_in1, my_in2, my_middle, my_out0, my_out1), + my_in0(my_g), my_in1(my_g), my_in2(my_g), my_middle(my_g, tag_match_0(), tag_match_1()), my_out0(my_g), my_out1(my_g) { } +}; +#endif + +struct threebyte { + unsigned char b1; + unsigned char b2; + unsigned char b3; + threebyte(int i = 0) { + b1 = (unsigned char)(i&0xFF); + b2 = (unsigned char)((i>>8)&0xFF); + b3 = (unsigned char)((i>>16)&0xFF); + } + operator int() const { return (int)(b1+(b2<<8)+(b3<<16)); } +}; + +const int Count = 150; + +const int Recirc_count = 1000; // number of tuples to be generated +const int MaxPorts = 10; +const int MaxNSources = 5; // max # of source_nodes to register for each join_node input in parallel test +bool outputCheck[MaxPorts][Count]; // for checking output + +void +check_outputCheck(int nUsed, int maxCnt) { + for(int i = 0; i < nUsed; ++i) { + for(int j = 0; j < maxCnt; ++j) { + ASSERT(outputCheck[i][j], NULL); + } + } +} + +void +reset_outputCheck(int nUsed, int maxCnt) { + for(int i = 0; i < nUsed; ++i) { + for(int j = 0; j < maxCnt; ++j) { + outputCheck[i][j] = false; + } + } +} + +template<typename T> +class name_of { +public: + static const char* name() { return "Unknown"; } +}; +template<typename T> +class name_of<check_type<T> > { +public: + static const char* name() { return "checktype"; } +}; +template<> +class name_of<int> { +public: + static const char* name() { return "int"; } +}; +template<> +class name_of<float> { +public: + static const char* name() { return "float"; } +}; +template<> +class name_of<double> { +public: + static const char* name() { return "double"; } +}; +template<> +class name_of<long> { +public: + static const char* name() { return "long"; } +}; +template<> +class name_of<short> { +public: + static const char* name() { return "short"; } +}; +template<> +class name_of<threebyte> { +public: + static const char* name() { return "threebyte"; } +}; +template<> +class name_of<std::string> { +public: + static const char* name() { return "std::string"; } +}; +template<typename K, typename V> +class name_of<MyKeyFirst<K, V> > { +public: + static const char* name() { return "MyKeyFirst<K,V>"; } +}; +template<typename K, typename V> +class name_of<MyKeySecond<K, V> > { +public: + static const char* name() { return "MyKeySecond<K,V>"; } +}; + +// The additional policy to differ message based key matching from usual key matching. +// It only has sense for the test because join_node is created with the key_matching policy for the both cases. +template <typename K, typename KHash = tbb::tbb_hash_compare<typename tbb::internal::strip<K>::type > > +struct message_based_key_matching {}; + +// test for key_matching +template<class JP> +struct is_key_matching_join { + static const bool value; + typedef int key_type; // have to define it to something +}; + +template<class JP> +const bool is_key_matching_join<JP>::value = false; + +template<class K, class KHash> +struct is_key_matching_join<tbb::flow::key_matching<K, KHash> > { + static const bool value; + typedef K key_type; +}; + +template<class K, class KHash> +const bool is_key_matching_join<tbb::flow::key_matching<K, KHash> >::value = true; + +template<class K, class KHash> +struct is_key_matching_join<message_based_key_matching<K, KHash> > { + static const bool value; + typedef K key_type; +}; + +template<class K, class KHash> +const bool is_key_matching_join<message_based_key_matching<K, KHash> >::value = true; + +// for recirculating tags, input is tuple<index,continue_msg> +// output is index*my_mult cast to the right type +template<typename TT> +class recirc_func_body { + TT my_mult; +public: + typedef tbb::flow::tuple<int, tbb::flow::continue_msg> input_type; + recirc_func_body(TT multiplier): my_mult(multiplier) {} + recirc_func_body(const recirc_func_body &other): my_mult(other.my_mult) { } + void operator=(const recirc_func_body &other) { my_mult = other.my_mult; } + TT operator()(const input_type &v) { + return TT(tbb::flow::get<0>(v)) * my_mult; + } +}; + +static int input_count; // source_nodes are serial + +// emit input_count continue_msg +class recirc_source_node_body { +public: +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(tbb::flow::continue_msg &v) { + --input_count; + v = tbb::flow::continue_msg(); + return 0<=input_count; + } +#else + tbb::flow::continue_msg operator()(tbb::flow_control &fc) { + if( --input_count < 0 ){ + fc.stop(); + } + return tbb::flow::continue_msg(); + } +#endif +}; + +// T must be arithmetic, and shouldn't wrap around for reasonable sizes of Count (which is now 150, and maxPorts is 10, +// so the max number generated right now is 1500 or so.) Source will generate a series of TT with value +// (init_val + (i-1)*addend) * my_mult, where i is the i-th invocation of the body. We are attaching addend +// source nodes to a join_port, and each will generate part of the numerical series the port is expecting +// to receive. If there is only one source node, the series order will be maintained; if more than one, +// this is not guaranteed. +template<typename TT, size_t INDEX> +class source_body { + int my_count; + int addend; +public: + source_body(int init_val, int addto): my_count(init_val), addend(addto) { } +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()(TT &v) { + int lc = my_count; + v = make_thingie<TT, INDEX>()(my_count); + my_count += addend; + return lc < Count; + } +#else + TT operator()(tbb::flow_control& fc) { + int lc = my_count; + TT ret = make_thingie<TT, INDEX>()(my_count); + my_count += addend; + if ( lc < Count){ + return ret; + }else{ + fc.stop(); + return TT(); + } + } +#endif +}; + +template<typename TT> +class tag_func { + TT my_mult; +public: + tag_func(TT multiplier): my_mult(multiplier) { } + // operator() will return [0 .. Count) + tbb::flow::tag_value operator()(TT v) { + tbb::flow::tag_value t = tbb::flow::tag_value(v/my_mult); + return t; + } +}; + +template <class JP> +struct filter_out_message_based_key_matching { + typedef JP policy; +}; + +template <typename K, typename KHash> +struct filter_out_message_based_key_matching<message_based_key_matching<K, KHash> > { + // To have message based key matching in join_node, the key_matchig policy should be specified. + typedef tbb::flow::key_matching<K, KHash> policy; +}; + +// allocator for join_node. This is specialized for tag_matching and key_matching joins because they require a variable number +// of tag_value methods passed to the constructor + +template<int N, typename JType, class JP> +class makeJoin { +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +// for general key_matching case, each type in the tuple is a class that has the my_key field and the my_value field. +// +template<typename JType, typename K, typename KHash> +class makeJoin<2, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<2, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +#if MAX_TUPLE_TEST_SIZE >= 3 +template<typename JType, typename K, typename KHash> +class makeJoin<3, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>(), + my_struct_key<K, T2>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<3, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)), + tag_func<T2>(T2(4)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +#endif +#if MAX_TUPLE_TEST_SIZE >= 4 + +template<typename JType, typename K, typename KHash> +class makeJoin<4, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>(), + my_struct_key<K, T2>(), + my_struct_key<K, T3>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<4, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)), + tag_func<T2>(T2(4)), + tag_func<T3>(T3(5)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +#endif +#if MAX_TUPLE_TEST_SIZE >= 5 +template<typename JType, typename K, typename KHash> +class makeJoin<5, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>(), + my_struct_key<K, T2>(), + my_struct_key<K, T3>(), + my_struct_key<K, T4>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<5, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)), + tag_func<T2>(T2(4)), + tag_func<T3>(T3(5)), + tag_func<T4>(T4(6)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; +#endif +#if MAX_TUPLE_TEST_SIZE >= 6 +template<typename JType, typename K, typename KHash> +class makeJoin<6, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>(), + my_struct_key<K, T2>(), + my_struct_key<K, T3>(), + my_struct_key<K, T4>(), + my_struct_key<K, T5>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<6, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)), + tag_func<T2>(T2(4)), + tag_func<T3>(T3(5)), + tag_func<T4>(T4(6)), + tag_func<T5>(T5(7)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; +#endif + +#if MAX_TUPLE_TEST_SIZE >= 7 +template<typename JType, typename K, typename KHash> +class makeJoin<7, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; + typedef typename tbb::flow::tuple_element<6, TType>::type T6; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>(), + my_struct_key<K, T2>(), + my_struct_key<K, T3>(), + my_struct_key<K, T4>(), + my_struct_key<K, T5>(), + my_struct_key<K, T6>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<7, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; + typedef typename tbb::flow::tuple_element<6, TType>::type T6; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)), + tag_func<T2>(T2(4)), + tag_func<T3>(T3(5)), + tag_func<T4>(T4(6)), + tag_func<T5>(T5(7)), + tag_func<T6>(T6(8)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; +#endif + +#if MAX_TUPLE_TEST_SIZE >= 8 +template<typename JType, typename K, typename KHash> +class makeJoin<8, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; + typedef typename tbb::flow::tuple_element<6, TType>::type T6; + typedef typename tbb::flow::tuple_element<7, TType>::type T7; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>(), + my_struct_key<K, T2>(), + my_struct_key<K, T3>(), + my_struct_key<K, T4>(), + my_struct_key<K, T5>(), + my_struct_key<K, T6>(), + my_struct_key<K, T7>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<8, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; + typedef typename tbb::flow::tuple_element<6, TType>::type T6; + typedef typename tbb::flow::tuple_element<7, TType>::type T7; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)), + tag_func<T2>(T2(4)), + tag_func<T3>(T3(5)), + tag_func<T4>(T4(6)), + tag_func<T5>(T5(7)), + tag_func<T6>(T6(8)), + tag_func<T7>(T7(9)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; +#endif + +#if MAX_TUPLE_TEST_SIZE >= 9 +template<typename JType, typename K, typename KHash> +class makeJoin<9, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; + typedef typename tbb::flow::tuple_element<6, TType>::type T6; + typedef typename tbb::flow::tuple_element<7, TType>::type T7; + typedef typename tbb::flow::tuple_element<8, TType>::type T8; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>(), + my_struct_key<K, T2>(), + my_struct_key<K, T3>(), + my_struct_key<K, T4>(), + my_struct_key<K, T5>(), + my_struct_key<K, T6>(), + my_struct_key<K, T7>(), + my_struct_key<K, T8>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<9, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; + typedef typename tbb::flow::tuple_element<6, TType>::type T6; + typedef typename tbb::flow::tuple_element<7, TType>::type T7; + typedef typename tbb::flow::tuple_element<8, TType>::type T8; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)), + tag_func<T2>(T2(4)), + tag_func<T3>(T3(5)), + tag_func<T4>(T4(6)), + tag_func<T5>(T5(7)), + tag_func<T6>(T6(8)), + tag_func<T7>(T7(9)), + tag_func<T8>(T8(10)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; +#endif + +#if MAX_TUPLE_TEST_SIZE >= 10 +template<typename JType, typename K, typename KHash> +class makeJoin<10, JType, tbb::flow::key_matching<K, KHash> > { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; + typedef typename tbb::flow::tuple_element<6, TType>::type T6; + typedef typename tbb::flow::tuple_element<7, TType>::type T7; + typedef typename tbb::flow::tuple_element<8, TType>::type T8; + typedef typename tbb::flow::tuple_element<9, TType>::type T9; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + my_struct_key<K, T0>(), + my_struct_key<K, T1>(), + my_struct_key<K, T2>(), + my_struct_key<K, T3>(), + my_struct_key<K, T4>(), + my_struct_key<K, T5>(), + my_struct_key<K, T6>(), + my_struct_key<K, T7>(), + my_struct_key<K, T8>(), + my_struct_key<K, T9>() + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; + +template<typename JType> +class makeJoin<10, JType, tbb::flow::tag_matching> { + typedef typename JType::output_type TType; + typedef typename tbb::flow::tuple_element<0, TType>::type T0; + typedef typename tbb::flow::tuple_element<1, TType>::type T1; + typedef typename tbb::flow::tuple_element<2, TType>::type T2; + typedef typename tbb::flow::tuple_element<3, TType>::type T3; + typedef typename tbb::flow::tuple_element<4, TType>::type T4; + typedef typename tbb::flow::tuple_element<5, TType>::type T5; + typedef typename tbb::flow::tuple_element<6, TType>::type T6; + typedef typename tbb::flow::tuple_element<7, TType>::type T7; + typedef typename tbb::flow::tuple_element<8, TType>::type T8; + typedef typename tbb::flow::tuple_element<9, TType>::type T9; +public: + static JType *create(tbb::flow::graph& g) { + JType *temp = new JType(g, + tag_func<T0>(T0(2)), + tag_func<T1>(T1(3)), + tag_func<T2>(T2(4)), + tag_func<T3>(T3(5)), + tag_func<T4>(T4(6)), + tag_func<T5>(T5(7)), + tag_func<T6>(T6(8)), + tag_func<T7>(T7(9)), + tag_func<T8>(T8(10)), + tag_func<T9>(T9(11)) + ); + return temp; + } + static void destroy(JType *p) { delete p; } +}; +#endif + +// holder for source_node pointers for eventual deletion + +static void* all_source_nodes[MaxPorts][MaxNSources]; + +template<int ELEM, typename JNT> +class source_node_helper { +public: + typedef JNT join_node_type; + typedef tbb::flow::join_node<tbb::flow::tuple<int, tbb::flow::continue_msg>, tbb::flow::reserving> input_join_type; + typedef typename join_node_type::output_type TT; + typedef typename tbb::flow::tuple_element<ELEM-1, TT>::type IT; + typedef typename tbb::flow::input_node<IT> my_source_node_type; + typedef typename tbb::flow::function_node<tbb::flow::tuple<int, tbb::flow::continue_msg>, IT> my_recirc_function_type; + static void print_remark(const char * str) { + source_node_helper<ELEM-1, JNT>::print_remark(str); + REMARK(", %s", name_of<IT>::name()); + } + static void add_source_nodes(join_node_type &my_join, tbb::flow::graph &g, int nInputs) { + for(int i = 0; i < nInputs; ++i) { + my_source_node_type *new_node = new my_source_node_type(g, source_body<IT, ELEM>(i, nInputs)); + tbb::flow::make_edge(*new_node, tbb::flow::input_port<ELEM-1>(my_join)); + all_source_nodes[ELEM-1][i] = (void *)new_node; + new_node->activate(); + } + // add the next source_node + source_node_helper<ELEM-1, JNT>::add_source_nodes(my_join, g, nInputs); + } + + static void add_recirc_func_nodes(join_node_type &my_join, input_join_type &my_input, tbb::flow::graph &g) { + my_recirc_function_type *new_node = new my_recirc_function_type(g, tbb::flow::unlimited, recirc_func_body<IT>((IT)(ELEM+1))); + tbb::flow::make_edge(*new_node, tbb::flow::input_port<ELEM-1>(my_join)); + tbb::flow::make_edge(my_input, *new_node); + all_source_nodes[ELEM-1][0] = (void *)new_node; + source_node_helper<ELEM-1, JNT>::add_recirc_func_nodes(my_join, my_input, g); + } + + static void only_check_value(const int i, const TT &v) { + ASSERT(tbb::flow::get<ELEM-1>(v)==(IT)(i*(ELEM+1)), NULL); + source_node_helper<ELEM-1, JNT>::only_check_value(i, v); + } + + static void check_value(int i, TT &v, bool is_serial) { + // the fetched value will match only if there is only one source_node. + ASSERT(!is_serial||tbb::flow::get<ELEM-1>(v)==(IT)(i*(ELEM+1)), NULL); + // tally the fetched value. + int ival = (int)tbb::flow::get<ELEM-1>(v); + ASSERT(!(ival%(ELEM+1)), NULL); + ival /= (ELEM+1); + ASSERT(!outputCheck[ELEM-1][ival], NULL); + outputCheck[ELEM-1][ival] = true; + source_node_helper<ELEM-1, JNT>::check_value(i, v, is_serial); + } + static void remove_source_nodes(join_node_type& my_join, int nInputs) { + for(int i = 0; i< nInputs; ++i) { + my_source_node_type *dp = reinterpret_cast<my_source_node_type *>(all_source_nodes[ELEM-1][i]); + tbb::flow::remove_edge(*dp, tbb::flow::input_port<ELEM-1>(my_join)); + delete dp; + } + source_node_helper<ELEM-1, JNT>::remove_source_nodes(my_join, nInputs); + } + + static void remove_recirc_func_nodes(join_node_type& my_join, input_join_type &my_input) { + my_recirc_function_type *fn = reinterpret_cast<my_recirc_function_type *>(all_source_nodes[ELEM-1][0]); + tbb::flow::remove_edge(*fn, tbb::flow::input_port<ELEM-1>(my_join)); + tbb::flow::remove_edge(my_input, *fn); + delete fn; + source_node_helper<ELEM-1, JNT>::remove_recirc_func_nodes(my_join, my_input); + } +}; + +template<typename JNT> +class source_node_helper<1, JNT> { + typedef JNT join_node_type; + typedef tbb::flow::join_node<tbb::flow::tuple<int, tbb::flow::continue_msg>, tbb::flow::reserving> input_join_type; + typedef typename join_node_type::output_type TT; + typedef typename tbb::flow::tuple_element<0, TT>::type IT; + typedef typename tbb::flow::input_node<IT> my_source_node_type; + typedef typename tbb::flow::function_node<tbb::flow::tuple<int, tbb::flow::continue_msg>, IT> my_recirc_function_type; +public: + static void print_remark(const char * str) { + REMARK("%s< %s", str, name_of<IT>::name()); + } + static void add_source_nodes(join_node_type &my_join, tbb::flow::graph &g, int nInputs) { + for(int i = 0; i < nInputs; ++i) { + my_source_node_type *new_node = new my_source_node_type(g, source_body<IT, 1>(i, nInputs)); + tbb::flow::make_edge(*new_node, tbb::flow::input_port<0>(my_join)); + all_source_nodes[0][i] = (void *)new_node; + new_node->activate(); + } + } + + static void add_recirc_func_nodes(join_node_type &my_join, input_join_type &my_input, tbb::flow::graph &g) { + my_recirc_function_type *new_node = new my_recirc_function_type(g, tbb::flow::unlimited, recirc_func_body<IT>((IT)(2))); + tbb::flow::make_edge(*new_node, tbb::flow::input_port<0>(my_join)); + tbb::flow::make_edge(my_input, *new_node); + all_source_nodes[0][0] = (void *)new_node; + } + + static void only_check_value(const int i, const TT &v) { + ASSERT(tbb::flow::get<0>(v)==(IT)(i*2), NULL); + } + + static void check_value(int i, TT &v, bool is_serial) { + ASSERT(!is_serial||tbb::flow::get<0>(v)==(IT)(i*(2)), NULL); + int ival = (int)tbb::flow::get<0>(v); + ASSERT(!(ival%2), NULL); + ival /= 2; + ASSERT(!outputCheck[0][ival], NULL); + outputCheck[0][ival] = true; + } + static void remove_source_nodes(join_node_type& my_join, int nInputs) { + for(int i = 0; i < nInputs; ++i) { + my_source_node_type *dp = reinterpret_cast<my_source_node_type *>(all_source_nodes[0][i]); + tbb::flow::remove_edge(*dp, tbb::flow::input_port<0>(my_join)); + delete dp; + } + } + + static void remove_recirc_func_nodes(join_node_type& my_join, input_join_type &my_input) { + my_recirc_function_type *fn = reinterpret_cast<my_recirc_function_type *>(all_source_nodes[0][0]); + tbb::flow::remove_edge(*fn, tbb::flow::input_port<0>(my_join)); + tbb::flow::remove_edge(my_input, *fn); + delete fn; + } +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) +// Suppress "conditional expression is constant" warning. +#pragma warning( push ) +#pragma warning( disable: 4127 ) +#endif + +template<typename JType, class JP> +class parallel_test { +public: + typedef typename JType::output_type TType; + typedef typename is_key_matching_join<JP>::key_type key_type; + static void test() { + const int TUPLE_SIZE = tbb::flow::tuple_size<TType>::value; + const bool is_key_matching = is_key_matching_join<JP>::value; + + TType v; + source_node_helper<TUPLE_SIZE, JType>::print_remark("Parallel test of join_node"); + REMARK(" > "); + if(is_key_matching) { + REMARK("with K == %s", name_of<typename K_deref<typename is_key_matching_join<JP>::key_type>::type >::name()); + if(is_ref<typename is_key_matching_join<JP>::key_type>::value) { + REMARK("&"); + } + } + REMARK("\n"); + for(int i = 0; i < MaxPorts; ++i) { + for(int j = 0; j < MaxNSources; ++j) { + all_source_nodes[i][j] = NULL; + } + } + for(int nInputs = 1; nInputs<=MaxNSources; ++nInputs) { + tbb::flow::graph g; + bool not_out_of_order = (nInputs==1)&&(!is_key_matching); + JType* my_join = makeJoin<TUPLE_SIZE, JType, JP>::create(g); + tbb::flow::queue_node<TType> outq1(g); + tbb::flow::queue_node<TType> outq2(g); + + tbb::flow::make_edge(*my_join, outq1); + tbb::flow::make_edge(*my_join, outq2); + + source_node_helper<TUPLE_SIZE, JType>::add_source_nodes((*my_join), g, nInputs); + + g.wait_for_all(); + + reset_outputCheck(TUPLE_SIZE, Count); + for(int i = 0; i < Count; ++i) { + ASSERT(outq1.try_get(v), NULL); + source_node_helper<TUPLE_SIZE, JType>::check_value(i, v, not_out_of_order); + } + + check_outputCheck(TUPLE_SIZE, Count); + reset_outputCheck(TUPLE_SIZE, Count); + + for(int i = 0; i < Count; i++) { + ASSERT(outq2.try_get(v), NULL);; + source_node_helper<TUPLE_SIZE, JType>::check_value(i, v, not_out_of_order); + } + check_outputCheck(TUPLE_SIZE, Count); + + ASSERT(!outq1.try_get(v), NULL); + ASSERT(!outq2.try_get(v), NULL); + + source_node_helper<TUPLE_SIZE, JType>::remove_source_nodes((*my_join), nInputs); + tbb::flow::remove_edge(*my_join, outq1); + tbb::flow::remove_edge(*my_join, outq2); + makeJoin<TUPLE_SIZE, JType, JP>::destroy(my_join); + } + } +}; + + +template<int ELEM, typename JType> +class serial_queue_helper { +public: + typedef typename JType::output_type TT; + typedef typename tbb::flow::tuple_element<ELEM-1, TT>::type IT; + typedef typename tbb::flow::queue_node<IT> my_queue_node_type; + static void print_remark() { + serial_queue_helper<ELEM-1, JType>::print_remark(); + REMARK(", %s", name_of<IT>::name()); + } + static void add_queue_nodes(tbb::flow::graph &g, JType &my_join) { + serial_queue_helper<ELEM-1, JType>::add_queue_nodes(g, my_join); + my_queue_node_type *new_node = new my_queue_node_type(g); + tbb::flow::make_edge(*new_node, tbb::flow::get<ELEM-1>(my_join.input_ports())); + all_source_nodes[ELEM-1][0] = (void *)new_node; + } + + static void fill_one_queue(int maxVal) { + // fill queue to "left" of me + my_queue_node_type *qptr = reinterpret_cast<my_queue_node_type *>(all_source_nodes[ELEM-1][0]); + serial_queue_helper<ELEM-1, JType>::fill_one_queue(maxVal); + for(int i = 0; i < maxVal; ++i) { + ASSERT(qptr->try_put(make_thingie<IT, ELEM>()(i)), NULL); + } + } + + static void put_one_queue_val(int myVal) { + // put this val to my "left". + serial_queue_helper<ELEM-1, JType>::put_one_queue_val(myVal); + my_queue_node_type *qptr = reinterpret_cast<my_queue_node_type *>(all_source_nodes[ELEM-1][0]); + ASSERT(qptr->try_put(make_thingie<IT, ELEM>()(myVal)), NULL); + } + + static void check_queue_value(int i, TT &v) { + serial_queue_helper<ELEM-1, JType>::check_queue_value(i, v); + ASSERT(cast_from<IT>::my_int_val(tbb::flow::get<ELEM-1>(v))==i * (ELEM+1), NULL); + } + + static void remove_queue_nodes(JType &my_join) { + my_queue_node_type *vptr = reinterpret_cast<my_queue_node_type *>(all_source_nodes[ELEM-1][0]); + tbb::flow::remove_edge(*vptr, tbb::flow::get<ELEM-1>(my_join.input_ports())); + serial_queue_helper<ELEM-1, JType>::remove_queue_nodes(my_join); + delete vptr; + } +}; + +template<typename JType> +class serial_queue_helper<1, JType> { +public: + typedef typename JType::output_type TT; + typedef typename tbb::flow::tuple_element<0, TT>::type IT; + typedef typename tbb::flow::queue_node<IT> my_queue_node_type; + static void print_remark() { + REMARK("Serial test of join_node< %s", name_of<IT>::name()); + } + + static void add_queue_nodes(tbb::flow::graph &g, JType &my_join) { + my_queue_node_type *new_node = new my_queue_node_type(g); + tbb::flow::make_edge(*new_node, tbb::flow::input_port<0>(my_join)); + all_source_nodes[0][0] = (void *)new_node; + } + + static void fill_one_queue(int maxVal) { + my_queue_node_type *qptr = reinterpret_cast<my_queue_node_type *>(all_source_nodes[0][0]); + for(int i = 0; i < maxVal; ++i) { + ASSERT(qptr->try_put(make_thingie<IT, 1>()(i)), NULL); + } + } + + static void put_one_queue_val(int myVal) { + my_queue_node_type *qptr = reinterpret_cast<my_queue_node_type *>(all_source_nodes[0][0]); + IT my_val = make_thingie<IT, 1>()(myVal); + ASSERT(qptr->try_put(my_val), NULL); + } + + static void check_queue_value(int i, TT &v) { + ASSERT(cast_from<IT>::my_int_val(tbb::flow::get<0>(v))==i*2, NULL); + } + + static void remove_queue_nodes(JType &my_join) { + my_queue_node_type *vptr = reinterpret_cast<my_queue_node_type *>(all_source_nodes[0][0]); + tbb::flow::remove_edge(*vptr, tbb::flow::get<0>(my_join.input_ports())); + delete vptr; + } +}; + +// +// Single reservable predecessor at each port, single accepting successor +// * put to buffer before port0, then put to buffer before port1, ... +// * fill buffer before port0 then fill buffer before port1, ... + +template<typename JType, class JP> +void test_one_serial(JType &my_join, tbb::flow::graph &g) { + typedef typename JType::output_type TType; + static const int TUPLE_SIZE = tbb::flow::tuple_size<TType>::value; + bool is_key_matching = is_key_matching_join<JP>::value; + std::vector<bool> flags; + serial_queue_helper<TUPLE_SIZE, JType>::add_queue_nodes(g, my_join); + typedef TType q3_input_type; + tbb::flow::queue_node< q3_input_type > q3(g); + + tbb::flow::make_edge(my_join, q3); + + // fill each queue with its value one-at-a-time + flags.clear(); + for(int i = 0; i < Count; ++i) { + serial_queue_helper<TUPLE_SIZE, JType>::put_one_queue_val(i); + flags.push_back(false); + } + + g.wait_for_all(); + for(int i = 0; i < Count; ++i) { + q3_input_type v; + g.wait_for_all(); + ASSERT(q3.try_get(v), "Error in try_get()"); + if(is_key_matching) { + // because we look up tags in the hash table, the output may be out of order. + int j = int(tbb::flow::get<0>(v))/2; // figure what the index should be + serial_queue_helper<TUPLE_SIZE, JType>::check_queue_value(j, v); + flags[j] = true; + } + else { + serial_queue_helper<TUPLE_SIZE, JType>::check_queue_value(i, v); + } + } + + if(is_key_matching) { + for(int i = 0; i < Count; ++i) { + ASSERT(flags[i], NULL); + flags[i] = false; + } + } + + // fill each queue completely before filling the next. + serial_queue_helper<TUPLE_SIZE, JType>::fill_one_queue(Count); + + g.wait_for_all(); + for(int i = 0; i < Count; ++i) { + q3_input_type v; + g.wait_for_all(); + ASSERT(q3.try_get(v), "Error in try_get()"); + if(is_key_matching) { + int j = int(tbb::flow::get<0>(v))/2; + serial_queue_helper<TUPLE_SIZE, JType>::check_queue_value(j, v); + flags[i] = true; + } + else { + serial_queue_helper<TUPLE_SIZE, JType>::check_queue_value(i, v); + } + } + + if(is_key_matching) { + for(int i = 0; i < Count; ++i) { + ASSERT(flags[i], NULL); + } + } + + serial_queue_helper<TUPLE_SIZE, JType>::remove_queue_nodes(my_join); + +} + +template<typename JType, class JP> +class serial_test { + typedef typename JType::output_type TType; +public: + static void test() { + tbb::flow::graph g; + std::vector<bool> flags; + bool is_key_matching = is_key_matching_join<JP>::value; + flags.reserve(Count); + + const int TUPLE_SIZE = tbb::flow::tuple_size<TType>::value; + static const int ELEMS = 3; + + JType* my_join = makeJoin<TUPLE_SIZE, JType, JP>::create(g); + test_input_ports_return_ref(*my_join); + serial_queue_helper<TUPLE_SIZE, JType>::print_remark(); REMARK(" >"); + if(is_key_matching) { + REMARK("with K == %s", name_of<typename K_deref<typename is_key_matching_join<JP>::key_type>::type >::name()); + if(is_ref<typename is_key_matching_join<JP>::key_type>::value) { + REMARK("&"); + } + } + REMARK("\n"); + + test_one_serial<JType, JP>(*my_join, g); + // build the vector with copy construction from the used join node. + std::vector<JType>join_vector(ELEMS, *my_join); + // destroy the tired old join_node in case we're accidentally reusing pieces of it. + makeJoin<TUPLE_SIZE, JType, JP>::destroy(my_join); + + for(int e = 0; e < ELEMS; ++e) { // exercise each of the vector elements + test_one_serial<JType, JP>(join_vector[e], g); + } + } + +}; // serial_test + +#if _MSC_VER && !defined(__INTEL_COMPILER) +#pragma warning( pop ) +#endif + +template< + template<typename, class > class TestType, // serial_test or parallel_test + typename OutputTupleType, // type of the output of the join + class J> // graph_buffer_policy (reserving, queueing, tag_matching or key_matching) + class generate_test { + public: + typedef tbb::flow::join_node<OutputTupleType, typename filter_out_message_based_key_matching<J>::policy> join_node_type; + static void do_test() { + TestType<join_node_type, J>::test(); + } +}; + +template<class JP> +void test_input_port_policies(); + +// join_node (reserving) does not consume inputs until an item is available at +// every input. It tries to reserve each input, and if any fails it releases the +// reservation. When it builds a tuple it broadcasts to all its successors and +// consumes all the inputs. +// +// So our test will put an item at one input port, then attach another node to the +// same node (a queue node in this case). The second successor should receive the +// item in the queue, emptying it. +// +// We then place an item in the second input queue, and check the output queues; they +// should still be empty. Then we place an item in the first queue; the output queues +// should then receive a tuple. +// +// we then attach another function node to the second input. It should not receive +// an item, verifying that the item in the queue is consumed. +template<> +void test_input_port_policies<tbb::flow::reserving>() { + tbb::flow::graph g; + typedef tbb::flow::join_node<tbb::flow::tuple<int, int>, tbb::flow::reserving > JType; // two-phase is the default policy + // create join_node<type0,type1> jn + JType jn(g); + // create output_queue oq0, oq1 + typedef JType::output_type OQType; + tbb::flow::queue_node<OQType> oq0(g); + tbb::flow::queue_node<OQType> oq1(g); + // create iq0, iq1 + typedef tbb::flow::queue_node<int> IQType; + IQType iq0(g); + IQType iq1(g); + // create qnp, qnq + IQType qnp(g); + IQType qnq(g); + REMARK("Testing policies of join_node<reserving> input ports\n"); + // attach jn to oq0, oq1 + tbb::flow::make_edge(jn, oq0); + tbb::flow::make_edge(jn, oq1); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(jn.successor_count()==2, NULL); + JType::successor_list_type my_succs; + jn.copy_successors(my_succs); + ASSERT(my_succs.size()==2, NULL); +#endif + // attach iq0, iq1 to jn + tbb::flow::make_edge(iq0, tbb::flow::get<0>(jn.input_ports())); + tbb::flow::make_edge(iq1, tbb::flow::get<1>(jn.input_ports())); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(tbb::flow::get<0>(jn.input_ports()).predecessor_count()==1, NULL); + tbb::flow::tuple_element<0, JType::input_type>::type::predecessor_list_type my_0preds; + tbb::flow::input_port<0>(jn).copy_predecessors(my_0preds); + ASSERT(my_0preds.size()==1, NULL); +#endif + for(int loop = 0; loop < 3; ++loop) { + // place one item in iq0 + ASSERT(iq0.try_put(1), "Error putting to iq1"); + // attach iq0 to qnp + tbb::flow::make_edge(iq0, qnp); + // qnp should have an item in it. + g.wait_for_all(); + { + int i; + ASSERT(qnp.try_get(i)&&i==1, "Error in item fetched by qnp"); + } + // place item in iq1 + ASSERT(iq1.try_put(2), "Error putting to iq1"); + // oq0, oq1 should be empty + g.wait_for_all(); + { + OQType t1; + ASSERT(!oq0.try_get(t1)&&!oq1.try_get(t1), "oq0 and oq1 not empty"); + } + // detach qnp from iq0 + tbb::flow::remove_edge(iq0, qnp); // if we don't remove qnp it will gobble any values we put in iq0 + // place item in iq0 + ASSERT(iq0.try_put(3), "Error on second put to iq0"); + // oq0, oq1 should have items in them + g.wait_for_all(); + { + OQType t0; + OQType t1; + ASSERT(oq0.try_get(t0)&&tbb::flow::get<0>(t0)==3&&tbb::flow::get<1>(t0)==2, "Error in oq0 output"); + ASSERT(oq1.try_get(t1)&&tbb::flow::get<0>(t1)==3&&tbb::flow::get<1>(t1)==2, "Error in oq1 output"); + } + // attach qnp to iq0, qnq to iq1 + // qnp and qnq should be empty + tbb::flow::make_edge(iq0, qnp); + tbb::flow::make_edge(iq1, qnq); + g.wait_for_all(); + { + int i; + ASSERT(!qnp.try_get(i), "iq0 still had value in it"); + ASSERT(!qnq.try_get(i), "iq1 still had value in it"); + } + tbb::flow::remove_edge(iq0, qnp); + tbb::flow::remove_edge(iq1, qnq); + } // for ( int loop ... +} + +// join_node (queueing) consumes inputs as soon as they are available at +// any input. When it builds a tuple it broadcasts to all its successors and +// discards the broadcast values. +// +// So our test will put an item at one input port, then attach another node to the +// same node (a queue node in this case). The second successor should not receive +// an item (because the join consumed it). +// +// We then place an item in the second input queue, and check the output queues; they +// should each have a tuple. +// +// we then attach another function node to the second input. It should not receive +// an item, verifying that the item in the queue is consumed. +template<> +void test_input_port_policies<tbb::flow::queueing>() { + tbb::flow::graph g; + typedef tbb::flow::join_node<tbb::flow::tuple<int, int>, tbb::flow::queueing > JType; + // create join_node<type0,type1> jn + JType jn(g); + // create output_queue oq0, oq1 + typedef JType::output_type OQType; + tbb::flow::queue_node<OQType> oq0(g); + tbb::flow::queue_node<OQType> oq1(g); + // create iq0, iq1 + typedef tbb::flow::queue_node<int> IQType; + IQType iq0(g); + IQType iq1(g); + // create qnp, qnq + IQType qnp(g); + IQType qnq(g); + REMARK("Testing policies of join_node<queueing> input ports\n"); + // attach jn to oq0, oq1 + tbb::flow::make_edge(jn, oq0); + tbb::flow::make_edge(jn, oq1); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(jn.successor_count()==2, NULL); + JType::successor_list_type my_succs; + jn.copy_successors(my_succs); + ASSERT(my_succs.size()==2, NULL); +#endif + // attach iq0, iq1 to jn + tbb::flow::make_edge(iq0, tbb::flow::get<0>(jn.input_ports())); + tbb::flow::make_edge(iq1, tbb::flow::get<1>(jn.input_ports())); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(tbb::flow::get<0>(jn.input_ports()).predecessor_count()==1, NULL); + tbb::flow::tuple_element<0, JType::input_type>::type::predecessor_list_type my_0preds; + tbb::flow::input_port<0>(jn).copy_predecessors(my_0preds); + ASSERT(my_0preds.size()==1, NULL); +#endif + for(int loop = 0; loop < 3; ++loop) { + // place one item in iq0 + ASSERT(iq0.try_put(1), "Error putting to iq1"); + // attach iq0 to qnp + tbb::flow::make_edge(iq0, qnp); + // qnp should have an item in it. + g.wait_for_all(); + { + int i; + ASSERT(!qnp.try_get(i), "Item was received by qnp"); + } + // place item in iq1 + ASSERT(iq1.try_put(2), "Error putting to iq1"); + // oq0, oq1 should have items + g.wait_for_all(); + { + OQType t0; + OQType t1; + ASSERT(oq0.try_get(t0)&&tbb::flow::get<0>(t0)==1&&tbb::flow::get<1>(t0)==2, "Error in oq0 output"); + ASSERT(oq1.try_get(t1)&&tbb::flow::get<0>(t1)==1&&tbb::flow::get<1>(t1)==2, "Error in oq1 output"); + } + // attach qnq to iq1 + // qnp and qnq should be empty + tbb::flow::make_edge(iq1, qnq); + g.wait_for_all(); + { + int i; + ASSERT(!qnp.try_get(i), "iq0 still had value in it"); + ASSERT(!qnq.try_get(i), "iq1 still had value in it"); + } + tbb::flow::remove_edge(iq0, qnp); + tbb::flow::remove_edge(iq1, qnq); + } // for ( int loop ... +} + +template<typename T> +struct myTagValue { + tbb::flow::tag_value operator()(T i) { return tbb::flow::tag_value(i); } +}; + +template<> +struct myTagValue<check_type<int> > { + tbb::flow::tag_value operator()(check_type<int> i) { return tbb::flow::tag_value((int)i); } +}; + +// join_node (tag_matching) consumes inputs as soon as they are available at +// any input. When it builds a tuple it broadcasts to all its successors and +// discards the broadcast values. +// +// It chooses the tuple it broadcasts by matching the tag values returned by the +// methods given the constructor of the join, in this case the method just casts +// the value in each port to tag_value. +// +// So our test will put an item at one input port, then attach another node to the +// same node (a queue node in this case). The second successor should not receive +// an item (because the join consumed it). +// +// We then place an item in the second input queue, and check the output queues; they +// should each have a tuple. +// +// we then attach another queue node to the second input. It should not receive +// an item, verifying that the item in the queue is consumed. +// +// We will then exercise the join with a bunch of values, and the output order should +// be determined by the order we insert items into the second queue. (Each tuple set +// corresponding to a tag will be complete when the second item is inserted.) +template<> +void test_input_port_policies<tbb::flow::tag_matching>() { + tbb::flow::graph g; + typedef tbb::flow::join_node<tbb::flow::tuple<int, check_type<int> >, tbb::flow::tag_matching > JoinNodeType; + typedef JoinNodeType::output_type CheckTupleType; + JoinNodeType testJoinNode(g, myTagValue<int>(), myTagValue<check_type<int> >()); + tbb::flow::queue_node<CheckTupleType> checkTupleQueue0(g); + tbb::flow::queue_node<CheckTupleType> checkTupleQueue1(g); + { + Check<check_type<int> > my_check; + + + typedef tbb::flow::queue_node<int> IntQueueType; + typedef tbb::flow::queue_node<check_type<int> > CheckQueueType; + IntQueueType intInputQueue(g); + CheckQueueType checkInputQueue(g); + IntQueueType intEmptyTestQueue(g); + CheckQueueType checkEmptyTestQueue(g); + REMARK("Testing policies of join_node<tag_matching> input ports\n"); + // attach testJoinNode to checkTupleQueue0, checkTupleQueue1 + tbb::flow::make_edge(testJoinNode, checkTupleQueue0); + tbb::flow::make_edge(testJoinNode, checkTupleQueue1); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(testJoinNode.successor_count()==2, NULL); + JoinNodeType::successor_list_type my_succs; + testJoinNode.copy_successors(my_succs); + ASSERT(my_succs.size()==2, NULL); +#endif + // attach intInputQueue, checkInputQueue to testJoinNode + tbb::flow::make_edge(intInputQueue, tbb::flow::input_port<0>(testJoinNode)); + tbb::flow::make_edge(checkInputQueue, tbb::flow::input_port<1>(testJoinNode)); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(tbb::flow::input_port<0>(testJoinNode).predecessor_count()==1, NULL); + tbb::flow::tuple_element<0, JoinNodeType::input_type>::type::predecessor_list_type my_0preds; + tbb::flow::input_port<0>(testJoinNode).copy_predecessors(my_0preds); + ASSERT(my_0preds.size()==1, NULL); +#endif + + // we'll put four discrete values in the inputs to the join_node. Each + // set of inputs should result in one output. + for(int loop = 0; loop < 4; ++loop) { + // place one item in intInputQueue + ASSERT(intInputQueue.try_put(loop), "Error putting to intInputQueue"); + // attach intInputQueue to intEmptyTestQueue + tbb::flow::make_edge(intInputQueue, intEmptyTestQueue); + // intEmptyTestQueue should not have an item in it. (the join consumed it.) + g.wait_for_all(); + { + int intVal0; + ASSERT(!intEmptyTestQueue.try_get(intVal0), "Item was received by intEmptyTestQueue"); + } + // place item in checkInputQueue + check_type<int> checkVal0(loop); + ASSERT(checkInputQueue.try_put(checkVal0), "Error putting to checkInputQueue"); + // checkTupleQueue0, checkTupleQueue1 should have items + g.wait_for_all(); + { + CheckTupleType t0; + CheckTupleType t1; + ASSERT(checkTupleQueue0.try_get(t0)&&tbb::flow::get<0>(t0)==loop&&(int)tbb::flow::get<1>(t0)==loop, "Error in checkTupleQueue0 output"); + ASSERT(checkTupleQueue1.try_get(t1)&&tbb::flow::get<0>(t1)==loop&&(int)tbb::flow::get<1>(t1)==loop, "Error in checkTupleQueue1 output"); + ASSERT(!checkTupleQueue0.try_get(t0), "extra object in output queue checkTupleQueue0"); + ASSERT(!checkTupleQueue1.try_get(t0), "extra object in output queue checkTupleQueue1"); + } + // attach checkEmptyTestQueue to checkInputQueue + // intEmptyTestQueue and checkEmptyTestQueue should be empty + tbb::flow::make_edge(checkInputQueue, checkEmptyTestQueue); + g.wait_for_all(); + { + int intVal1; + check_type<int> checkVal1; + ASSERT(!intEmptyTestQueue.try_get(intVal1), "intInputQueue still had value in it"); + ASSERT(!checkEmptyTestQueue.try_get(checkVal1), "checkInputQueue still had value in it"); + } + tbb::flow::remove_edge(intInputQueue, intEmptyTestQueue); + tbb::flow::remove_edge(checkInputQueue, checkEmptyTestQueue); + } // for ( int loop ... + + // Now we'll put [4 .. nValues - 1] in intInputQueue, and then put [4 .. nValues - 1] in checkInputQueue in + // a different order. We should see tuples in the output queues in the order we inserted + // the integers into checkInputQueue. + const int nValues = 100; + const int nIncr = 31; // relatively prime to nValues + + for(int loop = 4; loop < 4+nValues; ++loop) { + // place one item in intInputQueue + ASSERT(intInputQueue.try_put(loop), "Error putting to intInputQueue"); + g.wait_for_all(); + { + CheckTupleType t3; + ASSERT(!checkTupleQueue0.try_get(t3), "Object in output queue"); + ASSERT(!checkTupleQueue1.try_get(t3), "Object in output queue"); + } + } // for ( int loop ... + + for(int loop = 1; loop<=nValues; ++loop) { + int lp1 = 4+(loop * nIncr)%nValues; + // place item in checkInputQueue + ASSERT(checkInputQueue.try_put(lp1), "Error putting to checkInputQueue"); + // checkTupleQueue0, checkTupleQueue1 should have items + g.wait_for_all(); + { + CheckTupleType t0; + CheckTupleType t1; + ASSERT(checkTupleQueue0.try_get(t0)&&tbb::flow::get<0>(t0)==lp1 && tbb::flow::get<1>(t0)==lp1, "Error in checkTupleQueue0 output"); + ASSERT(checkTupleQueue1.try_get(t1)&&tbb::flow::get<0>(t1)==lp1 && tbb::flow::get<1>(t1)==lp1, "Error in checkTupleQueue1 output"); + ASSERT(!checkTupleQueue0.try_get(t0), "extra object in output queue checkTupleQueue0"); + ASSERT(!checkTupleQueue1.try_get(t0), "extra object in output queue checkTupleQueue1"); + } + } // for ( int loop ... + } // Check +} + +template<typename Policy> struct policy_name {}; + +template<> struct policy_name<tbb::flow::queueing> { +const char* msg_beg() { return "queueing\n";} +const char* msg_end() { return "test queueing extract\n";} +}; + +template<> struct policy_name<tbb::flow::reserving> { +const char* msg_beg() { return "reserving\n";} +const char* msg_end() { return "test reserving extract\n";} +}; + +template<> struct policy_name<tbb::flow::tag_matching> { +const char* msg_beg() { return "tag_matching\n";} +const char* msg_end() { return "test tag_matching extract\n";} +}; + +template<typename Policy> +void test_main() { + test_input_port_policies<Policy>(); + for(int p = 0; p < 2; ++p) { + REMARK(policy_name<Policy>().msg_beg()); + generate_test<serial_test, tbb::flow::tuple<threebyte, double>, Policy>::do_test(); +#if MAX_TUPLE_TEST_SIZE >= 4 + { + Check<check_type<int> > my_check; + generate_test<serial_test, tbb::flow::tuple<float, double, check_type<int>, long>, Policy>::do_test(); + } +#endif +#if MAX_TUPLE_TEST_SIZE >= 6 + generate_test<serial_test, tbb::flow::tuple<double, double, int, long, int, short>, Policy>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 8 + generate_test<serial_test, tbb::flow::tuple<float, double, double, double, float, int, float, long>, Policy>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 10 + generate_test<serial_test, tbb::flow::tuple<float, double, int, double, double, float, long, int, float, long>, Policy>::do_test(); +#endif + { + Check<check_type<int> > my_check1; + generate_test<parallel_test, tbb::flow::tuple<float, check_type<int> >, Policy>::do_test(); + } +#if MAX_TUPLE_TEST_SIZE >= 3 + generate_test<parallel_test, tbb::flow::tuple<float, int, long>, Policy>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 5 + generate_test<parallel_test, tbb::flow::tuple<double, double, int, int, short>, Policy>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 7 + generate_test<parallel_test, tbb::flow::tuple<float, int, double, float, long, float, long>, Policy>::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 9 + generate_test<parallel_test, tbb::flow::tuple<float, double, int, double, double, long, int, float, long>, Policy>::do_test(); +#endif + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + REMARK(policy_name<Policy>().msg_end()); + test_join_extract<int, tbb::flow::join_node< tbb::flow::tuple<int, int>, Policy> >().run_tests(); +#endif +} + +#endif /* tbb_test_join_node_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node_key_matching.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node_key_matching.cpp new file mode 100644 index 00000000..0a7dfe06 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node_key_matching.cpp @@ -0,0 +1,102 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#endif + +#define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1 +#include "test_join_node.h" + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + using tuple_type = std::tuple<int, int, double>; + + graph g; + auto body_int = [](const int&)->int { return 1; }; + auto body_double = [](const double&)->int { return 1; }; + + join_node j1(g, body_int, body_int, body_double); + static_assert(std::is_same_v<decltype(j1), join_node<tuple_type, key_matching<int>>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + broadcast_node<int> b1(g), b2(g); + broadcast_node<double> b3(g); + broadcast_node<tuple_type> b4(g); + + join_node j2(follows(b1, b2, b3), body_int, body_int, body_double); + static_assert(std::is_same_v<decltype(j2), join_node<tuple_type, key_matching<int>>>); + + join_node j3(precedes(b4), body_int, body_int, body_double); + static_assert(std::is_same_v<decltype(j3), join_node<tuple_type, key_matching<int>>>); +#endif + + join_node j4(j1); + static_assert(std::is_same_v<decltype(j4), join_node<tuple_type, key_matching<int>>>); +} +#endif + +int TestMain() { +#if __TBB_USE_TBB_TUPLE + REMARK(" Using TBB tuple\n"); +#else + REMARK(" Using platform tuple\n"); +#endif + + REMARK("key_matching\n"); + generate_test<serial_test, tbb::flow::tuple<MyKeyFirst<int, double>, MyKeySecond<int, float> >, tbb::flow::key_matching<int> >::do_test(); + generate_test<serial_test, tbb::flow::tuple<MyKeyFirst<std::string, double>, MyKeySecond<std::string, float> >, tbb::flow::key_matching<std::string> >::do_test(); +#if MAX_TUPLE_TEST_SIZE >= 3 + generate_test<serial_test, tbb::flow::tuple<MyKeyFirst<std::string, double>, MyKeySecond<std::string, float>, MyKeyWithBrokenMessageKey<std::string, int> >, tbb::flow::key_matching<std::string&> >::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 7 + generate_test<serial_test, tbb::flow::tuple< + MyKeyFirst<std::string, double>, + MyKeyWithBrokenMessageKey<std::string, int>, + MyKeyFirst<std::string, int>, + MyKeySecond<std::string, size_t>, + MyKeyWithBrokenMessageKey<std::string, int>, + MyKeySecond<std::string, short>, + MyKeySecond<std::string, threebyte> + >, tbb::flow::key_matching<std::string&> >::do_test(); +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + + generate_test<parallel_test, tbb::flow::tuple<MyKeyFirst<int, double>, MyKeySecond<int, float> >, tbb::flow::key_matching<int> >::do_test(); + generate_test<parallel_test, tbb::flow::tuple<MyKeyFirst<int, double>, MyKeySecond<int, float> >, tbb::flow::key_matching<int&> >::do_test(); + generate_test<parallel_test, tbb::flow::tuple<MyKeyFirst<std::string, double>, MyKeySecond<std::string, float> >, tbb::flow::key_matching<std::string&> >::do_test(); + +#if MAX_TUPLE_TEST_SIZE >= 10 + generate_test<parallel_test, tbb::flow::tuple< + MyKeyFirst<std::string, double>, + MyKeySecond<std::string, int>, + MyKeyFirst<std::string, int>, + MyKeyWithBrokenMessageKey<std::string, size_t>, + MyKeyWithBrokenMessageKey<std::string, int>, + MyKeySecond<std::string, short>, + MyKeySecond<std::string, threebyte>, + MyKeyFirst<std::string, int>, + MyKeySecond<std::string, threebyte>, + MyKeyWithBrokenMessageKey<std::string, size_t> + >, tbb::flow::key_matching<std::string&> >::do_test(); +#endif + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node_msg_key_matching.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node_msg_key_matching.cpp new file mode 100644 index 00000000..f893b295 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_join_node_msg_key_matching.cpp @@ -0,0 +1,115 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Message based key matching is a preview feature +#define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1 + +// This preview feature depends on +// TBB_PREVIEW_FLOW_GRAPH_FEATURES macro, and should not accidentally be dependent on +// this deprecated feature +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 0 + +#include "test_join_node.h" + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +struct message_key { + int my_key; + double my_value; + + int key() const { return my_key; } + + operator size_t() const { return my_key; } + + bool operator==(const message_key& rhs) { return my_value == rhs.my_value; } +}; + +void test_deduction_guides() { + using namespace tbb::flow; + using tuple_type = std::tuple<message_key, message_key>; + + graph g; + broadcast_node<message_key> bm1(g), bm2(g); + broadcast_node<tuple_type> bm3(g); + join_node<tuple_type, key_matching<int> > j0(g); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + join_node j1(follows(bm1, bm2), key_matching<int>()); + static_assert(std::is_same_v<decltype(j1), join_node<tuple_type, key_matching<int>>>); + + join_node j2(precedes(bm3), key_matching<int>()); + static_assert(std::is_same_v<decltype(j2), join_node<tuple_type, key_matching<int>>>); +#endif + + join_node j3(j0); + static_assert(std::is_same_v<decltype(j3), join_node<tuple_type, key_matching<int>>>); +} +#endif + +int TestMain() { +#if __TBB_USE_TBB_TUPLE + REMARK(" Using TBB tuple\n"); +#else + REMARK(" Using platform tuple\n"); +#endif + +#if !__TBB_MIC_OFFLOAD_TEST_COMPILATION_BROKEN + generate_test<serial_test, tbb::flow::tuple<MyMessageKeyWithBrokenKey<int, double>, MyMessageKeyWithoutKey<int, float> >, message_based_key_matching<int> >::do_test(); + generate_test<serial_test, tbb::flow::tuple<MyMessageKeyWithoutKeyMethod<std::string, double>, MyMessageKeyWithBrokenKey<std::string, float> >, message_based_key_matching<std::string> >::do_test(); +#if MAX_TUPLE_TEST_SIZE >= 3 + generate_test<serial_test, tbb::flow::tuple<MyMessageKeyWithoutKey<std::string, double>, MyMessageKeyWithoutKeyMethod<std::string, float>, MyMessageKeyWithBrokenKey<std::string, int> >, message_based_key_matching<std::string&> >::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 7 + generate_test<serial_test, tbb::flow::tuple< + MyMessageKeyWithoutKey<std::string, double>, + MyMessageKeyWithoutKeyMethod<std::string, int>, + MyMessageKeyWithBrokenKey<std::string, int>, + MyMessageKeyWithoutKey<std::string, size_t>, + MyMessageKeyWithoutKeyMethod<std::string, int>, + MyMessageKeyWithBrokenKey<std::string, short>, + MyMessageKeyWithoutKey<std::string, threebyte> + >, message_based_key_matching<std::string&> >::do_test(); +#endif + + generate_test<parallel_test, tbb::flow::tuple<MyMessageKeyWithBrokenKey<int, double>, MyMessageKeyWithoutKey<int, float> >, message_based_key_matching<int> >::do_test(); + generate_test<parallel_test, tbb::flow::tuple<MyMessageKeyWithoutKeyMethod<int, double>, MyMessageKeyWithBrokenKey<int, float> >, message_based_key_matching<int&> >::do_test(); + generate_test<parallel_test, tbb::flow::tuple<MyMessageKeyWithoutKey<std::string, double>, MyMessageKeyWithoutKeyMethod<std::string, float> >, message_based_key_matching<std::string&> >::do_test(); + + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + +#if MAX_TUPLE_TEST_SIZE >= 10 + generate_test<parallel_test, tbb::flow::tuple< + MyMessageKeyWithoutKeyMethod<std::string, double>, + MyMessageKeyWithBrokenKey<std::string, int>, + MyMessageKeyWithoutKey<std::string, int>, + MyMessageKeyWithoutKeyMethod<std::string, size_t>, + MyMessageKeyWithBrokenKey<std::string, int>, + MyMessageKeyWithoutKeyMethod<std::string, short>, + MyMessageKeyWithoutKeyMethod<std::string, threebyte>, + MyMessageKeyWithBrokenKey<std::string, int>, + MyMessageKeyWithoutKeyMethod<std::string, threebyte>, + MyMessageKeyWithBrokenKey<std::string, size_t> + >, message_based_key_matching<std::string&> >::do_test(); +#endif +#endif /* __TBB_MIC_OFFLOAD_TEST_COMPILATION_BROKEN */ + + generate_test<serial_test, tbb::flow::tuple<MyMessageKeyWithBrokenKey<int, double>, MyMessageKeyWithoutKey<int, float> >, message_based_key_matching<int> >::do_test(); + generate_test<serial_test, tbb::flow::tuple<MyMessageKeyWithoutKeyMethod<std::string, double>, MyMessageKeyWithBrokenKey<std::string, float> >, message_based_key_matching<std::string> >::do_test(); + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_lambda.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_lambda.cpp new file mode 100644 index 00000000..58489a97 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_lambda.cpp @@ -0,0 +1,235 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define NOMINMAX + +#include "harness_defs.h" +#if __TBB_TEST_SKIP_LAMBDA + +#include "harness.h" +int TestMain() { + REPORT("Known issue: lambdas are not properly supported on the platform \n"); + return Harness::Skipped; +} + +#else /*__TBB_TEST_SKIP_LAMBDA*/ + +#include "tbb/tbb.h" +#include "tbb/combinable.h" +#include <cstdio> +#include <list> + +using namespace std; +using namespace tbb; + +typedef pair<int,int> max_element_t; + +void f(int val, int *arr, int start, int stop) { + for (int i=start; i<=stop; ++i) { + arr[i] = val; + } +} + +#include "harness.h" + +#if __TBB_TASK_GROUP_CONTEXT +int Fib(int n) { + if( n<2 ) { + return n; + } else { + int x=0, y=0; + task_group g; + g.run( [&]{x=Fib(n-1);} ); // spawn a task + g.run( [&]{y=Fib(n-2);} ); // spawn another task + g.wait(); // wait for both tasks to complete + return x+y; + } +} +#endif /* !__TBB_TASK_GROUP_CONTEXT */ + +#include "harness_report.h" +#include "harness_assert.h" + +int TestMain () { + const int N = 1000; + const int Grainsize = N/1000; + int a[N]; + int max_sum; + ASSERT( MinThread>=1, "Error: Number of threads must be positive.\n"); + + for(int p=MinThread; p<=MaxThread; ++p) { + task_scheduler_init init(p); + + REMARK("Running lambda expression tests on %d threads...\n", p); + + //test parallel_for + REMARK("Testing parallel_for... "); + parallel_for(blocked_range<int>(0,N,Grainsize), + [&] (blocked_range<int>& r) { + for (int i=r.begin(); i!=r.end(); ++i) a[i] = i; + }); + ASSERT(a[0]==0 && a[N-1]==N-1, "parallel_for w/lambdas failed.\n"); + REMARK("passed.\n"); + + //test parallel_reduce + REMARK("Testing parallel_reduce... "); + int sum = parallel_reduce(blocked_range<int>(0,N,Grainsize), int(0), + [&] (blocked_range<int>& r, int current_sum) -> int { + for (int i=r.begin(); i!=r.end(); ++i) + current_sum += a[i]*(1000-i); + return current_sum; + }, + [] (const int x1, const int x2) { + return x1+x2; + } ); + + max_element_t max_el = + parallel_reduce(blocked_range<int>(0,N,Grainsize), make_pair(a[0], 0), + [&] (blocked_range<int>& r, max_element_t current_max) + -> max_element_t { + for (int i=r.begin(); i!=r.end(); ++i) + if (a[i]>current_max.first) + current_max = make_pair(a[i], i); + return current_max; + }, + [] (const max_element_t x1, const max_element_t x2) { + return (x1.first>x2.first)?x1:x2; + }); + ASSERT(sum==166666500 && max_el.first==999 && max_el.second==999, + "parallel_reduce w/lambdas failed.\n"); + REMARK("passed.\n"); + + //test parallel_do + REMARK("Testing parallel_do... "); + list<int> s; + s.push_back(0); + + parallel_do(s.begin(), s.end(), + [&](int foo, parallel_do_feeder<int>& feeder) { + if (foo == 42) return; + else if (foo>42) { + s.push_back(foo-3); + feeder.add(foo-3); + } else { + s.push_back(foo+5); + feeder.add(foo+5); + } + }); + ASSERT(s.back()==42, "parallel_do w/lambda failed.\n"); + REMARK("passed.\n"); + + //test parallel_invoke + REMARK("Testing parallel_invoke... "); + parallel_invoke([&]{ f(2, a, 0, N/3); }, + [&]{ f(1, a, N/3+1, 2*(N/3)); }, + [&]{ f(0, a, 2*(N/3)+1, N-1); }); + ASSERT(a[0]==2.0 && a[N-1]==0.0, "parallel_invoke w/lambda failed.\n"); + REMARK("passed.\n"); + + //test tbb_thread + REMARK("Testing tbb_thread... "); + tbb_thread::id myId; + tbb_thread myThread([](int x, int y) { + ASSERT(x==42 && y==64, "tbb_thread w/lambda failed.\n"); + REMARK("passed.\n"); + }, 42, 64); + myThread.join(); + +#if __TBB_TASK_GROUP_CONTEXT + // test task_group + REMARK("Testing task_group... "); + int result; + result = Fib(32); + ASSERT(result==2178309, "task_group w/lambda failed.\n"); + REMARK("passed.\n"); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + // Reset array a to index values + parallel_for(blocked_range<int>(0,N,Grainsize), + [&] (blocked_range<int>& r) { + for (int i=r.begin(); i!=r.end(); ++i) a[i] = i; + }); + // test parallel_sort + REMARK("Testing parallel_sort... "); + int pivot = 42; + + // sort nearest by increasing distance from pivot + parallel_sort(a, a+N, + [&](int x, int y) { return(abs(pivot-x) < abs(pivot-y)); }); + ASSERT(a[0]==42 && a[N-1]==N-1, "parallel_sort w/lambda failed.\n"); + REMARK("passed.\n"); + + //test combinable + REMARK("Testing combinable... "); + combinable<std::pair<int,int> > minmax_c([&]() { return std::make_pair(a[0], a[0]); } ); + + parallel_for(blocked_range<int>(0,N), + [&] (const blocked_range<int> &r) { + std::pair<int,int>& mmr = minmax_c.local(); + for(int i=r.begin(); i!=r.end(); ++i) { + if (mmr.first > a[i]) mmr.first = a[i]; + if (mmr.second < a[i]) mmr.second = a[i]; + } + }); + max_sum = 0; + minmax_c.combine_each([&max_sum](std::pair<int,int> x) { + int tsum = x.first + x.second; + if( tsum>max_sum ) max_sum = tsum; + }); + ASSERT( (N-1)<=max_sum && max_sum<=a[0]+N-1, "combinable::combine_each /w lambda failed." ); + + std::pair<int,int> minmax_result_c; + minmax_result_c = + minmax_c.combine([](std::pair<int,int> x, std::pair<int,int> y) { + return std::make_pair(x.first<y.first?x.first:y.first, + x.second>y.second?x.second:y.second); + }); + ASSERT(minmax_result_c.first==0 && minmax_result_c.second==999, + "combinable w/lambda failed.\n"); + REMARK("passed.\n"); + + //test enumerable_thread_specific + REMARK("Testing enumerable_thread_specific... "); + enumerable_thread_specific< std::pair<int,int> > minmax_ets([&]() { return std::make_pair(a[0], a[0]); } ); + + max_sum = 0; + parallel_for(blocked_range<int>(0,N), + [&] (const blocked_range<int> &r) { + std::pair<int,int>& mmr = minmax_ets.local(); + for(int i=r.begin(); i!=r.end(); ++i) { + if (mmr.first > a[i]) mmr.first = a[i]; + if (mmr.second < a[i]) mmr.second = a[i]; + } + }); + minmax_ets.combine_each([&max_sum](std::pair<int,int> x) { + int tsum = x.first + x.second; + if( tsum>max_sum ) max_sum = tsum; + }); + ASSERT( (N-1)<=max_sum && max_sum<=a[0]+N-1, "enumerable_thread_specific::combine_each /w lambda failed." ); + + std::pair<int,int> minmax_result_ets; + minmax_result_ets = + minmax_ets.combine([](std::pair<int,int> x, std::pair<int,int> y) { + return std::make_pair(x.first<y.first?x.first:y.first, + x.second>y.second?x.second:y.second); + }); + ASSERT(minmax_result_ets.first==0 && minmax_result_ets.second==999, + "enumerable_thread_specific w/lambda failed.\n"); + REMARK("passed.\n"); + } + return Harness::Done; +} +#endif /* __TBB_TEST_SKIP_LAMBDA */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_limiter_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_limiter_node.cpp new file mode 100644 index 00000000..c73a44e9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_limiter_node.cpp @@ -0,0 +1,674 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness.h" + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#include "harness_graph.h" +#endif + +#include "tbb/flow_graph.h" +#include "tbb/atomic.h" +#include "tbb/task_scheduler_init.h" +#include "test_follows_and_precedes_api.h" + +const int L = 10; +const int N = 1000; + +using tbb::flow::internal::SUCCESSFULLY_ENQUEUED; + +template< typename T > +struct serial_receiver : public tbb::flow::receiver<T>, NoAssign { + T next_value; + tbb::flow::graph& my_graph; + + serial_receiver(tbb::flow::graph& g) : next_value(T(0)), my_graph(g) {} + + tbb::task *try_put_task( const T &v ) __TBB_override { + ASSERT( next_value++ == v, NULL ); + return const_cast<tbb::task *>(SUCCESSFULLY_ENQUEUED); + } + + tbb::flow::graph& graph_reference() const __TBB_override { + return my_graph; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::receiver<T>::built_predecessors_type built_predecessors_type; + typedef typename tbb::flow::receiver<T>::predecessor_list_type predecessor_list_type; + typedef typename tbb::flow::receiver<T>::predecessor_type predecessor_type; + built_predecessors_type bpt; + built_predecessors_type &built_predecessors() __TBB_override { return bpt; } + void internal_add_built_predecessor( predecessor_type & ) __TBB_override { } + void internal_delete_built_predecessor( predecessor_type & ) __TBB_override { } + void copy_predecessors( predecessor_list_type & ) __TBB_override { } + size_t predecessor_count() __TBB_override { return 0; } +#endif + + void reset_receiver(tbb::flow::reset_flags /*f*/) __TBB_override {next_value = T(0);} +}; + +template< typename T > +struct parallel_receiver : public tbb::flow::receiver<T>, NoAssign { + + tbb::atomic<int> my_count; + tbb::flow::graph& my_graph; + + parallel_receiver(tbb::flow::graph& g) : my_graph(g) { my_count = 0; } + + tbb::task *try_put_task( const T &/*v*/ ) __TBB_override { + ++my_count; + return const_cast<tbb::task *>(tbb::flow::internal::SUCCESSFULLY_ENQUEUED); + } + + tbb::flow::graph& graph_reference() const __TBB_override { + return my_graph; + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::receiver<T>::built_predecessors_type built_predecessors_type; + typedef typename tbb::flow::receiver<T>::predecessor_list_type predecessor_list_type; + typedef typename tbb::flow::receiver<T>::predecessor_type predecessor_type; + built_predecessors_type bpt; + built_predecessors_type &built_predecessors() __TBB_override { return bpt; } + void internal_add_built_predecessor( predecessor_type & ) __TBB_override { } + void internal_delete_built_predecessor( predecessor_type & ) __TBB_override { } + void copy_predecessors( predecessor_list_type & ) __TBB_override { } + size_t predecessor_count( ) __TBB_override { return 0; } +#endif + void reset_receiver(tbb::flow::reset_flags /*f*/) __TBB_override {my_count = 0;} +}; + +template< typename T > +struct empty_sender : public tbb::flow::sender<T> { + typedef typename tbb::flow::sender<T>::successor_type successor_type; + + bool register_successor( successor_type & ) __TBB_override { return false; } + bool remove_successor( successor_type & ) __TBB_override { return false; } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::sender<T>::built_successors_type built_successors_type; + typedef typename tbb::flow::sender<T>::successor_list_type successor_list_type; + built_successors_type bst; + built_successors_type &built_successors() __TBB_override { return bst; } + void internal_add_built_successor( successor_type & ) __TBB_override { } + void internal_delete_built_successor( successor_type & ) __TBB_override { } + void copy_successors( successor_list_type & ) __TBB_override { } + size_t successor_count() __TBB_override { return 0; } +#endif +}; + + +template< typename T > +struct put_body : NoAssign { + + tbb::flow::limiter_node<T> &my_lim; + tbb::atomic<int> &my_accept_count; + + put_body( tbb::flow::limiter_node<T> &lim, tbb::atomic<int> &accept_count ) : + my_lim(lim), my_accept_count(accept_count) {} + + void operator()( int ) const { + for ( int i = 0; i < L; ++i ) { + bool msg = my_lim.try_put( T(i) ); + if ( msg == true ) + ++my_accept_count; + } + } +}; + +template< typename T > +struct put_dec_body : NoAssign { + + tbb::flow::limiter_node<T> &my_lim; + tbb::atomic<int> &my_accept_count; + + put_dec_body( tbb::flow::limiter_node<T> &lim, tbb::atomic<int> &accept_count ) : + my_lim(lim), my_accept_count(accept_count) {} + + void operator()( int ) const { + int local_accept_count = 0; + while ( local_accept_count < N ) { + bool msg = my_lim.try_put( T(local_accept_count) ); + if ( msg == true ) { + ++local_accept_count; + ++my_accept_count; + my_lim.decrement.try_put( tbb::flow::continue_msg() ); + } + } + } + +}; + +template< typename T > +void test_puts_with_decrements( int num_threads, tbb::flow::limiter_node< T >& lim , tbb::flow::graph& g) { + parallel_receiver<T> r(g); + empty_sender< tbb::flow::continue_msg > s; + tbb::atomic<int> accept_count; + accept_count = 0; + tbb::flow::make_edge( lim, r ); + tbb::flow::make_edge(s, lim.decrement); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(lim.decrement.predecessor_count() == 1, NULL); + ASSERT(lim.successor_count() == 1, NULL); + ASSERT(lim.predecessor_count() == 0, NULL); + typename tbb::flow::interface11::internal::decrementer + <tbb::flow::limiter_node<T>, tbb::flow::continue_msg>::predecessor_list_type dec_preds; + lim.decrement.copy_predecessors(dec_preds); + ASSERT(dec_preds.size() == 1, NULL); +#endif + // test puts with decrements + NativeParallelFor( num_threads, put_dec_body<T>(lim, accept_count) ); + int c = accept_count; + ASSERT( c == N*num_threads, NULL ); + ASSERT( r.my_count == N*num_threads, NULL ); +} + +// +// Tests +// +// limiter only forwards below the limit, multiple parallel senders / single receiver +// multiple parallel senders that put to decrement at each accept, limiter accepts new messages +// +// +template< typename T > +int test_parallel(int num_threads) { + + // test puts with no decrements + for ( int i = 0; i < L; ++i ) { + tbb::flow::graph g; + tbb::flow::limiter_node< T > lim(g, i); + parallel_receiver<T> r(g); + tbb::atomic<int> accept_count; + accept_count = 0; + tbb::flow::make_edge( lim, r ); + // test puts with no decrements + NativeParallelFor( num_threads, put_body<T>(lim, accept_count) ); + g.wait_for_all(); + int c = accept_count; + ASSERT( c == i, NULL ); + } + + // test puts with decrements + for ( int i = 1; i < L; ++i ) { + tbb::flow::graph g; + tbb::flow::limiter_node< T > lim(g, i); + test_puts_with_decrements(num_threads, lim, g); + tbb::flow::limiter_node< T > lim_copy( lim ); + test_puts_with_decrements(num_threads, lim_copy, g); + } + + return 0; +} + +// +// Tests +// +// limiter only forwards below the limit, single sender / single receiver +// at reject, a put to decrement, will cause next message to be accepted +// +template< typename T > +int test_serial() { + + // test puts with no decrements + for ( int i = 0; i < L; ++i ) { + tbb::flow::graph g; + tbb::flow::limiter_node< T > lim(g, i); + serial_receiver<T> r(g); + tbb::flow::make_edge( lim, r ); + for ( int j = 0; j < L; ++j ) { + bool msg = lim.try_put( T(j) ); + ASSERT( ( j < i && msg == true ) || ( j >= i && msg == false ), NULL ); + } + g.wait_for_all(); + } + + // test puts with decrements + for ( int i = 1; i < L; ++i ) { + tbb::flow::graph g; + tbb::flow::limiter_node< T > lim(g, i); + serial_receiver<T> r(g); + empty_sender< tbb::flow::continue_msg > s; + tbb::flow::make_edge( lim, r ); + tbb::flow::make_edge(s, lim.decrement); + for ( int j = 0; j < N; ++j ) { + bool msg = lim.try_put( T(j) ); + ASSERT( ( j < i && msg == true ) || ( j >= i && msg == false ), NULL ); + if ( msg == false ) { + lim.decrement.try_put( tbb::flow::continue_msg() ); + msg = lim.try_put( T(j) ); + ASSERT( msg == true, NULL ); + } + } + } + return 0; +} + +// reported bug in limiter (http://software.intel.com/en-us/comment/1752355) +#define DECREMENT_OUTPUT 1 // the port number of the decrement output of the multifunction_node +#define LIMITER_OUTPUT 0 // port number of the integer output + +typedef tbb::flow::multifunction_node<int, tbb::flow::tuple<int,tbb::flow::continue_msg> > mfnode_type; + +tbb::atomic<size_t> emit_count; +tbb::atomic<size_t> emit_sum; +tbb::atomic<size_t> receive_count; +tbb::atomic<size_t> receive_sum; + +struct mfnode_body { + int max_cnt; + tbb::atomic<int>* my_cnt; + mfnode_body(const int& _max, tbb::atomic<int> &_my) : max_cnt(_max), my_cnt(&_my) { } + void operator()(const int &/*in*/, mfnode_type::output_ports_type &out) { + int lcnt = ++(*my_cnt); + if(lcnt > max_cnt) { + return; + } + // put one continue_msg to the decrement of the limiter. + if(!tbb::flow::get<DECREMENT_OUTPUT>(out).try_put(tbb::flow::continue_msg())) { + ASSERT(false,"Unexpected rejection of decrement"); + } + { + // put messages to the input of the limiter_node until it rejects. + while( tbb::flow::get<LIMITER_OUTPUT>(out).try_put(lcnt) ) { + emit_sum += lcnt; + ++emit_count; + } + } + } +}; + +struct fn_body { + int operator()(const int &in) { + receive_sum += in; + ++receive_count; + return in; + } +}; + +// +------------+ +// +---------+ | v +// | mf_node |0---+ +----------+ +----------+ +// +->| |1---------->| lim_node |--------->| fn_node |--+ +// | +---------+ +----------+ +----------+ | +// | | +// | | +// +-------------------------------------------------------------+ +// +void +test_multifunction_to_limiter(int _max, int _nparallel) { + tbb::flow::graph g; + emit_count = 0; + emit_sum = 0; + receive_count = 0; + receive_sum = 0; + tbb::atomic<int> local_cnt; + local_cnt = 0; + mfnode_type mf_node(g, tbb::flow::unlimited, mfnode_body(_max, local_cnt)); + tbb::flow::function_node<int, int> fn_node(g, tbb::flow::unlimited, fn_body()); + tbb::flow::limiter_node<int> lim_node(g, _nparallel); + tbb::flow::make_edge(tbb::flow::output_port<LIMITER_OUTPUT>(mf_node), lim_node); + tbb::flow::make_edge(tbb::flow::output_port<DECREMENT_OUTPUT>(mf_node), lim_node.decrement); + tbb::flow::make_edge(lim_node, fn_node); + tbb::flow::make_edge(fn_node, mf_node); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + REMARK("pred cnt == %d\n",(int)(lim_node.predecessor_count())); + REMARK("succ cnt == %d\n",(int)(lim_node.successor_count())); + tbb::flow::limiter_node<int>::successor_list_type my_succs; + lim_node.copy_successors(my_succs); + REMARK("succ cnt from vector == %d\n",(int)(my_succs.size())); + tbb::flow::limiter_node<int>::predecessor_list_type my_preds; + lim_node.copy_predecessors(my_preds); + REMARK("pred cnt from vector == %d\n",(int)(my_preds.size())); +#endif + mf_node.try_put(1); + g.wait_for_all(); + ASSERT(emit_count == receive_count, "counts do not match"); + ASSERT(emit_sum == receive_sum, "sums do not match"); + + // reset, test again + g.reset(); + emit_count = 0; + emit_sum = 0; + receive_count = 0; + receive_sum = 0; + local_cnt = 0;; + mf_node.try_put(1); + g.wait_for_all(); + ASSERT(emit_count == receive_count, "counts do not match"); + ASSERT(emit_sum == receive_sum, "sums do not match"); +} + + +void +test_continue_msg_reception() { + tbb::flow::graph g; + tbb::flow::limiter_node<int> ln(g,2); + tbb::flow::queue_node<int> qn(g); + tbb::flow::make_edge(ln, qn); + ln.decrement.try_put(tbb::flow::continue_msg()); + ln.try_put(42); + g.wait_for_all(); + int outint; + ASSERT(qn.try_get(outint) && outint == 42, "initial put to decrement stops node"); +} + +#if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR +using namespace tbb::flow; +void run_and_check_result(graph& g, limiter_node<int>& limit, queue_node<int>& queue, broadcast_node<continue_msg>& broad) { + ASSERT( limit.try_put(1), NULL ); + ASSERT( limit.try_put(2), NULL ); + ASSERT( !limit.try_put(3), NULL ); + ASSERT( broad.try_put(continue_msg()), NULL ); + ASSERT( limit.decrement.try_put(continue_msg()), NULL ); + ASSERT( limit.try_put(4), NULL ); + ASSERT( !limit.try_put(5), NULL ); + g.wait_for_all(); + + int list[] = {1, 2, 4}; + int var = 0; + for (size_t i = 0; i < sizeof(list)/sizeof(list[0]); i++) { + queue.try_get(var); + ASSERT(var==list[i], "some data dropped, input does not match output"); + } +} + +void test_num_decrement_predecessors() { + graph g; + queue_node<int> output_queue(g); + limiter_node<int> limit1(g, 2, /*number_of_predecessors*/1); + limiter_node<int, continue_msg> limit2(g, 2, /*number_of_predecessors*/1); + broadcast_node<continue_msg> broadcast(g); + + make_edge(limit1, output_queue); + make_edge(limit2, output_queue); + + make_edge(broadcast, limit1.decrement); + make_edge(broadcast, limit2.decrement); + + run_and_check_result(g, limit1, output_queue, broadcast); + run_and_check_result(g, limit2, output_queue, broadcast); +} +#else // TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR +// +// This test ascertains that if a message is not successfully put +// to a successor, the message is not dropped but released. +// + +void test_reserve_release_messages() { + using namespace tbb::flow; + graph g; + + //making two queue_nodes: one broadcast_node and one limiter_node + queue_node<int> input_queue(g); + queue_node<int> output_queue(g); + broadcast_node<int> broad(g); + limiter_node<int, int> limit(g,2); //threshold of 2 + + //edges + make_edge(input_queue, limit); + make_edge(limit, output_queue); + make_edge(broad,limit.decrement); + + int list[4] = {19, 33, 72, 98}; //list to be put to the input queue + + input_queue.try_put(list[0]); // succeeds + input_queue.try_put(list[1]); // succeeds + input_queue.try_put(list[2]); // fails, stored in upstream buffer + g.wait_for_all(); + + remove_edge(limit, output_queue); //remove successor + + //sending message to the decrement port of the limiter + broad.try_put(1); //failed message retrieved. + g.wait_for_all(); + + make_edge(limit, output_queue); //putting the successor back + + broad.try_put(1); //drop the count + + input_queue.try_put(list[3]); //success + g.wait_for_all(); + + int var=0; + + for (int i=0; i<4; i++) { + output_queue.try_get(var); + ASSERT(var==list[i], "some data dropped, input does not match output"); + g.wait_for_all(); + } +} + +void test_decrementer() { + const int threshold = 5; + tbb::flow::graph g; + tbb::flow::limiter_node<int, int> limit(g, threshold); + tbb::flow::queue_node<int> queue(g); + make_edge(limit, queue); + int m = 0; + ASSERT( limit.try_put( m++ ), "Newly constructed limiter node does not accept message." ); + ASSERT( limit.decrement.try_put( -threshold ), // close limiter's gate + "Limiter node decrementer's port does not accept message." ); + ASSERT( !limit.try_put( m++ ), "Closed limiter node's accepts message." ); + ASSERT( limit.decrement.try_put( threshold + 5 ), // open limiter's gate + "Limiter node decrementer's port does not accept message." ); + for( int i = 0; i < threshold; ++i ) + ASSERT( limit.try_put( m++ ), "Limiter node does not accept message while open." ); + ASSERT( !limit.try_put( m ), "Limiter node's gate is not closed." ); + g.wait_for_all(); + int expected[] = {0, 2, 3, 4, 5, 6}; + int actual = -1; m = 0; + while( queue.try_get(actual) ) + ASSERT( actual == expected[m++], NULL ); + ASSERT( sizeof(expected) / sizeof(expected[0]) == m, "Not all messages have been processed." ); + g.wait_for_all(); + + const size_t threshold2 = size_t(-1); + tbb::flow::limiter_node<int, long long> limit2(g, threshold2); + make_edge(limit2, queue); + ASSERT( limit2.try_put( 1 ), "Newly constructed limiter node does not accept message." ); + long long decrement_value = (long long)( size_t(-1)/2 ); + ASSERT( limit2.decrement.try_put( -decrement_value ), + "Limiter node decrementer's port does not accept message" ); + ASSERT( limit2.try_put( 2 ), "Limiter's gate should not be closed yet." ); + ASSERT( limit2.decrement.try_put( -decrement_value ), + "Limiter node decrementer's port does not accept message" ); + ASSERT( !limit2.try_put( 3 ), "Overflow happened for internal counter." ); + int expected2[] = {1, 2}; + actual = -1; m = 0; + while( queue.try_get(actual) ) + ASSERT( actual == expected2[m++], NULL ); + ASSERT( sizeof(expected2) / sizeof(expected2[0]) == m, "Not all messages have been processed." ); + g.wait_for_all(); +} +#endif // TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +void test_extract() { + tbb::flow::graph g; + int j; + tbb::flow::limiter_node<int> node0(g, /*threshold*/1); + tbb::flow::queue_node<int> q0(g); + tbb::flow::queue_node<int> q1(g); + tbb::flow::queue_node<int> q2(g); + tbb::flow::broadcast_node<tbb::flow::continue_msg> b0(g); + tbb::flow::broadcast_node<tbb::flow::continue_msg> b1(g); + + for( int i = 0; i < 2; ++i ) { + REMARK("At pass %d\n", i); + ASSERT(node0.predecessor_count() == 0, "incorrect predecessor count at start"); + ASSERT(node0.successor_count() == 0, "incorrect successor count at start"); + ASSERT(node0.decrement.predecessor_count() == 0, "incorrect decrement pred count at start"); + + tbb::flow::make_edge(q0, node0); + tbb::flow::make_edge(q1, node0); + tbb::flow::make_edge(node0, q2); + tbb::flow::make_edge(b0, node0.decrement); + tbb::flow::make_edge(b1, node0.decrement); + g.wait_for_all(); + + /* b0 b1 */ + /* \ | */ + /* q0\ \ | */ + /* \ \| */ + /* +-node0---q2 */ + /* / */ + /* q1/ */ + + q0.try_put(i); + g.wait_for_all(); + ASSERT(node0.predecessor_count() == 2, "incorrect predecessor count after construction"); + ASSERT(node0.successor_count() == 1, "incorrect successor count after construction"); + ASSERT(node0.decrement.predecessor_count() == 2, "incorrect decrement pred count after construction"); + ASSERT(q2.try_get(j), "fetch of value forwarded to output queue failed"); + ASSERT(j == i, "improper value forwarded to output queue"); + q0.try_put(2*i); + g.wait_for_all(); + ASSERT(!q2.try_get(j), "limiter_node forwarded item improperly"); + b0.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(!q2.try_get(j), "limiter_node forwarded item improperly"); + b0.try_put(tbb::flow::continue_msg()); + g.wait_for_all(); + ASSERT(q2.try_get(j) && j == 2*i, "limiter_node failed to forward item"); + + tbb::flow::limiter_node<int>::successor_list_type sv; + tbb::flow::limiter_node<int>::predecessor_list_type pv; + tbb::flow::continue_receiver::predecessor_list_type dv; + tbb::flow::limiter_node<int>::successor_list_type sv1; + tbb::flow::limiter_node<int>::predecessor_list_type pv1; + tbb::flow::continue_receiver::predecessor_list_type dv1; + + node0.copy_predecessors(pv); + node0.copy_successors(sv); + node0.decrement.copy_predecessors(dv); + pv1.push_back(&(q0)); + pv1.push_back(&(q1)); + sv1.push_back(&(q2)); + dv1.push_back(&(b0)); + dv1.push_back(&(b1)); + + ASSERT(pv.size() == 2, "improper size for predecessors"); + ASSERT(sv.size() == 1, "improper size for successors"); + ASSERT(lists_match(pv,pv1), "predecessor lists do not match"); + ASSERT(lists_match(sv,sv1), "successor lists do not match"); + ASSERT(lists_match(dv,dv1), "successor lists do not match"); + + if(i == 0) { + node0.extract(); + ASSERT(node0.predecessor_count() == 0, "incorrect predecessor count after extraction"); + ASSERT(node0.successor_count() == 0, "incorrect successor count after extraction"); + ASSERT(node0.decrement.predecessor_count() == 0, "incorrect decrement pred count after extraction"); + } + else { + q0.extract(); + b0.extract(); + q2.extract(); + + ASSERT(node0.predecessor_count() == 1, "incorrect predecessor count after extract second iter"); + ASSERT(node0.successor_count() == 0, "incorrect successor count after extract second iter"); + ASSERT(node0.decrement.predecessor_count() == 1, "incorrect decrement pred count after extract second iter"); + + node0.copy_predecessors(pv); + node0.copy_successors(sv); + node0.decrement.copy_predecessors(dv); + pv1.clear(); + sv1.clear(); + dv1.clear(); + pv1.push_back(&(q1)); + dv1.push_back(&(b1)); + + ASSERT(lists_match(pv,pv1), "predecessor lists do not match second iter"); + ASSERT(lists_match(sv,sv1), "successor lists do not match second iter"); + ASSERT(lists_match(dv,dv1), "successor lists do not match second iter"); + + q1.extract(); + b1.extract(); + } + ASSERT(node0.predecessor_count() == 0, "incorrect predecessor count after extract"); + ASSERT(node0.successor_count() == 0, "incorrect successor count after extract"); + ASSERT(node0.decrement.predecessor_count() == 0, "incorrect decrement pred count after extract"); + + } + +} +#endif // TBB_DEPRECATED_FLOW_NODE_EXTRACTION + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + using msg_t = tbb::flow::continue_msg; + + std::array<msg_t, 3> messages_for_follows= { {msg_t(), msg_t(), msg_t()} }; + std::vector<msg_t> messages_for_precedes = {msg_t()}; + + follows_and_precedes_testing::test_follows + <msg_t, tbb::flow::limiter_node<msg_t, msg_t>>(messages_for_follows, 1000); + follows_and_precedes_testing::test_precedes + <msg_t, tbb::flow::limiter_node<msg_t, msg_t>>(messages_for_precedes, 1000); + +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + + graph g; + broadcast_node<int> br(g); + limiter_node<int> l0(g, 100); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + limiter_node l1(follows(br), 100); + static_assert(std::is_same_v<decltype(l1), limiter_node<int>>); + + limiter_node l2(precedes(br), 100); + static_assert(std::is_same_v<decltype(l2), limiter_node<int>>); +#endif + + limiter_node l3(l0); + static_assert(std::is_same_v<decltype(l3), limiter_node<int>>); +} +#endif + +int TestMain() { + for (int i = 1; i <= 8; ++i) { + tbb::task_scheduler_init init(i); + test_serial<int>(); + test_parallel<int>(i); + } + test_continue_msg_reception(); + test_multifunction_to_limiter(30,3); + test_multifunction_to_limiter(300,13); + test_multifunction_to_limiter(3000,1); +#if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR + test_num_decrement_predecessors(); +#else + test_reserve_release_messages(); + test_decrementer(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract(); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_atexit.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_atexit.cpp new file mode 100644 index 00000000..220b7652 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_atexit.cpp @@ -0,0 +1,157 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* Regression test against a bug in TBB allocator manifested when + dynamic library calls atexit() or registers dtors of static objects. + If the allocator is not initialized yet, we can get deadlock, + because allocator library has static object dtors as well, they + registered during allocator initialization, and atexit() is protected + by non-recursive mutex in some versions of GLIBC. + */ + +#include <stdlib.h> +#include "harness_allocator_overload.h" + +// __TBB_malloc_safer_msize() returns 0 for unknown objects, +// thus we can detect ownership +#if _USRDLL + #if _WIN32||_WIN64 +extern __declspec(dllexport) + #endif +bool dll_isMallocOverloaded() +#else +bool exe_isMallocOverloaded() +#endif +{ + const size_t reqSz = 8; + void *o = malloc(reqSz); + bool ret = __TBB_malloc_safer_msize(o, NULL) >= reqSz; + free(o); + return ret; +} + +#if _USRDLL + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED + +#define HARNESS_CUSTOM_MAIN 1 +#include "harness.h" + +#include <dlfcn.h> +#if __APPLE__ +#include <malloc/malloc.h> +#define malloc_usable_size(p) malloc_size(p) +#else +#include <malloc.h> +#endif +#include <signal.h> + +#if __linux__ && !__ANDROID__ +extern "C" { +void __libc_free(void *ptr); +void *__libc_realloc(void *ptr, size_t size); + +// check that such kind of free/realloc overload works correctly +void free(void *ptr) +{ + __libc_free(ptr); +} + +void *realloc(void *ptr, size_t size) +{ + return __libc_realloc(ptr, size); +} +} // extern "C" +#endif // __linux__ && !__ANDROID__ + +#endif // MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED + +// Even when the test is skipped, dll source must not be empty to generate .lib to link with. + +#ifndef _PGO_INSTRUMENT +void dummyFunction() {} + +// TODO: enable the check under Android +#if (MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED) && !__ANDROID__ +typedef void *(malloc_type)(size_t); + +static void SigSegv(int) +{ + REPORT("Known issue: SIGSEGV during work with memory allocated by replaced allocator.\n" + "skip\n"); + exit(0); +} + +// TODO: Using of SIGSEGV can be eliminated via parsing /proc/self/maps +// and series of system malloc calls. +void TestReplacedAllocFunc() +{ + struct sigaction sa, sa_default; + malloc_type *orig_malloc = (malloc_type*)dlsym(RTLD_NEXT, "malloc"); + void *p = (*orig_malloc)(16); + + // protect potentially unsafe actions + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SigSegv; + if (sigaction(SIGSEGV, &sa, &sa_default)) + ASSERT(0, "sigaction failed"); + + ASSERT(malloc_usable_size(p) >= 16, NULL); + free(p); + // no more unsafe actions, restore SIGSEGV + if (sigaction(SIGSEGV, &sa_default, NULL)) + ASSERT(0, "sigaction failed"); +} +#else +void TestReplacedAllocFunc() { } +#endif + +class Foo { +public: + Foo() { + // add a lot of exit handlers to cause memory allocation + for (int i=0; i<1024; i++) + atexit(dummyFunction); + TestReplacedAllocFunc(); + } +}; + +static Foo f; +#endif + +#else // _USRDLL +#include "harness.h" + +#if _WIN32||_WIN64 +#include "tbb/tbbmalloc_proxy.h" + +extern __declspec(dllimport) +#endif +bool dll_isMallocOverloaded(); + +int TestMain () { +#ifdef _PGO_INSTRUMENT + REPORT("Known issue: test_malloc_atexit hangs if compiled with -prof-genx\n"); + return Harness::Skipped; +#else + ASSERT( dll_isMallocOverloaded(), "malloc was not replaced" ); + ASSERT( exe_isMallocOverloaded(), "malloc was not replaced" ); + return Harness::Done; +#endif +} + +#endif // _USRDLL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_compliance.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_compliance.cpp new file mode 100644 index 00000000..c34e8dca --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_compliance.cpp @@ -0,0 +1,1121 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +bool __tbb_test_errno = false; + +#define __STDC_LIMIT_MACROS 1 // to get SIZE_MAX from stdint.h + +#include "tbb/tbb_config.h" + +#if __TBB_WIN8UI_SUPPORT +// testing allocator itself not interfaces +// so we can use desktop functions +#define _CRT_USE_WINAPI_FAMILY_DESKTOP_APP !_M_ARM +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" +// FIXME: fix the test to support New Windows *8 Store Apps mode. +int TestMain() { + return Harness::Skipped; +} +#else /* __TBB_WIN8UI_SUPPORT */ + +#include "harness_defs.h" +#include "harness_report.h" + +#if _WIN32 || _WIN64 +/* _WIN32_WINNT should be defined at the very beginning, + because other headers might include <windows.h> +*/ +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#include "tbb/machine/windows_api.h" +#include <stdio.h> + +#if _MSC_VER && defined(_MT) && defined(_DLL) + #pragma comment(lib, "version.lib") // to use GetFileVersionInfo* +#endif + +void limitMem( size_t limit ) +{ + static HANDLE hJob = NULL; + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo; + + jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY; + jobInfo.ProcessMemoryLimit = limit? limit*MByte : 2*MByte*1024; + if (NULL == hJob) { + if (NULL == (hJob = CreateJobObject(NULL, NULL))) { + REPORT("Can't assign create job object: %ld\n", GetLastError()); + exit(1); + } + if (0 == AssignProcessToJobObject(hJob, GetCurrentProcess())) { + REPORT("Can't assign process to job object: %ld\n", GetLastError()); + exit(1); + } + } + if (0 == SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, + &jobInfo, sizeof(jobInfo))) { + REPORT("Can't set limits: %ld\n", GetLastError()); + exit(1); + } +} +// Do not test errno with static VC runtime +#else // _WIN32 || _WIN64 +#include <sys/resource.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> // uint64_t on FreeBSD, needed for rlim_t +#include <stdint.h> // SIZE_MAX + +void limitMem( size_t limit ) +{ + rlimit rlim; + int ret = getrlimit(RLIMIT_AS,&rlim); + if (0 != ret) { + REPORT("getrlimit() returned an error: errno %d\n", errno); + exit(1); + } + if (rlim.rlim_max==(rlim_t)RLIM_INFINITY) + rlim.rlim_cur = (limit > 0) ? limit*MByte : rlim.rlim_max; + else rlim.rlim_cur = (limit > 0 && limit<rlim.rlim_max) ? limit*MByte : rlim.rlim_max; + ret = setrlimit(RLIMIT_AS,&rlim); + if (0 != ret) { + REPORT("Can't set limits: errno %d\n", errno); + exit(1); + } +} +#endif // _WIN32 || _WIN64 + +#define ASSERT_ERRNO(cond, msg) ASSERT( !__tbb_test_errno || (cond), msg ) +#define CHECK_ERRNO(cond) (__tbb_test_errno && (cond)) + +#include <time.h> +#include <errno.h> +#include <limits.h> // for CHAR_BIT +#define __TBB_NO_IMPLICIT_LINKAGE 1 +#include "tbb/scalable_allocator.h" + +#define HARNESS_CUSTOM_MAIN 1 +#define HARNESS_TBBMALLOC_THREAD_SHUTDOWN 1 +#include "harness.h" +#include "harness_barrier.h" +#if !__TBB_SOURCE_DIRECTLY_INCLUDED +#include "harness_tbb_independence.h" +#endif +#if __linux__ +#include <stdint.h> // uintptr_t +#endif +#if _WIN32 || _WIN64 +#include <malloc.h> // _aligned_(malloc|free|realloc) +#if __MINGW64__ +// Workaround a bug in MinGW64 headers with _aligned_(malloc|free) not declared by default +extern "C" void __cdecl _aligned_free(void *); +extern "C" void *__cdecl _aligned_malloc(size_t,size_t); +#endif +#endif + +#include <vector> + +const int COUNT_ELEM = 25000; +const size_t MAX_SIZE = 1000; +const int COUNTEXPERIMENT = 10000; + +const char strError[]="failed"; +const char strOk[]="done"; + +typedef unsigned int UINT; +typedef unsigned char UCHAR; +typedef unsigned long DWORD; +typedef unsigned char BYTE; + + +typedef void* TestMalloc(size_t size); +typedef void* TestCalloc(size_t num, size_t size); +typedef void* TestRealloc(void* memblock, size_t size); +typedef void TestFree(void* memblock); +typedef int TestPosixMemalign(void **memptr, size_t alignment, size_t size); +typedef void* TestAlignedMalloc(size_t size, size_t alignment); +typedef void* TestAlignedRealloc(void* memblock, size_t size, size_t alignment); +typedef void TestAlignedFree(void* memblock); + +// pointers to tested functions +TestMalloc* Rmalloc; +TestCalloc* Rcalloc; +TestRealloc* Rrealloc; +TestFree* Tfree; +TestPosixMemalign* Rposix_memalign; +TestAlignedMalloc* Raligned_malloc; +TestAlignedRealloc* Raligned_realloc; +TestAlignedFree* Taligned_free; + +// call functions via pointer and check result's alignment +void* Tmalloc(size_t size); +void* Tcalloc(size_t num, size_t size); +void* Trealloc(void* memblock, size_t size); +int Tposix_memalign(void **memptr, size_t alignment, size_t size); +void* Taligned_malloc(size_t size, size_t alignment); +void* Taligned_realloc(void* memblock, size_t size, size_t alignment); + + +bool error_occurred = false; + +#if __APPLE__ +// Tests that use the variables are skipped on macOS* +#else +const size_t COUNT_ELEM_CALLOC = 2; +const int COUNT_TESTS = 1000; +static bool perProcessLimits = true; +#endif + +const size_t POWERS_OF_2 = 20; + +struct MemStruct +{ + void* Pointer; + UINT Size; + + MemStruct() : Pointer(NULL), Size(0) {} + MemStruct(void* ptr, UINT sz) : Pointer(ptr), Size(sz) {} +}; + +class CMemTest: NoAssign +{ + UINT CountErrors; + bool FullLog; + Harness::SpinBarrier *limitBarrier; + static bool firstTime; + +public: + CMemTest(Harness::SpinBarrier *barrier, bool isVerbose=false) : + CountErrors(0), limitBarrier(barrier) + { + srand((UINT)time(NULL)); + FullLog=isVerbose; + } + void NULLReturn(UINT MinSize, UINT MaxSize, int total_threads); // NULL pointer + check errno + void UniquePointer(); // unique pointer - check with padding + void AddrArifm(); // unique pointer - check with pointer arithmetic + bool ShouldReportError(); + void Free_NULL(); // + void Zerofilling(); // check if arrays are zero-filled + void TestAlignedParameters(); + void RunAllTests(int total_threads); + ~CMemTest() {} +}; + +class Limit { + size_t limit; +public: + Limit(size_t a_limit) : limit(a_limit) {} + void operator() () const { + limitMem(limit); + } +}; + +int argC; +char** argV; + +struct RoundRobin: NoAssign { + const long number_of_threads; + mutable CMemTest test; + + RoundRobin( long p, Harness::SpinBarrier *limitBarrier, bool verbose ) : + number_of_threads(p), test(limitBarrier, verbose) {} + void operator()( int /*id*/ ) const + { + test.RunAllTests(number_of_threads); + } +}; + +bool CMemTest::firstTime = true; + +inline size_t choose_random_alignment() { + return sizeof(void*)<<(rand() % POWERS_OF_2); +} + +static void setSystemAllocs() +{ + Rmalloc=malloc; + Rrealloc=realloc; + Rcalloc=calloc; + Tfree=free; +#if _WIN32 || _WIN64 + Raligned_malloc=_aligned_malloc; + Raligned_realloc=_aligned_realloc; + Taligned_free=_aligned_free; + Rposix_memalign=0; +#elif __APPLE__ || __sun || __ANDROID__ +// macOS, Solaris*, and Android* don't have posix_memalign + Raligned_malloc=0; + Raligned_realloc=0; + Taligned_free=0; + Rposix_memalign=0; +#else + Raligned_malloc=0; + Raligned_realloc=0; + Taligned_free=0; + Rposix_memalign=posix_memalign; +#endif +} + +// check that realloc works as free and as malloc +void ReallocParam() +{ + const int ITERS = 1000; + int i; + void *bufs[ITERS]; + + bufs[0] = Trealloc(NULL, 30*MByte); + ASSERT(bufs[0], "Can't get memory to start the test."); + + for (i=1; i<ITERS; i++) + { + bufs[i] = Trealloc(NULL, 30*MByte); + if (NULL == bufs[i]) + break; + } + ASSERT(i<ITERS, "Limits should be decreased for the test to work."); + + Trealloc(bufs[0], 0); + /* There is a race for the free space between different threads at + this point. So, have to run the test sequentially. + */ + bufs[0] = Trealloc(NULL, 30*MByte); + ASSERT(bufs[0], NULL); + + for (int j=0; j<i; j++) + Trealloc(bufs[j], 0); +} + +void CheckArgumentsOverflow() +{ + void *p; + const size_t params[] = {SIZE_MAX, SIZE_MAX-16}; + + for (unsigned i=0; i<Harness::array_length(params); i++) { + p = Tmalloc(params[i]); + ASSERT(!p, NULL); + ASSERT_ERRNO(errno==ENOMEM, NULL); + p = Trealloc(NULL, params[i]); + ASSERT(!p, NULL); + ASSERT_ERRNO(errno==ENOMEM, NULL); + p = Tcalloc(1, params[i]); + ASSERT(!p, NULL); + ASSERT_ERRNO(errno==ENOMEM, NULL); + p = Tcalloc(params[i], 1); + ASSERT(!p, NULL); + ASSERT_ERRNO(errno==ENOMEM, NULL); + } + const size_t max_alignment = size_t(1) << (sizeof(size_t)*CHAR_BIT - 1); + if (Rposix_memalign) { + int ret = Rposix_memalign(&p, max_alignment, ~max_alignment); + ASSERT(ret == ENOMEM, NULL); + for (unsigned i=0; i<Harness::array_length(params); i++) { + ret = Rposix_memalign(&p, max_alignment, params[i]); + ASSERT(ret == ENOMEM, NULL); + ret = Rposix_memalign(&p, sizeof(void*), params[i]); + ASSERT(ret == ENOMEM, NULL); + } + } + if (Raligned_malloc) { + p = Raligned_malloc(~max_alignment, max_alignment); + ASSERT(!p, NULL); + for (unsigned i=0; i<Harness::array_length(params); i++) { + p = Raligned_malloc(params[i], max_alignment); + ASSERT(!p, NULL); + ASSERT_ERRNO(errno==ENOMEM, NULL); + p = Raligned_malloc(params[i], sizeof(void*)); + ASSERT(!p, NULL); + ASSERT_ERRNO(errno==ENOMEM, NULL); + } + } + + p = Tcalloc(SIZE_MAX/2-16, SIZE_MAX/2-16); + ASSERT(!p, NULL); + ASSERT_ERRNO(errno==ENOMEM, NULL); + p = Tcalloc(SIZE_MAX/2, SIZE_MAX/2); + ASSERT(!p, NULL); + ASSERT_ERRNO(errno==ENOMEM, NULL); +} + +void InvariantDataRealloc(bool aligned, size_t maxAllocSize, bool checkData) +{ + Harness::FastRandom fastRandom(1); + size_t size = 0, start = 0; + char *ptr = NULL, + // master to create copies and compare ralloc result against it + *master = (char*)Tmalloc(2*maxAllocSize); + + ASSERT(master, NULL); + ASSERT(!(2*maxAllocSize%sizeof(unsigned short)), + "The loop below expects that 2*maxAllocSize contains sizeof(unsigned short)"); + for (size_t k = 0; k<2*maxAllocSize; k+=sizeof(unsigned short)) + *(unsigned short*)(master+k) = fastRandom.get(); + + for (int i=0; i<100; i++) { + // don't want sizeNew==0 here + const size_t sizeNew = fastRandom.get() % (maxAllocSize-1) + 1; + char *ptrNew = aligned? + (char*)Taligned_realloc(ptr, sizeNew, choose_random_alignment()) + : (char*)Trealloc(ptr, sizeNew); + ASSERT(ptrNew, NULL); + // check that old data not changed + if (checkData) + ASSERT(!memcmp(ptrNew, master+start, min(size, sizeNew)), "broken data"); + + // prepare fresh data, copying them from random position in master + size = sizeNew; + ptr = ptrNew; + if (checkData) { + start = fastRandom.get() % maxAllocSize; + memcpy(ptr, master+start, size); + } + } + if (aligned) + Taligned_realloc(ptr, 0, choose_random_alignment()); + else + Trealloc(ptr, 0); + Tfree(master); +} + +#include "harness_memory.h" + +void CheckReallocLeak() +{ + int i; + const int ITER_TO_STABILITY = 10; + // do bootstrap + for (int k=0; k<3; k++) + InvariantDataRealloc(/*aligned=*/false, 128*MByte, /*checkData=*/false); + size_t prev = GetMemoryUsage(peakUsage); + // expect realloc to not increase peak memory consumption after ITER_TO_STABILITY-1 iterations + for (i=0; i<ITER_TO_STABILITY; i++) { + for (int k=0; k<3; k++) + InvariantDataRealloc(/*aligned=*/false, 128*MByte, /*checkData=*/false); + size_t curr = GetMemoryUsage(peakUsage); + if (prev == curr) + break; + prev = curr; + } + ASSERT(i < ITER_TO_STABILITY, "Can't stabilize memory consumption."); +} + +HARNESS_EXPORT +int main(int argc, char* argv[]) { + argC=argc; + argV=argv; + MaxThread = MinThread = 1; + Rmalloc=scalable_malloc; + Rrealloc=scalable_realloc; + Rcalloc=scalable_calloc; + Tfree=scalable_free; + Rposix_memalign=scalable_posix_memalign; + Raligned_malloc=scalable_aligned_malloc; + Raligned_realloc=scalable_aligned_realloc; + Taligned_free=scalable_aligned_free; + + // check if we were called to test standard behavior + for (int i=1; i< argc; i++) { + if (strcmp((char*)*(argv+i),"-s")==0) + { +#if __INTEL_COMPILER == 1400 && __linux__ + // Workaround for Intel(R) C++ Compiler XE, version 14.0.0.080: + // unable to call setSystemAllocs() in such configuration. + REPORT("Known issue: Standard allocator testing is not supported.\n"); + REPORT( "skip\n" ); + return 0; +#else + setSystemAllocs(); + argC--; + break; +#endif + } + } + + ParseCommandLine( argC, argV ); +#if __linux__ + /* According to man pthreads + "NPTL threads do not share resource limits (fixed in kernel 2.6.10)". + Use per-threads limits for affected systems. + */ + if ( LinuxKernelVersion() < 2*1000000 + 6*1000 + 10) + perProcessLimits = false; +#endif + //------------------------------------- +#if __APPLE__ + /* Skip due to lack of memory limit enforcing under macOS. */ +#else + limitMem(200); + ReallocParam(); + limitMem(0); +#endif + +//for linux and dynamic runtime errno is used to check allocator functions +//check if library compiled with /MD(d) and we can use errno +#if _MSC_VER +#if defined(_MT) && defined(_DLL) //check errno if test itself compiled with /MD(d) only + char* version_info_block = NULL; + int version_info_block_size; + LPVOID comments_block = NULL; + UINT comments_block_size; +#ifdef _DEBUG +#define __TBBMALLOCDLL "tbbmalloc_debug.dll" +#else //_DEBUG +#define __TBBMALLOCDLL "tbbmalloc.dll" +#endif //_DEBUG + version_info_block_size = GetFileVersionInfoSize( __TBBMALLOCDLL, (LPDWORD)&version_info_block_size ); + if( version_info_block_size + && ((version_info_block = (char*)malloc(version_info_block_size)) != NULL) + && GetFileVersionInfo( __TBBMALLOCDLL, NULL, version_info_block_size, version_info_block ) + && VerQueryValue( version_info_block, "\\StringFileInfo\\000004b0\\Comments", &comments_block, &comments_block_size ) + && strstr( (char*)comments_block, "/MD" ) + ){ + __tbb_test_errno = true; + } + if( version_info_block ) free( version_info_block ); +#endif // defined(_MT) && defined(_DLL) +#else // _MSC_VER + __tbb_test_errno = true; +#endif // _MSC_VER + + CheckArgumentsOverflow(); + CheckReallocLeak(); + for( int p=MaxThread; p>=MinThread; --p ) { + REMARK("testing with %d threads\n", p ); + for (int limit=0; limit<2; limit++) { + int ret = scalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, + 16*1024*limit); + ASSERT(ret==TBBMALLOC_OK, NULL); + Harness::SpinBarrier *barrier = new Harness::SpinBarrier(p); + NativeParallelFor( p, RoundRobin(p, barrier, Verbose) ); + delete barrier; + } + } + int ret = scalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, 0); + ASSERT(ret==TBBMALLOC_OK, NULL); + if( !error_occurred ) + REPORT("done\n"); + return 0; +} + +// if non-zero byte found, returns bad value address plus 1 +size_t NonZero(void *ptr, size_t size) +{ + size_t words = size / sizeof(intptr_t); + size_t tailSz = size % sizeof(intptr_t); + intptr_t *buf =(intptr_t*)ptr; + char *bufTail =(char*)(buf+words); + + for (size_t i=0; i<words; i++) + if (buf[i]) { + for (unsigned b=0; b<sizeof(intptr_t); b++) + if (((char*)(buf+i))[b]) + return sizeof(intptr_t)*i + b + 1; + } + for (size_t i=0; i<tailSz; i++) + if (bufTail[i]) { + return words*sizeof(intptr_t)+i+1; + } + return 0; +} + +struct TestStruct +{ + DWORD field1:2; + DWORD field2:6; + double field3; + UCHAR field4[100]; + TestStruct* field5; + std::vector<int> field7; + double field8; +}; + +void* Tmalloc(size_t size) +{ + // For compatibility, on 64-bit systems malloc should align to 16 bytes + size_t alignment = (sizeof(intptr_t)>4 && size>8) ? 16 : 8; + void *ret = Rmalloc(size); + if (0 != ret) + ASSERT(0==((uintptr_t)ret & (alignment-1)), + "allocation result should be properly aligned"); + return ret; +} +void* Tcalloc(size_t num, size_t size) +{ + // For compatibility, on 64-bit systems calloc should align to 16 bytes + size_t alignment = (sizeof(intptr_t)>4 && num && size>8) ? 16 : 8; + void *ret = Rcalloc(num, size); + if (0 != ret) + ASSERT(0==((uintptr_t)ret & (alignment-1)), + "allocation result should be properly aligned"); + return ret; +} +void* Trealloc(void* memblock, size_t size) +{ + // For compatibility, on 64-bit systems realloc should align to 16 bytes + size_t alignment = (sizeof(intptr_t)>4 && size>8) ? 16 : 8; + void *ret = Rrealloc(memblock, size); + if (0 != ret) + ASSERT(0==((uintptr_t)ret & (alignment-1)), + "allocation result should be properly aligned"); + return ret; +} +int Tposix_memalign(void **memptr, size_t alignment, size_t size) +{ + int ret = Rposix_memalign(memptr, alignment, size); + if (0 == ret) + ASSERT(0==((uintptr_t)*memptr & (alignment-1)), + "allocation result should be aligned"); + return ret; +} +void* Taligned_malloc(size_t size, size_t alignment) +{ + void *ret = Raligned_malloc(size, alignment); + if (0 != ret) + ASSERT(0==((uintptr_t)ret & (alignment-1)), + "allocation result should be aligned"); + return ret; +} +void* Taligned_realloc(void* memblock, size_t size, size_t alignment) +{ + void *ret = Raligned_realloc(memblock, size, alignment); + if (0 != ret) + ASSERT(0==((uintptr_t)ret & (alignment-1)), + "allocation result should be aligned"); + return ret; +} + +struct PtrSize { + void *ptr; + size_t size; +}; + +static int cmpAddrs(const void *p1, const void *p2) +{ + const PtrSize *a = (const PtrSize *)p1; + const PtrSize *b = (const PtrSize *)p2; + + return a->ptr < b->ptr ? -1 : ( a->ptr == b->ptr ? 0 : 1); +} + +void CMemTest::AddrArifm() +{ + PtrSize *arr = (PtrSize*)Tmalloc(COUNT_ELEM*sizeof(PtrSize)); + + if (FullLog) REPORT("\nUnique pointer using Address arithmetic\n"); + if (FullLog) REPORT("malloc...."); + ASSERT(arr, NULL); + for (int i=0; i<COUNT_ELEM; i++) + { + arr[i].size=rand()%MAX_SIZE; + arr[i].ptr=Tmalloc(arr[i].size); + } + qsort(arr, COUNT_ELEM, sizeof(PtrSize), cmpAddrs); + + for (int i=0; i<COUNT_ELEM-1; i++) + { + if (NULL!=arr[i].ptr && NULL!=arr[i+1].ptr) + ASSERT((uintptr_t)arr[i].ptr+arr[i].size <= (uintptr_t)arr[i+1].ptr, + "intersection detected"); + } + //---------------------------------------------------------------- + if (FullLog) REPORT("realloc...."); + for (int i=0; i<COUNT_ELEM; i++) + { + size_t count=arr[i].size*2; + void *tmpAddr=Trealloc(arr[i].ptr,count); + if (NULL!=tmpAddr) { + arr[i].ptr = tmpAddr; + arr[i].size = count; + } else if (count==0) { // because realloc(..., 0) works as free + arr[i].ptr = NULL; + arr[i].size = 0; + } + } + qsort(arr, COUNT_ELEM, sizeof(PtrSize), cmpAddrs); + + for (int i=0; i<COUNT_ELEM-1; i++) + { + if (NULL!=arr[i].ptr && NULL!=arr[i+1].ptr) + ASSERT((uintptr_t)arr[i].ptr+arr[i].size <= (uintptr_t)arr[i+1].ptr, + "intersection detected"); + } + for (int i=0; i<COUNT_ELEM; i++) + { + Tfree(arr[i].ptr); + } + //------------------------------------------- + if (FullLog) REPORT("calloc...."); + for (int i=0; i<COUNT_ELEM; i++) + { + arr[i].size=rand()%MAX_SIZE; + arr[i].ptr=Tcalloc(arr[i].size,1); + } + qsort(arr, COUNT_ELEM, sizeof(PtrSize), cmpAddrs); + + for (int i=0; i<COUNT_ELEM-1; i++) + { + if (NULL!=arr[i].ptr && NULL!=arr[i+1].ptr) + ASSERT((uintptr_t)arr[i].ptr+arr[i].size <= (uintptr_t)arr[i+1].ptr, + "intersection detected"); + } + for (int i=0; i<COUNT_ELEM; i++) + { + Tfree(arr[i].ptr); + } + Tfree(arr); +} + +void CMemTest::Zerofilling() +{ + TestStruct* TSMas; + size_t CountElement; + CountErrors=0; + if (FullLog) REPORT("\nzeroings elements of array...."); + //test struct + for (int i=0; i<COUNTEXPERIMENT; i++) + { + CountElement=rand()%MAX_SIZE; + TSMas=(TestStruct*)Tcalloc(CountElement,sizeof(TestStruct)); + if (NULL == TSMas) + continue; + for (size_t j=0; j<CountElement; j++) + { + if (NonZero(TSMas+j, sizeof(TestStruct))) + { + CountErrors++; + if (ShouldReportError()) REPORT("detect nonzero element at TestStruct\n"); + } + } + Tfree(TSMas); + } + if (CountErrors) REPORT("%s\n",strError); + else if (FullLog) REPORT("%s\n",strOk); + error_occurred |= ( CountErrors>0 ) ; +} + +#if !__APPLE__ + +void myMemset(void *ptr, int c, size_t n) +{ +#if __linux__ && __i386__ +// memset in Fedora 13 not always correctly sets memory to required values. + char *p = (char*)ptr; + for (size_t i=0; i<n; i++) + p[i] = c; +#else + memset(ptr, c, n); +#endif +} + +// This test requires more than TOTAL_MB_ALLOC MB of RAM. +#if __ANDROID__ +// Android requires lower limit due to lack of virtual memory. +#define TOTAL_MB_ALLOC 200 +#else +#define TOTAL_MB_ALLOC 800 +#endif +void CMemTest::NULLReturn(UINT MinSize, UINT MaxSize, int total_threads) +{ + const int MB_PER_THREAD = TOTAL_MB_ALLOC / total_threads; + // find size to guarantee getting NULL for 1024 B allocations + const int MAXNUM_1024 = (MB_PER_THREAD + (MB_PER_THREAD>>2)) * 1024; + + std::vector<MemStruct> PointerList; + void *tmp; + CountErrors=0; + int CountNULL, num_1024; + if (FullLog) REPORT("\nNULL return & check errno:\n"); + UINT Size; + Limit limit_total(TOTAL_MB_ALLOC), no_limit(0); + void **buf_1024 = (void**)Tmalloc(MAXNUM_1024*sizeof(void*)); + + ASSERT(buf_1024, NULL); + /* We must have space for pointers when memory limit is hit. + Reserve enough for the worst case, taking into account race for + limited space between threads. + */ + PointerList.reserve(TOTAL_MB_ALLOC*MByte/MinSize); + + /* There is a bug in the specific version of GLIBC (2.5-12) shipped + with RHEL5 that leads to erroneous working of the test + on Intel(R) 64 and Itanium(R) architecture when setrlimit-related part is enabled. + Switching to GLIBC 2.5-18 from RHEL5.1 resolved the issue. + */ + if (perProcessLimits) + limitBarrier->wait(limit_total); + else + limitMem(MB_PER_THREAD); + + /* regression test against the bug in allocator when it dereference NULL + while lack of memory + */ + for (num_1024=0; num_1024<MAXNUM_1024; num_1024++) { + buf_1024[num_1024] = Tcalloc(1024, 1); + if (! buf_1024[num_1024]) { + ASSERT_ERRNO(errno == ENOMEM, NULL); + break; + } + } + for (int i=0; i<num_1024; i++) + Tfree(buf_1024[i]); + Tfree(buf_1024); + + do { + Size=rand()%(MaxSize-MinSize)+MinSize; + tmp=Tmalloc(Size); + if (tmp != NULL) + { + myMemset(tmp, 0, Size); + PointerList.push_back(MemStruct(tmp, Size)); + } + } while(tmp != NULL); + ASSERT_ERRNO(errno == ENOMEM, NULL); + if (FullLog) REPORT("\n"); + + // preparation complete, now running tests + // malloc + if (FullLog) REPORT("malloc...."); + CountNULL = 0; + while (CountNULL==0) + for (int j=0; j<COUNT_TESTS; j++) + { + Size=rand()%(MaxSize-MinSize)+MinSize; + errno = ENOMEM+j+1; + tmp=Tmalloc(Size); + if (tmp == NULL) + { + CountNULL++; + if ( CHECK_ERRNO(errno != ENOMEM) ) { + CountErrors++; + if (ShouldReportError()) REPORT("NULL returned, error: errno (%d) != ENOMEM\n", errno); + } + } + else + { + // Technically, if malloc returns a non-NULL pointer, it is allowed to set errno anyway. + // However, on most systems it does not set errno. + bool known_issue = false; +#if __linux__ || __ANDROID__ + if( CHECK_ERRNO(errno==ENOMEM) ) known_issue = true; +#endif /* __linux__ */ + if ( CHECK_ERRNO(errno != ENOMEM+j+1) && !known_issue) { + CountErrors++; + if (ShouldReportError()) REPORT("error: errno changed to %d though valid pointer was returned\n", errno); + } + myMemset(tmp, 0, Size); + PointerList.push_back(MemStruct(tmp, Size)); + } + } + if (FullLog) REPORT("end malloc\n"); + if (CountErrors) REPORT("%s\n",strError); + else if (FullLog) REPORT("%s\n",strOk); + error_occurred |= ( CountErrors>0 ) ; + + CountErrors=0; + //calloc + if (FullLog) REPORT("calloc...."); + CountNULL = 0; + while (CountNULL==0) + for (int j=0; j<COUNT_TESTS; j++) + { + Size=rand()%(MaxSize-MinSize)+MinSize; + errno = ENOMEM+j+1; + tmp=Tcalloc(COUNT_ELEM_CALLOC,Size); + if (tmp == NULL) + { + CountNULL++; + if ( CHECK_ERRNO(errno != ENOMEM) ){ + CountErrors++; + if (ShouldReportError()) REPORT("NULL returned, error: errno(%d) != ENOMEM\n", errno); + } + } + else + { + // Technically, if calloc returns a non-NULL pointer, it is allowed to set errno anyway. + // However, on most systems it does not set errno. + bool known_issue = false; +#if __linux__ + if( CHECK_ERRNO(errno==ENOMEM) ) known_issue = true; +#endif /* __linux__ */ + if ( CHECK_ERRNO(errno != ENOMEM+j+1) && !known_issue ) { + CountErrors++; + if (ShouldReportError()) REPORT("error: errno changed to %d though valid pointer was returned\n", errno); + } + PointerList.push_back(MemStruct(tmp, Size)); + } + } + if (FullLog) REPORT("end calloc\n"); + if (CountErrors) REPORT("%s\n",strError); + else if (FullLog) REPORT("%s\n",strOk); + error_occurred |= ( CountErrors>0 ) ; + CountErrors=0; + if (FullLog) REPORT("realloc...."); + CountNULL = 0; + if (PointerList.size() > 0) + while (CountNULL==0) + for (size_t i=0; i<(size_t)COUNT_TESTS && i<PointerList.size(); i++) + { + errno = 0; + tmp=Trealloc(PointerList[i].Pointer,PointerList[i].Size*2); + if (tmp != NULL) // same or another place + { + bool known_issue = false; +#if __linux__ + if( errno==ENOMEM ) known_issue = true; +#endif /* __linux__ */ + if (errno != 0 && !known_issue) { + CountErrors++; + if (ShouldReportError()) REPORT("valid pointer returned, error: errno not kept\n"); + } + // newly allocated area have to be zeroed + myMemset((char*)tmp + PointerList[i].Size, 0, PointerList[i].Size); + PointerList[i].Pointer = tmp; + PointerList[i].Size *= 2; + } else { + CountNULL++; + if ( CHECK_ERRNO(errno != ENOMEM) ) + { + CountErrors++; + if (ShouldReportError()) REPORT("NULL returned, error: errno(%d) != ENOMEM\n", errno); + } + // check data integrity + if (NonZero(PointerList[i].Pointer, PointerList[i].Size)) { + CountErrors++; + if (ShouldReportError()) REPORT("NULL returned, error: data changed\n"); + } + } + } + if (FullLog) REPORT("realloc end\n"); + if (CountErrors) REPORT("%s\n",strError); + else if (FullLog) REPORT("%s\n",strOk); + error_occurred |= ( CountErrors>0 ) ; + for (UINT i=0; i<PointerList.size(); i++) + { + Tfree(PointerList[i].Pointer); + } + + if (perProcessLimits) + limitBarrier->wait(no_limit); + else + limitMem(0); +} +#endif /* #if !__APPLE__ */ + +void CMemTest::UniquePointer() +{ + CountErrors=0; + int **MasPointer = (int **)Tmalloc(sizeof(int*)*COUNT_ELEM); + size_t *MasCountElem = (size_t*)Tmalloc(sizeof(size_t)*COUNT_ELEM); + if (FullLog) REPORT("\nUnique pointer using 0\n"); + ASSERT(MasCountElem && MasPointer, NULL); + // + //------------------------------------------------------- + //malloc + for (int i=0; i<COUNT_ELEM; i++) + { + MasCountElem[i]=rand()%MAX_SIZE; + MasPointer[i]=(int*)Tmalloc(MasCountElem[i]*sizeof(int)); + if (NULL == MasPointer[i]) + MasCountElem[i]=0; + memset(MasPointer[i], 0, sizeof(int)*MasCountElem[i]); + } + if (FullLog) REPORT("malloc...."); + for (UINT i=0; i<COUNT_ELEM-1; i++) + { + if (size_t badOff = NonZero(MasPointer[i], sizeof(int)*MasCountElem[i])) { + CountErrors++; + if (ShouldReportError()) + REPORT("error, detect non-zero at %p\n", (char*)MasPointer[i]+badOff-1); + } + memset(MasPointer[i], 1, sizeof(int)*MasCountElem[i]); + } + if (CountErrors) REPORT("%s\n",strError); + else if (FullLog) REPORT("%s\n",strOk); + error_occurred |= ( CountErrors>0 ) ; + //---------------------------------------------------------- + //calloc + for (int i=0; i<COUNT_ELEM; i++) + Tfree(MasPointer[i]); + CountErrors=0; + for (long i=0; i<COUNT_ELEM; i++) + { + MasPointer[i]=(int*)Tcalloc(MasCountElem[i]*sizeof(int),2); + if (NULL == MasPointer[i]) + MasCountElem[i]=0; + } + if (FullLog) REPORT("calloc...."); + for (int i=0; i<COUNT_ELEM-1; i++) + { + if (size_t badOff = NonZero(MasPointer[i], sizeof(int)*MasCountElem[i])) { + CountErrors++; + if (ShouldReportError()) + REPORT("error, detect non-zero at %p\n", (char*)MasPointer[i]+badOff-1); + } + memset(MasPointer[i], 1, sizeof(int)*MasCountElem[i]); + } + if (CountErrors) REPORT("%s\n",strError); + else if (FullLog) REPORT("%s\n",strOk); + error_occurred |= ( CountErrors>0 ) ; + //--------------------------------------------------------- + //realloc + CountErrors=0; + for (int i=0; i<COUNT_ELEM; i++) + { + MasCountElem[i]*=2; + *(MasPointer+i)= + (int*)Trealloc(*(MasPointer+i),MasCountElem[i]*sizeof(int)); + if (NULL == MasPointer[i]) + MasCountElem[i]=0; + memset(MasPointer[i], 0, sizeof(int)*MasCountElem[i]); + } + if (FullLog) REPORT("realloc...."); + for (int i=0; i<COUNT_ELEM-1; i++) + { + if (NonZero(MasPointer[i], sizeof(int)*MasCountElem[i])) + CountErrors++; + memset(MasPointer[i], 1, sizeof(int)*MasCountElem[i]); + } + if (CountErrors) REPORT("%s\n",strError); + else if (FullLog) REPORT("%s\n",strOk); + error_occurred |= ( CountErrors>0 ) ; + for (int i=0; i<COUNT_ELEM; i++) + Tfree(MasPointer[i]); + Tfree(MasCountElem); + Tfree(MasPointer); +} + +bool CMemTest::ShouldReportError() +{ + if (FullLog) + return true; + else + if (firstTime) { + firstTime = false; + return true; + } else + return false; +} + +void CMemTest::Free_NULL() +{ + CountErrors=0; + if (FullLog) REPORT("\ncall free with parameter NULL...."); + errno = 0; + for (int i=0; i<COUNTEXPERIMENT; i++) + { + Tfree(NULL); + if (CHECK_ERRNO(errno)) + { + CountErrors++; + if (ShouldReportError()) REPORT("error is found by a call free with parameter NULL\n"); + } + } + if (CountErrors) REPORT("%s\n",strError); + else if (FullLog) REPORT("%s\n",strOk); + error_occurred |= ( CountErrors>0 ) ; +} + +void CMemTest::TestAlignedParameters() +{ + void *memptr; + int ret; + + if (Rposix_memalign) { + // alignment isn't power of 2 + for (int bad_align=3; bad_align<16; bad_align++) + if (bad_align&(bad_align-1)) { + ret = Tposix_memalign(NULL, bad_align, 100); + ASSERT(EINVAL==ret, NULL); + } + + memptr = &ret; + ret = Tposix_memalign(&memptr, 5*sizeof(void*), 100); + ASSERT(memptr == &ret, + "memptr should not be changed after unsuccessful call"); + ASSERT(EINVAL==ret, NULL); + + // alignment is power of 2, but not a multiple of sizeof(void *), + // we expect that sizeof(void*) > 2 + ret = Tposix_memalign(NULL, 2, 100); + ASSERT(EINVAL==ret, NULL); + } + if (Raligned_malloc) { + // alignment isn't power of 2 + for (int bad_align=3; bad_align<16; bad_align++) + if (bad_align&(bad_align-1)) { + memptr = Taligned_malloc(100, bad_align); + ASSERT(NULL==memptr, NULL); + ASSERT_ERRNO(EINVAL==errno, NULL); + } + + // size is zero + memptr = Taligned_malloc(0, 16); + ASSERT(NULL==memptr, "size is zero, so must return NULL"); + ASSERT_ERRNO(EINVAL==errno, NULL); + } + if (Taligned_free) { + // NULL pointer is OK to free + errno = 0; + Taligned_free(NULL); + /* As there is no return value for free, strictly speaking we can't + check errno here. But checked implementations obey the assertion. + */ + ASSERT_ERRNO(0==errno, NULL); + } + if (Raligned_realloc) { + for (int i=1; i<20; i++) { + // checks that calls work correctly in presence of non-zero errno + errno = i; + void *ptr = Taligned_malloc(i*10, 128); + ASSERT(NULL!=ptr, NULL); + ASSERT_ERRNO(0!=errno, NULL); + // if size is zero and pointer is not NULL, works like free + memptr = Taligned_realloc(ptr, 0, 64); + ASSERT(NULL==memptr, NULL); + ASSERT_ERRNO(0!=errno, NULL); + } + // alignment isn't power of 2 + for (int bad_align=3; bad_align<16; bad_align++) + if (bad_align&(bad_align-1)) { + void *ptr = &bad_align; + memptr = Taligned_realloc(&ptr, 100, bad_align); + ASSERT(NULL==memptr, NULL); + ASSERT(&bad_align==ptr, NULL); + ASSERT_ERRNO(EINVAL==errno, NULL); + } + } +} + +void CMemTest::RunAllTests(int total_threads) +{ + Zerofilling(); + Free_NULL(); + InvariantDataRealloc(/*aligned=*/false, 8*MByte, /*checkData=*/true); + if (Raligned_realloc) + InvariantDataRealloc(/*aligned=*/true, 8*MByte, /*checkData=*/true); + TestAlignedParameters(); + UniquePointer(); + AddrArifm(); +#if __APPLE__ + REPORT("Known issue: some tests are skipped on macOS\n"); +#else + NULLReturn(1*MByte,100*MByte,total_threads); +#endif + if (FullLog) REPORT("Tests for %d threads ended\n", total_threads); +} + +#endif /* __TBB_WIN8UI_SUPPORT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_init_shutdown.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_init_shutdown.cpp new file mode 100644 index 00000000..7e9e5b29 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_init_shutdown.cpp @@ -0,0 +1,176 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/scalable_allocator.h" +#include "tbb/atomic.h" +#include "tbb/aligned_space.h" + +#define HARNESS_TBBMALLOC_THREAD_SHUTDOWN 1 +#include "harness.h" +#include "harness_barrier.h" +#if !__TBB_SOURCE_DIRECTLY_INCLUDED +#include "harness_tbb_independence.h" +#endif + +tbb::atomic<int> FinishedTasks; +const int MaxTasks = 16; + +/*--------------------------------------------------------------------*/ +// The regression test against a bug triggered when malloc initialization +// and thread shutdown were called simultaneously, in which case +// Windows dynamic loader lock and allocator initialization/termination lock +// were taken in different order. + +class TestFunc1 { + Harness::SpinBarrier* my_barr; +public: + TestFunc1 (Harness::SpinBarrier& barr) : my_barr(&barr) {} + void operator() (bool do_malloc) const { + my_barr->wait(); + if (do_malloc) scalable_malloc(10); + ++FinishedTasks; + } +}; + +typedef NativeParallelForTask<bool,TestFunc1> TestTask1; + +void Test1 () { + int NTasks = min(MaxTasks, max(2, MaxThread)); + Harness::SpinBarrier barr(NTasks); + TestFunc1 tf(barr); + FinishedTasks = 0; + tbb::aligned_space<TestTask1,MaxTasks> tasks; + + for(int i=0; i<NTasks; ++i) { + TestTask1* t = tasks.begin()+i; + new(t) TestTask1(i%2==0, tf); + t->start(); + } + + Harness::Sleep(1000); // wait a second :) + ASSERT( FinishedTasks==NTasks, "Some threads appear to deadlock" ); + + for(int i=0; i<NTasks; ++i) { + TestTask1* t = tasks.begin()+i; + t->wait_to_finish(); + t->~TestTask1(); + } +} + +/*--------------------------------------------------------------------*/ +// The regression test against a bug when cross-thread deallocation +// caused livelock at thread shutdown. + +void* gPtr = NULL; + +class TestFunc2a { + Harness::SpinBarrier* my_barr; +public: + TestFunc2a (Harness::SpinBarrier& barr) : my_barr(&barr) {} + void operator() (int) const { + gPtr = scalable_malloc(8); + my_barr->wait(); + ++FinishedTasks; + } +}; + +typedef NativeParallelForTask<int,TestFunc2a> TestTask2a; + +class TestFunc2b: NoAssign { + Harness::SpinBarrier* my_barr; + TestTask2a& my_ward; +public: + TestFunc2b (Harness::SpinBarrier& barr, TestTask2a& t) : my_barr(&barr), my_ward(t) {} + void operator() (int) const { + tbb::internal::spin_wait_while_eq(gPtr, (void*)NULL); + scalable_free(gPtr); + my_barr->wait(); + my_ward.wait_to_finish(); + ++FinishedTasks; + } +}; +void Test2() { + Harness::SpinBarrier barr(2); + TestFunc2a func2a(barr); + TestTask2a t2a(0, func2a); + TestFunc2b func2b(barr, t2a); + NativeParallelForTask<int,TestFunc2b> t2b(1, func2b); + FinishedTasks = 0; + t2a.start(); t2b.start(); + Harness::Sleep(1000); // wait a second :) + ASSERT( FinishedTasks==2, "Threads appear to deadlock" ); + t2b.wait_to_finish(); // t2a is monitored by t2b +} + +#if _WIN32||_WIN64 + +void TestKeyDtor() {} + +#else + +void *currSmall, *prevSmall, *currLarge, *prevLarge; + +extern "C" void threadDtor(void*) { + // First, release memory that was allocated before; + // it will not re-initialize the thread-local data if already deleted + prevSmall = currSmall; + scalable_free(currSmall); + prevLarge = currLarge; + scalable_free(currLarge); + // Then, allocate more memory. + // It will re-initialize the allocator data in the thread. + scalable_free(scalable_malloc(8)); +} + +inline bool intersectingObjects(const void *p1, const void *p2, size_t n) +{ + return p1>p2 ? ((uintptr_t)p1-(uintptr_t)p2)<n : ((uintptr_t)p2-(uintptr_t)p1)<n; +} + +struct TestThread: NoAssign { + TestThread(int ) {} + + void operator()( int /*id*/ ) const { + pthread_key_t key; + + currSmall = scalable_malloc(8); + ASSERT(!prevSmall || currSmall==prevSmall, "Possible memory leak"); + currLarge = scalable_malloc(32*1024); + // intersectingObjects takes into account object shuffle + ASSERT(!prevLarge || intersectingObjects(currLarge, prevLarge, 32*1024), "Possible memory leak"); + pthread_key_create( &key, &threadDtor ); + pthread_setspecific(key, (const void*)42); + } +}; + +// test releasing memory from pthread key destructor +void TestKeyDtor() { + // Allocate region for large objects to prevent whole region release + // on scalable_free(currLarge) call, which result in wrong assert inside intersectingObjects check + void* preventLargeRelease = scalable_malloc(32*1024); + for (int i=0; i<4; i++) + NativeParallelFor( 1, TestThread(1) ); + scalable_free(preventLargeRelease); +} + +#endif // _WIN32||_WIN64 + +int TestMain () { + Test1(); // requires malloc initialization so should be first + Test2(); + TestKeyDtor(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_lib_unload.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_lib_unload.cpp new file mode 100644 index 00000000..9697037a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_lib_unload.cpp @@ -0,0 +1,218 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _USRDLL + +#include <stdlib.h> // for NULL +#include "harness_assert.h" +#define HARNESS_CUSTOM_MAIN 1 +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" + +const char *globalCallMsg = "A TBB allocator function call is resolved into wrong implementation."; + +#if _WIN32||_WIN64 +// must be defined in DLL for linker to not drop the dependency on the DLL. +extern "C" { + extern __declspec(dllexport) void *scalable_malloc(size_t); + extern __declspec(dllexport) void scalable_free (void *); + extern __declspec(dllexport) void safer_scalable_free (void *, void (*)(void*)); + extern __declspec(dllexport) void *scalable_realloc(void *, size_t); + extern __declspec(dllexport) void *safer_scalable_realloc(void *, size_t, void *); + extern __declspec(dllexport) void *scalable_calloc(size_t, size_t); + extern __declspec(dllexport) int scalable_posix_memalign(void **, size_t, size_t); + extern __declspec(dllexport) void *scalable_aligned_malloc(size_t, size_t); + extern __declspec(dllexport) void *scalable_aligned_realloc(void *, size_t, size_t); + extern __declspec(dllexport) void *safer_scalable_aligned_realloc(void *, size_t, size_t, void *); + extern __declspec(dllexport) void scalable_aligned_free(void *); + extern __declspec(dllexport) size_t scalable_msize(void *); + extern __declspec(dllexport) size_t safer_scalable_msize (void *, size_t (*)(void*)); +} +#endif + +// Those functions must not be called instead of presented in dynamic library. +extern "C" void *scalable_malloc(size_t) +{ + ASSERT(0, globalCallMsg); + return NULL; +} +extern "C" void scalable_free (void *) +{ + ASSERT(0, globalCallMsg); +} +extern "C" void safer_scalable_free (void *, void (*)(void*)) +{ + ASSERT(0, globalCallMsg); +} +extern "C" void *scalable_realloc(void *, size_t) +{ + ASSERT(0, globalCallMsg); + return NULL; +} +extern "C" void *safer_scalable_realloc(void *, size_t, void *) +{ + ASSERT(0, globalCallMsg); + return NULL; +} +extern "C" void *scalable_calloc(size_t, size_t) +{ + ASSERT(0, globalCallMsg); + return NULL; +} +extern "C" int scalable_posix_memalign(void **, size_t, size_t) +{ + ASSERT(0, globalCallMsg); + return 0; +} +extern "C" void *scalable_aligned_malloc(size_t, size_t) +{ + ASSERT(0, globalCallMsg); + return NULL; +} +extern "C" void *scalable_aligned_realloc(void *, size_t, size_t) +{ + ASSERT(0, globalCallMsg); + return NULL; +} +extern "C" void *safer_scalable_aligned_realloc(void *, size_t, size_t, void *) +{ + ASSERT(0, globalCallMsg); + return NULL; +} +extern "C" void scalable_aligned_free(void *) +{ + ASSERT(0, globalCallMsg); +} +extern "C" size_t scalable_msize(void *) +{ + ASSERT(0, globalCallMsg); + return 0; +} +extern "C" size_t safer_scalable_msize (void *, size_t (*)(void*)) +{ + ASSERT(0, globalCallMsg); + return 0; +} + +#else // _USRDLL + +// harness_defs.h must be included before tbb_stddef.h to overcome exception-dependent +// system headers that come from tbb_stddef.h +#include "harness_defs.h" +#include "tbb/tbb_stddef.h" +#if __TBB_WIN8UI_SUPPORT || __TBB_SOURCE_DIRECTLY_INCLUDED || __TBB_MIC_OFFLOAD +// The test does not work if dynamic load is unavailable. +// For MIC offload, it fails because liboffload brings libiomp which observes and uses the fake scalable_* calls. +#define HARNESS_SKIP_TEST 1 +#endif +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#define HARNESS_TBBMALLOC_THREAD_SHUTDOWN 1 +#include "harness.h" + +#if !HARNESS_SKIP_TEST + +#include "harness_dynamic_libs.h" +#include "harness_memory.h" + +extern "C" { +#if _WIN32||_WIN64 +extern __declspec(dllimport) +#endif +void *scalable_malloc(size_t); +} + +struct Run { + void operator()( int /*id*/ ) const { + using namespace Harness; + + void* (*malloc_ptr)(std::size_t); + void (*free_ptr)(void*); + + void* (*aligned_malloc_ptr)(size_t size, size_t alignment); + void (*aligned_free_ptr)(void*); + + const char* actual_name; + LIBRARY_HANDLE lib = OpenLibrary(actual_name = MALLOCLIB_NAME1); + if (!lib) lib = OpenLibrary(actual_name = MALLOCLIB_NAME2); + if (!lib) { + REPORT("Can't load " MALLOCLIB_NAME1 " or " MALLOCLIB_NAME2 "\n"); + exit(1); + } + GetAddress(lib, "scalable_malloc", malloc_ptr); + GetAddress(lib, "scalable_free", free_ptr); + GetAddress(lib, "scalable_aligned_malloc", aligned_malloc_ptr); + GetAddress(lib, "scalable_aligned_free", aligned_free_ptr); + + for (size_t sz = 1024; sz <= 10*1024 ; sz*=10) { + void *p1 = aligned_malloc_ptr(sz, 16); + memset(p1, 0, sz); + aligned_free_ptr(p1); + } + + void *p = malloc_ptr(100); + memset(p, 1, 100); + free_ptr(p); + + CloseLibrary(lib); +#if _WIN32 || _WIN64 + ASSERT(GetModuleHandle(actual_name), + "allocator library must not be unloaded"); +#else + ASSERT(dlsym(RTLD_DEFAULT, "scalable_malloc"), + "allocator library must not be unloaded"); +#endif + } +}; + +int TestMain () { + int i; + std::ptrdiff_t memory_leak; + + // warm-up run + NativeParallelFor( 1, Run() ); + + { + /* 1st call to GetMemoryUsage() allocate some memory, + but it seems memory consumption stabilized after this. + */ + GetMemoryUsage(); + std::size_t memory_in_use = GetMemoryUsage(); + ASSERT(memory_in_use == GetMemoryUsage(), + "Memory consumption should not increase after 1st GetMemoryUsage() call"); + } + { + // expect that memory consumption stabilized after several runs + for (i=0; i<3; i++) { + std::size_t memory_in_use = GetMemoryUsage(); + for (int j=0; j<10; j++) + NativeParallelFor( 1, Run() ); + memory_leak = GetMemoryUsage() - memory_in_use; + if (memory_leak == 0) // possibly too strong? + break; + } + } + if(3==i) { + // not stabilized, could be leak + REPORT( "Error: memory leak of up to %ld bytes\n", static_cast<long>(memory_leak)); + exit(1); + } + + return Harness::Done; +} + +#endif /* HARNESS_SKIP_TEST */ + +#endif // _USRDLL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_new_handler.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_new_handler.cpp new file mode 100644 index 00000000..1c6a1572 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_new_handler.cpp @@ -0,0 +1,81 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_allocator_overload.h" +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#define __TBB_NO_IMPLICIT_LINKAGE 1 + +#include "harness.h" + +#if !HARNESS_SKIP_TEST && TBB_USE_EXCEPTIONS + +#include "harness_tbb_independence.h" +#include "harness_assert.h" +#include "harness_barrier.h" + +#include "../tbb/tls.h" + +tbb::internal::tls<bool> new_handler_called; +void customNewHandler() { + new_handler_called = true; + throw std::bad_alloc(); +} + +// Return true if operator new threw exception +bool allocateWithException(size_t big_mem) { + bool exception_caught = false; + try { + // Allocate big array (should throw exception) + char* volatile big_array = new char[big_mem]; + // If succeeded, double the size (unless it overflows) and recursively retry + if (big_mem * 2 > big_mem) { + exception_caught = allocateWithException(big_mem * 2); + } + delete[] big_array; + } catch (const std::bad_alloc&) { + ASSERT(new_handler_called, "User provided new_handler was not called."); + exception_caught = true; + } + return exception_caught; +} + +class AllocLoopBody : NoAssign { +public: + void operator()(int) const { + size_t BIG_MEM = 100 * 1024 * 1024; + new_handler_called = false; + ASSERT(allocateWithException(BIG_MEM), "Operator new did not throw bad_alloc."); + } +}; + +int TestMain() { +#if __TBB_CPP11_GET_NEW_HANDLER_PRESENT + std::new_handler default_handler = std::get_new_handler(); + ASSERT(default_handler == NULL, "No handler should be set at this point."); +#endif + // Define the handler for new operations + std::set_new_handler(customNewHandler); + // Run the test + NativeParallelFor(8, AllocLoopBody()); + // Undo custom handler + std::set_new_handler(0); + return Harness::Done; +} +#else +int TestMain() { + return Harness::Skipped; +} +#endif // !HARNESS_SKIP_TEST && TBB_USE_EXCEPTIONS diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_overload.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_overload.cpp new file mode 100644 index 00000000..325ee11d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_overload.cpp @@ -0,0 +1,477 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + + +#if (_WIN32 || _WIN64) +// As the test is intentionally build with /EHs-, suppress multiple VS2005's +// warnings like C4530: C++ exception handler used, but unwind semantics are not enabled +#if defined(_MSC_VER) && !__INTEL_COMPILER +/* ICC 10.1 and 11.0 generates code that uses std::_Raise_handler, + but it's only defined in libcpmt(d), which the test doesn't linked with. + */ +#undef _HAS_EXCEPTIONS +#define _HAS_EXCEPTIONS _CPPUNWIND +#endif +// to use strdup w/o warnings +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif // _WIN32 || _WIN64 + +#define _ISOC11_SOURCE 1 // to get C11 declarations for GLIBC +#define HARNESS_NO_PARSE_COMMAND_LINE 1 + +#include "harness_allocator_overload.h" + +#if MALLOC_WINDOWS_OVERLOAD_ENABLED +#include "tbb/tbbmalloc_proxy.h" +#endif + +#include "harness.h" + +#if !HARNESS_SKIP_TEST + +#if __ANDROID__ + #include <android/api-level.h> // for __ANDROID_API__ +#endif + +#define __TBB_POSIX_MEMALIGN_PRESENT (__linux__ && !__ANDROID__) || __APPLE__ +#define __TBB_PVALLOC_PRESENT __linux__ && !__ANDROID__ +#if __GLIBC__ + // aligned_alloc available since GLIBC 2.16 + #define __TBB_ALIGNED_ALLOC_PRESENT __GLIBC_PREREQ(2, 16) +#endif // __GLIBC__ + // later Android doesn't have valloc or dlmalloc_usable_size +#define __TBB_VALLOC_PRESENT (__linux__ && __ANDROID_API__<21) || __APPLE__ +#define __TBB_DLMALLOC_USABLE_SIZE_PRESENT __ANDROID__ && __ANDROID_API__<21 + +#include "harness_report.h" +#include "harness_assert.h" +#include <stdlib.h> +#include <string.h> +#if !__APPLE__ +#include <malloc.h> +#endif +#include <stdio.h> +#include <new> +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED +#include <unistd.h> // for sysconf +#include <dlfcn.h> +#endif + +#if __linux__ +#include <stdint.h> // for uintptr_t + +extern "C" { +void *__libc_malloc(size_t size); +void *__libc_realloc(void *ptr, size_t size); +void *__libc_calloc(size_t num, size_t size); +void __libc_free(void *ptr); +void *__libc_memalign(size_t alignment, size_t size); +void *__libc_pvalloc(size_t size); +void *__libc_valloc(size_t size); +#if __TBB_DLMALLOC_USABLE_SIZE_PRESENT +#define malloc_usable_size(p) dlmalloc_usable_size(p) +size_t dlmalloc_usable_size(const void *ptr); +#endif +} + +#elif __APPLE__ + +#include <malloc/malloc.h> +#define malloc_usable_size(p) malloc_size(p) + +#elif _WIN32 +#include <stddef.h> +#if __MINGW32__ +#include <unistd.h> +#else +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +#endif + +#endif /* OS selection */ + +#if _WIN32 +// On Windows, the trick with string "dependency on msvcpXX.dll" is necessary to create +// dependency on msvcpXX.dll, for sake of a regression test. +// On Linux, C++ RTL headers are undesirable because of breaking strict ANSI mode. +#if defined(_MSC_VER) && _MSC_VER >= 1300 && _MSC_VER <= 1310 && !defined(__INTEL_COMPILER) +/* Fixing compilation error reported by VS2003 for exception class + when _HAS_EXCEPTIONS is 0: + bad_cast that inherited from exception is not in std namespace. +*/ +using namespace std; +#endif +#include <string> +#include <set> +#include <sstream> +#endif + +#include "../tbbmalloc/shared_utils.h" // alignDown, alignUp, estimatedCacheLineSize + +/* start of code replicated from src/tbbmalloc */ + +class BackRefIdx { // composite index to backreference array +private: + uint16_t master; // index in BackRefMaster + uint16_t largeObj:1; // is this object "large"? + uint16_t offset :15; // offset from beginning of BackRefBlock +public: + BackRefIdx() : master((uint16_t)-1) {} + bool isInvalid() { return master == (uint16_t)-1; } + bool isLargeObject() const { return largeObj; } + uint16_t getMaster() const { return master; } + uint16_t getOffset() const { return offset; } + + // only newBackRef can modify BackRefIdx + static BackRefIdx newBackRef(bool largeObj); +}; + +class MemoryPool; +class ExtMemoryPool; + +struct BlockI { + intptr_t blockState[2]; +}; + +struct LargeMemoryBlock : public BlockI { + MemoryPool *pool; // owner pool + LargeMemoryBlock *next, // ptrs in list of cached blocks + *prev, + *gPrev, // in pool's global list + *gNext; + uintptr_t age; // age of block while in cache + size_t objectSize; // the size requested by a client + size_t unalignedSize; // the size requested from getMemory + bool fromMapMemory; + BackRefIdx backRefIdx; // cached here, used copy is in LargeObjectHdr + void registerInPool(ExtMemoryPool *extMemPool); + void unregisterFromPool(ExtMemoryPool *extMemPool); +}; + +struct LargeObjectHdr { + LargeMemoryBlock *memoryBlock; + /* Have to duplicate it here from CachedObjectHdr, + as backreference must be checked without further pointer dereference. + Points to LargeObjectHdr. */ + BackRefIdx backRefIdx; +}; + +/* + * Objects of size minLargeObjectSize and larger are considered large objects. + */ +const uintptr_t blockSize = 16*1024; +const uint32_t fittingAlignment = rml::internal::estimatedCacheLineSize; +#define SET_FITTING_SIZE(N) ( (blockSize-2*rml::internal::estimatedCacheLineSize)/N ) & ~(fittingAlignment-1) +const uint32_t fittingSize5 = SET_FITTING_SIZE(2); // 8128/8064 +#undef SET_FITTING_SIZE +const uint32_t minLargeObjectSize = fittingSize5 + 1; + +/* end of code replicated from src/tbbmalloc */ + +static void scalableMallocCheckSize(void *object, size_t size) +{ +#if __clang__ +// This prevents Clang from throwing out the calls to new & delete in CheckNewDeleteOverload(). + static void *v = object; + Harness::suppress_unused_warning(v); +#endif + ASSERT(object, NULL); + if (size >= minLargeObjectSize) { + LargeMemoryBlock *lmb = ((LargeObjectHdr*)object-1)->memoryBlock; + ASSERT(uintptr_t(lmb)<uintptr_t(((LargeObjectHdr*)object-1)) + && lmb->objectSize >= size, NULL); + } +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED + ASSERT(malloc_usable_size(object) >= size, NULL); +#elif MALLOC_WINDOWS_OVERLOAD_ENABLED + // Check that _msize works correctly + ASSERT(_msize(object) >= size, NULL); + ASSERT(size<8 || _aligned_msize(object,8,0) >= size, NULL); +#endif +} + +void CheckStdFuncOverload(void *(*malloc_p)(size_t), void *(*calloc_p)(size_t, size_t), + void *(*realloc_p)(void *, size_t), void (*free_p)(void *)) +{ + void *ptr = malloc_p(minLargeObjectSize); + scalableMallocCheckSize(ptr, minLargeObjectSize); + free(ptr); + + ptr = calloc_p(minLargeObjectSize, 2); + scalableMallocCheckSize(ptr, 2*minLargeObjectSize); + void *ptr1 = realloc_p(ptr, 10*minLargeObjectSize); + scalableMallocCheckSize(ptr1, 10*minLargeObjectSize); + free_p(ptr1); +} + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED + +void CheckMemalignFuncOverload(void *(*memalign_p)(size_t, size_t), + void (*free_p)(void*)) +{ + void *ptr = memalign_p(128, 4*minLargeObjectSize); + scalableMallocCheckSize(ptr, 4*minLargeObjectSize); + ASSERT(is_aligned(ptr, 128), NULL); + free_p(ptr); +} + +void CheckVallocFuncOverload(void *(*valloc_p)(size_t), void (*free_p)(void*)) +{ + void *ptr = valloc_p(minLargeObjectSize); + scalableMallocCheckSize(ptr, minLargeObjectSize); + ASSERT(is_aligned(ptr, sysconf(_SC_PAGESIZE)), NULL); + free_p(ptr); +} + +void CheckPvalloc(void *(*pvalloc_p)(size_t), void (*free_p)(void*)) +{ + const long memoryPageSize = sysconf(_SC_PAGESIZE); + // request large object with not power-of-2 size + const size_t largeSz = alignUp(minLargeObjectSize, 16*1024) + 1; + + for (size_t sz = 0; sz<=largeSz; sz+=largeSz) { + void *ptr = pvalloc_p(sz); + scalableMallocCheckSize(ptr, sz? alignUp(sz, memoryPageSize) : memoryPageSize); + ASSERT(is_aligned(ptr, memoryPageSize), NULL); + free_p(ptr); + } +} + +#endif // MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED + +// regression test: on macOS scalable_free() treated small aligned object, +// placed in large block, as small block +void CheckFreeAligned() { + size_t sz[] = {8, 4*1024, 16*1024, 0}; + size_t align[] = {8, 4*1024, 16*1024, 0}; + + for (int s=0; sz[s]; s++) + for (int a=0; align[a]; a++) { + void *ptr = NULL; +#if __TBB_POSIX_MEMALIGN_PRESENT + int ret = posix_memalign(&ptr, align[a], sz[s]); + ASSERT(!ret, NULL); +#elif MALLOC_WINDOWS_OVERLOAD_ENABLED + ptr = _aligned_malloc(sz[s], align[a]); +#endif + ASSERT(is_aligned(ptr, align[a]), NULL); + free(ptr); + } +} + +#if __ANDROID__ +// Workaround for an issue with strdup somehow bypassing our malloc replacement on Android. +char *strdup(const char *str) { + REPORT( "Known issue: malloc replacement does not work for strdup on Android.\n" ); + size_t len = strlen(str)+1; + void *new_str = malloc(len); + return new_str ? reinterpret_cast<char *>(memcpy(new_str, str, len)) : 0; +} +#endif + +#if __APPLE__ +#include <mach/mach.h> + +// regression test: malloc_usable_size() that was passed to zone interface +// called system malloc_usable_size(), so for object that was not allocated +// by tbbmalloc non-zero was returned, so such objects were passed to +// tbbmalloc's free(), that is incorrect +void TestZoneOverload() { + vm_address_t *zones; + unsigned zones_num; + + kern_return_t ret = malloc_get_all_zones(mach_task_self(), NULL, &zones, &zones_num); + ASSERT(!ret && zones_num>1, NULL); + malloc_zone_t *sys_zone = (malloc_zone_t*)zones[1]; + ASSERT(strcmp("tbbmalloc", malloc_get_zone_name(sys_zone)), + "zone 1 expected to be not tbbmalloc"); + void *p = malloc_zone_malloc(sys_zone, 16); + free(p); +} +#else +#define TestZoneOverload() +#endif + +#if _WIN32 +// regression test: certain MSVC runtime functions use "public" allocation functions +// but internal free routines, causing crashes if tbbmalloc_proxy does not intercept the latter. +void TestRuntimeRoutines() { + system("rem should be a safe command to call"); +} +#else +#define TestRuntimeRoutines() +#endif + +struct BigStruct { + char f[minLargeObjectSize]; +}; + +void CheckNewDeleteOverload() { + BigStruct *s1, *s2, *s3, *s4; + + s1 = new BigStruct; + scalableMallocCheckSize(s1, sizeof(BigStruct)); + delete s1; + + s2 = new BigStruct[10]; + scalableMallocCheckSize(s2, 10*sizeof(BigStruct)); + delete []s2; + + s3 = new(std::nothrow) BigStruct; + scalableMallocCheckSize(s3, sizeof(BigStruct)); + delete s3; + + s4 = new(std::nothrow) BigStruct[2]; + scalableMallocCheckSize(s4, 2*sizeof(BigStruct)); + delete []s4; +} + +#if MALLOC_WINDOWS_OVERLOAD_ENABLED +void FuncReplacementInfoCheck() { + char **func_replacement_log; + int func_replacement_status = TBB_malloc_replacement_log(&func_replacement_log); + + std::set<std::string> functions; + functions.insert("free"); + functions.insert("_msize"); + functions.insert("_aligned_free"); + functions.insert("_aligned_msize"); + + int status_check = 0; + for (char** log_string = func_replacement_log; *log_string != 0; log_string++) { + std::stringstream s(*log_string); + std::string status, function_name; + s >> status >> function_name; + + if (status.find("Fail:") != status.npos) { + status_check = -1; + } + + functions.erase(function_name); + } + + ASSERT(functions.empty(), "Changed opcodes log must contain all required functions with \"Success\" changed status"); + ASSERT(func_replacement_status == status_check, "replacement_opcodes_log() function return wrong status"); + + func_replacement_status = TBB_malloc_replacement_log(NULL); + ASSERT(func_replacement_status == status_check, "replacement_opcodes_log() function return wrong status"); + + ASSERT_WARNING(func_replacement_status == 0, "Some standard allocation functions was not replaced to tbb_malloc functions."); +} +#endif // MALLOC_WINDOWS_OVERLOAD_ENABLED + +int TestMain() { + void *ptr = NULL; + +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED + ASSERT(dlsym(RTLD_DEFAULT, "scalable_malloc"), + "Lost dependency on malloc_proxy or LD_PRELOAD was not set?"); +#endif + +/* On Windows, memory block size returned by _msize() is sometimes used + to calculate the size for an extended block. Substituting _msize, + scalable_msize initially returned 0 for regions not allocated by the scalable + allocator, which led to incorrect memory reallocation and subsequent crashes. + It was found that adding a new environment variable triggers the error. +*/ + ASSERT(getenv("PATH"), "We assume that PATH is set everywhere."); + char *pathCopy = strdup(getenv("PATH")); +#if __ANDROID__ + ASSERT(strcmp(pathCopy,getenv("PATH")) == 0, "strdup workaround does not work as expected."); +#endif + const char *newEnvName = "__TBBMALLOC_OVERLOAD_REGRESSION_TEST_FOR_REALLOC_AND_MSIZE"; + ASSERT(!getenv(newEnvName), "Environment variable should not be used before."); + int r = Harness::SetEnv(newEnvName,"1"); + ASSERT(!r, NULL); + char *path = getenv("PATH"); + ASSERT(path && 0==strcmp(path, pathCopy), "Environment was changed erroneously."); + free(pathCopy); + + CheckStdFuncOverload(malloc, calloc, realloc, free); +#if MALLOC_UNIXLIKE_OVERLOAD_ENABLED || MALLOC_ZONE_OVERLOAD_ENABLED + +#if __TBB_POSIX_MEMALIGN_PRESENT + int ret = posix_memalign(&ptr, 1024, 3*minLargeObjectSize); + ASSERT(0 == ret, NULL); + scalableMallocCheckSize(ptr, 3*minLargeObjectSize); + ASSERT(is_aligned(ptr, 1024), NULL); + free(ptr); +#endif + +#if __TBB_VALLOC_PRESENT + CheckVallocFuncOverload(valloc, free); +#endif +#if __TBB_PVALLOC_PRESENT + CheckPvalloc(pvalloc, free); +#endif +#if __linux__ + CheckMemalignFuncOverload(memalign, free); +#if __TBB_ALIGNED_ALLOC_PRESENT + CheckMemalignFuncOverload(aligned_alloc, free); +#endif + + struct mallinfo info = mallinfo(); + // right now mallinfo initialized by zero + ASSERT(!info.arena && !info.ordblks && !info.smblks && !info.hblks + && !info.hblkhd && !info.usmblks && !info.fsmblks + && !info.uordblks && !info.fordblks && !info.keepcost, NULL); + + #if !__ANDROID__ + // These non-standard functions are exported by GLIBC, and might be used + // in conjunction with standard malloc/free. Test that we overload them as well. + // Bionic doesn't have them. + CheckStdFuncOverload(__libc_malloc, __libc_calloc, __libc_realloc, __libc_free); + CheckMemalignFuncOverload(__libc_memalign, __libc_free); + CheckVallocFuncOverload(__libc_valloc, __libc_free); + CheckPvalloc(__libc_pvalloc, __libc_free); + #endif +#endif // __linux__ + +#else // MALLOC_WINDOWS_OVERLOAD_ENABLED + + ptr = _aligned_malloc(minLargeObjectSize, 16); + scalableMallocCheckSize(ptr, minLargeObjectSize); + ASSERT(is_aligned(ptr, 16), NULL); + + // Testing of workaround for vs "is power of 2 pow N" bug that accepts zeros + void* ptr1 = _aligned_malloc(minLargeObjectSize, 0); + scalableMallocCheckSize(ptr, minLargeObjectSize); + ASSERT(is_aligned(ptr, sizeof(void*)), NULL); + _aligned_free(ptr1); + + ptr1 = _aligned_realloc(ptr, minLargeObjectSize*10, 16); + scalableMallocCheckSize(ptr1, minLargeObjectSize*10); + ASSERT(is_aligned(ptr, 16), NULL); + _aligned_free(ptr1); + + FuncReplacementInfoCheck(); + +#endif + CheckFreeAligned(); + + CheckNewDeleteOverload(); + +#if _WIN32 + std::string stdstring = "dependency on msvcpXX.dll"; + ASSERT(strcmp(stdstring.c_str(), "dependency on msvcpXX.dll") == 0, NULL); +#endif + TestZoneOverload(); + TestRuntimeRoutines(); + + return Harness::Done; +} +#endif // !HARNESS_SKIP_TEST diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_overload_disable.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_overload_disable.cpp new file mode 100644 index 00000000..8497e891 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_overload_disable.cpp @@ -0,0 +1,69 @@ +/* + Copyright (c) 2018-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_allocator_overload.h" +#include "harness.h" + +// Disabling malloc proxy via env variable is available only on Windows for now +#if MALLOC_WINDOWS_OVERLOAD_ENABLED + +#define TEST_SYSTEM_COMMAND "test_malloc_overload_disable.exe" + +#include "tbb/tbbmalloc_proxy.h" +#include "../tbb/tbb_environment.h" + +const size_t SmallObjectSize = 16; +const size_t LargeObjectSize = 2*8*1024; +const size_t HugeObjectSize = 2*1024*1024; + +void CheckWindowsProxyDisablingViaMemSize( size_t ObjectSize ) { + void* ptr = malloc(ObjectSize); + /* + * If msize returns 0 - tbbmalloc doesn't contain this object in it`s memory + * Also msize check that proxy lib is linked + */ + ASSERT(!__TBB_malloc_safer_msize(ptr,NULL), "Malloc replacement is not deactivated"); + free(ptr); + +} + +int TestMain() { + if (!tbb::internal::GetBoolEnvironmentVariable("TBB_MALLOC_DISABLE_REPLACEMENT")) + { + Harness::SetEnv("TBB_MALLOC_DISABLE_REPLACEMENT","1"); + if ((system(TEST_SYSTEM_COMMAND)) != 0) { + REPORT("Test error: unable to run the command: %s", TEST_SYSTEM_COMMAND); + exit(-1); + } + // We must execute exit(0) to avoid duplicate "Done" printing. + exit(0); + } + else + { + // Check SMALL objects replacement disable + CheckWindowsProxyDisablingViaMemSize(SmallObjectSize); + // Check LARGE objects replacement disable + CheckWindowsProxyDisablingViaMemSize(LargeObjectSize); + // Check HUGE objects replacement disable + CheckWindowsProxyDisablingViaMemSize(HugeObjectSize); + } + return Harness::Done; +} +#else // MALLOC_WINDOWS_OVERLOAD_ENABLED +int TestMain() { + return Harness::Skipped; +} +#endif // MALLOC_WINDOWS_OVERLOAD_ENABLED diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_pools.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_pools.cpp new file mode 100644 index 00000000..abacce3d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_pools.cpp @@ -0,0 +1,883 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/scalable_allocator.h" +#include "tbb/atomic.h" +#define HARNESS_TBBMALLOC_THREAD_SHUTDOWN 1 +#include "harness.h" +#include "harness_barrier.h" +#include "harness_tls.h" +#if !__TBB_SOURCE_DIRECTLY_INCLUDED +#include "harness_tbb_independence.h" +#endif + +template<typename T> +static inline T alignUp (T arg, uintptr_t alignment) { + return T(((uintptr_t)arg+(alignment-1)) & ~(alignment-1)); +} + +struct PoolSpace: NoCopy { + size_t pos; + int regions; + size_t bufSize; + char *space; + + static const size_t BUF_SIZE = 8*1024*1024; + + PoolSpace(size_t bufSz = BUF_SIZE) : + pos(0), regions(0), + bufSize(bufSz), space(new char[bufSize]) { + memset(space, 0, bufSize); + } + ~PoolSpace() { + delete []space; + } +}; + +static PoolSpace *poolSpace; + +struct MallocPoolHeader { + void *rawPtr; + size_t userSize; +}; + +static tbb::atomic<int> liveRegions; + +static void *getMallocMem(intptr_t /*pool_id*/, size_t &bytes) +{ + void *rawPtr = malloc(bytes+sizeof(MallocPoolHeader)+1); + if (!rawPtr) + return NULL; + // +1 to check working with unaligned space + void *ret = (void *)((uintptr_t)rawPtr+sizeof(MallocPoolHeader)+1); + + MallocPoolHeader *hdr = (MallocPoolHeader*)ret-1; + hdr->rawPtr = rawPtr; + hdr->userSize = bytes; + + liveRegions++; + + return ret; +} + +static int putMallocMem(intptr_t /*pool_id*/, void *ptr, size_t bytes) +{ + MallocPoolHeader *hdr = (MallocPoolHeader*)ptr-1; + ASSERT(bytes == hdr->userSize, "Invalid size in pool callback."); + free(hdr->rawPtr); + + liveRegions--; + + return 0; +} + +void TestPoolReset() +{ + rml::MemPoolPolicy pol(getMallocMem, putMallocMem); + rml::MemoryPool *pool; + + pool_create_v1(0, &pol, &pool); + for (int i=0; i<100; i++) { + ASSERT(pool_malloc(pool, 8), NULL); + ASSERT(pool_malloc(pool, 50*1024), NULL); + } + int regionsBeforeReset = liveRegions; + bool ok = pool_reset(pool); + ASSERT(ok, NULL); + for (int i=0; i<100; i++) { + ASSERT(pool_malloc(pool, 8), NULL); + ASSERT(pool_malloc(pool, 50*1024), NULL); + } + ASSERT(regionsBeforeReset == liveRegions, + "Expected no new regions allocation."); + ok = pool_destroy(pool); + ASSERT(ok, NULL); + ASSERT(!liveRegions, "Expected all regions were released."); +} + +class SharedPoolRun: NoAssign { + static long threadNum; + static Harness::SpinBarrier startB, + mallocDone; + static rml::MemoryPool *pool; + static void **crossThread, + **afterTerm; +public: + static const int OBJ_CNT = 100; + + static void init(int num, rml::MemoryPool *pl, void **crThread, void **aTerm) { + threadNum = num; + pool = pl; + crossThread = crThread; + afterTerm = aTerm; + startB.initialize(threadNum); + mallocDone.initialize(threadNum); + } + + void operator()( int id ) const { + const int ITERS = 1000; + void *local[ITERS]; + + startB.wait(); + for (int i=id*OBJ_CNT; i<(id+1)*OBJ_CNT; i++) { + afterTerm[i] = pool_malloc(pool, i%2? 8*1024 : 9*1024); + memset(afterTerm[i], i, i%2? 8*1024 : 9*1024); + crossThread[i] = pool_malloc(pool, i%2? 9*1024 : 8*1024); + memset(crossThread[i], i, i%2? 9*1024 : 8*1024); + } + + for (int i=1; i<ITERS; i+=2) { + local[i-1] = pool_malloc(pool, 6*1024); + memset(local[i-1], i, 6*1024); + local[i] = pool_malloc(pool, 16*1024); + memset(local[i], i, 16*1024); + } + mallocDone.wait(); + int myVictim = threadNum-id-1; + for (int i=myVictim*OBJ_CNT; i<(myVictim+1)*OBJ_CNT; i++) + pool_free(pool, crossThread[i]); + for (int i=0; i<ITERS; i++) + pool_free(pool, local[i]); + } +}; + +long SharedPoolRun::threadNum; +Harness::SpinBarrier SharedPoolRun::startB, + SharedPoolRun::mallocDone; +rml::MemoryPool *SharedPoolRun::pool; +void **SharedPoolRun::crossThread, + **SharedPoolRun::afterTerm; + +// single pool shared by different threads +void TestSharedPool() +{ + rml::MemPoolPolicy pol(getMallocMem, putMallocMem); + rml::MemoryPool *pool; + + pool_create_v1(0, &pol, &pool); + void **crossThread = new void*[MaxThread * SharedPoolRun::OBJ_CNT]; + void **afterTerm = new void*[MaxThread * SharedPoolRun::OBJ_CNT]; + + for (int p=MinThread; p<=MaxThread; p++) { + SharedPoolRun::init(p, pool, crossThread, afterTerm); + SharedPoolRun thr; + + void *hugeObj = pool_malloc(pool, 10*1024*1024); + ASSERT(hugeObj, NULL); + + NativeParallelFor( p, thr ); + + pool_free(pool, hugeObj); + for (int i=0; i<p*SharedPoolRun::OBJ_CNT; i++) + pool_free(pool, afterTerm[i]); + } + delete []afterTerm; + delete []crossThread; + + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + ASSERT(!liveRegions, "Expected all regions were released."); +} + +void *CrossThreadGetMem(intptr_t pool_id, size_t &bytes) +{ + if (poolSpace[pool_id].pos + bytes > poolSpace[pool_id].bufSize) + return NULL; + + void *ret = poolSpace[pool_id].space + poolSpace[pool_id].pos; + poolSpace[pool_id].pos += bytes; + poolSpace[pool_id].regions++; + + return ret; +} + +int CrossThreadPutMem(intptr_t pool_id, void* /*raw_ptr*/, size_t /*raw_bytes*/) +{ + poolSpace[pool_id].regions--; + return 0; +} + +class CrossThreadRun: NoAssign { + static long number_of_threads; + static Harness::SpinBarrier barrier; + static rml::MemoryPool **pool; + static char **obj; +public: + static void initBarrier(unsigned thrds) { barrier.initialize(thrds); } + static void init(long num) { + number_of_threads = num; + pool = new rml::MemoryPool*[number_of_threads]; + poolSpace = new PoolSpace[number_of_threads]; + obj = new char*[number_of_threads]; + } + static void destroy() { + for (long i=0; i<number_of_threads; i++) + ASSERT(!poolSpace[i].regions, "Memory leak detected"); + delete []pool; + delete []poolSpace; + delete []obj; + } + CrossThreadRun() {} + void operator()( int id ) const { + rml::MemPoolPolicy pol(CrossThreadGetMem, CrossThreadPutMem); + const int objLen = 10*id; + + pool_create_v1(id, &pol, &pool[id]); + obj[id] = (char*)pool_malloc(pool[id], objLen); + ASSERT(obj[id], NULL); + memset(obj[id], id, objLen); + + { + const size_t lrgSz = 2*16*1024; + void *ptrLarge = pool_malloc(pool[id], lrgSz); + ASSERT(ptrLarge, NULL); + memset(ptrLarge, 1, lrgSz); + // consume all small objects + while (pool_malloc(pool[id], 5 * 1024)); + // releasing of large object will not give a chance to allocate more + // since only fixed pool can look at other bins aligned/notAligned + pool_free(pool[id], ptrLarge); + ASSERT(!pool_malloc(pool[id], 5*1024), NULL); + } + + barrier.wait(); + int myPool = number_of_threads-id-1; + for (int i=0; i<10*myPool; i++) + ASSERT(myPool==obj[myPool][i], NULL); + pool_free(pool[myPool], obj[myPool]); + bool ok = pool_destroy(pool[myPool]); + ASSERT(ok, NULL); + } +}; + +long CrossThreadRun::number_of_threads; +Harness::SpinBarrier CrossThreadRun::barrier; +rml::MemoryPool **CrossThreadRun::pool; +char **CrossThreadRun::obj; + +// pools created, used and destroyed by different threads +void TestCrossThreadPools() +{ + for (int p=MinThread; p<=MaxThread; p++) { + CrossThreadRun::initBarrier(p); + CrossThreadRun::init(p); + NativeParallelFor( p, CrossThreadRun() ); + for (int i=0; i<p; i++) + ASSERT(!poolSpace[i].regions, "Region leak detected"); + CrossThreadRun::destroy(); + } +} + +// buffer is too small to pool be created, but must not leak resources +void TestTooSmallBuffer() +{ + poolSpace = new PoolSpace(8*1024); + + rml::MemPoolPolicy pol(CrossThreadGetMem, CrossThreadPutMem); + rml::MemoryPool *pool; + pool_create_v1(0, &pol, &pool); + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + ASSERT(!poolSpace[0].regions, "No leaks."); + + delete poolSpace; +} + +class FixedPoolHeadBase : NoAssign { + size_t size; + intptr_t used; + char *data; +public: + FixedPoolHeadBase(size_t s) : size(s), used(false) { + data = new char[size]; + } + void *useData(size_t &bytes) { + intptr_t wasUsed = __TBB_FetchAndStoreW(&used, true); + ASSERT(!wasUsed, "The buffer must not be used twice."); + bytes = size; + return data; + } + ~FixedPoolHeadBase() { + delete []data; + } +}; + +template<size_t SIZE> +class FixedPoolHead : FixedPoolHeadBase { +public: + FixedPoolHead() : FixedPoolHeadBase(SIZE) { } +}; + +static void *fixedBufGetMem(intptr_t pool_id, size_t &bytes) +{ + return ((FixedPoolHeadBase*)pool_id)->useData(bytes); +} + +class FixedPoolUse: NoAssign { + static Harness::SpinBarrier startB; + rml::MemoryPool *pool; + size_t reqSize; + int iters; +public: + FixedPoolUse(unsigned threads, rml::MemoryPool *p, size_t sz, int it) : + pool(p), reqSize(sz), iters(it) { + startB.initialize(threads); + } + void operator()( int /*id*/ ) const { + startB.wait(); + for (int i=0; i<iters; i++) { + void *o = pool_malloc(pool, reqSize); + ASSERT(o, NULL); + pool_free(pool, o); + } + } +}; + +Harness::SpinBarrier FixedPoolUse::startB; + +class FixedPoolNomem: NoAssign { + Harness::SpinBarrier *startB; + rml::MemoryPool *pool; +public: + FixedPoolNomem(Harness::SpinBarrier *b, rml::MemoryPool *p) : + startB(b), pool(p) {} + void operator()(int id) const { + startB->wait(); + void *o = pool_malloc(pool, id%2? 64 : 128*1024); + ASSERT(!o, "All memory must be consumed."); + } +}; + +class FixedPoolSomeMem: NoAssign { + Harness::SpinBarrier *barrier; + rml::MemoryPool *pool; +public: + FixedPoolSomeMem(Harness::SpinBarrier *b, rml::MemoryPool *p) : + barrier(b), pool(p) {} + void operator()(int id) const { + barrier->wait(); + Harness::Sleep(2*id); + void *o = pool_malloc(pool, id%2? 64 : 128*1024); + barrier->wait(); + pool_free(pool, o); + } +}; + +bool haveEnoughSpace(rml::MemoryPool *pool, size_t sz) +{ + if (void *p = pool_malloc(pool, sz)) { + pool_free(pool, p); + return true; + } + return false; +} + +void TestFixedBufferPool() +{ + const int ITERS = 7; + const size_t MAX_OBJECT = 7*1024*1024; + void *ptrs[ITERS]; + rml::MemPoolPolicy pol(fixedBufGetMem, NULL, 0, /*fixedSizePool=*/true, + /*keepMemTillDestroy=*/false); + rml::MemoryPool *pool; + { + FixedPoolHead<MAX_OBJECT + 1024*1024> head; + + pool_create_v1((intptr_t)&head, &pol, &pool); + { + NativeParallelFor( 1, FixedPoolUse(1, pool, MAX_OBJECT, 2) ); + + for (int i=0; i<ITERS; i++) { + ptrs[i] = pool_malloc(pool, MAX_OBJECT/ITERS); + ASSERT(ptrs[i], NULL); + } + for (int i=0; i<ITERS; i++) + pool_free(pool, ptrs[i]); + + NativeParallelFor( 1, FixedPoolUse(1, pool, MAX_OBJECT, 1) ); + } + // each thread asks for an MAX_OBJECT/p/2 object, + // /2 is to cover fragmentation + for (int p=MinThread; p<=MaxThread; p++) + NativeParallelFor( p, FixedPoolUse(p, pool, MAX_OBJECT/p/2, 10000) ); + { + const int p=128; + NativeParallelFor( p, FixedPoolUse(p, pool, MAX_OBJECT/p/2, 1) ); + } + { + size_t maxSz; + const int p = 512; + Harness::SpinBarrier barrier(p); + + // Find maximal useful object size. Start with MAX_OBJECT/2, + // as the pool might be fragmented by BootStrapBlocks consumed during + // FixedPoolRun. + size_t l, r; + ASSERT(haveEnoughSpace(pool, MAX_OBJECT/2), NULL); + for (l = MAX_OBJECT/2, r = MAX_OBJECT + 1024*1024; l < r-1; ) { + size_t mid = (l+r)/2; + if (haveEnoughSpace(pool, mid)) + l = mid; + else + r = mid; + } + maxSz = l; + ASSERT(!haveEnoughSpace(pool, maxSz+1), "Expect to find boundary value."); + // consume all available memory + void *largeObj = pool_malloc(pool, maxSz); + ASSERT(largeObj, NULL); + void *o = pool_malloc(pool, 64); + if (o) // pool fragmented, skip FixedPoolNomem + pool_free(pool, o); + else + NativeParallelFor( p, FixedPoolNomem(&barrier, pool) ); + pool_free(pool, largeObj); + // keep some space unoccupied + largeObj = pool_malloc(pool, maxSz-512*1024); + ASSERT(largeObj, NULL); + NativeParallelFor( p, FixedPoolSomeMem(&barrier, pool) ); + pool_free(pool, largeObj); + } + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + } + // check that fresh untouched pool can successfully fulfil requests from 128 threads + { + FixedPoolHead<MAX_OBJECT + 1024*1024> head; + pool_create_v1((intptr_t)&head, &pol, &pool); + int p=128; + NativeParallelFor( p, FixedPoolUse(p, pool, MAX_OBJECT/p/2, 1) ); + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + } +} + +static size_t currGranularity; + +static void *getGranMem(intptr_t /*pool_id*/, size_t &bytes) +{ + ASSERT(!(bytes%currGranularity), "Region size mismatch granularity."); + return malloc(bytes); +} + +static int putGranMem(intptr_t /*pool_id*/, void *ptr, size_t bytes) +{ + ASSERT(!(bytes%currGranularity), "Region size mismatch granularity."); + free(ptr); + return 0; +} + +void TestPoolGranularity() +{ + rml::MemPoolPolicy pol(getGranMem, putGranMem); + const size_t grans[] = {4*1024, 2*1024*1024, 6*1024*1024, 10*1024*1024}; + + for (unsigned i=0; i<sizeof(grans)/sizeof(grans[0]); i++) { + pol.granularity = currGranularity = grans[i]; + rml::MemoryPool *pool; + + pool_create_v1(0, &pol, &pool); + for (int sz=500*1024; sz<16*1024*1024; sz+=101*1024) { + void *p = pool_malloc(pool, sz); + ASSERT(p, "Can't allocate memory in pool."); + pool_free(pool, p); + } + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + } +} + +static size_t putMemAll, getMemAll, getMemSuccessful; + +static void *getMemMalloc(intptr_t /*pool_id*/, size_t &bytes) +{ + getMemAll++; + void *p = malloc(bytes); + if (p) + getMemSuccessful++; + return p; +} + +static int putMemFree(intptr_t /*pool_id*/, void *ptr, size_t /*bytes*/) +{ + putMemAll++; + free(ptr); + return 0; +} + +void TestPoolKeepTillDestroy() +{ + const int ITERS = 50*1024; + void *ptrs[2*ITERS+1]; + rml::MemPoolPolicy pol(getMemMalloc, putMemFree); + rml::MemoryPool *pool; + + // 1st create default pool that returns memory back to callback, + // then use keepMemTillDestroy policy + for (int keep=0; keep<2; keep++) { + getMemAll = putMemAll = 0; + if (keep) + pol.keepAllMemory = 1; + pool_create_v1(0, &pol, &pool); + for (int i=0; i<2*ITERS; i+=2) { + ptrs[i] = pool_malloc(pool, 7*1024); + ptrs[i+1] = pool_malloc(pool, 10*1024); + } + ptrs[2*ITERS] = pool_malloc(pool, 8*1024*1024); + ASSERT(!putMemAll, NULL); + for (int i=0; i<2*ITERS; i++) + pool_free(pool, ptrs[i]); + pool_free(pool, ptrs[2*ITERS]); + size_t totalPutMemCalls = putMemAll; + if (keep) + ASSERT(!putMemAll, NULL); + else { + ASSERT(putMemAll, NULL); + putMemAll = 0; + } + size_t getCallsBefore = getMemAll; + void *p = pool_malloc(pool, 8*1024*1024); + ASSERT(p, NULL); + if (keep) + ASSERT(getCallsBefore == getMemAll, "Must not lead to new getMem call"); + size_t putCallsBefore = putMemAll; + bool ok = pool_reset(pool); + ASSERT(ok, NULL); + ASSERT(putCallsBefore == putMemAll, "Pool is not releasing memory during reset."); + ok = pool_destroy(pool); + ASSERT(ok, NULL); + ASSERT(putMemAll, NULL); + totalPutMemCalls += putMemAll; + ASSERT(getMemAll == totalPutMemCalls, "Memory leak detected."); + } + +} + +static bool memEqual(char *buf, size_t size, int val) +{ + bool memEq = true; + for (size_t k=0; k<size; k++) + if (buf[k] != val) + memEq = false; + return memEq; +} + +void TestEntries() +{ + const int SZ = 4; + const int ALGN = 4; + size_t size[SZ] = {8, 8000, 9000, 100*1024}; + size_t algn[ALGN] = {8, 64, 4*1024, 8*1024*1024}; + + rml::MemPoolPolicy pol(getGranMem, putGranMem); + currGranularity = 1; // not check granularity in the test + rml::MemoryPool *pool; + + pool_create_v1(0, &pol, &pool); + for (int i=0; i<SZ; i++) + for (int j=0; j<ALGN; j++) { + char *p = (char*)pool_aligned_malloc(pool, size[i], algn[j]); + ASSERT(p && 0==((uintptr_t)p & (algn[j]-1)), NULL); + memset(p, j, size[i]); + + size_t curr_algn = algn[rand() % ALGN]; + size_t curr_sz = size[rand() % SZ]; + char *p1 = (char*)pool_aligned_realloc(pool, p, curr_sz, curr_algn); + ASSERT(p1 && 0==((uintptr_t)p1 & (curr_algn-1)), NULL); + ASSERT(memEqual(p1, min(size[i], curr_sz), j), NULL); + + memset(p1, j+1, curr_sz); + size_t curr_sz1 = size[rand() % SZ]; + char *p2 = (char*)pool_realloc(pool, p1, curr_sz1); + ASSERT(p2, NULL); + ASSERT(memEqual(p2, min(curr_sz1, curr_sz), j+1), NULL); + + pool_free(pool, p2); + } + + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + + bool fail = rml::pool_destroy(NULL); + ASSERT(!fail, NULL); + fail = rml::pool_reset(NULL); + ASSERT(!fail, NULL); +} + +rml::MemoryPool *CreateUsablePool(size_t size) +{ + rml::MemoryPool *pool; + rml::MemPoolPolicy okPolicy(getMemMalloc, putMemFree); + + putMemAll = getMemAll = getMemSuccessful = 0; + rml::MemPoolError res = pool_create_v1(0, &okPolicy, &pool); + if (res != rml::POOL_OK) { + ASSERT(!getMemAll && !putMemAll, "No callbacks after fail."); + return NULL; + } + void *o = pool_malloc(pool, size); + if (!getMemSuccessful) { + // no memory from callback, valid reason to leave + ASSERT(!o, "The pool must be unusable."); + return NULL; + } + ASSERT(o, "Created pool must be useful."); + ASSERT(getMemSuccessful == 1 || getMemSuccessful == 5 || getMemAll > getMemSuccessful, + "Multiple requests are allowed when unsuccessful request occurred or cannot search in bootstrap memory. "); + ASSERT(!putMemAll, NULL); + pool_free(pool, o); + + return pool; +} + +void CheckPoolLeaks(size_t poolsAlwaysAvailable) +{ + const size_t MAX_POOLS = 16*1000; + const int ITERS = 20, CREATED_STABLE = 3; + rml::MemoryPool *pools[MAX_POOLS]; + size_t created, maxCreated = MAX_POOLS; + int maxNotChangedCnt = 0; + + // expecting that for ITERS runs, max number of pools that can be created + // can be stabilized and still stable CREATED_STABLE times + for (int j=0; j<ITERS && maxNotChangedCnt<CREATED_STABLE; j++) { + for (created=0; created<maxCreated; created++) { + rml::MemoryPool *p = CreateUsablePool(1024); + if (!p) + break; + pools[created] = p; + } + ASSERT(created>=poolsAlwaysAvailable, + "Expect that the reasonable number of pools can be always created."); + for (size_t i=0; i<created; i++) { + bool ok = pool_destroy(pools[i]); + ASSERT(ok, NULL); + } + if (created < maxCreated) { + maxCreated = created; + maxNotChangedCnt = 0; + } else + maxNotChangedCnt++; + } + ASSERT(maxNotChangedCnt == CREATED_STABLE, "The number of created pools must be stabilized."); +} + +void TestPoolCreation() +{ + putMemAll = getMemAll = getMemSuccessful = 0; + + rml::MemPoolPolicy nullPolicy(NULL, putMemFree), + emptyFreePolicy(getMemMalloc, NULL), + okPolicy(getMemMalloc, putMemFree); + rml::MemoryPool *pool; + + rml::MemPoolError res = pool_create_v1(0, &nullPolicy, &pool); + ASSERT(res==rml::INVALID_POLICY, "pool with empty pAlloc can't be created"); + res = pool_create_v1(0, &emptyFreePolicy, &pool); + ASSERT(res==rml::INVALID_POLICY, "pool with empty pFree can't be created"); + ASSERT(!putMemAll && !getMemAll, "no callback calls are expected"); + res = pool_create_v1(0, &okPolicy, &pool); + ASSERT(res==rml::POOL_OK, NULL); + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + ASSERT(putMemAll == getMemSuccessful, "no leaks after pool_destroy"); + + // 32 is a guess for a number of pools that is acceptable everywere + CheckPoolLeaks(32); + // try to consume all but 16 TLS keys + LimitTLSKeysTo limitTLSTo(16); + // ...and check that we can create at least 16 pools + CheckPoolLeaks(16); +} + +struct AllocatedObject { + rml::MemoryPool *pool; +}; + +const size_t BUF_SIZE = 1024*1024; + +class PoolIdentityCheck : NoAssign { + rml::MemoryPool** const pools; + AllocatedObject** const objs; +public: + PoolIdentityCheck(rml::MemoryPool** p, AllocatedObject** o) : pools(p), objs(o) {} + void operator()(int id) const { + objs[id] = (AllocatedObject*)pool_malloc(pools[id], BUF_SIZE/2); + ASSERT(objs[id], NULL); + rml::MemoryPool *act_pool = rml::pool_identify(objs[id]); + ASSERT(act_pool == pools[id], NULL); + + for (size_t total=0; total<2*BUF_SIZE; total+=256) { + AllocatedObject *o = (AllocatedObject*)pool_malloc(pools[id], 256); + ASSERT(o, NULL); + act_pool = rml::pool_identify(o); + ASSERT(act_pool == pools[id], NULL); + pool_free(act_pool, o); + } + if( id&1 ) { // make every second returned object "small" + pool_free(act_pool, objs[id]); + objs[id] = (AllocatedObject*)pool_malloc(pools[id], 16); + ASSERT(objs[id], NULL); + } + objs[id]->pool = act_pool; + } +}; + +void TestPoolDetection() +{ + const int POOLS = 4; + rml::MemPoolPolicy pol(fixedBufGetMem, NULL, 0, /*fixedSizePool=*/true, + /*keepMemTillDestroy=*/false); + rml::MemoryPool *pools[POOLS]; + FixedPoolHead<BUF_SIZE*POOLS> head[POOLS]; + AllocatedObject *objs[POOLS]; + + for (int i=0; i<POOLS; i++) + pool_create_v1((intptr_t)(head+i), &pol, &pools[i]); + // if object somehow released to different pools, subsequent allocation + // from affected pools became impossible + for (int k=0; k<10; k++) { + PoolIdentityCheck check(pools, objs); + if( k&1 ) + NativeParallelFor( POOLS, check); + else + for (int i=0; i<POOLS; i++) check(i); + + for (int i=0; i<POOLS; i++) { + rml::MemoryPool *p = rml::pool_identify(objs[i]); + ASSERT(p == objs[i]->pool, NULL); + pool_free(p, objs[i]); + } + } + for (int i=0; i<POOLS; i++) { + bool ok = pool_destroy(pools[i]); + ASSERT(ok, NULL); + } +} + +void TestLazyBootstrap() +{ + rml::MemPoolPolicy pol(getMemMalloc, putMemFree); + const size_t sizes[] = {8, 9*1024, 0}; + + for (int i=0; sizes[i]; i++) { + rml::MemoryPool *pool = CreateUsablePool(sizes[i]); + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + ASSERT(getMemSuccessful == putMemAll, "No leak."); + } +} + +class NoLeakOnDestroyRun: NoAssign { + rml::MemoryPool *pool; + Harness::SpinBarrier *barrier; +public: + NoLeakOnDestroyRun(rml::MemoryPool *p, Harness::SpinBarrier *b) : pool(p), barrier(b) {} + void operator()(int id) const { + void *p = pool_malloc(pool, id%2? 8 : 9000); + ASSERT(p && liveRegions, NULL); + barrier->wait(); + if (!id) { + bool ok = pool_destroy(pool); + ASSERT(ok, NULL); + ASSERT(!liveRegions, "Expected all regions were released."); + } + // other threads must wait till pool destruction, + // to not call thread destruction cleanup before this + barrier->wait(); + } +}; + +void TestNoLeakOnDestroy() +{ + liveRegions = 0; + for (int p=MinThread; p<=MaxThread; p++) { + rml::MemPoolPolicy pol(getMallocMem, putMallocMem); + Harness::SpinBarrier barrier(p); + rml::MemoryPool *pool; + + pool_create_v1(0, &pol, &pool); + NativeParallelFor(p, NoLeakOnDestroyRun(pool, &barrier)); + } +} + + +static int putMallocMemError(intptr_t /*pool_id*/, void *ptr, size_t bytes) +{ + MallocPoolHeader *hdr = (MallocPoolHeader*)ptr-1; + ASSERT(bytes == hdr->userSize, "Invalid size in pool callback."); + free(hdr->rawPtr); + + liveRegions--; + + return -1; +} + +void TestDestroyFailed() +{ + rml::MemPoolPolicy pol(getMallocMem, putMallocMemError); + rml::MemoryPool *pool; + pool_create_v1(0, &pol, &pool); + void *ptr = pool_malloc(pool, 16); + ASSERT(ptr, NULL); + bool fail = pool_destroy(pool); + ASSERT(fail==false, "putMemPolicyError callback returns error, " + "expect pool_destroy() failure"); +} + +void TestPoolMSize() { + rml::MemoryPool *pool = CreateUsablePool(1024); + + const int SZ = 10; + // Original allocation requests, random numbers from small to large + size_t requestedSz[SZ] = {8, 16, 500, 1000, 2000, 4000, 8000, 1024*1024, 4242+4242, 8484+8484}; + + // Unlike large objects, small objects do not store its original size along with the object itself + // On Power architecture TLS bins are divided differently. + size_t allocatedSz[SZ] = +#if __powerpc64__ || __ppc64__ || __bgp__ + {8, 16, 512, 1024, 2688, 5376, 8064, 1024*1024, 4242+4242, 8484+8484}; +#else + {8, 16, 512, 1024, 2688, 4032, 8128, 1024*1024, 4242+4242, 8484+8484}; +#endif + for (int i = 0; i < SZ; i++) { + void* obj = pool_malloc(pool, requestedSz[i]); + size_t objSize = pool_msize(pool, obj); + ASSERT(objSize == allocatedSz[i], "pool_msize returned the wrong value"); + pool_free(pool, obj); + } + bool destroyed = pool_destroy(pool); + ASSERT(destroyed, NULL); +} + +int TestMain () { + TestTooSmallBuffer(); + TestPoolReset(); + TestSharedPool(); + TestCrossThreadPools(); + TestFixedBufferPool(); + TestPoolGranularity(); + TestPoolKeepTillDestroy(); + TestEntries(); + TestPoolCreation(); + TestPoolDetection(); + TestLazyBootstrap(); + TestNoLeakOnDestroy(); + TestDestroyFailed(); + TestPoolMSize(); + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_pure_c.c b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_pure_c.c new file mode 100644 index 00000000..6dcfb937 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_pure_c.c @@ -0,0 +1,128 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifdef __cplusplus +#error For testing purpose, this file should be compiled with a C compiler, not C++ +#endif /*__cplusplus */ + +#include "tbb/scalable_allocator.h" +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> /* for atexit */ + +/* + * The test is to check if the scalable_allocator.h and its functions + * can be used from pure C programs; also some regression checks are done + */ + +#if __linux__ +/* huge pages supported only under Linux so far */ +const int ExpectedResultHugePages = TBBMALLOC_OK; +#else +const int ExpectedResultHugePages = TBBMALLOC_NO_EFFECT; +#endif + +/* bool type definition for C */ +#if (defined(_MSC_VER) && _MSC_VER < 1800) || __sun || __SUNPRO_CC +typedef int bool; +#define false 0 +#define true 1 +#else +#include <stdbool.h> +#endif + +#if __TBB_SOURCE_DIRECTLY_INCLUDED +#include "../tbbmalloc/tbbmalloc_internal_api.h" +#else +#define __TBB_mallocProcessShutdownNotification(bool) +#endif + +/* test that it's possible to call allocation function from atexit + after mallocProcessShutdownNotification() called */ +static void MyExit(void) { + void *p = scalable_malloc(32); + assert(p); + scalable_free(p); + __TBB_mallocProcessShutdownNotification(false); +} + +int main(void) { + size_t i, j; + int curr_mode, res; + void *p1, *p2; + + atexit( MyExit ); + for ( curr_mode = 0; curr_mode<=1; curr_mode++) { + assert(ExpectedResultHugePages == + scalable_allocation_mode(TBBMALLOC_USE_HUGE_PAGES, !curr_mode)); + p1 = scalable_malloc(10*1024*1024); + assert(p1); + assert(ExpectedResultHugePages == + scalable_allocation_mode(TBBMALLOC_USE_HUGE_PAGES, curr_mode)); + scalable_free(p1); + } + /* note that huge pages (if supported) are still enabled at this point */ +#if __TBB_SOURCE_DIRECTLY_INCLUDED + assert(TBBMALLOC_OK == + scalable_allocation_mode(TBBMALLOC_INTERNAL_SOURCE_INCLUDED, 0)); +#endif + + for( i=0; i<=1<<16; ++i) { + p1 = scalable_malloc(i); + if( !p1 ) + printf("Warning: there should be memory but scalable_malloc returned NULL\n"); + scalable_free(p1); + } + p1 = p2 = NULL; + for( i=1024*1024; ; i/=2 ) + { + scalable_free(p1); + p1 = scalable_realloc(p2, i); + p2 = scalable_calloc(i, 32); + if (p2) { + if (i<sizeof(size_t)) { + for (j=0; j<i; j++) + assert(0==*((char*)p2+j)); + } else { + for (j=0; j<i; j+=sizeof(size_t)) + assert(0==*((size_t*)p2+j)); + } + } + scalable_free(p2); + p2 = scalable_malloc(i); + if (i==0) break; + } + for( i=1; i<1024*1024; i*=2 ) + { + scalable_free(p1); + p1 = scalable_realloc(p2, i); + p2 = scalable_malloc(i); + } + scalable_free(p1); + scalable_free(p2); + res = scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, NULL); + assert(res == TBBMALLOC_OK); + res = scalable_allocation_command(TBBMALLOC_CLEAN_THREAD_BUFFERS, NULL); + /* expect all caches cleaned before, so got nothing from CLEAN_THREAD_BUFFERS */ + assert(res == TBBMALLOC_NO_EFFECT); + /* check that invalid param argument give expected result*/ + res = scalable_allocation_command(TBBMALLOC_CLEAN_THREAD_BUFFERS, + (void*)(intptr_t)1); + assert(res == TBBMALLOC_INVALID_PARAM); + __TBB_mallocProcessShutdownNotification(false); + printf("done\n"); + return 0; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_regression.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_regression.cpp new file mode 100644 index 00000000..c880a293 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_regression.cpp @@ -0,0 +1,186 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 + +#include <stdio.h> +#include "tbb/scalable_allocator.h" + +class minimalAllocFree { +public: + void operator()(int size) const { + tbb::scalable_allocator<char> a; + char* str = a.allocate( size ); + a.deallocate( str, size ); + } +}; + +#define HARNESS_TBBMALLOC_THREAD_SHUTDOWN 1 +#include "harness.h" + +template<typename Body, typename Arg> +void RunThread(const Body& body, const Arg& arg) { + NativeParallelForTask<Arg,Body> job(arg, body); + job.start(); + job.wait_to_finish(); +} + +/*--------------------------------------------------------------------*/ +// The regression test against bug #1518 where thread bootstrap allocations "leaked" + +#include "harness_memory.h" + +bool TestBootstrapLeak() { + /* In the bug 1518, each thread leaked ~384 bytes. + Initially, scalable allocator maps 1MB. Thus it is necessary to take out most of this space. + 1MB is chunked into 16K blocks; of those, one block is for thread bootstrap, and one more + should be reserved for the test body. 62 blocks left, each can serve 15 objects of 1024 bytes. + */ + const int alloc_size = 1024; + const int take_out_count = 15*62; + + tbb::scalable_allocator<char> a; + char* array[take_out_count]; + for( int i=0; i<take_out_count; ++i ) + array[i] = a.allocate( alloc_size ); + + RunThread( minimalAllocFree(), alloc_size ); // for threading library to take some memory + size_t memory_in_use = GetMemoryUsage(); + // Wait for memory usage data to "stabilize". The test number (1000) has nothing underneath. + for( int i=0; i<1000; i++) { + if( GetMemoryUsage()!=memory_in_use ) { + memory_in_use = GetMemoryUsage(); + i = -1; + } + } + + ptrdiff_t memory_leak = 0; + // Note that 16K bootstrap memory block is enough to serve 42 threads. + const int num_thread_runs = 200; + for (int run=0; run<3; run++) { + memory_in_use = GetMemoryUsage(); + for( int i=0; i<num_thread_runs; ++i ) + RunThread( minimalAllocFree(), alloc_size ); + + memory_leak = GetMemoryUsage() - memory_in_use; + if (!memory_leak) + break; + } + if( memory_leak>0 ) { // possibly too strong? + REPORT( "Error: memory leak of up to %ld bytes\n", static_cast<long>(memory_leak)); + } + + for( int i=0; i<take_out_count; ++i ) + a.deallocate( array[i], alloc_size ); + + return memory_leak<=0; +} + +/*--------------------------------------------------------------------*/ +// The regression test against a bug with incompatible semantics of msize and realloc + +bool TestReallocMsize(size_t startSz) { + bool passed = true; + + char *buf = (char*)scalable_malloc(startSz); + ASSERT(buf, ""); + size_t realSz = scalable_msize(buf); + ASSERT(realSz>=startSz, "scalable_msize must be not less then allocated size"); + memset(buf, 'a', realSz-1); + buf[realSz-1] = 0; + char *buf1 = (char*)scalable_realloc(buf, 2*realSz); + ASSERT(buf1, ""); + ASSERT(scalable_msize(buf1)>=2*realSz, + "scalable_msize must be not less then allocated size"); + buf1[2*realSz-1] = 0; + if ( strspn(buf1, "a") < realSz-1 ) { + REPORT( "Error: data broken for %d Bytes object.\n", startSz); + passed = false; + } + scalable_free(buf1); + + return passed; +} + +// regression test against incorrect work of msize/realloc +// for aligned objects +void TestAlignedMsize() +{ + const int NUM = 4; + char *p[NUM]; + size_t objSizes[NUM]; + size_t allocSz[] = {4, 8, 512, 2*1024, 4*1024, 8*1024, 16*1024, 0}; + size_t align[] = {8, 512, 2*1024, 4*1024, 8*1024, 16*1024, 0}; + + for (int a=0; align[a]; a++) + for (int s=0; allocSz[s]; s++) { + for (int i=0; i<NUM; i++) { + p[i] = (char*)scalable_aligned_malloc(allocSz[s], align[a]); + ASSERT(is_aligned(p[i], align[a]), NULL); + } + + for (int i=0; i<NUM; i++) { + objSizes[i] = scalable_msize(p[i]); + ASSERT(objSizes[i] >= allocSz[s], + "allocated size must be not less than requested"); + memset(p[i], i, objSizes[i]); + } + for (int i=0; i<NUM; i++) { + for (unsigned j=0; j<objSizes[i]; j++) + ASSERT(((char*)p[i])[j] == i, "Error: data broken"); + } + + for (int i=0; i<NUM; i++) { + p[i] = (char*)scalable_aligned_realloc(p[i], 2*allocSz[s], align[a]); + ASSERT(is_aligned(p[i], align[a]), NULL); + memset((char*)p[i]+allocSz[s], i+1, allocSz[s]); + } + for (int i=0; i<NUM; i++) { + for (unsigned j=0; j<allocSz[s]; j++) + ASSERT(((char*)p[i])[j] == i, "Error: data broken"); + for (size_t j=allocSz[s]; j<2*allocSz[s]; j++) + ASSERT(((char*)p[i])[j] == i+1, "Error: data broken"); + } + for (int i=0; i<NUM; i++) + scalable_free(p[i]); + } +} + +/*--------------------------------------------------------------------*/ +// The main test function + +int TestMain () { + bool passed = true; + // Check whether memory usage data can be obtained; if not, skip test_bootstrap_leak. + if( GetMemoryUsage() ) + passed &= TestBootstrapLeak(); + + // TestReallocMsize runs for each power of 2 and each Fibonacci number below 64K + for (size_t a=1, b=1, sum=1; sum<=64*1024; ) { + passed &= TestReallocMsize(sum); + a = b; + b = sum; + sum = a+b; + } + for (size_t a=2; a<=64*1024; a*=2) + passed &= TestReallocMsize(a); + + ASSERT( passed, "Test failed" ); + + TestAlignedMsize(); + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_shutdown_hang.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_shutdown_hang.cpp new file mode 100644 index 00000000..eb3adb66 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_shutdown_hang.cpp @@ -0,0 +1,125 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_CUSTOM_MAIN 1 +#include "harness.h" + +#include <tbb/task.h> +#include <tbb/scalable_allocator.h> +#include <tbb/task_scheduler_init.h> + +// Lets slow down the main thread on exit +const int MAX_DELAY = 5; +struct GlobalObject { + ~GlobalObject() { + Harness::Sleep(rand( ) % MAX_DELAY); + } +} go; + +void allocatorRandomThrashing() { + const int ARRAY_SIZE = 1000; + const int MAX_ITER = 10000; + const int MAX_ALLOC = 10 * 1024 * 1024; + + void *arr[ARRAY_SIZE] = {0}; + for (int i = 0; i < rand() % MAX_ITER; ++i) { + // Random allocation size for random arrays + for (int j = 0; j < rand() % ARRAY_SIZE; ++j) { + arr[j] = scalable_malloc(rand() % MAX_ALLOC); + } + // Deallocate everything + for (int j = 0; j < ARRAY_SIZE; ++j) { + scalable_free(arr[j]); + arr[j] = NULL; + } + } +} + +struct AllocatorThrashTask : tbb::task { + tbb::task* execute() __TBB_override { + allocatorRandomThrashing(); + return NULL; + } +}; + +void hangOnExitReproducer() { + const int P = tbb::task_scheduler_init::default_num_threads(); + for (int i = 0; i < P-1; i++) { + // Enqueue tasks for workers + tbb::task::enqueue(*new (tbb::task::allocate_root()) AllocatorThrashTask()); + } +} + +#if (_WIN32 || _WIN64) && !__TBB_WIN8UI_SUPPORT +#include <process.h> // _spawnl +void processSpawn(const char* self) { + _spawnl(_P_WAIT, self, self, "1", NULL); +} +#elif __linux__ || __APPLE__ +#include <unistd.h> // fork/exec +#include <sys/wait.h> // waitpid +void processSpawn(const char* self) { + pid_t pid = fork(); + if (pid == -1) { + REPORT("ERROR: fork failed.\n"); + } else if (pid == 0) { // child + execl(self, self, "1", NULL); + REPORT("ERROR: exec never returns\n"); + exit(1); + } else { // parent + int status; + waitpid(pid, &status, 0); + } +} +#else +void processSpawn(const char* /*self*/) { + REPORT("Known issue: no support for process spawn on this platform.\n"); + REPORT("done\n"); + exit(0); +} +#endif + +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (push) +#pragma warning (disable: 4702) /* Unreachable code */ +#endif + +HARNESS_EXPORT +int main(int argc, char* argv[]) { + ParseCommandLine( argc, argv ); + + // Executed from child processes + if (argc == 2 && strcmp(argv[1],"1") == 0) { + hangOnExitReproducer(); + return 0; + } + + // The number of executions is a tradeoff + // between execution time and NBTS statistics + const int EXEC_TIMES = 100; + const char* self = argv[0]; + for (int i = 0; i < EXEC_TIMES; i++) { + processSpawn(self); + } + +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (pop) +#endif + + REPORT("done\n"); + return 0; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_used_by_lib.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_used_by_lib.cpp new file mode 100644 index 00000000..8fba3628 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_used_by_lib.cpp @@ -0,0 +1,167 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _USRDLL + +#include <stdlib.h> +#include "harness_defs.h" +#include "tbb/scalable_allocator.h" +#if __TBB_SOURCE_DIRECTLY_INCLUDED +#include "../tbbmalloc/tbbmalloc_internal_api.h" +#endif + +#define HARNESS_CUSTOM_MAIN 1 +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" +#include "harness_assert.h" + +#if _WIN32||_WIN64 +extern "C" { + extern __declspec(dllexport) void callDll(); +} +#endif + +extern "C" void callDll() +{ + static const int NUM = 20; + void *ptrs[NUM]; + + for (int i=0; i<NUM; i++) { + ptrs[i] = scalable_malloc(i*1024); + ASSERT(ptrs[i], NULL); + } + for (int i=0; i<NUM; i++) + scalable_free(ptrs[i]); +} + +#if __TBB_SOURCE_DIRECTLY_INCLUDED + +struct RegisterProcessShutdownNotification { + ~RegisterProcessShutdownNotification() { + __TBB_mallocProcessShutdownNotification(); + } +}; + +static RegisterProcessShutdownNotification reg; + +#endif + +#else // _USRDLL + +#define __TBB_NO_IMPLICIT_LINKAGE 1 +#include "harness_dynamic_libs.h" +#if __TBB_WIN8UI_SUPPORT +// FIXME: fix the test to support Windows* 8 Store Apps mode. +#define HARNESS_SKIP_TEST 1 +#endif +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" + +#if !HARNESS_SKIP_TEST + +#include "harness_memory.h" +#include "harness_tbb_independence.h" +#include "harness_barrier.h" + +class UseDll { + Harness::FunctionAddress run; +public: + UseDll(Harness::FunctionAddress runPtr) : run(runPtr) { } + void operator()( int /*id*/ ) const { + (*run)(); + } +}; + +void LoadThreadsUnload() +{ + Harness::LIBRARY_HANDLE lib = + Harness::OpenLibrary(TEST_LIBRARY_NAME("test_malloc_used_by_lib_dll")); + ASSERT(lib, "Can't load " TEST_LIBRARY_NAME("test_malloc_used_by_lib_dll")); + NativeParallelFor( 4, UseDll( Harness::GetAddress(lib, "callDll") ) ); + Harness::CloseLibrary(lib); +} + +struct UnloadCallback { + Harness::LIBRARY_HANDLE lib; + + void operator() () const { + Harness::CloseLibrary(lib); + } +}; + +struct RunWithLoad : NoAssign { + static Harness::SpinBarrier startBarr, endBarr; + static UnloadCallback unloadCallback; + static Harness::FunctionAddress runPtr; + + void operator()(int id) const { + if (!id) { + Harness::LIBRARY_HANDLE lib = + Harness::OpenLibrary(TEST_LIBRARY_NAME("test_malloc_used_by_lib_dll")); + ASSERT(lib, "Can't load " TEST_LIBRARY_NAME("test_malloc_used_by_lib_dll")); + runPtr = Harness::GetAddress(lib, "callDll"); + unloadCallback.lib = lib; + } + startBarr.wait(); + (*runPtr)(); + endBarr.wait(unloadCallback); + } +}; + +Harness::SpinBarrier RunWithLoad::startBarr, RunWithLoad::endBarr; +UnloadCallback RunWithLoad::unloadCallback; +Harness::FunctionAddress RunWithLoad::runPtr; + +void ThreadsLoadUnload() +{ + const int threads = 4; + + RunWithLoad::startBarr.initialize(threads); + RunWithLoad::endBarr.initialize(threads); + NativeParallelFor(threads, RunWithLoad()); +} + +int TestMain () { + const int ITERS = 20; + int i; + std::ptrdiff_t memory_leak = 0; + + GetMemoryUsage(); + + for (int run = 0; run<2; run++) { + // expect that memory consumption stabilized after several runs + for (i=0; i<ITERS; i++) { + std::size_t memory_in_use = GetMemoryUsage(); + if (run) + LoadThreadsUnload(); + else + ThreadsLoadUnload(); + memory_leak = GetMemoryUsage() - memory_in_use; + if (memory_leak == 0) // possibly too strong? + break; + } + if(i==ITERS) { + // not stabilized, could be leak + REPORT( "Error: memory leak of up to %ld bytes\n", static_cast<long>(memory_leak)); + exit(1); + } + } + + return Harness::Done; +} + +#endif /* HARNESS_SKIP_TEST */ +#endif // _USRDLL diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_whitebox.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_whitebox.cpp new file mode 100644 index 00000000..991ceee9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_malloc_whitebox.cpp @@ -0,0 +1,1629 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* to prevent loading dynamic TBBmalloc at startup, that is not needed + for the whitebox test */ +#define __TBB_SOURCE_DIRECTLY_INCLUDED 1 + +// According to C99 standard INTPTR_MIN defined for C++ +// iff __STDC_LIMIT_MACROS pre-defined +#define __STDC_LIMIT_MACROS 1 + +#define HARNESS_TBBMALLOC_THREAD_SHUTDOWN 1 + +#include "harness.h" +#include "harness_barrier.h" + +// To not depends on ITT support stuff +#ifdef DO_ITT_NOTIFY +#undef DO_ITT_NOTIFY +#endif + +#define __TBB_MALLOC_WHITEBOX_TEST 1 // to get access to allocator internals +// help trigger rare race condition +#define WhiteboxTestingYield() (__TBB_Yield(), __TBB_Yield(), __TBB_Yield(), __TBB_Yield()) + +#if __INTEL_COMPILER && __TBB_MIC_OFFLOAD +// 2571 is variable has not been declared with compatible "target" attribute +// 3218 is class/struct may fail when offloaded because this field is misaligned +// or contains data that is misaligned + #pragma warning(push) + #pragma warning(disable:2571 3218) +#endif +#define protected public +#define private public +#include "../tbbmalloc/frontend.cpp" +#undef protected +#undef private +#if __INTEL_COMPILER && __TBB_MIC_OFFLOAD + #pragma warning(pop) +#endif +#include "../tbbmalloc/backend.cpp" +#include "../tbbmalloc/backref.cpp" + +namespace tbbmalloc_whitebox { + size_t locGetProcessed = 0; + size_t locPutProcessed = 0; +} +#include "../tbbmalloc/large_objects.cpp" +#include "../tbbmalloc/tbbmalloc.cpp" + +const int LARGE_MEM_SIZES_NUM = 10; + +class AllocInfo { + int *p; + int val; + int size; +public: + AllocInfo() : p(NULL), val(0), size(0) {} + explicit AllocInfo(int sz) : p((int*)scalable_malloc(sz*sizeof(int))), + val(rand()), size(sz) { + ASSERT(p, NULL); + for (int k=0; k<size; k++) + p[k] = val; + } + void check() const { + for (int k=0; k<size; k++) + ASSERT(p[k] == val, NULL); + } + void clear() { + scalable_free(p); + } +}; + +class SimpleBarrier: NoAssign { +protected: + static Harness::SpinBarrier barrier; +public: + static void initBarrier(unsigned thrds) { barrier.initialize(thrds); } +}; + +Harness::SpinBarrier SimpleBarrier::barrier; + +class TestLargeObjCache: public SimpleBarrier { +public: + static int largeMemSizes[LARGE_MEM_SIZES_NUM]; + + TestLargeObjCache( ) {} + + void operator()( int /*mynum*/ ) const { + AllocInfo allocs[LARGE_MEM_SIZES_NUM]; + + // push to maximal cache limit + for (int i=0; i<2; i++) { + const int sizes[] = { MByte/sizeof(int), + (MByte-2*LargeObjectCache::LargeBSProps::CacheStep)/sizeof(int) }; + for (int q=0; q<2; q++) { + size_t curr = 0; + for (int j=0; j<LARGE_MEM_SIZES_NUM; j++, curr++) + new (allocs+curr) AllocInfo(sizes[q]); + + for (size_t j=0; j<curr; j++) { + allocs[j].check(); + allocs[j].clear(); + } + } + } + + barrier.wait(); + + // check caching correctness + for (int i=0; i<1000; i++) { + size_t curr = 0; + for (int j=0; j<LARGE_MEM_SIZES_NUM-1; j++, curr++) + new (allocs+curr) AllocInfo(largeMemSizes[j]); + + new (allocs+curr) + AllocInfo((int)(4*minLargeObjectSize + + 2*minLargeObjectSize*(1.*rand()/RAND_MAX))); + curr++; + + for (size_t j=0; j<curr; j++) { + allocs[j].check(); + allocs[j].clear(); + } + } + } +}; + +int TestLargeObjCache::largeMemSizes[LARGE_MEM_SIZES_NUM]; + +void TestLargeObjectCache() +{ + for (int i=0; i<LARGE_MEM_SIZES_NUM; i++) + TestLargeObjCache::largeMemSizes[i] = + (int)(minLargeObjectSize + 2*minLargeObjectSize*(1.*rand()/RAND_MAX)); + + for( int p=MaxThread; p>=MinThread; --p ) { + TestLargeObjCache::initBarrier( p ); + NativeParallelFor( p, TestLargeObjCache() ); + } +} + +#if MALLOC_CHECK_RECURSION + +class TestStartupAlloc: public SimpleBarrier { + struct TestBlock { + void *ptr; + size_t sz; + }; + static const int ITERS = 100; +public: + TestStartupAlloc() {} + void operator()(int) const { + TestBlock blocks1[ITERS], blocks2[ITERS]; + + barrier.wait(); + + for (int i=0; i<ITERS; i++) { + blocks1[i].sz = rand() % minLargeObjectSize; + blocks1[i].ptr = StartupBlock::allocate(blocks1[i].sz); + ASSERT(blocks1[i].ptr && StartupBlock::msize(blocks1[i].ptr)>=blocks1[i].sz + && 0==(uintptr_t)blocks1[i].ptr % sizeof(void*), NULL); + memset(blocks1[i].ptr, i, blocks1[i].sz); + } + for (int i=0; i<ITERS; i++) { + blocks2[i].sz = rand() % minLargeObjectSize; + blocks2[i].ptr = StartupBlock::allocate(blocks2[i].sz); + ASSERT(blocks2[i].ptr && StartupBlock::msize(blocks2[i].ptr)>=blocks2[i].sz + && 0==(uintptr_t)blocks2[i].ptr % sizeof(void*), NULL); + memset(blocks2[i].ptr, i, blocks2[i].sz); + + for (size_t j=0; j<blocks1[i].sz; j++) + ASSERT(*((char*)blocks1[i].ptr+j) == i, NULL); + Block *block = (Block *)alignDown(blocks1[i].ptr, slabSize); + ((StartupBlock *)block)->free(blocks1[i].ptr); + } + for (int i=ITERS-1; i>=0; i--) { + for (size_t j=0; j<blocks2[i].sz; j++) + ASSERT(*((char*)blocks2[i].ptr+j) == i, NULL); + Block *block = (Block *)alignDown(blocks2[i].ptr, slabSize); + ((StartupBlock *)block)->free(blocks2[i].ptr); + } + } +}; + +#endif /* MALLOC_CHECK_RECURSION */ + +#include <deque> + +template<int ITERS> +class BackRefWork: NoAssign { + struct TestBlock { + BackRefIdx idx; + char data; + TestBlock(BackRefIdx idx_) : idx(idx_) {} + }; +public: + BackRefWork() {} + void operator()(int) const { + size_t cnt; + // it's important to not invalidate pointers to the contents of the container + std::deque<TestBlock> blocks; + + // for ITERS==0 consume all available backrefs + for (cnt=0; !ITERS || cnt<ITERS; cnt++) { + BackRefIdx idx = BackRefIdx::newBackRef(/*largeObj=*/false); + if (idx.isInvalid()) + break; + blocks.push_back(TestBlock(idx)); + setBackRef(blocks.back().idx, &blocks.back().data); + } + for (size_t i=0; i<cnt; i++) + ASSERT((Block*)&blocks[i].data == getBackRef(blocks[i].idx), NULL); + for (size_t i=cnt; i>0; i--) + removeBackRef(blocks[i-1].idx); + } +}; + +class LocalCachesHit: NoAssign { + // set ITERS to trigger possible leak of backreferences + // during cleanup on cache overflow and on thread termination + static const int ITERS = 2*(FreeBlockPool::POOL_HIGH_MARK + + LocalLOC::LOC_HIGH_MARK); +public: + LocalCachesHit() {} + void operator()(int) const { + void *objsSmall[ITERS], *objsLarge[ITERS]; + + for (int i=0; i<ITERS; i++) { + objsSmall[i] = scalable_malloc(minLargeObjectSize-1); + objsLarge[i] = scalable_malloc(minLargeObjectSize); + } + for (int i=0; i<ITERS; i++) { + scalable_free(objsSmall[i]); + scalable_free(objsLarge[i]); + } + } +}; + +static size_t allocatedBackRefCount() +{ + size_t cnt = 0; + for (int i=0; i<=backRefMaster->lastUsed; i++) + cnt += backRefMaster->backRefBl[i]->allocatedCount; + return cnt; +} + +class TestInvalidBackrefs: public SimpleBarrier { +#if __ANDROID__ + // Android requires lower iters due to lack of virtual memory. + static const int BACKREF_GROWTH_ITERS = 50*1024; +#else + static const int BACKREF_GROWTH_ITERS = 200*1024; +#endif + + static tbb::atomic<bool> backrefGrowthDone; + static void *ptrs[BACKREF_GROWTH_ITERS]; +public: + TestInvalidBackrefs() {} + void operator()(int id) const { + + if (!id) { + backrefGrowthDone = false; + barrier.wait(); + + for (int i=0; i<BACKREF_GROWTH_ITERS; i++) + ptrs[i] = scalable_malloc(minLargeObjectSize); + backrefGrowthDone = true; + for (int i=0; i<BACKREF_GROWTH_ITERS; i++) + scalable_free(ptrs[i]); + } else { + void *p2 = scalable_malloc(minLargeObjectSize-1); + char *p1 = (char*)scalable_malloc(minLargeObjectSize-1); + LargeObjectHdr *hdr = + (LargeObjectHdr*)(p1+minLargeObjectSize-1 - sizeof(LargeObjectHdr)); + hdr->backRefIdx.master = 7; + hdr->backRefIdx.largeObj = 1; + hdr->backRefIdx.offset = 2000; + + barrier.wait(); + + while (!backrefGrowthDone) { + scalable_free(p2); + p2 = scalable_malloc(minLargeObjectSize-1); + } + scalable_free(p1); + scalable_free(p2); + } + } +}; + +tbb::atomic<bool> TestInvalidBackrefs::backrefGrowthDone; +void *TestInvalidBackrefs::ptrs[BACKREF_GROWTH_ITERS]; + +void TestBackRef() { + size_t beforeNumBackRef, afterNumBackRef; + + beforeNumBackRef = allocatedBackRefCount(); + for( int p=MaxThread; p>=MinThread; --p ) + NativeParallelFor( p, BackRefWork<2*BR_MAX_CNT+2>() ); + afterNumBackRef = allocatedBackRefCount(); + ASSERT(beforeNumBackRef==afterNumBackRef, "backreference leak detected"); + + // lastUsed marks peak resource consumption. As we allocate below the mark, + // it must not move up, otherwise there is a resource leak. + int sustLastUsed = backRefMaster->lastUsed; + NativeParallelFor( 1, BackRefWork<2*BR_MAX_CNT+2>() ); + ASSERT(sustLastUsed == backRefMaster->lastUsed, "backreference leak detected"); + + // check leak of back references while per-thread caches are in use + // warm up needed to cover bootStrapMalloc call + NativeParallelFor( 1, LocalCachesHit() ); + beforeNumBackRef = allocatedBackRefCount(); + NativeParallelFor( 2, LocalCachesHit() ); + int res = scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, NULL); + ASSERT(res == TBBMALLOC_OK, NULL); + afterNumBackRef = allocatedBackRefCount(); + ASSERT(beforeNumBackRef>=afterNumBackRef, "backreference leak detected"); + + // This is a regression test against race condition between backreference + // extension and checking invalid BackRefIdx. + // While detecting is object large or small, scalable_free 1st check for + // large objects, so there is a chance to prepend small object with + // seems valid BackRefIdx for large objects, and thus trigger the bug. + TestInvalidBackrefs::initBarrier(MaxThread); + NativeParallelFor( MaxThread, TestInvalidBackrefs() ); + // Consume all available backrefs and check they work correctly. + // For now test 32-bit machines only, because for 64-bit memory consumption is too high. + if (sizeof(uintptr_t) == 4) + NativeParallelFor( MaxThread, BackRefWork<0>() ); +} + +void *getMem(intptr_t /*pool_id*/, size_t &bytes) +{ + const size_t BUF_SIZE = 8*1024*1024; + static char space[BUF_SIZE]; + static size_t pos; + + if (pos + bytes > BUF_SIZE) + return NULL; + + void *ret = space + pos; + pos += bytes; + + return ret; +} + +int putMem(intptr_t /*pool_id*/, void* /*raw_ptr*/, size_t /*raw_bytes*/) +{ + return 0; +} + +struct MallocPoolHeader { + void *rawPtr; + size_t userSize; +}; + +void *getMallocMem(intptr_t /*pool_id*/, size_t &bytes) +{ + void *rawPtr = malloc(bytes+sizeof(MallocPoolHeader)); + void *ret = (void *)((uintptr_t)rawPtr+sizeof(MallocPoolHeader)); + + MallocPoolHeader *hdr = (MallocPoolHeader*)ret-1; + hdr->rawPtr = rawPtr; + hdr->userSize = bytes; + + return ret; +} + +int putMallocMem(intptr_t /*pool_id*/, void *ptr, size_t bytes) +{ + MallocPoolHeader *hdr = (MallocPoolHeader*)ptr-1; + ASSERT(bytes == hdr->userSize, "Invalid size in pool callback."); + free(hdr->rawPtr); + + return 0; +} + +class StressLOCacheWork: NoAssign { + rml::MemoryPool *my_mallocPool; +public: + StressLOCacheWork(rml::MemoryPool *mallocPool) : my_mallocPool(mallocPool) {} + void operator()(int) const { + for (size_t sz=minLargeObjectSize; sz<1*1024*1024; + sz+=LargeObjectCache::LargeBSProps::CacheStep) { + void *ptr = pool_malloc(my_mallocPool, sz); + ASSERT(ptr, "Memory was not allocated"); + memset(ptr, sz, sz); + pool_free(my_mallocPool, ptr); + } + } +}; + +void TestPools() { + rml::MemPoolPolicy pol(getMem, putMem); + size_t beforeNumBackRef, afterNumBackRef; + + rml::MemoryPool *pool1; + rml::MemoryPool *pool2; + pool_create_v1(0, &pol, &pool1); + pool_create_v1(0, &pol, &pool2); + pool_destroy(pool1); + pool_destroy(pool2); + + scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, NULL); + beforeNumBackRef = allocatedBackRefCount(); + rml::MemoryPool *fixedPool; + + pool_create_v1(0, &pol, &fixedPool); + pol.pAlloc = getMallocMem; + pol.pFree = putMallocMem; + pol.granularity = 8; + rml::MemoryPool *mallocPool; + + pool_create_v1(0, &pol, &mallocPool); +/* check that large object cache (LOC) returns correct size for cached objects + passBackendSz Byte objects are cached in LOC, but bypassed the backend, so + memory requested directly from allocation callback. + nextPassBackendSz Byte objects must fit to another LOC bin, + so that their allocation/realeasing leads to cache cleanup. + All this is expecting to lead to releasing of passBackendSz Byte object + from LOC during LOC cleanup, and putMallocMem checks that returned size + is correct. +*/ + const size_t passBackendSz = Backend::maxBinned_HugePage+1, + anotherLOCBinSz = minLargeObjectSize+1; + for (int i=0; i<10; i++) { // run long enough to be cached + void *p = pool_malloc(mallocPool, passBackendSz); + ASSERT(p, "Memory was not allocated"); + pool_free(mallocPool, p); + } + // run long enough to passBackendSz allocation was cleaned from cache + // and returned back to putMallocMem for size checking + for (int i=0; i<1000; i++) { + void *p = pool_malloc(mallocPool, anotherLOCBinSz); + ASSERT(p, "Memory was not allocated"); + pool_free(mallocPool, p); + } + + void *smallObj = pool_malloc(fixedPool, 10); + ASSERT(smallObj, "Memory was not allocated"); + memset(smallObj, 1, 10); + void *ptr = pool_malloc(fixedPool, 1024); + ASSERT(ptr, "Memory was not allocated"); + memset(ptr, 1, 1024); + void *largeObj = pool_malloc(fixedPool, minLargeObjectSize); + ASSERT(largeObj, "Memory was not allocated"); + memset(largeObj, 1, minLargeObjectSize); + ptr = pool_malloc(fixedPool, minLargeObjectSize); + ASSERT(ptr, "Memory was not allocated"); + memset(ptr, minLargeObjectSize, minLargeObjectSize); + pool_malloc(fixedPool, 10*minLargeObjectSize); // no leak for unsuccessful allocations + pool_free(fixedPool, smallObj); + pool_free(fixedPool, largeObj); + + // provoke large object cache cleanup and hope no leaks occurs + for( int p=MaxThread; p>=MinThread; --p ) + NativeParallelFor( p, StressLOCacheWork(mallocPool) ); + pool_destroy(mallocPool); + pool_destroy(fixedPool); + + scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, NULL); + afterNumBackRef = allocatedBackRefCount(); + ASSERT(beforeNumBackRef==afterNumBackRef, "backreference leak detected"); + + { + // test usedSize/cachedSize and LOC bitmask correctness + void *p[5]; + pool_create_v1(0, &pol, &mallocPool); + const LargeObjectCache *loc = &((rml::internal::MemoryPool*)mallocPool)->extMemPool.loc; + const int LargeCacheStep = LargeObjectCache::LargeBSProps::CacheStep; + p[3] = pool_malloc(mallocPool, minLargeObjectSize+2*LargeCacheStep); + for (int i=0; i<10; i++) { + p[0] = pool_malloc(mallocPool, minLargeObjectSize); + p[1] = pool_malloc(mallocPool, minLargeObjectSize+LargeCacheStep); + pool_free(mallocPool, p[0]); + pool_free(mallocPool, p[1]); + } + ASSERT(loc->getUsedSize(), NULL); + pool_free(mallocPool, p[3]); + ASSERT(loc->getLOCSize() < 3*(minLargeObjectSize+LargeCacheStep), NULL); + const size_t maxLocalLOCSize = LocalLOCImpl<3,30>::getMaxSize(); + ASSERT(loc->getUsedSize() <= maxLocalLOCSize, NULL); + for (int i=0; i<3; i++) + p[i] = pool_malloc(mallocPool, minLargeObjectSize+i*LargeCacheStep); + size_t currUser = loc->getUsedSize(); + ASSERT(!loc->getLOCSize() && currUser >= 3*(minLargeObjectSize+LargeCacheStep), NULL); + p[4] = pool_malloc(mallocPool, minLargeObjectSize+3*LargeCacheStep); + ASSERT(loc->getUsedSize() - currUser >= minLargeObjectSize+3*LargeCacheStep, NULL); + pool_free(mallocPool, p[4]); + ASSERT(loc->getUsedSize() <= currUser+maxLocalLOCSize, NULL); + pool_reset(mallocPool); + ASSERT(!loc->getLOCSize() && !loc->getUsedSize(), NULL); + pool_destroy(mallocPool); + } + // To test LOC we need bigger lists than released by current LocalLOC + // in production code. Create special LocalLOC. + { + LocalLOCImpl<2, 20> lLOC; + pool_create_v1(0, &pol, &mallocPool); + rml::internal::ExtMemoryPool *mPool = &((rml::internal::MemoryPool*)mallocPool)->extMemPool; + const LargeObjectCache *loc = &((rml::internal::MemoryPool*)mallocPool)->extMemPool.loc; + const int LargeCacheStep = LargeObjectCache::LargeBSProps::CacheStep; + for (int i=0; i<22; i++) { + void *o = pool_malloc(mallocPool, minLargeObjectSize+i*LargeCacheStep); + bool ret = lLOC.put(((LargeObjectHdr*)o - 1)->memoryBlock, mPool); + ASSERT(ret, NULL); + + o = pool_malloc(mallocPool, minLargeObjectSize+i*LargeCacheStep); + ret = lLOC.put(((LargeObjectHdr*)o - 1)->memoryBlock, mPool); + ASSERT(ret, NULL); + } + lLOC.externalCleanup(mPool); + ASSERT(!loc->getUsedSize(), NULL); + + pool_destroy(mallocPool); + } +} + +void TestObjectRecognition() { + size_t headersSize = sizeof(LargeMemoryBlock)+sizeof(LargeObjectHdr); + unsigned falseObjectSize = 113; // unsigned is the type expected by getObjectSize + size_t obtainedSize; + + ASSERT(sizeof(BackRefIdx)==sizeof(uintptr_t), "Unexpected size of BackRefIdx"); + ASSERT(getObjectSize(falseObjectSize)!=falseObjectSize, "Error in test: bad choice for false object size"); + + void* mem = scalable_malloc(2*slabSize); + ASSERT(mem, "Memory was not allocated"); + Block* falseBlock = (Block*)alignUp((uintptr_t)mem, slabSize); + falseBlock->objectSize = falseObjectSize; + char* falseSO = (char*)falseBlock + falseObjectSize*7; + ASSERT(alignDown(falseSO, slabSize)==(void*)falseBlock, "Error in test: false object offset is too big"); + + void* bufferLOH = scalable_malloc(2*slabSize + headersSize); + ASSERT(bufferLOH, "Memory was not allocated"); + LargeObjectHdr* falseLO = + (LargeObjectHdr*)alignUp((uintptr_t)bufferLOH + headersSize, slabSize); + LargeObjectHdr* headerLO = (LargeObjectHdr*)falseLO-1; + headerLO->memoryBlock = (LargeMemoryBlock*)bufferLOH; + headerLO->memoryBlock->unalignedSize = 2*slabSize + headersSize; + headerLO->memoryBlock->objectSize = slabSize + headersSize; + headerLO->backRefIdx = BackRefIdx::newBackRef(/*largeObj=*/true); + setBackRef(headerLO->backRefIdx, headerLO); + ASSERT(scalable_msize(falseLO) == slabSize + headersSize, + "Error in test: LOH falsification failed"); + removeBackRef(headerLO->backRefIdx); + + const int NUM_OF_IDX = BR_MAX_CNT+2; + BackRefIdx idxs[NUM_OF_IDX]; + for (int cnt=0; cnt<2; cnt++) { + for (int master = -10; master<10; master++) { + falseBlock->backRefIdx.master = (uint16_t)master; + headerLO->backRefIdx.master = (uint16_t)master; + + for (int bl = -10; bl<BR_MAX_CNT+10; bl++) { + falseBlock->backRefIdx.offset = (uint16_t)bl; + headerLO->backRefIdx.offset = (uint16_t)bl; + + for (int largeObj = 0; largeObj<2; largeObj++) { + falseBlock->backRefIdx.largeObj = largeObj; + headerLO->backRefIdx.largeObj = largeObj; + + obtainedSize = __TBB_malloc_safer_msize(falseSO, NULL); + ASSERT(obtainedSize==0, "Incorrect pointer accepted"); + obtainedSize = __TBB_malloc_safer_msize(falseLO, NULL); + ASSERT(obtainedSize==0, "Incorrect pointer accepted"); + } + } + } + if (cnt == 1) { + for (int i=0; i<NUM_OF_IDX; i++) + removeBackRef(idxs[i]); + break; + } + for (int i=0; i<NUM_OF_IDX; i++) { + idxs[i] = BackRefIdx::newBackRef(/*largeObj=*/false); + setBackRef(idxs[i], NULL); + } + } + char *smallPtr = (char*)scalable_malloc(falseObjectSize); + obtainedSize = __TBB_malloc_safer_msize(smallPtr, NULL); + ASSERT(obtainedSize==getObjectSize(falseObjectSize), "Correct pointer not accepted?"); + scalable_free(smallPtr); + + obtainedSize = __TBB_malloc_safer_msize(mem, NULL); + ASSERT(obtainedSize>=2*slabSize, "Correct pointer not accepted?"); + scalable_free(mem); + scalable_free(bufferLOH); +} + +class TestBackendWork: public SimpleBarrier { + struct TestBlock { + intptr_t data; + BackRefIdx idx; + }; + static const int ITERS = 20; + + rml::internal::Backend *backend; +public: + TestBackendWork(rml::internal::Backend *bknd) : backend(bknd) {} + void operator()(int) const { + barrier.wait(); + + for (int i=0; i<ITERS; i++) { + BlockI *slabBlock = backend->getSlabBlock(1); + ASSERT(slabBlock, "Memory was not allocated"); + uintptr_t prevBlock = (uintptr_t)slabBlock; + backend->putSlabBlock(slabBlock); + + LargeMemoryBlock *largeBlock = backend->getLargeBlock(16*1024); + ASSERT(largeBlock, "Memory was not allocated"); + ASSERT((uintptr_t)largeBlock != prevBlock, + "Large block cannot be reused from slab memory, only in fixed_pool case."); + backend->putLargeBlock(largeBlock); + } + } +}; + +void TestBackend() +{ + rml::MemPoolPolicy pol(getMallocMem, putMallocMem); + rml::MemoryPool *mPool; + pool_create_v1(0, &pol, &mPool); + rml::internal::ExtMemoryPool *ePool = &((rml::internal::MemoryPool*)mPool)->extMemPool; + rml::internal::Backend *backend = &ePool->backend; + + for( int p=MaxThread; p>=MinThread; --p ) { + // regression test against an race condition in backend synchronization, + // triggered only when WhiteboxTestingYield() call yields + for (int i=0; i<100; i++) { + TestBackendWork::initBarrier(p); + NativeParallelFor( p, TestBackendWork(backend) ); + } + } + + BlockI *block = backend->getSlabBlock(1); + ASSERT(block, "Memory was not allocated"); + backend->putSlabBlock(block); + + // Checks if the backend increases and decreases the amount of allocated memory when memory is allocated. + const size_t memSize0 = backend->getTotalMemSize(); + LargeMemoryBlock *lmb = backend->getLargeBlock(4*MByte); + ASSERT( lmb, ASSERT_TEXT ); + + const size_t memSize1 = backend->getTotalMemSize(); + ASSERT( (intptr_t)(memSize1-memSize0) >= 4*MByte, "The backend has not increased the amount of using memory." ); + + backend->putLargeBlock(lmb); + const size_t memSize2 = backend->getTotalMemSize(); + ASSERT( memSize2 == memSize0, "The backend has not decreased the amount of using memory." ); + + pool_destroy(mPool); +} + +void TestBitMask() +{ + BitMaskMin<256> mask; + + mask.reset(); + mask.set(10, 1); + mask.set(5, 1); + mask.set(1, 1); + ASSERT(mask.getMinTrue(2) == 5, NULL); + + mask.reset(); + mask.set(0, 1); + mask.set(64, 1); + mask.set(63, 1); + mask.set(200, 1); + mask.set(255, 1); + ASSERT(mask.getMinTrue(0) == 0, NULL); + ASSERT(mask.getMinTrue(1) == 63, NULL); + ASSERT(mask.getMinTrue(63) == 63, NULL); + ASSERT(mask.getMinTrue(64) == 64, NULL); + ASSERT(mask.getMinTrue(101) == 200, NULL); + ASSERT(mask.getMinTrue(201) == 255, NULL); + mask.set(255, 0); + ASSERT(mask.getMinTrue(201) == -1, NULL); +} + +size_t getMemSize() +{ + return defaultMemPool->extMemPool.backend.getTotalMemSize(); +} + +class CheckNotCached { + static size_t memSize; +public: + void operator() () const { + int res = scalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, 1); + ASSERT(res == TBBMALLOC_OK, NULL); + if (memSize==(size_t)-1) { + memSize = getMemSize(); + } else { + ASSERT(getMemSize() == memSize, NULL); + memSize=(size_t)-1; + } + } +}; + +size_t CheckNotCached::memSize = (size_t)-1; + +class RunTestHeapLimit: public SimpleBarrier { +public: + void operator()( int /*mynum*/ ) const { + // Provoke bootstrap heap initialization before recording memory size. + // NOTE: The initialization should be processed only with a "large" + // object. Since the "small" object allocation lead to blocking of a + // slab as an active block and it is impossible to release it with + // foreign thread. + scalable_free(scalable_malloc(minLargeObjectSize)); + barrier.wait(CheckNotCached()); + for (size_t n = minLargeObjectSize; n < 5*1024*1024; n += 128*1024) + scalable_free(scalable_malloc(n)); + barrier.wait(CheckNotCached()); + } +}; + +void TestHeapLimit() +{ + if(!isMallocInitialized()) doInitialization(); + // tiny limit to stop caching + int res = scalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, 1); + ASSERT(res == TBBMALLOC_OK, NULL); + // Provoke bootstrap heap initialization before recording memory size. + scalable_free(scalable_malloc(8)); + size_t n, sizeBefore = getMemSize(); + + // Try to provoke call to OS for memory to check that + // requests are not fulfilled from caches. + // Single call is not enough here because of backend fragmentation. + for (n = minLargeObjectSize; n < 10*1024*1024; n += 16*1024) { + void *p = scalable_malloc(n); + bool leave = (sizeBefore != getMemSize()); + scalable_free(p); + if (leave) + break; + ASSERT(sizeBefore == getMemSize(), "No caching expected"); + } + ASSERT(n < 10*1024*1024, "scalable_malloc doesn't provoke OS request for memory, " + "is some internal cache still used?"); + + for( int p=MaxThread; p>=MinThread; --p ) { + RunTestHeapLimit::initBarrier( p ); + NativeParallelFor( p, RunTestHeapLimit() ); + } + // it's try to match limit as well as set limit, so call here + res = scalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, 1); + ASSERT(res == TBBMALLOC_OK, NULL); + size_t m = getMemSize(); + ASSERT(sizeBefore == m, NULL); + // restore default + res = scalable_allocation_mode(TBBMALLOC_SET_SOFT_HEAP_LIMIT, 0); + ASSERT(res == TBBMALLOC_OK, NULL); +} + +void checkNoHugePages() +{ + ASSERT(!hugePages.isEnabled, "scalable_allocation_mode " + "must have priority over environment variable"); +} + +/*---------------------------------------------------------------------------*/ +// The regression test against bugs in TBBMALLOC_CLEAN_ALL_BUFFERS allocation command. +// The idea is to allocate and deallocate a set of objects randomly in parallel. +// For large sizes (16K), it forces conflicts in backend during coalescing. +// For small sizes (4K), it forces cross-thread deallocations and then orphaned slabs. +// Global cleanup should process orphaned slabs and the queue of postponed coalescing +// requests, otherwise it will not be able to unmap all unused memory. + +const int num_allocs = 10*1024; +void *ptrs[num_allocs]; +tbb::atomic<int> alloc_counter; + +inline void multiThreadAlloc(size_t alloc_size) { + for( int i = alloc_counter++; i < num_allocs; i = alloc_counter++ ) { + ptrs[i] = scalable_malloc( alloc_size ); + ASSERT( ptrs[i] != NULL, "scalable_malloc returned zero." ); + } +} +inline void crossThreadDealloc() { + for( int i = --alloc_counter; i >= 0; i = --alloc_counter ) { + if (i < num_allocs) scalable_free( ptrs[i] ); + } +} + +template<int AllocSize> +struct TestCleanAllBuffersBody : public SimpleBarrier { + void operator() ( int ) const { + barrier.wait(); + multiThreadAlloc(AllocSize); + barrier.wait(); + crossThreadDealloc(); + } +}; + +template<int AllocSize> +void TestCleanAllBuffers() { + const int num_threads = 8; + // Clean up if something was allocated before the test + scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS,0); + + size_t memory_in_use_before = getMemSize(); + alloc_counter = 0; + TestCleanAllBuffersBody<AllocSize>::initBarrier(num_threads); + + NativeParallelFor(num_threads, TestCleanAllBuffersBody<AllocSize>()); + // TODO: reproduce the bug conditions more reliably + if ( defaultMemPool->extMemPool.backend.coalescQ.blocksToFree == NULL ) + REMARK( "Warning: The queue of postponed coalescing requests is empty. Unable to create the condition for bug reproduction.\n" ); + int result = scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS,0); + ASSERT( result == TBBMALLOC_OK, "The cleanup request has not cleaned anything." ); + size_t memory_in_use_after = getMemSize(); + + size_t memory_leak = memory_in_use_after - memory_in_use_before; + REMARK( "memory_in_use_before = %ld\nmemory_in_use_after = %ld\n", memory_in_use_before, memory_in_use_after ); + ASSERT( memory_leak == 0, "Cleanup was unable to release all allocated memory." ); +} + +//! Force cross thread deallocation of small objects to create a set of privatizable slab blocks. +//! TBBMALLOC_CLEAN_THREAD_BUFFERS command have to privatize all the block. +struct TestCleanThreadBuffersBody : public SimpleBarrier { + void operator() ( int ) const { + barrier.wait(); + multiThreadAlloc(2*1024); + barrier.wait(); + crossThreadDealloc(); + barrier.wait(); + int result = scalable_allocation_command(TBBMALLOC_CLEAN_THREAD_BUFFERS,0); + ASSERT(result == TBBMALLOC_OK, "Per-thread clean request has not cleaned anything."); + + // Check that TLS was cleaned fully + TLSData *tlsCurr = defaultMemPool->getTLS(/*create=*/false); + for (int i = 0; i < numBlockBinLimit; i++) { + ASSERT(!(tlsCurr->bin[i].activeBlk), "Some bin was not cleaned."); + } + ASSERT(!(tlsCurr->lloc.head), "Local LOC was not cleaned."); + ASSERT(!(tlsCurr->freeSlabBlocks.head), "Free Block pool was not cleaned."); + } +}; + +void TestCleanThreadBuffers() { + const int num_threads = 8; + // Clean up if something was allocated before the test + scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS,0); + + alloc_counter = 0; + TestCleanThreadBuffersBody::initBarrier(num_threads); + NativeParallelFor(num_threads, TestCleanThreadBuffersBody()); +} + +/*---------------------------------------------------------------------------*/ +/*------------------------- Large Object Cache tests ------------------------*/ +#if _MSC_VER==1600 || _MSC_VER==1500 + // ignore C4275: non dll-interface class 'stdext::exception' used as + // base for dll-interface class 'std::bad_cast' + #pragma warning (disable: 4275) +#endif +#include <vector> +#include <list> +#include __TBB_STD_SWAP_HEADER + +// default constructor of CacheBin +template<typename Props> +rml::internal::LargeObjectCacheImpl<Props>::CacheBin::CacheBin() {} + +template<typename Props> +class CacheBinModel { + + typedef typename rml::internal::LargeObjectCacheImpl<Props>::CacheBin CacheBinType; + + // The emulated cache bin. + CacheBinType cacheBinModel; + // The reference to real cache bin inside the large object cache. + CacheBinType &cacheBin; + + const size_t size; + + // save only current time + std::list<uintptr_t> objects; + + void doCleanup() { + if ( cacheBinModel.cachedSize > Props::TooLargeFactor*cacheBinModel.usedSize ) tooLargeLOC++; + else tooLargeLOC = 0; + + if (tooLargeLOC>3 && cacheBinModel.ageThreshold) + cacheBinModel.ageThreshold = (cacheBinModel.ageThreshold + cacheBinModel.meanHitRange)/2; + + uintptr_t currTime = cacheCurrTime; + while (!objects.empty() && (intptr_t)(currTime - objects.front()) > cacheBinModel.ageThreshold) { + cacheBinModel.cachedSize -= size; + cacheBinModel.lastCleanedAge = objects.front(); + objects.pop_front(); + } + + cacheBinModel.oldest = objects.empty() ? 0 : objects.front(); + } + +public: + CacheBinModel(CacheBinType &_cacheBin, size_t allocSize) : cacheBin(_cacheBin), size(allocSize) { + cacheBinModel.oldest = cacheBin.oldest; + cacheBinModel.lastCleanedAge = cacheBin.lastCleanedAge; + cacheBinModel.ageThreshold = cacheBin.ageThreshold; + cacheBinModel.usedSize = cacheBin.usedSize; + cacheBinModel.cachedSize = cacheBin.cachedSize; + cacheBinModel.meanHitRange = cacheBin.meanHitRange; + cacheBinModel.lastGet = cacheBin.lastGet; + } + void get() { + uintptr_t currTime = ++cacheCurrTime; + + if ( objects.empty() ) { + const uintptr_t sinceLastGet = currTime - cacheBinModel.lastGet; + if ( ( cacheBinModel.ageThreshold && sinceLastGet > Props::LongWaitFactor*cacheBinModel.ageThreshold ) || + ( cacheBinModel.lastCleanedAge && sinceLastGet > Props::LongWaitFactor*(cacheBinModel.lastCleanedAge - cacheBinModel.lastGet) ) ) + cacheBinModel.lastCleanedAge = cacheBinModel.ageThreshold = 0; + + if (cacheBinModel.lastCleanedAge) + cacheBinModel.ageThreshold = Props::OnMissFactor*(currTime - cacheBinModel.lastCleanedAge); + } else { + uintptr_t obj_age = objects.back(); + objects.pop_back(); + if ( objects.empty() ) cacheBinModel.oldest = 0; + + intptr_t hitRange = currTime - obj_age; + cacheBinModel.meanHitRange = cacheBinModel.meanHitRange? (cacheBinModel.meanHitRange + hitRange)/2 : hitRange; + + cacheBinModel.cachedSize -= size; + } + + cacheBinModel.usedSize += size; + cacheBinModel.lastGet = currTime; + + if ( currTime % rml::internal::cacheCleanupFreq == 0 ) doCleanup(); + } + + void putList( int num ) { + uintptr_t currTime = cacheCurrTime; + cacheCurrTime += num; + + cacheBinModel.usedSize -= num*size; + + bool cleanUpNeeded = false; + if ( !cacheBinModel.lastCleanedAge ) { + cacheBinModel.lastCleanedAge = ++currTime; + cleanUpNeeded |= currTime % rml::internal::cacheCleanupFreq == 0; + num--; + } + + for ( int i=1; i<=num; ++i ) { + currTime+=1; + cleanUpNeeded |= currTime % rml::internal::cacheCleanupFreq == 0; + if ( objects.empty() ) + cacheBinModel.oldest = currTime; + objects.push_back(currTime); + } + + cacheBinModel.cachedSize += num*size; + + if ( cleanUpNeeded ) doCleanup(); + } + + void check() { + ASSERT(cacheBinModel.oldest == cacheBin.oldest, ASSERT_TEXT); + ASSERT(cacheBinModel.lastCleanedAge == cacheBin.lastCleanedAge, ASSERT_TEXT); + ASSERT(cacheBinModel.ageThreshold == cacheBin.ageThreshold, ASSERT_TEXT); + ASSERT(cacheBinModel.usedSize == cacheBin.usedSize, ASSERT_TEXT); + ASSERT(cacheBinModel.cachedSize == cacheBin.cachedSize, ASSERT_TEXT); + ASSERT(cacheBinModel.meanHitRange == cacheBin.meanHitRange, ASSERT_TEXT); + ASSERT(cacheBinModel.lastGet == cacheBin.lastGet, ASSERT_TEXT); + } + + static uintptr_t cacheCurrTime; + static intptr_t tooLargeLOC; +}; + +template<typename Props> uintptr_t CacheBinModel<Props>::cacheCurrTime; +template<typename Props> intptr_t CacheBinModel<Props>::tooLargeLOC; + +template <typename Scenario> +void LOCModelTester() { + defaultMemPool->extMemPool.loc.cleanAll(); + defaultMemPool->extMemPool.loc.reset(); + + const size_t size = 16 * 1024; + const size_t headersSize = sizeof(rml::internal::LargeMemoryBlock)+sizeof(rml::internal::LargeObjectHdr); + const size_t allocationSize = LargeObjectCache::alignToBin(size+headersSize+rml::internal::largeObjectAlignment); + const int binIdx = defaultMemPool->extMemPool.loc.largeCache.sizeToIdx( allocationSize ); + + CacheBinModel<rml::internal::LargeObjectCache::LargeCacheTypeProps>::cacheCurrTime = defaultMemPool->extMemPool.loc.cacheCurrTime; + CacheBinModel<rml::internal::LargeObjectCache::LargeCacheTypeProps>::tooLargeLOC = defaultMemPool->extMemPool.loc.largeCache.tooLargeLOC; + CacheBinModel<rml::internal::LargeObjectCache::LargeCacheTypeProps> cacheBinModel(defaultMemPool->extMemPool.loc.largeCache.bin[binIdx], allocationSize); + + Scenario scen; + for (rml::internal::LargeMemoryBlock *lmb = scen.next(); (intptr_t)lmb != (intptr_t)-1; lmb = scen.next()) { + if ( lmb ) { + int num=1; + for (rml::internal::LargeMemoryBlock *curr = lmb; curr->next; curr=curr->next) num+=1; + defaultMemPool->extMemPool.freeLargeObject(lmb); + cacheBinModel.putList(num); + } else { + scen.saveLmb(defaultMemPool->extMemPool.mallocLargeObject(defaultMemPool, allocationSize)); + cacheBinModel.get(); + } + + cacheBinModel.check(); + } +} + +class TestBootstrap { + bool allocating; + std::vector<rml::internal::LargeMemoryBlock*> lmbArray; +public: + TestBootstrap() : allocating(true) {} + + rml::internal::LargeMemoryBlock* next() { + if ( allocating ) + return NULL; + if ( !lmbArray.empty() ) { + rml::internal::LargeMemoryBlock *ret = lmbArray.back(); + lmbArray.pop_back(); + return ret; + } + return (rml::internal::LargeMemoryBlock*)-1; + } + + void saveLmb( rml::internal::LargeMemoryBlock *lmb ) { + lmb->next = NULL; + lmbArray.push_back(lmb); + if ( lmbArray.size() == 1000 ) allocating = false; + } +}; + +class TestRandom { + std::vector<rml::internal::LargeMemoryBlock*> lmbArray; + int numOps; +public: + TestRandom() : numOps(100000) { + srand(1234); + } + + rml::internal::LargeMemoryBlock* next() { + if ( numOps-- ) { + if ( lmbArray.empty() || rand() / (RAND_MAX>>1) == 0 ) + return NULL; + size_t ind = rand()%lmbArray.size(); + if ( ind != lmbArray.size()-1 ) std::swap(lmbArray[ind],lmbArray[lmbArray.size()-1]); + rml::internal::LargeMemoryBlock *lmb = lmbArray.back(); + lmbArray.pop_back(); + return lmb; + } + return (rml::internal::LargeMemoryBlock*)-1; + } + + void saveLmb( rml::internal::LargeMemoryBlock *lmb ) { + lmb->next = NULL; + lmbArray.push_back(lmb); + } +}; + +class TestCollapsingMallocFree : public SimpleBarrier { +public: + static const int NUM_ALLOCS = 100000; + const int num_threads; + + TestCollapsingMallocFree( int _num_threads ) : num_threads(_num_threads) { + initBarrier( num_threads ); + } + + void operator() ( int ) const { + const size_t size = 16 * 1024; + const size_t headersSize = sizeof(rml::internal::LargeMemoryBlock)+sizeof(rml::internal::LargeObjectHdr); + const size_t allocationSize = LargeObjectCache::alignToBin(size+headersSize+rml::internal::largeObjectAlignment); + + barrier.wait(); + for ( int i=0; i<NUM_ALLOCS; ++i ) { + defaultMemPool->extMemPool.freeLargeObject( + defaultMemPool->extMemPool.mallocLargeObject(defaultMemPool, allocationSize) ); + } + } + + void check() { + ASSERT( tbbmalloc_whitebox::locGetProcessed == tbbmalloc_whitebox::locPutProcessed, ASSERT_TEXT ); + ASSERT( tbbmalloc_whitebox::locGetProcessed < num_threads*NUM_ALLOCS, "No one Malloc/Free pair was collapsed." ); + } +}; + +class TestCollapsingBootstrap : public SimpleBarrier { + class CheckNumAllocs { + const int num_threads; + public: + CheckNumAllocs( int _num_threads ) : num_threads(_num_threads) {} + void operator()() const { + ASSERT( tbbmalloc_whitebox::locGetProcessed == num_threads*NUM_ALLOCS, ASSERT_TEXT ); + ASSERT( tbbmalloc_whitebox::locPutProcessed == 0, ASSERT_TEXT ); + } + }; +public: + static const int NUM_ALLOCS = 1000; + const int num_threads; + + TestCollapsingBootstrap( int _num_threads ) : num_threads(_num_threads) { + initBarrier( num_threads ); + } + + void operator() ( int ) const { + const size_t size = 16 * 1024; + size_t headersSize = sizeof(rml::internal::LargeMemoryBlock)+sizeof(rml::internal::LargeObjectHdr); + size_t allocationSize = LargeObjectCache::alignToBin(size+headersSize+rml::internal::largeObjectAlignment); + + barrier.wait(); + rml::internal::LargeMemoryBlock *lmbArray[NUM_ALLOCS]; + for ( int i=0; i<NUM_ALLOCS; ++i ) + lmbArray[i] = defaultMemPool->extMemPool.mallocLargeObject(defaultMemPool, allocationSize); + + barrier.wait(CheckNumAllocs(num_threads)); + for ( int i=0; i<NUM_ALLOCS; ++i ) + defaultMemPool->extMemPool.freeLargeObject( lmbArray[i] ); + } + + void check() { + ASSERT( tbbmalloc_whitebox::locGetProcessed == tbbmalloc_whitebox::locPutProcessed, ASSERT_TEXT ); + ASSERT( tbbmalloc_whitebox::locGetProcessed == num_threads*NUM_ALLOCS, ASSERT_TEXT ); + } +}; + +template <typename Scenario> +void LOCCollapsingTester( int num_threads ) { + tbbmalloc_whitebox::locGetProcessed = 0; + tbbmalloc_whitebox::locPutProcessed = 0; + defaultMemPool->extMemPool.loc.cleanAll(); + defaultMemPool->extMemPool.loc.reset(); + + Scenario scen(num_threads); + NativeParallelFor(num_threads, scen); + + scen.check(); +} + +void TestLOC() { + LOCModelTester<TestBootstrap>(); + LOCModelTester<TestRandom>(); + + const int num_threads = 16; + LOCCollapsingTester<TestCollapsingBootstrap>( num_threads ); + if ( num_threads > 1 ) { + REMARK( "num_threads = %d\n", num_threads ); + LOCCollapsingTester<TestCollapsingMallocFree>( num_threads ); + } else { + REPORT( "Warning: concurrency is too low for TestMallocFreeCollapsing ( num_threads = %d )\n", num_threads ); + } +} +/*---------------------------------------------------------------------------*/ + +void *findCacheLine(void *p) { + return (void*)alignDown((uintptr_t)p, estimatedCacheLineSize); +} + +// test that internals of Block are at expected cache lines +void TestSlabAlignment() { + const size_t min_sz = 8; + const int space = 2*16*1024; // fill at least 2 slabs + void *pointers[space / min_sz]; // the worst case is min_sz byte object + + for (size_t sz = min_sz; sz <= 64; sz *= 2) { + for (size_t i = 0; i < space/sz; i++) { + pointers[i] = scalable_malloc(sz); + Block *block = (Block *)alignDown(pointers[i], slabSize); + MALLOC_ASSERT(findCacheLine(&block->isFull) != findCacheLine(pointers[i]), + "A user object must not share a cache line with slab control structures."); + MALLOC_ASSERT(findCacheLine(&block->next) != findCacheLine(&block->nextPrivatizable), + "GlobalBlockFields and LocalBlockFields must be on different cache lines."); + } + for (size_t i = 0; i < space/sz; i++) + scalable_free(pointers[i]); + } +} + +#include "harness_memory.h" + +// TODO: Consider adding Huge Pages support on macOS (special mmap flag). +// Transparent Huge pages support could be enabled by different system parsing mechanism, +// because there is no /proc/meminfo on macOS +#if __linux__ +void TestTHP() { + // Get backend from default memory pool + rml::internal::Backend *backend = &(defaultMemPool->extMemPool.backend); + + // Configure malloc to use huge pages + scalable_allocation_mode(USE_HUGE_PAGES, 1); + MALLOC_ASSERT(hugePages.isEnabled, "Huge pages should be enabled via scalable_allocation_mode"); + + const int HUGE_PAGE_SIZE = 2 * 1024 * 1024; + + // allocCount transparent huge pages should be allocated + const int allocCount = 10; + + // Allocate huge page aligned memory regions to track system + // counters for transparent huge pages + void* allocPtrs[allocCount]; + + // Wait for the system to update process memory info files after other tests + Harness::Sleep(4000); + + // Parse system info regarding current THP status + size_t currentSystemTHPCount = getSystemTHPCount(); + size_t currentSystemTHPAllocatedSize = getSystemTHPAllocatedSize(); + + for (int i = 0; i < allocCount; i++) { + // Allocation size have to be aligned on page size + size_t allocSize = HUGE_PAGE_SIZE - (i * 1000); + + // Map memory + allocPtrs[i] = backend->allocRawMem(allocSize); + + MALLOC_ASSERT(allocPtrs[i], "Allocation not succeeded."); + MALLOC_ASSERT(allocSize == HUGE_PAGE_SIZE, + "Allocation size have to be aligned on Huge Page size internally."); + + // First touch policy - no real pages allocated by OS without accessing the region + memset(allocPtrs[i], 1, allocSize); + + MALLOC_ASSERT(isAligned(allocPtrs[i], HUGE_PAGE_SIZE), + "The pointer returned by scalable_malloc is not aligned on huge page size."); + } + + // Wait for the system to update process memory info files after allocations + Harness::Sleep(4000); + + // Generally, kernel tries to allocate transparent huge pages, but sometimes it cannot do this + // (tested on SLES 11/12), so consider this system info checks as a remark. + // Also, some systems can allocate more memory then needed in background (tested on Ubuntu 14.04) + size_t newSystemTHPCount = getSystemTHPCount(); + size_t newSystemTHPAllocatedSize = getSystemTHPAllocatedSize(); + if ((newSystemTHPCount - currentSystemTHPCount) < allocCount + && (newSystemTHPAllocatedSize - currentSystemTHPAllocatedSize) / (2 * 1024) < allocCount) { + REPORT( "Warning: the system didn't allocate needed amount of THPs.\n" ); + } + + // Test memory unmap + for (int i = 0; i < allocCount; i++) { + MALLOC_ASSERT(backend->freeRawMem(allocPtrs[i], HUGE_PAGE_SIZE), + "Something went wrong during raw memory free"); + } +} +#endif // __linux__ + +inline size_t getStabilizedMemUsage() { + for (int i = 0; i < 3; i++) GetMemoryUsage(); + return GetMemoryUsage(); +} + +inline void* reallocAndRetrieve(void* origPtr, size_t reallocSize, size_t& origBlockSize, size_t& reallocBlockSize) { + rml::internal::LargeMemoryBlock* origLmb = ((rml::internal::LargeObjectHdr *)origPtr - 1)->memoryBlock; + origBlockSize = origLmb->unalignedSize; + + void* reallocPtr = rml::internal::reallocAligned(defaultMemPool, origPtr, reallocSize, 0); + + // Retrieved reallocated block information + rml::internal::LargeMemoryBlock* reallocLmb = ((rml::internal::LargeObjectHdr *)reallocPtr - 1)->memoryBlock; + reallocBlockSize = reallocLmb->unalignedSize; + + return reallocPtr; +} + +void TestReallocDecreasing() { + + /* Testing that actual reallocation happens for large objects that do not fit the backend cache + but decrease in size by a factor of >= 2. */ + + size_t startSize = 100 * 1024 * 1024; + size_t maxBinnedSize = defaultMemPool->extMemPool.backend.getMaxBinnedSize(); + void* origPtr = scalable_malloc(startSize); + void* reallocPtr = NULL; + + // Realloc on 1MB less size + size_t origBlockSize = 42; + size_t reallocBlockSize = 43; + reallocPtr = reallocAndRetrieve(origPtr, startSize - 1 * 1024 * 1024, origBlockSize, reallocBlockSize); + MALLOC_ASSERT(origBlockSize == reallocBlockSize, "Reallocated block size shouldn't change"); + MALLOC_ASSERT(reallocPtr == origPtr, "Original pointer shouldn't change"); + + // Repeated decreasing reallocation while max cache bin size reached + size_t reallocSize = (startSize / 2) - 1000; // exact realloc + while(reallocSize > maxBinnedSize) { + + // Prevent huge/large objects caching + defaultMemPool->extMemPool.loc.cleanAll(); + // Prevent local large object caching + TLSData *tls = defaultMemPool->getTLS(/*create=*/false); + tls->lloc.externalCleanup(&defaultMemPool->extMemPool); + + size_t sysMemUsageBefore = getStabilizedMemUsage(); + size_t totalMemSizeBefore = defaultMemPool->extMemPool.backend.getTotalMemSize(); + + reallocPtr = reallocAndRetrieve(origPtr, reallocSize, origBlockSize, reallocBlockSize); + + MALLOC_ASSERT(origBlockSize > reallocBlockSize, "Reallocated block size should descrease."); + + size_t sysMemUsageAfter = getStabilizedMemUsage(); + size_t totalMemSizeAfter = defaultMemPool->extMemPool.backend.getTotalMemSize(); + + // Prevent false checking when backend caching occurred or could not read system memory usage info + if (totalMemSizeBefore > totalMemSizeAfter && sysMemUsageAfter != 0 && sysMemUsageBefore != 0) { + MALLOC_ASSERT(sysMemUsageBefore > sysMemUsageAfter, "Memory were not released"); + } + + origPtr = reallocPtr; + reallocSize = (reallocSize / 2) - 1000; // exact realloc + } + scalable_free(reallocPtr); + + /* TODO: Decreasing reallocation of large objects that fit backend cache */ + /* TODO: Small objects decreasing reallocation test */ +} +#if !__TBB_WIN8UI_SUPPORT && defined(_WIN32) + +#include "../src/tbbmalloc/tbb_function_replacement.cpp" +#include <string> +namespace FunctionReplacement { + FunctionInfo funcInfo = { "funcname","dllname" }; + char **func_replacement_log; + int status; + + void LogCleanup() { + // Free all allocated memory + for (unsigned i = 0; i < Log::record_number; i++){ + HeapFree(GetProcessHeap(), 0, Log::records[i]); + } + for (unsigned i = 0; i < Log::RECORDS_COUNT + 1; i++){ + Log::records[i] = NULL; + } + Log::replacement_status = true; + Log::record_number = 0; + } + + void TestEmptyLog() { + status = TBB_malloc_replacement_log(&func_replacement_log); + + ASSERT(status == -1, "Status is true, but log is empty"); + ASSERT(*func_replacement_log == NULL, "Log must be empty"); + } + + void TestLogOverload() { + for (int i = 0; i < 1000; i++) + Log::record(funcInfo, "opcode string", true); + + status = TBB_malloc_replacement_log(&func_replacement_log); + // Find last record + for (; *(func_replacement_log + 1) != 0; func_replacement_log++) {} + + std::string last_line(*func_replacement_log); + ASSERT(status == 0, "False status, but all functions found"); + ASSERT(last_line.compare("Log was truncated.") == 0, "Log overflow was not handled"); + + // Change status + Log::record(funcInfo, "opcode string", false); + status = TBB_malloc_replacement_log(NULL); + ASSERT(status == -1, "Status is true, but we have false search case"); + + LogCleanup(); + } + + void TestFalseSearchCase() { + Log::record(funcInfo, "opcode string", false); + std::string expected_line = "Fail: "+ std::string(funcInfo.funcName) + " (" + + std::string(funcInfo.dllName) + "), byte pattern: <opcode string>"; + + status = TBB_malloc_replacement_log(&func_replacement_log); + + ASSERT(expected_line.compare(*func_replacement_log) == 0, "Wrong last string contnent"); + ASSERT(status == -1, "Status is true, but we have false search case"); + LogCleanup(); + } + + void TestWrongFunctionInDll(){ + HMODULE ucrtbase_handle = GetModuleHandle("ucrtbase.dll"); + if (ucrtbase_handle) { + IsPrologueKnown("ucrtbase.dll", "fake_function", NULL, ucrtbase_handle); + std::string expected_line = "Fail: fake_function (ucrtbase.dll), byte pattern: <unknown>"; + + status = TBB_malloc_replacement_log(&func_replacement_log); + + ASSERT(expected_line.compare(*func_replacement_log) == 0, "Wrong last string contnent"); + ASSERT(status == -1, "Status is true, but we have false search case"); + LogCleanup(); + } else { + REMARK("Cannot found ucrtbase.dll on system, test skipped!\n"); + } + } +} + +void TesFunctionReplacementLog() { + using namespace FunctionReplacement; + // Do not reorder the test cases + TestEmptyLog(); + TestLogOverload(); + TestFalseSearchCase(); + TestWrongFunctionInDll(); +} + +#endif /*!__TBB_WIN8UI_SUPPORT && defined(_WIN32)*/ + +#include <cmath> // pow function + +// Huge objects cache: Size = MinSize * (2 ^ (Index / StepFactor) formula gives value for the bin size, +// but it is not matched with our sizeToIdx approximation algorithm, where step sizes between major +// (power of 2) sizes are equal. Used internally for the test. Static cast to avoid warnings. +inline size_t hocIdxToSizeFormula(int idx) { + return static_cast<size_t>(float(rml::internal::LargeObjectCache::maxLargeSize) * + pow(2, float(idx) / float(rml::internal::LargeObjectCache::HugeBSProps::StepFactor))); +} +// Large objects cache arithmetic progression +inline size_t locIdxToSizeFormula(int idx) { + return rml::internal::LargeObjectCache::LargeBSProps::MinSize + + (idx * rml::internal::LargeObjectCache::LargeBSProps::CacheStep); +} + +template <typename CacheType> +void TestLOCacheBinsConverterImpl(int idx, size_t checkingSize) { + size_t alignedSize = CacheType::alignToBin(checkingSize); + MALLOC_ASSERT(alignedSize >= checkingSize, "Size is not correctly aligned"); + int calcIdx = CacheType::sizeToIdx(alignedSize); + MALLOC_ASSERT(calcIdx == idx, "Index from size calculated not correctly"); +} + +void TestLOCacheBinsConverter(){ + typedef rml::internal::LargeObjectCache::LargeCacheType LargeCacheType; + typedef rml::internal::LargeObjectCache::HugeCacheType HugeCacheType; + + size_t checkingSize = 0; + for (int idx = 0; idx < LargeCacheType::numBins; idx++) { + checkingSize = locIdxToSizeFormula(idx); + TestLOCacheBinsConverterImpl<LargeCacheType>(idx, checkingSize); + } + for (int idx = 0; idx < HugeCacheType::numBins; idx++) { + checkingSize = hocIdxToSizeFormula(idx); + TestLOCacheBinsConverterImpl<HugeCacheType>(idx, checkingSize); + } +} + +struct HOThresholdTester { + LargeObjectCache* loc; + size_t hugeSize; + + static const size_t sieveSize = LargeObjectCache::defaultMaxHugeSize; + // Sieve starts from 64MB (24-th cache bin), enough to check 4 bins radius range + // for decent memory consumption (especially for 32-bit arch) + static const int MIN_BIN_IDX = 20; + static const int MAX_BIN_IDX = 28; + + enum CleanupType { + NO_CLEANUP, + REGULAR_CLEANUP, + HARD_CLEANUP + }; + + void populateCache() { + LargeMemoryBlock* loArray[MAX_BIN_IDX - MIN_BIN_IDX]; + // To avoid backend::softCacheCleanup consequences (cleanup by isLOCToolarge), + // firstly allocate all objects and then cache them at once. + // Morevover, just because first cache item will still be dropped from cache because of the lack of history, + // redo allocation 2 times. + for (int idx = MIN_BIN_IDX; idx < MAX_BIN_IDX; ++idx) { + size_t allocationSize = alignedSizeFromIdx(idx); + int localIdx = idx - MIN_BIN_IDX; + loArray[localIdx] = defaultMemPool->extMemPool.mallocLargeObject(defaultMemPool, allocationSize); + MALLOC_ASSERT(loArray[localIdx], "Large object was not allocated."); + loc->put(loArray[localIdx]); + loArray[localIdx] = defaultMemPool->extMemPool.mallocLargeObject(defaultMemPool, allocationSize); + } + for (int idx = MIN_BIN_IDX; idx < MAX_BIN_IDX; ++idx) { + loc->put(loArray[idx - MIN_BIN_IDX]); + } + } + void clean(bool all) { + if (all) { + // Should avoid any threshold and clean all bins + loc->cleanAll(); + } else { + // Regular cleanup should do nothing for bins above threshold. Decreasing option used + // for the test to be sure that all objects below defaultMaxHugeSize (sieveSize) were cleaned + loc->regularCleanup(); + loc->decreasingCleanup(); + } + } + void check(CleanupType type) { + for (int idx = MIN_BIN_IDX; idx < MAX_BIN_IDX; ++idx) { + size_t objectSize = alignedSizeFromIdx(idx); + // Cache object below sieve threshold and above huge object threshold should be cached + // (other should be sieved). Unless all cache is dropped. Regular cleanup drops object only below sieve size. + if (type == NO_CLEANUP && sizeInCacheRange(objectSize)) { + MALLOC_ASSERT(objectInCacheBin(idx, objectSize), "Object was released from cache, it shouldn't."); + } else if (type == REGULAR_CLEANUP && (objectSize >= hugeSize)) { + MALLOC_ASSERT(objectInCacheBin(idx, objectSize), "Object was released from cache, it shouldn't."); + } else { // HARD_CLEANUP + MALLOC_ASSERT(cacheBinEmpty(idx), "Object is still cached."); + } + } + } + +private: + bool cacheBinEmpty(int idx) { + return (loc->hugeCache.bin[idx].cachedSize == 0 && loc->hugeCache.bin[idx].get() == NULL); + } + bool objectInCacheBin(int idx, size_t size) { + return (loc->hugeCache.bin[idx].cachedSize != 0 && loc->hugeCache.bin[idx].cachedSize % size == 0); + } + bool sizeInCacheRange(size_t size) { + return size <= sieveSize || size >= hugeSize; + } + size_t alignedSizeFromIdx(int idx) { + return rml::internal::LargeObjectCache::alignToBin(hocIdxToSizeFormula(idx)); + } +}; + +// TBBMALLOC_SET_HUGE_OBJECT_THRESHOLD value should be set before the test, +// through scalable API or env variable +void TestHugeSizeThresholdImpl(LargeObjectCache* loc, size_t hugeSize, bool fullTesting) { + HOThresholdTester test = {loc, hugeSize}; + test.populateCache(); + // Check the default sieve value + test.check(HOThresholdTester::NO_CLEANUP); + + if(fullTesting) { + // Check that objects above threshold stay in cache after regular cleanup + test.clean(/*all*/false); + test.check(HOThresholdTester::REGULAR_CLEANUP); + } + // Check that all objects dropped from cache after hard cleanup (ignore huge obects threshold) + test.clean(/*all*/true); + test.check(HOThresholdTester::HARD_CLEANUP); + // Restore previous settings + loc->setHugeSizeThreshold(LargeObjectCache::maxHugeSize); + loc->reset(); +} + +/* + * Test for default huge size and behaviour when huge object settings defined + */ +void TestHugeSizeThreshold() { + // Clean up if something was allocated before the test and reset cache state + scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, 0); + LargeObjectCache* loc = &defaultMemPool->extMemPool.loc; + // Restore default settings just in case + loc->setHugeSizeThreshold(LargeObjectCache::maxHugeSize); + loc->reset(); + // Firstly check default huge size value (with max huge object threshold). + // Everything that more then this value should be released to OS without caching. + TestHugeSizeThresholdImpl(loc, loc->hugeSizeThreshold, false); + // Then set huge object threshold. + // All objects with sizes after threshold will be released only after the hard cleanup. +#if !__TBB_WIN8UI_SUPPORT + // Unit testing for environment variable + Harness::SetEnv("TBB_MALLOC_SET_HUGE_SIZE_THRESHOLD","67108864"); + // Large object cache reads threshold environment during initialization. + // Reset the value before the test. + loc->hugeSizeThreshold = 0; + loc->init(&defaultMemPool->extMemPool); + TestHugeSizeThresholdImpl(loc, 64 * MByte, true); +#endif + // Unit testing for scalable_allocation_command + scalable_allocation_mode(TBBMALLOC_SET_HUGE_SIZE_THRESHOLD, 56 * MByte); + TestHugeSizeThresholdImpl(loc, 56 * MByte, true); +} + +int TestMain () { + scalable_allocation_mode(USE_HUGE_PAGES, 0); +#if !__TBB_WIN8UI_SUPPORT + Harness::SetEnv("TBB_MALLOC_USE_HUGE_PAGES","yes"); +#endif + checkNoHugePages(); + // backreference requires that initialization was done + if(!isMallocInitialized()) doInitialization(); + checkNoHugePages(); + // to succeed, leak detection must be the 1st memory-intensive test + TestBackRef(); + TestCleanAllBuffers<4*1024>(); + TestCleanAllBuffers<16*1024>(); + TestCleanThreadBuffers(); + TestPools(); + TestBackend(); + +#if MALLOC_CHECK_RECURSION + for( int p=MaxThread; p>=MinThread; --p ) { + TestStartupAlloc::initBarrier( p ); + NativeParallelFor( p, TestStartupAlloc() ); + ASSERT(!firstStartupBlock, "Startup heap memory leak detected"); + } +#endif + + TestLargeObjectCache(); + TestObjectRecognition(); + TestBitMask(); + TestHeapLimit(); + TestLOC(); + TestSlabAlignment(); + TestReallocDecreasing(); + TestLOCacheBinsConverter(); + TestHugeSizeThreshold(); + +#if __linux__ + if (isTHPEnabledOnMachine()) { + TestTHP(); + } else { + REMARK("Transparent Huge Pages is not supported on the system - skipped the test\n"); + } +#endif + +#if !__TBB_WIN8UI_SUPPORT && defined(_WIN32) + TesFunctionReplacementLog(); +#endif + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_model_plugin.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_model_plugin.cpp new file mode 100644 index 00000000..a93b7ea2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_model_plugin.cpp @@ -0,0 +1,216 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 4 +#define HARNESS_DEFAULT_MAX_THREADS 4 + +// Need to include "tbb/tbb_config.h" to obtain the definition of __TBB_DEFINE_MIC. +#include "tbb/tbb_config.h" + +#if !__TBB_TODO || __TBB_WIN8UI_SUPPORT +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" +int TestMain() { + return Harness::Skipped; +} +#else /* __TBB_TODO */ +// TODO: There are a lot of problems with unloading DLL which uses TBB with automatic initialization + +#if __TBB_DEFINE_MIC + +#ifndef _USRDLL +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" +int TestMain() { + return Harness::Skipped; +} +#endif + +#else /* !__MIC__ */ + +#if _WIN32 || _WIN64 +#include "tbb/machine/windows_api.h" +#else +#include <dlfcn.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <stdexcept> + +#if TBB_USE_EXCEPTIONS + #include "harness_report.h" +#endif + +#ifdef _USRDLL +#include "tbb/task_scheduler_init.h" + +class CModel { +public: + CModel(void) {}; + static tbb::task_scheduler_init tbb_init; + + void init_and_terminate( int ); +}; + +tbb::task_scheduler_init CModel::tbb_init(1); + +//! Test that task::initialize and task::terminate work when doing nothing else. +/** maxthread is treated as the "maximum" number of worker threads. */ +void CModel::init_and_terminate( int maxthread ) { + for( int i=0; i<200; ++i ) { + switch( i&3 ) { + default: { + tbb::task_scheduler_init init( rand() % maxthread + 1 ); + break; + } + case 0: { + tbb::task_scheduler_init init; + break; + } + case 1: { + tbb::task_scheduler_init init( tbb::task_scheduler_init::automatic ); + break; + } + case 2: { + tbb::task_scheduler_init init( tbb::task_scheduler_init::deferred ); + init.initialize( rand() % maxthread + 1 ); + init.terminate(); + break; + } + } + } +} + +extern "C" +#if _WIN32 || _WIN64 +__declspec(dllexport) +#endif +void plugin_call(int maxthread) +{ + srand(2); + __TBB_TRY { + CModel model; + model.init_and_terminate(maxthread); + } __TBB_CATCH( std::runtime_error& error ) { +#if TBB_USE_EXCEPTIONS + REPORT("ERROR: %s\n", error.what()); +#endif /* TBB_USE_EXCEPTIONS */ + } +} + +#else /* _USRDLL undefined */ + +#include "harness.h" +#include "harness_dynamic_libs.h" +#include "harness_tls.h" + +extern "C" void plugin_call(int); + +void report_error_in(const char* function_name) +{ +#if _WIN32 || _WIN64 + char* message; + int code = GetLastError(); + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, code,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (char*)&message, 0, NULL ); +#else + char* message = (char*)dlerror(); + int code = 0; +#endif + REPORT( "%s failed with error %d: %s\n", function_name, code, message); + +#if _WIN32 || _WIN64 + LocalFree(message); +#endif +} + +typedef void (*PLUGIN_CALL)(int); + +#if __linux__ + #define RML_LIBRARY_NAME(base) TEST_LIBRARY_NAME(base) ".1" +#else + #define RML_LIBRARY_NAME(base) TEST_LIBRARY_NAME(base) +#endif + +int TestMain () { +#if !RML_USE_WCRM + PLUGIN_CALL my_plugin_call; + + LimitTLSKeysTo limitTLS(10); + + Harness::LIBRARY_HANDLE hLib; +#if _WIN32 || _WIN64 + hLib = LoadLibrary("irml.dll"); + if ( !hLib ) + hLib = LoadLibrary("irml_debug.dll"); + if ( !hLib ) + return Harness::Skipped; // No shared RML, skip the test + FreeLibrary(hLib); +#else /* !WIN */ +#if __TBB_ARENA_PER_MASTER + hLib = dlopen(RML_LIBRARY_NAME("libirml"), RTLD_LAZY); + if ( !hLib ) + hLib = dlopen(RML_LIBRARY_NAME("libirml_debug"), RTLD_LAZY); + if ( !hLib ) + return Harness::Skipped; + dlclose(hLib); +#endif /* __TBB_ARENA_PER_MASTER */ +#endif /* OS */ + for( int i=1; i<100; ++i ) { + REMARK("Iteration %d, loading plugin library...\n", i); + hLib = Harness::OpenLibrary(TEST_LIBRARY_NAME("test_model_plugin_dll")); + if ( !hLib ) { +#if !__TBB_NO_IMPLICIT_LINKAGE +#if _WIN32 || _WIN64 + report_error_in("LoadLibrary"); +#else + report_error_in("dlopen"); +#endif + return -1; +#else + return Harness::Skipped; +#endif + } + my_plugin_call = (PLUGIN_CALL)Harness::GetAddress(hLib, "plugin_call"); + if (my_plugin_call==NULL) { +#if _WIN32 || _WIN64 + report_error_in("GetProcAddress"); +#else + report_error_in("dlsym"); +#endif + return -1; + } + REMARK("Calling plugin method...\n"); + my_plugin_call(MaxThread); + + REMARK("Unloading plugin library...\n"); + Harness::CloseLibrary(hLib); + } // end for(1,100) + + return Harness::Done; +#else + return Harness::Skipped; +#endif /* !RML_USE_WCRM */ +} + +#endif//_USRDLL +#endif//__MIC__ + +#endif /*__TBB_WIN8UI_SUPPORT*/ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_multifunction_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_multifunction_node.cpp new file mode 100644 index 00000000..b5af423f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_multifunction_node.cpp @@ -0,0 +1,771 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_ALLOCATOR __TBB_CPF_BUILD + +#include "harness.h" +#include "harness_graph.h" + +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/spin_rw_mutex.h" +#include "test_follows_and_precedes_api.h" + +#if TBB_USE_DEBUG +#define N 16 +#else +#define N 100 +#endif +#define MAX_NODES 4 + +//! Performs test on function nodes with limited concurrency and buffering +/** These tests check: + 1) that the number of executing copies never exceed the concurrency limit + 2) that the node never rejects + 3) that no items are lost + and 4) all of this happens even if there are multiple predecessors and successors +*/ + +template< typename InputType > +struct parallel_put_until_limit : private NoAssign { + + harness_counting_sender<InputType> *my_senders; + + parallel_put_until_limit( harness_counting_sender<InputType> *senders ) : my_senders(senders) {} + + void operator()( int i ) const { + if ( my_senders ) { + my_senders[i].try_put_until_limit(); + } + } + +}; + +//! exercise buffered multifunction_node. +template< typename InputType, typename OutputTuple, typename Body > +void buffered_levels( size_t concurrency, Body body ) { + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type OutputType; + // Do for lc = 1 to concurrency level + for ( size_t lc = 1; lc <= concurrency; ++lc ) { + tbb::flow::graph g; + + // Set the execute_counter back to zero in the harness + harness_graph_multifunction_executor<InputType, OutputTuple>::execute_count = 0; + // Set the number of current executors to zero. + harness_graph_multifunction_executor<InputType, OutputTuple>::current_executors = 0; + // Set the max allowed executors to lc. There is a check in the functor to make sure this is never exceeded. + harness_graph_multifunction_executor<InputType, OutputTuple>::max_executors = lc; + + // Create the function_node with the appropriate concurrency level, and use default buffering + tbb::flow::multifunction_node< InputType, OutputTuple > exe_node( g, lc, body ); + + //Create a vector of identical exe_nodes + std::vector< tbb::flow::multifunction_node< InputType, OutputTuple > > exe_vec(2, exe_node); + + // exercise each of the copied nodes + for (size_t node_idx=0; node_idx<exe_vec.size(); ++node_idx) { + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + // Create num_receivers counting receivers and connect the exe_vec[node_idx] to them. + std::vector< harness_mapped_receiver<OutputType>* > receivers(num_receivers); + for (size_t i = 0; i < num_receivers; i++) { + receivers[i] = new harness_mapped_receiver<OutputType>(g); + } + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( tbb::flow::output_port<0>(exe_vec[node_idx]), *receivers[r] ); + } + + // Do the test with varying numbers of senders + harness_counting_sender<InputType> *senders = NULL; + for (size_t num_senders = 1; num_senders <= MAX_NODES; ++num_senders ) { + // Create num_senders senders, set their message limit each to N, and connect them to the exe_vec[node_idx] + senders = new harness_counting_sender<InputType>[num_senders]; + for (size_t s = 0; s < num_senders; ++s ) { + senders[s].my_limit = N; + tbb::flow::make_edge( senders[s], exe_vec[node_idx] ); + } + + // Initialize the receivers so they know how many senders and messages to check for + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->initialize_map( N, num_senders ); + } + + // Do the test + NativeParallelFor( (int)num_senders, parallel_put_until_limit<InputType>(senders) ); + g.wait_for_all(); + + // confirm that each sender was requested from N times + for (size_t s = 0; s < num_senders; ++s ) { + size_t n = senders[s].my_received; + ASSERT( n == N, NULL ); + ASSERT( senders[s].my_receiver == &exe_vec[node_idx], NULL ); + } + // validate the receivers + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->validate(); + } + delete [] senders; + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( tbb::flow::output_port<0>(exe_vec[node_idx]), *receivers[r] ); + } + ASSERT( exe_vec[node_idx].try_put( InputType() ) == true, NULL ); + g.wait_for_all(); + for (size_t r = 0; r < num_receivers; ++r ) { + // since it's detached, nothing should have changed + receivers[r]->validate(); + } + + for (size_t i = 0; i < num_receivers; i++) { + delete receivers[i]; + } + } + } + } +} + +const size_t Offset = 123; +tbb::atomic<size_t> global_execute_count; + +struct inc_functor { + + tbb::atomic<size_t> local_execute_count; + inc_functor( ) { local_execute_count = 0; } + inc_functor( const inc_functor &f ) { local_execute_count = f.local_execute_count; } + + template<typename output_ports_type> + void operator()( int i, output_ports_type &p ) { + ++global_execute_count; + ++local_execute_count; + (void)tbb::flow::get<0>(p).try_put(i); + } + +}; + +template< typename InputType, typename OutputTuple > +void buffered_levels_with_copy( size_t concurrency ) { + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type OutputType; + // Do for lc = 1 to concurrency level + for ( size_t lc = 1; lc <= concurrency; ++lc ) { + tbb::flow::graph g; + + inc_functor cf; + cf.local_execute_count = Offset; + global_execute_count = Offset; + + tbb::flow::multifunction_node< InputType, OutputTuple > exe_node( g, lc, cf ); + + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + + std::vector< harness_mapped_receiver<OutputType>* > receivers(num_receivers); + for (size_t i = 0; i < num_receivers; i++) { + receivers[i] = new harness_mapped_receiver<OutputType>(g); + } + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( tbb::flow::output_port<0>(exe_node), *receivers[r] ); + } + + harness_counting_sender<InputType> *senders = NULL; + for (size_t num_senders = 1; num_senders <= MAX_NODES; ++num_senders ) { + senders = new harness_counting_sender<InputType>[num_senders]; + for (size_t s = 0; s < num_senders; ++s ) { + senders[s].my_limit = N; + tbb::flow::make_edge( senders[s], exe_node ); + } + + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->initialize_map( N, num_senders ); + } + + NativeParallelFor( (int)num_senders, parallel_put_until_limit<InputType>(senders) ); + g.wait_for_all(); + + for (size_t s = 0; s < num_senders; ++s ) { + size_t n = senders[s].my_received; + ASSERT( n == N, NULL ); + ASSERT( senders[s].my_receiver == &exe_node, NULL ); + } + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->validate(); + } + delete [] senders; + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( tbb::flow::output_port<0>(exe_node), *receivers[r] ); + } + ASSERT( exe_node.try_put( InputType() ) == true, NULL ); + g.wait_for_all(); + for (size_t r = 0; r < num_receivers; ++r ) { + receivers[r]->validate(); + } + + for (size_t i = 0; i < num_receivers; i++) { + delete receivers[i]; + } + } + + // validate that the local body matches the global execute_count and both are correct + inc_functor body_copy = tbb::flow::copy_body<inc_functor>( exe_node ); + const size_t expected_count = N/2 * MAX_NODES * MAX_NODES * ( MAX_NODES + 1 ) + MAX_NODES + Offset; + size_t global_count = global_execute_count; + size_t inc_count = body_copy.local_execute_count; + ASSERT( global_count == expected_count && global_count == inc_count, NULL ); + } +} + +template< typename InputType, typename OutputTuple > +void run_buffered_levels( int c ) { + #if __TBB_CPP11_LAMBDAS_PRESENT + typedef typename tbb::flow::multifunction_node<InputType,OutputTuple>::output_ports_type output_ports_type; + buffered_levels<InputType,OutputTuple>( c, []( InputType i, output_ports_type &p ) { harness_graph_multifunction_executor<InputType, OutputTuple>::func(i,p); } ); + #endif + buffered_levels<InputType,OutputTuple>( c, &harness_graph_multifunction_executor<InputType, OutputTuple>::func ); + buffered_levels<InputType,OutputTuple>( c, typename harness_graph_multifunction_executor<InputType, OutputTuple>::functor() ); + buffered_levels_with_copy<InputType,OutputTuple>( c ); +} + + +//! Performs test on executable nodes with limited concurrency +/** These tests check: + 1) that the nodes will accepts puts up to the concurrency limit, + 2) the nodes do not exceed the concurrency limit even when run with more threads (this is checked in the harness_graph_executor), + 3) the nodes will receive puts from multiple successors simultaneously, + and 4) the nodes will send to multiple predecessors. + There is no checking of the contents of the messages for corruption. +*/ + +template< typename InputType, typename OutputTuple, typename Body > +void concurrency_levels( size_t concurrency, Body body ) { + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type OutputType; + for ( size_t lc = 1; lc <= concurrency; ++lc ) { + tbb::flow::graph g; + + // Set the execute_counter back to zero in the harness + harness_graph_multifunction_executor<InputType, OutputTuple>::execute_count = 0; + // Set the number of current executors to zero. + harness_graph_multifunction_executor<InputType, OutputTuple>::current_executors = 0; + // Set the max allowed executors to lc. There is a check in the functor to make sure this is never exceeded. + harness_graph_multifunction_executor<InputType, OutputTuple>::max_executors = lc; + + + tbb::flow::multifunction_node< InputType, OutputTuple, tbb::flow::rejecting > exe_node( g, lc, body ); + + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + + std::vector< harness_counting_receiver<OutputType> > receivers(num_receivers, harness_counting_receiver<OutputType>(g)); + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( tbb::flow::output_port<0>(exe_node), receivers[r] ); + } + + harness_counting_sender<InputType> *senders = NULL; + + for (size_t num_senders = 1; num_senders <= MAX_NODES; ++num_senders ) { + { + // Exclusively lock m to prevent exe_node from finishing + tbb::spin_rw_mutex::scoped_lock l( harness_graph_multifunction_executor< InputType, OutputTuple>::template mutex_holder<tbb::spin_rw_mutex>::mutex ); + + // put to lc level, it will accept and then block at m + for ( size_t c = 0 ; c < lc ; ++c ) { + ASSERT( exe_node.try_put( InputType() ) == true, NULL ); + } + // it only accepts to lc level + ASSERT( exe_node.try_put( InputType() ) == false, NULL ); + + senders = new harness_counting_sender<InputType>[num_senders]; + for (size_t s = 0; s < num_senders; ++s ) { + // register a sender + senders[s].my_limit = N; + exe_node.register_predecessor( senders[s] ); + } + + } // release lock at end of scope, setting the exe node free to continue + // wait for graph to settle down + g.wait_for_all(); + + // confirm that each sender was requested from N times + for (size_t s = 0; s < num_senders; ++s ) { + size_t n = senders[s].my_received; + ASSERT( n == N, NULL ); + ASSERT( senders[s].my_receiver == &exe_node, NULL ); + } + // confirm that each receivers got N * num_senders + the initial lc puts + for (size_t r = 0; r < num_receivers; ++r ) { + size_t n = receivers[r].my_count; + ASSERT( n == num_senders*N+lc, NULL ); + receivers[r].my_count = 0; + } + delete [] senders; + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( tbb::flow::output_port<0>(exe_node), receivers[r] ); + } + ASSERT( exe_node.try_put( InputType() ) == true, NULL ); + g.wait_for_all(); + for (size_t r = 0; r < num_receivers; ++r ) { + ASSERT( int(receivers[r].my_count) == 0, NULL ); + } + } + } +} + +template< typename InputType, typename OutputTuple > +void run_concurrency_levels( int c ) { + #if __TBB_CPP11_LAMBDAS_PRESENT + typedef typename tbb::flow::multifunction_node<InputType,OutputTuple>::output_ports_type output_ports_type; + concurrency_levels<InputType,OutputTuple>( c, []( InputType i, output_ports_type &p ) { harness_graph_multifunction_executor<InputType, OutputTuple>::template tfunc<tbb::spin_rw_mutex>(i,p); } ); + #endif + concurrency_levels<InputType,OutputTuple>( c, &harness_graph_multifunction_executor<InputType, OutputTuple>::template tfunc<tbb::spin_rw_mutex> ); + concurrency_levels<InputType,OutputTuple>( c, typename harness_graph_multifunction_executor<InputType, OutputTuple>::template tfunctor<tbb::spin_rw_mutex>() ); +} + + +struct empty_no_assign { + empty_no_assign() {} + empty_no_assign( int ) {} + operator int() { return 0; } + operator int() const { return 0; } +}; + +template< typename InputType > +struct parallel_puts : private NoAssign { + + tbb::flow::receiver< InputType > * const my_exe_node; + + parallel_puts( tbb::flow::receiver< InputType > &exe_node ) : my_exe_node(&exe_node) {} + + void operator()( int ) const { + for ( int i = 0; i < N; ++i ) { + // the nodes will accept all puts + ASSERT( my_exe_node->try_put( InputType() ) == true, NULL ); + } + } + +}; + +//! Performs test on executable nodes with unlimited concurrency +/** These tests check: + 1) that the nodes will accept all puts + 2) the nodes will receive puts from multiple predecessors simultaneously, + and 3) the nodes will send to multiple successors. + There is no checking of the contents of the messages for corruption. +*/ + +template< typename InputType, typename OutputTuple, typename Body > +void unlimited_concurrency( Body body ) { + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type OutputType; + + for (int p = 1; p < 2*MaxThread; ++p) { + tbb::flow::graph g; + tbb::flow::multifunction_node< InputType, OutputTuple, tbb::flow::rejecting > exe_node( g, tbb::flow::unlimited, body ); + + for (size_t num_receivers = 1; num_receivers <= MAX_NODES; ++num_receivers ) { + std::vector< harness_counting_receiver<OutputType> > receivers(num_receivers, harness_counting_receiver<OutputType>(g)); + + harness_graph_multifunction_executor<InputType, OutputTuple>::execute_count = 0; + + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::make_edge( tbb::flow::output_port<0>(exe_node), receivers[r] ); + } + + NativeParallelFor( p, parallel_puts<InputType>(exe_node) ); + g.wait_for_all(); + + // 2) the nodes will receive puts from multiple predecessors simultaneously, + size_t ec = harness_graph_multifunction_executor<InputType, OutputTuple>::execute_count; + ASSERT( (int)ec == p*N, NULL ); + for (size_t r = 0; r < num_receivers; ++r ) { + size_t c = receivers[r].my_count; + // 3) the nodes will send to multiple successors. + ASSERT( (int)c == p*N, NULL ); + } + for (size_t r = 0; r < num_receivers; ++r ) { + tbb::flow::remove_edge( tbb::flow::output_port<0>(exe_node), receivers[r] ); + } + } + } +} + +template< typename InputType, typename OutputTuple > +void run_unlimited_concurrency() { + harness_graph_multifunction_executor<InputType, OutputTuple>::max_executors = 0; + #if __TBB_CPP11_LAMBDAS_PRESENT + typedef typename tbb::flow::multifunction_node<InputType,OutputTuple>::output_ports_type output_ports_type; + unlimited_concurrency<InputType,OutputTuple>( []( InputType i, output_ports_type &p ) { harness_graph_multifunction_executor<InputType, OutputTuple>::func(i,p); } ); + #endif + unlimited_concurrency<InputType,OutputTuple>( &harness_graph_multifunction_executor<InputType, OutputTuple>::func ); + unlimited_concurrency<InputType,OutputTuple>( typename harness_graph_multifunction_executor<InputType, OutputTuple>::functor() ); +} + +template<typename InputType, typename OutputTuple> +struct oddEvenBody { + typedef typename tbb::flow::multifunction_node<InputType,OutputTuple>::output_ports_type output_ports_type; + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type EvenType; + typedef typename tbb::flow::tuple_element<1,OutputTuple>::type OddType; + void operator() (const InputType &i, output_ports_type &p) { + if((int)i % 2) { + (void)tbb::flow::get<1>(p).try_put(OddType(i)); + } + else { + (void)tbb::flow::get<0>(p).try_put(EvenType(i)); + } + } +}; + +template<typename InputType, typename OutputTuple > +void run_multiport_test(int num_threads) { + typedef typename tbb::flow::multifunction_node<InputType, OutputTuple> mo_node_type; + typedef typename tbb::flow::tuple_element<0,OutputTuple>::type EvenType; + typedef typename tbb::flow::tuple_element<1,OutputTuple>::type OddType; + tbb::task_scheduler_init init(num_threads); + tbb::flow::graph g; + mo_node_type mo_node(g, tbb::flow::unlimited, oddEvenBody<InputType, OutputTuple>() ); + + tbb::flow::queue_node<EvenType> q0(g); + tbb::flow::queue_node<OddType> q1(g); + + tbb::flow::make_edge(tbb::flow::output_port<0>(mo_node), q0); + tbb::flow::make_edge(tbb::flow::output_port<1>(mo_node), q1); + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(mo_node.predecessor_count() == 0, NULL); + ASSERT(tbb::flow::output_port<0>(mo_node).successor_count() == 1, NULL); + typedef typename mo_node_type::output_ports_type oports_type; + typedef typename tbb::flow::tuple_element<0,oports_type>::type port0_type; + typename port0_type::successor_list_type my_0succs; + tbb::flow::output_port<0>(mo_node).copy_successors(my_0succs); + ASSERT(my_0succs.size() == 1, NULL); + typename mo_node_type::predecessor_list_type my_preds; + mo_node.copy_predecessors(my_preds); + ASSERT(my_preds.size() == 0, NULL); +#endif + + for(InputType i = 0; i < N; ++i) { + mo_node.try_put(i); + } + + g.wait_for_all(); + for(int i = 0; i < N/2; ++i) { + EvenType e; + OddType o; + ASSERT(q0.try_get(e) && (int)e % 2 == 0, NULL); + ASSERT(q1.try_get(o) && (int)o % 2 == 1, NULL); + } +} + +//! Tests limited concurrency cases for nodes that accept data messages +void test_concurrency(int num_threads) { + tbb::task_scheduler_init init(num_threads); + run_concurrency_levels<int,tbb::flow::tuple<int> >(num_threads); + run_concurrency_levels<int,tbb::flow::tuple<tbb::flow::continue_msg> >(num_threads); + run_buffered_levels<int, tbb::flow::tuple<int> >(num_threads); + run_unlimited_concurrency<int, tbb::flow::tuple<int> >(); + run_unlimited_concurrency<int,tbb::flow::tuple<empty_no_assign> >(); + run_unlimited_concurrency<empty_no_assign,tbb::flow::tuple<int> >(); + run_unlimited_concurrency<empty_no_assign,tbb::flow::tuple<empty_no_assign> >(); + run_unlimited_concurrency<int,tbb::flow::tuple<tbb::flow::continue_msg> >(); + run_unlimited_concurrency<empty_no_assign,tbb::flow::tuple<tbb::flow::continue_msg> >(); + run_multiport_test<int, tbb::flow::tuple<int, int> >(num_threads); + run_multiport_test<float, tbb::flow::tuple<int, double> >(num_threads); +} + +template<typename Policy> +void test_ports_return_references() { + tbb::flow::graph g; + typedef int InputType; + typedef tbb::flow::tuple<int> OutputTuple; + tbb::flow::multifunction_node<InputType, OutputTuple, Policy> mf_node( + g, tbb::flow::unlimited, + &harness_graph_multifunction_executor<InputType, OutputTuple>::empty_func ); + test_output_ports_return_ref(mf_node); +} + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +// the integer received indicates which output ports should succeed and which should fail +// on try_put(). +typedef tbb::flow::multifunction_node<int, tbb::flow::tuple<int, int> > mf_node_type; + +struct add_to_counter { + int my_invocations; + int *counter; + add_to_counter(int& var):counter(&var){ my_invocations = 0;} + void operator()(const int &i, mf_node_type::output_ports_type &outports) { + *counter+=1; + ++my_invocations; + if(i & 0x1) { + ASSERT(tbb::flow::get<0>(outports).try_put(i), "port 0 expected to succeed"); + } + else { + ASSERT(!tbb::flow::get<0>(outports).try_put(i), "port 0 expected to fail"); + } + if(i & 0x2) { + ASSERT(tbb::flow::get<1>(outports).try_put(i), "port 1 expected to succeed"); + } + else { + ASSERT(!tbb::flow::get<1>(outports).try_put(i), "port 1 expected to fail"); + } + } + int my_inner() { return my_invocations; } +}; + +template<class FTYPE> +void test_extract() { + int my_count = 0; + int cm; + tbb::flow::graph g; + tbb::flow::broadcast_node<int> b0(g); + tbb::flow::broadcast_node<int> b1(g); + tbb::flow::multifunction_node<int, tbb::flow::tuple<int,int>, FTYPE> mf0(g, tbb::flow::unlimited, add_to_counter(my_count)); + tbb::flow::queue_node<int> q0(g); + tbb::flow::queue_node<int> q1(g); + + tbb::flow::make_edge(b0, mf0); + tbb::flow::make_edge(b1, mf0); + tbb::flow::make_edge(tbb::flow::output_port<0>(mf0), q0); + tbb::flow::make_edge(tbb::flow::output_port<1>(mf0), q1); + for( int i = 0; i < 2; ++i ) { + + /* b0 */ + /* \ |--q0 */ + /* mf0+ */ + /* / |--q1 */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 1, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 1, "b1 has incorrect counts"); + ASSERT(mf0.predecessor_count() == 2 + && tbb::flow::output_port<0>(mf0).successor_count() == 1 + && tbb::flow::output_port<1>(mf0).successor_count() == 1 + , "mf0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 1 && q0.successor_count() == 0, "q0 has incorrect counts"); + ASSERT(q1.predecessor_count() == 1 && q1.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(3); + g.wait_for_all(); + ASSERT(my_count == 1, "multifunction_node didn't fire"); + ASSERT(q0.try_get(cm), "multifunction_node didn't forward to 0"); + ASSERT(q1.try_get(cm), "multifunction_node didn't forward to 1"); + b1.try_put(3); + g.wait_for_all(); + ASSERT(my_count == 2, "multifunction_node didn't fire"); + ASSERT(q0.try_get(cm), "multifunction_node didn't forward to 0"); + ASSERT(q1.try_get(cm), "multifunction_node didn't forward to 1"); + + b0.extract(); + + + /* b0 */ + /* |--q0 */ + /* mf0+ */ + /* / |--q1 */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 0, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 1, "b1 has incorrect counts"); + ASSERT(mf0.predecessor_count() == 1 + && tbb::flow::output_port<0>(mf0).successor_count() == 1 + && tbb::flow::output_port<1>(mf0).successor_count() == 1 + , "mf0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 1 && q0.successor_count() == 0, "q0 has incorrect counts"); + ASSERT(q1.predecessor_count() == 1 && q1.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(1); + b0.try_put(1); + g.wait_for_all(); + ASSERT(my_count == 2, "b0 messages being forwarded to multifunction_node even though it is disconnected"); + b1.try_put(3); + g.wait_for_all(); + ASSERT(my_count == 3, "multifunction_node didn't fire though it has only one predecessor"); + ASSERT(q0.try_get(cm), "multifunction_node didn't forward second time"); + ASSERT(q1.try_get(cm), "multifunction_node didn't forward second time"); + + q0.extract(); + + /* b0 */ + /* | q0 */ + /* mf0+ */ + /* / |--q1 */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 0, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 1, "b1 has incorrect counts"); + ASSERT(mf0.predecessor_count() == 1 + && tbb::flow::output_port<0>(mf0).successor_count() == 0 + && tbb::flow::output_port<1>(mf0).successor_count() == 1 + , "mf0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 0 && q0.successor_count() == 0, "q0 has incorrect counts"); + ASSERT(q1.predecessor_count() == 1 && q1.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(1); + b0.try_put(1); + g.wait_for_all(); + ASSERT(my_count == 3, "b0 messages being forwarded to multifunction_node even though it is disconnected"); + b1.try_put(2); + g.wait_for_all(); + ASSERT(my_count == 4, "multifunction_node didn't fire though it has one predecessor"); + ASSERT(!q0.try_get(cm), "multifunction_node forwarded"); + ASSERT(q1.try_get(cm), "multifunction_node forwarded"); + mf0.extract(); + + if(i == 0) { + } + else { + g.reset(tbb::flow::rf_reset_bodies); + } + + + /* b0 */ + /* | q0 */ + /* mf0+ */ + /* | q1 */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 0, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 0, "b1 has incorrect counts"); + ASSERT(mf0.predecessor_count() == 0 + && tbb::flow::output_port<0>(mf0).successor_count() == 0 + && tbb::flow::output_port<1>(mf0).successor_count() == 0 + , "mf0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 0 && q0.successor_count() == 0, "q0 has incorrect counts"); + ASSERT(q1.predecessor_count() == 0 && q1.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(1); + b0.try_put(1); + g.wait_for_all(); + ASSERT(my_count == 4, "b0 messages being forwarded to multifunction_node even though it is disconnected"); + b1.try_put(2); + g.wait_for_all(); + ASSERT(my_count == 4, "b1 messages being forwarded to multifunction_node even though it is disconnected"); + ASSERT(!q0.try_get(cm), "multifunction_node forwarded"); + ASSERT(!q1.try_get(cm), "multifunction_node forwarded"); + make_edge(b0, mf0); + + /* b0 */ + /* \ | q0 */ + /* mf0+ */ + /* | q1 */ + /* b1 */ + + ASSERT(b0.predecessor_count() == 0 && b0.successor_count() == 1, "b0 has incorrect counts"); + ASSERT(b1.predecessor_count() == 0 && b1.successor_count() == 0, "b1 has incorrect counts"); + ASSERT(mf0.predecessor_count() == 1 + && tbb::flow::output_port<0>(mf0).successor_count() == 0 + && tbb::flow::output_port<1>(mf0).successor_count() == 0 + , "mf0 has incorrect counts"); + ASSERT(q0.predecessor_count() == 0 && q0.successor_count() == 0, "q0 has incorrect counts"); + ASSERT(q1.predecessor_count() == 0 && q1.successor_count() == 0, "q0 has incorrect counts"); + b0.try_put(0); + g.wait_for_all(); + ASSERT(my_count == 5, "multifunction_node didn't fire though it has one predecessor"); + b1.try_put(2); + g.wait_for_all(); + ASSERT(my_count == 5, "multifunction_node fired though it has only one predecessor"); + ASSERT(!q0.try_get(cm), "multifunction_node forwarded"); + ASSERT(!q1.try_get(cm), "multifunction_node forwarded"); + + tbb::flow::make_edge(b1, mf0); + tbb::flow::make_edge(tbb::flow::output_port<0>(mf0), q0); + tbb::flow::make_edge(tbb::flow::output_port<1>(mf0), q1); + ASSERT( ( i == 0 && tbb::flow::copy_body<add_to_counter>(mf0).my_inner() == 5 ) || + ( i == 1 && tbb::flow::copy_body<add_to_counter>(mf0).my_inner() == 1 ) , "reset_bodies failed"); + my_count = 0; + } +} +#endif + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> + +void test_precedes() { + using namespace tbb::flow; + + using multinode = multifunction_node<int, std::tuple<int, int>>; + + graph g; + + buffer_node<int> b1(g); + buffer_node<int> b2(g); + + multinode node(precedes(b1, b2), unlimited, [](const int& i, multinode::output_ports_type& op) -> void { + if (i % 2) + std::get<0>(op).try_put(i); + else + std::get<1>(op).try_put(i); + } + ); + + node.try_put(0); + node.try_put(1); + g.wait_for_all(); + + int storage; + ASSERT((b1.try_get(storage) && !b1.try_get(storage) && b2.try_get(storage) && !b2.try_get(storage)), + "Not exact edge quantity was made"); +} + +void test_follows_and_precedes_api() { + using multinode = tbb::flow::multifunction_node<int, std::tuple<int, int, int>>; + + std::array<int, 3> messages_for_follows = { {0, 1, 2} }; + + follows_and_precedes_testing::test_follows + <int, tbb::flow::multifunction_node<int, std::tuple<int, int, int>>> + (messages_for_follows, tbb::flow::unlimited, [](const int& i, multinode::output_ports_type& op) -> void { + std::get<0>(op).try_put(i); + }); + + test_precedes(); +} +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +typedef tbb::flow::multifunction_node< int, tbb::flow::tuple<int>, + tbb::flow::queueing, + std::allocator<int> > multifunction_type; +struct multipass_through { + void operator()( int, multifunction_type::output_ports_type& ) {} +}; + +void test_node_allocator() { + tbb::flow::graph g; + multifunction_type tmp( + g, tbb::flow::unlimited, multipass_through() + ); +} +#endif + +int TestMain() { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + test_concurrency(p); + } + test_ports_return_references<tbb::flow::queueing>(); + test_ports_return_references<tbb::flow::rejecting>(); + lightweight_testing::test<tbb::flow::multifunction_node>(10); +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract<tbb::flow::rejecting>(); + test_extract<tbb::flow::queueing>(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + test_node_allocator(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_mutex.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_mutex.cpp new file mode 100644 index 00000000..81c2d526 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_mutex.cpp @@ -0,0 +1,711 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +//------------------------------------------------------------------------ +// Test TBB mutexes when used with parallel_for.h +// +// Usage: test_Mutex.exe [-v] nthread +// +// The -v option causes timing information to be printed. +// +// Compile with _OPENMP and -openmp +//------------------------------------------------------------------------ +#include "harness_defs.h" +#include "tbb/spin_mutex.h" +#include "tbb/critical_section.h" +#include "tbb/spin_rw_mutex.h" +#include "tbb/queuing_rw_mutex.h" +#include "tbb/queuing_mutex.h" +#include "tbb/mutex.h" +#include "tbb/recursive_mutex.h" +#include "tbb/null_mutex.h" +#include "tbb/null_rw_mutex.h" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" +#include "tbb/tick_count.h" +#include "tbb/atomic.h" +#include "harness.h" +#include <cstdlib> +#include <cstdio> +#if _OPENMP +#include "test/OpenMP_Mutex.h" +#endif /* _OPENMP */ +#include "tbb/tbb_profiling.h" + +#ifndef TBB_TEST_LOW_WORKLOAD + #define TBB_TEST_LOW_WORKLOAD TBB_USE_THREADING_TOOLS +#endif + +// This test deliberately avoids a "using tbb" statement, +// so that the error of putting types in the wrong namespace will be caught. + +template<typename M> +struct Counter { + typedef M mutex_type; + M mutex; + volatile long value; +}; + +//! Function object for use with parallel_for.h. +template<typename C> +struct AddOne: NoAssign { + C& counter; + /** Increments counter once for each iteration in the iteration space. */ + void operator()( tbb::blocked_range<size_t>& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + if( i&1 ) { + // Try implicit acquire and explicit release + typename C::mutex_type::scoped_lock lock(counter.mutex); + counter.value = counter.value+1; + lock.release(); + } else { + // Try explicit acquire and implicit release + typename C::mutex_type::scoped_lock lock; + lock.acquire(counter.mutex); + counter.value = counter.value+1; + } + } + } + AddOne( C& counter_ ) : counter(counter_) {} +}; + +//! Adaptor for using ISO C++0x style mutex as a TBB-style mutex. +template<typename M> +class TBB_MutexFromISO_Mutex { + M my_iso_mutex; +public: + typedef TBB_MutexFromISO_Mutex mutex_type; + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock { + mutex_type* my_mutex; + public: + scoped_lock() : my_mutex(NULL) {} + scoped_lock( mutex_type& m ) : my_mutex(NULL) { + acquire(m); + } + scoped_lock( mutex_type& m, bool is_writer ) : my_mutex(NULL) { + acquire(m,is_writer); + } + void acquire( mutex_type& m ) { + m.my_iso_mutex.lock(); + my_mutex = &m; + } + bool try_acquire( mutex_type& m ) { + if( m.my_iso_mutex.try_lock() ) { + my_mutex = &m; + return true; + } else { + return false; + } + } + void release() { + my_mutex->my_iso_mutex.unlock(); + my_mutex = NULL; + } + + // Methods for reader-writer mutex + // These methods can be instantiated only if M supports lock_read() and try_lock_read(). + + void acquire( mutex_type& m, bool is_writer ) { + if( is_writer ) m.my_iso_mutex.lock(); + else m.my_iso_mutex.lock_read(); + my_mutex = &m; + } + bool try_acquire( mutex_type& m, bool is_writer ) { + if( is_writer ? m.my_iso_mutex.try_lock() : m.my_iso_mutex.try_lock_read() ) { + my_mutex = &m; + return true; + } else { + return false; + } + } + bool upgrade_to_writer() { + my_mutex->my_iso_mutex.unlock(); + my_mutex->my_iso_mutex.lock(); + return false; + } + bool downgrade_to_reader() { + my_mutex->my_iso_mutex.unlock(); + my_mutex->my_iso_mutex.lock_read(); + return false; + } + ~scoped_lock() { + if( my_mutex ) + release(); + } + }; + + static const bool is_recursive_mutex = M::is_recursive_mutex; + static const bool is_rw_mutex = M::is_rw_mutex; +}; + +namespace tbb { + namespace profiling { + template<typename M> + void set_name( const TBB_MutexFromISO_Mutex<M>&, const char* ) {} + } +} + +//! Generic test of a TBB mutex type M. +/** Does not test features specific to reader-writer locks. */ +template<typename M> +void Test( const char * name ) { + REMARK("%s size == %d, time = ",name, sizeof(M)); + Counter<M> counter; + counter.value = 0; + tbb::profiling::set_name(counter.mutex, name); +#if TBB_TEST_LOW_WORKLOAD + const int n = 10000; +#else + const int n = 100000; +#endif /* TBB_TEST_LOW_WORKLOAD */ + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for(tbb::blocked_range<size_t>(0,n,n/10),AddOne<Counter<M> >(counter)); + tbb::tick_count t1 = tbb::tick_count::now(); + REMARK("%g usec\n",(t1-t0).seconds()); + if( counter.value!=n ) + REPORT("ERROR for %s: counter.value=%ld\n",name,counter.value); +} + +template<typename M, size_t N> +struct Invariant { + typedef M mutex_type; + M mutex; + const char* mutex_name; + volatile long value[N]; + Invariant( const char* mutex_name_ ) : + mutex_name(mutex_name_) + { + for( size_t k=0; k<N; ++k ) + value[k] = 0; + tbb::profiling::set_name(mutex, mutex_name_); + } + ~Invariant() { + } + void update() { + for( size_t k=0; k<N; ++k ) + ++value[k]; + } + bool value_is( long expected_value ) const { + long tmp; + for( size_t k=0; k<N; ++k ) + if( (tmp=value[k])!=expected_value ) { + REPORT("ERROR: %ld!=%ld\n", tmp, expected_value); + return false; + } + return true; + } + bool is_okay() { + return value_is( value[0] ); + } +}; + +//! Function object for use with parallel_for.h. +template<typename I> +struct TwiddleInvariant: NoAssign { + I& invariant; + TwiddleInvariant( I& invariant_ ) : invariant(invariant_) {} + + /** Increments counter once for each iteration in the iteration space. */ + void operator()( tbb::blocked_range<size_t>& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + //! Every 8th access is a write access + const bool write = (i%8)==7; + bool okay = true; + bool lock_kept = true; + if( (i/8)&1 ) { + // Try implicit acquire and explicit release + typename I::mutex_type::scoped_lock lock(invariant.mutex,write); + execute_aux(lock, i, write, /*ref*/okay, /*ref*/lock_kept); + lock.release(); + } else { + // Try explicit acquire and implicit release + typename I::mutex_type::scoped_lock lock; + lock.acquire(invariant.mutex,write); + execute_aux(lock, i, write, /*ref*/okay, /*ref*/lock_kept); + } + if( !okay ) { + REPORT( "ERROR for %s at %ld: %s %s %s %s\n",invariant.mutex_name, long(i), + write ? "write," : "read,", + write ? (i%16==7?"downgrade,":"") : (i%8==3?"upgrade,":""), + lock_kept ? "lock kept," : "lock not kept,", // TODO: only if downgrade/upgrade + (i/8)&1 ? "impl/expl" : "expl/impl" ); + } + } + } +private: + void execute_aux(typename I::mutex_type::scoped_lock & lock, const size_t i, const bool write, bool & okay, bool & lock_kept) const { + if( write ) { + long my_value = invariant.value[0]; + invariant.update(); + if( i%16==7 ) { + lock_kept = lock.downgrade_to_reader(); + if( !lock_kept ) + my_value = invariant.value[0] - 1; + okay = invariant.value_is(my_value+1); + } + } else { + okay = invariant.is_okay(); + if( i%8==3 ) { + long my_value = invariant.value[0]; + lock_kept = lock.upgrade_to_writer(); + if( !lock_kept ) + my_value = invariant.value[0]; + invariant.update(); + okay = invariant.value_is(my_value+1); + } + } + } +}; + +/** This test is generic so that we can test any other kinds of ReaderWriter locks we write later. */ +template<typename M> +void TestReaderWriterLock( const char * mutex_name ) { + REMARK( "%s readers & writers time = ", mutex_name ); + Invariant<M,8> invariant(mutex_name); +#if TBB_TEST_LOW_WORKLOAD + const size_t n = 10000; +#else + const size_t n = 500000; +#endif /* TBB_TEST_LOW_WORKLOAD */ + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for(tbb::blocked_range<size_t>(0,n,n/100),TwiddleInvariant<Invariant<M,8> >(invariant)); + tbb::tick_count t1 = tbb::tick_count::now(); + // There is either a writer or a reader upgraded to a writer for each 4th iteration + long expected_value = n/4; + if( !invariant.value_is(expected_value) ) + REPORT("ERROR for %s: final invariant value is wrong\n",mutex_name); + REMARK( "%g usec\n", (t1-t0).seconds() ); +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress "conditional expression is constant" warning. + #pragma warning( push ) + #pragma warning( disable: 4127 ) +#endif + +/** Test try_acquire_reader functionality of a non-reenterable reader-writer mutex */ +template<typename M> +void TestTryAcquireReader_OneThread( const char * mutex_name ) { + M tested_mutex; + typename M::scoped_lock lock1; + if( M::is_rw_mutex ) { + if( lock1.try_acquire(tested_mutex, false) ) + lock1.release(); + else + REPORT("ERROR for %s: try_acquire failed though it should not\n", mutex_name); + { + typename M::scoped_lock lock2(tested_mutex, false); // read lock + if( lock1.try_acquire(tested_mutex) ) // attempt to acquire read + REPORT("ERROR for %s: try_acquire succeeded though it should not (1)\n", mutex_name); + lock2.release(); // unlock + lock2.acquire(tested_mutex, true); // write lock + if( lock1.try_acquire(tested_mutex, false) ) // attempt to acquire read + REPORT("ERROR for %s: try_acquire succeeded though it should not (2)\n", mutex_name); + } + if( lock1.try_acquire(tested_mutex, false) ) + lock1.release(); + else + REPORT("ERROR for %s: try_acquire failed though it should not\n", mutex_name); + } +} + +/** Test try_acquire functionality of a non-reenterable mutex */ +template<typename M> +void TestTryAcquire_OneThread( const char * mutex_name ) { + M tested_mutex; + typename M::scoped_lock lock1; + if( lock1.try_acquire(tested_mutex) ) + lock1.release(); + else + REPORT("ERROR for %s: try_acquire failed though it should not\n", mutex_name); + { + if( M::is_recursive_mutex ) { + typename M::scoped_lock lock2(tested_mutex); + if( lock1.try_acquire(tested_mutex) ) + lock1.release(); + else + REPORT("ERROR for %s: try_acquire on recursive lock failed though it should not\n", mutex_name); + //windows.. -- both are recursive + } else { + typename M::scoped_lock lock2(tested_mutex); + if( lock1.try_acquire(tested_mutex) ) + REPORT("ERROR for %s: try_acquire succeeded though it should not (3)\n", mutex_name); + } + } + if( lock1.try_acquire(tested_mutex) ) + lock1.release(); + else + REPORT("ERROR for %s: try_acquire failed though it should not\n", mutex_name); +} + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning( pop ) +#endif + +const int RecurN = 4; +int RecurArray[ RecurN ]; +tbb::recursive_mutex RecurMutex[ RecurN ]; + +struct RecursiveAcquisition { + /** x = number being decoded in base N + max_lock = index of highest lock acquired so far + mask = bit mask; ith bit set if lock i has been acquired. */ + void Body( size_t x, int max_lock=-1, unsigned int mask=0 ) const + { + int i = (int) (x % RecurN); + bool first = (mask&1U<<i)==0; + if( first ) { + // first time to acquire lock + if( i<max_lock ) + // out of order acquisition might lead to deadlock, so stop + return; + max_lock = i; + } + + if( (i&1)!=0 ) { + // acquire lock on location RecurArray[i] using explicit acquire + tbb::recursive_mutex::scoped_lock r_lock; + r_lock.acquire( RecurMutex[i] ); + int a = RecurArray[i]; + ASSERT( (a==0)==first, "should be either a==0 if it is the first time to acquire the lock or a!=0 otherwise" ); + ++RecurArray[i]; + if( x ) + Body( x/RecurN, max_lock, mask|1U<<i ); + --RecurArray[i]; + ASSERT( a==RecurArray[i], "a is not equal to RecurArray[i]" ); + + // release lock on location RecurArray[i] using explicit release; otherwise, use implicit one + if( (i&2)!=0 ) r_lock.release(); + } else { + // acquire lock on location RecurArray[i] using implicit acquire + tbb::recursive_mutex::scoped_lock r_lock( RecurMutex[i] ); + int a = RecurArray[i]; + + ASSERT( (a==0)==first, "should be either a==0 if it is the first time to acquire the lock or a!=0 otherwise" ); + + ++RecurArray[i]; + if( x ) + Body( x/RecurN, max_lock, mask|1U<<i ); + --RecurArray[i]; + + ASSERT( a==RecurArray[i], "a is not equal to RecurArray[i]" ); + + // release lock on location RecurArray[i] using explicit release; otherwise, use implicit one + if( (i&2)!=0 ) r_lock.release(); + } + } + + void operator()( const tbb::blocked_range<size_t> &r ) const + { + for( size_t x=r.begin(); x<r.end(); x++ ) { + Body( x ); + } + } +}; + +/** This test is generic so that we may test other kinds of recursive mutexes.*/ +template<typename M> +void TestRecursiveMutex( const char * mutex_name ) +{ + for ( int i = 0; i < RecurN; ++i ) { + tbb::profiling::set_name(RecurMutex[i], mutex_name); + } + tbb::tick_count t0 = tbb::tick_count::now(); + tbb::parallel_for(tbb::blocked_range<size_t>(0,10000,500), RecursiveAcquisition()); + tbb::tick_count t1 = tbb::tick_count::now(); + REMARK( "%s recursive mutex time = %g usec\n", mutex_name, (t1-t0).seconds() ); +} + +template<typename C> +struct NullRecursive: NoAssign { + void recurse_till( size_t i, size_t till ) const { + if( i==till ) { + counter.value = counter.value+1; + return; + } + if( i&1 ) { + typename C::mutex_type::scoped_lock lock2(counter.mutex); + recurse_till( i+1, till ); + lock2.release(); + } else { + typename C::mutex_type::scoped_lock lock2; + lock2.acquire(counter.mutex); + recurse_till( i+1, till ); + } + } + + void operator()( tbb::blocked_range<size_t>& range ) const { + typename C::mutex_type::scoped_lock lock(counter.mutex); + recurse_till( range.begin(), range.end() ); + } + NullRecursive( C& counter_ ) : counter(counter_) { + ASSERT( C::mutex_type::is_recursive_mutex, "Null mutex should be a recursive mutex." ); + } + C& counter; +}; + +template<typename M> +struct NullUpgradeDowngrade: NoAssign { + void operator()( tbb::blocked_range<size_t>& range ) const { + typename M::scoped_lock lock2; + for( size_t i=range.begin(); i!=range.end(); ++i ) { + if( i&1 ) { + typename M::scoped_lock lock1(my_mutex, true) ; + if( lock1.downgrade_to_reader()==false ) + REPORT("ERROR for %s: downgrade should always succeed\n", name); + } else { + lock2.acquire( my_mutex, false ); + if( lock2.upgrade_to_writer()==false ) + REPORT("ERROR for %s: upgrade should always succeed\n", name); + lock2.release(); + } + } + } + + NullUpgradeDowngrade( M& m_, const char* n_ ) : my_mutex(m_), name(n_) {} + M& my_mutex; + const char* name; +} ; + +template<typename M> +void TestNullMutex( const char * name ) { + Counter<M> counter; + counter.value = 0; + const int n = 100; + REMARK("TestNullMutex<%s>",name); + { + tbb::parallel_for(tbb::blocked_range<size_t>(0,n,10),AddOne<Counter<M> >(counter)); + } + counter.value = 0; + { + tbb::parallel_for(tbb::blocked_range<size_t>(0,n,10),NullRecursive<Counter<M> >(counter)); + } + REMARK("\n"); +} + +template<typename M> +void TestNullRWMutex( const char * name ) { + REMARK("TestNullRWMutex<%s>",name); + const int n = 100; + M m; + tbb::parallel_for(tbb::blocked_range<size_t>(0,n,10),NullUpgradeDowngrade<M>(m, name)); + REMARK("\n"); +} + +//! Test ISO C++0x compatibility portion of TBB mutex +template<typename M> +void TestISO( const char * name ) { + typedef TBB_MutexFromISO_Mutex<M> tbb_from_iso; + Test<tbb_from_iso>( name ); +} + +//! Test ISO C++0x try_lock functionality of a non-reenterable mutex */ +template<typename M> +void TestTryAcquire_OneThreadISO( const char * name ) { + typedef TBB_MutexFromISO_Mutex<M> tbb_from_iso; + TestTryAcquire_OneThread<tbb_from_iso>( name ); +} + +//! Test ISO-like C++0x compatibility portion of TBB reader-writer mutex +template<typename M> +void TestReaderWriterLockISO( const char * name ) { + typedef TBB_MutexFromISO_Mutex<M> tbb_from_iso; + TestReaderWriterLock<tbb_from_iso>( name ); + TestTryAcquireReader_OneThread<tbb_from_iso>( name ); +} + +//! Test ISO C++0x compatibility portion of TBB recursive mutex +template<typename M> +void TestRecursiveMutexISO( const char * name ) { + typedef TBB_MutexFromISO_Mutex<M> tbb_from_iso; + TestRecursiveMutex<tbb_from_iso>(name); +} + +#include "harness_tsx.h" +#include "tbb/task_scheduler_init.h" + +#if __TBB_TSX_TESTING_ENABLED_FOR_THIS_COMPILER + +//! Function object for use with parallel_for.h to see if a transaction is actually attempted. +tbb::atomic<size_t> n_transactions_attempted; +template<typename C> +struct AddOne_CheckTransaction: NoAssign { + C& counter; + /** Increments counter once for each iteration in the iteration space. */ + void operator()( tbb::blocked_range<size_t>& range ) const { + for( size_t i=range.begin(); i!=range.end(); ++i ) { + bool transaction_attempted = false; + { + typename C::mutex_type::scoped_lock lock(counter.mutex); + if( IsInsideTx() ) transaction_attempted = true; + counter.value = counter.value+1; + } + if( transaction_attempted ) ++n_transactions_attempted; + __TBB_Pause(i); + } + } + AddOne_CheckTransaction( C& counter_ ) : counter(counter_) {} +}; + +/* TestTransaction() checks if a speculative mutex actually uses transactions. */ +template<typename M> +void TestTransaction( const char * name ) +{ + Counter<M> counter; +#if TBB_TEST_LOW_WORKLOAD + const int n = 100; +#else + const int n = 1000; +#endif + REMARK("TestTransaction with %s: ",name); + + n_transactions_attempted = 0; + tbb::tick_count start, stop; + for( int i=0; i<5 && n_transactions_attempted==0; ++i ) { + counter.value = 0; + start = tbb::tick_count::now(); + tbb::parallel_for(tbb::blocked_range<size_t>(0,n,2),AddOne_CheckTransaction<Counter<M> >(counter)); + stop = tbb::tick_count::now(); + if( counter.value!=n ) { + REPORT("ERROR for %s: counter.value=%ld\n",name,counter.value); + break; + } + } + + if( n_transactions_attempted==0 ) + REPORT( "ERROR: transactions were never attempted\n" ); + else + REMARK("%d successful transactions in %6.6f seconds\n", (int)n_transactions_attempted, (stop - start).seconds()); +} +#endif /* __TBB_TSX_TESTING_ENABLED_FOR_THIS_COMPILER */ + +template<typename M> +class RWStateMultipleChangeBody { + M& my_mutex; +public: + RWStateMultipleChangeBody(M& m) : my_mutex(m) {} + + void operator()(const tbb::blocked_range<size_t>& r) const { + typename M::scoped_lock l(my_mutex, /*write=*/false); + for(size_t i = r.begin(); i != r.end(); ++i) { + ASSERT(l.downgrade_to_reader(), "Downgrade must succeed for read lock"); + } + l.upgrade_to_writer(); + for(size_t i = r.begin(); i != r.end(); ++i) { + ASSERT(l.upgrade_to_writer(), "Upgrade must succeed for write lock"); + } + } +}; + +template<typename M> +void TestRWStateMultipleChange() { + ASSERT(M::is_rw_mutex, "Incorrect mutex type"); + size_t n = 10000; + M mutex; + RWStateMultipleChangeBody<M> body(mutex); + tbb::parallel_for(tbb::blocked_range<size_t>(0, n, n/10), body); +} + +int TestMain () { + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init( p ); + REMARK( "testing with %d workers\n", static_cast<int>(p) ); +#if TBB_TEST_LOW_WORKLOAD + // The amount of work is decreased in this mode to bring the length + // of the runs under tools into the tolerable limits. + const int n = 1; +#else + const int n = 3; +#endif + // Run each test several times. + for( int i=0; i<n; ++i ) { + TestNullMutex<tbb::null_mutex>( "Null Mutex" ); + TestNullMutex<tbb::null_rw_mutex>( "Null RW Mutex" ); + TestNullRWMutex<tbb::null_rw_mutex>( "Null RW Mutex" ); + Test<tbb::spin_mutex>( "Spin Mutex" ); + Test<tbb::speculative_spin_mutex>( "Spin Mutex/speculative" ); +#if _OPENMP + Test<OpenMP_Mutex>( "OpenMP_Mutex" ); +#endif /* _OPENMP */ + Test<tbb::queuing_mutex>( "Queuing Mutex" ); + Test<tbb::mutex>( "Wrapper Mutex" ); + Test<tbb::recursive_mutex>( "Recursive Mutex" ); + Test<tbb::queuing_rw_mutex>( "Queuing RW Mutex" ); + Test<tbb::spin_rw_mutex>( "Spin RW Mutex" ); + Test<tbb::speculative_spin_rw_mutex>( "Spin RW Mutex/speculative" ); + + TestTryAcquire_OneThread<tbb::spin_mutex>("Spin Mutex"); + TestTryAcquire_OneThread<tbb::speculative_spin_mutex>("Spin Mutex/speculative"); + TestTryAcquire_OneThread<tbb::queuing_mutex>("Queuing Mutex"); +#if USE_PTHREAD + // under ifdef because on Windows tbb::mutex is reenterable and the test will fail + TestTryAcquire_OneThread<tbb::mutex>("Wrapper Mutex"); +#endif /* USE_PTHREAD */ + TestTryAcquire_OneThread<tbb::recursive_mutex>( "Recursive Mutex" ); + TestTryAcquire_OneThread<tbb::spin_rw_mutex>("Spin RW Mutex"); // only tests try_acquire for writers + TestTryAcquire_OneThread<tbb::speculative_spin_rw_mutex>("Spin RW Mutex/speculative"); // only tests try_acquire for writers + TestTryAcquire_OneThread<tbb::queuing_rw_mutex>("Queuing RW Mutex"); // only tests try_acquire for writers + + TestTryAcquireReader_OneThread<tbb::spin_rw_mutex>("Spin RW Mutex"); + TestTryAcquireReader_OneThread<tbb::speculative_spin_rw_mutex>("Spin RW Mutex/speculative"); + TestTryAcquireReader_OneThread<tbb::queuing_rw_mutex>("Queuing RW Mutex"); + + TestReaderWriterLock<tbb::queuing_rw_mutex>( "Queuing RW Mutex" ); + TestReaderWriterLock<tbb::spin_rw_mutex>( "Spin RW Mutex" ); + TestReaderWriterLock<tbb::speculative_spin_rw_mutex>( "Spin RW Mutex/speculative" ); + + TestRecursiveMutex<tbb::recursive_mutex>( "Recursive Mutex" ); + + // Test ISO C++11 interface + TestISO<tbb::spin_mutex>( "ISO Spin Mutex" ); + TestISO<tbb::mutex>( "ISO Mutex" ); + TestISO<tbb::spin_rw_mutex>( "ISO Spin RW Mutex" ); + TestISO<tbb::recursive_mutex>( "ISO Recursive Mutex" ); + TestISO<tbb::critical_section>( "ISO Critical Section" ); + TestTryAcquire_OneThreadISO<tbb::spin_mutex>( "ISO Spin Mutex" ); +#if USE_PTHREAD + // under ifdef because on Windows tbb::mutex is reenterable and the test will fail + TestTryAcquire_OneThreadISO<tbb::mutex>( "ISO Mutex" ); +#endif /* USE_PTHREAD */ + TestTryAcquire_OneThreadISO<tbb::spin_rw_mutex>( "ISO Spin RW Mutex" ); + TestTryAcquire_OneThreadISO<tbb::recursive_mutex>( "ISO Recursive Mutex" ); + TestTryAcquire_OneThreadISO<tbb::critical_section>( "ISO Critical Section" ); + TestReaderWriterLockISO<tbb::spin_rw_mutex>( "ISO Spin RW Mutex" ); + TestRecursiveMutexISO<tbb::recursive_mutex>( "ISO Recursive Mutex" ); + + TestRWStateMultipleChange<tbb::spin_rw_mutex>(); + TestRWStateMultipleChange<tbb::speculative_spin_rw_mutex>(); + TestRWStateMultipleChange<tbb::queuing_rw_mutex>(); + } + } + +#if __TBB_TSX_TESTING_ENABLED_FOR_THIS_COMPILER + // additional test for speculative mutexes to see if we actually attempt lock elisions + if( have_TSX() ) { + tbb::task_scheduler_init init( MaxThread ); + TestTransaction<tbb::speculative_spin_mutex>( "Spin Mutex/speculative" ); + TestTransaction<tbb::speculative_spin_rw_mutex>( "Spin RW Mutex/speculative" ); + } + else { + REMARK("Hardware transactions not supported\n"); + } +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_mutex_native_threads.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_mutex_native_threads.cpp new file mode 100644 index 00000000..68d9890d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_mutex_native_threads.cpp @@ -0,0 +1,217 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/spin_mutex.h" +#include "tbb/queuing_mutex.h" +#include "tbb/queuing_rw_mutex.h" +#include "tbb/spin_rw_mutex.h" +#include "tbb/mutex.h" + +#include "tbb/tick_count.h" +#include "tbb/atomic.h" + +#include "harness.h" + +// This test deliberately avoids a "using tbb" statement, +// so that the error of putting types in the wrong namespace will be caught. + +template<typename M> +struct Counter { + typedef M mutex_type; + M mutex; + volatile long value; + void flog_once( size_t mode ); +}; + +template<typename M> +void Counter<M>::flog_once(size_t mode) +/** Increments counter once for each iteration in the iteration space. */ +{ + if( mode&1 ) { + // Try implicit acquire and explicit release + typename mutex_type::scoped_lock lock(mutex); + value = value+1; + lock.release(); + } else { + // Try explicit acquire and implicit release + typename mutex_type::scoped_lock lock; + lock.acquire(mutex); + value = value+1; + } +} + +template<typename M, long N> +struct Invariant { + typedef M mutex_type; + M mutex; + const char* mutex_name; + volatile long value[N]; + Invariant( const char* mutex_name_ ) : + mutex_name(mutex_name_) + { + for( long k=0; k<N; ++k ) + value[k] = 0; + } + void update() { + for( long k=0; k<N; ++k ) + ++value[k]; + } + bool value_is( long expected_value ) const { + long tmp; + for( long k=0; k<N; ++k ) + if( (tmp=value[k])!=expected_value ) { + REPORT("ERROR: %ld!=%ld\n", tmp, expected_value); + return false; + } + return true; + } + bool is_okay() { + return value_is( value[0] ); + } + void flog_once( size_t mode ); +}; + +template<typename M, long N> +void Invariant<M,N>::flog_once( size_t mode ) +{ + //! Every 8th access is a write access + bool write = (mode%8)==7; + bool okay = true; + bool lock_kept = true; + if( (mode/8)&1 ) { + // Try implicit acquire and explicit release + typename mutex_type::scoped_lock lock(mutex,write); + if( write ) { + long my_value = value[0]; + update(); + if( mode%16==7 ) { + lock_kept = lock.downgrade_to_reader(); + if( !lock_kept ) + my_value = value[0] - 1; + okay = value_is(my_value+1); + } + } else { + okay = is_okay(); + if( mode%8==3 ) { + long my_value = value[0]; + lock_kept = lock.upgrade_to_writer(); + if( !lock_kept ) + my_value = value[0]; + update(); + okay = value_is(my_value+1); + } + } + lock.release(); + } else { + // Try explicit acquire and implicit release + typename mutex_type::scoped_lock lock; + lock.acquire(mutex,write); + if( write ) { + long my_value = value[0]; + update(); + if( mode%16==7 ) { + lock_kept = lock.downgrade_to_reader(); + if( !lock_kept ) + my_value = value[0] - 1; + okay = value_is(my_value+1); + } + } else { + okay = is_okay(); + if( mode%8==3 ) { + long my_value = value[0]; + lock_kept = lock.upgrade_to_writer(); + if( !lock_kept ) + my_value = value[0]; + update(); + okay = value_is(my_value+1); + } + } + } + if( !okay ) { + REPORT( "ERROR for %s at %ld: %s %s %s %s\n",mutex_name, long(mode), + write?"write,":"read,", write?(mode%16==7?"downgrade,":""):(mode%8==3?"upgrade,":""), + lock_kept?"lock kept,":"lock not kept,", (mode/8)&1?"imp/exp":"exp/imp" ); + } +} + +static tbb::atomic<size_t> Order; + +template<typename State, long TestSize> +struct Work: NoAssign { + static const size_t chunk = 100; + State& state; + Work( State& state_ ) : state(state_) {} + void operator()( int ) const { + size_t step; + while( (step=Order.fetch_and_add<tbb::acquire>(chunk))<TestSize ) + for( size_t i=0; i<chunk && step<TestSize; ++i, ++step ) + state.flog_once(step); + } +}; + +//! Generic test of a TBB Mutex type M. +/** Does not test features specific to reader-writer locks. */ +template<typename M> +void Test( const char * name, int nthread ) { + REMARK("testing %s\n",name); + Counter<M> counter; + counter.value = 0; + Order = 0; + // use the macro because of a gcc 4.6 bug +#define TEST_SIZE 100000 + tbb::tick_count t0 = tbb::tick_count::now(); + NativeParallelFor( nthread, Work<Counter<M>, TEST_SIZE>(counter) ); + tbb::tick_count t1 = tbb::tick_count::now(); + + REMARK("%s time = %g usec\n",name, (t1-t0).seconds() ); + if( counter.value!=TEST_SIZE ) + REPORT("ERROR for %s: counter.value=%ld != %ld=test_size\n",name,counter.value,TEST_SIZE); +#undef TEST_SIZE +} + + +//! Generic test of TBB ReaderWriterMutex type M +template<typename M> +void TestReaderWriter( const char * mutex_name, int nthread ) { + REMARK("testing %s\n",mutex_name); + Invariant<M,8> invariant(mutex_name); + Order = 0; + // use the macro because of a gcc 4.6 bug +#define TEST_SIZE 1000000 + tbb::tick_count t0 = tbb::tick_count::now(); + NativeParallelFor( nthread, Work<Invariant<M,8>, TEST_SIZE>(invariant) ); + tbb::tick_count t1 = tbb::tick_count::now(); + // There is either a writer or a reader upgraded to a writer for each 4th iteration + long expected_value = TEST_SIZE/4; + if( !invariant.value_is(expected_value) ) + REPORT("ERROR for %s: final invariant value is wrong\n",mutex_name); + REMARK("%s readers & writers time = %g usec\n",mutex_name,(t1-t0).seconds()); +#undef TEST_SIZE +} + +int TestMain () { + for( int p=MinThread; p<=MaxThread; ++p ) { + REMARK( "testing with %d threads\n", p ); + Test<tbb::spin_mutex>( "spin_mutex", p ); + Test<tbb::queuing_mutex>( "queuing_mutex", p ); + Test<tbb::queuing_rw_mutex>( "queuing_rw_mutex", p ); + Test<tbb::spin_rw_mutex>( "spin_rw_mutex", p ); + Test<tbb::mutex>( "mutex", p ); + TestReaderWriter<tbb::queuing_rw_mutex>( "queuing_rw_mutex", p ); + TestReaderWriter<tbb::spin_rw_mutex>( "spin_rw_mutex", p ); + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_kernel_32.spir b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_kernel_32.spir new file mode 100644 index 00000000..99055396 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_kernel_32.spir differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_kernel_64.spir b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_kernel_64.spir new file mode 100644 index 00000000..0f62ab5d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_kernel_64.spir differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_node.cl b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_node.cl new file mode 100644 index 00000000..42f26350 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_node.cl @@ -0,0 +1,185 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +static size_t my_strlen( __constant char* str ) { + size_t len = 0; + if ( str ) while ( *str++ ) ++len; + return len; +} + +static void my_strcpy(__global char *dest, __constant char *src, size_t n) { + while ( n-- ) *dest++ = *src++; +} + +static void set_error_msg( __global char *error_msg, size_t error_msg_size, __constant char *msg ) { + const size_t msg_len = my_strlen(msg); + const size_t len = msg_len < error_msg_size ? msg_len : error_msg_size-1; + my_strcpy( error_msg, msg, len ); + error_msg[len] = 0; +} + +__kernel +void TestArgumentPassing( + __global int *b1, __global int *b2, int stride_x, int stride_y, int stride_z, int dim, __global char *error_msg, int error_msg_size ) { + const int x = get_global_id(0); + const int y = get_global_id(1); + const int z = get_global_id(2); + + if ( dim < 2 ) { + if ( y != 0 ) { + set_error_msg( error_msg, (size_t)error_msg_size, "Y dimension does not equal 0" ); + return; + } + if ( stride_y != 0 ) { + set_error_msg( error_msg, (size_t)error_msg_size, "stride_y does not equal 0" ); + return; + } + } + + if ( dim < 3 ) { + if ( z != 0 ) { + set_error_msg( error_msg, (size_t)error_msg_size, "Z dimension does not equal 0" ); + return; + } + if ( stride_z != 0 ) { + set_error_msg( error_msg, (size_t)error_msg_size, "stride_z does not equal 0" ); + return; + } + } + + const int index = x*stride_x+y*stride_y+z*stride_z; + b2[index] = b1[index]; + + set_error_msg( error_msg, (size_t)error_msg_size, "Done" ); +} + +__kernel +void Sum( + __global float *b1, __global float *b2 ) +{ + const int index = get_global_id(0); + b2[index] += b1[index]; +} + +__kernel +void Mul( + __global int *b1, __global int *b2 ) +{ + const int index = get_global_id(0); + b1[index] *= b2[index]; +} + +__kernel +void Sqr( + __global float *b2, __global float *b3 ) +{ + const int index = get_global_id(0); + b3[index] = b2[index]*b2[index]; +} + +__kernel +void DiamondDependencyTestFill( + __global short *b, short v ) +{ + const int index = get_global_id(0); + b[index] = v; +} + +__kernel +void DiamondDependencyTestSquare( + __global short *b1, __global int *b2 ) +{ + const int index = get_global_id(0); + b2[index] = b1[index]*b1[index]; +} + +__kernel +void DiamondDependencyTestCube( + __global short *b1, __global int *b2 ) +{ + const int index = get_global_id(0); + b2[index] = b1[index]*b1[index]*b1[index]; +} + +__kernel +void DiamondDependencyTestDivision( + __global short *b, __global int *b1, __global int *b2 ) +{ + const int index = get_global_id(0); + b[index] *= b2[index]/b1[index]; +} + +__kernel +void LoopTestIter( __global long *b1, __global long *b2 ) { + const int index = get_global_id(0); + b1[index] += b2[index]++; +} + +__kernel +void ConcurrencyTestIter( __global char *b1, __global short *b2 ) { + const int index = get_global_id(0); + b2[index] += b1[index]; +} + +__kernel +void BroadcastTest( __global int *b1, __global int *b2 ) { + const int index = get_global_id(0); + b2[index] = b1[index]; +} + +#if __IMAGE_SUPPORT__ +const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST; + +__kernel +void Image2dTest ( + __read_only image2d_t src, + __write_only image2d_t dst, + char type) +{ + const int x = get_global_id(0); + const int y = get_global_id(1); + int2 coord = (int2)(x, y); + switch ( type ) { + case 'f': + write_imagef(dst, coord, read_imagef( src, sampler, coord )) ; + break; + case 'i': + write_imagei(dst, coord, read_imagei( src, sampler, coord )) ; + break; + case 'u': + write_imageui(dst, coord, read_imageui( src, sampler, coord )) ; + break; + } + +} + +__kernel +void Image2dTestDepth ( +#if __OPENCL_VERSION__ >= 200 + __read_only image2d_depth_t src, + __write_only image2d_depth_t dst, +#else + __read_only image2d_t src, + __write_only image2d_t dst, +#endif + char type ) +{ + const int x = get_global_id(0); + const int y = get_global_id(1); + int2 coord = (int2)(x, y); + write_imagef(dst, coord, read_imagef( src, sampler, coord )) ; +} +#endif /* __IMAGE_SUPPORT__ */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_node.cpp new file mode 100644 index 00000000..cc307992 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_node.cpp @@ -0,0 +1,911 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_PREVIEW_FLOW_GRAPH_NODES 1 +#define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1 + +#include "tbb/tbb_config.h" + +// The old versions of MSVC 2013 fail to compile the test with fatal error +#define __TBB_MSVC_TEST_COMPILATION_BROKEN (_MSC_VER && _MSC_FULL_VER <= 180021005 && !__INTEL_COMPILER) + +#if __TBB_PREVIEW_OPENCL_NODE && !__TBB_MSVC_TEST_COMPILATION_BROKEN +#if _MSC_VER +#pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning +#endif +#include <iterator> +#include "tbb/task_scheduler_init.h" +#include <vector> +#include <iostream> + +#include "tbb/flow_graph_opencl_node.h" +using namespace tbb::flow; + +#include "harness_assert.h" + +#if ( __INTEL_COMPILER && __INTEL_COMPILER <= 1500 ) || __clang__ +// In some corner cases the compiler fails to perform automatic type deduction for function pointer. +// Workaround is to replace a function pointer with a function call. +#define BROKEN_FUNCTION_POINTER_DEDUCTION(...) __VA_ARGS__() +#else +#define BROKEN_FUNCTION_POINTER_DEDUCTION(...) __VA_ARGS__ +#endif + +#if _MSC_VER <= 1800 && !__INTEL_COMPILER +// In some corner cases the compiler fails to perform automatic std::initializer_list deduction for curly brackets. +// Workaround is to perform implicit conversion. +template <typename T> +std::initializer_list<T> make_initializer_list( std::initializer_list<T> il ) { return il; } +#define BROKEN_INITIALIZER_LIST_DEDUCTION(...) make_initializer_list(__VA_ARGS__) +#else +#define BROKEN_INITIALIZER_LIST_DEDUCTION(...) __VA_ARGS__ +#endif + +#include "harness.h" + +#include <mutex> +std::once_flag tbbRootFlag; +char *tbbRoot = NULL; +std::string PathToFile(const std::string& fileName) { + std::call_once(tbbRootFlag, [] { tbbRoot = Harness::GetEnv("tbb_root"); }); + std::string prefix = tbbRoot ? tbbRoot : "../.."; + return prefix + "/src/test/" + fileName; +} + +// Global test variables and types +typedef tbb::flow::opencl_range OCLRange; +struct test_default_device_filter { + opencl_device_list operator()(const opencl_device_list &devices) { + opencl_device_list dl; + dl.add(*devices.begin()); + return dl; + } +}; +typedef opencl_factory<test_default_device_filter> DefaultFactoryType; + +struct test_default_device_selector { +public: + template <typename DeviceFilter> + tbb::flow::opencl_device operator()(tbb::flow::opencl_factory<DeviceFilter>& f) { + // This is the device filter result + const tbb::flow::opencl_device_list &devices = f.devices(); + + // Get total number of available platforms: + cl_uint num_of_platforms = 0; + clGetPlatformIDs(0, 0, &num_of_platforms); + cl_platform_id* platforms = new cl_platform_id[num_of_platforms]; + + // Get IDs for all platforms: + clGetPlatformIDs(num_of_platforms, platforms, 0); + + // By default device filter selects the first platform + cl_uint selected_platform_index = 0; + cl_platform_id platform = platforms[selected_platform_index]; + + // Count the number of platform devices and compare with selector list + cl_uint device_count; + clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, NULL, &device_count); + // It should be the same + ASSERT(device_count == devices.size(), "Default device filter returned not all devices from the platform"); + + // Retrieve device ids from the platform + cl_device_id* queuered_devices = (cl_device_id*) malloc(sizeof(cl_device_id) * device_count); + clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, device_count, queuered_devices, NULL); + + // Compare retrieved device ids with defaults + for (unsigned int i = 0; i < device_count; i++) { + cl_device_id searched_id = queuered_devices[i]; + + tbb::flow::opencl_device_list::const_iterator it = std::find_if(devices.cbegin(), devices.cend(), + [&searched_id](const tbb::flow::opencl_device &d) { + return d.device_id() == searched_id; + }); + + ASSERT(it != devices.cend(), "Devices parsed from the first platform and filtered devices are not the same"); + } + + return *(f.devices().begin()); + } +}; + +void TestArgumentPassing() { + REMARK( "TestArgumentPassing: " ); + + graph g; + test_default_device_selector test_device_selector; + opencl_node <tuple<opencl_buffer<int>, opencl_buffer<int>, OCLRange>> k( g, + opencl_program<>( PathToFile( "test_opencl_node.cl" ) ).get_kernel( "TestArgumentPassing" ), test_device_selector ); + split_node <tuple<opencl_buffer<int>, opencl_buffer<int>, OCLRange>> s( g ); + + make_edge( output_port<0>( s ), input_port<0>( k ) ); + make_edge( output_port<1>( s ), input_port<1>( k ) ); + make_edge( output_port<2>( s ), input_port<2>( k ) ); + + const int N = 1 * 1024 * 1024; + opencl_buffer<int> b1( N ), b2( N ); + + const int err_size = 128; + opencl_buffer<char> err( err_size ); + + OCLRange l; + + *err.data() = 0; ASSERT( err.data() != std::string( "Done" ), NULL ); + std::fill( b1.begin(), b1.end(), 1 ); + k.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }), BROKEN_INITIALIZER_LIST_DEDUCTION({ 16 }) } ); + k.set_args( port_ref<0, 1>(), /* stride_x */ 1, /* stride_y */ 0, /* stride_z */ 0, /* dim */ 1, err, err_size ); + s.try_put( std::tie( b1, b2, l ) ); + g.wait_for_all(); + ASSERT( err.data() == std::string( "Done" ), "Validation has failed" ); + ASSERT( std::all_of( b2.begin(), b2.end(), []( int c ) { return c == 1; } ), "Validation has failed" ); + + // By default, the first device is used. + opencl_device d = *interface11::opencl_info::available_devices().begin(); + std::array<size_t, 3> maxSizes = d.max_work_item_sizes(); + + *err.data() = 0; ASSERT( err.data() != std::string( "Done" ), NULL ); + std::fill( b1.begin(), b1.end(), 2 ); + int stride_x = 1; + k.set_args( port_ref<0>(), BROKEN_FUNCTION_POINTER_DEDUCTION( port_ref<1, 1> ), stride_x, /* stride_y */ 1024, /* stride_z */ 0, /* dim */ 2, err, err_size ); + k.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ 1024, 1024 }), + BROKEN_INITIALIZER_LIST_DEDUCTION({ 16, min( (int)maxSizes[1], 16 ) }) } ); + s.try_put( std::tie( b1, b2, l ) ); + g.wait_for_all(); + ASSERT( err.data() == std::string( "Done" ), "Validation has failed" ); + ASSERT( std::all_of( b2.begin(), b2.end(), []( int c ) { return c == 2; } ), "Validation has failed" ); + + *err.data() = 0; ASSERT( err.data() != std::string( "Done" ), NULL ); + std::fill( b1.begin(), b1.end(), 3 ); + stride_x = 2; // Nothing should be changed + s.try_put( std::tie( b1, b2, l ) ); + g.wait_for_all(); + ASSERT( err.data() == std::string( "Done" ), "Validation has failed" ); + ASSERT( std::all_of( b2.begin(), b2.end(), []( int c ) { return c == 3; } ), "Validation has failed" ); + + *err.data() = 0; ASSERT( err.data() != std::string( "Done" ), NULL ); + std::fill( b1.begin(), b1.end(), 4 ); + int stride_z = 64 * 64; + ASSERT( stride_z * 64 < N, NULL ); + k.set_args( port_ref<0>(), BROKEN_FUNCTION_POINTER_DEDUCTION( port_ref<1> ), /* stride_x */ 1, /* stride_y */ 64, /* stride_z */ stride_z, /* dim */ 3, err, err_size ); + k.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ 64, 64, 64 }), + BROKEN_INITIALIZER_LIST_DEDUCTION({ 4, min( (int)maxSizes[1], 4 ), min( (int)maxSizes[2], 4 ) }) } ); + s.try_put( std::make_tuple( b1, b2, OCLRange() ) ); + g.wait_for_all(); + ASSERT( err.data() == std::string( "Done" ), "Validation has failed" ); + ASSERT( std::all_of( b2.begin(), b2.begin() + stride_z * 64, []( int c ) { return c == 4; } ), "Validation has failed" ); + ASSERT( std::all_of( b2.begin() + stride_z * 64, b2.end(), []( int c ) { return c == 3; } ), "Validation has failed" ); + + *err.data() = 0; ASSERT( err.data() != std::string( "Done" ), NULL ); + std::fill( b1.begin(), b1.end(), 5 ); + ASSERT( 2 * 64 * 64 < N, NULL ); + k.set_args( port_ref<0, 1>(), /* stride_x */ 2, /* stride_y */ 2 * 64, /* stride_z */ 2 * 64 * 64, /* dim */ 3, err, err_size ); + k.set_range( BROKEN_FUNCTION_POINTER_DEDUCTION( port_ref<2> ) ); + l = { BROKEN_INITIALIZER_LIST_DEDUCTION({ 64, 64, 64 }), + BROKEN_INITIALIZER_LIST_DEDUCTION({ 4, min( (int)maxSizes[1], 4 ), min( (int)maxSizes[2], 4 ) }) }; + s.try_put( std::make_tuple( b1, b2, l ) ); + g.wait_for_all(); + ASSERT( err.data() == std::string( "Done" ), "Validation has failed" ); + auto it = b2.begin(); + for ( size_t i = 0; i < 64 * 64 * 64; ++i ) ASSERT( it[i] == (i % 2 ? 4 : 5), "Validation has failed" ); + for ( size_t i = 64 * 64 * 64; i < 2 * 64 * 64 * 64; ++i ) ASSERT( it[i] == (i % 2 ? 3 : 5), "Validation has failed" ); + ASSERT( std::all_of( b2.begin() + 2 * stride_z * 64, b2.end(), []( int c ) { return c == 3; } ), "Validation has failed" ); + + *err.data() = 0; ASSERT( err.data() != std::string( "Done" ), NULL ); + std::fill( b1.begin(), b1.end(), 6 ); + k.set_args( port_ref<0, 1>(), /* stride_x */ 1, /* stride_y */ 1024, /* stride_z */ 0, /* dim */ 2, err, err_size ); + k.set_range( std::deque<int>( { 1024, 1024 } ) ); + s.try_put( std::make_tuple( b1, b2, l ) ); + g.wait_for_all(); + ASSERT( err.data() == std::string( "Done" ), "Validation has failed" ); + ASSERT( std::all_of( b2.begin(), b2.end(), []( int c ) { return c == 6; } ), "Validation has failed" ); + REMARK( "done\n" ); +} + +void SimpleDependencyTest() { + REMARK( "SimpleDependencyTest: " ); + + const int N = 1 * 1024 * 1024; + opencl_buffer<float> b1( N ), b2( N ), b3( N ); + std::vector<float> v1( N ), v2( N ), v3( N ); + + auto i1 = b1.access<write_only>(); + auto i2 = b2.access<write_only>(); + + for ( int i = 0; i < N; ++i ) { + i1[i] = v1[i] = float( i ); + i2[i] = v2[i] = float( 2 * i ); + } + + graph g; + opencl_program<> p( PathToFile("test_opencl_node.cl") ) ; + opencl_node< tuple<opencl_buffer<float>, opencl_buffer<float>> > k1( g, p.get_kernel( "Sum" ) ); + k1.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }), BROKEN_INITIALIZER_LIST_DEDUCTION({ 16 }) } ); + + opencl_node < tuple<opencl_buffer<float>, opencl_buffer<float>> > k2( g, p.get_kernel( "Sqr" ) ); + k2.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }), BROKEN_INITIALIZER_LIST_DEDUCTION({ 16 }) } ); + + make_edge( output_port<1>( k1 ), input_port<0>( k2 ) ); + + split_node< tuple<opencl_buffer<float>, opencl_buffer<float>, opencl_buffer<float>> > s( g ); + + make_edge( output_port<0>( s ), input_port<0>( k1 ) ); + make_edge( output_port<1>( s ), input_port<1>( k1 ) ); + make_edge( output_port<2>( s ), input_port<1>( k2 ) ); + + s.try_put( std::tie( b1, b2, b3 ) ); + + g.wait_for_all(); + + // validation + for ( int i = 0; i < N; ++i ) { + v2[i] += v1[i]; + v3[i] = v2[i] * v2[i]; + } + + auto o2 = b2.access<read_only>(); + auto o3 = b3.access<read_only>(); + + ASSERT( memcmp( &o2[0], &v2[0], N*sizeof( float ) ) == 0, "Validation has failed" ); + ASSERT( memcmp( &o3[0], &v3[0], N*sizeof( float ) ) == 0, "Validation has failed" ); + REMARK( "done\n" ); +} + +class device_selector { + enum state { + DEFAULT_INITIALIZED, + COPY_INITIALIZED, + DELETED + }; + state my_state; +public: + device_selector() : my_state( DEFAULT_INITIALIZED ) {} + device_selector( const device_selector& ) : my_state( COPY_INITIALIZED ) {} + device_selector( device_selector&& ) : my_state( COPY_INITIALIZED ) {} + ~device_selector() { my_state = DELETED; } + + template <typename D> + opencl_device operator()( opencl_factory<D> &f ) { + ASSERT( my_state == COPY_INITIALIZED, NULL ); + ASSERT( ! f.devices().empty(), NULL ); + return *( f.devices().begin() ); + } +}; + +void BroadcastTest() { + REMARK( "BroadcastTest: " ); + + graph g; + + const int N = 1 * 1024; + opencl_buffer<cl_int> b( N ); + + const int numNodes = 4 * tbb::task_scheduler_init::default_num_threads(); + typedef opencl_node <tuple<opencl_buffer<cl_int>, opencl_buffer<cl_int>>> NodeType; + std::vector<NodeType> nodes( numNodes, NodeType( g, + opencl_program<>( PathToFile("test_opencl_node.cl") ).get_kernel( "BroadcastTest" ), + device_selector() ) ); + + for ( std::vector<NodeType>::iterator it = nodes.begin(); it != nodes.end(); ++it ) + it->set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }), BROKEN_INITIALIZER_LIST_DEDUCTION({ 16 }) } ); + + broadcast_node<opencl_buffer<cl_int>> bc( g ); + for ( auto &x : nodes ) make_edge( bc, x ); + + std::vector<opencl_buffer<cl_int>> res; + for ( int i = 0; i < numNodes; ++i ) res.emplace_back( N ); + + for ( cl_int r = 1; r < 100; ++r ) { + std::fill( b.begin(), b.end(), r ); + bc.try_put( b ); + for ( int i = 0; i < numNodes; ++i ) input_port<1>( nodes[i] ).try_put( res[i] ); + g.wait_for_all(); + + ASSERT( std::all_of( res.begin(), res.end(), [r]( const opencl_buffer<cl_int> &buf ) { + return std::all_of( buf.begin(), buf.end(), [r]( cl_int c ) { return c == r; } ); + } ), "Validation has failed" ); + } + REMARK( "done\n" ); +} + +void DiamondDependencyTest() { + REMARK( "DiamondDependencyTest: " ); + + const int N = 1 * 1024 * 1024; + opencl_buffer<cl_short> b( N ); + opencl_buffer<cl_int> b1( N ), b2( N ); + + graph g; + device_selector d; + opencl_program<> p( PathToFile("test_opencl_node.cl") ); + opencl_node <tuple<opencl_buffer<cl_short>, cl_short>> k0( g, p.get_kernel( "DiamondDependencyTestFill" ), d ); + k0.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) } ); + opencl_node <tuple<opencl_buffer<cl_short>, opencl_buffer<cl_int>>> k1( g, p.get_kernel( "DiamondDependencyTestSquare" ) ); + k1.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) } ); + opencl_node <tuple<opencl_buffer<cl_short>, opencl_buffer<cl_int>>> k2( g, p.get_kernel( "DiamondDependencyTestCube" ) ); + k2.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) } ); + opencl_node <tuple<opencl_buffer<cl_short>, opencl_buffer<cl_int>, opencl_buffer<cl_int>>> k3( g, p.get_kernel( "DiamondDependencyTestDivision" ) ); + k3.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) } ); + + make_edge( output_port<0>( k0 ), input_port<0>( k1 ) ); + make_edge( output_port<0>( k0 ), input_port<0>( k2 ) ); + make_edge( output_port<0>( k0 ), input_port<0>( k3 ) ); + + make_edge( output_port<1>( k1 ), input_port<1>( k3 ) ); + make_edge( output_port<1>( k2 ), input_port<2>( k3 ) ); + + split_node< tuple<opencl_buffer<cl_short>, cl_short, opencl_buffer<cl_int>, opencl_buffer<cl_int>> > s( g ); + + make_edge( output_port<0>( s ), input_port<0>( k0 ) ); + make_edge( output_port<1>( s ), input_port<1>( k0 ) ); + make_edge( output_port<2>( s ), input_port<1>( k1 ) ); + make_edge( output_port<3>( s ), input_port<1>( k2 ) ); + + for ( cl_short i = 1; i < 10; ++i ) { + s.try_put( std::tie( b, i, b1, b2 ) ); + g.wait_for_all(); + ASSERT( std::all_of( b.begin(), b.end(), [i]( cl_short c ) {return c == i*i; } ), "Validation has failed" ); + } + REMARK( "done\n" ); +} + +void LoopTest() { + REMARK( "LoopTest: " ); + + const int N = 1 * 1024; + opencl_buffer<cl_long> b1( N ), b2( N ); + + std::fill( b1.begin(), b1.end(), 0 ); + std::fill( b2.begin(), b2.end(), 1 ); + + graph g; + opencl_node <tuple<opencl_buffer<cl_long>, opencl_buffer<cl_long>>> k( g, + opencl_program<>( PathToFile("test_opencl_node.cl") ).get_kernel( "LoopTestIter" ) ); + k.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) } ); + + make_edge( output_port<1>( k ), input_port<1>( k ) ); + + const cl_long numIters = 1000; + cl_long iter = 0; + typedef multifunction_node < opencl_buffer<cl_long>, tuple < opencl_buffer<cl_long>, opencl_buffer<cl_long> > > multinode; + multinode mf( g, serial, [&iter, numIters]( const opencl_buffer<cl_long> &b, multinode::output_ports_type& op ) { + if ( ++iter < numIters ) get<1>( op ).try_put( b ); + else get<0>( op ).try_put( b ); + } ); + + make_edge( output_port<1>( mf ), input_port<0>( k ) ); + make_edge( output_port<0>( k ), mf ); + + function_node<opencl_buffer<cl_long>> f( g, unlimited, [numIters]( const opencl_buffer<cl_long> &b ) { + ASSERT( std::all_of( b.begin(), b.end(), [numIters]( cl_long c ) { return c == numIters*(numIters + 1) / 2; } ), "Validation has failed" ); + } ); + + make_edge( output_port<0>( mf ), f ); + + split_node< tuple<opencl_buffer<cl_long>, opencl_buffer<cl_long> > > s( g ); + + make_edge( output_port<0>( s ), input_port<0>( k ) ); + make_edge( output_port<1>( s ), input_port<1>( k ) ); + + s.try_put( std::tie( b1, b2 ) ); + g.wait_for_all(); + REMARK( "done\n" ); +} + +#include "harness_barrier.h" + +template <typename Factory> +struct ConcurrencyTestBodyData { + typedef opencl_node< tuple<opencl_buffer<cl_char, Factory>, opencl_subbuffer<cl_short, Factory>>, queueing, Factory > NodeType; + typedef std::vector< NodeType* > VectorType; + + Harness::SpinBarrier barrier; + VectorType nodes; + function_node< opencl_subbuffer<cl_short, Factory> > validationNode; + tbb::atomic<int> numChecks; + + ConcurrencyTestBodyData( graph &g, int numThreads ) : barrier( numThreads ), nodes(numThreads), + validationNode( g, unlimited, [numThreads, this]( const opencl_subbuffer<cl_short, Factory> &b ) { + ASSERT( std::all_of( b.begin(), b.end(), [numThreads]( cl_short c ) { return c == numThreads; } ), "Validation has failed" ); + --numChecks; + } ) + { + numChecks = 100; + // The test creates subbers in pairs so numChecks should be even. + ASSERT( numChecks % 2 == 0, NULL ); + } + + ~ConcurrencyTestBodyData() { + ASSERT( numChecks == 0, NULL ); + for ( NodeType *n : nodes ) delete n; + } +}; + +template <typename Factory> +class ConcurrencyTestBody : NoAssign { + graph &g; + std::shared_ptr<ConcurrencyTestBodyData<Factory>> data; + Factory &f; + const std::vector<opencl_device> &filteredDevices; + + class RoundRobinDeviceSelector : NoAssign { + public: + RoundRobinDeviceSelector( size_t cnt_, int num_checks_, const std::vector<opencl_device> &filteredDevices_ ) + : cnt( cnt_ ), num_checks( num_checks_ ), filteredDevices( filteredDevices_ ) { + } + RoundRobinDeviceSelector( const RoundRobinDeviceSelector &src ) + : cnt( src.cnt ), num_checks( src.num_checks ), filteredDevices( src.filteredDevices ) { + ASSERT( src.num_checks, "The source has already been copied" ); + src.num_checks = 0; + } + ~RoundRobinDeviceSelector() { + ASSERT( !num_checks, "Device Selector has not been called required number of times" ); + } + opencl_device operator()( Factory &a_factory ) { + const opencl_device_list& devices = a_factory.devices(); + ASSERT( filteredDevices.size() == devices.size(), "Incorrect list of devices" ); + std::vector<opencl_device>::const_iterator it = filteredDevices.cbegin(); + for ( auto d = devices.begin(); d != devices.end(); ++d ) ASSERT( (*d) == *it++, "Incorrect list of devices" ); + --num_checks; + return *(devices.begin() + cnt++ % devices.size()); + } + private: + size_t cnt; + mutable int num_checks; + const std::vector<opencl_device> &filteredDevices; + }; + +public: + ConcurrencyTestBody( graph &g_, int numThreads, Factory &f_, const std::vector<opencl_device> &filteredDevices_ ) + : g( g_ ) + , data( std::make_shared<ConcurrencyTestBodyData<Factory>>( g, numThreads ) ) + , f( f_ ) + , filteredDevices( filteredDevices_ ) { + } + void operator()( int idx ) const { + data->barrier.wait(); + + const int N = 1 * 1024; + const int numChecks = data->numChecks; + + typedef typename ConcurrencyTestBodyData<Factory>::NodeType NodeType; + NodeType *n1 = new NodeType( g, + opencl_program<Factory>( f, PathToFile( "test_opencl_node.cl" ) ).get_kernel( "ConcurrencyTestIter" ), + RoundRobinDeviceSelector( idx, numChecks, filteredDevices ), f ); + // n2 is used to test the copy constructor + NodeType *n2 = new NodeType( *n1 ); + delete n1; + data->nodes[idx] = n2; + n2->set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) } ); + + data->barrier.wait(); + + for ( size_t i = 0; i < data->nodes.size() - 1; ++i ) { + make_edge( output_port<0>( *data->nodes[i] ), input_port<0>( *data->nodes[i + 1] ) ); + make_edge( output_port<1>( *data->nodes[i] ), input_port<1>( *data->nodes[i + 1] ) ); + } + make_edge( output_port<1>( *data->nodes.back() ), data->validationNode ); + for ( size_t i = 0; i < data->nodes.size() - 1; ++i ) { + remove_edge( output_port<0>( *data->nodes[i] ), input_port<0>( *data->nodes[i + 1] ) ); + if ( i != (size_t)idx ) + remove_edge( output_port<1>( *data->nodes[i] ), input_port<1>( *data->nodes[i + 1] ) ); + } + if ( (size_t)idx != data->nodes.size() - 1 ) + remove_edge( output_port<1>( *data->nodes.back() ), data->validationNode ); + + data->barrier.wait(); + if ( idx == 0 ) { + // The first node needs two buffers. + Harness::FastRandom rnd(42); + cl_uint alignment = 0; + for ( auto d = filteredDevices.begin(); d != filteredDevices.end(); ++d ) { + cl_uint deviceAlignment; + (*d).info( CL_DEVICE_MEM_BASE_ADDR_ALIGN, deviceAlignment ); + alignment = max( alignment, deviceAlignment ); + } + alignment /= CHAR_BIT; + cl_uint alignmentMask = ~(alignment-1); + for ( int i = 0; i < numChecks; i += 2 ) { + for ( int j = 0; j < 2; ++j ) { + opencl_buffer<cl_char, Factory> b1( f, N ); + std::fill( b1.begin(), b1.end(), cl_char(1) ); + input_port<0>( *n2 ).try_put( b1 ); + } + + // The subbers are created in pairs from one big buffer + opencl_buffer<cl_short, Factory> b( f, 4*N ); + size_t id0 = (rnd.get() % N) & alignmentMask; + opencl_subbuffer<cl_short, Factory> sb1( b, id0, N ); + std::fill( sb1.begin(), sb1.end(), cl_short(0) ); + input_port<1>( *n2 ).try_put( sb1 ); + + size_t id1 = (rnd.get() % N) & alignmentMask; + opencl_subbuffer<cl_short, Factory> sb2 = b.subbuffer( 2*N + id1, N ); + std::fill( sb2.begin(), sb2.end(), cl_short(0) ); + input_port<1>( *n2 ).try_put( sb2 ); + } + } else { + // Other nodes need only one buffer each because input_port<1> is connected with + // output_port<1> of the previous node. + for ( int i = 0; i < numChecks; ++i ) { + opencl_buffer<cl_char, Factory> b( f, N ); + std::fill( b.begin(), b.end(), cl_char(1) ); + input_port<0>( *n2 ).try_put( b ); + } + } + + g.wait_for_all(); + + // n2 will be deleted in destructor of ConcurrencyTestBodyData + } +}; + +const int concurrencyTestNumRepeats = 5; + +template <typename Factory = DefaultFactoryType> +void ConcurrencyTest( const std::vector<opencl_device> &filteredDevices ) { + const int numThreads = min( tbb::task_scheduler_init::default_num_threads(), 8 ); + for ( int i = 0; i < concurrencyTestNumRepeats; ++i ) { + tbb::task_group_context ctx( tbb::task_group_context::isolated, tbb::task_group_context::default_traits | tbb::task_group_context::concurrent_wait ); + graph g( ctx ); + opencl_device_list dl; + Factory f; + ConcurrencyTestBody<Factory> body( g, numThreads, f, filteredDevices ); + NativeParallelFor( numThreads, body ); + } +} + +#include <unordered_map> + +enum FilterPolicy { + MAX_DEVICES, + ONE_DEVICE +}; + +template <FilterPolicy Policy> +struct DeviceFilter { + DeviceFilter() { + filteredDevices.clear(); + } + opencl_device_list operator()( opencl_device_list device_list ) { + ASSERT( filteredDevices.size() == 0, NULL ); + switch ( Policy ) { + case MAX_DEVICES: + { + std::unordered_map<std::string, std::vector<opencl_device>> platforms; + for (auto d = device_list.begin(); d != device_list.end(); ++d) { + platforms[(*d).platform_name()].push_back(*d); + } + + // Select a platform with maximum number of devices. + filteredDevices = std::max_element( platforms.begin(), platforms.end(), + []( const std::pair<std::string, std::vector<opencl_device>>& p1, const std::pair<std::string, std::vector<opencl_device>>& p2 ) { + return p1.second.size() < p2.second.size(); + } )->second; + + if ( !numRuns ) { + REMARK( " Chosen devices from the same platform (%s):\n", filteredDevices[0].platform_name().c_str() ); + for ( auto d = filteredDevices.begin(); d != filteredDevices.end(); d++ ) { + REMARK( " %s\n", (*d).name().c_str() ); + } + } + + if ( filteredDevices.size() < 2 ) + REPORT_ONCE( "Known issue: the system does not have several devices in one platform\n" ); + break; + } + case ONE_DEVICE: + { + ASSERT( deviceNum < device_list.size(), NULL ); + opencl_device_list::iterator it = device_list.begin(); + std::advance( it, deviceNum ); + filteredDevices.push_back( *it ); + break; + } + default: + ASSERT( false, NULL ); + } + opencl_device_list dl; + for ( auto d = filteredDevices.begin(); d != filteredDevices.end(); ++d ) dl.add( *d ); + + ++numRuns; + + return dl; + } + static opencl_device_list::size_type deviceNum; + static int numRuns; + static std::vector<opencl_device> filteredDevices; +}; + +template <FilterPolicy Policy> +opencl_device_list::size_type DeviceFilter<Policy>::deviceNum; +template <FilterPolicy Policy> +int DeviceFilter<Policy>::numRuns; +template <FilterPolicy Policy> +std::vector<opencl_device> DeviceFilter<Policy>::filteredDevices; + +void CustomFactoryTest() { + REMARK( "CustomFactoryTest:\n" ); + REMARK( " Multi device test:\n" ); + DeviceFilter<MAX_DEVICES>::numRuns = 0; + typedef tbb::flow::opencl_factory <DeviceFilter<MAX_DEVICES>> custom_factory; + ConcurrencyTest<custom_factory>( DeviceFilter<MAX_DEVICES>::filteredDevices ); + ASSERT( DeviceFilter<MAX_DEVICES>::numRuns == concurrencyTestNumRepeats, NULL ); + + REMARK( " One device tests:\n" ); + graph g; + opencl_device_list all_devices = interface11::opencl_info::available_devices(); + for ( int i = 0; i < (int)all_devices.size(); ++i ) { + opencl_device_list::const_iterator it = all_devices.begin(); + std::advance( it, i ); + REMARK( " %s: ", it->name().c_str() ); + DeviceFilter<ONE_DEVICE>::numRuns = 0; + DeviceFilter<ONE_DEVICE>::deviceNum = i; + typedef tbb::flow::opencl_factory <DeviceFilter<ONE_DEVICE>> one_device_factory; + ConcurrencyTest<one_device_factory>( DeviceFilter<ONE_DEVICE>::filteredDevices ); + ASSERT( DeviceFilter<ONE_DEVICE>::numRuns == concurrencyTestNumRepeats, NULL ); + ASSERT( DeviceFilter<ONE_DEVICE>::filteredDevices[0] == *it, NULL ); + REMARK( "done\n" ); + } + REMARK( "CustomFactoryTest: done\n" ); +} + +void DefaultConcurrencyTest() { + REMARK( "DefaultConcurrencyTest: " ); + // By default, the first device is selected. + ConcurrencyTest( { *interface11::opencl_info::available_devices().begin() } ); + REMARK( "done\n" ); +} + + +void SpirKernelTest() { + REMARK( "SpirKernelTest:\n" ); + + const opencl_device_list devices = interface11::opencl_info::available_devices(); + + for( auto d = devices.begin(); d != devices.end(); d++ ) { + if( !(*d).extension_available( "cl_khr_spir" ) ) { + REMARK( " Extension 'cl_khr_spir' is not available on the device '%s'\n", (*d).name().c_str() ); + continue; + } + + graph g; + DefaultFactoryType factory; + + bool init = factory.init( { *d } ); + ASSERT( init, "It should be the first initialization" ); + + std::string path_to_file = PathToFile(std::string("test_opencl_kernel_") + + std::to_string((*d).address_bits()) + std::string(".spir") ); + REMARK(" Using SPIR file '%s' on device '%s'\n", path_to_file.c_str(), (*d).name().c_str()); + const int N = 1 * 1024 * 1024; + opencl_buffer<float, DefaultFactoryType> b1( factory, N ), b2( factory, N ); + std::vector<float> v1( N ), v2( N ); + + auto i1 = b1.access<write_only>(); + auto i2 = b2.access<write_only>(); + + for ( int i = 0; i < N; ++i ) { + i1[i] = v1[i] = float( i ); + i2[i] = v2[i] = float( 2 * i ); + } + + typedef opencl_node< tuple<opencl_buffer<float, DefaultFactoryType>, opencl_buffer<float, DefaultFactoryType> >, queueing, DefaultFactoryType > OpenCLNodeType; + + OpenCLNodeType k1( g, opencl_program<DefaultFactoryType>( factory, opencl_program_type::SPIR, path_to_file ).get_kernel( "custom_summer" ), factory ); + k1.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) } ); + + input_port<0>(k1).try_put( b1 ); + input_port<1>(k1).try_put( b2 ); + + g.wait_for_all(); + + // validation + for ( int i = 0; i < N; ++i ) { + v2[i] += v1[i]; + } + + ASSERT( memcmp( &b2[0], &v2[0], N*sizeof( float ) ) == 0, "Validation has failed" ); + } + REMARK( "done\n" ); +} + +void PrecompiledKernelTest() { + REMARK( "PrecompiledKernelTest:\n" ); + + graph g; + DefaultFactoryType factory; + + const opencl_device_list devices = interface11::opencl_info::available_devices(); + opencl_device_list::const_iterator it = std::find_if( + devices.cbegin(), devices.cend(), + []( const opencl_device &d ) { + std::string vendor_name = d.vendor(); + return std::string::npos != vendor_name.find( "Intel" ) && CL_DEVICE_TYPE_GPU == d.type(); + } ); + + if ( it == devices.cend() ) { + REPORT( "Known issue: there is no device in the system that supports the precompiled GPU kernel.\n" ); + return; + } + bool init = factory.init( { *it } ); + ASSERT( init, "It should be the first initialization" ); + REMARK( " Device name '%s', %s:", it->name().c_str(), it->version().c_str() ); + + const int N = 1 * 1024 * 1024; + opencl_buffer<float, DefaultFactoryType> b1( factory, N ), b2( factory, N ); + std::vector<float> v1( N ), v2( N ); + + auto i1 = b1.access<write_only>(); + auto i2 = b2.access<write_only>(); + + for ( int i = 0; i < N; ++i ) { + i1[i] = v1[i] = float( i ); + i2[i] = v2[i] = float( 2 * i ); + } + + std::string path_to_file = PathToFile(std::string("test_opencl_precompiled_kernel_gpu_") + std::to_string((*it).address_bits()) + std::string(".ir")); + + opencl_program<DefaultFactoryType> p( factory, opencl_program_type::PRECOMPILED, path_to_file); + opencl_node < tuple<opencl_buffer<float, DefaultFactoryType>, opencl_buffer<float, DefaultFactoryType> >, queueing, DefaultFactoryType > k1(g, p.get_kernel("custom_subtractor"), factory); + k1.set_range({ BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) }); + + input_port<0>(k1).try_put( b1 ); + input_port<1>(k1).try_put( b2 ); + + g.wait_for_all(); + + // validation + for ( int i = 0; i < N; ++i ) { + v2[i] -= v1[i]; + } + + ASSERT( memcmp( &b2[0], &v2[0], N*sizeof( float ) ) == 0, "Validation has failed" ); + REMARK( " done\n" ); +} + +/* + /--functional_node-\ /-functional_node-\ /--functional_node-\ + | | | | /--opencl_node--\ | | + O Buffer generator O---O Buffer filler O---O O---O Result validator O + | | | | | | | | + \------------------/ \-----------------/ | | \------------------/ + | Multiplier | + /--functional_node-\ /-functional_node-\ | | + | | | | | | + O Buffer generator O---O Buffer filler O---O O + | | | | \---------------/ + \------------------/ \-----------------/ + */ + +template <typename Key> +struct BufferWithKey : public opencl_buffer<int> { + typedef typename std::decay<Key>::type KeyType; + KeyType my_key; + int my_idx; + + // TODO: investigate why default ctor is required + BufferWithKey() {} + BufferWithKey( size_t N, int idx ) : opencl_buffer<int>( N ), my_idx( idx ) {} + const KeyType& key() const { return my_key; } +}; + +template <typename Key> +Key KeyGenerator( int i ); + +template <> +int KeyGenerator<int>( int i ) { return i; } + +template <> +std::string KeyGenerator<std::string>( int i ) { return std::to_string( i ); } + +template <typename Key> +BufferWithKey<Key> GenerateRandomBuffer( BufferWithKey<Key> b ) { + b.my_key = KeyGenerator<typename std::decay<Key>::type>( b.my_idx ); + Harness::FastRandom r( b.my_idx ); + std::generate( b.begin(), b.end(), [&r]() { return r.get(); } ); + return b; +} + +template <typename Key, typename JP> +bool KeyMatchingTest() { + const int N = 1000; + const int numMessages = 100; + + graph g; + broadcast_node<int> b( g ); + + // Use opencl_async_msg's to have non-blocking map to host + function_node<int, opencl_async_msg<BufferWithKey<Key>>> + bufGenerator1( g, unlimited, [N]( int i ) { return opencl_async_msg<BufferWithKey<Key>>( BufferWithKey<Key >(N, i) ); } ), + bufGenerator2 = bufGenerator1; + + function_node<BufferWithKey<Key>, BufferWithKey<Key>> + bufFiller1( g, unlimited, []( const BufferWithKey<Key> &b ) { return GenerateRandomBuffer<Key>( b ); } ), + bufFiller2 = bufFiller1; + + opencl_node< tuple< BufferWithKey<Key>, BufferWithKey<Key> >, JP > k( g, + opencl_program<>( PathToFile( "test_opencl_node.cl" ) ).get_kernel( "Mul" ) ); + k.set_range( { BROKEN_INITIALIZER_LIST_DEDUCTION({ N }) } ); + + bool success = true; + function_node<BufferWithKey<Key>> checker( g, unlimited, [&success, N]( BufferWithKey<Key> b ) { + Harness::FastRandom r( b.my_idx ); + std::for_each( b.begin(), b.end(), [&success, &r]( int bv ) { + const int rv = r.get(); + if ( bv != rv*rv ) { + success = false; + return; + } + } ); + } ); + + make_edge( bufGenerator1, bufFiller1 ); + make_edge( bufGenerator2, bufFiller2 ); + make_edge( bufFiller1, input_port<0>( k ) ); + make_edge( bufFiller2, input_port<1>( k ) ); + make_edge( output_port<0>( k ), checker ); + + for ( int i = 0; i < numMessages; ++i ) { + bufGenerator1.try_put( i ); + bufGenerator2.try_put( numMessages - i - 1 ); + } + + g.wait_for_all(); + + return success; +} + +void KeyMatchingTest() { + REMARK( "KeyMatchingTest:\n" ); + REMARK( " Queueing negative test: " ); + bool res = !KeyMatchingTest<int, queueing>(); // The test should fail with the queueing policy, so the negative result is expected. + ASSERT( res, "Queueing negative test has failed" ); + REMARK( "done\n key_matching<int> test: " ); + res = KeyMatchingTest<int, key_matching<int>>(); + ASSERT( res, "key_matching<int> test has failed" ); + REMARK( "done\n key_matching<string&> test: " ); + res = KeyMatchingTest<std::string&, key_matching<std::string&>>(); + ASSERT( res, "key_matching<string&> test has failed" ); + REMARK( "done\n" ); + REMARK( "KeyMatchingTest: done\n" ); +} + +int TestMain() { + + + TestArgumentPassing(); + + SimpleDependencyTest(); + BroadcastTest(); + DiamondDependencyTest(); + LoopTest(); + + DefaultConcurrencyTest(); + CustomFactoryTest(); + + SpirKernelTest(); +#if !__APPLE__ + // Consider better support for precompiled programs on Apple + PrecompiledKernelTest(); +#endif + + KeyMatchingTest(); + + return Harness::Done; +} +#else +#define HARNESS_SKIP_TEST 1 +#include "harness.h" +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_precompiled_kernel_gpu_32.ir b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_precompiled_kernel_gpu_32.ir new file mode 100644 index 00000000..d65513a8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_precompiled_kernel_gpu_32.ir differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_precompiled_kernel_gpu_64.ir b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_precompiled_kernel_gpu_64.ir new file mode 100644 index 00000000..f05cdc69 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_opencl_precompiled_kernel_gpu_64.ir differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_openmp.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_openmp.cpp new file mode 100644 index 00000000..8498891e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_openmp.cpp @@ -0,0 +1,246 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Test mixing OpenMP and TBB + +/* SCR #471 + Below is workaround to compile test within environment of Intel Compiler + but by Microsoft Compiler. So, there is wrong "omp.h" file included and + manifest section is missed from .exe file - restoring here. + + As of Visual Studio 2010, crtassem.h is no longer shipped. + */ +#if !defined(__INTEL_COMPILER) && _MSC_VER >= 1400 && _MSC_VER < 1600 + #include <crtassem.h> + #if !defined(_OPENMP) + #define _OPENMP + #if defined(_DEBUG) + #pragma comment(lib, "vcompd") + #else // _DEBUG + #pragma comment(lib, "vcomp") + #endif // _DEBUG + #endif // _OPENMP + + #if defined(_DEBUG) + #if defined(_M_IX86) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugOpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='x86' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #elif defined(_M_X64) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugOpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='amd64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #elif defined(_M_IA64) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugOpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='ia64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #endif + #else // _DEBUG + #if defined(_M_IX86) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".OpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='x86' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #elif defined(_M_X64) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".OpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='amd64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #elif defined(_M_IA64) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".OpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='ia64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #endif + #endif // _DEBUG + #define _OPENMP_NOFORCE_MANIFEST +#endif + +#include <omp.h> + + +typedef short T; + +void SerialConvolve( T c[], const T a[], int m, const T b[], int n ) { + for( int i=0; i<m+n-1; ++i ) { + int start = i<n ? 0 : i-n+1; + int finish = i<m ? i+1 : m; + T sum = 0; + for( int j=start; j<finish; ++j ) + sum += a[j]*b[i-j]; + c[i] = sum; + } +} + +#define OPENMP_ASYNC_SHUTDOWN_BROKEN (__INTEL_COMPILER<=1400 && __linux__) +#define TBB_PREVIEW_WAITING_FOR_WORKERS 1 + +#include "tbb/blocked_range.h" +#include "tbb/parallel_for.h" +#include "tbb/parallel_reduce.h" +#include "tbb/task_scheduler_init.h" +#include "harness.h" + +using namespace tbb; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Suppress overzealous warning about short+=short + #pragma warning( push ) + #pragma warning( disable: 4244 ) +#endif + +class InnerBody: NoAssign { + const T* my_a; + const T* my_b; + const int i; +public: + T sum; + InnerBody( T /*c*/[], const T a[], const T b[], int ii ) : + my_a(a), my_b(b), i(ii), sum(0) + {} + InnerBody( InnerBody& x, split ) : + my_a(x.my_a), my_b(x.my_b), i(x.i), sum(0) + { + } + void join( InnerBody& x ) {sum += x.sum;} + void operator()( const blocked_range<int>& range ) { + for( int j=range.begin(); j!=range.end(); ++j ) + sum += my_a[j]*my_b[i-j]; + } +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning( pop ) +#endif + +//! Test OpenMMP loop around TBB loop +void OpenMP_TBB_Convolve( T c[], const T a[], int m, const T b[], int n ) { + REMARK("testing OpenMP loop around TBB loop\n"); +#pragma omp parallel + { + task_scheduler_init init; +#pragma omp for + for( int i=0; i<m+n-1; ++i ) { + int start = i<n ? 0 : i-n+1; + int finish = i<m ? i+1 : m; + InnerBody body(c,a,b,i); + parallel_reduce( blocked_range<int>(start,finish,10), body ); + c[i] = body.sum; + } + } +} + +class OuterBody: NoAssign { + const T* my_a; + const T* my_b; + T* my_c; + const int m; + const int n; +public: + OuterBody( T c[], const T a[], int m_, const T b[], int n_ ) : + my_a(a), my_b(b), my_c(c), m(m_), n(n_) + {} + void operator()( const blocked_range<int>& range ) const { + for( int i=range.begin(); i!=range.end(); ++i ) { + int start = i<n ? 0 : i-n+1; + int finish = i<m ? i+1 : m; + T sum = 0; +#pragma omp parallel for reduction(+:sum) + for( int j=start; j<finish; ++j ) + sum += my_a[j]*my_b[i-j]; + my_c[i] = sum; + } + } +}; + +//! Test TBB loop around OpenMP loop +void TBB_OpenMP_Convolve( T c[], const T a[], int m, const T b[], int n ) { + REMARK("testing TBB loop around OpenMP loop\n"); + parallel_for( blocked_range<int>(0,m+n-1,10), OuterBody( c, a, m, b, n ) ); +} + +#if __INTEL_COMPILER +// A regression test on OpenMP affinity settings affecting TBB. +// Testing only with __INTEL_COMPILER because we do not provide interoperability with other OpenMP implementations. + +#define __TBB_NUM_THREADS_AFFECTED_BY_LIBIOMP (KMP_VERSION_BUILD<20150922) + +void TestNumThreads() { +#if __TBB_NUM_THREADS_AFFECTED_BY_LIBIOMP + REPORT("Known issue: the default number of threads is affected by OpenMP affinity\n"); +#else + REMARK("Compare default number of threads for OpenMP and TBB\n"); + Harness::SetEnv("KMP_AFFINITY","compact"); + // Make an OpenMP call before initializing TBB + int omp_nthreads = omp_get_max_threads(); + #pragma omp parallel + {} + int tbb_nthreads = tbb::task_scheduler_init::default_num_threads(); + REMARK("# of threads (OpenMP): %d\n", omp_nthreads); + REMARK("# of threads (TBB): %d\n", tbb_nthreads); + // For the purpose of testing, assume that OpenMP and TBB should utilize the same # of threads. + // If it's not true on some platforms, the test will need to be adjusted. + ASSERT( tbb_nthreads==omp_nthreads, "Initialization of TBB is possibly affected by OpenMP"); +#endif +} +#endif // __INTEL_COMPILER + +const int M = 17*17; +const int N = 13*13; +T A[M], B[N]; +T expected[M+N], actual[M+N]; + +template <class Func> +void RunTest( Func F, int m, int n, int p, bool wait_workers = false ) { + task_scheduler_init init( p ); + memset( actual, -1, (m+n)*sizeof(T) ); + F( actual, A, m, B, n ); + ASSERT( memcmp(actual, expected, (m+n-1)*sizeof(T))==0, NULL ); + if (wait_workers) init.blocking_terminate(std::nothrow); + else init.terminate(); +} + +int TestMain () { +#if __INTEL_COMPILER + TestNumThreads(); // Testing initialization-related behavior; must be the first +#endif // __INTEL_COMPILER + MinThread = 1; + for( int p=MinThread; p<=MaxThread; ++p ) { + for( int m=1; m<=M; m*=17 ) { + for( int n=1; n<=N; n*=13 ) { + for( int i=0; i<m; ++i ) A[i] = T(1+i/5); + for( int i=0; i<n; ++i ) B[i] = T(1+i/7); + SerialConvolve( expected, A, m, B, n ); + RunTest( OpenMP_TBB_Convolve, m, n, p ); + RunTest( TBB_OpenMP_Convolve, m, n, p +#if OPENMP_ASYNC_SHUTDOWN_BROKEN + ,true +#endif + ); + } + } + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_overwrite_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_overwrite_node.cpp new file mode 100644 index 00000000..53147a72 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_overwrite_node.cpp @@ -0,0 +1,203 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#endif + +#include "harness.h" +#include "harness_graph.h" + +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include "test_follows_and_precedes_api.h" + +#define N 300 +#define T 4 +#define M 5 + +template< typename R > +void simple_read_write_tests() { + tbb::flow::graph g; + tbb::flow::overwrite_node<R> n(g); + + for ( int t = 0; t < T; ++t ) { + R v0(N+1); + std::vector< harness_counting_receiver<R> > r(M, harness_counting_receiver<R>(g)); + + ASSERT( n.is_valid() == false, NULL ); + ASSERT( n.try_get( v0 ) == false, NULL ); + if ( t % 2 ) { + ASSERT( n.try_put( static_cast<R>(N) ), NULL ); + ASSERT( n.is_valid() == true, NULL ); + ASSERT( n.try_get( v0 ) == true, NULL ); + ASSERT( v0 == R(N), NULL ); + } + + for (int i = 0; i < M; ++i) { + tbb::flow::make_edge( n, r[i] ); + } + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(n.successor_count() == M, NULL); + typename tbb::flow::overwrite_node<R>::successor_list_type my_succs; + n.copy_successors(my_succs); + ASSERT(my_succs.size() == M, NULL); + ASSERT(n.predecessor_count() == 0, NULL); +#endif + + for (int i = 0; i < N; ++i ) { + R v1(static_cast<R>(i)); + ASSERT( n.try_put( v1 ), NULL ); + ASSERT( n.is_valid() == true, NULL ); + for (int j = 0; j < N; ++j ) { + R v2(0); + ASSERT( n.try_get( v2 ), NULL ); + ASSERT( v1 == v2, NULL ); + } + } + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == N+t%2, NULL ); + } + for (int i = 0; i < M; ++i) { + tbb::flow::remove_edge( n, r[i] ); + } + ASSERT( n.try_put( R(0) ), NULL ); + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == N+t%2, NULL ); + } + n.clear(); + ASSERT( n.is_valid() == false, NULL ); + ASSERT( n.try_get( v0 ) == false, NULL ); + } +} + +template< typename R > +class native_body : NoAssign { + tbb::flow::overwrite_node<R> &my_node; + +public: + + native_body( tbb::flow::overwrite_node<R> &n ) : my_node(n) {} + + void operator()( int i ) const { + R v1(static_cast<R>(i)); + ASSERT( my_node.try_put( v1 ), NULL ); + ASSERT( my_node.is_valid() == true, NULL ); + } +}; + +template< typename R > +void parallel_read_write_tests() { + tbb::flow::graph g; + tbb::flow::overwrite_node<R> n(g); + //Create a vector of identical nodes + std::vector< tbb::flow::overwrite_node<R> > ow_vec(2, n); + + for (size_t node_idx=0; node_idx<ow_vec.size(); ++node_idx) { + for ( int t = 0; t < T; ++t ) { + std::vector< harness_counting_receiver<R> > r(M, harness_counting_receiver<R>(g)); + + for (int i = 0; i < M; ++i) { + tbb::flow::make_edge( ow_vec[node_idx], r[i] ); + } + R v0; + ASSERT( ow_vec[node_idx].is_valid() == false, NULL ); + ASSERT( ow_vec[node_idx].try_get( v0 ) == false, NULL ); + + NativeParallelFor( N, native_body<R>( ow_vec[node_idx] ) ); + + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == N, NULL ); + } + for (int i = 0; i < M; ++i) { + tbb::flow::remove_edge( ow_vec[node_idx], r[i] ); + } + ASSERT( ow_vec[node_idx].try_put( R(0) ), NULL ); + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == N, NULL ); + } + ow_vec[node_idx].clear(); + ASSERT( ow_vec[node_idx].is_valid() == false, NULL ); + ASSERT( ow_vec[node_idx].try_get( v0 ) == false, NULL ); + } + } +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + using msg_t = tbb::flow::continue_msg; + + std::array<msg_t, 3> messages_for_follows = { {msg_t(), msg_t(), msg_t()} }; + std::vector<msg_t> messages_for_precedes = {msg_t()}; + + follows_and_precedes_testing::test_follows<msg_t, tbb::flow::overwrite_node<msg_t>>(messages_for_follows); + follows_and_precedes_testing::test_precedes<msg_t, tbb::flow::overwrite_node<msg_t>>(messages_for_precedes); +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + + graph g; + broadcast_node<int> b1(g); + overwrite_node<int> o0(g); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + overwrite_node o1(follows(b1)); + static_assert(std::is_same_v<decltype(o1), overwrite_node<int>>); + + overwrite_node o2(precedes(b1)); + static_assert(std::is_same_v<decltype(o2), overwrite_node<int>>); +#endif + + overwrite_node o3(o0); + static_assert(std::is_same_v<decltype(o3), overwrite_node<int>>); +} +#endif + +int TestMain() { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + simple_read_write_tests<int>(); + simple_read_write_tests<float>(); + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + parallel_read_write_tests<int>(); + parallel_read_write_tests<float>(); + test_reserving_nodes<tbb::flow::overwrite_node, size_t>(); + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract_on_node<tbb::flow::overwrite_node, int>(); + test_extract_on_node<tbb::flow::overwrite_node, float>(); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_do.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_do.cpp new file mode 100644 index 00000000..c6ceeec4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_do.cpp @@ -0,0 +1,424 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/parallel_do.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/atomic.h" +#include "harness.h" +#include "harness_cpu.h" + +#if defined(_MSC_VER) && defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4267) +#endif /* _MSC_VER && _Wp64 */ + +#define N_DEPTHS 20 + +static tbb::atomic<int> g_values_counter; + +class value_t { + size_t x; + value_t& operator= ( const value_t& ); +public: + value_t ( size_t xx ) : x(xx) { ++g_values_counter; } + value_t ( const value_t& v ) : x(v.x) { ++g_values_counter; } +#if __TBB_CPP11_RVALUE_REF_PRESENT + value_t ( value_t&& v ) : x(v.x) { ++g_values_counter; } +#endif + ~value_t () { --g_values_counter; } + size_t value() const volatile { return x; } +}; + +#include "harness_iterator.h" + +static size_t g_tasks_expected = 0; +static tbb::atomic<size_t> g_tasks_observed; + +size_t FindNumOfTasks ( size_t max_depth ) { + if( max_depth == 0 ) + return 1; + return max_depth * FindNumOfTasks( max_depth - 1 ) + 1; +} + +//! Simplest form of the parallel_do functor object. +class FakeTaskGeneratorBody { +public: + //! The simplest form of the function call operator + /** It does not allow adding new tasks during its execution. **/ + void operator() ( value_t depth ) const { + g_tasks_observed += FindNumOfTasks(depth.value()); + } +}; + +/** Work item is passed by reference here. **/ +class FakeTaskGeneratorBody_RefVersion { +public: + void operator() ( value_t& depth ) const { + g_tasks_observed += FindNumOfTasks(depth.value()); + } +}; + +/** Work item is passed by reference to const here. **/ +class FakeTaskGeneratorBody_ConstRefVersion { +public: + void operator() ( const value_t& depth ) const { + g_tasks_observed += FindNumOfTasks(depth.value()); + } +}; + +/** Work item is passed by reference to volatile here. **/ +class FakeTaskGeneratorBody_VolatileRefVersion { +public: + void operator() ( volatile value_t& depth, tbb::parallel_do_feeder<value_t>& ) const { + g_tasks_observed += FindNumOfTasks(depth.value()); + } +}; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +/** Work item is passed by rvalue reference here. **/ +class FakeTaskGeneratorBody_RvalueRefVersion { +public: + void operator() ( value_t&& depth ) const { + g_tasks_observed += FindNumOfTasks(depth.value()); + } +}; +#endif + +void do_work ( const value_t& depth, tbb::parallel_do_feeder<value_t>& feeder ) { + ++g_tasks_observed; + value_t new_value(depth.value()-1); + for( size_t i = 0; i < depth.value(); ++i) { + if (i%2) feeder.add( new_value ); // pass lvalue + else feeder.add( value_t(depth.value()-1) ); // pass rvalue + } +} + +//! Standard form of the parallel_do functor object. +/** Allows adding new work items on the fly. **/ +class TaskGeneratorBody +{ +public: + //! This form of the function call operator can be used when the body needs to add more work during the processing + void operator() ( value_t depth, tbb::parallel_do_feeder<value_t>& feeder ) const { + do_work(depth, feeder); + } +private: + // Assert that parallel_do does not ever access body constructors + TaskGeneratorBody () {} + TaskGeneratorBody ( const TaskGeneratorBody& ); + // These functions need access to the default constructor + template<class Body, class Iterator> friend void TestBody( size_t ); + template<class Body, class Iterator> friend void TestBody_MoveOnly( size_t ); +}; + +/** Work item is passed by reference here. **/ +class TaskGeneratorBody_RefVersion +{ +public: + void operator() ( value_t& depth, tbb::parallel_do_feeder<value_t>& feeder ) const { + do_work(depth, feeder); + } +}; + +/** Work item is passed as const here. Compilers must ignore the const qualifier. **/ +class TaskGeneratorBody_ConstVersion +{ +public: + void operator() ( const value_t depth, tbb::parallel_do_feeder<value_t>& feeder ) const { + do_work(depth, feeder); + } +}; + +/** Work item is passed by reference to const here. **/ +class TaskGeneratorBody_ConstRefVersion +{ +public: + void operator() ( const value_t& depth, tbb::parallel_do_feeder<value_t>& feeder ) const { + do_work(depth, feeder); + } +}; + +/** Work item is passed by reference to volatile here. **/ +class TaskGeneratorBody_VolatileRefVersion +{ +public: + void operator() ( volatile value_t& depth, tbb::parallel_do_feeder<value_t>& feeder ) const { + do_work(const_cast<value_t&>(depth), feeder); + } +}; + +/** Work item is passed by reference to const volatile here. **/ +class TaskGeneratorBody_ConstVolatileRefVersion +{ +public: + void operator() ( const volatile value_t& depth, tbb::parallel_do_feeder<value_t>& feeder ) const { + do_work(const_cast<value_t&>(depth), feeder); + } +}; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +/** Work item is passed by rvalue reference here. **/ +class TaskGeneratorBody_RvalueRefVersion +{ +public: + void operator() ( value_t&& depth, tbb::parallel_do_feeder<value_t>& feeder ) const { + do_work(depth, feeder); + } +}; +#endif + +static value_t g_depths[N_DEPTHS] = {0, 1, 2, 3, 4, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 0, 1, 2}; + +#if __TBB_CPP11_RVALUE_REF_PRESENT +template<class Body, class Iterator> +void TestBody_MoveIter ( const Body& body, Iterator begin, Iterator end ) { + typedef std::move_iterator<Iterator> MoveIterator; + MoveIterator mbegin(begin); + MoveIterator mend(end); + g_tasks_observed = 0; + tbb::parallel_do(mbegin, mend, body); + ASSERT (g_tasks_observed == g_tasks_expected, NULL); +} + +template<class Body, class Iterator> +void TestBody_MoveOnly ( size_t depth ) { + typedef typename std::iterator_traits<Iterator>::value_type value_type; + value_type a_depths[N_DEPTHS] = {0, 1, 2, 3, 4, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 0, 1, 2}; + TestBody_MoveIter( Body(), Iterator(a_depths), Iterator(a_depths + depth)); +} +#endif + +template<class Body, class Iterator> +void TestBody ( size_t depth ) { + typedef typename std::iterator_traits<Iterator>::value_type value_type; + value_type a_depths[N_DEPTHS] = {0, 1, 2, 3, 4, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 0, 1, 2}; + Body body; + Iterator begin(a_depths); + Iterator end(a_depths + depth); + g_tasks_observed = 0; + tbb::parallel_do(begin, end, body); + ASSERT (g_tasks_observed == g_tasks_expected, NULL); +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestBody_MoveIter( body, Iterator(a_depths), Iterator(a_depths + depth) ); +#endif +} + +template<class Iterator> +void TestIterator_Common ( size_t depth ) { + TestBody<FakeTaskGeneratorBody, Iterator> (depth); + TestBody<FakeTaskGeneratorBody_ConstRefVersion, Iterator> (depth); + TestBody<TaskGeneratorBody, Iterator> (depth); + TestBody<TaskGeneratorBody_ConstVersion, Iterator> (depth); + TestBody<TaskGeneratorBody_ConstRefVersion, Iterator> (depth); +} + +template<class Iterator> +void TestIterator_Const ( size_t depth ) { + TestIterator_Common<Iterator>(depth); + TestBody<TaskGeneratorBody_ConstVolatileRefVersion, Iterator> (depth); +} + +template<class Iterator> +void TestIterator_Modifiable ( size_t depth ) { + TestIterator_Const<Iterator>(depth); + TestBody<FakeTaskGeneratorBody_RefVersion, Iterator> (depth); + TestBody<FakeTaskGeneratorBody_VolatileRefVersion, Iterator> (depth); + TestBody<TaskGeneratorBody_RefVersion, Iterator> (depth); + TestBody<TaskGeneratorBody_VolatileRefVersion, Iterator> (depth); +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestBody_MoveOnly<FakeTaskGeneratorBody_RvalueRefVersion, Iterator> (depth); + TestBody_MoveOnly<TaskGeneratorBody_RvalueRefVersion, Iterator> (depth); +#endif +} + +template<class Iterator> +void TestIterator_Movable ( size_t depth ) { + TestIterator_Common<Iterator>(depth); +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestBody<FakeTaskGeneratorBody_RvalueRefVersion, Iterator> (depth); + TestBody<TaskGeneratorBody_RvalueRefVersion, Iterator> (depth); +#endif +} + +void Run( int /*nthread*/ ) { + for( size_t depth = 0; depth <= N_DEPTHS; ++depth ) { + g_tasks_expected = 0; + for ( size_t i=0; i < depth; ++i ) + g_tasks_expected += FindNumOfTasks( g_depths[i].value() ); + // Test for iterators over values convertible to work item type + TestIterator_Movable<size_t*>(depth); + // Test for random access iterators + TestIterator_Modifiable<value_t*>(depth); + // Test for input iterators + TestIterator_Modifiable<Harness::InputIterator<value_t> >(depth); + // Test for forward iterators + TestIterator_Modifiable<Harness::ForwardIterator<value_t> >(depth); + // Test for const random access iterators + TestIterator_Const<Harness::ConstRandomIterator<value_t> >(depth); + } +} + +const size_t elements = 10000; +const size_t init_sum = 0; +tbb::atomic<size_t> element_counter; + +template<size_t K> +struct set_to { + void operator()(size_t& x) const { + x = K; + ++element_counter; + } +}; + +#include "test_range_based_for.h" +#include <functional> +#include <deque> + +void range_do_test() { + using namespace range_based_for_support_tests; + std::deque<size_t> v(elements, 0); + + // iterator, const and non-const range check + element_counter = 0; + tbb::parallel_do(v.begin(), v.end(), set_to<1>()); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == v.size(), "elements of v not all ones"); + + element_counter = 0; + tbb::parallel_do(v, set_to<0>()); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == init_sum, "elements of v not all zeros"); + + element_counter = 0; + tbb::parallel_do(tbb::blocked_range<std::deque<size_t>::iterator>(v.begin(), v.end()), set_to<1>()); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == v.size(), "elements of v not all ones"); + + // same as above with context group + element_counter = 0; + tbb::task_group_context context; + tbb::parallel_do(v.begin(), v.end(), set_to<0>(), context); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == init_sum, "elements of v not all ones"); + + element_counter = 0; + tbb::parallel_do(v, set_to<1>(), context); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == v.size(), "elements of v not all ones"); + + element_counter = 0; + tbb::parallel_do(tbb::blocked_range<std::deque<size_t>::iterator>(v.begin(), v.end()), set_to<0>(), context); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == init_sum, "elements of v not all zeros"); +} + +#if __TBB_CPP11_RVALUE_REF_PRESENT +namespace TestMoveSem { + struct MovePreferable : Movable { + MovePreferable() : Movable(), addtofeed(true) {} + MovePreferable(bool addtofeed_) : Movable(), addtofeed(addtofeed_) {} + MovePreferable(MovePreferable&& other) : Movable(std::move(other)), addtofeed(other.addtofeed) {}; + // base class is explicitly initialized in the copy ctor to avoid -Wextra warnings + MovePreferable(const MovePreferable& other) : Movable(other) { REPORT("Error: copy ctor preferred.\n"); }; + MovePreferable& operator=(const MovePreferable&) { REPORT("Error: copy assign operator preferred.\n"); return *this; } + bool addtofeed; + }; + struct MoveOnly : MovePreferable, NoCopy { + MoveOnly() : MovePreferable() {} + MoveOnly(bool addtofeed_) : MovePreferable(addtofeed_) {} + MoveOnly(MoveOnly&& other) : MovePreferable(std::move(other)) {}; + }; +} + +template<typename T> +void RecordAndAdd(const T& in, tbb::parallel_do_feeder<T>& feeder) { + ASSERT(in.alive, "Got dead object in body"); + size_t i = ++g_tasks_observed; + if (in.addtofeed) { + if (i%2) feeder.add(T(false)); + else { + T a(false); + feeder.add(std::move(a)); + } + } +} +// Take an item by rvalue reference +template<typename T> +struct TestMoveIteratorBody { + void operator() (T&& in, tbb::parallel_do_feeder<T>& feeder) const { RecordAndAdd(in, feeder); } +}; +// Take an item by value +template<typename T> +struct TestMoveIteratorBodyByValue { + void operator() (T in, tbb::parallel_do_feeder<T>& feeder) const { RecordAndAdd(in, feeder); } +}; + +template<typename Iterator, typename Body> +void TestMoveIterator() { + typedef typename std::iterator_traits<Iterator>::value_type value_type; + + Body body; + const size_t size = 65; + g_tasks_observed = 0; + value_type a[size]; + tbb::parallel_do( std::make_move_iterator(Iterator(a)), std::make_move_iterator(Iterator(a+size)), body ); + ASSERT(size * 2 == g_tasks_observed, NULL); +} + +template<typename T> +void DoTestMoveSemantics() { + TestMoveIterator< Harness::InputIterator<T>, TestMoveIteratorBody<T> >(); + TestMoveIterator< Harness::ForwardIterator<T>, TestMoveIteratorBody<T> >(); + TestMoveIterator< Harness::RandomIterator<T>, TestMoveIteratorBody<T> >(); + + TestMoveIterator< Harness::InputIterator<T>, TestMoveIteratorBodyByValue<T> >(); + TestMoveIterator< Harness::ForwardIterator<T>, TestMoveIteratorBodyByValue<T> >(); + TestMoveIterator< Harness::RandomIterator<T>, TestMoveIteratorBodyByValue<T> >(); +} + +void TestMoveSemantics() { + DoTestMoveSemantics<TestMoveSem::MovePreferable>(); +#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT && !__TBB_IS_COPY_CONSTRUCTIBLE_BROKEN + // parallel_do uses is_copy_constructible to support non-copyable types + DoTestMoveSemantics<TestMoveSem::MoveOnly>(); +#endif +} +#else /* __TBB_CPP11_RVALUE_REF_PRESENT */ +void TestMoveSemantics() { + REPORT("Known issue: move support tests are skipped.\n"); +} +#endif + +int TestMain () { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + g_values_counter = 0; + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init( p ); + Run(p); + range_do_test(); + // Test that all workers sleep when no work + TestCPUUserTime(p); + } + // This check must be performed after the scheduler terminated because only in this + // case there is a guarantee that the workers already destroyed their last tasks. + ASSERT( g_values_counter == 0, "Value objects were leaked" ); + + TestMoveSemantics(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for.cpp new file mode 100644 index 00000000..abc21a0a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for.cpp @@ -0,0 +1,777 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Test for function template parallel_for.h + +// These features are pure additions and thus can be always "on" in the test +#define TBB_PREVIEW_SERIAL_SUBSET 1 +#include "harness_defs.h" + +#if _MSC_VER +#pragma warning (push) +#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED + // Suppress pointless "unreachable code" warning. + #pragma warning (disable: 4702) +#endif +#if defined(_Wp64) + // Workaround for overzealous compiler warnings in /Wp64 mode + #pragma warning (disable: 4267) +#endif + +#define _SCL_SECURE_NO_WARNINGS +#endif //#if _MSC_VER + +#include "harness_defs.h" +#include "tbb/parallel_for.h" +#include "tbb/atomic.h" +#include "harness_assert.h" +#include "harness.h" + +static tbb::atomic<int> FooBodyCount; + +//! A range object whose only public members are those required by the Range concept. +template<size_t Pad> +class FooRange { + //! Start of range + int start; + + //! Size of range + int size; + FooRange( int start_, int size_ ) : start(start_), size(size_) { + zero_fill<char>(pad, Pad); + pad[Pad-1] = 'x'; + } + template<typename Flavor_, size_t Pad_> friend void Flog( int nthread ); + template<size_t Pad_> friend class FooBody; + void operator&(); + + char pad[Pad]; +public: + bool empty() const {return size==0;} + bool is_divisible() const {return size>1;} + FooRange( FooRange& original, tbb::split ) : size(original.size/2) { + original.size -= size; + start = original.start+original.size; + ASSERT( original.pad[Pad-1]=='x', NULL ); + pad[Pad-1] = 'x'; + } +}; + +//! A range object whose only public members are those required by the parallel_for.h body concept. +template<size_t Pad> +class FooBody { + static const int LIVE = 0x1234; + tbb::atomic<int>* array; + int state; + friend class FooRange<Pad>; + template<typename Flavor_, size_t Pad_> friend void Flog( int nthread ); + FooBody( tbb::atomic<int>* array_ ) : array(array_), state(LIVE) {} +public: + ~FooBody() { + --FooBodyCount; + for( size_t i=0; i<sizeof(*this); ++i ) + reinterpret_cast<char*>(this)[i] = -1; + } + //! Copy constructor + FooBody( const FooBody& other ) : array(other.array), state(other.state) { + ++FooBodyCount; + ASSERT( state==LIVE, NULL ); + } + void operator()( FooRange<Pad>& r ) const { + for( int k=0; k<r.size; ++k ) { + const int i = array[r.start+k]++; + ASSERT( i==0, NULL ); + } + } +}; + +#include "tbb/tick_count.h" + +static const int N = 500; +static tbb::atomic<int> Array[N]; + +struct serial_tag {}; +struct parallel_tag {}; +struct empty_partitioner_tag {}; + +template <typename Flavor, typename Partitioner, typename Range, typename Body> +struct Invoker; + +#if TBB_PREVIEW_SERIAL_SUBSET +template <typename Range, typename Body> +struct Invoker<serial_tag, empty_partitioner_tag, Range, Body> { + void operator()( const Range& r, const Body& body, empty_partitioner_tag& ) { + tbb::serial:: parallel_for( r, body ); + } +}; +template <typename Partitioner, typename Range, typename Body> +struct Invoker<serial_tag, Partitioner, Range, Body> { + void operator()( const Range& r, const Body& body, Partitioner& p ) { + tbb::serial:: parallel_for( r, body, p ); + } +}; +#endif + +template <typename Range, typename Body> +struct Invoker<parallel_tag, empty_partitioner_tag, Range, Body> { + void operator()( const Range& r, const Body& body, empty_partitioner_tag& ) { + tbb:: parallel_for( r, body ); + } +}; + +template <typename Partitioner, typename Range, typename Body> +struct Invoker<parallel_tag, Partitioner, Range, Body> { + void operator()( const Range& r, const Body& body, Partitioner& p ) { + tbb:: parallel_for( r, body, p ); + } +}; + +template <typename Flavor, typename Partitioner, typename T, typename Body> +struct InvokerStep; + +#if TBB_PREVIEW_SERIAL_SUBSET +template <typename T, typename Body> +struct InvokerStep<serial_tag, empty_partitioner_tag, T, Body> { + void operator()( const T& first, const T& last, const Body& f, empty_partitioner_tag& ) { + tbb::serial:: parallel_for( first, last, f ); + } + void operator()( const T& first, const T& last, const T& step, const Body& f, empty_partitioner_tag& ) { + tbb::serial:: parallel_for( first, last, step, f ); + } +}; + +template <typename Partitioner, typename T, typename Body> +struct InvokerStep<serial_tag, Partitioner, T, Body> { + void operator()( const T& first, const T& last, const Body& f, Partitioner& p ) { + tbb::serial:: parallel_for( first, last, f, p); + } + void operator()( const T& first, const T& last, const T& step, const Body& f, Partitioner& p ) { + tbb::serial:: parallel_for( first, last, step, f, p ); + } +}; +#endif + +template <typename T, typename Body> +struct InvokerStep<parallel_tag, empty_partitioner_tag, T, Body> { + void operator()( const T& first, const T& last, const Body& f, empty_partitioner_tag& ) { + tbb:: parallel_for( first, last, f ); + } + void operator()( const T& first, const T& last, const T& step, const Body& f, empty_partitioner_tag& ) { + tbb:: parallel_for( first, last, step, f ); + } +}; + +template <typename Partitioner, typename T, typename Body> +struct InvokerStep<parallel_tag, Partitioner, T, Body> { + void operator()( const T& first, const T& last, const Body& f, Partitioner& p ) { + tbb:: parallel_for( first, last, f, p ); + } + void operator()( const T& first, const T& last, const T& step, const Body& f, Partitioner& p ) { + tbb:: parallel_for( first, last, step, f, p ); + } +}; + +template<typename Flavor, size_t Pad> +void Flog( int nthread ) { + tbb::tick_count T0 = tbb::tick_count::now(); + for( int i=0; i<N; ++i ) { + for ( int mode = 0; mode < 4; ++mode) { + FooRange<Pad> r( 0, i ); + const FooRange<Pad> rc = r; + FooBody<Pad> f( Array ); + const FooBody<Pad> fc = f; + memset( Array, 0, sizeof(Array) ); + FooBodyCount = 1; + switch (mode) { + case 0: { + empty_partitioner_tag p; + Invoker< Flavor, empty_partitioner_tag, FooRange<Pad>, FooBody<Pad> > invoke_for; + invoke_for( rc, fc, p ); + } + break; + case 1: { + Invoker< Flavor, const tbb::simple_partitioner, FooRange<Pad>, FooBody<Pad> > invoke_for; + invoke_for( rc, fc, tbb::simple_partitioner() ); + } + break; + case 2: { + Invoker< Flavor, const tbb::auto_partitioner, FooRange<Pad>, FooBody<Pad> > invoke_for; + invoke_for( rc, fc, tbb::auto_partitioner() ); + } + break; + case 3: { + static tbb::affinity_partitioner affinity; + Invoker< Flavor, tbb::affinity_partitioner, FooRange<Pad>, FooBody<Pad> > invoke_for; + invoke_for( rc, fc, affinity ); + } + break; + } + for( int j=0; j<i; ++j ) + ASSERT( Array[j]==1, NULL ); + for( int j=i; j<N; ++j ) + ASSERT( Array[j]==0, NULL ); + ASSERT( FooBodyCount==1, NULL ); + } + } + tbb::tick_count T1 = tbb::tick_count::now(); + REMARK("time=%g\tnthread=%d\tpad=%d\n",(T1-T0).seconds(),nthread,int(Pad)); +} + +// Testing parallel_for with step support +const size_t PFOR_BUFFER_TEST_SIZE = 1024; +// test_buffer has some extra items beyond its right bound +const size_t PFOR_BUFFER_ACTUAL_SIZE = PFOR_BUFFER_TEST_SIZE + 1024; +size_t pfor_buffer[PFOR_BUFFER_ACTUAL_SIZE]; + +template<typename T> +class TestFunctor{ +public: + void operator ()(T index) const { + pfor_buffer[index]++; + } +}; + +#include <stdexcept> // std::invalid_argument + +template <typename Flavor, typename T, typename Partitioner> +void TestParallelForWithStepSupportHelper(Partitioner& p) +{ + const T pfor_buffer_test_size = static_cast<T>(PFOR_BUFFER_TEST_SIZE); + const T pfor_buffer_actual_size = static_cast<T>(PFOR_BUFFER_ACTUAL_SIZE); + // Testing parallel_for with different step values + InvokerStep< Flavor, Partitioner, T, TestFunctor<T> > invoke_for; + for (T begin = 0; begin < pfor_buffer_test_size - 1; begin += pfor_buffer_test_size / 10 + 1) { + T step; + for (step = 1; step < pfor_buffer_test_size; step++) { + memset(pfor_buffer, 0, pfor_buffer_actual_size * sizeof(size_t)); + if (step == 1){ + invoke_for(begin, pfor_buffer_test_size, TestFunctor<T>(), p); + } else { + invoke_for(begin, pfor_buffer_test_size, step, TestFunctor<T>(), p); + } + // Verifying that parallel_for processed all items it should + for (T i = begin; i < pfor_buffer_test_size; i = i + step) { + ASSERT(pfor_buffer[i] == 1, "parallel_for didn't process all required elements"); + pfor_buffer[i] = 0; + } + // Verifying that no extra items were processed and right bound of array wasn't crossed + for (T i = 0; i < pfor_buffer_actual_size; i++) { + ASSERT(pfor_buffer[i] == 0, "parallel_for processed an extra element"); + } + } + } +} + +template <typename Flavor, typename T> +void TestParallelForWithStepSupport() +{ + static tbb::affinity_partitioner affinity_p; + tbb::auto_partitioner auto_p; + tbb::simple_partitioner simple_p; + empty_partitioner_tag p; + + // Try out all partitioner combinations + TestParallelForWithStepSupportHelper< Flavor,T,empty_partitioner_tag >(p); + TestParallelForWithStepSupportHelper< Flavor,T,const tbb::auto_partitioner >(auto_p); + TestParallelForWithStepSupportHelper< Flavor,T,const tbb::simple_partitioner >(simple_p); + TestParallelForWithStepSupportHelper< Flavor,T,tbb::affinity_partitioner >(affinity_p); + + // Testing some corner cases + tbb::parallel_for(static_cast<T>(2), static_cast<T>(1), static_cast<T>(1), TestFunctor<T>()); +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + try{ + tbb::parallel_for(static_cast<T>(1), static_cast<T>(100), static_cast<T>(0), TestFunctor<T>()); // should cause std::invalid_argument + }catch(std::invalid_argument&){ + return; + } + catch ( ... ) { + ASSERT ( __TBB_EXCEPTION_TYPE_INFO_BROKEN, "Unrecognized exception. std::invalid_argument is expected" ); + } +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ +} + +#if __TBB_TASK_GROUP_CONTEXT +// Exception support test +#define HARNESS_EH_SIMPLE_MODE 1 +#include "tbb/tbb_exception.h" +#include "harness_eh.h" + +#if TBB_USE_EXCEPTIONS +class test_functor_with_exception { +public: + void operator ()(size_t) const { ThrowTestException(); } +}; + +void TestExceptionsSupport() { + REMARK (__FUNCTION__); + { // Tests version with a step provided + ResetEhGlobals(); + TRY(); + tbb::parallel_for((size_t)0, (size_t)PFOR_BUFFER_TEST_SIZE, (size_t)1, test_functor_with_exception()); + CATCH_AND_ASSERT(); + } + { // Tests version without a step + ResetEhGlobals(); + TRY(); + tbb::parallel_for((size_t)0, (size_t)PFOR_BUFFER_TEST_SIZE, test_functor_with_exception()); + CATCH_AND_ASSERT(); + } +} +#endif /* TBB_USE_EXCEPTIONS */ + +// Cancellation support test +class functor_to_cancel { +public: + void operator()(size_t) const { + ++g_CurExecuted; + CancellatorTask::WaitUntilReady(); + } +}; + +size_t g_worker_task_step = 0; + +class my_worker_pfor_step_task : public tbb::task +{ + tbb::task_group_context &my_ctx; + + tbb::task* execute () __TBB_override { + if (g_worker_task_step == 0){ + tbb::parallel_for((size_t)0, (size_t)PFOR_BUFFER_TEST_SIZE, functor_to_cancel(), my_ctx); + }else{ + tbb::parallel_for((size_t)0, (size_t)PFOR_BUFFER_TEST_SIZE, g_worker_task_step, functor_to_cancel(), my_ctx); + } + return NULL; + } +public: + my_worker_pfor_step_task ( tbb::task_group_context &context_) : my_ctx(context_) { } +}; + +void TestCancellation() +{ + // tests version without a step + g_worker_task_step = 0; + ResetEhGlobals(); + RunCancellationTest<my_worker_pfor_step_task, CancellatorTask>(); + + // tests version with step + g_worker_task_step = 1; + ResetEhGlobals(); + RunCancellationTest<my_worker_pfor_step_task, CancellatorTask>(); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#include "harness_m128.h" + +#if (HAVE_m128 || HAVE_m256) && !__TBB_SSE_STACK_ALIGNMENT_BROKEN +template<typename ClassWithVectorType> +struct SSE_Functor { + ClassWithVectorType* Src, * Dst; + SSE_Functor( ClassWithVectorType* src, ClassWithVectorType* dst ) : Src(src), Dst(dst) {} + + void operator()( tbb::blocked_range<int>& r ) const { + for( int i=r.begin(); i!=r.end(); ++i ) + Dst[i] = Src[i]; + } +}; + +//! Test that parallel_for works with stack-allocated __m128 +template<typename ClassWithVectorType> +void TestVectorTypes() { + const int aSize = 300; + ClassWithVectorType Array1[aSize], Array2[aSize]; + for( int i=0; i<aSize; ++i ) { + // VC8 does not properly align a temporary value; to work around, use explicit variable + ClassWithVectorType foo(i); + Array1[i] = foo; + } + tbb::parallel_for( tbb::blocked_range<int>(0,aSize), SSE_Functor<ClassWithVectorType>(Array1, Array2) ); + for( int i=0; i<aSize; ++i ) { + ClassWithVectorType foo(i); + ASSERT( Array2[i]==foo, NULL ) ; + } +} +#endif /* HAVE_m128 || HAVE_m256 */ + +#include <vector> +#include <sstream> +#include <tbb/blocked_range.h> + +struct TestSimplePartitionerStabilityFunctor:NoAssign{ + std::vector<int> & ranges; + TestSimplePartitionerStabilityFunctor(std::vector<int> & theRanges):ranges(theRanges){} + void operator()(tbb::blocked_range<size_t>& r)const{ + ranges.at(r.begin())=true; + } +}; +void TestSimplePartitionerStability(){ + const std::size_t repeat_count= 10; + const std::size_t rangeToSplitSize=1000000; + const std::size_t grainsizeStep=rangeToSplitSize/repeat_count; + typedef TestSimplePartitionerStabilityFunctor FunctorType; + + for (std::size_t i=0 , grainsize=grainsizeStep; i<repeat_count;i++, grainsize+=grainsizeStep){ + std::vector<int> firstSeries(rangeToSplitSize,0); + std::vector<int> secondSeries(rangeToSplitSize,0); + + tbb::parallel_for(tbb::blocked_range<size_t>(0,rangeToSplitSize,grainsize),FunctorType(firstSeries),tbb::simple_partitioner()); + tbb::parallel_for(tbb::blocked_range<size_t>(0,rangeToSplitSize,grainsize),FunctorType(secondSeries),tbb::simple_partitioner()); + std::stringstream str; str<<i; + ASSERT(firstSeries==secondSeries,("splitting range with tbb::simple_partitioner must be reproducible; i=" +str.str()).c_str() ); + } +} +#include <cstdio> +#include "tbb/task_scheduler_init.h" +#include "harness_cpu.h" +#include "harness_barrier.h" +#include "test_partitioner.h" + +namespace interaction_with_range_and_partitioner { + +// Test checks compatibility of parallel_for algorithm with various range implementations + +void test() { + using namespace test_partitioner_utils::interaction_with_range_and_partitioner; + + test_partitioner_utils::SimpleBody b; + tbb::affinity_partitioner ap; + + parallel_for(Range1(true, false), b, ap); + parallel_for(Range2(true, false), b, ap); + parallel_for(Range3(true, false), b, ap); + parallel_for(Range4(false, true), b, ap); + parallel_for(Range5(false, true), b, ap); + parallel_for(Range6(false, true), b, ap); + + parallel_for(Range1(false, true), b, tbb::simple_partitioner()); + parallel_for(Range2(false, true), b, tbb::simple_partitioner()); + parallel_for(Range3(false, true), b, tbb::simple_partitioner()); + parallel_for(Range4(false, true), b, tbb::simple_partitioner()); + parallel_for(Range5(false, true), b, tbb::simple_partitioner()); + parallel_for(Range6(false, true), b, tbb::simple_partitioner()); + + parallel_for(Range1(false, true), b, tbb::auto_partitioner()); + parallel_for(Range2(false, true), b, tbb::auto_partitioner()); + parallel_for(Range3(false, true), b, tbb::auto_partitioner()); + parallel_for(Range4(false, true), b, tbb::auto_partitioner()); + parallel_for(Range5(false, true), b, tbb::auto_partitioner()); + parallel_for(Range6(false, true), b, tbb::auto_partitioner()); +} + +} // namespace interaction_with_range_and_partitioner + +namespace various_range_implementations { + +using namespace test_partitioner_utils; +using namespace test_partitioner_utils::TestRanges; + +// Body ensures that initial work distribution is done uniformly through affinity mechanism and not +// through work stealing +class Body { + Harness::SpinBarrier &m_sb; +public: + Body(Harness::SpinBarrier& sb) : m_sb(sb) { } + Body(Body& b, tbb::split) : m_sb(b.m_sb) { } + Body& operator =(const Body&) { return *this; } + template <typename Range> + void operator()(Range& r) const { + REMARK("Executing range [%lu, %lu)\n", r.begin(), r.end()); + m_sb.timed_wait(10); // waiting for all threads + } +}; + +namespace correctness { + +/* Testing only correctness (that is parallel_for does not hang) */ +template <typename RangeType, bool /* feedback */, bool ensure_non_emptiness> +void test() { + static const int thread_num = tbb::task_scheduler_init::default_num_threads(); + RangeType range( 0, thread_num, NULL, false, ensure_non_emptiness ); + tbb::affinity_partitioner ap; + tbb::parallel_for( range, SimpleBody(), ap ); +} + +} // namespace correctness + +namespace uniform_distribution { + +/* Body of parallel_for algorithm would hang if non-uniform work distribution happened */ +template <typename RangeType, bool feedback, bool ensure_non_emptiness> +void test() { + static const int thread_num = tbb::task_scheduler_init::default_num_threads(); + Harness::SpinBarrier sb( thread_num ); + RangeType range(0, thread_num, NULL, feedback, ensure_non_emptiness); + const Body sync_body( sb ); + tbb::affinity_partitioner ap; + tbb::parallel_for( range, sync_body, ap ); + tbb::parallel_for( range, sync_body, tbb::static_partitioner() ); +} + +} // namespace uniform_distribution + +void test() { + const bool provide_feedback = __TBB_ENABLE_RANGE_FEEDBACK; + const bool ensure_non_empty_range = true; + + // BlockedRange does not take into account feedback and non-emptiness settings but uses the + // tbb::blocked_range implementation + uniform_distribution::test<BlockedRange, !provide_feedback, !ensure_non_empty_range>(); + +#if __TBB_ENABLE_RANGE_FEEDBACK + using uniform_distribution::test; // if feedback is enabled ensure uniform work distribution +#else + using correctness::test; +#endif + + { + test<RoundedDownRange, provide_feedback, ensure_non_empty_range>(); + test<RoundedDownRange, provide_feedback, !ensure_non_empty_range>(); +#if __TBB_ENABLE_RANGE_FEEDBACK && !__TBB_MIC_NATIVE + // due to fast division algorithm on MIC + test<RoundedDownRange, !provide_feedback, ensure_non_empty_range>(); + test<RoundedDownRange, !provide_feedback, !ensure_non_empty_range>(); +#endif + } + + { + test<RoundedUpRange, provide_feedback, ensure_non_empty_range>(); + test<RoundedUpRange, provide_feedback, !ensure_non_empty_range>(); +#if __TBB_ENABLE_RANGE_FEEDBACK && !__TBB_MIC_NATIVE + // due to fast division algorithm on MIC + test<RoundedUpRange, !provide_feedback, ensure_non_empty_range>(); + test<RoundedUpRange, !provide_feedback, !ensure_non_empty_range>(); +#endif + } + + // Testing that parallel_for algorithm works with such weird ranges + correctness::test<Range1_2, /* provide_feedback= */ false, !ensure_non_empty_range>(); + correctness::test<Range1_999, /* provide_feedback= */ false, !ensure_non_empty_range>(); + correctness::test<Range999_1, /* provide_feedback= */ false, !ensure_non_empty_range>(); + + // The following ranges do not comply with the proportion suggested by partitioner. Therefore + // they have to provide the proportion in which they were actually split back to partitioner and + // ensure theirs non-emptiness + test<Range1_2, provide_feedback, ensure_non_empty_range>(); + test<Range1_999, provide_feedback, ensure_non_empty_range>(); + test<Range999_1, provide_feedback, ensure_non_empty_range>(); +} + +} // namespace various_range_implementations + +#include <map> +#include <utility> +#include "tbb/task_arena.h" +#include "tbb/enumerable_thread_specific.h" + +namespace parallel_for_within_task_arena { + +using namespace test_partitioner_utils::TestRanges; +using tbb::split; +using tbb::proportional_split; + +class BlockedRangeWhitebox; + +typedef std::pair<size_t, size_t> range_borders; +typedef std::multimap<BlockedRangeWhitebox*, range_borders> MapType; +typedef tbb::enumerable_thread_specific<MapType> ETSType; +ETSType ets; + +class BlockedRangeWhitebox : public BlockedRange { +public: + static const bool is_splittable_in_proportion = true; + BlockedRangeWhitebox(size_t _begin, size_t _end) + : BlockedRange(_begin, _end, NULL, false, false) { } + + BlockedRangeWhitebox(BlockedRangeWhitebox& r, proportional_split& p) + :BlockedRange(r, p) { + update_ets(r); + update_ets(*this); + } + + BlockedRangeWhitebox(BlockedRangeWhitebox& r, split) + :BlockedRange(r, split()) { } + + void update_ets(BlockedRangeWhitebox& range) { + std::pair<MapType::iterator, MapType::iterator> equal_range = ets.local().equal_range(&range); + for (MapType::iterator it = equal_range.first; it != equal_range.second;++it) { + if (it->second.first <= range.begin() && range.end() <= it->second.second) { + ASSERT(!(it->second.first == range.begin() && it->second.second == range.end()), "Only one border of the range should be equal to the original"); + it->second.first = range.begin(); + it->second.second = range.end(); + return; + } + } + ets.local().insert(std::make_pair<BlockedRangeWhitebox*, range_borders>(&range, range_borders(range.begin(), range.end()))); + } +}; + +template <typename Partitioner> +struct ArenaBody { + size_t range_begin; + size_t range_end; + + ArenaBody(size_t _range_begin, size_t _range_end) + :range_begin(_range_begin), range_end(_range_end) { } + + void operator()() const { + Partitioner my_partitioner; + tbb::parallel_for(BlockedRangeWhitebox(range_begin, range_end), test_partitioner_utils::SimpleBody(), my_partitioner); + } +}; + +struct CombineBody { + MapType operator()(MapType x, const MapType& y) const { + x.insert(y.begin(), y.end()); + for (MapType::iterator it1 = x.begin(); it1 != x.end(); ++it1) { + for (MapType::iterator it2 = x.begin(); it2 != x.end(); ++it2) { + if (it1 == it2) continue; + bool is_1_subrange_of_2 = + it2->second.first <= it1->second.first && it1->second.second <= it2->second.second; + if (is_1_subrange_of_2) { + x.erase(it2); + break; + } + } + } + return x; + } +}; + +range_borders combine_range(const MapType& map) { + range_borders result_range = map.begin()->second; + for (MapType::const_iterator it = map.begin(); it != map.end(); it++) + result_range = range_borders( + (std::min)(result_range.first, it->second.first), + (std::max)(result_range.second, it->second.second) + ); + return result_range; +} + +template <typename Partitioner> +void test_body() { + unsigned hw_concurrency = tbb::tbb_thread::hardware_concurrency(); + for (unsigned int num_threads = hw_concurrency / 4 + 1; num_threads < hw_concurrency; num_threads *= 2) { + REMARK(" num_threads=%lu\n", num_threads); + for (size_t range_begin = 0, range_end = num_threads * 10 - 1, i = 0; i < 3; + range_begin += num_threads, range_end += num_threads + 1, ++i) { + REMARK(" processing range [%lu, %lu)\n", range_begin, range_end); + ets = ETSType(MapType()); + tbb::task_arena limited(num_threads); // at least two slots in arena. + limited.execute(ArenaBody<Partitioner>(range_begin, range_end)); + MapType combined_map = ets.combine(CombineBody()); + range_borders result_borders = combine_range(combined_map); + ASSERT(result_borders.first == range_begin, "Restored range begin does not match initial one"); + ASSERT(result_borders.second == range_end, "Restored range end does not match initial one"); + size_t map_size = combined_map.size(); + // In a single-thread arena, partitioners still do one split of a range. + size_t range_partitions = num_threads > 1 ? num_threads : 2; + ASSERT((map_size == range_partitions), "Incorrect number or post-proportional split ranges"); + size_t expected_size = (range_end - range_begin) / range_partitions; + for (MapType::iterator it = combined_map.begin(); it != combined_map.end(); ++it) { + size_t size = it->second.second - it->second.first; + ASSERT((size == expected_size || size == expected_size + 1), "Incorrect post-proportional range size"); + } + } + } +} + +void test() { + REMARK("parallel_for with affinity partitioner within task_arena\n"); + test_body<tbb::affinity_partitioner>(); + REMARK("parallel_for with static partitioner within task_arena\n"); + test_body<tbb::static_partitioner>(); +} + +} // namespace parallel_for_within_task_arena + +int TestMain () { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + if( p>0 ) { + tbb::task_scheduler_init init( p ); + Flog<parallel_tag,1>(p); + Flog<parallel_tag,10>(p); + Flog<parallel_tag,100>(p); + Flog<parallel_tag,1000>(p); + Flog<parallel_tag,10000>(p); + + // Testing with different integer types + TestParallelForWithStepSupport<parallel_tag,short>(); + TestParallelForWithStepSupport<parallel_tag,unsigned short>(); + TestParallelForWithStepSupport<parallel_tag,int>(); + TestParallelForWithStepSupport<parallel_tag,unsigned int>(); + TestParallelForWithStepSupport<parallel_tag,long>(); + TestParallelForWithStepSupport<parallel_tag,unsigned long>(); + TestParallelForWithStepSupport<parallel_tag,long long>(); + TestParallelForWithStepSupport<parallel_tag,unsigned long long>(); + TestParallelForWithStepSupport<parallel_tag,size_t>(); + +#if TBB_PREVIEW_SERIAL_SUBSET + // This is for testing serial implementation. + if( p == MaxThread ) { + Flog<serial_tag,1>(p); + Flog<serial_tag,10>(p); + Flog<serial_tag,100>(p); + TestParallelForWithStepSupport<serial_tag,short>(); + TestParallelForWithStepSupport<serial_tag,unsigned short>(); + TestParallelForWithStepSupport<serial_tag,int>(); + TestParallelForWithStepSupport<serial_tag,unsigned int>(); + TestParallelForWithStepSupport<serial_tag,long>(); + TestParallelForWithStepSupport<serial_tag,unsigned long>(); + TestParallelForWithStepSupport<serial_tag,long long>(); + TestParallelForWithStepSupport<serial_tag,unsigned long long>(); + TestParallelForWithStepSupport<serial_tag,size_t>(); + } +#endif + +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + TestExceptionsSupport(); +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ +#if __TBB_TASK_GROUP_CONTEXT + if ( p > 1 ) + TestCancellation(); +#endif /* __TBB_TASK_GROUP_CONTEXT */ +#if !__TBB_SSE_STACK_ALIGNMENT_BROKEN + #if HAVE_m128 + TestVectorTypes<ClassWithSSE>(); + #endif + #if HAVE_m256 + if (have_AVX()) TestVectorTypes<ClassWithAVX>(); + #endif +#endif /*!__TBB_SSE_STACK_ALIGNMENT_BROKEN*/ + // Test that all workers sleep when no work + TestCPUUserTime(p); + TestSimplePartitionerStability(); + } + } +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + REPORT("Known issue: exception handling tests are skipped.\n"); +#endif +#if (HAVE_m128 || HAVE_m256) && __TBB_SSE_STACK_ALIGNMENT_BROKEN + REPORT("Known issue: stack alignment for SIMD instructions not tested.\n"); +#endif + + various_range_implementations::test(); + interaction_with_range_and_partitioner::test(); + parallel_for_within_task_arena::test(); + return Harness::Done; +} + +#if _MSC_VER +#pragma warning (pop) +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for_each.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for_each.cpp new file mode 100644 index 00000000..7e942ebc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for_each.cpp @@ -0,0 +1,244 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _MSC_VER && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4180) // "qualifier applied to function type has no meaning; ignored" +#endif + +#include "tbb/parallel_for_each.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/atomic.h" +#include "harness.h" +#include "harness_iterator.h" +#include <list> + +// Some old compilers can't deduce template parameter type for parallel_for_each +// if the function name is passed without explicit cast to function pointer. +typedef void (*TestFunctionType)(size_t); + +tbb::atomic<size_t> sum; + +// This function is called via parallel_for_each +void TestFunction (size_t value) { + sum += (unsigned int)value; +} + +const size_t NUMBER_OF_ELEMENTS = 1000; + +// Tests tbb::parallel_for_each functionality +template <typename Iterator> +void RunPForEachTests() +{ + size_t test_vector[NUMBER_OF_ELEMENTS + 1]; + + sum = 0; + size_t test_sum = 0; + + for (size_t i =0; i < NUMBER_OF_ELEMENTS; i++) { + test_vector[i] = i; + test_sum += i; + } + test_vector[NUMBER_OF_ELEMENTS] = 1000000; // parallel_for_each shouldn't touch this element + + Iterator begin(&test_vector[0]); + Iterator end(&test_vector[NUMBER_OF_ELEMENTS]); + + tbb::parallel_for_each(begin, end, (TestFunctionType)TestFunction); + ASSERT(sum == test_sum, "Not all items of test vector were processed by parallel_for_each"); + ASSERT(test_vector[NUMBER_OF_ELEMENTS] == 1000000, "parallel_for_each processed an extra element"); +} + +typedef void (*TestMutatorType)(size_t&); + +void TestMutator(size_t& value) { + ASSERT(value==0,NULL); + ++sum; + ++value; +} + +//! Test that tbb::parallel_for_each works for mutable iterators. +template <typename Iterator> +void RunMutablePForEachTests() { + size_t test_vector[NUMBER_OF_ELEMENTS]; + for( size_t i=0; i<NUMBER_OF_ELEMENTS; ++i ) + test_vector[i] = 0; + sum = 0; + tbb::parallel_for_each( Iterator(test_vector), Iterator(test_vector+NUMBER_OF_ELEMENTS), (TestMutatorType)TestMutator ); + ASSERT( sum==NUMBER_OF_ELEMENTS, "parallel_for_each called function wrong number of times" ); + for( size_t i=0; i<NUMBER_OF_ELEMENTS; ++i ) + ASSERT( test_vector[i]==1, "parallel_for_each did not process each element exactly once" ); +} + +#if __TBB_TASK_GROUP_CONTEXT +#define HARNESS_EH_SIMPLE_MODE 1 +#include "tbb/tbb_exception.h" +#include "harness_eh.h" + +#if TBB_USE_EXCEPTIONS +void test_function_with_exception(size_t) { + ThrowTestException(); +} + +template <typename Iterator> +void TestExceptionsSupport() +{ + REMARK (__FUNCTION__); + size_t test_vector[NUMBER_OF_ELEMENTS + 1]; + + for (size_t i = 0; i < NUMBER_OF_ELEMENTS; i++) { + test_vector[i] = i; + } + + Iterator begin(&test_vector[0]); + Iterator end(&test_vector[NUMBER_OF_ELEMENTS]); + + TRY(); + tbb::parallel_for_each(begin, end, (TestFunctionType)test_function_with_exception); + CATCH_AND_ASSERT(); +} +#endif /* TBB_USE_EXCEPTIONS */ + +// Cancellation support test +void function_to_cancel(size_t ) { + ++g_CurExecuted; + CancellatorTask::WaitUntilReady(); +} + +template <typename Iterator> +class my_worker_pforeach_task : public tbb::task +{ + tbb::task_group_context &my_ctx; + + tbb::task* execute () __TBB_override { + size_t test_vector[NUMBER_OF_ELEMENTS + 1]; + for (size_t i = 0; i < NUMBER_OF_ELEMENTS; i++) { + test_vector[i] = i; + } + Iterator begin(&test_vector[0]); + Iterator end(&test_vector[NUMBER_OF_ELEMENTS]); + + tbb::parallel_for_each(begin, end, (TestFunctionType)function_to_cancel); + + return NULL; + } +public: + my_worker_pforeach_task ( tbb::task_group_context &ctx) : my_ctx(ctx) { } +}; + +template <typename Iterator> +void TestCancellation() +{ + REMARK (__FUNCTION__); + ResetEhGlobals(); + RunCancellationTest<my_worker_pforeach_task<Iterator>, CancellatorTask>(); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +#include "harness_cpu.h" + +const size_t elements = 10000; +const size_t init_sum = 0; +tbb::atomic<size_t> element_counter; + +template<size_t K> +struct set_to { + void operator()(size_t& x) const { + x = K; + ++element_counter; + } +}; + +#include "test_range_based_for.h" +#include <functional> + +void range_for_each_test() { + using namespace range_based_for_support_tests; + std::list<size_t> v(elements, 0); + + // iterator, const and non-const range check + element_counter = 0; + tbb::parallel_for_each(v.begin(), v.end(), set_to<1>()); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == v.size(), "elements of v not all ones"); + + element_counter = 0; + tbb::parallel_for_each(v, set_to<0>()); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == init_sum , "elements of v not all zeros"); + + element_counter = 0; + tbb::parallel_for_each(tbb::blocked_range<std::list<size_t>::iterator>(v.begin(), v.end()), set_to<1>()); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == v.size(), "elements of v not all ones"); + + // iterator, const and non-const range check with context + element_counter = 0; + tbb::task_group_context context; + tbb::parallel_for_each(v.begin(), v.end(), set_to<0>(), context); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == init_sum , "elements of v not all zeros"); + + element_counter = 0; + tbb::parallel_for_each(v, set_to<1>(), context); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == v.size(), "elements of v not all ones"); + + element_counter = 0; + tbb::parallel_for_each(tbb::blocked_range<std::list<size_t>::iterator>(v.begin(), v.end()), set_to<0>(), context); + ASSERT(element_counter == v.size() && element_counter == elements, "not all elements were set"); + ASSERT(range_based_for_accumulate(v, std::plus<size_t>(), init_sum) == init_sum , "elements of v not all zeros"); +} + +int TestMain () { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init( p ); + + RunPForEachTests<Harness::RandomIterator<size_t> >(); + RunPForEachTests<Harness::ConstRandomIterator<size_t> >(); + RunPForEachTests<Harness::InputIterator<size_t> >(); + RunPForEachTests<Harness::ForwardIterator<size_t> >(); + + RunMutablePForEachTests<Harness::RandomIterator<size_t> >(); + RunMutablePForEachTests<Harness::ForwardIterator<size_t> >(); + +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + TestExceptionsSupport<Harness::RandomIterator<size_t> >(); + TestExceptionsSupport<Harness::InputIterator<size_t> >(); + TestExceptionsSupport<Harness::ForwardIterator<size_t> >(); +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ + +#if __TBB_TASK_GROUP_CONTEXT + if (p > 1) { + TestCancellation<Harness::RandomIterator<size_t> >(); + TestCancellation<Harness::InputIterator<size_t> >(); + TestCancellation<Harness::ForwardIterator<size_t> >(); + } +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + range_for_each_test(); + + // Test that all workers sleep when no work + TestCPUUserTime(p); + } +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + REPORT("Known issue: exception handling tests are skipped.\n"); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for_vectorization.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for_vectorization.cpp new file mode 100644 index 00000000..3a39d5b2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_for_vectorization.cpp @@ -0,0 +1,71 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// The test checks if the vectorization happens when PPL-style parallel_for is +// used. The test implements two ideas: +// 1. "pragma always assert" issues a compiler-time error if the vectorization +// cannot be produced; +// 2. "#pragma ivdep" has a peculiarity which also can be used for detection of +// successful vectorization. See the comment below. + +// For now, only Intel(R) C++ Compiler 14.0 and later is supported. Also, no +// sense to run the test in debug mode. +#define HARNESS_SKIP_TEST ( __INTEL_COMPILER < 1400 || TBB_USE_DEBUG ) + +// __TBB_ASSERT_ON_VECTORIZATION_FAILURE enables "pragma always assert" for +// Intel(R) C++ Compiler. +#define __TBB_ASSERT_ON_VECTORIZATION_FAILURE ( !HARNESS_SKIP_TEST ) +#include "tbb/parallel_for.h" +#include "tbb/task_scheduler_init.h" + +#include "harness.h" +#include "harness_assert.h" + +#include <algorithm> + +class Body : NoAssign { + int *out_, *in_; +public: + Body( int* out, int *in ) : out_(out), in_(in) {} + void operator() ( int i ) const { + out_[i] = in_[i] + 1; + } +}; + +int TestMain () { + // Should be big enough that the partitioner generated at least a one range + // with a size greater than 1. See the comment below. + const int N = 10000; + tbb::task_scheduler_init init(1); + int array1[N]; + std::fill( array1, array1+N, 0 ); + // Use the same array (with a shift) for both input and output + tbb::parallel_for( 0, N-1, Body(array1+1, array1) ); + + int array2[N]; + std::fill( array2, array2+N, 0 ); + Body b(array2+1, array2); + for ( int i=0; i<N-1; ++i ) + b(i); + + // The ppl-style parallel_for implementation has pragma ivdep before the + // range loop. This pragma suppresses the dependency of overlapping arrays + // in "Body". Thus the vectorizer should generate code that produces incorrect + // results. + ASSERT( !std::equal( array1, array1+N, array2 ), "The loop was not vectorized." ); + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_invoke.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_invoke.cpp new file mode 100644 index 00000000..42d499ec --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_invoke.cpp @@ -0,0 +1,317 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _MSC_VER && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4180) // "qualifier applied to function type has no meaning; ignored" +#endif + +#ifndef TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE + #define TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE __TBB_CPF_BUILD +#endif + +#include "tbb/parallel_invoke.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/atomic.h" +#include "tbb/tbb_exception.h" +#include "harness.h" + +#if !__INTEL_COMPILER && (_MSC_VER && _MSC_VER <= 1400 || __GNUC__==3 && __GNUC_MINOR__<=3 || __SUNPRO_CC) + #define __TBB_FUNCTION_BY_CONSTREF_IN_TEMPLATE_BROKEN 1 +#endif + +tbb::atomic<size_t> function_counter; + +// Some macros to make the test easier to read + +// 10 functions test0 ... test9 are defined +// pointer to each function is also defined + +#define TEST_FUNCTION(value) void test##value () \ +{ \ + ASSERT(!(function_counter & (1 << value)), "Test function has already been called"); \ + function_counter += 1 << value; \ +} \ +void (*test_pointer##value)(void) = test##value; + +TEST_FUNCTION(0) +TEST_FUNCTION(1) +TEST_FUNCTION(2) +TEST_FUNCTION(3) +TEST_FUNCTION(4) +TEST_FUNCTION(5) +TEST_FUNCTION(6) +TEST_FUNCTION(7) +TEST_FUNCTION(8) +TEST_FUNCTION(9) + +// The same with functors +#define TEST_FUNCTOR(value) class test_functor##value \ +{ \ +public: \ + void operator() () const { \ + function_counter += 1 << value; \ + } \ +} functor##value; + +TEST_FUNCTOR(0) +TEST_FUNCTOR(1) +TEST_FUNCTOR(2) +TEST_FUNCTOR(3) +TEST_FUNCTOR(4) +TEST_FUNCTOR(5) +TEST_FUNCTOR(6) +TEST_FUNCTOR(7) +TEST_FUNCTOR(8) +TEST_FUNCTOR(9) + +#define INIT_TEST function_counter = 0; + +#define VALIDATE_INVOKE_RUN(number_of_args, test_type) \ + ASSERT( size_t(function_counter) == (size_t(1) << number_of_args) - 1, "parallel_invoke called with " #number_of_args " arguments didn't process all " #test_type); + +// Calls parallel_invoke for different number of arguments +// It can be called with and without user context +template <typename F0, typename F1, typename F2, typename F3, typename F4, typename F5, + typename F6, typename F7, typename F8, typename F9> +void call_parallel_invoke( size_t n, F0& f0, F1& f1, F2& f2, F3& f3, F4 &f4, F5 &f5, + F6& f6, F7 &f7, F8 &f8, F9 &f9, tbb::task_group_context* context) { + switch(n) { + case 2: + if (context) + tbb::parallel_invoke (f0, f1, *context); + else + tbb::parallel_invoke (f0, f1); + break; + case 3: + if (context) + tbb::parallel_invoke (f0, f1, f2, *context); + else + tbb::parallel_invoke (f0, f1, f2); + break; + case 4: + if(context) + tbb::parallel_invoke (f0, f1, f2, f3, *context); + else + tbb::parallel_invoke (f0, f1, f2, f3); + break; + case 5: + if(context) + tbb::parallel_invoke (f0, f1, f2, f3, f4, *context); + else + tbb::parallel_invoke (f0, f1, f2, f3, f4); + break; + case 6: + if(context) + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, *context); + else + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5); + break; + case 7: + if(context) + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, f6, *context); + else + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, f6); + break; + case 8: + if(context) + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, f6, f7, *context); + else + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, f6, f7); + break; + case 9: + if(context) + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, f6, f7, f8, *context); + else + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, f6, f7, f8); + break; + case 10: + if(context) + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, *context); + else + tbb::parallel_invoke (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); + break; + default: + ASSERT(false, "number of arguments must be between 2 and 10"); + } +} + +#if !__TBB_FUNCTION_BY_CONSTREF_IN_TEMPLATE_BROKEN +template<typename function> void aux_invoke(const function& f) { + f(); +} + +bool function_by_constref_in_template_codegen_broken() { + function_counter = 0; + aux_invoke(test1); + return function_counter==0; +} +#endif /* !__TBB_FUNCTION_BY_CONSTREF_IN_TEMPLATE_BROKEN */ + +void test_parallel_invoke() +{ + REMARK (__FUNCTION__); + // Testing with pointers to functions + for (int n = 2; n <=10; n++) + { + INIT_TEST; + call_parallel_invoke(n, test_pointer0, test_pointer1, test_pointer2, test_pointer3, test_pointer4, + test_pointer5, test_pointer6, test_pointer7, test_pointer8, test_pointer9, NULL); + VALIDATE_INVOKE_RUN(n, "pointers to function"); + } + + // Testing parallel_invoke with functors + for (int n = 2; n <=10; n++) + { + INIT_TEST; + call_parallel_invoke(n, functor0, functor1, functor2, functor3, functor4, + functor5, functor6, functor7, functor8, functor9, NULL); + VALIDATE_INVOKE_RUN(n, "functors"); + } + +#if __TBB_FUNCTION_BY_CONSTREF_IN_TEMPLATE_BROKEN + // some old compilers can't cope with passing function name into parallel_invoke +#else + // and some compile but generate broken code that does not call the function + if (function_by_constref_in_template_codegen_broken()) + return; + + // Testing parallel_invoke with functions + for (int n = 2; n <=10; n++) + { + INIT_TEST; + call_parallel_invoke(n, test0, test1, test2, test3, test4, test5, test6, test7, test8, test9, NULL); + VALIDATE_INVOKE_RUN(n, "functions"); + } +#endif +} + +// Exception handling support test + +#if __TBB_TASK_GROUP_CONTEXT +#define HARNESS_EH_SIMPLE_MODE 1 +#include "harness_eh.h" + +#if TBB_USE_EXCEPTIONS +volatile size_t exception_mask; // each bit represents whether the function should throw exception or not + +// throws exception if corresponding exception_mask bit is set +#define TEST_FUNCTOR_WITH_THROW(value) \ +struct throwing_functor##value { \ + void operator() () const { \ + if (exception_mask & (1 << value)) \ + ThrowTestException(); \ + } \ +} test_with_throw##value; + +TEST_FUNCTOR_WITH_THROW(0) +TEST_FUNCTOR_WITH_THROW(1) +TEST_FUNCTOR_WITH_THROW(2) +TEST_FUNCTOR_WITH_THROW(3) +TEST_FUNCTOR_WITH_THROW(4) +TEST_FUNCTOR_WITH_THROW(5) +TEST_FUNCTOR_WITH_THROW(6) +TEST_FUNCTOR_WITH_THROW(7) +TEST_FUNCTOR_WITH_THROW(8) +TEST_FUNCTOR_WITH_THROW(9) + +void TestExceptionHandling() +{ + REMARK (__FUNCTION__); + for( size_t n = 2; n <= 10; ++n ) { + for( exception_mask = 1; exception_mask < (size_t(1) << n); ++exception_mask ) { + ResetEhGlobals(); + TRY(); + REMARK("Calling parallel_invoke, number of functions = %d, exception_mask = %d\n", n, exception_mask); + call_parallel_invoke(n, test_with_throw0, test_with_throw1, test_with_throw2, test_with_throw3, + test_with_throw4, test_with_throw5, test_with_throw6, test_with_throw7, test_with_throw8, test_with_throw9, NULL); + CATCH_AND_ASSERT(); + } + } +} +#endif /* TBB_USE_EXCEPTIONS */ + +// Cancellation support test +void function_to_cancel() { + ++g_CurExecuted; + CancellatorTask::WaitUntilReady(); +} + +// The function is used to test cancellation +void simple_test_nothrow (){ + ++g_CurExecuted; +} + +size_t g_numFunctions, + g_functionToCancel; + +class ParInvokeLauncherTask : public tbb::task +{ + tbb::task_group_context &my_ctx; + void(*func_array[10])(void); + + tbb::task* execute () __TBB_override { + func_array[g_functionToCancel] = &function_to_cancel; + call_parallel_invoke(g_numFunctions, func_array[0], func_array[1], func_array[2], func_array[3], + func_array[4], func_array[5], func_array[6], func_array[7], func_array[8], func_array[9], &my_ctx); + return NULL; + } +public: + ParInvokeLauncherTask ( tbb::task_group_context& ctx ) : my_ctx(ctx) { + for (int i = 0; i <=9; ++i) + func_array[i] = &simple_test_nothrow; + } +}; + +void TestCancellation () +{ + REMARK (__FUNCTION__); + for ( int n = 2; n <= 10; ++n ) { + for ( int m = 0; m <= n - 1; ++m ) { + g_numFunctions = n; + g_functionToCancel = m; + ResetEhGlobals(); + RunCancellationTest<ParInvokeLauncherTask, CancellatorTask>(); + } + } +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +//------------------------------------------------------------------------ +// Entry point +//------------------------------------------------------------------------ + +#include "harness_cpu.h" + +int TestMain () { + MinThread = min(MinThread, MaxThread); + ASSERT (MinThread>=1, "Minimal number of threads must be 1 or more"); + for ( int p = MinThread; p <= MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + test_parallel_invoke(); + if (p > 1) { +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + REPORT("Known issue: exception handling tests are skipped.\n"); +#elif TBB_USE_EXCEPTIONS + TestExceptionHandling(); +#endif /* TBB_USE_EXCEPTIONS */ +#if __TBB_TASK_GROUP_CONTEXT + TestCancellation(); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + } + TestCPUUserTime(p); + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_pipeline.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_pipeline.cpp new file mode 100644 index 00000000..b19b29a0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_pipeline.cpp @@ -0,0 +1,673 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Before including pipeline.h, set up the variable to count heap allocated +// filter_node objects, and make it known for the header. +int filter_node_count = 0; +#define __TBB_TEST_FILTER_NODE_COUNT filter_node_count +#include "tbb/pipeline.h" + +#include "tbb/atomic.h" +#include "harness.h" +#include <string.h> + +#include "tbb/tbb_allocator.h" +#include "tbb/spin_mutex.h" + +#if __TBB_CPP11_RVALUE_REF_PRESENT +#include <memory> // std::unique_ptr +#endif + +const unsigned n_tokens = 8; +// we can conceivably have two buffers used in the middle filter for every token in flight, so +// we must allocate two buffers for every token. Unlikely, but possible. +const unsigned n_buffers = 2*n_tokens; +const int max_counter = 16; +static tbb::atomic<int> output_counter; +static tbb::atomic<int> input_counter; +static tbb::atomic<int> non_pointer_specialized_calls; +static tbb::atomic<int> pointer_specialized_calls; +static tbb::atomic<int> first_pointer_specialized_calls; +static tbb::atomic<int> second_pointer_specialized_calls; +static tbb::spin_mutex buffer_mutex; + +static int intbuffer[max_counter]; // store results for <int,int> parallel pipeline test +static bool check_intbuffer; + +static void* buffers[n_buffers]; +static bool buf_available[n_buffers]; + +void *fetchNextBuffer() { + tbb::spin_mutex::scoped_lock sl1(buffer_mutex); + for(size_t icnt = 0; icnt < n_buffers; ++icnt) { + if(buf_available[icnt]) { + buf_available[icnt] = false; + return buffers[icnt]; + } + } + ASSERT(0, "Ran out of buffers"); + return 0; +} +void freeBuffer(void *buf) { + for(size_t i=0; i < n_buffers;++i) { + if(buffers[i] == buf) { + buf_available[i] = true; + return; + } + } + ASSERT(0, "Tried to free a buffer not in our list"); +} + +template<typename T> +class free_on_scope_exit { +public: + free_on_scope_exit(T *p) : my_p(p) {} + ~free_on_scope_exit() { if(!my_p) return; my_p->~T(); freeBuffer(my_p); } +private: + T *my_p; +}; + +#include "harness_checktype.h" + +// methods for testing check_type< >, that return okay values for other types. +template<typename T> +bool middle_is_ready(T &/*p*/) { return false; } + +template<typename U> +bool middle_is_ready(check_type<U> &p) { return p.is_ready(); } + +template<typename T> +bool output_is_ready(T &/*p*/) { return true; } + +template<typename U> +bool output_is_ready(check_type<U> &p) { return p.is_ready(); } + +template<typename T> +int middle_my_id( T &/*p*/) { return 0; } + +template<typename U> +int middle_my_id(check_type<U> &p) { return p.my_id(); } + +template<typename T> +int output_my_id( T &/*p*/) { return 1; } + +template<typename U> +int output_my_id(check_type<U> &p) { return p.my_id(); } + +template<typename T> +void my_function(T &p) { p = 0; } + +template<typename U> +void my_function(check_type<U> &p) { p.function(); } + +// Filters must be copy-constructible, and be const-qualifiable. +template<typename U> +class input_filter : Harness::NoAfterlife { +public: + U operator()( tbb::flow_control& control ) const { + AssertLive(); + if( --input_counter < 0 ) { + control.stop(); + } + else // only count successful reads + ++non_pointer_specialized_calls; + return U(); // default constructed + } + +}; + +// specialization for pointer +template<typename U> +class input_filter<U*> : Harness::NoAfterlife { +public: + U* operator()(tbb::flow_control& control) const { + AssertLive(); + int ival = --input_counter; + if(ival < 0) { + control.stop(); + return NULL; + } + ++pointer_specialized_calls; + if(ival == max_counter / 2) { + return NULL; // non-stop NULL + } + U* myReturn = new(fetchNextBuffer()) U(); + return myReturn; + } +}; + +template<> +class input_filter<void> : Harness::NoAfterlife { +public: + void operator()( tbb::flow_control& control ) const { + AssertLive(); + if( --input_counter < 0 ) { + control.stop(); + } + else + ++non_pointer_specialized_calls; + } + +}; + +// specialization for int that passes back a sequence of integers +template<> +class input_filter<int> : Harness::NoAfterlife { +public: + int + operator()(tbb::flow_control& control ) const { + AssertLive(); + int oldval = --input_counter; + if( oldval < 0 ) { + control.stop(); + } + else + ++non_pointer_specialized_calls; + return oldval+1; + } +}; + +template<typename T, typename U> +class middle_filter : Harness::NoAfterlife { +public: + U operator()(T t) const { + AssertLive(); + ASSERT(!middle_my_id(t), "bad id value"); + ASSERT(!middle_is_ready(t), "Already ready" ); + U out; + my_function(out); + ++non_pointer_specialized_calls; + return out; + } +}; + +template<typename T, typename U> +class middle_filter<T*,U> : Harness::NoAfterlife { +public: + U operator()(T* my_storage) const { + free_on_scope_exit<T> my_ptr(my_storage); // free_on_scope_exit marks the buffer available + AssertLive(); + if(my_storage) { // may have been passed in a NULL + ASSERT(!middle_my_id(*my_storage), "bad id value"); + ASSERT(!middle_is_ready(*my_storage), "Already ready" ); + } + ++first_pointer_specialized_calls; + U out; + my_function(out); + return out; + } +}; + +template<typename T, typename U> +class middle_filter<T,U*> : Harness::NoAfterlife { +public: + U* operator()(T my_storage) const { + AssertLive(); + ASSERT(!middle_my_id(my_storage), "bad id value"); + ASSERT(!middle_is_ready(my_storage), "Already ready" ); + // allocate new space from buffers + U* my_return = new(fetchNextBuffer()) U(); + my_function(*my_return); + ++second_pointer_specialized_calls; + return my_return; + } +}; + +template<typename T, typename U> +class middle_filter<T*,U*> : Harness::NoAfterlife { +public: + U* operator()(T* my_storage) const { + free_on_scope_exit<T> my_ptr(my_storage); // free_on_scope_exit marks the buffer available + AssertLive(); + if(my_storage) { + ASSERT(!middle_my_id(*my_storage), "bad id value"); + ASSERT(!middle_is_ready(*my_storage), "Already ready" ); + } + // may have been passed a NULL + ++pointer_specialized_calls; + if(!my_storage) return NULL; + ASSERT(!middle_my_id(*my_storage), "bad id value"); + ASSERT(!middle_is_ready(*my_storage), "Already ready" ); + U* my_return = new(fetchNextBuffer()) U(); + my_function(*my_return); + return my_return; + } +}; + +// specialization for int that squares the input and returns that. +template<> +class middle_filter<int,int> : Harness::NoAfterlife { +public: + int operator()(int my_input) const { + AssertLive(); + ++non_pointer_specialized_calls; + return my_input*my_input; + } +}; + +// --------------------------------- +template<typename T> +class output_filter : Harness::NoAfterlife { +public: + void operator()(T c) const { + AssertLive(); + ASSERT(output_my_id(c), "unset id value"); + ASSERT(output_is_ready(c), "not yet ready"); + ++non_pointer_specialized_calls; + output_counter++; + } +}; + +// specialization for int that puts the received value in an array +template<> +class output_filter<int> : Harness::NoAfterlife { +public: + void operator()(int my_input) const { + AssertLive(); + ++non_pointer_specialized_calls; + int myindx = output_counter++; + intbuffer[myindx] = my_input; + } +}; + + +template<typename T> +class output_filter<T*> : Harness::NoAfterlife { +public: + void operator()(T* c) const { + free_on_scope_exit<T> my_ptr(c); + AssertLive(); + if(c) { + ASSERT(output_my_id(*c), "unset id value"); + ASSERT(output_is_ready(*c), "not yet ready"); + } + output_counter++; + ++pointer_specialized_calls; + } +}; + +typedef enum { + no_pointer_counts, + assert_nonpointer, + assert_firstpointer, + assert_secondpointer, + assert_allpointer +} final_assert_type; + +void resetCounters() { + output_counter = 0; + input_counter = max_counter; + non_pointer_specialized_calls = 0; + pointer_specialized_calls = 0; + first_pointer_specialized_calls = 0; + second_pointer_specialized_calls = 0; + // we have to reset the buffer flags because our input filters return allocated space on end-of-input, + // (on eof a default-constructed object is returned) and they do not pass through the filter further. + for(size_t i = 0; i < n_buffers; ++i) + buf_available[i] = true; +} + +void checkCounters(final_assert_type my_t) { + ASSERT(output_counter == max_counter, "not all tokens were passed through pipeline"); + switch(my_t) { + case assert_nonpointer: + ASSERT(pointer_specialized_calls+first_pointer_specialized_calls+second_pointer_specialized_calls == 0, "non-pointer filters specialized to pointer"); + ASSERT(non_pointer_specialized_calls == 3*max_counter, "bad count for non-pointer filters"); + if(check_intbuffer) { + for(int i = 1; i <= max_counter; ++i) { + int j = i*i; + bool found_val = false; + for(int k = 0; k < max_counter; ++k) { + if(intbuffer[k] == j) { + found_val = true; + break; + } + } + ASSERT(found_val, "Missing value in output array" ); + } + } + break; + case assert_firstpointer: + ASSERT(pointer_specialized_calls == max_counter && // input filter extra invocation + first_pointer_specialized_calls == max_counter && + non_pointer_specialized_calls == max_counter && + second_pointer_specialized_calls == 0, "incorrect specialization for firstpointer"); + break; + case assert_secondpointer: + ASSERT(pointer_specialized_calls == max_counter && + first_pointer_specialized_calls == 0 && + non_pointer_specialized_calls == max_counter && // input filter + second_pointer_specialized_calls == max_counter, "incorrect specialization for firstpointer"); + break; + case assert_allpointer: + ASSERT(non_pointer_specialized_calls+first_pointer_specialized_calls+second_pointer_specialized_calls == 0, "pointer filters specialized to non-pointer"); + ASSERT(pointer_specialized_calls == 3*max_counter, "bad count for pointer filters"); + break; + case no_pointer_counts: + break; + } +} + +static const tbb::filter::mode filter_table[] = { tbb::filter::parallel, tbb::filter::serial_in_order, tbb::filter::serial_out_of_order}; +const unsigned number_of_filter_types = sizeof(filter_table)/sizeof(filter_table[0]); + +typedef tbb::filter_t<void, void> filter_chain; +typedef tbb::filter::mode mode_array; + +// The filters are passed by value, which forces a temporary copy to be created. This is +// to reproduce the bug where a filter_chain uses refs to filters, which after a call +// would be references to destructed temporaries. +template<typename type1, typename type2> +void fill_chain( filter_chain &my_chain, mode_array *filter_type, input_filter<type1> i_filter, + middle_filter<type1, type2> m_filter, output_filter<type2> o_filter ) { + my_chain = tbb::make_filter<void, type1>(filter_type[0], i_filter) & + tbb::make_filter<type1, type2>(filter_type[1], m_filter) & + tbb::make_filter<type2, void>(filter_type[2], o_filter); +} + +void run_function_spec() { + ASSERT(!filter_node_count, NULL); + REMARK("Testing < void, void > (single filter in pipeline)"); +#if __TBB_CPP11_LAMBDAS_PRESENT + REMARK( " ( + lambdas)"); +#endif + REMARK("\n"); + input_filter<void> i_filter; + // Test pipeline that contains only one filter + for( unsigned i = 0; i<number_of_filter_types; i++) { + tbb::filter_t<void, void> one_filter( filter_table[i], i_filter ); + ASSERT(filter_node_count==1, "some filter nodes left after previous iteration?"); + resetCounters(); + tbb::parallel_pipeline( n_tokens, one_filter ); + // no need to check counters +#if __TBB_CPP11_LAMBDAS_PRESENT + tbb::atomic<int> counter; + counter = max_counter; + // Construct filter using lambda-syntax when parallel_pipeline() is being run; + tbb::parallel_pipeline( n_tokens, + tbb::make_filter<void, void>(filter_table[i], [&counter]( tbb::flow_control& control ) { + if( counter-- == 0 ) + control.stop(); + } + ) + ); +#endif + } + ASSERT(!filter_node_count, "filter_node objects leaked"); +} + +template<typename t1, typename t2> +void run_filter_set( + input_filter<t1>& i_filter, + middle_filter<t1,t2>& m_filter, + output_filter<t2>& o_filter, + mode_array *filter_type, + final_assert_type my_t) { + tbb::filter_t<void, t1> filter1( filter_type[0], i_filter ); + tbb::filter_t<t1, t2> filter2( filter_type[1], m_filter ); + tbb::filter_t<t2, void> filter3( filter_type[2], o_filter ); + ASSERT(filter_node_count==3, "some filter nodes left after previous iteration?"); + resetCounters(); + // Create filters sequence when parallel_pipeline() is being run + tbb::parallel_pipeline( n_tokens, filter1 & filter2 & filter3 ); + checkCounters(my_t); + + // Create filters sequence partially outside parallel_pipeline() and also when parallel_pipeline() is being run + tbb::filter_t<void, t2> filter12; + filter12 = filter1 & filter2; + resetCounters(); + tbb::parallel_pipeline( n_tokens, filter12 & filter3 ); + checkCounters(my_t); + + tbb::filter_t<void, void> filter123 = filter12 & filter3; + // Run pipeline twice with the same filter sequence + for( unsigned i = 0; i<2; i++ ) { + resetCounters(); + tbb::parallel_pipeline( n_tokens, filter123 ); + checkCounters(my_t); + } + + // Now copy-construct another filter_t instance, and use it to run pipeline + { + tbb::filter_t<void, void> copy123( filter123 ); + resetCounters(); + tbb::parallel_pipeline( n_tokens, copy123 ); + checkCounters(my_t); + } + + // Construct filters and create the sequence when parallel_pipeline() is being run + resetCounters(); + tbb::parallel_pipeline( n_tokens, + tbb::make_filter<void, t1>(filter_type[0], i_filter) & + tbb::make_filter<t1, t2>(filter_type[1], m_filter) & + tbb::make_filter<t2, void>(filter_type[2], o_filter) ); + checkCounters(my_t); + + // Construct filters, make a copy, destroy the original filters, and run with the copy + int cnt = filter_node_count; + { + tbb::filter_t<void, void>* p123 = new tbb::filter_t<void,void> ( + tbb::make_filter<void, t1>(filter_type[0], i_filter) & + tbb::make_filter<t1, t2>(filter_type[1], m_filter) & + tbb::make_filter<t2, void>(filter_type[2], o_filter) ); + ASSERT(filter_node_count==cnt+5, "filter node accounting error?"); + tbb::filter_t<void, void> copy123( *p123 ); + delete p123; + ASSERT(filter_node_count==cnt+5, "filter nodes deleted prematurely?"); + resetCounters(); + tbb::parallel_pipeline( n_tokens, copy123 ); + checkCounters(my_t); + } + + // construct a filter with temporaries + { + tbb::filter_t<void, void> my_filter; + fill_chain<t1,t2>( my_filter, filter_type, i_filter, m_filter, o_filter ); + resetCounters(); + tbb::parallel_pipeline( n_tokens, my_filter ); + checkCounters(my_t); + } + ASSERT(filter_node_count==cnt, "scope ended but filter nodes not deleted?"); +} + +#if __TBB_CPP11_LAMBDAS_PRESENT +template <typename t1, typename t2> +void run_lambdas_test( mode_array *filter_type ) { + tbb::atomic<int> counter; + counter = max_counter; + // Construct filters using lambda-syntax and create the sequence when parallel_pipeline() is being run; + resetCounters(); // only need the output_counter reset. + tbb::parallel_pipeline( n_tokens, + tbb::make_filter<void, t1>(filter_type[0], [&counter]( tbb::flow_control& control ) -> t1 { + if( --counter < 0 ) + control.stop(); + return t1(); } + ) & + tbb::make_filter<t1, t2>(filter_type[1], []( t1 /*my_storage*/ ) -> t2 { + return t2(); } + ) & + tbb::make_filter<t2, void>(filter_type[2], [] ( t2 ) -> void { + output_counter++; } + ) + ); + checkCounters(no_pointer_counts); // don't have to worry about specializations + counter = max_counter; + // pointer filters + resetCounters(); + tbb::parallel_pipeline( n_tokens, + tbb::make_filter<void, t1*>(filter_type[0], [&counter]( tbb::flow_control& control ) -> t1* { + if( --counter < 0 ) { + control.stop(); + return NULL; + } + return new(fetchNextBuffer()) t1(); } + ) & + tbb::make_filter<t1*, t2*>(filter_type[1], []( t1* my_storage ) -> t2* { + tbb::tbb_allocator<t1>().destroy(my_storage); // my_storage->~t1(); + return new(my_storage) t2(); } + ) & + tbb::make_filter<t2*, void>(filter_type[2], [] ( t2* my_storage ) -> void { + tbb::tbb_allocator<t2>().destroy(my_storage); // my_storage->~t2(); + freeBuffer(my_storage); + output_counter++; } + ) + ); + checkCounters(no_pointer_counts); + // first filter outputs pointer + counter = max_counter; + resetCounters(); + tbb::parallel_pipeline( n_tokens, + tbb::make_filter<void, t1*>(filter_type[0], [&counter]( tbb::flow_control& control ) -> t1* { + if( --counter < 0 ) { + control.stop(); + return NULL; + } + return new(fetchNextBuffer()) t1(); } + ) & + tbb::make_filter<t1*, t2>(filter_type[1], []( t1* my_storage ) -> t2 { + tbb::tbb_allocator<t1>().destroy(my_storage); // my_storage->~t1(); + freeBuffer(my_storage); + return t2(); } + ) & + tbb::make_filter<t2, void>(filter_type[2], [] ( t2 /*my_storage*/) -> void { + output_counter++; } + ) + ); + checkCounters(no_pointer_counts); + // second filter outputs pointer + counter = max_counter; + resetCounters(); + tbb::parallel_pipeline( n_tokens, + tbb::make_filter<void, t1>(filter_type[0], [&counter]( tbb::flow_control& control ) -> t1 { + if( --counter < 0 ) { + control.stop(); + } + return t1(); } + ) & + tbb::make_filter<t1, t2*>(filter_type[1], []( t1 /*my_storage*/ ) -> t2* { + return new(fetchNextBuffer()) t2(); } + ) & + tbb::make_filter<t2*, void>(filter_type[2], [] ( t2* my_storage) -> void { + tbb::tbb_allocator<t2>().destroy(my_storage); // my_storage->~t2(); + freeBuffer(my_storage); + output_counter++; } + ) + ); + checkCounters(no_pointer_counts); +} +#endif + +template<typename type1, typename type2> +void run_function(const char *l1, const char *l2) { + ASSERT(!filter_node_count, NULL); + REMARK("Testing < %s, %s >", l1, l2 ); +#if __TBB_CPP11_LAMBDAS_PRESENT + REMARK( " ( + lambdas)"); +#endif + check_intbuffer = (!strcmp(l1,"int") && !strcmp(l2,"int")); + if(check_intbuffer) REMARK(", check output of filters"); + REMARK("\n"); + + Check<type1> check1; // check constructions/destructions + Check<type2> check2; // for type1 or type2 === check_type<T> + + const size_t number_of_filters = 3; + + input_filter<type1> i_filter; + input_filter<type1*> p_i_filter; + + middle_filter<type1, type2> m_filter; + middle_filter<type1*, type2> pr_m_filter; + middle_filter<type1, type2*> rp_m_filter; + middle_filter<type1*, type2*> pp_m_filter; + + output_filter<type2> o_filter; + output_filter<type2*> p_o_filter; + + // allocate the buffers for the filters + unsigned max_size = (sizeof(type1) > sizeof(type2) ) ? sizeof(type1) : sizeof(type2); + for(unsigned i = 0; i < (unsigned)n_buffers; ++i) { + buffers[i] = malloc(max_size); + buf_available[i] = true; + } + + unsigned limit = 1; + // Test pipeline that contains number_of_filters filters + for( unsigned i=0; i<number_of_filters; ++i) + limit *= number_of_filter_types; + // Iterate over possible filter sequences + for( unsigned numeral=0; numeral<limit; ++numeral ) { + unsigned temp = numeral; + tbb::filter::mode filter_type[number_of_filter_types]; + for( unsigned i=0; i<number_of_filters; ++i, temp/=number_of_filter_types ) + filter_type[i] = filter_table[temp%number_of_filter_types]; + + run_filter_set<type1,type2>(i_filter, m_filter, o_filter, filter_type, assert_nonpointer ); + run_filter_set<type1*,type2>(p_i_filter, pr_m_filter, o_filter, filter_type, assert_firstpointer); + run_filter_set<type1,type2*>(i_filter, rp_m_filter, p_o_filter, filter_type, assert_secondpointer); + run_filter_set<type1*,type2*>(p_i_filter, pp_m_filter, p_o_filter, filter_type, assert_allpointer); + +#if __TBB_CPP11_LAMBDAS_PRESENT + run_lambdas_test<type1,type2>(filter_type); +#endif + } + ASSERT(!filter_node_count, "filter_node objects leaked"); + + for(unsigned i = 0; i < (unsigned)n_buffers; ++i) { + free(buffers[i]); + } +} + +#include "tbb/task_scheduler_init.h" + +int TestMain() { +#if TBB_USE_DEBUG + // size and copyability. + REMARK("use_allocator<int>::value=%d\n", tbb::interface6::internal::use_allocator<int>::value); + REMARK("use_allocator<double>::value=%d\n", tbb::interface6::internal::use_allocator<double>::value); + REMARK("use_allocator<int *>::value=%d\n", tbb::interface6::internal::use_allocator<int *>::value); + REMARK("use_allocator<check_type<int> >::value=%d\n", tbb::interface6::internal::use_allocator<check_type<int> >::value); + REMARK("use_allocator<check_type<int>* >::value=%d\n", tbb::interface6::internal::use_allocator<check_type<int>* >::value); + REMARK("use_allocator<check_type<short> >::value=%d\n\n", tbb::interface6::internal::use_allocator<check_type<short> >::value); +#endif + // Test with varying number of threads. + for( int nthread=MinThread; nthread<=MaxThread; ++nthread ) { + // Initialize TBB task scheduler + REMARK("\nTesting with nthread=%d\n", nthread); + tbb::task_scheduler_init init(nthread); + + // Run test several times with different types + run_function_spec(); + #define RUN_FUNCTION(type1, type2) run_function<type1, type2>(#type1, #type2); + RUN_FUNCTION(size_t, int) + RUN_FUNCTION(int, double) + RUN_FUNCTION(size_t, double) + RUN_FUNCTION(size_t, bool) + RUN_FUNCTION(int, int) + RUN_FUNCTION(check_type<unsigned int>, size_t) + RUN_FUNCTION(check_type<unsigned short>, size_t) + RUN_FUNCTION(check_type<unsigned int>, check_type<unsigned int>) + RUN_FUNCTION(check_type<unsigned int>, check_type<unsigned short>) + RUN_FUNCTION(check_type<unsigned short>, check_type<unsigned short>) + RUN_FUNCTION(double, check_type<unsigned short>) +#if __TBB_CPP11_RVALUE_REF_PRESENT + RUN_FUNCTION(std::unique_ptr<int>, std::unique_ptr<int>) // move-only type +#endif + #undef RUN_FUNCTION + } + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_reduce.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_reduce.cpp new file mode 100644 index 00000000..a8836858 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_reduce.cpp @@ -0,0 +1,488 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + + +#include "tbb/parallel_reduce.h" +#include "tbb/atomic.h" +#include "harness_assert.h" + +static tbb::atomic<long> ForkCount; +static tbb::atomic<long> FooBodyCount; + +//! Class with public interface that is exactly minimal requirements for Range concept +class MinimalRange { + size_t begin, end; + friend class FooBody; + explicit MinimalRange( size_t i ) : begin(0), end(i) {} + friend void Flog( int nthread, bool inteference ); +public: + MinimalRange( MinimalRange& r, tbb::split ) : end(r.end) { + begin = r.end = (r.begin+r.end)/2; + } + bool is_divisible() const {return end-begin>=2;} + bool empty() const {return begin==end;} +}; + +//! Class with public interface that is exactly minimal requirements for Body of a parallel_reduce +class FooBody { +private: + FooBody( const FooBody& ); // Deny access + void operator=( const FooBody& ); // Deny access + friend void Flog( int nthread, bool interference ); + //! Parent that created this body via split operation. NULL if original body. + FooBody* parent; + //! Total number of index values processed by body and its children. + size_t sum; + //! Number of join operations done so far on this body and its children. + long join_count; + //! Range that has been processed so far by this body and its children. + size_t begin, end; + //! True if body has not yet been processed at least once by operator(). + bool is_new; + //! 1 if body was created by split; 0 if original body. + int forked; + FooBody() {++FooBodyCount;} +public: + ~FooBody() { + forked = 0xDEADBEEF; + sum=0xDEADBEEF; + join_count=0xDEADBEEF; + --FooBodyCount; + } + FooBody( FooBody& other, tbb::split ) { + ++FooBodyCount; + ++ForkCount; + sum = 0; + parent = &other; + join_count = 0; + is_new = true; + forked = 1; + } + void join( FooBody& s ) { + ASSERT( s.forked==1, NULL ); + ASSERT( this!=&s, NULL ); + ASSERT( this==s.parent, NULL ); + ASSERT( end==s.begin, NULL ); + end = s.end; + sum += s.sum; + join_count += s.join_count + 1; + s.forked = 2; + } + void operator()( const MinimalRange& r ) { + for( size_t k=r.begin; k<r.end; ++k ) + ++sum; + if( is_new ) { + is_new = false; + begin = r.begin; + } else + ASSERT( end==r.begin, NULL ); + end = r.end; + } +}; + +#include "harness.h" +#include "tbb/tick_count.h" + +void Flog( int nthread, bool interference=false ) { + for (int mode = 0; mode < 4; mode++) { + tbb::tick_count T0 = tbb::tick_count::now(); + long join_count = 0; + tbb::affinity_partitioner ap; + for( size_t i=0; i<=1000; ++i ) { + FooBody f; + f.sum = 0; + f.parent = NULL; + f.join_count = 0; + f.is_new = true; + f.forked = 0; + f.begin = ~size_t(0); + f.end = ~size_t(0); + ASSERT( FooBodyCount==1, NULL ); + switch (mode) { + case 0: + tbb::parallel_reduce( MinimalRange(i), f ); + break; + case 1: + tbb::parallel_reduce( MinimalRange(i), f, tbb::simple_partitioner() ); + break; + case 2: + tbb::parallel_reduce( MinimalRange(i), f, tbb::auto_partitioner() ); + break; + case 3: + tbb::parallel_reduce( MinimalRange(i), f, ap ); + break; + } + join_count += f.join_count; + ASSERT( FooBodyCount==1, NULL ); + ASSERT( f.sum==i, NULL ); + ASSERT( f.begin==(i==0 ? ~size_t(0) : 0), NULL ); + ASSERT( f.end==(i==0 ? ~size_t(0) : i), NULL ); + } + tbb::tick_count T1 = tbb::tick_count::now(); + REMARK("time=%g join_count=%ld ForkCount=%ld nthread=%d%s\n", + (T1-T0).seconds(),join_count,long(ForkCount), nthread, interference ? " with interference":""); + } +} + +#include "tbb/blocked_range.h" + +#if _MSC_VER + typedef tbb::internal::uint64_t ValueType; +#else + typedef uint64_t ValueType; +#endif + +struct Sum { + template<typename T> + T operator() ( const T& v1, const T& v2 ) const { + return v1 + v2; + } +}; + +struct Accumulator { + ValueType operator() ( const tbb::blocked_range<ValueType*>& r, ValueType value ) const { + for ( ValueType* pv = r.begin(); pv != r.end(); ++pv ) + value += *pv; + return value; + } +}; + +class ParallelSumTester: public NoAssign { +public: + ParallelSumTester() : m_range(NULL, NULL) { + m_array = new ValueType[unsigned(N)]; + for ( ValueType i = 0; i < N; ++i ) + m_array[i] = i + 1; + m_range = tbb::blocked_range<ValueType*>( m_array, m_array + N ); + } + ~ParallelSumTester() { delete[] m_array; } + template<typename Partitioner> + void CheckParallelReduce() { + Partitioner partitioner; + ValueType r1 = tbb::parallel_reduce( m_range, I, Accumulator(), Sum(), partitioner ); + ASSERT( r1 == R, NULL ); +#if __TBB_CPP11_LAMBDAS_PRESENT + ValueType r2 = tbb::parallel_reduce( + m_range, I, + [](const tbb::blocked_range<ValueType*>& r, ValueType value) -> ValueType { + for ( const ValueType* pv = r.begin(); pv != r.end(); ++pv ) + value += *pv; + return value; + }, + Sum(), + partitioner + ); + ASSERT( r2 == R, NULL ); +#endif /* LAMBDAS */ + } + void CheckParallelReduceDefault() { + ValueType r1 = tbb::parallel_reduce( m_range, I, Accumulator(), Sum() ); + ASSERT( r1 == R, NULL ); +#if __TBB_CPP11_LAMBDAS_PRESENT + ValueType r2 = tbb::parallel_reduce( + m_range, I, + [](const tbb::blocked_range<ValueType*>& r, ValueType value) -> ValueType { + for ( const ValueType* pv = r.begin(); pv != r.end(); ++pv ) + value += *pv; + return value; + }, + Sum() + ); + ASSERT( r2 == R, NULL ); +#endif /* LAMBDAS */ + } +private: + ValueType* m_array; + tbb::blocked_range<ValueType*> m_range; + static const ValueType I, N, R; +}; + +const ValueType ParallelSumTester::I = 0; +const ValueType ParallelSumTester::N = 1000000; +const ValueType ParallelSumTester::R = N * (N + 1) / 2; + +void ParallelSum () { + ParallelSumTester pst; + pst.CheckParallelReduceDefault(); + pst.CheckParallelReduce<tbb::simple_partitioner>(); + pst.CheckParallelReduce<tbb::auto_partitioner>(); + pst.CheckParallelReduce<tbb::affinity_partitioner>(); + pst.CheckParallelReduce<tbb::static_partitioner>(); +} + +#include "harness_concurrency_tracker.h" + +class RotOp { +public: + typedef int Type; + int operator() ( int x, int i ) const { + return ( x<<1 ) ^ i; + } + int join( int x, int y ) const { + return operator()( x, y ); + } +}; + +template <class Op> +struct ReduceBody { + typedef typename Op::Type result_type; + result_type my_value; + + ReduceBody() : my_value() {} + ReduceBody( ReduceBody &, tbb::split ) : my_value() {} + + void operator() ( const tbb::blocked_range<int>& r ) { + Harness::ConcurrencyTracker ct; + for ( int i = r.begin(); i != r.end(); ++i ) { + Op op; + my_value = op(my_value, i); + } + } + + void join( const ReduceBody& y ) { + Op op; + my_value = op.join(my_value, y.my_value); + } +}; + +//! Type-tag for automatic testing algorithm deduction +struct harness_default_partitioner {}; + +template<typename Body, typename Partitioner> +struct parallel_deterministic_reduce_invoker { + template<typename Range> + static typename Body::result_type run( const Range& range ) { + Body body; + tbb::parallel_deterministic_reduce(range, body, Partitioner()); + return body.my_value; + } +}; + +template<typename Body> +struct parallel_deterministic_reduce_invoker<Body, harness_default_partitioner> { + template<typename Range> + static typename Body::result_type run( const Range& range ) { + Body body; + tbb::parallel_deterministic_reduce(range, body); + return body.my_value; + } +}; + +template<typename ResultType, typename Partitioner> +struct parallel_deterministic_reduce_lambda_invoker { + template<typename Range, typename Func, typename Reduction> + static ResultType run( const Range& range, Func f, Reduction r ) { + return tbb::parallel_deterministic_reduce(range, ResultType(), f, r, Partitioner()); + } +}; + +template<typename ResultType> +struct parallel_deterministic_reduce_lambda_invoker<ResultType, harness_default_partitioner> { + template<typename Range, typename Func, typename Reduction> + static ResultType run(const Range& range, Func f, Reduction r) { + return tbb::parallel_deterministic_reduce(range, ResultType(), f, r); + } +}; + +//! Define overloads of parallel_deterministic_reduce that accept "undesired" types of partitioners +namespace unsupported { + + template<typename Range, typename Body> + void parallel_deterministic_reduce(const Range&, Body&, const tbb::auto_partitioner&) { } + + template<typename Range, typename Body> + void parallel_deterministic_reduce(const Range&, Body&, tbb::affinity_partitioner&) { } + + template<typename Range, typename Value, typename RealBody, typename Reduction> + Value parallel_deterministic_reduce(const Range& , const Value& identity, const RealBody& , const Reduction& , const tbb::auto_partitioner&) { + return identity; + } + + template<typename Range, typename Value, typename RealBody, typename Reduction> + Value parallel_deterministic_reduce(const Range& , const Value& identity, const RealBody& , const Reduction& , tbb::affinity_partitioner&) { + return identity; + } + +} + +struct Body { + float value; + Body() : value(0) {} + Body(Body&, tbb::split) { value = 0; } + void operator()(const tbb::blocked_range<int>&) {} + void join(Body&) {} +}; + +//! Check that other types of partitioners are not supported (auto, affinity) +//! In the case of "unsupported" API unexpectedly sneaking into namespace tbb, +//! this test should result in a compilation error due to overload resolution ambiguity +static void TestUnsupportedPartitioners() { + using namespace tbb; + using namespace unsupported; + Body body; + parallel_deterministic_reduce(blocked_range<int>(0, 10), body, tbb::auto_partitioner()); + + tbb::affinity_partitioner ap; + parallel_deterministic_reduce(blocked_range<int>(0, 10), body, ap); + +#if __TBB_CPP11_LAMBDAS_PRESENT + parallel_deterministic_reduce( + blocked_range<int>(0, 10), + 0, + [](const blocked_range<int>&, int init)->int { + return init; + }, + [](int x, int y)->int { + return x + y; + }, + tbb::auto_partitioner() + ); + parallel_deterministic_reduce( + blocked_range<int>(0, 10), + 0, + [](const blocked_range<int>&, int init)->int { + return init; + }, + [](int x, int y)->int { + return x + y; + }, + ap + ); +#endif /* LAMBDAS */ +} + +template <class Partitioner> +void TestDeterministicReductionFor() { + const int N = 1000; + const tbb::blocked_range<int> range(0, N); + typedef ReduceBody<RotOp> BodyType; + BodyType::result_type R1 = + parallel_deterministic_reduce_invoker<BodyType, Partitioner>::run(range); + for ( int i=0; i<100; ++i ) { + BodyType::result_type R2 = + parallel_deterministic_reduce_invoker<BodyType, Partitioner>::run(range); + ASSERT( R1 == R2, "parallel_deterministic_reduce behaves differently from run to run" ); +#if __TBB_CPP11_LAMBDAS_PRESENT + typedef RotOp::Type Type; + Type R3 = parallel_deterministic_reduce_lambda_invoker<Type, Partitioner>::run( + range, + [](const tbb::blocked_range<int>& br, Type value) -> Type { + Harness::ConcurrencyTracker ct; + for ( int ii = br.begin(); ii != br.end(); ++ii ) { + RotOp op; + value = op(value, ii); + } + return value; + }, + [](const Type& v1, const Type& v2) -> Type { + RotOp op; + return op.join(v1,v2); + } + ); + ASSERT( R1 == R3, "lambda-based parallel_deterministic_reduce behaves differently from run to run" ); +#endif /* LAMBDAS */ + } +} + +void TestDeterministicReduction () { + TestDeterministicReductionFor<tbb::simple_partitioner>(); + TestDeterministicReductionFor<tbb::static_partitioner>(); + TestDeterministicReductionFor<harness_default_partitioner>(); + ASSERT_WARNING((Harness::ConcurrencyTracker::PeakParallelism() > 1), "no parallel execution\n"); +} + +#include "tbb/task_scheduler_init.h" +#include "harness_cpu.h" +#include "test_partitioner.h" + +namespace interaction_with_range_and_partitioner { + +// Test checks compatibility of parallel_reduce algorithm with various range implementations + +void test() { + using namespace test_partitioner_utils::interaction_with_range_and_partitioner; + + test_partitioner_utils::SimpleReduceBody body; + tbb::affinity_partitioner ap; + + parallel_reduce(Range1(/*assert_in_split*/ true, /*assert_in_proportional_split*/ false), body, ap); + parallel_reduce(Range2(true, false), body, ap); + parallel_reduce(Range3(true, false), body, ap); + parallel_reduce(Range4(false, true), body, ap); + parallel_reduce(Range5(false, true), body, ap); + parallel_reduce(Range6(false, true), body, ap); + + parallel_reduce(Range1(/*assert_in_split*/ true, /*assert_in_proportional_split*/ false), + body, tbb::static_partitioner()); + parallel_reduce(Range2(true, false), body, tbb::static_partitioner()); + parallel_reduce(Range3(true, false), body, tbb::static_partitioner()); + parallel_reduce(Range4(false, true), body, tbb::static_partitioner()); + parallel_reduce(Range5(false, true), body, tbb::static_partitioner()); + parallel_reduce(Range6(false, true), body, tbb::static_partitioner()); + + parallel_reduce(Range1(/*assert_in_split*/ false, /*assert_in_proportional_split*/ true), + body, tbb::simple_partitioner()); + parallel_reduce(Range2(false, true), body, tbb::simple_partitioner()); + parallel_reduce(Range3(false, true), body, tbb::simple_partitioner()); + parallel_reduce(Range4(false, true), body, tbb::simple_partitioner()); + parallel_reduce(Range5(false, true), body, tbb::simple_partitioner()); + parallel_reduce(Range6(false, true), body, tbb::simple_partitioner()); + + parallel_reduce(Range1(/*assert_in_split*/ false, /*assert_in_proportional_split*/ true), + body, tbb::auto_partitioner()); + parallel_reduce(Range2(false, true), body, tbb::auto_partitioner()); + parallel_reduce(Range3(false, true), body, tbb::auto_partitioner()); + parallel_reduce(Range4(false, true), body, tbb::auto_partitioner()); + parallel_reduce(Range5(false, true), body, tbb::auto_partitioner()); + parallel_reduce(Range6(false, true), body, tbb::auto_partitioner()); + + parallel_deterministic_reduce(Range1(/*assert_in_split*/true, /*assert_in_proportional_split*/ false), + body, tbb::static_partitioner()); + parallel_deterministic_reduce(Range2(true, false), body, tbb::static_partitioner()); + parallel_deterministic_reduce(Range3(true, false), body, tbb::static_partitioner()); + parallel_deterministic_reduce(Range4(false, true), body, tbb::static_partitioner()); + parallel_deterministic_reduce(Range5(false, true), body, tbb::static_partitioner()); + parallel_deterministic_reduce(Range6(false, true), body, tbb::static_partitioner()); + + parallel_deterministic_reduce(Range1(/*assert_in_split*/false, /*assert_in_proportional_split*/ true), + body, tbb::simple_partitioner()); + parallel_deterministic_reduce(Range2(false, true), body, tbb::simple_partitioner()); + parallel_deterministic_reduce(Range3(false, true), body, tbb::simple_partitioner()); + parallel_deterministic_reduce(Range4(false, true), body, tbb::simple_partitioner()); + parallel_deterministic_reduce(Range5(false, true), body, tbb::simple_partitioner()); + parallel_deterministic_reduce(Range6(false, true), body, tbb::simple_partitioner()); +} + +} // interaction_with_range_and_partitioner + +int TestMain () { + TestUnsupportedPartitioners(); + if( MinThread<0 ) { + REPORT("Usage: nthread must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init( p ); + Flog(p); + ParallelSum(); + if ( p>=2 ) + TestDeterministicReduction(); + // Test that all workers sleep when no work + TestCPUUserTime(p); + } + interaction_with_range_and_partitioner::test(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_scan.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_scan.cpp new file mode 100644 index 00000000..d81a3d16 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_scan.cpp @@ -0,0 +1,459 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/parallel_scan.h" +#include "tbb/blocked_range.h" +#include "harness_assert.h" +#include <vector> + +typedef tbb::blocked_range<long> Range; + +static volatile bool ScanIsRunning = false; + +//! Sum of 0..i with wrap around on overflow. +inline int TriangularSum( int i ) { + return i&1 ? ((i>>1)+1)*i : (i>>1)*(i+1); +} + +#include "harness.h" + +//! Verify that sum is init plus sum of integers in closed interval [0..finish_index]. +/** line should be the source line of the caller */ +void VerifySum( int init, long finish_index, int sum, int line ) { + int expected = init + TriangularSum(finish_index); + if (expected != sum) { + REPORT("line %d: sum[0..%ld] should be = %d, but was computed as %d\n", + line, finish_index, expected, sum); + abort(); + } +} + +const int MAXN = 2000; + +enum AddendFlag { + UNUSED=0, + USED_NONFINAL=1, + USED_FINAL=2 +}; + +//! Array recording how each addend was used. +/** 'unsigned char' instead of AddendFlag for sake of compactness. */ +static unsigned char AddendHistory[MAXN]; + +//! Set to 1 for debugging output +#define PRINT_DEBUG 0 + +#include "tbb/atomic.h" +#if PRINT_DEBUG +#include <stdio.h> +#include "harness_report.h" +tbb::atomic<long> NextBodyId; +#endif /* PRINT_DEBUG */ + +struct BodyId { +#if PRINT_DEBUG + const int id; + BodyId() : id(NextBodyId++) {} +#endif /* PRINT_DEBUG */ +}; + +tbb::atomic<long> NumberOfLiveStorage; + +static void Snooze( bool scan_should_be_running ) { + ASSERT( ScanIsRunning==scan_should_be_running, NULL ); +} + +template<typename T> +struct Storage { + T my_total; + Range my_range; + Storage(T init) : + my_total(init), my_range(-1, -1, 1) { + ++NumberOfLiveStorage; + } + ~Storage() { + --NumberOfLiveStorage; + } + Storage(const Storage& strg) : + my_total(strg.my_total), my_range(strg.my_range) { + ++NumberOfLiveStorage; + } + Storage & operator=(const Storage& strg) { + my_total = strg.my_total; + my_range = strg.my_range; + return *this; + } +}; + +template<typename T> +void JoinStorages(const Storage<T>& left, Storage<T>& right) { + Snooze(true); + ASSERT(ScanIsRunning, NULL); + ASSERT(left.my_range.end() == right.my_range.begin(), NULL); + right.my_total += left.my_total; + right.my_range = Range(left.my_range.begin(), right.my_range.end(), 1); + ASSERT(ScanIsRunning, NULL); + Snooze(true); + ASSERT(ScanIsRunning, NULL); +} + +template<typename T> +void Scan(const Range & r, bool is_final, Storage<T> & storage, std::vector<T> & sum, const std::vector<T> & addend) { + ASSERT(!is_final || (storage.my_range.begin() == 0 && storage.my_range.end() == r.begin()) || (storage.my_range.empty() && r.begin() == 0), NULL); + for (long i = r.begin(); i < r.end(); ++i) { + storage.my_total += addend[i]; + if (is_final) { + ASSERT(AddendHistory[i] < USED_FINAL, "addend used 'finally' twice?"); + AddendHistory[i] |= USED_FINAL; + sum[i] = storage.my_total; + VerifySum(42, i, int(sum[i]), __LINE__); + } + else { + ASSERT(AddendHistory[i] == UNUSED, "addend used too many times"); + AddendHistory[i] |= USED_NONFINAL; + } + } + if (storage.my_range.empty()) + storage.my_range = r; + else + storage.my_range = Range(storage.my_range.begin(), r.end(), 1); + Snooze(true); +} + +template<typename T> +Storage<T> ScanWithInit(const Range & r, T init, bool is_final, Storage<T> & storage, std::vector<T> & sum, const std::vector<T> & addend) { + if (r.begin() == 0) + storage.my_total = init; + Scan(r, is_final, storage, sum, addend); + return storage; +} + +template<typename T> +class Accumulator: BodyId { + const std::vector<T> &my_array; + std::vector<T> & my_sum; + Storage<T> storage; + enum state_type { + full, // Accumulator has sufficient information for final scan, + // i.e. has seen all iterations to its left. + // It's either the original Accumulator provided by the user + // or a Accumulator constructed by a splitting constructor *and* subsequently + // subjected to a reverse_join with a full accumulator. + + partial, // Accumulator has only enough information for pre_scan. + // i.e. has not seen all iterations to its left. + // It's an Accumulator created by a splitting constructor that + // has not yet been subjected to a reverse_join with a full accumulator. + + summary, // Accumulator has summary of iterations processed, but not necessarily + // the information required for a final_scan or pre_scan. + // It's the result of "assign". + + trash // Accumulator with possibly no useful information. + // It was the source for "assign". + + }; + mutable state_type my_state; + //! Equals this while object is fully constructed, NULL otherwise. + /** Used to detect premature destruction and accidental bitwise copy. */ + Accumulator* self; + Accumulator& operator= (const Accumulator& other); +public: + Accumulator( T init, const std::vector<T> & array, std::vector<T> & sum ) : + my_array(array), my_sum(sum), storage(init), my_state(full) + { + // Set self as last action of constructor, to indicate that object is fully constructed. + self = this; + } +#if PRINT_DEBUG + void print() const { + REPORT("%d [%ld..%ld)\n", id, storage.my_range.begin(), storage.my_range.end() ); + } +#endif /* PRINT_DEBUG */ + ~Accumulator() { +#if PRINT_DEBUG + REPORT("%d [%ld..%ld) destroyed\n",id, storage.my_range.begin(), storage.my_range.end() ); +#endif /* PRINT_DEBUG */ + // Clear self as first action of destructor, to indicate that object is not fully constructed. + self = 0; + } + Accumulator( Accumulator& a, tbb::split ) : + my_array(a.my_array), my_sum(a.my_sum), storage(0), my_state(partial) + { + ASSERT(a.my_state==full || a.my_state==partial, NULL); +#if PRINT_DEBUG + REPORT("%d forked from %d\n",id,a.id); +#endif /* PRINT_DEBUG */ + Snooze(true); + // Set self as last action of constructor, to indicate that object is fully constructed. + self = this; + } + template<typename Tag> + void operator()( const Range& r, Tag /*tag*/ ) { + ASSERT( Tag::is_final_scan() ? my_state==full : my_state==partial, NULL ); +#if PRINT_DEBUG + if(storage.my_range.empty() ) + REPORT("%d computing %s [%ld..%ld)\n",id,Tag::is_final_scan()?"final":"lookahead",r.begin(),r.end() ); + else + REPORT("%d computing %s [%ld..%ld) [%ld..%ld)\n",id,Tag::is_final_scan()?"final":"lookahead", storage.my_range.begin(), storage.my_range.end(),r.begin(),r.end()); +#endif /* PRINT_DEBUG */ + Scan(r, Tag::is_final_scan(), storage, my_sum, my_array); + ASSERT( self==this, "this Accumulator corrupted or prematurely destroyed" ); + } + void reverse_join( const Accumulator& left_body) { +#if PRINT_DEBUG + REPORT("reverse join %d [%ld..%ld) %d [%ld..%ld)\n", + left_body.id, left_body.storage.my_range.begin(), left_body.storage.my_range.end(), + id, storage.my_range.begin(), storage.my_range.end()); +#endif /* PRINT_DEBUG */ + const Storage<T> & left = left_body.storage; + Storage<T> & right = storage; + ASSERT(my_state==partial, NULL ); + ASSERT(left_body.my_state==full || left_body.my_state==partial, NULL ); + + JoinStorages(left, right); + + ASSERT(left_body.self==&left_body, NULL ); + my_state = left_body.my_state; + } + void assign( const Accumulator& other ) { + ASSERT(other.my_state==full, NULL); + ASSERT(my_state==full, NULL); + storage.my_total = other.storage.my_total; + storage.my_range = other.storage.my_range; + ASSERT( self==this, NULL ); + ASSERT( other.self==&other, "other Accumulator corrupted or prematurely destroyed" ); + my_state = summary; + other.my_state = trash; + } + T get_total() { + return storage.my_total; + } +}; + +#include "tbb/tick_count.h" + +template<typename T, typename Scan, typename ReverseJoin> +T ParallelScanFunctionalInvoker(const Range& range, T idx, const Scan& scan, const ReverseJoin& reverse_join, int mode) { + switch (mode%3) { + case 0: + return tbb::parallel_scan(range, idx, scan, reverse_join); + break; + case 1: + return tbb::parallel_scan(range, idx, scan, reverse_join, tbb::simple_partitioner()); + break; + default: + return tbb::parallel_scan(range, idx, scan, reverse_join, tbb::auto_partitioner()); + } +} + +template<typename T> +class ScanBody { + const std::vector<T> &my_addend; + std::vector<T> &my_sum; + const T my_init; + ScanBody& operator= (const ScanBody&); +public: + ScanBody(T init, const std::vector<T> &addend, std::vector<T> &sum) :my_addend(addend), my_sum(sum), my_init(init) {} + template<typename Tag> + Storage<T> operator()(const Range& r, Storage<T> storage, Tag) const { + return ScanWithInit(r, my_init, Tag::is_final_scan(), storage, my_sum, my_addend); + } +}; + +template<typename T> +class JoinBody { +public: + Storage<T> operator()(const Storage<T>& left, Storage<T>& right) const { + JoinStorages(left, right); + return right; + } +}; + +template<typename T> +T ParallelScanTemplateFunctor(Range range, T init, const std::vector<T> &addend, std::vector<T> &sum, int mode) { + for (long i = 0; i<MAXN; ++i) { + AddendHistory[i] = UNUSED; + } + ScanIsRunning = true; + ScanBody<T> sb(init, addend, sum); + JoinBody<T> jb; + Storage<T> res = ParallelScanFunctionalInvoker(range, Storage<T>(0), sb, jb, mode); + ScanIsRunning = false; + if (range.empty()) + res.my_total = init; + return res.my_total; +} + +#if __TBB_CPP11_LAMBDAS_PRESENT +template<typename T> +T ParallelScanLambda(Range range, T init, const std::vector<T> &addend, std::vector<T> &sum, int mode) { + for (long i = 0; i<MAXN; ++i) { + AddendHistory[i] = UNUSED; + } + ScanIsRunning = true; + Storage<T> res = ParallelScanFunctionalInvoker(range, Storage<T>(0), + [&addend, &sum, init](const Range& r, Storage<T> storage, bool is_final_scan /*tag*/) -> Storage<T> { + return ScanWithInit(r, init, is_final_scan, storage, sum, addend); + }, + [](const Storage<T>& left, Storage<T>& right) -> Storage<T> { + JoinStorages(left, right); + return right; + }, + mode); + ScanIsRunning = false; + if (range.empty()) + res.my_total = init; + return res.my_total; +} + +#if __TBB_CPP14_GENERIC_LAMBDAS_PRESENT +template<typename T> +T ParallelScanGenericLambda(Range range, T init, const std::vector<T> &addend, std::vector<T> &sum, int mode) { + for (long i = 0; i<MAXN; ++i) { + AddendHistory[i] = UNUSED; + } + ScanIsRunning = true; + Storage<T> res = ParallelScanFunctionalInvoker(range, Storage<T>(0), + [&addend, &sum, init](const Range& rng, Storage<T> storage, auto scan_tag) { + return ScanWithInit(rng, init, scan_tag.is_final_scan(), storage, sum, addend); + }, + [](const Storage<T>& left, Storage<T>& right) { + JoinStorages(left, right); + return right; + }, + mode); + ScanIsRunning = false; + if (range.empty()) + res.my_total = init; + return res.my_total; +} +#endif/* GENERIC_LAMBDAS */ +#endif/* LAMBDAS */ + +void TestAccumulator( int mode, int nthread ) { + typedef int T; + std::vector<T> addend(MAXN); + std::vector<T> sum(MAXN); + for( long n=0; n<=MAXN; ++n ) { + for( long i=0; i<MAXN; ++i ) { + addend[i] = -1; + sum[i] = -2; + AddendHistory[i] = UNUSED; + } + for( long i=0; i<n; ++i ) + addend[i] = i; + + Accumulator<T> acc( 42, addend, sum ); + tbb::tick_count t0 = tbb::tick_count::now(); +#if PRINT_DEBUG + REPORT("--------- mode=%d range=[0..%ld)\n",mode,n); +#endif /* PRINT_DEBUG */ + ScanIsRunning = true; + + switch (mode) { + case 0: + tbb::parallel_scan( Range( 0, n, 1 ), acc ); + break; + case 1: + tbb::parallel_scan( Range( 0, n, 1 ), acc, tbb::simple_partitioner() ); + break; + case 2: + tbb::parallel_scan( Range( 0, n, 1 ), acc, tbb::auto_partitioner() ); + break; + } + + ScanIsRunning = false; +#if PRINT_DEBUG + REPORT("=========\n"); +#endif /* PRINT_DEBUG */ + Snooze(false); + tbb::tick_count t1 = tbb::tick_count::now(); + long used_once_count = 0; + for( long i=0; i<n; ++i ) + if( !(AddendHistory[i]&USED_FINAL) ) { + REPORT("failed to use addend[%ld] %s\n",i,AddendHistory[i]&USED_NONFINAL?"(but used nonfinal)":""); + } + for( long i=0; i<n; ++i ) { + VerifySum( 42, i, sum[i], __LINE__ ); + used_once_count += AddendHistory[i]==USED_FINAL; + } + if( n ) + ASSERT( acc.get_total()==sum[n-1], NULL ); + else + ASSERT( acc.get_total()==42, NULL ); + REMARK("time [n=%ld] = %g\tused_once%% = %g\tnthread=%d\n",n,(t1-t0).seconds(), n==0 ? 0 : 100.0*used_once_count/n,nthread); + + + std::vector<T> sum_tmplt(MAXN); + for (long i = 0; i<MAXN; ++i) + sum_tmplt[i] = -2; + T total_tmplt = ParallelScanTemplateFunctor(Range(0, n, 1), 42, addend, sum_tmplt, mode); + + ASSERT(acc.get_total() == total_tmplt, "Parallel prefix sum with lambda interface is not equal to body interface"); + ASSERT(sum == sum_tmplt, "Parallel prefix vector with lambda interface is not equal to body interface"); + +#if __TBB_CPP11_LAMBDAS_PRESENT + std::vector<T> sum_lambda(MAXN); + for (long i = 0; i<MAXN; ++i) + sum_lambda[i] = -2; + T total_lambda = ParallelScanLambda(Range(0, n, 1), 42, addend, sum_lambda, mode); + + ASSERT(acc.get_total() == total_lambda, "Parallel prefix sum with lambda interface is not equal to body interface"); + ASSERT(sum == sum_lambda, "Parallel prefix vector with lambda interface is not equal to body interface"); + +#if __TBB_CPP14_GENERIC_LAMBDAS_PRESENT + std::vector<T> sum_generic_lambda(MAXN); + for (long i = 0; i<MAXN; ++i) + sum_generic_lambda[i] = -2; + T total_generic_lambda = ParallelScanGenericLambda(Range(0, n, 1), 42, addend, sum_generic_lambda, mode); + + ASSERT(acc.get_total() == total_generic_lambda, "Parallel prefix sum with lambda (generic) interface is not equal to body interface"); + ASSERT(sum == sum_generic_lambda, "Parallel prefix vector with lambda (generic) interface is not equal to body interface"); + +#endif /* GENERIC_LAMBDAS */ +#endif /* LAMBDAS */ + } +} + +static void TestScanTags() { + ASSERT( tbb::pre_scan_tag::is_final_scan()==false, NULL ); + ASSERT( tbb::final_scan_tag::is_final_scan()==true, NULL ); + ASSERT( tbb::pre_scan_tag() == false, NULL ); + ASSERT( tbb::final_scan_tag() == true, NULL ); +} + +#include "tbb/task_scheduler_init.h" +#include "harness_cpu.h" + +int TestMain () { + TestScanTags(); + for( int p=MinThread; p<=MaxThread; ++p ) { + for (int mode = 0; mode < 3; mode++) { + tbb::task_scheduler_init init(p); + NumberOfLiveStorage = 0; + TestAccumulator(mode, p); + // Test that all workers sleep when no work + TestCPUUserTime(p); + + // Checking has to be done late, because when parallel_scan makes copies of + // the user's "Body", the copies might be destroyed slightly after parallel_scan + // returns. + ASSERT( NumberOfLiveStorage==0, NULL ); + } + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_sort.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_sort.cpp new file mode 100644 index 00000000..95858de1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_sort.cpp @@ -0,0 +1,556 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/parallel_sort.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/concurrent_vector.h" +#include "harness.h" +#include <math.h> +#include <vector> +#include <exception> +#include <algorithm> +#include <iterator> +#include <functional> +#include <string> +#include <cstring> + +/** Has tightly controlled interface so that we can verify + that parallel_sort uses only the required interface. */ +class Minimal { + int val; +public: + Minimal() {} + void set_val(int i) { val = i; } + static bool CompareWith (const Minimal &a, const Minimal &b) { + return (a.val < b.val); + } + static bool AreEqual( Minimal &a, Minimal &b) { + return a.val == b.val; + } +}; + +//! Defines a comparison function object for Minimal +class MinimalCompare { +public: + bool operator() (const Minimal &a, const Minimal &b) const { + return Minimal::CompareWith(a,b); + } +}; + +//! The default validate; but it uses operator== which is not required +template<typename RandomAccessIterator> +bool Validate(RandomAccessIterator a, RandomAccessIterator b, size_t n) { + for (size_t i = 0; i < n; i++) { + ASSERT( a[i] == b[i], NULL ); + } + return true; +} + +//! A Validate specialized to string for debugging-only +template<> +bool Validate<std::string *>(std::string * a, std::string * b, size_t n) { + for (size_t i = 0; i < n; i++) { + if ( Verbose && a[i] != b[i]) { + for (size_t j = 0; j < n; j++) { + REPORT("a[%llu] == %s and b[%llu] == %s\n", static_cast<unsigned long long>(j), a[j].c_str(), static_cast<unsigned long long>(j), b[j].c_str()); + } + } + ASSERT( a[i] == b[i], NULL ); + } + return true; +} + +//! A Validate specialized to Minimal since it does not define an operator== +template<> +bool Validate<Minimal *>(Minimal *a, Minimal *b, size_t n) { + for (size_t i = 0; i < n; i++) { + ASSERT( Minimal::AreEqual(a[i],b[i]), NULL ); + } + return true; +} + +//! A Validate specialized to concurrent_vector<Minimal> since it does not define an operator== +template<> +bool Validate<tbb::concurrent_vector<Minimal>::iterator>(tbb::concurrent_vector<Minimal>::iterator a, + tbb::concurrent_vector<Minimal>::iterator b, size_t n) { + for (size_t i = 0; i < n; i++) { + ASSERT( Minimal::AreEqual(a[i],b[i]), NULL ); + } + return true; +} + +//! used in Verbose mode for identifying which data set is being used +static std::string test_type; + +//! The default initialization routine. +/*! This routine assumes that you can assign to the elements from a float. + It assumes that iter and sorted_list have already been allocated. It fills + them according to the current data set (tracked by a local static variable). + Returns true if a valid test has been setup, or false if there is no test to + perform. +*/ + +template < typename RandomAccessIterator, typename Compare > +bool init_iter(RandomAccessIterator iter, RandomAccessIterator sorted_list, size_t n, const Compare &compare, bool reset) { + static char test_case = 0; + const char num_cases = 3; + + if (reset) test_case = 0; + + if (test_case < num_cases) { + // switch on the current test case, filling the iter and sorted_list appropriately + switch(test_case) { + case 0: + /* use sin to generate the values */ + test_type = "sin"; + for (size_t i = 0; i < n; i++) + iter[i] = sorted_list[i] = static_cast<typename std::iterator_traits< RandomAccessIterator >::value_type>(sin(float(i))); + break; + case 1: + /* presorted list */ + test_type = "pre-sorted"; + for (size_t i = 0; i < n; i++) + iter[i] = sorted_list[i] = static_cast<typename std::iterator_traits< RandomAccessIterator >::value_type>(i); + break; + case 2: + /* reverse-sorted list */ + test_type = "reverse-sorted"; + for (size_t i = 0; i < n; i++) + iter[i] = sorted_list[i] = static_cast<typename std::iterator_traits< RandomAccessIterator >::value_type>(n - i); + break; + } + + // pre-sort sorted_list for later validity testing + std::sort(sorted_list, sorted_list + n, compare); + test_case++; + return true; + } + return false; +} + +template < typename T, typename Compare > +bool init_iter(T * iter, T * sorted_list, size_t n, const Compare &compare, bool reset) { + static char test_case = 0; + const char num_cases = 3; + + if (reset) test_case = 0; + + if (test_case < num_cases) { + // switch on the current test case, filling the iter and sorted_list appropriately + switch(test_case) { + case 0: + /* use sin to generate the values */ + test_type = "sin"; + for (size_t i = 0; i < n; i++) { + iter[i] = T(sin(float(i))); + sorted_list[i] = T(sin(float(i))); + } + break; + case 1: + /* presorted list */ + test_type = "pre-sorted"; + for (size_t i = 0; i < n; i++) { + iter[i] = T(i); + sorted_list[i] = T(i); + } + break; + case 2: + /* reverse-sorted list */ + test_type = "reverse-sorted"; + for (size_t i = 0; i < n; i++) { + iter[i] = T(n - i); + sorted_list[i] = T(n - i); + } + break; + } + + // pre-sort sorted_list for later validity testing + std::sort(sorted_list, sorted_list + n, compare); + test_case++; + return true; + } + return false; +} + + +//! The initialization routine specialized to the class Minimal +/*! Minimal cannot have floats assigned to it. This function uses the set_val method +*/ + +template < > +bool init_iter(Minimal* iter, Minimal * sorted_list, size_t n, const MinimalCompare &compare, bool reset) { + static char test_case = 0; + const char num_cases = 3; + + if (reset) test_case = 0; + + if (test_case < num_cases) { + switch(test_case) { + case 0: + /* use sin to generate the values */ + test_type = "sin"; + for (size_t i = 0; i < n; i++) { + iter[i].set_val( int( sin( float(i) ) * 1000.f) ); + sorted_list[i].set_val( int ( sin( float(i) ) * 1000.f) ); + } + break; + case 1: + /* presorted list */ + test_type = "pre-sorted"; + for (size_t i = 0; i < n; i++) { + iter[i].set_val( int(i) ); + sorted_list[i].set_val( int(i) ); + } + break; + case 2: + /* reverse-sorted list */ + test_type = "reverse-sorted"; + for (size_t i = 0; i < n; i++) { + iter[i].set_val( int(n-i) ); + sorted_list[i].set_val( int(n-i) ); + } + break; + } + std::sort(sorted_list, sorted_list + n, compare); + test_case++; + return true; + } + return false; +} + +//! The initialization routine specialized to the class concurrent_vector<Minimal> +/*! Minimal cannot have floats assigned to it. This function uses the set_val method +*/ + +template < > +bool init_iter(tbb::concurrent_vector<Minimal>::iterator iter, tbb::concurrent_vector<Minimal>::iterator sorted_list, + size_t n, const MinimalCompare &compare, bool reset) { + static char test_case = 0; + const char num_cases = 3; + + if (reset) test_case = 0; + + if (test_case < num_cases) { + switch(test_case) { + case 0: + /* use sin to generate the values */ + test_type = "sin"; + for (size_t i = 0; i < n; i++) { + iter[i].set_val( int( sin( float(i) ) * 1000.f) ); + sorted_list[i].set_val( int ( sin( float(i) ) * 1000.f) ); + } + break; + case 1: + /* presorted list */ + test_type = "pre-sorted"; + for (size_t i = 0; i < n; i++) { + iter[i].set_val( int(i) ); + sorted_list[i].set_val( int(i) ); + } + break; + case 2: + /* reverse-sorted list */ + test_type = "reverse-sorted"; + for (size_t i = 0; i < n; i++) { + iter[i].set_val( int(n-i) ); + sorted_list[i].set_val( int(n-i) ); + } + break; + } + std::sort(sorted_list, sorted_list + n, compare); + test_case++; + return true; + } + return false; +} + +//! The initialization routine specialized to the class string +/*! strings are created from floats. +*/ + +template<> +bool init_iter(std::string *iter, std::string *sorted_list, size_t n, const std::less<std::string> &compare, bool reset) { + static char test_case = 0; + const char num_cases = 1; + + if (reset) test_case = 0; + + if (test_case < num_cases) { + switch(test_case) { + case 0: + /* use sin to generate the values */ + test_type = "sin"; + for (size_t i = 0; i < n; i++) { + char buffer[20]; +// Getting rid of secure warning issued by VC 14 and newer +#if _MSC_VER && __STDC_SECURE_LIB__>=200411 + sprintf_s(buffer, sizeof(buffer), "%f", float(sin(float(i)))); +#else + sprintf(buffer, "%f", float(sin(float(i)))); +#endif + sorted_list[i] = iter[i] = std::string(buffer); + } + break; + } + std::sort(sorted_list, sorted_list + n, compare); + test_case++; + return true; + } + return false; +} + +//! The current number of threads in use (for Verbose only) +static size_t current_p; + +//! The current data type being sorted (for Verbose only) +static std::string current_type; + +//! The default test routine. +/*! Tests all data set sizes from 0 to N, all grainsizes from 0 to G=10, and selects from + all possible interfaces to parallel_sort depending on whether a scratch space and + compare have been provided. +*/ +template<typename RandomAccessIterator, typename Compare> +bool parallel_sortTest(size_t n, RandomAccessIterator iter, RandomAccessIterator sorted_list, const Compare *comp) { + bool passed = true; + + Compare local_comp; + + init_iter(iter, sorted_list, n, local_comp, true); + do { + REMARK("%s %s p=%llu n=%llu :",current_type.c_str(), test_type.c_str(), + static_cast<unsigned long long>(current_p), static_cast<unsigned long long>(n)); + if (comp != NULL) { + tbb::parallel_sort(iter, iter + n, local_comp ); + } else { + tbb::parallel_sort(iter, iter + n ); + } + if (!Validate(iter, sorted_list, n)) + passed = false; + REMARK("passed\n"); + } while (init_iter(iter, sorted_list, n, local_comp, false)); + return passed; +} + +//! The test routine specialize to Minimal, since it does not have a less defined for it +template<> +bool parallel_sortTest(size_t n, Minimal * iter, Minimal * sorted_list, const MinimalCompare *compare) { + bool passed = true; + + if (compare == NULL) return passed; + + init_iter(iter, sorted_list, n, *compare, true); + do { + REMARK("%s %s p=%llu n=%llu :",current_type.c_str(), test_type.c_str(), + static_cast<unsigned long long>(current_p), static_cast<unsigned long long>(n)); + + tbb::parallel_sort(iter, iter + n, *compare ); + + if (!Validate(iter, sorted_list, n)) + passed = false; + REMARK("passed\n"); + } while (init_iter(iter, sorted_list, n, *compare, false)); + return passed; +} + +//! The test routine specialize to concurrent_vector of Minimal, since it does not have a less defined for it +template<> +bool parallel_sortTest(size_t n, tbb::concurrent_vector<Minimal>::iterator iter, + tbb::concurrent_vector<Minimal>::iterator sorted_list, const MinimalCompare *compare) { + bool passed = true; + + if (compare == NULL) return passed; + + init_iter(iter, sorted_list, n, *compare, true); + do { + REMARK("%s %s p=%llu n=%llu :",current_type.c_str(), test_type.c_str(), + static_cast<unsigned long long>(current_p), static_cast<unsigned long long>(n)); + + tbb::parallel_sort(iter, iter + n, *compare ); + + if (!Validate(iter, sorted_list, n)) + passed = false; + REMARK("passed\n"); + } while (init_iter(iter, sorted_list, n, *compare, false)); + return passed; +} + +//! The main driver for the tests. +/*! Minimal, float and string types are used. All interfaces to parallel_sort that are usable + by each type are tested. +*/ +void Flog() { + // For each type create: + // the list to be sorted by parallel_sort (array) + // the list to be sort by STL sort (array_2) + // and a less function object + + const size_t N = 50000; + + Minimal *minimal_array = new Minimal[N]; + Minimal *minimal_array_2 = new Minimal[N]; + MinimalCompare minimal_less; + + float *float_array = new float[N]; + float *float_array_2 = new float[N]; + std::less<float> float_less; + + tbb::concurrent_vector<float> float_cv1; + tbb::concurrent_vector<float> float_cv2; + float_cv1.grow_to_at_least(N); + float_cv2.grow_to_at_least(N); + + std::string *string_array = new std::string[N]; + std::string *string_array_2 = new std::string[N]; + std::less<std::string> string_less; + + tbb::concurrent_vector<Minimal> minimal_cv1; + tbb::concurrent_vector<Minimal> minimal_cv2; + minimal_cv1.grow_to_at_least(N); + minimal_cv2.grow_to_at_least(N); + + + // run the appropriate tests for each type + + current_type = "Minimal(less)"; + parallel_sortTest(0, minimal_array, minimal_array_2, &minimal_less); + parallel_sortTest(1, minimal_array, minimal_array_2, &minimal_less); + parallel_sortTest(10, minimal_array, minimal_array_2, &minimal_less); + parallel_sortTest(9999, minimal_array, minimal_array_2, &minimal_less); + parallel_sortTest(50000, minimal_array, minimal_array_2, &minimal_less); + + current_type = "float (no less)"; + parallel_sortTest(0, float_array, float_array_2, static_cast<std::less<float> *>(NULL)); + parallel_sortTest(1, float_array, float_array_2, static_cast<std::less<float> *>(NULL)); + parallel_sortTest(10, float_array, float_array_2, static_cast<std::less<float> *>(NULL)); + parallel_sortTest(9999, float_array, float_array_2, static_cast<std::less<float> *>(NULL)); + parallel_sortTest(50000, float_array, float_array_2, static_cast<std::less<float> *>(NULL)); + + current_type = "float (less)"; + parallel_sortTest(0, float_array, float_array_2, &float_less); + parallel_sortTest(1, float_array, float_array_2, &float_less); + parallel_sortTest(10, float_array, float_array_2, &float_less); + parallel_sortTest(9999, float_array, float_array_2, &float_less); + parallel_sortTest(50000, float_array, float_array_2, &float_less); + + current_type = "concurrent_vector<float> (no less)"; + parallel_sortTest(0, float_cv1.begin(), float_cv2.begin(), static_cast<std::less<float> *>(NULL)); + parallel_sortTest(1, float_cv1.begin(), float_cv2.begin(), static_cast<std::less<float> *>(NULL)); + parallel_sortTest(10, float_cv1.begin(), float_cv2.begin(), static_cast<std::less<float> *>(NULL)); + parallel_sortTest(9999, float_cv1.begin(), float_cv2.begin(), static_cast<std::less<float> *>(NULL)); + parallel_sortTest(50000, float_cv1.begin(), float_cv2.begin(), static_cast<std::less<float> *>(NULL)); + + current_type = "concurrent_vector<float> (less)"; + parallel_sortTest(0, float_cv1.begin(), float_cv2.begin(), &float_less); + parallel_sortTest(1, float_cv1.begin(), float_cv2.begin(), &float_less); + parallel_sortTest(10, float_cv1.begin(), float_cv2.begin(), &float_less); + parallel_sortTest(9999, float_cv1.begin(), float_cv2.begin(), &float_less); + parallel_sortTest(50000, float_cv1.begin(), float_cv2.begin(), &float_less); + + current_type = "string (no less)"; + parallel_sortTest(0, string_array, string_array_2, static_cast<std::less<std::string> *>(NULL)); + parallel_sortTest(1, string_array, string_array_2, static_cast<std::less<std::string> *>(NULL)); + parallel_sortTest(10, string_array, string_array_2, static_cast<std::less<std::string> *>(NULL)); + parallel_sortTest(9999, string_array, string_array_2, static_cast<std::less<std::string> *>(NULL)); + parallel_sortTest(50000, string_array, string_array_2, static_cast<std::less<std::string> *>(NULL)); + + current_type = "string (less)"; + parallel_sortTest(0, string_array, string_array_2, &string_less); + parallel_sortTest(1, string_array, string_array_2, &string_less); + parallel_sortTest(10, string_array, string_array_2, &string_less); + parallel_sortTest(9999, string_array, string_array_2, &string_less); + parallel_sortTest(50000, string_array, string_array_2, &string_less); + + current_type = "concurrent_vector<Minimal> (less)"; + parallel_sortTest(0, minimal_cv1.begin(), minimal_cv2.begin(), &minimal_less); + parallel_sortTest(1, minimal_cv1.begin(), minimal_cv2.begin(), &minimal_less); + parallel_sortTest(10, minimal_cv1.begin(), minimal_cv2.begin(), &minimal_less); + parallel_sortTest(9999, minimal_cv1.begin(), minimal_cv2.begin(), &minimal_less); + parallel_sortTest(50000, minimal_cv1.begin(), minimal_cv2.begin(), &minimal_less); + + delete [] minimal_array; + delete [] minimal_array_2; + + delete [] float_array; + delete [] float_array_2; + + delete [] string_array; + delete [] string_array_2; +} + +const int elements = 10000; + +void rand_vec(std::vector<int> &v) { + for (int i=0; i<elements; ++i) { + (v.push_back(rand()%elements*10)); + } +} + +void range_sort_test() { + std::vector<int> v; + + typedef std::vector<int>::iterator itor; + // iterator checks + rand_vec(v); + tbb::parallel_sort(v.begin(), v.end()); + for(itor a=v.begin(); a<v.end()-1; ++a) ASSERT(*a <= *(a+1), "v not sorted"); + v.clear(); + + rand_vec(v); + tbb::parallel_sort(v.begin(), v.end(), std::greater<int>()); + for(itor a=v.begin(); a<v.end()-1; ++a) ASSERT(*a >= *(a+1), "v not sorted"); + v.clear(); + + // range checks + rand_vec(v); + tbb::parallel_sort(v); + for(itor a=v.begin(); a<v.end()-1; ++a) ASSERT(*a <= *(a+1), "v not sorted"); + v.clear(); + + rand_vec(v); + tbb::parallel_sort(v, std::greater<int>()); + for(itor a=v.begin(); a<v.end()-1; ++a) ASSERT(*a >= *(a+1), "v not sorted"); + v.clear(); + + // array tests + int arr[elements]; + for(int i=0; i<elements; ++i) arr[i] = rand()%(elements*10); + tbb::parallel_sort(arr); + for(int i=0; i<elements-1; ++i) ASSERT(arr[i] <= arr[i+1], "arr not sorted"); +} + +#include <cstdio> +#include "harness_cpu.h" + +int TestMain () { + if( MinThread<1 ) { + REPORT("Usage: number of threads must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + if( p>0 ) { + tbb::task_scheduler_init init( p ); + current_p = p; + Flog(); + range_sort_test(); + + // Test that all workers sleep when no work + TestCPUUserTime(p); + } + } + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_while.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_while.cpp new file mode 100644 index 00000000..d9cc771d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_parallel_while.cpp @@ -0,0 +1,167 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/parallel_while.h" +#include "harness.h" + +const int N = 200; + +typedef int Element; + +//! Representation of an array index with only those signatures required by parallel_while. +class MinimalArgumentType { + void operator=( const MinimalArgumentType& ); + long my_value; + enum { + DEAD=0xDEAD, + LIVE=0x2718, + INITIALIZED=0x3141 + } my_state; +public: + ~MinimalArgumentType() { + ASSERT( my_state==LIVE||my_state==INITIALIZED, NULL ); + my_state = DEAD; + } + MinimalArgumentType() { + my_state = LIVE; + } + void set_value( long i ) { + ASSERT( my_state==LIVE||my_state==INITIALIZED, NULL ); + my_value = i; + my_state = INITIALIZED; + } + long get_value() const { + ASSERT( my_state==INITIALIZED, NULL ); + return my_value; + } +}; + +class IntegerStream { + long my_limit; + long my_index; +public: + IntegerStream( long n ) : my_limit(n), my_index(0) {} + bool pop_if_present( MinimalArgumentType& v ) { + if( my_index>=my_limit ) + return false; + v.set_value( my_index ); + my_index+=2; + return true; + } +}; + +class MatrixMultiplyBody: NoAssign { + Element (*a)[N]; + Element (*b)[N]; + Element (*c)[N]; + const int n; + tbb::parallel_while<MatrixMultiplyBody>& my_while; +public: + typedef MinimalArgumentType argument_type; + void operator()( argument_type i_arg ) const { + long i = i_arg.get_value(); + if( (i&1)==0 && i+1<N ) { + MinimalArgumentType value; + value.set_value(i+1); + my_while.add( value ); + } + for( int j=0; j<n; ++j ) + c[i][j] = 0; + for( int k=0; k<n; ++k ) { + Element aik = a[i][k]; + for( int j=0; j<n; ++j ) + c[i][j] += aik*b[k][j]; + } + } + MatrixMultiplyBody( tbb::parallel_while<MatrixMultiplyBody>& w, Element c_[N][N], Element a_[N][N], Element b_[N][N], int n_ ) : + a(a_), b(b_), c(c_), n(n_), my_while(w) + {} +}; + +void WhileMatrixMultiply( Element c[N][N], Element a[N][N], Element b[N][N], int n ) { + IntegerStream stream( N ); + tbb::parallel_while<MatrixMultiplyBody> w; + MatrixMultiplyBody body(w,c,a,b,n); + w.run( stream, body ); +} + +#include "tbb/tick_count.h" +#include <cstdlib> +#include <cstdio> +using namespace std; + +static long Iterations = 5; + +static void SerialMatrixMultiply( Element c[N][N], Element a[N][N], Element b[N][N], int n ) { + for( int i=0; i<n; ++i ) { + for( int j=0; j<n; ++j ) + c[i][j] = 0; + for( int k=0; k<n; ++k ) { + Element aik = a[i][k]; + for( int j=0; j<n; ++j ) + c[i][j] += aik*b[k][j]; + } + } +} + +static void InitializeMatrix( Element x[N][N], int n, int salt ) { + for( int i=0; i<n; ++i ) + for( int j=0; j<n; ++j ) + x[i][j] = (i*n+j)^salt; +} + +static Element A[N][N], B[N][N], C[N][N], D[N][N]; + +static void Run( int nthread, int n ) { + /* Initialize matrices */ + InitializeMatrix(A,n,5); + InitializeMatrix(B,n,10); + InitializeMatrix(C,n,0); + InitializeMatrix(D,n,15); + + tbb::tick_count t0 = tbb::tick_count::now(); + for( long i=0; i<Iterations; ++i ) { + WhileMatrixMultiply( C, A, B, n ); + } + tbb::tick_count t1 = tbb::tick_count::now(); + SerialMatrixMultiply( D, A, B, n ); + + // Check result + for( int i=0; i<n; ++i ) + for( int j=0; j<n; ++j ) + ASSERT( C[i][j]==D[i][j], NULL ); + REMARK("time=%g\tnthread=%d\tn=%d\n",(t1-t0).seconds(),nthread,n); +} + +#include "tbb/task_scheduler_init.h" +#include "harness_cpu.h" + +int TestMain () { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init( p ); + for( int n=N/4; n<=N; n+=N/4 ) + Run(p,n); + + // Test that all workers sleep when no work + TestCPUUserTime(p); + } + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner.h new file mode 100644 index 00000000..de5543c8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner.h @@ -0,0 +1,607 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if _MSC_VER==1500 && !__INTEL_COMPILER + // VS2008/VC9 has an issue in math.h + #pragma warning( push ) + #pragma warning( disable: 4985 ) +#endif +#include <cmath> +#if _MSC_VER==1500 && !__INTEL_COMPILER + #pragma warning( pop ) +#endif +#include "tbb/tbb_stddef.h" +#include "harness.h" +#include <vector> + +namespace test_partitioner_utils { + +struct RangeStatisticData { + // denotes the number of range objects + size_t m_rangeNum; + + // store minimal and maximal range sizes (in terms of number of iterations) + size_t m_minRangeSize; + size_t m_maxRangeSize; + + bool m_wasMinRangeSizeWritten; // shows whether relevant field was written or not +}; + +using tbb::internal::uint64_t; +using tbb::split; +using tbb::proportional_split; +using tbb::blocked_range; + +// helper for calculating number of range objects created before balancing phase is started +// and for finding maximum and minimum number of iterations among all such ranges +// Note: class does not provide exclusive access to members +class RangeStatisticCollector { +public: + RangeStatisticCollector(RangeStatisticData *statisticData) : + m_statData(statisticData) + { + m_called = false; + if (m_statData) + m_statData->m_rangeNum = 1; + } + + // constructor is called from non-proportional split constructor of derived Range + RangeStatisticCollector(RangeStatisticCollector& sc, size_t rangeSize) { + if (!sc.m_called) { + // this is the first time non-proportional split constructor is called + // it means that work distribution phase has been completed and + // work balancing phase has been just started + sc.m_called = true; + + if (sc.m_statData) { + size_t *minRangeSize = &sc.m_statData->m_minRangeSize; + if (*minRangeSize > rangeSize || !sc.m_statData->m_wasMinRangeSizeWritten) { // if minimum is not an actual minimum + *minRangeSize = rangeSize; + sc.m_statData->m_wasMinRangeSizeWritten = true; + } + size_t *maxRangeSize = &sc.m_statData->m_maxRangeSize; + if (*maxRangeSize < rangeSize) { // if maximum is not an actual maximum + *maxRangeSize = rangeSize; + } + } + } + *this = sc; + // constructor is used on work balancing phase only, so no need to increment + // number of range objects created + } + + RangeStatisticCollector(RangeStatisticCollector& sc, proportional_split&) { + if (sc.m_statData) + sc.m_statData->m_rangeNum++; + *this = sc; + } + +private: + RangeStatisticData *m_statData; + + // turns to 'true' when non-proportional split constructor is called first time + bool m_called; +}; + +// Base class for fake ranges used in vaious tests for parallel +// algorithms as well as for partitioner +template <typename DerivedRange, typename T> +class RangeBase: public RangeStatisticCollector { +protected: + size_t my_begin, my_end; + bool m_provide_feedback; + bool m_ensure_non_empty_size; +public: + RangeBase(size_t _begin, size_t _end, RangeStatisticData *statData, + bool provide_feedback, bool ensure_non_empty_size) + : RangeStatisticCollector(statData) + , my_begin(_begin), my_end(_end) + , m_provide_feedback(provide_feedback) + , m_ensure_non_empty_size(ensure_non_empty_size) + { } + RangeBase(RangeBase& r, tbb::split) : RangeStatisticCollector(r, r.size()) { + *this = r; + size_t middle = r.my_begin + (r.my_end - r.my_begin) / 2u; + r.my_end = my_begin = middle; + } + + RangeBase(RangeBase& r, proportional_split& p) : RangeStatisticCollector(r, p) { + *this = r; + size_t original_size = r.size(); + T right = self().compute_right_part(r, p); + size_t right_part = self().round(right); + if( m_ensure_non_empty_size ) { + right_part = (original_size == right_part) ? (original_size - 1) : right_part; + right_part = (right_part != 0) ? right_part : 1; + } + r.my_end = my_begin = r.my_end - right_part; +#if __TBB_ENABLE_RANGE_FEEDBACK + if( m_provide_feedback ) + p.set_proportion(original_size - right_part, right_part); +#endif + if( m_ensure_non_empty_size ) + ASSERT(r.my_end != r.my_begin && my_end != my_begin, "Incorrect range split"); + } + + size_t begin() const { return my_begin; } + size_t end() const { return my_end; } + bool is_divisible() const { return (my_end - my_begin) > 1; } + bool empty() const { return my_end == my_begin; } + size_t size() const { return my_end - my_begin; } + + // helper methods (not part of the range concept) + DerivedRange& self() { return static_cast<DerivedRange&>(*this); } + size_t round(T part) { return size_t(part); } + T compute_right_part(RangeBase& r, proportional_split& p) { + return T(r.size() * T(p.right())) / T(p.left() + p.right()); + } + bool is_ensure_non_emptiness() { return m_ensure_non_empty_size; } +}; + +namespace TestRanges { +/* + * RoundedUpRange rounds result up + * RoundedDownRange rounds result down + * Range1_2 forces proportion always to be 1:2 and rounds up + * Range1_999 uses weird proportion 1:999 and rounds up + * Range1_999 uses weird proportion 999:1 and rounds up + * BlockedRange uses tbb::blocked_range formula for proportion calculation + * InvertedProportionRange inverts proportion suggested by partitioner (e.g. 1:3 --> 3:1) + * ExactSplitRange uses integer arithmetic for accurate splitting + */ + +class RoundedDownRange: public RangeBase<RoundedDownRange, float> { +public: + RoundedDownRange(size_t _begin, size_t _end, RangeStatisticData *statData, + bool provide_feedback, bool ensure_non_empty_size) + : RangeBase<RoundedDownRange, float>(_begin, _end, statData, provide_feedback, + ensure_non_empty_size) { } + RoundedDownRange(RoundedDownRange& r, tbb::split) + : RangeBase<RoundedDownRange, float>(r, tbb::split()) { } + RoundedDownRange(RoundedDownRange& r, proportional_split& p) + : RangeBase<RoundedDownRange, float>(r, p) { } + // uses default implementation of RangeBase::round() which rounds down + static const bool is_splittable_in_proportion = true; +}; + +class RoundedUpRange: public RangeBase<RoundedUpRange, float> { +public: + RoundedUpRange(size_t _begin, size_t _end, RangeStatisticData *statData, + bool provide_feedback, bool ensure_non_empty_size) + : RangeBase<RoundedUpRange, float>(_begin, _end, statData, provide_feedback, + ensure_non_empty_size) { } + RoundedUpRange(RoundedUpRange& r, tbb::split) + : RangeBase<RoundedUpRange, float>(r, tbb::split()) { } + RoundedUpRange(RoundedUpRange& r, proportional_split& p) + : RangeBase<RoundedUpRange, float>(r, p) { } + size_t round(float part) { return size_t(std::ceil(part)); } + static const bool is_splittable_in_proportion = true; +}; + +class Range1_2: public RangeBase<Range1_2, float> { +public: + Range1_2(size_t _begin, size_t _end, RangeStatisticData *statData, + bool provide_feedback, bool ensure_non_empty_size) + : RangeBase<Range1_2, float>(_begin, _end, statData, provide_feedback, + ensure_non_empty_size) { } + Range1_2(Range1_2& r, tbb::split) : RangeBase<Range1_2, float>(r, tbb::split()) { } + Range1_2(Range1_2& r, proportional_split& p) : RangeBase<Range1_2, float>(r, p) { } + static const bool is_splittable_in_proportion = true; + float compute_right_part(RangeBase<Range1_2, float>& r, proportional_split&) { + return float(r.size() * 2) / 3.0f; + } + // uses default implementation of RangeBase::round() which rounds down +}; + +class Range1_999: public RangeBase<Range1_999, float> { +public: + Range1_999(size_t _begin, size_t _end, RangeStatisticData *statData, + bool provide_feedback, bool ensure_non_empty_size) + : RangeBase<Range1_999, float>(_begin, _end, statData, provide_feedback, + ensure_non_empty_size) { } + Range1_999(Range1_999& r, tbb::split) : RangeBase<Range1_999, float>(r, tbb::split()) { } + Range1_999(Range1_999& r, proportional_split& p) : RangeBase<Range1_999, float>(r, p) { } + static const bool is_splittable_in_proportion = true; + float compute_right_part(RangeBase<Range1_999, float>& r, proportional_split&) { + return float(r.size() * 999) / 1000.0f; + } + // uses default implementation of RangeBase::round() which rounds down +}; + +class Range999_1: public RangeBase<Range999_1, float> { +public: + Range999_1(size_t _begin, size_t _end, RangeStatisticData *statData, + bool provide_feedback, bool ensure_non_empty_size) + : RangeBase<Range999_1, float>(_begin, _end, statData, provide_feedback, + ensure_non_empty_size) { } + Range999_1(Range999_1& r, tbb::split) : RangeBase<Range999_1, float>(r, tbb::split()) { } + Range999_1(Range999_1& r, proportional_split& p) : RangeBase<Range999_1, float>(r, p) { } + static const bool is_splittable_in_proportion = true; + float compute_right_part(RangeBase<Range999_1, float>& r, proportional_split&) { + return float(r.size()) / 1000.0f; + } + // uses default implementation of RangeBase::round() which rounds down +}; + +class BlockedRange: public RangeStatisticCollector, public blocked_range<size_t> { +public: + BlockedRange(size_t _begin, size_t _end, RangeStatisticData *statData, bool, bool) + : RangeStatisticCollector(statData), blocked_range<size_t>(_begin, _end) { } + BlockedRange(BlockedRange& r, split) + : RangeStatisticCollector(r, r.size()), blocked_range<size_t>(r, split()) { } + BlockedRange(BlockedRange& r, proportional_split& p) + : RangeStatisticCollector(r, p), blocked_range<size_t>(r, p) { } + static const bool is_splittable_in_proportion = true; + bool is_ensure_non_emptiness() { return false; } +}; + +class InvertedProportionRange: public RangeBase<InvertedProportionRange, float> { +public: + InvertedProportionRange(size_t _begin, size_t _end, RangeStatisticData *statData, + bool provide_feedback, bool ensure_non_empty_size) + : RangeBase<InvertedProportionRange, float>(_begin, _end, statData, provide_feedback, + ensure_non_empty_size) { } + InvertedProportionRange(InvertedProportionRange& r, split) + : RangeBase<InvertedProportionRange, float>(r, split()) { } + InvertedProportionRange(InvertedProportionRange& r, proportional_split& p) + : RangeBase<InvertedProportionRange, float>(r, p) { } + float compute_right_part(RangeBase<InvertedProportionRange, float>& r, + proportional_split& p) { + return float(r.size() * float(p.left())) / float(p.left() + p.right()); + } + static const bool is_splittable_in_proportion = true; +}; + +class ExactSplitRange: public RangeBase<ExactSplitRange, size_t> { +public: + ExactSplitRange(size_t _begin, size_t _end, RangeStatisticData *statData, + bool provide_feedback, bool ensure_non_empty_size) + : RangeBase<ExactSplitRange, size_t>(_begin, _end, statData, provide_feedback, + ensure_non_empty_size) { } + ExactSplitRange(ExactSplitRange& r, split) + : RangeBase<ExactSplitRange, size_t>(r, split()) { } + ExactSplitRange(ExactSplitRange& r, proportional_split& p) + : RangeBase<ExactSplitRange, size_t>(r, p) { } + size_t compute_right_part(RangeBase<ExactSplitRange, size_t>& r, proportional_split& p) { + size_t parts = size_t(p.left() + p.right()); + size_t currSize = r.size(); + size_t int_part = currSize / parts * p.right(); + size_t remainder = currSize % parts * p.right(); + int_part += remainder / parts; + remainder %= parts; + size_t right_part = int_part + (remainder > parts/2 ? 1 : 0); + return right_part; + } + static const bool is_splittable_in_proportion = true; +}; + +} // namespace TestRanges + +struct TreeNode { + size_t m_affinity; + size_t m_range_begin, m_range_end; + TreeNode *m_left, *m_right; +private: + TreeNode(size_t range_begin, size_t range_end, size_t affinity, + TreeNode* left, TreeNode* right) + : m_affinity(affinity), m_range_begin(range_begin), m_range_end(range_end), + m_left(left), m_right(right) { } + + friend TreeNode* make_node(size_t range_begin, size_t range_end, size_t affinity, + TreeNode *left, TreeNode *right); +}; + +TreeNode* make_node(size_t range_begin, size_t range_end, size_t affinity, + TreeNode* left = NULL, TreeNode* right = NULL) { + ASSERT(range_begin <= range_end, "Incorrect range interval"); + return new TreeNode(range_begin, range_end, affinity, left, right); +} + +// Class stores nodes as a binary tree +// (marshals TreeNode objects in accordance with values of range intervals) +// Note: BinaryTree deletes all TreeNode objects pushed into it in a destruction phase +class BinaryTree { +public: + BinaryTree() : m_root(NULL) { } + ~BinaryTree() { + if (m_root) + remove_node_recursively(m_root); + } + + // pushed node must be within subrange of the parent nodes + void push_node(TreeNode* node) { + if (!node) + return; + + if (m_root) { + ASSERT(node->m_range_begin >= m_root->m_range_begin && + node->m_range_end <= m_root->m_range_end, + "Cannot push node not from subrange"); + } + + push_subnode(m_root, node); + } + + void visualize() { + if (!m_root) { // nothing to visualize + REPORT("Tree is empty\n"); + return; + } + visualize_node(m_root); + } + + bool operator ==(const BinaryTree& other_tree) const { return compare_nodes(m_root, other_tree.m_root); } + void fill_leafs(std::vector<TreeNode*>& leafs) const { fill_leafs_impl(m_root, leafs); } + +private: + TreeNode *m_root; + + void push_subnode(TreeNode *&root_node, TreeNode *node) { + if (!root_node) { + root_node = node; + return; + } else if (are_nodes_equal(root_node, node)) { + // no need to push the same node + return; + } + + if (!has_children(root_node)) { + // if current root_node does not have children passed node + // should has one of the interval bounds to be equal to + // the same bound in the root_node + if (is_look_like_left_sibling(root_node, node)) + push_subnode(root_node->m_left, node); + else + push_subnode(root_node->m_right, node); + return; + } + + if (has_left_child(root_node)) { + if (is_subnode(root_node->m_left, node)) { + push_subnode(root_node->m_left, node); + return; + } + push_subnode(root_node->m_right, node); + return; + } + + ASSERT(root_node->m_right != NULL, "Right child is NULL but must be present"); + if (is_subnode(root_node->m_right, node)) { + push_subnode(root_node->m_right, node); + return; + } + push_subnode(root_node->m_left, node); + return; + } + + bool has_children(TreeNode *node) { return node->m_left || node->m_right; } + + bool is_look_like_left_sibling(TreeNode *root_node, TreeNode *node) { + if (root_node->m_range_begin == node->m_range_begin) + return true; + ASSERT(root_node->m_range_end == node->m_range_end, NULL); + return false; + } + + bool has_left_child(TreeNode *node) { return node->m_left != NULL; } + + bool is_subnode(TreeNode *root_node, TreeNode *node) { + return root_node->m_range_begin <= node->m_range_begin && + node->m_range_end <= root_node->m_range_end; + } + + bool are_nodes_equal(TreeNode *node1, TreeNode *node2) const { + return node1->m_range_begin == node2->m_range_begin && + node1->m_range_end == node2->m_range_end; + } + + void remove_node_recursively(TreeNode *node) { + if (node->m_left) + remove_node_recursively(node->m_left); + if (node->m_right) + remove_node_recursively(node->m_right); + delete node; + } + + static void visualize_node(const TreeNode* node, unsigned indent = 0) { + // respecting indent + const char *indentStep = " "; + for (unsigned i = 0; i < indent; ++i) + REPORT("%s", indentStep); + + size_t rangeSize = node->m_range_end - node->m_range_begin; + REPORT("[%llu, %llu)%%%llu@%llu\n", uint64_t(node->m_range_begin), uint64_t(node->m_range_end), + uint64_t(rangeSize), uint64_t(node->m_affinity)); + + if (node->m_left) + visualize_node(node->m_left, indent + 1); + if (node->m_right) + visualize_node(node->m_right, indent + 1); + } + + bool compare_nodes(TreeNode* node1, TreeNode* node2) const { + if (node1 == NULL && node2 == NULL) return true; + if (node1 == NULL || node2 == NULL) return false; + return are_nodes_equal(node1, node2) && compare_nodes(node1->m_left, node2->m_left) + && compare_nodes(node1->m_right, node2->m_right); + } + + void fill_leafs_impl(TreeNode* node, std::vector<TreeNode*>& leafs) const { + if (node->m_left == NULL && node->m_right == NULL) + leafs.push_back(node); + if (node->m_left != NULL) fill_leafs_impl(node->m_left, leafs); + if (node->m_right != NULL) fill_leafs_impl(node->m_right, leafs); + } +}; + +class SimpleBody { +public: + SimpleBody() { } + template <typename Range> + void operator()(Range&) const { } +}; + +class SimpleReduceBody { +public: + SimpleReduceBody() { } + SimpleReduceBody(SimpleReduceBody&, tbb::split) { } + template <typename Range> + void operator()(Range&) { } + void join(SimpleReduceBody&) { } +}; + +namespace interaction_with_range_and_partitioner { + +class SplitConstructorAssertedRange { + mutable bool is_divisible_called; + mutable bool is_empty_called; + bool my_assert_in_nonproportional, my_assert_in_proportional; +public: + SplitConstructorAssertedRange(bool assert_in_nonproportional, bool assert_in_proportional) + : is_divisible_called(false), + is_empty_called(false), + my_assert_in_nonproportional(assert_in_nonproportional), + my_assert_in_proportional(assert_in_proportional) { } + SplitConstructorAssertedRange(SplitConstructorAssertedRange& r, tbb::split) { + *this = r; + ASSERT( !my_assert_in_nonproportional, "Disproportional splitting constructor was called but should not been" ); + } + SplitConstructorAssertedRange(SplitConstructorAssertedRange& r, proportional_split&) { + *this = r; + ASSERT( !my_assert_in_proportional, "Proportional splitting constructor was called but should not been" ); + } + bool is_divisible() const { + if (!is_divisible_called) { + is_divisible_called = true; + return true; + } + return false; + } + bool empty() const { + if (!is_empty_called) { + is_empty_called = true; + return false; + } + return true; + } +}; + +/* + * Possible use cases are: + * ------------------------------------------------------------------------------------------------------------- + * Range# is_splittable_in_proportion Range proportional ctor Used partitioner Result Effect + * ------------------------------------------------------------------------------------------------------------- + * 1 true available proportional pMN, r(p), part(p) + * ------------------------------------------------------------------------------------------------------------- + * 2 false available proportional p11, r(p), part(p) + * ------------------------------------------------------------------------------------------------------------- + * 3 not defined available proportional p11, r(p), part(p) + * ------------------------------------------------------------------------------------------------------------- + * 4 true not available proportional pMN, r(s), part(p) * + * ------------------------------------------------------------------------------------------------------------- + * 5 false not available proportional p11, r(s), part(p) + * ------------------------------------------------------------------------------------------------------------- + * 6 not defined not available proportional p11, r(s), part(p) + * ------------------------------------------------------------------------------------------------------------- + * 1 true available simple s, r(s), part(s) + * ------------------------------------------------------------------------------------------------------------- + * 2 false available simple s, r(s), part(s) + * ------------------------------------------------------------------------------------------------------------- + * 3 not defined available simple s, r(s), part(s) + * ------------------------------------------------------------------------------------------------------------- + * 4 true not available simple s, r(s), part(s) + * ------------------------------------------------------------------------------------------------------------- + * 5 false not available simple s, r(s), part(s) + * ------------------------------------------------------------------------------------------------------------- + * 6 not defined not available simple s, r(s), part(s) + * ------------------------------------------------------------------------------------------------------------- + * + * Legend: + * proportional - with proportional splits (e.g. affinity_partitioner) + * simple - without proportional splits (e.g. simple_partitioner, auto_partitioner) + * pMN - proportional_split object with proportion M to N is created. (p11 - proportion 1 to 1) + * s - split object is created + * r(p) - range's proportional split constructor is called + * r(s) - range's ordinary split constructor is called + * part(p) - partitioner's proportional split constructor is called + * part(s) - partitioner's ordinary split constructor is called + * * - incorrect split behavior is possible (e.g. partitioner divides at an arbitrary ratio while + * range divides into halves) + */ + + +// is_splittable_in_proportion = true, proportional_split ctor +class Range1: public SplitConstructorAssertedRange { +public: + Range1(bool assert_in_nonproportional, bool assert_in_proportional) + : SplitConstructorAssertedRange(assert_in_nonproportional, assert_in_proportional) { } + Range1( Range1& r, tbb::split ) : SplitConstructorAssertedRange(r, tbb::split()) { } + Range1( Range1& r, proportional_split& proportion ) : SplitConstructorAssertedRange(r, proportion) { } + static const bool is_splittable_in_proportion = true; +}; + +// is_splittable_in_proportion = false, proportional_split ctor +class Range2: public SplitConstructorAssertedRange { +public: + Range2(bool assert_in_nonproportional, bool assert_in_proportional) + : SplitConstructorAssertedRange(assert_in_nonproportional, assert_in_proportional) { } + Range2(Range2& r, tbb::split) : SplitConstructorAssertedRange(r, tbb::split()) { } + Range2(Range2& r, proportional_split& p) : SplitConstructorAssertedRange(r, p) { + // TODO: add check that 'is_splittable_in_proportion==false' results only in 1:1 proportions + } + static const bool is_splittable_in_proportion = false; +}; + +// is_splittable_in_proportion is not defined, proportional_split ctor +class Range3: public SplitConstructorAssertedRange { +public: + Range3(bool assert_in_nonproportional, bool assert_in_proportional) + : SplitConstructorAssertedRange(assert_in_nonproportional, assert_in_proportional) { } + Range3(Range3& r, tbb::split) : SplitConstructorAssertedRange(r, tbb::split()) { } + Range3(Range3& r, proportional_split& p) : SplitConstructorAssertedRange(r, p) { + // TODO: add check that absence of 'is_splittable_in_proportion' results only in 1:1 proportions + } +}; + +// is_splittable_in_proportion = true, proportional_split ctor is not defined +class Range4: public SplitConstructorAssertedRange { +public: + Range4(bool assert_in_nonproportional, bool assert_in_proportional) + : SplitConstructorAssertedRange(assert_in_nonproportional, assert_in_proportional) { } + Range4(Range4& r, tbb::split) : SplitConstructorAssertedRange(r, tbb::split()) { } + static const bool is_splittable_in_proportion = true; +}; + +// is_splittable_in_proportion = false, proportional_split ctor is not defined +class Range5: public SplitConstructorAssertedRange { +public: + Range5(bool assert_in_nonproportional, bool assert_in_proportional) + : SplitConstructorAssertedRange(assert_in_nonproportional, assert_in_proportional) { } + Range5(Range5& r, tbb::split) : SplitConstructorAssertedRange(r, tbb::split()) { } + static const bool is_splittable_in_proportion = false; +}; + +// is_splittable_in_proportion is not defined, proportional_split ctor is not defined +class Range6: public SplitConstructorAssertedRange { +public: + Range6(bool assert_in_nonproportional, bool assert_in_proportional) + : SplitConstructorAssertedRange(assert_in_nonproportional, assert_in_proportional) { } + Range6(Range6& r, tbb::split) : SplitConstructorAssertedRange(r, tbb::split()) { } +}; + +} // namespace interaction_with_range_and_partitioner + +} // namespace test_partitioner_utils diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner_whitebox.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner_whitebox.cpp new file mode 100644 index 00000000..f8d22bd3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner_whitebox.cpp @@ -0,0 +1,147 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_assert.h" +#include "test_partitioner_whitebox.h" + +using uniform_iterations_distribution::ParallelTestBody; + +template<typename Partitioner> +class ParallelBody: public ParallelTestBody { +public: + ParallelBody(size_t parallel_group_thread_starting_index) + : ParallelTestBody(parallel_group_thread_starting_index) { } + + void operator()(size_t relative_thread_index) const { + use_case_settings_t settings = { + m_parallel_group_thread_starting_index + relative_thread_index, // thread_num + 0, // factors_array_len + 0, // range_begin + false, // provide_feedback (disabled) + true, // ensure_non_empty_size + 0, // above_threads_size_tolerance + 0, // below_threads_size_tolerance + 0, // between_min_max_ranges_tolerance + &ParallelTestBody::uniform_distribution_checker // checker function for a particular test case + }; + g_threadNums.local() = settings.thread_num; + using namespace test_partitioner_utils::TestRanges; + { + size_t factors[] = { 1, 2, 3, 4, 5, 7, 9, 13, 27, 29, 30, 31, 32 }; + settings.factors_array_len = sizeof(factors) / sizeof(factors[0]); + + settings.between_min_max_ranges_tolerance = 0; // it should be equal to zero for blocked_range + test<BlockedRange, Partitioner>(settings, factors); + + settings.checker = &ParallelTestBody::nonuniform_distribution_checker; + test<InvertedProportionRange, Partitioner>(settings, factors); + test<RoundedDownRange, Partitioner>(settings, factors); + test<RoundedUpRange, Partitioner>(settings, factors); + + test<Range1_2, Partitioner>(settings, factors); + test<Range1_999, Partitioner>(settings, factors); + test<Range999_1, Partitioner>(settings, factors); + } + + { + // iterations might not be distributed uniformly + float factors[] = { 1.2f, 2.5f, 3.7f, 4.2f, 5.1f, 8.9f, 27.8f }; + settings.factors_array_len = sizeof(factors) / sizeof(factors[0]); + + settings.between_min_max_ranges_tolerance = 1; // it should be equal to one for blocked_range + settings.checker = &ParallelTestBody::uniform_distribution_checker; + test<BlockedRange, Partitioner>(settings, factors); + + settings.checker = &ParallelTestBody::nonuniform_distribution_checker; + test<InvertedProportionRange, Partitioner>(settings, factors); + test<RoundedDownRange, Partitioner>(settings, factors); + test<RoundedUpRange, Partitioner>(settings, factors); + + test<Range1_2, Partitioner>(settings, factors); + test<Range1_999, Partitioner>(settings, factors); + test<Range999_1, Partitioner>(settings, factors); + } + + { + // iterations might not be distributed uniformly + size_t factors[] = { 1, 2, 3, 4, 5, 7, 9, 11, 13, 27, 29, 30, 31, 32 }; + settings.factors_array_len = sizeof(factors) / sizeof(factors[0]); + + settings.checker = &ParallelTestBody::uniform_distribution_checker; + test<BlockedRange, Partitioner>(settings, factors, &shifted_left_range_size_generator); + test<BlockedRange, Partitioner>(settings, factors, &shifted_right_range_size_generator); + + settings.checker = &ParallelTestBody::nonuniform_distribution_checker; + test<InvertedProportionRange, Partitioner>(settings, factors, &shifted_left_range_size_generator); + test<InvertedProportionRange, Partitioner>(settings, factors, &shifted_right_range_size_generator); + + test<RoundedDownRange, Partitioner>(settings, factors, &shifted_left_range_size_generator); + test<RoundedDownRange, Partitioner>(settings, factors, &shifted_right_range_size_generator); + + test<RoundedUpRange, Partitioner>(settings, factors, &shifted_left_range_size_generator); + test<RoundedUpRange, Partitioner>(settings, factors, &shifted_right_range_size_generator); + + test<Range1_2, Partitioner>(settings, factors, &shifted_left_range_size_generator); + test<Range1_2, Partitioner>(settings, factors, &shifted_right_range_size_generator); + + test<Range1_999, Partitioner>(settings, factors, &shifted_left_range_size_generator); + test<Range1_999, Partitioner>(settings, factors, &shifted_right_range_size_generator); + + test<Range999_1, Partitioner>(settings, factors, &shifted_left_range_size_generator); + test<Range999_1, Partitioner>(settings, factors, &shifted_right_range_size_generator); + } + + { + settings.factors_array_len = 1; + settings.between_min_max_ranges_tolerance = 1; // since range iterations are not divided without remainder + settings.checker = &ParallelTestBody::uniform_distribution_checker; + test<ExactSplitRange, Partitioner, size_t>(settings, NULL, &max_range_size_generator); + settings.range_begin = size_t(-1) - 10000; + test<ExactSplitRange, Partitioner, size_t>(settings, NULL, &max_range_size_generator); + } + + { + settings.range_begin = 0; + settings.factors_array_len = 2 * unsigned(settings.thread_num); + settings.checker = &ParallelTestBody::nonuniform_distribution_checker; + + test<RoundedUpRange, Partitioner, size_t>(settings, NULL, &simple_size_generator); + test<RoundedDownRange, Partitioner, size_t>(settings, NULL, &simple_size_generator); + + test<InvertedProportionRange, Partitioner, size_t>(settings, NULL, &simple_size_generator); + test<Range1_2, Partitioner, size_t>(settings, NULL, &simple_size_generator); + test<Range1_999, Partitioner, size_t>(settings, NULL, &simple_size_generator); + test<Range999_1, Partitioner, size_t>(settings, NULL, &simple_size_generator); + + settings.ensure_non_empty_size = false; + test<RoundedUpRange, Partitioner, size_t>(settings, NULL, &simple_size_generator); + test<RoundedDownRange, Partitioner, size_t>(settings, NULL, &simple_size_generator); + + test<InvertedProportionRange, Partitioner, size_t>(settings, NULL, &simple_size_generator); + test<Range1_2, Partitioner, size_t>(settings, NULL, &simple_size_generator); + test<Range1_999, Partitioner, size_t>(settings, NULL, &simple_size_generator); + test<Range999_1, Partitioner, size_t>(settings, NULL, &simple_size_generator); + } + } +}; + +int TestMain() { + uniform_iterations_distribution::test<ParallelBody <tbb::affinity_partitioner> >(); + uniform_iterations_distribution::test<ParallelBody <tbb::static_partitioner> >(); + uniform_iterations_distribution::test_task_affinity<tbb::affinity_partitioner>(); + uniform_iterations_distribution::test_task_affinity<tbb::static_partitioner>(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner_whitebox.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner_whitebox.h new file mode 100644 index 00000000..fd974fc5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_partitioner_whitebox.h @@ -0,0 +1,468 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* Common part for the partitioner whitebox tests */ + +#include <typeinfo> + +#include "string.h" +#include "harness_assert.h" +#include "test_partitioner.h" +#include <numeric> + +#if TBB_USE_DEBUG +// reducing number of simulations due to test timeout +const size_t max_simulated_threads = 256; +#else +const size_t max_simulated_threads = 640; +#endif + +namespace whitebox_simulation { +size_t whitebox_thread_index = 0; +test_partitioner_utils::BinaryTree reference_tree; +} + +// simulate a subset of task.h +namespace tbb { +namespace internal { +typedef unsigned short affinity_id; +void* internal_current_suspend_point() { return NULL; } +} +class fake_task { +public: + typedef void* suspend_point; + typedef internal::affinity_id affinity_id; + void set_affinity(affinity_id a) { my_affinity = a; } + affinity_id affinity() const { return my_affinity; } + void set_parent(fake_task* p) { my_parent = p; } + fake_task *parent() const { return my_parent; } + bool is_stolen_task() const { return false; } + intptr_t ref_count() const { return 1; } + bool is_cancelled() const { return false; } + static void spawn(fake_task &) {} // for legacy in partitioner.h + virtual fake_task* execute() = 0; // enables dynamic_cast + + fake_task() : my_parent(0), my_affinity(0) {} + virtual ~fake_task() {} +private: + fake_task *my_parent; + affinity_id my_affinity; +}; +namespace task_arena { +static const int not_initialized = -2;//should match corresponding value in task_arena.h +}//namespace task_arena +namespace this_task_arena { +inline int current_thread_index() { return (int)whitebox_simulation::whitebox_thread_index; } +} +}//namespace tbb + +#define __TBB_task_H +#define __TBB_task_arena_H +#define get_initial_auto_partitioner_divisor my_get_initial_auto_partitioner_divisor +#define affinity_partitioner_base_v3 my_affinity_partitioner_base_v3 +#define task fake_task +#include "tbb/tbb_thread.h" +#include "tbb/enumerable_thread_specific.h" +#define __TBB_STATIC_THRESHOLD 0 +#include "tbb/partitioner.h" +#undef __TBB_STATIC_THRESHOLD +#undef task +#undef affinity_partitioner_base_v3 +#undef get_initial_auto_partitioner_divisor + +typedef tbb::enumerable_thread_specific<size_t> ThreadNumsType; +size_t g_threadNumInitialValue = 10; +ThreadNumsType g_threadNums(g_threadNumInitialValue); + +// replace library functions to simulate concurrency +namespace tbb { +namespace internal { +size_t my_get_initial_auto_partitioner_divisor() { + const size_t X_FACTOR = 4; + return X_FACTOR * g_threadNums.local(); +} + +void* __TBB_EXPORTED_FUNC NFS_Allocate( size_t n_element, size_t element_size, void* hint ); +void __TBB_EXPORTED_FUNC NFS_Free( void* ); + +void my_affinity_partitioner_base_v3::resize( unsigned factor ) { + // Check factor to avoid asking for number of workers while there might be no arena. + size_t new_size = factor ? factor * g_threadNums.local() : 0; + if (new_size != my_size) { + if (my_array) { + NFS_Free(my_array); + // Following two assignments must be done here for sake of exception safety. + my_array = NULL; + my_size = 0; + } + if (new_size) { + my_array = static_cast<affinity_id*>(NFS_Allocate(new_size, sizeof(affinity_id), NULL )); + memset(my_array, 0, sizeof(affinity_id) * new_size); + my_size = new_size; + } + } +} + +} //namespace internal +// simulate a subset of parallel_for +namespace interface9 { +namespace internal { + +// parallel_for algorithm that executes sequentially +template<typename Range, typename Body, typename Partitioner> +class start_for : public fake_task { + Range my_range; + Body my_body; + typename Partitioner::task_partition_type my_partition; + size_t m_executedBegin, m_executedEnd; + bool m_firstTimeRun; + size_t m_joinedBegin, m_joinedEnd; + test_partitioner_utils::BinaryTree* m_tree; +public: + start_for( const Range& range, const Body& body, Partitioner& partitioner, + test_partitioner_utils::BinaryTree* tree ) : + my_range(range), my_body(body), my_partition(partitioner), + m_executedBegin(0), m_executedEnd(0), m_firstTimeRun(true), + m_joinedBegin(/* grows left */ range.end()), m_joinedEnd(range.end()), m_tree(tree) + { + if (m_tree) { + m_tree->push_node( test_partitioner_utils::make_node(my_range.begin(), my_range.end(), affinity()) ); + } + } + //! Splitting constructor used to generate children. + /** parent_ becomes left child. Newly constructed object is right child. */ + start_for( start_for& parent_, typename Partitioner::split_type& split_obj) : + my_range(parent_.my_range, split_obj), + my_body(parent_.my_body), + my_partition(parent_.my_partition, split_obj), + m_executedBegin(0), m_executedEnd(0), m_firstTimeRun(true), + m_joinedBegin(/* grows left */ my_range.end()), m_joinedEnd(my_range.end()), + m_tree(parent_.m_tree) + { + set_parent(parent_.parent()); + my_partition.set_affinity(*this); + + if (m_tree) { + // collecting splitting statistics + m_tree->push_node( test_partitioner_utils::make_node(my_range.begin(), + my_range.end(), + affinity()) ); + m_tree->push_node( test_partitioner_utils::make_node(parent_.my_range.begin(), + parent_.my_range.end(), + parent_.affinity()) ); + } + } + //! Construct right child from the given range as response to the demand. + /** parent_ remains left child. Newly constructed object is right child. */ + start_for( start_for& parent_, const Range& r, depth_t d ) : + my_range(r), + my_body(parent_.my_body), + my_partition(parent_.my_partition, tbb::split()), + m_executedBegin(0), m_executedEnd(0), m_firstTimeRun(true), + m_joinedBegin(/* grows left */ r.end()), m_joinedEnd(r.end()), + m_tree(parent_.m_tree) + { + set_parent(parent_.parent()); + my_partition.set_affinity(*this); + my_partition.align_depth( d ); + } + fake_task* execute() __TBB_override { + my_partition.check_being_stolen( *this ); + size_t origBegin = my_range.begin(); + size_t origEnd = my_range.end(); + + my_partition.execute(*this, my_range); + + ASSERT(m_executedEnd == m_joinedBegin, "Non-continuous execution"); + m_executedEnd = m_joinedEnd; + + ASSERT(origBegin == m_executedBegin && origEnd == m_executedEnd, + "Not all iterations were processed"); + return NULL; + } + //! Run body for range, serves as callback for partitioner + void run_body( Range &r ) { + if( r.is_ensure_non_emptiness() ) + ASSERT( !r.empty(), "Empty ranges are not allowed" ); + my_body(r); + if (m_firstTimeRun) { + m_firstTimeRun = false; + m_executedBegin = m_executedEnd = r.begin(); + } + ASSERT(m_executedBegin <= r.begin() && m_executedEnd <= r.end(), + "Non-continuous execution"); + m_executedEnd = r.end(); + } + //! spawn right task, serves as callback for partitioner + void offer_work(typename Partitioner::split_type& split_obj) { + start_for sibling(*this, split_obj); + sibling.execute(); + join(sibling.m_executedBegin, sibling.m_executedEnd); + } + //! spawn right task, serves as callback for partitioner + void offer_work(const Range& r, depth_t d = 0) { + start_for sibling(*this, r, d); + sibling.execute(); + join(sibling.m_executedBegin, sibling.m_executedEnd); + } + void join(size_t siblingExecutedBegin, size_t siblingExecutedEnd) { + ASSERT(siblingExecutedEnd == m_joinedBegin, "?"); + m_joinedBegin = siblingExecutedBegin; + } +}; + +} //namespace internal +} //namespace interfaceX +} //namespace tbb + +namespace whitebox_simulation { +using namespace tbb::interface9::internal; +template<typename Range, typename Body, typename Partitioner> +void parallel_for( const Range& range, const Body& body, Partitioner& partitioner, + test_partitioner_utils::BinaryTree* tree = NULL) { + if (!range.empty()) { + flag_task parent; + start_for<Range, Body, Partitioner> start(range, body, partitioner, tree); + start.set_parent(&parent); + start.execute(); + } +} + +} //namespace whitebox_simulation + +template <typename Range, typename Body, typename Partitioner> +void test_case(Range& range, const Body& body, Partitioner& partitioner, + test_partitioner_utils::BinaryTree* tree = NULL) { + whitebox_simulation::parallel_for(range, body, partitioner, tree); +} + +// Functions generate size for range objects used in tests +template <typename T> +size_t default_range_size_generator(T* factor, unsigned index, size_t thread_num) { + return size_t(factor[index] * thread_num); +} + +size_t shifted_left_range_size_generator(size_t* factor, unsigned index, size_t thread_num) { + return factor[index] * thread_num - 1; +} + +size_t shifted_right_range_size_generator(size_t* factor, unsigned index, size_t thread_num) { + return factor[index] * thread_num + 1; +} + +size_t max_range_size_generator(size_t*, unsigned, size_t) { + return size_t(-1); +} + +size_t simple_size_generator(size_t*, unsigned index, size_t) { + return index; +} + +namespace uniform_iterations_distribution { + +/* + * Test checks uniform distribution of range's iterations among all tasks just after + * work distribution phase has been completed and just before work balancing phase has been started + */ + +using namespace test_partitioner_utils; + +class ParallelTestBody { +public: + struct use_case_settings_t; + + typedef void (*CheckerFuncType)(const char*, size_t, const use_case_settings_t*, const RangeStatisticData&); + + struct use_case_settings_t { + size_t thread_num; // number of threads used during current use case + unsigned factors_array_len; // size of 'factors' array + size_t range_begin; // beginning of range iterations + bool provide_feedback; // 'true' if range should give feedback + bool ensure_non_empty_size; // don't allow empty size ranges + + size_t above_threads_size_tolerance; // allowed value for number of created ranges + // when initial size of the range was greater or + // equal to number of threads + + size_t below_threads_size_tolerance; // allowed value for number of created ranges + // when initial size of the range was less than + // number of threads + + size_t between_min_max_ranges_tolerance; // allowed value for difference of iterations + // between bigger and lesser ranges + + CheckerFuncType checker; // checker function for a particular test case + }; + + ParallelTestBody(size_t parallel_group_thread_starting_index) + : m_parallel_group_thread_starting_index(parallel_group_thread_starting_index) { } + + void operator()(size_t) const { ASSERT( false, "Empty ParallelTestBody called" ); } + + static void uniform_distribution_checker(const char* rangeName, size_t rangeSize, const use_case_settings_t* settings, + const RangeStatisticData& stat) + { + // Checking that all threads were given a task + if (rangeSize >= settings->thread_num) { + uint64_t disparity = + max(stat.m_rangeNum, settings->thread_num) - min(stat.m_rangeNum, settings->thread_num); + if (disparity > settings->above_threads_size_tolerance) { + REPORT("ERROR: '%s (f=%d|e=%d)': |#ranges(%llu)-#threads(%llu)|=%llu > %llu=tolerance\n", + rangeName, int(settings->provide_feedback), int(settings->ensure_non_empty_size), stat.m_rangeNum, + settings->thread_num, disparity, uint64_t(settings->above_threads_size_tolerance)); + ASSERT(disparity <= settings->above_threads_size_tolerance, "Incorrect number of range " + "objects was created before work balancing phase started"); + } + } else if (settings->ensure_non_empty_size && rangeSize != 0) { + uint64_t disparity = max(stat.m_rangeNum, rangeSize) - min(stat.m_rangeNum, rangeSize); + if (disparity > settings->below_threads_size_tolerance ) { + REPORT("ERROR: '%s (f=%d|e=%d)': |#ranges-range size|=%llu > %llu=tolerance\n", + rangeName, int(settings->provide_feedback), int(settings->ensure_non_empty_size), + disparity, uint64_t(settings->below_threads_size_tolerance)); + ASSERT(disparity <= settings->below_threads_size_tolerance, "Incorrect number of range objects" + " was created before work balancing phase started"); + } + } + // Checking difference between min and max number of range iterations + size_t diff = stat.m_maxRangeSize - stat.m_minRangeSize; + if (diff > settings->between_min_max_ranges_tolerance) { + REPORT("ERROR: '%s (f=%d|e=%d)': range size difference=%llu > %llu=tolerance\n", + rangeName, int(settings->provide_feedback), int(settings->ensure_non_empty_size), + uint64_t(diff), uint64_t(settings->between_min_max_ranges_tolerance)); + ASSERT(diff <= settings->between_min_max_ranges_tolerance, "Uniform iteration distribution error"); + } + } + // Checker for test cases where ranges don't provide feedback during proportional split to + // partitioner and differ from tbb::blocked_range implementation in their splitting algorithm + static void nonuniform_distribution_checker(const char* rangeName, size_t rangeSize, const use_case_settings_t* settings, + const RangeStatisticData& stat) + { + if (stat.m_rangeNum > settings->thread_num) { + REPORT("ERROR: '%s (f=%d|e=%d)': %llu=#ranges > #threads=%llu\n", + rangeName, int(settings->provide_feedback), int(settings->ensure_non_empty_size), + uint64_t(stat.m_rangeNum), uint64_t(settings->thread_num)); + ASSERT(stat.m_rangeNum <= settings->thread_num, + "Incorrect number of range objects was created before work balancing phase started"); + } + // Checking difference between min and max number of range iterations + size_t diff = stat.m_maxRangeSize - stat.m_minRangeSize; + if (diff > rangeSize) { + REPORT("ERROR: '%s (f=%d|e=%d)': range size difference=%llu > %llu=initial range size\n", + rangeName, int(settings->provide_feedback), int(settings->ensure_non_empty_size), + uint64_t(diff), uint64_t(rangeSize)); + ASSERT(diff <= rangeSize, "Iteration distribution error"); + } + } + +protected: + size_t m_parallel_group_thread_starting_index; // starting index of thread + + template <typename Range, typename Partitioner, typename T> + void test(use_case_settings_t& settings, T factors[], size_t (*rsgFunc)(T*, unsigned, size_t) + = &default_range_size_generator<T>) const + { + for (unsigned i = 0; i < settings.factors_array_len; ++i) { + size_t range_end = rsgFunc(factors, i, settings.thread_num); + RangeStatisticData stat = { /*range num=*/ 0, /*minimal size of range=*/ 0, + /*maximal size of range=*/ 0, /*minimal size of range was not rewritten yet=*/ false }; + Range range = Range(settings.range_begin, range_end, &stat, settings.provide_feedback, + settings.ensure_non_empty_size); + Partitioner my_partitioner; + test_case(range, SimpleBody(), my_partitioner, NULL); + size_t range_size = range_end - settings.range_begin; + const char* rangeName = typeid(range).name(); + settings.checker(rangeName, range_size, &settings, stat); + } + } +}; + +template <typename ParallelTestBody> +void test() { + size_t hw_threads_num = tbb::tbb_thread::hardware_concurrency(); + size_t threadsToRunOn = std::min<size_t>(max_simulated_threads, hw_threads_num); + + size_t parallel_group_thread_starting_index = 1; + while( parallel_group_thread_starting_index <= max_simulated_threads - threadsToRunOn ) { + NativeParallelFor(threadsToRunOn, ParallelTestBody(parallel_group_thread_starting_index)); + parallel_group_thread_starting_index += threadsToRunOn; + } + NativeParallelFor(max_simulated_threads - parallel_group_thread_starting_index, + ParallelTestBody(parallel_group_thread_starting_index)); +} + +namespace task_affinity_whitebox { +size_t range_begin = 0; +size_t range_end = 20; +} + +template<typename Partitioner> +void check_tree(const test_partitioner_utils::BinaryTree&); + +template<> +void check_tree<tbb::affinity_partitioner>(const test_partitioner_utils::BinaryTree& tree) { + ASSERT(tree == whitebox_simulation::reference_tree, + "affinity_partitioner distributes tasks differently from run to run"); +} + +template<> +void check_tree<tbb::static_partitioner>(const test_partitioner_utils::BinaryTree& tree) { + std::vector<test_partitioner_utils::TreeNode* > tree_leafs; + tree.fill_leafs(tree_leafs); + typedef std::vector<size_t> Slots; + Slots affinity_slots(tree_leafs.size() + 1, 0); + + for (std::vector<test_partitioner_utils::TreeNode*>::iterator i = tree_leafs.begin(); i != tree_leafs.end(); ++i) { + affinity_slots[(*i)->m_affinity]++; + if ((*i)->m_affinity == 0) + ASSERT((*i)->m_range_begin == task_affinity_whitebox::range_begin, + "Task with affinity 0 was executed with wrong range"); + } + + typedef std::iterator_traits<Slots::iterator>::difference_type slots_difference_type; + ASSERT(std::count(affinity_slots.begin(), affinity_slots.end(), size_t(0)) == slots_difference_type(1), + "static_partitioner incorrectly distributed tasks by threads"); + ASSERT(std::count(affinity_slots.begin(), affinity_slots.end(), size_t(1)) == slots_difference_type(g_threadNums.local()), + "static_partitioner incorrectly distributed tasks by threads"); + ASSERT(affinity_slots[tbb::this_task_arena::current_thread_index() + 1] == 0, + "static_partitioner incorrectly assigns task with 0 affinity"); + ASSERT(std::accumulate(affinity_slots.begin(), affinity_slots.end(), size_t(0)) == g_threadNums.local(), + "static_partitioner has created more tasks than the number of threads"); +} + +template<typename Partitioner> +void test_task_affinity() { + using namespace task_affinity_whitebox; + test_partitioner_utils::SimpleBody body; + for (size_t p = 1; p <= 50; ++p) { + g_threadNums.local() = p; + whitebox_simulation::whitebox_thread_index = 0; + test_partitioner_utils::TestRanges::BlockedRange range(range_begin, range_end, /*statData*/NULL, + /*provide_feedback*/false, /*ensure_non_empty_size*/false); + Partitioner partitioner; + whitebox_simulation::reference_tree = test_partitioner_utils::BinaryTree(); + whitebox_simulation::parallel_for(range, body, partitioner, &(whitebox_simulation::reference_tree)); + while (whitebox_simulation::whitebox_thread_index < p) { + test_partitioner_utils::BinaryTree tree; + whitebox_simulation::parallel_for(range, body, partitioner, &tree); + check_tree<Partitioner>(tree); + whitebox_simulation::whitebox_thread_index++; + } + range_begin++; + range_end += 2; + } +} + +} /* namespace uniform_iterations_distribution */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_pipeline.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_pipeline.cpp new file mode 100644 index 00000000..87ace55e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_pipeline.cpp @@ -0,0 +1,309 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_stddef.h" +#include "tbb/pipeline.h" +#include "tbb/spin_mutex.h" +#include "tbb/atomic.h" +#include <cstdlib> +#include <cstdio> +#include "harness.h" + +// In the test, variables related to token counting are declared +// as unsigned long to match definition of tbb::internal::Token. + +struct Buffer { + //! Indicates that the buffer is not used. + static const unsigned long unused = ~0ul; + unsigned long id; + //! True if Buffer is in use. + bool is_busy; + unsigned long sequence_number; + Buffer() : id(unused), is_busy(false), sequence_number(unused) {} +}; + +class waiting_probe { + size_t check_counter; +public: + waiting_probe() : check_counter(0) {} + bool required( ) { + ++check_counter; + return !((check_counter+1)&size_t(0x7FFF)); + } + void probe( ); // defined below +}; + +static const unsigned MaxStreamSize = 8000; +static const unsigned MaxStreamItemsPerThread = 1000; +//! Maximum number of filters allowed +static const unsigned MaxFilters = 5; +static unsigned StreamSize; +static const unsigned MaxBuffer = 8; +static bool Done[MaxFilters][MaxStreamSize]; +static waiting_probe WaitTest; +static unsigned out_of_order_count; + +#include "harness_concurrency_tracker.h" + +class BaseFilter: public tbb::filter { + bool* const my_done; + const bool my_is_last; + bool my_is_running; +public: + tbb::atomic<tbb::internal::Token> current_token; + BaseFilter( tbb::filter::mode type, bool done[], bool is_last ) : + filter(type), + my_done(done), + my_is_last(is_last), + my_is_running(false), + current_token() + {} + virtual Buffer* get_buffer( void* item ) { + current_token++; + return static_cast<Buffer*>(item); + } + void* operator()( void* item ) __TBB_override { + Harness::ConcurrencyTracker ct; + if( is_serial() ) + ASSERT( !my_is_running, "premature entry to serial stage" ); + my_is_running = true; + Buffer* b = get_buffer(item); + if( b ) { + if( is_ordered() ) { + if( b->sequence_number == Buffer::unused ) + b->sequence_number = current_token-1; + else + ASSERT( b->sequence_number==current_token-1, "item arrived out of order" ); + } else if( is_serial() ) { + if( b->sequence_number != current_token-1 && b->sequence_number != Buffer::unused ) + out_of_order_count++; + } + ASSERT( b->id < StreamSize, NULL ); + ASSERT( !my_done[b->id], "duplicate processing of token?" ); + ASSERT( b->is_busy, NULL ); + my_done[b->id] = true; + if( my_is_last ) { + b->id = Buffer::unused; + b->sequence_number = Buffer::unused; + __TBB_store_with_release(b->is_busy, false); + } + } + my_is_running = false; + return b; + } +}; + +class InputFilter: public BaseFilter { + tbb::spin_mutex input_lock; + Buffer buffer[MaxBuffer]; + const tbb::internal::Token my_number_of_tokens; +public: + InputFilter( tbb::filter::mode type, tbb::internal::Token ntokens, bool done[], bool is_last ) : + BaseFilter(type, done, is_last), + my_number_of_tokens(ntokens) + {} + Buffer* get_buffer( void* ) __TBB_override { + unsigned long next_input; + unsigned free_buffer = 0; + { // lock protected scope + tbb::spin_mutex::scoped_lock lock(input_lock); + if( current_token>=StreamSize ) + return NULL; + next_input = current_token++; + // once in a while, emulate waiting for input; this only makes sense for serial input + if( is_serial() && WaitTest.required() ) + WaitTest.probe( ); + while( free_buffer<MaxBuffer ) + if( __TBB_load_with_acquire(buffer[free_buffer].is_busy) ) + ++free_buffer; + else { + buffer[free_buffer].is_busy = true; + break; + } + } + ASSERT( free_buffer<my_number_of_tokens, "premature reuse of buffer" ); + Buffer* b = &buffer[free_buffer]; + ASSERT( &buffer[0] <= b, NULL ); + ASSERT( b <= &buffer[MaxBuffer-1], NULL ); + ASSERT( b->id == Buffer::unused, NULL); + b->id = next_input; + ASSERT( b->sequence_number == Buffer::unused, NULL); + return b; + } +}; + +//! The struct below repeats layout of tbb::pipeline. +struct hacked_pipeline { + tbb::filter* filter_list; + tbb::filter* filter_end; + tbb::empty_task* end_counter; + tbb::atomic<tbb::internal::Token> input_tokens; + tbb::atomic<tbb::internal::Token> token_counter; + bool end_of_input; + bool has_thread_bound_filters; + + virtual ~hacked_pipeline(); +}; + +//! The struct below repeats layout of tbb::internal::input_buffer. +struct hacked_input_buffer { + void* array; // This should be changed to task_info* if ever used + void* my_sem; // This should be changed to semaphore* if ever used + tbb::internal::Token array_size; + tbb::internal::Token low_token; + tbb::spin_mutex array_mutex; + tbb::internal::Token high_token; + bool is_ordered; + bool is_bound; +}; + +//! The struct below repeats layout of tbb::filter. +struct hacked_filter { + tbb::filter* next_filter_in_pipeline; + hacked_input_buffer* my_input_buffer; + unsigned char my_filter_mode; + tbb::filter* prev_filter_in_pipeline; + tbb::pipeline* my_pipeline; + tbb::filter* next_segment; + + virtual ~hacked_filter(); +}; + +bool do_hacking_tests = true; +const tbb::internal::Token tokens_before_wraparound = 0xF; + +void TestTrivialPipeline( unsigned nthread, unsigned number_of_filters ) { + // There are 3 filter types: parallel, serial_in_order and serial_out_of_order + static const tbb::filter::mode filter_table[] = { tbb::filter::parallel, tbb::filter::serial_in_order, tbb::filter::serial_out_of_order}; + const unsigned number_of_filter_types = sizeof(filter_table)/sizeof(filter_table[0]); + REMARK( "testing with %lu threads and %lu filters\n", nthread, number_of_filters ); + ASSERT( number_of_filters<=MaxFilters, "too many filters" ); + ASSERT( sizeof(hacked_pipeline) == sizeof(tbb::pipeline), "layout changed for tbb::pipeline?" ); + ASSERT( sizeof(hacked_filter) == sizeof(tbb::filter), "layout changed for tbb::filter?" ); + tbb::internal::Token ntokens = nthread<MaxBuffer ? nthread : MaxBuffer; + // Count maximum iterations number + unsigned limit = 1; + for( unsigned i=0; i<number_of_filters; ++i) + limit *= number_of_filter_types; + // Iterate over possible filter sequences + for( unsigned numeral=0; numeral<limit; ++numeral ) { + // Build pipeline + tbb::pipeline pipeline; + if( do_hacking_tests ) { + // A private member of pipeline is hacked there for sake of testing wrap-around immunity. + tbb::internal::punned_cast<hacked_pipeline*>(&pipeline)->token_counter = ~tokens_before_wraparound; + } + tbb::filter* filter[MaxFilters]; + unsigned temp = numeral; + // parallelism_limit is the upper bound on the possible parallelism + unsigned parallelism_limit = 0; + for( unsigned i=0; i<number_of_filters; ++i, temp/=number_of_filter_types ) { + tbb::filter::mode filter_type = filter_table[temp%number_of_filter_types]; + const bool is_last = i==number_of_filters-1; + if( i==0 ) + filter[i] = new InputFilter(filter_type,ntokens,Done[i],is_last); + else + filter[i] = new BaseFilter(filter_type,Done[i],is_last); + pipeline.add_filter(*filter[i]); + // The ordered buffer of serial filters is hacked as well. + if ( filter[i]->is_serial() ) { + if( do_hacking_tests ) { + ((hacked_filter*)(void*)filter[i])->my_input_buffer->low_token = ~tokens_before_wraparound; + ((hacked_filter*)(void*)filter[i])->my_input_buffer->high_token = ~tokens_before_wraparound; + } + parallelism_limit += 1; + } else { + parallelism_limit = nthread; + } + } + // Account for clipping of parallelism. + if( parallelism_limit>nthread ) + parallelism_limit = nthread; + if( parallelism_limit>ntokens ) + parallelism_limit = (unsigned)ntokens; + Harness::ConcurrencyTracker::Reset(); + unsigned streamSizeLimit = min( MaxStreamSize, nthread * MaxStreamItemsPerThread ); + for( StreamSize=0; StreamSize<=streamSizeLimit; ) { + memset( Done, 0, sizeof(Done) ); + for( unsigned i=0; i<number_of_filters; ++i ) { + static_cast<BaseFilter*>(filter[i])->current_token=0; + } + pipeline.run( ntokens ); + ASSERT( !Harness::ConcurrencyTracker::InstantParallelism(), "filter still running?" ); + for( unsigned i=0; i<number_of_filters; ++i ) + ASSERT( static_cast<BaseFilter*>(filter[i])->current_token==StreamSize, NULL ); + for( unsigned i=0; i<MaxFilters; ++i ) + for( unsigned j=0; j<StreamSize; ++j ) { + ASSERT( Done[i][j]==(i<number_of_filters), NULL ); + } + if( StreamSize < min(nthread*8, 32u) ) { + ++StreamSize; + } else { + StreamSize = StreamSize*8/3; + } + } + if( Harness::ConcurrencyTracker::PeakParallelism() < parallelism_limit ) + REMARK( "nthread=%lu ntokens=%lu MaxParallelism=%lu parallelism_limit=%lu\n", + nthread, ntokens, Harness::ConcurrencyTracker::PeakParallelism(), parallelism_limit ); + for( unsigned i=0; i < number_of_filters; ++i ) { + delete filter[i]; + filter[i] = NULL; + } + pipeline.clear(); + } +} + +#include "harness_cpu.h" + +static int nthread; // knowing number of threads is necessary to call TestCPUUserTime + +void waiting_probe::probe( ) { + if( nthread==1 ) return; + REMARK("emulating wait for input\n"); + // Test that threads sleep while no work. + // The master doesn't sleep so there could be 2 active threads if a worker is waiting for input + TestCPUUserTime(nthread, 2); +} + +#include "tbb/task_scheduler_init.h" + +int TestMain () { + out_of_order_count = 0; + if( MinThread<1 ) { + REPORT("must have at least one thread"); + exit(1); + } + if( tbb::TBB_runtime_interface_version()>TBB_INTERFACE_VERSION) { + REMARK("Warning: implementation dependent tests disabled\n"); + do_hacking_tests = false; + } + + // Test with varying number of threads. + for( nthread=MinThread; nthread<=MaxThread; ++nthread ) { + // Initialize TBB task scheduler + tbb::task_scheduler_init init(nthread); + + // Test pipelines with n filters + for( unsigned n=0; n<=MaxFilters; ++n ) + TestTrivialPipeline(nthread,n); + + // Test that all workers sleep when no work + TestCPUUserTime(nthread); + } + if( !out_of_order_count ) + REPORT("Warning: out of order serial filter received tokens in order\n"); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_pipeline_with_tbf.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_pipeline_with_tbf.cpp new file mode 100644 index 00000000..d462b00a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_pipeline_with_tbf.cpp @@ -0,0 +1,528 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/pipeline.h" +#include "tbb/spin_mutex.h" +#include "tbb/atomic.h" +#include "tbb/tbb_thread.h" +#include <cstdlib> +#include <cstdio> +#include "harness.h" + +// In the test, variables related to token counting are declared +// as unsigned long to match definition of tbb::internal::Token. + +//! Id of thread that first executes work on non-thread-bound stages +tbb::tbb_thread::id thread_id; +//! Zero thread id +tbb::tbb_thread::id id0; +//! True if non-thread-bound stages must be executed on one thread +bool is_serial_execution; +double sleeptime; // how long is a non-thread-bound stage to sleep? + +struct Buffer { + //! Indicates that the buffer is not used. + static const unsigned long unused = ~0ul; + unsigned long id; + //! True if Buffer is in use. + bool is_busy; + unsigned long sequence_number; + Buffer() : id(unused), is_busy(false), sequence_number(unused) {} +}; + +class waiting_probe { + size_t check_counter; +public: + waiting_probe() : check_counter(0) {} + bool required( ) { + ++check_counter; + return !((check_counter+1)&size_t(0x7FFF)); + } + void probe( ); // defined below +}; + +static const unsigned StreamSize = 10; +//! Maximum number of filters allowed +static const unsigned MaxFilters = 4; +static const unsigned MaxBuffer = 8; +static bool Done[MaxFilters][StreamSize]; +static waiting_probe WaitTest; +static unsigned out_of_order_count; + +#include "harness_concurrency_tracker.h" + +template<typename T> +class BaseFilter: public T { + bool* const my_done; + const bool my_is_last; + bool concurrency_observed; + tbb::atomic<int> running_count; +public: + tbb::atomic<tbb::internal::Token> current_token; + BaseFilter( tbb::filter::mode type, bool done[], bool is_last ) : + T(type), + my_done(done), + my_is_last(is_last), + concurrency_observed(false), + current_token() + { + running_count = 0; + } + ~BaseFilter() { + if( this->is_serial() || is_serial_execution ) + ASSERT( !concurrency_observed, "Unexpected concurrency in a [serial] filter" ); + else if( sleeptime > 0 ) + ASSERT( concurrency_observed, "No concurrency in a parallel filter" ); + } + virtual Buffer* get_buffer( void* item ) { + current_token++; + return static_cast<Buffer*>(item); + } + void* operator()( void* item ) __TBB_override { + // Check if work is done only on one thread when ntokens==1 or + // when pipeline has only one filter that is serial and non-thread-bound + if( is_serial_execution && !this->is_bound() ) { + // Get id of current thread + tbb::tbb_thread::id id = tbb::this_tbb_thread::get_id(); + // At first execution, set thread_id to current thread id. + // Serialized execution is expected, so there should be no race. + if( thread_id == id0 ) + thread_id = id; + // Check if work is done on one thread + ASSERT( thread_id == id, "non-thread-bound stages executed on different threads when must be executed on a single one"); + } + Harness::ConcurrencyTracker ct; + concurrency_observed = concurrency_observed || (running_count++ > 0); + if( this->is_serial() ) + ASSERT( !concurrency_observed, "premature entry to serial stage" ); + + Buffer* b = get_buffer(item); + if( b ) { + if(!this->is_bound() && sleeptime > 0) { + if(this->is_serial()) { + Harness::Sleep((int)sleeptime); + } else { + // early parallel tokens sleep longer + int i = (int)((5 - (int)b->sequence_number) * sleeptime); + if(i < (int)sleeptime) i = (int)sleeptime; + Harness::Sleep(i); + } + } + if( this->is_ordered() ) { + if( b->sequence_number == Buffer::unused ) + b->sequence_number = current_token-1; + else + ASSERT( b->sequence_number==current_token-1, "item arrived out of order" ); + } else if( this->is_serial() ) { + if( b->sequence_number != current_token-1 && b->sequence_number != Buffer::unused ) + out_of_order_count++; + } + ASSERT( b->id < StreamSize, NULL ); + ASSERT( !my_done[b->id], "duplicate processing of token?" ); + ASSERT( b->is_busy, NULL ); + my_done[b->id] = true; + if( my_is_last ) { + b->id = Buffer::unused; + b->sequence_number = Buffer::unused; + __TBB_store_with_release(b->is_busy, false); + } + } + concurrency_observed = concurrency_observed || (--running_count > 0); + return b; + } +}; + +template<typename T> +class InputFilter: public BaseFilter<T> { + tbb::spin_mutex input_lock; + Buffer buffer[MaxBuffer]; + const tbb::internal::Token my_number_of_tokens; +public: + InputFilter( tbb::filter::mode type, tbb::internal::Token ntokens, bool done[], bool is_last ) : + BaseFilter<T>(type, done, is_last), + my_number_of_tokens(ntokens) + {} + Buffer* get_buffer( void* ) __TBB_override { + unsigned long next_input; + unsigned free_buffer = 0; + { // lock protected scope + tbb::spin_mutex::scoped_lock lock(input_lock); + if( this->current_token>=StreamSize ) + return NULL; + next_input = this->current_token++; + // once in a while, emulate waiting for input; this only makes sense for serial input + if( this->is_serial() && WaitTest.required() ) + WaitTest.probe( ); + while( free_buffer<MaxBuffer ) + if( __TBB_load_with_acquire(buffer[free_buffer].is_busy) ) + ++free_buffer; + else { + buffer[free_buffer].is_busy = true; + break; + } + } + ASSERT( free_buffer<my_number_of_tokens, "premature reuse of buffer" ); + Buffer* b = &buffer[free_buffer]; + ASSERT( &buffer[0] <= b, NULL ); + ASSERT( b <= &buffer[MaxBuffer-1], NULL ); + ASSERT( b->id == Buffer::unused, NULL); + b->id = next_input; + ASSERT( b->sequence_number == Buffer::unused, NULL); + return b; + } +}; + +class process_loop { +public: + void operator()( tbb::thread_bound_filter* tbf ) { + tbb::thread_bound_filter::result_type flag; + do + flag = tbf->process_item(); + while( flag != tbb::thread_bound_filter::end_of_stream ); + } +}; + +//! The struct below repeats layout of tbb::pipeline. +struct hacked_pipeline { + tbb::filter* filter_list; + tbb::filter* filter_end; + tbb::empty_task* end_counter; + tbb::atomic<tbb::internal::Token> input_tokens; + tbb::atomic<tbb::internal::Token> global_token_counter; + bool end_of_input; + bool has_thread_bound_filters; + + virtual ~hacked_pipeline(); +}; + +//! The struct below repeats layout of tbb::internal::ordered_buffer. +struct hacked_ordered_buffer { + void* array; // This should be changed to task_info* if ever used + tbb::internal::Token array_size; + tbb::internal::Token low_token; + tbb::spin_mutex array_mutex; + tbb::internal::Token high_token; + bool is_ordered; + bool is_bound; +}; + +//! The struct below repeats layout of tbb::filter. +struct hacked_filter { + tbb::filter* next_filter_in_pipeline; + hacked_ordered_buffer* input_buffer; + unsigned char my_filter_mode; + tbb::filter* prev_filter_in_pipeline; + tbb::pipeline* my_pipeline; + tbb::filter* next_segment; + + virtual ~hacked_filter(); +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for overzealous compiler warnings + // Suppress compiler warning about constant conditional expression + #pragma warning (disable: 4127) +#endif + +void clear_global_state() { + Harness::ConcurrencyTracker::Reset(); + memset( Done, 0, sizeof(Done) ); + thread_id = id0; + is_serial_execution = false; +} + + +class PipelineTest { + // There are 3 non-thread-bound filter types: serial_in_order and serial_out_of_order, parallel + static const tbb::filter::mode non_tb_filters_table[3]; // = { tbb::filter::serial_in_order, tbb::filter::serial_out_of_order, tbb::filter::parallel}; + // There are 2 thread-bound filter types: serial_in_order and serial_out_of_order + static const tbb::filter::mode tb_filters_table[2]; // = { tbb::filter::serial_in_order, tbb::filter::serial_out_of_order }; + + static const unsigned number_of_non_tb_filter_types = sizeof(non_tb_filters_table)/sizeof(non_tb_filters_table[0]); + static const unsigned number_of_tb_filter_types = sizeof(tb_filters_table)/sizeof(tb_filters_table[0]); + static const unsigned number_of_filter_types = number_of_non_tb_filter_types + number_of_tb_filter_types; + // static unsigned my_nthread; + public: + static double TestOneConfiguration( unsigned numeral, unsigned nthread, unsigned number_of_filters, tbb::internal::Token ntokens); + static void TestTrivialPipeline( unsigned nthread, unsigned number_of_filters ); + static void TestIdleSpinning(unsigned nthread); + + static void PrintConfiguration(unsigned numeral, unsigned nFilters) { + REMARK( "{ "); + for( unsigned i = 0; i < nFilters; ++i) { + switch( numeral % number_of_filter_types ) { + case 0: REMARK("s "); break; + case 1: REMARK("B "); break; + case 2: REMARK("o "); break; + case 3: REMARK("Bo "); break; + case 4: REMARK("P "); break; + default: REMARK(" ** ERROR** "); break; + } + numeral /= number_of_filter_types; + } + REMARK("}"); + } + static bool ContainsBoundFilter(unsigned numeral) { + for( ;numeral != 0; numeral /= number_of_filter_types) + if(numeral & 0x1) return true; + return false; + } +}; + +const tbb::filter::mode PipelineTest::non_tb_filters_table[3] = { + tbb::filter::serial_in_order, // 0 + tbb::filter::serial_out_of_order, // 2 + tbb::filter::parallel // 4 +}; +const tbb::filter::mode PipelineTest::tb_filters_table[2] = { + tbb::filter::serial_in_order, // 1 + tbb::filter::serial_out_of_order // 3 +}; + +#include "harness_cpu.h" + +double PipelineTest::TestOneConfiguration(unsigned numeral, unsigned nthread, unsigned number_of_filters, tbb::internal::Token ntokens) +{ + // Build pipeline + tbb::pipeline pipeline; + tbb::filter* filter[MaxFilters]; + unsigned temp = numeral; + // parallelism_limit is the upper bound on the possible parallelism + unsigned parallelism_limit = 0; + // number of thread-bound-filters in the current sequence + unsigned number_of_tb_filters = 0; + // ordinal numbers of thread-bound-filters in the current sequence + unsigned array_of_tb_filter_numbers[MaxFilters]; + if(!ContainsBoundFilter(numeral)) return 0.0; + for( unsigned i=0; i<number_of_filters; ++i, temp/=number_of_filter_types ) { + bool is_bound = temp%number_of_filter_types&0x1; + tbb::filter::mode filter_type; + if( is_bound ) { + filter_type = tb_filters_table[temp%number_of_filter_types/number_of_non_tb_filter_types]; + } else + filter_type = non_tb_filters_table[temp%number_of_filter_types/number_of_tb_filter_types]; + const bool is_last = i==number_of_filters-1; + if( is_bound ) { + if( i == 0 ) + filter[i] = new InputFilter<tbb::thread_bound_filter>(filter_type,ntokens,Done[i],is_last); + else + filter[i] = new BaseFilter<tbb::thread_bound_filter>(filter_type,Done[i],is_last); + array_of_tb_filter_numbers[number_of_tb_filters] = i; + number_of_tb_filters++; + } else { + if( i == 0 ) + filter[i] = new InputFilter<tbb::filter>(filter_type,ntokens,Done[i],is_last); + else + filter[i] = new BaseFilter<tbb::filter>(filter_type,Done[i],is_last); + } + pipeline.add_filter(*filter[i]); + if ( filter[i]->is_serial() ) { + parallelism_limit += 1; + } else { + parallelism_limit = nthread; + } + } + ASSERT(number_of_tb_filters,NULL); + clear_global_state(); + // Account for clipping of parallelism. + if( parallelism_limit>nthread ) + parallelism_limit = nthread; + if( parallelism_limit>ntokens ) + parallelism_limit = (unsigned)ntokens; + + for( unsigned i=0; i<number_of_filters; ++i ) { + static_cast<BaseFilter<tbb::filter>*>(filter[i])->current_token=0; + } + tbb::tbb_thread* t[MaxFilters]; + for( unsigned j = 0; j<number_of_tb_filters; j++) + t[j] = new tbb::tbb_thread(process_loop(), static_cast<tbb::thread_bound_filter*>(filter[array_of_tb_filter_numbers[j]])); + if( ntokens == 1 || ( number_of_filters == 1 && number_of_tb_filters == 0 && filter[0]->is_serial() )) + is_serial_execution = true; + double strttime = GetCPUUserTime(); + pipeline.run( ntokens ); + double endtime = GetCPUUserTime(); + for( unsigned j = 0; j<number_of_tb_filters; j++) + t[j]->join(); + ASSERT( !Harness::ConcurrencyTracker::InstantParallelism(), "filter still running?" ); + for( unsigned i=0; i<number_of_filters; ++i ) + ASSERT( static_cast<BaseFilter<tbb::filter>*>(filter[i])->current_token==StreamSize, NULL ); + for( unsigned i=0; i<MaxFilters; ++i ) + for( unsigned j=0; j<StreamSize; ++j ) { + ASSERT( Done[i][j]==(i<number_of_filters), NULL ); + } + if( Harness::ConcurrencyTracker::PeakParallelism() < parallelism_limit ) + REMARK( "nthread=%lu ntokens=%lu MaxParallelism=%lu parallelism_limit=%lu\n", + nthread, ntokens, Harness::ConcurrencyTracker::PeakParallelism(), parallelism_limit ); + for( unsigned i=0; i < number_of_filters; ++i ) { + delete filter[i]; + filter[i] = NULL; + } + for( unsigned j = 0; j<number_of_tb_filters; j++) + delete t[j]; + pipeline.clear(); + return endtime - strttime; +} // TestOneConfiguration + +void PipelineTest::TestTrivialPipeline( unsigned nthread, unsigned number_of_filters ) { + + REMARK( "testing with %lu threads and %lu filters\n", nthread, number_of_filters ); + ASSERT( number_of_filters<=MaxFilters, "too many filters" ); + tbb::internal::Token max_tokens = nthread < MaxBuffer ? nthread : MaxBuffer; + // The loop has 1 iteration if max_tokens=1 and 2 iterations if max_tokens>1: + // one iteration for ntokens=1 and second for ntokens=max_tokens + // Iteration for ntokens=1 is required in each test case to check if pipeline run only on one thread + unsigned max_iteration = max_tokens > 1 ? 2 : 1; + tbb::internal::Token ntokens = 1; + for( unsigned iteration = 0; iteration < max_iteration; iteration++) { + if( iteration > 0 ) + ntokens = max_tokens; + // Count maximum iterations number + unsigned limit = 1; + for( unsigned i=0; i<number_of_filters; ++i) + limit *= number_of_filter_types; + // Iterate over possible filter sequences + for( unsigned numeral=0; numeral<limit; ++numeral ) { + REMARK( "testing configuration %lu of %lu\n", numeral, limit ); + (void)TestOneConfiguration(numeral, nthread, number_of_filters, ntokens); + } + } +} + +// varying times for sleep result in different user times for all pipelines. +// So we compare the running time of an all non-TBF pipeline with different (with +// luck representative) TBF configurations. +// +// We run the tests multiple times and compare the average runtimes for those cases +// that don't return 0 user time. configurations that exceed the allowable extra +// time are reported. +void PipelineTest::TestIdleSpinning( unsigned nthread) { + unsigned sample_setups[] = { + // in the comments below, s == serial, o == serial out-of-order, + // B == thread bound, Bo == thread bound out-of-order, p == parallel + 1, // B s s s + 5, // s B s s + 25, // s s B s + 125, // s s s B + 6, // B B s s + 26, // B s B s + 126, // B s s B + 30, // s B B s + 130, // s B s B + 150, // s s B B + 31, // B B B s + 131, // B B s B + 155, // s B B B + 495, // s p p Bo + 71, // B p o s + 355, // s B p o + 95, // s p Bo s + 475, // s s p Bo + }; + const int nsetups = sizeof(sample_setups) / sizeof(unsigned); + const int ntests = 4; + const double bignum = 1000000000.0; + const double allowable_slowdown = 3.5; + unsigned zero_count = 0; + + REMARK( "testing idle spinning with %lu threads\n", nthread ); + tbb::internal::Token max_tokens = nthread < MaxBuffer ? nthread : MaxBuffer; + for( int i=0; i<nsetups; ++i ) { + unsigned numeral = sample_setups[i]; + unsigned temp = numeral; + unsigned nbound = 0; + while(temp) { + if((temp%number_of_filter_types)&0x01) nbound++; + temp /= number_of_filter_types; + } + sleeptime = 20.0; + double s0 = bignum; + double s1 = bignum; + int v0cnt = 0; + int v1cnt = 0; + double s0sum = 0.0; + double s1sum = 0.0; + REMARK(" TestOneConfiguration, pipeline == "); + PrintConfiguration(numeral, MaxFilters); + REMARK(", max_tokens== %d\n", (int)max_tokens); + for(int j = 0; j < ntests; ++j) { + double s1a = TestOneConfiguration(numeral, nthread, MaxFilters, max_tokens); + double s0a = TestOneConfiguration((unsigned)0, nthread, MaxFilters, max_tokens); + s1sum += s1a; + s0sum += s0a; + if(s0a > 0.0) { + ++v0cnt; + s0 = (s0a < s0) ? s0a : s0; + } else { + ++zero_count; + } + if(s1a > 0.0) { + ++v1cnt; + s1 = (s1a < s1) ? s1a : s1; + } else { + ++zero_count; + } + } + if(s0 == bignum || s1 == bignum) continue; + s0sum /= (double)v0cnt; + s1sum /= (double)v1cnt; + double slowdown = (s1sum-s0sum)/s0sum; + if(slowdown > allowable_slowdown) + REMARK( "with %lu threads configuration %lu has slowdown > %g (%g)\n", nthread, numeral, allowable_slowdown, slowdown ); + } + REMARK("Total of %lu zero times\n", zero_count); +} + +static int nthread; // knowing number of threads is necessary to call TestCPUUserTime + +void waiting_probe::probe( ) { + if( nthread==1 ) return; + REMARK("emulating wait for input\n"); + // Test that threads sleep while no work. + // The master doesn't sleep so there could be 2 active threads if a worker is waiting for input + TestCPUUserTime(nthread, 2); +} + +#include "tbb/task_scheduler_init.h" + +int TestMain () { + out_of_order_count = 0; + if( MinThread<1 ) { + REPORT("must have at least one thread"); + exit(1); + } + + // Test with varying number of threads. + for( nthread=MinThread; nthread<=MaxThread; ++nthread ) { + // Initialize TBB task scheduler + tbb::task_scheduler_init init(nthread); + sleeptime = 0.0; // msec : 0 == no_timing, > 0, each filter stage sleeps for sleeptime + + // Test pipelines with 1 and maximal number of filters + for( unsigned n=1; n<=MaxFilters; n*=MaxFilters ) { + // Thread-bound stages are serviced by user-created threads; those + // don't run the pipeline and don't service non-thread-bound stages + PipelineTest::TestTrivialPipeline(nthread,n); + } + + // Test that all workers sleep when no work + TestCPUUserTime(nthread); + if((unsigned)nthread >= MaxFilters) // test works when number of threads >= number of stages + PipelineTest::TestIdleSpinning(nthread); + } + if( !out_of_order_count ) + REPORT("Warning: out of order serial filter received tokens in order\n"); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_priority_queue_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_priority_queue_node.cpp new file mode 100644 index 00000000..73724fb9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_priority_queue_node.cpp @@ -0,0 +1,410 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// TO DO: Add overlapping put / receive tests + +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_ALLOCATOR __TBB_CPF_BUILD + +#include "harness.h" + +#include "tbb/flow_graph.h" +#include "harness_checktype.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" +#include "harness_graph.h" +#include "test_follows_and_precedes_api.h" + +#include <cstdio> + +#define N 10 +#define C 10 + +template< typename T > +void spin_try_get( tbb::flow::priority_queue_node<T> &q, T &value ) { + while ( q.try_get(value) != true ) ; +} + +template< typename T > +void check_item( T* next_value, T &value ) { + int tid = value / N; + int offset = value % N; + ASSERT( next_value[tid] == T(offset), NULL ); + ++next_value[tid]; +} + +template< typename T > +struct parallel_puts : NoAssign { + tbb::flow::priority_queue_node<T> &my_q; + parallel_puts( tbb::flow::priority_queue_node<T> &q ) : my_q(q) {} + void operator()(int i) const { + for (int j = 0; j < N; ++j) { + bool msg = my_q.try_put( T(N*i + j) ); + ASSERT( msg == true, NULL ); + } + } +}; + +template< typename T > +struct parallel_gets : NoAssign { + tbb::flow::priority_queue_node<T> &my_q; + parallel_gets( tbb::flow::priority_queue_node<T> &q) : my_q(q) {} + void operator()(int) const { + T prev; + spin_try_get( my_q, prev ); + for (int j = 0; j < N-1; ++j) { + T v; + spin_try_get( my_q, v ); + ASSERT(v < prev, NULL); + } + } +}; + +template< typename T > +struct parallel_put_get : NoAssign { + tbb::flow::priority_queue_node<T> &my_q; + parallel_put_get( tbb::flow::priority_queue_node<T> &q ) : my_q(q) {} + void operator()(int tid) const { + for ( int i = 0; i < N; i+=C ) { + int j_end = ( N < i + C ) ? N : i + C; + // dump about C values into the Q + for ( int j = i; j < j_end; ++j ) { + ASSERT( my_q.try_put( T (N*tid + j ) ) == true, NULL ); + } + // receive about C values from the Q + for ( int j = i; j < j_end; ++j ) { + T v; + spin_try_get( my_q, v ); + } + } + } +}; + +// +// Tests +// +// Item can be reserved, released, consumed ( single serial receiver ) +// +template< typename T > +int test_reservation(int) { + tbb::flow::graph g; + + // Simple tests + tbb::flow::priority_queue_node<T> q(g); + + { + + T bogus_value(-1); + + q.try_put(T(1)); + q.try_put(T(2)); + q.try_put(T(3)); + g.wait_for_all(); + + T v=bogus_value, w=bogus_value; + ASSERT( q.try_reserve(v) == true, NULL ); + ASSERT( v == T(3), NULL ); + ASSERT( q.try_release() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + ASSERT( q.try_reserve(v) == true, NULL ); + ASSERT( v == T(3), NULL ); + ASSERT( q.try_consume() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + + ASSERT( q.try_get(v) == true, NULL ); + ASSERT( v == T(2), NULL ); + v = bogus_value; + g.wait_for_all(); + + ASSERT( q.try_reserve(v) == true, NULL ); + ASSERT( v == T(1), NULL ); + ASSERT( q.try_reserve(w) == false, NULL ); + ASSERT( w == bogus_value, NULL ); + ASSERT( q.try_get(w) == false, NULL ); + ASSERT( w == bogus_value, NULL ); + ASSERT( q.try_release() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + ASSERT( q.try_reserve(v) == true, NULL ); + ASSERT( v == T(1), NULL ); + ASSERT( q.try_consume() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get(v) == false, NULL ); + } + return 0; +} + +// +// Tests +// +// multiple parallel senders, items in FIFO (relatively to sender) order +// multiple parallel senders, multiple parallel receivers, items in FIFO order (relative to sender/receiver) and all items received +// * overlapped puts / gets +// * all puts finished before any getS +// +template< typename T > +int test_parallel(int num_threads) { + tbb::flow::graph g; + tbb::flow::priority_queue_node<T> q(g); + tbb::flow::priority_queue_node<T> q2(g); + tbb::flow::priority_queue_node<T> q3(g); + T bogus_value(-1); + T j = bogus_value; + + NativeParallelFor( num_threads, parallel_puts<T>(q) ); + for (int i = num_threads*N -1; i>=0; --i) { + spin_try_get( q, j ); + ASSERT(j == i, NULL); + j = bogus_value; + } + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + NativeParallelFor( num_threads, parallel_puts<T>(q) ); + g.wait_for_all(); + NativeParallelFor( num_threads, parallel_gets<T>(q) ); + g.wait_for_all(); + j = bogus_value; + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + NativeParallelFor( num_threads, parallel_put_get<T>(q) ); + g.wait_for_all(); + j = bogus_value; + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::make_edge( q, q2 ); + tbb::flow::make_edge( q2, q3 ); + NativeParallelFor( num_threads, parallel_puts<T>(q) ); + g.wait_for_all(); + NativeParallelFor( num_threads, parallel_gets<T>(q3) ); + g.wait_for_all(); + j = bogus_value; + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + ASSERT( q2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + ASSERT( q3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // test copy constructor + ASSERT( q.remove_successor( q2 ) == true, NULL ); + NativeParallelFor( num_threads, parallel_puts<T>(q) ); + tbb::flow::priority_queue_node<T> q_copy(q); + g.wait_for_all(); + j = bogus_value; + ASSERT( q_copy.try_get( j ) == false, NULL ); + ASSERT( q.register_successor( q_copy ) == true, NULL ); + for (int i = num_threads*N -1; i>=0; --i) { + spin_try_get( q_copy, j ); + ASSERT(j == i, NULL); + j = bogus_value; + } + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + ASSERT( q_copy.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + return 0; +} + +// +// Tests +// +// Predecessors cannot be registered +// Empty Q rejects item requests +// Single serial sender, items in FIFO order +// Chained Qs ( 2 & 3 ), single sender, items at last Q in FIFO order +// + +template< typename T > +int test_serial() { + tbb::flow::graph g; + T bogus_value(-1); + + tbb::flow::priority_queue_node<T> q(g); + tbb::flow::priority_queue_node<T> q2(g); + T j = bogus_value; + + // + // Rejects attempts to add / remove predecessor + // Rejects request from empty Q + // + ASSERT( q.register_predecessor( q2 ) == false, NULL ); + ASSERT( q.remove_predecessor( q2 ) == false, NULL ); + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // + // Simple puts and gets + // + + for (int i = 0; i < N; ++i) + ASSERT( q.try_put( T(i) ), NULL ); + for (int i = N-1; i >=0; --i) { + j = bogus_value; + spin_try_get( q, j ); + ASSERT( i == j, NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::make_edge( q, q2 ); + + for (int i = 0; i < N; ++i) + ASSERT( q.try_put( T(i) ), NULL ); + g.wait_for_all(); + for (int i = N-1; i >= 0; --i) { + j = bogus_value; + spin_try_get( q2, j ); + ASSERT( i == j, NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::remove_edge( q, q2 ); + ASSERT( q.try_put( 1 ) == true, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( q.try_get( j ) == true, NULL ); + ASSERT( j == 1, NULL ); + + tbb::flow::priority_queue_node<T> q3(g); + tbb::flow::make_edge( q, q2 ); + tbb::flow::make_edge( q2, q3 ); + + for (int i = 0; i < N; ++i) + ASSERT( q.try_put( T(i) ), NULL ); + g.wait_for_all(); + for (int i = N-1; i >= 0; --i) { + j = bogus_value; + spin_try_get( q3, j ); + ASSERT( i == j, NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( q3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::remove_edge( q, q2 ); + ASSERT( q.try_put( 1 ) == true, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( q3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( q.try_get( j ) == true, NULL ); + ASSERT( j == 1, NULL ); + + return 0; +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + std::array<int, 3> messages_for_follows = { {0, 1, 2} }; + std::vector<int> messages_for_precedes = {0, 1, 2}; + + follows_and_precedes_testing::test_follows <int, tbb::flow::priority_queue_node<int>>(messages_for_follows); + follows_and_precedes_testing::test_precedes <int, tbb::flow::priority_queue_node<int>>(messages_for_precedes); +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + + graph g; + broadcast_node<int> br(g); + priority_queue_node<int> pq0(g); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + using compare_type = std::greater<void>; + priority_queue_node pq1(follows(br)); + static_assert(std::is_same_v<decltype(pq1), priority_queue_node<int>>); + + priority_queue_node pq2(follows(br), compare_type()); + static_assert(std::is_same_v<decltype(pq2), priority_queue_node<int, compare_type>>); + + priority_queue_node pq3(precedes(br)); + static_assert(std::is_same_v<decltype(pq3), priority_queue_node<int>>); + + priority_queue_node pq4(precedes(br), compare_type()); + static_assert(std::is_same_v<decltype(pq4), priority_queue_node<int, compare_type>>); +#endif + + priority_queue_node pq5(pq0); + static_assert(std::is_same_v<decltype(pq5), priority_queue_node<int>>); + g.wait_for_all(); +} +#endif + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +void test_node_allocator() { + tbb::flow::graph g; + tbb::flow::priority_queue_node< int, std::less<int>, std::allocator<int> > tmp(g); +} +#endif + +int TestMain() { + tbb::tick_count start = tbb::tick_count::now(), stop; + for (int p = 2; p <= 4; ++p) { + tbb::task_scheduler_init init(p); + test_serial<int>(); + test_reservation<int>(p); + test_reservation<check_type<int> >(p); + test_parallel<int>(p); + } + stop = tbb::tick_count::now(); + REMARK("Priority_Queue_Node Time=%6.6f\n", (stop-start).seconds()); + REMARK("Testing resets\n"); + test_resets<int,tbb::flow::priority_queue_node<int> >(); + test_resets<float,tbb::flow::priority_queue_node<float> >(); +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_buffer_extract<tbb::flow::priority_queue_node<int> >().run_tests(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + test_node_allocator(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_queue_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_queue_node.cpp new file mode 100644 index 00000000..d29b9916 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_queue_node.cpp @@ -0,0 +1,518 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// TO DO: Add overlapping put / receive tests + +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_ALLOCATOR __TBB_CPF_BUILD + +#include "harness.h" + +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" +#include "harness_checktype.h" +#include "harness_graph.h" +#include "test_follows_and_precedes_api.h" + +#include <cstdio> + +#define N 1000 +#define C 10 + +template< typename T > +void spin_try_get( tbb::flow::queue_node<T> &q, T &value ) { + while ( q.try_get(value) != true ) ; +} + +template< typename T > +void check_item( T* next_value, T &value ) { + int tid = value / N; + int offset = value % N; + ASSERT( next_value[tid] == T(offset), NULL ); + ++next_value[tid]; +} + +template< typename T > +struct parallel_puts : NoAssign { + + tbb::flow::queue_node<T> &my_q; + + parallel_puts( tbb::flow::queue_node<T> &q ) : my_q(q) {} + + void operator()(int i) const { + for (int j = 0; j < N; ++j) { + bool msg = my_q.try_put( T(N*i + j) ); + ASSERT( msg == true, NULL ); + } + } + +}; + + + +template< typename T > +struct touches { + + bool **my_touches; + T **my_last_touch; + int my_num_threads; + + touches( int num_threads ) : my_num_threads(num_threads) { + my_last_touch = new T* [my_num_threads]; + my_touches = new bool* [my_num_threads]; + for ( int p = 0; p < my_num_threads; ++p) { + my_last_touch[p] = new T[my_num_threads]; + for ( int p2 = 0; p2 < my_num_threads; ++p2) + my_last_touch[p][p2] = -1; + + my_touches[p] = new bool[N*my_num_threads]; + for ( int n = 0; n < N*my_num_threads; ++n) + my_touches[p][n] = false; + } + } + + ~touches() { + for ( int p = 0; p < my_num_threads; ++p) { + delete [] my_touches[p]; + delete [] my_last_touch[p]; + } + delete [] my_touches; + delete [] my_last_touch; + } + + bool check( int tid, T v ) { + int v_tid = v / N; + if ( my_touches[tid][v] != false ) { + printf("Error: value seen twice by local thread\n"); + return false; + } + if ( v <= my_last_touch[tid][v_tid] ) { + printf("Error: value seen in wrong order by local thread\n"); + return false; + } + my_last_touch[tid][v_tid] = v; + my_touches[tid][v] = true; + return true; + } + + bool validate_touches() { + bool *all_touches = new bool[N*my_num_threads]; + for ( int n = 0; n < N*my_num_threads; ++n) + all_touches[n] = false; + + for ( int p = 0; p < my_num_threads; ++p) { + for ( int n = 0; n < N*my_num_threads; ++n) { + if ( my_touches[p][n] == true ) { + ASSERT( all_touches[n] == false, "value see by more than one thread\n" ); + all_touches[n] = true; + } + } + } + for ( int n = 0; n < N*my_num_threads; ++n) { + if ( !all_touches[n] ) + printf("No touch at %d, my_num_threads = %d\n", n, my_num_threads); + //ASSERT( all_touches[n] == true, "value not seen by any thread\n" ); + } + delete [] all_touches; + return true; + } + +}; + +template< typename T > +struct parallel_gets : NoAssign { + + tbb::flow::queue_node<T> &my_q; + touches<T> &my_touches; + + parallel_gets( tbb::flow::queue_node<T> &q, touches<T> &t) : my_q(q), my_touches(t) {} + + void operator()(int tid) const { + for (int j = 0; j < N; ++j) { + T v; + spin_try_get( my_q, v ); + my_touches.check( tid, v ); + } + } + +}; + +template< typename T > +struct parallel_put_get : NoAssign { + + tbb::flow::queue_node<T> &my_q; + touches<T> &my_touches; + + parallel_put_get( tbb::flow::queue_node<T> &q, touches<T> &t ) : my_q(q), my_touches(t) {} + + void operator()(int tid) const { + + for ( int i = 0; i < N; i+=C ) { + int j_end = ( N < i + C ) ? N : i + C; + // dump about C values into the Q + for ( int j = i; j < j_end; ++j ) { + ASSERT( my_q.try_put( T (N*tid + j ) ) == true, NULL ); + } + // receiver about C values from the Q + for ( int j = i; j < j_end; ++j ) { + T v; + spin_try_get( my_q, v ); + my_touches.check( tid, v ); + } + } + } + +}; + +// +// Tests +// +// Item can be reserved, released, consumed ( single serial receiver ) +// +template< typename T > +int test_reservation() { + tbb::flow::graph g; + T bogus_value(-1); + + // Simple tests + tbb::flow::queue_node<T> q(g); + + q.try_put(T(1)); + q.try_put(T(2)); + q.try_put(T(3)); + + T v; + ASSERT( q.reserve_item(v) == true, NULL ); + ASSERT( v == T(1), NULL ); + ASSERT( q.release_reservation() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + ASSERT( q.reserve_item(v) == true, NULL ); + ASSERT( v == T(1), NULL ); + ASSERT( q.consume_reservation() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + + ASSERT( q.try_get(v) == true, NULL ); + ASSERT( v == T(2), NULL ); + v = bogus_value; + g.wait_for_all(); + + ASSERT( q.reserve_item(v) == true, NULL ); + ASSERT( v == T(3), NULL ); + ASSERT( q.release_reservation() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + ASSERT( q.reserve_item(v) == true, NULL ); + ASSERT( v == T(3), NULL ); + ASSERT( q.consume_reservation() == true, NULL ); + v = bogus_value; + g.wait_for_all(); + + return 0; +} + +// +// Tests +// +// multiple parallel senders, items in FIFO (relatively to sender) order +// multiple parallel senders, multiple parallel receivers, items in FIFO order (relative to sender/receiver) and all items received +// * overlapped puts / gets +// * all puts finished before any getS +// +template< typename T > +int test_parallel(int num_threads) { + tbb::flow::graph g; + tbb::flow::queue_node<T> q(g); + tbb::flow::queue_node<T> q2(g); + tbb::flow::queue_node<T> q3(g); + { + Check< T > my_check; + T bogus_value(-1); + T j = bogus_value; + NativeParallelFor( num_threads, parallel_puts<T>(q) ); + + T *next_value = new T[num_threads]; + for (int tid = 0; tid < num_threads; ++tid) next_value[tid] = T(0); + + for (int i = 0; i < num_threads * N; ++i ) { + spin_try_get( q, j ); + check_item( next_value, j ); + j = bogus_value; + } + for (int tid = 0; tid < num_threads; ++tid) { + ASSERT( next_value[tid] == T(N), NULL ); + } + delete[] next_value; + + j = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + NativeParallelFor( num_threads, parallel_puts<T>(q) ); + + { + touches< T > t( num_threads ); + NativeParallelFor( num_threads, parallel_gets<T>(q, t) ); + g.wait_for_all(); + ASSERT( t.validate_touches(), NULL ); + } + j = bogus_value; + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + g.wait_for_all(); + { + touches< T > t2( num_threads ); + NativeParallelFor( num_threads, parallel_put_get<T>(q, t2) ); + g.wait_for_all(); + ASSERT( t2.validate_touches(), NULL ); + } + j = bogus_value; + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::make_edge( q, q2 ); + tbb::flow::make_edge( q2, q3 ); + + NativeParallelFor( num_threads, parallel_puts<T>(q) ); + { + touches< T > t3( num_threads ); + NativeParallelFor( num_threads, parallel_gets<T>(q3, t3) ); + g.wait_for_all(); + ASSERT( t3.validate_touches(), NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( q3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // test copy constructor + ASSERT( q.remove_successor( q2 ), NULL ); + NativeParallelFor( num_threads, parallel_puts<T>(q) ); + tbb::flow::queue_node<T> q_copy(q); + j = bogus_value; + g.wait_for_all(); + ASSERT( q_copy.try_get( j ) == false, NULL ); + ASSERT( q.register_successor( q_copy ) == true, NULL ); + { + touches< T > t( num_threads ); + NativeParallelFor( num_threads, parallel_gets<T>(q_copy, t) ); + g.wait_for_all(); + ASSERT( t.validate_touches(), NULL ); + } + j = bogus_value; + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + ASSERT( q_copy.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + } + + return 0; +} + +// +// Tests +// +// Predecessors cannot be registered +// Empty Q rejects item requests +// Single serial sender, items in FIFO order +// Chained Qs ( 2 & 3 ), single sender, items at last Q in FIFO order +// + +template< typename T > +int test_serial() { + tbb::flow::graph g; + tbb::flow::queue_node<T> q(g); + tbb::flow::queue_node<T> q2(g); + { // destroy the graph after manipulating it, and see if all the items in the buffers + // have been destroyed before the graph + Check<T> my_check; // if check_type< U > count constructions and destructions + T bogus_value(-1); + T j = bogus_value; + + // + // Rejects attempts to add / remove predecessor + // Rejects request from empty Q + // + ASSERT( q.register_predecessor( q2 ) == false, NULL ); + ASSERT( q.remove_predecessor( q2 ) == false, NULL ); + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // + // Simple puts and gets + // + + for (int i = 0; i < N; ++i) { + bool msg = q.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + + for (int i = 0; i < N; ++i) { + j = bogus_value; + spin_try_get( q, j ); + ASSERT( i == j, NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::make_edge( q, q2 ); + + for (int i = 0; i < N; ++i) { + bool msg = q.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + + for (int i = 0; i < N; ++i) { + j = bogus_value; + spin_try_get( q2, j ); + ASSERT( i == j, NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::remove_edge( q, q2 ); + ASSERT( q.try_put( 1 ) == true, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( q.try_get( j ) == true, NULL ); + ASSERT( j == 1, NULL ); + + tbb::flow::queue_node<T> q3(g); + tbb::flow::make_edge( q, q2 ); + tbb::flow::make_edge( q2, q3 ); + + for (int i = 0; i < N; ++i) { + bool msg = q.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + for (int i = 0; i < N; ++i) { + j = bogus_value; + spin_try_get( q3, j ); + ASSERT( i == j, NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( q.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( q3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + tbb::flow::remove_edge( q, q2 ); + ASSERT( q.try_put( 1 ) == true, NULL ); + g.wait_for_all(); + ASSERT( q2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( q3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + ASSERT( q.try_get( j ) == true, NULL ); + ASSERT( j == 1, NULL ); + } + + return 0; +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + std::array<int, 3> messages_for_follows = { {0, 1, 2} }; + std::vector<int> messages_for_precedes = {0, 1, 2}; + + follows_and_precedes_testing::test_follows <int, tbb::flow::queue_node<int>>(messages_for_follows); + follows_and_precedes_testing::test_precedes <int, tbb::flow::queue_node<int>>(messages_for_precedes); +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + graph g; + broadcast_node<int> br(g); + queue_node<int> q0(g); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + queue_node q1(follows(br)); + static_assert(std::is_same_v<decltype(q1), queue_node<int>>); + + queue_node q2(precedes(br)); + static_assert(std::is_same_v<decltype(q2), queue_node<int>>); +#endif + + queue_node q3(q0); + static_assert(std::is_same_v<decltype(q3), queue_node<int>>); + g.wait_for_all(); +} +#endif + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +void test_node_allocator() { + tbb::flow::graph g; + tbb::flow::queue_node< int, std::allocator<int> > tmp(g); +} +#endif + + +int TestMain() { + tbb::tick_count start = tbb::tick_count::now(), stop; + for (int p = 2; p <= 4; ++p) { + tbb::task_scheduler_init init(p); + test_serial<int>(); + test_serial<check_type<int> >(); + test_parallel<int>(p); + test_parallel<check_type<int> >(p); + } + stop = tbb::tick_count::now(); + REMARK("Queue_Node Time=%6.6f\n", (stop-start).seconds()); + REMARK("Testing resets\n"); + test_resets<int, tbb::flow::queue_node<int> >(); + test_resets<float, tbb::flow::queue_node<float> >(); +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_buffer_extract<tbb::flow::queue_node<int> >().run_tests(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + test_node_allocator(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_range_based_for.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_range_based_for.h new file mode 100644 index 00000000..c1b2c06f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_range_based_for.h @@ -0,0 +1,75 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __TBB_test_range_based_for_H +#define __TBB_test_range_based_for_H + +#include <utility> //for std::pair +namespace range_based_for_support_tests{ + + template<typename value_type, typename container, typename binary_op_type, typename init_value_type> + inline init_value_type range_based_for_accumulate(container const& c, binary_op_type accumulator, init_value_type init ) + { + init_value_type range_for_accumulated = init; + #if __TBB_RANGE_BASED_FOR_PRESENT + for (value_type x : c) { + range_for_accumulated = accumulator(range_for_accumulated, x); + } + #else + for (typename container::const_iterator x =c.begin(); x != c.end(); ++x) { + range_for_accumulated = accumulator(range_for_accumulated, *x); + } + #endif + return range_for_accumulated; + } + + template<typename container, typename binary_op_type, typename init_value_type> + inline init_value_type range_based_for_accumulate(container const& c, binary_op_type accumulator, init_value_type init ) + { + typedef typename container::value_type value_type; + return range_based_for_accumulate<value_type>(c,accumulator,init); + } + + template <typename integral_type > + integral_type gauss_summ_of_int_sequence(integral_type sequence_length){ + return (sequence_length +1)* sequence_length /2; + } + + struct unified_summer + { + template <typename type> + type operator()(type const& lhs, type const& rhs) + { + return lhs + rhs; + } + + template<typename first_type, typename second_type> + second_type operator()(second_type const& lhs, std::pair<first_type, second_type> const& rhs) + { + return lhs + rhs.second; + } + }; + + struct pair_second_summer{ + template<typename first_type, typename second_type> + second_type operator() (second_type const& lhs, std::pair<first_type, second_type> const& rhs) const + { + return lhs + rhs.second; + } + }; +} + +#endif /* __TBB_test_range_based_for_H */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_reader_writer_lock.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_reader_writer_lock.cpp new file mode 100644 index 00000000..18b504d0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_reader_writer_lock.cpp @@ -0,0 +1,234 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// test reader_writer_lock +#include "tbb/reader_writer_lock.h" +#include "tbb/atomic.h" +#include "tbb/tbb_exception.h" +#include "harness.h" +#include "harness_barrier.h" + +tbb::reader_writer_lock the_mutex; +const int MAX_WORK = 10000; + +tbb::atomic<size_t> active_readers, active_writers; +tbb::atomic<bool> sim_readers; +size_t n_tested__sim_readers; + + +int BusyWork(int percentOfMaxWork) { + int iters = 0; + for (int i=0; i<MAX_WORK*((double)percentOfMaxWork/100.0); ++i) { + iters++; + } + return iters; +} + +struct StressRWLBody : NoAssign { + const int nThread; + const int percentMax; + + StressRWLBody(int nThread_, int percentMax_) : nThread(nThread_), percentMax(percentMax_) {} + + void operator()(const int /* threadID */ ) const { + int nIters = 100; + int r_result=0, w_result=0; + for(int i=0; i<nIters; ++i) { + // test unscoped blocking write lock + the_mutex.lock(); + w_result += BusyWork(percentMax); +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + // test exception for recursive write lock + bool was_caught = false; + try { + the_mutex.lock(); + } + catch(tbb::improper_lock& ex) { + REMARK("improper_lock: %s\n", ex.what()); + was_caught = true; + } + catch(...) { + REPORT("Wrong exception caught during recursive lock attempt."); + } + ASSERT(was_caught, "Recursive lock attempt exception not caught properly."); + // test exception for recursive read lock + was_caught = false; + try { + the_mutex.lock_read(); + } + catch(tbb::improper_lock& ex) { + REMARK("improper_lock: %s\n", ex.what()); + was_caught = true; + } + catch(...) { + REPORT("Wrong exception caught during recursive lock attempt."); + } + ASSERT(was_caught, "Recursive lock attempt exception not caught properly."); +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ + the_mutex.unlock(); + // test unscoped non-blocking write lock + if (the_mutex.try_lock()) { + w_result += BusyWork(percentMax); + the_mutex.unlock(); + } + // test unscoped blocking read lock + the_mutex.lock_read(); + r_result += BusyWork(percentMax); + the_mutex.unlock(); + // test unscoped non-blocking read lock + if(the_mutex.try_lock_read()) { + r_result += BusyWork(percentMax); + the_mutex.unlock(); + } + { // test scoped blocking write lock + tbb::reader_writer_lock::scoped_lock my_lock(the_mutex); + w_result += BusyWork(percentMax); + } + { // test scoped blocking read lock + tbb::reader_writer_lock::scoped_lock_read my_lock(the_mutex); + r_result += BusyWork(percentMax); + } + } + REMARK(" R%d/W%d", r_result, w_result); // reader/writer iterations of busy work completed + } +}; + +struct CorrectRWLScopedBody : NoAssign { + const int nThread; + Harness::SpinBarrier& my_barrier; + + CorrectRWLScopedBody(int nThread_, Harness::SpinBarrier& b_) : nThread(nThread_),my_barrier(b_) {} + + void operator()(const int /* threadID */ ) const { + my_barrier.wait(); + for (int i=0; i<50; i++) { + const bool is_reader = i%5==0; // 1 writer for every 4 readers + + if (is_reader) { + tbb::reader_writer_lock::scoped_lock_read my_lock(the_mutex); + active_readers++; + if (active_readers > 1) sim_readers = true; + ASSERT(active_writers==0, "Active writers in read-locked region."); + Harness::Sleep(10); + active_readers--; + } + else { // is writer + tbb::reader_writer_lock::scoped_lock my_lock(the_mutex); + active_writers++; + ASSERT(active_readers==0, "Active readers in write-locked region."); + ASSERT(active_writers<=1, "More than one active writer in write-locked region."); + Harness::Sleep(10); + active_writers--; + } + } + } +}; + +struct CorrectRWLBody : NoAssign { + const int nThread; + Harness::SpinBarrier& my_barrier; + + CorrectRWLBody(int nThread_, Harness::SpinBarrier& b_ ) : nThread(nThread_), my_barrier(b_) {} + + void operator()(const int /* threadID */ ) const { + my_barrier.wait(); + for (int i=0; i<50; i++) { + const bool is_reader = i%5==0; // 1 writer for every 4 readers + + if (is_reader) { + the_mutex.lock_read(); + active_readers++; + if (active_readers > 1) sim_readers = true; + ASSERT(active_writers==0, "Active writers in read-locked region."); + } + else { // is writer + the_mutex.lock(); + active_writers++; + ASSERT(active_readers==0, "Active readers in write-locked region."); + ASSERT(active_writers<=1, "More than one active writer in write-locked region."); + } + Harness::Sleep(10); + if (is_reader) { + active_readers--; + } + else { // is writer + active_writers--; + } + the_mutex.unlock(); + } + } +}; + +void TestReaderWriterLockOnNThreads(int nThreads) { + // Stress-test all interfaces + for (int pc=0; pc<=100; pc+=20) { + REMARK("Testing with %d threads, percent of MAX_WORK=%d...", nThreads, pc); + StressRWLBody myStressBody(nThreads, pc); + NativeParallelFor(nThreads, myStressBody); + REMARK(" OK.\n"); + } + + int i; + n_tested__sim_readers = 0; + REMARK("Testing with %d threads, direct/unscoped locking mode...", nThreads); // TODO: choose direct or unscoped? + // TODO: refactor the following two for loops into a shared function + for( i=0; i<100; ++i ) { + Harness::SpinBarrier bar0(nThreads); + + CorrectRWLBody myCorrectBody(nThreads,bar0); + active_writers = active_readers = 0; + sim_readers = false; + NativeParallelFor(nThreads, myCorrectBody); + + if( sim_readers || nThreads==1 ) { + if( ++n_tested__sim_readers>5 ) + break; + } + } + ASSERT(i<100, "There were no simultaneous readers."); + REMARK(" OK.\n"); + + n_tested__sim_readers = 0; + REMARK("Testing with %d threads, scoped locking mode...", nThreads); + for( i=0; i<100; ++i ) { + Harness::SpinBarrier bar0(nThreads); + CorrectRWLScopedBody myCorrectScopedBody(nThreads, bar0); + active_writers = active_readers = 0; + sim_readers = false; + NativeParallelFor(nThreads, myCorrectScopedBody); + if( sim_readers || nThreads==1 ) { + if( ++n_tested__sim_readers>5 ) + break; + } + } + ASSERT(i<100, "There were no simultaneous readers."); + REMARK(" OK.\n"); +} + +void TestReaderWriterLock() { + for(int p = MinThread; p <= MaxThread; p++) { + TestReaderWriterLockOnNThreads(p); + } +} + + +int TestMain() { + if(MinThread <= 0) MinThread = 1; + if(MaxThread > 0) { + TestReaderWriterLock(); + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_resumable_tasks.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_resumable_tasks.cpp new file mode 100644 index 00000000..d08831ea --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_resumable_tasks.cpp @@ -0,0 +1,431 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" +#include "tbb/task_scheduler_observer.h" + +#include "harness.h" + +#if !__TBB_PREVIEW_RESUMABLE_TASKS +int TestMain() { + return Harness::Skipped; +} +#else // __TBB_PREVIEW_RESUMABLE_TASKS + +#include "tbb/task.h" +#include "tbb/concurrent_queue.h" +#include "tbb/atomic.h" +#include "tbb/parallel_for.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/enumerable_thread_specific.h" +#include "tbb/task_arena.h" +#include "tbb/task_group.h" +#include "tbb/tbb_thread.h" + +#include <vector> + +typedef tbb::enumerable_thread_specific<int, tbb::cache_aligned_allocator<int> > ets_int_t; +const int N = 10; + +// External activity used in all tests, which resumes suspended execution point +class AsyncActivity { +public: + AsyncActivity(int num_) : m_numAsyncThreads(num_) { + for (int i = 0; i < m_numAsyncThreads ; ++i) { + m_asyncThreads.push_back( new tbb::tbb_thread(AsyncActivity::asyncLoop, this) ); + } + } + ~AsyncActivity() { + for (int i = 0; i < m_numAsyncThreads; ++i) { + m_tagQueue.push(NULL); + } + for (int i = 0; i < m_numAsyncThreads; ++i) { + m_asyncThreads[i]->join(); + delete m_asyncThreads[i]; + } + ASSERT(m_tagQueue.empty(), NULL); + } + void submit(void* ctx) { + m_tagQueue.push(ctx); + } + +private: + static void asyncLoop(AsyncActivity* async) { + tbb::task::suspend_point tag; + async->m_tagQueue.pop(tag); + while (tag) { + tbb::task::resume(tag); + async->m_tagQueue.pop(tag); + } + } + + const int m_numAsyncThreads; + tbb::concurrent_bounded_queue<void*> m_tagQueue; + std::vector<tbb::tbb_thread*> m_asyncThreads; +}; + +struct SuspendBody { + SuspendBody(AsyncActivity& a_) : + m_asyncActivity(a_) {} + void operator()(tbb::task::suspend_point tag) { + m_asyncActivity.submit(tag); + } + +private: + AsyncActivity& m_asyncActivity; +}; + +class InnermostArenaBody { +public: + InnermostArenaBody(AsyncActivity& a_) : m_asyncActivity(a_) {} + + void operator()() { + InnermostOuterParFor inner_outer_body(m_asyncActivity); + tbb::parallel_for(0, N, inner_outer_body ); + } + +private: + struct InnermostInnerParFor { + InnermostInnerParFor(AsyncActivity& a_) : m_asyncActivity(a_) {} + void operator()(int) const { + tbb::task::suspend(SuspendBody(m_asyncActivity)); + } + AsyncActivity& m_asyncActivity; + }; + struct InnermostOuterParFor { + InnermostOuterParFor(AsyncActivity& a_) : m_asyncActivity(a_) {} + void operator()(int) const { + tbb::task::suspend(SuspendBody(m_asyncActivity)); + InnermostInnerParFor inner_inner_body(m_asyncActivity); + tbb::parallel_for(0, N, inner_inner_body); + } + AsyncActivity& m_asyncActivity; + }; + AsyncActivity& m_asyncActivity; +}; + +class OutermostArenaBody { +public: + OutermostArenaBody(AsyncActivity& a_, tbb::task_arena& o_, tbb::task_arena& i_, tbb::task_arena& id_, ets_int_t& ets_) : + m_asyncActivity(a_), m_outermostArena(o_), m_innermostArena(i_), m_innermostArenaDefault(id_), m_etsInner(ets_) {} + + void operator()() { + tbb::parallel_for(0, 32, *this); + } + + void operator()(int i) const { + tbb::task::suspend(SuspendBody(m_asyncActivity)); + + tbb::task_arena& nested_arena = (i % 3 == 0) ? + m_outermostArena : (i % 3 == 1 ? m_innermostArena : m_innermostArenaDefault); + + if (i % 3 != 0) { + // We can only guarantee recall coorectness for "not-same" nested arenas entry + m_etsInner.local() = i; + } + InnermostArenaBody innermost_arena_body(m_asyncActivity); + nested_arena.execute(innermost_arena_body); + if (i % 3 != 0) { + ASSERT(i == m_etsInner.local(), "Original thread wasn't recalled for innermost nested arena."); + } + } + +private: + AsyncActivity& m_asyncActivity; + tbb::task_arena& m_outermostArena; + tbb::task_arena& m_innermostArena; + tbb::task_arena& m_innermostArenaDefault; + ets_int_t& m_etsInner; +}; + +void TestNestedArena() { + AsyncActivity asyncActivity(4); + + ets_int_t ets_outer; + ets_int_t ets_inner; + + tbb::task_arena outermost_arena; + tbb::task_arena innermost_arena(2,2); + tbb::task_arena innermost_arena_default; + + outermost_arena.initialize(); + innermost_arena_default.initialize(); + innermost_arena.initialize(); + + ets_outer.local() = 42; + OutermostArenaBody outer_arena_body(asyncActivity, outermost_arena, innermost_arena, innermost_arena_default, ets_inner); + outermost_arena.execute(outer_arena_body); + ASSERT(ets_outer.local() == 42, "Original/main thread wasn't recalled."); +} + +#if __TBB_CPP11_LAMBDAS_PRESENT + +#include <thread> + +// External activity used in all tests, which resumes suspended execution point +class EpochAsyncActivity { +public: + EpochAsyncActivity(int num_, tbb::atomic<int>& e_) : m_numAsyncThreads(num_), m_globalEpoch(e_) { + for (int i = 0; i < m_numAsyncThreads ; ++i) { + m_asyncThreads.push_back( new tbb::tbb_thread(EpochAsyncActivity::asyncLoop, this) ); + } + } + ~EpochAsyncActivity() { + for (int i = 0; i < m_numAsyncThreads; ++i) { + m_ctxQueue.push(NULL); + } + for (int i = 0; i < m_numAsyncThreads; ++i) { + m_asyncThreads[i]->join(); + delete m_asyncThreads[i]; + } + ASSERT(m_ctxQueue.empty(), NULL); + } + void submit(void* ctx) { + m_ctxQueue.push(ctx); + } + +private: + static void asyncLoop(EpochAsyncActivity* async) { + tbb::task::suspend_point ctx; + async->m_ctxQueue.pop(ctx); + while (ctx) { + // Track the global epoch + async->m_globalEpoch++; + // Continue execution from suspended ctx + tbb::task::resume(ctx); + async->m_ctxQueue.pop(ctx); + } + } + + const int m_numAsyncThreads; + tbb::atomic<int>& m_globalEpoch; + tbb::concurrent_bounded_queue<void*> m_ctxQueue; + std::vector<tbb::tbb_thread*> m_asyncThreads; +}; + +struct EpochSuspendBody { + EpochSuspendBody(EpochAsyncActivity& a_, tbb::atomic<int>& e_, int& le_) : + m_asyncActivity(a_), m_globalEpoch(e_), m_localEpoch(le_) {} + + void operator()(tbb::task::suspend_point ctx) { + m_localEpoch = m_globalEpoch; + m_asyncActivity.submit(ctx); + } + +private: + EpochAsyncActivity& m_asyncActivity; + tbb::atomic<int>& m_globalEpoch; + int& m_localEpoch; +}; + +// Simple test for basic resumable tasks functionality +void TestSuspendResume() { + tbb::atomic<int> global_epoch; global_epoch = 0; + EpochAsyncActivity async(4, global_epoch); + + tbb::enumerable_thread_specific<int, tbb::cache_aligned_allocator<int>, tbb::ets_suspend_aware> ets_fiber; + tbb::atomic<int> inner_par_iters, outer_par_iters; + inner_par_iters = outer_par_iters = 0; + + tbb::parallel_for(0, N, [&](int) { + for (int i = 0; i < 100; ++i) { + ets_fiber.local() = i; + + int local_epoch; + tbb::task::suspend(EpochSuspendBody(async, global_epoch, local_epoch)); + ASSERT(local_epoch < global_epoch, NULL); + ASSERT(ets_fiber.local() == i, NULL); + + tbb::parallel_for(0, N, [&](int) { + int local_epoch2; + tbb::task::suspend(EpochSuspendBody(async, global_epoch, local_epoch2)); + ASSERT(local_epoch2 < global_epoch, NULL); + ++inner_par_iters; + }); + + ets_fiber.local() = i; + tbb::task::suspend(EpochSuspendBody(async, global_epoch, local_epoch)); + ASSERT(local_epoch < global_epoch, NULL); + ASSERT(ets_fiber.local() == i, NULL); + } + ++outer_par_iters; + }); + ASSERT(outer_par_iters == N, NULL); + ASSERT(inner_par_iters == N*N*100, NULL); +} + +// During cleanup master's local task pool may +// e.g. contain proxies of affinitized tasks, but can be recalled +void TestCleanupMaster() { + AsyncActivity asyncActivity(4); + tbb::task_group tg; + tbb::enumerable_thread_specific<int> ets; + tbb::atomic<int> iter_spawned; + tbb::atomic<int> iter_executed; + + for (int i = 0; i < 100; i++) { + ets.local() = i; + iter_spawned = 0; + iter_executed = 0; + + NativeParallelFor(N, [&asyncActivity, &tg, &iter_spawned, &iter_executed](int j) { + tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred); + if (tbb::task_scheduler_init::default_num_threads() == 1) { + init.initialize(2); + } + for (int k = 0; k < j*10 + 1; ++k) { + tg.run([&asyncActivity, j, &iter_executed] { + for (volatile int l = 0; l < j*10; ++l) {} + tbb::task::suspend(SuspendBody(asyncActivity)); + iter_executed++; + }); + iter_spawned++; + } + }); + ASSERT(iter_spawned == 460, NULL); + tg.wait(); + ASSERT(iter_executed == 460, NULL); + ASSERT(ets.local() == i, NULL); + } +} + +class ParForSuspendBody { + AsyncActivity& asyncActivity; + int m_numIters; +public: + ParForSuspendBody(AsyncActivity& a_, int iters) : asyncActivity(a_), m_numIters(iters) {} + void operator()(int) const { + for (volatile int i = 0; i < m_numIters; ++i) {} + tbb::task::suspend(SuspendBody(asyncActivity)); + } +}; + +#if __TBB_TASK_PRIORITY +class InnerParFor { + AsyncActivity& asyncActivity; +public: + InnerParFor(AsyncActivity& a_) : asyncActivity(a_) {} + void operator()(int) const { + tbb::affinity_partitioner ap; + tbb::task_group_context ctx; + ctx.set_priority(tbb::priority_high); + tbb::parallel_for(0, 10, ParForSuspendBody(asyncActivity, 1000), ap, ctx); + } +}; + +void TestPriorities() { + AsyncActivity asyncActivity(4); + + tbb::task_scheduler_init init; + tbb::affinity_partitioner ap; + tbb::enumerable_thread_specific<int> ets; + for (int i = 0; i < 10; ++i) { + ets.local() = i; + tbb::parallel_for(0, 10, InnerParFor(asyncActivity), ap); + ASSERT(ets.local() == i, NULL); + } +} +#endif + +void TestNativeThread() { + AsyncActivity asyncActivity(4); + + int num_threads = tbb::task_scheduler_init::default_num_threads(); + tbb::task_arena arena(num_threads); + tbb::task_group tg; + tbb::atomic<int> iter = 0; + NativeParallelFor(num_threads / 2, [&arena, &tg, &asyncActivity, &iter](int){ + for (int i = 0; i < 10; i++) { + arena.execute([&tg, &asyncActivity, &iter]() { + tg.run([&asyncActivity]() { + tbb::task::suspend(SuspendBody(asyncActivity)); + }); + iter++; + }); + } + }); + + tbb::enumerable_thread_specific<bool> ets; + ets.local() = true; + ASSERT(iter == (num_threads / 2) * 10, NULL); + arena.execute([&tg](){ + tg.wait(); + }); + ASSERT(ets.local() == true, NULL); +} + +class ObserverTracker : public tbb::task_scheduler_observer { + tbb::enumerable_thread_specific<bool> is_in_arena; +public: + tbb::atomic<int> counter; + + ObserverTracker(tbb::task_arena& a) : tbb::task_scheduler_observer(a) { + counter = 0; + observe(true); + } + void on_scheduler_entry(bool) __TBB_override { + bool& l = is_in_arena.local(); + ASSERT(l == false, "The thread must call on_scheduler_entry only one time."); + l = true; + ++counter; + } + void on_scheduler_exit(bool) __TBB_override { + bool& l = is_in_arena.local(); + ASSERT(l == true, "The thread must call on_scheduler_entry before calling on_scheduler_exit."); + l = false; + } +}; + +void TestObservers() { + tbb::task_arena arena; + ObserverTracker tracker(arena); + do { + arena.execute([] { + tbb::parallel_for(0, 10, [](int) { + tbb::task::suspend([](tbb::task::suspend_point tag) { + tbb::task::resume(tag); + }); + }, tbb::simple_partitioner()); + }); + } while (tracker.counter < 100); + tracker.observe(false); +} +#endif + +int TestMain() { + tbb::enumerable_thread_specific<bool> ets; + ets.local() = true; + + tbb::task_scheduler_init init(max(tbb::task_scheduler_init::default_num_threads(), 16)); + + TestNestedArena(); +#if __TBB_CPP11_LAMBDAS_PRESENT + // Using functors would make this test much bigger and with + // unnecessary complexity, one C++03 TestNestedArena is enough + TestSuspendResume(); + TestCleanupMaster(); +#if __TBB_TASK_PRIORITY + TestPriorities(); +#endif + TestNativeThread(); + TestObservers(); +#endif + ASSERT(ets.local() == true, NULL); + return Harness::Done; +} + +#endif // !__TBB_PREVIEW_RESUMABLE_TASKS + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_runtime_loader.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_runtime_loader.cpp new file mode 100644 index 00000000..b0eba537 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_runtime_loader.cpp @@ -0,0 +1,281 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +#if !(_WIN32||_WIN64) || (__MINGW64__||__MINGW32__) || __TBB_WIN8UI_SUPPORT + +#include "harness.h" + +int TestMain () { + return Harness::Skipped; +} + +#else // !(_WIN32||_WIN64) + +#define TBB_PREVIEW_RUNTIME_LOADER 1 +#include "tbb/runtime_loader.h" +#include "tbb/tbb_stddef.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tbb_exception.h" + +#include <cstdio> +#include <cstdlib> +#include <cerrno> +#include <vector> +#include <string> +#include <utility> +#include <typeinfo> +#include <stdexcept> + +#ifdef HARNESS_USE_RUNTIME_LOADER + #undef HARNESS_USE_RUNTIME_LOADER // We do not want harness to preload TBB. +#endif +#include "harness.h" + +static int errors = 0; + +#define CHECK( cond ) { \ + if ( ! (cond) ) { \ + ++ errors; \ + REPORT( "%s:%d: --- TEST FAILED ---\n", __FILE__, __LINE__ ); \ + }; \ +} + +#define SAY( msg ) \ + REMARK( "%s:%d: %s\n", __FILE__, __LINE__, msg ) + +typedef int (*int_func_t)(); + +namespace tbb { +namespace interface6 { +namespace internal { +namespace runtime_loader { + extern tbb::runtime_loader::error_mode stub_mode; +} } } } // namespaces runtime_loader, internal, interface6, tbb + +using tbb::interface6::internal::runtime_loader::stub_mode; + +#define _CHECK_TBB( code ) { \ + stub_mode = tbb::runtime_loader::em_status; \ + int ver = tbb::TBB_runtime_interface_version(); \ + stub_mode = tbb::runtime_loader::em_abort; \ + CHECK( ver == code ); \ +} + +#define CHECK_TBB_IS_LOADED() \ + _CHECK_TBB( TBB_INTERFACE_VERSION ) + +#define CHECK_TBB_IS_NOT_LOADED() \ + _CHECK_TBB( tbb::runtime_loader::ec_no_lib ) + +int TestMain() { + + + __TBB_TRY { + + { + SAY( "Call a function when library is not yet loaded, stub should return a error." ); + CHECK_TBB_IS_NOT_LOADED(); + } + + { + SAY( "Create a runtime_loader object, do not load library but make some bad calls." ); + tbb::runtime_loader rtl( tbb::runtime_loader::em_status ); + SAY( "After creating status should be ok." ); + CHECK( rtl.status() == tbb::runtime_loader::ec_ok ); + SAY( "Call a function, stub should return a error." ); + CHECK_TBB_IS_NOT_LOADED(); + } + + { + SAY( "Create a runtime_loader object and call load() with bad arguments." ); + char const * path[] = { ".", NULL }; + tbb::runtime_loader rtl( tbb::runtime_loader::em_status ); + SAY( "Min version is bad." ); + rtl.load( path, -1 ); + CHECK( rtl.status() == tbb::runtime_loader::ec_bad_arg ); + SAY( "Max version is bad." ); + rtl.load( path, TBB_INTERFACE_VERSION, -1 ); + CHECK( rtl.status() == tbb::runtime_loader::ec_bad_arg ); + SAY( "Both versions are bad." ); + rtl.load( path, -1, -1 ); + CHECK( rtl.status() == tbb::runtime_loader::ec_bad_arg ); + SAY( "Min is bigger than max." ); + rtl.load( path, TBB_INTERFACE_VERSION + 1, TBB_INTERFACE_VERSION - 1 ); + CHECK( rtl.status() == tbb::runtime_loader::ec_bad_arg ); + } + + { + SAY( "Create a proxy object and call load() with good arguments but not available version." ); + char const * path[] = { ".", NULL }; + tbb::runtime_loader rtl( tbb::runtime_loader::em_status ); + SAY( "Min version too big." ); + rtl.load( path, TBB_INTERFACE_VERSION + 1, TBB_INTERFACE_VERSION + 1 ); + CHECK( rtl.status() == tbb::runtime_loader::ec_no_lib ); + SAY( "Max version is too small." ); + rtl.load( path, TBB_INTERFACE_VERSION - 1, TBB_INTERFACE_VERSION - 1 ); + CHECK( rtl.status() == tbb::runtime_loader::ec_no_lib ); + } + + { + SAY( "Test em_throw mode." ); + char const * path[] = { ".", NULL }; + tbb::runtime_loader rtl( tbb::runtime_loader::em_throw ); + tbb::runtime_loader::error_code code = tbb::runtime_loader::ec_ok; + __TBB_TRY { + rtl.load( path, -1 ); + } __TBB_CATCH ( tbb::runtime_loader::error_code c ) { + code = c; + }; // __TBB_TRY + CHECK( code == tbb::runtime_loader::ec_bad_arg ); + __TBB_TRY { + rtl.load( path, TBB_INTERFACE_VERSION + 1 ); + } __TBB_CATCH ( tbb::runtime_loader::error_code c ) { + code = c; + }; // __TBB_TRY + CHECK( code == tbb::runtime_loader::ec_no_lib ); + } + + { + SAY( "Load current version, but specify wrong directories." ); + tbb::runtime_loader rtl( tbb::runtime_loader::em_status ); + SAY( "Specify no directories." ); + char const * path0[] = { NULL }; + rtl.load( path0 ); + CHECK( rtl.status() == tbb::runtime_loader::ec_no_lib ); + SAY( "Specify directories without library." ); + char const * path1[] = { "..", "/", NULL }; + rtl.load( path1 ); + CHECK( rtl.status() == tbb::runtime_loader::ec_no_lib ); + } + + { + SAY( "Now really load library and do various tests." ); + char const * path[] = { ".", NULL }; + tbb::runtime_loader rtl( tbb::runtime_loader::em_status ); + SAY( "Load current version." ); + rtl.load( path, TBB_INTERFACE_VERSION, TBB_INTERFACE_VERSION ); + CHECK( rtl.status() == tbb::runtime_loader::ec_ok ); + if ( rtl.status() == tbb::runtime_loader::ec_ok ) { + { + SAY( "Make sure the library really loaded." ); + CHECK_TBB_IS_LOADED(); + } + SAY( "Call load() again, it should return a error." ); + rtl.load( path, TBB_INTERFACE_VERSION, TBB_INTERFACE_VERSION ); + CHECK( rtl.status() == tbb::runtime_loader::ec_bad_call ); + { + SAY( "Initialize task_scheduler." ); + tbb::task_scheduler_init init( 1 ); + // Check what? + } + + // There was a problem on Linux* OS, and still a problem on macOS*. + SAY( "Throw an exception." ); + // Iterate through all the ids first. + for ( int id = 1; id < tbb::internal::eid_max; ++ id ) { + bool ex_caught = false; + __TBB_TRY { + tbb::internal::throw_exception( tbb::internal::exception_id( id ) ); + } __TBB_CATCH ( std::exception const & ) { + SAY( "Expected exception caught." ); + ex_caught = true; + } __TBB_CATCH ( ... ) { + SAY( "Unexpected exception caught." ); + }; // try + CHECK( ex_caught ); + }; // for + // Now try to catch exceptions of specific types. + #define CHECK_EXCEPTION( id, type ) \ + { \ + SAY( "Trowing " #id " exception of " #type " type..." ); \ + bool ex_caught = false; \ + __TBB_TRY { \ + tbb::internal::throw_exception( tbb::internal::id ); \ + } __TBB_CATCH ( type const & ) { \ + SAY( #type " exception caught." ); \ + ex_caught = true; \ + } __TBB_CATCH ( ... ) { \ + SAY( "Unexpected exception caught." ); \ + }; /* try */ \ + CHECK( ex_caught ); \ + } + CHECK_EXCEPTION( eid_bad_alloc, std::bad_alloc ); + CHECK_EXCEPTION( eid_bad_last_alloc, tbb::bad_last_alloc ); + CHECK_EXCEPTION( eid_nonpositive_step, std::invalid_argument ); + CHECK_EXCEPTION( eid_out_of_range, std::out_of_range ); + CHECK_EXCEPTION( eid_segment_range_error, std::range_error ); + CHECK_EXCEPTION( eid_missing_wait, tbb::missing_wait ); + CHECK_EXCEPTION( eid_invalid_multiple_scheduling, tbb::invalid_multiple_scheduling ); + CHECK_EXCEPTION( eid_improper_lock, tbb::improper_lock ); + CHECK_EXCEPTION( eid_possible_deadlock, std::runtime_error ); + CHECK_EXCEPTION( eid_reservation_length_error, std::length_error ); + CHECK_EXCEPTION( eid_user_abort, tbb::user_abort ); + #undef CHECK_EXCEPTION + { + bool ex_caught = false; + __TBB_TRY { + tbb::internal::handle_perror( EAGAIN, "apple" ); + } __TBB_CATCH ( std::runtime_error const & ) { + SAY( "Expected exception caught." ); + ex_caught = true; + } __TBB_CATCH ( ... ) { + SAY( "Unexpected exception caught." ); + }; // try + CHECK( ex_caught ); + } + }; // if + } + + { + SAY( "Test multiple proxies." ); + char const * path[] = { ".", NULL }; + tbb::runtime_loader rtl0( tbb::runtime_loader::em_status ); + tbb::runtime_loader rtl1( tbb::runtime_loader::em_status ); + CHECK( rtl0.status() == tbb::runtime_loader::ec_ok ); + CHECK( rtl1.status() == tbb::runtime_loader::ec_ok ); + SAY( "Load current version with the first rtl." ); + rtl0.load( path ); + CHECK( rtl0.status() == tbb::runtime_loader::ec_ok ); + CHECK_TBB_IS_LOADED(); + SAY( "Load another version with the second proxy, it should return a error." ); + rtl1.load( path, TBB_INTERFACE_VERSION + 1 ); + CHECK( rtl1.status() == tbb::runtime_loader::ec_bad_ver ); + SAY( "Load the same version with the second proxy, it should return ok." ); + rtl1.load( path ); + CHECK( rtl1.status() == tbb::runtime_loader::ec_ok ); + CHECK_TBB_IS_LOADED(); + } + + } __TBB_CATCH( ... ) { + + ASSERT( 0, "unexpected exception" ); + + }; // __TBB_TRY + + if ( errors > 0 ) { + REPORT( "Some tests failed.\n" ); + exit( 1 ); + }; // if + + return Harness::Done; + +} // main + +#endif // !(_WIN32||_WIN64) + +// end of file // diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_rwm_upgrade_downgrade.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_rwm_upgrade_downgrade.cpp new file mode 100644 index 00000000..cb7faca4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_rwm_upgrade_downgrade.cpp @@ -0,0 +1,70 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS 4 +#define HARNESS_DEFAULT_MAX_THREADS 4 + +#include "tbb/queuing_rw_mutex.h" +#include "tbb/spin_rw_mutex.h" +#include "harness.h" + +using namespace tbb; + +volatile int Count; + +template<typename RWMutex> +struct Hammer: NoAssign { + RWMutex &MutexProtectingCount; + mutable volatile int dummy; + + Hammer(RWMutex &m): MutexProtectingCount(m) {} + void operator()( int /*thread_id*/ ) const { + for( int j=0; j<100000; ++j ) { + typename RWMutex::scoped_lock lock(MutexProtectingCount,false); + int c = Count; + for( int k=0; k<10; ++k ) { + ++dummy; + } + if( lock.upgrade_to_writer() ) { + // The upgrade succeeded without any intervening writers + ASSERT( c==Count, "another thread modified Count while I held a read lock" ); + } else { + c = Count; + } + for( int k=0; k<10; ++k ) { + ++Count; + } + lock.downgrade_to_reader(); + for( int k=0; k<10; ++k ) { + ++dummy; + } + } + } +}; + +queuing_rw_mutex QRW_mutex; +spin_rw_mutex SRW_mutex; + +int TestMain () { + for( int p=MinThread; p<=MaxThread; ++p ) { + REMARK("Testing on %d threads", p); + Count = 0; + NativeParallelFor( p, Hammer<queuing_rw_mutex>(QRW_mutex) ); + Count = 0; + NativeParallelFor( p, Hammer<spin_rw_mutex>(SRW_mutex) ); + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_semaphore.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_semaphore.cpp new file mode 100644 index 00000000..8982a8a0 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_semaphore.cpp @@ -0,0 +1,311 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// +// Test for counting semaphore. +// +// set semaphore to N +// create N + M threads +// have each thread +// A. P() +// B. increment atomic count +// C. spin for awhile checking the value of the count; make sure it doesn't exceed N +// D. decrement atomic count +// E. V() +// + +#include "../tbb/semaphore.h" +#include "tbb/atomic.h" +#include "tbb/blocked_range.h" + +#include <vector> +using std::vector; + +#include "harness_assert.h" +#include "harness.h" + +using tbb::internal::semaphore; + +#include "harness_barrier.h" + +tbb::atomic<int> pCount; + +Harness::SpinBarrier sBarrier; + +#include "tbb/tick_count.h" +// semaphore basic function: +// set semaphore to initial value +// see that semaphore only allows that number of threads to be active +class Body: NoAssign { + const int nIters; + tbb::internal::semaphore &mySem; + vector<int> &ourCounts; + vector<double> &tottime; + static const int tickCounts = 1; // millisecond + static const int innerWait = 5; // millisecond +public: + Body(int nThread_, int nIter_, semaphore &mySem_, + vector<int>& ourCounts_, + vector<double>& tottime_ + ) : nIters(nIter_), mySem(mySem_), ourCounts(ourCounts_), tottime(tottime_) { sBarrier.initialize(nThread_); pCount = 0; } +void operator()(const int tid) const { + sBarrier.wait(); + for(int i=0; i < nIters; ++i) { + Harness::Sleep( tid * tickCounts ); + tbb::tick_count t0 = tbb::tick_count::now(); + mySem.P(); + tbb::tick_count t1 = tbb::tick_count::now(); + tottime[tid] += (t1-t0).seconds(); + int curval = ++pCount; + if(curval > ourCounts[tid]) ourCounts[tid] = curval; + Harness::Sleep( innerWait ); + --pCount; + ASSERT((int)pCount >= 0, NULL); + mySem.V(); + } +} +}; + + +void testSemaphore( int semInitCnt, int extraThreads ) { + semaphore my_sem(semInitCnt); + // tbb::task_scheduler_init init(tbb::task_scheduler_init::deferred); + int nThreads = semInitCnt + extraThreads; + vector<int> maxVals(nThreads); + vector<double> totTimes(nThreads); + int nIters = 10; + Body myBody(nThreads, nIters, my_sem, maxVals, totTimes); + + REMARK( " sem(%d) with %d extra threads\n", semInitCnt, extraThreads); + pCount = 0; + NativeParallelFor(nThreads, myBody); + if(extraThreads == 0) { + double allPWaits = 0; + for(vector<double>::const_iterator j = totTimes.begin(); j != totTimes.end(); ++j) { + allPWaits += *j; + } + allPWaits /= static_cast<double>(nThreads * nIters); + REMARK("Average wait for P() in uncontested case for nThreads = %d is %g\n", nThreads, allPWaits); + } + ASSERT(!pCount, "not all threads decremented pCount"); + int maxCount = -1; + for(vector<int>::const_iterator i=maxVals.begin(); i!= maxVals.end();++i) { + maxCount = max(maxCount,*i); + } + ASSERT(maxCount <= semInitCnt,"too many threads in semaphore-protected increment"); + if(maxCount < semInitCnt) { + REMARK("Not enough threads in semaphore-protected region (%d < %d)\n", static_cast<int>(maxCount), semInitCnt); + } +} + +#include "../tbb/semaphore.cpp" +#if _WIN32||_WIN64 +#include "../tbb/dynamic_link.cpp" + +void testOSVersion() { +#if __TBB_USE_SRWLOCK + BOOL bIsWindowsVistaOrLater; +#if __TBB_WIN8UI_SUPPORT + bIsWindowsVistaOrLater = true; +#else + OSVERSIONINFO osvi; + + memset( (void*)&osvi, 0, sizeof(OSVERSIONINFO) ); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + bIsWindowsVistaOrLater = (osvi.dwMajorVersion >= 6 ); +#endif + + if( bIsWindowsVistaOrLater ) { + REMARK("Checking SRWLock is loaded\n"); + tbb::internal::binary_semaphore s; + ASSERT( (uintptr_t)tbb::internal::__TBB_init_binsem!=(uintptr_t)&tbb::internal::init_binsem_using_event, NULL ); + ASSERT( (uintptr_t)tbb::internal::__TBB_acquire_binsem!=(uintptr_t)&tbb::internal::acquire_binsem_using_event, NULL ); + ASSERT( (uintptr_t)tbb::internal::__TBB_release_binsem!=(uintptr_t)&tbb::internal::release_binsem_using_event, NULL ); + } +#endif /* __TBB_USE_SRWLOCK */ +} +#endif /* _WIN32||_WIN64 */ + +#define N_TIMES 1000 + +template<typename S> +struct Counter { + volatile long value; + S my_sem; + Counter() : value(0) {} +}; + +//! Function object for use with parallel_for.h. +template<typename C> +struct AddOne: NoAssign { + C& my_counter; + /** Increments counter once for each iteration in the iteration space. */ + void operator()( int /*tid*/ ) const { + for( size_t i=0; i<N_TIMES; ++i ) { + my_counter.my_sem.P(); + my_counter.value = my_counter.value + 1; + my_counter.my_sem.V(); + } + } + AddOne( C& c_ ) : my_counter(c_) { my_counter.my_sem.V(); } +}; + +void testBinarySemaphore( int nThreads ) { + REMARK("Testing binary semaphore\n"); + Counter<tbb::internal::binary_semaphore> counter; + AddOne<Counter<tbb::internal::binary_semaphore> > myAddOne(counter); + NativeParallelFor( nThreads, myAddOne ); + ASSERT( nThreads*N_TIMES==counter.value, "Binary semaphore operations P()/V() have a race"); +} + +// Power of 2, the most tokens that can be in flight. +#define MAX_TOKENS 32 +enum FilterType { imaProducer, imaConsumer }; +class FilterBase : NoAssign { +protected: + FilterType ima; + unsigned totTokens; // total number of tokens to be emitted, only used by producer + tbb::atomic<unsigned>& myTokens; + tbb::atomic<unsigned>& otherTokens; + unsigned myWait; + semaphore &mySem; + semaphore &nextSem; + unsigned* myBuffer; + unsigned* nextBuffer; + unsigned curToken; +public: + FilterBase( FilterType ima_ + ,unsigned totTokens_ + ,tbb::atomic<unsigned>& myTokens_ + ,tbb::atomic<unsigned>& otherTokens_ + ,unsigned myWait_ + ,semaphore &mySem_ + ,semaphore &nextSem_ + ,unsigned* myBuffer_ + ,unsigned* nextBuffer_ + ) + : ima(ima_),totTokens(totTokens_),myTokens(myTokens_),otherTokens(otherTokens_),myWait(myWait_),mySem(mySem_), + nextSem(nextSem_),myBuffer(myBuffer_),nextBuffer(nextBuffer_) + { + curToken = 0; + } + void Produce(const int tid); + void Consume(const int tid); + void operator()(const int tid) { if(ima == imaConsumer) Consume(tid); else Produce(tid); } +}; + +class ProduceConsumeBody { + FilterBase** myFilters; + public: + ProduceConsumeBody(FilterBase** myFilters_) : myFilters(myFilters_) {} + void operator()(const int tid) const { + myFilters[tid]->operator()(tid); + } +}; + +// send a bunch of non-Null "tokens" to consumer, then a NULL. +void FilterBase::Produce(const int /*tid*/) { + nextBuffer[0] = 0; // just in case we provide no tokens + sBarrier.wait(); + while(totTokens) { + while(!myTokens) + mySem.P(); + // we have a slot available. + --myTokens; // moving this down reduces spurious wakeups + --totTokens; + if(totTokens) + nextBuffer[curToken&(MAX_TOKENS-1)] = curToken*3+1; + else + nextBuffer[curToken&(MAX_TOKENS-1)] = 0; + ++curToken; + Harness::Sleep(myWait); + unsigned temp = ++otherTokens; + if(temp == 1) + nextSem.V(); + } + nextSem.V(); // final wakeup +} + +void FilterBase::Consume(const int /*tid*/) { + unsigned myToken; + sBarrier.wait(); + do { + while(!myTokens) + mySem.P(); + // we have a slot available. + --myTokens; // moving this down reduces spurious wakeups + myToken = myBuffer[curToken&(MAX_TOKENS-1)]; + if(myToken) { + ASSERT(myToken == curToken*3+1, "Error in received token"); + ++curToken; + Harness::Sleep(myWait); + unsigned temp = ++otherTokens; + if(temp == 1) + nextSem.V(); + } + } while(myToken); + // end of processing + ASSERT(curToken + 1 == totTokens, "Didn't receive enough tokens"); +} + +// -- test of producer/consumer with atomic buffer cnt and semaphore +// nTokens are total number of tokens through the pipe +// pWait is the wait time for the producer +// cWait is the wait time for the consumer +void testProducerConsumer( unsigned totTokens, unsigned nTokens, unsigned pWait, unsigned cWait) { + semaphore pSem; + semaphore cSem; + tbb::atomic<unsigned> pTokens; + tbb::atomic<unsigned> cTokens; + cTokens = 0; + unsigned cBuffer[MAX_TOKENS]; + FilterBase* myFilters[2]; // one producer, one consumer + REMARK("Testing producer/consumer with %lu total tokens, %lu tokens at a time, producer wait(%lu), consumer wait (%lu)\n", totTokens, nTokens, pWait, cWait); + ASSERT(nTokens <= MAX_TOKENS, "Not enough slots for tokens"); + myFilters[0] = new FilterBase(imaProducer, totTokens, pTokens, cTokens, pWait, cSem, pSem, (unsigned *)NULL, &(cBuffer[0])); + myFilters[1] = new FilterBase(imaConsumer, totTokens, cTokens, pTokens, cWait, pSem, cSem, cBuffer, (unsigned *)NULL); + pTokens = nTokens; + ProduceConsumeBody myBody(myFilters); + sBarrier.initialize(2); + NativeParallelFor(2, myBody); + delete myFilters[0]; + delete myFilters[1]; +} + +int TestMain() { + REMARK("Started\n"); +#if _WIN32||_WIN64 + testOSVersion(); +#endif + if(MaxThread > 0) { + testBinarySemaphore( MaxThread ); + for(int semSize = 1; semSize <= MaxThread; ++semSize) { + for(int exThreads = 0; exThreads <= MaxThread - semSize; ++exThreads) { + testSemaphore( semSize, exThreads ); + } + } + } + // Test producer/consumer with varying execution times and buffer sizes + // ( total tokens, tokens in buffer, sleep for producer, sleep for consumer ) + testProducerConsumer( 10, 2, 5, 5 ); + testProducerConsumer( 10, 2, 20, 5 ); + testProducerConsumer( 10, 2, 5, 20 ); + testProducerConsumer( 10, 1, 5, 5 ); + testProducerConsumer( 20, 10, 5, 20 ); + testProducerConsumer( 64, 32, 1, 20 ); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_sequencer_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_sequencer_node.cpp new file mode 100644 index 00000000..e2f7d4c1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_sequencer_node.cpp @@ -0,0 +1,464 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_ALLOCATOR __TBB_CPF_BUILD + +#include "harness.h" +#include "harness_graph.h" + +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" +#include "tbb/atomic.h" +#include "test_follows_and_precedes_api.h" + +#include <cstdio> + +#define N 1000 +#define C 10 + +template< typename T > +struct seq_inspector { + size_t operator()(const T &v) const { return size_t(v); } +}; + +template< typename T > +bool wait_try_get( tbb::flow::graph &g, tbb::flow::sequencer_node<T> &q, T &value ) { + g.wait_for_all(); + return q.try_get(value); +} + +template< typename T > +void spin_try_get( tbb::flow::queue_node<T> &q, T &value ) { + while ( q.try_get(value) != true ) ; +} + +template< typename T > +struct parallel_puts : NoAssign { + + tbb::flow::sequencer_node<T> &my_q; + int my_num_threads; + + parallel_puts( tbb::flow::sequencer_node<T> &q, int num_threads ) : my_q(q), my_num_threads(num_threads) {} + + void operator()(int tid) const { + for (int j = tid; j < N; j+=my_num_threads) { + bool msg = my_q.try_put( T(j) ); + ASSERT( msg == true, NULL ); + } + } + +}; + +template< typename T > +struct touches { + + bool **my_touches; + T *my_last_touch; + int my_num_threads; + + touches( int num_threads ) : my_num_threads(num_threads) { + my_last_touch = new T[my_num_threads]; + my_touches = new bool* [my_num_threads]; + for ( int p = 0; p < my_num_threads; ++p) { + my_last_touch[p] = T(-1); + my_touches[p] = new bool[N]; + for ( int n = 0; n < N; ++n) + my_touches[p][n] = false; + } + } + + ~touches() { + for ( int p = 0; p < my_num_threads; ++p) { + delete [] my_touches[p]; + } + delete [] my_touches; + delete [] my_last_touch; + } + + bool check( int tid, T v ) { + if ( my_touches[tid][v] != false ) { + printf("Error: value seen twice by local thread\n"); + return false; + } + if ( v <= my_last_touch[tid] ) { + printf("Error: value seen in wrong order by local thread\n"); + return false; + } + my_last_touch[tid] = v; + my_touches[tid][v] = true; + return true; + } + + bool validate_touches() { + bool *all_touches = new bool[N]; + for ( int n = 0; n < N; ++n) + all_touches[n] = false; + + for ( int p = 0; p < my_num_threads; ++p) { + for ( int n = 0; n < N; ++n) { + if ( my_touches[p][n] == true ) { + ASSERT( all_touches[n] == false, "value see by more than one thread\n" ); + all_touches[n] = true; + } + } + } + for ( int n = 0; n < N; ++n) { + if ( !all_touches[n] ) + printf("No touch at %d, my_num_threads = %d\n", n, my_num_threads); + //ASSERT( all_touches[n] == true, "value not seen by any thread\n" ); + } + delete [] all_touches; + return true; + } + +}; + +template< typename T > +struct parallel_gets : NoAssign { + + tbb::flow::sequencer_node<T> &my_q; + int my_num_threads; + touches<T> &my_touches; + + parallel_gets( tbb::flow::sequencer_node<T> &q, int num_threads, touches<T> &t ) : my_q(q), my_num_threads(num_threads), my_touches(t) {} + + void operator()(int tid) const { + for (int j = tid; j < N; j+=my_num_threads) { + T v; + spin_try_get( my_q, v ); + my_touches.check( tid, v ); + } + } + +}; + +template< typename T > +struct parallel_put_get : NoAssign { + + tbb::flow::sequencer_node<T> &my_s1; + tbb::flow::sequencer_node<T> &my_s2; + int my_num_threads; + tbb::atomic< int > &my_counter; + touches<T> &my_touches; + + parallel_put_get( tbb::flow::sequencer_node<T> &s1, tbb::flow::sequencer_node<T> &s2, int num_threads, + tbb::atomic<int> &counter, touches<T> &t ) : my_s1(s1), my_s2(s2), my_num_threads(num_threads), my_counter(counter), my_touches(t) {} + + void operator()(int tid) const { + int i_start = 0; + + while ( (i_start = my_counter.fetch_and_add(C)) < N ) { + int i_end = ( N < i_start + C ) ? N : i_start + C; + for (int i = i_start; i < i_end; ++i) { + bool msg = my_s1.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + for (int i = i_start; i < i_end; ++i) { + T v; + spin_try_get( my_s2, v ); + my_touches.check( tid, v ); + } + } + } + +}; + +// +// Tests +// +// multiple parallel senders, multiple receivers, properly sequenced (relative to receiver) at output +// chained sequencers, multiple parallel senders, multiple receivers, properly sequenced (relative to receiver) at output +// + +template< typename T > +int test_parallel(int num_threads) { + tbb::flow::graph g; + + tbb::flow::sequencer_node<T> s(g, seq_inspector<T>()); + NativeParallelFor( num_threads, parallel_puts<T>(s, num_threads) ); + { + touches<T> t( num_threads ); + NativeParallelFor( num_threads, parallel_gets<T>(s, num_threads, t) ); + g.wait_for_all(); + ASSERT( t.validate_touches(), NULL ); + } + T bogus_value(-1); + T j = bogus_value; + ASSERT( s.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + g.wait_for_all(); + + tbb::flow::sequencer_node<T> s1(g, seq_inspector<T>()); + tbb::flow::sequencer_node<T> s2(g, seq_inspector<T>()); + tbb::flow::sequencer_node<T> s3(g, seq_inspector<T>()); + tbb::flow::make_edge( s1, s2 ); + tbb::flow::make_edge( s2, s3 ); + + { + touches<T> t( num_threads ); + tbb::atomic<int> counter; + counter = 0; + NativeParallelFor( num_threads, parallel_put_get<T>(s1, s3, num_threads, counter, t) ); + g.wait_for_all(); + t.validate_touches(); + } + g.wait_for_all(); + ASSERT( s1.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( s2.try_get( j ) == false, NULL ); + g.wait_for_all(); + ASSERT( s3.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // test copy constructor + tbb::flow::sequencer_node<T> s_copy(s); + NativeParallelFor( num_threads, parallel_puts<T>(s_copy, num_threads) ); + for (int i = 0; i < N; ++i) { + j = bogus_value; + spin_try_get( s_copy, j ); + ASSERT( i == j, NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( s_copy.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + return 0; +} + + +// +// Tests +// +// No predecessors can be registered +// Request from empty buffer fails +// In-order puts, single sender, single receiver, properly sequenced at output +// Reverse-order puts, single sender, single receiver, properly sequenced at output +// Chained sequencers (3), in-order and reverse-order tests, properly sequenced at output +// + +template< typename T > +int test_serial() { + tbb::flow::graph g; + T bogus_value(-1); + + tbb::flow::sequencer_node<T> s(g, seq_inspector<T>()); + tbb::flow::sequencer_node<T> s2(g, seq_inspector<T>()); + T j = bogus_value; + + // + // Rejects attempts to add / remove predecessor + // Rejects request from empty Q + // + ASSERT( s.register_predecessor( s2 ) == false, NULL ); + ASSERT( s.remove_predecessor( s2 ) == false, NULL ); + ASSERT( s.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // + // In-order simple puts and gets + // + + for (int i = 0; i < N; ++i) { + bool msg = s.try_put( T(i) ); + ASSERT( msg == true, NULL ); + ASSERT(!s.try_put( T(i) ), NULL); // second attempt to put should reject + } + + + for (int i = 0; i < N; ++i) { + j = bogus_value; + ASSERT(wait_try_get( g, s, j ) == true, NULL); + ASSERT( i == j, NULL ); + ASSERT(!s.try_put( T(i) ),NULL ); // after retrieving value, subsequent put should fail + } + j = bogus_value; + g.wait_for_all(); + ASSERT( s.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // + // Reverse-order simple puts and gets + // + + for (int i = N-1; i >= 0; --i) { + bool msg = s2.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + for (int i = 0; i < N; ++i) { + j = bogus_value; + ASSERT(wait_try_get( g, s2, j ) == true, NULL); + ASSERT( i == j, NULL ); + } + j = bogus_value; + g.wait_for_all(); + ASSERT( s2.try_get( j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + // + // Chained in-order simple puts and gets + // + + tbb::flow::sequencer_node<T> s3(g, seq_inspector<T>()); + tbb::flow::sequencer_node<T> s4(g, seq_inspector<T>()); + tbb::flow::sequencer_node<T> s5(g, seq_inspector<T>()); + tbb::flow::make_edge( s3, s4 ); + tbb::flow::make_edge( s4, s5 ); + + for (int i = 0; i < N; ++i) { + bool msg = s3.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + for (int i = 0; i < N; ++i) { + j = bogus_value; + ASSERT(wait_try_get( g, s5, j ) == true, NULL); + ASSERT( i == j, NULL ); + } + j = bogus_value; + ASSERT( wait_try_get( g, s3, j ) == false, NULL ); + ASSERT( wait_try_get( g, s4, j ) == false, NULL ); + ASSERT( wait_try_get( g, s5, j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + g.wait_for_all(); + tbb::flow::remove_edge( s3, s4 ); + ASSERT( s3.try_put( N ) == true, NULL ); + ASSERT( wait_try_get( g, s4, j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + ASSERT( wait_try_get( g, s5, j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + ASSERT( wait_try_get( g, s3, j ) == true, NULL ); + ASSERT( j == N, NULL ); + + // + // Chained reverse-order simple puts and gets + // + + tbb::flow::sequencer_node<T> s6(g, seq_inspector<T>()); + tbb::flow::sequencer_node<T> s7(g, seq_inspector<T>()); + tbb::flow::sequencer_node<T> s8(g, seq_inspector<T>()); + tbb::flow::make_edge( s6, s7 ); + tbb::flow::make_edge( s7, s8 ); + + for (int i = N-1; i >= 0; --i) { + bool msg = s6.try_put( T(i) ); + ASSERT( msg == true, NULL ); + } + + for (int i = 0; i < N; ++i) { + j = bogus_value; + ASSERT( wait_try_get( g, s8, j ) == true, NULL ); + ASSERT( i == j, NULL ); + } + j = bogus_value; + ASSERT( wait_try_get( g, s6, j ) == false, NULL ); + ASSERT( wait_try_get( g, s7, j ) == false, NULL ); + ASSERT( wait_try_get( g, s8, j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + + g.wait_for_all(); + tbb::flow::remove_edge( s6, s7 ); + ASSERT( s6.try_put( N ) == true, NULL ); + ASSERT( wait_try_get( g, s7, j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + ASSERT( wait_try_get( g, s8, j ) == false, NULL ); + ASSERT( j == bogus_value, NULL ); + ASSERT( wait_try_get( g, s6, j ) == true, NULL ); + ASSERT( j == N, NULL ); + + return 0; +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + std::array<int, 3> messages_for_follows = { {0, 1, 2} }; + std::vector<int> messages_for_precedes = {0, 1, 2}; + + follows_and_precedes_testing::test_follows + <int, tbb::flow::sequencer_node<int>> + (messages_for_follows, [](const int& i) { return i; }); + + follows_and_precedes_testing::test_precedes + <int, tbb::flow::sequencer_node<int>> + (messages_for_precedes, [](const int& i) { return i; }); +} +#endif + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +template <typename Body> +void test_deduction_guides_common(Body body) { + using namespace tbb::flow; + graph g; + broadcast_node<int> br(g); + + sequencer_node s1(g, body); + static_assert(std::is_same_v<decltype(s1), sequencer_node<int>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + sequencer_node s2(follows(br), body); + static_assert(std::is_same_v<decltype(s2), sequencer_node<int>>); +#endif + + sequencer_node s3(s1); + static_assert(std::is_same_v<decltype(s3), sequencer_node<int>>); +} + +int sequencer_body_f(const int&) { return 1; } + +void test_deduction_guides() { + test_deduction_guides_common([](const int&)->int { return 1; }); + test_deduction_guides_common([](const int&) mutable ->int { return 1; }); + test_deduction_guides_common(sequencer_body_f); +} +#endif + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +void test_node_allocator() { + tbb::flow::graph g; + tbb::flow::sequencer_node< int, std::allocator<int> > tmp(g, seq_inspector<int>()); +} +#endif + +int TestMain() { + tbb::tick_count start = tbb::tick_count::now(), stop; + for (int p = 2; p <= 4; ++p) { + tbb::task_scheduler_init init(p); + test_serial<int>(); + test_parallel<int>(p); + } +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_buffer_extract<tbb::flow::sequencer_node<int> >().run_tests(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + test_node_allocator(); +#endif + stop = tbb::tick_count::now(); + REMARK("Sequencer_Node Time=%6.6f\n", (stop-start).seconds()); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_source_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_source_node.cpp new file mode 100644 index 00000000..cfe0359d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_source_node.cpp @@ -0,0 +1,572 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// have to expose the reset_node method to be able to reset a function_body + +#define TBB_USE_SOURCE_NODE_AS_ALIAS __TBB_CPF_BUILD +#define TBB_DEPRECATED_INPUT_NODE_BODY !__TBB_CPF_BUILD + +#include "harness.h" + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#endif + + + +#include "harness_graph.h" +#include "tbb/flow_graph.h" +#include "tbb/task.h" +#include "tbb/task_scheduler_init.h" + +const int N = 1000; + +template< typename T > +class test_push_receiver : public tbb::flow::receiver<T>, NoAssign { + + tbb::atomic<int> my_counters[N]; + tbb::flow::graph& my_graph; + +public: + + test_push_receiver(tbb::flow::graph& g) : my_graph(g) { + for (int i = 0; i < N; ++i ) + my_counters[i] = 0; + } + + int get_count( int i ) { + int v = my_counters[i]; + return v; + } + + typedef typename tbb::flow::receiver<T>::predecessor_type predecessor_type; + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + typedef typename tbb::flow::receiver<T>::built_predecessors_type built_predecessors_type; + typedef typename tbb::flow::receiver<T>::predecessor_list_type predecessor_list_type; + built_predecessors_type bpt; + built_predecessors_type &built_predecessors() __TBB_override { return bpt; } + void internal_add_built_predecessor( predecessor_type & ) __TBB_override { } + void internal_delete_built_predecessor( predecessor_type & ) __TBB_override { } + void copy_predecessors( predecessor_list_type & ) __TBB_override { } + size_t predecessor_count() __TBB_override { return 0; } +#endif + + tbb::task *try_put_task( const T &v ) __TBB_override { + int i = (int)v; + ++my_counters[i]; + return const_cast<tbb::task *>(SUCCESSFULLY_ENQUEUED); + } + + tbb::flow::graph& graph_reference() const __TBB_override { + return my_graph; + } + + void reset_receiver(tbb::flow::reset_flags /*f*/) __TBB_override {} +}; + +template< typename T > +class source_body { + + unsigned my_count; + int *ninvocations; + +public: + + source_body() : ninvocations(NULL) { my_count = 0; } + source_body(int &_inv) : ninvocations(&_inv) { my_count = 0; } + +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()( T &v ) { + v = (T)my_count++; + if(ninvocations) ++(*ninvocations); + if ( (int)v < N ) + return true; + else + return false; + } +#else + T operator()( tbb::flow_control& fc ) { + T v = (T)my_count++; + if(ninvocations) ++(*ninvocations); + if ( (int)v < N ){ + return v; + }else{ + fc.stop(); + return T(); + } + } +#endif + +}; + +template< typename T > +class function_body { + + tbb::atomic<int> *my_counters; + +public: + + function_body( tbb::atomic<int> *counters ) : my_counters(counters) { + for (int i = 0; i < N; ++i ) + my_counters[i] = 0; + } + + bool operator()( T v ) { + ++my_counters[(int)v]; + return true; + } + +}; + +template< typename T > +void test_single_dest() { + + // push only + tbb::flow::graph g; + tbb::flow::source_node<T> src(g, source_body<T>() ); + test_push_receiver<T> dest(g); + tbb::flow::make_edge( src, dest ); +#if TBB_USE_SOURCE_NODE_AS_ALIAS + src.activate(); +#endif + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + ASSERT( dest.get_count(i) == 1, NULL ); + } + + // push only + tbb::atomic<int> counters3[N]; + tbb::flow::source_node<T> src3(g, source_body<T>() ); + function_body<T> b3( counters3 ); + tbb::flow::function_node<T,bool> dest3(g, tbb::flow::unlimited, b3 ); + tbb::flow::make_edge( src3, dest3 ); +#if TBB_USE_SOURCE_NODE_AS_ALIAS + src3.activate(); +#endif + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + } + + // push & pull + tbb::flow::source_node<T> src2(g, source_body<T>() ); + tbb::atomic<int> counters2[N]; + function_body<T> b2( counters2 ); + tbb::flow::function_node<T,bool,tbb::flow::rejecting> dest2(g, tbb::flow::serial, b2 ); + tbb::flow::make_edge( src2, dest2 ); + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + ASSERT(src2.successor_count() == 1, NULL); + typename tbb::flow::source_node<T>::successor_list_type my_succs; + src2.copy_successors(my_succs); + ASSERT(my_succs.size() == 1, NULL); +#endif + +#if TBB_USE_SOURCE_NODE_AS_ALIAS + src2.activate(); +#endif + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters2[i]; + ASSERT( v == 1, NULL ); + } + + // test copy constructor + tbb::flow::source_node<T> src_copy(src); + test_push_receiver<T> dest_c(g); + ASSERT( src_copy.register_successor(dest_c), NULL ); +#if TBB_USE_SOURCE_NODE_AS_ALIAS + src_copy.activate(); +#endif + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + ASSERT( dest_c.get_count(i) == 1, NULL ); + } +} + +void test_reset() { + // source_node -> function_node + tbb::flow::graph g; + tbb::atomic<int> counters3[N]; + tbb::flow::source_node<int> src3(g, source_body<int>() ); +#if TBB_USE_SOURCE_NODE_AS_ALIAS + tbb::flow::source_node<int> src_inactive(g, source_body<int>() ); +#else + tbb::flow::source_node<int> src_inactive(g, source_body<int>(), /*is_active=*/ false ); +#endif + function_body<int> b3( counters3 ); + tbb::flow::function_node<int,bool> dest3(g, tbb::flow::unlimited, b3 ); + tbb::flow::make_edge( src3, dest3 ); + + #if TBB_USE_SOURCE_NODE_AS_ALIAS + src3.activate(); + #endif + // source_node is now in active state. Let the graph run, + g.wait_for_all(); + // check the array for each value. + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + counters3[i] = 0; + } + g.reset(tbb::flow::rf_reset_bodies); // <-- re-initializes the counts. + #if TBB_USE_SOURCE_NODE_AS_ALIAS + src3.activate(); + #endif + // and spawns task to run source + g.wait_for_all(); + // check output queue again. Should be the same contents. + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + counters3[i] = 0; + } + g.reset(); // doesn't reset the source_node_body to initial state, but does spawn a task + // to run the source_node. + + g.wait_for_all(); + // array should be all zero + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } + + remove_edge(src3, dest3); + make_edge(src_inactive, dest3); + + // src_inactive doesn't run + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } + + // run graph + src_inactive.activate(); + g.wait_for_all(); + // check output + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + counters3[i] = 0; + } + g.reset(tbb::flow::rf_reset_bodies); // <-- reinitializes the counts + // src_inactive doesn't run + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } + + // start it up + src_inactive.activate(); + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 1, NULL ); + counters3[i] = 0; + } + g.reset(); // doesn't reset the source_node_body to initial state, and doesn't + // spawn a task to run the source_node. + + g.wait_for_all(); + // array should be all zero + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } + src_inactive.activate(); + // source_node_body is already in final state, so source_node will not forward a message. + g.wait_for_all(); + for (int i = 0; i < N; ++i ) { + int v = counters3[i]; + ASSERT( v == 0, NULL ); + } +} + +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION +void test_extract() { + int counts = 0; + tbb::flow::tuple<int,int> dont_care; + tbb::flow::graph g; + typedef tbb::flow::source_node<int> snode_type; + typedef snode_type::successor_list_type successor_list_type; +#if TBB_USE_SOURCE_NODE_AS_ALIAS + snode_type s0(g, source_body<int>(counts)); +#else + snode_type s0(g, source_body<int>(counts), false); +#endif + tbb::flow::join_node< tbb::flow::tuple<int,int>, tbb::flow::reserving > j0(g); + tbb::flow::join_node< tbb::flow::tuple<int,int>, tbb::flow::reserving > j1(g); + tbb::flow::join_node< tbb::flow::tuple<int,int>, tbb::flow::reserving > j2(g); + tbb::flow::queue_node<int> q0(g); + tbb::flow::queue_node<tbb::flow::tuple<int,int> > q1(g); + tbb::flow::make_edge(s0, tbb::flow::get<0>(j0.input_ports())); + /* s0 ----+ */ + /* | j0 */ + /* + */ + ASSERT(!counts, "source_node activated too soon"); + s0.activate(); + g.wait_for_all(); // should produce one value, buffer it. + ASSERT(counts == 1, "source_node did not react to activation"); + + g.reset(tbb::flow::rf_reset_bodies); + counts = 0; + s0.extract(); + /* s0 + */ + /* | j0 */ + /* + */ + s0.activate(); + g.wait_for_all(); // no successors, so the body will not execute + ASSERT(counts == 0, "source_node shouldn't forward (no successors)"); + g.reset(tbb::flow::rf_reset_bodies); + + tbb::flow::make_edge(s0, tbb::flow::get<0>(j0.input_ports())); + tbb::flow::make_edge(s0, tbb::flow::get<0>(j1.input_ports())); + tbb::flow::make_edge(s0, tbb::flow::get<0>(j2.input_ports())); + + /* /+ */ + /* / | j0 */ + /* / + */ + /* / */ + /* / /--+ */ + /* s0-/ | j1 */ + /* \ + */ + /* \ */ + /* \--+ */ + /* | j2 */ + /* + */ + + // do all joins appear in successor list? + successor_list_type jv1; + jv1.push_back(&(tbb::flow::get<0>(j0.input_ports()))); + jv1.push_back(&(tbb::flow::get<0>(j1.input_ports()))); + jv1.push_back(&(tbb::flow::get<0>(j2.input_ports()))); + snode_type::successor_list_type sv; + s0.copy_successors(sv); + ASSERT(lists_match(sv, jv1), "mismatch in successor list"); + + tbb::flow::make_edge(q0, tbb::flow::get<1>(j2.input_ports())); + tbb::flow::make_edge(j2, q1); + s0.activate(); + + /* /+ */ + /* / | j0 */ + /* / + */ + /* / */ + /* / /--+ */ + /* s0-/ | j1 */ + /* \ + */ + /* \ */ + /* \--+ */ + /* | j2----q1 */ + /* q0-----+ */ + + q0.try_put(1); + g.wait_for_all(); + ASSERT(q1.try_get(dont_care), "join did not emit result"); + j2.extract(); + tbb::flow::make_edge(q0, tbb::flow::get<1>(j2.input_ports())); + tbb::flow::make_edge(j2, q1); + + /* /+ */ + /* / | j0 */ + /* / + */ + /* / */ + /* / /--+ */ + /* s0-/ | j1 */ + /* + */ + /* */ + /* + */ + /* | j2----q1 */ + /* q0-----+ */ + + jv1.clear(); + jv1.push_back(&(tbb::flow::get<0>(j0.input_ports()))); + jv1.push_back(&(tbb::flow::get<0>(j1.input_ports()))); + s0.copy_successors(sv); + ASSERT(lists_match(sv, jv1), "mismatch in successor list"); + + q0.try_put(1); + g.wait_for_all(); + ASSERT(!q1.try_get(dont_care), "extract of successor did not remove pred link"); + + s0.extract(); + + /* + */ + /* | j0 */ + /* + */ + /* */ + /* + */ + /* s0 | j1 */ + /* + */ + /* */ + /* + */ + /* | j2----q1 */ + /* q0-----+ */ + + ASSERT(s0.successor_count() == 0, "successor list not cleared"); + s0.copy_successors(sv); + ASSERT(sv.size() == 0, "non-empty successor list"); + + tbb::flow::make_edge(s0, tbb::flow::get<0>(j2.input_ports())); + + /* + */ + /* | j0 */ + /* + */ + /* */ + /* + */ + /* s0 | j1 */ + /* \ + */ + /* \ */ + /* \--+ */ + /* | j2----q1 */ + /* q0-----+ */ + + jv1.clear(); + jv1.push_back(&(tbb::flow::get<0>(j2.input_ports()))); + s0.copy_successors(sv); + ASSERT(lists_match(sv, jv1), "mismatch in successor list"); + + q0.try_put(1); + g.wait_for_all(); + ASSERT(!q1.try_get(dont_care), "extract of successor did not remove pred link"); +} +#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */ + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool source_body_f(int& i) { return i > 5; } +#else + int source_body_f(tbb::flow_control&) { return 42; } +#endif + +void test_deduction_guides() { + using namespace tbb::flow; + graph g; + +#if TBB_DEPRECATED_INPUT_NODE_BODY + auto lambda = [](int& i) { return i > 5; }; + auto non_const_lambda = [](int& i) mutable { return i > 5; }; +#else + auto lambda = [](tbb::flow_control&) { return 42; }; + auto non_const_lambda = [](tbb::flow_control&) mutable { return 42; }; +#endif + + // Tests for source_node(graph&, Body) + source_node s1(g, lambda); + static_assert(std::is_same_v<decltype(s1), source_node<int>>); + + source_node s2(g, non_const_lambda); + static_assert(std::is_same_v<decltype(s2), source_node<int>>); + + source_node s3(g, source_body_f); + static_assert(std::is_same_v<decltype(s3), source_node<int>>); + + source_node s4(s3); + static_assert(std::is_same_v<decltype(s4), source_node<int>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + broadcast_node<int> bc(g); + + // Tests for source_node(const node_set<Args...>&, Body) + source_node s5(precedes(bc), lambda); + static_assert(std::is_same_v<decltype(s5), source_node<int>>); + + source_node s6(precedes(bc), non_const_lambda); + static_assert(std::is_same_v<decltype(s6), source_node<int>>); + + source_node s7(precedes(bc), source_body_f); + static_assert(std::is_same_v<decltype(s7), source_node<int>>); +#endif + g.wait_for_all(); +} + +#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +void test_follows_and_precedes_api() { + using namespace tbb::flow; + + graph g; + + std::array<buffer_node<bool>, 3> successors {{ + buffer_node<bool>(g), + buffer_node<bool>(g), + buffer_node<bool>(g) + }}; + + bool do_try_put = true; + + source_node<bool> src(precedes(successors[0], successors[1], successors[2]), + #if TBB_DEPRECATED_INPUT_NODE_BODY + [&](bool& v) -> bool { + if(do_try_put) { + v = do_try_put; + do_try_put = false; + return true; + } + else { + return false; + } + } + #else + [&](tbb::flow_control& fc) -> bool { + if(!do_try_put) + fc.stop(); + do_try_put = !do_try_put; + return true; + } + #endif + ); + + src.activate(); + g.wait_for_all(); + + bool storage; + for(auto& successor: successors) { + ASSERT((successor.try_get(storage) && !successor.try_get(storage)), + "Not exact edge quantity was made"); + } +} +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +int TestMain() { + if( MinThread<1 ) { + REPORT("number of threads must be positive\n"); + exit(1); + } + for ( int p = MinThread; p < MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + test_single_dest<int>(); + test_single_dest<float>(); + } + test_reset(); +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract(); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_split_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_split_node.cpp new file mode 100644 index 00000000..5879b977 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_split_node.cpp @@ -0,0 +1,452 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_DEPRECATED_FLOW_NODE_ALLOCATOR __TBB_CPF_BUILD +#define TBB_DEPRECATED_INPUT_NODE_BODY __TBB_CPF_BUILD + +#include "harness.h" +#include "harness_graph.h" +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" + +#if defined(_MSC_VER) && _MSC_VER < 1600 + #pragma warning (disable : 4503) //disabling the "decorated name length exceeded" warning for VS2008 and earlier +#endif + +// +// Tests +// + +const int Count = 300; +const int MaxPorts = 10; +const int MaxNSources = 5; // max # of source_nodes to register for each split_node input in parallel test + +std::vector<bool> flags; // for checking output + +template<typename T> +class name_of { +public: + static const char* name() { return "Unknown"; } +}; +template<> +class name_of<int> { +public: + static const char* name() { return "int"; } +}; +template<> +class name_of<float> { +public: + static const char* name() { return "float"; } +}; +template<> +class name_of<double> { +public: + static const char* name() { return "double"; } +}; +template<> +class name_of<long> { +public: + static const char* name() { return "long"; } +}; +template<> +class name_of<short> { +public: + static const char* name() { return "short"; } +}; + +// T must be arithmetic, and shouldn't wrap around for reasonable sizes of Count (which is now 150, and maxPorts is 10, +// so the max number generated right now is 1500 or so.) Source will generate a series of TT with value +// (init_val + (i-1)*addend) * my_mult, where i is the i-th invocation of the body. We are attaching addend +// source nodes to a join_port, and each will generate part of the numerical series the port is expecting +// to receive. If there is only one source node, the series order will be maintained; if more than one, +// this is not guaranteed. + +template<int N> +struct tuple_helper { + template<typename TupleType> + static void set_element( TupleType &t, int i) { + tbb::flow::get<N-1>(t) = (typename tbb::flow::tuple_element<N-1,TupleType>::type)(i * (N+1)); + tuple_helper<N-1>::set_element(t, i); + } +}; + +template<> +struct tuple_helper<1> { + template<typename TupleType> + static void set_element(TupleType &t, int i) { + tbb::flow::get<0>(t) = (typename tbb::flow::tuple_element<0,TupleType>::type)(i * 2); + } +}; + +// if we start N source_bodys they will all have the addend N, and my_count should be initialized to 0 .. N-1. +// the output tuples should have all the sequence, but the order will in general vary. +template<typename TupleType> +class source_body { + typedef TupleType TT; + static const int N = tbb::flow::tuple_size<TT>::value; + int my_count; + int addend; +public: + source_body(int init_val, int addto) : my_count(init_val), addend(addto) { } +#if TBB_DEPRECATED_INPUT_NODE_BODY + bool operator()( TT &v) { + if(my_count >= Count) return false; + tuple_helper<N>::set_element(v, my_count); + my_count += addend; + return true; + } +#else + TT operator()( tbb::flow_control &fc) { + if(my_count >= Count){ + fc.stop(); + return TT(); + } + TT v; + tuple_helper<N>::set_element(v, my_count); + my_count += addend; + return v; + } +#endif +}; + +// allocator for split_node. + +template<int N, typename SType> +class makeSplit { +public: + static SType *create(tbb::flow::graph& g) { + SType *temp = new SType(g); + return temp; + } + static void destroy(SType *p) { delete p; } +}; + +// holder for sink_node pointers for eventual deletion + +static void* all_sink_nodes[MaxPorts]; + + +template<int ELEM, typename SType> +class sink_node_helper { +public: + typedef typename SType::input_type TT; + typedef typename tbb::flow::tuple_element<ELEM-1,TT>::type IT; + typedef typename tbb::flow::queue_node<IT> my_sink_node_type; + static void print_parallel_remark() { + sink_node_helper<ELEM-1,SType>::print_parallel_remark(); + REMARK(", %s", name_of<IT>::name()); + } + static void print_serial_remark() { + sink_node_helper<ELEM-1,SType>::print_serial_remark(); + REMARK(", %s", name_of<IT>::name()); + } + static void add_sink_nodes(SType &my_split, tbb::flow::graph &g) { + my_sink_node_type *new_node = new my_sink_node_type(g); + tbb::flow::make_edge( tbb::flow::output_port<ELEM-1>(my_split) , *new_node); + all_sink_nodes[ELEM-1] = (void *)new_node; + sink_node_helper<ELEM-1, SType>::add_sink_nodes(my_split, g); + } + + static void check_sink_values() { + my_sink_node_type *dp = reinterpret_cast<my_sink_node_type *>(all_sink_nodes[ELEM-1]); + for(int i = 0; i < Count; ++i) { + IT v; + ASSERT(dp->try_get(v), NULL); + flags[((int)v) / (ELEM+1)] = true; + } + for(int i = 0; i < Count; ++i) { + ASSERT(flags[i], NULL); + flags[i] = false; // reset for next test + } + sink_node_helper<ELEM-1,SType>::check_sink_values(); + } + static void remove_sink_nodes(SType& my_split) { + my_sink_node_type *dp = reinterpret_cast<my_sink_node_type *>(all_sink_nodes[ELEM-1]); + tbb::flow::remove_edge( tbb::flow::output_port<ELEM-1>(my_split) , *dp); + delete dp; + sink_node_helper<ELEM-1, SType>::remove_sink_nodes(my_split); + } +}; + +template<typename SType> +class sink_node_helper<1, SType> { + typedef typename SType::input_type TT; + typedef typename tbb::flow::tuple_element<0,TT>::type IT; + typedef typename tbb::flow::queue_node<IT> my_sink_node_type; +public: + static void print_parallel_remark() { + REMARK("Parallel test of split_node< %s", name_of<IT>::name()); + } + static void print_serial_remark() { + REMARK("Serial test of split_node< %s", name_of<IT>::name()); + } + static void add_sink_nodes(SType &my_split, tbb::flow::graph &g) { + my_sink_node_type *new_node = new my_sink_node_type(g); + tbb::flow::make_edge( tbb::flow::output_port<0>(my_split) , *new_node); + all_sink_nodes[0] = (void *)new_node; + } + static void check_sink_values() { + my_sink_node_type *dp = reinterpret_cast<my_sink_node_type *>(all_sink_nodes[0]); + for(int i = 0; i < Count; ++i) { + IT v; + ASSERT(dp->try_get(v), NULL); + flags[((int)v) / 2] = true; + } + for(int i = 0; i < Count; ++i) { + ASSERT(flags[i], NULL); + flags[i] = false; // reset for next test + } + } + static void remove_sink_nodes(SType& my_split) { + my_sink_node_type *dp = reinterpret_cast<my_sink_node_type *>(all_sink_nodes[0]); + tbb::flow::remove_edge( tbb::flow::output_port<0>(my_split) , *dp); + delete dp; + } +}; + +// parallel_test: create source_nodes that feed tuples into the split node +// and queue_nodes that receive the output. +template<typename SType> +class parallel_test { +public: + typedef typename SType::input_type TType; + typedef tbb::flow::input_node<TType> source_type; + static const int N = tbb::flow::tuple_size<TType>::value; + static void test() { + source_type* all_source_nodes[MaxNSources]; + sink_node_helper<N,SType>::print_parallel_remark(); + REMARK(" >\n"); + for(int i=0; i < MaxPorts; ++i) { + all_sink_nodes[i] = NULL; + } + // try test for # sources 1 .. MaxNSources + for(int nInputs = 1; nInputs <= MaxNSources; ++nInputs) { + tbb::flow::graph g; + SType* my_split = makeSplit<N,SType>::create(g); + + // add sinks first so when sources start spitting out values they are there to catch them + sink_node_helper<N, SType>::add_sink_nodes((*my_split), g); + + // now create nInputs source_nodes, each spitting out i, i+nInputs, i+2*nInputs ... + // each element of the tuple is i*(n+1), where n is the tuple element index (1-N) + for(int i = 0; i < nInputs; ++i) { + // create source node + source_type *s = new source_type(g, source_body<TType>(i, nInputs) ); + tbb::flow::make_edge(*s, *my_split); + all_source_nodes[i] = s; + s->activate(); + } + + g.wait_for_all(); + + // check that we got Count values in each output queue, and all the index values + // are there. + sink_node_helper<N, SType>::check_sink_values(); + + sink_node_helper<N, SType>::remove_sink_nodes(*my_split); + for(int i = 0; i < nInputs; ++i) { + delete all_source_nodes[i]; + } + makeSplit<N,SType>::destroy(my_split); + } + } +}; + +// +// Single predecessor, single accepting successor at each port + +template<typename SType> +void test_one_serial( SType &my_split, tbb::flow::graph &g) { + typedef typename SType::input_type TType; + static const int TUPLE_SIZE = tbb::flow::tuple_size<TType>::value; + sink_node_helper<TUPLE_SIZE, SType>::add_sink_nodes(my_split,g); + typedef TType q3_input_type; + tbb::flow::queue_node< q3_input_type > q3(g); + + tbb::flow::make_edge( q3, my_split ); + + // fill the queue with its value one-at-a-time + flags.clear(); + for (int i = 0; i < Count; ++i ) { + TType v; + tuple_helper<TUPLE_SIZE>::set_element(v, i); + ASSERT(my_split.try_put(v), NULL); + flags.push_back(false); + } + + g.wait_for_all(); + + sink_node_helper<TUPLE_SIZE,SType>::check_sink_values(); + + sink_node_helper<TUPLE_SIZE, SType>::remove_sink_nodes(my_split); + +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +void test_follow_and_precedes_api() { + using namespace tbb::flow; + using msg_t = tuple<int, float, double>; + + graph g; + + function_node<msg_t, msg_t> f1(g, unlimited, [](msg_t msg) { return msg; } ); + auto f2(f1); + auto f3(f1); + + tbb::atomic<int> body_calls = 0; + + function_node<int, int> f4(g, unlimited, [&](int val) { ++body_calls; return val; } ); + function_node<float, float> f5(g, unlimited, [&](float val) { ++body_calls; return val; } ); + function_node<double, double> f6(g, unlimited, [&](double val) { ++body_calls; return val; } ); + + split_node<msg_t> following_node(follows(f1, f2, f3)); + make_edge(output_port<0>(following_node), f4); + make_edge(output_port<1>(following_node), f5); + make_edge(output_port<2>(following_node), f6); + + split_node<msg_t> preceding_node(precedes(f4, f5, f6)); + make_edge(f1, preceding_node); + make_edge(f2, preceding_node); + make_edge(f3, preceding_node); + + msg_t msg(1, 2.2f, 3.3); + f1.try_put(msg); + f2.try_put(msg); + f3.try_put(msg); + + g.wait_for_all(); + + // <number of try puts> * <number of splits by a source node> * <number of source nodes> + ASSERT((body_calls == 3*3*2), "Not exact edge quantity was made"); +} +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +template<typename SType> +class serial_test { + typedef typename SType::input_type TType; + static const int TUPLE_SIZE = tbb::flow::tuple_size<TType>::value; + static const int ELEMS = 3; +public: +static void test() { + tbb::flow::graph g; + flags.reserve(Count); + SType* my_split = makeSplit<TUPLE_SIZE,SType>::create(g); + sink_node_helper<TUPLE_SIZE, SType>::print_serial_remark(); REMARK(" >\n"); + + test_output_ports_return_ref(*my_split); + + test_one_serial<SType>(*my_split, g); + // build the vector with copy construction from the used split node. + std::vector<SType>split_vector(ELEMS, *my_split); + // destroy the tired old split_node in case we're accidentally reusing pieces of it. + makeSplit<TUPLE_SIZE,SType>::destroy(my_split); + + + for(int e = 0; e < ELEMS; ++e) { // exercise each of the vector elements + test_one_serial<SType>(split_vector[e], g); + } +} + +}; // serial_test + +template< + template<typename> class TestType, // serial_test or parallel_test + typename TupleType > // type of the input of the split +struct generate_test { + typedef tbb::flow::split_node<TupleType> split_node_type; + static void do_test() { + TestType<split_node_type>::test(); + } +}; // generate_test + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + +void test_deduction_guides() { + using namespace tbb::flow; + using tuple_type = std::tuple<int, int>; + + graph g; + split_node<tuple_type> s0(g); + + split_node s1(s0); + static_assert(std::is_same_v<decltype(s1), split_node<tuple_type>>); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + broadcast_node<tuple_type> b1(g), b2(g); + broadcast_node<int> b3(g), b4(g); + + split_node s2(follows(b1, b2)); + static_assert(std::is_same_v<decltype(s2), split_node<tuple_type>>); + + split_node s3(precedes(b3, b4)); + static_assert(std::is_same_v<decltype(s3), split_node<tuple_type>>); +#endif +} + +#endif + +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR +void test_node_allocator() { + tbb::flow::graph g; + tbb::flow::split_node< tbb::flow::tuple<int,int>, std::allocator<int> > tmp(g); +} +#endif + +int TestMain() { +#if __TBB_USE_TBB_TUPLE + REMARK(" Using TBB tuple\n"); +#else + REMARK(" Using platform tuple\n"); +#endif + for (int p = 0; p < 2; ++p) { + generate_test<serial_test, tbb::flow::tuple<float, double> >::do_test(); +#if MAX_TUPLE_TEST_SIZE >= 4 + generate_test<serial_test, tbb::flow::tuple<float, double, int, long> >::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 6 + generate_test<serial_test, tbb::flow::tuple<double, double, int, long, int, short> >::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 8 + generate_test<serial_test, tbb::flow::tuple<float, double, double, double, float, int, float, long> >::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 10 + generate_test<serial_test, tbb::flow::tuple<float, double, int, double, double, float, long, int, float, long> >::do_test(); +#endif + generate_test<parallel_test, tbb::flow::tuple<float, double> >::do_test(); +#if MAX_TUPLE_TEST_SIZE >= 3 + generate_test<parallel_test, tbb::flow::tuple<float, int, long> >::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 5 + generate_test<parallel_test, tbb::flow::tuple<double, double, int, int, short> >::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 7 + generate_test<parallel_test, tbb::flow::tuple<float, int, double, float, long, float, long> >::do_test(); +#endif +#if MAX_TUPLE_TEST_SIZE >= 9 + generate_test<parallel_test, tbb::flow::tuple<float, double, int, double, double, long, int, float, long> >::do_test(); +#endif + } +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follow_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif +#if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR + test_node_allocator(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_static_assert.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_static_assert.cpp new file mode 100644 index 00000000..dc07ee59 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_static_assert.cpp @@ -0,0 +1,85 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_stddef.h" + +void TestInsideFunction(){ + __TBB_STATIC_ASSERT(sizeof(char)>=1,""); +} +void TestTwiceAtTheSameLine(){ +// for current implementation it is not possible to use +// two __TBB_STATIC_ASSERT on a same line +// __TBB_STATIC_ASSERT(true,""); __TBB_STATIC_ASSERT(true,""); +} + +void TestInsideStructure(){ + struct helper{ + __TBB_STATIC_ASSERT(true,""); + }; +} + +void TestTwiceInsideStructure(){ + struct helper{ + //for current implementation it is not possible to use + //two __TBB_STATIC_ASSERT on a same line inside a class definition + //__TBB_STATIC_ASSERT(true,"");__TBB_STATIC_ASSERT(true,""); + + __TBB_STATIC_ASSERT(true,""); + __TBB_STATIC_ASSERT(true,""); + }; +} + +namespace TestTwiceInsideNamespaceHelper{ + __TBB_STATIC_ASSERT(true,""); + __TBB_STATIC_ASSERT(true,""); +} + +namespace TestTwiceInsideClassTemplateHelper{ + template <typename T> + struct template_struct{ + __TBB_STATIC_ASSERT(true,""); + __TBB_STATIC_ASSERT(true,""); + }; +} + +void TestTwiceInsideTemplateClass(){ + using namespace TestTwiceInsideClassTemplateHelper; + typedef template_struct<int> template_struct_int_typedef; + typedef template_struct<char> template_struct_char_typedef; + tbb::internal::suppress_unused_warning(template_struct_int_typedef(), template_struct_char_typedef()); +} + +template<typename T> +void TestTwiceInsideTemplateFunction(){ + __TBB_STATIC_ASSERT(sizeof(T)>=1,""); + __TBB_STATIC_ASSERT(true,""); +} + +#include "harness.h" +int TestMain() { + #if __TBB_STATIC_ASSERT_PRESENT + REPORT("Known issue: %s\n", "no need to test ad-hoc implementation as native feature of C++11 is used"); + return Harness::Skipped; + #else + TestInsideFunction(); + TestInsideStructure(); + TestTwiceAtTheSameLine(); + TestTwiceInsideStructure(); + TestTwiceInsideTemplateClass(); + TestTwiceInsideTemplateFunction<char>(); + return Harness::Done; + #endif +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_std_thread.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_std_thread.cpp new file mode 100644 index 00000000..66e80c4c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_std_thread.cpp @@ -0,0 +1,39 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_IMPLEMENT_CPP0X 1 +#include "tbb/tbb_config.h" + +#if __TBB_WIN8UI_SUPPORT +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" +int TestMain() { + return Harness::Skipped; +} +#else +#include "tbb/compat/thread" +#define THREAD std::thread +#define THIS_THREAD std::this_thread +#define THIS_THREAD_SLEEP THIS_THREAD::sleep_for +#include "test_thread.h" +#include "harness.h" + +int TestMain () { + CheckSignatures(); + RunTests(); + return Harness::Done; +} +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_streaming_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_streaming_node.cpp new file mode 100644 index 00000000..a3c82040 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_streaming_node.cpp @@ -0,0 +1,913 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_PREVIEW_FLOW_GRAPH_NODES 1 +#define TBB_PREVIEW_FLOW_GRAPH_FEATURES 1 + +#include "tbb/tbb_config.h" + +#if __TBB_PREVIEW_STREAMING_NODE + +#if _MSC_VER +#pragma warning (disable: 4503) // Suppress "decorated name length exceeded, name was truncated" warning +#pragma warning (disable: 4702) // Suppress "unreachable code" warning +#endif + +#include <functional> +#include <iostream> + +#include "harness.h" +#include "harness_assert.h" + +#include "tbb/concurrent_queue.h" +#include "tbb/flow_graph.h" +#include "tbb/tbb_thread.h" + +using namespace tbb::flow; + +//-------------------------------------------------------------------------------- +//--------------------------------TEST HELPERS------------------------------------ +//-------------------------------------------------------------------------------- + +template <typename ...A> +struct tuples_equal : std::false_type { }; + +template <typename ...A> +struct tuples_equal<std::tuple<A...>, std::tuple<>> : std::false_type { }; + +template <typename ...B> +struct tuples_equal<std::tuple<>, std::tuple<B...>> : std::false_type { }; + +template <> +struct tuples_equal<std::tuple<>, std::tuple<>> : std::true_type { }; + +template <typename A1, typename ...Aother, typename B1, typename ...Bother> +struct tuples_equal<std::tuple<A1, Aother...>, std::tuple<B1, Bother...>> +{ + static const bool value = std::is_same<A1, B1>::value && tuples_equal<std::tuple<Aother...>, std::tuple<Bother...>>::value; +}; + +template<typename...A> +struct first_variadic { + template<typename...B> + static void is_equal_to_second() + { + ASSERT((tuples_equal< std::tuple<A...>, std::tuple<B...> >::value), "Unexpected variadic types"); + } +}; + +//-------------------------------------------------------------------------------- + +template<typename T> +class factory_msg : public async_msg<T> { +public: + factory_msg() {} + factory_msg(const T& input_data) : m_data(input_data) {} + + const T& data() const { return m_data; } + void update_data(T value) { m_data = value; } +private: + T m_data; +}; + +//-------------------------------------------------------------------------------- + +class base_streaming_factory : NoCopy { +public: + + typedef int device_type; + typedef int kernel_type; + + template<typename T> using async_msg_type = factory_msg<T>; + + base_streaming_factory() : devices_list(1) {} + + std::vector<device_type> devices() { + return devices_list; + } + + template <typename ...Args> + void send_result_forward(Args&... args) { + deviceResult = doDeviceWork(); + send_result(args...); + } + + void clear_factory() { + arguments_list.clear(); + } + + void process_arg_list() {} + + template <typename T, typename ...Rest> + void process_arg_list(T& arg, Rest&... args) { + process_one_arg(arg); + process_arg_list(args...); + } + +private: + + int doDeviceWork() { + int result = 0; + for (size_t i = 0; i < arguments_list.size(); i++) + result += arguments_list[i]; + return result; + } + + // Pass calculation result to the next node + template <typename ...Args> + void set_result(Args...) {} + + template <typename T> + void set_result(async_msg_type<T>& msg) { + msg.set(deviceResult); + } + + // Variadic functions for result processing + // and sending them to all async_msgs + void send_result() {} + + template <typename T, typename ...Rest> + void send_result(T& arg, Rest&... args) { + set_result(arg); + send_result(args...); + } + + // Retrieve values from async_msg objects + // and store them in vector + template <typename T> + void process_one_arg(async_msg_type<T>& msg) { + arguments_list.push_back(msg.data()); + } + + template <typename T> + void process_one_arg(const async_msg_type<T>& msg) { + arguments_list.push_back(msg.data()); + } + + std::vector<device_type> devices_list; + std::vector<int> arguments_list; + + int deviceResult; +}; + +template<typename ...ExpectedArgs> +class test_streaming_factory : public base_streaming_factory { +public: + + template <typename ...Args> + void send_data(device_type /*device*/, Args&... /*args*/) {} + + template <typename ...Args> + void send_kernel(device_type /*device*/, const kernel_type& /*kernel*/, Args&... args) { + check_arguments(args...); + process_arg_list(args...); + send_result_forward(args...); + clear_factory(); + } + + template <typename FinalizeFn, typename ...Args> + void finalize(device_type /*device*/, FinalizeFn fn, Args&... args) { + check_arguments(args...); + fn(); + } + + template<typename ...Args> + void check_arguments(Args&... /*args*/) { + first_variadic< Args... >::template is_equal_to_second< ExpectedArgs... >(); + } +}; + +//-------------------------------------------------------------------------------- + +template<typename Factory> +class device_selector { +public: + device_selector() : my_state(DEFAULT_INITIALIZED) {} + device_selector(const device_selector&) : my_state(COPY_INITIALIZED) {} + device_selector(device_selector&&) : my_state(COPY_INITIALIZED) {} + ~device_selector() { my_state = DELETED; } + + typename Factory::device_type operator()(Factory &f) { + ASSERT(my_state == COPY_INITIALIZED, NULL); + ASSERT(!f.devices().empty(), NULL); + return *(f.devices().begin()); + } + +private: + enum state { + DEFAULT_INITIALIZED, + COPY_INITIALIZED, + DELETED + }; + state my_state; +}; + +//-------------------------------------------------------------------------------- + +void TestWithoutSetArgs() { + graph g; + + typedef test_streaming_factory< factory_msg<int>, factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + int expected_result; + split_node < tuple<int, int> > split_n(g); + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + function_node< int > function_n(g, unlimited, [&expected_result](const int& result) { + ASSERT(expected_result == result, "Validation has failed"); + }); + + make_edge(output_port<0>(split_n), input_port<0>(streaming_n)); + make_edge(output_port<1>(split_n), input_port<1>(streaming_n)); + + const int first_arg = 10; + const int second_arg = 20; + std::tuple<int, int> args_tuple = std::make_tuple(first_arg, second_arg); + + // test finalize function + split_n.try_put(args_tuple); + g.wait_for_all(); + + make_edge(output_port<0>(streaming_n), function_n); + expected_result = 30; + split_n.try_put(args_tuple); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestSetArgsOnly() { + graph g; + + typedef test_streaming_factory< const factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + split_node < tuple<int, int> > split_n(g); + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + + make_edge(output_port<0>(split_n), input_port<0>(streaming_n)); + make_edge(output_port<1>(split_n), input_port<1>(streaming_n)); + + const int first_arg = 10; + const int second_arg = 20; + std::tuple<int, int> args_tuple = std::make_tuple(first_arg, second_arg); + + streaming_n.set_args(100); + split_n.try_put(args_tuple); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestSetPortRefOnly() { + graph g; + + typedef test_streaming_factory< factory_msg<int>, factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + int expected_result; + split_node < tuple<int, int> > split_n(g); + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + function_node< int > function_n(g, unlimited, [&expected_result](const int& result) { + ASSERT(expected_result == result, "Validation has failed"); + }); + + make_edge(output_port<0>(split_n), input_port<0>(streaming_n)); + make_edge(output_port<1>(split_n), input_port<1>(streaming_n)); + + const int first_arg = 10; + const int second_arg = 20; + std::tuple<int, int> args_tuple = std::make_tuple(first_arg, second_arg); + + + streaming_n.set_args(port_ref<0, 1>()); + + // test finalize function + split_n.try_put(args_tuple); + g.wait_for_all(); + + make_edge(output_port<0>(streaming_n), function_n); + expected_result = 30; + split_n.try_put(args_tuple); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestSetArgsAndPortRef1() { + graph g; + + typedef test_streaming_factory< const factory_msg<int>, factory_msg<int>, factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + int expected_result; + split_node < tuple<int, int> > split_n(g); + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + function_node< int > function_n(g, unlimited, [&expected_result](const int& result) { + ASSERT(expected_result == result, "Validation has failed"); + }); + + make_edge(output_port<0>(split_n), input_port<0>(streaming_n)); + make_edge(output_port<1>(split_n), input_port<1>(streaming_n)); + + const int first_arg = 10; + const int second_arg = 20; + std::tuple<int, int> args_tuple = std::make_tuple(first_arg, second_arg); + + streaming_n.set_args(100, port_ref<0, 1>()); + + // test finalize function + split_n.try_put(args_tuple); + g.wait_for_all(); + + make_edge(output_port<0>(streaming_n), function_n); + expected_result = 130; + split_n.try_put(args_tuple); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestSetArgsAndPortRef2() { + graph g; + + typedef test_streaming_factory< const factory_msg<int>, factory_msg<int>, + const factory_msg<int>, factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + int expected_result; + split_node < tuple<int, int> > split_n(g); + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + function_node< int > function_n(g, unlimited, [&expected_result](const int& result) { + ASSERT(expected_result == result, "Validation has failed"); + }); + + make_edge(output_port<0>(split_n), input_port<0>(streaming_n)); + make_edge(output_port<1>(split_n), input_port<1>(streaming_n)); + + const int first_arg = 10; + const int second_arg = 20; + std::tuple<int, int> args_tuple = std::make_tuple(first_arg, second_arg); + + streaming_n.set_args(100, port_ref<0>(), 200, port_ref<1>()); + + // test finalize function + split_n.try_put(args_tuple); + g.wait_for_all(); + + make_edge(output_port<0>(streaming_n), function_n); + expected_result = 330; + split_n.try_put(args_tuple); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +template <typename ...ExpectedArgs> +class send_data_factory : public base_streaming_factory { +public: + + send_data_factory() : send_data_counter(0) {} + + template <typename ...Args> + void send_data(device_type /*device*/, Args&... /*args*/) { + switch (send_data_counter) { + case 0: + first_variadic< Args... >::template is_equal_to_second< ExpectedArgs... >(); + break; + case 1: + first_variadic< Args... >::template is_equal_to_second< factory_msg<int> >(); + break; + case 2: + first_variadic< Args... >::template is_equal_to_second< factory_msg<int> >(); + break; + default: + break; + } + send_data_counter++; + } + + template <typename ...Args> + void send_kernel(device_type /*device*/, const kernel_type& /*kernel*/, Args&... /*args*/) { + ASSERT(send_data_counter == 3, "send_data() was called not enough times"); + send_data_counter = 0; + } + + template <typename FinalizeFn, typename ...Args> + void finalize(device_type /*device*/, FinalizeFn fn, Args&... /*args*/) { + fn(); + } + +private: + int send_data_counter; +}; + +void TestSendData_withoutSetArgs() { + graph g; + + typedef send_data_factory< tbb::flow::interface11::internal::port_ref_impl<0, 1> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + + input_port<0>(streaming_n).try_put(10); + input_port<1>(streaming_n).try_put(20); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestSendData_setArgsOnly() { + graph g; + + typedef send_data_factory< factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + + streaming_n.set_args(100); + input_port<0>(streaming_n).try_put(10); + input_port<1>(streaming_n).try_put(20); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestSendData_portRefOnly() { + graph g; + + typedef send_data_factory< tbb::flow::interface11::internal::port_ref_impl<0,1> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + + streaming_n.set_args(port_ref<0,1>()); + input_port<0>(streaming_n).try_put(10); + input_port<1>(streaming_n).try_put(20); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestSendData_setArgsAndPortRef1() { + graph g; + + typedef send_data_factory< factory_msg<int>, tbb::flow::interface11::internal::port_ref_impl<0, 1> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + + streaming_n.set_args(100, port_ref<0,1>()); + input_port<0>(streaming_n).try_put(10); + input_port<1>(streaming_n).try_put(20); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestSendData_setArgsAndPortRef2() { + graph g; + + typedef send_data_factory< factory_msg<int>, tbb::flow::interface11::internal::port_ref_impl<0,0>, + factory_msg<int>, tbb::flow::interface11::internal::port_ref_impl<1,1> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + + streaming_n.set_args(100, port_ref<0>(), 200, port_ref<1>()); + input_port<0>(streaming_n).try_put(10); + input_port<1>(streaming_n).try_put(20); + g.wait_for_all(); +} + +//-------------------------------------------------------------------------------- + +void TestArgumentsPassing() { + REMARK("TestArgumentsPassing: "); + TestWithoutSetArgs(); + TestSetArgsOnly(); + TestSetPortRefOnly(); + TestSetArgsAndPortRef1(); + TestSetArgsAndPortRef2(); + + TestSendData_withoutSetArgs(); + TestSendData_setArgsOnly(); + TestSendData_portRefOnly(); + TestSendData_setArgsAndPortRef1(); + TestSendData_setArgsAndPortRef2(); + REMARK("done\n"); +} + +//-------------------------------------------------------------------------------- + +template<typename... ExpectedArgs> +class range_streaming_factory : public base_streaming_factory { +public: + + typedef std::array<int, 2> range_type; + + template <typename ...Args> + void send_data(device_type /*device*/, Args&... /*args*/) { + } + + template <typename ...Args> + void send_kernel(device_type /*device*/, const kernel_type& /*kernel*/, const range_type& work_size, Args&... args) { + ASSERT(work_size[0] == 1024, "Range was set incorrectly"); + ASSERT(work_size[1] == 720, "Range was set incorrectly"); + first_variadic< Args... >::template is_equal_to_second< ExpectedArgs... >(); + process_arg_list(args...); + send_result_forward(args...); + clear_factory(); + } + + template <typename FinalizeFn, typename ...Args> + void finalize(device_type /*device*/, FinalizeFn fn, Args&... /*args*/) { + first_variadic< Args... >::template is_equal_to_second< ExpectedArgs... >(); + fn(); + } + +}; + +void TestSetRange() { + REMARK("TestSetRange: "); + + graph g; + + typedef range_streaming_factory< const factory_msg<int>, factory_msg<int>, + const factory_msg<int>, factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + int expected_result; + split_node < tuple<int, int> > split_n(g); + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + function_node< int > function_n(g, unlimited, [&expected_result](const int& result) { + ASSERT(expected_result == result, "Validation has failed"); + }); + + make_edge(output_port<0>(split_n), input_port<0>(streaming_n)); + make_edge(output_port<1>(split_n), input_port<1>(streaming_n)); + + const int first_arg = 10; + const int second_arg = 20; + std::tuple<int, int> args_tuple = std::make_tuple(first_arg, second_arg); + + streaming_n.set_args(100, port_ref<0>(), 200, port_ref<1>()); + + // test version for GCC <= 4.7.2 (unsupported conversion from initializer_list to std::array) +#if __GNUC__ < 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ <= 7 || (__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ <= 2))) + std::array<int, 2> device_range; + device_range[0] = 1024; + device_range[1] = 720; + streaming_n.set_range(device_range); +#else + std::array<int, 2> device_range = { 1024,720 }; + streaming_n.set_range(device_range); +#endif + + split_n.try_put(args_tuple); + g.wait_for_all(); + + make_edge(output_port<0>(streaming_n), function_n); + expected_result = 330; + split_n.try_put(args_tuple); + g.wait_for_all(); + + REMARK("done\n"); +} + +//------------------------------------------------------------------------------------------------------------------------------------------- + +template <typename T> +class user_async_msg : public tbb::flow::async_msg<T> +{ +public: + user_async_msg() {} + user_async_msg(T value) : m_data(value) {} + void finalize() const __TBB_override; +private: + T m_data; +}; + +class user_async_activity { // Async activity singleton +public: + + static user_async_activity* instance() { + if (s_Activity == NULL) { + s_Activity = new user_async_activity(); + } + return s_Activity; + } + + static void destroy() { + ASSERT(s_Activity != NULL, "destroyed twice"); + s_Activity->myThread.join(); + delete s_Activity; + s_Activity = NULL; + } + + template <typename FinalizeFn> + static void finish(FinalizeFn fn) { + ASSERT(user_async_activity::s_Activity != NULL, "activity must be alive"); + user_async_activity::s_Activity->finishTaskQueue(fn); + } + + static void finish(const user_async_msg<int>& msg) { + ASSERT(user_async_activity::s_Activity != NULL, "activity must be alive"); + user_async_activity::s_Activity->finishTaskQueue(msg); + } + + static int getResult() { + ASSERT(user_async_activity::s_Activity != NULL, "activity must be alive"); + return user_async_activity::s_Activity->myQueueSum; + } + + void addWork(int addValue, int timeout = 0) { + myQueue.push(my_task(addValue, timeout)); + } + + template <typename FinalizeFn> + void finishTaskQueue(FinalizeFn fn) { + myFinalizer = fn; + myQueue.push(my_task(0, 0, true)); + } + + void finishTaskQueue(const user_async_msg<int>& msg) { + myMsg = msg; + myQueue.push(my_task(0, 0, true)); + } + +private: + + struct my_task { + my_task(int addValue = 0, int timeout = 0, bool finishFlag = false) + : myAddValue(addValue), myTimeout(timeout), myFinishFlag(finishFlag) {} + + int myAddValue; + int myTimeout; + bool myFinishFlag; + }; + + static void threadFunc(user_async_activity* activity) { + for (;;) { + my_task work; + activity->myQueue.pop(work); + Harness::Sleep(work.myTimeout); + if (work.myFinishFlag) { + break; + } + activity->myQueueSum += work.myAddValue; + } + + // Send result back to the graph + if (activity->myFinalizer) { + activity->myFinalizer(); + } + activity->myMsg.set(activity->myQueueSum); + + } + + user_async_activity() : myQueueSum(0), myThread(&user_async_activity::threadFunc, this) {} + + tbb::concurrent_bounded_queue<my_task> myQueue; + int myQueueSum; + user_async_msg<int> myMsg; + std::function<void(void)> myFinalizer; + tbb::tbb_thread myThread; + + static user_async_activity* s_Activity; +}; + +user_async_activity* user_async_activity::s_Activity = NULL; + +template <typename T> +void user_async_msg<T>::finalize() const { + user_async_activity::finish(*this); +} + +class data_streaming_factory { +public: + + typedef int device_type; + typedef int kernel_type; + + template<typename T> using async_msg_type = user_async_msg<T>; + + data_streaming_factory() : devices_list(1) {} + + template <typename ...Args> + void send_data(device_type /*device*/, Args&... /*args*/) {} + + template <typename ...Args> + void send_kernel(device_type /*device*/, const kernel_type& /*kernel*/, Args&... args) { + process_arg_list(args...); + } + + template <typename FinalizeFn, typename ...Args> + void finalize(device_type /*device*/, FinalizeFn fn, Args&... /*args*/) { + user_async_activity::finish(fn); + } + + // Retrieve values from async_msg objects + // and store them in vector + void process_arg_list() {} + + template <typename T, typename ...Rest> + void process_arg_list(T& arg, Rest&... args) { + process_one_arg(arg); + process_arg_list(args...); + } + + template <typename T> + void process_one_arg(async_msg_type<T>& /*msg*/) { + user_async_activity::instance()->addWork(1, 10); + } + + template <typename ...Args> + void process_one_arg(Args&... /*args*/) {} + + std::vector<device_type> devices() { + return devices_list; + } + +private: + std::vector<device_type> devices_list; +}; + +void TestChaining() { + REMARK("TestChaining: "); + + graph g; + typedef streaming_node< tuple<int>, queueing, data_streaming_factory > streaming_node_type; + typedef std::vector< streaming_node_type > nodes_vector_type; + + data_streaming_factory factory; + device_selector<data_streaming_factory> device_selector; + data_streaming_factory::kernel_type kernel(0); + + const int STREAMING_GRAPH_CHAIN_LENGTH = 1000; + nodes_vector_type nodes_vector; + for (int i = 0; i < STREAMING_GRAPH_CHAIN_LENGTH; i++) { + nodes_vector.emplace_back(g, kernel, device_selector, factory); + } + + function_node< int, int > source_n(g, unlimited, [](const int& value) -> int { + return value; + }); + + function_node< int > destination_n(g, unlimited, [&](const int& result) { + ASSERT(result == STREAMING_GRAPH_CHAIN_LENGTH, "calculation chain result is wrong"); + }); + + make_edge(source_n, input_port<0>(nodes_vector.front())); + for (size_t i = 0; i < nodes_vector.size() - 1; i++) { + make_edge(output_port<0>(nodes_vector[i]), input_port<0>(nodes_vector[i + 1])); + nodes_vector[i].set_args(port_ref<0>()); + } + nodes_vector.back().set_args(port_ref<0>()); + make_edge(output_port<0>(nodes_vector.back()), destination_n); + + source_n.try_put(0); + g.wait_for_all(); + + REMARK("result = %d; expected = %d\n", user_async_activity::getResult(), STREAMING_GRAPH_CHAIN_LENGTH); + ASSERT(user_async_activity::getResult() == STREAMING_GRAPH_CHAIN_LENGTH, "calculation chain result is wrong"); + + user_async_activity::destroy(); + + REMARK("done\n"); +} + +//-------------------------------------------------------------------------------- + +void TestCopyConstructor() { + REMARK("TestCopyConstructor: "); + + graph g; + + typedef test_streaming_factory< factory_msg<int>, factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + int expected_result; + split_node < tuple<int, int> > split_n(g); + function_node< int > function_n(g, unlimited, [&expected_result](const int& result) { + ASSERT(expected_result == result, "Validation has failed"); + }); + + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + + // Testing copy constructor + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n_copied(streaming_n); + + make_edge(output_port<0>(split_n), input_port<0>(streaming_n_copied)); + make_edge(output_port<1>(split_n), input_port<1>(streaming_n_copied)); + make_edge(output_port<0>(streaming_n_copied), function_n); + + std::tuple<int, int> args_tuple = std::make_tuple(10, 20); + expected_result = 30; + split_n.try_put(args_tuple); + g.wait_for_all(); + + REMARK("done\n"); +} + +void TestMoveConstructor() { + REMARK("TestMoveConstructor: "); + + graph g; + + typedef test_streaming_factory< factory_msg<int>, factory_msg<int> > device_factory; + + device_factory factory; + device_selector<device_factory> device_selector; + device_factory::kernel_type kernel(0); + + int expected_result; + split_node < tuple<int, int> > split_n(g); + function_node< int > function_n(g, unlimited, [&expected_result](const int& result) { + ASSERT(expected_result == result, "Validation has failed"); + }); + + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n(g, kernel, device_selector, factory); + + // Testing move constructor + streaming_node< tuple<int, int>, queueing, device_factory > streaming_n_moved(std::move(streaming_n)); + + make_edge(output_port<0>(split_n), input_port<0>(streaming_n_moved)); + make_edge(output_port<1>(split_n), input_port<1>(streaming_n_moved)); + make_edge(output_port<0>(streaming_n_moved), function_n); + + std::tuple<int, int> args_tuple = std::make_tuple(10, 20); + expected_result = 30; + split_n.try_put(args_tuple); + g.wait_for_all(); + + REMARK("done\n"); +} + +void TestConstructor() { + TestCopyConstructor(); + TestMoveConstructor(); +} + +//-------------------------------------------------------------------------------- + +int TestMain() { + TestArgumentsPassing(); + TestSetRange(); + TestChaining(); + TestConstructor(); + return Harness::Done; +} +#else +#define HARNESS_SKIP_TEST 1 +#include "harness.h" +#endif diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tagged_msg.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tagged_msg.cpp new file mode 100644 index 00000000..722d1f10 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tagged_msg.cpp @@ -0,0 +1,259 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define _VARIADIC_MAX 10 // Visual Studio 2012 +#include "harness.h" +#include "tbb/atomic.h" +#include "harness_checktype.h" + +#include "tbb/flow_graph.h" +#include <cstdio> +#include <stdexcept> +#include <vector> + +#if __TBB_GCC_STRICT_ALIASING_BROKEN + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + +// given a tuple, return the type of the element that has the maximum alignment requirement. +// Given a tuple and that type, return the number of elements of the object with the max +// alignment requirement that is at least as big as the largest object in the tuple. + +using tbb::flow::tuple_element; +using tbb::flow::tuple_size; +using tbb::flow::cast_to; +using tbb::flow::is_a; + +typedef int *int_ptr; +typedef char odd_array_type[15]; +typedef char odder_array[17]; +typedef check_type<int> counted_array_type[12]; +typedef std::vector<double> d_vector; +typedef std::vector<int> i_vector; +typedef i_vector i_vector_array[2]; +typedef tbb::flow::tagged_msg<size_t, int, char, double, odd_array_type, odder_array, d_vector, check_type<int>, counted_array_type, i_vector_array> tagged_msg_type; + +// test base of tagged_msg +void TestWrapper() { + using tbb::flow::interface11::internal::Wrapper; + Wrapper<int> wi(42); + Wrapper<int> wic(23); + + REMARK("Value of wic is %d\n", wic.value()); + + // pointer-type creation + int point_to_me = 23; + Wrapper<int_ptr> wip(&point_to_me); + ASSERT(*(wip.value()) == 23, "Error in wip value"); + + odd_array_type ww; + for(int ii = 0; ii < 15; ++ii) { ww[ii] = char('0' + ii); } ww[14] = 0; + + Wrapper<odd_array_type> ci(ww); + ASSERT(!strncmp(ci.value(), ww, 14), "odd_array_type ci not properly-constructed" ); + + Wrapper<odd_array_type> ci2(ci); + + ASSERT(!strncmp(ci2.value(), ww, 14), "odd_array_type ci2 not properly-constructed" ); + + d_vector di; + di.clear(); + di.push_back(2.0); + Wrapper<d_vector> dvec(di); + ASSERT(dvec.value()[0] == 2.0, "incorrect value in vector"); + + // test array of non-PODs. + i_vector_array oia; + oia[0].clear(); + oia[1].clear(); + oia[0].push_back(3); + oia[1].push_back(2); + Wrapper<i_vector_array> ia(oia); + ASSERT((ia.value()[1])[0] == 2, "integer vector array element[1] misbehaved"); + ASSERT((ia.value()[0])[0] == 3, "integer vector array element[0] misbehaved"); + Wrapper<i_vector_array> iac(ia); + ASSERT((iac.value()[1])[0] == 2, "integer vector array element[1] misbehaved"); + ASSERT((iac.value()[0])[0] == 3, "integer vector array element[0] misbehaved"); + + // counted_array + counted_array_type cat_orig; + for(int i = 0; i < 12; ++i) cat_orig[i] = i + 1; + Wrapper<counted_array_type> cat(cat_orig); + for(int j = 0; j < 12; ++j) + ASSERT(1 + j == cat.value()[j], "Error in cat array"); + + int i = wi.value(); + ASSERT(i == 42, "Assignment to i failed"); + ASSERT(wi.value() == 42, "Assignment to wi failed"); + double d = wi.value(); + ASSERT(d == 42, "Implicit cast in assign to double failed"); + int_ptr ip = wip.value(); + ASSERT(ip == &(point_to_me), "Error in assignment of pointer"); +} + +void RunTests() { + tagged_msg_type def; + tagged_msg_type i(1,3); + check_type<int>::check_type_counter = 0; + int z; + #if TBB_USE_EXCEPTIONS + try { + z = cast_to<int>(def); // disallowed (non-array returning int) + ASSERT(false, "should not allow cast to int of non-array"); + } + catch(...) { + REMARK("cast of non-array to int disallowed (okay)\n"); + } + #endif + z = cast_to<int>(i); + ASSERT(is_a<int>(i), "wrong type for i ( == int)"); + ASSERT(!(is_a<double>(i)), "Wrong type for i ( != double)"); + z = 5; + z = cast_to<int>(i); + + const int &ref_i(cast_to<int>(i)); + ASSERT(ref_i == 3, "ref_i got wrong value"); + tagged_msg_type j(2,4); + i = j; + ASSERT(ref_i == 4, "assign to i did not affect ref_i"); + + ASSERT( z == 3, "Error retrieving value from i"); + + //updating and retrieving tags + ASSERT(j.tag() == 2, "Error retrieving tag for j"); + j.set_tag(10); + ASSERT(j.tag() == 10, "Error updating tag for j"); + + tbb::flow::tagged_msg<char, int, char, double> k('a', 4); + k.set_tag('b'); + ASSERT(k.tag() == 'b', "Error updating char tag"); + + tagged_msg_type double_tagged_msg(3, 8.0); + ASSERT(is_a<double>(double_tagged_msg), "Wrong type for double_tagged_msg (== double)"); + ASSERT(!is_a<char>(double_tagged_msg), "Wrong type for double_tagged_msg (!= char)"); + ASSERT(!is_a<int>(double_tagged_msg), "Wrong type for double_tagged_msg (!= int)"); + tagged_msg_type copytype(double_tagged_msg); + ASSERT(is_a<double>(copytype), "Wrong type for double_tagged_msg (== double)"); + ASSERT(!is_a<char>(copytype), "Wrong type for double_tagged_msg (!= char)"); + ASSERT(!is_a<int>(copytype), "Wrong type for double_tagged_msg (!= int)"); + tagged_msg_type default_tagged_msg; + ASSERT(!(is_a<double>(default_tagged_msg)), "wrong type for default ( != double)"); + ASSERT(!(is_a<int>(default_tagged_msg)), "wrong type for default ( != int)"); + ASSERT(!(is_a<bool>(default_tagged_msg)), "wrong type for default ( != bool)"); + check_type<int> c; + ASSERT(check_type<int>::check_type_counter == 1, "Incorrect number of check_type<int>s created"); + tagged_msg_type cnt_type(4, c); + ASSERT(check_type<int>::check_type_counter == 2, "Incorrect number of check_type<int>s created"); + ASSERT(is_a<check_type<int> >(cnt_type), "Incorrect type for cnt_type"); + cnt_type = default_tagged_msg; + ASSERT(check_type<int>::check_type_counter == 1, "Incorrect number of check_type<int>s after reassignment"); + ASSERT(cnt_type.is_default_constructed(), "Assigned check_type<int>s is not default-constructed"); + // having problem with init on gcc 3.4.6 (fxeolin16) constructor for elements of array not called + // for this version. + // counted_array_type counted_array; + check_type<int> counted_array[12]; // this is okay + ASSERT(check_type<int>::check_type_counter == 13, "Incorrect number of check_type<int>s after counted_array construction"); + tagged_msg_type counted_array_tagged_msg(5, counted_array); + // the is_a<>() should return exact type matches. + ASSERT(!is_a<check_type<int> *>(counted_array_tagged_msg), "Test of is_a for counted_array_tagged_msg fails"); + #if TBB_USE_EXCEPTIONS + try { + int *iip = cast_to<int *>(counted_array_tagged_msg); + ASSERT(false, "did not throw on invalid cast"); + *iip = 2; // avoids "iip set but not used" warning + } + catch(std::runtime_error &re) { + REMARK("attempt to cast to invalid type caught %s\n", re.what()); + } + ASSERT(is_a<counted_array_type>(counted_array_tagged_msg), "testing"); + const check_type<int> *ctip = cast_to<counted_array_type>(counted_array_tagged_msg); + + ASSERT((int)(*ctip) == 0, "ctip incorrect"); + + ASSERT(check_type<int>::check_type_counter == 25, "Incorrect number of check_type<int>s after counted_array_tagged_msg construction"); + counted_array_tagged_msg = default_tagged_msg; + ASSERT(check_type<int>::check_type_counter == 13, "Incorrect number of check_type<int>s after counted_array_tagged_msg destruction"); + ASSERT(counted_array_tagged_msg.is_default_constructed(), "Assigned counted_array_type is not default-constructed"); + + default_tagged_msg = double_tagged_msg; + const double my_dval = cast_to<double>(default_tagged_msg); + ASSERT(my_dval == 8.0, "did not retrieve correct value from assigned default_tagged_msg"); + + { + odd_array_type my_b; + for(size_t ii=0; ii < 14;++ii) { + my_b[ii] = (char)('0' + ii); + } + my_b[14] = 0; + { + tagged_msg_type odd_array_tagged_msg(6, my_b); + const char *my_copy = cast_to<odd_array_type>(odd_array_tagged_msg); + ASSERT(!strncmp(my_b, my_copy, 14), "copied char array not correct value"); + default_tagged_msg = odd_array_tagged_msg; + try { + const char *my_copy2 = cast_to<odd_array_type>(default_tagged_msg); + ASSERT(!strncmp(my_b, my_copy2, 14), "char array from default tagged_msg assign not correct value"); + } + catch(...) { + ASSERT(false, "Bad cast"); + } + } + } + + ASSERT(!is_a<double>(i), "bad type for i"); + try { + double y = cast_to<double>(i); + // use '&' to force eval of RHS (fixes "initialized but not referenced" vs2012 warnings) + ASSERT(false & (0 != y), "Error: cast to type in tuple did not get exception"); + } + catch(std::runtime_error &bc) { + ASSERT(0 == strcmp(bc.what(), "Illegal tagged_msg cast"), "Incorrect std:runtime_error"); + } + catch(...) { + ASSERT(false & cast_to<int>(i), "Error: improper exception thrown"); + } + + try { + int *ip = cast_to<int *>(i); + ASSERT(false & (NULL!=ip), "Error: non-array cast to pointer type."); + } + catch(std::runtime_error &bc) { + ASSERT(0 == strcmp(bc.what(), "Illegal tagged_msg cast"), "Incorrect std:runtime_error"); + } + catch(...) { + ASSERT(false, "did not get runtime_error exception in casting non-array to pointer"); + } + + try { + bool b = cast_to<bool>(i); + ASSERT(false & b, "Error: cast against type did not get exception"); + } + catch(std::runtime_error &bc) { + ASSERT(0 == strcmp(bc.what(), "Illegal tagged_msg cast"), "Incorrect std:runtime_error"); + } + catch(...) { + ASSERT(false, "did not get runtime_error exception casting to disparate types"); + } + #endif //TBB_USE_EXCEPTIONS +} + +int TestMain() { + TestWrapper(); + ASSERT(check_type<int>::check_type_counter == 0, "After TestWrapper return not all check_type<int>s were destroyed"); + RunTests(); + ASSERT(check_type<int>::check_type_counter == 0, "After RunTests return not all check_type<int>s were destroyed"); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task.cpp new file mode 100644 index 00000000..8e42f3bc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task.cpp @@ -0,0 +1,1345 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_task.h" +#include "tbb/atomic.h" +#include "tbb/tbb_thread.h" +#include "tbb/task_scheduler_init.h" +#include <cstdlib> + +//------------------------------------------------------------------------ +// Test for task::spawn_children and task_list +//------------------------------------------------------------------------ + +class UnboundedlyRecursiveOnUnboundedStealingTask : public tbb::task { + typedef UnboundedlyRecursiveOnUnboundedStealingTask this_type; + + this_type *m_Parent; + const int m_Depth; + volatile bool m_GoAhead; + + // Well, virtually unboundedly, for any practical purpose + static const int max_depth = 1000000; + +public: + UnboundedlyRecursiveOnUnboundedStealingTask( this_type *parent_ = NULL, int depth_ = max_depth ) + : m_Parent(parent_) + , m_Depth(depth_) + , m_GoAhead(true) + {} + + tbb::task* execute() __TBB_override { + // Using large padding array speeds up reaching stealing limit + const int paddingSize = 16 * 1024; + volatile char padding[paddingSize]; + if( !m_Parent || (m_Depth > 0 && m_Parent->m_GoAhead) ) { + if ( m_Parent ) { + // We are stolen, let our parent start waiting for us + m_Parent->m_GoAhead = false; + } + tbb::task &t = *new( allocate_child() ) this_type(this, m_Depth - 1); + set_ref_count( 2 ); + spawn( t ); + // Give a willing thief a chance to steal + for( int i = 0; i < 1000000 && m_GoAhead; ++i ) { + ++padding[i % paddingSize]; + __TBB_Yield(); + } + // If our child has not been stolen yet, then prohibit it siring ones + // of its own (when this thread executes it inside the next wait_for_all) + m_GoAhead = false; + wait_for_all(); + } + return NULL; + } +}; // UnboundedlyRecursiveOnUnboundedStealingTask + +tbb::atomic<int> Count; + +class RecursiveTask: public tbb::task { + const int m_ChildCount; + const int m_Depth; + //! Spawn tasks in list. Exact method depends upon m_Depth&bit_mask. + void SpawnList( tbb::task_list& list, int bit_mask ) { + if( m_Depth&bit_mask ) { + // Take address to check that signature of spawn(task_list&) is static. + void (*s)(tbb::task_list&) = &tbb::task::spawn; + (*s)(list); + ASSERT( list.empty(), NULL ); + wait_for_all(); + } else { + spawn_and_wait_for_all(list); + ASSERT( list.empty(), NULL ); + } + } +public: + RecursiveTask( int child_count, int depth_ ) : m_ChildCount(child_count), m_Depth(depth_) {} + tbb::task* execute() __TBB_override { + ++Count; + if( m_Depth>0 ) { + tbb::task_list list; + ASSERT( list.empty(), NULL ); + for( int k=0; k<m_ChildCount; ++k ) { + list.push_back( *new( allocate_child() ) RecursiveTask(m_ChildCount/2,m_Depth-1 ) ); + ASSERT( !list.empty(), NULL ); + } + set_ref_count( m_ChildCount+1 ); + SpawnList( list, 1 ); + // Now try reusing this as the parent. + set_ref_count(2); + list.push_back( *new ( allocate_child() ) tbb::empty_task() ); + SpawnList( list, 2 ); + } + return NULL; + } +}; + +//! Compute what Count should be after RecursiveTask(child_count,depth) runs. +static int Expected( int child_count, int depth ) { + return depth<=0 ? 1 : 1+child_count*Expected(child_count/2,depth-1); +} + +void TestStealLimit( int nthread ) { +#if __TBB_DEFINE_MIC + REMARK( "skipping steal limiting heuristics for %d threads\n", nthread ); +#else// !_TBB_DEFINE_MIC + REMARK( "testing steal limiting heuristics for %d threads\n", nthread ); + tbb::task_scheduler_init init(nthread); + tbb::task &t = *new( tbb::task::allocate_root() ) UnboundedlyRecursiveOnUnboundedStealingTask(); + tbb::task::spawn_root_and_wait(t); +#endif// _TBB_DEFINE_MIC +} + +//! Test task::spawn( task_list& ) +void TestSpawnChildren( int nthread ) { + REMARK("testing task::spawn(task_list&) for %d threads\n",nthread); + tbb::task_scheduler_init init(nthread); + for( int j=0; j<50; ++j ) { + Count = 0; + RecursiveTask& p = *new( tbb::task::allocate_root() ) RecursiveTask(j,4); + tbb::task::spawn_root_and_wait(p); + int expected = Expected(j,4); + ASSERT( Count==expected, NULL ); + } +} + +//! Test task::spawn_root_and_wait( task_list& ) +void TestSpawnRootList( int nthread ) { + REMARK("testing task::spawn_root_and_wait(task_list&) for %d threads\n",nthread); + tbb::task_scheduler_init init(nthread); + for( int j=0; j<5; ++j ) + for( int k=0; k<10; ++k ) { + Count = 0; + tbb::task_list list; + for( int i=0; i<k; ++i ) + list.push_back( *new( tbb::task::allocate_root() ) RecursiveTask(j,4) ); + tbb::task::spawn_root_and_wait(list); + int expected = k*Expected(j,4); + ASSERT( Count==expected, NULL ); + } +} + +//------------------------------------------------------------------------ +// Test for task::recycle_as_safe_continuation +//------------------------------------------------------------------------ + +void TestSafeContinuation( int nthread ) { + REMARK("testing task::recycle_as_safe_continuation for %d threads\n",nthread); + tbb::task_scheduler_init init(nthread); + for( int j=8; j<33; ++j ) { + TaskGenerator& p = *new( tbb::task::allocate_root() ) TaskGenerator(j,5); + tbb::task::spawn_root_and_wait(p); + } +} + +//------------------------------------------------------------------------ +// Test affinity interface +//------------------------------------------------------------------------ +tbb::atomic<int> TotalCount; + +struct AffinityTask: public tbb::task { + const affinity_id expected_affinity_id; + bool noted; + /** Computing affinities is NOT supported by TBB, and may disappear in the future. + It is done here for sake of unit testing. */ + AffinityTask( int expected_affinity_id_ ) : + expected_affinity_id(affinity_id(expected_affinity_id_)), + noted(false) + { + set_affinity(expected_affinity_id); + ASSERT( 0u-expected_affinity_id>0u, "affinity_id not an unsigned integral type?" ); + ASSERT( affinity()==expected_affinity_id, NULL ); + } + tbb::task* execute() __TBB_override { + ++TotalCount; + return NULL; + } + void note_affinity( affinity_id id ) __TBB_override { + // There is no guarantee in TBB that a task runs on its affinity thread. + // However, the current implementation does accidentally guarantee it + // under certain conditions, such as the conditions here. + // We exploit those conditions for sake of unit testing. + ASSERT( id!=expected_affinity_id, NULL ); + ASSERT( !noted, "note_affinity_id called twice!" ); + ASSERT ( &self() == (tbb::task*)this, "Wrong innermost running task" ); + noted = true; + } +}; + +/** Note: This test assumes a lot about the internal implementation of affinity. + Do NOT use this as an example of good programming practice with TBB */ +void TestAffinity( int nthread ) { + TotalCount = 0; + int n = tbb::task_scheduler_init::default_num_threads(); + if( n>nthread ) + n = nthread; + tbb::task_scheduler_init init(n); + tbb::empty_task* t = new( tbb::task::allocate_root() ) tbb::empty_task; + tbb::task::affinity_id affinity_id = t->affinity(); + ASSERT( affinity_id==0, NULL ); + // Set ref_count for n-1 children, plus 1 for the wait. + t->set_ref_count(n); + // Spawn n-1 affinitized children. + for( int i=1; i<n; ++i ) + tbb::task::spawn( *new(t->allocate_child()) AffinityTask(i) ); + if( n>1 ) { + // Keep master from stealing + while( TotalCount!=n-1 ) + __TBB_Yield(); + } + // Wait for the children + t->wait_for_all(); + int k = 0; + GetTaskPtr(k)->destroy(*t); + ASSERT(k==1,NULL); +} + +struct NoteAffinityTask: public tbb::task { + bool noted; + NoteAffinityTask( int id ) : noted(false) + { + set_affinity(affinity_id(id)); + } + ~NoteAffinityTask () { + ASSERT (noted, "note_affinity has not been called"); + } + tbb::task* execute() __TBB_override { + return NULL; + } + void note_affinity( affinity_id /*id*/ ) __TBB_override { + noted = true; + ASSERT ( &self() == (tbb::task*)this, "Wrong innermost running task" ); + } +}; + +// This test checks one of the paths inside the scheduler by affinitizing the child task +// to non-existent thread so that it is proxied in the local task pool but not retrieved +// by another thread. +// If no workers requested, the extra slot #2 is allocated for a worker thread to serve +// "enqueued" tasks. In this test, it is used only for the affinity purpose. +void TestNoteAffinityContext() { + tbb::task_scheduler_init init(1); + tbb::empty_task* t = new( tbb::task::allocate_root() ) tbb::empty_task; + t->set_ref_count(2); + // This master in the absence of workers will have an affinity id of 1. + // So use another number to make the task get proxied. + tbb::task::spawn( *new(t->allocate_child()) NoteAffinityTask(2) ); + t->wait_for_all(); + tbb::task::destroy(*t); +} + +//------------------------------------------------------------------------ +// Test that recovery actions work correctly for task::allocate_* methods +// when a task's constructor throws an exception. +//------------------------------------------------------------------------ + +#if TBB_USE_EXCEPTIONS +static int TestUnconstructibleTaskCount; + +struct ConstructionFailure { +}; + +#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED + // Suppress pointless "unreachable code" warning. + #pragma warning (push) + #pragma warning (disable: 4702) +#endif + +//! Task that cannot be constructed. +template<size_t N> +struct UnconstructibleTask: public tbb::empty_task { + char space[N]; + UnconstructibleTask() { + throw ConstructionFailure(); + } +}; + +#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED + #pragma warning (pop) +#endif + +#define TRY_BAD_CONSTRUCTION(x) \ + { \ + try { \ + new(x) UnconstructibleTask<N>; \ + } catch( const ConstructionFailure& ) { \ + ASSERT( parent()==original_parent, NULL ); \ + ASSERT( ref_count()==original_ref_count, "incorrectly changed ref_count" );\ + ++TestUnconstructibleTaskCount; \ + } \ + } + +template<size_t N> +struct RootTaskForTestUnconstructibleTask: public tbb::task { + tbb::task* execute() __TBB_override { + tbb::task* original_parent = parent(); + ASSERT( original_parent!=NULL, NULL ); + int original_ref_count = ref_count(); + TRY_BAD_CONSTRUCTION( allocate_root() ); + TRY_BAD_CONSTRUCTION( allocate_child() ); + TRY_BAD_CONSTRUCTION( allocate_continuation() ); + TRY_BAD_CONSTRUCTION( allocate_additional_child_of(*this) ); + return NULL; + } +}; + +template<size_t N> +void TestUnconstructibleTask() { + TestUnconstructibleTaskCount = 0; + tbb::task_scheduler_init init; + tbb::task* t = new( tbb::task::allocate_root() ) RootTaskForTestUnconstructibleTask<N>; + tbb::task::spawn_root_and_wait(*t); + ASSERT( TestUnconstructibleTaskCount==4, NULL ); +} +#endif /* TBB_USE_EXCEPTIONS */ + +//------------------------------------------------------------------------ +// Test for alignment problems with task objects. +//------------------------------------------------------------------------ + +#if _MSC_VER && !defined(__INTEL_COMPILER) + // Workaround for pointless warning "structure was padded due to __declspec(align()) + #pragma warning (push) + #pragma warning (disable: 4324) +#endif + +//! Task with members of type T. +/** The task recursively creates tasks. */ +template<typename T> +class TaskWithMember: public tbb::task { + T x; + T y; + unsigned char count; + tbb::task* execute() __TBB_override { + x = y; + if( count>0 ) { + set_ref_count(2); + tbb::task* t = new( allocate_child() ) TaskWithMember<T>(count-1); + spawn_and_wait_for_all(*t); + } + return NULL; + } +public: + TaskWithMember( unsigned char n ) : count(n) {} +}; + +#if _MSC_VER && !defined(__INTEL_COMPILER) + #pragma warning (pop) +#endif + +template<typename T> +void TestAlignmentOfOneClass() { + typedef TaskWithMember<T> task_type; + tbb::task* t = new( tbb::task::allocate_root() ) task_type(10); + tbb::task::spawn_root_and_wait(*t); +} + +#include "harness_m128.h" + +void TestAlignment() { + REMARK("testing alignment\n"); + tbb::task_scheduler_init init; + // Try types that have variety of alignments + TestAlignmentOfOneClass<char>(); + TestAlignmentOfOneClass<short>(); + TestAlignmentOfOneClass<int>(); + TestAlignmentOfOneClass<long>(); + TestAlignmentOfOneClass<void*>(); + TestAlignmentOfOneClass<float>(); + TestAlignmentOfOneClass<double>(); +#if HAVE_m128 + TestAlignmentOfOneClass<__m128>(); +#endif +#if HAVE_m256 + if (have_AVX()) TestAlignmentOfOneClass<__m256>(); +#endif +} + +//------------------------------------------------------------------------ +// Test for recursing on left while spawning on right +//------------------------------------------------------------------------ + +int Fib( int n ); + +struct RightFibTask: public tbb::task { + int* y; + const int n; + RightFibTask( int* y_, int n_ ) : y(y_), n(n_) {} + task* execute() __TBB_override { + *y = Fib(n-1); + return 0; + } +}; + +int Fib( int n ) { + if( n<2 ) { + return n; + } else { + // y actually does not need to be initialized. It is initialized solely to suppress + // a gratuitous warning "potentially uninitialized local variable". + int y=-1; + tbb::task* root_task = new( tbb::task::allocate_root() ) tbb::empty_task; + root_task->set_ref_count(2); + tbb::task::spawn( *new( root_task->allocate_child() ) RightFibTask(&y,n) ); + int x = Fib(n-2); + root_task->wait_for_all(); + tbb::task::destroy(*root_task); + return y+x; + } +} + +void TestLeftRecursion( int p ) { + REMARK("testing non-spawned roots for %d threads\n",p); + tbb::task_scheduler_init init(p); + int sum = 0; + for( int i=0; i<100; ++i ) + sum +=Fib(10); + ASSERT( sum==5500, NULL ); +} + +//------------------------------------------------------------------------ +// Test for computing with DAG of tasks. +//------------------------------------------------------------------------ + +class DagTask: public tbb::task { + typedef unsigned long long number_t; + const int i, j; + number_t sum_from_left, sum_from_above; + void check_sum( number_t sum ) { + number_t expected_sum = 1; + for( int k=i+1; k<=i+j; ++k ) + expected_sum *= k; + for( int k=1; k<=j; ++k ) + expected_sum /= k; + ASSERT(sum==expected_sum, NULL); + } +public: + DagTask *successor_to_below, *successor_to_right; + DagTask( int i_, int j_ ) : i(i_), j(j_), sum_from_left(0), sum_from_above(0) {} + task* execute() __TBB_override { + ASSERT( ref_count()==0, NULL ); + number_t sum = i==0 && j==0 ? 1 : sum_from_left+sum_from_above; + check_sum(sum); + ++execution_count; + if( DagTask* t = successor_to_right ) { + t->sum_from_left = sum; + if( t->decrement_ref_count()==0 ) + // Test using spawn to evaluate DAG + spawn( *t ); + } + if( DagTask* t = successor_to_below ) { + t->sum_from_above = sum; + if( t->add_ref_count(-1)==0 ) + // Test using bypass to evaluate DAG + return t; + } + return NULL; + } + ~DagTask() {++destruction_count;} + static tbb::atomic<int> execution_count; + static tbb::atomic<int> destruction_count; +}; + +tbb::atomic<int> DagTask::execution_count; +tbb::atomic<int> DagTask::destruction_count; + +void TestDag( int p ) { + REMARK("testing evaluation of DAG for %d threads\n",p); + tbb::task_scheduler_init init(p); + DagTask::execution_count=0; + DagTask::destruction_count=0; + const int n = 10; + DagTask* a[n][n]; + for( int i=0; i<n; ++i ) + for( int j=0; j<n; ++j ) + a[i][j] = new( tbb::task::allocate_root() ) DagTask(i,j); + for( int i=0; i<n; ++i ) + for( int j=0; j<n; ++j ) { + a[i][j]->successor_to_below = i+1<n ? a[i+1][j] : NULL; + a[i][j]->successor_to_right = j+1<n ? a[i][j+1] : NULL; + a[i][j]->set_ref_count((i>0)+(j>0)); + } + a[n-1][n-1]->increment_ref_count(); + a[n-1][n-1]->spawn_and_wait_for_all(*a[0][0]); + ASSERT( DagTask::execution_count == n*n - 1, NULL ); + tbb::task::destroy(*a[n-1][n-1]); + ASSERT( DagTask::destruction_count > n*n - p, NULL ); + while ( DagTask::destruction_count != n*n ) + __TBB_Yield(); +} + +#include "harness_barrier.h" + +class RelaxedOwnershipTask: public tbb::task { + tbb::task &m_taskToSpawn, + &m_taskToDestroy, + &m_taskToExecute; + static Harness::SpinBarrier m_barrier; + + tbb::task* execute () __TBB_override { + tbb::task &p = *parent(); + tbb::task &r = *new( allocate_root() ) tbb::empty_task; + r.set_ref_count( 1 ); + m_barrier.wait(); + p.spawn( *new(p.allocate_child()) tbb::empty_task ); + p.spawn( *new(task::allocate_additional_child_of(p)) tbb::empty_task ); + p.spawn( m_taskToSpawn ); + p.destroy( m_taskToDestroy ); + r.spawn_and_wait_for_all( m_taskToExecute ); + p.destroy( r ); + return NULL; + } +public: + RelaxedOwnershipTask ( tbb::task& toSpawn, tbb::task& toDestroy, tbb::task& toExecute ) + : m_taskToSpawn(toSpawn) + , m_taskToDestroy(toDestroy) + , m_taskToExecute(toExecute) + {} + static void SetBarrier ( int numThreads ) { m_barrier.initialize( numThreads ); } +}; + +Harness::SpinBarrier RelaxedOwnershipTask::m_barrier; + +void TestRelaxedOwnership( int p ) { + if ( p < 2 ) + return; + + if( unsigned(p)>tbb::tbb_thread::hardware_concurrency() ) + return; + + REMARK("testing tasks exercising relaxed ownership freedom for %d threads\n", p); + tbb::task_scheduler_init init(p); + RelaxedOwnershipTask::SetBarrier(p); + tbb::task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + tbb::task_list tl; + for ( int i = 0; i < p; ++i ) { + tbb::task &tS = *new( r.allocate_child() ) tbb::empty_task, + &tD = *new( r.allocate_child() ) tbb::empty_task, + &tE = *new( r.allocate_child() ) tbb::empty_task; + tl.push_back( *new( r.allocate_child() ) RelaxedOwnershipTask(tS, tD, tE) ); + } + r.set_ref_count( 5 * p + 1 ); + int k=0; + GetTaskPtr(k)->spawn( tl ); + ASSERT(k==1,NULL); + r.wait_for_all(); + r.destroy( r ); +} + +//------------------------------------------------------------------------ +// Test for running TBB scheduler on user-created thread. +//------------------------------------------------------------------------ + +void RunSchedulerInstanceOnUserThread( int n_child ) { + tbb::task* e = new( tbb::task::allocate_root() ) tbb::empty_task; + e->set_ref_count(1+n_child); + for( int i=0; i<n_child; ++i ) + tbb::task::spawn( *new(e->allocate_child()) tbb::empty_task ); + e->wait_for_all(); + e->destroy(*e); +} + +void TestUserThread( int p ) { + tbb::task_scheduler_init init(p); + // Try with both 0 and 1 children. Only the latter scenario permits stealing. + for( int n_child=0; n_child<2; ++n_child ) { + tbb::tbb_thread t( RunSchedulerInstanceOnUserThread, n_child ); + t.join(); + } +} + +class TaskWithChildToSteal : public tbb::task { + const int m_Depth; + volatile bool m_GoAhead; + +public: + TaskWithChildToSteal( int depth_ ) + : m_Depth(depth_) + , m_GoAhead(false) + {} + + tbb::task* execute() __TBB_override { + m_GoAhead = true; + if ( m_Depth > 0 ) { + TaskWithChildToSteal &t = *new( allocate_child() ) TaskWithChildToSteal(m_Depth - 1); + t.SpawnAndWaitOnParent(); + } + else + Harness::Sleep(50); // The last task in chain sleeps for 50 ms + return NULL; + } + + void SpawnAndWaitOnParent() { + parent()->set_ref_count( 2 ); + parent()->spawn( *this ); + while (!this->m_GoAhead ) + __TBB_Yield(); + parent()->wait_for_all(); + } +}; // TaskWithChildToSteal + +// Success criterion of this test is not hanging +void TestDispatchLoopResponsiveness() { + REMARK("testing that dispatch loops do not go into eternal sleep when all remaining children are stolen\n"); + // Recursion depth values test the following sorts of dispatch loops + // 0 - master's outermost + // 1 - worker's nested + // 2 - master's nested + tbb::task_scheduler_init init(2); + tbb::task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + for ( int depth = 0; depth < 3; ++depth ) { + TaskWithChildToSteal &t = *new( r.allocate_child() ) TaskWithChildToSteal(depth); + t.SpawnAndWaitOnParent(); + } + r.destroy(r); +} + +void TestWaitDiscriminativenessWithoutStealing() { + REMARK( "testing that task::wait_for_all is specific to the root it is called on (no workers)\n" ); + // The test relies on the strict LIFO scheduling order in the absence of workers + tbb::task_scheduler_init init(1); + tbb::task &r1 = *new( tbb::task::allocate_root() ) tbb::empty_task; + tbb::task &r2 = *new( tbb::task::allocate_root() ) tbb::empty_task; + const int NumChildren = 10; + r1.set_ref_count( NumChildren + 1 ); + r2.set_ref_count( NumChildren + 1 ); + for( int i=0; i < NumChildren; ++i ) { + tbb::empty_task &t1 = *new( r1.allocate_child() ) tbb::empty_task; + tbb::empty_task &t2 = *new( r2.allocate_child() ) tbb::empty_task; + tbb::task::spawn(t1); + tbb::task::spawn(t2); + } + r2.wait_for_all(); + ASSERT( r2.ref_count() <= 1, "Not all children of r2 executed" ); + ASSERT( r1.ref_count() > 1, "All children of r1 prematurely executed" ); + r1.wait_for_all(); + ASSERT( r1.ref_count() <= 1, "Not all children of r1 executed" ); + r1.destroy(r1); + r2.destroy(r2); +} + + +using tbb::internal::spin_wait_until_eq; + +//! Deterministic emulation of a long running task +class LongRunningTask : public tbb::task { + volatile bool& m_CanProceed; + + tbb::task* execute() __TBB_override { + spin_wait_until_eq( m_CanProceed, true ); + return NULL; + } +public: + LongRunningTask ( volatile bool& canProceed ) : m_CanProceed(canProceed) {} +}; + +void TestWaitDiscriminativenessWithStealing() { + if( tbb::tbb_thread::hardware_concurrency() < 2 ) + return; + REMARK( "testing that task::wait_for_all is specific to the root it is called on (one worker)\n" ); + volatile bool canProceed = false; + tbb::task_scheduler_init init(2); + tbb::task &r1 = *new( tbb::task::allocate_root() ) tbb::empty_task; + tbb::task &r2 = *new( tbb::task::allocate_root() ) tbb::empty_task; + r1.set_ref_count( 2 ); + r2.set_ref_count( 2 ); + tbb::task& t1 = *new( r1.allocate_child() ) tbb::empty_task; + tbb::task& t2 = *new( r2.allocate_child() ) LongRunningTask(canProceed); + tbb::task::spawn(t2); + tbb::task::spawn(t1); + r1.wait_for_all(); + ASSERT( r1.ref_count() <= 1, "Not all children of r1 executed" ); + ASSERT( r2.ref_count() == 2, "All children of r2 prematurely executed" ); + canProceed = true; + r2.wait_for_all(); + ASSERT( r2.ref_count() <= 1, "Not all children of r2 executed" ); + r1.destroy(r1); + r2.destroy(r2); +} + +struct MasterBody : NoAssign, Harness::NoAfterlife { + static Harness::SpinBarrier my_barrier; + + class BarrenButLongTask : public tbb::task { + volatile bool& m_Started; + volatile bool& m_CanProceed; + + tbb::task* execute() __TBB_override { + m_Started = true; + spin_wait_until_eq( m_CanProceed, true ); + volatile int k = 0; + for ( int i = 0; i < 1000000; ++i ) ++k; + return NULL; + } + public: + BarrenButLongTask ( volatile bool& started, volatile bool& can_proceed ) + : m_Started(started), m_CanProceed(can_proceed) + {} + }; + + class BinaryRecursiveTask : public tbb::task { + int m_Depth; + + tbb::task* execute() __TBB_override { + if( !m_Depth ) + return NULL; + set_ref_count(3); + spawn( *new( allocate_child() ) BinaryRecursiveTask(m_Depth - 1) ); + spawn( *new( allocate_child() ) BinaryRecursiveTask(m_Depth - 1) ); + wait_for_all(); + return NULL; + } + + void note_affinity( affinity_id ) __TBB_override { + ASSERT( false, "These tasks cannot be stolen" ); + } + public: + BinaryRecursiveTask ( int depth_ ) : m_Depth(depth_) {} + }; + + void operator() ( int id ) const { + if ( id ) { + tbb::task_scheduler_init init(2); + volatile bool child_started = false, + can_proceed = false; + tbb::task& r = *new( tbb::task::allocate_root() ) tbb::empty_task; + r.set_ref_count(2); + r.spawn( *new(r.allocate_child()) BarrenButLongTask(child_started, can_proceed) ); + spin_wait_until_eq( child_started, true ); + my_barrier.wait(); + can_proceed = true; + r.wait_for_all(); + r.destroy(r); + } + else { + my_barrier.wait(); + tbb::task_scheduler_init init(1); + Count = 0; + int depth = 16; + BinaryRecursiveTask& r = *new( tbb::task::allocate_root() ) BinaryRecursiveTask(depth); + tbb::task::spawn_root_and_wait(r); + } + } +public: + MasterBody ( int num_masters ) { my_barrier.initialize(num_masters); } +}; + +Harness::SpinBarrier MasterBody::my_barrier; + +/** Ensures that tasks spawned by a master thread or one of the workers servicing + it cannot be stolen by another master thread. **/ +void TestMastersIsolation ( int p ) { + // The test requires at least 3-way parallelism to work correctly + if ( p > 2 && tbb::task_scheduler_init::default_num_threads() >= p ) { + tbb::task_scheduler_init init(p); + NativeParallelFor( p, MasterBody(p) ); + } +} + +struct waitable_task : tbb::task { + tbb::task* execute() __TBB_override { + recycle_as_safe_continuation(); // do not destroy the task after execution + set_parent(this); // decrement its own ref_count after completion + __TBB_Yield(); + return NULL; + } +}; +void TestWaitableTask() { + waitable_task &wt = *new( tbb::task::allocate_root() ) waitable_task; + for( int i = 0; i < 100000; i++ ) { + wt.set_ref_count(2); // prepare for waiting on it + wt.spawn(wt); + if( i&1 ) __TBB_Yield(); + wt.wait_for_all(); + } + wt.set_parent(NULL); // prevents assertions and atomics in task::destroy + tbb::task::destroy(wt); +} + +#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_TASK_PRIORITY +#include <stdexcept> +#include <vector> +#include <map> +#include "tbb/parallel_for.h" + +namespace CriticalTaskSupport { + +using tbb::task; +task* g_root_task = NULL; + +// markers to capture execution profile (declaration order is important) +enum task_marker_t { + no_task, regular_task, isolated_regular_task, + outer_critical_task, nested_critical_task, critical_from_isolated_task, bypassed_critical_task +}; +enum bypassed_critical_task_stage_t { not_bypassed, bypassed, executed }; + +typedef std::vector< std::vector<task_marker_t> > task_map_t; +task_map_t g_execution_profile; + +const int g_per_thread_regular_tasks_num = 5; +const int g_isolated_regular_task_num = 3; +tbb::atomic<bool> g_is_critical_task_submitted; +size_t g_bypassed_critical_task_index = size_t(-1); +task* g_bypassed_task_pointer = NULL; +int g_bypassed_task_creator = -1; +tbb::atomic<bypassed_critical_task_stage_t> g_bypassed_critical_task_stage; +tbb::task_arena g_arena; +Harness::SpinBarrier g_spin_barrier; + +struct parallel_for_body { + parallel_for_body(task_marker_t task_marker, bool submit_critical = false) + : my_task_marker(task_marker), my_submit_critical(submit_critical) {} + void operator()( int i ) const; +private: + task_marker_t my_task_marker; + bool my_submit_critical; +}; + +struct IsolatedFunctor { + void operator()() const { + parallel_for_body body(isolated_regular_task, /*submit_critical=*/ true); + tbb::parallel_for( 0, g_isolated_regular_task_num, body, tbb::simple_partitioner() ); + } +}; + +struct CriticalTaskBody : public task { + CriticalTaskBody(task_marker_t task_marker) : my_task_mark(task_marker) {} + task* execute() __TBB_override { + task* ret_task = NULL; + task* nested_task = NULL; + int thread_idx = tbb::this_task_arena::current_thread_index(); + g_execution_profile[thread_idx].push_back(my_task_mark); + switch( my_task_mark ) { + case outer_critical_task: + g_spin_barrier.wait(); // allow each thread to take its own critical task + // prefill queue with critical tasks + nested_task = new( task::allocate_additional_child_of(*g_root_task) ) + CriticalTaskBody(nested_critical_task); + enqueue( *nested_task, tbb::priority_t(tbb::internal::priority_critical) ); + if( not_bypassed == + g_bypassed_critical_task_stage.compare_and_swap(bypassed, not_bypassed) ) { + + // first, should process all the work from isolated region + tbb::this_task_arena::isolate( IsolatedFunctor() ); + + CriticalTaskBody* bypassed_task = + new( task::allocate_additional_child_of(*g_root_task) ) + CriticalTaskBody(bypassed_critical_task); + g_bypassed_task_pointer = bypassed_task; + g_bypassed_critical_task_index = g_execution_profile[thread_idx].size() + 1; + g_bypassed_task_creator = thread_idx; + tbb::internal::make_critical(*bypassed_task); + ret_task = bypassed_task; + } + g_spin_barrier.wait(); // allow thread to execute isolated region + break; + case nested_critical_task: + // wait until bypassed critical task has been executed + g_spin_barrier.wait(); + break; + case bypassed_critical_task: + ASSERT( bypassed == g_bypassed_critical_task_stage, "Unexpected bypassed critical task" ); + g_bypassed_critical_task_stage = executed; + ASSERT( thread_idx == g_bypassed_task_creator, + "Bypassed critical task is not being executed by the thread that bypassed it." ); + ASSERT( g_bypassed_task_pointer == this, "This is not bypassed task." ); + ASSERT( g_bypassed_critical_task_index == g_execution_profile[thread_idx].size(), + "Bypassed critical task was not selected as the next task." ); + break; + case critical_from_isolated_task: + break; + default: + ASSERT( false, "Incorrect critical task id." ); + } + return ret_task; + } +private: + task_marker_t my_task_mark; +}; + +void parallel_for_body::operator()( int i ) const { + int thread_idx = tbb::this_task_arena::current_thread_index(); + g_execution_profile[thread_idx].push_back(my_task_marker); + if( my_submit_critical && i == 0 ) { + task* isolated_task = new( task::allocate_additional_child_of(*g_root_task) ) + CriticalTaskBody(critical_from_isolated_task); + task::enqueue( *isolated_task, tbb::priority_t(tbb::internal::priority_critical) ); + } +} + +struct TaskBody: public task { + TaskBody() {} + TaskBody(task_marker_t /*mark*/) {} + task* execute() __TBB_override { + int thread_idx = tbb::this_task_arena::current_thread_index(); + g_execution_profile[thread_idx].push_back(regular_task); + if( !g_is_critical_task_submitted ) { + g_spin_barrier.wait(); // allow each thread to take its own task. + // prefill task pools with regular tasks + int half = g_per_thread_regular_tasks_num / 2; + for( int i = 0; i < half; ++i ) { + task& t = *new( task::allocate_additional_child_of(*g_root_task) ) + TaskBody; + spawn(t); + } + { + // prefill with critical tasks + task& t = *new( task::allocate_additional_child_of(*g_root_task) ) + CriticalTaskBody(outer_critical_task); + tbb::internal::make_critical(t); + tbb::task::spawn(t); + } + // prefill task pools with regular tasks + for( int i = half; i < g_per_thread_regular_tasks_num; ++i ) { + task& t = *new( task::allocate_additional_child_of(*g_root_task) ) + TaskBody; + spawn(t); + } + g_is_critical_task_submitted.store<tbb::relaxed>(true); + g_spin_barrier.wait(); + } + return NULL; + } +}; + +template<typename TaskType, void(*submit_task)(task&)> +struct WorkCreator { + WorkCreator(task*& root_task, size_t num_tasks, size_t num_critical_tasks = 0, + tbb::task_group_context* ctx = NULL) + : my_root_task(root_task), my_num_tasks(num_tasks), my_num_critical_tasks(num_critical_tasks), + my_context(ctx) {} + void operator()() const { + ASSERT( my_root_task == NULL, "Incorrect test set up." ); + task* root_task = NULL; + if( my_context ) + root_task = new( task::allocate_root(*my_context) ) TaskType(regular_task); + else + root_task = new( task::allocate_root() ) TaskType(regular_task); + root_task->increment_ref_count(); + for( size_t i = 0; i < my_num_tasks; ++i ) { + task& t = *new( task::allocate_additional_child_of(*root_task) ) TaskType(regular_task); + submit_task(t); + } + for( size_t i = 0; i < my_num_critical_tasks; ++i ) { + task& t = *new( task::allocate_additional_child_of(*root_task) ) + TaskType( outer_critical_task ); + tbb::task::enqueue( t, tbb::priority_t(tbb::internal::priority_critical) ); + } + my_root_task = root_task; + } +private: + task*& my_root_task; + size_t my_num_tasks; + size_t my_num_critical_tasks; + tbb::task_group_context* my_context; +}; + +struct WorkAwaiter { + WorkAwaiter(task*& root_task) : my_root_task(root_task) {} + void operator()() const { + while( !my_root_task ) __TBB_Yield(); // waiting on a tree construction + my_root_task->wait_for_all(); + task::destroy(*my_root_task); + my_root_task = NULL; + } +private: + task*& my_root_task; +}; + +void TestSchedulerTaskSelectionWhenSpawn() { + REMARK( "\tPreferring critical tasks among spawned\n" ); + typedef std::multimap<task_marker_t, task_marker_t> state_machine_t; + typedef state_machine_t::iterator states_it; + task_marker_t from_to_pairs[] = { + // from regular + regular_task, regular_task, + regular_task, outer_critical_task, + // from outermost critical + outer_critical_task, isolated_regular_task, + outer_critical_task, critical_from_isolated_task, + outer_critical_task, nested_critical_task, + // from isolated regular + isolated_regular_task, isolated_regular_task, + isolated_regular_task, critical_from_isolated_task, + isolated_regular_task, bypassed_critical_task, + // from critical that was enqueued from isolated region + critical_from_isolated_task, isolated_regular_task, + critical_from_isolated_task, nested_critical_task, + critical_from_isolated_task, regular_task, + critical_from_isolated_task, bypassed_critical_task, + // from bypassed critical + bypassed_critical_task, nested_critical_task, + bypassed_critical_task, critical_from_isolated_task, + // from nested critical + nested_critical_task, critical_from_isolated_task, + nested_critical_task, regular_task + }; + + state_machine_t allowed_transitions; + for( size_t i = 0; i < sizeof(from_to_pairs) / sizeof(from_to_pairs[0]); i += 2 ) + allowed_transitions.insert( std::make_pair( from_to_pairs[i], from_to_pairs[i+1] ) ); + + for( int num_threads = MinThread; num_threads <= MaxThread; ++num_threads ) { + for( int repeat = 0; repeat < 10; ++repeat ) { + // test initialization + g_bypassed_critical_task_stage = not_bypassed; + g_is_critical_task_submitted = false; + g_bypassed_critical_task_index = size_t(-1); + g_bypassed_task_creator = -1; + g_bypassed_task_pointer = NULL; + g_execution_profile.resize(num_threads); + g_spin_barrier.initialize(num_threads); + g_arena.initialize(num_threads); + + // test execution + g_arena.execute( + WorkCreator<TaskBody, task::spawn>(g_root_task, /*num_tasks=*/size_t(num_threads)) ); + g_arena.execute( WorkAwaiter(g_root_task) ); + + // checking how execution went + int critical_task_count = 0; + for( int thread = 0; thread < num_threads; ++thread ) { + bool started_critical_region = false; + bool pass_through_critical_region = false; + size_t thread_task_num = g_execution_profile[thread].size(); + for( size_t task_index = 0; task_index < thread_task_num; ++task_index ) { + const task_marker_t& executed_task = g_execution_profile[thread][task_index]; + + if( pass_through_critical_region ) { + ASSERT( executed_task < outer_critical_task, + "Thread did not process all the critical work at once." ); + } else if( isolated_regular_task <= executed_task && + executed_task <= bypassed_critical_task) { + started_critical_region = true; + if( isolated_regular_task < executed_task ) + ++critical_task_count; + if( bypassed_critical_task == executed_task ) { + size_t expected_bypass_task_min_index = + /* number of regular task before critical region */1 + + /* number of outermost critical tasks before isolated region */ 1 + + g_isolated_regular_task_num; + size_t expected_bypass_task_max_index = expected_bypass_task_min_index + + /* number of critical tasks inside isolated region */ 1; + ASSERT( expected_bypass_task_min_index <= task_index && + task_index <= expected_bypass_task_max_index, + "Bypassed critical task has been executed in wrong order" ); + } + } else if( started_critical_region ) { + pass_through_critical_region = true; + started_critical_region = false; + } + + if( thread_task_num - 1 == task_index ) + continue; // no transition check for the last executed task + const task_marker_t& next_task = g_execution_profile[thread][task_index + 1]; + std::pair<states_it, states_it> range = + allowed_transitions.equal_range( executed_task ); + bool is_choosen_task_allowed = false; + for (states_it it = range.first; it != range.second; ++it) { + is_choosen_task_allowed |= next_task == it->second; + } + ASSERT( is_choosen_task_allowed, "Thread chose incorrect task for execution." ); + } + } + ASSERT( critical_task_count == 2 * num_threads + 2, "Wrong number of critical tasks" ); + ASSERT( g_bypassed_critical_task_stage == executed, "Was bypassed critical task executed?" ); + + // test deinitialization + g_execution_profile.clear(); + g_arena.terminate(); + } + } +} + +struct TaskTypeExecutionMarker : public task { + TaskTypeExecutionMarker( task_marker_t mark ) : my_mark( mark ) {} + task* execute() __TBB_override { + g_execution_profile[tbb::this_task_arena::current_thread_index()].push_back( my_mark ); + return NULL; + } +private: + task_marker_t my_mark; +}; + +struct RegularTaskMarkChecker { + bool operator()(const task_marker_t& m) { return regular_task == m; } +}; + +void TestSchedulerTaskSelectionWhenEnqueue() { + REMARK( "\tPreferring critical tasks among enqueued\n" ); + g_execution_profile.clear(); + // creating two profiles because of enforced concurrency + g_execution_profile.resize(2); + g_root_task = NULL; + unsigned task_num = 99; + unsigned num_critical_tasks = 1; + g_arena.initialize( /*num_threads=*/1, /*reserved_for_masters=*/0 ); + g_arena.enqueue( + WorkCreator<TaskTypeExecutionMarker, task::enqueue>( + g_root_task, task_num, num_critical_tasks) + ); + WorkAwaiter awaiter(g_root_task); awaiter(); // waiting outside arena + g_arena.terminate(); + + unsigned idx = !g_execution_profile[1].empty(); + ASSERT( g_execution_profile[!idx].empty(), "" ); + + ASSERT( g_execution_profile[idx].size() == task_num + num_critical_tasks, + "Incorrect number of tasks executed" ); + ASSERT( *(g_execution_profile[idx].end() - 1) == outer_critical_task, + "Critical task was executed in wrong order. It should be the last one." ); + bool all_regular = true; + for( std::vector<task_marker_t>::const_iterator it = g_execution_profile[idx].begin(); + it != g_execution_profile[idx].end() - 1; ++it ) + all_regular &= regular_task == *it; + ASSERT( all_regular, "Critical task was executed in wrong order. It should be the last one." ); +} + +enum ways_to_cancel_t { + by_explicit_call = 0, + by_exception, + no_cancellation +}; + +tbb::atomic<size_t> g_num_executed_from_cancelled_context; +tbb::atomic<size_t> g_num_executed_from_working_context; +int g_cancelling_task_id = -1; + +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (push) +#pragma warning (disable: 4127) /* suppress conditional expression is constant */ +#endif + +template<bool cancelled_group> +struct ATask : public task { + ATask( task_marker_t /*mark*/ ) : my_cancellation_method( no_cancellation ) {} + ATask( ways_to_cancel_t cancellation_method ) : my_cancellation_method( cancellation_method ) {} + task* execute() __TBB_override { + while( ! g_is_critical_task_submitted ) __TBB_Yield(); + // scheduler should take critical task as the next task for execution. + bypassed_critical_task_stage_t previous_critical_task_stage = + g_bypassed_critical_task_stage.compare_and_swap(bypassed, not_bypassed); + while( + cancelled_group // Only tasks from cancelled group wait + && !this->is_cancelled() // for their group to be cancelled + && !tbb::internal::is_critical(*this) // allowing thread that took critical task + && bypassed == previous_critical_task_stage // to proceed and cancel the whole group. + ) __TBB_Yield(); + if( cancelled_group ) + ++g_num_executed_from_cancelled_context; + else + ++g_num_executed_from_working_context; + switch( my_cancellation_method ) { + case by_explicit_call: + g_cancelling_task_id = int(g_num_executed_from_cancelled_context); + self().cancel_group_execution(); + break; + case by_exception: + g_cancelling_task_id = int(g_num_executed_from_cancelled_context); + throw std::runtime_error("Exception data"); + break; + case no_cancellation: break; + default: + ASSERT( false, "Should not be here!" ); + break; + } + return NULL; + } +private: + ways_to_cancel_t my_cancellation_method; +}; + +#if _MSC_VER && !__INTEL_COMPILER +#pragma warning (pop) +#endif + +template<void(*submit_task)(task&)> +struct SubmitTaskFunctor { + SubmitTaskFunctor( task& t ) : my_task( t ) {} + void operator()() const { + submit_task(my_task); + } +private: + task& my_task; +}; + +void TestCancellation(bool cancel_by_exception) { + g_is_critical_task_submitted = false; + g_bypassed_critical_task_stage = not_bypassed; + tbb::task_group_context context_to_leave_working; + tbb::task_group_context context_to_cancel; + task* root_task_of_to_be_cancelled_context = NULL; + task* root_task_of_working_to_completion_context = NULL; + size_t task_num = 64; + size_t task_num_for_cancelled_context = 2 * MaxThread; + g_num_executed_from_cancelled_context = g_num_executed_from_working_context = 0; + g_cancelling_task_id = -1; + g_arena.initialize( MaxThread ); // leaving one slot to be occupied by master to submit the work + g_arena.execute( + WorkCreator<ATask</*cancelled_group=*/true>, task::spawn> + (root_task_of_to_be_cancelled_context, task_num_for_cancelled_context, + /*num_critical_tasks=*/0, &context_to_cancel) + ); + g_arena.execute( + WorkCreator<ATask</*cancelled_group=*/false>, task::spawn> + (root_task_of_working_to_completion_context, task_num, /*num_critical_tasks=*/1, + &context_to_leave_working) + ); + ways_to_cancel_t cancellation_method = ways_to_cancel_t( cancel_by_exception ); + task& terminating_task = *new( task::allocate_additional_child_of(*root_task_of_to_be_cancelled_context) ) + ATask</*cancelled_group=*/true>( cancellation_method ); + tbb::internal::make_critical( terminating_task ); // stop the work as soon as possible! + g_arena.enqueue( SubmitTaskFunctor<task::enqueue>(terminating_task), + tbb::priority_t(tbb::internal::priority_critical) ); + g_is_critical_task_submitted = true; + try { + g_arena.execute( WorkAwaiter(root_task_of_to_be_cancelled_context) ); + } catch( const std::runtime_error& e ) { + ASSERT( cancel_by_exception, "Exception was not expected!" ); + ASSERT( std::string(e.what()) == "Exception data", "Unexpected exception data!" ); + } catch( const tbb::captured_exception& e ) { + ASSERT( cancel_by_exception, "Exception was not expected!" ); + ASSERT( std::string(e.what()) == "Exception data", "Unexpected exception data!" ); + } catch( ... ) { + ASSERT( false, "Failed to catch specific exception" ); + } + g_arena.execute( WorkAwaiter(root_task_of_working_to_completion_context) ); + g_arena.terminate(); + + if( !cancel_by_exception ) { + ASSERT( context_to_cancel.is_group_execution_cancelled(), "Execution must be cancelled" ); + } + ASSERT( !context_to_leave_working.is_group_execution_cancelled(), + "Execution must NOT be cancelled" ); + + ASSERT( g_num_executed_from_working_context == task_num + /*one critical*/1, + "Incorrect number of tasks executed!" ); + ASSERT( g_num_executed_from_cancelled_context < task_num_for_cancelled_context, + "Number of executed tasks from the cancelled context should be less than submitted!" ); + ASSERT( 0 < g_cancelling_task_id && g_cancelling_task_id < MaxThread + 1, + "Critical task was executed in wrong order." ); +} + +void TestCancellationSupport(bool cancel_by_exception) { + const char* test_type[] = { "by explicit call to cancel", "by throwing an exception" }; + REMARK( "\tCancellation support %s\n", test_type[!!cancel_by_exception] ); + TestCancellation( cancel_by_exception ); +} + +namespace NestedArenaCase { + +static const size_t g_num_critical_tasks = 10; +static const size_t g_num_critical_nested = 5; + +struct CriticalTask : public task { + CriticalTask(task_marker_t /*mark*/) {} + task* execute() __TBB_override { + ++g_num_executed_from_working_context; + task* nested_root = NULL; + if( !g_is_critical_task_submitted ) { + g_is_critical_task_submitted = true; + g_arena.execute( + WorkCreator<CriticalTask, task::spawn>(nested_root, /*num_tasks=*/size_t(0), + g_num_critical_nested) ); + g_arena.execute( WorkAwaiter(nested_root) ); + } + return NULL; + } +}; + +void TestInNestedArena(tbb::task_arena& outer_arena) { + g_root_task = NULL; + g_is_critical_task_submitted = false; + g_num_executed_from_working_context = 0; + g_arena.initialize( 1 ); + outer_arena.execute( + WorkCreator<CriticalTask, task::spawn>( + g_root_task, /*num_tasks=*/size_t(0), g_num_critical_tasks) ); + outer_arena.execute( WorkAwaiter(g_root_task) ); + ASSERT( g_num_executed_from_working_context == g_num_critical_tasks + g_num_critical_nested, + "Mismatch in number of critical tasks executed in nested and outer arenas." ); + g_arena.terminate(); +} + +void test() { + REMARK( "\tWork in nested arenas\n" ); + TestInNestedArena( g_arena ); + + tbb::task_arena a( 1 ); + TestInNestedArena( a ); +} +} // namespace NestedArenaCase + +void test() { + REMARK("Testing support for critical tasks\n"); + TestSchedulerTaskSelectionWhenSpawn(); + TestSchedulerTaskSelectionWhenEnqueue(); + TestCancellationSupport(/*cancel_by_exception=*/false); + TestCancellationSupport(/*cancel_by_exception=*/true); + NestedArenaCase::test(); +} +} // namespace CriticalTaskSupport +#endif /* __TBB_PREVIEW_CRITICAL_TASKS && __TBB_TASK_PRIORITY */ + +int TestMain () { +#if TBB_USE_EXCEPTIONS + TestUnconstructibleTask<1>(); + TestUnconstructibleTask<10000>(); +#endif + TestAlignment(); + TestNoteAffinityContext(); + TestDispatchLoopResponsiveness(); + TestWaitDiscriminativenessWithoutStealing(); + TestWaitDiscriminativenessWithStealing(); + for( int p=MinThread; p<=MaxThread; ++p ) { + TestSpawnChildren( p ); + TestSpawnRootList( p ); + TestSafeContinuation( p ); + TestLeftRecursion( p ); + TestDag( p ); + TestAffinity( p ); + TestUserThread( p ); + TestStealLimit( p ); + TestRelaxedOwnership( p ); + TestMastersIsolation( p ); + } + TestWaitableTask(); +#if __TBB_PREVIEW_CRITICAL_TASKS && __TBB_TASK_PRIORITY + CriticalTaskSupport::test(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_arena.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_arena.cpp new file mode 100644 index 00000000..32cf5769 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_arena.cpp @@ -0,0 +1,1674 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define __TBB_EXTRA_DEBUG 1 + +#include <stdexcept> +#include <cstdlib> +#include <cstdio> +#include <vector> +#include <set> + +#include "harness_fp.h" + +#if __TBB_TASK_ISOLATION +// Whitebox stuff for TestIsolatedExecuteNS::ContinuationTest(). +// TODO: Consider better approach instead of the whitebox approach. +#define private public +#include "tbb/task.h" +#undef private +#endif /* __TBB_TASK_ISOLATION */ + +#include "tbb/task_arena.h" +#include "tbb/atomic.h" +#include "tbb/task_scheduler_observer.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" +#include "tbb/enumerable_thread_specific.h" + +#include "harness_assert.h" +#include "harness.h" +#include "harness_barrier.h" + +#include "tbb/tbb_thread.h" + +#if _MSC_VER +// plays around __TBB_NO_IMPLICIT_LINKAGE. __TBB_LIB_NAME should be defined (in makefiles) +#pragma comment(lib, __TBB_STRING(__TBB_LIB_NAME)) +#endif + +#include "tbb/global_control.h" +//--------------------------------------------------// +// Test that task_arena::initialize and task_arena::terminate work when doing nothing else. +/* maxthread is treated as the biggest possible concurrency level. */ +void InitializeAndTerminate( int maxthread ) { + __TBB_TRY { + for( int i=0; i<200; ++i ) { + switch( i&3 ) { + // Arena is created inactive, initialization is always explicit. Lazy initialization is covered by other test functions. + // Explicit initialization can either keep the original values or change those. + // Arena termination can be explicit or implicit (in the destructor). + // TODO: extend with concurrency level checks if such a method is added. + default: { + tbb::task_arena arena( std::rand() % maxthread + 1 ); + ASSERT(!arena.is_active(), "arena should not be active until initialized"); + arena.initialize(); + ASSERT(arena.is_active(), NULL); + arena.terminate(); + ASSERT(!arena.is_active(), "arena should not be active; it was terminated"); + break; + } + case 0: { + tbb::task_arena arena( 1 ); + ASSERT(!arena.is_active(), "arena should not be active until initialized"); + arena.initialize( std::rand() % maxthread + 1 ); // change the parameters + ASSERT(arena.is_active(), NULL); + break; + } + case 1: { + tbb::task_arena arena( tbb::task_arena::automatic ); + ASSERT(!arena.is_active(), NULL); + arena.initialize(); + ASSERT(arena.is_active(), NULL); + break; + } + case 2: { + tbb::task_arena arena; + ASSERT(!arena.is_active(), "arena should not be active until initialized"); + arena.initialize( std::rand() % maxthread + 1 ); + ASSERT(arena.is_active(), NULL); + arena.terminate(); + ASSERT(!arena.is_active(), "arena should not be active; it was terminated"); + break; + } + } + } + } __TBB_CATCH( std::runtime_error& error ) { +#if TBB_USE_EXCEPTIONS + REPORT("ERROR: %s\n", error.what() ); +#endif /* TBB_USE_EXCEPTIONS */ + } +} + +//--------------------------------------------------// +// Definitions used in more than one test +typedef tbb::blocked_range<int> Range; + +// slot_id value: -1 is reserved by current_slot(), -2 is set in on_scheduler_exit() below +static tbb::enumerable_thread_specific<int> local_id, old_id, slot_id(-3); + +void ResetTLS() { + local_id.clear(); + old_id.clear(); + slot_id.clear(); +} + +class ArenaObserver : public tbb::task_scheduler_observer { + int myId; // unique observer/arena id within a test + int myMaxConcurrency; // concurrency of the associated arena + int myNumReservedSlots; // reserved slots in the associated arena + void on_scheduler_entry( bool is_worker ) __TBB_override { + int current_index = tbb::this_task_arena::current_thread_index(); + REMARK("a %s #%p is entering arena %d from %d on slot %d\n", is_worker?"worker":"master", + &local_id.local(), myId, local_id.local(), current_index ); + ASSERT(current_index<(myMaxConcurrency>1?myMaxConcurrency:2), NULL); + if(is_worker) ASSERT(current_index>=myNumReservedSlots, NULL); + + ASSERT(!old_id.local(), "double call to on_scheduler_entry"); + old_id.local() = local_id.local(); + ASSERT(old_id.local() != myId, "double entry to the same arena"); + local_id.local() = myId; + slot_id.local() = current_index; + } + void on_scheduler_exit( bool is_worker ) __TBB_override { + REMARK("a %s #%p is leaving arena %d to %d\n", is_worker?"worker":"master", + &local_id.local(), myId, old_id.local()); + ASSERT(local_id.local() == myId, "nesting of arenas is broken"); + ASSERT(slot_id.local() == tbb::this_task_arena::current_thread_index(), NULL); + //!deprecated, remove when tbb::task_arena::current_thread_index is removed. + ASSERT(slot_id.local() == tbb::task_arena::current_thread_index(), NULL); + slot_id.local() = -2; + local_id.local() = old_id.local(); + old_id.local() = 0; + } +public: + ArenaObserver(tbb::task_arena &a, int maxConcurrency, int numReservedSlots, int id) + : tbb::task_scheduler_observer(a) + , myId(id) + , myMaxConcurrency(maxConcurrency) + , myNumReservedSlots(numReservedSlots) { + ASSERT(myId, NULL); + observe(true); + } + ~ArenaObserver () { + ASSERT(!old_id.local(), "inconsistent observer state"); + } +}; + +struct IndexTrackingBody { // Must be used together with ArenaObserver + void operator() ( const Range& ) const { + ASSERT(slot_id.local() == tbb::this_task_arena::current_thread_index(), NULL); + //!deprecated, remove when tbb::task_arena::current_thread_index is removed. + ASSERT(slot_id.local() == tbb::task_arena::current_thread_index(), NULL); + for ( volatile int i = 0; i < 50000; ++i ) + ; + } +}; + +struct AsynchronousWork : NoAssign { + Harness::SpinBarrier &my_barrier; + bool my_is_blocking; + AsynchronousWork(Harness::SpinBarrier &a_barrier, bool blocking = true) + : my_barrier(a_barrier), my_is_blocking(blocking) {} + void operator()() const { + ASSERT(local_id.local() != 0, "not in explicit arena"); + tbb::parallel_for(Range(0,500), IndexTrackingBody(), tbb::simple_partitioner(), *tbb::task::self().group()); + if(my_is_blocking) my_barrier.timed_wait(10); // must be asynchronous to master thread + else my_barrier.signal_nowait(); + } +}; + +//--------------------------------------------------// +// Test that task_arenas might be created and used from multiple application threads. +// Also tests arena observers. The parameter p is the index of an app thread running this test. +void TestConcurrentArenasFunc(int idx) { + // A regression test for observer activation order: + // check that arena observer can be activated before local observer + struct LocalObserver : public tbb::task_scheduler_observer { + LocalObserver() : tbb::task_scheduler_observer(/*local=*/true) { observe(true); } + }; + tbb::task_arena a1; + a1.initialize(1,0); + ArenaObserver o1(a1, 1, 0, idx*2+1); // the last argument is a "unique" observer/arena id for the test + ASSERT(o1.is_observing(), "Arena observer has not been activated"); + LocalObserver lo; + ASSERT(lo.is_observing(), "Local observer has not been activated"); + tbb::task_arena a2(2,1); + ArenaObserver o2(a2, 2, 1, idx*2+2); + ASSERT(o2.is_observing(), "Arena observer has not been activated"); + Harness::SpinBarrier barrier(2); + AsynchronousWork work(barrier); + a1.enqueue(work); // put async work + barrier.timed_wait(10); + a2.enqueue(work); // another work + a2.execute(work); // my_barrier.timed_wait(10) inside + a1.debug_wait_until_empty(); + a2.debug_wait_until_empty(); +} + +void TestConcurrentArenas(int p) { + ResetTLS(); + NativeParallelFor( p, &TestConcurrentArenasFunc ); +} + +//--------------------------------------------------// +// Test multiple application threads working with a single arena at the same time. +class MultipleMastersPart1 : NoAssign { + tbb::task_arena &my_a; + Harness::SpinBarrier &my_b1, &my_b2; +public: + MultipleMastersPart1( tbb::task_arena &a, Harness::SpinBarrier &b1, Harness::SpinBarrier &b2) + : my_a(a), my_b1(b1), my_b2(b2) {} + void operator()(int) const { + my_a.execute(AsynchronousWork(my_b2, /*blocking=*/false)); + my_b1.timed_wait(10); + // A regression test for bugs 1954 & 1971 + my_a.enqueue(AsynchronousWork(my_b2, /*blocking=*/false)); + } +}; + +class MultipleMastersPart2 : NoAssign { + tbb::task_arena &my_a; + Harness::SpinBarrier &my_b; +public: + MultipleMastersPart2( tbb::task_arena &a, Harness::SpinBarrier &b) : my_a(a), my_b(b) {} + void operator()(int) const { + my_a.execute(AsynchronousWork(my_b, /*blocking=*/false)); + } +}; + +class MultipleMastersPart3 : NoAssign { + tbb::task_arena &my_a; + Harness::SpinBarrier &my_b; + + struct Runner : NoAssign { + tbb::task* const a_task; + Runner(tbb::task* const t) : a_task(t) {} + void operator()() const { + for ( volatile int i = 0; i < 10000; ++i ) + ; + a_task->decrement_ref_count(); + } + }; + + struct Waiter : NoAssign { + tbb::task* const a_task; + Waiter(tbb::task* const t) : a_task(t) {} + void operator()() const { + a_task->wait_for_all(); + } + }; + +public: + MultipleMastersPart3(tbb::task_arena &a, Harness::SpinBarrier &b) + : my_a(a), my_b(b) {} + void operator()(int idx) const { + tbb::empty_task* root_task = new(tbb::task::allocate_root()) tbb::empty_task; + my_b.timed_wait(10); // increases chances for task_arena initialization contention + for( int i=0; i<100; ++i) { + root_task->set_ref_count(2); + my_a.enqueue(Runner(root_task)); + my_a.execute(Waiter(root_task)); + } + tbb::task::destroy(*root_task); + REMARK("Master #%d: job completed, wait for others\n", idx); + my_b.timed_wait(10); + } +}; + +class MultipleMastersPart4 : NoAssign { + tbb::task_arena &my_a; + Harness::SpinBarrier &my_b; + tbb::task_group_context *my_ag; + + struct Getter : NoAssign { + tbb::task_group_context *& my_g; + Getter(tbb::task_group_context *&a_g) : my_g(a_g) {} + void operator()() const { + my_g = tbb::task::self().group(); + } + }; + struct Checker : NoAssign { + tbb::task_group_context *my_g; + Checker(tbb::task_group_context *a_g) : my_g(a_g) {} + void operator()() const { + ASSERT(my_g == tbb::task::self().group(), NULL); + tbb::task *t = new( tbb::task::allocate_root() ) tbb::empty_task; + ASSERT(my_g == t->group(), NULL); + tbb::task::destroy(*t); + } + }; + struct NestedChecker : NoAssign { + const MultipleMastersPart4 &my_body; + NestedChecker(const MultipleMastersPart4 &b) : my_body(b) {} + void operator()() const { + tbb::task_group_context *nested_g = tbb::task::self().group(); + ASSERT(my_body.my_ag != nested_g, NULL); + tbb::task *t = new( tbb::task::allocate_root() ) tbb::empty_task; + ASSERT(nested_g == t->group(), NULL); + tbb::task::destroy(*t); + my_body.my_a.enqueue(Checker(my_body.my_ag)); + } + }; +public: + MultipleMastersPart4( tbb::task_arena &a, Harness::SpinBarrier &b) : my_a(a), my_b(b) { + my_a.execute(Getter(my_ag)); + } + // NativeParallelFor's functor + void operator()(int) const { + my_a.execute(*this); + } + // Arena's functor + void operator()() const { + Checker check(my_ag); + check(); + tbb::task_arena nested(1,1); + nested.execute(NestedChecker(*this)); // change arena + tbb::parallel_for(Range(0,1),*this); // change group context only + my_b.timed_wait(10); + my_a.execute(check); + check(); + } + // parallel_for's functor + void operator()(const Range &) const { + NestedChecker(*this)(); + my_a.execute(Checker(my_ag)); // restore arena context + } +}; + +void TestMultipleMasters(int p) { + { + REMARK("multiple masters, part 1\n"); + ResetTLS(); + tbb::task_arena a(1,0); + a.initialize(); + ArenaObserver o(a, 1, 0, 1); + Harness::SpinBarrier barrier1(p), barrier2(2*p+1); // each of p threads will submit two tasks signaling the barrier + NativeParallelFor( p, MultipleMastersPart1(a, barrier1, barrier2) ); + barrier2.timed_wait(10); + a.debug_wait_until_empty(); + } { + REMARK("multiple masters, part 2\n"); + ResetTLS(); + tbb::task_arena a(2,1); + ArenaObserver o(a, 2, 1, 2); + Harness::SpinBarrier barrier(p+2); + a.enqueue(AsynchronousWork(barrier, /*blocking=*/true)); // occupy the worker, a regression test for bug 1981 + NativeParallelFor( p, MultipleMastersPart2(a, barrier) ); + barrier.timed_wait(10); + a.debug_wait_until_empty(); + } { + // Regression test for the bug 1981 part 2 (task_arena::execute() with wait_for_all for an enqueued task) + REMARK("multiple masters, part 3: wait_for_all() in execute()\n"); + tbb::task_arena a(p,1); + Harness::SpinBarrier barrier(p+1); // for masters to avoid endless waiting at least in some runs + // "Oversubscribe" the arena by 1 master thread + NativeParallelFor( p+1, MultipleMastersPart3(a, barrier) ); + a.debug_wait_until_empty(); + } { + int c = p%3? (p%2? p : 2) : 3; + REMARK("multiple masters, part 4: contexts, arena(%d)\n", c); + ResetTLS(); + tbb::task_arena a(c, 1); + ArenaObserver o(a, c, 1, c); + Harness::SpinBarrier barrier(c); + MultipleMastersPart4 test(a, barrier); + NativeParallelFor(p, test); + a.debug_wait_until_empty(); + } +} + +//--------------------------------------------------// +// TODO: explain what TestArenaEntryConsistency does +#include <sstream> +#if TBB_USE_EXCEPTIONS +#include <stdexcept> +#include "tbb/tbb_exception.h" +#endif + +struct TestArenaEntryBody : FPModeContext { + tbb::atomic<int> &my_stage; // each execute increases it + std::stringstream my_id; + bool is_caught, is_expected; + enum { arenaFPMode = 1 }; + + TestArenaEntryBody(tbb::atomic<int> &s, int idx, int i) // init thread-specific instance + : FPModeContext(idx+i) + , my_stage(s) + , is_caught(false) + , is_expected( (idx&(1<<i)) != 0 && (TBB_USE_EXCEPTIONS) != 0 ) + { + my_id << idx << ':' << i << '@'; + } + void operator()() { // inside task_arena::execute() + // synchronize with other stages + int stage = my_stage++; + int slot = tbb::this_task_arena::current_thread_index(); + ASSERT(slot >= 0 && slot <= 1, "master or the only worker"); + // wait until the third stage is delegated and then starts on slot 0 + while(my_stage < 2+slot) __TBB_Yield(); + // deduct its entry type and put it into id, it helps to find source of a problem + my_id << (stage < 3 ? (tbb::this_task_arena::current_thread_index()? + "delegated_to_worker" : stage < 2? "direct" : "delegated_to_master") + : stage == 3? "nested_same_ctx" : "nested_alien_ctx"); + REMARK("running %s\n", my_id.str().c_str()); + AssertFPMode(arenaFPMode); + if(is_expected) + __TBB_THROW(std::logic_error(my_id.str())); + // no code can be put here since exceptions can be thrown + } + void on_exception(const char *e) { // outside arena, in catch block + is_caught = true; + REMARK("caught %s\n", e); + ASSERT(my_id.str() == e, NULL); + assertFPMode(); + } + void after_execute() { // outside arena and catch block + REMARK("completing %s\n", my_id.str().c_str() ); + ASSERT(is_caught == is_expected, NULL); + assertFPMode(); + } +}; + +class ForEachArenaEntryBody : NoAssign { + tbb::task_arena &my_a; // expected task_arena(2,1) + tbb::atomic<int> &my_stage; // each execute increases it + int my_idx; + +public: + ForEachArenaEntryBody(tbb::task_arena &a, tbb::atomic<int> &c) + : my_a(a), my_stage(c), my_idx(0) {} + + void test(int idx) { + my_idx = idx; + my_stage = 0; + NativeParallelFor(3, *this); // test cross-arena calls + ASSERT(my_stage == 3, NULL); + my_a.execute(*this); // test nested calls + ASSERT(my_stage == 5, NULL); + } + + // task_arena functor for nested tests + void operator()() const { + test_arena_entry(3); // in current task group context + tbb::parallel_for(4, 5, *this); // in different context + } + + // NativeParallelFor & parallel_for functor + void operator()(int i) const { + test_arena_entry(i); + } + +private: + void test_arena_entry(int i) const { + TestArenaEntryBody scoped_functor(my_stage, my_idx, i); + __TBB_TRY { + my_a.execute(scoped_functor); + } +#if TBB_USE_EXCEPTIONS + catch(tbb::captured_exception &e) { + scoped_functor.on_exception(e.what()); + ASSERT_WARNING(TBB_USE_CAPTURED_EXCEPTION, "Caught captured_exception while expecting exact one"); + } catch(std::logic_error &e) { + scoped_functor.on_exception(e.what()); + ASSERT(!TBB_USE_CAPTURED_EXCEPTION, "Caught exception of wrong type"); + } catch(...) { ASSERT(false, "Unexpected exception type"); } +#endif //TBB_USE_EXCEPTIONS + scoped_functor.after_execute(); + } +}; + +void TestArenaEntryConsistency() { + REMARK("test arena entry consistency\n"); + + tbb::task_arena a(2, 1); + tbb::atomic<int> c; + ForEachArenaEntryBody body(a, c); + + FPModeContext fp_scope(TestArenaEntryBody::arenaFPMode); + a.initialize(); // capture FP settings to arena + fp_scope.setNextFPMode(); + + for (int i = 0; i < 100; i++) // not less than 32 = 2^5 of entry types + body.test(i); +} + +//-------------------------------------------------- +// Test that the requested degree of concurrency for task_arena is achieved in various conditions +class TestArenaConcurrencyBody : NoAssign { + tbb::task_arena &my_a; + int my_max_concurrency; + int my_reserved_slots; + Harness::SpinBarrier *my_barrier; + Harness::SpinBarrier *my_worker_barrier; +public: + TestArenaConcurrencyBody( tbb::task_arena &a, int max_concurrency, int reserved_slots, Harness::SpinBarrier *b = NULL, Harness::SpinBarrier *wb = NULL ) + : my_a(a), my_max_concurrency(max_concurrency), my_reserved_slots(reserved_slots), my_barrier(b), my_worker_barrier(wb) {} + // NativeParallelFor's functor + void operator()( int ) const { + ASSERT( local_id.local() == 0, "TLS was not cleaned?" ); + local_id.local() = 1; + my_a.execute( *this ); + } + // Arena's functor + void operator()() const { + ASSERT( tbb::task_arena::current_thread_index() == tbb::this_task_arena::current_thread_index(), NULL ); + int idx = tbb::this_task_arena::current_thread_index(); + ASSERT( idx < (my_max_concurrency > 1 ? my_max_concurrency : 2), NULL ); + ASSERT( my_a.max_concurrency() == tbb::this_task_arena::max_concurrency(), NULL ); + int max_arena_concurrency = tbb::this_task_arena::max_concurrency(); + ASSERT( max_arena_concurrency == my_max_concurrency, NULL ); + if ( my_worker_barrier ) { + if ( local_id.local() == 1 ) { + // Master thread in a reserved slot + ASSERT( idx < my_reserved_slots, "Masters are supposed to use only reserved slots in this test" ); + } else { + // Worker thread + ASSERT( idx >= my_reserved_slots, NULL ); + my_worker_barrier->timed_wait( 10 ); + } + } else if ( my_barrier ) + ASSERT( local_id.local() == 1, "Workers are not supposed to enter the arena in this test" ); + if ( my_barrier ) my_barrier->timed_wait( 10 ); + else Harness::Sleep( 10 ); + } +}; + +void TestArenaConcurrency( int p, int reserved = 0, int step = 1) { + for (; reserved <= p; reserved += step) { + REMARK("TestArenaConcurrency: %d slots, %d reserved\n", p, reserved); + tbb::task_arena a( p, reserved ); + { // Check concurrency with worker & reserved master threads. + ResetTLS(); + Harness::SpinBarrier b( p ); + Harness::SpinBarrier wb( p-reserved ); + TestArenaConcurrencyBody test( a, p, reserved, &b, &wb ); + for ( int i = reserved; i < p; ++i ) + a.enqueue( test ); + if ( reserved==1 ) + test( 0 ); // calls execute() + else + NativeParallelFor( reserved, test ); + a.debug_wait_until_empty(); + } { // Check if multiple masters alone can achieve maximum concurrency. + ResetTLS(); + Harness::SpinBarrier b( p ); + NativeParallelFor( p, TestArenaConcurrencyBody( a, p, reserved, &b ) ); + a.debug_wait_until_empty(); + } { // Check oversubscription by masters. + ResetTLS(); + NativeParallelFor( 2*p, TestArenaConcurrencyBody( a, p, reserved ) ); + a.debug_wait_until_empty(); + } + } +} + +//--------------------------------------------------// +// Test creation/initialization of a task_arena that references an existing arena (aka attach). +// This part of the test uses the knowledge of task_arena internals + +typedef tbb::interface7::internal::task_arena_base task_arena_internals; + +struct TaskArenaValidator : public task_arena_internals { + int my_slot_at_construction; + TaskArenaValidator( const task_arena_internals& other ) + : task_arena_internals(other) /*copies the internal state of other*/ { + my_slot_at_construction = tbb::this_task_arena::current_thread_index(); + } + // Inspect the internal state + int concurrency() { return my_max_concurrency; } + int reserved_for_masters() { return (int)my_master_slots; } + + // This method should be called in task_arena::execute() for a captured arena + // by the same thread that created the validator. + void operator()() { + ASSERT( tbb::this_task_arena::current_thread_index()==my_slot_at_construction, + "Current thread index has changed since the validator construction" ); + //!deprecated + ASSERT( tbb::task_arena::current_thread_index()==my_slot_at_construction, + "Current thread index has changed since the validator construction" ); + } +}; + +void ValidateAttachedArena( tbb::task_arena& arena, bool expect_activated, + int expect_concurrency, int expect_masters ) { + ASSERT( arena.is_active()==expect_activated, "Unexpected activation state" ); + if( arena.is_active() ) { + TaskArenaValidator validator( arena ); + ASSERT( validator.concurrency()==expect_concurrency, "Unexpected arena size" ); + ASSERT( validator.reserved_for_masters()==expect_masters, "Unexpected # of reserved slots" ); + if ( tbb::this_task_arena::current_thread_index() != tbb::task_arena::not_initialized ) { + ASSERT( tbb::task_arena::current_thread_index() >= 0 && + tbb::this_task_arena::current_thread_index() >= 0, NULL); + // for threads already in arena, check that the thread index remains the same + arena.execute( validator ); + } else { // not_initialized + // Test the deprecated method + ASSERT( tbb::task_arena::current_thread_index()==-1, NULL); + } + + // Ideally, there should be a check for having the same internal arena object, + // but that object is not easily accessible for implicit arenas. + } +} + +struct TestAttachBody : NoAssign { + mutable int my_idx; // safe to modify and use within the NativeParallelFor functor + const int maxthread; + TestAttachBody( int max_thr ) : maxthread(max_thr) {} + + // The functor body for NativeParallelFor + void operator()( int idx ) const { + my_idx = idx; + int default_threads = tbb::task_scheduler_init::default_num_threads(); + + tbb::task_arena arena = tbb::task_arena( tbb::task_arena::attach() ); + ValidateAttachedArena( arena, false, -1, -1 ); // Nothing yet to attach to + + { // attach to an arena created via task_scheduler_init + tbb::task_scheduler_init init( idx+1 ); + + tbb::task_arena arena2 = tbb::task_arena( tbb::task_arena::attach() ); + ValidateAttachedArena( arena2, true, idx+1, 1 ); + + arena.initialize( tbb::task_arena::attach() ); + } + ValidateAttachedArena( arena, true, idx+1, 1 ); + + arena.terminate(); + ValidateAttachedArena( arena, false, -1, -1 ); + + // Check default behavior when attach cannot succeed + switch (idx%2) { + case 0: + { // construct as attached, then initialize + tbb::task_arena arena2 = tbb::task_arena( tbb::task_arena::attach() ); + ValidateAttachedArena( arena2, false, -1, -1 ); + arena2.initialize(); // must be initialized with default parameters + ValidateAttachedArena( arena2, true, default_threads, 1 ); + } + break; + case 1: + { // default-construct, then initialize as attached + tbb::task_arena arena2; + ValidateAttachedArena( arena2, false, -1, -1 ); + arena2.initialize( tbb::task_arena::attach() ); // must use default parameters + ValidateAttachedArena( arena2, true, default_threads, 1 ); + } + break; + } // switch + + // attach to an auto-initialized arena + tbb::empty_task& tsk = *new (tbb::task::allocate_root()) tbb::empty_task; + tbb::task::spawn_root_and_wait(tsk); + tbb::task_arena arena2 = tbb::task_arena( tbb::task_arena::attach() ); + ValidateAttachedArena( arena2, true, default_threads, 1 ); + + // attach to another task_arena + arena.initialize( maxthread, min(maxthread,idx) ); + arena.execute( *this ); + } + + // The functor body for task_arena::execute above + void operator()() const { + tbb::task_arena arena2 = tbb::task_arena( tbb::task_arena::attach() ); + ValidateAttachedArena( arena2, true, maxthread, min(maxthread,my_idx) ); + } + + // The functor body for tbb::parallel_for + void operator()( const Range& r ) const { + for( int i = r.begin(); i<r.end(); ++i ) { + tbb::task_arena arena2 = tbb::task_arena( tbb::task_arena::attach() ); + ValidateAttachedArena( arena2, true, maxthread+1, 1 ); // +1 to match initialization in TestMain + } + } +}; + +void TestAttach( int maxthread ) { + REMARK( "Testing attached task_arenas\n" ); + // Externally concurrent, but no concurrency within a thread + NativeParallelFor( max(maxthread,4), TestAttachBody( maxthread ) ); + // Concurrent within the current arena; may also serve as a stress test + tbb::parallel_for( Range(0,10000*maxthread), TestAttachBody( maxthread ) ); +} + +//--------------------------------------------------// +// Test that task_arena::enqueue does not tolerate a non-const functor. +// TODO: can it be reworked as SFINAE-based compile-time check? +struct TestFunctor { + void operator()() { ASSERT( false, "Non-const operator called" ); } + void operator()() const { /* library requires this overload only */ } +}; + +void TestConstantFunctorRequirement() { + tbb::task_arena a; + TestFunctor tf; + a.enqueue( tf ); +#if __TBB_TASK_PRIORITY + a.enqueue( tf, tbb::priority_normal ); +#endif +} +//--------------------------------------------------// +#if __TBB_TASK_ISOLATION +#include "tbb/parallel_reduce.h" +#include "tbb/parallel_invoke.h" +// Test this_task_arena::isolate +namespace TestIsolatedExecuteNS { + //--------------------------------------------------// + template <typename NestedPartitioner> + class NestedParFor : NoAssign { + public: + NestedParFor() {} + void operator()() const { + NestedPartitioner p; + tbb::parallel_for( 0, 10, Harness::DummyBody( 10 ), p ); + } + }; + + template <typename NestedPartitioner> + class ParForBody : NoAssign { + bool myOuterIsolation; + tbb::enumerable_thread_specific<int> &myEts; + tbb::atomic<bool> &myIsStolen; + public: + ParForBody( bool outer_isolation, tbb::enumerable_thread_specific<int> &ets, tbb::atomic<bool> &is_stolen ) + : myOuterIsolation( outer_isolation ), myEts( ets ), myIsStolen( is_stolen ) {} + void operator()( int ) const { + int &e = myEts.local(); + if ( e++ > 0 ) myIsStolen = true; + if ( myOuterIsolation ) + NestedParFor<NestedPartitioner>()(); + else + tbb::this_task_arena::isolate( NestedParFor<NestedPartitioner>() ); + --e; + } + }; + + template <typename OuterPartitioner, typename NestedPartitioner> + class OuterParFor : NoAssign { + bool myOuterIsolation; + tbb::atomic<bool> &myIsStolen; + public: + OuterParFor( bool outer_isolation, tbb::atomic<bool> &is_stolen ) : myOuterIsolation( outer_isolation ), myIsStolen( is_stolen ) {} + void operator()() const { + tbb::enumerable_thread_specific<int> ets( 0 ); + OuterPartitioner p; + tbb::parallel_for( 0, 1000, ParForBody<NestedPartitioner>( myOuterIsolation, ets, myIsStolen ), p ); + } + }; + + template <typename OuterPartitioner, typename NestedPartitioner> + void TwoLoopsTest( bool outer_isolation ) { + tbb::atomic<bool> is_stolen; + is_stolen = false; + const int max_repeats = 100; + if ( outer_isolation ) { + for ( int i = 0; i <= max_repeats; ++i ) { + tbb::this_task_arena::isolate( OuterParFor<OuterPartitioner, NestedPartitioner>( outer_isolation, is_stolen ) ); + if ( is_stolen ) break; + } + ASSERT_WARNING( is_stolen, "isolate() should not block stealing on nested levels without isolation" ); + } else { + for ( int i = 0; i <= max_repeats; ++i ) { + OuterParFor<OuterPartitioner, NestedPartitioner>( outer_isolation, is_stolen )(); + } + ASSERT( !is_stolen, "isolate() on nested levels should prevent stealing from outer leves" ); + } + } + + void TwoLoopsTest( bool outer_isolation ) { + TwoLoopsTest<tbb::simple_partitioner, tbb::simple_partitioner>( outer_isolation ); + TwoLoopsTest<tbb::simple_partitioner, tbb::affinity_partitioner>( outer_isolation ); + TwoLoopsTest<tbb::affinity_partitioner, tbb::simple_partitioner>( outer_isolation ); + TwoLoopsTest<tbb::affinity_partitioner, tbb::affinity_partitioner>( outer_isolation ); + } + + void TwoLoopsTest() { + TwoLoopsTest( true ); + TwoLoopsTest( false ); + } + //--------------------------------------------------// + class HeavyMixTestBody : NoAssign { + tbb::enumerable_thread_specific<Harness::FastRandom>& myRandom; + tbb::enumerable_thread_specific<int>& myIsolatedLevel; + int myNestedLevel; + + template <typename Partitioner, typename Body> + static void RunTwoBodies( Harness::FastRandom& rnd, const Body &body, Partitioner& p, tbb::task_group_context* ctx = NULL ) { + if ( rnd.get() % 2 ) + if (ctx ) + tbb::parallel_for( 0, 2, body, p, *ctx ); + else + tbb::parallel_for( 0, 2, body, p ); + else + tbb::parallel_invoke( body, body ); + } + + template <typename Partitioner> + class IsolatedBody : NoAssign { + const HeavyMixTestBody &myHeavyMixTestBody; + Partitioner &myPartitioner; + public: + IsolatedBody( const HeavyMixTestBody &body, Partitioner &partitioner ) + : myHeavyMixTestBody( body ), myPartitioner( partitioner ) {} + void operator()() const { + RunTwoBodies( myHeavyMixTestBody.myRandom.local(), + HeavyMixTestBody( myHeavyMixTestBody.myRandom, myHeavyMixTestBody.myIsolatedLevel, + myHeavyMixTestBody.myNestedLevel + 1 ), + myPartitioner ); + } + }; + + template <typename Partitioner> + void RunNextLevel( Harness::FastRandom& rnd, int &isolated_level ) const { + Partitioner p; + switch ( rnd.get() % 3 ) { + case 0: { + // No features + tbb::task_group_context ctx; + RunTwoBodies( rnd, HeavyMixTestBody(myRandom, myIsolatedLevel, myNestedLevel + 1), p, &ctx ); + break; + } + case 1: { + // High priority + tbb::task_group_context ctx; +#if __TBB_TASK_PRIORITY + ctx.set_priority( tbb::priority_high ); +#endif + RunTwoBodies( rnd, HeavyMixTestBody(myRandom, myIsolatedLevel, myNestedLevel + 1), p, &ctx ); + break; + } + case 2: { + // Isolation + int previous_isolation = isolated_level; + isolated_level = myNestedLevel; + tbb::this_task_arena::isolate( IsolatedBody<Partitioner>( *this, p ) ); + isolated_level = previous_isolation; + break; + } + } + } + public: + HeavyMixTestBody( tbb::enumerable_thread_specific<Harness::FastRandom>& random, + tbb::enumerable_thread_specific<int>& isolated_level, int nested_level ) + : myRandom( random ), myIsolatedLevel( isolated_level ) + , myNestedLevel( nested_level ) {} + void operator()() const { + int &isolated_level = myIsolatedLevel.local(); + ASSERT( myNestedLevel > isolated_level, "The outer-level task should not be stolen on isolated level" ); + if ( myNestedLevel == 20 ) + return; + Harness::FastRandom &rnd = myRandom.local(); + if ( rnd.get() % 2 == 1 ) { + RunNextLevel<tbb::auto_partitioner>( rnd, isolated_level ); + } else { + RunNextLevel<tbb::affinity_partitioner>( rnd, isolated_level ); + } + } + void operator()(int) const { + this->operator()(); + } + }; + + struct RandomInitializer { + Harness::FastRandom operator()() { + return Harness::FastRandom( tbb::this_task_arena::current_thread_index() ); + } + }; + + void HeavyMixTest() { + tbb::task_scheduler_init init( tbb::task_scheduler_init::default_num_threads() < 3 ? 3 : tbb::task_scheduler_init::automatic ); + RandomInitializer init_random; + tbb::enumerable_thread_specific<Harness::FastRandom> random( init_random ); + tbb::enumerable_thread_specific<int> isolated_level( 0 ); + for ( int i = 0; i < 5; ++i ) { + HeavyMixTestBody b( random, isolated_level, 1 ); + b( 0 ); + REMARK( "." ); + } + } + //--------------------------------------------------// + struct ContinuationTestReduceBody : NoAssign { + tbb::internal::isolation_tag myIsolation; + ContinuationTestReduceBody( tbb::internal::isolation_tag isolation ) : myIsolation( isolation ) {} + ContinuationTestReduceBody( ContinuationTestReduceBody& b, tbb::split ) : myIsolation( b.myIsolation ) {} + void operator()( tbb::blocked_range<int> ) {} + void join( ContinuationTestReduceBody& ) { + tbb::internal::isolation_tag isolation = tbb::task::self().prefix().isolation; + ASSERT( isolation == myIsolation, "The continuations should preserve children's isolation" ); + } + }; + struct ContinuationTestIsolated { + void operator()() const { + ContinuationTestReduceBody b( tbb::task::self().prefix().isolation ); + tbb::parallel_deterministic_reduce( tbb::blocked_range<int>( 0, 100 ), b ); + } + }; + struct ContinuationTestParForBody : NoAssign { + tbb::enumerable_thread_specific<int> &myEts; + public: + ContinuationTestParForBody( tbb::enumerable_thread_specific<int> &ets ) : myEts( ets ){} + void operator()( int ) const { + int &e = myEts.local(); + ++e; + ASSERT( e==1, "The task is stolen on isolated level" ); + tbb::this_task_arena::isolate( ContinuationTestIsolated() ); + --e; + } + }; + void ContinuationTest() { + for ( int i = 0; i < 5; ++i ) { + tbb::enumerable_thread_specific<int> myEts; + tbb::parallel_for( 0, 100, ContinuationTestParForBody( myEts ), tbb::simple_partitioner() ); + } + } + //--------------------------------------------------// +#if TBB_USE_EXCEPTIONS + struct MyException {}; + struct IsolatedBodyThrowsException { + void operator()() const { + __TBB_THROW( MyException() ); + } + }; + struct ExceptionTestBody : NoAssign { + tbb::enumerable_thread_specific<int>& myEts; + tbb::atomic<bool>& myIsStolen; + ExceptionTestBody( tbb::enumerable_thread_specific<int>& ets, tbb::atomic<bool>& is_stolen ) + : myEts( ets ), myIsStolen( is_stolen ) {} + void operator()( int i ) const { + try { + tbb::this_task_arena::isolate( IsolatedBodyThrowsException() ); + ASSERT( false, "The exception has been lost" ); + } + catch ( MyException ) {} + catch ( ... ) { + ASSERT( false, "Unexpected exception" ); + } + // Check that nested algorithms can steal outer-level tasks + int &e = myEts.local(); + if ( e++ > 0 ) myIsStolen = true; + // work imbalance increases chances for stealing + tbb::parallel_for( 0, 10+i, Harness::DummyBody( 100 ) ); + --e; + } + }; + +#endif /* TBB_USE_EXCEPTIONS */ + void ExceptionTest() { +#if TBB_USE_EXCEPTIONS + tbb::enumerable_thread_specific<int> ets; + tbb::atomic<bool> is_stolen; + is_stolen = false; + for ( int i = 0; i<10; ++i ) { + tbb::parallel_for( 0, 1000, ExceptionTestBody( ets, is_stolen ) ); + if ( is_stolen ) break; + } + ASSERT( is_stolen, "isolate should not affect non-isolated work" ); +#endif /* TBB_USE_EXCEPTIONS */ + } + + struct NonConstBody { + unsigned int state; + void operator()() { + state ^= ~0u; + } + }; + + void TestNonConstBody() { + NonConstBody body; + body.state = 0x6c97d5ed; + tbb::this_task_arena::isolate(body); + ASSERT(body.state == 0x93682a12, "The wrong state"); + } + + class TestEnqueueTask : public tbb::task { + bool enqueued; + tbb::enumerable_thread_specific<bool>& executed; + tbb::atomic<int>& completed; + public: + static const int N = 100; + + TestEnqueueTask(bool enq, tbb::enumerable_thread_specific<bool>& exe, tbb::atomic<int>& c) + : enqueued(enq), executed(exe), completed(c) {} + tbb::task* execute() __TBB_override { + if (enqueued) { + executed.local() = true; + ++completed; + __TBB_Yield(); + } else { + parent()->add_ref_count(N); + for (int i = 0; i < N; ++i) + tbb::task::enqueue(*new (parent()->allocate_child()) TestEnqueueTask(true, executed, completed)); + } + return NULL; + } + }; + + class TestEnqueueIsolateBody : NoCopy { + tbb::enumerable_thread_specific<bool>& executed; + tbb::atomic<int>& completed; + public: + TestEnqueueIsolateBody(tbb::enumerable_thread_specific<bool>& exe, tbb::atomic<int>& c) + : executed(exe), completed(c) {} + void operator()() { + tbb::task::spawn_root_and_wait(*new (tbb::task::allocate_root()) TestEnqueueTask(false, executed, completed)); + } + }; + + void TestEnqueue() { + tbb::enumerable_thread_specific<bool> executed(false); + tbb::atomic<int> completed; + + // Check that the main thread can process enqueued tasks. + completed = 0; + TestEnqueueIsolateBody b1(executed, completed); + b1(); + if (!executed.local()) + REPORT("Warning: No one enqueued task has executed by the main thread.\n"); + + executed.local() = false; + completed = 0; + const int N = 100; + // Create enqueued tasks out of isolation. + for (int i = 0; i < N; ++i) + tbb::task::enqueue(*new (tbb::task::allocate_root()) TestEnqueueTask(true, executed, completed)); + TestEnqueueIsolateBody b2(executed, completed); + tbb::this_task_arena::isolate(b2); + ASSERT(executed.local() == false, "An enqueued task was executed within isolate."); + + while (completed < TestEnqueueTask::N + N) __TBB_Yield(); + } +} + +void TestIsolatedExecute() { + REMARK("TestIsolatedExecute"); + // At least 3 threads (owner + 2 thieves) are required to reproduce a situation when the owner steals outer + // level task on a nested level. If we have only one thief then it will execute outer level tasks first and + // the owner will not have a possibility to steal outer level tasks. + int num_threads = min( tbb::task_scheduler_init::default_num_threads(), 3 ); + { + // Too many threads require too many work to reproduce the stealing from outer level. + tbb::task_scheduler_init init( max(num_threads, 7) ); + REMARK("."); TestIsolatedExecuteNS::TwoLoopsTest(); + REMARK("."); TestIsolatedExecuteNS::HeavyMixTest(); + REMARK("."); TestIsolatedExecuteNS::ContinuationTest(); + REMARK("."); TestIsolatedExecuteNS::ExceptionTest(); + } + tbb::task_scheduler_init init(num_threads); + REMARK("."); TestIsolatedExecuteNS::HeavyMixTest(); + REMARK("."); TestIsolatedExecuteNS::ContinuationTest(); + REMARK("."); TestIsolatedExecuteNS::TestNonConstBody(); + REMARK("."); TestIsolatedExecuteNS::TestEnqueue(); + REMARK("\rTestIsolatedExecute: done \n"); +} +#endif /* __TBB_TASK_ISOLATION */ +//--------------------------------------------------// +//--------------------------------------------------// + +class TestDelegatedSpawnWaitBody : NoAssign { + tbb::task_arena &my_a; + Harness::SpinBarrier &my_b1, &my_b2; + + struct Spawner : NoAssign { + tbb::task* const a_task; + Spawner(tbb::task* const t) : a_task(t) {} + void operator()() const { + tbb::task::spawn( *new(a_task->allocate_child()) tbb::empty_task ); + } + }; + + struct Waiter : NoAssign { + tbb::task* const a_task; + Waiter(tbb::task* const t) : a_task(t) {} + void operator()() const { + a_task->wait_for_all(); + } + }; + +public: + TestDelegatedSpawnWaitBody( tbb::task_arena &a, Harness::SpinBarrier &b1, Harness::SpinBarrier &b2) + : my_a(a), my_b1(b1), my_b2(b2) {} + // NativeParallelFor's functor + void operator()(int idx) const { + if ( idx==0 ) { // thread 0 works in the arena, thread 1 waits for it (to prevent test hang) + for( int i=0; i<2; ++i ) my_a.enqueue(*this); // tasks to sync with workers + tbb::empty_task* root_task = new(tbb::task::allocate_root()) tbb::empty_task; + root_task->set_ref_count(100001); + my_b1.timed_wait(10); // sync with the workers + for( int i=0; i<100000; ++i) { + my_a.execute(Spawner(root_task)); + } + my_a.execute(Waiter(root_task)); + tbb::task::destroy(*root_task); + } + my_b2.timed_wait(10); // sync both threads + } + // Arena's functor + void operator()() const { + my_b1.timed_wait(10); // sync with the arena master + } +}; + +void TestDelegatedSpawnWait() { + // Regression test for a bug with missed wakeup notification from a delegated task + REMARK( "Testing delegated spawn & wait\n" ); + tbb::task_arena a(2,0); + a.initialize(); + Harness::SpinBarrier barrier1(3), barrier2(2); + NativeParallelFor( 2, TestDelegatedSpawnWaitBody(a, barrier1, barrier2) ); + a.debug_wait_until_empty(); +} + +class TestMultipleWaitsArenaWait : NoAssign { +public: + TestMultipleWaitsArenaWait( int idx, int bunch_size, int num_tasks, tbb::task** waiters, tbb::atomic<int>& processed ) + : my_idx( idx ), my_bunch_size( bunch_size ), my_num_tasks(num_tasks), my_waiters( waiters ), my_processed( processed ) {} + void operator()() const { + ++my_processed; + // Wait for all tasks + if ( my_idx < my_num_tasks ) + my_waiters[my_idx]->wait_for_all(); + // Signal waiting tasks + if ( my_idx >= my_bunch_size ) + my_waiters[my_idx-my_bunch_size]->decrement_ref_count(); + } +private: + int my_idx; + int my_bunch_size; + int my_num_tasks; + tbb::task** my_waiters; + tbb::atomic<int>& my_processed; +}; + +class TestMultipleWaitsThreadBody : NoAssign { +public: + TestMultipleWaitsThreadBody( int bunch_size, int num_tasks, tbb::task_arena& a, tbb::task** waiters, tbb::atomic<int>& processed ) + : my_bunch_size( bunch_size ), my_num_tasks( num_tasks ), my_arena( a ), my_waiters( waiters ), my_processed( processed ) {} + void operator()( int idx ) const { + my_arena.execute( TestMultipleWaitsArenaWait( idx, my_bunch_size, my_num_tasks, my_waiters, my_processed ) ); + --my_processed; + } +private: + int my_bunch_size; + int my_num_tasks; + tbb::task_arena& my_arena; + tbb::task** my_waiters; + tbb::atomic<int>& my_processed; +}; + +#include "tbb/tbb_thread.h" + +void TestMultipleWaits( int num_threads, int num_bunches, int bunch_size ) { + tbb::task_arena a( num_threads ); + const int num_tasks = (num_bunches-1)*bunch_size; + tbb::task** tasks = new tbb::task*[num_tasks]; + for ( int i = 0; i<num_tasks; ++i ) + tasks[i] = new (tbb::task::allocate_root()) tbb::empty_task(); + tbb::atomic<int> processed; + processed = 0; + for ( int repeats = 0; repeats<10; ++repeats ) { + int idx = 0; + for ( int bunch = 0; bunch < num_bunches-1; ++bunch ) { + // Sync with the previous bunch of tasks to prevent "false" nested dependicies (when a nested task waits for an outer task). + while ( processed < bunch*bunch_size ) __TBB_Yield(); + // Run the bunch of threads/tasks that depend on the next bunch of threads/tasks. + for ( int i = 0; i<bunch_size; ++i ) { + tasks[idx]->set_ref_count( 2 ); + tbb::tbb_thread( TestMultipleWaitsThreadBody( bunch_size, num_tasks, a, tasks, processed ), idx++ ).detach(); + } + } + // No sync because the threads of the last bunch do not call wait_for_all. + // Run the last bunch of threads. + for ( int i = 0; i<bunch_size; ++i ) + tbb::tbb_thread( TestMultipleWaitsThreadBody( bunch_size, num_tasks, a, tasks, processed ), idx++ ).detach(); + while ( processed ) __TBB_Yield(); + } + for ( int i = 0; i<num_tasks; ++i ) + tbb::task::destroy( *tasks[i] ); + delete[] tasks; +} + +void TestMultipleWaits() { + REMARK( "Testing multiple waits\n" ); + // Limit the number of threads to prevent heavy oversubscription. + const int max_threads = min( 16, tbb::task_scheduler_init::default_num_threads() ); + + Harness::FastRandom rnd(1234); + for ( int threads = 1; threads <= max_threads; threads += max( threads/2, 1 ) ) { + for ( int i = 0; i<3; ++i ) { + const int num_bunches = 3 + rnd.get()%3; + const int bunch_size = max_threads + rnd.get()%max_threads; + TestMultipleWaits( threads, num_bunches, bunch_size ); + } + } +} +//--------------------------------------------------// +#include "tbb/global_control.h" + +void TestSmallStackSize() { + tbb::task_scheduler_init init(tbb::task_scheduler_init::automatic, + tbb::global_control::active_value(tbb::global_control::thread_stack_size) / 2 ); + // The test produces the warning (not a error) if fails. So the test is run many times + // to make the log annoying (to force to consider it as an error). + for (int i = 0; i < 100; ++i) { + tbb::task_arena a; + a.initialize(); + } +} +//--------------------------------------------------// +#if __TBB_CPP11_RVALUE_REF_PRESENT +namespace TestMoveSemanticsNS { + struct TestFunctor { + void operator()() const {}; + }; + + struct MoveOnlyFunctor : MoveOnly, TestFunctor { + MoveOnlyFunctor() : MoveOnly() {}; + MoveOnlyFunctor(MoveOnlyFunctor&& other) : MoveOnly(std::move(other)) {}; + }; + + struct MovePreferableFunctor : Movable, TestFunctor { + MovePreferableFunctor() : Movable() {}; + MovePreferableFunctor(MovePreferableFunctor&& other) : Movable( std::move(other) ) {}; + MovePreferableFunctor(const MovePreferableFunctor& other) : Movable(other) {}; + }; + + struct NoMoveNoCopyFunctor : NoCopy, TestFunctor { + NoMoveNoCopyFunctor() : NoCopy() {}; + // mv ctor is not allowed as cp ctor from parent NoCopy + private: + NoMoveNoCopyFunctor(NoMoveNoCopyFunctor&&); + }; + + + void TestFunctors() { + tbb::task_arena ta; + MovePreferableFunctor mpf; + // execute() doesn't have any copies or moves of arguments inside the impl + ta.execute( NoMoveNoCopyFunctor() ); + + ta.enqueue( MoveOnlyFunctor() ); + ta.enqueue( mpf ); + ASSERT(mpf.alive, "object was moved when was passed by lval"); + mpf.Reset(); + ta.enqueue( std::move(mpf) ); + ASSERT(!mpf.alive, "object was copied when was passed by rval"); + mpf.Reset(); +#if __TBB_TASK_PRIORITY + ta.enqueue( MoveOnlyFunctor(), tbb::priority_normal ); + ta.enqueue( mpf, tbb::priority_normal ); + ASSERT(mpf.alive, "object was moved when was passed by lval"); + mpf.Reset(); + ta.enqueue( std::move(mpf), tbb::priority_normal ); + ASSERT(!mpf.alive, "object was copied when was passed by rval"); + mpf.Reset(); +#endif + } +} +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +void TestMoveSemantics() { +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestMoveSemanticsNS::TestFunctors(); +#else + REPORT("Known issue: move support tests are skipped.\n"); +#endif +} +//--------------------------------------------------// +#if __TBB_CPP11_DECLTYPE_PRESENT && !__TBB_CPP11_DECLTYPE_OF_FUNCTION_RETURN_TYPE_BROKEN +#include <vector> +#include "harness_state_trackable.h" + +namespace TestReturnValueNS { + struct noDefaultTag {}; + class ReturnType : public Harness::StateTrackable<> { + static const int SIZE = 42; + std::vector<int> data; + public: + ReturnType(noDefaultTag) : Harness::StateTrackable<>(0) {} +#if !__TBB_IMPLICIT_MOVE_PRESENT + // Define copy constructor to test that it is never called + ReturnType(const ReturnType& r) : Harness::StateTrackable<>(r), data(r.data) {} + ReturnType(ReturnType&& r) : Harness::StateTrackable<>(std::move(r)), data(std::move(r.data)) {} +#endif + void fill() { + for (int i = 0; i < SIZE; ++i) + data.push_back(i); + } + void check() { + ASSERT(data.size() == unsigned(SIZE), NULL); + for (int i = 0; i < SIZE; ++i) + ASSERT(data[i] == i, NULL); + Harness::StateTrackableCounters::counters_t& cnts = Harness::StateTrackableCounters::counters; + ASSERT((cnts[Harness::StateTrackableBase::DefaultInitialized] == 0), NULL); + ASSERT(cnts[Harness::StateTrackableBase::DirectInitialized] == 1, NULL); + std::size_t copied = cnts[Harness::StateTrackableBase::CopyInitialized]; + std::size_t moved = cnts[Harness::StateTrackableBase::MoveInitialized]; + ASSERT(cnts[Harness::StateTrackableBase::Destroyed] == copied + moved, NULL); + // The number of copies/moves should not exceed 3: function return, store to an internal storage, + // acquire internal storage. +#if __TBB_CPP11_RVALUE_REF_PRESENT + ASSERT(copied == 0 && moved <=3, NULL); +#else + ASSERT(copied <= 3 && moved == 0, NULL); +#endif + } + }; + + template <typename R> + R function() { + noDefaultTag tag; + R r(tag); + r.fill(); + return r; + } + + template <> + void function<void>() {} + + template <typename R> + struct Functor { + R operator()() const { + return function<R>(); + } + }; + + tbb::task_arena& arena() { + static tbb::task_arena a; + return a; + } + + template <typename F> + void TestExecute(F &f) { + Harness::StateTrackableCounters::reset(); + ReturnType r = arena().execute(f); + r.check(); + } + + template <typename F> + void TestExecute(const F &f) { + Harness::StateTrackableCounters::reset(); + ReturnType r = arena().execute(f); + r.check(); + } +#if TBB_PREVIEW_TASK_ISOLATION + template <typename F> + void TestIsolate(F &f) { + Harness::StateTrackableCounters::reset(); + ReturnType r = tbb::this_task_arena::isolate(f); + r.check(); + } + + template <typename F> + void TestIsolate(const F &f) { + Harness::StateTrackableCounters::reset(); + ReturnType r = tbb::this_task_arena::isolate(f); + r.check(); + } +#endif + + void Test() { + TestExecute(Functor<ReturnType>()); + Functor<ReturnType> f1; + TestExecute(f1); + TestExecute(function<ReturnType>); + + arena().execute(Functor<void>()); + Functor<void> f2; + arena().execute(f2); + arena().execute(function<void>); +#if TBB_PREVIEW_TASK_ISOLATION + TestIsolate(Functor<ReturnType>()); + TestIsolate(f1); + TestIsolate(function<ReturnType>); + tbb::this_task_arena::isolate(Functor<void>()); + tbb::this_task_arena::isolate(f2); + tbb::this_task_arena::isolate(function<void>); +#endif + } +} +#endif /* __TBB_CPP11_DECLTYPE_PRESENT */ + +void TestReturnValue() { +#if __TBB_CPP11_DECLTYPE_PRESENT && !__TBB_CPP11_DECLTYPE_OF_FUNCTION_RETURN_TYPE_BROKEN + TestReturnValueNS::Test(); +#endif +} +//--------------------------------------------------// +void TestConcurrentFunctionality(int min_thread_num = MinThread, int max_thread_num = MaxThread) { + InitializeAndTerminate(max_thread_num); + for (int p = min_thread_num; p <= max_thread_num; ++p) { + REMARK("testing with %d threads\n", p); + TestConcurrentArenas(p); + TestMultipleMasters(p); + TestArenaConcurrency(p); + } +} +//--------------------------------------------------// +struct DefaultCreatedWorkersAmountBody { + int my_threadnum; + DefaultCreatedWorkersAmountBody(int threadnum) : my_threadnum(threadnum) {} + void operator()(int) const { + ASSERT(my_threadnum == tbb::this_task_arena::max_concurrency(), "concurrency level is not equal specified threadnum"); + ASSERT(tbb::this_task_arena::current_thread_index() < tbb::this_task_arena::max_concurrency(), "amount of created threads is more than specified by default"); + local_id.local() = 1; + Harness::Sleep(1); + } +}; + +struct NativeParallelForBody { + int my_thread_num; + int iterations; + NativeParallelForBody(int thread_num, int multiplier = 100) : my_thread_num(thread_num), iterations(multiplier * thread_num) {} + void operator()(int idx) const { + ASSERT(idx == 0, "more than 1 thread is going to reset TLS"); + ResetTLS(); + tbb::parallel_for(0, iterations, DefaultCreatedWorkersAmountBody(my_thread_num), tbb::simple_partitioner()); + ASSERT(local_id.size() == size_t(my_thread_num), "amount of created threads is not equal to default num"); + } +}; + +void TestDefaultCreatedWorkersAmount() { + NativeParallelFor(1, NativeParallelForBody(tbb::task_scheduler_init::default_num_threads())); +} + +void TestAbilityToCreateWorkers(int thread_num) { + tbb::task_scheduler_init init_market_with_necessary_amount_plus_one(thread_num); + // Checks only some part of reserved-master threads amount: + // 0 and 1 reserved threads are important cases but it is also needed + // to collect some statistic data with other amount and to not consume + // whole test sesion time checking each amount + TestArenaConcurrency(thread_num - 1, 0, int(thread_num / 2.72)); + TestArenaConcurrency(thread_num, 1, int(thread_num / 3.14)); +} + +void TestDefaultWorkersLimit() { + TestDefaultCreatedWorkersAmount(); + // Shared RML might limit the number of workers even if you specify the limits + // by the reason of (default_concurrency==max_concurrency) for shared RML +#ifndef RML_USE_WCRM + TestAbilityToCreateWorkers(256); +#endif +} +//--------------------------------------------------// + +// MyObserver checks if threads join to the same arena +struct MyObserver: public tbb::task_scheduler_observer { + tbb::enumerable_thread_specific<tbb::task_arena*>& my_tls; + tbb::task_arena& my_arena; + tbb::atomic<int>& my_failure_counter; + tbb::atomic<int>& my_counter; + + MyObserver(tbb::task_arena& a, + tbb::enumerable_thread_specific<tbb::task_arena*>& tls, + tbb::atomic<int>& failure_counter, + tbb::atomic<int>& counter) + : tbb::task_scheduler_observer(a), my_tls(tls), my_arena(a), + my_failure_counter(failure_counter), my_counter(counter) { + observe(true); + } + void on_scheduler_entry(bool worker) __TBB_override { + if (worker) { + ++my_counter; + tbb::task_arena*& cur_arena = my_tls.local(); + if (cur_arena != 0 && cur_arena != &my_arena) { + ++my_failure_counter; + } + cur_arena = &my_arena; + } + } +}; + +struct MyLoopBody { + Harness::SpinBarrier& m_barrier; + MyLoopBody(Harness::SpinBarrier& b):m_barrier(b) { } + void operator()(int) const { + m_barrier.wait(); + } +}; + +struct TaskForArenaExecute { + Harness::SpinBarrier& m_barrier; + TaskForArenaExecute(Harness::SpinBarrier& b):m_barrier(b) { } + void operator()() const { + tbb::parallel_for(0, tbb::this_task_arena::max_concurrency(), + MyLoopBody(m_barrier), tbb::simple_partitioner() + ); + } +}; + +struct ExecuteParallelFor { + int n_per_thread; + int n_repetitions; + std::vector<tbb::task_arena>& arenas; + Harness::SpinBarrier& arena_barrier; + Harness::SpinBarrier& master_barrier; + ExecuteParallelFor(const int n_per_thread_, const int n_repetitions_, + std::vector<tbb::task_arena>& arenas_, + Harness::SpinBarrier& arena_barrier_, Harness::SpinBarrier& master_barrier_) + : n_per_thread(n_per_thread_), n_repetitions(n_repetitions_), arenas(arenas_), + arena_barrier(arena_barrier_), master_barrier(master_barrier_){ } + void operator()(int i) const { + for (int j = 0; j < n_repetitions; ++j) { + arenas[i].execute(TaskForArenaExecute(arena_barrier)); + for(volatile int k = 0; k < n_per_thread; ++k){/* waiting until workers fall asleep */} + master_barrier.wait(); + } + } +}; + +// if n_threads == -1 then global_control initialized with default value +void TestArenaWorkersMigrationWithNumThreads(int n_threads = 0) { + if (n_threads == 0) { + n_threads = tbb::task_scheduler_init::default_num_threads(); + } + const int max_n_arenas = 8; + int n_arenas = 2; + if(n_threads >= 16) + n_arenas = max_n_arenas; + else if (n_threads >= 8) + n_arenas = 4; + n_threads = n_arenas * (n_threads / n_arenas); + const int n_per_thread = 10000000; + const int n_repetitions = 100; + const int n_outer_repetitions = 20; + std::multiset<float> failure_ratio; // for median calculating + tbb::global_control control(tbb::global_control::max_allowed_parallelism, n_threads - (n_arenas - 1)); + Harness::SpinBarrier master_barrier(n_arenas); + Harness::SpinBarrier arena_barrier(n_threads); + MyObserver* observer[max_n_arenas]; + std::vector<tbb::task_arena> arenas(n_arenas); + tbb::atomic<int> failure_counter; + tbb::atomic<int> counter; + tbb::enumerable_thread_specific<tbb::task_arena*> tls; + for (int i = 0; i < n_arenas; ++i) { + arenas[i].initialize(n_threads / n_arenas); + observer[i] = new MyObserver(arenas[i], tls, failure_counter, counter); + } + int ii = 0; + for (; ii < n_outer_repetitions; ++ii) { + failure_counter = 0; + counter = 0; + // Main code + NativeParallelFor(n_arenas, ExecuteParallelFor(n_per_thread, n_repetitions, + arenas, arena_barrier, master_barrier)); + // TODO: get rid of check below by setting ratio between n_threads and n_arenas + failure_ratio.insert((counter != 0 ? float(failure_counter) / counter : 1.0f)); + tls.clear(); + // collect 3 elements in failure_ratio before calculating median + if (ii > 1) { + std::multiset<float>::iterator it = failure_ratio.begin(); + std::advance(it, failure_ratio.size() / 2); + if (*it < 0.02) + break; + } + } + for (int i = 0; i < n_arenas; ++i) { + delete observer[i]; + } + // check if median is so big + std::multiset<float>::iterator it = failure_ratio.begin(); + std::advance(it, failure_ratio.size() / 2); + // TODO: decrease constants 0.05 and 0.3 by setting ratio between n_threads and n_arenas + if (*it > 0.05) { + REPORT("Warning: So many cases when threads join to different arenas.\n"); + ASSERT(*it <= 0.3, "A lot of cases when threads join to different arenas.\n"); + } +} + +void TestArenaWorkersMigration() { + TestArenaWorkersMigrationWithNumThreads(4); + if (tbb::task_scheduler_init::default_num_threads() != 4) { + TestArenaWorkersMigrationWithNumThreads(); + } +} + +class CheckArenaNumThreads : public tbb::task { +public: + static Harness::SpinBarrier m_barrier; + + CheckArenaNumThreads(int nt, int rm): num_threads(nt), reserved_for_masters(rm) { + m_barrier.initialize(2); + } + + tbb::task* execute() __TBB_override { + ASSERT( tbb::this_task_arena::max_concurrency() == num_threads, "Wrong concurrency of current arena" ); + ASSERT( tbb::this_task_arena::current_thread_index() >= reserved_for_masters, "Thread shouldn't attach to master's slots" ); + m_barrier.wait(); + return NULL; + } + +private: + const int num_threads; + const int reserved_for_masters; +}; + +Harness::SpinBarrier CheckArenaNumThreads::m_barrier; + +class EnqueueTaskIntoTaskArena +{ +public: + EnqueueTaskIntoTaskArena(tbb::task& t, tbb::task_arena& a) : my_task(t), my_arena(a) {} + void operator() () + { + tbb::task::enqueue(my_task, my_arena); + } +private: + tbb::task& my_task; + tbb::task_arena& my_arena; +}; + +void TestTaskEnqueueInArena() +{ + int pp[8]={3, 4, 5, 7, 8, 11, 13, 17}; + for(int i = 0; i < 8; ++i) + { + int p = pp[i]; + int reserved_for_masters = p - 1; + tbb::task_arena a(p, reserved_for_masters); + a.initialize(); + //Enqueue on master thread + { + CheckArenaNumThreads& t = *new( tbb::task::allocate_root() ) CheckArenaNumThreads(p, reserved_for_masters); + tbb::task::enqueue(t, a); + CheckArenaNumThreads::m_barrier.wait(); + a.debug_wait_until_empty(); + } + //Enqueue on thread without scheduler + { + CheckArenaNumThreads& t = *new( tbb::task::allocate_root() ) CheckArenaNumThreads(p, reserved_for_masters); + tbb::tbb_thread thr(EnqueueTaskIntoTaskArena(t, a)); + CheckArenaNumThreads::m_barrier.wait(); + a.debug_wait_until_empty(); + thr.join(); + } + } +} + +//--------------------------------------------------// + +int TestMain() { +#if __TBB_TASK_ISOLATION + TestIsolatedExecute(); +#endif /* __TBB_TASK_ISOLATION */ + TestSmallStackSize(); + TestDefaultWorkersLimit(); + // The test uses up to MaxThread workers (in arenas with no master thread), + // so the runtime should be initialized appropriately. + tbb::task_scheduler_init init_market_p_plus_one(MaxThread + 1); + TestConcurrentFunctionality(); + TestArenaEntryConsistency(); + TestAttach(MaxThread); + TestConstantFunctorRequirement(); + TestDelegatedSpawnWait(); + TestMultipleWaits(); + TestMoveSemantics(); + TestReturnValue(); + TestArenaWorkersMigration(); + TestTaskEnqueueInArena(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_assertions.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_assertions.cpp new file mode 100644 index 00000000..814dfbc3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_assertions.cpp @@ -0,0 +1,90 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Test correctness of forceful TBB initialization before any dynamic initialization +// of static objects inside the library took place. +namespace tbb { +namespace internal { + // Forward declaration of the TBB general initialization routine from task.cpp + void DoOneTimeInitializations(); +}} + +struct StaticInitializationChecker { + StaticInitializationChecker () { tbb::internal::DoOneTimeInitializations(); } +} theChecker; + +//------------------------------------------------------------------------ +// Test that important assertions in class task fail as expected. +//------------------------------------------------------------------------ + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness_inject_scheduler.h" +#include "harness.h" +#include "harness_bad_expr.h" + +#if TRY_BAD_EXPR_ENABLED +//! Task that will be abused. +tbb::task* volatile AbusedTask; + +//! Number of times that AbuseOneTask +int AbuseOneTaskRan; + +//! Body used to create task in thread 0 and abuse it in thread 1. +struct AbuseOneTask { + void operator()( int ) const { + tbb::task_scheduler_init init; + // Thread 1 attempts to incorrectly use the task created by thread 0. + tbb::task_list list; + // spawn_root_and_wait over empty list should vacuously succeed. + tbb::task::spawn_root_and_wait(list); + + // Check that spawn_root_and_wait fails on non-empty list. + list.push_back(*AbusedTask); + + // Try abusing recycle_as_continuation + TRY_BAD_EXPR(AbusedTask->recycle_as_continuation(), "execute" ); + TRY_BAD_EXPR(AbusedTask->recycle_as_safe_continuation(), "execute" ); + TRY_BAD_EXPR(AbusedTask->recycle_to_reexecute(), "execute" ); + ++AbuseOneTaskRan; + } +}; + +//! Test various __TBB_ASSERT assertions related to class tbb::task. +void TestTaskAssertions() { + // Catch assertion failures + tbb::set_assertion_handler( AssertionFailureHandler ); + tbb::task_scheduler_init init; + // Create task to be abused + AbusedTask = new( tbb::task::allocate_root() ) tbb::empty_task; + NativeParallelFor( 1, AbuseOneTask() ); + ASSERT( AbuseOneTaskRan==1, NULL ); + tbb::task::destroy(*AbusedTask); + // Restore normal assertion handling + tbb::set_assertion_handler( ReportError ); +} + +int TestMain () { + TestTaskAssertions(); + return Harness::Done; +} + +#else /* !TRY_BAD_EXPR_ENABLED */ + +int TestMain () { + return Harness::Skipped; +} + +#endif /* !TRY_BAD_EXPR_ENABLED */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_auto_init.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_auto_init.cpp new file mode 100644 index 00000000..5b9560b1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_auto_init.cpp @@ -0,0 +1,198 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Testing automatic initialization of TBB task scheduler, so do not use task_scheduler_init anywhere. + +#include "tbb/task.h" + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" +#include "tbb/atomic.h" + +static tbb::atomic<int> g_NumTestsExecuted; + +#define TEST_PROLOGUE() ++g_NumTestsExecuted + +// Global data used in testing use cases with cross-thread usage of TBB objects +static tbb::task *g_Root1 = NULL, + *g_Root2 = NULL, + *g_Root3 = NULL, + *g_Task = NULL; + +#if __TBB_TASK_GROUP_CONTEXT +static tbb::task_group_context* g_Ctx = NULL; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + + +void TestTaskSelf () { + TEST_PROLOGUE(); + tbb::task& t = tbb::task::self(); + ASSERT( !t.parent() && t.ref_count() == 1 && !t.affinity(), "Master's default task properties changed?" ); +} + +void TestRootAllocation () { + TEST_PROLOGUE(); + tbb::task &r = *new( tbb::task::allocate_root() ) tbb::empty_task; + tbb::task::spawn_root_and_wait(r); +} + +inline void ExecuteChildAndCleanup ( tbb::task &r, tbb::task &t ) { + r.set_ref_count(2); + r.spawn_and_wait_for_all(t); + r.destroy(r); +} + +void TestChildAllocation () { + TEST_PROLOGUE(); + tbb::task &t = *new( g_Root1->allocate_child() ) tbb::empty_task; + ExecuteChildAndCleanup( *g_Root1, t ); +} + +void TestAdditionalChildAllocation () { + TEST_PROLOGUE(); + tbb::task &t = *new( tbb::task::allocate_additional_child_of(*g_Root2) ) tbb::empty_task; + ExecuteChildAndCleanup( *g_Root2, t ); +} + +#if __TBB_TASK_GROUP_CONTEXT +void TestTaskGroupContextCreation () { + TEST_PROLOGUE(); + tbb::task_group_context ctx; + tbb::task &r = *new( tbb::task::allocate_root(ctx) ) tbb::empty_task; + tbb::task::spawn_root_and_wait(r); +} + +void TestRootAllocationWithContext () { + TEST_PROLOGUE(); + tbb::task* root = new( tbb::task::allocate_root(*g_Ctx) ) tbb::empty_task; + tbb::task::spawn_root_and_wait(*root); +} +#endif /* __TBB_TASK_GROUP_CONTEXT */ + +void TestSpawn () { + TEST_PROLOGUE(); + tbb::task::spawn(*g_Task); +} + +void TestWaitForAll () { + TEST_PROLOGUE(); + g_Root3->wait_for_all(); + tbb::task::destroy(*g_Root3); +} + +typedef void (*TestFnPtr)(); + +const TestFnPtr TestFuncsTable[] = { + TestTaskSelf, TestRootAllocation, TestChildAllocation, TestAdditionalChildAllocation, +#if __TBB_TASK_GROUP_CONTEXT + TestTaskGroupContextCreation, TestRootAllocationWithContext, +#endif /* __TBB_TASK_GROUP_CONTEXT */ + TestSpawn, TestWaitForAll }; + +const int NumTestFuncs = sizeof(TestFuncsTable) / sizeof(TestFnPtr); + +struct TestThreadBody : NoAssign, Harness::NoAfterlife { + // Each invocation of operator() happens in a fresh thread with zero-based ID + // id, and checks a specific auto-initialization scenario. + void operator() ( int id ) const { + ASSERT( id >= 0 && id < NumTestFuncs, "Test diver: NativeParallelFor is used incorrectly" ); + TestFuncsTable[id](); + } +}; + + +#include "../tbb/tls.h" + +void UseAFewNewTlsKeys () { + tbb::internal::tls<intptr_t> tls1, tls2, tls3, tls4; + tls1 = tls2 = tls3 = tls4 = -1; +} + +using tbb::internal::spin_wait_until_eq; + +volatile bool FafStarted = false, + FafCanFinish = false, + FafCompleted = false; + +//! This task is supposed to be executed during termination of an auto-initialized master thread +class FireAndForgetTask : public tbb::task { + tbb::task* execute () __TBB_override { + // Let another master thread proceed requesting new TLS keys + FafStarted = true; + UseAFewNewTlsKeys(); + // Wait while another master thread dirtied its new TLS slots + spin_wait_until_eq( FafCanFinish, true ); + FafCompleted = true; + return NULL; + } +public: // to make gcc 3.2.3 happy + ~FireAndForgetTask() { + ASSERT(FafCompleted, "FireAndForgetTask got erroneously cancelled?"); + } +}; + +#include "harness_barrier.h" +Harness::SpinBarrier driver_barrier(2); + +struct DriverThreadBody : NoAssign, Harness::NoAfterlife { + void operator() ( int id ) const { + ASSERT( id < 2, "Only two test driver threads are expected" ); + // a barrier is required to ensure both threads started; otherwise the test may deadlock: + // the first thread would execute FireAndForgetTask at shutdown and wait for FafCanFinish, + // while the second thread wouldn't even start waiting for the loader lock hold by the first one. + if ( id == 0 ) { + driver_barrier.wait(); + // Prepare global data + g_Root1 = new( tbb::task::allocate_root() ) tbb::empty_task; + g_Root2 = new( tbb::task::allocate_root() ) tbb::empty_task; + g_Root3 = new( tbb::task::allocate_root() ) tbb::empty_task; + g_Task = new( g_Root3->allocate_child() ) tbb::empty_task; + g_Root3->set_ref_count(2); + // Run tests + NativeParallelFor( NumTestFuncs, TestThreadBody() ); + ASSERT( g_NumTestsExecuted == NumTestFuncs, "Test driver: Wrong number of tests executed" ); + + // This test checks the validity of temporarily restoring the value of + // the last TLS slot for a given key during the termination of an + // auto-initialized master thread (in governor::auto_terminate). + // If anything goes wrong, generic_scheduler::cleanup_master() will assert. + // The context for this task must be valid till the task completion. +#if __TBB_TASK_GROUP_CONTEXT + tbb::task &r = *new( tbb::task::allocate_root(*g_Ctx) ) FireAndForgetTask; +#else + tbb::task &r = *new( tbb::task::allocate_root() ) FireAndForgetTask; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + tbb::task::spawn(r); + } + else { +#if __TBB_TASK_GROUP_CONTEXT + tbb::task_group_context ctx; + g_Ctx = &ctx; +#endif /* __TBB_TASK_GROUP_CONTEXT */ + driver_barrier.wait(); + spin_wait_until_eq( FafStarted, true ); + UseAFewNewTlsKeys(); + FafCanFinish = true; + spin_wait_until_eq( FafCompleted, true ); + } + } +}; + +int TestMain () { + // Do not use any TBB functionality in the main thread! + NativeParallelFor( 2, DriverThreadBody() ); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_enqueue.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_enqueue.cpp new file mode 100644 index 00000000..28ac860e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_enqueue.cpp @@ -0,0 +1,376 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_task.h" +#include "harness_barrier.h" +#include "tbb/atomic.h" +#include "tbb/tbb_thread.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tick_count.h" + +//////////////////////////////////////////////////////////////////////////////// +// Test for basic FIFO scheduling functionality + +const int PairsPerTrack = 100; + +class EnqueuedTask : public tbb::task { + task* my_successor; + int my_enqueue_order; + int* my_track; + tbb::task* execute() __TBB_override { + // Capture execution order in the very beginning + int execution_order = 2 - my_successor->decrement_ref_count(); + // Create some local work. + TaskGenerator& p = *new( allocate_root() ) TaskGenerator(2,2); + spawn_root_and_wait(p); + if( execution_order==2 ) { // the "slower" of two peer tasks + ++nCompletedPairs; + // Of course execution order can differ from dequeue order. + // But there is no better approximation at hand; and a single worker + // will execute in dequeue order, which is enough for our check. + if (my_enqueue_order==execution_order) + ++nOrderedPairs; + FireTwoTasks(my_track); + destroy(*my_successor); + } + return NULL; + } +public: + EnqueuedTask( task* successor, int enq_order, int* track ) + : my_successor(successor), my_enqueue_order(enq_order), my_track(track) {} + + // Create and enqueue two tasks + static void FireTwoTasks( int* track ) { + int progress = ++*track; + if( progress < PairsPerTrack ) { + task* successor = new (allocate_root()) tbb::empty_task; + successor->set_ref_count(2); + enqueue( *new (allocate_root()) EnqueuedTask(successor, 1, track) ); + enqueue( *new (allocate_root()) EnqueuedTask(successor, 2, track) ); + } + } + + static tbb::atomic<int> nCompletedPairs; + static tbb::atomic<int> nOrderedPairs; +}; + +tbb::atomic<int> EnqueuedTask::nCompletedPairs; +tbb::atomic<int> EnqueuedTask::nOrderedPairs; + +const int nTracks = 10; +static int TaskTracks[nTracks]; +const int stall_threshold = 1000000; // 1 sec + +void TimedYield( double pause_time ) { + tbb::tick_count start = tbb::tick_count::now(); + while( (tbb::tick_count::now()-start).seconds() < pause_time ) + tbb::this_tbb_thread::sleep(tbb::tick_count::interval_t(pause_time)); +} + +class ProgressMonitor { +public: + void operator() ( ) { + int track_snapshot[nTracks]; + int stall_count = 0, uneven_progress_count = 0, last_progress_mask = 0; + for(int i=0; i<nTracks; ++i) + track_snapshot[i]=0; + bool completed; + do { + // Yield repeatedly for at least 1 usec + TimedYield( 1E-6 ); + int overall_progress = 0, progress_mask = 0; + const int all_progressed = (1<<nTracks) - 1; + completed = true; + for(int i=0; i<nTracks; ++i) { + int ti = TaskTracks[i]; + int pi = ti-track_snapshot[i]; + if( pi ) progress_mask |= 1<<i; + overall_progress += pi; + completed = completed && ti==PairsPerTrack; + track_snapshot[i]=ti; + } + // The constants in the next asserts are subjective and may need correction. + if( overall_progress ) + stall_count=0; + else { + ++stall_count; + // no progress; consider it dead. + ASSERT(stall_count < stall_threshold, "no progress on enqueued tasks; deadlock, or the machine is heavily oversubscribed?"); + } + if( progress_mask==all_progressed || progress_mask^last_progress_mask ) { + uneven_progress_count = 0; + last_progress_mask = progress_mask; + } + else if ( overall_progress > 2 ) { + ++uneven_progress_count; + // The threshold of 32 is 4x bigger than what was observed on a 8-core machine with oversubscription. + ASSERT_WARNING(uneven_progress_count < 32, + "some enqueued tasks seem stalling; no simultaneous progress, or the machine is oversubscribed? Investigate if repeated"); + } + } while( !completed ); + } +}; + +void TestEnqueue( int p ) { + REMARK("Testing task::enqueue for %d threads\n", p); + for(int mode=0;mode<3;++mode) { + tbb::task_scheduler_init init(p); + EnqueuedTask::nCompletedPairs = EnqueuedTask::nOrderedPairs = 0; + for(int i=0; i<nTracks; ++i) { + TaskTracks[i] = -1; // to accommodate for the starting call + EnqueuedTask::FireTwoTasks(TaskTracks+i); + } + ProgressMonitor pm; + tbb::tbb_thread thr( pm ); + if(mode==1) { + // do some parallel work in the meantime + for(int i=0; i<10; i++) { + TaskGenerator& g = *new( tbb::task::allocate_root() ) TaskGenerator(2,5); + tbb::task::spawn_root_and_wait(g); + TimedYield( 1E-6 ); + } + } + if( mode==2 ) { + // Additionally enqueue a bunch of empty tasks. The goal is to test that tasks + // allocated and enqueued by a thread are safe to use after the thread leaves TBB. + tbb::task* root = new (tbb::task::allocate_root()) tbb::empty_task; + root->set_ref_count(100); + for( int i=0; i<100; ++i ) + tbb::task::enqueue( *new (root->allocate_child()) tbb::empty_task ); + init.terminate(); // master thread deregistered + } + thr.join(); + ASSERT(EnqueuedTask::nCompletedPairs==nTracks*PairsPerTrack, NULL); + ASSERT(EnqueuedTask::nOrderedPairs<EnqueuedTask::nCompletedPairs, + "all task pairs executed in enqueue order; de facto guarantee is too strong?"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Tests for Fire-And-Forget scheduling functionality + +int NumRepeats = 200; +const int MaxNumThreads = 16; +static volatile bool Finished[MaxNumThreads] = {}; + +static volatile bool CanStart; + +//! Custom user task interface +class ITask { +public: + virtual ~ITask() {} + virtual void Execute() = 0; + virtual void Release() { delete this; } +}; + +class TestTask : public ITask { + volatile bool *m_pDone; +public: + TestTask ( volatile bool *pDone ) : m_pDone(pDone) {} + + void Execute() __TBB_override { + *m_pDone = true; + } +}; + +class CarrierTask : public tbb::task { + ITask* m_pTask; +public: + CarrierTask(ITask* pTask) : m_pTask(pTask) {} + + task* execute() __TBB_override { + m_pTask->Execute(); + m_pTask->Release(); + return NULL; + } +}; + +class SpawnerTask : public ITask { + ITask* m_taskToSpawn; +public: + SpawnerTask(ITask* job) : m_taskToSpawn(job) {} + + void Execute() __TBB_override { + while ( !CanStart ) + __TBB_Yield(); + Harness::Sleep(10); // increases probability of the bug + tbb::task::enqueue( *new( tbb::task::allocate_root() ) CarrierTask(m_taskToSpawn) ); + } +}; + +class EnqueuerBody { +public: + void operator() ( int id ) const { + tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads() + 1); + + SpawnerTask* pTask = new SpawnerTask( new TestTask(Finished + id) ); + tbb::task::enqueue( *new( tbb::task::allocate_root() ) CarrierTask(pTask) ); + } +}; + +//! Regression test for a bug that caused premature arena destruction +void TestCascadedEnqueue () { + REMARK("Testing cascaded enqueue\n"); + tbb::task_scheduler_init init(tbb::task_scheduler_init::default_num_threads() + 1); + + int minNumThreads = min(tbb::task_scheduler_init::default_num_threads(), MaxNumThreads) / 2; + int maxNumThreads = min(tbb::task_scheduler_init::default_num_threads() * 2, MaxNumThreads); + + for ( int numThreads = minNumThreads; numThreads <= maxNumThreads; ++numThreads ) { + for ( int i = 0; i < NumRepeats; ++i ) { + CanStart = false; + __TBB_Yield(); + NativeParallelFor( numThreads, EnqueuerBody() ); + CanStart = true; + int j = 0; + while ( j < numThreads ) { + if ( Finished[j] ) + ++j; + else + __TBB_Yield(); + } + for ( j = 0; j < numThreads; ++j ) + Finished[j] = false; + REMARK("\r%02d threads; Iteration %03d", numThreads, i); + } + } + REMARK( "\r \r" ); +} + +class DummyTask : public tbb::task { +public: + task *execute() __TBB_override { + Harness::Sleep(1); + return NULL; + } +}; + +class SharedRootBody { + tbb::task *my_root; +public: + SharedRootBody ( tbb::task *root ) : my_root(root) {} + + void operator() ( int ) const { + tbb::task::enqueue( *new( tbb::task::allocate_additional_child_of(*my_root) ) DummyTask ); + } +}; + +//! Test for enqueuing children of the same root from different master threads +void TestSharedRoot ( int p ) { + REMARK("Testing enqueuing siblings from different masters\n"); + tbb::task_scheduler_init init(p); + tbb::task *root = new ( tbb::task::allocate_root() ) tbb::empty_task; + root->set_ref_count(1); + for( int n = MinThread; n <= MaxThread; ++n ) { + REMARK("%d masters, %d requested workers\r", n, p-1); + NativeParallelFor( n, SharedRootBody(root) ); + } + REMARK( " \r" ); + root->wait_for_all(); + tbb::task::destroy(*root); +} + +class BlockingTask : public tbb::task { + Harness::SpinBarrier &m_Barrier; + + tbb::task* execute () __TBB_override { + m_Barrier.wait(); + return 0; + } + +public: + BlockingTask ( Harness::SpinBarrier& bar ) : m_Barrier(bar) {} +}; + +//! Test making sure that masters can dequeue tasks +/** Success criterion is not hanging. **/ +void TestDequeueByMaster () { + REMARK("Testing task dequeuing by master\n"); + tbb::task_scheduler_init init(1); + Harness::SpinBarrier bar(2); + tbb::task &r = *new ( tbb::task::allocate_root() ) tbb::empty_task; + r.set_ref_count(3); + tbb::task::enqueue( *new(r.allocate_child()) BlockingTask(bar) ); + tbb::task::enqueue( *new(r.allocate_child()) BlockingTask(bar) ); + r.wait_for_all(); + tbb::task::destroy(r); +} + +////////////////////// Missed wake-ups /////// +#include "tbb/blocked_range.h" +#include "tbb/parallel_for.h" + +static const int NUM_TASKS = 4; +static const size_t NUM_REPEATS = TBB_USE_DEBUG ? 50000 : 100000; +static tbb::task_group_context persistent_context(tbb::task_group_context::isolated); + +struct Functor : NoAssign +{ + Harness::SpinBarrier &my_barrier; + Functor(Harness::SpinBarrier &a_barrier) : my_barrier(a_barrier) { } + void operator()(const tbb::blocked_range<int>& r) const + { + ASSERT(r.size() == 1, NULL); + // allocate_root() uses current context of parallel_for which is destroyed when it finishes. + // But enqueued tasks can outlive parallel_for execution. Thus, use a persistent context. + tbb::task *t = new(tbb::task::allocate_root(persistent_context)) tbb::empty_task(); + tbb::task::enqueue(*t); // ensure no missing wake-ups + my_barrier.timed_wait(10, "Attention: poorly reproducible event, if seen stress testing required" ); + } +}; + +void TestWakeups() +{ + tbb::task_scheduler_init my(tbb::task_scheduler_init::deferred); + if( tbb::task_scheduler_init::default_num_threads() <= NUM_TASKS ) + my.initialize(NUM_TASKS*2); + else // workaround issue #1996 for TestCascadedEnqueue + my.initialize(tbb::task_scheduler_init::default_num_threads()+1); + Harness::SpinBarrier barrier(NUM_TASKS); + REMARK("Missing wake-up: affinity_partitioner\n"); + tbb::affinity_partitioner aff; + for (size_t i = 0; i < NUM_REPEATS; ++i) + tbb::parallel_for(tbb::blocked_range<int>(0, NUM_TASKS), Functor(barrier), aff); + REMARK("Missing wake-up: simple_partitioner\n"); + for (size_t i = 0; i < NUM_REPEATS; ++i) + tbb::parallel_for(tbb::blocked_range<int>(0, NUM_TASKS), Functor(barrier), tbb::simple_partitioner()); + REMARK("Missing wake-up: auto_partitioner\n"); + for (size_t i = 0; i < NUM_REPEATS; ++i) + tbb::parallel_for(tbb::blocked_range<int>(0, NUM_TASKS), Functor(barrier)); // auto +} + +#include "tbb/global_control.h" + +int TestMain () { + + TestWakeups(); // 1st because requests oversubscription + for (int i=0; i<2; i++) { + tbb::global_control *c = i? + new tbb::global_control(tbb::global_control::max_allowed_parallelism, 1) : NULL; + if (i) // decrease workload for max_allowed_parallelism == 1 + NumRepeats = 10; + + TestCascadedEnqueue(); // needs oversubscription + if (!c) + TestDequeueByMaster(); // no oversubscription needed + for( int p=MinThread; p<=MaxThread; ++p ) { + TestEnqueue(p); + TestSharedRoot(p); + } + delete c; + } + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_group.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_group.cpp new file mode 100644 index 00000000..f436c26b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_group.cpp @@ -0,0 +1,1115 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "harness_defs.h" + +//Concurrency scheduler is not supported by Windows* new UI apps +//TODO: check whether we can test anything here +#include "tbb/tbb_config.h" +#if !__TBB_WIN8UI_SUPPORT +#ifndef TBBTEST_USE_TBB + #define TBBTEST_USE_TBB 1 +#endif +#else + #define TBBTEST_USE_TBB 0 + #undef __TBB_TASK_GROUP_CONTEXT + #define __TBB_TASK_GROUP_CONTEXT 0 +#endif + +#if !TBBTEST_USE_TBB + #if defined(_MSC_VER) && _MSC_VER < 1600 + #ifdef TBBTEST_USE_TBB + #undef TBBTEST_USE_TBB + #endif + #define TBBTEST_USE_TBB 1 + #endif +#endif + +#if TBBTEST_USE_TBB + + #include "tbb/compat/ppl.h" + #include "tbb/task_scheduler_init.h" + + #if _MSC_VER + typedef tbb::internal::uint32_t uint_t; + #else + typedef uint32_t uint_t; + #endif + +#else /* !TBBTEST_USE_TBB */ + + #if defined(_MSC_VER) + #pragma warning(disable: 4100 4180) + #endif + + #include <ppl.h> + + typedef unsigned int uint_t; + + // Bug in this ConcRT version results in task_group::wait() rethrowing + // internal cancellation exception propagated by the scheduler from the nesting + // task group. + #define __TBB_SILENT_CANCELLATION_BROKEN (_MSC_VER == 1600) + +#endif /* !TBBTEST_USE_TBB */ + +#if __TBB_TASK_GROUP_CONTEXT + +#include "tbb/atomic.h" +#include "tbb/aligned_space.h" +#include "harness.h" +#include "harness_concurrency_tracker.h" + +unsigned g_MaxConcurrency = 0; + +typedef tbb::atomic<uint_t> atomic_t; +typedef Concurrency::task_handle<void(*)()> handle_type; + +//------------------------------------------------------------------------ +// Tests for the thread safety of the task_group manipulations +//------------------------------------------------------------------------ + +#include "harness_barrier.h" + +enum SharingMode { + VagabondGroup = 1, + ParallelWait = 2 +}; + +template<typename task_group_type> +class SharedGroupBodyImpl : NoCopy, Harness::NoAfterlife { + static const uint_t c_numTasks0 = 4096, + c_numTasks1 = 1024; + + const uint_t m_numThreads; + const uint_t m_sharingMode; + + task_group_type *m_taskGroup; + atomic_t m_tasksSpawned, + m_threadsReady; + Harness::SpinBarrier m_barrier; + + static atomic_t s_tasksExecuted; + + struct TaskFunctor { + SharedGroupBodyImpl *m_pOwner; + void operator () () const { + if ( m_pOwner->m_sharingMode & ParallelWait ) { + while ( Harness::ConcurrencyTracker::PeakParallelism() < m_pOwner->m_numThreads ) + __TBB_Yield(); + } + ++s_tasksExecuted; + } + }; + + TaskFunctor m_taskFunctor; + + void Spawn ( uint_t numTasks ) { + for ( uint_t i = 0; i < numTasks; ++i ) { + ++m_tasksSpawned; + Harness::ConcurrencyTracker ct; + m_taskGroup->run( m_taskFunctor ); + } + ++m_threadsReady; + } + + void DeleteTaskGroup () { + delete m_taskGroup; + m_taskGroup = NULL; + } + + void Wait () { + while ( m_threadsReady != m_numThreads ) + __TBB_Yield(); + const uint_t numSpawned = c_numTasks0 + c_numTasks1 * (m_numThreads - 1); + ASSERT ( m_tasksSpawned == numSpawned, "Wrong number of spawned tasks. The test is broken" ); + REMARK("Max spawning parallelism is %u out of %u\n", Harness::ConcurrencyTracker::PeakParallelism(), g_MaxConcurrency); + if ( m_sharingMode & ParallelWait ) { + m_barrier.wait( &Harness::ConcurrencyTracker::Reset ); + { + Harness::ConcurrencyTracker ct; + m_taskGroup->wait(); + } + if ( Harness::ConcurrencyTracker::PeakParallelism() == 1 ) + REPORT ( "Warning: No parallel waiting detected in TestParallelWait\n" ); + m_barrier.wait(); + } + else + m_taskGroup->wait(); + ASSERT ( m_tasksSpawned == numSpawned, "No tasks should be spawned after wait starts. The test is broken" ); + ASSERT ( s_tasksExecuted == numSpawned, "Not all spawned tasks were executed" ); + } + +public: + SharedGroupBodyImpl ( uint_t numThreads, uint_t sharingMode = 0 ) + : m_numThreads(numThreads) + , m_sharingMode(sharingMode) + , m_taskGroup(NULL) + , m_barrier(numThreads) + { + ASSERT ( m_numThreads > 1, "SharedGroupBody tests require concurrency" ); + ASSERT ( !(m_sharingMode & VagabondGroup) || m_numThreads == 2, "In vagabond mode SharedGroupBody must be used with 2 threads only" ); + Harness::ConcurrencyTracker::Reset(); + s_tasksExecuted = 0; + m_tasksSpawned = 0; + m_threadsReady = 0; + m_taskFunctor.m_pOwner = this; + } + + void Run ( uint_t idx ) { +#if TBBTEST_USE_TBB + tbb::task_scheduler_init init(g_MaxConcurrency); +#endif + AssertLive(); + if ( idx == 0 ) { + ASSERT ( !m_taskGroup && !m_tasksSpawned, "SharedGroupBody must be reset before reuse"); + m_taskGroup = new task_group_type; + Spawn( c_numTasks0 ); + Wait(); + if ( m_sharingMode & VagabondGroup ) + m_barrier.wait(); + else + DeleteTaskGroup(); + } + else { + while ( m_tasksSpawned == 0 ) + __TBB_Yield(); + ASSERT ( m_taskGroup, "Task group is not initialized"); + Spawn (c_numTasks1); + if ( m_sharingMode & ParallelWait ) + Wait(); + if ( m_sharingMode & VagabondGroup ) { + ASSERT ( idx == 1, "In vagabond mode SharedGroupBody must be used with 2 threads only" ); + m_barrier.wait(); + DeleteTaskGroup(); + } + } + AssertLive(); + } +}; + +template<typename task_group_type> +atomic_t SharedGroupBodyImpl<task_group_type>::s_tasksExecuted; + +template<typename task_group_type> +class SharedGroupBody : NoAssign, Harness::NoAfterlife { + bool m_bOwner; + SharedGroupBodyImpl<task_group_type> *m_pImpl; +public: + SharedGroupBody ( uint_t numThreads, uint_t sharingMode = 0 ) + : NoAssign() + , Harness::NoAfterlife() + , m_bOwner(true) + , m_pImpl( new SharedGroupBodyImpl<task_group_type>(numThreads, sharingMode) ) + {} + SharedGroupBody ( const SharedGroupBody& src ) + : NoAssign() + , Harness::NoAfterlife() + , m_bOwner(false) + , m_pImpl(src.m_pImpl) + {} + ~SharedGroupBody () { + if ( m_bOwner ) + delete m_pImpl; + } + void operator() ( uint_t idx ) const { m_pImpl->Run(idx); } +}; + +template<typename task_group_type> +class RunAndWaitSyncronizationTestBody : NoAssign { + Harness::SpinBarrier& m_barrier; + tbb::atomic<bool>& m_completed; + task_group_type& m_tg; +public: + RunAndWaitSyncronizationTestBody(Harness::SpinBarrier& barrier, tbb::atomic<bool>& completed, task_group_type& tg) + : m_barrier(barrier), m_completed(completed), m_tg(tg) {} + + void operator()() const { + m_barrier.wait(); + for (volatile int i = 0; i < 100000; ++i) {} + m_completed = true; + } + + void operator()(int id) const { + if (id == 0) { + m_tg.run_and_wait(*this); + } else { + m_barrier.wait(); + m_tg.wait(); + ASSERT(m_completed, "A concurrent waiter has left the wait method earlier than work has finished"); + } + } +}; + + + +template<typename task_group_type> +void TestParallelSpawn () { + NativeParallelFor( g_MaxConcurrency, SharedGroupBody<task_group_type>(g_MaxConcurrency) ); +} + +template<typename task_group_type> +void TestParallelWait () { + NativeParallelFor( g_MaxConcurrency, SharedGroupBody<task_group_type>(g_MaxConcurrency, ParallelWait) ); + + Harness::SpinBarrier barrier(g_MaxConcurrency); + tbb::atomic<bool> completed; + completed = false; + task_group_type tg; + RunAndWaitSyncronizationTestBody<task_group_type> b(barrier, completed, tg); + NativeParallelFor( g_MaxConcurrency, b ); +} + +// Tests non-stack-bound task group (the group that is allocated by one thread and destroyed by the other) +template<typename task_group_type> +void TestVagabondGroup () { + NativeParallelFor( 2, SharedGroupBody<task_group_type>(2, VagabondGroup) ); +} + + + +template<typename task_group_type> +void TestThreadSafety() { + TestParallelSpawn<task_group_type>(); + TestParallelWait<task_group_type>(); + TestVagabondGroup<task_group_type>(); +} + +//------------------------------------------------------------------------ +// Common requisites of the Fibonacci tests +//------------------------------------------------------------------------ + +const uint_t N = 20; +const uint_t F = 6765; + +atomic_t g_Sum; + +#define FIB_TEST_PROLOGUE() \ + const unsigned numRepeats = g_MaxConcurrency * (TBB_USE_DEBUG ? 4 : 16); \ + Harness::ConcurrencyTracker::Reset() + +#define FIB_TEST_EPILOGUE(sum) \ + ASSERT( sum == numRepeats * F, NULL ); \ + REMARK("Realized parallelism in Fib test is %u out of %u\n", Harness::ConcurrencyTracker::PeakParallelism(), g_MaxConcurrency) + +// Fibonacci tasks specified as functors +template<class task_group_type> +class FibTaskBase : NoAssign, Harness::NoAfterlife { +protected: + uint_t* m_pRes; + mutable uint_t m_Num; + virtual void impl() const = 0; +public: + FibTaskBase( uint_t* y, uint_t n ) : m_pRes(y), m_Num(n) {} + void operator()() const { + Harness::ConcurrencyTracker ct; + AssertLive(); + if( m_Num < 2 ) { + *m_pRes = m_Num; + } else { + impl(); + } + } + virtual ~FibTaskBase() {} +}; + +template<class task_group_type> +class FibTaskAsymmetricTreeWithTaskHandle : public FibTaskBase<task_group_type> { +public: + FibTaskAsymmetricTreeWithTaskHandle( uint_t* y, uint_t n ) : FibTaskBase<task_group_type>(y, n) {} + virtual void impl() const __TBB_override { + uint_t x = ~0u; + task_group_type tg; + Concurrency::task_handle<FibTaskAsymmetricTreeWithTaskHandle> + h = FibTaskAsymmetricTreeWithTaskHandle(&x, this->m_Num-1); + tg.run( h ); + this->m_Num -= 2; (*this)(); + tg.wait(); + *(this->m_pRes) += x; + } +}; + +template<class task_group_type> +class FibTaskSymmetricTreeWithTaskHandle : public FibTaskBase<task_group_type> { +public: + FibTaskSymmetricTreeWithTaskHandle( uint_t* y, uint_t n ) : FibTaskBase<task_group_type>(y, n) {} + virtual void impl() const __TBB_override { + uint_t x = ~0u, + y = ~0u; + task_group_type tg; + Concurrency::task_handle<FibTaskSymmetricTreeWithTaskHandle> + h1 = FibTaskSymmetricTreeWithTaskHandle(&x, this->m_Num-1), + h2 = FibTaskSymmetricTreeWithTaskHandle(&y, this->m_Num-2); + tg.run( h1 ); + tg.run( h2 ); + tg.wait(); + *(this->m_pRes) = x + y; + } +}; + +template<class task_group_type> +class FibTaskAsymmetricTreeWithFunctor : public FibTaskBase<task_group_type> { +public: + FibTaskAsymmetricTreeWithFunctor( uint_t* y, uint_t n ) : FibTaskBase<task_group_type>(y, n) {} + virtual void impl() const __TBB_override { + uint_t x = ~0u; + task_group_type tg; + tg.run( FibTaskAsymmetricTreeWithFunctor(&x, this->m_Num-1) ); + this->m_Num -= 2; tg.run_and_wait( *this ); + *(this->m_pRes) += x; + } +}; + +template<class task_group_type> +class FibTaskSymmetricTreeWithFunctor : public FibTaskBase<task_group_type> { +public: + FibTaskSymmetricTreeWithFunctor( uint_t* y, uint_t n ) : FibTaskBase<task_group_type>(y, n) {} + virtual void impl() const __TBB_override { + uint_t x = ~0u, + y = ~0u; + task_group_type tg; + tg.run( FibTaskSymmetricTreeWithFunctor(&x, this->m_Num-1) ); + tg.run( FibTaskSymmetricTreeWithFunctor(&y, this->m_Num-2) ); + tg.wait(); + *(this->m_pRes) = x + y; + } +}; + + + +// Helper functions +template<class fib_task> +uint_t RunFibTask(uint_t n) { + uint_t res = ~0u; + fib_task(&res, n)(); + return res; +} + +template<typename fib_task> +void RunFibTest() { + FIB_TEST_PROLOGUE(); + uint_t sum = 0; + for( unsigned i = 0; i < numRepeats; ++i ) + sum += RunFibTask<fib_task>(N); + FIB_TEST_EPILOGUE(sum); +} + +template<typename fib_task> +void FibFunctionNoArgs() { + g_Sum += RunFibTask<fib_task>(N); +} + + + +template<typename task_group_type> +void TestFibWithTaskHandle() { + RunFibTest<FibTaskAsymmetricTreeWithTaskHandle<task_group_type> >(); + RunFibTest< FibTaskSymmetricTreeWithTaskHandle<task_group_type> >(); +} + +#if __TBB_CPP11_LAMBDAS_PRESENT +template<typename task_group_type> +void TestFibWithMakeTask() { + REMARK ("make_task test\n"); + atomic_t sum; + sum = 0; + task_group_type tg; + auto h1 = Concurrency::make_task( [&](){sum += RunFibTask<FibTaskSymmetricTreeWithTaskHandle<task_group_type> >(N);} ); + auto h2 = Concurrency::make_task( [&](){sum += RunFibTask<FibTaskSymmetricTreeWithTaskHandle<task_group_type> >(N);} ); + tg.run( h1 ); + tg.run_and_wait( h2 ); + ASSERT( sum == 2 * F, NULL ); +} + +template<typename task_group_type> +void TestFibWithLambdas() { + REMARK ("Lambdas test"); + FIB_TEST_PROLOGUE(); + atomic_t sum; + sum = 0; + task_group_type tg; + for( unsigned i = 0; i < numRepeats; ++i ) + tg.run( [&](){sum += RunFibTask<FibTaskSymmetricTreeWithFunctor<task_group_type> >(N);} ); + tg.wait(); + FIB_TEST_EPILOGUE(sum); +} +#endif //__TBB_CPP11_LAMBDAS_PRESENT + +template<typename task_group_type> +void TestFibWithFunctor() { + RunFibTest<FibTaskAsymmetricTreeWithFunctor<task_group_type> >(); + RunFibTest< FibTaskSymmetricTreeWithFunctor<task_group_type> >(); +} + +template<typename task_group_type> +void TestFibWithFunctionPtr() { + FIB_TEST_PROLOGUE(); + g_Sum = 0; + task_group_type tg; + for( unsigned i = 0; i < numRepeats; ++i ) + tg.run( &FibFunctionNoArgs<FibTaskSymmetricTreeWithFunctor<task_group_type> > ); + tg.wait(); + FIB_TEST_EPILOGUE(g_Sum); +} + +template<typename task_group_type> +void TestFibInvalidMultipleScheduling() { + FIB_TEST_PROLOGUE(); + g_Sum = 0; + task_group_type tg; + typedef tbb::aligned_space<handle_type> handle_space_t; + handle_space_t *handles = new handle_space_t[numRepeats]; + handle_type *h = NULL; +#if __TBB_ipf && __TBB_GCC_VERSION==40601 + volatile // Workaround for unexpected exit from the loop below after the exception was caught +#endif + unsigned i = 0; + for( ;; ++i ) { + h = handles[i].begin(); +#if __TBB_FUNC_PTR_AS_TEMPL_PARAM_BROKEN + new ( h ) handle_type((void(*)())FibFunctionNoArgs<FibTaskSymmetricTreeWithTaskHandle<task_group_type> >); +#else + new ( h ) handle_type(FibFunctionNoArgs<FibTaskSymmetricTreeWithTaskHandle<task_group_type> >); +#endif + if ( i == numRepeats - 1 ) + break; + tg.run( *h ); +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + bool caught = false; + try { + if( i&1 ) tg.run( *h ); + else tg.run_and_wait( *h ); + } + catch ( Concurrency::invalid_multiple_scheduling& e ) { + ASSERT( e.what(), "Error message is absent" ); + caught = true; + } + catch ( ... ) { + ASSERT ( __TBB_EXCEPTION_TYPE_INFO_BROKEN, "Unrecognized exception" ); + } + ASSERT ( caught, "Expected invalid_multiple_scheduling exception is missing" ); +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ + } + ASSERT( i == numRepeats - 1, "unexpected exit from the loop" ); + tg.run_and_wait( *h ); + + for( i = 0; i < numRepeats; ++i ) +#if __TBB_UNQUALIFIED_CALL_OF_DTOR_BROKEN + handles[i].begin()->Concurrency::task_handle<void(*)()>::~task_handle(); +#else + handles[i].begin()->~handle_type(); +#endif + delete []handles; + FIB_TEST_EPILOGUE(g_Sum); +} + + + +template<typename task_group_type> +void RunFibonacciTests() { + TestFibWithTaskHandle<task_group_type>(); +#if __TBB_CPP11_LAMBDAS_PRESENT + TestFibWithMakeTask<task_group_type>(); + TestFibWithLambdas<task_group_type>(); +#endif + TestFibWithFunctor<task_group_type>(); + TestFibWithFunctionPtr<task_group_type>(); + TestFibInvalidMultipleScheduling<task_group_type>(); +} + +// tbb::structured_task_group accepts tasks only as task_handle object +template<> void RunFibonacciTests<Concurrency::structured_task_group>() { + TestFibWithTaskHandle<Concurrency::structured_task_group>(); +#if __TBB_CPP11_LAMBDAS_PRESENT + TestFibWithMakeTask<Concurrency::structured_task_group>(); +#endif + TestFibInvalidMultipleScheduling<Concurrency::structured_task_group>(); +} + + + +class test_exception : public std::exception +{ + const char* m_strDescription; +public: + test_exception ( const char* descr ) : m_strDescription(descr) {} + + const char* what() const throw() __TBB_override { return m_strDescription; } +}; + +#if TBB_USE_CAPTURED_EXCEPTION + #include "tbb/tbb_exception.h" + typedef tbb::captured_exception TestException; +#else + typedef test_exception TestException; +#endif + +#include <string.h> + +#define NUM_CHORES 512 +#define NUM_GROUPS 64 +#define SKIP_CHORES (NUM_CHORES/4) +#define SKIP_GROUPS (NUM_GROUPS/4) +#define EXCEPTION_DESCR1 "Test exception 1" +#define EXCEPTION_DESCR2 "Test exception 2" + +atomic_t g_ExceptionCount; +atomic_t g_TaskCount; +unsigned g_ExecutedAtCancellation; +bool g_Rethrow; +bool g_Throw; +#if __TBB_SILENT_CANCELLATION_BROKEN + volatile bool g_CancellationPropagationInProgress; + #define CATCH_ANY() \ + __TBB_CATCH( ... ) { \ + if ( g_CancellationPropagationInProgress ) { \ + if ( g_Throw ) { \ + exceptionCaught = true; \ + ++g_ExceptionCount; \ + } \ + } else \ + ASSERT( false, "Unknown exception" ); \ + } +#else + #define CATCH_ANY() __TBB_CATCH( ... ) { ASSERT( __TBB_EXCEPTION_TYPE_INFO_BROKEN, "Unknown exception" ); } +#endif + +class ThrowingTask : NoAssign, Harness::NoAfterlife { + atomic_t &m_TaskCount; +public: + ThrowingTask( atomic_t& counter ) : m_TaskCount(counter) {} + void operator() () const { + Harness::ConcurrencyTracker ct; + AssertLive(); + if ( g_Throw ) { + if ( ++m_TaskCount == SKIP_CHORES ) + __TBB_THROW( test_exception(EXCEPTION_DESCR1) ); + __TBB_Yield(); + } + else { + ++g_TaskCount; + while( !Concurrency::is_current_task_group_canceling() ) + __TBB_Yield(); + } + } +}; + +inline void ResetGlobals ( bool bThrow, bool bRethrow ) { + g_Throw = bThrow; + g_Rethrow = bRethrow; +#if __TBB_SILENT_CANCELLATION_BROKEN + g_CancellationPropagationInProgress = false; +#endif + g_ExceptionCount = 0; + g_TaskCount = 0; + Harness::ConcurrencyTracker::Reset(); +} + +template<typename task_group_type> +void LaunchChildrenWithFunctor () { + atomic_t count; + count = 0; + task_group_type g; + bool exceptionCaught = false; + for( unsigned i = 0; i < NUM_CHORES; ++i ) + g.run( ThrowingTask(count) ); + Concurrency::task_group_status status = Concurrency::not_complete; + __TBB_TRY { + status = g.wait(); + } __TBB_CATCH ( TestException& e ) { +#if TBB_USE_EXCEPTIONS + ASSERT( e.what(), "Empty what() string" ); + ASSERT( __TBB_EXCEPTION_TYPE_INFO_BROKEN || strcmp(e.what(), EXCEPTION_DESCR1) == 0, "Unknown exception" ); +#endif /* TBB_USE_EXCEPTIONS */ + exceptionCaught = true; + ++g_ExceptionCount; + } CATCH_ANY(); + ASSERT( !g_Throw || exceptionCaught || status == Concurrency::canceled, "No exception in the child task group" ); + if ( g_Rethrow && g_ExceptionCount > SKIP_GROUPS ) { +#if __TBB_SILENT_CANCELLATION_BROKEN + g_CancellationPropagationInProgress = true; +#endif + __TBB_THROW( test_exception(EXCEPTION_DESCR2) ); + } +} + +template<typename task_group_type> +void LaunchChildrenWithTaskHandle () { + atomic_t count; + count = 0; + task_group_type g; + bool exceptionCaught = false; + typedef Concurrency::task_handle<ThrowingTask> throwing_handle_type; + tbb::aligned_space<throwing_handle_type,NUM_CHORES> handles; + for( unsigned i = 0; i < NUM_CHORES; ++i ) { + throwing_handle_type *h = handles.begin()+i; + new ( h ) throwing_handle_type( ThrowingTask(count) ); + g.run( *h ); + } + __TBB_TRY { + g.wait(); + } __TBB_CATCH( TestException& e ) { +#if TBB_USE_EXCEPTIONS + ASSERT( e.what(), "Empty what() string" ); + ASSERT( __TBB_EXCEPTION_TYPE_INFO_BROKEN || strcmp(e.what(), EXCEPTION_DESCR1) == 0, "Unknown exception" ); +#endif /* TBB_USE_EXCEPTIONS */ +#if __TBB_SILENT_CANCELLATION_BROKEN + ASSERT ( !g.is_canceling() || g_CancellationPropagationInProgress, "wait() has not reset cancellation state" ); +#else + ASSERT ( !g.is_canceling(), "wait() has not reset cancellation state" ); +#endif + exceptionCaught = true; + ++g_ExceptionCount; + } CATCH_ANY(); + ASSERT( !g_Throw || exceptionCaught, "No exception in the child task group" ); + for( unsigned i = 0; i < NUM_CHORES; ++i ) + (handles.begin()+i)->~throwing_handle_type(); + if ( g_Rethrow && g_ExceptionCount > SKIP_GROUPS ) { +#if __TBB_SILENT_CANCELLATION_BROKEN + g_CancellationPropagationInProgress = true; +#endif + __TBB_THROW( test_exception(EXCEPTION_DESCR2) ); + } +} + +template<typename task_group_type> +class LaunchChildrenWithTaskHandleDriver { + tbb::aligned_space<handle_type,NUM_CHORES> m_handles; + +public: + void Launch ( task_group_type& tg ) { + ResetGlobals( false, false ); + for( unsigned i = 0; i < NUM_GROUPS; ++i ) { + handle_type *h = m_handles.begin()+i; + new ( h ) handle_type( LaunchChildrenWithTaskHandle<task_group_type> ); + tg.run( *h ); + } + ASSERT ( !Concurrency::is_current_task_group_canceling(), "Unexpected cancellation" ); + ASSERT ( !tg.is_canceling(), "Unexpected cancellation" ); +#if __TBB_SILENT_CANCELLATION_BROKEN + g_CancellationPropagationInProgress = true; +#endif + while ( g_MaxConcurrency > 1 && g_TaskCount == 0 ) + __TBB_Yield(); + } + + void Finish () { + for( unsigned i = 0; i < NUM_GROUPS; ++i ) + (m_handles.begin()+i)->~handle_type(); + ASSERT( g_TaskCount <= NUM_GROUPS * NUM_CHORES, "Too many tasks reported. The test is broken" ); + ASSERT( g_TaskCount < NUM_GROUPS * NUM_CHORES, "No tasks were cancelled. Cancellation model changed?" ); + ASSERT( g_TaskCount <= g_ExecutedAtCancellation + g_MaxConcurrency, "Too many tasks survived cancellation" ); + } +}; // LaunchChildrenWithTaskHandleDriver + + + +// Tests for cancellation and exception handling behavior +template<typename task_group_type> +void TestManualCancellationWithFunctor () { + ResetGlobals( false, false ); + task_group_type tg; + for( unsigned i = 0; i < NUM_GROUPS; ++i ) + // TBB version does not require taking function address + tg.run( &LaunchChildrenWithFunctor<task_group_type> ); + ASSERT ( !Concurrency::is_current_task_group_canceling(), "Unexpected cancellation" ); + ASSERT ( !tg.is_canceling(), "Unexpected cancellation" ); +#if __TBB_SILENT_CANCELLATION_BROKEN + g_CancellationPropagationInProgress = true; +#endif + while ( g_MaxConcurrency > 1 && g_TaskCount == 0 ) + __TBB_Yield(); + tg.cancel(); + g_ExecutedAtCancellation = g_TaskCount; + ASSERT ( tg.is_canceling(), "No cancellation reported" ); + tg.wait(); + ASSERT( g_TaskCount <= NUM_GROUPS * NUM_CHORES, "Too many tasks reported. The test is broken" ); + ASSERT( g_TaskCount < NUM_GROUPS * NUM_CHORES, "No tasks were cancelled. Cancellation model changed?" ); + ASSERT( g_TaskCount <= g_ExecutedAtCancellation + Harness::ConcurrencyTracker::PeakParallelism(), "Too many tasks survived cancellation" ); +} + +template<typename task_group_type> +void TestManualCancellationWithTaskHandle () { + LaunchChildrenWithTaskHandleDriver<task_group_type> driver; + task_group_type tg; + driver.Launch( tg ); + tg.cancel(); + g_ExecutedAtCancellation = g_TaskCount; + ASSERT ( tg.is_canceling(), "No cancellation reported" ); + tg.wait(); + driver.Finish(); +} + +#if TBB_USE_EXCEPTIONS +template<typename task_group_type> +void TestExceptionHandling1 () { + ResetGlobals( true, false ); + task_group_type tg; + for( unsigned i = 0; i < NUM_GROUPS; ++i ) + // TBB version does not require taking function address + tg.run( &LaunchChildrenWithFunctor<task_group_type> ); + try { + tg.wait(); + } catch ( ... ) { + ASSERT( false, "Unexpected exception" ); + } + ASSERT( g_ExceptionCount <= NUM_GROUPS, "Too many exceptions from the child groups. The test is broken" ); + ASSERT( g_ExceptionCount == NUM_GROUPS, "Not all child groups threw the exception" ); +} + +template<typename task_group_type> +void TestExceptionHandling2 () { + ResetGlobals( true, true ); + task_group_type tg; + bool exceptionCaught = false; + for( unsigned i = 0; i < NUM_GROUPS; ++i ) + // TBB version does not require taking function address + tg.run( &LaunchChildrenWithFunctor<task_group_type> ); + try { + tg.wait(); + } catch ( TestException& e ) { + ASSERT( e.what(), "Empty what() string" ); + ASSERT( __TBB_EXCEPTION_TYPE_INFO_BROKEN || strcmp(e.what(), EXCEPTION_DESCR2) == 0, "Unknown exception" ); + ASSERT ( !tg.is_canceling(), "wait() has not reset cancellation state" ); + exceptionCaught = true; + } CATCH_ANY(); + ASSERT( exceptionCaught, "No exception thrown from the root task group" ); + ASSERT( g_ExceptionCount >= SKIP_GROUPS, "Too few exceptions from the child groups. The test is broken" ); + ASSERT( g_ExceptionCount <= NUM_GROUPS - SKIP_GROUPS, "Too many exceptions from the child groups. The test is broken" ); + ASSERT( g_ExceptionCount < NUM_GROUPS - SKIP_GROUPS, "None of the child groups was cancelled" ); +} + +#if defined(_MSC_VER) + #pragma warning (disable: 4127) +#endif + +template<typename task_group_type, bool Throw> +void TestMissingWait () { + bool exception_occurred = false, + unexpected_exception = false; + LaunchChildrenWithTaskHandleDriver<task_group_type> driver; + try { + task_group_type tg; + driver.Launch( tg ); + if ( Throw ) + throw int(); // Initiate stack unwinding + } + catch ( const Concurrency::missing_wait& e ) { + ASSERT( e.what(), "Error message is absent" ); + exception_occurred = true; + unexpected_exception = Throw; + } + catch ( int ) { + exception_occurred = true; + unexpected_exception = !Throw; + } + catch ( ... ) { + exception_occurred = unexpected_exception = true; + } + ASSERT( exception_occurred, NULL ); + ASSERT( !unexpected_exception, NULL ); + driver.Finish(); +} +#endif /* TBB_USE_EXCEPTIONS */ + +template<typename task_group_type> +void RunCancellationAndExceptionHandlingTests() { + TestManualCancellationWithFunctor <Concurrency::task_group>(); + TestManualCancellationWithTaskHandle<Concurrency::task_group>(); +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + TestExceptionHandling1<Concurrency::task_group>(); + TestExceptionHandling2<Concurrency::task_group>(); + + TestMissingWait<Concurrency::task_group, true>(); +#if !(__TBB_THROW_FROM_DTOR_BROKEN || __TBB_STD_UNCAUGHT_EXCEPTION_BROKEN) + TestMissingWait<Concurrency::task_group, false>(); +#else + REPORT("Known issue: TestMissingWait<task_group_type, false>() is skipped.\n"); +#endif +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ +} + +template<> void RunCancellationAndExceptionHandlingTests<Concurrency::structured_task_group>() { + TestManualCancellationWithTaskHandle<Concurrency::structured_task_group>(); +#if TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + TestMissingWait<Concurrency::structured_task_group, true>(); +#if !(__TBB_THROW_FROM_DTOR_BROKEN || __TBB_STD_UNCAUGHT_EXCEPTION_BROKEN) + TestMissingWait<Concurrency::structured_task_group, false>(); +#else + REPORT("Known issue: TestMissingWait<task_group_type, false>() is skipped.\n"); +#endif +#endif /* TBB_USE_EXCEPTIONS && !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN */ +} + + + +void EmptyFunction () {} + +void TestStructuredWait () { + Concurrency::structured_task_group sg; + handle_type h(EmptyFunction); + sg.run(h); + sg.wait(); + handle_type h2(EmptyFunction); + sg.run(h2); + sg.wait(); +} + +struct TestFunctor { + void operator()() { ASSERT( false, "Non-const operator called" ); } + void operator()() const { /* library requires this overload only */ } +}; + +template<typename task_group_type> +void TestConstantFunctorRequirement() { + task_group_type g; + TestFunctor tf; + g.run( tf ); g.wait(); + g.run_and_wait( tf ); +} + + + +//------------------------------------------------------------------------ +#if __TBB_CPP11_RVALUE_REF_PRESENT +namespace TestMoveSemanticsNS { + struct TestFunctor { + void operator()() const {}; + }; + + struct MoveOnlyFunctor : MoveOnly, TestFunctor { + MoveOnlyFunctor() : MoveOnly() {}; + MoveOnlyFunctor(MoveOnlyFunctor&& other) : MoveOnly(std::move(other)) {}; + }; + + struct MovePreferableFunctor : Movable, TestFunctor { + MovePreferableFunctor() : Movable() {}; + MovePreferableFunctor(MovePreferableFunctor&& other) : Movable(std::move(other)) {}; + MovePreferableFunctor(const MovePreferableFunctor& other) : Movable(other) {}; + }; + + struct NoMoveNoCopyFunctor : NoCopy, TestFunctor { + NoMoveNoCopyFunctor() : NoCopy() {}; + // mv ctor is not allowed as cp ctor from parent NoCopy + private: + NoMoveNoCopyFunctor(NoMoveNoCopyFunctor&&); + }; + + template<typename task_group_type> + void TestFunctorsWithinTaskHandles() { + // working with task_handle rvalues is not supported in task_group + + task_group_type tg; + MovePreferableFunctor mpf; + typedef tbb::task_handle<MoveOnlyFunctor> th_mv_only_type; + typedef tbb::task_handle<MovePreferableFunctor> th_mv_pref_type; + + th_mv_only_type th_mv_only = th_mv_only_type(MoveOnlyFunctor()); + tg.run_and_wait(th_mv_only); + + th_mv_only_type th_mv_only1 = th_mv_only_type(MoveOnlyFunctor()); + tg.run(th_mv_only1); + tg.wait(); + + th_mv_pref_type th_mv_pref = th_mv_pref_type(mpf); + tg.run_and_wait(th_mv_pref); + ASSERT(mpf.alive, "object was moved when was passed by lval"); + mpf.Reset(); + + th_mv_pref_type th_mv_pref1 = th_mv_pref_type(std::move(mpf)); + tg.run_and_wait(th_mv_pref1); + ASSERT(!mpf.alive, "object was copied when was passed by rval"); + mpf.Reset(); + + th_mv_pref_type th_mv_pref2 = th_mv_pref_type(mpf); + tg.run(th_mv_pref2); + tg.wait(); + ASSERT(mpf.alive, "object was moved when was passed by lval"); + mpf.Reset(); + + th_mv_pref_type th_mv_pref3 = th_mv_pref_type(std::move(mpf)); + tg.run(th_mv_pref3); + tg.wait(); + ASSERT(!mpf.alive, "object was copied when was passed by rval"); + mpf.Reset(); + } + + template<typename task_group_type> + void TestBareFunctors() { + task_group_type tg; + MovePreferableFunctor mpf; + // run_and_wait() doesn't have any copies or moves of arguments inside the impl + tg.run_and_wait( NoMoveNoCopyFunctor() ); + + tg.run( MoveOnlyFunctor() ); + tg.wait(); + + tg.run( mpf ); + tg.wait(); + ASSERT(mpf.alive, "object was moved when was passed by lval"); + mpf.Reset(); + + tg.run( std::move(mpf) ); + tg.wait(); + ASSERT(!mpf.alive, "object was copied when was passed by rval"); + mpf.Reset(); + } + + void TestMakeTask() { + MovePreferableFunctor mpf; + + tbb::make_task( MoveOnly() ); + + tbb::make_task( mpf ); + ASSERT(mpf.alive, "object was moved when was passed by lval"); + mpf.Reset(); + + tbb::make_task( std::move(mpf) ); + ASSERT(!mpf.alive, "object was copied when was passed by rval"); + mpf.Reset(); + } +} +#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */ + +template<typename task_group_type> +void TestMoveSemantics() { +#if __TBB_CPP11_RVALUE_REF_PRESENT + TestMoveSemanticsNS::TestBareFunctors<task_group_type>(); + TestMoveSemanticsNS::TestFunctorsWithinTaskHandles<task_group_type>(); + TestMoveSemanticsNS::TestMakeTask(); +#else + REPORT("Known issue: move support tests are skipped.\n"); +#endif +} +//------------------------------------------------------------------------ + + +#if TBBTEST_USE_TBB && TBB_PREVIEW_ISOLATED_TASK_GROUP +namespace TestIsolationNS { + class DummyFunctor { + public: + DummyFunctor() {} + void operator()() const { + for ( volatile int j = 0; j < 10; ++j ) {} + } + }; + + template<typename task_group_type> + class ParForBody { + task_group_type& m_tg; + tbb::atomic<bool>& m_preserved; + tbb::enumerable_thread_specific<int>& m_ets; + public: + ParForBody( + task_group_type& tg, + tbb::atomic<bool>& preserved, + tbb::enumerable_thread_specific<int>& ets + ) : m_tg(tg), m_preserved(preserved), m_ets(ets) {} + + void operator()(int) const { + if (++m_ets.local() > 1) m_preserved = false; + + for (int i = 0; i < 1000; ++i) + m_tg.run(DummyFunctor()); + m_tg.wait(); + m_tg.run_and_wait(DummyFunctor()); + + --m_ets.local(); + } + }; + + template<typename task_group_type> + void CheckIsolation(bool isolation_is_expected) { + task_group_type tg; + tbb::atomic<bool> isolation_is_preserved; + isolation_is_preserved = true; + tbb::enumerable_thread_specific<int> ets(0); + + tbb::parallel_for(0, 100, ParForBody<task_group_type>(tg, isolation_is_preserved, ets)); + + ASSERT( + isolation_is_expected == isolation_is_preserved, + "Actual and expected isolation-related behaviours are different" + ); + } + + // Should be called only when > 1 thread is used, because otherwise isolation is guaranteed to take place + void TestIsolation() { + CheckIsolation<tbb::task_group>(false); + CheckIsolation<tbb::isolated_task_group>(true); + } +} +#endif + + +int TestMain () { + REMARK ("Testing %s task_group functionality\n", TBBTEST_USE_TBB ? "TBB" : "PPL"); + for( int p=MinThread; p<=MaxThread; ++p ) { + g_MaxConcurrency = p; +#if TBBTEST_USE_TBB + tbb::task_scheduler_init init(p); +#else + Concurrency::SchedulerPolicy sp( 4, + Concurrency::SchedulerKind, Concurrency::ThreadScheduler, + Concurrency::MinConcurrency, 1, + Concurrency::MaxConcurrency, p, + Concurrency::TargetOversubscriptionFactor, 1); + Concurrency::Scheduler *s = Concurrency::Scheduler::Create( sp ); +#endif /* !TBBTEST_USE_TBB */ + if ( p > 1 ) + TestThreadSafety<Concurrency::task_group>(); + + RunFibonacciTests<Concurrency::task_group>(); + RunFibonacciTests<Concurrency::structured_task_group>(); + + RunCancellationAndExceptionHandlingTests<Concurrency::task_group>(); + RunCancellationAndExceptionHandlingTests<Concurrency::structured_task_group>(); + +#if TBBTEST_USE_TBB && TBB_PREVIEW_ISOLATED_TASK_GROUP + if ( p > 1 ) { + TestThreadSafety<tbb::isolated_task_group>(); + TestIsolationNS::TestIsolation(); + } + RunFibonacciTests<tbb::isolated_task_group>(); + RunCancellationAndExceptionHandlingTests<tbb::isolated_task_group>(); + TestConstantFunctorRequirement<tbb::isolated_task_group>(); + TestMoveSemantics<tbb::isolated_task_group>(); +#else + REPORT ("Known issue: tests for tbb::isolated_task_group are skipped.\n"); +#endif + +#if !TBBTEST_USE_TBB + s->Release(); +#endif + } + TestStructuredWait(); + TestConstantFunctorRequirement<Concurrency::task_group>(); + TestMoveSemantics<Concurrency::task_group>(); +#if __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + REPORT("Known issue: exception handling tests are skipped.\n"); +#endif + return Harness::Done; +} + +#else /* !__TBB_TASK_GROUP_CONTEXT */ + +#include "harness.h" + +int TestMain () { + return Harness::Skipped; +} + +#endif /* !__TBB_TASK_GROUP_CONTEXT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_leaks.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_leaks.cpp new file mode 100644 index 00000000..dda2ae13 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_leaks.cpp @@ -0,0 +1,293 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* The test uses "single produces multiple consumers" (SPMC )pattern to check + if the memory of the tasks stolen by consumer threads is returned to the + producer thread and is reused. + + The test consists of a series of iterations, which execute a task tree. + the test fails is the memory consumption is not stabilized during some + number of iterations. + + After the memory consumption stabilized the memory state is perturbed by + switching producer thread, and the check is repeated. +*/ + +#define HARNESS_DEFAULT_MIN_THREADS -1 + +#define __TBB_COUNT_TASK_NODES 1 +#include "harness_inject_scheduler.h" + +#include "tbb/atomic.h" +#include "harness_assert.h" +#include <cstdlib> + + +// Test configuration parameters + +//! Maximal number of test iterations +const int MaxIterations = 600; +//! Number of iterations during which the memory consumption must stabilize +const int AsymptoticRange = 100; +//! Number of times the memory state is perturbed to repeat the check +const int NumProducerSwitches = 2; +//! Number of iterations after which the success of producer switch is checked +const int ProducerCheckTimeout = 10; +//! Number of initial iteration used to collect statistics to be used in later checks +const int InitialStatsIterations = 20; +//! Inner iterations of RunTaskGenerators() +const int TaskGeneratorsIterations = TBB_USE_DEBUG ? 30 : 100; + +tbb::atomic<int> Count; +tbb::atomic<tbb::task*> Exchanger; +tbb::internal::scheduler* Producer; + +#include "tbb/task_scheduler_init.h" + +#include "harness.h" + +using namespace tbb; +using namespace tbb::internal; + +class ChangeProducer: public tbb::task { +public: + tbb::task* execute() __TBB_override { + if( is_stolen_task() ) { + Producer = internal::governor::local_scheduler(); + } + return NULL; + } +}; + +class TaskGenerator: public tbb::task { + const int my_child_count; + int my_depth; +public: + TaskGenerator(int child_count, int d) : my_child_count(child_count), my_depth(d) { + ASSERT(my_child_count>1, "The TaskGenerator should produce at least two children"); + } + tbb::task* execute() __TBB_override { + if( my_depth>0 ) { + int child_count = my_child_count; + scheduler* my_sched = internal::governor::local_scheduler(); + tbb::task& c = *new( allocate_continuation() ) tbb::empty_task; + c.set_ref_count( child_count ); + recycle_as_child_of(c); + --child_count; + if( Producer==my_sched ) { + // produce a task and put it into Exchanger + tbb::task* t = new( c.allocate_child() ) tbb::empty_task; + --child_count; + t = Exchanger.fetch_and_store(t); + if( t ) spawn(*t); + } else { + tbb::task* t = Exchanger.fetch_and_store(NULL); + if( t ) spawn(*t); + } + while( child_count ) { + tbb::task* t = new( c.allocate_child() ) TaskGenerator(my_child_count, my_depth-1); + if( my_depth >4 ) enqueue(*t); + else spawn(*t); + --child_count; + } + --my_depth; + return this; + } else { + tbb::task* t = Exchanger.fetch_and_store(NULL); + if( t ) spawn(*t); + return NULL; + } + } +}; + +#include "harness_memory.h" +#if _MSC_VER==1500 && !defined(__INTEL_COMPILER) + // VS2008/VC9 seems to have an issue + #pragma warning( push ) + #pragma warning( disable: 4985 ) +#endif +#include <math.h> +#if _MSC_VER==1500 && !defined(__INTEL_COMPILER) + #pragma warning( pop ) +#endif + +void RunTaskGenerators( bool switchProducer = false, bool checkProducer = false ) { + if( switchProducer ) + Producer = NULL; + tbb::task* dummy_root = new( tbb::task::allocate_root() ) tbb::empty_task; + dummy_root->set_ref_count( 2 ); + // If no producer, start elections; some worker will take the role + if( Producer ) + tbb::task::spawn( *new( dummy_root->allocate_child() ) tbb::empty_task ); + else + tbb::task::spawn( *new( dummy_root->allocate_child() ) ChangeProducer ); + if( checkProducer && !Producer ) + REPORT("Warning: producer has not changed after 10 attempts; running on a single core?\n"); + for( int j=0; j<TaskGeneratorsIterations; ++j ) { + if( j&1 ) { + tbb::task& t = *new( tbb::task::allocate_root() ) TaskGenerator(/*child_count=*/4, /*depth=*/6); + tbb::task::spawn_root_and_wait(t); + } else { + tbb::task& t = *new (tbb::task::allocate_additional_child_of(*dummy_root)) + TaskGenerator(/*child_count=*/4, /*depth=*/6); + tbb::task::enqueue(t); + } + } + dummy_root->wait_for_all(); + tbb::task::destroy( *dummy_root ); +} + +#include "tbb/parallel_for.h" +#include "tbb/task_arena.h" +tbb::task_arena* BigArena; + +struct AffParFor { + void operator()() const { + for (int i = 0; i < 10; ++i) + tbb::parallel_for(0, BigArena->max_concurrency(), AffParFor(), tbb::static_partitioner()); + } + void operator()(int) const {} +}; + +void RunAffinityTaskGenerator() { + BigArena->execute(AffParFor()); +} + +class TaskList: public tbb::task { + const int my_num_childs; +public: + TaskList(const int num_childs) : my_num_childs(num_childs) {} + tbb::task* execute() __TBB_override { + tbb::task_list list; + for (int i=0; i<my_num_childs; ++i) + { + list.push_back( *new( allocate_child() ) tbb::empty_task ); + } + set_ref_count(my_num_childs+1); + spawn(list); + + wait_for_all(); + return 0; + } +}; + +void RunTaskListGenerator() +{ + const int max_num_childs = 10000; + int num_childs=3; + + while ( num_childs < max_num_childs ) + { + tbb::task& root = *new( tbb::task::allocate_root() ) TaskList(num_childs); + + tbb::task::spawn_root_and_wait(root); + + num_childs = 3 * num_childs; + } +} + +//! Tests whether task scheduler allows thieves to hoard task objects. +/** The test takes a while to run, so we run it only with the default + number of threads. */ +void TestTaskReclamation() { + REMARK("testing task reclamation\n"); + + size_t initial_amount_of_memory = 0; + double task_count_sum = 0; + double task_count_sum_square = 0; + double average, sigma; + + tbb::task_scheduler_init init (MinThread); + REMARK("Starting with %d threads\n", MinThread); + + // Reserve multiple slots for masters to have slots that are never occupied. + // "+1" to avoid warning about maximum number of threads. + int num_threads = tbb::task_scheduler_init::default_num_threads() < 8 ? tbb::task_scheduler_init::default_num_threads() : 8; + BigArena = new tbb::task_arena(2*num_threads, num_threads+1); + + // For now, the master will produce "additional" tasks; later a worker will replace it; + Producer = internal::governor::local_scheduler(); + int N = InitialStatsIterations; + // First N iterations fill internal buffers and collect initial statistics + for( int i=0; i<N; ++i ) { + // First N iterations fill internal buffers and collect initial statistics + RunTaskGenerators(); + RunTaskListGenerator(); + RunAffinityTaskGenerator(); + + size_t m = GetMemoryUsage(); + if( m-initial_amount_of_memory > 0) + initial_amount_of_memory = m; + + intptr_t n = internal::governor::local_scheduler()->get_task_node_count( /*count_arena_workers=*/true ); + task_count_sum += n; + task_count_sum_square += n*n; + + REMARK( "Consumed %ld bytes and %ld objects (iteration=%d)\n", long(m), long(n), i ); + } + // Calculate statistical values + average = task_count_sum / N; + sigma = sqrt( (task_count_sum_square - task_count_sum*task_count_sum/N)/N ); + REMARK("Average task count: %g, sigma: %g, sum: %g, square sum:%g \n", average, sigma, task_count_sum, task_count_sum_square); + + int last_error_iteration = 0, + producer_switch_iteration = 0, + producer_switches = 0; + bool switchProducer = false, + checkProducer = false; + for( int i=0; i < MaxIterations; ++i ) { + // These iterations check for excessive memory use and unreasonable task count + RunTaskGenerators( switchProducer, checkProducer ); + RunTaskListGenerator(); + RunAffinityTaskGenerator(); + + intptr_t n = internal::governor::local_scheduler()->get_task_node_count( /*count_arena_workers=*/true ); + size_t m = GetMemoryUsage(); + + if( (m-initial_amount_of_memory > 0) && (n > average+4*sigma) ) { + // Use 4*sigma interval (for normal distribution, 3*sigma contains ~99% of values). + REMARK( "Warning: possible leak of up to %ld bytes; currently %ld cached task objects (iteration=%d)\n", + static_cast<unsigned long>(m-initial_amount_of_memory), long(n), i ); + last_error_iteration = i; + initial_amount_of_memory = m; + } else { + REMARK( "Consumed %ld bytes and %ld objects (iteration=%d)\n", long(m), long(n), i ); + } + if ( i == last_error_iteration + AsymptoticRange ) { + if ( producer_switches++ == NumProducerSwitches ) + break; + else { + last_error_iteration = producer_switch_iteration = i; + switchProducer = true; + } + } + else { + switchProducer = false; + checkProducer = producer_switch_iteration && (i == producer_switch_iteration + ProducerCheckTimeout); + } + } + ASSERT( last_error_iteration < MaxIterations - AsymptoticRange, "The amount of allocated tasks keeps growing. Leak is possible." ); + delete BigArena; +} + +int TestMain () { + if( !GetMemoryUsage() ) { + REMARK("GetMemoryUsage is not implemented for this platform\n"); + return Harness::Skipped; + } + TestTaskReclamation(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_priority.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_priority.cpp new file mode 100644 index 00000000..557cb45f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_priority.cpp @@ -0,0 +1,667 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" +#include "harness.h" + +#if __TBB_GCC_STRICT_ALIASING_BROKEN + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + +// TODO: This test could work with and without priorities, but after disabling task priorities +// it doesn`t work - investigate +#if __TBB_TASK_GROUP_CONTEXT && __TBB_TASK_PRIORITY + +#include "tbb/task.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/atomic.h" +#include <cstdlib> + +#if _MSC_VER && __TBB_NO_IMPLICIT_LINKAGE +// plays around __TBB_NO_IMPLICIT_LINKAGE. __TBB_LIB_NAME should be defined (in makefiles) + #pragma comment(lib, __TBB_STRING(__TBB_LIB_NAME)) +#endif + +const int NumIterations = 100; +const int NumLeafTasks = 2; +int MinBaseDepth = 8; +int MaxBaseDepth = 10; +int BaseDepth = 0; + +const int DesiredNumThreads = 12; + +const int NumTests = 8; +int TestSwitchBetweenMastersRepeats = 4; + +int g_NumMasters = 0; +volatile intptr_t *g_LeavesExecuted = NULL; + +int g_TestFailures[NumTests]; +int g_CurConfig = 0; + +int P = 0; + +#if !__TBB_TASK_PRIORITY +namespace tbb { + enum priority_t { + priority_low = 0, + priority_normal = 1, + priority_high = 2 + }; +} +#endif /* __TBB_TASK_PRIORITY */ + +tbb::priority_t Low, + High; +int PreemptionActivatorId = 1; + +enum Options { + NoPriorities = 0, + TestPreemption = 1, + Flog = 2, + FlogEncloser = Flog | 4 +}; + +const char *PriorityName(tbb::priority_t p) { + if( p == tbb::priority_high ) return "high"; + if( p == tbb::priority_normal ) return "normal"; + if( p == tbb::priority_low ) return "low"; + return "bad"; +} + +void PrepareGlobals ( int numMasters ) { + ASSERT( !g_NumMasters && !g_LeavesExecuted, NULL ); + g_NumMasters = numMasters; + if ( !g_LeavesExecuted ) + g_LeavesExecuted = new intptr_t[numMasters]; + g_CurConfig = 0; + memset( const_cast<intptr_t*>(g_LeavesExecuted), 0, sizeof(intptr_t) * numMasters ); + memset( g_TestFailures, 0, sizeof(int) * NumTests ); +} + +void ClearGlobals () { + ASSERT( g_LeavesExecuted, NULL ); + delete [] g_LeavesExecuted; + g_LeavesExecuted = NULL; + g_NumMasters = 0; + REMARK("\r \r"); +} + +class LeafTask : public tbb::task { + int m_tid; + uintptr_t m_opts; + + tbb::task* execute () __TBB_override { + volatile int anchor = 0; + for ( int i = 0; i < NumIterations; ++i ) + anchor += i; + __TBB_FetchAndAddW(g_LeavesExecuted + m_tid, 1); +#if __TBB_TASK_PRIORITY + ASSERT( !m_opts || (m_opts & Flog) || (!(m_opts & TestPreemption) ^ (m_tid == PreemptionActivatorId)), NULL ); + if ( (m_opts & TestPreemption) && g_LeavesExecuted[0] > P && group_priority() == tbb::priority_normal ) { + ASSERT( m_tid == PreemptionActivatorId, NULL ); + ASSERT( (PreemptionActivatorId == 1 ? High > tbb::priority_normal : Low < tbb::priority_normal), NULL ); + set_group_priority( PreemptionActivatorId == 1 ? High : Low ); + } +#endif /* __TBB_TASK_PRIORITY */ + return NULL; + } +public: + LeafTask ( int tid, uintptr_t opts ) : m_tid(tid), m_opts(opts) { + ASSERT( tid < g_NumMasters, NULL ); + } +}; + +template<class NodeType> +class NodeTask : public tbb::task { +protected: + int m_tid; + int m_depth; + uintptr_t m_opts; + task *m_root; + + void SpawnChildren ( task* parent_node ) { + ASSERT( m_depth > 0, NULL ); + if ( g_LeavesExecuted[m_tid] % (100 / m_depth) == 0 ) { + if ( m_opts & Flog ) { +#if __TBB_TASK_PRIORITY + task *r = m_opts & FlogEncloser ? this : m_root; + tbb::priority_t p = r->group_priority(); + r->set_group_priority( p == Low ? High : Low ); +#endif /* __TBB_TASK_PRIORITY */ + } + else + __TBB_Yield(); + } + parent_node->set_ref_count(NumLeafTasks + 1); + --m_depth; + for ( int i = 0; i < NumLeafTasks; ++i ) { + task *t = m_depth ? (task*) new(parent_node->allocate_child()) NodeType(m_tid, m_depth, m_opts, m_root) + : (task*) new(parent_node->allocate_child()) LeafTask(m_tid, m_opts); + task::spawn(*t); + } + } + +public: + NodeTask ( int tid, int _depth, uintptr_t opts, task *r = NULL ) + : m_tid(tid), m_depth(_depth), m_opts(opts), m_root(r) + {} +}; + +class NestedGroupNodeTask : public NodeTask<NestedGroupNodeTask> { + task* execute () __TBB_override { + tbb::task_group_context ctx; // Use bound context + tbb::empty_task &r = *new( task::allocate_root(ctx) ) tbb::empty_task; + SpawnChildren(&r); + r.wait_for_all(); + task::destroy(r); + return NULL; + } +public: + NestedGroupNodeTask ( int tid, int _depth, uintptr_t opts, task *r = NULL ) + : NodeTask<NestedGroupNodeTask>(tid, _depth, opts, r) + {} +}; + +class BlockingNodeTask : public NodeTask<BlockingNodeTask> { + task* execute () __TBB_override { + SpawnChildren(this); + wait_for_all(); + return NULL; + } +public: + BlockingNodeTask ( int tid, int _depth, uintptr_t opts, task *r = NULL ) + : NodeTask<BlockingNodeTask>(tid, _depth, opts, r) {} +}; + +class NonblockingNodeTask : public NodeTask<NonblockingNodeTask> { + task* execute () __TBB_override { + if ( m_depth < 0 ) + return NULL; // I'm just a continuation now + recycle_as_safe_continuation(); + SpawnChildren(this); + m_depth = -1; + return NULL; + } +public: + NonblockingNodeTask ( int tid, int _depth, uintptr_t opts, task *r = NULL ) + : NodeTask<NonblockingNodeTask>(tid, _depth, opts, r) + {} +}; + +template<class NodeType> +class MasterBodyBase : NoAssign, Harness::NoAfterlife { +protected: + uintptr_t m_opts; + +public: + void RunTaskForest ( int id ) const { + ASSERT( id < g_NumMasters, NULL ); + g_LeavesExecuted[id] = 0; + int d = BaseDepth + id; + tbb::task_scheduler_init init(P-1); + tbb::task_group_context ctx (tbb::task_group_context::isolated); + tbb::empty_task &r = *new( tbb::task::allocate_root(ctx) ) tbb::empty_task; + const int R = 4; + r.set_ref_count( R * P + 1 ); + // Only PreemptionActivator thread changes its task tree priority in preemption test mode + const uintptr_t opts = (id == PreemptionActivatorId) ? m_opts : (m_opts & ~(uintptr_t)TestPreemption); + for ( int i = 0; i < R; ++i ) { + for ( int j = 1; j < P; ++j ) + r.spawn( *new(r.allocate_child()) NodeType(id, MinBaseDepth + id, opts, &r) ); + r.spawn( *new(r.allocate_child()) NodeType(id, d, opts, &r) ); + } + int count = 1; + intptr_t lastExecuted = 0; + while ( r.ref_count() > 1 ) { + // Give workers time to make some progress. + for ( int i = 0; i < 10 * count; ++i ) + __TBB_Yield(); +#if __TBB_TASK_PRIORITY + if ( lastExecuted == g_LeavesExecuted[id] ) { + // No progress. Likely all workers left to higher priority arena, + // and then returned to RML. Request workers back from RML. + tbb::task::enqueue( *new(tbb::task::allocate_root() ) tbb::empty_task, id == 0 ? Low : High ); + Harness::Sleep(count); +#if __TBB_ipf + // Increased sleep periods are required on systems with unfair hyperthreading (Itanium(R) 2 processor) + count += 10; +#endif + } + else { + count = 1; + lastExecuted = g_LeavesExecuted[id]; + } +#else /* !__TBB_TASK_PRIORITY */ + (void)lastExecuted; + tbb::task::enqueue( *new(tbb::task::allocate_root() ) tbb::empty_task ); +#endif /* !__TBB_TASK_PRIORITY */ + } + ASSERT( g_LeavesExecuted[id] == R * ((1 << d) + ((P - 1) * (1 << (MinBaseDepth + id)))), NULL ); + g_LeavesExecuted[id] = -1; + tbb::task::destroy(r); + } + + MasterBodyBase ( uintptr_t opts ) : m_opts(opts) {} +}; + +template<class NodeType> +class MasterBody : public MasterBodyBase<NodeType> { + int m_testIndex; +public: + void operator() ( int id ) const { + this->RunTaskForest(id); + if ( this->m_opts & Flog ) + return; + if ( this->m_opts & TestPreemption ) { + if ( id == 1 && g_LeavesExecuted[0] == -1 ) { + //REMARK( "Warning: Low priority master finished too early [depth %d]\n", Depth ); + ++g_TestFailures[m_testIndex]; + } + } + else { + if ( id == 0 && g_LeavesExecuted[1] == -1 ) { + //REMARK( "Warning: Faster master takes too long [depth %d]\n", Depth ); + ++g_TestFailures[m_testIndex]; + } + } + } + + MasterBody ( int idx, uintptr_t opts ) : MasterBodyBase<NodeType>(opts), m_testIndex(idx) {} +}; + +template<class NodeType> +void RunPrioritySwitchBetweenTwoMasters ( int idx, uintptr_t opts ) { + ASSERT( idx < NumTests, NULL ); + REMARK( "Config %d: idx=%i, opts=%u\r", ++g_CurConfig, idx, (unsigned)opts ); + NativeParallelFor ( 2, MasterBody<NodeType>(idx, opts) ); + Harness::Sleep(50); +} + +void TestPrioritySwitchBetweenTwoMasters () { + if ( P > DesiredNumThreads ) { + REPORT_ONCE( "Known issue: TestPrioritySwitchBetweenTwoMasters is skipped for big number of threads\n" ); + return; + } + tbb::task_scheduler_init init; // keeps the market alive to reduce the amount of TBB warnings + REMARK( "Stress tests: %s / %s \n", Low == tbb::priority_low ? "Low" : "Normal", High == tbb::priority_normal ? "Normal" : "High" ); + PrepareGlobals( 2 ); + for ( int i = 0; i < TestSwitchBetweenMastersRepeats; ++i ) { + for ( BaseDepth = MinBaseDepth; BaseDepth <= MaxBaseDepth; ++BaseDepth ) { + RunPrioritySwitchBetweenTwoMasters<BlockingNodeTask>( 0, NoPriorities ); + RunPrioritySwitchBetweenTwoMasters<BlockingNodeTask>( 1, TestPreemption ); + RunPrioritySwitchBetweenTwoMasters<NonblockingNodeTask>( 2, NoPriorities ); + RunPrioritySwitchBetweenTwoMasters<NonblockingNodeTask>( 3, TestPreemption ); + if ( i == 0 ) { + RunPrioritySwitchBetweenTwoMasters<BlockingNodeTask>( 4, Flog ); + RunPrioritySwitchBetweenTwoMasters<NonblockingNodeTask>( 5, Flog ); + RunPrioritySwitchBetweenTwoMasters<NestedGroupNodeTask>( 6, Flog ); + RunPrioritySwitchBetweenTwoMasters<NestedGroupNodeTask>( 7, FlogEncloser ); + } + } + } +#if __TBB_TASK_PRIORITY + const int NumRuns = TestSwitchBetweenMastersRepeats * (MaxBaseDepth - MinBaseDepth + 1); + for ( int i = 0; i < NumTests; ++i ) { + if ( g_TestFailures[i] ) + REMARK( "Test %d: %d failures in %d runs\n", i, g_TestFailures[i], NumRuns ); + if ( g_TestFailures[i] * 100 / NumRuns > 50 ) { + if ( i == 1 ) + REPORT_ONCE( "Known issue: priority effect is limited in case of blocking-style nesting\n" ); + else + REPORT( "Warning: test %d misbehaved too often (%d out of %d)\n", i, g_TestFailures[i], NumRuns ); + } + } +#endif /* __TBB_TASK_PRIORITY */ + ClearGlobals(); +} + +class SingleChildRootTask : public tbb::task { + tbb::task* execute () __TBB_override { + set_ref_count(2); + spawn ( *new(allocate_child()) tbb::empty_task ); + wait_for_all(); + return NULL; + } +}; + +int TestSimplePriorityOps ( tbb::priority_t prio ) { + tbb::task_scheduler_init init; + tbb::task_group_context ctx; +#if __TBB_TASK_PRIORITY + ctx.set_priority( prio ); +#else /* !__TBB_TASK_PRIORITY */ + (void)prio; +#endif /* !__TBB_TASK_PRIORITY */ + tbb::task *r = new( tbb::task::allocate_root(ctx) ) tbb::empty_task; + r->set_ref_count(2); + r->spawn ( *new(r->allocate_child()) tbb::empty_task ); + REMARK( "TestSimplePriorityOps: waiting for a child\n" ); + r->wait_for_all(); + ASSERT( !r->ref_count(), NULL ); + REMARK( "TestLowPriority: executing an empty root\n" ); + tbb::task::spawn_root_and_wait(*r); + r = new( tbb::task::allocate_root(ctx) ) SingleChildRootTask; + REMARK( "TestLowPriority: executing a root with a single child\n" ); + tbb::task::spawn_root_and_wait(*r); + return 0; +} + +#include "tbb/parallel_for.h" + +void EmulateWork( int ) { + for ( int i = 0; i < 1000; ++i ) + __TBB_Yield(); +} + +class PeriodicActivitiesBody { +public: + static const int parallelIters[2]; + static const int seqIters[2]; + static int mode; + void operator() ( int id ) const { + tbb::task_group_context ctx; +#if __TBB_TASK_PRIORITY + ctx.set_priority( id ? High : Low ); +#else /* !__TBB_TASK_PRIORITY */ + (void)id; +#endif /* !__TBB_TASK_PRIORITY */ + for ( int i = 0; i < seqIters[mode]; ++i ) { + tbb::task_scheduler_init init; + tbb::parallel_for( 1, parallelIters[mode], &EmulateWork, ctx ); + } + } +}; + +const int PeriodicActivitiesBody::parallelIters[] = {10000, 100}; +const int PeriodicActivitiesBody::seqIters[] = {5, 2}; +int PeriodicActivitiesBody::mode = 0; + +void TestPeriodicConcurrentActivities () { + REMARK( "TestPeriodicConcurrentActivities: %s / %s \n", Low == tbb::priority_low ? "Low" : "Normal", High == tbb::priority_normal ? "Normal" : "High" ); + NativeParallelFor ( 2, PeriodicActivitiesBody() ); +} + +#include "harness_bad_expr.h" + +void TestPriorityAssertions () { +#if TRY_BAD_EXPR_ENABLED && __TBB_TASK_PRIORITY + REMARK( "TestPriorityAssertions\n" ); + tbb::task_scheduler_init init; // to avoid autoinit that'd affect subsequent tests + tbb::priority_t bad_low_priority = tbb::priority_t( tbb::priority_low - 1 ), + bad_high_priority = tbb::priority_t( tbb::priority_high + 1 ); + tbb::task_group_context ctx; + // Catch assertion failures + tbb::set_assertion_handler( AssertionFailureHandler ); + TRY_BAD_EXPR( ctx.set_priority( bad_low_priority ), "Invalid priority level value" ); + tbb::task &t = *new( tbb::task::allocate_root() ) tbb::empty_task; + TRY_BAD_EXPR( tbb::task::enqueue( t, bad_high_priority ), "Invalid priority level value" ); + // Restore normal assertion handling + tbb::set_assertion_handler( ReportError ); +#endif /* TRY_BAD_EXPR_ENABLED && __TBB_TASK_PRIORITY */ +} + +#if __TBB_TASK_PRIORITY + +tbb::atomic<tbb::priority_t> g_order; +tbb::atomic<bool> g_order_established; +tbb::atomic<int> g_num_tasks; +tbb::atomic<bool> g_all_tasks_enqueued; +int g_failures; +class OrderedTask : public tbb::task { + tbb::priority_t my_priority; +public: + OrderedTask(tbb::priority_t p) : my_priority(p) { + ++g_num_tasks; + } + tbb::task* execute() __TBB_override { + tbb::priority_t prev = g_order.fetch_and_store(my_priority); + if( my_priority != prev) { + REMARK("prev:%s --> new:%s\n", PriorityName(prev), PriorityName(my_priority)); + // TODO: improve the test for concurrent workers + if(!g_order_established) { + // initial transition path allowed low->[normal]->high + if(my_priority == tbb::priority_high) + g_order_established = true; + else ASSERT(my_priority == tbb::priority_normal && prev == tbb::priority_low, NULL); + } else { //transition path allowed high->normal->low + bool fail = prev==tbb::priority_high && my_priority!=tbb::priority_normal; // previous priority is high - bad order + fail |= prev==tbb::priority_normal && my_priority!=tbb::priority_low; // previous priority is normal - bad order + fail |= prev==tbb::priority_low; // transition from low priority but not during initialization + if ( fail ) { + if ( g_all_tasks_enqueued ) + REPORT_ONCE( "ERROR: Bad order: prev = %s, my_priority = %s\n", PriorityName( prev ), PriorityName( my_priority ) ); + ++g_failures; + } + } + } + EmulateWork(0); + --g_num_tasks; + return NULL; + } + static void start(int i) { + tbb::priority_t p = i%3==0? tbb::priority_low : (i%3==1? tbb::priority_normal : tbb::priority_high ); + OrderedTask &t = *new(tbb::task::allocate_root()) OrderedTask(p); + tbb::task::enqueue(t, p); + } +}; + +//Look for discussion of the issue at http://software.intel.com/en-us/forums/showthread.php?t=102159 +void TestEnqueueOrder () { + REMARK("Testing order of enqueued tasks\n"); + tbb::task_scheduler_init init(1); // to simplify transition checks only one extra worker for enqueue + g_order = tbb::priority_low; + g_order_established = false; + g_all_tasks_enqueued = false; + g_failures = 0; + for( int i = 0; i < 1000; i++) + OrderedTask::start(i); + if ( int curr_num_tasks = g_num_tasks ) { + // Sync with worker not to set g_all_tasks_enqueued too early. + while ( curr_num_tasks == g_num_tasks ) __TBB_Yield(); + } + g_all_tasks_enqueued = true; + while( g_order == tbb::priority_low && g_num_tasks>0 ) __TBB_Yield(); + while( g_order != tbb::priority_low && g_num_tasks>0 ) __TBB_Yield(); + // We cannot differentiate if this misbehavior is caused by the test or by the implementation. + // Howerever, we do not promise mandatory priorities so we can state that the misbehavior in less + // than 1% cases is our best effort. + ASSERT( g_failures < 5, "Too many failures" ); +} + +namespace test_propagation { + +// This test creates two binary trees of task_group_context objects. +// Indices in a binary tree have the following layout: +// [1]--> [2] -> [4],[5] +// \-> [3] -> [6],[7] +static const int first = 1, last = 7; +tbb::task_group_context* g_trees[2][/*last+1*/8]; +tbb::task_group_context* g_default_ctx; +tbb::atomic<int> g_barrier; +tbb::atomic<bool> is_finished; + +class TestSetPriorityTask : public tbb::task { + const int m_tree, m_i; +public: + TestSetPriorityTask(int t, int i) : m_tree(t), m_i(i) {} + tbb::task* execute() __TBB_override { + if( !m_i ) { // the first task creates two trees + g_default_ctx = group(); + for( int i = 0; i <= 1; ++i ) { + g_trees[i][1] = new tbb::task_group_context( tbb::task_group_context::isolated ); + tbb::task::spawn(*new(tbb::task::allocate_root(*g_trees[i][1])) TestSetPriorityTask(i, 1)); + } + } + else if( m_i <= last/2 ) { // is divisible + for( int i = 0; i <= 1; ++i ) { + const int index = 2*m_i + i; + g_trees[m_tree][index] = new tbb::task_group_context ( tbb::task_group_context::bound ); + tbb::task::spawn(*new(tbb::task::allocate_root(*g_trees[m_tree][index])) TestSetPriorityTask(m_tree, index)); + } + } + --g_barrier; + //REMARK("Task %i executing\n", m_i); + while (!is_finished) __TBB_Yield(); + change_group(*g_default_ctx); // avoid races with destruction of custom contexts + --g_barrier; + return NULL; + } +}; + +// Tests task_group_context state propagation, also for cancellation. +void TestSetPriority() { + REMARK("Testing set_priority() with existing forest\n"); + const int workers = last*2+1; // +1 is worker thread executing the first task + const int max_workers = 4*tbb::task_scheduler_init::default_num_threads(); + if ( workers+1 > max_workers ) { + REPORT( "Known issue: TestSetPriority requires %d threads but due to 4P hard limit the maximum number of threads is %d\n", workers+1, max_workers ); + return; + } + tbb::task_scheduler_init init(workers+1); // +1 is master thread + g_barrier = workers; + is_finished = false; + tbb::task::spawn(*new(tbb::task::allocate_root()) TestSetPriorityTask(0,0)); + while(g_barrier) __TBB_Yield(); + g_trees[0][2]->set_priority(tbb::priority_high); + g_trees[0][4]->set_priority(tbb::priority_normal); + g_trees[1][3]->set_priority(tbb::priority_high); // Regression test: it must not set priority_high to g_trees[0][4] + // - 1 2 3 4 5 6 7 + const int expected_priority[2][last+1] = {{0, 0, 1, 0, 0, 1, 0, 0}, + {0, 0, 0, 1, 0, 0, 1, 1}}; + for (int t = 0; t < 2; ++t) + for (int i = first; i <= last; ++i) { + REMARK("\r \rTask %i... ", i); + ASSERT(g_trees[t][i]->priority() == (expected_priority[t][i]? tbb::priority_high : tbb::priority_normal), NULL); + REMARK("OK"); + } + REMARK("\r \r"); + REMARK("Also testing cancel_group_execution()\n"); // cancellation shares propagation logic with set_priority() but there are also differences + g_trees[0][4]->cancel_group_execution(); + g_trees[0][5]->cancel_group_execution(); + g_trees[1][3]->cancel_group_execution(); + // - 1 2 3 4 5 6 7 + const int expected_cancellation[2][last+1] = {{0, 0, 0, 0, 1, 1, 0, 0}, + {0, 0, 0, 1, 0, 0, 1, 1}}; + for (int t = 0; t < 2; ++t) + for (int i = first; i <= last; ++i) { + REMARK("\r \rTask %i... ", i); + ASSERT( g_trees[t][i]->is_group_execution_cancelled() == (expected_cancellation[t][i]==1), NULL); + REMARK("OK"); + } + REMARK("\r \r"); + g_barrier = workers; + is_finished = true; + REMARK("waiting tasks to terminate\n"); + while(g_barrier) __TBB_Yield(); + for (int t = 0; t < 2; ++t) + for (int i = first; i <= last; ++i) + delete g_trees[t][i]; +} +}//namespace test_propagation + +struct OuterParFor { + void operator()(int) const { + tbb::affinity_partitioner ap; + tbb::task_group_context ctx; + ctx.set_priority(tbb::priority_high); + tbb::parallel_for(0, 100, Harness::DummyBody(1000), ap, ctx); + } +}; + +// Test priorities with affinity tasks. +void TestAffinityTasks() { + REMARK("Test priorities with affinity tasks\n"); + tbb::task_scheduler_init init; + tbb::affinity_partitioner ap; + for (int i = 0; i < 10; ++i) + tbb::parallel_for(0, 100, OuterParFor(), ap); +} + +namespace regression { +// This is a regression test for a bug with task_group_context used from a thread that created its local scheduler but not the implicit arena +class TestTGContext { +public: + void operator() (int) const { + tbb::task_group_context ctx; + ctx.cancel_group_execution(); // initializes the local weak scheduler on the thread + ctx.set_priority(tbb::priority_high); + } +}; + +void TestTGContextOnNewThread() { + REMARK("Testing a regression for a bug with task_group_context\n"); + TestTGContext body; + NativeParallelFor(1, body); +} +}//namespace regression_priorities +#endif /* __TBB_TASK_PRIORITY */ + +#if !__TBB_TEST_SKIP_AFFINITY +#include "harness_concurrency.h" +#endif + +int RunTests () { + TestEnqueueOrder(); + TestPriorityAssertions(); + TestSimplePriorityOps(tbb::priority_low); + TestSimplePriorityOps(tbb::priority_high); + P = tbb::task_scheduler_init::default_num_threads(); + REMARK( "The number of threads: %d\n", P ); + if ( P < 3 ) + return Harness::Skipped; + Low = tbb::priority_normal; + High = tbb::priority_high; + TestPeriodicConcurrentActivities(); + TestPrioritySwitchBetweenTwoMasters(); + Low = tbb::priority_low; + High = tbb::priority_normal; + PreemptionActivatorId = 0; + TestPeriodicConcurrentActivities(); + TestPrioritySwitchBetweenTwoMasters(); + High = tbb::priority_high; + TestPeriodicConcurrentActivities(); + TestPrioritySwitchBetweenTwoMasters(); + PreemptionActivatorId = 1; + TestPrioritySwitchBetweenTwoMasters(); + TestAffinityTasks(); + regression::TestTGContextOnNewThread(); + + return Harness::Done; +} + +#include "tbb/global_control.h" + +int TestMain () { +#if !__TBB_TEST_SKIP_AFFINITY + Harness::LimitNumberOfThreads( DesiredNumThreads ); +#endif /* !__TBB_TASK_PRIORITY */ + test_propagation::TestSetPriority(); // TODO: move down when bug 1996 is fixed + + RunTests(); + tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); + PeriodicActivitiesBody::mode = 1; + TestSwitchBetweenMastersRepeats = 1; + return RunTests(); +} + +#else /* !__TBB_TASK_GROUP_CONTEXT && !__TBB_TASK_PRIORITY*/ + +int TestMain () { + return Harness::Skipped; +} + +#endif /* !__TBB_TASK_GROUP_CONTEXT && !__TBB_TASK_PRIORITY*/ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_scheduler_init.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_scheduler_init.cpp new file mode 100644 index 00000000..6479ea1f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_scheduler_init.cpp @@ -0,0 +1,367 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// We want to test waiting for workers feature with non-preview binaries. However, +// we want to have some testing of task_scheduler_init without this macro. +#if !__TBB_CPF_BUILD +#define TBB_PREVIEW_WAITING_FOR_WORKERS 1 +#endif + +#include "tbb/task_scheduler_init.h" +#include <cstdlib> +#include <cstdio> +#if TBB_USE_EXCEPTIONS +#include <stdexcept> +#endif + +#include "harness_assert.h" +#if _MSC_VER +#pragma warning (push) + // MSVC discovers that ASSERT(false) inside TestBlockingTerminateNS::ExceptionTest2::Body makes the code + // in parallel_for after the body call unreachable. So suppress the warning. +#pragma warning (disable: 4702) +#endif +#include "tbb/parallel_for.h" +#if _MSC_VER +#pragma warning (pop) +#endif + +#include "harness_concurrency_tracker.h" +#include "harness_task.h" +#include "harness.h" + +const int DefaultThreads = tbb::task_scheduler_init::default_num_threads(); + +namespace tbb { namespace internal { +size_t __TBB_EXPORTED_FUNC get_initial_auto_partitioner_divisor(); +}} + +int ArenaConcurrency() { + return int(tbb::internal::get_initial_auto_partitioner_divisor()/4); // TODO: expose through task_arena interface? +} + +// Generally, TBB does not guarantee mandatory parallelism. This test uses some whitebox knowledge about when all the threads can be available +bool test_mandatory_parallelism = true; + +//! Test that task::initialize and task::terminate work when doing nothing else. +/** maxthread is treated as the "maximum" number of worker threads. */ +void InitializeAndTerminate( int maxthread ) { + __TBB_TRY { + for( int i=0; i<256; ++i ) { + int threads = (std::rand() % maxthread) + 1; + switch( i&3 ) { + default: { + tbb::task_scheduler_init init( threads ); + ASSERT(init.is_active(), NULL); + ASSERT(ArenaConcurrency()==(threads==1?2:threads), NULL); + if (test_mandatory_parallelism) + Harness::ExactConcurrencyLevel::check(threads, Harness::ExactConcurrencyLevel::Serialize); + if(i&0x20) tbb::task::enqueue( (*new( tbb::task::allocate_root() ) TaskGenerator(2,6)) ); // a work deferred to workers + break; + } + case 0: { + tbb::task_scheduler_init init; + ASSERT(init.is_active(), NULL); + ASSERT(ArenaConcurrency()==(DefaultThreads==1?2:init.default_num_threads()), NULL); + if (test_mandatory_parallelism) + Harness::ExactConcurrencyLevel::check(init.default_num_threads(), Harness::ExactConcurrencyLevel::Serialize); + if(i&0x40) tbb::task::enqueue( (*new( tbb::task::allocate_root() ) TaskGenerator(3,5)) ); // a work deferred to workers + break; + } + case 1: { + tbb::task_scheduler_init init( tbb::task_scheduler_init::deferred ); + ASSERT(!init.is_active(), "init should not be active; initialization was deferred"); + init.initialize( threads ); + ASSERT(init.is_active(), NULL); + ASSERT(ArenaConcurrency()==(threads==1?2:threads), NULL); + if (test_mandatory_parallelism) + Harness::ExactConcurrencyLevel::check(threads, Harness::ExactConcurrencyLevel::Serialize); + init.terminate(); + ASSERT(!init.is_active(), "init should not be active; it was terminated"); + break; + } + case 2: { + tbb::task_scheduler_init init( tbb::task_scheduler_init::automatic ); + ASSERT(init.is_active(), NULL); + ASSERT(ArenaConcurrency()==(DefaultThreads==1?2:init.default_num_threads()), NULL); + if (test_mandatory_parallelism) + Harness::ExactConcurrencyLevel::check(init.default_num_threads(), Harness::ExactConcurrencyLevel::Serialize); + break; + } + } + } + } __TBB_CATCH( std::runtime_error& error ) { +#if TBB_USE_EXCEPTIONS + REPORT("ERROR: %s\n", error.what() ); +#endif /* TBB_USE_EXCEPTIONS */ + } +} + +#if _WIN64 +namespace std { // 64-bit Windows compilers have not caught up with 1998 ISO C++ standard + using ::srand; +} +#endif /* _WIN64 */ + +struct ThreadedInit { + void operator()( int ) const { + InitializeAndTerminate(MaxThread); + } +}; + +#if _MSC_VER +#include "tbb/machine/windows_api.h" +#include <tchar.h> +#endif /* _MSC_VER */ + +/** The test will fail in particular if task_scheduler_init mistakenly hooks up + auto-initialization mechanism. **/ +void AssertExplicitInitIsNotSupplanted () { + tbb::task_scheduler_init init(1); + + Harness::ExactConcurrencyLevel::check(1); +} + +struct TestNoWorkerSurplusRun { + void operator() (int) const { + const unsigned THREADS = tbb::tbb_thread::hardware_concurrency()*2/3; + for (int j=0; j<10; j++) { + tbb::task_scheduler_init t(THREADS); + Harness::ExactConcurrencyLevel::Combinable unique; + + for (int i=0; i<50; i++) + Harness::ExactConcurrencyLevel::checkLessOrEqual(THREADS, &unique); + } + } +}; + +void TestNoWorkerSurplus () { + // Run the test in a special thread because otherwise the surplus issue + // is not observed for some hardware configurations + NativeParallelFor( 1, TestNoWorkerSurplusRun() ); +} + +#if TBB_PREVIEW_WAITING_FOR_WORKERS +#include "tbb/task_group.h" +#include "tbb/task_arena.h" + +namespace TestBlockingTerminateNS { + struct EmptyBody { + void operator()() const {} + void operator()( int ) const {} + }; + + struct TestAutoInitBody { + void operator()( int ) const { + tbb::parallel_for( 0, 100, EmptyBody() ); + } + }; + + static tbb::atomic<int> gSeed; + static tbb::atomic<int> gNumSuccesses; + + class TestMultpleWaitBody { + bool myAutoInit; + public: + TestMultpleWaitBody( bool autoInit = false ) : myAutoInit( autoInit ) {} + void operator()( int ) const { + tbb::task_scheduler_init init( tbb::task_scheduler_init::deferred ); + if ( !myAutoInit ) + init.initialize( tbb::task_scheduler_init::automatic ); + Harness::FastRandom rnd( ++gSeed ); + // In case of auto init sub-tests we skip + // - case #4 to avoid recursion + // - case #5 because it is explicit initialization + const int numCases = myAutoInit ? 4 : 6; + switch ( rnd.get() % numCases ) { + case 0: { + tbb::task_arena a; + a.enqueue( EmptyBody() ); + break; + } + case 1: { + tbb::task_group tg; + tg.run( EmptyBody() ); + tg.wait(); + break; + } + case 2: + tbb::parallel_for( 0, 100, EmptyBody() ); + break; + case 3: + /* do nothing */ + break; + case 4: + // Create and join several threads with auto initialized scheduler. + NativeParallelFor( rnd.get() % 5 + 1, TestMultpleWaitBody( true ) ); + break; + case 5: + { + tbb::task_scheduler_init init2; + bool res = init2.blocking_terminate( std::nothrow ); + ASSERT( !res, NULL ); + } + break; + } + if ( !myAutoInit && init.blocking_terminate( std::nothrow ) ) + ++gNumSuccesses; + } + }; + + void TestMultpleWait() { + const int minThreads = 1; + const int maxThreads = 16; + const int numRepeats = 5; + // Initialize seed with different values on different machines. + gSeed = tbb::task_scheduler_init::default_num_threads(); + for ( int repeats = 0; repeats<numRepeats; ++repeats ) { + for ( int threads = minThreads; threads<maxThreads; ++threads ) { + gNumSuccesses = 0; + NativeParallelFor( threads, TestMultpleWaitBody() ); + ASSERT( gNumSuccesses > 0, "At least one blocking terminate must return 'true'" ); + } + } + } + +#if TBB_USE_EXCEPTIONS + template <typename F> + void TestException( F &f ) { + Harness::suppress_unused_warning( f ); + bool caught = false; + try { + f(); + ASSERT( false, NULL ); + } + catch ( const std::runtime_error& ) { + caught = true; + } +#if TBB_USE_CAPTURED_EXCEPTION + catch ( const tbb::captured_exception& ) { + caught = true; + } +#endif + catch ( ... ) { + ASSERT( false, NULL ); + } + ASSERT( caught, NULL ); + } + + class ExceptionTest1 { + tbb::task_scheduler_init tsi1; + int myIndex; + public: + ExceptionTest1( int index ) : myIndex( index ) {} + + void operator()() { + tbb::task_scheduler_init tsi2; + (myIndex == 0 ? tsi1 : tsi2).blocking_terminate(); + ASSERT( false, "Blocking terminate did not throw the exception" ); + } + }; + + struct ExceptionTest2 { + class Body { + Harness::SpinBarrier& myBarrier; + public: + Body( Harness::SpinBarrier& barrier ) : myBarrier( barrier ) {} + void operator()( int ) const { + myBarrier.wait(); + tbb::task_scheduler_init init; + init.blocking_terminate(); + ASSERT( false, "Blocking terminate did not throw the exception inside the parallel region" ); + } + }; + void operator()() { + const int numThreads = 4; + tbb::task_scheduler_init init( numThreads ); + Harness::SpinBarrier barrier( numThreads ); + tbb::parallel_for( 0, numThreads, Body( barrier ) ); + ASSERT( false, "Parallel loop did not throw the exception" ); + } + }; +#endif /* TBB_USE_EXCEPTIONS */ + + void TestExceptions() { + for ( int i = 0; i<2; ++i ) { + tbb::task_scheduler_init tsi[2]; + bool res1 = tsi[i].blocking_terminate( std::nothrow ); + ASSERT( !res1, NULL ); + bool res2 = tsi[1-i].blocking_terminate( std::nothrow ); + ASSERT( res2, NULL ); + } +#if TBB_USE_EXCEPTIONS + ExceptionTest1 Test1(0), Test2(1); + TestException( Test1 ); + TestException( Test2 ); + ExceptionTest2 Test3; + TestException( Test3 ); +#endif + } +} + +void TestBlockingTerminate() { + TestBlockingTerminateNS::TestExceptions(); + TestBlockingTerminateNS::TestMultpleWait(); +} +#endif /* TBB_PREVIEW_WAITING_FOR_WORKERS */ + +int TestMain () { + // Do not use tbb::task_scheduler_init directly in the scope of main's body, + // as a static variable, or as a member of a static variable. +#if _MSC_VER && !__TBB_NO_IMPLICIT_LINKAGE && !defined(__TBB_LIB_NAME) + #ifdef _DEBUG + ASSERT(!GetModuleHandle(_T("tbb.dll")) && GetModuleHandle(_T("tbb_debug.dll")), + "test linked with wrong (non-debug) TBB library"); + #else + ASSERT(!GetModuleHandle(_T("tbb_debug.dll")) && GetModuleHandle(_T("tbb.dll")), + "test linked with wrong (debug) TBB library"); + #endif +#endif /* _MSC_VER && !__TBB_NO_IMPLICIT_LINKAGE && !__TBB_LIB_NAME */ + std::srand(2); + REMARK("testing master thread\n"); + int threads = DefaultThreads*2; + { // work-around shared RML + tbb::task_scheduler_init init( threads ); + if( !Harness::ExactConcurrencyLevel::isEqual( threads ) ) { + threads = DefaultThreads; + if( MaxThread > DefaultThreads ) + MaxThread = DefaultThreads; +#if RML_USE_WCRM + REPORT("Known issue: shared RML for ConcRT does not support oversubscription\n"); + test_mandatory_parallelism = false; // we cannot rely on ConcRT to provide all the requested threads +#else + REPORT("Known issue: machine is heavy loaded or shared RML which does not support oversubscription is loaded\n"); +#endif + } + } + InitializeAndTerminate( threads ); // test initialization of more than default number of threads + for( int p=MinThread; p<=MaxThread; ++p ) { + REMARK("testing with %d threads\n", p ); + // protect market with excess threads from default initializations + // TODO IDEA: enhance task_scheduler_init to serve as global_control setting so that + // number of threads > default concurrency will be requested from market. + // Such settings must be aggregated via 'max' function and 'max_allowed_parallelism' control + // (which has 'min' aggregation) will have precedence over it. + tbb::task_scheduler_init init( tbb::task_scheduler_init::deferred ); + if( MaxThread > DefaultThreads ) init.initialize( MaxThread ); + NativeParallelFor( p, ThreadedInit() ); + } + AssertExplicitInitIsNotSupplanted(); +#if TBB_PREVIEW_WAITING_FOR_WORKERS + TestBlockingTerminate(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_scheduler_observer.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_scheduler_observer.cpp new file mode 100644 index 00000000..c27944e2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_scheduler_observer.cpp @@ -0,0 +1,344 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// undefine __TBB_CPF_BUILD to simulate user's setup +#undef __TBB_CPF_BUILD + +#include "tbb/tbb_config.h" +#include "harness.h" + +#if __TBB_SCHEDULER_OBSERVER +#include "tbb/task_scheduler_observer.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/atomic.h" +#include "tbb/task.h" +#include "tbb/enumerable_thread_specific.h" +#include "../tbb/tls.h" +#include "tbb/tick_count.h" +#include "harness_barrier.h" + +#if _MSC_VER && __TBB_NO_IMPLICIT_LINKAGE +// plays around __TBB_NO_IMPLICIT_LINKAGE. __TBB_LIB_NAME should be defined (in makefiles) + #pragma comment(lib, __TBB_STRING(__TBB_LIB_NAME)) +#endif + +const int MaxFlagIndex = sizeof(uintptr_t)*8-1; + +struct ObserverStats { + tbb::atomic<int> m_entries; + tbb::atomic<int> m_exits; + tbb::atomic<int> m_workerEntries; + tbb::atomic<int> m_workerExits; + + void Reset () { + m_entries = m_exits = m_workerEntries = m_workerExits = 0; + } + + void operator += ( const ObserverStats& s ) { + m_entries += s.m_entries; + m_exits += s.m_exits; + m_workerEntries += s.m_workerEntries; + m_workerExits += s.m_workerExits; + } +}; + +struct ThreadState { + uintptr_t m_flags; + tbb::task_scheduler_observer *m_dyingObserver; + bool m_isMaster; + ThreadState() { reset(); } + void reset() { + m_flags = 0; + m_dyingObserver = NULL; + m_isMaster = false; + } + static ThreadState &get(); +}; + +tbb::enumerable_thread_specific<ThreadState> theLocalState; +tbb::internal::tls<intptr_t> theThreadPrivate; + +ThreadState &ThreadState::get() { + bool exists; + ThreadState& state = theLocalState.local(exists); + // ETS will not detect that a thread was allocated with the same id as a destroyed thread + if( exists && theThreadPrivate.get() == 0 ) state.reset(); + theThreadPrivate = 1; // mark thread constructed + return state; +} + +static ObserverStats theStats; +static tbb::atomic<int> theNumObservers; + +const int P = min( tbb::task_scheduler_init::default_num_threads(), (int)sizeof(int) * CHAR_BIT ); + +enum TestMode { + //! Ensure timely workers destruction in order to guarantee all exit notification are fired. + tmSynchronized = 1, + //! Use local observer. + tmLocalObservation = 2, + //! Observer causes autoinitialization of the scheduler + tmAutoinitialization = 4 +}; + +uintptr_t theTestMode, + thePrevMode = 0; + +class MyObserver : public tbb::task_scheduler_observer, public ObserverStats { + uintptr_t m_flag; + tbb::atomic<bool> m_dying; + + void on_scheduler_entry( bool is_worker ) __TBB_override { + ThreadState& state = ThreadState::get(); + ASSERT( is_worker==!state.m_isMaster, NULL ); + if ( thePrevMode & tmSynchronized ) { + ASSERT( !(state.m_flags & m_flag), "Observer repeatedly invoked for the same thread" ); + if ( theTestMode & tmLocalObservation ) + ASSERT( !state.m_flags, "Observer locality breached" ); + } + if ( m_dying && theTestMode & tmLocalObservation ) { + // In case of local observation a worker may enter the arena after + // the wait for lagging on_entry calls in the MyObserver destructor + // succeeds but before its base class tbb::task_scheduler_observer + // destructor removes it from the internal list maintained by the + // task scheduler. This will result in on_entry notification without, + // subsequent on_exit as the observer is likely to be destroyed before + // the worker discovers that the arena is empty and leaves it. + // + // To prevent statistics distortion, ignore the notifications for + // observers about to be destroyed. + ASSERT( !state.m_dyingObserver || state.m_dyingObserver != this || thePrevMode & tmSynchronized, NULL ); + state.m_dyingObserver = this; + return; + } + state.m_dyingObserver = NULL; + ++m_entries; + state.m_flags |= m_flag; + if ( is_worker ) + ++m_workerEntries; + } + void on_scheduler_exit( bool is_worker ) __TBB_override { + ThreadState& state = ThreadState::get(); + ASSERT( is_worker==!state.m_isMaster, NULL ); + if ( m_dying && state.m_dyingObserver ) { + ASSERT( state.m_dyingObserver == this, "Exit without entry (for a dying observer)" ); + state.m_dyingObserver = NULL; + return; + } + ASSERT( state.m_flags & m_flag, "Exit without entry" ); + state.m_flags &= ~m_flag; + ++m_exits; + if ( is_worker ) + ++m_workerExits; + } +public: + MyObserver( uintptr_t flag ) + : tbb::task_scheduler_observer(theTestMode & tmLocalObservation ? true : false) + , m_flag(flag) + { + ++theNumObservers; + Reset(); + m_dying = false; + // Local observer causes automatic scheduler initialization + // in the current thread, so here, we must postpone the activation. + if ( !(theTestMode & tmLocalObservation)) + observe(true); + } + + ~MyObserver () { + m_dying = true; + ASSERT( m_exits <= m_entries, NULL ); + if ( theTestMode & tmSynchronized ) { + tbb::tick_count t0 = tbb::tick_count::now(); + while ( m_exits < m_entries && (tbb::tick_count::now() - t0).seconds() < 5 ) + Harness::Sleep(10); + if ( m_exits < m_entries ) + REPORT( "Warning: Entry/exit count mismatch (%d, %d). Observer is broken or machine is overloaded.\n", (int)m_entries, (int)m_exits ); + } + theStats += *this; + --theNumObservers; + // it is recommended to disable observation before destructor of the base class starts, + // otherwise it can lead to concurrent notification callback on partly destroyed object, + // which in turn can harm (in addition) if derived class has new virtual methods. + // This class has no, and for test purposes we rely on implementation failsafe mechanism. + //observe(false); + } +}; // class MyObserver + +Harness::SpinBarrier theGlobalBarrier; +bool theGlobalBarrierActive = true; + +class FibTask : public tbb::task { + const int N; + uintptr_t m_flag; + MyObserver &m_observer; +public: + FibTask( int n, uintptr_t flags, MyObserver &obs ) : N(n), m_flag(flags), m_observer(obs) {} + + tbb::task* execute() __TBB_override { + ThreadState& s = ThreadState::get(); + ASSERT( !(~s.m_flags & m_flag), NULL ); + if( N < 2 ) + return NULL; + bool globalBarrierActive = false; + if ( s.m_isMaster ) { + if ( theGlobalBarrierActive ) { + // This is the root task. Its N is equal to the number of threads. + // Spawn a task for each worker. + set_ref_count(N); + for ( int i = 1; i < N; ++i ) + spawn( *new( allocate_child() ) FibTask(20, m_flag, m_observer) ); + if ( theTestMode & tmSynchronized ) { + theGlobalBarrier.wait(); + ASSERT( m_observer.m_entries >= N, "Wrong number of on_entry calls after the first barrier" ); + // All the spawned tasks have been stolen by workers. + // Now wait for workers to spawn some more tasks for this thread to steal back. + theGlobalBarrier.wait(); + ASSERT( !theGlobalBarrierActive, "Workers are expected to have reset this flag" ); + } + else + theGlobalBarrierActive = false; + wait_for_all(); + return NULL; + } + } + else { + if ( theGlobalBarrierActive ) { + if ( theTestMode & tmSynchronized ) { + theGlobalBarrier.wait(); + globalBarrierActive = true; + } + theGlobalBarrierActive = false; + } + } + set_ref_count(3); + spawn( *new( allocate_child() ) FibTask(N-1, m_flag, m_observer) ); + spawn( *new( allocate_child() ) FibTask(N-2, m_flag, m_observer) ); + if ( globalBarrierActive ) { + // It's the first task executed by a worker. Release the master thread. + theGlobalBarrier.wait(); + } + wait_for_all(); + return NULL; + } +}; // class FibTask + +Harness::SpinBarrier theMasterBarrier; + +class TestBody { + int m_numThreads; +public: + TestBody( int numThreads ) : m_numThreads(numThreads) {} + + void operator()( int i ) const { + ThreadState &state = ThreadState::get(); + ASSERT( !state.m_isMaster, "should be newly initialized thread"); + state.m_isMaster = true; + uintptr_t f = i <= MaxFlagIndex ? 1<<i : 0; + MyObserver o(f); + if ( theTestMode & tmSynchronized ) + theMasterBarrier.wait(); + // when mode is local observation but not synchronized and when num threads == default + if ( theTestMode & tmAutoinitialization ) + o.observe(true); // test autoinitialization can be done by observer + // Observer in enabled state must outlive the scheduler to ensure that + // all exit notifications are called. + tbb::task_scheduler_init init(m_numThreads); + // when local & non-autoinitialized observation mode + if ( theTestMode & tmLocalObservation ) + o.observe(true); + for ( int j = 0; j < 2; ++j ) { + tbb::task &t = *new( tbb::task::allocate_root() ) FibTask(m_numThreads, f, o); + tbb::task::spawn_root_and_wait(t); + thePrevMode = theTestMode; + } + } +}; // class TestBody + +void TestObserver( int M, int T, uintptr_t testMode ) { + theLocalState.clear(); + theStats.Reset(); + theGlobalBarrierActive = true; + theTestMode = testMode; + NativeParallelFor( M, TestBody(T) ); + // When T (number of threads in arena, i.e. master + workers) is less than P + // (hardware concurrency), more than T-1 workers can visit the same arena. This + // is possible in case of imbalance or when other arenas are activated/deactivated + // concurrently). + ASSERT( !theNumObservers, "Unexpected alive observer(s)" ); + REMARK( "Entries %d / %d, exits %d\n", (int)theStats.m_entries, (int)theStats.m_workerEntries, (int)theStats.m_exits ); + if ( testMode & tmSynchronized ) { + if ( testMode & tmLocalObservation ) { + ASSERT( theStats.m_entries >= M * T, "Too few on_entry calls" ); + ASSERT( theStats.m_workerEntries >= M * (T - 1), "Too few worker entries" ); + } + else { + ASSERT( theStats.m_entries >= M * M * T, "Too few on_entry calls" ); + ASSERT( theStats.m_entries <= M * (P + 1), "Too many on_entry calls" ); + ASSERT( theStats.m_workerEntries >= M * M * (T - 1), "Too few worker entries" ); + ASSERT( theStats.m_workerEntries <= M * (P - 1), "Too many worker entries" ); + } + ASSERT( theStats.m_entries == theStats.m_exits, "Entries/exits mismatch" ); + } + else { + ASSERT( theStats.m_entries >= M, "Too few on_entry calls" ); + ASSERT( theStats.m_exits >= M || (testMode & tmAutoinitialization), "Too few on_exit calls" ); + if ( !(testMode & tmLocalObservation) ) { + ASSERT( theStats.m_entries <= M * M * P, "Too many on_entry calls" ); + ASSERT( theStats.m_exits <= M * M * T, "Too many on_exit calls" ); + } + ASSERT( theStats.m_entries >= theStats.m_exits, "More exits than entries" ); + } +} + +int TestMain () { + if ( P < 2 ) + return Harness::Skipped; + theNumObservers = 0; + // Fully- and under-utilized mode + for ( int M = 1; M < P; M <<= 1 ) { + if ( M > P/2 ) { + ASSERT( P & (P-1), "Can get here only in case of non power of two cores" ); + M = P/2; + if ( M==1 || (M & (M-1)) ) + break; // Already tested this configuration + } + int T = P / M; + ASSERT( T > 1, NULL ); + REMARK( "Masters: %d; Arena size: %d\n", M, T ); + theMasterBarrier.initialize(M); + theGlobalBarrier.initialize(M * T); + TestObserver(M, T, 0); + TestObserver(M, T, tmSynchronized | tmLocalObservation ); + // keep tmAutoInitialization the last, as it does not release worker threads + TestObserver(M, T, tmLocalObservation | ( T==P? tmAutoinitialization : 0) ); + } + // Oversubscribed mode + for ( int i = 0; i < 4; ++i ) { + REMARK( "Masters: %d; Arena size: %d\n", P-1, P ); + TestObserver(P-1, P, 0); + TestObserver(P-1, P, tmLocalObservation); + } + Harness::Sleep(20); + return Harness::Done; +} + +#else /* !__TBB_SCHEDULER_OBSERVER */ + +int TestMain () { + return Harness::Skipped; +} +#endif /* !__TBB_SCHEDULER_OBSERVER */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_steal_limit.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_steal_limit.cpp new file mode 100644 index 00000000..cb111a1c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_task_steal_limit.cpp @@ -0,0 +1,75 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/task.h" +#include "harness.h" +#include "tbb/task_scheduler_init.h" + +using tbb::task; + +#if __TBB_ipf + const unsigned StackSize = 1024*1024*6; +#else /* */ + const unsigned StackSize = 1024*1024*3; +#endif + +// GCC and ICC on Linux store TLS data in the stack space. This test makes sure +// that the stealing limiting heuristic used by the task scheduler does not +// switch off stealing when a large amount of TLS data is reserved. +#if _MSC_VER +__declspec(thread) +#elif __linux__ || ((__MINGW32__ || __MINGW64__) && __TBB_GCC_VERSION >= 40500) +__thread +#endif + char map2[1024*1024*2]; + +class TestTask : public task { +public: + static volatile int completed; + task* execute() __TBB_override { + completed = 1; + return NULL; + }; +}; + +volatile int TestTask::completed = 0; + +void TestStealingIsEnabled () { + tbb::task_scheduler_init init(2, StackSize); + task &r = *new( task::allocate_root() ) tbb::empty_task; + task &t = *new( r.allocate_child() ) TestTask; + r.set_ref_count(2); + r.spawn(t); + int count = 0; + while ( !TestTask::completed && ++count < 6 ) + Harness::Sleep(1000); + ASSERT( TestTask::completed, "Stealing is disabled or the machine is heavily oversubscribed" ); + r.wait_for_all(); + task::destroy(r); +} + +int TestMain () { +#if !__TBB_THREAD_LOCAL_VARIABLES_PRESENT + REPORT( "Known issue: Test skipped because no compiler support for __thread keyword.\n" ); + return Harness::Skipped; +#endif + if ( tbb::task_scheduler_init::default_num_threads() == 1 ) { + REPORT( "Known issue: Test requires at least 2 hardware threads.\n" ); + return Harness::Skipped; + } + TestStealingIsEnabled(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_condition_variable.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_condition_variable.cpp new file mode 100644 index 00000000..36e61345 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_condition_variable.cpp @@ -0,0 +1,25 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_config.h" + +#include "test_condition_variable.h" + +int TestMain() { + REMARK( "testing with tbb condvar\n" ); + DoCondVarTest<tbb::mutex,tbb::recursive_mutex>(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_fork.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_fork.cpp new file mode 100644 index 00000000..ac9b1f0c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_fork.cpp @@ -0,0 +1,326 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#define TBB_PREVIEW_WAITING_FOR_WORKERS 1 +#include "tbb/task_scheduler_init.h" +#include "tbb/blocked_range.h" +#include "tbb/cache_aligned_allocator.h" +#include "tbb/parallel_for.h" + +#define HARNESS_DEFAULT_MIN_THREADS (tbb::task_scheduler_init::default_num_threads()) +#define HARNESS_DEFAULT_MAX_THREADS (4*tbb::task_scheduler_init::default_num_threads()) +#if __bg__ +// CNK does not support fork() +#define HARNESS_SKIP_TEST 1 +#endif +#include "harness.h" + +#if _WIN32||_WIN64 +#include "tbb/concurrent_hash_map.h" + +HANDLE getCurrentThreadHandle() +{ + HANDLE hProc = GetCurrentProcess(), hThr = INVALID_HANDLE_VALUE; +#if TBB_USE_ASSERT + BOOL res = +#endif + DuplicateHandle( hProc, GetCurrentThread(), hProc, &hThr, 0, FALSE, DUPLICATE_SAME_ACCESS ); + __TBB_ASSERT( res, "Retrieving current thread handle failed" ); + return hThr; +} + +bool threadTerminated(HANDLE h) +{ + DWORD ret = WaitForSingleObjectEx(h, 0, FALSE); + return WAIT_OBJECT_0 == ret; +} + +struct Data { + HANDLE h; +}; + +typedef tbb::concurrent_hash_map<DWORD, Data> TidTableType; + +static TidTableType tidTable; + +#else + +#if __sun || __SUNPRO_CC +#define _POSIX_PTHREAD_SEMANTICS 1 // to get standard-conforming sigwait(2) +#endif +#include <signal.h> +#include <sys/types.h> +#include <unistd.h> +#include <sys/wait.h> +#include <sched.h> + +#include "tbb/tick_count.h" + +void SigHandler(int) { } + +#endif // _WIN32||_WIN64 + +class AllocTask { +public: + void operator() (const tbb::blocked_range<int> &r) const { +#if _WIN32||_WIN64 + HANDLE h = getCurrentThreadHandle(); + DWORD tid = GetCurrentThreadId(); + { + TidTableType::accessor acc; + if (tidTable.insert(acc, tid)) { + acc->second.h = h; + } + } +#endif + for (int y = r.begin(); y != r.end(); ++y) { + void *p = tbb::internal::NFS_Allocate(1, 7000, NULL); + tbb::internal::NFS_Free(p); + } + } + AllocTask() {} +}; + +void CallParallelFor() +{ + tbb::parallel_for(tbb::blocked_range<int>(0, 10000, 1), AllocTask(), + tbb::simple_partitioner()); +} + +/* Regression test against data race between termination of workers + and setting blocking terination mode in main thread. */ +class RunWorkersBody : NoAssign { + bool wait_workers; +public: + RunWorkersBody(bool waitWorkers) : wait_workers(waitWorkers) {} + void operator()(const int /*threadID*/) const { + tbb::task_scheduler_init sch(MaxThread); + CallParallelFor(); + if (wait_workers) { + bool ok = sch.blocking_terminate(std::nothrow); + ASSERT(ok, NULL); + } + } +}; + +void TestBlockNonblock() +{ + for (int i=0; i<100; i++) { + REMARK("\rIteration %d ", i); + NativeParallelFor(4, RunWorkersBody(/*wait_workers=*/false)); + RunWorkersBody(/*wait_workers=*/true)(0); + } +} + +class RunInNativeThread : NoAssign { + bool create_tsi, + blocking; +public: + RunInNativeThread(bool create_tsi_, bool blocking_) : + create_tsi(create_tsi_), blocking(blocking_) {} + void operator()(const int /*threadID*/) const { + // nested TSI or auto-initialized TSI can be terminated when + // wait_workers is true (deferred TSI means auto-initialization) + tbb::task_scheduler_init tsi(create_tsi? 2 : tbb::task_scheduler_init::deferred); + CallParallelFor(); + if (blocking) { + bool ok = tsi.blocking_terminate(std::nothrow); + // all usages are nested + ASSERT(!ok, "Nested blocking terminate must fail."); + } + } +}; + +void TestTasksInThread() +{ + tbb::task_scheduler_init sch(2); + CallParallelFor(); + for (int i=0; i<2; i++) + NativeParallelFor(2, RunInNativeThread(/*create_tsi=*/1==i, /*blocking=*/false)); + bool ok = sch.blocking_terminate(std::nothrow); + ASSERT(ok, NULL); +} + +#include "harness_memory.h" + +// check for memory leak during TBB task scheduler init/terminate life cycle +// TODO: move to test_task_scheduler_init after workers waiting productization +void TestSchedulerMemLeaks() +{ + const int ITERS = 10; + int it; + + for (it=0; it<ITERS; it++) { + size_t memBefore = GetMemoryUsage(); +#if _MSC_VER && _DEBUG + // _CrtMemCheckpoint() and _CrtMemDifference are non-empty only in _DEBUG + _CrtMemState stateBefore, stateAfter, diffState; + _CrtMemCheckpoint(&stateBefore); +#endif + for (int i=0; i<100; i++) { + tbb::task_scheduler_init sch(1); + for (int k=0; k<10; k++) { + tbb::empty_task *t = new( tbb::task::allocate_root() ) tbb::empty_task(); + tbb::task::enqueue(*t); + } + bool ok = sch.blocking_terminate(std::nothrow); + ASSERT(ok, NULL); + } +#if _MSC_VER && _DEBUG + _CrtMemCheckpoint(&stateAfter); + int ret = _CrtMemDifference(&diffState, &stateBefore, &stateAfter); + ASSERT(!ret, "It must be no memory leaks at this point."); +#endif + if (GetMemoryUsage() <= memBefore) + break; + } + ASSERT(it < ITERS, "Memory consumption has not stabilized. Memory Leak?"); +} + +void TestNestingTSI() +{ + // nesting with and without blocking is possible + for (int i=0; i<2; i++) { + tbb::task_scheduler_init schBlock(2); + CallParallelFor(); + tbb::task_scheduler_init schBlock1(2); + CallParallelFor(); + if (i) + schBlock1.terminate(); + else { + bool ok = schBlock1.blocking_terminate(std::nothrow); + ASSERT(!ok, "Nested blocking terminate must fail."); + } + bool ok = schBlock.blocking_terminate(std::nothrow); + ASSERT(ok, NULL); + } + { + tbb::task_scheduler_init schBlock(2); + NativeParallelFor(1, RunInNativeThread(/*create_tsi=*/true, /*blocking=*/true)); + bool ok = schBlock.blocking_terminate(std::nothrow); + ASSERT(ok, NULL); + } +} + +void TestAutoInit() +{ + CallParallelFor(); // autoinit + // creation of blocking scheduler is possible, but one is not block + NativeParallelFor(1, RunInNativeThread(/*create_tsi=*/true, /*blocking=*/true)); +} + +int TestMain() +{ + using namespace Harness; + + TestNestingTSI(); + TestBlockNonblock(); + TestTasksInThread(); + TestSchedulerMemLeaks(); + + bool child = false; +#if _WIN32||_WIN64 + DWORD masterTid = GetCurrentThreadId(); +#else + struct sigaction sa; + sigset_t sig_set; + + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SigHandler; + if (sigaction(SIGCHLD, &sa, NULL)) + ASSERT(0, "sigaction failed"); + if (sigaction(SIGALRM, &sa, NULL)) + ASSERT(0, "sigaction failed"); + // block SIGCHLD and SIGALRM, the mask is inherited by worker threads + sigemptyset(&sig_set); + sigaddset(&sig_set, SIGCHLD); + sigaddset(&sig_set, SIGALRM); + if (pthread_sigmask(SIG_BLOCK, &sig_set, NULL)) + ASSERT(0, "pthread_sigmask failed"); +#endif + for (int threads=MinThread; threads<=MaxThread; threads+=MinThread) { + for (int i=0; i<20; i++) { + if (!child) + REMARK("\rThreads %d %d ", threads, i); + { + tbb::task_scheduler_init sch(threads); + bool ok = sch.blocking_terminate(std::nothrow); + ASSERT(ok, NULL); + } + tbb::task_scheduler_init sch(threads); + + CallParallelFor(); + bool ok = sch.blocking_terminate(std::nothrow); + ASSERT(ok, NULL); + +#if _WIN32||_WIN64 + // check that there is no alive threads after terminate() + for (TidTableType::const_iterator it = tidTable.begin(); + it != tidTable.end(); ++it) { + if (masterTid != it->first) { + ASSERT(threadTerminated(it->second.h), NULL); + } + } + tidTable.clear(); +#else // _WIN32||_WIN64 + if (child) + exit(0); + else { + pid_t pid = fork(); + if (!pid) { + i = -1; + child = true; + } else { + int sig; + pid_t w_ret = 0; + // wait for SIGCHLD up to timeout + alarm(30); + if (0 != sigwait(&sig_set, &sig)) + ASSERT(0, "sigwait failed"); + alarm(0); + w_ret = waitpid(pid, NULL, WNOHANG); + ASSERT(w_ret>=0, "waitpid failed"); + if (!w_ret) { + ASSERT(!kill(pid, SIGKILL), NULL); + w_ret = waitpid(pid, NULL, 0); + ASSERT(w_ret!=-1, "waitpid failed"); + + ASSERT(0, "Hang after fork"); + } + // clean pending signals (if any occurs since sigwait) + sigset_t p_mask; + for (;;) { + sigemptyset(&p_mask); + sigpending(&p_mask); + if (sigismember(&p_mask, SIGALRM) + || sigismember(&p_mask, SIGCHLD)) { + if (0 != sigwait(&p_mask, &sig)) + ASSERT(0, "sigwait failed"); + } else + break; + } + } + } +#endif // _WIN32||_WIN64 + } + } + // auto initialization at this point + TestAutoInit(); + + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_header.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_header.cpp new file mode 100644 index 00000000..d47bb1ef --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_header.cpp @@ -0,0 +1,365 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + This test ensures that tbb.h brings in all the public TBB interface definitions, + and if all the necessary symbols are exported from the library. + + Most of the checks happen at the compilation or link phases. +**/ +#if __TBB_CPF_BUILD +// Add testing of preview features +#define TBB_PREVIEW_AGGREGATOR 1 +#define TBB_PREVIEW_CONCURRENT_LRU_CACHE 1 +#define TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE 1 +#define TBB_PREVIEW_FLOW_GRAPH_NODES 1 +#define TBB_PREVIEW_BLOCKED_RANGE_ND 1 +#define TBB_PREVIEW_WAITING_FOR_WORKERS 1 +#define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1 +#define TBB_PREVIEW_ISOLATED_TASK_GROUP 1 +#endif + +#if __TBB_TEST_SECONDARY + // Test _DEBUG macro custom definitions. + #if TBB_USE_DEBUG + #ifdef _DEBUG + #undef _DEBUG + #endif /* _DEBUG */ + // Check that empty value successfully enables the debug mode. + #define _DEBUG + static bool isDebugExpected = true; + #else + // Check that zero value does not enable the debug mode. + #define _DEBUG 0x0 + static bool isDebugExpected = false; + #endif /* TBB_USE_DEBUG */ + #define DO_TEST_DEBUG_MACRO 1 +#else + // Test default definitions of _DEBUG. + #if _DEBUG + static bool isDebugExpected = true; + #define DO_TEST_DEBUG_MACRO 1 + #elif _MSC_VER + // for MSVC, _DEBUG not defined indicates a release mode. + static bool isDebugExpected = false; + #define DO_TEST_DEBUG_MACRO 1 + #endif /* _DEBUG */ +#endif /* __TBB_TEST_SECONDARY */ + +#if DO_TEST_DEBUG_MACRO +// Reset TBB_USE_DEBUG defined in makefiles. +#undef TBB_USE_DEBUG +#endif /* DO_TEST_DEBUG_MACRO */ +#define __TBB_CONFIG_PREPROC_ONLY _MSC_VER // For MSVC, prevent including standard headers in tbb_config.h +#include "tbb/tbb_config.h" + +#if !TBB_USE_DEBUG && defined(_DEBUG) +// TBB_USE_DEBUG is 0 but _DEBUG is defined, it means that _DEBUG is 0 +// MSVC C++ headers consider any definition of _DEBUG, including 0, as debug mode +#undef _DEBUG +#endif /* !TBB_USE_DEBUG && defined(_DEBUG) */ + +#include "harness_defs.h" +#if _MSC_VER +#pragma warning (disable : 4503) // decorated name length exceeded, name was truncated +#endif + +#if !(__TBB_TEST_SECONDARY && __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN) + +#include "tbb/tbb.h" + +static volatile size_t g_sink; + +#define TestTypeDefinitionPresence( Type ) g_sink = sizeof(tbb::Type); +#define TestTypeDefinitionPresence2(TypeStart, TypeEnd) g_sink = sizeof(tbb::TypeStart,TypeEnd); +#define TestTypeDefinitionPresence3(TypeStart, TypeMid, TypeEnd) g_sink = sizeof(tbb::TypeStart,TypeMid,TypeEnd); +#define TestFuncDefinitionPresence(Fn, Args, ReturnType) { ReturnType (*pfn)Args = &tbb::Fn; (void)pfn; } + +struct Body { + void operator() () const {} +}; +struct Body1 { + void operator() ( int ) const {} +}; +struct Body1a { // feeder body for parallel_do + void operator() ( int, tbb::parallel_do_feeder<int>& ) const {} +}; +struct Body1b { // binary operator for reduction and comparison + int operator() ( const int, const int ) const { return 0; } +}; +struct Body2 { + Body2 () {} + Body2 ( const Body2&, tbb::split ) {} + void operator() ( const tbb::blocked_range<int>& ) const {} + void join( const Body2& ) {} +}; +struct Body2a { // for lambda-friendly parallel_reduce + int operator() ( const tbb::blocked_range<int>&, const int ) const { return 0; } +}; +struct Body3 { // for parallel_scan + Body3 () {} + Body3 ( const Body3&, tbb::split ) {} + void operator() ( const tbb::blocked_range2d<int>&, tbb::pre_scan_tag ) const {} + void operator() ( const tbb::blocked_range2d<int>&, tbb::final_scan_tag ) const {} + void reverse_join( Body3& ) {} + void assign( const Body3& ) {} +}; +struct Body3a { // for lambda-friednly parallel_scan + int operator() ( const tbb::blocked_range<int>&, const int, bool ) const { return 0; } +}; +struct Msg {}; + +#if !__TBB_TEST_SECONDARY + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" + +// Test if all the necessary symbols are exported for the exceptions thrown by TBB. +// Missing exports result either in link error or in runtime assertion failure. +#include <stdexcept> + +template <typename E> +void TestExceptionClassExports ( const E& exc, tbb::internal::exception_id eid ) { + // The assertion here serves to shut up warnings about "eid not used". + ASSERT( eid<tbb::internal::eid_max, NULL ); +#if TBB_USE_EXCEPTIONS + for ( int i = 0; i < 2; ++i ) { + try { + if ( i == 0 ) + throw exc; +#if !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN + else + tbb::internal::throw_exception( eid ); +#endif + } + catch ( E& e ) { + ASSERT ( e.what(), "Missing what() string" ); + } + catch ( ... ) { + ASSERT ( __TBB_EXCEPTION_TYPE_INFO_BROKEN, "Unrecognized exception. Likely RTTI related exports are missing" ); + } + } +#else /* TBB_USE_EXCEPTIONS */ + (void)exc; +#endif /* TBB_USE_EXCEPTIONS */ +} + +void TestExceptionClassesExports () { + TestExceptionClassExports( std::bad_alloc(), tbb::internal::eid_bad_alloc ); + TestExceptionClassExports( tbb::bad_last_alloc(), tbb::internal::eid_bad_last_alloc ); + TestExceptionClassExports( std::invalid_argument("test"), tbb::internal::eid_nonpositive_step ); + TestExceptionClassExports( std::out_of_range("test"), tbb::internal::eid_out_of_range ); + TestExceptionClassExports( std::range_error("test"), tbb::internal::eid_segment_range_error ); + TestExceptionClassExports( std::range_error("test"), tbb::internal::eid_index_range_error ); + TestExceptionClassExports( tbb::missing_wait(), tbb::internal::eid_missing_wait ); + TestExceptionClassExports( tbb::invalid_multiple_scheduling(), tbb::internal::eid_invalid_multiple_scheduling ); + TestExceptionClassExports( tbb::improper_lock(), tbb::internal::eid_improper_lock ); + TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_possible_deadlock ); + TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_operation_not_permitted ); + TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_condvar_wait_failed ); + TestExceptionClassExports( std::out_of_range("test"), tbb::internal::eid_invalid_load_factor ); + TestExceptionClassExports( std::invalid_argument("test"), tbb::internal::eid_invalid_swap ); + TestExceptionClassExports( std::length_error("test"), tbb::internal::eid_reservation_length_error ); + TestExceptionClassExports( std::out_of_range("test"), tbb::internal::eid_invalid_key ); + TestExceptionClassExports( tbb::user_abort(), tbb::internal::eid_user_abort ); + TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_bad_tagged_msg_cast ); +} +#endif /* !__TBB_TEST_SECONDARY */ + +#if __TBB_CPF_BUILD +// These names are only tested in "preview" configuration +// When a feature becomes fully supported, its names should be moved to the main test +struct Handler { + void operator()( tbb::aggregator_operation* ) {} +}; +static void TestPreviewNames() { + TestTypeDefinitionPresence( aggregator ); + TestTypeDefinitionPresence( aggregator_ext<Handler> ); +#if __TBB_CPP11_PRESENT + TestTypeDefinitionPresence2(blocked_rangeNd<int,4> ); +#endif + TestTypeDefinitionPresence2(concurrent_lru_cache<int, int> ); + TestTypeDefinitionPresence( isolated_task_group ); +#if !__TBB_TEST_SECONDARY + TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_blocking_thread_join_impossible ); +#endif +#if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT + TestTypeDefinitionPresence2(concurrent_map<int, int> ); + TestTypeDefinitionPresence2(concurrent_multimap<int, int> ); + TestTypeDefinitionPresence(concurrent_set<int> ); + TestTypeDefinitionPresence(concurrent_multiset<int> ); +#endif +} +#endif + +#if __TBB_TEST_SECONDARY +/* This mode is used to produce a secondary object file that is linked with + the main one in order to detect "multiple definition" linker error. +*/ +#include "harness_assert.h" +bool Secondary() +#else +bool Secondary(); +int TestMain () +#endif +{ + #if __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN + REPORT("Known issue: \"multiple definition\" linker error detection test skipped.\n"); + #endif + TestTypeDefinitionPresence( aligned_space<int> ); + TestTypeDefinitionPresence( atomic<int> ); + TestTypeDefinitionPresence( cache_aligned_allocator<int> ); + TestTypeDefinitionPresence( tbb_hash_compare<int> ); + TestTypeDefinitionPresence2(concurrent_hash_map<int, int> ); + TestTypeDefinitionPresence2(concurrent_unordered_map<int, int> ); + TestTypeDefinitionPresence2(concurrent_unordered_multimap<int, int> ); + TestTypeDefinitionPresence( concurrent_unordered_set<int> ); + TestTypeDefinitionPresence( concurrent_unordered_multiset<int> ); + TestTypeDefinitionPresence( concurrent_bounded_queue<int> ); + TestTypeDefinitionPresence( concurrent_queue<int> ); + TestTypeDefinitionPresence( strict_ppl::concurrent_queue<int> ); + TestTypeDefinitionPresence( concurrent_priority_queue<int> ); + TestTypeDefinitionPresence( concurrent_vector<int> ); + TestTypeDefinitionPresence( combinable<int> ); + TestTypeDefinitionPresence( enumerable_thread_specific<int> ); + /* Flow graph names */ + TestTypeDefinitionPresence( flow::graph ); + TestTypeDefinitionPresence( flow::continue_msg ); + TestTypeDefinitionPresence2(flow::tagged_msg<int, int> ); + TestFuncDefinitionPresence( flow::make_edge, (tbb::flow::sender<Msg>&, tbb::flow::receiver<Msg>&), void ); + TestFuncDefinitionPresence( flow::remove_edge, (tbb::flow::sender<Msg>&, tbb::flow::receiver<Msg>&), void ); + typedef tbb::flow::tuple<int, int> intpair; + TestTypeDefinitionPresence( flow::source_node<int> ); + TestTypeDefinitionPresence( flow::input_node<int> ); + TestTypeDefinitionPresence3(flow::function_node<int, int, tbb::flow::rejecting> ); + TestTypeDefinitionPresence3(flow::multifunction_node<int, intpair, tbb::flow::queueing> ); + TestTypeDefinitionPresence3(flow::async_node<int, int, tbb::flow::queueing_lightweight> ); + TestTypeDefinitionPresence2(flow::continue_node<int, tbb::flow::lightweight> ); + TestTypeDefinitionPresence2(flow::join_node<intpair, tbb::flow::reserving> ); + TestTypeDefinitionPresence2(flow::join_node<intpair, tbb::flow::key_matching<int> > ); + TestTypeDefinitionPresence( flow::split_node<intpair> ); + TestTypeDefinitionPresence( flow::overwrite_node<int> ); + TestTypeDefinitionPresence( flow::write_once_node<int> ); + TestTypeDefinitionPresence( flow::broadcast_node<int> ); + TestTypeDefinitionPresence( flow::buffer_node<int> ); + TestTypeDefinitionPresence( flow::queue_node<int> ); + TestTypeDefinitionPresence( flow::sequencer_node<int> ); + TestTypeDefinitionPresence( flow::priority_queue_node<int> ); + TestTypeDefinitionPresence( flow::limiter_node<int> ); + TestTypeDefinitionPresence2(flow::indexer_node<int, int> ); +#if __TBB_FLOW_GRAPH_CPP11_FEATURES + TestTypeDefinitionPresence2(flow::composite_node<tbb::flow::tuple<int>, tbb::flow::tuple<int> > ); +#endif + /* Mutex names */ + TestTypeDefinitionPresence( mutex ); + TestTypeDefinitionPresence( null_mutex ); + TestTypeDefinitionPresence( null_rw_mutex ); + TestTypeDefinitionPresence( queuing_mutex ); + TestTypeDefinitionPresence( queuing_rw_mutex ); + TestTypeDefinitionPresence( recursive_mutex ); + TestTypeDefinitionPresence( spin_mutex ); + TestTypeDefinitionPresence( spin_rw_mutex ); + TestTypeDefinitionPresence( speculative_spin_mutex ); + TestTypeDefinitionPresence( speculative_spin_rw_mutex ); + TestTypeDefinitionPresence( critical_section ); + TestTypeDefinitionPresence( reader_writer_lock ); +#if __TBB_TASK_GROUP_CONTEXT + TestTypeDefinitionPresence( tbb_exception ); + TestTypeDefinitionPresence( captured_exception ); + TestTypeDefinitionPresence( movable_exception<int> ); +#if !TBB_USE_CAPTURED_EXCEPTION + TestTypeDefinitionPresence( internal::tbb_exception_ptr ); +#endif /* !TBB_USE_CAPTURED_EXCEPTION */ + TestTypeDefinitionPresence( task_group_context ); + TestTypeDefinitionPresence( task_group ); + TestTypeDefinitionPresence( structured_task_group ); + TestTypeDefinitionPresence( task_handle<Body> ); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + /* Algorithm related names */ + TestTypeDefinitionPresence( blocked_range<int> ); + TestTypeDefinitionPresence( blocked_range2d<int> ); + TestTypeDefinitionPresence( blocked_range3d<int> ); + TestFuncDefinitionPresence( parallel_invoke, (const Body&, const Body&, const Body&), void ); + TestFuncDefinitionPresence( parallel_do, (int*, int*, const Body1&), void ); + TestFuncDefinitionPresence( parallel_for_each, (int*, int*, const Body1&), void ); + TestFuncDefinitionPresence( parallel_for, (int, int, int, const Body1&), void ); + TestFuncDefinitionPresence( parallel_for, (const tbb::blocked_range<int>&, const Body2&, const tbb::simple_partitioner&), void ); + TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, const int&, const Body2a&, const Body1b&), int ); + TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::affinity_partitioner&), void ); + TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, const int&, const Body2a&, const Body1b&), int ); + TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::static_partitioner&), void ); + TestFuncDefinitionPresence( parallel_scan, (const tbb::blocked_range2d<int>&, Body3&, const tbb::auto_partitioner&), void ); + TestFuncDefinitionPresence( parallel_scan, (const tbb::blocked_range<int>&, const int&, const Body3a&, const Body1b&), int ); + typedef int intarray[10]; + TestFuncDefinitionPresence( parallel_sort, (int*, int*), void ); + TestFuncDefinitionPresence( parallel_sort, (intarray&, const Body1b&), void ); + TestTypeDefinitionPresence( pipeline ); + TestFuncDefinitionPresence( parallel_pipeline, (size_t, const tbb::filter_t<void,void>&), void ); +#if __TBB_TASK_GROUP_CONTEXT + TestFuncDefinitionPresence( parallel_invoke, (const Body&, const Body&, tbb::task_group_context&), void ); + TestFuncDefinitionPresence( parallel_do, (const intarray&, const Body1a&, tbb::task_group_context&), void ); + TestFuncDefinitionPresence( parallel_for_each, (const intarray&, const Body1&, tbb::task_group_context&), void ); + TestFuncDefinitionPresence( parallel_for, (int, int, const Body1&, const tbb::auto_partitioner&, tbb::task_group_context&), void ); + TestFuncDefinitionPresence( parallel_for, (int, int, const Body1&, tbb::task_group_context&), void ); + TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::auto_partitioner&, tbb::task_group_context&), void ); + TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::task_group_context&), void ); + TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::simple_partitioner&, tbb::task_group_context&), void ); + TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::task_group_context&), void ); +#endif /* __TBB_TASK_GROUP_CONTEXT */ + TestTypeDefinitionPresence( proportional_split ); + + TestTypeDefinitionPresence( task ); + TestTypeDefinitionPresence( empty_task ); + TestTypeDefinitionPresence( task_list ); + TestTypeDefinitionPresence( task_arena ); + TestFuncDefinitionPresence( this_task_arena::current_thread_index, (), int ); + TestFuncDefinitionPresence( this_task_arena::max_concurrency, (), int ); +#if !__TBB_GCC_OVERLOADED_TEMPLATE_FUNCTION_ADDRESS_BROKEN + TestFuncDefinitionPresence( this_task_arena::isolate, (const Body&), void ); +#endif + TestTypeDefinitionPresence( task_scheduler_init ); + TestTypeDefinitionPresence( task_scheduler_observer ); + TestTypeDefinitionPresence( tbb_thread ); + TestFuncDefinitionPresence( tbb_thread::hardware_concurrency, (), unsigned ); + TestFuncDefinitionPresence( this_tbb_thread::yield, (), void ); + TestTypeDefinitionPresence( tbb_allocator<int> ); + TestTypeDefinitionPresence( zero_allocator<int> ); + TestTypeDefinitionPresence( tick_count ); + TestTypeDefinitionPresence( global_control ); +#if __TBB_CPP11_PRESENT + TestTypeDefinitionPresence( counting_iterator<int> ); + TestTypeDefinitionPresence2(zip_iterator<int*,int*> ); +#endif + +#if __TBB_CPF_BUILD + TestPreviewNames(); +#endif +#ifdef DO_TEST_DEBUG_MACRO +#if TBB_USE_DEBUG + ASSERT( isDebugExpected, "Debug mode is observed while release mode is expected." ); +#else + ASSERT( !isDebugExpected, "Release mode is observed while debug mode is expected." ); +#endif /* TBB_USE_DEBUG */ +#endif /* DO_TEST_DEBUG_MACRO */ +#if __TBB_TEST_SECONDARY + return true; +#else + TestExceptionClassesExports(); + Secondary(); + return Harness::Done; +#endif /* __TBB_TEST_SECONDARY */ +} +#endif //!(__TBB_TEST_SECONDARY && __TBB_CPP11_STD_PLACEHOLDERS_LINKING_BROKEN) diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_thread.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_thread.cpp new file mode 100644 index 00000000..878353b7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_thread.cpp @@ -0,0 +1,29 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_thread.h" +#define THREAD tbb::tbb_thread +#define THIS_THREAD tbb::this_tbb_thread +#define THIS_THREAD_SLEEP THIS_THREAD::sleep +#include "test_thread.h" +#include "harness.h" + +/* we want to test tbb::tbb_thread */ +int TestMain () { + CheckSignatures(); + RunTests(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_version.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_version.cpp new file mode 100644 index 00000000..9032fc5e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tbb_version.cpp @@ -0,0 +1,284 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tbb_stddef.h" + +#if __TBB_WIN8UI_SUPPORT +// TODO: figure out how the test can be enabled for win8ui +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness.h" +int TestMain() { + return Harness::Skipped; +} +#else + +#include <stdio.h> +#include <stdlib.h> +#include <vector> +#include <string> +#include <utility> + +#include "tbb/task_scheduler_init.h" + +#define HARNESS_CUSTOM_MAIN 1 +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#define HARNESS_NO_MAIN_ARGS 0 +#include "harness.h" + +#if defined (_WIN32) || defined (_WIN64) +#define TEST_SYSTEM_COMMAND "test_tbb_version.exe @" +#elif __APPLE__ +// DYLD_LIBRARY_PATH is purged for OS X 10.11, set it again +#define TEST_SYSTEM_COMMAND "DYLD_LIBRARY_PATH=. ./test_tbb_version.exe @" +#else +#define TEST_SYSTEM_COMMAND "./test_tbb_version.exe @" +#endif + +enum string_required { + required, + optional, + optional_multiple + }; + +typedef std::pair <std::string, string_required> string_pair; + +void initialize_strings_vector(std::vector <string_pair>* vector); + +const char stderr_stream[] = "version_test.err"; +const char stdout_stream[] = "version_test.out"; + +HARNESS_EXPORT +int main(int argc, char *argv[] ) { + const size_t psBuffer_len = 2048; + char psBuffer[psBuffer_len]; +/* We first introduced runtime version identification in 3014 */ +#if TBB_INTERFACE_VERSION>=3014 + // For now, just test that run-time TBB version matches the compile-time version, + // since otherwise the subsequent test of "TBB: INTERFACE VERSION" string will fail anyway. + // We need something more clever in future. + if ( tbb::TBB_runtime_interface_version()!=TBB_INTERFACE_VERSION ){ + snprintf( psBuffer, psBuffer_len, + "%s %s %d %s %d.", + "Running with the library of different version than the test was compiled against.", + "Expected", + TBB_INTERFACE_VERSION, + "- got", + tbb::TBB_runtime_interface_version() + ); + ASSERT( tbb::TBB_runtime_interface_version()==TBB_INTERFACE_VERSION, psBuffer ); + } +#endif +#if __TBB_MIC_OFFLOAD + // Skip the test in offload mode. + // Run the test in 'true' native mode (because 'system()' works in 'true' native mode). + (argc, argv); + REPORT("skip\n"); +#elif __TBB_MPI_INTEROP || __bg__ + (void) argc; // unused + (void) argv; // unused + REPORT("skip\n"); +#else + __TBB_TRY { + FILE *stream_out; + FILE *stream_err; + + if(argc>1 && argv[1][0] == '@' ) { + stream_err = freopen( stderr_stream, "w", stderr ); + if( stream_err == NULL ){ + REPORT( "Internal test error (freopen)\n" ); + exit( 1 ); + } + stream_out = freopen( stdout_stream, "w", stdout ); + if( stream_out == NULL ){ + REPORT( "Internal test error (freopen)\n" ); + exit( 1 ); + } + { + tbb::task_scheduler_init init(1); + } + fclose( stream_out ); + fclose( stream_err ); + exit(0); + } + //1st step check that output is empty if TBB_VERSION is not defined. + if ( getenv("TBB_VERSION") ){ + REPORT( "TBB_VERSION defined, skipping step 1 (empty output check)\n" ); + }else{ + if( ( system(TEST_SYSTEM_COMMAND) ) != 0 ){ + REPORT( "Error (step 1): Internal test error\n" ); + exit( 1 ); + } + //Checking output streams - they should be empty + stream_err = fopen( stderr_stream, "r" ); + if( stream_err == NULL ){ + REPORT( "Error (step 1):Internal test error (stderr open)\n" ); + exit( 1 ); + } + while( !feof( stream_err ) ) { + if( fgets( psBuffer, psBuffer_len, stream_err ) != NULL ){ + REPORT( "Error (step 1): stderr should be empty\n" ); + exit( 1 ); + } + } + fclose( stream_err ); + stream_out = fopen( stdout_stream, "r" ); + if( stream_out == NULL ){ + REPORT( "Error (step 1):Internal test error (stdout open)\n" ); + exit( 1 ); + } + while( !feof( stream_out ) ) { + if( fgets( psBuffer, psBuffer_len, stream_out ) != NULL ){ + REPORT( "Error (step 1): stdout should be empty\n" ); + exit( 1 ); + } + } + fclose( stream_out ); + } + + //Setting TBB_VERSION in case it is not set + if ( !getenv("TBB_VERSION") ){ + Harness::SetEnv("TBB_VERSION","1"); + } + + if( ( system(TEST_SYSTEM_COMMAND) ) != 0 ){ + REPORT( "Error (step 2):Internal test error\n" ); + exit( 1 ); + } + //Checking pipe - it should contain version data + std::vector <string_pair> strings_vector; + std::vector <string_pair>::iterator strings_iterator; + + initialize_strings_vector( &strings_vector ); + strings_iterator = strings_vector.begin(); + + stream_out = fopen( stdout_stream, "r" ); + if( stream_out == NULL ){ + REPORT( "Error (step 2):Internal test error (stdout open)\n" ); + exit( 1 ); + } + while( !feof( stream_out ) ) { + if( fgets( psBuffer, psBuffer_len, stream_out ) != NULL ){ + REPORT( "Error (step 2): stdout should be empty\n" ); + exit( 1 ); + } + } + fclose( stream_out ); + + stream_err = fopen( stderr_stream, "r" ); + if( stream_err == NULL ){ + REPORT( "Error (step 1):Internal test error (stderr open)\n" ); + exit( 1 ); + } + + while( !feof( stream_err ) ) { + if( fgets( psBuffer, psBuffer_len, stream_err ) != NULL ){ + if (strstr( psBuffer, "TBBmalloc: " )) { + // TBB allocator might or might not be here, ignore it + continue; + } + bool match_found = false; + do{ + if ( strings_iterator == strings_vector.end() ){ + REPORT( "Error: version string dictionary ended prematurely.\n" ); + REPORT( "No match for: \t%s", psBuffer ); + exit( 1 ); + } + if ( strstr( psBuffer, strings_iterator->first.c_str() ) == NULL ){ // mismatch + if( strings_iterator->second == required ){ + REPORT( "Error: version strings do not match.\n" ); + REPORT( "Expected \"%s\" not found in:\n\t%s", strings_iterator->first.c_str(), psBuffer ); + exit( 1 ); + } + ++strings_iterator; + }else{ + match_found = true; + if( strings_iterator->second != optional_multiple ) + ++strings_iterator; + } + }while( !match_found ); + } + } + fclose( stream_err ); + } __TBB_CATCH(...) { + ASSERT( 0,"unexpected exception" ); + } + REPORT("done\n"); +#endif //__TBB_MIC_OFFLOAD, __TBB_MPI_INTEROP etc + return 0; +} + + +// Fill dictionary with version strings for platforms +void initialize_strings_vector(std::vector <string_pair>* vector) +{ + vector->push_back(string_pair("TBB: VERSION\t\t2020.3", required)); // check TBB_VERSION + vector->push_back(string_pair("TBB: INTERFACE VERSION\t11103", required)); // check TBB_INTERFACE_VERSION + vector->push_back(string_pair("TBB: BUILD_DATE", required)); + vector->push_back(string_pair("TBB: BUILD_HOST", required)); + vector->push_back(string_pair("TBB: BUILD_OS", required)); +#if _WIN32||_WIN64 +#if !__MINGW32__ + vector->push_back(string_pair("TBB: BUILD_CL", required)); + vector->push_back(string_pair("TBB: BUILD_COMPILER", required)); +#else + vector->push_back(string_pair("TBB: BUILD_GCC", required)); +#endif +#elif __APPLE__ + vector->push_back(string_pair("TBB: BUILD_KERNEL", required)); + vector->push_back(string_pair("TBB: BUILD_CLANG", required)); + vector->push_back(string_pair("TBB: BUILD_XCODE", optional)); + vector->push_back(string_pair("TBB: BUILD_COMPILER", optional)); //if( getenv("COMPILER_VERSION") ) +#elif __sun + vector->push_back(string_pair("TBB: BUILD_KERNEL", required)); + vector->push_back(string_pair("TBB: BUILD_SUNCC", required)); + vector->push_back(string_pair("TBB: BUILD_COMPILER", optional)); //if( getenv("COMPILER_VERSION") ) +#else // We use version_info_linux.sh for unsupported OSes +#if !__ANDROID__ + vector->push_back(string_pair("TBB: BUILD_KERNEL", required)); +#endif + vector->push_back(string_pair("TBB: BUILD_GCC", optional)); + vector->push_back(string_pair("TBB: BUILD_CLANG", optional)); + vector->push_back(string_pair("TBB: BUILD_TARGET_CXX", optional)); + vector->push_back(string_pair("TBB: BUILD_COMPILER", optional)); //if( getenv("COMPILER_VERSION") ) +#if __ANDROID__ + vector->push_back(string_pair("TBB: BUILD_NDK", optional)); + vector->push_back(string_pair("TBB: BUILD_LD", optional)); +#else + vector->push_back(string_pair("TBB: BUILD_LIBC", required)); + vector->push_back(string_pair("TBB: BUILD_LD", required)); +#endif // !__ANDROID__ +#endif // OS + vector->push_back(string_pair("TBB: BUILD_TARGET", required)); + vector->push_back(string_pair("TBB: BUILD_COMMAND", required)); + vector->push_back(string_pair("TBB: TBB_USE_DEBUG", required)); + vector->push_back(string_pair("TBB: TBB_USE_ASSERT", required)); +#if __TBB_CPF_BUILD + vector->push_back(string_pair("TBB: TBB_PREVIEW_BINARY", required)); +#endif + vector->push_back(string_pair("TBB: DO_ITT_NOTIFY", required)); + vector->push_back(string_pair("TBB: ITT", optional)); //#ifdef DO_ITT_NOTIFY + vector->push_back(string_pair("TBB: ALLOCATOR", required)); +#if _WIN32||_WIN64 + vector->push_back(string_pair("TBB: Processor groups", required)); + vector->push_back(string_pair("TBB: ----- Group", optional_multiple)); +#endif + vector->push_back(string_pair("TBB: RML", optional)); + vector->push_back(string_pair("TBB: Intel(R) RML library built:", optional)); + vector->push_back(string_pair("TBB: Intel(R) RML library version:", optional)); + vector->push_back(string_pair("TBB: Tools support", required)); + return; +} +#endif /* __TBB_WIN8UI_SUPPORT */ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_thread.h b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_thread.h new file mode 100644 index 00000000..3d8f95eb --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_thread.h @@ -0,0 +1,305 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/atomic.h" +#if __TBB_CPP11_RVALUE_REF_PRESENT +#include <utility> // std::move +#endif + +#define HARNESS_NO_PARSE_COMMAND_LINE 1 +#include "harness_report.h" +#include "harness_assert.h" + +bool CheckSignatures() { + // Checks that thread ids can be compared, in the way users would do it + THREAD::id id1, id2; + bool result = id1 == id2; + result |= id1 != id2; + result |= id1 < id2; + result |= id1 > id2; + result |= id1 <= id2; + result |= id1 >= id2; + tbb::tbb_hash<THREAD::id> hash; + return result |= hash(id1)==hash(id2); +} + +static const int THRDS = 3; +static const int THRDS_DETACH = 2; +static tbb::atomic<int> sum; +static tbb::atomic<int> BaseCount; +static THREAD::id real_ids[THRDS+THRDS_DETACH]; + +class Base { + mutable int copy_throws; + friend void RunTests(); + friend void CheckExceptionSafety(); + void operator=( const Base& ); // Deny access +protected: + Base() : copy_throws(100) {++BaseCount;} + Base( const Base& c ) : copy_throws(c.copy_throws) { + if( --copy_throws<=0 ) + __TBB_THROW(0); + ++BaseCount; + } + ~Base() {--BaseCount;} +}; + +template<int N> +class Data: Base { + Data(); // Deny access + explicit Data(int v) : value(v) {} + + friend void RunTests(); + friend void CheckExceptionSafety(); +public: + int value; +}; + +#include "harness_barrier.h" + +class ThreadFunc: Base { + ThreadFunc() {} + + static Harness::SpinBarrier init_barrier; + + friend void RunTests(); +public: + void operator()(){ + real_ids[0] = THIS_THREAD::get_id(); + init_barrier.wait(); + + sum.fetch_and_add(1); + } + void operator()(int num){ + real_ids[num] = THIS_THREAD::get_id(); + init_barrier.wait(); + + sum.fetch_and_add(num); + } + void operator()(int num, Data<0> dx) { + real_ids[num] = THIS_THREAD::get_id(); + + const double WAIT = .1; +#if _WIN32 || _WIN64 + const double LONG_TOLERANCE = 0.120; // maximal scheduling quantum for Windows Server +#else + const double LONG_TOLERANCE = 0.200; // reasonable upper bound +#endif + tbb::tick_count::interval_t test_interval(WAIT); + tbb::tick_count t0 = tbb::tick_count::now(); + THIS_THREAD_SLEEP ( test_interval ); + tbb::tick_count t1 = tbb::tick_count::now(); + double delta = ((t1-t0)-test_interval).seconds(); + if(delta < 0.0) + REPORT("ERROR: Sleep interval too short (%g < %g)\n", + (t1-t0).seconds(), test_interval.seconds() ); + if(delta > LONG_TOLERANCE) + REPORT("Warning: Sleep interval too long (%g outside long tolerance(%g))\n", + (t1-t0).seconds(), test_interval.seconds() + LONG_TOLERANCE); + init_barrier.wait(); + + sum.fetch_and_add(num); + sum.fetch_and_add(dx.value); + } + void operator()(Data<0> d) { + THIS_THREAD_SLEEP ( tbb::tick_count::interval_t(d.value*1.) ); + } +}; + +Harness::SpinBarrier ThreadFunc::init_barrier(THRDS); + +void CheckRelations( const THREAD::id ids[], int n, bool duplicates_allowed ) { + for( int i=0; i<n; ++i ) { + const THREAD::id x = ids[i]; + for( int j=0; j<n; ++j ) { + const THREAD::id y = ids[j]; + ASSERT( (x==y)==!(x!=y), NULL ); + ASSERT( (x<y)==!(x>=y), NULL ); + ASSERT( (x>y)==!(x<=y), NULL ); + ASSERT( (x<y)+(x==y)+(x>y)==1, NULL ); + ASSERT( x!=y || i==j || duplicates_allowed, NULL ); + for( int k=0; k<n; ++k ) { + const THREAD::id z = ids[j]; + ASSERT( !(x<y && y<z) || x<z, "< is not transitive" ); + } + } + } +} + +class AnotherThreadFunc: Base { +public: + void operator()() {} + void operator()(const Data<1>&) {} + void operator()(const Data<1>&, const Data<2>&) {} + friend void CheckExceptionSafety(); +}; + +#if TBB_USE_EXCEPTIONS +void CheckExceptionSafety() { + int original_count = BaseCount; + // d loops over number of copies before throw occurs + for( int d=1; d<=3; ++d ) { + // Try all combinations of throw/nothrow for f, x, and y's copy constructor. + for( int i=0; i<8; ++i ) { + { + const AnotherThreadFunc f = AnotherThreadFunc(); + if( i&1 ) f.copy_throws = d; + const Data<1> x(0); + if( i&2 ) x.copy_throws = d; + const Data<2> y(0); + if( i&4 ) y.copy_throws = d; + bool exception_caught = false; + for( int j=0; j<3; ++j ) { + try { + switch(j) { + case 0: {THREAD t(f); t.join();} break; + case 1: {THREAD t(f,x); t.join();} break; + case 2: {THREAD t(f,x,y); t.join();} break; + } + } catch(...) { + exception_caught = true; + } + ASSERT( !exception_caught||(i&((1<<(j+1))-1))!=0, NULL ); + } + } + ASSERT( BaseCount==original_count, "object leak detected" ); + } + } +} +#endif /* TBB_USE_EXCEPTIONS */ + +#include <cstdio> + +#if __TBB_CPP11_RVALUE_REF_PRESENT +THREAD returnThread() { + return THREAD(); +} +#endif + +void RunTests() { + + ThreadFunc t; + Data<0> d100(100), d1(1), d0(0); + const THREAD::id id_zero; + THREAD::id id0, uniq_ids[THRDS]; + + THREAD thrs[THRDS]; + THREAD thr; + THREAD thr0(t); + THREAD thr1(t, 2); + THREAD thr2(t, 1, d100); + + ASSERT( thr0.get_id() != id_zero, NULL ); + id0 = thr0.get_id(); + tbb::move(thrs[0], thr0); + ASSERT( thr0.get_id() == id_zero, NULL ); + ASSERT( thrs[0].get_id() == id0, NULL ); + + THREAD::native_handle_type h1 = thr1.native_handle(); + THREAD::native_handle_type h2 = thr2.native_handle(); + THREAD::id id1 = thr1.get_id(); + THREAD::id id2 = thr2.get_id(); + tbb::swap(thr1, thr2); + ASSERT( thr1.native_handle() == h2, NULL ); + ASSERT( thr2.native_handle() == h1, NULL ); + ASSERT( thr1.get_id() == id2, NULL ); + ASSERT( thr2.get_id() == id1, NULL ); +#if __TBB_CPP11_RVALUE_REF_PRESENT + { + THREAD tmp_thr(std::move(thr1)); + ASSERT( tmp_thr.native_handle() == h2 && tmp_thr.get_id() == id2, NULL ); + thr1 = std::move(tmp_thr); + ASSERT( thr1.native_handle() == h2 && thr1.get_id() == id2, NULL ); + } +#endif + + thr1.swap(thr2); + ASSERT( thr1.native_handle() == h1, NULL ); + ASSERT( thr2.native_handle() == h2, NULL ); + ASSERT( thr1.get_id() == id1, NULL ); + ASSERT( thr2.get_id() == id2, NULL ); + thr1.swap(thr2); + + tbb::move(thrs[1], thr1); + ASSERT( thr1.get_id() == id_zero, NULL ); + +#if __TBB_CPP11_RVALUE_REF_PRESENT + thrs[2] = returnThread(); + ASSERT( thrs[2].get_id() == id_zero, NULL ); +#endif + tbb::move(thrs[2], thr2); + ASSERT( thr2.get_id() == id_zero, NULL ); + + for (int i=0; i<THRDS; i++) + uniq_ids[i] = thrs[i].get_id(); + + ASSERT( thrs[2].joinable(), NULL ); + + for (int i=0; i<THRDS; i++) + thrs[i].join(); + +#if !__TBB_WIN8UI_SUPPORT + // TODO: to find out the way to find thread_id without GetThreadId and other + // desktop functions. + // Now tbb_thread does have its own thread_id that stores std::thread object + // Test will fail in case it is run in desktop mode against New Windows*8 UI library + for (int i=0; i<THRDS; i++) + ASSERT( real_ids[i] == uniq_ids[i], NULL ); +#endif + + int current_sum = sum; + ASSERT( current_sum == 104, NULL ); + ASSERT( ! thrs[2].joinable(), NULL ); + ASSERT( BaseCount==4, "object leak detected" ); + +#if TBB_USE_EXCEPTIONS + CheckExceptionSafety(); +#endif + + // Note: all tests involving BaseCount should be put before the tests + // involing detached threads, because there is no way of knowing when + // a detached thread destroys its arguments. + + THREAD thr_detach_0(t, d0); + real_ids[THRDS] = thr_detach_0.get_id(); + thr_detach_0.detach(); + ASSERT( thr_detach_0.get_id() == id_zero, NULL ); + + THREAD thr_detach_1(t, d1); + real_ids[THRDS+1] = thr_detach_1.get_id(); + thr_detach_1.detach(); + ASSERT( thr_detach_1.get_id() == id_zero, NULL ); + + CheckRelations(real_ids, THRDS+THRDS_DETACH, true); + + CheckRelations(uniq_ids, THRDS, false); + + for (int i=0; i<2; i++) { + AnotherThreadFunc empty_func; + THREAD thr_to(empty_func), thr_from(empty_func); + THREAD::id from_id = thr_from.get_id(); + if (i) thr_to.join(); +#if __TBB_CPP11_RVALUE_REF_PRESENT + thr_to = std::move(thr_from); +#else + thr_to = thr_from; +#endif + ASSERT( thr_from.get_id() == THREAD::id(), NULL ); + ASSERT( thr_to.get_id() == from_id, NULL ); + } + + ASSERT( THREAD::hardware_concurrency() > 0, NULL); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tick_count.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tick_count.cpp new file mode 100644 index 00000000..19018156 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tick_count.cpp @@ -0,0 +1,199 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "tbb/tick_count.h" +#include "harness_assert.h" + +//! Assert that two times in seconds are very close. +void AssertNear( double x, double y ) { + ASSERT( -1.0E-10 <= x-y && x-y <=1.0E-10, NULL ); +} + +//! Test arithmetic operators on tick_count::interval_t +void TestArithmetic( const tbb::tick_count& t0, const tbb::tick_count& t1, const tbb::tick_count& t2 ) { + tbb::tick_count::interval_t i= t1-t0; + tbb::tick_count::interval_t j = t2-t1; + tbb::tick_count::interval_t k = t2-t0; + AssertSameType( tbb::tick_count::interval_t(), i-j ); + AssertSameType( tbb::tick_count::interval_t(), i+j ); + ASSERT( i.seconds()>1E-9, NULL ); + ASSERT( j.seconds()>1E-9, NULL ); + ASSERT( k.seconds()>2E-9, NULL ); + AssertNear( (i+j).seconds(), k.seconds() ); + AssertNear( (k-j).seconds(), i.seconds() ); + AssertNear( ((k-j)+(j-i)).seconds(), k.seconds()-i.seconds() ); + tbb::tick_count::interval_t sum; + sum += i; + sum += j; + AssertNear( sum.seconds(), k.seconds() ); + sum -= i; + AssertNear( sum.seconds(), j.seconds() ); + sum -= j; + AssertNear( sum.seconds(), 0.0 ); +} + +//------------------------------------------------------------------------ +// Test for overhead in calls to tick_count +//------------------------------------------------------------------------ + +//! Wait for given duration. +/** The duration parameter is in units of seconds. */ +static void WaitForDuration( double duration ) { + tbb::tick_count start = tbb::tick_count::now(); + while( (tbb::tick_count::now()-start).seconds() < duration ) + continue; +} + +#include "harness.h" + +//! Test that average timer overhead is within acceptable limit. +/** The 'tolerance' value inside the test specifies the limit. */ +void TestSimpleDelay( int ntrial, double duration, double tolerance ) { + int error_count = 0; + double delta = 0; + // Iteration -1 warms up the code cache. + for( int trial=-1; trial<ntrial; ++trial ) { + tbb::tick_count t = tbb::tick_count::now(); + if( duration ) WaitForDuration(duration); + delta = (tbb::tick_count::now() - t).seconds() - duration; + if( trial>=0 && delta > tolerance ) { + error_count++; + } + ASSERT(delta >= 0,"Delta is negative"); + } + ASSERT(error_count < ntrial / 4, "The number of errors exceeded the threshold"); +} + +//------------------------------------------------------------------------ +// Test for subtracting calls to tick_count from different threads. +//------------------------------------------------------------------------ + +#include "tbb/atomic.h" +static tbb::atomic<int> Counter1, Counter2; +static tbb::atomic<bool> Flag1, Flag2; +static tbb::tick_count *tick_count_array; +static double barrier_time; + +struct TickCountDifferenceBody { + TickCountDifferenceBody( int num_threads ) { + Counter1 = Counter2 = num_threads; + Flag1 = Flag2 = false; + } + void operator()( int id ) const { + bool last = false; + // The first barrier. + if ( --Counter1 == 0 ) last = true; + while ( !last && !Flag1.load<tbb::acquire>() ) __TBB_Pause( 1 ); + // Save a time stamp of the first barrier releasing. + tick_count_array[id] = tbb::tick_count::now(); + + // The second barrier. + if ( --Counter2 == 0 ) Flag2.store<tbb::release>(true); + // The last thread should release threads from the first barrier after it reaches the second + // barrier to avoid a deadlock. + if ( last ) Flag1.store<tbb::release>(true); + // After the last thread releases threads from the first barrier it waits for a signal from + // the second barrier. + while ( !Flag2.load<tbb::acquire>() ) __TBB_Pause( 1 ); + + if ( last ) + // We suppose that the barrier time is a time interval between the moment when the last + // thread reaches the first barrier and the moment when the same thread is released from + // the second barrier. This time is not accurate time of two barriers but it is + // guaranteed that it does not exceed it. + barrier_time = (tbb::tick_count::now() - tick_count_array[id]).seconds() / 2; + } + ~TickCountDifferenceBody() { + ASSERT( Counter1 == 0 && Counter2 == 0, NULL ); + } +}; + +//! Test that two tick_count values recorded on different threads can be meaningfully subtracted. +void TestTickCountDifference( int n ) { + const double tolerance = 3E-4; + tick_count_array = new tbb::tick_count[n]; + + int num_trials = 0; + tbb::tick_count start_time = tbb::tick_count::now(); + do { + NativeParallelFor( n, TickCountDifferenceBody( n ) ); + if ( barrier_time > tolerance ) + // The machine seems to be oversubscribed so skip the test. + continue; + for ( int i = 0; i < n; ++i ) { + for ( int j = 0; j < i; ++j ) { + double diff = (tick_count_array[i] - tick_count_array[j]).seconds(); + if ( diff < 0 ) diff = -diff; + if ( diff > tolerance ) + REPORT( "Warning: cross-thread tick_count difference = %g > %g = tolerance\n", diff, tolerance ); + ASSERT( diff < 3 * tolerance, "Too big difference." ); + } + } + // During 5 seconds we are trying to get 10 successful trials. + } while ( ++num_trials < 10 && (tbb::tick_count::now() - start_time).seconds() < 5 ); + REMARK( "Difference test time: %g sec\n", (tbb::tick_count::now() - start_time).seconds() ); + // TODO: Find the cause of the machine high load, fix it and upgrade ASSERT_WARNING to ASSERT + ASSERT_WARNING( num_trials == 10, "The machine seems to be heavily oversubscribed, difference test was skipped." ); + delete[] tick_count_array; +} + +void TestResolution() { + static double target_value = 0.314159265358979323846264338327950288419; + static double step_value = 0.00027182818284590452353602874713526624977572; + static int range_value = 100; + double avg_diff = 0.0; + double max_diff = 0.0; + for( int i = -range_value; i <= range_value; ++i ) { + double my_time = target_value + step_value * i; + tbb::tick_count::interval_t t0(my_time); + double interval_time = t0.seconds(); + avg_diff += (my_time - interval_time); + if ( max_diff < my_time-interval_time) max_diff = my_time-interval_time; + // time always truncates + ASSERT(interval_time >= 0 && my_time - interval_time < tbb::tick_count::resolution(), "tick_count resolution out of range"); + } + avg_diff = (avg_diff/(2*range_value+1))/tbb::tick_count::resolution(); + max_diff /= tbb::tick_count::resolution(); + REMARK("avg_diff = %g ticks, max_diff = %g ticks\n", avg_diff, max_diff); +} + +#include "tbb/tbb_thread.h" + +int TestMain () { + // Increased tolerance for Virtual Machines + double tolerance_multiplier = Harness::GetEnv( "VIRTUAL_MACHINE" ) ? 50. : 1.; + REMARK( "tolerance_multiplier = %g \n", tolerance_multiplier ); + + tbb::tick_count t0 = tbb::tick_count::now(); + TestSimpleDelay(/*ntrial=*/1000000,/*duration=*/0, /*tolerance=*/6E-6 * tolerance_multiplier); + tbb::tick_count t1 = tbb::tick_count::now(); + TestSimpleDelay(/*ntrial=*/1000, /*duration=*/0.001,/*tolerance=*/15E-6 * tolerance_multiplier); + tbb::tick_count t2 = tbb::tick_count::now(); + TestArithmetic(t0,t1,t2); + + TestResolution(); + + int num_threads = tbb::tbb_thread::hardware_concurrency(); + ASSERT( num_threads > 0, "tbb::thread::hardware_concurrency() has returned an incorrect value" ); + if ( num_threads > 1 ) { + REMARK( "num_threads = %d\n", num_threads ); + TestTickCountDifference( num_threads ); + } else { + REPORT( "Warning: concurrency is too low for TestTickCountDifference ( num_threads = %d )\n", num_threads ); + } + + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tuple.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tuple.cpp new file mode 100644 index 00000000..8708d373 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_tuple.cpp @@ -0,0 +1,200 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// tbb::flow::tuple (implementation used in tbb::flow) +// if <tuple> is available on the compiler/platform, that version should be the +// one tested. + +#include "harness.h" +// this test should match that in graph.h, so we test whatever tuple is +// being used by the join_node. +#if __TBB_CPP11_TUPLE_PRESENT +#define __TESTING_STD_TUPLE__ 1 +#include <tuple> +using namespace std; +#else +#define __TESTING_STD_TUPLE__ 0 +#include "tbb/compat/tuple" +using namespace tbb::flow; +#endif /*!__TBB_CPP11_TUPLE_PRESENT*/ +#include <string> +#include <iostream> + +class non_trivial { +public: + non_trivial() {} + ~non_trivial() {} + non_trivial(const non_trivial& other) : my_int(other.my_int), my_float(other.my_float) { } + int get_int() const { return my_int; } + float get_float() const { return my_float; } + void set_int(int newval) { my_int = newval; } + void set_float(float newval) { my_float = newval; } +private: + int my_int; + float my_float; +}; + +template<typename T1, typename T2, typename T3, typename U1, typename U2, typename U3> +void RunOneComparisonTest() { + typedef tuple<T1,T2,T3> t_tuple; + typedef tuple<U1,U2,U3> u_tuple; + + ASSERT(t_tuple((T1)1,(T2)1,(T3)1) == u_tuple((U1)1,(U2)1,(U3)1),NULL); + ASSERT(t_tuple((T1)1,(T2)0,(T3)1) < u_tuple((U1)1,(U2)1,(U3)1),NULL); + ASSERT(t_tuple((T1)1,(T2)1,(T3)1) > u_tuple((U1)1,(U2)1,(U3)0),NULL); + ASSERT(t_tuple((T1)1,(T2)0,(T3)1) != u_tuple((U1)1,(U2)1,(U3)1),NULL); + ASSERT(t_tuple((T1)1,(T2)0,(T3)1) <= u_tuple((U1)1,(U2)1,(U3)0),NULL); + ASSERT(t_tuple((T1)1,(T2)0,(T3)0) <= u_tuple((U1)1,(U2)0,(U3)0),NULL); + ASSERT(t_tuple((T1)1,(T2)1,(T3)1) >= u_tuple((U1)1,(U2)0,(U3)1),NULL); + ASSERT(t_tuple((T1)0,(T2)1,(T3)1) >= u_tuple((U1)0,(U2)1,(U3)1),NULL); + + ASSERT(!(t_tuple((T1)2,(T2)1,(T3)1) == u_tuple((U1)1,(U2)1,(U3)1)),NULL); + ASSERT(!(t_tuple((T1)1,(T2)2,(T3)1) == u_tuple((U1)1,(U2)1,(U3)1)),NULL); + ASSERT(!(t_tuple((T1)1,(T2)1,(T3)2) == u_tuple((U1)1,(U2)1,(U3)1)),NULL); + + ASSERT(!(t_tuple((T1)1,(T2)1,(T3)1) < u_tuple((U1)1,(U2)1,(U3)1)),NULL); + ASSERT(!(t_tuple((T1)1,(T2)1,(T3)1) > u_tuple((U1)1,(U2)1,(U3)1)),NULL); + ASSERT(!(t_tuple((T1)1,(T2)1,(T3)1) != u_tuple((U1)1,(U2)1,(U3)1)),NULL); + + ASSERT(t_tuple((T1)1,(T2)1,(T3)1) <= u_tuple((U1)1,(U2)1,(U3)1),NULL); + ASSERT(t_tuple((T1)1,(T2)1,(T3)1) >= u_tuple((U1)1,(U2)1,(U3)1),NULL); + +} + +#include "harness_defs.h" + +void RunTests() { + +#if __TESTING_STD_TUPLE__ + REMARK("Testing platform tuple\n"); +#else + REMARK("Testing compat/tuple\n"); +#endif + tuple<int> ituple1(3); + tuple<int> ituple2(5); + tuple<double> ftuple2(4.1); + + ASSERT(!(ituple1 == ituple2), NULL); + ASSERT(ituple1 != ituple2, NULL); + ASSERT(!(ituple1 > ituple2), NULL); + ASSERT(ituple1 < ituple2, NULL); + ASSERT(ituple1 <= ituple2, NULL); + ASSERT(!(ituple1 >= ituple2), NULL); + ASSERT(ituple1 < ftuple2, NULL); + + typedef tuple<int,double,float> tuple_type1; + typedef tuple<int,int,int> int_tuple_type; + typedef tuple<int,non_trivial,int> non_trivial_tuple_type; + typedef tuple<double,std::string,char> stringy_tuple_type; + const tuple_type1 tup1(42,3.14159,2.0f); + int_tuple_type int_tup(4, 5, 6); + non_trivial_tuple_type nti; + stringy_tuple_type stv; + get<1>(stv) = "hello"; + get<2>(stv) = 'x'; + + ASSERT(get<0>(stv) == 0.0, NULL); + ASSERT(get<1>(stv) == "hello", NULL); + ASSERT(get<2>(stv) == 'x', NULL); + + ASSERT(tuple_size<tuple_type1>::value == 3, NULL); + ASSERT(get<0>(tup1) == 42, NULL); + ASSERT(get<1>(tup1) == 3.14159, NULL); + ASSERT(get<2>(tup1) == 2.0, NULL); + + get<1>(nti).set_float(1.0); + get<1>(nti).set_int(32); + ASSERT(get<1>(nti).get_int() == 32, NULL); + ASSERT(get<1>(nti).get_float() == 1.0, NULL); + + // converting constructor + tuple<double,double,double> tup2(1,2.0,3.0f); + tuple<double,double,double> tup3(9,4.0,7.0f); + ASSERT(tup2 != tup3, NULL); + + ASSERT(tup2 < tup3, NULL); + + // assignment + tup2 = tup3; + ASSERT(tup2 == tup3, NULL); + + tup2 = int_tup; + ASSERT(get<0>(tup2) == 4, NULL); + ASSERT(get<1>(tup2) == 5, NULL); + ASSERT(get<2>(tup2) == 6, NULL); + + // increment component of tuple + get<0>(tup2) += 1; + ASSERT(get<0>(tup2) == 5, NULL); + + std::pair<int,int> two_pair( 4, 8); + tuple<int,int> two_pair_tuple; + two_pair_tuple = two_pair; + ASSERT(get<0>(two_pair_tuple) == 4, NULL); + ASSERT(get<1>(two_pair_tuple) == 8, NULL); + + //relational ops + ASSERT(int_tuple_type(1,1,0) == int_tuple_type(1,1,0),NULL); + ASSERT(int_tuple_type(1,0,1) < int_tuple_type(1,1,1),NULL); + ASSERT(int_tuple_type(1,0,0) > int_tuple_type(0,1,0),NULL); + ASSERT(int_tuple_type(0,0,0) != int_tuple_type(1,0,1),NULL); + ASSERT(int_tuple_type(0,1,0) <= int_tuple_type(0,1,1),NULL); + ASSERT(int_tuple_type(0,0,1) <= int_tuple_type(0,0,1),NULL); + ASSERT(int_tuple_type(1,1,1) >= int_tuple_type(1,0,0),NULL); + ASSERT(int_tuple_type(0,1,1) >= int_tuple_type(0,1,1),NULL); + +#if !__TBB_TUPLE_COMPARISON_COMPILATION_BROKEN + typedef tuple<int,float,double,char> mixed_tuple_left; + typedef tuple<float,int,char,double> mixed_tuple_right; + + ASSERT(mixed_tuple_left(1,1.f,1,char(1)) == mixed_tuple_right(1.f,1,char(1),1),NULL); + ASSERT(mixed_tuple_left(1,0.f,1,char(1)) < mixed_tuple_right(1.f,1,char(1),1),NULL); + ASSERT(mixed_tuple_left(1,1.f,1,char(1)) > mixed_tuple_right(1.f,1,char(0),1),NULL); + ASSERT(mixed_tuple_left(1,1.f,1,char(0)) != mixed_tuple_right(1.f,1,char(1),1),NULL); + ASSERT(mixed_tuple_left(1,0.f,1,char(1)) <= mixed_tuple_right(1.f,1,char(0),1),NULL); + ASSERT(mixed_tuple_left(1,0.f,0,char(1)) <= mixed_tuple_right(1.f,0,char(0),1),NULL); + ASSERT(mixed_tuple_left(1,1.f,1,char(0)) >= mixed_tuple_right(1.f,0,char(1),1),NULL); + ASSERT(mixed_tuple_left(0,1.f,1,char(0)) >= mixed_tuple_right(0.f,1,char(1),0),NULL); + + ASSERT(!(mixed_tuple_left(2,1.f,1,char(1)) == mixed_tuple_right(1.f,1,char(1),1)),NULL); + ASSERT(!(mixed_tuple_left(1,2.f,1,char(1)) == mixed_tuple_right(1.f,1,char(1),1)),NULL); + ASSERT(!(mixed_tuple_left(1,1.f,2,char(1)) == mixed_tuple_right(1.f,1,char(1),1)),NULL); + ASSERT(!(mixed_tuple_left(1,1.f,1,char(2)) == mixed_tuple_right(1.f,1,char(1),1)),NULL); + + ASSERT(!(mixed_tuple_left(1,1.f,1,char(1)) < mixed_tuple_right(1.f,1,char(1),1)),NULL); + ASSERT(!(mixed_tuple_left(1,1.f,1,char(1)) > mixed_tuple_right(1.f,1,char(1),1)),NULL); + ASSERT(!(mixed_tuple_left(1,1.f,1,char(1)) != mixed_tuple_right(1.f,1,char(1),1)),NULL); + + ASSERT(mixed_tuple_left(1,1.f,1,char(1)) <= mixed_tuple_right(1.f,1,char(1),1),NULL); + ASSERT(mixed_tuple_left(1,1.f,1,char(1)) >= mixed_tuple_right(1.f,1,char(1),1),NULL); + + RunOneComparisonTest<int,float,char,float,char,int>(); + RunOneComparisonTest<double,float,char,float,double,int>(); + RunOneComparisonTest<int,float,char,short,char,short>(); + RunOneComparisonTest<double,float,short,float,char,int>(); +#endif /* __TBB_TUPLE_COMPARISON_COMPILATION_BROKEN */ + + + // the following should result in a syntax error + // typedef tuple<float,float> mixed_short_tuple; + // ASSERT(mixed_tuple_left(1,1.f,1,1) != mixed_short_tuple(1.f,1.f),NULL); + +} + +int TestMain() { + RunTests(); + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_write_once_node.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_write_once_node.cpp new file mode 100644 index 00000000..07206743 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_write_once_node.cpp @@ -0,0 +1,212 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if __TBB_CPF_BUILD +#define TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1 +#endif + +#include "harness.h" +#include "harness_graph.h" + +#include "tbb/flow_graph.h" +#include "tbb/task_scheduler_init.h" +#include "test_follows_and_precedes_api.h" + +#define N 300 +#define T 4 +#define M 4 + +template< typename R > +void simple_read_write_tests() { + tbb::flow::graph g; + tbb::flow::write_once_node<R> n(g); + + for ( int t = 0; t < T; ++t ) { + R v0(0); + std::vector< harness_counting_receiver<R> > r(M, harness_counting_receiver<R>(g)); + + ASSERT( n.is_valid() == false, NULL ); + ASSERT( n.try_get( v0 ) == false, NULL ); + + if ( t % 2 ) { + ASSERT( n.try_put( static_cast<R>(N+1) ), NULL ); + ASSERT( n.is_valid() == true, NULL ); + ASSERT( n.try_get( v0 ) == true, NULL ); + ASSERT( v0 == R(N+1), NULL ); + } + + for (int i = 0; i < M; ++i) { + tbb::flow::make_edge( n, r[i] ); + } + + if ( t%2 ) { + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == 1, NULL ); + } + } + + for (int i = 1; i <= N; ++i ) { + R v1(static_cast<R>(i)); + + bool result = n.try_put( v1 ); + if ( !(t%2) && i == 1 ) + ASSERT( result == true, NULL ); + else + ASSERT( result == false, NULL ); + + ASSERT( n.is_valid() == true, NULL ); + + for (int j = 0; j < N; ++j ) { + R v2(0); + ASSERT( n.try_get( v2 ), NULL ); + if ( t%2 ) + ASSERT( R(N+1) == v2, NULL ); + else + ASSERT( R(1) == v2, NULL ); + } + } + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == 1, NULL ); + } + for (int i = 0; i < M; ++i) { + tbb::flow::remove_edge( n, r[i] ); + } + ASSERT( n.try_put( R(0) ) == false, NULL ); + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == 1, NULL ); + } + n.clear(); + ASSERT( n.is_valid() == false, NULL ); + ASSERT( n.try_get( v0 ) == false, NULL ); + } +} + +template< typename R > +class native_body : NoAssign { + tbb::flow::write_once_node<R> &my_node; + +public: + + native_body( tbb::flow::write_once_node<R> &n ) : my_node(n) {} + + void operator()( int i ) const { + R v1(static_cast<R>(i)); + ASSERT( my_node.try_put( v1 ) == false, NULL ); + ASSERT( my_node.is_valid() == true, NULL ); + ASSERT( my_node.try_get( v1 ) == true, NULL ); + ASSERT( v1 == R(-1), NULL ); + } +}; + +template< typename R > +void parallel_read_write_tests() { + tbb::flow::graph g; + tbb::flow::write_once_node<R> n(g); + //Create a vector of identical nodes + std::vector< tbb::flow::write_once_node<R> > wo_vec(2, n); + + for (size_t node_idx=0; node_idx<wo_vec.size(); ++node_idx) { + for ( int t = 0; t < T; ++t ) { + std::vector< harness_counting_receiver<R> > r(M, harness_counting_receiver<R>(g)); + + for (int i = 0; i < M; ++i) { + tbb::flow::make_edge( wo_vec[node_idx], r[i] ); + } + R v0; + ASSERT( wo_vec[node_idx].is_valid() == false, NULL ); + ASSERT( wo_vec[node_idx].try_get( v0 ) == false, NULL ); + + ASSERT( wo_vec[node_idx].try_put( R(-1) ), NULL ); + + NativeParallelFor( N, native_body<R>( wo_vec[node_idx] ) ); + + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == 1, NULL ); + } + for (int i = 0; i < M; ++i) { + tbb::flow::remove_edge( wo_vec[node_idx], r[i] ); + } + ASSERT( wo_vec[node_idx].try_put( R(0) ) == false, NULL ); + for (int i = 0; i < M; ++i) { + size_t c = r[i].my_count; + ASSERT( int(c) == 1, NULL ); + } + wo_vec[node_idx].clear(); + ASSERT( wo_vec[node_idx].is_valid() == false, NULL ); + ASSERT( wo_vec[node_idx].try_get( v0 ) == false, NULL ); + } + } +} + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET +#include <array> +#include <vector> +void test_follows_and_precedes_api() { + using msg_t = tbb::flow::continue_msg; + + std::array<msg_t, 3> messages_for_follows= {msg_t(), msg_t(), msg_t()}; + std::vector<msg_t> messages_for_precedes = {msg_t()}; + + follows_and_precedes_testing::test_follows<msg_t, tbb::flow::write_once_node<msg_t>>(messages_for_follows); + follows_and_precedes_testing::test_precedes<msg_t, tbb::flow::write_once_node<msg_t>>(messages_for_precedes); +} +#endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT +void test_deduction_guides() { + using namespace tbb::flow; + + graph g; + broadcast_node<int> b1(g); + write_once_node<int> wo0(g); + +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + write_once_node wo1(follows(b1)); + static_assert(std::is_same_v<decltype(wo1), write_once_node<int>>); + + write_once_node wo2(precedes(b1)); + static_assert(std::is_same_v<decltype(wo2), write_once_node<int>>); +#endif + + write_once_node wo3(wo0); + static_assert(std::is_same_v<decltype(wo3), write_once_node<int>>); +} +#endif + +int TestMain() { + simple_read_write_tests<int>(); + simple_read_write_tests<float>(); + for( int p=MinThread; p<=MaxThread; ++p ) { + tbb::task_scheduler_init init(p); + parallel_read_write_tests<int>(); + parallel_read_write_tests<float>(); + test_reserving_nodes<tbb::flow::write_once_node, size_t>(); + } +#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION + test_extract_on_node<tbb::flow::write_once_node, int>(); +#endif +#if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET + test_follows_and_precedes_api(); +#endif +#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT + test_deduction_guides(); +#endif + return Harness::Done; +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_yield.cpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_yield.cpp new file mode 100644 index 00000000..287379a5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/src/test/test_yield.cpp @@ -0,0 +1,64 @@ +/* + Copyright (c) 2005-2020 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Test that __TBB_Yield works. +// On Red Hat EL4 U1, it does not work, because sched_yield is broken. + +#define HARNESS_DEFAULT_MIN_THREADS 4 +#define HARNESS_DEFAULT_MAX_THREADS 8 + +#include "tbb/tbb_machine.h" +#include "tbb/tick_count.h" +#include "harness.h" + +static volatile long CyclicCounter; +static volatile bool Quit; +double SingleThreadTime; + +struct RoundRobin: NoAssign { + const int number_of_threads; + RoundRobin( long p ) : number_of_threads(p) {} + void operator()( long k ) const { + tbb::tick_count t0 = tbb::tick_count::now(); + for( long i=0; i<10000; ++i ) { + // Wait for previous thread to notify us + for( int j=0; CyclicCounter!=k && !Quit; ++j ) { + __TBB_Yield(); + if( j%100==0 ) { + tbb::tick_count t1 = tbb::tick_count::now(); + if( (t1-t0).seconds()>=1.0*number_of_threads ) { + REPORT("Warning: __TBB_Yield failing to yield with %d threads (or system is heavily loaded)\n",number_of_threads); + Quit = true; + return; + } + } + } + // Notify next thread that it can run + CyclicCounter = (k+1)%number_of_threads; + } + } +}; + +int TestMain () { + for( int p=MinThread; p<=MaxThread; ++p ) { + REMARK("testing with %d threads\n", p ); + CyclicCounter = 0; + Quit = false; + NativeParallelFor( long(p), RoundRobin(p) ); + } + return Harness::Done; +} + diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/third-party-programs.txt b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/third-party-programs.txt new file mode 100644 index 00000000..7360813b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/cmdstan-2.33.1/stan/lib/stan_math/lib/tbb_2020.3/third-party-programs.txt @@ -0,0 +1,230 @@ +Intel(R) Threading Building Blocks Third Party Programs File + +This file contains the list of third party software ("third party programs") +contained in the Intel software and their required notices and/or license terms. +This third party software, even if included with the distribution of the Intel +software, may be governed by separate license terms, including without limitation, +third party license terms, other Intel software license terms, and open source +software license terms. These separate license terms govern your use of the third +party programs as set forth in the "third-party-programs.txt" or other similarly named text file. + +Third party programs and their corresponding required notices and/or license +terms are listed below. +____________________________________________________________________________________________________ + +1. Portable Hardware Locality (hwloc): + Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana University Research and Technology Corporation. All rights reserved. + Copyright (c) 2004-2005 The University of Tennessee and The University of Tennessee Research Foundation. All rights reserved. + Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, University of Stuttgart. All rights reserved. + Copyright (c) 2004-2005 The Regents of the University of California. All rights reserved. + Copyright (c) 2009 CNRS + Copyright (c) 2009-2016 Inria. All rights reserved. + Copyright (c) 2009-2015 Universite Bordeaux + Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved. + Copyright (c) 2009-2012 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010 IBM + Copyright (c) 2010 Jirka Hladky + Copyright (c) 2012 Aleksej Saushev, The NetBSD Foundation + Copyright (c) 2012 Blue Brain Project, EPFL. All rights reserved. + Copyright (c) 2013-2014 University of Wisconsin-La Crosse. All rights reserved. + Copyright (c) 2015 Research Organization for Information Science and Technology (RIST). All rights reserved. + Copyright (c) 2015-2016 Intel, Inc. All rights reserved. + See COPYING in top-level directory. + + New BSD License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +_______________________________________________________________________________________________________ + +2. Instrumentation and Tracing Technology (ITT) Notify User API: + Copyright (c) 2005-2014 Intel Corporation. All rights reserved. + + The 3-Clause BSD License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +_______________________________________________________________________________________________________ + +3. ActiveState Thread pool with same API as (multi) processing.Pool (Python recipe): + Copyright (c) 2008,2016 david decotigny (this file) + Copyright (c) 2006-2008, R Oudkerk (multiprocessing.Pool) + + BSD 3-clause "New" or "Revised" License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of author nor the names of any contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +_______________________________________________________________________________________________________ + +4. gperftools: Copyright (c) 2011, Google Inc. + + Tachyon: Copyright (c) 1994-2008 John E. Stone. All rights reserved. + + BSD 3-Clause "New" or "Revised" License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +_______________________________________________________________________________________________________ + +5. Mateusz Kwiatkowski Workaround for bug 62258 in libstdc++ + + Public domain +_______________________________________________________________________________________________________ + +6. Bzip2: Copyright (c) 1996-2019 Julian Seward. + + Bzip 2 License + + This program, bzip2, the associated library libbzip2, and all documentation, are copyright (c) 1996-2019 Julian Seward. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + + Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + + The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +_______________________________________________________________________________________________________ + +7. Apple OpenGL Image Sample Source Code + + Apple License + + ("Apple") in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this Apple software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and subject to these terms, Apple grants you a personal, non-exclusive license, under Apple's copyrights in this original Apple software (the "Apple Software"), to use, reproduce, modify and redistribute the Apple Software, with or without modifications, in source and/or binary forms; provided that if you redistribute the Apple Software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the Apple Software. Neither the name, trademarks, service marks or logos of Apple Computer, Inc. may be used to endorse or promote products derived from the Apple Software without specific prior written permission from Apple.Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Apple herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +_______________________________________________________________________________________________________ + +8. LodePNG: Copyright (c) 2005-2019 by Lode Vandevenne. + + zlib License + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +_______________________________________________________________________________________________________ + +9. prism: Copyright (c) 2012-2013 Lea Verou. + + jquery: Copyright (c) 2005, 2014 jQuery Foundation, Inc. + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +_______________________________________________________________________________________________________ + +*Other names and brands may be claimed as the property of others. diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet b/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet new file mode 100755 index 00000000..65101a12 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet differ diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet.hpp b/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet.hpp new file mode 100644 index 00000000..20154888 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet.hpp @@ -0,0 +1,1343 @@ +// Code generated by stanc v2.33.1 +#include <stan/model/model_header.hpp> +namespace prophet_model_namespace { +using stan::model::model_base_crtp; +using namespace stan::math; +stan::math::profile_map profiles__; +static constexpr std::array<const char*, 96> locations_array__ = + {" (found before start of program)", + " (in 'prophet.stan', line 110, column 2 to column 9)", + " (in 'prophet.stan', line 111, column 2 to column 9)", + " (in 'prophet.stan', line 112, column 2 to column 18)", + " (in 'prophet.stan', line 113, column 2 to column 26)", + " (in 'prophet.stan', line 114, column 2 to column 17)", + " (in 'prophet.stan', line 118, column 2 to column 18)", + " (in 'prophet.stan', line 124, column 4 to column 29)", + " (in 'prophet.stan', line 123, column 35 to line 125, column 3)", + " (in 'prophet.stan', line 123, column 9 to line 125, column 3)", + " (in 'prophet.stan', line 122, column 4 to column 64)", + " (in 'prophet.stan', line 121, column 35 to line 123, column 3)", + " (in 'prophet.stan', line 121, column 9 to line 125, column 3)", + " (in 'prophet.stan', line 120, column 4 to column 54)", + " (in 'prophet.stan', line 119, column 28 to line 121, column 3)", + " (in 'prophet.stan', line 119, column 2 to line 125, column 3)", + " (in 'prophet.stan', line 130, column 2 to column 19)", + " (in 'prophet.stan', line 131, column 2 to column 19)", + " (in 'prophet.stan', line 132, column 2 to column 37)", + " (in 'prophet.stan', line 133, column 2 to column 29)", + " (in 'prophet.stan', line 134, column 2 to column 27)", + " (in 'prophet.stan', line 137, column 2 to line 142, column 4)", + " (in 'prophet.stan', line 88, column 2 to column 8)", + " (in 'prophet.stan', line 89, column 2 to column 17)", + " (in 'prophet.stan', line 90, column 9 to column 10)", + " (in 'prophet.stan', line 90, column 2 to column 14)", + " (in 'prophet.stan', line 91, column 9 to column 10)", + " (in 'prophet.stan', line 91, column 2 to column 16)", + " (in 'prophet.stan', line 92, column 9 to column 10)", + " (in 'prophet.stan', line 92, column 2 to column 14)", + " (in 'prophet.stan', line 93, column 2 to column 8)", + " (in 'prophet.stan', line 94, column 9 to column 10)", + " (in 'prophet.stan', line 94, column 2 to column 21)", + " (in 'prophet.stan', line 95, column 9 to column 10)", + " (in 'prophet.stan', line 95, column 11 to column 12)", + " (in 'prophet.stan', line 95, column 2 to column 16)", + " (in 'prophet.stan', line 96, column 9 to column 10)", + " (in 'prophet.stan', line 96, column 2 to column 19)", + " (in 'prophet.stan', line 97, column 2 to column 20)", + " (in 'prophet.stan', line 98, column 2 to column 22)", + " (in 'prophet.stan', line 99, column 9 to column 10)", + " (in 'prophet.stan', line 99, column 2 to column 16)", + " (in 'prophet.stan', line 100, column 9 to column 10)", + " (in 'prophet.stan', line 100, column 2 to column 16)", + " (in 'prophet.stan', line 104, column 9 to column 10)", + " (in 'prophet.stan', line 104, column 12 to column 13)", + " (in 'prophet.stan', line 104, column 2 to column 61)", + " (in 'prophet.stan', line 105, column 9 to column 10)", + " (in 'prophet.stan', line 105, column 12 to column 13)", + " (in 'prophet.stan', line 105, column 2 to column 47)", + " (in 'prophet.stan', line 106, column 9 to column 10)", + " (in 'prophet.stan', line 106, column 12 to column 13)", + " (in 'prophet.stan', line 106, column 2 to column 47)", + " (in 'prophet.stan', line 112, column 9 to column 10)", + " (in 'prophet.stan', line 114, column 9 to column 10)", + " (in 'prophet.stan', line 118, column 9 to column 10)", + " (in 'prophet.stan', line 9, column 11 to column 12)", + " (in 'prophet.stan', line 9, column 14 to column 15)", + " (in 'prophet.stan', line 9, column 4 to column 19)", + " (in 'prophet.stan', line 10, column 15 to column 16)", + " (in 'prophet.stan', line 10, column 4 to column 24)", + " (in 'prophet.stan', line 11, column 4 to column 15)", + " (in 'prophet.stan', line 14, column 4 to column 28)", + " (in 'prophet.stan', line 15, column 4 to column 33)", + " (in 'prophet.stan', line 16, column 4 to column 15)", + " (in 'prophet.stan', line 21, column 8 to column 26)", + " (in 'prophet.stan', line 22, column 8 to column 28)", + " (in 'prophet.stan', line 20, column 58 to line 23, column 7)", + " (in 'prophet.stan', line 20, column 6 to line 23, column 7)", + " (in 'prophet.stan', line 24, column 6 to column 19)", + " (in 'prophet.stan', line 19, column 19 to line 25, column 5)", + " (in 'prophet.stan', line 19, column 4 to line 25, column 5)", + " (in 'prophet.stan', line 26, column 4 to column 13)", + " (in 'prophet.stan', line 7, column 73 to line 27, column 3)", + " (in 'prophet.stan', line 32, column 11 to column 12)", + " (in 'prophet.stan', line 32, column 4 to column 20)", + " (in 'prophet.stan', line 33, column 11 to column 16)", + " (in 'prophet.stan', line 33, column 4 to column 22)", + " (in 'prophet.stan', line 34, column 4 to column 14)", + " (in 'prophet.stan', line 37, column 4 to column 51)", + " (in 'prophet.stan', line 40, column 4 to column 13)", + " (in 'prophet.stan', line 42, column 6 to column 66)", + " (in 'prophet.stan', line 43, column 6 to column 29)", + " (in 'prophet.stan', line 41, column 19 to line 44, column 5)", + " (in 'prophet.stan', line 41, column 4 to line 44, column 5)", + " (in 'prophet.stan', line 45, column 4 to column 17)", + " (in 'prophet.stan', line 31, column 78 to line 46, column 3)", + " (in 'prophet.stan', line 58, column 11 to column 12)", + " (in 'prophet.stan', line 58, column 4 to column 20)", + " (in 'prophet.stan', line 60, column 4 to column 53)", + " (in 'prophet.stan', line 61, column 4 to column 70)", + " (in 'prophet.stan', line 57, column 4 to line 62, column 3)", + " (in 'prophet.stan', line 74, column 4 to column 65)", + " (in 'prophet.stan', line 73, column 4 to line 75, column 3)", + " (in 'prophet.stan', line 83, column 4 to column 28)", + " (in 'prophet.stan', line 82, column 4 to line 84, column 3)"}; +template <typename T0__, typename T1__, typename T2__, typename T3__, + stan::require_all_t<stan::is_col_vector<T0__>, + stan::is_vt_not_complex<T0__>, + stan::is_col_vector<T1__>, + stan::is_vt_not_complex<T1__>, + std::is_integral<T2__>, std::is_integral<T3__>>* = nullptr> +Eigen::Matrix<stan::promote_args_t<stan::base_type_t<T0__>, + stan::base_type_t<T1__>>,-1,-1> +get_changepoint_matrix(const T0__& t_arg__, const T1__& t_change_arg__, + const T2__& T, const T3__& S, std::ostream* pstream__); +template <typename T0__, typename T1__, typename T2__, typename T3__, + typename T4__, + stan::require_all_t<stan::math::disjunction<stan::is_autodiff<T0__>, + std::is_floating_point<T0__>>, + stan::math::disjunction<stan::is_autodiff<T1__>, + std::is_floating_point<T1__>>, + stan::is_col_vector<T2__>, + stan::is_vt_not_complex<T2__>, + stan::is_col_vector<T3__>, + stan::is_vt_not_complex<T3__>, + std::is_integral<T4__>>* = nullptr> +Eigen::Matrix<stan::promote_args_t<T0__, T1__, stan::base_type_t<T2__>, + stan::base_type_t<T3__>>,-1,1> +logistic_gamma(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_change_arg__, const T4__& S, std::ostream* + pstream__); +template <typename T0__, typename T1__, typename T2__, typename T3__, + typename T4__, typename T5__, typename T6__, typename T7__, + stan::require_all_t<stan::math::disjunction<stan::is_autodiff<T0__>, + std::is_floating_point<T0__>>, + stan::math::disjunction<stan::is_autodiff<T1__>, + std::is_floating_point<T1__>>, + stan::is_col_vector<T2__>, + stan::is_vt_not_complex<T2__>, + stan::is_col_vector<T3__>, + stan::is_vt_not_complex<T3__>, + stan::is_col_vector<T4__>, + stan::is_vt_not_complex<T4__>, + stan::is_eigen_matrix_dynamic<T5__>, + stan::is_vt_not_complex<T5__>, + stan::is_col_vector<T6__>, + stan::is_vt_not_complex<T6__>, + std::is_integral<T7__>>* = nullptr> +Eigen::Matrix<stan::promote_args_t<T0__, T1__, stan::base_type_t<T2__>, + stan::base_type_t<T3__>, stan::base_type_t<T4__>, + stan::promote_args_t<stan::base_type_t<T5__>, + stan::base_type_t<T6__>>>,-1,1> +logistic_trend(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_arg__, const T4__& cap_arg__, const T5__& + A_arg__, const T6__& t_change_arg__, const T7__& S, + std::ostream* pstream__); +template <typename T0__, typename T1__, typename T2__, typename T3__, + typename T4__, typename T5__, + stan::require_all_t<stan::math::disjunction<stan::is_autodiff<T0__>, + std::is_floating_point<T0__>>, + stan::math::disjunction<stan::is_autodiff<T1__>, + std::is_floating_point<T1__>>, + stan::is_col_vector<T2__>, + stan::is_vt_not_complex<T2__>, + stan::is_col_vector<T3__>, + stan::is_vt_not_complex<T3__>, + stan::is_eigen_matrix_dynamic<T4__>, + stan::is_vt_not_complex<T4__>, + stan::is_col_vector<T5__>, + stan::is_vt_not_complex<T5__>>* = nullptr> +Eigen::Matrix<stan::promote_args_t<T0__, T1__, stan::base_type_t<T2__>, + stan::base_type_t<T3__>, stan::base_type_t<T4__>, + stan::promote_args_t<stan::base_type_t<T5__>>>,-1,1> +linear_trend(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_arg__, const T4__& A_arg__, const T5__& + t_change_arg__, std::ostream* pstream__); +template <typename T0__, typename T1__, + stan::require_all_t<stan::math::disjunction<stan::is_autodiff<T0__>, + std::is_floating_point<T0__>>, + std::is_integral<T1__>>* = nullptr> +Eigen::Matrix<stan::promote_args_t<T0__>,-1,1> +flat_trend(const T0__& m, const T1__& T, std::ostream* pstream__); +// matrix get_changepoint_matrix(vector, vector, int, int) +template <typename T0__, typename T1__, typename T2__, typename T3__, + stan::require_all_t<stan::is_col_vector<T0__>, + stan::is_vt_not_complex<T0__>, + stan::is_col_vector<T1__>, + stan::is_vt_not_complex<T1__>, + std::is_integral<T2__>, std::is_integral<T3__>>*> +Eigen::Matrix<stan::promote_args_t<stan::base_type_t<T0__>, + stan::base_type_t<T1__>>,-1,-1> +get_changepoint_matrix(const T0__& t_arg__, const T1__& t_change_arg__, + const T2__& T, const T3__& S, std::ostream* pstream__) { + using local_scalar_t__ = stan::promote_args_t<stan::base_type_t<T0__>, + stan::base_type_t<T1__>>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + const auto& t = stan::math::to_ref(t_arg__); + const auto& t_change = stan::math::to_ref(t_change_arg__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 56; + stan::math::validate_non_negative_index("A", "T", T); + current_statement__ = 57; + stan::math::validate_non_negative_index("A", "S", S); + Eigen::Matrix<local_scalar_t__,-1,-1> A = + Eigen::Matrix<local_scalar_t__,-1,-1>::Constant(T, S, DUMMY_VAR__); + current_statement__ = 59; + stan::math::validate_non_negative_index("a_row", "S", S); + Eigen::Matrix<local_scalar_t__,1,-1> a_row = + Eigen::Matrix<local_scalar_t__,1,-1>::Constant(S, DUMMY_VAR__); + int cp_idx = std::numeric_limits<int>::min(); + current_statement__ = 62; + stan::model::assign(A, stan::math::rep_matrix(0, T, S), + "assigning variable A"); + current_statement__ = 63; + stan::model::assign(a_row, stan::math::rep_row_vector(0, S), + "assigning variable a_row"); + current_statement__ = 64; + cp_idx = 1; + current_statement__ = 71; + for (int i = 1; i <= T; ++i) { + current_statement__ = 68; + while ((stan::math::primitive_value(stan::math::logical_lte(cp_idx, S)) + && + stan::math::primitive_value( + stan::math::logical_gte( + stan::model::rvalue(t, "t", stan::model::index_uni(i)), + stan::model::rvalue(t_change, "t_change", + stan::model::index_uni(cp_idx)))))) { + current_statement__ = 65; + stan::model::assign(a_row, 1, "assigning variable a_row", + stan::model::index_uni(cp_idx)); + current_statement__ = 66; + cp_idx = (cp_idx + 1); + } + current_statement__ = 69; + stan::model::assign(A, a_row, "assigning variable A", + stan::model::index_uni(i)); + } + current_statement__ = 72; + return A; + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +// vector logistic_gamma(real, real, vector, vector, int) +template <typename T0__, typename T1__, typename T2__, typename T3__, + typename T4__, + stan::require_all_t<stan::math::disjunction<stan::is_autodiff<T0__>, + std::is_floating_point<T0__>>, + stan::math::disjunction<stan::is_autodiff<T1__>, + std::is_floating_point<T1__>>, + stan::is_col_vector<T2__>, + stan::is_vt_not_complex<T2__>, + stan::is_col_vector<T3__>, + stan::is_vt_not_complex<T3__>, + std::is_integral<T4__>>*> +Eigen::Matrix<stan::promote_args_t<T0__, T1__, stan::base_type_t<T2__>, + stan::base_type_t<T3__>>,-1,1> +logistic_gamma(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_change_arg__, const T4__& S, std::ostream* + pstream__) { + using local_scalar_t__ = stan::promote_args_t<T0__, T1__, + stan::base_type_t<T2__>, + stan::base_type_t<T3__>>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + const auto& delta = stan::math::to_ref(delta_arg__); + const auto& t_change = stan::math::to_ref(t_change_arg__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 74; + stan::math::validate_non_negative_index("gamma", "S", S); + Eigen::Matrix<local_scalar_t__,-1,1> gamma = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(S, DUMMY_VAR__); + current_statement__ = 76; + stan::math::validate_non_negative_index("k_s", "S + 1", (S + 1)); + Eigen::Matrix<local_scalar_t__,-1,1> k_s = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant((S + 1), DUMMY_VAR__); + local_scalar_t__ m_pr = DUMMY_VAR__; + current_statement__ = 79; + stan::model::assign(k_s, + stan::math::append_row(k, + stan::math::add(k, stan::math::cumulative_sum(delta))), + "assigning variable k_s"); + current_statement__ = 80; + m_pr = m; + current_statement__ = 84; + for (int i = 1; i <= S; ++i) { + current_statement__ = 81; + stan::model::assign(gamma, + ((stan::model::rvalue(t_change, "t_change", stan::model::index_uni(i)) + - m_pr) * (1 - + (stan::model::rvalue(k_s, "k_s", stan::model::index_uni(i)) / + stan::model::rvalue(k_s, "k_s", stan::model::index_uni((i + 1)))))), + "assigning variable gamma", stan::model::index_uni(i)); + current_statement__ = 82; + m_pr = (m_pr + + stan::model::rvalue(gamma, "gamma", stan::model::index_uni(i))); + } + current_statement__ = 85; + return gamma; + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +/* vector + logistic_trend(real, real, vector, vector, vector, matrix, vector, int) + */ +template <typename T0__, typename T1__, typename T2__, typename T3__, + typename T4__, typename T5__, typename T6__, typename T7__, + stan::require_all_t<stan::math::disjunction<stan::is_autodiff<T0__>, + std::is_floating_point<T0__>>, + stan::math::disjunction<stan::is_autodiff<T1__>, + std::is_floating_point<T1__>>, + stan::is_col_vector<T2__>, + stan::is_vt_not_complex<T2__>, + stan::is_col_vector<T3__>, + stan::is_vt_not_complex<T3__>, + stan::is_col_vector<T4__>, + stan::is_vt_not_complex<T4__>, + stan::is_eigen_matrix_dynamic<T5__>, + stan::is_vt_not_complex<T5__>, + stan::is_col_vector<T6__>, + stan::is_vt_not_complex<T6__>, + std::is_integral<T7__>>*> +Eigen::Matrix<stan::promote_args_t<T0__, T1__, stan::base_type_t<T2__>, + stan::base_type_t<T3__>, stan::base_type_t<T4__>, + stan::promote_args_t<stan::base_type_t<T5__>, + stan::base_type_t<T6__>>>,-1,1> +logistic_trend(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_arg__, const T4__& cap_arg__, const T5__& + A_arg__, const T6__& t_change_arg__, const T7__& S, + std::ostream* pstream__) { + using local_scalar_t__ = stan::promote_args_t<T0__, T1__, + stan::base_type_t<T2__>, + stan::base_type_t<T3__>, + stan::base_type_t<T4__>, + stan::promote_args_t<stan::base_type_t<T5__>, + stan::base_type_t<T6__>>>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + const auto& delta = stan::math::to_ref(delta_arg__); + const auto& t = stan::math::to_ref(t_arg__); + const auto& cap = stan::math::to_ref(cap_arg__); + const auto& A = stan::math::to_ref(A_arg__); + const auto& t_change = stan::math::to_ref(t_change_arg__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 87; + stan::math::validate_non_negative_index("gamma", "S", S); + Eigen::Matrix<local_scalar_t__,-1,1> gamma = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(S, DUMMY_VAR__); + current_statement__ = 89; + stan::model::assign(gamma, + logistic_gamma(k, m, delta, t_change, S, pstream__), + "assigning variable gamma"); + current_statement__ = 90; + return stan::math::elt_multiply(cap, + stan::math::inv_logit( + stan::math::elt_multiply( + stan::math::add(k, stan::math::multiply(A, delta)), + stan::math::subtract(t, + stan::math::add(m, stan::math::multiply(A, gamma)))))); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +// vector linear_trend(real, real, vector, vector, matrix, vector) +template <typename T0__, typename T1__, typename T2__, typename T3__, + typename T4__, typename T5__, + stan::require_all_t<stan::math::disjunction<stan::is_autodiff<T0__>, + std::is_floating_point<T0__>>, + stan::math::disjunction<stan::is_autodiff<T1__>, + std::is_floating_point<T1__>>, + stan::is_col_vector<T2__>, + stan::is_vt_not_complex<T2__>, + stan::is_col_vector<T3__>, + stan::is_vt_not_complex<T3__>, + stan::is_eigen_matrix_dynamic<T4__>, + stan::is_vt_not_complex<T4__>, + stan::is_col_vector<T5__>, + stan::is_vt_not_complex<T5__>>*> +Eigen::Matrix<stan::promote_args_t<T0__, T1__, stan::base_type_t<T2__>, + stan::base_type_t<T3__>, stan::base_type_t<T4__>, + stan::promote_args_t<stan::base_type_t<T5__>>>,-1,1> +linear_trend(const T0__& k, const T1__& m, const T2__& delta_arg__, + const T3__& t_arg__, const T4__& A_arg__, const T5__& + t_change_arg__, std::ostream* pstream__) { + using local_scalar_t__ = stan::promote_args_t<T0__, T1__, + stan::base_type_t<T2__>, + stan::base_type_t<T3__>, + stan::base_type_t<T4__>, + stan::promote_args_t<stan::base_type_t<T5__>>>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + const auto& delta = stan::math::to_ref(delta_arg__); + const auto& t = stan::math::to_ref(t_arg__); + const auto& A = stan::math::to_ref(A_arg__); + const auto& t_change = stan::math::to_ref(t_change_arg__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 92; + return stan::math::add( + stan::math::elt_multiply( + stan::math::add(k, stan::math::multiply(A, delta)), t), + stan::math::add(m, + stan::math::multiply(A, + stan::math::elt_multiply(stan::math::minus(t_change), delta)))); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +// vector flat_trend(real, int) +template <typename T0__, typename T1__, + stan::require_all_t<stan::math::disjunction<stan::is_autodiff<T0__>, + std::is_floating_point<T0__>>, + std::is_integral<T1__>>*> +Eigen::Matrix<stan::promote_args_t<T0__>,-1,1> +flat_trend(const T0__& m, const T1__& T, std::ostream* pstream__) { + using local_scalar_t__ = stan::promote_args_t<T0__>; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 94; + return stan::math::rep_vector(m, T); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } +} +class prophet_model final : public model_base_crtp<prophet_model> { + private: + int T; + int K; + Eigen::Matrix<double,-1,1> t_data__; + Eigen::Matrix<double,-1,1> cap_data__; + Eigen::Matrix<double,-1,1> y_data__; + int S; + Eigen::Matrix<double,-1,1> t_change_data__; + Eigen::Matrix<double,-1,-1> X_data__; + Eigen::Matrix<double,-1,1> sigmas_data__; + double tau; + int trend_indicator; + Eigen::Matrix<double,-1,1> s_a_data__; + Eigen::Matrix<double,-1,1> s_m_data__; + Eigen::Matrix<double,-1,-1> A_data__; + Eigen::Matrix<double,-1,-1> X_sa_data__; + Eigen::Matrix<double,-1,-1> X_sm_data__; + Eigen::Map<Eigen::Matrix<double,-1,1>> t{nullptr, 0}; + Eigen::Map<Eigen::Matrix<double,-1,1>> cap{nullptr, 0}; + Eigen::Map<Eigen::Matrix<double,-1,1>> y{nullptr, 0}; + Eigen::Map<Eigen::Matrix<double,-1,1>> t_change{nullptr, 0}; + Eigen::Map<Eigen::Matrix<double,-1,-1>> X{nullptr, 0, 0}; + Eigen::Map<Eigen::Matrix<double,-1,1>> sigmas{nullptr, 0}; + Eigen::Map<Eigen::Matrix<double,-1,1>> s_a{nullptr, 0}; + Eigen::Map<Eigen::Matrix<double,-1,1>> s_m{nullptr, 0}; + Eigen::Map<Eigen::Matrix<double,-1,-1>> A{nullptr, 0, 0}; + Eigen::Map<Eigen::Matrix<double,-1,-1>> X_sa{nullptr, 0, 0}; + Eigen::Map<Eigen::Matrix<double,-1,-1>> X_sm{nullptr, 0, 0}; + public: + ~prophet_model() {} + prophet_model(stan::io::var_context& context__, unsigned int + random_seed__ = 0, std::ostream* pstream__ = nullptr) + : model_base_crtp(0) { + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + using local_scalar_t__ = double; + boost::ecuyer1988 base_rng__ = + stan::services::util::create_rng(random_seed__, 0); + // suppress unused var warning + (void) base_rng__; + static constexpr const char* function__ = + "prophet_model_namespace::prophet_model"; + // suppress unused var warning + (void) function__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + int pos__ = std::numeric_limits<int>::min(); + pos__ = 1; + current_statement__ = 22; + context__.validate_dims("data initialization", "T", "int", + std::vector<size_t>{}); + T = std::numeric_limits<int>::min(); + current_statement__ = 22; + T = context__.vals_i("T")[(1 - 1)]; + current_statement__ = 23; + context__.validate_dims("data initialization", "K", "int", + std::vector<size_t>{}); + K = std::numeric_limits<int>::min(); + current_statement__ = 23; + K = context__.vals_i("K")[(1 - 1)]; + current_statement__ = 23; + stan::math::check_greater_or_equal(function__, "K", K, 1); + current_statement__ = 24; + stan::math::validate_non_negative_index("t", "T", T); + current_statement__ = 25; + context__.validate_dims("data initialization", "t", "double", + std::vector<size_t>{static_cast<size_t>(T)}); + t_data__ = Eigen::Matrix<double,-1,1>::Constant(T, + std::numeric_limits<double>::quiet_NaN()); + new (&t) Eigen::Map<Eigen::Matrix<double,-1,1>>(t_data__.data(), T); + { + std::vector<local_scalar_t__> t_flat__; + current_statement__ = 25; + t_flat__ = context__.vals_r("t"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + stan::model::assign(t, t_flat__[(pos__ - 1)], + "assigning variable t", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 26; + stan::math::validate_non_negative_index("cap", "T", T); + current_statement__ = 27; + context__.validate_dims("data initialization", "cap", "double", + std::vector<size_t>{static_cast<size_t>(T)}); + cap_data__ = Eigen::Matrix<double,-1,1>::Constant(T, + std::numeric_limits<double>::quiet_NaN()); + new (&cap) Eigen::Map<Eigen::Matrix<double,-1,1>>(cap_data__.data(), T); + { + std::vector<local_scalar_t__> cap_flat__; + current_statement__ = 27; + cap_flat__ = context__.vals_r("cap"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + stan::model::assign(cap, cap_flat__[(pos__ - 1)], + "assigning variable cap", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 28; + stan::math::validate_non_negative_index("y", "T", T); + current_statement__ = 29; + context__.validate_dims("data initialization", "y", "double", + std::vector<size_t>{static_cast<size_t>(T)}); + y_data__ = Eigen::Matrix<double,-1,1>::Constant(T, + std::numeric_limits<double>::quiet_NaN()); + new (&y) Eigen::Map<Eigen::Matrix<double,-1,1>>(y_data__.data(), T); + { + std::vector<local_scalar_t__> y_flat__; + current_statement__ = 29; + y_flat__ = context__.vals_r("y"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + stan::model::assign(y, y_flat__[(pos__ - 1)], + "assigning variable y", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 30; + context__.validate_dims("data initialization", "S", "int", + std::vector<size_t>{}); + S = std::numeric_limits<int>::min(); + current_statement__ = 30; + S = context__.vals_i("S")[(1 - 1)]; + current_statement__ = 31; + stan::math::validate_non_negative_index("t_change", "S", S); + current_statement__ = 32; + context__.validate_dims("data initialization", "t_change", "double", + std::vector<size_t>{static_cast<size_t>(S)}); + t_change_data__ = Eigen::Matrix<double,-1,1>::Constant(S, + std::numeric_limits<double>::quiet_NaN()); + new (&t_change) + Eigen::Map<Eigen::Matrix<double,-1,1>>(t_change_data__.data(), S); + { + std::vector<local_scalar_t__> t_change_flat__; + current_statement__ = 32; + t_change_flat__ = context__.vals_r("t_change"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= S; ++sym1__) { + stan::model::assign(t_change, t_change_flat__[(pos__ - 1)], + "assigning variable t_change", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 33; + stan::math::validate_non_negative_index("X", "T", T); + current_statement__ = 34; + stan::math::validate_non_negative_index("X", "K", K); + current_statement__ = 35; + context__.validate_dims("data initialization", "X", "double", + std::vector<size_t>{static_cast<size_t>(T), static_cast<size_t>(K)}); + X_data__ = Eigen::Matrix<double,-1,-1>::Constant(T, K, + std::numeric_limits<double>::quiet_NaN()); + new (&X) Eigen::Map<Eigen::Matrix<double,-1,-1>>(X_data__.data(), T, K); + { + std::vector<local_scalar_t__> X_flat__; + current_statement__ = 35; + X_flat__ = context__.vals_r("X"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + for (int sym2__ = 1; sym2__ <= T; ++sym2__) { + stan::model::assign(X, X_flat__[(pos__ - 1)], + "assigning variable X", stan::model::index_uni(sym2__), + stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + } + current_statement__ = 36; + stan::math::validate_non_negative_index("sigmas", "K", K); + current_statement__ = 37; + context__.validate_dims("data initialization", "sigmas", "double", + std::vector<size_t>{static_cast<size_t>(K)}); + sigmas_data__ = Eigen::Matrix<double,-1,1>::Constant(K, + std::numeric_limits<double>::quiet_NaN()); + new (&sigmas) + Eigen::Map<Eigen::Matrix<double,-1,1>>(sigmas_data__.data(), K); + { + std::vector<local_scalar_t__> sigmas_flat__; + current_statement__ = 37; + sigmas_flat__ = context__.vals_r("sigmas"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + stan::model::assign(sigmas, sigmas_flat__[(pos__ - 1)], + "assigning variable sigmas", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 38; + context__.validate_dims("data initialization", "tau", "double", + std::vector<size_t>{}); + tau = std::numeric_limits<double>::quiet_NaN(); + current_statement__ = 38; + tau = context__.vals_r("tau")[(1 - 1)]; + current_statement__ = 38; + stan::math::check_greater_or_equal(function__, "tau", tau, 0); + current_statement__ = 39; + context__.validate_dims("data initialization", "trend_indicator", + "int", std::vector<size_t>{}); + trend_indicator = std::numeric_limits<int>::min(); + current_statement__ = 39; + trend_indicator = context__.vals_i("trend_indicator")[(1 - 1)]; + current_statement__ = 40; + stan::math::validate_non_negative_index("s_a", "K", K); + current_statement__ = 41; + context__.validate_dims("data initialization", "s_a", "double", + std::vector<size_t>{static_cast<size_t>(K)}); + s_a_data__ = Eigen::Matrix<double,-1,1>::Constant(K, + std::numeric_limits<double>::quiet_NaN()); + new (&s_a) Eigen::Map<Eigen::Matrix<double,-1,1>>(s_a_data__.data(), K); + { + std::vector<local_scalar_t__> s_a_flat__; + current_statement__ = 41; + s_a_flat__ = context__.vals_r("s_a"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + stan::model::assign(s_a, s_a_flat__[(pos__ - 1)], + "assigning variable s_a", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 42; + stan::math::validate_non_negative_index("s_m", "K", K); + current_statement__ = 43; + context__.validate_dims("data initialization", "s_m", "double", + std::vector<size_t>{static_cast<size_t>(K)}); + s_m_data__ = Eigen::Matrix<double,-1,1>::Constant(K, + std::numeric_limits<double>::quiet_NaN()); + new (&s_m) Eigen::Map<Eigen::Matrix<double,-1,1>>(s_m_data__.data(), K); + { + std::vector<local_scalar_t__> s_m_flat__; + current_statement__ = 43; + s_m_flat__ = context__.vals_r("s_m"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + stan::model::assign(s_m, s_m_flat__[(pos__ - 1)], + "assigning variable s_m", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + current_statement__ = 44; + stan::math::validate_non_negative_index("A", "T", T); + current_statement__ = 45; + stan::math::validate_non_negative_index("A", "S", S); + current_statement__ = 46; + A_data__ = Eigen::Matrix<double,-1,-1>::Constant(T, S, + std::numeric_limits<double>::quiet_NaN()); + new (&A) Eigen::Map<Eigen::Matrix<double,-1,-1>>(A_data__.data(), T, S); + current_statement__ = 46; + stan::model::assign(A, + get_changepoint_matrix(t, t_change, T, S, pstream__), + "assigning variable A"); + current_statement__ = 47; + stan::math::validate_non_negative_index("X_sa", "T", T); + current_statement__ = 48; + stan::math::validate_non_negative_index("X_sa", "K", K); + current_statement__ = 49; + X_sa_data__ = Eigen::Matrix<double,-1,-1>::Constant(T, K, + std::numeric_limits<double>::quiet_NaN()); + new (&X_sa) Eigen::Map<Eigen::Matrix<double,-1,-1>>(X_sa_data__.data(), + T, K); + current_statement__ = 49; + stan::model::assign(X_sa, + stan::math::elt_multiply(X, + stan::math::rep_matrix(stan::math::transpose(s_a), T)), + "assigning variable X_sa"); + current_statement__ = 50; + stan::math::validate_non_negative_index("X_sm", "T", T); + current_statement__ = 51; + stan::math::validate_non_negative_index("X_sm", "K", K); + current_statement__ = 52; + X_sm_data__ = Eigen::Matrix<double,-1,-1>::Constant(T, K, + std::numeric_limits<double>::quiet_NaN()); + new (&X_sm) Eigen::Map<Eigen::Matrix<double,-1,-1>>(X_sm_data__.data(), + T, K); + current_statement__ = 52; + stan::model::assign(X_sm, + stan::math::elt_multiply(X, + stan::math::rep_matrix(stan::math::transpose(s_m), T)), + "assigning variable X_sm"); + current_statement__ = 53; + stan::math::validate_non_negative_index("delta", "S", S); + current_statement__ = 54; + stan::math::validate_non_negative_index("beta", "K", K); + current_statement__ = 55; + stan::math::validate_non_negative_index("trend", "T", T); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + num_params_r__ = 1 + 1 + S + 1 + K; + } + inline std::string model_name() const final { + return "prophet_model"; + } + inline std::vector<std::string> model_compile_info() const noexcept { + return std::vector<std::string>{"stanc_version = stanc3 v2.33.1", + "stancflags = --filename-in-msg=prophet.stan"}; + } + // Base log prob + template <bool propto__, bool jacobian__, typename VecR, typename VecI, + stan::require_vector_like_t<VecR>* = nullptr, + stan::require_vector_like_vt<std::is_integral, VecI>* = nullptr, + stan::require_not_st_var<VecR>* = nullptr> + inline stan::scalar_type_t<VecR> + log_prob_impl(VecR& params_r__, VecI& params_i__, std::ostream* + pstream__ = nullptr) const { + using T__ = stan::scalar_type_t<VecR>; + using local_scalar_t__ = T__; + T__ lp__(0.0); + stan::math::accumulator<T__> lp_accum__; + stan::io::deserializer<local_scalar_t__> in__(params_r__, params_i__); + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + static constexpr const char* function__ = + "prophet_model_namespace::log_prob"; + // suppress unused var warning + (void) function__; + try { + local_scalar_t__ k = DUMMY_VAR__; + current_statement__ = 1; + k = in__.template read<local_scalar_t__>(); + local_scalar_t__ m = DUMMY_VAR__; + current_statement__ = 2; + m = in__.template read<local_scalar_t__>(); + Eigen::Matrix<local_scalar_t__,-1,1> delta = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(S, DUMMY_VAR__); + current_statement__ = 3; + delta = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(S); + local_scalar_t__ sigma_obs = DUMMY_VAR__; + current_statement__ = 4; + sigma_obs = in__.template read_constrain_lb<local_scalar_t__, + jacobian__>(0, lp__); + Eigen::Matrix<local_scalar_t__,-1,1> beta = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(K, DUMMY_VAR__); + current_statement__ = 5; + beta = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(K); + Eigen::Matrix<local_scalar_t__,-1,1> trend = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(T, DUMMY_VAR__); + current_statement__ = 15; + if (stan::math::logical_eq(trend_indicator, 0)) { + current_statement__ = 13; + stan::model::assign(trend, + linear_trend(k, m, delta, t, A, t_change, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 12; + if (stan::math::logical_eq(trend_indicator, 1)) { + current_statement__ = 10; + stan::model::assign(trend, + logistic_trend(k, m, delta, t, cap, A, t_change, S, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 9; + if (stan::math::logical_eq(trend_indicator, 2)) { + current_statement__ = 7; + stan::model::assign(trend, flat_trend(m, T, pstream__), + "assigning variable trend"); + } + } + } + { + current_statement__ = 16; + lp_accum__.add(stan::math::normal_lpdf<propto__>(k, 0, 5)); + current_statement__ = 17; + lp_accum__.add(stan::math::normal_lpdf<propto__>(m, 0, 5)); + current_statement__ = 18; + lp_accum__.add(stan::math::double_exponential_lpdf<propto__>(delta, + 0, tau)); + current_statement__ = 19; + lp_accum__.add(stan::math::normal_lpdf<propto__>(sigma_obs, 0, 0.5)); + current_statement__ = 20; + lp_accum__.add(stan::math::normal_lpdf<propto__>(beta, 0, sigmas)); + current_statement__ = 21; + lp_accum__.add(stan::math::normal_id_glm_lpdf<propto__>(y, X_sa, + stan::math::elt_multiply(trend, + stan::math::add(1, + stan::math::multiply(X_sm, beta))), beta, + sigma_obs)); + } + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + lp_accum__.add(lp__); + return lp_accum__.sum(); + } + // Reverse mode autodiff log prob + template <bool propto__, bool jacobian__, typename VecR, typename VecI, + stan::require_vector_like_t<VecR>* = nullptr, + stan::require_vector_like_vt<std::is_integral, VecI>* = nullptr, + stan::require_st_var<VecR>* = nullptr> + inline stan::scalar_type_t<VecR> + log_prob_impl(VecR& params_r__, VecI& params_i__, std::ostream* + pstream__ = nullptr) const { + using T__ = stan::scalar_type_t<VecR>; + using local_scalar_t__ = T__; + T__ lp__(0.0); + stan::math::accumulator<T__> lp_accum__; + stan::io::deserializer<local_scalar_t__> in__(params_r__, params_i__); + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + static constexpr const char* function__ = + "prophet_model_namespace::log_prob"; + // suppress unused var warning + (void) function__; + try { + local_scalar_t__ k = DUMMY_VAR__; + current_statement__ = 1; + k = in__.template read<local_scalar_t__>(); + local_scalar_t__ m = DUMMY_VAR__; + current_statement__ = 2; + m = in__.template read<local_scalar_t__>(); + Eigen::Matrix<local_scalar_t__,-1,1> delta = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(S, DUMMY_VAR__); + current_statement__ = 3; + delta = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(S); + local_scalar_t__ sigma_obs = DUMMY_VAR__; + current_statement__ = 4; + sigma_obs = in__.template read_constrain_lb<local_scalar_t__, + jacobian__>(0, lp__); + Eigen::Matrix<local_scalar_t__,-1,1> beta = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(K, DUMMY_VAR__); + current_statement__ = 5; + beta = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(K); + Eigen::Matrix<local_scalar_t__,-1,1> trend = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(T, DUMMY_VAR__); + current_statement__ = 15; + if (stan::math::logical_eq(trend_indicator, 0)) { + current_statement__ = 13; + stan::model::assign(trend, + linear_trend(k, m, delta, t, A, t_change, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 12; + if (stan::math::logical_eq(trend_indicator, 1)) { + current_statement__ = 10; + stan::model::assign(trend, + logistic_trend(k, m, delta, t, cap, A, t_change, S, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 9; + if (stan::math::logical_eq(trend_indicator, 2)) { + current_statement__ = 7; + stan::model::assign(trend, flat_trend(m, T, pstream__), + "assigning variable trend"); + } + } + } + { + current_statement__ = 16; + lp_accum__.add(stan::math::normal_lpdf<propto__>(k, 0, 5)); + current_statement__ = 17; + lp_accum__.add(stan::math::normal_lpdf<propto__>(m, 0, 5)); + current_statement__ = 18; + lp_accum__.add(stan::math::double_exponential_lpdf<propto__>(delta, + 0, tau)); + current_statement__ = 19; + lp_accum__.add(stan::math::normal_lpdf<propto__>(sigma_obs, 0, 0.5)); + current_statement__ = 20; + lp_accum__.add(stan::math::normal_lpdf<propto__>(beta, 0, sigmas)); + current_statement__ = 21; + lp_accum__.add(stan::math::normal_id_glm_lpdf<propto__>(y, X_sa, + stan::math::elt_multiply(trend, + stan::math::add(1, + stan::math::multiply(X_sm, beta))), beta, + sigma_obs)); + } + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + lp_accum__.add(lp__); + return lp_accum__.sum(); + } + template <typename RNG, typename VecR, typename VecI, typename VecVar, + stan::require_vector_like_vt<std::is_floating_point, + VecR>* = nullptr, stan::require_vector_like_vt<std::is_integral, + VecI>* = nullptr, stan::require_vector_vt<std::is_floating_point, + VecVar>* = nullptr> + inline void + write_array_impl(RNG& base_rng__, VecR& params_r__, VecI& params_i__, + VecVar& vars__, const bool + emit_transformed_parameters__ = true, const bool + emit_generated_quantities__ = true, std::ostream* + pstream__ = nullptr) const { + using local_scalar_t__ = double; + stan::io::deserializer<local_scalar_t__> in__(params_r__, params_i__); + stan::io::serializer<local_scalar_t__> out__(vars__); + static constexpr bool propto__ = true; + // suppress unused var warning + (void) propto__; + double lp__ = 0.0; + // suppress unused var warning + (void) lp__; + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + stan::math::accumulator<double> lp_accum__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + constexpr bool jacobian__ = false; + // suppress unused var warning + (void) jacobian__; + static constexpr const char* function__ = + "prophet_model_namespace::write_array"; + // suppress unused var warning + (void) function__; + try { + double k = std::numeric_limits<double>::quiet_NaN(); + current_statement__ = 1; + k = in__.template read<local_scalar_t__>(); + double m = std::numeric_limits<double>::quiet_NaN(); + current_statement__ = 2; + m = in__.template read<local_scalar_t__>(); + Eigen::Matrix<double,-1,1> delta = + Eigen::Matrix<double,-1,1>::Constant(S, + std::numeric_limits<double>::quiet_NaN()); + current_statement__ = 3; + delta = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(S); + double sigma_obs = std::numeric_limits<double>::quiet_NaN(); + current_statement__ = 4; + sigma_obs = in__.template read_constrain_lb<local_scalar_t__, + jacobian__>(0, lp__); + Eigen::Matrix<double,-1,1> beta = + Eigen::Matrix<double,-1,1>::Constant(K, + std::numeric_limits<double>::quiet_NaN()); + current_statement__ = 5; + beta = in__.template read<Eigen::Matrix<local_scalar_t__,-1,1>>(K); + Eigen::Matrix<double,-1,1> trend = + Eigen::Matrix<double,-1,1>::Constant(T, + std::numeric_limits<double>::quiet_NaN()); + out__.write(k); + out__.write(m); + out__.write(delta); + out__.write(sigma_obs); + out__.write(beta); + if (stan::math::logical_negation( + (stan::math::primitive_value(emit_transformed_parameters__) || + stan::math::primitive_value(emit_generated_quantities__)))) { + return ; + } + current_statement__ = 15; + if (stan::math::logical_eq(trend_indicator, 0)) { + current_statement__ = 13; + stan::model::assign(trend, + linear_trend(k, m, delta, t, A, t_change, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 12; + if (stan::math::logical_eq(trend_indicator, 1)) { + current_statement__ = 10; + stan::model::assign(trend, + logistic_trend(k, m, delta, t, cap, A, t_change, S, pstream__), + "assigning variable trend"); + } else { + current_statement__ = 9; + if (stan::math::logical_eq(trend_indicator, 2)) { + current_statement__ = 7; + stan::model::assign(trend, flat_trend(m, T, pstream__), + "assigning variable trend"); + } + } + } + if (emit_transformed_parameters__) { + out__.write(trend); + } + if (stan::math::logical_negation(emit_generated_quantities__)) { + return ; + } + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + } + template <typename VecVar, typename VecI, + stan::require_vector_t<VecVar>* = nullptr, + stan::require_vector_like_vt<std::is_integral, VecI>* = nullptr> + inline void + unconstrain_array_impl(const VecVar& params_r__, const VecI& params_i__, + VecVar& vars__, std::ostream* pstream__ = nullptr) const { + using local_scalar_t__ = double; + stan::io::deserializer<local_scalar_t__> in__(params_r__, params_i__); + stan::io::serializer<local_scalar_t__> out__(vars__); + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + local_scalar_t__ k = DUMMY_VAR__; + current_statement__ = 1; + k = in__.read<local_scalar_t__>(); + out__.write(k); + local_scalar_t__ m = DUMMY_VAR__; + current_statement__ = 2; + m = in__.read<local_scalar_t__>(); + out__.write(m); + Eigen::Matrix<local_scalar_t__,-1,1> delta = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(S, DUMMY_VAR__); + current_statement__ = 3; + stan::model::assign(delta, + in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(S), + "assigning variable delta"); + out__.write(delta); + local_scalar_t__ sigma_obs = DUMMY_VAR__; + current_statement__ = 4; + sigma_obs = in__.read<local_scalar_t__>(); + out__.write_free_lb(0, sigma_obs); + Eigen::Matrix<local_scalar_t__,-1,1> beta = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(K, DUMMY_VAR__); + current_statement__ = 5; + stan::model::assign(beta, + in__.read<Eigen::Matrix<local_scalar_t__,-1,1>>(K), + "assigning variable beta"); + out__.write(beta); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + } + template <typename VecVar, stan::require_vector_t<VecVar>* = nullptr> + inline void + transform_inits_impl(const stan::io::var_context& context__, VecVar& + vars__, std::ostream* pstream__ = nullptr) const { + using local_scalar_t__ = double; + stan::io::serializer<local_scalar_t__> out__(vars__); + int current_statement__ = 0; + // suppress unused var warning + (void) current_statement__; + local_scalar_t__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN()); + // suppress unused var warning + (void) DUMMY_VAR__; + try { + current_statement__ = 1; + context__.validate_dims("parameter initialization", "k", "double", + std::vector<size_t>{}); + current_statement__ = 2; + context__.validate_dims("parameter initialization", "m", "double", + std::vector<size_t>{}); + current_statement__ = 3; + context__.validate_dims("parameter initialization", "delta", "double", + std::vector<size_t>{static_cast<size_t>(S)}); + current_statement__ = 4; + context__.validate_dims("parameter initialization", "sigma_obs", + "double", std::vector<size_t>{}); + current_statement__ = 5; + context__.validate_dims("parameter initialization", "beta", "double", + std::vector<size_t>{static_cast<size_t>(K)}); + int pos__ = std::numeric_limits<int>::min(); + pos__ = 1; + local_scalar_t__ k = DUMMY_VAR__; + current_statement__ = 1; + k = context__.vals_r("k")[(1 - 1)]; + out__.write(k); + local_scalar_t__ m = DUMMY_VAR__; + current_statement__ = 2; + m = context__.vals_r("m")[(1 - 1)]; + out__.write(m); + Eigen::Matrix<local_scalar_t__,-1,1> delta = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(S, DUMMY_VAR__); + { + std::vector<local_scalar_t__> delta_flat__; + current_statement__ = 3; + delta_flat__ = context__.vals_r("delta"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= S; ++sym1__) { + stan::model::assign(delta, delta_flat__[(pos__ - 1)], + "assigning variable delta", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + out__.write(delta); + local_scalar_t__ sigma_obs = DUMMY_VAR__; + current_statement__ = 4; + sigma_obs = context__.vals_r("sigma_obs")[(1 - 1)]; + out__.write_free_lb(0, sigma_obs); + Eigen::Matrix<local_scalar_t__,-1,1> beta = + Eigen::Matrix<local_scalar_t__,-1,1>::Constant(K, DUMMY_VAR__); + { + std::vector<local_scalar_t__> beta_flat__; + current_statement__ = 5; + beta_flat__ = context__.vals_r("beta"); + pos__ = 1; + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + stan::model::assign(beta, beta_flat__[(pos__ - 1)], + "assigning variable beta", stan::model::index_uni(sym1__)); + pos__ = (pos__ + 1); + } + } + out__.write(beta); + } catch (const std::exception& e) { + stan::lang::rethrow_located(e, locations_array__[current_statement__]); + } + } + inline void + get_param_names(std::vector<std::string>& names__, const bool + emit_transformed_parameters__ = true, const bool + emit_generated_quantities__ = true) const { + names__ = std::vector<std::string>{"k", "m", "delta", "sigma_obs", + "beta"}; + if (emit_transformed_parameters__) { + std::vector<std::string> temp{"trend"}; + names__.reserve(names__.size() + temp.size()); + names__.insert(names__.end(), temp.begin(), temp.end()); + } + if (emit_generated_quantities__) {} + } + inline void + get_dims(std::vector<std::vector<size_t>>& dimss__, const bool + emit_transformed_parameters__ = true, const bool + emit_generated_quantities__ = true) const { + dimss__ = std::vector<std::vector<size_t>>{std::vector<size_t>{}, + std::vector<size_t>{}, + std::vector<size_t>{static_cast<size_t>(S)}, + std::vector<size_t>{}, + std::vector<size_t>{static_cast<size_t>(K)}}; + if (emit_transformed_parameters__) { + std::vector<std::vector<size_t>> + temp{std::vector<size_t>{static_cast<size_t>(T)}}; + dimss__.reserve(dimss__.size() + temp.size()); + dimss__.insert(dimss__.end(), temp.begin(), temp.end()); + } + if (emit_generated_quantities__) {} + } + inline void + constrained_param_names(std::vector<std::string>& param_names__, bool + emit_transformed_parameters__ = true, bool + emit_generated_quantities__ = true) const final { + param_names__.emplace_back(std::string() + "k"); + param_names__.emplace_back(std::string() + "m"); + for (int sym1__ = 1; sym1__ <= S; ++sym1__) { + param_names__.emplace_back(std::string() + "delta" + '.' + + std::to_string(sym1__)); + } + param_names__.emplace_back(std::string() + "sigma_obs"); + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + param_names__.emplace_back(std::string() + "beta" + '.' + + std::to_string(sym1__)); + } + if (emit_transformed_parameters__) { + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + param_names__.emplace_back(std::string() + "trend" + '.' + + std::to_string(sym1__)); + } + } + if (emit_generated_quantities__) {} + } + inline void + unconstrained_param_names(std::vector<std::string>& param_names__, bool + emit_transformed_parameters__ = true, bool + emit_generated_quantities__ = true) const final { + param_names__.emplace_back(std::string() + "k"); + param_names__.emplace_back(std::string() + "m"); + for (int sym1__ = 1; sym1__ <= S; ++sym1__) { + param_names__.emplace_back(std::string() + "delta" + '.' + + std::to_string(sym1__)); + } + param_names__.emplace_back(std::string() + "sigma_obs"); + for (int sym1__ = 1; sym1__ <= K; ++sym1__) { + param_names__.emplace_back(std::string() + "beta" + '.' + + std::to_string(sym1__)); + } + if (emit_transformed_parameters__) { + for (int sym1__ = 1; sym1__ <= T; ++sym1__) { + param_names__.emplace_back(std::string() + "trend" + '.' + + std::to_string(sym1__)); + } + } + if (emit_generated_quantities__) {} + } + inline std::string get_constrained_sizedtypes() const { + return std::string("[{\"name\":\"k\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"m\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"delta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(S) + "},\"block\":\"parameters\"},{\"name\":\"sigma_obs\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"beta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(K) + "},\"block\":\"parameters\"},{\"name\":\"trend\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(T) + "},\"block\":\"transformed_parameters\"}]"); + } + inline std::string get_unconstrained_sizedtypes() const { + return std::string("[{\"name\":\"k\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"m\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"delta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(S) + "},\"block\":\"parameters\"},{\"name\":\"sigma_obs\",\"type\":{\"name\":\"real\"},\"block\":\"parameters\"},{\"name\":\"beta\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(K) + "},\"block\":\"parameters\"},{\"name\":\"trend\",\"type\":{\"name\":\"vector\",\"length\":" + std::to_string(T) + "},\"block\":\"transformed_parameters\"}]"); + } + // Begin method overload boilerplate + template <typename RNG> inline void + write_array(RNG& base_rng, Eigen::Matrix<double,-1,1>& params_r, + Eigen::Matrix<double,-1,1>& vars, const bool + emit_transformed_parameters = true, const bool + emit_generated_quantities = true, std::ostream* + pstream = nullptr) const { + const size_t num_params__ = ((((1 + 1) + S) + 1) + K); + const size_t num_transformed = emit_transformed_parameters * (T); + const size_t num_gen_quantities = emit_generated_quantities * (0); + const size_t num_to_write = num_params__ + num_transformed + + num_gen_quantities; + std::vector<int> params_i; + vars = Eigen::Matrix<double,-1,1>::Constant(num_to_write, + std::numeric_limits<double>::quiet_NaN()); + write_array_impl(base_rng, params_r, params_i, vars, + emit_transformed_parameters, emit_generated_quantities, pstream); + } + template <typename RNG> inline void + write_array(RNG& base_rng, std::vector<double>& params_r, std::vector<int>& + params_i, std::vector<double>& vars, bool + emit_transformed_parameters = true, bool + emit_generated_quantities = true, std::ostream* + pstream = nullptr) const { + const size_t num_params__ = ((((1 + 1) + S) + 1) + K); + const size_t num_transformed = emit_transformed_parameters * (T); + const size_t num_gen_quantities = emit_generated_quantities * (0); + const size_t num_to_write = num_params__ + num_transformed + + num_gen_quantities; + vars = std::vector<double>(num_to_write, + std::numeric_limits<double>::quiet_NaN()); + write_array_impl(base_rng, params_r, params_i, vars, + emit_transformed_parameters, emit_generated_quantities, pstream); + } + template <bool propto__, bool jacobian__, typename T_> inline T_ + log_prob(Eigen::Matrix<T_,-1,1>& params_r, std::ostream* pstream = nullptr) const { + Eigen::Matrix<int,-1,1> params_i; + return log_prob_impl<propto__, jacobian__>(params_r, params_i, pstream); + } + template <bool propto__, bool jacobian__, typename T_> inline T_ + log_prob(std::vector<T_>& params_r, std::vector<int>& params_i, + std::ostream* pstream = nullptr) const { + return log_prob_impl<propto__, jacobian__>(params_r, params_i, pstream); + } + inline void + transform_inits(const stan::io::var_context& context, + Eigen::Matrix<double,-1,1>& params_r, std::ostream* + pstream = nullptr) const final { + std::vector<double> params_r_vec(params_r.size()); + std::vector<int> params_i; + transform_inits(context, params_i, params_r_vec, pstream); + params_r = Eigen::Map<Eigen::Matrix<double,-1,1>>(params_r_vec.data(), + params_r_vec.size()); + } + inline void + transform_inits(const stan::io::var_context& context, std::vector<int>& + params_i, std::vector<double>& vars, std::ostream* + pstream__ = nullptr) const { + vars.resize(num_params_r__); + transform_inits_impl(context, vars, pstream__); + } + inline void + unconstrain_array(const std::vector<double>& params_constrained, + std::vector<double>& params_unconstrained, std::ostream* + pstream = nullptr) const { + const std::vector<int> params_i; + params_unconstrained = std::vector<double>(num_params_r__, + std::numeric_limits<double>::quiet_NaN()); + unconstrain_array_impl(params_constrained, params_i, + params_unconstrained, pstream); + } + inline void + unconstrain_array(const Eigen::Matrix<double,-1,1>& params_constrained, + Eigen::Matrix<double,-1,1>& params_unconstrained, + std::ostream* pstream = nullptr) const { + const std::vector<int> params_i; + params_unconstrained = Eigen::Matrix<double,-1,1>::Constant(num_params_r__, + std::numeric_limits<double>::quiet_NaN()); + unconstrain_array_impl(params_constrained, params_i, + params_unconstrained, pstream); + } +}; +} +using stan_model = prophet_model_namespace::prophet_model; +#ifndef USING_R +// Boilerplate +stan::model::model_base& +new_model(stan::io::var_context& data_context, unsigned int seed, + std::ostream* msg_stream) { + stan_model* m = new stan_model(data_context, seed, msg_stream); + return *m; +} +stan::math::profile_map& get_stan_profile_data() { + return prophet_model_namespace::profiles__; +} +#endif \ No newline at end of file diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet.stan b/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet.stan new file mode 100644 index 00000000..05bcb34a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet.stan @@ -0,0 +1,143 @@ +// Copyright (c) Facebook, Inc. and its affiliates. + +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +functions { + matrix get_changepoint_matrix(vector t, vector t_change, int T, int S) { + // Assumes t and t_change are sorted. + matrix[T, S] A; + row_vector[S] a_row; + int cp_idx; + + // Start with an empty matrix. + A = rep_matrix(0, T, S); + a_row = rep_row_vector(0, S); + cp_idx = 1; + + // Fill in each row of A. + for (i in 1:T) { + while ((cp_idx <= S) && (t[i] >= t_change[cp_idx])) { + a_row[cp_idx] = 1; + cp_idx = cp_idx + 1; + } + A[i] = a_row; + } + return A; + } + + // Logistic trend functions + + vector logistic_gamma(real k, real m, vector delta, vector t_change, int S) { + vector[S] gamma; // adjusted offsets, for piecewise continuity + vector[S + 1] k_s; // actual rate in each segment + real m_pr; + + // Compute the rate in each segment + k_s = append_row(k, k + cumulative_sum(delta)); + + // Piecewise offsets + m_pr = m; // The offset in the previous segment + for (i in 1:S) { + gamma[i] = (t_change[i] - m_pr) * (1 - k_s[i] / k_s[i + 1]); + m_pr = m_pr + gamma[i]; // update for the next segment + } + return gamma; + } + + vector logistic_trend( + real k, + real m, + vector delta, + vector t, + vector cap, + matrix A, + vector t_change, + int S + ) { + vector[S] gamma; + + gamma = logistic_gamma(k, m, delta, t_change, S); + return cap .* inv_logit((k + A * delta) .* (t - (m + A * gamma))); + } + + // Linear trend function + + vector linear_trend( + real k, + real m, + vector delta, + vector t, + matrix A, + vector t_change + ) { + return (k + A * delta) .* t + (m + A * (-t_change .* delta)); + } + + // Flat trend function + + vector flat_trend( + real m, + int T + ) { + return rep_vector(m, T); + } +} + +data { + int T; // Number of time periods + int<lower=1> K; // Number of regressors + vector[T] t; // Time + vector[T] cap; // Capacities for logistic trend + vector[T] y; // Time series + int S; // Number of changepoints + vector[S] t_change; // Times of trend changepoints + matrix[T,K] X; // Regressors + vector[K] sigmas; // Scale on seasonality prior + real<lower=0> tau; // Scale on changepoints prior + int trend_indicator; // 0 for linear, 1 for logistic, 2 for flat + vector[K] s_a; // Indicator of additive features + vector[K] s_m; // Indicator of multiplicative features +} + +transformed data { + matrix[T, S] A = get_changepoint_matrix(t, t_change, T, S); + matrix[T, K] X_sa = X .* rep_matrix(s_a', T); + matrix[T, K] X_sm = X .* rep_matrix(s_m', T); +} + +parameters { + real k; // Base trend growth rate + real m; // Trend offset + vector[S] delta; // Trend rate adjustments + real<lower=0> sigma_obs; // Observation noise + vector[K] beta; // Regressor coefficients +} + +transformed parameters { + vector[T] trend; + if (trend_indicator == 0) { + trend = linear_trend(k, m, delta, t, A, t_change); + } else if (trend_indicator == 1) { + trend = logistic_trend(k, m, delta, t, cap, A, t_change, S); + } else if (trend_indicator == 2) { + trend = flat_trend(m, T); + } +} + +model { + //priors + k ~ normal(0, 5); + m ~ normal(0, 5); + delta ~ double_exponential(0, tau); + sigma_obs ~ normal(0, 0.5); + beta ~ normal(0, sigmas); + + // Likelihood + y ~ normal_id_glm( + X_sa, + trend .* (1 + X_sm * beta), + beta, + sigma_obs + ); +} diff --git a/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet_model.bin b/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet_model.bin new file mode 100755 index 00000000..65101a12 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/stan_model/prophet_model.bin differ diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/__init__.py b/.venv/lib/python3.12/site-packages/prophet/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..658eac91 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/conftest.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/conftest.cpython-312.pyc new file mode 100644 index 00000000..76bd18e3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/conftest.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_diagnostics.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_diagnostics.cpython-312.pyc new file mode 100644 index 00000000..e260bf56 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_diagnostics.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_prophet.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_prophet.cpython-312.pyc new file mode 100644 index 00000000..eb3e5109 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_prophet.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_serialize.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_serialize.cpython-312.pyc new file mode 100644 index 00000000..d37654b9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_serialize.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_utilities.cpython-312.pyc b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_utilities.cpython-312.pyc new file mode 100644 index 00000000..304b5fa3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/prophet/tests/__pycache__/test_utilities.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/conftest.py b/.venv/lib/python3.12/site-packages/prophet/tests/conftest.py new file mode 100644 index 00000000..bc168216 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/conftest.py @@ -0,0 +1,57 @@ +from pathlib import Path + +import pandas as pd +import pytest + + +@pytest.fixture(scope="package") +def daily_univariate_ts() -> pd.DataFrame: + """Daily univariate time series with 2 years of data""" + return pd.read_csv(Path(__file__).parent / "data.csv", parse_dates=["ds"]) + + +@pytest.fixture(scope="package") +def subdaily_univariate_ts() -> pd.DataFrame: + """Sub-daily univariate time series""" + return pd.read_csv(Path(__file__).parent / "data2.csv", parse_dates=["ds"]) + + +@pytest.fixture(scope="package") +def large_numbers_ts() -> pd.DataFrame: + """Univariate time series with large values to test scaling""" + return pd.read_csv(Path(__file__).parent / "data3.csv", parse_dates=["ds"]) + + +def pytest_configure(config): + config.addinivalue_line("markers", "slow: mark tests as slow (include in run with --test-slow)") + + +def pytest_addoption(parser): + parser.addoption("--test-slow", action="store_true", default=False, help="Run slow tests") + parser.addoption( + "--backend", + nargs="+", + default=["CMDSTANPY"], + help="Probabilistic Programming Language backend to perform tests with.", + ) + + +def pytest_collection_modifyitems(config, items): + if config.getoption("--test-slow"): + return + skip_slow = pytest.mark.skip(reason="Skipped due to the lack of '--test-slow' argument") + for item in items: + if "slow" in item.keywords: + item.add_marker(skip_slow) + + +def pytest_generate_tests(metafunc): + """ + For each test, if `backend` is used as a fixture, add a parametrization equal to the value of the + --backend option. + + This is used to re-run the test suite for different probabilistic programming language backends + (e.g. cmdstanpy, numpyro). + """ + if "backend" in metafunc.fixturenames: + metafunc.parametrize("backend", metafunc.config.getoption("backend")) diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/data.csv b/.venv/lib/python3.12/site-packages/prophet/tests/data.csv new file mode 100644 index 00000000..f59d29b8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/data.csv @@ -0,0 +1,511 @@ +ds,y +2012-05-18,38.23 +2012-05-21,34.03 +2012-05-22,31.0 +2012-05-23,32.0 +2012-05-24,33.03 +2012-05-25,31.91 +2012-05-29,28.84 +2012-05-30,28.19 +2012-05-31,29.6 +2012-06-01,27.72 +2012-06-04,26.9 +2012-06-05,25.87 +2012-06-06,26.81 +2012-06-07,26.31 +2012-06-08,27.1 +2012-06-11,27.01 +2012-06-12,27.4 +2012-06-13,27.27 +2012-06-14,28.29 +2012-06-15,30.01 +2012-06-18,31.41 +2012-06-19,31.91 +2012-06-20,31.6 +2012-06-21,31.84 +2012-06-22,33.05 +2012-06-25,32.06 +2012-06-26,33.1 +2012-06-27,32.23 +2012-06-28,31.36 +2012-06-29,31.1 +2012-07-02,30.77 +2012-07-03,31.2 +2012-07-05,31.47 +2012-07-06,31.73 +2012-07-09,32.17 +2012-07-10,31.47 +2012-07-11,30.97 +2012-07-12,30.81 +2012-07-13,30.72 +2012-07-16,28.25 +2012-07-17,28.09 +2012-07-18,29.11 +2012-07-19,29.0 +2012-07-20,28.76 +2012-07-23,28.75 +2012-07-24,28.45 +2012-07-25,29.34 +2012-07-26,26.85 +2012-07-27,23.71 +2012-07-30,23.15 +2012-07-31,21.71 +2012-08-01,20.88 +2012-08-02,20.04 +2012-08-03,21.09 +2012-08-06,21.92 +2012-08-07,20.72 +2012-08-08,20.72 +2012-08-09,21.01 +2012-08-10,21.81 +2012-08-13,21.6 +2012-08-14,20.38 +2012-08-15,21.2 +2012-08-16,19.87 +2012-08-17,19.05 +2012-08-20,20.01 +2012-08-21,19.16 +2012-08-22,19.44 +2012-08-23,19.44 +2012-08-24,19.41 +2012-08-27,19.15 +2012-08-28,19.34 +2012-08-29,19.1 +2012-08-30,19.09 +2012-08-31,18.06 +2012-09-04,17.73 +2012-09-05,18.58 +2012-09-06,18.96 +2012-09-07,18.98 +2012-09-10,18.81 +2012-09-11,19.43 +2012-09-12,20.93 +2012-09-13,20.71 +2012-09-14,22.0 +2012-09-17,21.52 +2012-09-18,21.87 +2012-09-19,23.29 +2012-09-20,22.59 +2012-09-21,22.86 +2012-09-24,20.79 +2012-09-25,20.28 +2012-09-26,20.62 +2012-09-27,20.32 +2012-09-28,21.66 +2012-10-01,21.99 +2012-10-02,22.27 +2012-10-03,21.83 +2012-10-04,21.95 +2012-10-05,20.91 +2012-10-08,20.4 +2012-10-09,20.23 +2012-10-10,19.64 +2012-10-11,19.75 +2012-10-12,19.52 +2012-10-15,19.52 +2012-10-16,19.48 +2012-10-17,19.88 +2012-10-18,18.98 +2012-10-19,19.0 +2012-10-22,19.32 +2012-10-23,19.5 +2012-10-24,23.23 +2012-10-25,22.56 +2012-10-26,21.94 +2012-10-31,21.11 +2012-11-01,21.21 +2012-11-02,21.18 +2012-11-05,21.25 +2012-11-06,21.17 +2012-11-07,20.47 +2012-11-08,19.99 +2012-11-09,19.21 +2012-11-12,20.07 +2012-11-13,19.86 +2012-11-14,22.36 +2012-11-15,22.17 +2012-11-16,23.56 +2012-11-19,22.92 +2012-11-20,23.1 +2012-11-21,24.32 +2012-11-23,24.0 +2012-11-26,25.94 +2012-11-27,26.15 +2012-11-28,26.36 +2012-11-29,27.32 +2012-11-30,28.0 +2012-12-03,27.04 +2012-12-04,27.46 +2012-12-05,27.71 +2012-12-06,26.97 +2012-12-07,27.49 +2012-12-10,27.84 +2012-12-11,27.98 +2012-12-12,27.58 +2012-12-13,28.24 +2012-12-14,26.81 +2012-12-17,26.75 +2012-12-18,27.71 +2012-12-19,27.41 +2012-12-20,27.36 +2012-12-21,26.26 +2012-12-24,26.93 +2012-12-26,26.51 +2012-12-27,26.05 +2012-12-28,25.91 +2012-12-31,26.62 +2013-01-02,28.0 +2013-01-03,27.77 +2013-01-04,28.76 +2013-01-07,29.42 +2013-01-08,29.06 +2013-01-09,30.59 +2013-01-10,31.3 +2013-01-11,31.72 +2013-01-14,30.95 +2013-01-15,30.1 +2013-01-16,29.85 +2013-01-17,30.14 +2013-01-18,29.66 +2013-01-22,30.73 +2013-01-23,30.82 +2013-01-24,31.08 +2013-01-25,31.54 +2013-01-28,32.47 +2013-01-29,30.79 +2013-01-30,31.24 +2013-01-31,30.98 +2013-02-01,29.73 +2013-02-04,28.11 +2013-02-05,28.64 +2013-02-06,29.05 +2013-02-07,28.65 +2013-02-08,28.55 +2013-02-11,28.26 +2013-02-12,27.37 +2013-02-13,27.91 +2013-02-14,28.5 +2013-02-15,28.32 +2013-02-19,28.93 +2013-02-20,28.46 +2013-02-21,27.28 +2013-02-22,27.13 +2013-02-25,27.27 +2013-02-26,27.39 +2013-02-27,26.87 +2013-02-28,27.25 +2013-03-01,27.78 +2013-03-04,27.72 +2013-03-05,27.52 +2013-03-06,27.45 +2013-03-07,28.58 +2013-03-08,27.96 +2013-03-11,28.14 +2013-03-12,27.83 +2013-03-13,27.08 +2013-03-14,27.04 +2013-03-15,26.65 +2013-03-18,26.49 +2013-03-19,26.55 +2013-03-20,25.86 +2013-03-21,25.74 +2013-03-22,25.73 +2013-03-25,25.13 +2013-03-26,25.21 +2013-03-27,26.09 +2013-03-28,25.58 +2013-04-01,25.53 +2013-04-02,25.42 +2013-04-03,26.25 +2013-04-04,27.07 +2013-04-05,27.39 +2013-04-08,26.85 +2013-04-09,26.59 +2013-04-10,27.57 +2013-04-11,28.02 +2013-04-12,27.4 +2013-04-15,26.52 +2013-04-16,26.92 +2013-04-17,26.63 +2013-04-18,25.69 +2013-04-19,25.73 +2013-04-22,25.97 +2013-04-23,25.98 +2013-04-24,26.11 +2013-04-25,26.14 +2013-04-26,26.85 +2013-04-29,26.98 +2013-04-30,27.77 +2013-05-01,27.43 +2013-05-02,28.97 +2013-05-03,28.31 +2013-05-06,27.57 +2013-05-07,26.89 +2013-05-08,27.12 +2013-05-09,27.04 +2013-05-10,26.68 +2013-05-13,26.82 +2013-05-14,27.07 +2013-05-15,26.6 +2013-05-16,26.13 +2013-05-17,26.25 +2013-05-20,25.76 +2013-05-21,25.66 +2013-05-22,25.16 +2013-05-23,25.06 +2013-05-24,24.31 +2013-05-28,24.1 +2013-05-29,23.32 +2013-05-30,24.55 +2013-05-31,24.35 +2013-06-03,23.85 +2013-06-04,23.52 +2013-06-05,22.9 +2013-06-06,22.97 +2013-06-07,23.29 +2013-06-10,24.33 +2013-06-11,24.03 +2013-06-12,23.77 +2013-06-13,23.73 +2013-06-14,23.63 +2013-06-17,24.02 +2013-06-18,24.21 +2013-06-19,24.31 +2013-06-20,23.9 +2013-06-21,24.53 +2013-06-24,23.94 +2013-06-25,24.25 +2013-06-26,24.16 +2013-06-27,24.66 +2013-06-28,24.88 +2013-07-01,24.81 +2013-07-02,24.41 +2013-07-03,24.52 +2013-07-05,24.37 +2013-07-08,24.71 +2013-07-09,25.48 +2013-07-10,25.8 +2013-07-11,25.81 +2013-07-12,25.91 +2013-07-15,26.28 +2013-07-16,26.32 +2013-07-17,26.65 +2013-07-18,26.18 +2013-07-19,25.88 +2013-07-22,26.05 +2013-07-23,26.13 +2013-07-24,26.51 +2013-07-25,34.36 +2013-07-26,34.01 +2013-07-29,35.43 +2013-07-30,37.63 +2013-07-31,36.8 +2013-08-01,37.49 +2013-08-02,38.05 +2013-08-05,39.19 +2013-08-06,38.55 +2013-08-07,38.87 +2013-08-08,38.54 +2013-08-09,38.5 +2013-08-12,38.22 +2013-08-13,37.02 +2013-08-14,36.65 +2013-08-15,36.56 +2013-08-16,37.08 +2013-08-19,37.81 +2013-08-20,38.41 +2013-08-21,38.32 +2013-08-22,38.55 +2013-08-23,40.55 +2013-08-26,41.34 +2013-08-27,39.64 +2013-08-28,40.55 +2013-08-29,41.28 +2013-08-30,41.29 +2013-09-03,41.87 +2013-09-04,41.78 +2013-09-05,42.66 +2013-09-06,43.95 +2013-09-09,44.04 +2013-09-10,43.6 +2013-09-11,45.04 +2013-09-12,44.75 +2013-09-13,44.31 +2013-09-16,42.51 +2013-09-17,45.07 +2013-09-18,45.23 +2013-09-19,45.98 +2013-09-20,47.49 +2013-09-23,47.19 +2013-09-24,48.45 +2013-09-25,49.46 +2013-09-26,50.39 +2013-09-27,51.24 +2013-09-30,50.23 +2013-10-01,50.42 +2013-10-02,50.28 +2013-10-03,49.18 +2013-10-04,51.04 +2013-10-07,50.52 +2013-10-08,47.14 +2013-10-09,46.77 +2013-10-10,49.05 +2013-10-11,49.11 +2013-10-14,49.51 +2013-10-15,49.5 +2013-10-16,51.14 +2013-10-17,52.21 +2013-10-18,54.22 +2013-10-21,53.85 +2013-10-22,52.68 +2013-10-23,51.9 +2013-10-24,52.45 +2013-10-25,51.95 +2013-10-28,50.23 +2013-10-29,49.4 +2013-10-30,49.01 +2013-10-31,50.21 +2013-11-01,49.75 +2013-11-04,48.22 +2013-11-05,50.11 +2013-11-06,49.12 +2013-11-07,47.56 +2013-11-08,47.53 +2013-11-11,46.2 +2013-11-12,46.61 +2013-11-13,48.71 +2013-11-14,48.99 +2013-11-15,49.01 +2013-11-18,45.83 +2013-11-19,46.36 +2013-11-20,46.43 +2013-11-21,46.7 +2013-11-22,46.23 +2013-11-25,44.82 +2013-11-26,45.89 +2013-11-27,46.49 +2013-11-29,47.01 +2013-12-02,47.06 +2013-12-03,46.73 +2013-12-04,48.62 +2013-12-05,48.34 +2013-12-06,47.94 +2013-12-09,48.84 +2013-12-10,50.25 +2013-12-11,49.38 +2013-12-12,51.83 +2013-12-13,53.32 +2013-12-16,53.81 +2013-12-17,54.86 +2013-12-18,55.57 +2013-12-19,55.05 +2013-12-20,55.12 +2013-12-23,57.77 +2013-12-24,57.96 +2013-12-26,57.73 +2013-12-27,55.44 +2013-12-30,53.71 +2013-12-31,54.65 +2014-01-02,54.71 +2014-01-03,54.56 +2014-01-06,57.2 +2014-01-07,57.92 +2014-01-08,58.23 +2014-01-09,57.22 +2014-01-10,57.94 +2014-01-13,55.91 +2014-01-14,57.74 +2014-01-15,57.6 +2014-01-16,57.19 +2014-01-17,56.3 +2014-01-21,58.51 +2014-01-22,57.51 +2014-01-23,56.63 +2014-01-24,54.45 +2014-01-27,53.55 +2014-01-28,55.14 +2014-01-29,53.53 +2014-01-30,61.08 +2014-01-31,62.57 +2014-02-03,61.48 +2014-02-04,62.75 +2014-02-05,62.19 +2014-02-06,62.16 +2014-02-07,64.32 +2014-02-10,63.55 +2014-02-11,64.85 +2014-02-12,64.45 +2014-02-13,67.33 +2014-02-14,67.09 +2014-02-18,67.3 +2014-02-19,68.06 +2014-02-20,69.63 +2014-02-21,68.59 +2014-02-24,70.78 +2014-02-25,69.85 +2014-02-26,69.26 +2014-02-27,68.94 +2014-02-28,68.46 +2014-03-03,67.41 +2014-03-04,68.8 +2014-03-05,71.57 +2014-03-06,70.84 +2014-03-07,69.8 +2014-03-10,72.03 +2014-03-11,70.1 +2014-03-12,70.88 +2014-03-13,68.83 +2014-03-14,67.72 +2014-03-17,68.74 +2014-03-18,69.19 +2014-03-19,68.24 +2014-03-20,66.97 +2014-03-21,67.24 +2014-03-24,64.1 +2014-03-25,64.89 +2014-03-26,60.39 +2014-03-27,60.97 +2014-03-28,60.01 +2014-03-31,60.24 +2014-04-01,62.62 +2014-04-02,62.72 +2014-04-03,59.49 +2014-04-04,56.75 +2014-04-07,56.95 +2014-04-08,58.19 +2014-04-09,62.41 +2014-04-10,59.16 +2014-04-11,58.53 +2014-04-14,58.89 +2014-04-15,59.09 +2014-04-16,59.72 +2014-04-17,58.94 +2014-04-21,61.24 +2014-04-22,63.03 +2014-04-23,61.36 +2014-04-24,60.87 +2014-04-25,57.71 +2014-04-28,56.14 +2014-04-29,58.15 +2014-04-30,59.78 +2014-05-01,61.15 +2014-05-02,60.46 +2014-05-05,61.22 +2014-05-06,58.53 +2014-05-07,57.39 +2014-05-08,56.76 +2014-05-09,57.24 +2014-05-12,59.83 +2014-05-13,59.83 +2014-05-14,59.23 +2014-05-15,57.92 +2014-05-16,58.02 +2014-05-19,59.21 +2014-05-20,58.56 +2014-05-21,60.49 +2014-05-22,60.52 +2014-05-23,61.35 +2014-05-27,63.48 +2014-05-28,63.51 +2014-05-29,63.83 +2014-05-30,63.30 diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/data2.csv b/.venv/lib/python3.12/site-packages/prophet/tests/data2.csv new file mode 100644 index 00000000..9885a89c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/data2.csv @@ -0,0 +1,864 @@ +ds,y +2017-01-01 00:05:00,0.0 +2017-01-01 00:10:00,0.0 +2017-01-01 00:15:00,0.0 +2017-01-01 00:20:00,0.0 +2017-01-01 00:25:00,-0.1 +2017-01-01 00:30:00,-0.1 +2017-01-01 00:35:00,-0.1 +2017-01-01 00:40:00,-0.1 +2017-01-01 00:45:00,-0.1 +2017-01-01 00:50:00,-0.1 +2017-01-01 00:55:00,-0.3 +2017-01-01 01:00:00,-0.2 +2017-01-01 01:05:00,-0.3 +2017-01-01 01:10:00,-0.4 +2017-01-01 01:15:00,-0.4 +2017-01-01 01:20:00,-0.3 +2017-01-01 01:25:00,-0.3 +2017-01-01 01:30:00,-0.2 +2017-01-01 01:35:00,-0.3 +2017-01-01 01:40:00,-0.3 +2017-01-01 01:45:00,-0.3 +2017-01-01 01:50:00,-0.3 +2017-01-01 01:55:00,-0.3 +2017-01-01 02:00:00,-0.3 +2017-01-01 02:05:00,-0.3 +2017-01-01 02:10:00,-0.3 +2017-01-01 02:15:00,-0.3 +2017-01-01 02:20:00,-0.3 +2017-01-01 02:25:00,-0.3 +2017-01-01 02:30:00,-0.3 +2017-01-01 02:35:00,-0.3 +2017-01-01 02:40:00,-0.3 +2017-01-01 02:45:00,-0.3 +2017-01-01 02:50:00,-0.3 +2017-01-01 02:55:00,-0.3 +2017-01-01 03:00:00,-0.3 +2017-01-01 03:05:00,-0.3 +2017-01-01 03:10:00,-0.3 +2017-01-01 03:15:00,-0.3 +2017-01-01 03:20:00,-0.3 +2017-01-01 03:25:00,-0.4 +2017-01-01 03:30:00,-0.6 +2017-01-01 03:35:00,-0.4 +2017-01-01 03:40:00,-0.3 +2017-01-01 03:45:00,-0.4 +2017-01-01 03:50:00,-0.7 +2017-01-01 03:55:00,-0.8 +2017-01-01 04:00:00,-0.4 +2017-01-01 04:05:00,-0.3 +2017-01-01 04:10:00,-0.4 +2017-01-01 04:15:00,-0.4 +2017-01-01 04:20:00,-0.4 +2017-01-01 04:25:00,-0.5 +2017-01-01 04:30:00,-0.5 +2017-01-01 04:35:00,-0.5 +2017-01-01 04:40:00,-0.4 +2017-01-01 04:45:00,-0.5 +2017-01-01 04:50:00,-0.5 +2017-01-01 04:55:00,-0.5 +2017-01-01 05:00:00,-0.6 +2017-01-01 05:05:00,-0.9 +2017-01-01 05:10:00,-0.9 +2017-01-01 05:15:00,-1.2 +2017-01-01 05:20:00,-1.4 +2017-01-01 05:25:00,-1.8 +2017-01-01 05:30:00,-2.0 +2017-01-01 05:35:00,-2.2 +2017-01-01 05:40:00,-1.6 +2017-01-01 05:45:00,-1.2 +2017-01-01 05:50:00,-1.2 +2017-01-01 05:55:00,-1.4 +2017-01-01 06:00:00,-1.2 +2017-01-01 06:05:00,-0.9 +2017-01-01 06:10:00,-0.9 +2017-01-01 06:15:00,-0.9 +2017-01-01 06:20:00,-0.9 +2017-01-01 06:25:00,-0.9 +2017-01-01 06:30:00,-1.2 +2017-01-01 06:35:00,-1.1 +2017-01-01 06:40:00,-1.2 +2017-01-01 06:45:00,-1.3 +2017-01-01 06:50:00,-1.4 +2017-01-01 06:55:00,-1.7 +2017-01-01 07:00:00,-1.7 +2017-01-01 07:05:00,-1.7 +2017-01-01 07:10:00,-1.8 +2017-01-01 07:15:00,-2.4 +2017-01-01 07:20:00,-2.9 +2017-01-01 07:25:00,-3.2 +2017-01-01 07:30:00,-3.4 +2017-01-01 07:35:00,-3.6 +2017-01-01 07:40:00,-3.6 +2017-01-01 07:45:00,-3.5 +2017-01-01 07:50:00,-3.5 +2017-01-01 07:55:00,-3.5 +2017-01-01 08:00:00,-3.6 +2017-01-01 08:05:00,-3.7 +2017-01-01 08:10:00,-3.6 +2017-01-01 08:15:00,-3.6 +2017-01-01 08:20:00,-3.8 +2017-01-01 08:25:00,-4.0 +2017-01-01 08:30:00,-3.9 +2017-01-01 08:35:00,-3.9 +2017-01-01 08:40:00,-4.1 +2017-01-01 08:45:00,-4.0 +2017-01-01 08:50:00,-4.1 +2017-01-01 08:55:00,-4.1 +2017-01-01 09:00:00,-4.2 +2017-01-01 09:05:00,-4.1 +2017-01-01 09:10:00,-4.2 +2017-01-01 09:15:00,-4.1 +2017-01-01 09:20:00,-4.0 +2017-01-01 09:25:00,-4.0 +2017-01-01 09:30:00,-4.0 +2017-01-01 09:35:00,-4.1 +2017-01-01 09:40:00,-4.1 +2017-01-01 09:45:00,-4.2 +2017-01-01 09:50:00,-4.3 +2017-01-01 09:55:00,-4.4 +2017-01-01 10:00:00,-4.5 +2017-01-01 10:05:00,-4.6 +2017-01-01 10:10:00,-4.7 +2017-01-01 10:15:00,-4.6 +2017-01-01 10:20:00,-4.6 +2017-01-01 10:25:00,-4.6 +2017-01-01 10:30:00,-4.5 +2017-01-01 10:35:00,-4.6 +2017-01-01 10:40:00,-4.6 +2017-01-01 10:45:00,-4.6 +2017-01-01 10:50:00,-4.6 +2017-01-01 10:55:00,-4.7 +2017-01-01 11:00:00,-4.7 +2017-01-01 11:05:00,-4.6 +2017-01-01 11:10:00,-4.5 +2017-01-01 11:15:00,-4.7 +2017-01-01 11:20:00,-4.7 +2017-01-01 11:25:00,-4.8 +2017-01-01 11:30:00,-4.8 +2017-01-01 11:35:00,-4.8 +2017-01-01 11:40:00,-4.8 +2017-01-01 11:45:00,-4.7 +2017-01-01 11:50:00,-4.6 +2017-01-01 11:55:00,-4.6 +2017-01-01 12:00:00,-4.8 +2017-01-01 12:05:00,-4.9 +2017-01-01 12:10:00,-4.9 +2017-01-01 12:15:00,-4.9 +2017-01-01 12:20:00,-5.0 +2017-01-01 12:25:00,-4.9 +2017-01-01 12:30:00,-4.9 +2017-01-01 12:35:00,-5.0 +2017-01-01 12:40:00,-5.1 +2017-01-01 12:45:00,-5.3 +2017-01-01 12:50:00,-5.5 +2017-01-01 12:55:00,-5.7 +2017-01-01 13:00:00,-5.8 +2017-01-01 13:05:00,-5.9 +2017-01-01 13:10:00,-5.9 +2017-01-01 13:15:00,-6.1 +2017-01-01 13:20:00,-6.1 +2017-01-01 13:25:00,-6.1 +2017-01-01 13:30:00,-6.2 +2017-01-01 13:35:00,-6.3 +2017-01-01 13:40:00,-6.4 +2017-01-01 13:45:00,-6.5 +2017-01-01 13:50:00,-6.6 +2017-01-01 13:55:00,-6.7 +2017-01-01 14:00:00,-6.7 +2017-01-01 14:05:00,-6.7 +2017-01-01 14:10:00,-6.6 +2017-01-01 14:15:00,-6.7 +2017-01-01 14:20:00,-6.7 +2017-01-01 14:25:00,-6.6 +2017-01-01 14:30:00,-6.7 +2017-01-01 14:35:00,-6.6 +2017-01-01 14:40:00,-6.6 +2017-01-01 14:45:00,-6.4 +2017-01-01 14:50:00,-6.5 +2017-01-01 14:55:00,-6.5 +2017-01-01 15:00:00,-6.4 +2017-01-01 15:05:00,-6.4 +2017-01-01 15:10:00,-6.3 +2017-01-01 15:15:00,-6.3 +2017-01-01 15:20:00,-6.4 +2017-01-01 15:25:00,-6.5 +2017-01-01 15:30:00,-6.6 +2017-01-01 15:35:00,-6.6 +2017-01-01 15:40:00,-6.6 +2017-01-01 15:45:00,-6.6 +2017-01-01 15:50:00,-6.5 +2017-01-01 15:55:00,-6.4 +2017-01-01 16:00:00,-6.3 +2017-01-01 16:05:00,-6.3 +2017-01-01 16:10:00,-6.2 +2017-01-01 16:15:00,-6.1 +2017-01-01 16:20:00,-6.0 +2017-01-01 16:25:00,-5.9 +2017-01-01 16:30:00,-5.8 +2017-01-01 16:35:00,-5.7 +2017-01-01 16:40:00,-5.4 +2017-01-01 16:45:00,-5.3 +2017-01-01 16:50:00,-5.1 +2017-01-01 16:55:00,-5.0 +2017-01-01 17:00:00,-4.8 +2017-01-01 17:05:00,-4.6 +2017-01-01 17:10:00,-4.3 +2017-01-01 17:15:00,-4.1 +2017-01-01 17:20:00,-3.9 +2017-01-01 17:25:00,-3.6 +2017-01-01 17:30:00,-3.3 +2017-01-01 17:35:00,-3.1 +2017-01-01 17:40:00,-2.8 +2017-01-01 17:45:00,-2.7 +2017-01-01 17:50:00,-2.4 +2017-01-01 17:55:00,-2.0 +2017-01-01 18:00:00,-1.6 +2017-01-01 18:05:00,-1.3 +2017-01-01 18:10:00,-1.1 +2017-01-01 18:15:00,-0.9 +2017-01-01 18:20:00,-0.7 +2017-01-01 18:25:00,-0.4 +2017-01-01 18:30:00,-0.4 +2017-01-01 18:35:00,-0.2 +2017-01-01 18:40:00,0.0 +2017-01-01 18:45:00,0.3 +2017-01-01 18:50:00,0.6 +2017-01-01 18:55:00,0.6 +2017-01-01 19:00:00,1.0 +2017-01-01 19:05:00,1.0 +2017-01-01 19:10:00,1.1 +2017-01-01 19:15:00,1.3 +2017-01-01 19:20:00,1.0 +2017-01-01 19:25:00,1.2 +2017-01-01 19:30:00,1.3 +2017-01-01 19:35:00,0.9 +2017-01-01 19:40:00,1.1 +2017-01-01 19:45:00,1.3 +2017-01-01 19:50:00,1.5 +2017-01-01 19:55:00,1.3 +2017-01-01 20:00:00,1.6 +2017-01-01 20:05:00,1.6 +2017-01-01 20:10:00,1.8 +2017-01-01 20:15:00,1.4 +2017-01-01 20:20:00,1.4 +2017-01-01 20:25:00,1.6 +2017-01-01 20:30:00,1.6 +2017-01-01 20:35:00,1.5 +2017-01-01 20:40:00,1.5 +2017-01-01 20:45:00,1.8 +2017-01-01 20:50:00,1.6 +2017-01-01 20:55:00,1.7 +2017-01-01 21:00:00,1.5 +2017-01-01 21:05:00,1.8 +2017-01-01 21:10:00,1.6 +2017-01-01 21:15:00,1.7 +2017-01-01 21:20:00,1.9 +2017-01-01 21:25:00,1.6 +2017-01-01 21:30:00,1.8 +2017-01-01 21:35:00,1.8 +2017-01-01 21:40:00,1.5 +2017-01-01 21:45:00,1.6 +2017-01-01 21:50:00,1.6 +2017-01-01 21:55:00,1.4 +2017-01-01 22:00:00,1.1 +2017-01-01 22:05:00,1.5 +2017-01-01 22:10:00,1.5 +2017-01-01 22:15:00,1.6 +2017-01-01 22:20:00,1.5 +2017-01-01 22:25:00,1.1 +2017-01-01 22:30:00,1.0 +2017-01-01 22:35:00,1.0 +2017-01-01 22:40:00,1.1 +2017-01-01 22:45:00,1.1 +2017-01-01 22:50:00,0.7 +2017-01-01 22:55:00,0.6 +2017-01-01 23:00:00,0.5 +2017-01-01 23:05:00,0.3 +2017-01-01 23:10:00,0.5 +2017-01-01 23:15:00,0.2 +2017-01-01 23:20:00,0.2 +2017-01-01 23:25:00,0.0 +2017-01-01 23:30:00,-0.2 +2017-01-01 23:35:00,-0.3 +2017-01-01 23:40:00,-0.5 +2017-01-01 23:45:00,-0.7 +2017-01-01 23:50:00,-1.1 +2017-01-01 23:55:00,-1.3 +2017-01-02 00:00:00,-1.4 +2017-01-02 00:05:00,-1.7 +2017-01-02 00:10:00,-2.1 +2017-01-02 00:15:00,-2.4 +2017-01-02 00:20:00,-2.6 +2017-01-02 00:25:00,-2.9 +2017-01-02 00:30:00,-3.2 +2017-01-02 00:35:00,-3.5 +2017-01-02 00:40:00,-3.9 +2017-01-02 00:45:00,-4.1 +2017-01-02 00:50:00,-4.2 +2017-01-02 00:55:00,-4.4 +2017-01-02 01:00:00,-4.6 +2017-01-02 01:05:00,-4.7 +2017-01-02 01:10:00,-5.0 +2017-01-02 01:15:00,-5.1 +2017-01-02 01:20:00,-4.8 +2017-01-02 01:25:00,-4.7 +2017-01-02 01:30:00,-4.5 +2017-01-02 01:35:00,-4.0 +2017-01-02 01:40:00,-3.6 +2017-01-02 01:45:00,-3.1 +2017-01-02 01:50:00,-3.0 +2017-01-02 01:55:00,-3.0 +2017-01-02 02:00:00,-3.0 +2017-01-02 02:05:00,-2.9 +2017-01-02 02:10:00,-3.0 +2017-01-02 02:15:00,-2.9 +2017-01-02 02:20:00,-3.0 +2017-01-02 02:25:00,-3.0 +2017-01-02 02:30:00,-3.0 +2017-01-02 02:35:00,-3.0 +2017-01-02 02:40:00,-3.2 +2017-01-02 02:45:00,-3.5 +2017-01-02 02:50:00,-3.7 +2017-01-02 02:55:00,-3.5 +2017-01-02 03:00:00,-3.5 +2017-01-02 03:05:00,-3.4 +2017-01-02 03:10:00,-3.3 +2017-01-02 03:15:00,-3.2 +2017-01-02 03:20:00,-3.2 +2017-01-02 03:25:00,-3.3 +2017-01-02 03:30:00,-3.3 +2017-01-02 03:35:00,-3.3 +2017-01-02 03:40:00,-3.4 +2017-01-02 03:45:00,-3.4 +2017-01-02 03:50:00,-3.4 +2017-01-02 03:55:00,-3.5 +2017-01-02 04:00:00,-3.5 +2017-01-02 04:05:00,-3.5 +2017-01-02 04:10:00,-3.5 +2017-01-02 04:15:00,-3.6 +2017-01-02 04:20:00,-3.6 +2017-01-02 04:25:00,-3.8 +2017-01-02 04:30:00,-3.8 +2017-01-02 04:35:00,-3.8 +2017-01-02 04:40:00,-3.9 +2017-01-02 04:45:00,-3.9 +2017-01-02 04:50:00,-3.9 +2017-01-02 04:55:00,-3.9 +2017-01-02 05:00:00,-3.9 +2017-01-02 05:05:00,-3.9 +2017-01-02 05:10:00,-3.9 +2017-01-02 05:15:00,-4.0 +2017-01-02 05:20:00,-3.9 +2017-01-02 05:25:00,-4.0 +2017-01-02 05:30:00,-4.2 +2017-01-02 05:35:00,-4.2 +2017-01-02 05:40:00,-4.4 +2017-01-02 05:45:00,-4.4 +2017-01-02 05:50:00,-4.4 +2017-01-02 05:55:00,-4.4 +2017-01-02 06:00:00,-4.4 +2017-01-02 06:05:00,-5.3 +2017-01-02 06:10:00,-5.2 +2017-01-02 06:15:00,-5.3 +2017-01-02 06:20:00,-5.2 +2017-01-02 06:25:00,-5.0 +2017-01-02 06:30:00,-4.9 +2017-01-02 06:35:00,-4.8 +2017-01-02 06:40:00,-4.8 +2017-01-02 06:45:00,-4.7 +2017-01-02 06:50:00,-4.7 +2017-01-02 06:55:00,-4.8 +2017-01-02 07:00:00,-4.7 +2017-01-02 07:05:00,-4.7 +2017-01-02 07:10:00,-4.7 +2017-01-02 07:15:00,-5.0 +2017-01-02 07:20:00,-5.0 +2017-01-02 07:25:00,-4.9 +2017-01-02 07:30:00,-4.8 +2017-01-02 07:35:00,-4.8 +2017-01-02 07:40:00,-4.7 +2017-01-02 07:45:00,-4.6 +2017-01-02 07:50:00,-4.6 +2017-01-02 07:55:00,-4.7 +2017-01-02 08:00:00,-4.6 +2017-01-02 08:05:00,-4.6 +2017-01-02 08:10:00,-4.5 +2017-01-02 08:15:00,-4.5 +2017-01-02 08:20:00,-4.5 +2017-01-02 08:25:00,-4.5 +2017-01-02 08:30:00,-4.5 +2017-01-02 08:35:00,-4.5 +2017-01-02 08:40:00,-4.6 +2017-01-02 08:45:00,-4.6 +2017-01-02 08:50:00,-4.6 +2017-01-02 08:55:00,-4.6 +2017-01-02 09:00:00,-4.6 +2017-01-02 09:05:00,-4.6 +2017-01-02 09:10:00,-4.5 +2017-01-02 09:15:00,-4.5 +2017-01-02 09:20:00,-4.5 +2017-01-02 09:25:00,-4.5 +2017-01-02 09:30:00,-4.5 +2017-01-02 09:35:00,-4.5 +2017-01-02 09:40:00,-4.5 +2017-01-02 09:45:00,-4.5 +2017-01-02 09:50:00,-4.4 +2017-01-02 09:55:00,-4.4 +2017-01-02 10:00:00,-4.4 +2017-01-02 10:05:00,-4.5 +2017-01-02 10:10:00,-4.5 +2017-01-02 10:15:00,-4.4 +2017-01-02 10:20:00,-4.5 +2017-01-02 10:25:00,-4.5 +2017-01-02 10:30:00,-4.5 +2017-01-02 10:35:00,-4.5 +2017-01-02 10:40:00,-4.5 +2017-01-02 10:45:00,-4.5 +2017-01-02 10:50:00,-4.5 +2017-01-02 10:55:00,-4.4 +2017-01-02 11:00:00,-4.4 +2017-01-02 11:05:00,-4.5 +2017-01-02 11:10:00,-4.5 +2017-01-02 11:15:00,-4.5 +2017-01-02 11:20:00,-4.5 +2017-01-02 11:25:00,-4.5 +2017-01-02 11:30:00,-4.5 +2017-01-02 11:35:00,-4.5 +2017-01-02 11:40:00,-4.5 +2017-01-02 11:45:00,-4.6 +2017-01-02 11:50:00,-4.6 +2017-01-02 11:55:00,-4.6 +2017-01-02 12:00:00,-4.6 +2017-01-02 12:05:00,-4.7 +2017-01-02 12:10:00,-4.8 +2017-01-02 12:15:00,-4.8 +2017-01-02 12:20:00,-4.9 +2017-01-02 12:25:00,-5.0 +2017-01-02 12:30:00,-5.3 +2017-01-02 12:35:00,-5.5 +2017-01-02 12:40:00,-5.5 +2017-01-02 12:45:00,-5.6 +2017-01-02 12:50:00,-5.9 +2017-01-02 12:55:00,-6.1 +2017-01-02 13:00:00,-6.0 +2017-01-02 13:05:00,-6.1 +2017-01-02 13:10:00,-6.1 +2017-01-02 13:15:00,-6.0 +2017-01-02 13:20:00,-5.7 +2017-01-02 13:25:00,-5.5 +2017-01-02 13:30:00,-5.3 +2017-01-02 13:35:00,-5.2 +2017-01-02 13:40:00,-5.1 +2017-01-02 13:45:00,-5.0 +2017-01-02 13:50:00,-5.0 +2017-01-02 13:55:00,-5.0 +2017-01-02 14:00:00,-4.9 +2017-01-02 14:05:00,-4.9 +2017-01-02 14:10:00,-5.0 +2017-01-02 14:15:00,-4.9 +2017-01-02 14:20:00,-4.9 +2017-01-02 14:25:00,-4.9 +2017-01-02 14:30:00,-4.9 +2017-01-02 14:35:00,-4.9 +2017-01-02 14:40:00,-5.0 +2017-01-02 14:45:00,-4.9 +2017-01-02 14:50:00,-4.9 +2017-01-02 14:55:00,-5.0 +2017-01-02 15:00:00,-4.9 +2017-01-02 15:05:00,-4.9 +2017-01-02 15:10:00,-4.9 +2017-01-02 15:15:00,-4.9 +2017-01-02 15:20:00,-4.9 +2017-01-02 15:25:00,-4.9 +2017-01-02 15:30:00,-4.9 +2017-01-02 15:35:00,-4.9 +2017-01-02 15:40:00,-4.9 +2017-01-02 15:45:00,-4.9 +2017-01-02 15:50:00,-4.9 +2017-01-02 15:55:00,-4.9 +2017-01-02 16:00:00,-4.9 +2017-01-02 16:05:00,-4.9 +2017-01-02 16:10:00,-4.9 +2017-01-02 16:15:00,-4.9 +2017-01-02 16:20:00,-4.9 +2017-01-02 16:25:00,-4.8 +2017-01-02 16:30:00,-4.8 +2017-01-02 16:35:00,-4.7 +2017-01-02 16:40:00,-4.8 +2017-01-02 16:45:00,-4.8 +2017-01-02 16:50:00,-4.8 +2017-01-02 16:55:00,-4.9 +2017-01-02 17:00:00,-4.8 +2017-01-02 17:05:00,-4.8 +2017-01-02 17:10:00,-4.8 +2017-01-02 17:15:00,-4.8 +2017-01-02 17:20:00,-4.7 +2017-01-02 17:25:00,-4.7 +2017-01-02 17:30:00,-4.7 +2017-01-02 17:35:00,-4.7 +2017-01-02 17:40:00,-4.7 +2017-01-02 17:45:00,-4.6 +2017-01-02 17:50:00,-4.7 +2017-01-02 17:55:00,-4.7 +2017-01-02 18:00:00,-4.5 +2017-01-02 18:05:00,-4.6 +2017-01-02 18:10:00,-4.5 +2017-01-02 18:15:00,-4.4 +2017-01-02 18:20:00,-4.6 +2017-01-02 18:25:00,-4.6 +2017-01-02 18:30:00,-4.5 +2017-01-02 18:35:00,-4.4 +2017-01-02 18:40:00,-4.4 +2017-01-02 18:45:00,-4.4 +2017-01-02 18:50:00,-4.3 +2017-01-02 18:55:00,-4.2 +2017-01-02 19:00:00,-4.2 +2017-01-02 19:05:00,-4.2 +2017-01-02 19:10:00,-4.2 +2017-01-02 19:15:00,-4.1 +2017-01-02 19:20:00,-4.2 +2017-01-02 19:25:00,-4.2 +2017-01-02 19:30:00,-4.1 +2017-01-02 19:35:00,-3.9 +2017-01-02 19:40:00,-3.9 +2017-01-02 19:45:00,-4.1 +2017-01-02 19:50:00,-4.2 +2017-01-02 19:55:00,-4.0 +2017-01-02 20:00:00,-4.0 +2017-01-02 20:05:00,-4.1 +2017-01-02 20:10:00,-4.0 +2017-01-02 20:15:00,-4.1 +2017-01-02 20:20:00,-4.1 +2017-01-02 20:25:00,-4.0 +2017-01-02 20:30:00,-4.2 +2017-01-02 20:35:00,-4.1 +2017-01-02 20:40:00,-4.1 +2017-01-02 20:45:00,-4.2 +2017-01-02 20:50:00,-4.1 +2017-01-02 20:55:00,-4.3 +2017-01-02 21:00:00,-4.3 +2017-01-02 21:05:00,-4.4 +2017-01-02 21:10:00,-4.5 +2017-01-02 21:15:00,-4.4 +2017-01-02 21:20:00,-4.2 +2017-01-02 21:25:00,-4.5 +2017-01-02 21:30:00,-4.4 +2017-01-02 21:35:00,-4.2 +2017-01-02 21:40:00,-4.3 +2017-01-02 21:45:00,-4.3 +2017-01-02 21:50:00,-4.2 +2017-01-02 21:55:00,-4.2 +2017-01-02 22:00:00,-4.3 +2017-01-02 22:05:00,-4.2 +2017-01-02 22:10:00,-4.3 +2017-01-02 22:15:00,-4.4 +2017-01-02 22:20:00,-4.3 +2017-01-02 22:25:00,-4.3 +2017-01-02 22:30:00,-4.0 +2017-01-02 22:35:00,-4.3 +2017-01-02 22:40:00,-4.1 +2017-01-02 22:45:00,-4.2 +2017-01-02 22:50:00,-4.0 +2017-01-02 22:55:00,-3.9 +2017-01-02 23:00:00,-4.0 +2017-01-02 23:05:00,-4.1 +2017-01-02 23:10:00,-4.1 +2017-01-02 23:15:00,-4.0 +2017-01-02 23:20:00,-4.1 +2017-01-02 23:25:00,-4.2 +2017-01-02 23:30:00,-4.3 +2017-01-02 23:35:00,-4.2 +2017-01-02 23:40:00,-4.3 +2017-01-02 23:45:00,-4.3 +2017-01-02 23:50:00,-4.3 +2017-01-02 23:55:00,-4.4 +2017-01-03 00:00:00,-4.5 +2017-01-03 00:05:00,-4.5 +2017-01-03 00:10:00,-4.5 +2017-01-03 00:15:00,-4.5 +2017-01-03 00:20:00,-4.6 +2017-01-03 00:25:00,-4.6 +2017-01-03 00:30:00,-4.5 +2017-01-03 00:35:00,-4.6 +2017-01-03 00:40:00,-4.6 +2017-01-03 00:45:00,-4.5 +2017-01-03 00:50:00,-4.5 +2017-01-03 00:55:00,-4.6 +2017-01-03 01:00:00,-4.5 +2017-01-03 01:05:00,-4.6 +2017-01-03 01:10:00,-4.7 +2017-01-03 01:15:00,-4.7 +2017-01-03 01:20:00,-4.7 +2017-01-03 01:25:00,-4.9 +2017-01-03 01:30:00,-4.9 +2017-01-03 01:35:00,-4.9 +2017-01-03 01:40:00,-5.0 +2017-01-03 01:45:00,-5.0 +2017-01-03 01:50:00,-5.2 +2017-01-03 01:55:00,-5.2 +2017-01-03 02:00:00,-5.5 +2017-01-03 02:05:00,-5.3 +2017-01-03 02:10:00,-5.2 +2017-01-03 02:15:00,-5.2 +2017-01-03 02:20:00,-5.9 +2017-01-03 02:25:00,-6.4 +2017-01-03 02:30:00,-6.5 +2017-01-03 02:35:00,-6.0 +2017-01-03 02:40:00,-5.8 +2017-01-03 02:45:00,-5.5 +2017-01-03 02:50:00,-5.4 +2017-01-03 02:55:00,-5.5 +2017-01-03 03:00:00,-6.3 +2017-01-03 03:05:00,-6.3 +2017-01-03 03:10:00,-6.8 +2017-01-03 03:15:00,-6.3 +2017-01-03 03:20:00,-5.8 +2017-01-03 03:25:00,-6.8 +2017-01-03 03:30:00,-6.2 +2017-01-03 03:35:00,-5.7 +2017-01-03 03:40:00,-5.4 +2017-01-03 03:45:00,-5.3 +2017-01-03 03:50:00,-5.3 +2017-01-03 03:55:00,-5.2 +2017-01-03 04:00:00,-5.3 +2017-01-03 04:05:00,-5.3 +2017-01-03 04:10:00,-5.2 +2017-01-03 04:15:00,-5.2 +2017-01-03 04:20:00,-5.6 +2017-01-03 04:25:00,-6.1 +2017-01-03 04:30:00,-6.1 +2017-01-03 04:35:00,-6.1 +2017-01-03 04:40:00,-6.0 +2017-01-03 04:45:00,-5.8 +2017-01-03 04:50:00,-5.6 +2017-01-03 04:55:00,-5.7 +2017-01-03 05:00:00,-5.6 +2017-01-03 05:05:00,-6.1 +2017-01-03 05:10:00,-5.8 +2017-01-03 05:15:00,-5.9 +2017-01-03 05:20:00,-5.8 +2017-01-03 05:25:00,-6.3 +2017-01-03 05:30:00,-6.4 +2017-01-03 05:35:00,-6.5 +2017-01-03 05:40:00,-6.5 +2017-01-03 05:45:00,-5.9 +2017-01-03 05:50:00,-5.7 +2017-01-03 05:55:00,-5.8 +2017-01-03 06:00:00,-6.0 +2017-01-03 06:05:00,-6.3 +2017-01-03 06:10:00,-6.7 +2017-01-03 06:15:00,-6.6 +2017-01-03 06:20:00,-6.5 +2017-01-03 06:25:00,-6.4 +2017-01-03 06:30:00,-6.1 +2017-01-03 06:35:00,-6.3 +2017-01-03 06:40:00,-6.2 +2017-01-03 06:45:00,-6.1 +2017-01-03 06:50:00,-6.1 +2017-01-03 06:55:00,-6.0 +2017-01-03 07:00:00,-6.0 +2017-01-03 07:05:00,-6.2 +2017-01-03 07:10:00,-6.4 +2017-01-03 07:15:00,-6.2 +2017-01-03 07:20:00,-6.1 +2017-01-03 07:25:00,-5.9 +2017-01-03 07:30:00,-5.9 +2017-01-03 07:35:00,-5.9 +2017-01-03 07:40:00,-6.2 +2017-01-03 07:45:00,-6.4 +2017-01-03 07:50:00,-6.2 +2017-01-03 07:55:00,-6.0 +2017-01-03 08:00:00,-5.9 +2017-01-03 08:05:00,-5.9 +2017-01-03 08:10:00,-5.8 +2017-01-03 08:15:00,-5.8 +2017-01-03 08:20:00,-5.8 +2017-01-03 08:25:00,-5.8 +2017-01-03 08:30:00,-6.0 +2017-01-03 08:35:00,-5.9 +2017-01-03 08:40:00,-5.9 +2017-01-03 08:45:00,-5.8 +2017-01-03 08:50:00,-5.8 +2017-01-03 08:55:00,-5.7 +2017-01-03 09:00:00,-5.8 +2017-01-03 09:05:00,-5.8 +2017-01-03 09:10:00,-6.0 +2017-01-03 09:15:00,-6.1 +2017-01-03 09:20:00,-6.0 +2017-01-03 09:25:00,-5.9 +2017-01-03 09:30:00,-6.0 +2017-01-03 09:35:00,-6.0 +2017-01-03 09:40:00,-6.1 +2017-01-03 09:45:00,-6.2 +2017-01-03 09:50:00,-6.1 +2017-01-03 09:55:00,-6.3 +2017-01-03 10:00:00,-6.3 +2017-01-03 10:05:00,-6.1 +2017-01-03 10:10:00,-6.0 +2017-01-03 10:15:00,-5.9 +2017-01-03 10:20:00,-5.8 +2017-01-03 10:25:00,-5.7 +2017-01-03 10:30:00,-5.7 +2017-01-03 10:35:00,-5.8 +2017-01-03 10:40:00,-5.6 +2017-01-03 10:45:00,-5.6 +2017-01-03 10:50:00,-5.6 +2017-01-03 10:55:00,-5.6 +2017-01-03 11:00:00,-5.5 +2017-01-03 11:05:00,-5.6 +2017-01-03 11:10:00,-5.7 +2017-01-03 11:15:00,-5.7 +2017-01-03 11:20:00,-5.8 +2017-01-03 11:25:00,-5.7 +2017-01-03 11:30:00,-5.6 +2017-01-03 11:35:00,-5.5 +2017-01-03 11:40:00,-5.3 +2017-01-03 11:45:00,-5.2 +2017-01-03 11:50:00,-5.1 +2017-01-03 11:55:00,-5.0 +2017-01-03 12:00:00,-5.1 +2017-01-03 12:05:00,-5.0 +2017-01-03 12:10:00,-5.0 +2017-01-03 12:15:00,-5.0 +2017-01-03 12:20:00,-4.8 +2017-01-03 12:25:00,-4.8 +2017-01-03 12:30:00,-4.7 +2017-01-03 12:35:00,-4.6 +2017-01-03 12:40:00,-4.5 +2017-01-03 12:45:00,-4.4 +2017-01-03 12:50:00,-4.5 +2017-01-03 12:55:00,-4.6 +2017-01-03 13:00:00,-4.6 +2017-01-03 13:05:00,-4.6 +2017-01-03 13:10:00,-4.5 +2017-01-03 13:15:00,-4.5 +2017-01-03 13:20:00,-4.5 +2017-01-03 13:25:00,-4.3 +2017-01-03 13:30:00,-4.3 +2017-01-03 13:35:00,-4.3 +2017-01-03 13:40:00,-4.2 +2017-01-03 13:45:00,-4.2 +2017-01-03 13:50:00,-4.2 +2017-01-03 13:55:00,-4.2 +2017-01-03 14:00:00,-4.3 +2017-01-03 14:05:00,-4.3 +2017-01-03 14:10:00,-4.3 +2017-01-03 14:15:00,-4.3 +2017-01-03 14:20:00,-4.3 +2017-01-03 14:25:00,-4.3 +2017-01-03 14:30:00,-4.4 +2017-01-03 14:35:00,-4.4 +2017-01-03 14:40:00,-4.4 +2017-01-03 14:45:00,-4.5 +2017-01-03 14:50:00,-4.6 +2017-01-03 14:55:00,-4.5 +2017-01-03 15:00:00,-4.5 +2017-01-03 15:05:00,-4.5 +2017-01-03 15:10:00,-4.5 +2017-01-03 15:15:00,-4.5 +2017-01-03 15:20:00,-4.5 +2017-01-03 15:25:00,-4.5 +2017-01-03 15:30:00,-4.5 +2017-01-03 15:35:00,-4.5 +2017-01-03 15:40:00,-4.5 +2017-01-03 15:45:00,-4.6 +2017-01-03 15:50:00,-4.6 +2017-01-03 15:55:00,-4.5 +2017-01-03 16:00:00,-4.6 +2017-01-03 16:05:00,-4.5 +2017-01-03 16:10:00,-4.3 +2017-01-03 16:15:00,-4.2 +2017-01-03 16:20:00,-4.3 +2017-01-03 16:25:00,-4.2 +2017-01-03 16:30:00,-4.1 +2017-01-03 16:35:00,-4.0 +2017-01-03 16:40:00,-3.9 +2017-01-03 16:45:00,-3.8 +2017-01-03 16:50:00,-3.7 +2017-01-03 16:55:00,-3.7 +2017-01-03 17:00:00,-3.4 +2017-01-03 17:05:00,-3.3 +2017-01-03 17:10:00,-3.5 +2017-01-03 17:15:00,-3.4 +2017-01-03 17:20:00,-3.3 +2017-01-03 17:25:00,-3.2 +2017-01-03 17:30:00,-3.1 +2017-01-03 17:35:00,-3.0 +2017-01-03 17:40:00,-2.7 +2017-01-03 17:45:00,-2.6 +2017-01-03 17:50:00,-2.2 +2017-01-03 17:55:00,-2.4 +2017-01-03 18:00:00,-2.4 +2017-01-03 18:05:00,-2.7 +2017-01-03 18:10:00,-2.7 +2017-01-03 18:15:00,-2.6 +2017-01-03 18:20:00,-2.7 +2017-01-03 18:25:00,-2.5 +2017-01-03 18:30:00,-2.5 +2017-01-03 18:35:00,-2.6 +2017-01-03 18:40:00,-2.6 +2017-01-03 18:45:00,-2.6 +2017-01-03 18:50:00,-2.9 +2017-01-03 18:55:00,-2.7 +2017-01-03 19:00:00,-2.5 +2017-01-03 19:05:00,-2.3 +2017-01-03 19:10:00,-2.3 +2017-01-03 19:15:00,-2.3 +2017-01-03 19:20:00,-2.3 +2017-01-03 19:25:00,-2.2 +2017-01-03 19:30:00,-2.1 +2017-01-03 19:35:00,-2.3 +2017-01-03 19:40:00,-2.2 +2017-01-03 19:45:00,-2.0 +2017-01-03 19:50:00,-1.9 +2017-01-03 19:55:00,-1.8 +2017-01-03 20:00:00,-1.8 +2017-01-03 20:05:00,-1.9 +2017-01-03 20:10:00,-1.8 +2017-01-03 20:15:00,-1.6 +2017-01-03 20:20:00,-1.5 +2017-01-03 20:25:00,-1.1 +2017-01-03 20:30:00,-1.6 +2017-01-03 20:35:00,-2.2 +2017-01-03 20:40:00,-2.2 +2017-01-03 20:45:00,-2.3 +2017-01-03 20:50:00,-2.4 +2017-01-03 20:55:00,-2.4 +2017-01-03 21:00:00,-2.4 +2017-01-03 21:05:00,-2.3 +2017-01-03 21:10:00,-2.4 +2017-01-03 21:15:00,-2.5 +2017-01-03 21:20:00,-2.3 +2017-01-03 21:25:00,-2.1 +2017-01-03 21:30:00,-2.2 +2017-01-03 21:35:00,-2.2 +2017-01-03 21:40:00,-2.3 +2017-01-03 21:45:00,-2.3 +2017-01-03 21:50:00,-2.3 +2017-01-03 21:55:00,-2.3 +2017-01-03 22:00:00,-2.4 +2017-01-03 22:05:00,-2.3 +2017-01-03 22:10:00,-2.3 +2017-01-03 22:15:00,-2.4 +2017-01-03 22:20:00,-2.4 +2017-01-03 22:25:00,-2.5 +2017-01-03 22:30:00,-2.5 +2017-01-03 22:35:00,-2.7 +2017-01-03 22:40:00,-2.7 +2017-01-03 22:45:00,-2.8 +2017-01-03 22:50:00,-2.8 +2017-01-03 22:55:00,-2.8 +2017-01-03 23:00:00,-2.8 +2017-01-03 23:05:00,-2.8 +2017-01-03 23:10:00,-2.8 +2017-01-03 23:15:00,-2.7 +2017-01-03 23:20:00,-2.7 +2017-01-03 23:25:00,-2.6 +2017-01-03 23:30:00,-2.6 +2017-01-03 23:35:00,-2.5 +2017-01-03 23:40:00,-2.5 +2017-01-03 23:45:00,-2.4 +2017-01-03 23:50:00,-2.4 +2017-01-03 23:55:00,-2.4 diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/data3.csv b/.venv/lib/python3.12/site-packages/prophet/tests/data3.csv new file mode 100644 index 00000000..eac84a1e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/data3.csv @@ -0,0 +1,71 @@ +ds,y +2023-03-02,623031970.0 +2023-03-06,623032040.0 +2023-03-07,623032054.0 +2023-03-08,623032091.0 +2023-03-09,623032123.0 +2023-03-10,623032152.0 +2023-03-11,623032177.0 +2023-03-12,623032184.0 +2023-03-13,623032193.0 +2023-03-16,623032296.0 +2023-03-17,623032316.0 +2023-03-18,623032328.0 +2023-03-19,623032339.0 +2023-03-20,623032352.0 +2023-03-21,623032385.0 +2023-03-22,623032410.0 +2023-03-23,623032427.0 +2023-03-25,623032479.0 +2023-03-26,623032496.0 +2023-03-27,623032506.0 +2023-03-28,623032533.0 +2023-03-29,623032598.0 +2023-03-30,623032643.0 +2023-03-31,623032681.0 +2023-04-01,623032727.0 +2023-04-02,623032756.0 +2023-04-03,623032767.0 +2023-04-04,623032799.0 +2023-04-05,623032843.0 +2023-04-06,623032890.0 +2023-04-07,623032934.0 +2023-04-08,623032954.0 +2023-04-09,623032959.0 +2023-04-10,623032964.0 +2023-04-11,623032997.0 +2023-04-12,623033041.0 +2023-04-13,623033062.0 +2023-04-14,623033095.0 +2023-04-15,623033122.0 +2023-04-16,623033163.0 +2023-04-17,623033190.0 +2023-04-18,623033227.0 +2023-04-19,623033258.0 +2023-04-20,623033294.0 +2023-04-21,623033329.0 +2023-04-22,623033361.0 +2023-04-23,623033385.0 +2023-04-24,623033397.0 +2023-04-25,623033419.0 +2023-04-26,623033440.0 +2023-04-27,623033482.0 +2023-04-28,623033535.0 +2023-04-29,623033575.0 +2023-04-30,623033600.0 +2023-05-01,623033610.0 +2023-05-02,623033632.0 +2023-05-03,623033666.0 +2023-05-04,623033704.0 +2023-05-05,623033714.0 +2023-05-06,623033752.0 +2023-05-07,623033760.0 +2023-05-08,623033769.0 +2023-05-09,623033784.0 +2023-05-10,623033823.0 +2023-05-11,623033853.0 +2023-05-12,623034010.0 +2023-05-13,623034041.0 +2023-05-14,623034060.0 +2023-05-15,623034068.0 +2023-05-16,623034084.0 diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v0.6.1.dev0.json b/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v0.6.1.dev0.json new file mode 100644 index 00000000..21dbd873 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v0.6.1.dev0.json @@ -0,0 +1 @@ +"{\"growth\": \"linear\", \"n_changepoints\": 15, \"specified_changepoints\": false, \"changepoint_range\": 0.8, \"yearly_seasonality\": \"auto\", \"weekly_seasonality\": \"auto\", \"daily_seasonality\": \"auto\", \"seasonality_mode\": \"additive\", \"seasonality_prior_scale\": 10.0, \"changepoint_prior_scale\": 0.05, \"holidays_prior_scale\": 10.0, \"mcmc_samples\": 0, \"interval_width\": 0.8, \"uncertainty_samples\": 1000, \"y_scale\": 19.0, \"logistic_floor\": false, \"country_holidays\": null, \"component_modes\": {\"additive\": [\"weekly\", \"additive_terms\", \"extra_regressors_additive\", \"holidays\"], \"multiplicative\": [\"multiplicative_terms\", \"extra_regressors_multiplicative\"]}, \"fit_kwargs\": {}, \"changepoints\": \"{\\\"name\\\":\\\"ds\\\",\\\"index\\\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],\\\"data\\\":[\\\"2020-01-02T00:00:00.000Z\\\",\\\"2020-01-03T00:00:00.000Z\\\",\\\"2020-01-04T00:00:00.000Z\\\",\\\"2020-01-05T00:00:00.000Z\\\",\\\"2020-01-06T00:00:00.000Z\\\",\\\"2020-01-07T00:00:00.000Z\\\",\\\"2020-01-08T00:00:00.000Z\\\",\\\"2020-01-09T00:00:00.000Z\\\",\\\"2020-01-10T00:00:00.000Z\\\",\\\"2020-01-11T00:00:00.000Z\\\",\\\"2020-01-12T00:00:00.000Z\\\",\\\"2020-01-13T00:00:00.000Z\\\",\\\"2020-01-14T00:00:00.000Z\\\",\\\"2020-01-15T00:00:00.000Z\\\",\\\"2020-01-16T00:00:00.000Z\\\"]}\", \"history_dates\": \"{\\\"name\\\":\\\"ds\\\",\\\"index\\\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],\\\"data\\\":[\\\"2020-01-01T00:00:00.000Z\\\",\\\"2020-01-02T00:00:00.000Z\\\",\\\"2020-01-03T00:00:00.000Z\\\",\\\"2020-01-04T00:00:00.000Z\\\",\\\"2020-01-05T00:00:00.000Z\\\",\\\"2020-01-06T00:00:00.000Z\\\",\\\"2020-01-07T00:00:00.000Z\\\",\\\"2020-01-08T00:00:00.000Z\\\",\\\"2020-01-09T00:00:00.000Z\\\",\\\"2020-01-10T00:00:00.000Z\\\",\\\"2020-01-11T00:00:00.000Z\\\",\\\"2020-01-12T00:00:00.000Z\\\",\\\"2020-01-13T00:00:00.000Z\\\",\\\"2020-01-14T00:00:00.000Z\\\",\\\"2020-01-15T00:00:00.000Z\\\",\\\"2020-01-16T00:00:00.000Z\\\",\\\"2020-01-17T00:00:00.000Z\\\",\\\"2020-01-18T00:00:00.000Z\\\",\\\"2020-01-19T00:00:00.000Z\\\",\\\"2020-01-20T00:00:00.000Z\\\"]}\", \"train_holiday_names\": null, \"start\": 1577836800.0, \"t_scale\": 1641600.0, \"holidays\": null, \"history\": \"{\\\"schema\\\":{\\\"fields\\\":[{\\\"name\\\":\\\"ds\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"y\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"floor\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"t\\\",\\\"type\\\":\\\"number\\\"},{\\\"name\\\":\\\"y_scaled\\\",\\\"type\\\":\\\"number\\\"}],\\\"pandas_version\\\":\\\"0.20.0\\\"},\\\"data\\\":[{\\\"ds\\\":\\\"2020-01-01T00:00:00.000Z\\\",\\\"y\\\":0,\\\"floor\\\":0,\\\"t\\\":0.0,\\\"y_scaled\\\":0.0},{\\\"ds\\\":\\\"2020-01-02T00:00:00.000Z\\\",\\\"y\\\":1,\\\"floor\\\":0,\\\"t\\\":0.0526315789,\\\"y_scaled\\\":0.0526315789},{\\\"ds\\\":\\\"2020-01-03T00:00:00.000Z\\\",\\\"y\\\":2,\\\"floor\\\":0,\\\"t\\\":0.1052631579,\\\"y_scaled\\\":0.1052631579},{\\\"ds\\\":\\\"2020-01-04T00:00:00.000Z\\\",\\\"y\\\":3,\\\"floor\\\":0,\\\"t\\\":0.1578947368,\\\"y_scaled\\\":0.1578947368},{\\\"ds\\\":\\\"2020-01-05T00:00:00.000Z\\\",\\\"y\\\":4,\\\"floor\\\":0,\\\"t\\\":0.2105263158,\\\"y_scaled\\\":0.2105263158},{\\\"ds\\\":\\\"2020-01-06T00:00:00.000Z\\\",\\\"y\\\":5,\\\"floor\\\":0,\\\"t\\\":0.2631578947,\\\"y_scaled\\\":0.2631578947},{\\\"ds\\\":\\\"2020-01-07T00:00:00.000Z\\\",\\\"y\\\":6,\\\"floor\\\":0,\\\"t\\\":0.3157894737,\\\"y_scaled\\\":0.3157894737},{\\\"ds\\\":\\\"2020-01-08T00:00:00.000Z\\\",\\\"y\\\":7,\\\"floor\\\":0,\\\"t\\\":0.3684210526,\\\"y_scaled\\\":0.3684210526},{\\\"ds\\\":\\\"2020-01-09T00:00:00.000Z\\\",\\\"y\\\":8,\\\"floor\\\":0,\\\"t\\\":0.4210526316,\\\"y_scaled\\\":0.4210526316},{\\\"ds\\\":\\\"2020-01-10T00:00:00.000Z\\\",\\\"y\\\":9,\\\"floor\\\":0,\\\"t\\\":0.4736842105,\\\"y_scaled\\\":0.4736842105},{\\\"ds\\\":\\\"2020-01-11T00:00:00.000Z\\\",\\\"y\\\":10,\\\"floor\\\":0,\\\"t\\\":0.5263157895,\\\"y_scaled\\\":0.5263157895},{\\\"ds\\\":\\\"2020-01-12T00:00:00.000Z\\\",\\\"y\\\":11,\\\"floor\\\":0,\\\"t\\\":0.5789473684,\\\"y_scaled\\\":0.5789473684},{\\\"ds\\\":\\\"2020-01-13T00:00:00.000Z\\\",\\\"y\\\":12,\\\"floor\\\":0,\\\"t\\\":0.6315789474,\\\"y_scaled\\\":0.6315789474},{\\\"ds\\\":\\\"2020-01-14T00:00:00.000Z\\\",\\\"y\\\":13,\\\"floor\\\":0,\\\"t\\\":0.6842105263,\\\"y_scaled\\\":0.6842105263},{\\\"ds\\\":\\\"2020-01-15T00:00:00.000Z\\\",\\\"y\\\":14,\\\"floor\\\":0,\\\"t\\\":0.7368421053,\\\"y_scaled\\\":0.7368421053},{\\\"ds\\\":\\\"2020-01-16T00:00:00.000Z\\\",\\\"y\\\":15,\\\"floor\\\":0,\\\"t\\\":0.7894736842,\\\"y_scaled\\\":0.7894736842},{\\\"ds\\\":\\\"2020-01-17T00:00:00.000Z\\\",\\\"y\\\":16,\\\"floor\\\":0,\\\"t\\\":0.8421052632,\\\"y_scaled\\\":0.8421052632},{\\\"ds\\\":\\\"2020-01-18T00:00:00.000Z\\\",\\\"y\\\":17,\\\"floor\\\":0,\\\"t\\\":0.8947368421,\\\"y_scaled\\\":0.8947368421},{\\\"ds\\\":\\\"2020-01-19T00:00:00.000Z\\\",\\\"y\\\":18,\\\"floor\\\":0,\\\"t\\\":0.9473684211,\\\"y_scaled\\\":0.9473684211},{\\\"ds\\\":\\\"2020-01-20T00:00:00.000Z\\\",\\\"y\\\":19,\\\"floor\\\":0,\\\"t\\\":1.0,\\\"y_scaled\\\":1.0}]}\", \"train_component_cols\": \"{\\\"schema\\\":{\\\"fields\\\":[{\\\"name\\\":\\\"additive_terms\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"weekly\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"multiplicative_terms\\\",\\\"type\\\":\\\"integer\\\"}],\\\"pandas_version\\\":\\\"0.20.0\\\"},\\\"data\\\":[{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0}]}\", \"changepoints_t\": [0.05263157894736842, 0.10526315789473684, 0.15789473684210525, 0.21052631578947367, 0.2631578947368421, 0.3157894736842105, 0.3684210526315789, 0.42105263157894735, 0.47368421052631576, 0.5263157894736842, 0.5789473684210527, 0.631578947368421, 0.6842105263157895, 0.7368421052631579, 0.7894736842105263], \"seasonalities\": [[\"weekly\"], {\"weekly\": {\"period\": 7, \"fourier_order\": 3, \"prior_scale\": 10.0, \"mode\": \"additive\", \"condition_name\": null}}], \"extra_regressors\": [[], {}], \"params\": {\"k\": [[1.0602577093594823]], \"m\": [[-0.004702319079611993]], \"delta\": [[-0.0340439667236795, -8.209452442966747e-14, -2.3754012547042104e-13, 3.543693429450493e-13, -0.1293439581042728, 0.04114775103469311, 0.12224017379322774, -0.03404396672382336, 2.980940404592971e-14, -1.6422578408979347e-13, 3.641514165715795e-13, -0.12934395810441496, 0.0411477510348335, 0.12224017379301462, -0.03404396672364116]], \"sigma_obs\": [[9.77385680687189e-13]], \"beta\": [[-0.0015889307327346812, 0.0029864727119731007, -0.0012450988159614497, -0.0011006619700103823, 0.00041622470940299385, -0.00035495004969666316]]}, \"__fbprophet_version\": \"0.6.1.dev0\"}" diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v0.7.1.json b/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v0.7.1.json new file mode 100644 index 00000000..5d5b880b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v0.7.1.json @@ -0,0 +1 @@ +"{\"growth\": \"linear\", \"n_changepoints\": 15, \"specified_changepoints\": false, \"changepoint_range\": 0.8, \"yearly_seasonality\": \"auto\", \"weekly_seasonality\": \"auto\", \"daily_seasonality\": \"auto\", \"seasonality_mode\": \"additive\", \"seasonality_prior_scale\": 10.0, \"changepoint_prior_scale\": 0.05, \"holidays_prior_scale\": 10.0, \"mcmc_samples\": 0, \"interval_width\": 0.8, \"uncertainty_samples\": 1000, \"y_scale\": 19.0, \"logistic_floor\": false, \"country_holidays\": null, \"component_modes\": {\"additive\": [\"weekly\", \"additive_terms\", \"extra_regressors_additive\", \"holidays\"], \"multiplicative\": [\"multiplicative_terms\", \"extra_regressors_multiplicative\"]}, \"fit_kwargs\": {}, \"changepoints\": \"{\\\"name\\\":\\\"ds\\\",\\\"index\\\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],\\\"data\\\":[\\\"2020-01-02T00:00:00.000Z\\\",\\\"2020-01-03T00:00:00.000Z\\\",\\\"2020-01-04T00:00:00.000Z\\\",\\\"2020-01-05T00:00:00.000Z\\\",\\\"2020-01-06T00:00:00.000Z\\\",\\\"2020-01-07T00:00:00.000Z\\\",\\\"2020-01-08T00:00:00.000Z\\\",\\\"2020-01-09T00:00:00.000Z\\\",\\\"2020-01-10T00:00:00.000Z\\\",\\\"2020-01-11T00:00:00.000Z\\\",\\\"2020-01-12T00:00:00.000Z\\\",\\\"2020-01-13T00:00:00.000Z\\\",\\\"2020-01-14T00:00:00.000Z\\\",\\\"2020-01-15T00:00:00.000Z\\\",\\\"2020-01-16T00:00:00.000Z\\\"]}\", \"history_dates\": \"{\\\"name\\\":\\\"ds\\\",\\\"index\\\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],\\\"data\\\":[\\\"2020-01-01T00:00:00.000Z\\\",\\\"2020-01-02T00:00:00.000Z\\\",\\\"2020-01-03T00:00:00.000Z\\\",\\\"2020-01-04T00:00:00.000Z\\\",\\\"2020-01-05T00:00:00.000Z\\\",\\\"2020-01-06T00:00:00.000Z\\\",\\\"2020-01-07T00:00:00.000Z\\\",\\\"2020-01-08T00:00:00.000Z\\\",\\\"2020-01-09T00:00:00.000Z\\\",\\\"2020-01-10T00:00:00.000Z\\\",\\\"2020-01-11T00:00:00.000Z\\\",\\\"2020-01-12T00:00:00.000Z\\\",\\\"2020-01-13T00:00:00.000Z\\\",\\\"2020-01-14T00:00:00.000Z\\\",\\\"2020-01-15T00:00:00.000Z\\\",\\\"2020-01-16T00:00:00.000Z\\\",\\\"2020-01-17T00:00:00.000Z\\\",\\\"2020-01-18T00:00:00.000Z\\\",\\\"2020-01-19T00:00:00.000Z\\\",\\\"2020-01-20T00:00:00.000Z\\\"]}\", \"train_holiday_names\": null, \"start\": 1577836800.0, \"t_scale\": 1641600.0, \"holidays\": null, \"history\": \"{\\\"schema\\\":{\\\"fields\\\":[{\\\"name\\\":\\\"ds\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"y\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"floor\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"t\\\",\\\"type\\\":\\\"number\\\"},{\\\"name\\\":\\\"y_scaled\\\",\\\"type\\\":\\\"number\\\"}],\\\"pandas_version\\\":\\\"0.20.0\\\"},\\\"data\\\":[{\\\"ds\\\":\\\"2020-01-01T00:00:00.000Z\\\",\\\"y\\\":0,\\\"floor\\\":0,\\\"t\\\":0.0,\\\"y_scaled\\\":0.0},{\\\"ds\\\":\\\"2020-01-02T00:00:00.000Z\\\",\\\"y\\\":1,\\\"floor\\\":0,\\\"t\\\":0.0526315789,\\\"y_scaled\\\":0.0526315789},{\\\"ds\\\":\\\"2020-01-03T00:00:00.000Z\\\",\\\"y\\\":2,\\\"floor\\\":0,\\\"t\\\":0.1052631579,\\\"y_scaled\\\":0.1052631579},{\\\"ds\\\":\\\"2020-01-04T00:00:00.000Z\\\",\\\"y\\\":3,\\\"floor\\\":0,\\\"t\\\":0.1578947368,\\\"y_scaled\\\":0.1578947368},{\\\"ds\\\":\\\"2020-01-05T00:00:00.000Z\\\",\\\"y\\\":4,\\\"floor\\\":0,\\\"t\\\":0.2105263158,\\\"y_scaled\\\":0.2105263158},{\\\"ds\\\":\\\"2020-01-06T00:00:00.000Z\\\",\\\"y\\\":5,\\\"floor\\\":0,\\\"t\\\":0.2631578947,\\\"y_scaled\\\":0.2631578947},{\\\"ds\\\":\\\"2020-01-07T00:00:00.000Z\\\",\\\"y\\\":6,\\\"floor\\\":0,\\\"t\\\":0.3157894737,\\\"y_scaled\\\":0.3157894737},{\\\"ds\\\":\\\"2020-01-08T00:00:00.000Z\\\",\\\"y\\\":7,\\\"floor\\\":0,\\\"t\\\":0.3684210526,\\\"y_scaled\\\":0.3684210526},{\\\"ds\\\":\\\"2020-01-09T00:00:00.000Z\\\",\\\"y\\\":8,\\\"floor\\\":0,\\\"t\\\":0.4210526316,\\\"y_scaled\\\":0.4210526316},{\\\"ds\\\":\\\"2020-01-10T00:00:00.000Z\\\",\\\"y\\\":9,\\\"floor\\\":0,\\\"t\\\":0.4736842105,\\\"y_scaled\\\":0.4736842105},{\\\"ds\\\":\\\"2020-01-11T00:00:00.000Z\\\",\\\"y\\\":10,\\\"floor\\\":0,\\\"t\\\":0.5263157895,\\\"y_scaled\\\":0.5263157895},{\\\"ds\\\":\\\"2020-01-12T00:00:00.000Z\\\",\\\"y\\\":11,\\\"floor\\\":0,\\\"t\\\":0.5789473684,\\\"y_scaled\\\":0.5789473684},{\\\"ds\\\":\\\"2020-01-13T00:00:00.000Z\\\",\\\"y\\\":12,\\\"floor\\\":0,\\\"t\\\":0.6315789474,\\\"y_scaled\\\":0.6315789474},{\\\"ds\\\":\\\"2020-01-14T00:00:00.000Z\\\",\\\"y\\\":13,\\\"floor\\\":0,\\\"t\\\":0.6842105263,\\\"y_scaled\\\":0.6842105263},{\\\"ds\\\":\\\"2020-01-15T00:00:00.000Z\\\",\\\"y\\\":14,\\\"floor\\\":0,\\\"t\\\":0.7368421053,\\\"y_scaled\\\":0.7368421053},{\\\"ds\\\":\\\"2020-01-16T00:00:00.000Z\\\",\\\"y\\\":15,\\\"floor\\\":0,\\\"t\\\":0.7894736842,\\\"y_scaled\\\":0.7894736842},{\\\"ds\\\":\\\"2020-01-17T00:00:00.000Z\\\",\\\"y\\\":16,\\\"floor\\\":0,\\\"t\\\":0.8421052632,\\\"y_scaled\\\":0.8421052632},{\\\"ds\\\":\\\"2020-01-18T00:00:00.000Z\\\",\\\"y\\\":17,\\\"floor\\\":0,\\\"t\\\":0.8947368421,\\\"y_scaled\\\":0.8947368421},{\\\"ds\\\":\\\"2020-01-19T00:00:00.000Z\\\",\\\"y\\\":18,\\\"floor\\\":0,\\\"t\\\":0.9473684211,\\\"y_scaled\\\":0.9473684211},{\\\"ds\\\":\\\"2020-01-20T00:00:00.000Z\\\",\\\"y\\\":19,\\\"floor\\\":0,\\\"t\\\":1.0,\\\"y_scaled\\\":1.0}]}\", \"train_component_cols\": \"{\\\"schema\\\":{\\\"fields\\\":[{\\\"name\\\":\\\"additive_terms\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"weekly\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"multiplicative_terms\\\",\\\"type\\\":\\\"integer\\\"}],\\\"pandas_version\\\":\\\"0.20.0\\\"},\\\"data\\\":[{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0}]}\", \"changepoints_t\": [0.05263157894736842, 0.10526315789473684, 0.15789473684210525, 0.21052631578947367, 0.2631578947368421, 0.3157894736842105, 0.3684210526315789, 0.42105263157894735, 0.47368421052631576, 0.5263157894736842, 0.5789473684210527, 0.631578947368421, 0.6842105263157895, 0.7368421052631579, 0.7894736842105263], \"seasonalities\": [[\"weekly\"], {\"weekly\": {\"period\": 7, \"fourier_order\": 3, \"prior_scale\": 10.0, \"mode\": \"additive\", \"condition_name\": null}}], \"extra_regressors\": [[], {}], \"params\": {\"k\": [[1.02697210905145]], \"m\": [[-0.0030769618763556213]], \"delta\": [[-0.0067713344295760635, -1.8489743725556455e-13, -3.3570135589463447e-14, 2.0851492724135376e-13, -0.05560834408005808, -0.03696006862215325, 0.09933974713183089, -0.006771334429730693, 7.87431718983493e-14, -1.234385828898371e-13, 9.554119248353166e-14, -0.05560834408004029, -0.03696006862202002, 0.09933974713167956, -0.006771334429674014]], \"sigma_obs\": [[3.114271923280071e-13]], \"beta\": [[-0.00034958928816783473, 0.0022663968006279714, -0.0009616626944811777, -0.00018603166834996976, -7.034133451705964e-05, -0.00042298794284303893]], \"trend\": [[-0.0030769618763556213, 0.05097420175793122, 0.10466897936960881, 0.15836375698127664, 0.21205853459294272, 0.2657533122046198, 0.3165213348647148, 0.3653440907552229, 0.4193952543895115, 0.4730900320011826, 0.526784809612858, 0.580479587224527, 0.6341743648362007, 0.6849423874962937, 0.7337651433868063, 0.7878163070210918, 0.8415110846327628, 0.8952058622444338, 0.9489006398561047, 1.0025954174677758]]}, \"__fbprophet_version\": \"0.7.1\"}" diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v1.0.1.json b/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v1.0.1.json new file mode 100644 index 00000000..6fec26c8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/serialized_model_v1.0.1.json @@ -0,0 +1 @@ +"{\"growth\": \"linear\", \"n_changepoints\": 15, \"specified_changepoints\": false, \"changepoint_range\": 0.8, \"yearly_seasonality\": \"auto\", \"weekly_seasonality\": \"auto\", \"daily_seasonality\": \"auto\", \"seasonality_mode\": \"additive\", \"seasonality_prior_scale\": 10.0, \"changepoint_prior_scale\": 0.05, \"holidays_prior_scale\": 10.0, \"mcmc_samples\": 0, \"interval_width\": 0.8, \"uncertainty_samples\": 1000, \"y_scale\": 19.0, \"logistic_floor\": false, \"country_holidays\": null, \"component_modes\": {\"additive\": [\"weekly\", \"additive_terms\", \"extra_regressors_additive\", \"holidays\"], \"multiplicative\": [\"multiplicative_terms\", \"extra_regressors_multiplicative\"]}, \"changepoints\": \"{\\\"name\\\":\\\"ds\\\",\\\"index\\\":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],\\\"data\\\":[\\\"2020-01-02T00:00:00.000Z\\\",\\\"2020-01-03T00:00:00.000Z\\\",\\\"2020-01-04T00:00:00.000Z\\\",\\\"2020-01-05T00:00:00.000Z\\\",\\\"2020-01-06T00:00:00.000Z\\\",\\\"2020-01-07T00:00:00.000Z\\\",\\\"2020-01-08T00:00:00.000Z\\\",\\\"2020-01-09T00:00:00.000Z\\\",\\\"2020-01-10T00:00:00.000Z\\\",\\\"2020-01-11T00:00:00.000Z\\\",\\\"2020-01-12T00:00:00.000Z\\\",\\\"2020-01-13T00:00:00.000Z\\\",\\\"2020-01-14T00:00:00.000Z\\\",\\\"2020-01-15T00:00:00.000Z\\\",\\\"2020-01-16T00:00:00.000Z\\\"]}\", \"history_dates\": \"{\\\"name\\\":\\\"ds\\\",\\\"index\\\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],\\\"data\\\":[\\\"2020-01-01T00:00:00.000Z\\\",\\\"2020-01-02T00:00:00.000Z\\\",\\\"2020-01-03T00:00:00.000Z\\\",\\\"2020-01-04T00:00:00.000Z\\\",\\\"2020-01-05T00:00:00.000Z\\\",\\\"2020-01-06T00:00:00.000Z\\\",\\\"2020-01-07T00:00:00.000Z\\\",\\\"2020-01-08T00:00:00.000Z\\\",\\\"2020-01-09T00:00:00.000Z\\\",\\\"2020-01-10T00:00:00.000Z\\\",\\\"2020-01-11T00:00:00.000Z\\\",\\\"2020-01-12T00:00:00.000Z\\\",\\\"2020-01-13T00:00:00.000Z\\\",\\\"2020-01-14T00:00:00.000Z\\\",\\\"2020-01-15T00:00:00.000Z\\\",\\\"2020-01-16T00:00:00.000Z\\\",\\\"2020-01-17T00:00:00.000Z\\\",\\\"2020-01-18T00:00:00.000Z\\\",\\\"2020-01-19T00:00:00.000Z\\\",\\\"2020-01-20T00:00:00.000Z\\\"]}\", \"train_holiday_names\": null, \"start\": 1577836800.0, \"t_scale\": 1641600.0, \"holidays\": null, \"history\": \"{\\\"schema\\\":{\\\"fields\\\":[{\\\"name\\\":\\\"ds\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"y\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"floor\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"t\\\",\\\"type\\\":\\\"number\\\"},{\\\"name\\\":\\\"y_scaled\\\",\\\"type\\\":\\\"number\\\"}],\\\"pandas_version\\\":\\\"1.4.0\\\"},\\\"data\\\":[{\\\"ds\\\":\\\"2020-01-01T00:00:00.000Z\\\",\\\"y\\\":0,\\\"floor\\\":0,\\\"t\\\":0.0,\\\"y_scaled\\\":0.0},{\\\"ds\\\":\\\"2020-01-02T00:00:00.000Z\\\",\\\"y\\\":1,\\\"floor\\\":0,\\\"t\\\":0.0526315789,\\\"y_scaled\\\":0.0526315789},{\\\"ds\\\":\\\"2020-01-03T00:00:00.000Z\\\",\\\"y\\\":2,\\\"floor\\\":0,\\\"t\\\":0.1052631579,\\\"y_scaled\\\":0.1052631579},{\\\"ds\\\":\\\"2020-01-04T00:00:00.000Z\\\",\\\"y\\\":3,\\\"floor\\\":0,\\\"t\\\":0.1578947368,\\\"y_scaled\\\":0.1578947368},{\\\"ds\\\":\\\"2020-01-05T00:00:00.000Z\\\",\\\"y\\\":4,\\\"floor\\\":0,\\\"t\\\":0.2105263158,\\\"y_scaled\\\":0.2105263158},{\\\"ds\\\":\\\"2020-01-06T00:00:00.000Z\\\",\\\"y\\\":5,\\\"floor\\\":0,\\\"t\\\":0.2631578947,\\\"y_scaled\\\":0.2631578947},{\\\"ds\\\":\\\"2020-01-07T00:00:00.000Z\\\",\\\"y\\\":6,\\\"floor\\\":0,\\\"t\\\":0.3157894737,\\\"y_scaled\\\":0.3157894737},{\\\"ds\\\":\\\"2020-01-08T00:00:00.000Z\\\",\\\"y\\\":7,\\\"floor\\\":0,\\\"t\\\":0.3684210526,\\\"y_scaled\\\":0.3684210526},{\\\"ds\\\":\\\"2020-01-09T00:00:00.000Z\\\",\\\"y\\\":8,\\\"floor\\\":0,\\\"t\\\":0.4210526316,\\\"y_scaled\\\":0.4210526316},{\\\"ds\\\":\\\"2020-01-10T00:00:00.000Z\\\",\\\"y\\\":9,\\\"floor\\\":0,\\\"t\\\":0.4736842105,\\\"y_scaled\\\":0.4736842105},{\\\"ds\\\":\\\"2020-01-11T00:00:00.000Z\\\",\\\"y\\\":10,\\\"floor\\\":0,\\\"t\\\":0.5263157895,\\\"y_scaled\\\":0.5263157895},{\\\"ds\\\":\\\"2020-01-12T00:00:00.000Z\\\",\\\"y\\\":11,\\\"floor\\\":0,\\\"t\\\":0.5789473684,\\\"y_scaled\\\":0.5789473684},{\\\"ds\\\":\\\"2020-01-13T00:00:00.000Z\\\",\\\"y\\\":12,\\\"floor\\\":0,\\\"t\\\":0.6315789474,\\\"y_scaled\\\":0.6315789474},{\\\"ds\\\":\\\"2020-01-14T00:00:00.000Z\\\",\\\"y\\\":13,\\\"floor\\\":0,\\\"t\\\":0.6842105263,\\\"y_scaled\\\":0.6842105263},{\\\"ds\\\":\\\"2020-01-15T00:00:00.000Z\\\",\\\"y\\\":14,\\\"floor\\\":0,\\\"t\\\":0.7368421053,\\\"y_scaled\\\":0.7368421053},{\\\"ds\\\":\\\"2020-01-16T00:00:00.000Z\\\",\\\"y\\\":15,\\\"floor\\\":0,\\\"t\\\":0.7894736842,\\\"y_scaled\\\":0.7894736842},{\\\"ds\\\":\\\"2020-01-17T00:00:00.000Z\\\",\\\"y\\\":16,\\\"floor\\\":0,\\\"t\\\":0.8421052632,\\\"y_scaled\\\":0.8421052632},{\\\"ds\\\":\\\"2020-01-18T00:00:00.000Z\\\",\\\"y\\\":17,\\\"floor\\\":0,\\\"t\\\":0.8947368421,\\\"y_scaled\\\":0.8947368421},{\\\"ds\\\":\\\"2020-01-19T00:00:00.000Z\\\",\\\"y\\\":18,\\\"floor\\\":0,\\\"t\\\":0.9473684211,\\\"y_scaled\\\":0.9473684211},{\\\"ds\\\":\\\"2020-01-20T00:00:00.000Z\\\",\\\"y\\\":19,\\\"floor\\\":0,\\\"t\\\":1.0,\\\"y_scaled\\\":1.0}]}\", \"train_component_cols\": \"{\\\"schema\\\":{\\\"fields\\\":[{\\\"name\\\":\\\"additive_terms\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"weekly\\\",\\\"type\\\":\\\"integer\\\"},{\\\"name\\\":\\\"multiplicative_terms\\\",\\\"type\\\":\\\"integer\\\"}],\\\"pandas_version\\\":\\\"1.4.0\\\"},\\\"data\\\":[{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0},{\\\"additive_terms\\\":1,\\\"weekly\\\":1,\\\"multiplicative_terms\\\":0}]}\", \"changepoints_t\": [0.05263157894736842, 0.10526315789473684, 0.15789473684210525, 0.21052631578947367, 0.2631578947368421, 0.3157894736842105, 0.3684210526315789, 0.42105263157894735, 0.47368421052631576, 0.5263157894736842, 0.5789473684210527, 0.631578947368421, 0.6842105263157895, 0.7368421052631579, 0.7894736842105263], \"seasonalities\": [[\"weekly\"], {\"weekly\": {\"period\": 7, \"fourier_order\": 3, \"prior_scale\": 10.0, \"mode\": \"additive\", \"condition_name\": null}}], \"extra_regressors\": [[], {}], \"fit_kwargs\": {}, \"params\": {\"k\": [[1.02697210905145]], \"m\": [[-0.0030769618763556213]], \"delta\": [[-0.0067713344295760635, -1.8489743725556455e-13, -3.3570135589463447e-14, 2.0851492724135376e-13, -0.05560834408005808, -0.03696006862215325, 0.09933974713183089, -0.006771334429730693, 7.87431718983493e-14, -1.234385828898371e-13, 9.554119248353166e-14, -0.05560834408004029, -0.03696006862202002, 0.09933974713167956, -0.006771334429674014]], \"sigma_obs\": [[3.114271923280071e-13]], \"beta\": [[-0.00034958928816783473, 0.0022663968006279714, -0.0009616626944811777, -0.00018603166834996976, -7.034133451705964e-05, -0.00042298794284303893]], \"trend\": [[-0.0030769618763556213, 0.05097420175793122, 0.10466897936960881, 0.15836375698127664, 0.21205853459294272, 0.2657533122046198, 0.3165213348647148, 0.3653440907552229, 0.4193952543895115, 0.4730900320011826, 0.526784809612858, 0.580479587224527, 0.6341743648362007, 0.6849423874962937, 0.7337651433868063, 0.7878163070210918, 0.8415110846327628, 0.8952058622444338, 0.9489006398561047, 1.0025954174677758]]}, \"__prophet_version\": \"1.0.1\"}" diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/test_diagnostics.py b/.venv/lib/python3.12/site-packages/prophet/tests/test_diagnostics.py new file mode 100644 index 00000000..4eba826b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/test_diagnostics.py @@ -0,0 +1,403 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import datetime +import itertools + +import numpy as np +import pandas as pd +import pytest + +from prophet import Prophet, diagnostics + + +@pytest.fixture(scope="module") +def ts_short(daily_univariate_ts): + return daily_univariate_ts.head(100) + + +class CustomParallelBackend: + def map(self, func, *iterables): + results = [func(*args) for args in zip(*iterables)] + return results + + +PARALLEL_METHODS = [None, "processes", "threads", CustomParallelBackend()] +try: + from dask.distributed import Client + + client = Client(processes=False) # noqa + PARALLEL_METHODS.append("dask") +except ImportError: + pass + +@diagnostics.register_performance_metric +def mase(df, w): + """Mean absolute scale error + + Parameters + ---------- + df: Cross-validation results dataframe. + w: Aggregation window size. + + Returns + ------- + Dataframe with columns horizon and mase. + """ + e = (df['y'] - df['yhat']) + d = np.abs(np.diff(df['y'])).sum()/(df['y'].shape[0]-1) + se = np.abs(e/d) + if w < 0: + return pd.DataFrame({'horizon': df['horizon'], 'mase': se}) + return diagnostics.rolling_mean_by_h( + x=se.values, h=df['horizon'].values, w=w, name='mase' + ) + +class TestCrossValidation: + @pytest.mark.parametrize("parallel_method", PARALLEL_METHODS) + def test_cross_validation(self, ts_short, parallel_method, backend): + m = Prophet(stan_backend=backend) + m.fit(ts_short) + # Calculate the number of cutoff points(k) + horizon = pd.Timedelta("4 days") + period = pd.Timedelta("10 days") + initial = pd.Timedelta("115 days") + df_cv = diagnostics.cross_validation( + m, horizon="4 days", period="10 days", initial="115 days", parallel=parallel_method + ) + assert len(np.unique(df_cv["cutoff"])) == 3 + assert max(df_cv["ds"] - df_cv["cutoff"]) == horizon + assert min(df_cv["cutoff"]) >= min(ts_short["ds"]) + initial + dc = df_cv["cutoff"].diff() + dc = dc[dc > pd.Timedelta(0)].min() + assert dc >= period + assert (df_cv["cutoff"] < df_cv["ds"]).all() + # Each y in df_cv and ts_short with same ds should be equal + df_merged = pd.merge(df_cv, ts_short, "left", on="ds") + assert np.sum((df_merged["y_x"] - df_merged["y_y"]) ** 2) == pytest.approx(0.0) + df_cv = diagnostics.cross_validation( + m, horizon="4 days", period="10 days", initial="135 days" + ) + assert len(np.unique(df_cv["cutoff"])) == 1 + with pytest.raises(ValueError): + diagnostics.cross_validation(m, horizon="10 days", period="10 days", initial="140 days") + + def test_bad_parallel_methods(self, ts_short, backend): + m = Prophet(stan_backend=backend) + m.fit(ts_short) + # invalid alias + with pytest.raises(ValueError, match="'parallel' should be one"): + diagnostics.cross_validation(m, horizon="4 days", parallel="bad") + # no map method + with pytest.raises(ValueError, match="'parallel' should be one"): + diagnostics.cross_validation(m, horizon="4 days", parallel=object()) + + def test_check_single_cutoff_forecast_func_calls(self, ts_short, monkeypatch, backend): + m = Prophet(stan_backend=backend) + m.fit(ts_short) + + def mock_predict(df, model, cutoff, horizon, predict_columns): + nonlocal n_calls + n_calls = n_calls + 1 + return pd.DataFrame( + { + "ds": pd.date_range(start="2012-09-17", periods=3), + "yhat": np.arange(16, 19), + "yhat_lower": np.arange(15, 18), + "yhat_upper": np.arange(17, 20), + "y": np.arange(16.5, 19.5), + "cutoff": [datetime.date(2012, 9, 15)] * 3, + } + ) + + monkeypatch.setattr(diagnostics, "single_cutoff_forecast", mock_predict) + # cross validation with 3 and 7 forecasts + for args, forecasts in ( + (["4 days", "10 days", "115 days"], 3), + (["4 days", "4 days", "115 days"], 7), + ): + n_calls = 0 + _ = diagnostics.cross_validation(m, *args) + # check single forecast function called expected number of times + assert n_calls == forecasts + + @pytest.mark.parametrize("extra_output_columns", ["trend", ["trend"]]) + def test_check_extra_output_columns_cross_validation(self, ts_short, backend, extra_output_columns): + m = Prophet(stan_backend=backend) + m.fit(ts_short) + df_cv = diagnostics.cross_validation( + m, + horizon="1 days", + period="1 days", + initial="140 days", + extra_output_columns=extra_output_columns + ) + assert "trend" in df_cv.columns + + @pytest.mark.parametrize("growth", ["logistic", "flat"]) + def test_cross_validation_logistic_or_flat_growth(self, growth, ts_short, backend): + df = ts_short.copy() + if growth == "logistic": + df["cap"] = 40 + m = Prophet(growth=growth, stan_backend=backend).fit(df) + df_cv = diagnostics.cross_validation( + m, horizon="1 days", period="1 days", initial="140 days" + ) + assert len(np.unique(df_cv["cutoff"])) == 2 + assert (df_cv["cutoff"] < df_cv["ds"]).all() + df_merged = pd.merge(df_cv, ts_short, "left", on="ds") + assert np.sum((df_merged["y_x"] - df_merged["y_y"]) ** 2) == pytest.approx(0.0) + + def test_cross_validation_extra_regressors(self, ts_short, backend): + df = ts_short.copy() + df["extra"] = range(df.shape[0]) + df["is_conditional_week"] = np.arange(df.shape[0]) // 7 % 2 + m = Prophet(stan_backend=backend) + m.add_seasonality(name="monthly", period=30.5, fourier_order=5) + m.add_seasonality( + name="conditional_weekly", + period=7, + fourier_order=3, + prior_scale=2.0, + condition_name="is_conditional_week", + ) + m.add_regressor("extra") + m.fit(df) + df_cv = diagnostics.cross_validation( + m, horizon="4 days", period="4 days", initial="135 days" + ) + assert len(np.unique(df_cv["cutoff"])) == 2 + period = pd.Timedelta("4 days") + dc = df_cv["cutoff"].diff() + dc = dc[dc > pd.Timedelta(0)].min() + assert dc >= period + assert (df_cv["cutoff"] < df_cv["ds"]).all() + df_merged = pd.merge(df_cv, ts_short, "left", on="ds") + assert np.sum((df_merged["y_x"] - df_merged["y_y"]) ** 2) == pytest.approx(0.0) + + def test_cross_validation_default_value_check(self, ts_short, backend): + m = Prophet(stan_backend=backend) + m.fit(ts_short) + # Default value of initial should be equal to 3 * horizon + df_cv1 = diagnostics.cross_validation(m, horizon="32 days", period="10 days") + df_cv2 = diagnostics.cross_validation( + m, horizon="32 days", period="10 days", initial="96 days" + ) + assert ((df_cv1["y"] - df_cv2["y"]) ** 2).sum() == pytest.approx(0.0) + assert ((df_cv1["yhat"] - df_cv2["yhat"]) ** 2).sum() == pytest.approx(0.0) + + def test_cross_validation_custom_cutoffs(self, ts_short, backend): + m = Prophet(stan_backend=backend) + m.fit(ts_short) + # When specify a list of cutoffs + # the cutoff dates in df_cv are those specified + df_cv1 = diagnostics.cross_validation( + m, + horizon="32 days", + period="10 days", + cutoffs=[pd.Timestamp("2012-07-31"), pd.Timestamp("2012-08-31")], + ) + assert len(df_cv1["cutoff"].unique()) == 2 + + def test_cross_validation_uncertainty_disabled(self, ts_short, backend): + df = ts_short.copy() + for uncertainty in [0, False]: + m = Prophet(uncertainty_samples=uncertainty, stan_backend=backend) + m.fit(df, algorithm="Newton") + df_cv = diagnostics.cross_validation( + m, horizon="4 days", period="4 days", initial="115 days" + ) + expected_cols = ["ds", "yhat", "y", "cutoff"] + assert all(col in expected_cols for col in df_cv.columns.tolist()) + df_p = diagnostics.performance_metrics(df_cv) + assert "coverage" not in df_p.columns + + +class TestPerformanceMetrics: + def test_performance_metrics(self, ts_short, backend): + m = Prophet(stan_backend=backend) + m.fit(ts_short) + df_cv = diagnostics.cross_validation( + m, horizon="4 days", period="10 days", initial="90 days" + ) + # Aggregation level none + df_none = diagnostics.performance_metrics(df_cv, rolling_window=-1) + assert set(df_none.columns) == { + "horizon", + "coverage", + "mae", + "mape", + "mdape", + "mse", + "rmse", + "smape", + } + assert df_none.shape[0] == 16 + # Aggregation level 0 + df_0 = diagnostics.performance_metrics(df_cv, rolling_window=0) + assert len(df_0) == 4 + assert len(df_0["horizon"].unique()) == 4 + # Aggregation level 0.2 + df_horizon = diagnostics.performance_metrics(df_cv, rolling_window=0.2) + assert len(df_horizon) == 4 + assert len(df_horizon["horizon"].unique()) == 4 + # Aggregation level all + df_all = diagnostics.performance_metrics(df_cv, rolling_window=1) + assert df_all.shape[0] == 1 + for metric in ["mse", "mape", "mae", "coverage"]: + assert df_all[metric].values[0] == pytest.approx(df_none[metric].mean()) + assert df_all["mdape"].values[0] == pytest.approx(df_none["mdape"].median()) + # Custom list of metrics + df_horizon = diagnostics.performance_metrics( + df_cv, + metrics=["coverage", "mse", "mase"], + ) + assert set(df_horizon.columns) == {"coverage", "mse", "mase","horizon"} + # Skip MAPE + df_cv.loc[0, "y"] = 0.0 + df_horizon = diagnostics.performance_metrics( + df_cv, + metrics=["coverage", "mape"], + ) + assert set(df_horizon.columns) == {"coverage", "horizon"} + # Handle zero y and yhat + df_cv["y"] = 0.0 + df_cv["yhat"] = 0.0 + df_horizon = diagnostics.performance_metrics( + df_cv, + ) + assert set(df_horizon.columns) == {"coverage", "horizon", "mae", "mdape", "mse", "rmse", "smape"} + df_horizon = diagnostics.performance_metrics( + df_cv, + metrics=["mape"], + ) + assert df_horizon is None + # List of metrics containing non-valid metrics + with pytest.raises(ValueError): + diagnostics.performance_metrics( + df_cv, + metrics=["mse", "error_metric"], + ) + + def test_rolling_mean(self): + x = np.arange(10) + h = np.arange(10) + df = diagnostics.rolling_mean_by_h(x=x, h=h, w=1, name="x") + assert np.array_equal(x, df["x"].values) + assert np.array_equal(h, df["horizon"].values) + + df = diagnostics.rolling_mean_by_h(x, h, w=4, name="x") + assert np.allclose(x[3:] - 1.5, df["x"].values) + assert np.array_equal(np.arange(3, 10), df["horizon"].values) + + h = np.array([1.0, 2.0, 3.0, 4.0, 4.0, 4.0, 4.0, 4.0, 7.0, 7.0]) + x_true = np.array([1.0, 5.0, 22.0 / 3]) + h_true = np.array([3.0, 4.0, 7.0]) + df = diagnostics.rolling_mean_by_h(x, h, w=3, name="x") + assert np.allclose(x_true, df["x"].values) + assert np.array_equal(h_true, df["horizon"].values) + + df = diagnostics.rolling_mean_by_h(x, h, w=10, name="x") + assert np.allclose(np.array([7.0]), df["horizon"].values) + assert np.allclose(np.array([4.5]), df["x"].values) + + def test_rolling_median(self): + x = np.arange(10) + h = np.arange(10) + df = diagnostics.rolling_median_by_h(x=x, h=h, w=1, name="x") + assert np.array_equal(x, df["x"].values) + assert np.array_equal(h, df["horizon"].values) + + df = diagnostics.rolling_median_by_h(x, h, w=4, name="x") + x_true = x[3:] - 1.5 + assert np.allclose(x_true, df["x"].values) + assert np.array_equal(np.arange(3, 10), df["horizon"].values) + + h = np.array([1.0, 2.0, 3.0, 4.0, 4.0, 4.0, 4.0, 4.0, 7.0, 7.0]) + x_true = np.array([1.0, 5.0, 8.0]) + h_true = np.array([3.0, 4.0, 7.0]) + df = diagnostics.rolling_median_by_h(x, h, w=3, name="x") + assert np.allclose(x_true, df["x"].values) + assert np.array_equal(h_true, df["horizon"].values) + + df = diagnostics.rolling_median_by_h(x, h, w=10, name="x") + assert np.allclose(np.array([7.0]), df["horizon"].values) + assert np.allclose(np.array([4.5]), df["x"].values) + + +class TestProphetCopy: + @pytest.fixture(scope="class") + def data(self, daily_univariate_ts): + df = daily_univariate_ts.copy() + df["cap"] = 200.0 + df["binary_feature"] = [0] * 255 + [1] * 255 + return df + + def test_prophet_copy(self, data, backend): + # These values are created except for its default values + holiday = pd.DataFrame({"ds": pd.to_datetime(["2016-12-25"]), "holiday": ["x"]}) + products = itertools.product( + ["linear", "logistic"], # growth + [None, pd.to_datetime(["2016-12-25"])], # changepoints + [3], # n_changepoints + [0.9], # changepoint_range + [True, False], # yearly_seasonality + [True, False], # weekly_seasonality + [True, False], # daily_seasonality + [None, holiday], # holidays + ["additive", "multiplicative"], # seasonality_mode + [1.1], # seasonality_prior_scale + [1.1], # holidays_prior_scale + [0.1], # changepoint_prior_scale + [100], # mcmc_samples + [0.9], # interval_width + [200], # uncertainty_samples + ) + # Values should be copied correctly + for product in products: + m1 = Prophet(*product, stan_backend=backend) + m1.country_holidays = "US" + m1.history = m1.setup_dataframe(data.copy(), initialize_scales=True) + m1.set_auto_seasonalities() + m2 = diagnostics.prophet_copy(m1) + assert m1.growth == m2.growth + assert m1.n_changepoints == m2.n_changepoints + assert m1.changepoint_range == m2.changepoint_range + if m1.changepoints is None: + assert m1.changepoints == m2.changepoints + else: + assert m1.changepoints.equals(m2.changepoints) + assert False == m2.yearly_seasonality + assert False == m2.weekly_seasonality + assert False == m2.daily_seasonality + assert m1.yearly_seasonality == ("yearly" in m2.seasonalities) + assert m1.weekly_seasonality == ("weekly" in m2.seasonalities) + assert m1.daily_seasonality == ("daily" in m2.seasonalities) + if m1.holidays is None: + assert m1.holidays == m2.holidays + else: + assert (m1.holidays == m2.holidays).values.all() + assert m1.country_holidays == m2.country_holidays + assert m1.holidays_mode == m2.holidays_mode + assert m1.seasonality_mode == m2.seasonality_mode + assert m1.seasonality_prior_scale == m2.seasonality_prior_scale + assert m1.changepoint_prior_scale == m2.changepoint_prior_scale + assert m1.holidays_prior_scale == m2.holidays_prior_scale + assert m1.mcmc_samples == m2.mcmc_samples + assert m1.interval_width == m2.interval_width + assert m1.uncertainty_samples == m2.uncertainty_samples + + def test_prophet_copy_custom(self, data, backend): + changepoints = pd.date_range("2012-06-15", "2012-09-15") + cutoff = pd.Timestamp("2012-07-25") + m1 = Prophet(changepoints=changepoints, stan_backend=backend) + m1.add_seasonality("custom", 10, 5) + m1.add_regressor("binary_feature") + m1.fit(data) + m2 = diagnostics.prophet_copy(m1, cutoff=cutoff) + changepoints = changepoints[changepoints < cutoff] + assert (changepoints == m2.changepoints).all() + assert "custom" in m2.seasonalities + assert "binary_feature" in m2.extra_regressors diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/test_prophet.py b/.venv/lib/python3.12/site-packages/prophet/tests/test_prophet.py new file mode 100644 index 00000000..1313006f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/test_prophet.py @@ -0,0 +1,984 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import numpy as np +import pandas as pd +import pytest + +from prophet import Prophet +from prophet.utilities import warm_start_params + + +def train_test_split(ts_data: pd.DataFrame, n_test_rows: int) -> pd.DataFrame: + train = ts_data.head(ts_data.shape[0] - n_test_rows) + test = ts_data.tail(n_test_rows) + return train.reset_index(), test.reset_index() + + +def rmse(predictions, targets) -> float: + return np.sqrt(np.mean((predictions - targets) ** 2)) + + +class TestProphetFitPredictDefault: + @pytest.mark.parametrize( + "scaling,expected", + [("absmax", 10.64), ("minmax", 11.13)], + ids=["absmax", "minmax"] + ) + def test_fit_predict(self, daily_univariate_ts, backend, scaling, expected): + test_days = 30 + train, test = train_test_split(daily_univariate_ts, test_days) + forecaster = Prophet(stan_backend=backend, scaling=scaling) + forecaster.fit(train, seed=1237861298) + np.random.seed(876543987) + future = forecaster.make_future_dataframe(test_days, include_history=False) + future = forecaster.predict(future) + res = rmse(future["yhat"], test["y"]) + # Higher threshold due to cmdstan 2.33.1 producing numerical differences for macOS Intel (ARM is fine). + assert res == pytest.approx(expected, 0.1), "backend: {}".format(forecaster.stan_backend) + + @pytest.mark.parametrize( + "scaling,expected", + [("absmax", 23.44), ("minmax", 11.29)], + ids=["absmax", "minmax"] + ) + def test_fit_predict_newton(self, daily_univariate_ts, backend, scaling, expected): + test_days = 30 + train, test = train_test_split(daily_univariate_ts, test_days) + forecaster = Prophet(stan_backend=backend, scaling=scaling) + forecaster.fit(train, algorithm="Newton", seed=1237861298) + np.random.seed(876543987) + future = forecaster.make_future_dataframe(test_days, include_history=False) + future = forecaster.predict(future) + res = rmse(future["yhat"], test["y"]) + assert res == pytest.approx(expected, 0.01), "backend: {}".format(forecaster.stan_backend) + + @pytest.mark.parametrize( + "scaling,expected", + [("absmax", 127.01), ("minmax", 93.45)], + ids=["absmax", "minmax"] + ) + def test_fit_predict_large_numbers(self, large_numbers_ts, backend, scaling, expected): + test_days = 30 + train, test = train_test_split(large_numbers_ts, test_days) + forecaster = Prophet(stan_backend=backend, scaling=scaling) + forecaster.fit(train, seed=1237861298) + np.random.seed(876543987) + future = forecaster.make_future_dataframe(test_days, include_history=False) + future = forecaster.predict(future) + res = rmse(future["yhat"], test["y"]) + assert res == pytest.approx(expected, 0.01), "backend: {}".format(forecaster.stan_backend) + + @pytest.mark.slow + def test_fit_predict_sampling(self, daily_univariate_ts, backend): + test_days = 30 + train, test = train_test_split(daily_univariate_ts, test_days) + forecaster = Prophet(mcmc_samples=500, stan_backend=backend) + # chains adjusted from 4 to 7 to satisfy test for cmdstanpy + forecaster.fit(train, seed=1237861298, chains=7, show_progress=False) + np.random.seed(876543987) + future = forecaster.make_future_dataframe(test_days, include_history=False) + future = forecaster.predict(future) + # this gives ~ 215.77 + res = rmse(future["yhat"], test["y"]) + assert 236 < res < 193, "backend: {}".format(forecaster.stan_backend) + + def test_fit_predict_no_seasons(self, daily_univariate_ts, backend): + test_days = 30 + train, _ = train_test_split(daily_univariate_ts, test_days) + forecaster = Prophet( + weekly_seasonality=False, yearly_seasonality=False, stan_backend=backend + ) + forecaster.fit(train) + future = forecaster.make_future_dataframe(test_days, include_history=False) + result = forecaster.predict(future) + assert (future.ds == result.ds).all() + + def test_fit_predict_no_changepoints(self, daily_univariate_ts, backend): + test_days = daily_univariate_ts.shape[0] // 2 + train, future = train_test_split(daily_univariate_ts, test_days) + forecaster = Prophet(n_changepoints=0, stan_backend=backend) + forecaster.fit(train) + forecaster.predict(future) + assert forecaster.params is not None + assert forecaster.n_changepoints == 0 + + @pytest.mark.slow + def test_fit_predict_no_changepoints_mcmc(self, daily_univariate_ts, backend): + test_days = daily_univariate_ts.shape[0] // 2 + train, future = train_test_split(daily_univariate_ts, test_days) + forecaster = Prophet(n_changepoints=0, mcmc_samples=100, stan_backend=backend) + forecaster.fit(train, show_progress=False) + forecaster.predict(future) + assert forecaster.params is not None + assert forecaster.n_changepoints == 0 + + def test_fit_changepoint_not_in_history(self, daily_univariate_ts, backend): + train = daily_univariate_ts[ + (daily_univariate_ts["ds"] < "2013-01-01") | (daily_univariate_ts["ds"] > "2014-01-01") + ] + future = pd.DataFrame({"ds": daily_univariate_ts["ds"]}) + prophet = Prophet(changepoints=["2013-06-06"], stan_backend=backend) + forecaster = prophet + forecaster.fit(train) + forecaster.predict(future) + assert forecaster.params is not None + assert forecaster.n_changepoints == 1 + + def test_fit_predict_duplicates(self, daily_univariate_ts, backend): + """ + The underlying model should still fit successfully when there are duplicate dates in the history. + The model essentially sees this as multiple observations for the same time value, and fits the parameters + accordingly. + """ + train, test = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + repeated_obs = train.copy() + repeated_obs["y"] += 10 + train = pd.concat([train, repeated_obs]) + forecaster = Prophet(stan_backend=backend) + forecaster.fit(train) + forecaster.predict(test) + + def test_fit_predict_constant_history(self, daily_univariate_ts, backend): + """ + When the training data history is constant, Prophet should predict the same value for all future dates. + """ + for constant in [0, 20]: + train, test = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + train["y"] = constant + forecaster = Prophet(stan_backend=backend) + forecaster.fit(train) + result = forecaster.predict(test) + assert result["yhat"].values[-1] == constant + + def test_fit_predict_uncertainty_disabled(self, daily_univariate_ts, backend): + test_days = daily_univariate_ts.shape[0] // 2 + train, future = train_test_split(daily_univariate_ts, test_days) + for uncertainty in [0, False]: + forecaster = Prophet(uncertainty_samples=uncertainty, stan_backend=backend) + forecaster.fit(train) + result = forecaster.predict(future) + expected_cols = [ + "ds", + "trend", + "additive_terms", + "multiplicative_terms", + "weekly", + "yhat", + ] + assert all(col in expected_cols for col in result.columns.tolist()) + + +class TestProphetDataPrep: + def test_setup_dataframe(self, daily_univariate_ts, backend): + """Test that the columns 't' and 'y_scaled' are added to the dataframe.""" + train, _ = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + m = Prophet(stan_backend=backend) + history = m.setup_dataframe(train, initialize_scales=True) + + assert "t" in history + assert history["t"].min() == 0.0 + assert history["t"].max() == 1.0 + + assert "y_scaled" in history + assert history["y_scaled"].max() == 1.0 + + def test_setup_dataframe_ds_column(self, daily_univariate_ts, backend): + """Test case where 'ds' exists as an index name and column. Prophet should use the column.""" + train, _ = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + train.index = pd.to_datetime(["1970-01-01" for _ in range(train.shape[0])]) + train.index.rename("ds", inplace=True) + m = Prophet(stan_backend=backend) + m.fit(train) + assert np.all(m.history["ds"].values == train["ds"].values) + + def test_logistic_floor(self, daily_univariate_ts, backend): + """Test the scaling of y with logistic growth and a floor/cap.""" + train, _ = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + train["floor"] = 10.0 + train["cap"] = 80.0 + m = Prophet(growth="logistic", stan_backend=backend) + m.fit(train) + assert m.logistic_floor + assert "floor" in m.history + assert m.history["y_scaled"][0] == 1.0 + for col in ["y", "floor", "cap"]: + train[col] += 10.0 + m2 = Prophet(growth="logistic", stan_backend=backend) + m2.fit(train) + assert m2.history["y_scaled"][0] == pytest.approx(1.0, 0.01) + + def test_logistic_floor_minmax(self, daily_univariate_ts, backend): + """Test the scaling of y with logistic growth and a floor/cap.""" + train, _ = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + train["floor"] = 10.0 + train["cap"] = 80.0 + m = Prophet(growth="logistic", stan_backend=backend, scaling="minmax") + m.fit(train) + assert m.logistic_floor + assert "floor" in m.history + assert m.history["y_scaled"].min() > 0.0 + assert m.history["y_scaled"].max() < 1.0 + for col in ["y", "floor", "cap"]: + train[col] += 10.0 + m2 = Prophet(growth="logistic", stan_backend=backend, scaling="minmax") + m2.fit(train) + assert m2.history["y_scaled"].min() > 0.0 + assert m2.history["y_scaled"].max() < 1.0 + # Check that the scaling is the same + assert m2.history['y_scaled'].mean() == m.history['y_scaled'].mean() + + def test_make_future_dataframe(self, daily_univariate_ts, backend): + train = daily_univariate_ts.head(468 // 2) + forecaster = Prophet(stan_backend=backend) + forecaster.fit(train) + future = forecaster.make_future_dataframe(periods=3, freq="D", include_history=False) + correct = pd.DatetimeIndex(["2013-04-26", "2013-04-27", "2013-04-28"]) + assert len(future) == 3 + assert np.all(future["ds"].values == correct.values) + + future = forecaster.make_future_dataframe(periods=3, freq=pd.tseries.offsets.MonthEnd(1), include_history=False) + correct = pd.DatetimeIndex(["2013-04-30", "2013-05-31", "2013-06-30"]) + assert len(future) == 3 + assert np.all(future["ds"].values == correct.values) + + def test_make_future_dataframe_include_history(self, daily_univariate_ts, backend): + train = daily_univariate_ts.head(468 // 2).copy() + #cover history with NAs + train.loc[train.sample(10).index, "y"] = np.nan + + forecaster = Prophet(stan_backend=backend) + forecaster.fit(train) + future = forecaster.make_future_dataframe(periods=3, freq="D", include_history=True) + + assert len(future) == train.shape[0] + 3 + +class TestProphetTrendComponent: + def test_invalid_growth_input(self, backend): + msg = 'Parameter "growth" should be "linear", ' '"logistic" or "flat".' + with pytest.raises(ValueError, match=msg): + Prophet(growth="constant", stan_backend=backend) + + def test_growth_init(self, daily_univariate_ts, backend): + model = Prophet(growth="logistic", stan_backend=backend) + train = daily_univariate_ts.iloc[:468].copy() + train["cap"] = train["y"].max() + + history = model.setup_dataframe(train, initialize_scales=True) + + k, m = model.linear_growth_init(history) + assert k == pytest.approx(0.3055671) + assert m == pytest.approx(0.5307511) + + k, m = model.logistic_growth_init(history) + assert k == pytest.approx(1.507925, abs=1e-4) + assert m == pytest.approx(-0.08167497, abs=1e-4) + + k, m = model.flat_growth_init(history) + assert k == 0 + assert m == pytest.approx(0.49335657, abs=1e-4) + + def test_growth_init_minmax(self, daily_univariate_ts, backend): + model = Prophet(growth="logistic", stan_backend=backend, scaling="minmax") + train = daily_univariate_ts.iloc[:468].copy() + train["cap"] = train["y"].max() + + history = model.setup_dataframe(train, initialize_scales=True) + + k, m = model.linear_growth_init(history) + assert k == pytest.approx(0.4053406) + assert m == pytest.approx(0.3775322) + + k, m = model.logistic_growth_init(history) + assert k == pytest.approx(1.782523, abs=1e-4) + assert m == pytest.approx(0.280521, abs=1e-4) + + k, m = model.flat_growth_init(history) + assert k == 0 + assert m == pytest.approx(0.32792770, abs=1e-4) + + @pytest.mark.parametrize("scaling",["absmax","minmax"]) + def test_flat_growth(self, backend, scaling): + m = Prophet(growth="flat", stan_backend=backend, scaling=scaling) + x = np.linspace(0, 2 * np.pi, 8 * 7) + history = pd.DataFrame( + { + "ds": pd.date_range(start="2020-01-01", periods=8 * 7, freq="d"), + "y": 30 + np.sin(x * 8.0), + } + ) + m.fit(history) + future = m.make_future_dataframe(10, include_history=True) + fcst = m.predict(future) + m_ = m.params["m"][0, 0] + k = m.params["k"][0, 0] + assert k == pytest.approx(0.0) + assert fcst["trend"].unique()[0] == pytest.approx((m_ * m.y_scale) + m.y_min) + assert np.round((m_ * m.y_scale) + m.y_min) == 30.0 + + def test_piecewise_linear(self, backend): + model = Prophet(stan_backend=backend) + + t = np.arange(11.0) + m = 0 + k = 1.0 + deltas = np.array([0.5]) + changepoint_ts = np.array([5]) + + y = model.piecewise_linear(t, deltas, k, m, changepoint_ts) + y_true = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.5, 8.0, 9.5, 11.0, 12.5]) + assert (y - y_true).sum() == 0.0 + + t = t[8:] + y_true = y_true[8:] + y = model.piecewise_linear(t, deltas, k, m, changepoint_ts) + assert (y - y_true).sum() == 0.0 + + def test_piecewise_logistic(self, backend): + model = Prophet(stan_backend=backend) + + t = np.arange(11.0) + cap = np.ones(11) * 10 + m = 0 + k = 1.0 + deltas = np.array([0.5]) + changepoint_ts = np.array([5]) + + y = model.piecewise_logistic(t, cap, deltas, k, m, changepoint_ts) + y_true = np.array( + [ + 5.000000, + 7.310586, + 8.807971, + 9.525741, + 9.820138, + 9.933071, + 9.984988, + 9.996646, + 9.999252, + 9.999833, + 9.999963, + ] + ) + + t = t[8:] + y_true = y_true[8:] + cap = cap[8:] + y = model.piecewise_logistic(t, cap, deltas, k, m, changepoint_ts) + assert (y - y_true).sum() == pytest.approx(0.0, abs=1e-5) + + def test_flat_trend(self, backend): + model = Prophet(stan_backend=backend) + t = np.arange(11) + m = 0.5 + y = model.flat_trend(t, m) + y_true = np.array([0.5] * 11) + assert (y - y_true).sum() == 0.0 + t = t[8:] + y_true = y_true[8:] + y = model.flat_trend(t, m) + assert (y - y_true).sum() == 0.0 + + def test_get_changepoints(self, daily_univariate_ts, backend): + """ + By default, Prophet uses the first 80% of the history to detect changepoints. + """ + train, _ = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + m = Prophet(stan_backend=backend) + history = m.setup_dataframe(train, initialize_scales=True) + m.history = history + m.set_changepoints() + cp = m.changepoints_t + assert cp.shape[0] == m.n_changepoints + assert len(cp.shape) == 1 + assert cp.min() > 0 + cp_indx = int(np.ceil(0.8 * history.shape[0])) + assert cp.max() <= history["t"].values[cp_indx] + + def test_set_changepoint_range(self, daily_univariate_ts, backend): + train, _ = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + m = Prophet(changepoint_range=0.4, stan_backend=backend) + history = m.setup_dataframe(train, initialize_scales=True) + m.history = history + m.set_changepoints() + cp = m.changepoints_t + assert cp.shape[0] == m.n_changepoints + assert len(cp.shape) == 1 + assert cp.min() > 0 + cp_indx = int(np.ceil(0.4 * history.shape[0])) + cp.max() <= history["t"].values[cp_indx] + for out_of_range in [-0.1, 2]: + with pytest.raises(ValueError): + m = Prophet(changepoint_range=out_of_range, stan_backend=backend) + + def test_get_zero_changepoints(self, daily_univariate_ts, backend): + train, _ = train_test_split(daily_univariate_ts, daily_univariate_ts.shape[0] // 2) + m = Prophet(n_changepoints=0, stan_backend=backend) + history = m.setup_dataframe(train, initialize_scales=True) + m.history = history + m.set_changepoints() + cp = m.changepoints_t + assert cp.shape[0] == 1 + assert cp[0] == 0 + + def test_override_n_changepoints(self, daily_univariate_ts, backend): + train = daily_univariate_ts.head(20).copy() + m = Prophet(n_changepoints=15, stan_backend=backend) + history = m.setup_dataframe(train, initialize_scales=True) + m.history = history + m.set_changepoints() + assert m.n_changepoints == 15 + cp = m.changepoints_t + assert cp.shape[0] == 15 + + +class TestProphetSeasonalComponent: + def test_fourier_series_weekly(self, daily_univariate_ts): + mat = Prophet.fourier_series(daily_univariate_ts["ds"], 7, 3) + # These are from the R forecast package directly. + true_values = np.array([0.7818315, 0.6234898, 0.9749279, -0.2225209, 0.4338837, -0.9009689]) + assert np.sum((mat[0] - true_values) ** 2) == pytest.approx(0.0) + + def test_fourier_series_yearly(self, daily_univariate_ts): + mat = Prophet.fourier_series(daily_univariate_ts["ds"], 365.25, 3) + # These are from the R forecast package directly. + true_values = np.array( + [0.7006152, -0.7135393, -0.9998330, 0.01827656, 0.7262249, 0.6874572] + ) + assert np.sum((mat[0] - true_values) ** 2) == pytest.approx(0.0) + + def test_auto_weekly_seasonality(self, daily_univariate_ts, backend): + # Should be enabled + train = daily_univariate_ts.head(15) + m = Prophet(stan_backend=backend) + assert m.weekly_seasonality == "auto" + m.fit(train) + assert "weekly" in m.seasonalities + assert m.seasonalities["weekly"] == { + "period": 7, + "fourier_order": 3, + "prior_scale": 10.0, + "mode": "additive", + "condition_name": None, + } + # Should be disabled due to too short history + train = daily_univariate_ts.head(9) + m = Prophet(stan_backend=backend) + m.fit(train) + assert "weekly" not in m.seasonalities + m = Prophet(weekly_seasonality=True, stan_backend=backend) + m.fit(train) + assert "weekly" in m.seasonalities + # Should be False due to weekly spacing + train = daily_univariate_ts.iloc[::7, :] + m = Prophet(stan_backend=backend) + m.fit(train) + assert "weekly" not in m.seasonalities + m = Prophet(weekly_seasonality=2, seasonality_prior_scale=3.0, stan_backend=backend) + m.fit(daily_univariate_ts) + assert m.seasonalities["weekly"] == { + "period": 7, + "fourier_order": 2, + "prior_scale": 3.0, + "mode": "additive", + "condition_name": None, + } + + def test_auto_yearly_seasonality(self, daily_univariate_ts, backend): + # Should be enabled + m = Prophet(stan_backend=backend) + assert m.yearly_seasonality == "auto" + m.fit(daily_univariate_ts) + assert "yearly" in m.seasonalities + assert m.seasonalities["yearly"] == { + "period": 365.25, + "fourier_order": 10, + "prior_scale": 10.0, + "mode": "additive", + "condition_name": None, + } + # Should be disabled due to too short history + train = daily_univariate_ts.head(240) + m = Prophet(stan_backend=backend) + m.fit(train) + assert "yearly" not in m.seasonalities + m = Prophet(yearly_seasonality=True, stan_backend=backend) + m.fit(train) + assert "yearly" in m.seasonalities + m = Prophet(yearly_seasonality=7, seasonality_prior_scale=3.0, stan_backend=backend) + m.fit(daily_univariate_ts) + assert m.seasonalities["yearly"] == { + "period": 365.25, + "fourier_order": 7, + "prior_scale": 3.0, + "mode": "additive", + "condition_name": None, + } + + def test_auto_daily_seasonality(self, daily_univariate_ts, subdaily_univariate_ts, backend): + # Should be enabled + m = Prophet(stan_backend=backend) + assert m.daily_seasonality == "auto" + m.fit(subdaily_univariate_ts) + assert "daily" in m.seasonalities + assert m.seasonalities["daily"] == { + "period": 1, + "fourier_order": 4, + "prior_scale": 10.0, + "mode": "additive", + "condition_name": None, + } + # Should be disabled due to too short history + train = subdaily_univariate_ts.head(430) + m = Prophet(stan_backend=backend) + m.fit(train) + assert "daily" not in m.seasonalities + m = Prophet(daily_seasonality=True, stan_backend=backend) + m.fit(train) + assert "daily" in m.seasonalities + m = Prophet(daily_seasonality=7, seasonality_prior_scale=3.0, stan_backend=backend) + m.fit(subdaily_univariate_ts) + assert m.seasonalities["daily"] == { + "period": 1, + "fourier_order": 7, + "prior_scale": 3.0, + "mode": "additive", + "condition_name": None, + } + m = Prophet(stan_backend=backend) + m.fit(daily_univariate_ts) + assert "daily" not in m.seasonalities + + def test_set_seasonality_mode(self, backend): + # Setting attribute + m = Prophet(stan_backend=backend) + assert m.seasonality_mode == "additive" + m = Prophet(seasonality_mode="multiplicative", stan_backend=backend) + assert m.seasonality_mode == "multiplicative" + with pytest.raises(ValueError): + Prophet(seasonality_mode="batman", stan_backend=backend) + + def test_set_holidays_mode(self, backend): + # Setting attribute + m = Prophet(stan_backend=backend) + assert m.holidays_mode == "additive" + m = Prophet(seasonality_mode="multiplicative", stan_backend=backend) + assert m.holidays_mode == "multiplicative" + m = Prophet(holidays_mode="multiplicative", stan_backend=backend) + assert m.holidays_mode == "multiplicative" + with pytest.raises(ValueError): + Prophet(holidays_mode="batman", stan_backend=backend) + + def test_seasonality_modes(self, daily_univariate_ts, backend): + # Model with holidays, seasonalities, and extra regressors + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2016-12-25"]), + "holiday": ["xmas"], + "lower_window": [-1], + "upper_window": [0], + } + ) + m = Prophet(seasonality_mode="multiplicative", holidays=holidays, stan_backend=backend) + m.add_seasonality("monthly", period=30, mode="additive", fourier_order=3) + m.add_regressor("binary_feature", mode="additive") + m.add_regressor("numeric_feature") + # Construct seasonal features + df = daily_univariate_ts.copy() + df["binary_feature"] = [0] * 255 + [1] * 255 + df["numeric_feature"] = range(510) + df = m.setup_dataframe(df, initialize_scales=True) + m.history = df.copy() + m.set_auto_seasonalities() + seasonal_features, prior_scales, component_cols, modes = m.make_all_seasonality_features(df) + assert sum(component_cols["additive_terms"]) == 7 + assert sum(component_cols["multiplicative_terms"]) == 29 + assert set(modes["additive"]) == { + "monthly", + "binary_feature", + "additive_terms", + "extra_regressors_additive", + } + assert set(modes["multiplicative"]) == { + "weekly", + "yearly", + "xmas", + "numeric_feature", + "multiplicative_terms", + "extra_regressors_multiplicative", + "holidays", + } + + +class TestProphetCustomSeasonalComponent: + def test_custom_monthly_seasonality(self, backend): + m = Prophet(stan_backend=backend) + m.add_seasonality(name="monthly", period=30, fourier_order=5, prior_scale=2.0) + assert m.seasonalities["monthly"] == { + "period": 30, + "fourier_order": 5, + "prior_scale": 2.0, + "mode": "additive", + "condition_name": None, + } + + def test_duplicate_component_names(self, backend): + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2017-01-02"]), + "holiday": ["special_day"], + "prior_scale": [4.0], + } + ) + m = Prophet(holidays=holidays, stan_backend=backend) + + with pytest.raises(ValueError): + m.add_seasonality(name="special_day", period=30, fourier_order=5) + with pytest.raises(ValueError): + m.add_seasonality(name="trend", period=30, fourier_order=5) + m.add_seasonality(name="weekly", period=30, fourier_order=5) + + def test_custom_fourier_order(self, backend): + """Fourier order cannot be <= 0""" + m = Prophet(stan_backend=backend) + with pytest.raises(ValueError): + m.add_seasonality(name="weekly", period=7, fourier_order=0) + with pytest.raises(ValueError): + m.add_seasonality(name="weekly", period=7, fourier_order=-1) + + def test_custom_priors(self, daily_univariate_ts, backend): + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2017-01-02"]), + "holiday": ["special_day"], + "prior_scale": [4.0], + } + ) + m = Prophet( + holidays=holidays, + yearly_seasonality=False, + seasonality_mode="multiplicative", + stan_backend=backend, + ) + m.add_seasonality( + name="monthly", period=30, fourier_order=5, prior_scale=2.0, mode="additive" + ) + m.fit(daily_univariate_ts) + assert m.seasonalities["monthly"]["mode"] == "additive" + assert m.seasonalities["weekly"]["mode"] == "multiplicative" + seasonal_features, prior_scales, component_cols, modes = m.make_all_seasonality_features( + m.history + ) + assert sum(component_cols["monthly"]) == 10 + assert sum(component_cols["special_day"]) == 1 + assert sum(component_cols["weekly"]) == 6 + assert sum(component_cols["additive_terms"]) == 10 + assert sum(component_cols["multiplicative_terms"]) == 7 + + if seasonal_features.columns[0] == "monthly_delim_1": + true = [2.0] * 10 + [10.0] * 6 + [4.0] + assert sum(component_cols["monthly"][:10]) == 10 + assert sum(component_cols["weekly"][10:16]) == 6 + else: + true = [10.0] * 6 + [2.0] * 10 + [4.0] + assert sum(component_cols["weekly"][:6]) == 6 + assert sum(component_cols["monthly"][6:16]) == 10 + assert prior_scales == true + + def test_conditional_custom_seasonality(self, daily_univariate_ts, backend): + m = Prophet(weekly_seasonality=False, yearly_seasonality=False, stan_backend=backend) + m.add_seasonality( + name="conditional_weekly", + period=7, + fourier_order=3, + prior_scale=2.0, + condition_name="is_conditional_week", + ) + m.add_seasonality(name="normal_monthly", period=30.5, fourier_order=5, prior_scale=2.0) + df = daily_univariate_ts.copy() + with pytest.raises(ValueError): + # Require all conditions names in df + m.fit(df) + df["is_conditional_week"] = [0] * 255 + [2] * 255 + with pytest.raises(ValueError): + # Require boolean compatible values + m.fit(df) + df["is_conditional_week"] = [0] * 255 + [1] * 255 + m.fit(df) + assert m.seasonalities["conditional_weekly"] == { + "period": 7, + "fourier_order": 3, + "prior_scale": 2.0, + "mode": "additive", + "condition_name": "is_conditional_week", + } + assert m.seasonalities["normal_monthly"]["condition_name"] is None + seasonal_features, prior_scales, component_cols, modes = m.make_all_seasonality_features( + m.history + ) + # Confirm that only values without is_conditional_week has non zero entries + condition_cols = [ + c for c in seasonal_features.columns if c.startswith("conditional_weekly") + ] + assert np.array_equal( + (seasonal_features[condition_cols] != 0).any(axis=1).values, + df["is_conditional_week"].values, + ) + + +class TestProphetHolidays: + def test_holidays_lower_window(self, backend): + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2016-12-25"]), + "holiday": ["xmas"], + "lower_window": [-1], + "upper_window": [0], + } + ) + model = Prophet(holidays=holidays, stan_backend=backend) + df = pd.DataFrame({"ds": pd.date_range("2016-12-20", "2016-12-31")}) + feats, priors, names = model.make_holiday_features(df["ds"], model.holidays) + assert feats.shape == (df.shape[0], 2) + assert (feats.sum(axis=0) - np.array([1.0, 1.0])).sum() == 0.0 + assert priors == [10.0, 10.0] # Default prior + assert names == ["xmas"] + + def test_holidays_upper_window(self, backend): + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2016-12-25"]), + "holiday": ["xmas"], + "lower_window": [-1], + "upper_window": [10], + } + ) + m = Prophet(holidays=holidays, stan_backend=backend) + df = pd.DataFrame({"ds": pd.date_range("2016-12-20", "2016-12-31")}) + feats, priors, names = m.make_holiday_features(df["ds"], m.holidays) + # 12 columns generated even though only 8 overlap + assert feats.shape == (df.shape[0], 12) + assert priors == [10.0 for _ in range(12)] + assert names == ["xmas"] + + def test_holidays_priors(self, backend): + # Check prior specifications + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2016-12-25", "2017-12-25"]), + "holiday": ["xmas", "xmas"], + "lower_window": [-1, -1], + "upper_window": [0, 0], + "prior_scale": [5.0, 5.0], + } + ) + m = Prophet(holidays=holidays, stan_backend=backend) + df = pd.DataFrame({"ds": pd.date_range("2016-12-20", "2016-12-31")}) + feats, priors, names = m.make_holiday_features(df["ds"], m.holidays) + assert priors == [5.0, 5.0] + assert names == ["xmas"] + # 2 different priors + holidays2 = pd.DataFrame( + { + "ds": pd.to_datetime(["2012-06-06", "2013-06-06"]), + "holiday": ["seans-bday"] * 2, + "lower_window": [0] * 2, + "upper_window": [1] * 2, + "prior_scale": [8] * 2, + } + ) + holidays2 = pd.concat((holidays, holidays2), sort=True) + m = Prophet(holidays=holidays2, stan_backend=backend) + feats, priors, names = m.make_holiday_features(df["ds"], m.holidays) + pn = zip(priors, [s.split("_delim_")[0] for s in feats.columns]) + for t in pn: + assert t in [(8.0, "seans-bday"), (5.0, "xmas")] + holidays2 = pd.DataFrame( + { + "ds": pd.to_datetime(["2012-06-06", "2013-06-06"]), + "holiday": ["seans-bday"] * 2, + "lower_window": [0] * 2, + "upper_window": [1] * 2, + } + ) + holidays2 = pd.concat((holidays, holidays2), sort=True) + feats, priors, names = Prophet( + holidays=holidays2, holidays_prior_scale=4, stan_backend=backend + ).make_holiday_features(df["ds"], holidays2) + assert set(priors) == {4.0, 5.0} + + def test_holidays_bad_priors(self, backend): + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2016-12-25", "2016-12-27"]), + "holiday": ["xmasish", "xmasish"], + "lower_window": [-1, -1], + "upper_window": [0, 0], + "prior_scale": [5.0, 6.0], + } + ) + df = pd.DataFrame({"ds": pd.date_range("2016-12-20", "2016-12-31")}) + with pytest.raises(ValueError): + Prophet(holidays=holidays, stan_backend=backend).make_holiday_features( + df["ds"], holidays + ) + + def test_fit_with_holidays(self, daily_univariate_ts, backend): + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2012-06-06", "2013-06-06"]), + "holiday": ["seans-bday"] * 2, + "lower_window": [0] * 2, + "upper_window": [1] * 2, + } + ) + model = Prophet(holidays=holidays, uncertainty_samples=0, stan_backend=backend) + model.fit(daily_univariate_ts).predict() + + def test_fit_predict_with_country_holidays(self, daily_univariate_ts, backend): + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2012-06-06", "2013-06-06"]), + "holiday": ["seans-bday"] * 2, + "lower_window": [0] * 2, + "upper_window": [1] * 2, + } + ) + # Test with holidays and country_holidays + model = Prophet(holidays=holidays, uncertainty_samples=0, stan_backend=backend) + model.add_country_holidays(country_name="US") + model.fit(daily_univariate_ts).predict() + # There are training holidays missing in the test set + train = daily_univariate_ts.head(154) + future = daily_univariate_ts.tail(355) + model = Prophet(uncertainty_samples=0, stan_backend=backend) + model.add_country_holidays(country_name="US") + model.fit(train).predict(future) + # There are test holidays missing in the training set + train = daily_univariate_ts.tail(355) + model = Prophet(uncertainty_samples=0, stan_backend=backend) + model.add_country_holidays(country_name="US") + model.fit(train) + future = model.make_future_dataframe(periods=60, include_history=False) + model.predict(future) + + def test_subdaily_holidays(self, subdaily_univariate_ts, backend): + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2017-01-02"]), + "holiday": ["special_day"], + } + ) + m = Prophet(holidays=holidays, stan_backend=backend) + m.fit(subdaily_univariate_ts) + fcst = m.predict() + assert sum(fcst["special_day"] == 0) == 575 + + + +class TestProphetRegressors: + def test_added_regressors(self, daily_univariate_ts, backend): + m = Prophet(stan_backend=backend) + m.add_regressor("binary_feature", prior_scale=0.2) + m.add_regressor("numeric_feature", prior_scale=0.5) + m.add_regressor("numeric_feature2", prior_scale=0.5, mode="multiplicative") + m.add_regressor("binary_feature2", standardize=True) + df = daily_univariate_ts.copy() + df["binary_feature"] = ["0"] * 255 + ["1"] * 255 + df["numeric_feature"] = range(510) + df["numeric_feature2"] = range(510) + with pytest.raises(ValueError): + # Require all regressors in df + m.fit(df) + df["binary_feature2"] = [1] * 100 + [0] * 410 + m.fit(df) + # Check that standardizations are correctly set + assert m.extra_regressors["binary_feature"] == { + "prior_scale": 0.2, + "mu": 0, + "std": 1, + "standardize": "auto", + "mode": "additive", + } + assert m.extra_regressors["numeric_feature"]["prior_scale"] == 0.5 + assert m.extra_regressors["numeric_feature"]["mu"] == 254.5 + assert m.extra_regressors["numeric_feature"]["std"] == pytest.approx(147.368585, abs=1e-5) + assert m.extra_regressors["numeric_feature2"]["mode"] == "multiplicative" + assert m.extra_regressors["binary_feature2"]["prior_scale"] == 10.0 + assert m.extra_regressors["binary_feature2"]["mu"] == pytest.approx(0.1960784, abs=1e-5) + assert m.extra_regressors["binary_feature2"]["std"] == pytest.approx(0.3974183, abs=1e-5) + # Check that standardization is done correctly + df2 = m.setup_dataframe(df.copy()) + assert df2["binary_feature"][0] == 0 + assert df2["numeric_feature"][0] == pytest.approx(-1.726962, abs=1e-4) + assert df2["binary_feature2"][0] == pytest.approx(2.022859, abs=1e-4) + # Check that feature matrix and prior scales are correctly constructed + seasonal_features, prior_scales, component_cols, modes = m.make_all_seasonality_features( + df2 + ) + assert seasonal_features.shape[1] == 30 + names = ["binary_feature", "numeric_feature", "binary_feature2"] + true_priors = [0.2, 0.5, 10.0] + for i, name in enumerate(names): + assert name in seasonal_features + assert sum(component_cols[name]) == 1 + assert sum(np.array(prior_scales) * component_cols[name]) == true_priors[i] + # Check that forecast components are reasonable + future = pd.DataFrame( + { + "ds": ["2014-06-01"], + "binary_feature": [0], + "numeric_feature": [10], + "numeric_feature2": [10], + } + ) + # future dataframe also requires regressor values + with pytest.raises(ValueError): + m.predict(future) + future["binary_feature2"] = 0 + fcst = m.predict(future) + assert fcst.shape[1] == 37 + assert fcst["binary_feature"][0] == 0 + assert fcst["extra_regressors_additive"][0] == pytest.approx( + fcst["numeric_feature"][0] + fcst["binary_feature2"][0] + ) + assert fcst["extra_regressors_multiplicative"][0] == pytest.approx( + fcst["numeric_feature2"][0] + ) + assert fcst["additive_terms"][0] == pytest.approx( + fcst["yearly"][0] + fcst["weekly"][0] + fcst["extra_regressors_additive"][0] + ) + assert fcst["multiplicative_terms"][0] == pytest.approx( + fcst["extra_regressors_multiplicative"][0] + ) + assert fcst["yhat"][0] == pytest.approx( + fcst["trend"][0] * (1 + fcst["multiplicative_terms"][0]) + fcst["additive_terms"][0] + ) + + def test_constant_regressor(self, daily_univariate_ts, backend): + df = daily_univariate_ts.copy() + df["constant_feature"] = 0 + m = Prophet(stan_backend=backend) + m.add_regressor("constant_feature") + m.fit(df) + assert m.extra_regressors["constant_feature"]["std"] == 1 + + +class TestProphetWarmStart: + def test_fit_warm_start(self, daily_univariate_ts, backend): + m = Prophet(stan_backend=backend).fit(daily_univariate_ts.iloc[:500]) + m2 = Prophet(stan_backend=backend).fit( + daily_univariate_ts.iloc[:510], init=warm_start_params(m) + ) + assert len(m2.params["delta"][0]) == 25 + + def test_sampling_warm_start(self, daily_univariate_ts, backend): + m = Prophet(mcmc_samples=100, stan_backend=backend).fit( + daily_univariate_ts.iloc[:500], show_progress=False + ) + m2 = Prophet(mcmc_samples=100, stan_backend=backend).fit( + daily_univariate_ts.iloc[:510], init=warm_start_params(m), show_progress=False + ) + assert m2.params["delta"].shape == (200, 25) diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/test_serialize.py b/.venv/lib/python3.12/site-packages/prophet/tests/test_serialize.py new file mode 100644 index 00000000..6e42bde2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/test_serialize.py @@ -0,0 +1,142 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import json +from pathlib import Path + +import numpy as np +import pandas as pd +import pytest + +from prophet import Prophet +from prophet.serialize import PD_DATAFRAME, PD_SERIES, model_from_json, model_to_json + + +class TestSerialize: + def test_simple_serialize(self, daily_univariate_ts, backend): + m = Prophet(stan_backend=backend) + df = daily_univariate_ts.head(daily_univariate_ts.shape[0] - 30) + m.fit(df) + + future = m.make_future_dataframe(2, include_history=False) + fcst = m.predict(future) + + model_str = model_to_json(m) + # Make sure json doesn't get too large in the future + assert len(model_str) < 200000 + m2 = model_from_json(model_str) + + # Check that m and m2 are equal + assert m.__dict__.keys() == m2.__dict__.keys() + for k, v in m.__dict__.items(): + if k in ["stan_fit", "stan_backend"]: + continue + if k == "params": + assert v.keys() == m2.params.keys() + for kk, vv in v.items(): + assert np.array_equal(vv, m2.params[kk]) + elif k in PD_SERIES and v is not None: + assert v.equals(m2.__dict__[k]) + elif k in PD_DATAFRAME and v is not None: + pd.testing.assert_frame_equal(v, m2.__dict__[k], check_index_type=False) + elif k == "changepoints_t": + assert np.array_equal(v, m.__dict__[k]) + else: + assert v == m2.__dict__[k] + assert m2.stan_fit is None + assert m2.stan_backend is None + + # Check that m2 makes the same forecast + future2 = m2.make_future_dataframe(2, include_history=False) + fcst2 = m2.predict(future2) + + assert np.array_equal(fcst["yhat"].values, fcst2["yhat"].values) + + def test_full_serialize(self, daily_univariate_ts, backend): + # Construct a model with all attributes + holidays = pd.DataFrame( + { + "ds": pd.to_datetime(["2012-06-06", "2013-06-06"]), + "holiday": ["seans-bday"] * 2, + "lower_window": [0] * 2, + "upper_window": [1] * 2, + } + ) + # Test with holidays and country_holidays + m = Prophet( + holidays=holidays, + seasonality_mode="multiplicative", + changepoints=["2012-07-01", "2012-10-01", "2013-01-01"], + stan_backend=backend, + ) + m.add_country_holidays(country_name="US") + m.add_seasonality( + name="conditional_weekly", + period=7, + fourier_order=3, + prior_scale=2.0, + condition_name="is_conditional_week", + ) + m.add_seasonality(name="normal_monthly", period=30.5, fourier_order=5, prior_scale=2.0) + df = daily_univariate_ts.copy() + df["is_conditional_week"] = [0] * 255 + [1] * 255 + m.add_regressor("binary_feature", prior_scale=0.2) + m.add_regressor("numeric_feature", prior_scale=0.5) + m.add_regressor("numeric_feature2", prior_scale=0.5, mode="multiplicative") + m.add_regressor("binary_feature2", standardize=True) + df["binary_feature"] = ["0"] * 255 + ["1"] * 255 + df["numeric_feature"] = range(510) + df["numeric_feature2"] = range(510) + df["binary_feature2"] = [1] * 100 + [0] * 410 + + train = df.head(400) + test = df.tail(100) + + m.fit(train) + fcst = m.predict(test) + # Serialize! + m2 = model_from_json(model_to_json(m)) + + # Check that m and m2 are equal + assert m.__dict__.keys() == m2.__dict__.keys() + for k, v in m.__dict__.items(): + if k in ["stan_fit", "stan_backend"]: + continue + if k == "params": + assert v.keys() == m2.params.keys() + for kk, vv in v.items(): + assert np.array_equal(vv, m2.params[kk]) + elif k in PD_SERIES and v is not None: + assert v.equals(m2.__dict__[k]) + elif k in PD_DATAFRAME and v is not None: + pd.testing.assert_frame_equal(v, m2.__dict__[k], check_index_type=False) + elif k == "changepoints_t": + assert np.array_equal(v, m.__dict__[k]) + else: + assert v == m2.__dict__[k] + assert m2.stan_fit is None + assert m2.stan_backend is None + + # Check that m2 makes the same forecast + fcst2 = m2.predict(test) + assert np.array_equal(fcst["yhat"].values, fcst2["yhat"].values) + + def test_backwards_compatibility(self): + old_versions = { + "0.6.1.dev0": (29.3669923968994, "fb"), + "0.7.1": (29.282810844704414, "fb"), + "1.0.1": (29.282810844704414, ""), + } + for v, (pred_val, v_str) in old_versions.items(): + fname = Path(__file__).parent / f"serialized_model_v{v}.json" + with open(fname, "r") as fin: + model_str = json.load(fin) + # Check that deserializes + m = model_from_json(model_str) + assert json.loads(model_str)[f"__{v_str}prophet_version"] == v + # Predict + future = m.make_future_dataframe(10) + fcst = m.predict(future) + assert fcst["yhat"].values[-1] == pytest.approx(pred_val) diff --git a/.venv/lib/python3.12/site-packages/prophet/tests/test_utilities.py b/.venv/lib/python3.12/site-packages/prophet/tests/test_utilities.py new file mode 100644 index 00000000..646df3b7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/tests/test_utilities.py @@ -0,0 +1,27 @@ +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import numpy as np + +from prophet import Prophet +from prophet.utilities import regressor_coefficients + + +class TestUtilities: + def test_regressor_coefficients(self, daily_univariate_ts, backend): + m = Prophet(stan_backend=backend) + df = daily_univariate_ts.copy() + np.random.seed(123) + df["regr1"] = np.random.normal(size=df.shape[0]) + df["regr2"] = np.random.normal(size=df.shape[0]) + m.add_regressor("regr1", mode="additive") + m.add_regressor("regr2", mode="multiplicative") + m.fit(df) + + coefs = regressor_coefficients(m) + assert coefs.shape == (2, 6) + # No MCMC sampling, so lower and upper should be the same as mean + assert np.array_equal(coefs["coef_lower"].values, coefs["coef"].values) + assert np.array_equal(coefs["coef_upper"].values, coefs["coef"].values) diff --git a/.venv/lib/python3.12/site-packages/prophet/utilities.py b/.venv/lib/python3.12/site-packages/prophet/utilities.py new file mode 100644 index 00000000..252c700e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/prophet/utilities.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +# Copyright (c) Facebook, Inc. and its affiliates. + +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +from __future__ import absolute_import, division, print_function + +import numpy as np +import pandas as pd + +def regressor_index(m, name): + """Given the name of a regressor, return its (column) index in the `beta` matrix. + + Parameters + ---------- + m: Prophet model object, after fitting. + name: Name of the regressor, as passed into the `add_regressor` function. + + Returns + ------- + The column index of the regressor in the `beta` matrix. + """ + return np.extract( + m.train_component_cols[name] == 1, m.train_component_cols.index + )[0] + +def regressor_coefficients(m): + """Summarise the coefficients of the extra regressors used in the model. + + For additive regressors, the coefficient represents the incremental impact + on `y` of a unit increase in the regressor. For multiplicative regressors, + the incremental impact is equal to `trend(t)` multiplied by the coefficient. + + Coefficients are measured on the original scale of the training data. + + Parameters + ---------- + m: Prophet model object, after fitting. + + Returns + ------- + pd.DataFrame containing: + - `regressor`: Name of the regressor + - `regressor_mode`: Whether the regressor has an additive or multiplicative + effect on `y`. + - `center`: The mean of the regressor if it was standardized. Otherwise 0. + - `coef_lower`: Lower bound for the coefficient, estimated from the MCMC samples. + Only different to `coef` if `mcmc_samples > 0`. + - `coef`: Expected value of the coefficient. + - `coef_upper`: Upper bound for the coefficient, estimated from MCMC samples. + Only different to `coef` if `mcmc_samples > 0`. + """ + assert len(m.extra_regressors) > 0, 'No extra regressors found.' + coefs = [] + for regressor, params in m.extra_regressors.items(): + beta = m.params['beta'][:, regressor_index(m, regressor)] + if params['mode'] == 'additive': + coef = beta * m.y_scale / params['std'] + else: + coef = beta / params['std'] + percentiles = [ + (1 - m.interval_width) / 2, + 1 - (1 - m.interval_width) / 2, + ] + coef_bounds = np.quantile(coef, q=percentiles) + record = { + 'regressor': regressor, + 'regressor_mode': params['mode'], + 'center': params['mu'], + 'coef_lower': coef_bounds[0], + 'coef': np.mean(coef), + 'coef_upper': coef_bounds[1], + } + coefs.append(record) + + return pd.DataFrame(coefs) + +def warm_start_params(m): + """ + Retrieve parameters from a trained model in the format used to initialize a new Stan model. + Note that the new Stan model must have these same settings: + n_changepoints, seasonality features, mcmc sampling + for the retrieved parameters to be valid for the new model. + + Parameters + ---------- + m: A trained model of the Prophet class. + + Returns + ------- + A Dictionary containing retrieved parameters of m. + """ + res = {} + for pname in ['k', 'm', 'sigma_obs']: + if m.mcmc_samples == 0: + res[pname] = m.params[pname][0][0] + else: + res[pname] = np.mean(m.params[pname]) + for pname in ['delta', 'beta']: + if m.mcmc_samples == 0: + res[pname] = m.params[pname][0] + else: + res[pname] = np.mean(m.params[pname], axis=0) + return res diff --git a/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/LICENSE b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/LICENSE new file mode 100644 index 00000000..0040820c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/LICENSE @@ -0,0 +1,11 @@ +Copyright 2023 Simons Foundation + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/METADATA b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/METADATA new file mode 100644 index 00000000..1a81bfc8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/METADATA @@ -0,0 +1,37 @@ +Metadata-Version: 2.1 +Name: stanio +Version: 0.5.1 +Summary: Utilities for preparing Stan inputs and processing Stan outputs +Author: Stan Dev Team +License: BSD-3-Clause +Project-URL: Homepage, https://github.com/stan-dev/stanio +Project-URL: Bug Tracker, https://github.com/stan-dev/stanio/issues +Classifier: Programming Language :: Python :: 3 +Classifier: Development Status :: 4 - Beta +Classifier: Operating System :: OS Independent +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +License-File: LICENSE +Requires-Dist: numpy +Provides-Extra: test +Requires-Dist: pandas ; extra == 'test' +Requires-Dist: pytest ; extra == 'test' +Requires-Dist: pytest-cov ; extra == 'test' +Provides-Extra: ujson +Requires-Dist: ujson >=5.5.0 ; extra == 'ujson' + +# StanIO + +[![codecov](https://codecov.io/gh/stan-dev/stanio/graph/badge.svg?token=P93MLO21FK)](https://codecov.io/gh/stan-dev/stanio) [![Tests](https://github.com/stan-dev/stanio/actions/workflows/test.yaml/badge.svg)](https://github.com/stan-dev/stanio/actions/workflows/test.yaml) + +A set of Python functions for data-wrangling in the formats used by +the [Stan](https://mc-stan.org) probabalistic programming language. + +It is primarily developed for use in [cmdstanpy](https://github.com/stan-dev/cmdstanpy). + +## Features + +- Writing Python dictionaries to Stan-compatible JSON (with optional support for using `ujson` for faster serialization) +- Basic reading of StanCSV files into numpy arrays +- Parameter extraction from numpy arrays based on StanCSV headers + - e.g., if you have a `matrix[2,3] x` in a Stan program, extracting `x` will give you a `(num_draws, 2, 3)` numpy array diff --git a/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/RECORD b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/RECORD new file mode 100644 index 00000000..039a3d51 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/RECORD @@ -0,0 +1,15 @@ +stanio-0.5.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +stanio-0.5.1.dist-info/LICENSE,sha256=s2th4HWOqlkI2OT5_fRkTO28dmCVv56-G81FlgQMNgc,1466 +stanio-0.5.1.dist-info/METADATA,sha256=oDJcilgD8jl765aA-rVCa5VAlLECS0GDznCAuOOpZ1g,1637 +stanio-0.5.1.dist-info/RECORD,, +stanio-0.5.1.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91 +stanio-0.5.1.dist-info/top_level.txt,sha256=ADUEOe-H90-2Jrf-brIXR6JxLolmsg1rTENW5_f1-7Y,7 +stanio/__init__.py,sha256=KKRXh8gAZrQ2-Ai8vGVLN7WA9O-0nDXifn_9QlT1KGg,293 +stanio/__pycache__/__init__.cpython-312.pyc,, +stanio/__pycache__/csv.cpython-312.pyc,, +stanio/__pycache__/json.cpython-312.pyc,, +stanio/__pycache__/reshape.cpython-312.pyc,, +stanio/csv.py,sha256=l1by_WdR8JvBQ1VO_dC2_iCpBqphkInIpKHPOkjneHg,1552 +stanio/json.py,sha256=1PHNjdZNsr7Is3EAvtahT3MHkG-kPwHk3GX3a5D9Qs0,3467 +stanio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +stanio/reshape.py,sha256=-08gOOdsbo3fqJazjkMvPrhO9UiRf6xWg7fAxDrdQsg,8519 diff --git a/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/WHEEL new file mode 100644 index 00000000..564c6724 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (70.2.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/top_level.txt b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/top_level.txt new file mode 100644 index 00000000..b0ac2b48 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio-0.5.1.dist-info/top_level.txt @@ -0,0 +1 @@ +stanio diff --git a/.venv/lib/python3.12/site-packages/stanio/__init__.py b/.venv/lib/python3.12/site-packages/stanio/__init__.py new file mode 100644 index 00000000..fcdb8748 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio/__init__.py @@ -0,0 +1,14 @@ +from .csv import read_csv +from .json import dump_stan_json, write_stan_json +from .reshape import Variable, parse_header, stan_variables + +__all__ = [ + "read_csv", + "write_stan_json", + "dump_stan_json", + "Variable", + "parse_header", + "stan_variables", +] + +__version__ = "0.5.1" diff --git a/.venv/lib/python3.12/site-packages/stanio/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/stanio/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..d676a3f4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/stanio/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/stanio/__pycache__/csv.cpython-312.pyc b/.venv/lib/python3.12/site-packages/stanio/__pycache__/csv.cpython-312.pyc new file mode 100644 index 00000000..169b34f2 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/stanio/__pycache__/csv.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/stanio/__pycache__/json.cpython-312.pyc b/.venv/lib/python3.12/site-packages/stanio/__pycache__/json.cpython-312.pyc new file mode 100644 index 00000000..649ebcf0 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/stanio/__pycache__/json.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/stanio/__pycache__/reshape.cpython-312.pyc b/.venv/lib/python3.12/site-packages/stanio/__pycache__/reshape.cpython-312.pyc new file mode 100644 index 00000000..3634929c Binary files /dev/null and b/.venv/lib/python3.12/site-packages/stanio/__pycache__/reshape.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/stanio/csv.py b/.venv/lib/python3.12/site-packages/stanio/csv.py new file mode 100644 index 00000000..0a299cfe --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio/csv.py @@ -0,0 +1,50 @@ +""" +Module to load the minimal information from a Stan CSV file. +Only the header row and data are read, no metadata is parsed. +""" +from typing import List, Tuple, Union + +import numpy as np +import numpy.typing as npt + + +def read_csv(filenames: Union[str, List[str]]) -> Tuple[str, npt.NDArray[np.float64]]: + """ + Reads CSV files like those produced by Stan, returning the header and data. + + If multiple files are given, the data is stacked along the first axis, + so in typical usage, the shape of the returned data will be + ``(n_chains, n_samples, n_params)``. + + Parameters + ---------- + filenames : Union[str, List[str]] + Path to the CSV file(s) to read. + + Returns + ------- + Tuple[str, npt.NDArray[np.float64]] + The header row and data from the CSV file(s). + + Raises + ------ + ValueError + If multiple files are given and the headers do not match between them. + """ + + if not isinstance(filenames, list): + filenames = [filenames] + + header = "" + data: List[npt.NDArray[np.float64]] = [None for _ in range(len(filenames))] # type: ignore + for i, f in enumerate(filenames): + with open(f, "r") as fd: + while (file_header := fd.readline()).startswith("#"): + pass + if header == "": + header = file_header + elif header != file_header: + raise ValueError("Headers do not match") + data[i] = np.loadtxt(fd, delimiter=",", comments="#") + + return header.strip(), np.stack(data, axis=0) diff --git a/.venv/lib/python3.12/site-packages/stanio/json.py b/.venv/lib/python3.12/site-packages/stanio/json.py new file mode 100644 index 00000000..59c5562a --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio/json.py @@ -0,0 +1,102 @@ +""" +Utilities for writing Stan Json files +""" +try: + import ujson as json + + uj_version = tuple(map(int, json.__version__.split("."))) + if uj_version < (5, 5, 0): + raise ImportError("ujson version too old") # pragma: no cover + UJSON_AVAILABLE = True +except: + UJSON_AVAILABLE = False + import json + +from typing import Any, Mapping + +import numpy as np + + +def process_dictionary(d: Mapping[str, Any]) -> Mapping[str, Any]: + return {k: process_value(v) for k, v in d.items()} + + +# pylint: disable=too-many-return-statements +def process_value(val: Any) -> Any: + if val is None: + return None + if isinstance(val, bool): # stan uses 0, 1 + return int(val) + if isinstance(val, complex): # treat as 2-long array + return [val.real, val.imag] + if isinstance(val, dict): # if a tuple was manually specified + return process_dictionary(val) + if isinstance(val, tuple): # otherwise, turn a tuple into a dict + return dict(zip(range(1, len(val) + 1), map(process_value, val))) + if isinstance(val, list): + return [process_value(i) for i in val] + original_module = getattr(type(val), "__module__", "") + if ( + "numpy" in original_module + or "xarray" in original_module + or "pandas" in original_module + ): + numpy_val = np.asanyarray(val) + # fast paths for numeric types + if numpy_val.dtype.kind in "iuf": + return numpy_val.tolist() + if numpy_val.dtype.kind == "c": + return np.stack([np.asarray(numpy_val.real), np.asarray(numpy_val.imag)], axis=-1).tolist() + if numpy_val.dtype.kind == "b": + return numpy_val.astype(int).tolist() + + # should only be object arrays (tuples, etc) + return process_value(numpy_val.tolist()) + + return val + + +def dump_stan_json(data: Mapping[str, Any]) -> str: + """ + Convert a mapping of strings to data to a JSON string. + + Values can be any numeric type, a boolean (converted to int), + or any collection compatible with :func:`numpy.asarray`, e.g a + :class:`pandas.Series`. + + Produces a string compatible with the + `Json Format for Cmdstan + <https://mc-stan.org/docs/cmdstan-guide/json.html>`__ + + :param data: A mapping from strings to values. This can be a dictionary + or something more exotic like an :class:`xarray.Dataset`. This will be + copied before type conversion, not modified + """ + return json.dumps(process_dictionary(data)) + + +def write_stan_json(path: str, data: Mapping[str, Any]) -> None: + """ + Dump a mapping of strings to data to a JSON file. + + Values can be any numeric type, a boolean (converted to int), + or any collection compatible with :func:`numpy.asarray`, e.g a + :class:`pandas.Series`. + + Produces a file compatible with the + `Json Format for Cmdstan + <https://mc-stan.org/docs/cmdstan-guide/json.html>`__ + + :param path: File path for the created json. Will be overwritten if + already in existence. + + :param data: A mapping from strings to values. This can be a dictionary + or something more exotic like an :class:`xarray.Dataset`. This will be + copied before type conversion, not modified + """ + with open(path, "w") as fd: + if UJSON_AVAILABLE: + json.dump(process_dictionary(data), fd) + else: + for chunk in json.JSONEncoder().iterencode(process_dictionary(data)): + fd.write(chunk) diff --git a/.venv/lib/python3.12/site-packages/stanio/py.typed b/.venv/lib/python3.12/site-packages/stanio/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/.venv/lib/python3.12/site-packages/stanio/reshape.py b/.venv/lib/python3.12/site-packages/stanio/reshape.py new file mode 100644 index 00000000..3f776a62 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/stanio/reshape.py @@ -0,0 +1,252 @@ +""" +Classes and functions for reshaping Stan output. + +Especially with the addition of tuples, Stan writes +flat arrays of data with a rich internal structure. +""" +from dataclasses import dataclass +from enum import Enum +from math import prod +from typing import Any, Dict, Iterable, List, Tuple + +import numpy as np +import numpy.typing as npt + + +class VariableType(Enum): + SCALAR = 1 # real or integer + COMPLEX = 2 # complex number - requires striding + TUPLE = 3 # tuples - require recursive handling + + +@dataclass +class Variable: + """ + This class represents a single output variable of a Stan model. + + It contains information about the name, dimensions, and type of the + variable, as well as the indices of where that variable is located in + the flattened output array Stan models write. + + Generally, this class should not be instantiated directly, but rather + created by the :func:`parse_header()` function. + """ + + # name of the parameter as given in stan. For nested parameters, this is a dummy name + name: str + # where to start (resp. end) reading from the flattened array. + # For arrays with nested parameters, this will be for the first element + # and is relative to the start of the parent + start_idx: int + end_idx: int + # rectangular dimensions of the parameter (e.g. (2, 3) for a 2x3 matrix) + # For nested parameters, this will be the dimensions of the outermost array. + dimensions: Tuple[int, ...] + # type of the parameter + type: VariableType + # list of nested parameters + contents: List["Variable"] + + def dtype(self, top: bool = True) -> np.dtype: + if self.type == VariableType.TUPLE: + elts = [ + (str(i + 1), param.dtype(top=False)) + for i, param in enumerate(self.contents) + ] + dtype = np.dtype(elts) + elif self.type == VariableType.SCALAR: + dtype = np.float64 + elif self.type == VariableType.COMPLEX: + dtype = np.complex128 + + if top: + return dtype + else: + return np.dtype((dtype, self.dimensions)) + + def columns(self) -> Iterable[int]: + return range(self.start_idx, self.end_idx) + + def num_elts(self) -> int: + return prod(self.dimensions) + + def elt_size(self) -> int: + return self.end_idx - self.start_idx + + # total size is elt_size * num_elts + + def _extract_helper(self, src: np.ndarray, offset: int = 0) -> np.ndarray: + start = self.start_idx + offset + end = self.end_idx + offset + if self.type == VariableType.SCALAR: + return src[..., start:end].reshape(-1, *self.dimensions, order="F") + elif self.type == VariableType.COMPLEX: + ret = src[..., start:end].reshape(-1, 2, *self.dimensions, order="F") + ret = ret[:, ::2] + 1j * ret[:, 1::2] + return ret.squeeze().reshape(-1, *self.dimensions, order="F") + elif self.type == VariableType.TUPLE: + out: np.ndarray = np.empty( + (prod(src.shape[:-1]), prod(self.dimensions)), dtype=object + ) + for idx in range(self.num_elts()): + off = idx * self.elt_size() // self.num_elts() + elts = [ + param._extract_helper(src, offset=start + off) + for param in self.contents + ] + for i in range(elts[0].shape[0]): + out[i, idx] = tuple(elt[i] for elt in elts) + return out.reshape(-1, *self.dimensions, order="F") + + def extract_reshape(self, src: np.ndarray, object: bool = True) -> npt.NDArray[Any]: + """ + Given an array where the final dimension is the flattened output of a + Stan model, (e.g. one row of a Stan CSV file), extract the variable + and reshape it to the correct type and dimensions. + + This will most likely result in copies of the data being made if + the variable is not a scalar. + + Parameters + ---------- + src : np.ndarray + The array to extract from. + + Indicies besides the final dimension are preserved + in the output. + + object : bool + If True, the output of tuple types will be an object array, + otherwise it will use custom dtypes to represent tuples. + + Returns + ------- + npt.NDArray[Any] + The extracted variable, reshaped to the correct dimensions. + If the variable is a tuple, this will be an object array, + otherwise it will have a dtype of either float64 or complex128. + """ + out = self._extract_helper(src) + if not object: + out = out.astype(self.dtype()) + if src.ndim > 1: + out = out.reshape(*src.shape[:-1], *self.dimensions, order="F") + else: + out = out.squeeze(axis=0) + + return out + + +def _munge_first_tuple(tup: str) -> str: + return "dummy_" + tup.split(":", 1)[1] + + +def _get_base_name(param: str) -> str: + return param.split(".")[0].split(":")[0] + + +def _from_header(header: str) -> List[Variable]: + # appending __dummy ensures one extra iteration in the later loop + header = header.strip() + ",__dummy" + entries = header.split(",") + params = [] + start_idx = 0 + name = _get_base_name(entries[0]) + for i in range(0, len(entries) - 1): + entry = entries[i] + next_name = _get_base_name(entries[i + 1]) + + if next_name != name: + if ":" not in entry: + dims = entry.split(".")[1:] + if ".real" in entry or ".imag" in entry: + type = VariableType.COMPLEX + dims = dims[:-1] + else: + type = VariableType.SCALAR + params.append( + Variable( + name=name, + start_idx=start_idx, + end_idx=i + 1, + dimensions=tuple(map(int, dims)), + type=type, + contents=[], + ) + ) + else: + dims = entry.split(":")[0].split(".")[1:] + munged_header = ",".join( + dict.fromkeys(map(_munge_first_tuple, entries[start_idx : i + 1])) + ) + + params.append( + Variable( + name=name, + start_idx=start_idx, + end_idx=i + 1, + dimensions=tuple(map(int, dims)), + type=VariableType.TUPLE, + contents=_from_header(munged_header), + ) + ) + + start_idx = i + 1 + name = next_name + + return params + + +def parse_header(header: str) -> Dict[str, Variable]: + """ + Given a comma-separated list of names of Stan outputs, like + that from the header row of a CSV file, parse it into a dictionary of + :class:`Variable` objects. + + Parameters + ---------- + header : str + Comma separated list of Stan variables, including index information. + For example, an ``array[2] real foo` would be represented as + ``foo.1,foo.2``. + + Returns + ------- + Dict[str, Variable] + A dictionary mapping the base name of each variable to a :class:`Variable`. + """ + return {param.name: param for param in _from_header(header)} + + +def stan_variables( + parameters: Dict[str, Variable], + source: npt.NDArray[np.float64], + *, + object: bool = True, +) -> Dict[str, npt.NDArray[Any]]: + """ + Given a dictionary of :class:`Variable` objects and a source array, + extract the variables from the source array and reshape them to the + correct dimensions. + + Parameters + ---------- + parameters : Dict[str, Variable] + A dictionary of :class:`Variable` objects, + like that returned by :func:`parse_header()`. + source : npt.NDArray[np.float64] + The array to extract from. + object : bool + If True, the output of tuple types will be an object array, + otherwise it will use custom dtypes to represent tuples. + + Returns + ------- + Dict[str, npt.NDArray[Any]] + A dictionary mapping the base name of each variable to the extracted + and reshaped data. + """ + return { + param.name: param.extract_reshape(source, object=object) + for param in parameters.values() + } diff --git a/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/INSTALLER b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/LICENCE b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/LICENCE new file mode 100644 index 00000000..a8922b18 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/LICENCE @@ -0,0 +1,49 @@ +`tqdm` is a product of collaborative work. +Unless otherwise stated, all authors (see commit logs) retain copyright +for their respective work, and release the work under the MIT licence +(text below). + +Exceptions or notable authors are listed below +in reverse chronological order: + +* files: * + MPL-2.0 2015-2024 (c) Casper da Costa-Luis + [casperdcl](https://github.com/casperdcl). +* files: tqdm/_tqdm.py + MIT 2016 (c) [PR #96] on behalf of Google Inc. +* files: tqdm/_tqdm.py README.rst .gitignore + MIT 2013 (c) Noam Yorav-Raphael, original author. + +[PR #96]: https://github.com/tqdm/tqdm/pull/96 + + +Mozilla Public Licence (MPL) v. 2.0 - Exhibit A +----------------------------------------------- + +This Source Code Form is subject to the terms of the +Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this project, +You can obtain one at https://mozilla.org/MPL/2.0/. + + +MIT License (MIT) +----------------- + +Copyright (c) 2013 noamraph + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/METADATA b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/METADATA new file mode 100644 index 00000000..181b4dc8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/METADATA @@ -0,0 +1,1594 @@ +Metadata-Version: 2.1 +Name: tqdm +Version: 4.67.1 +Summary: Fast, Extensible Progress Meter +Maintainer-email: tqdm developers <devs@tqdm.ml> +License: MPL-2.0 AND MIT +Project-URL: homepage, https://tqdm.github.io +Project-URL: repository, https://github.com/tqdm/tqdm +Project-URL: changelog, https://tqdm.github.io/releases +Project-URL: wiki, https://github.com/tqdm/tqdm/wiki +Keywords: progressbar,progressmeter,progress,bar,meter,rate,eta,console,terminal,time +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Environment :: MacOS X +Classifier: Environment :: Other Environment +Classifier: Environment :: Win32 (MS Windows) +Classifier: Environment :: X11 Applications +Classifier: Framework :: IPython +Classifier: Framework :: Jupyter +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Education +Classifier: Intended Audience :: End Users/Desktop +Classifier: Intended Audience :: Other Audience +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: MIT License +Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) +Classifier: Operating System :: MacOS +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: Microsoft +Classifier: Operating System :: Microsoft :: MS-DOS +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX +Classifier: Operating System :: POSIX :: BSD +Classifier: Operating System :: POSIX :: BSD :: FreeBSD +Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: POSIX :: SunOS/Solaris +Classifier: Operating System :: Unix +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation +Classifier: Programming Language :: Python :: Implementation :: IronPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Unix Shell +Classifier: Topic :: Desktop Environment +Classifier: Topic :: Education :: Computer Aided Instruction (CAI) +Classifier: Topic :: Education :: Testing +Classifier: Topic :: Office/Business +Classifier: Topic :: Other/Nonlisted Topic +Classifier: Topic :: Software Development :: Build Tools +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Pre-processors +Classifier: Topic :: Software Development :: User Interfaces +Classifier: Topic :: System :: Installation/Setup +Classifier: Topic :: System :: Logging +Classifier: Topic :: System :: Monitoring +Classifier: Topic :: System :: Shells +Classifier: Topic :: Terminals +Classifier: Topic :: Utilities +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENCE +Requires-Dist: colorama; platform_system == "Windows" +Provides-Extra: dev +Requires-Dist: pytest>=6; extra == "dev" +Requires-Dist: pytest-cov; extra == "dev" +Requires-Dist: pytest-timeout; extra == "dev" +Requires-Dist: pytest-asyncio>=0.24; extra == "dev" +Requires-Dist: nbval; extra == "dev" +Provides-Extra: discord +Requires-Dist: requests; extra == "discord" +Provides-Extra: slack +Requires-Dist: slack-sdk; extra == "slack" +Provides-Extra: telegram +Requires-Dist: requests; extra == "telegram" +Provides-Extra: notebook +Requires-Dist: ipywidgets>=6; extra == "notebook" + +|Logo| + +tqdm +==== + +|Py-Versions| |Versions| |Conda-Forge-Status| |Docker| |Snapcraft| + +|Build-Status| |Coverage-Status| |Branch-Coverage-Status| |Codacy-Grade| |Libraries-Rank| |PyPI-Downloads| + +|LICENCE| |OpenHub-Status| |binder-demo| |awesome-python| + +``tqdm`` derives from the Arabic word *taqaddum* (تقدّم) which can mean "progress," +and is an abbreviation for "I love you so much" in Spanish (*te quiero demasiado*). + +Instantly make your loops show a smart progress meter - just wrap any +iterable with ``tqdm(iterable)``, and you're done! + +.. code:: python + + from tqdm import tqdm + for i in tqdm(range(10000)): + ... + +``76%|████████████████████████        | 7568/10000 [00:33<00:10, 229.00it/s]`` + +``trange(N)`` can be also used as a convenient shortcut for +``tqdm(range(N))``. + +|Screenshot| + |Video| |Slides| |Merch| + +It can also be executed as a module with pipes: + +.. code:: sh + + $ seq 9999999 | tqdm --bytes | wc -l + 75.2MB [00:00, 217MB/s] + 9999999 + + $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \ + > backup.tgz + 32%|██████████▍ | 8.89G/27.9G [00:42<01:31, 223MB/s] + +Overhead is low -- about 60ns per iteration (80ns with ``tqdm.gui``), and is +unit tested against performance regression. +By comparison, the well-established +`ProgressBar <https://github.com/niltonvolpato/python-progressbar>`__ has +an 800ns/iter overhead. + +In addition to its low overhead, ``tqdm`` uses smart algorithms to predict +the remaining time and to skip unnecessary iteration displays, which allows +for a negligible overhead in most cases. + +``tqdm`` works on any platform +(Linux, Windows, Mac, FreeBSD, NetBSD, Solaris/SunOS), +in any console or in a GUI, and is also friendly with IPython/Jupyter notebooks. + +``tqdm`` does not require any dependencies (not even ``curses``!), just +Python and an environment supporting ``carriage return \r`` and +``line feed \n`` control characters. + +------------------------------------------ + +.. contents:: Table of contents + :backlinks: top + :local: + + +Installation +------------ + +Latest PyPI stable release +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|Versions| |PyPI-Downloads| |Libraries-Dependents| + +.. code:: sh + + pip install tqdm + +Latest development release on GitHub +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|GitHub-Status| |GitHub-Stars| |GitHub-Commits| |GitHub-Forks| |GitHub-Updated| + +Pull and install pre-release ``devel`` branch: + +.. code:: sh + + pip install "git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm" + +Latest Conda release +~~~~~~~~~~~~~~~~~~~~ + +|Conda-Forge-Status| + +.. code:: sh + + conda install -c conda-forge tqdm + +Latest Snapcraft release +~~~~~~~~~~~~~~~~~~~~~~~~ + +|Snapcraft| + +There are 3 channels to choose from: + +.. code:: sh + + snap install tqdm # implies --stable, i.e. latest tagged release + snap install tqdm --candidate # master branch + snap install tqdm --edge # devel branch + +Note that ``snap`` binaries are purely for CLI use (not ``import``-able), and +automatically set up ``bash`` tab-completion. + +Latest Docker release +~~~~~~~~~~~~~~~~~~~~~ + +|Docker| + +.. code:: sh + + docker pull tqdm/tqdm + docker run -i --rm tqdm/tqdm --help + +Other +~~~~~ + +There are other (unofficial) places where ``tqdm`` may be downloaded, particularly for CLI use: + +|Repology| + +.. |Repology| image:: https://repology.org/badge/tiny-repos/python:tqdm.svg + :target: https://repology.org/project/python:tqdm/versions + +Changelog +--------- + +The list of all changes is available either on GitHub's Releases: +|GitHub-Status|, on the +`wiki <https://github.com/tqdm/tqdm/wiki/Releases>`__, or on the +`website <https://tqdm.github.io/releases>`__. + + +Usage +----- + +``tqdm`` is very versatile and can be used in a number of ways. +The three main ones are given below. + +Iterable-based +~~~~~~~~~~~~~~ + +Wrap ``tqdm()`` around any iterable: + +.. code:: python + + from tqdm import tqdm + from time import sleep + + text = "" + for char in tqdm(["a", "b", "c", "d"]): + sleep(0.25) + text = text + char + +``trange(i)`` is a special optimised instance of ``tqdm(range(i))``: + +.. code:: python + + from tqdm import trange + + for i in trange(100): + sleep(0.01) + +Instantiation outside of the loop allows for manual control over ``tqdm()``: + +.. code:: python + + pbar = tqdm(["a", "b", "c", "d"]) + for char in pbar: + sleep(0.25) + pbar.set_description("Processing %s" % char) + +Manual +~~~~~~ + +Manual control of ``tqdm()`` updates using a ``with`` statement: + +.. code:: python + + with tqdm(total=100) as pbar: + for i in range(10): + sleep(0.1) + pbar.update(10) + +If the optional variable ``total`` (or an iterable with ``len()``) is +provided, predictive stats are displayed. + +``with`` is also optional (you can just assign ``tqdm()`` to a variable, +but in this case don't forget to ``del`` or ``close()`` at the end: + +.. code:: python + + pbar = tqdm(total=100) + for i in range(10): + sleep(0.1) + pbar.update(10) + pbar.close() + +Module +~~~~~~ + +Perhaps the most wonderful use of ``tqdm`` is in a script or on the command +line. Simply inserting ``tqdm`` (or ``python -m tqdm``) between pipes will pass +through all ``stdin`` to ``stdout`` while printing progress to ``stderr``. + +The example below demonstrate counting the number of lines in all Python files +in the current directory, with timing information included. + +.. code:: sh + + $ time find . -name '*.py' -type f -exec cat \{} \; | wc -l + 857365 + + real 0m3.458s + user 0m0.274s + sys 0m3.325s + + $ time find . -name '*.py' -type f -exec cat \{} \; | tqdm | wc -l + 857366it [00:03, 246471.31it/s] + 857365 + + real 0m3.585s + user 0m0.862s + sys 0m3.358s + +Note that the usual arguments for ``tqdm`` can also be specified. + +.. code:: sh + + $ find . -name '*.py' -type f -exec cat \{} \; | + tqdm --unit loc --unit_scale --total 857366 >> /dev/null + 100%|█████████████████████████████████| 857K/857K [00:04<00:00, 246Kloc/s] + +Backing up a large directory? + +.. code:: sh + + $ tar -zcf - docs/ | tqdm --bytes --total `du -sb docs/ | cut -f1` \ + > backup.tgz + 44%|██████████████▊ | 153M/352M [00:14<00:18, 11.0MB/s] + +This can be beautified further: + +.. code:: sh + + $ BYTES=$(du -sb docs/ | cut -f1) + $ tar -cf - docs/ \ + | tqdm --bytes --total "$BYTES" --desc Processing | gzip \ + | tqdm --bytes --total "$BYTES" --desc Compressed --position 1 \ + > ~/backup.tgz + Processing: 100%|██████████████████████| 352M/352M [00:14<00:00, 30.2MB/s] + Compressed: 42%|█████████▎ | 148M/352M [00:14<00:19, 10.9MB/s] + +Or done on a file level using 7-zip: + +.. code:: sh + + $ 7z a -bd -r backup.7z docs/ | grep Compressing \ + | tqdm --total $(find docs/ -type f | wc -l) --unit files \ + | grep -v Compressing + 100%|██████████████████████████▉| 15327/15327 [01:00<00:00, 712.96files/s] + +Pre-existing CLI programs already outputting basic progress information will +benefit from ``tqdm``'s ``--update`` and ``--update_to`` flags: + +.. code:: sh + + $ seq 3 0.1 5 | tqdm --total 5 --update_to --null + 100%|████████████████████████████████████| 5.0/5 [00:00<00:00, 9673.21it/s] + $ seq 10 | tqdm --update --null # 1 + 2 + ... + 10 = 55 iterations + 55it [00:00, 90006.52it/s] + +FAQ and Known Issues +-------------------- + +|GitHub-Issues| + +The most common issues relate to excessive output on multiple lines, instead +of a neat one-line progress bar. + +- Consoles in general: require support for carriage return (``CR``, ``\r``). + + * Some cloud logging consoles which don't support ``\r`` properly + (`cloudwatch <https://github.com/tqdm/tqdm/issues/966>`__, + `K8s <https://github.com/tqdm/tqdm/issues/1319>`__) may benefit from + ``export TQDM_POSITION=-1``. + +- Nested progress bars: + + * Consoles in general: require support for moving cursors up to the + previous line. For example, + `IDLE <https://github.com/tqdm/tqdm/issues/191#issuecomment-230168030>`__, + `ConEmu <https://github.com/tqdm/tqdm/issues/254>`__ and + `PyCharm <https://github.com/tqdm/tqdm/issues/203>`__ (also + `here <https://github.com/tqdm/tqdm/issues/208>`__, + `here <https://github.com/tqdm/tqdm/issues/307>`__, and + `here <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__) + lack full support. + * Windows: additionally may require the Python module ``colorama`` + to ensure nested bars stay within their respective lines. + +- Unicode: + + * Environments which report that they support unicode will have solid smooth + progressbars. The fallback is an ``ascii``-only bar. + * Windows consoles often only partially support unicode and thus + `often require explicit ascii=True <https://github.com/tqdm/tqdm/issues/454#issuecomment-335416815>`__ + (also `here <https://github.com/tqdm/tqdm/issues/499>`__). This is due to + either normal-width unicode characters being incorrectly displayed as + "wide", or some unicode characters not rendering. + +- Wrapping generators: + + * Generator wrapper functions tend to hide the length of iterables. + ``tqdm`` does not. + * Replace ``tqdm(enumerate(...))`` with ``enumerate(tqdm(...))`` or + ``tqdm(enumerate(x), total=len(x), ...)``. + The same applies to ``numpy.ndenumerate``. + * Replace ``tqdm(zip(a, b))`` with ``zip(tqdm(a), b)`` or even + ``zip(tqdm(a), tqdm(b))``. + * The same applies to ``itertools``. + * Some useful convenience functions can be found under ``tqdm.contrib``. + +- `No intermediate output in docker-compose <https://github.com/tqdm/tqdm/issues/771>`__: + use ``docker-compose run`` instead of ``docker-compose up`` and ``tty: true``. + +- Overriding defaults via environment variables: + e.g. in CI/cloud jobs, ``export TQDM_MININTERVAL=5`` to avoid log spam. + This override logic is handled by the ``tqdm.utils.envwrap`` decorator + (useful independent of ``tqdm``). + +If you come across any other difficulties, browse and file |GitHub-Issues|. + +Documentation +------------- + +|Py-Versions| |README-Hits| (Since 19 May 2016) + +.. code:: python + + class tqdm(): + """ + Decorate an iterable object, returning an iterator which acts exactly + like the original iterable, but prints a dynamically updating + progressbar every time a value is requested. + """ + + @envwrap("TQDM_") # override defaults via env vars + def __init__(self, iterable=None, desc=None, total=None, leave=True, + file=None, ncols=None, mininterval=0.1, + maxinterval=10.0, miniters=None, ascii=None, disable=False, + unit='it', unit_scale=False, dynamic_ncols=False, + smoothing=0.3, bar_format=None, initial=0, position=None, + postfix=None, unit_divisor=1000, write_bytes=False, + lock_args=None, nrows=None, colour=None, delay=0): + +Parameters +~~~~~~~~~~ + +* iterable : iterable, optional + Iterable to decorate with a progressbar. + Leave blank to manually manage the updates. +* desc : str, optional + Prefix for the progressbar. +* total : int or float, optional + The number of expected iterations. If unspecified, + len(iterable) is used if possible. If float("inf") or as a last + resort, only basic progress statistics are displayed + (no ETA, no progressbar). + If ``gui`` is True and this parameter needs subsequent updating, + specify an initial arbitrary large positive number, + e.g. 9e9. +* leave : bool, optional + If [default: True], keeps all traces of the progressbar + upon termination of iteration. + If ``None``, will leave only if ``position`` is ``0``. +* file : ``io.TextIOWrapper`` or ``io.StringIO``, optional + Specifies where to output the progress messages + (default: sys.stderr). Uses ``file.write(str)`` and ``file.flush()`` + methods. For encoding, see ``write_bytes``. +* ncols : int, optional + The width of the entire output message. If specified, + dynamically resizes the progressbar to stay within this bound. + If unspecified, attempts to use environment width. The + fallback is a meter width of 10 and no limit for the counter and + statistics. If 0, will not print any meter (only stats). +* mininterval : float, optional + Minimum progress display update interval [default: 0.1] seconds. +* maxinterval : float, optional + Maximum progress display update interval [default: 10] seconds. + Automatically adjusts ``miniters`` to correspond to ``mininterval`` + after long display update lag. Only works if ``dynamic_miniters`` + or monitor thread is enabled. +* miniters : int or float, optional + Minimum progress display update interval, in iterations. + If 0 and ``dynamic_miniters``, will automatically adjust to equal + ``mininterval`` (more CPU efficient, good for tight loops). + If > 0, will skip display of specified number of iterations. + Tweak this and ``mininterval`` to get very efficient loops. + If your progress is erratic with both fast and slow iterations + (network, skipping items, etc) you should set miniters=1. +* ascii : bool or str, optional + If unspecified or False, use unicode (smooth blocks) to fill + the meter. The fallback is to use ASCII characters " 123456789#". +* disable : bool, optional + Whether to disable the entire progressbar wrapper + [default: False]. If set to None, disable on non-TTY. +* unit : str, optional + String that will be used to define the unit of each iteration + [default: it]. +* unit_scale : bool or int or float, optional + If 1 or True, the number of iterations will be reduced/scaled + automatically and a metric prefix following the + International System of Units standard will be added + (kilo, mega, etc.) [default: False]. If any other non-zero + number, will scale ``total`` and ``n``. +* dynamic_ncols : bool, optional + If set, constantly alters ``ncols`` and ``nrows`` to the + environment (allowing for window resizes) [default: False]. +* smoothing : float, optional + Exponential moving average smoothing factor for speed estimates + (ignored in GUI mode). Ranges from 0 (average speed) to 1 + (current/instantaneous speed) [default: 0.3]. +* bar_format : str, optional + Specify a custom bar string formatting. May impact performance. + [default: '{l_bar}{bar}{r_bar}'], where + l_bar='{desc}: {percentage:3.0f}%|' and + r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ' + '{rate_fmt}{postfix}]' + Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, + percentage, elapsed, elapsed_s, ncols, nrows, desc, unit, + rate, rate_fmt, rate_noinv, rate_noinv_fmt, + rate_inv, rate_inv_fmt, postfix, unit_divisor, + remaining, remaining_s, eta. + Note that a trailing ": " is automatically removed after {desc} + if the latter is empty. +* initial : int or float, optional + The initial counter value. Useful when restarting a progress + bar [default: 0]. If using float, consider specifying ``{n:.3f}`` + or similar in ``bar_format``, or specifying ``unit_scale``. +* position : int, optional + Specify the line offset to print this bar (starting from 0) + Automatic if unspecified. + Useful to manage multiple bars at once (eg, from threads). +* postfix : dict or ``*``, optional + Specify additional stats to display at the end of the bar. + Calls ``set_postfix(**postfix)`` if possible (dict). +* unit_divisor : float, optional + [default: 1000], ignored unless ``unit_scale`` is True. +* write_bytes : bool, optional + Whether to write bytes. If (default: False) will write unicode. +* lock_args : tuple, optional + Passed to ``refresh`` for intermediate output + (initialisation, iterating, and updating). +* nrows : int, optional + The screen height. If specified, hides nested bars outside this + bound. If unspecified, attempts to use environment height. + The fallback is 20. +* colour : str, optional + Bar colour (e.g. 'green', '#00ff00'). +* delay : float, optional + Don't display until [default: 0] seconds have elapsed. + +Extra CLI Options +~~~~~~~~~~~~~~~~~ + +* delim : chr, optional + Delimiting character [default: '\n']. Use '\0' for null. + N.B.: on Windows systems, Python converts '\n' to '\r\n'. +* buf_size : int, optional + String buffer size in bytes [default: 256] + used when ``delim`` is specified. +* bytes : bool, optional + If true, will count bytes, ignore ``delim``, and default + ``unit_scale`` to True, ``unit_divisor`` to 1024, and ``unit`` to 'B'. +* tee : bool, optional + If true, passes ``stdin`` to both ``stderr`` and ``stdout``. +* update : bool, optional + If true, will treat input as newly elapsed iterations, + i.e. numbers to pass to ``update()``. Note that this is slow + (~2e5 it/s) since every input must be decoded as a number. +* update_to : bool, optional + If true, will treat input as total elapsed iterations, + i.e. numbers to assign to ``self.n``. Note that this is slow + (~2e5 it/s) since every input must be decoded as a number. +* null : bool, optional + If true, will discard input (no stdout). +* manpath : str, optional + Directory in which to install tqdm man pages. +* comppath : str, optional + Directory in which to place tqdm completion. +* log : str, optional + CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET. + +Returns +~~~~~~~ + +* out : decorated iterator. + +.. code:: python + + class tqdm(): + def update(self, n=1): + """ + Manually update the progress bar, useful for streams + such as reading files. + E.g.: + >>> t = tqdm(total=filesize) # Initialise + >>> for current_buffer in stream: + ... ... + ... t.update(len(current_buffer)) + >>> t.close() + The last line is highly recommended, but possibly not necessary if + ``t.update()`` will be called in such a way that ``filesize`` will be + exactly reached and printed. + + Parameters + ---------- + n : int or float, optional + Increment to add to the internal counter of iterations + [default: 1]. If using float, consider specifying ``{n:.3f}`` + or similar in ``bar_format``, or specifying ``unit_scale``. + + Returns + ------- + out : bool or None + True if a ``display()`` was triggered. + """ + + def close(self): + """Cleanup and (if leave=False) close the progressbar.""" + + def clear(self, nomove=False): + """Clear current bar display.""" + + def refresh(self): + """ + Force refresh the display of this bar. + + Parameters + ---------- + nolock : bool, optional + If ``True``, does not lock. + If [default: ``False``]: calls ``acquire()`` on internal lock. + lock_args : tuple, optional + Passed to internal lock's ``acquire()``. + If specified, will only ``display()`` if ``acquire()`` returns ``True``. + """ + + def unpause(self): + """Restart tqdm timer from last print time.""" + + def reset(self, total=None): + """ + Resets to 0 iterations for repeated use. + + Consider combining with ``leave=True``. + + Parameters + ---------- + total : int or float, optional. Total to use for the new bar. + """ + + def set_description(self, desc=None, refresh=True): + """ + Set/modify description of the progress bar. + + Parameters + ---------- + desc : str, optional + refresh : bool, optional + Forces refresh [default: True]. + """ + + def set_postfix(self, ordered_dict=None, refresh=True, **tqdm_kwargs): + """ + Set/modify postfix (additional stats) + with automatic formatting based on datatype. + + Parameters + ---------- + ordered_dict : dict or OrderedDict, optional + refresh : bool, optional + Forces refresh [default: True]. + kwargs : dict, optional + """ + + @classmethod + def write(cls, s, file=sys.stdout, end="\n"): + """Print a message via tqdm (without overlap with bars).""" + + @property + def format_dict(self): + """Public API for read-only member access.""" + + def display(self, msg=None, pos=None): + """ + Use ``self.sp`` to display ``msg`` in the specified ``pos``. + + Consider overloading this function when inheriting to use e.g.: + ``self.some_frontend(**self.format_dict)`` instead of ``self.sp``. + + Parameters + ---------- + msg : str, optional. What to display (default: ``repr(self)``). + pos : int, optional. Position to ``moveto`` + (default: ``abs(self.pos)``). + """ + + @classmethod + @contextmanager + def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs): + """ + stream : file-like object. + method : str, "read" or "write". The result of ``read()`` and + the first argument of ``write()`` should have a ``len()``. + + >>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj: + ... while True: + ... chunk = fobj.read(chunk_size) + ... if not chunk: + ... break + """ + + @classmethod + def pandas(cls, *targs, **tqdm_kwargs): + """Registers the current `tqdm` class with `pandas`.""" + + def trange(*args, **tqdm_kwargs): + """Shortcut for `tqdm(range(*args), **tqdm_kwargs)`.""" + +Convenience Functions +~~~~~~~~~~~~~~~~~~~~~ + +.. code:: python + + def tqdm.contrib.tenumerate(iterable, start=0, total=None, + tqdm_class=tqdm.auto.tqdm, **tqdm_kwargs): + """Equivalent of `numpy.ndenumerate` or builtin `enumerate`.""" + + def tqdm.contrib.tzip(iter1, *iter2plus, **tqdm_kwargs): + """Equivalent of builtin `zip`.""" + + def tqdm.contrib.tmap(function, *sequences, **tqdm_kwargs): + """Equivalent of builtin `map`.""" + +Submodules +~~~~~~~~~~ + +.. code:: python + + class tqdm.notebook.tqdm(tqdm.tqdm): + """IPython/Jupyter Notebook widget.""" + + class tqdm.auto.tqdm(tqdm.tqdm): + """Automatically chooses beween `tqdm.notebook` and `tqdm.tqdm`.""" + + class tqdm.asyncio.tqdm(tqdm.tqdm): + """Asynchronous version.""" + @classmethod + def as_completed(cls, fs, *, loop=None, timeout=None, total=None, + **tqdm_kwargs): + """Wrapper for `asyncio.as_completed`.""" + + class tqdm.gui.tqdm(tqdm.tqdm): + """Matplotlib GUI version.""" + + class tqdm.tk.tqdm(tqdm.tqdm): + """Tkinter GUI version.""" + + class tqdm.rich.tqdm(tqdm.tqdm): + """`rich.progress` version.""" + + class tqdm.keras.TqdmCallback(keras.callbacks.Callback): + """Keras callback for epoch and batch progress.""" + + class tqdm.dask.TqdmCallback(dask.callbacks.Callback): + """Dask callback for task progress.""" + + +``contrib`` ++++++++++++ + +The ``tqdm.contrib`` package also contains experimental modules: + +- ``tqdm.contrib.itertools``: Thin wrappers around ``itertools`` +- ``tqdm.contrib.concurrent``: Thin wrappers around ``concurrent.futures`` +- ``tqdm.contrib.slack``: Posts to `Slack <https://slack.com>`__ bots +- ``tqdm.contrib.discord``: Posts to `Discord <https://discord.com>`__ bots +- ``tqdm.contrib.telegram``: Posts to `Telegram <https://telegram.org>`__ bots +- ``tqdm.contrib.bells``: Automagically enables all optional features + + * ``auto``, ``pandas``, ``slack``, ``discord``, ``telegram`` + +Examples and Advanced Usage +--------------------------- + +- See the `examples <https://github.com/tqdm/tqdm/tree/master/examples>`__ + folder; +- import the module and run ``help()``; +- consult the `wiki <https://github.com/tqdm/tqdm/wiki>`__; + + * this has an + `excellent article <https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar>`__ + on how to make a **great** progressbar; + +- check out the `slides from PyData London <https://tqdm.github.io/PyData2019/slides.html>`__, or +- run the |binder-demo|. + +Description and additional stats +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Custom information can be displayed and updated dynamically on ``tqdm`` bars +with the ``desc`` and ``postfix`` arguments: + +.. code:: python + + from tqdm import tqdm, trange + from random import random, randint + from time import sleep + + with trange(10) as t: + for i in t: + # Description will be displayed on the left + t.set_description('GEN %i' % i) + # Postfix will be displayed on the right, + # formatted automatically based on argument's datatype + t.set_postfix(loss=random(), gen=randint(1,999), str='h', + lst=[1, 2]) + sleep(0.1) + + with tqdm(total=10, bar_format="{postfix[0]} {postfix[1][value]:>8.2g}", + postfix=["Batch", {"value": 0}]) as t: + for i in range(10): + sleep(0.1) + t.postfix[1]["value"] = i / 2 + t.update() + +Points to remember when using ``{postfix[...]}`` in the ``bar_format`` string: + +- ``postfix`` also needs to be passed as an initial argument in a compatible + format, and +- ``postfix`` will be auto-converted to a string if it is a ``dict``-like + object. To prevent this behaviour, insert an extra item into the dictionary + where the key is not a string. + +Additional ``bar_format`` parameters may also be defined by overriding +``format_dict``, and the bar itself may be modified using ``ascii``: + +.. code:: python + + from tqdm import tqdm + class TqdmExtraFormat(tqdm): + """Provides a `total_time` format parameter""" + @property + def format_dict(self): + d = super().format_dict + total_time = d["elapsed"] * (d["total"] or 0) / max(d["n"], 1) + d.update(total_time=self.format_interval(total_time) + " in total") + return d + + for i in TqdmExtraFormat( + range(9), ascii=" .oO0", + bar_format="{total_time}: {percentage:.0f}%|{bar}{r_bar}"): + if i == 4: + break + +.. code:: + + 00:00 in total: 44%|0000. | 4/9 [00:00<00:00, 962.93it/s] + +Note that ``{bar}`` also supports a format specifier ``[width][type]``. + +- ``width`` + + * unspecified (default): automatic to fill ``ncols`` + * ``int >= 0``: fixed width overriding ``ncols`` logic + * ``int < 0``: subtract from the automatic default + +- ``type`` + + * ``a``: ascii (``ascii=True`` override) + * ``u``: unicode (``ascii=False`` override) + * ``b``: blank (``ascii=" "`` override) + +This means a fixed bar with right-justified text may be created by using: +``bar_format="{l_bar}{bar:10}|{bar:-10b}right-justified"`` + +Nested progress bars +~~~~~~~~~~~~~~~~~~~~ + +``tqdm`` supports nested progress bars. Here's an example: + +.. code:: python + + from tqdm.auto import trange + from time import sleep + + for i in trange(4, desc='1st loop'): + for j in trange(5, desc='2nd loop'): + for k in trange(50, desc='3rd loop', leave=False): + sleep(0.01) + +For manual control over positioning (e.g. for multi-processing use), +you may specify ``position=n`` where ``n=0`` for the outermost bar, +``n=1`` for the next, and so on. +However, it's best to check if ``tqdm`` can work without manual ``position`` +first. + +.. code:: python + + from time import sleep + from tqdm import trange, tqdm + from multiprocessing import Pool, RLock, freeze_support + + L = list(range(9)) + + def progresser(n): + interval = 0.001 / (n + 2) + total = 5000 + text = f"#{n}, est. {interval * total:<04.2}s" + for _ in trange(total, desc=text, position=n): + sleep(interval) + + if __name__ == '__main__': + freeze_support() # for Windows support + tqdm.set_lock(RLock()) # for managing output contention + p = Pool(initializer=tqdm.set_lock, initargs=(tqdm.get_lock(),)) + p.map(progresser, L) + +Note that in Python 3, ``tqdm.write`` is thread-safe: + +.. code:: python + + from time import sleep + from tqdm import tqdm, trange + from concurrent.futures import ThreadPoolExecutor + + L = list(range(9)) + + def progresser(n): + interval = 0.001 / (n + 2) + total = 5000 + text = f"#{n}, est. {interval * total:<04.2}s" + for _ in trange(total, desc=text): + sleep(interval) + if n == 6: + tqdm.write("n == 6 completed.") + tqdm.write("`tqdm.write()` is thread-safe in py3!") + + if __name__ == '__main__': + with ThreadPoolExecutor() as p: + p.map(progresser, L) + +Hooks and callbacks +~~~~~~~~~~~~~~~~~~~ + +``tqdm`` can easily support callbacks/hooks and manual updates. +Here's an example with ``urllib``: + +**``urllib.urlretrieve`` documentation** + + | [...] + | If present, the hook function will be called once + | on establishment of the network connection and once after each block read + | thereafter. The hook will be passed three arguments; a count of blocks + | transferred so far, a block size in bytes, and the total size of the file. + | [...] + +.. code:: python + + import urllib, os + from tqdm import tqdm + urllib = getattr(urllib, 'request', urllib) + + class TqdmUpTo(tqdm): + """Provides `update_to(n)` which uses `tqdm.update(delta_n)`.""" + def update_to(self, b=1, bsize=1, tsize=None): + """ + b : int, optional + Number of blocks transferred so far [default: 1]. + bsize : int, optional + Size of each block (in tqdm units) [default: 1]. + tsize : int, optional + Total size (in tqdm units). If [default: None] remains unchanged. + """ + if tsize is not None: + self.total = tsize + return self.update(b * bsize - self.n) # also sets self.n = b * bsize + + eg_link = "https://caspersci.uk.to/matryoshka.zip" + with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1, + desc=eg_link.split('/')[-1]) as t: # all optional kwargs + urllib.urlretrieve(eg_link, filename=os.devnull, + reporthook=t.update_to, data=None) + t.total = t.n + +Inspired by `twine#242 <https://github.com/pypa/twine/pull/242>`__. +Functional alternative in +`examples/tqdm_wget.py <https://github.com/tqdm/tqdm/blob/master/examples/tqdm_wget.py>`__. + +It is recommend to use ``miniters=1`` whenever there is potentially +large differences in iteration speed (e.g. downloading a file over +a patchy connection). + +**Wrapping read/write methods** + +To measure throughput through a file-like object's ``read`` or ``write`` +methods, use ``CallbackIOWrapper``: + +.. code:: python + + from tqdm.auto import tqdm + from tqdm.utils import CallbackIOWrapper + + with tqdm(total=file_obj.size, + unit='B', unit_scale=True, unit_divisor=1024) as t: + fobj = CallbackIOWrapper(t.update, file_obj, "read") + while True: + chunk = fobj.read(chunk_size) + if not chunk: + break + t.reset() + # ... continue to use `t` for something else + +Alternatively, use the even simpler ``wrapattr`` convenience function, +which would condense both the ``urllib`` and ``CallbackIOWrapper`` examples +down to: + +.. code:: python + + import urllib, os + from tqdm import tqdm + + eg_link = "https://caspersci.uk.to/matryoshka.zip" + response = getattr(urllib, 'request', urllib).urlopen(eg_link) + with tqdm.wrapattr(open(os.devnull, "wb"), "write", + miniters=1, desc=eg_link.split('/')[-1], + total=getattr(response, 'length', None)) as fout: + for chunk in response: + fout.write(chunk) + +The ``requests`` equivalent is nearly identical: + +.. code:: python + + import requests, os + from tqdm import tqdm + + eg_link = "https://caspersci.uk.to/matryoshka.zip" + response = requests.get(eg_link, stream=True) + with tqdm.wrapattr(open(os.devnull, "wb"), "write", + miniters=1, desc=eg_link.split('/')[-1], + total=int(response.headers.get('content-length', 0))) as fout: + for chunk in response.iter_content(chunk_size=4096): + fout.write(chunk) + +**Custom callback** + +``tqdm`` is known for intelligently skipping unnecessary displays. To make a +custom callback take advantage of this, simply use the return value of +``update()``. This is set to ``True`` if a ``display()`` was triggered. + +.. code:: python + + from tqdm.auto import tqdm as std_tqdm + + def external_callback(*args, **kwargs): + ... + + class TqdmExt(std_tqdm): + def update(self, n=1): + displayed = super().update(n) + if displayed: + external_callback(**self.format_dict) + return displayed + +``asyncio`` +~~~~~~~~~~~ + +Note that ``break`` isn't currently caught by asynchronous iterators. +This means that ``tqdm`` cannot clean up after itself in this case: + +.. code:: python + + from tqdm.asyncio import tqdm + + async for i in tqdm(range(9)): + if i == 2: + break + +Instead, either call ``pbar.close()`` manually or use the context manager syntax: + +.. code:: python + + from tqdm.asyncio import tqdm + + with tqdm(range(9)) as pbar: + async for i in pbar: + if i == 2: + break + +Pandas Integration +~~~~~~~~~~~~~~~~~~ + +Due to popular demand we've added support for ``pandas`` -- here's an example +for ``DataFrame.progress_apply`` and ``DataFrameGroupBy.progress_apply``: + +.. code:: python + + import pandas as pd + import numpy as np + from tqdm import tqdm + + df = pd.DataFrame(np.random.randint(0, 100, (100000, 6))) + + # Register `pandas.progress_apply` and `pandas.Series.map_apply` with `tqdm` + # (can use `tqdm.gui.tqdm`, `tqdm.notebook.tqdm`, optional kwargs, etc.) + tqdm.pandas(desc="my bar!") + + # Now you can use `progress_apply` instead of `apply` + # and `progress_map` instead of `map` + df.progress_apply(lambda x: x**2) + # can also groupby: + # df.groupby(0).progress_apply(lambda x: x**2) + +In case you're interested in how this works (and how to modify it for your +own callbacks), see the +`examples <https://github.com/tqdm/tqdm/tree/master/examples>`__ +folder or import the module and run ``help()``. + +Keras Integration +~~~~~~~~~~~~~~~~~ + +A ``keras`` callback is also available: + +.. code:: python + + from tqdm.keras import TqdmCallback + + ... + + model.fit(..., verbose=0, callbacks=[TqdmCallback()]) + +Dask Integration +~~~~~~~~~~~~~~~~ + +A ``dask`` callback is also available: + +.. code:: python + + from tqdm.dask import TqdmCallback + + with TqdmCallback(desc="compute"): + ... + arr.compute() + + # or use callback globally + cb = TqdmCallback(desc="global") + cb.register() + arr.compute() + +IPython/Jupyter Integration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +IPython/Jupyter is supported via the ``tqdm.notebook`` submodule: + +.. code:: python + + from tqdm.notebook import trange, tqdm + from time import sleep + + for i in trange(3, desc='1st loop'): + for j in tqdm(range(100), desc='2nd loop'): + sleep(0.01) + +In addition to ``tqdm`` features, the submodule provides a native Jupyter +widget (compatible with IPython v1-v4 and Jupyter), fully working nested bars +and colour hints (blue: normal, green: completed, red: error/interrupt, +light blue: no ETA); as demonstrated below. + +|Screenshot-Jupyter1| +|Screenshot-Jupyter2| +|Screenshot-Jupyter3| + +The ``notebook`` version supports percentage or pixels for overall width +(e.g.: ``ncols='100%'`` or ``ncols='480px'``). + +It is also possible to let ``tqdm`` automatically choose between +console or notebook versions by using the ``autonotebook`` submodule: + +.. code:: python + + from tqdm.autonotebook import tqdm + tqdm.pandas() + +Note that this will issue a ``TqdmExperimentalWarning`` if run in a notebook +since it is not meant to be possible to distinguish between ``jupyter notebook`` +and ``jupyter console``. Use ``auto`` instead of ``autonotebook`` to suppress +this warning. + +Note that notebooks will display the bar in the cell where it was created. +This may be a different cell from the one where it is used. +If this is not desired, either + +- delay the creation of the bar to the cell where it must be displayed, or +- create the bar with ``display=False``, and in a later cell call + ``display(bar.container)``: + +.. code:: python + + from tqdm.notebook import tqdm + pbar = tqdm(..., display=False) + +.. code:: python + + # different cell + display(pbar.container) + +The ``keras`` callback has a ``display()`` method which can be used likewise: + +.. code:: python + + from tqdm.keras import TqdmCallback + cbk = TqdmCallback(display=False) + +.. code:: python + + # different cell + cbk.display() + model.fit(..., verbose=0, callbacks=[cbk]) + +Another possibility is to have a single bar (near the top of the notebook) +which is constantly re-used (using ``reset()`` rather than ``close()``). +For this reason, the notebook version (unlike the CLI version) does not +automatically call ``close()`` upon ``Exception``. + +.. code:: python + + from tqdm.notebook import tqdm + pbar = tqdm() + +.. code:: python + + # different cell + iterable = range(100) + pbar.reset(total=len(iterable)) # initialise with new `total` + for i in iterable: + pbar.update() + pbar.refresh() # force print final status but don't `close()` + +Custom Integration +~~~~~~~~~~~~~~~~~~ + +To change the default arguments (such as making ``dynamic_ncols=True``), +simply use built-in Python magic: + +.. code:: python + + from functools import partial + from tqdm import tqdm as std_tqdm + tqdm = partial(std_tqdm, dynamic_ncols=True) + +For further customisation, +``tqdm`` may be inherited from to create custom callbacks (as with the +``TqdmUpTo`` example `above <#hooks-and-callbacks>`__) or for custom frontends +(e.g. GUIs such as notebook or plotting packages). In the latter case: + +1. ``def __init__()`` to call ``super().__init__(..., gui=True)`` to disable + terminal ``status_printer`` creation. +2. Redefine: ``close()``, ``clear()``, ``display()``. + +Consider overloading ``display()`` to use e.g. +``self.frontend(**self.format_dict)`` instead of ``self.sp(repr(self))``. + +Some submodule examples of inheritance: + +- `tqdm/notebook.py <https://github.com/tqdm/tqdm/blob/master/tqdm/notebook.py>`__ +- `tqdm/gui.py <https://github.com/tqdm/tqdm/blob/master/tqdm/gui.py>`__ +- `tqdm/tk.py <https://github.com/tqdm/tqdm/blob/master/tqdm/tk.py>`__ +- `tqdm/contrib/slack.py <https://github.com/tqdm/tqdm/blob/master/tqdm/contrib/slack.py>`__ +- `tqdm/contrib/discord.py <https://github.com/tqdm/tqdm/blob/master/tqdm/contrib/discord.py>`__ +- `tqdm/contrib/telegram.py <https://github.com/tqdm/tqdm/blob/master/tqdm/contrib/telegram.py>`__ + +Dynamic Monitor/Meter +~~~~~~~~~~~~~~~~~~~~~ + +You can use a ``tqdm`` as a meter which is not monotonically increasing. +This could be because ``n`` decreases (e.g. a CPU usage monitor) or ``total`` +changes. + +One example would be recursively searching for files. The ``total`` is the +number of objects found so far, while ``n`` is the number of those objects which +are files (rather than folders): + +.. code:: python + + from tqdm import tqdm + import os.path + + def find_files_recursively(path, show_progress=True): + files = [] + # total=1 assumes `path` is a file + t = tqdm(total=1, unit="file", disable=not show_progress) + if not os.path.exists(path): + raise IOError("Cannot find:" + path) + + def append_found_file(f): + files.append(f) + t.update() + + def list_found_dir(path): + """returns os.listdir(path) assuming os.path.isdir(path)""" + listing = os.listdir(path) + # subtract 1 since a "file" we found was actually this directory + t.total += len(listing) - 1 + # fancy way to give info without forcing a refresh + t.set_postfix(dir=path[-10:], refresh=False) + t.update(0) # may trigger a refresh + return listing + + def recursively_search(path): + if os.path.isdir(path): + for f in list_found_dir(path): + recursively_search(os.path.join(path, f)) + else: + append_found_file(path) + + recursively_search(path) + t.set_postfix(dir=path) + t.close() + return files + +Using ``update(0)`` is a handy way to let ``tqdm`` decide when to trigger a +display refresh to avoid console spamming. + +Writing messages +~~~~~~~~~~~~~~~~ + +This is a work in progress (see +`#737 <https://github.com/tqdm/tqdm/issues/737>`__). + +Since ``tqdm`` uses a simple printing mechanism to display progress bars, +you should not write any message in the terminal using ``print()`` while +a progressbar is open. + +To write messages in the terminal without any collision with ``tqdm`` bar +display, a ``.write()`` method is provided: + +.. code:: python + + from tqdm.auto import tqdm, trange + from time import sleep + + bar = trange(10) + for i in bar: + # Print using tqdm class method .write() + sleep(0.1) + if not (i % 3): + tqdm.write("Done task %i" % i) + # Can also use bar.write() + +By default, this will print to standard output ``sys.stdout``. but you can +specify any file-like object using the ``file`` argument. For example, this +can be used to redirect the messages writing to a log file or class. + +Redirecting writing +~~~~~~~~~~~~~~~~~~~ + +If using a library that can print messages to the console, editing the library +by replacing ``print()`` with ``tqdm.write()`` may not be desirable. +In that case, redirecting ``sys.stdout`` to ``tqdm.write()`` is an option. + +To redirect ``sys.stdout``, create a file-like class that will write +any input string to ``tqdm.write()``, and supply the arguments +``file=sys.stdout, dynamic_ncols=True``. + +A reusable canonical example is given below: + +.. code:: python + + from time import sleep + import contextlib + import sys + from tqdm import tqdm + from tqdm.contrib import DummyTqdmFile + + + @contextlib.contextmanager + def std_out_err_redirect_tqdm(): + orig_out_err = sys.stdout, sys.stderr + try: + sys.stdout, sys.stderr = map(DummyTqdmFile, orig_out_err) + yield orig_out_err[0] + # Relay exceptions + except Exception as exc: + raise exc + # Always restore sys.stdout/err if necessary + finally: + sys.stdout, sys.stderr = orig_out_err + + def some_fun(i): + print("Fee, fi, fo,".split()[i]) + + # Redirect stdout to tqdm.write() (don't forget the `as save_stdout`) + with std_out_err_redirect_tqdm() as orig_stdout: + # tqdm needs the original stdout + # and dynamic_ncols=True to autodetect console width + for i in tqdm(range(3), file=orig_stdout, dynamic_ncols=True): + sleep(.5) + some_fun(i) + + # After the `with`, printing is restored + print("Done!") + +Redirecting ``logging`` +~~~~~~~~~~~~~~~~~~~~~~~ + +Similar to ``sys.stdout``/``sys.stderr`` as detailed above, console ``logging`` +may also be redirected to ``tqdm.write()``. + +Warning: if also redirecting ``sys.stdout``/``sys.stderr``, make sure to +redirect ``logging`` first if needed. + +Helper methods are available in ``tqdm.contrib.logging``. For example: + +.. code:: python + + import logging + from tqdm import trange + from tqdm.contrib.logging import logging_redirect_tqdm + + LOG = logging.getLogger(__name__) + + if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + with logging_redirect_tqdm(): + for i in trange(9): + if i == 4: + LOG.info("console logging redirected to `tqdm.write()`") + # logging restored + +Monitoring thread, intervals and miniters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``tqdm`` implements a few tricks to increase efficiency and reduce overhead. + +- Avoid unnecessary frequent bar refreshing: ``mininterval`` defines how long + to wait between each refresh. ``tqdm`` always gets updated in the background, + but it will display only every ``mininterval``. +- Reduce number of calls to check system clock/time. +- ``mininterval`` is more intuitive to configure than ``miniters``. + A clever adjustment system ``dynamic_miniters`` will automatically adjust + ``miniters`` to the amount of iterations that fit into time ``mininterval``. + Essentially, ``tqdm`` will check if it's time to print without actually + checking time. This behaviour can be still be bypassed by manually setting + ``miniters``. + +However, consider a case with a combination of fast and slow iterations. +After a few fast iterations, ``dynamic_miniters`` will set ``miniters`` to a +large number. When iteration rate subsequently slows, ``miniters`` will +remain large and thus reduce display update frequency. To address this: + +- ``maxinterval`` defines the maximum time between display refreshes. + A concurrent monitoring thread checks for overdue updates and forces one + where necessary. + +The monitoring thread should not have a noticeable overhead, and guarantees +updates at least every 10 seconds by default. +This value can be directly changed by setting the ``monitor_interval`` of +any ``tqdm`` instance (i.e. ``t = tqdm.tqdm(...); t.monitor_interval = 2``). +The monitor thread may be disabled application-wide by setting +``tqdm.tqdm.monitor_interval = 0`` before instantiation of any ``tqdm`` bar. + + +Merch +----- + +You can buy `tqdm branded merch <https://tqdm.github.io/merch>`__ now! + +Contributions +------------- + +|GitHub-Commits| |GitHub-Issues| |GitHub-PRs| |OpenHub-Status| |GitHub-Contributions| |CII Best Practices| + +All source code is hosted on `GitHub <https://github.com/tqdm/tqdm>`__. +Contributions are welcome. + +See the +`CONTRIBUTING <https://github.com/tqdm/tqdm/blob/master/CONTRIBUTING.md>`__ +file for more information. + +Developers who have made significant contributions, ranked by *SLoC* +(surviving lines of code, +`git fame <https://github.com/casperdcl/git-fame>`__ ``-wMC --excl '\.(png|gif|jpg)$'``), +are: + +==================== ======================================================== ==== ================================ +Name ID SLoC Notes +==================== ======================================================== ==== ================================ +Casper da Costa-Luis `casperdcl <https://github.com/casperdcl>`__ ~80% primary maintainer |Gift-Casper| +Stephen Larroque `lrq3000 <https://github.com/lrq3000>`__ ~9% team member +Martin Zugnoni `martinzugnoni <https://github.com/martinzugnoni>`__ ~3% +Daniel Ecer `de-code <https://github.com/de-code>`__ ~2% +Richard Sheridan `richardsheridan <https://github.com/richardsheridan>`__ ~1% +Guangshuo Chen `chengs <https://github.com/chengs>`__ ~1% +Helio Machado `0x2b3bfa0 <https://github.com/0x2b3bfa0>`__ ~1% +Kyle Altendorf `altendky <https://github.com/altendky>`__ <1% +Noam Yorav-Raphael `noamraph <https://github.com/noamraph>`__ <1% original author +Matthew Stevens `mjstevens777 <https://github.com/mjstevens777>`__ <1% +Hadrien Mary `hadim <https://github.com/hadim>`__ <1% team member +Mikhail Korobov `kmike <https://github.com/kmike>`__ <1% team member +==================== ======================================================== ==== ================================ + +Ports to Other Languages +~~~~~~~~~~~~~~~~~~~~~~~~ + +A list is available on +`this wiki page <https://github.com/tqdm/tqdm/wiki/tqdm-ports>`__. + + +LICENCE +------- + +Open Source (OSI approved): |LICENCE| + +Citation information: |DOI| + +|README-Hits| (Since 19 May 2016) + +.. |Logo| image:: https://tqdm.github.io/img/logo.gif +.. |Screenshot| image:: https://tqdm.github.io/img/tqdm.gif +.. |Video| image:: https://tqdm.github.io/img/video.jpg + :target: https://tqdm.github.io/video +.. |Slides| image:: https://tqdm.github.io/img/slides.jpg + :target: https://tqdm.github.io/PyData2019/slides.html +.. |Merch| image:: https://tqdm.github.io/img/merch.jpg + :target: https://tqdm.github.io/merch +.. |Build-Status| image:: https://img.shields.io/github/actions/workflow/status/tqdm/tqdm/test.yml?branch=master&label=tqdm&logo=GitHub + :target: https://github.com/tqdm/tqdm/actions/workflows/test.yml +.. |Coverage-Status| image:: https://img.shields.io/coveralls/github/tqdm/tqdm/master?logo=coveralls + :target: https://coveralls.io/github/tqdm/tqdm +.. |Branch-Coverage-Status| image:: https://codecov.io/gh/tqdm/tqdm/branch/master/graph/badge.svg + :target: https://codecov.io/gh/tqdm/tqdm +.. |Codacy-Grade| image:: https://app.codacy.com/project/badge/Grade/3f965571598f44549c7818f29cdcf177 + :target: https://www.codacy.com/gh/tqdm/tqdm/dashboard +.. |CII Best Practices| image:: https://bestpractices.coreinfrastructure.org/projects/3264/badge + :target: https://bestpractices.coreinfrastructure.org/projects/3264 +.. |GitHub-Status| image:: https://img.shields.io/github/tag/tqdm/tqdm.svg?maxAge=86400&logo=github&logoColor=white + :target: https://github.com/tqdm/tqdm/releases +.. |GitHub-Forks| image:: https://img.shields.io/github/forks/tqdm/tqdm.svg?logo=github&logoColor=white + :target: https://github.com/tqdm/tqdm/network +.. |GitHub-Stars| image:: https://img.shields.io/github/stars/tqdm/tqdm.svg?logo=github&logoColor=white + :target: https://github.com/tqdm/tqdm/stargazers +.. |GitHub-Commits| image:: https://img.shields.io/github/commit-activity/y/tqdm/tqdm.svg?logo=git&logoColor=white + :target: https://github.com/tqdm/tqdm/graphs/commit-activity +.. |GitHub-Issues| image:: https://img.shields.io/github/issues-closed/tqdm/tqdm.svg?logo=github&logoColor=white + :target: https://github.com/tqdm/tqdm/issues?q= +.. |GitHub-PRs| image:: https://img.shields.io/github/issues-pr-closed/tqdm/tqdm.svg?logo=github&logoColor=white + :target: https://github.com/tqdm/tqdm/pulls +.. |GitHub-Contributions| image:: https://img.shields.io/github/contributors/tqdm/tqdm.svg?logo=github&logoColor=white + :target: https://github.com/tqdm/tqdm/graphs/contributors +.. |GitHub-Updated| image:: https://img.shields.io/github/last-commit/tqdm/tqdm/master.svg?logo=github&logoColor=white&label=pushed + :target: https://github.com/tqdm/tqdm/pulse +.. |Gift-Casper| image:: https://img.shields.io/badge/dynamic/json.svg?color=ff69b4&label=gifts%20received&prefix=%C2%A3&query=%24..sum&url=https%3A%2F%2Fcaspersci.uk.to%2Fgifts.json + :target: https://cdcl.ml/sponsor +.. |Versions| image:: https://img.shields.io/pypi/v/tqdm.svg + :target: https://tqdm.github.io/releases +.. |PyPI-Downloads| image:: https://img.shields.io/pypi/dm/tqdm.svg?label=pypi%20downloads&logo=PyPI&logoColor=white + :target: https://pepy.tech/project/tqdm +.. |Py-Versions| image:: https://img.shields.io/pypi/pyversions/tqdm.svg?logo=python&logoColor=white + :target: https://pypi.org/project/tqdm +.. |Conda-Forge-Status| image:: https://img.shields.io/conda/v/conda-forge/tqdm.svg?label=conda-forge&logo=conda-forge + :target: https://anaconda.org/conda-forge/tqdm +.. |Snapcraft| image:: https://img.shields.io/badge/snap-install-82BEA0.svg?logo=snapcraft + :target: https://snapcraft.io/tqdm +.. |Docker| image:: https://img.shields.io/badge/docker-pull-blue.svg?logo=docker&logoColor=white + :target: https://hub.docker.com/r/tqdm/tqdm +.. |Libraries-Rank| image:: https://img.shields.io/librariesio/sourcerank/pypi/tqdm.svg?logo=koding&logoColor=white + :target: https://libraries.io/pypi/tqdm +.. |Libraries-Dependents| image:: https://img.shields.io/librariesio/dependent-repos/pypi/tqdm.svg?logo=koding&logoColor=white + :target: https://github.com/tqdm/tqdm/network/dependents +.. |OpenHub-Status| image:: https://www.openhub.net/p/tqdm/widgets/project_thin_badge?format=gif + :target: https://www.openhub.net/p/tqdm?ref=Thin+badge +.. |awesome-python| image:: https://awesome.re/mentioned-badge.svg + :target: https://github.com/vinta/awesome-python +.. |LICENCE| image:: https://img.shields.io/pypi/l/tqdm.svg + :target: https://raw.githubusercontent.com/tqdm/tqdm/master/LICENCE +.. |DOI| image:: https://img.shields.io/badge/DOI-10.5281/zenodo.595120-blue.svg + :target: https://doi.org/10.5281/zenodo.595120 +.. |binder-demo| image:: https://mybinder.org/badge_logo.svg + :target: https://mybinder.org/v2/gh/tqdm/tqdm/master?filepath=DEMO.ipynb +.. |Screenshot-Jupyter1| image:: https://tqdm.github.io/img/jupyter-1.gif +.. |Screenshot-Jupyter2| image:: https://tqdm.github.io/img/jupyter-2.gif +.. |Screenshot-Jupyter3| image:: https://tqdm.github.io/img/jupyter-3.gif +.. |README-Hits| image:: https://cgi.cdcl.ml/hits?q=tqdm&style=social&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif + :target: https://cgi.cdcl.ml/hits?q=tqdm&a=plot&r=https://github.com/tqdm/tqdm&l=https://tqdm.github.io/img/favicon.png&f=https://tqdm.github.io/img/logo.gif&style=social diff --git a/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/RECORD b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/RECORD new file mode 100644 index 00000000..3c414765 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/RECORD @@ -0,0 +1,74 @@ +../../../bin/tqdm,sha256=7ems-LFtqvtg6oBUAXmwYlN_vpZ80RxB3HfM2WJTpmA,259 +tqdm-4.67.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +tqdm-4.67.1.dist-info/LICENCE,sha256=3DMlLoKQFeOxUAhvubOkD2rW-zLC9GEM6BL6Z301mGo,1985 +tqdm-4.67.1.dist-info/METADATA,sha256=aIoWMt9SWhmP7FLc_vsSRtMerO6cA1qsrC1-r42P9mk,57675 +tqdm-4.67.1.dist-info/RECORD,, +tqdm-4.67.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91 +tqdm-4.67.1.dist-info/entry_points.txt,sha256=ReJCH7Ui3Zyh6M16E4OhsZ1oU7WtMXCfbtoyBhGO29Y,39 +tqdm-4.67.1.dist-info/top_level.txt,sha256=NLiUJNfmc9At15s7JURiwvqMEjUi9G5PMGRrmMYzNSM,5 +tqdm/__init__.py,sha256=9mQNYSSqP99JasubEC1POJLMmhkkBH6cJZxPIR5G2pQ,1572 +tqdm/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 +tqdm/__pycache__/__init__.cpython-312.pyc,, +tqdm/__pycache__/__main__.cpython-312.pyc,, +tqdm/__pycache__/_dist_ver.cpython-312.pyc,, +tqdm/__pycache__/_main.cpython-312.pyc,, +tqdm/__pycache__/_monitor.cpython-312.pyc,, +tqdm/__pycache__/_tqdm.cpython-312.pyc,, +tqdm/__pycache__/_tqdm_gui.cpython-312.pyc,, +tqdm/__pycache__/_tqdm_notebook.cpython-312.pyc,, +tqdm/__pycache__/_tqdm_pandas.cpython-312.pyc,, +tqdm/__pycache__/_utils.cpython-312.pyc,, +tqdm/__pycache__/asyncio.cpython-312.pyc,, +tqdm/__pycache__/auto.cpython-312.pyc,, +tqdm/__pycache__/autonotebook.cpython-312.pyc,, +tqdm/__pycache__/cli.cpython-312.pyc,, +tqdm/__pycache__/dask.cpython-312.pyc,, +tqdm/__pycache__/gui.cpython-312.pyc,, +tqdm/__pycache__/keras.cpython-312.pyc,, +tqdm/__pycache__/notebook.cpython-312.pyc,, +tqdm/__pycache__/rich.cpython-312.pyc,, +tqdm/__pycache__/std.cpython-312.pyc,, +tqdm/__pycache__/tk.cpython-312.pyc,, +tqdm/__pycache__/utils.cpython-312.pyc,, +tqdm/__pycache__/version.cpython-312.pyc,, +tqdm/_dist_ver.py,sha256=m5AdYI-jB-v6P0VJ_70isH_p24EzSOGSwVvuAZmkmKY,23 +tqdm/_main.py,sha256=9ySvgmi_2Sw4CAo5UDW0Q2dxfTryboEWGHohfCJz0sA,283 +tqdm/_monitor.py,sha256=Uku-DPWgzJ7dO5CK08xKJK-E_F6qQ-JB3ksuXczSYR0,3699 +tqdm/_tqdm.py,sha256=LfLCuJ6bpsVo9xilmtBXyEm1vGnUCFrliW85j3J-nD4,283 +tqdm/_tqdm_gui.py,sha256=03Hc8KayxJveieI5-0-2NGiDpLvw9jZekofJUV7CCwk,287 +tqdm/_tqdm_notebook.py,sha256=BuHiLuxu6uEfZFaPJW3RPpPaxaVctEQA3kdSJSDL1hw,307 +tqdm/_tqdm_pandas.py,sha256=c9jptUgigN6axRDhRd4Rif98Tmxeopc1nFNFhIpbFUE,888 +tqdm/_utils.py,sha256=_4E73bfDj4f1s3sM42NLHNrZDOkijZoWq-n6xWLkdZ8,553 +tqdm/asyncio.py,sha256=Kp2rSkNRf9KRqa3d9YpgeZQ7L7EZf2Ki4bSc7UPIyoo,2757 +tqdm/auto.py,sha256=nDZflj6p2zKkjBCNBourrhS81zYfZy1_dQvbckrdW8o,871 +tqdm/autonotebook.py,sha256=Yb9F5uaiBPhfbDDFpbtoG8I2YUw3uQJ89rUDLbfR6ws,956 +tqdm/cli.py,sha256=SbKlN8QyZ2ogenqt-wT_p6_sx2OOdCjCyhoZBFnlmyI,11010 +tqdm/completion.sh,sha256=j79KbSmpIj_E11jfTfBXrGnUTzKXVpQ1vGVQvsyDRl4,946 +tqdm/contrib/__init__.py,sha256=OgSwVXm-vlDJ-2imtoQ9z8qdom4snMSRztH72KMA82A,2494 +tqdm/contrib/__pycache__/__init__.cpython-312.pyc,, +tqdm/contrib/__pycache__/bells.cpython-312.pyc,, +tqdm/contrib/__pycache__/concurrent.cpython-312.pyc,, +tqdm/contrib/__pycache__/discord.cpython-312.pyc,, +tqdm/contrib/__pycache__/itertools.cpython-312.pyc,, +tqdm/contrib/__pycache__/logging.cpython-312.pyc,, +tqdm/contrib/__pycache__/slack.cpython-312.pyc,, +tqdm/contrib/__pycache__/telegram.cpython-312.pyc,, +tqdm/contrib/__pycache__/utils_worker.cpython-312.pyc,, +tqdm/contrib/bells.py,sha256=Yx1HqGCmHrESCAO700j5wE__JCleNODJxedh1ijPLD0,837 +tqdm/contrib/concurrent.py,sha256=K1yjloKS5WRNFyjLRth0DmU5PAnDbF0A-GD27N-J4a8,3986 +tqdm/contrib/discord.py,sha256=MtVIL1s_dxH21G4sL8FBgQ4Wei23ho9Ek5T-AommvNc,5243 +tqdm/contrib/itertools.py,sha256=WdKKQU5eSzsqHu29SN_oH12huYZo0Jihqoi9-nVhwz4,774 +tqdm/contrib/logging.py,sha256=NsYtnKttj2mMrGm58mEdo5a9DP_2vv8pZyrimSuWulA,3760 +tqdm/contrib/slack.py,sha256=eP_Mr5sQonYniHxxQNGue3jk2JkIPmPWFZqIYxnOui0,4007 +tqdm/contrib/telegram.py,sha256=vn_9SATMbbwn2PAbzSDyOX6av3eBB01QBug11P4H-Og,5008 +tqdm/contrib/utils_worker.py,sha256=HJP5Mz1S1xyzEke2JaqJ2sYLHXADYoo2epT5AzQ38eA,1207 +tqdm/dask.py,sha256=9Ei58eVqTossRLhAfWyUFCduXYKjmLmwkaXIy-CHYfs,1319 +tqdm/gui.py,sha256=STIB3K8iDzDgkNUqWIpvcI_u0OGtbGNy5NwpALXhfWs,5479 +tqdm/keras.py,sha256=op9sBkb6q6c6dw2wJ0SD2ZwpPK7yM1Vbg4l1Qiy3MIo,4373 +tqdm/notebook.py,sha256=GtZ3IapLL1v8WNDaTSvPw0bJGTyfp71Vfz5HDnAzx1M,10895 +tqdm/rich.py,sha256=YyMPkEHVyYUVUR3adJKbVX26iTmNKpNMf3DEqmm-m60,5021 +tqdm/std.py,sha256=tWjz6-QCa92aqYjz7PIdkLUCAfiy-lJZheBtZyIIyO0,57461 +tqdm/tk.py,sha256=Gu0uwXwLCGPRGHORdi3WvBLGiseUp_xxX_h_gp9VpK0,6701 +tqdm/tqdm.1,sha256=aILyUPk2S4OPe_uWy2P4AMjUf0oQ6PUW0nLYXB-BWwI,7889 +tqdm/utils.py,sha256=6E0BQw3Sg7uGWKBM_cDn3P42tXswRhzkggbhBgLDjl8,11821 +tqdm/version.py,sha256=-1yWjfu3P0eghVsysHH07fbzdiADNRdzRtYPqOaqR2A,333 diff --git a/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/WHEEL b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/WHEEL new file mode 100644 index 00000000..ae527e7d --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (75.6.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/entry_points.txt b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/entry_points.txt new file mode 100644 index 00000000..540e60f4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +tqdm = tqdm.cli:main diff --git a/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/top_level.txt b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/top_level.txt new file mode 100644 index 00000000..78620c47 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm-4.67.1.dist-info/top_level.txt @@ -0,0 +1 @@ +tqdm diff --git a/.venv/lib/python3.12/site-packages/tqdm/__init__.py b/.venv/lib/python3.12/site-packages/tqdm/__init__.py new file mode 100644 index 00000000..8081f77b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/__init__.py @@ -0,0 +1,38 @@ +from ._monitor import TMonitor, TqdmSynchronisationWarning +from ._tqdm_pandas import tqdm_pandas +from .cli import main # TODO: remove in v5.0.0 +from .gui import tqdm as tqdm_gui # TODO: remove in v5.0.0 +from .gui import trange as tgrange # TODO: remove in v5.0.0 +from .std import ( + TqdmDeprecationWarning, TqdmExperimentalWarning, TqdmKeyError, TqdmMonitorWarning, + TqdmTypeError, TqdmWarning, tqdm, trange) +from .version import __version__ + +__all__ = ['tqdm', 'tqdm_gui', 'trange', 'tgrange', 'tqdm_pandas', + 'tqdm_notebook', 'tnrange', 'main', 'TMonitor', + 'TqdmTypeError', 'TqdmKeyError', + 'TqdmWarning', 'TqdmDeprecationWarning', + 'TqdmExperimentalWarning', + 'TqdmMonitorWarning', 'TqdmSynchronisationWarning', + '__version__'] + + +def tqdm_notebook(*args, **kwargs): # pragma: no cover + """See tqdm.notebook.tqdm for full documentation""" + from warnings import warn + + from .notebook import tqdm as _tqdm_notebook + warn("This function will be removed in tqdm==5.0.0\n" + "Please use `tqdm.notebook.tqdm` instead of `tqdm.tqdm_notebook`", + TqdmDeprecationWarning, stacklevel=2) + return _tqdm_notebook(*args, **kwargs) + + +def tnrange(*args, **kwargs): # pragma: no cover + """Shortcut for `tqdm.notebook.tqdm(range(*args), **kwargs)`.""" + from warnings import warn + + from .notebook import trange as _tnrange + warn("Please use `tqdm.notebook.trange` instead of `tqdm.tnrange`", + TqdmDeprecationWarning, stacklevel=2) + return _tnrange(*args, **kwargs) diff --git a/.venv/lib/python3.12/site-packages/tqdm/__main__.py b/.venv/lib/python3.12/site-packages/tqdm/__main__.py new file mode 100644 index 00000000..4e28416e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..2e77ff67 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/__main__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/__main__.cpython-312.pyc new file mode 100644 index 00000000..b60f4a08 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/__main__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_dist_ver.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_dist_ver.cpython-312.pyc new file mode 100644 index 00000000..b0f3b981 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_dist_ver.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_main.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_main.cpython-312.pyc new file mode 100644 index 00000000..8ba7ad6d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_main.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_monitor.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_monitor.cpython-312.pyc new file mode 100644 index 00000000..070fddd6 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_monitor.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm.cpython-312.pyc new file mode 100644 index 00000000..5225ff2a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_gui.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_gui.cpython-312.pyc new file mode 100644 index 00000000..e29b02a4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_gui.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_notebook.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_notebook.cpython-312.pyc new file mode 100644 index 00000000..0dab1c1a Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_notebook.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_pandas.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_pandas.cpython-312.pyc new file mode 100644 index 00000000..0c32e693 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_tqdm_pandas.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_utils.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_utils.cpython-312.pyc new file mode 100644 index 00000000..24eda16e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/_utils.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/asyncio.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/asyncio.cpython-312.pyc new file mode 100644 index 00000000..3f3a1ef8 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/asyncio.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/auto.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/auto.cpython-312.pyc new file mode 100644 index 00000000..f42cec78 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/auto.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/autonotebook.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/autonotebook.cpython-312.pyc new file mode 100644 index 00000000..a2dbf75f Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/autonotebook.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/cli.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/cli.cpython-312.pyc new file mode 100644 index 00000000..7888f5c3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/cli.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/dask.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/dask.cpython-312.pyc new file mode 100644 index 00000000..fb0c095e Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/dask.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/gui.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/gui.cpython-312.pyc new file mode 100644 index 00000000..78140ea9 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/gui.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/keras.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/keras.cpython-312.pyc new file mode 100644 index 00000000..7dfb93c7 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/keras.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/notebook.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/notebook.cpython-312.pyc new file mode 100644 index 00000000..a18eca39 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/notebook.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/rich.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/rich.cpython-312.pyc new file mode 100644 index 00000000..81c8e9fd Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/rich.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/std.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/std.cpython-312.pyc new file mode 100644 index 00000000..3f8bc7d4 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/std.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/tk.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/tk.cpython-312.pyc new file mode 100644 index 00000000..a2155552 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/tk.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/utils.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/utils.cpython-312.pyc new file mode 100644 index 00000000..5775bbe3 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/utils.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/__pycache__/version.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/version.cpython-312.pyc new file mode 100644 index 00000000..9d42a842 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/__pycache__/version.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/_dist_ver.py b/.venv/lib/python3.12/site-packages/tqdm/_dist_ver.py new file mode 100644 index 00000000..61af7d5b --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/_dist_ver.py @@ -0,0 +1 @@ +__version__ = '4.67.1' diff --git a/.venv/lib/python3.12/site-packages/tqdm/_main.py b/.venv/lib/python3.12/site-packages/tqdm/_main.py new file mode 100644 index 00000000..04fdeeff --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/_main.py @@ -0,0 +1,9 @@ +from warnings import warn + +from .cli import * # NOQA +from .cli import __all__ # NOQA +from .std import TqdmDeprecationWarning + +warn("This function will be removed in tqdm==5.0.0\n" + "Please use `tqdm.cli.*` instead of `tqdm._main.*`", + TqdmDeprecationWarning, stacklevel=2) diff --git a/.venv/lib/python3.12/site-packages/tqdm/_monitor.py b/.venv/lib/python3.12/site-packages/tqdm/_monitor.py new file mode 100644 index 00000000..f71aa568 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/_monitor.py @@ -0,0 +1,95 @@ +import atexit +from threading import Event, Thread, current_thread +from time import time +from warnings import warn + +__all__ = ["TMonitor", "TqdmSynchronisationWarning"] + + +class TqdmSynchronisationWarning(RuntimeWarning): + """tqdm multi-thread/-process errors which may cause incorrect nesting + but otherwise no adverse effects""" + pass + + +class TMonitor(Thread): + """ + Monitoring thread for tqdm bars. + Monitors if tqdm bars are taking too much time to display + and readjusts miniters automatically if necessary. + + Parameters + ---------- + tqdm_cls : class + tqdm class to use (can be core tqdm or a submodule). + sleep_interval : float + Time to sleep between monitoring checks. + """ + _test = {} # internal vars for unit testing + + def __init__(self, tqdm_cls, sleep_interval): + Thread.__init__(self) + self.daemon = True # kill thread when main killed (KeyboardInterrupt) + self.woken = 0 # last time woken up, to sync with monitor + self.tqdm_cls = tqdm_cls + self.sleep_interval = sleep_interval + self._time = self._test.get("time", time) + self.was_killed = self._test.get("Event", Event)() + atexit.register(self.exit) + self.start() + + def exit(self): + self.was_killed.set() + if self is not current_thread(): + self.join() + return self.report() + + def get_instances(self): + # returns a copy of started `tqdm_cls` instances + return [i for i in self.tqdm_cls._instances.copy() + # Avoid race by checking that the instance started + if hasattr(i, 'start_t')] + + def run(self): + cur_t = self._time() + while True: + # After processing and before sleeping, notify that we woke + # Need to be done just before sleeping + self.woken = cur_t + # Sleep some time... + self.was_killed.wait(self.sleep_interval) + # Quit if killed + if self.was_killed.is_set(): + return + # Then monitor! + # Acquire lock (to access _instances) + with self.tqdm_cls.get_lock(): + cur_t = self._time() + # Check tqdm instances are waiting too long to print + instances = self.get_instances() + for instance in instances: + # Check event in loop to reduce blocking time on exit + if self.was_killed.is_set(): + return + # Only if mininterval > 1 (else iterations are just slow) + # and last refresh exceeded maxinterval + if ( + instance.miniters > 1 + and (cur_t - instance.last_print_t) >= instance.maxinterval + ): + # force bypassing miniters on next iteration + # (dynamic_miniters adjusts mininterval automatically) + instance.miniters = 1 + # Refresh now! (works only for manual tqdm) + instance.refresh(nolock=True) + # Remove accidental long-lived strong reference + del instance + if instances != self.get_instances(): # pragma: nocover + warn("Set changed size during iteration" + + " (see https://github.com/tqdm/tqdm/issues/481)", + TqdmSynchronisationWarning, stacklevel=2) + # Remove accidental long-lived strong references + del instances + + def report(self): + return not self.was_killed.is_set() diff --git a/.venv/lib/python3.12/site-packages/tqdm/_tqdm.py b/.venv/lib/python3.12/site-packages/tqdm/_tqdm.py new file mode 100644 index 00000000..7fc49627 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/_tqdm.py @@ -0,0 +1,9 @@ +from warnings import warn + +from .std import * # NOQA +from .std import __all__ # NOQA +from .std import TqdmDeprecationWarning + +warn("This function will be removed in tqdm==5.0.0\n" + "Please use `tqdm.std.*` instead of `tqdm._tqdm.*`", + TqdmDeprecationWarning, stacklevel=2) diff --git a/.venv/lib/python3.12/site-packages/tqdm/_tqdm_gui.py b/.venv/lib/python3.12/site-packages/tqdm/_tqdm_gui.py new file mode 100644 index 00000000..f32aa894 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/_tqdm_gui.py @@ -0,0 +1,9 @@ +from warnings import warn + +from .gui import * # NOQA +from .gui import __all__ # NOQA +from .std import TqdmDeprecationWarning + +warn("This function will be removed in tqdm==5.0.0\n" + "Please use `tqdm.gui.*` instead of `tqdm._tqdm_gui.*`", + TqdmDeprecationWarning, stacklevel=2) diff --git a/.venv/lib/python3.12/site-packages/tqdm/_tqdm_notebook.py b/.venv/lib/python3.12/site-packages/tqdm/_tqdm_notebook.py new file mode 100644 index 00000000..f225fbf5 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/_tqdm_notebook.py @@ -0,0 +1,9 @@ +from warnings import warn + +from .notebook import * # NOQA +from .notebook import __all__ # NOQA +from .std import TqdmDeprecationWarning + +warn("This function will be removed in tqdm==5.0.0\n" + "Please use `tqdm.notebook.*` instead of `tqdm._tqdm_notebook.*`", + TqdmDeprecationWarning, stacklevel=2) diff --git a/.venv/lib/python3.12/site-packages/tqdm/_tqdm_pandas.py b/.venv/lib/python3.12/site-packages/tqdm/_tqdm_pandas.py new file mode 100644 index 00000000..c4fe6efd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/_tqdm_pandas.py @@ -0,0 +1,24 @@ +import sys + +__author__ = "github.com/casperdcl" +__all__ = ['tqdm_pandas'] + + +def tqdm_pandas(tclass, **tqdm_kwargs): + """ + Registers the given `tqdm` instance with + `pandas.core.groupby.DataFrameGroupBy.progress_apply`. + """ + from tqdm import TqdmDeprecationWarning + + if isinstance(tclass, type) or (getattr(tclass, '__name__', '').startswith( + 'tqdm_')): # delayed adapter case + TqdmDeprecationWarning( + "Please use `tqdm.pandas(...)` instead of `tqdm_pandas(tqdm, ...)`.", + fp_write=getattr(tqdm_kwargs.get('file', None), 'write', sys.stderr.write)) + tclass.pandas(**tqdm_kwargs) + else: + TqdmDeprecationWarning( + "Please use `tqdm.pandas(...)` instead of `tqdm_pandas(tqdm(...))`.", + fp_write=getattr(tclass.fp, 'write', sys.stderr.write)) + type(tclass).pandas(deprecated_t=tclass) diff --git a/.venv/lib/python3.12/site-packages/tqdm/_utils.py b/.venv/lib/python3.12/site-packages/tqdm/_utils.py new file mode 100644 index 00000000..385e849e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/_utils.py @@ -0,0 +1,11 @@ +from warnings import warn + +from .std import TqdmDeprecationWarning +from .utils import ( # NOQA, pylint: disable=unused-import + CUR_OS, IS_NIX, IS_WIN, RE_ANSI, Comparable, FormatReplace, SimpleTextIOWrapper, + _environ_cols_wrapper, _is_ascii, _is_utf, _screen_shape_linux, _screen_shape_tput, + _screen_shape_windows, _screen_shape_wrapper, _supports_unicode, _term_move_up, colorama) + +warn("This function will be removed in tqdm==5.0.0\n" + "Please use `tqdm.utils.*` instead of `tqdm._utils.*`", + TqdmDeprecationWarning, stacklevel=2) diff --git a/.venv/lib/python3.12/site-packages/tqdm/asyncio.py b/.venv/lib/python3.12/site-packages/tqdm/asyncio.py new file mode 100644 index 00000000..2d00a0a2 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/asyncio.py @@ -0,0 +1,93 @@ +""" +Asynchronous progressbar decorator for iterators. +Includes a default `range` iterator printing to `stderr`. + +Usage: +>>> from tqdm.asyncio import trange, tqdm +>>> async for i in trange(10): +... ... +""" +import asyncio +from sys import version_info + +from .std import tqdm as std_tqdm + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['tqdm_asyncio', 'tarange', 'tqdm', 'trange'] + + +class tqdm_asyncio(std_tqdm): + """ + Asynchronous-friendly version of tqdm. + """ + def __init__(self, iterable=None, *args, **kwargs): + super().__init__(iterable, *args, **kwargs) + self.iterable_awaitable = False + if iterable is not None: + if hasattr(iterable, "__anext__"): + self.iterable_next = iterable.__anext__ + self.iterable_awaitable = True + elif hasattr(iterable, "__next__"): + self.iterable_next = iterable.__next__ + else: + self.iterable_iterator = iter(iterable) + self.iterable_next = self.iterable_iterator.__next__ + + def __aiter__(self): + return self + + async def __anext__(self): + try: + if self.iterable_awaitable: + res = await self.iterable_next() + else: + res = self.iterable_next() + self.update() + return res + except StopIteration: + self.close() + raise StopAsyncIteration + except BaseException: + self.close() + raise + + def send(self, *args, **kwargs): + return self.iterable.send(*args, **kwargs) + + @classmethod + def as_completed(cls, fs, *, loop=None, timeout=None, total=None, **tqdm_kwargs): + """ + Wrapper for `asyncio.as_completed`. + """ + if total is None: + total = len(fs) + kwargs = {} + if version_info[:2] < (3, 10): + kwargs['loop'] = loop + yield from cls(asyncio.as_completed(fs, timeout=timeout, **kwargs), + total=total, **tqdm_kwargs) + + @classmethod + async def gather(cls, *fs, loop=None, timeout=None, total=None, **tqdm_kwargs): + """ + Wrapper for `asyncio.gather`. + """ + async def wrap_awaitable(i, f): + return i, await f + + ifs = [wrap_awaitable(i, f) for i, f in enumerate(fs)] + res = [await f for f in cls.as_completed(ifs, loop=loop, timeout=timeout, + total=total, **tqdm_kwargs)] + return [i for _, i in sorted(res)] + + +def tarange(*args, **kwargs): + """ + A shortcut for `tqdm.asyncio.tqdm(range(*args), **kwargs)`. + """ + return tqdm_asyncio(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_asyncio +trange = tarange diff --git a/.venv/lib/python3.12/site-packages/tqdm/auto.py b/.venv/lib/python3.12/site-packages/tqdm/auto.py new file mode 100644 index 00000000..206c4409 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/auto.py @@ -0,0 +1,40 @@ +""" +Enables multiple commonly used features. + +Method resolution order: + +- `tqdm.autonotebook` without import warnings +- `tqdm.asyncio` +- `tqdm.std` base class + +Usage: +>>> from tqdm.auto import trange, tqdm +>>> for i in trange(10): +... ... +""" +import warnings + +from .std import TqdmExperimentalWarning + +with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=TqdmExperimentalWarning) + from .autonotebook import tqdm as notebook_tqdm + +from .asyncio import tqdm as asyncio_tqdm +from .std import tqdm as std_tqdm + +if notebook_tqdm != std_tqdm: + class tqdm(notebook_tqdm, asyncio_tqdm): # pylint: disable=inconsistent-mro + pass +else: + tqdm = asyncio_tqdm + + +def trange(*args, **kwargs): + """ + A shortcut for `tqdm.auto.tqdm(range(*args), **kwargs)`. + """ + return tqdm(range(*args), **kwargs) + + +__all__ = ["tqdm", "trange"] diff --git a/.venv/lib/python3.12/site-packages/tqdm/autonotebook.py b/.venv/lib/python3.12/site-packages/tqdm/autonotebook.py new file mode 100644 index 00000000..a09f2ec4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/autonotebook.py @@ -0,0 +1,29 @@ +""" +Automatically choose between `tqdm.notebook` and `tqdm.std`. + +Usage: +>>> from tqdm.autonotebook import trange, tqdm +>>> for i in trange(10): +... ... +""" +import sys +from warnings import warn + +try: + get_ipython = sys.modules['IPython'].get_ipython + if 'IPKernelApp' not in get_ipython().config: # pragma: no cover + raise ImportError("console") + from .notebook import WARN_NOIPYW, IProgress + if IProgress is None: + from .std import TqdmWarning + warn(WARN_NOIPYW, TqdmWarning, stacklevel=2) + raise ImportError('ipywidgets') +except Exception: + from .std import tqdm, trange +else: # pragma: no cover + from .notebook import tqdm, trange + from .std import TqdmExperimentalWarning + warn("Using `tqdm.autonotebook.tqdm` in notebook mode." + " Use `tqdm.tqdm` instead to force console mode" + " (e.g. in jupyter console)", TqdmExperimentalWarning, stacklevel=2) +__all__ = ["tqdm", "trange"] diff --git a/.venv/lib/python3.12/site-packages/tqdm/cli.py b/.venv/lib/python3.12/site-packages/tqdm/cli.py new file mode 100644 index 00000000..e54a7fc8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/cli.py @@ -0,0 +1,324 @@ +""" +Module version for monitoring CLI pipes (`... | python -m tqdm | ...`). +""" +import logging +import re +import sys +from ast import literal_eval as numeric +from textwrap import indent + +from .std import TqdmKeyError, TqdmTypeError, tqdm +from .version import __version__ + +__all__ = ["main"] +log = logging.getLogger(__name__) + + +def cast(val, typ): + log.debug((val, typ)) + if " or " in typ: + for t in typ.split(" or "): + try: + return cast(val, t) + except TqdmTypeError: + pass + raise TqdmTypeError(f"{val} : {typ}") + + # sys.stderr.write('\ndebug | `val:type`: `' + val + ':' + typ + '`.\n') + if typ == 'bool': + if (val == 'True') or (val == ''): + return True + if val == 'False': + return False + raise TqdmTypeError(val + ' : ' + typ) + if typ == 'chr': + if len(val) == 1: + return val.encode() + if re.match(r"^\\\w+$", val): + return eval(f'"{val}"').encode() + raise TqdmTypeError(f"{val} : {typ}") + if typ == 'str': + return val + if typ == 'int': + try: + return int(val) + except ValueError as exc: + raise TqdmTypeError(f"{val} : {typ}") from exc + if typ == 'float': + try: + return float(val) + except ValueError as exc: + raise TqdmTypeError(f"{val} : {typ}") from exc + raise TqdmTypeError(f"{val} : {typ}") + + +def posix_pipe(fin, fout, delim=b'\\n', buf_size=256, + callback=lambda float: None, callback_len=True): + """ + Params + ------ + fin : binary file with `read(buf_size : int)` method + fout : binary file with `write` (and optionally `flush`) methods. + callback : function(float), e.g.: `tqdm.update` + callback_len : If (default: True) do `callback(len(buffer))`. + Otherwise, do `callback(data) for data in buffer.split(delim)`. + """ + fp_write = fout.write + + if not delim: + while True: + tmp = fin.read(buf_size) + + # flush at EOF + if not tmp: + getattr(fout, 'flush', lambda: None)() + return + + fp_write(tmp) + callback(len(tmp)) + # return + + buf = b'' + len_delim = len(delim) + # n = 0 + while True: + tmp = fin.read(buf_size) + + # flush at EOF + if not tmp: + if buf: + fp_write(buf) + if callback_len: + # n += 1 + buf.count(delim) + callback(1 + buf.count(delim)) + else: + for i in buf.split(delim): + callback(i) + getattr(fout, 'flush', lambda: None)() + return # n + + while True: + i = tmp.find(delim) + if i < 0: + buf += tmp + break + fp_write(buf + tmp[:i + len(delim)]) + # n += 1 + callback(1 if callback_len else (buf + tmp[:i])) + buf = b'' + tmp = tmp[i + len_delim:] + + +# ((opt, type), ... ) +RE_OPTS = re.compile(r'\n {4}(\S+)\s{2,}:\s*([^,]+)') +# better split method assuming no positional args +RE_SHLEX = re.compile(r'\s*(?<!\S)--?([^\s=]+)(\s+|=|$)') + +# TODO: add custom support for some of the following? +UNSUPPORTED_OPTS = ('iterable', 'gui', 'out', 'file') + +# The 8 leading spaces are required for consistency +CLI_EXTRA_DOC = r""" + Extra CLI Options + ----------------- + name : type, optional + TODO: find out why this is needed. + delim : chr, optional + Delimiting character [default: '\n']. Use '\0' for null. + N.B.: on Windows systems, Python converts '\n' to '\r\n'. + buf_size : int, optional + String buffer size in bytes [default: 256] + used when `delim` is specified. + bytes : bool, optional + If true, will count bytes, ignore `delim`, and default + `unit_scale` to True, `unit_divisor` to 1024, and `unit` to 'B'. + tee : bool, optional + If true, passes `stdin` to both `stderr` and `stdout`. + update : bool, optional + If true, will treat input as newly elapsed iterations, + i.e. numbers to pass to `update()`. Note that this is slow + (~2e5 it/s) since every input must be decoded as a number. + update_to : bool, optional + If true, will treat input as total elapsed iterations, + i.e. numbers to assign to `self.n`. Note that this is slow + (~2e5 it/s) since every input must be decoded as a number. + null : bool, optional + If true, will discard input (no stdout). + manpath : str, optional + Directory in which to install tqdm man pages. + comppath : str, optional + Directory in which to place tqdm completion. + log : str, optional + CRITICAL|FATAL|ERROR|WARN(ING)|[default: 'INFO']|DEBUG|NOTSET. +""" + + +def main(fp=sys.stderr, argv=None): + """ + Parameters (internal use only) + --------- + fp : file-like object for tqdm + argv : list (default: sys.argv[1:]) + """ + if argv is None: + argv = sys.argv[1:] + try: + log_idx = argv.index('--log') + except ValueError: + for i in argv: + if i.startswith('--log='): + logLevel = i[len('--log='):] + break + else: + logLevel = 'INFO' + else: + # argv.pop(log_idx) + # logLevel = argv.pop(log_idx) + logLevel = argv[log_idx + 1] + logging.basicConfig(level=getattr(logging, logLevel), + format="%(levelname)s:%(module)s:%(lineno)d:%(message)s") + + # py<3.13 doesn't dedent docstrings + d = (tqdm.__doc__ if sys.version_info < (3, 13) + else indent(tqdm.__doc__, " ")) + CLI_EXTRA_DOC + + opt_types = dict(RE_OPTS.findall(d)) + # opt_types['delim'] = 'chr' + + for o in UNSUPPORTED_OPTS: + opt_types.pop(o) + + log.debug(sorted(opt_types.items())) + + # d = RE_OPTS.sub(r' --\1=<\1> : \2', d) + split = RE_OPTS.split(d) + opt_types_desc = zip(split[1::3], split[2::3], split[3::3]) + d = ''.join(('\n --{0} : {2}{3}' if otd[1] == 'bool' else + '\n --{0}=<{1}> : {2}{3}').format( + otd[0].replace('_', '-'), otd[0], *otd[1:]) + for otd in opt_types_desc if otd[0] not in UNSUPPORTED_OPTS) + + help_short = "Usage:\n tqdm [--help | options]\n" + d = help_short + """ +Options: + -h, --help Print this help and exit. + -v, --version Print version and exit. +""" + d.strip('\n') + '\n' + + # opts = docopt(d, version=__version__) + if any(v in argv for v in ('-v', '--version')): + sys.stdout.write(__version__ + '\n') + sys.exit(0) + elif any(v in argv for v in ('-h', '--help')): + sys.stdout.write(d + '\n') + sys.exit(0) + elif argv and argv[0][:2] != '--': + sys.stderr.write(f"Error:Unknown argument:{argv[0]}\n{help_short}") + + argv = RE_SHLEX.split(' '.join(["tqdm"] + argv)) + opts = dict(zip(argv[1::3], argv[3::3])) + + log.debug(opts) + opts.pop('log', True) + + tqdm_args = {'file': fp} + try: + for (o, v) in opts.items(): + o = o.replace('-', '_') + try: + tqdm_args[o] = cast(v, opt_types[o]) + except KeyError as e: + raise TqdmKeyError(str(e)) + log.debug('args:' + str(tqdm_args)) + + delim_per_char = tqdm_args.pop('bytes', False) + update = tqdm_args.pop('update', False) + update_to = tqdm_args.pop('update_to', False) + if sum((delim_per_char, update, update_to)) > 1: + raise TqdmKeyError("Can only have one of --bytes --update --update_to") + except Exception: + fp.write("\nError:\n" + help_short) + stdin, stdout_write = sys.stdin, sys.stdout.write + for i in stdin: + stdout_write(i) + raise + else: + buf_size = tqdm_args.pop('buf_size', 256) + delim = tqdm_args.pop('delim', b'\\n') + tee = tqdm_args.pop('tee', False) + manpath = tqdm_args.pop('manpath', None) + comppath = tqdm_args.pop('comppath', None) + if tqdm_args.pop('null', False): + class stdout(object): + @staticmethod + def write(_): + pass + else: + stdout = sys.stdout + stdout = getattr(stdout, 'buffer', stdout) + stdin = getattr(sys.stdin, 'buffer', sys.stdin) + if manpath or comppath: + try: # py<3.9 + import importlib_resources as resources + except ImportError: + from importlib import resources + from pathlib import Path + + def cp(name, dst): + """copy resource `name` to `dst`""" + fi = resources.files('tqdm') / name + dst.write_bytes(fi.read_bytes()) + log.info("written:%s", dst) + if manpath is not None: + cp('tqdm.1', Path(manpath) / 'tqdm.1') + if comppath is not None: + cp('completion.sh', Path(comppath) / 'tqdm_completion.sh') + sys.exit(0) + if tee: + stdout_write = stdout.write + fp_write = getattr(fp, 'buffer', fp).write + + class stdout(object): # pylint: disable=function-redefined + @staticmethod + def write(x): + with tqdm.external_write_mode(file=fp): + fp_write(x) + stdout_write(x) + if delim_per_char: + tqdm_args.setdefault('unit', 'B') + tqdm_args.setdefault('unit_scale', True) + tqdm_args.setdefault('unit_divisor', 1024) + log.debug(tqdm_args) + with tqdm(**tqdm_args) as t: + posix_pipe(stdin, stdout, '', buf_size, t.update) + elif delim == b'\\n': + log.debug(tqdm_args) + write = stdout.write + if update or update_to: + with tqdm(**tqdm_args) as t: + if update: + def callback(i): + t.update(numeric(i.decode())) + else: # update_to + def callback(i): + t.update(numeric(i.decode()) - t.n) + for i in stdin: + write(i) + callback(i) + else: + for i in tqdm(stdin, **tqdm_args): + write(i) + else: + log.debug(tqdm_args) + with tqdm(**tqdm_args) as t: + callback_len = False + if update: + def callback(i): + t.update(numeric(i.decode())) + elif update_to: + def callback(i): + t.update(numeric(i.decode()) - t.n) + else: + callback = t.update + callback_len = True + posix_pipe(stdin, stdout, delim, buf_size, callback, callback_len) diff --git a/.venv/lib/python3.12/site-packages/tqdm/completion.sh b/.venv/lib/python3.12/site-packages/tqdm/completion.sh new file mode 100755 index 00000000..9f61c7f1 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/completion.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +_tqdm(){ + local cur prv + cur="${COMP_WORDS[COMP_CWORD]}" + prv="${COMP_WORDS[COMP_CWORD - 1]}" + + case ${prv} in + --bar_format|--buf_size|--colour|--comppath|--delay|--delim|--desc|--initial|--lock_args|--manpath|--maxinterval|--mininterval|--miniters|--ncols|--nrows|--position|--postfix|--smoothing|--total|--unit|--unit_divisor) + # await user input + ;; + "--log") + COMPREPLY=($(compgen -W 'CRITICAL FATAL ERROR WARN WARNING INFO DEBUG NOTSET' -- ${cur})) + ;; + *) + COMPREPLY=($(compgen -W '--ascii --bar_format --buf_size --bytes --colour --comppath --delay --delim --desc --disable --dynamic_ncols --help --initial --leave --lock_args --log --manpath --maxinterval --mininterval --miniters --ncols --nrows --null --position --postfix --smoothing --tee --total --unit --unit_divisor --unit_scale --update --update_to --version --write_bytes -h -v' -- ${cur})) + ;; + esac +} +complete -F _tqdm tqdm diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__init__.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/__init__.py new file mode 100644 index 00000000..d059461f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/__init__.py @@ -0,0 +1,92 @@ +""" +Thin wrappers around common functions. + +Subpackages contain potentially unstable extensions. +""" +from warnings import warn + +from ..auto import tqdm as tqdm_auto +from ..std import TqdmDeprecationWarning, tqdm +from ..utils import ObjectWrapper + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['tenumerate', 'tzip', 'tmap'] + + +class DummyTqdmFile(ObjectWrapper): + """Dummy file-like that will write to tqdm""" + + def __init__(self, wrapped): + super().__init__(wrapped) + self._buf = [] + + def write(self, x, nolock=False): + nl = b"\n" if isinstance(x, bytes) else "\n" + pre, sep, post = x.rpartition(nl) + if sep: + blank = type(nl)() + tqdm.write(blank.join(self._buf + [pre, sep]), + end=blank, file=self._wrapped, nolock=nolock) + self._buf = [post] + else: + self._buf.append(x) + + def __del__(self): + if self._buf: + blank = type(self._buf[0])() + try: + tqdm.write(blank.join(self._buf), end=blank, file=self._wrapped) + except (OSError, ValueError): + pass + + +def builtin_iterable(func): + """Returns `func`""" + warn("This function has no effect, and will be removed in tqdm==5.0.0", + TqdmDeprecationWarning, stacklevel=2) + return func + + +def tenumerate(iterable, start=0, total=None, tqdm_class=tqdm_auto, **tqdm_kwargs): + """ + Equivalent of `numpy.ndenumerate` or builtin `enumerate`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + """ + try: + import numpy as np + except ImportError: + pass + else: + if isinstance(iterable, np.ndarray): + return tqdm_class(np.ndenumerate(iterable), total=total or iterable.size, + **tqdm_kwargs) + return enumerate(tqdm_class(iterable, total=total, **tqdm_kwargs), start) + + +def tzip(iter1, *iter2plus, **tqdm_kwargs): + """ + Equivalent of builtin `zip`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + """ + kwargs = tqdm_kwargs.copy() + tqdm_class = kwargs.pop("tqdm_class", tqdm_auto) + for i in zip(tqdm_class(iter1, **kwargs), *iter2plus): + yield i + + +def tmap(function, *sequences, **tqdm_kwargs): + """ + Equivalent of builtin `map`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + """ + for i in tzip(*sequences, **tqdm_kwargs): + yield function(*i) diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/__init__.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..9ae4b580 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/__init__.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/bells.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/bells.cpython-312.pyc new file mode 100644 index 00000000..7b3ade96 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/bells.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/concurrent.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/concurrent.cpython-312.pyc new file mode 100644 index 00000000..18634a04 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/concurrent.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/discord.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/discord.cpython-312.pyc new file mode 100644 index 00000000..a4329c37 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/discord.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/itertools.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/itertools.cpython-312.pyc new file mode 100644 index 00000000..e23d122b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/itertools.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/logging.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/logging.cpython-312.pyc new file mode 100644 index 00000000..22418a28 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/logging.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/slack.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/slack.cpython-312.pyc new file mode 100644 index 00000000..68925a6d Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/slack.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/telegram.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/telegram.cpython-312.pyc new file mode 100644 index 00000000..1fca004b Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/telegram.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/utils_worker.cpython-312.pyc b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/utils_worker.cpython-312.pyc new file mode 100644 index 00000000..edc12d24 Binary files /dev/null and b/.venv/lib/python3.12/site-packages/tqdm/contrib/__pycache__/utils_worker.cpython-312.pyc differ diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/bells.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/bells.py new file mode 100644 index 00000000..5b8f4b9e --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/bells.py @@ -0,0 +1,26 @@ +""" +Even more features than `tqdm.auto` (all the bells & whistles): + +- `tqdm.auto` +- `tqdm.tqdm.pandas` +- `tqdm.contrib.telegram` + + uses `${TQDM_TELEGRAM_TOKEN}` and `${TQDM_TELEGRAM_CHAT_ID}` +- `tqdm.contrib.discord` + + uses `${TQDM_DISCORD_TOKEN}` and `${TQDM_DISCORD_CHANNEL_ID}` +""" +__all__ = ['tqdm', 'trange'] +import warnings +from os import getenv + +if getenv("TQDM_SLACK_TOKEN") and getenv("TQDM_SLACK_CHANNEL"): + from .slack import tqdm, trange +elif getenv("TQDM_TELEGRAM_TOKEN") and getenv("TQDM_TELEGRAM_CHAT_ID"): + from .telegram import tqdm, trange +elif getenv("TQDM_DISCORD_TOKEN") and getenv("TQDM_DISCORD_CHANNEL_ID"): + from .discord import tqdm, trange +else: + from ..auto import tqdm, trange + +with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=FutureWarning) + tqdm.pandas() diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/concurrent.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/concurrent.py new file mode 100644 index 00000000..cd81d622 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/concurrent.py @@ -0,0 +1,105 @@ +""" +Thin wrappers around `concurrent.futures`. +""" +from contextlib import contextmanager +from operator import length_hint +from os import cpu_count + +from ..auto import tqdm as tqdm_auto +from ..std import TqdmWarning + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['thread_map', 'process_map'] + + +@contextmanager +def ensure_lock(tqdm_class, lock_name=""): + """get (create if necessary) and then restore `tqdm_class`'s lock""" + old_lock = getattr(tqdm_class, '_lock', None) # don't create a new lock + lock = old_lock or tqdm_class.get_lock() # maybe create a new lock + lock = getattr(lock, lock_name, lock) # maybe subtype + tqdm_class.set_lock(lock) + yield lock + if old_lock is None: + del tqdm_class._lock + else: + tqdm_class.set_lock(old_lock) + + +def _executor_map(PoolExecutor, fn, *iterables, **tqdm_kwargs): + """ + Implementation of `thread_map` and `process_map`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + max_workers : [default: min(32, cpu_count() + 4)]. + chunksize : [default: 1]. + lock_name : [default: "":str]. + """ + kwargs = tqdm_kwargs.copy() + if "total" not in kwargs: + kwargs["total"] = length_hint(iterables[0]) + tqdm_class = kwargs.pop("tqdm_class", tqdm_auto) + max_workers = kwargs.pop("max_workers", min(32, cpu_count() + 4)) + chunksize = kwargs.pop("chunksize", 1) + lock_name = kwargs.pop("lock_name", "") + with ensure_lock(tqdm_class, lock_name=lock_name) as lk: + # share lock in case workers are already using `tqdm` + with PoolExecutor(max_workers=max_workers, initializer=tqdm_class.set_lock, + initargs=(lk,)) as ex: + return list(tqdm_class(ex.map(fn, *iterables, chunksize=chunksize), **kwargs)) + + +def thread_map(fn, *iterables, **tqdm_kwargs): + """ + Equivalent of `list(map(fn, *iterables))` + driven by `concurrent.futures.ThreadPoolExecutor`. + + Parameters + ---------- + tqdm_class : optional + `tqdm` class to use for bars [default: tqdm.auto.tqdm]. + max_workers : int, optional + Maximum number of workers to spawn; passed to + `concurrent.futures.ThreadPoolExecutor.__init__`. + [default: max(32, cpu_count() + 4)]. + """ + from concurrent.futures import ThreadPoolExecutor + return _executor_map(ThreadPoolExecutor, fn, *iterables, **tqdm_kwargs) + + +def process_map(fn, *iterables, **tqdm_kwargs): + """ + Equivalent of `list(map(fn, *iterables))` + driven by `concurrent.futures.ProcessPoolExecutor`. + + Parameters + ---------- + tqdm_class : optional + `tqdm` class to use for bars [default: tqdm.auto.tqdm]. + max_workers : int, optional + Maximum number of workers to spawn; passed to + `concurrent.futures.ProcessPoolExecutor.__init__`. + [default: min(32, cpu_count() + 4)]. + chunksize : int, optional + Size of chunks sent to worker processes; passed to + `concurrent.futures.ProcessPoolExecutor.map`. [default: 1]. + lock_name : str, optional + Member of `tqdm_class.get_lock()` to use [default: mp_lock]. + """ + from concurrent.futures import ProcessPoolExecutor + if iterables and "chunksize" not in tqdm_kwargs: + # default `chunksize=1` has poor performance for large iterables + # (most time spent dispatching items to workers). + longest_iterable_len = max(map(length_hint, iterables)) + if longest_iterable_len > 1000: + from warnings import warn + warn("Iterable length %d > 1000 but `chunksize` is not set." + " This may seriously degrade multiprocess performance." + " Set `chunksize=1` or more." % longest_iterable_len, + TqdmWarning, stacklevel=2) + if "lock_name" not in tqdm_kwargs: + tqdm_kwargs = tqdm_kwargs.copy() + tqdm_kwargs["lock_name"] = "mp_lock" + return _executor_map(ProcessPoolExecutor, fn, *iterables, **tqdm_kwargs) diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/discord.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/discord.py new file mode 100644 index 00000000..574baa84 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/discord.py @@ -0,0 +1,156 @@ +""" +Sends updates to a Discord bot. + +Usage: +>>> from tqdm.contrib.discord import tqdm, trange +>>> for i in trange(10, token='{token}', channel_id='{channel_id}'): +... ... + +![screenshot](https://tqdm.github.io/img/screenshot-discord.png) +""" +from os import getenv +from warnings import warn + +from requests import Session +from requests.utils import default_user_agent + +from ..auto import tqdm as tqdm_auto +from ..std import TqdmWarning +from ..version import __version__ +from .utils_worker import MonoWorker + +__author__ = {"github.com/": ["casperdcl", "guigoruiz1"]} +__all__ = ['DiscordIO', 'tqdm_discord', 'tdrange', 'tqdm', 'trange'] + + +class DiscordIO(MonoWorker): + """Non-blocking file-like IO using a Discord Bot.""" + API = "https://discord.com/api/v10" + UA = f"tqdm (https://tqdm.github.io, {__version__}) {default_user_agent()}" + + def __init__(self, token, channel_id): + """Creates a new message in the given `channel_id`.""" + super().__init__() + self.token = token + self.channel_id = channel_id + self.session = Session() + self.text = self.__class__.__name__ + self.message_id + + @property + def message_id(self): + if hasattr(self, '_message_id'): + return self._message_id + try: + res = self.session.post( + f'{self.API}/channels/{self.channel_id}/messages', + headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA}, + json={'content': f"`{self.text}`"}).json() + except Exception as e: + tqdm_auto.write(str(e)) + else: + if res.get('error_code') == 429: + warn("Creation rate limit: try increasing `mininterval`.", + TqdmWarning, stacklevel=2) + else: + self._message_id = res['id'] + return self._message_id + + def write(self, s): + """Replaces internal `message_id`'s text with `s`.""" + if not s: + s = "..." + s = s.replace('\r', '').strip() + if s == self.text: + return # avoid duplicate message Bot error + message_id = self.message_id + if message_id is None: + return + self.text = s + try: + future = self.submit( + self.session.patch, + f'{self.API}/channels/{self.channel_id}/messages/{message_id}', + headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA}, + json={'content': f"`{self.text}`"}) + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + def delete(self): + """Deletes internal `message_id`.""" + try: + future = self.submit( + self.session.delete, + f'{self.API}/channels/{self.channel_id}/messages/{self.message_id}', + headers={'Authorization': f'Bot {self.token}', 'User-Agent': self.UA}) + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + +class tqdm_discord(tqdm_auto): + """ + Standard `tqdm.auto.tqdm` but also sends updates to a Discord Bot. + May take a few seconds to create (`__init__`). + + - create a discord bot (not public, no requirement of OAuth2 code + grant, only send message permissions) & invite it to a channel: + <https://discordpy.readthedocs.io/en/latest/discord.html> + - copy the bot `{token}` & `{channel_id}` and paste below + + >>> from tqdm.contrib.discord import tqdm, trange + >>> for i in tqdm(iterable, token='{token}', channel_id='{channel_id}'): + ... ... + """ + def __init__(self, *args, **kwargs): + """ + Parameters + ---------- + token : str, required. Discord bot token + [default: ${TQDM_DISCORD_TOKEN}]. + channel_id : int, required. Discord channel ID + [default: ${TQDM_DISCORD_CHANNEL_ID}]. + + See `tqdm.auto.tqdm.__init__` for other parameters. + """ + if not kwargs.get('disable'): + kwargs = kwargs.copy() + self.dio = DiscordIO( + kwargs.pop('token', getenv('TQDM_DISCORD_TOKEN')), + kwargs.pop('channel_id', getenv('TQDM_DISCORD_CHANNEL_ID'))) + super().__init__(*args, **kwargs) + + def display(self, **kwargs): + super().display(**kwargs) + fmt = self.format_dict + if fmt.get('bar_format', None): + fmt['bar_format'] = fmt['bar_format'].replace( + '<bar/>', '{bar:10u}').replace('{bar}', '{bar:10u}') + else: + fmt['bar_format'] = '{l_bar}{bar:10u}{r_bar}' + self.dio.write(self.format_meter(**fmt)) + + def clear(self, *args, **kwargs): + super().clear(*args, **kwargs) + if not self.disable: + self.dio.write("") + + def close(self): + if self.disable: + return + super().close() + if not (self.leave or (self.leave is None and self.pos == 0)): + self.dio.delete() + + +def tdrange(*args, **kwargs): + """Shortcut for `tqdm.contrib.discord.tqdm(range(*args), **kwargs)`.""" + return tqdm_discord(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_discord +trange = tdrange diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/itertools.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/itertools.py new file mode 100644 index 00000000..e67651a4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/itertools.py @@ -0,0 +1,35 @@ +""" +Thin wrappers around `itertools`. +""" +import itertools + +from ..auto import tqdm as tqdm_auto + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['product'] + + +def product(*iterables, **tqdm_kwargs): + """ + Equivalent of `itertools.product`. + + Parameters + ---------- + tqdm_class : [default: tqdm.auto.tqdm]. + """ + kwargs = tqdm_kwargs.copy() + tqdm_class = kwargs.pop("tqdm_class", tqdm_auto) + try: + lens = list(map(len, iterables)) + except TypeError: + total = None + else: + total = 1 + for i in lens: + total *= i + kwargs.setdefault("total", total) + with tqdm_class(**kwargs) as t: + it = itertools.product(*iterables) + for i in it: + yield i + t.update() diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/logging.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/logging.py new file mode 100644 index 00000000..e06febe3 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/logging.py @@ -0,0 +1,126 @@ +""" +Helper functionality for interoperability with stdlib `logging`. +""" +import logging +import sys +from contextlib import contextmanager + +try: + from typing import Iterator, List, Optional, Type # noqa: F401 +except ImportError: + pass + +from ..std import tqdm as std_tqdm + + +class _TqdmLoggingHandler(logging.StreamHandler): + def __init__( + self, + tqdm_class=std_tqdm # type: Type[std_tqdm] + ): + super().__init__() + self.tqdm_class = tqdm_class + + def emit(self, record): + try: + msg = self.format(record) + self.tqdm_class.write(msg, file=self.stream) + self.flush() + except (KeyboardInterrupt, SystemExit): + raise + except: # noqa pylint: disable=bare-except + self.handleError(record) + + +def _is_console_logging_handler(handler): + return (isinstance(handler, logging.StreamHandler) + and handler.stream in {sys.stdout, sys.stderr}) + + +def _get_first_found_console_logging_handler(handlers): + for handler in handlers: + if _is_console_logging_handler(handler): + return handler + + +@contextmanager +def logging_redirect_tqdm( + loggers=None, # type: Optional[List[logging.Logger]], + tqdm_class=std_tqdm # type: Type[std_tqdm] +): + # type: (...) -> Iterator[None] + """ + Context manager redirecting console logging to `tqdm.write()`, leaving + other logging handlers (e.g. log files) unaffected. + + Parameters + ---------- + loggers : list, optional + Which handlers to redirect (default: [logging.root]). + tqdm_class : optional + + Example + ------- + ```python + import logging + from tqdm import trange + from tqdm.contrib.logging import logging_redirect_tqdm + + LOG = logging.getLogger(__name__) + + if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + with logging_redirect_tqdm(): + for i in trange(9): + if i == 4: + LOG.info("console logging redirected to `tqdm.write()`") + # logging restored + ``` + """ + if loggers is None: + loggers = [logging.root] + original_handlers_list = [logger.handlers for logger in loggers] + try: + for logger in loggers: + tqdm_handler = _TqdmLoggingHandler(tqdm_class) + orig_handler = _get_first_found_console_logging_handler(logger.handlers) + if orig_handler is not None: + tqdm_handler.setFormatter(orig_handler.formatter) + tqdm_handler.stream = orig_handler.stream + logger.handlers = [ + handler for handler in logger.handlers + if not _is_console_logging_handler(handler)] + [tqdm_handler] + yield + finally: + for logger, original_handlers in zip(loggers, original_handlers_list): + logger.handlers = original_handlers + + +@contextmanager +def tqdm_logging_redirect( + *args, + # loggers=None, # type: Optional[List[logging.Logger]] + # tqdm=None, # type: Optional[Type[tqdm.tqdm]] + **kwargs +): + # type: (...) -> Iterator[None] + """ + Convenience shortcut for: + ```python + with tqdm_class(*args, **tqdm_kwargs) as pbar: + with logging_redirect_tqdm(loggers=loggers, tqdm_class=tqdm_class): + yield pbar + ``` + + Parameters + ---------- + tqdm_class : optional, (default: tqdm.std.tqdm). + loggers : optional, list. + **tqdm_kwargs : passed to `tqdm_class`. + """ + tqdm_kwargs = kwargs.copy() + loggers = tqdm_kwargs.pop('loggers', None) + tqdm_class = tqdm_kwargs.pop('tqdm_class', std_tqdm) + with tqdm_class(*args, **tqdm_kwargs) as pbar: + with logging_redirect_tqdm(loggers=loggers, tqdm_class=tqdm_class): + yield pbar diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/slack.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/slack.py new file mode 100644 index 00000000..9bca8ee9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/slack.py @@ -0,0 +1,120 @@ +""" +Sends updates to a Slack app. + +Usage: +>>> from tqdm.contrib.slack import tqdm, trange +>>> for i in trange(10, token='{token}', channel='{channel}'): +... ... + +![screenshot](https://tqdm.github.io/img/screenshot-slack.png) +""" +import logging +from os import getenv + +try: + from slack_sdk import WebClient +except ImportError: + raise ImportError("Please `pip install slack-sdk`") + +from ..auto import tqdm as tqdm_auto +from .utils_worker import MonoWorker + +__author__ = {"github.com/": ["0x2b3bfa0", "casperdcl"]} +__all__ = ['SlackIO', 'tqdm_slack', 'tsrange', 'tqdm', 'trange'] + + +class SlackIO(MonoWorker): + """Non-blocking file-like IO using a Slack app.""" + def __init__(self, token, channel): + """Creates a new message in the given `channel`.""" + super().__init__() + self.client = WebClient(token=token) + self.text = self.__class__.__name__ + try: + self.message = self.client.chat_postMessage(channel=channel, text=self.text) + except Exception as e: + tqdm_auto.write(str(e)) + self.message = None + + def write(self, s): + """Replaces internal `message`'s text with `s`.""" + if not s: + s = "..." + s = s.replace('\r', '').strip() + if s == self.text: + return # skip duplicate message + message = self.message + if message is None: + return + self.text = s + try: + future = self.submit(self.client.chat_update, channel=message['channel'], + ts=message['ts'], text='`' + s + '`') + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + +class tqdm_slack(tqdm_auto): + """ + Standard `tqdm.auto.tqdm` but also sends updates to a Slack app. + May take a few seconds to create (`__init__`). + + - create a Slack app with the `chat:write` scope & invite it to a + channel: <https://api.slack.com/authentication/basics> + - copy the bot `{token}` & `{channel}` and paste below + >>> from tqdm.contrib.slack import tqdm, trange + >>> for i in tqdm(iterable, token='{token}', channel='{channel}'): + ... ... + """ + def __init__(self, *args, **kwargs): + """ + Parameters + ---------- + token : str, required. Slack token + [default: ${TQDM_SLACK_TOKEN}]. + channel : int, required. Slack channel + [default: ${TQDM_SLACK_CHANNEL}]. + mininterval : float, optional. + Minimum of [default: 1.5] to avoid rate limit. + + See `tqdm.auto.tqdm.__init__` for other parameters. + """ + if not kwargs.get('disable'): + kwargs = kwargs.copy() + logging.getLogger("HTTPClient").setLevel(logging.WARNING) + self.sio = SlackIO( + kwargs.pop('token', getenv("TQDM_SLACK_TOKEN")), + kwargs.pop('channel', getenv("TQDM_SLACK_CHANNEL"))) + kwargs['mininterval'] = max(1.5, kwargs.get('mininterval', 1.5)) + super().__init__(*args, **kwargs) + + def display(self, **kwargs): + super().display(**kwargs) + fmt = self.format_dict + if fmt.get('bar_format', None): + fmt['bar_format'] = fmt['bar_format'].replace( + '<bar/>', '`{bar:10}`').replace('{bar}', '`{bar:10u}`') + else: + fmt['bar_format'] = '{l_bar}`{bar:10}`{r_bar}' + if fmt['ascii'] is False: + fmt['ascii'] = [":black_square:", ":small_blue_diamond:", ":large_blue_diamond:", + ":large_blue_square:"] + fmt['ncols'] = 336 + self.sio.write(self.format_meter(**fmt)) + + def clear(self, *args, **kwargs): + super().clear(*args, **kwargs) + if not self.disable: + self.sio.write("") + + +def tsrange(*args, **kwargs): + """Shortcut for `tqdm.contrib.slack.tqdm(range(*args), **kwargs)`.""" + return tqdm_slack(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_slack +trange = tsrange diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/telegram.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/telegram.py new file mode 100644 index 00000000..01915180 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/telegram.py @@ -0,0 +1,153 @@ +""" +Sends updates to a Telegram bot. + +Usage: +>>> from tqdm.contrib.telegram import tqdm, trange +>>> for i in trange(10, token='{token}', chat_id='{chat_id}'): +... ... + +![screenshot](https://tqdm.github.io/img/screenshot-telegram.gif) +""" +from os import getenv +from warnings import warn + +from requests import Session + +from ..auto import tqdm as tqdm_auto +from ..std import TqdmWarning +from .utils_worker import MonoWorker + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['TelegramIO', 'tqdm_telegram', 'ttgrange', 'tqdm', 'trange'] + + +class TelegramIO(MonoWorker): + """Non-blocking file-like IO using a Telegram Bot.""" + API = 'https://api.telegram.org/bot' + + def __init__(self, token, chat_id): + """Creates a new message in the given `chat_id`.""" + super().__init__() + self.token = token + self.chat_id = chat_id + self.session = Session() + self.text = self.__class__.__name__ + self.message_id + + @property + def message_id(self): + if hasattr(self, '_message_id'): + return self._message_id + try: + res = self.session.post( + self.API + '%s/sendMessage' % self.token, + data={'text': '`' + self.text + '`', 'chat_id': self.chat_id, + 'parse_mode': 'MarkdownV2'}).json() + except Exception as e: + tqdm_auto.write(str(e)) + else: + if res.get('error_code') == 429: + warn("Creation rate limit: try increasing `mininterval`.", + TqdmWarning, stacklevel=2) + else: + self._message_id = res['result']['message_id'] + return self._message_id + + def write(self, s): + """Replaces internal `message_id`'s text with `s`.""" + if not s: + s = "..." + s = s.replace('\r', '').strip() + if s == self.text: + return # avoid duplicate message Bot error + message_id = self.message_id + if message_id is None: + return + self.text = s + try: + future = self.submit( + self.session.post, self.API + '%s/editMessageText' % self.token, + data={'text': '`' + s + '`', 'chat_id': self.chat_id, + 'message_id': message_id, 'parse_mode': 'MarkdownV2'}) + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + def delete(self): + """Deletes internal `message_id`.""" + try: + future = self.submit( + self.session.post, self.API + '%s/deleteMessage' % self.token, + data={'chat_id': self.chat_id, 'message_id': self.message_id}) + except Exception as e: + tqdm_auto.write(str(e)) + else: + return future + + +class tqdm_telegram(tqdm_auto): + """ + Standard `tqdm.auto.tqdm` but also sends updates to a Telegram Bot. + May take a few seconds to create (`__init__`). + + - create a bot <https://core.telegram.org/bots#6-botfather> + - copy its `{token}` + - add the bot to a chat and send it a message such as `/start` + - go to <https://api.telegram.org/bot`{token}`/getUpdates> to find out + the `{chat_id}` + - paste the `{token}` & `{chat_id}` below + + >>> from tqdm.contrib.telegram import tqdm, trange + >>> for i in tqdm(iterable, token='{token}', chat_id='{chat_id}'): + ... ... + """ + def __init__(self, *args, **kwargs): + """ + Parameters + ---------- + token : str, required. Telegram token + [default: ${TQDM_TELEGRAM_TOKEN}]. + chat_id : str, required. Telegram chat ID + [default: ${TQDM_TELEGRAM_CHAT_ID}]. + + See `tqdm.auto.tqdm.__init__` for other parameters. + """ + if not kwargs.get('disable'): + kwargs = kwargs.copy() + self.tgio = TelegramIO( + kwargs.pop('token', getenv('TQDM_TELEGRAM_TOKEN')), + kwargs.pop('chat_id', getenv('TQDM_TELEGRAM_CHAT_ID'))) + super().__init__(*args, **kwargs) + + def display(self, **kwargs): + super().display(**kwargs) + fmt = self.format_dict + if fmt.get('bar_format', None): + fmt['bar_format'] = fmt['bar_format'].replace( + '<bar/>', '{bar:10u}').replace('{bar}', '{bar:10u}') + else: + fmt['bar_format'] = '{l_bar}{bar:10u}{r_bar}' + self.tgio.write(self.format_meter(**fmt)) + + def clear(self, *args, **kwargs): + super().clear(*args, **kwargs) + if not self.disable: + self.tgio.write("") + + def close(self): + if self.disable: + return + super().close() + if not (self.leave or (self.leave is None and self.pos == 0)): + self.tgio.delete() + + +def ttgrange(*args, **kwargs): + """Shortcut for `tqdm.contrib.telegram.tqdm(range(*args), **kwargs)`.""" + return tqdm_telegram(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_telegram +trange = ttgrange diff --git a/.venv/lib/python3.12/site-packages/tqdm/contrib/utils_worker.py b/.venv/lib/python3.12/site-packages/tqdm/contrib/utils_worker.py new file mode 100644 index 00000000..2a03a2a8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/contrib/utils_worker.py @@ -0,0 +1,38 @@ +""" +IO/concurrency helpers for `tqdm.contrib`. +""" +from collections import deque +from concurrent.futures import ThreadPoolExecutor + +from ..auto import tqdm as tqdm_auto + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['MonoWorker'] + + +class MonoWorker(object): + """ + Supports one running task and one waiting task. + The waiting task is the most recent submitted (others are discarded). + """ + def __init__(self): + self.pool = ThreadPoolExecutor(max_workers=1) + self.futures = deque([], 2) + + def submit(self, func, *args, **kwargs): + """`func(*args, **kwargs)` may replace currently waiting task.""" + futures = self.futures + if len(futures) == futures.maxlen: + running = futures.popleft() + if not running.done(): + if len(futures): # clear waiting + waiting = futures.pop() + waiting.cancel() + futures.appendleft(running) # re-insert running + try: + waiting = self.pool.submit(func, *args, **kwargs) + except Exception as e: + tqdm_auto.write(str(e)) + else: + futures.append(waiting) + return waiting diff --git a/.venv/lib/python3.12/site-packages/tqdm/dask.py b/.venv/lib/python3.12/site-packages/tqdm/dask.py new file mode 100644 index 00000000..57f1b668 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/dask.py @@ -0,0 +1,44 @@ +from functools import partial + +from dask.callbacks import Callback + +from .auto import tqdm as tqdm_auto + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['TqdmCallback'] + + +class TqdmCallback(Callback): + """Dask callback for task progress.""" + def __init__(self, start=None, pretask=None, tqdm_class=tqdm_auto, + **tqdm_kwargs): + """ + Parameters + ---------- + tqdm_class : optional + `tqdm` class to use for bars [default: `tqdm.auto.tqdm`]. + tqdm_kwargs : optional + Any other arguments used for all bars. + """ + super().__init__(start=start, pretask=pretask) + if tqdm_kwargs: + tqdm_class = partial(tqdm_class, **tqdm_kwargs) + self.tqdm_class = tqdm_class + + def _start_state(self, _, state): + self.pbar = self.tqdm_class(total=sum( + len(state[k]) for k in ['ready', 'waiting', 'running', 'finished'])) + + def _posttask(self, *_, **__): + self.pbar.update() + + def _finish(self, *_, **__): + self.pbar.close() + + def display(self): + """Displays in the current cell in Notebooks.""" + container = getattr(self.bar, 'container', None) + if container is None: + return + from .notebook import display + display(container) diff --git a/.venv/lib/python3.12/site-packages/tqdm/gui.py b/.venv/lib/python3.12/site-packages/tqdm/gui.py new file mode 100644 index 00000000..cb52fb91 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/gui.py @@ -0,0 +1,179 @@ +""" +Matplotlib GUI progressbar decorator for iterators. + +Usage: +>>> from tqdm.gui import trange, tqdm +>>> for i in trange(10): +... ... +""" +# future division is important to divide integers and get as +# a result precise floating numbers (instead of truncated int) +import re +from warnings import warn + +# to inherit from the tqdm class +from .std import TqdmExperimentalWarning +from .std import tqdm as std_tqdm + +# import compatibility functions and utilities + +__author__ = {"github.com/": ["casperdcl", "lrq3000"]} +__all__ = ['tqdm_gui', 'tgrange', 'tqdm', 'trange'] + + +class tqdm_gui(std_tqdm): # pragma: no cover + """Experimental Matplotlib GUI version of tqdm!""" + # TODO: @classmethod: write() on GUI? + def __init__(self, *args, **kwargs): + from collections import deque + + import matplotlib as mpl + import matplotlib.pyplot as plt + kwargs = kwargs.copy() + kwargs['gui'] = True + colour = kwargs.pop('colour', 'g') + super().__init__(*args, **kwargs) + + if self.disable: + return + + warn("GUI is experimental/alpha", TqdmExperimentalWarning, stacklevel=2) + self.mpl = mpl + self.plt = plt + + # Remember if external environment uses toolbars + self.toolbar = self.mpl.rcParams['toolbar'] + self.mpl.rcParams['toolbar'] = 'None' + + self.mininterval = max(self.mininterval, 0.5) + self.fig, ax = plt.subplots(figsize=(9, 2.2)) + # self.fig.subplots_adjust(bottom=0.2) + total = self.__len__() # avoids TypeError on None #971 + if total is not None: + self.xdata = [] + self.ydata = [] + self.zdata = [] + else: + self.xdata = deque([]) + self.ydata = deque([]) + self.zdata = deque([]) + self.line1, = ax.plot(self.xdata, self.ydata, color='b') + self.line2, = ax.plot(self.xdata, self.zdata, color='k') + ax.set_ylim(0, 0.001) + if total is not None: + ax.set_xlim(0, 100) + ax.set_xlabel("percent") + self.fig.legend((self.line1, self.line2), ("cur", "est"), + loc='center right') + # progressbar + self.hspan = plt.axhspan(0, 0.001, xmin=0, xmax=0, color=colour) + else: + # ax.set_xlim(-60, 0) + ax.set_xlim(0, 60) + ax.invert_xaxis() + ax.set_xlabel("seconds") + ax.legend(("cur", "est"), loc='lower left') + ax.grid() + # ax.set_xlabel('seconds') + ax.set_ylabel((self.unit if self.unit else "it") + "/s") + if self.unit_scale: + plt.ticklabel_format(style='sci', axis='y', scilimits=(0, 0)) + ax.yaxis.get_offset_text().set_x(-0.15) + + # Remember if external environment is interactive + self.wasion = plt.isinteractive() + plt.ion() + self.ax = ax + + def close(self): + if self.disable: + return + + self.disable = True + + with self.get_lock(): + self._instances.remove(self) + + # Restore toolbars + self.mpl.rcParams['toolbar'] = self.toolbar + # Return to non-interactive mode + if not self.wasion: + self.plt.ioff() + if self.leave: + self.display() + else: + self.plt.close(self.fig) + + def clear(self, *_, **__): + pass + + def display(self, *_, **__): + n = self.n + cur_t = self._time() + elapsed = cur_t - self.start_t + delta_it = n - self.last_print_n + delta_t = cur_t - self.last_print_t + + # Inline due to multiple calls + total = self.total + xdata = self.xdata + ydata = self.ydata + zdata = self.zdata + ax = self.ax + line1 = self.line1 + line2 = self.line2 + hspan = getattr(self, 'hspan', None) + # instantaneous rate + y = delta_it / delta_t + # overall rate + z = n / elapsed + # update line data + xdata.append(n * 100.0 / total if total else cur_t) + ydata.append(y) + zdata.append(z) + + # Discard old values + # xmin, xmax = ax.get_xlim() + # if (not total) and elapsed > xmin * 1.1: + if (not total) and elapsed > 66: + xdata.popleft() + ydata.popleft() + zdata.popleft() + + ymin, ymax = ax.get_ylim() + if y > ymax or z > ymax: + ymax = 1.1 * y + ax.set_ylim(ymin, ymax) + ax.figure.canvas.draw() + + if total: + line1.set_data(xdata, ydata) + line2.set_data(xdata, zdata) + if hspan: + hspan.set_xy((0, ymin)) + hspan.set_height(ymax - ymin) + hspan.set_width(n / total) + else: + t_ago = [cur_t - i for i in xdata] + line1.set_data(t_ago, ydata) + line2.set_data(t_ago, zdata) + + d = self.format_dict + # remove {bar} + d['bar_format'] = (d['bar_format'] or "{l_bar}<bar/>{r_bar}").replace( + "{bar}", "<bar/>") + msg = self.format_meter(**d) + if '<bar/>' in msg: + msg = "".join(re.split(r'\|?<bar/>\|?', msg, maxsplit=1)) + ax.set_title(msg, fontname="DejaVu Sans Mono", fontsize=11) + self.plt.pause(1e-9) + + +def tgrange(*args, **kwargs): + """Shortcut for `tqdm.gui.tqdm(range(*args), **kwargs)`.""" + return tqdm_gui(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_gui +trange = tgrange diff --git a/.venv/lib/python3.12/site-packages/tqdm/keras.py b/.venv/lib/python3.12/site-packages/tqdm/keras.py new file mode 100644 index 00000000..cce9467c --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/keras.py @@ -0,0 +1,122 @@ +from copy import copy +from functools import partial + +from .auto import tqdm as tqdm_auto + +try: + import keras +except (ImportError, AttributeError) as e: + try: + from tensorflow import keras + except ImportError: + raise e +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['TqdmCallback'] + + +class TqdmCallback(keras.callbacks.Callback): + """Keras callback for epoch and batch progress.""" + @staticmethod + def bar2callback(bar, pop=None, delta=(lambda logs: 1)): + def callback(_, logs=None): + n = delta(logs) + if logs: + if pop: + logs = copy(logs) + [logs.pop(i, 0) for i in pop] + bar.set_postfix(logs, refresh=False) + bar.update(n) + + return callback + + def __init__(self, epochs=None, data_size=None, batch_size=None, verbose=1, + tqdm_class=tqdm_auto, **tqdm_kwargs): + """ + Parameters + ---------- + epochs : int, optional + data_size : int, optional + Number of training pairs. + batch_size : int, optional + Number of training pairs per batch. + verbose : int + 0: epoch, 1: batch (transient), 2: batch. [default: 1]. + Will be set to `0` unless both `data_size` and `batch_size` + are given. + tqdm_class : optional + `tqdm` class to use for bars [default: `tqdm.auto.tqdm`]. + tqdm_kwargs : optional + Any other arguments used for all bars. + """ + if tqdm_kwargs: + tqdm_class = partial(tqdm_class, **tqdm_kwargs) + self.tqdm_class = tqdm_class + self.epoch_bar = tqdm_class(total=epochs, unit='epoch') + self.on_epoch_end = self.bar2callback(self.epoch_bar) + if data_size and batch_size: + self.batches = batches = (data_size + batch_size - 1) // batch_size + else: + self.batches = batches = None + self.verbose = verbose + if verbose == 1: + self.batch_bar = tqdm_class(total=batches, unit='batch', leave=False) + self.on_batch_end = self.bar2callback( + self.batch_bar, pop=['batch', 'size'], + delta=lambda logs: logs.get('size', 1)) + + def on_train_begin(self, *_, **__): + params = self.params.get + auto_total = params('epochs', params('nb_epoch', None)) + if auto_total is not None and auto_total != self.epoch_bar.total: + self.epoch_bar.reset(total=auto_total) + + def on_epoch_begin(self, epoch, *_, **__): + if self.epoch_bar.n < epoch: + ebar = self.epoch_bar + ebar.n = ebar.last_print_n = ebar.initial = epoch + if self.verbose: + params = self.params.get + total = params('samples', params( + 'nb_sample', params('steps', None))) or self.batches + if self.verbose == 2: + if hasattr(self, 'batch_bar'): + self.batch_bar.close() + self.batch_bar = self.tqdm_class( + total=total, unit='batch', leave=True, + unit_scale=1 / (params('batch_size', 1) or 1)) + self.on_batch_end = self.bar2callback( + self.batch_bar, pop=['batch', 'size'], + delta=lambda logs: logs.get('size', 1)) + elif self.verbose == 1: + self.batch_bar.unit_scale = 1 / (params('batch_size', 1) or 1) + self.batch_bar.reset(total=total) + else: + raise KeyError('Unknown verbosity') + + def on_train_end(self, *_, **__): + if hasattr(self, 'batch_bar'): + self.batch_bar.close() + self.epoch_bar.close() + + def display(self): + """Displays in the current cell in Notebooks.""" + container = getattr(self.epoch_bar, 'container', None) + if container is None: + return + from .notebook import display + display(container) + batch_bar = getattr(self, 'batch_bar', None) + if batch_bar is not None: + display(batch_bar.container) + + @staticmethod + def _implements_train_batch_hooks(): + return True + + @staticmethod + def _implements_test_batch_hooks(): + return True + + @staticmethod + def _implements_predict_batch_hooks(): + return True diff --git a/.venv/lib/python3.12/site-packages/tqdm/notebook.py b/.venv/lib/python3.12/site-packages/tqdm/notebook.py new file mode 100644 index 00000000..77b91bdd --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/notebook.py @@ -0,0 +1,317 @@ +""" +IPython/Jupyter Notebook progressbar decorator for iterators. +Includes a default `range` iterator printing to `stderr`. + +Usage: +>>> from tqdm.notebook import trange, tqdm +>>> for i in trange(10): +... ... +""" +# import compatibility functions and utilities +import re +import sys +from html import escape +from weakref import proxy + +# to inherit from the tqdm class +from .std import tqdm as std_tqdm + +if True: # pragma: no cover + # import IPython/Jupyter base widget and display utilities + IPY = 0 + try: # IPython 4.x + import ipywidgets + IPY = 4 + except ImportError: # IPython 3.x / 2.x + IPY = 32 + import warnings + with warnings.catch_warnings(): + warnings.filterwarnings( + 'ignore', message=".*The `IPython.html` package has been deprecated.*") + try: + import IPython.html.widgets as ipywidgets # NOQA: F401 + except ImportError: + pass + + try: # IPython 4.x / 3.x + if IPY == 32: + from IPython.html.widgets import HTML + from IPython.html.widgets import FloatProgress as IProgress + from IPython.html.widgets import HBox + IPY = 3 + else: + from ipywidgets import HTML + from ipywidgets import FloatProgress as IProgress + from ipywidgets import HBox + except ImportError: + try: # IPython 2.x + from IPython.html.widgets import HTML + from IPython.html.widgets import ContainerWidget as HBox + from IPython.html.widgets import FloatProgressWidget as IProgress + IPY = 2 + except ImportError: + IPY = 0 + IProgress = None + HBox = object + + try: + from IPython.display import display # , clear_output + except ImportError: + pass + +__author__ = {"github.com/": ["lrq3000", "casperdcl", "alexanderkuk"]} +__all__ = ['tqdm_notebook', 'tnrange', 'tqdm', 'trange'] +WARN_NOIPYW = ("IProgress not found. Please update jupyter and ipywidgets." + " See https://ipywidgets.readthedocs.io/en/stable" + "/user_install.html") + + +class TqdmHBox(HBox): + """`ipywidgets.HBox` with a pretty representation""" + def _json_(self, pretty=None): + pbar = getattr(self, 'pbar', None) + if pbar is None: + return {} + d = pbar.format_dict + if pretty is not None: + d["ascii"] = not pretty + return d + + def __repr__(self, pretty=False): + pbar = getattr(self, 'pbar', None) + if pbar is None: + return super().__repr__() + return pbar.format_meter(**self._json_(pretty)) + + def _repr_pretty_(self, pp, *_, **__): + pp.text(self.__repr__(True)) + + +class tqdm_notebook(std_tqdm): + """ + Experimental IPython/Jupyter Notebook widget using tqdm! + """ + @staticmethod + def status_printer(_, total=None, desc=None, ncols=None): + """ + Manage the printing of an IPython/Jupyter Notebook progress bar widget. + """ + # Fallback to text bar if there's no total + # DEPRECATED: replaced with an 'info' style bar + # if not total: + # return super(tqdm_notebook, tqdm_notebook).status_printer(file) + + # fp = file + + # Prepare IPython progress bar + if IProgress is None: # #187 #451 #558 #872 + raise ImportError(WARN_NOIPYW) + if total: + pbar = IProgress(min=0, max=total) + else: # No total? Show info style bar with no progress tqdm status + pbar = IProgress(min=0, max=1) + pbar.value = 1 + pbar.bar_style = 'info' + if ncols is None: + pbar.layout.width = "20px" + + ltext = HTML() + rtext = HTML() + if desc: + ltext.value = desc + container = TqdmHBox(children=[ltext, pbar, rtext]) + # Prepare layout + if ncols is not None: # use default style of ipywidgets + # ncols could be 100, "100px", "100%" + ncols = str(ncols) # ipywidgets only accepts string + try: + if int(ncols) > 0: # isnumeric and positive + ncols += 'px' + except ValueError: + pass + pbar.layout.flex = '2' + container.layout.width = ncols + container.layout.display = 'inline-flex' + container.layout.flex_flow = 'row wrap' + + return container + + def display(self, msg=None, pos=None, + # additional signals + close=False, bar_style=None, check_delay=True): + # Note: contrary to native tqdm, msg='' does NOT clear bar + # goal is to keep all infos if error happens so user knows + # at which iteration the loop failed. + + # Clear previous output (really necessary?) + # clear_output(wait=1) + + if not msg and not close: + d = self.format_dict + # remove {bar} + d['bar_format'] = (d['bar_format'] or "{l_bar}<bar/>{r_bar}").replace( + "{bar}", "<bar/>") + msg = self.format_meter(**d) + + ltext, pbar, rtext = self.container.children + pbar.value = self.n + + if msg: + msg = msg.replace(' ', u'\u2007') # fix html space padding + # html escape special characters (like '&') + if '<bar/>' in msg: + left, right = map(escape, re.split(r'\|?<bar/>\|?', msg, maxsplit=1)) + else: + left, right = '', escape(msg) + + # Update description + ltext.value = left + # never clear the bar (signal: msg='') + if right: + rtext.value = right + + # Change bar style + if bar_style: + # Hack-ish way to avoid the danger bar_style being overridden by + # success because the bar gets closed after the error... + if pbar.bar_style != 'danger' or bar_style != 'success': + pbar.bar_style = bar_style + + # Special signal to close the bar + if close and pbar.bar_style != 'danger': # hide only if no error + try: + self.container.close() + except AttributeError: + self.container.visible = False + self.container.layout.visibility = 'hidden' # IPYW>=8 + + if check_delay and self.delay > 0 and not self.displayed: + display(self.container) + self.displayed = True + + @property + def colour(self): + if hasattr(self, 'container'): + return self.container.children[-2].style.bar_color + + @colour.setter + def colour(self, bar_color): + if hasattr(self, 'container'): + self.container.children[-2].style.bar_color = bar_color + + def __init__(self, *args, **kwargs): + """ + Supports the usual `tqdm.tqdm` parameters as well as those listed below. + + Parameters + ---------- + display : Whether to call `display(self.container)` immediately + [default: True]. + """ + kwargs = kwargs.copy() + # Setup default output + file_kwarg = kwargs.get('file', sys.stderr) + if file_kwarg is sys.stderr or file_kwarg is None: + kwargs['file'] = sys.stdout # avoid the red block in IPython + + # Initialize parent class + avoid printing by using gui=True + kwargs['gui'] = True + # convert disable = None to False + kwargs['disable'] = bool(kwargs.get('disable', False)) + colour = kwargs.pop('colour', None) + display_here = kwargs.pop('display', True) + super().__init__(*args, **kwargs) + if self.disable or not kwargs['gui']: + self.disp = lambda *_, **__: None + return + + # Get bar width + self.ncols = '100%' if self.dynamic_ncols else kwargs.get("ncols", None) + + # Replace with IPython progress bar display (with correct total) + unit_scale = 1 if self.unit_scale is True else self.unit_scale or 1 + total = self.total * unit_scale if self.total else self.total + self.container = self.status_printer(self.fp, total, self.desc, self.ncols) + self.container.pbar = proxy(self) + self.displayed = False + if display_here and self.delay <= 0: + display(self.container) + self.displayed = True + self.disp = self.display + self.colour = colour + + # Print initial bar state + if not self.disable: + self.display(check_delay=False) + + def __iter__(self): + try: + it = super().__iter__() + for obj in it: + # return super(tqdm...) will not catch exception + yield obj + # NB: except ... [ as ...] breaks IPython async KeyboardInterrupt + except: # NOQA + self.disp(bar_style='danger') + raise + # NB: don't `finally: close()` + # since this could be a shared bar which the user will `reset()` + + def update(self, n=1): + try: + return super().update(n=n) + # NB: except ... [ as ...] breaks IPython async KeyboardInterrupt + except: # NOQA + # cannot catch KeyboardInterrupt when using manual tqdm + # as the interrupt will most likely happen on another statement + self.disp(bar_style='danger') + raise + # NB: don't `finally: close()` + # since this could be a shared bar which the user will `reset()` + + def close(self): + if self.disable: + return + super().close() + # Try to detect if there was an error or KeyboardInterrupt + # in manual mode: if n < total, things probably got wrong + if self.total and self.n < self.total: + self.disp(bar_style='danger', check_delay=False) + else: + if self.leave: + self.disp(bar_style='success', check_delay=False) + else: + self.disp(close=True, check_delay=False) + + def clear(self, *_, **__): + pass + + def reset(self, total=None): + """ + Resets to 0 iterations for repeated use. + + Consider combining with `leave=True`. + + Parameters + ---------- + total : int or float, optional. Total to use for the new bar. + """ + if self.disable: + return super().reset(total=total) + _, pbar, _ = self.container.children + pbar.bar_style = '' + if total is not None: + pbar.max = total + if not self.total and self.ncols is None: # no longer unknown total + pbar.layout.width = None # reset width + return super().reset(total=total) + + +def tnrange(*args, **kwargs): + """Shortcut for `tqdm.notebook.tqdm(range(*args), **kwargs)`.""" + return tqdm_notebook(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_notebook +trange = tnrange diff --git a/.venv/lib/python3.12/site-packages/tqdm/rich.py b/.venv/lib/python3.12/site-packages/tqdm/rich.py new file mode 100644 index 00000000..3d392eda --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/rich.py @@ -0,0 +1,151 @@ +""" +`rich.progress` decorator for iterators. + +Usage: +>>> from tqdm.rich import trange, tqdm +>>> for i in trange(10): +... ... +""" +from warnings import warn + +from rich.progress import ( + BarColumn, Progress, ProgressColumn, Text, TimeElapsedColumn, TimeRemainingColumn, filesize) + +from .std import TqdmExperimentalWarning +from .std import tqdm as std_tqdm + +__author__ = {"github.com/": ["casperdcl"]} +__all__ = ['tqdm_rich', 'trrange', 'tqdm', 'trange'] + + +class FractionColumn(ProgressColumn): + """Renders completed/total, e.g. '0.5/2.3 G'.""" + def __init__(self, unit_scale=False, unit_divisor=1000): + self.unit_scale = unit_scale + self.unit_divisor = unit_divisor + super().__init__() + + def render(self, task): + """Calculate common unit for completed and total.""" + completed = int(task.completed) + total = int(task.total) + if self.unit_scale: + unit, suffix = filesize.pick_unit_and_suffix( + total, + ["", "K", "M", "G", "T", "P", "E", "Z", "Y"], + self.unit_divisor, + ) + else: + unit, suffix = filesize.pick_unit_and_suffix(total, [""], 1) + precision = 0 if unit == 1 else 1 + return Text( + f"{completed/unit:,.{precision}f}/{total/unit:,.{precision}f} {suffix}", + style="progress.download") + + +class RateColumn(ProgressColumn): + """Renders human readable transfer speed.""" + def __init__(self, unit="", unit_scale=False, unit_divisor=1000): + self.unit = unit + self.unit_scale = unit_scale + self.unit_divisor = unit_divisor + super().__init__() + + def render(self, task): + """Show data transfer speed.""" + speed = task.speed + if speed is None: + return Text(f"? {self.unit}/s", style="progress.data.speed") + if self.unit_scale: + unit, suffix = filesize.pick_unit_and_suffix( + speed, + ["", "K", "M", "G", "T", "P", "E", "Z", "Y"], + self.unit_divisor, + ) + else: + unit, suffix = filesize.pick_unit_and_suffix(speed, [""], 1) + precision = 0 if unit == 1 else 1 + return Text(f"{speed/unit:,.{precision}f} {suffix}{self.unit}/s", + style="progress.data.speed") + + +class tqdm_rich(std_tqdm): # pragma: no cover + """Experimental rich.progress GUI version of tqdm!""" + # TODO: @classmethod: write()? + def __init__(self, *args, **kwargs): + """ + This class accepts the following parameters *in addition* to + the parameters accepted by `tqdm`. + + Parameters + ---------- + progress : tuple, optional + arguments for `rich.progress.Progress()`. + options : dict, optional + keyword arguments for `rich.progress.Progress()`. + """ + kwargs = kwargs.copy() + kwargs['gui'] = True + # convert disable = None to False + kwargs['disable'] = bool(kwargs.get('disable', False)) + progress = kwargs.pop('progress', None) + options = kwargs.pop('options', {}).copy() + super().__init__(*args, **kwargs) + + if self.disable: + return + + warn("rich is experimental/alpha", TqdmExperimentalWarning, stacklevel=2) + d = self.format_dict + if progress is None: + progress = ( + "[progress.description]{task.description}" + "[progress.percentage]{task.percentage:>4.0f}%", + BarColumn(bar_width=None), + FractionColumn( + unit_scale=d['unit_scale'], unit_divisor=d['unit_divisor']), + "[", TimeElapsedColumn(), "<", TimeRemainingColumn(), + ",", RateColumn(unit=d['unit'], unit_scale=d['unit_scale'], + unit_divisor=d['unit_divisor']), "]" + ) + options.setdefault('transient', not self.leave) + self._prog = Progress(*progress, **options) + self._prog.__enter__() + self._task_id = self._prog.add_task(self.desc or "", **d) + + def close(self): + if self.disable: + return + self.display() # print 100%, vis #1306 + super().close() + self._prog.__exit__(None, None, None) + + def clear(self, *_, **__): + pass + + def display(self, *_, **__): + if not hasattr(self, '_prog'): + return + self._prog.update(self._task_id, completed=self.n, description=self.desc) + + def reset(self, total=None): + """ + Resets to 0 iterations for repeated use. + + Parameters + ---------- + total : int or float, optional. Total to use for the new bar. + """ + if hasattr(self, '_prog'): + self._prog.reset(total=total) + super().reset(total=total) + + +def trrange(*args, **kwargs): + """Shortcut for `tqdm.rich.tqdm(range(*args), **kwargs)`.""" + return tqdm_rich(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_rich +trange = trrange diff --git a/.venv/lib/python3.12/site-packages/tqdm/std.py b/.venv/lib/python3.12/site-packages/tqdm/std.py new file mode 100644 index 00000000..e91ad309 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/std.py @@ -0,0 +1,1524 @@ +""" +Customisable progressbar decorator for iterators. +Includes a default `range` iterator printing to `stderr`. + +Usage: +>>> from tqdm import trange, tqdm +>>> for i in trange(10): +... ... +""" +import sys +from collections import OrderedDict, defaultdict +from contextlib import contextmanager +from datetime import datetime, timedelta, timezone +from numbers import Number +from time import time +from warnings import warn +from weakref import WeakSet + +from ._monitor import TMonitor +from .utils import ( + CallbackIOWrapper, Comparable, DisableOnWriteError, FormatReplace, SimpleTextIOWrapper, + _is_ascii, _screen_shape_wrapper, _supports_unicode, _term_move_up, disp_len, disp_trim, + envwrap) + +__author__ = "https://github.com/tqdm/tqdm#contributions" +__all__ = ['tqdm', 'trange', + 'TqdmTypeError', 'TqdmKeyError', 'TqdmWarning', + 'TqdmExperimentalWarning', 'TqdmDeprecationWarning', + 'TqdmMonitorWarning'] + + +class TqdmTypeError(TypeError): + pass + + +class TqdmKeyError(KeyError): + pass + + +class TqdmWarning(Warning): + """base class for all tqdm warnings. + + Used for non-external-code-breaking errors, such as garbled printing. + """ + def __init__(self, msg, fp_write=None, *a, **k): + if fp_write is not None: + fp_write("\n" + self.__class__.__name__ + ": " + str(msg).rstrip() + '\n') + else: + super().__init__(msg, *a, **k) + + +class TqdmExperimentalWarning(TqdmWarning, FutureWarning): + """beta feature, unstable API and behaviour""" + pass + + +class TqdmDeprecationWarning(TqdmWarning, DeprecationWarning): + # not suppressed if raised + pass + + +class TqdmMonitorWarning(TqdmWarning, RuntimeWarning): + """tqdm monitor errors which do not affect external functionality""" + pass + + +def TRLock(*args, **kwargs): + """threading RLock""" + try: + from threading import RLock + return RLock(*args, **kwargs) + except (ImportError, OSError): # pragma: no cover + pass + + +class TqdmDefaultWriteLock(object): + """ + Provide a default write lock for thread and multiprocessing safety. + Works only on platforms supporting `fork` (so Windows is excluded). + You must initialise a `tqdm` or `TqdmDefaultWriteLock` instance + before forking in order for the write lock to work. + On Windows, you need to supply the lock from the parent to the children as + an argument to joblib or the parallelism lib you use. + """ + # global thread lock so no setup required for multithreading. + # NB: Do not create multiprocessing lock as it sets the multiprocessing + # context, disallowing `spawn()`/`forkserver()` + th_lock = TRLock() + + def __init__(self): + # Create global parallelism locks to avoid racing issues with parallel + # bars works only if fork available (Linux/MacOSX, but not Windows) + cls = type(self) + root_lock = cls.th_lock + if root_lock is not None: + root_lock.acquire() + cls.create_mp_lock() + self.locks = [lk for lk in [cls.mp_lock, cls.th_lock] if lk is not None] + if root_lock is not None: + root_lock.release() + + def acquire(self, *a, **k): + for lock in self.locks: + lock.acquire(*a, **k) + + def release(self): + for lock in self.locks[::-1]: # Release in inverse order of acquisition + lock.release() + + def __enter__(self): + self.acquire() + + def __exit__(self, *exc): + self.release() + + @classmethod + def create_mp_lock(cls): + if not hasattr(cls, 'mp_lock'): + try: + from multiprocessing import RLock + cls.mp_lock = RLock() + except (ImportError, OSError): # pragma: no cover + cls.mp_lock = None + + @classmethod + def create_th_lock(cls): + assert hasattr(cls, 'th_lock') + warn("create_th_lock not needed anymore", TqdmDeprecationWarning, stacklevel=2) + + +class Bar(object): + """ + `str.format`-able bar with format specifiers: `[width][type]` + + - `width` + + unspecified (default): use `self.default_len` + + `int >= 0`: overrides `self.default_len` + + `int < 0`: subtract from `self.default_len` + - `type` + + `a`: ascii (`charset=self.ASCII` override) + + `u`: unicode (`charset=self.UTF` override) + + `b`: blank (`charset=" "` override) + """ + ASCII = " 123456789#" + UTF = u" " + u''.join(map(chr, range(0x258F, 0x2587, -1))) + BLANK = " " + COLOUR_RESET = '\x1b[0m' + COLOUR_RGB = '\x1b[38;2;%d;%d;%dm' + COLOURS = {'BLACK': '\x1b[30m', 'RED': '\x1b[31m', 'GREEN': '\x1b[32m', + 'YELLOW': '\x1b[33m', 'BLUE': '\x1b[34m', 'MAGENTA': '\x1b[35m', + 'CYAN': '\x1b[36m', 'WHITE': '\x1b[37m'} + + def __init__(self, frac, default_len=10, charset=UTF, colour=None): + if not 0 <= frac <= 1: + warn("clamping frac to range [0, 1]", TqdmWarning, stacklevel=2) + frac = max(0, min(1, frac)) + assert default_len > 0 + self.frac = frac + self.default_len = default_len + self.charset = charset + self.colour = colour + + @property + def colour(self): + return self._colour + + @colour.setter + def colour(self, value): + if not value: + self._colour = None + return + try: + if value.upper() in self.COLOURS: + self._colour = self.COLOURS[value.upper()] + elif value[0] == '#' and len(value) == 7: + self._colour = self.COLOUR_RGB % tuple( + int(i, 16) for i in (value[1:3], value[3:5], value[5:7])) + else: + raise KeyError + except (KeyError, AttributeError): + warn("Unknown colour (%s); valid choices: [hex (#00ff00), %s]" % ( + value, ", ".join(self.COLOURS)), + TqdmWarning, stacklevel=2) + self._colour = None + + def __format__(self, format_spec): + if format_spec: + _type = format_spec[-1].lower() + try: + charset = {'a': self.ASCII, 'u': self.UTF, 'b': self.BLANK}[_type] + except KeyError: + charset = self.charset + else: + format_spec = format_spec[:-1] + if format_spec: + N_BARS = int(format_spec) + if N_BARS < 0: + N_BARS += self.default_len + else: + N_BARS = self.default_len + else: + charset = self.charset + N_BARS = self.default_len + + nsyms = len(charset) - 1 + bar_length, frac_bar_length = divmod(int(self.frac * N_BARS * nsyms), nsyms) + + res = charset[-1] * bar_length + if bar_length < N_BARS: # whitespace padding + res = res + charset[frac_bar_length] + charset[0] * (N_BARS - bar_length - 1) + return self.colour + res + self.COLOUR_RESET if self.colour else res + + +class EMA(object): + """ + Exponential moving average: smoothing to give progressively lower + weights to older values. + + Parameters + ---------- + smoothing : float, optional + Smoothing factor in range [0, 1], [default: 0.3]. + Increase to give more weight to recent values. + Ranges from 0 (yields old value) to 1 (yields new value). + """ + def __init__(self, smoothing=0.3): + self.alpha = smoothing + self.last = 0 + self.calls = 0 + + def __call__(self, x=None): + """ + Parameters + ---------- + x : float + New value to include in EMA. + """ + beta = 1 - self.alpha + if x is not None: + self.last = self.alpha * x + beta * self.last + self.calls += 1 + return self.last / (1 - beta ** self.calls) if self.calls else self.last + + +class tqdm(Comparable): + """ + Decorate an iterable object, returning an iterator which acts exactly + like the original iterable, but prints a dynamically updating + progressbar every time a value is requested. + + Parameters + ---------- + iterable : iterable, optional + Iterable to decorate with a progressbar. + Leave blank to manually manage the updates. + desc : str, optional + Prefix for the progressbar. + total : int or float, optional + The number of expected iterations. If unspecified, + len(iterable) is used if possible. If float("inf") or as a last + resort, only basic progress statistics are displayed + (no ETA, no progressbar). + If `gui` is True and this parameter needs subsequent updating, + specify an initial arbitrary large positive number, + e.g. 9e9. + leave : bool, optional + If [default: True], keeps all traces of the progressbar + upon termination of iteration. + If `None`, will leave only if `position` is `0`. + file : `io.TextIOWrapper` or `io.StringIO`, optional + Specifies where to output the progress messages + (default: sys.stderr). Uses `file.write(str)` and `file.flush()` + methods. For encoding, see `write_bytes`. + ncols : int, optional + The width of the entire output message. If specified, + dynamically resizes the progressbar to stay within this bound. + If unspecified, attempts to use environment width. The + fallback is a meter width of 10 and no limit for the counter and + statistics. If 0, will not print any meter (only stats). + mininterval : float, optional + Minimum progress display update interval [default: 0.1] seconds. + maxinterval : float, optional + Maximum progress display update interval [default: 10] seconds. + Automatically adjusts `miniters` to correspond to `mininterval` + after long display update lag. Only works if `dynamic_miniters` + or monitor thread is enabled. + miniters : int or float, optional + Minimum progress display update interval, in iterations. + If 0 and `dynamic_miniters`, will automatically adjust to equal + `mininterval` (more CPU efficient, good for tight loops). + If > 0, will skip display of specified number of iterations. + Tweak this and `mininterval` to get very efficient loops. + If your progress is erratic with both fast and slow iterations + (network, skipping items, etc) you should set miniters=1. + ascii : bool or str, optional + If unspecified or False, use unicode (smooth blocks) to fill + the meter. The fallback is to use ASCII characters " 123456789#". + disable : bool, optional + Whether to disable the entire progressbar wrapper + [default: False]. If set to None, disable on non-TTY. + unit : str, optional + String that will be used to define the unit of each iteration + [default: it]. + unit_scale : bool or int or float, optional + If 1 or True, the number of iterations will be reduced/scaled + automatically and a metric prefix following the + International System of Units standard will be added + (kilo, mega, etc.) [default: False]. If any other non-zero + number, will scale `total` and `n`. + dynamic_ncols : bool, optional + If set, constantly alters `ncols` and `nrows` to the + environment (allowing for window resizes) [default: False]. + smoothing : float, optional + Exponential moving average smoothing factor for speed estimates + (ignored in GUI mode). Ranges from 0 (average speed) to 1 + (current/instantaneous speed) [default: 0.3]. + bar_format : str, optional + Specify a custom bar string formatting. May impact performance. + [default: '{l_bar}{bar}{r_bar}'], where + l_bar='{desc}: {percentage:3.0f}%|' and + r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ' + '{rate_fmt}{postfix}]' + Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, + percentage, elapsed, elapsed_s, ncols, nrows, desc, unit, + rate, rate_fmt, rate_noinv, rate_noinv_fmt, + rate_inv, rate_inv_fmt, postfix, unit_divisor, + remaining, remaining_s, eta. + Note that a trailing ": " is automatically removed after {desc} + if the latter is empty. + initial : int or float, optional + The initial counter value. Useful when restarting a progress + bar [default: 0]. If using float, consider specifying `{n:.3f}` + or similar in `bar_format`, or specifying `unit_scale`. + position : int, optional + Specify the line offset to print this bar (starting from 0) + Automatic if unspecified. + Useful to manage multiple bars at once (eg, from threads). + postfix : dict or *, optional + Specify additional stats to display at the end of the bar. + Calls `set_postfix(**postfix)` if possible (dict). + unit_divisor : float, optional + [default: 1000], ignored unless `unit_scale` is True. + write_bytes : bool, optional + Whether to write bytes. If (default: False) will write unicode. + lock_args : tuple, optional + Passed to `refresh` for intermediate output + (initialisation, iterating, and updating). + nrows : int, optional + The screen height. If specified, hides nested bars outside this + bound. If unspecified, attempts to use environment height. + The fallback is 20. + colour : str, optional + Bar colour (e.g. 'green', '#00ff00'). + delay : float, optional + Don't display until [default: 0] seconds have elapsed. + gui : bool, optional + WARNING: internal parameter - do not use. + Use tqdm.gui.tqdm(...) instead. If set, will attempt to use + matplotlib animations for a graphical output [default: False]. + + Returns + ------- + out : decorated iterator. + """ + + monitor_interval = 10 # set to 0 to disable the thread + monitor = None + _instances = WeakSet() + + @staticmethod + def format_sizeof(num, suffix='', divisor=1000): + """ + Formats a number (greater than unity) with SI Order of Magnitude + prefixes. + + Parameters + ---------- + num : float + Number ( >= 1) to format. + suffix : str, optional + Post-postfix [default: '']. + divisor : float, optional + Divisor between prefixes [default: 1000]. + + Returns + ------- + out : str + Number with Order of Magnitude SI unit postfix. + """ + for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']: + if abs(num) < 999.5: + if abs(num) < 99.95: + if abs(num) < 9.995: + return f'{num:1.2f}{unit}{suffix}' + return f'{num:2.1f}{unit}{suffix}' + return f'{num:3.0f}{unit}{suffix}' + num /= divisor + return f'{num:3.1f}Y{suffix}' + + @staticmethod + def format_interval(t): + """ + Formats a number of seconds as a clock time, [H:]MM:SS + + Parameters + ---------- + t : int + Number of seconds. + + Returns + ------- + out : str + [H:]MM:SS + """ + mins, s = divmod(int(t), 60) + h, m = divmod(mins, 60) + return f'{h:d}:{m:02d}:{s:02d}' if h else f'{m:02d}:{s:02d}' + + @staticmethod + def format_num(n): + """ + Intelligent scientific notation (.3g). + + Parameters + ---------- + n : int or float or Numeric + A Number. + + Returns + ------- + out : str + Formatted number. + """ + f = f'{n:.3g}'.replace('e+0', 'e+').replace('e-0', 'e-') + n = str(n) + return f if len(f) < len(n) else n + + @staticmethod + def status_printer(file): + """ + Manage the printing and in-place updating of a line of characters. + Note that if the string is longer than a line, then in-place + updating may not work (it will print a new line at each refresh). + """ + fp = file + fp_flush = getattr(fp, 'flush', lambda: None) # pragma: no cover + if fp in (sys.stderr, sys.stdout): + getattr(sys.stderr, 'flush', lambda: None)() + getattr(sys.stdout, 'flush', lambda: None)() + + def fp_write(s): + fp.write(str(s)) + fp_flush() + + last_len = [0] + + def print_status(s): + len_s = disp_len(s) + fp_write('\r' + s + (' ' * max(last_len[0] - len_s, 0))) + last_len[0] = len_s + + return print_status + + @staticmethod + def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, unit='it', + unit_scale=False, rate=None, bar_format=None, postfix=None, + unit_divisor=1000, initial=0, colour=None, **extra_kwargs): + """ + Return a string-based progress bar given some parameters + + Parameters + ---------- + n : int or float + Number of finished iterations. + total : int or float + The expected total number of iterations. If meaningless (None), + only basic progress statistics are displayed (no ETA). + elapsed : float + Number of seconds passed since start. + ncols : int, optional + The width of the entire output message. If specified, + dynamically resizes `{bar}` to stay within this bound + [default: None]. If `0`, will not print any bar (only stats). + The fallback is `{bar:10}`. + prefix : str, optional + Prefix message (included in total width) [default: '']. + Use as {desc} in bar_format string. + ascii : bool, optional or str, optional + If not set, use unicode (smooth blocks) to fill the meter + [default: False]. The fallback is to use ASCII characters + " 123456789#". + unit : str, optional + The iteration unit [default: 'it']. + unit_scale : bool or int or float, optional + If 1 or True, the number of iterations will be printed with an + appropriate SI metric prefix (k = 10^3, M = 10^6, etc.) + [default: False]. If any other non-zero number, will scale + `total` and `n`. + rate : float, optional + Manual override for iteration rate. + If [default: None], uses n/elapsed. + bar_format : str, optional + Specify a custom bar string formatting. May impact performance. + [default: '{l_bar}{bar}{r_bar}'], where + l_bar='{desc}: {percentage:3.0f}%|' and + r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ' + '{rate_fmt}{postfix}]' + Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, + percentage, elapsed, elapsed_s, ncols, nrows, desc, unit, + rate, rate_fmt, rate_noinv, rate_noinv_fmt, + rate_inv, rate_inv_fmt, postfix, unit_divisor, + remaining, remaining_s, eta. + Note that a trailing ": " is automatically removed after {desc} + if the latter is empty. + postfix : *, optional + Similar to `prefix`, but placed at the end + (e.g. for additional stats). + Note: postfix is usually a string (not a dict) for this method, + and will if possible be set to postfix = ', ' + postfix. + However other types are supported (#382). + unit_divisor : float, optional + [default: 1000], ignored unless `unit_scale` is True. + initial : int or float, optional + The initial counter value [default: 0]. + colour : str, optional + Bar colour (e.g. 'green', '#00ff00'). + + Returns + ------- + out : Formatted meter and stats, ready to display. + """ + + # sanity check: total + if total and n >= (total + 0.5): # allow float imprecision (#849) + total = None + + # apply custom scale if necessary + if unit_scale and unit_scale not in (True, 1): + if total: + total *= unit_scale + n *= unit_scale + if rate: + rate *= unit_scale # by default rate = self.avg_dn / self.avg_dt + unit_scale = False + + elapsed_str = tqdm.format_interval(elapsed) + + # if unspecified, attempt to use rate = average speed + # (we allow manual override since predicting time is an arcane art) + if rate is None and elapsed: + rate = (n - initial) / elapsed + inv_rate = 1 / rate if rate else None + format_sizeof = tqdm.format_sizeof + rate_noinv_fmt = ((format_sizeof(rate) if unit_scale else f'{rate:5.2f}') + if rate else '?') + unit + '/s' + rate_inv_fmt = ( + (format_sizeof(inv_rate) if unit_scale else f'{inv_rate:5.2f}') + if inv_rate else '?') + 's/' + unit + rate_fmt = rate_inv_fmt if inv_rate and inv_rate > 1 else rate_noinv_fmt + + if unit_scale: + n_fmt = format_sizeof(n, divisor=unit_divisor) + total_fmt = format_sizeof(total, divisor=unit_divisor) if total is not None else '?' + else: + n_fmt = str(n) + total_fmt = str(total) if total is not None else '?' + + try: + postfix = ', ' + postfix if postfix else '' + except TypeError: + pass + + remaining = (total - n) / rate if rate and total else 0 + remaining_str = tqdm.format_interval(remaining) if rate else '?' + try: + eta_dt = (datetime.now() + timedelta(seconds=remaining) + if rate and total else datetime.fromtimestamp(0, timezone.utc)) + except OverflowError: + eta_dt = datetime.max + + # format the stats displayed to the left and right sides of the bar + if prefix: + # old prefix setup work around + bool_prefix_colon_already = (prefix[-2:] == ": ") + l_bar = prefix if bool_prefix_colon_already else prefix + ": " + else: + l_bar = '' + + r_bar = f'| {n_fmt}/{total_fmt} [{elapsed_str}<{remaining_str}, {rate_fmt}{postfix}]' + + # Custom bar formatting + # Populate a dict with all available progress indicators + format_dict = { + # slight extension of self.format_dict + 'n': n, 'n_fmt': n_fmt, 'total': total, 'total_fmt': total_fmt, + 'elapsed': elapsed_str, 'elapsed_s': elapsed, + 'ncols': ncols, 'desc': prefix or '', 'unit': unit, + 'rate': inv_rate if inv_rate and inv_rate > 1 else rate, + 'rate_fmt': rate_fmt, 'rate_noinv': rate, + 'rate_noinv_fmt': rate_noinv_fmt, 'rate_inv': inv_rate, + 'rate_inv_fmt': rate_inv_fmt, + 'postfix': postfix, 'unit_divisor': unit_divisor, + 'colour': colour, + # plus more useful definitions + 'remaining': remaining_str, 'remaining_s': remaining, + 'l_bar': l_bar, 'r_bar': r_bar, 'eta': eta_dt, + **extra_kwargs} + + # total is known: we can predict some stats + if total: + # fractional and percentage progress + frac = n / total + percentage = frac * 100 + + l_bar += f'{percentage:3.0f}%|' + + if ncols == 0: + return l_bar[:-1] + r_bar[1:] + + format_dict.update(l_bar=l_bar) + if bar_format: + format_dict.update(percentage=percentage) + + # auto-remove colon for empty `{desc}` + if not prefix: + bar_format = bar_format.replace("{desc}: ", '') + else: + bar_format = "{l_bar}{bar}{r_bar}" + + full_bar = FormatReplace() + nobar = bar_format.format(bar=full_bar, **format_dict) + if not full_bar.format_called: + return nobar # no `{bar}`; nothing else to do + + # Formatting progress bar space available for bar's display + full_bar = Bar(frac, + max(1, ncols - disp_len(nobar)) if ncols else 10, + charset=Bar.ASCII if ascii is True else ascii or Bar.UTF, + colour=colour) + if not _is_ascii(full_bar.charset) and _is_ascii(bar_format): + bar_format = str(bar_format) + res = bar_format.format(bar=full_bar, **format_dict) + return disp_trim(res, ncols) if ncols else res + + elif bar_format: + # user-specified bar_format but no total + l_bar += '|' + format_dict.update(l_bar=l_bar, percentage=0) + full_bar = FormatReplace() + nobar = bar_format.format(bar=full_bar, **format_dict) + if not full_bar.format_called: + return nobar + full_bar = Bar(0, + max(1, ncols - disp_len(nobar)) if ncols else 10, + charset=Bar.BLANK, colour=colour) + res = bar_format.format(bar=full_bar, **format_dict) + return disp_trim(res, ncols) if ncols else res + else: + # no total: no progressbar, ETA, just progress stats + return (f'{(prefix + ": ") if prefix else ""}' + f'{n_fmt}{unit} [{elapsed_str}, {rate_fmt}{postfix}]') + + def __new__(cls, *_, **__): + instance = object.__new__(cls) + with cls.get_lock(): # also constructs lock if non-existent + cls._instances.add(instance) + # create monitoring thread + if cls.monitor_interval and (cls.monitor is None + or not cls.monitor.report()): + try: + cls.monitor = TMonitor(cls, cls.monitor_interval) + except Exception as e: # pragma: nocover + warn("tqdm:disabling monitor support" + " (monitor_interval = 0) due to:\n" + str(e), + TqdmMonitorWarning, stacklevel=2) + cls.monitor_interval = 0 + return instance + + @classmethod + def _get_free_pos(cls, instance=None): + """Skips specified instance.""" + positions = {abs(inst.pos) for inst in cls._instances + if inst is not instance and hasattr(inst, "pos")} + return min(set(range(len(positions) + 1)).difference(positions)) + + @classmethod + def _decr_instances(cls, instance): + """ + Remove from list and reposition another unfixed bar + to fill the new gap. + + This means that by default (where all nested bars are unfixed), + order is not maintained but screen flicker/blank space is minimised. + (tqdm<=4.44.1 moved ALL subsequent unfixed bars up.) + """ + with cls._lock: + try: + cls._instances.remove(instance) + except KeyError: + # if not instance.gui: # pragma: no cover + # raise + pass # py2: maybe magically removed already + # else: + if not instance.gui: + last = (instance.nrows or 20) - 1 + # find unfixed (`pos >= 0`) overflow (`pos >= nrows - 1`) + instances = list(filter( + lambda i: hasattr(i, "pos") and last <= i.pos, + cls._instances)) + # set first found to current `pos` + if instances: + inst = min(instances, key=lambda i: i.pos) + inst.clear(nolock=True) + inst.pos = abs(instance.pos) + + @classmethod + def write(cls, s, file=None, end="\n", nolock=False): + """Print a message via tqdm (without overlap with bars).""" + fp = file if file is not None else sys.stdout + with cls.external_write_mode(file=file, nolock=nolock): + # Write the message + fp.write(s) + fp.write(end) + + @classmethod + @contextmanager + def external_write_mode(cls, file=None, nolock=False): + """ + Disable tqdm within context and refresh tqdm when exits. + Useful when writing to standard output stream + """ + fp = file if file is not None else sys.stdout + + try: + if not nolock: + cls.get_lock().acquire() + # Clear all bars + inst_cleared = [] + for inst in getattr(cls, '_instances', []): + # Clear instance if in the target output file + # or if write output + tqdm output are both either + # sys.stdout or sys.stderr (because both are mixed in terminal) + if hasattr(inst, "start_t") and (inst.fp == fp or all( + f in (sys.stdout, sys.stderr) for f in (fp, inst.fp))): + inst.clear(nolock=True) + inst_cleared.append(inst) + yield + # Force refresh display of bars we cleared + for inst in inst_cleared: + inst.refresh(nolock=True) + finally: + if not nolock: + cls._lock.release() + + @classmethod + def set_lock(cls, lock): + """Set the global lock.""" + cls._lock = lock + + @classmethod + def get_lock(cls): + """Get the global lock. Construct it if it does not exist.""" + if not hasattr(cls, '_lock'): + cls._lock = TqdmDefaultWriteLock() + return cls._lock + + @classmethod + def pandas(cls, **tqdm_kwargs): + """ + Registers the current `tqdm` class with + pandas.core. + ( frame.DataFrame + | series.Series + | groupby.(generic.)DataFrameGroupBy + | groupby.(generic.)SeriesGroupBy + ).progress_apply + + A new instance will be created every time `progress_apply` is called, + and each instance will automatically `close()` upon completion. + + Parameters + ---------- + tqdm_kwargs : arguments for the tqdm instance + + Examples + -------- + >>> import pandas as pd + >>> import numpy as np + >>> from tqdm import tqdm + >>> from tqdm.gui import tqdm as tqdm_gui + >>> + >>> df = pd.DataFrame(np.random.randint(0, 100, (100000, 6))) + >>> tqdm.pandas(ncols=50) # can use tqdm_gui, optional kwargs, etc + >>> # Now you can use `progress_apply` instead of `apply` + >>> df.groupby(0).progress_apply(lambda x: x**2) + + References + ---------- + <https://stackoverflow.com/questions/18603270/\ + progress-indicator-during-pandas-operations-python> + """ + from warnings import catch_warnings, simplefilter + + from pandas.core.frame import DataFrame + from pandas.core.series import Series + try: + with catch_warnings(): + simplefilter("ignore", category=FutureWarning) + from pandas import Panel + except ImportError: # pandas>=1.2.0 + Panel = None + Rolling, Expanding = None, None + try: # pandas>=1.0.0 + from pandas.core.window.rolling import _Rolling_and_Expanding + except ImportError: + try: # pandas>=0.18.0 + from pandas.core.window import _Rolling_and_Expanding + except ImportError: # pandas>=1.2.0 + try: # pandas>=1.2.0 + from pandas.core.window.expanding import Expanding + from pandas.core.window.rolling import Rolling + _Rolling_and_Expanding = Rolling, Expanding + except ImportError: # pragma: no cover + _Rolling_and_Expanding = None + try: # pandas>=0.25.0 + from pandas.core.groupby.generic import SeriesGroupBy # , NDFrameGroupBy + from pandas.core.groupby.generic import DataFrameGroupBy + except ImportError: # pragma: no cover + try: # pandas>=0.23.0 + from pandas.core.groupby.groupby import DataFrameGroupBy, SeriesGroupBy + except ImportError: + from pandas.core.groupby import DataFrameGroupBy, SeriesGroupBy + try: # pandas>=0.23.0 + from pandas.core.groupby.groupby import GroupBy + except ImportError: # pragma: no cover + from pandas.core.groupby import GroupBy + + try: # pandas>=0.23.0 + from pandas.core.groupby.groupby import PanelGroupBy + except ImportError: + try: + from pandas.core.groupby import PanelGroupBy + except ImportError: # pandas>=0.25.0 + PanelGroupBy = None + + tqdm_kwargs = tqdm_kwargs.copy() + deprecated_t = [tqdm_kwargs.pop('deprecated_t', None)] + + def inner_generator(df_function='apply'): + def inner(df, func, *args, **kwargs): + """ + Parameters + ---------- + df : (DataFrame|Series)[GroupBy] + Data (may be grouped). + func : function + To be applied on the (grouped) data. + **kwargs : optional + Transmitted to `df.apply()`. + """ + + # Precompute total iterations + total = tqdm_kwargs.pop("total", getattr(df, 'ngroups', None)) + if total is None: # not grouped + if df_function == 'applymap': + total = df.size + elif isinstance(df, Series): + total = len(df) + elif (_Rolling_and_Expanding is None or + not isinstance(df, _Rolling_and_Expanding)): + # DataFrame or Panel + axis = kwargs.get('axis', 0) + if axis == 'index': + axis = 0 + elif axis == 'columns': + axis = 1 + # when axis=0, total is shape[axis1] + total = df.size // df.shape[axis] + + # Init bar + if deprecated_t[0] is not None: + t = deprecated_t[0] + deprecated_t[0] = None + else: + t = cls(total=total, **tqdm_kwargs) + + if len(args) > 0: + # *args intentionally not supported (see #244, #299) + TqdmDeprecationWarning( + "Except func, normal arguments are intentionally" + + " not supported by" + + " `(DataFrame|Series|GroupBy).progress_apply`." + + " Use keyword arguments instead.", + fp_write=getattr(t.fp, 'write', sys.stderr.write)) + + try: # pandas>=1.3.0 + from pandas.core.common import is_builtin_func + except ImportError: + is_builtin_func = df._is_builtin_func + try: + func = is_builtin_func(func) + except TypeError: + pass + + # Define bar updating wrapper + def wrapper(*args, **kwargs): + # update tbar correctly + # it seems `pandas apply` calls `func` twice + # on the first column/row to decide whether it can + # take a fast or slow code path; so stop when t.total==t.n + t.update(n=1 if not t.total or t.n < t.total else 0) + return func(*args, **kwargs) + + # Apply the provided function (in **kwargs) + # on the df using our wrapper (which provides bar updating) + try: + return getattr(df, df_function)(wrapper, **kwargs) + finally: + t.close() + + return inner + + # Monkeypatch pandas to provide easy methods + # Enable custom tqdm progress in pandas! + Series.progress_apply = inner_generator() + SeriesGroupBy.progress_apply = inner_generator() + Series.progress_map = inner_generator('map') + SeriesGroupBy.progress_map = inner_generator('map') + + DataFrame.progress_apply = inner_generator() + DataFrameGroupBy.progress_apply = inner_generator() + DataFrame.progress_applymap = inner_generator('applymap') + DataFrame.progress_map = inner_generator('map') + DataFrameGroupBy.progress_map = inner_generator('map') + + if Panel is not None: + Panel.progress_apply = inner_generator() + if PanelGroupBy is not None: + PanelGroupBy.progress_apply = inner_generator() + + GroupBy.progress_apply = inner_generator() + GroupBy.progress_aggregate = inner_generator('aggregate') + GroupBy.progress_transform = inner_generator('transform') + + if Rolling is not None and Expanding is not None: + Rolling.progress_apply = inner_generator() + Expanding.progress_apply = inner_generator() + elif _Rolling_and_Expanding is not None: + _Rolling_and_Expanding.progress_apply = inner_generator() + + # override defaults via env vars + @envwrap("TQDM_", is_method=True, types={'total': float, 'ncols': int, 'miniters': float, + 'position': int, 'nrows': int}) + def __init__(self, iterable=None, desc=None, total=None, leave=True, file=None, + ncols=None, mininterval=0.1, maxinterval=10.0, miniters=None, + ascii=None, disable=False, unit='it', unit_scale=False, + dynamic_ncols=False, smoothing=0.3, bar_format=None, initial=0, + position=None, postfix=None, unit_divisor=1000, write_bytes=False, + lock_args=None, nrows=None, colour=None, delay=0.0, gui=False, + **kwargs): + """see tqdm.tqdm for arguments""" + if file is None: + file = sys.stderr + + if write_bytes: + # Despite coercing unicode into bytes, py2 sys.std* streams + # should have bytes written to them. + file = SimpleTextIOWrapper( + file, encoding=getattr(file, 'encoding', None) or 'utf-8') + + file = DisableOnWriteError(file, tqdm_instance=self) + + if disable is None and hasattr(file, "isatty") and not file.isatty(): + disable = True + + if total is None and iterable is not None: + try: + total = len(iterable) + except (TypeError, AttributeError): + total = None + if total == float("inf"): + # Infinite iterations, behave same as unknown + total = None + + if disable: + self.iterable = iterable + self.disable = disable + with self._lock: + self.pos = self._get_free_pos(self) + self._instances.remove(self) + self.n = initial + self.total = total + self.leave = leave + return + + if kwargs: + self.disable = True + with self._lock: + self.pos = self._get_free_pos(self) + self._instances.remove(self) + raise ( + TqdmDeprecationWarning( + "`nested` is deprecated and automated.\n" + "Use `position` instead for manual control.\n", + fp_write=getattr(file, 'write', sys.stderr.write)) + if "nested" in kwargs else + TqdmKeyError("Unknown argument(s): " + str(kwargs))) + + # Preprocess the arguments + if ( + (ncols is None or nrows is None) and (file in (sys.stderr, sys.stdout)) + ) or dynamic_ncols: # pragma: no cover + if dynamic_ncols: + dynamic_ncols = _screen_shape_wrapper() + if dynamic_ncols: + ncols, nrows = dynamic_ncols(file) + else: + _dynamic_ncols = _screen_shape_wrapper() + if _dynamic_ncols: + _ncols, _nrows = _dynamic_ncols(file) + if ncols is None: + ncols = _ncols + if nrows is None: + nrows = _nrows + + if miniters is None: + miniters = 0 + dynamic_miniters = True + else: + dynamic_miniters = False + + if mininterval is None: + mininterval = 0 + + if maxinterval is None: + maxinterval = 0 + + if ascii is None: + ascii = not _supports_unicode(file) + + if bar_format and ascii is not True and not _is_ascii(ascii): + # Convert bar format into unicode since terminal uses unicode + bar_format = str(bar_format) + + if smoothing is None: + smoothing = 0 + + # Store the arguments + self.iterable = iterable + self.desc = desc or '' + self.total = total + self.leave = leave + self.fp = file + self.ncols = ncols + self.nrows = nrows + self.mininterval = mininterval + self.maxinterval = maxinterval + self.miniters = miniters + self.dynamic_miniters = dynamic_miniters + self.ascii = ascii + self.disable = disable + self.unit = unit + self.unit_scale = unit_scale + self.unit_divisor = unit_divisor + self.initial = initial + self.lock_args = lock_args + self.delay = delay + self.gui = gui + self.dynamic_ncols = dynamic_ncols + self.smoothing = smoothing + self._ema_dn = EMA(smoothing) + self._ema_dt = EMA(smoothing) + self._ema_miniters = EMA(smoothing) + self.bar_format = bar_format + self.postfix = None + self.colour = colour + self._time = time + if postfix: + try: + self.set_postfix(refresh=False, **postfix) + except TypeError: + self.postfix = postfix + + # Init the iterations counters + self.last_print_n = initial + self.n = initial + + # if nested, at initial sp() call we replace '\r' by '\n' to + # not overwrite the outer progress bar + with self._lock: + # mark fixed positions as negative + self.pos = self._get_free_pos(self) if position is None else -position + + if not gui: + # Initialize the screen printer + self.sp = self.status_printer(self.fp) + if delay <= 0: + self.refresh(lock_args=self.lock_args) + + # Init the time counter + self.last_print_t = self._time() + # NB: Avoid race conditions by setting start_t at the very end of init + self.start_t = self.last_print_t + + def __bool__(self): + if self.total is not None: + return self.total > 0 + if self.iterable is None: + raise TypeError('bool() undefined when iterable == total == None') + return bool(self.iterable) + + def __len__(self): + return ( + self.total if self.iterable is None + else self.iterable.shape[0] if hasattr(self.iterable, "shape") + else len(self.iterable) if hasattr(self.iterable, "__len__") + else self.iterable.__length_hint__() if hasattr(self.iterable, "__length_hint__") + else getattr(self, "total", None)) + + def __reversed__(self): + try: + orig = self.iterable + except AttributeError: + raise TypeError("'tqdm' object is not reversible") + else: + self.iterable = reversed(self.iterable) + return self.__iter__() + finally: + self.iterable = orig + + def __contains__(self, item): + contains = getattr(self.iterable, '__contains__', None) + return contains(item) if contains is not None else item in self.__iter__() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + try: + self.close() + except AttributeError: + # maybe eager thread cleanup upon external error + if (exc_type, exc_value, traceback) == (None, None, None): + raise + warn("AttributeError ignored", TqdmWarning, stacklevel=2) + + def __del__(self): + self.close() + + def __str__(self): + return self.format_meter(**self.format_dict) + + @property + def _comparable(self): + return abs(getattr(self, "pos", 1 << 31)) + + def __hash__(self): + return id(self) + + def __iter__(self): + """Backward-compatibility to use: for x in tqdm(iterable)""" + + # Inlining instance variables as locals (speed optimisation) + iterable = self.iterable + + # If the bar is disabled, then just walk the iterable + # (note: keep this check outside the loop for performance) + if self.disable: + for obj in iterable: + yield obj + return + + mininterval = self.mininterval + last_print_t = self.last_print_t + last_print_n = self.last_print_n + min_start_t = self.start_t + self.delay + n = self.n + time = self._time + + try: + for obj in iterable: + yield obj + # Update and possibly print the progressbar. + # Note: does not call self.update(1) for speed optimisation. + n += 1 + + if n - last_print_n >= self.miniters: + cur_t = time() + dt = cur_t - last_print_t + if dt >= mininterval and cur_t >= min_start_t: + self.update(n - last_print_n) + last_print_n = self.last_print_n + last_print_t = self.last_print_t + finally: + self.n = n + self.close() + + def update(self, n=1): + """ + Manually update the progress bar, useful for streams + such as reading files. + E.g.: + >>> t = tqdm(total=filesize) # Initialise + >>> for current_buffer in stream: + ... ... + ... t.update(len(current_buffer)) + >>> t.close() + The last line is highly recommended, but possibly not necessary if + `t.update()` will be called in such a way that `filesize` will be + exactly reached and printed. + + Parameters + ---------- + n : int or float, optional + Increment to add to the internal counter of iterations + [default: 1]. If using float, consider specifying `{n:.3f}` + or similar in `bar_format`, or specifying `unit_scale`. + + Returns + ------- + out : bool or None + True if a `display()` was triggered. + """ + if self.disable: + return + + if n < 0: + self.last_print_n += n # for auto-refresh logic to work + self.n += n + + # check counter first to reduce calls to time() + if self.n - self.last_print_n >= self.miniters: + cur_t = self._time() + dt = cur_t - self.last_print_t + if dt >= self.mininterval and cur_t >= self.start_t + self.delay: + cur_t = self._time() + dn = self.n - self.last_print_n # >= n + if self.smoothing and dt and dn: + # EMA (not just overall average) + self._ema_dn(dn) + self._ema_dt(dt) + self.refresh(lock_args=self.lock_args) + if self.dynamic_miniters: + # If no `miniters` was specified, adjust automatically to the + # maximum iteration rate seen so far between two prints. + # e.g.: After running `tqdm.update(5)`, subsequent + # calls to `tqdm.update()` will only cause an update after + # at least 5 more iterations. + if self.maxinterval and dt >= self.maxinterval: + self.miniters = dn * (self.mininterval or self.maxinterval) / dt + elif self.smoothing: + # EMA miniters update + self.miniters = self._ema_miniters( + dn * (self.mininterval / dt if self.mininterval and dt + else 1)) + else: + # max iters between two prints + self.miniters = max(self.miniters, dn) + + # Store old values for next call + self.last_print_n = self.n + self.last_print_t = cur_t + return True + + def close(self): + """Cleanup and (if leave=False) close the progressbar.""" + if self.disable: + return + + # Prevent multiple closures + self.disable = True + + # decrement instance pos and remove from internal set + pos = abs(self.pos) + self._decr_instances(self) + + if self.last_print_t < self.start_t + self.delay: + # haven't ever displayed; nothing to clear + return + + # GUI mode + if getattr(self, 'sp', None) is None: + return + + # annoyingly, _supports_unicode isn't good enough + def fp_write(s): + self.fp.write(str(s)) + + try: + fp_write('') + except ValueError as e: + if 'closed' in str(e): + return + raise # pragma: no cover + + leave = pos == 0 if self.leave is None else self.leave + + with self._lock: + if leave: + # stats for overall rate (no weighted average) + self._ema_dt = lambda: None + self.display(pos=0) + fp_write('\n') + else: + # clear previous display + if self.display(msg='', pos=pos) and not pos: + fp_write('\r') + + def clear(self, nolock=False): + """Clear current bar display.""" + if self.disable: + return + + if not nolock: + self._lock.acquire() + pos = abs(self.pos) + if pos < (self.nrows or 20): + self.moveto(pos) + self.sp('') + self.fp.write('\r') # place cursor back at the beginning of line + self.moveto(-pos) + if not nolock: + self._lock.release() + + def refresh(self, nolock=False, lock_args=None): + """ + Force refresh the display of this bar. + + Parameters + ---------- + nolock : bool, optional + If `True`, does not lock. + If [default: `False`]: calls `acquire()` on internal lock. + lock_args : tuple, optional + Passed to internal lock's `acquire()`. + If specified, will only `display()` if `acquire()` returns `True`. + """ + if self.disable: + return + + if not nolock: + if lock_args: + if not self._lock.acquire(*lock_args): + return False + else: + self._lock.acquire() + self.display() + if not nolock: + self._lock.release() + return True + + def unpause(self): + """Restart tqdm timer from last print time.""" + if self.disable: + return + cur_t = self._time() + self.start_t += cur_t - self.last_print_t + self.last_print_t = cur_t + + def reset(self, total=None): + """ + Resets to 0 iterations for repeated use. + + Consider combining with `leave=True`. + + Parameters + ---------- + total : int or float, optional. Total to use for the new bar. + """ + self.n = 0 + if total is not None: + self.total = total + if self.disable: + return + self.last_print_n = 0 + self.last_print_t = self.start_t = self._time() + self._ema_dn = EMA(self.smoothing) + self._ema_dt = EMA(self.smoothing) + self._ema_miniters = EMA(self.smoothing) + self.refresh() + + def set_description(self, desc=None, refresh=True): + """ + Set/modify description of the progress bar. + + Parameters + ---------- + desc : str, optional + refresh : bool, optional + Forces refresh [default: True]. + """ + self.desc = desc + ': ' if desc else '' + if refresh: + self.refresh() + + def set_description_str(self, desc=None, refresh=True): + """Set/modify description without ': ' appended.""" + self.desc = desc or '' + if refresh: + self.refresh() + + def set_postfix(self, ordered_dict=None, refresh=True, **kwargs): + """ + Set/modify postfix (additional stats) + with automatic formatting based on datatype. + + Parameters + ---------- + ordered_dict : dict or OrderedDict, optional + refresh : bool, optional + Forces refresh [default: True]. + kwargs : dict, optional + """ + # Sort in alphabetical order to be more deterministic + postfix = OrderedDict([] if ordered_dict is None else ordered_dict) + for key in sorted(kwargs.keys()): + postfix[key] = kwargs[key] + # Preprocess stats according to datatype + for key in postfix.keys(): + # Number: limit the length of the string + if isinstance(postfix[key], Number): + postfix[key] = self.format_num(postfix[key]) + # Else for any other type, try to get the string conversion + elif not isinstance(postfix[key], str): + postfix[key] = str(postfix[key]) + # Else if it's a string, don't need to preprocess anything + # Stitch together to get the final postfix + self.postfix = ', '.join(key + '=' + postfix[key].strip() + for key in postfix.keys()) + if refresh: + self.refresh() + + def set_postfix_str(self, s='', refresh=True): + """ + Postfix without dictionary expansion, similar to prefix handling. + """ + self.postfix = str(s) + if refresh: + self.refresh() + + def moveto(self, n): + # TODO: private method + self.fp.write('\n' * n + _term_move_up() * -n) + getattr(self.fp, 'flush', lambda: None)() + + @property + def format_dict(self): + """Public API for read-only member access.""" + if self.disable and not hasattr(self, 'unit'): + return defaultdict(lambda: None, { + 'n': self.n, 'total': self.total, 'elapsed': 0, 'unit': 'it'}) + if self.dynamic_ncols: + self.ncols, self.nrows = self.dynamic_ncols(self.fp) + return { + 'n': self.n, 'total': self.total, + 'elapsed': self._time() - self.start_t if hasattr(self, 'start_t') else 0, + 'ncols': self.ncols, 'nrows': self.nrows, 'prefix': self.desc, + 'ascii': self.ascii, 'unit': self.unit, 'unit_scale': self.unit_scale, + 'rate': self._ema_dn() / self._ema_dt() if self._ema_dt() else None, + 'bar_format': self.bar_format, 'postfix': self.postfix, + 'unit_divisor': self.unit_divisor, 'initial': self.initial, + 'colour': self.colour} + + def display(self, msg=None, pos=None): + """ + Use `self.sp` to display `msg` in the specified `pos`. + + Consider overloading this function when inheriting to use e.g.: + `self.some_frontend(**self.format_dict)` instead of `self.sp`. + + Parameters + ---------- + msg : str, optional. What to display (default: `repr(self)`). + pos : int, optional. Position to `moveto` + (default: `abs(self.pos)`). + """ + if pos is None: + pos = abs(self.pos) + + nrows = self.nrows or 20 + if pos >= nrows - 1: + if pos >= nrows: + return False + if msg or msg is None: # override at `nrows - 1` + msg = " ... (more hidden) ..." + + if not hasattr(self, "sp"): + raise TqdmDeprecationWarning( + "Please use `tqdm.gui.tqdm(...)`" + " instead of `tqdm(..., gui=True)`\n", + fp_write=getattr(self.fp, 'write', sys.stderr.write)) + + if pos: + self.moveto(pos) + self.sp(self.__str__() if msg is None else msg) + if pos: + self.moveto(-pos) + return True + + @classmethod + @contextmanager + def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs): + """ + stream : file-like object. + method : str, "read" or "write". The result of `read()` and + the first argument of `write()` should have a `len()`. + + >>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj: + ... while True: + ... chunk = fobj.read(chunk_size) + ... if not chunk: + ... break + """ + with cls(total=total, **tqdm_kwargs) as t: + if bytes: + t.unit = "B" + t.unit_scale = True + t.unit_divisor = 1024 + yield CallbackIOWrapper(t.update, stream, method) + + +def trange(*args, **kwargs): + """Shortcut for tqdm(range(*args), **kwargs).""" + return tqdm(range(*args), **kwargs) diff --git a/.venv/lib/python3.12/site-packages/tqdm/tk.py b/.venv/lib/python3.12/site-packages/tqdm/tk.py new file mode 100644 index 00000000..788303c8 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/tk.py @@ -0,0 +1,196 @@ +""" +Tkinter GUI progressbar decorator for iterators. + +Usage: +>>> from tqdm.tk import trange, tqdm +>>> for i in trange(10): +... ... +""" +import re +import sys +import tkinter +import tkinter.ttk as ttk +from warnings import warn + +from .std import TqdmExperimentalWarning, TqdmWarning +from .std import tqdm as std_tqdm + +__author__ = {"github.com/": ["richardsheridan", "casperdcl"]} +__all__ = ['tqdm_tk', 'ttkrange', 'tqdm', 'trange'] + + +class tqdm_tk(std_tqdm): # pragma: no cover + """ + Experimental Tkinter GUI version of tqdm! + + Note: Window interactivity suffers if `tqdm_tk` is not running within + a Tkinter mainloop and values are generated infrequently. In this case, + consider calling `tqdm_tk.refresh()` frequently in the Tk thread. + """ + + # TODO: @classmethod: write()? + + def __init__(self, *args, **kwargs): + """ + This class accepts the following parameters *in addition* to + the parameters accepted by `tqdm`. + + Parameters + ---------- + grab : bool, optional + Grab the input across all windows of the process. + tk_parent : `tkinter.Wm`, optional + Parent Tk window. + cancel_callback : Callable, optional + Create a cancel button and set `cancel_callback` to be called + when the cancel or window close button is clicked. + """ + kwargs = kwargs.copy() + kwargs['gui'] = True + # convert disable = None to False + kwargs['disable'] = bool(kwargs.get('disable', False)) + self._warn_leave = 'leave' in kwargs + grab = kwargs.pop('grab', False) + tk_parent = kwargs.pop('tk_parent', None) + self._cancel_callback = kwargs.pop('cancel_callback', None) + super().__init__(*args, **kwargs) + + if self.disable: + return + + if tk_parent is None: # Discover parent widget + try: + tk_parent = tkinter._default_root + except AttributeError: + raise AttributeError( + "`tk_parent` required when using `tkinter.NoDefaultRoot()`") + if tk_parent is None: # use new default root window as display + self._tk_window = tkinter.Tk() + else: # some other windows already exist + self._tk_window = tkinter.Toplevel() + else: + self._tk_window = tkinter.Toplevel(tk_parent) + + warn("GUI is experimental/alpha", TqdmExperimentalWarning, stacklevel=2) + self._tk_dispatching = self._tk_dispatching_helper() + + self._tk_window.protocol("WM_DELETE_WINDOW", self.cancel) + self._tk_window.wm_title(self.desc) + self._tk_window.wm_attributes("-topmost", 1) + self._tk_window.after(0, lambda: self._tk_window.wm_attributes("-topmost", 0)) + self._tk_n_var = tkinter.DoubleVar(self._tk_window, value=0) + self._tk_text_var = tkinter.StringVar(self._tk_window) + pbar_frame = ttk.Frame(self._tk_window, padding=5) + pbar_frame.pack() + _tk_label = ttk.Label(pbar_frame, textvariable=self._tk_text_var, + wraplength=600, anchor="center", justify="center") + _tk_label.pack() + self._tk_pbar = ttk.Progressbar( + pbar_frame, variable=self._tk_n_var, length=450) + if self.total is not None: + self._tk_pbar.configure(maximum=self.total) + else: + self._tk_pbar.configure(mode="indeterminate") + self._tk_pbar.pack() + if self._cancel_callback is not None: + _tk_button = ttk.Button(pbar_frame, text="Cancel", command=self.cancel) + _tk_button.pack() + if grab: + self._tk_window.grab_set() + + def close(self): + if self.disable: + return + + self.disable = True + + with self.get_lock(): + self._instances.remove(self) + + def _close(): + self._tk_window.after('idle', self._tk_window.destroy) + if not self._tk_dispatching: + self._tk_window.update() + + self._tk_window.protocol("WM_DELETE_WINDOW", _close) + + # if leave is set but we are self-dispatching, the left window is + # totally unresponsive unless the user manually dispatches + if not self.leave: + _close() + elif not self._tk_dispatching: + if self._warn_leave: + warn("leave flag ignored if not in tkinter mainloop", + TqdmWarning, stacklevel=2) + _close() + + def clear(self, *_, **__): + pass + + def display(self, *_, **__): + self._tk_n_var.set(self.n) + d = self.format_dict + # remove {bar} + d['bar_format'] = (d['bar_format'] or "{l_bar}<bar/>{r_bar}").replace( + "{bar}", "<bar/>") + msg = self.format_meter(**d) + if '<bar/>' in msg: + msg = "".join(re.split(r'\|?<bar/>\|?', msg, maxsplit=1)) + self._tk_text_var.set(msg) + if not self._tk_dispatching: + self._tk_window.update() + + def set_description(self, desc=None, refresh=True): + self.set_description_str(desc, refresh) + + def set_description_str(self, desc=None, refresh=True): + self.desc = desc + if not self.disable: + self._tk_window.wm_title(desc) + if refresh and not self._tk_dispatching: + self._tk_window.update() + + def cancel(self): + """ + `cancel_callback()` followed by `close()` + when close/cancel buttons clicked. + """ + if self._cancel_callback is not None: + self._cancel_callback() + self.close() + + def reset(self, total=None): + """ + Resets to 0 iterations for repeated use. + + Parameters + ---------- + total : int or float, optional. Total to use for the new bar. + """ + if hasattr(self, '_tk_pbar'): + if total is None: + self._tk_pbar.configure(maximum=100, mode="indeterminate") + else: + self._tk_pbar.configure(maximum=total, mode="determinate") + super().reset(total=total) + + @staticmethod + def _tk_dispatching_helper(): + """determine if Tkinter mainloop is dispatching events""" + codes = {tkinter.mainloop.__code__, tkinter.Misc.mainloop.__code__} + for frame in sys._current_frames().values(): + while frame: + if frame.f_code in codes: + return True + frame = frame.f_back + return False + + +def ttkrange(*args, **kwargs): + """Shortcut for `tqdm.tk.tqdm(range(*args), **kwargs)`.""" + return tqdm_tk(range(*args), **kwargs) + + +# Aliases +tqdm = tqdm_tk +trange = ttkrange diff --git a/.venv/lib/python3.12/site-packages/tqdm/tqdm.1 b/.venv/lib/python3.12/site-packages/tqdm/tqdm.1 new file mode 100644 index 00000000..b90ab4b9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/tqdm.1 @@ -0,0 +1,314 @@ +.\" Automatically generated by Pandoc 1.19.2 +.\" +.TH "TQDM" "1" "2015\-2021" "tqdm User Manuals" "" +.hy +.SH NAME +.PP +tqdm \- fast, extensible progress bar for Python and CLI +.SH SYNOPSIS +.PP +tqdm [\f[I]options\f[]] +.SH DESCRIPTION +.PP +See <https://github.com/tqdm/tqdm>. +Can be used as a pipe: +.IP +.nf +\f[C] +$\ #\ count\ lines\ of\ code +$\ cat\ *.py\ |\ tqdm\ |\ wc\ \-l +327it\ [00:00,\ 981773.38it/s] +327 + +$\ #\ find\ all\ files +$\ find\ .\ \-name\ "*.py"\ |\ tqdm\ |\ wc\ \-l +432it\ [00:00,\ 833842.30it/s] +432 + +#\ ...\ and\ more\ info +$\ find\ .\ \-name\ \[aq]*.py\[aq]\ \-exec\ wc\ \-l\ \\{}\ \\;\ \\ +\ \ |\ tqdm\ \-\-total\ 432\ \-\-unit\ files\ \-\-desc\ counting\ \\ +\ \ |\ awk\ \[aq]{\ sum\ +=\ $1\ };\ END\ {\ print\ sum\ }\[aq] +counting:\ 100%|█████████|\ 432/432\ [00:00<00:00,\ 794361.83files/s] +131998 +\f[] +.fi +.SH OPTIONS +.TP +.B \-h, \-\-help +Print this help and exit. +.RS +.RE +.TP +.B \-v, \-\-version +Print version and exit. +.RS +.RE +.TP +.B \-\-desc=\f[I]desc\f[] +str, optional. +Prefix for the progressbar. +.RS +.RE +.TP +.B \-\-total=\f[I]total\f[] +int or float, optional. +The number of expected iterations. +If unspecified, len(iterable) is used if possible. +If float("inf") or as a last resort, only basic progress statistics are +displayed (no ETA, no progressbar). +If \f[C]gui\f[] is True and this parameter needs subsequent updating, +specify an initial arbitrary large positive number, e.g. +9e9. +.RS +.RE +.TP +.B \-\-leave +bool, optional. +If [default: True], keeps all traces of the progressbar upon termination +of iteration. +If \f[C]None\f[], will leave only if \f[C]position\f[] is \f[C]0\f[]. +.RS +.RE +.TP +.B \-\-ncols=\f[I]ncols\f[] +int, optional. +The width of the entire output message. +If specified, dynamically resizes the progressbar to stay within this +bound. +If unspecified, attempts to use environment width. +The fallback is a meter width of 10 and no limit for the counter and +statistics. +If 0, will not print any meter (only stats). +.RS +.RE +.TP +.B \-\-mininterval=\f[I]mininterval\f[] +float, optional. +Minimum progress display update interval [default: 0.1] seconds. +.RS +.RE +.TP +.B \-\-maxinterval=\f[I]maxinterval\f[] +float, optional. +Maximum progress display update interval [default: 10] seconds. +Automatically adjusts \f[C]miniters\f[] to correspond to +\f[C]mininterval\f[] after long display update lag. +Only works if \f[C]dynamic_miniters\f[] or monitor thread is enabled. +.RS +.RE +.TP +.B \-\-miniters=\f[I]miniters\f[] +int or float, optional. +Minimum progress display update interval, in iterations. +If 0 and \f[C]dynamic_miniters\f[], will automatically adjust to equal +\f[C]mininterval\f[] (more CPU efficient, good for tight loops). +If > 0, will skip display of specified number of iterations. +Tweak this and \f[C]mininterval\f[] to get very efficient loops. +If your progress is erratic with both fast and slow iterations (network, +skipping items, etc) you should set miniters=1. +.RS +.RE +.TP +.B \-\-ascii=\f[I]ascii\f[] +bool or str, optional. +If unspecified or False, use unicode (smooth blocks) to fill the meter. +The fallback is to use ASCII characters " 123456789#". +.RS +.RE +.TP +.B \-\-disable +bool, optional. +Whether to disable the entire progressbar wrapper [default: False]. +If set to None, disable on non\-TTY. +.RS +.RE +.TP +.B \-\-unit=\f[I]unit\f[] +str, optional. +String that will be used to define the unit of each iteration [default: +it]. +.RS +.RE +.TP +.B \-\-unit\-scale=\f[I]unit_scale\f[] +bool or int or float, optional. +If 1 or True, the number of iterations will be reduced/scaled +automatically and a metric prefix following the International System of +Units standard will be added (kilo, mega, etc.) [default: False]. +If any other non\-zero number, will scale \f[C]total\f[] and \f[C]n\f[]. +.RS +.RE +.TP +.B \-\-dynamic\-ncols +bool, optional. +If set, constantly alters \f[C]ncols\f[] and \f[C]nrows\f[] to the +environment (allowing for window resizes) [default: False]. +.RS +.RE +.TP +.B \-\-smoothing=\f[I]smoothing\f[] +float, optional. +Exponential moving average smoothing factor for speed estimates (ignored +in GUI mode). +Ranges from 0 (average speed) to 1 (current/instantaneous speed) +[default: 0.3]. +.RS +.RE +.TP +.B \-\-bar\-format=\f[I]bar_format\f[] +str, optional. +Specify a custom bar string formatting. +May impact performance. +[default: \[aq]{l_bar}{bar}{r_bar}\[aq]], where l_bar=\[aq]{desc}: +{percentage:3.0f}%|\[aq] and r_bar=\[aq]| {n_fmt}/{total_fmt} +[{elapsed}<{remaining}, \[aq] \[aq]{rate_fmt}{postfix}]\[aq] Possible +vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, percentage, +elapsed, elapsed_s, ncols, nrows, desc, unit, rate, rate_fmt, +rate_noinv, rate_noinv_fmt, rate_inv, rate_inv_fmt, postfix, +unit_divisor, remaining, remaining_s, eta. +Note that a trailing ": " is automatically removed after {desc} if the +latter is empty. +.RS +.RE +.TP +.B \-\-initial=\f[I]initial\f[] +int or float, optional. +The initial counter value. +Useful when restarting a progress bar [default: 0]. +If using float, consider specifying \f[C]{n:.3f}\f[] or similar in +\f[C]bar_format\f[], or specifying \f[C]unit_scale\f[]. +.RS +.RE +.TP +.B \-\-position=\f[I]position\f[] +int, optional. +Specify the line offset to print this bar (starting from 0) Automatic if +unspecified. +Useful to manage multiple bars at once (eg, from threads). +.RS +.RE +.TP +.B \-\-postfix=\f[I]postfix\f[] +dict or *, optional. +Specify additional stats to display at the end of the bar. +Calls \f[C]set_postfix(**postfix)\f[] if possible (dict). +.RS +.RE +.TP +.B \-\-unit\-divisor=\f[I]unit_divisor\f[] +float, optional. +[default: 1000], ignored unless \f[C]unit_scale\f[] is True. +.RS +.RE +.TP +.B \-\-write\-bytes +bool, optional. +Whether to write bytes. +If (default: False) will write unicode. +.RS +.RE +.TP +.B \-\-lock\-args=\f[I]lock_args\f[] +tuple, optional. +Passed to \f[C]refresh\f[] for intermediate output (initialisation, +iterating, and updating). +.RS +.RE +.TP +.B \-\-nrows=\f[I]nrows\f[] +int, optional. +The screen height. +If specified, hides nested bars outside this bound. +If unspecified, attempts to use environment height. +The fallback is 20. +.RS +.RE +.TP +.B \-\-colour=\f[I]colour\f[] +str, optional. +Bar colour (e.g. +\[aq]green\[aq], \[aq]#00ff00\[aq]). +.RS +.RE +.TP +.B \-\-delay=\f[I]delay\f[] +float, optional. +Don\[aq]t display until [default: 0] seconds have elapsed. +.RS +.RE +.TP +.B \-\-delim=\f[I]delim\f[] +chr, optional. +Delimiting character [default: \[aq]\\n\[aq]]. +Use \[aq]\\0\[aq] for null. +N.B.: on Windows systems, Python converts \[aq]\\n\[aq] to +\[aq]\\r\\n\[aq]. +.RS +.RE +.TP +.B \-\-buf\-size=\f[I]buf_size\f[] +int, optional. +String buffer size in bytes [default: 256] used when \f[C]delim\f[] is +specified. +.RS +.RE +.TP +.B \-\-bytes +bool, optional. +If true, will count bytes, ignore \f[C]delim\f[], and default +\f[C]unit_scale\f[] to True, \f[C]unit_divisor\f[] to 1024, and +\f[C]unit\f[] to \[aq]B\[aq]. +.RS +.RE +.TP +.B \-\-tee +bool, optional. +If true, passes \f[C]stdin\f[] to both \f[C]stderr\f[] and +\f[C]stdout\f[]. +.RS +.RE +.TP +.B \-\-update +bool, optional. +If true, will treat input as newly elapsed iterations, i.e. +numbers to pass to \f[C]update()\f[]. +Note that this is slow (~2e5 it/s) since every input must be decoded as +a number. +.RS +.RE +.TP +.B \-\-update\-to +bool, optional. +If true, will treat input as total elapsed iterations, i.e. +numbers to assign to \f[C]self.n\f[]. +Note that this is slow (~2e5 it/s) since every input must be decoded as +a number. +.RS +.RE +.TP +.B \-\-null +bool, optional. +If true, will discard input (no stdout). +.RS +.RE +.TP +.B \-\-manpath=\f[I]manpath\f[] +str, optional. +Directory in which to install tqdm man pages. +.RS +.RE +.TP +.B \-\-comppath=\f[I]comppath\f[] +str, optional. +Directory in which to place tqdm completion. +.RS +.RE +.TP +.B \-\-log=\f[I]log\f[] +str, optional. +CRITICAL|FATAL|ERROR|WARN(ING)|[default: \[aq]INFO\[aq]]|DEBUG|NOTSET. +.RS +.RE +.SH AUTHORS +tqdm developers <https://github.com/tqdm>. diff --git a/.venv/lib/python3.12/site-packages/tqdm/utils.py b/.venv/lib/python3.12/site-packages/tqdm/utils.py new file mode 100644 index 00000000..af3ec7de --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/utils.py @@ -0,0 +1,399 @@ +""" +General helpers required for `tqdm.std`. +""" +import os +import re +import sys +from functools import partial, partialmethod, wraps +from inspect import signature +# TODO consider using wcswidth third-party package for 0-width characters +from unicodedata import east_asian_width +from warnings import warn +from weakref import proxy + +_range, _unich, _unicode, _basestring = range, chr, str, str +CUR_OS = sys.platform +IS_WIN = any(CUR_OS.startswith(i) for i in ['win32', 'cygwin']) +IS_NIX = any(CUR_OS.startswith(i) for i in ['aix', 'linux', 'darwin', 'freebsd']) +RE_ANSI = re.compile(r"\x1b\[[;\d]*[A-Za-z]") + +try: + if IS_WIN: + import colorama + else: + raise ImportError +except ImportError: + colorama = None +else: + try: + colorama.init(strip=False) + except TypeError: + colorama.init() + + +def envwrap(prefix, types=None, is_method=False): + """ + Override parameter defaults via `os.environ[prefix + param_name]`. + Maps UPPER_CASE env vars map to lower_case param names. + camelCase isn't supported (because Windows ignores case). + + Precedence (highest first): + + - call (`foo(a=3)`) + - environ (`FOO_A=2`) + - signature (`def foo(a=1)`) + + Parameters + ---------- + prefix : str + Env var prefix, e.g. "FOO_" + types : dict, optional + Fallback mappings `{'param_name': type, ...}` if types cannot be + inferred from function signature. + Consider using `types=collections.defaultdict(lambda: ast.literal_eval)`. + is_method : bool, optional + Whether to use `functools.partialmethod`. If (default: False) use `functools.partial`. + + Examples + -------- + ``` + $ cat foo.py + from tqdm.utils import envwrap + @envwrap("FOO_") + def test(a=1, b=2, c=3): + print(f"received: a={a}, b={b}, c={c}") + + $ FOO_A=42 FOO_C=1337 python -c 'import foo; foo.test(c=99)' + received: a=42, b=2, c=99 + ``` + """ + if types is None: + types = {} + i = len(prefix) + env_overrides = {k[i:].lower(): v for k, v in os.environ.items() if k.startswith(prefix)} + part = partialmethod if is_method else partial + + def wrap(func): + params = signature(func).parameters + # ignore unknown env vars + overrides = {k: v for k, v in env_overrides.items() if k in params} + # infer overrides' `type`s + for k in overrides: + param = params[k] + if param.annotation is not param.empty: # typehints + for typ in getattr(param.annotation, '__args__', (param.annotation,)): + try: + overrides[k] = typ(overrides[k]) + except Exception: + pass + else: + break + elif param.default is not None: # type of default value + overrides[k] = type(param.default)(overrides[k]) + else: + try: # `types` fallback + overrides[k] = types[k](overrides[k]) + except KeyError: # keep unconverted (`str`) + pass + return part(func, **overrides) + return wrap + + +class FormatReplace(object): + """ + >>> a = FormatReplace('something') + >>> f"{a:5d}" + 'something' + """ # NOQA: P102 + def __init__(self, replace=''): + self.replace = replace + self.format_called = 0 + + def __format__(self, _): + self.format_called += 1 + return self.replace + + +class Comparable(object): + """Assumes child has self._comparable attr/@property""" + def __lt__(self, other): + return self._comparable < other._comparable + + def __le__(self, other): + return (self < other) or (self == other) + + def __eq__(self, other): + return self._comparable == other._comparable + + def __ne__(self, other): + return not self == other + + def __gt__(self, other): + return not self <= other + + def __ge__(self, other): + return not self < other + + +class ObjectWrapper(object): + def __getattr__(self, name): + return getattr(self._wrapped, name) + + def __setattr__(self, name, value): + return setattr(self._wrapped, name, value) + + def wrapper_getattr(self, name): + """Actual `self.getattr` rather than self._wrapped.getattr""" + try: + return object.__getattr__(self, name) + except AttributeError: # py2 + return getattr(self, name) + + def wrapper_setattr(self, name, value): + """Actual `self.setattr` rather than self._wrapped.setattr""" + return object.__setattr__(self, name, value) + + def __init__(self, wrapped): + """ + Thin wrapper around a given object + """ + self.wrapper_setattr('_wrapped', wrapped) + + +class SimpleTextIOWrapper(ObjectWrapper): + """ + Change only `.write()` of the wrapped object by encoding the passed + value and passing the result to the wrapped object's `.write()` method. + """ + # pylint: disable=too-few-public-methods + def __init__(self, wrapped, encoding): + super().__init__(wrapped) + self.wrapper_setattr('encoding', encoding) + + def write(self, s): + """ + Encode `s` and pass to the wrapped object's `.write()` method. + """ + return self._wrapped.write(s.encode(self.wrapper_getattr('encoding'))) + + def __eq__(self, other): + return self._wrapped == getattr(other, '_wrapped', other) + + +class DisableOnWriteError(ObjectWrapper): + """ + Disable the given `tqdm_instance` upon `write()` or `flush()` errors. + """ + @staticmethod + def disable_on_exception(tqdm_instance, func): + """ + Quietly set `tqdm_instance.miniters=inf` if `func` raises `errno=5`. + """ + tqdm_instance = proxy(tqdm_instance) + + def inner(*args, **kwargs): + try: + return func(*args, **kwargs) + except OSError as e: + if e.errno != 5: + raise + try: + tqdm_instance.miniters = float('inf') + except ReferenceError: + pass + except ValueError as e: + if 'closed' not in str(e): + raise + try: + tqdm_instance.miniters = float('inf') + except ReferenceError: + pass + return inner + + def __init__(self, wrapped, tqdm_instance): + super().__init__(wrapped) + if hasattr(wrapped, 'write'): + self.wrapper_setattr( + 'write', self.disable_on_exception(tqdm_instance, wrapped.write)) + if hasattr(wrapped, 'flush'): + self.wrapper_setattr( + 'flush', self.disable_on_exception(tqdm_instance, wrapped.flush)) + + def __eq__(self, other): + return self._wrapped == getattr(other, '_wrapped', other) + + +class CallbackIOWrapper(ObjectWrapper): + def __init__(self, callback, stream, method="read"): + """ + Wrap a given `file`-like object's `read()` or `write()` to report + lengths to the given `callback` + """ + super().__init__(stream) + func = getattr(stream, method) + if method == "write": + @wraps(func) + def write(data, *args, **kwargs): + res = func(data, *args, **kwargs) + callback(len(data)) + return res + self.wrapper_setattr('write', write) + elif method == "read": + @wraps(func) + def read(*args, **kwargs): + data = func(*args, **kwargs) + callback(len(data)) + return data + self.wrapper_setattr('read', read) + else: + raise KeyError("Can only wrap read/write methods") + + +def _is_utf(encoding): + try: + u'\u2588\u2589'.encode(encoding) + except UnicodeEncodeError: + return False + except Exception: + try: + return encoding.lower().startswith('utf-') or ('U8' == encoding) + except Exception: + return False + else: + return True + + +def _supports_unicode(fp): + try: + return _is_utf(fp.encoding) + except AttributeError: + return False + + +def _is_ascii(s): + if isinstance(s, str): + for c in s: + if ord(c) > 255: + return False + return True + return _supports_unicode(s) + + +def _screen_shape_wrapper(): # pragma: no cover + """ + Return a function which returns console dimensions (width, height). + Supported: linux, osx, windows, cygwin. + """ + _screen_shape = None + if IS_WIN: + _screen_shape = _screen_shape_windows + if _screen_shape is None: + _screen_shape = _screen_shape_tput + if IS_NIX: + _screen_shape = _screen_shape_linux + return _screen_shape + + +def _screen_shape_windows(fp): # pragma: no cover + try: + import struct + from ctypes import create_string_buffer, windll + from sys import stdin, stdout + + io_handle = -12 # assume stderr + if fp == stdin: + io_handle = -10 + elif fp == stdout: + io_handle = -11 + + h = windll.kernel32.GetStdHandle(io_handle) + csbi = create_string_buffer(22) + res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi) + if res: + (_bufx, _bufy, _curx, _cury, _wattr, left, top, right, bottom, + _maxx, _maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw) + return right - left, bottom - top # +1 + except Exception: # nosec + pass + return None, None + + +def _screen_shape_tput(*_): # pragma: no cover + """cygwin xterm (windows)""" + try: + import shlex + from subprocess import check_call # nosec + return [int(check_call(shlex.split('tput ' + i))) - 1 + for i in ('cols', 'lines')] + except Exception: # nosec + pass + return None, None + + +def _screen_shape_linux(fp): # pragma: no cover + + try: + from array import array + from fcntl import ioctl + from termios import TIOCGWINSZ + except ImportError: + return None, None + else: + try: + rows, cols = array('h', ioctl(fp, TIOCGWINSZ, '\0' * 8))[:2] + return cols, rows + except Exception: + try: + return [int(os.environ[i]) - 1 for i in ("COLUMNS", "LINES")] + except (KeyError, ValueError): + return None, None + + +def _environ_cols_wrapper(): # pragma: no cover + """ + Return a function which returns console width. + Supported: linux, osx, windows, cygwin. + """ + warn("Use `_screen_shape_wrapper()(file)[0]` instead of" + " `_environ_cols_wrapper()(file)`", DeprecationWarning, stacklevel=2) + shape = _screen_shape_wrapper() + if not shape: + return None + + @wraps(shape) + def inner(fp): + return shape(fp)[0] + + return inner + + +def _term_move_up(): # pragma: no cover + return '' if (os.name == 'nt') and (colorama is None) else '\x1b[A' + + +def _text_width(s): + return sum(2 if east_asian_width(ch) in 'FW' else 1 for ch in str(s)) + + +def disp_len(data): + """ + Returns the real on-screen length of a string which may contain + ANSI control codes and wide chars. + """ + return _text_width(RE_ANSI.sub('', data)) + + +def disp_trim(data, length): + """ + Trim a string which may contain ANSI control characters. + """ + if len(data) == disp_len(data): + return data[:length] + + ansi_present = bool(RE_ANSI.search(data)) + while disp_len(data) > length: # carefully delete one char at a time + data = data[:-1] + if ansi_present and bool(RE_ANSI.search(data)): + # assume ANSI reset is required + return data if data.endswith("\033[0m") else data + "\033[0m" + return data diff --git a/.venv/lib/python3.12/site-packages/tqdm/version.py b/.venv/lib/python3.12/site-packages/tqdm/version.py new file mode 100644 index 00000000..11cbaea7 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/tqdm/version.py @@ -0,0 +1,9 @@ +"""`tqdm` version detector. Precedence: installed dist, git, 'UNKNOWN'.""" +try: + from ._dist_ver import __version__ +except ImportError: + try: + from setuptools_scm import get_version + __version__ = get_version(root='..', relative_to=__file__) + except (ImportError, LookupError): + __version__ = "UNKNOWN" diff --git a/app.py b/app.py index 19d74cef..c1bb418f 100644 --- a/app.py +++ b/app.py @@ -1,23 +1,10 @@ -from flask import Flask, request, render_template, send_file, session -import pandas as pd -import io -import os -from statsmodels.tsa.seasonal import seasonal_decompose -from statsmodels.graphics.tsaplots import plot_acf, plot_pacf -import pmdarima as pm -import plotly.express as px -import plotly.graph_objects as go -from plotly.subplots import make_subplots -import plotly.io as pio +from flask import Flask, request, render_template, session from werkzeug.utils import secure_filename -import matplotlib - -matplotlib.use('Agg') # Use non-interactive backend -import matplotlib.pyplot as plt -import io -import base64 -import numpy as np -from sklearn.metrics import mean_absolute_error, mean_squared_error +from models.time_series import process_time_series +from models.plotting import create_comparison_plot +from utils.file_handling import allowed_file, read_file, save_processed_file +from utils.forecast_history import update_forecast_history, download_forecast_history +import os app = Flask(__name__) app.config['UPLOAD_FOLDER'] = 'Uploads' @@ -28,176 +15,6 @@ app.secret_key = 'your-secret-key' # Required for session management os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) -def allowed_file(filename): - return '.' in filename and filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS'] - - -def create_acf_pacf_plots(data): - # Create ACF and PACF plots using matplotlib - fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8)) - - plot_acf(data, ax=ax1, lags=40) - ax1.set_title('Autocorrelation Function') - - plot_pacf(data, ax=ax2, lags=40) - ax2.set_title('Partial Autocorrelation Function') - - # Convert matplotlib plot to Plotly - buf = io.BytesIO() - plt.savefig(buf, format='png') - plt.close(fig) - buf.seek(0) - img_str = base64.b64encode(buf.getvalue()).decode('utf-8') - - # Create Plotly figure with image - fig_plotly = go.Figure() - fig_plotly.add_layout_image( - dict( - source=f'data:image/png;base64,{img_str}', - x=0, - y=1, - xref="paper", - yref="paper", - sizex=1, - sizey=1, - sizing="stretch", - opacity=1, - layer="below" - ) - ) - fig_plotly.update_layout( - height=600, - showlegend=False, - xaxis=dict(visible=False), - yaxis=dict(visible=False) - ) - return pio.to_html(fig_plotly, full_html=False) - - -def process_time_series(filepath, do_decomposition, do_forecasting, do_acf_pacf, train_percent, forecast_periods): - try: - # Read file - if filepath.endswith('.csv'): - df = pd.read_csv(filepath) - else: - df = pd.read_excel(filepath) - - # Ensure datetime column exists - date_col = df.columns[0] # Assume first column is date - value_col = df.columns[1] # Assume second column is value - df[date_col] = pd.to_datetime(df[date_col]) - df.set_index(date_col, inplace=True) - - # Initialize variables - plot_html = None - forecast_html = None - acf_pacf_html = None - summary = df[value_col].describe().to_dict() - arima_params = None - seasonal_params = None - train_size = None - test_size = None - metrics = None - - # Save processed data - processed_df = df.copy() - - # Time series decomposition - if do_decomposition: - decomposition = seasonal_decompose(df[value_col], model='additive', period=12) - fig = make_subplots(rows=4, cols=1, - subplot_titles=('Original Series', 'Trend', 'Seasonality', 'Residuals')) - - fig.add_trace(go.Scatter(x=df.index, y=df[value_col], name='Original'), row=1, col=1) - fig.add_trace(go.Scatter(x=df.index, y=decomposition.trend, name='Trend'), row=2, col=1) - fig.add_trace(go.Scatter(x=df.index, y=decomposition.seasonal, name='Seasonality'), row=3, col=1) - fig.add_trace(go.Scatter(x=df.index, y=decomposition.resid, name='Residuals'), row=4, col=1) - - fig.update_layout(height=800, showlegend=True) - plot_html = pio.to_html(fig, full_html=False) - - processed_df['Trend'] = decomposition.trend - processed_df['Seasonality'] = decomposition.seasonal - processed_df['Residuals'] = decomposition.resid - - # Forecasting - if do_forecasting: - # Split data into train and test - train_size = int(len(df) * train_percent) - test_size = len(df) - train_size - train_data = df[value_col].iloc[:train_size] - test_data = df[value_col].iloc[train_size:] if test_size > 0 else pd.Series() - - # Auto ARIMA for best parameters - model = pm.auto_arima(train_data, - seasonal=True, - m=12, - start_p=0, start_q=0, - max_p=3, max_q=3, - start_P=0, start_Q=0, - max_P=2, max_Q=2, - d=1, D=1, - trace=False, - error_action='ignore', - suppress_warnings=True, - stepwise=True) - - # Fit ARIMA with best parameters - model_fit = model.fit(train_data) - forecast = model_fit.predict(n_periods=forecast_periods) - - # Get ARIMA parameters - arima_params = model.order - seasonal_params = model.seasonal_order - - # Calculate metrics on test data if available - if test_size > 0: - test_predictions = model_fit.predict(n_periods=test_size) - mae = mean_absolute_error(test_data, test_predictions) - mse = mean_squared_error(test_data, test_predictions) - rmse = np.sqrt(mse) - metrics = {'MAE': mae, 'MSE': mse, 'RMSE': rmse} - - # Forecast plot - forecast_dates = pd.date_range(start=df.index[-1], periods=forecast_periods + 1, - freq=df.index.inferred_freq)[1:] - forecast_fig = go.Figure() - forecast_fig.add_trace(go.Scatter(x=df.index, y=df[value_col], name='Historical')) - if test_size > 0: - forecast_fig.add_trace( - go.Scatter(x=df.index[train_size:], y=test_data, name='Test Data', line=dict(color='green'))) - forecast_fig.add_trace(go.Scatter(x=forecast_dates, y=forecast, - name=f'Forecast (ARIMA{arima_params}, Seasonal{seasonal_params})', - line=dict(dash='dash'))) - forecast_fig.update_layout(title='Forecast', height=400) - forecast_html = pio.to_html(forecast_fig, full_html=False) - - # ACF/PACF plots - if do_acf_pacf: - acf_pacf_html = create_acf_pacf_plots(df[value_col]) - - # Save processed data - processed_df.to_csv(os.path.join(app.config['UPLOAD_FOLDER'], 'processed_' + os.path.basename(filepath))) - - return { - 'plot_html': plot_html, - 'forecast_html': forecast_html, - 'acf_pacf_html': acf_pacf_html, - 'summary': summary, - 'filename': 'processed_' + os.path.basename(filepath), - 'arima_params': arima_params, - 'seasonal_params': seasonal_params, - 'train_size': train_size, - 'test_size': test_size, - 'metrics': metrics, - 'forecast_dates': forecast_dates.tolist() if do_forecasting else [], - 'forecast_values': forecast.tolist() if do_forecasting else [] - } - - except Exception as e: - return {'error': str(e)} - - @app.route('/') def index(): return render_template('index.html') @@ -227,6 +44,7 @@ def upload_file(): train_percent = float(request.form.get('train_percent', 80)) / 100 test_percent = float(request.form.get('test_percent', 20)) / 100 forecast_periods = int(request.form.get('forecast_periods', 12)) + model_type = request.form.get('model_type', 'ARIMA') # Validate train/test percentages if abs(train_percent + test_percent - 1.0) > 0.01: # Allow small float precision errors @@ -238,33 +56,18 @@ def upload_file(): session['train_percent'] = train_percent session['test_percent'] = test_percent session['forecast_periods'] = forecast_periods + session['model_type'] = model_type result = process_time_series(filepath, do_decomposition, do_forecasting, do_acf_pacf, train_percent, - forecast_periods) + forecast_periods, model_type) if 'error' in result: return render_template('index.html', error=result['error']) # Update forecast history if unique if do_forecasting and result['metrics']: - new_entry = { - 'train_percent': train_percent * 100, - 'test_percent': test_percent * 100, - 'forecast_periods': forecast_periods, - 'mae': result['metrics']['MAE'] if result['metrics'] else None, - 'mse': result['metrics']['MSE'] if result['metrics'] else None, - 'rmse': result['metrics']['RMSE'] if result['metrics'] else None - } - # Check for duplicates - forecast_history = session.get('forecast_history', []) - if not any(entry['train_percent'] == new_entry['train_percent'] and - entry['test_percent'] == new_entry['test_percent'] and - entry['forecast_periods'] == new_entry['forecast_periods'] - for entry in forecast_history): - forecast_history.append(new_entry) - session['forecast_history'] = forecast_history - session['selected_indices'] = [len(forecast_history) - 1] # Select latest forecast - session.modified = True + update_forecast_history(session, train_percent, test_percent, forecast_periods, model_type, + result['metrics']) return render_template('results.html', do_decomposition=do_decomposition, @@ -288,6 +91,7 @@ def reforecast(): train_percent = float(request.form.get('train_percent', 80)) / 100 test_percent = float(request.form.get('test_percent', 20)) / 100 forecast_periods = int(request.form.get('forecast_periods', 12)) + model_type = request.form.get('model_type', 'ARIMA') add_to_existing = 'add_to_existing' in request.form # Validate train/test percentages @@ -300,45 +104,26 @@ def reforecast(): do_acf_pacf = session.get('do_acf_pacf', False) result = process_time_series(filepath, do_decomposition, do_forecasting, do_acf_pacf, train_percent, - forecast_periods) + forecast_periods, model_type) if 'error' in result: return render_template('index.html', error=result['error']) # Update forecast history if unique - forecast_history = session.get('forecast_history', []) - selected_indices = session.get('selected_indices', []) if do_forecasting and result['metrics']: - new_entry = { - 'train_percent': train_percent * 100, - 'test_percent': test_percent * 100, - 'forecast_periods': forecast_periods, - 'mae': result['metrics']['MAE'] if result['metrics'] else None, - 'mse': result['metrics']['MSE'] if result['metrics'] else None, - 'rmse': result['metrics']['RMSE'] if result['metrics'] else None - } - # Check for duplicates - if not any(entry['train_percent'] == new_entry['train_percent'] and - entry['test_percent'] == new_entry['test_percent'] and - entry['forecast_periods'] == new_entry['forecast_periods'] - for entry in forecast_history): - forecast_history.append(new_entry) - session['forecast_history'] = forecast_history - if add_to_existing: - selected_indices.append(len(forecast_history) - 1) - else: - selected_indices = [len(forecast_history) - 1] - session['selected_indices'] = selected_indices - session.modified = True + update_forecast_history(session, train_percent, test_percent, forecast_periods, model_type, result['metrics'], + add_to_existing) # Update session with current parameters session['train_percent'] = train_percent session['test_percent'] = test_percent session['forecast_periods'] = forecast_periods + session['model_type'] = model_type # Generate comparison plot if multiple forecasts are selected - if len(selected_indices) > 1: - result['forecast_html'] = create_comparison_plot(filepath, forecast_history, selected_indices) + if len(session.get('selected_indices', [])) > 1: + result['forecast_html'] = create_comparison_plot(filepath, session['forecast_history'], + session['selected_indices']) return render_template('results.html', do_decomposition=do_decomposition, @@ -347,75 +132,12 @@ def reforecast(): train_percent=train_percent * 100, test_percent=test_percent * 100, forecast_periods=forecast_periods, - forecast_history=forecast_history, - selected_indices=selected_indices, + forecast_history=session['forecast_history'], + selected_indices=session['selected_indices'], scroll_to_forecast=True, **result) -def create_comparison_plot(filepath, forecast_history, selected_indices): - # Read data - if filepath.endswith('.csv'): - df = pd.read_csv(filepath) - else: - df = pd.read_excel(filepath) - - date_col = df.columns[0] - value_col = df.columns[1] - df[date_col] = pd.to_datetime(df[date_col]) - df.set_index(date_col, inplace=True) - - # Create Plotly figure - fig = go.Figure() - fig.add_trace(go.Scatter(x=df.index, y=df[value_col], name='Historical', line=dict(color='black'))) - - # Use Plotly qualitative colors - colors = px.colors.qualitative.Plotly - - # Generate forecasts for selected indices - for idx, run_idx in enumerate(selected_indices): - entry = forecast_history[run_idx] - train_percent = entry['train_percent'] / 100 - forecast_periods = entry['forecast_periods'] - - # Split data - train_size = int(len(df) * train_percent) - test_size = len(df) - train_size - train_data = df[value_col].iloc[:train_size] - test_data = df[value_col].iloc[train_size:] if test_size > 0 else pd.Series() - - # Run ARIMA - model = pm.auto_arima(train_data, - seasonal=True, - m=12, - start_p=0, start_q=0, - max_p=3, max_q=3, - start_P=0, start_Q=0, - max_P=2, max_Q=2, - d=1, D=1, - trace=False, - error_action='ignore', - suppress_warnings=True, - stepwise=True) - - model_fit = model.fit(train_data) - forecast = model_fit.predict(n_periods=forecast_periods) - forecast_dates = pd.date_range(start=df.index[-1], periods=forecast_periods + 1, freq=df.index.inferred_freq)[ - 1:] - - # Add test data if available (only once to avoid clutter) - if test_size > 0 and idx == 0: - fig.add_trace(go.Scatter(x=df.index[train_size:], y=test_data, name='Test Data', line=dict(color='green'))) - - # Add forecast - label = f"Forecast Run {run_idx + 1}: {entry['train_percent']:.0f}/{entry['test_percent']:.0f}, {forecast_periods} periods" - fig.add_trace(go.Scatter(x=forecast_dates, y=forecast, name=label, - line=dict(dash='dash', color=colors[idx % len(colors)]))) - - fig.update_layout(title='Forecast Comparison', height=400, showlegend=True) - return pio.to_html(fig, full_html=False) - - @app.route('/compare_forecasts', methods=['POST']) def compare_forecasts(): filepath = session.get('filepath') @@ -438,14 +160,14 @@ def compare_forecasts(): train_percent = session.get('train_percent', 0.8) test_percent = session.get('test_percent', 0.2) forecast_periods = session.get('forecast_periods', 12) - forecast_history = session.get('forecast_history', []) + model_type = session.get('model_type', 'ARIMA') # Generate comparison plot - forecast_html = create_comparison_plot(filepath, forecast_history, selected_indices) + forecast_html = create_comparison_plot(filepath, session['forecast_history'], selected_indices) # Re-run the current forecast to maintain other results result = process_time_series(filepath, do_decomposition, do_forecasting, do_acf_pacf, train_percent, - forecast_periods) + forecast_periods, model_type) if 'error' in result: return render_template('index.html', error=result['error']) @@ -459,7 +181,7 @@ def compare_forecasts(): train_percent=train_percent * 100, test_percent=test_percent * 100, forecast_periods=forecast_periods, - forecast_history=forecast_history, + forecast_history=session['forecast_history'], selected_indices=selected_indices, scroll_to_forecast=True, **result) @@ -467,31 +189,7 @@ def compare_forecasts(): @app.route('/download_forecast_history') def download_forecast_history(): - forecast_history = session.get('forecast_history', []) - if not forecast_history: - return render_template('index.html', error='No forecast history available') - - # Create DataFrame for forecast history - df = pd.DataFrame(forecast_history) - df = df.rename(columns={ - 'train_percent': 'Train Percent (%)', - 'test_percent': 'Test Percent (%)', - 'forecast_periods': 'Forecast Periods', - 'mae': 'MAE', - 'mse': 'MSE', - 'rmse': 'RMSE' - }) - df.insert(0, 'Run', range(1, len(df) + 1)) - - # Save to Excel - output = io.BytesIO() - df.to_excel(output, index=False) - output.seek(0) - - return send_file(output, - mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - as_attachment=True, - download_name='forecast_history.xlsx') + return download_forecast_history(session) @app.route('/download/<filename>') diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 00000000..4a6c1e05 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1 @@ +# Empty __init__.py to make models a package \ No newline at end of file diff --git a/models/__pycache__/__init__.cpython-312.pyc b/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..b2dc4251 Binary files /dev/null and b/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/models/__pycache__/plotting.cpython-312.pyc b/models/__pycache__/plotting.cpython-312.pyc new file mode 100644 index 00000000..df56f746 Binary files /dev/null and b/models/__pycache__/plotting.cpython-312.pyc differ diff --git a/models/__pycache__/time_series.cpython-312.pyc b/models/__pycache__/time_series.cpython-312.pyc new file mode 100644 index 00000000..baf8fc48 Binary files /dev/null and b/models/__pycache__/time_series.cpython-312.pyc differ diff --git a/models/plotting.py b/models/plotting.py new file mode 100644 index 00000000..01b290ac --- /dev/null +++ b/models/plotting.py @@ -0,0 +1,138 @@ +import pandas as pd +import plotly.express as px +import plotly.graph_objects as go +import plotly.io as pio +from statsmodels.graphics.tsaplots import plot_acf, plot_pacf +import matplotlib + +matplotlib.use('Agg') +import matplotlib.pyplot as plt +import io +import base64 +from statsmodels.tsa.holtwinters import ExponentialSmoothing +import pmdarima as pm +from prophet import Prophet + + +def create_acf_pacf_plots(data): + # Create ACF and PACF plots using matplotlib + fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8)) + + plot_acf(data, ax=ax1, lags=40) + ax1.set_title('Autocorrelation Function') + + plot_pacf(data, ax=ax2, lags=40) + ax2.set_title('Partial Autocorrelation Function') + + # Convert matplotlib plot to Plotly + buf = io.BytesIO() + plt.savefig(buf, format='png') + plt.close(fig) + buf.seek(0) + img_str = base64.b64encode(buf.getvalue()).decode('utf-8') + + # Create Plotly figure with image + fig_plotly = go.Figure() + fig_plotly.add_layout_image( + dict( + source=f'data:image/png;base64,{img_str}', + x=0, + y=1, + xref="paper", + yref="paper", + sizex=1, + sizey=1, + sizing="stretch", + opacity=1, + layer="below" + ) + ) + fig_plotly.update_layout( + height=600, + showlegend=False, + xaxis=dict(visible=False), + yaxis=dict(visible=False) + ) + return pio.to_html(fig_plotly, full_html=False) + + +def create_comparison_plot(filepath, forecast_history, selected_indices): + # Read data + if filepath.endswith('.csv'): + df = pd.read_csv(filepath) + else: + df = pd.read_excel(filepath) + + date_col = df.columns[0] + value_col = df.columns[1] + df[date_col] = pd.to_datetime(df[date_col]) + df.set_index(date_col, inplace=True) + + # Create Plotly figure + fig = go.Figure() + fig.add_trace(go.Scatter(x=df.index, y=df[value_col], name='Historical', line=dict(color='black'))) + + # Use Plotly qualitative colors + colors = px.colors.qualitative.Plotly + + # Generate forecasts for selected indices + for idx, run_idx in enumerate(selected_indices): + entry = forecast_history[run_idx] + train_percent = entry['train_percent'] / 100 + forecast_periods = entry['forecast_periods'] + model_type = entry['model_type'] + + # Split data + train_size = int(len(df) * train_percent) + test_size = len(df) - train_size + train_data = df[value_col].iloc[:train_size] + test_data = df[value_col].iloc[train_size:] if test_size > 0 else pd.Series() + forecast_dates = pd.date_range(start=df.index[-1], periods=forecast_periods + 1, freq=df.index.inferred_freq)[ + 1:] + + # Run model based on model_type + forecast = None + if model_type == 'ARIMA': + model = pm.auto_arima(train_data, + seasonal=True, + m=12, + start_p=0, start_q=0, + max_p=3, max_q=3, + start_P=0, start_Q=0, + max_P=2, max_Q=2, + d=1, D=1, + trace=False, + error_action='ignore', + suppress_warnings=True, + stepwise=True) + model_fit = model.fit(train_data) + forecast = model_fit.predict(n_periods=forecast_periods) + + elif model_type == 'Exponential Smoothing': + model = ExponentialSmoothing(train_data, + trend='add', + seasonal='add', + seasonal_periods=12) + model_fit = model.fit() + forecast = model_fit.forecast(forecast_periods) + + elif model_type == 'Prophet': + prophet_df = train_data.reset_index().rename(columns={date_col: 'ds', value_col: 'y'}) + model = Prophet(yearly_seasonality=True, weekly_seasonality=False, daily_seasonality=False) + model.add_seasonality(name='monthly', period=30.5, fourier_order=5) + model_fit = model.fit(prophet_df) + future = model.make_future_dataframe(periods=forecast_periods, freq=df.index.inferred_freq) + forecast_full = model_fit.predict(future) + forecast = forecast_full['yhat'].iloc[-forecast_periods:].values + + # Add test data if available (only once to avoid clutter) + if test_size > 0 and idx == 0: + fig.add_trace(go.Scatter(x=df.index[train_size:], y=test_data, name='Test Data', line=dict(color='green'))) + + # Add forecast + label = f"Forecast Run {run_idx + 1}: {model_type}, {entry['train_percent']:.0f}/{entry['test_percent']:.0f}, {forecast_periods} periods" + fig.add_trace(go.Scatter(x=forecast_dates, y=forecast, name=label, + line=dict(dash='dash', color=colors[idx % len(colors)]))) + + fig.update_layout(title='Forecast Comparison', height=400, showlegend=True) + return pio.to_html(fig, full_html=False) \ No newline at end of file diff --git a/models/time_series.py b/models/time_series.py new file mode 100644 index 00000000..3b91c570 --- /dev/null +++ b/models/time_series.py @@ -0,0 +1,176 @@ +import pandas as pd +from statsmodels.tsa.seasonal import seasonal_decompose +from statsmodels.tsa.holtwinters import ExponentialSmoothing +import pmdarima as pm +from prophet import Prophet +import plotly.express as px +import plotly.graph_objects as go +from plotly.subplots import make_subplots +import plotly.io as pio +import numpy as np +from sklearn.metrics import mean_absolute_error, mean_squared_error +from utils.file_handling import save_processed_file +from .plotting import create_acf_pacf_plots + + +def process_time_series(filepath, do_decomposition, do_forecasting, do_acf_pacf, train_percent, forecast_periods, + model_type): + try: + # Read file + if filepath.endswith('.csv'): + df = pd.read_csv(filepath) + else: + df = pd.read_excel(filepath) + + # Ensure datetime column exists + date_col = df.columns[0] # Assume first column is date + value_col = df.columns[1] # Assume second column is value + df[date_col] = pd.to_datetime(df[date_col]) + df.set_index(date_col, inplace=True) + + # Initialize variables + plot_html = None + forecast_html = None + acf_pacf_html = None + summary = df[value_col].describe().to_dict() + model_params = None + train_size = None + test_size = None + metrics = None + + # Save processed data + processed_df = df.copy() + + # Time series decomposition + if do_decomposition: + decomposition = seasonal_decompose(df[value_col], model='additive', period=12) + fig = make_subplots(rows=4, cols=1, + subplot_titles=('Original Series', 'Trend', 'Seasonality', 'Residuals')) + + fig.add_trace(go.Scatter(x=df.index, y=df[value_col], name='Original'), row=1, col=1) + fig.add_trace(go.Scatter(x=df.index, y=decomposition.trend, name='Trend'), row=2, col=1) + fig.add_trace(go.Scatter(x=df.index, y=decomposition.seasonal, name='Seasonality'), row=3, col=1) + fig.add_trace(go.Scatter(x=df.index, y=decomposition.resid, name='Residuals'), row=4, col=1) + + fig.update_layout(height=800, showlegend=True) + plot_html = pio.to_html(fig, full_html=False) + + processed_df['Trend'] = decomposition.trend + processed_df['Seasonality'] = decomposition.seasonal + processed_df['Residuals'] = decomposition.resid + + # Forecasting + if do_forecasting: + # Split data into train and test + train_size = int(len(df) * train_percent) + test_size = len(df) - train_size + train_data = df[value_col].iloc[:train_size] + test_data = df[value_col].iloc[train_size:] if test_size > 0 else pd.Series() + forecast_dates = pd.date_range(start=df.index[-1], periods=forecast_periods + 1, + freq=df.index.inferred_freq)[1:] + + # Initialize forecast and model parameters + forecast = None + if model_type == 'ARIMA': + # Auto ARIMA for best parameters + model = pm.auto_arima(train_data, + seasonal=True, + m=12, + start_p=0, start_q=0, + max_p=3, max_q=3, + start_P=0, start_Q=0, + max_P=2, max_Q=2, + d=1, D=1, + trace=False, + error_action='ignore', + suppress_warnings=True, + stepwise=True) + + # Fit ARIMA with best parameters + model_fit = model.fit(train_data) + forecast = model_fit.predict(n_periods=forecast_periods) + model_params = f"{model.order}, Seasonal{model.seasonal_order}" + + # Calculate metrics on test data if available + if test_size > 0: + test_predictions = model_fit.predict(n_periods=test_size) + mae = mean_absolute_error(test_data, test_predictions) + mse = mean_squared_error(test_data, test_predictions) + rmse = np.sqrt(mse) + metrics = {'MAE': mae, 'MSE': mse, 'RMSE': rmse} + + elif model_type == 'Exponential Smoothing': + # Fit Exponential Smoothing model + model = ExponentialSmoothing(train_data, + trend='add', + seasonal='add', + seasonal_periods=12) + model_fit = model.fit() + forecast = model_fit.forecast(forecast_periods) + model_params = "Additive Trend, Additive Seasonal" + + # Calculate metrics on test data if available + if test_size > 0: + test_predictions = model_fit.forecast(test_size) + mae = mean_absolute_error(test_data, test_predictions) + mse = mean_squared_error(test_data, test_predictions) + rmse = np.sqrt(mse) + metrics = {'MAE': mae, 'MSE': mse, 'RMSE': rmse} + + elif model_type == 'Prophet': + # Prepare data for Prophet + prophet_df = train_data.reset_index().rename(columns={date_col: 'ds', value_col: 'y'}) + model = Prophet(yearly_seasonality=True, weekly_seasonality=False, daily_seasonality=False) + model.add_seasonality(name='monthly', period=30.5, fourier_order=5) + model_fit = model.fit(prophet_df) + + # Create future dataframe + future = model.make_future_dataframe(periods=forecast_periods, freq=df.index.inferred_freq) + forecast_full = model_fit.predict(future) + forecast = forecast_full['yhat'].iloc[-forecast_periods:].values + model_params = "Prophet" + + # Calculate metrics on test data if available + if test_size > 0: + test_future = model.make_future_dataframe(periods=test_size, freq=df.index.inferred_freq) + test_predictions = model.predict(test_future)['yhat'].iloc[-test_size:].values + mae = mean_absolute_error(test_data, test_predictions) + mse = mean_squared_error(test_data, test_predictions) + rmse = np.sqrt(mse) + metrics = {'MAE': mae, 'MSE': mse, 'RMSE': rmse} + + # Forecast plot + forecast_fig = go.Figure() + forecast_fig.add_trace(go.Scatter(x=df.index, y=df[value_col], name='Historical')) + if test_size > 0: + forecast_fig.add_trace( + go.Scatter(x=df.index[train_size:], y=test_data, name='Test Data', line=dict(color='green'))) + forecast_fig.add_trace( + go.Scatter(x=forecast_dates, y=forecast, name=f'Forecast ({model_type})', line=dict(dash='dash'))) + forecast_fig.update_layout(title=f'Forecast ({model_type})', height=400) + forecast_html = pio.to_html(forecast_fig, full_html=False) + + # ACF/PACF plots + if do_acf_pacf: + acf_pacf_html = create_acf_pacf_plots(df[value_col]) + + # Save processed data + filename = save_processed_file(processed_df, filepath) + + return { + 'plot_html': plot_html, + 'forecast_html': forecast_html, + 'acf_pacf_html': acf_pacf_html, + 'summary': summary, + 'filename': filename, + 'model_params': model_params, + 'train_size': train_size, + 'test_size': test_size, + 'metrics': metrics, + 'forecast_dates': forecast_dates.tolist() if do_forecasting else [], + 'forecast_values': forecast.tolist() if do_forecasting else [], + 'model_type': model_type + } + + except Exception as e: + return {'error': str(e)} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 94543680..4f11f5c1 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,76 +1,106 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Time Series Analysis + -
-

Time Series Analysis App

-
-
-
Upload Time Series Data
-

Upload a CSV or Excel file with time series data. First column should be dates, second column should be values.

-
-
- -
-
Select Analyses:
-
- - -
-
- - -
-
- - -
- - -
- {% if error %} -
{{ error }}
- {% endif %} -
+
+ + + +

Time Series Analysis

+ + {% if error %} +
{{ error }}
+ {% endif %} + +
+
+ + +
+ +
+
Analysis Options
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ + \ No newline at end of file diff --git a/templates/results.html b/templates/results.html index 4f795866..9e728eb7 100644 --- a/templates/results.html +++ b/templates/results.html @@ -1,139 +1,238 @@ - + + + Analysis Results - + + -
-

Time Series Analysis Results

- -
-
-
Summary Statistics
- - {% for key, value in summary.items() %} - - - - - {% endfor %} -
{{ key }}{{ value|round(2) }}
-
+
+ + - {% if do_decomposition %} -
-
-
Time Series Decomposition
- {{ plot_html | safe }} -
-
- {% endif %} +

Analysis Results

- {% if do_forecasting %} -
-
-
Forecast (ARIMA{{ arima_params }}, Seasonal{{ seasonal_params }})
-
-
- - -
-
- - -
-
- - -
-
- - -
- -
-
-

Training Data: {{ train_percent }}% ({{ train_size }} observations)

-

Test Data: {{ test_percent }}% ({{ test_size }} observations)

-

Forecast Periods: {{ forecast_periods }}

- {% if metrics %} -

Mean Absolute Error (MAE): {{ metrics.MAE|round(4) }}

-

Mean Squared Error (MSE): {{ metrics.MSE|round(4) }}

-

Root Mean Squared Error (RMSE): {{ metrics.RMSE|round(4) }}

- {% endif %} - {{ forecast_html | safe }} -
-
Forecast History
-
- - - - - - - - - - - - - - - {% for entry in forecast_history %} - - - - - - - - - - - {% endfor %} - + +
+ +
+
+
Summary Statistics
+
RunSelectTrain Percent (%)Test Percent (%)Forecast PeriodsMAEMSERMSE
{{ loop.index }} - - {{ entry.train_percent|round(2) }}{{ entry.test_percent|round(2) }}{{ entry.forecast_periods }}{{ entry.mae|round(4) if entry.mae else 'N/A' }}{{ entry.mse|round(4) if entry.mse else 'N/A' }}{{ entry.rmse|round(4) if entry.rmse else 'N/A' }}
+ {% for key, value in summary.items() %} + + + + + {% endfor %}
{{ key }}{{ value | round(2) }}
- -
- Download Forecast History (Excel) + Download Processed Data +
+
+
+ + + {% if do_decomposition and plot_html %} +
+ +
+
+
Decomposition
+
{{ plot_html | safe }}
+
{% endif %} - {% if do_acf_pacf %} -
-
-
ACF and PACF Plots
- {{ acf_pacf_html | safe }} + + {% if do_acf_pacf and acf_pacf_html %} +
+ +
+
+
ACF/PACF Plots
+
{{ acf_pacf_html | safe }}
+
{% endif %} - Download Processed Data - Upload Another File + + {% if do_forecasting and forecast_html %} +
+ +
+
+
Forecast Plot
+

Model: {{ model_type }}

+ {% if model_params %} +

Model Parameters: {{ model_params }}

+ {% endif %} + {% if metrics %} +

Test Set Metrics:

+
    +
  • MAE: {{ metrics.MAE | round(2) }}
  • +
  • MSE: {{ metrics.MSE | round(2) }}
  • +
  • RMSE: {{ metrics.RMSE | round(2) }}
  • +
+ {% endif %} +
{{ forecast_html | safe }}
+ + {% if forecast_history %} +
Forecast History
+
+ + + + + + + + + + + + + + + + {% for entry in forecast_history %} + + + + + + + + + + + + {% endfor %} + +
SelectRunTrain Percent (%)Test Percent (%)Forecast PeriodsMAEMSERMSEModel
{{ loop.index }}{{ entry.train_percent | round(2) }}{{ entry.test_percent | round(2) }}{{ entry.forecast_periods }}{{ entry.mae | round(2) if entry.mae else '-' }}{{ entry.mse | round(2) if entry.mse else '-' }}{{ entry.rmse | round(2) if entry.rmse else '-' }}{{ entry.model_type }}
+ +
+ Download Forecast History + {% endif %} + +
Re-forecast
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+ {% endif %}
+ + \ No newline at end of file diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 00000000..01a42709 --- /dev/null +++ b/utils/__init__.py @@ -0,0 +1 @@ +# Empty __init__.py to make utils a package \ No newline at end of file diff --git a/utils/__pycache__/__init__.cpython-312.pyc b/utils/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..db63631b Binary files /dev/null and b/utils/__pycache__/__init__.cpython-312.pyc differ diff --git a/utils/__pycache__/file_handling.cpython-312.pyc b/utils/__pycache__/file_handling.cpython-312.pyc new file mode 100644 index 00000000..16b72c97 Binary files /dev/null and b/utils/__pycache__/file_handling.cpython-312.pyc differ diff --git a/utils/__pycache__/forecast_history.cpython-312.pyc b/utils/__pycache__/forecast_history.cpython-312.pyc new file mode 100644 index 00000000..41178026 Binary files /dev/null and b/utils/__pycache__/forecast_history.cpython-312.pyc differ diff --git a/utils/file_handling.py b/utils/file_handling.py new file mode 100644 index 00000000..c216aedc --- /dev/null +++ b/utils/file_handling.py @@ -0,0 +1,15 @@ +import pandas as pd +import os + +def allowed_file(filename): + return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'csv', 'xls', 'xlsx'} + +def read_file(filepath): + if filepath.endswith('.csv'): + return pd.read_csv(filepath) + else: + return pd.read_excel(filepath) + +def save_processed_file(processed_df, filepath): + processed_df.to_csv(os.path.join(os.path.dirname(filepath), 'processed_' + os.path.basename(filepath))) + return 'processed_' + os.path.basename(filepath) \ No newline at end of file diff --git a/utils/forecast_history.py b/utils/forecast_history.py new file mode 100644 index 00000000..f9febeb2 --- /dev/null +++ b/utils/forecast_history.py @@ -0,0 +1,58 @@ +import pandas as pd +import io +from flask import send_file + + +def update_forecast_history(session, train_percent, test_percent, forecast_periods, model_type, metrics, + add_to_existing=False): + new_entry = { + 'train_percent': train_percent * 100, + 'test_percent': test_percent * 100, + 'forecast_periods': forecast_periods, + 'mae': metrics['MAE'] if metrics else None, + 'mse': metrics['MSE'] if metrics else None, + 'rmse': metrics['RMSE'] if metrics else None, + 'model_type': model_type + } + forecast_history = session.get('forecast_history', []) + if not any(entry['train_percent'] == new_entry['train_percent'] and + entry['test_percent'] == new_entry['test_percent'] and + entry['forecast_periods'] == new_entry['forecast_periods'] and + entry['model_type'] == new_entry['model_type'] + for entry in forecast_history): + forecast_history.append(new_entry) + session['forecast_history'] = forecast_history + if add_to_existing: + session['selected_indices'] = session.get('selected_indices', []) + [len(forecast_history) - 1] + else: + session['selected_indices'] = [len(forecast_history) - 1] + session.modified = True + + +def download_forecast_history(session): + forecast_history = session.get('forecast_history', []) + if not forecast_history: + return None, 'No forecast history available' + + # Create DataFrame for forecast history + df = pd.DataFrame(forecast_history) + df = df.rename(columns={ + 'train_percent': 'Train Percent (%)', + 'test_percent': 'Test Percent (%)', + 'forecast_periods': 'Forecast Periods', + 'mae': 'MAE', + 'mse': 'MSE', + 'rmse': 'RMSE', + 'model_type': 'Model' + }) + df.insert(0, 'Run', range(1, len(df) + 1)) + + # Save to Excel + output = io.BytesIO() + df.to_excel(output, index=False) + output.seek(0) + + return send_file(output, + mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + as_attachment=True, + download_name='forecast_history.xlsx'), None \ No newline at end of file